Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / sys / net / ipfw / ip_fw.c
1 /*
2  * Copyright (c) 1993 Daniel Boulet
3  * Copyright (c) 1994 Ugen J.S.Antsilevich
4  * Copyright (c) 1996 Alex Nash
5  * Copyright (c) 2000-2001 Luigi Rizzo
6  *
7  * Redistribution and use in source forms, with and without modification,
8  * are permitted provided that this entire comment appears intact.
9  *
10  * Redistribution in binary form may occur without any restrictions.
11  * Obviously, it would be nice if you gave credit where credit is due
12  * but requiring it would be too onerous.
13  *
14  * This software is provided ``AS IS'' without any warranties of any kind.
15  *
16  * $FreeBSD: src/sys/netinet/ip_fw.c,v 1.131.2.39 2003/01/20 02:23:07 iedowse Exp $
17  * $DragonFly: src/sys/net/ipfw/Attic/ip_fw.c,v 1.2 2003/06/17 04:28:51 dillon Exp $
18  */
19
20 #define        DEB(x)
21 #define        DDB(x) x
22
23 /*
24  * Implement IP packet firewall
25  */
26
27 #if !defined(KLD_MODULE)
28 #include "opt_ipfw.h"
29 #include "opt_ipdn.h"
30 #include "opt_ipdivert.h"
31 #include "opt_inet.h"
32 #ifndef INET
33 #error IPFIREWALL requires INET.
34 #endif /* INET */
35 #endif
36
37 #if !(IPFW2)
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/malloc.h>
42 #include <sys/mbuf.h>
43 #include <sys/kernel.h>
44 #include <sys/proc.h>
45 #include <sys/socket.h>
46 #include <sys/socketvar.h>
47 #include <sys/sysctl.h>
48 #include <sys/syslog.h>
49 #include <sys/ucred.h>
50 #include <net/if.h>
51 #include <net/route.h>
52 #include <netinet/in.h>
53 #include <netinet/in_systm.h>
54 #include <netinet/in_var.h>
55 #include <netinet/in_pcb.h>
56 #include <netinet/ip.h>
57 #include <netinet/ip_var.h>
58 #include <netinet/ip_icmp.h>
59 #include <netinet/ip_fw.h>
60 #include <netinet/ip_dummynet.h>
61 #include <netinet/tcp.h>
62 #include <netinet/tcp_timer.h>
63 #include <netinet/tcp_var.h>
64 #include <netinet/tcpip.h>
65 #include <netinet/udp.h>
66 #include <netinet/udp_var.h>
67
68 #include <netinet/if_ether.h> /* XXX ethertype_ip */
69
70 static int fw_debug = 1;
71 #ifdef IPFIREWALL_VERBOSE
72 static int fw_verbose = 1;
73 #else
74 static int fw_verbose = 0;
75 #endif
76 #ifdef IPFIREWALL_VERBOSE_LIMIT
77 static int fw_verbose_limit = IPFIREWALL_VERBOSE_LIMIT;
78 #else
79 static int fw_verbose_limit = 0;
80 #endif
81
82 /*
83  * Right now, two fields in the IP header are changed to host format
84  * by the IP layer before calling the firewall. Ideally, we would like
85  * to have them in network format so that the packet can be
86  * used as it comes from the device driver (and is thus readonly).
87  */
88
89 static u_int64_t counter;       /* counter for ipfw_report(NULL...) */
90
91 #define IPFW_DEFAULT_RULE       ((u_int)(u_short)~0)
92
93 LIST_HEAD (ip_fw_head, ip_fw) ip_fw_chain_head;
94
95 MALLOC_DEFINE(M_IPFW, "IpFw/IpAcct", "IpFw/IpAcct chain's");
96
97 #ifdef SYSCTL_NODE
98 SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
99 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, enable, CTLFLAG_RW,
100     &fw_enable, 0, "Enable ipfw");
101 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO,one_pass,CTLFLAG_RW, 
102     &fw_one_pass, 0, 
103     "Only do a single pass through ipfw when using dummynet(4)");
104 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, debug, CTLFLAG_RW, 
105     &fw_debug, 0, "Enable printing of debug ip_fw statements");
106 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose, CTLFLAG_RW, 
107     &fw_verbose, 0, "Log matches to ipfw rules");
108 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit, CTLFLAG_RW, 
109     &fw_verbose_limit, 0, "Set upper limit of matches of ipfw rules logged");
110
111 /*
112  * Extension for stateful ipfw.
113  *
114  * Dynamic rules are stored in lists accessed through a hash table
115  * (ipfw_dyn_v) whose size is curr_dyn_buckets. This value can
116  * be modified through the sysctl variable dyn_buckets which is
117  * updated when the table becomes empty.
118  *
119  * XXX currently there is only one list, ipfw_dyn.
120  *
121  * When a packet is received, it is first hashed, then matched
122  * against the entries in the corresponding list.
123  * Matching occurs according to the rule type. The default is to
124  * match the four fields and the protocol, and rules are bidirectional.
125  *
126  * For a busy proxy/web server we will have lots of connections to
127  * the server. We could decide for a rule type where we ignore
128  * ports (different hashing) and avoid special SYN/RST/FIN handling.
129  *
130  * XXX when we decide to support more than one rule type, we should
131  * repeat the hashing multiple times uing only the useful fields.
132  * Or, we could run the various tests in parallel, because the
133  * 'move to front' technique should shorten the average search.
134  *
135  * The lifetime of dynamic rules is regulated by dyn_*_lifetime,
136  * measured in seconds and depending on the flags.
137  *
138  * The total number of dynamic rules is stored in dyn_count.
139  * The max number of dynamic rules is dyn_max. When we reach
140  * the maximum number of rules we do not create anymore. This is
141  * done to avoid consuming too much memory, but also too much
142  * time when searching on each packet (ideally, we should try instead
143  * to put a limit on the length of the list on each bucket...).
144  *
145  * Each dynamic rules holds a pointer to the parent ipfw rule so
146  * we know what action to perform. Dynamic rules are removed when
147  * the parent rule is deleted.
148  * There are some limitations with dynamic rules -- we do not
149  * obey the 'randomized match', and we do not do multiple
150  * passes through the firewall.
151  * XXX check the latter!!!
152  */
153 static struct ipfw_dyn_rule **ipfw_dyn_v = NULL ;
154 static u_int32_t dyn_buckets = 256 ; /* must be power of 2 */
155 static u_int32_t curr_dyn_buckets = 256 ; /* must be power of 2 */
156
157 /*
158  * timeouts for various events in handing dynamic rules.
159  */
160 static u_int32_t dyn_ack_lifetime = 300 ;
161 static u_int32_t dyn_syn_lifetime = 20 ;
162 static u_int32_t dyn_fin_lifetime = 1 ;
163 static u_int32_t dyn_rst_lifetime = 1 ;
164 static u_int32_t dyn_udp_lifetime = 10 ;
165 static u_int32_t dyn_short_lifetime = 5 ;
166
167 /*
168  * after reaching 0, dynamic rules are considered still valid for
169  * an additional grace time, unless there is lack of resources.
170  */
171 static u_int32_t dyn_grace_time = 10 ;
172
173 static u_int32_t static_count = 0 ;     /* # of static rules */
174 static u_int32_t dyn_count = 0 ;        /* # of dynamic rules */
175 static u_int32_t dyn_max = 1000 ;       /* max # of dynamic rules */
176
177 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_buckets, CTLFLAG_RW,
178     &dyn_buckets, 0, "Number of dyn. buckets");
179 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, curr_dyn_buckets, CTLFLAG_RD,
180     &curr_dyn_buckets, 0, "Current Number of dyn. buckets");
181 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_count, CTLFLAG_RD,
182     &dyn_count, 0, "Number of dyn. rules");
183 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_max, CTLFLAG_RW,
184     &dyn_max, 0, "Max number of dyn. rules");
185 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, static_count, CTLFLAG_RD,
186     &static_count, 0, "Number of static rules");
187 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_ack_lifetime, CTLFLAG_RW,
188     &dyn_ack_lifetime, 0, "Lifetime of dyn. rules for acks");
189 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_syn_lifetime, CTLFLAG_RW,
190     &dyn_syn_lifetime, 0, "Lifetime of dyn. rules for syn");
191 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_fin_lifetime, CTLFLAG_RW,
192     &dyn_fin_lifetime, 0, "Lifetime of dyn. rules for fin");
193 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_rst_lifetime, CTLFLAG_RW,
194     &dyn_rst_lifetime, 0, "Lifetime of dyn. rules for rst");
195 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_udp_lifetime, CTLFLAG_RW,
196     &dyn_udp_lifetime, 0, "Lifetime of dyn. rules for UDP");
197 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime, CTLFLAG_RW,
198     &dyn_short_lifetime, 0, "Lifetime of dyn. rules for other situations");
199 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_grace_time, CTLFLAG_RD,
200     &dyn_grace_time, 0, "Grace time for dyn. rules");
201
202 #endif /* SYSCTL_NODE */
203
204 #define dprintf(a)      do {                                            \
205                                 if (fw_debug)                           \
206                                         printf a;                       \
207                         } while (0)
208 #define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0
209
210 static int      add_entry (struct ip_fw_head *chainptr, struct ip_fw *frwl);
211 static int      del_entry (struct ip_fw_head *chainptr, u_short number);
212 static int      zero_entry (struct ip_fw *, int);
213 static int      check_ipfw_struct (struct ip_fw *m);
214 static int      iface_match (struct ifnet *ifp, union ip_fw_if *ifu,
215                                  int byname);
216 static int      ipopts_match (struct ip *ip, struct ip_fw *f);
217 static __inline int
218                 port_match (u_short *portptr, int nports, u_short port,
219                                 int range_flag, int mask);
220 static int      tcpflg_match (struct tcphdr *tcp, struct ip_fw *f);
221 static int      icmptype_match (struct icmp *  icmp, struct ip_fw * f);
222 static void     ipfw_report (struct ip_fw *f, struct ip *ip, int ip_off,
223                                 int ip_len, struct ifnet *rif,
224                                 struct ifnet *oif);
225
226 static void     flush_rule_ptrs(void);
227
228 static ip_fw_chk_t ip_fw_chk;
229 static int      ip_fw_ctl (struct sockopt *sopt);
230
231 ip_dn_ruledel_t *ip_dn_ruledel_ptr = NULL;
232
233 static char err_prefix[] = "ip_fw_ctl:";
234
235 /*
236  * Returns 1 if the port is matched by the vector, 0 otherwise
237  */
238 static __inline int 
239 port_match(u_short *portptr, int nports, u_short port, int range_flag, int mask)
240 {
241         if (!nports)
242                 return 1;
243         if (mask) {
244                 if ( 0 == ((portptr[0] ^ port) & portptr[1]) )
245                         return 1;
246                 nports -= 2;
247                 portptr += 2;
248         }
249         if (range_flag) {
250                 if (portptr[0] <= port && port <= portptr[1])
251                         return 1;
252                 nports -= 2;
253                 portptr += 2;
254         }
255         while (nports-- > 0)
256                 if (*portptr++ == port)
257                         return 1;
258         return 0;
259 }
260
261 static int
262 tcpflg_match(struct tcphdr *tcp, struct ip_fw *f)
263 {
264         u_char          flg_set, flg_clr;
265
266         /*
267          * If an established connection is required, reject packets that
268          * have only SYN of RST|ACK|SYN set.  Otherwise, fall through to
269          * other flag requirements.
270          */
271         if ((f->fw_ipflg & IP_FW_IF_TCPEST) &&
272             ((tcp->th_flags & (IP_FW_TCPF_RST | IP_FW_TCPF_ACK |
273             IP_FW_TCPF_SYN)) == IP_FW_TCPF_SYN))
274                 return 0;
275
276         flg_set = tcp->th_flags & f->fw_tcpf;
277         flg_clr = tcp->th_flags & f->fw_tcpnf;
278
279         if (flg_set != f->fw_tcpf)
280                 return 0;
281         if (flg_clr)
282                 return 0;
283
284         return 1;
285 }
286
287 static int
288 icmptype_match(struct icmp *icmp, struct ip_fw *f)
289 {
290         int type;
291
292         if (!(f->fw_flg & IP_FW_F_ICMPBIT))
293                 return(1);
294
295         type = icmp->icmp_type;
296
297         /* check for matching type in the bitmap */
298         if (type < IP_FW_ICMPTYPES_MAX &&
299             (f->fw_uar.fw_icmptypes[type / (sizeof(unsigned) * NBBY)] & 
300             (1U << (type % (sizeof(unsigned) * NBBY)))))
301                 return(1);
302
303         return(0); /* no match */
304 }
305
306 static int
307 is_icmp_query(struct ip *ip)
308 {
309         const struct icmp *icmp;
310         int icmp_type;
311
312         icmp = (struct icmp *)((u_int32_t *)ip + ip->ip_hl);
313         icmp_type = icmp->icmp_type;
314
315         if (icmp_type == ICMP_ECHO || icmp_type == ICMP_ROUTERSOLICIT ||
316             icmp_type == ICMP_TSTAMP || icmp_type == ICMP_IREQ ||
317             icmp_type == ICMP_MASKREQ)
318                 return(1);
319
320         return(0);
321 }
322
323 static int
324 ipopts_match(struct ip *ip, struct ip_fw *f)
325 {
326         register u_char *cp;
327         int opt, optlen, cnt;
328         u_char  opts, nopts, nopts_sve;
329
330         cp = (u_char *)(ip + 1);
331         cnt = (ip->ip_hl << 2) - sizeof (struct ip);
332         opts = f->fw_ipopt;
333         nopts = nopts_sve = f->fw_ipnopt;
334
335         for (; cnt > 0; cnt -= optlen, cp += optlen) {
336                 opt = cp[IPOPT_OPTVAL];
337                 if (opt == IPOPT_EOL)
338                         break;
339                 if (opt == IPOPT_NOP)
340                         optlen = 1;
341                 else {
342                         optlen = cp[IPOPT_OLEN];
343                         if (optlen <= 0 || optlen > cnt) {
344                                 return 0; /*XXX*/
345                         }
346                 }
347                 switch (opt) {
348
349                 default:
350                         break;
351
352                 case IPOPT_LSRR:
353                         opts &= ~IP_FW_IPOPT_LSRR;
354                         nopts &= ~IP_FW_IPOPT_LSRR;
355                         break;
356
357                 case IPOPT_SSRR:
358                         opts &= ~IP_FW_IPOPT_SSRR;
359                         nopts &= ~IP_FW_IPOPT_SSRR;
360                         break;
361
362                 case IPOPT_RR:
363                         opts &= ~IP_FW_IPOPT_RR;
364                         nopts &= ~IP_FW_IPOPT_RR;
365                         break;
366                 case IPOPT_TS:
367                         opts &= ~IP_FW_IPOPT_TS;
368                         nopts &= ~IP_FW_IPOPT_TS;
369                         break;
370                 }
371                 if (opts == nopts)
372                         break;
373         }
374         if (opts == 0 && nopts == nopts_sve)
375                 return 1;
376         else
377                 return 0;
378 }
379
380 static int
381 tcpopts_match(struct tcphdr *tcp, struct ip_fw *f)
382 {
383         register u_char *cp;
384         int opt, optlen, cnt;
385         u_char  opts, nopts, nopts_sve;
386
387         cp = (u_char *)(tcp + 1);
388         cnt = (tcp->th_off << 2) - sizeof (struct tcphdr);
389         opts = f->fw_tcpopt;
390         nopts = nopts_sve = f->fw_tcpnopt;
391
392         for (; cnt > 0; cnt -= optlen, cp += optlen) {
393                 opt = cp[0];
394                 if (opt == TCPOPT_EOL)
395                         break;
396                 if (opt == TCPOPT_NOP)
397                         optlen = 1;
398                 else {
399                         optlen = cp[1];
400                         if (optlen <= 0)
401                                 break;
402                 }
403
404
405                 switch (opt) {
406
407                 default:
408                         break;
409
410                 case TCPOPT_MAXSEG:
411                         opts &= ~IP_FW_TCPOPT_MSS;
412                         nopts &= ~IP_FW_TCPOPT_MSS;
413                         break;
414
415                 case TCPOPT_WINDOW:
416                         opts &= ~IP_FW_TCPOPT_WINDOW;
417                         nopts &= ~IP_FW_TCPOPT_WINDOW;
418                         break;
419
420                 case TCPOPT_SACK_PERMITTED:
421                 case TCPOPT_SACK:
422                         opts &= ~IP_FW_TCPOPT_SACK;
423                         nopts &= ~IP_FW_TCPOPT_SACK;
424                         break;
425
426                 case TCPOPT_TIMESTAMP:
427                         opts &= ~IP_FW_TCPOPT_TS;
428                         nopts &= ~IP_FW_TCPOPT_TS;
429                         break;
430
431                 case TCPOPT_CC:
432                 case TCPOPT_CCNEW:
433                 case TCPOPT_CCECHO:
434                         opts &= ~IP_FW_TCPOPT_CC;
435                         nopts &= ~IP_FW_TCPOPT_CC;
436                         break;
437                 }
438                 if (opts == nopts)
439                         break;
440         }
441         if (opts == 0 && nopts == nopts_sve)
442                 return 1;
443         else
444                 return 0;
445 }
446
447 static int
448 iface_match(struct ifnet *ifp, union ip_fw_if *ifu, int byname)
449 {
450         /* Check by name or by IP address */
451         if (byname) {
452                 /* Check unit number (-1 is wildcard) */
453                 if (ifu->fu_via_if.unit != -1
454                     && ifp->if_unit != ifu->fu_via_if.unit)
455                         return(0);
456                 /* Check name */
457                 if (strncmp(ifp->if_name, ifu->fu_via_if.name, FW_IFNLEN))
458                         return(0);
459                 return(1);
460         } else if (ifu->fu_via_ip.s_addr != 0) {        /* Zero == wildcard */
461                 struct ifaddr *ia;
462
463                 TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
464                         if (ia->ifa_addr == NULL)
465                                 continue;
466                         if (ia->ifa_addr->sa_family != AF_INET)
467                                 continue;
468                         if (ifu->fu_via_ip.s_addr != ((struct sockaddr_in *)
469                             (ia->ifa_addr))->sin_addr.s_addr)
470                                 continue;
471                         return(1);
472                 }
473                 return(0);
474         }
475         return(1);
476 }
477
478 static void
479 ipfw_report(struct ip_fw *f, struct ip *ip, int ip_off, int ip_len,
480         struct ifnet *rif, struct ifnet *oif)
481 {
482     struct tcphdr *const tcp = (struct tcphdr *) ((u_int32_t *) ip+ ip->ip_hl);
483     struct udphdr *const udp = (struct udphdr *) ((u_int32_t *) ip+ ip->ip_hl);
484     struct icmp *const icmp = (struct icmp *) ((u_int32_t *) ip + ip->ip_hl);
485     u_int64_t count;
486     char *action;
487     char action2[32], proto[47], name[18], fragment[27];
488     int len;
489     int offset = ip_off & IP_OFFMASK;
490
491     count = f ? f->fw_pcnt : ++counter;
492     if ((f == NULL && fw_verbose_limit != 0 && count > fw_verbose_limit) ||
493         (f && f->fw_logamount != 0 && count > f->fw_loghighest))
494             return;
495
496     /* Print command name */
497     snprintf(SNPARGS(name, 0), "ipfw: %d", f ? f->fw_number : -1);
498
499     action = action2;
500     if (!f)
501             action = "Refuse";
502     else {
503             switch (f->fw_flg & IP_FW_F_COMMAND) {
504             case IP_FW_F_DENY:
505                     action = "Deny";
506                     break;
507             case IP_FW_F_REJECT:
508                     if (f->fw_reject_code == IP_FW_REJECT_RST)
509                             action = "Reset";
510                     else
511                             action = "Unreach";
512                     break;
513             case IP_FW_F_ACCEPT:
514                     action = "Accept";
515                     break;
516             case IP_FW_F_COUNT:
517                     action = "Count";
518                     break;
519 #ifdef IPDIVERT
520             case IP_FW_F_DIVERT:
521                     snprintf(SNPARGS(action2, 0), "Divert %d",
522                         f->fw_divert_port);
523                     break;
524             case IP_FW_F_TEE:
525                     snprintf(SNPARGS(action2, 0), "Tee %d",
526                         f->fw_divert_port);
527                     break;
528 #endif
529             case IP_FW_F_SKIPTO:
530                     snprintf(SNPARGS(action2, 0), "SkipTo %d",
531                         f->fw_skipto_rule);
532                     break;
533             case IP_FW_F_PIPE:
534                     snprintf(SNPARGS(action2, 0), "Pipe %d",
535                         f->fw_skipto_rule);
536                     break;
537             case IP_FW_F_QUEUE:
538                     snprintf(SNPARGS(action2, 0), "Queue %d",
539                         f->fw_skipto_rule);
540                     break;
541
542             case IP_FW_F_FWD:
543                     if (f->fw_fwd_ip.sin_port)
544                             snprintf(SNPARGS(action2, 0),
545                                 "Forward to %s:%d",
546                                 inet_ntoa(f->fw_fwd_ip.sin_addr),
547                                 f->fw_fwd_ip.sin_port);
548                     else
549                             snprintf(SNPARGS(action2, 0), "Forward to %s",
550                                 inet_ntoa(f->fw_fwd_ip.sin_addr));
551                     break;
552
553             default:    
554                     action = "UNKNOWN";
555                     break;
556             }
557     }
558
559     switch (ip->ip_p) {
560     case IPPROTO_TCP:
561             len = snprintf(SNPARGS(proto, 0), "TCP %s",
562                 inet_ntoa(ip->ip_src));
563             if (offset == 0)
564                     len += snprintf(SNPARGS(proto, len), ":%d ",
565                         ntohs(tcp->th_sport));
566             else
567                     len += snprintf(SNPARGS(proto, len), " ");
568             len += snprintf(SNPARGS(proto, len), "%s",
569                 inet_ntoa(ip->ip_dst));
570             if (offset == 0)
571                     snprintf(SNPARGS(proto, len), ":%d",
572                         ntohs(tcp->th_dport));
573             break;
574     case IPPROTO_UDP:
575             len = snprintf(SNPARGS(proto, 0), "UDP %s",
576                 inet_ntoa(ip->ip_src));
577             if (offset == 0)
578                     len += snprintf(SNPARGS(proto, len), ":%d ",
579                         ntohs(udp->uh_sport));
580             else
581                     len += snprintf(SNPARGS(proto, len), " ");
582             len += snprintf(SNPARGS(proto, len), "%s",
583                 inet_ntoa(ip->ip_dst));
584             if (offset == 0)
585                     snprintf(SNPARGS(proto, len), ":%d",
586                         ntohs(udp->uh_dport));
587             break;
588     case IPPROTO_ICMP:
589             if (offset == 0)
590                     len = snprintf(SNPARGS(proto, 0), "ICMP:%u.%u ",
591                         icmp->icmp_type, icmp->icmp_code);
592             else
593                     len = snprintf(SNPARGS(proto, 0), "ICMP ");
594             len += snprintf(SNPARGS(proto, len), "%s",
595                 inet_ntoa(ip->ip_src));
596             snprintf(SNPARGS(proto, len), " %s", inet_ntoa(ip->ip_dst));
597             break;
598     default:
599             len = snprintf(SNPARGS(proto, 0), "P:%d %s", ip->ip_p,
600                 inet_ntoa(ip->ip_src));
601             snprintf(SNPARGS(proto, len), " %s", inet_ntoa(ip->ip_dst));
602             break;
603     }
604
605     if (ip_off & (IP_MF | IP_OFFMASK))
606             snprintf(SNPARGS(fragment, 0), " (frag %d:%d@%d%s)",
607                      ntohs(ip->ip_id), ip_len - (ip->ip_hl << 2),
608                      offset << 3,
609                      (ip_off & IP_MF) ? "+" : "");
610     else
611             fragment[0] = '\0';
612     if (oif)
613             log(LOG_SECURITY | LOG_INFO, "%s %s %s out via %s%d%s\n",
614                 name, action, proto, oif->if_name, oif->if_unit, fragment);
615     else if (rif)
616             log(LOG_SECURITY | LOG_INFO, "%s %s %s in via %s%d%s\n", name,
617                 action, proto, rif->if_name, rif->if_unit, fragment);
618     else
619             log(LOG_SECURITY | LOG_INFO, "%s %s %s%s\n", name, action,
620                 proto, fragment);
621     if ((f ? f->fw_logamount != 0 : 1) &&
622         count == (f ? f->fw_loghighest : fw_verbose_limit))
623             log(LOG_SECURITY | LOG_NOTICE,
624                 "ipfw: limit %d reached on entry %d\n",
625                 f ? f->fw_logamount : fw_verbose_limit,
626                 f ? f->fw_number : -1);
627 }
628
629 static __inline int
630 hash_packet(struct ipfw_flow_id *id)
631 {
632     u_int32_t i ;
633
634     i = (id->dst_ip) ^ (id->src_ip) ^ (id->dst_port) ^ (id->src_port);
635     i &= (curr_dyn_buckets - 1) ;
636     return i ;
637 }
638
639 /**
640  * unlink a dynamic rule from a chain. prev is a pointer to
641  * the previous one, q is a pointer to the rule to delete,
642  * head is a pointer to the head of the queue.
643  * Modifies q and potentially also head.
644  */
645 #define UNLINK_DYN_RULE(prev, head, q) {                                \
646         struct ipfw_dyn_rule *old_q = q;                                \
647                                                                         \
648         /* remove a refcount to the parent */                           \
649         if (q->dyn_type == DYN_LIMIT)                                   \
650                 q->parent->count--;                                     \
651         DEB(printf("-- unlink entry 0x%08x %d -> 0x%08x %d, %d left\n", \
652                 (q->id.src_ip), (q->id.src_port),                       \
653                 (q->id.dst_ip), (q->id.dst_port), dyn_count-1 ); )      \
654         if (prev != NULL)                                               \
655                 prev->next = q = q->next ;                              \
656         else                                                            \
657                 ipfw_dyn_v[i] = q = q->next ;                           \
658         dyn_count-- ;                                                   \
659         free(old_q, M_IPFW); }
660
661 #define TIME_LEQ(a,b)       ((int)((a)-(b)) <= 0)
662 /**
663  * Remove all dynamic rules pointing to a given rule, or all
664  * rules if rule == NULL. Second parameter is 1 if we want to
665  * delete unconditionally, otherwise only expired rules are removed.
666  */
667 static void
668 remove_dyn_rule(struct ip_fw *rule, int force)
669 {
670     struct ipfw_dyn_rule *prev, *q;
671     int i, pass, max_pass ;
672     static u_int32_t last_remove = 0 ;
673
674     if (ipfw_dyn_v == NULL || dyn_count == 0)
675         return ;
676     /* do not expire more than once per second, it is useless */
677     if (force == 0 && last_remove == time_second)
678         return ;
679     last_remove = time_second ;
680
681     /*
682      * because DYN_LIMIT refer to parent rules, during the first pass only
683      * remove child and mark any pending LIMIT_PARENT, and remove
684      * them in a second pass.
685      */
686   for (pass = max_pass = 0; pass <= max_pass ; pass++ ) {
687     for (i = 0 ; i < curr_dyn_buckets ; i++) {
688         for (prev=NULL, q = ipfw_dyn_v[i] ; q ; ) {
689             /*
690              * logic can become complex here, so we split tests.
691              * First, test if we match any rule,
692              * then make sure the rule is expired or we want to kill it,
693              * and possibly more in the future.
694              */
695             int zap = ( rule == NULL || rule == q->rule);
696             if (zap)
697                 zap = force || TIME_LEQ( q->expire , time_second );
698             /* do not zap parent in first pass, record we need a second pass */
699             if (zap && q->dyn_type == DYN_LIMIT_PARENT) {
700                 max_pass = 1; /* we need a second pass */
701                 if (pass == 0 || q->count != 0) {
702                     zap = 0 ;
703                     if (pass == 1 && force) /* should not happen */
704                         printf("OUCH! cannot remove rule, count %d\n",
705                                 q->count);
706                 }
707             }
708             if (zap) {
709                 UNLINK_DYN_RULE(prev, ipfw_dyn_v[i], q);
710             } else {
711                 prev = q ;
712                 q = q->next ;
713             }
714         }
715     }
716   }
717 }
718
719 #define EXPIRE_DYN_CHAIN(rule) remove_dyn_rule(rule, 0 /* expired ones */)
720 #define EXPIRE_DYN_CHAINS() remove_dyn_rule(NULL, 0 /* expired ones */)
721 #define DELETE_DYN_CHAIN(rule) remove_dyn_rule(rule, 1 /* force removal */)
722 #define DELETE_DYN_CHAINS() remove_dyn_rule(NULL, 1 /* force removal */)
723
724 /**
725  * lookup a dynamic rule.
726  */
727 static struct ipfw_dyn_rule *
728 lookup_dyn_rule(struct ipfw_flow_id *pkt, int *match_direction)
729 {
730     /*
731      * stateful ipfw extensions.
732      * Lookup into dynamic session queue
733      */
734     struct ipfw_dyn_rule *prev, *q ;
735     int i, dir = 0;
736 #define MATCH_FORWARD 1
737
738     if (ipfw_dyn_v == NULL)
739         return NULL ;
740     i = hash_packet( pkt );
741     for (prev=NULL, q = ipfw_dyn_v[i] ; q != NULL ; ) {
742         if (q->dyn_type == DYN_LIMIT_PARENT)
743             goto next;
744         if (TIME_LEQ( q->expire , time_second ) ) { /* expire entry */
745             UNLINK_DYN_RULE(prev, ipfw_dyn_v[i], q);
746             continue;
747         }
748         if ( pkt->proto == q->id.proto) {
749             if (pkt->src_ip == q->id.src_ip &&
750                     pkt->dst_ip == q->id.dst_ip &&
751                     pkt->src_port == q->id.src_port &&
752                     pkt->dst_port == q->id.dst_port ) {
753                 dir = MATCH_FORWARD ;
754                 goto found ;
755             }
756             if (pkt->src_ip == q->id.dst_ip &&
757                     pkt->dst_ip == q->id.src_ip &&
758                     pkt->src_port == q->id.dst_port &&
759                     pkt->dst_port == q->id.src_port ) {
760                 dir = 0 ; /* reverse match */
761                 goto found ;
762             }
763         }
764 next:
765         prev = q ;
766         q = q->next ;
767     }
768     return NULL ; /* clearly not found */
769 found:
770     if ( prev != NULL) { /* found and not in front */
771         prev->next = q->next ;
772         q->next = ipfw_dyn_v[i] ;
773         ipfw_dyn_v[i] = q ;
774     }
775     if (pkt->proto == IPPROTO_TCP) {
776         /* update state according to flags */
777         u_char flags = pkt->flags & (TH_FIN|TH_SYN|TH_RST);
778         q->state |= (dir == MATCH_FORWARD ) ? flags : (flags << 8);
779         switch (q->state) {
780         case TH_SYN :
781             /* opening */
782             q->expire = time_second + dyn_syn_lifetime ;
783             break ;
784         case TH_SYN | (TH_SYN << 8) :
785             /* move to established */
786             q->expire = time_second + dyn_ack_lifetime ;
787             break ;
788         case TH_SYN | (TH_SYN << 8) | TH_FIN :
789         case TH_SYN | (TH_SYN << 8) | (TH_FIN << 8) :
790             /* one side tries to close */
791             q->expire = time_second + dyn_ack_lifetime ;
792             break ;
793         case TH_SYN | (TH_SYN << 8) | TH_FIN | (TH_FIN << 8) :
794             /* both sides closed */
795             q->expire = time_second + dyn_fin_lifetime ;
796             break ;
797         default:
798 #if 0
799             /*
800              * reset or some invalid combination, but can also
801              * occur if we use keep-state the wrong way.
802              */
803             if ( (q->state & ((TH_RST << 8)|TH_RST)) == 0)
804                 printf("invalid state: 0x%x\n", q->state);
805 #endif
806             q->expire = time_second + dyn_rst_lifetime ;
807             break ;
808         }
809     } else if (pkt->proto == IPPROTO_UDP) {
810         q->expire = time_second + dyn_udp_lifetime ;
811     } else {
812         /* other protocols */
813         q->expire = time_second + dyn_short_lifetime ;
814     }
815     if (match_direction)
816         *match_direction = dir ;
817     return q ;
818 }
819
820 /**
821  * Install state of type 'type' for a dynamic session.
822  * The hash table contains two type of rules:
823  * - regular rules (DYN_KEEP_STATE)
824  * - rules for sessions with limited number of sess per user
825  *   (DYN_LIMIT). When they are created, the parent is
826  *   increased by 1, and decreased on delete. In this case,
827  *   the third parameter is the parent rule and not the chain.
828  * - "parent" rules for the above (DYN_LIMIT_PARENT).
829  */
830
831 static struct ipfw_dyn_rule *
832 add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
833 {
834     struct ipfw_dyn_rule *r ;
835
836     int i ;
837     if (ipfw_dyn_v == NULL ||
838                 (dyn_count == 0 && dyn_buckets != curr_dyn_buckets)) {
839         /* try reallocation, make sure we have a power of 2 */
840         u_int32_t i = dyn_buckets ;
841         while ( i > 0 && (i & 1) == 0 )
842             i >>= 1 ;
843         if (i != 1) /* not a power of 2 */
844             dyn_buckets = curr_dyn_buckets ; /* reset */
845         else {
846             curr_dyn_buckets = dyn_buckets ;
847             if (ipfw_dyn_v != NULL)
848                 free(ipfw_dyn_v, M_IPFW);
849             ipfw_dyn_v = malloc(curr_dyn_buckets * sizeof r,
850                    M_IPFW, M_DONTWAIT | M_ZERO);
851             if (ipfw_dyn_v == NULL)
852                 return NULL; /* failed ! */
853         }
854     }
855     i = hash_packet(id);
856
857     r = malloc(sizeof *r, M_IPFW, M_DONTWAIT | M_ZERO);
858     if (r == NULL) {
859         printf ("sorry cannot allocate state\n");
860         return NULL ;
861     }
862
863     /* increase refcount on parent, and set pointer */
864     if (dyn_type == DYN_LIMIT) {
865         struct ipfw_dyn_rule *parent = (struct ipfw_dyn_rule *)rule;
866         if ( parent->dyn_type != DYN_LIMIT_PARENT)
867             panic("invalid parent");
868         parent->count++ ;
869         r->parent = parent ;
870         rule = parent->rule;
871     }
872
873     r->id = *id ;
874     r->expire = time_second + dyn_syn_lifetime ;
875     r->rule = rule ;
876     r->dyn_type = dyn_type ;
877     r->pcnt = r->bcnt = 0 ;
878     r->count = 0 ;
879
880     r->bucket = i ;
881     r->next = ipfw_dyn_v[i] ;
882     ipfw_dyn_v[i] = r ;
883     dyn_count++ ;
884     DEB(printf("-- add entry 0x%08x %d -> 0x%08x %d, total %d\n",
885        (r->id.src_ip), (r->id.src_port),
886        (r->id.dst_ip), (r->id.dst_port),
887        dyn_count ); )
888     return r;
889 }
890
891 /**
892  * lookup dynamic parent rule using pkt and rule as search keys.
893  * If the lookup fails, then install one.
894  */
895 static struct ipfw_dyn_rule *
896 lookup_dyn_parent(struct ipfw_flow_id *pkt, struct ip_fw *rule)
897 {
898     struct ipfw_dyn_rule *q;
899     int i;
900
901     if (ipfw_dyn_v) {
902         i = hash_packet( pkt );
903         for (q = ipfw_dyn_v[i] ; q != NULL ; q=q->next)
904             if (q->dyn_type == DYN_LIMIT_PARENT && rule == q->rule &&
905                     pkt->proto == q->id.proto &&
906                     pkt->src_ip == q->id.src_ip &&
907                     pkt->dst_ip == q->id.dst_ip &&
908                     pkt->src_port == q->id.src_port &&
909                     pkt->dst_port == q->id.dst_port) {
910                 q->expire = time_second + dyn_short_lifetime ;
911                 DEB(printf("lookup_dyn_parent found 0x%p\n", q);)
912                 return q;
913             }
914     }
915     return add_dyn_rule(pkt, DYN_LIMIT_PARENT, rule);
916 }
917
918 /*
919  * Install dynamic state.
920  * There are different types of dynamic rules which can be installed.
921  * The type is in rule->dyn_type.
922  * Type 0 (default) is a bidirectional rule
923  *
924  * Returns 1 (failure) if state is not installed because of errors or because
925  * session limitations are enforced.
926  */
927 static int
928 install_state(struct ip_fw *rule, struct ip_fw_args *args)
929 {
930     struct ipfw_dyn_rule *q ;
931     static int last_log ;
932
933     u_int8_t type = rule->dyn_type ;
934
935     DEB(printf("-- install state type %d 0x%08x %u -> 0x%08x %u\n",
936        type,
937        (args->f_id.src_ip), (args->f_id.src_port),
938        (args->f_id.dst_ip), (args->f_id.dst_port) );)
939
940     q = lookup_dyn_rule(&args->f_id, NULL) ;
941     if (q != NULL) { /* should never occur */
942         if (last_log != time_second) {
943             last_log = time_second ;
944             printf(" entry already present, done\n");
945         }
946         return 0 ;
947     }
948     if (dyn_count >= dyn_max) /* try remove old ones... */
949         EXPIRE_DYN_CHAINS();
950     if (dyn_count >= dyn_max) {
951         if (last_log != time_second) {
952             last_log = time_second ;
953             printf(" Too many dynamic rules, sorry\n");
954         }
955         return 1; /* cannot install, notify caller */
956     }
957
958     switch (type) {
959     case DYN_KEEP_STATE: /* bidir rule */
960         add_dyn_rule(&args->f_id, DYN_KEEP_STATE, rule);
961         break ;
962     case DYN_LIMIT: /* limit number of sessions */
963         {
964         u_int16_t limit_mask = rule->limit_mask ;
965         u_int16_t conn_limit = rule->conn_limit ;
966         struct ipfw_flow_id id;
967         struct ipfw_dyn_rule *parent;
968
969         DEB(printf("installing dyn-limit rule %d\n", conn_limit);)
970
971         id.dst_ip = id.src_ip = 0;
972         id.dst_port = id.src_port = 0 ;
973         id.proto = args->f_id.proto ;
974
975         if (limit_mask & DYN_SRC_ADDR)
976             id.src_ip = args->f_id.src_ip;
977         if (limit_mask & DYN_DST_ADDR)
978             id.dst_ip = args->f_id.dst_ip;
979         if (limit_mask & DYN_SRC_PORT)
980             id.src_port = args->f_id.src_port;
981         if (limit_mask & DYN_DST_PORT)
982             id.dst_port = args->f_id.dst_port;
983         parent = lookup_dyn_parent(&id, rule);
984         if (parent == NULL) {
985             printf("add parent failed\n");
986             return 1;
987         }
988         if (parent->count >= conn_limit) {
989             EXPIRE_DYN_CHAIN(rule); /* try to expire some */
990             /*
991              * The expiry might have removed the parent too.
992              * We lookup again, which will re-create if necessary.
993              */
994             parent = lookup_dyn_parent(&id, rule);
995             if (parent == NULL) {
996                 printf("add parent failed\n");
997                 return 1;
998             }
999             if (parent->count >= conn_limit) {
1000                 if (fw_verbose && last_log != time_second) {
1001                         last_log = time_second;
1002                         log(LOG_SECURITY | LOG_DEBUG,
1003                             "drop session, too many entries\n");
1004                 }
1005                 return 1;
1006             }
1007         }
1008         add_dyn_rule(&args->f_id, DYN_LIMIT, (struct ip_fw *)parent);
1009         }
1010         break ;
1011     default:
1012         printf("unknown dynamic rule type %u\n", type);
1013         return 1 ;
1014     }
1015     lookup_dyn_rule(&args->f_id, NULL) ; /* XXX just set the lifetime */
1016     return 0;
1017 }
1018
1019 /*
1020  * given an ip_fw *, lookup_next_rule will return a pointer
1021  * of the same type to the next one. This can be either the jump
1022  * target (for skipto instructions) or the next one in the list (in
1023  * all other cases including a missing jump target).
1024  * Backward jumps are not allowed, so start looking from the next
1025  * rule...
1026  */ 
1027 static struct ip_fw * lookup_next_rule(struct ip_fw *me);
1028
1029 static struct ip_fw *
1030 lookup_next_rule(struct ip_fw *me)
1031 {
1032     struct ip_fw *rule ;
1033     int rulenum = me->fw_skipto_rule ; /* guess... */
1034
1035     if ( (me->fw_flg & IP_FW_F_COMMAND) == IP_FW_F_SKIPTO )
1036         for (rule = LIST_NEXT(me,next); rule ; rule = LIST_NEXT(rule,next))
1037             if (rule->fw_number >= rulenum)
1038                 return rule ;
1039     return LIST_NEXT(me,next) ; /* failure or not a skipto */
1040 }
1041
1042 /*
1043  * Parameters:
1044  *
1045  *      *m      The packet; we set to NULL when/if we nuke it.
1046  *      oif     Outgoing interface, or NULL if packet is incoming
1047  *      *cookie Skip up to the first rule past this rule number;
1048  *              upon return, non-zero port number for divert or tee.
1049  *              Special case: cookie == NULL on input for bridging.
1050  *      *flow_id pointer to the last matching rule (in/out)
1051  *      *next_hop socket we are forwarding to (in/out).
1052  *
1053  * Return value:
1054  *
1055  *      IP_FW_PORT_DENY_FLAG    the packet must be dropped.
1056  *      0       The packet is to be accepted and routed normally OR
1057  *              the packet was denied/rejected and has been dropped;
1058  *              in the latter case, *m is equal to NULL upon return.
1059  *      port    Divert the packet to port, with these caveats:
1060  *
1061  *              - If IP_FW_PORT_TEE_FLAG is set, tee the packet instead
1062  *                of diverting it (ie, 'ipfw tee').
1063  *
1064  *              - If IP_FW_PORT_DYNT_FLAG is set, interpret the lower
1065  *                16 bits as a dummynet pipe number instead of diverting
1066  */
1067
1068 static int 
1069 ip_fw_chk(struct ip_fw_args *args)
1070 {
1071         /*
1072          * grab things into variables to minimize diffs.
1073          * XXX this has to be cleaned up later.
1074          */
1075         struct mbuf **m = &(args->m);
1076         struct ifnet *oif = args->oif;
1077         u_int16_t *cookie = &(args->divert_rule);
1078         struct ip_fw **flow_id = &(args->rule);
1079         struct sockaddr_in **next_hop = &(args->next_hop);
1080
1081         struct ip_fw *f = NULL;         /* matching rule */
1082         struct ip *ip = mtod(*m, struct ip *);
1083         struct ifnet *const rif = (*m)->m_pkthdr.rcvif;
1084         struct ifnet *tif;
1085         u_int hlen = 0;
1086
1087         u_short ip_off=0, offset = 0;
1088         /* local copy of addresses for faster matching */
1089         u_short src_port = 0, dst_port = 0;
1090         struct in_addr src_ip, dst_ip;
1091         u_int8_t proto= 0, flags = 0;
1092         u_int16_t skipto;
1093         u_int16_t ip_len=0;
1094
1095         int dyn_checked = 0 ; /* set after dyn.rules have been checked. */
1096         int direction = MATCH_FORWARD ; /* dirty trick... */
1097         struct ipfw_dyn_rule *q = NULL ;
1098
1099         /* Special hack for bridging (as usual) */
1100 #define BRIDGED         (args->eh != NULL)
1101         if (BRIDGED) {  /* this is a bridged packet */
1102                 if ( (*m)->m_pkthdr.len >= sizeof(struct ip) &&
1103                             ntohs(args->eh->ether_type) == ETHERTYPE_IP)
1104                         hlen = ip->ip_hl << 2;
1105                 else
1106                         return 0; /* XXX ipfw1 always accepts non-ip pkts */
1107         } else
1108                 hlen = ip->ip_hl << 2;
1109
1110         /* Grab and reset cookie */
1111         skipto = *cookie;
1112         *cookie = 0;
1113
1114 #define PULLUP_TO(len)  do {                                            \
1115                             if ((*m)->m_len < (len)) {                  \
1116                                 if ((*m = m_pullup(*m, (len))) == 0)    \
1117                                     goto bogusfrag;                     \
1118                                 ip = mtod(*m, struct ip *);             \
1119                             }                                           \
1120                         } while (0)
1121
1122     if (hlen > 0) { /* this is an IP packet */
1123         /*
1124          * Collect parameters into local variables for faster matching.
1125          */
1126         proto = ip->ip_p;
1127         src_ip = ip->ip_src;
1128         dst_ip = ip->ip_dst;
1129         if (BRIDGED) { /* bridged packets are as on the wire */
1130             ip_off = ntohs(ip->ip_off);
1131             ip_len = ntohs(ip->ip_len);
1132         } else {
1133             ip_off = ip->ip_off;
1134             ip_len = ip->ip_len;
1135         }
1136         offset = ip_off & IP_OFFMASK;
1137         if (offset == 0) {
1138             switch (proto) {
1139             case IPPROTO_TCP : {
1140                 struct tcphdr *tcp;
1141
1142                 PULLUP_TO(hlen + sizeof(struct tcphdr));
1143                 tcp =(struct tcphdr *)((u_int32_t *)ip + ip->ip_hl);
1144                 dst_port = tcp->th_dport ;
1145                 src_port = tcp->th_sport ;
1146                 flags = tcp->th_flags ;
1147                 }
1148                 break ;
1149
1150             case IPPROTO_UDP : {
1151                 struct udphdr *udp;
1152
1153                 PULLUP_TO(hlen + sizeof(struct udphdr));
1154                 udp =(struct udphdr *)((u_int32_t *)ip + ip->ip_hl);
1155                 dst_port = udp->uh_dport ;
1156                 src_port = udp->uh_sport ;
1157                 }
1158                 break;
1159
1160             case IPPROTO_ICMP:
1161                 PULLUP_TO(hlen + 4);    /* type, code and checksum. */
1162                 flags = ((struct icmp *)
1163                         ((u_int32_t *)ip + ip->ip_hl))->icmp_type ;
1164                 break ;
1165
1166             default :
1167                 break;
1168             }
1169         }
1170     }
1171 #undef PULLUP_TO
1172         args->f_id.src_ip = ntohl(src_ip.s_addr);
1173         args->f_id.dst_ip = ntohl(dst_ip.s_addr);
1174         args->f_id.proto = proto;
1175         args->f_id.src_port = ntohs(src_port);
1176         args->f_id.dst_port = ntohs(dst_port);
1177         args->f_id.flags = flags;
1178
1179         if (*flow_id) {
1180             /*
1181              * Packet has already been tagged. Look for the next rule
1182              * to restart processing.
1183              */
1184             if (fw_one_pass) /* just accept if fw_one_pass is set */
1185                 return 0;
1186
1187             f = (*flow_id)->next_rule_ptr ;
1188             if (f == NULL)
1189                 f = (*flow_id)->next_rule_ptr = lookup_next_rule(*flow_id);
1190             if (f == NULL)
1191                 goto dropit;
1192         } else {
1193             /*
1194              * Go down the list, looking for enlightment.
1195              * If we've been asked to start at a given rule, do so.
1196              */
1197             f = LIST_FIRST(&ip_fw_chain_head);
1198             if (skipto != 0) {
1199                 if (skipto >= IPFW_DEFAULT_RULE)
1200                     goto dropit;
1201                 while (f && f->fw_number <= skipto)
1202                     f = LIST_NEXT(f, next);
1203                 if (f == NULL)
1204                     goto dropit;
1205             }
1206         }
1207
1208         for (; f; f = LIST_NEXT(f, next)) {
1209 again:
1210                 if (f->fw_number == IPFW_DEFAULT_RULE)
1211                     goto got_match ;
1212
1213                 /*
1214                  * dynamic rules are checked at the first keep-state or
1215                  * check-state occurrence.
1216                  */
1217                 if (f->fw_flg & (IP_FW_F_KEEP_S|IP_FW_F_CHECK_S) &&
1218                          dyn_checked == 0 ) {
1219                     dyn_checked = 1 ;
1220                     q = lookup_dyn_rule(&args->f_id, &direction);
1221                     if (q != NULL) {
1222                         DEB(printf("-- dynamic match 0x%08x %d %s 0x%08x %d\n",
1223                             (q->id.src_ip), (q->id.src_port),
1224                             (direction == MATCH_FORWARD ? "-->" : "<--"),
1225                             (q->id.dst_ip), (q->id.dst_port) ); )
1226                         f = q->rule ;
1227                         q->pcnt++ ;
1228                         q->bcnt += ip_len;
1229                         goto got_match ; /* random not allowed here */
1230                     }
1231                     /* if this was a check-only rule, continue with next */
1232                     if (f->fw_flg & IP_FW_F_CHECK_S)
1233                         continue ;
1234                 }
1235
1236                 /* Check if rule only valid for bridged packets */
1237                 if ((f->fw_flg & IP_FW_BRIDGED) != 0 && !(BRIDGED))
1238                         continue;
1239
1240                 if (oif) {
1241                         /* Check direction outbound */
1242                         if (!(f->fw_flg & IP_FW_F_OUT))
1243                                 continue;
1244                 } else {
1245                         /* Check direction inbound */
1246                         if (!(f->fw_flg & IP_FW_F_IN))
1247                                 continue;
1248                 }
1249
1250                 /* Fragments */
1251                 if ((f->fw_flg & IP_FW_F_FRAG) && offset == 0 )
1252                         continue;
1253
1254                 if (f->fw_flg & IP_FW_F_SME) {
1255                         INADDR_TO_IFP(src_ip, tif);
1256                         if (tif == NULL)
1257                                 continue;
1258                 }
1259                 if (f->fw_flg & IP_FW_F_DME) {
1260                         INADDR_TO_IFP(dst_ip, tif);
1261                         if (tif == NULL)
1262                                 continue;
1263                 }
1264                 /* If src-addr doesn't match, not this rule. */
1265                 if (((f->fw_flg & IP_FW_F_INVSRC) != 0) ^ ((src_ip.s_addr
1266                     & f->fw_smsk.s_addr) != f->fw_src.s_addr))
1267                         continue;
1268
1269                 /* If dest-addr doesn't match, not this rule. */
1270                 if (((f->fw_flg & IP_FW_F_INVDST) != 0) ^ ((dst_ip.s_addr
1271                     & f->fw_dmsk.s_addr) != f->fw_dst.s_addr))
1272                         continue;
1273
1274                 /* Interface check */
1275                 if ((f->fw_flg & IF_FW_F_VIAHACK) == IF_FW_F_VIAHACK) {
1276                         struct ifnet *const iface = oif ? oif : rif;
1277
1278                         /* Backwards compatibility hack for "via" */
1279                         if (!iface || !iface_match(iface,
1280                             &f->fw_in_if, f->fw_flg & IP_FW_F_OIFNAME))
1281                                 continue;
1282                 } else {
1283                         /* Check receive interface */
1284                         if ((f->fw_flg & IP_FW_F_IIFACE)
1285                             && (!rif || !iface_match(rif,
1286                               &f->fw_in_if, f->fw_flg & IP_FW_F_IIFNAME)))
1287                                 continue;
1288                         /* Check outgoing interface */
1289                         if ((f->fw_flg & IP_FW_F_OIFACE)
1290                             && (!oif || !iface_match(oif,
1291                               &f->fw_out_if, f->fw_flg & IP_FW_F_OIFNAME)))
1292                                 continue;
1293                 }
1294
1295                 /* Check IP options */
1296                 if (f->fw_ipopt != f->fw_ipnopt && !ipopts_match(ip, f))
1297                         continue;
1298
1299                 /* Check protocol; if wildcard, and no [ug]id, match */
1300                 if (f->fw_prot == IPPROTO_IP) {
1301                         if (!(f->fw_flg & (IP_FW_F_UID|IP_FW_F_GID)))
1302                                 goto rnd_then_got_match;
1303                 } else
1304                     /* If different, don't match */
1305                     if (proto != f->fw_prot) 
1306                             continue;
1307
1308                 /* Protocol specific checks for uid only */
1309                 if (f->fw_flg & (IP_FW_F_UID|IP_FW_F_GID)) {
1310                     switch (proto) {
1311                     case IPPROTO_TCP:
1312                         {
1313                             struct inpcb *P;
1314
1315                             if (offset == 1)    /* cf. RFC 1858 */
1316                                     goto bogusfrag;
1317                             if (offset != 0)
1318                                     continue;
1319
1320                             if (oif)
1321                                 P = in_pcblookup_hash(&tcbinfo, dst_ip,
1322                                    dst_port, src_ip, src_port, 0,
1323                                    oif);
1324                             else
1325                                 P = in_pcblookup_hash(&tcbinfo, src_ip,
1326                                    src_port, dst_ip, dst_port, 0,
1327                                    NULL);
1328
1329                             if (P && P->inp_socket) {
1330                                 if (f->fw_flg & IP_FW_F_UID) {
1331                                         if (P->inp_socket->so_cred->cr_uid !=
1332                                             f->fw_uid)
1333                                                 continue;
1334                                 } else if (!groupmember(f->fw_gid,
1335                                             P->inp_socket->so_cred))
1336                                                 continue;
1337                             } else
1338                                 continue;
1339                             break;
1340                         }
1341
1342                     case IPPROTO_UDP:
1343                         {
1344                             struct inpcb *P;
1345
1346                             if (offset != 0)
1347                                 continue;
1348
1349                             if (oif)
1350                                 P = in_pcblookup_hash(&udbinfo, dst_ip,
1351                                    dst_port, src_ip, src_port, 1,
1352                                    oif);
1353                             else
1354                                 P = in_pcblookup_hash(&udbinfo, src_ip,
1355                                    src_port, dst_ip, dst_port, 1,
1356                                    NULL);
1357
1358                             if (P && P->inp_socket) {
1359                                 if (f->fw_flg & IP_FW_F_UID) {
1360                                         if (P->inp_socket->so_cred->cr_uid !=
1361                                             f->fw_uid)
1362                                                 continue;
1363                                 } else if (!groupmember(f->fw_gid,
1364                                             P->inp_socket->so_cred))
1365                                                 continue;
1366                             } else
1367                                 continue;
1368                             break;
1369                         }
1370
1371                     default:
1372                             continue;
1373                     }
1374                 }
1375                     
1376                 /* Protocol specific checks */
1377                 switch (proto) {
1378                 case IPPROTO_TCP:
1379                     {
1380                         struct tcphdr *tcp;
1381
1382                         if (offset == 1)        /* cf. RFC 1858 */
1383                                 goto bogusfrag;
1384                         if (offset != 0) {
1385                                 /*
1386                                  * TCP flags and ports aren't available in this
1387                                  * packet -- if this rule specified either one,
1388                                  * we consider the rule a non-match.
1389                                  */
1390                                 if (IP_FW_HAVEPORTS(f) != 0 ||
1391                                     f->fw_tcpopt != f->fw_tcpnopt ||
1392                                     f->fw_tcpf != f->fw_tcpnf)
1393                                         continue;
1394
1395                                 break;
1396                         }
1397                         tcp = (struct tcphdr *) ((u_int32_t *)ip + ip->ip_hl);
1398
1399                         if (f->fw_tcpopt != f->fw_tcpnopt && !tcpopts_match(tcp, f))
1400                                 continue;
1401                         if (((f->fw_tcpf != f->fw_tcpnf) ||
1402                             (f->fw_ipflg & IP_FW_IF_TCPEST)) &&
1403                             !tcpflg_match(tcp, f))
1404                                 continue;
1405                         goto check_ports;
1406                     }
1407
1408                 case IPPROTO_UDP:
1409                         if (offset != 0) {
1410                                 /*
1411                                  * Port specification is unavailable -- if this
1412                                  * rule specifies a port, we consider the rule
1413                                  * a non-match.
1414                                  */
1415                                 if (IP_FW_HAVEPORTS(f) )
1416                                         continue;
1417
1418                                 break;
1419                         }
1420 check_ports:
1421                         if (!port_match(&f->fw_uar.fw_pts[0],
1422                             IP_FW_GETNSRCP(f), ntohs(src_port),
1423                             f->fw_flg & IP_FW_F_SRNG,
1424                             f->fw_flg & IP_FW_F_SMSK))
1425                                 continue;
1426                         if (!port_match(&f->fw_uar.fw_pts[IP_FW_GETNSRCP(f)],
1427                             IP_FW_GETNDSTP(f), ntohs(dst_port),
1428                             f->fw_flg & IP_FW_F_DRNG,
1429                             f->fw_flg & IP_FW_F_DMSK)) 
1430                                 continue;
1431                         break;
1432
1433                 case IPPROTO_ICMP:
1434                     {
1435                         struct icmp *icmp;
1436
1437                         if (offset != 0)        /* Type isn't valid */
1438                                 break;
1439                         icmp = (struct icmp *) ((u_int32_t *)ip + ip->ip_hl);
1440                         if (!icmptype_match(icmp, f))
1441                                 continue;
1442                         break;
1443                     }
1444
1445                 default:
1446                         break;
1447
1448 bogusfrag:
1449                 if (fw_verbose) {
1450                         if (m != NULL)
1451                                 ipfw_report(NULL, ip, ip_off, ip_len, rif, oif);
1452                         else
1453                                 printf("pullup failed\n");
1454                 }
1455                 goto dropit;
1456
1457                 }
1458
1459 rnd_then_got_match:
1460                 if ( f->dont_match_prob && random() < f->dont_match_prob )
1461                         continue ;
1462 got_match:
1463                 /*
1464                  * If not a dynamic match (q == NULL) and keep-state, install
1465                  * a new dynamic entry.
1466                  */
1467                 if (q == NULL && f->fw_flg & IP_FW_F_KEEP_S) {
1468                     if (install_state(f, args)) /* error or limit violation */
1469                         goto dropit;
1470                 }
1471                 /* Update statistics */
1472                 f->fw_pcnt += 1;
1473                 f->fw_bcnt += ip_len;
1474                 f->timestamp = time_second;
1475
1476                 /* Log to console if desired */
1477                 if ((f->fw_flg & IP_FW_F_PRN) && fw_verbose && hlen > 0)
1478                         ipfw_report(f, ip, offset, ip_len, rif, oif);
1479
1480                 /* Take appropriate action */
1481                 switch (f->fw_flg & IP_FW_F_COMMAND) {
1482                 case IP_FW_F_ACCEPT:
1483                         return(0);
1484                 case IP_FW_F_COUNT:
1485                         continue;
1486 #ifdef IPDIVERT
1487                 case IP_FW_F_DIVERT:
1488                         *cookie = f->fw_number;
1489                         return(f->fw_divert_port);
1490                 case IP_FW_F_TEE:
1491                         *cookie = f->fw_number;
1492                         return(f->fw_divert_port | IP_FW_PORT_TEE_FLAG);
1493 #endif
1494                 case IP_FW_F_SKIPTO: /* XXX check */
1495                         if (f->next_rule_ptr == NULL)
1496                             f->next_rule_ptr = lookup_next_rule(f) ;
1497                         f = f->next_rule_ptr;
1498                         if (!f)
1499                             goto dropit;
1500                         goto again ;
1501
1502                 case IP_FW_F_PIPE:
1503                 case IP_FW_F_QUEUE:
1504                         *flow_id = f ; /* XXX set flow id */
1505                         return(f->fw_pipe_nr | IP_FW_PORT_DYNT_FLAG);
1506
1507                 case IP_FW_F_FWD:
1508                         /* Change the next-hop address for this packet.
1509                          * Initially we'll only worry about directly
1510                          * reachable next-hop's, but ultimately
1511                          * we will work out for next-hops that aren't
1512                          * direct the route we would take for it. We
1513                          * [cs]ould leave this latter problem to
1514                          * ip_output.c. We hope to high [name the abode of
1515                          * your favourite deity] that ip_output doesn't modify
1516                          * the new value of next_hop (which is dst there)
1517                          * XXX warning-- there is a dangerous reference here
1518                          * from next_hop to a field within the rule. If the
1519                          * rule is deleted, weird things might occur.
1520                          */
1521                         if (next_hop != NULL /* Make sure, first... */
1522                             && (q == NULL || direction == MATCH_FORWARD) )
1523                                 *next_hop = &(f->fw_fwd_ip);
1524                         return(0); /* Allow the packet */
1525
1526                 }
1527
1528                 /* Deny/reject this packet using this rule */
1529                 break;
1530         }
1531
1532         /* Rule IPFW_DEFAULT_RULE should always be there and match */
1533         KASSERT(f != NULL, ("ip_fw: no chain"));
1534
1535         /*
1536          * At this point, we're going to drop the packet.
1537          * Send a reject notice if all of the following are true:
1538          *
1539          * - The packet matched a reject rule
1540          * - The packet is not an ICMP packet, or is an ICMP query packet
1541          * - The packet is not a multicast or broadcast packet
1542          */
1543         if ((f->fw_flg & IP_FW_F_COMMAND) == IP_FW_F_REJECT
1544             && (proto != IPPROTO_ICMP || is_icmp_query(ip))
1545             && !((*m)->m_flags & (M_BCAST|M_MCAST))
1546             && !IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
1547                 /* Must convert to host order for icmp_error() etc. */
1548                 if (BRIDGED) {
1549                         ip->ip_len = ntohs(ip->ip_len);
1550                         ip->ip_off = ntohs(ip->ip_off);
1551                 }
1552                 switch (f->fw_reject_code) {
1553                 case IP_FW_REJECT_RST:
1554                   {
1555                         /* XXX warning, this code writes into the mbuf */
1556                         struct tcphdr *const tcp =
1557                                 (struct tcphdr *) ((u_int32_t *)ip + ip->ip_hl);
1558                         struct tcpiphdr ti, *const tip = (struct tcpiphdr *) ip;
1559
1560                         if (offset != 0 || (tcp->th_flags & TH_RST))
1561                                 break;
1562                         ti.ti_i = *((struct ipovly *) ip);
1563                         ti.ti_t = *tcp;
1564                         bcopy(&ti, ip, sizeof(ti));
1565                         NTOHL(tip->ti_seq);
1566                         NTOHL(tip->ti_ack);
1567                         tip->ti_len = ip_len - hlen - (tip->ti_off << 2);
1568                         if (tcp->th_flags & TH_ACK) {
1569                                 tcp_respond(NULL, (void *)ip, tcp, *m,
1570                                     (tcp_seq)0, tcp->th_ack, TH_RST);
1571                         } else {
1572                                 if (tcp->th_flags & TH_SYN)
1573                                         tip->ti_len++;
1574                                 tcp_respond(NULL, (void *)ip, tcp, *m, 
1575                                     tip->ti_seq + tip->ti_len,
1576                                     (tcp_seq)0, TH_RST|TH_ACK);
1577                         }
1578                         *m = NULL;
1579                         break;
1580                   }
1581                 default:        /* Send an ICMP unreachable using code */
1582                         icmp_error(*m, ICMP_UNREACH,
1583                             f->fw_reject_code, 0L, 0);
1584                         *m = NULL;
1585                         break;
1586                 }
1587         }
1588
1589 dropit:
1590         /*
1591          * Finally, drop the packet.
1592          */
1593         return(IP_FW_PORT_DENY_FLAG);
1594 #undef BRIDGED
1595 }
1596
1597 /*
1598  * when a rule is added/deleted, zero the direct pointers within
1599  * all firewall rules. These will be reconstructed on the fly
1600  * as packets are matched.
1601  * Must be called at splimp().
1602  */
1603 static void
1604 flush_rule_ptrs()
1605 {
1606     struct ip_fw *fcp ;
1607
1608     LIST_FOREACH(fcp, &ip_fw_chain_head, next) {
1609         fcp->next_rule_ptr = NULL ;
1610     }
1611 }
1612
1613 void
1614 flush_pipe_ptrs(struct dn_flow_set *match)
1615 {
1616     struct ip_fw *fcp ;
1617
1618     LIST_FOREACH(fcp, &ip_fw_chain_head, next) {
1619         if (match == NULL || fcp->pipe_ptr == match)
1620                 fcp->pipe_ptr = NULL;
1621     }
1622 }
1623
1624 static int
1625 add_entry(struct ip_fw_head *head, struct ip_fw *rule)
1626 {
1627         struct ip_fw *ftmp, *fcp, *fcpl;
1628         u_short nbr = 0;
1629         int s;
1630
1631         ftmp = malloc(sizeof *ftmp, M_IPFW, M_DONTWAIT | M_ZERO);
1632         if (!ftmp)
1633                 return (ENOSPC);
1634         bcopy(rule, ftmp, sizeof(*ftmp));
1635
1636         ftmp->fw_in_if.fu_via_if.name[FW_IFNLEN - 1] = '\0';
1637         ftmp->fw_pcnt = 0L;
1638         ftmp->fw_bcnt = 0L;
1639         ftmp->next_rule_ptr = NULL ;
1640         ftmp->pipe_ptr = NULL ;
1641         
1642         s = splimp();
1643
1644         if (LIST_FIRST(head) == 0) {
1645                 LIST_INSERT_HEAD(head, ftmp, next);
1646                 goto done;
1647         }
1648
1649         /* If entry number is 0, find highest numbered rule and add 100 */
1650         if (ftmp->fw_number == 0) {
1651                 LIST_FOREACH(fcp, head, next) {
1652                         if (fcp->fw_number != IPFW_DEFAULT_RULE)
1653                                 nbr = fcp->fw_number;
1654                         else
1655                                 break;
1656                 }
1657                 if (nbr < IPFW_DEFAULT_RULE - 100)
1658                         nbr += 100;
1659                 ftmp->fw_number = rule->fw_number = nbr;
1660         }
1661
1662         /* Got a valid number; now insert it, keeping the list ordered */
1663         fcpl = NULL ;
1664         LIST_FOREACH(fcp, head, next) {
1665                 if (fcp->fw_number > ftmp->fw_number) {
1666                         if (fcpl) {
1667                                 LIST_INSERT_AFTER(fcpl, ftmp, next);
1668                         } else {
1669                                 LIST_INSERT_HEAD(head, ftmp, next);
1670                         }
1671                         break;
1672                 } else {
1673                         fcpl = fcp;
1674                 }
1675         }
1676         flush_rule_ptrs();
1677 done:
1678         static_count++;
1679         splx(s);
1680         DEB(printf("++ installed rule %d, static count now %d\n",
1681                 ftmp->fw_number, static_count);)
1682         return (0);
1683 }
1684
1685 /**
1686  * free storage associated with a static rule entry (including
1687  * dependent dynamic rules), and zeroes rule pointers to avoid
1688  * dangling pointer dereferences.
1689  * @return a pointer to the next entry.
1690  * Must be called at splimp() and with a non-null argument.
1691  */
1692 static struct ip_fw *
1693 free_chain(struct ip_fw *fcp)
1694 {
1695     struct ip_fw *n;
1696
1697     n = LIST_NEXT(fcp, next);
1698     DELETE_DYN_CHAIN(fcp);
1699     LIST_REMOVE(fcp, next);
1700     static_count--;
1701     if (DUMMYNET_LOADED)
1702         ip_dn_ruledel_ptr(fcp) ;
1703     flush_rule_ptrs(); /* more efficient to do outside the loop */
1704     free(fcp, M_IPFW);
1705     return n;
1706 }
1707
1708 /**
1709  * remove all rules with given number.
1710  */
1711 static int
1712 del_entry(struct ip_fw_head *chainptr, u_short number)
1713 {
1714     struct ip_fw *rule;
1715
1716     if (number != IPFW_DEFAULT_RULE) {
1717         LIST_FOREACH(rule, chainptr, next) {
1718             if (rule->fw_number == number) {
1719                 int s ;
1720
1721                 s = splimp(); /* prevent access to rules while removing */
1722                 while (rule && rule->fw_number == number)
1723                     rule = free_chain(rule);
1724                 /* XXX could move flush_rule_ptrs() here */
1725                 splx(s);
1726                 return 0 ;
1727             }
1728         }
1729     }
1730     return (EINVAL);
1731 }
1732
1733 /**
1734  * Reset some or all counters on firewall rules.
1735  * @arg frwl is null to clear all entries, or contains a specific
1736  * rule number.
1737  * @arg log_only is 1 if we only want to reset logs, zero otherwise.
1738  */
1739
1740 static int
1741 zero_entry(struct ip_fw *frwl, int log_only)
1742 {
1743     struct ip_fw *rule;
1744     int s;
1745     u_short number = 0 ;
1746     char *msg ;
1747
1748     if (frwl == 0) {
1749         s = splimp();
1750         LIST_FOREACH(rule, &ip_fw_chain_head, next) {
1751             if (log_only == 0) {
1752                 rule->fw_bcnt = rule->fw_pcnt = 0;
1753                 rule->timestamp = 0;
1754             }
1755             rule->fw_loghighest = rule->fw_pcnt+rule->fw_logamount;
1756         }
1757         splx(s);
1758         msg = log_only ? "ipfw: All logging counts cleared.\n" :
1759                         "ipfw: Accounting cleared.\n";
1760     } else {
1761         int cleared = 0;
1762         number = frwl->fw_number ;
1763         /*
1764          * It is possible to insert multiple chain entries with the
1765          * same number, so we don't stop after finding the first
1766          * match if zeroing a specific entry.
1767          */
1768         LIST_FOREACH(rule, &ip_fw_chain_head, next)
1769             if (number == rule->fw_number) {
1770                 s = splimp();
1771                 while (rule && number == rule->fw_number) {
1772                     if (log_only == 0) {
1773                         rule->fw_bcnt = rule->fw_pcnt = 0;
1774                         rule->timestamp = 0;
1775                     }
1776                     rule->fw_loghighest = rule->fw_pcnt+ rule->fw_logamount;
1777                     rule = LIST_NEXT(rule, next);
1778                 }
1779                 splx(s);
1780                 cleared = 1;
1781                 break;
1782             }
1783         if (!cleared)   /* we did not find any matching rules */
1784             return (EINVAL);
1785         msg = log_only ? "ipfw: Entry %d logging count reset.\n" :
1786                         "ipfw: Entry %d cleared.\n";
1787     }
1788     if (fw_verbose)
1789         log(LOG_SECURITY | LOG_NOTICE, msg, number);
1790     return (0);
1791 }
1792
1793 static int
1794 check_ipfw_struct(struct ip_fw *frwl)
1795 {
1796         /* Check for invalid flag bits */
1797         if ((frwl->fw_flg & ~IP_FW_F_MASK) != 0) {
1798                 dprintf(("%s undefined flag bits set (flags=%x)\n",
1799                     err_prefix, frwl->fw_flg));
1800                 return (EINVAL);
1801         }
1802         if (frwl->fw_flg == IP_FW_F_CHECK_S) {
1803                 /* check-state */
1804                 return 0 ;
1805         }
1806         /* Must apply to incoming or outgoing (or both) */
1807         if (!(frwl->fw_flg & (IP_FW_F_IN | IP_FW_F_OUT))) {
1808                 dprintf(("%s neither in nor out\n", err_prefix));
1809                 return (EINVAL);
1810         }
1811         /* Empty interface name is no good */
1812         if (((frwl->fw_flg & IP_FW_F_IIFNAME)
1813               && !*frwl->fw_in_if.fu_via_if.name)
1814             || ((frwl->fw_flg & IP_FW_F_OIFNAME)
1815               && !*frwl->fw_out_if.fu_via_if.name)) {
1816                 dprintf(("%s empty interface name\n", err_prefix));
1817                 return (EINVAL);
1818         }
1819         /* Sanity check interface matching */
1820         if ((frwl->fw_flg & IF_FW_F_VIAHACK) == IF_FW_F_VIAHACK) {
1821                 ;               /* allow "via" backwards compatibility */
1822         } else if ((frwl->fw_flg & IP_FW_F_IN)
1823             && (frwl->fw_flg & IP_FW_F_OIFACE)) {
1824                 dprintf(("%s outgoing interface check on incoming\n",
1825                     err_prefix));
1826                 return (EINVAL);
1827         }
1828         /* Sanity check port ranges */
1829         if ((frwl->fw_flg & IP_FW_F_SRNG) && IP_FW_GETNSRCP(frwl) < 2) {
1830                 dprintf(("%s src range set but n_src_p=%d\n",
1831                     err_prefix, IP_FW_GETNSRCP(frwl)));
1832                 return (EINVAL);
1833         }
1834         if ((frwl->fw_flg & IP_FW_F_DRNG) && IP_FW_GETNDSTP(frwl) < 2) {
1835                 dprintf(("%s dst range set but n_dst_p=%d\n",
1836                     err_prefix, IP_FW_GETNDSTP(frwl)));
1837                 return (EINVAL);
1838         }
1839         if (IP_FW_GETNSRCP(frwl) + IP_FW_GETNDSTP(frwl) > IP_FW_MAX_PORTS) {
1840                 dprintf(("%s too many ports (%d+%d)\n",
1841                     err_prefix, IP_FW_GETNSRCP(frwl), IP_FW_GETNDSTP(frwl)));
1842                 return (EINVAL);
1843         }
1844         /*
1845          *      Protocols other than TCP/UDP don't use port range
1846          */
1847         if ((frwl->fw_prot != IPPROTO_TCP) &&
1848             (frwl->fw_prot != IPPROTO_UDP) &&
1849             (IP_FW_GETNSRCP(frwl) || IP_FW_GETNDSTP(frwl))) {
1850                 dprintf(("%s port(s) specified for non TCP/UDP rule\n",
1851                     err_prefix));
1852                 return (EINVAL);
1853         }
1854
1855         /*
1856          *      Rather than modify the entry to make such entries work, 
1857          *      we reject this rule and require user level utilities
1858          *      to enforce whatever policy they deem appropriate.
1859          */
1860         if ((frwl->fw_src.s_addr & (~frwl->fw_smsk.s_addr)) || 
1861                 (frwl->fw_dst.s_addr & (~frwl->fw_dmsk.s_addr))) {
1862                 dprintf(("%s rule never matches\n", err_prefix));
1863                 return (EINVAL);
1864         }
1865
1866         if ((frwl->fw_flg & IP_FW_F_FRAG) &&
1867                 (frwl->fw_prot == IPPROTO_UDP || frwl->fw_prot == IPPROTO_TCP)) {
1868                 if (IP_FW_HAVEPORTS(frwl)) {
1869                         dprintf(("%s cannot mix 'frag' and ports\n", err_prefix));
1870                         return (EINVAL);
1871                 }
1872                 if (frwl->fw_prot == IPPROTO_TCP &&
1873                         frwl->fw_tcpf != frwl->fw_tcpnf) {
1874                         dprintf(("%s cannot mix 'frag' and TCP flags\n", err_prefix));
1875                         return (EINVAL);
1876                 }
1877         }
1878
1879         /* Check command specific stuff */
1880         switch (frwl->fw_flg & IP_FW_F_COMMAND) {
1881         case IP_FW_F_REJECT:
1882                 if (frwl->fw_reject_code >= 0x100
1883                     && !(frwl->fw_prot == IPPROTO_TCP
1884                       && frwl->fw_reject_code == IP_FW_REJECT_RST)) {
1885                         dprintf(("%s unknown reject code\n", err_prefix));
1886                         return (EINVAL);
1887                 }
1888                 break;
1889 #ifdef IPDIVERT
1890         case IP_FW_F_DIVERT:            /* Diverting to port zero is invalid */
1891         case IP_FW_F_TEE:
1892 #endif
1893         case IP_FW_F_PIPE:              /* pipe 0 is invalid */
1894         case IP_FW_F_QUEUE:             /* queue 0 is invalid */
1895                 if (frwl->fw_divert_port == 0) {
1896                         dprintf(("%s 0 is an invalid argument\n", err_prefix));
1897                         return (EINVAL);
1898                 }
1899                 break;
1900         case IP_FW_F_DENY:
1901         case IP_FW_F_ACCEPT:
1902         case IP_FW_F_COUNT:
1903         case IP_FW_F_SKIPTO:
1904         case IP_FW_F_FWD:
1905         case IP_FW_F_UID:
1906         case IP_FW_F_GID:
1907                 break;
1908         default:
1909                 dprintf(("%s invalid command\n", err_prefix));
1910                 return (EINVAL);
1911         }
1912
1913         return 0;
1914 }
1915
1916 static int
1917 ip_fw_ctl(struct sockopt *sopt)
1918 {
1919         int error, s;
1920         size_t size;
1921         struct ip_fw *fcp;
1922         struct ip_fw frwl, *bp , *buf;
1923
1924         /*
1925          * Disallow modifications in really-really secure mode, but still allow
1926          * the logging counters to be reset.
1927          */
1928         if (securelevel >= 3 && (sopt->sopt_name == IP_FW_ADD ||
1929             (sopt->sopt_dir == SOPT_SET && sopt->sopt_name != IP_FW_RESETLOG)))
1930                         return (EPERM);
1931         error = 0;
1932
1933         switch (sopt->sopt_name) {
1934         case IP_FW_GET:
1935                 /*
1936                  * pass up a copy of the current rules. Static rules
1937                  * come first (the last of which has number 65535),
1938                  * followed by a possibly empty list of dynamic rule.
1939                  * The last dynamic rule has NULL in the "next" field.
1940                  */
1941                 s = splimp();
1942                 /* size of static rules */
1943                 size = static_count * sizeof(struct ip_fw) ;
1944                 if (ipfw_dyn_v)         /* add size of dyn.rules */
1945                     size += (dyn_count * sizeof(struct ipfw_dyn_rule));
1946
1947                 /*
1948                  * XXX todo: if the user passes a short length to know how
1949                  * much room is needed, do not
1950                  * bother filling up the buffer, just jump to the
1951                  * sooptcopyout.
1952                  */
1953                 buf = malloc(size, M_TEMP, M_WAITOK);
1954                 if (buf == 0) {
1955                     splx(s);
1956                     error = ENOBUFS;
1957                     break;
1958                 }
1959
1960                 bp = buf ;
1961                 LIST_FOREACH(fcp, &ip_fw_chain_head, next) {
1962                     bcopy(fcp, bp, sizeof *fcp);
1963                     bp++;
1964                 }
1965                 if (ipfw_dyn_v) {
1966                     int i ;
1967                     struct ipfw_dyn_rule *p, *dst, *last = NULL ;
1968
1969                     dst = (struct ipfw_dyn_rule *)bp ;
1970                     for (i = 0 ; i < curr_dyn_buckets ; i++ )
1971                         for ( p = ipfw_dyn_v[i] ; p != NULL ; p = p->next, dst++ ) {
1972                             bcopy(p, dst, sizeof *p);
1973                             (int)dst->rule = p->rule->fw_number ;
1974                             /*
1975                              * store a non-null value in "next". The userland
1976                              * code will interpret a NULL here as a marker
1977                              * for the last dynamic rule.
1978                              */
1979                             dst->next = dst ;
1980                             last = dst ;
1981                             if (TIME_LEQ(dst->expire, time_second) )
1982                                 dst->expire = 0 ;
1983                             else
1984                                 dst->expire -= time_second ;
1985                             }
1986                     if (last != NULL)
1987                         last->next = NULL ; /* mark last dynamic rule */
1988                 }
1989                 splx(s);
1990
1991                 error = sooptcopyout(sopt, buf, size);
1992                 free(buf, M_TEMP);
1993                 break;
1994
1995         case IP_FW_FLUSH:
1996                 /*
1997                  * Normally we cannot release the lock on each iteration.
1998                  * We could do it here only because we start from the head all
1999                  * the times so there is no risk of missing some entries.
2000                  * On the other hand, the risk is that we end up with
2001                  * a very inconsistent ruleset, so better keep the lock
2002                  * around the whole cycle.
2003                  * 
2004                  * XXX this code can be improved by resetting the head of
2005                  * the list to point to the default rule, and then freeing
2006                  * the old list without the need for a lock.
2007                  */
2008
2009                 s = splimp();
2010                 while ( (fcp = LIST_FIRST(&ip_fw_chain_head)) &&
2011                         fcp->fw_number != IPFW_DEFAULT_RULE )
2012                     free_chain(fcp);
2013                 splx(s);
2014                 break;
2015
2016         case IP_FW_ADD:
2017                 error = sooptcopyin(sopt, &frwl, sizeof frwl, sizeof frwl);
2018                 if (error || (error = check_ipfw_struct(&frwl)))
2019                         break;
2020
2021                 if (frwl.fw_number == IPFW_DEFAULT_RULE) {
2022                         dprintf(("%s can't add rule %u\n", err_prefix,
2023                                  (unsigned)IPFW_DEFAULT_RULE));
2024                         error = EINVAL;
2025                 } else {
2026                         error = add_entry(&ip_fw_chain_head, &frwl);
2027                         if (!error && sopt->sopt_dir == SOPT_GET)
2028                                 error = sooptcopyout(sopt, &frwl, sizeof frwl);
2029                 }
2030                 break;
2031
2032         case IP_FW_DEL:
2033                 error = sooptcopyin(sopt, &frwl, sizeof frwl, sizeof frwl);
2034                 if (error)
2035                         break;
2036
2037                 if (frwl.fw_number == IPFW_DEFAULT_RULE) {
2038                         dprintf(("%s can't delete rule %u\n", err_prefix,
2039                                  (unsigned)IPFW_DEFAULT_RULE));
2040                         error = EINVAL;
2041                 } else {
2042                         error = del_entry(&ip_fw_chain_head, frwl.fw_number);
2043                 }
2044                 break;
2045
2046         case IP_FW_ZERO:
2047         case IP_FW_RESETLOG:
2048             {
2049                 int cmd = (sopt->sopt_name == IP_FW_RESETLOG );
2050                 void *arg = NULL ;
2051
2052                 if (sopt->sopt_val != 0) {
2053                     error = sooptcopyin(sopt, &frwl, sizeof frwl, sizeof frwl);
2054                     if (error)
2055                         break;
2056                     arg = &frwl ;
2057                 }
2058                 error = zero_entry(arg, cmd);
2059             }
2060             break;
2061
2062         default:
2063                 printf("ip_fw_ctl invalid option %d\n", sopt->sopt_name);
2064                 error = EINVAL ;
2065         }
2066
2067         return (error);
2068 }
2069
2070 /**
2071  * dummynet needs a reference to the default rule, because rules can
2072  * be deleted while packets hold a reference to them (e.g. to resume
2073  * processing at the next rule). When this happens, dummynet changes
2074  * the reference to the default rule (probably it could well be a
2075  * NULL pointer, but this way we do not need to check for the special
2076  * case, plus here he have info on the default behaviour.
2077  */
2078 struct ip_fw *ip_fw_default_rule ;
2079
2080 void
2081 ip_fw_init(void)
2082 {
2083         struct ip_fw default_rule;
2084
2085         ip_fw_chk_ptr = ip_fw_chk;
2086         ip_fw_ctl_ptr = ip_fw_ctl;
2087         LIST_INIT(&ip_fw_chain_head);
2088
2089         bzero(&default_rule, sizeof default_rule);
2090         default_rule.fw_prot = IPPROTO_IP;
2091         default_rule.fw_number = IPFW_DEFAULT_RULE;
2092 #ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
2093         default_rule.fw_flg |= IP_FW_F_ACCEPT;
2094 #else
2095         default_rule.fw_flg |= IP_FW_F_DENY;
2096 #endif
2097         default_rule.fw_flg |= IP_FW_F_IN | IP_FW_F_OUT;
2098         if (check_ipfw_struct(&default_rule) != 0 ||
2099             add_entry(&ip_fw_chain_head, &default_rule))
2100                 panic("ip_fw_init");
2101
2102         ip_fw_default_rule = LIST_FIRST(&ip_fw_chain_head) ;
2103         printf("IP packet filtering initialized, "
2104 #ifdef IPDIVERT
2105                 "divert enabled, "
2106 #else
2107                 "divert disabled, "
2108 #endif
2109                 "rule-based forwarding enabled, "
2110 #ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
2111                 "default to accept, ");
2112 #else
2113                 "default to deny, " );
2114 #endif
2115 #ifndef IPFIREWALL_VERBOSE
2116         printf("logging disabled\n");
2117 #else
2118         if (fw_verbose_limit == 0)
2119                 printf("unlimited logging\n");
2120         else
2121                 printf("logging limited to %d packets/entry by default\n",
2122                     fw_verbose_limit);
2123 #endif
2124 }
2125
2126 static int
2127 ipfw_modevent(module_t mod, int type, void *unused)
2128 {
2129         int s;
2130         int err = 0 ;
2131 #if defined(KLD_MODULE)
2132         struct ip_fw *fcp;
2133 #endif
2134         
2135         switch (type) {
2136         case MOD_LOAD:
2137                 s = splimp();
2138                 if (IPFW_LOADED) {
2139                         splx(s);
2140                         printf("IP firewall already loaded\n");
2141                         err = EEXIST ;
2142                 } else {
2143                         ip_fw_init();
2144                         splx(s);
2145                 }
2146                 break ;
2147         case MOD_UNLOAD:
2148 #if !defined(KLD_MODULE)
2149                 printf("ipfw statically compiled, cannot unload\n");
2150                 err = EBUSY;
2151 #else
2152                 s = splimp();
2153                 ip_fw_chk_ptr = NULL ;
2154                 ip_fw_ctl_ptr = NULL ;
2155                 while ( (fcp = LIST_FIRST(&ip_fw_chain_head)) != NULL)
2156                         free_chain(fcp);
2157                 splx(s);
2158                 printf("IP firewall unloaded\n");
2159 #endif
2160                 break ;
2161
2162         default:
2163                 break;
2164         }
2165         return err;
2166 }
2167
2168 static moduledata_t ipfwmod = {
2169         "ipfw",
2170         ipfw_modevent,
2171         0
2172 };
2173 DECLARE_MODULE(ipfw, ipfwmod, SI_SUB_PSEUDO, SI_ORDER_ANY);
2174 #endif /* !IPFW2 */