/* shell commands */ int _netif_send(int argc, char **argv) { kernel_pid_t dev; uint8_t addr[MAX_ADDR_LEN]; size_t addr_len; gnrc_pktsnip_t *pkt; gnrc_netif_hdr_t *nethdr; uint8_t flags = 0x00; if (argc < 4) { printf("usage: %s <if> [<addr>|bcast] <data>\n", argv[0]); return 1; } /* parse interface */ dev = (kernel_pid_t)atoi(argv[1]); if (!_is_iface(dev)) { puts("error: invalid interface given"); return 1; } /* parse address */ addr_len = gnrc_netif_addr_from_str(addr, sizeof(addr), argv[2]); if (addr_len == 0) { if (strcmp(argv[2], "bcast") == 0) { flags |= GNRC_NETIF_HDR_FLAGS_BROADCAST; } else { puts("error: invalid address given"); return 1; } } /* put packet together */ pkt = gnrc_pktbuf_add(NULL, argv[3], strlen(argv[3]), GNRC_NETTYPE_UNDEF); pkt = gnrc_pktbuf_add(pkt, NULL, sizeof(gnrc_netif_hdr_t) + addr_len, GNRC_NETTYPE_NETIF); nethdr = (gnrc_netif_hdr_t *)pkt->data; gnrc_netif_hdr_init(nethdr, 0, addr_len); gnrc_netif_hdr_set_dst_addr(nethdr, addr, addr_len); nethdr->flags = flags; /* and send it */ if (gnrc_netapi_send(dev, pkt) < 1) { puts("error: unable to send\n"); gnrc_pktbuf_release(pkt); return 1; } return 0; }
gnrc_pktsnip_t *gnrc_netif_hdr_build(const uint8_t *src, uint8_t src_len, const uint8_t *dst, uint8_t dst_len) { gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, NULL, sizeof(gnrc_netif_hdr_t) + src_len + dst_len, GNRC_NETTYPE_NETIF); if (pkt == NULL) { return NULL; } gnrc_netif_hdr_init(pkt->data, src_len, dst_len); if (src != NULL && src_len > 0) { gnrc_netif_hdr_set_src_addr(pkt->data, src, src_len); } if (dst != NULL && dst_len > 0) { gnrc_netif_hdr_set_dst_addr(pkt->data, dst, dst_len); } return pkt; }
static gnrc_pktsnip_t *_recv(gnrc_netdev2_t *gnrc_netdev2) { netdev2_t *dev = gnrc_netdev2->dev; cc110x_t *cc110x = &((netdev2_cc110x_t*) dev)->cc110x; cc110x_pkt_t *cc110x_pkt = &cc110x->pkt_buf.packet; int payload_length = cc110x_pkt->length - CC110X_HEADER_LENGTH; int nettype; int addr_len; switch (cc110x_pkt->flags) { #ifdef MODULE_GNRC_SIXLOWPAN case 1: addr_len = 8; nettype = GNRC_NETTYPE_SIXLOWPAN; break; #endif default: addr_len = 1; nettype = GNRC_NETTYPE_UNDEF; } /* copy packet payload into pktbuf */ gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, cc110x_pkt->data, payload_length, nettype); if(!pkt) { DEBUG("cc110x: _recv: cannot allocate pktsnip.\n"); return NULL; } gnrc_pktsnip_t *netif_hdr; netif_hdr = gnrc_pktbuf_add(NULL, NULL, sizeof(gnrc_netif_hdr_t) + 2*addr_len, GNRC_NETTYPE_NETIF); if (netif_hdr == NULL) { DEBUG("gnrc_netdev2_cc110x: no space left in packet buffer\n"); gnrc_pktbuf_release(pkt); return NULL; } gnrc_netif_hdr_init(netif_hdr->data, addr_len, addr_len); if (addr_len == 8) { uint64_t src_addr = cc110x_pkt->phy_src; uint64_t dst_addr = cc110x_pkt->address; gnrc_netif_hdr_set_src_addr(netif_hdr->data, (uint8_t*)&src_addr, addr_len); gnrc_netif_hdr_set_dst_addr(netif_hdr->data, (uint8_t*)&dst_addr, addr_len); } else { gnrc_netif_hdr_set_src_addr(netif_hdr->data, (uint8_t*)&cc110x_pkt->phy_src, addr_len); gnrc_netif_hdr_set_dst_addr(netif_hdr->data, (uint8_t*)&cc110x_pkt->address, addr_len); } ((gnrc_netif_hdr_t *)netif_hdr->data)->if_pid = thread_getpid(); ((gnrc_netif_hdr_t *)netif_hdr->data)->lqi = cc110x->pkt_buf.lqi; ((gnrc_netif_hdr_t *)netif_hdr->data)->rssi = cc110x->pkt_buf.rssi; DEBUG("gnrc_netdev2_cc110x: received packet from %02x" " of length %u\n", (unsigned)cc110x_pkt->phy_src, (unsigned)cc110x_pkt->length-CC110X_HEADER_LENGTH); #if defined(MODULE_OD) && ENABLE_DEBUG od_hex_dump(cc110x_pkt->data, payload_length, OD_WIDTH_DEFAULT); #endif pkt->next = netif_hdr; return pkt; }
static gnrc_pktsnip_t *_recv(gnrc_netdev2_t *gnrc_netdev2) { netdev2_t *dev = gnrc_netdev2->dev; int bytes_expected = dev->driver->recv(dev, NULL, 0); gnrc_pktsnip_t *pkt = NULL; if (bytes_expected) { pkt = gnrc_pktbuf_add(NULL, NULL, bytes_expected, GNRC_NETTYPE_UNDEF); if(!pkt) { DEBUG("_recv_ethernet_packet: cannot allocate pktsnip.\n"); goto out; } int nread = dev->driver->recv(dev, pkt->data, bytes_expected); if(nread <= 0) { DEBUG("_recv_ethernet_packet: read error.\n"); goto safe_out; } if (nread < bytes_expected) { /* we've got less then the expected packet size, * so free the unused space.*/ DEBUG("_recv_ethernet_packet: reallocating.\n"); gnrc_pktbuf_realloc_data(pkt, nread); } /* mark ethernet header */ gnrc_pktsnip_t *eth_hdr = gnrc_pktbuf_mark(pkt, sizeof(ethernet_hdr_t), GNRC_NETTYPE_UNDEF); if (!eth_hdr) { DEBUG("gnrc_netdev2_eth: no space left in packet buffer\n"); goto safe_out; } ethernet_hdr_t *hdr = (ethernet_hdr_t *)eth_hdr->data; /* set payload type from ethertype */ pkt->type = gnrc_nettype_from_ethertype(byteorder_ntohs(hdr->type)); /* create netif header */ gnrc_pktsnip_t *netif_hdr; netif_hdr = gnrc_pktbuf_add(NULL, NULL, sizeof(gnrc_netif_hdr_t) + (2 * ETHERNET_ADDR_LEN), GNRC_NETTYPE_NETIF); if (netif_hdr == NULL) { DEBUG("gnrc_netdev2_eth: no space left in packet buffer\n"); pkt = eth_hdr; goto safe_out; } gnrc_netif_hdr_init(netif_hdr->data, ETHERNET_ADDR_LEN, ETHERNET_ADDR_LEN); gnrc_netif_hdr_set_src_addr(netif_hdr->data, hdr->src, ETHERNET_ADDR_LEN); gnrc_netif_hdr_set_dst_addr(netif_hdr->data, hdr->dst, ETHERNET_ADDR_LEN); ((gnrc_netif_hdr_t *)netif_hdr->data)->if_pid = thread_getpid(); DEBUG("gnrc_netdev2_eth: received packet from %02x:%02x:%02x:%02x:%02x:%02x " "of length %zu\n", hdr->src[0], hdr->src[1], hdr->src[2], hdr->src[3], hdr->src[4], hdr->src[5], nread); #if defined(MODULE_OD) && ENABLE_DEBUG od_hex_dump(hdr, nread, OD_WIDTH_DEFAULT); #endif gnrc_pktbuf_remove_snip(pkt, eth_hdr); LL_APPEND(pkt, netif_hdr); } out: return pkt; safe_out: gnrc_pktbuf_release(pkt); return NULL; }