Integrating with DM320

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@368 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2007-11-04 22:59:30 +00:00
parent 643c8d6401
commit 5fe0d01775
13 changed files with 267 additions and 123 deletions

View file

@ -293,6 +293,13 @@ CONFIG_NET_BROADCAST=n
CONFIG_NET_DHCP_LIGHT=n
CONFIG_NET_RESOLV_ENTRIES=4
#
# Settings for examples/nettest
CONFIG_EXAMPLE_NETTEST_IPADDR=(10<<24|0<<16|0<<8|2)
CONFIG_EXAMPLE_NETTEST_DRIPADDR=(10<<24|0<<16|0<<8|1)
CONFIG_EXAMPLE_NETTEST_NETMASK=(255<<24|255<<16|255<<8|0)
CONFIG_EXAMPLE_NETTEST_CLIENTIP=(10<<24|0<<16|0<<8|1)
#
# DM90x0 Driver Settings
CONFIG_NET_DM90x0=n

View file

@ -257,6 +257,9 @@ CONFIG_NET_RESOLV_ENTRIES=4
#
# Settings for examples/uip
CONFIG_EXAMPLE_UIP_IPADDR=(192<<24|168<<16|0<<8|128)
CONFIG_EXAMPLE_UIP_DRIPADDR=(192<<24|168<<16|0<<8|1)
CONFIG_EXAMPLE_UIP_NETMASK=(255<<24|255<<16|255<<8|0)
#CONFIG_EXAMPLE_UIP_SMTP=
#CONFIG_EXAMPLE_UIP_TELNETD=
#CONFIG_EXAMPLE_UIP_WEBSERVER=
@ -264,6 +267,13 @@ CONFIG_EXAMPLE_UIP_DHCPC=y
#CONFIG_EXAMPLE_UIP_RESOLV=
#CONFIG_EXAMPLE_UIP_WEBCLIENT=
#
# Settings for examples/nettest
CONFIG_EXAMPLE_NETTEST_IPADDR=(192<<24|168<<16|0<<8|128)
CONFIG_EXAMPLE_NETTEST_DRIPADDR=(192<<24|168<<16|0<<8|1)
CONFIG_EXAMPLE_NETTEST_NETMASK=(255<<24|255<<16|255<<8|0)
CONFIG_EXAMPLE_NETTEST_CLIENTIP=(192<<24|168<<16|0<<8|106)
#
# Stack and heap information
#

View file

@ -258,6 +258,9 @@ CONFIG_NET_RESOLV_ENTRIES=4
#
# Settings for examples/uip
CONFIG_EXAMPLE_UIP_IPADDR=(192<<24|168<<16|0<<8|128)
CONFIG_EXAMPLE_UIP_DRIPADDR=(192<<24|168<<16|0<<8|1)
CONFIG_EXAMPLE_UIP_NETMASK=(255<<24|255<<16|255<<8|0)
#CONFIG_EXAMPLE_UIP_SMTP=
#CONFIG_EXAMPLE_UIP_TELNETD=
#CONFIG_EXAMPLE_UIP_WEBSERVER=
@ -265,6 +268,13 @@ CONFIG_EXAMPLE_UIP_DHCPC=y
#CONFIG_EXAMPLE_UIP_RESOLV=
#CONFIG_EXAMPLE_UIP_WEBCLIENT=
#
# Settings for examples/nettest
CONFIG_EXAMPLE_NETTEST_IPADDR=(192<<24|168<<16|0<<8|128)
CONFIG_EXAMPLE_NETTEST_DRIPADDR=(192<<24|168<<16|0<<8|1)
CONFIG_EXAMPLE_NETTEST_NETMASK=(255<<24|255<<16|255<<8|0)
CONFIG_EXAMPLE_NETTEST_CLIENTIP=(192<<24|168<<16|0<<8|106)
# Stack and heap information
#
# CONFIG_BOOT_FROM_FLASH - Some configurations support XIP

View file

