// File: /workspace/github_c_makefile_star2_O1/FH0[P]tun_direct/lwip-2.1.2/src/core/tcp.c
// Function: tcp_bind
err_t
tcp_bind(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
{
  int i;
  int max_pcb_list = NUM_TCP_PCB_LISTS;
  struct tcp_pcb *cpcb;
#if LWIP_IPV6 && LWIP_IPV6_SCOPES
  ip_addr_t zoned_ipaddr;
#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */

  LWIP_ASSERT_CORE_LOCKED();

#if LWIP_IPV4
  /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */
  if (ipaddr == NULL) {
    ipaddr = IP4_ADDR_ANY;
  }
#else /* LWIP_IPV4 */
  LWIP_ERROR("tcp_bind: invalid ipaddr", ipaddr != NULL, return ERR_ARG);
#endif /* LWIP_IPV4 */

  LWIP_ERROR("tcp_bind: invalid pcb", pcb != NULL, return ERR_ARG);

  LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL);

#if SO_REUSE
  /* Unless the REUSEADDR flag is set,
     we have to check the pcbs in TIME-WAIT state, also.
     We do not dump TIME_WAIT pcb's; they can still be matched by incoming
     packets using both local and remote IP addresses and ports to distinguish.
   */
  if (ip_get_option(pcb, SOF_REUSEADDR)) {
    max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT;
  }
#endif /* SO_REUSE */

#if LWIP_IPV6 && LWIP_IPV6_SCOPES
  /* If the given IP address should have a zone but doesn't, assign one now.
   * This is legacy support: scope-aware callers should always provide properly
   * zoned source addresses. Do the zone selection before the address-in-use
   * check below; as such we have to make a temporary copy of the address. */
  if (IP_IS_V6(ipaddr) && ip6_addr_lacks_zone(ip_2_ip6(ipaddr), IP6_UNICAST)) {
    ip_addr_copy(zoned_ipaddr, *ipaddr);
    ip6_addr_select_zone(ip_2_ip6(&zoned_ipaddr), ip_2_ip6(&zoned_ipaddr));
    ipaddr = &zoned_ipaddr;
  }
#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */

  if (port == 0) {
    port = tcp_new_port();
    if (port == 0) {
      return ERR_BUF;
    }
  } else {
    /* Check if the address already is in use (on all lists) */
    for (i = 0; i < max_pcb_list; i++) {
      for (cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
        if (cpcb->local_port == port) {
#if SO_REUSE
          /* Omit checking for the same port if both pcbs have REUSEADDR set.
             For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in
             tcp_connect. */
          if (!ip_get_option(pcb, SOF_REUSEADDR) ||
              !ip_get_option(cpcb, SOF_REUSEADDR))
#endif /* SO_REUSE */
          {
            /* @todo: check accept_any_ip_version */
            if ((IP_IS_V6(ipaddr) == IP_IS_V6_VAL(cpcb->local_ip)) &&
                (ip_addr_isany(&cpcb->local_ip) ||
                 ip_addr_isany(ipaddr) ||
                 ip_addr_cmp(&cpcb->local_ip, ipaddr))) {
              return ERR_USE;
            }
          }
        }
      }
    }
  }

  if (!ip_addr_isany(ipaddr)
#if LWIP_IPV4 && LWIP_IPV6
      || (IP_GET_TYPE(ipaddr) != IP_GET_TYPE(&pcb->local_ip))
#endif /* LWIP_IPV4 && LWIP_IPV6 */
     ) {
    ip_addr_set(&pcb->local_ip, ipaddr);
  }
  pcb->local_port = port;
  TCP_REG(&tcp_bound_pcbs, pcb);
  LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));
  return ERR_OK;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0x20, %rsp
