/**@brief Sends UDP data in Request format described in description above. * * @details Sends UDP data in Request of size 8 in format described in description above. */ static void udp_data_send(void) { struct pbuf * p_send_buf; uint8_t * p_udp_data; APPL_LOG ("[APPL]: >> UDP Data Tx\r\n"); m_sequence_number++; p_send_buf = pbuf_alloc (PBUF_TRANSPORT, UDP_DATA_SIZE, PBUF_RAM); ASSERT(p_send_buf != NULL); p_send_buf->len = UDP_DATA_SIZE; p_udp_data = p_send_buf->payload; p_udp_data[0] = (uint8_t )((m_sequence_number >> 24) & 0x000000FF); p_udp_data[1] = (uint8_t )((m_sequence_number >> 16) & 0x000000FF); p_udp_data[2] = (uint8_t )((m_sequence_number >> 8) & 0x000000FF); p_udp_data[3] = (uint8_t )(m_sequence_number & 0x000000FF); p_udp_data[4] = 'P'; p_udp_data[5] = 'i'; p_udp_data[6] = 'n'; p_udp_data[7] = 'g'; //Send UDP Data packet. err_t err = udp_sendto_ip6(mp_udp_port, p_send_buf, &m_remote_addr, UDP_SERVER_PORT); if (err != ERR_OK) { APPL_LOG ("[APPL]: Failed to send UDP packet, reason %d\r\n", err); m_sequence_number--; } APPL_DUMP(p_send_buf->payload,p_send_buf->len); APPL_LOG ("[APPL]: << UDP Data Tx, %d len %d\r\n", err, p_send_buf->len); UNUSED_VARIABLE(pbuf_free(p_send_buf)); }
static void dhcp6ds_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip6_addr_t *addr, u16_t port) { u8_t msg_header[4]; unsigned int msg_type, msg_tid; int copied; size_t roff; struct pbuf *q; err_t error; LWIP_UNUSED_ARG(arg); LWIP_ASSERT1(p != NULL); copied = pbuf_copy_partial(p, msg_header, sizeof(msg_header), 0); if (copied != sizeof(msg_header)) { DPRINTF(("%s: message header truncated\n", __func__)); pbuf_free(p); return; } pbuf_header(p, -(s16_t)sizeof(msg_header)); msg_type = msg_header[0]; msg_tid = (msg_header[1] << 16) | (msg_header[2] << 8) | msg_header[3]; DPRINTF(("%s: type %u, tid 0x%6x\n", __func__, msg_type, msg_tid)); if (msg_type != DHCP6_INFORMATION_REQUEST) { /* TODO:? RELAY_FORW */ pbuf_free(p); return; } roff = 0; msg_header[0] = DHCP6_REPLY; memcpy(dhcp6ds_reply_buf + roff, msg_header, sizeof(msg_header)); roff += sizeof(msg_header); /* loop over options */ while (p->tot_len > 0) { u16_t opt, optlen; /* fetch option code */ copied = pbuf_copy_partial(p, &opt, sizeof(opt), 0); if (copied != sizeof(opt)) { DPRINTF(("%s: option header truncated\n", __func__)); pbuf_free(p); return; } pbuf_header(p, -(s16_t)sizeof(opt)); opt = ntohs(opt); /* fetch option length */ copied = pbuf_copy_partial(p, &optlen, sizeof(optlen), 0); if (copied != sizeof(optlen)) { DPRINTF(("%s: option %u length truncated\n", __func__, opt)); pbuf_free(p); return; } pbuf_header(p, -(s16_t)sizeof(optlen)); optlen = ntohs(optlen); /* enough data? */ if (optlen > p->tot_len) { DPRINTF(("%s: option %u truncated: expect %u, got %u\n", __func__, opt, optlen, p->tot_len)); pbuf_free(p); return; } DPRINTF2(("%s: option %u length %u\n", __func__, opt, optlen)); if (opt == DHCP6_OPTION_CLIENTID) { u16_t s; /* "A DUID can be no more than 128 octets long (not including the type code)." */ if (optlen > 130) { DPRINTF(("%s: client DUID too long: %u\n", __func__, optlen)); pbuf_free(p); return; } s = PP_HTONS(DHCP6_OPTION_CLIENTID); memcpy(dhcp6ds_reply_buf + roff, &s, sizeof(s)); roff += sizeof(s); s = ntohs(optlen); memcpy(dhcp6ds_reply_buf + roff, &s, sizeof(s)); roff += sizeof(s); pbuf_copy_partial(p, dhcp6ds_reply_buf + roff, optlen, 0); roff += optlen; } else if (opt == DHCP6_OPTION_ORO) { u16_t *opts; int i, nopts; if (optlen % 2 != 0) { DPRINTF2(("%s: Option Request of odd length\n", __func__)); goto bad_oro; } nopts = optlen / 2; opts = (u16_t *)malloc(optlen); if (opts == NULL) { DPRINTF2(("%s: failed to allocate space for Option Request\n", __func__)); goto bad_oro; } pbuf_copy_partial(p, opts, optlen, 0); for (i = 0; i < nopts; ++i) { opt = ntohs(opts[i]); DPRINTF2(("> request option %u\n", opt)); }; free(opts); bad_oro: /* empty */; } pbuf_header(p, -optlen); /* go to next option */ } pbuf_free(p); /* done */ memcpy(dhcp6ds_reply_buf + roff, dhcp6ds_serverid, sizeof(dhcp6ds_serverid)); roff += sizeof(dhcp6ds_serverid); memcpy(dhcp6ds_reply_buf + roff, dhcp6ds_dns, sizeof(dhcp6ds_dns)); roff += sizeof(dhcp6ds_dns); q = pbuf_alloc(PBUF_RAW, roff, PBUF_RAM); if (q == NULL) { DPRINTF(("%s: pbuf_alloc(%d) failed\n", __func__, (int)roff)); return; } error = pbuf_take(q, dhcp6ds_reply_buf, roff); if (error != ERR_OK) { DPRINTF(("%s: pbuf_take(%d) failed: %s\n", __func__, (int)roff, proxy_lwip_strerr(error))); pbuf_free(q); return; } error = udp_sendto_ip6(pcb, q, addr, port); if (error != ERR_OK) { DPRINTF(("%s: udp_sendto failed: %s\n", __func__, proxy_lwip_strerr(error))); } pbuf_free(q); }