Merge branch 'master' of git://git.ucc.asn.au/tpg/acess2
authorJohn Hodge <[email protected]>
Mon, 14 May 2012 06:56:47 +0000 (14:56 +0800)
committerJohn Hodge <[email protected]>
Mon, 14 May 2012 06:56:47 +0000 (14:56 +0800)
34 files changed:
KernelLand/Modules/IPStack/Makefile
KernelLand/Modules/IPStack/adapters.c [new file with mode: 0644]
KernelLand/Modules/IPStack/arp.c
KernelLand/Modules/IPStack/buffer.c
KernelLand/Modules/IPStack/include/adapters.h [new file with mode: 0644]
KernelLand/Modules/IPStack/include/adapters_api.h [new file with mode: 0644]
KernelLand/Modules/IPStack/include/adapters_int.h [new file with mode: 0644]
KernelLand/Modules/IPStack/include/buffer.h
KernelLand/Modules/IPStack/interface.c
KernelLand/Modules/IPStack/ipstack.h
KernelLand/Modules/IPStack/ipv4.c
KernelLand/Modules/IPStack/link.c
KernelLand/Modules/IPStack/link.h
KernelLand/Modules/IPStack/main.c
KernelLand/Modules/IPStack/routing.c
KernelLand/Modules/IPStack/tcp.c
KernelLand/Modules/Network/NE2000/ne2000.c
KernelLand/Modules/Network/RTL8139/rtl8139.c
KernelLand/Modules/Network/VIARhineII/rhine2.c
KernelLand/Modules/Network/VIARhineII/rhine2_hw.h [new file with mode: 0644]
KernelLand/Modules/USB/Core/usb_devinit.c
Makefile
Usermode/Applications/dhcpclient_src/main.c
Usermode/Applications/ifconfig_src/Makefile [deleted file]
Usermode/Applications/ifconfig_src/main.c [deleted file]
Usermode/Applications/ifconfig_src/rules.mk [deleted file]
Usermode/Applications/ip_src/Makefile [new file with mode: 0644]
Usermode/Applications/ip_src/addr.c [new file with mode: 0644]
Usermode/Applications/ip_src/common.h [new file with mode: 0644]
Usermode/Applications/ip_src/main.c [new file with mode: 0644]
Usermode/Applications/ip_src/routes.c [new file with mode: 0644]
Usermode/Applications/ip_src/rules.mk [new file with mode: 0644]
Usermode/Applications/irc_src/main.c
Usermode/Applications/ping_src/main.c

index b0ee26b..3ea5f7e 100644 (file)
@@ -1,7 +1,7 @@
 #
 #
 
-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
diff --git a/KernelLand/Modules/IPStack/adapters.c b/KernelLand/Modules/IPStack/adapters.c
new file mode 100644 (file)
index 0000000..8289455
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * 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 ) { \
+                       return Adapter_GetName(a);\
+               } \
+               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;
+}
+
+char *Adapter_GetName(tAdapter *Adapter)
+{
+       if( Adapter == &gIP_LoopAdapter )
+       {
+               return strdup("lo");
+       }
+       else
+       {
+               // TODO: Support multiple adapter types
+               char    buf[sizeof("eth")+10];
+               sprintf(buf, "eth%i", Adapter->Index);
+               return strdup(buf);
+       }
+}
+
+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;
+}
+
index 607f201..e152e33 100644 (file)
@@ -8,6 +8,7 @@
 #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
@@ -145,7 +146,7 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address)
        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;
@@ -332,7 +333,7 @@ void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffe
                                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],
@@ -341,7 +342,7 @@ void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffe
                                
                                // 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);
                        }
index 9151c1c..b8462e6 100644 (file)
@@ -19,6 +19,8 @@ struct sIPStackBuffer
                const void      *Data;
                size_t  PreLength;
                size_t  PostLength;
+               tIPStackBufferCb        Cb;
+               void    *CbArg;
                // TODO: Callbacks?
        } SubBuffers[];
 };
@@ -36,11 +38,27 @@ tIPStackBuffer *IPStack_Buffer_CreateBuffer(int MaxBuffers)
        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);
 }
 
@@ -62,6 +80,8 @@ void IPStack_Buffer_AppendSubBuffer(tIPStackBuffer *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)
@@ -69,9 +89,43 @@ 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;
@@ -79,27 +133,9 @@ void *IPStack_Buffer_CompactBuffer(tIPStackBuffer *Buffer, size_t *Length)
        }
        
        *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;
 }
 
diff --git a/KernelLand/Modules/IPStack/include/adapters.h b/KernelLand/Modules/IPStack/include/adapters.h
new file mode 100644 (file)
index 0000000..e0b13ff
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * 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 char    *Adapter_GetName(tAdapter *Adapter);
+extern void    Adapter_SendPacket(tAdapter *Handle, tIPStackBuffer *Buffer);
+
+
+#endif
+
diff --git a/KernelLand/Modules/IPStack/include/adapters_api.h b/KernelLand/Modules/IPStack/include/adapters_api.h
new file mode 100644 (file)
index 0000000..0ecd847
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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
+
diff --git a/KernelLand/Modules/IPStack/include/adapters_int.h b/KernelLand/Modules/IPStack/include/adapters_int.h
new file mode 100644 (file)
index 0000000..c474818
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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
+
index 62c1308..ad0516a 100644 (file)
@@ -15,6 +15,10 @@ typedef void (*tIPStackBufferCb)(void *Arg, size_t HeadLen, size_t FootLen, cons
  * \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
  */
@@ -38,6 +42,15 @@ extern void  IPStack_Buffer_AppendSubBuffer(tIPStackBuffer *Buffer,
  * \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
index b0b63b9..8fe0a43 100644 (file)
@@ -7,7 +7,7 @@
 #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
@@ -17,6 +17,7 @@
 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);
@@ -25,7 +26,6 @@ tVFS_Node     *IPStack_Root_FindDir(tVFS_Node *Node, 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);
 tVFS_Node      *IPStack_Iface_FindDir(tVFS_Node *Node, const char *Name);
@@ -53,17 +53,10 @@ tInterface  gIP_LoopInterface = {
 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 ===
 
 /**
@@ -81,12 +74,17 @@ char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos)
                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 ) ;
@@ -145,6 +143,12 @@ tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name)
                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);
@@ -210,7 +214,7 @@ tInterface *IPStack_AddInterface(const char *Device, const char *Name)
        
        ENTER("sDevice", Device);
        
-       card = IPStack_GetAdapter(Device);
+       card = Adapter_GetByName(Device);
        if( !card ) {
                Log_Debug("IPStack", "Unable to open card '%s'", Device);
                LEAVE('n');
@@ -438,12 +442,17 @@ int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
        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
@@ -471,109 +480,3 @@ int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
        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;
-}
index e51fded..5ea5dc9 100644 (file)
@@ -71,6 +71,7 @@ struct sInterface {
        char    Name[];
 };
 
+#if 0
 /**
  * \brief Represents a network adapter
  */
@@ -84,6 +85,7 @@ struct sAdapter {
         int    DeviceLen;      //!< Device name length
        char    Device[];       //!< Device name
 };
+#endif
 
 /**
  * \brief Describes a socket file definition
index d5c2f96..3162301 100644 (file)
@@ -15,6 +15,7 @@ extern tInterface     *gIP_Interfaces;
 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();
@@ -185,6 +186,9 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff
                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);
index 37b7260..3dcd294 100644 (file)
@@ -1,10 +1,15 @@
 /*
- * 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
@@ -12,7 +17,7 @@
 // === 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);
@@ -87,7 +92,7 @@ void Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, tIPStackBuffer
                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;
 
@@ -95,95 +100,67 @@ void Link_SendPacket(tAdapter *Adapter, Uint16 Type, tMacAddr To, tIPStackBuffer
        
        *(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
index bdea0e2..ac07342 100644 (file)
@@ -12,6 +12,7 @@ typedef void (*tPacketCallback)(tAdapter *Interface, tMacAddr From, int Length,
 
 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 ===
index d5d1ebc..5763e2d 100644 (file)
@@ -8,6 +8,7 @@
 #include "link.h"
 #include <modules.h>
 #include <fs_devfs.h>
+#include "include/adapters.h"
 
 // === IMPORTS ===
 extern int     ARP_Initialise();
@@ -16,7 +17,6 @@ extern void   TCP_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);
@@ -53,8 +53,7 @@ tDevFS_Driver gIP_DriverInfo = {
  */
 int IPStack_Install(char **Arguments)
 {
-        int    i = 0;
-       
+       // TODO: different Layer 2 protocols
        // Layer 3 - Network Layer Protocols
        ARP_Initialise();
        IPv4_Initialise();
@@ -63,136 +62,8 @@ int IPStack_Install(char **Arguments)
        TCP_Initialise();
        UDP_Initialise();
        
-       if(Arguments)
-       {
-               // Parse module arguments
-               for( i = 0; Arguments[i]; i++ )
-               {
-                       // TODO:
-                       // Define interfaces by <Device>:<Type>:<HexStreamAddress>:<Bits>
-                       // Where:
-                       // - <Device> is the device path (E.g. /Devices/ne2k/0)
-                       // - <Type> is a number (e.g. 4) or symbol (e.g. AF_INET4)
-                       // - <HexStreamAddress> is a condensed hexadecimal stream (in big endian)
-                       //      (E.g. 0A000201 for 10.0.2.1 IPv4)
-                       // - <Bits> is the number of subnet bits (E.g. 24 for an IPv4 Class C)
-                       // Example: /Devices/ne2k/0:4:0A00020A:24
-                       //  would define an interface with the address 10.0.2.10/24
-                       if( Arguments[i][0] == '/' ) {
-                               // Define Interface
-                               char    *dev, *type, *addr, *bits;
-                               
-                               // Read definition
-                               dev = Arguments[i];
-                               type = strchr(dev, ':');
-                               if( !type ) {
-                                       Log_Warning("IPStack", "<Device>:<Type>:<HexStreamAddress>:<Bits>");
-                                       continue;
-                               }
-                               *type = '\0';   type ++;
-                               
-                               addr = strchr(type, ':');
-                               if( !addr ) {
-                                       Log_Warning("IPStack", "<Device>:<Type>:<HexStreamAddress>:<Bits>");
-                                       continue;
-                               }
-                               *addr = '\0';   addr ++;
-                               
-                               bits = strchr(addr, ':');
-                               if( !bits ) {
-                                       Log_Warning("IPStack", "<Device>:<Type>:<HexStreamAddress>:<Bits>");
-                                       continue;
-                               }
-                               *bits = '\0';   bits ++;
-                               
-                               // Define interface
-                               {
-                                        int    iType = atoi(type);
-                                        int    size = IPStack_GetAddressSize(iType);
-                                       Uint8   addrData[size];
-                                        int    iBits = atoi(bits);
-                                       
-                                       UnHex(addrData, size, addr);
-                                       
-                                       tInterface      *iface = IPStack_AddInterface(dev, "");
-                                       if( !iface ) {
-                                               Log_Warning("IPStack", "Unable to add interface on '%s'", dev);
-                                               continue ;
-                                       }
-                                       iface->Type = iType;
-                                       memcpy(iface->Address, addrData, size);
-                                       iface->SubnetBits = iBits;
-                                       
-                                       // Route for addrData/iBits, no next hop, default metric
-                                       IPStack_AddRoute(iface->Name, iface->Address, iBits, NULL, 0);
-
-                                       Log_Notice("IPStack", "Boot interface %s/%i on %s",
-                                               IPStack_PrintAddress(iType, addrData), iBits,
-                                               dev);
-                               }
-                               
-                               continue;
-                       }
-                       
-                       // I could also define routes using <Interface>:<HexStreamNetwork>:<Bits>[:<HexStreamGateway>]
-                       // Example: 1:00000000:0:0A000201
-                       if( '0' <= Arguments[i][0] && Arguments[i][0] <= '9' )
-                       {
-                               // Define Interface
-                               char    *ifaceName, *network, *bits, *gateway;
-                               
-                               // Read definition
-                               ifaceName = Arguments[i];
-                               
-                               network = strchr(ifaceName, ':');
-                               if( !network ) {
-                                       Log_Warning("IPStack", "<iface>:<HexStreamNetwork>:<Bits>:<HexStreamGateway>");
-                                       continue;
-                               }
-                               *network = '\0';        network ++;
-                               
-                               bits = strchr(network, ':');
-                               if( !bits ) {
-                                       Log_Warning("IPStack", "<Device>:<Type>:<HexStreamAddress>:<Bits>");
-                                       continue;
-                               }
-                               *bits = '\0';   bits ++;
-                               
-                               gateway = strchr(bits, ':');
-                               if( gateway ) {
-                                       *gateway = '\0';        gateway ++;
-                               }
-                               
-                               // Define route
-                               {
-                                       tVFS_Node       *node = IPStack_Root_FindDir(NULL, ifaceName);
-                                       if( !node ) {
-                                               Log_Warning("IPStack", "Unknown interface '%s' in arg %i", ifaceName, i);
-                                               continue ;
-                                       }
-                                       tInterface      *iface = node->ImplPtr;
-                                       
-                                        int    size = IPStack_GetAddressSize(iface->Type);
-                                       Uint8   netData[size];
-                                       Uint8   gwData[size];
-                                        int    iBits = atoi(bits);
-                                       
-                                       UnHex(netData, size, network);
-                                       if( gateway )
-                                               UnHex(gwData, size, gateway);
-                                       else
-                                               memset(gwData, 0, size);
-                                       
-                                       IPStack_AddRoute(ifaceName, netData, iBits, gwData, 30);
-                               }
-                               
-                               continue;
-                       }
-               }
-       }
-       
        // Initialise loopback interface
-       gIP_LoopInterface.Adapter = IPStack_GetAdapter("LOOPBACK");
+       gIP_LoopInterface.Adapter = Adapter_GetByName("lo");
        
        DevFS_AddDevice( &gIP_DriverInfo );
        
index 7173d1f..c4b5392 100644 (file)
@@ -27,6 +27,7 @@ tRoute        *_Route_FindExactRoute(int Type, void *Network, int Subnet, int Metric);
 // - 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);
@@ -112,17 +113,25 @@ tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name)
                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] == '#' )
        {
@@ -435,13 +444,56 @@ tRoute *IPStack_AddRoute(const char *Interface, void *Network, int SubnetBits, v
        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",
@@ -460,7 +512,7 @@ tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address)
        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;
                
@@ -489,37 +541,7 @@ tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address)
        // 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 )
        {
@@ -559,6 +581,8 @@ int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data)
 {
        tRoute  *rt = Node->ImplPtr;
         int    addrSize = IPStack_GetAddressSize(rt->AddressType);
+
+       ENTER("pNode iID pData", Node, ID, Data);
        
        switch(ID)
        {
@@ -567,57 +591,57 @@ int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data)
        
        // 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);
        }
 }
