/* Transport layer */ MOCKABLE int32_t pico_transport_receive(struct pico_frame *f, uint8_t proto) { int32_t ret = -1; switch (proto) { #ifdef PICO_SUPPORT_ICMP4 case PICO_PROTO_ICMP4: ret = pico_enqueue(pico_proto_icmp4.q_in, f); break; #endif #ifdef PICO_SUPPORT_ICMP6 case PICO_PROTO_ICMP6: ret = pico_enqueue(pico_proto_icmp6.q_in, f); break; #endif #if defined(PICO_SUPPORT_IGMP) && defined(PICO_SUPPORT_MCAST) case PICO_PROTO_IGMP: ret = pico_enqueue(pico_proto_igmp.q_in, f); break; #endif #ifdef PICO_SUPPORT_UDP case PICO_PROTO_UDP: ret = pico_enqueue(pico_proto_udp.q_in, f); break; #endif #ifdef PICO_SUPPORT_TCP case PICO_PROTO_TCP: ret = pico_enqueue(pico_proto_tcp.q_in, f); break; #endif default: /* Protocol not available */ dbg("pkt: no such protocol (%d)\n", proto); pico_notify_proto_unreachable(f); pico_frame_discard(f); ret = -1; } return ret; }
int pico_network_receive(struct pico_frame *f) { if (0) {} #ifdef PICO_SUPPORT_IPV4 else if (IS_IPV4(f)) { pico_enqueue(pico_proto_ipv4.q_in, f); } #endif #ifdef PICO_SUPPORT_IPV6 else if (IS_IPV6(f)) { pico_enqueue(pico_proto_ipv6.q_in, f); } #endif else { dbg("Network not found.\n"); pico_frame_discard(f); return -1; } return f->buffer_len; }
static int32_t pico_ipv6_ethernet_receive(struct pico_frame *f) { if (IS_IPV6(f)) { pico_enqueue(pico_proto_ipv6.q_in, f); } else { /* Wrong version for link layer type */ pico_frame_discard(f); return -1; } return (int32_t)f->buffer_len; }
static int32_t pico_ipv4_ethernet_receive(struct pico_frame *f) { if (IS_IPV4(f)) { pico_enqueue(pico_proto_ipv4.q_in, f); } else { (void)pico_icmp4_param_problem(f, 0); pico_frame_discard(f); return -1; } return (int32_t)f->buffer_len; }
static int pico_ipv4_process_bcast_in(struct pico_frame *f) { struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr; #ifdef PICO_SUPPORT_UDP if (pico_ipv4_is_broadcast(hdr->dst.addr) && (hdr->proto == PICO_PROTO_UDP)) { /* Receiving UDP broadcast datagram */ f->flags |= PICO_FRAME_FLAG_BCAST; pico_enqueue(pico_proto_udp.q_in, f); return 1; } #endif #ifdef PICO_SUPPORT_ICMP4 if (pico_ipv4_is_broadcast(hdr->dst.addr) && (hdr->proto == PICO_PROTO_ICMP4)) { /* Receiving ICMP4 bcast packet */ f->flags |= PICO_FRAME_FLAG_BCAST; pico_enqueue(pico_proto_icmp4.q_in, f); return 1; } #endif return 0; }
static int pico_ipv4_process_mcast_in(struct pico_frame *f) { struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr; if (pico_ipv4_is_multicast(hdr->dst.addr)) { #ifdef PICO_SUPPORT_MCAST /* Receiving UDP multicast datagram TODO set f->flags? */ if (hdr->proto == PICO_PROTO_IGMP) { ip_mcast_dbg("MCAST: received IGMP message\n"); pico_transport_receive(f, PICO_PROTO_IGMP); return 1; } else if ((pico_ipv4_mcast_filter(f) == 0) && (hdr->proto == PICO_PROTO_UDP)) { pico_enqueue(pico_proto_udp.q_in, f); return 1; } #endif pico_frame_discard(f); return 1; } return 0; }
return -1; /* Association to the device that just received the frame. */ f->dev = dev; /* Setup the start pointer, lenght. */ f->start = f->buffer; f->len = f->buffer_len; if (f->len > 8) { uint32_t mid_frame = (f->buffer_len >> 2) << 1; mid_frame -= (mid_frame % 4); pico_rand_feed(*(uint32_t*)(f->buffer + mid_frame)); } memcpy(f->buffer, buffer, len); ret = pico_enqueue(dev->q_in, f); if (ret <= 0) { pico_frame_discard(f); } return ret; } int32_t pico_sendto_dev(struct pico_frame *f) { if (!f->dev) { pico_frame_discard(f); return -1; } else { if (f->len > 8) { uint32_t mid_frame = (f->buffer_len >> 2) << 1;