/** * Change the IP address of a network interface * * @param netif the network interface to change * @param ipaddr the new IP address * * @note call netif_set_addr() if you also want to change netmask and * default gateway */ void netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr) { ip4_addr_t new_addr = (ipaddr ? *ipaddr : *IP4_ADDR_ANY); /* address is actually being changed? */ if (ip4_addr_cmp(&new_addr, netif_ip4_addr(netif)) == 0) { LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); #if LWIP_TCP tcp_netif_ipv4_addr_changed(netif_ip4_addr(netif), ipaddr); #endif /* LWIP_TCP */ #if LWIP_UDP udp_netif_ipv4_addr_changed(netif_ip4_addr(netif), ipaddr); #endif /* LWIP_UDP */ mib2_remove_ip4(netif); mib2_remove_route_ip4(0, netif); /* set new IP address to netif */ ip4_addr_set(ip_2_ip4(&netif->ip_addr), ipaddr); IP_SET_TYPE_VAL(netif->ip_addr, IPADDR_TYPE_V4); mib2_add_ip4(netif); mib2_add_route_ip4(0, netif); netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4); NETIF_STATUS_CALLBACK(netif); } LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", netif->name[0], netif->name[1], ip4_addr1_16(netif_ip4_addr(netif)), ip4_addr2_16(netif_ip4_addr(netif)), ip4_addr3_16(netif_ip4_addr(netif)), ip4_addr4_16(netif_ip4_addr(netif)))); }
/** * Search for a specific igmp group and create a new one if not found- * * @param ifp the network interface for which to look * @param addr the group ip address to search * @return a struct igmp_group*, * NULL on memory error. */ struct igmp_group * igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr) { struct igmp_group *group; /* Search if the group already exists */ group = igmp_lookfor_group(ifp, addr); if (group != NULL) { /* Group already exists. */ return group; } /* Group doesn't exist yet, create a new one */ group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP); if (group != NULL) { group->netif = ifp; ip4_addr_set(&(group->group_address), addr); group->timer = 0; /* Not running */ group->group_state = IGMP_GROUP_NON_MEMBER; group->last_reporter_flag = 0; group->use = 0; group->next = igmp_group_list; igmp_group_list = group; } LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group?"":"impossible to "))); ip4_addr_debug_print(IGMP_DEBUG, addr); LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void*)ifp)); return group; }
/** * Change the IP address of a network interface * * @param netif the network interface to change * @param ipaddr the new IP address * * @note call netif_set_addr() if you also want to change netmask and * default gateway */ void netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr) { ip4_addr_t new_addr = (ipaddr ? *ipaddr : *IP4_ADDR_ANY); /* address is actually being changed? */ if (ip4_addr_cmp(&new_addr, &(netif->ip_addr)) == 0) { LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); #if LWIP_TCP tcp_netif_ipv4_addr_changed(&netif->ip_addr, ipaddr); #endif /* LWIP_TCP */ #if LWIP_UDP udp_netif_ipv4_addr_changed(&netif->ip_addr, ipaddr); #endif /* LWIP_UDP */ snmp_delete_ipaddridx_tree(netif); snmp_delete_iprteidx_tree(0, netif); /* set new IP address to netif */ ip4_addr_set(&(netif->ip_addr), ipaddr); snmp_insert_ipaddridx_tree(netif); snmp_insert_iprteidx_tree(0, netif); netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4); NETIF_STATUS_CALLBACK(netif); } LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", netif->name[0], netif->name[1], ip4_addr1_16(&netif->ip_addr), ip4_addr2_16(&netif->ip_addr), ip4_addr3_16(&netif->ip_addr), ip4_addr4_16(&netif->ip_addr))); }
/** * Change the default gateway for a network interface * * @param netif the network interface to change * @param gw the new default gateway * * @note call netif_set_addr() if you also want to change ip address and netmask */ void netif_set_gw(struct netif *netif, const ip4_addr_t *gw) { ip4_addr_set(&(netif->gw), gw); LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", netif->name[0], netif->name[1], ip4_addr1_16(&netif->gw), ip4_addr2_16(&netif->gw), ip4_addr3_16(&netif->gw), ip4_addr4_16(&netif->gw))); }
/** * Change the default gateway for a network interface * * @param netif the network interface to change * @param gw the new default gateway * * @note call netif_set_addr() if you also want to change ip address and netmask */ void netif_set_gw(struct netif *netif, const ip4_addr_t *gw) { ip4_addr_set(ip_2_ip4(&netif->gw), gw); IP_SET_TYPE_VAL(netif->gw, IPADDR_TYPE_V4); LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", netif->name[0], netif->name[1], ip4_addr1_16(netif_ip4_gw(netif)), ip4_addr2_16(netif_ip4_gw(netif)), ip4_addr3_16(netif_ip4_gw(netif)), ip4_addr4_16(netif_ip4_gw(netif)))); }
/** * Change the netmask of a network interface * * @param netif the network interface to change * @param netmask the new netmask * * @note call netif_set_addr() if you also want to change ip address and * default gateway */ void netif_set_netmask(struct netif *netif, const ip4_addr_t *netmask) { snmp_delete_iprteidx_tree(0, netif); /* set new netmask to netif */ ip4_addr_set(&(netif->netmask), netmask); snmp_insert_iprteidx_tree(0, netif); LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", netif->name[0], netif->name[1], ip4_addr1_16(&netif->netmask), ip4_addr2_16(&netif->netmask), ip4_addr3_16(&netif->netmask), ip4_addr4_16(&netif->netmask))); }
/** * Change the netmask of a network interface * * @param netif the network interface to change * @param netmask the new netmask * * @note call netif_set_addr() if you also want to change ip address and * default gateway */ void netif_set_netmask(struct netif *netif, const ip4_addr_t *netmask) { mib2_remove_route_ip4(0, netif); /* set new netmask to netif */ ip4_addr_set(ip_2_ip4(&netif->netmask), netmask); IP_SET_TYPE_VAL(netif->netmask, IPADDR_TYPE_V4); mib2_add_route_ip4(0, netif); LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", netif->name[0], netif->name[1], ip4_addr1_16(netif_ip4_netmask(netif)), ip4_addr2_16(netif_ip4_netmask(netif)), ip4_addr3_16(netif_ip4_netmask(netif)), ip4_addr4_16(netif_ip4_netmask(netif)))); }
/** * Search for a specific igmp group and create a new one if not found- * * @param ifp the network interface for which to look * @param addr the group ip address to search * @return a struct igmp_group*, * NULL on memory error. */ struct igmp_group * igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr) { struct igmp_group *group; struct igmp_group *list_head = netif_igmp_data(ifp); /* Search if the group already exists */ group = igmp_lookfor_group(ifp, addr); if (group != NULL) { /* Group already exists. */ return group; } /* Group doesn't exist yet, create a new one */ group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP); if (group != NULL) { ip4_addr_set(&(group->group_address), addr); group->timer = 0; /* Not running */ group->group_state = IGMP_GROUP_NON_MEMBER; group->last_reporter_flag = 0; group->use = 0; /* Ensure allsystems group is always first in list */ if (list_head == NULL) { /* this is the first entry in linked list */ LWIP_ASSERT("igmp_lookup_group: first group must be allsystems", (ip4_addr_cmp(addr, &allsystems) != 0)); group->next = NULL; netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, group); } else { /* append _after_ first entry */ LWIP_ASSERT("igmp_lookup_group: all except first group must not be allsystems", (ip4_addr_cmp(addr, &allsystems) == 0)); group->next = list_head->next; list_head->next = group; } } LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group?"":"impossible to "))); ip4_addr_debug_print(IGMP_DEBUG, addr); LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void*)ifp)); return group; }
/** * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache * send out queued IP packets. Updates cache with snooped address pairs. * * Should be called for incoming ARP packets. The pbuf in the argument * is freed by this function. * * @param netif The lwIP network interface on which the ARP packet pbuf arrived. * @param pbuf The ARP packet that arrived on netif. Is freed by this function. * @param ethaddr Ethernet address of netif. * * @return NULL * * @see pbuf_free() */ void etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) { struct etharp_hdr *hdr; /* these are aligned properly, whereas the ARP header fields might not be */ struct ip_addr_list *el; struct ip_addr v4dipaddr,v4sipaddr; u8_t i; LWIP_ASSERT("netif != NULL", netif != NULL); /* drop short ARP packets */ if (p->tot_len < sizeof(struct etharp_hdr)) { LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet dropped, too short (%d/%d)\n", p->tot_len, sizeof(struct etharp_hdr))); pbuf_free(p); return; } hdr = p->payload; IP64_CONV(&v4dipaddr,&(hdr->dipaddr)); IP64_CONV(&v4sipaddr,&(hdr->sipaddr)); el= ip_addr_list_find(netif->addrs,&v4dipaddr,NULL); /* ARP message directed to us? */ if (el != NULL) { /* add IP address in ARP cache; assume requester wants to talk to us. * can result in directly sending the queued packets for this host. */ update_arp_entry(netif, &v4sipaddr, &(hdr->shwaddr), ETHARP_TRY_HARD); /* ARP message not directed to us? */ } else { /* update the source IP address in the cache, if present */ update_arp_entry(netif, &v4sipaddr, &(hdr->shwaddr), 0); } /* now act on the message itself */ switch (htons(hdr->opcode)) { /* ARP request? */ case ARP_REQUEST: /* ARP request. If it asked for our address, we send out a * reply. In any case, we time-stamp any existing ARP entry, * and possiby send out an IP packet that was queued on it. */ LWIP_DEBUGF (ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n")); /* ARP request for our address? */ if (el != NULL) { LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n")); /* re-use pbuf to send ARP reply */ hdr->opcode = htons(ARP_REPLY); /*hdr->dipaddr = hdr->sipaddr; hdr->sipaddr = *(struct ip_addr2 *)&netif->ip_addr;*/ ip4_addr_set(&(hdr->dipaddr), &(hdr->sipaddr)); ip64_addr_set(&(hdr->sipaddr), &(el->ipaddr)); for(i = 0; i < netif->hwaddr_len; ++i) { hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i]; hdr->shwaddr.addr[i] = ethaddr->addr[i]; hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i]; hdr->ethhdr.src.addr[i] = ethaddr->addr[i]; } hdr->hwtype = htons(HWTYPE_ETHERNET); ARPH_HWLEN_SET(hdr, netif->hwaddr_len); hdr->proto = htons(ETHTYPE_IP); ARPH_PROTOLEN_SET(hdr, sizeof(struct ip4_addr)); hdr->ethhdr.type = htons(ETHTYPE_ARP); /* return ARP reply */ LINKOUTPUT(netif, p); /* we are not configured? */ } #if 0 else if (netif->ip_addr.addr == 0) { /* { for_us == 0 and netif->ip_addr.addr == 0 } */ LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n")); /* request was not directed to us */ } #endif else { /* { for_us == 0 and netif->ip_addr.addr != 0 } */ LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n")); } break; case ARP_REPLY: /* ARP reply. We already updated the ARP cache earlier. */ LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n")); #if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) /* DHCP wants to know about ARP replies from any host with an * IP address also offered to us by the DHCP server. We do not * want to take a duplicate IP address on a single network. * @todo How should we handle redundant (fail-over) interfaces? * */ ///dhcp_arp_reply(netif, &sipaddr); dhcp_arp_reply(netif, (struct ip4_addr *) &(hdr->sipaddr)); #endif break; default: LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %d\n", htons(hdr->opcode))); break; } /* free ARP packet */ pbuf_free(p); }