From ee3c5d1c8dc4929f4d288d49eb0c5287d0b708a8 Mon Sep 17 00:00:00 2001 From: ru Date: Tue, 20 Jun 2000 11:41:48 +0000 Subject: Added true support for PPTP aliasing. Some nice features include: - Multiple PPTP clients behind NAT to the same or different servers. - Single PPTP server behind NAT -- you just need to redirect TCP port 1723 to a local machine. Multiple servers behind NAT is possible but would require a simple API change. - No API changes! For more information on how this works see comments at the start of the alias_pptp.c. PacketAliasPptp() is no longer necessary and will be removed soon. Submitted by: Erik Salander Reviewed by: ru Rewritten by: ru Reviewed by: Erik Salander --- sys/netinet/libalias/HISTORY | 5 + sys/netinet/libalias/Makefile | 2 +- sys/netinet/libalias/alias.c | 59 +++++++- sys/netinet/libalias/alias_db.c | 74 +++++++++- sys/netinet/libalias/alias_local.h | 12 ++ sys/netinet/libalias/alias_pptp.c | 279 +++++++++++++++++++++++++++++++++++++ sys/netinet/libalias/libalias.3 | 2 + 7 files changed, 422 insertions(+), 11 deletions(-) create mode 100644 sys/netinet/libalias/alias_pptp.c (limited to 'sys/netinet/libalias') diff --git a/sys/netinet/libalias/HISTORY b/sys/netinet/libalias/HISTORY index f26299c..8760d92 100644 --- a/sys/netinet/libalias/HISTORY +++ b/sys/netinet/libalias/HISTORY @@ -134,3 +134,8 @@ Version 3.0: January 1, 1999 - Transparent proxying support added. - PPTP redirecting support added based on patches contributed by Dru Nelson . + +Version 3.1: May, 2000 (Erik Salander, erik@whistle.com) + - Added support to alias 227 replies, allows aliasing for + FTP servers in passive mode. + - Added support for PPTP aliasing. diff --git a/sys/netinet/libalias/Makefile b/sys/netinet/libalias/Makefile index 05411f5..3208014 100644 --- a/sys/netinet/libalias/Makefile +++ b/sys/netinet/libalias/Makefile @@ -5,7 +5,7 @@ SHLIB_MAJOR= 3 SHLIB_MINOR= 0 CFLAGS+= -Wall -I${.CURDIR} SRCS= alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \ - alias_nbt.c alias_proxy.c alias_util.c + alias_nbt.c alias_pptp.c alias_proxy.c alias_util.c INCS= alias.h MAN3= libalias.3 diff --git a/sys/netinet/libalias/alias.c b/sys/netinet/libalias/alias.c index eaaedac..e4770fe 100644 --- a/sys/netinet/libalias/alias.c +++ b/sys/netinet/libalias/alias.c @@ -76,6 +76,9 @@ Version 2.3 Dec 1998 (dillon) - Major bounds checking additions, see FreeBSD/CVS + Version 3.1 May, 2000 (eds) + - Added hooks to handle PPTP. + See HISTORY file for additional revisions. $FreeBSD$ @@ -90,12 +93,6 @@ #include #include -#ifndef IPPROTO_GRE -#define IPPROTO_GRE 47 -#define IPPROTO_ESP 50 -#define IPPROTO_AH 51 -#endif - #include "alias_local.h" #include "alias.h" @@ -105,6 +102,7 @@ #define IRC_CONTROL_PORT_NUMBER_1 6667 #define IRC_CONTROL_PORT_NUMBER_2 6668 #define CUSEEME_PORT_NUMBER 7648 +#define PPTP_CONTROL_PORT_NUMBER 1723 @@ -181,6 +179,7 @@ TcpMonitorOut(struct ip *pip, struct alias_link *link) ProtoAliasIn(), ProtoAliasOut() UdpAliasIn(), UdpAliasOut() TcpAliasIn(), TcpAliasOut() + GreAliasIn() These routines handle protocol specific details of packet aliasing. One may observe a certain amount of repetitive arithmetic in these @@ -234,6 +233,8 @@ static int UdpAliasIn (struct ip *); static int TcpAliasOut(struct ip *, int); static int TcpAliasIn (struct ip *); +static int GreAliasIn(struct ip *); + static int IcmpAliasIn1(struct ip *pip) @@ -725,6 +726,39 @@ ProtoAliasOut(struct ip *pip) } +static int +GreAliasIn(struct ip *pip) +{ + u_short call_id; + struct alias_link *link; + +/* Return if proxy-only mode is enabled. */ + if (packetAliasMode & PKT_ALIAS_PROXY_ONLY) + return (PKT_ALIAS_OK); + + if (PptpGetCallID(pip, &call_id)) { + if ((link = FindPptpIn(pip->ip_src, pip->ip_dst, call_id)) != NULL) { + struct in_addr alias_address; + struct in_addr original_address; + + alias_address = GetAliasAddress(link); + original_address = GetOriginalAddress(link); + PptpSetCallID(pip, GetOriginalPort(link)); + + /* Restore original IP address. */ + DifferentialChecksum(&pip->ip_sum, + (u_short *)&original_address, + (u_short *)&pip->ip_dst, + 2); + pip->ip_dst = original_address; + + return (PKT_ALIAS_OK); + } else + return (PKT_ALIAS_IGNORED); + } else + return ProtoAliasIn(pip); +} + static int UdpAliasIn(struct ip *pip) @@ -903,6 +937,11 @@ TcpAliasIn(struct ip *pip) int accumulate; u_short *sptr; +/* Special processing for IP encoding protocols */ + if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER + || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER) + AliasHandlePptpIn(pip, link); + alias_address = GetAliasAddress(link); original_address = GetOriginalAddress(link); proxy_address = GetProxyAddress(link); @@ -1070,9 +1109,12 @@ TcpAliasOut(struct ip *pip, int maxpacketsize) 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 + else if (ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_1 || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2) AliasHandleIrcOut(pip, link, maxpacketsize); + else if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER + || ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER) + AliasHandlePptpOut(pip, link); /* Adjust TCP checksum since source port is being aliased */ /* and source address is being altered */ @@ -1301,6 +1343,9 @@ PacketAliasIn(char *ptr, int maxpacketsize) case IPPROTO_TCP: iresult = TcpAliasIn(pip); break; + case IPPROTO_GRE: + iresult = GreAliasIn(pip); + break; default: iresult = ProtoAliasIn(pip); break; diff --git a/sys/netinet/libalias/alias_db.c b/sys/netinet/libalias/alias_db.c index 211a7c2..408fcdd 100644 --- a/sys/netinet/libalias/alias_db.c +++ b/sys/netinet/libalias/alias_db.c @@ -147,6 +147,7 @@ /* Timeouts (in seconds) for different link types */ #define ICMP_EXPIRE_TIME 60 #define UDP_EXPIRE_TIME 60 +#define PPTP_EXPIRE_TIME 60 #define PROTO_EXPIRE_TIME 60 #define FRAGMENT_ID_EXPIRE_TIME 10 #define FRAGMENT_PTR_EXPIRE_TIME 30 @@ -265,6 +266,7 @@ struct alias_link /* Main data structure */ #define LINK_FRAGMENT_ID (IPPROTO_MAX + 1) #define LINK_FRAGMENT_PTR (IPPROTO_MAX + 2) #define LINK_ADDR (IPPROTO_MAX + 3) +#define LINK_PPTP (IPPROTO_MAX + 4) int flags; /* indicates special characteristics */ @@ -329,6 +331,7 @@ linkTableIn[LINK_TABLE_IN_SIZE]; /* into input and output lookup */ static int icmpLinkCount; /* Link statistics */ static int udpLinkCount; static int tcpLinkCount; +static int pptpLinkCount; static int protoLinkCount; static int fragmentIdLinkCount; static int fragmentPtrLinkCount; @@ -455,10 +458,11 @@ ShowAliasStats(void) if (monitorFile) { - fprintf(monitorFile, "icmp=%d, udp=%d, tcp=%d, proto=%d, frag_id=%d frag_ptr=%d", + fprintf(monitorFile, "icmp=%d, udp=%d, tcp=%d, pptp=%d, proto=%d, frag_id=%d frag_ptr=%d", icmpLinkCount, udpLinkCount, tcpLinkCount, + pptpLinkCount, protoLinkCount, fragmentIdLinkCount, fragmentPtrLinkCount); @@ -466,6 +470,7 @@ ShowAliasStats(void) fprintf(monitorFile, " / tot=%d (sock=%d)\n", icmpLinkCount + udpLinkCount + tcpLinkCount + + pptpLinkCount + protoLinkCount + fragmentIdLinkCount + fragmentPtrLinkCount, @@ -550,7 +555,7 @@ GetNewPort(struct alias_link *link, int alias_port_param) the port number. GetNewPort() will return this number without check that it is in use. - When this parameter is -1, it indicates to get a randomly + When this parameter is GET_ALIAS_PORT, it indicates to get a randomly selected port number. */ @@ -618,7 +623,9 @@ GetNewPort(struct alias_link *link, int alias_port_param) if (go_ahead) { if ((packetAliasMode & PKT_ALIAS_USE_SOCKETS) - && (link->flags & LINK_PARTIALLY_SPECIFIED)) + && (link->flags & LINK_PARTIALLY_SPECIFIED) + && ((link->link_type == LINK_TCP) || + (link->link_type == LINK_UDP))) { if (GetSocket(port_net, &link->sockfd, link->link_type)) { @@ -838,6 +845,9 @@ DeleteLink(struct alias_link *link) if (link->data.tcp != NULL) free(link->data.tcp); break; + case LINK_PPTP: + pptpLinkCount--; + break; case LINK_FRAGMENT_ID: fragmentIdLinkCount--; break; @@ -906,6 +916,9 @@ AddLink(struct in_addr src_addr, case LINK_TCP: link->expire_time = TCP_EXPIRE_INITIAL; break; + case LINK_PPTP: + link->expire_time = PPTP_EXPIRE_TIME; + break; case LINK_FRAGMENT_ID: link->expire_time = FRAGMENT_ID_EXPIRE_TIME; break; @@ -994,6 +1007,9 @@ AddLink(struct in_addr src_addr, #endif } break; + case LINK_PPTP: + pptpLinkCount++; + break; case LINK_FRAGMENT_ID: fragmentIdLinkCount++; break; @@ -1307,6 +1323,7 @@ FindLinkIn(struct in_addr dst_addr, AddFragmentPtrLink(), FindFragmentPtr() FindProtoIn(), FindProtoOut() FindUdpTcpIn(), FindUdpTcpOut() + FindPptpIn(), FindPptpOut() FindOriginalAddress(), FindAliasAddress() (prototypes in alias_local.h) @@ -1533,6 +1550,56 @@ FindUdpTcpOut(struct in_addr src_addr, } +struct alias_link * +FindPptpIn(struct in_addr dst_addr, + struct in_addr alias_addr, + u_short call_id) +{ + struct alias_link *link; + + link = FindLinkIn(dst_addr, alias_addr, + NO_DEST_PORT, call_id, + LINK_PPTP, 1); + + if (link == NULL && !(packetAliasMode & PKT_ALIAS_DENY_INCOMING)) + { + struct in_addr target_addr; + + target_addr = FindOriginalAddress(alias_addr); + link = AddLink(target_addr, dst_addr, alias_addr, + call_id, NO_DEST_PORT, call_id, + LINK_PPTP); + } + + return(link); +} + + +struct alias_link * +FindPptpOut(struct in_addr src_addr, + struct in_addr dst_addr, + u_short call_id) +{ + struct alias_link *link; + + link = FindLinkOut(src_addr, dst_addr, + call_id, NO_DEST_PORT, + LINK_PPTP, 1); + + if (link == NULL) + { + struct in_addr alias_addr; + + alias_addr = FindAliasAddress(src_addr); + link = AddLink(src_addr, dst_addr, alias_addr, + call_id, NO_DEST_PORT, GET_ALIAS_PORT, + LINK_PPTP); + } + + return(link); +} + + struct in_addr FindOriginalAddress(struct in_addr alias_addr) { @@ -2308,6 +2375,7 @@ PacketAliasInit(void) icmpLinkCount = 0; udpLinkCount = 0; tcpLinkCount = 0; + pptpLinkCount = 0; protoLinkCount = 0; fragmentIdLinkCount = 0; fragmentPtrLinkCount = 0; diff --git a/sys/netinet/libalias/alias_local.h b/sys/netinet/libalias/alias_local.h index 783f6b2..439c9ea 100644 --- a/sys/netinet/libalias/alias_local.h +++ b/sys/netinet/libalias/alias_local.h @@ -107,6 +107,12 @@ FindUdpTcpIn (struct in_addr, struct in_addr, u_short, u_short, u_char); struct alias_link * FindUdpTcpOut(struct in_addr, struct in_addr, u_short, u_short, u_char); +struct alias_link * +FindPptpIn(struct in_addr, struct in_addr, u_short); + +struct alias_link * +FindPptpOut(struct in_addr, struct in_addr, u_short); + struct in_addr FindOriginalAddress(struct in_addr); @@ -159,6 +165,12 @@ void AliasHandleFtpOut(struct ip *, struct alias_link *, int); /* IRC routines */ void AliasHandleIrcOut(struct ip *, struct alias_link *, int); +/* PPTP routines */ +int PptpGetCallID(struct ip *, u_short *); +void PptpSetCallID(struct ip *, u_short); +void AliasHandlePptpOut(struct ip *, struct alias_link *); +void AliasHandlePptpIn(struct ip *, struct alias_link *); + /* 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 *); diff --git a/sys/netinet/libalias/alias_pptp.c b/sys/netinet/libalias/alias_pptp.c new file mode 100644 index 0000000..822cfa6 --- /dev/null +++ b/sys/netinet/libalias/alias_pptp.c @@ -0,0 +1,279 @@ +/* + * alias_pptp.c + * + * Copyright (c) 2000 Whistle Communications, Inc. + * All rights reserved. + * + * Subject to the following obligations and disclaimer of warranty, use and + * redistribution of this software, in source or object code forms, with or + * without modifications are expressly permitted by Whistle Communications; + * provided, however, that: + * 1. Any and all reproductions of the source or object code must include the + * copyright notice above and the following disclaimer of warranties; and + * 2. No rights are granted, in any manner or form, to use Whistle + * Communications, Inc. trademarks, including the mark "WHISTLE + * COMMUNICATIONS" on advertising, endorsements, or otherwise except as + * such appears in the above copyright notice or in the software. + * + * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND + * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO + * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, + * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY + * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS + * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. + * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES + * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING + * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Erik Salander + * + * $FreeBSD$ + */ + +/* + Alias_pptp.c performs special processing for PPTP sessions under TCP. + Specifically, watch PPTP control messages and alias the Call ID or the + Peer's Call ID in the appropriate messages. Note, PPTP requires + "de-aliasing" of incoming packets, this is different than any other + TCP applications that are currently (ie. FTP, IRC and RTSP) aliased. + + For Call IDs encountered for the first time, a GRE alias link is created. + The GRE alias link uses the Call ID in place of the original port number. + An alias Call ID is created. + + For this routine to work, the PPTP control messages must fit entirely + into a single TCP packet. This is typically the case, but is not + required by the spec. + + Unlike some of the other TCP applications that are aliased (ie. FTP, + IRC and RTSP), the PPTP control messages that need to be aliased are + guaranteed to remain the same length. The aliased Call ID is a fixed + length field. + + Reference: RFC 2637 + + Initial version: May, 2000 (eds) + +*/ + +/* Includes */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "alias_local.h" + +/* + * PPTP definitions + */ + +struct grehdr /* Enhanced GRE header. */ +{ + u_char gh_recursion:3, /* Recursion control. */ + gh_ssr_flag:1, /* Strict source route present. */ + gh_seq_no_flag:1, /* Sequence number present. */ + gh_key_flag:1, /* Key present. */ + gh_rt_flag:1, /* Routing present. */ + gh_cksum_flag:1; /* Checksum present. */ + u_char gh_version:3, /* GRE version. */ + gh_flags:4, /* Flags. */ + gh_ack_no_flag:1; /* Acknowledgment sequence number present. */ + u_short gh_protocol; /* Protocol type. */ + u_short gh_length; /* Payload length. */ + u_short gh_call_id; /* Call ID. */ + u_int32_t gh_seq_no; /* Sequence number (optional). */ + u_int32_t gh_ack_no; /* Acknowledgment number (optional). */ +}; + +/* The PPTP protocol ID used in the GRE 'proto' field. */ +#define PPTP_GRE_PROTO 0x880b + +/* Bits that must be set a certain way in all PPTP/GRE packets. */ +#define PPTP_INIT_VALUE ((0x2001 << 16) | PPTP_GRE_PROTO) +#define PPTP_INIT_MASK 0xef7fffff + +#define PPTP_MAGIC 0x1a2b3c4d +#define PPTP_CTRL_MSG_TYPE 1 + +enum { + PPTP_StartCtrlConnRequest = 1, + PPTP_StartCtrlConnReply = 2, + PPTP_StopCtrlConnRequest = 3, + PPTP_StopCtrlConnReply = 4, + PPTP_EchoRequest = 5, + PPTP_statoReply = 6, + PPTP_OutCallRequest = 7, + PPTP_OutCallReply = 8, + PPTP_InCallRequest = 9, + PPTP_InCallReply = 10, + PPTP_InCallConn = 11, + PPTP_CallClearRequest = 12, + PPTP_CallDiscNotify = 13, + PPTP_WanErrorNotify = 14, + PPTP_SetLinkInfo = 15, +}; + + /* Message structures */ + struct pptpMsgHead { + u_int16_t length; /* total length */ + u_int16_t msgType; /* PPTP message type */ + u_int32_t magic; /* magic cookie */ + u_int16_t type; /* control message type */ + u_int16_t resv0; /* reserved */ + }; + typedef struct pptpMsgHead *PptpMsgHead; + + struct pptpCallIds { + u_int16_t cid1; /* Call ID field #1 */ + u_int16_t cid2; /* Call ID field #2 */ + }; + typedef struct pptpCallIds *PptpCallId; + +static PptpCallId AliasVerifyPptp(struct ip *, u_int16_t *); + +int +PptpGetCallID(struct ip *pip, + u_short *call_id) +{ + struct grehdr *gr; + + gr = (struct grehdr *)((char *)pip + (pip->ip_hl << 2)); + + /* Check GRE header bits. */ + if ((ntohl(*((u_int32_t *)gr)) & PPTP_INIT_MASK) == PPTP_INIT_VALUE) { + *call_id = gr->gh_call_id; + return 1; + } else + return 0; +}; + +void PptpSetCallID(struct ip *pip, u_short call_id) +{ + struct grehdr *gr; + + gr = (struct grehdr *)((char *)pip + (pip->ip_hl << 2)); + gr->gh_call_id = call_id; +}; + +void +AliasHandlePptpOut(struct ip *pip, /* IP packet to examine/patch */ + struct alias_link *link) /* The PPTP control link */ +{ + struct alias_link *gre_link; + PptpCallId cptr; + u_int16_t ctl_type; /* control message type */ + struct tcphdr *tc; + + /* Verify valid PPTP control message */ + if ((cptr = AliasVerifyPptp(pip, &ctl_type)) == NULL) + return; + + /* Modify certain PPTP messages */ + if ((ctl_type >= PPTP_OutCallRequest) && + (ctl_type <= PPTP_CallDiscNotify)) { + + /* Establish GRE link for address and Call ID found in PPTP Control Msg */ + gre_link = FindPptpOut(GetOriginalAddress(link), GetDestAddress(link), + cptr->cid1); + + if (gre_link != NULL) { + /* alias the Call Id */ + cptr->cid1 = GetAliasPort(gre_link); + + /* Compute TCP checksum for revised packet */ + tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); + tc->th_sum = 0; + tc->th_sum = TcpChecksum(pip); + } + } +} + +void +AliasHandlePptpIn(struct ip *pip, /* IP packet to examine/patch */ + struct alias_link *link) /* The PPTP control link */ +{ + struct alias_link *gre_link; + PptpCallId cptr; + u_int16_t *pcall_id; + u_int16_t ctl_type; /* control message type */ + struct tcphdr *tc; + + /* Verify valid PPTP control message */ + if ((cptr = AliasVerifyPptp(pip, &ctl_type)) == NULL) + return; + + /* Modify certain PPTP messages */ + switch (ctl_type) + { + case PPTP_InCallConn: + case PPTP_WanErrorNotify: + case PPTP_SetLinkInfo: + pcall_id = &cptr->cid1; + break; + case PPTP_OutCallReply: + case PPTP_InCallReply: + pcall_id = &cptr->cid2; + break; + default: + return; + break; + } + + /* Find GRE link for address and Call ID found in PPTP Control Msg */ + gre_link = FindPptpIn(GetDestAddress(link), GetAliasAddress(link), + *pcall_id); + + if (gre_link != NULL) { + /* alias the Call Id */ + *pcall_id = GetOriginalPort(gre_link); + + /* Compute TCP checksum for modified packet */ + tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); + tc->th_sum = 0; + tc->th_sum = TcpChecksum(pip); + } +} + +PptpCallId +AliasVerifyPptp(struct ip *pip, u_int16_t *ptype) /* IP packet to examine/patch */ +{ + int hlen, tlen, dlen; + PptpMsgHead hptr; + struct tcphdr *tc; + + /* Calculate some lengths */ + tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); + hlen = (pip->ip_hl + tc->th_off) << 2; + tlen = ntohs(pip->ip_len); + dlen = tlen - hlen; + + /* Verify data length */ + if (dlen < (sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds))) + return(NULL); + + /* Move up to PPTP message header */ + hptr = (PptpMsgHead)(((char *) pip) + hlen); + + /* Return the control message type */ + *ptype = ntohs(hptr->type); + + /* Verify PPTP Control Message */ + if ((ntohs(hptr->msgType) != PPTP_CTRL_MSG_TYPE) || + (ntohl(hptr->magic) != PPTP_MAGIC)) + return(NULL); + else + return((PptpCallId)(((char *)hptr) + sizeof(struct pptpMsgHead))); +} diff --git a/sys/netinet/libalias/libalias.3 b/sys/netinet/libalias/libalias.3 index 3b69983..53c0d6b 100644 --- a/sys/netinet/libalias/libalias.3 +++ b/sys/netinet/libalias/libalias.3 @@ -835,6 +835,8 @@ versions 1.0 - 1.8, 2.0 - 2.4. versions 1.8b, 1.9 and 2.5. Added IRC DCC support as well as contributing a number of architectural improvements; added the firewall bypass for FTP/IRC DCC. +.An Erik Salander Aq erik@whistle.com +added support for PPTP. .Sh ACKNOWLEDGMENTS Listed below, in approximate chronological order, are individuals who have provided valuable comments and/or debugging assistance. -- cgit v1.1