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);
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
};
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;
}
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
*/
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_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
};
}
return rt->Metric;
+ // Get interface name
+ case 10:
+ 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;
}