index ee71bc7..c8a5584 100644 (file)
@@ -2,7 +2,7 @@
  * Acess2 IP Stack
  * - TCP Handling
  */
-#define DEBUG  1
+#define DEBUG  0
 #include "ipstack.h"
 #include "ipv4.h"
 #include "ipv6.h"
@@ -105,7 +105,7 @@ void TCP_SendPacket( tTCPConnection *Conn, tTCPHeader *Header, size_t Length, co
                IPStack_Buffer_AppendSubBuffer(buffer, Length, 0, Data, NULL, NULL);
        IPStack_Buffer_AppendSubBuffer(buffer, sizeof(*Header), 0, Header, NULL, NULL);
 
-       Log_Debug("TCP", "Sending %i+%i to %s:%i", sizeof(*Header), Length,
+       LOG("Sending %i+%i to %s:%i", sizeof(*Header), Length,
                IPStack_PrintAddress(Conn->Interface->Type, &Conn->RemoteIP),
                Conn->RemotePort
                );
@@ -161,7 +161,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
        tTCPListener    *srv;
        tTCPConnection  *conn;
 
-       Log_Log("TCP", "TCP_GetPacket: <Local>:%i from [%s]:%i, Flags= %s%s%s%s%s%s%s%s",
+       Log_Log("TCP", "TCP_GetPacket: <Local>:%i from [%s]:%i, Flags = %s%s%s%s%s%s%s%s",
                ntohs(hdr->DestPort),
                IPStack_PrintAddress(Interface->Type, Address),
                ntohs(hdr->SourcePort),
@@ -177,7 +177,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
 
        if( Length > (hdr->DataOffset >> 4)*4 )
        {
-               Log_Log("TCP", "TCP_GetPacket: SequenceNumber = 0x%x", ntohl(hdr->SequenceNumber));
+               LOG("SequenceNumber = 0x%x", ntohl(hdr->SequenceNumber));
 #if HEXDUMP_INCOMING
                Debug_HexDump(
                        "TCP_GetPacket: Packet Data = ",
@@ -337,12 +337,12 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
        // Ackowledge a sent packet
        if(Header->Flags & TCP_FLAG_ACK) {
                // TODO: Process an ACKed Packet
-               Log_Log("TCP", "Conn %p, Sent packet 0x%x ACKed", Connection, Header->AcknowlegementNumber);
+               LOG("Conn %p, Sent packet 0x%x ACKed", Connection, Header->AcknowlegementNumber);
        }
        
        // Get length of data
        dataLen = Length - (Header->DataOffset>>4)*4;
-       Log_Log("TCP", "HandleConnectionPacket - dataLen = %i", dataLen);
+       LOG("dataLen = %i", dataLen);
        
        // 
        // State Machine
@@ -432,7 +432,7 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
                
                sequence_num = ntohl(Header->SequenceNumber);
                
-               Log_Log("TCP", "0x%08x <= 0x%08x < 0x%08x",
+               LOG("TCP", "0x%08x <= 0x%08x < 0x%08x",
                        Connection->NextSequenceRcv,
                        ntohl(Header->SequenceNumber),
                        Connection->NextSequenceRcv + TCP_WINDOW_SIZE
@@ -450,7 +450,7 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
                        if(rv != 0) {
                                break;
                        }
-                       Log_Log("TCP", "0x%08x += %i", Connection->NextSequenceRcv, dataLen);
+                       LOG("0x%08x += %i", Connection->NextSequenceRcv, dataLen);
                        Connection->NextSequenceRcv += dataLen;
                        
                        // TODO: This should be moved out of the watcher thread,
@@ -460,6 +460,7 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
                        TCP_INT_UpdateRecievedFromFuture(Connection);
                
                        // ACK Packet
+                       // TODO: Implement delayed ACK sending
                        Header->DestPort = Header->SourcePort;
                        Header->SourcePort = htons(Connection->LocalPort);
                        Header->AcknowlegementNumber = htonl(Connection->NextSequenceRcv);
@@ -467,7 +468,7 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
                        Header->WindowSize = htons(TCP_WINDOW_SIZE);
                        Header->Flags &= TCP_FLAG_SYN;  // Eliminate all flags save for SYN
                        Header->Flags |= TCP_FLAG_ACK;  // Add ACK
-                       Log_Log("TCP", "Sending ACK for 0x%08x", Connection->NextSequenceRcv);
+                       LOG("TCP", "Sending ACK for 0x%08x", Connection->NextSequenceRcv);
                        TCP_SendPacket( Connection, Header, 0, NULL );
                        //Connection->NextSequenceSend ++;
                }
index 01f5f1f..c8ea019 100644 (file)
@@ -1,16 +1,16 @@
-/* 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
@@ -76,18 +76,15 @@ typedef struct sNe2k_Card {
        
         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);
@@ -95,26 +92,13 @@ void        Ne2k_IRQHandler(int IntNum, void *Ptr);
 
 // === 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;
 
@@ -136,8 +120,9 @@ int Ne2k_Install(char **Options)
        {
                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;
@@ -146,24 +131,35 @@ int Ne2k_Install(char **Options)
        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
@@ -180,12 +176,12 @@ int Ne2k_Install(char **Options)
                        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
@@ -198,111 +194,49 @@ int Ne2k_Install(char **Options)
                        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
@@ -312,23 +246,31 @@ size_t Ne2k_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buff
        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
@@ -343,31 +285,39 @@ size_t Ne2k_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buff
        // 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
@@ -384,52 +334,60 @@ size_t Ne2k_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
        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)
@@ -440,8 +398,8 @@ size_t Ne2k_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
        // 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)
index 8492fe8..84f141f 100644 (file)
@@ -6,10 +6,9 @@
 #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
@@ -38,7 +37,7 @@ enum eRTL8139_Regs
        // Early RX Status Register
        ERSR = 0x36,
        
-       // ??, ??, ??, RST, RE, TE, ??, ??
+       // -, -, -, RST, RE, TE, -, BUFE
        CMD     = 0x37,
        
        CAPR    = 0x38, // Current address of packet read
@@ -92,42 +91,26 @@ typedef struct sCard
        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;
 
@@ -220,14 +203,9 @@ int RTL8139_Install(char **Options)
                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],
@@ -235,53 +213,24 @@ int RTL8139_Install(char **Options)
                        );
        }
        
-       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 );
@@ -293,6 +242,37 @@ retry:
        
        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
@@ -302,38 +282,24 @@ retry:
        }
        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
 
@@ -351,40 +317,20 @@ size_t RTL8139_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *B
        // 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;
 }
 
@@ -394,11 +340,10 @@ void RTL8139_IRQHandler(int Num, void *Ptr)
        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
@@ -476,8 +421,8 @@ void RTL8139_IRQHandler(int Num, void *Ptr)
                {
                        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);
index d351a4d..d8bbf88 100644 (file)
@@ -6,72 +6,65 @@
 #define VERSION        ((0<<8)|10)
 #include <acess.h>
 #include <modules.h>
-#include <fs_devfs.h>
 #include <drv_pci.h>
-#include <api_drv_network.h>
 #include <semaphore.h>
+#include "rhine2_hw.h"
+#include <IPStack/include/adapters_api.h>
 
 // === CONSTANTS ===
 #define VENDOR_ID      0x1106
 #define DEVICE_ID      0x3065
 
-enum eRegs
-{
-       REG_PAR0, REG_PAR1,
-       REG_PAR2, REG_PAR3,
-       REG_PAR4, REG_PAR5,
-       REG_RCR,  REG_TCR,
-       REG_CR0,  REG_CR1,
-       REG_rsv0, REG_rsv1,
-       REG_ISR0, REG_ISR1,
-       REG_IMR0, REG_IMR1,
-};
-
 // === TYPES ===
 typedef struct sCard
 {
        Uint16  IOBase;
        Uint8   IRQ;
        
-        int    NumWaitingPackets;
+       tSemaphore      ReadSemaphore;
+
+       Uint32  RXBuffersPhys;
+       void    *RXBuffers;
+
+       Uint32  DescTablePhys;
+       void    *DescTable;
        
-       char    Name[2];
-       tVFS_Node       Node;
+       struct sTXDesc  *FirstTX;
+       struct sTXDesc  *LastTX;        // Most recent unsent packet
+       
+       struct sRXDesc  *FirstRX;       // Most recent unread packet
+       struct sRXDesc  *LastRX;        // End of RX descriptor queue
+
+       void    *IPHandle;      
        Uint8   MacAddr[6];
 }      tCard;
 
 // === PROTOTYPES ===
  int   Rhine2_Install(char **Options);
-char   *Rhine2_ReadDir(tVFS_Node *Node, int Pos);
-tVFS_Node      *Rhine2_FindDir(tVFS_Node *Node, const char *Filename);
- int   Rhine2_RootIOCtl(tVFS_Node *Node, int ID, void *Arg);
-Uint64 Rhine2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
-Uint64 Rhine2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
- int   Rhine2_IOCtl(tVFS_Node *Node, int ID, void *Arg);
+tIPStackBuffer *Rhine2_WaitPacket(void *Ptr);
+ int   Rhine2_SendPacket(void *Ptr, tIPStackBuffer *Buffer);
 void   Rhine2_IRQHandler(int Num);
+// --- Helpers ---
+struct sRXDesc *Rhine2_int_GetDescFromPhys(tCard *Card, Uint32 Addr);
+void   *Rhine2_int_GetBufferFromPhys(tCard *Card, Uint32 Addr);
+void   Rhine2_int_FreeRXDesc(void *Desc, size_t, size_t, const void*);
+struct sTXDesc *Rhine2_int_AllocTXDesc(tCard *Card);
+// --- IO ---
+void   _WriteDWord(tCard *Card, int Offset, Uint32 Value);
 
 // === GLOBALS ===
 MODULE_DEFINE(0, VERSION, VIARhineII, Rhine2_Install, NULL, NULL);
-tVFS_NodeType  gRhine2_DirType = {
-       .ReadDir = Rhine2_ReadDir,
-       .FindDir = Rhine2_FindDir,
-       .IOCtl = Rhine2_RootIOCtl
-       };
-tDevFS_Driver  gRhine2_DriverInfo = {
-       NULL, "Rhine2",
-       {
-       .NumACLs = 1,
-       .ACLs = &gVFS_ACL_EveryoneRX,
-       .Flags = VFS_FFLAG_DIRECTORY,
-       .Type = &gRhine2_DirType
-       }
+tIPStack_AdapterType   gRhine2_AdapterType = {
+       .Name = "VIA Rhine II",
+       .SendPacket = Rhine2_SendPacket,
+       .WaitForPacket = Rhine2_WaitPacket,
 };
  int   giRhine2_CardCount;
 tCard  *gaRhine2_Cards;
 
 // === CODE ===
 /**
- * \brief Installs the PCnet3 Driver
+ * \brief Initialises the driver
  */
 int Rhine2_Install(char **Options)
 {
@@ -81,7 +74,7 @@ int Rhine2_Install(char **Options)
        tCard   *card;
        
        giRhine2_CardCount = PCI_CountDevices(VENDOR_ID, DEVICE_ID);
-       Log_Debug("PCnet3", "%i cards", giRhine2_CardCount);
+       Log_Debug("Rhine2", "%i cards", giRhine2_CardCount);
        
        if( giRhine2_CardCount == 0 )   return MODULE_ERR_NOTNEEDED;
        
@@ -99,7 +92,7 @@ int Rhine2_Install(char **Options)
                LOG("BAR5 = 0x%08x", PCI_GetBAR(id, 5));
                
 //             card->IOBase = base;
-//             card->IRQ = PCI_GetIRQ( id );
+               card->IRQ = PCI_GetIRQ( id );
                
                // Install IRQ Handler
 //             IRQ_AddHandler(card->IRQ, Rhine2_IRQHandler);
@@ -115,253 +108,137 @@ int Rhine2_Install(char **Options)
                i ++;
        }
        
-       gRhine2_DriverInfo.RootNode.Size = giRhine2_CardCount;
-       DevFS_AddDevice( &gRhine2_DriverInfo );
-       
        return MODULE_ERR_OK;
 }
 
-// --- Root Functions ---
-char *Rhine2_ReadDir(tVFS_Node *Node, int Pos)
+// --- File Functions ---
+tIPStackBuffer *Rhine2_WaitPacket(void *Ptr)
 {
-       if( Pos < 0 || Pos >= giRhine2_CardCount )      return NULL;
+       tCard   *card = Ptr;
+       tIPStackBuffer  *ret;
+       struct sRXDesc  *desc;
+        int    nDesc;
        
-       return strdup( gaRhine2_Cards[Pos].Name );
-}
-
-tVFS_Node *Rhine2_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 &gaRhine2_Cards[ Filename[0]-'0' ].Node;
-}
+       ENTER("pPtr", Ptr);
 
-const char *csaRhine2_RootIOCtls[] = {DRV_IOCTLNAMES, NULL};
-int Rhine2_RootIOCtl(tVFS_Node *Node, int ID, void *Data)
-{
-       ENTER("pNode iID pData", Node, ID, Data);
-       switch(ID)
+       if( Semaphore_Wait( &card->ReadSemaphore, 1 ) != 1 )
        {
-       BASE_IOCTLS(DRV_TYPE_NETWORK, "PCnet3", VERSION, csaRhine2_RootIOCtls);
+               LEAVE('n');
+               return NULL;
        }
-       LEAVE('i', 0);
-       return 0;
+       
+       nDesc = 0;
+       desc = card->FirstRX;
+       while( desc->BufferSize & (1 << 15) )
+       {
+               desc = Rhine2_int_GetDescFromPhys(card, desc->RDBranchAddress);
+               nDesc ++;
+       }
+
+       LOG("%i descriptors in packet", nDesc);
+
+       ret = IPStack_Buffer_CreateBuffer(nDesc);
+       desc = card->FirstRX;
+       while( desc->BufferSize & (1 << 15) )
+       {
+               void    *data = Rhine2_int_GetBufferFromPhys(card, desc->RXBufferStart);
+               IPStack_Buffer_AppendSubBuffer(ret,
+                       desc->Length, 0, data,
+                       Rhine2_int_FreeRXDesc, desc
+                       );
+               desc = Rhine2_int_GetDescFromPhys(card, desc->RDBranchAddress);
+       }       
+       card->FirstRX = desc;
+
+       LEAVE('p', ret);
+       return ret;
 }
 
-// --- File Functions ---
-Uint64 Rhine2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+int Rhine2_SendPacket(void *Ptr, tIPStackBuffer *Buffer)
 {
-       #if 0
-       tCard   *card = Node->ImplPtr;
-       Uint16  read_ofs, pkt_length;
-        int    new_read_ofs;
+       tCard   *card = Ptr;
+       size_t  len;
+       const void      *data;
+       struct sTXDesc  *first_desc = NULL;
+       struct sTXDesc  *last_desc = NULL;
 
-       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
+       ENTER("pPtr pBuffer", Ptr, Buffer);     
 
-retry:
-       if( Semaphore_Wait( &card->ReadSemaphore, 1 ) != 1 )
+       // Iterate buffers
+       for( int id = -1; -1 != (id = IPStack_Buffer_GetBuffer(Buffer, id, &len, &data)); )
        {
-               LEAVE_RET('i', 0);
+               tPAddr  pdata = MM_GetPhysAddr( (tVAddr)data );
+               struct sTXDesc  *desc;
+               #if PHYS_BITS > 32
+               if( pdata >> 32 ) {
+                       // TODO: re-map
+               } 
+               #endif
+               
+               desc = Rhine2_int_AllocTXDesc(card);
+               if(!last_desc)
+                       first_desc = desc;
+               else
+                       last_desc->TDBranchAddress = MM_GetPhysAddr( (tVAddr)desc );
+
+               desc->TXBufferStart = pdata;
+               desc->BufferSize = len;
+               // TODO: TCR
+               desc->TCR = 0;
+               desc->TDBranchAddress = 0;
+
+               last_desc = desc;
        }
        
-       Mutex_Acquire( &card->ReadMutex );
-       
-       read_ofs = inw( card->IOBase + CAPR );
-       LOG("raw read_ofs = %i", read_ofs);
-       read_ofs = (read_ofs + 0x10) & 0xFFFF;
-       LOG("read_ofs = %i", read_ofs);
-       
-       pkt_length = *(Uint16*)&card->ReceiveBuffer[read_ofs+2];
-       
-       // Calculate new read offset
-       new_read_ofs = read_ofs + pkt_length + 4;
-       new_read_ofs = (new_read_ofs + 3) & ~3; // Align
-       if(new_read_ofs > card->ReceiveBufferLength) {
-               LOG("wrapping read_ofs");
-               new_read_ofs -= card->ReceiveBufferLength;
+       if( !first_desc ) {
+               LEAVE('i', -1);
+               return -1;
        }
-       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
+
+       first_desc->TCR |= TD_TCR_STP;
+       last_desc->TCR |= TD_TCR_EDP;
+
+       if( card->LastTX )
+               card->LastTX->TDBranchAddress = MM_GetPhysAddr( (tVAddr)first_desc );
+       else {
+               card->FirstTX = first_desc;
+               card->LastTX = first_desc;
+               _WriteDWord(card, REG_CUR_TX_DESC, MM_GetPhysAddr( (tVAddr)first_desc ));
        }
        
-       // 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);
-       #endif
-       
-       return Length;
+       // TODO: Wait until the packet has sent, then clean up
+
+       return 0;
 }
 
-Uint64 Rhine2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+void Rhine2_IRQHandler(int Num)
 {
-       #if 0
-        int    td;
-       Uint32  status;
-       tCard   *card = Node->ImplPtr;
-       
-       if( Length > 1500 )     return 0;       // MTU exceeded
        
-       ENTER("pNode XLength pBuffer", Node, Length, Buffer);
-       
-       // TODO: Implement a semaphore for avaliable transmit buffers
+}
 
-       // Find an avaliable descriptor
-       Mutex_Acquire(&card->CurTXProtector);
-       td = card->CurTXDescriptor;
-       card->CurTXDescriptor ++;
-       card->CurTXDescriptor %= 4;
-       Mutex_Release(&card->CurTXProtector);
-       // - Lock it
-       Mutex_Acquire( &card->TransmitInUse[td] );
-       
-       LOG("td = %i", td);
-       
-       // 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);
-       // Start
-       status = 0;
-       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);
-       #endif
-       
-       return Length;
+// --- Helpers ---
+struct sRXDesc *Rhine2_int_GetDescFromPhys(tCard *Card, Uint32 Addr)
+{
+       return NULL;
 }
 
-const char *csaRhine2_NodeIOCtls[] = {DRV_IOCTLNAMES, NULL};
-int Rhine2_IOCtl(tVFS_Node *Node, int ID, void *Data)
+void *Rhine2_int_GetBufferFromPhys(tCard *Card, Uint32 Addr)
 {
-       tCard   *card = Node->ImplPtr;
-       ENTER("pNode iID pData", Node, ID, Data);
-       switch(ID)
-       {
-       BASE_IOCTLS(DRV_TYPE_NETWORK, "PCnet3", VERSION, csaRhine2_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);
-       return 0;
+       return NULL;
 }
 
-void Rhine2_IRQHandler(int Num)
+void Rhine2_int_FreeRXDesc(void *Desc, size_t u1, size_t u2, const void *u3)
 {
-       #if 0
-        int    i, j;
-       tCard   *card;
-       Uint16  status;
+       
+}
+
+struct sTXDesc *Rhine2_int_AllocTXDesc(tCard *Card)
+{
+       return NULL;
+}
 
-       LOG("Num = %i", Num);
+// --- IO ---
+void _WriteDWord(tCard *Card, int Offset, Uint32 Value)
+{
        
-       for( i = 0; i < giRhine2_CardCount; i ++ )
-       {
-               card = &gaRhine2_Cards[i];
-               if( Num != card->IRQ )  break;
-               
-               status = inw(card->IOBase + ISR);
-               LOG("status = 0x%02x", status);
-               
-               // Transmit OK, a transmit descriptor is now free
-               if( status & FLAG_ISR_TOK )
-               {
-                       for( j = 0; j < 4; j ++ )
-                       {
-                               if( ind(card->IOBase + TSD0 + j*4) & 0x8000 ) { // TSD TOK
-                                       Mutex_Release( &card->TransmitInUse[j] );
-                                       // TODO: Update semaphore once implemented
-                               }
-                       }
-                       outw(card->IOBase + ISR, FLAG_ISR_TOK);
-               }
-               
-               // Recieve OK, inform read
-               if( status & FLAG_ISR_ROK )
-               {
-                        int    read_ofs, end_ofs;
-                        int    packet_count = 0;
-                        int    len;
-                       
-                       // Scan recieve buffer for packets
-                       end_ofs = inw(card->IOBase + CBA);
-                       read_ofs = card->SeenOfs;
-                       LOG("read_ofs = %i, end_ofs = %i", read_ofs, end_ofs);
-                       if( read_ofs > end_ofs )
-                       {
-                               while( read_ofs < card->ReceiveBufferLength )
-                               {
-                                       packet_count ++;
-                                       len = *(Uint16*)&card->ReceiveBuffer[read_ofs+2];
-                                       LOG("%i 0x%x Pkt Hdr: 0x%04x, len: 0x%04x",
-                                               packet_count, read_ofs,
-                                               *(Uint16*)&card->ReceiveBuffer[read_ofs],
-                                               len
-                                               );
-                                       if(len > 2000) {
-                                               Log_Warning("PCnet3", "IRQ: Packet in buffer exceeds sanity (%i>2000)", len);
-                                       }
-                                       read_ofs += len + 4;
-                                       read_ofs = (read_ofs + 3) & ~3; // Align
-                               }
-                               read_ofs -= card->ReceiveBufferLength;
-                               LOG("wrapped read_ofs");
-                       }
-                       while( read_ofs < end_ofs )
-                       {
-                               packet_count ++;
-                               LOG("%i 0x%x Pkt Hdr: 0x%04x, len: 0x%04x",
-                                       packet_count, read_ofs,
-                                       *(Uint16*)&card->ReceiveBuffer[read_ofs],
-                                       *(Uint16*)&card->ReceiveBuffer[read_ofs+2]
-                                       );
-                               read_ofs += *(Uint16*)&card->ReceiveBuffer[read_ofs+2] + 4;
-                               read_ofs = (read_ofs + 3) & ~3; // Align
-                       }
-                       if( read_ofs != end_ofs ) {
-                               Log_Warning("PCnet3", "IRQ: read_ofs (%i) != end_ofs(%i)", read_ofs, end_ofs);
-                               read_ofs = end_ofs;
-                       }
-                       card->SeenOfs = read_ofs;
-                       
-                       LOG("packet_count = %i, read_ofs = 0x%x", packet_count, read_ofs);
-                       
-                       if( packet_count )
-                       {
-                               if( Semaphore_Signal( &card->ReadSemaphore, packet_count ) != packet_count ) {
-                                       // Oops?
-                               }
-                               VFS_MarkAvaliable( &card->Node, 1 );
-                       }
-                       
-                       outw(card->IOBase + ISR, FLAG_ISR_ROK);
-               }
-       }
-       #endif
 }
diff --git a/KernelLand/Modules/Network/VIARhineII/rhine2_hw.h b/KernelLand/Modules/Network/VIARhineII/rhine2_hw.h
new file mode 100644 (file)
index 0000000..afe9cc9
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Acess2 VIA Rhine II Driver (VT6102)
+ * - By John Hodge (thePowersGang)
+ */
+#ifndef _VIARHINEII__RHINE2_HW_H_
+#define _VIARHINEII__RHINE2_HW_H_
+
+enum eRegs
+{
+       REG_PAR0, REG_PAR1,
+       REG_PAR2, REG_PAR3,
+       REG_PAR4, REG_PAR5,
+       REG_RCR,  REG_TCR,
+       REG_CR0,  REG_CR1,
+       REG_rsv0, REG_rsv1,
+       REG_ISR0, REG_ISR1,
+       REG_IMR0, REG_IMR1,
+       
+       REG_MAR0, REG_MAR1,
+       REG_MAR2, REG_MAR3,
+       REG_MAR4, REG_MAR5,
+       REG_MAR6, REG_MAR7,
+       
+       REG_CUR_RX_DESC,
+       REG_CUR_TX_DESC = 0x1C,
+
+       REG_GFTEST = 0x54, REG_RFTCMD,
+       REG_TFTCMD, REG_GFSTATUS,
+       REG_BNRY, _REG_BNRY_HI,
+       REG_CURR, _REG_CURR,
+       
+       //TODO: More?
+};
+
+#define RCR_SEP        (1 << 0)        // Accept error packets
+#define RCR_AR         (1 << 1)        // Accept small packets (< 64 bytes)
+#define RCR_AM         (1 << 2)        // Accept multicast packets
+#define RCR_AB         (1 << 3)        // Accept broadcast packets
+#define RCR_PROM       (1 << 4)        // Accept any addressed packet
+#define RCR_RRFT(v)    (((v)&7)<<5)    // Recieve FIFO threshold (64,32,128,256,512,768,1024,s&f)
+
+#define TCR_RSVD0      (1 << 0)        // reserved
+#define TCR_LB(v)      (((v)&3)<<1)    // Loopback mode (normal, internal, MII, 223/other)
+#define TCR_OFSET      (1 << 3)        // Backoff algo (VIA, Standard)
+#define TCR_RSVD1      (1 << 4)        // reserved
+#define TCR_TRSF(v)    (((v)&7)<<5)    // Transmit FIFO threshold
+
+// TODO: Other Regs?
+
+struct sRXDesc
+{
+       Uint16  RSR;
+       Uint16  Length; // 11 bits, Bit 15 is owner bit
+       Uint16  BufferSize;     // 11 bits, Bit 15 is chain bit (means the packet continues in the next desc)
+       Uint16  _resvd;
+       Uint32  RXBufferStart;
+       Uint32  RDBranchAddress;        // ? - I'm guessing it's the next descriptor in the chain
+};
+
+#define RSR_RERR       (1 << 0)        // Receiver error
+#define RSR_CRC        (1 << 1)        // CRC Error
+#define RSR_FAE        (1 << 2)        // Frame Alignment error
+#define RSR_FOV        (1 << 3)        // FIFO Overflow
+#define RSR_LONG       (1 << 4)        // Long packet
+#define RSR_RUNT       (1 << 5)        // Runt packet
+#define RSR_SERR       (1 << 6)        // System Error
+#define RSR_BUFF       (1 << 7)        // Buffer underflow
+#define RSR_EDP        (1 << 8)        // End of Packet
+#define RSR_STP        (1 << 9)        // Start of Packet
+#define RSR_CHN        (1 << 10)       // Chain buffer
+#define RSR_PHY        (1 << 11)       // Physical address match
+#define RSR_BAR        (1 << 12)       // Broadcast packet
+#define RSR_MAR        (1 << 13)       // Multicast packet
+#define RSR_RESVD      (1 << 14)       // reserved
+#define RSR_RXOK       (1 << 15)       // Recieved OK
+
+struct sTXDesc
+{
+       Uint32  TSR;
+       Uint16  BufferSize;     // 11 bits, bit 15 is chain
+       Uint8   TCR;
+       Uint8   _resvd;
+       Uint32  TXBufferStart;
+       Uint32  TDBranchAddress;        // Bit 0: Disable interrupt
+};
+
+#define TD_TCR_CRC     (1 << 0)        // Disable CRC generation
+#define TD_TCR_STP     (1 << 5)        // First descriptor in packet
+#define TD_TCR_EDP     (1 << 6)        // Last descriptor in packet
+#define TD_TCR_IC      (1 << 7)        // Interrupt when transmitted
+
+#endif
+
index 3207669..7b1b724 100644 (file)
@@ -6,7 +6,6 @@
  * - USB Device Initialisation
  */
 #define DEBUG  1
-
 #include <acess.h>
 #include <vfs.h>
 #include <drv_pci.h>
@@ -14,6 +13,8 @@
 #include "usb_proto.h"
 #include "usb_lowlevel.h"
 
+#define DUMP_DESCRIPTORS       0
+
 // === PROTOTYPES ===
 void   USB_DeviceConnected(tUSBHub *Hub, int Port);
 void   USB_DeviceDisconnected(tUSBHub *Hub, int Port);
@@ -55,7 +56,8 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                LOG("Getting device descriptor");
                // Endpoint 0, Desc Type 1, Index 0
                USB_int_ReadDescriptor(dev, 0, 1, 0, sizeof(desc), &desc);
-               
+
+               #if DUMP_DESCRIPTORS            
                LOG("Device Descriptor = {");
                LOG(" .Length = %i", desc.Length);
                LOG(" .Type = %i", desc.Type);
@@ -99,6 +101,7 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                        }
                }
                #endif
+               #endif
        }
 
        // TODO: Support alternate configurations
@@ -112,6 +115,7 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                size_t  total_length;
        
                USB_int_ReadDescriptor(dev, 0, 2, i, sizeof(desc), &desc);
+               #if DUMP_DESCRIPTORS
                LOG("Configuration Descriptor %i = {", i);
                LOG(" .Length = %i", desc.Length);
                LOG(" .Type = %i", desc.Type);
@@ -127,6 +131,7 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                        LOG("ConfigurationStr = '%s'", tmp);
                        free(tmp);
                }
+               #endif
 
                // TODO: Split here and allow some method of selection
 
@@ -167,20 +172,22 @@ void USB_DeviceConnected(tUSBHub *Hub, int Port)
                                continue ;
                        }
 
+                       #if DUMP_DESCRIPTORS
                        LOG("Interface %i/%i = {", i, j);
                        LOG(" .InterfaceNum = %i", iface->InterfaceNum);
                        LOG(" .NumEndpoints = %i", iface->NumEndpoints);
                        LOG(" .InterfaceClass = 0x%x", iface->InterfaceClass);
                        LOG(" .InterfaceSubClass = 0x%x", iface->InterfaceSubClass);
                        LOG(" .InterfaceProcol = 0x%x", iface->InterfaceProtocol);
-                       #if DEBUG       
+                       # if DEBUG      
                        if( iface->InterfaceStr ) {
                                char    *tmp = USB_int_GetDeviceString(dev, 0, iface->InterfaceStr);
                                LOG(" .InterfaceStr = %i '%s'", iface->InterfaceStr, tmp);
                                free(tmp);
                        }
-                       #endif
+                       # endif
                        LOG("}");
+                       #endif
 
                        dev_if = malloc(sizeof(tUSBInterface) + iface->NumEndpoints*sizeof(dev_if->Endpoints[0]));
                        dev_if->Dev = dev;
index faa0ab3..54d0e16 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ USRLIBS += libimage_sif.so
 
 USRAPPS := init login CLIShell cat ls mount
 USRAPPS += bomb dhcpclient
-USRAPPS += ifconfig ping telnet irc
+USRAPPS += ip ping telnet irc
 USRAPPS += axwin3
 
 ALL_DYNMODS = $(addprefix all-,$(DYNMODS))
index 643624a..149bd0a 100644 (file)
@@ -91,7 +91,7 @@ int main(int argc, char *argv[])
                ifaces->Adapter = argv[1];
        }
        else {
-               Scan_Dir( &ifaces, "/Devices" );
+               Scan_Dir( &ifaces, "/Devices/ip/adapters" );
        }
 
        for( i = ifaces; i; i = i->Next )
