gnrc_pktsnip_t *gnrc_netreg_hdr_build(gnrc_nettype_t type, gnrc_pktsnip_t *payload, uint8_t *src, uint8_t src_len, uint8_t *dst, uint8_t dst_len) { switch (type) { #ifdef MODULE_GNRC_IPV6 case GNRC_NETTYPE_IPV6: return gnrc_ipv6_hdr_build(payload, src, src_len, dst, dst_len); #endif #ifdef MODULE_GNRC_TCP case GNRC_NETTYPE_TCP: return gnrc_tcp_hdr_build(payload, src, src_len, dst, dst_len); #endif #ifdef MODULE_GNRC_UDP case GNRC_NETTYPE_UDP: return gnrc_udp_hdr_build(payload, src, src_len, dst, dst_len); #endif default: (void)payload; (void)src; (void)src_len; (void)dst; (void)dst_len; return NULL; } }
int conn_udp_sendto(const void *data, size_t len, const void *src, size_t src_len, const void *dst, size_t dst_len, int family, uint16_t sport, uint16_t dport) { gnrc_pktsnip_t *pkt, *hdr = NULL; pkt = gnrc_pktbuf_add(NULL, (void *)data, len, GNRC_NETTYPE_UNDEF); /* data will only be copied */ hdr = gnrc_udp_hdr_build(pkt, (uint8_t *)&sport, sizeof(uint16_t), (uint8_t *)&dport, sizeof(uint16_t)); if (hdr == NULL) { gnrc_pktbuf_release(pkt); return -ENOMEM; } pkt = hdr; switch (family) { #ifdef MODULE_GNRC_IPV6 case AF_INET6: if (((src != NULL) && (src_len != sizeof(ipv6_addr_t))) || (dst_len != sizeof(ipv6_addr_t))) { gnrc_pktbuf_release(pkt); return -EINVAL; } /* addr will only be copied */ hdr = gnrc_ipv6_hdr_build(pkt, (uint8_t *)src, src_len, (uint8_t *)dst, dst_len); if (hdr == NULL) { gnrc_pktbuf_release(pkt); return -ENOMEM; } pkt = hdr; break; #endif /* MODULE_GNRC_IPV6 */ default: (void)hdr; (void)src; (void)src_len; (void)dst; (void)dst_len; gnrc_pktbuf_release(pkt); return -EAFNOSUPPORT; } gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, GNRC_NETREG_DEMUX_CTX_ALL, pkt); return len; }
tftp_state _tftp_send(gnrc_pktsnip_t *buf, tftp_context_t *ctxt, size_t len) { network_uint16_t src_port, dst_port; gnrc_pktsnip_t *udp, *ip; assert(len <= TFTP_DEFAULT_DATA_SIZE); /* down-size the packet to it's used size */ if (len > TFTP_DEFAULT_DATA_SIZE) { DEBUG("tftp: can't reallocate to bigger packet, buffer overflowed\n"); gnrc_pktbuf_release(buf); if (ctxt->stop_cb) { ctxt->stop_cb(TFTP_INTERN_ERROR, "buffer overflowed"); } return TS_FAILED; } else if (gnrc_pktbuf_realloc_data(buf, len) != 0) { assert(false); DEBUG("tftp: failed to reallocate data snippet\n"); gnrc_pktbuf_release(buf); /* inform the user that we can't reallocate */ if (ctxt->stop_cb) { ctxt->stop_cb(TFTP_INTERN_ERROR, "no reallocate"); } return TS_FAILED; } /* allocate UDP header, set source port := destination port */ src_port.u16 = ctxt->src_port; dst_port.u16 = ctxt->dst_port; udp = gnrc_udp_hdr_build(buf, src_port.u16, dst_port.u16); if (udp == NULL) { DEBUG("tftp: error unable to allocate UDP header\n"); gnrc_pktbuf_release(buf); if (ctxt->stop_cb) { ctxt->stop_cb(TFTP_INTERN_ERROR, "no udp allocate"); } return TS_FAILED; } /* allocate IPv6 header */ ip = gnrc_ipv6_hdr_build(udp, NULL, &(ctxt->peer)); if (ip == NULL) { DEBUG("tftp: error unable to allocate IPv6 header\n"); gnrc_pktbuf_release(udp); if (ctxt->stop_cb) { ctxt->stop_cb(TFTP_INTERN_ERROR, "no ip allocate"); } return TS_FAILED; } /* send packet */ if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, GNRC_NETREG_DEMUX_CTX_ALL, ip) == 0) { /* if send failed inform the user */ DEBUG("tftp: error unable to locate UDP thread\n"); gnrc_pktbuf_release(ip); if (ctxt->stop_cb) { ctxt->stop_cb(TFTP_INTERN_ERROR, "no dispatch send"); } return TS_FAILED; } /* only set timeout if enabled for this block */ if (ctxt->block_timeout) { ctxt->timer_msg.type = TFTP_TIMEOUT_MSG; xtimer_set_msg(&(ctxt->timer), ctxt->block_timeout, &(ctxt->timer_msg), thread_getpid()); DEBUG("tftp: set timeout %" PRIu32 " ms\n", ctxt->block_timeout / MS_IN_USEC); } return TS_BUSY; }