void ng_ipv6_demux(kernel_pid_t iface, ng_pktsnip_t *pkt, uint8_t nh) { int receiver_num; pkt->type = ng_nettype_from_protnum(nh); switch (nh) { case NG_PROTNUM_ICMPV6: ng_icmpv6_demux(iface, pkt); break; /* TODO: add extension header handling */ default: break; } receiver_num = ng_netreg_num(pkt->type, NG_NETREG_DEMUX_CTX_ALL) + ng_netreg_num(NG_NETTYPE_IPV6, nh); if (receiver_num == 0) { DEBUG("ipv6: unable to forward packet as no one is interested in it\n"); ng_pktbuf_release(pkt); return; } ng_pktbuf_hold(pkt, receiver_num - 1); /* IPv6 is not interested anymore so `- 1` */ _dispatch_rcv_pkt(pkt->type, NG_NETREG_DEMUX_CTX_ALL, pkt); _dispatch_rcv_pkt(NG_NETTYPE_IPV6, nh, pkt); }
void ng_ipv6_demux(kernel_pid_t iface, ng_pktsnip_t *pkt, uint8_t nh) { int receiver_num; pkt->type = ng_nettype_from_protnum(nh); switch (nh) { case NG_PROTNUM_ICMPV6: DEBUG("ipv6: handle ICMPv6 packet (nh = %" PRIu8 ")\n", nh); ng_icmpv6_demux(iface, pkt); break; #ifdef MODULE_NG_IPV6_EXT case NG_PROTNUM_IPV6_EXT_HOPOPT: case NG_PROTNUM_IPV6_EXT_DST: case NG_PROTNUM_IPV6_EXT_RH: case NG_PROTNUM_IPV6_EXT_FRAG: case NG_PROTNUM_IPV6_EXT_AH: case NG_PROTNUM_IPV6_EXT_ESP: case NG_PROTNUM_IPV6_EXT_MOB: DEBUG("ipv6: handle extension header (nh = %" PRIu8 ")\n", nh); if (!ng_ipv6_ext_demux(iface, pkt, nh)) { DEBUG("ipv6: unable to parse extension headers.\n"); ng_pktbuf_release(pkt); return; } #endif case NG_PROTNUM_IPV6: DEBUG("ipv6: handle encapsulated IPv6 packet (nh = %" PRIu8 ")\n", nh); _decapsulate(pkt); break; default: break; } DEBUG("ipv6: forward nh = %" PRIu8 " to other threads\n", nh); receiver_num = ng_netreg_num(pkt->type, NG_NETREG_DEMUX_CTX_ALL) + ng_netreg_num(NG_NETTYPE_IPV6, nh); if (receiver_num == 0) { DEBUG("ipv6: unable to forward packet as no one is interested in it\n"); ng_pktbuf_release(pkt); return; } ng_pktbuf_hold(pkt, receiver_num - 1); /* IPv6 is not interested anymore so `- 1` */ _dispatch_rcv_pkt(pkt->type, NG_NETREG_DEMUX_CTX_ALL, pkt); _dispatch_rcv_pkt(NG_NETTYPE_IPV6, nh, pkt); }
static void _send(ng_pktsnip_t *pkt) { ng_udp_hdr_t *hdr; ng_pktsnip_t *udp_snip; ng_netreg_entry_t *sendto; /* get udp snip and hdr */ LL_SEARCH_SCALAR(pkt, udp_snip, type, NG_NETTYPE_UDP); udp_snip = ng_pktbuf_start_write(udp_snip); if (udp_snip == NULL) { DEBUG("udp: cannot send packet: unable to allocate packet\n"); ng_pktbuf_release(pkt); return; } hdr = (ng_udp_hdr_t *)udp_snip->data; /* fill in size field */ hdr->length = byteorder_htons(ng_pkt_len(udp_snip)); /* and forward packet to the network layer */ sendto = ng_netreg_lookup(pkt->type, NG_NETREG_DEMUX_CTX_ALL); /* throw away packet if no one is interested */ if (sendto == NULL) { DEBUG("udp: cannot send packet: network layer not found\n"); ng_pktbuf_release(pkt); return; } /* send packet to network layer */ ng_pktbuf_hold(pkt, ng_netreg_num(pkt->type, NG_NETREG_DEMUX_CTX_ALL) - 1); while (sendto != NULL) { ng_netapi_send(sendto->pid, pkt); sendto = ng_netreg_getnext(sendto); } }
/** * @brief Function called by the device driver on device events * * @param[in] event type of event * @param[in] data optional parameter */ static void _event_cb(ng_netdev_event_t event, void *data) { DEBUG("nomac: event triggered -> %i\n", event); /* NOMAC only understands the RX_COMPLETE event... */ if (event == NETDEV_EVENT_RX_COMPLETE) { ng_pktsnip_t *pkt; ng_netreg_entry_t *sendto; /* get pointer to the received packet */ pkt = (ng_pktsnip_t *)data; /* find out, who to send the packet to */ sendto = ng_netreg_lookup(pkt->type, NG_NETREG_DEMUX_CTX_ALL); /* throw away packet if no one is interested */ if (sendto == NULL) { DEBUG("nomac: unable to forward packet of type %i\n", pkt->type); ng_pktbuf_release(pkt); return; } /* send the packet to everyone interested in it's type */ ng_pktbuf_hold(pkt, ng_netreg_num(pkt->type, NG_NETREG_DEMUX_CTX_ALL) - 1); while (sendto != NULL) { DEBUG("nomac: sending pkt %p to PID %u\n", (void*)pkt, sendto->pid); ng_netapi_receive(sendto->pid, pkt); sendto = ng_netreg_getnext(sendto); } } }
static void _send_to_iface(kernel_pid_t iface, ng_pktsnip_t *pkt) { ng_ipv6_netif_t *if_entry = ng_ipv6_netif_get(iface); ((ng_netif_hdr_t *)pkt->data)->if_pid = iface; if ((if_entry != NULL) && (if_entry->flags & NG_IPV6_NETIF_FLAGS_SIXLOWPAN)) { DEBUG("ipv6: send to 6LoWPAN instead\n"); ng_netreg_entry_t *reg = ng_netreg_lookup(NG_NETTYPE_SIXLOWPAN, NG_NETREG_DEMUX_CTX_ALL); if (reg != NULL) { ng_pktbuf_hold(pkt, ng_netreg_num(NG_NETTYPE_SIXLOWPAN, NG_NETREG_DEMUX_CTX_ALL) - 1); } else { DEBUG("ipv6: no 6LoWPAN thread found"); } while (reg) { ng_netapi_send(reg->pid, pkt); reg = ng_netreg_getnext(reg); } } else { ng_netapi_send(iface, pkt); } }
static void send(char *addr_str, char *port_str, char *data) { uint8_t port[2]; uint16_t tmp; ng_pktsnip_t *payload, *udp, *ip; ng_ipv6_addr_t addr; ng_netreg_entry_t *sendto; /* parse destination address */ if (ng_ipv6_addr_from_str(&addr, addr_str) == NULL) { puts("Error: unable to parse destination address"); return; } /* parse port */ tmp = (uint16_t)atoi(port_str); if (tmp == 0) { puts("Error: unable to parse destination port"); return; } port[0] = (uint8_t)tmp; port[1] = tmp >> 8; /* allocate payload */ payload = ng_pktbuf_add(NULL, data, strlen(data), NG_NETTYPE_UNDEF); if (payload == NULL) { puts("Error: unable to copy data to packet buffer"); return; } /* allocate UDP header, set source port := destination port */ udp = ng_udp_hdr_build(payload, port, 2, port, 2); if (udp == NULL) { puts("Error: unable to allocate UDP header"); ng_pktbuf_release(payload); return; } /* allocate IPv6 header */ ip = ng_ipv6_hdr_build(udp, NULL, 0, (uint8_t *)&addr, sizeof(addr)); if (ip == NULL) { puts("Error: unable to allocate IPv6 header"); ng_pktbuf_release(udp); return; } /* send packet */ sendto = ng_netreg_lookup(NG_NETTYPE_UDP, NG_NETREG_DEMUX_CTX_ALL); if (sendto == NULL) { puts("Error: unable to locate UDP thread"); ng_pktbuf_release(ip); return; } ng_pktbuf_hold(ip, ng_netreg_num(NG_NETTYPE_UDP, NG_NETREG_DEMUX_CTX_ALL) - 1); while (sendto != NULL) { ng_netapi_send(sendto->pid, ip); sendto = ng_netreg_getnext(sendto); } printf("Success: send %i byte to %s:%u\n", payload->size, addr_str, tmp); }
/* SLIP receive handler */ static void _slip_receive(ng_slip_dev_t *dev, size_t bytes) { ng_netif_hdr_t *hdr; ng_netreg_entry_t *sendto; ng_pktsnip_t *pkt, *netif_hdr; pkt = ng_pktbuf_add(NULL, NULL, bytes, NG_NETTYPE_UNDEF); if (pkt == NULL) { DEBUG("slip: no space left in packet buffer\n"); return; } netif_hdr = ng_pktbuf_add(pkt, NULL, sizeof(ng_netif_hdr_t), NG_NETTYPE_NETIF); if (netif_hdr == NULL) { DEBUG("slip: no space left in packet buffer\n"); ng_pktbuf_release(pkt); return; } hdr = netif_hdr->data; ng_netif_hdr_init(hdr, 0, 0); hdr->if_pid = thread_getpid(); if (ringbuffer_get(dev->in_buf, pkt->data, bytes) != bytes) { DEBUG("slip: could not read %zu bytes from ringbuffer\n", bytes); ng_pktbuf_release(pkt); return; } #ifdef MODULE_NG_IPV6 if ((pkt->size >= sizeof(ipv6_hdr_t)) && ipv6_hdr_is(pkt->data)) { pkt->type = NG_NETTYPE_IPV6; } #endif sendto = ng_netreg_lookup(pkt->type, NG_NETREG_DEMUX_CTX_ALL); if (sendto == NULL) { DEBUG("slip: unable to forward packet of type %i\n", pkt->type); ng_pktbuf_release(pkt); } ng_pktbuf_hold(pkt, ng_netreg_num(pkt->type, NG_NETREG_DEMUX_CTX_ALL) - 1); while (sendto != NULL) { DEBUG("slip: sending pkt %p to PID %u\n", pkt, sendto->pid); ng_netapi_receive(sendto->pid, pkt); sendto = ng_netreg_getnext(sendto); } }
static void _receive(ng_pktsnip_t *pkt) { ng_pktsnip_t *udp, *ipv6; ng_udp_hdr_t *hdr; uint32_t port; ng_netreg_entry_t *sendto; /* mark UDP header */ udp = ng_pktbuf_start_write(pkt); if (udp == NULL) { DEBUG("udp: unable to get write access to packet\n"); ng_pktbuf_release(pkt); return; } pkt = udp; udp = ng_pktbuf_add(pkt, pkt->data, sizeof(ng_udp_hdr_t), NG_NETTYPE_UDP); if (udp == NULL) { DEBUG("udp: error marking UDP header, dropping packet\n"); ng_pktbuf_release(pkt); return; } /* mark payload as Type: UNDEF */ pkt->type = NG_NETTYPE_UNDEF; /* get explicit pointer to UDP header */ hdr = (ng_udp_hdr_t *)udp->data; LL_SEARCH_SCALAR(pkt, ipv6, type, NG_NETTYPE_IPV6); /* validate checksum */ if (_calc_csum(udp, ipv6, pkt)) { DEBUG("udp: received packet with invalid checksum, dropping it\n"); ng_pktbuf_release(pkt); return; } /* get port (netreg demux context) */ port = (uint32_t)byteorder_ntohs(hdr->dst_port); /* send payload to receivers */ sendto = ng_netreg_lookup(NG_NETTYPE_UDP, port); if (sendto == NULL) { DEBUG("udp: unable to forward packet as no one is interested in it\n"); ng_pktbuf_release(pkt); return; } ng_pktbuf_hold(pkt, ng_netreg_num(NG_NETTYPE_UDP, port) - 1); while (sendto != NULL) { ng_netapi_receive(sendto->pid, pkt); sendto = ng_netreg_getnext(sendto); } }
static void udp_send(const char *str) { uint8_t data[20]; ng_pktsnip_t *payload, *udp, *ip; ng_netreg_entry_t *sendto; memcpy(data, str, strlen(str)); /* allocate payload */ payload = ng_pktbuf_add(NULL, data, strlen(str), NG_NETTYPE_UNDEF); if (payload == NULL) { puts("Error: unable to copy data to packet buffer"); return; } /* allocate UDP header, set source port := destination port */ udp = ng_udp_hdr_build(payload, port, 2, port, 2); if (udp == NULL) { puts("Error: unable to allocate UDP header"); ng_pktbuf_release(payload); return; } /* allocate IPv6 header */ ip = ng_ipv6_hdr_build(udp, NULL, 0, (uint8_t *)&addr, sizeof(addr)); if (ip == NULL) { puts("Error: unable to allocate IPv6 header"); ng_pktbuf_release(udp); return; } /* send packet */ sendto = ng_netreg_lookup(NG_NETTYPE_UDP, NG_NETREG_DEMUX_CTX_ALL); if (sendto == NULL) { puts("Error: unable to locate UDP thread"); ng_pktbuf_release(ip); return; } ng_pktbuf_hold(ip, ng_netreg_num(NG_NETTYPE_UDP, NG_NETREG_DEMUX_CTX_ALL) - 1); while (sendto != NULL) { ng_netapi_send(sendto->pid, ip); sendto = ng_netreg_getnext(sendto); } printf("Send %s\n", str); }
void ng_icmpv6_echo_req_handle(kernel_pid_t iface, ng_ipv6_hdr_t *ipv6_hdr, ng_icmpv6_echo_t *echo, uint16_t len) { uint8_t *payload = ((uint8_t *)echo) + sizeof(ng_icmpv6_echo_t); ng_pktsnip_t *hdr, *pkt; ng_netreg_entry_t *sendto = NULL; if ((echo == NULL) || (len < sizeof(ng_icmpv6_echo_t))) { DEBUG("icmpv6_echo: echo was NULL or len (%" PRIu16 ") was < sizeof(ng_icmpv6_echo_t)\n", len); return; } pkt = ng_icmpv6_echo_build(NG_ICMPV6_ECHO_REP, byteorder_ntohs(echo->id), byteorder_ntohs(echo->seq), payload, len - sizeof(ng_icmpv6_echo_t)); if (pkt == NULL) { DEBUG("icmpv6_echo: no space left in packet buffer\n"); return; } if (ipv6_addr_is_multicast(&ipv6_hdr->dst)) { hdr = ng_ipv6_hdr_build(pkt, NULL, 0, (uint8_t *)&ipv6_hdr->src, sizeof(ipv6_addr_t)); } else { hdr = ng_ipv6_hdr_build(pkt, (uint8_t *)&ipv6_hdr->dst, sizeof(ipv6_addr_t), (uint8_t *)&ipv6_hdr->src, sizeof(ipv6_addr_t)); } if (hdr == NULL) { DEBUG("icmpv6_echo: no space left in packet buffer\n"); ng_pktbuf_release(pkt); return; } pkt = hdr; hdr = ng_netif_hdr_build(NULL, 0, NULL, 0); ((ng_netif_hdr_t *)hdr->data)->if_pid = iface; LL_PREPEND(pkt, hdr); sendto = ng_netreg_lookup(NG_NETTYPE_IPV6, NG_NETREG_DEMUX_CTX_ALL); if (sendto == NULL) { DEBUG("icmpv6_echo: no receivers for IPv6 packets\n"); ng_pktbuf_release(pkt); return; } /* ICMPv6 is not interested anymore so `- 1` */ ng_pktbuf_hold(pkt, ng_netreg_num(NG_NETTYPE_IPV6, NG_NETREG_DEMUX_CTX_ALL) - 1); while (sendto != NULL) { ng_netapi_send(sendto->pid, pkt); sendto = ng_netreg_getnext(sendto); } }
void ng_icmpv6_demux(kernel_pid_t iface, ng_pktsnip_t *pkt) { ng_pktsnip_t *icmpv6, *ipv6; ng_icmpv6_hdr_t *hdr; ng_netreg_entry_t *sendto; LL_SEARCH_SCALAR(pkt, icmpv6, type, NG_NETTYPE_ICMPV6); /* there can be extension headers between IPv6 and ICMPv6 header so we have * to search it */ LL_SEARCH_SCALAR(icmpv6, ipv6, type, NG_NETTYPE_IPV6); hdr = (ng_icmpv6_hdr_t *)icmpv6->data; if (_calc_csum(icmpv6, ipv6, pkt)) { DEBUG("icmpv6: wrong checksum.\n"); /* don't release: IPv6 does this */ return; } switch (hdr->type) { /* TODO: handle ICMPv6 errors */ #ifdef MODULE_NG_ICMPV6_ECHO case NG_ICMPV6_ECHO_REQ: DEBUG("icmpv6: handle echo request.\n"); ng_icmpv6_echo_req_handle(iface, (ng_ipv6_hdr_t *)ipv6->data, (ng_icmpv6_echo_t *)hdr, icmpv6->size); break; #endif case NG_ICMPV6_RTR_SOL: DEBUG("icmpv6: router solicitation received\n"); /* TODO */ break; case NG_ICMPV6_RTR_ADV: DEBUG("icmpv6: router advertisement received\n"); /* TODO */ break; case NG_ICMPV6_NBR_SOL: DEBUG("icmpv6: neighbor solicitation received\n"); ng_ndp_nbr_sol_handle(iface, pkt, ipv6->data, (ng_ndp_nbr_sol_t *)hdr, icmpv6->size); break; case NG_ICMPV6_NBR_ADV: DEBUG("icmpv6: neighbor advertisement received\n"); ng_ndp_nbr_adv_handle(iface, pkt, ipv6->data, (ng_ndp_nbr_adv_t *)hdr, icmpv6->size); break; case NG_ICMPV6_REDIRECT: DEBUG("icmpv6: redirect message received\n"); /* TODO */ break; #ifdef MODULE_NG_RPL case NG_ICMPV6_RPL_CTRL: DEBUG("icmpv6: RPL control message received\n"); /* TODO */ break; #endif default: DEBUG("icmpv6: unknown type field %" PRIu8 "\n", hdr->type); break; } /* ICMPv6-all will be send in ng_ipv6.c so only dispatch of subtypes is * needed */ sendto = ng_netreg_lookup(NG_NETTYPE_ICMPV6, hdr->type); if (sendto == NULL) { DEBUG("icmpv6: no receivers for ICMPv6 type %" PRIu8 "\n", hdr->type); /* don't release: IPv6 does this */ return; } /* ICMPv6 is not interested anymore so `- 1` */ ng_pktbuf_hold(pkt, ng_netreg_num(NG_NETTYPE_ICMPV6, hdr->type)); while (sendto != NULL) { ng_netapi_receive(sendto->pid, pkt); sendto = ng_netreg_getnext(sendto); } }
void _receive(ng_pktsnip_t *pkt) { ng_pktsnip_t *payload; uint8_t *dispatch; ng_netreg_entry_t *entry; LL_SEARCH_SCALAR(pkt, payload, type, NG_NETTYPE_SIXLOWPAN); if ((payload == NULL) || (payload->size < 1)) { DEBUG("6lo: Received packet has no 6LoWPAN payload\n"); ng_pktbuf_release(pkt); } dispatch = payload->data; if (dispatch[0] == NG_SIXLOWPAN_UNCOMPRESSED) { ng_pktsnip_t *sixlowpan; DEBUG("6lo: received uncompressed IPv6 packet\n"); payload = ng_pktbuf_start_write(payload); if (payload == NULL) { DEBUG("6lo: can not get write access on received packet\n"); #if defined(DEVELHELP) && defined(ENABLE_DEBUG) ng_pktbuf_stats(); #endif ng_pktbuf_release(pkt); return; } /* packet is uncompressed: just mark and remove the dispatch */ sixlowpan = ng_pktbuf_add(payload, payload->data, sizeof(uint8_t), NG_NETTYPE_SIXLOWPAN); LL_DELETE(pkt, sixlowpan); ng_pktbuf_release(sixlowpan); } #ifdef MODULE_NG_SIXLOWPAN_FRAG else if (ng_sixlowpan_frag_is((ng_sixlowpan_frag_t *)dispatch)) { DEBUG("6lo: received 6LoWPAN fragment\n"); ng_sixlowpan_frag_handle_pkt(pkt); } #endif else { DEBUG("6lo: dispatch %02x ... is not supported\n", dispatch[0]); ng_pktbuf_release(pkt); return; } payload->type = NG_NETTYPE_IPV6; entry = ng_netreg_lookup(NG_NETTYPE_IPV6, NG_NETREG_DEMUX_CTX_ALL); if (entry == NULL) { DEBUG("ipv6: No receivers for this packet found\n"); ng_pktbuf_release(pkt); return; } ng_pktbuf_hold(pkt, ng_netreg_num(NG_NETTYPE_IPV6, NG_NETREG_DEMUX_CTX_ALL) - 1); while (entry) { DEBUG("6lo: Send receive command for %p to %" PRIu16 "\n", (void *)pkt, entry->pid); ng_netapi_receive(entry->pid, pkt); entry = ng_netreg_getnext(entry); } }