Networking - Working on DHCP client (and related changes)
authorJohn Hodge <[email protected]>
Sun, 5 Feb 2012 04:10:35 +0000 (12:10 +0800)
committerJohn Hodge <[email protected]>
Sun, 5 Feb 2012 04:10:35 +0000 (12:10 +0800)
- Fixing broadcast behavior
- Cleaning up IPStack debug
- Added userspace rand()
- Slight commenting changes

Makefile
Modules/IPStack/arp.c
Modules/IPStack/interface.c
Modules/IPStack/ipv4.c
Modules/IPStack/udp.c
Usermode/Applications/dhcpclient_src/Makefile [new file with mode: 0644]
Usermode/Applications/dhcpclient_src/main.c [new file with mode: 0644]
Usermode/Applications/ifconfig_src/main.c
Usermode/Libraries/libc.so_src/Makefile
Usermode/include/stdlib.h

index d343708..4597d87 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ USRLIBS += libreadline.so libnet.so liburi.so
 USRLIBS += libimage_sif.so
 
 USRAPPS := init login CLIShell cat ls mount
-USRAPPS += bomb
+USRAPPS += bomb dhcpclient
 USRAPPS += ifconfig ping telnet irc
 USRAPPS += axwin3
 
index e0912ad..abaea27 100644 (file)
@@ -77,6 +77,14 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address)
        
        ENTER("pInterface xAddress", Interface, Address);
        
+       // Check for broadcast
+       if( Address.L == -1 )
+       {
+               LOG("Broadcast");
+               LEAVE('-');
+               return cMAC_BROADCAST;
+       }
+
        // Check routing tables if not on this subnet
        if( IPStack_CompareAddress(4, &Address, Interface->Address, Interface->SubnetBits) == 0 )
        {
@@ -86,8 +94,23 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address)
                if( route && ((tIPv4*)route->NextHop)->L != 0 )
                {
                        // Recursion: see /Recursion/
+                       LOG("Recursing with %s", IPStack_PrintAddress(4, route->NextHop));
+                       LEAVE('-');
                        return ARP_Resolve4(Interface, *(tIPv4*)route->NextHop);
                }
+               // No route, fall though
+       }
+       else
+       {
+               Uint32  netmask;
+               // Check for broadcast
+               netmask = IPv4_Netmask(Interface->SubnetBits);
+               if( (Address.L & ~netmask) == (0xFFFFFFFF & ~netmask) )
+               {
+                       LOG("Local Broadcast");
+                       LEAVE('-');
+                       return cMAC_BROADCAST;
+               }
        }
        
        // Check ARP Cache
index 5bfcda7..b0b63b9 100644 (file)
@@ -78,10 +78,12 @@ char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos)
 
        // Routing Subdir
        if( Pos == 0 ) {
+               LEAVE('s', "routes");
                return strdup("routes");
        }
        // Pseudo Interfaces
        if( Pos == 1 ) {
+               LEAVE('s', "lo");
                return strdup("lo");
        }
        Pos -= 2;
@@ -139,11 +141,13 @@ tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name)
        
        // Routing subdir
        if( strcmp(Name, "routes") == 0 ) {
+               LEAVE('p', &gIP_RouteNode);
                return &gIP_RouteNode;
        }
        
        // Loopback
        if( strcmp(Name, "lo") == 0 ) {
+               LEAVE('p', &gIP_LoopInterface.Node);
                return &gIP_LoopInterface.Node;
        }
        
@@ -181,6 +185,7 @@ int IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data)
        case 4:
                if( Threads_GetUID() != 0 )     LEAVE_RET('i', -1);
                if( !CheckString( Data ) )      LEAVE_RET('i', -1);
