void netif_create_ip4_linklocal_address(struct netif * netif) { #if 1 ip_addr_t linklocal; ip_addr_t linklocal_mask; ip4_addr_t addr = {0}; /* Link-local prefix and mask. */ IP4_ADDR(ip_2_ip4(&linklocal), 169, 254, 0, 0); IP4_ADDR(ip_2_ip4(&linklocal_mask), 255, 255, 0, 0); if (!ip4_addr_netcmp( ip_2_ip4(&linklocal), ip_2_ip4(&netif->link_local_addr), ip_2_ip4(&linklocal_mask) ) && !ip4_addr_isany(ip_2_ip4(&netif->ip_addr)) ) { IP4_ADDR( ip_2_ip4(&netif->link_local_addr), 169, 254, ip4_addr3( ip_2_ip4(&netif->ip_addr) ) , ip4_addr4( ip_2_ip4(&netif->ip_addr) ) ); return; } while ( !(addr.addr) || !ip4_addr4(&addr) ) //os_get_random((unsigned char *)&addr, sizeof(addr)); addr.addr = LWIP_RAND(); if ( ip_2_ip4(&netif->netmask)->addr > IP_CLASSB_NET && !ip4_addr_isany( ip_2_ip4(&netif->ip_addr) )) { // random host address IP4_ADDR( ip_2_ip4(&netif->link_local_addr), 169, 254, ip4_addr3( ip_2_ip4(&netif->ip_addr)) , ip4_addr4(&addr)); } else { IP4_ADDR( ip_2_ip4(&netif->link_local_addr), 169, 254, ip4_addr3(&addr), ip4_addr4(&addr) ); } #endif }
/** * Determine if an address is a broadcast address on a network interface * * @param addr address to be checked * @param netif the network interface against which the address is checked * @return returns non-zero if the address is a broadcast address */ u8_t ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif) { ip4_addr_t ipaddr; ip4_addr_set_u32(&ipaddr, addr); /* all ones (broadcast) or all zeroes (old skool broadcast) */ if ((~addr == IPADDR_ANY) || (addr == IPADDR_ANY)) { return 1; /* no broadcast support on this network interface? */ } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) { /* the given address cannot be a broadcast address * nor can we check against any broadcast addresses */ return 0; /* address matches network interface address exactly? => no broadcast */ } else if (addr == ip4_addr_get_u32(netif_ip4_addr(netif))) { return 0; /* on the same (sub) network... */ } else if (ip4_addr_netcmp(&ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) /* ...and host identifier bits are all ones? =>... */ && ((addr & ~ip4_addr_get_u32(netif_ip4_netmask(netif))) == (IPADDR_BROADCAST & ~ip4_addr_get_u32(netif_ip4_netmask(netif))))) { /* => network broadcast address */ return 1; } else { return 0; } }
/** Common code to see if the current input packet matches the pcb * (current input packet is accessed via ip(4/6)_current_* macros) * * @param pcb pcb to check * @param inp network interface on which the datagram was received (only used for IPv4) * @param broadcast 1 if his is an IPv4 broadcast (global or subnet-only), 0 otherwise (only used for IPv4) * @return 1 on match, 0 otherwise */ static u8_t ESP_IRAM_ATTR udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast) { LWIP_UNUSED_ARG(inp); /* in IPv6 only case */ LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */ /* Dual-stack: PCBs listening to any IP type also listen to any IP address */ if(IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { #if LWIP_IPV4 && IP_SOF_BROADCAST_RECV if((broadcast != 0) && !ip_get_option(pcb, SOF_BROADCAST)) { return 0; } #endif /* LWIP_IPV4 && IP_SOF_BROADCAST_RECV */ return 1; } /* Only need to check PCB if incoming IP version matches PCB IP version */ if(IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ip_current_dest_addr())) { LWIP_ASSERT("UDP PCB: inconsistent local/remote IP versions", IP_IS_V6_VAL(pcb->local_ip) == IP_IS_V6_VAL(pcb->remote_ip)); #if LWIP_IPV4 /* Special case: IPv4 broadcast: all or broadcasts in my subnet * Note: broadcast variable can only be 1 if it is an IPv4 broadcast */ if(broadcast != 0) { #if IP_SOF_BROADCAST_RECV if(ip_get_option(pcb, SOF_BROADCAST)) #endif /* IP_SOF_BROADCAST_RECV */ { if(ip4_addr_isany(ip_2_ip4(&pcb->local_ip)) || ((ip4_current_dest_addr()->addr == IPADDR_BROADCAST)) || ip4_addr_netcmp(ip_2_ip4(&pcb->local_ip), ip4_current_dest_addr(), netif_ip4_netmask(inp))) { return 1; } } } else #endif /* LWIP_IPV4 */ /* Handle IPv4 and IPv6: all, multicast or exact match */ if(ip_addr_isany(&pcb->local_ip) || #if LWIP_IPV6_MLD (ip_current_is_v6() && ip6_addr_ismulticast(ip6_current_dest_addr())) || #endif /* LWIP_IPV6_MLD */ #if LWIP_IGMP (!ip_current_is_v6() && ip4_addr_ismulticast(ip4_current_dest_addr())) || #endif /* LWIP_IGMP */ ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { return 1; } } return 0; }