suricata
win32-misc.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Jan Jezek <jjezek@kerio.com>
22  *
23  * Misc Windows utility functions
24  */
25 
26 #ifdef OS_WIN32
27 
28 #include "suricata-common.h"
29 #include "win32-misc.h"
30 #include "direct.h"
31 #include "util-ip.h"
32 
33 #include <fcntl.h>
34 #include <io.h>
35 
36 void setenv(const char *name, const char *value, int overwrite)
37 {
38  if (overwrite || NULL == getenv(name)) {
39  char *str = SCMalloc(strlen(name) + strlen(value) + 2);
40  if (unlikely(str == NULL))
41  return;
42  snprintf(str, strlen(name) + strlen(value) + 1, "%s=%s", name, value);
43  putenv(str);
44  SCFree(str);
45  }
46 }
47 
48 void unsetenv(const char *name)
49 {
50  char *str = SCMalloc(strlen(name) + 2);
51  if (unlikely(str == NULL))
52  return;
53  snprintf(str, strlen(name) + 1, "%s=", name);
54  putenv(str);
55  SCFree(str);
56 }
57 
58 /* these functions have been defined on Vista and later */
59 #if NTDDI_VERSION < NTDDI_VISTA
60 const char* inet_ntop(int af, const void *src, char *dst, uint32_t cnt)
61 {
62  if (af == AF_INET)
63  {
64  struct sockaddr_in in;
65  memset(&in, 0, sizeof(in));
66  in.sin_family = AF_INET;
67  memcpy(&in.sin_addr, src, sizeof(struct in_addr));
68  if (0 == getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST))
69  return dst;
70  }
71  else if (af == AF_INET6)
72  {
73  struct sockaddr_in6 in6;
74  memset(&in6, 0, sizeof(in6));
75  in6.sin6_family = AF_INET6;
76  memcpy(&in6.sin6_addr, src, sizeof(struct in_addr6));
77  if (0 == getnameinfo((struct sockaddr *)&in6, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST))
78  return dst;
79  }
80  return NULL;
81 }
82 
83 int inet_pton(int af, const char *src, void *dst)
84 {
85  struct addrinfo hints;
86  memset(&hints, 0, sizeof(struct addrinfo));
87  hints.ai_family = af;
88 
89  /* as getaddrinfo below seems more liberal that inet_pton on Linux,
90  * add this check here that does a guess at the validity of the
91  * input address. */
92  if (af == AF_INET) {
94  return -1;
95  } else if (af == AF_INET6) {
97  return -1;
98  }
99 
100  struct addrinfo* result = NULL;
101  if (0 != getaddrinfo(src, NULL, &hints, &result))
102  return -1;
103 
104  if (result) {
105  if (result->ai_family == AF_INET) {
106  struct sockaddr_in* in = (struct sockaddr_in*)result->ai_addr;
107  memcpy(dst, &in->sin_addr, 4);
108  }
109  else if (result->ai_family == AF_INET6) {
110  struct sockaddr_in6* in6 = (struct sockaddr_in6*)result->ai_addr;
111  memcpy(dst, &in6->sin6_addr, 16);
112  }
113  else {
114  freeaddrinfo(result);
115  return -1;
116  }
117 
118  freeaddrinfo(result);
119  return 1;
120  }
121 
122  return -1;
123 }
124 #endif
125 
126 /**
127  * \brief Open a file for writing.
128  *
129  * Like fopen() with a mode of "a" or "w", but also opens the file with
130  * FILE_SHARE_DELETE, which fopen() does not. This allows the file to be
131  * renamed or deleted while open, for example so log files can be rotated by
132  * external tools, then reopened by Suricata.
133  *
134  * \param path The file path to open
135  * \param mode "a" to append or "w" to truncate
136  * \retval FILE* on success
137  * \retval NULL on error with errno set
138  */
139 FILE *SCWin32Fopen(const char *path, const char *mode)
140 {
141  bool append;
142  if (strcmp(mode, "a") == 0) {
143  append = true;
144  } else if (strcmp(mode, "w") == 0) {
145  append = false;
146  } else {
147  errno = EINVAL;
148  return NULL;
149  }
150 
151  HANDLE h =
152  CreateFileA(path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
153  NULL, append ? OPEN_ALWAYS : CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
154  if (h == INVALID_HANDLE_VALUE) {
155  switch (GetLastError()) {
156  case ERROR_FILE_NOT_FOUND:
157  case ERROR_PATH_NOT_FOUND:
158  errno = ENOENT;
159  break;
160  case ERROR_ACCESS_DENIED:
161  case ERROR_SHARING_VIOLATION:
162  case ERROR_LOCK_VIOLATION:
163  errno = EACCES;
164  break;
165  case ERROR_INVALID_NAME:
166  case ERROR_BAD_PATHNAME:
167  case ERROR_DIRECTORY:
168  errno = EINVAL;
169  break;
170  case ERROR_FILENAME_EXCED_RANGE:
171  errno = ENAMETOOLONG;
172  break;
173  case ERROR_TOO_MANY_OPEN_FILES:
174  errno = EMFILE;
175  break;
176  case ERROR_DISK_FULL:
177  case ERROR_HANDLE_DISK_FULL:
178  errno = ENOSPC;
179  break;
180  default:
181  errno = EIO;
182  break;
183  }
184  return NULL;
185  }
186 
187  /* Text mode, to match fopen() without a 'b' mode. */
188  int fd = _open_osfhandle((intptr_t)h, _O_TEXT | (append ? _O_APPEND : 0));
189  if (fd == -1) {
190  CloseHandle(h);
191  return NULL;
192  }
193 
194  FILE *fp = _fdopen(fd, mode);
195  if (fp == NULL) {
196  /* Also closes the underlying handle. */
197  int err = errno;
198  _close(fd);
199  errno = err;
200  return NULL;
201  }
202 
203  return fp;
204 }
205 
206 #endif /* OS_WIN32 */
win32-misc.h
unsetenv
void unsetenv(const char *name)
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
name
const char * name
Definition: detect-engine-proto.c:47
IPv4AddressStringIsValid
bool IPv4AddressStringIsValid(const char *str)
determine if a string is a valid ipv4 address
Definition: util-ip.c:35
util-ip.h
IPv6AddressStringIsValid
bool IPv6AddressStringIsValid(const char *str)
determine if a string is a valid ipv6 address
Definition: util-ip.c:82
setenv
void setenv(const char *name, const char *value, int overwrite)
cnt
uint32_t cnt
Definition: tmqh-packetpool.h:7
suricata-common.h
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
str
#define str(s)
Definition: suricata-common.h:313
SCFree
#define SCFree(p)
Definition: util-mem.h:61
src
uint16_t src
Definition: app-layer-dnp3.h:5
SCWin32Fopen
FILE * SCWin32Fopen(const char *path, const char *mode)
af
uint16_t af
Definition: decode-gre.h:0
dst
uint16_t dst
Definition: app-layer-dnp3.h:4