示例#1
0
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);
}
示例#2
0
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);
	}