d57b124dd55aa09a16dab251bdeddc7a175a94fc
[tpg/acess2.git] / Modules / IPStack / ipv4.c
1 /*
2  * Acess2 IP Stack
3  * - IPv4 Protcol Handling
4  */
5 #include "ipstack.h"
6 #include "link.h"
7 #include "ipv4.h"
8
9 // === PROTOTYPES ===
10  int    IPv4_Initialise();
11 void    IPv4_int_GetPacket(tAdapter *Interface, tMacAddr From, int Length, void *Buffer);
12 tInterface      *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast);
13 Uint32  IPv4_Netmask(int FixedBits);
14
15 // === GLOBALS ===
16 tIPCallback     gaIPv4_Callbacks[256];
17
18 // === CODE ===
19 /**
20  * \fn int IPv4_Initialise()
21  */
22 int IPv4_Initialise()
23 {
24         Link_RegisterType(IPV4_ETHERNET_ID, IPv4_int_GetPacket);
25         return 1;
26 }
27
28 /**
29  * \fn void IPv4_int_GetPacket(tInterface *Adapter, tMacAddr From, int Length, void *Buffer)
30  * \brief Process an IPv4 Packet
31  */
32 void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer)
33 {
34         tIPv4Header     *hdr = Buffer;
35         tInterface      *iface;
36         char    *data;
37          int    dataLength;
38         if(Length < sizeof(tIPv4Header))        return;
39         
40         // Check that the version IS IPv4
41         if(hdr->Version != 4)   return;
42         
43         // Check Header checksum
44         //TODO
45         
46         // Check Packet length
47         if(hdr->TotalLength > Length)   return;
48         
49         // Get Interface (allowing broadcasts)
50         iface = IPv4_GetInterface(Adapter, hdr->Source, 1);
51         if(!iface)      return; // Not for us? Well, let's ignore it
52         
53         // Defragment
54         //TODO
55         
56         dataLength = hdr->TotalLength - sizeof(tIPv4Header);
57         data = &hdr->Options[0];
58         
59         // Send it on
60         gaIPv4_Callbacks[hdr->Protocol] (iface, &hdr->Source, dataLength, data);
61 }
62
63 /**
64  * \fn tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address)
65  * \brief Searches an adapter for a matching address
66  */
67 tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast)
68 {
69         tInterface      *iface = NULL;
70         Uint32  netmask;
71         
72         for( iface = Adapter->Interfaces; iface; iface = iface->Next)
73         {
74                 if( iface->Type != 4 )  continue;
75                 if( IP4_EQU(Address, iface->IP4.Address) )
76                         return iface;
77                 
78                 if( !Broadcast )        continue;
79                 
80                 // Check for broadcast
81                 netmask = IPv4_Netmask(iface->IP4.SubnetBits);
82                 if( (Address.L & netmask) == (iface->IP4.Address.L & netmask)
83                  && (Address.L & ~netmask) == (0xFFFFFFFF & ~netmask) )
84                         return iface;
85         }
86         return NULL;
87 }
88
89 /**
90  * \brief Convert a network prefix to a netmask
91  * 
92  * For example /24 will become 255.255.255.0
93  */
94 Uint32 IPv4_Netmask(int FixedBits)
95 {
96         Uint32  ret = 0xFFFFFFFF;
97         ret >>= (32-FixedBits);
98         ret <<= (32-FixedBits);
99         return ret;
100 }

UCC git Repository :: git.ucc.asn.au