Composite commit (GUI / Networking)
[tpg/acess2.git] / Modules / IPStack / routing.c
1 /*
2  * Acess2 IP Stack
3  * - Routing Tables
4  */
5 #include "ipstack.h"
6 #include "link.h"
7
8
9 // === TYPES ===
10 typedef struct sRoute {
11         struct sRoute   *Next;
12         tVFS_Node       Node;
13         
14          int    AddressType;    // 0: Invalid, 4: IPv4, 6: IPv4
15         void    *Network;       // Pointer to tIPv4/tIPv6/... at end of structure
16          int    SubnetBits;
17         void    *NextHop;       // Pointer to tIPv4/tIPv6/... at end of structure
18         tInterface      *Interface;
19 }       tRoute;
20
21 // === PROTOTYPES ===
22 // - Routes directory
23 char    *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos);
24 tVFS_Node       *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name);
25  int    IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data);
26  int    IPStack_Route_Create(const char *InterfaceName);
27 // - Individual Routes
28 Uint64  IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data);
29
30
31 // === GLOBALS ===
32  int    giIP_NextRouteId = 1;
33 tRoute  *gIP_Routes;
34 tRoute  *gIP_RoutesEnd;
35 tVFS_Node       gIP_RouteNode = {
36         Flags: VFS_FFLAG_DIRECTORY,
37         Size: -1,
38         NumACLs: 1,
39         ACLs: &gVFS_ACL_EveryoneRX,
40         ReadDir: IPStack_RouteDir_ReadDir,
41         FindDir: IPStack_RouteDir_FindDir,
42         IOCtl: IPStack_RouteDir_IOCtl
43 };
44
45 // === CODE ===
46 /**
47  * \brief ReadDir for the /Devices/ip/routes/ directory
48  */
49 char *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos)
50 {
51         tRoute  *rt;
52         
53         for(rt = gIP_Routes; rt && Pos --; rt = rt->Next);
54         
55         if( !rt ) {
56                 return NULL;
57         }
58         
59         {
60                  int    len = snprintf(NULL, 12, "%i", rt->Node.Inode);
61                 char    buf[len+1];
62                 sprintf(buf, "%i", rt->Node.Inode);
63                 return strdup(buf);
64         }
65 }
66
67 /**
68  * \brief FindDir for the /Devices/ip/routes/ directory
69  */
70 tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name)
71 {
72          int    num = atoi(Name);
73         
74         // Zero is invalid, sorry :)
75         if( !num )      return NULL;
76         
77         // The list is inherently sorted, so we can do a quick search
78         for(rt = gIP_Routes; rt && rt->Node.Inode < num; rt = rt->Next);
79         // Fast fail on larger number
80         if( rt->Node.Inode > num )
81                 return NULL;
82         
83         return &rt->Node;
84 }
85
86 /**
87  * \brief Names for interface IOCtl Calls
88  */
89 static const char *casIOCtls_RouteDir[] = {
90         DRV_IOCTLNAMES,
91         "add_route"     // Add a route - char *InterfaceName
92         NULL
93         };
94
95 int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data)
96 {
97         switch(ID)
98         {
99         // --- Standard IOCtls (0-3) ---
100         case DRV_IOCTL_TYPE:
101                 LEAVE('i', DRV_TYPE_MISC);
102                 return DRV_TYPE_MISC;
103         
104         case DRV_IOCTL_IDENT:
105                 tmp = ModUtil_SetIdent(Data, STR(IDENT));
106                 LEAVE('i', 1);
107                 return 1;
108         
109         case DRV_IOCTL_VERSION:
110                 LEAVE('x', VERSION);
111                 return VERSION;
112         
113         case DRV_IOCTL_LOOKUP:
114                 tmp = ModUtil_LookupString( (char**)casIOCtls_RouteDir, (char*)Data );
115                 LEAVE('i', tmp);
116                 return tmp;
117         
118         case 4: // Add Route
119                 if( !CheckString(Data) )        return -1;
120                 return IPStack_Route_Create(Data);
121         }
122         return 0;
123 }
124
125 /**
126  * \brief Create a new route entry
127  */
128 int IPStack_Route_Create(const char *InterfaceName)
129 {
130         tRoute  *rt;
131         tInterface      *iface;
132          int    size;
133         
134         // Get interface
135         // Note: Oh man! This is such a hack
136         {
137                 tVFS_Node       *node = IPStack_Root_FindDir(NULL, InterfaceName);
138                 if( !node )     return 0;
139                 iface = node->ImplPtr;
140         }
141         
142         // Get the size of the specified address type
143         size = IPStack_GetAddressSize(iface->AddressType);
144         if( size == 0 ) {
145                 return 0;
146         }
147         
148         // Allocate space
149         rt = calloc(1, sizeof(tRoute) + size*2 );
150         
151         rt->Next = NULL;
152         //rt->Node
153         
154         rt->AddressType = iface->AddressType;
155         rt->Network = (void *)( (tVAddr)rt + sizeof(tRoute) );
156         rt->SubnetBits = 0;
157         rt->NextHop = (void *)( (tVAddr)rt + sizeof(tRoute) + size );
158         rt->Interface = iface;
159 }

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