+               LOG("New interface for '%s'", Data);
                {
                        char    name[4] = "";
                        tInterface      *iface = IPStack_AddInterface(Data, name);
@@ -364,6 +369,7 @@ int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
                        
                        // Set type
                        iface->Type = *(int*)Data;
+                       LOG("Interface type set to %i", iface->Type);
                        size = IPStack_GetAddressSize(iface->Type);
                        // Check it's actually valid
                        if( iface->Type != 0 && size == 0 ) {
@@ -399,9 +405,9 @@ int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
                size = IPStack_GetAddressSize(iface->Type);
                if( !CheckMem( Data, size ) )   LEAVE_RET('i', -1);
                // TODO: Protect against trashing
+               LOG("Interface address set to '%s'", IPStack_PrintAddress(iface->Type, Data));
                memcpy( iface->Address, Data, size );
-               LEAVE('i', 1);
-               return 1;
+               LEAVE_RET('i', 1);
        
        /*
         * getset_subnet
@@ -419,12 +425,11 @@ int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
                        // Is the mask sane?
                        if( *(int*)Data < 0 || *(int*)Data > IPStack_GetAddressSize(iface->Type)*8-1 )
                                LEAVE_RET('i', -1);
-                       
+                       LOG("Set subnet bits to %i", *(int*)Data);
                        // Ok, set it
                        iface->SubnetBits = *(int*)Data;
                }
-               LEAVE('i', iface->SubnetBits);
-               return iface->SubnetBits;
+               LEAVE_RET('i', iface->SubnetBits);
        
        /*
         * get_device
@@ -438,7 +443,7 @@ int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
                if( !CheckMem( Data, iface->Adapter->DeviceLen+1 ) )
                        LEAVE_RET('i', -1);
                strcpy( Data, iface->Adapter->Device );
-               return iface->Adapter->DeviceLen;
+               LEAVE_RET('i', iface->Adapter->DeviceLen);
        
        /*
         * ping
@@ -453,8 +458,7 @@ int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data)
                case 4:
                        if( !CheckMem( Data, sizeof(tIPv4) ) )  LEAVE_RET('i', -1);
                        tmp = IPv4_Ping(iface, *(tIPv4*)Data);
-                       LEAVE('i', tmp);
-                       return tmp;
+                       LEAVE_RET('i', tmp);
                        
                case 6:
                        LEAVE_RET('i', 1);
index d16cc97..86301e9 100644 (file)
@@ -2,6 +2,7 @@
  * Acess2 IP Stack
  * - IPv4 Protcol Handling
  */
+#define DEBUG  1
 #include "ipstack.h"
 #include "link.h"
 #include "ipv4.h"
@@ -63,12 +64,13 @@ int IPv4_RegisterCallback(int ID, tIPCallback Callback)
  */
 int IPv4_SendPacket(tInterface *Iface, tIPv4 Address, int Protocol, int ID, int Length, const void *Data)
 {
-       tMacAddr        to = ARP_Resolve4(Iface, Address);
+       tMacAddr        to;
         int    bufSize = sizeof(tIPv4Header) + Length;
        char    buf[bufSize];
        tIPv4Header     *hdr = (void*)buf;
         int    ret;
        
+       to = ARP_Resolve4(Iface, Address);
        if( MAC_EQU(to, cMAC_ZERO) ) {
                // No route to host
                Log_Notice("IPv4", "No route to host %i.%i.%i.%i",
@@ -171,6 +173,11 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff
        // TODO: Handle packet fragmentation
        
        
+       Log_Debug("IPv4", " From %i.%i.%i.%i to %i.%i.%i.%i",
+               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]
+               );
+       
        // Get Data and Data Length
        dataLength = ntohs(hdr->TotalLength) - sizeof(tIPv4Header);
        data = &hdr->Options[0];
@@ -221,13 +228,15 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff
                Log_Debug("IPv4", "Route the packet");
                // Drop the packet if the TTL is zero
                if( hdr->TTL == 0 ) {
-                       Log_Warning("IPv4", "TODO: Sent ICMP-Timeout when TTL exceeded");
+                       Log_Warning("IPv4", "TODO: Send ICMP-Timeout when TTL exceeded");
                        return ;
                }
                
                hdr->TTL --;
                
                rt = IPStack_FindRoute(4, NULL, &hdr->Destination);     // Get the route (gets the interface)
+               if( !rt || !rt->Interface )
+                       return ;
                to = ARP_Resolve4(rt->Interface, hdr->Destination);     // Resolve address
                if( MAC_EQU(to, cMAC_ZERO) )
                        return ;
@@ -265,27 +274,37 @@ tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast)
        tInterface      *iface = NULL;
        Uint32  netmask;
        Uint32  addr, this;
-       
+
+       ENTER("pAdapter xAddress bBroadcast", Adapter, Address, Broadcast);     
+
        addr = ntohl( Address.L );
+       LOG("addr = 0x%x", addr);
        
        for( iface = gIP_Interfaces; iface; iface = iface->Next)
        {
                if( iface->Adapter != Adapter ) continue;
                if( iface->Type != 4 )  continue;
-               if( IP4_EQU(Address, *(tIPv4*)iface->Address) )
+               if( IP4_EQU(Address, *(tIPv4*)iface->Address) ) {
+                       LOG("Exact match");
+                       LEAVE('p', iface);
                        return iface;
+               }
                
                if( !Broadcast )        continue;
                
-               this = ntohl( ((tIPv4*)iface->Address)->L );
-               
                // Check for broadcast
+               this = ntohl( ((tIPv4*)iface->Address)->L );
                netmask = IPv4_Netmask(iface->SubnetBits);
-               
-               if( (addr & netmask) == (this & netmask)
-                && (addr & ~netmask) == (0xFFFFFFFF & ~netmask) )
+               LOG("iface addr = 0x%x, netmask = 0x%x (bits = %i)", this, netmask, iface->SubnetBits);
+
+               if( (addr & netmask) == (this & netmask) && (addr & ~netmask) == (0xFFFFFFFF & ~netmask) )
+               {
+                       LOG("Broadcast match");
+                       LEAVE('p', iface);
                        return iface;
+               }
        }
+       LEAVE('n');
        return NULL;
 }
 
@@ -298,8 +317,13 @@ tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast)
 Uint32 IPv4_Netmask(int FixedBits)
 {
        Uint32  ret = 0xFFFFFFFF;
-       ret >>= (32-FixedBits);
-       ret <<= (32-FixedBits);
+       if( FixedBits == 0 )
+               return 0;
+       if( FixedBits < 32 )
+       {
+               ret >>= (32-FixedBits);
+               ret <<= (32-FixedBits);
+       }
        // Returns a native endian netmask
        return ret;
 }
index 2cf7692..cbdcd56 100644 (file)
@@ -91,6 +91,7 @@ int UDP_int_ScanList(tUDPChannel *List, tInterface *Interface, void *Address, in
                pack->Next = NULL;
                memcpy(&pack->Remote.Addr, Address, IPStack_GetAddressSize(Interface->Type));
                pack->Remote.Port = ntohs(hdr->SourcePort);
+               pack->Remote.AddrType = Interface->Type;
                pack->Length = len;
                memcpy(pack->Data, hdr->Data, len);
                
@@ -193,7 +194,7 @@ Uint64 UDP_Channel_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buf
        tUDPChannel     *chan = Node->ImplPtr;
        tUDPPacket      *pack;
        tUDPEndpoint    *ep;
-        int    ofs;
+        int    ofs, addrlen;
        
        if(chan->LocalPort == 0) {
                Log_Notice("UDP", "Channel %p sent with no local port", chan);
@@ -221,8 +222,9 @@ Uint64 UDP_Channel_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buf
        }
 
        // Check that the header fits
+       addrlen = IPStack_GetAddressSize(pack->Remote.AddrType);
        ep = Buffer;
-       ofs = 4 + IPStack_GetAddressSize(pack->Remote.AddrType);
+       ofs = 4 + addrlen;
        if(Length < ofs) {
                free(pack);
                Log_Notice("UDP", "Insuficient space for header in buffer (%i < %i)", (int)Length, ofs);
@@ -232,7 +234,7 @@ Uint64 UDP_Channel_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buf
        // Fill header
        ep->Port = pack->Remote.Port;
        ep->AddrType = pack->Remote.AddrType;
-       memcpy(&ep->Addr, &pack->Remote.Addr, IPStack_GetAddressSize(pack->Remote.AddrType));
+       memcpy(&ep->Addr, &pack->Remote.Addr, addrlen);
        
        // Copy packet data
        if(Length > ofs + pack->Length) Length = ofs + pack->Length;
diff --git a/Usermode/Applications/dhcpclient_src/Makefile b/Usermode/Applications/dhcpclient_src/Makefile
new file mode 100644 (file)
index 0000000..f14d39e
--- /dev/null
@@ -0,0 +1,11 @@
+# Project: DHCP Client
+
+-include ../Makefile.cfg
+
+LDFLAGS += -lnet
+
+OBJ = main.o
+BIN = dhcpc
+DIR = SBin
+
+-include ../Makefile.tpl
diff --git a/Usermode/Applications/dhcpclient_src/main.c b/Usermode/Applications/dhcpclient_src/main.c
new file mode 100644 (file)
index 0000000..ad071db
--- /dev/null
@@ -0,0 +1,364 @@
+/*
+ */
+#include <unistd.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <net.h>
+
+// --- Translation functions ---
+static inline uint32_t htonl(uint32_t v)
+{
+       return    (((v >> 24) & 0xFF) <<  0)
+               | (((v >> 16) & 0xFF) <<  8)
+               | (((v >>  8) & 0xFF) << 16)
+               | (((v >>  0) & 0xFF) << 24);
+}
+static inline uint16_t htons(uint16_t v)
+{
+       return    (((v >> 8) & 0xFF) <<  0)
+               | (((v >> 0) & 0xFF) <<  8);
+}
+#define htonb(v)       v
+#define ntohl(v)       htonl(v)
+
+// === CONSTANTS ===
+enum eStates
+{
+       STATE_PREINIT,
+       STATE_DISCOVER_SENT,
+       STATE_REQUEST_SENT,
+       STATE_COMPLETE
+};
+
+// === STRUCTURES ===
+#define DHCP_MAGIC     0x63825363
+struct sDHCP_Message
+{
+       uint8_t op;
+       uint8_t htype;  // 1 = Ethernet
+       uint8_t hlen;   // 6 bytes for MAC
+       uint8_t hops;   // Hop counting
+       uint32_t        xid;
+       uint16_t        secs;
+       uint16_t        flags;
+       uint32_t        ciaddr;
+       uint32_t        yiaddr;
+       uint32_t        siaddr;
+       uint32_t        giaddr;
+       uint8_t chaddr[16];
+       uint8_t sname[64];
+       uint8_t file[128];
+       uint32_t        dhcp_magic;     // 0x63 0x82 0x53 0x63
+       uint8_t options[];
+};
+
+typedef struct sInterface
+{
+       const char      *Adapter;
+        int    State;
+        int    Num;
+        int    SocketFD;
+        int    IfaceFD;
+} tInterface;
+
+// === PROTOTYPES ===
+int    main(int argc, char *argv[]);
+int    Start_Interface(tInterface *Iface);
+void   Send_DHCPDISCOVER(tInterface *Iface);
+void   Send_DHCPREQUEST(tInterface *Iface, void *OfferBuffer, int TypeOffset);
+void   Handle_Packet(tInterface *Iface);
+void   SetAddress(tInterface *Iface, void *Addr, void *Mask, void *Router);
+
+// === CODE ===
+int main(int argc, char *argv[])
+{
+       tInterface      iface;
+
+       if( argc != 2 ) {
+               fprintf(stderr, "Usage: %s <interface>\n", argv[0]);
+               return -1;
+       }       
+
+       iface.State = STATE_PREINIT;
+       iface.Adapter = argv[1];
+
+       if( Start_Interface(&iface) < 0 ) {
+               return -1;
+       }
+       
+       // Send request
+       Send_DHCPDISCOVER(&iface);
+
+       for( ;; ) 
+       {
+                int    maxfd;
+               fd_set  fds;
+       
+               maxfd = 0;
+               FD_ZERO(&fds);
+               FD_SET(iface.SocketFD, &fds);   if(maxfd < iface.SocketFD) maxfd = iface.SocketFD;
+               if( select(maxfd+1, &fds, NULL, NULL, NULL) < 0 )
+               {
+                       // TODO: Check error result
+                       return -1;
+               }
+
+               _SysDebug("select returned");   
+       
+               if( FD_ISSET(iface.SocketFD, &fds) )
+               {
+                       // TODO: Catch response
+                       Handle_Packet( &iface );
+                       
+               }
+       }
+       return 0;
+}
+
+// RETURN: Client FD
+int Start_Interface(tInterface *Iface)
+{
+        int    fd, tmp;
+       char    path[] = "/Devices/ip/XXXXX/udpc";
+       char    addr[4] = {0,0,0,0};
+       
+       // TODO: Check that the adapter is not in use
+       
+       // Initialise an interface, with a dummy IP address (zero)
+       fd = open("/Devices/ip", 0);
+       if( fd == -1 ) {
+               fprintf(stderr, "ERROR: Unable to open '/Devices/ip'\n"); 
+               return -1;
+       }
+       Iface->Num = ioctl(fd, 4, (void*)Iface->Adapter);       // Create interface
+       if( Iface->Num == -1 ) {
+               fprintf(stderr, "ERROR: Unable to create new interface\n");
+               return -1;
+       }
+       close(fd);
+       
+       // Open new interface
+       snprintf(path, sizeof(path), "/Devices/ip/%i", Iface->Num);
+       Iface->IfaceFD = fd = open(path, 0);
+       if( fd == -1 ) {
+               fprintf(stderr, "ERROR: Unable to open '%s'\n", path); 
+               return -1;
+       }
+       tmp = 4; ioctl(fd, 4, &tmp);    // Set to IPv4
+       ioctl(fd, 6, addr);     // Set address to 0.0.0.0
+       tmp = 0; ioctl(fd, 7, &tmp);    // Set subnet mask to 0
+
+       // Open UDP Client
+       snprintf(path, sizeof(path), "/Devices/ip/%i/udp", Iface->Num);
+       Iface->SocketFD = fd = open(path, O_RDWR);
+       if( fd == -1 ) {
+               fprintf(stderr, "ERROR: Unable to open '%s'\n", path); 
+               return -1;
+       }
+       tmp = 68; ioctl(fd, 4, &tmp);   // Local port
+       tmp = 67; ioctl(fd, 5, &tmp);   // Remote port
+       tmp = 0;        ioctl(fd, 7, &tmp);     // Remote addr mask - we don't care where the reply comes from
+       addr[0] = addr[1] = addr[2] = addr[3] = 255;    // 255.255.255.255
+       ioctl(fd, 8, addr);     // Remote address
+       
+       return fd;
+}
+
+void Send_DHCPDISCOVER(tInterface *Iface)
+{
+       uint32_t        transaction_id;
+       struct sDHCP_Message    *msg;
+       char    data[8 + sizeof(struct sDHCP_Message) + 3 + 1];
+       msg = (void*)data + 8;
+       
+       transaction_id = rand();
+
+       msg->op    = htonb(1);  // BOOTREQUEST
+       msg->htype = htonb(1);  // 10mb Ethernet
+       msg->hlen  = htonb(6);  // 6 byte MAC
+       msg->hops  = htonb(0);  // Hop count so far
+       msg->xid   = htonl(transaction_id);     // Transaction ID
+       msg->secs  = htons(0);  // secs - No time has elapsed
+       msg->flags = htons(0);  // flags - TODO: Check if broadcast bit need be set
+       msg->ciaddr = htonl(0); // ciaddr - Zero, as we don't have one yet
+       msg->yiaddr = htonl(0); // yiaddr - Zero?
+       msg->siaddr = htonl(0); // siaddr - Zero? maybe -1
+       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);
+       }
+       memset(msg->sname, 0, sizeof(msg->sname));      // Nuke the rest
+       memset(msg->file, 0, sizeof(msg->file));        // Nuke the rest
+       msg->dhcp_magic = htonl(DHCP_MAGIC);
+
+       int i = 0;
+       msg->options[i++] =  53;        // DHCP Message Type
+       msg->options[i++] =   1;
+       msg->options[i++] =   1;        // - DHCPDISCOVER
+       msg->options[i++] = 255;        // End of list
+       
+
+       data[0] = 67;   data[1] = 0;    // Port
+       data[2] = 4;    data[3] = 0;    // AddrType
+       data[4] = 255;  data[5] = 255;  data[6] = 255;  data[7] = 255;
+
+       write(Iface->SocketFD, data, sizeof(data));
+       Iface->State = STATE_DISCOVER_SENT;
+}
+
+void Send_DHCPREQUEST(tInterface *Iface, void *OfferPacket, int TypeOffset)
+{
+       struct sDHCP_Message    *msg;
+       msg = (void*) ((char*)OfferPacket) + 8;
+
+       // Reuses old data :)
+       msg->op = 1;
+       msg->options[TypeOffset+2] = 3; // DHCPREQUEST
+       msg->options[TypeOffset+3] = 255;
+       
+       write(Iface->SocketFD, OfferPacket, 8 + sizeof(*msg) + TypeOffset + 4);
+       Iface->State = STATE_REQUEST_SENT;
+}
+
+void Handle_Packet(tInterface *Iface)
+{
+       char    data[8+576];
+       struct sDHCP_Message    *msg = (void*)(data + 8);
+        int    len, i;
+       
+        int    dhcp_msg_type = 0, dhcp_msg_type_ofs;
+       void    *router = NULL;
+       void    *subnet_mask = NULL;
+       
+       _SysDebug("Doing read on %i", Iface->SocketFD);
+       len = read(Iface->SocketFD, data, sizeof(data));
+       _SysDebug("len = %i", len);
+
+       _SysDebug("*msg = {");
+       _SysDebug("  .op = %i", msg->op);
+       _SysDebug("  .htype = %i", msg->htype);
+       _SysDebug("  .ciaddr = 0x%x", ntohl(msg->ciaddr));
+       _SysDebug("  .yiaddr = 0x%x", ntohl(msg->yiaddr));
+       _SysDebug("}");
+       if( msg->op != 2 ) {
+               // Not a response
+               _SysDebug("Not a response message");
+               return ;
+       }
+
+       if( htonl(msg->dhcp_magic) != DHCP_MAGIC ) {
+               _SysDebug("DHCP magic doesn't match (got 0x%x, expected 0x%x)",
+                       htonl(msg->dhcp_magic), DHCP_MAGIC);
+               return ;
+       }       
+
+       i = 0;
+       while( i < len - sizeof(*msg) - 8 && msg->options[i] != 255 )
+       {
+               if( msg->options[i] == 0 ) {
+                       i ++;
+                       continue ;
+               }
+               _SysDebug("Option %i, %i bytes long", msg->options[i], msg->options[i+1]);
+               switch(msg->options[i])
+               {
+               case 1:
+                       subnet_mask = &msg->options[i+2];
+                       break;
+               case 3:
+                       router = &msg->options[i+2];
+                       break;
+               case 53:
+                       dhcp_msg_type_ofs = i;
+                       dhcp_msg_type = msg->options[i+2];
+                       break;
+               }
+               i += msg->options[i+1]+2;
+       }
+       
+       _SysDebug("dhcp_msg_type = %i", dhcp_msg_type);
+
+       switch( dhcp_msg_type )
+       {
+       case 1: // DHCPDISCOVER - wut?
+               break;
+       case 2: // DHCPOFFER
+               // Send out request for this address
+               if( Iface->State != STATE_DISCOVER_SENT )       return ;
+               Send_DHCPREQUEST(Iface, data, dhcp_msg_type_ofs);
+               break;
+       case 3: // DHCPREQUEST - wut?
+               break;
+       case 4: // DHCPDECLINE - ?
+               break;
+       case 5: // DHCPACK
+               // TODO: Apply address
+               SetAddress(Iface, &msg->yiaddr, subnet_mask, router);
+               exit( 0 );
+               break;
+       }
+}
+
+void SetAddress(tInterface *Iface, void *Addr, void *Mask, void *Router)
+{
+        int    mask_bits = 0;  
+
+       // Translate the mask
+       if( Mask )
+       {
+               uint8_t *mask = Mask;
+                int    i;
+               _SysDebug("Mask %i.%i.%i.%i", mask[0], mask[1], mask[2], mask[3]);
+               for( i = 0; i < 4 && mask[i] == 0xFF; i ++ ) ;
+               mask_bits = i*8;
+               if( i == 4 )
+               {
+                       // Wut? /32?
+               }
+               else
+               {
+                       switch(mask[i])
+                       {
+                       case 0x00:      mask_bits += 0; break;
+                       case 0x80:      mask_bits += 1; break;
+                       case 0xC0:      mask_bits += 2; break;
+                       case 0xE0:      mask_bits += 3; break;
+                       case 0xF0:      mask_bits += 4; break;
+                       case 0xF8:      mask_bits += 5; break;
+                       case 0xFC:      mask_bits += 6; break;
+                       case 0xFE:      mask_bits += 7; break;
+                       default:
+                               // Bad mask!
+                               break;
+                       }
+               }
+       }
+       
+       {
+               uint8_t *addr = Addr;
+               _SysDebug("Addr %i.%i.%i.%i/%i", addr[0], addr[1], addr[2], addr[3], mask_bits);
+
+               printf("Assigned %i.%i.%i.%i/%i to IF#%i (%s)\n",
+                       addr[0], addr[1], addr[2], addr[3], mask_bits,
+                       Iface->Num, Iface->Adapter
+                       );
+       }
+
+       ioctl(Iface->IfaceFD, 6, Addr);
+       ioctl(Iface->IfaceFD, 7, &mask_bits);
+
+       if( Router );
+       {
+               uint8_t *addr = Router;
+               _SysDebug("Router %i.%i.%i.%i", addr[0], addr[1], addr[2], addr[3]);
+//             ioctl(Iface->IfaceFD, 8, addr);
+               // TODO: Default route
+       }
+}
+
index 6091bdc..e2db088 100644 (file)
@@ -483,8 +483,8 @@ void AddRoute(const char *Interface, int AddressType, void *Dest, int MaskBits,
 
 /**
  * \note Debugging HACK!
- * \brief Autoconfigure the specified device to 10.0.2.55/8 using
- *        10.0.2.1 as the gateway.
+ * \brief Autoconfigure the specified device to 10.0.2.55/24 using
+ *        10.0.2.2 as the gateway.
  */
 int DoAutoConfig(const char *Device)
 {
index 8d9960c..7142820 100644 (file)
@@ -8,7 +8,7 @@ CFLAGS   +=
 ASFLAGS  +=\r
 LDFLAGS  += -soname libc.so -Map map.txt -lgcc\r
 \r
-OBJ  = stub.o heap.o stdlib.o env.o fileIO.o string.o select.o\r
+OBJ  = stub.o heap.o stdlib.o env.o fileIO.o string.o select.o rand.o\r
 OBJ += arch/$(ARCHDIR).ao\r
 # signals.o\r
 DEPFILES := $(OBJ:%.o=%.d)\r
index 160993d..0e6d9e0 100644 (file)
@@ -35,6 +35,11 @@ extern void  *calloc(size_t __nmemb, size_t __size);
 extern void    *realloc(void *__ptr, size_t __size);\r
 extern int     IsHeap(void *ptr);\r
 \r
+/* --- Random --- */\r
+extern void    srand(unsigned int seed);\r
+extern int     rand(void);\r
+extern int     rand_p(unsigned int *seedp);\r
+\r
 #ifndef SEEK_CUR\r
 # define SEEK_CUR      0\r
 # define SEEK_SET      1\r

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