From: John Hodge Date: Sun, 5 Feb 2012 04:10:35 +0000 (+0800) Subject: Networking - Working on DHCP client (and related changes) X-Git-Tag: rel0.15~792^2~2 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=7c43aea724fea42bc297f47f9c180a5080c6fd17;p=tpg%2Facess2.git Networking - Working on DHCP client (and related changes) - Fixing broadcast behavior - Cleaning up IPStack debug - Added userspace rand() - Slight commenting changes --- diff --git a/Makefile b/Makefile index d343708a..4597d875 100644 --- 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 diff --git a/Modules/IPStack/arp.c b/Modules/IPStack/arp.c index e0912ad8..abaea275 100644 --- a/Modules/IPStack/arp.c +++ b/Modules/IPStack/arp.c @@ -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 diff --git a/Modules/IPStack/interface.c b/Modules/IPStack/interface.c index 5bfcda77..b0b63b9a 100644 --- a/Modules/IPStack/interface.c +++ b/Modules/IPStack/interface.c @@ -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); diff --git a/Modules/IPStack/ipv4.c b/Modules/IPStack/ipv4.c index d16cc97d..86301e97 100644 --- a/Modules/IPStack/ipv4.c +++ b/Modules/IPStack/ipv4.c @@ -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; } diff --git a/Modules/IPStack/udp.c b/Modules/IPStack/udp.c index 2cf76926..cbdcd56b 100644 --- a/Modules/IPStack/udp.c +++ b/Modules/IPStack/udp.c @@ -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 index 00000000..f14d39e9 --- /dev/null +++ b/Usermode/Applications/dhcpclient_src/Makefile @@ -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 index 00000000..ad071db7 --- /dev/null +++ b/Usermode/Applications/dhcpclient_src/main.c @@ -0,0 +1,364 @@ +/* + */ +#include +#include +#include +#include +#include + +// --- 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 \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 + } +} + diff --git a/Usermode/Applications/ifconfig_src/main.c b/Usermode/Applications/ifconfig_src/main.c index 6091bdcc..e2db088f 100644 --- a/Usermode/Applications/ifconfig_src/main.c +++ b/Usermode/Applications/ifconfig_src/main.c @@ -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) { diff --git a/Usermode/Libraries/libc.so_src/Makefile b/Usermode/Libraries/libc.so_src/Makefile index 8d9960c6..7142820f 100644 --- a/Usermode/Libraries/libc.so_src/Makefile +++ b/Usermode/Libraries/libc.so_src/Makefile @@ -8,7 +8,7 @@ CFLAGS += ASFLAGS += LDFLAGS += -soname libc.so -Map map.txt -lgcc -OBJ = stub.o heap.o stdlib.o env.o fileIO.o string.o select.o +OBJ = stub.o heap.o stdlib.o env.o fileIO.o string.o select.o rand.o OBJ += arch/$(ARCHDIR).ao # signals.o DEPFILES := $(OBJ:%.o=%.d) diff --git a/Usermode/include/stdlib.h b/Usermode/include/stdlib.h index 160993d1..0e6d9e03 100644 --- a/Usermode/include/stdlib.h +++ b/Usermode/include/stdlib.h @@ -35,6 +35,11 @@ extern void *calloc(size_t __nmemb, size_t __size); extern void *realloc(void *__ptr, size_t __size); extern int IsHeap(void *ptr); +/* --- Random --- */ +extern void srand(unsigned int seed); +extern int rand(void); +extern int rand_p(unsigned int *seedp); + #ifndef SEEK_CUR # define SEEK_CUR 0 # define SEEK_SET 1