When programming network packet transmission and resolution, win socket technology is widely used. However, this technology is only applicable to the transport layers at the network layer and above, and there are not many lower-layer applications, to understand the real mechanism of data packet sending, we need to use Winpcap to send data packets. The following describes how to use Winpcap to send data packets for the two Protocols.
Windows AP: http://www.winpcap.org/archive/
Use Winpcap to send TCP Packets
First, install Winpcap and wpcap on the local machine to call the functions in Winpcap.
The following is an analysis of the TCP protocol:
Because the Ethernet data header, IP address data header and TCP Data header must be constructed for the data to be sent, the data to be sent should be as follows:
Ethernet data Header| *. * IPData Header| TCPData Header|Data
- Define the Ethernet data header Structure
Typedef struct et_header
{
Unsigned char eh_dst [6]; // Destination Address
Unsigned char eh_src [6]; // Source Address
Unsigned short eh_type; // The value of eh_type needs to evaluate the protocol of the previous layer. If it is an IP address, it is 0 × 0800.
} Et_header;
- Define IP data Headers
Typedef struct ip_hdr
{
Unsigned char h_verlen; // IP header length (4-byte aligned)
Unsigned char TOS; // service type
Unsigned short total_len; // total length (including IP data header, TCP Data header, and data)
Unsigned char version: 4; // The general IP type is IPv4
Unsigned short ident; // ID defines a separate IP Address
Unsigned short frag_and_flags; // The flag offset.
Unsigned char TTL; // survival time
Unsigned char proto; // protocol type
Unsigned short checksum; // check and
Unsigned int sourceip; // source IP address
Unsigned int destip; // destination IP address
} Ip_header;
- Define TCP Data Headers
Typedef struct tcp_hdr
{
Unsigned short th_sport; // Source Port
Unsigned short th_dport; // destination port
Unsigned int th_seq; // serial number
Unsigned int th_ack; // confirmation number
Unsigned char th_lenres; // 4-bit Header Length
Unsigned char th_flag; // flag
Unsigned short th_win; // window size
Unsigned short th_sum; // check
Unsigned short th_urp; // emergency pointer
} Tcp_header;
All the information in the Data header is constructed in the preceding three structure types.
In consideration of the verification, you need to add a pseudo header:
Typedef struct tsd_hdr
{
Unsigned long saddr; // Source Address
Unsigned long daddr; // Destination Address
Char mbz; // null
Char ptcl; // protocol type
Unsigned short tcpl; // Packet Length
} Psd_header;
Process the following information:
Process:
L obtain the list of devices on the local machine (call the pcap_findalldevs_ex function). If you find the NIC device, store the device in the interfacename (customizable) variable and obtain the local IP address (under the most basic conditions ), call the pcap_freealldevs function to release the device.
L obtain the MAC address of the local gateway, declare ppacket_oid_data oiddata, and then allocate space for the MAC address.
Oiddata = (ppacket_oid_data) malloc (6 + sizeof (packet_oid_data), call oiddata-> OID = empty; zeromemory (oiddata-> data, 6); to obtain the MAC address
L next, assign values to the packet header. In particular, you can use bitwise operations to determine the specific flag value due to the large number of TCP flag bits.
L pcap_open (interfacename, 100, pcap_openflag_promiscuous, 100, null, errbuf) This function opens the NIC Device
L pcap_sendpacket (pcap_t * P, buffer, sizeof (buffer) send data packets, buffer is to send data packets, P indicates Winpcap handle
Use Winpcap to send UDP Packets
What is different from TCP is that UDP header data needs to be added.
UDPData Header
Struct udphdr
{
U_int16_t source;/* Source Port */
U_int16_t DEST;/* destination port */
U_int16_t Len;/* UDP length */
U_int16_t checkl;/* UDP checksum */
};
To avoid duplication, the following describes the packet header settings.
Ether_header * pether_header = (ether_header *) buffer; // Ethernet header pointer
Ip_header * pip_herder = (ip_header *) (buffer + sizeof (ether_header); // IP data header pointer
Udphdr * pudp_herder = (udphdr *) (buffer + sizeof (ether_header) + sizeof (ip_header); // UDP data header pointer
// Assign values to the source address of the Ethernet header
Pether_header-> ether_dhost [0] = 1; // 0 × 0*16 + 0 × 0 ;;
Pether_header-> ether_dhost [1] = 1; // 0 × 2*16 + 0 × 1;
Pether_header-> ether_dhost [2] = 1; // 0 × 2*16 + 0 × 7;
Pether_header-> ether_dhost [3] = 1; // 0 × 2*16 + 0 × 3;
Pether_header-> ether_dhost [4] = 1; // 0 × 7*16 + 0 × 2;
Pether_header-> ether_dhost [5] = 1; // 0xf * 16 + 0xe;
// Assign values to the destination address of the Ethernet header
Pether_header-> ether_shost [0] = 1; // 0 × 0*16 + 0 × 0 ;;
Pether_header-> ether_shost [1] = 1; // 0 × 1*16 + 0xf;
Pether_header-> ether_shost [2] = 1; // 0xd * 16 + 0 × 0;
Pether_header-> ether_shost [3] = 1; // 0 × 1*16 + 0 × 6;
Pether_header-> ether_shost [4] = 1; // 0 × 6*16 + 0 × 3;
Pether_header-> ether_shost [5] = 1; // 0 × 7*16 + 0 × 1;
// Assign values for the Ethernet protocol
Pether_header-> ether_type = htons (ethertype_ip );
// Construct an IP address data Header
Pip_herder-> IHL = sizeof (ip_header)/4; // The unit is 4 bytes.
Pip_herder-> Version = 4; // sets the version number.
Pip_herder-> TOS = 0; // set the type
Pip_herder-> tot_len = htons (sizeof (buffer)-sizeof (ether_header); // set the length
Pip_herder-> id = htons (0 × 1000); // set the ID
Pip_herder-> frag_off = htons (0); // sets the offset.
Pip_herder-> TTL = 0 × 80; // set the TTL.
Pip_herder-> protocol = ipproto_udp; // set the protocol type.
Pip_herder-> check = 0; // set the check result.
Pip_herder-> saddr = inet_addr ("192.168.18. *"); // set the source address
Pip_herder-> daddr = inet_addr ("122. *"); // set the destination address
Pip_herder-> check = in_cksum (u_int16_t *) pip_herder, sizeof (ip_header); // reset the validation
// Construct a UDP data header;
Pudp_herder-> DEST = htons (7865); // destination port number
Pudp_herder-> source = htons (2834); // source port number
Pudp_herder-> Len = htons (sizeof (buffer)-sizeof (ether_header)-sizeof (ip_header); // set the length
Pudp_herder-> checkl = 0; // sets the check result.
// Construct the pseudo UDP Header
Char buffer2 [64] = {0 };
Psd_header * PSD = (psd_header *) buffer2;
PSD-> sourceip = inet_addr ("192.168.18 .*");
PSD-> destip = inet_addr ("122 .*.*.*");
PSD-> ptcl = ipproto_udp;
PSD-> Plen = htons (sizeof (buffer)-sizeof (ether_header)-sizeof (ip_header ));
PSD-> mbz = 0;
Memcpy (buffer2 + sizeof (psd_header), (void *) pudp_herder, sizeof (buffer)-sizeof (ether_header)-sizeof (ip_header ));
Pudp_herder-> checkl = in_cksum (u_int16_t *) buffer2, sizeof (buffer)-sizeof (ether_header)-sizeof (ip_header) + sizeof (psd_header ));
Next, call pcap_open and pcap_sendpacket to send data packets.
Conclusion: We have studied the two protocols to understand the process and principle of Winpcap packet sending. I believe that the process for sending packets from Winpcap is similar to that for other protocols.