tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name);
int IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data);
- int IPStack_AddInterface(const char *Device, const char *Name);
int IPStack_AddFile(tSocketFile *File);
+tInterface *IPStack_AddInterface(const char *Device, const char *Name);
tAdapter *IPStack_GetAdapter(const char *Path);
char *IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos);
tInterface *gIP_Interfaces_Last = NULL;
tSocketFile *gIP_FileTemplates;
+
+tAdapter gIP_LoopAdapter = {
+ DeviceLen: 8,
+ Device: "LOOPBACK"
+ };
tMutex glIP_Adapters;
tAdapter *gIP_Adapters = NULL;
int giIP_NextIfaceId = 1;
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, "IPStack");
- LEAVE('i', 1);
- return 1;
-
- case DRV_IOCTL_VERSION:
- LEAVE('x', VERSION);
- return VERSION;
-
- case DRV_IOCTL_LOOKUP:
- tmp = ModUtil_LookupString( (char**)casIOCtls_Root, (char*)Data );
- LEAVE('i', tmp);
- return tmp;
+ BASE_IOCTLS(DRV_TYPE_MISC, "IPStack", VERSION, casIOCtls_Root)
- /*
- * add_interface
- * - Adds a new IP interface and binds it to a device
- */
+ /*
+ * add_interface
+ * - Adds a new IP interface and binds it to a device
+ */
case 4:
if( Threads_GetUID() != 0 ) LEAVE_RET('i', -1);
if( !CheckString( Data ) ) LEAVE_RET('i', -1);
{
char name[4] = "";
- tmp = IPStack_AddInterface(Data, name);
+ tInterface *iface = IPStack_AddInterface(Data, name);
+ tmp = iface->Node.ImplInt;
}
LEAVE_RET('i', tmp);
}
}
/**
- * \fn int IPStack_AddInterface(char *Device)
+ * \fn tInterface *IPStack_AddInterface(char *Device)
* \brief Adds an interface to the list
*/
-int IPStack_AddInterface(const char *Device, const char *Name)
+tInterface *IPStack_AddInterface(const char *Device, const char *Name)
{
tInterface *iface;
tAdapter *card;
card = IPStack_GetAdapter(Device);
if( !card ) {
- LEAVE('i', -1);
- return -1; // ERR_YOURBAD
+ LEAVE('n');
+ return NULL; // ERR_YOURBAD
}
nameLen = sprintf(NULL, "%i", giIP_NextIfaceId);
iface = malloc(
sizeof(tInterface)
+ nameLen + 1
- + IPStack_GetAddressSize(-1)
+ + IPStack_GetAddressSize(-1)*3 // Address, Route->Network, Route->NextHop
);
if(!iface) {
- LEAVE('i', -2);
- return -2; // Return ERR_MYBAD
+ LEAVE('n');
+ return NULL; // Return ERR_MYBAD
}
iface->Next = NULL;
iface->Type = 0; // Unset type
iface->Address = iface->Name + nameLen + 1; // Address
+ iface->Route.Network = iface->Address + IPStack_GetAddressSize(-1);
+ iface->Route.NextHop = iface->Route.Network + IPStack_GetAddressSize(-1);
// Create Node
iface->Node.ImplPtr = iface;
iface->Adapter = IPStack_GetAdapter(Device);
if( !iface->Adapter ) {
free( iface );
- LEAVE('i', -1);
- return -1; // Return ERR_YOUFAIL
+ LEAVE('n');
+ return NULL; // Return ERR_YOUFAIL
}
// Delay setting ImplInt until after the adapter is opened
// gIP_DriverInfo.RootNode.Size ++;
// Success!
- LEAVE('i', iface->Node.ImplInt);
- return iface->Node.ImplInt;
+ LEAVE('p', iface);
+ return iface;
}
/**
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_Iface, (char*)Data );
- LEAVE('i', tmp);
- return tmp;
+ BASE_IOCTLS(DRV_TYPE_MISC, "IPStack", VERSION, casIOCtls_Iface)
/*
* getset_type
ENTER("sPath", Path);
+ // Check for loopback
+ if( strcmp(Path, "LOOPBACK") == 0 )
+ {
+ // Initialise if required
+ if( gIP_LoopAdapter.DeviceFD == 0 )
+ {
+ dev = &gIP_LoopAdapter;
+
+ dev->NRef = 1;
+ dev->DeviceLen = 8;
+
+ dev->DeviceFD = VFS_Open( "/Devices/fifo/anon", VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE );
+ if( dev->DeviceFD == -1 ) {
+ Log_Warning("IPStack", "Unable to open FIFO '/Devices/fifo/anon' for loopback");
+ return NULL;
+ }
+
+ dev->MacAddr.B[0] = 'A';
+ dev->MacAddr.B[1] = 'c';
+ dev->MacAddr.B[2] = 'e';
+ dev->MacAddr.B[3] = 's';
+ dev->MacAddr.B[4] = 's';
+ dev->MacAddr.B[5] = '2';
+
+ // Start watcher
+ Link_WatchDevice( dev );
+ }
+ LEAVE('p', &gIP_LoopAdapter);
+ return &gIP_LoopAdapter;
+ }
+
Mutex_Acquire( &glIP_Adapters );
// Check if this adapter is already open