// File: /workspace/github_c_makefile_star2_O0/FH0[P]tun_direct/lwip-2.1.2/src/core/ipv6/nd6.c
// Function: nd6_process_autoconfig_prefix
static void
nd6_process_autoconfig_prefix(struct netif *netif,
  struct prefix_option *prefix_opt, const ip6_addr_t *prefix_addr)
{
  ip6_addr_t ip6addr;
  u32_t valid_life, pref_life;
  u8_t addr_state;
  s8_t i, free_idx;

  /* The caller already checks RFC 4862 Sec. 5.5.3 points (a) and (b). We do
   * the rest, starting with checks for (c) and (d) here. */
  valid_life = lwip_htonl(prefix_opt->valid_lifetime);
  pref_life = lwip_htonl(prefix_opt->preferred_lifetime);
  if (pref_life > valid_life || prefix_opt->prefix_length != 64) {
    return; /* silently ignore this prefix for autoconfiguration purposes */
  }

  /* If an autogenerated address already exists for this prefix, update its
   * lifetimes. An address is considered autogenerated if 1) it is not static
   * (i.e., manually assigned), and 2) there is an advertised autoconfiguration
   * prefix for it (the one we are processing here). This does not necessarily
   * exclude the possibility that the address was actually assigned by, say,
   * DHCPv6. If that distinction becomes important in the future, more state
   * must be kept. As explained elsewhere we also update lifetimes of tentative
   * and duplicate addresses. Skip address slot 0 (the link-local address). */
  for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
    addr_state = netif_ip6_addr_state(netif, i);
    if (!ip6_addr_isinvalid(addr_state) && !netif_ip6_addr_isstatic(netif, i) &&
        ip6_addr_netcmp(prefix_addr, netif_ip6_addr(netif, i))) {
      /* Update the valid lifetime, as per RFC 4862 Sec. 5.5.3 point (e).
       * The valid lifetime will never drop to zero as a result of this. */
      u32_t remaining_life = netif_ip6_addr_valid_life(netif, i);
      if (valid_life > ND6_2HRS || valid_life > remaining_life) {
        netif_ip6_addr_set_valid_life(netif, i, valid_life);
      } else if (remaining_life > ND6_2HRS) {
        netif_ip6_addr_set_valid_life(netif, i, ND6_2HRS);
      }
      LWIP_ASSERT("bad valid lifetime", !netif_ip6_addr_isstatic(netif, i));
      /* Update the preferred lifetime. No bounds checks are needed here. In
       * rare cases the advertisement may un-deprecate the address, though.
       * Deprecation is left to the timer code where it is handled anyway. */
      if (pref_life > 0 && addr_state == IP6_ADDR_DEPRECATED) {
        netif_ip6_addr_set_state(netif, i, IP6_ADDR_PREFERRED);
      }
      netif_ip6_addr_set_pref_life(netif, i, pref_life);
      return; /* there should be at most one matching address */
    }
  }

  /* No autogenerated address exists for this prefix yet. See if we can add a
   * new one. However, if IPv6 autoconfiguration is administratively disabled,
   * do not generate new addresses, but do keep updating lifetimes for existing
   * addresses. Also, when adding new addresses, we must protect explicitly
   * against a valid lifetime of zero, because again, we use that as a special
   * value. The generated address would otherwise expire immediately anyway.
   * Finally, the original link-local address must be usable at all. We start
   * creating addresses even if the link-local address is still in tentative
   * state though, and deal with the fallout of that upon DAD collision. */
  addr_state = netif_ip6_addr_state(netif, 0);
  if (!netif->ip6_autoconfig_enabled || valid_life == IP6_ADDR_LIFE_STATIC ||
      ip6_addr_isinvalid(addr_state) || ip6_addr_isduplicated(addr_state)) {
    return;
  }

  /* Construct the new address that we intend to use, and then see if that
   * address really does not exist. It might have been added manually, after
   * all. As a side effect, find a free slot. Note that we cannot use
   * netif_add_ip6_address() here, as it would return ERR_OK if the address
   * already did exist, resulting in that address being given lifetimes. */
  IP6_ADDR(&ip6addr, prefix_addr->addr[0], prefix_addr->addr[1],
    netif_ip6_addr(netif, 0)->addr[2], netif_ip6_addr(netif, 0)->addr[3]);
  ip6_addr_assign_zone(&ip6addr, IP6_UNICAST, netif);

  free_idx = 0;
  for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
    if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i))) {
      if (ip6_addr_cmp(&ip6addr, netif_ip6_addr(netif, i))) {
        return; /* formed address already exists */
      }
    } else if (free_idx == 0) {
      free_idx = i;
    }
  }
  if (free_idx == 0) {
    return; /* no address slots available, try again on next advertisement */
  }

  /* Assign the new address to the interface. */
  ip_addr_copy_from_ip6(netif->ip6_addr[free_idx], ip6addr);
  netif_ip6_addr_set_valid_life(netif, free_idx, valid_life);
  netif_ip6_addr_set_pref_life(netif, free_idx, pref_life);
  netif_ip6_addr_set_state(netif, free_idx, IP6_ADDR_TENTATIVE);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %edi
