diff --git a/XFX.sln b/XFX.sln
index b55d17f..1cffc00 100644
--- a/XFX.sln
+++ b/XFX.sln
@@ -21,7 +21,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libSystem.Windows", "src\li
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xnbbuild", "src\xnbbuild\xnbbuild.vcxproj", "{E5F1599D-C9FE-4EFB-97B6-13B46D4A1E35}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsocket", "libsocket\libsocket.vcxproj", "{FC85E968-A227-460F-858B-06A3581A65E0}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsocket", "src\libsocket\libsocket.vcxproj", "{FC85E968-A227-460F-858B-06A3581A65E0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/include/System/Types.h b/include/System/Types.h
index fbd12e9..a8837e8 100644
--- a/include/System/Types.h
+++ b/include/System/Types.h
@@ -40,6 +40,9 @@ namespace System
#define __attribute__(x)
#endif
+// Structure packing
+#define PACKED __attribute__((packed))
+
// Aligning Data types
//
#define ALIGNED4 __attribute__((aligned (4)))
@@ -54,4 +57,6 @@ namespace System
#define NONNULL(x...) __attribute__((nonnull(x)))
#endif
+#define DEPRECATED __attribute__((deprecated))
+
#endif //_SYSTEM_TYPES_
diff --git a/libsocket/libsocket.vcxproj b/src/libsocket/libsocket.vcxproj
similarity index 72%
rename from libsocket/libsocket.vcxproj
rename to src/libsocket/libsocket.vcxproj
index 272b019..37a2797 100644
--- a/libsocket/libsocket.vcxproj
+++ b/src/libsocket/libsocket.vcxproj
@@ -37,7 +37,12 @@
libsocket.a
- WIN32;_DEBUG;$(NMakePreprocessorDefinitions)
+ ENABLE_XBOX
+ C:\cygwin\usr\local\openxdk\include;C:\cygwin\usr\local\openxdk\i386-pc-xbox\include;C:\cygwin\usr\local\openxdk\include\SDL;..\..\include;$(NMakeIncludeSearchPath)
+ make all 2>&1 | sed -e %27s/\(\w\+\):\([0-9]\+\):/\1(\2):/%27
+ make rebuild 2>&1 | sed -e %27s/\(\w\+\):\([0-9]\+\):/\1(\2):/%27
+ make clean 2>&1 | sed -e %27s/\(\w\+\):\([0-9]\+\):/\1(\2):/%27
+ C:\cygwin\usr\include;C:\cygwin\usr\local\openxdk\i386-pc-xbox\include;C:\cygwin\usr\local\openxdk\include;C:\cygwin\usr\local\openxdk\include\SDL;$(SolutionDir)include
libsocket.a
@@ -47,7 +52,9 @@
+
+
@@ -55,11 +62,19 @@
+
+
+
+
+
+
+
+
diff --git a/libsocket/libsocket.vcxproj.filters b/src/libsocket/libsocket.vcxproj.filters
similarity index 72%
rename from libsocket/libsocket.vcxproj.filters
rename to src/libsocket/libsocket.vcxproj.filters
index 4c21f62..d8261bc 100644
--- a/libsocket/libsocket.vcxproj.filters
+++ b/src/libsocket/libsocket.vcxproj.filters
@@ -54,5 +54,31 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
\ No newline at end of file
diff --git a/libsocket/src/addr2ascii.c b/src/libsocket/src/addr2ascii.c
similarity index 100%
rename from libsocket/src/addr2ascii.c
rename to src/libsocket/src/addr2ascii.c
diff --git a/src/libsocket/src/arp.c b/src/libsocket/src/arp.c
new file mode 100644
index 0000000..ac58246
--- /dev/null
+++ b/src/libsocket/src/arp.c
@@ -0,0 +1,116 @@
+/*
+** Copyright 2001, Travis Geiselbrecht. All rights reserved.
+** Distributed under the terms of the NewOS License.
+*/
+/*
+ * Copyright (c) 2008 Travis Geiselbrecht
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include
+
+#include
+
+#include "ethernet.h"
+
+#define MIN_ARP_SIZE 28
+
+
+typedef struct arp_packet {
+ uint16_t hard_type;
+ uint16_t prot_type;
+ uint8_t hard_size;
+ uint8_t prot_size;
+ uint16_t op;
+ ethernet_addr sender_ethernet;
+ ipv4_addr sender_ipv4;
+ ethernet_addr target_ethernet;
+ ipv4_addr target_ipv4;
+} PACKED arp_packet;
+
+enum
+{
+ ARP_OP_REQUEST = 1,
+ ARP_OP_REPLY,
+ ARP_OP_RARP_REQUEST,
+ ARP_OP_RARP_REPLY
+};
+
+enum
+{
+ ARP_HARD_TYPE_ETHERNET = 1
+};
+
+typedef struct arp_cache_entry
+{
+ struct arp_cache_entry *next;
+ struct arp_cache_entry *all_next;
+ ipv4_addr ip_addr;
+ netaddr link_addr;
+ time_t last_used_time;
+} arp_cache_entry;
+
+// arp cache
+static void *arp_table;
+static mutex_t arp_table_mutex;
+static arp_cache_entry *arp_cache_entries;
+
+typedef struct arp_wait_request
+{
+ struct arp_wait_request *next;
+ ipv4_addr sender_ipaddr;
+ ipv4_addr ip_addr;
+ time_t last_attempt_time;
+ int attempt_count;
+ void (*callback)(int code, void *, ifnet *, netaddr *);
+ void *callback_args;
+ ifnet *i;
+} arp_wait_request;
+
+// list of threads blocked on arp requests
+static arp_wait_request *arp_waiters;
+static mutex_t arp_wait_mutex;
+static event_t arp_wait_event;
+
+static int arp_cache_compare(void *_e, const void *_key)
+{
+ arp_cache_entry *e = (arp_cache_entry *)_e;
+ const ipv4_addr *addr = (const ipv4_addr *)_key;
+
+ return (e->ip_addr == *addr) ? 0 : 1;
+}
+
+static unsigned int arp_cache_hash(void *_e, const void *_key, unsigned int range)
+{
+ arp_cache_entry *e = (arp_cache_entry *)_e;
+ const ipv4_addr *key = (const ipv4_addr *)_key;
+ const ipv4_addr *addr;
+
+ if(e)
+ addr = &e->ip_addr;
+ else
+ addr = key;
+
+ // XXX make this smarter
+ return ((*addr) ^ (*addr >> 8) ^ (*addr >> 16) ^ (*addr >> 24)) % range;
+}
+
+
diff --git a/libsocket/src/ascii2addr.c b/src/libsocket/src/ascii2addr.c
similarity index 100%
rename from libsocket/src/ascii2addr.c
rename to src/libsocket/src/ascii2addr.c
diff --git a/src/libsocket/src/cbuf.h b/src/libsocket/src/cbuf.h
new file mode 100644
index 0000000..13e73b4
--- /dev/null
+++ b/src/libsocket/src/cbuf.h
@@ -0,0 +1,80 @@
+/*
+** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
+** Distributed under the terms of the NewOS License.
+*/
+/*
+ * Copyright (c) 2008 Travis Geiselbrecht
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _LIB_NET_CBUF_H
+#define _LIB_NET_CBUF_H
+
+#include
+
+#define CBUF_LEN 2048
+
+#define CBUF_FLAG_CHAIN_HEAD 1
+#define CBUF_FLAG_CHAIN_TAIL 2
+
+typedef struct cbuf {
+ struct cbuf *next;
+ size_t len;
+ size_t total_len;
+ void *data;
+ int flags;
+
+ /* used by the network stack to chain a list of these together */
+ struct cbuf *packet_next;
+
+ char dat[CBUF_LEN - 2*sizeof(struct cbuf *) - 2*sizeof(size_t) - sizeof(void *) - sizeof(int)];
+} cbuf;
+
+int cbuf_init(void);
+cbuf *cbuf_get_chain(size_t len);
+cbuf *cbuf_get_chain_noblock(size_t len);
+void cbuf_free_chain_noblock(cbuf *buf);
+void cbuf_free_chain(cbuf *buf);
+
+size_t cbuf_get_len(cbuf *buf);
+void *cbuf_get_ptr(cbuf *buf, size_t offset);
+int cbuf_is_contig_region(cbuf *buf, size_t start, size_t end);
+
+int cbuf_memcpy_to_chain(cbuf *chain, size_t offset, const void *_src, size_t len);
+int cbuf_memcpy_from_chain(void *dest, cbuf *chain, size_t offset, size_t len);
+
+int cbuf_user_memcpy_to_chain(cbuf *chain, size_t offset, const void *_src, size_t len);
+int cbuf_user_memcpy_from_chain(void *dest, cbuf *chain, size_t offset, size_t len);
+
+uint16_t cbuf_ones_cksum16(cbuf *chain, size_t offset, size_t len);
+uint16_t cbuf_ones_cksum16_2(cbuf *chain, size_t offset, size_t len, void *buf, size_t buf_len);
+
+cbuf *cbuf_merge_chains(cbuf *chain1, cbuf *chain2);
+cbuf *cbuf_duplicate_chain(cbuf *chain, size_t offset, size_t len, size_t leading_space);
+
+cbuf *cbuf_truncate_head(cbuf *chain, size_t trunc_bytes, bool free_unused);
+int cbuf_truncate_tail(cbuf *chain, size_t trunc_bytes, bool free_unused);
+
+int cbuf_extend_head(cbuf **chain, size_t extend_bytes);
+int cbuf_extend_tail(cbuf *chain, size_t extend_bytes);
+
+void cbuf_test(void);
+
+#endif
diff --git a/src/libsocket/src/detect_ping.c b/src/libsocket/src/detect_ping.c
new file mode 100644
index 0000000..3d3a686
--- /dev/null
+++ b/src/libsocket/src/detect_ping.c
@@ -0,0 +1,269 @@
+//Ping detection (it detects incoming pings, but does not reply to them -only arp-)
+//Write here your xbox ip address
+//(first 3 numbers should match your PC IP address, last one must be unique on your network)
+#define MY_IP_ADDRESS "192.168.0.10"
+
+#include
+#include
+#include
+#include
+
+#include
+#include "string.h"
+#include "stdio.h"
+#include
+
+#include "memory.h"
+
+#include "pktdrv.h"
+
+
+
+struct _arp
+{
+ //ethernet header (14 bytes)
+ unsigned char EthDst[6]; //0xFFFFFFFFFFFF=any (broadcast)
+ unsigned char EthSrc[6];
+ unsigned short ProtocolType; //0x0608 (0x08 then 0x06)=IP ARP
+ //arp header (2+2+1+1+2+6+4+6+4=28 bytes)
+ unsigned short Hardware; //0x0100 (0x00 then 0x01)=Ethernet (10Mbps)
+ unsigned short Protocol; //0x0008 (0x08 then 0x00)=IP
+ unsigned char HardwareAddrLen; //6 (bytes)
+ unsigned char ProtocolAddrLen; //4 (bytes)
+ unsigned short Operation; //0x0100 (0x00 then 0x01)=Request 0x0200=Answer
+ unsigned char SenderHardwareAddr[6];
+ unsigned char SenderProtocolAddr[4]; //Sender IP address
+ unsigned char TargetHardwareAddr[6]; //0 if not known yet
+ unsigned char TargetProtocolAddr[4]; //Target IP address
+};
+
+struct _ip
+{
+ //ethernet header (14 bytes)
+ unsigned char EthDst[6]; //0xFFFFFFFFFFFF=any (broadcast)
+ unsigned char EthSrc[6];
+ unsigned short ProtocolType; //0x0008 (0x08 then 0x00)=IP
+ //ip header (8 bytes)
+ unsigned char Version:4; //4 bits, value 4
+ unsigned char HeaderLength:4; //4 bits, value 5 (means 20 bytes)
+ unsigned char DifferentiatedServices; //0
+ unsigned short TotalLength; //0x2000 (0x00 then 0x20)=32 bytes
+ unsigned short Identifier; //Variant
+ unsigned short FragmentationFlagOffset;//0
+ unsigned char TimeToLive; //128
+ unsigned char Protocol; //1 = ICMP (Internet Control Message Protocol)
+ unsigned short HeaderChecksum; //Variant
+ unsigned char SrcIPAddr[4]; //Sender IP address
+ unsigned char DstIPAddr[4]; //Target IP address
+ //icmp sub-protocol
+ unsigned char ICMPType; //8 = Echo request
+ unsigned char ICMPCode; //0
+ unsigned short Checksum; //Variant
+ unsigned short ID; //Variant
+ unsigned short SequenceNumber; //0 then increments with retries
+ unsigned char ICMPDataArea[18];
+};
+
+static unsigned long counter=0;
+static unsigned int packetsize=0;
+static unsigned char *packetbuffer;
+
+unsigned long myipaddress;
+
+void report(void)
+{
+ int i;
+ unsigned char *p;
+ struct _arp *parp;
+ struct _ip *pip;
+
+ debugPrint("Received packets : %ld\n",counter);
+ debugPrint("Last received packet size : %d bytes\n",packetsize);
+ if (packetsize<100)
+ {
+
+ p=packetbuffer;
+ for(i=0;iProtocolType==0x0608)&&
+ (parp->Operation==0x100) )
+ debugPrint("It was an ARP request from %d.%d.%d.%d\n",
+ parp->SenderProtocolAddr[0],
+ parp->SenderProtocolAddr[1],
+ parp->SenderProtocolAddr[2],
+ parp->SenderProtocolAddr[3]);
+
+ pip=(struct _ip *)packetbuffer;
+ if ( (pip->ProtocolType==0x0008)&&
+ (pip->Protocol==1)&&
+ (pip->ICMPType==8) )
+ debugPrint("It was a Ping request from %d.%d.%d.%d!\nPktdrv worked!\n",
+ pip->SrcIPAddr[0],
+ pip->SrcIPAddr[1],
+ pip->SrcIPAddr[2],
+ pip->SrcIPAddr[3]);
+
+ }
+}
+
+int Pktdrv_Callback(unsigned char *packetaddr, unsigned int size)
+{
+ //We are either called from a Dpc (if line uncommented in MyPktdrvDpc)
+ //or from our own code (no need to be reentrant)
+
+ counter++;
+ packetsize=size;
+ memcpy(packetbuffer,packetaddr,packetsize);
+
+ return 1; //we declare we have taken the packet (reply 0 if you want keep it for later)
+}
+
+void process_last_packet(void)
+{
+ struct _ip *pip;
+ struct _arp *parp;
+
+ parp = (struct _arp *)packetbuffer;
+
+ if ((parp->ProtocolType == 0x608) && (parp->Operation == 0x100))
+ {
+ // It's an ARP request
+ unsigned char tmp[4];
+ unsigned long ltmp;
+
+ memcpy(tmp,parp->TargetProtocolAddr,4);
+ ltmp = *((unsigned long *)tmp);
+
+ // Are we the target?
+ if (ltmp == myipaddress)
+ {
+ // Yes, build up an ARP response (invert src and dst)
+ memcpy(parp->EthDst,parp->EthSrc,6);
+ Pktdrv_GetEthernetAddr(parp->EthSrc);
+ parp->Operation=0x200;
+ memcpy(parp->TargetHardwareAddr,parp->SenderHardwareAddr,6);
+ Pktdrv_GetEthernetAddr(parp->SenderHardwareAddr);
+ memcpy(parp->TargetProtocolAddr,parp->SenderProtocolAddr,4);
+ memcpy(parp->SenderProtocolAddr,tmp,4);
+
+ debugPrint("Answering to ARP request now!\n");
+
+ // As a rule, always wait until number of packet not yet sent goes
+ // below the number of buffers -ring- you are using to send them
+ while (Pktdrv_GetQueuedTxPkts() >= 1) { /*wait*/ };
+
+ // In this sample we only send a reply to a request. It never waits.
+ Pktdrv_SendPacket(packetbuffer,14+28);
+ }
+ }
+
+ pip = (struct _ip *)packetbuffer;
+ if ((pip->ProtocolType == 0x0008) &&
+ (pip->Protocol == 1) &&
+ (pip->ICMPType == 8))
+ {
+ // It's a Ping request (an IP packet with a ICMP Echo request inside)
+ unsigned char tmp[4];
+ unsigned long ltmp;
+
+ memcpy(tmp,pip->DstIPAddr,4);
+ ltmp = *((unsigned long *)tmp);
+
+ // Are we the target?
+ if (ltmp == myipaddress)
+ {
+ debugPrint("It's a Ping request from %d.%d.%d.%d!\nPktdrv is working!\n",
+ pip->SrcIPAddr[0],
+ pip->SrcIPAddr[1],
+ pip->SrcIPAddr[2],
+ pip->SrcIPAddr[3]);
+ //Here we should build up an answer to the ping request
+ //Do it yourself as an exercise...
+ //Caution checksums are tricky to calculate...
+ }
+ }
+}
+
+void XBoxStartup(void)
+{
+ int i,v,n,done=0;
+ char *p;
+ unsigned char *p2;
+
+ packetbuffer = (unsigned char *)MmAllocateContiguousMemoryEx(
+ 1520,
+ 0, //lowest acceptable
+ 0xFFFFFFFF, //highest acceptable
+ 0, //no need to align to specific boundaries multiple
+ 4); //non cached, non ordered
+ if (!packetbuffer) return; //don't waste my time!
+
+ // convert IP address string into an unsigned long
+ p = MY_IP_ADDRESS;
+ p2 = (unsigned char *)&myipaddress;
+
+ for (i = 0, n = 0, v = 0; i < strlen(p) + 1; i++)
+ {
+ if (isdigit(p[i]))
+ v = v * 10 + p[i] - '0';
+ else
+ if ((p[i] == '.') || (p[i] == '\0'))
+ {
+ *p2 = (unsigned char)(v&255);
+ v = 0;
+ p2++;
+ n++;
+ if (n == 4) break;
+ }
+ }
+
+ XInput_Init();
+
+ if (Pktdrv_Init())
+ {
+ debugPrint("Try to ping your XBOX!\n");
+ debugPrint("Press A to show statistics\n");
+ debugPrint("Press B to stop program\n");
+
+ while(!done)
+ {
+ //When a ping will come, we will receive an ARP then an IP
+ //-ARP will ask who has the requested ip address on network
+ //-We will reply and that will give sender our MAC Address
+ //-The ping itself (an IP packet) will then come
+
+ if (Pktdrv_ReceivePackets())
+ {
+ //We received at least 1 packet. Process last received packet.
+ process_last_packet();
+ }
+
+ XInput_GetEvents();
+
+ for (i = 0; i < 4; i++)
+ {
+ if(g_Pads[i].PressedButtons.ucAnalogButtons[XPAD_A]) report();
+ if(g_Pads[i].PressedButtons.ucAnalogButtons[XPAD_B]) done = 1;
+ }
+ };
+
+ Pktdrv_Quit();
+ }
+ else
+ debugPrint("Couldn't initialize network packet driver\n");
+
+ XInput_Quit();
+
+ MmFreeContiguousMemory(packetbuffer);
+
+ debugPrint("Quitting...\n");
+ XSleep(5000);
+ XReboot();
+}
diff --git a/src/libsocket/src/ethernet.h b/src/libsocket/src/ethernet.h
new file mode 100644
index 0000000..857c7cc
--- /dev/null
+++ b/src/libsocket/src/ethernet.h
@@ -0,0 +1,52 @@
+/*
+** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
+** Distributed under the terms of the NewOS License.
+*/
+/*
+ * Copyright (c) 2008 Travis Geiselbrecht
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _LIB_NET_ETHERNET_H
+#define _LIB_NET_ETHERNET_H
+
+#include
+
+#include "if.h"
+#include "cbuf.h"
+
+#define PROT_TYPE_IPV4 0x0800
+#define PROT_TYPE_ARP 0x0806
+
+#define ETHERNET_HEADER_SIZE (6+6+2)
+#define ETHERNET_MAX_SIZE (ETHERNET_HEADER_SIZE+1500)
+#define ETHERNET_MIN_SIZE (ETHERNET_HEADER_SIZE+46)
+
+typedef uint8_t ethernet_addr[6];
+
+// not to be called directly, use the ifnet.link_output and link_input
+int ethernet_input(cbuf *buf, ifnet *i);
+int ethernet_output(cbuf *buf, ifnet *i, netaddr *target, int protocol_type);
+
+int ethernet_init(void);
+
+void dump_ethernet_addr(ethernet_addr addr);
+
+#endif
diff --git a/src/libsocket/src/if.h b/src/libsocket/src/if.h
new file mode 100644
index 0000000..ee3f570
--- /dev/null
+++ b/src/libsocket/src/if.h
@@ -0,0 +1,93 @@
+/*
+** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
+** Distributed under the terms of the NewOS License.
+*/
+/*
+ * Copyright (c) 2008 Travis Geiselbrecht
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _LIB_NET_IF_H
+#define _LIB_NET_IF_H
+
+#include
+#include "net.h"
+#include
+#include
+#include
+#include
+#include
+
+typedef struct ifaddr
+{
+ struct ifaddr *next;
+ struct ifnet *if_owner;
+ netaddr addr;
+ netaddr netmask;
+ netaddr broadcast;
+} ifaddr;
+
+enum
+{
+ IF_TYPE_NULL = 0,
+ IF_TYPE_LOOPBACK,
+ IF_TYPE_ETHERNET
+};
+
+typedef struct ifhook
+{
+ int type;
+ size_t mtu;
+ netaddr linkaddr;
+ void *cookie;
+ int (*if_input)(void *cookie, void *buf, size_t len);
+ int (*if_output)(void *cookie, const void *buf, size_t len);
+} ifhook;
+
+typedef int if_id;
+
+typedef struct ifnet
+{
+ struct ifnet *next;
+ const ifhook *hook;
+ if_id id;
+ int type;
+ thread_t *rx_thread;
+ thread_t *tx_thread;
+ ifaddr *addr_list;
+ ifaddr *link_addr;
+ int (*link_input)(cbuf *buf, struct ifnet *i);
+ int (*link_output)(cbuf *buf, struct ifnet *i, netaddr *target, int protocol_type);
+ event_t tx_queue_event;
+ mutex_t tx_queue_lock;
+ fixed_queue tx_queue;
+ uint8_t tx_buf[2048];
+ uint8_t rx_buf[2048];
+} ifnet;
+
+int if_init(void);
+ifnet *if_id_to_ifnet(if_id id);
+int if_register_interface(const ifhook *hook, ifnet **i);
+void if_bind_address(ifnet *i, ifaddr *addr);
+void if_bind_link_address(ifnet *i, ifaddr *addr);
+int if_boot_interface(ifnet *i);
+int if_output(cbuf *b, ifnet *i);
+
+#endif
diff --git a/libsocket/src/inet_addr.c b/src/libsocket/src/inet_addr.c
similarity index 100%
rename from libsocket/src/inet_addr.c
rename to src/libsocket/src/inet_addr.c
diff --git a/libsocket/src/inet_lnaof.c b/src/libsocket/src/inet_lnaof.c
similarity index 100%
rename from libsocket/src/inet_lnaof.c
rename to src/libsocket/src/inet_lnaof.c
diff --git a/libsocket/src/inet_makeaddr.c b/src/libsocket/src/inet_makeaddr.c
similarity index 100%
rename from libsocket/src/inet_makeaddr.c
rename to src/libsocket/src/inet_makeaddr.c
diff --git a/libsocket/src/inet_net_ntop.c b/src/libsocket/src/inet_net_ntop.c
similarity index 100%
rename from libsocket/src/inet_net_ntop.c
rename to src/libsocket/src/inet_net_ntop.c
diff --git a/libsocket/src/inet_net_pton.c b/src/libsocket/src/inet_net_pton.c
similarity index 100%
rename from libsocket/src/inet_net_pton.c
rename to src/libsocket/src/inet_net_pton.c
diff --git a/libsocket/src/inet_ntoa.c b/src/libsocket/src/inet_ntoa.c
similarity index 100%
rename from libsocket/src/inet_ntoa.c
rename to src/libsocket/src/inet_ntoa.c
diff --git a/src/libsocket/src/net.h b/src/libsocket/src/net.h
new file mode 100644
index 0000000..7bb73ad
--- /dev/null
+++ b/src/libsocket/src/net.h
@@ -0,0 +1,76 @@
+/*
+** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
+** Distributed under the terms of the NewOS License.
+*/
+/*
+ * Copyright (c) 2008 Travis Geiselbrecht
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _LIB_NET_NET_H
+#define _LIB_NET_NET_H
+
+#include
+
+int net_init(void);
+int net_init_postdev(void);
+
+#define NET_CHATTY 0
+
+/* common net stuff */
+typedef struct netaddr {
+ uint8_t len;
+ uint8_t type;
+ uint8_t pad0;
+ uint8_t pad1;
+ uint8_t addr[12];
+} netaddr;
+
+enum {
+ SOCK_PROTO_NULL = 0,
+ SOCK_PROTO_UDP,
+ SOCK_PROTO_TCP
+};
+
+enum {
+ ADDR_TYPE_NULL = 0,
+ ADDR_TYPE_ETHERNET,
+ ADDR_TYPE_IP
+};
+
+#define SOCK_FLAG_TIMEOUT 1
+
+typedef struct sockaddr {
+ netaddr addr;
+ int port;
+} sockaddr;
+
+enum {
+ IP_PROT_ICMP = 1,
+ IP_PROT_TCP = 6,
+ IP_PROT_UDP = 17,
+};
+
+typedef uint32_t ipv4_addr;
+#define NETADDR_TO_IPV4(naddr) (*(ipv4_addr *)(&((&(naddr))->addr[0])))
+#define IPV4_DOTADDR_TO_ADDR(a, b, c, d) \
+ (((ipv4_addr)(a) << 24) | (((ipv4_addr)(b) & 0xff) << 16) | (((ipv4_addr)(c) & 0xff) << 8) | ((ipv4_addr)(d) & 0xff))
+
+#endif
diff --git a/libsocket/src/nsap_addr.c b/src/libsocket/src/nsap_addr.c
similarity index 100%
rename from libsocket/src/nsap_addr.c
rename to src/libsocket/src/nsap_addr.c
diff --git a/src/libsocket/src/pktdrv.c b/src/libsocket/src/pktdrv.c
new file mode 100644
index 0000000..ac76635
--- /dev/null
+++ b/src/libsocket/src/pktdrv.c
@@ -0,0 +1,968 @@
+// XBOX low level network interface driver (packet driver)
+// =======================================================
+// Minimum capabilites : send and receive ethernet packets
+// Based on forcedeth Linux nForce driver
+
+// Ring of buffers for received packets is handled by driver.
+// Ring of buffers for sent packets must be handled by yourself.
+// Driver will only handle the ring of descriptors for them.
+// i.e Call Pktdrv_SendPacket with a buffer address taken among
+// your ring of n buffers in a circular way and always verify
+// that Pktdrv_GetQueuedTxPkts()
+#include
+#include
+
+#include "string.h"
+#include "stdio.h"
+#include
+#include
+
+#include "pktdrv.h"
+
+//#define DISPLAYMSG
+
+// Defines number of Rx & Tx descriptors, and number of buffers -ring- for received pkts
+#define NBBUFF 32
+
+extern unsigned long times(void *);
+
+// temporary dirty interface
+extern int something_to_send;
+extern unsigned char *packet_to_send;
+extern unsigned int size_of_packet_to_send;
+extern int Pktdrv_Callback(unsigned char *packetaddr, unsigned int packetsize);
+
+#define MIN(a,b) (((a) < (b))? (a) : (b))
+
+struct s_MyStructures
+{
+ char MyContext[1];
+ unsigned char NbrRxBuffersWithoutCheck;
+ unsigned char Ethaddr[6];
+ unsigned char Ethaddr2[6];
+ unsigned char Ethaddr_reversed[6];
+ KDPC MyPktdrvDpcObject;
+ ULONG PktdrvIsrCounter;
+ KIRQL IrqLevel;
+ ULONG Vector;
+ ULONG Speed;
+ ULONG OldPhyState;
+ ULONG PhysicalMinusVirtual; // = buffers_physaddr - buffers_addrs;
+ ULONG NbrRxBuffers;
+ ULONG RxBufferDesc; //= buffers_addr + 2048;
+ ULONG RxBufferTail; //= buffers_addr + 2048 + g_s->NbrRxBuffers * 8 - 8;
+ ULONG RxBufferNext; //= buffers_addr + 2048; //Point to next incoming packet entry
+ ULONG NbrTxBuffers;
+ ULONG TxBufferDesc; //= buffers_addr;
+ ULONG TxBufferLast; //= buffers_addr; //Points to last sent packet(s) to check
+ ULONG TxBufferNext; //= buffers_addr; //Points to next packet to send entry
+ ULONG TxBufferTail; //= buffers_addr + 8 * g_s->NbrTxBuffers - 8;
+ ULONG QueuedTxPkts;
+};
+
+static int g_running=0;
+static struct s_MyStructures *g_s;
+static KINTERRUPT s_MyInterruptObject;
+
+// Types and descriptions coming from
+// - ntddk.h (WinXP SP1 DDK)
+// - winddk.h (Reactos source)
+// - forcedeth.c (Linux NVidia nForce driver)
+
+/*
+ * Hardware registers:
+ */
+
+enum
+{
+ NvRegIrqStatus = 0x000,
+#define NVREG_IRQSTAT_BIT0EVENT 0x002
+#define NVREG_IRQSTAT_BIT1EVENT 0x004
+#define NVREG_IRQSTAT_BIT2EVENT 0x008
+#define NVREG_IRQSTAT_MIIEVENT 0x040
+#define NVREG_IRQSTAT_UNKEVENT 0x080
+#define NVREG_IRQSTAT_MASK 0x1FF
+
+ NvRegIrqMask = 0x004,
+#define NVREG_IRQ_RX_ERROR 0x0001
+#define NVREG_IRQ_RX 0x0002
+#define NVREG_IRQ_RX_NOBUF 0x0004
+#define NVREG_IRQ_TX_ERROR 0x0008
+#define NVREG_IRQ_TX_OK 0x0010
+#define NVREG_IRQ_TIMER 0x0020
+#define NVREG_IRQ_LINK 0x0040
+#define NVREG_IRQ_RX_FORCED 0x0080
+#define NVREG_IRQ_TX_FORCED 0x0100
+#define NVREG_IRQMASK_THROUGHPUT 0x00DF
+#define NVREG_IRQMASK_CPU 0x0040
+#define NVREG_IRQ_TX_ALL 0x0118
+//=(NVREG_IRQ_TX_ERROR|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_FORCED)
+#define NVREG_IRQ_RX_ALL 0x0087
+//=(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_RX_FORCED)
+#define NVREG_IRQ_OTHER 0x0060
+//=(NVREG_IRQ_TIMER|NVREG_IRQ_LINK)
+#define NVREG_IRQ_UNKNOWN 0x01FF
+//=(~
+// (
+// NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|
+// NVREG_IRQ_TX_ERROR|NVREG_IRQ_TX_OK|NVREG_IRQ_TIMER|
+// NVREG_IRQ_LINK|NVREG_IRQ_RX_FORCED|NVREG_IRQ_TX_FORCED
+// )
+// )
+
+ NvRegUnknownSetupReg6 = 0x008,
+#define NVREG_UNKSETUP6_VAL 3
+
+/*
+ * NVREG_POLL_DEFAULT is the interval length of the timer source on the Pktdrv
+ * NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms
+ */
+ NvRegPollingInterval = 0x00c,
+#define NVREG_POLL_DEFAULT_THROUGHPUT 970
+#define NVREG_POLL_DEFAULT_CPU 013
+
+ NvRegMSIMap0 = 0x020,
+ NvRegMSIMap1 = 0x024,
+ NvRegMSIIrqMask = 0x030,
+#define NVREG_MSI_VECTOR_0_ENABLED 0x001
+
+ NvRegMacReset = 0x03c,
+#define NVREG_MAC_RESET_ASSERT 0x0F3
+
+ NvRegDuplexMode = 0x080,
+#define NVREG_DUPLEX_MODE_HDFLAG 0x00000002
+#define NVREG_DUPLEX_MODE_FORCEF 0x003B0F3C
+#define NVREG_DUPLEX_MODE_FORCEH 0x003B0F3E
+#define NVREG_DUPLEX_MODE_FDMASK 0xFFFFFFFD
+
+ NvRegTransmitterControl = 0x084,
+#define NVREG_SendCTL_START 0x01
+
+ NvRegTransmitterStatus = 0x088,
+#define NVREG_SendSTAT_BUSY 0x01
+
+ NvRegPacketFilterFlags = 0x08c,
+#define NVREG_PFF_ALWAYS 0x7F0008
+#define NVREG_PFF_PROMISC 0x000080
+#define NVREG_PFF_MYADDR 0x000020
+#define NVREG_PFF_ALWAYS_MYADDR 0x7F0020
+
+ NvRegOffloadConfig = 0x090,
+#define NVREG_OFFLOAD_HOMEPHY 0x601
+#define NVREG_OFFLOAD_NORMAL 0x5EE
+
+ NvRegReceiverControl = 0x094,
+#define NVREG_RCVCTL_START 0x01
+
+ NvRegReceiverStatus = 0x098,
+#define NVREG_RCVSTAT_BUSY 0x01
+
+ NvRegRandomSeed = 0x09c,
+#define NVREG_RNDSEED_MASK 0x00FF
+#define NVREG_RNDSEED_FORCE 0x7F00
+#define NVREG_RNDSEED_FORCE2 0x2D00
+#define NVREG_RNDSEED_FORCE3 0x7400
+
+ NvRegUnknownSetupReg1 = 0x0A0,
+#define NVREG_UNKSETUP1_VAL 0x16070F
+ NvRegUnknownSetupReg2 = 0x0A4,
+#define NVREG_UNKSETUP2_VAL 0x16
+
+ NvRegMacAddrA = 0x0A8,
+ NvRegMacAddrB = 0x0AC,
+ NvRegMulticastAddrA = 0x0B0,
+#define NVREG_MCASTADDRA_FORCE 0x01
+ NvRegMulticastAddrB = 0x0B4,
+ NvRegMulticastMaskA = 0x0B8,
+ NvRegMulticastMaskB = 0x0BC,
+
+ NvRegPhyInterface = 0x0C0,
+#define PHY_RGMII 0x10000000
+
+ NvRegTxRingPhysAddr = 0x100,
+ NvRegRxRingPhysAddr = 0x104,
+ NvRegRingSizes = 0x108,
+#define NVREG_RINGSZ_TXSHIFT 0
+#define NVREG_RINGSZ_RXSHIFT 16
+
+ NvRegUnkTransmitterReg = 0x10c,
+
+ NvRegLinkSpeed = 0x110,
+#define NVREG_LINKSPEED_FORCE 0x10000
+#define NVREG_LINKSPEED_10MBPS 1000
+#define NVREG_LINKSPEED_100MBPS 100
+#define NVREG_LINKSPEED_1000MBPS 50
+#define NVREG_LINKSPEED_MASK 0xFFF
+
+ NvRegUnknownSetupReg5 = 0x130,
+#define NVREG_UNKSETUP5_BIT31 (1<<31)
+ NvRegUnknownSetupReg3 = 0x13C,
+#define NVREG_UNKSETUP3_VAL1 0x200010
+ NvRegUnknownSetupReg7 = 0x140,
+#define NVREG_UNKSETUP7_VAL1 0x300010
+
+ NvRegTxRxControl = 0x144,
+#define NVREG_TXRXCTL_KICK 0x0001
+#define NVREG_TXRXCTL_BIT1 0x0002
+#define NVREG_TXRXCTL_BIT2 0x0004
+#define NVREG_TXRXCTL_IDLE 0x0008
+#define NVREG_TXRXCTL_RESET 0x0010
+#define NVREG_TXRXCTL_RXCHECK 0x0400
+#define NVREG_TXRXCTL_DESC_1 0x0000
+#define NVREG_TXRXCTL_DESC_2 0x2100
+#define NVREG_TXRXCTL_DESC_3 0x2200
+#define NVREG_TXRXCTL_VLANSTRIP 0x0040
+#define NVREG_TXRXCTL_VLANINS 0x0080
+
+ NvRegTxRingPhysAddrHigh = 0x148,
+ NvRegRxRingPhysAddrHigh = 0x14C,
+ NvRegMIIStatus = 0x180,
+#define NVREG_MIISTAT_ERROR 0x0001
+#define NVREG_MIISTAT_LINKCHANGE 0x0008
+#define NVREG_MIISTAT_MASK 0x000F
+#define NVREG_MIISTAT_MASK2 0x000F
+
+ NvRegUnknownSetupReg4 = 0x184,
+#define NVREG_UNKSETUP4_VAL 8
+
+ NvRegAdapterControl = 0x188,
+#define NVREG_ADAPTCTL_START 0x02
+#define NVREG_ADAPTCTL_LINKUP 0x04
+#define NVREG_ADAPTCTL_PHYVALID 0x40000
+#define NVREG_ADAPTCTL_RUNNING 0x100000
+#define NVREG_ADAPTCTL_PHYSHIFT 24
+
+ NvRegMIISpeed = 0x18c,
+#define NVREG_MIISPEED_BIT8 (1<<8)
+#define NVREG_MIIDELAY 5
+ NvRegMIIControl = 0x190,
+#define NVREG_MIICTL_INUSE 0x08000
+#define NVREG_MIICTL_WRITE 0x00400
+#define NVREG_MIICTL_ADDRSHIFT 5
+ NvRegMIIData = 0x194,
+
+ NvRegWakeUpFlags = 0x200,
+#define NVREG_WAKEUPFLAGS_VAL 0x7770
+#define NVREG_WAKEUPFLAGS_BUSYSHIFT 24
+#define NVREG_WAKEUPFLAGS_ENABLESHIFT 16
+#define NVREG_WAKEUPFLAGS_D3SHIFT 12
+#define NVREG_WAKEUPFLAGS_D2SHIFT 8
+#define NVREG_WAKEUPFLAGS_D1SHIFT 4
+#define NVREG_WAKEUPFLAGS_D0SHIFT 0
+#define NVREG_WAKEUPFLAGS_ACCEPT_MAGPAT 0x01
+#define NVREG_WAKEUPFLAGS_ACCEPT_WAKEUPPAT 0x02
+#define NVREG_WAKEUPFLAGS_ACCEPT_LINKCHANGE 0x04
+#define NVREG_WAKEUPFLAGS_ENABLE 0x1111
+
+ NvRegPatternCRC = 0x204,
+ NvRegPatternMask = 0x208,
+
+ NvRegPowerCap = 0x268,
+#define NVREG_POWERCAP_D3SUPP (1<<30)
+#define NVREG_POWERCAP_D2SUPP (1<<26)
+#define NVREG_POWERCAP_D1SUPP (1<<25)
+ NvRegPowerState = 0x26c,
+#define NVREG_POWERSTATE_POWEREDUP 0x8000
+#define NVREG_POWERSTATE_VALID 0x0100
+#define NVREG_POWERSTATE_MASK 0x0003
+#define NVREG_POWERSTATE_D0 0x0000
+#define NVREG_POWERSTATE_D1 0x0001
+#define NVREG_POWERSTATE_D2 0x0002
+#define NVREG_POWERSTATE_D3 0x0003
+
+ NvRegVlanControl = 0x300,
+#define NVREG_VLANCONTROL_ENABLE 0x2000
+
+ NvRegMSIXMap0 = 0x3E0,
+ NvRegMSIXMap1 = 0x3E4,
+ NvRegMSIXIrqStatus = 0x3F0,
+
+ NvRegPowerState2 = 0x600,
+#define NVREG_POWERSTATE2_POWERUP_MASK 0x0F11
+#define NVREG_POWERSTATE2_POWERUP_REV_A3 0x0001
+};
+
+#define EEPROM_INDEX_MACADDR 0x101
+
+#define FLAG_MASK_V1 0xffff0000
+#define LEN_MASK_V1 (0xffffffff ^ FLAG_MASK_V1)
+
+#define NV_TX_LASTPACKET (1<<16)
+#define NV_TX_RETRYERROR (1<<19)
+#define NV_TX_FORCED_INTERRUPT (1<<24)
+#define NV_TX_DEFERRED (1<<26)
+#define NV_TX_CARRIERLOST (1<<27)
+#define NV_TX_LATECOLLISION (1<<28)
+#define NV_TX_UNDERFLOW (1<<29)
+#define NV_TX_ERROR (1<<30)
+#define NV_TX_VALID (1<<31)
+
+#define NV_RX_DESCRIPTORVALID (1<<16)
+#define NV_RX_MISSEDFRAME (1<<17)
+#define NV_RX_SUBSTRACT1 (1<<18)
+#define NV_RX_ERROR1 (1<<23)
+#define NV_RX_ERROR2 (1<<24)
+#define NV_RX_ERROR3 (1<<25)
+#define NV_RX_ERROR4 (1<<26)
+#define NV_RX_CRCERR (1<<27)
+#define NV_RX_OVERFLOW (1<<28)
+#define NV_RX_FRAMINGERR (1<<29)
+#define NV_RX_ERROR (1<<30)
+#define NV_RX_AVAIL (1<<31)
+
+// PhyGetLinkState
+#define PHY_LINK_RUNNING 0x01
+#define PHY_LINK_100MBPS 0x02
+#define PHY_LINK_10MBPS 0x04
+#define PHY_LINK_FULL_DUPLEX 0x08
+#define PHY_LINK_HALF_DUPLEX 0x10
+
+// Register access macros for XBOX
+#define BASE 0xFEF00000
+#define REG(x) (*((DWORD *)(BASE+(x))))
+#define REGW(x) (*((WORD *)(BASE+(x))))
+#define REGB(x) (*((BYTE *)(BASE+(x))))
+
+typedef enum _MEMORY_CACHING_TYPE_ORIG
+{
+ MmFrameBufferCached = 2
+} MEMORY_CACHING_TYPE_ORIG;
+
+typedef enum _MEMORY_CACHING_TYPE
+{
+ MmNonCached = 0,
+ MmCached = 1,
+ MmWriteCombined = MmFrameBufferCached,
+ MmHardwareCoherentCached,
+ MmNonCachedUnordered, // IA64
+ MmUSWCCached,
+ MmMaximumCacheType
+} MEMORY_CACHING_TYPE;
+/*
+ MmNonCached : The requested memory should not be cached by the processor.
+ MmCached : The processor should cache the requested memory.
+ MmWriteCombined : The requested memory should not be cached by the processor,
+ but writes to the memory can be combined by the processor.
+*/
+
+
+
+// Checks for possible received packets
+static int PktdrvRecvInterrupt(void)
+{
+ ULONG p;
+ ULONG flag;
+ BOOLEAN fatal;
+ int handled;
+ int n=0;
+
+ // Look for next entry in Rx ring and read its flag
+ while(1)
+ {
+ p = g_s->RxBufferNext;
+ flag = *((ULONG *)(p + 4));
+
+ if (flag & NV_RX_AVAIL) return n; //we received nothing!
+
+ if ((flag & NV_RX_DESCRIPTORVALID) == 0)
+ {
+ // Not a received packet
+ }
+ else
+ {
+ fatal = FALSE;
+
+ if (flag & NV_RX_ERROR)
+ {
+ if (flag & NV_RX_FRAMINGERR) { /* not fatal */ }
+ if (flag & NV_RX_OVERFLOW) { fatal = TRUE; }
+ if (flag & NV_RX_CRCERR) { fatal = TRUE; }
+ if (flag & NV_RX_ERROR4) { fatal = TRUE; }
+ if (flag & NV_RX_ERROR3) { fatal = TRUE; }
+ if (flag & NV_RX_ERROR2) { fatal = TRUE; }
+ if (flag & NV_RX_ERROR1) { fatal = TRUE; }
+ }
+
+ if (!fatal)
+ {
+ //Call user callback and warn that a packet has been received
+ //Phys Addr of packet is *p
+ //Length of packet is 1 up to 2046 bytes
+ //Length = ( (*((ULONG *)(p+4))) & 0x7FF ) + 1
+ handled = Pktdrv_Callback(
+ (unsigned char *)((*((ULONG *)p)) - g_s->PhysicalMinusVirtual),
+ (unsigned int)(((*((ULONG *)(p + 4))) & 0x7FF ) + 1 ));
+
+ if (!handled)
+ return n; //We probably lack space up there
+ else
+ n++;
+ }
+ }
+
+ //Empty the entry
+ *((ULONG *)(p + 4)) = NV_RX_AVAIL | 2045;
+
+ //Have RxBufferNext Point to next entry in ring
+ if (g_s->RxBufferNext == g_s->RxBufferTail) //return to start of ring?
+ g_s->RxBufferNext = g_s->RxBufferDesc;
+ else
+ g_s->RxBufferNext += 8;
+ };
+
+ return n;
+}
+
+// Detects if Tx ring is full or not
+static BOOLEAN PktdrvSendReady(void)
+{
+ return (g_s->QueuedTxPkts != g_s->NbrTxBuffers);
+}
+
+// Checks for a patcket to send
+static void PktdrvSendInterrupt(void)
+{
+ ULONG p, flag;
+
+ // Before we send any packet, let's check if last packets have been sent
+ while (g_s->TxBufferLast != g_s->TxBufferNext)
+ {
+ p = g_s->TxBufferLast;
+ flag = *((ULONG *)(p + 4));
+
+ if ((flag & NV_TX_VALID) == 0)
+ {
+ //Packet is gone, reduce counter and check next one.
+ //Note that errors and actual number of bytes sent
+ //can be read from flag right now and right here!
+ //Actual number is higher because of padding...
+ g_s->QueuedTxPkts--;
+
+ //Let's cleanup
+ *((ULONG *)p) = 0;
+ *((ULONG *)(p + 4)) = 0;
+
+ //Have TxBufferLast point to next entry
+ if (g_s->TxBufferLast == g_s->TxBufferTail)
+ g_s->TxBufferLast = g_s->TxBufferDesc;
+ else
+ g_s->TxBufferLast += 8;
+ }
+ else
+ break; //packet not sent already, we will check later
+ }
+}
+
+static void PktdrvSendPacket(unsigned char *buffer, int length)
+{
+ ULONG p;
+
+ if (PktdrvSendReady()) // Do we have room in the Tx ring?
+ {
+ // p points to next free entry of Tx ring descriptor
+ p = g_s->TxBufferNext;
+
+ MmLockUnlockBufferPages(
+ (ULONG)buffer,
+ length,
+ 0);
+
+ *((ULONG *)p) = MmGetPhysicalAddress(buffer);
+ *((ULONG *)(p + 4)) = (length-1) | NV_TX_VALID | NV_TX_LASTPACKET;
+
+ g_s->QueuedTxPkts++;
+
+ //Have TxBufferNext point to next entry
+ if (g_s->TxBufferNext == g_s->TxBufferTail) //return to start of ring?
+ g_s->TxBufferNext = g_s->TxBufferDesc;
+ else
+ g_s->TxBufferNext += 8;
+
+ REG(NvRegTxRxControl) = NVREG_TXRXCTL_KICK;
+ }
+ else
+ {
+ //Tx ring is full
+ //User should do : while(Xnet_GetQueuedPkts()>=n) { /*wait*/ }; then send pkt
+ //That will prevent the loss of sent packet right here
+ //Where n is the number of buffers (ring) where pending outcoming packets are
+ //stored. In most case n=1 (just one buffer is used to send 1 packet at a time)
+ }
+}
+
+// Starts Pktdrv
+static void PktdrvStartSendRecv(void)
+{
+ REG(NvRegLinkSpeed) = NVREG_LINKSPEED_FORCE | g_s->Speed;
+
+ REG(NvRegTransmitterControl) = NVREG_SendCTL_START;
+ REG(NvRegReceiverControl) = NVREG_RCVCTL_START;
+
+ REG(NvRegTxRxControl) = NVREG_TXRXCTL_KICK | NVREG_TXRXCTL_BIT1;
+}
+
+//Stops Pktdrv
+static void PktdrvStopSendRecv(void)
+{
+ int i;
+
+ REG(NvRegLinkSpeed) = 0;
+ REG(NvRegReceiverControl) = 0;
+ REG(NvRegTransmitterControl) = 0;
+
+ for (i = 0; i < 500; i++)
+ {
+ if (((REGB(NvRegReceiverStatus) & NVREG_RCVSTAT_BUSY) == 0) &&
+ ((REGB(NvRegTransmitterStatus) & NVREG_SendSTAT_BUSY) == 0))
+ break;
+
+ KeStallExecutionProcessor(10); //Wait 10 microseconds
+ }
+
+ REG(NvRegTxRxControl) = NVREG_TXRXCTL_BIT2;
+
+ for (i = 0; i < 100000; i++)
+ {
+ if (REGB(NvRegTxRxControl) & NVREG_TXRXCTL_IDLE) break;
+
+ KeStallExecutionProcessor(10);
+ }
+
+ REG(NvRegTxRxControl) = 0;
+}
+
+// Resets Pktdrv
+static void PktdrvReset(void)
+{
+ PktdrvStopSendRecv();
+
+ REG(NvRegTxRxControl) = NVREG_TXRXCTL_RESET;
+ KeStallExecutionProcessor(10); // 10 microseconds of busy-wait
+
+ REG(NvRegTxRxControl) = 0;
+ KeStallExecutionProcessor(10);
+
+ REG(NvRegUnknownSetupReg4) = 0;
+ REG(NvRegIrqMask) = 0;
+ REG(NvRegWakeUpFlags) = 0;
+ REG(NvRegUnknownSetupReg6) = 0;
+ REG(NvRegTxRingPhysAddr) = 0;
+ REG(NvRegRxRingPhysAddr) = 0;
+ REG(NvRegUnkTransmitterReg) = 0;
+ REG(NvRegLinkSpeed) = 0;
+
+ REG(NvRegTransmitterStatus) = REG(NvRegTransmitterStatus);
+ REG(NvRegReceiverStatus) = REG(NvRegReceiverStatus);
+ REG(NvRegMIIStatus) = REG(NvRegMIIStatus);
+ REG(NvRegIrqStatus) = REG(NvRegIrqStatus);
+}
+
+// Checks possible speed or duplex mode change
+static void PktdrvMiiInterrupt(int mode)
+{
+ // Verifies if speed or duplex mode changed
+ // mode=1 -> startup mode (calls PhyGetLinkState(0))
+ // (used at startup, before Pktdrv driver is started)
+ // mode=0 -> running mode (calls PhyGetLinkState(1))
+ // (used in interrupt, while Pktdrv driver is running)
+ ULONG state,dummy;
+
+ mode &= 1; // only 0 or 1 is accepted
+ dummy = REG(NvRegAdapterControl); // just read it
+ state = PhyGetLinkState(1 - mode);
+
+ if ((mode == 0) && (state == g_s->OldPhyState)) return; // All is ok, remain silent
+
+ //We want details (startup) or state changed (both modes)
+#ifdef DISPLAYMSG
+ debugPrint("Transceiver link state :\n");
+
+ if (state & PHY_LINK_RUNNING)
+ debugPrint(" Running at ");
+ else
+ debugPrint(" NOT running at ");
+
+ if (state & PHY_LINK_100MBPS)
+ debugPrint("100 Mbps ");
+ else
+ if (state & PHY_LINK_10MBPS)
+ debugPrint("10 Mbps ");
+ else
+ debugPrint("unknown speed ");
+
+ if (state & PHY_LINK_FULL_DUPLEX)
+ debugPrint("in full duplex mode\n");
+ else
+ if (state & PHY_LINK_HALF_DUPLEX)
+ debugPrint("in half duplex mode\n");
+ else
+ debugPrint("in unknown duplex mode\n");
+#endif
+ if (mode == 0) PktdrvStopSendRecv(); // Pktdrv is running. Stop it.
+
+ if (state & PHY_LINK_10MBPS) // update Speed member in structure
+ g_s->Speed = NVREG_LINKSPEED_10MBPS; // decimal value 1000!!!
+ else
+ g_s->Speed = NVREG_LINKSPEED_100MBPS; // decimal value 100
+
+ if (state & PHY_LINK_FULL_DUPLEX) // update mode in Pktdrv register
+ REG(NvRegDuplexMode) &= NVREG_DUPLEX_MODE_FDMASK;
+ else
+ REG(NvRegDuplexMode) |= NVREG_DUPLEX_MODE_HDFLAG;
+
+ if (mode == 0) PktdrvStartSendRecv(); // Mode changed. Restart Pktdrv.
+ // This function will read g_s->Speed and program speed link register.
+
+ g_s->OldPhyState = state;
+}
+
+static BOOLEAN __stdcall MyPktdrvIsr(PKINTERRUPT Interrupt, PVOID ServiceContext)
+{
+ REG(NvRegIrqMask) = 0;
+
+ if (g_running)
+ {
+ KeInsertQueueDpc(&g_s->MyPktdrvDpcObject,NULL,NULL);
+ g_s->PktdrvIsrCounter++;
+ }
+
+ return TRUE;
+}
+
+static void __stdcall MyPktdrvDpc
+(
+ PKDPC Dpc,
+ PVOID DeferredContext,
+ PVOID SystemArgument1,
+ PVOID SystemArgument2
+)
+{
+ // DPCs allow to use non reentrant procedures (called sequentially, FOR SURE).
+ // CAUTION : if you use fpu in DPC you have to save & restore yourself fpu state!!!
+ // (fpu=floating point unit, i.e the coprocessor executing floating point opcodes)
+
+ ULONG irq_status;
+ ULONG mii_status;
+
+ if (g_running == 0) return;
+
+ mii_status = 0;
+ irq_status = NVREG_IRQSTAT_BIT0EVENT |
+ NVREG_IRQSTAT_BIT1EVENT |
+ NVREG_IRQSTAT_BIT2EVENT |
+ NVREG_IRQSTAT_UNKEVENT;
+
+ while (irq_status)
+ {
+ if (irq_status & NVREG_IRQSTAT_MIIEVENT) PktdrvMiiInterrupt(0);
+ REG(NvRegMIIStatus) = mii_status;
+ REG(NvRegIrqStatus) = irq_status;
+//uncomment this line if you want your callback to be called as soon as packet arrived
+// PktdrvRecvInterrupt(); //Check if we received packets // (let them stock up)
+ PktdrvSendInterrupt(); //Check if we have a packet to send
+
+ if (irq_status & NVREG_IRQSTAT_BIT1EVENT)
+ {
+ REG(NvRegTxRxControl) = NVREG_TXRXCTL_BIT1;
+ }
+
+ mii_status = REG(NvRegMIIStatus);
+ irq_status = REG(NvRegIrqStatus);
+ };
+
+ REG(NvRegIrqMask) = NVREG_IRQ_LINK |
+ NVREG_IRQ_TX_OK |
+ NVREG_IRQ_TX_ERROR |
+ NVREG_IRQ_RX_NOBUF |
+ NVREG_IRQ_RX |
+ NVREG_IRQ_RX_ERROR;
+
+ return;
+}
+
+void Pktdrv_Quit(void)
+{
+ if (g_running == 0) return;
+
+ g_running = 0;
+
+ PktdrvStopSendRecv();
+ PktdrvReset();
+ KeDisconnectInterrupt(&s_MyInterruptObject);
+
+ MmFreeContiguousMemory((void *)g_s->TxBufferDesc);
+
+ free(g_s);
+}
+
+// Returns 1 if everything is ok
+int Pktdrv_Init(void)
+{
+ int n,len,type;
+ ULONG buffers_addr;
+ ULONG buffers_physaddr;
+ ULONG status;
+ ULONG buffers_total_size;
+ ULONG p,p2;
+ ULONG RandomValue;
+
+ if (g_running == 1) return 1;
+
+ g_s = (struct s_MyStructures *)malloc(sizeof(struct s_MyStructures));
+
+ // g_s holds the various needed structures
+ if (!g_s)
+ {
+ debugPrint("Can't allocate global structure.\n");
+ return 0;
+ }
+
+ g_s->Vector = HalGetInterruptVector(4,&g_s->IrqLevel);
+
+ KeInitializeDpc(&g_s->MyPktdrvDpcObject,&MyPktdrvDpc,&g_s->MyContext);
+
+ KeInitializeInterrupt(&s_MyInterruptObject,
+ &MyPktdrvIsr,
+ &g_s->MyContext,
+ g_s->Vector,
+ g_s->IrqLevel,
+ LevelSensitive,
+ TRUE);
+
+ PktdrvReset();
+
+ g_s->NbrRxBuffersWithoutCheck = NBBUFF; //Total buffers = NBBUFF+2 (Tx&Rx Descriptors)
+
+ n = g_s->NbrRxBuffersWithoutCheck;
+ g_s->NbrRxBuffers = MIN(n,256);
+ g_s->NbrTxBuffers = MIN(n,256);
+
+ //Rx ring will point to the pool of n allocated buffers
+ //Tx ring is empty at startup may point to any contiguous buffer physical address
+
+ buffers_total_size = ((n + 1 + 1) << 11);
+
+ //allocates n+1+1 DMA buffers 2048 bytes each
+ buffers_addr = (ULONG)MmAllocateContiguousMemoryEx(
+ buffers_total_size,
+ 0, //lowest acceptable
+ 0x10000, //highest acceptable
+ 0, //no need to align to specific boundaries multiple
+ MmNonCachedUnordered); //4
+
+ if (!buffers_addr)
+ buffers_addr=(ULONG)MmAllocateContiguousMemoryEx(
+ buffers_total_size,
+ 0, //lowest acceptable
+ 0xFFFFFFFF, //highest acceptable
+ 0, //no need to align to specific boundaries multiple
+ MmNonCachedUnordered); //4
+
+ if (!buffers_addr)
+ {
+ debugPrint("Can't allocate DMA reception buffers\n");
+
+ free(g_s);
+
+ return 0;
+ }
+
+ //Write zeroes in first buffer and second buffer (descriptors)
+ memset((void *)buffers_addr, 0, 4096);
+
+ buffers_physaddr = MmGetPhysicalAddress((void *)buffers_addr);
+
+ g_s->PhysicalMinusVirtual = buffers_physaddr - buffers_addr;
+
+ g_s->RxBufferDesc = buffers_addr + 2048;
+ g_s->RxBufferNext = buffers_addr + 2048;
+ g_s->RxBufferTail = buffers_addr + 2048 + g_s->NbrRxBuffers * 8 - 8;
+
+ g_s->TxBufferDesc = buffers_addr;
+ g_s->TxBufferLast = buffers_addr;
+ g_s->TxBufferNext = buffers_addr;
+ g_s->TxBufferTail = buffers_addr + 8 * g_s->NbrTxBuffers - 8;
+
+ p = buffers_addr + 4096 + 2 + g_s->PhysicalMinusVirtual; //Points 1st buffer at offset 2
+ p2 = buffers_addr + 2048;
+
+ while(p2 <= g_s->RxBufferTail)
+ {
+ *((DWORD *)p2) = p; //Physical address of offset 2 of buffer
+ *((DWORD *)(p2 + 4)) = NV_RX_AVAIL | 2045; //Makes all Rx buffers available
+ //2046 bytes available for incoming packet at offset 2
+ p2 += 8;
+ p += 2048;
+ };
+
+ //Buffers description :
+ //1st buffer is a list of n pointers+flags (every 8 bytes) and is Tx ring descriptor
+ //2nd buffer is a list of n pointers+flags (every 8 bytes) and is Rx ring descriptor
+ //3rd buffer and following ones are pointed by the Rx ring pointers (at offset 2)
+ //(n buffers used for packet receiving at startup while Tx ring is all zeroed)
+ //Total : 1+1+n buffers
+ //Descriptor is a list of 8 bytes values (a 32 bits physical address + a 32 bits flag)
+ //The flag has the length (minus one) of available room/received packet/to send packet
+ //in the lower 11 bits of the 32 bits flag
+
+ len = 0;
+ ExQueryNonVolatileSetting(EEPROM_INDEX_MACADDR, &type, g_s->Ethaddr, 6, &len);
+
+ if (len != 6)
+ debugPrint("Can't read ethernet address from EEPROM\n");
+#ifdef DISPLAYMSG
+ else
+ debugPrint("EEPROM MacAddress = %02x %02x %02x %02x %02x %02x\n",
+ g_s->Ethaddr[0],
+ g_s->Ethaddr[1],
+ g_s->Ethaddr[2],
+ g_s->Ethaddr[3],
+ g_s->Ethaddr[4],
+ g_s->Ethaddr[5]);
+#endif
+
+ g_s->Speed = NVREG_LINKSPEED_100MBPS;
+
+ g_s->Ethaddr_reversed[0] = g_s->Ethaddr[5];
+ g_s->Ethaddr_reversed[1] = g_s->Ethaddr[4];
+ g_s->Ethaddr_reversed[2] = g_s->Ethaddr[3];
+ g_s->Ethaddr_reversed[3] = g_s->Ethaddr[2];
+ g_s->Ethaddr_reversed[4] = g_s->Ethaddr[1];
+ g_s->Ethaddr_reversed[5] = g_s->Ethaddr[0];
+
+ //Writing the MAC address (6 bytes ethernet address)
+ REG(NvRegMacAddrA) = *((DWORD *)&g_s->Ethaddr_reversed[0]);
+ REG(NvRegMacAddrB) = (ULONG)(*((WORD *)&g_s->Ethaddr_reversed[4]));
+
+ REG(NvRegMulticastMaskA) = 0xFFFFFFFF;
+ REG(NvRegMulticastMaskB) = 0x0000FFFF;
+ REG(NvRegMulticastAddrA) = *((DWORD *)&g_s->Ethaddr[0]); //Yes, not reversed!
+ REG(NvRegMulticastAddrB) = (ULONG)(*((WORD *)&g_s->Ethaddr[4]));
+
+ RandomValue = times(0) + 0x1234 + *((DWORD *)g_s->Ethaddr) + *((WORD *)&g_s->Ethaddr[4]);
+
+ //In case of ethernet colision, random duration pauses are used before retry
+ REG(NvRegRandomSeed) = (RandomValue & NVREG_RNDSEED_MASK) | NVREG_RNDSEED_FORCE;
+
+ REG(NvRegOffloadConfig) = NVREG_OFFLOAD_NORMAL; //1518 bytes
+ REG(NvRegPacketFilterFlags) = NVREG_PFF_ALWAYS_MYADDR;
+ REG(NvRegDuplexMode) = NVREG_DUPLEX_MODE_FORCEH;
+
+ REG(NvRegUnknownSetupReg1) = NVREG_UNKSETUP1_VAL;
+ REG(NvRegUnknownSetupReg2) = NVREG_UNKSETUP2_VAL;
+
+ //Writing the DMA buffers addresses and sizes
+ REG(NvRegTxRingPhysAddr) = g_s->TxBufferDesc + g_s->PhysicalMinusVirtual; // 1st buf phys
+ REG(NvRegRxRingPhysAddr) = g_s->RxBufferDesc + g_s->PhysicalMinusVirtual; // 2nd buf phys
+ REG(NvRegRingSizes) = ((g_s->NbrRxBuffers - 1) << 16) | (g_s->NbrTxBuffers - 1);
+
+ REG(NvRegUnknownSetupReg7) = NVREG_UNKSETUP7_VAL1;
+ REG(NvRegUnknownSetupReg3) = NVREG_UNKSETUP7_VAL1; //Yes, Val7 into Reg3!
+
+ REG(NvRegAdapterControl) = (1 << NVREG_ADAPTCTL_PHYSHIFT) | NVREG_ADAPTCTL_PHYVALID;
+ REG(NvRegMIISpeed) = NVREG_MIISPEED_BIT8 | NVREG_MIIDELAY;
+
+ KeStallExecutionProcessor(50); //50 micro seconds of busy-wait
+
+ g_running=1;
+
+ // XBOX specific (nForce specific)
+ if (PhyInitialize(0, 0) < 0) // Initialize transceiver
+ {
+ debugPrint("PhyInitialize error\n");
+
+ Pktdrv_Quit();
+
+ return 0;
+ }
+
+ REG(NvRegAdapterControl) = NVREG_ADAPTCTL_RUNNING;
+
+ KeStallExecutionProcessor(50);
+
+ PktdrvMiiInterrupt(1); //force display/update of current speed and duplex mode
+
+ PktdrvStartSendRecv();
+
+ REG(NvRegMIIStatus) = REG(NvRegMIIStatus);
+ REG(NvRegIrqStatus) = REG(NvRegIrqStatus);
+
+ REG(NvRegUnknownSetupReg4) = NVREG_UNKSETUP4_VAL;
+
+ REG(NvRegIrqMask)= NVREG_IRQ_LINK |
+ NVREG_IRQ_TX_OK |
+ NVREG_IRQ_TX_ERROR |
+ NVREG_IRQ_RX_NOBUF |
+ NVREG_IRQ_RX |
+ NVREG_IRQ_RX_ERROR;
+
+ status = KeConnectInterrupt(&s_MyInterruptObject);
+
+ if (status == 0)
+ {
+ debugPrint("KeConnectInterrupt error\n");
+
+ Pktdrv_Quit();
+
+ return 0;
+ }
+#ifdef DISPLAYMSG
+ else
+ debugPrint("Network interruption initialized successfully\n");
+#endif
+ return 1;
+}
+
+int Pktdrv_ReceivePackets(void)
+{
+ if (g_running) return PktdrvRecvInterrupt(); //returns nbr of packets accepted by callback
+
+ return 0;
+}
+
+void Pktdrv_SendPacket(unsigned char *buffer,int length)
+{
+ if (g_running)
+ {
+ PktdrvSendInterrupt();
+
+ // if QueuedTxPkts>=n (n=number of outgoing buffers -ring- in calling app)
+ // then packet will not be sent (app has to wait until QueuedTxPktsEthaddr, 6);
+ }
+}
+
+int Pktdrv_GetQueuedTxPkts(void)
+{
+ if (g_running)
+ {
+ PktdrvSendInterrupt(); // detects any sent packet and updates QueuedTxPkts
+
+ return g_s->QueuedTxPkts;
+ }
+ else
+ return 0;
+}
diff --git a/src/libsocket/src/pktdrv.h b/src/libsocket/src/pktdrv.h
new file mode 100644
index 0000000..888527c
--- /dev/null
+++ b/src/libsocket/src/pktdrv.h
@@ -0,0 +1,11 @@
+#ifndef _Pktdrv_
+#define _Pktdrv_
+
+int Pktdrv_Init(void);
+void Pktdrv_Quit(void);
+int Pktdrv_ReceivePackets(void);
+void Pktdrv_SendPacket(unsigned char *buffer,int length);
+void Pktdrv_GetEthernetAddr(unsigned char *address);
+int Pktdrv_GetQueuedTxPkts(void);
+
+#endif
diff --git a/libsocket/src/recv.c b/src/libsocket/src/recv.c
similarity index 100%
rename from libsocket/src/recv.c
rename to src/libsocket/src/recv.c
diff --git a/libsocket/src/send.c b/src/libsocket/src/send.c
similarity index 100%
rename from libsocket/src/send.c
rename to src/libsocket/src/send.c
diff --git a/libsocket/src/sockatmark.c b/src/libsocket/src/sockatmark.c
similarity index 100%
rename from libsocket/src/sockatmark.c
rename to src/libsocket/src/sockatmark.c
diff --git a/libsocket/src/sourcefilter.c b/src/libsocket/src/sourcefilter.c
similarity index 100%
rename from libsocket/src/sourcefilter.c
rename to src/libsocket/src/sourcefilter.c