// File: /workspace/github_c_makefile_star2_O1/FH0[P]tun_direct/lwip-2.1.2/src/core/ipv6/nd6.c
// Function: nd6_new_router
static s8_t
nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif)
{
  s8_t router_index;
  s8_t free_router_index;
  s8_t neighbor_index;

  IP6_ADDR_ZONECHECK_NETIF(router_addr, netif);

  /* Do we have a neighbor entry for this router? */
  neighbor_index = nd6_find_neighbor_cache_entry(router_addr);
  if (neighbor_index < 0) {
    /* Create a neighbor entry for this router. */
    neighbor_index = nd6_new_neighbor_cache_entry();
    if (neighbor_index < 0) {
      /* Could not create neighbor entry for this router. */
      return -1;
    }
    ip6_addr_set(&(neighbor_cache[neighbor_index].next_hop_address), router_addr);
    neighbor_cache[neighbor_index].netif = netif;
    neighbor_cache[neighbor_index].q = NULL;
    neighbor_cache[neighbor_index].state = ND6_INCOMPLETE;
    neighbor_cache[neighbor_index].counter.probes_sent = 1;
    nd6_send_neighbor_cache_probe(&neighbor_cache[neighbor_index], ND6_SEND_FLAG_MULTICAST_DEST);
  }

  /* Mark neighbor as router. */
  neighbor_cache[neighbor_index].isrouter = 1;

  /* Look for empty entry. */
  free_router_index = LWIP_ND6_NUM_ROUTERS;
  for (router_index = LWIP_ND6_NUM_ROUTERS - 1; router_index >= 0; router_index--) {
    /* check if router already exists (this is a special case for 2 netifs on the same subnet
       - e.g. wifi and cable) */
    if(default_router_list[router_index].neighbor_entry == &(neighbor_cache[neighbor_index])){ 
      return router_index; 
    } 
    if (default_router_list[router_index].neighbor_entry == NULL) {
      /* remember lowest free index to create a new entry */
      free_router_index = router_index;
    }
  }
  if (free_router_index < LWIP_ND6_NUM_ROUTERS) {
    default_router_list[free_router_index].neighbor_entry = &(neighbor_cache[neighbor_index]);
    return free_router_index;
  }

  /* Could not create a router entry. */

  /* Mark neighbor entry as not-router. Entry might be useful as neighbor still. */
  neighbor_cache[neighbor_index].isrouter = 0;

  /* router not found. */
  return -1;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movq %rdi, %rbx
leaq 0xadbd(%rip), %r14      # 0x1d770
leaq 0x24(%r14), %rdi
callq 0x123f7
movl %eax, %ebp
testb %al, %al
jns 0x12a33
callq 0x126cc
testb %al, %al
js 0x12a93
movl %eax, %ebp
movl 0x24(%r14), %eax
movzbl %bpl, %ecx
imulq $0x38, %rcx, %rcx
leaq 0xb02c(%rip), %rdx      # 0x1da10
leaq (%rdx,%rcx), %rsi
movl %eax, (%rcx,%rdx)
movl 0x28(%r14), %eax
movl %eax, 0x4(%rcx,%rdx)
movl 0x2c(%r14), %eax
movl %eax, 0x8(%rcx,%rdx)
movl 0x30(%r14), %eax
movl %eax, 0xc(%rcx,%rdx)
movb 0x34(%r14), %al
movb %al, 0x10(%rcx,%rdx)
movq %rbx, 0x18(%rcx,%rdx)
movq $0x0, 0x28(%rcx,%rdx)
movb $0x1, 0x30(%rcx,%rdx)
movl $0x1, 0x34(%rcx,%rdx)
movq %rbx, %rdi
movl $0x1, %edx
callq 0x13132
movzbl %bpl, %eax
imulq $0x38, %rax, %rax
leaq 0xafce(%rip), %rdx      # 0x1da10
leaq (%rdx,%rax), %rcx
movb $0x1, 0x31(%rax,%rdx)
movb $0x2, %al
movb $0x3, %dl
leaq 0xb1ea(%rip), %rsi      # 0x1dc40
movzbl %al, %edi
movl %edi, %r8d
shll $0x4, %r8d
movq (%r8,%rsi), %r8
cmpq %rcx, %r8
je 0x12a95
testq %r8, %r8
movzbl %dl, %edx
cmovel %edi, %edx
addb $-0x1, %dil
movl %edi, %eax
jb 0x12a56
cmpb $0x2, %dl
jg 0x12a8f
movsbq %dl, %rax
shlq $0x4, %rax
movq %rcx, (%rax,%rsi)
movl %edx, %eax
jmp 0x12a95
movb $0x0, 0x31(%rcx)
movb $-0x1, %al
popq %rbx
popq %r14
popq %rbp
retq