Mercurial > flash_v2
diff packages/net/tcpip/current/src/lib/bootp_support.c @ 110:84e4bde58b26 ecos-sw-2000-07-14
Merge from eCos master repository on 2000-07-14-22:00:02-BST
| author | jlarmour |
|---|---|
| date | Mon, 17 Jul 2000 14:42:27 +0000 |
| parents | ced4577552cd |
| children | 02ea4320376c |
line wrap: on
line diff
--- a/packages/net/tcpip/current/src/lib/bootp_support.c +++ b/packages/net/tcpip/current/src/lib/bootp_support.c @@ -52,7 +52,10 @@ // //========================================================================== -// BOOTP support +// BOOTP support (and a little DHCP support also) + +#include <pkgconf/system.h> +#include <pkgconf/net.h> #include <network.h> @@ -71,6 +74,7 @@ do_bootp(const char *intf, struct bootp struct bootp bootp_xmit; unsigned char mincookie[] = {99,130,83,99,255} ; struct timeval tv; + cyg_bool_t retcode = true; // Ensure clean slate route_reinit(); // Force any existing routes to be forgotten @@ -196,11 +200,13 @@ do_bootp(const char *intf, struct bootp addrlen = sizeof(bootp_server_addr); if (recvfrom(s, recv, sizeof(struct bootp), 0, (struct sockaddr *)&bootp_server_addr, &addrlen) < 0) { - perror("recvfrom error"); - return false; + // This is an "acceptable" error, it means there is no server for + // us: do not initialize the interface. + retcode = false; } - + // Shut things down regardless of success of rx, otherwise other + // interfaces cannot be initialised! memset(addrp, 0, sizeof(*addrp)); addrp->sin_family = AF_INET; addrp->sin_len = sizeof(*addrp); @@ -221,22 +227,30 @@ do_bootp(const char *intf, struct bootp // All done with socket close(s); - return true; + return retcode; } static char *_bootp_op[] = {"", "REQUEST", "REPLY"}; static char *_bootp_hw_type[] = {"", "Ethernet", "Exp Ethernet", "AX25", "Pronet", "Chaos", "IEEE802", "Arcnet"}; +static char *_dhcpmsgs[] = {"","DISCOVER", "OFFER", "REQUEST", "DECLINE", + "ACK", "NAK", "RELEASE" }; + void show_bootp(const char *intf, struct bootp *bp) { int i, len; - unsigned char *op, *ap = 0; + unsigned char *op, *ap = 0, optover; unsigned char name[128]; struct in_addr addr[32]; diag_printf("BOOTP[%s] op: %s\n", intf, _bootp_op[bp->bp_op]); - diag_printf(" hw_type: %s\n", _bootp_hw_type[bp->bp_htype]); + diag_printf(" htype: %s\n", _bootp_hw_type[bp->bp_htype]); + diag_printf(" hlen: %d\n", bp->bp_hlen ); + diag_printf(" hops: %d\n", bp->bp_hops ); + diag_printf(" xid: 0x%x\n", bp->bp_xid ); + diag_printf(" secs: %d\n", bp->bp_secs ); + diag_printf(" flags: 0x%x\n", bp->bp_flags ); diag_printf(" hw_addr: "); for (i = 0; i < bp->bp_hlen; i++) { diag_printf("%02x", bp->bp_chaddr[i]); @@ -247,12 +261,13 @@ show_bootp(const char *intf, struct boot diag_printf(" my IP: %s\n", inet_ntoa(bp->bp_yiaddr)); diag_printf(" server IP: %s\n", inet_ntoa(bp->bp_siaddr)); diag_printf(" gateway IP: %s\n", inet_ntoa(bp->bp_giaddr)); - if (bp->bp_sname[0]) { + + optover = 0; // See whether sname and file are overridden for options + (void)get_bootp_option( bp, TAG_DHCP_OPTOVER, &optover ); + if ( !(1 & optover) && bp->bp_sname[0] ) diag_printf(" server: %s\n", bp->bp_sname); - } - if (bp->bp_file[0]) { + if ( ! (2 & optover) && bp->bp_file[0] ) diag_printf(" file: %s\n", bp->bp_file); - } if (bp->bp_vend[0]) { diag_printf(" options:\n"); op = &bp->bp_vend[4]; @@ -291,8 +306,51 @@ show_bootp(const char *intf, struct boot if (*op == TAG_HOST_NAME) ap = " host name"; diag_printf(" %s: %s\n", ap, name); break; + case TAG_DHCP_MESS_TYPE: + diag_printf(" DHCP message: %d %s\n", + op[2], _dhcpmsgs[op[2]] ); + break; + case TAG_DHCP_REQ_IP: + diag_printf(" DHCP requested ip: %d.%d.%d.%d\n", + op[2], op[3], op[4], op[5] ); + break; + case TAG_DHCP_LEASE_TIME : + case TAG_DHCP_RENEWAL_TIME : + case TAG_DHCP_REBIND_TIME : + diag_printf(" DHCP time %d: %d\n", + *op, ((((((op[2]<<8)+op[3])<<8)+op[4])<<8)+op[5]) ); + + break; + case TAG_DHCP_SERVER_ID : + diag_printf(" DHCP server id: %d.%d.%d.%d\n", + op[2], op[3], op[4], op[5] ); + break; + + case TAG_DHCP_OPTOVER : + case TAG_DHCP_PARM_REQ_LIST: + case TAG_DHCP_TEXT_MESSAGE : + case TAG_DHCP_MAX_MSGSZ : + case TAG_DHCP_CLASSID : + case TAG_DHCP_CLIENTID : + diag_printf(" DHCP option: %x/%d.%d:", *op, *op, *(op+1)); + if ( 1 == op[1] ) + diag_printf( " %d", op[2] ); + else if ( 2 == op[1] ) + diag_printf( " %d", (op[2]<<8)+op[3] ); + else if ( 4 == op[1] ) + diag_printf( " %d", ((((((op[2]<<8)+op[3])<<8)+op[4])<<8)+op[5]) ); + else + for ( i = 2; i < 2 + op[1]; i++ ) + diag_printf(" %d",op[i]); + diag_printf("\n"); + break; + default: - diag_printf("Unknown option: %x.%d\n", *op, *(op+1)); + diag_printf("Unknown option: %x/%d.%d:", *op, *op, *(op+1)); + for ( i = 2; i < 2 + op[1]; i++ ) + diag_printf(" %d",op[i]); + diag_printf("\n"); + break; } op += *(op+1)+2; } @@ -302,19 +360,38 @@ show_bootp(const char *intf, struct boot cyg_bool_t get_bootp_option(struct bootp *bp, unsigned char tag, void *opt) { - unsigned char *op; unsigned char *val = (unsigned char *)opt; int i; - op = &bp->bp_vend[4]; - while (*op != TAG_END) { - if (*op == tag) { - for (i = 0; i < *(op+1); i++) { - *val++ = *(op+i+2); - } - return true; - } - op += *(op+1)+2; - } + cyg_uint8 optover; + +#define SCANTAG( ptr ) CYG_MACRO_START \ + unsigned char *op = (ptr); \ + while (*op != TAG_END) { \ + if (*op == tag) { \ + for (i = 0; i < *(op+1); i++) { \ + *val++ = *(op+i+2); \ + } \ + return true; \ + } \ + op += *(op+1)+2; \ + } \ +CYG_MACRO_END + + SCANTAG( &bp->bp_vend[4] ); + + if ( TAG_DHCP_OPTOVER == tag ) // prevent recursion > once + return false; + // else, look for that tag to see if there's more... + optover = 0; + if ( ! get_bootp_option( bp, TAG_DHCP_OPTOVER, &optover ) ) + return false; + + if ( 1 & optover ) // then the file field also holds options + SCANTAG( &bp->bp_file[0] ); + + if ( 2 & optover ) // then the sname field also holds options + SCANTAG( &bp->bp_sname[0] ); + return false; }
