extern int strpos8(const char *str, Uint32 search);
extern void itoa(char *buf, Uint64 num, int base, int minLength, char pad);
extern int atoi(const char *string);
+extern int ParseInt(const char *string, int *Val);
extern int ReadUTF8(const Uint8 *str, Uint32 *Val);
extern int WriteUTF8(Uint8 *str, Uint32 Val);
extern int ModUtil_SetIdent(char *Dest, const char *Value);
extern int ModUtil_LookupString(const char **Array, const char *Needle);
extern Uint8 ByteSum(const void *Ptr, int Size);
+extern int Hex(char *Dest, size_t Size, const Uint8 *SourceData);
extern int UnHex(Uint8 *Dest, size_t DestSize, const char *SourceString);
/**
* \}
EREADONLY, // Read only
ENOTIMPL, // Not implemented
ENOENT, // No entry?
+ EEXIST, // Already exists
ENFILE, // Too many open files
ENOTDIR, // Not a directory
#define VFS_OPENFLAG_WRITE 0x04
//! Do not resolve the final symbolic link
#define VFS_OPENFLAG_NOLINK 0x40
+//! Create the file if it doesn't exist
+#define VFS_OPENFLAG_CREATE 0x80
//! Open as a user
-#define VFS_OPENFLAG_USER 0x80
+#define VFS_OPENFLAG_USER 0x8000
/**
* \}
*/
/**
* \brief Open a file
* \param Path Absolute or relative path to the file
- * \param Mode Flags defining how to open the file
+ * \param Flags Flags defining how to open the file
* \return VFS Handle (an integer) or -1 if an error occured
+ * \note Calls VFS_OpenEx(Path, Flags, 0)
*/
-extern int VFS_Open(const char *Path, Uint Mode);
+extern int VFS_Open(const char *Path, Uint Flags);
+/**
+ * \brief Open a file
+ * \param Path Absolute or relative path to the file
+ * \param Flags Flags defining how to open the file
+ * \param Mode Mode for newly created file (POSIX compatability)
+ * \return VFS Handle (an integer) or -1 if an error occured
+ */
+extern int VFS_OpenEx(const char *Path, Uint Flags, Uint Mode);
/**
* \brief Opens a file via an open directory
* \note The file to open must be a direct child of the parent
extern int VFS_CheckACL(tVFS_Node *Node, Uint Permissions);
// --- mount.c ---
extern tVFS_Mount *VFS_GetMountByIdent(Uint32 MountID);
+// --- dir.c ---
+extern int VFS_MkNod(const char *Path, Uint Flags);
// --- VFS Helpers ---
int ModUtil_LookupString(char **Array, char *Needle);
int ModUtil_SetIdent(char *Dest, char *Value);
+ int Hex(char *Dest, size_t Size, const Uint8 *SourceData);
int UnHex(Uint8 *Dest, size_t DestSize, const char *SourceString);
#endif
* \brief Convert a string into an integer
*/
int atoi(const char *string)
+{
+ int ret = 0;
+ ParseInt(string, &ret);
+ return ret;
+}
+int ParseInt(const char *string, int *Val)
{
int ret = 0;
int bNeg = 0;
+ const char *orig_string = string;
//Log("atoi: (string='%s')", string);
ret *= 10;
ret += *string - '0';
}
+ // Error check
+ if( ret == 0 ) return 0;
}
if(bNeg) ret = -ret;
//Log("atoi: RETURN %i", ret);
- return ret;
+ if(Val) *Val = ret;
+
+ return string - orig_string;
}
static const char cUCDIGITS[] = "0123456789ABCDEF";
return 1;
}
+int Hex(char *Dest, size_t Size, const Uint8 *SourceData)
+{
+ int i;
+ for( i = 0; i < Size; i ++ )
+ {
+ sprintf(Dest + i*2, "%02x", SourceData[i]);
+ }
+ return i*2;
+}
+
/**
* \brief Convert a string of hexadecimal digits into a byte stream
*/
* \fn int VFS_Open(const char *Path, Uint Mode)
* \brief Open a file
*/
-int VFS_Open(const char *Path, Uint Mode)
+int VFS_Open(const char *Path, Uint Flags)
+{
+ return VFS_OpenEx(Path, Flags, 0);
+}
+
+int VFS_OpenEx(const char *Path, Uint Flags, Uint Mode)
{
tVFS_Node *node;
tVFS_Mount *mnt;
char *absPath;
- ENTER("sPath xMode", Path, Mode);
+ ENTER("sPath xFlags oMode", Path, Flags);
// Get absolute path
absPath = VFS_GetAbsPath(Path);
LEAVE_RET('i', -1);
}
LOG("absPath = \"%s\"", absPath);
+
// Parse path and get mount point
node = VFS_ParsePath(absPath, NULL, &mnt);
+
+ // Create file if requested and it doesn't exist
+ if( !node && (Flags & VFS_OPENFLAG_CREATE) )
+ {
+ // TODO: Translate `Mode` into ACL and node flags
+ // Get parent, create node
+ VFS_MkNod(absPath, 0);
+ node = VFS_ParsePath(absPath, NULL, &mnt);
+ }
+
// Free generated path
free(absPath);
- if(!node) {
+ // Check for error
+ if(!node)
+ {
LOG("Cannot find node");
errno = ENOENT;
LEAVE_RET('i', -1);
}
// Check for symlinks
- if( !(Mode & VFS_OPENFLAG_NOLINK) && (node->Flags & VFS_FFLAG_SYMLINK) )
+ if( !(Flags & VFS_OPENFLAG_NOLINK) && (node->Flags & VFS_FFLAG_SYMLINK) )
{
char tmppath[node->Size+1];
if( node->Size > MAX_PATH_LEN ) {
}
}
- LEAVE_RET('x', VFS_int_CreateHandle(node, mnt, Mode));
+ LEAVE_RET('x', VFS_int_CreateHandle(node, mnt, Flags));
}
static char ret[8*4+7+1];
const Uint16 *addr = Address;
sprintf(ret, "%x:%x:%x:%x:%x:%x:%x:%x",
- addr[0], addr[1], addr[2], addr[3],
- addr[4], addr[5], addr[6], addr[7]
+ ntohs(addr[0]), ntohs(addr[1]), ntohs(addr[2]), ntohs(addr[3]),
+ ntohs(addr[4]), ntohs(addr[5]), ntohs(addr[6]), ntohs(addr[7])
);
return ret;
}
// - 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_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+ int IPStack_RouteDir_Relink(tVFS_Node *Node, const char *OldName, const char *NewName);
+tRoute *_Route_FindExactRoute(int Type, void *Network, int Subnet, int Metric);
+ int _Route_ParseRouteName(const char *Name, void *Addr, int *SubnetBits, int *Metric);
int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data);
// - Route Management
-tRoute *IPStack_Route_Create(const char *InterfaceName);
+tRoute *IPStack_Route_Create(int AddrType, void *Network, int SubnetBits, int Metric);
tRoute *IPStack_AddRoute(const char *Interface, void *Network, int SubnetBits, void *NextHop, int Metric);
tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address);
// - Individual Routes
tVFS_NodeType gIP_RouteDirNodeType = {
.ReadDir = IPStack_RouteDir_ReadDir,
.FindDir = IPStack_RouteDir_FindDir,
+ .MkNod = IPStack_RouteDir_MkNod,
+ .Relink = IPStack_RouteDir_Relink,
.IOCtl = IPStack_RouteDir_IOCtl
};
tVFS_Node gIP_RouteNode = {
tRoute *rt;
for(rt = gIP_Routes; rt && Pos --; rt = rt->Next);
-
- if( !rt ) {
- return NULL;
- }
+ if( !rt ) return NULL;
{
- int len = sprintf(NULL, "%i", (int)rt->Node.Inode);
+ int addrlen = IPStack_GetAddressSize(rt->AddressType);
+ int len = sprintf(NULL, "%i::%i:%i", rt->AddressType, rt->SubnetBits, rt->Metric) + addrlen*2;
char buf[len+1];
- sprintf(buf, "%i", (int)rt->Node.Inode);
+ int ofs;
+ ofs = sprintf(buf, "%i:", rt->AddressType);
+ ofs += Hex(buf+ofs, addrlen, rt->Network);
+ sprintf(buf+ofs, ":%i:%i", rt->SubnetBits, rt->Metric);
return strdup(buf);
}
}
*/
tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name)
{
- int num = atoi(Name);
- tRoute *rt;
-
- // Zero is invalid, sorry :)
- if( !num ) return NULL;
-
// Interpret the name as <type>:<addr>, returning the interface for
// needed to access that address.
- // E.g. '4:0A02000A' - 10.2.0.10
+ // E.g. '@4:0A02000A' - 10.2.0.10
// Hm... It could do with a way to have a better address type representation
- if( Name[1] == ':' ) // TODO: Allow variable length type codes
+ if( Name[0] == '@' )
{
- int addrSize = IPStack_GetAddressSize(num);
- Uint8 addrData[addrSize];
+ tRoute *rt;
+ int ofs = 1;
+ int type;
- // Errof if the size is invalid
- if( strlen(Name) != 2 + addrSize*2 )
+ ofs += ParseInt(Name+ofs, &type);
+ int addrSize = IPStack_GetAddressSize(type);
+ Uint8 addrData[addrSize];
+
+ // Separator
+ if( Name[ofs] != ':' ) return NULL;
+ ofs ++;
+
+ // Error if the size is invalid
+ if( strlen(Name+ofs) != addrSize*2 )
return NULL;
// Parse the address
// - Error if the address data is not fully hex
- if( UnHex(addrData, addrSize, Name + 2) != addrSize )
+ if( UnHex(addrData, addrSize, Name + ofs) != addrSize )
return NULL;
// Find the route
- rt = IPStack_FindRoute(num, NULL, addrData);
+ rt = IPStack_FindRoute(type, NULL, addrData);
if(!rt) return NULL;
+
+ if( rt->Interface )
+ {
+ // Return the interface node
+ // - Sure it's hijacking it from inteface.c's area, but it's
+ // simpler this way
+ return &rt->Interface->Node;
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+ else if( Name[0] == '#' )
+ {
+ int num, ofs = 1;
- // Return the interface node
- // - Sure it's hijacking it from inteface.c's area, but it's
- // simpler this way
- return &rt->Interface->Node;
+ ofs = ParseInt(Name+ofs, &num);
+ if( ofs == 1 ) return NULL;
+ if( Name[ofs] != '\0' ) return NULL;
+ if( num < 0) return NULL;
+
+ for( tRoute *rt = gIP_Routes; rt; rt = rt->Next )
+ {
+ if( rt->Node.Inode > num ) return NULL;
+ if( rt->Node.Inode == num ) return &rt->Node;
+ }
+ return NULL;
}
+ else
+ {
+ int type = _Route_ParseRouteName(Name, NULL, NULL, NULL);
+ if( type <= 0 ) return NULL;
+
+ int addrSize = IPStack_GetAddressSize(type);
+ Uint8 addrData[addrSize];
+ int subnet_bits, metric;
+
+ _Route_ParseRouteName(Name, addrData, &subnet_bits, &metric);
+
+ tRoute *rt = _Route_FindExactRoute(type, addrData, subnet_bits, metric);
+ if(rt) return &rt->Node;
+ return NULL;
+ }
+}
+
+/**
+ * \brief Create a new route node
+ */
+int IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
+{
+ if( Flags ) return -EINVAL;
+ if( Threads_GetUID() != 0 ) return -EACCES;
+
+ int type = _Route_ParseRouteName(Name, NULL, NULL, NULL);
+ if( type <= 0 ) return -EINVAL;
+
+ int size = IPStack_GetAddressSize(type);
+ Uint8 addrdata[size];
+ int subnet, metric;
+
+ _Route_ParseRouteName(Name, addrdata, &subnet, &metric);
+
+ // Check for duplicates
+ if( _Route_FindExactRoute(type, addrdata, subnet, metric) )
+ return -EEXIST;
+
+ IPStack_Route_Create(type, addrdata, subnet, metric);
+
+ return 0;
+}
+
+/**
+ * \brief Rename / Delete a route
+ */
+int IPStack_RouteDir_Relink(tVFS_Node *Node, const char *OldName, const char *NewName)
+{
+ tRoute *rt;
- // The list is inherently sorted, so we can do a quick search
- for(rt = gIP_Routes; rt && rt->Node.Inode < num; rt = rt->Next);
+ if( Threads_GetUID() != 0 ) return -EACCES;
+
+ // Get the original route entry
+ {
+ int type = _Route_ParseRouteName(OldName, NULL, NULL, NULL);
+ if(type <= 0) return -EINVAL;
+ Uint8 addr[IPStack_GetAddressSize(type)];
+ int subnet, metric;
+ _Route_ParseRouteName(OldName, addr, &subnet, &metric);
+
+ rt = _Route_FindExactRoute(type, addr, subnet, metric);
+ }
+
+ if( NewName == NULL )
+ {
+ // Delete the route
+ tRoute *prev = NULL;
+ for(tRoute *r = gIP_Routes; r && r != rt; prev = r, r = r->Next);
+
+ if(prev)
+ prev->Next = rt->Next;
+ else
+ gIP_Routes = rt->Next;
+ free(rt);
+ }
+ else
+ {
+ // Change the route
+ int type = _Route_ParseRouteName(NewName, NULL, NULL, NULL);
+ if(type <= 0) return -EINVAL;
+ Uint8 addr[IPStack_GetAddressSize(type)];
+ int subnet, metric;
+ _Route_ParseRouteName(NewName, addr, &subnet, &metric);
+
+ return -ENOTIMPL;
+ }
+ return 0;
+}
+
+tRoute *_Route_FindExactRoute(int Type, void *Network, int Subnet, int Metric)
+{
+ for(tRoute *rt = gIP_Routes; rt; rt = rt->Next)
+ {
+ if( rt->AddressType != Type ) continue;
+ if( rt->Metric != Metric ) continue;
+ if( rt->SubnetBits != Subnet ) continue;
+ if( IPStack_CompareAddress(Type, rt->Network, Network, -1) == 0 )
+ continue ;
+ return rt;
+ }
+ return NULL;
+}
+
+int _Route_ParseRouteName(const char *Name, void *Addr, int *SubnetBits, int *Metric)
+{
+ int type, addrlen;
+ int ofs = 0, ilen;
- // Fast fail end of list / larger number
- if( !rt || rt->Node.Inode > num )
- return NULL;
+ ENTER("sName pAddr pSubnetBits pMetric", Name, Addr, SubnetBits, Metric);
+
+ ilen = ParseInt(Name, &type);
+ if(ilen == 0) {
+ LOG("Type failed to parse");
+ LEAVE_RET('i', -1);
+ }
+ ofs += ilen;
- return &rt->Node;
+ if(Name[ofs] != ':') LEAVE_RET('i', -1);
+ ofs ++;
+
+ addrlen = IPStack_GetAddressSize(type);
+ if( Addr )
+ {
+ if( UnHex(Addr, addrlen, Name + ofs) != addrlen )
+ return -1;
+ }
+ ofs += addrlen*2;
+
+ if(Name[ofs] != ':') LEAVE_RET('i', -1);
+ ofs ++;
+
+ ilen = ParseInt(Name+ofs, SubnetBits);
+ if(ilen == 0) {
+ LOG("Subnet failed to parse");
+ LEAVE_RET('i', -1);
+ }
+ ofs += ilen;
+
+ if(Name[ofs] != ':') LEAVE_RET('i', -1);
+ ofs ++;
+
+ ilen = ParseInt(Name+ofs, Metric);
+ if(ilen == 0) {
+ LOG("Metric failed to parse");
+ LEAVE_RET('i', -1);
+ }
+ ofs += ilen;
+
+ if(Name[ofs] != '\0') LEAVE_RET('i', -1);
+
+ LEAVE('i', type);
+ return type;
}
/**
*/
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
};
*/
int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data)
{
- int tmp;
tRoute *rt;
ENTER("pNode iID pData", Node, ID, Data);
switch(ID)
// --- Standard IOCtls (0-3) ---
BASE_IOCTLS(DRV_TYPE_MISC, STR(IDENT), VERSION, casIOCtls_RouteDir)
- case 4: // Add Route
- if( !CheckString(Data) ) LEAVE_RET('i', -1);
- rt = IPStack_Route_Create(Data);
- if( !rt )
- tmp = -1;
- else
- tmp = rt->Node.Inode;
- LEAVE('i', tmp);
- return tmp;
-
- case 5: // Locate Route
+ case 4: // Locate Route
{
struct {
int Type;
* \brief Create a new route entry
* \param InterfaceName Name of the interface using this route
*/
-tRoute *IPStack_Route_Create(const char *InterfaceName)
+tRoute *IPStack_Route_Create(int AddrType, void *Network, int SubnetBits, int Metric)
{
tRoute *rt;
- tInterface *iface;
int size;
- // Get interface
- // Note: Oh man! This is such a hack
- {
- tVFS_Node *node = IPStack_Root_FindDir(NULL, InterfaceName);
- if( !node ) {
- Log_Debug("IPStack", "IPStack_Route_Create - Unknown interface '%s'\n", InterfaceName);
- return NULL;
- }
- iface = node->ImplPtr;
- if(node->Type->Close) node->Type->Close(node);
- }
-
// Get the size of the specified address type
- size = IPStack_GetAddressSize(iface->Type);
+ size = IPStack_GetAddressSize(AddrType);
if( size == 0 ) {
return NULL;
}
rt->Node.Type = &gIP_RouteNodeType;
// Set up state
- rt->AddressType = iface->Type;
+ rt->AddressType = AddrType;
rt->Network = (void *)( (tVAddr)rt + sizeof(tRoute) );
- rt->SubnetBits = 0;
+ rt->SubnetBits = SubnetBits;
rt->NextHop = (void *)( (tVAddr)rt + sizeof(tRoute) + size );
- rt->Interface = iface;
- rt->Metric = DEFAUTL_METRIC;
- memset(rt->Network, 0, size);
+ rt->Interface = NULL;
+ rt->Metric = Metric;
+ memcpy(rt->Network, Network, size);
memset(rt->NextHop, 0, size);
+ // Clear non-fixed bits
+ {
+ Uint8 *data = rt->Network;
+ int i;
+ i = SubnetBits / 8;
+ if( SubnetBits % 8 ) {
+ data[i] &= ~((1 << (8 - SubnetBits % 8)) - 1);
+ i ++;
+ }
+ memset(data + i, 0, size - i);
+ }
+
+
// Add to list
if( gIP_RoutesEnd ) {
gIP_RoutesEnd->Next = rt;
gIP_Routes = gIP_RoutesEnd = rt;
}
- Log_Log("IPStack", "Route entry for '%s' created", InterfaceName);
+// Log_Log("IPStack", "Route entry for '%s' created", InterfaceName);
return rt;
}
*/
tRoute *IPStack_AddRoute(const char *Interface, void *Network, int SubnetBits, void *NextHop, int Metric)
{
- tRoute *rt = IPStack_Route_Create(Interface);
+ tInterface *iface;
+ tRoute *rt;
int addrSize;
+ {
+ tVFS_Node *tmp;
+ tmp = IPStack_Root_FindDir(NULL, Interface);
+ if(!tmp) return NULL;
+ iface = tmp->ImplPtr;
+ if(tmp->Type->Close) tmp->Type->Close(tmp);
+ }
+
+ rt = IPStack_Route_Create(iface->Type, Network, SubnetBits, Metric);
if( !rt ) return NULL;
- addrSize = IPStack_GetAddressSize(rt->Interface->Type);
+ addrSize = IPStack_GetAddressSize(iface->Type);
+ rt->Interface = iface;
- memcpy(rt->Network, Network, addrSize);
if( NextHop )
memcpy(rt->NextHop, NextHop, addrSize);
- rt->SubnetBits = SubnetBits;
- if( Metric )
- rt->Metric = Metric;
return rt;
}
*/
static const char *casIOCtls_Route[] = {
DRV_IOCTLNAMES,
- "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
+ "set_interface", // Set interface - (const char *Name)
NULL
};
*/
int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data)
{
- int *iData = Data;
tRoute *rt = Node->ImplPtr;
int addrSize = IPStack_GetAddressSize(rt->AddressType);
// --- Standard IOCtls (0-3) ---
BASE_IOCTLS(DRV_TYPE_MISC, STR(IDENT), VERSION, casIOCtls_Route)
- // 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 6:
- if( !CheckMem(Data, addrSize) ) return -1;
- memcpy(rt->Network, Data, addrSize);
- return 1;
-
// Get Next Hop
- case 7:
+ case 4:
if( !CheckMem(Data, addrSize) ) return -1;
memcpy(Data, rt->NextHop, addrSize);
return 1;
// Set Next Hop
- case 8:
+ case 5:
+ if( Threads_GetUID() != 0 ) return -1;
if( !CheckMem(Data, addrSize) ) return -1;
memcpy(rt->NextHop, Data, addrSize);
return 1;
-
- // Get/Set Subnet Bits
- case 9:
- if( Data ) {
- if( !CheckMem(Data, sizeof(int)) ) return -1;
- if( *iData < 0 || *iData > addrSize*8 )
+
+ // Get interface name
+ case 6:
+ if( !rt->Interface ) {
+ if(Data && !CheckMem(Data, 1) )
return -1;
- rt->SubnetBits = *iData;
- }
- return rt->SubnetBits;
-
- // Get/Set Metric
- case 10:
- if( Data ) {
- if( !CheckMem(Data, sizeof(int)) ) return -1;
- if( *iData < 0 ) return -1;
- rt->Metric = *iData;
+ if(Data)
+ *(char*)Data = 0;
+ return 0;
}
- 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);
+ // Set interface name
+ case 7:
+ if( Threads_GetUID() != 0 )
+ return -1;
+ if( !CheckString(Data) )
+ return -1;
+ else
+ {
+ tInterface *iface;
+ tVFS_Node *tmp;
+ tmp = IPStack_Root_FindDir(NULL, Data);
+ if(!tmp)
+ return -1;
+ iface = tmp->ImplPtr;
+ if(tmp->Type->Close) tmp->Type->Close(tmp);
+
+ if( iface->Type != rt->AddressType )
+ return -1;
+
+ // TODO: Other checks?
+ rt->Interface = iface;
+ }
+ return 0;
+
default:
return -1;
}
--- /dev/null
+Network only?
+- "/Devices/ip/routes/4:0A000200:24"
+Network and Metric?
+- "/Devices/ip/routes/4:0A000200:24:10"
+
+Would it need the interface?
+- "/Devices/ip/routes/0:4:0A000200:24:10"
+
+
+Current model
+- num = "/Devices/ip/routes"->CreateRoute("interface")
+- "/Devices/ip/routes/{num}"->SetNetwork()
+- "/Devices/ip/routes/{num}"->SetSubnetBits()
+- "/Devices/ip/routes/{num}"->SetMetric()
+- "/Devices/ip/routes/{num}"->SetNextHop()
+
+New Model
+- "/Devices/ip/routes/{type}:{network}:{subnet}:{metric}"->SetNextHop()
+- "/Devices/ip/routes/{type}:{network}:{subnet}:{metric}"->SetInterface()?
}
#define htonb(v) v
#define ntohl(v) htonl(v)
+#define ntohs(v) htons(v)
// === CONSTANTS ===
enum eStates
{
uint8_t *addr = Router;
_SysDebug("Router %i.%i.%i.%i", addr[0], addr[1], addr[2], addr[3]);
-// ioctl(Iface->IfaceFD, 8, addr);
- // TODO: Default route
+
+ // Set default route
+ int fd;
+ fd = open("/Devices/ip/routes/4:00000000:0:0", OPENFLAG_CREATE);
+ if(fd == -1) {
+ fprintf(stderr, "ERROR: Unable to open default route\n");
+ }
+ else {
+ char ifname[snprintf(NULL,0,"%i",Iface->Num)+1];
+ sprintf(ifname, "%i", Iface->Num);
+ ioctl(fd, ioctl(fd, 3, "set_nexthop"), Router);
+ ioctl(fd, ioctl(fd, 3, "set_interface"), ifname);
+ close(fd);
+ }
}
}
dp = open(IPSTACK_ROOT"/routes", OPENFLAG_READ);
- printf("ID\tType\tNetwork \tGateway \tMetric\tIFace\n");
+ printf("Type\tNetwork \tGateway \tMetric\tIFace\n");
while( readdir(dp, filename) )
{
return ;
}
- type = ioctl(fd, 4, NULL);
-
- // Ignore -1 values
- if( type == -1 ) {
- return ;
+ int ofs = 2;
+ type = atoi(Name);
+
+ int i;
+ int len = Net_GetAddressSize(type);
+ uint8_t net[len], gw[len];
+ int subnet, metric;
+ for( i = 0; i < len; i ++ ) {
+ char tmp[5] = "0x00";
+ tmp[2] = Name[ofs++];
+ tmp[3] = Name[ofs++];
+ net[i] = atoi(tmp);
}
-
- // Number
- printf("%s\t", Name);
+ ofs ++;
+ subnet = atoi(Name+ofs);
+ ofs ++;
+ metric = atoi(Name+ofs);
+ ioctl(fd, ioctl(fd, 3, "get_nexthop"), gw); // Get Gateway/NextHop
// Get the address type
switch(type)
printf("DISABLED\n");
break;
case 4: // IPv4
- {
- uint8_t net[4], addr[4];
- int subnet, metric;
printf("IPv4\t");
- ioctl(fd, ioctl(fd, 3, "get_network"), net); // Get Network
- ioctl(fd, ioctl(fd, 3, "get_nexthop"), addr); // Get Gateway/NextHop
- subnet = ioctl(fd, ioctl(fd, 3, "getset_subnetbits"), NULL); // Get Subnet Bits
- metric = ioctl(fd, ioctl(fd, 3, "getset_metric"), NULL); // Get Subnet Bits
- printf("%s/%i\t", Net_PrintAddress(4, net), subnet);
- printf("%s \t", Net_PrintAddress(4, addr));
- printf("%i\t", metric);
- }
break;
case 6: // IPv6
- {
- uint16_t net[8], addr[8];
- int subnet, metric;
printf("IPv6\t");
- ioctl(fd, ioctl(fd, 3, "get_network"), net); // Get Network
- ioctl(fd, ioctl(fd, 3, "get_nexthop"), addr); // Get Gateway/NextHop
- subnet = ioctl(fd, ioctl(fd, 3, "getset_subnetbits"), NULL); // Get Subnet Bits
- metric = ioctl(fd, ioctl(fd, 3, "getset_metric"), NULL); // Get Subnet Bits
- printf("%s/%i\t", Net_PrintAddress(6, net), subnet);
- printf("%s\t", Net_PrintAddress(6, addr));
- printf("%i\t", metric);
- }
break;
default: // Unknow
printf("UNKNOWN (%i)\n", type);
break;
}
+ printf("%s/%i\t", Net_PrintAddress(type, net), subnet);
+ printf("%s \t", Net_PrintAddress(type, gw));
+ printf("%i\t", metric);
// Interface
{
{
int fd;
int num;
- char tmp[sizeof(IPSTACK_ROOT"/routes/") + 5]; // enough for 4 digits
char *ifaceToFree = NULL;
// Get interface name
}
// Create route
- fd = open(IPSTACK_ROOT"/routes", 0);
- num = ioctl(fd, ioctl(fd, 3, "add_route"), (char*)Interface);
- close(fd);
-
- // Open route
- sprintf(tmp, IPSTACK_ROOT"/routes/%i", num);
- fd = open(tmp, 0);
+ int addrsize = Net_GetAddressSize(AddressType);
+ int len = snprintf(NULL, 0, "/Devices/ip/routes/%i::%i:%i", AddressType, MaskBits, Metric) + addrsize*2;
+ char path[len+1];
+ {
+ int i, ofs;
+ ofs = sprintf(path, "/Devices/ip/routes/%i:", AddressType);
+ for( i = 0; i < addrsize; i ++ )
+ sprintf(path+ofs+i*2, "%02x", ((uint8_t*)Dest)[i]);
+ ofs += addrsize*2;
+ sprintf(path+ofs, ":%i:%i", MaskBits, Metric);
+ }
+
+ fd = open(path, 0);
+ if( fd != -1 ) {
+ close(fd);
+ fprintf(stderr, "Unable to create route '%s', already exists\n", path);
+ return ;
+ }
+ fd = open(path, OPENFLAG_CREATE, 0);
+ if( fd == -1 ) {
+ fprintf(stderr, "Unable to create '%s'\n", path);
+ return ;
+ }
- ioctl(fd, ioctl(fd, 3, "set_network"), Dest);
if( NextHop )
ioctl(fd, ioctl(fd, 3, "set_nexthop"), NextHop);
- ioctl(fd, ioctl(fd, 3, "getset_subnetbits"), &MaskBits);
- ioctl(fd, ioctl(fd, 3, "getset_metric"), &Metric);
+ ioctl(fd, ioctl(fd, 3, "set_interface"), (void*)Interface);
close(fd);
return 1;
}
- if( !iface )
- {
- iface = Net_GetInterface(type, addr);
- if( !iface ) {
- fprintf(stderr, "Unable to find a route to '%s'\n",
- Net_PrintAddress(type, addr)
- );
- return -1;
- }
-
- printf("iface = '%s'\n", iface);
- }
-
+ if( iface )
{
char *_iface = malloc( sizeof("/Devices/ip/") + strlen(iface) + 1 );
strcpy(_iface, "/Devices/ip/");
free(iface); // TODO: Handle when this is not heap
iface = _iface;
printf("iface = '%s'\n", iface);
+ fd = open(iface, OPENFLAG_EXEC);
+ if(fd == -1) {
+ fprintf(stderr, "ERROR: Unable to open interface '%s'\n", iface);
+ return 1;
+ }
+
}
-
- fd = open(iface, OPENFLAG_EXEC);
- if(fd == -1) {
- fprintf(stderr, "ERROR: Unable to open interface '%s'\n", iface);
- return 1;
+ else
+ {
+ fd = Net_OpenSocket(type, addr, NULL);
+ if( fd == -1 ) {
+ fprintf(stderr, "Unable to find a route to '%s'\n",
+ Net_PrintAddress(type, addr)
+ );
+ return -1;
+ }
}
-
+
call = ioctl(fd, 3, "ping");
if(call == 0) {
fprintf(stderr, "ERROR: '%s' does not have a 'ping' call\n", iface);
extern void *SysLoadBin(const char *path, void **entry);
extern int SysUnloadBin(void *Base);
extern void SysSetFaultHandler(int (*Hanlder)(int));
-extern int open(const char *filename, int flags);
+extern int open(const char *filename, int flags, ...);
extern int close(int fd);
// === ELF Loader ===
--- /dev/null
+/*
+ * Acess2 Lib C
+ * - By John Hodge (thePowersGang)
+ *
+ * rand.c
+ * - srand/rand/rand_p functions
+ */
+#include <stdlib.h>
+
+// === GLOBALS ===
+unsigned int _rand_state_x = 123456789;
+unsigned int _rand_state_y = 362436069;
+unsigned int _rand_state_z = 521288629;
+unsigned int _rand_state_w = 88675123;
+
+// === FUNCTIONS ===
+int rand_p(unsigned int *seedp)
+{
+ const int const_a = 0x731ADE, const_c = 12345;
+ // Linear Congruency
+ *seedp = *seedp * const_a + const_c;
+ return *seedp;
+}
+
+void srand(unsigned int seed)
+{
+ _rand_state_x = rand_p( &seed );
+ _rand_state_y = rand_p( &seed );
+ _rand_state_z = rand_p( &seed );
+ _rand_state_w = rand_p( &seed );
+}
+
+int rand(void)
+{
+ unsigned int t;
+
+ t = _rand_state_x ^ (_rand_state_x << 11);
+ _rand_state_x = _rand_state_y; _rand_state_y = _rand_state_z; _rand_state_z = _rand_state_w;
+ return _rand_state_w = _rand_state_w ^ (_rand_state_w >> 19) ^ t ^ (t >> 8);
+}
+
#include <stdio.h>
#define DEBUG 0
+static inline uint32_t htonl(uint32_t v)
+{
+ return (((v >> 24) & 0xFF) << 0)
+ | (((v >> 16) & 0xFF) << 8)
+ | (((v >> 8) & 0xFF) << 16)
+ | (((v >> 0) & 0xFF) << 24);
+}
+static inline uint16_t htons(uint16_t v)
+{
+ return (((v >> 8) & 0xFF) << 0)
+ | (((v >> 0) & 0xFF) << 8);
+}
+#define htonb(v) v
+#define ntohl(v) htonl(v)
+#define ntohs(v) htons(v)
+#define ntohb(v) v
+
#define __thread // Disable TLS
/**
#endif
sprintf(ret, "%x:%x:%x:%x:%x:%x:%x:%x",
- Address[0], Address[1], Address[2], Address[3],
- Address[4], Address[5], Address[6], Address[7]
+ ntohs(Address[0]), ntohs(Address[1]), ntohs(Address[2]), ntohs(Address[3]),
+ ntohs(Address[4]), ntohs(Address[5]), ntohs(Address[6]), ntohs(Address[7])
);
return ret;
#include <stdlib.h>
#include <stdio.h>
+
// === CODE ===
int SoMain(void)
{
if(Filename)
{
- int len = snprintf(NULL, 100, "/Devices/ip/routes/%i:%s/%s", AddrType, hexAddr, Filename);
+ int len = snprintf(NULL, 100, "/Devices/ip/routes/@%i:%s/%s", AddrType, hexAddr, Filename);
char path[len+1];
- snprintf(path, 100, "/Devices/ip/routes/%i:%s/%s", AddrType, hexAddr, Filename);
+ snprintf(path, 100, "/Devices/ip/routes/@%i:%s/%s", AddrType, hexAddr, Filename);
return open(path, OPENFLAG_READ|OPENFLAG_WRITE);
}
else
{
- int len = snprintf(NULL, 100, "/Devices/ip/routes/%i:%s", AddrType, hexAddr);
+ int len = snprintf(NULL, 100, "/Devices/ip/routes/@%i:%s", AddrType, hexAddr);
char path[len+1];
- snprintf(path, 100, "/Devices/ip/routes/%i:%s", AddrType, hexAddr);
+ snprintf(path, 100, "/Devices/ip/routes/@%i:%s", AddrType, hexAddr);
return open(path, OPENFLAG_READ);
}
}
// Check answer validity
if( routeNum > 0 ) {
- int len = sprintf(NULL, "/Devices/ip/routes/%i", routeNum);
+ int len = sprintf(NULL, "/Devices/ip/routes/#%i", routeNum);
char buf[len+1];
char *ret;
- sprintf(buf, "/Devices/ip/routes/%i", routeNum);
+ sprintf(buf, "/Devices/ip/routes/#%i", routeNum);
// Open route
fd = open(buf, 0);
- if( !fd ) return NULL; // Shouldn't happen :/
+ if( fd == -1 ) {
+ fprintf(stderr, "Net_GetInterface - ERROR: Unabel to open %s\n", buf);
+ return NULL; // Shouldn't happen :/
+ }
// Allocate space for name
ret = malloc( ioctl(fd, ioctl(fd, 3, "get_interface"), NULL) + 1 );
// --- VFS ---
extern int chdir(const char *dir);
-extern int open(const char *path, int flags);
+extern int open(const char *path, int flags, ...);
extern int reopen(int fd, const char *path, int flags);
extern int close(int fd);
extern uint read(int fd, void *buffer, uint length);