diff options
Diffstat (limited to 'lib/libalias/alias_pptp.c')
-rw-r--r-- | lib/libalias/alias_pptp.c | 480 |
1 files changed, 243 insertions, 237 deletions
diff --git a/lib/libalias/alias_pptp.c b/lib/libalias/alias_pptp.c index 946ae2f..5df60cb 100644 --- a/lib/libalias/alias_pptp.c +++ b/lib/libalias/alias_pptp.c @@ -80,16 +80,16 @@ __FBSDID("$FreeBSD$"); * PPTP definitions */ -struct grehdr /* Enhanced GRE header. */ -{ - u_int16_t gh_flags; /* Flags. */ - u_int16_t gh_protocol; /* Protocol type. */ - u_int16_t gh_length; /* Payload length. */ - u_int16_t gh_call_id; /* Call ID. */ - u_int32_t gh_seq_no; /* Sequence number (optional). */ - u_int32_t gh_ack_no; /* Acknowledgment number (optional). */ +struct grehdr { /* Enhanced GRE header. */ + u_int16_t gh_flags; /* Flags. */ + u_int16_t gh_protocol; /* Protocol type. */ + u_int16_t gh_length; /* Payload length. */ + u_int16_t gh_call_id; /* Call ID. */ + u_int32_t gh_seq_no; /* Sequence number (optional). */ + u_int32_t gh_ack_no; /* Acknowledgment number + * (optional). */ }; -typedef struct grehdr GreHdr; +typedef struct grehdr GreHdr; /* The PPTP protocol ID used in the GRE 'proto' field. */ #define PPTP_GRE_PROTO 0x880b @@ -102,270 +102,276 @@ typedef struct grehdr GreHdr; #define PPTP_CTRL_MSG_TYPE 1 enum { - PPTP_StartCtrlConnRequest = 1, - PPTP_StartCtrlConnReply = 2, - PPTP_StopCtrlConnRequest = 3, - PPTP_StopCtrlConnReply = 4, - PPTP_EchoRequest = 5, - PPTP_EchoReply = 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 + PPTP_StartCtrlConnRequest = 1, + PPTP_StartCtrlConnReply = 2, + PPTP_StopCtrlConnRequest = 3, + PPTP_StopCtrlConnReply = 4, + PPTP_EchoRequest = 5, + PPTP_EchoReply = 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; - /* 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 pptpCodes { - u_int8_t resCode; /* Result Code */ - u_int8_t errCode; /* Error Code */ - }; - typedef struct pptpCodes *PptpCode; - - struct pptpCallIds { - u_int16_t cid1; /* Call ID field #1 */ - u_int16_t cid2; /* Call ID field #2 */ - }; - typedef struct pptpCallIds *PptpCallId; +struct pptpCodes { + u_int8_t resCode;/* Result Code */ + u_int8_t errCode;/* Error Code */ +}; +typedef struct pptpCodes *PptpCode; + +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 *); void AliasHandlePptpOut(struct libalias *la, - struct ip *pip, /* IP packet to examine/patch */ - struct alias_link *link) /* The PPTP control link */ -{ - struct alias_link *pptp_link; - PptpCallId cptr; - PptpCode codes; - 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_OutCallRequest: - case PPTP_OutCallReply: - case PPTP_InCallRequest: - case PPTP_InCallReply: - /* Establish PPTP link for address and Call ID found in control message. */ - pptp_link = AddPptp(la, GetOriginalAddress(link), GetDestAddress(link), - GetAliasAddress(link), cptr->cid1); - break; - case PPTP_CallClearRequest: - case PPTP_CallDiscNotify: - /* Find PPTP link for address and Call ID found in control message. */ - pptp_link = FindPptpOutByCallId(la, GetOriginalAddress(link), - GetDestAddress(link), - cptr->cid1); - break; - default: - return; - } - - if (pptp_link != NULL) { - int accumulate = cptr->cid1; - - /* alias the Call Id */ - cptr->cid1 = GetAliasPort(pptp_link); - - /* Compute TCP checksum for revised packet */ - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - accumulate -= cptr->cid1; - ADJUST_CHECKSUM(accumulate, tc->th_sum); - + struct ip *pip, /* IP packet to examine/patch */ + struct alias_link *link) +{ /* The PPTP control link */ + struct alias_link *pptp_link; + PptpCallId cptr; + PptpCode codes; + 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_OutCallRequest: case PPTP_OutCallReply: + case PPTP_InCallRequest: case PPTP_InCallReply: - codes = (PptpCode)(cptr + 1); - if (codes->resCode == 1) /* Connection established, */ - SetDestCallId(pptp_link, /* note the Peer's Call ID. */ - cptr->cid2); - else - SetExpire(pptp_link, 0); /* Connection refused. */ - break; - case PPTP_CallDiscNotify: /* Connection closed. */ - SetExpire(pptp_link, 0); - break; + /* + * Establish PPTP link for address and Call ID found in + * control message. + */ + pptp_link = AddPptp(la, GetOriginalAddress(link), GetDestAddress(link), + GetAliasAddress(link), cptr->cid1); + break; + case PPTP_CallClearRequest: + case PPTP_CallDiscNotify: + /* + * Find PPTP link for address and Call ID found in control + * message. + */ + pptp_link = FindPptpOutByCallId(la, GetOriginalAddress(link), + GetDestAddress(link), + cptr->cid1); + break; + default: + return; + } + + if (pptp_link != NULL) { + int accumulate = cptr->cid1; + + /* alias the Call Id */ + cptr->cid1 = GetAliasPort(pptp_link); + + /* Compute TCP checksum for revised packet */ + tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2)); + accumulate -= cptr->cid1; + ADJUST_CHECKSUM(accumulate, tc->th_sum); + + switch (ctl_type) { + case PPTP_OutCallReply: + case PPTP_InCallReply: + codes = (PptpCode) (cptr + 1); + if (codes->resCode == 1) /* Connection + * established, */ + SetDestCallId(pptp_link, /* note the Peer's Call + * ID. */ + cptr->cid2); + else + SetExpire(pptp_link, 0); /* Connection refused. */ + break; + case PPTP_CallDiscNotify: /* Connection closed. */ + SetExpire(pptp_link, 0); + break; + } } - } } void -AliasHandlePptpIn(struct libalias *la, - struct ip *pip, /* IP packet to examine/patch */ - struct alias_link *link) /* The PPTP control link */ -{ - struct alias_link *pptp_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; - case PPTP_CallDiscNotify: /* Connection closed. */ - pptp_link = FindPptpInByCallId(la, GetDestAddress(link), - GetAliasAddress(link), - cptr->cid1); - if (pptp_link != NULL) - SetExpire(pptp_link, 0); - return; - default: - return; - } - - /* Find PPTP link for address and Call ID found in PPTP Control Msg */ - pptp_link = FindPptpInByPeerCallId(la, GetDestAddress(link), - GetAliasAddress(link), - *pcall_id); - - if (pptp_link != NULL) { - int accumulate = *pcall_id; - - /* De-alias the Peer's Call Id. */ - *pcall_id = GetOriginalPort(pptp_link); - - /* Compute TCP checksum for modified packet */ - tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2)); - accumulate -= *pcall_id; - ADJUST_CHECKSUM(accumulate, tc->th_sum); - - if (ctl_type == PPTP_OutCallReply || ctl_type == PPTP_InCallReply) { - PptpCode codes = (PptpCode)(cptr + 1); - - if (codes->resCode == 1) /* Connection established, */ - SetDestCallId(pptp_link, /* note the Call ID. */ - cptr->cid1); - else - SetExpire(pptp_link, 0); /* Connection refused. */ - } - } +AliasHandlePptpIn(struct libalias *la, + struct ip *pip, /* IP packet to examine/patch */ + struct alias_link *link) +{ /* The PPTP control link */ + struct alias_link *pptp_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; + case PPTP_CallDiscNotify: /* Connection closed. */ + pptp_link = FindPptpInByCallId(la, GetDestAddress(link), + GetAliasAddress(link), + cptr->cid1); + if (pptp_link != NULL) + SetExpire(pptp_link, 0); + return; + default: + return; + } + + /* Find PPTP link for address and Call ID found in PPTP Control Msg */ + pptp_link = FindPptpInByPeerCallId(la, GetDestAddress(link), + GetAliasAddress(link), + *pcall_id); + + if (pptp_link != NULL) { + int accumulate = *pcall_id; + + /* De-alias the Peer's Call Id. */ + *pcall_id = GetOriginalPort(pptp_link); + + /* Compute TCP checksum for modified packet */ + tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2)); + accumulate -= *pcall_id; + ADJUST_CHECKSUM(accumulate, tc->th_sum); + + if (ctl_type == PPTP_OutCallReply || ctl_type == PPTP_InCallReply) { + PptpCode codes = (PptpCode) (cptr + 1); + + if (codes->resCode == 1) /* Connection + * established, */ + SetDestCallId(pptp_link, /* note the Call ID. */ + cptr->cid1); + else + SetExpire(pptp_link, 0); /* Connection refused. */ + } + } } -static 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); - - /* Verify data length. */ - if ((*ptype == PPTP_OutCallReply || *ptype == PPTP_InCallReply) && - (dlen < sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds) + - sizeof(struct pptpCodes))) - return (NULL); - else - return (PptpCallId)(hptr + 1); +static 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); + + /* Verify data length. */ + if ((*ptype == PPTP_OutCallReply || *ptype == PPTP_InCallReply) && + (dlen < sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds) + + sizeof(struct pptpCodes))) + return (NULL); + else + return (PptpCallId) (hptr + 1); } int AliasHandlePptpGreOut(struct libalias *la, struct ip *pip) { - GreHdr *gr; - struct alias_link *link; - - gr = (GreHdr *)((char *)pip + (pip->ip_hl << 2)); + GreHdr *gr; + struct alias_link *link; - /* Check GRE header bits. */ - if ((ntohl(*((u_int32_t *)gr)) & PPTP_INIT_MASK) != PPTP_INIT_VALUE) - return (-1); + gr = (GreHdr *) ((char *)pip + (pip->ip_hl << 2)); - link = FindPptpOutByPeerCallId(la, pip->ip_src, pip->ip_dst, gr->gh_call_id); - if (link != NULL) { - struct in_addr alias_addr = GetAliasAddress(link); + /* Check GRE header bits. */ + if ((ntohl(*((u_int32_t *) gr)) & PPTP_INIT_MASK) != PPTP_INIT_VALUE) + return (-1); - /* Change source IP address. */ - DifferentialChecksum(&pip->ip_sum, - (u_short *)&alias_addr, - (u_short *)&pip->ip_src, - 2); - pip->ip_src = alias_addr; - } + link = FindPptpOutByPeerCallId(la, pip->ip_src, pip->ip_dst, gr->gh_call_id); + if (link != NULL) { + struct in_addr alias_addr = GetAliasAddress(link); - return (0); + /* Change source IP address. */ + DifferentialChecksum(&pip->ip_sum, + (u_short *) & alias_addr, + (u_short *) & pip->ip_src, + 2); + pip->ip_src = alias_addr; + } + return (0); } int AliasHandlePptpGreIn(struct libalias *la, struct ip *pip) { - GreHdr *gr; - struct alias_link *link; - - gr = (GreHdr *)((char *)pip + (pip->ip_hl << 2)); + GreHdr *gr; + struct alias_link *link; - /* Check GRE header bits. */ - if ((ntohl(*((u_int32_t *)gr)) & PPTP_INIT_MASK) != PPTP_INIT_VALUE) - return (-1); + gr = (GreHdr *) ((char *)pip + (pip->ip_hl << 2)); - link = FindPptpInByPeerCallId(la, pip->ip_src, pip->ip_dst, gr->gh_call_id); - if (link != NULL) { - struct in_addr src_addr = GetOriginalAddress(link); + /* Check GRE header bits. */ + if ((ntohl(*((u_int32_t *) gr)) & PPTP_INIT_MASK) != PPTP_INIT_VALUE) + return (-1); - /* De-alias the Peer's Call Id. */ - gr->gh_call_id = GetOriginalPort(link); + link = FindPptpInByPeerCallId(la, pip->ip_src, pip->ip_dst, gr->gh_call_id); + if (link != NULL) { + struct in_addr src_addr = GetOriginalAddress(link); - /* Restore original IP address. */ - DifferentialChecksum(&pip->ip_sum, - (u_short *)&src_addr, - (u_short *)&pip->ip_dst, - 2); - pip->ip_dst = src_addr; - } + /* De-alias the Peer's Call Id. */ + gr->gh_call_id = GetOriginalPort(link); - return (0); + /* Restore original IP address. */ + DifferentialChecksum(&pip->ip_sum, + (u_short *) & src_addr, + (u_short *) & pip->ip_dst, + 2); + pip->ip_dst = src_addr; + } + return (0); } |