@@ -150,34 +150,14 @@ void Scan_Dir(tInterface **IfaceList, const char *Directory)
 
        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);
 }
@@ -253,11 +233,17 @@ void Send_DHCPDISCOVER(tInterface *Iface)
        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
@@ -356,7 +342,10 @@ int Handle_Packet(tInterface *Iface)
                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?
diff --git a/Usermode/Applications/ifconfig_src/Makefile b/Usermode/Applications/ifconfig_src/Makefile
deleted file mode 100644 (file)
index e914e2b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# Project: ifconfig
-
--include ../Makefile.cfg
-
-LDFLAGS += -lnet
-
-OBJ = main.o
-BIN = ifconfig
-
--include ../Makefile.tpl
-
diff --git a/Usermode/Applications/ifconfig_src/main.c b/Usermode/Applications/ifconfig_src/main.c
deleted file mode 100644 (file)
index 334ea13..0000000
+++ /dev/null
@@ -1,734 +0,0 @@
-/*
- * Acess2 IFCONFIG command
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <acess/sys.h>
-#include <net.h>
-
-// === CONSTANTS ===
-#define FILENAME_MAX   255
-#define IPSTACK_ROOT   "/Devices/ip"
-#define DEFAULT_METRIC 30
-
-// TODO: Move this to a header
-#define ntohs(v)       (((v&0xFF)<<8)|((v>>8)&0xFF))
-
-// === PROTOTYPES ===
-void   PrintUsage(const char *ProgName);
-void   DumpInterfaces(void);
-void   DumpRoutes(void);
-void   DumpInterface(const char *Name);
-void   DumpRoute(const char *Name);
- int   AddInterface(const char *Device);
-void   AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, int Metric, void *NextHop);
- int   DoAutoConfig(const char *Device);
- int   SetAddress(int IFNum, const char *Address);
- int   ParseIPAddress(const char *Address, uint8_t *Dest, int *SubnetBits);
-
-// === CODE ===
-/**
- * \brief Program entrypoint
- */
-int main(int argc, char *argv[])
-{
-        int    ret;
-       
-       // No args, dump interfaces
-       if(argc == 1) {
-               DumpInterfaces();
-               return 0;
-       }
-       
-       // Routes
-       if( strcmp(argv[1], "route") == 0 )
-       {
-               // Add new route
-               if( argc > 2 && strcmp(argv[2], "add") == 0 )
-               {
-                       uint8_t dest[16] = {0};
-                       uint8_t nextHop[16] = {0};
-                        int    addrType, subnetBits = -1;
-                        int    nextHopType, nextHopBits=-1;
-                       char    *ifaceName = NULL;
-                        int    metric = DEFAULT_METRIC;
-                       // Usage:
-                       // ifconfig route add <host>[/<prefix>] <interface> [<metric>]
-                       // ifconfig route add <host>[/<prefix>] <next hop> [<metric>]
-                       if( argc - 3  < 2 ) {
-                               fprintf(stderr, "ERROR: '%s route add' takes at least two arguments, %i passed\n",
-                                       argv[0], argc-3);
-                               PrintUsage(argv[0]);
-                               return -1;
-                       }
-                       
-                       if( argc - 3 > 3 ) {
-                               fprintf(stderr, "ERROR: '%s route add' takes at most three arguments, %i passed\n",
-                                       argv[0], argc-3);
-                               PrintUsage(argv[0]);
-                               return -1;
-                       }
-                       
-                       // Destination IP
-                       addrType = ParseIPAddress(argv[3], dest, &subnetBits);
-                       if( subnetBits == -1 ) {
-                               subnetBits = Net_GetAddressSize(addrType)*8;
-                       }
-                       // Interface Name / Next Hop
-                       if( (nextHopType = ParseIPAddress(argv[4], nextHop, &nextHopBits)) == 0 )
-                       {
-                               // Interface name
-                               ifaceName = argv[4];
-                       }
-                       else
-                       {
-                               // Next Hop
-                               // - Check if it's the same type as the network/destination
-                               if( nextHopType != addrType ) {
-                                       fprintf(stderr, "ERROR: Address type mismatch\n");
-                                       return -1;
-                               }
-                               // - Make sure there's no mask
-                               if( nextHopBits != -1 ) {
-                                       fprintf(stderr, "Error: Next hop cannot be masked\n");
-                                       return -1;
-                               }
-                       }
-                       
-                       // Metric
-                       if( argc - 3 >= 3 )
-                       {
-                               metric = atoi(argv[5]);
-                               if( metric == 0 && argv[5][0] != '0' ) {
-                                       fprintf(stderr, "ERROR: Metric should be a number\n");
-                                       return -1;
-                               }
-                       }
-                       
-                       // Make the route!
-                       AddRoute(ifaceName, addrType, dest, subnetBits, metric, nextHop);
-                       
-                       return 0;
-               }
-               // Delete a route
-               else if( argc > 2 && strcmp(argv[2], "del") == 0 )
-               {
-                       // Usage:
-                       // ifconfig route del <routenum>
-                       // ifconfig route del <host>[/<prefix>]
-               }
-               else
-               {
-                       // List routes
-                       DumpRoutes();
-               }
-               return 0;
-       }
-       // Add a new interface
-       else if( strcmp(argv[1], "add") == 0 )
-       {
-               if( argc < 4 ) {
-                       fprintf(stderr, "ERROR: '%s add' requires two arguments, %i passed\n", argv[0], argc-2);
-                       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] );
-               return ret;
-       }
-       // Delete an interface
-       else if( strcmp(argv[1], "del") == 0 )
-       {
-               if( argc < 3 ) {
-                       fprintf(stderr, "ERROR: '%s del' requires an argument\n", argv[0]);
-                       PrintUsage(argv[0]);
-                       return -1;
-               }
-               // TODO:
-       }
-       // Autoconfigure an interface
-       // NOTE: Debugging hack (see the function for more details)
-       else if( strcmp(argv[1], "autoconf") == 0 )
-       {
-               DoAutoConfig(argv[2]);
-               return 0;
-       }
-       else if( strcmp(argv[1], "help") == 0 || strcmp(argv[1], "--help") == 0 )
-       {
-               PrintUsage(argv[0]);
-               return 0;
-       }
-       
-       // Dump a named interface
-       DumpInterface(argv[1]);
-       
-       return 0;
-}
-
-/**
- * \brief Print usage instructions
- */
-void PrintUsage(const char *ProgName)
-{
-       fprintf(stderr, "Usage:\n");
-       fprintf(stderr, "    %s add <device> <ip>/<prefix>\n", ProgName);
-       fprintf(stderr, "        Add a new interface listening on <device> with the specified\n");
-       fprintf(stderr, "        address.\n");
-       fprintf(stderr, "    %s del <interface>\n", ProgName);
-       fprintf(stderr, "        Delete an interface\n");
-       fprintf(stderr, "    %s [<interface>]\n", ProgName);
-       fprintf(stderr, "        Print the current interfaces (or only <interface> if passed)\n");
-       fprintf(stderr, "\n");
-       fprintf(stderr, "    %s route\n", ProgName);
-       fprintf(stderr, "        Print the routing tables\n");
-       fprintf(stderr, "    %s route add <host>[/<prefix>] [<nexthop> OR <iface>] [<metric>]\n", ProgName);
-       fprintf(stderr, "        Add a new route\n");
-       fprintf(stderr, "    %s route del <host>[/<prefix>]\n", ProgName);
-       fprintf(stderr, "    %s route del <routenum>\n", ProgName);
-       fprintf(stderr, "        Add a new route\n");
-       fprintf(stderr, "\n");
-       fprintf(stderr, "A note on Acess's IP Stack:\n");
-       fprintf(stderr, "    Each interface corresponds to only one IP address (either IPv4\n");
-       fprintf(stderr, "    or IPv6). A network device can have multiple interfaces bound\n");
-       fprintf(stderr, "    to it, allowing multiple addresses for one network connection\n");
-       fprintf(stderr, "\n");
-}
-
-/**
- * \brief Dump all interfaces
- */
-void DumpInterfaces(void)
-{
-        int    dp;
-       char    filename[FILENAME_MAX+1];
-       
-       dp = open(IPSTACK_ROOT, OPENFLAG_READ);
-       
-       while( readdir(dp, filename) )
-       {
-               if(filename[0] == '.')  continue;
-               DumpInterface(filename);
-       }
-       
-       close(dp);
-}
-
-/**
- * \brief Dump all interfaces
- */
-void DumpRoutes(void)
-{
-        int    dp;
-       char    filename[FILENAME_MAX+1];
-       
-       dp = open(IPSTACK_ROOT"/routes", OPENFLAG_READ);
-       
-       printf("Type\tNetwork \tGateway \tMetric\tIFace\n");
-       
-       while( readdir(dp, filename) )
-       {
-               if(filename[0] == '.')  continue;
-               DumpRoute(filename);
-       }
-       
-       close(dp);
-}
-
-/**
- * \brief Dump an interface
- */
-void DumpInterface(const char *Name)
-{
-        int    fd;
-        int    type;
-       char    path[sizeof(IPSTACK_ROOT)+1+FILENAME_MAX+1] = IPSTACK_ROOT"/";
-       
-       strcat(path, Name);
-       
-       fd = open(path, OPENFLAG_READ);
-       if(fd == -1) {
-               fprintf(stderr, "Bad interface name '%s' (%s does not exist)\t", Name, path);
-               return ;
-       }
-       
-       type = ioctl(fd, 4, NULL);
-       
-       // Ignore -1 values
-       if( type == -1 ) {
-               return ;
-       }
-       
-       printf("%s:\t", Name);
-       {
-                int    call_num = ioctl(fd, 3, "get_device");
-                int    len = ioctl(fd, call_num, NULL);
-               char    *buf = malloc(len+1);
-               ioctl(fd, call_num, buf);
-               printf("'%s'\n", buf);
-               free(buf);
-       }
-       printf("\t");
-       // Get the address type
-       switch(type)
-       {
-       case 0: // Disabled/Unset
-               printf("DISABLED\n");
-               break;
-       case 4: // IPv4
-               {
-               uint8_t ip[4];
-                int    subnet;
-               printf("IPv4\t");
-               ioctl(fd, 5, ip);       // Get IP Address
-               subnet = ioctl(fd, 7, NULL);    // Get Subnet Bits
-               printf("%i.%i.%i.%i/%i\n", ip[0], ip[1], ip[2], ip[3], subnet);
-               }
-               break;
-       case 6: // IPv6
-               {
-               uint16_t        ip[8];
-                int    subnet;
-               printf("IPv6\t");
-               ioctl(fd, 5, ip);       // Get IP Address
-               subnet = ioctl(fd, 7, NULL);    // Get Subnet Bits
-               printf("%x:%x:%x:%x:%x:%x:%x:%x/%i\n",
-                       ntohs(ip[0]), ntohs(ip[1]), ntohs(ip[2]), ntohs(ip[3]),
-                       ntohs(ip[4]), ntohs(ip[5]), ntohs(ip[6]), ntohs(ip[7]),
-                       subnet);
-               }
-               break;
-       default:        // Unknow
-               printf("UNKNOWN (%i)\n", type);
-               break;
-       }
-                       
-       close(fd);
-}
-
-
-/**
- * \brief Dump a route
- */
-void DumpRoute(const char *Name)
-{
-        int    fd;
-        int    type;
-       char    path[sizeof(IPSTACK_ROOT)+8+FILENAME_MAX+1] = IPSTACK_ROOT"/routes/";
-       
-       strcat(path, Name);
-       
-       fd = open(path, OPENFLAG_READ);
-       if(fd == -1) {
-               printf("%s:\tUnable to open ('%s')\n", Name, path);
-               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);
-       }
-       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)
-       {
-       case 0: // Disabled/Unset
-               printf("DISABLED\n");
-               break;
-       case 4: // IPv4
-               printf("IPv4\t");
-               break;
-       case 6: // IPv6
-               printf("IPv6\t");
-               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    call_num = ioctl(fd, 3, "get_interface");
-                int    len = ioctl(fd, call_num, NULL);
-               char    *buf = malloc(len+1);
-               ioctl(fd, call_num, buf);
-               printf("'%s'\t", buf);
-               free(buf);
-       }
-       
-       printf("\n");
-                       
-       close(fd);
-}
-
-/**
- * \brief Create a new interface using the passed device
- * \param Device       Network device to bind to
- */
-int AddInterface(const char *Device)
-{
-        int    dp, ret;
-       
-       dp = open(IPSTACK_ROOT, OPENFLAG_READ);
-       ret = ioctl(dp, 4, (void*)Device);
-       close(dp);
-       
-       if( ret < 0 ) {
-               fprintf(stderr, "Unable to add '%s' as a network interface\n", Device);
-               return -1;
-       }
-       
-       printf("-- Added '"IPSTACK_ROOT"/%i' using device %s\n", ret, Device);
-       
-       return ret;
-}
-
-void AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, int Metric, void *NextHop)
-{
-        int    fd;
-        int    num;
-       char    *ifaceToFree = NULL;
-       
-       // Get interface name
-       if( !Interface )
-       {
-               if( !NextHop ) {
-                       fprintf(stderr,
-                               "BUG: AddRoute(Interface=NULL,...,NextHop=NULL)\n"
-                               "Only one should be NULL\n"
-                               );
-                       return ;
-               }
-               
-               // Query for the interface name
-               Interface = ifaceToFree = Net_GetInterface(AddressType, NextHop);
-       }
-       // Check address type (if the interface was passed)
-       // - If we got the interface name, then it should be correct
-       else
-       {
-               char    ifacePath[sizeof(IPSTACK_ROOT"/")+strlen(Interface)+1];
-               
-               // Open interface
-               strcpy(ifacePath, IPSTACK_ROOT"/");
-               strcat(ifacePath, Interface);
-               fd = open(ifacePath, 0);
-               if( fd == -1 ) {
-                       fprintf(stderr, "Error: Interface '%s' does not exist\n", Interface);
-                       return ;
-               }
-               // Get and check type
-               num = ioctl(fd, ioctl(fd, 3, "getset_type"), NULL);
-               if( num != AddressType ) {
-                       fprintf(stderr, "Error: Passed type does not match interface type (%i != %i)\n",
-                               AddressType, num);
-                       return ;
-               }
-               
-               close(fd);
-       }
-       
-       // Create route
-        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 ;
-       }
-       
-       if( NextHop )
-               ioctl(fd, ioctl(fd, 3, "set_nexthop"), NextHop);
-       ioctl(fd, ioctl(fd, 3, "set_interface"), (void*)Interface);
-       
-       close(fd);
-       
-       // Check if the interface name was allocated by us
-       if( ifaceToFree )
-               free(ifaceToFree);
-}
-
-/**
- * \note Debugging HACK!
- * \brief Autoconfigure the specified device to 10.0.2.55/24 using
- *        10.0.2.2 as the gateway.
- */
-int DoAutoConfig(const char *Device)
-{
-        int    tmp, fd;
-       char    path[sizeof(IPSTACK_ROOT)+1+4+1];       // /0000
-       uint8_t addr[4] = {10,0,2,55};
-       uint8_t gw[4] = {10,0,2,2};
-        int    subnet = 24;
-       
-       tmp = AddInterface(Device);
-       if( tmp < 0 )   return tmp;
-       
-       sprintf(path, IPSTACK_ROOT"/%i", tmp);
-       
-       fd = open(path, OPENFLAG_READ);
-       if( fd == -1 ) {
-               fprintf(stderr, "Unable to open '%s'\n", path);
-               return -1;
-       }
-       
-       tmp = 4;        // IPv4
-       tmp = ioctl(fd, ioctl(fd, 3, "getset_type"), &tmp);
-       if( tmp != 4 ) {
-               fprintf(stderr, "Error in setting address type (got %i, expected 4)\n", tmp);
-               return -1;
-       }
-       // Set Address
-       ioctl(fd, ioctl(fd, 3, "set_address"), addr);
-       // Set Subnet
-       ioctl(fd, ioctl(fd, 3, "getset_subnet"), &subnet);
-       
-       // Set routes
-       {
-               uint8_t net[4] = {0,0,0,0};
-               AddRoute(path + sizeof(IPSTACK_ROOT), 4, addr, subnet, DEFAULT_METRIC, net);    // This interface
-               AddRoute(path + sizeof(IPSTACK_ROOT), 4, net, 0, DEFAULT_METRIC, gw);   // Gateway
-       }
-       
-       close(fd);
-       
-       printf("Set address to %i.%i.%i.%i/%i (GW: %i.%i.%i.%i)\n",
-               addr[0], addr[1], addr[2], addr[3],
-               subnet,
-               gw[0], gw[1], gw[2], gw[3]);
-       
-       return 0;
-}
-
-/**
- * \brief Set the address on an interface from a textual IP address
- */
-int    SetAddress(int IFNum, const char *Address)
-{
-       uint8_t addr[16];
-        int    type;
-       char    path[sizeof(IPSTACK_ROOT)+1+5+1];       // ip000
-        int    tmp, fd, subnet;
-       
-       // Parse IP Address
-       type = ParseIPAddress(Address, addr, &subnet);
-       if(type == 0) {
-               fprintf(stderr, "'%s' cannot be parsed as an IP address\n", Address);
-               return -1;
-       }
-       
-       // Open file
-       sprintf(path, IPSTACK_ROOT"/%i", IFNum);
-       fd = open(path, OPENFLAG_READ);
-       if( fd == -1 ) {
-               fprintf(stderr, "Unable to open '%s'\n", path);
-               return -1;
-       }
-       
-       tmp = type;
-       tmp = ioctl(fd, ioctl(fd, 3, "getset_type"), &tmp);
-       if( tmp != type ) {
-               fprintf(stderr, "Error in setting address type (got %i, expected %i)\n", tmp, type);
-               close(fd);
-               return -1;
-       }
-       // Set Address
-       ioctl(fd, ioctl(fd, 3, "set_address"), addr);
-       
-       // Set Subnet
-       ioctl(fd, ioctl(fd, 3, "getset_subnet"), &subnet);
-       
-       close(fd);
-       
-       // Dump!
-       //DumpInterface( path+sizeof(IPSTACK_ROOT)+1 );
-       
-       return 0;
-}
-
-/**
- * \brief Parse an IP Address
- * \return 0 for unknown, 4 for IPv4 and 6 for IPv6
- */
-int ParseIPAddress(const char *Address, uint8_t *Dest, int *SubnetBits)
-{
-       const char      *p = Address;
-       
-       // Check first block
-       while(*p && *p >= '0' && *p <= '9')     p ++;
-       
-       // IPv4?
-       if(*p == '.')
-       {
-                int    i = 0, j;
-                int    val;
-               
-               for( j = 0; Address[i] && j < 4; j ++ )
-               {
-                       val = 0;
-                       for( ; '0' <= Address[i] && Address[i] <= '9'; i++ )
-                       {
-                               val = val*10 + Address[i] - '0';
-                       }
-                       if(val > 255) {
-                               //printf("val > 255 (%i)\n", val);
-                               return 0;
-                       }
-                       Dest[j] = val;
-                       
-                       if(Address[i] == '.')
-                               i ++;
-               }
-               if( j != 4 ) {
-                       //printf("4 parts expected, %i found\n", j);
-                       return 0;
-               }
-               // Parse subnet size
-               if(Address[i] == '/') {
-                       val = 0;
-                       i ++;
-                       while('0' <= Address[i] && Address[i] <= '9') {
-                               val *= 10;
-                               val += Address[i] - '0';
-                               i ++;
-                       }
-                       if(val > 32) {
-                               printf("Notice: Subnet size >32 (%i)\n", val);
-                       }
-                       if(SubnetBits)  *SubnetBits = val;
-               }
-               if(Address[i] != '\0') {
-                       //printf("EOS != '\\0', '%c'\n", Address[i]);
-                       return 0;
-               }
-               return 4;
-       }
-       
-       // IPv6
-       if(*p == ':' || ('a' <= *p && *p <= 'f') || ('A' <= *p && *p <= 'F'))
-       {
-                int    i = 0;
-                int    j, k;
-                int    val, split = -1, end;
-               uint16_t        hi[8], low[8];
-               
-               for( j = 0; Address[i] && j < 8; j ++ )
-               {
-                       if(Address[i] == '/')
-                               break;
-                       
-                       if(Address[i] == ':') {
-                               if(split != -1) {
-                                       printf("Two '::'s\n");
-                                       return 0;
-                               }
-                               split = j;
-                               i ++;
-                               continue;
-                       }
-                       
-                       val = 0;
-                       for( k = 0; Address[i] && Address[i] != ':' && Address[i] != '/'; i++, k++ )
-                       {
-                               val *= 16;
-                               if('0' <= Address[i] && Address[i] <= '9')
-                                       val += Address[i] - '0';
-                               else if('A' <= Address[i] && Address[i] <= 'F')
-                                       val += Address[i] - 'A' + 10;
-                               else if('a' <= Address[i] && Address[i] <= 'f')
-                                       val += Address[i] - 'a' + 10;
-                               else {
-                                       printf("%c unexpected\n", Address[i]);
-                                       return 0;
-                               }
-                       }
-                       
-                       if(val > 0xFFFF) {
-                               printf("val (0x%x) > 0xFFFF\n", val);
-                               return 0;
-                       }
-                       
-                       if(split == -1)
-                               hi[j] = val;
-                       else
-                               low[j-split] = val;
-                       
-                       if( Address[i] == ':' ) {
-                               i ++;
-                       }
-               }
-               end = j;
-               
-               // Parse subnet size
-               if(Address[i] == '/') {
-                       val = 0;
-                       while('0' <= Address[i] && Address[i] <= '9') {
-                               val *= 10;
-                               val += Address[i] - '0';
-                               i ++;
-                       }
-                       if(val > 128) {
-                               printf("Notice: Subnet size >128 (%i)\n", val);
-                       }
-                       if(SubnetBits)  *SubnetBits = val;
-               }
-               
-               for( j = 0; j < split; j ++ )
-               {
-                       //printf("%04x:", hi[j]);
-                       Dest[j*2] = hi[j]>>8;
-                       Dest[j*2+1] = hi[j]&0xFF;
-               }
-               for( ; j < 8 - (end - split); j++ )
-               {
-                       //printf("0000:", hi[j]);
-                       Dest[j*2] = 0;
-                       Dest[j*2+1] = 0;
-               }
-               for( k = 0; j < 8; j ++, k++)
-               {
-                       //printf("%04x:", low[k]);
-                       Dest[j*2] = low[k]>>8;
-                       Dest[j*2+1] = low[k]&0xFF;
-               }
-               return 6;
-       }
-       // Unknown type
-       return 0;
-}
diff --git a/Usermode/Applications/ifconfig_src/rules.mk b/Usermode/Applications/ifconfig_src/rules.mk
deleted file mode 100644 (file)
index f420eb8..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# ifconfig
-
-include $(BASE)header.mk
-
-# Variables
-SRCS := main.c
-BIN  := $(OUTPUTDIR)Bin/ifconfig
-
-LDFLAGS-$(DIR) += -lnet
-
-include $(BASE)body.mk
-
-include $(BASE)footer.mk
-
diff --git a/Usermode/Applications/ip_src/Makefile b/Usermode/Applications/ip_src/Makefile
new file mode 100644 (file)
index 0000000..1c976b5
--- /dev/null
@@ -0,0 +1,11 @@
+# Project: ip
+
+-include ../Makefile.cfg
+
+LDFLAGS += -lnet
+
+OBJ = main.o addr.o routes.o
+BIN = ip
+
+-include ../Makefile.tpl
+
diff --git a/Usermode/Applications/ip_src/addr.c b/Usermode/Applications/ip_src/addr.c
new file mode 100644 (file)
index 0000000..579aa47
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * Acess2 ip command
+ * - By John Hodge (thePowersGang)
+ * 
+ * addr.c
+ * - `ip addr` sub command
+ */
+#include "common.h"
+
+// === PROTOTYPES ===
+ int   Addr_main(int argc, char *argv[]);
+ int   AddInterface(const char *Device);
+ int   SetAddress(int IFNum, const char *Address);
+void   DumpInterfaces(void);
+void   DumpInterface(const char *Name);
+void   DumpRoute(const char *Name);
+
+// === CODE ===
+int Addr_main(int argc, char *argv[])
+{
+        int    ret;
+       if( argc <= 1 )
+       {
+               // No action
+               DumpInterfaces();
+       }
+       else if( strcmp(argv[1], "add") == 0 )
+       {
+               if( argc - 2 < 2 ) {
+                       fprintf(stderr, "ERROR: '%s add' requires two arguments, %i passed\n", argv[0], argc-2);
+                       PrintUsage(argv[0]);
+                       return -1;
+               }
+               ret = AddInterface( argv[2] );
+               if(ret < 0)     return ret;
+               ret = SetAddress( ret, argv[3] );
+               return ret;
+       }
+       // Delete an interface
+       else if( strcmp(argv[1], "del") == 0 )
+       {
+               if( argc - 2 < 1 ) {
+                       fprintf(stderr, "ERROR: '%s del' requires an argument\n", argv[0]);
+                       PrintUsage(argv[0]);
+                       return -1;
+               }
+       }
+       else
+       {
+               // Show named iface?
+               DumpInterface(argv[1]);
+       }
+       return 0;
+}
+
+/**
+ * \brief Create a new interface using the passed device
+ * \param Device       Network device to bind to
+ */
+int AddInterface(const char *Device)
+{
+        int    dp, ret;
+       
+       dp = open(IPSTACK_ROOT, OPENFLAG_READ);
+       ret = ioctl(dp, 4, (void*)Device);
+       close(dp);
+       
+       if( ret < 0 ) {
+               fprintf(stderr, "Unable to add '%s' as a network interface\n", Device);
+               return -1;
+       }
+       
+       printf("-- Added '"IPSTACK_ROOT"/%i' using device %s\n", ret, Device);
+       
+       return ret;
+}
+
+/**
+ * \brief Set the address on an interface from a textual IP address
+ */
+int SetAddress(int IFNum, const char *Address)
+{
+       uint8_t addr[16];
+        int    type;
+       char    path[sizeof(IPSTACK_ROOT)+1+5+1];       // ip000
+        int    tmp, fd, subnet;
+       
+       // Parse IP Address
+       type = ParseIPAddress(Address, addr, &subnet);
+       if(type == 0) {
+               fprintf(stderr, "'%s' cannot be parsed as an IP address\n", Address);
+               return -1;
+       }
+       
+       // Open file
+       sprintf(path, IPSTACK_ROOT"/%i", IFNum);
+       fd = open(path, OPENFLAG_READ);
+       if( fd == -1 ) {
+               fprintf(stderr, "Unable to open '%s'\n", path);
+               return -1;
+       }
+       
+       tmp = type;
+       tmp = ioctl(fd, ioctl(fd, 3, "getset_type"), &tmp);
+       if( tmp != type ) {
+               fprintf(stderr, "Error in setting address type (got %i, expected %i)\n", tmp, type);
+               close(fd);
+               return -1;
+       }
+       // Set Address
+       ioctl(fd, ioctl(fd, 3, "set_address"), addr);
+       
+       // Set Subnet
+       ioctl(fd, ioctl(fd, 3, "getset_subnet"), &subnet);
+       
+       close(fd);
+       
+       // Dump!
+       //DumpInterface( path+sizeof(IPSTACK_ROOT)+1 );
+       
+       return 0;
+}
+
+/**
+ * \brief Dump all interfaces
+ */
+void DumpInterfaces(void)
+{
+        int    dp;
+       char    filename[FILENAME_MAX+1];
+       
+       dp = open(IPSTACK_ROOT, OPENFLAG_READ);
+       
+       while( readdir(dp, filename) )
+       {
+               if(filename[0] == '.')  continue;
+               DumpInterface(filename);
+       }
+       
+       close(dp);
+}
+
+/**
+ * \brief Dump an interface
+ */
+void DumpInterface(const char *Name)
+{
+        int    fd;
+        int    type;
+       char    path[sizeof(IPSTACK_ROOT)+1+FILENAME_MAX+1] = IPSTACK_ROOT"/";
+       
+       strcat(path, Name);
+       
+       fd = open(path, OPENFLAG_READ);
+       if(fd == -1) {
+               fprintf(stderr, "Bad interface name '%s' (%s does not exist)\t", Name, path);
+               return ;
+       }
+       
+       type = ioctl(fd, 4, NULL);
+       
+       // Ignore -1 values
+       if( type == -1 ) {
+               return ;
+       }
+       
+       printf("%s:\t", Name);
+       {
+                int    call_num = ioctl(fd, 3, "get_device");
+                int    len = ioctl(fd, call_num, NULL);
+               char    *buf = malloc(len+1);
+               ioctl(fd, call_num, buf);
+               printf("'%s'\n", buf);
+               free(buf);
+       }
+       printf("\t");
+       // Get the address type
+       switch(type)
+       {
+       case 0: // Disabled/Unset
+               printf("DISABLED\n");
+               break;
+       case 4: // IPv4
+               {
+               uint8_t ip[4];
+                int    subnet;
+               printf("IPv4\t");
+               ioctl(fd, 5, ip);       // Get IP Address
+               subnet = ioctl(fd, 7, NULL);    // Get Subnet Bits
+               printf("%i.%i.%i.%i/%i\n", ip[0], ip[1], ip[2], ip[3], subnet);
+               }
+               break;
+       case 6: // IPv6
+               {
+               uint16_t        ip[8];
+                int    subnet;
+               printf("IPv6\t");
+               ioctl(fd, 5, ip);       // Get IP Address
+               subnet = ioctl(fd, 7, NULL);    // Get Subnet Bits
+               printf("%x:%x:%x:%x:%x:%x:%x:%x/%i\n",
+                       ntohs(ip[0]), ntohs(ip[1]), ntohs(ip[2]), ntohs(ip[3]),
+                       ntohs(ip[4]), ntohs(ip[5]), ntohs(ip[6]), ntohs(ip[7]),
+                       subnet);
+               }
+               break;
+       default:        // Unknow
+               printf("UNKNOWN (%i)\n", type);
+               break;
+       }
+                       
+       close(fd);
+}
+
diff --git a/Usermode/Applications/ip_src/common.h b/Usermode/Applications/ip_src/common.h
new file mode 100644 (file)
index 0000000..f4aa373
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Acess2 ip command
+ * - By John Hodge (thePowersGang)
+ * 
+ * common.h
+ * - Shared header
+ */
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <net.h>
+#include <acess/sys.h>
+
+#define FILENAME_MAX   255
+#define IPSTACK_ROOT   "/Devices/ip"
+
+#define ntohs(v)       (((v&0xFF)<<8)|((v>>8)&0xFF))
+
+extern void    PrintUsage(const char *ProgName);
+extern int     ParseIPAddress(const char *Address, uint8_t *Dest, int *SubnetBits);
+extern int     Addr_main(int argc, char *argv[]);
+extern int     Routes_main(int argc, char *argv[]);
+
+#endif
+
diff --git a/Usermode/Applications/ip_src/main.c b/Usermode/Applications/ip_src/main.c
new file mode 100644 (file)
index 0000000..580fb4e
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Acess2 ip command
+ * - By John Hodge (thePowersGang)
+ */
+#include "common.h"
+
+// === CONSTANTS ===
+
+// === PROTOTYPES ===
+void   PrintUsage(const char *ProgName);
+ int   ParseIPAddress(const char *Address, uint8_t *Dest, int *SubnetBits);
+
+// === CODE ===
+/**
+ * \brief Program entrypoint
+ */
+int main(int argc, char *argv[])
+{
+       // No args, dump interfaces
+       if(argc == 1) {
+//             DumpInterfaces();
+               return 0;
+       }
+       
+       // Routes
+       if( strcmp(argv[1], "route") == 0 )
+       {
+               Routes_main(argc-1, argv+1);
+               return 0;
+       }
+       else if( strcmp(argv[1], "addr") == 0 )
+       {
+               Addr_main(argc-1, argv+1);
+               return 0;
+       }
+       else if( strcmp(argv[1], "help") == 0 || strcmp(argv[1], "--help") == 0 )
+       {
+               PrintUsage(argv[0]);
+               return 0;
+       }
+       
+       return 0;
+}
+
+/**
+ * \brief Print usage instructions
+ */
+void PrintUsage(const char *ProgName)
+{
+       fprintf(stderr, "Usage:\n");
+       fprintf(stderr, "    %s addr add <device> <ip>/<prefix>\n", ProgName);
+       fprintf(stderr, "        Add a new interface listening on <device> with the specified\n");
+       fprintf(stderr, "        address.\n");
+       fprintf(stderr, "    %s addr del <interface>\n", ProgName);
+       fprintf(stderr, "        Delete an interface\n");
+       fprintf(stderr, "    %s addr [<interface>]\n", ProgName);
+       fprintf(stderr, "        Print the current interfaces (or only <interface> if passed)\n");
+       fprintf(stderr, "\n");
+       fprintf(stderr, "    %s route\n", ProgName);
+       fprintf(stderr, "        Print the routing tables\n");
+       fprintf(stderr, "    %s route add <host>[/<prefix>] [<nexthop> OR <iface>] [<metric>]\n", ProgName);
+       fprintf(stderr, "        Add a new route\n");
+       fprintf(stderr, "    %s route del <host>[/<prefix>]\n", ProgName);
+       fprintf(stderr, "    %s route del <routenum>\n", ProgName);
+       fprintf(stderr, "        Add a new route\n");
+       fprintf(stderr, "\n");
+       fprintf(stderr, "A note on Acess's IP Stack:\n");
+       fprintf(stderr, "    Each interface corresponds to only one IP address (either IPv4\n");
+       fprintf(stderr, "    or IPv6). A network device can have multiple interfaces bound\n");
+       fprintf(stderr, "    to it, allowing multiple addresses for one network connection\n");
+       fprintf(stderr, "\n");
+}
+
+
+/**
+ * \brief Parse an IP Address
+ * \return 0 for unknown, 4 for IPv4 and 6 for IPv6
+ */
+int ParseIPAddress(const char *Address, uint8_t *Dest, int *SubnetBits)
+{
+       const char      *p = Address;
+       
+       // Check first block
+       while(*p && *p >= '0' && *p <= '9')     p ++;
+       
+       // IPv4?
+       if(*p == '.')
+       {
+                int    i = 0, j;
+                int    val;
+               
+               for( j = 0; Address[i] && j < 4; j ++ )
+               {
+                       val = 0;
+                       for( ; '0' <= Address[i] && Address[i] <= '9'; i++ )
+                       {
+                               val = val*10 + Address[i] - '0';
+                       }
+                       if(val > 255) {
+                               //printf("val > 255 (%i)\n", val);
+                               return 0;
+                       }
+                       Dest[j] = val;
+                       
+                       if(Address[i] == '.')
+                               i ++;
+               }
+               if( j != 4 ) {
+                       //printf("4 parts expected, %i found\n", j);
+                       return 0;
+               }
+               // Parse subnet size
+               if(Address[i] == '/') {
+                       val = 0;
+                       i ++;
+                       while('0' <= Address[i] && Address[i] <= '9') {
+                               val *= 10;
+                               val += Address[i] - '0';
+                               i ++;
+                       }
+                       if(val > 32) {
+                               printf("Notice: Subnet size >32 (%i)\n", val);
+                       }
+                       if(SubnetBits)  *SubnetBits = val;
+               }
+               if(Address[i] != '\0') {
+                       //printf("EOS != '\\0', '%c'\n", Address[i]);
+                       return 0;
+               }
+               return 4;
+       }
+       
+       // IPv6
+       if(*p == ':' || ('a' <= *p && *p <= 'f') || ('A' <= *p && *p <= 'F'))
+       {
+                int    i = 0;
+                int    j, k;
+                int    val, split = -1, end;
+               uint16_t        hi[8], low[8];
+               
+               for( j = 0; Address[i] && j < 8; j ++ )
+               {
+                       if(Address[i] == '/')
+                               break;
+                       
+                       if(Address[i] == ':') {
+                               if(split != -1) {
+                                       printf("Two '::'s\n");
+                                       return 0;
+                               }
+                               split = j;
+                               i ++;
+                               continue;
+                       }
+                       
+                       val = 0;
+                       for( k = 0; Address[i] && Address[i] != ':' && Address[i] != '/'; i++, k++ )
+                       {
+                               val *= 16;
+                               if('0' <= Address[i] && Address[i] <= '9')
+                                       val += Address[i] - '0';
+                               else if('A' <= Address[i] && Address[i] <= 'F')
+                                       val += Address[i] - 'A' + 10;
+                               else if('a' <= Address[i] && Address[i] <= 'f')
+                                       val += Address[i] - 'a' + 10;
+                               else {
+                                       printf("%c unexpected\n", Address[i]);
+                                       return 0;
+                               }
+                       }
+                       
+                       if(val > 0xFFFF) {
+                               printf("val (0x%x) > 0xFFFF\n", val);
+                               return 0;
+                       }
+                       
+                       if(split == -1)
+                               hi[j] = val;
+                       else
+                               low[j-split] = val;
+                       
+                       if( Address[i] == ':' ) {
+                               i ++;
+                       }
+               }
+               end = j;
+               
+               // Parse subnet size
+               if(Address[i] == '/') {
+                       val = 0;
+                       while('0' <= Address[i] && Address[i] <= '9') {
+                               val *= 10;
+                               val += Address[i] - '0';
+                               i ++;
+                       }
+                       if(val > 128) {
+                               printf("Notice: Subnet size >128 (%i)\n", val);
+                       }
+                       if(SubnetBits)  *SubnetBits = val;
+               }
+               
+               for( j = 0; j < split; j ++ )
+               {
+                       //printf("%04x:", hi[j]);
+                       Dest[j*2] = hi[j]>>8;
+                       Dest[j*2+1] = hi[j]&0xFF;
+               }
+               for( ; j < 8 - (end - split); j++ )
+               {
+                       //printf("0000:", hi[j]);
+                       Dest[j*2] = 0;
+                       Dest[j*2+1] = 0;
+               }
+               for( k = 0; j < 8; j ++, k++)
+               {
+                       //printf("%04x:", low[k]);
+                       Dest[j*2] = low[k]>>8;
+                       Dest[j*2+1] = low[k]&0xFF;
+               }
+               return 6;
+       }
+       // Unknown type
+       return 0;
+}
diff --git a/Usermode/Applications/ip_src/routes.c b/Usermode/Applications/ip_src/routes.c
new file mode 100644 (file)
index 0000000..1d60fbc
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * Acess2 ip command
+ * - By John Hodge (thePowersGang)
+ * 
+ * routes.c
+ * - `ip route` sub-command
+ */
+#include "common.h"
+
+#define DEFAULT_METRIC 30
+
+// === PROTOTYPES ===
+ int   Routes_main(int argc, char *argv[]);
+void   DumpRoutes(void);
+void   DumpRoute(const char *Name);
+void   AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, int Metric, void *NextHop);
+
+// === CODE ===
+int Routes_main(int argc, char *argv[])
+{
+       if( argc <= 1 )
+       {
+               // Show routes
+               DumpRoutes();
+       }
+       // Add new route
+       else if( strcmp(argv[1], "add") == 0 )
+       {
+               uint8_t dest[16] = {0};
+               uint8_t nextHop[16] = {0};
+                int    addrType, subnetBits = -1;
+                int    nextHopType, nextHopBits=-1;
+               char    *ifaceName = NULL;
+                int    metric = DEFAULT_METRIC;
+               // Usage:
+               // ifconfig route add <host>[/<prefix>] <interface> [<metric>]
+               // ifconfig route add <host>[/<prefix>] <next hop> [<metric>]
+               if( argc - 2 < 2 ) {
+                       fprintf(stderr, "ERROR: '%s route add' takes at least two arguments, %i passed\n",
+                               argv[0], argc-3);
+                       PrintUsage(argv[0]);
+                       return -1;
+               }
+               
+               if( argc - 2 > 3 ) {
+                       fprintf(stderr, "ERROR: '%s route add' takes at most three arguments, %i passed\n",
+                               argv[0], argc-3);
+                       PrintUsage(argv[0]);
+                       return -1;
+               }
+               
+               // Destination IP
+               addrType = ParseIPAddress(argv[3], dest, &subnetBits);
+               if( subnetBits == -1 ) {
+                       subnetBits = Net_GetAddressSize(addrType)*8;
+               }
+               // Interface Name / Next Hop
+               if( (nextHopType = ParseIPAddress(argv[4], nextHop, &nextHopBits)) == 0 )
+               {
+                       // Interface name
+                       ifaceName = argv[4];
+               }
+               else
+               {
+                       // Next Hop
+                       // - Check if it's the same type as the network/destination
+                       if( nextHopType != addrType ) {
+                               fprintf(stderr, "ERROR: Address type mismatch\n");
+                               return -1;
+                       }
+                       // - Make sure there's no mask
+                       if( nextHopBits != -1 ) {
+                               fprintf(stderr, "Error: Next hop cannot be masked\n");
+                               return -1;
+                       }
+               }
+               
+               // Metric
+               if( argc - 3 >= 3 )
+               {
+                       metric = atoi(argv[5]);
+                       if( metric == 0 && argv[5][0] != '0' ) {
+                               fprintf(stderr, "ERROR: Metric should be a number\n");
+                               return -1;
+                       }
+               }
+               
+               // Make the route!
+               AddRoute(ifaceName, addrType, dest, subnetBits, metric, nextHop);
+               
+               return 0;
+       }
+       // Delete a route
+       else if( strcmp(argv[2], "del") == 0 )
+       {
+               // Usage:
+               // ifconfig route del <routenum>
+               // ifconfig route del <host>[/<prefix>]
+       }
+       else
+       {
+               // List routes
+               DumpRoutes();
+       }
+       
+       return 0;
+}
+
+/**
+ * \brief Dump all interfaces
+ */
+void DumpRoutes(void)
+{
+        int    dp;
+       char    filename[FILENAME_MAX+1];
+       
+       dp = open(IPSTACK_ROOT"/routes", OPENFLAG_READ);
+       
+       printf("Type\tNetwork \tGateway \tMetric\tIFace\n");
+       
+       while( readdir(dp, filename) )
+       {
+               if(filename[0] == '.')  continue;
+               DumpRoute(filename);
+       }
+       
+       close(dp);
+}
+
+/**
+ * \brief Dump a route
+ */
+void DumpRoute(const char *Name)
+{
+        int    fd;
+        int    type;
+       char    path[sizeof(IPSTACK_ROOT)+8+FILENAME_MAX+1] = IPSTACK_ROOT"/routes/";
+       
+       strcat(path, Name);
+       
+       fd = open(path, OPENFLAG_READ);
+       if(fd == -1) {
+               printf("%s:\tUnable to open ('%s')\n", Name, path);
+               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);
+       }
+       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)
+       {
+       case 0: // Disabled/Unset
+               printf("DISABLED\n");
+               break;
+       case 4: // IPv4
+               printf("IPv4\t");
+               break;
+       case 6: // IPv6
+               printf("IPv6\t");
+               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    call_num = ioctl(fd, 3, "get_interface");
+                int    len = ioctl(fd, call_num, NULL);
+               char    *buf = malloc(len+1);
+               ioctl(fd, call_num, buf);
+               printf("'%s'\t", buf);
+               free(buf);
+       }
+       
+       printf("\n");
+                       
+       close(fd);
+}
+
+void AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits, int Metric, void *NextHop)
+{
+        int    fd;
+        int    num;
+       char    *ifaceToFree = NULL;
+       
+       // Get interface name
+       if( !Interface )
+       {
+               if( !NextHop ) {
+                       fprintf(stderr,
+                               "BUG: AddRoute(Interface=NULL,...,NextHop=NULL)\n"
+                               "Only one should be NULL\n"
+                               );
+                       return ;
+               }
+               
+               // Query for the interface name
+               Interface = ifaceToFree = Net_GetInterface(AddressType, NextHop);
+       }
+       // Check address type (if the interface was passed)
+       // - If we got the interface name, then it should be correct
+       else
+       {
+               char    ifacePath[sizeof(IPSTACK_ROOT"/")+strlen(Interface)+1];
+               
+               // Open interface
+               strcpy(ifacePath, IPSTACK_ROOT"/");
+               strcat(ifacePath, Interface);
+               fd = open(ifacePath, 0);
+               if( fd == -1 ) {
+                       fprintf(stderr, "Error: Interface '%s' does not exist\n", Interface);
+                       return ;
+               }
+               // Get and check type
+               num = ioctl(fd, ioctl(fd, 3, "getset_type"), NULL);
+               if( num != AddressType ) {
+                       fprintf(stderr, "Error: Passed type does not match interface type (%i != %i)\n",
+                               AddressType, num);
+                       return ;
+               }
+               
+               close(fd);
+       }
+       
+       // Create route
+        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 ;
+       }
+       
+       if( NextHop )
+               ioctl(fd, ioctl(fd, 3, "set_nexthop"), NextHop);
+       ioctl(fd, ioctl(fd, 3, "set_interface"), (void*)Interface);
+       
+       close(fd);
+       
+       // Check if the interface name was allocated by us
+       if( ifaceToFree )
+               free(ifaceToFree);
+}
+
diff --git a/Usermode/Applications/ip_src/rules.mk b/Usermode/Applications/ip_src/rules.mk
new file mode 100644 (file)
index 0000000..f420eb8
--- /dev/null
@@ -0,0 +1,14 @@
+# ifconfig
+
+include $(BASE)header.mk
+
+# Variables
+SRCS := main.c
+BIN  := $(OUTPUTDIR)Bin/ifconfig
+
+LDFLAGS-$(DIR) += -lnet
+
+include $(BASE)body.mk
+
+include $(BASE)footer.mk
+
index 3f46d15..901e8ac 100644 (file)
@@ -113,10 +113,12 @@ int main(int argc, const char *argv[], const char *envp[])
        \r
        // HACK: Static server entry\r
        // UCC (University [of Western Australia] Computer Club) IRC Server\r
