diff options
author | glebius <glebius@FreeBSD.org> | 2005-05-05 22:00:32 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2005-05-05 22:00:32 +0000 |
commit | 225ea2fb026651e6888d032de9ae92ac79d4cb10 (patch) | |
tree | 95f2ca25aae9d0285d54a645661fd64af5ee8dd0 | |
parent | 32b37f4983e41f5e01c3f8d4855f21bc38733229 (diff) | |
download | FreeBSD-src-225ea2fb026651e6888d032de9ae92ac79d4cb10.zip FreeBSD-src-225ea2fb026651e6888d032de9ae92ac79d4cb10.tar.gz |
More bits for kernel version:
- copy inet_aton() from libc
- disable getservbyname() lookup and accept only numeric port
-rw-r--r-- | sys/netinet/libalias/alias_proxy.c | 108 |
1 files changed, 107 insertions, 1 deletions
diff --git a/sys/netinet/libalias/alias_proxy.c b/sys/netinet/libalias/alias_proxy.c index f090157..3450349 100644 --- a/sys/netinet/libalias/alias_proxy.c +++ b/sys/netinet/libalias/alias_proxy.c @@ -143,6 +143,9 @@ struct proxy_entry { destination of a proxied IP packet */ +#ifdef _KERNEL /* XXX: can it be moved to libkern? */ +static int inet_aton(const char *cp, struct in_addr *addr); +#endif static int IpMask(int, struct in_addr *); static int IpAddr(char *, struct in_addr *); static int IpPort(char *, int, int *); @@ -152,6 +155,104 @@ static int RuleNumberDelete(struct libalias *la, int); static void ProxyEncodeTcpStream(struct alias_link *, struct ip *, int); static void ProxyEncodeIpHeader(struct ip *, int); +#ifdef _KERNEL +static int +inet_aton(cp, addr) + const char *cp; + struct in_addr *addr; +{ + u_long parts[4]; + in_addr_t val; + const char *c; + char *endptr; + int gotend, n; + + c = (const char *)cp; + n = 0; + /* + * Run through the string, grabbing numbers until + * the end of the string, or some error + */ + gotend = 0; + while (!gotend) { + val = strtoul(c, &endptr, 0); + + if (val == ULONG_MAX || val == 0) + return (0); + + /* + * If the whole string is invalid, endptr will equal + * c.. this way we can make sure someone hasn't + * gone '.12' or something which would get past + * the next check. + */ + if (endptr == c) + return (0); + parts[n] = val; + c = endptr; + + /* Check the next character past the previous number's end */ + switch (*c) { + case '.' : + /* Make sure we only do 3 dots .. */ + if (n == 3) /* Whoops. Quit. */ + return (0); + n++; + c++; + break; + + case '\0': + gotend = 1; + break; + + default: + if (isspace((unsigned char)*c)) { + gotend = 1; + break; + } else + return (0); /* Invalid character, so fail */ + } + + } + + /* + * Concoct the address according to + * the number of parts specified. + */ + + switch (n) { + case 0: /* a -- 32 bits */ + /* + * Nothing is necessary here. Overflow checking was + * already done in strtoul(). + */ + break; + case 1: /* a.b -- 8.24 bits */ + if (val > 0xffffff || parts[0] > 0xff) + return (0); + val |= parts[0] << 24; + break; + + case 2: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff || parts[0] > 0xff || parts[1] > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 3: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff || parts[0] > 0xff || parts[1] > 0xff || + parts[2] > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + + if (addr != NULL) + addr->s_addr = htonl(val); + return (1); +} +#endif + static int IpMask(int nbits, struct in_addr *mask) { @@ -184,7 +285,9 @@ IpPort(char *s, int proto, int *port) int n; n = sscanf(s, "%d", port); - if (n != 1) { + if (n != 1) +#ifndef _KERNEL /* XXX: we accept only numeric ports in kernel */ + { struct servent *se; if (proto == IPPROTO_TCP) @@ -199,6 +302,9 @@ IpPort(char *s, int proto, int *port) *port = (u_int) ntohs(se->s_port); } +#else + return (-1); +#endif return (0); } |