From: John Hodge Date: Mon, 18 Jan 2010 05:21:02 +0000 (+0800) Subject: Changes and Features to IPStack X-Git-Tag: rel0.06~324 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=25f19babe7a0ab75d04ff7e6f98f7bcb65fb8941;p=tpg%2Facess2.git Changes and Features to IPStack - Added 'ping' ioctl and required calls, currently incomplete --- diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index b0b7558c..fb947585 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 1368 +BUILD_NUM = 1369 diff --git a/Modules/IPStack/arp.c b/Modules/IPStack/arp.c index 2ee4fac6..0ba0fd35 100644 --- a/Modules/IPStack/arp.c +++ b/Modules/IPStack/arp.c @@ -7,6 +7,7 @@ #include "link.h" #define ARP_CACHE_SIZE 64 +#define ARP_MAX_AGE (60*60*1000) // 1Hr // === IMPORTS === extern tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast); @@ -23,8 +24,11 @@ struct sARP_Cache { tIPv4 IP4; tIPv6 IP6; Sint64 LastUpdate; + Sint64 LastUsed; } *gaARP_Cache; int giARP_CacheSpace; + int giARP_LastUpdateID = 0; +tSpinlock glARP_Cache; // === CODE === /** @@ -41,6 +45,45 @@ int ARP_Initialise() return 1; } +/** + * \brief Resolves a MAC address from an IPv4 address + */ +tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address) +{ + int lastID; + int i; + + LOCK( &glARP_Cache ); + for( i = 0; i < giARP_CacheSpace; i++ ) + { + if(gaARP_Cache[i].IP4.L != Address.L) continue; + + // Check if the entry needs to be refreshed + if( now() - gaARP_Cache[i].LastUpdate > ARP_MAX_AGE ) break; + + RELEASE( &glARP_Cache ); + return gaARP_Cache[i].MAC; + } + RELEASE( &glARP_Cache ); + + lastID = giARP_LastUpdateID; + ARP_int_Resolve4(Interface, Address); + for(;;) + { + while(lastID == giARP_LastUpdateID) Threads_Yield(); + + LOCK( &glARP_Cache ); + for( i = 0; i < giARP_CacheSpace; i++ ) + { + if(gaARP_Cache[i].IP4.L != Address.L) continue; + + RELEASE( &glARP_Cache ); + return gaARP_Cache[i].MAC; + } + RELEASE( &glARP_Cache ); + } +} + /** * \fn int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address) * \brief Request the network to resolve an IPv4 Address @@ -160,6 +203,7 @@ void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffe case 2: // Ooh! A response! // Find an entry for the MAC address in the cache + LOCK(&glARP_Cache); for( i = giARP_CacheSpace; i--; ) { if(gaARP_Cache[oldest].LastUpdate > gaARP_Cache[i].LastUpdate) { @@ -190,10 +234,12 @@ void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffe break; default: Log("[ARP ] Unknown Protocol Address size (%i)", req4->SWSize); + RELEASE(&glARP_Cache); return ; } gaARP_Cache[i].LastUpdate = now(); + RELEASE(&glARP_Cache); break; } } diff --git a/Modules/IPStack/icmp.c b/Modules/IPStack/icmp.c index 5d53cc6c..3f82f878 100644 --- a/Modules/IPStack/icmp.c +++ b/Modules/IPStack/icmp.c @@ -6,11 +6,18 @@ #include "ipv4.h" #include "icmp.h" +// === CONSTANTS === +#define PING_SLOTS 64 + // === PROTOTYPES === void ICMP_Initialise(); void ICMP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer); // === GLOBALS === +struct { + tInterface *Interface; + int bArrived; +} gICMP_PingSlots[PING_SLOTS]; // === CODE === /** @@ -35,4 +42,51 @@ void ICMP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buff Log("[ICMP ] hdr->Checksum = 0x%x", ntohs(hdr->Checksum)); Log("[ICMP ] hdr->ID = 0x%x", ntohs(hdr->ID)); Log("[ICMP ] hdr->Sequence = 0x%x", ntohs(hdr->Sequence)); + + switch(hdr->Type) + { + case ICMP_ECHOREPLY: + if(hdr->Code != 0) { + Warning("[ICMP ] Code == %i for ICMP Echo Reply, should be 0", hdr->Code); + return ; + } + if(hdr->ID != ~hdr->Sequence) { + Warning("[ICMP ] ID and Sequence values do not match"); + return ; + } + gICMP_PingSlots[hdr->ID].bArrived = 1; + break; + } + +} + +/** + * \brief Sends ICMP Echo and waits for the reply + * \note Times out after \a Interface->TimeoutDelay has elapsed + */ +int ICMP_Ping(tInterface *Interface, tIPv4 Addr) +{ + //Sint64 ts; + char buf[32] = "\x8\0\0\0\0\0\0\0Acess2 I" + "P/TCP Stack 1.0\0"; + tICMPHeader *hdr = (void*)buf; + int i; + + for(;;) + { + for(i=0;iID = i; + hdr->Sequence = ~i; + hdr->Checksum = htons( IPv4_Checksum(hdr, sizeof(buf)) ); + IPv4_SendPacket(Interface, Addr, 1, i, 32, buf); + + return -1; } diff --git a/Modules/IPStack/icmp.h b/Modules/IPStack/icmp.h index 73a641fb..abd19cbd 100644 --- a/Modules/IPStack/icmp.h +++ b/Modules/IPStack/icmp.h @@ -18,4 +18,16 @@ struct sICMPHeader Uint16 Sequence; }; +// === CONSTANTS === +enum eICMPTypes +{ + ICMP_ECHOREPLY = 1, + ICMP_UNREACHABLE = 3, + ICMP_QUENCH = 4, + ICMP_REDIRECT = 5, + ICMP_ALTADDR = 6, + ICMP_ECHOREQ = 8, + ICMP_TRACE = 30 // Information Request +}; + #endif diff --git a/Modules/IPStack/ipstack.h b/Modules/IPStack/ipstack.h index 94fabbb5..faf8cb8c 100644 --- a/Modules/IPStack/ipstack.h +++ b/Modules/IPStack/ipstack.h @@ -34,6 +34,7 @@ struct sInterface { struct sInterface *Next; tVFS_Node Node; tAdapter *Adapter; + int TimeoutDelay; // Time in miliseconds before a connection times out int Type; // 0 for disabled, 4 for IPv4 and 6 for IPv6 union { struct { diff --git a/Modules/IPStack/ipv4.c b/Modules/IPStack/ipv4.c index 7e7c5854..282e71bb 100644 --- a/Modules/IPStack/ipv4.c +++ b/Modules/IPStack/ipv4.c @@ -6,10 +6,14 @@ #include "link.h" #include "ipv4.h" +#define DEFAULT_TTL 32 + // === IMPORTS === extern tInterface *gIP_Interfaces; extern void ICMP_Initialise(); +extern int ICMP_Ping(tInterface *Interface, tIPv4 Addr); extern void UDP_Initialise(); +extern tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address); // === PROTOTYPES === int IPv4_Initialise(); @@ -17,6 +21,8 @@ extern void UDP_Initialise(); void IPv4_int_GetPacket(tAdapter *Interface, tMacAddr From, int Length, void *Buffer); tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast); Uint32 IPv4_Netmask(int FixedBits); +Uint16 IPv4_Checksum(void *Buf, int Size); + int IPv4_Ping(tInterface *Iface, tIPv4 Addr); // === GLOBALS === tIPCallback gaIPv4_Callbacks[256]; @@ -45,6 +51,33 @@ int IPv4_RegisterCallback(int ID, tIPCallback Callback) return 1; } +/** + * \brief Creates and sends an IPv4 Packet + */ +int IPv4_SendPacket(tInterface *Iface, tIPv4 Address, int Protocol, int ID, int Length, void *Data) +{ + tMacAddr to = ARP_Resolve4(Iface, Address); + int bufSize = sizeof(tIPv4Header) + Length; + char buf[bufSize]; + tIPv4Header *hdr = (void*)buf; + + memcpy(&hdr->Options[0], Data, Length); + hdr->Version = 4; + hdr->HeaderLength = htons( sizeof(tIPv4Header) ); + hdr->DiffServices = 0; // TODO: Check + hdr->TotalLength = htons( bufSize ); + hdr->Identifcation = htons( ID ); // TODO: Check + hdr->TTL = DEFAULT_TTL; + hdr->Protocol = Protocol; + hdr->HeaderChecksum = 0; // Will be set later + hdr->Source = Iface->IP4.Address; + hdr->Destination = Address; + hdr->HeaderChecksum = htons( IPv4_Checksum(hdr, sizeof(tIPv4Header)) ); + + Link_SendPacket(Iface->Adapter, IPV4_ETHERNET_ID, to, bufSize, buf); + return 1; +} + /** * \fn void IPv4_int_GetPacket(tInterface *Adapter, tMacAddr From, int Length, void *Buffer) * \brief Process an IPv4 Packet @@ -156,3 +189,30 @@ Uint32 IPv4_Netmask(int FixedBits) // Returs a little endian netmask return ret; } + +/** + * \brief Calculate the IPv4 Checksum + */ +Uint16 IPv4_Checksum(void *Buf, int Size) +{ + Uint16 sum = 0; + Uint16 *arr = Buf; + int i; + + Size = (Size + 1) >> 1; + for(i = 0; i < Size; i++ ) + { + if((int)sum + arr[i] > 0xFFFF) + sum ++; // Simulate 1's complement + sum += arr[i]; + } + return ~sum; +} + +/** + * \brief Sends an ICMP Echo and waits for a reply + */ +int IPv4_Ping(tInterface *Iface, tIPv4 Addr) +{ + return ICMP_Ping(Iface, Addr); +} diff --git a/Modules/IPStack/ipv4.h b/Modules/IPStack/ipv4.h index b092becb..e8c2bc38 100644 --- a/Modules/IPStack/ipv4.h +++ b/Modules/IPStack/ipv4.h @@ -46,5 +46,7 @@ struct sIPv4Header // === FUNCTIONS === extern int IPv4_RegisterCallback(int ID, tIPCallback Callback); +extern Uint16 IPv4_Checksum(void *Buf, int Size); +extern int IPv4_SendPacket(tInterface *Iface, tIPv4 Address, int Protocol, int ID, int Length, void *Data); #endif diff --git a/Modules/IPStack/main.c b/Modules/IPStack/main.c index 448381db..1a581735 100644 --- a/Modules/IPStack/main.c +++ b/Modules/IPStack/main.c @@ -11,12 +11,18 @@ #include #include +// === CONSTANTS === +//! Default timeout value, 30 seconds +#define DEFAULT_TIMEOUT (30*1000) + // === IMPORTS === extern int ARP_Initialise(); extern int IPv4_Initialise(); +extern int IPv4_Ping(tInterface *Iface, tIPv4 Addr); // === PROTOTYPES === int IPStack_Install(char **Arguments); + int IPStack_IOCtlRoot(tVFS_Node *Node, int ID, void *Data); char *IPStack_ReadDir(tVFS_Node *Node, int Pos); tVFS_Node *IPStack_FindDir(tVFS_Node *Node, char *Name); int IPStack_IOCtl(tVFS_Node *Node, int ID, void *Data); @@ -34,7 +40,7 @@ tDevFS_Driver gIP_DriverInfo = { .Flags = VFS_FFLAG_DIRECTORY, .ReadDir = IPStack_ReadDir, .FindDir = IPStack_FindDir, - .IOCtl = IPStack_IOCtl + .IOCtl = IPStack_IOCtlRoot } }; tSpinlock glIP_Interfaces = 0; @@ -158,20 +164,71 @@ tVFS_Node *IPStack_FindDir(tVFS_Node *Node, char *Name) } static const char *casIOCtls_Root[] = { DRV_IOCTLNAMES, "add_interface", NULL }; +/** + * \brief Handles IOCtls for the IPStack root + */ +int IPStack_IOCtlRoot(tVFS_Node *Node, int ID, void *Data) +{ + int tmp; + ENTER("pNode iID pData", Node, ID, Data); + + switch(ID) + { + // --- Standard IOCtls (0-3) --- + case DRV_IOCTL_TYPE: + LEAVE('i', DRV_TYPE_MISC); + return DRV_TYPE_MISC; + + case DRV_IOCTL_IDENT: + if( !CheckMem( Data, 4 ) ) LEAVE_RET('i', -1); + memcpy(Data, "IP\0\0", 4); + LEAVE('i', 1); + return 1; + + case DRV_IOCTL_VERSION: + LEAVE('x', VERSION); + return VERSION; + + case DRV_IOCTL_LOOKUP: + if( !CheckString( Data ) ) LEAVE_RET('i', -1); + LOG("Lookup '%s'", Data); + if( Node == &gIP_DriverInfo.RootNode ) + tmp = LookupString( (char**)casIOCtls_Root, (char*)Data ); + else + tmp = LookupString( (char**)casIOCtls_Iface, (char*)Data ); + LEAVE('i', tmp); + return tmp; + + /* + * add_interface + * - Adds a new IP interface and binds it to a device + */ + case 4: + if( Threads_GetUID() != 0 ) LEAVE_RET('i', -1); + if( !CheckString( Data ) ) LEAVE_RET('i', -1); + tmp = IPStack_AddInterface(Data); + LEAVE_RET('i', tmp); + } + LEAVE('i', 0); + return 0; +} + static const char *casIOCtls_Iface[] = { DRV_IOCTLNAMES, "getset_type", "get_address", "set_address", "getset_subnet", "get_gateway", "set_gateway", + "ping", NULL }; /** - * \brief Handles IOCtls for the IPStack root/interfaces + * \brief Handles IOCtls for the IPStack interfaces */ int IPStack_IOCtl(tVFS_Node *Node, int ID, void *Data) { int tmp; + tInterface *iface = (tInterface*)Node->ImplPtr; ENTER("pNode iID pData", Node, ID, Data); switch(ID) @@ -200,194 +257,192 @@ int IPStack_IOCtl(tVFS_Node *Node, int ID, void *Data) tmp = LookupString( (char**)casIOCtls_Iface, (char*)Data ); LEAVE('i', tmp); return tmp; - } - if(Node == &gIP_DriverInfo.RootNode) - { - switch(ID) + /* + * getset_type + * - Get/Set the interface type + */ + case 4: + // Set Type? + if( Data ) { - /* - * add_interface - * - Adds a new IP interface and binds it to a device - */ + // Ok, it's set type + if( Threads_GetUID() != 0 ) { + LOG("Attempt by non-root to alter an interface (%i)", Threads_GetUID()); + LEAVE('i', -1); + return -1; + } + if( !CheckMem( Data, sizeof(int) ) ) { + LOG("Invalid pointer %p", Data); + LEAVE('i', -1); + return -1; + } + switch( *(int*)Data ) + { + case 0: // Disable + iface->Type = 0; + memset(&iface->IP6, 0, sizeof(tIPv6)); // Clear address + break; + case 4: // IPv4 + iface->Type = 4; + memset(&iface->IP4, 0, sizeof(tIPv4)); + break; + case 6: // IPv6 + iface->Type = 6; + memset(&iface->IP6, 0, sizeof(tIPv6)); + break; + default: + LEAVE('i', -1); + return -1; + } + } + LEAVE('i', iface->Type); + return iface->Type; + + /* + * get_address + * - Get the interface's address + */ + case 5: + switch(iface->Type) + { + case 0: LEAVE_RET('i', 1); case 4: - if( Threads_GetUID() != 0 ) LEAVE_RET('i', -1); - if( !CheckString( Data ) ) LEAVE_RET('i', -1); - tmp = IPStack_AddInterface(Data); - LEAVE_RET('i', tmp); + if( !CheckMem( Data, sizeof(tIPv4) ) ) LEAVE_RET('i', -1); + memcpy( Data, &iface->IP4.Address, sizeof(tIPv4) ); + LEAVE_RET('i', 1); + case 6: + if( !CheckMem( Data, sizeof(tIPv6) ) ) LEAVE_RET('i', -1); + memcpy( Data, &iface->IP6.Address, sizeof(tIPv6) ); + LEAVE_RET('i', 1); } - LEAVE('i', 0); - return 0; - } - else - { - tInterface *iface = (tInterface*)Node->ImplPtr; - switch(ID) + LEAVE_RET('i', 0); + + /* + * set_address + * - Get the interface's address + */ + case 6: + if( Threads_GetUID() != 0 ) LEAVE_RET('i', -1); + switch(iface->Type) { - /* - * getset_type - * - Get/Set the interface type - */ + case 0: LEAVE_RET('i', 1); case 4: - // Set Type? - if( Data ) + if( !CheckMem( Data, sizeof(tIPv4) ) ) LEAVE_RET('i', -1); + iface->Type = 0; // One very hacky mutex/trash protector + memcpy( &iface->IP4.Address, Data, sizeof(tIPv4) ); + iface->Type = 4; + LEAVE_RET('i', 1); + case 6: + if( !CheckMem( Data, sizeof(tIPv6) ) ) LEAVE_RET('i', -1); + iface->Type = 0; + memcpy( &iface->IP6.Address, Data, sizeof(tIPv6) ); + iface->Type = 6; + LEAVE_RET('i', 1); + } + LEAVE_RET('i', 0); + + /* + * getset_subnet + * - Get/Set the bits in the address subnet + */ + case 7: + // Get? + if( Data == NULL ) + { + switch( iface->Type ) { - // Ok, it's set type - if( Threads_GetUID() != 0 ) { - LOG("Attempt by non-root to alter an interface (%i)", Threads_GetUID()); - LEAVE('i', -1); - return -1; - } - if( !CheckMem( Data, sizeof(int) ) ) { - LOG("Invalid pointer %p", Data); - LEAVE('i', -1); - return -1; - } - switch( *(int*)Data ) - { - case 0: // Disable - iface->Type = 0; - memset(&iface->IP6, 0, sizeof(tIPv6)); // Clear address - break; - case 4: // IPv4 - iface->Type = 4; - memset(&iface->IP4, 0, sizeof(tIPv4)); - break; - case 6: // IPv6 - iface->Type = 6; - memset(&iface->IP6, 0, sizeof(tIPv6)); - break; - default: - LEAVE('i', -1); - return -1; - } + case 4: LEAVE_RET('i', iface->IP4.SubnetBits); + case 6: LEAVE_RET('i', iface->IP6.SubnetBits); + default: LEAVE_RET('i', 0); } - LEAVE('i', iface->Type); - return iface->Type; + } - /* - * get_address - * - Get the interface's address - */ - case 5: - switch(iface->Type) - { - case 0: LEAVE_RET('i', 1); - case 4: - if( !CheckMem( Data, sizeof(tIPv4) ) ) LEAVE_RET('i', -1); - memcpy( Data, &iface->IP4.Address, sizeof(tIPv4) ); - LEAVE_RET('i', 1); - case 6: - if( !CheckMem( Data, sizeof(tIPv6) ) ) LEAVE_RET('i', -1); - memcpy( Data, &iface->IP6.Address, sizeof(tIPv6) ); - LEAVE_RET('i', 1); - } - LEAVE_RET('i', 0); + // Ok, set. + if( Threads_GetUID() != 0 ) LEAVE_RET('i', -1); + if( !CheckMem(Data, sizeof(int)) ) LEAVE_RET('i', -1); - /* - * set_address - * - Get the interface's address - */ + // Check and set the subnet bits + switch( iface->Type ) + { + case 4: + if( *(int*)Data < 0 || *(int*)Data > 31 ) LEAVE_RET('i', -1); + iface->IP4.SubnetBits = *(int*)Data; + LEAVE_RET('i', iface->IP4.SubnetBits); case 6: - if( Threads_GetUID() != 0 ) LEAVE_RET('i', -1); - switch(iface->Type) - { - case 0: LEAVE_RET('i', 1); - case 4: - if( !CheckMem( Data, sizeof(tIPv4) ) ) LEAVE_RET('i', -1); - iface->Type = 0; // One very hacky mutex/trash protector - memcpy( &iface->IP4.Address, Data, sizeof(tIPv4) ); - iface->Type = 4; - LEAVE_RET('i', 1); - case 6: - if( !CheckMem( Data, sizeof(tIPv6) ) ) LEAVE_RET('i', -1); - iface->Type = 0; - memcpy( &iface->IP6.Address, Data, sizeof(tIPv6) ); - iface->Type = 6; - LEAVE_RET('i', 1); - } - LEAVE_RET('i', 0); + if( *(int*)Data < 0 || *(int*)Data > 127 ) LEAVE_RET('i', -1); + iface->IP6.SubnetBits = *(int*)Data; + LEAVE_RET('i', iface->IP6.SubnetBits); + default: + break; + } - /* - * getset_subnet - * - Get/Set the bits in the address subnet - */ - case 7: - // Get? - if( Data == NULL ) - { - switch( iface->Type ) - { - case 4: LEAVE_RET('i', iface->IP4.SubnetBits); - case 6: LEAVE_RET('i', iface->IP6.SubnetBits); - default: LEAVE_RET('i', 0); - } - } - - // Ok, set. - if( Threads_GetUID() != 0 ) LEAVE_RET('i', -1); - if( !CheckMem(Data, sizeof(int)) ) LEAVE_RET('i', -1); - - // Check and set the subnet bits - switch( iface->Type ) - { - case 4: - if( *(int*)Data < 0 || *(int*)Data > 31 ) LEAVE_RET('i', -1); - iface->IP4.SubnetBits = *(int*)Data; - LEAVE_RET('i', iface->IP4.SubnetBits); - case 6: - if( *(int*)Data < 0 || *(int*)Data > 127 ) LEAVE_RET('i', -1); - iface->IP6.SubnetBits = *(int*)Data; - LEAVE_RET('i', iface->IP6.SubnetBits); - default: - break; - } - - LEAVE('i', 0); - return 0; + LEAVE('i', 0); + return 0; + + /* + * get_gateway + * - Get the interface's IPv4 gateway + */ + case 8: + switch(iface->Type) + { + case 0: + LEAVE_RET('i', 1); + case 4: + if( !CheckMem( Data, sizeof(tIPv4) ) ) LEAVE_RET('i', -1); + memcpy( Data, &iface->IP4.Gateway, sizeof(tIPv4) ); + LEAVE_RET('i', 1); + case 6: + LEAVE_RET('i', 1); + } + LEAVE('i', 0); + return 0; + + /* + * set_gateway + * - Get/Set the interface's IPv4 gateway + */ + case 9: + if( Threads_GetUID() != 0 ) LEAVE_RET('i', -1); + switch(iface->Type) + { + case 0: + LEAVE_RET('i', 1); + + case 4: + if( !CheckMem( Data, sizeof(tIPv4) ) ) LEAVE_RET('i', -1); + iface->Type = 0; // One very hacky mutex/trash protector + memcpy( &iface->IP4.Gateway, Data, sizeof(tIPv4) ); + iface->Type = 4; + LEAVE_RET('i', 1); - /* - * get_gateway - * - Get the interface's IPv4 gateway - */ - case 8: - switch(iface->Type) - { - case 0: - LEAVE_RET('i', 1); - case 4: - if( !CheckMem( Data, sizeof(tIPv4) ) ) LEAVE_RET('i', -1); - memcpy( Data, &iface->IP4.Gateway, sizeof(tIPv4) ); - LEAVE_RET('i', 1); - case 6: - LEAVE_RET('i', 1); - } - LEAVE('i', 0); - return 0; + case 6: + LEAVE_RET('i', 1); + } + break; + + /* + * ping + * - Send an ICMP Echo + */ + case 10: + switch(iface->Type) + { + case 0: + LEAVE_RET('i', 1); - /* - * set_gateway - * - Get the interface's IPv4 gateway - */ - case 9: - if( Threads_GetUID() != 0 ) LEAVE_RET('i', -1); - switch(iface->Type) - { - case 0: - LEAVE_RET('i', 1); + case 4: + if( !CheckMem( Data, sizeof(tIPv4) ) ) LEAVE_RET('i', -1); + tmp = IPv4_Ping(iface, *(tIPv4*)Data); + LEAVE('i', tmp); + return tmp; - case 4: - if( !CheckMem( Data, sizeof(tIPv4) ) ) LEAVE_RET('i', -1); - iface->Type = 0; // One very hacky mutex/trash protector - memcpy( &iface->IP4.Gateway, Data, sizeof(tIPv4) ); - iface->Type = 4; - LEAVE_RET('i', 1); - - case 6: - LEAVE_RET('i', 1); - } - LEAVE_RET('i', 0); + case 6: + LEAVE_RET('i', 1); } + break; + } LEAVE('i', 0); @@ -425,6 +480,9 @@ int IPStack_AddInterface(char *Device) iface->Node.FindDir = NULL; iface->Node.IOCtl = IPStack_IOCtl; + // Set Defaults + iface->TimeoutDelay = DEFAULT_TIMEOUT; + // Get adapter handle iface->Adapter = IPStack_GetAdapter(Device); if( !iface->Adapter ) {