Пример #1
0
        // 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));
        }
Пример #2
0
 //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);
 }
Пример #3
0
        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));
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
 //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);
     }
 }
Пример #6
0
        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));
        }
Пример #7
0
        // 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));
        }
Пример #8
0
        /// <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);
        }