2 * Copyright (C) 1993-1997 by Darren Reed.
4 * Redistribution and use in source and binary forms are permitted
5 * provided that this notice is preserved and due credit is given
6 * to the original author and the contributors.
9 static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-1995 Darren Reed";
10 static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.0.2.44.2.7 1998/05/03 10:55:49 darrenr Exp $";
14 #define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
17 #if defined(KERNEL) && !defined(_KERNEL)
21 # if defined(_KERNEL) && !defined(IPFILTER_LKM)
22 # include <sys/osreldate.h>
24 # include <osreldate.h>
33 #include <sys/errno.h>
34 #include <sys/types.h>
35 #include <sys/param.h>
37 #if __FreeBSD_version >= 220000 && defined(_KERNEL)
38 # include <sys/fcntl.h>
39 # include <sys/filio.h>
41 # include <sys/ioctl.h>
45 # include <sys/systm.h>
49 # if (NetBSD > 199609) || (OpenBSD > 199603)
50 # include <sys/dirent.h>
54 # include <sys/mbuf.h>
56 # include <sys/filio.h>
58 #include <sys/protosw.h>
59 #include <sys/socket.h>
65 #if __FreeBSD_version >= 300000
66 # include <net/if_var.h>
69 #include <sys/debug.h>
70 # ifdef IFF_DRVRLOCK /* IRIX6 */
71 #include <sys/hashing.h>
74 #include <net/route.h>
75 #include <netinet/in.h>
76 #if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /* IRIX < 6 */
77 #include <netinet/in_var.h>
79 #include <netinet/in_systm.h>
80 #include <netinet/ip.h>
81 #include <netinet/ip_var.h>
82 #include <netinet/tcp.h>
83 #include <netinet/udp.h>
84 #include <netinet/tcpip.h>
85 #include <netinet/ip_icmp.h>
89 #include "netinet/ip_compat.h"
90 #include "netinet/ip_fil.h"
91 #include "netinet/ip_proxy.h"
92 #include "netinet/ip_nat.h"
93 #include "netinet/ip_frag.h"
94 #include "netinet/ip_state.h"
95 #include "netinet/ip_auth.h"
97 #define MIN(a,b) (((a)<(b))?(a):(b))
99 #if !SOLARIS && defined(_KERNEL)
100 extern int ip_optcopy __P((struct ip *, struct ip *));
104 extern struct protosw inetsw[];
108 static struct ifnet **ifneta = NULL;
111 # if (BSD < 199306) && !defined(__sgi)
112 static int (*fr_saveslowtimo) __P((void));
114 static void (*fr_saveslowtimo) __P((void));
116 # if (BSD < 199306) || defined(__sgi)
122 int ipl_unreach = ICMP_UNREACH_FILTER;
123 u_long ipl_frouteok[2] = {0, 0};
125 static void fixskip __P((frentry_t **, frentry_t *, int));
126 static void frzerostats __P((caddr_t));
127 static void frsync __P((void));
128 #if defined(__NetBSD__) || defined(__OpenBSD__)
129 static int frrequest __P((int, u_long, caddr_t, int));
131 static int frrequest __P((int, int, caddr_t, int));
134 static int (*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **));
136 int ipllog __P((void));
137 void init_ifp __P((void));
139 static int no_output __P((struct ifnet *, struct mbuf *,
141 static int write_output __P((struct ifnet *, struct mbuf *,
144 static int no_output __P((struct ifnet *, struct mbuf *,
145 struct sockaddr *, struct rtentry *));
146 static int write_output __P((struct ifnet *, struct mbuf *,
147 struct sockaddr *, struct rtentry *));
151 #if (_BSDI_VERSION >= 199510) && defined(_KERNEL)
152 # include <sys/device.h>
153 # include <sys/conf.h>
155 struct cfdriver iplcd = {
156 NULL, "ipl", NULL, NULL, DV_DULL, 0
159 struct devsw iplsw = {
161 iplopen, iplclose, iplread, nowrite, iplioctl, noselect, nommap,
162 nostrat, nodump, nopsize, 0,
165 #endif /* _BSDI_VERSION >= 199510 && _KERNEL */
167 #if defined(__NetBSD__) || defined(__OpenBSD__) || (_BSDI_VERSION >= 199701)
168 # include <sys/conf.h>
169 # if defined(NETBSD_PF)
170 # include <net/pfil.h>
172 * We provide the fr_checkp name just to minimize changes later.
174 int (*fr_checkp) __P((ip_t *ip, int hlen, void *ifp, int out, mb_t **mp));
175 # endif /* NETBSD_PF */
176 #endif /* __NetBSD__ */
179 # if defined(IPFILTER_LKM) && !defined(__sgi)
183 if (strcmp(s, "ipl") == 0)
187 # endif /* IPFILTER_LKM */
191 * Try to detect the case when compiling for NetBSD with pseudo-device
193 # if defined(__NetBSD__) && defined(PFIL_HOOKS)
195 ipfilterattach(count)
212 if (ipl_inited || (fr_checkp == fr_check)) {
213 printf("IP Filter: already initialized\n");
219 pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
223 error = ipfilter_sgi_attach();
231 bzero((char *)frcache, sizeof(frcache));
232 bzero((char *)nat_table, sizeof(nat_table));
233 fr_savep = fr_checkp;
234 fr_checkp = fr_check;
235 fr_saveslowtimo = inetsw[0].pr_slowtimo;
236 inetsw[0].pr_slowtimo = ipfr_slowtimer;
242 if (fr_pass & FR_PASS)
244 else if (fr_pass & FR_BLOCK)
247 defpass = "no-match -> block";
249 printf("IP Filter: initialized. Default = %s all, Logging = %s\n",
261 * Disable the filter by removing the hooks from the IP input/output
266 int s, i = FR_INQUE|FR_OUTQUE;
271 printf("IP Filter: not initialized\n");
276 fr_checkp = fr_savep;
277 inetsw[0].pr_slowtimo = fr_saveslowtimo;
278 frflush(IPL_LOGIPF, &i);
282 pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
286 ipfilter_sgi_detach();
300 static void frzerostats(data)
305 bcopy((char *)frstats, (char *)fio.f_st,
306 sizeof(struct filterstats) * 2);
307 fio.f_fin[0] = ipfilter[0][0];
308 fio.f_fin[1] = ipfilter[0][1];
309 fio.f_fout[0] = ipfilter[1][0];
310 fio.f_fout[1] = ipfilter[1][1];
311 fio.f_acctin[0] = ipacct[0][0];
312 fio.f_acctin[1] = ipacct[0][1];
313 fio.f_acctout[0] = ipacct[1][0];
314 fio.f_acctout[1] = ipacct[1][1];
315 fio.f_active = fr_active;
316 fio.f_froute[0] = ipl_frouteok[0];
317 fio.f_froute[1] = ipl_frouteok[1];
318 IWCOPY((caddr_t)&fio, data, sizeof(fio));
319 bzero((char *)frstats, sizeof(*frstats) * 2);
324 * Filter ioctl interface.
327 int IPL_EXTERN(ioctl)(dev_t dev, int cmd, caddr_t data, int mode
329 , cred_t *cp, int *rp
333 int IPL_EXTERN(ioctl)(dev, cmd, data, mode
334 #if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
335 (__FreeBSD_version >= 220000)) && defined(_KERNEL)
342 #if defined(__NetBSD__) || defined(__OpenBSD__) || (_BSDI_VERSION >= 199701)
351 #if defined(_KERNEL) && !SOLARIS
354 int error = 0, unit = 0, tmp;
357 unit = GET_MINOR(dev);
358 if ((IPL_LOGMAX < unit) || (unit < 0))
364 if (unit == IPL_LOGNAT) {
365 error = nat_ioctl(data, cmd, mode);
369 if (unit == IPL_LOGSTATE) {
370 error = fr_state_ioctl(data, cmd, mode);
377 IWCOPY((caddr_t)&iplused[IPL_LOGIPF], (caddr_t)data,
378 sizeof(iplused[IPL_LOGIPF]));
381 #if !defined(IPFILTER_LKM) && defined(_KERNEL)
386 if (!(mode & FWRITE))
389 IRCOPY(data, (caddr_t)&enable, sizeof(enable));
399 if (!(mode & FWRITE))
402 IRCOPY(data, (caddr_t)&fr_flags, sizeof(fr_flags));
405 IWCOPY((caddr_t)&fr_flags, data, sizeof(fr_flags));
411 if (!(mode & FWRITE))
414 error = frrequest(unit, cmd, data, fr_active);
419 if (!(mode & FWRITE))
422 error = frrequest(unit, cmd, data, 1 - fr_active);
425 if (!(mode & FWRITE))
428 bzero((char *)frcache, sizeof(frcache[0]) * 2);
429 *(u_int *)data = fr_active;
430 fr_active = 1 - fr_active;
437 bcopy((char *)frstats, (char *)fio.f_st,
438 sizeof(struct filterstats) * 2);
439 fio.f_fin[0] = ipfilter[0][0];
440 fio.f_fin[1] = ipfilter[0][1];
441 fio.f_fout[0] = ipfilter[1][0];
442 fio.f_fout[1] = ipfilter[1][1];
443 fio.f_acctin[0] = ipacct[0][0];
444 fio.f_acctin[1] = ipacct[0][1];
445 fio.f_acctout[0] = ipacct[1][0];
446 fio.f_acctout[1] = ipacct[1][1];
448 fio.f_active = fr_active;
449 fio.f_froute[0] = ipl_frouteok[0];
450 fio.f_froute[1] = ipl_frouteok[1];
451 IWCOPY((caddr_t)&fio, data, sizeof(fio));
455 if (!(mode & FWRITE))
461 if (!(mode & FWRITE))
464 IRCOPY(data, (caddr_t)&tmp, sizeof(tmp));
466 IWCOPY((caddr_t)&tmp, data, sizeof(tmp));
471 if (!(mode & FWRITE))
474 *(int *)data = ipflog_clear(unit);
476 #endif /* IPFILTER_LOG */
478 IWCOPY((caddr_t)ipfr_fragstats(), data, sizeof(ipfrstat_t));
482 if (!(mode & FWRITE)) {
487 error = fr_auth_ioctl(data, cmd, NULL, NULL);
490 if (!(mode & FWRITE))
493 #if defined(_KERNEL) && defined(__sgi)
513 # if defined(__OpenBSD__) || (NetBSD >= 199511)
514 for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
516 for (ifp = ifnet; ifp; ifp = ifp->if_next)
523 static void fixskip(listp, rp, addremove)
524 frentry_t **listp, *rp;
528 int rules = 0, rn = 0;
530 for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rules++)
536 for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rn++)
537 if (fp->fr_skip && (rn + fp->fr_skip >= rules))
538 fp->fr_skip += addremove;
542 static int frrequest(unit, req, data, set)
544 #if defined(__NetBSD__) || defined(__OpenBSD__)
552 register frentry_t *fp, *f, **fprev;
553 register frentry_t **ftail;
556 frgroup_t *fg = NULL;
557 int error = 0, in, group;
560 IRCOPY(data, (caddr_t)fp, sizeof(*fp));
563 * Check that the group number does exist and that if a head group
564 * has been specified, doesn't exist.
567 fr_findgroup(fp->fr_grhead, fp->fr_flags, unit, set, NULL))
570 !fr_findgroup(fp->fr_group, fp->fr_flags, unit, set, NULL))
573 in = (fp->fr_flags & FR_INQUE) ? 0 : 1;
575 if (unit == IPL_LOGAUTH)
576 ftail = fprev = &ipauth;
577 else if (fp->fr_flags & FR_ACCOUNT)
578 ftail = fprev = &ipacct[in][set];
579 else if (fp->fr_flags & (FR_OUTQUE|FR_INQUE))
580 ftail = fprev = &ipfilter[in][set];
584 if ((group = fp->fr_group)) {
585 if (!(fg = fr_findgroup(group, fp->fr_flags, unit, set, NULL)))
587 ftail = fprev = fg->fg_start;
590 bzero((char *)frcache, sizeof(frcache[0]) * 2);
592 if (*fp->fr_ifname) {
593 fp->fr_ifa = GETUNIT(fp->fr_ifname);
595 fp->fr_ifa = (void *)-1;
599 fp->fr_flags &= ~FR_DUP;
600 if (*fdp->fd_ifname) {
601 fdp->fd_ifp = GETUNIT(fdp->fd_ifname);
603 fdp->fd_ifp = (struct ifnet *)-1;
605 fp->fr_flags |= FR_DUP;
609 if (*fdp->fd_ifname) {
610 fdp->fd_ifp = GETUNIT(fdp->fd_ifname);
612 fdp->fd_ifp = (struct ifnet *)-1;
616 * Look for a matching filter rule, but don't include the next or
617 * interface pointer in the comparison (fr_next, fr_ifa).
619 for (; (f = *ftail); ftail = &f->fr_next)
620 if (bcmp((char *)&f->fr_ip, (char *)&fp->fr_ip,
625 * If zero'ing statistics, copy current to caller and zero.
627 if (req == SIOCZRLST) {
630 IWCOPY((caddr_t)f, data, sizeof(*f));
638 if (req != SIOCINAFR && req != SIOCINIFR)
641 else if (fp->fr_hits)
642 while (--fp->fr_hits && (f = *ftail))
647 if (req == SIOCDELFR || req == SIOCRMIFR) {
653 if (fg && fg->fg_head)
654 fg->fg_head->fr_ref--;
655 if (unit == IPL_LOGAUTH)
656 return fr_auth_ioctl(data, req, f, ftail);
658 fr_delgroup(f->fr_grhead, fp->fr_flags, unit,
660 fixskip(fprev, f, -1);
668 if (unit == IPL_LOGAUTH)
669 return fr_auth_ioctl(data, req, f, ftail);
670 KMALLOC(f, frentry_t *, sizeof(*f));
672 if (fg && fg->fg_head)
673 fg->fg_head->fr_ref++;
674 bcopy((char *)fp, (char *)f, sizeof(*f));
679 if (req == SIOCINIFR || req == SIOCINAFR)
680 fixskip(fprev, f, 1);
682 if ((group = f->fr_grhead))
683 fg = fr_addgroup(group, f, unit, set);
694 * routines below for saving IP headers to buffer
698 int IPL_EXTERN(open)(dev_t *pdev, int flags, int devtype, cred_t *cp)
700 int IPL_EXTERN(open)(dev_t dev, int flags)
703 int IPL_EXTERN(open)(dev, flags
704 # if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
705 (__FreeBSD_version >= 220000)) && defined(_KERNEL)
716 #if defined(__sgi) && defined(_KERNEL)
717 u_int min = geteminor(*pdev);
719 u_int min = GET_MINOR(dev);
731 int IPL_EXTERN(close)(dev_t dev, int flags, int devtype, cred_t *cp)
733 int IPL_EXTERN(close)(dev, flags
734 # if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
735 (__FreeBSD_version >= 220000)) && defined(_KERNEL)
746 u_int min = GET_MINOR(dev);
757 * both of these must operate with at least splnet() lest they be
758 * called during packet processing and cause an inconsistancy to appear in
762 int IPL_EXTERN(read)(dev_t dev, uio_t *uio, cred_t *crp)
765 int IPL_EXTERN(read)(dev, uio, ioflag)
768 int IPL_EXTERN(read)(dev, uio)
771 register struct uio *uio;
775 return ipflog_read(GET_MINOR(dev), uio);
783 * send_reset - this could conceivably be a call to tcp_respond(), but that
784 * requires a large amount of setting up and isn't any more efficient.
794 # if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
798 if (ti->ti_flags & TH_RST)
799 return -1; /* feedback loop */
800 # if (BSD < 199306) || defined(__sgi)
801 m = m_get(M_DONTWAIT, MT_HEADER);
803 m = m_gethdr(M_DONTWAIT, MT_HEADER);
804 m->m_data += max_linkhdr;
809 if (ti->ti_flags & TH_SYN)
811 m->m_len = sizeof (struct tcpiphdr);
813 m->m_pkthdr.len = sizeof (struct tcpiphdr);
814 m->m_pkthdr.rcvif = (struct ifnet *)0;
816 bzero(mtod(m, char *), sizeof(struct tcpiphdr));
817 ip = mtod(m, struct ip *);
818 tp = mtod(m, struct tcpiphdr *);
819 tcp = (struct tcphdr *)((char *)ip + sizeof(struct ip));
821 ip->ip_src.s_addr = ti->ti_dst.s_addr;
822 ip->ip_dst.s_addr = ti->ti_src.s_addr;
823 tcp->th_dport = ti->ti_sport;
824 tcp->th_sport = ti->ti_dport;
825 tcp->th_ack = htonl(ntohl(ti->ti_seq) + tlen);
826 tcp->th_off = sizeof(struct tcphdr) >> 2;
827 tcp->th_flags = TH_RST|TH_ACK;
828 tp->ti_pr = ((struct ip *)ti)->ip_p;
829 tp->ti_len = htons(sizeof(struct tcphdr));
830 tcp->th_sum = in_cksum(m, sizeof(struct tcpiphdr));
832 ip->ip_tos = ((struct ip *)ti)->ip_tos;
833 ip->ip_p = ((struct ip *)ti)->ip_p;
834 ip->ip_len = sizeof (struct tcpiphdr);
835 # if (BSD < 199306) || defined(__sgi)
836 ip->ip_ttl = tcp_ttl;
838 ip->ip_ttl = ip_defttl;
841 # if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
842 bzero((char *)&ro, sizeof(ro));
843 err = ip_output(m, (struct mbuf *)0, &ro, 0, 0);
848 * extra 0 in case of multicast
850 err = ip_output(m, (struct mbuf *)0, 0, 0, 0);
856 # if !defined(IPFILTER_LKM) && (__FreeBSD_version < 300000) && !defined(__sgi)
858 int iplinit __P((void));
862 void iplinit __P((void));
871 # endif /* ! __NetBSD__ */
874 size_t mbufchainlen(m0)
875 register struct mbuf *m0;
877 register size_t len = 0;
879 for (; m0; m0 = m0->m_next)
885 void ipfr_fastroute(m0, fin, fdp)
890 register struct ip *ip, *mhip;
891 register struct mbuf *m = m0;
892 register struct route *ro;
893 struct ifnet *ifp = fdp->fd_ifp;
894 int len, off, error = 0;
895 int hlen = fin->fin_hlen;
896 struct route iproute;
897 struct sockaddr_in *dst;
899 ip = mtod(m0, struct ip *);
904 bzero((caddr_t)ro, sizeof (*ro));
905 dst = (struct sockaddr_in *)&ro->ro_dst;
906 dst->sin_family = AF_INET;
907 dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst;
909 dst->sin_len = sizeof(*dst);
911 # if (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \
912 !defined(__OpenBSD__)
914 rtalloc_ign(ro, RTF_CLONING);
916 rtalloc_ign(ro, RTF_PRCLONING);
922 if (!(fin->fin_fr->fr_flags & FR_FASTROUTE)) {
926 if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) {
927 if (in_localaddr(ip->ip_dst))
928 error = EHOSTUNREACH;
933 if (ro->ro_rt->rt_flags & RTF_GATEWAY)
934 dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
940 * For input packets which are being "fastrouted", they won't
941 * go back through output filtering and miss their chance to get
944 (void) ip_natout(ip, hlen, fin);
948 * If small enough for interface, can just send directly.
950 if (ip->ip_len <= ifp->if_mtu) {
952 ip->ip_id = htons(ip->ip_id);
953 ip->ip_len = htons(ip->ip_len);
954 ip->ip_off = htons(ip->ip_off);
957 ip->ip_sum = in_cksum(m, hlen);
959 error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst,
962 error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst);
967 * Too large for interface; fragment if possible.
968 * Must be able to put at least 8 bytes per fragment.
970 if (ip->ip_off & IP_DF) {
974 len = (ifp->if_mtu - hlen) &~ 7;
981 int mhlen, firstlen = len;
982 struct mbuf **mnext = &m->m_act;
985 * Loop through length of segment after first fragment,
986 * make new header and copy data of each part and link onto chain.
989 mhlen = sizeof (struct ip);
990 for (off = hlen + len; off < ip->ip_len; off += len) {
991 MGET(m, M_DONTWAIT, MT_HEADER);
997 m->m_data += max_linkhdr;
999 m->m_off = MMAXOFF - hlen;
1001 mhip = mtod(m, struct ip *);
1002 bcopy((char *)ip, (char *)mhip, sizeof(*ip));
1003 if (hlen > sizeof (struct ip)) {
1004 mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
1005 mhip->ip_hl = mhlen >> 2;
1008 mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
1009 if (ip->ip_off & IP_MF)
1010 mhip->ip_off |= IP_MF;
1011 if (off + len >= ip->ip_len)
1012 len = ip->ip_len - off;
1014 mhip->ip_off |= IP_MF;
1015 mhip->ip_len = htons((u_short)(len + mhlen));
1016 m->m_next = m_copy(m0, off, len);
1017 if (m->m_next == 0) {
1018 error = ENOBUFS; /* ??? */
1022 mhip->ip_off = htons((u_short)mhip->ip_off);
1025 mhip->ip_sum = in_cksum(m, mhlen);
1030 * Update first fragment by trimming what's been copied out
1031 * and updating header, then send each fragment (in order).
1033 m_adj(m0, hlen + firstlen - ip->ip_len);
1034 ip->ip_len = htons((u_short)(hlen + firstlen));
1035 ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
1037 ip->ip_sum = in_cksum(m0, hlen);
1039 for (m = m0; m; m = m0) {
1044 error = (*ifp->if_output)(ifp, m,
1045 (struct sockaddr *)dst, ro->ro_rt);
1047 error = (*ifp->if_output)(ifp, m,
1048 (struct sockaddr *)dst);
1068 #else /* #ifdef _KERNEL */
1072 static int no_output __P((struct ifnet *ifp, struct mbuf *m,
1073 struct sockaddr *s))
1075 static int no_output __P((struct ifnet *ifp, struct mbuf *m,
1076 struct sockaddr *s, struct rtentry *rt))
1085 static int write_output __P((struct ifnet *ifp, struct mbuf *m,
1086 struct sockaddr *s))
1088 static int write_output __P((struct ifnet *ifp, struct mbuf *m,
1089 struct sockaddr *s, struct rtentry *rt))
1092 # if !(defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
1093 (defined(OpenBSD) && (OpenBSD >= 199603))
1094 ip_t *ip = (ip_t *)m;
1097 static int write_output(ifp, ip)
1105 # if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
1106 (defined(OpenBSD) && (OpenBSD >= 199603))
1107 sprintf(fname, "/tmp/%s", ifp->if_xname);
1108 if ((fp = fopen(fname, "a"))) {
1112 sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
1113 if ((fp = fopen(fname, "a"))) {
1114 fwrite((char *)ip, ntohs(ip->ip_len), 1, fp);
1122 struct ifnet *get_unit(name)
1125 struct ifnet *ifp, **ifa;
1126 # if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
1127 (defined(OpenBSD) && (OpenBSD >= 199603))
1128 for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
1129 if (!strcmp(name, ifp->if_xname))
1133 char ifname[32], *s;
1135 for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
1136 (void) sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit);
1137 if (!strcmp(name, ifname))
1143 ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2);
1145 ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp));
1149 ifneta = (struct ifnet **)realloc(ifneta,
1150 (nifs + 1) * sizeof(*ifa));
1151 ifneta[nifs] = NULL;
1152 ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp));
1154 ifp = ifneta[nifs - 1];
1156 # if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
1157 (defined(OpenBSD) && (OpenBSD >= 199603))
1158 strncpy(ifp->if_xname, name, sizeof(ifp->if_xname));
1160 for (s = name; *s && !isdigit(*s); s++)
1162 if (*s && isdigit(*s)) {
1163 ifp->if_unit = atoi(s);
1164 ifp->if_name = (char *)malloc(s - name + 1);
1165 strncpy(ifp->if_name, name, s - name);
1166 ifp->if_name[s - name] = '\0';
1168 ifp->if_name = strdup(name);
1172 ifp->if_output = no_output;
1181 struct ifnet *ifp, **ifa;
1183 # if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
1184 (defined(OpenBSD) && (OpenBSD >= 199603))
1185 for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
1186 ifp->if_output = write_output;
1187 sprintf(fname, "/tmp/%s", ifp->if_xname);
1188 if ((fp = fopen(fname, "w")))
1193 for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
1194 ifp->if_output = write_output;
1195 sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
1196 if ((fp = fopen(fname, "w")))
1203 void ipfr_fastroute(ip, fin, fdp)
1208 struct ifnet *ifp = fdp->fd_ifp;
1211 return; /* no routing table out here */
1213 ip->ip_len = htons((u_short)ip->ip_len);
1214 ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
1217 (*ifp->if_output)(ifp, (void *)ip, NULL);
1219 (*ifp->if_output)(ifp, (void *)ip, NULL, 0);
1224 int ipllog __P((void))
1231 int send_reset(ip, ifp)
1235 verbose("- TCP RST sent\n");
1240 int icmp_error(ip, ifp)
1244 verbose("- TCP RST sent\n");
1247 #endif /* _KERNEL */