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 - Linux TUN/TAP virtual network interfaces ↗
Thursday' 13-Aug-2020

Online Course - Networking Protocols ↗
Thursday' 13-Aug-2020

Networking and Q&A ↗
Thursday' 13-Aug-2020

Data Visualization and Analytics ↗
Thursday' 13-Aug-2020

Ethtool - Source Code Walk ↗
Thursday' 13-Aug-2020

Code Snippets ↗
Thursday' 13-Aug-2020

VRF - Virtual Routing and Forwarding ↗
Thursday' 13-Aug-2020

net-tools - Source Code Walk ↗
Thursday' 13-Aug-2020

OpenWRT - BusyBox and Embedded Linux ↗
Thursday' 13-Aug-2020

IPUtils - Source Code Walk ↗
Thursday' 13-Aug-2020

Quagga Routing Suite - OSPF, RIP, RIPng BGP4 | GNU Zebra fork | ZebOS ↗
Thursday' 13-Aug-2020
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.

Online Course - Linux CLI Scripting ↗
Thursday' 13-Aug-2020

CPU Performance and Benchmarks ↗
Thursday' 13-Aug-2020

Building my own Userspace Network Stack - Platform/OS and Hardware Independent ↗
Thursday' 13-Aug-2020

Linux (user-space) RAW Socket Programming ↗
Thursday' 13-Aug-2020

Oracle VM VirtualBox ↗
Thursday' 13-Aug-2020

Systems Architecture ↗
Thursday' 13-Aug-2020

NAS (Network Attached Storage) Operating Systems - FreeNAS, OpenZFS, etc ↗
Thursday' 13-Aug-2020

CUDA GPU Distributed Parallel Computing ↗
Thursday' 13-Aug-2020

Wireshark Packet Capture ↗
Thursday' 13-Aug-2020

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 - [216//0] 0x1bd Raspberry Pi Official Universal Power Supply | DC 2.5 Amps - 5.1 Volts | Unboxing and Review ↗

Adding your own Kernel Modules into Linux Kernel Source | Linux Kernel Programming ↗
Thursday' 13-Aug-2020
Whenever you do custom kernel modules, you can optionally make it a part of existing Linux Kernel source. This does not mean you are submitting your kernel module to the mainline kernel source (i.e kernel.org Linux Kernel Foundation). What I meant is, you can make your kernel module(s) part of Linux Kernel source so that when you compile your kernel you can automatically compile your kernel module(s) too. As well when you create/modify kernel .config configuration file (such as via make menuconfig, etc), you can enable or disable your kernel module(s) too.
To do the same you have to register (and include) your custom Kernel Module's Kconfig and Makefile to the existing Kconfig and Makefile of the Linux Kernel source Here is a detailed multi-episode video of mine which gives the overall idea and the big-picture.

Linux Kernel Programming | with or without Kernel Modules | Device Drivers ↗
Thursday' 13-Aug-2020
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.

Roadmap - How to become Linux Kernel Developer - Device Drivers Programmer and a Systems Software Expert ↗
Thursday' 13-Aug-2020
Many viewers and even sometimes my students ask me how I can become a kernel programmer or just device driver developer and so on. So I shot this video (and an add-on video) where I summarized steps and a roadmap to become a full-fledged Linux Kernel Developer.

Weekly News Digest - Week 03 - July 2020 ↗
Thursday' 13-Aug-2020
The Linux Channel :: Weekly News Digest - Week 03 - July 2020
> Linux founder tells Intel to stop inventing 'magic instructions' and 'start fixing real problems'
> QNAP launches its first 2.5GbE network switch - QSW-1105-5T
> Japan's ARM-based Fugaku is the world's fastest supercomputer
> FreeBSD Back To Seeing Progress On 802.11ac WiFi Support, Ath10k Driver
> Sparkfun Launches the ZED-F9R GPS Dead Reckoning Raspberry Pi pHAT for Mobile Robots
> ODROID-N2 Plus SBC Gets Amlogic S922X Rev. C Processor Clocked at up to 2.4 GHz
> Rock Pi E SBC Comes with WiFi, Bluetooth, Two Ethernet Ports, and Optional PoE

Linux Software Development and Tools ↗
Thursday' 13-Aug-2020

Compiling a C Compiler with a C Compilter | Compile gcc with gcc ↗
Thursday' 13-Aug-2020
The fundamental aspect of a programming language compiler is to translate code written from language to other. But most commonly compilers will compile code written in high-level human friendly language such as C, C++, Java, etc. to native CPU architecture specific (machine understandable) binary code which is nothing but sequence of CPU instructions. Hence if we see that way we should able to compile gcc Compiler source code with a gcc Compiler binary.

PyDelhi + PyData + ILUG-D + Linux Chix meetup mash @ Sarai on 17-Dec-2016 ↗
Thursday' 13-Aug-2020

Programming Language Performance and Overheads ↗
Thursday' 13-Aug-2020
A detailed Youtube video series of various programming language performance and overheads - a big picture

C Programming Language Basics - Pointers in C ↗
Thursday' 13-Aug-2020

Software Programming Standards (Coding Standards) ↗
Thursday' 13-Aug-2020


Trending Video:
Watch on Youtube - [154//0] 0x182 Best 5 Tips | for Women in Systems Software Development | Reduce Time | Boost Productivity ↗

Linux Kernel struct tcphdr data-structure ↗
Thursday' 13-Aug-2020



Recommended Video:
Watch on Youtube - [147//0] 0x1a6 Balancing Work and Personal Life in IT (Tech) Industry | The Linux Channel ↗