diff options
Diffstat (limited to 'sys/contrib/pf/net/pf_osfp.c')
-rw-r--r-- | sys/contrib/pf/net/pf_osfp.c | 135 |
1 files changed, 57 insertions, 78 deletions
diff --git a/sys/contrib/pf/net/pf_osfp.c b/sys/contrib/pf/net/pf_osfp.c index 15dca8e..ce1efee 100644 --- a/sys/contrib/pf/net/pf_osfp.c +++ b/sys/contrib/pf/net/pf_osfp.c @@ -1,4 +1,5 @@ -/* $OpenBSD: pf_osfp.c,v 1.12 2006/12/13 18:14:10 itojun Exp $ */ +/* $FreeBSD$ */ +/* $OpenBSD: pf_osfp.c,v 1.10 2004/04/09 19:30:41 frantzen Exp $ */ /* * Copyright (c) 2003 Mike Frantzen <frantzen@w4g.org> @@ -32,17 +33,19 @@ #include <net/if.h> #include <net/pfvar.h> +#ifdef INET6 #include <netinet/ip6.h> -#ifdef _KERNEL -#include <netinet6/in6_var.h> -#endif - +#endif /* INET6 */ #ifdef _KERNEL # define DPFPRINTF(format, x...) \ if (pf_status.debug >= PF_DEBUG_NOISY) \ printf(format , ##x) +#ifdef __FreeBSD__ +typedef uma_zone_t pool_t; +#else typedef struct pool pool_t; +#endif #else /* Userland equivalents so we can lend code to tcpdump et al. */ @@ -52,12 +55,15 @@ typedef struct pool pool_t; # include <stdio.h> # include <stdlib.h> # include <string.h> -# include <netdb.h> # define pool_t int # define pool_get(pool, flags) malloc(*(pool)) # define pool_put(pool, item) free(item) # define pool_init(pool, size, a, ao, f, m, p) (*(pool)) = (size) +# ifdef __FreeBSD__ +# define NTOHS(x) (x) = ntohs((u_int16_t)(x)) +# endif + # ifdef PFDEBUG # include <sys/stdarg.h> # define DPFPRINTF(format, x...) fprintf(stderr, format , ##x) @@ -89,96 +95,38 @@ pf_osfp_fingerprint(struct pf_pdesc *pd, struct mbuf *m, int off, const struct tcphdr *tcp) { struct ip *ip; - struct ip6_hdr *ip6; char hdr[60]; - if ((pd->af != PF_INET && pd->af != PF_INET6) || - pd->proto != IPPROTO_TCP || (tcp->th_off << 2) < sizeof(*tcp)) + /* XXX don't have a fingerprint database for IPv6 :-( */ + if (pd->af != PF_INET || pd->proto != IPPROTO_TCP || (tcp->th_off << 2) + < sizeof(*tcp)) return (NULL); - if (pd->af == PF_INET) { - ip = mtod(m, struct ip *); - ip6 = (struct ip6_hdr *)NULL; - } else { - ip = (struct ip *)NULL; - ip6 = mtod(m, struct ip6_hdr *); - } - if (!pf_pull_hdr(m, off, hdr, tcp->th_off << 2, NULL, NULL, - pd->af)) return (NULL); + ip = mtod(m, struct ip *); + if (!pf_pull_hdr(m, off, hdr, tcp->th_off << 2, NULL, NULL, pd->af)) + return (NULL); - return (pf_osfp_fingerprint_hdr(ip, ip6, (struct tcphdr *)hdr)); + return (pf_osfp_fingerprint_hdr(ip, (struct tcphdr *)hdr)); } #endif /* _KERNEL */ struct pf_osfp_enlist * -pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcp) +pf_osfp_fingerprint_hdr(const struct ip *ip, const struct tcphdr *tcp) { struct pf_os_fingerprint fp, *fpresult; int cnt, optlen = 0; const u_int8_t *optp; -#ifdef _KERNEL - char srcname[128]; -#else - char srcname[NI_MAXHOST]; -#endif - if ((tcp->th_flags & (TH_SYN|TH_ACK)) != TH_SYN) + if ((tcp->th_flags & (TH_SYN|TH_ACK)) != TH_SYN || (ip->ip_off & + htons(IP_OFFMASK))) return (NULL); - if (ip) { - if ((ip->ip_off & htons(IP_OFFMASK)) != 0) - return (NULL); - } memset(&fp, 0, sizeof(fp)); - if (ip) { -#ifndef _KERNEL - struct sockaddr_in sin; -#endif - - fp.fp_psize = ntohs(ip->ip_len); - fp.fp_ttl = ip->ip_ttl; - if (ip->ip_off & htons(IP_DF)) - fp.fp_flags |= PF_OSFP_DF; -#ifdef _KERNEL - strlcpy(srcname, inet_ntoa(ip->ip_src), sizeof(srcname)); -#else - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_addr = ip->ip_src; - (void)getnameinfo((struct sockaddr *)&sin, - sizeof(struct sockaddr_in), srcname, sizeof(srcname), - NULL, 0, NI_NUMERICHOST); -#endif - } -#ifdef INET6 - else if (ip6) { -#ifndef _KERNEL - struct sockaddr_in6 sin6; -#endif - - /* jumbo payload? */ - fp.fp_psize = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen); - fp.fp_ttl = ip6->ip6_hlim; + fp.fp_psize = ntohs(ip->ip_len); + fp.fp_ttl = ip->ip_ttl; + if (ip->ip_off & htons(IP_DF)) fp.fp_flags |= PF_OSFP_DF; - fp.fp_flags |= PF_OSFP_INET6; -#ifdef _KERNEL - strlcpy(srcname, ip6_sprintf((struct in6_addr *)&ip6->ip6_src), - sizeof(srcname)); -#else - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_family = AF_INET6; - sin6.sin6_len = sizeof(struct sockaddr_in6); - sin6.sin6_addr = ip6->ip6_src; - (void)getnameinfo((struct sockaddr *)&sin6, - sizeof(struct sockaddr_in6), srcname, sizeof(srcname), - NULL, 0, NI_NUMERICHOST); -#endif - } -#endif - else - return (NULL); fp.fp_wsize = ntohs(tcp->th_win); @@ -241,7 +189,7 @@ pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const st DPFPRINTF("fingerprinted %s:%d %d:%d:%d:%d:%llx (%d) " "(TS=%s,M=%s%d,W=%s%d)\n", - srcname, ntohs(tcp->th_sport), + inet_ntoa(ip->ip_src), ntohs(tcp->th_sport), fp.fp_wsize, fp.fp_ttl, (fp.fp_flags & PF_OSFP_DF) != 0, fp.fp_psize, (long long int)fp.fp_tcpopts, fp.fp_optcnt, (fp.fp_flags & PF_OSFP_TS0) ? "0" : "", @@ -289,16 +237,47 @@ pf_osfp_match(struct pf_osfp_enlist *list, pf_osfp_t os) } /* Initialize the OS fingerprint system */ +#ifdef __FreeBSD__ +int +#else void +#endif pf_osfp_initialize(void) { +#if defined(__FreeBSD__) && defined(_KERNEL) + int error = ENOMEM; + + do { + pf_osfp_entry_pl = pf_osfp_pl = NULL; + UMA_CREATE(pf_osfp_entry_pl, struct pf_osfp_entry, "pfospfen"); + UMA_CREATE(pf_osfp_pl, struct pf_os_fingerprint, "pfosfp"); + error = 0; + } while(0); +#else pool_init(&pf_osfp_entry_pl, sizeof(struct pf_osfp_entry), 0, 0, 0, "pfosfpen", &pool_allocator_nointr); pool_init(&pf_osfp_pl, sizeof(struct pf_os_fingerprint), 0, 0, 0, "pfosfp", &pool_allocator_nointr); +#endif SLIST_INIT(&pf_osfp_list); +#ifdef __FreeBSD__ +#ifdef _KERNEL + return (error); +#else + return (0); +#endif +#endif } +#if defined(__FreeBSD__) && (_KERNEL) +void +pf_osfp_cleanup(void) +{ + UMA_DESTROY(pf_osfp_entry_pl); + UMA_DESTROY(pf_osfp_pl); +} +#endif + /* Flush the fingerprint list */ void pf_osfp_flush(void) |