Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

SRC/pcbootp.c

Go to the documentation of this file.
00001 00013 #include <stdio.h> 00014 #include <stdlib.h> 00015 00016 #include "copyrigh.h" 00017 #include "wattcp.h" 00018 #include "strings.h" 00019 #include "language.h" 00020 #include "udp_dom.h" 00021 #include "syslog2.h" 00022 #include "misc.h" 00023 #include "timer.h" 00024 #include "netaddr.h" 00025 #include "pctcp.h" 00026 #include "pcsed.h" 00027 #include "pcarp.h" 00028 #include "pcconfig.h" 00029 #include "pcqueue.h" 00030 #include "pcpkt.h" 00031 #include "pcbootp.h" 00032 00033 DWORD _bootp_host = IP_BCAST_ADDR; 00034 00035 #if defined(USE_DHCP) 00036 int _bootp_timeout = 15; /* give DHCP a chance also (sock_delay=30) */ 00037 #else 00038 int _bootp_timeout = 30; 00039 #endif 00040 00041 #if defined(USE_BOOTP) 00042 00043 static sock_type *boot_sock; 00044 00045 static int bootp_xmit (struct bootp *bootp_out); 00046 static BOOL bootp_recv (struct bootp *bootp_out, struct bootp *bootp_in); 00047 static void bootp_parse (const struct bootp *bootp_in, int len); 00048 00058 int BOOTP_do_boot (void) 00059 { 00060 struct bootp bootp_out, bootp_in; 00061 struct _udp_Socket sock; 00062 DWORD save_ip = my_ip_addr; 00063 int rc = 0; 00064 00065 boot_sock = (sock_type*) &sock; 00066 00067 outs (_LANG("Configuring through BOOTP..")); 00068 00069 my_ip_addr = 0UL; /* We must use IP address 0.0.0.0 for sending */ 00070 00071 if (!udp_open(&sock,IPPORT_BOOTPC,_bootp_host,IPPORT_BOOTPS,NULL)) 00072 { 00073 outsnl (boot_sock->udp.err_msg); 00074 my_ip_addr = save_ip; 00075 } 00076 else 00077 { 00078 memset (&bootp_in, 0, sizeof(bootp_in)); 00079 memset (&bootp_out, 0, sizeof(bootp_out)); 00080 bootp_xmit (&bootp_out); 00081 if (bootp_recv(&bootp_out, &bootp_in)) 00082 { 00083 my_ip_addr = intel (bootp_in.bp_yiaddr); 00084 rc = 1; 00085 } 00086 } 00087 sock_close (boot_sock); 00088 boot_sock = NULL; 00089 outsnl (rc ? "okay" : "failed"); 00090 return (rc); 00091 } 00092 00093 static int bootp_xmit (struct bootp *bootp_out) 00094 { 00095 DWORD exchange_id = set_timeout (0); /* "random" exchange ID */ 00096 00097 _eth_get_hwtype (&bootp_out->bp_htype, &bootp_out->bp_hlen); 00098 00099 bootp_out->bp_op = BOOTP_REQUEST; 00100 bootp_out->bp_xid = exchange_id; 00101 bootp_out->bp_secs = intel16 (((WORD)exchange_id & 7) + 7); 00102 *(DWORD*) &bootp_out->bp_vend = intel (VM_RFC1048); /* Magic Number */ 00103 00104 memcpy (&bootp_out->bp_chaddr, _eth_addr, _eth_mac_len); 00105 return sock_fastwrite (boot_sock, (BYTE*)bootp_out, sizeof(*bootp_out)); 00106 } 00107 00108 static BOOL bootp_recv (struct bootp *bootp_out, struct bootp *bootp_in) 00109 { 00110 DWORD exchange_id = bootp_out->bp_xid; 00111 DWORD boot_timer = set_timeout (1000 * _bootp_timeout); 00112 00113 while (1) 00114 { 00115 DWORD vendor; 00116 int len; 00117 00118 WATT_YIELD(); 00119 00120 if (chk_timeout(boot_timer) || !tcp_tick(boot_sock)) 00121 return (FALSE); 00122 00123 if (sock_dataready(boot_sock) < sizeof(*bootp_in)) 00124 continue; 00125 00126 /* got a response, lets consider it 00127 */ 00128 memset (bootp_in, 0, sizeof(*bootp_in)); 00129 len = sock_fastread (boot_sock, (BYTE*)bootp_in, sizeof(*bootp_in)); 00130 if (len < BOOTP_MIN_SIZE || 00131 bootp_in->bp_op != BOOTP_REPLY) 00132 continue; 00133 00134 /* Check if transaction ID and MAC-address matches 00135 */ 00136 if (bootp_in->bp_xid != exchange_id || 00137 memcmp(&bootp_in->bp_chaddr, _eth_addr, _eth_mac_len)) 00138 continue; 00139 00140 vendor = intel (*(DWORD*)&bootp_in->bp_vend); 00141 if (vendor == VM_RFC1048) 00142 bootp_parse (bootp_in, len); 00143 break; 00144 } 00145 return (TRUE); 00146 } 00147 00148 /* 00149 * Parse RFC1048 compliant BOOTP vendor field. 00150 * Based heavily on NCSA Telnet BOOTP 00151 */ 00152 static void bootp_parse (const struct bootp *bootp_in, int max) 00153 { 00154 const BYTE *p = &bootp_in->bp_vend[4]; /* Point after magic value */ 00155 const BYTE *end = max + (const BYTE*)bootp_in; 00156 BOOL got_end = FALSE; 00157 00158 while (!got_end && p < end) 00159 { 00160 DWORD ip; 00161 int i, len; 00162 00163 switch (*p) 00164 { 00165 case BOOTP_OPT_PAD: 00166 p++; 00167 continue; 00168 00169 case BOOTP_OPT_SUBNET_MASK: 00170 sin_mask = intel (*(DWORD*)(p+2)); 00171 break; 00172 00173 case BOOTP_OPT_ROUTERS_ON_SNET: 00174 /* only add first */ 00175 ip = intel (*(DWORD*)(p+2)); 00176 _arp_add_gateway (NULL, ip); 00177 break; 00178 00179 case BOOTP_OPT_DNS_SRV: 00180 for (i = 0; i < *(p+1); i += sizeof(ip)) 00181 { 00182 ip = intel (*(DWORD*)(p+2+i)); 00183 _add_server (&last_nameserver, MAX_NAMESERVERS, 00184 def_nameservers, ip); 00185 } 00186 break; 00187 00188 case BOOTP_OPT_COOKIE_SRV: 00189 for (i = 0; i < *(p+1) ; i += sizeof(ip)) 00190 { 00191 ip = intel (*(DWORD*)(p+2+i)); 00192 _add_server (&last_cookie, MAX_COOKIES, cookies, ip); 00193 } 00194 break; 00195 00196 #if defined(USE_BSD_API) 00197 case BOOTP_OPT_LOG_SRV: 00198 ip = intel (*(DWORD*)(p+2)); /* select 1st host */ 00199 if (!syslog_host_name[0] && /* not in config-file */ 00200 p[1] % 4 == 0) /* length = n * 4 */ 00201 StrLcpy (syslog_host_name, _inet_ntoa(NULL,ip), 00202 sizeof(syslog_host_name)); 00203 break; 00204 #endif 00205 00206 case BOOTP_OPT_HOST_NAME: 00207 len = min (p[1], sizeof(hostname)); 00208 memcpy (&hostname[0], p+2, len); 00209 hostname[len] = '\0'; 00210 break; 00211 00212 case BOOTP_OPT_NAME_SRV: /* IEN-116 name server */ 00213 case BOOTP_OPT_LPR_SRV: 00214 case BOOTP_OPT_IMPRESS_SRV: 00215 case BOOTP_OPT_RES_LOCATION_SRV: 00216 case BOOTP_OPT_TIME_SRV: 00217 case BOOTP_OPT_TIME_OFFSET: 00218 break; 00219 00220 case BOOTP_OPT_END: 00221 got_end = TRUE; 00222 break; 00223 00224 default: 00225 break; 00226 } 00227 p += *(p+1) + 2; 00228 } 00229 } 00230 #endif /* USE_BOOTP */ 00231

Generated on Wed Aug 4 08:55:49 2010 for Watt-32 tcp/ip by doxygen 1.3.8