movl %edx, %ebp
movq %rdi, %rbx
testq %rsi, %rsi
jne 0x75c1
leaq 0xfdd7(%rip), %rsi      # 0x17398
testq %rbx, %rbx
je 0x781d
cmpl $0x0, 0x48(%rbx)
jne 0x7839
movb 0x14(%rsi), %cl
cmpb $0x6, %cl
jne 0x766e
movb 0x10(%rsi), %al
testb %al, %al
jne 0x766e
movl (%rsi), %edx
movl %edx, %edi
andl $0xc0ff, %edi           # imm = 0xC0FF
cmpl $0x80fe, %edi           # imm = 0x80FE
jne 0x766e
leaq 0x8(%rsp), %r14
movb %cl, 0x14(%r14)
movl %edx, (%r14)
movl 0x4(%rsi), %ecx
movl %ecx, 0x4(%r14)
movl 0x8(%rsi), %ecx
movl %ecx, 0x8(%r14)
movl 0xc(%rsi), %ecx
movl %ecx, 0xc(%r14)
movb %al, 0x10(%r14)
movq %r14, %rdi
movq %r14, %rsi
callq 0xfae4
testq %rax, %rax
je 0x7671
movl 0x8(%rsp), %ecx
movl %ecx, %edx
andl $0xc0ff, %edx           # imm = 0xC0FF
cmpl $0x80fe, %edx           # imm = 0x80FE
je 0x7660
andl $0x8fff, %ecx           # imm = 0x8FFF
cmpl $0x2ff, %ecx            # imm = 0x2FF
je 0x7660
cmpl $0x1ff, %ecx            # imm = 0x1FF
jne 0x7816
movb 0xee(%rax), %al
incb %al
movb %al, 0x18(%rsp)
jmp 0x7671
movq %rsi, %r14
testw %bp, %bp
je 0x7776
xorl %eax, %eax
leaq 0x156dd(%rip), %rcx     # 0x1cd60
movq (%rcx,%rax,8), %rdx
movq (%rdx), %rdx
testq %rdx, %rdx
je 0x7760
cmpw %bp, 0x4e(%rdx)
jne 0x7757
movb 0x14(%r14), %dil
movb 0x14(%rdx), %sil
cmpb $0x6, %sil
sete %r8b
cmpb $0x6, %dil
setne %r9b
cmpb %r8b, %r9b
je 0x7757
movl (%rdx), %r8d
cmpb $0x6, %sil
jne 0x76e3
testl %r8d, %r8d
jne 0x76ec
cmpl $0x0, 0x4(%rdx)
jne 0x76ec
cmpl $0x0, 0x8(%rdx)
jne 0x76ec
cmpl $0x0, 0xc(%rdx)
jne 0x76ec
jmp 0x776f
testl %r8d, %r8d
je 0x776f
movl (%r14), %r8d
cmpb $0x6, %dil
jne 0x7711
testl %r8d, %r8d
jne 0x7716
cmpl $0x0, 0x4(%r14)
jne 0x7716
cmpl $0x0, 0x8(%r14)
jne 0x7716
cmpl $0x0, 0xc(%r14)
jne 0x7716
jmp 0x776f
testl %r8d, %r8d
je 0x776f
cmpb %dil, %sil
jne 0x7757
movl (%rdx), %edi
movl (%r14), %r8d
cmpb $0x6, %sil
jne 0x7752
cmpl %r8d, %edi
jne 0x7757
movl 0x4(%rdx), %esi
cmpl 0x4(%r14), %esi
jne 0x7757
movl 0x8(%rdx), %esi
cmpl 0x8(%r14), %esi
jne 0x7757
movl 0xc(%rdx), %esi
cmpl 0xc(%r14), %esi
jne 0x7757
movb 0x10(%rdx), %sil
cmpb 0x10(%r14), %sil
jne 0x7757
jmp 0x776f
cmpl %r8d, %edi
je 0x776f
movq 0x38(%rdx), %rdx
jmp 0x768a
incq %rax
cmpq $0x4, %rax
jne 0x7683
jmp 0x7786
movb $-0x8, %al
jmp 0x780d
callq 0x7866
movl %eax, %ebp
testw %ax, %ax
je 0x780b
movb 0x14(%r14), %al
movl (%r14), %ecx
cmpb $0x6, %al
jne 0x77ac
testl %ecx, %ecx
jne 0x77b5
cmpl $0x0, 0x4(%r14)
jne 0x77b5
cmpl $0x0, 0x8(%r14)
jne 0x77b5
cmpl $0x0, 0xc(%r14)
jne 0x77b5
jmp 0x77b0
testl %ecx, %ecx
jne 0x77b5
cmpb 0x14(%rbx), %al
je 0x77ec
movb %al, 0x14(%rbx)
cmpb $0x6, 0x14(%r14)
movl (%r14), %eax
movl %eax, (%rbx)
jne 0x77e2
movl 0x4(%r14), %eax
movl %eax, 0x4(%rbx)
movl 0x8(%r14), %eax
movl %eax, 0x8(%rbx)
movl 0xc(%r14), %eax
movl %eax, 0xc(%rbx)
movb 0x10(%r14), %al
movb %al, 0x10(%rbx)
jmp 0x77ec
xorl %eax, %eax
movq %rax, 0x9(%rbx)
movq %rax, 0x4(%rbx)
movw %bp, 0x4e(%rbx)
movq 0x16109(%rip), %rax     # 0x1d900
movq %rax, 0x38(%rbx)
movq %rbx, 0x160fe(%rip)     # 0x1d900
callq 0xce20
xorl %eax, %eax
jmp 0x780d
movb $-0x2, %al
addq $0x20, %rsp
popq %rbx
popq %r14
popq %rbp
retq
xorl %eax, %eax
jmp 0x7668
leaq 0xdaa8(%rip), %rdi      # 0x152cc
leaq 0xe509(%rip), %rsi      # 0x15d34
leaq 0xe46d(%rip), %rcx      # 0x15c9f
movl $0x2a9, %edx            # imm = 0x2A9
jmp 0x7853
leaq 0xda8c(%rip), %rdi      # 0x152cc
leaq 0xe503(%rip), %rsi      # 0x15d4a
leaq 0xe451(%rip), %rcx      # 0x15c9f
movl $0x2ab, %edx            # imm = 0x2AB
xorl %eax, %eax
callq 0x20d0
xorl %edi, %edi
callq 0x21b0
callq 0x2050