66static struct raw_pcb *raw_pcbs;
69raw_input_local_match(
struct raw_pcb *pcb, u8_t broadcast)
74 if ((pcb->netif_idx != NETIF_NO_INDEX) &&
75 (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
79#if LWIP_IPV4 && LWIP_IPV6
81 if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
82#if IP_SOF_BROADCAST_RECV
97#if IP_SOF_BROADCAST_RECV
101 if (ip4_addr_isany(ip_2_ip4(&pcb->local_ip))) {
108 if (ip_addr_isany(&pcb->local_ip) ||
135raw_input(
struct pbuf *p,
struct netif *inp)
137 struct raw_pcb *pcb, *prev;
139 raw_input_state_t ret = RAW_INPUT_NONE;
150 proto = IP6H_NEXTH(ip6hdr);
158 proto = IPH_PROTO((
struct ip_hdr *)p->payload);
166 while (pcb != NULL) {
167 if ((pcb->protocol == proto) && raw_input_local_match(pcb, broadcast) &&
168 (((pcb->flags & RAW_FLAGS_CONNECTED) == 0) ||
171 if (pcb->recv != NULL) {
174 void *old_payload = p->payload;
176 ret = RAW_INPUT_DELIVERED;
185 prev->next = pcb->next;
186 pcb->next = raw_pcbs;
189 return RAW_INPUT_EATEN;
192 LWIP_ASSERT(
"raw pcb recv callback altered pbuf payload pointer without eating packet",
193 p->payload == old_payload);
221raw_bind(
struct raw_pcb *pcb,
const ip_addr_t *ipaddr)
224 if ((pcb == NULL) || (ipaddr == NULL)) {
227 ip_addr_set_ipaddr(&pcb->local_ip, ipaddr);
228#if LWIP_IPV6 && LWIP_IPV6_SCOPES
232 if (IP_IS_V6(&pcb->local_ip) &&
233 ip6_addr_lacks_zone(ip_2_ip6(&pcb->local_ip), IP6_UNKNOWN)) {
234 ip6_addr_select_zone(ip_2_ip6(&pcb->local_ip), ip_2_ip6(&pcb->local_ip));
253raw_bind_netif(
struct raw_pcb *pcb,
const struct netif *
netif)
257 pcb->netif_idx = netif_get_index(
netif);
259 pcb->netif_idx = NETIF_NO_INDEX;
278raw_connect(
struct raw_pcb *pcb,
const ip_addr_t *ipaddr)
281 if ((pcb == NULL) || (ipaddr == NULL)) {
284 ip_addr_set_ipaddr(&pcb->remote_ip, ipaddr);
285#if LWIP_IPV6 && LWIP_IPV6_SCOPES
288 if (IP_IS_V6(&pcb->remote_ip) &&
289 ip6_addr_lacks_zone(ip_2_ip6(&pcb->remote_ip), IP6_UNKNOWN)) {
290 ip6_addr_select_zone(ip_2_ip6(&pcb->remote_ip), ip_2_ip6(&pcb->local_ip));
293 raw_set_flags(pcb, RAW_FLAGS_CONNECTED);
304raw_disconnect(
struct raw_pcb *pcb)
308#if LWIP_IPV4 && LWIP_IPV6
309 if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
310 ip_addr_copy(pcb->remote_ip, *IP_ANY_TYPE);
313 ip_addr_set_any(IP_IS_V6_VAL(pcb->remote_ip), &pcb->remote_ip);
314#if LWIP_IPV4 && LWIP_IPV6
317 pcb->netif_idx = NETIF_NO_INDEX;
319 raw_clear_flags(pcb, RAW_FLAGS_CONNECTED);
334raw_recv(
struct raw_pcb *pcb, raw_recv_fn recv,
void *recv_arg)
339 pcb->recv_arg = recv_arg;
354raw_sendto(
struct raw_pcb *pcb,
struct pbuf *p,
const ip_addr_t *ipaddr)
357 const ip_addr_t *src_ip;
359 if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
365 if (pcb->netif_idx != NETIF_NO_INDEX) {
368#if LWIP_MULTICAST_TX_OPTIONS
370 if (ip_addr_ismulticast(ipaddr)) {
380 netif = ip_route(&pcb->local_ip, ipaddr);
391 if (ip_addr_isany(&pcb->local_ip) || ip_addr_ismulticast(&pcb->local_ip)) {
393 src_ip = ip_netif_get_local_ip(
netif, ipaddr);
395 if (src_ip == NULL) {
401 src_ip = &pcb->local_ip;
404 return raw_sendto_if_src(pcb, p, ipaddr,
netif, src_ip);
421raw_sendto_if_src(
struct raw_pcb *pcb,
struct pbuf *p,
const ip_addr_t *dst_ip,
431 if ((pcb == NULL) || (dst_ip == NULL) || (
netif == NULL) || (src_ip == NULL) ||
432 !IP_ADDR_PCB_VERSION_MATCH(pcb, src_ip) || !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) {
437#if LWIP_IPV4 && LWIP_IPV6
438 IP_IS_V6(dst_ip) ? IP6_HLEN : IP_HLEN);
447 if (pcb->flags & RAW_FLAGS_HDRINCL) {
450 if (p->len < header_size) {
454 NETIF_SET_HINTS(
netif, &pcb->netif_hints);
455 err = ip_output_if_hdrincl(p, src_ip, dst_ip,
netif);
456 NETIF_RESET_HINTS(
netif);
461 if ((u16_t)(p->tot_len + header_size) < p->tot_len) {
473 if (p->tot_len != 0) {
478 LWIP_DEBUGF(
RAW_DEBUG, (
"raw_sendto: added header pbuf %p before given pbuf %p\n", (
void *)q, (
void *)p));
483 LWIP_ASSERT(
"Can't restore header we just removed!", 0);
489 if (IP_IS_V4(dst_ip)) {
503#if LWIP_MULTICAST_TX_OPTIONS
504 if (((pcb->flags & RAW_FLAGS_MULTICAST_LOOP) != 0) && ip_addr_ismulticast(dst_ip)) {
512 if (IP_IS_V6(dst_ip) && pcb->chksum_reqd) {
513 u16_t chksum = ip6_chksum_pseudo(p, pcb->protocol, p->tot_len, ip_2_ip6(src_ip), ip_2_ip6(dst_ip));
514 LWIP_ASSERT(
"Checksum must fit into first pbuf", p->len >= (pcb->chksum_offset + 2));
515 SMEMCPY(((u8_t *)p->payload) + pcb->chksum_offset, &chksum,
sizeof(u16_t));
520#if LWIP_MULTICAST_TX_OPTIONS
521 ttl = (ip_addr_ismulticast(dst_ip) ? raw_get_multicast_ttl(pcb) : pcb->ttl);
526 NETIF_SET_HINTS(
netif, &pcb->netif_hints);
527 err = ip_output_if(q, src_ip, dst_ip, ttl, pcb->tos, pcb->protocol,
netif);
528 NETIF_RESET_HINTS(
netif);
547raw_send(
struct raw_pcb *pcb,
struct pbuf *p)
549 return raw_sendto(pcb, p, &pcb->remote_ip);
562raw_remove(
struct raw_pcb *pcb)
564 struct raw_pcb *pcb2;
567 if (raw_pcbs == pcb) {
569 raw_pcbs = raw_pcbs->next;
572 for (pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
574 if (pcb2->next != NULL && pcb2->next == pcb) {
576 pcb2->next = pcb->next;
607 memset(pcb, 0,
sizeof(
struct raw_pcb));
608 pcb->protocol = proto;
610#if LWIP_MULTICAST_TX_OPTIONS
611 raw_set_multicast_ttl(pcb,
RAW_TTL);
614 pcb->next = raw_pcbs;
636raw_new_ip_type(u8_t type, u8_t proto)
640 pcb = raw_new(proto);
641#if LWIP_IPV4 && LWIP_IPV6
643 IP_SET_TYPE_VAL(pcb->local_ip, type);
644 IP_SET_TYPE_VAL(pcb->remote_ip, type);
657void raw_netif_ip_addr_changed(
const ip_addr_t *old_addr,
const ip_addr_t *new_addr)
659 struct raw_pcb *rpcb;
661 if (!ip_addr_isany(old_addr) && !ip_addr_isany(new_addr)) {
662 for (rpcb = raw_pcbs; rpcb != NULL; rpcb = rpcb->next) {
664 if (ip_addr_eq(&rpcb->local_ip, old_addr)) {
667 ip_addr_copy(rpcb->local_ip, *new_addr);
#define LWIP_UNUSED_ARG(x)
#define LWIP_DBG_LEVEL_SERIOUS
#define LWIP_DBG_LEVEL_WARNING
#define LWIP_ASSERT_CORE_LOCKED()
#define SMEMCPY(dst, src, len)
struct netif * netif_get_by_index(u8_t idx)
void pbuf_chain(struct pbuf *h, struct pbuf *t)
u8 pbuf_free(struct pbuf *p)
#define ip_get_option(pcb, opt)
#define ip_current_src_addr()
#define ip_current_dest_addr()
#define ip_current_netif()
void * memp_malloc(memp_t type)
void memp_free(memp_t type, void *mem)
u8_t pbuf_add_header(struct pbuf *p, size_t header_size_increment)
u8_t pbuf_remove_header(struct pbuf *p, size_t header_size)
#define PBUF_FLAG_MCASTLOOP
#define IP_HDR_GET_VERSION(ptr)