+
+ // Add to list
+ if( gIP_RoutesEnd ) {
+ gIP_RoutesEnd->Next = rt;
+ gIP_RoutesEnd = rt;
+ }
+ else {
+ gIP_Routes = gIP_RoutesEnd = rt;
+ }
+
+ return rt->Node.Inode;
+}
+
+/**
+ * \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)
+ NULL
+ };
+
+/**
+ * \brief IOCtl for /Devices/ip/routes/#
+ */
+int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data)
+{
+ int tmp;
+ int *iData = Data;
+ tRoute *rt = Node->ImplPtr;
+ int addrSize = IPStack_GetAddressSize(rt->AddressType);
+
+ switch(ID)
+ {
+ // --- Standard IOCtls (0-3) ---
+ case DRV_IOCTL_TYPE:
+ LEAVE('i', DRV_TYPE_MISC);
+ return DRV_TYPE_MISC;
+
+ case DRV_IOCTL_IDENT:
+ tmp = ModUtil_SetIdent(Data, STR(IDENT));
+ LEAVE('i', 1);
+ return 1;
+
+ case DRV_IOCTL_VERSION:
+ LEAVE('x', VERSION);
+ return VERSION;
+
+ case DRV_IOCTL_LOOKUP:
+ tmp = ModUtil_LookupString( (char**)casIOCtls_Route, (char*)Data );
+ LEAVE('i', tmp);
+ return tmp;
+
+ // Get Network
+ case 4:
+ if( !CheckMem(Data, addrSize) ) return -1;
+ memcpy(Data, rt->Network, addrSize);
+ return 1;
+ // Set Network
+ case 5:
+ if( !CheckMem(Data, addrSize) ) return -1;
+ memcpy(rt->Network, Data, addrSize);
+ return 1;
+
+ // Get Next Hop
+ case 6:
+ if( !CheckMem(Data, addrSize) ) return -1;
+ memcpy(Data, rt->NextHop, addrSize);
+ return 1;
+ // Set Next Hop
+ case 7:
+ if( !CheckMem(Data, addrSize) ) return -1;
+ memcpy(rt->NextHop, Data, addrSize);
+ return 1;
+
+ // Get/Set Subnet Bits
+ case 8:
+ if( Data ) {
+ if( !CheckMem(Data, sizeof(int)) ) return -1;
+ if( *iData < 0 || *iData > addrSize*8 )
+ return -1;
+ rt->SubnetBits = *iData;
+ }
+ return rt->SubnetBits;
+
+ // Get/Set Metric
+ case 9:
+ if( Data ) {
+ if( !CheckMem(Data, sizeof(int)) ) return -1;
+ if( *iData < 0 ) return -1;
+ rt->Metric = *iData;
+ }
+ return rt->Metric;
+
+ default:
+ return 0;
+ }