b709dfa0999ba50ba5cf6c8bceff93fd30195eb3
[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  * \fn int IPv6_Initialise()
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  */
32 void IPv6_int_GetPacket(tAdapter *Interface, tMacAddr From, int Length, void *Buffer)
33 {
34         tIPv6Header     *hdr = Buffer;
35         if(Length < sizeof(tIPv6Header))        return;
36         
37         if( ((hdr->Head >> (20+8)) & 0xF) != 6 )
38                 return;
39         
40         Log("[IPv6 ] hdr = {");
41         Log("[IPv6 ]  .Version = %i", (hdr->Head >> (20+8)) & 0xF );
42         Log("[IPv6 ]  .TrafficClass = %i", (hdr->Head >> (20)) & 0xFF );
43         Log("[IPv6 ]  .FlowLabel = %i", hdr->Head & 0xFFFFF );
44         Log("[IPv6 ]  .PayloadLength = 0x%04x", ntohs(hdr->PayloadLength) );
45         Log("[IPv6 ]  .NextHeader = 0x%02x", hdr->NextHeader );
46         Log("[IPv6 ]  .HopLimit = 0x%02x", hdr->HopLimit );
47         Log("[IPv6 ]  .Source = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Source );
48         Log("[IPv6 ]  .Destination = %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", hdr->Destination );
49         Log("[IPv6 ] }");
50         
51 }
52
53 /**
54  * \fn tInterface *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address)
55  * \brief Searches an adapter for a matching address
56  */
57 tInterface *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address, int Broadcast)
58 {
59          int    i, j;
60         tInterface      *iface = NULL;
61         Uint32  netmask;
62         
63         for( iface = gIP_Interfaces; iface; iface = iface->Next)
64         {
65                 // Check for this adapter
66                 if( iface->Adapter != Adapter ) continue;
67                 
68                 // Skip non-IPv6 Interfaces
69                 if( iface->Type != 6 )  continue;
70                 
71                 // If the address is a perfect match, return this interface
72                 if( IP6_EQU(Address, iface->IP6.Address) )      return iface;
73                 
74                 // Check if we want to match broadcast addresses
75                 if( !Broadcast )        continue;
76                 
77                 // Check for broadcast
78                 if( iface->IP6.SubnetBits > 32 && Address.L[0] != iface->IP6.Address.L[0] )
79                         continue;
80                 if( iface->IP6.SubnetBits > 64 && Address.L[1] != iface->IP6.Address.L[1] )
81                         continue;
82                 if( iface->IP6.SubnetBits > 96 && Address.L[2] != iface->IP6.Address.L[2] )
83                         continue;
84                 
85                 j = iface->IP6.SubnetBits / 32;
86                 i = iface->IP6.SubnetBits % 32;
87                 netmask = IPv4_Netmask( iface->IP6.SubnetBits % 32 );
88                 
89                 // Check the last bit of the netmask
90                 if( (Address.L[j] >> i) != (iface->IP6.Address.L[j] >> i) )     continue;
91                 
92                 // Check that the host portion is one
93                 if( (Address.L[j] & ~netmask) != (0xFFFFFFFF & ~netmask) )      continue;
94                 if( j >= 2 && Address.L[3] != 0xFFFFFFFF)       continue;
95                 if( j >= 1 && Address.L[2] != 0xFFFFFFFF)       continue;
96                 if( j >= 0 && Address.L[1] != 0xFFFFFFFF)       continue;
97                 
98                 return iface;
99         }
100         return NULL;
101 }

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