summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrian <brian@cvs.openbsd.org>1999-03-08 01:40:24 +0000
committerbrian <brian@cvs.openbsd.org>1999-03-08 01:40:24 +0000
commit514916901d81186acd389b2eb81ddeff211f0b03 (patch)
tree364f2eb7e436323265748dc31a271a79cbad687d
parentc3d2496b1d90b8d38fbd08d667ceb52f4d41c5cd (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/Makefile16
-rw-r--r--usr.sbin/ppp/ppp/alias.c259
-rw-r--r--usr.sbin/ppp/ppp/alias.h39
-rw-r--r--usr.sbin/ppp/ppp/alias_cmd.c49
-rw-r--r--usr.sbin/ppp/ppp/alias_cmd.h4
-rw-r--r--usr.sbin/ppp/ppp/alias_db.c107
-rw-r--r--usr.sbin/ppp/ppp/alias_local.h75
-rw-r--r--usr.sbin/ppp/ppp/alias_nbt.c215
-rw-r--r--usr.sbin/ppp/ppp/alias_proxy.c801
-rw-r--r--usr.sbin/ppp/ppp/command.c8
-rw-r--r--usr.sbin/ppp/ppp/ppp.871
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 ,