diff options
author | brian <brian@cvs.openbsd.org> | 1999-03-08 01:40:24 +0000 |
---|---|---|
committer | brian <brian@cvs.openbsd.org> | 1999-03-08 01:40:24 +0000 |
commit | 514916901d81186acd389b2eb81ddeff211f0b03 (patch) | |
tree | 364f2eb7e436323265748dc31a271a79cbad687d | |
parent | c3d2496b1d90b8d38fbd08d667ceb52f4d41c5cd (diff) |
Add proxying & transparent proxying support (``alias proxy'').
Add PPTP packet aliasing (GRE fixed address) support (``alias pptp'').
Add a 0 to the front of the mode to signify octal.
Thanks to: Charles Mott <cmott@srv.net> & Dru Nelson <dnelson@redwoodsoft.com>
-rw-r--r-- | usr.sbin/ppp/ppp/Makefile | 16 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/alias.c | 259 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/alias.h | 39 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/alias_cmd.c | 49 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/alias_cmd.h | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/alias_db.c | 107 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/alias_local.h | 75 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/alias_nbt.c | 215 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/alias_proxy.c | 801 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/command.c | 8 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ppp.8 | 71 |
11 files changed, 1475 insertions, 169 deletions
diff --git a/usr.sbin/ppp/ppp/Makefile b/usr.sbin/ppp/ppp/Makefile index 042db528042..d75560c297e 100644 --- a/usr.sbin/ppp/ppp/Makefile +++ b/usr.sbin/ppp/ppp/Makefile @@ -1,13 +1,14 @@ -# $Id: Makefile,v 1.6 1999/02/06 03:22:30 brian Exp $ +# $Id: Makefile,v 1.7 1999/03/08 01:40:21 brian Exp $ PROG= ppp SRCS= alias.c alias_cmd.c alias_cuseeme.c alias_db.c alias_ftp.c \ - alias_irc.c alias_nbt.c alias_util.c arp.c async.c auth.c bundle.c \ - cbcp.c ccp.c chap.c chap_ms.c chat.c command.c datalink.c deflate.c \ - defs.c filter.c fsm.c hdlc.c id.c iface.c ip.c ipcp.c iplist.c lcp.c \ - link.c log.c lqr.c main.c mbuf.c modem.c mp.c pap.c physical.c pred.c \ - probe.c prompt.c radius.c radlib.c route.c server.c sig.c slcompress.c \ - systems.c throughput.c timer.c tun.c vjcomp.c + alias_irc.c alias_nbt.c alias_proxy.c alias_util.c arp.c async.c \ + auth.c bundle.c cbcp.c ccp.c chap.c chap_ms.c chat.c command.c \ + datalink.c deflate.c defs.c filter.c fsm.c hdlc.c id.c iface.c ip.c \ + ipcp.c iplist.c lcp.c link.c log.c lqr.c main.c mbuf.c modem.c mp.c \ + pap.c physical.c pred.c probe.c prompt.c radius.c radlib.c route.c \ + server.c sig.c slcompress.c systems.c throughput.c timer.c tun.c \ + vjcomp.c CFLAGS+=-Wall -DHAVE_DES -DNO_FW_PUNCH LDADD+= -ldes -lutil -lz DPADD+= ${LIBDES} ${LIBUTIL} ${LIBZ} @@ -16,5 +17,4 @@ BINOWN= root BINGRP= network MAN= ppp.8 - .include <bsd.prog.mk> diff --git a/usr.sbin/ppp/ppp/alias.c b/usr.sbin/ppp/ppp/alias.c index 48a852a250f..13d972c6ff8 100644 --- a/usr.sbin/ppp/ppp/alias.c +++ b/usr.sbin/ppp/ppp/alias.c @@ -73,6 +73,9 @@ - Eliminated PacketAliasIn2() and PacketAliasOut2() as poorly conceived. + Version 2.3 Dec 1998 (dillon) + - Major bounds checking additions, see FreeBSD/CVS + See HISTORY file for additional revisions. */ @@ -90,6 +93,10 @@ #include <netinet/tcp.h> #include <netinet/udp.h> +#ifndef IPPROTO_GRE +#define IPPROTO_GRE 47 +#endif + #include "alias_local.h" #include "alias.h" @@ -101,38 +108,13 @@ #define IRC_CONTROL_PORT_NUMBER_2 6668 #define CUSEEME_PORT_NUMBER 7648 -/* - The following macro is used to update an - internet checksum. "delta" is a 32-bit - accumulation of all the changes to the - checksum (adding in new 16-bit words and - subtracting out old words), and "cksum" - is the checksum value to be updated. -*/ -#define ADJUST_CHECKSUM(acc, cksum) { \ - acc += cksum; \ - if (acc < 0) \ - { \ - acc = -acc; \ - acc = (acc >> 16) + (acc & 0xffff); \ - acc += acc >> 16; \ - cksum = (u_short) ~acc; \ - } \ - else \ - { \ - acc = (acc >> 16) + (acc & 0xffff); \ - acc += acc >> 16; \ - cksum = (u_short) acc; \ - } \ -} - /* TCP Handling Routines TcpMonitorIn() -- These routines monitor TCP connections, and - TcpMonitorOut() -- delete a link node when a connection is closed. + TcpMonitorOut() delete a link when a connection is closed. These routines look for SYN, ACK and RST flags to determine when TCP connections open and close. When a TCP connection closes, the data @@ -403,7 +385,6 @@ fragment contained in ICMP data section */ return(PKT_ALIAS_IGNORED); } - static int IcmpAliasIn3(struct ip *pip) { @@ -426,6 +407,10 @@ IcmpAliasIn(struct ip *pip) int iresult; struct icmp *ic; +/* Return if proxy-only mode is enabled */ + if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) + return PKT_ALIAS_OK; + ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); iresult = PKT_ALIAS_IGNORED; @@ -560,6 +545,10 @@ IcmpAliasOut(struct ip *pip) int iresult; struct icmp *ic; +/* Return if proxy-only mode is enabled */ + if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) + return PKT_ALIAS_OK; + ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2)); iresult = PKT_ALIAS_IGNORED; @@ -585,12 +574,73 @@ IcmpAliasOut(struct ip *pip) return(iresult); } + + +static int +PptpAliasIn(struct ip *pip) +{ +/* + Handle incoming PPTP packets. The + only thing which is done in this case is to alias + the dest IP address of the packet to our inside + machine. +*/ + struct in_addr alias_addr; + + if (!GetPptpAlias (&alias_addr)) + return PKT_ALIAS_IGNORED; + + if (pip->ip_src.s_addr != alias_addr.s_addr) { + + DifferentialChecksum(&pip->ip_sum, + (u_short *) &alias_addr, + (u_short *) &pip->ip_dst, + 2); + pip->ip_dst = alias_addr; + } + + return PKT_ALIAS_OK; +} + + +static int +PptpAliasOut(struct ip *pip) +{ +/* + Handle outgoing PPTP packets. The + only thing which is done in this case is to alias + the source IP address of the packet. +*/ + struct in_addr alias_addr; + + if (!GetPptpAlias (&alias_addr)) + return PKT_ALIAS_IGNORED; + + if (pip->ip_src.s_addr == alias_addr.s_addr) { + + alias_addr = FindAliasAddress(pip->ip_src); + DifferentialChecksum(&pip->ip_sum, + (u_short *) &alias_addr, + (u_short *) &pip->ip_src, + 2); + pip->ip_src = alias_addr; + } + + return PKT_ALIAS_OK; +} + + + static int UdpAliasIn(struct ip *pip) { struct udphdr *ud; struct alias_link *link; +/* Return if proxy-only mode is enabled */ + if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) + return PKT_ALIAS_OK; + ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); link = FindUdpTcpIn(pip->ip_src, pip->ip_dst, @@ -603,6 +653,7 @@ UdpAliasIn(struct ip *pip) u_short alias_port; int accumulate; u_short *sptr; + int r = 0; alias_address = GetAliasAddress(link); original_address = GetOriginalAddress(link); @@ -613,11 +664,11 @@ UdpAliasIn(struct ip *pip) if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER ) { - AliasHandleUdpNbt(pip, link, &original_address, ud->uh_dport); + r = AliasHandleUdpNbt(pip, link, &original_address, ud->uh_dport); } else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER ) { - AliasHandleUdpNbtNS(pip, link, + r = AliasHandleUdpNbtNS(pip, link, &alias_address, &alias_port, &original_address, @@ -648,7 +699,14 @@ UdpAliasIn(struct ip *pip) (u_short *) &pip->ip_dst, 2); pip->ip_dst = original_address; - return(PKT_ALIAS_OK); + + /* + * If we cannot figure out the packet, ignore it. + */ + if (r < 0) + return(PKT_ALIAS_IGNORED); + else + return(PKT_ALIAS_OK); } return(PKT_ALIAS_IGNORED); } @@ -659,6 +717,10 @@ UdpAliasOut(struct ip *pip) struct udphdr *ud; struct alias_link *link; +/* Return if proxy-only mode is enabled */ + if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) + return PKT_ALIAS_OK; + ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); link = FindUdpTcpOut(pip->ip_src, pip->ip_dst, @@ -740,14 +802,18 @@ TcpAliasIn(struct ip *pip) { struct in_addr alias_address; struct in_addr original_address; + struct in_addr proxy_address; u_short alias_port; + u_short proxy_port; int accumulate; u_short *sptr; alias_address = GetAliasAddress(link); original_address = GetOriginalAddress(link); + proxy_address = GetProxyAddress(link); alias_port = tc->th_dport; tc->th_dport = GetOriginalPort(link); + proxy_port = GetProxyPort(link); /* Adjust TCP checksum since destination port is being unaliased */ /* and destination port is being altered. */ @@ -760,6 +826,22 @@ TcpAliasIn(struct ip *pip) accumulate -= *sptr++; accumulate -= *sptr; +/* If this is a proxy, then modify the tcp source port and + checksum accumulation */ + if (proxy_port != 0) + { + accumulate += tc->th_sport; + tc->th_sport = proxy_port; + accumulate -= tc->th_sport; + + sptr = (u_short *) &pip->ip_src; + accumulate += *sptr++; + accumulate += *sptr; + sptr = (u_short *) &proxy_address; + accumulate -= *sptr++; + accumulate -= *sptr; + } + /* See if ack number needs to be modified */ if (GetAckModified(link) == 1) { @@ -781,11 +863,28 @@ TcpAliasIn(struct ip *pip) ADJUST_CHECKSUM(accumulate, tc->th_sum); /* Restore original IP address */ - DifferentialChecksum(&pip->ip_sum, - (u_short *) &original_address, - (u_short *) &pip->ip_dst, - 2); + sptr = (u_short *) &pip->ip_dst; + accumulate = *sptr++; + accumulate += *sptr; pip->ip_dst = original_address; + sptr = (u_short *) &pip->ip_dst; + accumulate -= *sptr++; + accumulate -= *sptr; + +/* If this is a transparent proxy packet, then modify the source + address */ + if (proxy_address.s_addr != 0) + { + sptr = (u_short *) &pip->ip_src; + accumulate += *sptr++; + accumulate += *sptr; + pip->ip_src = proxy_address; + sptr = (u_short *) &pip->ip_src; + accumulate -= *sptr++; + accumulate -= *sptr; + } + + ADJUST_CHECKSUM(accumulate, pip->ip_sum); /* Monitor TCP connection state */ TcpMonitorIn(pip, link); @@ -798,39 +897,94 @@ TcpAliasIn(struct ip *pip) static int TcpAliasOut(struct ip *pip, int maxpacketsize) { + int proxy_type; + u_short dest_port; + u_short proxy_server_port; + struct in_addr dest_address; + struct in_addr proxy_server_address; struct tcphdr *tc; struct alias_link *link; tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); + proxy_type = ProxyCheck(pip, &proxy_server_address, &proxy_server_port); + + if (proxy_type == 0 && (packetAliasMode & PKT_ALIAS_PROXY_ONLY)) + return PKT_ALIAS_OK; + +/* If this is a transparent proxy, save original destination, + then alter the destination and adust checksums */ + dest_port = tc->th_dport; + dest_address = pip->ip_dst; + if (proxy_type != 0) + { + int accumulate; + u_short *sptr; + + accumulate = tc->th_dport; + tc->th_dport = proxy_server_port; + accumulate -= tc->th_dport; + + sptr = (u_short *) &(pip->ip_dst); + accumulate += *sptr++; + accumulate += *sptr; + sptr = (u_short *) &proxy_server_address; + accumulate -= *sptr++; + accumulate -= *sptr; + + ADJUST_CHECKSUM(accumulate, tc->th_sum); + + sptr = (u_short *) &(pip->ip_dst); + accumulate = *sptr++; + accumulate += *sptr; + pip->ip_dst = proxy_server_address; + sptr = (u_short *) &(pip->ip_dst); + accumulate -= *sptr++; + accumulate -= *sptr; + + ADJUST_CHECKSUM(accumulate, pip->ip_sum); + } + link = FindUdpTcpOut(pip->ip_src, pip->ip_dst, tc->th_sport, tc->th_dport, IPPROTO_TCP); if (link !=NULL) { - struct in_addr alias_address; u_short alias_port; + struct in_addr alias_address; int accumulate; u_short *sptr; +/* Save original destination address, if this is a proxy packet. + Also modify packet to include destination encoding. */ + if (proxy_type != 0) + { + SetProxyPort(link, dest_port); + SetProxyAddress(link, dest_address); + ProxyModify(link, pip, maxpacketsize, proxy_type); + } + +/* Get alias address and port */ alias_port = GetAliasPort(link); alias_address = GetAliasAddress(link); /* Monitor tcp connection state */ TcpMonitorOut(pip, link); -/* Special processing for ftp connection */ +/* Special processing for IP encoding protocols */ if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER || ntohs(tc->th_sport) == FTP_CONTROL_PORT_NUMBER) AliasHandleFtpOut(pip, link, maxpacketsize); if (ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_1 - || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2) + || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2) AliasHandleIrcOut(pip, link, maxpacketsize); /* Adjust TCP checksum since source port is being aliased */ /* and source address is being altered */ accumulate = tc->th_sport; - accumulate -= alias_port; + tc->th_sport = alias_port; + accumulate -= tc->th_sport; + sptr = (u_short *) &(pip->ip_src); accumulate += *sptr++; accumulate += *sptr; @@ -858,15 +1012,16 @@ TcpAliasOut(struct ip *pip, int maxpacketsize) ADJUST_CHECKSUM(accumulate, tc->th_sum) -/* Put alias address in TCP header */ - tc->th_sport = alias_port; - /* Change source address */ - DifferentialChecksum(&pip->ip_sum, - (u_short *) &alias_address, - (u_short *) &pip->ip_src, - 2); + sptr = (u_short *) &(pip->ip_src); + accumulate = *sptr++; + accumulate += *sptr; pip->ip_src = alias_address; + sptr = (u_short *) &(pip->ip_src); + accumulate -= *sptr++; + accumulate -= *sptr; + + ADJUST_CHECKSUM(accumulate, pip->ip_sum) return(PKT_ALIAS_OK); } @@ -1020,6 +1175,9 @@ PacketAliasIn(char *ptr, int maxpacketsize) struct ip *pip; int iresult; + if (packetAliasMode & PKT_ALIAS_REVERSE) + return PacketAliasOut(ptr, maxpacketsize); + HouseKeeping(); ClearCheckNewLink(); pip = (struct ip *) ptr; @@ -1044,6 +1202,9 @@ PacketAliasIn(char *ptr, int maxpacketsize) case IPPROTO_TCP: iresult = TcpAliasIn(pip); break; + case IPPROTO_GRE: + iresult = PptpAliasIn(pip); + break; } if (ntohs(pip->ip_off) & IP_MF) @@ -1086,8 +1247,6 @@ PacketAliasIn(char *ptr, int maxpacketsize) #define UNREG_ADDR_C_LOWER 0xc0a80000 #define UNREG_ADDR_C_UPPER 0xc0a8ffff - - int PacketAliasOut(char *ptr, /* valid IP packet */ int maxpacketsize /* How much the packet data may grow @@ -1098,6 +1257,9 @@ PacketAliasOut(char *ptr, /* valid IP packet */ struct in_addr addr_save; struct ip *pip; + if (packetAliasMode & PKT_ALIAS_REVERSE) + return PacketAliasIn(ptr, maxpacketsize); + HouseKeeping(); ClearCheckNewLink(); pip = (struct ip *) ptr; @@ -1142,6 +1304,9 @@ PacketAliasOut(char *ptr, /* valid IP packet */ case IPPROTO_TCP: iresult = TcpAliasOut(pip, maxpacketsize); break; + case IPPROTO_GRE: + iresult = PptpAliasOut(pip); + break; } } else diff --git a/usr.sbin/ppp/ppp/alias.h b/usr.sbin/ppp/ppp/alias.h index 81a65248eb7..89705bb2930 100644 --- a/usr.sbin/ppp/ppp/alias.h +++ b/usr.sbin/ppp/ppp/alias.h @@ -7,7 +7,7 @@ This software is placed into the public domain with no restrictions on its distribution. - $Id: alias.h,v 1.1 1998/08/31 08:16:27 brian Exp $ + $Id: alias.h,v 1.2 1999/03/08 01:40:22 brian Exp $ */ @@ -55,6 +55,10 @@ struct alias_link; struct in_addr, u_short, u_char); + extern int + PacketAliasPptp(struct in_addr); + + extern struct alias_link * PacketAliasRedirectAddr(struct in_addr, struct in_addr); @@ -82,28 +86,10 @@ struct alias_link; extern u_short PacketAliasInternetChecksum(u_short *, int); +/* Transparent Proxying */ + extern int + PacketAliasProxyRule(char *); -/* - In version 2.2, the function names were rationalized - to all be of the form PacketAlias... These are the - old function names for backwards compatibility -*/ -extern int SaveFragmentPtr(char *); -extern char *GetNextFragmentPtr(char *); -extern void FragmentAliasIn(char *, char *); -extern void SetPacketAliasAddress(struct in_addr); -extern void InitPacketAlias(void); -extern unsigned int SetPacketAliasMode(unsigned int, unsigned int); -extern int PacketAliasIn2(char *, struct in_addr, int maxpacketsize); -extern int PacketAliasOut2(char *, struct in_addr, int maxpacketsize); -extern int -PacketAliasPermanentLink(struct in_addr, u_short, - struct in_addr, u_short, - u_short, u_char); -extern u_short InternetChecksum(u_short *, int); - -/* Obsolete constant */ -#define PKT_ALIAS_NEW_LINK 5 /********************** Mode flags ********************/ /* Set these flags using SetPacketAliasMode() */ @@ -138,7 +124,6 @@ extern u_short InternetChecksum(u_short *, int); unregistered source addresses will be aliased (along with those of the ppp host maching itself. Private addresses are those in the following ranges: - 10.0.0.0 -> 10.255.255.255 172.16.0.0 -> 172.31.255.255 192.168.0.0 -> 192.168.255.255 */ @@ -162,6 +147,14 @@ extern u_short InternetChecksum(u_short *, int); #define PKT_ALIAS_PUNCH_FW 0x40 #endif +/* If PKT_ALIAS_PROXY_ONLY is set, then NAT will be disabled and only + transparent proxying performed */ +#define PKT_ALIAS_PROXY_ONLY 0x40 + +/* If PKT_ALIAS_REVERSE is set, the actions of PacketAliasIn() + and PacketAliasOut() are reversed */ +#define PKT_ALIAS_REVERSE 0x80 + /* Return Codes */ #define PKT_ALIAS_ERROR -1 #define PKT_ALIAS_OK 1 diff --git a/usr.sbin/ppp/ppp/alias_cmd.c b/usr.sbin/ppp/ppp/alias_cmd.c index 7acb2cd1d7d..bdfede04870 100644 --- a/usr.sbin/ppp/ppp/alias_cmd.c +++ b/usr.sbin/ppp/ppp/alias_cmd.c @@ -2,7 +2,7 @@ * The code in this file was written by Eivind Eklund <perhaps@yes.no>, * who places it in the public domain without restriction. * - * $Id: alias_cmd.c,v 1.3 1999/02/06 03:22:30 brian Exp $ + * $Id: alias_cmd.c,v 1.4 1999/03/08 01:40:22 brian Exp $ */ #include <sys/param.h> @@ -216,3 +216,50 @@ StrToAddrAndPort(const char *str, struct in_addr *addr, u_short *port, const cha return StrToPort(colon+1, port, proto); } + +int +alias_ProxyRule(struct cmdargs const *arg) +{ + char cmd[LINE_LEN]; + int f, pos; + size_t len; + + if (arg->argn >= arg->argc) + return -1; + + for (f = arg->argn, pos = 0; f < arg->argc; f++) { + len = strlen(arg->argv[f]); + if (sizeof cmd - pos < len + (f ? 1 : 0)) + break; + if (f) + cmd[pos++] = ' '; + strcpy(cmd + pos, arg->argv[f]); + pos += len; + } + + return PacketAliasProxyRule(cmd); +} + +int +alias_Pptp(struct cmdargs const *arg) +{ + struct in_addr addr; + + if (arg->argc == arg->argn) { + addr.s_addr = INADDR_NONE; + PacketAliasPptp(addr); + return 0; + } + + if (arg->argc != arg->argn + 1) + return -1; + + addr = GetIpAddr(arg->argv[arg->argn]); + if (addr.s_addr == INADDR_NONE) { + log_Printf(LogWARN, "%s: invalid address\n", arg->argv[arg->argn]); + return 1; + } + + PacketAliasPptp(addr); + return 0; +} diff --git a/usr.sbin/ppp/ppp/alias_cmd.h b/usr.sbin/ppp/ppp/alias_cmd.h index 1f38ff55893..a65b9803fee 100644 --- a/usr.sbin/ppp/ppp/alias_cmd.h +++ b/usr.sbin/ppp/ppp/alias_cmd.h @@ -2,10 +2,12 @@ * The code in this file was written by Eivind Eklund <perhaps@yes.no>, * who places it in the public domain without restriction. * - * $Id: alias_cmd.h,v 1.2 1999/02/06 03:22:30 brian Exp $ + * $Id: alias_cmd.h,v 1.3 1999/03/08 01:40:22 brian Exp $ */ struct cmdargs; extern int alias_RedirectPort(struct cmdargs const *); extern int alias_RedirectAddr(struct cmdargs const *); +extern int alias_ProxyRule(struct cmdargs const *); +extern int alias_Pptp(struct cmdargs const *); diff --git a/usr.sbin/ppp/ppp/alias_db.c b/usr.sbin/ppp/ppp/alias_db.c index dc9d020bd85..bd730ba5b15 100644 --- a/usr.sbin/ppp/ppp/alias_db.c +++ b/usr.sbin/ppp/ppp/alias_db.c @@ -56,12 +56,12 @@ Added ability to create an alias port without either destination address or port specified. port type = ALIAS_PORT_UNKNOWN_DEST_ALL (ee) - + Removed K&R style function headers and general cleanup. (ee) Added packetAliasMode to replace compiler #defines's (ee) - + Allocates sockets for partially specified ports if ALIAS_USE_SOCKETS defined. (cjm) @@ -73,10 +73,10 @@ links. (J. Fortes suggested the need for this.) Examples: - (192.168.0.1, port 23) <-> alias port 6002, unknown dest addr/port + (192.168.0.1, port 23) <-> alias port 6002, unknown dest addr/port (192.168.0.2, port 21) <-> alias port 3604, known dest addr - unknown dest port + unknown dest port These permament links allow for incoming connections to machines on the local network. They can be given with a @@ -111,7 +111,7 @@ #include <stdlib.h> #include <stdio.h> #include <unistd.h> - + #include <sys/errno.h> #include <sys/socket.h> #include <sys/time.h> @@ -139,7 +139,7 @@ #define LINK_TABLE_IN_SIZE 4001 /* Parameters used for cleanup of expired links */ -#define ALIAS_CLEANUP_INTERVAL_SECS 60 +#define ALIAS_CLEANUP_INTERVAL_SECS 60 #define ALIAS_CLEANUP_MAX_SPOKES 30 /* Timouts (in seconds) for different link types) */ @@ -174,14 +174,14 @@ /* Dummy port number codes used for FindLinkIn/Out() and AddLink(). These constants can be anything except zero, which indicates an - unknown port numbea. */ + unknown port number. */ #define NO_DEST_PORT 1 #define NO_SRC_PORT 1 -/* Data Structures +/* Data Structures The fundamental data structure used in this program is "struct alias_link". Whenever a TCP connection is made, @@ -237,11 +237,13 @@ struct tcp_dat struct alias_link /* Main data structure */ { struct in_addr src_addr; /* Address and port information */ - struct in_addr dst_addr; /* . */ - struct in_addr alias_addr; /* . */ - u_short src_port; /* . */ - u_short dst_port; /* . */ - u_short alias_port; /* . */ + struct in_addr dst_addr; + struct in_addr alias_addr; + struct in_addr proxy_addr; + u_short src_port; + u_short dst_port; + u_short alias_port; + u_short proxy_port; int link_type; /* Type of link: tcp, udp, icmp, frag */ @@ -348,6 +350,12 @@ static int fireWallFD = -1; /* File descriptor to be able to */ /* flag. */ #endif +static int pptpAliasFlag; /* Indicates if PPTP aliasing is */ + /* on or off */ +static struct in_addr pptpAliasAddr; /* Address of source of PPTP */ + /* packets. */ + + @@ -853,15 +861,17 @@ AddLink(struct in_addr src_addr, alias_addr.s_addr = 0; /* Basic initialization */ - link->src_addr = src_addr; - link->dst_addr = dst_addr; - link->src_port = src_port; - link->alias_addr = alias_addr; - link->dst_port = dst_port; - link->link_type = link_type; - link->sockfd = -1; - link->flags = 0; - link->timestamp = timeStamp; + link->src_addr = src_addr; + link->dst_addr = dst_addr; + link->alias_addr = alias_addr; + link->proxy_addr.s_addr = 0; + link->src_port = src_port; + link->dst_port = dst_port; + link->proxy_port = 0; + link->link_type = link_type; + link->sockfd = -1; + link->flags = 0; + link->timestamp = timeStamp; /* Expiration time */ switch (link_type) @@ -1304,7 +1314,9 @@ FindUdpTcpIn(struct in_addr dst_addr, dst_port, alias_port, link_type, 1); - if ( !(packetAliasMode & PKT_ALIAS_DENY_INCOMING) && link == NULL) + if (!(packetAliasMode & PKT_ALIAS_DENY_INCOMING) + && !(packetAliasMode & PKT_ALIAS_PROXY_ONLY) + && link == NULL) { struct in_addr target_addr; @@ -1578,6 +1590,34 @@ SetAckModified(struct alias_link *link) } +struct in_addr +GetProxyAddress(struct alias_link *link) +{ + return link->proxy_addr; +} + + +void +SetProxyAddress(struct alias_link *link, struct in_addr addr) +{ + link->proxy_addr = addr; +} + + +u_short +GetProxyPort(struct alias_link *link) +{ + return link->proxy_port; +} + + +void +SetProxyPort(struct alias_link *link, u_short port) +{ + link->proxy_port = port; +} + + int GetAckModified(struct alias_link *link) { @@ -1906,6 +1946,25 @@ PacketAliasRedirectPort(struct in_addr src_addr, u_short src_port, return link; } +/* Translate PPTP packets to a machine on the inside + */ +int +PacketAliasPptp(struct in_addr src_addr) +{ + + pptpAliasAddr = src_addr; /* Address of the inside PPTP machine */ + pptpAliasFlag = src_addr.s_addr != INADDR_NONE; + + return 1; +} + +int GetPptpAlias (struct in_addr* alias_addr) +{ + if (pptpAliasFlag) + *alias_addr = pptpAliasAddr; + + return pptpAliasFlag; +} /* Static address translation */ struct alias_link * @@ -2007,6 +2066,8 @@ PacketAliasInit(void) packetAliasMode = PKT_ALIAS_SAME_PORTS | PKT_ALIAS_USE_SOCKETS | PKT_ALIAS_RESET_ON_ADDR_CHANGE; + + pptpAliasFlag = 0; } void diff --git a/usr.sbin/ppp/ppp/alias_local.h b/usr.sbin/ppp/ppp/alias_local.h index 0e94a64b281..da451259cdf 100644 --- a/usr.sbin/ppp/ppp/alias_local.h +++ b/usr.sbin/ppp/ppp/alias_local.h @@ -1,9 +1,11 @@ /* -*- mode: c; tab-width: 3; c-basic-offset: 3; -*- Alias_local.h contains the function prototypes for alias.c, alias_db.c, alias_util.c and alias_ftp.c, alias_irc.c (as well - as any future add-ons). It is intended to be used only within - the aliasing software. Outside world interfaces are defined - in alias.h + as any future add-ons). It also includes macros, globals and + struct definitions shared by more than one alias*.c file. + + This include file is intended to be used only within the aliasing + software. Outside world interfaces are defined in alias.h This software is placed into the public domain with no restrictions on its distribution. @@ -15,9 +17,54 @@ #ifndef ALIAS_LOCAL_H #define ALIAS_LOCAL_H + +/* + Macros + */ + +/* + The following macro is used to update an + internet checksum. "delta" is a 32-bit + accumulation of all the changes to the + checksum (adding in new 16-bit words and + subtracting out old words), and "cksum" + is the checksum value to be updated. +*/ +#define ADJUST_CHECKSUM(acc, cksum) { \ + acc += cksum; \ + if (acc < 0) \ + { \ + acc = -acc; \ + acc = (acc >> 16) + (acc & 0xffff); \ + acc += acc >> 16; \ + cksum = (u_short) ~acc; \ + } \ + else \ + { \ + acc = (acc >> 16) + (acc & 0xffff); \ + acc += acc >> 16; \ + cksum = (u_short) acc; \ + } \ +} + + +/* + Globals +*/ + extern int packetAliasMode; -struct alias_link; + +/* + Structs +*/ + +struct alias_link; /* Incomplete structure */ + + +/* + Prototypes +*/ /* General utilities */ u_short IpChecksum(struct ip *); @@ -71,6 +118,10 @@ struct in_addr GetDefaultAliasAddress(void); void SetDefaultAliasAddress(struct in_addr); u_short GetOriginalPort(struct alias_link *); u_short GetAliasPort(struct alias_link *); +struct in_addr GetProxyAddress(struct alias_link *); +void SetProxyAddress(struct alias_link *, struct in_addr); +u_short GetProxyPort(struct alias_link *); +void SetProxyPort(struct alias_link *, u_short); void SetAckModified(struct alias_link *); int GetAckModified(struct alias_link *); int GetDeltaAckIn(struct ip *, struct alias_link *); @@ -88,13 +139,24 @@ void HouseKeeping(void); /* Tcp specfic routines */ /*lint -save -library Suppress flexelint warnings */ + +/* FTP routines */ void AliasHandleFtpOut(struct ip *, struct alias_link *, int); + +/* IRC routines */ void AliasHandleIrcOut(struct ip *pip, struct alias_link *link, int maxsize ); -void AliasHandleUdpNbt(struct ip *, struct alias_link *, struct in_addr *, u_short); -void AliasHandleUdpNbtNS(struct ip *, struct alias_link *, struct in_addr *, u_short *, struct in_addr *, u_short *); + +/* NetBIOS routines */ +int AliasHandleUdpNbt(struct ip *, struct alias_link *, struct in_addr *, u_short); +int AliasHandleUdpNbtNS(struct ip *, struct alias_link *, struct in_addr *, u_short *, struct in_addr *, u_short *); + +/* CUSeeMe routines */ void AliasHandleCUSeeMeOut(struct ip *, struct alias_link *); void AliasHandleCUSeeMeIn(struct ip *, struct in_addr); +/* Transparent proxy routines */ +int ProxyCheck(struct ip *, struct in_addr *, u_short *); +void ProxyModify(struct alias_link *, struct ip *, int, int); enum alias_tcp_state { @@ -103,5 +165,6 @@ enum alias_tcp_state { ALIAS_TCP_STATE_DISCONNECTED }; +int GetPptpAlias (struct in_addr*); /*lint -restore */ #endif /* defined(ALIAS_LOCAL_H) */ diff --git a/usr.sbin/ppp/ppp/alias_nbt.c b/usr.sbin/ppp/ppp/alias_nbt.c index 87dc89ac68b..adefebdbf49 100644 --- a/usr.sbin/ppp/ppp/alias_nbt.c +++ b/usr.sbin/ppp/ppp/alias_nbt.c @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: alias_nbt.c,v 1.1 1998/08/31 08:16:33 brian Exp $ + * $Id: alias_nbt.c,v 1.2 1999/03/08 01:40:22 brian Exp $ * * TODO: * oClean up. @@ -132,15 +132,21 @@ void PrintRcode( u_char rcode ) { /* Handling Name field */ -u_char *AliasHandleName ( u_char *p ) { +u_char *AliasHandleName ( u_char *p, char *pmax ) { u_char *s; u_char c; int compress; /* Following length field */ + + if (p == NULL || (char *)p >= pmax) + return(NULL); + if (*p & 0xc0 ) { p = p + 2; + if ((char *)p > pmax) + return(NULL); return ((u_char *)p); } while ( ( *p & 0x3f) != 0x00 ) { @@ -152,6 +158,10 @@ u_char *AliasHandleName ( u_char *p ) { /* Get next length field */ p = (u_char *)(p + (*p & 0x3f) + 1); + if ((char *)p > pmax) { + p = NULL; + break; + } #ifdef DEBUG printf(":"); #endif @@ -179,7 +189,10 @@ u_char *AliasHandleName ( u_char *p ) { } /* Set up to out of Name field */ - p++; + if (p == NULL || (char *)p >= pmax) + p = NULL; + else + p++; return ((u_char *)p); } @@ -194,19 +207,24 @@ u_char *AliasHandleName ( u_char *p ) { #define DGM_POSITIVE_RES 0x15 #define DGM_NEGATIVE_RES 0x16 -void AliasHandleUdpNbt( +int AliasHandleUdpNbt( struct ip *pip, /* IP packet to examine/patch */ struct alias_link *link, struct in_addr *alias_address, - u_short alias_port ) -{ + u_short alias_port +) { struct udphdr * uh; NbtDataHeader *ndh; - u_char *p; + u_char *p = NULL; + char *pmax; /* Calculate data length of UDP packet */ uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); + pmax = (char *)uh + ntohs( uh->uh_ulen ); + ndh = (NbtDataHeader *)((char *)uh + (sizeof (struct udphdr))); + if ((char *)(ndh + 1) > pmax) + return(-1); #ifdef DEBUG printf("\nType=%02x,", ndh->type ); #endif @@ -215,8 +233,8 @@ void AliasHandleUdpNbt( case DGM_DIRECT_GROUP: case DGM_BROADCAST: p = (u_char *)ndh + 14; - p = AliasHandleName ( p ); /* Source Name */ - p = AliasHandleName ( p ); /* Destination Name */ + p = AliasHandleName ( p, pmax ); /* Source Name */ + p = AliasHandleName ( p, pmax ); /* Destination Name */ break; case DGM_ERROR: p = (u_char *)ndh + 11; @@ -225,9 +243,11 @@ void AliasHandleUdpNbt( case DGM_POSITIVE_RES: case DGM_NEGATIVE_RES: p = (u_char *)ndh + 10; - p = AliasHandleName ( p ); /* Destination Name */ + p = AliasHandleName ( p, pmax ); /* Destination Name */ break; } + if (p == NULL || (char *)p > pmax) + p = NULL; #ifdef DEBUG printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) ); #endif @@ -251,6 +271,7 @@ void AliasHandleUdpNbt( printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) ); fflush(stdout); #endif + return((p == NULL) ? -1 : 0); } /* Question Section */ #define QS_TYPE_NB 0x0020 @@ -261,14 +282,22 @@ typedef struct { u_short class; /* The class of Request */ } NBTNsQuestion; -u_char *AliasHandleQuestion(u_short count, +u_char * +AliasHandleQuestion( + u_short count, NBTNsQuestion *q, + char *pmax, NBTArguments *nbtarg) { while ( count != 0 ) { /* Name Filed */ - q = (NBTNsQuestion *)AliasHandleName((u_char *)q ); + q = (NBTNsQuestion *)AliasHandleName((u_char *)q, pmax); + + if (q == NULL || (char *)(q + 1) > pmax) { + q = NULL; + break; + } /* Type and Class filed */ switch ( ntohs(q->type) ) { @@ -308,12 +337,17 @@ typedef struct { struct in_addr addr; } NBTNsRNB; -u_char *AliasHandleResourceNB( NBTNsResource *q, +u_char * +AliasHandleResourceNB( + NBTNsResource *q, + char *pmax, NBTArguments *nbtarg) { NBTNsRNB *nb; u_short bcount; + if (q == NULL || (char *)(q + 1) > pmax) + return(NULL); /* Check out a length */ bcount = ntohs(q->rdlen); @@ -325,7 +359,11 @@ u_char *AliasHandleResourceNB( NBTNsResource *q, printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr)); printf("->%s, %dbytes] ",inet_ntoa(nbtarg->newaddr ), bcount); #endif - while ( bcount != 0 ) { + while ( nb != NULL && bcount != 0 ) { + if ((char *)(nb + 1) > pmax) { + nb = NULL; + break; + } #ifdef DEBUG printf("<%s>", inet_ntoa(nb->addr) ); #endif @@ -356,6 +394,9 @@ u_char *AliasHandleResourceNB( NBTNsResource *q, nb=(NBTNsRNB *)((u_char *)nb + SizeOfNsRNB); bcount -= SizeOfNsRNB; } + if (nb == NULL || (char *)(nb + 1) > pmax) { + nb = NULL; + } return ((u_char *)nb); } @@ -365,12 +406,18 @@ typedef struct { struct in_addr addr; } NBTNsResourceA; -u_char *AliasHandleResourceA( NBTNsResource *q, +u_char * +AliasHandleResourceA( + NBTNsResource *q, + char *pmax, NBTArguments *nbtarg) { NBTNsResourceA *a; u_short bcount; + if (q == NULL || (char *)(q + 1) > pmax) + return(NULL); + /* Forward to Resource A position */ a = (NBTNsResourceA *)( (u_char *)q + sizeof(NBTNsResource) ); @@ -383,6 +430,8 @@ u_char *AliasHandleResourceA( NBTNsResource *q, printf("->%s]",inet_ntoa(nbtarg->newaddr )); #endif while ( bcount != 0 ) { + if (a == NULL || (char *)(a + 1) > pmax) + return(NULL); #ifdef DEBUG printf("..%s", inet_ntoa(a->addr) ); #endif @@ -405,6 +454,8 @@ u_char *AliasHandleResourceA( NBTNsResource *q, a++; /*XXXX*/ bcount -= SizeOfResourceA; } + if (a == NULL || (char *)(a + 1) > pmax) + a = NULL; return ((u_char *)a); } @@ -412,12 +463,18 @@ typedef struct { u_short opcode:4, flags:8, resv:4; } NBTNsResourceNULL; -u_char *AliasHandleResourceNULL( NBTNsResource *q, +u_char * +AliasHandleResourceNULL( + NBTNsResource *q, + char *pmax, NBTArguments *nbtarg) { NBTNsResourceNULL *n; u_short bcount; + if (q == NULL || (char *)(q + 1) > pmax) + return(NULL); + /* Forward to Resource NULL position */ n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) ); @@ -426,19 +483,31 @@ u_char *AliasHandleResourceNULL( NBTNsResource *q, /* Processing all in_addr array */ while ( bcount != 0 ) { + if ((char *)(n + 1) > pmax) { + n = NULL; + break; + } n++; bcount -= sizeof(NBTNsResourceNULL); } + if ((char *)(n + 1) > pmax) + n = NULL; return ((u_char *)n); } -u_char *AliasHandleResourceNS( NBTNsResource *q, +u_char * +AliasHandleResourceNS( + NBTNsResource *q, + char *pmax, NBTArguments *nbtarg) { NBTNsResourceNULL *n; u_short bcount; + if (q == NULL || (char *)(q + 1) > pmax) + return(NULL); + /* Forward to Resource NULL position */ n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) ); @@ -446,8 +515,11 @@ u_char *AliasHandleResourceNS( NBTNsResource *q, bcount = ntohs(q->rdlen); /* Resource Record Name Filed */ - q = (NBTNsResource *)AliasHandleName( (u_char *)n ); /* XXX */ + q = (NBTNsResource *)AliasHandleName( (u_char *)n, pmax ); /* XXX */ + if (q == NULL || (char *)((u_char *)n + bcount) > pmax) + return(NULL); + else return ((u_char *)n + bcount); } @@ -455,28 +527,44 @@ typedef struct { u_short numnames; } NBTNsResourceNBSTAT; -u_char *AliasHandleResourceNBSTAT( NBTNsResource *q, +u_char * +AliasHandleResourceNBSTAT( + NBTNsResource *q, + char *pmax, NBTArguments *nbtarg) { NBTNsResourceNBSTAT *n; u_short bcount; + if (q == NULL || (char *)(q + 1) > pmax) + return(NULL); + /* Forward to Resource NBSTAT position */ n = (NBTNsResourceNBSTAT *)( (u_char *)q + sizeof(NBTNsResource) ); /* Check out of length */ bcount = ntohs(q->rdlen); + if (q == NULL || (char *)((u_char *)n + bcount) > pmax) + return(NULL); + else return ((u_char *)n + bcount); } -u_char *AliasHandleResource(u_short count, +u_char * +AliasHandleResource( + u_short count, NBTNsResource *q, - NBTArguments *nbtarg) + char *pmax, + NBTArguments + *nbtarg) { while ( count != 0 ) { /* Resource Record Name Filed */ - q = (NBTNsResource *)AliasHandleName( (u_char *)q ); + q = (NBTNsResource *)AliasHandleName( (u_char *)q, pmax ); + + if (q == NULL || (char *)(q + 1) > pmax) + break; #ifdef DEBUG printf("type=%02x, count=%d\n", ntohs(q->type), count ); #endif @@ -484,22 +572,45 @@ u_char *AliasHandleResource(u_short count, /* Type and Class filed */ switch ( ntohs(q->type) ) { case RR_TYPE_NB: - q = (NBTNsResource *)AliasHandleResourceNB( q, nbtarg ); + q = (NBTNsResource *)AliasHandleResourceNB( + q, + pmax, + nbtarg + ); break; case RR_TYPE_A: - q = (NBTNsResource *)AliasHandleResourceA( q, nbtarg ); + q = (NBTNsResource *)AliasHandleResourceA( + q, + pmax, + nbtarg + ); break; case RR_TYPE_NS: - q = (NBTNsResource *)AliasHandleResourceNS( q, nbtarg ); + q = (NBTNsResource *)AliasHandleResourceNS( + q, + pmax, + nbtarg + ); break; case RR_TYPE_NULL: - q = (NBTNsResource *)AliasHandleResourceNULL( q, nbtarg ); + q = (NBTNsResource *)AliasHandleResourceNULL( + q, + pmax, + nbtarg + ); break; case RR_TYPE_NBSTAT: - q = (NBTNsResource *)AliasHandleResourceNBSTAT( q, nbtarg ); + q = (NBTNsResource *)AliasHandleResourceNBSTAT( + q, + pmax, + nbtarg + ); break; - default: printf("\nUnknown Type of Resource %0x\n", - ntohs(q->type) ); + default: + printf( + "\nUnknown Type of Resource %0x\n", + ntohs(q->type) + ); break; } count--; @@ -508,7 +619,7 @@ u_char *AliasHandleResource(u_short count, return ((u_char *)q); } -void AliasHandleUdpNbtNS( +int AliasHandleUdpNbtNS( struct ip *pip, /* IP packet to examine/patch */ struct alias_link *link, struct in_addr *alias_address, @@ -518,8 +629,8 @@ void AliasHandleUdpNbtNS( { struct udphdr * uh; NbtNSHeader * nsh; - u_short dlen; u_char * p; + char *pmax; NBTArguments nbtarg; /* Set up Common Parameter */ @@ -531,12 +642,16 @@ void AliasHandleUdpNbtNS( /* Calculate data length of UDP packet */ uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2)); nbtarg.uh_sum = &(uh->uh_sum); - dlen = ntohs( uh->uh_ulen ); nsh = (NbtNSHeader *)((char *)uh + (sizeof(struct udphdr))); p = (u_char *)(nsh + 1); + pmax = (char *)uh + ntohs( uh->uh_ulen ); + + if ((char *)(nsh + 1) > pmax) + return(-1); #ifdef DEBUG - printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x, an=%04x, ns=%04x, ar=%04x, [%d]-->", + printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x" + ", an=%04x, ns=%04x, ar=%04x, [%d]-->", nsh->dir ? "Response": "Request", nsh->nametrid, nsh->opcode, @@ -546,31 +661,53 @@ void AliasHandleUdpNbtNS( ntohs(nsh->ancount), ntohs(nsh->nscount), ntohs(nsh->arcount), - (u_char *)p -(u_char *)nsh); + (u_char *)p -(u_char *)nsh + ); #endif /* Question Entries */ if (ntohs(nsh->qdcount) !=0 ) { - p = AliasHandleQuestion(ntohs(nsh->qdcount), (NBTNsQuestion *)p, &nbtarg ); + p = AliasHandleQuestion( + ntohs(nsh->qdcount), + (NBTNsQuestion *)p, + pmax, + &nbtarg + ); } /* Answer Resource Records */ if (ntohs(nsh->ancount) !=0 ) { - p = AliasHandleResource(ntohs(nsh->ancount), (NBTNsResource *)p, &nbtarg ); + p = AliasHandleResource( + ntohs(nsh->ancount), + (NBTNsResource *)p, + pmax, + &nbtarg + ); } /* Authority Resource Recodrs */ if (ntohs(nsh->nscount) !=0 ) { - p = AliasHandleResource(ntohs(nsh->nscount), (NBTNsResource *)p, &nbtarg ); + p = AliasHandleResource( + ntohs(nsh->nscount), + (NBTNsResource *)p, + pmax, + &nbtarg + ); } /* Additional Resource Recodrs */ if (ntohs(nsh->arcount) !=0 ) { - p = AliasHandleResource(ntohs(nsh->arcount), (NBTNsResource *)p, &nbtarg ); + p = AliasHandleResource( + ntohs(nsh->arcount), + (NBTNsResource *)p, + pmax, + &nbtarg + ); } #ifdef DEBUG PrintRcode(nsh->rcode); #endif - return; + return ((p == NULL) ? -1 : 0); } + diff --git a/usr.sbin/ppp/ppp/alias_proxy.c b/usr.sbin/ppp/ppp/alias_proxy.c new file mode 100644 index 00000000000..27a56c25dae --- /dev/null +++ b/usr.sbin/ppp/ppp/alias_proxy.c @@ -0,0 +1,801 @@ +/* file: alias_proxy.c + + This file encapsulates special operations related to transparent + proxy redirection. This is where packets with a particular destination, + usually tcp port 80, are redirected to a proxy server. + + When packets are proxied, the destination address and port are + modified. In certain cases, it is necessary to somehow encode + the original address/port info into the packet. Two methods are + presently supported: addition of a [DEST addr port] string at the + beginning a of tcp stream, or inclusion of an optional field + in the IP header. + + There is one public API function: + + PacketAliasProxyRule() -- Adds and deletes proxy + rules. + + Rules are stored in a linear linked list, so lookup efficiency + won't be too good for large lists. + + + Initial development: April, 1998 (cjm) +*/ + + +/* System includes */ +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netdb.h> + +#include <sys/types.h> +#include <sys/socket.h> + +/* BSD IPV4 includes */ +#include <netinet/in_systm.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/tcp.h> + +#include <arpa/inet.h> + +#include "alias_local.h" /* Functions used by alias*.c */ +#include "alias.h" /* Public API functions for libalias */ + + + +/* + Data structures + */ + +/* + * A linked list of arbitrary length, based on struct proxy_entry is + * used to store proxy rules. + */ +struct proxy_entry +{ +#define PROXY_TYPE_ENCODE_NONE 1 +#define PROXY_TYPE_ENCODE_TCPSTREAM 2 +#define PROXY_TYPE_ENCODE_IPHDR 3 + int rule_index; + int proxy_type; + u_char proto; + u_short proxy_port; + u_short server_port; + + struct in_addr server_addr; + + struct in_addr src_addr; + struct in_addr src_mask; + + struct in_addr dst_addr; + struct in_addr dst_mask; + + struct proxy_entry *next; + struct proxy_entry *last; +}; + + + +/* + File scope variables +*/ + +static struct proxy_entry *proxyList; + + + +/* Local (static) functions: + + IpMask() -- Utility function for creating IP + masks from integer (1-32) specification. + IpAddr() -- Utility function for converting string + to IP address + IpPort() -- Utility function for converting string + to port number + RuleAdd() -- Adds an element to the rule list. + RuleDelete() -- Removes an element from the rule list. + RuleNumberDelete() -- Removes all elements from the rule list + having a certain rule number. + ProxyEncodeTcpStream() -- Adds [DEST x.x.x.x xxxx] to the beginning + of a TCP stream. + ProxyEncodeIpHeader() -- Adds an IP option indicating the true + destination of a proxied IP packet +*/ + +static int IpMask(int, struct in_addr *); +static int IpAddr(char *, struct in_addr *); +static int IpPort(char *, int, int *); +static void RuleAdd(struct proxy_entry *); +static void RuleDelete(struct proxy_entry *); +static int RuleNumberDelete(int); +static void ProxyEncodeTcpStream(struct alias_link *, struct ip *, int); +static void ProxyEncodeIpHeader(struct ip *, int); + +static int +IpMask(int nbits, struct in_addr *mask) +{ + int i; + u_int imask; + + if (nbits < 0 || nbits > 32) + return -1; + + imask = 0; + for (i=0; i<nbits; i++) + imask = (imask >> 1) + 0x80000000; + mask->s_addr = htonl(imask); + + return 0; +} + +static int +IpAddr(char *s, struct in_addr *addr) +{ + if (inet_aton(s, addr) == 0) + return -1; + else + return 0; +} + +static int +IpPort(char *s, int proto, int *port) +{ + int n; + + n = sscanf(s, "%d", port); + if (n != 1) + { + struct servent *se; + + if (proto == IPPROTO_TCP) + se = getservbyname(s, "tcp"); + else if (proto == IPPROTO_UDP) + se = getservbyname(s, "udp"); + else + return -1; + + if (se == NULL) + return -1; + + *port = (u_int) ntohs(se->s_port); + } + + return 0; +} + +void +RuleAdd(struct proxy_entry *entry) +{ + int rule_index; + struct proxy_entry *ptr; + struct proxy_entry *ptr_last; + + if (proxyList == NULL) + { + proxyList = entry; + entry->last = NULL; + entry->next = NULL; + return; + } + + rule_index = entry->rule_index; + ptr = proxyList; + ptr_last = NULL; + while (ptr != NULL) + { + if (ptr->rule_index >= rule_index) + { + if (ptr_last == NULL) + { + entry->next = proxyList; + entry->last = NULL; + proxyList->last = entry; + proxyList = entry; + return; + } + + ptr_last->next = entry; + ptr->last = entry; + entry->last = ptr->last; + entry->next = ptr; + return; + } + ptr_last = ptr; + ptr = ptr->next; + } + + ptr_last->next = entry; + entry->last = ptr_last; + entry->next = NULL; +} + +static void +RuleDelete(struct proxy_entry *entry) +{ + if (entry->last != NULL) + entry->last->next = entry->next; + else + proxyList = entry->next; + + if (entry->next != NULL) + entry->next->last = entry->last; + + free(entry); +} + +static int +RuleNumberDelete(int rule_index) +{ + int err; + struct proxy_entry *ptr; + + err = -1; + ptr = proxyList; + while (ptr != NULL) + { + struct proxy_entry *ptr_next; + + ptr_next = ptr->next; + if (ptr->rule_index == rule_index) + { + err = 0; + RuleDelete(ptr); + } + + ptr = ptr_next; + } + + return err; +} + +static void +ProxyEncodeTcpStream(struct alias_link *link, + struct ip *pip, + int maxpacketsize) +{ + int slen; + char buffer[40]; + struct tcphdr *tc; + +/* Compute pointer to tcp header */ + tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); + +/* Don't modify if once already modified */ + + if (GetAckModified (link)) + return; + +/* Translate destination address and port to string form */ + snprintf(buffer, sizeof(buffer) - 2, "[DEST %s %d]", + inet_ntoa(GetProxyAddress (link)), (u_int) ntohs(GetProxyPort (link))); + +/* Pad string out to a multiple of two in length */ + slen = strlen(buffer); + switch (slen % 2) + { + case 0: + strcat(buffer, " \n"); + slen += 2; + break; + case 1: + strcat(buffer, "\n"); + slen += 1; + } + +/* Check for packet overflow */ + if ((ntohs(pip->ip_len) + strlen(buffer)) > maxpacketsize) + return; + +/* Shift existing TCP data and insert destination string */ + { + int dlen; + int hlen; + u_char *p; + + hlen = (pip->ip_hl + tc->th_off) << 2; + dlen = ntohs (pip->ip_len) - hlen; + +/* Modify first packet that has data in it */ + + if (dlen == 0) + return; + + p = (char *) pip; + p += hlen; + + memmove(p + slen, p, dlen); + memcpy(p, buffer, slen); + } + +/* Save information about modfied sequence number */ + { + int delta; + + SetAckModified(link); + delta = GetDeltaSeqOut(pip, link); + AddSeq(pip, link, delta+slen); + } + +/* Update IP header packet length and checksum */ + { + int accumulate; + + accumulate = pip->ip_len; + pip->ip_len = htons(ntohs(pip->ip_len) + slen); + accumulate -= pip->ip_len; + + ADJUST_CHECKSUM(accumulate, pip->ip_sum); + } + +/* Update TCP checksum, Use TcpChecksum since so many things have + already changed. */ + + tc->th_sum = 0; + tc->th_sum = TcpChecksum (pip); +} + +static void +ProxyEncodeIpHeader(struct ip *pip, + int maxpacketsize) +{ +#define OPTION_LEN_BYTES 8 +#define OPTION_LEN_INT16 4 +#define OPTION_LEN_INT32 2 + u_char option[OPTION_LEN_BYTES]; + +fprintf(stdout, " ip cksum 1 = %x\n", (u_int) IpChecksum(pip)); +fprintf(stdout, "tcp cksum 1 = %x\n", (u_int) TcpChecksum(pip)); + +/* Check to see that there is room to add an IP option */ + if (pip->ip_hl > (0x0f - OPTION_LEN_INT32)) + return; + +/* Build option and copy into packet */ + { + u_char *ptr; + struct tcphdr *tc; + + ptr = (u_char *) pip; + ptr += 20; + memcpy(ptr + OPTION_LEN_BYTES, ptr, ntohs(pip->ip_len) - 20); + + option[0] = 0x64; /* class: 3 (reserved), option 4 */ + option[1] = OPTION_LEN_BYTES; + + memcpy(&option[2], (u_char *) &pip->ip_dst, 4); + + tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); + memcpy(&option[6], (u_char *) &tc->th_sport, 2); + + memcpy(ptr, option, 8); + } + +/* Update checksum, header length and packet length */ + { + int i; + int accumulate; + u_short *sptr; + + sptr = (u_short *) option; + accumulate = 0; + for (i=0; i<OPTION_LEN_INT16; i++) + accumulate -= *(sptr++); + + sptr = (u_short *) pip; + accumulate += *sptr; + pip->ip_hl += OPTION_LEN_INT32; + accumulate -= *sptr; + + accumulate += pip->ip_len; + pip->ip_len = htons(ntohs(pip->ip_len) + OPTION_LEN_BYTES); + accumulate -= pip->ip_len; + + ADJUST_CHECKSUM(accumulate, pip->ip_sum); + } +#undef OPTION_LEN_BYTES +#undef OPTION_LEN_INT16 +#undef OPTION_LEN_INT32 +fprintf(stdout, " ip cksum 2 = %x\n", (u_int) IpChecksum(pip)); +fprintf(stdout, "tcp cksum 2 = %x\n", (u_int) TcpChecksum(pip)); +} + + +/* Functions by other packet alias source files + + ProxyCheck() -- Checks whether an outgoing packet should + be proxied. + ProxyModify() -- Encodes the original destination address/port + for a packet which is to be redirected to + a proxy server. +*/ + +int +ProxyCheck(struct ip *pip, + struct in_addr *proxy_server_addr, + u_short *proxy_server_port) +{ + u_short dst_port; + struct in_addr src_addr; + struct in_addr dst_addr; + struct proxy_entry *ptr; + + src_addr = pip->ip_src; + dst_addr = pip->ip_dst; + dst_port = ((struct tcphdr *) ((char *) pip + (pip->ip_hl << 2))) + ->th_dport; + + ptr = proxyList; + while (ptr != NULL) + { + u_short proxy_port; + + proxy_port = ptr->proxy_port; + if ((dst_port == proxy_port || proxy_port == 0) + && pip->ip_p == ptr->proto + && src_addr.s_addr != ptr->server_addr.s_addr) + { + struct in_addr src_addr_masked; + struct in_addr dst_addr_masked; + + src_addr_masked.s_addr = src_addr.s_addr & ptr->src_mask.s_addr; + dst_addr_masked.s_addr = dst_addr.s_addr & ptr->dst_mask.s_addr; + + if ((src_addr_masked.s_addr == ptr->src_addr.s_addr) + && (dst_addr_masked.s_addr == ptr->dst_addr.s_addr)) + { + if ((*proxy_server_port = ptr->server_port) == 0) + *proxy_server_port = dst_port; + *proxy_server_addr = ptr->server_addr; + return ptr->proxy_type; + } + } + ptr = ptr->next; + } + + return 0; +} + +void +ProxyModify(struct alias_link *link, + struct ip *pip, + int maxpacketsize, + int proxy_type) +{ + switch (proxy_type) + { + case PROXY_TYPE_ENCODE_IPHDR: + ProxyEncodeIpHeader(pip, maxpacketsize); + break; + + case PROXY_TYPE_ENCODE_TCPSTREAM: + ProxyEncodeTcpStream(link, pip, maxpacketsize); + break; + } +} + + +/* + Public API functions +*/ + +int +PacketAliasProxyRule(char *cmd) +{ +/* + * This function takes command strings of the form: + * + * server <addr>[:<port>] + * [port <port>] + * [rule n] + * [proto tcp|udp] + * [src <addr>[/n]] + * [dst <addr>[/n]] + * [type encode_tcp_stream|encode_ip_hdr|no_encode] + * + * delete <rule number> + * + * Subfields can be in arbitrary order. Port numbers and addresses + * must be in either numeric or symbolic form. An optional rule number + * is used to control the order in which rules are searched. If two + * rules have the same number, then search order cannot be guaranteed, + * and the rules should be disjoint. If no rule number is specified, + * then 0 is used, and group 0 rules are always checked before any + * others. + */ + int i, n, len; + int cmd_len; + int token_count; + int state; + char *token; + char buffer[256]; + char str_port[sizeof(buffer)]; + char str_server_port[sizeof(buffer)]; + + int rule_index; + int proto; + int proxy_type; + int proxy_port; + int server_port; + struct in_addr server_addr; + struct in_addr src_addr, src_mask; + struct in_addr dst_addr, dst_mask; + struct proxy_entry *proxy_entry; + +/* Copy command line into a buffer */ + cmd_len = strlen(cmd); + if (cmd_len > (sizeof(buffer) - 1)) + return -1; + strcpy(buffer, cmd); + +/* Convert to lower case */ + len = strlen(buffer); + for (i=0; i<len; i++) + buffer[i] = tolower(buffer[i]); + +/* Set default proxy type */ + +/* Set up default values */ + rule_index = 0; + proxy_type = PROXY_TYPE_ENCODE_NONE; + proto = IPPROTO_TCP; + proxy_port = 0; + server_addr.s_addr = 0; + server_port = 0; + src_addr.s_addr = 0; + IpMask(0, &src_mask); + dst_addr.s_addr = 0; + IpMask(0, &dst_mask); + + str_port[0] = 0; + str_server_port[0] = 0; + +/* Parse command string with state machine */ +#define STATE_READ_KEYWORD 0 +#define STATE_READ_TYPE 1 +#define STATE_READ_PORT 2 +#define STATE_READ_SERVER 3 +#define STATE_READ_RULE 4 +#define STATE_READ_DELETE 5 +#define STATE_READ_PROTO 6 +#define STATE_READ_SRC 7 +#define STATE_READ_DST 8 + state = STATE_READ_KEYWORD; + token = strtok(buffer, " \t"); + token_count = 0; + while (token != NULL) + { + token_count++; + switch (state) + { + case STATE_READ_KEYWORD: + if (strcmp(token, "type") == 0) + state = STATE_READ_TYPE; + else if (strcmp(token, "port") == 0) + state = STATE_READ_PORT; + else if (strcmp(token, "server") == 0) + state = STATE_READ_SERVER; + else if (strcmp(token, "rule") == 0) + state = STATE_READ_RULE; + else if (strcmp(token, "delete") == 0) + state = STATE_READ_DELETE; + else if (strcmp(token, "proto") == 0) + state = STATE_READ_PROTO; + else if (strcmp(token, "src") == 0) + state = STATE_READ_SRC; + else if (strcmp(token, "dst") == 0) + state = STATE_READ_DST; + else + return -1; + break; + + case STATE_READ_TYPE: + if (strcmp(token, "encode_ip_hdr") == 0) + proxy_type = PROXY_TYPE_ENCODE_IPHDR; + else if (strcmp(token, "encode_tcp_stream") == 0) + proxy_type = PROXY_TYPE_ENCODE_TCPSTREAM; + else if (strcmp(token, "no_encode") == 0) + proxy_type = PROXY_TYPE_ENCODE_NONE; + else + return -1; + state = STATE_READ_KEYWORD; + break; + + case STATE_READ_PORT: + strcpy(str_port, token); + state = STATE_READ_KEYWORD; + break; + + case STATE_READ_SERVER: + { + int err; + char *p; + char s[sizeof(buffer)]; + + p = token; + while (*p != ':' && *p != 0) + p++; + + if (*p != ':') + { + err = IpAddr(token, &server_addr); + if (err) + return -1; + } + else + { + *p = ' '; + + n = sscanf(token, "%s %s", s, str_server_port); + if (n != 2) + return -1; + + err = IpAddr(s, &server_addr); + if (err) + return -1; + } + } + state = STATE_READ_KEYWORD; + break; + + case STATE_READ_RULE: + n = sscanf(token, "%d", &rule_index); + if (n != 1 || rule_index < 0) + return -1; + state = STATE_READ_KEYWORD; + break; + + case STATE_READ_DELETE: + { + int err; + int rule_to_delete; + + if (token_count != 2) + return -1; + + n = sscanf(token, "%d", &rule_to_delete); + if (n != 1) + return -1; + err = RuleNumberDelete(rule_to_delete); + if (err) + return -1; + return 0; + } + + case STATE_READ_PROTO: + if (strcmp(token, "tcp") == 0) + proto = IPPROTO_TCP; + else if (strcmp(token, "udp") == 0) + proto = IPPROTO_UDP; + else + return -1; + state = STATE_READ_KEYWORD; + break; + + case STATE_READ_SRC: + case STATE_READ_DST: + { + int err; + char *p; + struct in_addr mask; + struct in_addr addr; + + p = token; + while (*p != '/' && *p != 0) + p++; + + if (*p != '/') + { + IpMask(32, &mask); + err = IpAddr(token, &addr); + if (err) + return -1; + } + else + { + int n; + int nbits; + char s[sizeof(buffer)]; + + *p = ' '; + n = sscanf(token, "%s %d", s, &nbits); + if (n != 2) + return -1; + + err = IpAddr(s, &addr); + if (err) + return -1; + + err = IpMask(nbits, &mask); + if (err) + return -1; + } + + if (state == STATE_READ_SRC) + { + src_addr = addr; + src_mask = mask; + } + else + { + dst_addr = addr; + dst_mask = mask; + } + } + state = STATE_READ_KEYWORD; + break; + + default: + return -1; + break; + } + + token = strtok(NULL, " \t"); + } +#undef STATE_READ_KEYWORD +#undef STATE_READ_TYPE +#undef STATE_READ_PORT +#undef STATE_READ_SERVER +#undef STATE_READ_RULE +#undef STATE_READ_DELETE +#undef STATE_READ_PROTO +#undef STATE_READ_SRC +#undef STATE_READ_DST + +/* Convert port strings to numbers. This needs to be done after + the string is parsed, because the prototype might not be designated + before the ports (which might be symbolic entries in /etc/services) */ + + if (strlen(str_port) != 0) + { + int err; + + err = IpPort(str_port, proto, &proxy_port); + if (err) + return -1; + } + else + { + proxy_port = 0; + } + + if (strlen(str_server_port) != 0) + { + int err; + + err = IpPort(str_server_port, proto, &server_port); + if (err) + return -1; + } + else + { + server_port = 0; + } + +/* Check that at least the server address has been defined */ + if (server_addr.s_addr == 0) + return -1; + +/* Add to linked list */ + proxy_entry = malloc(sizeof(struct proxy_entry)); + if (proxy_entry == NULL) + return -1; + + proxy_entry->proxy_type = proxy_type; + proxy_entry->rule_index = rule_index; + proxy_entry->proto = proto; + proxy_entry->proxy_port = htons(proxy_port); + proxy_entry->server_port = htons(server_port); + proxy_entry->server_addr = server_addr; + proxy_entry->src_addr.s_addr = src_addr.s_addr & src_mask.s_addr; + proxy_entry->dst_addr.s_addr = dst_addr.s_addr & dst_mask.s_addr; + proxy_entry->src_mask = src_mask; + proxy_entry->dst_mask = dst_mask; + + RuleAdd(proxy_entry); + + return 0; +} diff --git a/usr.sbin/ppp/ppp/command.c b/usr.sbin/ppp/ppp/command.c index 4193536e549..c730972fa3f 100644 --- a/usr.sbin/ppp/ppp/command.c +++ b/usr.sbin/ppp/ppp/command.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: command.c,v 1.14 1999/03/04 17:42:25 brian Exp $ + * $Id: command.c,v 1.15 1999/03/08 01:40:23 brian Exp $ * */ #include <sys/param.h> @@ -141,7 +141,7 @@ #define NEG_DNS 52 const char Version[] = "2.11"; -const char VersionDate[] = "$Date: 1999/03/04 17:42:25 $"; +const char VersionDate[] = "$Date: 1999/03/08 01:40:23 $"; static int ShowCommand(struct cmdargs const *); static int TerminalCommand(struct cmdargs const *); @@ -554,6 +554,10 @@ static struct cmdtab const AliasCommands[] = (const void *) PKT_ALIAS_LOG}, {"port", NULL, alias_RedirectPort, LOCAL_AUTH, "port redirection", "alias port [proto addr_local:port_local port_alias]"}, + {"pptp", NULL, alias_Pptp, LOCAL_AUTH, + "Set the PPTP address", "alias pptp IP"}, + {"proxy", NULL, alias_ProxyRule, LOCAL_AUTH, + "proxy control", "alias proxy server host[:port] ..."}, {"same_ports", NULL, AliasOption, LOCAL_AUTH, "try to leave port numbers unchanged", "alias same_ports [yes|no]", (const void *) PKT_ALIAS_SAME_PORTS}, diff --git a/usr.sbin/ppp/ppp/ppp.8 b/usr.sbin/ppp/ppp/ppp.8 index 9069fc1969e..277882d9413 100644 --- a/usr.sbin/ppp/ppp/ppp.8 +++ b/usr.sbin/ppp/ppp/ppp.8 @@ -1,4 +1,4 @@ -.\" $Id: ppp.8,v 1.26 1999/03/07 11:55:26 brian Exp $ +.\" $Id: ppp.8,v 1.27 1999/03/08 01:40:23 brian Exp $ .Dd 20 September 1995 .nr XX \w'\fC00' .Os FreeBSD @@ -184,7 +184,7 @@ is installed as user and group .Dv network , with permissions -.Dv 4554 . +.Dv 04554 . By default, .Nm will not run if the invoking user id is not zero. This may be overridden @@ -2648,6 +2648,22 @@ The .Fl alias command line flag is synonymous with .Dq alias enable yes . +.It alias addr Op Ar addr_local addr_alias +This command allows data for +.Ar addr_alias +to be redirected to +.Ar addr_local . +It is useful if you own a small number of real IP numbers that +you wish to map to specific machines behind your gateway. +.It alias deny_incoming [yes|no] +If set to yes, this command will refuse all incoming connections +by dropping the packets in much the same way as a firewall would. +.It alias help|? +This command gives a summary of available alias commands. +.It alias log [yes|no] +This option causes various aliasing statistics and information to +be logged to the file +.Pa /var/log/alias.log . .It alias port Op Ar proto targetIP:targetPORT [aliasIP:]aliasPORT This command allows us to redirect connections arriving at .Ar aliasPORT @@ -2665,22 +2681,38 @@ or and only connections of the given protocol are matched. This option is useful if you wish to run things like Internet phone on the machines behind your gateway. -.It alias addr Op Ar addr_local addr_alias -This command allows data for -.Ar addr_alias -to be redirected to -.Ar addr_local . -It is useful if you own a small number of real IP numbers that -you wish to map to specific machines behind your gateway. -.It alias deny_incoming [yes|no] -If set to yes, this command will refuse all incoming connections -by dropping the packets in much the same way as a firewall would. -.It alias help|? -This command gives a summary of available alias commands. -.It alias log [yes|no] -This option causes various aliasing statistics and information to -be logged to the file -.Pa /var/log/alias.log . +.It "alias pptp" Op Ar addr +This tells +.Nm +to alias any +.Em G Ns No eneral +.Em R Ns No outing +.Em E Ns No encapsulated +.Pq Dv IPPROTO_GRE +packets using +.Ar addr +rather than the local interface address. This allows the uses of the +.Em P Ns No oint +to +.Em P Ns No oint +.Em T Ns No unneling +.Em P Ns No rotocol +on a machine on the internal network. +.Pp +If +.Ar addr +is not specified, +.Dv PPTP +aliasing is disabled. +.It "alias proxy cmd" Ar arg Ns No ... +This command tells +.Nm +to proxy certain connections, redirecting them to a given server. Refer +to the description of +.Fn PacketAliasProxyRule +in +.Xr libalias 3 +for details of the available commands. .It alias same_ports [yes|no] When enabled, this command will tell the alias library attempt to avoid changing the port number on outgoing packets. This is useful @@ -4241,11 +4273,13 @@ This socket is used to pass links between different instances of .Xr login 1 , .Xr tcpdump 1 , .Xr telnet 1 , +.Xr libalias 3 , .Xr syslog 3 , .Xr uucplock 3 , .Xr crontab 5 , .Xr group 5 , .Xr passwd 5 , +.Xr radius.conf 5 , .Xr resolv.conf 5 , .Xr syslog.conf 5 , .Xr adduser 8 , @@ -4257,7 +4291,6 @@ This socket is used to pass links between different instances of .Xr ping 8 , .Xr pppctl 8 , .Xr pppd 8 , -.Xr radius.conf 5 , .Xr route 8 , .Xr syslogd 8 , .Xr traceroute 8 , |