]> git.kernelconcepts.de Git - karo-tx-redboot.git/blobdiff - packages/redboot/v2_0/src/net/bootp.c
RedBoot Release TX53-v3 2012-02-08
[karo-tx-redboot.git] / packages / redboot / v2_0 / src / net / bootp.c
index 3a0c60acae5998a5ccd263cabbbea25a861eeab8..551bb4aeb571465fea307e635c4510f7ddfb30f8 100644 (file)
@@ -44,9 +44,9 @@
 // Author(s):    gthomas
 // Contributors: gthomas
 // Date:         2000-07-14
-// Purpose:      
-// Description:  
-//              
+// Purpose:
+// Description:
+//
 // This code is part of RedBoot (tm).
 //
 //####DESCRIPTIONEND####
@@ -69,7 +69,7 @@
 #define MAX_RETRIES    8
 
 static bootp_header_t *bp_info;
-  
+
 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP
 static const unsigned char dhcpCookie[] = {99,130,83,99};
 static const unsigned char dhcpEnd[] = {255};
@@ -78,89 +78,89 @@ static const unsigned char dhcpRequest[] = {53,1,3};
 static const unsigned char dhcpRequestIP[] = {50,4};
 static const unsigned char dhcpParamRequestList[] = {55,3,1,3,6};
 static enum {
-    DHCP_NONE = 0,
-    DHCP_DISCOVER,
-    DHCP_OFFER,
-    DHCP_REQUEST,
-    DHCP_ACK
+       DHCP_NONE = 0,
+       DHCP_DISCOVER,
+       DHCP_OFFER,
+       DHCP_REQUEST,
+       DHCP_ACK
 } dhcpState;
 #endif
 
 static void
 bootp_handler(udp_socket_t *skt, void *buf, int len,
-             ip_route_t *src_route, word src_port)
+                       ip_route_t *src_route, word src_port)
 {
-    bootp_header_t *b;
+       bootp_header_t *b;
 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP
-    unsigned char *p, expected = 0;
+       unsigned char *p, expected = 0;
 #endif
 
-    b = buf;
-    if (bp_info) {
-        memset(bp_info,0,sizeof *bp_info);
-        if (len > sizeof *bp_info)
-            len = sizeof *bp_info;
-        memcpy(bp_info, b, len);
-    }
+       b = buf;
+       if (bp_info) {
+               memset(bp_info,0,sizeof *bp_info);
+               if (len > sizeof *bp_info)
+                       len = sizeof *bp_info;
+               memcpy(bp_info, b, len);
+       }
+
+       // Only accept pure REPLY responses
+       if (b->bp_op != BOOTREPLY)
+               return;
+
+       // Must be sent to me, as well!
+       if (memcmp(b->bp_chaddr, __local_enet_addr, 6))
+               return;
 
-    // Only accept pure REPLY responses
-    if (b->bp_op != BOOTREPLY)
-      return;
-    
-    // Must be sent to me, as well!
-    if (memcmp(b->bp_chaddr, __local_enet_addr, 6))
-      return;
-        
 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP
-    p = b->bp_vend;
-    if (memcmp(p, dhcpCookie, sizeof(dhcpCookie)))
-      return;
-    p += 4;
+       p = b->bp_vend;
+       if (memcmp(p, dhcpCookie, sizeof(dhcpCookie)))
+               return;
+       p += 4;
 
-    // Find the DHCP Message Type tag
-    while (*p != TAG_DHCP_MESS_TYPE) {
-        p += p[1] + 2;
-        if (p >= (unsigned char*)b + sizeof(*bp_info))
-            return;
-    }
+       // Find the DHCP Message Type tag
+       while (*p != TAG_DHCP_MESS_TYPE) {
+               p += p[1] + 2;
+               if (p >= (unsigned char*)b + sizeof(*bp_info))
+                       return;
+       }
 
-    p += 2;
+       p += 2;
 
-    switch (dhcpState) {
-    case DHCP_DISCOVER:
-        // The discover message has been sent, only accept an offer reply
-        if (*p == DHCP_MESS_TYPE_OFFER) {
-            dhcpState = DHCP_OFFER;
-            return;
-        } else {
-            expected = DHCP_MESS_TYPE_OFFER;
-        }
-        break;
-    case DHCP_REQUEST:
-        // The request message has been sent, only accept an ack reply
-        if (*p == DHCP_MESS_TYPE_ACK) {
-            dhcpState = DHCP_ACK;
-            return;
-        } else {
-            expected = DHCP_MESS_TYPE_ACK;
-        }
-        break;
-    case DHCP_NONE:
-    case DHCP_OFFER:
-    case DHCP_ACK:
-        // Quitely ignore these - they indicate repeated message from server
-        return;
-    }
-    // See if we've been NAK'd - if so, give up and try again
-    if (*p == DHCP_MESS_TYPE_NAK) {
-        dhcpState = DHCP_NONE;
-        return;
-    }
-    diag_printf("DHCP reply: %d, not %d\n", (int)*p, (int)expected);
-    return;
+       switch (dhcpState) {
+       case DHCP_DISCOVER:
+               // The discover message has been sent, only accept an offer reply
+               if (*p == DHCP_MESS_TYPE_OFFER) {
+                       dhcpState = DHCP_OFFER;
+                       return;
+               } else {
+                       expected = DHCP_MESS_TYPE_OFFER;
+               }
+               break;
+       case DHCP_REQUEST:
+               // The request message has been sent, only accept an ack reply
+               if (*p == DHCP_MESS_TYPE_ACK) {
+                       dhcpState = DHCP_ACK;
+                       return;
+               } else {
+                       expected = DHCP_MESS_TYPE_ACK;
+               }
+               break;
+       case DHCP_NONE:
+       case DHCP_OFFER:
+       case DHCP_ACK:
+               // Quietly ignore these - they indicate repeated message from server
+               return;
+       }
+       // See if we've been NAK'd - if so, give up and try again
+       if (*p == DHCP_MESS_TYPE_NAK) {
+               dhcpState = DHCP_NONE;
+               return;
+       }
+       diag_printf("DHCP reply: %d, not %d\n", (int)*p, (int)expected);
+       return;
 #else
-    // Simple BOOTP - this is all there is!
-    memcpy(__local_ip_addr, &b->bp_yiaddr, 4);
+       // Simple BOOTP - this is all there is!
+       memcpy(__local_ip_addr, &b->bp_yiaddr, 4);
 #endif
 }
 
