#
#
-OBJ := main.o interface.o
+OBJ := main.o interface.o adapters.o
OBJ += buffer.o
OBJ += link.o arp.o
OBJ += ipv4.o icmp.o
--- /dev/null
+/*
+ * Acess2 Networking Stack
+ * - By John Hodge (thePowersGang)
+ *
+ * adapters.c
+ * - Network Adapter Management
+ */
+#define DEBUG 0
+#define VERSION VER2(0,1)
+#include "ipstack.h"
+#include "include/buffer.h"
+#include "include/adapters.h"
+#include "include/adapters_int.h"
+#include "link.h"
+#include <api_drv_common.h> // For the VFS hack
+#include <api_drv_network.h>
+
+// === PROTOTYPES ===
+// --- "External" (NIC) API ---
+void *IPStack_Adapter_Add(const tIPStack_AdapterType *Type, void *Ptr, const void *HWAddr);
+void IPStack_Adapter_Del(void *Handle);
+// --- VFS API ---
+char *Adapter_ReadDir(tVFS_Node *Node, int Pos);
+tVFS_Node *Adapter_FindDir(tVFS_Node *Node, const char *Name);
+ int Adapter_DirIOCtl(tVFS_Node *Node, int Num, void *Data);
+ int Adapter_IOCtl(tVFS_Node *Node, int Num, void *Data);
+// --- "Internal" (IPStack) API ---
+tAdapter *Adapter_GetByName(const char *Name);
+void Adapter_SendPacket(tAdapter *Handle, tIPStackBuffer *Buffer);
+// --- Helpers ---
+void Adapter_int_WatchThread(void *Ptr);
+tIPStackBuffer *Adapter_int_LoopbackWaitPacket(void *Unused);
+ int Adapter_int_LoopbackSendPacket(void *Unused, tIPStackBuffer *Buffer);
+
+// === GLOBALS ===
+// --- VFS Magic ---
+tVFS_NodeType gIP_AdaptersDirType = {
+ .ReadDir = Adapter_ReadDir,
+ .FindDir = Adapter_FindDir,
+ .IOCtl = Adapter_DirIOCtl
+};
+tVFS_NodeType gIP_AdapterType = {
+ // TODO: Should direct IO be allowed?
+ .IOCtl = Adapter_IOCtl
+};
+tVFS_Node gIP_AdaptersNode = {
+ .Type = &gIP_AdaptersDirType,
+ .Flags = VFS_FFLAG_DIRECTORY,
+ .Size = -1
+};
+// --- Loopback Adapter ---
+tIPStack_AdapterType gIP_LoopAdapterType = {
+ .Name = "Loopback",
+ .WaitForPacket = Adapter_int_LoopbackWaitPacket,
+ .SendPacket = Adapter_int_LoopbackSendPacket
+ };
+tAdapter gIP_LoopAdapter;
+// --- Main adapter list ---
+tMutex glIP_Adapters;
+tAdapter *gpIP_AdapterList;
+tAdapter *gpIP_AdapterList_Last = (void*)&gpIP_AdapterList; // HACK!
+ int giIP_NextAdapterIndex;
+
+// === CODE ===
+// --- "External" (NIC) API ---
+void *IPStack_Adapter_Add(const tIPStack_AdapterType *Type, void *Ptr, const void *HWAddr)
+{
+ tAdapter *ret;
+
+ ret = malloc(sizeof(tAdapter) + 6); // TODO: Don't assume 6-byte MAC addresses
+ ret->Next = NULL;
+ ret->Type = Type;
+ ret->CardHandle = Ptr;
+ ret->RefCount = 0;
+ ret->Index = giIP_NextAdapterIndex++;
+ memcpy(ret->HWAddr, HWAddr, 6);
+
+ memset(&ret->Node, 0, sizeof(ret->Node));
+ ret->Node.Type = &gIP_AdapterType;
+ ret->Node.ImplPtr = ret;
+
+ // TODO: Locking
+ gpIP_AdapterList_Last->Next = ret;
+ gpIP_AdapterList_Last = ret;
+
+ // Watch the adapter for incoming packets
+ tTID tid = Proc_SpawnWorker(Adapter_int_WatchThread, ret);
+ if(tid < 0) {
+ Log_Warning("IPStack", "Unable to create watcher thread for %p", ret);
+ }
+
+ return ret;
+}
+
+void *IPStack_Adapter_AddVFS(const char *Path)
+{
+ int fd, tmp;
+ char mac[6];
+
+ ENTER("sPath", Path);
+
+ // Open Device
+ fd = VFS_Open( Path, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE );
+ if( fd == -1 ) {
+ LEAVE('n');
+ return NULL;
+ }
+
+ // Check that it is a network interface
+ tmp = VFS_IOCtl(fd, 0, NULL);
+ LOG("Device type = %i", tmp);
+ if( tmp != DRV_TYPE_NETWORK ) {
+ Log_Warning("IPStack", "IPStack_Adapter_AddVFS: '%s' is not a network interface", Path);
+ VFS_Close( fd );
+ LEAVE('n');
+ return NULL;
+ }
+
+ // Get MAC Address
+ VFS_IOCtl(fd, NET_IOCTL_GETMAC, mac);
+
+ return IPStack_Adapter_Add(NULL, (void*)fd, mac);
+}
+
+void IPStack_Adapter_Del(void *Handle)
+{
+ Log_Error("IPStack", "TODO: Implement IPStack_Adapter_Del");
+ // TODO: Allow removing adapters during system operation
+}
+
+// --- VFS API ---
+char *Adapter_ReadDir(tVFS_Node *Node, int Pos)
+{
+ if( Pos < 0 ) return NULL;
+
+ // Loopback
+ if( Pos == 0 ) {
+ return strdup("lo");
+ }
+ Pos --;
+
+ #define CHECK_LIST(list, type) do{ \
+ tAdapter *a; int i;\
+ for(i=0,a=list; i < Pos && a; i ++, a = a->Next ); \
+ if( a ) { \
+ char buf[sizeof(type)+10]; \
+ sprintf(buf, type"%i", a->Index); \
+ return strdup(buf); \
+ } \
+ Pos -= i; \
+ } while(0);
+
+ CHECK_LIST(gpIP_AdapterList, "eth");
+ // TODO: Support other types of adapters (wifi, tap, ...)
+
+ return NULL;
+}
+
+tVFS_Node *Adapter_FindDir(tVFS_Node *Node, const char *Name)
+{
+ tAdapter *a = Adapter_GetByName(Name);
+ if(!a)
+ return NULL;
+ else
+ return &a->Node;
+}
+
+static const char *casIOCtls_Root[] = { DRV_IOCTLNAMES, "add_vfs_adapter", NULL };
+int Adapter_DirIOCtl(tVFS_Node *Node, int Num, void *Data)
+{
+ switch(Num)
+ {
+ BASE_IOCTLS(DRV_TYPE_MISC, "IPStack-AdapterList", VERSION, casIOCtls_Root)
+
+ case 4:
+ if( !CheckString(Data) )
+ return -1;
+
+ // Return non-zero if add fails
+ return IPStack_Adapter_AddVFS(Data) == NULL;
+ }
+ return -1;
+}
+
+static const char *casIOCtls_Dev[] = { DRV_IOCTLNAMES, "get_hwaddr", NULL };
+int Adapter_IOCtl(tVFS_Node *Node, int Num, void *Data)
+{
+ tAdapter *adapter = Node->ImplPtr;
+ switch(Num)
+ {
+ BASE_IOCTLS(DRV_TYPE_MISC, "IPStack-Adapter", VERSION, casIOCtls_Dev)
+
+ case 4:
+ if( !CheckMem(Data, 6) )
+ return -1;
+
+ memcpy(Data, adapter->HWAddr, 6);
+ return 0;
+ }
+ return -1;
+}
+
+// --- "Internal" (IPStack) API ---
+tAdapter *Adapter_GetByName(const char *Name)
+{
+ if( strcmp(Name, "lo") == 0 ) {
+ return &gIP_LoopAdapter;
+ }
+
+ if( strncmp(Name, "eth", 3) == 0 )
+ {
+ // Possibly an ethX interface
+ int index, ofs;
+
+ // Get the index at the end
+ ofs = ParseInt(Name + 3, &index);
+ if( ofs == 0 || Name[3+ofs] != '\0' )
+ return NULL;
+
+ // Find the adapter with that index
+ for( tAdapter *a = gpIP_AdapterList; a && a->Index <= index; a = a->Next ) {
+ if( a->Index == index )
+ return a;
+ }
+
+ return NULL;
+ }
+
+ return NULL;
+}
+
+void Adapter_SendPacket(tAdapter *Handle, tIPStackBuffer *Buffer)
+{
+ if( Handle->Type == NULL )
+ {
+ size_t outlen = 0;
+ void *data = IPStack_Buffer_CompactBuffer(Buffer, &outlen);
+ VFS_Write((tVAddr)Handle->CardHandle, outlen, data);
+ free(data);
+ }
+ else
+ {
+ Handle->Type->SendPacket( Handle->CardHandle, Buffer );
+ }
+}
+
+// --- Helpers ---
+void Adapter_int_WatchThread(void *Ptr)
+{
+ tAdapter *Adapter = Ptr;
+ const int MTU = 1520;
+ tIPStackBuffer *buf = NULL;
+ void *data = NULL;
+
+ if( Adapter->Type == NULL )
+ {
+ data = malloc( MTU );
+ buf = IPStack_Buffer_CreateBuffer(1);
+ }
+
+
+ Threads_SetName("Adapter Watcher");
+ Log_Log("IPStack", "Thread %i watching eth%i '%s'", Threads_GetTID(), Adapter->Index,
+ Adapter->Type?Adapter->Type->Name:"VFS");
+
+ for( ;; )
+ {
+ if( Adapter->Type == NULL )
+ {
+ int len = VFS_Read((tVAddr)Adapter->CardHandle, MTU, data);
+ IPStack_Buffer_AppendSubBuffer(buf, len, 0, buf, NULL, NULL);
+ }
+ else
+ {
+ buf = Adapter->Type->WaitForPacket( Adapter->CardHandle );
+ }
+
+ Link_HandlePacket(Adapter, buf);
+
+ if( Adapter->Type == NULL )
+ {
+ IPStack_Buffer_ClearBuffer(buf);
+ }
+ else
+ {
+ IPStack_Buffer_DestroyBuffer(buf);
+ }
+ }
+}
+
+tIPStackBuffer *Adapter_int_LoopbackWaitPacket(void *Unused)
+{
+ Threads_Sleep();
+ return NULL;
+}
+
+int Adapter_int_LoopbackSendPacket(void *Unused, tIPStackBuffer *Buffer)
+{
+ // This is a little hacky :)
+ Link_HandlePacket(&gIP_LoopAdapter, Buffer);
+ return 0;
+}
+
#include "arp.h"
#include "link.h"
#include "ipv4.h" // For IPv4_Netmask
+#include "include/adapters_int.h" // for MAC addr
#define ARPv6 0
#define ARP_CACHE_SIZE 64
req.HWSize = 6;
req.SWSize = 4;
req.Request = htons(1);
- req.SourceMac = Interface->Adapter->MacAddr;
+ memcpy(&req.SourceMac, Interface->Adapter->HWAddr, 6); // TODO: Remove hard size
req.SourceIP = *(tIPv4*)Interface->Address;
req.DestMac = cMAC_BROADCAST;
req.DestIP = Address;
req4->DestIP = req4->SourceIP;
req4->DestMac = req4->SourceMac;
req4->SourceIP = *(tIPv4*)iface->Address;;
- req4->SourceMac = Adapter->MacAddr;
+ memcpy(&req4->SourceMac, Adapter->HWAddr, 6); // TODO: Remove hard size
req4->Request = htons(2);
Log_Debug("ARP", "Sending back us (%02x:%02x:%02x:%02x:%02x:%02x)",
req4->SourceMac.B[0], req4->SourceMac.B[1],
// Assumes only a header and footer at link layer
tIPStackBuffer *buffer = IPStack_Buffer_CreateBuffer(3);
- IPStack_Buffer_AppendSubBuffer(buffer, sizeof(struct sArpRequest4), 0, &req4, NULL, NULL);
+ IPStack_Buffer_AppendSubBuffer(buffer, sizeof(struct sArpRequest4), 0, req4, NULL, NULL);
Link_SendPacket(Adapter, 0x0806, req4->DestMac, buffer);
IPStack_Buffer_DestroyBuffer(buffer);
}
const void *Data;
size_t PreLength;
size_t PostLength;
+ tIPStackBufferCb Cb;
+ void *CbArg;
// TODO: Callbacks?
} SubBuffers[];
};
return ret;
}
-void IPStack_Buffer_DestroyBuffer(tIPStackBuffer *Buffer)
+void IPStack_Buffer_ClearBuffer(tIPStackBuffer *Buffer)
{
+ for( int i = 0; i < Buffer->nSubBuffers; i ++ )
+ {
+ if( Buffer->SubBuffers[i].Cb == NULL )
+ continue ;
+ Buffer->SubBuffers[i].Cb(
+ Buffer->SubBuffers[i].CbArg,
+ Buffer->SubBuffers[i].PreLength,
+ Buffer->SubBuffers[i].PostLength,
+ Buffer->SubBuffers[i].Data
+ );
+ }
// TODO: Fire callbacks?
- Buffer->MaxSubBufffers = 0;
Buffer->nSubBuffers = 0;
+}
+
+void IPStack_Buffer_DestroyBuffer(tIPStackBuffer *Buffer)
+{
+ IPStack_Buffer_ClearBuffer(Buffer);
+ Buffer->MaxSubBufffers = 0;
free(Buffer);
}
Buffer->SubBuffers[index].Data = Data;
Buffer->SubBuffers[index].PreLength = HeaderLen;
Buffer->SubBuffers[index].PostLength = FooterLen;
+ Buffer->SubBuffers[index].Cb = Cb;
+ Buffer->SubBuffers[index].CbArg = Arg;
}
size_t IPStack_Buffer_GetLength(tIPStackBuffer *Buffer)
return Buffer->TotalLength;
}
+size_t IPStack_Buffer_GetData(tIPStackBuffer *Buffer, void *Dest, size_t MaxBytes)
+{
+ Uint8 *dest = Dest;
+ size_t rem_space = MaxBytes;
+ size_t len;
+
+ for( int i = Buffer->nSubBuffers; i -- && rem_space != 0; )
+ {
+ len = MIN(Buffer->SubBuffers[i].PreLength, rem_space);
+ memcpy(dest,
+ Buffer->SubBuffers[i].Data,
+ len
+ );
+ dest += len;
+ rem_space -= len;
+ }
+ for( int i = 0; i < Buffer->nSubBuffers && rem_space; i ++ )
+ {
+ if( Buffer->SubBuffers[i].PostLength == 0 )
+ continue ;
+
+ len = MIN(Buffer->SubBuffers[i].PostLength, rem_space);
+ memcpy(dest,
+ (Uint8*)Buffer->SubBuffers[i].Data + Buffer->SubBuffers[i].PreLength,
+ len
+ );
+ dest += len;
+ rem_space -= len;
+ }
+
+ return MaxBytes - rem_space;
+}
+
void *IPStack_Buffer_CompactBuffer(tIPStackBuffer *Buffer, size_t *Length)
{
void *ret;
+
ret = malloc(Buffer->TotalLength);
if(!ret) {
*Length = 0;
}
*Length = Buffer->TotalLength;
-
- Uint8 *dest = ret;
- for( int i = Buffer->nSubBuffers; i --; )
- {
- memcpy(dest,
- Buffer->SubBuffers[i].Data,
- Buffer->SubBuffers[i].PreLength
- );
- dest += Buffer->SubBuffers[i].PreLength;
- }
- for( int i = 0; i < Buffer->nSubBuffers; i ++ )
- {
- if( Buffer->SubBuffers[i].PostLength )
- {
- memcpy(dest,
- (Uint8*)Buffer->SubBuffers[i].Data + Buffer->SubBuffers[i].PreLength,
- Buffer->SubBuffers[i].PostLength
- );
- dest += Buffer->SubBuffers[i].PreLength;
- }
- }
+
+ IPStack_Buffer_GetData(Buffer, ret, Buffer->TotalLength);
+
return ret;
}
--- /dev/null
+/*
+ * Acess2 Networking Stack
+ * - By John Hodge (thePowersGang)
+ *
+ * adapters.h
+ * - Network Adapter Management (IPStack Internal)
+ */
+#ifndef _IPSTACK__ADAPTERS_H_
+#define _IPSTACK__ADAPTERS_H_
+
+#include "adapters_api.h"
+
+extern tAdapter *Adapter_GetByName(const char *Name);
+extern void Adapter_SendPacket(tAdapter *Handle, tIPStackBuffer *Buffer);
+
+
+#endif
+
--- /dev/null
+/*
+ * Acess2 Networking Stack
+ * - By John Hodge (thePowersGang)
+ *
+ * adapters_api.h
+ * - Network Adapter Management (API Header)
+ */
+#ifndef _IPSTACK__ADAPTERS_API_H_
+#define _IPSTACK__ADAPTERS_API_H_
+
+#include "buffer.h"
+
+typedef struct sIPStack_AdapterType tIPStack_AdapterType;
+
+struct sIPStack_AdapterType
+{
+ int Type;
+ Uint Flags;
+ const char *Name;
+
+ int (*SendPacket)(void *Card, tIPStackBuffer *Buffer);
+ tIPStackBuffer *(*WaitForPacket)(void *Card);
+};
+
+extern void *IPStack_Adapter_Add(const tIPStack_AdapterType *Type, void *Ptr, const void *HWAddr);
+extern void IPStack_Adapter_Del(void *Handle);
+
+#endif
+
--- /dev/null
+/*
+ * Acess2 Networking Stack
+ * - By John Hodge (thePowersGang)
+ *
+ * adapters_int.h
+ * - Network Adapter Management (API Header)
+ */
+#ifndef _IPSTACK__ADAPTERS_INT_H_
+#define _IPSTACK__ADAPTERS_INT_H_
+
+#include "adapters.h"
+#include "adapters_api.h"
+
+struct sAdapter
+{
+ struct sAdapter *Next;
+
+ int RefCount;
+ int Index;
+
+ const tIPStack_AdapterType *Type;
+ void *CardHandle;
+
+ tVFS_Node Node;
+
+ char HWAddr[];
+};
+
+extern void Adapter_SendPacket(tAdapter *Handle, tIPStackBuffer *Buffer);
+extern void Adapter_Watch(tAdapter *Handle);
+
+#endif
+
* \brief Create a buffer object, with space for \a MaxSubBuffers calls to IPStack_Buffer_AppendSubBuffer
*/
extern tIPStackBuffer *IPStack_Buffer_CreateBuffer(int MaxSubBuffers);
+/**
+ * \brief Clear a buffer object without deallocating it
+ */
+extern void IPStack_Buffer_ClearBuffer(tIPStackBuffer *Buffer);
/**
* \brief Destory a created buffer object
*/
* \brief Get the total length of a buffer
*/
extern size_t IPStack_Buffer_GetLength(tIPStackBuffer *Buffer);
+
+/**
+ * \brief Copy data from a buffer to a preallocated flat buffer
+ * \param Dest Destination flat buffer
+ * \param MaxBytes Maximum number of bytes to copy (size of \a Dest)
+ * \return Number of bytes copied
+ */
+extern size_t IPStack_Buffer_GetData(tIPStackBuffer *Buffer, void *Dest, size_t MaxBytes);
+
/**
* \brief Get a sub-buffer from the buffer object
* \param PrevID Previous return value, or -1 to start
#include "ipstack.h"
#include "link.h"
#include <api_drv_common.h>
-#include <api_drv_network.h>
+#include "include/adapters.h"
// === CONSTANTS ===
//! Default timeout value, 30 seconds
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_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);
tVFS_Node *IPStack_Iface_FindDir(tVFS_Node *Node, const char *Name);
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 ===
/**
LEAVE('s', "routes");
return strdup("routes");
}
- // Pseudo Interfaces
+ // Adapters
if( Pos == 1 ) {
+ LEAVE('s', "adapters");
+ return strdup("adapters");
+ }
+ // Pseudo Interfaces
+ if( Pos == 2 ) {
LEAVE('s', "lo");
return strdup("lo");
}
- Pos -= 2;
+ Pos -= 3;
// Traverse the list
for( iface = gIP_Interfaces; iface && Pos--; iface = iface->Next ) ;
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');
* - Gets the name of the attached device
*/
case 8:
- if( iface->Adapter == NULL )
+ Log_Error("IPStack", "TODO: Reimplement interface.ioctl(get_device)");
+// 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);
+// 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);
/*
* 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;
-}
char Name[];
};
+#if 0
/**
* \brief Represents a network adapter
*/
int DeviceLen; //!< Device name length
char Device[]; //!< Device name
};
+#endif
/**
* \brief Describes a socket file definition
extern void ICMP_Initialise();
extern int ICMP_Ping(tInterface *Interface, tIPv4 Addr);
extern tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address);
+extern void ARP_UpdateCache4(tIPv4 SWAddr, tMacAddr HWAddr);
// === PROTOTYPES ===
int IPv4_Initialise();
hdr->Source.B[0], hdr->Source.B[1], hdr->Source.B[2], hdr->Source.B[3],
hdr->Destination.B[0], hdr->Destination.B[1], hdr->Destination.B[2], hdr->Destination.B[3]
);
+
+ // TODO: Tell ARP?
+ ARP_UpdateCache4(hdr->Source, From);
// Get Data and Data Length
dataLength = ntohs(hdr->TotalLength) - sizeof(tIPv4Header);
/*
- * Acess2 IP Stack
- * - Link/Media Layer Interface
+ * Acess2 Networking Stack
+ * - By John Hodge (thePowersGang)
+ *
+ * link.c
+ * - Ethernet/802.3 Handling code
+ * TODO: Rename file
*/
#include "ipstack.h"
#include "link.h"
#include "include/buffer.h"
+#include "include/adapters_int.h"
// === CONSTANTS ===
#define MAX_PACKET_SIZE 2048
// === PROTOTYPES ===
void Link_RegisterType(Uint16 Type, tPacketCallback Callback);
void Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, tIPStackBuffer *Buffer);
-void Link_WatchDevice(tAdapter *Adapter);
+ int Link_HandlePacket(tAdapter *Adapter, tIPStackBuffer *Buffer);
// --- CRC ---
void Link_InitCRC(void);
Uint32 Link_CalculateCRC(tIPStackBuffer *Buffer);
length, To.B[0], To.B[1], To.B[2], To.B[3], To.B[4], To.B[5], Type);
hdr->Dest = To;
- hdr->Src = Adapter->MacAddr;
+ memcpy(&hdr->Src, Adapter->HWAddr, 6); // TODO: Remove hard coded 6
hdr->Type = htons(Type);
*(Uint32*)(buf + sizeof(tEthernetHeader) + ofs) = 0;
*(Uint32*)(buf + sizeof(tEthernetHeader) + ofs) = htonl( Link_CalculateCRC(Buffer) );
- size_t outlen = 0;
- void *data = IPStack_Buffer_CompactBuffer(Buffer, &outlen);
- VFS_Write(Adapter->DeviceFD, outlen, data);
- free(data);
+ Log_Log("Net Link", " from %02x:%02x:%02x:%02x:%02x:%02x",
+ hdr->Src.B[0], hdr->Src.B[1], hdr->Src.B[2],
+ hdr->Src.B[3], hdr->Src.B[4], hdr->Src.B[5]
+ );
+
+ Adapter_SendPacket(Adapter, Buffer);
}
-void Link_WorkerThread(void *Ptr)
+int Link_HandlePacket(tAdapter *Adapter, tIPStackBuffer *Buffer)
{
- tAdapter *Adapter = Ptr;
+ size_t len = 0;
+ void *data = IPStack_Buffer_CompactBuffer(Buffer, &len);
- Threads_SetName(Adapter->Device);
- Log_Log("Net Link", "Thread %i watching '%s'", Threads_GetTID(), Adapter->Device);
+ tEthernetHeader *hdr = (void*)data;
+ int i;
+ Uint32 checksum;
- // Child Thread
- while(Adapter->DeviceFD != -1)
- {
- Uint8 buf[MAX_PACKET_SIZE];
- tEthernetHeader *hdr = (void*)buf;
- int ret, i;
- Uint32 checksum;
-
- // Wait for a packet (Read on a network device is blocking)
- //Log_Debug("NET", "Waiting on adapter FD#0x%x", Adapter->DeviceFD);
- ret = VFS_Read(Adapter->DeviceFD, MAX_PACKET_SIZE, buf);
- if(ret == -1) break;
-
- if(ret < sizeof(tEthernetHeader)) {
- Log_Log("Net Link", "Recieved an undersized packet (%i < %i)",
- ret, sizeof(tEthernetHeader));
- continue;
- }
-
- Log_Log("Net Link",
- "Packet from %02x:%02x:%02x:%02x:%02x:%02x"
- " to %02x:%02x:%02x:%02x:%02x:%02x (Type=%04x)",
- hdr->Src.B[0], hdr->Src.B[1], hdr->Src.B[2],
- hdr->Src.B[3], hdr->Src.B[4], hdr->Src.B[5],
- hdr->Dest.B[0], hdr->Dest.B[1], hdr->Dest.B[2],
- hdr->Dest.B[3], hdr->Dest.B[4], hdr->Dest.B[5],
- ntohs(hdr->Type)
- );
- checksum = *(Uint32*)&hdr->Data[ret-sizeof(tEthernetHeader)-4];
- //Log_Log("NET", "Checksum 0x%08x", checksum);
- // TODO: Check checksum
+ if(len < sizeof(tEthernetHeader)) {
+ Log_Log("Net Link", "Recieved an undersized packet (%i < %i)",
+ len, sizeof(tEthernetHeader));
+ free(data);
+ return 1;
+ }
- // Check if there is a registered callback for this packet type
- for( i = giRegisteredTypes; i--; )
- {
- if(gaRegisteredTypes[i].Type == ntohs(hdr->Type)) break;
- }
- // No? Ignore it
- if( i == -1 ) {
- Log_Log("Net Link", "Unregistered type 0x%x", ntohs(hdr->Type));
- continue;
- }
+ Log_Log("Net Link",
+ "Packet from %02x:%02x:%02x:%02x:%02x:%02x"
+ " to %02x:%02x:%02x:%02x:%02x:%02x (Type=%04x)",
+ hdr->Src.B[0], hdr->Src.B[1], hdr->Src.B[2],
+ hdr->Src.B[3], hdr->Src.B[4], hdr->Src.B[5],
+ hdr->Dest.B[0], hdr->Dest.B[1], hdr->Dest.B[2],
+ hdr->Dest.B[3], hdr->Dest.B[4], hdr->Dest.B[5],
+ ntohs(hdr->Type)
+ );
+ checksum = *(Uint32*)&hdr->Data[len-sizeof(tEthernetHeader)-4];
+ //Log_Log("NET", "Checksum 0x%08x", checksum);
+ // TODO: Check checksum
+
+ // Check if there is a registered callback for this packet type
+ for( i = giRegisteredTypes; i--; )
+ {
+ if(gaRegisteredTypes[i].Type == ntohs(hdr->Type)) break;
+ }
+ // No? Ignore it
+ if( i == -1 ) {
+ Log_Log("Net Link", "Unregistered type 0x%x", ntohs(hdr->Type));
- // Call the callback
- gaRegisteredTypes[i].Callback(
- Adapter,
- hdr->Src,
- ret - sizeof(tEthernetHeader),
- hdr->Data
- );
+ free(data);
+ return 1;
}
- Log_Log("Net Link", "Watcher terminated (file closed)");
-
- Threads_Exit(0, 0);
-}
-
-/**
- * \fn void Link_WatchDevice(tAdapter *Adapter)
- * \brief Spawns a worker thread to watch the specified adapter
- */
-void Link_WatchDevice(tAdapter *Adapter)
-{
- int tid;
-
- if( !gbLink_CRCTableGenerated )
- Link_InitCRC();
-
- tid = Proc_SpawnWorker(Link_WorkerThread, Adapter); // Create a new worker thread
+ // Call the callback
+ gaRegisteredTypes[i].Callback(
+ Adapter,
+ hdr->Src,
+ len - sizeof(tEthernetHeader),
+ hdr->Data
+ );
- if(tid < 0) {
- Log_Warning("Net Link", "Unable to create watcher thread for '%s'", Adapter->Device);
- return ;
- }
+ free(data);
- Log_Log("Net Link", "Watching '%s' using tid %i", Adapter->Device, tid);
+ return 0;
}
// From http://www.cl.cam.ac.uk/research/srg/bluebook/21/crc/node6.html
extern void Link_RegisterType(Uint16 Type, tPacketCallback Callback);
extern void Link_SendPacket(tAdapter *Interface, Uint16 Type, tMacAddr To, tIPStackBuffer *Buffer);
+extern int Link_HandlePacket(tAdapter *Adapter, tIPStackBuffer *Buffer);
extern void Link_WatchDevice(tAdapter *Adapter);
// === INTERNAL ===
#include "link.h"
#include <modules.h>
#include <fs_devfs.h>
+#include "include/adapters.h"
// === IMPORTS ===
extern int ARP_Initialise();
extern int IPv4_Initialise();
extern int IPv6_Initialise();
-extern tAdapter *IPStack_GetAdapter(const char *Path);
extern char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos);
extern tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name);
extern int IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data);
}
// Initialise loopback interface
- gIP_LoopInterface.Adapter = IPStack_GetAdapter("LOOPBACK");
+ gIP_LoopInterface.Adapter = Adapter_GetByName("lo");
DevFS_AddDevice( &gIP_DriverInfo );
// - Route Management
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 *_Route_FindInterfaceRoute(int AddressType, void *Address);
tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address);
// - Individual Routes
int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data);
rt = IPStack_FindRoute(type, NULL, addrData);
if(!rt) return NULL;
- if( rt->Interface )
+ 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;
+ LOG("Why does this route not have a node? trying to find an iface for the next hop");
+
+ rt = _Route_FindInterfaceRoute(type, rt->NextHop);
+ if(!rt) {
+ Log_Notice("Cannot find route to next hop '%s'",
+ IPStack_PrintAddress(type, rt->NextHop));
+ return NULL;
+ }
}
- else
- {
+ if( !rt->Interface ) {
+ Log_Notice("Routes", "No interface for route %p, what the?", rt);
return NULL;
}
+ // 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 if( Name[0] == '#' )
{
return rt;
}
+/**
+ * \brief Locates what interface should be used to get directly to an address
+ */
+tRoute *_Route_FindInterfaceRoute(int AddressType, void *Address)
+{
+ tRoute *best = NULL, *rt;
+ int addrSize = IPStack_GetAddressSize(AddressType);
+ for( tInterface *iface = gIP_Interfaces; iface; iface = iface->Next )
+ {
+ if( iface->Type != AddressType ) continue;
+
+ // Check if the address matches
+ if( !IPStack_CompareAddress(AddressType, iface->Address, Address, iface->SubnetBits) )
+ continue;
+
+ rt = &iface->Route;
+ if( !rt->Interface )
+ {
+ memcpy(rt->Network, iface->Address, addrSize);
+ memset(rt->NextHop, 0, addrSize);
+ rt->Metric = DEFAUTL_METRIC;
+ rt->SubnetBits = iface->SubnetBits;
+ rt->Interface = iface;
+ }
+
+ if( best ) {
+ // More direct routes are preferred
+ if( best->SubnetBits > rt->SubnetBits ) {
+ LOG("Skipped - less direct (%i < %i)", rt->SubnetBits, best->SubnetBits);
+ continue;
+ }
+ // If equally direct, choose the best metric
+ if( best->SubnetBits == rt->SubnetBits && best->Metric < rt->Metric ) {
+ LOG("Skipped - higher metric (%i > %i)", rt->Metric, best->Metric);
+ continue;
+ }
+ }
+
+ best = rt;
+ }
+
+ return best;
+}
+
/**
*/
tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address)
{
tRoute *rt;
tRoute *best = NULL;
- tInterface *iface;
int addrSize;
ENTER("iAddressType pInterface sAddress",
for( rt = gIP_Routes; rt; rt = rt->Next )
{
// Check interface
- if( Interface && rt->Interface != Interface ) continue;
+ if( Interface && rt->Interface && rt->Interface != Interface ) continue;
// Check address type
if( rt->AddressType != AddressType ) continue;
// Check against implicit routes
if( !best && !Interface )
{
- for( iface = gIP_Interfaces; iface; iface = iface->Next )
- {
- if( Interface && iface != Interface ) continue;
- if( iface->Type != AddressType ) continue;
-
-
- // Check if the address matches
- if( !IPStack_CompareAddress(AddressType, iface->Address, Address, iface->SubnetBits) )
- continue;
-
- if( best ) {
- // More direct routes are preferred
- if( best->SubnetBits > rt->SubnetBits ) {
- LOG("Skipped - less direct (%i < %i)", rt->SubnetBits, best->SubnetBits);
- continue;
- }
- // If equally direct, choose the best metric
- if( best->SubnetBits == rt->SubnetBits && best->Metric < rt->Metric ) {
- LOG("Skipped - higher metric (%i > %i)", rt->Metric, best->Metric);
- continue;
- }
- }
-
- rt = &iface->Route;
- memcpy(rt->Network, iface->Address, addrSize);
- memset(rt->NextHop, 0, addrSize);
- rt->Metric = DEFAUTL_METRIC;
- rt->SubnetBits = iface->SubnetBits;
-
- best = rt;
- }
+ best = _Route_FindInterfaceRoute(AddressType, Address);
}
if( !best && Interface )
{
{
tRoute *rt = Node->ImplPtr;
int addrSize = IPStack_GetAddressSize(rt->AddressType);
+
+ ENTER("pNode iID pData", Node, ID, Data);
switch(ID)
{
// Get Next Hop
case 4:
- if( !CheckMem(Data, addrSize) ) return -1;
+ if( !CheckMem(Data, addrSize) ) LEAVE_RET('i', -1);
memcpy(Data, rt->NextHop, addrSize);
- return 1;
+ LEAVE_RET('i', 1);
// Set Next Hop
case 5:
- if( Threads_GetUID() != 0 ) return -1;
- if( !CheckMem(Data, addrSize) ) return -1;
+ if( Threads_GetUID() != 0 ) LEAVE_RET('i', -1);
+ if( !CheckMem(Data, addrSize) ) LEAVE_RET('i', -1);
memcpy(rt->NextHop, Data, addrSize);
- return 1;
+ LEAVE_RET('i', 1);
// Get interface name
case 6:
if( !rt->Interface ) {
if(Data && !CheckMem(Data, 1) )
- return -1;
+ LEAVE_RET('i', -1);
if(Data)
*(char*)Data = 0;
- return 0;
+ LEAVE_RET('i', 0);
}
if( Data ) {
if( !CheckMem(Data, strlen(rt->Interface->Name) + 1) )
- return -1;
+ LEAVE_RET('i', -1);
strcpy(Data, rt->Interface->Name);
}
- return strlen(rt->Interface->Name);
+ LEAVE_RET('i', strlen(rt->Interface->Name));
// Set interface name
case 7:
if( Threads_GetUID() != 0 )
- return -1;
+ LEAVE_RET('i', -1);
if( !CheckString(Data) )
- return -1;
+ LEAVE_RET('i', -1);
else
{
tInterface *iface;
tVFS_Node *tmp;
tmp = IPStack_Root_FindDir(NULL, Data);
if(!tmp)
- return -1;
+ LEAVE_RET('i', -1);
iface = tmp->ImplPtr;
if(tmp->Type->Close) tmp->Type->Close(tmp);
if( iface->Type != rt->AddressType )
- return -1;
+ LEAVE_RET('i', -1);
// TODO: Other checks?
rt->Interface = iface;
}
- return 0;
+ LEAVE_RET('i', 0);
default:
- return -1;
+ LEAVE_RET('i', -1);
}
}
-/* Acess2
- * NE2000 Driver
+/*
+ * Acess2 NE2000 Driver
+ * - By John Hodge (thePowersGang)
*
* See: ~/Sources/bochs/bochs.../iodev/ne2k.cc
*/
#define DEBUG 1
-#define VERSION ((0<<8)|50)
+#define VERSION VER2(0,6)
#include <acess.h>
#include <modules.h>
-#include <fs_devfs.h>
#include <drv_pci.h>
-#include <api_drv_network.h>
#include <semaphore.h>
+#include <IPStack/include/adapters_api.h>
// === CONSTANTS ===
#define MEM_START 0x40
int NextMemPage; //!< Next Card Memory page to use
- char Name[2]; // "0"
- tVFS_Node Node; //!< VFS Node
+ void *IPStackHandle;
Uint8 MacAddr[6]; //!< Cached MAC address
} tCard;
// === PROTOTYPES ===
int Ne2k_Install(char **Arguments);
-char *Ne2k_ReadDir(tVFS_Node *Node, int Pos);
-tVFS_Node *Ne2k_FindDir(tVFS_Node *Node, const char *Name);
- int Ne2k_IOCtl(tVFS_Node *Node, int ID, void *Data);
-size_t Ne2k_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);
-size_t Ne2k_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
+
+ int Ne2k_SendPacket(void *Ptr, tIPStackBuffer *Buffer);
+tIPStackBuffer *Ne2k_WaitForPacket(void *Ptr);
int Ne2k_int_ReadDMA(tCard *Card, int FirstPage, int NumPages, void *Buffer);
Uint8 Ne2k_int_GetWritePage(tCard *Card, Uint16 Length);
// === GLOBALS ===
MODULE_DEFINE(0, VERSION, Ne2k, Ne2k_Install, NULL, NULL);
-tVFS_NodeType gNe2K_RootNodeType = {
- .ReadDir = Ne2k_ReadDir,
- .FindDir = Ne2k_FindDir,
- .IOCtl = Ne2k_IOCtl
- };
-tVFS_NodeType gNe2K_DevNodeType = {
- .Write = Ne2k_Write,
- .Read = Ne2k_Read,
- .IOCtl = Ne2k_IOCtl
- };
-tDevFS_Driver gNe2k_DriverInfo = {
- NULL, "ne2k",
- {
- .NumACLs = 1,
- .ACLs = &gVFS_ACL_EveryoneRX,
- .Flags = VFS_FFLAG_DIRECTORY,
- .Type = &gNe2K_RootNodeType
- }
+tIPStack_AdapterType gNe2k_AdapterType = {
+ .Name = "Ne2k",
+ .Type = 0, // TODO: Differentiate differnet wire protos and speeds
+ .Flags = 0, // TODO: IP checksum offloading, MAC checksum offloading etc
+ .SendPacket = Ne2k_SendPacket,
+ .WaitForPacket = Ne2k_WaitForPacket
};
-Uint16 gNe2k_BaseAddress;
int giNe2k_CardCount = 0;
tCard *gpNe2k_Cards = NULL;
{
giNe2k_CardCount += PCI_CountDevices( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device );
}
-
if( giNe2k_CardCount == 0 ) return MODULE_ERR_NOTNEEDED;
+
+ LOG("%i NE2K cards found", giNe2k_CardCount);
// Enumerate Cards
k = 0;
for( i = 0; i < NUM_COMPAT_DEVICES; i ++ )
{
count = PCI_CountDevices( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device );
- for( j = 0; j < count; j ++,k ++ )
+ for( j = 0; j < count; j ++, k ++ )
{
+ tCard *card = &gpNe2k_Cards[k];
+
id = PCI_GetDevice( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, j );
// Create Structure
base = PCI_GetBAR( id, 0 );
- gpNe2k_Cards[ k ].IOBase = base;
- gpNe2k_Cards[ k ].IRQ = PCI_GetIRQ( id );
- gpNe2k_Cards[ k ].NextMemPage = 64;
- gpNe2k_Cards[ k ].NextRXPage = RX_FIRST;
+ LOG("%i: %i/%i id = %i, base = 0x%x", k, i, j, id, base);
+ if( !(base & 1) ) {
+ Log_Warning("Ne2k", "PCI %i's BARs are incorrect (BAR0 is not IO)", id);
+ continue ;
+ }
+ base &= ~1;
+ card->IOBase = base;
+ card->IRQ = PCI_GetIRQ( id );
+ card->NextMemPage = 64;
+ card->NextRXPage = RX_FIRST;
// Install IRQ Handler
- IRQ_AddHandler(gpNe2k_Cards[ k ].IRQ, Ne2k_IRQHandler, &gpNe2k_Cards[k]);
+ IRQ_AddHandler(card->IRQ, Ne2k_IRQHandler, &gpNe2k_Cards[k]);
+ LOG("%i: IRQ %i mapped, IOBase = 0x%x", k, card->IRQ, card->IOBase);
// Reset Card
outb( base + 0x1F, inb(base + 0x1F) );
- while( (inb( base+ISR ) & 0x80) == 0 );
+ while( (inb( base + ISR ) & 0x80) == 0 );
outb( base + ISR, 0x80 );
-
+
+ LOG("Reset done");
+
// Initialise Card
outb( base + CMD, 0x40|0x21 ); // Page 1, No DMA, Stop
outb( base + CURR, RX_FIRST ); // Current RX page
outb( base + RSAR0, 0 ); // Clear Source Address
outb( base + RSAR1, 0 );
outb( base + CMD, 0x0A ); // Remote Read, Start
- gpNe2k_Cards[ k ].MacAddr[0] = inb(base+0x10);// inb(base+0x10);
- gpNe2k_Cards[ k ].MacAddr[1] = inb(base+0x10);// inb(base+0x10);
- gpNe2k_Cards[ k ].MacAddr[2] = inb(base+0x10);// inb(base+0x10);
- gpNe2k_Cards[ k ].MacAddr[3] = inb(base+0x10);// inb(base+0x10);
- gpNe2k_Cards[ k ].MacAddr[4] = inb(base+0x10);// inb(base+0x10);
- gpNe2k_Cards[ k ].MacAddr[5] = inb(base+0x10);// inb(base+0x10);
+ card->MacAddr[0] = inb(base+0x10);// inb(base+0x10);
+ card->MacAddr[1] = inb(base+0x10);// inb(base+0x10);
+ card->MacAddr[2] = inb(base+0x10);// inb(base+0x10);
+ card->MacAddr[3] = inb(base+0x10);// inb(base+0x10);
+ card->MacAddr[4] = inb(base+0x10);// inb(base+0x10);
+ card->MacAddr[5] = inb(base+0x10);// inb(base+0x10);
outb( base+PSTART, RX_FIRST); // Set Receive Start
outb( base+BNRY, RX_LAST-1); // Set Boundary Page
outb( base+TPSR, 0x40); // Set Transmit Start
Log_Log("Ne2k", "Card %i 0x%04x IRQ%i %02x:%02x:%02x:%02x:%02x:%02x",
- k, base, gpNe2k_Cards[ k ].IRQ,
- gpNe2k_Cards[k].MacAddr[0], gpNe2k_Cards[k].MacAddr[1],
- gpNe2k_Cards[k].MacAddr[2], gpNe2k_Cards[k].MacAddr[3],
- gpNe2k_Cards[k].MacAddr[4], gpNe2k_Cards[k].MacAddr[5]
+ k, base, card->IRQ,
+ card->MacAddr[0], card->MacAddr[1],
+ card->MacAddr[2], card->MacAddr[3],
+ card->MacAddr[4], card->MacAddr[5]
);
- // Set VFS Node
- gpNe2k_Cards[ k ].Name[0] = '0'+k;
- gpNe2k_Cards[ k ].Name[1] = '\0';
- gpNe2k_Cards[ k ].Node.ImplPtr = &gpNe2k_Cards[ k ];
- gpNe2k_Cards[ k ].Node.NumACLs = 0; // Root Only
- gpNe2k_Cards[ k ].Node.CTime = now();
- gpNe2k_Cards[ k ].Node.Type = &gNe2K_DevNodeType;
+ card->IPStackHandle = IPStack_Adapter_Add(&gNe2k_AdapterType, card, card->MacAddr);
// Initialise packet semaphore
// - Start at zero, no max
- Semaphore_Init( &gpNe2k_Cards[k].Semaphore, 0, 0, "NE2000", gpNe2k_Cards[ k ].Name );
+ char name[10];
+ sprintf(name, "%i", k-1);
+ Semaphore_Init( &card->Semaphore, 0, 0, "NE2000", name );
}
}
- gNe2k_DriverInfo.RootNode.Size = giNe2k_CardCount;
- DevFS_AddDevice( &gNe2k_DriverInfo );
return MODULE_ERR_OK;
}
-/**
- * \fn char *Ne2k_ReadDir(tVFS_Node *Node, int Pos)
- */
-char *Ne2k_ReadDir(tVFS_Node *Node, int Pos)
-{
- char ret[2];
- if(Pos < 0 || Pos >= giNe2k_CardCount) return NULL;
- ret[0] = '0'+Pos;
- ret[1] = '\0';
- return strdup(ret);
-}
-
-/**
- * \fn tVFS_Node *Ne2k_FindDir(tVFS_Node *Node, const char *Name)
- */
-tVFS_Node *Ne2k_FindDir(tVFS_Node *Node, const char *Name)
-{
- if(Name[0] == '\0' || Name[1] != '\0') return NULL;
-
- return &gpNe2k_Cards[ Name[0]-'0' ].Node;
-}
-
-static const char *casIOCtls[] = { DRV_IOCTLNAMES, DRV_NETWORK_IOCTLNAMES, NULL };
-/**
- * \fn int Ne2k_IOCtl(tVFS_Node *Node, int ID, void *Data)
- * \brief IOCtl calls for a network device
- */
-int Ne2k_IOCtl(tVFS_Node *Node, int ID, void *Data)
-{
- ENTER("pNode iID pData", Node, ID, Data);
- switch( ID )
- {
- BASE_IOCTLS(DRV_TYPE_NETWORK, "NE2000", VERSION, casIOCtls);
- }
-
- // If this is the root, return
- if( Node == &gNe2k_DriverInfo.RootNode ) {
- LEAVE('i', 0);
- return 0;
- }
-
- // Device specific settings
- switch( ID )
- {
- case NET_IOCTL_GETMAC:
- if( !CheckMem(Data, 6) ) {
- LEAVE('i', -1);
- return -1;
- }
- memcpy( Data, ((tCard*)Node->ImplPtr)->MacAddr, 6 );
- LEAVE('i', 1);
- return 1;
- }
- LEAVE('i', 0);
- return 0;
-}
-
/**
* \brief Send a packet from the network card
*/
-size_t Ne2k_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer)
+int Ne2k_SendPacket(void *Ptr, tIPStackBuffer *Buffer)
{
- tCard *Card = (tCard*)Node->ImplPtr;
- const Uint16 *buf = Buffer;
- int rem = Length;
+ tCard *Card = Ptr;
+ int length;
int page;
- ENTER("pNode XOffset xLength pBuffer", Node, Offset, Length, Buffer);
+ ENTER("pPtr pBuffer", Ptr, Buffer);
+ length = IPStack_Buffer_GetLength(Buffer);
+
// TODO: Lock
// Sanity Check Length
- if(Length > TX_BUF_SIZE*256) {
+ if(length > TX_BUF_SIZE*256) {
Log_Warning(
"Ne2k",
"Ne2k_Write - Attempting to send over TX_BUF_SIZE*256 (%i) bytes (%i)",
- TX_BUF_SIZE*256, Length
+ TX_BUF_SIZE*256, length
);
- LEAVE('i', 0);
- return 0;
+ LEAVE('i', -1);
+ return -1;
}
// Make sure that the card is in page 0
outb(Card->IOBase + ISR, 0x40); // Bit 6
// Send Size - Transfer Byte Count Register
- outb(Card->IOBase + TBCR0, Length & 0xFF);
- outb(Card->IOBase + TBCR1, Length >> 8);
+ outb(Card->IOBase + TBCR0, length & 0xFF);
+ outb(Card->IOBase + TBCR1, length >> 8);
// Send Size - Remote Byte Count Register
- outb(Card->IOBase + RBCR0, Length & 0xFF);
- outb(Card->IOBase + RBCR1, Length >> 8);
+ outb(Card->IOBase + RBCR0, length & 0xFF);
+ outb(Card->IOBase + RBCR1, length >> 8);
// Set up transfer
outb(Card->IOBase + RSAR0, 0x00); // Page Offset
- page = Ne2k_int_GetWritePage(Card, Length);
+ page = Ne2k_int_GetWritePage(Card, length);
outb(Card->IOBase + RSAR1, page); // Page Offset
// Start
outb(Card->IOBase + CMD, 0|0x10|0x2); // Page 0, Remote Write, Start
// Send Data
- for(rem = Length; rem > 0; rem -= 2) {
- outw(Card->IOBase + 0x10, *buf++);
+ size_t buflen;
+ const void *bufptr;
+ for(int id = -1; (id = IPStack_Buffer_GetBuffer(Buffer, -1, &buflen, &bufptr)) != -1; )
+ {
+ const Uint16 *buf = bufptr;
+ if( buflen & 1 )
+ Log_Notice("NE2000", "Alignment issue in TX buffer");
+ buflen = (buflen + 1) / 2;
+ while(buflen --)
+ outw(Card->IOBase + 0x10, *buf++);
}
while( !(inb(Card->IOBase + ISR) & 0x40) ) // Wait for Remote DMA Complete
// Complete DMA
//outb(Card->IOBase + CMD, 0|0x20);
- LEAVE('i', Length);
- return Length;
+ LEAVE('i', 0);
+ return 0;
+}
+
+void _FreeHeapSubBuf(void *Arg, size_t Pre, size_t Post, const void *DataBuf)
+{
+ free(Arg);
}
/**
* \brief Wait for and read a packet from the network card
*/
-size_t Ne2k_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
+tIPStackBuffer *Ne2k_WaitForPacket(void *Ptr)
{
- tCard *Card = Node->ImplPtr;
+ tCard *Card = Ptr;
Uint8 page;
Uint8 data[256];
+ void *buf;
+ tIPStackBuffer *ret;
struct {
Uint8 Status;
Uint8 NextPacketPage;
Uint16 Length; // Little Endian
} *pktHdr;
- ENTER("pNode XOffset xLength pBuffer", Node, Offset, Length, Buffer);
+ ENTER("pPtr", Ptr);
// Wait for packets
if( Semaphore_Wait( &Card->Semaphore, 1 ) != 1 )
{
// Error or interrupted
- LEAVE_RET('i', 0);
+ LEAVE('n');
+ return NULL;
}
outb(Card->IOBase, 0x22 | (1 << 6)); // Page 6
LOG("pktHdr->Status = 0x%x", pktHdr->Status);
LOG("pktHdr->NextPacketPage = %i", pktHdr->NextPacketPage);
LOG("pktHdr->Length = 0x%03x", pktHdr->Length);
-
+
+ ret = IPStack_Buffer_CreateBuffer(1);
+ if(!ret) LEAVE_RET('n', NULL);
+ buf = malloc( pktHdr->Length );
+ if(!buf) LEAVE_RET('n', NULL);
+ IPStack_Buffer_AppendSubBuffer(ret, pktHdr->Length, 0, buf, _FreeHeapSubBuf, buf);
+
// Have we read all the required bytes yet?
if(pktHdr->Length < 256 - 4)
{
- if(Length > pktHdr->Length)
- Length = pktHdr->Length;
- memcpy(Buffer, &data[4], Length);
+ memcpy(buf, &data[4], pktHdr->Length);
}
// No? oh damn, now we need to allocate a buffer
else
{
int pages = pktHdr->NextPacketPage - page;
- char *buf = malloc( pages*256 );
+ Uint8 *writepos = buf;
+ int rem_bytes = pktHdr->Length;
LOG("pktHdr->Length (%i) > 256 - 4, allocated buffer %p", pktHdr->Length, buf);
- if(!buf) LEAVE_RET('i', -1);
// Copy the already read data
- memcpy(buf, data, 256);
+ memcpy(writepos, data+4, 256-4);
+ writepos += 256-4;
+ rem_bytes -= 256-4;
// Read all the needed pages
page ++;
if(page == RX_LAST+1) page = RX_FIRST;
-
- if( page + pages > RX_LAST )
+
+ // - Body Pages
+ if( pages > 2 )
{
- int first_count = RX_LAST+1 - page;
- int tmp = 0;
- tmp += Ne2k_int_ReadDMA(Card, page, first_count, buf+256);
- tmp += Ne2k_int_ReadDMA(Card, RX_FIRST, pages-1-first_count, buf+(first_count+1)*256);
- LOG("composite return count = %i", tmp);
+ if( page + pages - 2 > RX_LAST )
+ {
+ int first_count = RX_LAST - page + 1;
+ Ne2k_int_ReadDMA(Card, page, first_count, writepos);
+ Ne2k_int_ReadDMA(Card, RX_FIRST, pages-2-first_count, writepos + first_count*256);
+ writepos += (pages-2-first_count) * 256;
+ }
+ else
+ Ne2k_int_ReadDMA(Card, page, pages - 2, writepos);
+ page += pages - 2;
+ if(page > RX_LAST) page -= (RX_LAST-RX_FIRST)+1;
+ writepos += (pages-2) * 256;
+ rem_bytes -= (pages-2) * 256;
}
- else
- Ne2k_int_ReadDMA(Card, page, pages-1, buf+256);
-
- // Wrap length to the packet length
- if(Length > pktHdr->Length)
- Length = pktHdr->Length;
- else if( Length < pktHdr->Length ) {
- Log_Warning("NE2000", "Packet truncated! (%i bytes truncated to %i)",
- pktHdr->Length, Length);
- }
- memcpy(Buffer, &buf[4], Length);
-
- free(buf);
+
+ ASSERT(rem_bytes > 0 && rem_bytes <= 0x100);
+
+ // Final page
+ Ne2k_int_ReadDMA(Card, page, 1, data);
+ memcpy(writepos, data, rem_bytes);
}
// Write BNRY (maximum page for incoming packets)
// Set next RX Page and decrement the waiting list
Card->NextRXPage = pktHdr->NextPacketPage;
- LEAVE('i', Length);
- return Length;
+ LEAVE('p', ret);
+ return ret;
}
int Ne2k_int_ReadDMA(tCard *Card, int FirstPage, int NumPages, void *Buffer)
#define VERSION ((0<<8)|20)
#include <acess.h>
#include <modules.h>
-#include <fs_devfs.h>
#include <drv_pci.h>
-#include <api_drv_network.h>
#include <semaphore.h>
+#include <IPStack/include/adapters_api.h>
// === CONSTANTS ===
#define VENDOR_ID 0x10EC
// Early RX Status Register
ERSR = 0x36,
- // ??, ??, ??, RST, RE, TE, ??, ??
+ // -, -, -, RST, RE, TE, -, BUFE
CMD = 0x37,
CAPR = 0x38, // Current address of packet read
tMutex CurTXProtector; //!< Protects \a .CurTXDescriptor
int CurTXDescriptor;
- char Name[2];
- tVFS_Node Node;
+ void *IPStackHandle;
Uint8 MacAddr[6];
} tCard;
// === PROTOTYPES ===
int RTL8139_Install(char **Options);
-char *RTL8139_ReadDir(tVFS_Node *Node, int Pos);
-tVFS_Node *RTL8139_FindDir(tVFS_Node *Node, const char *Filename);
- int RTL8139_RootIOCtl(tVFS_Node *Node, int ID, void *Arg);
-size_t RTL8139_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
-size_t RTL8139_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);
- int RTL8139_IOCtl(tVFS_Node *Node, int ID, void *Arg);
+tIPStackBuffer *RTL8139_WaitForPacket(void *Ptr);
+void RTL8139_int_UpdateCAPR(void *Ptr, size_t pkt_length, size_t Unused, const void *DataPtr);
+ int RTL8139_SendPacket(void *Ptr, tIPStackBuffer *Buffer);
void RTL8139_IRQHandler(int Num, void *Ptr);
// === GLOBALS ===
MODULE_DEFINE(0, VERSION, RTL8139, RTL8139_Install, NULL, NULL);
-tVFS_NodeType gRTL8139_RootNodeType = {
- .ReadDir = RTL8139_ReadDir,
- .FindDir = RTL8139_FindDir,
- .IOCtl = RTL8139_IOCtl
+tIPStack_AdapterType gRTL8139_AdapterType = {
+ .Name = "RTL8139",
+ .Type = 0, // TODO: Differentiate differnet wire protos and speeds
+ .Flags = 0, // TODO: IP checksum offloading, MAC checksum offloading etc
+ .SendPacket = RTL8139_SendPacket,
+ .WaitForPacket = RTL8139_WaitForPacket
};
-tVFS_NodeType gRTL8139_DevNodeType = {
- .Write = RTL8139_Write,
- .Read = RTL8139_Read,
- .IOCtl = RTL8139_IOCtl
- };
-tDevFS_Driver gRTL8139_DriverInfo = {
- NULL, "RTL8139",
- {
- .NumACLs = 1,
- .ACLs = &gVFS_ACL_EveryoneRX,
- .Flags = VFS_FFLAG_DIRECTORY,
- .Type = &gRTL8139_RootNodeType
- }
-};
int giRTL8139_CardCount;
tCard *gaRTL8139_Cards;
card->MacAddr[4] = inb(base+MAC4);
card->MacAddr[5] = inb(base+MAC5);
- // Set VFS Node
- card->Name[0] = '0'+i;
- card->Name[1] = '\0';
- card->Node.ImplPtr = card;
- card->Node.NumACLs = 0;
- card->Node.CTime = now();
- card->Node.Type = &gRTL8139_DevNodeType;
-
+ // Interface with IPStack
+ card->IPStackHandle = IPStack_Adapter_Add(&gRTL8139_AdapterType, card, card->MacAddr);
+
Log_Log("RTL8139", "Card %i 0x%04x, IRQ %i %02x:%02x:%02x:%02x:%02x:%02x",
i, card->IOBase, card->IRQ,
card->MacAddr[0], card->MacAddr[1], card->MacAddr[2],
);
}
- gRTL8139_DriverInfo.RootNode.Size = giRTL8139_CardCount;
- DevFS_AddDevice( &gRTL8139_DriverInfo );
-
return MODULE_ERR_OK;
}
-// --- Root Functions ---
-char *RTL8139_ReadDir(tVFS_Node *Node, int Pos)
-{
- if( Pos < 0 || Pos >= giRTL8139_CardCount ) return NULL;
-
- return strdup( gaRTL8139_Cards[Pos].Name );
-}
-
-tVFS_Node *RTL8139_FindDir(tVFS_Node *Node, const char *Filename)
-{
- //TODO: It might be an idea to supprt >10 cards
- if(Filename[0] == '\0' || Filename[1] != '\0') return NULL;
- if(Filename[0] < '0' || Filename[0] > '9') return NULL;
- return &gaRTL8139_Cards[ Filename[0]-'0' ].Node;
-}
-
-const char *csaRTL8139_RootIOCtls[] = {DRV_IOCTLNAMES, NULL};
-int RTL8139_RootIOCtl(tVFS_Node *Node, int ID, void *Data)
-{
- ENTER("pNode iID pData", Node, ID, Data);
- switch(ID)
- {
- BASE_IOCTLS(DRV_TYPE_NETWORK, "RTL8139", VERSION, csaRTL8139_RootIOCtls);
- }
- LEAVE('i', 0);
- return 0;
-}
-
// --- File Functions ---
-size_t RTL8139_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
+tIPStackBuffer *RTL8139_WaitForPacket(void *Ptr)
{
- tCard *card = Node->ImplPtr;
+ tCard *card = Ptr;
Uint16 read_ofs, pkt_length;
- int new_read_ofs;
+ tIPStackBuffer *ret;
- ENTER("pNode XOffset xLength pBuffer", Node, Offset, Length, Buffer);
+ ENTER("pPtr", Ptr);
retry:
+ LOG("IMR = %x, ISR = %x", inw(card->IOBase + IMR), inw(card->IOBase + ISR));
if( Semaphore_Wait( &card->ReadSemaphore, 1 ) != 1 )
{
- LEAVE_RET('i', 0);
+ LEAVE('n');
+ return NULL;
}
Mutex_Acquire( &card->ReadMutex );
pkt_length = *(Uint16*)&card->ReceiveBuffer[read_ofs+2];
+ // Check for errors
+ if( *(Uint16*)&card->ReceiveBuffer[read_ofs] & 0x1E )
+ {
+ // Update CAPR
+ RTL8139_int_UpdateCAPR( card, pkt_length, 0, &card->ReceiveBuffer[read_ofs+4] );
+ Mutex_Release( &card->ReadMutex );
+ goto retry; // I feel evil
+ }
+
+ ret = IPStack_Buffer_CreateBuffer(1);
+ IPStack_Buffer_AppendSubBuffer(ret,
+ pkt_length, 0, &card->ReceiveBuffer[read_ofs+4],
+ RTL8139_int_UpdateCAPR, card
+ );
+
+ Mutex_Release( &card->ReadMutex );
+
+ LEAVE('p', ret);
+ return ret;
+}
+
+/**
+ * \brief Updates CAPR after a packet has been read
+ * \note Assumes that buffers are freed in the order we allocate them
+ */
+void RTL8139_int_UpdateCAPR(void *Ptr, size_t pkt_length, size_t Unused, const void *DataPtr)
+{
+ tCard *card = Ptr;
+ int read_ofs = DataPtr - (const void *)card->ReceiveBuffer - 4;
+ int new_read_ofs;
+
// Calculate new read offset
new_read_ofs = read_ofs + pkt_length + 4;
new_read_ofs = (new_read_ofs + 3) & ~3; // Align
}
new_read_ofs -= 0x10; // I dunno
LOG("new_read_ofs = %i", new_read_ofs);
-
- // Check for errors
- if( *(Uint16*)&card->ReceiveBuffer[read_ofs] & 0x1E ) {
- // Update CAPR
- outw(card->IOBase + CAPR, new_read_ofs);
- Mutex_Release( &card->ReadMutex );
- goto retry; // I feel evil
- }
-
- // Get packet
- if( Length > pkt_length ) Length = pkt_length;
- memcpy(Buffer, &card->ReceiveBuffer[read_ofs+4], Length);
-
+
// Update CAPR
outw(card->IOBase + CAPR, new_read_ofs);
-
- Mutex_Release( &card->ReadMutex );
-
- LEAVE('i', Length);
-
- return Length;
}
-size_t RTL8139_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer)
+int RTL8139_SendPacket(void *Ptr, tIPStackBuffer *Buffer)
{
- int td;
+ int td, length;
Uint32 status;
- tCard *card = Node->ImplPtr;
-
- if( Length > 1500 ) return 0; // MTU exceeded
+ tCard *card = Ptr;
- ENTER("pNode XLength pBuffer", Node, Length, Buffer);
+ ENTER("pPtr pBuffer", Ptr, Buffer);
+
+ length = IPStack_Buffer_GetLength(Buffer);
+ if( length > 1500 ) {
+ LEAVE('i', -1);
+ return -1; // MTU exceeded
+ }
// TODO: Implement a semaphore for avaliable transmit buffers
// Transmit using descriptor `td`
LOG("card->PhysTransmitBuffers[td] = %P", card->PhysTransmitBuffers[td]);
outd(card->IOBase + TSAD0 + td*4, card->PhysTransmitBuffers[td]);
- LOG("card->TransmitBuffers[td] = %p", card->TransmitBuffers[td]);
+
// Copy to buffer
- memcpy(card->TransmitBuffers[td], Buffer, Length);
+ LOG("card->TransmitBuffers[td] = %p", card->TransmitBuffers[td]);
+ IPStack_Buffer_GetData(Buffer, card->TransmitBuffers[td], length);
+
// Start
status = 0;
- status |= Length & 0x1FFF; // 0-12: Length
+ status |= length & 0x1FFF; // 0-12: Length
status |= 0 << 13; // 13: OWN bit
status |= (0 & 0x3F) << 16; // 16-21: Early TX threshold (zero atm, TODO: check)
LOG("status = 0x%08x", status);
outd(card->IOBase + TSD0 + td*4, status);
- LEAVE('i', (int)Length);
-
- return Length;
-}
-
-const char *csaRTL8139_NodeIOCtls[] = {DRV_IOCTLNAMES, NULL};
-int RTL8139_IOCtl(tVFS_Node *Node, int ID, void *Data)
-{
- tCard *card = Node->ImplPtr;
- ENTER("pNode iID pData", Node, ID, Data);
- switch(ID)
- {
- BASE_IOCTLS(DRV_TYPE_NETWORK, "RTL8139", VERSION, csaRTL8139_NodeIOCtls);
- case NET_IOCTL_GETMAC:
- if( !CheckMem(Data, 6) ) {
- LEAVE('i', -1);
- return -1;
- }
- memcpy( Data, card->MacAddr, 6 );
- LEAVE('i', 1);
- return 1;
- }
- LEAVE('i', 0);
+ LEAVE('i', 0);
return 0;
}
tCard *card = Ptr;
Uint16 status;
- LOG("Num = %i", Num);
-
if( Num != card->IRQ ) return;
status = inw(card->IOBase + ISR);
+ if( !status ) return ;
LOG("status = 0x%02x", status);
// Transmit OK, a transmit descriptor is now free
{
if( Semaphore_Signal( &card->ReadSemaphore, packet_count ) != packet_count ) {
// Oops?
+ Log_Warning("RTL8139", "IRQ: signalling read semaphore failed, Oops?");
}
- VFS_MarkAvaliable( &card->Node, 1 );
}
outw(card->IOBase + ISR, FLAG_ISR_ROK);
ifaces->Adapter = argv[1];
}
else {
- Scan_Dir( &ifaces, "/Devices" );
+ Scan_Dir( &ifaces, "/Devices/ip/adapters" );
}
for( i = ifaces; i; i = i->Next )
while( readdir(dp, filename) )
{
- int pathlen = strlen(Directory) + 1 + strlen(filename) + 1;
- char path[pathlen];
- int fd;
- t_sysFInfo info;
-
- sprintf(path, "%s/%s", Directory, filename);
- fd = open(path, 0);
-
- // Check if the device type is 9 (Network)
- if( ioctl(fd, 0, NULL) != 9 )
- continue ;
-
- // Check if it's a directory
- finfo(fd, &info, 0);
- if( info.flags & FILEFLAG_DIRECTORY )
- {
- // If so, recurse
- Scan_Dir(IfaceList, path);
- }
- else
- {
- // Otherwise, add it to the list
- tInterface *new = malloc(sizeof(tInterface) + pathlen);
- new->Adapter = (void*)(new + 1);
- strcpy(new->Adapter, path);
- new->Next = *IfaceList;
- *IfaceList = new;
- }
+ if( filename[0] == '.' ) continue ;
+ if( strcmp(filename, "lo") == 0 ) continue ;
+
+ tInterface *new = malloc(sizeof(tInterface) + strlen(filename)+1);
+ new->Adapter = (void*)(new + 1);
+ strcpy(new->Adapter, filename);
+ new->Next = *IfaceList;
+ *IfaceList = new;
}
close(dp);
}
msg->giaddr = htonl(0); // giaddr - Zero?
// Request MAC address from network adapter
{
- int fd = open(Iface->Adapter, 0);
- // TODO: Check if open() failed
- ioctl(fd, 4, msg->chaddr);
- // TODO: Check if ioctl() failed
- close(fd);
+ char path[] = "/Devices/ip/adapters/ethXXXX";
+ sprintf(path, "/Devices/ip/adapters/%s", Iface->Adapter);
+ int fd = open(path, 0);
+ if(fd == -1) {
+ _SysDebug("Unable to open adapter %s", path);
+ }
+ else {
+ ioctl(fd, 4, msg->chaddr);
+ // TODO: Check if ioctl() failed
+ close(fd);
+ }
}
memset(msg->sname, 0, sizeof(msg->sname)); // Nuke the rest
memset(msg->file, 0, sizeof(msg->file)); // Nuke the rest
break;
case 2: // DHCPOFFER
// Send out request for this address
- if( Iface->State != STATE_DISCOVER_SENT ) return 0;
+ if( Iface->State != STATE_DISCOVER_SENT ) {
+ _SysDebug("Ignoring DHCPOFFER when not in STATE_DISCOVER_SENT");
+ return 0;
+ }
Send_DHCPREQUEST(Iface, data, dhcp_msg_type_ofs);
break;
case 3: // DHCPREQUEST - wut?
PrintUsage(argv[0]);
return -1;
}
- // TODO: Also set the IP address as the usage says it does
ret = AddInterface( argv[2] );
if(ret < 0) return ret;
ret = SetAddress( ret, argv[3] );
/*
- * Acess2 IFCONFIG command
+ * Acess2 ping command
*/
#include <stdlib.h>
#include <stdint.h>