Codebase list libfindrtp / 57495544-23c6-4a99-ac64-1fe509bb7dbe/main packet.c
57495544-23c6-4a99-ac64-1fe509bb7dbe/main

Tree @57495544-23c6-4a99-ac64-1fe509bb7dbe/main (Download .tar.gz)

packet.c @57495544-23c6-4a99-ac64-1fe509bb7dbe/mainraw · history · blame

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <pcap.h>
#include "libfindrtp.h"


void _libfindrtp_packet_handler( u_char *null, const struct pcap_pkthdr *h, const u_char *p ) {
	extern unsigned int libfindrtp_debug;
	extern rtp_pair lfr_rp;
	addr_port_pair *addr_port = NULL;
	u_int16_t port = 0;

	/* reject non-IP packets */
	if( (p[12] != 0x08) || (p[13] != 0x00) ) return;

	/* Cisco Skinny (SCCP) */
   port = htons(LIBFINDRTP_SCCP_PORT);
   if( p[23] == 0x06 &&                             // TCP
	    ( (!memcmp( &port, &p[34], 2 )) ||          // Src port is SCCP (or)
         (!memcmp( &port, &p[36], 2 )) ) ) {       // Dst port is SCCP

		if(libfindrtp_debug) printf( "libfindrtp_find_rtp(): Got a SCCP packet, looking for RTP port numbers...\n");

		addr_port = _libfindrtp_parse_sccp_packet( p, h->caplen );

		if( addr_port ) {
			if(libfindrtp_debug) printf( "libfindrtp_find_rtp(): Found RTP port number.\n");

			/* OpenReceiveChannelAck packet */
			if( p[62] == 0x22 ) {
				/* Fill-in side A */
				memcpy( &lfr_rp.ip_a_n, &addr_port->addr, 4 );
				lfr_rp.ip_a = ntohl(lfr_rp.ip_a_n);
				sprintf( lfr_rp.ip_a_a, "%s", inet_ntoa( *((struct in_addr *)&lfr_rp.ip_a_n)) );
				/* Null side B */
				lfr_rp.ip_b_n = lfr_rp.ip_b = 0;
				memset( &lfr_rp.ip_a_a, 0, 16 );
			}

			/* StartMediaTransmission packet */
			if( p[62] == 0x0a ) {
				/* If destination address of packet is same as first side of session */
				if( !memcmp( &lfr_rp.ip_a_n, &p[30], 4) ) {
					/* Fill in side B */
					memcpy( &lfr_rp.ip_b_n, &addr_port->addr, 4 );
					lfr_rp.ip_b = ntohl(lfr_rp.ip_b_n);
					sprintf( lfr_rp.ip_b_a, "%s", inet_ntoa( *((struct in_addr *)&lfr_rp.ip_b_n)) );
				}
			}
		}
	}

	/* SIP */
	port = htons(LIBFINDRTP_SIP_PORT);
	if( p[23] == 0x11 &&                             // UDP
       ( (!memcmp( &port, &p[34], 2 )) ||          // Src port is SIP (or)
	      (!memcmp( &port, &p[36], 2 )) )  ) {      // Dst port is SIP

		if(libfindrtp_debug) printf( "libfindrtp_find_rtp(): Got a SIP packet, looking for SDP/RTP port numbers...\n");

		addr_port = _libfindrtp_parse_sip_packet( p, h->caplen );

		if( addr_port ) {
			if(libfindrtp_debug) printf( "libfindrtp_find_rtp(): Found RTP port number.\n");

			/* struct has no addresses yet */
			if( !lfr_rp.ip_a && !lfr_rp.ip_b ) {
				if(libfindrtp_debug) printf( "No addresses in struct yet...\n" );
				memcpy( &lfr_rp.ip_a_n, &addr_port->addr, 4 );
				lfr_rp.ip_a = ntohl(lfr_rp.ip_a_n);
				sprintf( lfr_rp.ip_a_a, "%s", inet_ntoa( *((struct in_addr *)&lfr_rp.ip_a_n)) );
				memcpy( &lfr_rp.ip_b_n, &p[30], 4 );
				lfr_rp.ip_b = ntohl(lfr_rp.ip_b_n);
				sprintf( lfr_rp.ip_b_a, "%s", inet_ntoa( *((struct in_addr *)&lfr_rp.ip_b_n)) );
			} else
			/* struct has only address a */
			if( !lfr_rp.ip_b ) {
				if(libfindrtp_debug) printf( "Address A still missing in struct...\n" );
				if( !memcmp( &lfr_rp.ip_a_n, &addr_port->addr, 4 ) ) { 
					memcpy( &lfr_rp.ip_b_n, &p[30], 4 );
					lfr_rp.ip_b = ntohl(lfr_rp.ip_b_n);
					sprintf( lfr_rp.ip_b_a, "%s", inet_ntoa( *((struct in_addr *)&lfr_rp.ip_b_n)) );
				} else
				if( !memcmp( &lfr_rp.ip_a_n, &p[30], 4 ) ) {
					memcpy( &lfr_rp.ip_b_n, &addr_port->addr, 4 ); 
					lfr_rp.ip_b = ntohl(lfr_rp.ip_b_n);
					sprintf( lfr_rp.ip_b_a, "%s", inet_ntoa( *((struct in_addr *)&lfr_rp.ip_b_n)) );
				}
			} else 
			/* struct has only address b */
			if( !lfr_rp.ip_a ) {
				if(libfindrtp_debug) printf( "Address B still missing in struct...\n" );
				if( !memcmp( &lfr_rp.ip_b_n, &addr_port->addr, 4 ) ) { 
					memcpy( &lfr_rp.ip_a_n, &p[30], 4 );
					lfr_rp.ip_a = ntohl(lfr_rp.ip_a_n);
					sprintf( lfr_rp.ip_a_a, "%s", inet_ntoa( *((struct in_addr *)&lfr_rp.ip_a_n)) );
				} else
				if( !memcmp( &lfr_rp.ip_b_n, &p[30], 4 ) ) {
					memcpy( &lfr_rp.ip_a_n, &addr_port->addr, 4 ); 
					lfr_rp.ip_a = ntohl(lfr_rp.ip_a_n);
					sprintf( lfr_rp.ip_a_a, "%s", inet_ntoa( *((struct in_addr *)&lfr_rp.ip_a_n)) );
				}
			} 
			
			/* check for IP addresses match in struct for a and b */
			if( !memcmp( &lfr_rp.ip_a_n, &addr_port->addr, 4 ) && !lfr_rp.port_a ) {
				if(libfindrtp_debug) printf( "Found address match for IP A, writing port\n" );
				if( lfr_rp.ip_a_n == lfr_rp.ip_b_n && lfr_rp.port_b_n == addr_port->port ) {
					/* Already have this side of the local connection */
				} else {
					lfr_rp.port_a_n = addr_port->port;
					lfr_rp.port_a = ntohs(addr_port->port);
				}
			}
			if( !memcmp( &lfr_rp.ip_b_n, &addr_port->addr, 4 ) && !lfr_rp.port_b ) {
				if(libfindrtp_debug) printf( "Found address match for IP B, writing port\n" );
				if( lfr_rp.ip_a_n == lfr_rp.ip_b_n && lfr_rp.port_a_n == addr_port->port ) {
					/* Already have this side of the local connection */
				} else {
					lfr_rp.port_b_n = addr_port->port;
					lfr_rp.port_b = ntohs(addr_port->port);
				}
			}
			free(addr_port);
		}
	}

	return;
}