LwIP UDP部分常见函数精简

static u8_t
udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast)
{
  /* Dual-stack: PCBs listening to any IP type also listen to any IP address */
  if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
    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())) {
    /* 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 (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
    /* Handle IPv4 and IPv6: all or exact match */
    if (ip_addr_isany(&pcb->local_ip) || ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) {
      return 1;
    }
  }

  return 0;
}
/*在协议控制块中绑定本地IP地址和本地IP端口号*/
int udp_bind(struct udp_pcb *pcb, const in_addr_udp *ipaddr, u_short port) {
	struct udp_pcb *ipcb;
	u_char rebind;

	/* 不要将空指针(IPv4任何)传播给后续函数 */
	if (ipaddr == NULL) {
		ipaddr = IP4_ADDR_ANY;
	}

	/* still need to check for ipaddr == NULL in IPv6 only case */
	if ((pcb == NULL) || (ipaddr == NULL)
			|| !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
		return ERR_VAL;
	}

	rebind = 0;
	/* Check for double bind and rebind of the same pcb */
	for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
		/* is this UDP PCB already on active list? */
		if (pcb == ipcb) {
			rebind = 1;
			break;
		}
	}

	/* no port specified? */
	if (port == 0) {
		port = udp_new_port();
		if (port == 0) {
			/* no more ports available in local range */
			return ERR_USE;
		}
	} else {
		for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
			if (pcb != ipcb) {
				/* By default, we don't allow to bind to a port that any other udp
				 PCB is already bound to, unless *all* PCBs with that port have tha
				 REUSEADDR flag set. */
				{
					/* port matches that of PCB in list and REUSEADDR not set -> reject *//* IP address matches? */
					if ((ipcb->local_port == port)
							&& ip_addr_cmp(&ipcb->local_ip, ipaddr)) {
						return ERR_USE;
					}
				}
			}
		}
	}

	ip_addr_set_ipaddr(&pcb->local_ip, ipaddr);

	pcb->local_port = port;
	/* pcb not active yet? */
	if (rebind == 0) {
		/* place the PCB on the active list if not already there */
		pcb->next = udp_pcbs;
		udp_pcbs = pcb;
	}

	return ERR_OK;
} /*udp_bind()*/
static u16_t udp_new_port(void) {
	u16_t n = 0;
	struct udp_pcb *pcb;

	again: if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) {
		udp_port = UDP_LOCAL_PORT_RANGE_START;
	}
	/* Check all PCBs. */
	for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
		if (pcb->local_port == udp_port) {
			if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) {
				return 0;
			}
			goto again;
		}
	}
	return udp_port;
} /*udp_new_port()*/
上一篇:LWIP应用开发|IP协议原理


下一篇:LWIP应用开发|RAW API编程模型