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 *)ip_next(pip); hlen = (pip->ip_hl + tc->th_off) << 2; tlen = ntohs(pip->ip_len); dlen = tlen - hlen; /* Verify data length */ if (dlen < (int)(sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds))) return (NULL); /* Move up to PPTP message header */ hptr = (PptpMsgHead) tcp_next(tc); /* 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 < (int)(sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds) + sizeof(struct pptpCodes)))) return (NULL); else return (PptpCallId) (hptr + 1); }
static void AliasHandleSkinny(struct libalias *la, struct ip *pip, struct alias_link *lnk) { size_t hlen, tlen, dlen; struct tcphdr *tc; u_int32_t msgId, t, len, lip; struct skinny_header *sd; size_t orig_len, skinny_hdr_len = sizeof(struct skinny_header); ConvDirection direction; lip = -1; tc = (struct tcphdr *)ip_next(pip); hlen = (pip->ip_hl + tc->th_off) << 2; tlen = ntohs(pip->ip_len); dlen = tlen - hlen; sd = (struct skinny_header *)tcp_next(tc); /* * XXX This direction is reserved for future use. I still need to * handle the scenario where the call manager is on the inside, and * the calling phone is on the global outside. */ if (ntohs(tc->th_dport) == la->skinnyPort) { direction = ClientToServer; } else if (ntohs(tc->th_sport) == la->skinnyPort) { direction = ServerToClient; } else { #ifdef LIBALIAS_DEBUG fprintf(stderr, "PacketAlias/Skinny: Invalid port number, not a Skinny packet\n"); #endif return; } orig_len = dlen; /* * Skinny packets can contain many messages. We need to loop * through the packet using len to determine message boundaries. * This comes into play big time with port messages being in the * same packet as register messages. Also, open receive channel * acks are usually buried in a pakcet some 400 bytes long. */ while (dlen >= skinny_hdr_len) { len = (sd->len); msgId = (sd->msgId); t = len; if (t > orig_len || t > dlen) { #ifdef LIBALIAS_DEBUG fprintf(stderr, "PacketAlias/Skinny: Not a skinny packet, invalid length \n"); #endif return; } switch (msgId) { case REG_MSG: { struct RegisterMessage *reg_mesg; if (len < (int)sizeof(struct RegisterMessage)) { #ifdef LIBALIAS_DEBUG fprintf(stderr, "PacketAlias/Skinny: Not a skinny packet, bad registration message\n"); #endif return; } reg_mesg = (struct RegisterMessage *)&sd->msgId; #ifdef LIBALIAS_DEBUG fprintf(stderr, "PacketAlias/Skinny: Received a register message"); #endif alias_skinny_reg_msg(reg_mesg, pip, tc, lnk, direction); break; } case IP_PORT_MSG: { struct IpPortMessage *port_mesg; if (len < (int)sizeof(struct IpPortMessage)) { #ifdef LIBALIAS_DEBUG fprintf(stderr, "PacketAlias/Skinny: Not a skinny packet, port message\n"); #endif return; } #ifdef LIBALIAS_DEBUG fprintf(stderr, "PacketAlias/Skinny: Received ipport message\n"); #endif port_mesg = (struct IpPortMessage *)&sd->msgId; alias_skinny_port_msg(port_mesg, pip, tc, lnk, direction); break; } case OPNRCVCH_ACK: { struct OpenReceiveChannelAck *opnrcvchn_ack; if (len < (int)sizeof(struct OpenReceiveChannelAck)) { #ifdef LIBALIAS_DEBUG fprintf(stderr, "PacketAlias/Skinny: Not a skinny packet, packet,OpnRcvChnAckMsg\n"); #endif return; } #ifdef LIBALIAS_DEBUG fprintf(stderr, "PacketAlias/Skinny: Received open rcv channel msg\n"); #endif opnrcvchn_ack = (struct OpenReceiveChannelAck *)&sd->msgId; alias_skinny_opnrcvch_ack(la, opnrcvchn_ack, pip, tc, lnk, &lip, direction); break; } case START_MEDIATX: { struct StartMediaTransmission *startmedia_tx; if (len < (int)sizeof(struct StartMediaTransmission)) { #ifdef LIBALIAS_DEBUG fprintf(stderr, "PacketAlias/Skinny: Not a skinny packet,StartMediaTx Message\n"); #endif return; } if (lip == -1) { #ifdef LIBALIAS_DEBUG fprintf(stderr, "PacketAlias/Skinny: received a" " packet,StartMediaTx Message before" " packet,OpnRcvChnAckMsg\n" #endif return; } #ifdef LIBALIAS_DEBUG fprintf(stderr, "PacketAlias/Skinny: Received start media trans msg\n"); #endif startmedia_tx = (struct StartMediaTransmission *)&sd->msgId; alias_skinny_startmedia(startmedia_tx, pip, tc, lnk, lip, direction); break; } default: break; } /* Place the pointer at the next message in the packet. */ dlen -= len + (skinny_hdr_len - sizeof(msgId)); sd = (struct skinny_header *)(((char *)&sd->msgId) + len); }