2 * Copyright (C) 1993-2001 by Darren Reed.
4 * See the IPFILTER.LICENCE file for details on licencing.
7 static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.6.2.5 2002/10/03 13:47:19 darrenr Exp $";
10 #if defined(KERNEL) && !defined(_KERNEL)
13 #include <sys/errno.h>
14 #include <sys/types.h>
15 #include <sys/param.h>
17 #include <sys/ioctl.h>
20 #include <sys/socket.h>
27 # include <linux/module.h>
31 #include <net/route.h>
32 #include <netinet/in.h>
33 #include <netinet/in_systm.h>
34 #include <netinet/ip.h>
35 #include <netinet/tcp.h>
36 #include <netinet/udp.h>
37 #include <netinet/ip_icmp.h>
41 #include "netinet/ip_compat.h"
42 #include <netinet/tcpip.h>
43 #include "netinet/ip_fil.h"
44 #include "netinet/ip_nat.h"
45 #include "netinet/ip_proxy.h"
46 #include "netinet/ip_frag.h"
47 #include "netinet/ip_state.h"
48 #include "netinet/ip_auth.h"
50 #include <net/ip_forward.h>
53 #define MIN(a,b) (((a)<(b))?(a):(b))
59 static struct ifnet **ifneta = NULL;
64 int ipl_unreach = ICMP_UNREACH_FILTER;
65 u_long ipl_frouteok[2] = {0, 0};
67 static int frzerostats __P((caddr_t));
68 static void frsync __P((void));
69 #if defined(__NetBSD__) || defined(__OpenBSD__)
70 static int frrequest __P((int, u_long, caddr_t, int));
72 static int frrequest __P((int, u_long, caddr_t, int));
75 static int (*fr_savep) __P((ip_t *, int, void *, int, mb_t **));
77 int ipllog __P((void));
78 void init_ifp __P((void));
79 static int no_output __P((mb_t *, struct ifnet *));
80 static int write_output __P((mb_t *, struct ifnet *));
85 int fr_precheck(struct iphdr *ip, struct device *dev, int out, struct device **ifp)
87 int hlen = ip->ihl << 2;
89 return fr_check((ip_t *)ip, hlen, dev, out, (mb_t **)ifp);
98 if (fr_running || (fr_checkp == fr_precheck)) {
99 printk("IP Filter: already initialized\n");
104 bzero((char *)frcache, sizeof(frcache));
105 bzero((char *)nat_table, sizeof(nat_table));
106 fr_savep = fr_checkp;
107 fr_checkp = fr_precheck;
112 if (fr_pass & FR_PASS)
114 else if (fr_pass & FR_BLOCK)
117 defpass = "no-match -> block";
119 printk("IP Filter: initialized. Default = %s all, Logging = %s\n",
131 * Disable the filter by removing the hooks from the IP input/output
136 int s, i = FR_INQUE|FR_OUTQUE;
140 printk("IP Filter: not initialized\n");
144 fr_checkp = fr_savep;
145 i = frflush(IPL_LOGIPF, i);
153 printk("IP Filter: unloaded\n");
160 static int frzerostats(data)
166 bcopy((char *)frstats, (char *)fio.f_st,
167 sizeof(struct filterstats) * 2);
168 fio.f_fin[0] = ipfilter[0][0];
169 fio.f_fin[1] = ipfilter[0][1];
170 fio.f_fout[0] = ipfilter[1][0];
171 fio.f_fout[1] = ipfilter[1][1];
172 fio.f_acctin[0] = ipacct[0][0];
173 fio.f_acctin[1] = ipacct[0][1];
174 fio.f_acctout[0] = ipacct[1][0];
175 fio.f_acctout[1] = ipacct[1][1];
176 fio.f_active = fr_active;
177 fio.f_froute[0] = ipl_frouteok[0];
178 fio.f_froute[1] = ipl_frouteok[1];
179 error = IWCOPYPTR((caddr_t)&fio, data, sizeof(fio));
181 bzero((char *)frstats, sizeof(*frstats) * 2);
187 * Filter ioctl interface.
190 int iplioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg)
193 caddr_t data = (caddr_t)arg;
195 int mode = file->f_mode;
197 int iplioctl(dev_t dev, int cmd, caddr_t data, int mode)
200 int error = 0, unit = 0, tmp;
203 unit = GET_MINOR(inode->i_rdev);
204 if ((IPL_LOGMAX < unit) || (unit < 0))
208 if (unit == IPL_LOGNAT) {
209 error = nat_ioctl(data, cmd, mode);
212 if (unit == IPL_LOGSTATE) {
213 error = fr_state_ioctl(data, cmd, mode);
220 error = IWCOPY((caddr_t)&iplused[IPL_LOGIPF], data,
221 sizeof(iplused[IPL_LOGIPF]));
224 #if !defined(IPFILTER_LKM) && defined(_KERNEL)
229 if (!(mode & FWRITE))
232 error = IRCOPY(data, (caddr_t)&enable, sizeof(enable));
244 if (!(mode & FWRITE))
247 error = IRCOPY(data, (caddr_t)&fr_flags,
251 error = IWCOPY((caddr_t)&fr_flags, data, sizeof(fr_flags));
257 if (!(mode & FWRITE))
260 error = frrequest(unit, cmd, data, fr_active);
265 if (!(mode & FWRITE))
268 error = frrequest(unit, cmd, data, 1 - fr_active);
271 if (!(mode & FWRITE))
274 bzero((char *)frcache, sizeof(frcache[0]) * 2);
275 *(u_int *)data = fr_active;
276 fr_active = 1 - fr_active;
283 bcopy((char *)frstats, (char *)fio.f_st,
284 sizeof(struct filterstats) * 2);
285 fio.f_fin[0] = ipfilter[0][0];
286 fio.f_fin[1] = ipfilter[0][1];
287 fio.f_fout[0] = ipfilter[1][0];
288 fio.f_fout[1] = ipfilter[1][1];
289 fio.f_acctin[0] = ipacct[0][0];
290 fio.f_acctin[1] = ipacct[0][1];
291 fio.f_acctout[0] = ipacct[1][0];
292 fio.f_acctout[1] = ipacct[1][1];
294 fio.f_active = fr_active;
295 fio.f_froute[0] = ipl_frouteok[0];
296 fio.f_froute[1] = ipl_frouteok[1];
297 error = IWCOPYPTR((caddr_t)&fio, data, sizeof(fio));
301 if (!(mode & FWRITE))
304 error = frzerostats(data);
307 if (!(mode & FWRITE))
310 error = IRCOPY(data, (caddr_t)&tmp, sizeof(tmp));
312 tmp = frflush(unit, tmp);
313 error = IWCOPY((caddr_t)&tmp, data,
320 if (!(mode & FWRITE))
323 *(int *)data = ipflog_clear(unit);
325 #endif /* IPFILTER_LOG */
327 error = IWCOPYPTR((caddr_t)ipfr_fragstats(), data,
331 if (!(mode & FWRITE))
334 #if defined(_KERNEL) && defined(__sgi)
353 for (dev = dev_base; dev; dev = dev->next)
359 static int frrequest(unit, req, data, set)
365 register frentry_t *fp, *f, **fprev;
366 register frentry_t **ftail;
369 frgroup_t *fg = NULL;
374 error = IRCOPYPTR(data, (caddr_t)fp, sizeof(*fp));
379 * Check that the group number does exist and that if a head group
380 * has been specified, doesn't exist.
383 fr_findgroup((u_int)fp->fr_grhead, fp->fr_flags, unit, set, NULL))
386 !fr_findgroup((u_int)fp->fr_group, fp->fr_flags, unit, set, NULL))
389 in = (fp->fr_flags & FR_INQUE) ? 0 : 1;
391 if (unit == IPL_LOGAUTH)
392 ftail = fprev = &ipauth;
393 else if (fp->fr_flags & FR_ACCOUNT)
394 ftail = fprev = &ipacct[in][set];
395 else if (fp->fr_flags & (FR_OUTQUE|FR_INQUE))
396 ftail = fprev = &ipfilter[in][set];
400 if ((group = fp->fr_group)) {
401 if (!(fg = fr_findgroup(group, fp->fr_flags, unit, set, NULL)))
403 ftail = fprev = fg->fg_start;
406 bzero((char *)frcache, sizeof(frcache[0]) * 2);
408 if (*fp->fr_ifname) {
409 fp->fr_ifa = GETUNIT(fp->fr_ifname, fp->fr_ip.fi_v);
411 fp->fr_ifa = (void *)-1;
415 fp->fr_flags &= ~FR_DUP;
416 if (*fdp->fd_ifname) {
417 fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fp->fr_ip.fi_v);
419 fdp->fd_ifp = (struct ifnet *)-1;
421 fp->fr_flags |= FR_DUP;
425 if (*fdp->fd_ifname) {
426 fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fp->fr_ip.fi_v);
428 fdp->fd_ifp = (struct ifnet *)-1;
432 * Look for a matching filter rule, but don't include the next or
433 * interface pointer in the comparison (fr_next, fr_ifa).
435 for (; (f = *ftail); ftail = &f->fr_next)
436 if (bcmp((char *)&f->fr_ip, (char *)&fp->fr_ip,
441 * If zero'ing statistics, copy current to caller and zero.
443 if (req == SIOCZRLST) {
446 error = IWCOPYPTR((caddr_t)f, data, sizeof(*f));
455 if (req == SIOCINAFR || req == SIOCINIFR) {
458 while (--fp->fr_hits && (f = *ftail)) {
466 if (req == SIOCRMAFR || req == SIOCRMIFR) {
472 if (fg && fg->fg_head)
473 fg->fg_head->fr_ref--;
474 if (unit == IPL_LOGAUTH)
475 return fr_auth_ioctl(data, mode, req, f, ftail);
477 fr_delgroup((u_int)f->fr_grhead, fp->fr_flags,
479 fixskip(fprev, f, -1);
487 if (unit == IPL_LOGAUTH)
488 return fr_auth_ioctl(data, mode, req, f, ftail);
489 KMALLOC(f, frentry_t *);
491 if (fg && fg->fg_head)
492 fg->fg_head->fr_ref++;
493 bcopy((char *)fp, (char *)f, sizeof(*f));
498 if (req == SIOCINIFR || req == SIOCINAFR)
499 fixskip(fprev, f, 1);
501 if ((group = f->fr_grhead))
502 fg = fr_addgroup(group, f, unit, set);
513 * routines below for saving IP headers to buffer
515 int iplopen(struct inode *inode, struct file *file)
517 u_int min = GET_MINOR(inode->i_rdev);
519 if (IPL_LOGMAX < min)
529 void iplclose(struct inode *inode, struct file *file)
531 u_int min = GET_MINOR(inode->i_rdev);
533 if (IPL_LOGMAX >= min) {
540 * both of these must operate with at least splnet() lest they be
541 * called during packet processing and cause an inconsistancy to appear in
544 int iplread(struct inode *inode, struct file *file, char *buf, int nbytes)
546 struct uio uiob, *uio = &uiob;
549 uio->uio_resid = nbytes;
551 return ipflog_read(GET_MINOR(inode->i_rdev), uio);
559 * send_reset - this could conceivably be a call to tcp_respond(), but that
560 * requires a large amount of setting up and isn't any more efficient.
562 int send_reset(ti, ifp)
571 if (ti->ti_flags & TH_RST)
572 return -1; /* feedback loop */
574 m = alloc_skb(sizeof(tcpiphdr_t), GFP_ATOMIC);
578 if (ti->ti_flags & TH_SYN)
583 ip = mtod(m, ip_t *);
586 m->m_len = sizeof(tcpiphdr_t);
587 tcp = (tcphdr_t *)((char *)ip + sizeof(ip_t));
588 bzero((char *)ip, sizeof(tcpiphdr_t));
590 ip->ip_v = IPVERSION;
591 ip->ip_hl = sizeof(ip_t) >> 2;
592 ip->ip_tos = ((ip_t *)ti)->ip_tos;
593 ip->ip_p = ((ip_t *)ti)->ip_p;
594 ip->ip_id = ((ip_t *)ti)->ip_id;
595 ip->ip_len = htons(sizeof(tcpiphdr_t));
597 ip->ip_src.s_addr = ti->ti_dst.s_addr;
598 ip->ip_dst.s_addr = ti->ti_src.s_addr;
599 tcp->th_dport = ti->ti_sport;
600 tcp->th_sport = ti->ti_dport;
601 tcp->th_ack = htonl(ntohl(ti->ti_seq) + tlen);
602 tcp->th_off = sizeof(tcphdr_t) >> 2;
603 tcp->th_flags = TH_RST|TH_ACK;
606 ip->ip_sum = ipf_cksum((u_short *)ip, sizeof(ip_t));
607 tcp->th_sum = fr_tcpsum(m, ip, tcp);
608 return ip_forward(m, NULL, IPFWD_NOTTLDEC, ip->ip_dst.s_addr);
612 size_t mbufchainlen(m0)
615 register size_t len = 0;
617 for (; m0; m0 = m0->m_next)
623 void ipfr_fastroute(m0, fin, fdp)
629 register ip_t *ip, *mhip;
630 register mb_t *m = m0;
631 register struct route *ro;
632 struct ifnet *ifp = fdp->fd_ifp;
633 int len, off, error = 0;
634 int hlen = fin->fin_hlen;
635 struct route iproute;
636 struct sockaddr_in *dst;
638 ip = mtod(m0, ip_t *);
643 bzero((caddr_t)ro, sizeof (*ro));
644 dst = (struct sockaddr_in *)&ro->ro_dst;
645 dst->sin_family = AF_INET;
646 dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst;
648 * XXX -allocate route here
651 if (!(fin->fin_fr->fr_flags & FR_FASTROUTE)) {
655 if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) {
656 if (in_localaddr(ip->ip_dst))
657 error = EHOSTUNREACH;
662 if (ro->ro_rt->rt_flags & RTF_GATEWAY)
663 dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
668 * For input packets which are being "fastrouted", they won't
669 * go back through output filtering and miss their chance to get
672 (void) ip_natout(ip, hlen, fin);
676 * If small enough for interface, can just send directly.
678 if (ip->ip_len <= ifp->if_mtu) {
680 ip->ip_id = htons(ip->ip_id);
681 ip->ip_len = htons(ip->ip_len);
682 ip->ip_off = htons(ip->ip_off);
685 ip->ip_sum = in_cksum(m, hlen);
686 error = (*ifp->hard_start_xmit)(m, ifp, m);
690 * Too large for interface; fragment if possible.
691 * Must be able to put at least 8 bytes per fragment.
693 if (ip->ip_off & IP_DF) {
697 len = (ifp->if_mtu - hlen) &~ 7;
704 int mhlen, firstlen = len;
705 mb_t **mnext = &m->m_act;
708 * Loop through length of segment after first fragment,
709 * make new header and copy data of each part and link onto chain.
712 mhlen = sizeof (struct ip);
713 for (off = hlen + len; off < ip->ip_len; off += len) {
714 MGET(m, M_DONTWAIT, MT_HEADER);
719 m->m_data += max_linkhdr;
720 mhip = mtod(m, struct ip *);
721 bcopy((char *)ip, (char *)mhip, sizeof(*ip));
722 if (hlen > sizeof (struct ip)) {
723 mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
724 mhip->ip_hl = mhlen >> 2;
727 mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
728 if (ip->ip_off & IP_MF)
729 mhip->ip_off |= IP_MF;
730 if (off + len >= ip->ip_len)
731 len = ip->ip_len - off;
733 mhip->ip_off |= IP_MF;
734 mhip->ip_len = htons((u_short)(len + mhlen));
735 m->m_next = m_copy(m0, off, len);
736 if (m->m_next == 0) {
737 error = ENOBUFS; /* ??? */
741 mhip->ip_off = htons((u_short)mhip->ip_off);
744 mhip->ip_sum = in_cksum(m, mhlen);
749 * Update first fragment by trimming what's been copied out
750 * and updating header, then send each fragment (in order).
752 m_adj(m0, hlen + firstlen - ip->ip_len);
753 ip->ip_len = htons((u_short)(hlen + firstlen));
754 ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
756 ip->ip_sum = in_cksum(m0, hlen);
758 for (m = m0; m; m = m0) {
762 error = (*ifp->if_output)(ifp, m,
763 (struct sockaddr *)dst);
786 * Fake BSD uiomove() call.
788 int uiomove(caddr_t src, size_t ssize, int rw, struct uio *uio)
791 size_t mv = MIN(ssize, uio->uio_resid);
793 if (rw == UIO_READ) {
794 error = IWCOPY(src, (caddr_t)uio->uio_buf, mv);
795 } else if (rw == UIO_WRITE) {
796 error = IRCOPY((caddr_t)uio->uio_buf, src, mv);
800 uio->uio_resid -= mv;
808 # define IPL_MAJOR 95
812 # define IPL_NAME "/dev/ipl"
815 static struct file_operations ipl_fops = {
821 iplioctl, /* ioctl */
824 iplclose, /* release */
827 NULL, /* check_media_change */
828 NULL, /* revalidate */
832 int init_module(void)
834 int error = 0, major;
836 if (register_chrdev(IPL_MAJOR, "ipf", &ipl_fops)) {
837 printk("ipf: unable to get major number: %d\n", IPL_MAJOR);
847 void cleanup_module(void)
849 unregister_chrdev(IPL_MAJOR, "ipf");
852 # endif /* IPFILTER_LKM */
853 #else /* #ifdef _KERNEL */
856 static int no_output __P((mb_t *m, struct ifnet *ifp))
862 static int write_output __P((mb_t *m, struct ifnet *ifp))
868 ip = mtod(m, ip_t *);
869 sprintf(fname, "/tmp/%s", ifp->name);
870 if ((fp = fopen(fname, "a"))) {
871 fwrite((char *)ip, ntohs(ip->ip_len), 1, fp);
878 struct ifnet *get_unit(name, v)
882 struct ifnet *ifp, **ifa;
885 for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
886 (void) sprintf(ifname, "%s", ifp->name);
887 if (!strcmp(name, ifname))
892 ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2);
894 ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp));
898 ifneta = (struct ifnet **)realloc(ifneta,
899 (nifs + 1) * sizeof(*ifa));
901 ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp));
903 ifp = ifneta[nifs - 1];
905 for (s = name; *s && !isdigit(*s); s++)
907 if (*s && isdigit(*s)) {
908 ifp->name = (char *)malloc(s - name + 1);
909 strncpy(ifp->name, name, s - name);
910 ifp->name[s - name] = '\0';
912 ifp->name = strdup(name);
914 ifp->hard_start_xmit = no_output;
923 struct ifnet *ifp, **ifa;
926 for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
927 ifp->hard_start_xmit = write_output;
928 sprintf(fname, "/tmp/%s", ifp->name);
929 if ((fp = fopen(fname, "w")))
935 void ipfr_fastroute(ip, fin, fdp)
940 struct ifnet *ifp = fdp->fd_ifp;
943 return; /* no routing table out here */
945 ip->ip_len = htons((u_short)ip->ip_len);
946 ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
948 (*ifp->hard_start_xmit)((mb_t *)ip, ifp);
952 int ipllog __P((void))
959 int send_reset(ip, ifp)
963 verbose("- TCP RST sent\n");
968 int icmp_error(ip, ifp)
972 verbose("- TCP RST sent\n");