FreeBSD/sys/netpfil/pf/pf_osfp.c
/* Find a fingerprint in the list */
Find a fingerprint in the list
Find a fingerprint in the list
static struct pf_os_fingerprint *
pf_osfp_find(struct pf_osfp_list *list, struct pf_os_fingerprint *find,
    u_int8_t ttldiff)
{
	struct pf_os_fingerprint *f;
#define	MATCH_INT(_MOD, _DC, _field)					\
	if ((f->fp_flags & _DC) == 0) {					\
		if ((f->fp_flags & _MOD) == 0) {			\
			if (f->_field != find->_field)			\
				continue;				\
		} else {						\
			if (f->_field == 0 || find->_field % f->_field)	\
				continue;				\
		}							\
	}
	SLIST_FOREACH(f, list, fp_next) {
		if (f->fp_tcpopts != find->fp_tcpopts ||
		    f->fp_optcnt != find->fp_optcnt ||
		    f->fp_ttl < find->fp_ttl ||
		    f->fp_ttl - find->fp_ttl > ttldiff ||
		    (f->fp_flags & (PF_OSFP_DF|PF_OSFP_TS0)) !=
		    (find->fp_flags & (PF_OSFP_DF|PF_OSFP_TS0)))
			continue;
		MATCH_INT(PF_OSFP_PSIZE_MOD, PF_OSFP_PSIZE_DC, fp_psize)
		MATCH_INT(PF_OSFP_MSS_MOD, PF_OSFP_MSS_DC, fp_mss)
		MATCH_INT(PF_OSFP_WSCALE_MOD, PF_OSFP_WSCALE_DC, fp_wscale)
		if ((f->fp_flags & PF_OSFP_WSIZE_DC) == 0) {
			if (f->fp_flags & PF_OSFP_WSIZE_MSS) {
				if (find->fp_mss == 0)
					continue;
#define	SMART_MSS	1460
				if ((find->fp_wsize % find->fp_mss ||
				    find->fp_wsize / find->fp_mss !=
				    f->fp_wsize) &&
				    (find->fp_wsize % SMART_MSS ||
				    find->fp_wsize / SMART_MSS !=
				    f->fp_wsize))
					continue;
			} else if (f->fp_flags & PF_OSFP_WSIZE_MTU) {
				if (find->fp_mss == 0)
					continue;
#define	MTUOFF		(sizeof(struct ip) + sizeof(struct tcphdr))
#define	SMART_MTU	(SMART_MSS + MTUOFF)
				if ((find->fp_wsize % (find->fp_mss + MTUOFF) ||
				    find->fp_wsize / (find->fp_mss + MTUOFF) !=
				    f->fp_wsize) &&
				    (find->fp_wsize % SMART_MTU ||
				    find->fp_wsize / SMART_MTU !=
				    f->fp_wsize))
					continue;
			} else if (f->fp_flags & PF_OSFP_WSIZE_MOD) {
				if (f->fp_wsize == 0 || find->fp_wsize %
				    f->fp_wsize)
					continue;
			} else {
				if (f->fp_wsize != find->fp_wsize)
					continue;
			}
		}
		return (f);
	}
	return (NULL);
}
static struct pf_os_fingerprint * pf_osfp_find ( struct pf_osfp_list * list , struct pf_os_fingerprint * find , u_int8_t ttldiff ) { struct pf_os_fingerprint * f ; #define MATCH_INT ( _MOD , _DC , _field ) 					\
	if ((f->fp_flags & _DC) == 0) {					\
		if ((f->fp_flags & _MOD) == 0) {			\
			if (f->_field != find->_field)			\
				continue;				\
		} else {						\
			if (f->_field == 0 || find->_field % f->_field)	\
				continue;				\
		}							\
	} SLIST_FOREACH ( f , list , fp_next ) { if ( f -> fp_tcpopts != find -> fp_tcpopts || f -> fp_optcnt != find -> fp_optcnt || f -> fp_ttl < find -> fp_ttl || f -> fp_ttl - find -> fp_ttl > ttldiff || ( f -> fp_flags & ( PF_OSFP_DF | PF_OSFP_TS0 ) ) != ( find -> fp_flags & ( PF_OSFP_DF | PF_OSFP_TS0 ) ) ) continue ; MATCH_INT ( PF_OSFP_PSIZE_MOD , PF_OSFP_PSIZE_DC , fp_psize ) MATCH_INT ( PF_OSFP_MSS_MOD , PF_OSFP_MSS_DC , fp_mss ) MATCH_INT ( PF_OSFP_WSCALE_MOD , PF_OSFP_WSCALE_DC , fp_wscale ) if ( ( f -> fp_flags & PF_OSFP_WSIZE_DC ) == 0 ) { if ( f -> fp_flags & PF_OSFP_WSIZE_MSS ) { if ( find -> fp_mss == 0 ) continue ; #define SMART_MSS 	1460 if ( ( find -> fp_wsize % find -> fp_mss || find -> fp_wsize / find -> fp_mss != f -> fp_wsize ) && ( find -> fp_wsize % SMART_MSS || find -> fp_wsize / SMART_MSS != f -> fp_wsize ) ) continue ; } else if ( f -> fp_flags & PF_OSFP_WSIZE_MTU ) { if ( find -> fp_mss == 0 ) continue ; #define MTUOFF 		(sizeof(struct ip) + sizeof(struct tcphdr)) #define SMART_MTU 	(SMART_MSS + MTUOFF) if ( ( find -> fp_wsize % ( find -> fp_mss + MTUOFF ) || find -> fp_wsize / ( find -> fp_mss + MTUOFF ) != f -> fp_wsize ) && ( find -> fp_wsize % SMART_MTU || find -> fp_wsize / SMART_MTU != f -> fp_wsize ) ) continue ; } else if ( f -> fp_flags & PF_OSFP_WSIZE_MOD ) { if ( f -> fp_wsize == 0 || find -> fp_wsize % f -> fp_wsize ) continue ; } else { if ( f -> fp_wsize != find -> fp_wsize ) continue ; } } return ( f ) ; } return ( NULL ) ; }
Find a fingerprint in the list
Find a fingerprint in the list
/*
 * Some "smart" NAT devices and DSL routers will tweak the MSS size and
 * will set it to whatever is suitable for the link type.
 */