// File: /workspace/github_c_makefile_star2_O0/FH0[P]tun_direct/lwip-2.1.2/src/core/ipv6/ip6.c
// Function: ip6_output_if_src
err_t
ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
             u8_t hl, u8_t tc,
             u8_t nexth, struct netif *netif)
{
  struct ip6_hdr *ip6hdr;
  ip6_addr_t dest_addr;

  LWIP_ASSERT_CORE_LOCKED();
  LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p);

  /* Should the IPv6 header be generated or is it already included in p? */
  if (dest != LWIP_IP_HDRINCL) {
#if LWIP_IPV6_SCOPES
    /* If the destination address is scoped but lacks a zone, add a zone now,
     * based on the outgoing interface. The lower layers (e.g., nd6) absolutely
     * require addresses to be properly zoned for correctness. In some cases,
     * earlier attempts will have been made to add a zone to the destination,
     * but this function is the only one that is called in all (other) cases,
     * so we must do this here. */
    if (ip6_addr_lacks_zone(dest, IP6_UNKNOWN)) {
      ip6_addr_copy(dest_addr, *dest);
      ip6_addr_assign_zone(&dest_addr, IP6_UNKNOWN, netif);
      dest = &dest_addr;
    }
#endif /* LWIP_IPV6_SCOPES */

    /* generate IPv6 header */
    if (pbuf_add_header(p, IP6_HLEN)) {
      LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: not enough room for IPv6 header in pbuf\n"));
      IP6_STATS_INC(ip6.err);
      return ERR_BUF;
    }

    ip6hdr = (struct ip6_hdr *)p->payload;
    LWIP_ASSERT("check that first pbuf can hold struct ip6_hdr",
               (p->len >= sizeof(struct ip6_hdr)));

    IP6H_HOPLIM_SET(ip6hdr, hl);
    IP6H_NEXTH_SET(ip6hdr, nexth);

    /* dest cannot be NULL here */
    ip6_addr_copy_to_packed(ip6hdr->dest, *dest);

    IP6H_VTCFL_SET(ip6hdr, 6, tc, 0);
    IP6H_PLEN_SET(ip6hdr, (u16_t)(p->tot_len - IP6_HLEN));

    if (src == NULL) {
      src = IP6_ADDR_ANY6;
    }
    /* src cannot be NULL here */
    ip6_addr_copy_to_packed(ip6hdr->src, *src);

  } else {
    /* IP header already included in p */
    ip6hdr = (struct ip6_hdr *)p->payload;
    ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
    ip6_addr_assign_zone(&dest_addr, IP6_UNKNOWN, netif);
    dest = &dest_addr;
  }

  IP6_STATS_INC(ip6.xmit);

  LWIP_DEBUGF(IP6_DEBUG, ("ip6_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num));
  ip6_debug_print(p);

#if ENABLE_LOOPBACK
  {
    int i;
#if !LWIP_HAVE_LOOPIF
    if (ip6_addr_isloopback(dest)) {
      return netif_loop_output(netif, p);
    }
#endif /* !LWIP_HAVE_LOOPIF */
    for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
      if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
          ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) {
        /* Packet to self, enqueue it for loopback */
        LWIP_DEBUGF(IP6_DEBUG, ("netif_loop_output()\n"));
        return netif_loop_output(netif, p);
      }
    }
  }
#if LWIP_MULTICAST_TX_OPTIONS
  if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
    netif_loop_output(netif, p);
  }
#endif /* LWIP_MULTICAST_TX_OPTIONS */
#endif /* ENABLE_LOOPBACK */
#if LWIP_IPV6_FRAG
  /* don't fragment if interface has mtu set to 0 [loopif] */
  if (netif_mtu6(netif) && (p->tot_len > nd6_get_destination_mtu(dest, netif))) {
    return ip6_frag(p, netif, dest);
  }
#endif /* LWIP_IPV6_FRAG */

  LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()\n"));
  return netif->output_ip6(netif, p, dest);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movl %r8d, -0x60(%rbp)
