Implementing (and using) select() at kernel level
[tpg/acess2.git] / Modules / IPStack / ipv6.c
1 /*
2  * Acess2 IP Stack
3  * - IPv6 Protcol Handling
4  */
5 #include "ipstack.h"
6 #include "link.h"
7 #include "ipv6.h"
8
9 // === IMPORTS ===
10 extern tInterface       *gIP_Interfaces;
11 extern Uint32   IPv4_Netmask(int FixedBits);
12
13 // === PROTOTYPES ===
14  int    IPv6_Initialise();
15 void    IPv6_int_GetPacket(tAdapter *Interface, tMacAddr From, int Length, void *Buffer);
16 tInterface      *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address, int Broadcast);
17
18 // === CODE ===
19 /**
20  * \brief Initialise the IPv6 handling code
21  */
22 int IPv6_Initialise()
23 {
24         Link_RegisterType(IPV6_ETHERNET_ID, IPv6_int_GetPacket);
25         return 1;
26 }
27
28 /**
29  * \fn void IPv6_int_GetPacket(tInterface *Interface, tMacAddr From, int Length, void *Buffer)
30  * \brief Process an IPv6 Packet
31  * \param Interface     Input interface
32  * \param From  Source MAC address
33  * \param Length        Packet length
34  * \param Buffer        Packet data
35  */
36 void IPv6_int_GetPacket(tAdapter *Interface, tMacAddr From, int Length, void *Buffer)
37 {
38         tIPv6Header     *hdr = Buffer;
39         if(Length < sizeof(tIPv6Header))        return;
40         
41         hdr->Head = ntohl(hdr->Head);
42         
43         //if( ((hdr->Head >> (20+8)) & 0xF) != 6 )
44         if( hdr->Version != 6 )
45                 return;
46         
47         Log_Debug("IPv6", "hdr = {");
48         Log_Debug("IPv6", " .Version       = %i", hdr->Version );
49         Log_Debug("IPv6", " .TrafficClass  = %i", hdr->TrafficClass );
50         Log_Debug("IPv6", " .FlowLabel     = %i", hdr->FlowLabel );
51         Log_Debug("IPv6", " .PayloadLength = 0x%04x", ntohs(hdr->PayloadLength) );
52         Log_Debug("IPv6", " .NextHeader    = 0x%02x", hdr->NextHeader );
53         Log_Debug("IPv6", " .HopLimit      = 0x%02x", hdr->HopLimit );
54         Log_Debug("IPv6", " .Source        = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Source );
55         Log_Debug("IPv6", " .Destination   = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Destination );
56         Log_Debug("IPv6", "}");
57         
58 }
59
60 /**
61  * \fn tInterface *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address)
62  * \brief Searches an adapter for a matching address
63  * \param Adapter       Source adapter
64  * \param Address       Destination Address
65  * \param Broadcast     Allow broadcast?
66  */
67 tInterface *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address, int Broadcast)
68 {
69          int    i, j;
70         tInterface      *iface = NULL;
71         Uint32  netmask;
72         
73         for( iface = gIP_Interfaces; iface; iface = iface->Next)
74         {
75                 tIPv6   *thisAddr;
76                 // Check for this adapter
77                 if( iface->Adapter != Adapter ) continue;
78                 
79                 // Skip non-IPv6 Interfaces
80                 if( iface->Type != 6 )  continue;
81                 
82                 thisAddr = (tIPv6*)iface->Address;
83                 // If the address is a perfect match, return this interface
84                 if( IP6_EQU(Address, *thisAddr) )       return iface;
85                 
86                 // Check if we want to match broadcast addresses
87                 if( !Broadcast )        continue;
88                 
89                 // Check for broadcast
90                 if( iface->SubnetBits > 32 && Address.L[0] != thisAddr->L[0] )
91                         continue;
92                 if( iface->SubnetBits > 64 && Address.L[1] != thisAddr->L[1] )
93                         continue;
94                 if( iface->SubnetBits > 96 && Address.L[2] != thisAddr->L[2] )
95                         continue;
96                 
97                 j = iface->SubnetBits / 32;
98                 i = iface->SubnetBits % 32;
99                 netmask = IPv4_Netmask( iface->SubnetBits % 32 );
100                 
101                 // Check the last bit of the netmask
102                 if( (Address.L[j] >> i) != (thisAddr->L[j] >> i) )      continue;
103                 
104                 // Check that the host portion is one
105                 if( (Address.L[j] & ~netmask) != (0xFFFFFFFF & ~netmask) )      continue;
106                 if( j >= 2 && Address.L[3] != 0xFFFFFFFF)       continue;
107                 if( j >= 1 && Address.L[2] != 0xFFFFFFFF)       continue;
108                 if( j >= 0 && Address.L[1] != 0xFFFFFFFF)       continue;
109                 
110                 return iface;
111         }
112         return NULL;
113 }

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