suricata
util-host-os-info.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 Anoop Saldanha <anoopsaldanha@gmail.com>
22  *
23  * Host info utility functions
24  */
25 
26 #include "suricata-common.h"
27 #include "util-host-os-info.h"
28 #include "util-error.h"
29 #include "util-debug.h"
30 #include "util-ip.h"
31 #include "util-radix-tree.h"
32 #include "util-byte.h"
33 #include "stream-tcp-private.h"
34 #include "stream-tcp-reassemble.h"
35 
36 #include "conf.h"
37 #include "conf-yaml-loader.h"
38 
39 #include "util-enum.h"
40 #include "util-unittest.h"
41 
42 /** Enum map for the various OS flavours */
44  { "none", OS_POLICY_NONE },
45  { "bsd", OS_POLICY_BSD },
46  { "bsd-right", OS_POLICY_BSD_RIGHT },
47  { "old-linux", OS_POLICY_OLD_LINUX },
48  { "linux", OS_POLICY_LINUX },
49  { "old-solaris", OS_POLICY_OLD_SOLARIS },
50  { "solaris", OS_POLICY_SOLARIS },
51  { "hpux10", OS_POLICY_HPUX10 },
52  { "hpux11", OS_POLICY_HPUX11 },
53  { "irix", OS_POLICY_IRIX },
54  { "macos", OS_POLICY_MACOS },
55  { "windows", OS_POLICY_WINDOWS },
56  { "vista", OS_POLICY_VISTA },
57  { "windows2k3", OS_POLICY_WINDOWS2K3 },
58  { NULL, -1 },
59 };
60 
61 /** Radix tree that holds the host OS information */
62 static SCRadixTree *sc_hinfo_tree = NULL;
63 
64 
65 /**
66  * \brief Allocates the host_os flavour wrapped in user_data variable to be sent
67  * along with the key to the radix tree
68  *
69  * \param host_os Pointer to a character string containing the host_os flavour
70  *
71  * \retval user_data On success, pointer to the user_data that has to be sent
72  * along with the key, to be added to the Radix tree; NULL on
73  * failure
74  * \initonly
75  */
76 static void *SCHInfoAllocUserDataOSPolicy(const char *host_os)
77 {
78  int *user_data = NULL;
79 
80  if ( (user_data = SCMalloc(sizeof(int))) == NULL) {
81  SCLogError(SC_ERR_FATAL, "Error allocating memory. Exiting");
82  exit(EXIT_FAILURE);
83  }
84 
85  /* the host os flavour that has to be sent as user data */
86  if ( (*user_data = SCMapEnumNameToValue(host_os, sc_hinfo_os_policy_map)) == -1) {
87  SCLogError(SC_ERR_INVALID_ENUM_MAP, "Invalid enum map inside "
88  "SCHInfoAddHostOSInfo()");
89  SCFree(user_data);
90  return NULL;
91  }
92 
93  return (void *)user_data;
94 }
95 
96 /**
97  * \brief Used to free the user data that is allocated by host_os_info API
98  *
99  * \param Pointer to the data that has to be freed
100  */
101 static void SCHInfoFreeUserDataOSPolicy(void *data)
102 {
103  if (data != NULL)
104  SCFree(data);
105 
106  return;
107 }
108 
109 /**
110  * \brief Used to add the host-os-info data obtained from the conf
111  *
112  * \param host_os The host_os name/flavour from the conf file
113  * \param host_os_ip_range Pointer to a char string holding the ip/ip_netblock
114  * for the host_os specified in the first argument
115  * \param is_ipv4 Indicates if the ip address to be considered for the
116  * default configuration is IPV4; if not it is IPV6.
117  * Specified using SC_HINFO_IS_IPV6 or SC_HINFO_IS_IPV4
118  *
119  * \retval 0 On successfully adding the host os info to the Radix tree
120  * \retval -1 On failure
121  * \initonly (only specified from config, at the startup)
122  */
123 int SCHInfoAddHostOSInfo(const char *host_os, const char *host_os_ip_range, int is_ipv4)
124 {
125  char *ip_str = NULL;
126  char *ip_str_rem = NULL;
127  struct in_addr *ipv4_addr = NULL;
128  struct in6_addr *ipv6_addr = NULL;
129  char *netmask_str = NULL;
130  int netmask_value = 0;
131  int *user_data = NULL;
132  char recursive = FALSE;
133 
134  if (host_os == NULL || host_os_ip_range == NULL ||
135  strlen(host_os_ip_range) == 0) {
136  SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid arguments");
137  return -1;
138  }
139 
140  /* create the radix tree that would hold all the host os info */
141  if (sc_hinfo_tree == NULL)
142  sc_hinfo_tree = SCRadixCreateRadixTree(SCHInfoFreeUserDataOSPolicy, NULL);
143 
144  /* the host os flavour that has to be sent as user data */
145  if ( (user_data = SCHInfoAllocUserDataOSPolicy(host_os)) == NULL) {
146  SCLogError(SC_ERR_INVALID_ENUM_MAP, "Invalid enum map inside");
147  return -1;
148  }
149 
150  /* if we have a default configuration set the appropriate values for the
151  * netblocks */
152  if ( (strcasecmp(host_os_ip_range, "default")) == 0) {
153  if (is_ipv4)
154  host_os_ip_range = "0.0.0.0/0";
155  else
156  host_os_ip_range = "::/0";
157  }
158 
159  if ( (ip_str = SCStrdup(host_os_ip_range)) == NULL) {
160  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
161  exit(EXIT_FAILURE);
162  }
163 
164  /* check if we have more addresses in the host_os_ip_range */
165  if ((ip_str_rem = strchr(ip_str, ',')) != NULL) {
166  ip_str_rem[0] = '\0';
167  ip_str_rem++;
168  recursive = TRUE;
169  }
170 
171  /* check if we have received a netblock */
172  if ( (netmask_str = strchr(ip_str, '/')) != NULL) {
173  netmask_str[0] = '\0';
174  netmask_str++;
175  }
176 
177  if (strchr(ip_str, ':') == NULL) {
178  /* if we are here, we have an IPV4 address */
179  if ( (ipv4_addr = ValidateIPV4Address(ip_str)) == NULL) {
180  SCLogError(SC_ERR_INVALID_IPV4_ADDR, "Invalid IPV4 address");
181  SCHInfoFreeUserDataOSPolicy(user_data);
182  SCFree(ip_str);
183  return -1;
184  }
185 
186  if (netmask_str == NULL) {
187  SCRadixAddKeyIPV4((uint8_t *)ipv4_addr, sc_hinfo_tree,
188  (void *)user_data);
189  } else {
190  if (StringParseI32RangeCheck(&netmask_value, 10, 0, (const char *)netmask_str, 0, 32) < 0) {
191  SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "Invalid IPV4 Netblock");
192  SCHInfoFreeUserDataOSPolicy(user_data);
193  SCFree(ipv4_addr);
194  SCFree(ip_str);
195  return -1;
196  }
197 
198  MaskIPNetblock((uint8_t *)ipv4_addr, netmask_value, 32);
199  SCRadixAddKeyIPV4Netblock((uint8_t *)ipv4_addr, sc_hinfo_tree,
200  (void *)user_data, netmask_value);
201  }
202  } else {
203  /* if we are here, we have an IPV6 address */
204  if ( (ipv6_addr = ValidateIPV6Address(ip_str)) == NULL) {
205  SCLogError(SC_ERR_INVALID_IPV6_ADDR, "Invalid IPV6 address inside");
206  SCHInfoFreeUserDataOSPolicy(user_data);
207  SCFree(ip_str);
208  return -1;
209  }
210 
211  if (netmask_str == NULL) {
212  SCRadixAddKeyIPV6((uint8_t *)ipv6_addr, sc_hinfo_tree,
213  (void *)user_data);
214  } else {
215  if (StringParseI32RangeCheck(&netmask_value, 10, 0, (const char *)netmask_str, 0, 128) < 0) {
216  SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "Invalid IPV6 Netblock");
217  SCHInfoFreeUserDataOSPolicy(user_data);
218  SCFree(ipv6_addr);
219  SCFree(ip_str);
220  return -1;
221  }
222 
223  MaskIPNetblock((uint8_t *)ipv6_addr, netmask_value, 128);
224  SCRadixAddKeyIPV6Netblock((uint8_t *)ipv6_addr, sc_hinfo_tree,
225  (void *)user_data, netmask_value);
226  }
227  }
228 
229  if (recursive == TRUE) {
230  SCHInfoAddHostOSInfo(host_os, ip_str_rem, is_ipv4);
231  }
232 
233  SCFree(ip_str);
234  if (ipv4_addr != NULL)
235  SCFree(ipv4_addr);
236  if (ipv6_addr != NULL)
237  SCFree(ipv6_addr);
238  return *user_data;
239 }
240 
241 /**
242  * \brief Retrieves the host os flavour, given an ipv4/ipv6 address as a string.
243  *
244  * \param Pointer to a string containing an IP address
245  *
246  * \retval The OS flavour on success; -1 on failure, or on not finding the key
247  */
248 int SCHInfoGetHostOSFlavour(const char *ip_addr_str)
249 {
250  struct in_addr *ipv4_addr = NULL;
251  struct in6_addr *ipv6_addr = NULL;
252  void *user_data = NULL;
253 
254  if (ip_addr_str == NULL || strchr(ip_addr_str, '/') != NULL)
255  return -1;
256 
257  if (strchr(ip_addr_str, ':') != NULL) {
258  if ( (ipv6_addr = ValidateIPV6Address(ip_addr_str)) == NULL) {
259  SCLogError(SC_ERR_INVALID_IPV4_ADDR, "Invalid IPV4 address");
260  return -1;
261  }
262 
263  (void)SCRadixFindKeyIPV6BestMatch((uint8_t *)ipv6_addr, sc_hinfo_tree, &user_data);
264  SCFree(ipv6_addr);
265  if (user_data == NULL)
266  return -1;
267  else
268  return *((int *)user_data);
269  } else {
270  if ( (ipv4_addr = ValidateIPV4Address(ip_addr_str)) == NULL) {
271  SCLogError(SC_ERR_INVALID_IPV4_ADDR, "Invalid IPV4 address");
272  return -1;
273  }
274 
275  (void)SCRadixFindKeyIPV4BestMatch((uint8_t *)ipv4_addr, sc_hinfo_tree, &user_data);
276  SCFree(ipv4_addr);
277  if (user_data == NULL)
278  return -1;
279  else
280  return *((int *)user_data);
281  }
282 }
283 
284 /**
285  * \brief Retrieves the host os flavour, given an ipv4 address in the raw
286  * address format.
287  *
288  * \param Pointer to a raw ipv4 address.
289  *
290  * \retval The OS flavour on success; -1 on failure, or on not finding the key
291  */
292 int SCHInfoGetIPv4HostOSFlavour(uint8_t *ipv4_addr)
293 {
294  void *user_data = NULL;
295  (void)SCRadixFindKeyIPV4BestMatch(ipv4_addr, sc_hinfo_tree, &user_data);
296  if (user_data == NULL)
297  return -1;
298  else
299  return *((int *)user_data);
300 }
301 
302 /**
303  * \brief Retrieves the host os flavour, given an ipv6 address in the raw
304  * address format.
305  *
306  * \param Pointer to a raw ipv6 address.
307  *
308  * \retval The OS flavour on success; -1 on failure, or on not finding the key
309  */
310 int SCHInfoGetIPv6HostOSFlavour(uint8_t *ipv6_addr)
311 {
312  void *user_data = NULL;
313  (void)SCRadixFindKeyIPV6BestMatch(ipv6_addr, sc_hinfo_tree, &user_data);
314  if (user_data == NULL)
315  return -1;
316  else
317  return *((int *)user_data);
318 }
319 
321 {
322  if (sc_hinfo_tree != NULL) {
323  SCRadixReleaseRadixTree(sc_hinfo_tree);
324  sc_hinfo_tree = NULL;
325  }
326 
327  return;
328 }
329 
330 /**
331  * \brief Load the host os policy information from the configuration.
332  *
333  * \initonly (A mem alloc error should cause an exit failure)
334  */
336 {
337  ConfNode *root = ConfGetNode("host-os-policy");
338  if (root == NULL)
339  return;
340 
341  ConfNode *policy;
342  TAILQ_FOREACH(policy, &root->head, next) {
343  ConfNode *host;
344  TAILQ_FOREACH(host, &policy->head, next) {
345  int is_ipv4 = 1;
346  if (host->val != NULL && strchr(host->val, ':') != NULL)
347  is_ipv4 = 0;
348  if (SCHInfoAddHostOSInfo(policy->name, host->val, is_ipv4) == -1) {
350  "Failed to add host \"%s\" with policy \"%s\" to host "
351  "info database", host->val, policy->name);
352  exit(EXIT_FAILURE);
353  }
354  }
355  }
356 }
357 
358 /*------------------------------------Unit_Tests------------------------------*/
359 
360 #ifdef UNITTESTS
361 static SCRadixTree *sc_hinfo_tree_backup = NULL;
362 
363 static void SCHInfoCreateContextBackup(void)
364 {
365  sc_hinfo_tree_backup = sc_hinfo_tree;
366  sc_hinfo_tree = NULL;
367 
368  return;
369 }
370 
371 static void SCHInfoRestoreContextBackup(void)
372 {
373  sc_hinfo_tree = sc_hinfo_tree_backup;
374  sc_hinfo_tree_backup = NULL;
375 
376  return;
377 }
378 
379 /**
380  * \test Check if we the IPs with the right OS flavours are added to the host OS
381  * radix tree, and the IPS with invalid flavours returns an error(-1)
382  */
383 static int SCHInfoTestInvalidOSFlavour01(void)
384 {
385  SCHInfoCreateContextBackup();
386 
387  int result = 0;
388 
389  if (SCHInfoAddHostOSInfo("bamboo", "192.168.1.1", SC_HINFO_IS_IPV4) != -1) {
390  goto end;
391  }
392  if (SCHInfoAddHostOSInfo("linux", "192.168.1.1", SC_HINFO_IS_IPV4) !=
394  goto end;
395  }
396  if (SCHInfoAddHostOSInfo("windows", "192.168.1.1", SC_HINFO_IS_IPV4) !=
398  goto end;
399  }
400  if (SCHInfoAddHostOSInfo("solaris", "192.168.1.1", SC_HINFO_IS_IPV4) !=
402  goto end;
403  }
404  if (SCHInfoAddHostOSInfo("hpux10", "192.168.1.1", SC_HINFO_IS_IPV4) !=
406  goto end;
407  }
408  if (SCHInfoAddHostOSInfo("hpux11", "192.168.1.1", SC_HINFO_IS_IPV4) !=
410  goto end;
411  }
412  if (SCHInfoAddHostOSInfo("irix", "192.168.1.1", SC_HINFO_IS_IPV4) !=
414  goto end;
415  }
416  if (SCHInfoAddHostOSInfo("bsd", "192.168.1.1", SC_HINFO_IS_IPV4) !=
418  goto end;
419  }
420  if (SCHInfoAddHostOSInfo("old_linux", "192.168.1.1", SC_HINFO_IS_IPV4) !=
422  goto end;
423  }
424  if (SCHInfoAddHostOSInfo("macos", "192.168.1.1", SC_HINFO_IS_IPV4) !=
426  goto end;
427  }
428  if (SCHInfoAddHostOSInfo("vista", "192.168.1.1", SC_HINFO_IS_IPV4) !=
430  goto end;
431  }
432  if (SCHInfoAddHostOSInfo("windows2k3", "192.168.1.1", SC_HINFO_IS_IPV4) !=
434  goto end;
435  }
436 
437  result = 1;
438 
439  end:
441  SCHInfoRestoreContextBackup();
442 
443  return result;
444 }
445 
446 /**
447  * \test Check that invalid ipv4 addresses and ipv4 netblocks are rejected by
448  * the host os info API
449  */
450 static int SCHInfoTestInvalidIPV4Address02(void)
451 {
452  SCHInfoCreateContextBackup();
453 
454  int result = 0;
455 
456  if (SCHInfoAddHostOSInfo("linux", "192.168.1.566", SC_HINFO_IS_IPV4) != -1) {
457  goto end;
458  }
459  if (SCHInfoAddHostOSInfo("linux", "192.168.1", SC_HINFO_IS_IPV4) != -1) {
460  goto end;
461  }
462  if (SCHInfoAddHostOSInfo("linux", "192.", SC_HINFO_IS_IPV4) != -1) {
463  goto end;
464  }
465  if (SCHInfoAddHostOSInfo("linux", "192.168", SC_HINFO_IS_IPV4) != -1) {
466  goto end;
467  }
468  if (SCHInfoAddHostOSInfo("linux", "", SC_HINFO_IS_IPV4) != -1) {
469  goto end;
470  }
471  if (SCHInfoAddHostOSInfo("linux", "192.168.1.1/33", SC_HINFO_IS_IPV4) != -1) {
472  goto end;
473  }
474 
475  result = 1;
476 
477  end:
479  SCHInfoRestoreContextBackup();
480 
481  return result;
482 }
483 
484 /**
485  * \test Check that invalid ipv4 addresses and ipv4 netblocks are rejected by
486  * the host os info API
487  */
488 static int SCHInfoTestInvalidIPV6Address03(void)
489 {
490  SCHInfoCreateContextBackup();
491 
492  int result = 0;
493 
494  if (SCHInfoAddHostOSInfo("linux", "2362:7322", SC_HINFO_IS_IPV6) != -1) {
495  goto end;
496  }
497  if (SCHInfoAddHostOSInfo("linux", "19YW:", SC_HINFO_IS_IPV6) != -1) {
498  goto end;
499  }
500  if (SCHInfoAddHostOSInfo("linux", "1235", SC_HINFO_IS_IPV6) != -1) {
501  goto end;
502  }
503  if (SCHInfoAddHostOSInfo("linux", "1922:236115:", SC_HINFO_IS_IPV6) != -1) {
504  goto end;
505  }
506  if (SCHInfoAddHostOSInfo("linux", "", SC_HINFO_IS_IPV6) != -1) {
507  goto end;
508  }
509  if (SCHInfoAddHostOSInfo("linux",
510  "1921.6311:6241:6422:7352:ABBB:DDDD:EEEE/129",
511  SC_HINFO_IS_IPV6) != -1) {
512  goto end;
513  }
514 
515  result = 1;
516 
517  end:
519  SCHInfoRestoreContextBackup();
520 
521  return result;
522 }
523 
524 /**
525  * \test Check that valid ipv4 addresses are inserted into the host os radix
526  * tree, and the host os api retrieves the right value for the host os
527  * flavour, on supplying as arg an ipv4 addresses that has been added to
528  * the host os radix tree.
529  */
530 static int SCHInfoTestValidIPV4Address04(void)
531 {
532  SCHInfoCreateContextBackup();
533 
534  int result = 0;
535 
536  if (SCHInfoAddHostOSInfo("linux", "192.168.1.1", SC_HINFO_IS_IPV4) == -1) {
537  goto end;
538  }
539  if (SCHInfoAddHostOSInfo("windows", "192.192.1.2", SC_HINFO_IS_IPV4) == -1) {
540  goto end;
541  }
542  if (SCHInfoAddHostOSInfo("solaris", "192.168.1.100", SC_HINFO_IS_IPV4) == -1) {
543  goto end;
544  }
545  if (SCHInfoAddHostOSInfo("hpux10", "192.168.2.4", SC_HINFO_IS_IPV4) == -1) {
546  goto end;
547  }
548  if (SCHInfoAddHostOSInfo("linux", "192.192.1.5", SC_HINFO_IS_IPV4) == -1) {
549  goto end;
550  }
551  if (SCHInfoAddHostOSInfo("vista", "192.168.10.20", SC_HINFO_IS_IPV4) == -1) {
552  goto end;
553  }
554  if (SCHInfoAddHostOSInfo("solaris", "111.163.151.62", SC_HINFO_IS_IPV4) == -1) {
555  goto end;
556  }
557  if (SCHInfoAddHostOSInfo("solaris", "11.1.120.210", SC_HINFO_IS_IPV4) == -1) {
558  goto end;
559  }
560  if (SCHInfoAddHostOSInfo("linux", "19.18.110.210", SC_HINFO_IS_IPV4) == -1) {
561  goto end;
562  }
563  if (SCHInfoAddHostOSInfo("windows", "19.18.120.110", SC_HINFO_IS_IPV4) == -1) {
564  goto end;
565  }
566  if (SCHInfoAddHostOSInfo("hpux11", "191.168.11.128", SC_HINFO_IS_IPV4) == -1) {
567  goto end;
568  }
569  if (SCHInfoAddHostOSInfo("vista", "191.168.11.192", SC_HINFO_IS_IPV4) == -1) {
570  goto end;
571  }
572 
573  if (SCHInfoGetHostOSFlavour("192.168.1.1") !=
575  goto end;
576  }
577  if (SCHInfoGetHostOSFlavour("192.168.1.2") != -1) {
578  goto end;
579  }
580  if (SCHInfoGetHostOSFlavour("192.168.1.100") !=
582  goto end;
583  }
584  if (SCHInfoGetHostOSFlavour("192.192.2.4") != -1) {
585  goto end;
586  }
587  if (SCHInfoGetHostOSFlavour("192.168.2.4") !=
589  goto end;
590  }
591  if (SCHInfoGetHostOSFlavour("192.192.1.5") !=
593  goto end;
594  }
595  if (SCHInfoGetHostOSFlavour("192.168.10.20") !=
597  goto end;
598  }
599  if (SCHInfoGetHostOSFlavour("111.163.151.62") !=
601  goto end;
602  }
603  if (SCHInfoGetHostOSFlavour("11.1.120.210") !=
605  goto end;
606  }
607  if (SCHInfoGetHostOSFlavour("19.18.110.210") !=
609  goto end;
610  }
611  if (SCHInfoGetHostOSFlavour("19.18.120.110") !=
613  goto end;
614  }
615  if (SCHInfoGetHostOSFlavour("191.168.11.128") !=
617  goto end;
618  }
619  if (SCHInfoGetHostOSFlavour("191.168.11.192") !=
621  goto end;
622  }
623  if (SCHInfoGetHostOSFlavour("191.168.11.224") != -1) {
624  goto end;
625  }
626 
627  result = 1;
628 
629  end:
631  SCHInfoRestoreContextBackup();
632 
633  return result;
634 }
635 
636 /**
637  * \test Check that valid ipv4 addresses/netblocks are inserted into the host os
638  * radix tree, and the host os api retrieves the right value for the host
639  * os flavour, on supplying as arg an ipv4 addresses that has been added
640  * to the host os radix tree.
641  */
642 static int SCHInfoTestValidIPV4Address05(void)
643 {
644  SCHInfoCreateContextBackup();
645 
646  struct in_addr in;
647  int result = 0;
648 
649  if (SCHInfoAddHostOSInfo("linux", "192.168.1.1", SC_HINFO_IS_IPV4) == -1) {
650  goto end;
651  }
652  if (SCHInfoAddHostOSInfo("windows", "192.192.1.2", SC_HINFO_IS_IPV4) == -1) {
653  goto end;
654  }
655  if (SCHInfoAddHostOSInfo("solaris", "192.168.1.100", SC_HINFO_IS_IPV4) == -1) {
656  goto end;
657  }
658  if (SCHInfoAddHostOSInfo("hpux10", "192.168.2.4", SC_HINFO_IS_IPV4) == -1) {
659  goto end;
660  }
661  if (SCHInfoAddHostOSInfo("linux", "192.192.1.5", SC_HINFO_IS_IPV4) == -1) {
662  goto end;
663  }
664  if (SCHInfoAddHostOSInfo("vista", "192.168.10.20", SC_HINFO_IS_IPV4) == -1) {
665  goto end;
666  }
667  if (SCHInfoAddHostOSInfo("solaris", "111.163.151.62", SC_HINFO_IS_IPV4) == -1) {
668  goto end;
669  }
670  if (SCHInfoAddHostOSInfo("hpux11", "111.162.208.124/20", SC_HINFO_IS_IPV4) == -1) {
671  goto end;
672  }
673  if (SCHInfoAddHostOSInfo("windows", "111.162.240.1", SC_HINFO_IS_IPV4) == -1) {
674  goto end;
675  }
676  if (SCHInfoAddHostOSInfo("solaris", "111.162.214.100", SC_HINFO_IS_IPV4) == -1) {
677  goto end;
678  }
679  if (SCHInfoAddHostOSInfo("vista", "111.162.208.100", SC_HINFO_IS_IPV4) == -1) {
680  goto end;
681  }
682  if (SCHInfoAddHostOSInfo("linux", "111.162.194.112", SC_HINFO_IS_IPV4) == -1) {
683  goto end;
684  }
685 
686  if (SCHInfoGetHostOSFlavour("192.168.1.1") !=
688  goto end;
689  }
690  if (SCHInfoGetHostOSFlavour("192.168.1.2") != -1) {
691  goto end;
692  }
693  if (SCHInfoGetHostOSFlavour("192.168.1.100") !=
695  goto end;
696  }
697  if (SCHInfoGetHostOSFlavour("192.192.2.4") != -1) {
698  goto end;
699  }
700  if (SCHInfoGetHostOSFlavour("192.168.2.4") !=
702  goto end;
703  }
704  if (SCHInfoGetHostOSFlavour("192.192.1.5") !=
706  goto end;
707  }
708  if (SCHInfoGetHostOSFlavour("192.168.10.20") !=
710  goto end;
711  }
712  if (SCHInfoGetHostOSFlavour("111.163.151.62") !=
714  goto end;
715  }
716  if (SCHInfoGetHostOSFlavour("111.162.208.0") !=
718  goto end;
719  }
720  if (SCHInfoGetHostOSFlavour("111.162.210.1") !=
722  goto end;
723  }
724  if (SCHInfoGetHostOSFlavour("111.162.214.1") !=
726  goto end;
727  }
728  if (SCHInfoGetHostOSFlavour("111.162.0.0") != -1) {
729  goto end;
730  }
731  if (SCHInfoGetHostOSFlavour("111.162.240.112") != -1) {
732  goto end;
733  }
734  if (SCHInfoGetHostOSFlavour("111.162.240.1") !=
736  goto end;
737  }
738  if (SCHInfoGetHostOSFlavour("111.162.214.100") !=
740  goto end;
741  }
742  if (inet_pton(AF_INET, "111.162.208.100", &in) < 0) {
743  goto end;
744  }
745  if (SCHInfoGetIPv4HostOSFlavour((uint8_t *)&in) !=
747  goto end;
748  }
749  if (SCHInfoGetHostOSFlavour("111.162.194.112") !=
751  goto end;
752  }
753  if (SCHInfoGetHostOSFlavour("111.162.208.200") !=
755  goto end;
756  }
757  if (inet_pton(AF_INET, "111.162.208.200", &in) < 0) {
758  goto end;
759  }
760  if (SCHInfoGetIPv4HostOSFlavour((uint8_t *)&in) !=
762  goto end;
763  }
764  if (SCHInfoGetHostOSFlavour("111.162.200.201") != -1) {
765  goto end;
766  }
767 
768  result = 1;
769 
770  end:
772  SCHInfoRestoreContextBackup();
773 
774  return result;
775 }
776 
777 /**
778  * \test Check that valid ipv6 addresses are inserted into the host os radix
779  * tree, and the host os api retrieves the right value for the host os
780  * flavour, on supplying as arg an ipv6 address that has been added to
781  * the host os radix tree.
782  */
783 static int SCHInfoTestValidIPV6Address06(void)
784 {
785  SCHInfoCreateContextBackup();
786 
787  int result = 0;
788 
789  if (SCHInfoAddHostOSInfo("linux",
790  "2351:2512:6211:6246:235A:6242:2352:62AD",
791  SC_HINFO_IS_IPV6) == -1) {
792  goto end;
793  }
794  if (SCHInfoAddHostOSInfo("windows",
795  "6961:6121:2132:6241:423A:2135:2461:621D",
796  SC_HINFO_IS_IPV6) == -1) {
797  goto end;
798  }
799  if (SCHInfoAddHostOSInfo("solaris",
800  "DD13:613D:F312:62DD:6213:421A:6212:2652",
801  SC_HINFO_IS_IPV6) == -1) {
802  goto end;
803  }
804  if (SCHInfoAddHostOSInfo("hpux10",
805  "9891:2131:2151:6426:1342:674D:622F:2342",
806  SC_HINFO_IS_IPV6) == -1) {
807  goto end;
808  }
809  if (SCHInfoAddHostOSInfo("linux",
810  "3525:2351:4223:6211:2311:2667:6242:2154",
811  SC_HINFO_IS_IPV6) == -1) {
812  goto end;
813  }
814  if (SCHInfoAddHostOSInfo("vista",
815  "1511:6211:6726:7777:1212:2333:6222:7722",
816  SC_HINFO_IS_IPV6) == -1) {
817  goto end;
818  }
819  if (SCHInfoAddHostOSInfo("solaris",
820  "2666:6222:7222:2335:6223:7722:3425:2362",
821  SC_HINFO_IS_IPV6) == -1) {
822  goto end;
823  }
824  if (SCHInfoAddHostOSInfo("solaris",
825  "8762:2352:6241:7245:EE23:21AD:2312:622C",
826  SC_HINFO_IS_IPV6) == -1) {
827  goto end;
828  }
829  if (SCHInfoAddHostOSInfo("linux",
830  "6422:EE1A:2621:34AD:2462:432D:642E:E13A",
831  SC_HINFO_IS_IPV6) == -1) {
832  goto end;
833  }
834  if (SCHInfoAddHostOSInfo("windows",
835  "3521:7622:6241:6242:7277:1234:2352:6234",
836  SC_HINFO_IS_IPV6) == -1) {
837  goto end;
838  }
839  if (SCHInfoAddHostOSInfo("hpux11",
840  "2141:6232:6252:2223:7734:2345:6245:6222",
841  SC_HINFO_IS_IPV6) == -1) {
842  goto end;
843  }
844  if (SCHInfoAddHostOSInfo("vista",
845  "5222:6432:6432:2322:6662:3423:4322:3245",
846  SC_HINFO_IS_IPV6) == -1) {
847  goto end;
848  }
849 
850  if (SCHInfoGetHostOSFlavour("2351:2512:6211:6246:235A:6242:2352:62AD") !=
852  goto end;
853  }
854  if (SCHInfoGetHostOSFlavour("2351:2512:6211:6246:235A:6242:2352:6FFFE") != -1) {
855  goto end;
856  }
857  if (SCHInfoGetHostOSFlavour("DD13:613D:F312:62DD:6213:421A:6212:2652") !=
859  goto end;
860  }
861  if (SCHInfoGetHostOSFlavour("DD13:613D:F312:62DD:6213:421A:6212:2222") != -1) {
862  goto end;
863  }
864  if (SCHInfoGetHostOSFlavour("9891:2131:2151:6426:1342:674D:622F:2342") !=
866  goto end;
867  }
868  if (SCHInfoGetHostOSFlavour("3525:2351:4223:6211:2311:2667:6242:2154") !=
870  goto end;
871  }
872  if (SCHInfoGetHostOSFlavour("1511:6211:6726:7777:1212:2333:6222:7722") !=
874  goto end;
875  }
876  if (SCHInfoGetHostOSFlavour("2666:6222:7222:2335:6223:7722:3425:2362") !=
878  goto end;
879  }
880  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2312:622C") !=
882  goto end;
883  }
884  if (SCHInfoGetHostOSFlavour("6422:EE1A:2621:34AD:2462:432D:642E:E13A") !=
886  goto end;
887  }
888  if (SCHInfoGetHostOSFlavour("3521:7622:6241:6242:7277:1234:2352:6234") !=
890  goto end;
891  }
892  if (SCHInfoGetHostOSFlavour("2141:6232:6252:2223:7734:2345:6245:6222") !=
894  goto end;
895  }
896  if (SCHInfoGetHostOSFlavour("5222:6432:6432:2322:6662:3423:4322:3245") !=
898  goto end;
899  }
900  if (SCHInfoGetHostOSFlavour("5222:6432:6432:2322:6662:3423:4322:DDDD") != -1) {
901  goto end;
902  }
903 
904  result = 1;
905 
906  end:
908  SCHInfoRestoreContextBackup();
909 
910  return result;
911 }
912 
913 /**
914  * \test Check that valid ipv6 addresses/netblocks are inserted into the host os
915  * radix tree, and the host os api retrieves the right value for the host
916  * os flavour, on supplying as arg an ipv6 address that has been added to
917  * the host os radix tree.
918  */
919 static int SCHInfoTestValidIPV6Address07(void)
920 {
921  SCHInfoCreateContextBackup();
922 
923  int result = 0;
924 
925  if (SCHInfoAddHostOSInfo("linux",
926  "2351:2512:6211:6246:235A:6242:2352:62AD",
927  SC_HINFO_IS_IPV6) == -1) {
928  goto end;
929  }
930  if (SCHInfoAddHostOSInfo("windows",
931  "6961:6121:2132:6241:423A:2135:2461:621D",
932  SC_HINFO_IS_IPV6) == -1) {
933  goto end;
934  }
935  if (SCHInfoAddHostOSInfo("solaris",
936  "DD13:613D:F312:62DD:6213:421A:6212:2652",
937  SC_HINFO_IS_IPV6) == -1) {
938  goto end;
939  }
940  if (SCHInfoAddHostOSInfo("hpux10",
941  "9891:2131:2151:6426:1342:674D:622F:2342",
942  SC_HINFO_IS_IPV6) == -1) {
943  goto end;
944  }
945  if (SCHInfoAddHostOSInfo("linux",
946  "3525:2351:4223:6211:2311:2667:6242:2154",
947  SC_HINFO_IS_IPV6) == -1) {
948  goto end;
949  }
950  if (SCHInfoAddHostOSInfo("vista",
951  "1511:6211:6726:7777:1212:2333:6222:7722",
952  SC_HINFO_IS_IPV6) == -1) {
953  goto end;
954  }
955  if (SCHInfoAddHostOSInfo("solaris",
956  "2666:6222:7222:2335:6223:7722:3425:2362",
957  SC_HINFO_IS_IPV6) == -1) {
958  goto end;
959  }
960  if (SCHInfoAddHostOSInfo("solaris",
961  "8762:2352:6241:7245:EE23:21AD:2312:622C/68",
962  SC_HINFO_IS_IPV6) == -1) {
963  goto end;
964  }
965  if (SCHInfoAddHostOSInfo("linux",
966  "8762:2352:6241:7245:EE23:21AD:2412:622C",
967  SC_HINFO_IS_IPV6) == -1) {
968  goto end;
969  }
970  if (SCHInfoAddHostOSInfo("windows",
971  "8762:2352:6241:7245:EE23:21AD:FFFF:622C",
972  SC_HINFO_IS_IPV6) == -1) {
973  goto end;
974  }
975  if (SCHInfoAddHostOSInfo("hpux11",
976  "8762:2352:6241:7245:EE23:21AD:2312:62FF",
977  SC_HINFO_IS_IPV6) == -1) {
978  goto end;
979  }
980  if (SCHInfoAddHostOSInfo("vista",
981  "8762:2352:6241:7245:EE23:21AD:2121:1212",
982  SC_HINFO_IS_IPV6) == -1) {
983  goto end;
984  }
985 
986  if (SCHInfoGetHostOSFlavour("2351:2512:6211:6246:235A:6242:2352:62AD") !=
988  goto end;
989  }
990  if (SCHInfoGetHostOSFlavour("2351:2512:6211:6246:235A:6242:2352:6FFFE") != -1) {
991  goto end;
992  }
993  if (SCHInfoGetHostOSFlavour("DD13:613D:F312:62DD:6213:421A:6212:2652") !=
995  goto end;
996  }
997  if (SCHInfoGetHostOSFlavour("DD13:613D:F312:62DD:6213:421A:6212:2222") != -1) {
998  goto end;
999  }
1000  if (SCHInfoGetHostOSFlavour("9891:2131:2151:6426:1342:674D:622F:2342") !=
1002  goto end;
1003  }
1004  if (SCHInfoGetHostOSFlavour("3525:2351:4223:6211:2311:2667:6242:2154") !=
1006  goto end;
1007  }
1008  if (SCHInfoGetHostOSFlavour("1511:6211:6726:7777:1212:2333:6222:7722") !=
1010  goto end;
1011  }
1012  if (SCHInfoGetHostOSFlavour("2666:6222:7222:2335:6223:7722:3425:2362") !=
1014  goto end;
1015  }
1016  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2312:622C") !=
1018  goto end;
1019  }
1020  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2412:622C") !=
1022  goto end;
1023  }
1024  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:FFFF:622C") !=
1026  goto end;
1027  }
1028  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2312:62FF") !=
1030  goto end;
1031  }
1032  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2121:1212") !=
1034  goto end;
1035  }
1036  if (SCHInfoGetHostOSFlavour("5222:6432:6432:2322:6662:3423:4322:DDDD") != -1) {
1037  goto end;
1038  }
1039  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2121:1DDD") !=
1041  goto end;
1042  }
1043  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:FFFF:2121:1DDD") !=
1045  goto end;
1046  }
1047  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2312:622C") !=
1049  goto end;
1050  }
1051  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE00:0000:0000:0000") !=
1053  goto end;
1054  }
1055  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:E000:0000:0000:0000") !=
1057  goto end;
1058  }
1059 
1060  result = 1;
1061 
1062  end:
1064  SCHInfoRestoreContextBackup();
1065 
1066  return result;
1067 }
1068 
1069 /**
1070  * \test Check that valid ipv6 addresses/netblocks are inserted into the host os
1071  * radix tree, and the host os api retrieves the right value for the host
1072  * os flavour, on supplying as arg an ipv6 address that has been added to
1073  * the host os radix tree.
1074  */
1075 static int SCHInfoTestValidIPV6Address08(void)
1076 {
1077  SCHInfoCreateContextBackup();
1078 
1079  struct in6_addr in6;
1080  int result = 0;
1081 
1082  if (SCHInfoAddHostOSInfo("linux",
1083  "2351:2512:6211:6246:235A:6242:2352:62AD",
1084  SC_HINFO_IS_IPV6) == -1) {
1085  goto end;
1086  }
1087  if (SCHInfoAddHostOSInfo("windows",
1088  "6961:6121:2132:6241:423A:2135:2461:621D",
1089  SC_HINFO_IS_IPV6) == -1) {
1090  goto end;
1091  }
1092  if (SCHInfoAddHostOSInfo("solaris",
1093  "DD13:613D:F312:62DD:6213:421A:6212:2652",
1094  SC_HINFO_IS_IPV6) == -1) {
1095  goto end;
1096  }
1097  if (SCHInfoAddHostOSInfo("hpux10",
1098  "9891:2131:2151:6426:1342:674D:622F:2342",
1099  SC_HINFO_IS_IPV6) == -1) {
1100  goto end;
1101  }
1102  if (SCHInfoAddHostOSInfo("linux",
1103  "3525:2351:4223:6211:2311:2667:6242:2154",
1104  SC_HINFO_IS_IPV6) == -1) {
1105  goto end;
1106  }
1107  if (SCHInfoAddHostOSInfo("vista",
1108  "1511:6211:6726:7777:1212:2333:6222:7722",
1109  SC_HINFO_IS_IPV6) == -1) {
1110  goto end;
1111  }
1112  if (SCHInfoAddHostOSInfo("solaris",
1113  "2666:6222:7222:2335:6223:7722:3425:2362",
1114  SC_HINFO_IS_IPV6) == -1) {
1115  goto end;
1116  }
1117  if (SCHInfoAddHostOSInfo("solaris",
1118  "8762:2352:6241:7245:EE23:21AD:2312:622C/68",
1119  SC_HINFO_IS_IPV6) == -1) {
1120  goto end;
1121  }
1122  if (SCHInfoAddHostOSInfo("linux",
1123  "8762:2352:6241:7245:EE23:21AD:2412:622C",
1124  SC_HINFO_IS_IPV6) == -1) {
1125  goto end;
1126  }
1127  if (SCHInfoAddHostOSInfo("windows",
1128  "8762:2352:6241:7245:EE23:21AD:FFFF:622C",
1129  SC_HINFO_IS_IPV6) == -1) {
1130  goto end;
1131  }
1132  if (SCHInfoAddHostOSInfo("hpux11",
1133  "8762:2352:6241:7245:EE23:21AD:2312:62FF",
1134  SC_HINFO_IS_IPV6) == -1) {
1135  goto end;
1136  }
1137  if (SCHInfoAddHostOSInfo("vista",
1138  "8762:2352:6241:7245:EE23:21AD:2121:1212",
1139  SC_HINFO_IS_IPV6) == -1) {
1140  goto end;
1141  }
1142  if (SCHInfoAddHostOSInfo("irix", "default", SC_HINFO_IS_IPV6) == -1) {
1143  goto end;
1144  }
1145 
1146  if (SCHInfoGetHostOSFlavour("2351:2512:6211:6246:235A:6242:2352:62AD") !=
1148  goto end;
1149  }
1150  if (SCHInfoGetHostOSFlavour("2351:2512:6211:6246:235A:6242:2352:6FFF") !=
1152  goto end;
1153  }
1154  if (SCHInfoGetHostOSFlavour("DD13:613D:F312:62DD:6213:421A:6212:2652") !=
1156  goto end;
1157  }
1158  if (SCHInfoGetHostOSFlavour("DD13:613D:F312:62DD:6213:421A:6212:2222") !=
1160  goto end;
1161  }
1162  if (SCHInfoGetHostOSFlavour("9891:2131:2151:6426:1342:674D:622F:2342") !=
1164  goto end;
1165  }
1166  if (SCHInfoGetHostOSFlavour("3525:2351:4223:6211:2311:2667:6242:2154") !=
1168  goto end;
1169  }
1170  if (SCHInfoGetHostOSFlavour("1511:6211:6726:7777:1212:2333:6222:7722") !=
1172  goto end;
1173  }
1174  if (SCHInfoGetHostOSFlavour("2666:6222:7222:2335:6223:7722:3425:2362") !=
1176  goto end;
1177  }
1178  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2312:622C") !=
1180  goto end;
1181  }
1182  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2412:622C") !=
1184  goto end;
1185  }
1186  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:FFFF:622C") !=
1188  goto end;
1189  }
1190  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2312:62FF") !=
1192  goto end;
1193  }
1194  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2121:1212") !=
1196  goto end;
1197  }
1198  if (SCHInfoGetHostOSFlavour("5222:6432:6432:2322:6662:3423:4322:DDDD") !=
1200  goto end;
1201  }
1202  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2121:1DDD") !=
1204  goto end;
1205  }
1206  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:FFFF:2121:1DDD") !=
1208  goto end;
1209  }
1210  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2312:622C") !=
1212  goto end;
1213  }
1214  if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE00:0000:0000:0000") !=
1216  goto end;
1217  }
1218  if (inet_pton(AF_INET6, "8762:2352:6241:7245:E000:0000:0000:0000", &in6) < 0) {
1219  goto end;
1220  }
1221  if (SCHInfoGetIPv6HostOSFlavour((uint8_t *)&in6) !=
1223  goto end;
1224  }
1225  if (inet_pton(AF_INET6, "AD23:2DDA:6D1D:A223:E235:0232:1241:1666", &in6) < 0) {
1226  goto end;
1227  }
1228  if (SCHInfoGetIPv6HostOSFlavour((uint8_t *)&in6) !=
1230  goto end;
1231  }
1232 
1233  result = 1;
1234 
1235  end:
1237  SCHInfoRestoreContextBackup();
1238 
1239  return result;
1240 }
1241 
1242 /**
1243  * \test Check that valid ipv4 addresses are inserted into the host os radix
1244  * tree, and the host os api retrieves the right value for the host os
1245  * flavour, on supplying as arg an ipv4 addresses that has been added to
1246  * the host os radix tree.
1247  */
1248 static int SCHInfoTestValidIPV4Address09(void)
1249 {
1250  SCHInfoCreateContextBackup();
1251 
1252  int result = 0;
1253 
1254  if (SCHInfoAddHostOSInfo("linux", "192.168.1.0", SC_HINFO_IS_IPV4) == -1) {
1255  goto end;
1256  }
1257  if (SCHInfoAddHostOSInfo("windows", "192.192.1.2", SC_HINFO_IS_IPV4) == -1) {
1258  goto end;
1259  }
1260  if (SCHInfoGetHostOSFlavour("192.168.1.0") !=
1262  goto end;
1263  }
1264  if (SCHInfoAddHostOSInfo("solaris", "192.168.1.0/16", SC_HINFO_IS_IPV4) == -1) {
1265  goto end;
1266  }
1267  if (SCHInfoAddHostOSInfo("macos", "192.168.1.0/20", SC_HINFO_IS_IPV4) == -1) {
1268  goto end;
1269  }
1270  if (SCHInfoGetHostOSFlavour("192.168.1.0") !=
1272  goto end;
1273  }
1274  if (SCHInfoAddHostOSInfo("vista", "192.168.50.128/25", SC_HINFO_IS_IPV4) == -1) {
1275  goto end;
1276  }
1277  if (SCHInfoGetHostOSFlavour("192.168.50.128") !=
1279  goto end;
1280  }
1281  if (SCHInfoAddHostOSInfo("irix", "192.168.50.128", SC_HINFO_IS_IPV4) == -1) {
1282  goto end;
1283  }
1284  if (SCHInfoGetHostOSFlavour("192.168.50.128") !=
1286  goto end;
1287  }
1288 
1289  if (SCHInfoGetHostOSFlavour("192.168.1.100") !=
1291  goto end;
1292  }
1293 
1294  struct sockaddr_in servaddr;
1295  memset(&servaddr, 0, sizeof(servaddr));
1296  if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0) {
1297  goto end;
1298  }
1299 
1300  SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, sc_hinfo_tree, 16);
1301 
1302  if (SCHInfoGetHostOSFlavour("192.168.1.100") !=
1304  goto end;
1305  }
1306 
1307  memset(&servaddr, 0, sizeof(servaddr));
1308  if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0) {
1309  goto end;
1310  }
1311  SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, sc_hinfo_tree, 20);
1312 
1313  if (SCHInfoGetHostOSFlavour("192.168.1.100") != -1) {
1314  goto end;
1315  }
1316  if (SCHInfoAddHostOSInfo("solaris", "192.168.1.0/16", SC_HINFO_IS_IPV4) == -1) {
1317  goto end;
1318  }
1319  if (SCHInfoAddHostOSInfo("macos", "192.168.1.0/20", SC_HINFO_IS_IPV4) == -1) {
1320  goto end;
1321  }
1322 
1323  /* 192.168.1.100 should match "macos" as its more specific than
1324  * "solaris". */
1325  if (SCHInfoGetHostOSFlavour("192.168.1.100") !=
1327  goto end;
1328  }
1329 
1330  /* Remove the 192.168.1.0/20 -> macos entry. */
1331  memset(&servaddr, 0, sizeof(servaddr));
1332  if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0) {
1333  goto end;
1334  }
1335  SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, sc_hinfo_tree, 20);
1336 
1337  if (SCHInfoGetHostOSFlavour("192.168.1.100") !=
1339  goto end;
1340  }
1341 
1342  /* Remove the 192.168.1.0/16 -> solaris entry. */
1343  memset(&servaddr, 0, sizeof(servaddr));
1344  if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0) {
1345  goto end;
1346  }
1347  SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, sc_hinfo_tree, 16);
1348 
1349  if (SCHInfoGetHostOSFlavour("192.168.1.100") != -1) {
1350  goto end;
1351  }
1352 
1353  result = 1;
1354 
1355  end:
1357  SCHInfoRestoreContextBackup();
1358 
1359  return result;
1360 }
1361 
1362 /**
1363  * \test Check the loading of host info from a configuration file.
1364  */
1365 static int SCHInfoTestLoadFromConfig01(void)
1366 {
1367  char config[] = "\
1368 %YAML 1.1\n\
1369 ---\n\
1370 host-os-policy:\n\
1371  bsd: [0.0.0.0/0]\n\
1372  windows: [10.0.0.0/8, 192.168.1.0/24]\n\
1373  linux: [10.0.0.5/32]\n\
1374 \n";
1375 
1376  int result = 0;
1377 
1378  SCHInfoCreateContextBackup();
1379 
1381  ConfInit();
1382  ConfYamlLoadString(config, strlen(config));
1383 
1385  if (SCHInfoGetHostOSFlavour("10.0.0.4") != OS_POLICY_WINDOWS)
1386  goto end;
1387  if (SCHInfoGetHostOSFlavour("10.0.0.5") != OS_POLICY_LINUX)
1388  goto end;
1389  if (SCHInfoGetHostOSFlavour("192.168.1.1") != OS_POLICY_WINDOWS)
1390  goto end;
1391  if (SCHInfoGetHostOSFlavour("172.168.1.1") != OS_POLICY_BSD)
1392  goto end;
1393 
1394  result = 1;
1395 
1396  end:
1397  ConfDeInit();
1399 
1400  SCHInfoRestoreContextBackup();
1401 
1402  return result;
1403 }
1404 
1405 /**
1406  * \test Check the loading of host info from a configuration file.
1407  */
1408 static int SCHInfoTestLoadFromConfig02(void)
1409 {
1410  char config[] = "\
1411 %YAML 1.1\n\
1412 ---\n\
1413 host-os-policy:\n\
1414  one-two: [0.0.0.0/0]\n\
1415  one-two-three:\n\
1416  four_five:\n\
1417  six-seven_eight: [10.0.0.0/8, 192.168.1.0/24]\n\
1418  nine_ten_eleven: [10.0.0.5/32]\n\
1419 \n";
1420 
1421  int result = 0;
1422 
1423  SCHInfoCreateContextBackup();
1424 
1426  ConfInit();
1427  ConfYamlLoadString(config, strlen(config));
1428 
1429  ConfNode *root = ConfGetNode("host-os-policy");
1430  if (root == NULL)
1431  goto end;
1432 
1433  int count = 0;
1434 
1435  ConfNode *policy;
1436  TAILQ_FOREACH(policy, &root->head, next) {
1437  switch (count) {
1438  case 0:
1439  if (strcmp("one-two", policy->name) != 0)
1440  goto end;
1441  break;
1442  case 1:
1443  if (strcmp("one-two-three", policy->name) != 0)
1444  goto end;
1445  break;
1446  case 2:
1447  if (strcmp("four-five", policy->name) != 0)
1448  goto end;
1449  break;
1450  case 3:
1451  if (strcmp("six-seven-eight", policy->name) != 0)
1452  goto end;
1453  break;
1454  case 4:
1455  if (strcmp("nine-ten-eleven", policy->name) != 0)
1456  goto end;
1457  break;
1458  }
1459  count++;
1460  }
1461 
1462  result = 1;
1463 
1464  end:
1465  ConfDeInit();
1467 
1468  SCHInfoRestoreContextBackup();
1469 
1470  return result;
1471 }
1472 
1473 /**
1474  * \test Check the loading of host info from a configuration file.
1475  */
1476 static int SCHInfoTestLoadFromConfig03(void)
1477 {
1478  char config[] = "\
1479 %YAML 1.1\n\
1480 ---\n\
1481 host-os-policy:\n\
1482  bsd-right: [0.0.0.1]\n\
1483  old-linux: [0.0.0.2]\n\
1484  old-solaris: [0.0.0.3]\n\
1485  windows: [0.0.0.4]\n\
1486  vista: [0.0.0.5]\n\
1487 \n";
1488 
1489  int result = 0;
1490 
1491  SCHInfoCreateContextBackup();
1492 
1494  ConfInit();
1495  ConfYamlLoadString(config, strlen(config));
1496 
1497  ConfNode *root = ConfGetNode("host-os-policy");
1498  if (root == NULL)
1499  goto end;
1500 
1501  ConfNode *policy;
1502  TAILQ_FOREACH(policy, &root->head, next) {
1503  if (SCMapEnumNameToValue(policy->name, sc_hinfo_os_policy_map) == -1) {
1504  printf("Invalid enum map inside\n");
1505  goto end;
1506  }
1507  }
1508 
1509  result = 1;
1510 
1511  end:
1512  ConfDeInit();
1514 
1515  SCHInfoRestoreContextBackup();
1516  return result;
1517 }
1518 
1519 /**
1520  * \test Check the loading of host info from a configuration file.
1521  */
1522 static int SCHInfoTestLoadFromConfig04(void)
1523 {
1524  char config[] = "\
1525 %YAML 1.1\n\
1526 ---\n\
1527 host-os-policy:\n\
1528  bsd_right: [0.0.0.1]\n\
1529  old_linux: [0.0.0.2]\n\
1530  old_solaris: [0.0.0.3]\n\
1531  windows: [0.0.0.4]\n\
1532  vista: [0.0.0.5]\n\
1533 \n";
1534 
1535  int result = 0;
1536 
1537  SCHInfoCreateContextBackup();
1538 
1540  ConfInit();
1541  ConfYamlLoadString(config, strlen(config));
1542 
1543  ConfNode *root = ConfGetNode("host-os-policy");
1544  if (root == NULL)
1545  goto end;
1546 
1547  ConfNode *policy;
1548  TAILQ_FOREACH(policy, &root->head, next) {
1549  if (SCMapEnumNameToValue(policy->name, sc_hinfo_os_policy_map) == -1) {
1550  printf("Invalid enum map inside\n");
1551  goto end;
1552  }
1553  }
1554 
1555  result = 1;
1556 
1557  end:
1558  ConfDeInit();
1560 
1561  SCHInfoRestoreContextBackup();
1562  return result;
1563 }
1564 
1565 /**
1566  * \test Check the loading of host info from a configuration file.
1567  */
1568 static int SCHInfoTestLoadFromConfig05(void)
1569 {
1570  char config[] = "\
1571 %YAML 1.1\n\
1572 ---\n\
1573 host-os-policy:\n\
1574  bsd_right: [0.0.0.1]\n\
1575  old_linux: [0.0.0.2]\n\
1576  old-solaris: [0.0.0.3]\n\
1577  windows: [0.0.0.4]\n\
1578  linux: [0.0.0.5]\n\
1579 \n";
1580 
1581  SCHInfoCreateContextBackup();
1582 
1584  ConfInit();
1585  ConfYamlLoadString(config, strlen(config));
1587 
1593  FAIL_IF (SCHInfoGetHostOSFlavour("0.0.0.0") != -1);
1594  FAIL_IF (SCHInfoGetHostOSFlavour("0.0.0.6") != -1);
1595 
1596  ConfDeInit();
1598  SCHInfoRestoreContextBackup();
1599  PASS;
1600 }
1601 
1602 #endif /* UNITTESTS */
1603 
1605 {
1606 
1607 #ifdef UNITTESTS
1608 
1609  UtRegisterTest("SCHInfoTesInvalidOSFlavour01",
1610  SCHInfoTestInvalidOSFlavour01);
1611  UtRegisterTest("SCHInfoTestInvalidIPV4Address02",
1612  SCHInfoTestInvalidIPV4Address02);
1613  UtRegisterTest("SCHInfoTestInvalidIPV6Address03",
1614  SCHInfoTestInvalidIPV6Address03);
1615  UtRegisterTest("SCHInfoTestValidIPV4Address04",
1616  SCHInfoTestValidIPV4Address04);
1617  UtRegisterTest("SCHInfoTestValidIPV4Address05",
1618  SCHInfoTestValidIPV4Address05);
1619  UtRegisterTest("SCHInfoTestValidIPV6Address06",
1620  SCHInfoTestValidIPV6Address06);
1621  UtRegisterTest("SCHInfoTestValidIPV6Address07",
1622  SCHInfoTestValidIPV6Address07);
1623  UtRegisterTest("SCHInfoTestValidIPV6Address08",
1624  SCHInfoTestValidIPV6Address08);
1625  UtRegisterTest("SCHInfoTestValidIPV4Address09",
1626  SCHInfoTestValidIPV4Address09);
1627 
1628  UtRegisterTest("SCHInfoTestLoadFromConfig01", SCHInfoTestLoadFromConfig01);
1629  UtRegisterTest("SCHInfoTestLoadFromConfig02", SCHInfoTestLoadFromConfig02);
1630  UtRegisterTest("SCHInfoTestLoadFromConfig03", SCHInfoTestLoadFromConfig03);
1631  UtRegisterTest("SCHInfoTestLoadFromConfig04", SCHInfoTestLoadFromConfig04);
1632  UtRegisterTest("SCHInfoTestLoadFromConfig05", SCHInfoTestLoadFromConfig05);
1633 #endif /* UNITTESTS */
1634 
1635 }
util-byte.h
SCRadixRemoveKeyIPV4Netblock
void SCRadixRemoveKeyIPV4Netblock(uint8_t *key_stream, SCRadixTree *tree, uint8_t netmask)
Removes an IPV4 address netblock key from the Radix tree.
Definition: util-radix-tree.c:1274
OS_POLICY_MACOS
@ OS_POLICY_MACOS
Definition: stream-tcp-reassemble.h:46
OS_POLICY_BSD_RIGHT
@ OS_POLICY_BSD_RIGHT
Definition: stream-tcp-reassemble.h:38
MaskIPNetblock
void MaskIPNetblock(uint8_t *stream, int netmask, int key_bitlen)
Culls the non-netmask portion of the IP address. For example an IP address 192.168....
Definition: util-ip.c:188
ConfNode_::val
char * val
Definition: conf.h:34
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
ConfGetNode
ConfNode * ConfGetNode(const char *name)
Get a ConfNode by name.
Definition: conf.c:176
SC_ERR_INVALID_IPV6_ADDR
@ SC_ERR_INVALID_IPV6_ADDR
Definition: util-error.h:48
SCRadixTree_
Structure for the radix tree.
Definition: util-radix-tree.h:86
OS_POLICY_HPUX10
@ OS_POLICY_HPUX10
Definition: stream-tcp-reassemble.h:43
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:350
SCRadixAddKeyIPV6
SCRadixNode * SCRadixAddKeyIPV6(uint8_t *key_stream, SCRadixTree *tree, void *user)
Adds a new IPV6 address to the Radix tree.
Definition: util-radix-tree.c:879
stream-tcp-reassemble.h
SCRadixFindKeyIPV4BestMatch
SCRadixNode * SCRadixFindKeyIPV4BestMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
Checks if an IPV4 address is present in the tree under a netblock.
Definition: util-radix-tree.c:1491
SCHInfoGetHostOSFlavour
int SCHInfoGetHostOSFlavour(const char *ip_addr_str)
Retrieves the host os flavour, given an ipv4/ipv6 address as a string.
Definition: util-host-os-info.c:248
sc_hinfo_os_policy_map
SCEnumCharMap sc_hinfo_os_policy_map[]
Definition: util-host-os-info.c:43
SCRadixFindKeyIPV6BestMatch
SCRadixNode * SCRadixFindKeyIPV6BestMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
Checks if an IPV6 address is present in the tree under a netblock.
Definition: util-radix-tree.c:1557
OS_POLICY_NONE
@ OS_POLICY_NONE
Definition: stream-tcp-reassemble.h:36
util-unittest.h
OS_POLICY_OLD_LINUX
@ OS_POLICY_OLD_LINUX
Definition: stream-tcp-reassemble.h:39
SCRadixAddKeyIPV4Netblock
SCRadixNode * SCRadixAddKeyIPV4Netblock(uint8_t *key_stream, SCRadixTree *tree, void *user, uint8_t netmask)
Adds a new IPV4 netblock to the Radix tree.
Definition: util-radix-tree.c:899
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
util-error.h
SCRadixReleaseRadixTree
void SCRadixReleaseRadixTree(SCRadixTree *tree)
Frees a Radix tree and all its nodes.
Definition: util-radix-tree.c:466
OS_POLICY_LINUX
@ OS_POLICY_LINUX
Definition: stream-tcp-reassemble.h:40
ValidateIPV4Address
struct in_addr * ValidateIPV4Address(const char *addr_str)
Validates an IPV4 address and returns the network endian arranged version of the IPV4 address.
Definition: util-ip.c:129
OS_POLICY_SOLARIS
@ OS_POLICY_SOLARIS
Definition: stream-tcp-reassemble.h:42
util-ip.h
SCHInfoGetIPv6HostOSFlavour
int SCHInfoGetIPv6HostOSFlavour(uint8_t *ipv6_addr)
Retrieves the host os flavour, given an ipv6 address in the raw address format.
Definition: util-host-os-info.c:310
SC_ERR_INVALID_IP_NETBLOCK
@ SC_ERR_INVALID_IP_NETBLOCK
Definition: util-error.h:46
SCHInfoRegisterTests
void SCHInfoRegisterTests(void)
Definition: util-host-os-info.c:1604
SC_HINFO_IS_IPV6
#define SC_HINFO_IS_IPV6
Definition: util-host-os-info.h:27
ConfYamlLoadString
int ConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
Definition: conf-yaml-loader.c:465
SCRadixCreateRadixTree
SCRadixTree * SCRadixCreateRadixTree(void(*Free)(void *), void(*PrintData)(void *))
Creates a new Radix tree.
Definition: util-radix-tree.c:427
SC_ERR_INVALID_ARGUMENT
@ SC_ERR_INVALID_ARGUMENT
Definition: util-error.h:43
TRUE
#define TRUE
Definition: suricata-common.h:33
FALSE
#define FALSE
Definition: suricata-common.h:34
OS_POLICY_BSD
@ OS_POLICY_BSD
Definition: stream-tcp-reassemble.h:37
conf-yaml-loader.h
stream-tcp-private.h
conf.h
util-radix-tree.h
ConfCreateContextBackup
void ConfCreateContextBackup(void)
Creates a backup of the conf_hash hash_table used by the conf API.
Definition: conf.c:699
SCHInfoAddHostOSInfo
int SCHInfoAddHostOSInfo(const char *host_os, const char *host_os_ip_range, int is_ipv4)
Used to add the host-os-info data obtained from the conf.
Definition: util-host-os-info.c:123
OS_POLICY_VISTA
@ OS_POLICY_VISTA
Definition: stream-tcp-reassemble.h:48
SC_ERR_INVALID_IPV4_ADDR
@ SC_ERR_INVALID_IPV4_ADDR
Definition: util-error.h:47
SCHInfoCleanResources
void SCHInfoCleanResources(void)
Definition: util-host-os-info.c:320
util-host-os-info.h
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
SC_HINFO_IS_IPV4
#define SC_HINFO_IS_IPV4
Definition: util-host-os-info.h:28
ValidateIPV6Address
struct in6_addr * ValidateIPV6Address(const char *addr_str)
Validates an IPV6 address and returns the network endian arranged version of the IPV6 addresss.
Definition: util-ip.c:159
SCMapEnumNameToValue
int SCMapEnumNameToValue(const char *enum_name, SCEnumCharMap *table)
Maps a string name to an enum value from the supplied table. Please specify the last element of any m...
Definition: util-enum.c:40
suricata-common.h
SCEnumCharMap_
Definition: util-enum.h:27
SCHInfoLoadFromConfig
void SCHInfoLoadFromConfig(void)
Load the host os policy information from the configuration.
Definition: util-host-os-info.c:335
ConfNode_::name
char * name
Definition: conf.h:33
SCRadixAddKeyIPV6Netblock
SCRadixNode * SCRadixAddKeyIPV6Netblock(uint8_t *key_stream, SCRadixTree *tree, void *user, uint8_t netmask)
Adds a new IPV6 netblock to the Radix tree.
Definition: util-radix-tree.c:919
OS_POLICY_OLD_SOLARIS
@ OS_POLICY_OLD_SOLARIS
Definition: stream-tcp-reassemble.h:41
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
ConfRestoreContextBackup
void ConfRestoreContextBackup(void)
Restores the backup of the hash_table present in backup_conf_hash back to conf_hash.
Definition: conf.c:711
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
OS_POLICY_HPUX11
@ OS_POLICY_HPUX11
Definition: stream-tcp-reassemble.h:44
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
ConfInit
void ConfInit(void)
Initialize the configuration system.
Definition: conf.c:113
SCHInfoGetIPv4HostOSFlavour
int SCHInfoGetIPv4HostOSFlavour(uint8_t *ipv4_addr)
Retrieves the host os flavour, given an ipv4 address in the raw address format.
Definition: util-host-os-info.c:292
SCFree
#define SCFree(p)
Definition: util-mem.h:61
ConfNode_
Definition: conf.h:32
SC_ERR_FATAL
@ SC_ERR_FATAL
Definition: util-error.h:203
SCRadixAddKeyIPV4
SCRadixNode * SCRadixAddKeyIPV4(uint8_t *key_stream, SCRadixTree *tree, void *user)
Adds a new IPV4 address to the Radix tree.
Definition: util-radix-tree.c:860
SC_ERR_MEM_ALLOC
@ SC_ERR_MEM_ALLOC
Definition: util-error.h:31
SC_ERR_INVALID_ENUM_MAP
@ SC_ERR_INVALID_ENUM_MAP
Definition: util-error.h:45
ConfDeInit
void ConfDeInit(void)
De-initializes the configuration system.
Definition: conf.c:722
OS_POLICY_WINDOWS
@ OS_POLICY_WINDOWS
Definition: stream-tcp-reassemble.h:47
OS_POLICY_WINDOWS2K3
@ OS_POLICY_WINDOWS2K3
Definition: stream-tcp-reassemble.h:49
util-enum.h
StringParseI32RangeCheck
int StringParseI32RangeCheck(int32_t *res, int base, uint16_t len, const char *str, int32_t min, int32_t max)
Definition: util-byte.c:704
OS_POLICY_IRIX
@ OS_POLICY_IRIX
Definition: stream-tcp-reassemble.h:45