-//     gWindow_Status.Server = Server_Connect( "UCC", "130.95.13.18", 6667 );\r
-       gWindow_Status.Server = Server_Connect( "Freenode", "89.16.176.16", 6667 );\r
+       gWindow_Status.Server = Server_Connect( "UCC", "130.95.13.18", 6667 );\r
+       // Freenode (#osdev)\r
+//     gWindow_Status.Server = Server_Connect( "Freenode", "89.16.176.16", 6667 );\r
 //     gWindow_Status.Server = Server_Connect( "Host", "10.0.2.2", 6667 );\r
-//     gWindow_Status.Server = Server_Connect( "BitlBee", "192.168.1.34", 6667 );\r
+       // Local server\r
+//     gWindow_Status.Server = Server_Connect( "BitlBee", "192.168.1.39", 6667 );\r
        \r
        if( !gWindow_Status.Server )\r
                return -1;\r
@@ -205,6 +207,9 @@ int ParseArguments(int argc, const char *argv[])
        return 0;\r
 }\r
 \r
+/**\r
+ * \brief Handle a line from the prompt\r
+ */\r
 int ParseUserCommand(char *String)\r
 {\r
        if( String[0] == '/' )\r
@@ -519,11 +524,12 @@ void ParseServerLine(tServer *Server, char *Line)
         int    pos = 0;\r
        char    *ident, *cmd;\r
 \r
-       _SysDebug("Server %s: Line = %s", Server->Name, Line);  \r
+       _SysDebug("[%s] %s", Server->Name, Line);       \r
        \r
        // Message?\r
        if( *Line == ':' )\r
        {\r
+               pos ++;\r
                ident = GetValue(Line, &pos);   // Ident (user or server)\r
                cmd = GetValue(Line, &pos);\r
                \r
@@ -547,18 +553,29 @@ void ParseServerLine(tServer *Server, char *Line)
                        \r
                        switch(num)\r
                        {\r
+                       case 332:       // Topic\r
+                               user = message; // Channel\r
+                               message = Line + pos + 1;       // Topic\r
+                               Message_AppendF(Server, MSG_TYPE_SERVER, user, user, "Topic: %s", message);\r
+                               break;\r
+                       case 333:       // Topic set by\r
+                               user = message; // Channel\r
+                               message = GetValue(Line, &pos); // User\r
+                               GetValue(Line, &pos);   // Timestamp\r
+                               Message_AppendF(Server, MSG_TYPE_SERVER, user, user, "Set by %s", message);\r
+                               break;\r
                        case 353:       // /NAMES list\r
                                // <user> = <channel> :list\r
-//                             GetValue(Line, &pos);   // '='\r
+                               // '=' was eaten in and set to message\r
                                user = GetValue(Line, &pos);    // Actually channel\r
                                message = Line + pos + 1;       // List\r
-                               Message_AppendF(Server, MSG_TYPE_SERVER, user, "", "Names: %s", message);\r
+                               Message_AppendF(Server, MSG_TYPE_SERVER, user, user, "Names: %s", message);\r
                                break;\r
                        case 366:       // end of /NAMES list\r
                                // <user> <channel> :msg\r
                                user = message;\r
                                message = Line + pos + 1;\r
-                               Message_Append(Server, MSG_TYPE_SERVER, user, "", message);\r
+                               Message_Append(Server, MSG_TYPE_SERVER, user, user, message);\r
                                break;\r
                        case 372:       // MOTD Data\r
                        case 376:       // MOTD End\r
@@ -597,13 +614,17 @@ void ParseServerLine(tServer *Server, char *Line)
                        else {\r
                                message = GetValue(Line, &pos);\r
                        }\r
+\r
+                       // TODO: Catch when the privmsg is addressed to the user\r
+\r
 //                     Cmd_PRIVMSG(Server, dest, ident, message);\r
+                       *strchr(ident, '!') = '\0';     // Hello SIGSEGV\r
                        Message_Append(Server, MSG_TYPE_STANDARD, ident, dest, message);\r
                }\r
                else if( strcmp(cmd, "JOIN" ) == 0 )\r
                {\r
                        char    *channel;\r
-                       channel = GetValue(Line, &pos) + 1;\r
+                       channel = Line + pos + 1;\r
                        Window_Create(Server, channel);\r
                }\r
                else\r
index 33113c8..7686e5c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Acess2 IFCONFIG command
+ * Acess2 ping command
  */
 #include <stdlib.h>
 #include <stdint.h>

UCC git Repository :: git.ucc.asn.au