Home PC Games Linux Windows Database Network Programming Server Mobile  
           
  Home \ Programming \ Linux raw socket     - How to install Linux Kernel 4.0 On CentOS 7 system (Linux)

- How to monitor Nginx (Database)

- To create a full command line Android Build System (Linux)

- Install the system cleaning software under Linux: BleachBit 1.4 (Linux)

- Upgrade to Linux Mint 16 petra Mint 17 Qiana (Linux)

- to install the deployment of LVS under CentOS 7.0 (Server)

- To configure linux transparent firewall (Linux)

- Linear table with a Java implementation of the iterator (Programming)

- Linux environment to configure Apache + Django + wsgi (Server)

- Getting Started with Linux system to learn: how to get the process ID (PID) in the script (Linux)

- How to modify the Ubuntu terminal user name changed to red color (Linux)

- MySQL binlog automatic cleanup script (Database)

- Understanding the Linux load average on other UNIX-Like systems (Linux)

- Intruder tools Knark Analysis and Prevention Linux environment (Linux)

- MySQL Data Types (Database)

- Oracle 11gr2 new APPEND_VALUES tips (Database)

- CoreOS use register mirror to build private warehouse (Linux)

- Linux performance monitoring - CPU, Memory, IO, Network (Linux)

- ORA-04091 and Compound Trigger (Oracle 11g) (Database)

- Storm basic framework for analysis (Programming)

 
         
  Linux raw socket
     
  Add Date : 2018-11-21      
         
         
         
  One. Overview

One,Arp Ethernet packet structure
arp structure op operating parameters: 1 request 2 response.

Common data structure is as follows:

1. Physical address structure located netpacket / packet.h

struct sockaddr_ll
{
unsigned short int sll_family;
unsigned short int sll_protocol;
int sll_ifindex;
unsigned short int sll_hatype;
unsigned char sll_pkttype;
unsigned char sll_halen;
unsigned char sll_addr [8];
};
sll_ifindex network (LAN) interface index, the representative from this interface to send and receive data packets

2. Network (LAN) interface data structures are located net / if.h

Copy the code
struct ifreq
{
# define IFHWADDRLEN 6
# define IFNAMSIZ IF_NAMESIZE
union
{
char ifrn_name [IFNAMSIZ]; / * Interface name, e.g. "en0" * /.
} ifr_ifrn;

union
{
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
struct sockaddr ifru_netmask;
struct sockaddr ifru_hwaddr;
short int ifru_flags;
int ifru_ivalue;
int ifru_mtu;
struct ifmap ifru_map;
char ifru_slave [IFNAMSIZ]; / * Just fits the size * /
char ifru_newname [IFNAMSIZ];
__caddr_t ifru_data;
} ifr_ifru;
};
The structure which contains two union, the first is the interface name, such as: eth0, wlan0, etc. You can obtain the corresponding interface information via ioctl () function, ip address, mac address, the interface indexes.

3. Ethernet header structure is located net / ethernet.h

struct ether_header
{
u_int8_t ether_dhost [ETH_ALEN]; / * destination eth addr * /
u_int8_t ether_shost [ETH_ALEN]; / * source ether addr * /
u_int16_t ether_type; / * packet type ID field * /
} __attribute__ ((__packed__));
ether_type frame types: a common IP, ARP, RARP, has a corresponding macro definition.

4.arp package structure located netinet / if_ether.h

struct ether_arp {
struct arphdr ea_hdr; / * fixed-size header * /
u_int8_t arp_sha [ETH_ALEN]; / * sender hardware address * /
u_int8_t arp_spa [4]; / ​​* sender protocol address * /
u_int8_t arp_tha [ETH_ALEN]; / * target hardware address * /
u_int8_t arp_tpa [4]; / ​​* target protocol address * /
};
#define arp_hrd ea_hdr.ar_hrd
#define arp_pro ea_hdr.ar_pro
#define arp_hln ea_hdr.ar_hln
#define arp_pln ea_hdr.ar_pln
#define arp_op ea_hdr.ar_op
ether_arp above structure further comprises a header arp Located net / if_arp.h

