From d2a24a161b5fa7425d1ee0cb0378a16e62cf51be Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Mon, 9 Mar 2015 17:19:46 +0100 Subject: [PATCH] [SQUASH ME] ng_tapnet: fixes --- cpu/native/ng_tapnet/ng_tapnet.c | 145 ++++++++++++++++++++----------- cpu/native/startup.c | 2 +- 2 files changed, 93 insertions(+), 54 deletions(-) diff --git a/cpu/native/ng_tapnet/ng_tapnet.c b/cpu/native/ng_tapnet/ng_tapnet.c index 193e711235e5..b64f1a0255b7 100644 --- a/cpu/native/ng_tapnet/ng_tapnet.c +++ b/cpu/native/ng_tapnet/ng_tapnet.c @@ -52,6 +52,7 @@ #include "net/ng_netif/hdr.h" #include "net/ng_pkt.h" #include "net/ng_pktbuf.h" +#include "od.h" #include "thread.h" #include "utlist.h" @@ -64,6 +65,9 @@ ng_tapnet_t ng_tapnet; +static uint8_t send_buffer[ETHER_MAX_LEN]; +static uint8_t recv_buffer[ETHER_MAX_LEN]; + #ifdef __MACH__ pid_t _sigio_child_pid; @@ -102,45 +106,56 @@ static void _sigio_child(ng_tapnet_t *dev) } #endif +static inline bool _has_source(ng_pktsnip_t *pkt) +{ + return (pkt->size != (sizeof(ng_netif_hdr_t) + (2 * ETHER_ADDR_LEN))); +} + +static inline bool _for_ethernet(ng_pktsnip_t *pkt) +{ + return ((pkt->size != (sizeof(ng_netif_hdr_t) + ETHER_ADDR_LEN)) || + _has_source(pkt)); +} + static int _marshall_ethernet(ng_tapnet_t *dev, uint8_t *buffer, ng_pktsnip_t *pkt) { int data_len = 0; struct ether_header *hdr = (struct ether_header *)buffer; ng_netif_hdr_t *netif_hdr; - ng_pktsnip_t *ptr = pkt, *payload; + ng_pktsnip_t *payload; - if (ptr == NULL) { + if (pkt == NULL) { DEBUG("ng_tapnet: pkt was NULL"); + ng_pktbuf_release(pkt); return -EINVAL; } - while (ptr->next != NULL) { - payload = ptr; - ptr = ptr->next; - } + payload = pkt->next; - if (ptr->size != (sizeof(ng_netif_hdr_t) + ETHER_ADDR_LEN)) { - DEBUG("ng_tapnet: First header was not generic netif header\n"); + if (!_for_ethernet(pkt)) { + DEBUG("ng_tapnet: First header was not generic netif header for Ethernet\n"); + ng_pktbuf_release(pkt); return -EBADMSG; } - switch (payload->type) { + switch (pkt->next->type) { #ifdef MODULE_NG_IPV6 case NG_NETTYPE_IPV6: - DEBUG("ng_tapnet: use ether type IPV6\n"); + DEBUG("ng_tapnet: use Ethertype IPV6\n"); hdr->ether_type = ETHERTYPE_IPV6; break; #endif default: - DEBUG("ng_tapnet: use ether type unknown, use 0xffff\n"); + DEBUG("ng_tapnet: Ethertype unknown, use 0xffff\n"); hdr->ether_type = 0xffff; break; } - netif_hdr = ptr->data; + netif_hdr = pkt->data; + /* set ethernet header */ memcpy(hdr->ether_shost, dev->addr, ETHER_ADDR_LEN); memcpy(hdr->ether_dhost, ng_netif_hdr_get_dst_addr(netif_hdr), netif_hdr->dst_l2addr_len); @@ -148,34 +163,29 @@ static int _marshall_ethernet(ng_tapnet_t *dev, uint8_t *buffer, ng_pktsnip_t *p hdr->ether_dhost[0], hdr->ether_dhost[1], hdr->ether_dhost[2], hdr->ether_dhost[3], hdr->ether_dhost[4], hdr->ether_dhost[5]); - LL_DELETE(pkt, ptr); - ng_pktbuf_release(ptr); - - buffer += ETHER_HDR_LEN; data_len += ETHER_HDR_LEN; - while (pkt != NULL) { - LL_SEARCH_SCALAR(pkt, ptr, next, NULL); - - if ((data_len + ptr->size) > ETHER_MAX_LEN) { + while (payload != NULL) { + if ((data_len + payload->size) > ETHER_MAX_LEN) { DEBUG("ng_tapnet: Packet too big for ethernet frame\n"); + ng_pktbuf_release(pkt); return -ENOBUFS; } - memcpy(buffer, pkt->data, pkt->size); - buffer += ptr->size; - data_len += ptr->size; + memcpy(send_buffer + data_len, payload->data, payload->size); - LL_DELETE(pkt, ptr); - ng_pktbuf_release(ptr); + data_len += payload->size; + payload = payload->next; } + ng_pktbuf_release(pkt); + /* Pad to minimum payload size. * Linux does this on its own, but it doesn't hurt to do it here. * As of now only tuntaposx needs this. */ if (data_len < ETHER_MIN_LEN) { - DEBUG("padding data!(%d -> ", data_len); - memset(buffer, 0, ETHER_MIN_LEN - data_len); + DEBUG("ng_tapnet: padding data! (%d -> ", data_len); + memset(send_buffer + data_len, 0, ETHER_MIN_LEN - data_len); data_len = ETHER_MIN_LEN; DEBUG("%d)\n", data_len); } @@ -304,7 +314,7 @@ int ng_tapnet_init(ng_tapnet_t *dev, char *name, size_t name_len) static inline int _get_addr(ng_tapnet_t *dev, uint8_t *value, size_t *value_len) { - if ((*value_len) != ETHER_ADDR_LEN) { + if ((*value_len) < ETHER_ADDR_LEN) { /* value buffer not big enough */ return -EOVERFLOW; } @@ -312,12 +322,12 @@ static inline int _get_addr(ng_tapnet_t *dev, uint8_t *value, size_t *value_len) *value_len = ETHER_ADDR_LEN; memcpy(value, dev->addr, ETHER_ADDR_LEN); - return 0; + return ETHER_ADDR_LEN; } static inline int _get_addr_len(uint16_t *value, size_t *value_len) { - if ((*value_len) < sizeof(uint16_t)) { + if ((*value_len) != sizeof(uint16_t)) { /* value buffer not big enough */ return -EOVERFLOW; } @@ -325,7 +335,7 @@ static inline int _get_addr_len(uint16_t *value, size_t *value_len) *value_len = sizeof(uint16_t); *value = ETHER_ADDR_LEN; - return 0; + return sizeof(uint16_t); } static inline int _get_max_pkt_sz(uint16_t *value, size_t *value_len) @@ -338,7 +348,7 @@ static inline int _get_max_pkt_sz(uint16_t *value, size_t *value_len) *value_len = sizeof(uint16_t); *value = ETHER_MAX_LEN; - return 0; + return sizeof(uint16_t); } static inline int _get_promiscousmode(ng_tapnet_t *dev, ng_netconf_enable_t *value, @@ -352,7 +362,7 @@ static inline int _get_promiscousmode(ng_tapnet_t *dev, ng_netconf_enable_t *val *value_len = sizeof(ng_netconf_enable_t); *value = (ng_netconf_enable_t)dev->promiscous; - return 0; + return sizeof(ng_netconf_enable_t); } static inline int _set_promiscousmode(ng_tapnet_t *dev, ng_netconf_enable_t *value, @@ -370,20 +380,19 @@ static inline int _set_promiscousmode(ng_tapnet_t *dev, ng_netconf_enable_t *val static int _send_data(ng_netdev_t *netdev, ng_pktsnip_t *pkt) { - uint8_t buffer[ETHER_MAX_LEN]; int nsent, to_send; ng_tapnet_t *dev = (ng_tapnet_t *)netdev; DEBUG("ng_tapnet: send data "); - if ((dev == NULL) || (dev->driver == &ng_tapnet_driver)) { + if ((dev == NULL) || (dev->driver != &ng_tapnet_driver)) { DEBUG("[wrong device descriptor]\n"); return -ENODEV; } DEBUG("\n"); - to_send = _marshall_ethernet(dev, buffer, pkt); + to_send = _marshall_ethernet(dev, send_buffer, pkt); if (to_send < 0) { errno = -to_send; @@ -392,8 +401,11 @@ static int _send_data(ng_netdev_t *netdev, ng_pktsnip_t *pkt) } DEBUG("ng_tapnet: send %d bytes\n", to_send); +#if MODULE_OD && defined(ENABLE_DEBUG) + od_hex_dump(send_buffer, to_send, OD_WIDTH_DEFAULT); +#endif - if ((nsent = _native_write(dev->tap_fd, buffer, to_send)) < 0) { + if ((nsent = _native_write(dev->tap_fd, send_buffer, to_send)) < 0) { warn("write"); return -EIO; } @@ -405,7 +417,7 @@ static int _add_event_callback(ng_netdev_t *dev, ng_netdev_event_cb_t cb) { DEBUG("ng_tapnet: add event callback"); - if ((dev == NULL) || (dev->driver == &ng_tapnet_driver)) { + if ((dev == NULL) || (dev->driver != &ng_tapnet_driver)) { DEBUG(" [wrong device descriptor]\n"); return -ENODEV; } @@ -425,7 +437,7 @@ static int _rem_event_callback(ng_netdev_t *dev, ng_netdev_event_cb_t cb) { DEBUG("ng_tapnet: remove event callback"); - if ((dev == NULL) || (dev->driver == &ng_tapnet_driver)) { + if ((dev == NULL) || (dev->driver != &ng_tapnet_driver)) { DEBUG(" [wrong device descriptor]\n"); return -ENODEV; } @@ -446,7 +458,7 @@ static int _get(ng_netdev_t *dev, ng_netconf_opt_t opt, void *value, { DEBUG("ng_tapnet: get "); - if ((dev == NULL) || (dev->driver == &ng_tapnet_driver)) { + if ((dev == NULL) || (dev->driver != &ng_tapnet_driver)) { DEBUG("[wrong device descriptor]\n"); return -ENODEV; } @@ -479,7 +491,7 @@ static int _set(ng_netdev_t *dev, ng_netconf_opt_t opt, void *value, { DEBUG("ng_tapnet: set "); - if ((dev == NULL) || (dev->driver == &ng_tapnet_driver)) { + if ((dev == NULL) || (dev->driver != &ng_tapnet_driver)) { DEBUG("[wrong device descriptor]\n"); return -ENODEV; } @@ -495,27 +507,37 @@ static int _set(ng_netdev_t *dev, ng_netconf_opt_t opt, void *value, } } +static inline bool _addr_broadcast(uint8_t *addr) +{ + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); +} + static void _rx_event(ng_tapnet_t *dev) { - uint8_t buffer[ETHER_MAX_LEN]; - int nread = real_read(dev->tap_fd, buffer, ETHER_MAX_LEN); + int nread = real_read(dev->tap_fd, recv_buffer, ETHER_MAX_LEN); DEBUG("ng_tapnet: read %d bytes\n", nread); if (nread > 0) { - struct ether_header *hdr = (struct ether_header *)buffer; + struct ether_header *hdr = (struct ether_header *)recv_buffer; ng_pktsnip_t *pkt; + ng_nettype_t receive_type = NG_NETTYPE_UNDEF; size_t data_len = (nread - ETHER_HDR_LEN); data_len += sizeof(ng_netif_hdr_t) + (2 * ETHER_ADDR_LEN); - if (!(dev->promiscous) && (memcmp(hdr->ether_dhost, dev->addr, ETHER_ADDR_LEN) != 0)) { + if (!(dev->promiscous) && (memcmp(hdr->ether_dhost, dev->addr, ETHER_ADDR_LEN) != 0) && + (!_addr_broadcast(hdr->ether_dhost))) { + /* TODO: check multicast */ DEBUG("ng_tapnet: received for %02x:%02x:%02x:%02x:%02x:%02x\n" "That's not me => Dropped\n", hdr->ether_dhost[0], hdr->ether_dhost[1], hdr->ether_dhost[2], hdr->ether_dhost[3], hdr->ether_dhost[4], hdr->ether_dhost[5]); + return; } - pkt = ng_pktbuf_add(NULL, NULL, data_len, NG_NETTYPE_UNDEF); + pkt = ng_pktbuf_add(NULL, NULL, sizeof(ng_netif_hdr_t) + (2 * ETHER_ADDR_LEN), + NG_NETTYPE_UNDEF); if (pkt == NULL) { DEBUG("ng_tapnet: no space left in packet buffer\n"); @@ -526,17 +548,34 @@ static void _rx_event(ng_tapnet_t *dev) ng_netif_hdr_set_src_addr(pkt->data, hdr->ether_shost, ETHER_ADDR_LEN); ng_netif_hdr_set_dst_addr(pkt->data, hdr->ether_dhost, ETHER_ADDR_LEN); ((ng_netif_hdr_t *)pkt->data)->if_pid = thread_getpid(); - /* XXX: Ethertype? */ - DEBUG("ng_tapnet: receive from %02x:%02x:%02x:%02x:%02x:%02x of length %zu\n", + switch (hdr->ether_type) { +#ifdef MODULE_NG_IPV6 + + case ETHERTYPE_IPV6: + DEBUG("ng_tapnet: received IPv6 packet "); + receive_type = NG_NETTYPE_IPV6; +#endif + + default: + DEBUG("ng_tapnet: received packet of unknown type "); + break; + } + + DEBUG("from %02x:%02x:%02x:%02x:%02x:%02x of length %zu\n", hdr->ether_shost[0], hdr->ether_shost[1], hdr->ether_shost[2], hdr->ether_shost[3], hdr->ether_shost[4], hdr->ether_shost[5], data_len - ng_netif_hdr_sizeof(pkt->data)); +#if defined(MODULE_OD) && ENABLE_DEBUG + od_hex_dump(hdr, data_len, OD_WIDTH_DEFAULT); +#endif - pkt = ng_pktbuf_add(pkt, /* Mark netif header and payload for next layer */ - pkt->data, - ng_netif_hdr_sizeof(pkt->data), - NG_NETTYPE_NUMOF); /* XXX: is this correct? */ + /* Mark netif header and payload for next layer */ + if ((pkt = ng_pktbuf_add(pkt, NULL, data_len - ETHER_HDR_LEN, + receive_type)) == NULL) { + DEBUG("ng_tapnet: no space left in packet buffer\n"); + return; + } if (dev->event_cb != NULL) { dev->event_cb(NETDEV_EVENT_RX_COMPLETE, pkt); @@ -585,7 +624,7 @@ static void _isr_event(ng_netdev_t *dev, uint16_t event_type) { DEBUG("ng_tapnet: ISR event "); - if ((dev == NULL) || (dev->driver == &ng_tapnet_driver)) { + if ((dev == NULL) || (dev->driver != &ng_tapnet_driver)) { return; } diff --git a/cpu/native/startup.c b/cpu/native/startup.c index a5f19e45cbca..2dbc05d33cc9 100644 --- a/cpu/native/startup.c +++ b/cpu/native/startup.c @@ -253,7 +253,7 @@ __attribute__((constructor)) static void startup(int argc, char **argv) int replay = 0; #endif -#ifdef MODULE_NATIVENET +#if defined(MODULE_NATIVENET) || defined(MODULE_NG_TAPNET) if ( (argc < 2) || (