URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/bootloaders/orpmon/services
- from Rev 405 to Rev 406
- ↔ Reverse comparison
Rev 405 → Rev 406
/modem.c
19,26 → 19,23
#define TIMEOUT 3 |
|
/* update CRC */ |
unsigned short |
updcrc(register int c, register unsigned int crc) |
unsigned short updcrc(register int c, register unsigned int crc) |
{ |
register int count; |
|
for (count=8; --count>=0;) { |
if (crc & 0x8000) { |
crc <<= 1; |
crc += (((c<<=1) & 0400) != 0); |
crc ^= 0x1021; |
} |
else { |
crc <<= 1; |
crc += (((c<<=1) & 0400) != 0); |
} |
} |
return crc; |
register int count; |
|
for (count = 8; --count >= 0;) { |
if (crc & 0x8000) { |
crc <<= 1; |
crc += (((c <<= 1) & 0400) != 0); |
crc ^= 0x1021; |
} else { |
crc <<= 1; |
crc += (((c <<= 1) & 0400) != 0); |
} |
} |
return crc; |
} |
|
|
static thand_f *mTimeHandler; |
static unsigned long mTimeValue; |
static int mTimeoutCount; |
52,191 → 49,184
|
static void mStartTimeout(void); |
|
void |
mSetTimeout(int iv, thand_f *f) |
void mSetTimeout(int iv, thand_f * f) |
{ |
if(iv == 0) |
mTimeHandler = (thand_f *)0; |
else { |
mTimeHandler = f; |
mTimeValue = get_timer(0) + iv; |
} |
if (iv == 0) |
mTimeHandler = (thand_f *) 0; |
else { |
mTimeHandler = f; |
mTimeValue = get_timer(0) + iv; |
} |
} |
|
static void |
mStartTimeout(void) |
static void mStartTimeout(void) |
{ |
if(++mTimeoutCount >= RETRY) { |
printf("...retry counter exceeded, quitting...\n"); |
return; |
} else { |
printf("."); |
mSetTimeout(TIMEOUT * TICKS_PER_SEC, mStartTimeout); |
uart_putc(C); |
if (++mTimeoutCount >= RETRY) { |
printf("...retry counter exceeded, quitting...\n"); |
return; |
} else { |
printf("."); |
mSetTimeout(TIMEOUT * TICKS_PER_SEC, mStartTimeout); |
uart_putc(C); |
|
} |
} |
} |
|
static void |
mReceiveTimeout(void) |
static void mReceiveTimeout(void) |
{ |
if(++mTimeoutCount >= RETRY) { |
uart_putc(NAK); |
printf("..."); |
return; |
} else { |
mSetTimeout(TIMEOUT * TICKS_PER_SEC, mReceiveTimeout); |
uart_putc(NAK); |
} |
if (++mTimeoutCount >= RETRY) { |
uart_putc(NAK); |
printf("..."); |
return; |
} else { |
mSetTimeout(TIMEOUT * TICKS_PER_SEC, mReceiveTimeout); |
uart_putc(NAK); |
} |
} |
|
int |
getBlock(unsigned char t) |
int getBlock(unsigned char t) |
{ |
unsigned int i = 0, j = 0; |
unsigned char mybuf[133]; |
unsigned char bNo, nBno; |
unsigned long dst_addr; |
unsigned int i = 0, j = 0; |
unsigned char mybuf[133]; |
unsigned char bNo, nBno; |
unsigned long dst_addr; |
|
unsigned char flags; |
flags = UART_LSR_FE | UART_LSR_PE | UART_LSR_OE | UART_LSR_BI; /*frame,parity,overrun errors */ |
unsigned char flags; |
flags = UART_LSR_FE | UART_LSR_PE | UART_LSR_OE | UART_LSR_BI; /*frame,parity,overrun errors */ |
|
mycrc = 0; |
mycrc = 0; |
|
switch(t) { |
case SOH: |
for(i = 0; i < 132; i++) { |
if((REG8(UART_BASE + UART_LSR) & flags) == flags) { |
uart_putc(CAN); |
} |
mybuf[i] = uart_getc(); |
} |
switch (t) { |
case SOH: |
for (i = 0; i < 132; i++) { |
if ((REG8(UART_BASE + UART_LSR) & flags) == flags) { |
uart_putc(CAN); |
} |
mybuf[i] = uart_getc(); |
} |
|
bNo = mybuf[0]; /* packet id */ |
nBno = mybuf[1]; /* neg. packet id */ |
bNo = mybuf[0]; /* packet id */ |
nBno = mybuf[1]; /* neg. packet id */ |
|
if((bNo == 0x00) && (nBno == 0xff) && (bno == 0)) { /* start block */ |
modemMode = 2; /* ymodem */ |
uart_putc(ACK); |
uart_putc(C); |
return 1; |
} |
else if((0xff-bNo) == nBno) { /* data block */ |
for(i = 2, j = 0; i < 130; i++, j++) { |
length++; |
mycrc = updcrc(mybuf[i], mycrc); |
dst_addr = src_addr+(bno*0x8000)+((bNo-1)*0x80)+j; |
REG8(dst_addr) = mybuf[i]; |
} |
if ((bNo == 0x00) && (nBno == 0xff) && (bno == 0)) { /* start block */ |
modemMode = 2; /* ymodem */ |
uart_putc(ACK); |
uart_putc(C); |
return 1; |
} else if ((0xff - bNo) == nBno) { /* data block */ |
for (i = 2, j = 0; i < 130; i++, j++) { |
length++; |
mycrc = updcrc(mybuf[i], mycrc); |
dst_addr = |
src_addr + (bno * 0x8000) + |
((bNo - 1) * 0x80) + j; |
REG8(dst_addr) = mybuf[i]; |
} |
|
mycrc = updcrc(mybuf[130], mycrc); |
mycrc = updcrc(mybuf[131], mycrc); |
mycrc = updcrc(mybuf[130], mycrc); |
mycrc = updcrc(mybuf[131], mycrc); |
|
if(mycrc == 0) /* CRC match! */ { |
uart_putc(ACK); |
for(i=0;i < 128; i+=4) { |
/* for(j=0; j<4; j++) { |
tmp = tmp << 8; |
tmp |= mybuf[i+j+2]; |
if (mycrc == 0) { /* CRC match! */ |
uart_putc(ACK); |
for (i = 0; i < 128; i += 4) { |
/* for(j=0; j<4; j++) { |
tmp = tmp << 8; |
tmp |= mybuf[i+j+2]; |
} |
dst_addr = src_addr+(bno*0x8000)+((bNo-1)*128)+i; |
fl_word_program(dst_addr, tmp); */ |
} |
if (bNo == 0xff) |
bno++; |
return 1; |
} else { |
uart_putc(NAK); |
return -1; |
} |
} else { /* packet id didn't match neg packet id! */ |
uart_putc(NAK); |
return -1; |
} |
return 1; |
break; |
case EOT: |
if (modemMode == 2) { /* ymodem */ |
uart_putc(NAK); |
if (uart_getc() == EOT) { |
uart_putc(ACK); |
uart_putc(C); |
} else |
uart_putc(ACK); |
} else /* zmodem */ |
uart_putc(ACK); |
|
return 0; |
break; |
default: |
/* Unknown header */ |
uart_putc(NAK); |
return -1; |
} |
dst_addr = src_addr+(bno*0x8000)+((bNo-1)*128)+i; |
fl_word_program(dst_addr, tmp);*/ |
} |
if(bNo == 0xff) |
bno++; |
return 1; |
} |
else { |
uart_putc(NAK); |
return -1; |
} |
} |
else { /* packet id didn't match neg packet id! */ |
uart_putc(NAK); |
return -1; |
} |
return 1; |
break; |
case EOT: |
if(modemMode == 2) {/* ymodem */ |
uart_putc(NAK); |
if(uart_getc() == EOT) { |
uart_putc(ACK); |
uart_putc(C); |
} |
else |
uart_putc(ACK); |
} else /* zmodem */ |
uart_putc(ACK); |
|
return 0; |
break; |
default: |
/* Unknown header */ |
uart_putc(NAK); |
return -1; |
} |
} |
|
int |
mGetData(unsigned long saddr) |
int mGetData(unsigned long saddr) |
{ |
int retval = 1; |
unsigned char c; |
int retval = 1; |
unsigned char c; |
|
length = 0; |
src_addr = saddr; |
modemMode = 1; |
bno = 0; |
length = 0; |
src_addr = saddr; |
modemMode = 1; |
bno = 0; |
|
printf("src_addr: 0x%lx\n", src_addr); |
if(fl_init() != 0) { |
printf("Flash init failed!\n"); |
return(-1); |
} |
|
printf("src_addr: 0x%lx\n", src_addr); |
if (fl_init() != 0) { |
printf("Flash init failed!\n"); |
return (-1); |
} |
#if 0 |
printf("Unlocking flash..."); |
for (i = 0, c = FLASH_BASE_ADDR; i < (FLASH_SIZE / FLASH_BLOCK_SIZE); |
i++, c += FLASH_BLOCK_SIZE) |
if (fl_unlock_one_block (c)) return 1; |
printf("done\n"); |
printf("Unlocking flash..."); |
for (i = 0, c = FLASH_BASE_ADDR; i < (FLASH_SIZE / FLASH_BLOCK_SIZE); |
i++, c += FLASH_BLOCK_SIZE) |
if (fl_unlock_one_block(c)) |
return 1; |
printf("done\n"); |
|
printf("Erasing flash..."); |
for (i = 0, c = FLASH_BASE_ADDR; i < (FLASH_SIZE / FLASH_BLOCK_SIZE); |
i++, c += FLASH_BLOCK_SIZE) |
if (fl_block_erase (c)) return 1; |
printf ("done\n"); |
printf("Erasing flash..."); |
for (i = 0, c = FLASH_BASE_ADDR; i < (FLASH_SIZE / FLASH_BLOCK_SIZE); |
i++, c += FLASH_BLOCK_SIZE) |
if (fl_block_erase(c)) |
return 1; |
printf("done\n"); |
#endif |
printf("Waiting..."); |
printf("Waiting..."); |
|
mTimeoutCount = 0; |
mSetTimeout(TIMEOUT * TICKS_PER_SEC, mStartTimeout); |
mTimeoutCount = 0; |
mSetTimeout(TIMEOUT * TICKS_PER_SEC, mStartTimeout); |
|
while(1) { |
if(mTimeHandler && (get_timer(0) > mTimeValue)) { |
thand_f *x; |
x = mTimeHandler; |
mTimeHandler = (thand_f *)0; |
(*x)(); |
} |
c = uart_testc(); |
if(c != 0) |
break; |
} |
while (1) { |
if (mTimeHandler && (get_timer(0) > mTimeValue)) { |
thand_f *x; |
x = mTimeHandler; |
mTimeHandler = (thand_f *) 0; |
(*x) (); |
} |
c = uart_testc(); |
if (c != 0) |
break; |
} |
|
while(retval != 0) { |
retval = getBlock(c); |
if(retval != 0) |
c = uart_getc(); |
} |
while (retval != 0) { |
retval = getBlock(c); |
if (retval != 0) |
c = uart_getc(); |
} |
|
if(modemMode == 2) { |
c = uart_getc(); |
retval = getBlock(c); /* last 'dummy' block for YModem */ |
printf("... protocol: YModem, "); |
} |
else |
printf("... protocol: ZModem, "); |
return length; |
if (modemMode == 2) { |
c = uart_getc(); |
retval = getBlock(c); /* last 'dummy' block for YModem */ |
printf("... protocol: YModem, "); |
} else |
printf("... protocol: ZModem, "); |
return length; |
} |
/arp.c
29,13 → 29,14
#include "arp.h" |
#include "string.h" |
|
#define TIMEOUT 5 /* Seconds before trying ARP again */ |
#define TIMEOUT_COUNT 1 /* # of timeouts before giving up */ |
#define DEBUG // jb |
static void ArpHandler(unsigned char *pkt, unsigned dest, unsigned src, unsigned len); |
#define TIMEOUT 5 /* Seconds before trying ARP again */ |
#define TIMEOUT_COUNT 1 /* # of timeouts before giving up */ |
#define DEBUG // jb |
static void ArpHandler(unsigned char *pkt, unsigned dest, unsigned src, |
unsigned len); |
static void ArpTimeout(void); |
|
int ArpTry = 0; |
int ArpTry = 0; |
|
/* |
* Handle a ARP received packet. |
44,68 → 45,67
ArpHandler(unsigned char *pkt, unsigned dest, unsigned src, unsigned len) |
{ |
/* Check if the frame is really an ARP reply */ |
if (memcmp (NetServerEther, NetBcastAddr, 6) != 0) { |
if (memcmp(NetServerEther, NetBcastAddr, 6) != 0) { |
#ifdef DEBUG |
printf("Got good ARP - start TFTP\n"); |
#endif |
TftpStart (); |
TftpStart(); |
} |
} |
|
|
/* |
* Timeout on ARP request. |
*/ |
static void |
ArpTimeout(void) |
static void ArpTimeout(void) |
{ |
if (ArpTry >= TIMEOUT_COUNT) { |
printf("\nRetry count exceeded; starting again\n"); |
NetStartAgain (); |
NetStartAgain(); |
} else { |
NetSetTimeout (TIMEOUT * TICKS_PER_SEC, ArpTimeout); |
ArpRequest (); |
NetSetTimeout(TIMEOUT * TICKS_PER_SEC, ArpTimeout); |
ArpRequest(); |
} |
} |
|
|
void |
ArpRequest (void) |
void ArpRequest(void) |
{ |
int i; |
volatile unsigned char *pkt; |
ARP_t * arp; |
ARP_t *arp; |
#ifdef DEBUG |
printf("ARP broadcast %d\n", ++ArpTry); |
#endif |
pkt = NetTxPacket; |
#endif |
// NetTxPacket is a char* to global buffer used for constructing |
// a packet to send. |
pkt = NetTxPacket; |
|
// Setup an ethernet header for ARP protocol in packet |
NetSetEther(pkt, NetBcastAddr, PROT_ARP); |
pkt += ETHER_HDR_SIZE; |
|
arp = (ARP_t *)pkt; |
arp = (ARP_t *) pkt; |
|
arp->ar_hrd = ARP_ETHER; |
arp->ar_pro = PROT_IP; |
arp->ar_hln = 6; |
arp->ar_pln = 4; |
arp->ar_op = ARPOP_REQUEST; |
arp->ar_op = ARPOP_REQUEST; |
NetCopyEther(&arp->ar_data[0], NetOurEther); /* source ET addr */ |
//*(IPaddr_t *)(&arp->ar_data[6]) = NetOurIP; /* source IP addr */ |
memcpy(&arp->ar_data[6], (unsigned char*) &NetOurIP, 4); |
|
for (i=10; i<16; ++i) { |
arp->ar_data[i] = 0; /* dest ET addr = 0*/ |
//*(IPaddr_t *)(&arp->ar_data[6]) = NetOurIP; /* source IP addr */ |
memcpy(&arp->ar_data[6], (unsigned char *)&NetOurIP, 4); |
|
for (i = 10; i < 16; ++i) { |
arp->ar_data[i] = 0; /* dest ET addr = 0 */ |
} |
|
if((NetServerIP & NetOurSubnetMask) != (NetOurIP & NetOurSubnetMask)) { |
//*(IPaddr_t *)(&arp->ar_data[16]) = NetOurGatewayIP; |
memcpy(&arp->ar_data[16], (unsigned char*) &NetOurGatewayIP, |
sizeof(IPaddr_t)); |
if ((NetServerIP & NetOurSubnetMask) != (NetOurIP & NetOurSubnetMask)) { |
//*(IPaddr_t *)(&arp->ar_data[16]) = NetOurGatewayIP; |
memcpy(&arp->ar_data[16], (unsigned char *)&NetOurGatewayIP, |
sizeof(IPaddr_t)); |
} else { |
//*((IPaddr_t *)(&(arp->ar_data[16]))) = NetServerIP; |
memcpy(&arp->ar_data[16], (unsigned char*) &NetServerIP, |
sizeof(IPaddr_t)); |
//*((IPaddr_t *)(&(arp->ar_data[16]))) = NetServerIP; |
memcpy(&arp->ar_data[16], (unsigned char *)&NetServerIP, |
sizeof(IPaddr_t)); |
} |
|
NetSendPacket(NetTxPacket, ETHER_HDR_SIZE + ARP_HDR_SIZE); |
113,4 → 113,3
NetSetTimeout(TIMEOUT * TICKS_PER_SEC, ArpTimeout); |
NetSetHandler(ArpHandler); |
} |
|
/tftp.h
14,7 → 14,7
*/ |
|
/* tftp.c */ |
extern void TftpStart (void); /* Begin TFTP get */ |
extern void TftpStart(void); /* Begin TFTP get */ |
|
/**********************************************************************/ |
|
/bootp.c
9,7 → 9,7
|
#if 1 |
#define DEBUG 1 /* general debug */ |
#define DEBUG_BOOTP_EXT 1 /* Debug received vendor fields */ |
#define DEBUG_BOOTP_EXT 1 /* Debug received vendor fields */ |
#endif |
|
#ifdef DEBUG_BOOTP_EXT |
24,24 → 24,24
#include "tftp.h" |
#include "arp.h" |
|
#define BOOTP_VENDOR_MAGIC 0x63825363 /* RFC1048 Magic Cookie */ |
#define BOOTP_VENDOR_MAGIC 0x63825363 /* RFC1048 Magic Cookie */ |
|
#if (CONFIG_COMMANDS & CFG_CMD_NET) |
|
#define TIMEOUT 5 /* Seconds before trying BOOTP again */ |
#define TIMEOUT_COUNT 1 /* # of timeouts before giving up */ |
#define TIMEOUT 5 /* Seconds before trying BOOTP again */ |
#define TIMEOUT_COUNT 1 /* # of timeouts before giving up */ |
|
#define PORT_BOOTPS 67 /* BOOTP server UDP port */ |
#define PORT_BOOTPC 68 /* BOOTP client UDP port */ |
#define PORT_BOOTPS 67 /* BOOTP server UDP port */ |
#define PORT_BOOTPC 68 /* BOOTP client UDP port */ |
|
#ifndef CONFIG_DHCP_MIN_EXT_LEN /* minimal length of extension list */ |
#ifndef CONFIG_DHCP_MIN_EXT_LEN /* minimal length of extension list */ |
#define CONFIG_DHCP_MIN_EXT_LEN 64 |
#endif |
|
ulong BootpID; |
int BootpTry; |
ulong BootpID; |
int BootpTry; |
#ifdef CONFIG_BOOTP_RANDOM_DELAY |
ulong seed1, seed2; |
ulong seed1, seed2; |
#endif |
|
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
53,25 → 53,41
char *dhcpmsg2str(int type) |
{ |
switch (type) { |
case 1: return "DHCPDISCOVER"; break; |
case 2: return "DHCPOFFER"; break; |
case 3: return "DHCPREQUEST"; break; |
case 4: return "DHCPDECLINE"; break; |
case 5: return "DHCPACK"; break; |
case 6: return "DHCPNACK"; break; |
case 7: return "DHCPRELEASE"; break; |
default: return "UNKNOWN/INVALID MSG TYPE"; break; |
case 1: |
return "DHCPDISCOVER"; |
break; |
case 2: |
return "DHCPOFFER"; |
break; |
case 3: |
return "DHCPREQUEST"; |
break; |
case 4: |
return "DHCPDECLINE"; |
break; |
case 5: |
return "DHCPACK"; |
break; |
case 6: |
return "DHCPNACK"; |
break; |
case 7: |
return "DHCPRELEASE"; |
break; |
default: |
return "UNKNOWN/INVALID MSG TYPE"; |
break; |
} |
} |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX) |
extern u8 *dhcp_vendorex_prep (u8 *e); /*rtn new e after add own opts. */ |
extern u8 *dhcp_vendorex_proc (u8 *e); /*rtn next e if mine,else NULL */ |
extern u8 *dhcp_vendorex_prep(u8 * e); /*rtn new e after add own opts. */ |
extern u8 *dhcp_vendorex_proc(u8 * e); /*rtn next e if mine,else NULL */ |
#endif |
|
#endif /* CFG_CMD_DHCP */ |
#endif /* CFG_CMD_DHCP */ |
|
static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len) |
static int BootpCheckPkt(uchar * pkt, unsigned dest, unsigned src, unsigned len) |
{ |
Bootp_t *bp = (Bootp_t *) pkt; |
int retval = 0; |
78,13 → 94,12
|
if (dest != PORT_BOOTPC || src != PORT_BOOTPS) |
retval = -1; |
if (len < sizeof (Bootp_t) - OPT_SIZE) |
if (len < sizeof(Bootp_t) - OPT_SIZE) |
retval = -2; |
if (bp->bp_op != OP_BOOTREQUEST && |
bp->bp_op != OP_BOOTREPLY && |
bp->bp_op != DHCP_OFFER && |
bp->bp_op != DHCP_ACK && |
bp->bp_op != DHCP_NAK ) { |
bp->bp_op != DHCP_ACK && bp->bp_op != DHCP_NAK) { |
retval = -3; |
} |
if (bp->bp_htype != HWT_ETHER) |
94,7 → 109,7
if (bp->bp_id != BootpID) |
retval = -6; |
|
debug ("Filtering pkt = %d\n", retval); |
debug("Filtering pkt = %d\n", retval); |
|
return retval; |
} |
102,29 → 117,30
/* |
* Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet |
*/ |
void BootpCopyNetParams(Bootp_t *bp) |
void BootpCopyNetParams(Bootp_t * bp) |
{ |
NetOurIP = bp->bp_yiaddr; |
NetServerIP = bp->bp_siaddr; |
NetCopyEther(NetServerEther, ((Ethernet_t *)NetRxPkt)->et_src); |
copy_filename (BootFile, bp->bp_file, sizeof(BootFile)); |
NetCopyEther(NetServerEther, ((Ethernet_t *) NetRxPkt)->et_src); |
copy_filename(BootFile, bp->bp_file, sizeof(BootFile)); |
|
debug ("Bootfile: %s\n", BootFile); |
debug("Bootfile: %s\n", BootFile); |
|
/* Propagate to environment: |
* don't delete exising entry when BOOTP / DHCP reply does |
* don't delete exising entry when BOOTP / DHCP reply does |
* not contain a new value |
*/ |
if (*BootFile) { |
setenv ("bootfile", BootFile); |
setenv("bootfile", BootFile); |
} |
} |
|
static int truncate_sz (const char *name, int maxlen, int curlen) |
static int truncate_sz(const char *name, int maxlen, int curlen) |
{ |
if (curlen >= maxlen) { |
printf("*** WARNING: %s is too long (%d - max: %d) - truncated\n", |
name, curlen, maxlen); |
printf |
("*** WARNING: %s is too long (%d - max: %d) - truncated\n", |
name, curlen, maxlen); |
curlen = maxlen - 1; |
} |
return (curlen); |
132,180 → 148,183
|
#if !(CONFIG_COMMANDS & CFG_CMD_DHCP) |
|
static void BootpVendorFieldProcess(u8 *ext) |
static void BootpVendorFieldProcess(u8 * ext) |
{ |
int size = *(ext+1) ; |
int size = *(ext + 1); |
|
debug_ext ("[BOOTP] Processing extension %d... (%d bytes)\n", *ext, *(ext+1)); |
debug_ext("[BOOTP] Processing extension %d... (%d bytes)\n", *ext, |
*(ext + 1)); |
|
NetBootFileSize = 0; |
NetBootFileSize = 0; |
|
switch (*ext) { |
/* Fixed length fields */ |
case 1: /* Subnet mask */ |
switch (*ext) { |
/* Fixed length fields */ |
case 1: /* Subnet mask */ |
if (NetOurSubnetMask == 0) |
memcpy(&NetOurSubnetMask, ext+2, 4); |
memcpy(&NetOurSubnetMask, ext + 2, 4); |
break; |
case 2: /* Time offset - Not yet supported */ |
case 2: /* Time offset - Not yet supported */ |
break; |
/* Variable length fields */ |
case 3: /* Gateways list */ |
/* Variable length fields */ |
case 3: /* Gateways list */ |
if (NetOurGatewayIP == 0) { |
memcpy(&NetOurGatewayIP, ext+2, 4); |
memcpy(&NetOurGatewayIP, ext + 2, 4); |
} |
break; |
case 4: /* Time server - Not yet supported */ |
case 4: /* Time server - Not yet supported */ |
break; |
case 5: /* IEN-116 name server - Not yet supported */ |
case 5: /* IEN-116 name server - Not yet supported */ |
break; |
case 6: |
if (NetOurDNSIP == 0) { |
memcpy(&NetOurDNSIP, ext+2, 4); |
memcpy(&NetOurDNSIP, ext + 2, 4); |
} |
break; |
case 7: /* Log server - Not yet supported */ |
case 7: /* Log server - Not yet supported */ |
break; |
case 8: /* Cookie/Quote server - Not yet supported */ |
case 8: /* Cookie/Quote server - Not yet supported */ |
break; |
case 9: /* LPR server - Not yet supported */ |
case 9: /* LPR server - Not yet supported */ |
break; |
case 10: /* Impress server - Not yet supported */ |
case 10: /* Impress server - Not yet supported */ |
break; |
case 11: /* RPL server - Not yet supported */ |
case 11: /* RPL server - Not yet supported */ |
break; |
case 12: /* Host name */ |
case 12: /* Host name */ |
if (NetOurHostName[0] == 0) { |
size = truncate_sz("Host Name", sizeof(NetOurHostName), size); |
memcpy(&NetOurHostName, ext+2, size); |
NetOurHostName[size] = 0 ; |
size = |
truncate_sz("Host Name", sizeof(NetOurHostName), |
size); |
memcpy(&NetOurHostName, ext + 2, size); |
NetOurHostName[size] = 0; |
} |
break; |
case 13: /* Boot file size */ |
memcpy(&NetBootFileSize, ext+2, size); |
case 13: /* Boot file size */ |
memcpy(&NetBootFileSize, ext + 2, size); |
break; |
case 14: /* Merit dump file - Not yet supported */ |
case 14: /* Merit dump file - Not yet supported */ |
break; |
case 15: /* Domain name - Not yet supported */ |
case 15: /* Domain name - Not yet supported */ |
break; |
case 16: /* Swap server - Not yet supported */ |
case 16: /* Swap server - Not yet supported */ |
break; |
case 17: /* Root path */ |
case 17: /* Root path */ |
if (NetOurRootPath[0] == 0) { |
size = truncate_sz("Root Path", sizeof(NetOurRootPath), size); |
memcpy(&NetOurRootPath, ext+2, size); |
NetOurRootPath[size] = 0 ; |
size = |
truncate_sz("Root Path", sizeof(NetOurRootPath), |
size); |
memcpy(&NetOurRootPath, ext + 2, size); |
NetOurRootPath[size] = 0; |
} |
break; |
case 18: /* Extension path - Not yet supported */ |
case 18: /* Extension path - Not yet supported */ |
/* |
* This can be used to send the informations of the |
* vendor area in another file that the client can |
* access via TFTP. |
* This can be used to send the informations of the |
* vendor area in another file that the client can |
* access via TFTP. |
*/ |
break; |
/* IP host layer fields */ |
case 40: /* NIS Domain name */ |
/* IP host layer fields */ |
case 40: /* NIS Domain name */ |
if (NetOurNISDomain[0] == 0) { |
size = truncate_sz ("NIS Domain Name", |
sizeof(NetOurNISDomain), |
size); |
memcpy(&NetOurNISDomain, ext+2, size); |
NetOurNISDomain[size] = 0 ; |
size = truncate_sz("NIS Domain Name", |
sizeof(NetOurNISDomain), size); |
memcpy(&NetOurNISDomain, ext + 2, size); |
NetOurNISDomain[size] = 0; |
} |
break; |
/* Application layer fields */ |
case 43: /* Vendor specific info - Not yet supported */ |
/* Application layer fields */ |
case 43: /* Vendor specific info - Not yet supported */ |
/* |
* Binary informations to exchange specific |
* product information. |
* Binary informations to exchange specific |
* product information. |
*/ |
break; |
/* Reserved (custom) fields (128..254) */ |
} |
/* Reserved (custom) fields (128..254) */ |
} |
} |
|
static void BootpVendorProcess(u8 *ext, int size) |
static void BootpVendorProcess(u8 * ext, int size) |
{ |
u8 *end = ext + size ; |
u8 *end = ext + size; |
|
debug_ext ("[BOOTP] Checking extension (%d bytes)...\n", size); |
debug_ext("[BOOTP] Checking extension (%d bytes)...\n", size); |
|
while ((ext < end) && (*ext != 0xff)) { |
if (*ext == 0) { |
ext ++ ; |
} else { |
u8 *opt = ext ; |
ext += ext[1] + 2 ; |
if (ext <= end) |
BootpVendorFieldProcess (opt) ; |
while ((ext < end) && (*ext != 0xff)) { |
if (*ext == 0) { |
ext++; |
} else { |
u8 *opt = ext; |
ext += ext[1] + 2; |
if (ext <= end) |
BootpVendorFieldProcess(opt); |
} |
} |
} |
|
#ifdef DEBUG_BOOTP_EXT |
printf("[BOOTP] Received fields: \n"); |
if (NetOurSubnetMask) { |
puts ("NetOurSubnetMask : "); |
print_IPaddr (NetOurSubnetMask); |
putc('\n'); |
} |
printf("[BOOTP] Received fields: \n"); |
if (NetOurSubnetMask) { |
puts("NetOurSubnetMask : "); |
print_IPaddr(NetOurSubnetMask); |
putc('\n'); |
} |
|
if (NetOurGatewayIP) { |
puts ("NetOurGatewayIP : "); |
print_IPaddr (NetOurGatewayIP); |
putc('\n'); |
} |
if (NetOurGatewayIP) { |
puts("NetOurGatewayIP : "); |
print_IPaddr(NetOurGatewayIP); |
putc('\n'); |
} |
|
if (NetBootFileSize) { |
printf("NetBootFileSize : %d\n", NetBootFileSize); |
} |
if (NetBootFileSize) { |
printf("NetBootFileSize : %d\n", NetBootFileSize); |
} |
|
if (NetOurHostName[0]) { |
printf("NetOurHostName : %s\n", NetOurHostName); |
} |
if (NetOurHostName[0]) { |
printf("NetOurHostName : %s\n", NetOurHostName); |
} |
|
if (NetOurRootPath[0]) { |
printf("NetOurRootPath : %s\n", NetOurRootPath); |
} |
if (NetOurRootPath[0]) { |
printf("NetOurRootPath : %s\n", NetOurRootPath); |
} |
|
if (NetOurNISDomain[0]) { |
printf("NetOurNISDomain : %s\n", NetOurNISDomain); |
} |
#endif /* DEBUG_BOOTP_EXT */ |
if (NetOurNISDomain[0]) { |
printf("NetOurNISDomain : %s\n", NetOurNISDomain); |
} |
#endif /* DEBUG_BOOTP_EXT */ |
} |
|
/* |
* Handle a BOOTP received packet. |
*/ |
static void |
BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) |
static void BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) |
{ |
Bootp_t *bp; |
char *s; |
char *s; |
|
debug ("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%d)\n", |
src, dest, len, sizeof (Bootp_t)); |
debug("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%d)\n", |
src, dest, len, sizeof(Bootp_t)); |
|
bp = (Bootp_t *)pkt; |
bp = (Bootp_t *) pkt; |
|
if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */ |
return; |
|
/* |
* Got a good BOOTP reply. Copy the data into our variables. |
* Got a good BOOTP reply. Copy the data into our variables. |
*/ |
#ifdef CONFIG_STATUS_LED |
status_led_set (STATUS_LED_BOOT, STATUS_LED_OFF); |
status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF); |
#endif |
|
BootpCopyNetParams(bp); /* Store net parameters from reply */ |
BootpCopyNetParams(bp); /* Store net parameters from reply */ |
|
/* Retrieve extended informations (we must parse the vendor area) */ |
if ((*(uint *)bp->bp_vend) == BOOTP_VENDOR_MAGIC) |
BootpVendorProcess(&bp->bp_vend[4], len); |
if ((*(uint *) bp->bp_vend) == BOOTP_VENDOR_MAGIC) |
BootpVendorProcess(&bp->bp_vend[4], len); |
|
NetSetTimeout(0, (thand_f *)0); |
NetSetTimeout(0, (thand_f *) 0); |
|
debug ("Got good BOOTP\n"); |
debug("Got good BOOTP\n"); |
|
if (((s = getenv("autoload")) != NULL) && (*s == 'n')) { |
/* |
321,20 → 340,19
*/ |
ArpRequest(); |
} |
#endif /* !CFG_CMD_DHCP */ |
#endif /* !CFG_CMD_DHCP */ |
|
/* |
* Timeout on BOOTP/DHCP request. |
*/ |
static void |
BootpTimeout(void) |
static void BootpTimeout(void) |
{ |
if (BootpTry >= TIMEOUT_COUNT) { |
puts ("\nRetry count exceeded; starting again\n"); |
NetStartAgain (); |
puts("\nRetry count exceeded; starting again\n"); |
NetStartAgain(); |
} else { |
NetSetTimeout (TIMEOUT * CFG_HZ, BootpTimeout); |
BootpRequest (); |
NetSetTimeout(TIMEOUT * CFG_HZ, BootpTimeout); |
BootpRequest(); |
} |
} |
|
342,167 → 360,166
* Initialize BOOTP extension fields in the request. |
*/ |
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
static int DhcpExtended(u8 *e, int message_type, IPaddr_t ServerID, IPaddr_t RequestedIP) |
static int DhcpExtended(u8 * e, int message_type, IPaddr_t ServerID, |
IPaddr_t RequestedIP) |
{ |
u8 *start = e ; |
u8 *cnt; |
u8 *start = e; |
u8 *cnt; |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX) |
u8 *x; |
u8 *x; |
#endif |
|
*e++ = 99; /* RFC1048 Magic Cookie */ |
*e++ = 130; |
*e++ = 83; |
*e++ = 99; |
*e++ = 99; /* RFC1048 Magic Cookie */ |
*e++ = 130; |
*e++ = 83; |
*e++ = 99; |
|
*e++ = 53; /* DHCP Message Type */ |
*e++ = 1; |
*e++ = message_type; |
*e++ = 53; /* DHCP Message Type */ |
*e++ = 1; |
*e++ = message_type; |
|
*e++ = 57; /* Maximum DHCP Message Size */ |
*e++ = 2; |
*e++ = (576-312+OPT_SIZE) >> 8; |
*e++ = (576-312+OPT_SIZE) & 0xff; |
*e++ = 57; /* Maximum DHCP Message Size */ |
*e++ = 2; |
*e++ = (576 - 312 + OPT_SIZE) >> 8; |
*e++ = (576 - 312 + OPT_SIZE) & 0xff; |
|
if ( ServerID ) { |
*e++ = 54; /* ServerID */ |
*e++ = 4; |
*e++ = ServerID >> 24; |
*e++ = ServerID >> 16; |
*e++ = ServerID >> 8; |
*e++ = ServerID & 0xff; |
} |
if (ServerID) { |
*e++ = 54; /* ServerID */ |
*e++ = 4; |
*e++ = ServerID >> 24; |
*e++ = ServerID >> 16; |
*e++ = ServerID >> 8; |
*e++ = ServerID & 0xff; |
} |
|
if ( RequestedIP ) { |
*e++ = 50; /* Requested IP */ |
*e++ = 4; |
*e++ = RequestedIP >> 24; |
*e++ = RequestedIP >> 16; |
*e++ = RequestedIP >> 8; |
*e++ = RequestedIP & 0xff; |
} |
|
if (RequestedIP) { |
*e++ = 50; /* Requested IP */ |
*e++ = 4; |
*e++ = RequestedIP >> 24; |
*e++ = RequestedIP >> 16; |
*e++ = RequestedIP >> 8; |
*e++ = RequestedIP & 0xff; |
} |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX) |
if ((x = dhcp_vendorex_prep (e))) |
return x - start ; |
if ((x = dhcp_vendorex_prep(e))) |
return x - start; |
#endif |
|
*e++ = 55; /* Parameter Request List */ |
cnt = e++; /* Pointer to count of requested items */ |
*cnt = 0; |
*e++ = 55; /* Parameter Request List */ |
cnt = e++; /* Pointer to count of requested items */ |
*cnt = 0; |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_SUBNETMASK) |
*e++ = 1; /* Subnet Mask */ |
*cnt += 1; |
*e++ = 1; /* Subnet Mask */ |
*cnt += 1; |
#endif |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_GATEWAY) |
*e++ = 3; /* Router Option */ |
*cnt += 1; |
*e++ = 3; /* Router Option */ |
*cnt += 1; |
#endif |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS) |
*e++ = 6; /* DNS Server(s) */ |
*cnt += 1; |
*e++ = 6; /* DNS Server(s) */ |
*cnt += 1; |
#endif |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_HOSTNAME) |
*e++ = 12; /* Hostname */ |
*cnt += 1; |
*e++ = 12; /* Hostname */ |
*cnt += 1; |
#endif |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTFILESIZE) |
*e++ = 13; /* Boot File Size */ |
*cnt += 1; |
*e++ = 13; /* Boot File Size */ |
*cnt += 1; |
#endif |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTPATH) |
*e++ = 17; /* Boot path */ |
*cnt += 1; |
*e++ = 17; /* Boot path */ |
*cnt += 1; |
#endif |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NISDOMAIN) |
*e++ = 40; /* NIS Domain name request */ |
*cnt += 1; |
*e++ = 40; /* NIS Domain name request */ |
*cnt += 1; |
#endif |
*e++ = 255; /* End of the list */ |
*e++ = 255; /* End of the list */ |
|
/* Pad to minimal length */ |
/* Pad to minimal length */ |
#ifdef CONFIG_DHCP_MIN_EXT_LEN |
while ((e - start) <= CONFIG_DHCP_MIN_EXT_LEN) |
*e++ = 0; |
while ((e - start) <= CONFIG_DHCP_MIN_EXT_LEN) |
*e++ = 0; |
#endif |
|
return e - start ; |
return e - start; |
} |
|
#else /* CFG_CMD_DHCP */ |
#else /* CFG_CMD_DHCP */ |
/* |
* Warning: no field size check - change CONFIG_BOOTP_MASK at your own risk! |
*/ |
static int BootpExtended (u8 *e) |
static int BootpExtended(u8 * e) |
{ |
u8 *start = e ; |
u8 *start = e; |
|
*e++ = 99; /* RFC1048 Magic Cookie */ |
*e++ = 130; |
*e++ = 83; |
*e++ = 99; |
*e++ = 99; /* RFC1048 Magic Cookie */ |
*e++ = 130; |
*e++ = 83; |
*e++ = 99; |
|
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
*e++ = 53; /* DHCP Message Type */ |
*e++ = 1; |
*e++ = DHCP_DISCOVER; |
*e++ = 53; /* DHCP Message Type */ |
*e++ = 1; |
*e++ = DHCP_DISCOVER; |
|
*e++ = 57; /* Maximum DHCP Message Size */ |
*e++ = 2; |
*e++ = (576-312+OPT_SIZE) >> 16; |
*e++ = (576-312+OPT_SIZE) & 0xff; |
#endif /* CFG_CMD_DHCP */ |
*e++ = 57; /* Maximum DHCP Message Size */ |
*e++ = 2; |
*e++ = (576 - 312 + OPT_SIZE) >> 16; |
*e++ = (576 - 312 + OPT_SIZE) & 0xff; |
#endif /* CFG_CMD_DHCP */ |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_SUBNETMASK) |
*e++ = 1; /* Subnet mask request */ |
*e++ = 4; |
e += 4; |
*e++ = 1; /* Subnet mask request */ |
*e++ = 4; |
e += 4; |
#endif |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_GATEWAY) |
*e++ = 3; /* Default gateway request */ |
*e++ = 4; |
e += 4; |
*e++ = 3; /* Default gateway request */ |
*e++ = 4; |
e += 4; |
#endif |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_DNS) |
*e++ = 6; /* Domain Name Server */ |
*e++ = 4; |
e += 4; |
*e++ = 6; /* Domain Name Server */ |
*e++ = 4; |
e += 4; |
#endif |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_HOSTNAME) |
*e++ = 12; /* Host name request */ |
*e++ = 32; |
e += 32; |
*e++ = 12; /* Host name request */ |
*e++ = 32; |
e += 32; |
#endif |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTFILESIZE) |
*e++ = 13; /* Boot file size */ |
*e++ = 2; |
e += 2; |
*e++ = 13; /* Boot file size */ |
*e++ = 2; |
e += 2; |
#endif |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_BOOTPATH) |
*e++ = 17; /* Boot path */ |
*e++ = 32; |
e += 32; |
*e++ = 17; /* Boot path */ |
*e++ = 32; |
e += 32; |
#endif |
|
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_NISDOMAIN) |
*e++ = 40; /* NIS Domain name request */ |
*e++ = 32; |
e += 32; |
*e++ = 40; /* NIS Domain name request */ |
*e++ = 32; |
e += 32; |
#endif |
|
*e++ = 255; /* End of the list */ |
*e++ = 255; /* End of the list */ |
|
return e - start ; |
return e - start; |
} |
#endif /* CFG_CMD_DHCP */ |
#endif /* CFG_CMD_DHCP */ |
|
void |
BootpRequest (void) |
void BootpRequest(void) |
{ |
volatile uchar *pkt, *iphdr; |
Bootp_t *bp; |
512,50 → 529,48
dhcp_state = INIT; |
#endif |
|
#ifdef CONFIG_BOOTP_RANDOM_DELAY /* Random BOOTP delay */ |
#ifdef CONFIG_BOOTP_RANDOM_DELAY /* Random BOOTP delay */ |
unsigned char bi_enetaddr[6]; |
int reg; |
char *e,*s; |
int reg; |
char *e, *s; |
uchar tmp[64]; |
ulong tst1, tst2, sum, m_mask, m_value = 0; |
|
if (BootpTry ==0) { |
if (BootpTry == 0) { |
/* get our mac */ |
reg = getenv_r ("ethaddr", tmp, sizeof(tmp)); |
reg = getenv_r("ethaddr", tmp, sizeof(tmp)); |
s = (reg > 0) ? tmp : NULL; |
|
for (reg=0; reg<6; ++reg) { |
for (reg = 0; reg < 6; ++reg) { |
bi_enetaddr[reg] = s ? simple_strtoul(s, &e, 16) : 0; |
if (s) { |
s = (*e) ? e+1 : e; |
s = (*e) ? e + 1 : e; |
} |
} |
#ifdef DEBUG |
printf("BootpRequest => Our Mac: "); |
for (reg=0; reg<6; reg++) { |
printf ("%x%c", |
bi_enetaddr[reg], |
reg==5 ? '\n' : ':'); |
for (reg = 0; reg < 6; reg++) { |
printf("%x%c", bi_enetaddr[reg], reg == 5 ? '\n' : ':'); |
} |
#endif /* DEBUG */ |
|
/* Mac-Manipulation 2 get seed1 */ |
tst1=0; |
tst2=0; |
for (reg=2; reg<6; reg++) { |
tst1 = 0; |
tst2 = 0; |
for (reg = 2; reg < 6; reg++) { |
tst1 = tst1 << 8; |
tst1 = tst1 | bi_enetaddr[reg]; |
} |
for (reg=0; reg<2; reg++) { |
for (reg = 0; reg < 2; reg++) { |
tst2 = tst2 | bi_enetaddr[reg]; |
tst2 = tst2 << 8; |
} |
|
seed1 = tst1^tst2; |
seed1 = tst1 ^ tst2; |
|
/* Mirror seed1*/ |
m_mask=0x1; |
for (reg=1;reg<=32;reg++) { |
/* Mirror seed1 */ |
m_mask = 0x1; |
for (reg = 1; reg <= 32; reg++) { |
m_value |= (m_mask & seed1); |
seed1 = seed1 >> 1; |
m_value = m_value << 1; |
566,29 → 581,29
|
/* Random Number Generator */ |
|
for (reg=0;reg<=0;reg++) { |
for (reg = 0; reg <= 0; reg++) { |
sum = seed1 + seed2; |
if (sum < seed1 || sum < seed2) |
sum++; |
seed2 = seed1; |
seed2 = seed1; |
seed1 = sum; |
|
if (BootpTry<=2) { /* Start with max 1024 * 1ms */ |
sum = sum >> (22-BootpTry); |
} else { /*After 3rd BOOTP request max 8192 * 1ms */ |
if (BootpTry <= 2) { /* Start with max 1024 * 1ms */ |
sum = sum >> (22 - BootpTry); |
} else { /*After 3rd BOOTP request max 8192 * 1ms */ |
sum = sum >> 19; |
} |
} |
|
printf ("Random delay: %ld ms...\n", sum); |
for (reg=0; reg <sum; reg++) { |
udelay(1000); /*Wait 1ms*/ |
printf("Random delay: %ld ms...\n", sum); |
for (reg = 0; reg < sum; reg++) { |
udelay(1000); /*Wait 1ms */ |
} |
#endif /* CONFIG_BOOTP_RANDOM_DELAY */ |
#endif /* CONFIG_BOOTP_RANDOM_DELAY */ |
|
printf("BOOTP broadcast %d\n", ++BootpTry); |
pkt = NetTxPacket; |
memset ((void*)pkt, 0, PKTSIZE); |
memset((void *)pkt, 0, PKTSIZE); |
|
NetSetEther(pkt, NetBcastAddr, PROT_IP); |
pkt += ETHER_HDR_SIZE; |
600,21 → 615,21
* C. Hallinan, DS4.COM, Inc. |
*/ |
/* NetSetIP(pkt, 0xffffffffL, PORT_BOOTPS, PORT_BOOTPC, sizeof (Bootp_t)); */ |
iphdr = pkt; /* We need this later for NetSetIP() */ |
iphdr = pkt; /* We need this later for NetSetIP() */ |
pkt += IP_HDR_SIZE; |
|
bp = (Bootp_t *)pkt; |
bp = (Bootp_t *) pkt; |
bp->bp_op = OP_BOOTREQUEST; |
bp->bp_htype = HWT_ETHER; |
bp->bp_hlen = HWL_ETHER; |
bp->bp_hops = 0; |
bp->bp_secs = SWAP16( get_timer(0) / CFG_HZ); |
bp->bp_secs = SWAP16(get_timer(0) / CFG_HZ); |
bp->bp_ciaddr = 0; |
bp->bp_yiaddr = 0; |
bp->bp_siaddr = 0; |
bp->bp_giaddr = 0; |
NetCopyEther(bp->bp_chaddr, NetOurEther); |
copy_filename (bp->bp_file, BootFile, sizeof(bp->bp_file)); |
copy_filename(bp->bp_file, BootFile, sizeof(bp->bp_file)); |
|
/* Request additional information from the BOOTP/DHCP server */ |
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
621,16 → 636,16
ext_len = DhcpExtended(bp->bp_vend, DHCP_DISCOVER, 0, 0); |
#else |
ext_len = BootpExtended(bp->bp_vend); |
#endif /* CFG_CMD_DHCP */ |
#endif /* CFG_CMD_DHCP */ |
|
/* |
* Bootp ID is the lower 4 bytes of our ethernet address |
* plus the current time in HZ. |
* Bootp ID is the lower 4 bytes of our ethernet address |
* plus the current time in HZ. |
*/ |
BootpID = ((ulong)NetOurEther[2] << 24) |
| ((ulong)NetOurEther[3] << 16) |
| ((ulong)NetOurEther[4] << 8) |
| (ulong)NetOurEther[5]; |
BootpID = ((ulong) NetOurEther[2] << 24) |
| ((ulong) NetOurEther[3] << 16) |
| ((ulong) NetOurEther[4] << 8) |
| (ulong) NetOurEther[5]; |
BootpID += get_timer(0); |
bp->bp_id = BootpID; |
|
648,7 → 663,7
NetSetHandler(DhcpHandler); |
#else |
NetSetHandler(BootpHandler); |
#endif /* CFG_CMD_DHCP */ |
#endif /* CFG_CMD_DHCP */ |
NetSendPacket(NetTxPacket, pktlen); |
} |
|
658,54 → 673,52
char *end = popt + BOOTP_HDR_SIZE; |
int oplen, size; |
|
while ( popt < end && *popt != 0xff ) { |
while (popt < end && *popt != 0xff) { |
oplen = *(popt + 1); |
switch(*popt) { |
case 1: |
NetOurSubnetMask = *(IPaddr_t *)(popt + 2); |
switch (*popt) { |
case 1: |
NetOurSubnetMask = *(IPaddr_t *) (popt + 2); |
break; |
case 3: |
NetOurGatewayIP = *(IPaddr_t *) (popt + 2); |
break; |
case 6: |
NetOurDNSIP = *(IPaddr_t *) (popt + 2); |
break; |
case 12: |
size = truncate_sz("Host Name", |
sizeof(NetOurHostName), oplen); |
memcpy(&NetOurHostName, popt + 2, size); |
NetOurHostName[size] = 0; |
break; |
case 15: /* Ignore Domain Name Option */ |
break; |
case 17: |
size = truncate_sz("Root Path", |
sizeof(NetOurRootPath), oplen); |
memcpy(&NetOurRootPath, popt + 2, size); |
NetOurRootPath[size] = 0; |
break; |
case 51: |
dhcp_leasetime = *(unsigned int *)(popt + 2); |
break; |
case 53: /* Ignore Message Type Option */ |
break; |
case 54: |
NetServerIP = *(IPaddr_t *) (popt + 2); |
break; |
case 58: /* Ignore Renewal Time Option */ |
break; |
case 59: /* Ignore Rebinding Time Option */ |
break; |
default: |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX) |
if (dhcp_vendorex_proc(popt)) |
break; |
case 3: |
NetOurGatewayIP = *(IPaddr_t *)(popt + 2); |
break; |
case 6: |
NetOurDNSIP = *(IPaddr_t *)(popt +2); |
break; |
case 12: |
size = truncate_sz ("Host Name", |
sizeof(NetOurHostName), |
oplen); |
memcpy(&NetOurHostName, popt+2, size); |
NetOurHostName[size] = 0 ; |
break; |
case 15: /* Ignore Domain Name Option */ |
break; |
case 17: |
size = truncate_sz ("Root Path", |
sizeof(NetOurRootPath), |
oplen); |
memcpy(&NetOurRootPath, popt+2, size); |
NetOurRootPath[size] = 0 ; |
break; |
case 51: |
dhcp_leasetime = *(unsigned int *)(popt + 2); |
break; |
case 53: /* Ignore Message Type Option */ |
break; |
case 54: |
NetServerIP = *(IPaddr_t *)(popt+2); |
break; |
case 58: /* Ignore Renewal Time Option */ |
break; |
case 59: /* Ignore Rebinding Time Option */ |
break; |
default: |
#if (CONFIG_BOOTP_MASK & CONFIG_BOOTP_VENDOREX) |
if (dhcp_vendorex_proc(popt)) |
break; |
#endif |
printf("*** Unhandled DHCP Option in OFFER/ACK: %d\n", |
*popt); |
break; |
printf("*** Unhandled DHCP Option in OFFER/ACK: %d\n", |
*popt); |
break; |
} |
popt += oplen + 2; /* Process next option */ |
} |
713,12 → 726,12
|
static int DhcpMessageType(unsigned char *popt) |
{ |
if ((*(uint *)popt) != BOOTP_VENDOR_MAGIC) |
if ((*(uint *) popt) != BOOTP_VENDOR_MAGIC) |
return -1; |
|
popt += 4; |
while ( *popt != 0xff ) { |
if ( *popt == 53 ) /* DHCP Message Type */ |
while (*popt != 0xff) { |
if (*popt == 53) /* DHCP Message Type */ |
return *(popt + 2); |
popt += *(popt + 1) + 2; /* Scan through all options */ |
} |
725,15 → 738,15
return -1; |
} |
|
void DhcpSendRequestPkt(Bootp_t *bp_offer) |
void DhcpSendRequestPkt(Bootp_t * bp_offer) |
{ |
volatile uchar *pkt, *iphdr; |
Bootp_t *bp; |
int pktlen, iplen, extlen; |
|
debug ("DhcpSendRequestPkt: Sending DHCPREQUEST\n"); |
debug("DhcpSendRequestPkt: Sending DHCPREQUEST\n"); |
pkt = NetTxPacket; |
memset ((void*)pkt, 0, PKTSIZE); |
memset((void *)pkt, 0, PKTSIZE); |
|
NetSetEther(pkt, NetBcastAddr, PROT_IP); |
pkt += ETHER_HDR_SIZE; |
741,16 → 754,16
iphdr = pkt; /* We'll need this later to set proper pkt size */ |
pkt += IP_HDR_SIZE; |
|
bp = (Bootp_t *)pkt; |
bp = (Bootp_t *) pkt; |
bp->bp_op = OP_BOOTREQUEST; |
bp->bp_htype = HWT_ETHER; |
bp->bp_hlen = HWL_ETHER; |
bp->bp_hops = 0; |
bp->bp_secs = SWAP16( get_timer(0) / CFG_HZ); |
bp->bp_ciaddr = bp_offer->bp_ciaddr; |
bp->bp_yiaddr = bp_offer->bp_yiaddr; |
bp->bp_siaddr = bp_offer->bp_siaddr; |
bp->bp_giaddr = bp_offer->bp_giaddr; |
bp->bp_secs = SWAP16(get_timer(0) / CFG_HZ); |
bp->bp_ciaddr = bp_offer->bp_ciaddr; |
bp->bp_yiaddr = bp_offer->bp_yiaddr; |
bp->bp_siaddr = bp_offer->bp_siaddr; |
bp->bp_giaddr = bp_offer->bp_giaddr; |
NetCopyEther(bp->bp_chaddr, NetOurEther); |
|
/* |
762,13 → 775,14
/* |
* Copy options from OFFER packet if present |
*/ |
extlen = DhcpExtended(bp->bp_vend, DHCP_REQUEST, NetServerIP, bp->bp_yiaddr); |
extlen = |
DhcpExtended(bp->bp_vend, DHCP_REQUEST, NetServerIP, bp->bp_yiaddr); |
|
pktlen = BOOTP_SIZE - sizeof(bp->bp_vend) + extlen; |
iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + extlen; |
NetSetIP(iphdr, 0xffffffffL, PORT_BOOTPS, PORT_BOOTPC, iplen); |
|
debug ("Transmitting DHCPREQUEST packet: len = %d\n", pktlen); |
debug("Transmitting DHCPREQUEST packet: len = %d\n", pktlen); |
NetSendPacket(NetTxPacket, pktlen); |
} |
|
775,19 → 789,19
/* |
* Handle DHCP received packets. |
*/ |
static void |
DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) |
static void DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len) |
{ |
Bootp_t *bp = (Bootp_t *)pkt; |
Bootp_t *bp = (Bootp_t *) pkt; |
|
debug ("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n", |
src, dest, len, dhcp_state); |
debug("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n", |
src, dest, len, dhcp_state); |
|
if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */ |
return; |
|
debug ("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: %d\n", |
src, dest, len, dhcp_state); |
debug |
("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: %d\n", |
src, dest, len, dhcp_state); |
|
switch (dhcp_state) { |
case SELECTING: |
797,17 → 811,17
* If filename is in format we recognize, assume it is a valid |
* OFFER from a server we want. |
*/ |
debug ("DHCP: state=SELECTING bp_file: \"%s\"\n", bp->bp_file); |
debug("DHCP: state=SELECTING bp_file: \"%s\"\n", bp->bp_file); |
#ifdef CFG_BOOTFILE_PREFIX |
if (strncmp(bp->bp_file, |
CFG_BOOTFILE_PREFIX, |
strlen(CFG_BOOTFILE_PREFIX)) == 0 ) { |
#endif /* CFG_BOOTFILE_PREFIX */ |
strlen(CFG_BOOTFILE_PREFIX)) == 0) { |
#endif /* CFG_BOOTFILE_PREFIX */ |
|
debug ("TRANSITIONING TO REQUESTING STATE\n"); |
debug("TRANSITIONING TO REQUESTING STATE\n"); |
dhcp_state = REQUESTING; |
#if 0 |
if ((*(uint *)bp->bp_vend) == BOOTP_VENDOR_MAGIC) |
if ((*(uint *) bp->bp_vend) == BOOTP_VENDOR_MAGIC) |
DhcpOptionsProcess(&bp->bp_vend[4]); |
|
#endif |
817,17 → 831,17
DhcpSendRequestPkt(bp); |
#ifdef CFG_BOOTFILE_PREFIX |
} |
#endif /* CFG_BOOTFILE_PREFIX */ |
#endif /* CFG_BOOTFILE_PREFIX */ |
|
return; |
break; |
case REQUESTING: |
debug ("DHCP State: REQUESTING\n"); |
debug("DHCP State: REQUESTING\n"); |
|
if ( DhcpMessageType(bp->bp_vend) == DHCP_ACK ) { |
if (DhcpMessageType(bp->bp_vend) == DHCP_ACK) { |
char *s; |
|
if ((*(uint *)bp->bp_vend) == BOOTP_VENDOR_MAGIC) |
if ((*(uint *) bp->bp_vend) == BOOTP_VENDOR_MAGIC) |
DhcpOptionsProcess(&bp->bp_vend[4]); |
BootpCopyNetParams(bp); /* Store net params from reply */ |
dhcp_state = BOUND; |
858,6 → 872,6
{ |
BootpRequest(); |
} |
#endif /* CFG_CMD_DHCP */ |
#endif /* CFG_CMD_DHCP */ |
|
#endif /* CFG_CMD_NET */ |
/rarp.c
29,12 → 29,11
|
#if (CONFIG_COMMANDS & CFG_CMD_NET) |
|
#define TIMEOUT 5 /* Seconds before trying BOOTP again */ |
#define TIMEOUT_COUNT 1 /* # of timeouts before giving up */ |
#define TIMEOUT 5 /* Seconds before trying BOOTP again */ |
#define TIMEOUT_COUNT 1 /* # of timeouts before giving up */ |
|
int RarpTry; |
|
int RarpTry; |
|
/* |
* Handle a RARP received packet. |
*/ |
44,32 → 43,28
#ifdef DEBUG |
printf("Got good RARP\n"); |
#endif |
TftpStart (); |
TftpStart(); |
} |
|
|
/* |
* Timeout on BOOTP request. |
*/ |
static void |
RarpTimeout(void) |
static void RarpTimeout(void) |
{ |
if (RarpTry >= TIMEOUT_COUNT) { |
puts ("\nRetry count exceeded; starting again\n"); |
NetStartAgain (); |
puts("\nRetry count exceeded; starting again\n"); |
NetStartAgain(); |
} else { |
NetSetTimeout (TIMEOUT * CFG_HZ, RarpTimeout); |
RarpRequest (); |
NetSetTimeout(TIMEOUT * CFG_HZ, RarpTimeout); |
RarpRequest(); |
} |
} |
|
|
void |
RarpRequest (void) |
void RarpRequest(void) |
{ |
int i; |
volatile uchar *pkt; |
ARP_t * rarp; |
ARP_t *rarp; |
|
printf("RARP broadcast %d\n", ++RarpTry); |
pkt = NetTxPacket; |
77,16 → 72,16
NetSetEther(pkt, NetBcastAddr, PROT_RARP); |
pkt += ETHER_HDR_SIZE; |
|
rarp = (ARP_t *)pkt; |
rarp = (ARP_t *) pkt; |
|
rarp->ar_hrd = ARP_ETHER; |
rarp->ar_pro = PROT_IP; |
rarp->ar_hln = 6; |
rarp->ar_pln = 4; |
rarp->ar_op = RARPOP_REQUEST; |
rarp->ar_op = RARPOP_REQUEST; |
NetCopyEther(&rarp->ar_data[0], NetOurEther); /* source ET addr */ |
*(IPaddr_t *)(&rarp->ar_data[6]) = NetOurIP; /* source IP addr */ |
NetCopyEther(&rarp->ar_data[10], NetOurEther); /* dest ET addr = source ET addr ??*/ |
*(IPaddr_t *) (&rarp->ar_data[6]) = NetOurIP; /* source IP addr */ |
NetCopyEther(&rarp->ar_data[10], NetOurEther); /* dest ET addr = source ET addr ?? */ |
/* dest. IP addr set to broadcast */ |
for (i = 0; i <= 3; i++) { |
rarp->ar_data[16 + i] = 0xff; |
/dos.c
19,7 → 19,6
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
*/ |
|
|
//#include "common.h" |
|
#include <stddef.h> |
27,70 → 26,67
#include "dos.h" |
#include "ata.h" |
|
|
/* |
D O S _ O P E N |
*/ |
int dos_open(struct dosparam *params) |
{ |
int error, start_sector, partition; |
unsigned char buf[512]; |
int error, start_sector, partition; |
unsigned char buf[512]; |
|
struct inode *inode = ¶ms->inode; |
struct file *filp = ¶ms->filp; |
struct request *request = ¶ms->request; |
struct inode *inode = ¶ms->inode; |
struct file *filp = ¶ms->filp; |
struct request *request = ¶ms->request; |
|
if( (error = ata_open(inode, filp)) ) |
return error; |
if ((error = ata_open(inode, filp))) |
return error; |
|
/* device opened, read MBR */ |
request->cmd = READ; |
request->sector = 0; |
request->nr_sectors = 1; |
request->buffer = buf; |
|
/* device opened, read MBR */ |
request->cmd = READ; |
request->sector = 0; |
request->nr_sectors = 1; |
request->buffer = buf; |
/* skip bootload (446) bytes */ |
/* currently only support the first partition (partition 4) */ |
/* This is OK, because CompactFLASH devices only have 1 partition */ |
if ((error = ata_request(inode, filp, request))) |
return error; |
|
/* skip bootload (446) bytes */ |
/* currently only support the first partition (partition 4) */ |
/* This is OK, because CompactFLASH devices only have 1 partition */ |
if ( (error = ata_request(inode, filp, request)) ) |
return error; |
partition = 0; /* first partition */ |
partition *= 16; /* 16 bytes per partition table */ |
partition += 446; /* skip bootloader, go to partition table */ |
start_sector = buf[partition + 11] << 24 | |
buf[partition + 10] << 16 | |
buf[partition + 9] << 8 | buf[partition + 8]; |
|
partition = 0; /* first partition */ |
partition *= 16; /* 16 bytes per partition table */ |
partition += 446; /* skip bootloader, go to partition table */ |
start_sector = buf[partition +11] << 24 | |
buf[partition +10] << 16 | |
buf[partition +9] << 8 | |
buf[partition +8]; |
/* device opened, read boot-sector */ |
request->cmd = READ; |
request->sector = start_sector; |
request->nr_sectors = 1; |
request->buffer = buf; |
|
/* device opened, read boot-sector */ |
request->cmd = READ; |
request->sector = start_sector; |
request->nr_sectors = 1; |
request->buffer = buf; |
if ((error = ata_request(inode, filp, request))) |
return error; |
|
if ( (error = ata_request(inode, filp, request)) ) |
return error; |
/* get the necessary data from the boot-sector */ |
params->bytes_per_sector = (buf[12] << 8) | buf[11]; |
params->fats = buf[16]; |
params->sectors_per_fat = (buf[23] << 8) | buf[22]; |
params->root_entries = (buf[18] << 8) | buf[17]; |
params->sectors_per_cluster = buf[13]; |
|
/* get the necessary data from the boot-sector */ |
params->bytes_per_sector = (buf[12]<<8) | buf[11]; |
params->fats = buf[16]; |
params->sectors_per_fat = (buf[23]<<8) | buf[22]; |
params->root_entries = (buf[18]<<8) | buf[17]; |
params->sectors_per_cluster = buf[13]; |
/* set start of current directory to start of root-directory */ |
params->ssector = |
start_sector + params->fats * params->sectors_per_fat + 1; |
|
/* set current sector to start of root-directory */ |
params->csector = params->ssector; |
|
/* set start of current directory to start of root-directory */ |
params->ssector = start_sector + params->fats * params->sectors_per_fat +1; |
/* set start-entry number */ |
params->sentry = 0; |
|
/* set current sector to start of root-directory */ |
params->csector = params->ssector; |
|
/* set start-entry number */ |
params->sentry = 0; |
|
return 0; |
return 0; |
} |
|
/* |
98,7 → 94,7
*/ |
int dos_release(struct dosparam *params) |
{ |
return 0; |
return 0; |
} |
|
/* |
106,126 → 102,124
*/ |
int dos_namecmp(const char *sname, const char *name, const char *ext) |
{ |
char fname[9], fext[4], *p; |
char fname[9], fext[4], *p; |
|
/* filename : */ |
/* copy the filename */ |
strncpy(fname, sname, 8); |
/* filename : */ |
/* copy the filename */ |
strncpy(fname, sname, 8); |
|
/* check if we copied the '.' already, if so terminate string */ |
if ( (p = strchr(fname, '.')) ) |
*p = '\0'; |
/* check if we copied the '.' already, if so terminate string */ |
if ((p = strchr(fname, '.'))) |
*p = '\0'; |
|
/* fill remaining chars with ' ' */ |
strncat(fname, " ", 8-strlen(fname) ); |
/* fill remaining chars with ' ' */ |
strncat(fname, " ", 8 - strlen(fname)); |
|
fname[9] = '\0'; |
fname[9] = '\0'; |
|
/* file-extension */ |
/* search for the '.' in the filename */ |
if ( (p = strchr(sname, '.')) ) |
strncpy(fext, p, 3); |
else |
fext[0] = fext[1] = fext[2] = ' '; |
/* file-extension */ |
/* search for the '.' in the filename */ |
if ((p = strchr(sname, '.'))) |
strncpy(fext, p, 3); |
else |
fext[0] = fext[1] = fext[2] = ' '; |
|
fext[4] = '\0'; |
fext[4] = '\0'; |
|
return ( strcmp(fname, name) && strcmp(fext, ext) ); |
return (strcmp(fname, name) && strcmp(fext, ext)); |
} |
|
|
/* |
D O S _ D I R _ F I N D _ E N T R Y |
*/ |
struct dos_dir_entry *dos_dir_find_entry(struct dosparam *params, const char *name) |
struct dos_dir_entry *dos_dir_find_entry(struct dosparam *params, |
const char *name) |
{ |
struct dos_dir_entry *entry; |
unsigned long entry_no = 0; |
struct dos_dir_entry *entry; |
unsigned long entry_no = 0; |
|
/* go to start of current directory */ |
if (params->csector != params->ssector) |
dos_dir_cluster_reset(params); |
/* go to start of current directory */ |
if (params->csector != params->ssector) |
dos_dir_cluster_reset(params); |
|
/* search for the requested entry */ |
while ( (entry = dos_dir_get_entry(params, entry_no)) && dos_namecmp(name, entry->name, entry->ext) ) |
entry_no++; |
/* search for the requested entry */ |
while ((entry = dos_dir_get_entry(params, entry_no)) |
&& dos_namecmp(name, entry->name, entry->ext)) |
entry_no++; |
|
return entry; |
return entry; |
} |
|
|
/* |
D O S _ D I R _ G E T _ E N T R Y |
*/ |
struct dos_dir_entry *dos_dir_get_entry(struct dosparam *params, unsigned long entry) |
struct dos_dir_entry *dos_dir_get_entry(struct dosparam *params, |
unsigned long entry) |
{ |
char *buf = params->cbuf; |
char *buf = params->cbuf; |
|
if (entry < params->sentry) |
buf = dos_dir_cluster_reset(params); |
if (entry < params->sentry) |
buf = dos_dir_cluster_reset(params); |
|
while ( entry >= (params->sentry + entries_per_cluster(params)) ) |
if ( !(buf = dos_dir_cluster_read_nxt(params)) ) |
return NULL; |
while (entry >= (params->sentry + entries_per_cluster(params))) |
if (!(buf = dos_dir_cluster_read_nxt(params))) |
return NULL; |
|
return (struct dos_dir_entry*)(buf + ( (entry - params->sentry) * sizeof(struct dos_dir_entry)) ); |
return (struct dos_dir_entry *)(buf + |
((entry - |
params->sentry) * |
sizeof(struct dos_dir_entry))); |
} |
|
|
/* |
D O S _ R E A D _ C L U S T E R |
*/ |
char *dos_read_cluster(struct dosparam *params, unsigned long ssector) |
{ |
int error; |
int error; |
|
struct inode *inode = ¶ms->inode; |
struct file *filp = ¶ms->filp; |
struct request *request = ¶ms->request; |
struct inode *inode = ¶ms->inode; |
struct file *filp = ¶ms->filp; |
struct request *request = ¶ms->request; |
|
request->cmd = READ; |
request->sector = ssector; |
request->nr_sectors = params->sectors_per_cluster; |
request->buffer = params->cbuf; |
request->cmd = READ; |
request->sector = ssector; |
request->nr_sectors = params->sectors_per_cluster; |
request->buffer = params->cbuf; |
|
if ( (error = ata_request(inode, filp, request)) ) |
return NULL; |
if ((error = ata_request(inode, filp, request))) |
return NULL; |
|
params->csector = ssector; |
params->csector = ssector; |
|
return params->cbuf; |
return params->cbuf; |
} |
|
|
/* |
D O S _ D I R _ C L U S T E R _ R E A D _ N X T |
*/ |
char *dos_dir_cluster_read_nxt(struct dosparam *params) |
{ |
char *p; |
unsigned long nxt_cluster_start; |
char *p; |
unsigned long nxt_cluster_start; |
|
/* TODO: add FAT lookup */ |
/* TODO: add FAT lookup */ |
|
nxt_cluster_start = params->csector + params->sectors_per_cluster; |
nxt_cluster_start = params->csector + params->sectors_per_cluster; |
|
if ( !(p = dos_read_cluster(params, nxt_cluster_start)) ) |
return NULL; |
if (!(p = dos_read_cluster(params, nxt_cluster_start))) |
return NULL; |
|
params->sentry += entries_per_cluster(params); |
|
params->sentry += entries_per_cluster(params); |
|
return p; |
return p; |
} |
|
|
/* |
D O S _ D I R _ C L U S T E R _ R E S E T |
*/ |
char *dos_dir_cluster_reset(struct dosparam *params) |
{ |
params->sentry = 0; |
return dos_read_cluster(params, params->ssector); |
params->sentry = 0; |
return dos_read_cluster(params, params->ssector); |
} |
|
|
/net.c
57,7 → 57,6
* Next step: none |
*/ |
|
|
#include "common.h" |
#include "support.h" |
#include "net.h" |
67,7 → 66,7
#include "arp.h" |
#if OC_LAN==1 |
#include "eth.h" |
#else |
#else |
# if SMC91111_LAN==1 |
# include "smc91111.h" |
# endif |
79,202 → 78,203
|
/** BOOTP EXTENTIONS **/ |
|
IPaddr_t NetOurSubnetMask=0; /* Our subnet mask (0=unknown) */ |
IPaddr_t NetOurGatewayIP=0; /* Our gateways IP address */ |
IPaddr_t NetOurDNSIP=0; /* Our DNS IP address */ |
char NetOurNISDomain[32]={0,}; /* Our NIS domain */ |
char NetOurHostName[32]={0,}; /* Our hostname */ |
char NetOurRootPath[64]={0,}; /* Our bootpath */ |
unsigned short NetBootFileSize=0; /* Our bootfile size in blocks */ |
IPaddr_t NetOurSubnetMask = 0; /* Our subnet mask (0=unknown) */ |
IPaddr_t NetOurGatewayIP = 0; /* Our gateways IP address */ |
IPaddr_t NetOurDNSIP = 0; /* Our DNS IP address */ |
char NetOurNISDomain[32] = { 0, }; /* Our NIS domain */ |
char NetOurHostName[32] = { 0, }; /* Our hostname */ |
char NetOurRootPath[64] = { 0, }; /* Our bootpath */ |
|
unsigned short NetBootFileSize = 0; /* Our bootfile size in blocks */ |
|
/** END OF BOOTP EXTENTIONS **/ |
|
unsigned long NetBootFileXferSize; /* The actual transferred size of the bootfile (in bytes) */ |
unsigned char NetOurEther[6]; /* Our ethernet address */ |
unsigned char NetServerEther[6] = /* Boot server enet address */ |
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ |
IPaddr_t NetServerIP; /* Our IP addr (0 = unknown) */ |
volatile unsigned char *NetRxPkt; /* Current receive packet */ |
int NetRxPktLen; /* Current rx packet length */ |
unsigned NetIPID; /* IP packet ID */ |
unsigned char NetBcastAddr[6] = /* Ethernet bcast address */ |
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
int NetState; /* Network loop state */ |
unsigned long NetBootFileXferSize; /* The actual transferred size |
of the bootfile (in bytes) */ |
unsigned char NetOurEther[6]; /* Our ethernet address */ |
unsigned char NetServerEther[6] = /* Boot server enet address */ |
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
|
char BootFile[128]; /* Boot File name */ |
IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */ |
IPaddr_t NetServerIP; /* Our IP addr (0 = unknown) */ |
volatile unsigned char *NetRxPkt; /* Current receive packet */ |
int NetRxPktLen; /* Current rx packet length */ |
unsigned NetIPID; /* IP packet ID */ |
unsigned char NetBcastAddr[6] = /* Ethernet bcast address */ |
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
|
volatile unsigned char PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN]; |
int NetState; /* Network loop state */ |
|
volatile unsigned char *NetRxPackets[PKTBUFSRX]; /* Receive packets */ |
char BootFile[128]; /* Boot File name */ |
|
static rxhand_f *packetHandler; /* Current RX packet handler */ |
static thand_f *timeHandler; /* Current timeout handler */ |
static unsigned long timeValue; /* Current timeout value */ |
volatile unsigned char *NetTxPacket = 0; /* THE transmit packet */ |
volatile unsigned char PktBuf[(PKTBUFSRX + 1) * PKTSIZE_ALIGN + PKTALIGN]; |
|
static int net_check_prereq (proto_t protocol); |
volatile unsigned char *NetRxPackets[PKTBUFSRX]; /* Receive packets*/ |
|
static rxhand_f *packetHandler; /* Current RX packet handler */ |
static thand_f *timeHandler; /* Current timeout handler */ |
static unsigned long timeValue; /* Current timeout value */ |
volatile unsigned char *NetTxPacket = 0; /* THE transmit packet */ |
|
static int net_check_prereq(proto_t protocol); |
|
/**********************************************************************/ |
/* |
* Main network processing loop. |
*/ |
int |
NetLoop(proto_t protocol) |
int NetLoop(proto_t protocol) |
{ |
|
if (!NetTxPacket) { |
int i; |
printf("NetTxPacket begin setup\n"); |
/* |
* Setup packet buffers, aligned correctly. |
*/ |
NetTxPacket = &PktBuf[0] + (PKTALIGN - 1); |
NetTxPacket -= (unsigned long)NetTxPacket % PKTALIGN; |
for (i = 0; i < PKTBUFSRX; i++) { |
NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN; |
} |
} |
if (!NetTxPacket) { |
int i; |
printf("NetTxPacket begin setup\n"); |
/* |
* Setup packet buffers, aligned correctly. |
*/ |
NetTxPacket = &PktBuf[0] + (PKTALIGN - 1); |
NetTxPacket -= (unsigned long)NetTxPacket % PKTALIGN; |
for (i = 0; i < PKTBUFSRX; i++) { |
NetRxPackets[i] = NetTxPacket + (i + 1) * PKTSIZE_ALIGN; |
} |
} |
|
eth_halt(); |
eth_init(NetReceive); |
eth_halt(); |
eth_init(NetReceive); |
|
restart: |
restart: |
|
NetCopyEther(NetOurEther, global.eth_add); |
NetCopyEther(NetOurEther, global.eth_add); |
|
NetState = NETLOOP_CONTINUE; |
NetState = NETLOOP_CONTINUE; |
|
/* |
* Start the ball rolling with the given start function. From |
* here on, this code is a state machine driven by received |
* packets and timer events. |
*/ |
/* |
* Start the ball rolling with the given start function. From |
* here on, this code is a state machine driven by received |
* packets and timer events. |
*/ |
|
if (protocol == TFTP) { /* TFTP */ |
NetOurIP = global.ip; |
NetServerIP = global.srv_ip; |
NetOurGatewayIP = global.gw_ip; |
NetOurSubnetMask= global.mask; |
if (protocol == TFTP) { /* TFTP */ |
NetOurIP = global.ip; |
NetServerIP = global.srv_ip; |
NetOurGatewayIP = global.gw_ip; |
NetOurSubnetMask = global.mask; |
|
if (net_check_prereq (protocol) != 0) { |
return 0; |
} |
if (net_check_prereq(protocol) != 0) { |
return 0; |
} |
|
/* always use ARP to get server ethernet address */ |
ArpTry = 0; |
/* always use ARP to get server ethernet address */ |
ArpTry = 0; |
|
ArpRequest (); |
ArpRequest(); |
|
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
} else if (protocol == DHCP) { |
if (net_check_prereq (protocol) != 0) { |
return 0; |
} |
} else if (protocol == DHCP) { |
if (net_check_prereq(protocol) != 0) { |
return 0; |
} |
|
/* Start with a clean slate... */ |
NetOurIP = 0; |
NetServerIP = 0; |
DhcpRequest(); /* Basically same as BOOTP */ |
/* Start with a clean slate... */ |
NetOurIP = 0; |
NetServerIP = 0; |
DhcpRequest(); /* Basically same as BOOTP */ |
|
#endif /* CFG_CMD_DHCP */ |
#endif /* CFG_CMD_DHCP */ |
|
} else { /* BOOTP or RARP */ |
} else { /* BOOTP or RARP */ |
|
/* |
* initialize our IP addr to 0 in order to accept ANY |
* IP addr assigned to us by the BOOTP / RARP server |
*/ |
NetOurIP = 0; |
NetServerIP = 0; |
/* |
* initialize our IP addr to 0 in order to accept ANY |
* IP addr assigned to us by the BOOTP / RARP server |
*/ |
NetOurIP = 0; |
NetServerIP = 0; |
|
if (net_check_prereq (protocol) != 0) { |
return 0; |
} |
if (net_check_prereq(protocol) != 0) { |
return 0; |
} |
#ifdef BOOTP |
if (protocol == BOOTP) { |
BootpTry = 0; |
BootpRequest (); |
} |
if (protocol == BOOTP) { |
BootpTry = 0; |
BootpRequest(); |
} |
#endif |
#ifdef RARP |
if { |
RarpTry = 0; |
RarpRequest (); |
} |
if { |
RarpTry |
= 0; |
RarpRequest(); |
} |
#endif |
} |
} |
|
NetBootFileXferSize = 0; |
NetBootFileXferSize = 0; |
|
/* |
* Main packet reception loop. Loop receiving packets until |
* someone sets `NetQuit'. |
*/ |
for (;;) { |
// WATCHDOG_RESET(); |
/* |
* Check the ethernet for a new packet. The ethernet |
* receive routine will process it. |
*/ |
eth_rx(); |
/* |
* Main packet reception loop. Loop receiving packets until |
* someone sets `NetQuit'. |
*/ |
for (;;) { |
// WATCHDOG_RESET(); |
/* |
* Check the ethernet for a new packet. The ethernet |
* receive routine will process it. |
*/ |
eth_rx(); |
|
/* |
* Abort if ctrl-c was pressed. |
*/ |
if (ctrlc()) { |
eth_halt(); |
printf("\nAbort\n"); |
return 0; |
} |
/* |
* Abort if ctrl-c was pressed. |
*/ |
if (ctrlc()) { |
eth_halt(); |
printf("\nAbort\n"); |
return 0; |
} |
|
/* |
* Check for a timeout, and run the timeout handler |
* if we have one. |
*/ |
/* |
if (timeHandler && (get_timer(0) > timeValue)) { |
thand_f *x; |
|
/* |
* Check for a timeout, and run the timeout handler |
* if we have one. |
*/ |
/* |
if (timeHandler && (get_timer(0) > timeValue)) { |
thand_f *x; |
x = timeHandler; |
timeHandler = (thand_f *)0; |
(*x)(); |
} |
*/ |
|
x = timeHandler; |
timeHandler = (thand_f *)0; |
(*x)(); |
} |
*/ |
|
switch (NetState) { |
switch (NetState) { |
|
case NETLOOP_RESTART: |
goto restart; |
case NETLOOP_RESTART: |
goto restart; |
|
case NETLOOP_SUCCESS: |
if (NetBootFileXferSize > 0) { |
printf("Bytes transferred = %ld (0x%lx)\n", |
NetBootFileXferSize, |
NetBootFileXferSize); |
case NETLOOP_SUCCESS: |
if (NetBootFileXferSize > 0) { |
printf("Bytes transferred = %ld (0x%lx)\n", |
NetBootFileXferSize, |
NetBootFileXferSize); |
#ifdef TFTP_CALC_CHKSUM |
printf("CHKSUM: 0x%lx\n", TFTP_CHKSUM); |
printf("CHKSUM: 0x%lx\n", TFTP_CHKSUM); |
#endif |
} |
eth_halt(); |
return NetBootFileXferSize; |
} |
eth_halt(); |
return NetBootFileXferSize; |
|
case NETLOOP_FAIL: |
return 0; |
} |
} |
case NETLOOP_FAIL: |
return 0; |
} |
} |
|
} |
|
/**********************************************************************/ |
|
|
#if 1 |
void |
NetStartAgain(void) |
void NetStartAgain(void) |
{ |
NetState = NETLOOP_RESTART; |
NetState = NETLOOP_RESTART; |
} |
|
/**********************************************************************/ |
282,446 → 282,448
* Miscelaneous bits. |
*/ |
|
void |
NetSetHandler(rxhand_f * f) |
void NetSetHandler(rxhand_f * f) |
{ |
packetHandler = f; |
packetHandler = f; |
} |
|
|
void |
NetSetTimeout(int iv, thand_f * f) |
void NetSetTimeout(int iv, thand_f * f) |
{ |
if (iv == 0) { |
timeHandler = (thand_f *)0; |
} else { |
timeHandler = f; |
timeValue = get_timer(0) + iv; |
} |
if (iv == 0) { |
timeHandler = (thand_f *) 0; |
} else { |
timeHandler = f; |
timeValue = get_timer(0) + iv; |
} |
} |
|
|
void |
NetSendPacket(volatile unsigned char * pkt, int len) |
void NetSendPacket(volatile unsigned char *pkt, int len) |
{ |
|
#if OC_LAN==1 |
unsigned char *p = (unsigned char *)0; |
while (p == (unsigned char*) 0) |
p = eth_get_tx_buf(); |
|
memcpy(p, (void *)pkt, len); |
eth_send(p, len); |
unsigned char *p = (unsigned char *)0; |
while (p == (unsigned char *)0) |
p = eth_get_tx_buf(); |
|
memcpy(p, (void *)pkt, len); |
eth_send(p, len); |
#else |
# if SMC91111_LAN==1 |
eth_send(pkt, len); |
eth_send(pkt, len); |
# endif |
#endif |
} |
|
|
|
void |
NetReceive(volatile unsigned char * pkt, int len) |
void NetReceive(volatile unsigned char *pkt, int len) |
{ |
Ethernet_t *et; |
IP_t *ip; |
ARP_t *arp; |
int x; |
IPaddr_t ip_to_check; // Used as a temp variable to check IP |
Ethernet_t *et; |
IP_t *ip; |
ARP_t *arp; |
int x; |
IPaddr_t ip_to_check; // Used as a temp variable to check IP |
|
NetRxPkt = pkt; |
NetRxPktLen = len; |
et = (Ethernet_t *)pkt; |
NetRxPkt = pkt; |
NetRxPktLen = len; |
et = (Ethernet_t *) pkt; |
|
x = SWAP16(et->et_protlen); |
x = SWAP16(et->et_protlen); |
|
if (x < 1514) { |
/* |
* Got a 802 packet. Check the other protocol field. |
*/ |
x = SWAP16(et->et_prot); |
ip = (IP_t *)(pkt + E802_HDR_SIZE); |
len -= E802_HDR_SIZE; |
} else { |
ip = (IP_t *)(pkt + ETHER_HDR_SIZE); |
len -= ETHER_HDR_SIZE; |
} |
if (x < 1514) { |
/* |
* Got a 802 packet. Check the other protocol field. |
*/ |
x = SWAP16(et->et_prot); |
ip = (IP_t *) (pkt + E802_HDR_SIZE); |
len -= E802_HDR_SIZE; |
} else { |
ip = (IP_t *) (pkt + ETHER_HDR_SIZE); |
len -= ETHER_HDR_SIZE; |
} |
|
#ifdef ET_DEBUG |
printf("Receive from protocol 0x%x\n", x); |
printf("Receive from protocol 0x%x\n", x); |
#endif |
|
switch (x) { |
switch (x) { |
|
case PROT_ARP: |
/* |
* We have to deal with two types of ARP packets: |
* - REQUEST packets will be answered by sending our |
* IP address - if we know it. |
* - REPLY packates are expected only after we asked |
* for the TFTP server's or the gateway's ethernet |
* address; so if we receive such a packet, we set |
* the server ethernet address |
*/ |
case PROT_ARP: |
/* |
* We have to deal with two types of ARP packets: |
* - REQUEST packets will be answered by sending our |
* IP address - if we know it. |
* - REPLY packates are expected only after we asked |
* for the TFTP server's or the gateway's ethernet |
* address; so if we receive such a packet, we set |
* the server ethernet address |
*/ |
#ifdef ET_DEBUG |
printf("Got ARP\n"); |
printf("Got ARP\n"); |
#endif |
arp = (ARP_t *)ip; |
if (len < ARP_HDR_SIZE) { |
printf("bad length %d < %d\n", len, ARP_HDR_SIZE); |
return; |
} |
if (SWAP16(arp->ar_hrd) != ARP_ETHER) { |
return; |
} |
if (SWAP16(arp->ar_pro) != PROT_IP) { |
return; |
} |
if (arp->ar_hln != 6) { |
return; |
} |
if (arp->ar_pln != 4) { |
return; |
} |
|
memcpy((void*) &ip_to_check, (void*)&arp->ar_data[16], |
sizeof(IPaddr_t)); |
if (NetOurIP == 0 || |
ip_to_check != NetOurIP) { |
return; |
} |
arp = (ARP_t *) ip; |
if (len < ARP_HDR_SIZE) { |
printf("bad length %d < %d\n", len, ARP_HDR_SIZE); |
return; |
} |
if (SWAP16(arp->ar_hrd) != ARP_ETHER) { |
return; |
} |
if (SWAP16(arp->ar_pro) != PROT_IP) { |
return; |
} |
if (arp->ar_hln != 6) { |
return; |
} |
if (arp->ar_pln != 4) { |
return; |
} |
|
switch (SWAP16(arp->ar_op)) { |
case ARPOP_REQUEST: /* reply with our IP address */ |
memcpy((void *)&ip_to_check, (void *)&arp->ar_data[16], |
sizeof(IPaddr_t)); |
if (NetOurIP == 0 || ip_to_check != NetOurIP) { |
return; |
} |
|
switch (SWAP16(arp->ar_op)) { |
case ARPOP_REQUEST: /* reply with our IP address */ |
#ifdef ET_DEBUG |
printf("Got ARP REQUEST, return our IP\n"); |
printf("Got ARP REQUEST, return our IP\n"); |
#endif |
NetSetEther((unsigned char *)et, et->et_src, PROT_ARP); |
arp->ar_op = SWAP16(ARPOP_REPLY); |
NetCopyEther(&arp->ar_data[10], &arp->ar_data[0]); |
NetCopyEther(&arp->ar_data[0], NetOurEther); |
//*(IPaddr_t *)(&arp->ar_data[16]) = *(IPaddr_t *)(&arp->ar_data[6]); |
memcpy((void*)&arp->ar_data[16],(void*) &arp->ar_data[6], |
sizeof(IPaddr_t)); |
//*(IPaddr_t *)(&arp->ar_data[6]) = NetOurIP; |
memcpy((void*)&arp->ar_data[6],(void*) &NetOurIP, |
sizeof(IPaddr_t)); |
|
NetSendPacket((unsigned char *)et, |
((unsigned char *)arp-pkt)+ARP_HDR_SIZE); |
return; |
case ARPOP_REPLY: /* set TFTP server eth addr */ |
NetSetEther((unsigned char *)et, et->et_src, PROT_ARP); |
arp->ar_op = SWAP16(ARPOP_REPLY); |
NetCopyEther(&arp->ar_data[10], &arp->ar_data[0]); |
NetCopyEther(&arp->ar_data[0], NetOurEther); |
//*(IPaddr_t *)(&arp->ar_data[16]) = *(IPaddr_t *)(&arp->ar_data[6]); |
memcpy((void *)&arp->ar_data[16], |
(void *)&arp->ar_data[6], sizeof(IPaddr_t)); |
//*(IPaddr_t *)(&arp->ar_data[6]) = NetOurIP; |
memcpy((void *)&arp->ar_data[6], (void *)&NetOurIP, |
sizeof(IPaddr_t)); |
|
NetSendPacket((unsigned char *)et, |
((unsigned char *)arp - pkt) + |
ARP_HDR_SIZE); |
return; |
case ARPOP_REPLY: /* set TFTP server eth addr */ |
#ifdef ET_DEBUG |
printf("Got ARP REPLY, set server/gtwy eth addr\n"); |
printf("Got ARP REPLY, set server/gtwy eth addr\n"); |
#endif |
NetCopyEther(NetServerEther, &arp->ar_data[0]); |
(*packetHandler)(0,0,0,0); /* start TFTP */ |
return; |
default: |
NetCopyEther(NetServerEther, &arp->ar_data[0]); |
(*packetHandler) (0, 0, 0, 0); /* start TFTP */ |
return; |
default: |
#ifdef ET_DEBUG |
printf("Unexpected ARP opcode 0x%x\n", SWAP16(arp->ar_op)); |
printf("Unexpected ARP opcode 0x%x\n", |
SWAP16(arp->ar_op)); |
#endif |
return; |
} |
return; |
} |
|
case PROT_RARP: |
case PROT_RARP: |
#ifdef ET_DEBUG |
printf("Got RARP\n"); |
printf("Got RARP\n"); |
#endif |
arp = (ARP_t *)ip; |
if (len < ARP_HDR_SIZE) { |
printf("bad length %d < %d\n", len, ARP_HDR_SIZE); |
return; |
} |
arp = (ARP_t *) ip; |
if (len < ARP_HDR_SIZE) { |
printf("bad length %d < %d\n", len, ARP_HDR_SIZE); |
return; |
} |
|
if ((SWAP16(arp->ar_op) != RARPOP_REPLY) || |
(SWAP16(arp->ar_hrd) != ARP_ETHER) || |
(SWAP16(arp->ar_pro) != PROT_IP) || |
(arp->ar_hln != 6) || (arp->ar_pln != 4)) { |
if ((SWAP16(arp->ar_op) != RARPOP_REPLY) || |
(SWAP16(arp->ar_hrd) != ARP_ETHER) || |
(SWAP16(arp->ar_pro) != PROT_IP) || |
(arp->ar_hln != 6) || (arp->ar_pln != 4)) { |
|
printf("invalid RARP header\n"); |
} else { |
//NetOurIP = *((IPaddr_t *)&arp->ar_data[16]); |
memcpy((void*) &NetOurIP, (void*) &arp->ar_data[16], |
sizeof(IPaddr_t)); |
//NetServerIP = *((IPaddr_t *)&arp->ar_data[6]); |
memcpy((void*) &NetServerIP,(void*) &arp->ar_data[6], |
sizeof(IPaddr_t)); |
printf("invalid RARP header\n"); |
} else { |
//NetOurIP = *((IPaddr_t *)&arp->ar_data[16]); |
memcpy((void *)&NetOurIP, (void *)&arp->ar_data[16], |
sizeof(IPaddr_t)); |
//NetServerIP = *((IPaddr_t *)&arp->ar_data[6]); |
memcpy((void *)&NetServerIP, (void *)&arp->ar_data[6], |
sizeof(IPaddr_t)); |
|
NetCopyEther(NetServerEther, &arp->ar_data[0]); |
NetCopyEther(NetServerEther, &arp->ar_data[0]); |
|
(*packetHandler)(0,0,0,0); |
} |
break; |
(*packetHandler) (0, 0, 0, 0); |
} |
break; |
|
case PROT_IP: |
case PROT_IP: |
#ifdef ET_DEBUG |
printf("Got IP\n"); |
printf("Got IP\n"); |
#endif |
if (len < IP_HDR_SIZE) { |
debug ("ip header len bad %d < %d\n", len, IP_HDR_SIZE); |
return; |
} |
if (len < SWAP16(ip->ip_len)) { |
printf("ip header (swap) len bad %d < %d\n", len, SWAP16(ip->ip_len)); |
return; |
} |
len = SWAP16(ip->ip_len); |
if (len < IP_HDR_SIZE) { |
debug("ip header len bad %d < %d\n", len, IP_HDR_SIZE); |
return; |
} |
if (len < SWAP16(ip->ip_len)) { |
printf("ip header (swap) len bad %d < %d\n", len, |
SWAP16(ip->ip_len)); |
return; |
} |
len = SWAP16(ip->ip_len); |
#ifdef ET_DEBUG |
printf("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff); |
printf("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff); |
#endif |
if ((ip->ip_hl_v & 0xf0) != 0x40) { |
return; |
} |
if (ip->ip_off & SWAP16c(0x1fff)) { /* Can't deal w/ fragments */ |
return; |
} |
if (!NetCksumOk((unsigned char *)ip, IP_HDR_SIZE_NO_UDP / 2)) { |
//printf("checksum bad\n"); |
return; |
} |
if ((ip->ip_hl_v & 0xf0) != 0x40) { |
return; |
} |
if (ip->ip_off & SWAP16c(0x1fff)) { /* Can't deal w/ fragments */ |
return; |
} |
if (!NetCksumOk((unsigned char *)ip, IP_HDR_SIZE_NO_UDP / 2)) { |
//printf("checksum bad\n"); |
return; |
} |
|
memcpy((void*)&ip_to_check,(void*)&ip->ip_dst, sizeof (IPaddr_t)); |
memcpy((void *)&ip_to_check, (void *)&ip->ip_dst, |
sizeof(IPaddr_t)); |
|
if (NetOurIP && |
ip_to_check != NetOurIP && |
ip_to_check != 0xFFFFFFFF) { |
return; |
} |
/* |
* watch for ICMP host redirects |
* |
* There is no real handler code (yet). We just watch |
* for ICMP host redirect messages. In case anybody |
* sees these messages: please contact me |
* (wd@denx.de), or - even better - send me the |
* necessary fixes :-) |
* |
* Note: in all cases where I have seen this so far |
* it was a problem with the router configuration, |
* for instance when a router was configured in the |
* BOOTP reply, but the TFTP server was on the same |
* subnet. So this is probably a warning that your |
* configuration might be wrong. But I'm not really |
* sure if there aren't any other situations. |
*/ |
if (ip->ip_p == IPPROTO_ICMP) { |
ICMP_t *icmph = (ICMP_t *)&(ip->udp_src); |
if (NetOurIP && |
ip_to_check != NetOurIP && ip_to_check != 0xFFFFFFFF) { |
return; |
} |
/* |
* watch for ICMP host redirects |
* |
* There is no real handler code (yet). We just watch |
* for ICMP host redirect messages. In case anybody |
* sees these messages: please contact me |
* (wd@denx.de), or - even better - send me the |
* necessary fixes :-) |
* |
* Note: in all cases where I have seen this so far |
* it was a problem with the router configuration, |
* for instance when a router was configured in the |
* BOOTP reply, but the TFTP server was on the same |
* subnet. So this is probably a warning that your |
* configuration might be wrong. But I'm not really |
* sure if there aren't any other situations. |
*/ |
if (ip->ip_p == IPPROTO_ICMP) { |
ICMP_t *icmph = (ICMP_t *) & (ip->udp_src); |
|
if (icmph->type != ICMP_REDIRECT) |
return; |
if (icmph->code != ICMP_REDIR_HOST) |
return; |
printf (" ICMP Host Redirect to "); |
print_IPaddr(icmph->un.gateway); |
putc(' '); |
} else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */ |
return; |
} |
if (icmph->type != ICMP_REDIRECT) |
return; |
if (icmph->code != ICMP_REDIR_HOST) |
return; |
printf(" ICMP Host Redirect to "); |
print_IPaddr(icmph->un.gateway); |
putc(' '); |
} else if (ip->ip_p != IPPROTO_UDP) { /* Only UDP packets */ |
return; |
} |
|
/* |
* IP header OK. Pass the packet to the current handler. |
*/ |
(*packetHandler)((unsigned char *)ip +IP_HDR_SIZE, |
SWAP16(ip->udp_dst), |
SWAP16(ip->udp_src), |
SWAP16(ip->udp_len) - 8); |
/* |
* IP header OK. Pass the packet to the current handler. |
*/ |
(*packetHandler) ((unsigned char *)ip + IP_HDR_SIZE, |
SWAP16(ip->udp_dst), |
SWAP16(ip->udp_src), SWAP16(ip->udp_len) - 8); |
|
break; |
} |
break; |
} |
} |
|
|
/**********************************************************************/ |
|
static int net_check_prereq (proto_t protocol) |
static int net_check_prereq(proto_t protocol) |
{ |
switch (protocol) { |
case ARP: /* nothing to do */ |
break; |
switch (protocol) { |
case ARP: /* nothing to do */ |
break; |
|
case TFTP: |
if (NetServerIP == 0) { |
printf ("*** ERROR: `serverip' not set\n"); |
return (1); |
} |
case TFTP: |
if (NetServerIP == 0) { |
printf("*** ERROR: `serverip' not set\n"); |
return (1); |
} |
|
if (NetOurIP == 0) { |
printf ("*** ERROR: `ipaddr' not set\n"); |
return (1); |
} |
/* Fall through */ |
if (NetOurIP == 0) { |
printf("*** ERROR: `ipaddr' not set\n"); |
return (1); |
} |
/* Fall through */ |
|
case DHCP: |
case RARP: |
case BOOTP: |
if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) { |
printf ("*** ERROR: `ethaddr' not set\n"); |
return (1); |
} |
/* Fall through */ |
} |
return (0); /* OK */ |
case DHCP: |
case RARP: |
case BOOTP: |
if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) { |
printf("*** ERROR: `ethaddr' not set\n"); |
return (1); |
} |
/* Fall through */ |
} |
return (0); /* OK */ |
} |
|
/**********************************************************************/ |
|
int |
NetCksumOk(unsigned char * ptr, int len) |
int NetCksumOk(unsigned char *ptr, int len) |
{ |
return !((NetCksum(ptr, len) + 1) & 0xfffe); |
return !((NetCksum(ptr, len) + 1) & 0xfffe); |
} |
|
|
unsigned |
NetCksum(unsigned char * ptr, int len) |
unsigned NetCksum(unsigned char *ptr, int len) |
{ |
unsigned long xsum; |
unsigned long xsum; |
|
xsum = 0; |
while (len-- > 0) |
{ |
xsum += (*((unsigned short *)ptr)); |
ptr += sizeof(short); |
} |
|
xsum = (xsum & 0xffff) + (xsum >> 16); |
xsum = (xsum & 0xffff) + (xsum >> 16); |
return (xsum & 0xffff); |
xsum = 0; |
while (len-- > 0) { |
xsum += (*((unsigned short *)ptr)); |
ptr += sizeof(short); |
} |
|
xsum = (xsum & 0xffff) + (xsum >> 16); |
xsum = (xsum & 0xffff) + (xsum >> 16); |
return (xsum & 0xffff); |
} |
|
|
void |
NetCopyEther(volatile unsigned char * to, unsigned char * from) |
void NetCopyEther(volatile unsigned char *to, unsigned char *from) |
{ |
int i; |
int i; |
|
for (i = 0; i < 6; i++) |
*to++ = *from++; |
for (i = 0; i < 6; i++) |
*to++ = *from++; |
} |
|
|
void |
NetSetEther(volatile unsigned char * xet, unsigned char * addr, unsigned long prot) |
NetSetEther(volatile unsigned char *xet, unsigned char *addr, |
unsigned long prot) |
{ |
volatile Ethernet_t *et = (Ethernet_t *)xet; |
volatile Ethernet_t *et = (Ethernet_t *) xet; |
|
NetCopyEther(et->et_dest, addr); |
NetCopyEther(et->et_src, NetOurEther); |
et->et_protlen = SWAP16(prot); |
NetCopyEther(et->et_dest, addr); |
NetCopyEther(et->et_src, NetOurEther); |
et->et_protlen = SWAP16(prot); |
} |
|
|
void |
NetSetIP(volatile unsigned char * xip, IPaddr_t dest, int dport, int sport, int len) |
NetSetIP(volatile unsigned char *xip, IPaddr_t dest, int dport, int sport, |
int len) |
{ |
volatile IP_t *ip = (IP_t *)xip; |
volatile IP_t *ip = (IP_t *) xip; |
|
/* |
* If the data is an odd number of bytes, zero the |
* byte after the last byte so that the checksum |
* will work. |
*/ |
if (len & 1) |
xip[IP_HDR_SIZE + len] = 0; |
/* |
* If the data is an odd number of bytes, zero the |
* byte after the last byte so that the checksum |
* will work. |
*/ |
if (len & 1) |
xip[IP_HDR_SIZE + len] = 0; |
|
/* |
* Construct an IP and UDP header. |
(need to set no fragment bit - XXX) |
*/ |
ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ |
ip->ip_tos = 0; |
ip->ip_len = SWAP16(IP_HDR_SIZE + len); |
ip->ip_id = SWAP16(NetIPID++); |
ip->ip_off = SWAP16c(0x4000); /* No fragmentation */ |
ip->ip_ttl = 255; |
ip->ip_p = 17; /* UDP */ |
ip->ip_sum = 0; |
//ip->ip_src = NetOurIP; |
memcpy((void*)&ip->ip_src,(void*) &NetOurIP, |
sizeof(IPaddr_t)); |
//ip->ip_dst = dest; |
memcpy((void*)&ip->ip_dst,(void*) &dest, |
sizeof(IPaddr_t)); |
ip->udp_src = SWAP16(sport); |
ip->udp_dst = SWAP16(dport); |
ip->udp_len = SWAP16(8 + len); |
ip->udp_xsum = 0; |
ip->ip_sum = ~NetCksum((unsigned char *)ip, IP_HDR_SIZE_NO_UDP / 2); |
/* |
* Construct an IP and UDP header. |
(need to set no fragment bit - XXX) |
*/ |
ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ |
ip->ip_tos = 0; |
ip->ip_len = SWAP16(IP_HDR_SIZE + len); |
ip->ip_id = SWAP16(NetIPID++); |
ip->ip_off = SWAP16c(0x4000); /* No fragmentation */ |
ip->ip_ttl = 255; |
ip->ip_p = 17; /* UDP */ |
ip->ip_sum = 0; |
//ip->ip_src = NetOurIP; |
memcpy((void *)&ip->ip_src, (void *)&NetOurIP, sizeof(IPaddr_t)); |
//ip->ip_dst = dest; |
memcpy((void *)&ip->ip_dst, (void *)&dest, sizeof(IPaddr_t)); |
ip->udp_src = SWAP16(sport); |
ip->udp_dst = SWAP16(dport); |
ip->udp_len = SWAP16(8 + len); |
ip->udp_xsum = 0; |
ip->ip_sum = ~NetCksum((unsigned char *)ip, IP_HDR_SIZE_NO_UDP / 2); |
} |
|
void copy_filename (unsigned char *dst, unsigned char *src, int size) |
void copy_filename(unsigned char *dst, unsigned char *src, int size) |
{ |
if (*src && (*src == '"')) { |
++src; |
--size; |
} |
if (*src && (*src == '"')) { |
++src; |
--size; |
} |
|
while ((--size > 0) && *src && (*src != '"')) { |
*dst++ = *src++; |
} |
*dst = '\0'; |
while ((--size > 0) && *src && (*src != '"')) { |
*dst++ = *src++; |
} |
*dst = '\0'; |
} |
|
void ip_to_string (IPaddr_t x, char *s) |
void ip_to_string(IPaddr_t x, char *s) |
{ |
char num[] = "0123456789ABCDEF"; |
int i; |
char num[] = "0123456789ABCDEF"; |
int i; |
|
x = SWAP32(x); |
|
for(i = 28; i >= 0; i -= 4) |
*s++ = num[((x >> i) & 0x0f)]; |
*s = 0; |
x = SWAP32(x); |
|
for (i = 28; i >= 0; i -= 4) |
*s++ = num[((x >> i) & 0x0f)]; |
*s = 0; |
} |
|
void print_IPaddr (IPaddr_t x) |
void print_IPaddr(IPaddr_t x) |
{ |
char tmp[12]; |
char tmp[12]; |
|
ip_to_string(x, tmp); |
ip_to_string(x, tmp); |
|
printf(tmp); |
printf(tmp); |
} |
|
static unsigned int i2a(char* dest,unsigned int x) { |
register unsigned int tmp=x; |
register unsigned int len=0; |
if (x>=100) { *dest++=tmp/100+'0'; tmp=tmp%100; ++len; } |
if (x>=10) { *dest++=tmp/10+'0'; tmp=tmp%10; ++len; } |
*dest++=tmp+'0'; |
return len+1; |
static unsigned int i2a(char *dest, unsigned int x) |
{ |
register unsigned int tmp = x; |
register unsigned int len = 0; |
if (x >= 100) { |
*dest++ = tmp / 100 + '0'; |
tmp = tmp % 100; |
++len; |
} |
if (x >= 10) { |
*dest++ = tmp / 10 + '0'; |
tmp = tmp % 10; |
++len; |
} |
*dest++ = tmp + '0'; |
return len + 1; |
} |
|
char *inet_ntoa(unsigned long in) { |
static char buf[20]; |
unsigned int len; |
unsigned char *ip=(unsigned char*)∈ |
char *inet_ntoa(unsigned long in) |
{ |
static char buf[20]; |
unsigned int len; |
unsigned char *ip = (unsigned char *)∈ |
|
len=i2a(buf,ip[0]); buf[len]='.'; ++len; |
len+=i2a(buf+ len,ip[1]); buf[len]='.'; ++len; |
len+=i2a(buf+ len,ip[2]); buf[len]='.'; ++len; |
len+=i2a(buf+ len,ip[3]); buf[len]=0; |
return buf; |
len = i2a(buf, ip[0]); |
buf[len] = '.'; |
++len; |
len += i2a(buf + len, ip[1]); |
buf[len] = '.'; |
++len; |
len += i2a(buf + len, ip[2]); |
buf[len] = '.'; |
++len; |
len += i2a(buf + len, ip[3]); |
buf[len] = 0; |
return buf; |
} |
|
unsigned long inet_aton(const char *cp) |
{ |
unsigned long a[4]; |
unsigned long ret; |
char *p = (char *)cp; |
int i,d; |
if (strcmp(cp, "255.255.255.255") == 0) |
return -1; |
|
for(i = 0; i < 4; i++) { |
a[i] = strtoul(p, 0, 0); |
for(d=1; (p[d] != '.') && (i < 3); d++); |
p = &p[d+1]; |
} |
unsigned long a[4]; |
unsigned long ret; |
char *p = (char *)cp; |
int i, d; |
if (strcmp(cp, "255.255.255.255") == 0) |
return -1; |
|
ret = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]; |
return ret; |
for (i = 0; i < 4; i++) { |
a[i] = strtoul(p, 0, 0); |
for (d = 1; (p[d] != '.') && (i < 3); d++) ; |
p = &p[d + 1]; |
} |
|
ret = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]; |
return ret; |
} |
|
#endif |
/arp.h
21,7 → 21,6
* MA 02111-1307 USA |
*/ |
|
|
#ifndef __ARP_H__ |
#define __ARP_H__ |
|
32,9 → 31,8
|
extern int ArpTry; |
|
extern void ArpRequest (void); /* Send a ARP request */ |
extern void ArpRequest(void); /* Send a ARP request */ |
|
/**********************************************************************/ |
|
#endif /* __ARP_H__ */ |
|
/bootp.h
19,33 → 19,32
* BOOTP header. |
*/ |
#if (CONFIG_COMMANDS & CFG_CMD_DHCP) |
#define OPT_SIZE 312 /* Minimum DHCP Options size per RFC2131 - results in 576 byte pkt */ |
#define OPT_SIZE 312 /* Minimum DHCP Options size per RFC2131 - results in 576 byte pkt */ |
#else |
#define OPT_SIZE 64 |
#endif |
|
typedef struct |
{ |
unsigned char bp_op; /* Operation */ |
typedef struct { |
unsigned char bp_op; /* Operation */ |
# define OP_BOOTREQUEST 1 |
# define OP_BOOTREPLY 2 |
unsigned char bp_htype; /* Hardware type */ |
unsigned char bp_htype; /* Hardware type */ |
# define HWT_ETHER 1 |
unsigned char bp_hlen; /* Hardware address length */ |
unsigned char bp_hlen; /* Hardware address length */ |
# define HWL_ETHER 6 |
unsigned char bp_hops; /* Hop count (gateway thing) */ |
unsigned long bp_id; /* Transaction ID */ |
unsigned short bp_secs; /* Seconds since boot */ |
unsigned short bp_spare1; /* Alignment */ |
IPaddr_t bp_ciaddr; /* Client IP address */ |
IPaddr_t bp_yiaddr; /* Your (client) IP address */ |
IPaddr_t bp_siaddr; /* Server IP address */ |
IPaddr_t bp_giaddr; /* Gateway IP address */ |
unsigned char bp_chaddr[16]; /* Client hardware address */ |
char bp_sname[64]; /* Server host name */ |
char bp_file[128]; /* Boot file name */ |
char bp_vend[OPT_SIZE]; /* Vendor information */ |
} Bootp_t; |
unsigned char bp_hops; /* Hop count (gateway thing) */ |
unsigned long bp_id; /* Transaction ID */ |
unsigned short bp_secs; /* Seconds since boot */ |
unsigned short bp_spare1; /* Alignment */ |
IPaddr_t bp_ciaddr; /* Client IP address */ |
IPaddr_t bp_yiaddr; /* Your (client) IP address */ |
IPaddr_t bp_siaddr; /* Server IP address */ |
IPaddr_t bp_giaddr; /* Gateway IP address */ |
unsigned char bp_chaddr[16]; /* Client hardware address */ |
char bp_sname[64]; /* Server host name */ |
char bp_file[128]; /* Boot file name */ |
char bp_vend[OPT_SIZE]; /* Vendor information */ |
} Bootp_t; |
|
#define BOOTP_HDR_SIZE sizeof (Bootp_t) |
#define BOOTP_SIZE (ETHER_HDR_SIZE + IP_HDR_SIZE + BOOTP_HDR_SIZE) |
56,16 → 55,15
*/ |
|
/* bootp.c */ |
extern unsigned long BootpID; /* ID of cur BOOTP request */ |
extern char BootFile[128]; /* Boot file name */ |
extern int BootpTry; |
extern unsigned long BootpID; /* ID of cur BOOTP request */ |
extern char BootFile[128]; /* Boot file name */ |
extern int BootpTry; |
#ifdef CONFIG_BOOTP_RANDOM_DELAY |
unsigned long seed1, seed2; /* seed for random BOOTP delay */ |
unsigned long seed1, seed2; /* seed for random BOOTP delay */ |
#endif |
|
|
/* Send a BOOTP request */ |
extern void BootpRequest (void); |
extern void BootpRequest(void); |
|
/****************** DHCP Support *********************/ |
extern void DhcpRequest(void); |
72,13 → 70,14
|
/* DHCP States */ |
typedef enum { INIT, |
INIT_REBOOT, |
REBOOTING, |
SELECTING, |
REQUESTING, |
REBINDING, |
BOUND, |
RENEWING } dhcp_state_t; |
INIT_REBOOT, |
REBOOTING, |
SELECTING, |
REQUESTING, |
REBINDING, |
BOUND, |
RENEWING |
} dhcp_state_t; |
|
#define DHCP_DISCOVER 1 |
#define DHCP_OFFER 2 |
/rarp.h
21,7 → 21,6
* MA 02111-1307 USA |
*/ |
|
|
#ifndef __RARP_H__ |
#define __RARP_H__ |
|
29,15 → 28,14
#include "net.h" |
#endif /* __NET_H__ */ |
|
|
/**********************************************************************/ |
/* |
* Global functions and variables. |
*/ |
|
extern int RarpTry; |
extern int RarpTry; |
|
extern void RarpRequest (void); /* Send a RARP request */ |
extern void RarpRequest(void); /* Send a RARP request */ |
|
/**********************************************************************/ |
|
/tftp.c
10,13 → 10,12
#include "tftp.h" |
#include "bootp.h" |
|
#define WELL_KNOWN_PORT 69 /* Well known TFTP port # */ |
#define TIMEOUT 2 /* Seconds to timeout for a lost pkt */ |
#define TIMEOUT_COUNT 10 /* # of timeouts before giving up */ |
/* (for checking the image size) */ |
#define HASHES_PER_LINE 65 /* Number of "loading" hashes per line */ |
|
#define WELL_KNOWN_PORT 69 /* Well known TFTP port # */ |
#define TIMEOUT 2 /* Seconds to timeout for a lost pkt */ |
#define TIMEOUT_COUNT 10 /* # of timeouts before giving up */ |
/* (for checking the image size) */ |
#define HASHES_PER_LINE 65 /* Number of "loading" hashes per line */ |
|
/* |
* TFTP operations. |
*/ |
26,13 → 25,12
#define TFTP_ACK 4 |
#define TFTP_ERROR 5 |
|
|
static int TftpServerPort; /* The UDP port at their end */ |
static int TftpOurPort; /* The UDP port at our end */ |
static int TftpTimeoutCount; |
static unsigned TftpBlock; |
static unsigned TftpLastBlock; |
static int TftpState; |
static int TftpServerPort; /* The UDP port at their end */ |
static int TftpOurPort; /* The UDP port at our end */ |
static int TftpTimeoutCount; |
static unsigned TftpBlock; |
static unsigned TftpLastBlock; |
static int TftpState; |
#define STATE_RRQ 1 |
#define STATE_DATA 2 |
#define STATE_TOO_LARGE 3 |
40,7 → 38,6
|
char *tftp_filename; |
|
|
// running TFTP CRC value |
unsigned long TFTP_CHKSUM; |
|
49,13 → 46,13
#endif |
|
static __inline__ void |
store_block (unsigned block, unsigned char * src, unsigned len) |
store_block(unsigned block, unsigned char *src, unsigned len) |
{ |
unsigned long offset = block * 512, newsize = offset + len; |
#ifdef CFG_DIRECT_FLASH_TFTP |
int i, rc = 0; |
|
for (i=0; i<CFG_MAX_FLASH_BANKS; i++) { |
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { |
/* start address in flash? */ |
if (global.src_addr + offset >= flash_info[i].start[0]) { |
rc = 1; |
63,23 → 60,30
} |
} |
|
if (rc) { /* Flash is destination for this packet */ |
rc = flash_write ((unsigned char *)src, (unsigned long)(global.src_addr+offset), len); |
if (rc) { /* Flash is destination for this packet */ |
rc = flash_write((unsigned char *)src, |
(unsigned long)(global.src_addr + offset), |
len); |
switch (rc) { |
case 0: /* OK */ |
break; |
case 1: printf ("Timeout writing to Flash\n"); |
case 1: |
printf("Timeout writing to Flash\n"); |
break; |
case 2: printf ("Flash not Erased\n"); |
case 2: |
printf("Flash not Erased\n"); |
break; |
case 4: printf ("Can't write to protected Flash sectors\n"); |
case 4: |
printf("Can't write to protected Flash sectors\n"); |
break; |
case 8: printf ("Outside available Flash\n"); |
case 8: |
printf("Outside available Flash\n"); |
break; |
case 16:printf ("Size must be aligned (multiple of 8?)\n"); |
case 16: |
printf("Size must be aligned (multiple of 8?)\n"); |
break; |
default: |
printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc); |
printf("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, rc); |
break; |
} |
if (rc) { |
86,86 → 90,84
NetState = NETLOOP_FAIL; |
return; |
} |
} |
else |
} else |
#endif /* CFG_DIRECT_FLASH_TFTP */ |
|
//#define QUICK_ETHPACKET_COPY |
//#define QUICK_ETHPACKET_COPY |
#ifdef QUICK_ETHPACKET_COPY |
{ |
unsigned char * dst = (unsigned char*)(global.src_addr + offset); |
//printf("quick ethpacket copy: src: 0x%x dst: 0x%x, len: %d\n",(unsigned long)src, (unsigned long)dst, len); |
// First, align the destination address so we can copy words |
// If either src or dst are not word aligned, then we will never |
// be able to do word copies |
while((len) && ((((unsigned long)dst) & 0x3) || (((unsigned long)src) & 0x3))) |
{ |
// printf("bc: src: 0x%x dst: 0x%x, len: %d\n",(unsigned long)src, (unsigned long)dst, len); |
dst[0] = src[0]; |
len--; |
dst++; |
src++; |
|
} |
unsigned long *wdst, *wsrc; |
wdst = (unsigned long*) dst; |
wsrc = (unsigned long*) src; |
while(len >= 4) |
{ |
//printf("wc: src: 0x%x dst: 0x%x, len: %d\n",(unsigned long)src, (unsigned long)dst, len); |
wdst[0] = wsrc[0]; |
wdst++; wsrc++; |
len -= 4; |
dst+=4; |
src+=4; |
{ |
unsigned char *dst = |
(unsigned char *)(global.src_addr + offset); |
//printf("quick ethpacket copy: src: 0x%x dst: 0x%x, len: %d\n",(unsigned long)src, (unsigned long)dst, len); |
// First, align the destination address so we can copy words |
// If either src or dst are not word aligned, then we will never |
// be able to do word copies |
while ((len) |
&& ((((unsigned long)dst) & 0x3) |
|| (((unsigned long)src) & 0x3))) { |
// printf("bc: src: 0x%x dst: 0x%x, len: %d\n",(unsigned long)src, (unsigned long)dst, len); |
dst[0] = src[0]; |
len--; |
dst++; |
src++; |
|
} |
while (len) |
{ |
//printf("cu: src: 0x%x dst: 0x%x, len: %d\n",(unsigned long)src, (unsigned long)dst, len); |
dst[0] = src[0]; |
len--; |
dst++; |
src++; |
} |
} |
} |
unsigned long *wdst, *wsrc; |
wdst = (unsigned long *)dst; |
wsrc = (unsigned long *)src; |
while (len >= 4) { |
//printf("wc: src: 0x%x dst: 0x%x, len: %d\n",(unsigned long)src, (unsigned long)dst, len); |
wdst[0] = wsrc[0]; |
wdst++; |
wsrc++; |
len -= 4; |
dst += 4; |
src += 4; |
|
} |
while (len) { |
//printf("cu: src: 0x%x dst: 0x%x, len: %d\n",(unsigned long)src, (unsigned long)dst, len); |
dst[0] = src[0]; |
len--; |
dst++; |
src++; |
} |
} |
#else |
|
|
#ifdef TFTP_CALC_CRC |
// Call special memcpy that calculates CRC for us: |
TFTP_CHKSUM += memcpy_crc((void *)(global.src_addr + offset), src, len); |
// Call special memcpy that calculates CRC for us: |
TFTP_CHKSUM += |
memcpy_crc((void *)(global.src_addr + offset), src, len); |
#else |
// Standard memcpy: |
(void)memcpy((void *)(global.src_addr + offset), src, len); |
// Standard memcpy: |
(void)memcpy((void *)(global.src_addr + offset), src, len); |
#endif |
|
|
#endif |
#endif |
|
if (NetBootFileXferSize < newsize) |
NetBootFileXferSize = newsize; |
} |
|
static void TftpSend (void); |
static void TftpTimeout (void); |
static void TftpSend(void); |
static void TftpTimeout(void); |
|
/**********************************************************************/ |
|
static void |
TftpSend (void) |
static void TftpSend(void) |
{ |
volatile unsigned char * pkt; |
volatile unsigned char * xp; |
int len = 0; |
volatile unsigned char *pkt; |
volatile unsigned char *xp; |
int len = 0; |
|
#ifdef ET_DEBUG |
printf("TftpSend: %d\n", TftpState); |
#endif |
|
|
/* |
* We will always be sending some sort of packet, so |
* cobble together the packet headers now. |
* We will always be sending some sort of packet, so |
* cobble together the packet headers now. |
*/ |
pkt = NetTxPacket + ETHER_HDR_SIZE + IP_HDR_SIZE; |
|
175,10 → 177,10
xp = pkt; |
(*((unsigned short *)pkt)) = SWAP16c(TFTP_RRQ); |
pkt += sizeof(short); |
strcpy ((char *)pkt, tftp_filename); |
strcpy((char *)pkt, tftp_filename); |
pkt += strlen(tftp_filename) + 1; |
strcpy ((char *)pkt, "octet"); |
pkt += 5 /*strlen("octet")*/ + 1; |
strcpy((char *)pkt, "octet"); |
pkt += 5 /*strlen("octet") */ + 1; |
len = pkt - xp; |
|
break; |
198,8 → 200,8
pkt += sizeof(short); |
*((unsigned short *)pkt) = SWAP16(3); |
pkt += sizeof(short); |
strcpy ((char *)pkt, "File too large"); |
pkt += 14 /*strlen("File too large")*/ + 1; |
strcpy((char *)pkt, "File too large"); |
pkt += 14 /*strlen("File too large") */ + 1; |
len = pkt - xp; |
break; |
|
209,25 → 211,24
pkt += sizeof(short); |
*((unsigned short *)pkt) = SWAP16(2); |
pkt += sizeof(short); |
strcpy ((char *)pkt, "File has bad magic"); |
pkt += 18 /*strlen("File has bad magic")*/ + 1; |
strcpy((char *)pkt, "File has bad magic"); |
pkt += 18 /*strlen("File has bad magic") */ + 1; |
len = pkt - xp; |
break; |
} |
|
NetSetEther (NetTxPacket, NetServerEther, PROT_IP); |
NetSetIP (NetTxPacket + ETHER_HDR_SIZE, NetServerIP, |
TftpServerPort, TftpOurPort, len); |
NetSendPacket (NetTxPacket, ETHER_HDR_SIZE + IP_HDR_SIZE + len); |
NetSetEther(NetTxPacket, NetServerEther, PROT_IP); |
NetSetIP(NetTxPacket + ETHER_HDR_SIZE, NetServerIP, |
TftpServerPort, TftpOurPort, len); |
NetSendPacket(NetTxPacket, ETHER_HDR_SIZE + IP_HDR_SIZE + len); |
|
} |
|
|
static void |
TftpHandler (unsigned char * pkt, unsigned dest, unsigned src, unsigned len) |
TftpHandler(unsigned char *pkt, unsigned dest, unsigned src, unsigned len) |
{ |
#ifdef ET_DEBUG |
// printf("TftpHandler\n"); |
// printf("TftpHandler\n"); |
#endif |
if (dest != TftpOurPort) { |
return; |
245,22 → 246,22
case TFTP_RRQ: |
case TFTP_WRQ: |
case TFTP_ACK: |
pkt += sizeof(short); |
pkt += sizeof(short); |
break; |
default: |
break; |
|
case TFTP_DATA: |
pkt += sizeof(short); |
pkt += sizeof(short); |
if (len < 2) |
return; |
len -= 2; |
TftpBlock = SWAP16(*(unsigned short *)pkt); |
if (((TftpBlock - 1) % 10) == 0) { |
putc ('#'); |
putc('#'); |
TftpTimeoutCount = 0; |
} else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0) { |
printf ("\n\t "); |
printf("\n\t "); |
} |
|
if (TftpState == STATE_RRQ) { |
268,13 → 269,11
TftpServerPort = src; |
TftpLastBlock = 0; |
|
|
if (TftpBlock != 1) { /* Assertion */ |
printf ("\nTFTP error: " |
"First block is not block 1 (%d)\n" |
"Starting again\n\n", |
TftpBlock); |
NetStartAgain (); |
printf("\nTFTP error: " |
"First block is not block 1 (%d)\n" |
"Starting again\n\n", TftpBlock); |
NetStartAgain(); |
break; |
} |
} |
281,115 → 280,108
|
if (TftpBlock == TftpLastBlock) { |
#ifdef ET_DEBUG |
printf("block %d - repeated\n",TftpLastBlock); |
printf("block %d - repeated\n", TftpLastBlock); |
#endif |
/* |
* Same block again; resend ack (maybe got lost last time) |
*/ |
TftpSend (); |
break; |
} |
else |
{ |
/* |
* Same block again; resend ack (maybe got lost last time) |
*/ |
TftpSend(); |
break; |
} else { |
#ifdef ET_DEBUG |
printf("block %d - OK\n",TftpLastBlock); |
printf("block %d - OK\n", TftpLastBlock); |
#endif |
TftpLastBlock = TftpBlock; |
NetSetTimeout (TIMEOUT * TICKS_PER_SEC, TftpTimeout); |
|
store_block (TftpBlock - 1, pkt + 2, len); |
} |
|
TftpLastBlock = TftpBlock; |
NetSetTimeout(TIMEOUT * TICKS_PER_SEC, TftpTimeout); |
|
store_block(TftpBlock - 1, pkt + 2, len); |
} |
|
/* |
* Acknoledge the block just received, which will prompt |
* the server for the next one. |
* Acknoledge the block just received, which will prompt |
* the server for the next one. |
*/ |
TftpSend (); |
|
TftpSend(); |
|
if (len < 512) { |
/* |
* We received the whole thing. Try to |
* run it. |
* We received the whole thing. Try to |
* run it. |
*/ |
printf ("\ndone\n"); |
printf("\ndone\n"); |
NetState = NETLOOP_SUCCESS; |
} |
break; |
|
case TFTP_ERROR: |
pkt += sizeof(short); |
printf ("\nTFTP error: '%s' (%d)\n", |
pkt + 2, SWAP16(*(unsigned short *)pkt)); |
printf ("Starting again\n\n"); |
NetStartAgain (); |
pkt += sizeof(short); |
printf("\nTFTP error: '%s' (%d)\n", |
pkt + 2, SWAP16(*(unsigned short *)pkt)); |
printf("Starting again\n\n"); |
NetStartAgain(); |
break; |
} |
|
|
} |
|
|
static void |
TftpTimeout (void) |
static void TftpTimeout(void) |
{ |
if (++TftpTimeoutCount >= TIMEOUT_COUNT) { |
printf ("\nRetry count exceeded; starting again\n"); |
NetStartAgain (); |
printf("\nRetry count exceeded; starting again\n"); |
NetStartAgain(); |
} else { |
printf ("T "); |
NetSetTimeout (TIMEOUT * TICKS_PER_SEC, TftpTimeout); |
TftpSend (); |
printf("T "); |
NetSetTimeout(TIMEOUT * TICKS_PER_SEC, TftpTimeout); |
TftpSend(); |
} |
} |
|
|
void |
TftpStart (void) |
void TftpStart(void) |
{ |
#ifdef ET_DEBUG |
printf ("\nServer ethernet address %02x:%02x:%02x:%02x:%02x:%02x\n", |
NetServerEther[0], |
NetServerEther[1], |
NetServerEther[2], |
NetServerEther[3], |
NetServerEther[4], |
NetServerEther[5] |
); |
printf("\nServer ethernet address %02x:%02x:%02x:%02x:%02x:%02x\n", |
NetServerEther[0], |
NetServerEther[1], |
NetServerEther[2], |
NetServerEther[3], NetServerEther[4], NetServerEther[5] |
); |
#endif /* DEBUG */ |
|
TFTP_CHKSUM = 0; // Reset checksum |
TFTP_CHKSUM = 0; // Reset checksum |
|
printf ("TFTP from server "); print_IPaddr (NetServerIP); |
printf ("; our IP address is "); print_IPaddr (NetOurIP); |
printf("TFTP from server "); |
print_IPaddr(NetServerIP); |
printf("; our IP address is "); |
print_IPaddr(NetOurIP); |
|
// Check if we need to send across this subnet |
if (NetOurGatewayIP && NetOurSubnetMask) { |
IPaddr_t OurNet = NetOurIP & NetOurSubnetMask; |
IPaddr_t ServerNet = NetServerIP & NetOurSubnetMask; |
IPaddr_t OurNet = NetOurIP & NetOurSubnetMask; |
IPaddr_t ServerNet = NetServerIP & NetOurSubnetMask; |
|
if (OurNet != ServerNet) { |
printf ("; sending through gateway "); |
print_IPaddr (NetOurGatewayIP) ; |
} |
if (OurNet != ServerNet) { |
printf("; sending through gateway "); |
print_IPaddr(NetOurGatewayIP); |
} |
} |
putc ('\n'); |
putc('\n'); |
|
printf ("Filename '%s'.", tftp_filename); |
printf("Filename '%s'.", tftp_filename); |
|
if (NetBootFileSize) { |
printf (" Size is %d%s kB => %x Bytes", |
NetBootFileSize/2, |
(NetBootFileSize%2) ? ".5" : "", |
NetBootFileSize<<9); |
printf(" Size is %d%s kB => %x Bytes", |
NetBootFileSize / 2, |
(NetBootFileSize % 2) ? ".5" : "", NetBootFileSize << 9); |
} |
|
putc ('\n'); |
putc('\n'); |
|
printf ("Load address: 0x%lx\n", global.src_addr); |
printf("Load address: 0x%lx\n", global.src_addr); |
|
printf ("Loading: *\b"); |
printf("Loading: *\b"); |
|
NetSetTimeout (TIMEOUT * TICKS_PER_SEC, TftpTimeout); |
NetSetHandler (TftpHandler); |
NetSetTimeout(TIMEOUT * TICKS_PER_SEC, TftpTimeout); |
NetSetHandler(TftpHandler); |
|
TftpServerPort = WELL_KNOWN_PORT; |
TftpTimeoutCount = 0; |
396,6 → 388,5
TftpState = STATE_RRQ; |
TftpOurPort = 1024 + (get_timer(0) % 3072); |
|
TftpSend (); |
TftpSend(); |
} |
|