diff --git a/sbin/ipf/ipf/ipf.c b/sbin/ipf/ipf/ipf.c index de5121d94767..f2b668ba14b4 100644 --- a/sbin/ipf/ipf/ipf.c +++ b/sbin/ipf/ipf/ipf.c @@ -1,578 +1,578 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. */ #include "ipf.h" #include #include #include #include "netinet/ipl.h" #if !defined(lint) static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #if !defined(__SVR4) && defined(__GNUC__) extern char *index(const char *, int); #endif extern char *optarg; extern int optind; extern frentry_t *frtop; void ipf_frsync(void); void zerostats(void); int main(int, char *[]); int opts = 0; int outputc = 0; int use_inet6 = 0; int exitstatus = 0; static void procfile(char *); static void flushfilter(char *, int *); static void set_state(u_int); static void showstats(friostat_t *); static void packetlogon(char *); static void swapactive(void); static int opendevice(char *, int); static void closedevice(void); static char *ipfname = IPL_NAME; static void usage(void); static int showversion(void); static int get_flags(void); static int ipf_interceptadd(int, ioctlfunc_t, void *); static int fd = -1; static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ioctl, ioctl, ioctl, ioctl, ioctl, ioctl, ioctl, ioctl }; /* XXX The following was added to satisfy a rescue/rescue/ build XXX requirement. */ int nohdrfields; static void usage() { fprintf(stderr, "usage: ipf [-6AdDEInoPrRsvVyzZ] %s %s %s\n", "[-l block|pass|nomatch|state|nat]", "[-cc] [-F i|o|a|s|S|u]", "[-f filename] [-T ]"); exit(1); } int main(int argc, char *argv[]) { int c, *filter = NULL; if (argc < 2) usage(); assigndefined(getenv("IPF_PREDEFINED")); while ((c = getopt(argc, argv, "46Ac:dDEf:F:Il:m:noPrRsT:vVyzZ")) != -1) { switch (c) { case '?' : usage(); break; case '4' : use_inet6 = -1; break; case '6' : use_inet6 = 1; break; case 'A' : opts &= ~OPT_INACTIVE; break; case 'c' : if (strcmp(optarg, "c") == 0) outputc = 1; break; case 'E' : set_state((u_int)1); break; case 'D' : set_state((u_int)0); break; case 'd' : opts ^= OPT_DEBUG; break; case 'f' : procfile(optarg); break; case 'F' : flushfilter(optarg, filter); break; case 'I' : opts ^= OPT_INACTIVE; break; case 'l' : packetlogon(optarg); break; case 'm' : filter = parseipfexpr(optarg, NULL); break; case 'n' : opts ^= OPT_DONOTHING|OPT_DONTOPEN; break; case 'o' : break; case 'P' : ipfname = IPAUTH_NAME; break; case 'R' : opts ^= OPT_NORESOLVE; break; case 'r' : opts ^= OPT_REMOVE; break; case 's' : swapactive(); break; case 'T' : if (opendevice(ipfname, 1) >= 0) ipf_dotuning(fd, optarg, ioctl); break; case 'v' : opts += OPT_VERBOSE; break; case 'V' : if (showversion()) exit(1); break; case 'y' : ipf_frsync(); break; case 'z' : opts ^= OPT_ZERORULEST; break; case 'Z' : zerostats(); break; } } if (optind < 2) usage(); if (fd != -1) (void) close(fd); return (exitstatus); /* NOTREACHED */ } static int opendevice(char *ipfdev, int check) { if (opts & OPT_DONOTHING) return (-2); if (check && checkrev(ipfname) == -1) { fprintf(stderr, "User/kernel version check failed\n"); return (-2); } if (!ipfdev) ipfdev = ipfname; if (fd == -1) if ((fd = open(ipfdev, O_RDWR)) == -1) if ((fd = open(ipfdev, O_RDONLY)) == -1) ipferror(fd, "open device"); return (fd); } static void closedevice(void) { close(fd); fd = -1; } static int get_flags(void) { int i = 0; if ((opendevice(ipfname, 1) != -2) && (ioctl(fd, SIOCGETFF, &i) == -1)) { ipferror(fd, "SIOCGETFF"); return (0); } return (i); } static void set_state(u_int enable) { if (opendevice(ipfname, 0) != -2) { if (ioctl(fd, SIOCFRENB, &enable) == -1) { if (errno == EBUSY) { fprintf(stderr, "IP FIlter: already initialized\n"); } else { ipferror(fd, "SIOCFRENB"); } } } return; } static void procfile(char *file) { (void) opendevice(ipfname, 1); initparse(); ipf_parsefile(fd, ipf_interceptadd, iocfunctions, file); if (outputc) { printC(0); printC(1); emit(-1, -1, NULL, NULL); } } static int ipf_interceptadd(int fd, ioctlfunc_t ioctlfunc, void *ptr) { if (outputc) printc(ptr); if (ipf_addrule(fd, ioctlfunc, ptr) != 0) exitstatus = 1; return (0); } static void packetlogon(char *opt) { int flag, xfd, logopt, change = 0; flag = get_flags(); if (flag != 0) { if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) printf("log flag is currently %#x\n", flag); } flag &= ~(FF_LOGPASS|FF_LOGNOMATCH|FF_LOGBLOCK); if (strstr(opt, "pass")) { flag |= FF_LOGPASS; if (opts & OPT_VERBOSE) printf("set log flag: pass\n"); change = 1; } if (strstr(opt, "nomatch")) { flag |= FF_LOGNOMATCH; if (opts & OPT_VERBOSE) printf("set log flag: nomatch\n"); change = 1; } if (strstr(opt, "block") || strchr(opt, 'd')) { flag |= FF_LOGBLOCK; if (opts & OPT_VERBOSE) printf("set log flag: block\n"); change = 1; } if (strstr(opt, "none")) { if (opts & OPT_VERBOSE) printf("disable all log flags\n"); change = 1; } if (change == 1) { if (opendevice(ipfname, 1) != -2 && (ioctl(fd, SIOCSETFF, &flag) != 0)) ipferror(fd, "ioctl(SIOCSETFF)"); } if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { flag = get_flags(); printf("log flags are now %#x\n", flag); } if (strstr(opt, "state")) { if (opts & OPT_VERBOSE) printf("set state log flag\n"); xfd = open(IPSTATE_NAME, O_RDWR); if (xfd >= 0) { logopt = 0; if (ioctl(xfd, SIOCGETLG, &logopt)) ipferror(fd, "ioctl(SIOCGETLG)"); else { logopt = 1 - logopt; if (ioctl(xfd, SIOCSETLG, &logopt)) ipferror(xfd, "ioctl(SIOCSETLG)"); } close(xfd); } } if (strstr(opt, "nat")) { if (opts & OPT_VERBOSE) printf("set nat log flag\n"); xfd = open(IPNAT_NAME, O_RDWR); if (xfd >= 0) { logopt = 0; if (ioctl(xfd, SIOCGETLG, &logopt)) ipferror(xfd, "ioctl(SIOCGETLG)"); else { logopt = 1 - logopt; if (ioctl(xfd, SIOCSETLG, &logopt)) ipferror(xfd, "ioctl(SIOCSETLG)"); } close(xfd); } } } static void flushfilter(char *arg, int *filter) { int fl = 0, rem; if (!arg || !*arg) return; if (!strcmp(arg, "s") || !strcmp(arg, "S") || ISDIGIT(*arg)) { if (*arg == 'S') fl = 0; else if (*arg == 's') fl = 1; else fl = atoi(arg); rem = fl; closedevice(); if (opendevice(IPSTATE_NAME, 1) == -2) exit(1); if (!(opts & OPT_DONOTHING)) { if (use_inet6) { fprintf(stderr, - "IPv6 rules are no longer seperate\n"); + "IPv6 rules are no longer separate\n"); } else if (filter != NULL) { ipfobj_t obj; obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_size = filter[0] * sizeof(int); obj.ipfo_type = IPFOBJ_IPFEXPR; obj.ipfo_ptr = filter; if (ioctl(fd, SIOCMATCHFLUSH, &obj) == -1) { ipferror(fd, "ioctl(SIOCMATCHFLUSH)"); fl = -1; } else { fl = obj.ipfo_retval; } } else { if (ioctl(fd, SIOCIPFFL, &fl) == -1) { ipferror(fd, "ioctl(SIOCIPFFL)"); exit(1); } } } if ((opts & (OPT_DONOTHING|OPT_DEBUG)) == OPT_DEBUG) { printf("remove flags %s (%d)\n", arg, rem); } if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { printf("%d state entries removed\n", fl); } closedevice(); return; } else if (strchr(arg, 'i') || strchr(arg, 'I')) fl = FR_INQUE; else if (strchr(arg, 'o') || strchr(arg, 'O')) fl = FR_OUTQUE; else if (strchr(arg, 'a') || strchr(arg, 'A')) fl = FR_OUTQUE|FR_INQUE; else { fprintf(stderr, "Incorrect flush argument: %s\n", arg); usage(); } if (opts & OPT_INACTIVE) fl |= FR_INACTIVE; rem = fl; if (opendevice(ipfname, 1) == -2) exit(1); if (!(opts & OPT_DONOTHING)) { if (use_inet6) { if (ioctl(fd, SIOCIPFL6, &fl) == -1) { ipferror(fd, "ioctl(SIOCIPFL6)"); exit(1); } } else { if (ioctl(fd, SIOCIPFFL, &fl) == -1) { ipferror(fd, "ioctl(SIOCIPFFL)"); exit(1); } } } if ((opts & (OPT_DONOTHING|OPT_DEBUG)) == OPT_DEBUG) { printf("remove flags %s%s (%d)\n", (rem & FR_INQUE) ? "I" : "", (rem & FR_OUTQUE) ? "O" : "", rem); } if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { printf("%d filter rules removed\n", fl); } return; } static void swapactive(void) { int in = 2; if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCSWAPA, &in) == -1) ipferror(fd, "ioctl(SIOCSWAPA)"); else printf("Set %d now inactive\n", in); } void ipf_frsync(void) { int frsyn = 0; if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCFRSYN, &frsyn) == -1) ipferror(fd, "SIOCFRSYN"); else printf("filter sync'd\n"); } void zerostats(void) { ipfobj_t obj; friostat_t fio; obj.ipfo_rev = IPFILTER_VERSION; obj.ipfo_type = IPFOBJ_IPFSTAT; obj.ipfo_size = sizeof(fio); obj.ipfo_ptr = &fio; obj.ipfo_offset = 0; if (opendevice(ipfname, 1) != -2) { if (ioctl(fd, SIOCFRZST, &obj) == -1) { ipferror(fd, "ioctl(SIOCFRZST)"); exit(-1); } showstats(&fio); } } /* * read the kernel stats for packets blocked and passed */ static void showstats(friostat_t *fp) { printf("bad packets:\t\tin %lu\tout %lu\n", fp->f_st[0].fr_bad, fp->f_st[1].fr_bad); printf(" input packets:\t\tblocked %lu passed %lu nomatch %lu", fp->f_st[0].fr_block, fp->f_st[0].fr_pass, fp->f_st[0].fr_nom); printf(" counted %lu\n", fp->f_st[0].fr_acct); printf("output packets:\t\tblocked %lu passed %lu nomatch %lu", fp->f_st[1].fr_block, fp->f_st[1].fr_pass, fp->f_st[1].fr_nom); printf(" counted %lu\n", fp->f_st[0].fr_acct); printf(" input packets logged:\tblocked %lu passed %lu\n", fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl); printf("output packets logged:\tblocked %lu passed %lu\n", fp->f_st[1].fr_bpkl, fp->f_st[1].fr_ppkl); } static int showversion(void) { struct friostat fio; ipfobj_t ipfo; u_32_t flags; char *s; int vfd; bzero((caddr_t)&ipfo, sizeof(ipfo)); ipfo.ipfo_rev = IPFILTER_VERSION; ipfo.ipfo_size = sizeof(fio); ipfo.ipfo_ptr = (void *)&fio; ipfo.ipfo_type = IPFOBJ_IPFSTAT; printf("ipf: %s (%d)\n", IPL_VERSION, (int)sizeof(frentry_t)); if ((vfd = open(ipfname, O_RDONLY)) == -1) { perror("open device"); return (1); } if (ioctl(vfd, SIOCGETFS, &ipfo)) { ipferror(vfd, "ioctl(SIOCGETFS)"); close(vfd); return (1); } close(vfd); flags = get_flags(); printf("Kernel: %-*.*s\n", (int)sizeof(fio.f_version), (int)sizeof(fio.f_version), fio.f_version); printf("Running: %s\n", (fio.f_running > 0) ? "yes" : "no"); printf("Log Flags: %#x = ", flags); s = ""; if (flags & FF_LOGPASS) { printf("pass"); s = ", "; } if (flags & FF_LOGBLOCK) { printf("%sblock", s); s = ", "; } if (flags & FF_LOGNOMATCH) { printf("%snomatch", s); s = ", "; } if (flags & FF_BLOCKNONIP) { printf("%snonip", s); s = ", "; } if (!*s) printf("none set"); putchar('\n'); printf("Default: "); if (FR_ISPASS(fio.f_defpass)) s = "pass"; else if (FR_ISBLOCK(fio.f_defpass)) s = "block"; else s = "nomatch -> block"; printf("%s all, Logging: %savailable\n", s, fio.f_logging ? "" : "un"); printf("Active list: %d\n", fio.f_active); printf("Feature mask: %#x\n", fio.f_features); return (0); } diff --git a/sbin/ipf/ipftest/ip_fil.c b/sbin/ipf/ipftest/ip_fil.c index f5955ddffdfe..2d270924d1b4 100644 --- a/sbin/ipf/ipftest/ip_fil.c +++ b/sbin/ipf/ipftest/ip_fil.c @@ -1,812 +1,812 @@ /* $FreeBSD$ */ /* * Copyright (C) 2012 by Darren Reed. * * See the IPFILTER.LICENCE file for details on licencing. * * $Id$ */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; static const char rcsid[] = "@(#)$Id$"; #endif #include "ipf.h" #include "md5.h" #include "ipt.h" ipf_main_softc_t ipfmain; static struct ifnet **ifneta = NULL; static int nifs = 0; struct rtentry; static void ipf_setifpaddr(struct ifnet *, char *); void init_ifp(void); static int no_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); static int write_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); struct ifaddr { struct sockaddr_storage ifa_addr; }; int ipfattach(softc) ipf_main_softc_t *softc; { return (0); } int ipfdetach(softc) ipf_main_softc_t *softc; { return (0); } /* * Filter ioctl interface. */ int ipfioctl(softc, dev, cmd, data, mode) ipf_main_softc_t *softc; int dev; ioctlcmd_t cmd; caddr_t data; int mode; { int error = 0, unit = 0, uid; uid = getuid(); unit = dev; SPL_NET(s); error = ipf_ioctlswitch(softc, unit, data, cmd, mode, uid, NULL); if (error != -1) { SPL_X(s); return (error); } SPL_X(s); return (error); } void ipf_forgetifp(softc, ifp) ipf_main_softc_t *softc; void *ifp; { register frentry_t *f; WRITE_ENTER(&softc->ipf_mutex); for (f = softc->ipf_acct[0][softc->ipf_active]; (f != NULL); f = f->fr_next) if (f->fr_ifa == ifp) f->fr_ifa = (void *)-1; for (f = softc->ipf_acct[1][softc->ipf_active]; (f != NULL); f = f->fr_next) if (f->fr_ifa == ifp) f->fr_ifa = (void *)-1; for (f = softc->ipf_rules[0][softc->ipf_active]; (f != NULL); f = f->fr_next) if (f->fr_ifa == ifp) f->fr_ifa = (void *)-1; for (f = softc->ipf_rules[1][softc->ipf_active]; (f != NULL); f = f->fr_next) if (f->fr_ifa == ifp) f->fr_ifa = (void *)-1; RWLOCK_EXIT(&softc->ipf_mutex); ipf_nat_sync(softc, ifp); ipf_lookup_sync(softc, ifp); } static int no_output(ifp, m, s, rt) struct rtentry *rt; struct ifnet *ifp; struct mbuf *m; struct sockaddr *s; { return (0); } static int write_output(ifp, m, s, rt) struct rtentry *rt; struct ifnet *ifp; struct mbuf *m; struct sockaddr *s; { char fname[32]; mb_t *mb; ip_t *ip; int fd; mb = (mb_t *)m; ip = MTOD(mb, ip_t *); #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ defined(__FreeBSD__) sprintf(fname, "/tmp/%s", ifp->if_xname); #else sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); #endif fd = open(fname, O_WRONLY|O_APPEND); if (fd == -1) { perror("open"); return (-1); } write(fd, (char *)ip, ntohs(ip->ip_len)); close(fd); return (0); } static void ipf_setifpaddr(ifp, addr) struct ifnet *ifp; char *addr; { struct ifaddr *ifa; #if defined(__NetBSD__) || defined(__FreeBSD__) if (ifp->if_addrlist.tqh_first != NULL) #else if (ifp->if_addrlist != NULL) #endif return; ifa = (struct ifaddr *)malloc(sizeof(*ifa)); #if defined(__NetBSD__) || defined(__FreeBSD__) ifp->if_addrlist.tqh_first = ifa; #else ifp->if_addrlist = ifa; #endif if (ifa != NULL) { struct sockaddr_in *sin; sin = (struct sockaddr_in *)&ifa->ifa_addr; #ifdef USE_INET6 if (index(addr, ':') != NULL) { struct sockaddr_in6 *sin6; sin6 = (struct sockaddr_in6 *)&ifa->ifa_addr; sin6->sin6_family = AF_INET6; /* Abort if bad address. */ switch (inet_pton(AF_INET6, addr, &sin6->sin6_addr)) { case 1: break; case -1: perror("inet_pton"); abort(); break; default: abort(); break; } } else #endif { sin->sin_family = AF_INET; sin->sin_addr.s_addr = inet_addr(addr); if (sin->sin_addr.s_addr == 0) abort(); } } } struct ifnet * get_unit(name, family) char *name; int family; { struct ifnet *ifp, **ifpp, **old_ifneta; char *addr; #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ defined(__FreeBSD__) if (!*name) return (NULL); if (name == NULL) name = "anon0"; addr = strchr(name, '='); if (addr != NULL) *addr++ = '\0'; for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { if (!strcmp(name, ifp->if_xname)) { if (addr != NULL) ipf_setifpaddr(ifp, addr); return (ifp); } } #else char *s, ifname[LIFNAMSIZ+1]; if (name == NULL) name = "anon0"; addr = strchr(name, '='); if (addr != NULL) *addr++ = '\0'; for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { COPYIFNAME(family, ifp, ifname); if (!strcmp(name, ifname)) { if (addr != NULL) ipf_setifpaddr(ifp, addr); return (ifp); } } #endif if (!ifneta) { ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2); if (!ifneta) return (NULL); ifneta[1] = NULL; ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp)); if (!ifneta[0]) { free(ifneta); return (NULL); } nifs = 1; } else { old_ifneta = ifneta; nifs++; ifneta = (struct ifnet **)reallocarray(ifneta, nifs + 1, sizeof(ifp)); if (!ifneta) { free(old_ifneta); nifs = 0; return (NULL); } ifneta[nifs] = NULL; ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp)); if (!ifneta[nifs - 1]) { nifs--; return (NULL); } } ifp = ifneta[nifs - 1]; #if defined(__NetBSD__) || defined(__FreeBSD__) TAILQ_INIT(&ifp->if_addrlist); #endif #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ defined(__FreeBSD__) (void) strncpy(ifp->if_xname, name, sizeof(ifp->if_xname)); #else s = name + strlen(name) - 1; for (; s > name; s--) { if (!ISDIGIT(*s)) { s++; break; } } if ((s > name) && (*s != 0) && ISDIGIT(*s)) { ifp->if_unit = atoi(s); ifp->if_name = (char *)malloc(s - name + 1); (void) strncpy(ifp->if_name, name, s - name); ifp->if_name[s - name] = '\0'; } else { ifp->if_name = strdup(name); ifp->if_unit = -1; } #endif ifp->if_output = (void *)no_output; if (addr != NULL) { ipf_setifpaddr(ifp, addr); } return (ifp); } char * get_ifname(ifp) struct ifnet *ifp; { static char ifname[LIFNAMSIZ]; #if defined(__NetBSD__) || defined(__FreeBSD__) sprintf(ifname, "%s", ifp->if_xname); #else if (ifp->if_unit != -1) sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit); else strcpy(ifname, ifp->if_name); #endif return (ifname); } void init_ifp() { struct ifnet *ifp, **ifpp; char fname[32]; int fd; #if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ defined(__FreeBSD__) for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { ifp->if_output = (void *)write_output; sprintf(fname, "/tmp/%s", ifp->if_xname); fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); if (fd == -1) perror("open"); else close(fd); } #else for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { ifp->if_output = (void *)write_output; sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); if (fd == -1) perror("open"); else close(fd); } #endif } int ipf_fastroute(m, mpp, fin, fdp) mb_t *m, **mpp; fr_info_t *fin; frdest_t *fdp; { struct ifnet *ifp; ip_t *ip = fin->fin_ip; frdest_t node; int error = 0; frentry_t *fr; void *sifp; int sout; sifp = fin->fin_ifp; sout = fin->fin_out; fr = fin->fin_fr; ip->ip_sum = 0; if (!(fr->fr_flags & FR_KEEPSTATE) && (fdp != NULL) && (fdp->fd_type == FRD_DSTLIST)) { bzero(&node, sizeof(node)); ipf_dstlist_select_node(fin, fdp->fd_ptr, NULL, &node); fdp = &node; } ifp = fdp->fd_ptr; if (ifp == NULL) return (0; /* no routing table out here */); if (fin->fin_out == 0) { fin->fin_ifp = ifp; fin->fin_out = 1; (void) ipf_acctpkt(fin, NULL); fin->fin_fr = NULL; if (!fr || !(fr->fr_flags & FR_RETMASK)) { u_32_t pass; (void) ipf_state_check(fin, &pass); } switch (ipf_nat_checkout(fin, NULL)) { case 0 : break; case 1 : ip->ip_sum = 0; break; case -1 : error = -1; goto done; break; } } m->mb_ifp = ifp; printpacket(fin->fin_out, m); (*ifp->if_output)(ifp, (void *)m, NULL, 0); done: fin->fin_ifp = sifp; fin->fin_out = sout; return (error); } int ipf_send_reset(fin) fr_info_t *fin; { ipfkverbose("- TCP RST sent\n"); return (0); } int ipf_send_icmp_err(type, fin, dst) int type; fr_info_t *fin; int dst; { ipfkverbose("- ICMP unreachable sent\n"); return (0); } void m_freem(m) mb_t *m; { return; } void m_copydata(m, off, len, cp) mb_t *m; int off, len; caddr_t cp; { bcopy((char *)m + off, cp, len); } int ipfuiomove(buf, len, rwflag, uio) caddr_t buf; int len, rwflag; struct uio *uio; { int left, ioc, num, offset; struct iovec *io; char *start; if (rwflag == UIO_READ) { left = len; ioc = 0; offset = uio->uio_offset; while ((left > 0) && (ioc < uio->uio_iovcnt)) { io = uio->uio_iov + ioc; num = io->iov_len; if (num > left) num = left; start = (char *)io->iov_base + offset; if (start > (char *)io->iov_base + io->iov_len) { offset -= io->iov_len; ioc++; continue; } bcopy(buf, start, num); uio->uio_resid -= num; uio->uio_offset += num; left -= num; if (left > 0) ioc++; } if (left > 0) return (EFAULT); } return (0); } u_32_t ipf_newisn(fin) fr_info_t *fin; { static int iss_seq_off = 0; u_char hash[16]; u_32_t newiss; MD5_CTX ctx; /* * Compute the base value of the ISS. It is a hash * of (saddr, sport, daddr, dport, secret). */ MD5Init(&ctx); MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src, sizeof(fin->fin_fi.fi_src)); MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst, sizeof(fin->fin_fi.fi_dst)); MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat)); /* MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); */ MD5Final(hash, &ctx); memcpy(&newiss, hash, sizeof(newiss)); /* * Now increment our "timer", and add it in to * the computed value. * * XXX Use `addin'? * XXX TCP_ISSINCR too large to use? */ iss_seq_off += 0x00010000; newiss += iss_seq_off; return (newiss); } /* ------------------------------------------------------------------------ */ /* Function: ipf_nextipid */ -/* Returns: int - 0 == success, -1 == error (packet should be droppped) */ +/* Returns: int - 0 == success, -1 == error (packet should be dropped) */ /* Parameters: fin(I) - pointer to packet information */ /* */ /* Returns the next IPv4 ID to use for this packet. */ /* ------------------------------------------------------------------------ */ inline u_short ipf_nextipid(fin) fr_info_t *fin; { static u_short ipid = 0; ipf_main_softc_t *softc = fin->fin_main_soft; u_short id; MUTEX_ENTER(&softc->ipf_rw); if (fin->fin_pktnum != 0) { /* * The -1 is for aligned test results. */ id = (fin->fin_pktnum - 1) & 0xffff; } else { } id = ipid++; MUTEX_EXIT(&softc->ipf_rw); return (id); } inline int ipf_checkv4sum(fin) fr_info_t *fin; { if (fin->fin_flx & FI_SHORT) return (1); if (ipf_checkl4sum(fin) == -1) { fin->fin_flx |= FI_BAD; return (-1); } return (0); } #ifdef USE_INET6 inline int ipf_checkv6sum(fin) fr_info_t *fin; { if (fin->fin_flx & FI_SHORT) return (1); if (ipf_checkl4sum(fin) == -1) { fin->fin_flx |= FI_BAD; return (-1); } return (0); } #endif #if 0 /* * See above for description, except that all addressing is in user space. */ int copyoutptr(softc, src, dst, size) void *src, *dst; size_t size; { caddr_t ca; bcopy(dst, (char *)&ca, sizeof(ca)); bcopy(src, ca, size); return (0); } /* * See above for description, except that all addressing is in user space. */ int copyinptr(src, dst, size) void *src, *dst; size_t size; { caddr_t ca; bcopy(src, (char *)&ca, sizeof(ca)); bcopy(ca, dst, size); return (0); } #endif /* * return the first IP Address associated with an interface */ int ipf_ifpaddr(softc, v, atype, ifptr, inp, inpmask) ipf_main_softc_t *softc; int v, atype; void *ifptr; i6addr_t *inp, *inpmask; { struct ifnet *ifp = ifptr; struct ifaddr *ifa; #if defined(__NetBSD__) || defined(__FreeBSD__) ifa = ifp->if_addrlist.tqh_first; #else ifa = ifp->if_addrlist; #endif if (ifa != NULL) { if (v == 4) { struct sockaddr_in *sin, mask; mask.sin_addr.s_addr = 0xffffffff; sin = (struct sockaddr_in *)&ifa->ifa_addr; return (ipf_ifpfillv4addr(atype, sin, &mask, &inp->in4, &inpmask->in4)); } #ifdef USE_INET6 if (v == 6) { struct sockaddr_in6 *sin6, mask; sin6 = (struct sockaddr_in6 *)&ifa->ifa_addr; ((i6addr_t *)&mask.sin6_addr)->i6[0] = 0xffffffff; ((i6addr_t *)&mask.sin6_addr)->i6[1] = 0xffffffff; ((i6addr_t *)&mask.sin6_addr)->i6[2] = 0xffffffff; ((i6addr_t *)&mask.sin6_addr)->i6[3] = 0xffffffff; return (ipf_ifpfillv6addr(atype, sin6, &mask, inp, inpmask)); } #endif } return (0); } /* * This function is not meant to be random, rather just produce a * sequence of numbers that isn't linear to show "randomness". */ u_32_t ipf_random() { static unsigned int last = 0xa5a5a5a5; static int calls = 0; int number; calls++; /* * These are deliberately chosen to ensure that there is some * attempt to test whether the output covers the range in test n18. */ switch (calls) { case 1 : number = 0; break; case 2 : number = 4; break; case 3 : number = 3999; break; case 4 : number = 4000; break; case 5 : number = 48999; break; case 6 : number = 49000; break; default : number = last; last *= calls; last++; number ^= last; break; } return (number); } int ipf_verifysrc(fin) fr_info_t *fin; { return (1); } int ipf_inject(fin, m) fr_info_t *fin; mb_t *m; { FREE_MB_T(m); return (0); } u_int ipf_pcksum(fin, hlen, sum) fr_info_t *fin; int hlen; u_int sum; { u_short *sp; u_int sum2; int slen; slen = fin->fin_plen - hlen; sp = (u_short *)((u_char *)fin->fin_ip + hlen); for (; slen > 1; slen -= 2) sum += *sp++; if (slen) sum += ntohs(*(u_char *)sp << 8); while (sum > 0xffff) sum = (sum & 0xffff) + (sum >> 16); sum2 = (u_short)(~sum & 0xffff); return (sum2); } void * ipf_pullup(m, fin, plen) mb_t *m; fr_info_t *fin; int plen; { if (M_LEN(m) >= plen) return (fin->fin_ip); /* * Fake ipf_pullup failing */ fin->fin_reason = FRB_PULLUP; *fin->fin_mp = NULL; fin->fin_m = NULL; fin->fin_ip = NULL; return (NULL); } diff --git a/sbin/ipf/ipsend/ipsend.h b/sbin/ipf/ipsend/ipsend.h index bfec90f1c5b3..a8ed3cbc7430 100644 --- a/sbin/ipf/ipsend/ipsend.h +++ b/sbin/ipf/ipsend/ipsend.h @@ -1,62 +1,62 @@ /* $FreeBSD$ */ /* * ipsend.h (C) 1997-1998 Darren Reed * * This was written to test what size TCP fragments would get through * various TCP/IP packet filters, as used in IP firewalls. In certain * conditions, enough of the TCP header is missing for unpredictable * results unless the filter is aware that this can happen. * - * The author provides this program as-is, with no gaurantee for its + * The author provides this program as-is, with no guarantee for its * suitability for any specific purpose. The author takes no responsibility * for the misuse/abuse of this program and provides it for the sole purpose * of testing packet filter policies. This file maybe distributed freely * providing it is not modified and that this notice remains in tact. * */ #ifndef __P # define __P(x) x #endif #include #include "ipf.h" /* XXX: The following is needed by tcpip.h */ #include #include "netinet/tcpip.h" #include "ipt.h" extern int resolve(char *, char *); extern int arp(char *, char *); extern u_short chksum(u_short *, int); extern int send_ether(int, char *, int, struct in_addr); extern int send_ip(int, int, ip_t *, struct in_addr, int); extern int send_tcp(int, int, ip_t *, struct in_addr); extern int send_udp(int, int, ip_t *, struct in_addr); extern int send_icmp(int, int, ip_t *, struct in_addr); extern int send_packet(int, int, ip_t *, struct in_addr); extern int send_packets(char *, int, ip_t *, struct in_addr); extern u_short ipseclevel(char *); extern u_32_t buildopts(char *, char *, int); extern int addipopt(char *, struct ipopt_names *, int, char *); extern int initdevice(char *, int); extern int sendip(int, char *, int); extern struct tcpcb *find_tcp(int, struct tcpiphdr *); extern int ip_resend(char *, int, struct ipread *, struct in_addr, char *); extern void ip_test1(char *, int, ip_t *, struct in_addr, int); extern void ip_test2(char *, int, ip_t *, struct in_addr, int); extern void ip_test3(char *, int, ip_t *, struct in_addr, int); extern void ip_test4(char *, int, ip_t *, struct in_addr, int); extern void ip_test5(char *, int, ip_t *, struct in_addr, int); extern void ip_test6(char *, int, ip_t *, struct in_addr, int); extern void ip_test7(char *, int, ip_t *, struct in_addr, int); extern int do_socket(char *, int, struct tcpiphdr *, struct in_addr); extern int kmemcpy(char *, void *, int); #define KMCPY(a,b,c) kmemcpy((char *)(a), (void *)(b), (int)(c)) #ifndef OPT_RAW #define OPT_RAW 0x80000 #endif