@@ -183,136 +183,136 @@ static int get_xid(void)
 int
 __bootp_find_local_ip(bootp_header_t *info)
 {
-    udp_socket_t udp_skt;
-    bootp_header_t b;
-    ip_route_t     r;
-    int            retry;
-    unsigned long  start;
-    ip_addr_t saved_ip_addr;
+       udp_socket_t udp_skt;
+       bootp_header_t b;
+       ip_route_t     r;
+       int            retry;
+       unsigned long  start;
+       ip_addr_t saved_ip_addr;
 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP
-    unsigned char *p;
-    int oldState;
+       unsigned char *p;
+       int oldState;
 #endif
-    int txSize;
-    bool abort = false;
+       int txSize;
+       bool abort = false;
 
 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP
-    dhcpState = DHCP_NONE;
+       dhcpState = DHCP_NONE;
 #endif
 
-    // Where we want the results saved
-    bp_info = info;
-    // Preserve any IP address we currently have, just in case
-    memcpy(saved_ip_addr, __local_ip_addr, sizeof(__local_ip_addr));
+       // Where we want the results saved
+       bp_info = info;
+       // Preserve any IP address we currently have, just in case
+       memcpy(saved_ip_addr, __local_ip_addr, sizeof(__local_ip_addr));
 
-    // fill out route for a broadcast
-    r.ip_addr[0] = 255;
-    r.ip_addr[1] = 255;
-    r.ip_addr[2] = 255;
-    r.ip_addr[3] = 255;
-    r.enet_addr[0] = 255;
-    r.enet_addr[1] = 255;
-    r.enet_addr[2] = 255;
-    r.enet_addr[3] = 255;
-    r.enet_addr[4] = 255;
-    r.enet_addr[5] = 255;
+       // fill out route for a broadcast
+       r.ip_addr[0] = 255;
+       r.ip_addr[1] = 255;
+       r.ip_addr[2] = 255;
+       r.ip_addr[3] = 255;
+       r.enet_addr[0] = 255;
+       r.enet_addr[1] = 255;
+       r.enet_addr[2] = 255;
+       r.enet_addr[3] = 255;
+       r.enet_addr[4] = 255;
+       r.enet_addr[5] = 255;
 
-    // setup a socket listener for bootp replies
-    __udp_install_listener(&udp_skt, IPPORT_BOOTPC, bootp_handler);
+       // setup a socket listener for bootp replies
+       __udp_install_listener(&udp_skt, IPPORT_BOOTPC, bootp_handler);
 
-    retry = MAX_RETRIES;  
-    do {
+       retry = MAX_RETRIES;
+       do {
        start = MS_TICKS();
 
-        // Build up the BOOTP/DHCP request
-        memset(&b, 0, sizeof(b));
-        b.bp_op = BOOTREQUEST;
-        b.bp_htype = HTYPE_ETHERNET;
-        b.bp_hlen = 6;
-        b.bp_xid = get_xid();
-        memcpy(b.bp_chaddr, __local_enet_addr, 6);
-        memset(__local_ip_addr, 0, sizeof(__local_ip_addr));
-         
+               // Build up the BOOTP/DHCP request
+               memset(&b, 0, sizeof(b));
+               b.bp_op = BOOTREQUEST;
+               b.bp_htype = HTYPE_ETHERNET;
+               b.bp_hlen = 6;
+               b.bp_xid = get_xid();
+               memcpy(b.bp_chaddr, __local_enet_addr, 6);
+               memset(__local_ip_addr, 0, sizeof(__local_ip_addr));
+
 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP
-        p = b.bp_vend;
-        switch (dhcpState) {
-        case DHCP_NONE:
-        case DHCP_DISCOVER:
-            AddOption(p,dhcpCookie);
-            AddOption(p,dhcpDiscover);
-            AddOption(p,dhcpParamRequestList);
-            AddOption(p,dhcpEnd);
-            dhcpState = DHCP_DISCOVER;
-            break;
-        case DHCP_OFFER:
-            retry = MAX_RETRIES;
-        case DHCP_REQUEST:
-            b.bp_xid = bp_info->bp_xid;  // Match what server sent
-            AddOption(p,dhcpCookie);
-            AddOption(p,dhcpRequest);
-            AddOption(p,dhcpRequestIP);
-            memcpy(p, &bp_info->bp_yiaddr, 4);  p += 4;  // Ask for the address just given
-            AddOption(p,dhcpParamRequestList);
-            AddOption(p,dhcpEnd);
-            dhcpState = DHCP_REQUEST;
-            memset(&b.bp_yiaddr, 0xFF, 4);
-            memset(&b.bp_siaddr, 0xFF, 4);
-            memset(&b.bp_yiaddr, 0x00, 4);
-            memset(&b.bp_siaddr, 0x00, 4);
-            break;
-        case DHCP_ACK:
-            // Ignore these states (they won't happen)
-            break;
-        }
-     
-        // Some servers insist on a minimum amount of "vendor" data
-        if (p < &b.bp_vend[BP_MIN_VEND_SIZE]) p = &b.bp_vend[BP_MIN_VEND_SIZE];
-        txSize = p - (unsigned char*)&b;
-        oldState = dhcpState;
+               p = b.bp_vend;
+               switch (dhcpState) {
+               case DHCP_NONE:
+               case DHCP_DISCOVER:
+                       AddOption(p, dhcpCookie);
+                       AddOption(p, dhcpDiscover);
+                       AddOption(p, dhcpParamRequestList);
+                       AddOption(p, dhcpEnd);
+                       dhcpState = DHCP_DISCOVER;
+                       break;
+               case DHCP_OFFER:
+                       retry = MAX_RETRIES;
+               case DHCP_REQUEST:
+                       b.bp_xid = bp_info->bp_xid;  // Match what server sent
+                       AddOption(p, dhcpCookie);
+                       AddOption(p, dhcpRequest);
+                       AddOption(p, dhcpRequestIP);
+                       memcpy(p, &bp_info->bp_yiaddr, 4);  p += 4;  // Ask for the address just given
+                       AddOption(p,dhcpParamRequestList);
+                       AddOption(p,dhcpEnd);
+                       dhcpState = DHCP_REQUEST;
+                       memset(&b.bp_yiaddr, 0xFF, 4);
+                       memset(&b.bp_siaddr, 0xFF, 4);
+                       memset(&b.bp_yiaddr, 0x00, 4);
+                       memset(&b.bp_siaddr, 0x00, 4);
+                       break;
+               case DHCP_ACK:
+                       // Ignore these states (they won't happen)
+                       break;
+               }
+
+               // Some servers insist on a minimum amount of "vendor" data
+               if (p < &b.bp_vend[BP_MIN_VEND_SIZE]) p = &b.bp_vend[BP_MIN_VEND_SIZE];
+               txSize = p - (unsigned char*)&b;
+               oldState = dhcpState;
 #else
-        txSize = sizeof(b);
+               txSize = sizeof(b);
 #endif
 
        __udp_send((char *)&b, txSize, &r, IPPORT_BOOTPS, IPPORT_BOOTPC);
 
-        // If we're retrying, inform the user
-        if (retry == (MAX_RETRIES - 1))
-            diag_printf("... waiting for BOOTP information\n");
+               // If we're retrying, inform the user
+               if (retry == (MAX_RETRIES - 1))
+                       diag_printf("... waiting for BOOTP information\n");
 
        do {
-           __enet_poll();
+               __enet_poll();
 #ifdef CYGSEM_REDBOOT_NETWORKING_DHCP
-            if (dhcpState != oldState) {
-                if (dhcpState == DHCP_ACK) {
-                    unsigned char *end;
-                    int optlen;
-                    // Address information has now arrived!
-                    memcpy(__local_ip_addr, &bp_info->bp_yiaddr, 4);
+                       if (dhcpState != oldState) {
+                               if (dhcpState == DHCP_ACK) {
+                                       unsigned char *end;
+                                       int optlen;
+                                       // Address information has now arrived!
+                                       memcpy(__local_ip_addr, &bp_info->bp_yiaddr, 4);
 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
-                    memcpy(__local_ip_gate, &bp_info->bp_giaddr, 4);
+                                       memcpy(__local_ip_gate, &bp_info->bp_giaddr, 4);
 #endif
-                    p = bp_info->bp_vend+4;
-                    end = (unsigned char *)bp_info+sizeof(*bp_info);
-                    while (p < end) {
-                        unsigned char tag = *p;
-                        if (tag == TAG_END)
-                            break;
-                        if (tag == TAG_PAD)
-                            optlen = 1;
-                        else {
-                            optlen = p[1];
-                            p += 2;
-                            switch (tag) {
+                                       p = bp_info->bp_vend+4;
+                                       end = (unsigned char *)bp_info+sizeof(*bp_info);
+                                       while (p < end) {
+                                               unsigned char tag = *p;
+                                               if (tag == TAG_END)
+                                                       break;
+                                               if (tag == TAG_PAD)
+                                                       optlen = 1;
+                                               else {
+                                                       optlen = p[1];
+                                                       p += 2;
+                                                       switch (tag) {
 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
-                            case TAG_SUBNET_MASK:  // subnet mask
-                                memcpy(__local_ip_mask,p,4); 
-                                break;
-                            case TAG_GATEWAY:  // router
-                                memcpy(__local_ip_gate,p,4); 
-                                break;
+                                                       case TAG_SUBNET_MASK:  // subnet mask
+                                                               memcpy(__local_ip_mask,p,4);
+                                                               break;
+                                                       case TAG_GATEWAY:  // router
+                                                               memcpy(__local_ip_gate,p,4);
+                                                               break;
 #endif
 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS
-                           case TAG_DOMAIN_SERVER:
+                               case TAG_DOMAIN_SERVER:
 //                             diag_printf(" DNS server found!\n");
                                memcpy(&__bootp_dns_addr, p, 4);
                                __bootp_dns_set = 1;
@@ -329,43 +329,41 @@ __bootp_find_local_ip(bootp_header_t *info)
                                                                break;
 #endif //CYGPKG_REDBOOT_NETWORKING_DNS_DHCP_DOMAIN
 #endif //CYGPKG_REDBOOT_NETWORKING_DNS
-                            default:
-                                break;
-                            }
-                        }
-                        p += optlen;
-                    }
-                    __udp_remove_listener(IPPORT_BOOTPC);
-                    return 0;
-                } else {
-                    break;  // State changed, handle it
-                }
-            }
+                                                       default:
+                                                               break;
+                                                       }
+                                               }
+                                               p += optlen;
+                                       }
+                                       __udp_remove_listener(IPPORT_BOOTPC);
+                                       return 0;
+                               } else {
+                                       break;  // State changed, handle it
+                               }
+                       }
 #else
-            // All done, if address response has arrived
-           if (__local_ip_addr[0] || __local_ip_addr[1] ||
+                       // All done, if address response has arrived
+               if (__local_ip_addr[0] || __local_ip_addr[1] ||
                __local_ip_addr[2] || __local_ip_addr[3]) {
                /* success */
                __udp_remove_listener(IPPORT_BOOTPC);
                return 0;
-           }
+               }
 #endif
-           if (retry < MAX_RETRIES) {
+               if (retry < MAX_RETRIES) {
                if (_rb_break(1)) {
-                   // The user typed ^C on the console
-                   abort = true;
-                   break;
+                       // The user typed ^C on the console
+                       abort = true;
+                       break;
                }
                start--; /* account for time spent in _rb_break() */
-           }
+               }
        } while ((int)(MS_TICKS_DELAY() - start) < RETRY_TIME);
-    } while (!abort && (retry-- > 0));
+       } while (!abort && (retry-- > 0));
 
-    // timed out
-    __udp_remove_listener(IPPORT_BOOTPC);
-    // Restore any previous IP address
-    memcpy(__local_ip_addr, saved_ip_addr, sizeof(__local_ip_addr));
-    return -1;
+       // timed out
+       __udp_remove_listener(IPPORT_BOOTPC);
+       // Restore any previous IP address
+       memcpy(__local_ip_addr, saved_ip_addr, sizeof(__local_ip_addr));
+       return -1;
 }
-
-