pf_osfp.c (223637) | pf_osfp.c (240233) |
---|---|
1/* $OpenBSD: pf_osfp.c,v 1.14 2008/06/12 18:17:01 henning Exp $ */ 2 3/* 4 * Copyright (c) 2003 Mike Frantzen <frantzen@w4g.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 */ 19 | 1/* $OpenBSD: pf_osfp.c,v 1.14 2008/06/12 18:17:01 henning Exp $ */ 2 3/* 4 * Copyright (c) 2003 Mike Frantzen <frantzen@w4g.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 */ 19 |
20#ifdef __FreeBSD__ | |
21#include <sys/cdefs.h> | 20#include <sys/cdefs.h> |
22__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf_osfp.c 223637 2011-06-28 11:57:25Z bz $"); 23#endif | 21__FBSDID("$FreeBSD: head/sys/contrib/pf/net/pf_osfp.c 240233 2012-09-08 06:41:54Z glebius $"); |
24 25#include <sys/param.h> | 22 23#include <sys/param.h> |
24#include <sys/kernel.h> |
|
26#include <sys/socket.h> | 25#include <sys/socket.h> |
27#ifdef _KERNEL 28#include <sys/systm.h> 29#ifndef __FreeBSD__ 30#include <sys/pool.h> 31#endif 32#endif /* _KERNEL */ 33#include <sys/mbuf.h> | |
34 35#include <netinet/in.h> | 26 27#include <netinet/in.h> |
36#include <netinet/in_systm.h> | |
37#include <netinet/ip.h> 38#include <netinet/tcp.h> 39 40#include <net/if.h> 41#include <net/pfvar.h> 42 43#include <netinet/ip6.h> | 28#include <netinet/ip.h> 29#include <netinet/tcp.h> 30 31#include <net/if.h> 32#include <net/pfvar.h> 33 34#include <netinet/ip6.h> |
44#ifdef _KERNEL | |
45#include <netinet6/in6_var.h> | 35#include <netinet6/in6_var.h> |
46#endif | |
47 | 36 |
48 49#ifdef _KERNEL 50#ifdef __FreeBSD__ | 37static MALLOC_DEFINE(M_PFOSFP, "pf_osfp", "pf(4) operating system fingerprints"); |
51#define DPFPRINTF(format, x...) \ 52 if (V_pf_status.debug >= PF_DEBUG_NOISY) \ 53 printf(format , ##x) | 38#define DPFPRINTF(format, x...) \ 39 if (V_pf_status.debug >= PF_DEBUG_NOISY) \ 40 printf(format , ##x) |
54#else 55#define DPFPRINTF(format, x...) \ 56 if (pf_status.debug >= PF_DEBUG_NOISY) \ 57 printf(format , ##x) 58#endif 59#ifdef __FreeBSD__ 60typedef uma_zone_t pool_t; 61#else 62typedef struct pool pool_t; 63#endif | |
64 | 41 |
65#else 66/* Userland equivalents so we can lend code to tcpdump et al. */ 67 68#include <arpa/inet.h> 69#include <errno.h> 70#include <stdio.h> 71#include <stdlib.h> 72#include <string.h> 73#include <netdb.h> 74#define pool_t int 75#define pool_get(pool, flags) malloc(*(pool)) 76#define pool_put(pool, item) free(item) 77#define pool_init(pool, size, a, ao, f, m, p) (*(pool)) = (size) 78 79#ifdef __FreeBSD__ 80#define NTOHS(x) (x) = ntohs((u_int16_t)(x)) 81#endif 82 83#ifdef PFDEBUG 84#include <sys/stdarg.h> 85#define DPFPRINTF(format, x...) fprintf(stderr, format , ##x) 86#else 87#define DPFPRINTF(format, x...) ((void)0) 88#endif /* PFDEBUG */ 89#endif /* _KERNEL */ 90 91 92#ifdef __FreeBSD__ | |
93SLIST_HEAD(pf_osfp_list, pf_os_fingerprint); | 42SLIST_HEAD(pf_osfp_list, pf_os_fingerprint); |
94VNET_DEFINE(struct pf_osfp_list, pf_osfp_list); | 43static VNET_DEFINE(struct pf_osfp_list, pf_osfp_list) = 44 SLIST_HEAD_INITIALIZER(); |
95#define V_pf_osfp_list VNET(pf_osfp_list) | 45#define V_pf_osfp_list VNET(pf_osfp_list) |
96VNET_DEFINE(pool_t, pf_osfp_entry_pl); 97#define pf_osfp_entry_pl VNET(pf_osfp_entry_pl) 98VNET_DEFINE(pool_t, pf_osfp_pl); 99#define pf_osfp_pl VNET(pf_osfp_pl) 100#else 101SLIST_HEAD(pf_osfp_list, pf_os_fingerprint) pf_osfp_list; 102pool_t pf_osfp_entry_pl; 103pool_t pf_osfp_pl; 104#endif | |
105 | 46 |
106struct pf_os_fingerprint *pf_osfp_find(struct pf_osfp_list *, | 47static struct pf_osfp_enlist *pf_osfp_fingerprint_hdr(const struct ip *, 48 const struct ip6_hdr *, 49 const struct tcphdr *); 50static struct pf_os_fingerprint *pf_osfp_find(struct pf_osfp_list *, |
107 struct pf_os_fingerprint *, u_int8_t); | 51 struct pf_os_fingerprint *, u_int8_t); |
108struct pf_os_fingerprint *pf_osfp_find_exact(struct pf_osfp_list *, | 52static struct pf_os_fingerprint *pf_osfp_find_exact(struct pf_osfp_list *, |
109 struct pf_os_fingerprint *); | 53 struct pf_os_fingerprint *); |
110void pf_osfp_insert(struct pf_osfp_list *, | 54static void pf_osfp_insert(struct pf_osfp_list *, |
111 struct pf_os_fingerprint *); | 55 struct pf_os_fingerprint *); |
56#ifdef PFDEBUG 57static struct pf_os_fingerprint *pf_osfp_validate(void); 58#endif |
|
112 | 59 |
113 114#ifdef _KERNEL | |
115/* 116 * Passively fingerprint the OS of the host (IPv4 TCP SYN packets only) 117 * Returns the list of possible OSes. 118 */ 119struct pf_osfp_enlist * 120pf_osfp_fingerprint(struct pf_pdesc *pd, struct mbuf *m, int off, 121 const struct tcphdr *tcp) 122{ --- 12 unchanged lines hidden (view full) --- 135 ip = (struct ip *)NULL; 136 ip6 = mtod(m, struct ip6_hdr *); 137 } 138 if (!pf_pull_hdr(m, off, hdr, tcp->th_off << 2, NULL, NULL, 139 pd->af)) return (NULL); 140 141 return (pf_osfp_fingerprint_hdr(ip, ip6, (struct tcphdr *)hdr)); 142} | 60/* 61 * Passively fingerprint the OS of the host (IPv4 TCP SYN packets only) 62 * Returns the list of possible OSes. 63 */ 64struct pf_osfp_enlist * 65pf_osfp_fingerprint(struct pf_pdesc *pd, struct mbuf *m, int off, 66 const struct tcphdr *tcp) 67{ --- 12 unchanged lines hidden (view full) --- 80 ip = (struct ip *)NULL; 81 ip6 = mtod(m, struct ip6_hdr *); 82 } 83 if (!pf_pull_hdr(m, off, hdr, tcp->th_off << 2, NULL, NULL, 84 pd->af)) return (NULL); 85 86 return (pf_osfp_fingerprint_hdr(ip, ip6, (struct tcphdr *)hdr)); 87} |
143#endif /* _KERNEL */ | |
144 | 88 |
145struct pf_osfp_enlist * | 89static struct pf_osfp_enlist * |
146pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcp) 147{ 148 struct pf_os_fingerprint fp, *fpresult; 149 int cnt, optlen = 0; 150 const u_int8_t *optp; | 90pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcp) 91{ 92 struct pf_os_fingerprint fp, *fpresult; 93 int cnt, optlen = 0; 94 const u_int8_t *optp; |
151#ifdef _KERNEL | |
152 char srcname[128]; | 95 char srcname[128]; |
153#else 154 char srcname[NI_MAXHOST]; 155#endif | |
156 157 if ((tcp->th_flags & (TH_SYN|TH_ACK)) != TH_SYN) 158 return (NULL); 159 if (ip) { 160 if ((ip->ip_off & htons(IP_OFFMASK)) != 0) 161 return (NULL); 162 } 163 164 memset(&fp, 0, sizeof(fp)); 165 166 if (ip) { | 96 97 if ((tcp->th_flags & (TH_SYN|TH_ACK)) != TH_SYN) 98 return (NULL); 99 if (ip) { 100 if ((ip->ip_off & htons(IP_OFFMASK)) != 0) 101 return (NULL); 102 } 103 104 memset(&fp, 0, sizeof(fp)); 105 106 if (ip) { |
167#ifndef _KERNEL 168 struct sockaddr_in sin; 169#endif 170 | |
171 fp.fp_psize = ntohs(ip->ip_len); 172 fp.fp_ttl = ip->ip_ttl; 173 if (ip->ip_off & htons(IP_DF)) 174 fp.fp_flags |= PF_OSFP_DF; | 107 fp.fp_psize = ntohs(ip->ip_len); 108 fp.fp_ttl = ip->ip_ttl; 109 if (ip->ip_off & htons(IP_DF)) 110 fp.fp_flags |= PF_OSFP_DF; |
175#ifdef _KERNEL | |
176 strlcpy(srcname, inet_ntoa(ip->ip_src), sizeof(srcname)); | 111 strlcpy(srcname, inet_ntoa(ip->ip_src), sizeof(srcname)); |
177#else 178 memset(&sin, 0, sizeof(sin)); 179 sin.sin_family = AF_INET; 180 sin.sin_len = sizeof(struct sockaddr_in); 181 sin.sin_addr = ip->ip_src; 182 (void)getnameinfo((struct sockaddr *)&sin, 183 sizeof(struct sockaddr_in), srcname, sizeof(srcname), 184 NULL, 0, NI_NUMERICHOST); 185#endif | |
186 } 187#ifdef INET6 188 else if (ip6) { | 112 } 113#ifdef INET6 114 else if (ip6) { |
189#ifndef _KERNEL 190 struct sockaddr_in6 sin6; 191#endif 192 | |
193 /* jumbo payload? */ 194 fp.fp_psize = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen); 195 fp.fp_ttl = ip6->ip6_hlim; 196 fp.fp_flags |= PF_OSFP_DF; 197 fp.fp_flags |= PF_OSFP_INET6; | 115 /* jumbo payload? */ 116 fp.fp_psize = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen); 117 fp.fp_ttl = ip6->ip6_hlim; 118 fp.fp_flags |= PF_OSFP_DF; 119 fp.fp_flags |= PF_OSFP_INET6; |
198#ifdef _KERNEL | |
199 strlcpy(srcname, ip6_sprintf((struct in6_addr *)&ip6->ip6_src), 200 sizeof(srcname)); | 120 strlcpy(srcname, ip6_sprintf((struct in6_addr *)&ip6->ip6_src), 121 sizeof(srcname)); |
201#else 202 memset(&sin6, 0, sizeof(sin6)); 203 sin6.sin6_family = AF_INET6; 204 sin6.sin6_len = sizeof(struct sockaddr_in6); 205 sin6.sin6_addr = ip6->ip6_src; 206 (void)getnameinfo((struct sockaddr *)&sin6, 207 sizeof(struct sockaddr_in6), srcname, sizeof(srcname), 208 NULL, 0, NI_NUMERICHOST); 209#endif | |
210 } 211#endif 212 else 213 return (NULL); 214 fp.fp_wsize = ntohs(tcp->th_win); 215 216 217 cnt = (tcp->th_off << 2) - sizeof(*tcp); --- 61 unchanged lines hidden (view full) --- 279 (fp.fp_flags & PF_OSFP_TS0) ? "0" : "", 280 (fp.fp_flags & PF_OSFP_MSS_MOD) ? "%" : 281 (fp.fp_flags & PF_OSFP_MSS_DC) ? "*" : "", 282 fp.fp_mss, 283 (fp.fp_flags & PF_OSFP_WSCALE_MOD) ? "%" : 284 (fp.fp_flags & PF_OSFP_WSCALE_DC) ? "*" : "", 285 fp.fp_wscale); 286 | 122 } 123#endif 124 else 125 return (NULL); 126 fp.fp_wsize = ntohs(tcp->th_win); 127 128 129 cnt = (tcp->th_off << 2) - sizeof(*tcp); --- 61 unchanged lines hidden (view full) --- 191 (fp.fp_flags & PF_OSFP_TS0) ? "0" : "", 192 (fp.fp_flags & PF_OSFP_MSS_MOD) ? "%" : 193 (fp.fp_flags & PF_OSFP_MSS_DC) ? "*" : "", 194 fp.fp_mss, 195 (fp.fp_flags & PF_OSFP_WSCALE_MOD) ? "%" : 196 (fp.fp_flags & PF_OSFP_WSCALE_DC) ? "*" : "", 197 fp.fp_wscale); 198 |
287#ifdef __FreeBSD__ | |
288 if ((fpresult = pf_osfp_find(&V_pf_osfp_list, &fp, | 199 if ((fpresult = pf_osfp_find(&V_pf_osfp_list, &fp, |
289#else 290 if ((fpresult = pf_osfp_find(&pf_osfp_list, &fp, 291#endif | |
292 PF_OSFP_MAXTTL_OFFSET))) 293 return (&fpresult->fp_oses); 294 return (NULL); 295} 296 297/* Match a fingerprint ID against a list of OSes */ 298int 299pf_osfp_match(struct pf_osfp_enlist *list, pf_osfp_t os) --- 19 unchanged lines hidden (view full) --- 319 entry->fp_subtype_nm, os, entry->fp_os); 320 return (1); 321 } 322 } 323 DPFPRINTF("fingerprint 0x%x didn't match\n", os); 324 return (0); 325} 326 | 200 PF_OSFP_MAXTTL_OFFSET))) 201 return (&fpresult->fp_oses); 202 return (NULL); 203} 204 205/* Match a fingerprint ID against a list of OSes */ 206int 207pf_osfp_match(struct pf_osfp_enlist *list, pf_osfp_t os) --- 19 unchanged lines hidden (view full) --- 227 entry->fp_subtype_nm, os, entry->fp_os); 228 return (1); 229 } 230 } 231 DPFPRINTF("fingerprint 0x%x didn't match\n", os); 232 return (0); 233} 234 |
327/* Initialize the OS fingerprint system */ 328#ifdef __FreeBSD__ 329int 330#else 331void 332#endif 333pf_osfp_initialize(void) 334{ 335#if defined(__FreeBSD__) && defined(_KERNEL) 336 int error = ENOMEM; 337 338 do { 339 pf_osfp_entry_pl = pf_osfp_pl = NULL; 340 UMA_CREATE(pf_osfp_entry_pl, struct pf_osfp_entry, "pfospfen"); 341 UMA_CREATE(pf_osfp_pl, struct pf_os_fingerprint, "pfosfp"); 342 error = 0; 343 } while(0); 344 345 SLIST_INIT(&V_pf_osfp_list); 346#else 347 pool_init(&pf_osfp_entry_pl, sizeof(struct pf_osfp_entry), 0, 0, 0, 348 "pfosfpen", &pool_allocator_nointr); 349 pool_init(&pf_osfp_pl, sizeof(struct pf_os_fingerprint), 0, 0, 0, 350 "pfosfp", &pool_allocator_nointr); 351 SLIST_INIT(&pf_osfp_list); 352#endif 353 354#ifdef __FreeBSD__ 355#ifdef _KERNEL 356 return (error); 357#else 358 return (0); 359#endif 360#endif 361} 362 363#if defined(__FreeBSD__) && (_KERNEL) 364void 365pf_osfp_cleanup(void) 366{ 367 368 UMA_DESTROY(pf_osfp_entry_pl); 369 UMA_DESTROY(pf_osfp_pl); 370} 371#endif 372 | |
373/* Flush the fingerprint list */ 374void 375pf_osfp_flush(void) 376{ 377 struct pf_os_fingerprint *fp; 378 struct pf_osfp_entry *entry; 379 | 235/* Flush the fingerprint list */ 236void 237pf_osfp_flush(void) 238{ 239 struct pf_os_fingerprint *fp; 240 struct pf_osfp_entry *entry; 241 |
380#ifdef __FreeBSD__ | |
381 while ((fp = SLIST_FIRST(&V_pf_osfp_list))) { 382 SLIST_REMOVE_HEAD(&V_pf_osfp_list, fp_next); | 242 while ((fp = SLIST_FIRST(&V_pf_osfp_list))) { 243 SLIST_REMOVE_HEAD(&V_pf_osfp_list, fp_next); |
383#else 384 while ((fp = SLIST_FIRST(&pf_osfp_list))) { 385 SLIST_REMOVE_HEAD(&pf_osfp_list, fp_next); 386#endif | |
387 while ((entry = SLIST_FIRST(&fp->fp_oses))) { 388 SLIST_REMOVE_HEAD(&fp->fp_oses, fp_entry); | 244 while ((entry = SLIST_FIRST(&fp->fp_oses))) { 245 SLIST_REMOVE_HEAD(&fp->fp_oses, fp_entry); |
389 pool_put(&pf_osfp_entry_pl, entry); | 246 free(entry, M_PFOSFP); |
390 } | 247 } |
391 pool_put(&pf_osfp_pl, fp); | 248 free(fp, M_PFOSFP); |
392 } 393} 394 395 396/* Add a fingerprint */ 397int 398pf_osfp_add(struct pf_osfp_ioctl *fpioc) 399{ 400 struct pf_os_fingerprint *fp, fpadd; 401 struct pf_osfp_entry *entry; 402 | 249 } 250} 251 252 253/* Add a fingerprint */ 254int 255pf_osfp_add(struct pf_osfp_ioctl *fpioc) 256{ 257 struct pf_os_fingerprint *fp, fpadd; 258 struct pf_osfp_entry *entry; 259 |
260 PF_RULES_WASSERT(); 261 |
|
403 memset(&fpadd, 0, sizeof(fpadd)); 404 fpadd.fp_tcpopts = fpioc->fp_tcpopts; 405 fpadd.fp_wsize = fpioc->fp_wsize; 406 fpadd.fp_psize = fpioc->fp_psize; 407 fpadd.fp_mss = fpioc->fp_mss; 408 fpadd.fp_flags = fpioc->fp_flags; 409 fpadd.fp_optcnt = fpioc->fp_optcnt; 410 fpadd.fp_wscale = fpioc->fp_wscale; --- 20 unchanged lines hidden (view full) --- 431 (fpadd.fp_flags & PF_OSFP_MSS_DC) ? "*" : "", 432 fpadd.fp_mss, 433 (fpadd.fp_flags & PF_OSFP_WSCALE_MOD) ? "%" : 434 (fpadd.fp_flags & PF_OSFP_WSCALE_DC) ? "*" : "", 435 fpadd.fp_wscale, 436 fpioc->fp_os.fp_os); 437#endif 438 | 262 memset(&fpadd, 0, sizeof(fpadd)); 263 fpadd.fp_tcpopts = fpioc->fp_tcpopts; 264 fpadd.fp_wsize = fpioc->fp_wsize; 265 fpadd.fp_psize = fpioc->fp_psize; 266 fpadd.fp_mss = fpioc->fp_mss; 267 fpadd.fp_flags = fpioc->fp_flags; 268 fpadd.fp_optcnt = fpioc->fp_optcnt; 269 fpadd.fp_wscale = fpioc->fp_wscale; --- 20 unchanged lines hidden (view full) --- 290 (fpadd.fp_flags & PF_OSFP_MSS_DC) ? "*" : "", 291 fpadd.fp_mss, 292 (fpadd.fp_flags & PF_OSFP_WSCALE_MOD) ? "%" : 293 (fpadd.fp_flags & PF_OSFP_WSCALE_DC) ? "*" : "", 294 fpadd.fp_wscale, 295 fpioc->fp_os.fp_os); 296#endif 297 |
439#ifdef __FreeBSD__ | |
440 if ((fp = pf_osfp_find_exact(&V_pf_osfp_list, &fpadd))) { | 298 if ((fp = pf_osfp_find_exact(&V_pf_osfp_list, &fpadd))) { |
441#else 442 if ((fp = pf_osfp_find_exact(&pf_osfp_list, &fpadd))) { 443#endif | |
444 SLIST_FOREACH(entry, &fp->fp_oses, fp_entry) { 445 if (PF_OSFP_ENTRY_EQ(entry, &fpioc->fp_os)) 446 return (EEXIST); 447 } | 299 SLIST_FOREACH(entry, &fp->fp_oses, fp_entry) { 300 if (PF_OSFP_ENTRY_EQ(entry, &fpioc->fp_os)) 301 return (EEXIST); 302 } |
448 if ((entry = pool_get(&pf_osfp_entry_pl, 449#ifdef __FreeBSD__ 450 PR_NOWAIT)) == NULL) 451#else 452 PR_WAITOK|PR_LIMITFAIL)) == NULL) 453#endif | 303 if ((entry = malloc(sizeof(*entry), M_PFOSFP, M_NOWAIT)) 304 == NULL) |
454 return (ENOMEM); 455 } else { | 305 return (ENOMEM); 306 } else { |
456 if ((fp = pool_get(&pf_osfp_pl, 457#ifdef __FreeBSD__ 458 PR_NOWAIT)) == NULL) 459#else 460 PR_WAITOK|PR_LIMITFAIL)) == NULL) 461#endif | 307 if ((fp = malloc(sizeof(*fp), M_PFOSFP, M_ZERO | M_NOWAIT)) 308 == NULL) |
462 return (ENOMEM); | 309 return (ENOMEM); |
463 memset(fp, 0, sizeof(*fp)); | |
464 fp->fp_tcpopts = fpioc->fp_tcpopts; 465 fp->fp_wsize = fpioc->fp_wsize; 466 fp->fp_psize = fpioc->fp_psize; 467 fp->fp_mss = fpioc->fp_mss; 468 fp->fp_flags = fpioc->fp_flags; 469 fp->fp_optcnt = fpioc->fp_optcnt; 470 fp->fp_wscale = fpioc->fp_wscale; 471 fp->fp_ttl = fpioc->fp_ttl; 472 SLIST_INIT(&fp->fp_oses); | 310 fp->fp_tcpopts = fpioc->fp_tcpopts; 311 fp->fp_wsize = fpioc->fp_wsize; 312 fp->fp_psize = fpioc->fp_psize; 313 fp->fp_mss = fpioc->fp_mss; 314 fp->fp_flags = fpioc->fp_flags; 315 fp->fp_optcnt = fpioc->fp_optcnt; 316 fp->fp_wscale = fpioc->fp_wscale; 317 fp->fp_ttl = fpioc->fp_ttl; 318 SLIST_INIT(&fp->fp_oses); |
473 if ((entry = pool_get(&pf_osfp_entry_pl, 474#ifdef __FreeBSD__ 475 PR_NOWAIT)) == NULL) { 476#else 477 PR_WAITOK|PR_LIMITFAIL)) == NULL) { 478#endif 479 pool_put(&pf_osfp_pl, fp); | 319 if ((entry = malloc(sizeof(*entry), M_PFOSFP, M_NOWAIT)) 320 == NULL) { 321 free(fp, M_PFOSFP); |
480 return (ENOMEM); 481 } | 322 return (ENOMEM); 323 } |
482#ifdef __FreeBSD__ | |
483 pf_osfp_insert(&V_pf_osfp_list, fp); | 324 pf_osfp_insert(&V_pf_osfp_list, fp); |
484#else 485 pf_osfp_insert(&pf_osfp_list, fp); 486#endif | |
487 } 488 memcpy(entry, &fpioc->fp_os, sizeof(*entry)); 489 490 /* Make sure the strings are NUL terminated */ 491 entry->fp_class_nm[sizeof(entry->fp_class_nm)-1] = '\0'; 492 entry->fp_version_nm[sizeof(entry->fp_version_nm)-1] = '\0'; 493 entry->fp_subtype_nm[sizeof(entry->fp_subtype_nm)-1] = '\0'; 494 495 SLIST_INSERT_HEAD(&fp->fp_oses, entry, fp_entry); 496 497#ifdef PFDEBUG 498 if ((fp = pf_osfp_validate())) 499 printf("Invalid fingerprint list\n"); 500#endif /* PFDEBUG */ 501 return (0); 502} 503 504 505/* Find a fingerprint in the list */ | 325 } 326 memcpy(entry, &fpioc->fp_os, sizeof(*entry)); 327 328 /* Make sure the strings are NUL terminated */ 329 entry->fp_class_nm[sizeof(entry->fp_class_nm)-1] = '\0'; 330 entry->fp_version_nm[sizeof(entry->fp_version_nm)-1] = '\0'; 331 entry->fp_subtype_nm[sizeof(entry->fp_subtype_nm)-1] = '\0'; 332 333 SLIST_INSERT_HEAD(&fp->fp_oses, entry, fp_entry); 334 335#ifdef PFDEBUG 336 if ((fp = pf_osfp_validate())) 337 printf("Invalid fingerprint list\n"); 338#endif /* PFDEBUG */ 339 return (0); 340} 341 342 343/* Find a fingerprint in the list */ |
506struct pf_os_fingerprint * | 344static struct pf_os_fingerprint * |
507pf_osfp_find(struct pf_osfp_list *list, struct pf_os_fingerprint *find, 508 u_int8_t ttldiff) 509{ 510 struct pf_os_fingerprint *f; 511 512#define MATCH_INT(_MOD, _DC, _field) \ 513 if ((f->fp_flags & _DC) == 0) { \ 514 if ((f->fp_flags & _MOD) == 0) { \ --- 58 unchanged lines hidden (view full) --- 573 } 574 return (f); 575 } 576 577 return (NULL); 578} 579 580/* Find an exact fingerprint in the list */ | 345pf_osfp_find(struct pf_osfp_list *list, struct pf_os_fingerprint *find, 346 u_int8_t ttldiff) 347{ 348 struct pf_os_fingerprint *f; 349 350#define MATCH_INT(_MOD, _DC, _field) \ 351 if ((f->fp_flags & _DC) == 0) { \ 352 if ((f->fp_flags & _MOD) == 0) { \ --- 58 unchanged lines hidden (view full) --- 411 } 412 return (f); 413 } 414 415 return (NULL); 416} 417 418/* Find an exact fingerprint in the list */ |
581struct pf_os_fingerprint * | 419static struct pf_os_fingerprint * |
582pf_osfp_find_exact(struct pf_osfp_list *list, struct pf_os_fingerprint *find) 583{ 584 struct pf_os_fingerprint *f; 585 586 SLIST_FOREACH(f, list, fp_next) { 587 if (f->fp_tcpopts == find->fp_tcpopts && 588 f->fp_wsize == find->fp_wsize && 589 f->fp_psize == find->fp_psize && --- 4 unchanged lines hidden (view full) --- 594 f->fp_ttl == find->fp_ttl) 595 return (f); 596 } 597 598 return (NULL); 599} 600 601/* Insert a fingerprint into the list */ | 420pf_osfp_find_exact(struct pf_osfp_list *list, struct pf_os_fingerprint *find) 421{ 422 struct pf_os_fingerprint *f; 423 424 SLIST_FOREACH(f, list, fp_next) { 425 if (f->fp_tcpopts == find->fp_tcpopts && 426 f->fp_wsize == find->fp_wsize && 427 f->fp_psize == find->fp_psize && --- 4 unchanged lines hidden (view full) --- 432 f->fp_ttl == find->fp_ttl) 433 return (f); 434 } 435 436 return (NULL); 437} 438 439/* Insert a fingerprint into the list */ |
602void | 440static void |
603pf_osfp_insert(struct pf_osfp_list *list, struct pf_os_fingerprint *ins) 604{ 605 struct pf_os_fingerprint *f, *prev = NULL; 606 607 /* XXX need to go semi tree based. can key on tcp options */ 608 609 SLIST_FOREACH(f, list, fp_next) 610 prev = f; --- 9 unchanged lines hidden (view full) --- 620{ 621 struct pf_os_fingerprint *fp; 622 struct pf_osfp_entry *entry; 623 int num = fpioc->fp_getnum; 624 int i = 0; 625 626 627 memset(fpioc, 0, sizeof(*fpioc)); | 441pf_osfp_insert(struct pf_osfp_list *list, struct pf_os_fingerprint *ins) 442{ 443 struct pf_os_fingerprint *f, *prev = NULL; 444 445 /* XXX need to go semi tree based. can key on tcp options */ 446 447 SLIST_FOREACH(f, list, fp_next) 448 prev = f; --- 9 unchanged lines hidden (view full) --- 458{ 459 struct pf_os_fingerprint *fp; 460 struct pf_osfp_entry *entry; 461 int num = fpioc->fp_getnum; 462 int i = 0; 463 464 465 memset(fpioc, 0, sizeof(*fpioc)); |
628#ifdef __FreeBSD__ | |
629 SLIST_FOREACH(fp, &V_pf_osfp_list, fp_next) { | 466 SLIST_FOREACH(fp, &V_pf_osfp_list, fp_next) { |
630#else 631 SLIST_FOREACH(fp, &pf_osfp_list, fp_next) { 632#endif | |
633 SLIST_FOREACH(entry, &fp->fp_oses, fp_entry) { 634 if (i++ == num) { 635 fpioc->fp_mss = fp->fp_mss; 636 fpioc->fp_wsize = fp->fp_wsize; 637 fpioc->fp_flags = fp->fp_flags; 638 fpioc->fp_psize = fp->fp_psize; 639 fpioc->fp_ttl = fp->fp_ttl; 640 fpioc->fp_wscale = fp->fp_wscale; --- 4 unchanged lines hidden (view full) --- 645 } 646 } 647 } 648 649 return (EBUSY); 650} 651 652 | 467 SLIST_FOREACH(entry, &fp->fp_oses, fp_entry) { 468 if (i++ == num) { 469 fpioc->fp_mss = fp->fp_mss; 470 fpioc->fp_wsize = fp->fp_wsize; 471 fpioc->fp_flags = fp->fp_flags; 472 fpioc->fp_psize = fp->fp_psize; 473 fpioc->fp_ttl = fp->fp_ttl; 474 fpioc->fp_wscale = fp->fp_wscale; --- 4 unchanged lines hidden (view full) --- 479 } 480 } 481 } 482 483 return (EBUSY); 484} 485 486 |
487#ifdef PFDEBUG |
|
653/* Validate that each signature is reachable */ | 488/* Validate that each signature is reachable */ |
654struct pf_os_fingerprint * | 489static struct pf_os_fingerprint * |
655pf_osfp_validate(void) 656{ 657 struct pf_os_fingerprint *f, *f2, find; 658 | 490pf_osfp_validate(void) 491{ 492 struct pf_os_fingerprint *f, *f2, find; 493 |
659#ifdef __FreeBSD__ | |
660 SLIST_FOREACH(f, &V_pf_osfp_list, fp_next) { | 494 SLIST_FOREACH(f, &V_pf_osfp_list, fp_next) { |
661#else 662 SLIST_FOREACH(f, &pf_osfp_list, fp_next) { 663#endif | |
664 memcpy(&find, f, sizeof(find)); 665 666 /* We do a few MSS/th_win percolations to make things unique */ 667 if (find.fp_mss == 0) 668 find.fp_mss = 128; 669 if (f->fp_flags & PF_OSFP_WSIZE_MSS) 670 find.fp_wsize *= find.fp_mss; 671 else if (f->fp_flags & PF_OSFP_WSIZE_MTU) 672 find.fp_wsize *= (find.fp_mss + 40); 673 else if (f->fp_flags & PF_OSFP_WSIZE_MOD) 674 find.fp_wsize *= 2; | 495 memcpy(&find, f, sizeof(find)); 496 497 /* We do a few MSS/th_win percolations to make things unique */ 498 if (find.fp_mss == 0) 499 find.fp_mss = 128; 500 if (f->fp_flags & PF_OSFP_WSIZE_MSS) 501 find.fp_wsize *= find.fp_mss; 502 else if (f->fp_flags & PF_OSFP_WSIZE_MTU) 503 find.fp_wsize *= (find.fp_mss + 40); 504 else if (f->fp_flags & PF_OSFP_WSIZE_MOD) 505 find.fp_wsize *= 2; |
675#ifdef __FreeBSD__ | |
676 if (f != (f2 = pf_osfp_find(&V_pf_osfp_list, &find, 0))) { | 506 if (f != (f2 = pf_osfp_find(&V_pf_osfp_list, &find, 0))) { |
677#else 678 if (f != (f2 = pf_osfp_find(&pf_osfp_list, &find, 0))) { 679#endif | |
680 if (f2) 681 printf("Found \"%s %s %s\" instead of " 682 "\"%s %s %s\"\n", 683 SLIST_FIRST(&f2->fp_oses)->fp_class_nm, 684 SLIST_FIRST(&f2->fp_oses)->fp_version_nm, 685 SLIST_FIRST(&f2->fp_oses)->fp_subtype_nm, 686 SLIST_FIRST(&f->fp_oses)->fp_class_nm, 687 SLIST_FIRST(&f->fp_oses)->fp_version_nm, 688 SLIST_FIRST(&f->fp_oses)->fp_subtype_nm); 689 else 690 printf("Couldn't find \"%s %s %s\"\n", 691 SLIST_FIRST(&f->fp_oses)->fp_class_nm, 692 SLIST_FIRST(&f->fp_oses)->fp_version_nm, 693 SLIST_FIRST(&f->fp_oses)->fp_subtype_nm); 694 return (f); 695 } 696 } 697 return (NULL); 698} | 507 if (f2) 508 printf("Found \"%s %s %s\" instead of " 509 "\"%s %s %s\"\n", 510 SLIST_FIRST(&f2->fp_oses)->fp_class_nm, 511 SLIST_FIRST(&f2->fp_oses)->fp_version_nm, 512 SLIST_FIRST(&f2->fp_oses)->fp_subtype_nm, 513 SLIST_FIRST(&f->fp_oses)->fp_class_nm, 514 SLIST_FIRST(&f->fp_oses)->fp_version_nm, 515 SLIST_FIRST(&f->fp_oses)->fp_subtype_nm); 516 else 517 printf("Couldn't find \"%s %s %s\"\n", 518 SLIST_FIRST(&f->fp_oses)->fp_class_nm, 519 SLIST_FIRST(&f->fp_oses)->fp_version_nm, 520 SLIST_FIRST(&f->fp_oses)->fp_subtype_nm); 521 return (f); 522 } 523 } 524 return (NULL); 525} |
526#endif /* PFDEBUG */ |
|