HOMECOURSESSTUDENTSDONATIONSVIDEOSEVENTSTUTORIALSLINKSNEWSCONTACT


VIDEOS 》 Linux (user-space) RAW Socket Programming

Download quic.c raw sockets sample source-code discussed in the video HERE. And here is the same source code for a quick reference.

/*---------- 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;
}

void main(int argc, char ** argv)
{
BYTE quic[631]={0x01,0xbb,0xe1,0x50,0x02,0x77,0x00,0x00,
0x00,0x3e,0x86,0x1c,0x84,0x90,0x8f,0xc9,0x3f,0xd1,0xdc,0x58,0x2d,0xde,0xd4,0x3c,
0x00,0xc6,0x50,0xa9,0x80,0xfd,0xac,0xa8,0x84,0x20,0x77,0x1b,0x10,0x2e,0x3d,0x1b,
0xee,0x1a,0x7c,0xc8,0x8d,0xe9,0x1e,0x5f,0x95,0x1a,0xb6,0xcd,0x8c,0x2d,0x1f,0xc4,
0x7b,0xeb,0xa6,0x1b,0x8a,0x35,0x4b,0xc0,0x68,0x49,0x81,0x1f,0xc3,0xd4,0x54,0x08,
0xee,0x6b,0x41,0xe1,0x0f,0x77,0x27,0x35,0xc4,0xd9,0xd1,0x78,0x4f,0xbc,0xba,0xd6,
0x0e,0x81,0x8a,0xfb,0x54,0x61,0x91,0x5a,0x40,0xb5,0xc5,0xef,0xbd,0xae,0x7d,0xe1,
0xb6,0x70,0x43,0xd8,0x2e,0x91,0x3e,0x32,0x30,0x94,0xdf,0x94,0x54,0xac,0x90,0x0b,
0x43,0x9d,0x5b,0x5f,0x9b,0x81,0xaa,0x9f,0x63,0x74,0x66,0x2d,0x20,0x32,0xf6,0xe7,
0xc3,0x16,0xbd,0x08,0x16,0x04,0xe1,0xc8,0xa6,0x71,0x8d,0x5c,0x1f,0x6a,0xe4,0x5c,
0x23,0x77,0xe6,0x7b,0x31,0xde,0xa0,0x8e,0x18,0xf7,0x64,0x56,0x3a,0xfa,0xe4,0xeb,
0xb9,0xa0,0xe3,0xef,0xd3,0x1f,0x60,0xd7,0x51,0xb5,0x75,0xdc,0x12,0xbb,0x68,0x98,
0x97,0xe7,0xf6,0xc9,0x94,0xc7,0x29,0xe1,0x5d,0x8a,0x26,0xb9,0xa5,0x48,0x5a,0xc2,
0x2b,0x75,0xd0,0x99,0x5d,0xb7,0x5c,0xa4,0xb2,0xc4,0xd8,0x13,0x81,0x70,0xec,0xcb,
0x2e,0xf3,0x4a,0x24,0x78,0x5d,0x08,0xf0,0xd9,0xcc,0xbe,0x18,0x2e,0x58,0x7a,0x9c,
0x91,0xba,0x6e,0xb2,0x81,0x56,0x8f,0xcf,0xe2,0x17,0x34,0xfa,0x87,0xca,0x1a,0x43,
0x9d,0xde,0x02,0x73,0xc4,0x2d,0xbe,0x86,0x49,0xf7,0xa3,0xf3,0x16,0xf4,0x66,0x4a,
0xde,0x33,0x90,0xef,0x77,0x65,0x47,0x93,0xb0,0xdf,0x43,0x01,0x15,0x8a,0x6c,0xf9,
0xe1,0x5d,0x94,0x9b,0xa1,0xca,0x1f,0xed,0x45,0x49,0x53,0x02,0x55,0x63,0x55,0x42,
0x28,0xcf,0x61,0xe6,0xde,0x6c,0x25,0x5a,0xb5,0x19,0xbe,0xa3,0xb0,0x66,0x72,0x12,
0xde,0xdb,0x0e,0xf0,0xb8,0xbd,0xcf,0xcd,0x1a,0x6d,0x3f,0x22,0x53,0x63,0xba,0xd0,
0xb2,0xbc,0xb3,0x42,0x1f,0x8a,0x0a,0x2d,0xa6,0xac,0xff,0x88,0x31,0xcf,0x04,0x9f,
0x4e,0x17,0xf8,0xbf,0xfd,0x66,0x87,0x29,0x8d,0x8e,0x7d,0x55,0xa2,0xdc,0xe2,0xd7,
0xe7,0x75,0xe4,0x09,0x33,0x86,0xa7,0xf0,0xc0,0x9a,0xbe,0xdb,0x98,0x32,0x88,0x35,
0xd3,0xc5,0xe3,0x0e,0xb2,0x52,0x65,0x3b,0x68,0x6e,0x5a,0xaf,0x68,0xdf,0xb7,0x10,
0x1b,0xa4,0x0e,0x14,0xe7,0xf0,0x2f,0x63,0xaa,0x99,0x2e,0x95,0x2f,0x91,0x70,0x94,
0xa8,0x30,0x9b,0x82,0xa2,0x9b,0xa5,0x23,0x9b,0x93,0xec,0xe5,0xb8,0x68,0x6a,0x99,
0x99,0x99,0x22,0x40,0xe9,0xe9,0xf0,0x71,0x49,0x61,0x36,0x21,0x7a,0xb4,0xe5,0x54,
0xd2,0x2f,0xe1,0x0f,0x7c,0x12,0xb8,0x67,0xdb,0x90,0x20,0x50,0x52,0xac,0x22,0x04,
0x02,0x3d,0xa5,0x95,0xf0,0x97,0x27,0x20,0x43,0x2d,0xc9,0x01,0x08,0x93,0x61,0x8c,
0x23,0xa8,0x38,0xc4,0x8f,0x6a,0xab,0x6f,0x53,0xcd,0x5a,0x03,0x32,0x35,0x8c,0x50,
0xa9,0xc6,0xb9,0x8a,0xa3,0x3e,0x44,0x81,0xbd,0x92,0x77,0x63,0x7e,0xfa,0x96,0x67,
0x1c,0x99,0xc7,0xb3,0x72,0x0d,0x5e,0x5f,0xb0,0xbe,0x34,0xab,0x76,0xe8,0xb3,0x46,
0x4d,0x4a,0x5d,0x44,0xab,0xf6,0xd1,0x9e,0x6e,0xb7,0x16,0x60,0x23,0xed,0x83,0x03,
0x21,0xeb,0x5f,0xe6,0x34,0x48,0x3f,0x5c,0x98,0xf2,0x2c,0xf3,0xbc,0x93,0xba,0x2a,
0x7d,0x32,0xeb,0xec,0x72,0x85,0xf5,0x94,0x68,0x00,0x23,0x13,0x07,0x36,0x09,0xeb,
0x6c,0x19,0x10,0xd9,0xc9,0xa9,0x2b,0xe1,0xec,0x3d,0x88,0x5b,0x75,0x05,0xa6,0x4b,
0xfb,0x0b,0xb5,0xd3,0x7a,0x8e,0x43,0x96,0xaa,0x2f,0xff,0xf6,0x55,0x4a,0x9e,0x28,
0x69,0x8e,0xc5,0xa3,0xb3,0xb6,0x02,0x37,0xc5,0xcf,0x93,0x99,0x22,0xf7,0xe2,0x0c,
0x46,0xf9,0x36,0xe6,0x28,0xf5,0x9e,0xe1,0x03,0x05,0x71,0xb3,0xee,0x0c,0x6b};
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(631+IPHSIZE);

   BYTE buf[1600];
   BYTE *buf_chksum = (BYTE *)(buf+120); //use after few bytes !
   
	memcpy(buf_chksum, quic,631);
	new_udp_chksum = magic_tcpudp_cksum(ip.saddr, ip.daddr, ip.protocol, (u16)631, (u8 *)buf_chksum);
   memcpy((BYTE *)(quic+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, quic, 631);
   
   int sock_fd = create_socket(argv[1]);
	if(!(sock_fd) ) { printf("no sock_fd found\n"); }
 
	write(sock_fd, buf, ETHSIZE+IPHSIZE+631);

}

Download voip_sip.c sockets sample source-code discussed in the video HERE. And here is the same source code for a quick reference.

/*---------- 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;
}

Download stp.c sample source-code discussed in the video HERE. And here is the same source code for a quick reference.

/*---------- 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   */

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

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;
}

