X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FIPStack%2Frouting.c;h=7c6ab2ac3105f54033407487a8bb315910dede26;hb=7758e1bf2e2a1ad35def1eb8cf9aab55d13e05a0;hp=33b756cb8602d15f5d4282bd99a71b0d1a4997da;hpb=8c721d1069e9c0c769b847e9903d83b99d1acdfe;p=tpg%2Facess2.git diff --git a/Modules/IPStack/routing.c b/Modules/IPStack/routing.c index 33b756cb..7c6ab2ac 100644 --- a/Modules/IPStack/routing.c +++ b/Modules/IPStack/routing.c @@ -2,7 +2,7 @@ * Acess2 IP Stack * - Routing Tables */ -#define DEBUG 0 +#define DEBUG 1 #define VERSION VER2(0,10) #include #include @@ -12,27 +12,13 @@ // === IMPORTS === tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, const char *Filename); -// === TYPES === -typedef struct sRoute { - struct sRoute *Next; - - tVFS_Node Node; - - tInterface *Interface; // Interface for this route - int AddressType; // 0: Invalid, 4: IPv4, 6: IPv4 - void *Network; // Network - Pointer to tIPv4/tIPv6/... at end of structure - int SubnetBits; // Number of bits in \a Network that are valid - void *NextHop; // Next Hop address - Pointer to tIPv4/tIPv6/... at end of structure - int Metric; // Route priority -} tRoute; - // === PROTOTYPES === // - Routes directory 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); +tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address); // - Individual Routes int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data); @@ -108,6 +94,7 @@ static const char *casIOCtls_RouteDir[] = { int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data) { int tmp; + ENTER("pNode iID pData", Node, ID, Data); switch(ID) { // --- Standard IOCtls (0-3) --- @@ -130,8 +117,10 @@ int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data) return tmp; case 4: // Add Route - if( !CheckString(Data) ) return -1; - return IPStack_Route_Create(Data); + if( !CheckString(Data) ) LEAVE_RET('i', -1); + tmp = IPStack_Route_Create(Data); + LEAVE('i', tmp); + return tmp; case 5: // Locate Route { @@ -142,19 +131,23 @@ int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data) tRoute *rt; if( !CheckMem(Data, sizeof(int)) ) - return -1; + LEAVE_RET('i', -1); if( !CheckMem(Data, sizeof(int) + IPStack_GetAddressSize(data->Type)) ) - return -1; + LEAVE_RET('i', -1); - rt = IPStack_FindRoute(data->Type, data->Addr); + Log_Debug("IPStack", "Route_RouteDir_IOCtl - FindRoute %i, %s", + data->Type, IPStack_PrintAddress(data->Type, data->Addr) ); + rt = IPStack_FindRoute(data->Type, NULL, data->Addr); if( !rt ) - return 0; + LEAVE_RET('i', 0); + LEAVE('i', rt->Node.Inode); return rt->Node.Inode; } break; } + LEAVE('i', 0); return 0; } @@ -172,7 +165,10 @@ int IPStack_Route_Create(const char *InterfaceName) // Note: Oh man! This is such a hack { tVFS_Node *node = IPStack_Root_FindDir(NULL, InterfaceName); - if( !node ) return 0; + if( !node ) { + Log_Debug("IPStack", "IPStack_Route_Create - Unknown interface '%s'\n", InterfaceName); + return 0; + } iface = node->ImplPtr; } @@ -209,33 +205,57 @@ int IPStack_Route_Create(const char *InterfaceName) gIP_Routes = gIP_RoutesEnd = rt; } + Log_Log("IPStack", "Route entry for '%s' created", InterfaceName); + return rt->Node.Inode; } /** */ -tRoute *IPStack_FindRoute(int AddressType, void *Address) +tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address) { tRoute *rt; tRoute *best = NULL; + ENTER("iAddressType pInterface sAddress", + AddressType, Interface, IPStack_PrintAddress(AddressType, Address)); + + if( Interface && AddressType != Interface->Type ) { + LOG("Interface->Type (%i) != AddressType", Interface->Type); + LEAVE('n'); + return NULL; + } + for( rt = gIP_Routes; rt; rt = rt->Next ) { + // Check interface + if( Interface && rt->Interface != Interface ) continue; + // Check address type if( rt->AddressType != AddressType ) continue; + LOG("Checking network %s/%i", IPStack_PrintAddress(AddressType, rt->Network), rt->SubnetBits); + + // Check if the address matches if( !IPStack_CompareAddress(AddressType, rt->Network, Address, rt->SubnetBits) ) continue; if( best ) { // More direct routes are preferred - if( best->SubnetBits > rt->SubnetBits ) continue; + if( best->SubnetBits > rt->SubnetBits ) { + LOG("Skipped - less direct (%i < %i)", rt->SubnetBits, best->SubnetBits); + continue; + } // If equally direct, choose the best metric - if( best->SubnetBits == rt->SubnetBits && best->Metric < rt->Metric ) continue; + if( best->SubnetBits == rt->SubnetBits && best->Metric < rt->Metric ) { + LOG("Skipped - higher metric (%i > %i)", rt->Metric, best->Metric); + continue; + } } best = rt; } + LEAVE('p', best); return best; } @@ -244,12 +264,14 @@ tRoute *IPStack_FindRoute(int AddressType, void *Address) */ static const char *casIOCtls_Route[] = { DRV_IOCTLNAMES, - "get_network", // Get network - (void *Data) - "set_network", // Set network - (void *Data) - "get_nexthop", // Get next hop - (void *Data) - "set_nexthop", // Set next hop - (void *Data) - "getset_subnetbits", // Get/Set subnet bits - (int *Bits) - "getset_metric", // Get/Set metric - (int *Metric) + "get_type", // Get address type - (void), returns integer type + "get_network", // Get network - (void *Data), returns boolean success + "set_network", // Set network - (void *Data), returns boolean success + "get_nexthop", // Get next hop - (void *Data), returns boolean success + "set_nexthop", // Set next hop - (void *Data), returns boolean success + "getset_subnetbits", // Get/Set subnet bits - (int *Bits), returns current value + "getset_metric", // Get/Set metric - (int *Metric), returns current value + "get_interface", // Get interface name - (char *Name), returns name length, NULL OK NULL }; @@ -284,30 +306,34 @@ int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data) LEAVE('i', tmp); return tmp; - // Get Network + // Get address type case 4: + return rt->AddressType; + + // Get Network + case 5: if( !CheckMem(Data, addrSize) ) return -1; memcpy(Data, rt->Network, addrSize); return 1; // Set Network - case 5: + case 6: if( !CheckMem(Data, addrSize) ) return -1; memcpy(rt->Network, Data, addrSize); return 1; // Get Next Hop - case 6: + case 7: if( !CheckMem(Data, addrSize) ) return -1; memcpy(Data, rt->NextHop, addrSize); return 1; // Set Next Hop - case 7: + case 8: if( !CheckMem(Data, addrSize) ) return -1; memcpy(rt->NextHop, Data, addrSize); return 1; // Get/Set Subnet Bits - case 8: + case 9: if( Data ) { if( !CheckMem(Data, sizeof(int)) ) return -1; if( *iData < 0 || *iData > addrSize*8 ) @@ -317,7 +343,7 @@ int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data) return rt->SubnetBits; // Get/Set Metric - case 9: + case 10: if( Data ) { if( !CheckMem(Data, sizeof(int)) ) return -1; if( *iData < 0 ) return -1; @@ -325,7 +351,16 @@ int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data) } return rt->Metric; + // Get interface name + case 11: + if( Data ) { + if( !CheckMem(Data, strlen(rt->Interface->Name) + 1) ) + return -1; + strcpy(Data, rt->Interface->Name); + } + return strlen(rt->Interface->Name); + default: - return 0; + return -1; } }