After receiving the previous blog post, we continue to parse network data packets and parse the three protocols that are hosted on the Ethernet. This mainly involves first parsing the header data according to the RFC-defined standards and then obtaining the payload, that is, the entity data contained in the Protocol is further processed by the upper layer.
I. ARP Protocol
As an important protocol for ing between lan ip addresses and MAC addresses, this protocol is similar to that of DNS in ing domain names and IP addresses. When the Ethernet Type field is 0x0806, it is an ARP packet. Definition:
The hardware type is the Ethernet code. The protocol type supported by ARP is IP (0x0800), the hardware address length is 6 for the MAC address, the Protocol address length is 4 for the IP address, and the OP field is the current datagram type, 0x0001 indicates the request packet, and 0x0002 indicates the response packet. These constitute the ARP data header, a total of 8 bytes.
The next 20 bytes are shown in. They are used for MAC address and IP address ing.
Resolution:
/// <Summary> /// define the ARP packet header by rfc826 // </Summary> public class arppacketheader: inetworklayerheader {public ushort hardwaretype = 0; // 2 bytes hardware type public ushort protocaltype = 0; // 2 bytes protocol type public byte hardwareaddresslength = 6; // 1 byte hardware address length (that is, the MAC address length is 6) public byte protocoladdresslength = 4; // 1 byte Protocol address length (that is, the IP address length is 4) Public ushort op = 0; // 2 byte ARP packet type (0x0001: request Packet 0x0002: Response packet)} // <summary> // parse the ARP packet /// </Summary> public class arppacket: inetworklayerpacket {private byte [] rawpacket; Public arppacketheader; Public String sendermac; Public String senderip; Public String receivermac; Public String receiverip; Public arppacket (byte [] rawarppacket) {sendermac = util. joinbytearr (util. subbytearr (rawarppacket, 8, 6), "-"); senderip = util. joinbytearr (util. subbytearr (rawarppacket, 14, 4 ),". "," D "); receivermac = util. joinbytearr (util. subbytearr (rawarppacket, 18, 6), "-"); receiverip = util. joinbytearr (util. subbytearr (rawarppacket, 24, 4 ),". "," D "); rawpacket = rawarppacket;} public inetworklayerheader getheader () {header = new arppacketheader (); header. hardwaretype = (ushort) (rawpacket [0] <8) + (ushort) rawpacket [1]); header. protocaltype = (ushort) (rawpacket [2] <8) + (ushort) rawpacket [3]); header. hardwareaddresslength = (byte) rawpacket [4]; header. protocoladdresslength = (byte) rawpacket [5]; header. OP = (ushort) (rawpacket [6] <8) + (ushort) rawpacket [7]); Return header;} public byte [] getbody () {return util. subbytearr (rawpacket, 8 );}}
Ii. IPv4 protocol
The parsing process is similar to the above and can be compared. As the most extensive network layer protocol, the detailed structure is not described in detail. View the structure chart directly:
The parsing process is as follows:
/// <Summary> /// define the IPv4 packet header by rfc791 // </Summary> public class limit 4packetheader: inetworklayerheader {public byte version = 4; // 3 bits version public byte length = 0; // 5 bits header length public byte TOS = 0; // 1 byte service type public ushort datagramlength = 0; // 2 bytes packet length public ushort identification = 0; // 2 bytes mark public byte mark = 0; // 3 bits mark public ushort offset = 0; // 13 BITs segment offset public byte TTL = 0; // 1 byte packet lifetime public byte upperprotocal = 0; // 1 byte upper layer protocol public ushort headerchecksum = 0; // 2 byte header check and Public String srcip = ""; // 4 bytes Source IP Address Public String dstip = ""; // 4 bytes destination IP address} // <summary> // parse the IPv4 packet /// </Summary> public class limit 4packet: inetworklayerpacket {private byte [] rawpacket; public ipv4packetheader header; Public byte [] body; Public ipv4packet (byte [] rawpacket) {rawpacket = rawpacket;} public inetworklayerheader getheader () {header = new ipv4packetheader (); header. length = (byte) (rawpacket [0] & 0x1f); header. toS = rawpacket [1]; header. required ramlength = (ushort) (rawpacket [2] <8) + (ushort) rawpacket [3]); header. identification = (ushort) (rawpacket [4] <8) + (ushort) rawpacket [5]); header. mark = (byte) (rawpacket [6]> 5); header. offset = (ushort) (rawpacket [6] & 0x1f) <8) + (ushort) rawpacket [7]); header. TTL = rawpacket [8]; header. upperprotocal = rawpacket [9]; header. headerchecksum = (ushort) (rawpacket [10] <8) + (ushort) rawpacket [11]); header. srcip = util. joinbytearr (util. subbytearr (rawpacket, 12, 4 ),". "," D "); header. dstip = util. joinbytearr (util. subbytearr (rawpacket, 16, 4 ),". "," D "); Return header;} public byte [] getbody () {body = util. subbytearr (rawpacket, 20); return body ;}}
Iii. IPv6 protocol
IPv6 is used to replace IPv4 to solve the problem of insufficient address space. At the same time, the Protocol has been greatly changed on the basis of IPv4, for example, you cannot perform sharding on an intermediate router. Although the application scope is difficult to replace IPv4, it provides a great advantage. For its datagram structure:
The parsing process is as follows:
/// <Summary> /// define the IPv6 packet header by RFC 2460 // </Summary> public class limit 6packetheader: inetworklayerheader {public byte version = 6; // 3 bits version public byte TOS = 0; // 1 byte traffic (service) Type Public uint flowtag = 0; // 21 bits stream tag public ushort availoad = 0; // 2 bytes payload length public byte nextheader = 0; // The next header of 1 byte (same as the Protocol field value in IPv4) Public byte hoplimit = 0; // 1 byte hop count limit public string srcip = ""; // 16 bytes source IPv6 Address Public String dstip = ""; // 16 bytes destination IPv6 address} // <summary> // parse the IPv6 packet /// </Summary> public class ipv6packet: inetworklayerpacket {private byte [] rawpacket; public ipv6packetheader header; Public byte [] body; Public ipv6packet (byte [] rawpacket) {rawpacket = rawpacket;} public inetworklayerheader getheader () {header = new ipv6packetheader (); header. toS = (byte) (rawpacket [0] & 0x1fu) <3 + rawpacket [1]> 5); header. flowtag = (uint) (rawpacket [1] & 0x1fu) <16 + rawpacket [2] <8 + rawpacket [3]); header. availoad = (ushort) (rawpacket [4] <8) + (ushort) rawpacket [5]); header. nextheader = rawpacket [6]; header. hoplimit = rawpacket [7]; header. srcip = util. joinbytearr (util. subbytearr (rawpacket, 8, 16), ":", "X2", 2); header. dstip = util. joinbytearr (util. subbytearr (rawpacket, 24, 16), ":", "X2", 2); Return header;} public byte [] getbody () {body = util. subbytearr (rawpacket, 40); return body ;}}
Through the analysis of these protocols, you can have a deeper understanding of network transmission and provide good guidance for application development at the application layer.
Analysis of packets hosted on Ethernet frames-arp, IPv4, and IPv6