struct arphdr
{
unsigned short int ar_hrd; / * Format of hardware address * /.
unsigned short int ar_pro; / * Format of protocol address * /.
unsigned char ar_hln;. / * Length of hardware address * /
unsigned char ar_pln; / * Length of protocol address * /.
unsigned short int ar_op; / * ARP opcode (command) * /.
}
Two,arp request code

  1 /**
  2 * @file arp_request.c
  3 * /
  4
  5 #include
  6 #include
  7 #include
  8 #include
  9 #include
 10 #include
 11 #include
 12 #include
 13 #include
 14 #include
 15 #include
 16 #include
 17 #include
 18
 19 / * Ethernet frame header length * /
 20 #define ETHER_HEADER_LEN sizeof (struct ether_header)
 21 / * arp entire length of the structure * /
 22 #define ETHER_ARP_LEN sizeof (struct ether_arp)
 23 / * Ethernet + arp entire length of the structure * /
 24 #define ETHER_ARP_PACKET_LEN ETHER_HEADER_LEN + ETHER_ARP_LEN
 25 / * IP address length * /
 26 #define IP_ADDR_LEN 4
 27 / * broadcast address * /
 28 #define BROADCAST_ADDR {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
 29
 30 void err_exit (const char * err_msg)
 31 {
 32 perror (err_msg);
 33 exit (1);
 34}
 35
 36 / * fill arp packet * /
 37 struct ether_arp * fill_arp_packet (const unsigned char * src_mac_addr, const char * src_ip, const char * dst_ip)
 38 {
 39 struct ether_arp * arp_packet;
 40 struct in_addr src_in_addr, dst_in_addr;
 41 unsigned char dst_mac_addr [ETH_ALEN] = BROADCAST_ADDR;
 42
 43 / * convert network byte order * /
 44 inet_pton (AF_INET, src_ip, & src_in_addr);
 45 inet_pton (AF_INET, dst_ip, & dst_in_addr);
 46
 47 / * * the whole package arp /
 48 arp_packet = (struct ether_arp *) malloc (ETHER_ARP_LEN);
 49 arp_packet-> arp_hrd = htons (ARPHRD_ETHER);
 50 arp_packet-> arp_pro = htons (ETHERTYPE_IP);
 51 arp_packet-> arp_hln = ETH_ALEN;
 52 arp_packet-> arp_pln = IP_ADDR_LEN;
 53 arp_packet-> arp_op = htons (ARPOP_REQUEST);
 54 memcpy (arp_packet-> arp_sha, src_mac_addr, ETH_ALEN);
 55 memcpy (arp_packet-> arp_tha, dst_mac_addr, ETH_ALEN);
 56 memcpy (arp_packet-> arp_spa, & src_in_addr, IP_ADDR_LEN);
 57 memcpy (arp_packet-> arp_tpa, & dst_in_addr, IP_ADDR_LEN);
 58
 59 return arp_packet;
 60}
 61
 62 / * arp request * /
 63 void arp_request (const char * if_name, const char * dst_ip)
 64 {
 65 struct sockaddr_ll saddr_ll;
 66 struct ether_header * eth_header;
 67 struct ether_arp * arp_packet;
 68 struct ifreq ifr;
 69 char buf [ETHER_ARP_PACKET_LEN];
 70 unsigned char src_mac_addr [ETH_ALEN];
 71 unsigned char dst_mac_addr [ETH_ALEN] = BROADCAST_ADDR;
 72 char * src_ip;
 73 int sock_raw_fd, ret_len, i;
 74
 75 if ((sock_raw_fd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ARP))) == -1)
 76 err_exit ( "socket ()");
 77
 78 bzero (& saddr_ll, sizeof (struct sockaddr_ll));
 79 bzero (& ifr, sizeof (struct ifreq));
 80 / * LAN interface name * /
 81 memcpy (ifr.ifr_name, if_name, strlen (if_name));
 82
 83 / * Get network interface index * /
 84 if (ioctl (sock_raw_fd, SIOCGIFINDEX, & ifr) == -1)
 85 err_exit ( "ioctl () get ifindex");
 86 saddr_ll.sll_ifindex = ifr.ifr_ifindex;
 87 saddr_ll.sll_family = PF_PACKET;
 88
 89 / * Get network interface IP * /
 90 if (ioctl (sock_raw_fd, SIOCGIFADDR, & ifr) == -1)
 91 err_exit ( "ioctl () get ip");
 92 src_ip = inet_ntoa (((struct sockaddr_in *) & (ifr.ifr_addr)) -> sin_addr);
 93 printf ( "local ip:% s n", src_ip);
 94
 95 / * Get network interface MAC address * /
 96 if (ioctl (sock_raw_fd, SIOCGIFHWADDR, & ifr))
 97 err_exit ( "ioctl () get mac");
 98 memcpy (src_mac_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
 99 printf ( "local mac");
100 for (i = 0; i 101 printf ( ":% 02x", src_mac_addr [i]);
102 printf ( " n");
103
104 bzero (buf, ETHER_ARP_PACKET_LEN);
105 / * fill Ethernet header * /
106 eth_header = (struct ether_header *) buf;
107 memcpy (eth_header-> ether_shost, src_mac_addr, ETH_ALEN);
108 memcpy (eth_header-> ether_dhost, dst_mac_addr, ETH_ALEN);
109 eth_header-> ether_type = htons (ETHERTYPE_ARP);
110 / * arp packet * /
111 arp_packet = fill_arp_packet (src_mac_addr, src_ip, dst_ip);
112 memcpy (buf + ETHER_HEADER_LEN, arp_packet, ETHER_ARP_LEN);
113
114 / * Send Request * /
115 ret_len = sendto (sock_raw_fd, buf, ETHER_ARP_PACKET_LEN, 0, (struct sockaddr *) & saddr_ll, sizeof (struct sockaddr_ll));
116 if (ret_len> 0)
117 printf ( "sendto () ok !!! n");
118
119 close (sock_raw_fd);
120}
121
122 int main (int argc, const char * argv [])
123 {
124 if (argc! = 3)
125 {
126 printf ( "usage:% s device_name dst_ip n", argv [0]);
127 exit (1);
128}
129
130 arp_request (argv [1], argv [2]);
131
132 return 0;
133}
Processes: Command Line Interface receiving NIC name and destination IP addresses to be requested, the incoming arp_request () function. Creating ARP types of raw socket with PF_PACKET option. With ioctl () function to get the interface corresponding to the mac address, ip address, and interface index by the name of network interface cards. Interface index population to physical addresses sockaddr_ll inside. Then fill the Ethernet header, the source address of the network interface corresponding to just mac address, destination address, fill in a broadcast address (line 28 defined macros). Ethernet frame header type is ETHERTYPE_ARP, representatives arp type. Then fill arp data packet structure to be filled with the same source / ip address and mac address of the destination, and Options arp packets fill ARPOP_REQUEST, on behalf of the requested operation. Just sent to the physical address sockaddr_ll after filling is completed.

III. Received arp packet

 1 /**
 2 * @file arp_recv.c
 3 * /
 4
 5 #include
 6 #include
 7 #include
 8 #include
 9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
Fifteen
16 / * Ethernet frame header length * /
17 #define ETHER_HEADER_LEN sizeof (struct ether_header)
18 / * arp entire length of the structure * /
19 #define ETHER_ARP_LEN sizeof (struct ether_arp)
20 / * Ethernet + arp entire length of the structure * /
21 #define ETHER_ARP_PACKET_LEN ETHER_HEADER_LEN + ETHER_ARP_LEN
22 / * IP address length * /
23 #define IP_ADDR_LEN 4
twenty four
25 void err_exit (const char * err_msg)
26 {
27 perror (err_msg);
28 exit (1);
29}
30
31 int main (void)
32 {
33 struct ether_arp * arp_packet;
34 char buf [ETHER_ARP_PACKET_LEN];
35 int sock_raw_fd, ret_len, i;
36
37 if ((sock_raw_fd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ARP))) == -1)
38 err_exit ( "socket ()");
39
40 while (1)
41 {
42 bzero (buf, ETHER_ARP_PACKET_LEN);
43 ret_len = recv (sock_raw_fd, buf, ETHER_ARP_PACKET_LEN, 0);
44 if (ret_len> 0)
forty five {
46 / * Strip the Ethernet header * /
47 arp_packet = (struct ether_arp *) (buf + ETHER_HEADER_LEN);
48 / * arp operation code represents arp response * /
49 if (ntohs (arp_packet-> arp_op) == 2)
50 {
51 printf ( "========================== arp replay ================== ==== n ");
52 printf ( "from ip:");
53 for (i = 0; i 54 printf ( "% u.", Arp_packet-> arp_spa [i]);
55 printf ( " nfrom mac");
56 for (i = 0; i 57 printf ( ":% 02x", arp_packet-> arp_sha [i]);
58 printf ( " n");
59}
60}
61}
62
63 close (sock_raw_fd);
64 return 0;
65}
Process: Creating ARP types of raw socket. Directly call reception function receives arp packets received by the NIC, arp packet operation judgment is received arp response opcode is 2. Then stripped Ethernet header, remove the source mac address and ip address! ! !

IV. Experimental

For more intuitive, we open wireshark viewed together, I have here is wlan environment, listening wlan0. Raw socket to run as root, run arp_recv, then run arp_request send arp request

wireshark Results

Can be seen above, the first data packet to ask who is 192.168.0.1, then the second packet sent a reply, you can see wireshark inside Opcode: reply (2). Source ip and mac address with our own program to receive the same.
One. Overview

Previous arp request using raw sockets link layer. icmp ip packet encapsulated in the inside, so icmp request can use raw sockets network layer, namely the socket () The first parameter is PF_INET. as follows:

1 sockfd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP);
icmp packets of different types have different formats, we will icmp echo request and echo reply message format (namely, the packet type used by ping program) as an example:



8 indicates that the request type, 0 indicates response. To calculate the checksum own identifier generally progress of the program ID number. Custom number, usually starting at 1. Option data which can put a time stamp, a ping used to calculate the time spent!

icmp packet structure is defined in netinet / ip_icmp.h

Copy the code
 1 struct icmp
 2 {
 3 u_int8_t icmp_type; / * type of message, see below * /
 4 u_int8_t icmp_code; / * type sub code * /
 5 u_int16_t icmp_cksum; / * ones complement checksum of struct * /
 6 union
 7 {
 8 u_char ih_pptr; / * ICMP_PARAMPROB * /
 9 struct in_addr ih_gwaddr; / * gateway address * /
10 struct ih_idseq / * echo datagram * /
11 {
12 u_int16_t icd_id;
13 u_int16_t icd_seq;
14} ih_idseq;
15 u_int32_t ih_void;
16
17 / * ICMP_UNREACH_NEEDFRAG - Path MTU Discovery (RFC1191) * /
18 struct ih_pmtu
19 {
20 u_int16_t ipm_void;
21 u_int16_t ipm_nextmtu;
22} ih_pmtu;
twenty three
24 struct ih_rtradv
25 {
26 u_int8_t irt_num_addrs;
27 u_int8_t irt_wpa;
28 u_int16_t irt_lifetime;
29} ih_rtradv;
30} icmp_hun;
31 #define icmp_pptr icmp_hun.ih_pptr
32 #define icmp_gwaddr icmp_hun.ih_gwaddr
33 #define icmp_id icmp_hun.ih_idseq.icd_id
34 #define icmp_seq icmp_hun.ih_idseq.icd_seq
35 #define icmp_void icmp_hun.ih_void
36 #define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
37 #define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
38 #define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
39 #define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
40 #define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
41 union
42 {
43 struct
44 {
45 u_int32_t its_otime;
46 u_int32_t its_rtime;
47 u_int32_t its_ttime;
48} id_ts;
49 struct
50 {
51 struct ip idi_ip;
52 / * options and then 64 bits of data * /
53} id_ip;
54 struct icmp_ra_addr id_radv;
55 u_int32_t id_mask;
56 u_int8_t id_data [1];
57} icmp_dun;
58 #define icmp_otime icmp_dun.id_ts.its_otime
59 #define icmp_rtime icmp_dun.id_ts.its_rtime
60 #define icmp_ttime icmp_dun.id_ts.its_ttime
61 #define icmp_ip icmp_dun.id_ip.idi_ip
62 #define icmp_radv icmp_dun.id_radv
63 #define icmp_mask icmp_dun.id_mask
64 #define icmp_data icmp_dun.id_data
65};
Copy the code
Two .icmp request code

Copy the code
  1 /**
  2 * @file icmp_request.c
  3 * /
  4
  5 #include
  6 #include
  7 #include
  8 #include
  9 #include
 10 #include
 11 #include
 12 #include
 13 #include
 14
 15 / * icmp packet length * /
 16 #define ICMP_PACKET_LEN sizeof (struct icmp)
 17
 18 void err_exit (const char * err_msg)
 19 {
 20 perror (err_msg);
 21 exit (1);
 twenty two }
 twenty three
 24 / * checksum * /
 25 unsigned short check_sum (unsigned short * addr, int len)
 26 {
 27 int nleft = len;
 28 int sum = 0;
 29 unsigned short * w = addr;
 30 unsigned short answer = 0;
 31
 32 while (nleft> 1)
 33 {
 34 sum + = * w ++;
 35 nleft - = 2;
 36}
 37 if (nleft == 1)
 38 {
 39 * (unsigned char *) (& answer) = * (unsigned char *) w;
 40 sum + = answer;
 41}
 42
 43 sum = (sum >> 16) + (sum & 0xffff);
 44 sum + = (sum >> 16);
 45 answer = ~ sum;
 46
 47 return answer;
 48}
 49
 50 / * fill icmp packet * /
 51 struct icmp * fill_icmp_packet (int icmp_type, int icmp_sequ)
 52 {
 53 struct icmp * icmp_packet;
 54
 55 icmp_packet = (struct icmp *) malloc (ICMP_PACKET_LEN);
 56 icmp_packet-> icmp_type = icmp_type;
 57 icmp_packet-> icmp_code = 0;
 58 icmp_packet-> icmp_cksum = 0;
 59 icmp_packet-> icmp_id = htons (getpid ());
 60 icmp_packet-> icmp_seq = icmp_sequ;
 61 / * Send time * /
 62 gettimeofday ((struct timeval *) icmp_packet-> icmp_data, NULL);
 63 / * checksum * /
 64 icmp_packet-> icmp_cksum = check_sum ((unsigned short *) icmp_packet, ICMP_PACKET_LEN);
 65
 66 return icmp_packet;
 67}
 68
 69 / * Send icmp request * /
 70 void icmp_request (const char * dst_ip, int icmp_type, int icmp_sequ)
 71 {
 72 struct sockaddr_in dst_addr;
 73 struct icmp * icmp_packet;
 74 int sockfd, ret_len;
 75 char buf [ICMP_PACKET_LEN];
 76
 77 / * requested address * /
 78 bzero (& dst_addr, sizeof (struct sockaddr_in));
 79 dst_addr.sin_family = AF_INET;
 80 dst_addr.sin_addr.s_addr = inet_addr (dst_ip);
 81
 82 if ((sockfd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1)
 83 err_exit ( "sockfd ()");
 84
 85 / * icmp packet * /
 86 icmp_packet = fill_icmp_packet (icmp_type, icmp_sequ);
 87 memcpy (buf, icmp_packet, ICMP_PACKET_LEN);
 88
 89 / * Send Request * /
 90 ret_len = sendto (sockfd, buf, ICMP_PACKET_LEN, 0, (struct sockaddr *) & dst_addr, sizeof (struct sockaddr_in));
 91 if (ret_len> 0)
 92 printf ( "sendto () ok !!! n");
 93
 94 close (sockfd);
 95}
 96
 97 int main (int argc, const char * argv [])
 98 {
 99 if (argc! = 2)
100 {
101 printf ( "usage:% s dst_ip n", argv [0]);
102 exit (1);
103}
104
105 / * Send icmp request * /
106 icmp_request (argv [1], 8, 1);
107
108 return 0;
109}
Copy the code
Process: Command-line receiving icmp request target IP, 106 lines to send the request to specify the type of icmp 8, the serial number is 1. By then create target IP address of the network address structure, then create ICMP raw socket type, filling icmp packets, and sends the time to fill icmp data structure.

Three .icmp receive code

Copy the code
 1 /**
 2 * @file icmp_recv.c
 3 * /
 4
 5 #include
 6 #include
 7 #include
 8 #include
 9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
Fifteen
16 / * IP header length * /
17 #define IP_HEADER_LEN sizeof (struct ip)
18 / * icmp packet length * /
19 #define ICMP_PACKET_LEN sizeof (struct icmp)
20 / * IP + ICMP length * /
21 #define IP_ICMP_PACKET_LEN IP_HEADER_LEN + ICMP_PACKET_LEN
twenty two
23 void err_exit (const char * err_msg)
twenty four {
25 perror (err_msg);
26 exit (1);
27}
28
29 / * calculate the time difference in milliseconds to send and receive time * /
30 float time_interval (struct timeval * recv_time, struct timeval * send_time)
31 {
32 float msec = 0;
33
34 / * If the time received less than subtle subtle transmitted * /
35 if (recv_time-> tv_usec tv_usec)
36 {
37 recv_time-> tv_sec - = 1;
38 recv_time-> tv_usec + = 1000000;
39}
40 msec = (recv_time-> tv_sec - send_time-> tv_sec) * 1000.0 + (recv_time-> tv_usec - send_time-> tv_usec) / 1000.0;
41
42 return msec;
43}
44
45 int main (void)
46 {
47 struct ip * ip_header;
48 struct icmp * icmp_packet;
49 char buf [IP_ICMP_PACKET_LEN];
50 struct timeval * recv_timeval, * send_timeval;
51 int sockfd, ret_len;
52
53 if ((sockfd = socket (PF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1)
54 err_exit ( "sockfd ()");
55
56 recv_timeval = malloc (sizeof (struct timeval));
57 while (1)
58 {
59 ret_len = recv (sockfd, buf, IP_ICMP_PACKET_LEN, 0);
60 if (ret_len> 0)
61 {
62 / * Receive time * /
63 gettimeofday (recv_timeval, NULL);
64 / * Remove the ip header * /
65 / * Remove icmp packet * /
66 ip_header = (struct ip *) buf;
67 icmp_packet = (struct icmp *) (buf + IP_HEADER_LEN);
68 / * Remove the transmission time * /
69 send_timeval = (struct timeval *) icmp_packet-> icmp_data;
70 printf ( "=============================== n");
71 printf ( "from ip:% s n", inet_ntoa (ip_header-> ip_src));
72 printf ( "icmp_type:% d n", icmp_packet-> icmp_type);
73 printf ( "icmp_code:% d n", icmp_packet-> icmp_code);
74 printf ( ". Time interval:% 3fms n", time_interval (recv_timeval, send_timeval));
75}
76}
77
78 free (recv_timeval);
79 close (sockfd);
80 return 0;
81}
Copy the code
Process: After you create directly receive ICMP raw socket type. First obtain the reception time, followed by removing ip header, icmp packet, and then remove the icmp request time. Access to the source ip ip address from the header, to get the type of the packet, the code numbers from icmp packets through the transmission time and the reception time calculation millisecond difference!

IV. Experimental

1. Open wireshark viewed together. Running as root icmp_recv, then run icmp_request







You can see the type icmp is 0, the code is 0. Response time with our program almost.

2. We now address a request ip unreachable





Host unreachable, icmp message types returns 3, code 1. Packets of different structures, remove the transmission time is not normal, so the time interval calculated here is not normal. Results wireshark is inside, the machine automatically broadcast an arp request, but no machine answer machine.
One. Overview

tcp ip packet is encapsulated in packets, tcp create raw sockets as follows:

1 sockfd = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);
At this time can only configured tcp packet header further if you want to construct ip, then it would open the IP_HDRINCL sockfd options:

1 int on = 1;
2 setsockopt (sockfd, IPPROTO_IP, IP_HDRINCL, & on, sizeof (on));
ip packet format:



ip header structure is defined in netinet / ip.h

 1 struct ip
 2 {
 3 #if __BYTE_ORDER == __LITTLE_ENDIAN
 4 unsigned int ip_hl: 4; / * header length * /
 5 unsigned int ip_v: 4; / * version * /
 6 #endif
 7 #if __BYTE_ORDER == __BIG_ENDIAN
 8 unsigned int ip_v: 4; / * version * /
 9 unsigned int ip_hl: 4; / * header length * /
10 #endif
11 u_int8_t ip_tos; / * type of service * /
12 u_short ip_len; / * total length * /
13 u_short ip_id; / * identification * /
14 u_short ip_off; / * fragment offset field * /
15 #define IP_RF 0x8000 / * reserved fragment flag * /
16 #define IP_DF 0x4000 / * dont fragment flag * /
17 #define IP_MF 0x2000 / * more fragments flag * /
18 #define IP_OFFMASK 0x1fff / * mask for fragmenting bits * /
19 u_int8_t ip_ttl; / * time to live * /
20 u_int8_t ip_p; / * protocol * /
21 u_short ip_sum; / * checksum * /
22 struct in_addr ip_src, ip_dst; / * source and dest address * /
twenty three };
tcp packet format:



tcp header structure is defined in netinet / tcp.h:

 1 struct tcphdr
 2 {
 3 __extension__ union
 4 {
 5 struct
 6 {
 7 u_int16_t th_sport; / * source port * /
 8 u_int16_t th_dport; / * destination port * /
 9 tcp_seq th_seq; / * sequence number * /
10 tcp_seq th_ack; / * acknowledgement number * /
11 # if __BYTE_ORDER == __LITTLE_ENDIAN
12 u_int8_t th_x2: 4; / * (unused) * /
13 u_int8_t th_off: 4; / * data offset * /
14 # endif
15 # if __BYTE_ORDER == __BIG_ENDIAN
16 u_int8_t th_off: 4; / * data offset * /
17 u_int8_t th_x2: 4; / * (unused) * /
18 # endif
19 u_int8_t th_flags;
20 # define TH_FIN 0x01
21 # define TH_SYN 0x02
22 # define TH_RST 0x04
23 # define TH_PUSH 0x08
24 # define TH_ACK 0x10
25 # define TH_URG 0x20
26 u_int16_t th_win; / * window * /
27 u_int16_t th_sum; / * checksum * /
28 u_int16_t th_urp; / * urgent pointer * /
29};
30 struct
31 {
32 u_int16_t source;
33 u_int16_t dest;
34 u_int32_t seq;
35 u_int32_t ack_seq;
36 # if __BYTE_ORDER == __LITTLE_ENDIAN
37 u_int16_t res1: 4;
38 u_int16_t doff: 4;
39 u_int16_t fin: 1;
40 u_int16_t syn: 1;
41 u_int16_t rst: 1;
42 u_int16_t psh: 1;
43 u_int16_t ack: 1;
44 u_int16_t urg: 1;
45 u_int16_t res2: 2;
46 # elif __BYTE_ORDER == __BIG_ENDIAN
47 u_int16_t doff: 4;
48 u_int16_t res1: 4;
49 u_int16_t res2: 2;
50 u_int16_t urg: 1;
51 u_int16_t ack: 1;
52 u_int16_t psh: 1;
53 u_int16_t rst: 1;
54 u_int16_t syn: 1;
55 u_int16_t fin: 1;
56 # else
57 # error "Adjust your defines"
58 # endif
59 u_int16_t window;
60 u_int16_t check;
61 u_int16_t urg_ptr;
62};
63};
64};
The above definition and structure of the control structure is easy to understand. Note: Four and tcp ip header length is 32bit refers to the number of accounts. If ordinary ip header length is 20 bytes, 4 bytes accounted for 32, then this value is 20/4 = 5.

II. IP_TCP send configuration

  1 /**
  2 * @file ip_tcp_send.c
  3 * /
  4
  5 #include
  6 #include
  7 #include
  8 #include
  9 #include
 10 #include
 11 #include
 12 #include
 13 #include
 14
 15 / * ip header length * /
 16 #define IP_HEADER_LEN sizeof (struct ip)
 17 / * tcp header length * /
 18 #define TCP_HEADER_LEN sizeof (struct tcphdr)
 19 / * ip header + tcp header length * /
 20 #define IP_TCP_HEADER_LEN IP_HEADER_LEN + TCP_HEADER_LEN
 twenty one
 22 void err_exit (const char * err_msg)
 twenty three {
 24 perror (err_msg);
 25 exit (1);
 26}
 27
 28 / * fill ip header * /
 29 struct ip * fill_ip_header (const char * src_ip, const char * dst_ip, int ip_packet_len)
 30 {
 31 struct ip * ip_header;
 32
 33 ip_header = (struct ip *) malloc (IP_HEADER_LEN);
 34 ip_header-> ip_v = IPVERSION;
 35 ip_header-> ip_hl = sizeof (struct ip) / 4; / * Note here that, ip header length refers to the number of accounting for more than 32, 4 bytes = 32 bits, divided by 4 * /
 36 ip_header-> ip_tos = 0;
 37 ip_header-> ip_len = htons (ip_packet_len); / * length of the entire IP datagram, including ordinary data * /
 38 ip_header-> ip_id = 0; / * fill to make the kernel's own flag * /
 39 ip_header-> ip_off = 0;
 40 ip_header-> ip_ttl = MAXTTL;
 41 ip_header-> ip_p = IPPROTO_TCP; / * ip packet encapsulation protocol type * /
 42 ip_header-> ip_sum = 0; / * make the kernel's own calculated checksum * /
 43 ip_header-> ip_src.s_addr = inet_addr (src_ip); / * Source IP address * /
 44 ip_header-> ip_dst.s_addr = inet_addr (dst_ip); / * destination IP address * /
 forty five
 46 return ip_header;
 47}
 48
 49 / * fill tcp header * /
 50 struct tcphdr * fill_tcp_header (int src_port, int dst_port)
 51 {
 52 struct tcphdr * tcp_header;
 53
 54 tcp_header = (struct tcphdr *) malloc (TCP_HEADER_LEN);
 55 tcp_header-> source = htons (src_port);
 56 tcp_header-> dest = htons (dst_port);
 57 / * the same IP header, as here, is accounted for 32 of the number of bytes * /
 58 tcp_header-> doff = sizeof (struct tcphdr) / 4;
 59 / * initiated the connection * /
 60 tcp_header-> syn = 1;
 61 tcp_header-> window = 4096;
 62 tcp_header-> check = 0;
 63
 64 return tcp_header;
 65}
 66
 67 / * Send ip_tcp packet * /
 68 void ip_tcp_send (const char * src_ip, int src_port, const char * dst_ip, int dst_port, const char * data)
 69 {
 70 struct ip * ip_header;
 71 struct tcphdr * tcp_header;
 72 struct sockaddr_in dst_addr;
 73 socklen_t sock_addrlen = sizeof (struct sockaddr_in);
 74
 75 int data_len = strlen (data);
 76 int ip_packet_len = IP_TCP_HEADER_LEN + data_len;
 77 char buf [ip_packet_len];
 78 int sockfd, ret_len, on = 1;
 79
 80 bzero (& dst_addr, sock_addrlen);
 81 dst_addr.sin_family = PF_INET;
 82 dst_addr.sin_addr.s_addr = inet_addr (dst_ip);
 83 dst_addr.sin_port = htons (dst_port);
 84
 85 / * * Create a raw socket tcp /
 86 if ((sockfd = socket (PF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)
 87 err_exit ( "socket ()");
 88
 89 / * Open IP_HDRINCL, custom IP header * /
 90 if (setsockopt (sockfd, IPPROTO_IP, IP_HDRINCL, & on, sizeof (on)) == -1)
 91 err_exit ( "setsockopt ()");
 92
 93 / * ip header * /
 94 ip_header = fill_ip_header (src_ip, dst_ip, ip_packet_len);
 95 / * tcp header * /
 96 tcp_header = fill_tcp_header (src_port, dst_port);
 97
 98 bzero (buf, ip_packet_len);
 99 memcpy (buf, ip_header, IP_HEADER_LEN);
100 memcpy (buf + IP_HEADER_LEN, tcp_header, TCP_HEADER_LEN);
101 memcpy (buf + IP_TCP_HEADER_LEN, data, data_len);
102
103 / * Send message * /
104 ret_len = sendto (sockfd, buf, ip_packet_len, 0, (struct sockaddr *) & dst_addr, sock_addrlen);
105 if (ret_len> 0)
106 printf ( "sendto () ok !!! n");
107 else printf ( "sendto () failed n");
108
109 close (sockfd);
110 free (ip_header);
111 free (tcp_header);
112}
113
114 int main (int argc, const char * argv [])
115 {
116 if (argc! = 6)
117 {
118 printf ( "usage:% s src_ip src_port dst_ip dst_port data n", argv [0]);
119 exit (1);
120}
121
122 / * Send ip_tcp packet * /
123 ip_tcp_send (argv [1], atoi (argv [2]), argv [3], atoi (argv [4]), argv [5]);
124
125 return 0;
126}
Process: Command line parameters received are: source ip address, source port, destination ip address, destination port, normal data. Then by source / destination ip ip header structure, by source / destination port tcp header structure. Target ip / port filled sockaddr_in, finally ip header structure, tcp header, ordinary copy all the data into the buffer, just be sent to the address of sockaddr_in! ! !

III. Received IP_TCP

 1 /**
 2 * @file ip_tcp_recv.c
 3 * /
 4
 5 #include
 6 #include
 7 #include
 8 #include
 9 #include
10 #include
11 #include
12 #include
13 #include
14
15 / * ip header length * /
16 #define IP_HEADER_LEN sizeof (struct ip)
17 / * tcp header length * /
18 #define TCP_HEADER_LEN sizeof (struct tcphdr)
19 / * ip header + tcp header length * /
20 #define IP_TCP_HEADER_LEN IP_HEADER_LEN + TCP_HEADER_LEN
21 / * Receive data buffer size * /
22 #define BUFFER_SIZE 1024
23 / * ip header + tcp header + data buffer size * /
24 #define IP_TCP_BUFF_SIZE IP_TCP_HEADER_LEN + BUFFER_SIZE
25
26 void err_exit (const char * err_msg)
27 {
28 perror (err_msg);
29 exit (1);
30}
31
32 / * * received raw socket /
33 void raw_socket_recv ()
34 {
35 struct ip * ip_header;
36 struct tcphdr * tcp_header;
37 int sock_raw_fd, ret_len;
38 char buf [IP_TCP_BUFF_SIZE];
39
40 if ((sock_raw_fd = socket (PF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)
41 err_exit ( "socket ()");
42
43 / * Receive data * /
44 while (1)
forty five {
46 bzero (buf, IP_TCP_BUFF_SIZE);
47 ret_len = recv (sock_raw_fd, buf, IP_TCP_BUFF_SIZE, 0);
48 if (ret_len> 0)
49 {
50 / * Remove the ip header * /
51 ip_header = (struct ip *) buf;
52 / * Remove the tcp header * /
53 tcp_header = (struct tcphdr *) (buf + IP_HEADER_LEN);
54 printf ( "======================================= n");
55 printf ( "from ip:% s n", inet_ntoa (ip_header-> ip_src));
56 printf ( "from port:% d n", ntohs (tcp_header-> source));
57 / * retrieve data * /
58 printf ( "get data:% s n", buf + IP_TCP_HEADER_LEN);
59}
60}
61
62 close (sock_raw_fd);
63}
64
65 int main (void)
66 {
67 / * * received raw socket /
68 raw_socket_recv ();
69
70 return 0;
71}
Process: Create a TCP raw sockets, the original socket is point to point transmission, unlike TCP / UDP is end to end, so there is no port raw socket concept can be received directly. Here is the entire received IP packet, which contains a TCP packet. Successively removed after receiving a header ip, tcp header, common data! ! !

IV. Experimental

The sender and receiver are in the machine, we open wireshark listen lo interface. As root run two programs:



The above two tcp packets sent each time the source ip, source port is counterfeit. DDOS program is the principle.

wireshark Results:
One. Overview

Ibid as a tcp, udp ip packet is encapsulated in the inside. UDP create raw sockets as follows:

1 (sockfd = socket (PF_INET, SOCK_RAW, IPPROTO_UDP);
Similarly, if you want to construct the udp ip header to open IP_HDRINCL option!

udp header format:



udp unreliability, much simpler than tcp packets. Above 16 UDP header + UDP length is the total length of normal data, and this point with a total length of 16 ip header of the same!

udp structure is defined in netinet / udp.h

Copy the code
 1 struct udphdr
 2 {
 3 __extension__ union
 4 {
 5 struct
 6 {
 7 u_int16_t uh_sport; / * source port * /
 8 u_int16_t uh_dport; / * destination port * /
 9 u_int16_t uh_ulen; / * udp length * /
10 u_int16_t uh_sum; / * udp checksum * /
11};
12 struct
13 {
14 u_int16_t source;
15 u_int16_t dest;
16 u_int16_t len;
17 u_int16_t check;
18};
19};
20};
II. Construction IP_UDP packets

  1 /**
  2 * @file ip_udp_send.c
  3 * /
  4
  5 #include
  6 #include
  7 #include
  8 #include
  9 #include
 10 #include
 11 #include
 12 #include
 13
 14 / * ip header length * /
 15 #define IP_HEADER_LEN sizeof (struct ip)
 16 / * udp header length * /
 17 #define UDP_HEADER_LEN sizeof (struct udphdr)
 18 / * ip header + udp header length * /
 19 #define IP_UDP_HEADER_LEN IP_HEADER_LEN + UDP_HEADER_LEN
 20
 21 void err_exit (const char * err_msg)
 twenty two {
 23 perror (err_msg);
 24 exit (1);
 25}
 26
 27 / * fill ip header * /
 28 struct ip * fill_ip_header (const char * src_ip, const char * dst_ip, int ip_packet_len)
 29 {
 30 struct ip * ip_header;
 31
 32 ip_header = (struct ip *) malloc (IP_HEADER_LEN);
 33 ip_header-> ip_v = IPVERSION;
 34 ip_header-> ip_hl = IP_HEADER_LEN / 4;
 35 ip_header-> ip_tos = 0;
 36 ip_header-> ip_len = htons (ip_packet_len);
 37 ip_header-> ip_id = 0;
 38 ip_header-> ip_off = 0;
 39 ip_header-> ip_ttl = MAXTTL;
 40 ip_header-> ip_p = IPPROTO_UDP; / * This is the UDP * /
 41 ip_header-> ip_sum = 0;
 42 ip_header-> ip_src.s_addr = inet_addr (src_ip);
 43 ip_header-> ip_dst.s_addr = inet_addr (dst_ip);
 44
 45 return ip_header;
 46}
 47
 48 / * fill udp header * /
 49 struct udphdr * fill_udp_header (int src_port, int dst_port, int udp_packet_len)
 50 {
 51 struct udphdr * udp_header;
 52
 53 udp_header = (struct udphdr *) malloc (UDP_HEADER_LEN);
 54 udp_header-> source = htons (src_port);
 55 udp_header-> source = htons (dst_port);
 56 / * Here is the entire length of the UDP packet * /
 57 udp_header-> len = htons (udp_packet_len);
 58 udp_header-> check = 0;
 59
 60 return udp_header;
 61}
 62
 63 / * Send ip_udp packet * /
 64 void ip_udp_send (const char * src_ip, int src_port, const char * dst_ip, int dst_port, const char * data)
 65 {
 66 struct ip * ip_header;
 67 struct udphdr * udp_header;
 68 struct sockaddr_in dst_addr;
 69 socklen_t sock_addrlen = sizeof (struct sockaddr_in);
 70
 71 int data_len = strlen (data);
 72 int ip_packet_len = IP_UDP_HEADER_LEN + data_len;
 73 int udp_packet_len = UDP_HEADER_LEN + data_len;
 74 char buf [ip_packet_len];
 75 int sockfd, ret_len, on = 1;
 76
 77 bzero (& dst_addr, sock_addrlen);
 78 dst_addr.sin_family = PF_INET;
 79 dst_addr.sin_addr.s_addr = inet_addr (dst_ip);
 80 dst_addr.sin_port = htons (dst_port);
 81
 82 / * Create udp raw socket * /
 83 if ((sockfd = socket (PF_INET, SOCK_RAW, IPPROTO_UDP)) == -1)
 84 err_exit ( "socket ()");
 85
 86 / * Open IP_HDRINCL, custom IP header * /
 87 if (setsockopt (sockfd, IPPROTO_IP, IP_HDRINCL, & on, sizeof (on)) == -1)
 88 err_exit ( "setsockopt ()");
 89
 90 / * ip header * /
 91 ip_header = fill_ip_header (src_ip, dst_ip, ip_packet_len);
 92 / * udp header * /
 93 udp_header = fill_udp_header (src_port, dst_port, udp_packet_len);
 94
 95 bzero (buf, ip_packet_len);
 96 memcpy (buf, ip_header, IP_HEADER_LEN);
 97 memcpy (buf + IP_HEADER_LEN, udp_header, UDP_HEADER_LEN);
 98 memcpy (buf + IP_UDP_HEADER_LEN, data, data_len);
 99
100 / * Send message * /
101 ret_len = sendto (sockfd, buf, ip_packet_len, 0, (struct sockaddr *) & dst_addr, sock_addrlen);
102 if (ret_len> 0)
103 printf ( "sendto () ok !!! n");
104 else printf ( "sendto () failed n");
105
106 close (sockfd);
107 free (ip_header);
108 free (udp_header);
109}
110
111 int main (int argc, const char * argv [])
112 {
113 if (argc! = 6)
114 {
115 printf ( "usage:% s src_ip src_port dst_ip dst_port data n", argv [0]);
116 exit (1);
117}
118
119 / * Send ip_udp packet * /
120 ip_udp_send (argv [1], atoi (argv [2]), argv [3], atoi (argv [4]), argv [5]);
121
122 return 0;
123}
Above most of the code to keep up with a similar. The difference is that this time is filled udp header, create raw socket type is UDP.
     
         
         
         
  More:      
 
- Python when automated operation and maintenance often used method (Programming)
- Linux disk quota-related instruction (Linux)
- Python dictionary applications get built-in method (Programming)
- How to find out a Unix system library files are 32-bit or 64-bit (Linux)
- Port Telnet command to detect the remote host is turned on (Linux)
- Ubuntu 15.10 install the latest Arduino IDE 1.6.7 (Linux)
- Can not remember how to solve the problem under Ubuntu brightness setting (Linux)
- Let Linux operating system more secure (Linux)
- Java annotations entry automatically generates SQL statements (Programming)
- TCP network communication Java Programming (Programming)
- The istgt PSD on ported to Mac OS X (Linux)
- To change CentOS7 runlevel (Linux)
- Change all child files and subdirectories in the owner permissions Ubuntu (Linux)
- Fedora 20 users install the Mate 1.8 desktop (Linux)
- How to understand the difference between synchronous and asynchronous non-blocking blocking (Programming)
- C ++ runtime environment built on CentOS 6.6 and Oracle database connection (Database)
- JDK comes with tools jinfo (Linux)
- Linux character device - user mode and kernel mode data transfer data (Linux)
- ActiveMQ5.10.2 version configuration JMX (Linux)
- Linux Security Raiders SSH tools SCP uses examples to explain in detail (Linux)
     
           
     
  CopyRight 2002-2020 newfreesoft.com, All Rights Reserved.