/* Load failed. Start again. */
extern void NetStartAgain(void);
+/*
+ * The following functions are a bit ugly, but necessary to deal with
+ * alignment restrictions on ARM.
+ *
+ * We're using inline functions, which had the smallest memory
+ * footprint in our tests.
+ */
/* Copy ethernet address */
-extern void NetCopyEther(volatile uchar *, uchar *);
+static inline void NetCopyEther(volatile uchar *to, uchar *from)
+{
+ memcpy((void*)to, (void*)from, 6);
+}
-/* Write IP address to network data structure (outgoing traffic) */
-extern void NetWriteIP(volatile uchar * to, IPaddr_t ip);
+static inline int NetCmpEther(uchar *a, uchar *b)
+{
+ return(memcmp((void*)a, (void*)b, 6));
+}
-/* Read IP address from network data structure (incoming traffic) */
-extern IPaddr_t NetReadIP(volatile uchar * to);
+/* return IP *in network byteorder* */
+static inline IPaddr_t NetReadIP(IPaddr_t *from)
+{
+ IPaddr_t ip;
+ memcpy((void*)&ip, (void*)from, sizeof(ip));
+ return ip;
+}
-/* Copy IP address from one location to another */
-extern void NetCopyIP(volatile uchar * to, volatile uchar *from);
+/* write IP *in network byteorder* */
+static inline void NetWriteIP(IPaddr_t *to, IPaddr_t ip)
+{
+ memcpy((void*)to, (void*)&ip, sizeof(ip));
+}
+
+/* copy IP */
+static inline void NetCopyIP(volatile IPaddr_t *to, IPaddr_t *from)
+{
+ memcpy((void*)to, (void*)from, sizeof(IPaddr_t));
+}
+
+/* return ulong *in network byteorder* */
+static inline ulong NetReadLong(ulong *from)
+{
+ ulong l;
+ memcpy((void*)&l, (void*)from, sizeof(l));
+ return l;
+}
+
+/* copy ulong */
+static inline void NetCopyLong(ulong *to, ulong *from)
+{
+ memcpy((void*)to, (void*)from, sizeof(ulong));
+}
/* Set ethernet header */
extern void NetSetEther(volatile uchar *, uchar *, uint);
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;
+ 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;
}
}
{
Bootp_t *bp = (Bootp_t *) pkt;
int retval = 0;
- ulong id;
if (dest != PORT_BOOTPC || src != PORT_BOOTPS)
retval = -1;
- /* note: use "else if" instead of "if" or the debug message
- below shows a wrong retval */
else if (len < sizeof (Bootp_t) - OPT_SIZE)
retval = -2;
else if (bp->bp_op != OP_BOOTREQUEST &&
retval = -4;
else if (bp->bp_hlen != HWL_ETHER)
retval = -5;
- else
- {
- memcpy(&id, &bp->bp_id, sizeof(id));
- id = ntohl(id);
- if (id != BootpID)
- retval = -6;
+ else if (NetReadLong((ulong*)&bp->bp_id) != BootpID) {
+ retval = -6;
}
+
debug ("Filtering pkt = %d\n", retval);
return retval;
*/
void BootpCopyNetParams(Bootp_t *bp)
{
- NetOurIP = NetReadIP((vuchar*)&bp->bp_yiaddr);
- NetServerIP = NetReadIP((vuchar*)&bp->bp_siaddr);
+ NetCopyIP(&NetOurIP, &bp->bp_yiaddr);
+ NetCopyIP(&NetServerIP, &bp->bp_siaddr);
NetCopyEther(NetServerEther, ((Ethernet_t *)NetRxPkt)->et_src);
copy_filename (BootFile, bp->bp_file, sizeof(BootFile));
debug ("Bootfile: %s\n", BootFile);
- /* Propagate to environment */
- setenv (Net_bd, "bootfile", BootFile);
+ /* Propagate to environment
+ * don't delete exising entry when BOOTP / DHCP reply does
+ * not contain a new value
+ */
+ if (*BootFile) {
+ setenv (Net_bd, "bootfile", BootFile);
+ }
}
static int truncate_sz (const char *name, int maxlen, int curlen)
/* Fixed length fields */
case 1: /* Subnet mask */
if (NetOurSubnetMask == 0)
- NetOurSubnetMask = NetReadIP(ext+2);
+ NetCopyIP(&NetOurSubnetMask, (IPaddr_t*)(ext+2));
break;
case 2: /* Time offset - Not yet supported */
break;
/* Variable length fields */
case 3: /* Gateways list */
if (NetOurGatewayIP == 0) {
- NetOurGatewayIP = NetReadIP(ext+2);
+ NetCopyIP(&NetOurGatewayIP, (IPaddr_t*)(ext+2));
}
break;
case 4: /* Time server - Not yet supported */
break;
case 6:
if (NetOurDNSIP == 0) {
- NetOurDNSIP = NetReadIP(ext+2);
+ NetCopyIP(&NetOurDNSIP, (IPaddr_t*)(ext+2));
}
break;
case 7: /* Log server - Not yet supported */
}
break;
case 13: /* Boot file size */
- if(size == 2)
+ if (size == 2)
NetBootFileSize = ntohs(*(ushort*)(ext+2));
- else if(size == 4)
+ else if (size == 4)
NetBootFileSize = ntohl(*(ulong*)(ext+2));
break;
case 14: /* Merit dump file - Not yet supported */
printf("NetOurNISDomain : %s\n", NetOurNISDomain);
}
- if (NetBootFileSize) {
- printf("NetBootFileSize: %d\n", NetBootFileSize);
- }
#endif
}
{
Bootp_t *bp;
char *s;
- ulong vendmagic;
debug ("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%d)\n",
src, dest, len, sizeof (Bootp_t));
BootpCopyNetParams(bp); /* Store net parameters from reply */
- /* Retrieve extended informations (we must parse the vendor area) */
- memcpy(&vendmagic, bp->bp_vend, sizeof(vendmagic));
- if (ntohl(vendmagic) == BOOTP_VENDOR_MAGIC)
- BootpVendorProcess(&bp->bp_vend[4], len);
+ /* Retrieve extended information (we must parse the vendor area) */
+ if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
+ BootpVendorProcess(&bp->bp_vend[4], len);
NetSetTimeout(0, (thand_f *)0);
*e++ = (576-312+OPT_SIZE) & 0xff;
if ( ServerID ) {
+ int tmp = ntohl(ServerID);
+
*e++ = 54; /* ServerID */
*e++ = 4;
- *e++ = ServerID >> 24;
- *e++ = ServerID >> 16;
- *e++ = ServerID >> 8;
- *e++ = ServerID & 0xff;
+ *e++ = tmp >> 24;
+ *e++ = tmp >> 16;
+ *e++ = tmp >> 8;
+ *e++ = tmp & 0xff;
}
if ( RequestedIP ) {
+ int tmp = ntohl(RequestedIP);
+
*e++ = 50; /* Requested IP */
*e++ = 4;
- *e++ = RequestedIP >> 24;
- *e++ = RequestedIP >> 16;
- *e++ = RequestedIP >> 8;
- *e++ = RequestedIP & 0xff;
+ *e++ = tmp >> 24;
+ *e++ = tmp >> 16;
+ *e++ = tmp >> 8;
+ *e++ = tmp & 0xff;
}
*e++ = 55; /* Parameter Request List */
*e++ = 40; /* NIS Domain name request */
*cnt += 1;
#endif
-
*e++ = 255; /* End of the list */
return e - start ;
volatile uchar *pkt, *iphdr;
Bootp_t *bp;
int ext_len, pktlen, iplen;
- ulong id;
#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
dhcp_state = INIT;
* set in packet header after extension length has been determined.
* C. Hallinan, DS4.COM, Inc.
*/
- /* NetSetIP(pkt, 0xffffffffL, PORT_BOOTPS, PORT_BOOTPC, sizeof (Bootp_t)); */
+ /* NetSetIP(pkt, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, sizeof (Bootp_t)); */
iphdr = pkt; /* We need this later for NetSetIP() */
pkt += IP_HDR_SIZE;
bp->bp_htype = HWT_ETHER;
bp->bp_hlen = HWL_ETHER;
bp->bp_hops = 0;
- bp->bp_secs = htons( get_timer(0) / CFG_HZ);
- NetWriteIP((vuchar*)&bp->bp_ciaddr, 0);
- NetWriteIP((vuchar*)&bp->bp_yiaddr, 0);
- NetWriteIP((vuchar*)&bp->bp_siaddr, 0);
- NetWriteIP((vuchar*)&bp->bp_giaddr, 0);
+ bp->bp_secs = htons(get_timer(0) / CFG_HZ);
+ NetWriteIP(&bp->bp_ciaddr, 0);
+ NetWriteIP(&bp->bp_yiaddr, 0);
+ NetWriteIP(&bp->bp_siaddr, 0);
+ NetWriteIP(&bp->bp_giaddr, 0);
NetCopyEther(bp->bp_chaddr, NetOurEther);
copy_filename (bp->bp_file, BootFile, sizeof(bp->bp_file));
| ((ulong)NetOurEther[4] << 8)
| (ulong)NetOurEther[5];
BootpID += get_timer(0);
-
- id = htonl(BootpID);
- memcpy(&bp->bp_id, &id, sizeof(id));
+ BootpID = htonl(BootpID);
+ NetCopyLong(&bp->bp_id, &BootpID);
/*
* Calculate proper packet lengths taking into account the
*/
pktlen = BOOTP_SIZE - sizeof(bp->bp_vend) + ext_len;
iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + ext_len;
- NetSetIP(iphdr, 0xffffffffL, PORT_BOOTPS, PORT_BOOTPC, iplen);
+ NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
NetSetTimeout(SELECT_TIMEOUT * CFG_HZ, BootpTimeout);
#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
oplen = *(popt + 1);
switch(*popt) {
case 1:
- NetOurSubnetMask = *(IPaddr_t *)(popt + 2);
+ NetCopyIP(&NetOurSubnetMask, (popt+2));
break;
case 3:
- NetOurGatewayIP = *(IPaddr_t *)(popt + 2);
+ NetCopyIP(&NetOurGatewayIP, (popt+2));
break;
case 6:
- NetOurDNSIP = *(IPaddr_t *)(popt +2);
+ NetCopyIP(&NetOurDNSIP, (popt+2));
break;
case 12:
size = truncate_sz ("Host Name",
case 53: /* Ignore Message Type Option */
break;
case 54:
- NetServerIP = *(IPaddr_t *)(popt+2);
+ NetCopyIP(&NetServerIP, (popt+2));
break;
case 58: /* Ignore Renewal Time Option */
break;
static int DhcpMessageType(unsigned char *popt)
{
- ulong vendmagic;
- memcpy(&vendmagic, popt, sizeof(vendmagic));
- if (ntohl(vendmagic) != BOOTP_VENDOR_MAGIC)
+ if (NetReadLong((ulong*)popt) != htonl(BOOTP_VENDOR_MAGIC))
return -1;
popt += 4;
bp->bp_htype = HWT_ETHER;
bp->bp_hlen = HWL_ETHER;
bp->bp_hops = 0;
- bp->bp_secs = htons( get_timer(0) / CFG_HZ);
- NetCopyIP((vuchar*)&bp->bp_ciaddr, (vuchar*)&bp_offer->bp_ciaddr);
- NetCopyIP((vuchar*)&bp->bp_yiaddr, (vuchar*)&bp_offer->bp_yiaddr);
- NetCopyIP((vuchar*)&bp->bp_siaddr, (vuchar*)&bp_offer->bp_siaddr);
- NetCopyIP((vuchar*)&bp->bp_giaddr, (vuchar*)&bp_offer->bp_giaddr);
+ bp->bp_secs = htons(get_timer(0) / CFG_HZ);
+ NetCopyIP(&bp->bp_ciaddr, &bp_offer->bp_ciaddr); /* both in network byte order */
+ NetCopyIP(&bp->bp_yiaddr, &bp_offer->bp_yiaddr);
+ NetCopyIP(&bp->bp_siaddr, &bp_offer->bp_siaddr);
+ NetCopyIP(&bp->bp_giaddr, &bp_offer->bp_giaddr);
NetCopyEther(bp->bp_chaddr, NetOurEther);
/*
* ID is the id of the OFFER packet
*/
- memcpy(&bp->bp_id, &bp_offer->bp_id, sizeof(bp->bp_id));
+ NetCopyLong(&bp->bp_id, &bp_offer->bp_id);
/*
* Copy options from OFFER packet if present
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);
+ NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
debug ("Transmitting DHCPREQUEST packet: len = %d\n", pktlen);
NetSendPacket(NetTxPacket, pktlen);
static void
DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
{
- ulong vendmagic;
Bootp_t *bp = (Bootp_t *)pkt;
debug ("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n",
debug ("TRANSITIONING TO REQUESTING STATE\n");
dhcp_state = REQUESTING;
#if 0
- memcpy(&vendmagic, bp->bp_vend, sizeof(vendmagic));
- if (ntohl(vendmagic) == BOOTP_VENDOR_MAGIC)
+ if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
DhcpOptionsProcess(&bp->bp_vend[4]);
#endif
debug ("DHCP State: REQUESTING\n");
if ( DhcpMessageType(bp->bp_vend) == DHCP_ACK ) {
- memcpy(&vendmagic, bp->bp_vend, sizeof(vendmagic));
- if (ntohl(vendmagic) == BOOTP_VENDOR_MAGIC)
+
+ if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
DhcpOptionsProcess(&bp->bp_vend[4]);
BootpCopyNetParams(bp); /* Store net params from reply */
dhcp_state = BOUND;
*/
if (protocol == TFTP) { /* TFTP */
- NetOurIP = bis->bi_ip_addr;
+ NetCopyIP(&NetOurIP, (IPaddr_t*)&bis->bi_ip_addr);
NetServerIP = 0;
s = getenv (bis, "serverip");
for (reg=0; reg<4; ++reg) {
Ethernet_t *et;
IP_t *ip;
ARP_t *arp;
+ IPaddr_t tmp;
int x;
NetRxPkt = pkt;
}
- {
- IPaddr_t ip = NetReadIP((uchar*)&arp->ar_data[16]);
- if (ip != NetOurIP) {
+ if (NetReadIP((IPaddr_t*)&arp->ar_data[16]) != NetOurIP) {
#ifdef ET_DEBUG
- printf("Requested IP is not ours\n");
+ printf("Requested IP is not ours\n");
#endif
- return;
- }
+ return;
}
switch (ntohs(arp->ar_op)) {
#endif
NetSetEther((uchar *)et, et->et_src, PROT_ARP);
arp->ar_op = htons(ARPOP_REPLY);
- NetCopyEther(&arp->ar_data[0], NetOurEther);
- NetWriteIP( &arp->ar_data[6], NetOurIP);
- NetCopyEther(&arp->ar_data[10], NetOurEther);
- NetWriteIP( &arp->ar_data[16], NetOurIP);
+ NetCopyEther(&arp->ar_data[10], &arp->ar_data[0]);
+ NetCopyIP((IPaddr_t*)&arp->ar_data[16], (IPaddr_t*)&arp->ar_data[6]);
+ NetCopyEther(&arp->ar_data[ 0], NetOurEther);
+ NetCopyIP((IPaddr_t*)&arp->ar_data[ 6], &NetOurIP);
NetSendPacket((uchar *)et,((uchar *)arp-pkt)+ARP_HDR_SIZE);
return;
case ARPOP_REPLY: /* set TFTP server eth addr */
printf("Got ARP REPLY, set server/gtwy eth addr\n");
#endif
/* check if target ether is ours */
- if ( memcmp(NetOurEther, &(arp->ar_data[10]), 6) != 0 )
+ if ( NetCmpEther(NetOurEther, &(arp->ar_data[10])) != 0 )
{
#ifdef ET_DEBUG
printf(" Reply is not for us. Ignoring it...\n");
printf("invalid RARP header\n");
} else {
- NetOurIP = NetReadIP((uchar*)&arp->ar_data[16]);
- NetServerIP = NetReadIP((uchar*)&arp->ar_data[6]);
- NetCopyEther(NetServerEther, &arp->ar_data[0]);
+ NetCopyIP(&NetOurIP, (IPaddr_t*)&arp->ar_data[16]);
+ NetCopyIP(&NetServerIP, (IPaddr_t*)&arp->ar_data[ 6]);
+ NetCopyEther(NetServerEther, &arp->ar_data[ 0]);
(*packetHandler)(0,0,0,0);
}
printf("checksum bad\n");
return;
}
- if (NetOurIP) {
- IPaddr_t ipaddr = NetReadIP((uchar*)&ip->ip_dst);
- if (ipaddr != NetOurIP && ipaddr != 0xFFFFFFFF)
- {
+ tmp = NetReadIP((IPaddr_t*)&ip->ip_dst);
+ if (NetOurIP && tmp != NetOurIP && tmp != 0xFFFFFFFF) {
#ifdef ET_DEBUG
printf("ip packet not for us\n");
- print_IPaddr(ipaddr);
+ print_IPaddr(tmp);
#endif
return;
- }
}
/*
* watch for ICMP host redirects
case DHCP:
case RARP:
case BOOTP:
- if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) {
+ if (NetCmpEther(NetOurEther, "\0\0\0\0\0\0") == 0) {
puts ("*** ERROR: `ethaddr' not set\n");
return (1);
}
}
-void
-NetCopyEther(volatile uchar * to, uchar * from)
-{
- int i;
-
- for (i = 0; i < 6; i++)
- *to++ = *from++;
-}
-
-void
-NetWriteIP(volatile uchar * to, IPaddr_t ip)
-{
- int i;
-
- for (i = 0; i < 4; i++)
- {
- *to++ = ip >> 24;
- ip <<= 8;
- }
-}
-
-IPaddr_t
-NetReadIP(volatile uchar * from)
-{
- IPaddr_t ip;
- int i;
-
- ip = 0;
- for (i = 0; i < 4; i++)
- ip = (ip << 8) | *from++;
-
- return ip;
-}
-
-void
-NetCopyIP(volatile uchar * to, volatile uchar *from)
-{
- int i;
- for (i = 0; i < 4; i++)
- *to++ = *from++;
-}
-
void
NetSetEther(volatile uchar * xet, uchar * addr, uint prot)
{
ip->ip_ttl = 255;
ip->ip_p = 17; /* UDP */
ip->ip_sum = 0;
- NetWriteIP((uchar*)&ip->ip_src, NetOurIP);
- NetWriteIP((uchar*)&ip->ip_dst, dest);
+ NetCopyIP(&ip->ip_src, &NetOurIP); /* already in network byte order */
+ NetCopyIP(&ip->ip_dst, &dest); /* - "" - */
ip->udp_src = htons(sport);
ip->udp_dst = htons(dport);
ip->udp_len = htons(8 + len);
void ip_to_string (IPaddr_t x, char *s)
{
+ x = ntohl(x);
sprintf (s,"%d.%d.%d.%d",
(int)((x >> 24) & 0xff),
(int)((x >> 16) & 0xff),