]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/contrib/pf/net/pf_norm.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / contrib / pf / net / pf_norm.c
1 /*      $OpenBSD: pf_norm.c,v 1.107 2006/04/16 00:59:52 pascoe Exp $ */
2
3 /*
4  * Copyright 2001 Niels Provos <provos@citi.umich.edu>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #ifdef __FreeBSD__
29 #include "opt_inet.h"
30 #include "opt_inet6.h"
31 #include "opt_pf.h"
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #ifdef DEV_PFLOG
37 #define NPFLOG DEV_PFLOG
38 #else
39 #define NPFLOG 0
40 #endif
41 #else
42 #include "pflog.h"
43 #endif
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/mbuf.h>
48 #include <sys/filio.h>
49 #include <sys/fcntl.h>
50 #include <sys/socket.h>
51 #include <sys/kernel.h>
52 #include <sys/time.h>
53 #ifndef __FreeBSD__
54 #include <sys/pool.h>
55
56 #include <dev/rndvar.h>
57 #endif
58 #include <net/if.h>
59 #include <net/if_types.h>
60 #include <net/bpf.h>
61 #include <net/route.h>
62 #include <net/if_pflog.h>
63
64 #include <netinet/in.h>
65 #include <netinet/in_var.h>
66 #include <netinet/in_systm.h>
67 #include <netinet/ip.h>
68 #include <netinet/ip_var.h>
69 #include <netinet/tcp.h>
70 #include <netinet/tcp_seq.h>
71 #include <netinet/udp.h>
72 #include <netinet/ip_icmp.h>
73
74 #ifdef INET6
75 #include <netinet/ip6.h>
76 #endif /* INET6 */
77
78 #include <net/pfvar.h>
79
80 #ifndef __FreeBSD__
81 #include <inttypes.h>
82
83 struct pf_frent {
84         LIST_ENTRY(pf_frent) fr_next;
85         struct ip *fr_ip;
86         struct mbuf *fr_m;
87 };
88
89 struct pf_frcache {
90         LIST_ENTRY(pf_frcache) fr_next;
91         uint16_t        fr_off;
92         uint16_t        fr_end;
93 };
94 #endif
95
96 #define PFFRAG_SEENLAST 0x0001          /* Seen the last fragment for this */
97 #define PFFRAG_NOBUFFER 0x0002          /* Non-buffering fragment cache */
98 #define PFFRAG_DROP     0x0004          /* Drop all fragments */
99 #define BUFFER_FRAGMENTS(fr)    (!((fr)->fr_flags & PFFRAG_NOBUFFER))
100
101 #ifndef __FreeBSD__
102 struct pf_fragment {
103         RB_ENTRY(pf_fragment) fr_entry;
104         TAILQ_ENTRY(pf_fragment) frag_next;
105         struct in_addr  fr_src;
106         struct in_addr  fr_dst;
107         u_int8_t        fr_p;           /* protocol of this fragment */
108         u_int8_t        fr_flags;       /* status flags */
109         u_int16_t       fr_id;          /* fragment id for reassemble */
110         u_int16_t       fr_max;         /* fragment data max */
111         u_int32_t       fr_timeout;
112 #define fr_queue        fr_u.fru_queue
113 #define fr_cache        fr_u.fru_cache
114         union {
115                 LIST_HEAD(pf_fragq, pf_frent) fru_queue;        /* buffering */
116                 LIST_HEAD(pf_cacheq, pf_frcache) fru_cache;     /* non-buf */
117         } fr_u;
118 };
119 #endif
120
121 TAILQ_HEAD(pf_fragqueue, pf_fragment)   pf_fragqueue;
122 TAILQ_HEAD(pf_cachequeue, pf_fragment)  pf_cachequeue;
123
124 #ifndef __FreeBSD__
125 static __inline int      pf_frag_compare(struct pf_fragment *,
126                             struct pf_fragment *);
127 #else
128 static int       pf_frag_compare(struct pf_fragment *,
129                             struct pf_fragment *);
130 #endif
131 RB_HEAD(pf_frag_tree, pf_fragment)      pf_frag_tree, pf_cache_tree;
132 RB_PROTOTYPE(pf_frag_tree, pf_fragment, fr_entry, pf_frag_compare);
133 RB_GENERATE(pf_frag_tree, pf_fragment, fr_entry, pf_frag_compare);
134
135 /* Private prototypes */
136 void                     pf_ip2key(struct pf_fragment *, struct ip *);
137 void                     pf_remove_fragment(struct pf_fragment *);
138 void                     pf_flush_fragments(void);
139 void                     pf_free_fragment(struct pf_fragment *);
140 struct pf_fragment      *pf_find_fragment(struct ip *, struct pf_frag_tree *);
141 struct mbuf             *pf_reassemble(struct mbuf **, struct pf_fragment **,
142                             struct pf_frent *, int);
143 struct mbuf             *pf_fragcache(struct mbuf **, struct ip*,
144                             struct pf_fragment **, int, int, int *);
145 int                      pf_normalize_tcpopt(struct pf_rule *, struct mbuf *,
146                             struct tcphdr *, int);
147
148 #define DPFPRINTF(x) do {                               \
149         if (pf_status.debug >= PF_DEBUG_MISC) {         \
150                 printf("%s: ", __func__);               \
151                 printf x ;                              \
152         }                                               \
153 } while(0)
154
155 /* Globals */
156 #ifdef __FreeBSD__
157 uma_zone_t               pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
158 uma_zone_t               pf_state_scrub_pl;
159 #else
160 struct pool              pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
161 struct pool              pf_state_scrub_pl;
162 #endif
163 int                      pf_nfrents, pf_ncache;
164
165 void
166 pf_normalize_init(void)
167 {
168 #ifdef __FreeBSD__
169         /*
170          * XXX
171          * No high water mark support(It's hint not hard limit).
172          * uma_zone_set_max(pf_frag_pl, PFFRAG_FRAG_HIWAT);
173          */
174         uma_zone_set_max(pf_frent_pl, PFFRAG_FRENT_HIWAT);
175         uma_zone_set_max(pf_cache_pl, PFFRAG_FRCACHE_HIWAT);
176         uma_zone_set_max(pf_cent_pl, PFFRAG_FRCENT_HIWAT);
177 #else
178         pool_init(&pf_frent_pl, sizeof(struct pf_frent), 0, 0, 0, "pffrent",
179             NULL);
180         pool_init(&pf_frag_pl, sizeof(struct pf_fragment), 0, 0, 0, "pffrag",
181             NULL);
182         pool_init(&pf_cache_pl, sizeof(struct pf_fragment), 0, 0, 0,
183             "pffrcache", NULL);
184         pool_init(&pf_cent_pl, sizeof(struct pf_frcache), 0, 0, 0, "pffrcent",
185             NULL);
186         pool_init(&pf_state_scrub_pl, sizeof(struct pf_state_scrub), 0, 0, 0,
187             "pfstscr", NULL);
188
189         pool_sethiwat(&pf_frag_pl, PFFRAG_FRAG_HIWAT);
190         pool_sethardlimit(&pf_frent_pl, PFFRAG_FRENT_HIWAT, NULL, 0);
191         pool_sethardlimit(&pf_cache_pl, PFFRAG_FRCACHE_HIWAT, NULL, 0);
192         pool_sethardlimit(&pf_cent_pl, PFFRAG_FRCENT_HIWAT, NULL, 0);
193 #endif
194
195         TAILQ_INIT(&pf_fragqueue);
196         TAILQ_INIT(&pf_cachequeue);
197 }
198
199 #ifdef __FreeBSD__
200 static int
201 #else
202 static __inline int
203 #endif
204 pf_frag_compare(struct pf_fragment *a, struct pf_fragment *b)
205 {
206         int     diff;
207
208         if ((diff = a->fr_id - b->fr_id))
209                 return (diff);
210         else if ((diff = a->fr_p - b->fr_p))
211                 return (diff);
212         else if (a->fr_src.s_addr < b->fr_src.s_addr)
213                 return (-1);
214         else if (a->fr_src.s_addr > b->fr_src.s_addr)
215                 return (1);
216         else if (a->fr_dst.s_addr < b->fr_dst.s_addr)
217                 return (-1);
218         else if (a->fr_dst.s_addr > b->fr_dst.s_addr)
219                 return (1);
220         return (0);
221 }
222
223 void
224 pf_purge_expired_fragments(void)
225 {
226         struct pf_fragment      *frag;
227         u_int32_t                expire = time_second -
228                                     pf_default_rule.timeout[PFTM_FRAG];
229
230         while ((frag = TAILQ_LAST(&pf_fragqueue, pf_fragqueue)) != NULL) {
231 #ifdef __FreeBSD__
232                 KASSERT((BUFFER_FRAGMENTS(frag)),
233                         ("BUFFER_FRAGMENTS(frag) == 0: %s", __FUNCTION__));
234 #else
235                 KASSERT(BUFFER_FRAGMENTS(frag));
236 #endif
237                 if (frag->fr_timeout > expire)
238                         break;
239
240                 DPFPRINTF(("expiring %d(%p)\n", frag->fr_id, frag));
241                 pf_free_fragment(frag);
242         }
243
244         while ((frag = TAILQ_LAST(&pf_cachequeue, pf_cachequeue)) != NULL) {
245 #ifdef __FreeBSD__
246                 KASSERT((!BUFFER_FRAGMENTS(frag)),
247                         ("BUFFER_FRAGMENTS(frag) != 0: %s", __FUNCTION__));
248 #else
249                 KASSERT(!BUFFER_FRAGMENTS(frag));
250 #endif
251                 if (frag->fr_timeout > expire)
252                         break;
253
254                 DPFPRINTF(("expiring %d(%p)\n", frag->fr_id, frag));
255                 pf_free_fragment(frag);
256 #ifdef __FreeBSD__
257                 KASSERT((TAILQ_EMPTY(&pf_cachequeue) ||
258                     TAILQ_LAST(&pf_cachequeue, pf_cachequeue) != frag),
259                     ("!(TAILQ_EMPTY() || TAILQ_LAST() == farg): %s",
260                     __FUNCTION__));
261 #else
262                 KASSERT(TAILQ_EMPTY(&pf_cachequeue) ||
263                     TAILQ_LAST(&pf_cachequeue, pf_cachequeue) != frag);
264 #endif
265         }
266 }
267
268 /*
269  * Try to flush old fragments to make space for new ones
270  */
271
272 void
273 pf_flush_fragments(void)
274 {
275         struct pf_fragment      *frag;
276         int                      goal;
277
278         goal = pf_nfrents * 9 / 10;
279         DPFPRINTF(("trying to free > %d frents\n",
280             pf_nfrents - goal));
281         while (goal < pf_nfrents) {
282                 frag = TAILQ_LAST(&pf_fragqueue, pf_fragqueue);
283                 if (frag == NULL)
284                         break;
285                 pf_free_fragment(frag);
286         }
287
288
289         goal = pf_ncache * 9 / 10;
290         DPFPRINTF(("trying to free > %d cache entries\n",
291             pf_ncache - goal));
292         while (goal < pf_ncache) {
293                 frag = TAILQ_LAST(&pf_cachequeue, pf_cachequeue);
294                 if (frag == NULL)
295                         break;
296                 pf_free_fragment(frag);
297         }
298 }
299
300 /* Frees the fragments and all associated entries */
301
302 void
303 pf_free_fragment(struct pf_fragment *frag)
304 {
305         struct pf_frent         *frent;
306         struct pf_frcache       *frcache;
307
308         /* Free all fragments */
309         if (BUFFER_FRAGMENTS(frag)) {
310                 for (frent = LIST_FIRST(&frag->fr_queue); frent;
311                     frent = LIST_FIRST(&frag->fr_queue)) {
312                         LIST_REMOVE(frent, fr_next);
313
314                         m_freem(frent->fr_m);
315                         pool_put(&pf_frent_pl, frent);
316                         pf_nfrents--;
317                 }
318         } else {
319                 for (frcache = LIST_FIRST(&frag->fr_cache); frcache;
320                     frcache = LIST_FIRST(&frag->fr_cache)) {
321                         LIST_REMOVE(frcache, fr_next);
322
323 #ifdef __FreeBSD__
324                         KASSERT((LIST_EMPTY(&frag->fr_cache) ||
325                             LIST_FIRST(&frag->fr_cache)->fr_off >
326                             frcache->fr_end),
327                             ("! (LIST_EMPTY() || LIST_FIRST()->fr_off >"
328                              " frcache->fr_end): %s", __FUNCTION__));
329 #else
330                         KASSERT(LIST_EMPTY(&frag->fr_cache) ||
331                             LIST_FIRST(&frag->fr_cache)->fr_off >
332                             frcache->fr_end);
333 #endif
334
335                         pool_put(&pf_cent_pl, frcache);
336                         pf_ncache--;
337                 }
338         }
339
340         pf_remove_fragment(frag);
341 }
342
343 void
344 pf_ip2key(struct pf_fragment *key, struct ip *ip)
345 {
346         key->fr_p = ip->ip_p;
347         key->fr_id = ip->ip_id;
348         key->fr_src.s_addr = ip->ip_src.s_addr;
349         key->fr_dst.s_addr = ip->ip_dst.s_addr;
350 }
351
352 struct pf_fragment *
353 pf_find_fragment(struct ip *ip, struct pf_frag_tree *tree)
354 {
355         struct pf_fragment       key;
356         struct pf_fragment      *frag;
357
358         pf_ip2key(&key, ip);
359
360         frag = RB_FIND(pf_frag_tree, tree, &key);
361         if (frag != NULL) {
362                 /* XXX Are we sure we want to update the timeout? */
363                 frag->fr_timeout = time_second;
364                 if (BUFFER_FRAGMENTS(frag)) {
365                         TAILQ_REMOVE(&pf_fragqueue, frag, frag_next);
366                         TAILQ_INSERT_HEAD(&pf_fragqueue, frag, frag_next);
367                 } else {
368                         TAILQ_REMOVE(&pf_cachequeue, frag, frag_next);
369                         TAILQ_INSERT_HEAD(&pf_cachequeue, frag, frag_next);
370                 }
371         }
372
373         return (frag);
374 }
375
376 /* Removes a fragment from the fragment queue and frees the fragment */
377
378 void
379 pf_remove_fragment(struct pf_fragment *frag)
380 {
381         if (BUFFER_FRAGMENTS(frag)) {
382                 RB_REMOVE(pf_frag_tree, &pf_frag_tree, frag);
383                 TAILQ_REMOVE(&pf_fragqueue, frag, frag_next);
384                 pool_put(&pf_frag_pl, frag);
385         } else {
386                 RB_REMOVE(pf_frag_tree, &pf_cache_tree, frag);
387                 TAILQ_REMOVE(&pf_cachequeue, frag, frag_next);
388                 pool_put(&pf_cache_pl, frag);
389         }
390 }
391
392 #define FR_IP_OFF(fr)   ((ntohs((fr)->fr_ip->ip_off) & IP_OFFMASK) << 3)
393 struct mbuf *
394 pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
395     struct pf_frent *frent, int mff)
396 {
397         struct mbuf     *m = *m0, *m2;
398         struct pf_frent *frea, *next;
399         struct pf_frent *frep = NULL;
400         struct ip       *ip = frent->fr_ip;
401         int              hlen = ip->ip_hl << 2;
402         u_int16_t        off = (ntohs(ip->ip_off) & IP_OFFMASK) << 3;
403         u_int16_t        ip_len = ntohs(ip->ip_len) - ip->ip_hl * 4;
404         u_int16_t        max = ip_len + off;
405
406 #ifdef __FreeBSD__
407         KASSERT((*frag == NULL || BUFFER_FRAGMENTS(*frag)),
408             ("! (*frag == NULL || BUFFER_FRAGMENTS(*frag)): %s", __FUNCTION__));
409 #else
410         KASSERT(*frag == NULL || BUFFER_FRAGMENTS(*frag));
411 #endif
412
413         /* Strip off ip header */
414         m->m_data += hlen;
415         m->m_len -= hlen;
416
417         /* Create a new reassembly queue for this packet */
418         if (*frag == NULL) {
419                 *frag = pool_get(&pf_frag_pl, PR_NOWAIT);
420                 if (*frag == NULL) {
421                         pf_flush_fragments();
422                         *frag = pool_get(&pf_frag_pl, PR_NOWAIT);
423                         if (*frag == NULL)
424                                 goto drop_fragment;
425                 }
426
427                 (*frag)->fr_flags = 0;
428                 (*frag)->fr_max = 0;
429                 (*frag)->fr_src = frent->fr_ip->ip_src;
430                 (*frag)->fr_dst = frent->fr_ip->ip_dst;
431                 (*frag)->fr_p = frent->fr_ip->ip_p;
432                 (*frag)->fr_id = frent->fr_ip->ip_id;
433                 (*frag)->fr_timeout = time_second;
434                 LIST_INIT(&(*frag)->fr_queue);
435
436                 RB_INSERT(pf_frag_tree, &pf_frag_tree, *frag);
437                 TAILQ_INSERT_HEAD(&pf_fragqueue, *frag, frag_next);
438
439                 /* We do not have a previous fragment */
440                 frep = NULL;
441                 goto insert;
442         }
443
444         /*
445          * Find a fragment after the current one:
446          *  - off contains the real shifted offset.
447          */
448         LIST_FOREACH(frea, &(*frag)->fr_queue, fr_next) {
449                 if (FR_IP_OFF(frea) > off)
450                         break;
451                 frep = frea;
452         }
453
454 #ifdef __FreeBSD__
455         KASSERT((frep != NULL || frea != NULL),
456             ("!(frep != NULL || frea != NULL): %s", __FUNCTION__));;
457 #else
458         KASSERT(frep != NULL || frea != NULL);
459 #endif
460
461         if (frep != NULL &&
462             FR_IP_OFF(frep) + ntohs(frep->fr_ip->ip_len) - frep->fr_ip->ip_hl *
463             4 > off)
464         {
465                 u_int16_t       precut;
466
467                 precut = FR_IP_OFF(frep) + ntohs(frep->fr_ip->ip_len) -
468                     frep->fr_ip->ip_hl * 4 - off;
469                 if (precut >= ip_len)
470                         goto drop_fragment;
471                 m_adj(frent->fr_m, precut);
472                 DPFPRINTF(("overlap -%d\n", precut));
473                 /* Enforce 8 byte boundaries */
474                 ip->ip_off = htons(ntohs(ip->ip_off) + (precut >> 3));
475                 off = (ntohs(ip->ip_off) & IP_OFFMASK) << 3;
476                 ip_len -= precut;
477                 ip->ip_len = htons(ip_len);
478         }
479
480         for (; frea != NULL && ip_len + off > FR_IP_OFF(frea);
481             frea = next)
482         {
483                 u_int16_t       aftercut;
484
485                 aftercut = ip_len + off - FR_IP_OFF(frea);
486                 DPFPRINTF(("adjust overlap %d\n", aftercut));
487                 if (aftercut < ntohs(frea->fr_ip->ip_len) - frea->fr_ip->ip_hl
488                     * 4)
489                 {
490                         frea->fr_ip->ip_len =
491                             htons(ntohs(frea->fr_ip->ip_len) - aftercut);
492                         frea->fr_ip->ip_off = htons(ntohs(frea->fr_ip->ip_off) +
493                             (aftercut >> 3));
494                         m_adj(frea->fr_m, aftercut);
495                         break;
496                 }
497
498                 /* This fragment is completely overlapped, lose it */
499                 next = LIST_NEXT(frea, fr_next);
500                 m_freem(frea->fr_m);
501                 LIST_REMOVE(frea, fr_next);
502                 pool_put(&pf_frent_pl, frea);
503                 pf_nfrents--;
504         }
505
506  insert:
507         /* Update maximum data size */
508         if ((*frag)->fr_max < max)
509                 (*frag)->fr_max = max;
510         /* This is the last segment */
511         if (!mff)
512                 (*frag)->fr_flags |= PFFRAG_SEENLAST;
513
514         if (frep == NULL)
515                 LIST_INSERT_HEAD(&(*frag)->fr_queue, frent, fr_next);
516         else
517                 LIST_INSERT_AFTER(frep, frent, fr_next);
518
519         /* Check if we are completely reassembled */
520         if (!((*frag)->fr_flags & PFFRAG_SEENLAST))
521                 return (NULL);
522
523         /* Check if we have all the data */
524         off = 0;
525         for (frep = LIST_FIRST(&(*frag)->fr_queue); frep; frep = next) {
526                 next = LIST_NEXT(frep, fr_next);
527
528                 off += ntohs(frep->fr_ip->ip_len) - frep->fr_ip->ip_hl * 4;
529                 if (off < (*frag)->fr_max &&
530                     (next == NULL || FR_IP_OFF(next) != off))
531                 {
532                         DPFPRINTF(("missing fragment at %d, next %d, max %d\n",
533                             off, next == NULL ? -1 : FR_IP_OFF(next),
534                             (*frag)->fr_max));
535                         return (NULL);
536                 }
537         }
538         DPFPRINTF(("%d < %d?\n", off, (*frag)->fr_max));
539         if (off < (*frag)->fr_max)
540                 return (NULL);
541
542         /* We have all the data */
543         frent = LIST_FIRST(&(*frag)->fr_queue);
544 #ifdef __FreeBSD__
545         KASSERT((frent != NULL), ("frent == NULL: %s", __FUNCTION__));
546 #else
547         KASSERT(frent != NULL);
548 #endif
549         if ((frent->fr_ip->ip_hl << 2) + off > IP_MAXPACKET) {
550                 DPFPRINTF(("drop: too big: %d\n", off));
551                 pf_free_fragment(*frag);
552                 *frag = NULL;
553                 return (NULL);
554         }
555         next = LIST_NEXT(frent, fr_next);
556
557         /* Magic from ip_input */
558         ip = frent->fr_ip;
559         m = frent->fr_m;
560         m2 = m->m_next;
561         m->m_next = NULL;
562         m_cat(m, m2);
563         pool_put(&pf_frent_pl, frent);
564         pf_nfrents--;
565         for (frent = next; frent != NULL; frent = next) {
566                 next = LIST_NEXT(frent, fr_next);
567
568                 m2 = frent->fr_m;
569                 pool_put(&pf_frent_pl, frent);
570                 pf_nfrents--;
571 #ifdef __FreeBSD__
572                 m->m_pkthdr.csum_flags &= m2->m_pkthdr.csum_flags;
573                 m->m_pkthdr.csum_data += m2->m_pkthdr.csum_data;
574 #endif
575                 m_cat(m, m2);
576         }
577 #ifdef __FreeBSD__
578         while (m->m_pkthdr.csum_data & 0xffff0000)
579                 m->m_pkthdr.csum_data = (m->m_pkthdr.csum_data & 0xffff) +
580                     (m->m_pkthdr.csum_data >> 16);
581 #endif
582
583         ip->ip_src = (*frag)->fr_src;
584         ip->ip_dst = (*frag)->fr_dst;
585
586         /* Remove from fragment queue */
587         pf_remove_fragment(*frag);
588         *frag = NULL;
589
590         hlen = ip->ip_hl << 2;
591         ip->ip_len = htons(off + hlen);
592         m->m_len += hlen;
593         m->m_data -= hlen;
594
595         /* some debugging cruft by sklower, below, will go away soon */
596         /* XXX this should be done elsewhere */
597         if (m->m_flags & M_PKTHDR) {
598                 int plen = 0;
599                 for (m2 = m; m2; m2 = m2->m_next)
600                         plen += m2->m_len;
601                 m->m_pkthdr.len = plen;
602         }
603
604         DPFPRINTF(("complete: %p(%d)\n", m, ntohs(ip->ip_len)));
605         return (m);
606
607  drop_fragment:
608         /* Oops - fail safe - drop packet */
609         pool_put(&pf_frent_pl, frent);
610         pf_nfrents--;
611         m_freem(m);
612         return (NULL);
613 }
614
615 struct mbuf *
616 pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
617     int drop, int *nomem)
618 {
619         struct mbuf             *m = *m0;
620         struct pf_frcache       *frp, *fra, *cur = NULL;
621         int                      ip_len = ntohs(h->ip_len) - (h->ip_hl << 2);
622         u_int16_t                off = ntohs(h->ip_off) << 3;
623         u_int16_t                max = ip_len + off;
624         int                      hosed = 0;
625
626 #ifdef __FreeBSD__
627         KASSERT((*frag == NULL || !BUFFER_FRAGMENTS(*frag)),
628             ("!(*frag == NULL || !BUFFER_FRAGMENTS(*frag)): %s", __FUNCTION__));
629 #else
630         KASSERT(*frag == NULL || !BUFFER_FRAGMENTS(*frag));
631 #endif
632
633         /* Create a new range queue for this packet */
634         if (*frag == NULL) {
635                 *frag = pool_get(&pf_cache_pl, PR_NOWAIT);
636                 if (*frag == NULL) {
637                         pf_flush_fragments();
638                         *frag = pool_get(&pf_cache_pl, PR_NOWAIT);
639                         if (*frag == NULL)
640                                 goto no_mem;
641                 }
642
643                 /* Get an entry for the queue */
644                 cur = pool_get(&pf_cent_pl, PR_NOWAIT);
645                 if (cur == NULL) {
646                         pool_put(&pf_cache_pl, *frag);
647                         *frag = NULL;
648                         goto no_mem;
649                 }
650                 pf_ncache++;
651
652                 (*frag)->fr_flags = PFFRAG_NOBUFFER;
653                 (*frag)->fr_max = 0;
654                 (*frag)->fr_src = h->ip_src;
655                 (*frag)->fr_dst = h->ip_dst;
656                 (*frag)->fr_p = h->ip_p;
657                 (*frag)->fr_id = h->ip_id;
658                 (*frag)->fr_timeout = time_second;
659
660                 cur->fr_off = off;
661                 cur->fr_end = max;
662                 LIST_INIT(&(*frag)->fr_cache);
663                 LIST_INSERT_HEAD(&(*frag)->fr_cache, cur, fr_next);
664
665                 RB_INSERT(pf_frag_tree, &pf_cache_tree, *frag);
666                 TAILQ_INSERT_HEAD(&pf_cachequeue, *frag, frag_next);
667
668                 DPFPRINTF(("fragcache[%d]: new %d-%d\n", h->ip_id, off, max));
669
670                 goto pass;
671         }
672
673         /*
674          * Find a fragment after the current one:
675          *  - off contains the real shifted offset.
676          */
677         frp = NULL;
678         LIST_FOREACH(fra, &(*frag)->fr_cache, fr_next) {
679                 if (fra->fr_off > off)
680                         break;
681                 frp = fra;
682         }
683
684 #ifdef __FreeBSD__
685         KASSERT((frp != NULL || fra != NULL),
686             ("!(frp != NULL || fra != NULL): %s", __FUNCTION__));
687 #else
688         KASSERT(frp != NULL || fra != NULL);
689 #endif
690
691         if (frp != NULL) {
692                 int     precut;
693
694                 precut = frp->fr_end - off;
695                 if (precut >= ip_len) {
696                         /* Fragment is entirely a duplicate */
697                         DPFPRINTF(("fragcache[%d]: dead (%d-%d) %d-%d\n",
698                             h->ip_id, frp->fr_off, frp->fr_end, off, max));
699                         goto drop_fragment;
700                 }
701                 if (precut == 0) {
702                         /* They are adjacent.  Fixup cache entry */
703                         DPFPRINTF(("fragcache[%d]: adjacent (%d-%d) %d-%d\n",
704                             h->ip_id, frp->fr_off, frp->fr_end, off, max));
705                         frp->fr_end = max;
706                 } else if (precut > 0) {
707                         /* The first part of this payload overlaps with a
708                          * fragment that has already been passed.
709                          * Need to trim off the first part of the payload.
710                          * But to do so easily, we need to create another
711                          * mbuf to throw the original header into.
712                          */
713
714                         DPFPRINTF(("fragcache[%d]: chop %d (%d-%d) %d-%d\n",
715                             h->ip_id, precut, frp->fr_off, frp->fr_end, off,
716                             max));
717
718                         off += precut;
719                         max -= precut;
720                         /* Update the previous frag to encompass this one */
721                         frp->fr_end = max;
722
723                         if (!drop) {
724                                 /* XXX Optimization opportunity
725                                  * This is a very heavy way to trim the payload.
726                                  * we could do it much faster by diddling mbuf
727                                  * internals but that would be even less legible
728                                  * than this mbuf magic.  For my next trick,
729                                  * I'll pull a rabbit out of my laptop.
730                                  */
731 #ifdef __FreeBSD__
732                                 *m0 = m_dup(m, M_DONTWAIT);
733 #else
734                                 *m0 = m_copym2(m, 0, h->ip_hl << 2, M_NOWAIT);
735 #endif
736                                 if (*m0 == NULL)
737                                         goto no_mem;
738 #ifdef __FreeBSD__
739                                 /* From KAME Project : We have missed this! */
740                                 m_adj(*m0, (h->ip_hl << 2) -
741                                     (*m0)->m_pkthdr.len);
742
743                                 KASSERT(((*m0)->m_next == NULL), 
744                                     ("(*m0)->m_next != NULL: %s", 
745                                     __FUNCTION__));
746 #else
747                                 KASSERT((*m0)->m_next == NULL);
748 #endif
749                                 m_adj(m, precut + (h->ip_hl << 2));
750                                 m_cat(*m0, m);
751                                 m = *m0;
752                                 if (m->m_flags & M_PKTHDR) {
753                                         int plen = 0;
754                                         struct mbuf *t;
755                                         for (t = m; t; t = t->m_next)
756                                                 plen += t->m_len;
757                                         m->m_pkthdr.len = plen;
758                                 }
759
760
761                                 h = mtod(m, struct ip *);
762
763 #ifdef __FreeBSD__
764                                 KASSERT(((int)m->m_len ==
765                                     ntohs(h->ip_len) - precut),
766                                     ("m->m_len != ntohs(h->ip_len) - precut: %s",
767                                     __FUNCTION__));
768 #else
769                                 KASSERT((int)m->m_len ==
770                                     ntohs(h->ip_len) - precut);
771 #endif
772                                 h->ip_off = htons(ntohs(h->ip_off) +
773                                     (precut >> 3));
774                                 h->ip_len = htons(ntohs(h->ip_len) - precut);
775                         } else {
776                                 hosed++;
777                         }
778                 } else {
779                         /* There is a gap between fragments */
780
781                         DPFPRINTF(("fragcache[%d]: gap %d (%d-%d) %d-%d\n",
782                             h->ip_id, -precut, frp->fr_off, frp->fr_end, off,
783                             max));
784
785                         cur = pool_get(&pf_cent_pl, PR_NOWAIT);
786                         if (cur == NULL)
787                                 goto no_mem;
788                         pf_ncache++;
789
790                         cur->fr_off = off;
791                         cur->fr_end = max;
792                         LIST_INSERT_AFTER(frp, cur, fr_next);
793                 }
794         }
795
796         if (fra != NULL) {
797                 int     aftercut;
798                 int     merge = 0;
799
800                 aftercut = max - fra->fr_off;
801                 if (aftercut == 0) {
802                         /* Adjacent fragments */
803                         DPFPRINTF(("fragcache[%d]: adjacent %d-%d (%d-%d)\n",
804                             h->ip_id, off, max, fra->fr_off, fra->fr_end));
805                         fra->fr_off = off;
806                         merge = 1;
807                 } else if (aftercut > 0) {
808                         /* Need to chop off the tail of this fragment */
809                         DPFPRINTF(("fragcache[%d]: chop %d %d-%d (%d-%d)\n",
810                             h->ip_id, aftercut, off, max, fra->fr_off,
811                             fra->fr_end));
812                         fra->fr_off = off;
813                         max -= aftercut;
814
815                         merge = 1;
816
817                         if (!drop) {
818                                 m_adj(m, -aftercut);
819                                 if (m->m_flags & M_PKTHDR) {
820                                         int plen = 0;
821                                         struct mbuf *t;
822                                         for (t = m; t; t = t->m_next)
823                                                 plen += t->m_len;
824                                         m->m_pkthdr.len = plen;
825                                 }
826                                 h = mtod(m, struct ip *);
827 #ifdef __FreeBSD__
828                                 KASSERT(((int)m->m_len == ntohs(h->ip_len) - aftercut),
829                                     ("m->m_len != ntohs(h->ip_len) - aftercut: %s",
830                                     __FUNCTION__));
831 #else
832                                 KASSERT((int)m->m_len ==
833                                     ntohs(h->ip_len) - aftercut);
834 #endif
835                                 h->ip_len = htons(ntohs(h->ip_len) - aftercut);
836                         } else {
837                                 hosed++;
838                         }
839                 } else if (frp == NULL) {
840                         /* There is a gap between fragments */
841                         DPFPRINTF(("fragcache[%d]: gap %d %d-%d (%d-%d)\n",
842                             h->ip_id, -aftercut, off, max, fra->fr_off,
843                             fra->fr_end));
844
845                         cur = pool_get(&pf_cent_pl, PR_NOWAIT);
846                         if (cur == NULL)
847                                 goto no_mem;
848                         pf_ncache++;
849
850                         cur->fr_off = off;
851                         cur->fr_end = max;
852                         LIST_INSERT_BEFORE(fra, cur, fr_next);
853                 }
854
855
856                 /* Need to glue together two separate fragment descriptors */
857                 if (merge) {
858                         if (cur && fra->fr_off <= cur->fr_end) {
859                                 /* Need to merge in a previous 'cur' */
860                                 DPFPRINTF(("fragcache[%d]: adjacent(merge "
861                                     "%d-%d) %d-%d (%d-%d)\n",
862                                     h->ip_id, cur->fr_off, cur->fr_end, off,
863                                     max, fra->fr_off, fra->fr_end));
864                                 fra->fr_off = cur->fr_off;
865                                 LIST_REMOVE(cur, fr_next);
866                                 pool_put(&pf_cent_pl, cur);
867                                 pf_ncache--;
868                                 cur = NULL;
869
870                         } else if (frp && fra->fr_off <= frp->fr_end) {
871                                 /* Need to merge in a modified 'frp' */
872 #ifdef __FreeBSD__
873                                 KASSERT((cur == NULL), ("cur != NULL: %s",
874                                     __FUNCTION__));
875 #else
876                                 KASSERT(cur == NULL);
877 #endif
878                                 DPFPRINTF(("fragcache[%d]: adjacent(merge "
879                                     "%d-%d) %d-%d (%d-%d)\n",
880                                     h->ip_id, frp->fr_off, frp->fr_end, off,
881                                     max, fra->fr_off, fra->fr_end));
882                                 fra->fr_off = frp->fr_off;
883                                 LIST_REMOVE(frp, fr_next);
884                                 pool_put(&pf_cent_pl, frp);
885                                 pf_ncache--;
886                                 frp = NULL;
887
888                         }
889                 }
890         }
891
892         if (hosed) {
893                 /*
894                  * We must keep tracking the overall fragment even when
895                  * we're going to drop it anyway so that we know when to
896                  * free the overall descriptor.  Thus we drop the frag late.
897                  */
898                 goto drop_fragment;
899         }
900
901
902  pass:
903         /* Update maximum data size */
904         if ((*frag)->fr_max < max)
905                 (*frag)->fr_max = max;
906
907         /* This is the last segment */
908         if (!mff)
909                 (*frag)->fr_flags |= PFFRAG_SEENLAST;
910
911         /* Check if we are completely reassembled */
912         if (((*frag)->fr_flags & PFFRAG_SEENLAST) &&
913             LIST_FIRST(&(*frag)->fr_cache)->fr_off == 0 &&
914             LIST_FIRST(&(*frag)->fr_cache)->fr_end == (*frag)->fr_max) {
915                 /* Remove from fragment queue */
916                 DPFPRINTF(("fragcache[%d]: done 0-%d\n", h->ip_id,
917                     (*frag)->fr_max));
918                 pf_free_fragment(*frag);
919                 *frag = NULL;
920         }
921
922         return (m);
923
924  no_mem:
925         *nomem = 1;
926
927         /* Still need to pay attention to !IP_MF */
928         if (!mff && *frag != NULL)
929                 (*frag)->fr_flags |= PFFRAG_SEENLAST;
930
931         m_freem(m);
932         return (NULL);
933
934  drop_fragment:
935
936         /* Still need to pay attention to !IP_MF */
937         if (!mff && *frag != NULL)
938                 (*frag)->fr_flags |= PFFRAG_SEENLAST;
939
940         if (drop) {
941                 /* This fragment has been deemed bad.  Don't reass */
942                 if (((*frag)->fr_flags & PFFRAG_DROP) == 0)
943                         DPFPRINTF(("fragcache[%d]: dropping overall fragment\n",
944                             h->ip_id));
945                 (*frag)->fr_flags |= PFFRAG_DROP;
946         }
947
948         m_freem(m);
949         return (NULL);
950 }
951
952 int
953 pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
954     struct pf_pdesc *pd)
955 {
956         struct mbuf             *m = *m0;
957         struct pf_rule          *r;
958         struct pf_frent         *frent;
959         struct pf_fragment      *frag = NULL;
960         struct ip               *h = mtod(m, struct ip *);
961         int                      mff = (ntohs(h->ip_off) & IP_MF);
962         int                      hlen = h->ip_hl << 2;
963         u_int16_t                fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
964         u_int16_t                max;
965         int                      ip_len;
966         int                      ip_off;
967
968         r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
969         while (r != NULL) {
970                 r->evaluations++;
971                 if (pfi_kif_match(r->kif, kif) == r->ifnot)
972                         r = r->skip[PF_SKIP_IFP].ptr;
973                 else if (r->direction && r->direction != dir)
974                         r = r->skip[PF_SKIP_DIR].ptr;
975                 else if (r->af && r->af != AF_INET)
976                         r = r->skip[PF_SKIP_AF].ptr;
977                 else if (r->proto && r->proto != h->ip_p)
978                         r = r->skip[PF_SKIP_PROTO].ptr;
979                 else if (PF_MISMATCHAW(&r->src.addr,
980                     (struct pf_addr *)&h->ip_src.s_addr, AF_INET,
981                     r->src.neg, kif))
982                         r = r->skip[PF_SKIP_SRC_ADDR].ptr;
983                 else if (PF_MISMATCHAW(&r->dst.addr,
984                     (struct pf_addr *)&h->ip_dst.s_addr, AF_INET,
985                     r->dst.neg, NULL))
986                         r = r->skip[PF_SKIP_DST_ADDR].ptr;
987                 else
988                         break;
989         }
990
991         if (r == NULL || r->action == PF_NOSCRUB)
992                 return (PF_PASS);
993         else {
994                 r->packets[dir == PF_OUT]++;
995                 r->bytes[dir == PF_OUT] += pd->tot_len;
996         }
997
998         /* Check for illegal packets */
999         if (hlen < (int)sizeof(struct ip))
1000                 goto drop;
1001
1002         if (hlen > ntohs(h->ip_len))
1003                 goto drop;
1004
1005         /* Clear IP_DF if the rule uses the no-df option */
1006         if (r->rule_flag & PFRULE_NODF && h->ip_off & htons(IP_DF)) {
1007                 u_int16_t ip_off = h->ip_off;
1008
1009                 h->ip_off &= htons(~IP_DF);
1010                 h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
1011         }
1012
1013         /* We will need other tests here */
1014         if (!fragoff && !mff)
1015                 goto no_fragment;
1016
1017         /* We're dealing with a fragment now. Don't allow fragments
1018          * with IP_DF to enter the cache. If the flag was cleared by
1019          * no-df above, fine. Otherwise drop it.
1020          */
1021         if (h->ip_off & htons(IP_DF)) {
1022                 DPFPRINTF(("IP_DF\n"));
1023                 goto bad;
1024         }
1025
1026         ip_len = ntohs(h->ip_len) - hlen;
1027         ip_off = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
1028
1029         /* All fragments are 8 byte aligned */
1030         if (mff && (ip_len & 0x7)) {
1031                 DPFPRINTF(("mff and %d\n", ip_len));
1032                 goto bad;
1033         }
1034
1035         /* Respect maximum length */
1036         if (fragoff + ip_len > IP_MAXPACKET) {
1037                 DPFPRINTF(("max packet %d\n", fragoff + ip_len));
1038                 goto bad;
1039         }
1040         max = fragoff + ip_len;
1041
1042         if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0) {
1043                 /* Fully buffer all of the fragments */
1044
1045                 frag = pf_find_fragment(h, &pf_frag_tree);
1046
1047                 /* Check if we saw the last fragment already */
1048                 if (frag != NULL && (frag->fr_flags & PFFRAG_SEENLAST) &&
1049                     max > frag->fr_max)
1050                         goto bad;
1051
1052                 /* Get an entry for the fragment queue */
1053                 frent = pool_get(&pf_frent_pl, PR_NOWAIT);
1054                 if (frent == NULL) {
1055                         REASON_SET(reason, PFRES_MEMORY);
1056                         return (PF_DROP);
1057                 }
1058                 pf_nfrents++;
1059                 frent->fr_ip = h;
1060                 frent->fr_m = m;
1061
1062                 /* Might return a completely reassembled mbuf, or NULL */
1063                 DPFPRINTF(("reass frag %d @ %d-%d\n", h->ip_id, fragoff, max));
1064                 *m0 = m = pf_reassemble(m0, &frag, frent, mff);
1065
1066                 if (m == NULL)
1067                         return (PF_DROP);
1068
1069                 /* use mtag from concatenated mbuf chain */
1070                 pd->pf_mtag = pf_find_mtag(m);
1071 #ifdef DIAGNOSTIC
1072                 if (pd->pf_mtag == NULL) {
1073                         printf("%s: pf_find_mtag returned NULL(1)\n", __func__);
1074                         if ((pd->pf_mtag = pf_get_mtag(m)) == NULL) {
1075                                 m_freem(m);
1076                                 *m0 = NULL;
1077                                 goto no_mem;
1078                         }
1079                 }
1080 #endif
1081                 if (frag != NULL && (frag->fr_flags & PFFRAG_DROP))
1082                         goto drop;
1083
1084                 h = mtod(m, struct ip *);
1085         } else {
1086                 /* non-buffering fragment cache (drops or masks overlaps) */
1087                 int     nomem = 0;
1088
1089                 if (dir == PF_OUT && pd->pf_mtag->flags & PF_TAG_FRAGCACHE) {
1090                         /*
1091                          * Already passed the fragment cache in the
1092                          * input direction.  If we continued, it would
1093                          * appear to be a dup and would be dropped.
1094                          */
1095                         goto fragment_pass;
1096                 }
1097
1098                 frag = pf_find_fragment(h, &pf_cache_tree);
1099
1100                 /* Check if we saw the last fragment already */
1101                 if (frag != NULL && (frag->fr_flags & PFFRAG_SEENLAST) &&
1102                     max > frag->fr_max) {
1103                         if (r->rule_flag & PFRULE_FRAGDROP)
1104                                 frag->fr_flags |= PFFRAG_DROP;
1105                         goto bad;
1106                 }
1107
1108                 *m0 = m = pf_fragcache(m0, h, &frag, mff,
1109                     (r->rule_flag & PFRULE_FRAGDROP) ? 1 : 0, &nomem);
1110                 if (m == NULL) {
1111                         if (nomem)
1112                                 goto no_mem;
1113                         goto drop;
1114                 }
1115
1116                 /* use mtag from copied and trimmed mbuf chain */
1117                 pd->pf_mtag = pf_find_mtag(m);
1118 #ifdef DIAGNOSTIC
1119                 if (pd->pf_mtag == NULL) {
1120                         printf("%s: pf_find_mtag returned NULL(2)\n", __func__);
1121                         if ((pd->pf_mtag = pf_get_mtag(m)) == NULL) {
1122                                 m_freem(m);
1123                                 *m0 = NULL;
1124                                 goto no_mem;
1125                         }
1126                 }
1127 #endif
1128                 if (dir == PF_IN)
1129                         pd->pf_mtag->flags |= PF_TAG_FRAGCACHE;
1130
1131                 if (frag != NULL && (frag->fr_flags & PFFRAG_DROP))
1132                         goto drop;
1133                 goto fragment_pass;
1134         }
1135
1136  no_fragment:
1137         /* At this point, only IP_DF is allowed in ip_off */
1138         if (h->ip_off & ~htons(IP_DF)) {
1139                 u_int16_t ip_off = h->ip_off;
1140
1141                 h->ip_off &= htons(IP_DF);
1142                 h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
1143         }
1144
1145         /* Enforce a minimum ttl, may cause endless packet loops */
1146         if (r->min_ttl && h->ip_ttl < r->min_ttl) {
1147                 u_int16_t ip_ttl = h->ip_ttl;
1148
1149                 h->ip_ttl = r->min_ttl;
1150                 h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_ttl, h->ip_ttl, 0);
1151         }
1152
1153         if (r->rule_flag & PFRULE_RANDOMID) {
1154                 u_int16_t ip_id = h->ip_id;
1155
1156                 h->ip_id = ip_randomid();
1157                 h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);
1158         }
1159         if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0)
1160                 pd->flags |= PFDESC_IP_REAS;
1161
1162         return (PF_PASS);
1163
1164  fragment_pass:
1165         /* Enforce a minimum ttl, may cause endless packet loops */
1166         if (r->min_ttl && h->ip_ttl < r->min_ttl) {
1167                 u_int16_t ip_ttl = h->ip_ttl;
1168
1169                 h->ip_ttl = r->min_ttl;
1170                 h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_ttl, h->ip_ttl, 0);
1171         }
1172         if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0)
1173                 pd->flags |= PFDESC_IP_REAS;
1174         return (PF_PASS);
1175
1176  no_mem:
1177         REASON_SET(reason, PFRES_MEMORY);
1178         if (r != NULL && r->log)
1179                 PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
1180         return (PF_DROP);
1181
1182  drop:
1183         REASON_SET(reason, PFRES_NORM);
1184         if (r != NULL && r->log)
1185                 PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
1186         return (PF_DROP);
1187
1188  bad:
1189         DPFPRINTF(("dropping bad fragment\n"));
1190
1191         /* Free associated fragments */
1192         if (frag != NULL)
1193                 pf_free_fragment(frag);
1194
1195         REASON_SET(reason, PFRES_FRAG);
1196         if (r != NULL && r->log)
1197                 PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
1198
1199         return (PF_DROP);
1200 }
1201
1202 #ifdef INET6
1203 int
1204 pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
1205     u_short *reason, struct pf_pdesc *pd)
1206 {
1207         struct mbuf             *m = *m0;
1208         struct pf_rule          *r;
1209         struct ip6_hdr          *h = mtod(m, struct ip6_hdr *);
1210         int                      off;
1211         struct ip6_ext           ext;
1212         struct ip6_opt           opt;
1213         struct ip6_opt_jumbo     jumbo;
1214         struct ip6_frag          frag;
1215         u_int32_t                jumbolen = 0, plen;
1216         u_int16_t                fragoff = 0;
1217         int                      optend;
1218         int                      ooff;
1219         u_int8_t                 proto;
1220         int                      terminal;
1221
1222         r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
1223         while (r != NULL) {
1224                 r->evaluations++;
1225                 if (pfi_kif_match(r->kif, kif) == r->ifnot)
1226                         r = r->skip[PF_SKIP_IFP].ptr;
1227                 else if (r->direction && r->direction != dir)
1228                         r = r->skip[PF_SKIP_DIR].ptr;
1229                 else if (r->af && r->af != AF_INET6)
1230                         r = r->skip[PF_SKIP_AF].ptr;
1231 #if 0 /* header chain! */
1232                 else if (r->proto && r->proto != h->ip6_nxt)
1233                         r = r->skip[PF_SKIP_PROTO].ptr;
1234 #endif
1235                 else if (PF_MISMATCHAW(&r->src.addr,
1236                     (struct pf_addr *)&h->ip6_src, AF_INET6,
1237                     r->src.neg, kif))
1238                         r = r->skip[PF_SKIP_SRC_ADDR].ptr;
1239                 else if (PF_MISMATCHAW(&r->dst.addr,
1240                     (struct pf_addr *)&h->ip6_dst, AF_INET6,
1241                     r->dst.neg, NULL))
1242                         r = r->skip[PF_SKIP_DST_ADDR].ptr;
1243                 else
1244                         break;
1245         }
1246
1247         if (r == NULL || r->action == PF_NOSCRUB)
1248                 return (PF_PASS);
1249         else {
1250                 r->packets[dir == PF_OUT]++;
1251                 r->bytes[dir == PF_OUT] += pd->tot_len;
1252         }
1253
1254         /* Check for illegal packets */
1255         if (sizeof(struct ip6_hdr) + IPV6_MAXPACKET < m->m_pkthdr.len)
1256                 goto drop;
1257
1258         off = sizeof(struct ip6_hdr);
1259         proto = h->ip6_nxt;
1260         terminal = 0;
1261         do {
1262                 switch (proto) {
1263                 case IPPROTO_FRAGMENT:
1264                         goto fragment;
1265                         break;
1266                 case IPPROTO_AH:
1267                 case IPPROTO_ROUTING:
1268                 case IPPROTO_DSTOPTS:
1269                         if (!pf_pull_hdr(m, off, &ext, sizeof(ext), NULL,
1270                             NULL, AF_INET6))
1271                                 goto shortpkt;
1272                         if (proto == IPPROTO_AH)
1273                                 off += (ext.ip6e_len + 2) * 4;
1274                         else
1275                                 off += (ext.ip6e_len + 1) * 8;
1276                         proto = ext.ip6e_nxt;
1277                         break;
1278                 case IPPROTO_HOPOPTS:
1279                         if (!pf_pull_hdr(m, off, &ext, sizeof(ext), NULL,
1280                             NULL, AF_INET6))
1281                                 goto shortpkt;
1282                         optend = off + (ext.ip6e_len + 1) * 8;
1283                         ooff = off + sizeof(ext);
1284                         do {
1285                                 if (!pf_pull_hdr(m, ooff, &opt.ip6o_type,
1286                                     sizeof(opt.ip6o_type), NULL, NULL,
1287                                     AF_INET6))
1288                                         goto shortpkt;
1289                                 if (opt.ip6o_type == IP6OPT_PAD1) {
1290                                         ooff++;
1291                                         continue;
1292                                 }
1293                                 if (!pf_pull_hdr(m, ooff, &opt, sizeof(opt),
1294                                     NULL, NULL, AF_INET6))
1295                                         goto shortpkt;
1296                                 if (ooff + sizeof(opt) + opt.ip6o_len > optend)
1297                                         goto drop;
1298                                 switch (opt.ip6o_type) {
1299                                 case IP6OPT_JUMBO:
1300                                         if (h->ip6_plen != 0)
1301                                                 goto drop;
1302                                         if (!pf_pull_hdr(m, ooff, &jumbo,
1303                                             sizeof(jumbo), NULL, NULL,
1304                                             AF_INET6))
1305                                                 goto shortpkt;
1306                                         memcpy(&jumbolen, jumbo.ip6oj_jumbo_len,
1307                                             sizeof(jumbolen));
1308                                         jumbolen = ntohl(jumbolen);
1309                                         if (jumbolen <= IPV6_MAXPACKET)
1310                                                 goto drop;
1311                                         if (sizeof(struct ip6_hdr) + jumbolen !=
1312                                             m->m_pkthdr.len)
1313                                                 goto drop;
1314                                         break;
1315                                 default:
1316                                         break;
1317                                 }
1318                                 ooff += sizeof(opt) + opt.ip6o_len;
1319                         } while (ooff < optend);
1320
1321                         off = optend;
1322                         proto = ext.ip6e_nxt;
1323                         break;
1324                 default:
1325                         terminal = 1;
1326                         break;
1327                 }
1328         } while (!terminal);
1329
1330         /* jumbo payload option must be present, or plen > 0 */
1331         if (ntohs(h->ip6_plen) == 0)
1332                 plen = jumbolen;
1333         else
1334                 plen = ntohs(h->ip6_plen);
1335         if (plen == 0)
1336                 goto drop;
1337         if (sizeof(struct ip6_hdr) + plen > m->m_pkthdr.len)
1338                 goto shortpkt;
1339
1340         /* Enforce a minimum ttl, may cause endless packet loops */
1341         if (r->min_ttl && h->ip6_hlim < r->min_ttl)
1342                 h->ip6_hlim = r->min_ttl;
1343
1344         return (PF_PASS);
1345
1346  fragment:
1347         if (ntohs(h->ip6_plen) == 0 || jumbolen)
1348                 goto drop;
1349         plen = ntohs(h->ip6_plen);
1350
1351         if (!pf_pull_hdr(m, off, &frag, sizeof(frag), NULL, NULL, AF_INET6))
1352                 goto shortpkt;
1353         fragoff = ntohs(frag.ip6f_offlg & IP6F_OFF_MASK);
1354         if (fragoff + (plen - off - sizeof(frag)) > IPV6_MAXPACKET)
1355                 goto badfrag;
1356
1357         /* do something about it */
1358         /* remember to set pd->flags |= PFDESC_IP_REAS */
1359         return (PF_PASS);
1360
1361  shortpkt:
1362         REASON_SET(reason, PFRES_SHORT);
1363         if (r != NULL && r->log)
1364                 PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
1365         return (PF_DROP);
1366
1367  drop:
1368         REASON_SET(reason, PFRES_NORM);
1369         if (r != NULL && r->log)
1370                 PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
1371         return (PF_DROP);
1372
1373  badfrag:
1374         REASON_SET(reason, PFRES_FRAG);
1375         if (r != NULL && r->log)
1376                 PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
1377         return (PF_DROP);
1378 }
1379 #endif /* INET6 */
1380
1381 int
1382 pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
1383     int off, void *h, struct pf_pdesc *pd)
1384 {
1385         struct pf_rule  *r, *rm = NULL;
1386         struct tcphdr   *th = pd->hdr.tcp;
1387         int              rewrite = 0;
1388         u_short          reason;
1389         u_int8_t         flags;
1390         sa_family_t      af = pd->af;
1391
1392         r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
1393         while (r != NULL) {
1394                 r->evaluations++;
1395                 if (pfi_kif_match(r->kif, kif) == r->ifnot)
1396                         r = r->skip[PF_SKIP_IFP].ptr;
1397                 else if (r->direction && r->direction != dir)
1398                         r = r->skip[PF_SKIP_DIR].ptr;
1399                 else if (r->af && r->af != af)
1400                         r = r->skip[PF_SKIP_AF].ptr;
1401                 else if (r->proto && r->proto != pd->proto)
1402                         r = r->skip[PF_SKIP_PROTO].ptr;
1403                 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
1404                     r->src.neg, kif))
1405                         r = r->skip[PF_SKIP_SRC_ADDR].ptr;
1406                 else if (r->src.port_op && !pf_match_port(r->src.port_op,
1407                             r->src.port[0], r->src.port[1], th->th_sport))
1408                         r = r->skip[PF_SKIP_SRC_PORT].ptr;
1409                 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
1410                     r->dst.neg, NULL))
1411                         r = r->skip[PF_SKIP_DST_ADDR].ptr;
1412                 else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
1413                             r->dst.port[0], r->dst.port[1], th->th_dport))
1414                         r = r->skip[PF_SKIP_DST_PORT].ptr;
1415                 else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
1416                             pf_osfp_fingerprint(pd, m, off, th),
1417                             r->os_fingerprint))
1418                         r = TAILQ_NEXT(r, entries);
1419                 else {
1420                         rm = r;
1421                         break;
1422                 }
1423         }
1424
1425         if (rm == NULL || rm->action == PF_NOSCRUB)
1426                 return (PF_PASS);
1427         else {
1428                 r->packets[dir == PF_OUT]++;
1429                 r->bytes[dir == PF_OUT] += pd->tot_len;
1430         }
1431
1432         if (rm->rule_flag & PFRULE_REASSEMBLE_TCP)
1433                 pd->flags |= PFDESC_TCP_NORM;
1434
1435         flags = th->th_flags;
1436         if (flags & TH_SYN) {
1437                 /* Illegal packet */
1438                 if (flags & TH_RST)
1439                         goto tcp_drop;
1440
1441                 if (flags & TH_FIN)
1442                         flags &= ~TH_FIN;
1443         } else {
1444                 /* Illegal packet */
1445                 if (!(flags & (TH_ACK|TH_RST)))
1446                         goto tcp_drop;
1447         }
1448
1449         if (!(flags & TH_ACK)) {
1450                 /* These flags are only valid if ACK is set */
1451                 if ((flags & TH_FIN) || (flags & TH_PUSH) || (flags & TH_URG))
1452                         goto tcp_drop;
1453         }
1454
1455         /* Check for illegal header length */
1456         if (th->th_off < (sizeof(struct tcphdr) >> 2))
1457                 goto tcp_drop;
1458
1459         /* If flags changed, or reserved data set, then adjust */
1460         if (flags != th->th_flags || th->th_x2 != 0) {
1461                 u_int16_t       ov, nv;
1462
1463                 ov = *(u_int16_t *)(&th->th_ack + 1);
1464                 th->th_flags = flags;
1465                 th->th_x2 = 0;
1466                 nv = *(u_int16_t *)(&th->th_ack + 1);
1467
1468                 th->th_sum = pf_cksum_fixup(th->th_sum, ov, nv, 0);
1469                 rewrite = 1;
1470         }
1471
1472         /* Remove urgent pointer, if TH_URG is not set */
1473         if (!(flags & TH_URG) && th->th_urp) {
1474                 th->th_sum = pf_cksum_fixup(th->th_sum, th->th_urp, 0, 0);
1475                 th->th_urp = 0;
1476                 rewrite = 1;
1477         }
1478
1479         /* Process options */
1480         if (r->max_mss && pf_normalize_tcpopt(r, m, th, off))
1481                 rewrite = 1;
1482
1483         /* copy back packet headers if we sanitized */
1484         if (rewrite)
1485                 m_copyback(m, off, sizeof(*th), (caddr_t)th);
1486
1487         return (PF_PASS);
1488
1489  tcp_drop:
1490         REASON_SET(&reason, PFRES_NORM);
1491         if (rm != NULL && r->log)
1492                 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, NULL, NULL, pd);
1493         return (PF_DROP);
1494 }
1495
1496 int
1497 pf_normalize_tcp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
1498     struct tcphdr *th, struct pf_state_peer *src, struct pf_state_peer *dst)
1499 {
1500         u_int32_t tsval, tsecr;
1501         u_int8_t hdr[60];
1502         u_int8_t *opt;
1503
1504 #ifdef __FreeBSD__
1505         KASSERT((src->scrub == NULL), 
1506             ("pf_normalize_tcp_init: src->scrub != NULL"));
1507 #else
1508         KASSERT(src->scrub == NULL);
1509 #endif
1510
1511         src->scrub = pool_get(&pf_state_scrub_pl, PR_NOWAIT);
1512         if (src->scrub == NULL)
1513                 return (1);
1514         bzero(src->scrub, sizeof(*src->scrub));
1515
1516         switch (pd->af) {
1517 #ifdef INET
1518         case AF_INET: {
1519                 struct ip *h = mtod(m, struct ip *);
1520                 src->scrub->pfss_ttl = h->ip_ttl;
1521                 break;
1522         }
1523 #endif /* INET */
1524 #ifdef INET6
1525         case AF_INET6: {
1526                 struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
1527                 src->scrub->pfss_ttl = h->ip6_hlim;
1528                 break;
1529         }
1530 #endif /* INET6 */
1531         }
1532
1533
1534         /*
1535          * All normalizations below are only begun if we see the start of
1536          * the connections.  They must all set an enabled bit in pfss_flags
1537          */
1538         if ((th->th_flags & TH_SYN) == 0)
1539                 return (0);
1540
1541
1542         if (th->th_off > (sizeof(struct tcphdr) >> 2) && src->scrub &&
1543             pf_pull_hdr(m, off, hdr, th->th_off << 2, NULL, NULL, pd->af)) {
1544                 /* Diddle with TCP options */
1545                 int hlen;
1546                 opt = hdr + sizeof(struct tcphdr);
1547                 hlen = (th->th_off << 2) - sizeof(struct tcphdr);
1548                 while (hlen >= TCPOLEN_TIMESTAMP) {
1549                         switch (*opt) {
1550                         case TCPOPT_EOL:        /* FALLTHROUGH */
1551                         case TCPOPT_NOP:
1552                                 opt++;
1553                                 hlen--;
1554                                 break;
1555                         case TCPOPT_TIMESTAMP:
1556                                 if (opt[1] >= TCPOLEN_TIMESTAMP) {
1557                                         src->scrub->pfss_flags |=
1558                                             PFSS_TIMESTAMP;
1559                                         src->scrub->pfss_ts_mod =
1560                                             htonl(arc4random());
1561
1562                                         /* note PFSS_PAWS not set yet */
1563                                         memcpy(&tsval, &opt[2],
1564                                             sizeof(u_int32_t));
1565                                         memcpy(&tsecr, &opt[6],
1566                                             sizeof(u_int32_t));
1567                                         src->scrub->pfss_tsval0 = ntohl(tsval);
1568                                         src->scrub->pfss_tsval = ntohl(tsval);
1569                                         src->scrub->pfss_tsecr = ntohl(tsecr);
1570                                         getmicrouptime(&src->scrub->pfss_last);
1571                                 }
1572                                 /* FALLTHROUGH */
1573                         default:
1574                                 hlen -= MAX(opt[1], 2);
1575                                 opt += MAX(opt[1], 2);
1576                                 break;
1577                         }
1578                 }
1579         }
1580
1581         return (0);
1582 }
1583
1584 void
1585 pf_normalize_tcp_cleanup(struct pf_state *state)
1586 {
1587         if (state->src.scrub)
1588                 pool_put(&pf_state_scrub_pl, state->src.scrub);
1589         if (state->dst.scrub)
1590                 pool_put(&pf_state_scrub_pl, state->dst.scrub);
1591
1592         /* Someday... flush the TCP segment reassembly descriptors. */
1593 }
1594
1595 int
1596 pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
1597     u_short *reason, struct tcphdr *th, struct pf_state *state,
1598     struct pf_state_peer *src, struct pf_state_peer *dst, int *writeback)
1599 {
1600         struct timeval uptime;
1601         u_int32_t tsval, tsecr;
1602         u_int tsval_from_last;
1603         u_int8_t hdr[60];
1604         u_int8_t *opt;
1605         int copyback = 0;
1606         int got_ts = 0;
1607
1608 #ifdef __FreeBSD__
1609         KASSERT((src->scrub || dst->scrub), 
1610             ("pf_normalize_tcp_statefull: src->scrub && dst->scrub!"));
1611 #else
1612         KASSERT(src->scrub || dst->scrub);
1613 #endif
1614
1615         /*
1616          * Enforce the minimum TTL seen for this connection.  Negate a common
1617          * technique to evade an intrusion detection system and confuse
1618          * firewall state code.
1619          */
1620         switch (pd->af) {
1621 #ifdef INET
1622         case AF_INET: {
1623                 if (src->scrub) {
1624                         struct ip *h = mtod(m, struct ip *);
1625                         if (h->ip_ttl > src->scrub->pfss_ttl)
1626                                 src->scrub->pfss_ttl = h->ip_ttl;
1627                         h->ip_ttl = src->scrub->pfss_ttl;
1628                 }
1629                 break;
1630         }
1631 #endif /* INET */
1632 #ifdef INET6
1633         case AF_INET6: {
1634                 if (src->scrub) {
1635                         struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
1636                         if (h->ip6_hlim > src->scrub->pfss_ttl)
1637                                 src->scrub->pfss_ttl = h->ip6_hlim;
1638                         h->ip6_hlim = src->scrub->pfss_ttl;
1639                 }
1640                 break;
1641         }
1642 #endif /* INET6 */
1643         }
1644
1645         if (th->th_off > (sizeof(struct tcphdr) >> 2) &&
1646             ((src->scrub && (src->scrub->pfss_flags & PFSS_TIMESTAMP)) ||
1647             (dst->scrub && (dst->scrub->pfss_flags & PFSS_TIMESTAMP))) &&
1648             pf_pull_hdr(m, off, hdr, th->th_off << 2, NULL, NULL, pd->af)) {
1649                 /* Diddle with TCP options */
1650                 int hlen;
1651                 opt = hdr + sizeof(struct tcphdr);
1652                 hlen = (th->th_off << 2) - sizeof(struct tcphdr);
1653                 while (hlen >= TCPOLEN_TIMESTAMP) {
1654                         switch (*opt) {
1655                         case TCPOPT_EOL:        /* FALLTHROUGH */
1656                         case TCPOPT_NOP:
1657                                 opt++;
1658                                 hlen--;
1659                                 break;
1660                         case TCPOPT_TIMESTAMP:
1661                                 /* Modulate the timestamps.  Can be used for
1662                                  * NAT detection, OS uptime determination or
1663                                  * reboot detection.
1664                                  */
1665
1666                                 if (got_ts) {
1667                                         /* Huh?  Multiple timestamps!? */
1668                                         if (pf_status.debug >= PF_DEBUG_MISC) {
1669                                                 DPFPRINTF(("multiple TS??"));
1670                                                 pf_print_state(state);
1671                                                 printf("\n");
1672                                         }
1673                                         REASON_SET(reason, PFRES_TS);
1674                                         return (PF_DROP);
1675                                 }
1676                                 if (opt[1] >= TCPOLEN_TIMESTAMP) {
1677                                         memcpy(&tsval, &opt[2],
1678                                             sizeof(u_int32_t));
1679                                         if (tsval && src->scrub &&
1680                                             (src->scrub->pfss_flags &
1681                                             PFSS_TIMESTAMP)) {
1682                                                 tsval = ntohl(tsval);
1683                                                 pf_change_a(&opt[2],
1684                                                     &th->th_sum,
1685                                                     htonl(tsval +
1686                                                     src->scrub->pfss_ts_mod),
1687                                                     0);
1688                                                 copyback = 1;
1689                                         }
1690
1691                                         /* Modulate TS reply iff valid (!0) */
1692                                         memcpy(&tsecr, &opt[6],
1693                                             sizeof(u_int32_t));
1694                                         if (tsecr && dst->scrub &&
1695                                             (dst->scrub->pfss_flags &
1696                                             PFSS_TIMESTAMP)) {
1697                                                 tsecr = ntohl(tsecr)
1698                                                     - dst->scrub->pfss_ts_mod;
1699                                                 pf_change_a(&opt[6],
1700                                                     &th->th_sum, htonl(tsecr),
1701                                                     0);
1702                                                 copyback = 1;
1703                                         }
1704                                         got_ts = 1;
1705                                 }
1706                                 /* FALLTHROUGH */
1707                         default:
1708                                 hlen -= MAX(opt[1], 2);
1709                                 opt += MAX(opt[1], 2);
1710                                 break;
1711                         }
1712                 }
1713                 if (copyback) {
1714                         /* Copyback the options, caller copys back header */
1715                         *writeback = 1;
1716                         m_copyback(m, off + sizeof(struct tcphdr),
1717                             (th->th_off << 2) - sizeof(struct tcphdr), hdr +
1718                             sizeof(struct tcphdr));
1719                 }
1720         }
1721
1722
1723         /*
1724          * Must invalidate PAWS checks on connections idle for too long.
1725          * The fastest allowed timestamp clock is 1ms.  That turns out to
1726          * be about 24 days before it wraps.  XXX Right now our lowerbound
1727          * TS echo check only works for the first 12 days of a connection
1728          * when the TS has exhausted half its 32bit space
1729          */
1730 #define TS_MAX_IDLE     (24*24*60*60)
1731 #define TS_MAX_CONN     (12*24*60*60)   /* XXX remove when better tsecr check */
1732
1733         getmicrouptime(&uptime);
1734         if (src->scrub && (src->scrub->pfss_flags & PFSS_PAWS) &&
1735             (uptime.tv_sec - src->scrub->pfss_last.tv_sec > TS_MAX_IDLE ||
1736             time_second - state->creation > TS_MAX_CONN))  {
1737                 if (pf_status.debug >= PF_DEBUG_MISC) {
1738                         DPFPRINTF(("src idled out of PAWS\n"));
1739                         pf_print_state(state);
1740                         printf("\n");
1741                 }
1742                 src->scrub->pfss_flags = (src->scrub->pfss_flags & ~PFSS_PAWS)
1743                     | PFSS_PAWS_IDLED;
1744         }
1745         if (dst->scrub && (dst->scrub->pfss_flags & PFSS_PAWS) &&
1746             uptime.tv_sec - dst->scrub->pfss_last.tv_sec > TS_MAX_IDLE) {
1747                 if (pf_status.debug >= PF_DEBUG_MISC) {
1748                         DPFPRINTF(("dst idled out of PAWS\n"));
1749                         pf_print_state(state);
1750                         printf("\n");
1751                 }
1752                 dst->scrub->pfss_flags = (dst->scrub->pfss_flags & ~PFSS_PAWS)
1753                     | PFSS_PAWS_IDLED;
1754         }
1755
1756         if (got_ts && src->scrub && dst->scrub &&
1757             (src->scrub->pfss_flags & PFSS_PAWS) &&
1758             (dst->scrub->pfss_flags & PFSS_PAWS)) {
1759                 /* Validate that the timestamps are "in-window".
1760                  * RFC1323 describes TCP Timestamp options that allow
1761                  * measurement of RTT (round trip time) and PAWS
1762                  * (protection against wrapped sequence numbers).  PAWS
1763                  * gives us a set of rules for rejecting packets on
1764                  * long fat pipes (packets that were somehow delayed 
1765                  * in transit longer than the time it took to send the
1766                  * full TCP sequence space of 4Gb).  We can use these
1767                  * rules and infer a few others that will let us treat
1768                  * the 32bit timestamp and the 32bit echoed timestamp
1769                  * as sequence numbers to prevent a blind attacker from
1770                  * inserting packets into a connection.
1771                  *
1772                  * RFC1323 tells us:
1773                  *  - The timestamp on this packet must be greater than
1774                  *    or equal to the last value echoed by the other
1775                  *    endpoint.  The RFC says those will be discarded
1776                  *    since it is a dup that has already been acked.
1777                  *    This gives us a lowerbound on the timestamp.
1778                  *        timestamp >= other last echoed timestamp
1779                  *  - The timestamp will be less than or equal to
1780                  *    the last timestamp plus the time between the
1781                  *    last packet and now.  The RFC defines the max
1782                  *    clock rate as 1ms.  We will allow clocks to be
1783                  *    up to 10% fast and will allow a total difference
1784                  *    or 30 seconds due to a route change.  And this
1785                  *    gives us an upperbound on the timestamp.
1786                  *        timestamp <= last timestamp + max ticks
1787                  *    We have to be careful here.  Windows will send an
1788                  *    initial timestamp of zero and then initialize it
1789                  *    to a random value after the 3whs; presumably to
1790                  *    avoid a DoS by having to call an expensive RNG
1791                  *    during a SYN flood.  Proof MS has at least one
1792                  *    good security geek.
1793                  *
1794                  *  - The TCP timestamp option must also echo the other
1795                  *    endpoints timestamp.  The timestamp echoed is the
1796                  *    one carried on the earliest unacknowledged segment
1797                  *    on the left edge of the sequence window.  The RFC
1798                  *    states that the host will reject any echoed
1799                  *    timestamps that were larger than any ever sent.
1800                  *    This gives us an upperbound on the TS echo.
1801                  *        tescr <= largest_tsval
1802                  *  - The lowerbound on the TS echo is a little more
1803                  *    tricky to determine.  The other endpoint's echoed
1804                  *    values will not decrease.  But there may be
1805                  *    network conditions that re-order packets and
1806                  *    cause our view of them to decrease.  For now the
1807                  *    only lowerbound we can safely determine is that
1808                  *    the TS echo will never be less than the orginal
1809                  *    TS.  XXX There is probably a better lowerbound.
1810                  *    Remove TS_MAX_CONN with better lowerbound check.
1811                  *        tescr >= other original TS
1812                  *
1813                  * It is also important to note that the fastest
1814                  * timestamp clock of 1ms will wrap its 32bit space in
1815                  * 24 days.  So we just disable TS checking after 24
1816                  * days of idle time.  We actually must use a 12d
1817                  * connection limit until we can come up with a better
1818                  * lowerbound to the TS echo check.
1819                  */
1820                 struct timeval delta_ts;
1821                 int ts_fudge;
1822
1823
1824                 /*
1825                  * PFTM_TS_DIFF is how many seconds of leeway to allow
1826                  * a host's timestamp.  This can happen if the previous
1827                  * packet got delayed in transit for much longer than
1828                  * this packet.
1829                  */
1830                 if ((ts_fudge = state->rule.ptr->timeout[PFTM_TS_DIFF]) == 0)
1831                         ts_fudge = pf_default_rule.timeout[PFTM_TS_DIFF];
1832
1833
1834                 /* Calculate max ticks since the last timestamp */
1835 #define TS_MAXFREQ      1100            /* RFC max TS freq of 1Khz + 10% skew */
1836 #define TS_MICROSECS    1000000         /* microseconds per second */
1837 #ifdef __FreeBSD__
1838 #ifndef timersub
1839 #define timersub(tvp, uvp, vvp)                                         \
1840         do {                                                            \
1841                 (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;          \
1842                 (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec;       \
1843                 if ((vvp)->tv_usec < 0) {                               \
1844                         (vvp)->tv_sec--;                                \
1845                         (vvp)->tv_usec += 1000000;                      \
1846                 }                                                       \
1847         } while (0)
1848 #endif
1849 #endif
1850                 timersub(&uptime, &src->scrub->pfss_last, &delta_ts);
1851                 tsval_from_last = (delta_ts.tv_sec + ts_fudge) * TS_MAXFREQ;
1852                 tsval_from_last += delta_ts.tv_usec / (TS_MICROSECS/TS_MAXFREQ);
1853
1854
1855                 if ((src->state >= TCPS_ESTABLISHED &&
1856                     dst->state >= TCPS_ESTABLISHED) &&
1857                     (SEQ_LT(tsval, dst->scrub->pfss_tsecr) ||
1858                     SEQ_GT(tsval, src->scrub->pfss_tsval + tsval_from_last) ||
1859                     (tsecr && (SEQ_GT(tsecr, dst->scrub->pfss_tsval) ||
1860                     SEQ_LT(tsecr, dst->scrub->pfss_tsval0))))) {
1861                         /* Bad RFC1323 implementation or an insertion attack.
1862                          *
1863                          * - Solaris 2.6 and 2.7 are known to send another ACK
1864                          *   after the FIN,FIN|ACK,ACK closing that carries
1865                          *   an old timestamp.
1866                          */
1867
1868                         DPFPRINTF(("Timestamp failed %c%c%c%c\n",
1869                             SEQ_LT(tsval, dst->scrub->pfss_tsecr) ? '0' : ' ',
1870                             SEQ_GT(tsval, src->scrub->pfss_tsval +
1871                             tsval_from_last) ? '1' : ' ',
1872                             SEQ_GT(tsecr, dst->scrub->pfss_tsval) ? '2' : ' ',
1873                             SEQ_LT(tsecr, dst->scrub->pfss_tsval0)? '3' : ' '));
1874 #ifdef __FreeBSD__
1875                         DPFPRINTF((" tsval: %u  tsecr: %u  +ticks: %u  "
1876                             "idle: %jus %lums\n",
1877                             tsval, tsecr, tsval_from_last,
1878                             (uintmax_t)delta_ts.tv_sec,
1879                             delta_ts.tv_usec / 1000));
1880                         DPFPRINTF((" src->tsval: %u  tsecr: %u\n",
1881                             src->scrub->pfss_tsval, src->scrub->pfss_tsecr));
1882                         DPFPRINTF((" dst->tsval: %u  tsecr: %u  tsval0: %u"
1883                             "\n", dst->scrub->pfss_tsval,
1884                             dst->scrub->pfss_tsecr, dst->scrub->pfss_tsval0));
1885 #else
1886                         DPFPRINTF((" tsval: %lu  tsecr: %lu  +ticks: %lu  "
1887                             "idle: %lus %lums\n",
1888                             tsval, tsecr, tsval_from_last, delta_ts.tv_sec,
1889                             delta_ts.tv_usec / 1000));
1890                         DPFPRINTF((" src->tsval: %lu  tsecr: %lu\n",
1891                             src->scrub->pfss_tsval, src->scrub->pfss_tsecr));
1892                         DPFPRINTF((" dst->tsval: %lu  tsecr: %lu  tsval0: %lu"
1893                             "\n", dst->scrub->pfss_tsval,
1894                             dst->scrub->pfss_tsecr, dst->scrub->pfss_tsval0));
1895 #endif
1896                         if (pf_status.debug >= PF_DEBUG_MISC) {
1897                                 pf_print_state(state);
1898                                 pf_print_flags(th->th_flags);
1899                                 printf("\n");
1900                         }
1901                         REASON_SET(reason, PFRES_TS);
1902                         return (PF_DROP);
1903                 }
1904
1905                 /* XXX I'd really like to require tsecr but it's optional */
1906
1907         } else if (!got_ts && (th->th_flags & TH_RST) == 0 &&
1908             ((src->state == TCPS_ESTABLISHED && dst->state == TCPS_ESTABLISHED)
1909             || pd->p_len > 0 || (th->th_flags & TH_SYN)) &&
1910             src->scrub && dst->scrub &&
1911             (src->scrub->pfss_flags & PFSS_PAWS) &&
1912             (dst->scrub->pfss_flags & PFSS_PAWS)) {
1913                 /* Didn't send a timestamp.  Timestamps aren't really useful
1914                  * when:
1915                  *  - connection opening or closing (often not even sent).
1916                  *    but we must not let an attacker to put a FIN on a
1917                  *    data packet to sneak it through our ESTABLISHED check.
1918                  *  - on a TCP reset.  RFC suggests not even looking at TS.
1919                  *  - on an empty ACK.  The TS will not be echoed so it will
1920                  *    probably not help keep the RTT calculation in sync and
1921                  *    there isn't as much danger when the sequence numbers
1922                  *    got wrapped.  So some stacks don't include TS on empty
1923                  *    ACKs :-(
1924                  *
1925                  * To minimize the disruption to mostly RFC1323 conformant
1926                  * stacks, we will only require timestamps on data packets.
1927                  *
1928                  * And what do ya know, we cannot require timestamps on data
1929                  * packets.  There appear to be devices that do legitimate
1930                  * TCP connection hijacking.  There are HTTP devices that allow
1931                  * a 3whs (with timestamps) and then buffer the HTTP request.
1932                  * If the intermediate device has the HTTP response cache, it
1933                  * will spoof the response but not bother timestamping its
1934                  * packets.  So we can look for the presence of a timestamp in
1935                  * the first data packet and if there, require it in all future
1936                  * packets.
1937                  */
1938
1939                 if (pd->p_len > 0 && (src->scrub->pfss_flags & PFSS_DATA_TS)) {
1940                         /*
1941                          * Hey!  Someone tried to sneak a packet in.  Or the
1942                          * stack changed its RFC1323 behavior?!?!
1943                          */
1944                         if (pf_status.debug >= PF_DEBUG_MISC) {
1945                                 DPFPRINTF(("Did not receive expected RFC1323 "
1946                                     "timestamp\n"));
1947                                 pf_print_state(state);
1948                                 pf_print_flags(th->th_flags);
1949                                 printf("\n");
1950                         }
1951                         REASON_SET(reason, PFRES_TS);
1952                         return (PF_DROP);
1953                 }
1954         }
1955
1956
1957         /*
1958          * We will note if a host sends his data packets with or without
1959          * timestamps.  And require all data packets to contain a timestamp
1960          * if the first does.  PAWS implicitly requires that all data packets be
1961          * timestamped.  But I think there are middle-man devices that hijack
1962          * TCP streams immediately after the 3whs and don't timestamp their
1963          * packets (seen in a WWW accelerator or cache).
1964          */
1965         if (pd->p_len > 0 && src->scrub && (src->scrub->pfss_flags &
1966             (PFSS_TIMESTAMP|PFSS_DATA_TS|PFSS_DATA_NOTS)) == PFSS_TIMESTAMP) {
1967                 if (got_ts)
1968                         src->scrub->pfss_flags |= PFSS_DATA_TS;
1969                 else {
1970                         src->scrub->pfss_flags |= PFSS_DATA_NOTS;
1971                         if (pf_status.debug >= PF_DEBUG_MISC && dst->scrub &&
1972                             (dst->scrub->pfss_flags & PFSS_TIMESTAMP)) {
1973                                 /* Don't warn if other host rejected RFC1323 */
1974                                 DPFPRINTF(("Broken RFC1323 stack did not "
1975                                     "timestamp data packet. Disabled PAWS "
1976                                     "security.\n"));
1977                                 pf_print_state(state);
1978                                 pf_print_flags(th->th_flags);
1979                                 printf("\n");
1980                         }
1981                 }
1982         }
1983
1984
1985         /*
1986          * Update PAWS values
1987          */
1988         if (got_ts && src->scrub && PFSS_TIMESTAMP == (src->scrub->pfss_flags &
1989             (PFSS_PAWS_IDLED|PFSS_TIMESTAMP))) {
1990                 getmicrouptime(&src->scrub->pfss_last);
1991                 if (SEQ_GEQ(tsval, src->scrub->pfss_tsval) ||
1992                     (src->scrub->pfss_flags & PFSS_PAWS) == 0)
1993                         src->scrub->pfss_tsval = tsval;
1994
1995                 if (tsecr) {
1996                         if (SEQ_GEQ(tsecr, src->scrub->pfss_tsecr) ||
1997                             (src->scrub->pfss_flags & PFSS_PAWS) == 0)
1998                                 src->scrub->pfss_tsecr = tsecr;
1999
2000                         if ((src->scrub->pfss_flags & PFSS_PAWS) == 0 &&
2001                             (SEQ_LT(tsval, src->scrub->pfss_tsval0) ||
2002                             src->scrub->pfss_tsval0 == 0)) {
2003                                 /* tsval0 MUST be the lowest timestamp */
2004                                 src->scrub->pfss_tsval0 = tsval;
2005                         }
2006
2007                         /* Only fully initialized after a TS gets echoed */
2008                         if ((src->scrub->pfss_flags & PFSS_PAWS) == 0)
2009                                 src->scrub->pfss_flags |= PFSS_PAWS;
2010                 }
2011         }
2012
2013         /* I have a dream....  TCP segment reassembly.... */
2014         return (0);
2015 }
2016
2017 int
2018 pf_normalize_tcpopt(struct pf_rule *r, struct mbuf *m, struct tcphdr *th,
2019     int off)
2020 {
2021         u_int16_t       *mss;
2022         int              thoff;
2023         int              opt, cnt, optlen = 0;
2024         int              rewrite = 0;
2025         u_char          *optp;
2026
2027         thoff = th->th_off << 2;
2028         cnt = thoff - sizeof(struct tcphdr);
2029         optp = mtod(m, caddr_t) + off + sizeof(struct tcphdr);
2030
2031         for (; cnt > 0; cnt -= optlen, optp += optlen) {
2032                 opt = optp[0];
2033                 if (opt == TCPOPT_EOL)
2034                         break;
2035                 if (opt == TCPOPT_NOP)
2036                         optlen = 1;
2037                 else {
2038                         if (cnt < 2)
2039                                 break;
2040                         optlen = optp[1];
2041                         if (optlen < 2 || optlen > cnt)
2042                                 break;
2043                 }
2044                 switch (opt) {
2045                 case TCPOPT_MAXSEG:
2046                         mss = (u_int16_t *)(optp + 2);
2047                         if ((ntohs(*mss)) > r->max_mss) {
2048                                 th->th_sum = pf_cksum_fixup(th->th_sum,
2049                                     *mss, htons(r->max_mss), 0);
2050                                 *mss = htons(r->max_mss);
2051                                 rewrite = 1;
2052                         }
2053                         break;
2054                 default:
2055                         break;
2056                 }
2057         }
2058
2059         return (rewrite);
2060 }