Raw Sockets programming on Linux with C

Raw sockets or packets contain user defined IP headers. Its as simple as that.

Here we shall consider sending a raw tcp packets. A tcp packets has 3 parts : IP header + TCP header + data

The structure of IP Header as given by RFC 791 is :

1 0                   1                   2                   3
2 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
3 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4 |Version|  IHL  |Type of Service|          Total Length         |
5 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6 |         Identification        |Flags|      Fragment Offset    |
7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8 |  Time to Live |    Protocol   |         Header Checksum       |
9 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10 |                       Source Address                          |
11 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12 |                    Destination Address                        |
13 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
14 |                    Options                    |    Padding    |
15 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The structure of a TCP header as given by RFC 793 :

1 0                   1                   2                   3
2 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
3 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4 |          Source Port          |       Destination Port        |
5 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
6 |                        Sequence Number                        |
7 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8 |                    Acknowledgment Number                      |
9 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10 |  Data |           |U|A|P|R|S|F|                               |
11 | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
12 |       |           |G|K|H|T|N|N|                               |
13 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
14 |           Checksum            |         Urgent Pointer        |
15 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16 |                    Options                    |    Padding    |
17 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
18 |                             data                              |
19 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

To create a raw socket :

1 int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);

Another option to make sure the kernel uses the raw headers :

1 {
2  int one = 1;
3  const int *val = &one;
4  if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
5   printf ("Warning: Cannot set HDRINCL!\n");
6 }

Below is an example code which constructs a raw TCP packet :
Code :

1 /*
2  Raw Sockets with LINUX
3 */
4 #include<stdio.h>
5 #include<netinet/tcp.h> //Provides declarations for tcp header
6 #include<netinet/ip.h> //Provides declarations for ip header
7  
8 //Checksum calculation function
9 unsigned short csum (unsigned short *buf, int nwords)
10 {
11  unsigned long sum;
12   
13  for (sum = 0; nwords > 0; nwords--)
14   sum += *buf++;
15   
16  sum = (sum >> 16) + (sum & 0xffff);
17  sum += (sum >> 16);
18   
19  return ~sum;
20 }
21  
22 int main (void)
23 {
24  //Create a raw socket
25  int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);
26  //Datagram to represent the packet
27  char datagram[4096];
28  //IP header
29  struct iphdr *iph = (struct iphdr *) datagram;
30  //TCP header
31  struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct ip));
32  struct sockaddr_in sin;
33    
34  sin.sin_family = AF_INET;
35  sin.sin_port = htons(40);
36  sin.sin_addr.s_addr = inet_addr ("60.61.62.63");
37   
38  memset (datagram, 0, 4096); /* zero out the buffer */
39   
40  //Fill in the IP Header
41  iph->ihl = 5;
42  iph->version = 4;
43  iph->tos = 0;
44  iph->tot_len = sizeof (struct ip) + sizeof (struct tcphdr);
45  iph->id = htonl (54321); //Id of this packet
46  iph->frag_off = 0;
47  iph->ttl = 255;
48  iph->protocol = 6;
49  iph->check = 0;  //Set to 0 before calculating checksum
50  iph->saddr = inet_addr ("1.2.3.4"); //Spoof the source ip address
51  iph->daddr = sin.sin_addr.s_addr;
52   
53  //TCP Header
54  tcph->source = htons (1234);
55  tcph->dest = htons (85);
56  tcph->seq = random ();
57  tcph->ack_seq = 0;
58  tcph->doff = 0;  /* first and only tcp segment */
59  tcph->syn = 1;
60  tcph->window = htonl (65535); /* maximum allowed window size */
61  tcph->check = 0;/* if you set a checksum to zero, your kernel's IP stack
62     should fill in the correct checksum during transmission */
63  tcph->urg_ptr = 0;
64  //Now the IP checksum
65  iph->check = csum ((unsigned short *) datagram, iph->tot_len >> 1);
66   
67  //IP_HDRINCL to tell the kernel that headers are included in the packet
68  {
69   int one = 1;
70   const int *val = &one;
71   if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
72    printf ("Warning: Cannot set HDRINCL!\n");
73  }
74   
75  while (1)
76  {
77   //Send the packet
78   if (sendto (s,  /* our socket */
79      datagram, /* the buffer containing headers and data */
80      iph->tot_len, /* total length of our datagram */
81      0,  /* routing flags, normally always 0 */
82      (struct sockaddr *) &sin/* socket addr, just like in */
83      sizeof (sin)) < 0)  /* a normal send() */
84    printf ("error\n");
85   else
86    printf (".");
87  }
88   
89  return 0;
90 }

