int pico_frame_dst_is_unicast(struct pico_frame *f) { if (0) { return 0; } #ifdef PICO_SUPPORT_IPV4 if (IS_IPV4(f)) { struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *)f->net_hdr; if (pico_ipv4_is_multicast(hdr->dst.addr) || pico_ipv4_is_broadcast(hdr->dst.addr)) return 0; return 1; } #endif #ifdef PICO_SUPPORT_IPV6 if (IS_IPV6(f)) { struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *)f->net_hdr; if (pico_ipv6_is_multicast(hdr->dst.addr) || pico_ipv6_is_unspecified(hdr->dst.addr)) return 0; return 1; } #endif else return 0; }
static int destination_is_mcast(struct pico_frame *f) { if (!f) return 0; if (IS_IPV6(f)) return 0; #ifdef PICO_SUPPORT_IPV4 else { struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr; return pico_ipv4_is_multicast(hdr->dst.addr); } #endif return 0; }
void pre_init(void) { struct pico_ip4 netmask, ipaddr, gw, multicast, zero = {0}; pico_device_eth *pico_driver; memset(&io_ops, 0, sizeof(io_ops)); io_ops.dma_manager = (ps_dma_man_t) { .cookie = NULL, .dma_alloc_fn = malloc_dma_alloc, .dma_free_fn = malloc_dma_free, .dma_pin_fn = malloc_dma_pin, .dma_unpin_fn = malloc_dma_unpin, .dma_cache_op_fn = malloc_dma_cache_op }; /* Initialise the PicoTCP stack */ pico_stack_init(); /* Create a driver. This utilises preallocated buffers, backed up by malloc above */ pico_driver = pico_eth_create_no_malloc("eth0", ethdriver_init, NULL, io_ops, &_picotcp_driver); assert(pico_driver); pico_string_to_ipv4("0.0.0.0", &gw.addr); pico_string_to_ipv4(server_ip_addr, &ipaddr.addr); pico_string_to_ipv4(multicast_addr, &multicast.addr); pico_string_to_ipv4("255.255.255.0", &netmask.addr); pico_ipv4_link_add(pico_driver, ipaddr, netmask); pico_ipv4_route_add(zero, zero, gw, 1, NULL); if (pico_ipv4_is_multicast(multicast.addr)) { ZF_LOGE("Multicast not yet implemented\n"); // PicoTCP usually deals with multicast at the socket layer, using pico_socket_setoption. // It can be done at the igmp level too by using igmp_state_change. See the picoTCP documentation // Eg: pico_igmp_state_change(&ipaddr, &multicast, .... ); } /* Start the timer for tcp */ // TCP runs off a tick for handling events and timeouts. timer_periodic(0, NS_IN_MS * PICO_TICK_MS); start_tcpecho(); }
int pico_ipv4_is_valid_src(uint32_t address, struct pico_device *dev) { if (pico_ipv4_is_broadcast(address)) { dbg("Source is a broadcast address, discard packet\n"); return 0; } else if ( pico_ipv4_is_multicast(address)) { dbg("Source is a multicast address, discard packet\n"); return 0; } else if (pico_ipv4_is_invalid_loopback(address, dev)) { dbg("Source is a loopback address, discard packet\n"); return 0; } else { #ifdef PICO_SUPPORT_AODV union pico_address src; src.ip4.addr = address; pico_aodv_refresh(&src); #endif return 1; } }
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; }