Linux (user-space) RAW Socket Programming – Generate VOIP SIP UDP PacketsLinux (user-space) RAW Socket Programming – Generate VOIP SIP UDP Packets

Here is the VOIP SIP UDP Packet raw sockets sample source-code discussed in the video:

/*---------- The Linux Channel ------------*/

#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <netpacket/packet.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <getopt.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <malloc.h>
#include <net/ethernet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>

typedef unsigned char  BYTE;    /* 8-bit   */
typedef unsigned short BYTEx2;  /* 16-bit  */

typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;

#define IPHSIZE   20
#define ETHSIZE	14 

enum _Boolean_ { FALSE =0, TRUE  =1 };


static unsigned short in_cksum(u16 *ptr, int nbytes)
{
  register long sum=0;
  u16 oddbyte;
  register u16 answer;

  while(nbytes>1) { sum += *ptr++; nbytes -= 2; }
  if(nbytes == 1) { oddbyte = 0; *((unsigned char *) &oddbyte) = *(unsigned char *)ptr; sum += oddbyte; }
  sum  = (sum >> 16)+(sum & 0xffff); sum+=(sum >> 16); answer = ~sum;
  return(answer);
}

unsigned short magic_tcpudp_cksum(u32 src, u32 dst, u8 proto, u16 len, u8 *hstart)
{
	struct pseudo { u32 src; u32 dst; u8 zero; u8 proto; u16 length;
	} *hdr = (struct pseudo *) (hstart - sizeof(struct pseudo));
	
	hdr->src = src;
	hdr->dst = dst;
	hdr->zero = 0;
	hdr->proto = proto;
	hdr->length = htons(len);
	return in_cksum((u16 *) hdr, len + sizeof(struct pseudo));
}

int create_socket(char *device)
{	int sock_fd;
   struct ifreq ifr;
   struct sockaddr_ll sll;
	memset(&ifr, 0, sizeof(ifr));
   memset(&sll, 0, sizeof(sll));

   sock_fd = socket (PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));

   if(sock_fd == 0) { printf("ERR: socket creation for device: %s\n", device); return FALSE; }
   strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
   if(ioctl(sock_fd, SIOCGIFINDEX, &ifr) == -1) { printf(" ERR: ioctl failed for device: %s\n", device); return FALSE; }
	
	sll.sll_family      = AF_PACKET;
	sll.sll_ifindex     = ifr.ifr_ifindex;
	sll.sll_protocol    = htons(ETH_P_ALL);
	if(bind(sock_fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) { printf("ERR: bind failed for device: %s\n", device); return FALSE; }
  return sock_fd;
}