callq 0x251f0
movl %eax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movl 0x8(%rax), %edi
callq 0x251f0
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x30(%rbp), %eax
ja 0x22347
movq -0x10(%rbp), %rax
movzbl 0x2(%rax), %eax
cmpl $0x40, %eax
je 0x2234c
jmp 0x227cd
movb $0x1, -0x36(%rbp)
movsbl -0x36(%rbp), %eax
cmpl $0x3, %eax
jge 0x22553
movq -0x8(%rbp), %rax
movsbq -0x36(%rbp), %rcx
movb 0x98(%rax,%rcx), %al
movb %al, -0x35(%rbp)
movzbl -0x35(%rbp), %eax
cmpl $0x0, %eax
je 0x22544
cmpq $0x0, -0x8(%rbp)
je 0x22399
movq -0x8(%rbp), %rax
movsbq -0x36(%rbp), %rcx
movl 0x9c(%rax,%rcx,4), %eax
movl %eax, -0x40(%rbp)
jmp 0x223a0
xorl %eax, %eax
movl %eax, -0x40(%rbp)
jmp 0x223a0
movl -0x40(%rbp), %eax
cmpl $0x0, %eax
je 0x22544
movq -0x18(%rbp), %rax
movl (%rax), %eax
movq -0x8(%rbp), %rcx
addq $0x50, %rcx
movsbq -0x36(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
cmpl (%rcx), %eax
jne 0x22544
movq -0x18(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x8(%rbp), %rcx
addq $0x50, %rcx
movsbq -0x36(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
cmpl 0x4(%rcx), %eax
jne 0x22544
movq -0x18(%rbp), %rax
movzbl 0x10(%rax), %eax
movq -0x8(%rbp), %rcx
addq $0x50, %rcx
movsbq -0x36(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movzbl 0x10(%rcx), %ecx
cmpl %ecx, %eax
jne 0x22544
cmpq $0x0, -0x8(%rbp)
je 0x22436
movq -0x8(%rbp), %rax
movsbq -0x36(%rbp), %rcx
movl 0x9c(%rax,%rcx,4), %eax
movl %eax, -0x44(%rbp)
jmp 0x2243d
xorl %eax, %eax
movl %eax, -0x44(%rbp)
jmp 0x2243d
movl -0x44(%rbp), %eax
movl %eax, -0x3c(%rbp)
cmpl $0x1c20, -0x30(%rbp)    # imm = 0x1C20
ja 0x22454
movl -0x30(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jbe 0x22474
jmp 0x22456
cmpq $0x0, -0x8(%rbp)
je 0x22470
movl -0x30(%rbp), %edx
movq -0x8(%rbp), %rax
movsbq -0x36(%rbp), %rcx
movl %edx, 0x9c(%rax,%rcx,4)
jmp 0x22472
jmp 0x224a0
cmpl $0x1c20, -0x3c(%rbp)    # imm = 0x1C20
jbe 0x2249e
jmp 0x2247f
cmpq $0x0, -0x8(%rbp)
je 0x2249a
movq -0x8(%rbp), %rax
movsbq -0x36(%rbp), %rcx
movl $0x1c20, 0x9c(%rax,%rcx,4) # imm = 0x1C20
jmp 0x2249c
jmp 0x2249e
jmp 0x224a0
jmp 0x224a2
cmpq $0x0, -0x8(%rbp)
je 0x224be
movq -0x8(%rbp), %rax
movsbq -0x36(%rbp), %rcx
movl 0x9c(%rax,%rcx,4), %eax
movl %eax, -0x48(%rbp)
jmp 0x224c5
xorl %eax, %eax
movl %eax, -0x48(%rbp)
jmp 0x224c5
movl -0x48(%rbp), %eax
cmpl $0x0, %eax
jne 0x224fe
jmp 0x224cf
leaq 0x4df6(%rip), %rdi      # 0x272cc
leaq 0x7757(%rip), %rsi      # 0x29c34
movl $0xde, %edx
leaq 0x775e(%rip), %rcx      # 0x29c47
movb $0x0, %al
callq 0x20d0
xorl %eax, %eax
movl %eax, %edi
callq 0x21b0
callq 0x2040
jmp 0x22500
cmpl $0x0, -0x34(%rbp)
jbe 0x22521
movzbl -0x35(%rbp), %eax
cmpl $0x10, %eax
jne 0x22521
movq -0x8(%rbp), %rdi
movl $0x30, %edx
movsbl -0x36(%rbp), %esi
callq 0x6420
jmp 0x22523
cmpq $0x0, -0x8(%rbp)
je 0x2253d
movl -0x34(%rbp), %edx
movq -0x8(%rbp), %rax
movsbq -0x36(%rbp), %rcx
movl %edx, 0xa8(%rax,%rcx,4)
jmp 0x2253f
jmp 0x227cd
jmp 0x22546
movb -0x36(%rbp), %al
addb $0x1, %al
movb %al, -0x36(%rbp)
jmp 0x22350
movq -0x8(%rbp), %rax
movb 0x98(%rax), %al
movb %al, -0x35(%rbp)
movq -0x8(%rbp), %rax
cmpb $0x0, 0xef(%rax)
je 0x22585
cmpl $0x0, -0x30(%rbp)
je 0x22585
movzbl -0x35(%rbp), %eax
cmpl $0x0, %eax
je 0x22585
movzbl -0x35(%rbp), %eax
cmpl $0x40, %eax
jne 0x2258a
jmp 0x227cd
jmp 0x2258c
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x2c(%rbp)
movq -0x18(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x28(%rbp)
movq -0x8(%rbp), %rax
movl 0x58(%rax), %eax
movl %eax, -0x24(%rbp)
movq -0x8(%rbp), %rax
movl 0x5c(%rax), %eax
movl %eax, -0x20(%rbp)
movb $0x0, -0x1c(%rbp)
movl -0x2c(%rbp), %eax
andq $0xc0ff, %rax           # imm = 0xC0FF
cmpq $0x80fe, %rax           # imm = 0x80FE
jne 0x225de
movq -0x8(%rbp), %rax
movzbl 0xee(%rax), %eax
addl $0x1, %eax
movzbl %al, %eax
movl %eax, -0x4c(%rbp)
jmp 0x225e5
xorl %eax, %eax
movl %eax, -0x4c(%rbp)
jmp 0x225e5
movl -0x4c(%rbp), %eax
movb %al, -0x1c(%rbp)
movb $0x0, -0x37(%rbp)
movb $0x1, -0x36(%rbp)
movsbl -0x36(%rbp), %eax
cmpl $0x3, %eax
jge 0x226d0
movq -0x8(%rbp), %rax
movsbq -0x36(%rbp), %rcx
movzbl 0x98(%rax,%rcx), %eax
cmpl $0x0, %eax
je 0x226b0
movl -0x2c(%rbp), %eax
movq -0x8(%rbp), %rcx
addq $0x50, %rcx
movsbq -0x36(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
cmpl (%rcx), %eax
jne 0x226ae
movl -0x28(%rbp), %eax
movq -0x8(%rbp), %rcx
addq $0x50, %rcx
movsbq -0x36(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
cmpl 0x4(%rcx), %eax
jne 0x226ae
movl -0x24(%rbp), %eax
movq -0x8(%rbp), %rcx
addq $0x50, %rcx
movsbq -0x36(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
cmpl 0x8(%rcx), %eax
jne 0x226ae
movl -0x20(%rbp), %eax
movq -0x8(%rbp), %rcx
addq $0x50, %rcx
movsbq -0x36(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
cmpl 0xc(%rcx), %eax
jne 0x226ae
movzbl -0x1c(%rbp), %eax
movq -0x8(%rbp), %rcx
addq $0x50, %rcx
movsbq -0x36(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movzbl 0x10(%rcx), %ecx
cmpl %ecx, %eax
jne 0x226ae
jmp 0x227cd
jmp 0x226c1
movsbl -0x37(%rbp), %eax
cmpl $0x0, %eax
jne 0x226bf
movb -0x36(%rbp), %al
movb %al, -0x37(%rbp)
jmp 0x226c1
jmp 0x226c3
movb -0x36(%rbp), %al
addb $0x1, %al
movb %al, -0x36(%rbp)
jmp 0x225f3
movsbl -0x37(%rbp), %eax
cmpl $0x0, %eax
jne 0x226de
jmp 0x227cd
jmp 0x226e0
jmp 0x226e2
movl -0x2c(%rbp), %ecx
movq -0x8(%rbp), %rax
addq $0x50, %rax
movsbq -0x37(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movl %ecx, (%rax)
movl -0x28(%rbp), %ecx
movq -0x8(%rbp), %rax
addq $0x50, %rax
movsbq -0x37(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x4(%rax)
movl -0x24(%rbp), %ecx
movq -0x8(%rbp), %rax
addq $0x50, %rax
movsbq -0x37(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x8(%rax)
movl -0x20(%rbp), %ecx
movq -0x8(%rbp), %rax
addq $0x50, %rax
movsbq -0x37(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0xc(%rax)
movb -0x1c(%rbp), %cl
movq -0x8(%rbp), %rax
addq $0x50, %rax
movsbq -0x37(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rax
movb %cl, 0x10(%rax)
jmp 0x22765
movq -0x8(%rbp), %rax
addq $0x50, %rax
movsbq -0x37(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movb $0x6, 0x14(%rax)
jmp 0x2277f
jmp 0x22781
cmpq $0x0, -0x8(%rbp)
je 0x2279b
movl -0x30(%rbp), %edx
movq -0x8(%rbp), %rax
movsbq -0x37(%rbp), %rcx
movl %edx, 0x9c(%rax,%rcx,4)
jmp 0x2279d
jmp 0x2279f
cmpq $0x0, -0x8(%rbp)
je 0x227b9
movl -0x34(%rbp), %edx
movq -0x8(%rbp), %rax
movsbq -0x37(%rbp), %rcx
movl %edx, 0xa8(%rax,%rcx,4)
jmp 0x227bb
movq -0x8(%rbp), %rdi
movl $0x8, %edx
movsbl -0x37(%rbp), %esi
callq 0x6420
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)