X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FIPStack%2Frouting.c;h=33b756cb8602d15f5d4282bd99a71b0d1a4997da;hb=8c721d1069e9c0c769b847e9903d83b99d1acdfe;hp=690352ce23629d96c47227a9370cffd9a4ab2263;hpb=fd2f0a88bc702cccc6e15fdf39caaa084c3dd2fe;p=tpg%2Facess2.git diff --git a/Modules/IPStack/routing.c b/Modules/IPStack/routing.c index 690352ce..33b756cb 100644 --- a/Modules/IPStack/routing.c +++ b/Modules/IPStack/routing.c @@ -32,6 +32,7 @@ char *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos); tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name); int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data); int IPStack_Route_Create(const char *InterfaceName); +tRoute *IPStack_FindRoute(int AddressType, void *Address); // - Individual Routes int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data); @@ -97,6 +98,7 @@ tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name) static const char *casIOCtls_RouteDir[] = { DRV_IOCTLNAMES, "add_route", // Add a route - char *InterfaceName + "locate_route", // Find the best route for an address - struct {int Type, char Address[]} * NULL }; @@ -130,6 +132,28 @@ int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data) case 4: // Add Route if( !CheckString(Data) ) return -1; return IPStack_Route_Create(Data); + + case 5: // Locate Route + { + struct { + int Type; + Uint8 Addr[]; + } *data = Data; + tRoute *rt; + + if( !CheckMem(Data, sizeof(int)) ) + return -1; + if( !CheckMem(Data, sizeof(int) + IPStack_GetAddressSize(data->Type)) ) + return -1; + + rt = IPStack_FindRoute(data->Type, data->Addr); + + if( !rt ) + return 0; + + return rt->Node.Inode; + } + break; } return 0; } @@ -188,6 +212,33 @@ int IPStack_Route_Create(const char *InterfaceName) return rt->Node.Inode; } +/** + */ +tRoute *IPStack_FindRoute(int AddressType, void *Address) +{ + tRoute *rt; + tRoute *best = NULL; + + for( rt = gIP_Routes; rt; rt = rt->Next ) + { + if( rt->AddressType != AddressType ) continue; + + if( !IPStack_CompareAddress(AddressType, rt->Network, Address, rt->SubnetBits) ) + continue; + + if( best ) { + // More direct routes are preferred + if( best->SubnetBits > rt->SubnetBits ) continue; + // If equally direct, choose the best metric + if( best->SubnetBits == rt->SubnetBits && best->Metric < rt->Metric ) continue; + } + + best = rt; + } + + return best; +} + /** * \brief Names for route IOCtl Calls */