// handle incoming IP packets public NetStatus OnProtocolReceive(NetPacket !pkt) { IPFormat.IPHeader !ipHeader; if (IPFormat.ReadIPHeader(pkt, out ipHeader) == false) { DebugPrint("bad header\n"); return(NetStatus.Code.PROTOCOL_OK); } pkt.OverlapContext = ipHeader; Debug.Assert(IPFormat.IsMoreFragSet(ipHeader) == false); // check packet checksum if (IPFormat.IsCheckSumOK(ipHeader) == false) { DebugPrint("checksum error, dropping!\n"); return(NetStatus.Code.PROTOCOL_DROP_CHKSUM); } // check if the packet is for us... // TBC: for now we ignore broadcasts // (directed + limited bcast addresses) Core core = Core.Instance(); // if its not ours but we are a gateway, we should route it. if (hostConfig.IsLocalAddress(ipHeader.Destination) == false && ipHeader.Destination != IPv4.Broadcast) { if (hostConfig.IsRouter) { // Not supported for the time being. } // DebugPrint("Dropping wrong destination\n"); return(NetStatus.Code.RT_DROP_WRONG_DEST); } // we should handle it.. IProtocol prot = core.GetProtocolFromID(ipHeader.protocol); if (prot == null) { DebugPrint("Packet drop no handler for protocol id = {0}\n", (ushort)ipHeader.protocol); return(NetStatus.Code.RT_DROP_NO_HANDLER); } else { DebugPrint("Got packet of type {0}\n", ipHeader.protocol); } // clip the packet for the next protocol header + data pkt.Clip(ipHeader.totalLength - IPFormat.Size - 1); return(prot.OnProtocolReceive(pkt)); }
//When it is in Mode 2 private static IPLocation ReadMode2Record(FileStream fs, BinaryReader reader, IPAddress ip) { uint countryOffset = IPFormat.ToUint(reader.ReadBytes(IPFormat.RecOffsetLength)); uint curOffset = Convert.ToUInt32(fs.Position); if (countryOffset == 0) return GetUnknownLocation(ip); fs.Position = countryOffset; string country = ReadString(reader); string zone = ReadZone(fs, reader, curOffset); return new IPLocation(ip, country, zone); }
private static IPLocation GetIPInfo(FileStream fs, BinaryReader reader, long offset, IPAddress ipToLoc, Byte[] ipBytes) { fs.Position = offset; //To confirm that the given ip is within the range of record IP range byte[] endIP = reader.ReadBytes(4); uint endIpVal = BitConverter.ToUInt32(endIP, 0); uint ipVal = BitConverter.ToUInt32(ipBytes, 0); if (endIpVal < ipVal) { return(null); } string country; string zone; //Read the Redirection pattern byte Byte pattern = reader.ReadByte(); if (pattern == RedirectMode.Mode_1) { Byte[] countryOffsetBytes = reader.ReadBytes(IPFormat.RecOffsetLength); uint countryOffset = IPFormat.ToUint(countryOffsetBytes); if (countryOffset == 0) { return(GetUnknownLocation(ipToLoc)); } fs.Position = countryOffset; if (fs.ReadByte() == RedirectMode.Mode_2) { return(ReadMode2Record(fs, reader, ipToLoc)); } else { fs.Position--; country = ReadString(reader); zone = ReadZone(fs, reader, Convert.ToUInt32(fs.Position)); } } else if (pattern == RedirectMode.Mode_2) { return(ReadMode2Record(fs, reader, ipToLoc)); } else { fs.Position--; country = ReadString(reader); zone = ReadZone(fs, reader, Convert.ToUInt32(fs.Position)); } return(new IPLocation(ipToLoc, country, zone)); }
private void SendResponsePacket(DhcpFormat dhcp) { int packetSize = dhcp.Size + UdpFormat.Size + IPFormat.Size + EthernetFormat.Size; byte [] packet = new byte [packetSize]; // Write out DHCP packet int dhcpSize = dhcp.Size; int dhcpOffset = packet.Length - dhcpSize; dhcp.Write(packet, dhcpOffset); // Create UDP Header UdpFormat.UdpHeader udpHeader = new UdpFormat.UdpHeader(); udpHeader.srcPort = DhcpFormat.ServerPort; udpHeader.dstPort = DhcpFormat.ClientPort; udpHeader.length = (ushort)(UdpFormat.Size + dhcpSize); // Create IP Header IPFormat.IPHeader ipHeader = new NetStack.Protocols.IPFormat.IPHeader(); ipHeader.SetDefaults(IPFormat.Protocol.UDP); IPFormat.SetDontFragBit(ipHeader); ipHeader.Source = ServerAddress; ipHeader.Destination = IPv4.Broadcast; ipHeader.totalLength = (ushort)(IPFormat.Size + UdpFormat.Size + dhcpSize); // Write out IP and Header int udpOffset = packet.Length - dhcp.Size - UdpFormat.Size; int ipOffset = udpOffset - IPFormat.Size; UdpFormat.WriteUdpPacket(packet, ipOffset, ref ipHeader, ref udpHeader, packet, dhcpOffset, dhcpSize); // Add Ethernet Header EthernetFormat.Write(packet, 0, ServerMac, EthernetAddress.Broadcast, EthernetFormat.Protocol.IP); NetPacket np = new NetPacket(packet); if (adapter.ReceivePacket(np) == false) { Console.WriteLine("Failed to send packet"); SetState(ServerState.Failed); } }
//Retrieve the zone info private static string ReadZone(FileStream fs, BinaryReader reader, uint offset) { fs.Position = offset; byte b = reader.ReadByte(); if (b == RedirectMode.Mode_1 || b == RedirectMode.Mode_2) { uint zoneOffset = IPFormat.ToUint(reader.ReadBytes(3)); if (zoneOffset == 0) return IPFormat.UnknownZone; return ReadZone(fs, reader, zoneOffset); } else { fs.Position--; return ReadString(reader); } }
internal bool Send(EthernetAddress dstAddr, DhcpFormat !dhcp) { int packetSize = dhcp.Size + UdpFormat.Size + IPFormat.Size + EthernetFormat.Size; byte [] packet = new byte [packetSize]; // Write out DHCP packet int dhcpSize = dhcp.Size; int dhcpOffset = packet.Length - dhcpSize; dhcp.Write(packet, dhcpOffset); // Create UDP Header UdpFormat.UdpHeader udpHeader = new UdpFormat.UdpHeader(); udpHeader.srcPort = DhcpFormat.ClientPort; udpHeader.dstPort = DhcpFormat.ServerPort; udpHeader.length = (ushort)(UdpFormat.Size + dhcpSize); // Create IP Header IPFormat.IPHeader ipHeader = new NetStack.Protocols.IPFormat.IPHeader(); ipHeader.SetDefaults(IPFormat.Protocol.UDP); IPFormat.SetDontFragBit(ipHeader); ipHeader.Source = IPv4.Any; ipHeader.Destination = IPv4.Broadcast; ipHeader.totalLength = (ushort)(IPFormat.Size + UdpFormat.Size + dhcpSize); // Write out IP and Header int udpOffset = packet.Length - dhcp.Size - UdpFormat.Size; int ipOffset = udpOffset - IPFormat.Size; UdpFormat.WriteUdpPacket(packet, ipOffset, ipHeader, ref udpHeader, packet, dhcpOffset, dhcpSize); // Add Ethernet Header EthernetFormat.Write(packet, 0, adapter.HardwareAddress, dstAddr, EthernetFormat.PROTOCOL_IP); NetPacket np = new NetPacket(packet); return(udpSession.WritePacket(np)); }
// this method sends an IP packet. It uses the IP header // target address to find route and sets the packet's Mux. // it also sets the target and source mac addresses public NetStatus OnProtocolSend(NetPacket !packet) { Multiplexer mux = (Multiplexer)packet.Mux; if (mux != null) { byte[] !data = (byte[] !)packet.GetRawData(); // Source has already resolved outbound mux. Check // briefly that they've put values in for ethernet headers // (yes, only ethernet is supported here folks) int dstOkay = ((int)data[0] | (int)data[1] | (int)data[2] | (int)data[3] | (int)data[4] | (int)data[5]); int srcOkay = ((int)data[6] | (int)data[7] | (int)data[8] | (int)data[9] | (int)data[10] | (int)data[11]); if (dstOkay != 0 && srcOkay != 0) { mux.SendBuffered(packet); DebugPrint("Packet sent (had mux)\n"); return(NetStatus.Code.PROTOCOL_OK); } // Invalid destination or source address. Ignore request // to send via specific mux. } // since we may retransmit this packet, we should // reset the buffer to the IP boundaries! packet.Clip(EthernetFormat.Size, packet.Length - EthernetFormat.Size - 1); IPFormat.IPHeader !ipHeader; if (IPFormat.ReadIPHeader(packet, out ipHeader) == false) { DebugPrint("Packet dropped error)\n"); DebugStub.Break(); return(NetStatus.Code.PROTOCOL_DROP_ERROR); } Debug.Assert(ipHeader.Destination != IPv4.Zero); RouteEntry e = HostConfiguration.RoutingTable.Lookup(ipHeader.Destination); if (e == null) { DebugPrint("Packet dropped no route)\n"); return(NetStatus.Code.RT_DROP_NO_ROUTE); } // DebugPrint("{0} -> {1}\n", ipHeader.Destination, e); // DebugPrint("Packet source {0}\n", ipHeader.Source); IPv4 ifaddr = e.InterfaceAddress; IPv4 nexthop; if (e.Gateway == e.InterfaceAddress) { nexthop = ipHeader.Destination; } else { nexthop = e.Gateway; } // DebugPrint("Selected destination {0}\n", nexthop); IAdapter adapter = hostConfig.Bindings.GetAdapter(ifaddr); assert adapter != null; Multiplexer targetMux = Core.Instance().GetMuxForAdapter(adapter); assert targetMux != null; packet.Mux = targetMux; EthernetAddress localMac = adapter.HardwareAddress; EthernetAddress remoteMac; IAdapter targetAdapter = hostConfig.Bindings.GetAdapter(nexthop); if (targetAdapter != null) { remoteMac = targetAdapter.HardwareAddress; } else { if (arp.Lookup(nexthop, out remoteMac) == false) { DebugPrint("No ARP Entry for: {0}\n", nexthop); arp.ArpRequest(ipHeader.Source, nexthop, targetMux, new ArpRequestCallback(ArpResponse), packet, TimeSpan.FromSeconds(3)); BlockAssociatedSession(packet); return(NetStatus.Code.RT_RETRY_PENDING_ARP); } } return(SendResolved(packet, targetMux, localMac, remoteMac)); }
/// <summary> /// Check Ethernet, IP, and UDP headers match those expected. /// </summary> private bool ValidHeaders(NetPacket packet) { if (packet.Length < NonDhcpHeaderSize) { Console.WriteLine("Packet too short"); return(false); } // // Check EthernetHeader // EthernetAddress originMac; EthernetAddress targetMac; EthernetFormat.Protocol protocol; EthernetFormat.Read(packet, out originMac, out targetMac, out protocol); if (originMac != adapter.HardwareAddress) { Console.WriteLine("Bad origin mac: {0}", originMac); return(false); } else if (targetMac != EthernetAddress.Broadcast && targetMac != ServerMac) { Console.WriteLine("Bad target mac: {0}", targetMac); return(false); } else if (protocol != EthernetFormat.Protocol.IP) { Console.WriteLine("Bad encapsulated protocol: {0}", protocol); return(false); } // // Check IP Header // IPFormat.IPHeader ipHeader; if (IPFormat.ReadIPHeader(packet, out ipHeader) == false) { Console.WriteLine("Failed to read IP Header"); return(false); } else if (ipHeader.Protocol != IPFormat.Protocol.UDP) { Console.WriteLine("Bad encapsulated IP protocol: {0}", ipHeader.Protocol); return(false); } else if (ipHeader.Source != IPv4.Zero && ipHeader.Source != assignedAddress) { Console.WriteLine("Bad IP source address: {0}", ipHeader.Source); return(false); } else if (ipHeader.Destination != IPv4.AllOnes && ipHeader.Destination != ServerAddress) { Console.WriteLine("Bad IP destination address: {0}", ipHeader.Destination); return(false); } Console.WriteLine("{0} {1}", ipHeader.Source, ipHeader.Destination); // // Check UDP Header // UdpFormat.UdpHeader udpHeader; if (UdpFormat.ReadUdpHeader(packet, out udpHeader) == false) { Console.WriteLine("Failed to read UDP Header"); return(false); } else if (udpHeader.srcPort != 68) { Console.WriteLine("Bad UDP source port: {0}", udpHeader.srcPort); return(false); } else if (udpHeader.dstPort != 67) { Console.WriteLine("Bad UDP destination port: {0}", udpHeader.dstPort); return(false); } return(true); }