// methods: public static int Write(byte [] !pkt, int offset, EthernetAddress srchw, IPv4 srcip, Type operation, EthernetAddress targethw, IPv4 targetip) { int o = offset; pkt[o++] = 0x00; pkt[o++] = 0x01; // hardware type = 0x0001 pkt[o++] = 0x08; pkt[o++] = 0x00; // protocol type = 0x0800 pkt[o++] = 0x06; // hardware addr len (bytes) pkt[o++] = 0x04; // protocol address len (bytes) pkt[o++] = (byte)(((ushort)operation) >> 8); pkt[o++] = (byte)(((ushort)operation) & 0xff); srchw.CopyOut(pkt, o); o += EthernetAddress.Length; srcip.CopyOut(pkt, o); o += IPv4.Length; targethw.CopyOut(pkt, o); o += EthernetAddress.Length; targetip.CopyOut(pkt, o); o += IPv4.Length; return(o); }
public static int Write(Bytes pkt, EthernetAddress srchw, IPv4 srcip, ushort operation, EthernetAddress targethw, IPv4 targetip) { int o = 0; pkt[o++] = 0x00; pkt[o++] = 0x01; // hardware type = 0x0001 pkt[o++] = 0x08; pkt[o++] = 0x00; // protocol type = 0x0800 pkt[o++] = 0x06; // hardware addr len (bytes) pkt[o++] = 0x04; // protocol address len (bytes) pkt[o++] = (byte)(operation >> 8); pkt[o++] = (byte)(operation & 0xff); srchw.CopyOut(pkt.Array, pkt.Start + o); o += EthernetAddress.Length; srcip.CopyOut(pkt.Array, pkt.Start + o); o += IPv4.Length; targethw.CopyOut(pkt.Array, pkt.Start + o); o += EthernetAddress.Length; targetip.CopyOut(pkt.Array, pkt.Start + o); o += IPv4.Length; return(o); }
//assume ethernet //we have to expose this for the DhcpClient //Once we move the Dhcp client into an app this can be hidden again public void WriteCompleteUDPHeader(Bytes header, Bytes data, int payloadLength) { int totalLength = IpHeader.Size + UDPHeader.Size + payloadLength; //write ip header int offset = EthernetHeader.Size; int o = EthernetHeader.Size; DebugStub.Assert(payloadLength < 0xffff); header[o++] = 0x45; //default version 4, header_len 5 header[o++] = 0; //tos header[o++] = (byte)(((ushort)totalLength) >> 8); //total length of the ip header header[o++] = (byte)(((ushort)totalLength) & 0xff); header[o++] = (byte)(((ushort)0) >> 8); //fragment id header[o++] = (byte)(((ushort)0) & 0xff); //fragment id header[o++] = (byte)(((ushort)0) >> 8); //fragment offset header[o++] = (byte)(((ushort)0) & 0xff); //fragment offset header[o++] = 128; //default ttl header[o++] = 17; // protocol ID --> udp header[o++] = 0; //ipchecksum (fill it in later) header[o++] = 0; //ipchecksum // set the ip addresses localIPAddress.CopyOut(header.Array, header.Start + o); o += IPv4.Length; remoteIPAddress.CopyOut(header.Array, header.Start + o); o += IPv4.Length; // calculate checksum ushort chk = IpHeader.CalculateChecksum(header, offset, IpHeader.Size); header[offset + 10] = (byte)(((ushort)chk) >> 8); header[offset + 11] = (byte)(((ushort)chk) & 0xff); //write the udp header header[o++] = (byte)(((ushort)localPort) >> 8); header[o++] = (byte)(((ushort)localPort) & 0xff); header[o++] = (byte)(((ushort)remotePort) >> 8); header[o++] = (byte)(((ushort)remotePort) & 0xff); ushort udpLength = (ushort)(UDPHeader.Size + payloadLength); header[o++] = (byte)(((ushort)udpLength) >> 8); header[o++] = (byte)(((ushort)udpLength) & 0xff); // udp checksum (forget for now) header[o++] = 0; header[o++] = 0; UDPHeader.SetUdpChecksum(header, data, EthernetHeader.Size, udpLength); }
// creates an arp reply using the received packet // the packet must be an arp request // the responder should pass its own IP and MAC address // we assume that we have the same hw type // (return offset_arp size) public static int CreateArpReply(ref byte[] !pkt, IPv4 selfIP, EthernetAddress selfMACAddr) { int offset = 14; // arp message starts here. int o = offset; // check we have enough packet if (pkt.Length - offset < Size) { return(offset); } // check hardware type == 0x0001 (Ethernet) if (pkt[o++] != 0x00 || pkt[o++] != 0x01) { return(offset); } // check protocol type == 0x0800 (IP) if (pkt[o++] != 0x08 || pkt[o++] != 0x00) { return(offset); // error } // check addresses len if (pkt[o++] != 0x06) { return(offset); } if (pkt[o++] != 0x04) { return(offset); } // operation code Type opcode = (Type)(((int)pkt[o++] << 8) | (int)pkt[o++]); // we need a request message. if (opcode != Type.ARP_REQUEST) { return(offset); } // sender HW & IP EthernetAddress senderhw = EthernetAddress.ParseBytes(pkt, o); o += EthernetAddress.Length; IPv4 senderIP = IPv4.ParseBytes(pkt, o); o += IPv4.Length; // target HW & IP // EthernetAddress targethw = EthernetAddress.ParseBytes(pkt, o); o += EthernetAddress.Length; // IPv4 targetIP = IPv4.ParseBytes(pkt, o); o += IPv4.Length; // all is well, do our stuff... // 1. set local hw address to arp's source ether address + fix dest addresses // 2. set arp type = ARP_REPLY // 3. set the destination's ethernet address to self // and target is the source of the request. o = offset + 6; // opcode entry pkt[o++] = (byte)(((ushort)Type.ARP_REPLY) >> 8); pkt[o++] = (byte)Type.ARP_REPLY; // set hw and IP address selfMACAddr.CopyOut(pkt, o); o += EthernetAddress.Length; selfIP.CopyOut(pkt, o); o += IPv4.Length; // setup dest address to the requesting host address senderhw.CopyOut(pkt, o); o += EthernetAddress.Length; senderIP.CopyOut(pkt, o); o += IPv4.Length; // set ethernet level addresses Array.Copy(pkt, 6, pkt, 0, 6); // src -> dest selfMACAddr.CopyOut(pkt, 6); // self -> src return(offset + Size); }