diff options
author | Kjell Wooding <kjell@cvs.openbsd.org> | 1999-12-14 04:17:18 +0000 |
---|---|---|
committer | Kjell Wooding <kjell@cvs.openbsd.org> | 1999-12-14 04:17:18 +0000 |
commit | d7490544c35fd00d5fa574f813e1a80638a69107 (patch) | |
tree | 5622e08b40efddbb6423f66ed3229d3f00d88fdd | |
parent | 9f37deb56afe80d3130c1317b569eaa08a5518ab (diff) |
New ipfilter files. Preparing for merge of ipfilter 3.3.4.
-rw-r--r-- | sbin/ipf/facpri.c | 147 | ||||
-rw-r--r-- | sbin/ipf/facpri.h | 43 | ||||
-rw-r--r-- | sbin/ipnat/natparse.c | 795 | ||||
-rw-r--r-- | sys/netinet/ip_raudio_pxy.c | 294 | ||||
-rw-r--r-- | sys/netinet/ip_rcmd_pxy.c | 157 | ||||
-rw-r--r-- | sys/netinet/ipl.h | 17 |
6 files changed, 1453 insertions, 0 deletions
diff --git a/sbin/ipf/facpri.c b/sbin/ipf/facpri.c new file mode 100644 index 00000000000..c3af7068cc2 --- /dev/null +++ b/sbin/ipf/facpri.c @@ -0,0 +1,147 @@ +/* $OpenBSD: facpri.c,v 1.1 1999/12/14 04:17:17 kjell Exp $ */ +/* + * Copyright (C) 1993-1998 by Darren Reed. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and due credit is given + * to the original author and the contributors. + */ +#include <stdio.h> +#include <string.h> +#include <limits.h> +#include <sys/types.h> +#if !defined(__SVR4) && !defined(__svr4__) +#include <strings.h> +#endif +#include <stdlib.h> +#include <unistd.h> +#include <stddef.h> +#include <syslog.h> +#include "facpri.h" + +#if !defined(lint) +static const char rcsid[] = "@(#)$Id: facpri.c,v 1.1 1999/12/14 04:17:17 kjell Exp $"; +#endif + +typedef struct table { + char *name; + int value; +} table_t; + +table_t facs[] = { + { "kern", LOG_KERN }, { "user", LOG_USER }, + { "mail", LOG_MAIL }, { "daemon", LOG_DAEMON }, + { "auth", LOG_AUTH }, { "syslog", LOG_SYSLOG }, + { "lpr", LOG_LPR }, { "news", LOG_NEWS }, + { "uucp", LOG_UUCP }, +#if LOG_CRON == LOG_CRON2 + { "cron2", LOG_CRON1 }, +#else + { "cron", LOG_CRON1 }, +#endif +#ifdef LOG_FTP + { "ftp", LOG_FTP }, +#endif +#ifdef LOG_AUTHPRIV + { "authpriv", LOG_AUTHPRIV }, +#endif +#ifdef LOG_AUDIT + { "audit", LOG_AUDIT }, +#endif +#ifdef LOG_LFMT + { "logalert", LOG_LFMT }, +#endif +#if LOG_CRON == LOG_CRON1 + { "cron", LOG_CRON2 }, +#else + { "cron2", LOG_CRON2 }, +#endif + { "local0", LOG_LOCAL0 }, { "local1", LOG_LOCAL1 }, + { "local2", LOG_LOCAL2 }, { "local3", LOG_LOCAL3 }, + { "local4", LOG_LOCAL4 }, { "local5", LOG_LOCAL5 }, + { "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 }, + { NULL, 0 } +}; + + +/* + * map a facility number to its name + */ +char * +fac_toname(facpri) + int facpri; +{ + int i, j, fac; + + fac = facpri & LOG_FACMASK; + j = fac >> 3; + if (j < 24) { + if (facs[j].value == fac) + return facs[j].name; + for (i = 0; facs[i].name; i++) + if (fac == facs[i].value) + return facs[i].name; + } + + return NULL; +} + + +/* + * map a facility name to its number + */ +int +fac_findname(name) + char *name; +{ + int i; + + for (i = 0; facs[i].name; i++) + if (!strcmp(facs[i].name, name)) + return facs[i].value; + return -1; +} + + +table_t pris[] = { + { "emerg", LOG_EMERG }, { "alert", LOG_ALERT }, + { "crit", LOG_CRIT }, { "err", LOG_ERR }, + { "warn", LOG_WARNING }, { "notice", LOG_NOTICE }, + { "info", LOG_INFO }, { "debug", LOG_DEBUG }, + { NULL, 0 } +}; + + +/* + * map a priority name to its number + */ +int +pri_findname(name) + char *name; +{ + int i; + + for (i = 0; pris[i].name; i++) + if (!strcmp(pris[i].name, name)) + return pris[i].value; + return -1; +} + + +/* + * map a priority number to its name + */ +char * +pri_toname(facpri) + int facpri; +{ + int i, pri; + + pri = facpri & LOG_PRIMASK; + if (pris[pri].value == pri) + return pris[pri].name; + for (i = 0; pris[i].name; i++) + if (pri == pris[i].value) + return pris[i].name; + return NULL; +} diff --git a/sbin/ipf/facpri.h b/sbin/ipf/facpri.h new file mode 100644 index 00000000000..1ca7ddd26f5 --- /dev/null +++ b/sbin/ipf/facpri.h @@ -0,0 +1,43 @@ +/* $OpenBSD: facpri.h,v 1.1 1999/12/14 04:17:17 kjell Exp $ */ +/* + * Copyright (C) 1999 by Darren Reed. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and due credit is given + * to the original author and the contributors. + * $Id: facpri.h,v 1.1 1999/12/14 04:17:17 kjell Exp $ + */ + +#ifndef __FACPRI_H__ +#define __FACPRI_H__ + +#ifndef __P +# define P_DEF +# ifdef __STDC__ +# define __P(x) x +# else +# define __P(x) () +# endif +#endif + +extern char *fac_toname __P((int)); +extern int fac_findname __P((char *)); + +extern char *pri_toname __P((int)); +extern int pri_findname __P((char *)); + +#ifdef P_DEF +# undef __P +# undef P_DEF +#endif + +#if LOG_CRON == (9<<3) +# define LOG_CRON1 LOG_CRON +# define LOG_CRON2 (15<<3) +#endif +#if LOG_CRON == (15<<3) +# define LOG_CRON1 (9<<3) +# define LOG_CRON2 LOG_CRON +#endif + +#endif /* __FACPRI_H__ */ diff --git a/sbin/ipnat/natparse.c b/sbin/ipnat/natparse.c new file mode 100644 index 00000000000..f20a8704ae5 --- /dev/null +++ b/sbin/ipnat/natparse.c @@ -0,0 +1,795 @@ +/* $OpenBSD: natparse.c,v 1.1 1999/12/14 04:17:17 kjell Exp $ */ +/* + * Copyright (C) 1993-1998 by Darren Reed. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and due credit is given + * to the original author and the contributors. + */ +#include <stdio.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/types.h> +#if !defined(__SVR4) && !defined(__svr4__) +#include <strings.h> +#else +#include <sys/byteorder.h> +#endif +#include <sys/time.h> +#include <sys/param.h> +#include <stdlib.h> +#include <unistd.h> +#include <stddef.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#if defined(sun) && (defined(__svr4__) || defined(__SVR4)) +# include <sys/ioccom.h> +# include <sys/sysmacros.h> +#endif +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/tcp.h> +#include <net/if.h> +#if __FreeBSD_version >= 300000 +# include <net/if_var.h> +#endif +#include <netdb.h> +#include <arpa/nameser.h> +#include <arpa/inet.h> +#include <resolv.h> +#include <ctype.h> +#include <netinet/ip_fil_compat.h> +#include <netinet/ip_fil.h> +#include <netinet/ip_proxy.h> +#include <netinet/ip_nat.h> + +#if defined(sun) && !SOLARIS2 +# define STRERROR(x) sys_errlist[x] +extern char *sys_errlist[]; +#else +# define STRERROR(x) strerror(x) +#endif + +#if !defined(lint) +static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; +static const char rcsid[] = "@(#)$Id: natparse.c,v 1.1 1999/12/14 04:17:17 kjell Exp $"; +#endif + + +#if SOLARIS +#define bzero(a,b) memset(a,0,b) +#endif + +extern int countbits __P((u_32_t)); +extern u_32_t hostnum __P((char *, int *, int)); + +ipnat_t *natparse __P((char *, int)); +void printnat __P((ipnat_t *, int, void *)); +void natparsefile __P((int, char *, int)); +u_32_t n_hostmask __P((char *)); +u_short n_portnum __P((char *, char *, int)); +void nat_setgroupmap __P((struct ipnat *)); + +#define OPT_REM 1 +#define OPT_NODO 2 +#define OPT_STAT 4 +#define OPT_LIST 8 +#define OPT_VERBOSE 16 +#define OPT_FLUSH 32 +#define OPT_CLEAR 64 + + +void printnat(np, verbose, ptr) +ipnat_t *np; +int verbose; +void *ptr; +{ + struct protoent *pr; + struct servent *sv; + int bits; + + switch (np->in_redir) + { + case NAT_REDIRECT : + printf("rdr "); + break; + case NAT_MAP : + printf("map "); + break; + case NAT_MAPBLK : + printf("map-block "); + break; + case NAT_BIMAP : + printf("bimap "); + break; + default : + fprintf(stderr, "unknown value for in_redir: %#x\n", + np->in_redir); + break; + } + + if (np->in_redir == NAT_REDIRECT) { + printf("%s ", np->in_ifname); + if (np->in_src[0].s_addr || np->in_src[1].s_addr) { + printf("from %s",inet_ntoa(np->in_src[0])); + bits = countbits(np->in_src[1].s_addr); + if (bits != -1) + printf("/%d ", bits); + else + printf("/%s ", inet_ntoa(np->in_src[1])); + } + printf("%s",inet_ntoa(np->in_out[0])); + bits = countbits(np->in_out[1].s_addr); + if (bits != -1) + printf("/%d ", bits); + else + printf("/%s ", inet_ntoa(np->in_out[1])); + if (np->in_pmin) + printf("port %d ", ntohs(np->in_pmin)); + printf("-> %s", inet_ntoa(np->in_in[0])); + if (np->in_pnext) + printf(" port %d", ntohs(np->in_pnext)); + if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP) + printf(" tcp/udp"); + else if ((np->in_flags & IPN_TCP) == IPN_TCP) + printf(" tcp"); + else if ((np->in_flags & IPN_UDP) == IPN_UDP) + printf(" udp"); + printf("\n"); + if (verbose) + printf("\t%p %lu %x %u %p %d\n", np->in_ifp, + np->in_space, np->in_flags, np->in_pnext, np, + np->in_use); + } else { + np->in_nextip.s_addr = htonl(np->in_nextip.s_addr); + printf("%s %s/", np->in_ifname, inet_ntoa(np->in_in[0])); + bits = countbits(np->in_in[1].s_addr); + if (bits != -1) + printf("%d ", bits); + else + printf("%s", inet_ntoa(np->in_in[1])); + printf(" -> "); + if (np->in_flags & IPN_RANGE) { + printf("range %s-", inet_ntoa(np->in_out[0])); + printf("%s", inet_ntoa(np->in_out[1])); + } else { + printf("%s/", inet_ntoa(np->in_out[0])); + bits = countbits(np->in_out[1].s_addr); + if (bits != -1) + printf("%d ", bits); + else + printf("%s", inet_ntoa(np->in_out[1])); + } + if (*np->in_plabel) { + pr = getprotobynumber(np->in_p); + printf(" proxy port"); + if (np->in_dport != 0) { + if (pr != NULL) + sv = getservbyport(np->in_dport, + pr->p_name); + else + sv = getservbyport(np->in_dport, NULL); + if (sv != NULL) + printf(" %s", sv->s_name); + else + printf(" %hu", ntohs(np->in_dport)); + } + printf(" %.*s/", (int)sizeof(np->in_plabel), + np->in_plabel); + if (pr != NULL) + fputs(pr->p_name, stdout); + else + printf("%d", np->in_p); + } else if (np->in_redir == NAT_MAPBLK) { + printf(" ports %d", np->in_pmin); + if (verbose) + printf("\n\tip modulous %d", np->in_pmax); + } else if (np->in_pmin || np->in_pmax) { + printf(" portmap"); + if (np->in_flags & IPN_AUTOPORTMAP) { + printf(" auto"); + if (verbose) + printf(" [%d:%d %d %d]", + ntohs(np->in_pmin), + ntohs(np->in_pmax), + np->in_ippip, np->in_ppip); + } else { + if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP) + printf(" tcp/udp"); + else if (np->in_flags & IPN_TCP) + printf(" tcp"); + else if (np->in_flags & IPN_UDP) + printf(" udp"); + printf(" %d:%d", ntohs(np->in_pmin), + ntohs(np->in_pmax)); + } + } + printf("\n"); + if (verbose) { + printf("\tifp %p space %lu nextip %s pnext %d", + np->in_ifp, np->in_space, + inet_ntoa(np->in_nextip), np->in_pnext); + printf(" flags %x use %u\n", + np->in_flags, np->in_use); + } + } +} + + +void nat_setgroupmap(n) +ipnat_t *n; +{ + if (n->in_outmsk == n->in_inmsk) + n->in_ippip = 1; + else if (n->in_flags & IPN_AUTOPORTMAP) { + n->in_ippip = ~ntohl(n->in_inmsk); + if (n->in_outmsk != 0xffffffff) + n->in_ippip /= (~ntohl(n->in_outmsk) + 1); + n->in_ippip++; + if (n->in_ippip == 0) + n->in_ippip = 1; + n->in_ppip = USABLE_PORTS / n->in_ippip; + } else { + n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk); + n->in_nip = 0; + if (!(n->in_ppip = n->in_pmin)) + n->in_ppip = 1; + n->in_ippip = USABLE_PORTS / n->in_ppip; + } +} + + + +ipnat_t *natparse(line, linenum) +char *line; +int linenum; +{ + struct protoent *pr; + static ipnat_t ipn; + char *s, *t; + char *shost, *snetm, *dhost, *proto, *srchost, *srcnetm; + char *dnetm = NULL, *dport = NULL, *tport = NULL; + int resolved; + + srchost = NULL; + srcnetm = NULL; + + bzero((char *)&ipn, sizeof(ipn)); + if ((s = strchr(line, '\n'))) + *s = '\0'; + if ((s = strchr(line, '#'))) + *s = '\0'; + if (!*line) + return NULL; + if (!(s = strtok(line, " \t"))) + return NULL; + if (!strcasecmp(s, "map")) + ipn.in_redir = NAT_MAP; + else if (!strcasecmp(s, "map-block")) + ipn.in_redir = NAT_MAPBLK; + else if (!strcasecmp(s, "rdr")) + ipn.in_redir = NAT_REDIRECT; + else if (!strcasecmp(s, "bimap")) + ipn.in_redir = NAT_BIMAP; + else { + fprintf(stderr, "%d: unknown mapping: \"%s\"\n", + linenum, s); + return NULL; + } + + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, "%d: missing fields (interface)\n", + linenum); + return NULL; + } + + strncpy(ipn.in_ifname, s, sizeof(ipn.in_ifname) - 1); + ipn.in_ifname[sizeof(ipn.in_ifname) - 1] = '\0'; + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, "%d: missing fields (%s)\n", linenum, + ipn.in_redir ? "from source | destination" : "source"); + return NULL; + } + + if ((ipn.in_redir == NAT_REDIRECT) && !strcasecmp(s, "from")) { + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, + "%d: missing fields (source address)\n", + linenum); + return NULL; + } + + srchost = s; + srcnetm = strrchr(srchost, '/'); + + if (srcnetm == NULL) { + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, + "%d: missing fields (source netmask)\n", + linenum); + return NULL; + } + + if (strcasecmp(s, "netmask")) { + fprintf(stderr, + "%d: missing fields (netmask)\n", + linenum); + return NULL; + } + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, + "%d: missing fields (source netmask)\n", + linenum); + return NULL; + } + srcnetm = s; + } + if (*srcnetm == '/') + *srcnetm++ = '\0'; + + /* re read the next word -- destination */ + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, + "%d: missing fields (destination)\n", linenum); + return NULL; + } + + } + + shost = s; + + if (ipn.in_redir == NAT_REDIRECT) { + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, + "%d: missing fields (destination port)\n", + linenum); + return NULL; + } + + if (strcasecmp(s, "port")) { + fprintf(stderr, "%d: missing fields (port)\n", linenum); + return NULL; + } + + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, + "%d: missing fields (destination port)\n", + linenum); + return NULL; + } + + dport = s; + } + + + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, "%d: missing fields (->)\n", linenum); + return NULL; + } + if (!strcmp(s, "->")) { + snetm = strrchr(shost, '/'); + if (!snetm) { + fprintf(stderr, + "%d: missing fields (%s netmask)\n", linenum, + ipn.in_redir ? "destination" : "source"); + return NULL; + } + } else { + if (strcasecmp(s, "netmask")) { + fprintf(stderr, "%d: missing fields (netmask)\n", + linenum); + return NULL; + } + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, + "%d: missing fields (%s netmask)\n", linenum, + ipn.in_redir ? "destination" : "source"); + return NULL; + } + snetm = s; + } + + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, "%d: missing fields (%s)\n", + linenum, ipn.in_redir ? "destination":"target"); + return NULL; + } + + if (ipn.in_redir == NAT_MAP) { + if (!strcasecmp(s, "range")) { + ipn.in_flags |= IPN_RANGE; + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, "%d: missing fields (%s)\n", + linenum, + ipn.in_redir ? "destination":"target"); + return NULL; + } + } + } + dhost = s; + + if (ipn.in_redir & (NAT_MAP|NAT_MAPBLK)) { + if (ipn.in_flags & IPN_RANGE) { + dnetm = strrchr(dhost, '-'); + if (dnetm == NULL) { + if (!(s = strtok(NULL, " \t"))) + dnetm = NULL; + else { + if (strcmp(s, "-")) + s = NULL; + else if ((s = strtok(NULL, " \t"))) { + dnetm = s; + } + } + } else + *dnetm++ = '\0'; + if (dnetm == NULL || *dnetm == '\0') { + fprintf(stderr, + "%d: desination range not specified\n", + linenum); + return NULL; + } + } else { + dnetm = strrchr(dhost, '/'); + if (dnetm == NULL) { + if (!(s = strtok(NULL, " \t"))) + dnetm = NULL; + else if (!strcasecmp(s, "netmask")) + if ((s = strtok(NULL, " \t")) != NULL) + dnetm = s; + } + if (dnetm == NULL) { + fprintf(stderr, + "%d: missing fields (dest netmask)\n", + linenum); + return NULL; + } + if (*dnetm == '/') + *dnetm++ = '\0'; + } + s = strtok(NULL, " \t"); + } + + if (ipn.in_redir & NAT_MAPBLK) { + if (s && strcasecmp(s, "ports")) { + fprintf(stderr, + "%d: expected \"ports\" - got \"%s\"\n", + linenum, s); + return NULL; + } + if (s != NULL) { + if ((s = strtok(NULL, " \t")) == NULL) + return NULL; + ipn.in_pmin = atoi(s); + s = strtok(NULL, " \t"); + } else + ipn.in_pmin = 0; + } else if ((ipn.in_redir & NAT_BIMAP) == NAT_REDIRECT) { + if (strrchr(dhost, '/') != NULL) { + fprintf(stderr, "%d: No netmask supported in %s\n", + linenum, "destination host for redirect"); + return NULL; + } + /* If it's a in_redir, expect target port */ + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, + "%d: missing fields (destination port)\n", + linenum); + return NULL; + } + + if (strcasecmp(s, "port")) { + fprintf(stderr, "%d: missing fields (port)\n", + linenum); + return NULL; + } + + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, + "%d: missing fields (destination port)\n", + linenum); + return NULL; + } + tport = s; + } + if (dnetm && *dnetm == '/') + *dnetm++ = '\0'; + if (snetm && *snetm == '/') + *snetm++ = '\0'; + + if (ipn.in_redir & (NAT_MAP|NAT_MAPBLK)) { + ipn.in_inip = hostnum(shost, &resolved, linenum); + if (resolved == -1) + return NULL; + ipn.in_inmsk = n_hostmask(snetm); + ipn.in_outip = hostnum(dhost, &resolved, linenum); + if (resolved == -1) + return NULL; + if (ipn.in_flags & IPN_RANGE) { + ipn.in_outmsk = hostnum(dnetm, &resolved, linenum); + if (resolved == -1) + return NULL; + } else + ipn.in_outmsk = n_hostmask(dnetm); + if (srchost) { + ipn.in_srcip = hostnum(srchost, &resolved, linenum); + if (resolved == -1) + return NULL; + } + if (srcnetm) + ipn.in_srcmsk = n_hostmask(srcnetm); + } else { + if (srchost) { + ipn.in_srcip = hostnum(srchost, &resolved, linenum); + if (resolved == -1) + return NULL; + } + if (srcnetm) + ipn.in_srcmsk = n_hostmask(srcnetm); + ipn.in_inip = hostnum(dhost, &resolved, linenum); + if (resolved == -1) + return NULL; + ipn.in_inmsk = n_hostmask("255.255.255.255"); + ipn.in_outip = hostnum(shost, &resolved, linenum); + if (resolved == -1) + return NULL; + ipn.in_outmsk = n_hostmask(snetm); + if (!(s = strtok(NULL, " \t"))) { + ipn.in_flags = IPN_TCP; /* XXX- TCP only by default */ + proto = "tcp"; + } else { + if (!strcasecmp(s, "tcp")) + ipn.in_flags = IPN_TCP; + else if (!strcasecmp(s, "udp")) + ipn.in_flags = IPN_UDP; + else if (!strcasecmp(s, "tcp/udp")) + ipn.in_flags = IPN_TCPUDP; + else if (!strcasecmp(s, "tcpudp")) + ipn.in_flags = IPN_TCPUDP; + else if (!strcasecmp(s, "ip")) + ipn.in_flags = IPN_ANY; + else { + ipn.in_flags = IPN_ANY; + if ((pr = getprotobyname(s))) + ipn.in_p = pr->p_proto; + else + ipn.in_p = atoi(s); + } + proto = s; + if ((s = strtok(NULL, " \t"))) { + fprintf(stderr, + "%d: extra junk at the end of rdr: %s\n", + linenum, s); + return NULL; + } + } + ipn.in_pmin = n_portnum(dport, proto, linenum); + ipn.in_pmax = ipn.in_pmin; + ipn.in_pnext = n_portnum(tport, proto, linenum); + s = NULL; + } + ipn.in_inip &= ipn.in_inmsk; + if ((ipn.in_flags & IPN_RANGE) == 0) + ipn.in_outip &= ipn.in_outmsk; + ipn.in_srcip &= ipn.in_srcmsk; + + if ((ipn.in_redir & NAT_MAPBLK) != 0) + nat_setgroupmap(&ipn); + + if (!s) + return &ipn; + + if (ipn.in_redir == NAT_BIMAP) { + fprintf(stderr, + "%d: extra words at the end of bimap line: %s\n", + linenum, s); + return NULL; + } + if (!strcasecmp(s, "proxy")) { + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, + "%d: missing parameter for \"proxy\"\n", + linenum); + return NULL; + } + dport = NULL; + + if (!strcasecmp(s, "port")) { + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, + "%d: missing parameter for \"port\"\n", + linenum); + return NULL; + } + + dport = s; + + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, + "%d: missing parameter for \"proxy\"\n", + linenum); + return NULL; + } + } else { + fprintf(stderr, + "%d: missing keyword \"port\"\n", linenum); + return NULL; + } + if ((proto = index(s, '/'))) { + *proto++ = '\0'; + if ((pr = getprotobyname(proto))) + ipn.in_p = pr->p_proto; + else + ipn.in_p = atoi(proto); + if (dport) + ipn.in_dport = n_portnum(dport, proto, linenum); + } else { + ipn.in_p = 0; + if (dport) + ipn.in_dport = n_portnum(dport, NULL, linenum); + } + + (void) strncpy(ipn.in_plabel, s, sizeof(ipn.in_plabel)); + if ((s = strtok(NULL, " \t"))) { + fprintf(stderr, + "%d: too many parameters for \"proxy\"\n", + linenum); + return NULL; + } + return &ipn; + + } + + if (strcasecmp(s, "portmap")) { + fprintf(stderr, + "%d: expected \"portmap\" - got \"%s\"\n", linenum, s); + return NULL; + } + if (!(s = strtok(NULL, " \t"))) + return NULL; + if (!strcasecmp(s, "tcp")) + ipn.in_flags = IPN_TCP; + else if (!strcasecmp(s, "udp")) + ipn.in_flags = IPN_UDP; + else if (!strcasecmp(s, "tcpudp")) + ipn.in_flags = IPN_TCPUDP; + else if (!strcasecmp(s, "tcp/udp")) + ipn.in_flags = IPN_TCPUDP; + else { + fprintf(stderr, + "%d: expected protocol name - got \"%s\"\n", + linenum, s); + return NULL; + } + + if (!(s = strtok(NULL, " \t"))) { + fprintf(stderr, "%d: no port range found\n", linenum); + return NULL; + } + + if (!strcasecmp(s, "auto")) { + ipn.in_flags |= IPN_AUTOPORTMAP; + ipn.in_pmin = htons(1024); + ipn.in_pmax = htons(65535); + nat_setgroupmap(&ipn); + return &ipn; + } + proto = s; + if (!(t = strchr(s, ':'))) { + fprintf(stderr, "%d: no port range in \"%s\"\n", linenum, s); + return NULL; + } + *t++ = '\0'; + ipn.in_pmin = n_portnum(s, proto, linenum); + ipn.in_pmax = n_portnum(t, proto, linenum); + return &ipn; +} + + +void natparsefile(fd, file, opts) +int fd; +char *file; +int opts; +{ + char line[512], *s; + ipnat_t *np; + FILE *fp; + int linenum = 0; + + if (strcmp(file, "-")) { + if (!(fp = fopen(file, "r"))) { + fprintf(stderr, "%s: open: %s\n", file, + STRERROR(errno)); + exit(1); + } + } else + fp = stdin; + + while (fgets(line, sizeof(line) - 1, fp)) { + linenum++; + line[sizeof(line) - 1] = '\0'; + if ((s = strchr(line, '\n'))) + *s = '\0'; + + if (!(np = natparse(line, linenum))) { + if (*line) + fprintf(stderr, "%d: syntax error in \"%s\"\n", + linenum, line); + } else { + if ((opts & OPT_VERBOSE) && np) + printnat(np, opts & OPT_VERBOSE, NULL); + if (!(opts & OPT_NODO)) { + if (!(opts & OPT_REM)) { + if (ioctl(fd, SIOCADNAT, np) == -1) + perror("ioctl(SIOCADNAT)"); + } else if (ioctl(fd, SIOCRMNAT, np) == -1) + perror("ioctl(SIOCRMNAT)"); + } + } + } + if (fp != stdin) + fclose(fp); +} + + +u_32_t n_hostmask(msk) +char *msk; +{ + int bits = -1; + u_32_t mask; + + if (!isdigit(*msk)) + return (u_32_t)-1; + if (strchr(msk, '.')) + return inet_addr(msk); + if (strchr(msk, 'x')) + return (u_32_t)strtol(msk, NULL, 0); + /* + * set x most significant bits + */ + for (mask = 0, bits = atoi(msk); bits; bits--) { + mask /= 2; + mask |= ntohl(inet_addr("128.0.0.0")); + } + mask = htonl(mask); + return mask; +} + + +u_short n_portnum(name, proto, linenum) +char *name, *proto; +int linenum; +{ + struct servent *sp, *sp2; + u_short p1 = 0; + + if (isdigit(*name)) + return htons((u_short)atoi(name)); + if (!proto) + proto = "tcp/udp"; + if (strcasecmp(proto, "tcp/udp")) { + sp = getservbyname(name, proto); + if (sp) + return sp->s_port; + fprintf(stderr, "%d: unknown service \"%s\".\n", linenum, name); + return 0; + } + sp = getservbyname(name, "tcp"); + if (sp) + p1 = sp->s_port; + sp2 = getservbyname(name, "udp"); + if (!sp || !sp2) { + fprintf(stderr, "%d: unknown tcp/udp service \"%s\".\n", + linenum, name); + return 0; + } + if (p1 != sp2->s_port) { + fprintf(stderr, "%d: %s %d/tcp is a different port to ", + linenum, name, p1); + fprintf(stderr, "%d: %s %d/udp\n", linenum, name, sp->s_port); + return 0; + } + return p1; +} diff --git a/sys/netinet/ip_raudio_pxy.c b/sys/netinet/ip_raudio_pxy.c new file mode 100644 index 00000000000..9cbff3fc059 --- /dev/null +++ b/sys/netinet/ip_raudio_pxy.c @@ -0,0 +1,294 @@ +/* $OpenBSD: ip_raudio_pxy.c,v 1.1 1999/12/14 04:17:17 kjell Exp $ */ +#if SOLARIS && defined(_KERNEL) +extern kmutex_t ipf_rw; +#endif + +#define IPF_RAUDIO_PROXY + + +int ippr_raudio_init __P((void)); +int ippr_raudio_new __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *)); +int ippr_raudio_in __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *)); +int ippr_raudio_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *)); + +static frentry_t raudiofr; + + +/* + * Real Audio application proxy initialization. + */ +int ippr_raudio_init() +{ + bzero((char *)&raudiofr, sizeof(raudiofr)); + raudiofr.fr_ref = 1; + raudiofr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; + return 0; +} + + +/* + * Setup for a new proxy to handle Real Audio. + */ +int ippr_raudio_new(fin, ip, aps, nat) +fr_info_t *fin; +ip_t *ip; +ap_session_t *aps; +nat_t *nat; +{ + raudio_t *rap; + + + KMALLOCS(aps->aps_data, void *, sizeof(raudio_t)); + if (aps->aps_data != NULL) { + bzero(aps->aps_data, sizeof(raudio_t)); + rap = aps->aps_data; + aps->aps_psiz = sizeof(raudio_t); + rap->rap_mode = RAP_M_TCP; /* default is for TCP */ + } + return 0; +} + + + +int ippr_raudio_out(fin, ip, aps, nat) +fr_info_t *fin; +ip_t *ip; +ap_session_t *aps; +nat_t *nat; +{ + raudio_t *rap = aps->aps_data; + char membuf[512 + 1], *s; + u_short id = 0; + tcphdr_t *tcp; + int off, dlen; + int len = 0; + mb_t *m; +#if SOLARIS + mb_t *m1; +#endif + + /* + * If we've already processed the start messages, then nothing left + * for the proxy to do. + */ + if (rap->rap_eos == 1) + return 0; + + tcp = (tcphdr_t *)fin->fin_dp; + off = (ip->ip_hl << 2) + (tcp->th_off << 2); + bzero(membuf, sizeof(membuf)); +#if SOLARIS + m = fin->fin_qfm; + + dlen = msgdsize(m) - off; + if (dlen <= 0) + return 0; + copyout_mblk(m, off, MIN(sizeof(membuf), dlen), membuf); +#else + m = *(mb_t **)fin->fin_mp; + + dlen = mbufchainlen(m) - off; + if (dlen <= 0) + return 0; + m_copydata(m, off, MIN(sizeof(membuf), dlen), membuf); +#endif + /* + * In all the startup parsing, ensure that we don't go outside + * the packet buffer boundary. + */ + /* + * Look for the start of connection "PNA" string if not seen yet. + */ + if (rap->rap_seenpna == 0) { + s = memstr("PNA", membuf, 3, dlen); + if (s == NULL) + return 0; + s += 3; + rap->rap_seenpna = 1; + } else + s = membuf; + + /* + * Directly after the PNA will be the version number of this + * connection. + */ + if (rap->rap_seenpna == 1 && rap->rap_seenver == 0) { + if ((s + 1) - membuf < dlen) { + rap->rap_version = (*s << 8) | *(s + 1); + s += 2; + rap->rap_seenver = 1; + } else + return 0; + } + + /* + * Now that we've been past the PNA and version number, we're into the + * startup messages block. This ends when a message with an ID of 0. + */ + while ((rap->rap_eos == 0) && ((s + 1) - membuf < dlen)) { + if (rap->rap_gotid == 0) { + id = (*s << 8) | *(s + 1); + s += 2; + rap->rap_gotid = 1; + if (id == RA_ID_END) { + rap->rap_eos = 1; + break; + } + } else if (rap->rap_gotlen == 0) { + len = (*s << 8) | *(s + 1); + s += 2; + rap->rap_gotlen = 1; + } + + if (rap->rap_gotid == 1 && rap->rap_gotlen == 1) { + if (id == RA_ID_UDP) { + rap->rap_mode &= ~RAP_M_TCP; + rap->rap_mode |= RAP_M_UDP; + rap->rap_plport = (*s << 8) | *(s + 1); + } else if (id == RA_ID_ROBUST) { + rap->rap_mode |= RAP_M_ROBUST; + rap->rap_prport = (*s << 8) | *(s + 1); + } + s += len; + rap->rap_gotlen = 0; + rap->rap_gotid = 0; + } + } + return 0; +} + + +int ippr_raudio_in(fin, ip, aps, nat) +fr_info_t *fin; +ip_t *ip; +ap_session_t *aps; +nat_t *nat; +{ + char membuf[IPF_MAXPORTLEN + 1], *s; + tcphdr_t *tcp, tcph, *tcp2 = &tcph; + raudio_t *rap = aps->aps_data; + struct in_addr swa, swb; + u_int a1, a2, a3, a4; + u_short sp, dp; + int off, dlen; + fr_info_t fi; + tcp_seq seq; + nat_t *ipn; + u_char swp; + mb_t *m; +#if SOLARIS + mb_t *m1; +#endif + + /* + * Wait until we've seen the end of the start messages and even then + * only proceed further if we're using UDP. If they want to use TCP + * then data is sent back on the same channel that is already open. + */ + if (rap->rap_sdone != 0) + return 0; + + tcp = (tcphdr_t *)fin->fin_dp; + off = (ip->ip_hl << 2) + (tcp->th_off << 2); + m = *(mb_t **)fin->fin_mp; + +#if SOLARIS + m = fin->fin_qfm; + + dlen = msgdsize(m) - off; + if (dlen <= 0) + return 0; + bzero(membuf, sizeof(membuf)); + copyout_mblk(m, off, MIN(sizeof(membuf), dlen), membuf); +#else + dlen = mbufchainlen(m) - off; + if (dlen <= 0) + return 0; + bzero(membuf, sizeof(membuf)); + m_copydata(m, off, MIN(sizeof(membuf), dlen), membuf); +#endif + + seq = ntohl(tcp->th_seq); + /* + * Check to see if the data in this packet is of interest to us. + * We only care for the first 19 bytes coming back from the server. + */ + if (rap->rap_sseq == 0) { + s = memstr("PNA", membuf, 3, dlen); + if (s == NULL) + return 0; + a1 = s - membuf; + dlen -= a1; + a1 = 0; + rap->rap_sseq = seq; + a2 = MIN(dlen, sizeof(rap->rap_svr)); + } else if (seq <= rap->rap_sseq + sizeof(rap->rap_svr)) { + /* + * seq # which is the start of data and from that the offset + * into the buffer array. + */ + a1 = seq - rap->rap_sseq; + a2 = MIN(dlen, sizeof(rap->rap_svr)); + a2 -= a1; + s = membuf; + } else + return 0; + + for (a3 = a1, a4 = a2; a4 > 0; a4--, a3++) { + rap->rap_sbf |= (1 << a3); + rap->rap_svr[a3] = *s++; + } + + if ((rap->rap_sbf != 0x7ffff) || (!rap->rap_eos)) /* 19 bits */ + return 0; + rap->rap_sdone = 1; + + s = rap->rap_svr + 13; + rap->rap_srport = (*s << 8) | *(s + 1); + swp = ip->ip_p; + swa = ip->ip_src; + swb = ip->ip_dst; + ip->ip_p = IPPROTO_UDP; + bcopy((char *)fin, (char *)&fi, sizeof(fi)); + bzero((char *)tcp2, sizeof(*tcp2)); + fi.fin_dp = (char *)tcp2; + fi.fin_fr = &raudiofr; + tcp2->th_win = htons(8192); + + if ((rap->rap_mode & RAP_M_UDP_ROBUST) == RAP_M_UDP_ROBUST) { + ip->ip_src = nat->nat_inip; + ip->ip_dst = nat->nat_oip; + sp = rap->rap_srport; + dp = rap->rap_prport; + tcp2->th_sport = htons(dp); + tcp2->th_dport = htons(sp); + fi.fin_data[0] = dp; + fi.fin_data[1] = sp; + ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_UDP, NAT_OUTBOUND); + if (ipn != NULL) { + ipn->nat_age = fr_defnatage; + (void) fr_addstate(ip, &fi, 0); + } + ip->ip_src = swa; + ip->ip_dst = swb; + } + + sp = rap->rap_plport; + + tcp2->th_sport = htons(sp); + tcp2->th_dport = 0; /* XXX - don't specify remote port */ + fi.fin_data[0] = sp; + fi.fin_data[1] = 0; + ip->ip_src = nat->nat_inip; + ip->ip_src = nat->nat_oip; + ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_UDP|FI_W_DPORT, NAT_OUTBOUND); + if (ipn != NULL) { + ipn->nat_age = fr_defnatage; + (void) fr_addstate(ip, &fi, FI_W_DPORT); + } + + ip->ip_p = swp; + ip->ip_src = swa; + ip->ip_dst = swb; + return 0; +} diff --git a/sys/netinet/ip_rcmd_pxy.c b/sys/netinet/ip_rcmd_pxy.c new file mode 100644 index 00000000000..5782e9f3400 --- /dev/null +++ b/sys/netinet/ip_rcmd_pxy.c @@ -0,0 +1,157 @@ +/* $OpenBSD: ip_rcmd_pxy.c,v 1.1 1999/12/14 04:17:17 kjell Exp $ */ +/* + * Simple RCMD transparent proxy for in-kernel use. For use with the NAT + * code. + */ +#if SOLARIS && defined(_KERNEL) +extern kmutex_t ipf_rw; +#endif + +#define isdigit(x) ((x) >= '0' && (x) <= '9') + +#define IPF_RCMD_PROXY + + +int ippr_rcmd_init __P((void)); +int ippr_rcmd_new __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *)); +int ippr_rcmd_out __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *)); +u_short ipf_rcmd_atoi __P((char *)); +int ippr_rcmd_portmsg __P((fr_info_t *, ip_t *, ap_session_t *, nat_t *)); + +static frentry_t rcmdfr; + + +/* + * RCMD application proxy initialization. + */ +int ippr_rcmd_init() +{ + bzero((char *)&rcmdfr, sizeof(rcmdfr)); + rcmdfr.fr_ref = 1; + rcmdfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; + return 0; +} + + +/* + * Setup for a new RCMD proxy. + */ +int ippr_rcmd_new(fin, ip, aps, nat) +fr_info_t *fin; +ip_t *ip; +ap_session_t *aps; +nat_t *nat; +{ + tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp; + + aps->aps_psiz = sizeof(u_32_t); + KMALLOCS(aps->aps_data, u_32_t *, sizeof(u_32_t)); + if (aps->aps_data == NULL) + return -1; + *(u_32_t *)aps->aps_data = 0; + aps->aps_sport = tcp->th_sport; + aps->aps_dport = tcp->th_dport; + return 0; +} + + +/* + * ipf_rcmd_atoi - implement a simple version of atoi + */ +u_short ipf_rcmd_atoi(ptr) +char *ptr; +{ + register char *s = ptr, c; + register u_short i = 0; + + while ((c = *s++) && isdigit(c)) { + i *= 10; + i += c - '0'; + } + return i; +} + + +int ippr_rcmd_portmsg(fin, ip, aps, nat) +fr_info_t *fin; +ip_t *ip; +ap_session_t *aps; +nat_t *nat; +{ + char portbuf[8], *s; + struct in_addr swip; + u_short sp, dp; + int off, dlen; + tcphdr_t *tcp, tcph, *tcp2 = &tcph; + fr_info_t fi; + nat_t *ipn; + mb_t *m; +#if SOLARIS + mb_t *m1; +#endif + + tcp = (tcphdr_t *)fin->fin_dp; + off = (ip->ip_hl << 2) + (tcp->th_off << 2); + m = *(mb_t **)fin->fin_mp; + +#if SOLARIS + m = fin->fin_qfm; + + dlen = msgdsize(m) - off; + bzero(portbuf, sizeof(portbuf)); + copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf); +#else + dlen = mbufchainlen(m) - off; + bzero(portbuf, sizeof(portbuf)); + m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf); +#endif + if ((*(u_32_t *)aps->aps_data != 0) && + (tcp->th_seq != *(u_32_t *)aps->aps_data)) + return 0; + + portbuf[sizeof(portbuf) - 1] = '\0'; + s = portbuf; + sp = ipf_rcmd_atoi(s); + if (!sp) + return 0; + + /* + * Add skeleton NAT entry for connection which will come back the + * other way. + */ + sp = htons(sp); + dp = htons(fin->fin_data[1]); + ipn = nat_outlookup(fin->fin_ifp, IPN_TCP, nat->nat_p, nat->nat_inip, + ip->ip_dst, (dp << 16) | sp); + if (ipn == NULL) { + bcopy((char *)fin, (char *)&fi, sizeof(fi)); + bzero((char *)tcp2, sizeof(*tcp2)); + tcp2->th_win = htons(8192); + tcp2->th_sport = sp; + tcp2->th_dport = 0; /* XXX - don't specify remote port */ + fi.fin_data[0] = ntohs(sp); + fi.fin_data[1] = 0; + fi.fin_dp = (char *)tcp2; + swip = ip->ip_src; + ip->ip_src = nat->nat_inip; + ipn = nat_new(nat->nat_ptr, ip, &fi, IPN_TCP|FI_W_DPORT, + NAT_OUTBOUND); + if (ipn != NULL) { + ipn->nat_age = fr_defnatage; + fi.fin_fr = &rcmdfr; + (void) fr_addstate(ip, &fi, FI_W_DPORT); + } + ip->ip_src = swip; + } + return 0; +} + + +int ippr_rcmd_out(fin, ip, aps, nat) +fr_info_t *fin; +ip_t *ip; +ap_session_t *aps; +nat_t *nat; +{ + return ippr_rcmd_portmsg(fin, ip, aps, nat); +} diff --git a/sys/netinet/ipl.h b/sys/netinet/ipl.h new file mode 100644 index 00000000000..9ebb6abc239 --- /dev/null +++ b/sys/netinet/ipl.h @@ -0,0 +1,17 @@ +/* $OpenBSD: ipl.h,v 1.1 1999/12/14 04:17:17 kjell Exp $ */ +/* + * Copyright (C) 1993-1999 by Darren Reed. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and due credit is given + * to the original author and the contributors. + * + * @(#)ipl.h 1.21 6/5/96 + */ + +#ifndef __IPL_H__ +#define __IPL_H__ + +#define IPL_VERSION "IP Filter: v3.3.4" + +#endif |