using sys = System; using Cosmos.HAL; using Cosmos.HAL.Network; using Cosmos.System.Network.IPv4; namespace Cosmos.System.Network.ARP { /// /// ARPPacket class. See also: . /// internal class ARPPacket : EthernetPacket { /// /// Hardware type. /// protected ushort aHardwareType; /// /// Protocol type. /// protected ushort aProtocolType; /// /// Hardware address length. /// protected byte aHardwareLen; /// /// Protocol address length. /// protected byte aProtocolLen; /// /// Operation code. /// protected ushort aOperation; /// /// ARP handler. /// /// Packet data. /// Thrown on fatal error (contact support). /// Thrown on IO error. /// Thrown on fatal error (contact support). /// Thrown on fatal error (contact support). internal static void ARPHandler(byte[] packetData) { ARPPacket arp_packet = new ARPPacket(packetData); //Sys.Console.WriteLine("Received ARP Packet"); //Sys.Console.WriteLine(arp_packet.ToString()); if (arp_packet.Operation == 0x01) { if ((arp_packet.HardwareType == 1) && (arp_packet.ProtocolType == 0x0800)) { ARPRequest_Ethernet arp_request = new ARPRequest_Ethernet(packetData); if (arp_request.SenderIP == null) { NetworkStack.debugger.Send("SenderIP null in ARPHandler!"); } arp_request = new ARPRequest_Ethernet(packetData); ARPCache.Update(arp_request.SenderIP, arp_request.SenderMAC); if (NetworkStack.AddressMap.ContainsKey(arp_request.TargetIP.Hash) == true) { NetworkStack.debugger.Send("ARP Request Recvd from " + arp_request.SenderIP.ToString()); NetworkDevice nic = NetworkStack.AddressMap[arp_request.TargetIP.Hash]; ARPReply_Ethernet reply = new ARPReply_Ethernet(nic.MACAddress, arp_request.TargetIP, arp_request.SenderMAC, arp_request.SenderIP); nic.QueueBytes(reply.RawData); } } } else if (arp_packet.Operation == 0x02) { if ((arp_packet.HardwareType == 1) && (arp_packet.ProtocolType == 0x0800)) { ARPReply_Ethernet arp_reply = new ARPReply_Ethernet(packetData); NetworkStack.debugger.Send("Received ARP Reply"); NetworkStack.debugger.Send(arp_reply.ToString()); NetworkStack.debugger.Send("ARP Reply Recvd from " + arp_reply.SenderIP.ToString()); ARPCache.Update(arp_reply.SenderIP, arp_reply.SenderMAC); OutgoingBuffer.ARPCache_Update(arp_reply); } } } /// /// Work around to make VMT scanner include the initFields method /// public static void VMTInclude() { new ARPPacket(); } /// /// Create new inctanse of the class. /// internal ARPPacket() : base() { } /// /// Create new inctanse of the class. /// /// Raw data. internal ARPPacket(byte[] rawData) : base(rawData) { } /// /// Init ARPPacket fields. /// protected override void initFields() { base.initFields(); aHardwareType = (ushort)((RawData[14] << 8) | RawData[15]); aProtocolType = (ushort)((RawData[16] << 8) | RawData[17]); aHardwareLen = RawData[18]; aProtocolLen = RawData[19]; aOperation = (ushort)((RawData[20] << 8) | RawData[21]); } /// /// Create new inctanse of the class. /// /// Destination MAC address. /// Source MAC address. /// Hardware type. /// Protocol type. /// Hardware address length. /// Protocol length. /// Operation. /// Packet size. protected ARPPacket(MACAddress dest, MACAddress src, ushort hwType, ushort protoType, byte hwLen, byte protoLen, ushort operation, int packet_size) : base(dest, src, 0x0806, packet_size) { RawData[14] = (byte)(hwType >> 8); RawData[15] = (byte)(hwType >> 0); RawData[16] = (byte)(protoType >> 8); RawData[17] = (byte)(protoType >> 0); RawData[18] = hwLen; RawData[19] = protoLen; RawData[20] = (byte)(operation >> 8); RawData[21] = (byte)(operation >> 0); initFields(); } /// /// Get operation. /// internal ushort Operation => aOperation; /// /// Get hardware type. /// internal ushort HardwareType => aHardwareType; /// /// Get protocol type. /// internal ushort ProtocolType => aProtocolType; /// /// To string. /// /// string value. public override string ToString() { return "ARP Packet Src=" + srcMAC + ", Dest=" + destMAC + ", HWType=" + aHardwareType + ", Protocol=" + aProtocolType + ", Operation=" + Operation; } } }