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

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