Skip to content

Commit

Permalink
[SQUASH ME] ng_tapnet: fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
miri64 committed Mar 9, 2015
1 parent 1484f5a commit d2a24a1
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 54 deletions.
145 changes: 92 additions & 53 deletions cpu/native/ng_tapnet/ng_tapnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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;

Expand Down Expand Up @@ -102,80 +106,86 @@ 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);
DEBUG("ng_tapnet: send to %02x:%02x:%02x:%02x:%02x:%02x\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]);

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);
}
Expand Down Expand Up @@ -304,28 +314,28 @@ 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;
}

*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;
}

*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)
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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;
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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");
Expand All @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion cpu/native/startup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
|| (
Expand Down

0 comments on commit d2a24a1

Please sign in to comment.