From 61eae05ef8b1b90d010819745266bbe7bc3f9e14 Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 31 Oct 2007 00:13:07 +0000 Subject: [PATCH] dhcpc debug git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@357 42af7a65-404d-4744-a932-0658087f49c3 --- arch/sim/src/up_internal.h | 2 +- arch/sim/src/up_tapdev.c | 73 +++++++++++++++++++++---------- arch/sim/src/up_uipdriver.c | 87 ++++++++++++++++++++++++++----------- 3 files changed, 113 insertions(+), 49 deletions(-) diff --git a/arch/sim/src/up_internal.h b/arch/sim/src/up_internal.h index 1d08f83817b..42b368d671c 100644 --- a/arch/sim/src/up_internal.h +++ b/arch/sim/src/up_internal.h @@ -113,7 +113,7 @@ extern char *up_deviceimage(void); extern unsigned long up_getwalltime( void ); extern void tapdev_init(void); extern unsigned int tapdev_read(unsigned char *buf, unsigned int buflen); -extern void tapdev_send(char *buf, unsigned int buflen); +extern void tapdev_send(unsigned char *buf, unsigned int buflen); #endif /* up_uipdriver.c *********************************************************/ diff --git a/arch/sim/src/up_tapdev.c b/arch/sim/src/up_tapdev.c index bf9d9db81a9..1961cfbaeac 100644 --- a/arch/sim/src/up_tapdev.c +++ b/arch/sim/src/up_tapdev.c @@ -85,6 +85,17 @@ extern int lib_rawprintf(const char *format, ...); * Private Types ****************************************************************************/ +/* Warning: This is very much Linux version specific! */ + +struct sel_arg_struct +{ + unsigned long n; + fd_set *inp; + fd_set *outp; + fd_set *exp; + struct timeval *tvp; +}; + /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -156,19 +167,35 @@ static inline int up_ioctl(int fd, unsigned int cmd, unsigned long arg) return (int)result; } -static inline int up_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp) +static inline int up_select(struct sel_arg_struct *arg) { ssize_t result; __asm__ volatile ("int $0x80" \ : "=a" (result) \ - : "0" (SELECT),"b" ((long)(n)),"c" ((long)(inp)), \ - "d" ((long)(outp)),"S" ((long)(exp)), "D"((long)tvp) \ + : "0" (SELECT),"b" ((struct sel_arg_struct *)(arg)) : "memory"); return (int)result; } +#ifdef TAPDEV_DEBUG +static inline void dump_ethhdr(const char *msg, unsigned char *buf, int buflen) +{ + lib_rawprintf("TAPDEV: %s %d bytes\n", msg, buflen); + lib_rawprintf(" %02x:%02x:%02x:%02x:%02x:%02x %02x:%02x:%02x:%02x:%02x:%02x %02x%02x\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], + buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], +#if UIP_BYTE_ORDER == UIP_LITTLE_ENDIAN + buf[12], buf[13]); +#else + buf[13], buf[12]); +#endif +} +#else +# define dump_ethhdr(m,b,l) +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -197,7 +224,7 @@ void tapdev_init(void) struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP|IFF_NO_PI; - ret = up_ioctl(gtapdevfd, TUNSETIFF, (unsigned long *) &ifr); + ret = up_ioctl(gtapdevfd, TUNSETIFF, (unsigned long) &ifr); if (ret < 0) { lib_rawprintf("TAPDEV: ioctl failed: %d\n", -ret ); @@ -213,23 +240,33 @@ void tapdev_init(void) unsigned int tapdev_read(unsigned char *buf, unsigned int buflen) { - fd_set fdset; - struct timeval tv; - int ret; + struct sel_arg_struct arg; + fd_set fdset; + struct timeval tv; + int ret; /* We can't do anything if we failed to open the tap device */ + if (gtapdevfd < 0) { return 0; } - tv.tv_sec = 0; + /* Wait for data on the tap device (or a timeout) */ + + tv.tv_sec = 0; tv.tv_usec = 1000; FD_ZERO(&fdset); FD_SET(gtapdevfd, &fdset); - ret = up_select(gtapdevfd + 1, &fdset, NULL, NULL, &tv); + arg.n = gtapdevfd + 1; + arg.inp = &fdset; + arg.outp = NULL; + arg.exp = NULL; + arg.tvp = &tv; + + ret = up_select(&arg); if(ret == 0) { return 0; @@ -242,22 +279,11 @@ unsigned int tapdev_read(unsigned char *buf, unsigned int buflen) return 0; } -#ifdef TAPDEV_DEBUG - lib_rawprintf("TAPDEV: read %d bytes\n", ret); - { - int i; - for(i = 0; i < 20; i++) - { - lib_rawprintf("%02x ", buf[i]); - } - lib_rawprintf("\n"); - } -#endif - + dump_ethhdr("read", buf, ret); return ret; } -void tapdev_send(char *buf, unsigned int buflen) +void tapdev_send(unsigned char *buf, unsigned int buflen) { int ret; #ifdef TAPDEV_DEBUG @@ -274,9 +300,10 @@ void tapdev_send(char *buf, unsigned int buflen) ret = up_write(gtapdevfd, buf, buflen); if (ret < 0) { - lib_rawprintf("TAPDEV: write"); + lib_rawprintf("TAPDEV: write failed: %d", -ret); exit(1); } + dump_ethhdr("write", buf, buflen); } #endif /* linux */ diff --git a/arch/sim/src/up_uipdriver.c b/arch/sim/src/up_uipdriver.c index b49e772e013..a3f641a36fc 100644 --- a/arch/sim/src/up_uipdriver.c +++ b/arch/sim/src/up_uipdriver.c @@ -46,6 +46,8 @@ #include #include +#include +#include #include #include @@ -102,6 +104,15 @@ void timer_reset(struct timer *t) t->start += t->interval; } +#ifdef CONFIG_NET_PROMISCUOUS +# define uipdriver_comparemac(a,b) (0) +#else +static inline int uip_comparemac(struct uip_eth_addr *paddr1, struct uip_eth_addr *paddr2) +{ + return memcmp(paddr1, paddr2, sizeof(struct uip_eth_addr)); +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -110,40 +121,65 @@ void uipdriver_loop(void) { int i; + /* tapdev_read will return 0 on a timeout event and >0 on a data received event */ + g_sim_dev.d_len = tapdev_read((unsigned char*)g_sim_dev.d_buf, UIP_BUFSIZE); + + /* Disable preemption through to the following so that it behaves a little more + * like an interrupt (otherwise, the following logic gets pre-empted an behaves + * oddly. + */ + + sched_lock(); if (g_sim_dev.d_len > 0) { - if (BUF->type == htons(UIP_ETHTYPE_IP)) + /* Data received event. Check for valid Ethernet header with destination == our + * MAC address + */ + + if (g_sim_dev.d_len > UIP_LLH_LEN && uip_comparemac( &BUF->dest, &g_sim_dev.d_mac) == 0) { - uip_arp_ipin(); - uip_input(&g_sim_dev); + /* We only accept IP packets of the configured type and ARP packets */ - /* If the above function invocation resulted in data that - * should be sent out on the network, the global variable - * d_len is set to a value > 0. - */ - - if (g_sim_dev.d_len > 0) +#ifdef CONFIG_NET_IPv6 + if (BUF->type == htons(UIP_ETHTYPE_IP6)) +#else + if (BUF->type == htons(UIP_ETHTYPE_IP)) +#endif { - uip_arp_out(&g_sim_dev); - tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len); + uip_arp_ipin(); + uip_input(&g_sim_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the global variable + * d_len is set to a value > 0. + */ + + if (g_sim_dev.d_len > 0) + { + uip_arp_out(&g_sim_dev); + tapdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); + } } - } - else if (BUF->type == htons(UIP_ETHTYPE_ARP)) - { - uip_arp_arpin(&g_sim_dev); - - /* If the above function invocation resulted in data that - * should be sent out on the network, the global variable - * d_len is set to a value > 0. - */ - - if (g_sim_dev.d_len > 0) + else if (BUF->type == htons(UIP_ETHTYPE_ARP)) { - tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len); + uip_arp_arpin(&g_sim_dev); + + /* If the above function invocation resulted in data that + * should be sent out on the network, the global variable + * d_len is set to a value > 0. + */ + + if (g_sim_dev.d_len > 0) + { + tapdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); + } } } } + + /* Otherwise, it must be a timeout event */ + else if (timer_expired(&g_periodic_timer)) { timer_reset(&g_periodic_timer); @@ -159,7 +195,7 @@ void uipdriver_loop(void) if (g_sim_dev.d_len > 0) { uip_arp_out(&g_sim_dev); - tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len); + tapdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); } } @@ -176,7 +212,7 @@ void uipdriver_loop(void) if (g_sim_dev.d_len > 0) { uip_arp_out(&g_sim_dev); - tapdev_send((char*)g_sim_dev.d_buf, g_sim_dev.d_len); + tapdev_send(g_sim_dev.d_buf, g_sim_dev.d_len); } } #endif /* CONFIG_NET_UDP */ @@ -189,6 +225,7 @@ void uipdriver_loop(void) uip_arp_timer(); } } + sched_unlock(); } int uipdriver_init(void)