@ -457,6 +457,7 @@ static void putreg(int reg, uint8 value)
static void read8(uint8 *ptr, int len)
{
vdbg("Read %d bytes (8-bit mode)\n", len);
for (; len > 0; len--)
{
*ptr++ = DM9X_DATA;
@ -466,6 +467,7 @@ static void read8(uint8 *ptr, int len)
static void read16(uint8 *ptr, int len)
{
register uint16 *ptr16 = (uint16*)ptr;
vdbg("Read %d bytes (16-bit mode)\n", len);
for (; len > 0; len -= sizeof(uint16))
{
*ptr16++ = DM9X_DATA;
@ -475,6 +477,7 @@ static void read16(uint8 *ptr, int len)
static void read32(uint8 *ptr, int len)
{
register uint32 *ptr32 = (uint32*)ptr;
vdbg("Read %d bytes (32-bit mode)\n", len);
for (; len > 0; len -= sizeof(uint32))
{
*ptr32++ = DM9X_DATA;
@ -500,6 +503,7 @@ static void read32(uint8 *ptr, int len)
static void discard8(int len)
{
vdbg("Discard %d bytes (8-bit mode)\n", len);
for (; len > 0; len--)
{
DM9X_DATA;
@ -508,6 +512,7 @@ static void discard8(int len)
static void discard16(int len)
{
vdbg("Discard %d bytes (16-bit mode)\n", len);
for (; len > 0; len -= sizeof(uint16))
{
DM9X_DATA;
@ -516,6 +521,7 @@ static void discard16(int len)
static void discard32(int len)
{
vdbg("Discard %d bytes (32-bit mode)\n", len);
for (; len > 0; len -= sizeof(uint32))
{
DM9X_DATA;
@ -541,15 +547,18 @@ static void discard32(int len)
static void write8(const uint8 *ptr, int len)
{
vdbg("Write %d bytes (8-bit mode)\n", len);
for (; len > 0; len--)
{
DM9X_DATA =(*ptr++ & 0xff);
DM9X_DATA = (*ptr++ & 0xff);
}
}
static void write16(const uint8 *ptr, int len)
{
register uint16 *ptr16 = (uint16*)ptr;
vdbg("Write %d bytes (16-bit mode)\n", len);
for (; len > 0; len -= sizeof(uint16))
{
DM9X_DATA = *ptr16++;
@ -559,6 +568,7 @@ static void write16(const uint8 *ptr, int len)
static void write32(const uint8 *ptr, int len)
{
register uint32 *ptr32 = (uint32*)ptr;
vdbg("Write %d bytes (32-bit mode)\n", len);
for (; len > 0; len -= sizeof(uint32))
{
DM9X_DATA = *ptr32++;
@ -991,9 +1001,9 @@ static void dm9x_receive(struct dm9x_driver_s *dm9x)
/* We only accept IP packets of the configured type and ARP packets */
#ifdef CONFIG_NET_IPv6
if (BUF->type == htons(UIP_ETHTYPE_IP6))
if (BUF->type == HTONS(UIP_ETHTYPE_IP6))
#else
if (BUF->type == htons(UIP_ETHTYPE_IP))
if (BUF->type == HTONS(UIP_ETHTYPE_IP))
#endif
{
uip_arp_ipin();
@ -1684,7 +1694,7 @@ int dm9x_initialize(void)
mptr[i] = getreg(j);
}
lldbg("MAC: %0x:%0x:%0x:%0x:%0x:%0x",
lldbg("MAC: %0x:%0x:%0x:%0x:%0x:%0x\n",
mptr[0], mptr[1], mptr[2], mptr[3], mptr[4], mptr[5]);
/* Register the device with the OS so that socket IOCTLs can be performed */

View file

@ -84,7 +84,7 @@ void send_client(void)
#if 0
myaddr.sin_addr.s_addr = HTONL(INADDR_LOOPBACK);
#else
myaddr.sin_addr.s_addr = HTONL(192 << 24 | 168 << 16 | 0 << 8 |106);
myaddr.sin_addr.s_addr = HTONL(CONFIG_EXAMPLE_NETTEST_CLIENTIP);
#endif
printf("client: Connecting...\n");

View file

@ -39,6 +39,7 @@
#include <nuttx/config.h>
#include <stdio.h>
#include <debug.h>
#include <net/uip/uip.h>
#include <net/uip/uip-lib.h>
@ -80,17 +81,17 @@ int user_start(int argc, char *argv[])
/* Set up our host address */
uip_ipaddr(addr.s_addr, 192, 168, 0, 128 );
addr.s_addr = HTONL(CONFIG_EXAMPLE_NETTEST_IPADDR);
uip_sethostaddr("eth0", &addr);
/* Set up the default router address */
uip_ipaddr(addr.s_addr, 192, 168, 0, 1);
addr.s_addr = HTONL(CONFIG_EXAMPLE_NETTEST_DRIPADDR);
uip_setdraddr("eth0", &addr);
/* Setup the subnet mask */
uip_ipaddr(addr.s_addr, 255, 255, 255, 0);
addr.s_addr = HTONL(CONFIG_EXAMPLE_NETTEST_NETMASK);
uip_setnetmask("eth0", &addr);
#ifdef CONFIG_NETTEST_SERVER

View file

@ -49,6 +49,7 @@
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <debug.h>
#include <net/uip/uip.h>
#include <net/uip/uip-arp.h>
@ -140,17 +141,17 @@ int user_start(int argc, char *argv[])
#if !defined(CONFIG_EXAMPLE_UIP_DHCPC)
/* Set up our host address */
uip_ipaddr(addr.s_addr, 192, 168, 0, 128 );
addr.s_addr = HTONL(CONFIG_EXAMPLE_UIP_IPADDR);
uip_sethostaddr("eth0", &addr);
/* Set up the default router address */
uip_ipaddr(addr.s_addr, 192, 168, 0, 1);
addr.s_addr = HTONL(CONFIG_EXAMPLE_UIP_DRIPADDR);
uip_setdraddr("eth0", &addr);
/* Setup the subnet mask */
uip_ipaddr(addr.s_addr, 255, 255, 255, 0);
addr.s_addr = HTONL(CONFIG_EXAMPLE_UIP_NETMASK);
uip_setnetmask("eth0", &addr);
#endif

View file

@ -35,17 +35,24 @@
#define __UIP_ARP_H__
#include <sys/types.h>
#include <nuttx/compiler.h>
#include <net/uip/uip.h>
/* The Ethernet header */
/* The Ethernet header -- 14 bytes. The first two fields are type 'struct
* uip_eth_addr but are represented as a simple byte array here because
* some compilers refuse to pack 6 byte structures.
*/
struct uip_eth_hdr
{
struct uip_eth_addr dest;
struct uip_eth_addr src;
uint16 type;
uint8 dest[6]; /* Ethernet destination address (6 bytes) */
uint8 src[6]; /* Ethernet source address (6 bytes) */
uint16 type; /* Type code (2 bytes) */
};
/* Recognized values of the type bytes in the Ethernet header */
#define UIP_ETHTYPE_ARP 0x0806
#define UIP_ETHTYPE_IP 0x0800
#define UIP_ETHTYPE_IP6 0x86dd

View file

@ -280,7 +280,7 @@ struct uip_tcpip_hdr
{
#ifdef CONFIG_NET_IPv6
/* IPv6 header. */
/* IPv6 Ip header. */
uint8 vtc;
uint8 tcflow;
@ -292,18 +292,18 @@ struct uip_tcpip_hdr
#else /* CONFIG_NET_IPv6 */
/* IPv4 header. */
/* IPv4 IP header. */
uint8 vhl;
uint8 tos;
uint8 len[2];
uint8 ipid[2];
uint8 ipoffset[2];
uint8 ttl;
uint8 proto;
uint16 ipchksum;
uint16 srcipaddr[2];
uint16 destipaddr[2];
uint8 vhl; /* 8-bit Version (4) and header length (5 or 6) */
uint8 tos; /* 8-bit Type of service (e.g., 6=TCP) */
uint8 len[2]; /* 16-bit Total length */
uint8 ipid[2]; /* 16-bit Identification */
uint8 ipoffset[2]; /* 16-bit IP flags + fragment offset */
uint8 ttl; /* 8-bit Time to Live */
uint8 proto; /* 8-bit Protocol */
uint16 ipchksum; /* 16-bit Header checksum */
uint16 srcipaddr[2]; /* 32-bit Source IP address */
uint16 destipaddr[2]; /* 32-bit Destination IP address */
#endif /* CONFIG_NET_IPv6 */
@ -327,7 +327,7 @@ struct uip_icmpip_hdr
{
#ifdef CONFIG_NET_IPv6
/* IPv6 header. */
/* IPv6 IP header. */
uint8 vtc;
uint8 tcf;
@ -340,18 +340,18 @@ struct uip_icmpip_hdr
#else /* CONFIG_NET_IPv6 */
/* IPv4 header. */
/* IPv4 IP header. */
uint8 vhl;
uint8 tos;
uint8 len[2];
uint8 ipid[2];
uint8 ipoffset[2];
uint8 ttl;
uint8 proto;
uint16 ipchksum;
uint16 srcipaddr[2];
uint16 destipaddr[2];
uint8 vhl; /* 8-bit Version (4) and header length (5 or 6) */
uint8 tos; /* 8-bit Type of service (e.g., 6=TCP) */
uint8 len[2]; /* 16-bit Total length */
uint8 ipid[2]; /* 16-bit Identification */
uint8 ipoffset[2]; /* 16-bit IP flags + fragment offset */
uint8 ttl; /* 8-bit Time to Live */
uint8 proto; /* 8-bit Protocol */
uint16 ipchksum; /* 16-bit Header checksum */
uint16 srcipaddr[2]; /* 32-bit Source IP address */
uint16 destipaddr[2]; /* 32-bit Destination IP address */
#endif /* CONFIG_NET_IPv6 */
@ -384,13 +384,14 @@ struct uip_udpip_hdr
{
#ifdef CONFIG_NET_IPv6
/* IPv6 header. */
/* IPv6 IP header. */
uint8 vtc;
uint8 vtc;
uint8 tcf;
uint16 flow;
uint8 len[2];
uint8 proto, ttl;
uint8 len[2];
uint8 proto;
uint8 ttl;
uip_ip6addr_t srcipaddr;
uip_ip6addr_t destipaddr;
@ -398,16 +399,16 @@ struct uip_udpip_hdr
/* IPv4 header. */
uint8 vhl;
uint8 tos;
uint8 len[2];
uint8 ipid[2];
uint8 ipoffset[2];
uint8 ttl;
uint8 proto;
uint16 ipchksum;
uint16 srcipaddr[2];
uint16 destipaddr[2];
uint8 vhl; /* 8-bit Version (4) and header length (5 or 6) */
uint8 tos; /* 8-bit Type of service (e.g., 6=TCP) */
uint8 len[2]; /* 16-bit Total length */
uint8 ipid[2]; /* 16-bit Identification */
uint8 ipoffset[2]; /* 16-bit IP flags + fragment offset */
uint8 ttl; /* 8-bit Time to Live */
uint8 proto; /* 8-bit Protocol */
uint16 ipchksum; /* 16-bit Header checksum */
uint16 srcipaddr[2]; /* 32-bit Source IP address */
uint16 destipaddr[2]; /* 32-bit Destination IP address */
#endif /* CONFIG_NET_IPv6 */

View file

@ -72,6 +72,12 @@
# define noreturn_function __attribute__ ((noreturn))
/* The packed attribute informs GCC that the stucture elements
* are packed, ignoring other alignment rules.
*/
# define packed_struct __attribute__ ((packed))
/* GCC does not support the reentrant attribute */
# define reentrant_function
@ -123,9 +129,10 @@
# define weak_function
# define weak_const_function
/* SDCC does not support the noreturn attribute */
/* SDCC does not support the noreturn or packed attributes */
# define noreturn_function
# define packed_struct
/* The reentrant attribute informs SDCC that the function
* must be reentrant. In this case, SDCC will store input
@ -192,6 +199,7 @@
# define weak_function
# define weak_const_function
# define noreturn_function
# define packed_struct
# define reentrant_function
# define FAR

View file

@ -43,8 +43,11 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/net.h>
#include <net/uip/uip-arch.h>
@ -187,54 +190,95 @@ int netdev_ioctl(int sockfd, int cmd, struct ifreq *req)
{
case SIOCGIFADDR: /* Get IP address */
ioctl_getipaddr(&req->ifr_addr, &dev->d_ipaddr);
dbg("Dev: %s IP: %d.%d.%d.%d\n",
dev->d_ifname,
(dev->d_ipaddr >> 24) & 0xff, (dev->d_ipaddr >> 16) & 0xff,
(dev->d_ipaddr >> 8) & 0xff, dev->d_ipaddr & 0xff);
break;
case SIOCSIFADDR: /* Set IP address */
ioctl_ifdown(dev);
ioctl_setipaddr(&dev->d_ipaddr, &req->ifr_addr);
dbg("Dev: %s IP: %d.%d.%d.%d\n",
dev->d_ifname,
(dev->d_ipaddr >> 24) & 0xff, (dev->d_ipaddr >> 16) & 0xff,
(dev->d_ipaddr >> 8) & 0xff, dev->d_ipaddr & 0xff);
ioctl_ifup(dev);
break;
case SIOCGIFDSTADDR: /* Get P-to-P address */
ioctl_getipaddr(&req->ifr_dstaddr, &dev->d_draddr);
dbg("Dev: %s Default router: %d.%d.%d.%d\n",
dev->d_ifname,
(dev->d_draddr >> 24) & 0xff, (dev->d_draddr >> 16) & 0xff,
(dev->d_draddr >> 8) & 0xff, dev->d_draddr & 0xff);
break;
case SIOCSIFDSTADDR: /* Set P-to-P address */
ioctl_setipaddr(&dev->d_draddr, &req->ifr_dstaddr);
dbg("Dev: %s Default router: %d.%d.%d.%d\n",
dev->d_ifname,
(dev->d_draddr >> 24) & 0xff, (dev->d_draddr >> 16) & 0xff,
(dev->d_draddr >> 8) & 0xff, dev->d_draddr & 0xff);
break;
case SIOCGIFNETMASK: /* Get network mask */
ioctl_getipaddr(&req->ifr_addr, &dev->d_netmask);
dbg("Dev: %s Netmask: %d.%d.%d.%d\n",
dev->d_ifname,
(dev->d_netmask >> 24) & 0xff, (dev->d_netmask >> 16) & 0xff,
(dev->d_netmask >> 8) & 0xff, dev->d_netmask & 0xff);
break;
case SIOCSIFNETMASK: /* Set network mask */
ioctl_setipaddr(&dev->d_netmask, &req->ifr_addr);
dbg("Dev: %s Netmask: %d.%d.%d.%d\n",
dev->d_ifname,
(dev->d_netmask >> 24) & 0xff, (dev->d_netmask >> 16) & 0xff,
(dev->d_netmask >> 8) & 0xff, dev->d_netmask & 0xff);
break;
case SIOCGIFMTU: /* Get MTU size */
req->ifr_mtu = UIP_BUFSIZE;
dbg("Dev: %s MTU: %d\n", dev->d_ifname, UIP_BUFSIZE);
break;
case SIOCGIFHWADDR: /* Get hardware address */
req->ifr_hwaddr.sa_family = AF_INETX;
memcpy(req->ifr_hwaddr.sa_data, dev->d_mac.addr, IFHWADDRLEN);
dbg("Dev: %s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
dev->d_ifname,
dev->d_mac.addr[0], dev->d_mac.addr[1], dev->d_mac.addr[2],
dev->d_mac.addr[3], dev->d_mac.addr[4], dev->d_mac.addr[5]);
break;
case SIOCSIFHWADDR: /* Set hardware address */
req->ifr_hwaddr.sa_family = AF_INETX;
memcpy(dev->d_mac.addr, req->ifr_hwaddr.sa_data, IFHWADDRLEN);
dbg("Dev: %s MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
dev->d_ifname,
dev->d_mac.addr[0], dev->d_mac.addr[1], dev->d_mac.addr[2],
dev->d_mac.addr[3], dev->d_mac.addr[4], dev->d_mac.addr[5]);
break;
case SIOCDIFADDR: /* Delete IP address */
ioctl_ifdown(dev);
memset(&dev->d_ipaddr, 0, sizeof(uip_ipaddr_t));
dbg("Dev: %s IP: %d.%d.%d.%d\n",
dev->d_ifname,
(dev->d_ipaddr >> 24) & 0xff, (dev->d_ipaddr >> 16) & 0xff,
(dev->d_ipaddr >> 8) & 0xff, dev->d_ipaddr & 0xff);
break;
case SIOCGIFCOUNT: /* Get number of devices */
req->ifr_count = netdev_count();
break;
dbg("Dev: %s I/F count: %d\n", netdev_count());
err = ENOSYS;
break;
case SIOCGIFBRDADDR: /* Get broadcast IP address */
case SIOCSIFBRDADDR: /* Set broadcast IP address */
dbg("Dev: %s Broadcast: 255.255.255.255d\n", dev->d_ifname);
err = ENOSYS;
goto errout;

View file

@ -47,6 +47,7 @@
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <net/uip/uip-arch.h>
@ -139,9 +140,15 @@ int netdev_register(FAR struct uip_driver_s *dev)
dev->flink = g_netdevices;
g_netdevices = dev;
netdev_semgive();
lldbg("Registered MAC: %02x:%02x:%02x:%02x:%02x:%02x as dev: %s\n",
dev->d_mac.addr[0], dev->d_mac.addr[1], dev->d_mac.addr[2],
dev->d_mac.addr[3], dev->d_mac.addr[4], dev->d_mac.addr[5],
dev->d_ifname);
return OK;
}
return ERROR;
return -EINVAL;
}
#endif /* CONFIG_NET && CONFIG_NSOCKET_DESCRIPTORS */

View file

@ -54,7 +54,10 @@
#include <sys/types.h>
#include <sys/ioctl.h>
#include <string.h>
#include <debug.h>
#include <netinet/in.h>
#include <net/uip/uip-arch.h>
#include <net/uip/uip-arp.h>
@ -68,43 +71,44 @@
#define ARP_HWTYPE_ETH 1
#define BUF ((struct arp_hdr *)&dev->d_buf[0])
#define IPBUF ((struct ethip_hdr *)&dev->d_buf[0])
#define ETHBUF ((struct uip_eth_hdr *)&dev->d_buf[0])
#define ARPBUF ((struct arp_hdr *)&dev->d_buf[UIP_LLH_LEN])
#define IPBUF ((struct ethip_hdr *)&dev->d_buf[UIP_LLH_LEN])
/****************************************************************************
* Private Types
****************************************************************************/
/* ARP header -- Size 28 bytes */
struct arp_hdr
{
struct uip_eth_hdr ah_ethhdr;
uint16 ah_hwtype;
uint16 ah_protocol;
uint8 ah_hwlen;
uint8 ah_protolen;
uint16 ah_opcode;
struct uip_eth_addr ah_shwaddr;
uint16 ah_sipaddr[2];
struct uip_eth_addr ah_dhwaddr;
uint16 ah_dipaddr[2];
uint16 ah_hwtype; /* 16-bit Hardware type (Ethernet=0x001) */
uint16 ah_protocol; /* 16-bit Protocoal type (IP=0x0800 */
uint8 ah_hwlen; /* 8-bit Hardware address size (6) */
uint8 ah_protolen; /* 8-bit Procotol address size (4) */
uint16 ah_opcode; /* 16-bit Operation */
uint8 ah_shwaddr[6]; /* 48-bit Sender hardware address */
uint16 ah_sipaddr[2]; /* 32-bit Sender IP adress */
uint8 ah_dhwaddr[6]; /* 48-bit Target hardware address */
uint16 ah_dipaddr[2]; /* 32-bit Target IP address */
};
/* IP header -- Size 20 or 24 bytes */
struct ethip_hdr
{
struct uip_eth_hdr eh_ethhdr;
/* IP header. */
uint8 eh_vhl;
uint8 eh_tos;
uint8 eh_len[2];
uint8 eh_ipid[2];
uint8 eh_ipoffset[2];
uint8 eh_ttl;
uint8 eh_proto;
uint16 eh_ipchksum;
uint16 eh_srcipaddr[2];
uint16 eh_destipaddr[2];
uint8 eh_vhl; /* 8-bit Version (4) and header length (5 or 6) */
uint8 eh_tos; /* 8-bit Type of service (e.g., 6=TCP) */
uint8 eh_len[2]; /* 16-bit Total length */
uint8 eh_ipid[2]; /* 16-bit Identification */
uint8 eh_ipoffset[2]; /* 16-bit IP flags + fragment offset */
uint8 eh_ttl; /* 8-bit Time to Live */
uint8 eh_proto; /* 8-bit Protocol */
uint16 eh_ipchksum; /* 16-bit Header checksum */
uint16 eh_srcipaddr[2]; /* 32-bit Source IP address */
uint16 eh_destipaddr[2]; /* 32-bit Destination IP address */
uint16 eh_ipoption[2]; /* (optional) */
};
struct arp_entry
@ -130,7 +134,29 @@ static uint8 g_arptime;
* Private Functions
****************************************************************************/
static void uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
#ifdef CONFIG_DEBUG_VERBOSE
static void uip_arp_dump(struct arp_hdr *arp)
{
vdbg(" HW type: %04x Protocol: %04x\n",
arp->ah_hwtype, arp->ah_protocol);\
vdbg(" HW len: %02x Proto len: %02x Operation: %04x\n",
arp->ah_hwlen, arp->ah_protolen, arp->ah_opcode);
vdbg(" Sender MAC: %02x:%02x:%02x:%02x:%02x:%02x IP: %d.%d.%d.%d\n",
arp->ah_shwaddr[0], arp->ah_shwaddr[1], arp->ah_shwaddr[2],
arp->ah_shwaddr[3], arp->ah_shwaddr[4], arp->ah_shwaddr[5],
arp->ah_sipaddr[0] >> 8, arp->ah_sipaddr[0] & 0xff,
arp->ah_sipaddr[1] >> 8, arp->ah_sipaddr[1] & 0xff);
vdbg(" Dest MAC: %02x:%02x:%02x:%02x:%02x:%02x IP: %d.%d.%d.%d\n",
arp->ah_dhwaddr[0], arp->ah_dhwaddr[1], arp->ah_dhwaddr[2],
arp->ah_dhwaddr[3], arp->ah_dhwaddr[4], arp->ah_dhwaddr[5],
arp->ah_dipaddr[0] >> 8, arp->ah_dipaddr[0] & 0xff,
arp->ah_dipaddr[1] >> 8, arp->ah_dipaddr[1] & 0xff);
}
#else
# define uip_arp_dump(arp)
#endif
static void uip_arp_update(uint16 *pipaddr, uint8 *ethaddr)
{
struct arp_entry *tabptr;
in_addr_t ipaddr = uip_ip4addr_conv(pipaddr);
@ -156,7 +182,7 @@ static void uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
if (uip_ipaddr_cmp(ipaddr, tabptr->at_ipaddr))
{
/* An old entry found, update this and return. */
memcpy(tabptr->at_ethaddr.addr, ethaddr->addr, IFHWADDRLEN);
memcpy(tabptr->at_ethaddr.addr, ethaddr, IFHWADDRLEN);
tabptr->at_time = g_arptime;
return;
@ -204,7 +230,7 @@ static void uip_arp_update(uint16 *pipaddr, struct uip_eth_addr *ethaddr)
*/
tabptr->at_ipaddr = ipaddr;
memcpy(tabptr->at_ethaddr.addr, ethaddr->addr, IFHWADDRLEN);
memcpy(tabptr->at_ethaddr.addr, ethaddr, IFHWADDRLEN);
tabptr->at_time = g_arptime;
}
@ -270,7 +296,7 @@ void uip_arp_ipin(void)
return;
}
uip_arp_update(IPBUF->eh_srcipaddr, &(IPBUF->eh_ethhdr.src));
uip_arp_update(IPBUF->eh_srcipaddr, ETHBUF->eh_ethhdr.src);
}
#endif /* 0 */
@ -305,8 +331,8 @@ void uip_arp_arpin(struct uip_driver_s *dev)
}
dev->d_len = 0;
ipaddr = uip_ip4addr_conv(BUF->ah_dipaddr);
switch(BUF->ah_opcode)
ipaddr = uip_ip4addr_conv(ARPBUF->ah_dipaddr);
switch(ARPBUF->ah_opcode)
{
case HTONS(ARP_REQUEST):
/* ARP request. If it asked for our address, we send out a reply. */
@ -318,23 +344,23 @@ void uip_arp_arpin(struct uip_driver_s *dev)
* with this host in the future.
*/
uip_arp_update(BUF->ah_sipaddr, &BUF->ah_shwaddr);
uip_arp_update(ARPBUF->ah_sipaddr, ARPBUF->ah_shwaddr);
/* The reply opcode is 2. */
BUF->ah_opcode = HTONS(2);
ARPBUF->ah_opcode = HTONS(2);
memcpy(BUF->ah_dhwaddr.addr, BUF->ah_shwaddr.addr, IFHWADDRLEN);
memcpy(BUF->ah_shwaddr.addr, dev->d_mac.addr, IFHWADDRLEN);
memcpy(BUF->ah_ethhdr.src.addr, dev->d_mac.addr, IFHWADDRLEN);
memcpy(BUF->ah_ethhdr.dest.addr, BUF->ah_dhwaddr.addr, IFHWADDRLEN);
memcpy(ARPBUF->ah_dhwaddr, ARPBUF->ah_shwaddr, IFHWADDRLEN);
memcpy(ARPBUF->ah_shwaddr, dev->d_mac.addr, IFHWADDRLEN);
memcpy(ETHBUF->src, dev->d_mac.addr, IFHWADDRLEN);
memcpy(ETHBUF->dest, ARPBUF->ah_dhwaddr, IFHWADDRLEN);
BUF->ah_dipaddr[0] = BUF->ah_sipaddr[0];
BUF->ah_dipaddr[1] = BUF->ah_sipaddr[1];
BUF->ah_sipaddr[0] = dev->d_ipaddr >> 16;
BUF->ah_sipaddr[1] = dev->d_ipaddr & 0xffff;
ARPBUF->ah_dipaddr[0] = ARPBUF->ah_sipaddr[0];
ARPBUF->ah_dipaddr[1] = ARPBUF->ah_sipaddr[1];
ARPBUF->ah_sipaddr[0] = dev->d_ipaddr >> 16;
ARPBUF->ah_sipaddr[1] = dev->d_ipaddr & 0xffff;
BUF->ah_ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
ETHBUF->type = HTONS(UIP_ETHTYPE_ARP);
dev->d_len = sizeof(struct arp_hdr);
}
break;
@ -346,7 +372,7 @@ void uip_arp_arpin(struct uip_driver_s *dev)
if (uip_ipaddr_cmp(ipaddr, dev->d_ipaddr))
{
uip_arp_update(BUF->ah_sipaddr, &BUF->ah_shwaddr);
uip_arp_update(ARPBUF->ah_sipaddr, ARPBUF->ah_shwaddr);
}
break;
}
@ -385,17 +411,18 @@ void uip_arp_out(struct uip_driver_s *dev)
int i;
/* Find the destination IP address in the ARP table and construct
the Ethernet header. If the destination IP addres isn't on the
local network, we use the default router's IP address instead.
If not ARP table entry is found, we overwrite the original IP
packet with an ARP request for the IP address. */
* the Ethernet header. If the destination IP addres isn't on the
* local network, we use the default router's IP address instead.
*
* If not ARP table entry is found, we overwrite the original IP
* packet with an ARP request for the IP address.
*/
/* First check if destination is a local broadcast. */
if (uiphdr_ipaddr_cmp(IPBUF->eh_destipaddr, broadcast_ipaddr))
{
memcpy(IPBUF->eh_ethhdr.dest.addr, broadcast_ethaddr.addr, IFHWADDRLEN);
memcpy(ETHBUF->dest, broadcast_ethaddr.addr, IFHWADDRLEN);
}
else
{
@ -418,11 +445,20 @@ void uip_arp_out(struct uip_driver_s *dev)
uip_ipaddr_copy(ipaddr, destipaddr);
}
vdbg("Dest IP addr: %d.%d.%d.%d -> ARP IP addr: %d.%d.%d.%d\n",
(destipaddr >> 24) & 0xff, (destipaddr >> 16) & 0xff,
(destipaddr >> 8) & 0xff, destipaddr & 0xff,
(ipaddr >> 24) & 0xff, (ipaddr >> 16) & 0xff,
(ipaddr >> 8) & 0xff, ipaddr & 0xff);
/* Check if we already have this destination address in the ARP table */
for (i = 0; i < UIP_ARPTAB_SIZE; ++i)
{
tabptr = &arp_table[i];
if (uip_ipaddr_cmp(ipaddr, tabptr->at_ipaddr))
{
vdbg("Dest IP found in ARP table\n");
break;
}
}
@ -433,33 +469,35 @@ void uip_arp_out(struct uip_driver_s *dev)
* overwrite the IP packet with an ARP request.
*/
memset(BUF->ah_ethhdr.dest.addr, 0xff, IFHWADDRLEN);
memset(BUF->ah_dhwaddr.addr, 0x00, IFHWADDRLEN);
memcpy(BUF->ah_ethhdr.src.addr, dev->d_mac.addr, IFHWADDRLEN);
memcpy(BUF->ah_shwaddr.addr, dev->d_mac.addr, IFHWADDRLEN);
memset(ETHBUF->dest, 0xff, IFHWADDRLEN);
memset(ARPBUF->ah_dhwaddr, 0x00, IFHWADDRLEN);
memcpy(ETHBUF->src, dev->d_mac.addr, IFHWADDRLEN);
memcpy(ARPBUF->ah_shwaddr, dev->d_mac.addr, IFHWADDRLEN);
uiphdr_ipaddr_copy(BUF->ah_dipaddr, &ipaddr);
uiphdr_ipaddr_copy(BUF->ah_sipaddr, &dev->d_ipaddr);
BUF->ah_opcode = HTONS(ARP_REQUEST); /* ARP request. */
BUF->ah_hwtype = HTONS(ARP_HWTYPE_ETH);
BUF->ah_protocol = HTONS(UIP_ETHTYPE_IP);
BUF->ah_hwlen = IFHWADDRLEN;
BUF->ah_protolen = 4;
BUF->ah_ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
uiphdr_ipaddr_copy(ARPBUF->ah_dipaddr, &ipaddr);
uiphdr_ipaddr_copy(ARPBUF->ah_sipaddr, &dev->d_ipaddr);
dev->d_appdata = &dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
ARPBUF->ah_opcode = HTONS(ARP_REQUEST);
ARPBUF->ah_hwtype = HTONS(ARP_HWTYPE_ETH);
ARPBUF->ah_protocol = HTONS(UIP_ETHTYPE_IP);
ARPBUF->ah_hwlen = IFHWADDRLEN;
ARPBUF->ah_protolen = 4;
uip_arp_dump(ARPBUF);
dev->d_len = sizeof(struct arp_hdr);
ETHBUF->type = HTONS(UIP_ETHTYPE_ARP);
dev->d_appdata = &dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
dev->d_len = sizeof(struct arp_hdr);
return;
}
/* Build an ethernet header. */
memcpy(IPBUF->eh_ethhdr.dest.addr, tabptr->at_ethaddr.addr, IFHWADDRLEN);
memcpy(ETHBUF->dest, tabptr->at_ethaddr.addr, IFHWADDRLEN);
}
memcpy(IPBUF->eh_ethhdr.src.addr, dev->d_mac.addr, IFHWADDRLEN);
memcpy(ETHBUF->src, dev->d_mac.addr, IFHWADDRLEN);
IPBUF->eh_ethhdr.type = HTONS(UIP_ETHTYPE_IP);
ETHBUF->type = HTONS(UIP_ETHTYPE_IP);
dev->d_len += sizeof(struct uip_eth_hdr);
}