void main(int argc, char ** argv)
{	int sock_fd=0; 
	BYTE stp[60] ={ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x1c,   0x0e, 0x87, 0x85, 0x04, 0x00, 0x26, 0x42, 0x42,
					  	 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x64,   0x00, 0x1c, 0x0e, 0x87, 0x78, 0x00, 0x00, 0x00,
					  	 0x00, 0x04, 0x80, 0x64, 0x00, 0x1c, 0x0e, 0x87,   0x85, 0x00, 0x80, 0x04, 0x01, 0x00, 0x14, 0x00,
					  	 0x02, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,   0x00, 0x00, 0x00, 0x00 };

	
	sock_fd = create_socket(argv[1]);
	if( !(sock_fd) ) { printf("no sock_fd found\n"); return; }
	write(sock_fd, stp, 60);
}

Download ospf.c sockets sample source-code discussed in the video HERE. And here is the same source code for a quick reference.

/*---------- 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>

#define ETHSIZE         14
#define IPHSIZE         20
#define TCPHSIZE        20

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

typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;

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

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;
}

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);
}

void main(int argc, char ** argv)
{
	BYTE ospf[56]={0x02,0x01,0x00,0x2c,0xc0,0xa8,0x67,0x01,0x00,0x00,0x00,0x01,0xb9,0xf8,0x00,0x01,
		0x63,0x69,0x73,0x63,0x6f,0x00,0x00,0x00,0xff,0xff,0xff,0xf8,0x00,0x0a,0x12,0x01,
		0x00,0x00,0x00,0x28,0x0a,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0xff,0xf6,0x00,0x03,
		0x00,0x01,0x00,0x04,0x00,0x00,0x00,0x01 };
	BYTE l2[14] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x05, 0xc0, 0x01, 0x0f, 0x78, 0x00, 0x00, 0x08, 0x00};
	
	struct iphdr ip;
	memset(&ip, 0x0, IPHSIZE);
	ip.version    = 4;
   ip.ihl        = IPHSIZE >> 2;
   ip.tos        = 0;
   ip.tot_len    = htons(56+IPHSIZE);
   ip.id         = htons(rand()%65535);
   ip.frag_off   = 0;
   ip.ttl        = htons(254);
   ip.protocol   = 0x59;
   ip.saddr      = inet_addr(argv[2]);
   ip.daddr	     = inet_addr("224.0.0.5");
   ip.check      = (unsigned short)in_cksum((unsigned short *)&ip, IPHSIZE);
   
   BYTE buf[300];
   memcpy(buf, l2, ETHSIZE);
   memcpy(buf+ETHSIZE, &ip, IPHSIZE);
   memcpy(buf+ETHSIZE+IPHSIZE, ospf, 56); 
   
   int sock_fd = create_socket(argv[1]);
	if(!(sock_fd) ) { printf("no sock_fd found\n"); return; }
	write(sock_fd, (BYTE *)buf, ETHSIZE+ntohs(ip.tot_len));
}




Suggested Topics:


Video Episodes :: Linux (user-space), Systems Architecture and Networking

Online Course - Networking Protocols ↗
Saturday' 13-Mar-2021

Data Visualization and Analytics ↗
Saturday' 13-Mar-2021

Linux (user-space) RAW Socket Programming ↗
Saturday' 13-Mar-2021

Quagga Routing Suite - OSPF, RIP, RIPng BGP4 | GNU Zebra fork | ZebOS ↗
Saturday' 13-Mar-2021
GNU Zebra is one of the oldest open-source Dynamic Routing Protocol suite stack developed by Kunihiro Ishiguro. Zebra supports features such as RIPv1/RIPv2 for IPv4 and RIPng for IPv6, OSPFv2 and OSPFv3, BGPv4+ and so on. Zebra is an active project for many years. After many years of active support Zebra is discontinued, and sometime down the lane a new fork is created from Zebra called Quagga which is now maintained by a separate independent open-source community. Quagga is a routing software suite, providing implementations of OSPFv2, OSPFv3, RIP v1 and v2, RIPng and BGP-4 for Unix platforms, particularly FreeBSD, Linux, Solaris and NetBSD. Quagga is a fork of GNU Zebra which was developed by Kunihiro Ishiguro. The Quagga architecture consists of a core daemon, zebra, which acts as an abstraction layer to the underlying Unix kernel and presents the Zserv API over a Unix or TCP stream to Quagga clients.

CPU Performance and Benchmarks ↗
Saturday' 13-Mar-2021

CUDA GPU Distributed Parallel Computing ↗
Saturday' 13-Mar-2021

net-tools - Source Code Walk ↗
Saturday' 13-Mar-2021

NAS (Network Attached Storage) Operating Systems - FreeNAS, OpenZFS, etc ↗
Saturday' 13-Mar-2021

Systems Architecture ↗
Saturday' 13-Mar-2021

VRF - Virtual Routing and Forwarding ↗
Saturday' 13-Mar-2021

Online Course - Linux CLI Scripting ↗
Saturday' 13-Mar-2021

Code Snippets ↗
Saturday' 13-Mar-2021

Building my own Userspace Network Stack - Platform/OS and Hardware Independent ↗
Saturday' 13-Mar-2021

Oracle VM VirtualBox ↗
Saturday' 13-Mar-2021

IPUtils - Source Code Walk ↗
Saturday' 13-Mar-2021

OpenWRT - BusyBox and Embedded Linux ↗
Saturday' 13-Mar-2021

Wireshark Packet Capture ↗
Saturday' 13-Mar-2021

Online Course - Linux TUN/TAP virtual network interfaces ↗
Saturday' 13-Mar-2021

Ethtool - Source Code Walk ↗
Saturday' 13-Mar-2021

Networking and Q&A ↗
Saturday' 13-Mar-2021

Join The Linux Channel :: Facebook Group ↗

Visit The Linux Channel :: on Youtube ↗


💗 Help shape the future: Sponsor/Donate


Recommended Topics:
Featured Video:
Watch on Youtube - x22f Linux Kernel Network Drivers - Classification ↗

Raspberry Pi OS with PIXEL ↗
Saturday' 13-Mar-2021

Programming Language Performance and Overheads ↗
Saturday' 13-Mar-2021
A detailed Youtube video series of various programming language performance and overheads - a big picture

What is a Linux Kernel Module - a Big Picture ↗
Saturday' 13-Mar-2021
Learning Linux Kernel Programming is always fascinating and yet challenging. So generally you may tend to learn Kernel Module programming, since such a module can be dynamically plugged into running Linux Kernel. But this will lead to confusion, and many assume kernel source is mostly a collection of these modules. Which in reality is not. Not just that, when we say Kernel Module, its a vaguely defined term. The term Module (as we know) is nothing but a collection of APIs, bunch of variables and associated data-structures. Which may or may not be a plugable kernel module. If you ask me, I am a fan of wiring Linux Kernel Modules, which may not be necessarily a pluggable kernel module. It all boils down to the address space at which these modules function inside a monolithic Linux Kernel. Which is nothing but Linux Kernel's address space. Hence here is my detailed multi-episode Youtube video series on Linux Kernel modules, a big picture and the significance of the

Linux Kernel Programming | with or without Kernel Modules | Device Drivers ↗
Saturday' 13-Mar-2021
When learning Linux Kernel programming, often I notice my students and viewers gets confused and they start with learning writing Linux Kernel modules. And so they develop the common misconception about Kernel Programming in general. They assume writing code in Linux Kernel means writing kernel modules. Which is absolutely not. Kernel modules are an optional choice and are part of Linux Kernel. But besides modules, Linux Kernel has lot of other mainstream code. Hence if anyone wants to be a Kernel Developer, you should be aware that sometimes you add new code via modules, sometimes without them. And if you ask me, I am not much in favor of writing Kernel modules. Instead in my code, I try to integrate and make them a part of Linux Kernel so that they all get initialized during boot time. Here is an extensive Youtube video of mine on Linux Kernel Programming, with and without Kernel Modules.

Weekly News Digest - Week 03 - June 2020 ↗
Saturday' 13-Mar-2021
The Linux Channel :: Weekly News Digest - Week 03 - June 2020 > KimĪ‡ Micro: A powerful alternative to the Raspberry Pi that supports PCIe cards > Linux Lands And Then Reverts Usage Of Flexible Array Members > AMD Ryzen 4000-Powered Asus Mini PC Challenges Intel's NUC > Aaeon's Raspberry Pi-like Board Bears An Intel 8th Gen Core i7 CPU and 16GB of DDR4 > Linus Torvalds Announces Massive Linux Kernel 5.8 Update > New Cisco Cloud Scale ASIC & 400G Line Card Announced > Key Differences of PoE vs PoE+ vs PoE++ Switches a STH Guide

CEO, CTO Talk ↗
Saturday' 13-Mar-2021

TCP vs UDP an Expert Opinion ↗
Saturday' 13-Mar-2021

Weekly News Digest - Week 5 - February 2018 ↗
Saturday' 13-Mar-2021
> Mini-ITX board fosters flexibility and fights obsolescence > You Can Do Better Than Arduino: Try These Microcontrollers > Open source is 20: How it changed programming and business forever > Since computer technology evolves so rapidly, does it matter if you have 5 or 15 years of experience as e.g. software developer? > Linux Kernel net_device data-structure - possible_net_t nd_net - Network namespace and Linux Containers - Ep7 > New Wave of Mini Satellites Could Boost Climate Research > Here come all the AI deployments; Now how do we manage AI? > Imagination announces neural network acceleration push

How to start Open-Source Project ↗
Saturday' 13-Mar-2021

Weekly News Digest - Week 8 - February 2018 ↗
Saturday' 13-Mar-2021
> Asymmetric Processor Cores > Using QCT Quanta LB6M 10GbE Switch for Container Networking > Using SSE Instead Of WebSockets For Unidirectional Data Flow Over HTTP/2 > Why IPv6 networks create DNS configuration problems > Hypervisor or containers: Which solution is right for you? > Blockchain for 2018 and Beyond: A (growing) list of blockchain use cases > Raw sockets backdoor gives attackers complete control of some Linux servers


Trending Video:
Watch on Youtube - x224 Linux Kernel Dummy Network Interface /drivers/net/dummy... ↗

Linux Kernel struct udphdr data-structure ↗
Saturday' 13-Mar-2021



Recommended Video:
Watch on Youtube - x22f Linux Kernel Network Drivers - Classification ↗