int main( int argc, char ** argv )
{
BYTE udpsip_request[688]={0x13,0xc4,0x13,0xc4,0x02,0xb0,0x00,0x00,
0x52,0x45,0x47,0x49,0x53,0x54,0x45,0x52,0x20,0x73,0x69,0x70,0x3a,0x73,0x69,0x70,
0x2e,0x63,0x79,0x62,0x65,0x72,0x63,0x69,0x74,0x79,0x2e,0x64,0x6b,0x20,0x53,0x49,
0x50,0x2f,0x32,0x2e,0x30,0x0d,0x0a,0x56,0x69,0x61,0x3a,0x20,0x53,0x49,0x50,0x2f,
0x32,0x2e,0x30,0x2f,0x55,0x44,0x50,0x20,0x31,0x39,0x32,0x2e,0x31,0x36,0x38,0x2e,
0x31,0x2e,0x32,0x3b,0x62,0x72,0x61,0x6e,0x63,0x68,0x3d,0x7a,0x39,0x68,0x47,0x34,
0x62,0x4b,0x6e,0x70,0x31,0x34,0x39,0x35,0x30,0x35,0x31,0x37,0x38,0x2d,0x34,0x33,
0x38,0x63,0x35,0x32,0x38,0x62,0x31,0x39,0x32,0x2e,0x31,0x36,0x38,0x2e,0x31,0x2e,
0x32,0x3b,0x72,0x70,0x6f,0x72,0x74,0x0d,0x0a,0x46,0x72,0x6f,0x6d,0x3a,0x20,0x3c,
0x73,0x69,0x70,0x3a,0x76,0x6f,0x69,0x31,0x38,0x30,0x36,0x33,0x40,0x73,0x69,0x70,
0x2e,0x63,0x79,0x62,0x65,0x72,0x63,0x69,0x74,0x79,0x2e,0x64,0x6b,0x3e,0x3b,0x74,
0x61,0x67,0x3d,0x38,0x65,0x39,0x34,0x38,0x62,0x30,0x0d,0x0a,0x54,0x6f,0x3a,0x20,
0x3c,0x73,0x69,0x70,0x3a,0x76,0x6f,0x69,0x31,0x38,0x30,0x36,0x33,0x40,0x73,0x69,
0x70,0x2e,0x63,0x79,0x62,0x65,0x72,0x63,0x69,0x74,0x79,0x2e,0x64,0x6b,0x3e,0x0d,
0x0a,0x43,0x61,0x6c,0x6c,0x2d,0x49,0x44,0x3a,0x20,0x35,0x37,0x38,0x32,0x32,0x32,
0x37,0x32,0x39,0x2d,0x34,0x36,0x36,0x35,0x64,0x37,0x37,0x35,0x40,0x35,0x37,0x38,
0x32,0x32,0x32,0x37,0x33,0x32,0x2d,0x34,0x36,0x36,0x35,0x64,0x37,0x37,0x32,0x0d,
0x0a,0x43,0x6f,0x6e,0x74,0x61,0x63,0x74,0x3a,0x20,0x20,0x3c,0x73,0x69,0x70,0x3a,
0x76,0x6f,0x69,0x31,0x38,0x30,0x36,0x33,0x40,0x31,0x39,0x32,0x2e,0x31,0x36,0x38,
0x2e,0x31,0x2e,0x32,0x3a,0x35,0x30,0x36,0x30,0x3b,0x6c,0x69,0x6e,0x65,0x3d,0x39,
0x63,0x37,0x64,0x32,0x64,0x62,0x64,0x38,0x38,0x32,0x32,0x30,0x31,0x33,0x63,0x3e,
0x3b,0x65,0x78,0x70,0x69,0x72,0x65,0x73,0x3d,0x31,0x32,0x30,0x30,0x3b,0x71,0x3d,
0x30,0x2e,0x35,0x30,0x30,0x0d,0x0a,0x45,0x78,0x70,0x69,0x72,0x65,0x73,0x3a,0x20,
0x31,0x32,0x30,0x30,0x0d,0x0a,0x43,0x53,0x65,0x71,0x3a,0x20,0x36,0x39,0x20,0x52,
0x45,0x47,0x49,0x53,0x54,0x45,0x52,0x0d,0x0a,0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,
0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,0x30,0x0d,0x0a,0x41,0x75,0x74,0x68,
0x6f,0x72,0x69,0x7a,0x61,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x44,0x69,0x67,0x65,0x73,
0x74,0x20,0x75,0x73,0x65,0x72,0x6e,0x61,0x6d,0x65,0x3d,0x22,0x76,0x6f,0x69,0x31,
0x38,0x30,0x36,0x33,0x22,0x2c,0x72,0x65,0x61,0x6c,0x6d,0x3d,0x22,0x73,0x69,0x70,
0x2e,0x63,0x79,0x62,0x65,0x72,0x63,0x69,0x74,0x79,0x2e,0x64,0x6b,0x22,0x2c,0x75,
0x72,0x69,0x3d,0x22,0x73,0x69,0x70,0x3a,0x31,0x39,0x32,0x2e,0x31,0x36,0x38,0x2e,
0x31,0x2e,0x32,0x22,0x2c,0x6e,0x6f,0x6e,0x63,0x65,0x3d,0x22,0x31,0x37,0x30,0x31,
0x61,0x66,0x35,0x36,0x36,0x62,0x65,0x31,0x38,0x32,0x30,0x37,0x30,0x30,0x38,0x34,
0x63,0x36,0x66,0x37,0x34,0x30,0x37,0x30,0x36,0x62,0x62,0x22,0x2c,0x6f,0x70,0x61,
0x71,0x75,0x65,0x3d,0x22,0x31,0x37,0x30,0x31,0x61,0x31,0x33,0x35,0x31,0x66,0x37,
0x30,0x37,0x39,0x35,0x22,0x2c,0x6e,0x63,0x3d,0x22,0x30,0x30,0x30,0x30,0x30,0x30,
0x30,0x31,0x22,0x2c,0x72,0x65,0x73,0x70,0x6f,0x6e,0x73,0x65,0x3d,0x22,0x62,0x64,
0x37,0x39,0x66,0x65,0x63,0x61,0x65,0x36,0x30,0x30,0x61,0x32,0x65,0x62,0x37,0x39,
0x64,0x33,0x37,0x65,0x63,0x37,0x33,0x32,0x31,0x34,0x38,0x33,0x30,0x62,0x22,0x0d,
0x0a,0x4d,0x61,0x78,0x2d,0x46,0x6f,0x72,0x77,0x61,0x72,0x64,0x73,0x3a,0x20,0x37,
0x30,0x0d,0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67,0x65,0x6e,0x74,0x3a,0x20,0x4e,
0x65,0x72,0x6f,0x20,0x53,0x49,0x50,0x50,0x53,0x20,0x49,0x50,0x20,0x50,0x68,0x6f,
0x6e,0x65,0x20,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x32,0x2e,0x30,0x2e,0x35,
0x31,0x2e,0x31,0x36,0x0d,0x0a,0x0d,0x0a};
BYTE l2[14] = {0x00,0x30,0x54,0x00,0x34,0x56,0x00,0xe0,0xed,0x01,0x6e,0xbd,0x08,0x00};
BYTEx2 new_udp_chksum = 0x0000;
struct iphdr ip;
	memset(&ip, 0x0, IPHSIZE);
	ip.version    = 4;
   ip.ihl        = IPHSIZE >> 2;
   ip.tos        = 0;
   ip.id         = htons(rand()%65535);
   ip.frag_off   = 0;
   ip.ttl        = htons(254);
   ip.protocol   = IPPROTO_UDP;
   ip.saddr      = inet_addr("1.1.1.1");
   ip.daddr      = inet_addr("2.2.2.2"); 
   ip.tot_len    = htons(688+IPHSIZE);

   BYTE buf[1600];
   BYTE *buf_chksum = (BYTE *)(buf+120); //use after few bytes !
   
	memcpy(buf_chksum, udpsip_request,688);
	new_udp_chksum = magic_tcpudp_cksum(ip.saddr, ip.daddr, ip.protocol, (u16)688, (u8 *)buf_chksum);
   memcpy((BYTE *)(udpsip_request+6), &new_udp_chksum, 2);
   ip.check=(unsigned short)in_cksum((unsigned short *)&ip, IPHSIZE);
   
   memcpy(buf, l2, ETHSIZE);
   memcpy(buf+ETHSIZE, &ip, IPHSIZE);
   memcpy(buf+ETHSIZE+IPHSIZE, udpsip_request, 688);
   
   int sock_fd = create_socket(argv[1]);
	if(!(sock_fd) ) { printf("no sock_fd found\n"); return FALSE; }
 
	write(sock_fd, buf, ETHSIZE+IPHSIZE+688);

	return TRUE;
}