1145554Sdarrenr/* $FreeBSD$ */ 2145554Sdarrenr 3145554Sdarrenr/* 4145554Sdarrenr * Copyright (C) 1993-2001 by Darren Reed. 5145554Sdarrenr * 6145554Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 7145554Sdarrenr */ 8145554Sdarrenr#if !defined(lint) 9145554Sdarrenrstatic const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; 10172776Sdarrenrstatic const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.133.2.18 2007/09/09 11:32:05 darrenr Exp $"; 11145554Sdarrenr#endif 12145554Sdarrenr 13145554Sdarrenr#ifndef SOLARIS 14145554Sdarrenr#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) 15145554Sdarrenr#endif 16145554Sdarrenr 17145554Sdarrenr#include <sys/param.h> 18145554Sdarrenr#if defined(__FreeBSD__) && !defined(__FreeBSD_version) 19145554Sdarrenr# if defined(IPFILTER_LKM) 20145554Sdarrenr# ifndef __FreeBSD_cc_version 21145554Sdarrenr# include <osreldate.h> 22145554Sdarrenr# else 23145554Sdarrenr# if __FreeBSD_cc_version < 430000 24145554Sdarrenr# include <osreldate.h> 25145554Sdarrenr# endif 26145554Sdarrenr# endif 27145554Sdarrenr# endif 28145554Sdarrenr#endif 29145554Sdarrenr#include <sys/errno.h> 30145554Sdarrenr#if defined(__hpux) && (HPUXREV >= 1111) && !defined(_KERNEL) 31145554Sdarrenr# include <sys/kern_svcs.h> 32145554Sdarrenr#endif 33145554Sdarrenr#include <sys/types.h> 34145554Sdarrenr#define _KERNEL 35145554Sdarrenr#define KERNEL 36145554Sdarrenr#ifdef __OpenBSD__ 37145554Sdarrenrstruct file; 38145554Sdarrenr#endif 39145554Sdarrenr#include <sys/uio.h> 40145554Sdarrenr#undef _KERNEL 41145554Sdarrenr#undef KERNEL 42145554Sdarrenr#include <sys/file.h> 43145554Sdarrenr#include <sys/ioctl.h> 44145554Sdarrenr#ifdef __sgi 45145554Sdarrenr# include <sys/ptimers.h> 46145554Sdarrenr#endif 47145554Sdarrenr#include <sys/time.h> 48145554Sdarrenr#if !SOLARIS 49145554Sdarrenr# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000) 50145554Sdarrenr# include <sys/dirent.h> 51145554Sdarrenr# else 52145554Sdarrenr# include <sys/dir.h> 53145554Sdarrenr# endif 54145554Sdarrenr#else 55145554Sdarrenr# include <sys/filio.h> 56145554Sdarrenr#endif 57145554Sdarrenr#ifndef linux 58145554Sdarrenr# include <sys/protosw.h> 59145554Sdarrenr#endif 60145554Sdarrenr#include <sys/socket.h> 61145554Sdarrenr 62145554Sdarrenr#include <stdio.h> 63145554Sdarrenr#include <string.h> 64145554Sdarrenr#include <stdlib.h> 65145554Sdarrenr#include <ctype.h> 66145554Sdarrenr#include <fcntl.h> 67145554Sdarrenr 68145554Sdarrenr#ifdef __hpux 69145554Sdarrenr# define _NET_ROUTE_INCLUDED 70145554Sdarrenr#endif 71145554Sdarrenr#include <net/if.h> 72145554Sdarrenr#ifdef sun 73145554Sdarrenr# include <net/af.h> 74145554Sdarrenr#endif 75145554Sdarrenr#if __FreeBSD_version >= 300000 76145554Sdarrenr# include <net/if_var.h> 77145554Sdarrenr#endif 78145554Sdarrenr#ifdef __sgi 79145554Sdarrenr#include <sys/debug.h> 80145554Sdarrenr# ifdef IFF_DRVRLOCK /* IRIX6 */ 81145554Sdarrenr#include <sys/hashing.h> 82145554Sdarrenr# endif 83145554Sdarrenr#endif 84172776Sdarrenr#if defined(__FreeBSD__) || defined(SOLARIS2) 85145554Sdarrenr# include "radix_ipf.h" 86145554Sdarrenr#endif 87170268Sdarrenr#ifndef __osf__ 88170268Sdarrenr# include <net/route.h> 89170268Sdarrenr#endif 90145554Sdarrenr#include <netinet/in.h> 91145554Sdarrenr#if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /* IRIX < 6 */ && \ 92145554Sdarrenr !defined(__hpux) && !defined(linux) 93145554Sdarrenr# include <netinet/in_var.h> 94145554Sdarrenr#endif 95145554Sdarrenr#include <netinet/in_systm.h> 96145554Sdarrenr#include <netinet/ip.h> 97145554Sdarrenr#if !defined(linux) 98145554Sdarrenr# include <netinet/ip_var.h> 99145554Sdarrenr#endif 100145554Sdarrenr#include <netinet/tcp.h> 101145554Sdarrenr#if defined(__osf__) 102145554Sdarrenr# include <netinet/tcp_timer.h> 103145554Sdarrenr#endif 104145554Sdarrenr#if defined(__osf__) || defined(__hpux) || defined(__sgi) 105145554Sdarrenr# include "radix_ipf_local.h" 106145554Sdarrenr# define _RADIX_H_ 107145554Sdarrenr#endif 108145554Sdarrenr#include <netinet/udp.h> 109145554Sdarrenr#include <netinet/tcpip.h> 110145554Sdarrenr#include <netinet/ip_icmp.h> 111145554Sdarrenr#include <unistd.h> 112145554Sdarrenr#include <syslog.h> 113170268Sdarrenr#include <arpa/inet.h> 114145554Sdarrenr#ifdef __hpux 115145554Sdarrenr# undef _NET_ROUTE_INCLUDED 116145554Sdarrenr#endif 117145554Sdarrenr#include "netinet/ip_compat.h" 118145554Sdarrenr#include "netinet/ip_fil.h" 119145554Sdarrenr#include "netinet/ip_nat.h" 120145554Sdarrenr#include "netinet/ip_frag.h" 121145554Sdarrenr#include "netinet/ip_state.h" 122145554Sdarrenr#include "netinet/ip_proxy.h" 123145554Sdarrenr#include "netinet/ip_auth.h" 124145554Sdarrenr#ifdef IPFILTER_SYNC 125145554Sdarrenr#include "netinet/ip_sync.h" 126145554Sdarrenr#endif 127145554Sdarrenr#ifdef IPFILTER_SCAN 128145554Sdarrenr#include "netinet/ip_scan.h" 129145554Sdarrenr#endif 130145554Sdarrenr#include "netinet/ip_pool.h" 131145554Sdarrenr#ifdef IPFILTER_COMPILED 132145554Sdarrenr# include "netinet/ip_rules.h" 133145554Sdarrenr#endif 134145554Sdarrenr#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) 135145554Sdarrenr# include <sys/malloc.h> 136145554Sdarrenr#endif 137145554Sdarrenr#ifdef __hpux 138145554Sdarrenrstruct rtentry; 139145554Sdarrenr#endif 140145554Sdarrenr#include "md5.h" 141145554Sdarrenr 142145554Sdarrenr 143161357Sguido#if !defined(__osf__) && !defined(__linux__) 144145554Sdarrenrextern struct protosw inetsw[]; 145145554Sdarrenr#endif 146145554Sdarrenr 147145554Sdarrenr#include "ipt.h" 148145554Sdarrenrstatic struct ifnet **ifneta = NULL; 149145554Sdarrenrstatic int nifs = 0; 150145554Sdarrenr 151145554Sdarrenrstatic void fr_setifpaddr __P((struct ifnet *, char *)); 152145554Sdarrenrvoid init_ifp __P((void)); 153145554Sdarrenr#if defined(__sgi) && (IRIX < 60500) 154145554Sdarrenrstatic int no_output __P((struct ifnet *, struct mbuf *, 155145554Sdarrenr struct sockaddr *)); 156145554Sdarrenrstatic int write_output __P((struct ifnet *, struct mbuf *, 157145554Sdarrenr struct sockaddr *)); 158145554Sdarrenr#else 159145554Sdarrenr# if TRU64 >= 1885 160145554Sdarrenrstatic int no_output __P((struct ifnet *, struct mbuf *, 161145554Sdarrenr struct sockaddr *, struct rtentry *, char *)); 162145554Sdarrenrstatic int write_output __P((struct ifnet *, struct mbuf *, 163145554Sdarrenr struct sockaddr *, struct rtentry *, char *)); 164145554Sdarrenr# else 165145554Sdarrenrstatic int no_output __P((struct ifnet *, struct mbuf *, 166145554Sdarrenr struct sockaddr *, struct rtentry *)); 167145554Sdarrenrstatic int write_output __P((struct ifnet *, struct mbuf *, 168145554Sdarrenr struct sockaddr *, struct rtentry *)); 169145554Sdarrenr# endif 170145554Sdarrenr#endif 171145554Sdarrenr 172145554Sdarrenr 173170268Sdarrenrint ipfattach() 174145554Sdarrenr{ 175145554Sdarrenr fr_running = 1; 176145554Sdarrenr return 0; 177145554Sdarrenr} 178145554Sdarrenr 179145554Sdarrenr 180170268Sdarrenrint ipfdetach() 181145554Sdarrenr{ 182145554Sdarrenr fr_running = -1; 183145554Sdarrenr return 0; 184145554Sdarrenr} 185145554Sdarrenr 186145554Sdarrenr 187145554Sdarrenr/* 188145554Sdarrenr * Filter ioctl interface. 189145554Sdarrenr */ 190145554Sdarrenrint iplioctl(dev, cmd, data, mode) 191145554Sdarrenrint dev; 192145554Sdarrenrioctlcmd_t cmd; 193145554Sdarrenrcaddr_t data; 194145554Sdarrenrint mode; 195145554Sdarrenr{ 196170268Sdarrenr int error = 0, unit = 0, uid; 197170268Sdarrenr SPL_INT(s); 198145554Sdarrenr 199170268Sdarrenr uid = getuid(); 200145554Sdarrenr unit = dev; 201145554Sdarrenr 202145554Sdarrenr SPL_NET(s); 203145554Sdarrenr 204170268Sdarrenr error = fr_ioctlswitch(unit, data, cmd, mode, uid, NULL); 205170268Sdarrenr if (error != -1) { 206145554Sdarrenr SPL_X(s); 207145554Sdarrenr return error; 208145554Sdarrenr } 209145554Sdarrenr 210145554Sdarrenr SPL_X(s); 211145554Sdarrenr return error; 212145554Sdarrenr} 213145554Sdarrenr 214145554Sdarrenr 215145554Sdarrenrvoid fr_forgetifp(ifp) 216145554Sdarrenrvoid *ifp; 217145554Sdarrenr{ 218145554Sdarrenr register frentry_t *f; 219145554Sdarrenr 220145554Sdarrenr WRITE_ENTER(&ipf_mutex); 221145554Sdarrenr for (f = ipacct[0][fr_active]; (f != NULL); f = f->fr_next) 222145554Sdarrenr if (f->fr_ifa == ifp) 223145554Sdarrenr f->fr_ifa = (void *)-1; 224145554Sdarrenr for (f = ipacct[1][fr_active]; (f != NULL); f = f->fr_next) 225145554Sdarrenr if (f->fr_ifa == ifp) 226145554Sdarrenr f->fr_ifa = (void *)-1; 227145554Sdarrenr for (f = ipfilter[0][fr_active]; (f != NULL); f = f->fr_next) 228145554Sdarrenr if (f->fr_ifa == ifp) 229145554Sdarrenr f->fr_ifa = (void *)-1; 230145554Sdarrenr for (f = ipfilter[1][fr_active]; (f != NULL); f = f->fr_next) 231145554Sdarrenr if (f->fr_ifa == ifp) 232145554Sdarrenr f->fr_ifa = (void *)-1; 233145554Sdarrenr#ifdef USE_INET6 234145554Sdarrenr for (f = ipacct6[0][fr_active]; (f != NULL); f = f->fr_next) 235145554Sdarrenr if (f->fr_ifa == ifp) 236145554Sdarrenr f->fr_ifa = (void *)-1; 237145554Sdarrenr for (f = ipacct6[1][fr_active]; (f != NULL); f = f->fr_next) 238145554Sdarrenr if (f->fr_ifa == ifp) 239145554Sdarrenr f->fr_ifa = (void *)-1; 240145554Sdarrenr for (f = ipfilter6[0][fr_active]; (f != NULL); f = f->fr_next) 241145554Sdarrenr if (f->fr_ifa == ifp) 242145554Sdarrenr f->fr_ifa = (void *)-1; 243145554Sdarrenr for (f = ipfilter6[1][fr_active]; (f != NULL); f = f->fr_next) 244145554Sdarrenr if (f->fr_ifa == ifp) 245145554Sdarrenr f->fr_ifa = (void *)-1; 246145554Sdarrenr#endif 247145554Sdarrenr RWLOCK_EXIT(&ipf_mutex); 248145554Sdarrenr fr_natsync(ifp); 249145554Sdarrenr} 250145554Sdarrenr 251145554Sdarrenr 252145554Sdarrenr#if defined(__sgi) && (IRIX < 60500) 253145554Sdarrenrstatic int no_output(ifp, m, s) 254145554Sdarrenr#else 255145554Sdarrenr# if TRU64 >= 1885 256145554Sdarrenrstatic int no_output (ifp, m, s, rt, cp) 257145554Sdarrenrchar *cp; 258145554Sdarrenr# else 259145554Sdarrenrstatic int no_output(ifp, m, s, rt) 260145554Sdarrenr# endif 261145554Sdarrenrstruct rtentry *rt; 262145554Sdarrenr#endif 263145554Sdarrenrstruct ifnet *ifp; 264145554Sdarrenrstruct mbuf *m; 265145554Sdarrenrstruct sockaddr *s; 266145554Sdarrenr{ 267145554Sdarrenr return 0; 268145554Sdarrenr} 269145554Sdarrenr 270145554Sdarrenr 271145554Sdarrenr#if defined(__sgi) && (IRIX < 60500) 272145554Sdarrenrstatic int write_output(ifp, m, s) 273145554Sdarrenr#else 274145554Sdarrenr# if TRU64 >= 1885 275145554Sdarrenrstatic int write_output (ifp, m, s, rt, cp) 276145554Sdarrenrchar *cp; 277145554Sdarrenr# else 278145554Sdarrenrstatic int write_output(ifp, m, s, rt) 279145554Sdarrenr# endif 280145554Sdarrenrstruct rtentry *rt; 281145554Sdarrenr#endif 282145554Sdarrenrstruct ifnet *ifp; 283145554Sdarrenrstruct mbuf *m; 284145554Sdarrenrstruct sockaddr *s; 285145554Sdarrenr{ 286145554Sdarrenr char fname[32]; 287145554Sdarrenr mb_t *mb; 288145554Sdarrenr ip_t *ip; 289145554Sdarrenr int fd; 290145554Sdarrenr 291145554Sdarrenr mb = (mb_t *)m; 292145554Sdarrenr ip = MTOD(mb, ip_t *); 293145554Sdarrenr 294145554Sdarrenr#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 295145554Sdarrenr (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 296145554Sdarrenr (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 297145554Sdarrenr sprintf(fname, "/tmp/%s", ifp->if_xname); 298145554Sdarrenr#else 299145554Sdarrenr sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); 300145554Sdarrenr#endif 301145554Sdarrenr fd = open(fname, O_WRONLY|O_APPEND); 302145554Sdarrenr if (fd == -1) { 303145554Sdarrenr perror("open"); 304145554Sdarrenr return -1; 305145554Sdarrenr } 306145554Sdarrenr write(fd, (char *)ip, ntohs(ip->ip_len)); 307145554Sdarrenr close(fd); 308145554Sdarrenr return 0; 309145554Sdarrenr} 310145554Sdarrenr 311145554Sdarrenr 312145554Sdarrenrstatic void fr_setifpaddr(ifp, addr) 313145554Sdarrenrstruct ifnet *ifp; 314145554Sdarrenrchar *addr; 315145554Sdarrenr{ 316145554Sdarrenr#ifdef __sgi 317145554Sdarrenr struct in_ifaddr *ifa; 318145554Sdarrenr#else 319145554Sdarrenr struct ifaddr *ifa; 320145554Sdarrenr#endif 321145554Sdarrenr 322145554Sdarrenr#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 323145554Sdarrenr if (ifp->if_addrlist.tqh_first != NULL) 324145554Sdarrenr#else 325145554Sdarrenr# ifdef __sgi 326145554Sdarrenr if (ifp->in_ifaddr != NULL) 327145554Sdarrenr# else 328145554Sdarrenr if (ifp->if_addrlist != NULL) 329145554Sdarrenr# endif 330145554Sdarrenr#endif 331145554Sdarrenr return; 332145554Sdarrenr 333145554Sdarrenr ifa = (struct ifaddr *)malloc(sizeof(*ifa)); 334145554Sdarrenr#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 335145554Sdarrenr ifp->if_addrlist.tqh_first = ifa; 336145554Sdarrenr#else 337145554Sdarrenr# ifdef __sgi 338145554Sdarrenr ifp->in_ifaddr = ifa; 339145554Sdarrenr# else 340145554Sdarrenr ifp->if_addrlist = ifa; 341145554Sdarrenr# endif 342145554Sdarrenr#endif 343145554Sdarrenr 344145554Sdarrenr if (ifa != NULL) { 345145554Sdarrenr struct sockaddr_in *sin; 346145554Sdarrenr 347145554Sdarrenr#ifdef __sgi 348145554Sdarrenr sin = (struct sockaddr_in *)&ifa->ia_addr; 349145554Sdarrenr#else 350145554Sdarrenr sin = (struct sockaddr_in *)&ifa->ifa_addr; 351145554Sdarrenr#endif 352145554Sdarrenr sin->sin_addr.s_addr = inet_addr(addr); 353145554Sdarrenr if (sin->sin_addr.s_addr == 0) 354145554Sdarrenr abort(); 355145554Sdarrenr } 356145554Sdarrenr} 357145554Sdarrenr 358145554Sdarrenrstruct ifnet *get_unit(name, v) 359145554Sdarrenrchar *name; 360145554Sdarrenrint v; 361145554Sdarrenr{ 362145554Sdarrenr struct ifnet *ifp, **ifpp, **old_ifneta; 363145554Sdarrenr char *addr; 364145554Sdarrenr#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 365145554Sdarrenr (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 366145554Sdarrenr (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 367145554Sdarrenr 368145554Sdarrenr if (name == NULL) 369145554Sdarrenr name = "anon0"; 370145554Sdarrenr 371145554Sdarrenr addr = strchr(name, '='); 372145554Sdarrenr if (addr != NULL) 373145554Sdarrenr *addr++ = '\0'; 374145554Sdarrenr 375145554Sdarrenr for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 376145554Sdarrenr if (!strcmp(name, ifp->if_xname)) { 377145554Sdarrenr if (addr != NULL) 378145554Sdarrenr fr_setifpaddr(ifp, addr); 379145554Sdarrenr return ifp; 380145554Sdarrenr } 381145554Sdarrenr } 382145554Sdarrenr#else 383145554Sdarrenr char *s, ifname[LIFNAMSIZ+1]; 384145554Sdarrenr 385145554Sdarrenr if (name == NULL) 386145554Sdarrenr name = "anon0"; 387145554Sdarrenr 388145554Sdarrenr addr = strchr(name, '='); 389145554Sdarrenr if (addr != NULL) 390145554Sdarrenr *addr++ = '\0'; 391145554Sdarrenr 392145554Sdarrenr for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 393172776Sdarrenr COPYIFNAME(v, ifp, ifname); 394145554Sdarrenr if (!strcmp(name, ifname)) { 395145554Sdarrenr if (addr != NULL) 396145554Sdarrenr fr_setifpaddr(ifp, addr); 397145554Sdarrenr return ifp; 398145554Sdarrenr } 399145554Sdarrenr } 400145554Sdarrenr#endif 401145554Sdarrenr 402145554Sdarrenr if (!ifneta) { 403145554Sdarrenr ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2); 404145554Sdarrenr if (!ifneta) 405145554Sdarrenr return NULL; 406145554Sdarrenr ifneta[1] = NULL; 407145554Sdarrenr ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp)); 408145554Sdarrenr if (!ifneta[0]) { 409145554Sdarrenr free(ifneta); 410145554Sdarrenr return NULL; 411145554Sdarrenr } 412145554Sdarrenr nifs = 1; 413145554Sdarrenr } else { 414145554Sdarrenr old_ifneta = ifneta; 415145554Sdarrenr nifs++; 416145554Sdarrenr ifneta = (struct ifnet **)realloc(ifneta, 417145554Sdarrenr (nifs + 1) * sizeof(ifp)); 418145554Sdarrenr if (!ifneta) { 419145554Sdarrenr free(old_ifneta); 420145554Sdarrenr nifs = 0; 421145554Sdarrenr return NULL; 422145554Sdarrenr } 423145554Sdarrenr ifneta[nifs] = NULL; 424145554Sdarrenr ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp)); 425145554Sdarrenr if (!ifneta[nifs - 1]) { 426145554Sdarrenr nifs--; 427145554Sdarrenr return NULL; 428145554Sdarrenr } 429145554Sdarrenr } 430145554Sdarrenr ifp = ifneta[nifs - 1]; 431145554Sdarrenr 432172776Sdarrenr#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 433172776Sdarrenr TAILQ_INIT(&ifp->if_addrlist); 434172776Sdarrenr#endif 435145554Sdarrenr#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 436145554Sdarrenr (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 437145554Sdarrenr (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 438145554Sdarrenr (void) strncpy(ifp->if_xname, name, sizeof(ifp->if_xname)); 439145554Sdarrenr#else 440145554Sdarrenr for (s = name; *s && !ISDIGIT(*s); s++) 441145554Sdarrenr ; 442145554Sdarrenr if (*s && ISDIGIT(*s)) { 443145554Sdarrenr ifp->if_unit = atoi(s); 444145554Sdarrenr ifp->if_name = (char *)malloc(s - name + 1); 445145554Sdarrenr (void) strncpy(ifp->if_name, name, s - name); 446145554Sdarrenr ifp->if_name[s - name] = '\0'; 447145554Sdarrenr } else { 448145554Sdarrenr ifp->if_name = strdup(name); 449145554Sdarrenr ifp->if_unit = -1; 450145554Sdarrenr } 451145554Sdarrenr#endif 452170268Sdarrenr ifp->if_output = (void *)no_output; 453145554Sdarrenr 454145554Sdarrenr if (addr != NULL) { 455145554Sdarrenr fr_setifpaddr(ifp, addr); 456145554Sdarrenr } 457145554Sdarrenr 458145554Sdarrenr return ifp; 459145554Sdarrenr} 460145554Sdarrenr 461145554Sdarrenr 462145554Sdarrenrchar *get_ifname(ifp) 463145554Sdarrenrstruct ifnet *ifp; 464145554Sdarrenr{ 465145554Sdarrenr static char ifname[LIFNAMSIZ]; 466145554Sdarrenr 467145554Sdarrenr#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(linux) || \ 468145554Sdarrenr (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 469145554Sdarrenr sprintf(ifname, "%s", ifp->if_xname); 470145554Sdarrenr#else 471145554Sdarrenr sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit); 472145554Sdarrenr#endif 473145554Sdarrenr return ifname; 474145554Sdarrenr} 475145554Sdarrenr 476145554Sdarrenr 477145554Sdarrenr 478145554Sdarrenrvoid init_ifp() 479145554Sdarrenr{ 480145554Sdarrenr struct ifnet *ifp, **ifpp; 481145554Sdarrenr char fname[32]; 482145554Sdarrenr int fd; 483145554Sdarrenr 484145554Sdarrenr#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \ 485145554Sdarrenr (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ 486145554Sdarrenr (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) 487145554Sdarrenr for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 488170268Sdarrenr ifp->if_output = (void *)write_output; 489145554Sdarrenr sprintf(fname, "/tmp/%s", ifp->if_xname); 490145554Sdarrenr fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); 491145554Sdarrenr if (fd == -1) 492145554Sdarrenr perror("open"); 493145554Sdarrenr else 494145554Sdarrenr close(fd); 495145554Sdarrenr } 496145554Sdarrenr#else 497145554Sdarrenr 498145554Sdarrenr for (ifpp = ifneta; ifpp && (ifp = *ifpp); ifpp++) { 499145554Sdarrenr ifp->if_output = write_output; 500145554Sdarrenr sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit); 501145554Sdarrenr fd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); 502145554Sdarrenr if (fd == -1) 503145554Sdarrenr perror("open"); 504145554Sdarrenr else 505145554Sdarrenr close(fd); 506145554Sdarrenr } 507145554Sdarrenr#endif 508145554Sdarrenr} 509145554Sdarrenr 510145554Sdarrenr 511145554Sdarrenrint fr_fastroute(m, mpp, fin, fdp) 512145554Sdarrenrmb_t *m, **mpp; 513145554Sdarrenrfr_info_t *fin; 514145554Sdarrenrfrdest_t *fdp; 515145554Sdarrenr{ 516145554Sdarrenr struct ifnet *ifp = fdp->fd_ifp; 517145554Sdarrenr ip_t *ip = fin->fin_ip; 518161357Sguido int error = 0; 519161357Sguido frentry_t *fr; 520161357Sguido void *sifp; 521145554Sdarrenr 522145554Sdarrenr if (!ifp) 523145554Sdarrenr return 0; /* no routing table out here */ 524145554Sdarrenr 525161357Sguido fr = fin->fin_fr; 526145554Sdarrenr ip->ip_sum = 0; 527161357Sguido 528161357Sguido if (fin->fin_out == 0) { 529161357Sguido sifp = fin->fin_ifp; 530161357Sguido fin->fin_ifp = ifp; 531161357Sguido fin->fin_out = 1; 532161357Sguido (void) fr_acctpkt(fin, NULL); 533161357Sguido fin->fin_fr = NULL; 534161357Sguido if (!fr || !(fr->fr_flags & FR_RETMASK)) { 535161357Sguido u_32_t pass; 536161357Sguido 537161357Sguido (void) fr_checkstate(fin, &pass); 538161357Sguido } 539161357Sguido 540161357Sguido switch (fr_checknatout(fin, NULL)) 541161357Sguido { 542161357Sguido case 0 : 543161357Sguido break; 544161357Sguido case 1 : 545161357Sguido ip->ip_sum = 0; 546161357Sguido break; 547161357Sguido case -1 : 548161357Sguido error = -1; 549161357Sguido goto done; 550161357Sguido break; 551161357Sguido } 552161357Sguido 553161357Sguido fin->fin_ifp = sifp; 554161357Sguido fin->fin_out = 0; 555161357Sguido } 556161357Sguido 557145554Sdarrenr#if defined(__sgi) && (IRIX < 60500) 558145554Sdarrenr (*ifp->if_output)(ifp, (void *)ip, NULL); 559145554Sdarrenr# if TRU64 >= 1885 560145554Sdarrenr (*ifp->if_output)(ifp, (void *)m, NULL, 0, 0); 561145554Sdarrenr# else 562145554Sdarrenr (*ifp->if_output)(ifp, (void *)m, NULL, 0); 563145554Sdarrenr# endif 564145554Sdarrenr#endif 565161357Sguidodone: 566161357Sguido return error; 567145554Sdarrenr} 568145554Sdarrenr 569145554Sdarrenr 570145554Sdarrenrint fr_send_reset(fin) 571145554Sdarrenrfr_info_t *fin; 572145554Sdarrenr{ 573145554Sdarrenr verbose("- TCP RST sent\n"); 574145554Sdarrenr return 0; 575145554Sdarrenr} 576145554Sdarrenr 577145554Sdarrenr 578145554Sdarrenrint fr_send_icmp_err(type, fin, dst) 579145554Sdarrenrint type; 580145554Sdarrenrfr_info_t *fin; 581145554Sdarrenrint dst; 582145554Sdarrenr{ 583145554Sdarrenr verbose("- ICMP unreachable sent\n"); 584145554Sdarrenr return 0; 585145554Sdarrenr} 586145554Sdarrenr 587145554Sdarrenr 588145554Sdarrenrvoid frsync(ifp) 589145554Sdarrenrvoid *ifp; 590145554Sdarrenr{ 591145554Sdarrenr return; 592145554Sdarrenr} 593145554Sdarrenr 594145554Sdarrenr 595145554Sdarrenrvoid m_freem(m) 596145554Sdarrenrmb_t *m; 597145554Sdarrenr{ 598145554Sdarrenr return; 599145554Sdarrenr} 600145554Sdarrenr 601145554Sdarrenr 602145554Sdarrenrvoid m_copydata(m, off, len, cp) 603145554Sdarrenrmb_t *m; 604145554Sdarrenrint off, len; 605145554Sdarrenrcaddr_t cp; 606145554Sdarrenr{ 607145554Sdarrenr bcopy((char *)m + off, cp, len); 608145554Sdarrenr} 609145554Sdarrenr 610145554Sdarrenr 611145554Sdarrenrint ipfuiomove(buf, len, rwflag, uio) 612145554Sdarrenrcaddr_t buf; 613145554Sdarrenrint len, rwflag; 614145554Sdarrenrstruct uio *uio; 615145554Sdarrenr{ 616145554Sdarrenr int left, ioc, num, offset; 617145554Sdarrenr struct iovec *io; 618145554Sdarrenr char *start; 619145554Sdarrenr 620145554Sdarrenr if (rwflag == UIO_READ) { 621145554Sdarrenr left = len; 622145554Sdarrenr ioc = 0; 623145554Sdarrenr 624145554Sdarrenr offset = uio->uio_offset; 625145554Sdarrenr 626145554Sdarrenr while ((left > 0) && (ioc < uio->uio_iovcnt)) { 627145554Sdarrenr io = uio->uio_iov + ioc; 628145554Sdarrenr num = io->iov_len; 629145554Sdarrenr if (num > left) 630145554Sdarrenr num = left; 631145554Sdarrenr start = (char *)io->iov_base + offset; 632145554Sdarrenr if (start > (char *)io->iov_base + io->iov_len) { 633145554Sdarrenr offset -= io->iov_len; 634145554Sdarrenr ioc++; 635145554Sdarrenr continue; 636145554Sdarrenr } 637145554Sdarrenr bcopy(buf, start, num); 638145554Sdarrenr uio->uio_resid -= num; 639145554Sdarrenr uio->uio_offset += num; 640145554Sdarrenr left -= num; 641145554Sdarrenr if (left > 0) 642145554Sdarrenr ioc++; 643145554Sdarrenr } 644145554Sdarrenr if (left > 0) 645145554Sdarrenr return EFAULT; 646145554Sdarrenr } 647145554Sdarrenr return 0; 648145554Sdarrenr} 649145554Sdarrenr 650145554Sdarrenr 651145554Sdarrenru_32_t fr_newisn(fin) 652145554Sdarrenrfr_info_t *fin; 653145554Sdarrenr{ 654145554Sdarrenr static int iss_seq_off = 0; 655145554Sdarrenr u_char hash[16]; 656145554Sdarrenr u_32_t newiss; 657145554Sdarrenr MD5_CTX ctx; 658145554Sdarrenr 659145554Sdarrenr /* 660145554Sdarrenr * Compute the base value of the ISS. It is a hash 661145554Sdarrenr * of (saddr, sport, daddr, dport, secret). 662145554Sdarrenr */ 663145554Sdarrenr MD5Init(&ctx); 664145554Sdarrenr 665145554Sdarrenr MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src, 666145554Sdarrenr sizeof(fin->fin_fi.fi_src)); 667145554Sdarrenr MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst, 668145554Sdarrenr sizeof(fin->fin_fi.fi_dst)); 669145554Sdarrenr MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat)); 670145554Sdarrenr 671145554Sdarrenr /* MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); */ 672145554Sdarrenr 673145554Sdarrenr MD5Final(hash, &ctx); 674145554Sdarrenr 675145554Sdarrenr memcpy(&newiss, hash, sizeof(newiss)); 676145554Sdarrenr 677145554Sdarrenr /* 678145554Sdarrenr * Now increment our "timer", and add it in to 679145554Sdarrenr * the computed value. 680145554Sdarrenr * 681145554Sdarrenr * XXX Use `addin'? 682145554Sdarrenr * XXX TCP_ISSINCR too large to use? 683145554Sdarrenr */ 684145554Sdarrenr iss_seq_off += 0x00010000; 685145554Sdarrenr newiss += iss_seq_off; 686145554Sdarrenr return newiss; 687145554Sdarrenr} 688145554Sdarrenr 689145554Sdarrenr 690145554Sdarrenr/* ------------------------------------------------------------------------ */ 691145554Sdarrenr/* Function: fr_nextipid */ 692145554Sdarrenr/* Returns: int - 0 == success, -1 == error (packet should be droppped) */ 693145554Sdarrenr/* Parameters: fin(I) - pointer to packet information */ 694145554Sdarrenr/* */ 695145554Sdarrenr/* Returns the next IPv4 ID to use for this packet. */ 696145554Sdarrenr/* ------------------------------------------------------------------------ */ 697145554SdarrenrINLINE u_short fr_nextipid(fin) 698145554Sdarrenrfr_info_t *fin; 699145554Sdarrenr{ 700145554Sdarrenr static u_short ipid = 0; 701145554Sdarrenr u_short id; 702145554Sdarrenr 703145554Sdarrenr MUTEX_ENTER(&ipf_rw); 704145554Sdarrenr id = ipid++; 705145554Sdarrenr MUTEX_EXIT(&ipf_rw); 706145554Sdarrenr 707145554Sdarrenr return id; 708145554Sdarrenr} 709145554Sdarrenr 710145554Sdarrenr 711145554SdarrenrINLINE void fr_checkv4sum(fin) 712145554Sdarrenrfr_info_t *fin; 713145554Sdarrenr{ 714145554Sdarrenr if (fr_checkl4sum(fin) == -1) 715145554Sdarrenr fin->fin_flx |= FI_BAD; 716145554Sdarrenr} 717145554Sdarrenr 718145554Sdarrenr 719145554Sdarrenr#ifdef USE_INET6 720145554SdarrenrINLINE void fr_checkv6sum(fin) 721145554Sdarrenrfr_info_t *fin; 722145554Sdarrenr{ 723145554Sdarrenr if (fr_checkl4sum(fin) == -1) 724145554Sdarrenr fin->fin_flx |= FI_BAD; 725145554Sdarrenr} 726145554Sdarrenr#endif 727145554Sdarrenr 728145554Sdarrenr 729145554Sdarrenr/* 730145554Sdarrenr * See above for description, except that all addressing is in user space. 731145554Sdarrenr */ 732145554Sdarrenrint copyoutptr(src, dst, size) 733145554Sdarrenrvoid *src, *dst; 734145554Sdarrenrsize_t size; 735145554Sdarrenr{ 736145554Sdarrenr caddr_t ca; 737145554Sdarrenr 738145554Sdarrenr bcopy(dst, (char *)&ca, sizeof(ca)); 739145554Sdarrenr bcopy(src, ca, size); 740145554Sdarrenr return 0; 741145554Sdarrenr} 742145554Sdarrenr 743145554Sdarrenr 744145554Sdarrenr/* 745145554Sdarrenr * See above for description, except that all addressing is in user space. 746145554Sdarrenr */ 747145554Sdarrenrint copyinptr(src, dst, size) 748145554Sdarrenrvoid *src, *dst; 749145554Sdarrenrsize_t size; 750145554Sdarrenr{ 751145554Sdarrenr caddr_t ca; 752145554Sdarrenr 753145554Sdarrenr bcopy(src, (char *)&ca, sizeof(ca)); 754145554Sdarrenr bcopy(ca, dst, size); 755145554Sdarrenr return 0; 756145554Sdarrenr} 757145554Sdarrenr 758145554Sdarrenr 759145554Sdarrenr/* 760145554Sdarrenr * return the first IP Address associated with an interface 761145554Sdarrenr */ 762145554Sdarrenrint fr_ifpaddr(v, atype, ifptr, inp, inpmask) 763145554Sdarrenrint v, atype; 764145554Sdarrenrvoid *ifptr; 765145554Sdarrenrstruct in_addr *inp, *inpmask; 766145554Sdarrenr{ 767145554Sdarrenr struct ifnet *ifp = ifptr; 768145554Sdarrenr#ifdef __sgi 769145554Sdarrenr struct in_ifaddr *ifa; 770145554Sdarrenr#else 771145554Sdarrenr struct ifaddr *ifa; 772145554Sdarrenr#endif 773145554Sdarrenr 774145554Sdarrenr#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 775145554Sdarrenr ifa = ifp->if_addrlist.tqh_first; 776145554Sdarrenr#else 777145554Sdarrenr# ifdef __sgi 778145554Sdarrenr ifa = (struct in_ifaddr *)ifp->in_ifaddr; 779145554Sdarrenr# else 780145554Sdarrenr ifa = ifp->if_addrlist; 781145554Sdarrenr# endif 782145554Sdarrenr#endif 783145554Sdarrenr if (ifa != NULL) { 784145554Sdarrenr struct sockaddr_in *sin, mask; 785145554Sdarrenr 786145554Sdarrenr mask.sin_addr.s_addr = 0xffffffff; 787145554Sdarrenr 788145554Sdarrenr#ifdef __sgi 789145554Sdarrenr sin = (struct sockaddr_in *)&ifa->ia_addr; 790145554Sdarrenr#else 791145554Sdarrenr sin = (struct sockaddr_in *)&ifa->ifa_addr; 792145554Sdarrenr#endif 793145554Sdarrenr 794145554Sdarrenr return fr_ifpfillv4addr(atype, sin, &mask, inp, inpmask); 795145554Sdarrenr } 796145554Sdarrenr return 0; 797145554Sdarrenr} 798170268Sdarrenr 799170268Sdarrenr 800170268Sdarrenrint ipfsync() 801170268Sdarrenr{ 802170268Sdarrenr return 0; 803170268Sdarrenr} 804180778Sdarrenr 805180778Sdarrenr 806181313Smlaier#ifndef ipf_random 807180778Sdarrenru_32_t ipf_random() 808180778Sdarrenr{ 809180778Sdarrenr static int seeded = 0; 810180778Sdarrenr 811180778Sdarrenr /* 812180778Sdarrenr * Choose a non-random seed so that "randomness" can be "tested." 813180778Sdarrenr */ 814180778Sdarrenr if (seeded == 0) { 815180778Sdarrenr srand(0); 816180778Sdarrenr seeded = 1; 817180778Sdarrenr } 818180778Sdarrenr return rand(); 819180778Sdarrenr} 820181313Smlaier#endif 821