Remember to run the above code with root privileges. Raw sockets require root privileges

User wireshark to check the output.

时间: 2024-08-31 03:17:21

Raw Sockets programming on Linux with C的相关文章

【转】Raw Sockets Gone in XP SP2

Raw Sockets Gone in XP SP2 - Thursday 12 August, 2004, 2:07 PM http://www.interact-sw.co.uk/iangblog/2004/08/12/norawsockets    Well, not strictly gone, but their power has been reduced in certain respects. While it might make Steve Gibson happy, I'm

如何把几个onclick监听器放到sockets programming方法中?

问题描述 如何把几个onclick监听器放到sockets programming方法中? 在我的android程序中有一个sockets program,我想要在客户端通过点击按钮来发送一个command或者是文本消息.然后,发不同的文本消息要依靠于是哪个按钮被点击的.但是我从PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket .getOutputStream())), true)

【转】A little more info on raw sockets and Windows XP SP2

 http://blogs.msdn.com/michael_howard/archive/2004/08/12/213611.aspx There's been a little confusion about raw sockets and Windows XP SP2. Hopefully, this little entry from the "Changes in functionality..." doc (see my last blog entry for an URL

Serial Port Programming on Linux(转载)

This is a tutorial on how to program the Serial Ports on your Linux box.Serial Ports are nice little interfaces on the PC which helps you to interface your embedded system projects using a minimum number of wires.In this tutorial we will write a smal

linux c socket programming

原文:linux c socket programming http://54min.com/post/http-client-examples-using-c.html 好文章   PPT http://www.slideshare.net/Arbow/asynchronous-io-programming verygood   C: Linux Socket Programming, TCP, a simple HTTP client http://coding.debuntu.org/c-

Tcp syn portscan code in C with Linux sockets

Port Scanning searches for open ports on a remote system. The basic logic for a portscanner would be to connect to the port we want to check. If the socket gives a valid connection without any error then the port is open , closed otherwise (or inacce

剖析 Linux hypervisor--KVM 和 Lguest 简介

慢慢弄清楚..   M. Tim Jones, 顾问工程师, Emulex Corp. M. Tim Jones 是一名嵌入式软件工程师,他是 Artificial Intelligence: A Systems Approach, GNU/Linux Application Programming(现在已经是第 2 版).AI Application Programming(第 2 版)和 BSD Sockets Programming from a Multilanguage Perspec

socket programming example

1. 头文件 vi server.h  // 头文件 // 注册信号处理函数 int catch_signal(int sig, void (*handler) (int)); // 从socket读数据到char *buf int read_in(int socket, char *buf, int len); // 错误函数, 当exit_val=0只输出错误信息, 不退出程序. 其他值输出错误信息并退出程序 void error(char * msg, int exit_val); //

redhat linux通过udev创建裸设备

在redhat5中,raw文件的位置已经改变成/bin/raw,系统里面已经不存在/etc/sysconfig/rawdevices和/etc/init.d/rawdevices文件了,可以通过如下方法来管理raw文件. 1,建立/etc/sysconfig/rawdevices文件,然后从其他操作系统上拷贝/etc/init.d/rawdevices到本地机,修改 /etc/init.d/rawdevices文件中raw命令的具体位置,然后就可以通过/etc/init.d/rawdevices