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;
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;
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);
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);
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
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
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
00150
00151
00152
static void bootp_parse (
const struct bootp *bootp_in,
int max)
00153 {
00154
const BYTE *p = &bootp_in->
bp_vend[4];
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
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));
00199
if (!syslog_host_name[0] &&
00200 p[1] % 4 == 0)
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:
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
00231