#include "ipstack.h"
#include "link.h"
#include <api_drv_common.h>
-#include <api_drv_network.h>
+#include "include/adapters.h"
+#include "interface.h"
// === CONSTANTS ===
-//! Default timeout value, 30 seconds
-#define DEFAULT_TIMEOUT (30*1000)
+//! Default timeout value, 5 seconds
+#define DEFAULT_TIMEOUT (5*1000)
// === IMPORTS ===
extern int IPv4_Ping(tInterface *Iface, tIPv4 Addr);
//extern int IPv6_Ping(tInterface *Iface, tIPv6 Addr);
extern tVFS_Node gIP_RouteNode;
+extern tVFS_Node gIP_AdaptersNode;
// === PROTOTYPES ===
-char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos);
+ int IPStack_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name);
int IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data);
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);
+ int IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
tVFS_Node *IPStack_Iface_FindDir(tVFS_Node *Node, const char *Name);
int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data);
// === GLOBALS ===
+tVFS_NodeType gIP_RootNodeType = {
+ .ReadDir = IPStack_Root_ReadDir,
+ .FindDir = IPStack_Root_FindDir,
+ .IOCtl = IPStack_Root_IOCtl
+};
tVFS_NodeType gIP_InterfaceNodeType = {
.ReadDir = IPStack_Iface_ReadDir,
.FindDir = IPStack_Iface_FindDir,
tShortSpinlock glIP_Interfaces;
tInterface *gIP_Interfaces = NULL;
tInterface *gIP_Interfaces_Last = NULL;
+ int giIP_NextIfaceId = 1;
tSocketFile *gIP_FileTemplates;
-tAdapter gIP_LoopAdapter = {
- .DeviceLen = 8,
- .Device = "LOOPBACK"
- };
-tMutex glIP_Adapters;
-tAdapter *gIP_Adapters = NULL;
- int giIP_NextIfaceId = 1;
-
// === CODE ===
/**
* \brief Read from the IP Stack's Device Directory
*/
-char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos)
+int IPStack_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
tInterface *iface;
- char *name;
ENTER("pNode iPos", Node, Pos);
// Routing Subdir
if( Pos == 0 ) {
- LEAVE('s', "routes");
- return strdup("routes");
+ strcpy(Dest, "routes");
+ return 0;
}
- // Pseudo Interfaces
+ // Adapters
if( Pos == 1 ) {
- LEAVE('s', "lo");
- return strdup("lo");
+ strcpy(Dest, "adapters");
+ return 0;
+ }
+ // Pseudo Interfaces
+ if( Pos == 2 ) {
+ strcpy(Dest, "lo");
+ return 0;
}
- Pos -= 2;
+ Pos -= 3;
// Traverse the list
for( iface = gIP_Interfaces; iface && Pos--; iface = iface->Next ) ;
// Did we run off the end?
if(!iface) {
- LEAVE('n');
- return NULL;
- }
-
- name = malloc(4);
- if(!name) {
- Log_Warning("IPStack", "IPStack_Root_ReadDir - malloc error");
- LEAVE('n');
- return NULL;
+ LEAVE('i', -EINTERNAL);
+ return -EINVAL;
}
// Create the name
Pos = iface->Node.ImplInt;
- if(Pos < 10) {
- name[0] = '0' + Pos;
- name[1] = '\0';
- }
- else if(Pos < 100) {
- name[0] = '0' + Pos/10;
- name[1] = '0' + Pos%10;
- name[2] = '\0';
- }
- else {
- name[0] = '0' + Pos/100;
- name[1] = '0' + (Pos/10)%10;
- name[2] = '0' + Pos%10;
- name[3] = '\0';
- }
+ snprintf(Dest, FILENAME_MAX, "%i", Pos);
- LEAVE('s', name);
- // Return the pre-generated name
- return name;
+ LEAVE('i', 0);
+ return 0;
}
/**
return &gIP_RouteNode;
}
+ // Adapters subdir
+ if( strcmp(Name, "adapters") == 0 ) {
+ LEAVE('p', &gIP_AdaptersNode);
+ return &gIP_AdaptersNode;
+ }
+
// Loopback
if( strcmp(Name, "lo") == 0 ) {
LEAVE('p', &gIP_LoopInterface.Node);
ENTER("sDevice", Device);
- card = IPStack_GetAdapter(Device);
+ card = Adapter_GetByName(Device);
if( !card ) {
Log_Debug("IPStack", "Unable to open card '%s'", Device);
LEAVE('n');
iface->Next = NULL;
iface->Type = 0; // Unset type
iface->Address = iface->Name + nameLen + 1; // Address
+ memset(&iface->Route, 0, sizeof(iface->Route));
iface->Route.Network = iface->Address + IPStack_GetAddressSize(-1);
iface->Route.NextHop = iface->Route.Network + IPStack_GetAddressSize(-1);
/**
* \brief Read from an interface's directory
*/
-char *IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos)
+int IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
tSocketFile *file = gIP_FileTemplates;
while(Pos-- && file) {
file = file->Next;
}
- if(!file) return NULL;
+ if(!file)
+ return -EINVAL;
- return strdup(file->Name);
+ strncpy(Dest, file->Name, FILENAME_MAX);
+ return 0;
}
/**
case 8:
if( iface->Adapter == NULL )
LEAVE_RET('i', 0);
- if( Data == NULL )
- LEAVE_RET('i', iface->Adapter->DeviceLen);
- if( !CheckMem( Data, iface->Adapter->DeviceLen+1 ) )
- LEAVE_RET('i', -1);
- strcpy( Data, iface->Adapter->Device );
- LEAVE_RET('i', iface->Adapter->DeviceLen);
+ char *name = Adapter_GetName(iface->Adapter);
+ int len = strlen(name);
+ if( Data ) {
+ if( !CheckMem( Data, len+1 ) ) {
+ free(name);
+ LEAVE_RET('i', -1);
+ }
+ strcpy( Data, name );
+ }
+ free(name);
+ LEAVE_RET('i', len);
/*
* ping
return 0;
}
-// --- Internal ---
-/**
- * \fn tAdapter *IPStack_GetAdapter(const char *Path)
- * \brief Gets/opens an adapter given the path
- */
-tAdapter *IPStack_GetAdapter(const char *Path)
-{
- tAdapter *dev;
- int tmp;
-
- 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
- for( dev = gIP_Adapters; dev; dev = dev->Next )
- {
- if( strcmp(dev->Device, Path) == 0 ) {
- dev->NRef ++;
- Mutex_Release( &glIP_Adapters );
- LEAVE('p', dev);
- return dev;
- }
- }
-
- // Ok, so let's open it
- dev = malloc( sizeof(tAdapter) + strlen(Path) + 1 );
- if(!dev) {
- Log_Warning("IPStack", "GetAdapter - malloc() failed");
- Mutex_Release( &glIP_Adapters );
- LEAVE('n');
- return NULL;
- }
-
- // Fill Structure
- strcpy( dev->Device, Path );
- dev->NRef = 1;
- dev->DeviceLen = strlen(Path);
-
- // Open Device
- dev->DeviceFD = VFS_Open( dev->Device, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE );
- if( dev->DeviceFD == -1 ) {
- free( dev );
- Mutex_Release( &glIP_Adapters );
- LEAVE('n');
- return NULL;
- }
-
- // Check that it is a network interface
- tmp = VFS_IOCtl(dev->DeviceFD, 0, NULL);
- LOG("Device type = %i", tmp);
- if( tmp != DRV_TYPE_NETWORK ) {
- Log_Warning("IPStack", "IPStack_GetAdapter: '%s' is not a network interface", dev->Device);
- VFS_Close( dev->DeviceFD );
- free( dev );
- Mutex_Release( &glIP_Adapters );
- LEAVE('n');
- return NULL;
- }
-
- // Get MAC Address
- VFS_IOCtl(dev->DeviceFD, NET_IOCTL_GETMAC, &dev->MacAddr);
-
- // Add to list
- dev->Next = gIP_Adapters;
- gIP_Adapters = dev;
-
- Mutex_Release( &glIP_Adapters );
-
- // Start watcher
- Link_WatchDevice( dev );
-
- LEAVE('p', dev);
- return dev;
-}