3 * - IPv4 Protcol Handling
10 extern tInterface *gIP_Interfaces;
11 extern void ICMP_Initialise();
12 extern void UDP_Initialise();
15 int IPv4_Initialise();
16 int IPv4_RegisterCallback(int ID, tIPCallback Callback);
17 void IPv4_int_GetPacket(tAdapter *Interface, tMacAddr From, int Length, void *Buffer);
18 tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast);
19 Uint32 IPv4_Netmask(int FixedBits);
22 tIPCallback gaIPv4_Callbacks[256];
26 * \fn int IPv4_Initialise()
32 Link_RegisterType(IPV4_ETHERNET_ID, IPv4_int_GetPacket);
37 * \fn int IPv4_RegisterCallback( int ID, tIPCallback Callback )
38 * \brief Registers a callback
40 int IPv4_RegisterCallback(int ID, tIPCallback Callback)
42 if( ID < 0 || ID > 255 ) return 0;
43 if( gaIPv4_Callbacks[ID] ) return 0;
44 gaIPv4_Callbacks[ID] = Callback;
49 * \fn void IPv4_int_GetPacket(tInterface *Adapter, tMacAddr From, int Length, void *Buffer)
50 * \brief Process an IPv4 Packet
52 void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer)
54 tIPv4Header *hdr = Buffer;
58 if(Length < sizeof(tIPv4Header)) return;
60 //Log("[IPv4 ] Version = %i", hdr->Version);
61 Log("[IPv4 ] HeaderLength = %i", hdr->HeaderLength);
62 Log("[IPv4 ] DiffServices = %i", hdr->DiffServices);
63 //Log("[IPv4 ] TotalLength = %i", ntohs(hdr->TotalLength) );
64 //Log("[IPv4 ] Identifcation = %i", ntohs(hdr->Identifcation) );
65 //Log("[IPv4 ] TTL = %i", hdr->TTL );
66 Log("[IPv4 ] Protocol = %i", hdr->Protocol );
67 //Log("[IPv4 ] HeaderChecksum = 0x%x", ntohs(hdr->HeaderChecksum) );
68 Log("[IPv4 ] Source = %i.%i.%i.%i",
69 hdr->Source.B[0], hdr->Source.B[1], hdr->Source.B[2], hdr->Source.B[3] );
70 Log("[IPv4 ] Destination = %i.%i.%i.%i",
71 hdr->Destination.B[0], hdr->Destination.B[1],
72 hdr->Destination.B[2], hdr->Destination.B[3] );
74 // Check that the version IS IPv4
75 if(hdr->Version != 4) {
76 Log("[IPv4 ] hdr->Version(%i) != 4", hdr->Version);
80 // Check Header checksum
83 // Check Packet length
84 if( ntohs(hdr->TotalLength) > Length) {
85 Log("[IPv4 ] hdr->TotalLength(%i) > Length(%i)", hdr->TotalLength, Length);
89 // Get Interface (allowing broadcasts)
90 iface = IPv4_GetInterface(Adapter, hdr->Destination, 1);
92 Log("[IPv4 ] Ignoring Packet (Not for us)");
93 return; // Not for us? Well, let's ignore it
99 dataLength = hdr->TotalLength - sizeof(tIPv4Header);
100 data = &hdr->Options[0];
103 gaIPv4_Callbacks[hdr->Protocol] (iface, &hdr->Source, dataLength, data);
107 * \fn tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address)
108 * \brief Searches an adapter for a matching address
110 tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast)
112 tInterface *iface = NULL;
116 addr = ntohl( Address.L );
118 for( iface = gIP_Interfaces; iface; iface = iface->Next)
120 if( iface->Adapter != Adapter ) continue;
121 if( iface->Type != 4 ) continue;
122 if( IP4_EQU(Address, iface->IP4.Address) )
125 if( !Broadcast ) continue;
127 this = ntohl( iface->IP4.Address.L );
129 // Check for broadcast
130 netmask = IPv4_Netmask(iface->IP4.SubnetBits);
132 //Log("netmask = 0x%08x", netmask);
133 //Log("addr = 0x%08x", addr);
134 //Log("this = 0x%08x", this);
135 //Log("%08x == %08x && %08x == %08x",
136 // (addr & netmask), (this & netmask),
137 // (addr & ~netmask), (0xFFFFFFFF & ~netmask)
139 if( (addr & netmask) == (this & netmask)
140 && (addr & ~netmask) == (0xFFFFFFFF & ~netmask) )
147 * \brief Convert a network prefix to a netmask
149 * For example /24 will become 255.255.255.0
151 Uint32 IPv4_Netmask(int FixedBits)
153 Uint32 ret = 0xFFFFFFFF;
154 ret >>= (32-FixedBits);
155 ret <<= (32-FixedBits);
156 // Returs a little endian netmask