movl %ecx, %eax
movl -0x60(%rbp), %ecx
movl %eax, -0x5c(%rbp)
movq %rdx, %rax
movl -0x5c(%rbp), %edx
movq %rax, -0x58(%rbp)
movq %rsi, %rax
movq -0x58(%rbp), %rsi
movq %rax, -0x50(%rbp)
movq %rdi, %r8
movq -0x50(%rbp), %rdi
movb %r9b, %al
movq 0x10(%rbp), %r9
movq %r8, -0x10(%rbp)
movq %rdi, -0x18(%rbp)
movq %rsi, -0x20(%rbp)
movb %dl, -0x21(%rbp)
movb %cl, -0x22(%rbp)
movb %al, -0x23(%rbp)
movq -0x10(%rbp), %rax
movzbl 0x16(%rax), %eax
cmpl $0x1, %eax
je 0x1d71a
jmp 0x1d6eb
leaq 0x9bda(%rip), %rdi      # 0x272cc
leaq 0xbfe5(%rip), %rsi      # 0x296de
movl $0x4aa, %edx            # imm = 0x4AA
leaq 0xc304(%rip), %rcx      # 0x29a09
movb $0x0, %al
callq 0x20d0
xorl %eax, %eax
movl %eax, %edi
callq 0x21b0
callq 0x2040
jmp 0x1d71c
cmpq $0x0, -0x20(%rbp)
je 0x1d94b
movq -0x20(%rbp), %rax
movzbl 0x10(%rax), %eax
cmpl $0x0, %eax
jne 0x1d809
movq -0x20(%rbp), %rax
movl (%rax), %eax
andq $0xc0ff, %rax           # imm = 0xC0FF
cmpq $0x80fe, %rax           # imm = 0x80FE
je 0x1d778
movq -0x20(%rbp), %rax
movl (%rax), %eax
andq $0x8fff, %rax           # imm = 0x8FFF
cmpq $0x1ff, %rax            # imm = 0x1FF
je 0x1d778
movq -0x20(%rbp), %rax
movl (%rax), %eax
andq $0x8fff, %rax           # imm = 0x8FFF
cmpq $0x2ff, %rax            # imm = 0x2FF
jne 0x1d809
jmp 0x1d77a
movq -0x20(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x44(%rbp)
movq -0x20(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x40(%rbp)
movq -0x20(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0x3c(%rbp)
movq -0x20(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x38(%rbp)
movq -0x20(%rbp), %rax
movb 0x10(%rax), %al
movb %al, -0x34(%rbp)
movl -0x44(%rbp), %eax
andq $0xc0ff, %rax           # imm = 0xC0FF
cmpq $0x80fe, %rax           # imm = 0x80FE
je 0x1d7de
movl -0x44(%rbp), %eax
andq $0x8fff, %rax           # imm = 0x8FFF
cmpq $0x1ff, %rax            # imm = 0x1FF
je 0x1d7de
movl -0x44(%rbp), %eax
andq $0x8fff, %rax           # imm = 0x8FFF
cmpq $0x2ff, %rax            # imm = 0x2FF
jne 0x1d7f4
movq 0x10(%rbp), %rax
movzbl 0xee(%rax), %eax
addl $0x1, %eax
movzbl %al, %eax
movl %eax, -0x64(%rbp)
jmp 0x1d7fb
xorl %eax, %eax
movl %eax, -0x64(%rbp)
jmp 0x1d7fb
movl -0x64(%rbp), %eax
movb %al, -0x34(%rbp)
leaq -0x44(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movl $0x28, %esi
callq 0x7780
cmpb $0x0, %al
je 0x1d828
jmp 0x1d81d
jmp 0x1d81f
movb $-0x2, -0x1(%rbp)
jmp 0x1db4d
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movzwl 0x12(%rax), %eax
cmpq $0x28, %rax
jae 0x1d873
jmp 0x1d844
leaq 0x9a81(%rip), %rdi      # 0x272cc
leaq 0xc1d6(%rip), %rsi      # 0x29a28
movl $0x4c5, %edx            # imm = 0x4C5
leaq 0xc1ab(%rip), %rcx      # 0x29a09
movb $0x0, %al
callq 0x20d0
xorl %eax, %eax
movl %eax, %edi
callq 0x21b0
callq 0x2040
jmp 0x1d875
movb -0x21(%rbp), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x7(%rax)
movb -0x23(%rbp), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x6(%rax)
movq -0x20(%rbp), %rax
movl (%rax), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x18(%rax)
movq -0x20(%rbp), %rax
movl 0x4(%rax), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x1c(%rax)
movq -0x20(%rbp), %rax
movl 0x8(%rax), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x20(%rax)
movq -0x20(%rbp), %rax
movl 0xc(%rax), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x24(%rax)
movzbl -0x22(%rbp), %edi
shll $0x14, %edi
orl $0x60000000, %edi       # imm = 0x60000000
orl $0x0, %edi
callq 0x251f0
movl %eax, %ecx
movq -0x30(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movzwl 0x10(%rax), %eax
subl $0x28, %eax
movzwl %ax, %edi
callq 0x251c0
movw %ax, %cx
movq -0x30(%rbp), %rax
movw %cx, 0x4(%rax)
cmpq $0x0, -0x18(%rbp)
jne 0x1d90d
leaq 0xc14f(%rip), %rax      # 0x29a58
movq %rax, -0x18(%rbp)
jmp 0x1d90f
movq -0x18(%rbp), %rax
movl (%rax), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x18(%rbp), %rax
movl 0x4(%rax), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x18(%rbp), %rax
movl 0x8(%rax), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x18(%rbp), %rax
movl 0xc(%rax), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x14(%rax)
jmp 0x1d9e1
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movl 0x18(%rax), %eax
movl %eax, -0x44(%rbp)
movq -0x30(%rbp), %rax
movl 0x1c(%rax), %eax
movl %eax, -0x40(%rbp)
movq -0x30(%rbp), %rax
movl 0x20(%rax), %eax
movl %eax, -0x3c(%rbp)
movq -0x30(%rbp), %rax
movl 0x24(%rax), %eax
movl %eax, -0x38(%rbp)
movb $0x0, -0x34(%rbp)
movl -0x44(%rbp), %eax
andq $0xc0ff, %rax           # imm = 0xC0FF
cmpq $0x80fe, %rax           # imm = 0x80FE
je 0x1d9b6
movl -0x44(%rbp), %eax
andq $0x8fff, %rax           # imm = 0x8FFF
cmpq $0x1ff, %rax            # imm = 0x1FF
je 0x1d9b6
movl -0x44(%rbp), %eax
andq $0x8fff, %rax           # imm = 0x8FFF
cmpq $0x2ff, %rax            # imm = 0x2FF
jne 0x1d9cc
movq 0x10(%rbp), %rax
movzbl 0xee(%rax), %eax
addl $0x1, %eax
movzbl %al, %eax
movl %eax, -0x68(%rbp)
jmp 0x1d9d3
xorl %eax, %eax
movl %eax, -0x68(%rbp)
jmp 0x1d9d3
movl -0x68(%rbp), %eax
movb %al, -0x34(%rbp)
leaq -0x44(%rbp), %rax
movq %rax, -0x20(%rbp)
jmp 0x1d9e3
jmp 0x1d9e5
movq -0x10(%rbp), %rdi
callq 0x1d510
movl $0x0, -0x48(%rbp)
cmpl $0x3, -0x48(%rbp)
jge 0x1dae2
movq 0x10(%rbp), %rax
movslq -0x48(%rbp), %rcx
movzbl 0x98(%rax,%rcx), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x1dad2
movq -0x20(%rbp), %rax
movl (%rax), %eax
movq 0x10(%rbp), %rcx
addq $0x50, %rcx
movslq -0x48(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
cmpl (%rcx), %eax
jne 0x1dad2
movq -0x20(%rbp), %rax
movl 0x4(%rax), %eax
movq 0x10(%rbp), %rcx
addq $0x50, %rcx
movslq -0x48(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
cmpl 0x4(%rcx), %eax
jne 0x1dad2
movq -0x20(%rbp), %rax
movl 0x8(%rax), %eax
movq 0x10(%rbp), %rcx
addq $0x50, %rcx
movslq -0x48(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
cmpl 0x8(%rcx), %eax
jne 0x1dad2
movq -0x20(%rbp), %rax
movl 0xc(%rax), %eax
movq 0x10(%rbp), %rcx
addq $0x50, %rcx
movslq -0x48(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
cmpl 0xc(%rcx), %eax
jne 0x1dad2
movq -0x20(%rbp), %rax
movzbl 0x10(%rax), %eax
movq 0x10(%rbp), %rcx
addq $0x50, %rcx
movslq -0x48(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movzbl 0x10(%rcx), %ecx
cmpl %ecx, %eax
jne 0x1dad2
jmp 0x1dabe
jmp 0x1dac0
movq 0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x5c90
movb %al, -0x1(%rbp)
jmp 0x1db4d
jmp 0x1dad4
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x1d9f5
movq 0x10(%rbp), %rax
movzwl 0xe2(%rax), %eax
cmpl $0x0, %eax
je 0x1db2d
movq -0x10(%rbp), %rax
movzwl 0x10(%rax), %eax
movl %eax, -0x6c(%rbp)
movq -0x20(%rbp), %rdi
movq 0x10(%rbp), %rsi
callq 0x24910
movw %ax, %cx
movl -0x6c(%rbp), %eax
movzwl %cx, %ecx
cmpl %ecx, %eax
jle 0x1db2d
movq -0x10(%rbp), %rdi
movq 0x10(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x1f460
movb %al, -0x1(%rbp)
jmp 0x1db4d
jmp 0x1db2f
jmp 0x1db31
movq 0x10(%rbp), %rax
movq 0xd0(%rax), %rax
movq 0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq *%rax
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)