Changeset 636 for Whitix/branches

Show
Ignore:
Timestamp:
06/24/08 13:59:31 (5 months ago)
Author:
mwhitworth
Message:

Add to DHCP client.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • Whitix/branches/network/user/net/dhcp.c

    r361 r636  
    3636}__attribute__((packed)); 
    3737 
     38/* Need to be more flexible. */ 
    3839char sourceAddr[6]; 
     40DWORD address; 
     41DWORD serverIp; 
    3942 
    4043void DhcpError(char* message) 
     
    103106 
    104107        ipHeader->versionLength=(4 << 4) | 5; 
    105         printf("versionLength = %#X\n", ipHeader->versionLength); 
    106108        ipHeader->id=HostToNetShort(1); 
    107109        ipHeader->ttl=8; 
     
    201203} 
    202204 
     205int DhcpConstructRequest(char* buf) 
     206{ 
     207        int offset, length; 
     208        struct DhcpPacket* dhcpPacket; 
     209        struct DhcpOption* options; 
     210        BYTE optionsWanted[7]={1, 28, 2, 3, 15, 6, 12}; 
     211        DWORD netAddress; 
     212 
     213        offset=DhcpConstructHeaders(buf); 
     214 
     215        dhcpPacket=(struct DhcpPacket*)(buf+offset); 
     216        memset(dhcpPacket, 0, sizeof(struct DhcpPacket)); 
     217 
     218        dhcpPacket->op=DHCP_BOOT_REQUEST; 
     219        dhcpPacket->hType=1; 
     220        dhcpPacket->hLen=6; 
     221        dhcpPacket->flags=HostToNetShort(0x8000); 
     222        dhcpPacket->xId=HostToNetLong(0xDEADBEEF); 
     223 
     224        memcpy(dhcpPacket->clientHw, sourceAddr, 6); 
     225        dhcpPacket->cookie=HostToNetLong(0x63825363); 
     226 
     227        options=(struct DhcpOption*)(buf+offset+sizeof(struct DhcpPacket)); 
     228 
     229        /* DHCP message type. */ 
     230        options->code=53; 
     231        options->len=1; 
     232        options->data[0]=3;      
     233 
     234        length=offset+sizeof(struct DhcpPacket)+sizeof(struct DhcpOption); 
     235 
     236        netAddress=HostToNetLong(address); 
     237 
     238        options=(struct DhcpOption*)(buf+length); 
     239        options->code=50; 
     240        options->len=4; 
     241        memcpy(options->data, &netAddress, 4); 
     242 
     243        length+=sizeof(struct DhcpOption)+3; 
     244 
     245        options=(struct DhcpOption*)(buf+length); 
     246        options->code=54; 
     247        options->len=4; 
     248        memcpy(options->data, &serverIp, 4); 
     249 
     250        length+=sizeof(struct DhcpOption)+3; 
     251 
     252        /* End option */ 
     253        buf[length]=0xFF; 
     254        length++; 
     255 
     256        /* Padding */ 
     257        memset(buf+length, 0, 344-length); 
     258 
     259        length=344; 
     260 
     261        DhcpFinishPacket(buf, length); 
     262         
     263        return length; 
     264} 
     265 
     266int DhcpPacketCheck(char* buf) 
     267{ 
     268        struct EthHeader* ethHeader=(struct EthHeader*)buf; 
     269        struct IpHeader* ipHeader; 
     270        struct UdpHeader* udpHeader; 
     271 
     272        if (HostToNetShort(ethHeader->ethType) != ETH_TYPE_IP) 
     273                return 0; 
     274 
     275#if 0 
     276        printf("%X:%X:%X:%X:%X:%X\n", ethHeader->dest[0], ethHeader->dest[1], ethHeader->dest[2], 
     277                ethHeader->dest[3], ethHeader->dest[4], ethHeader->dest[5]); 
     278 
     279        /* Should be addressed only to us. */ 
     280        if (memcmp(sourceAddr, ethHeader->dest, 6)) 
     281                return 0; 
     282#endif 
     283 
     284        ipHeader=(struct IpHeader*)(buf+sizeof(struct EthHeader)); 
     285 
     286        /* TODO: Checksum */ 
     287 
     288        if (ipHeader->protocol != PROTOCOL_RAW_UDP) 
     289                return 0; 
     290 
     291        udpHeader=(struct UdpHeader*)(buf+sizeof(struct EthHeader)+sizeof(struct IpHeader)); 
     292 
     293        if (HostToNetShort(udpHeader->destPort) != 68) 
     294                return 0; 
     295 
     296        /* TODO: Checksum */ 
     297 
     298        return 1; 
     299} 
     300 
     301int DhcpParseOffer(char* buf) 
     302{ 
     303        struct DhcpPacket* dhcpPacket=(struct DhcpPacket*)(buf+sizeof(struct EthHeader)+sizeof(struct IpHeader)+sizeof(struct UdpHeader)); 
     304        struct DhcpOption* dhcpOption=(struct DhcpOption*)((char*)dhcpPacket+sizeof(struct DhcpPacket)); 
     305        char* option=(char*)dhcpOption; 
     306 
     307        address=NetToHostLong(dhcpPacket->yourIp); 
     308 
     309        while (dhcpOption->code != 0xFF) 
     310        { 
     311                if (dhcpOption->code == 54) 
     312                { 
     313                        memcpy(&serverIp, dhcpOption->data, 4); 
     314                        break; 
     315                } 
     316 
     317                option+=sizeof(struct DhcpOption)+dhcpOption->len-1; 
     318                dhcpOption=(struct DhcpOption*)option; 
     319        } 
     320 
     321        return 0; 
     322} 
     323 
    203324int DhcpPacketSend(int sockFd, char* buf, int (*packetConstructor)(char*)) 
    204325{ 
     
    219340                startSeconds=time.seconds; 
    220341 
    221                 while (1) 
     342                /* And check for receive. */ 
     343                do 
    222344                { 
    223                         SysGetTime(&time); 
    224                         if (time.seconds - startSeconds > i) 
    225                                 break; 
    226                 } 
    227  
    228                 /* And check for receive. */ 
    229                 SysSocketReceive(sockFd, buf, 1024, 0); 
     345                        SysSocketReceive(sockFd, buf, 1024, 0); 
     346                }while( !DhcpPacketCheck(buf)); 
     347 
     348                if (DhcpPacketCheck(buf)) 
     349                        break; 
    230350 
    231351                i *= 2; 
    232352        } 
     353 
     354        if (i == 128) 
     355                return 1; 
    233356 
    234357        return 0; 
     
    255378        DhcpPacketSend(sockFd, buf, DhcpConstructDiscover); 
    256379         
     380        /* Parse the DHCPOFFER packet */ 
     381        DhcpParseOffer(buf); 
     382 
     383        printf("dhcp: Sending DHCPREQUEST packet\n"); 
     384        DhcpPacketSend(sockFd, buf, DhcpConstructRequest); 
     385 
     386        printf("Address is: %u.%u.%u.%u\n", (address >> 24) & 0xFF, (address >> 16) & 0xFF, (address >> 8) & 0xFF, address & 0xFF); 
     387 
     388        /* Check lease time. Process DHCP ACK packet. */ 
    257389 
    258390        NetSocketClose(sockFd);