// File: /workspace/github_c_makefile_star2_O2/FH0[P]tun_direct/udp.c
// Function: tun_udp_recv
void tun_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p,
                  const ip_addr_t *saddr, u16_t sport, const ip_addr_t *daddr,
                  u16_t dport) {
  ELOG(__FUNCTION__);

  tun_data_t *data;
  static char *buf = NULL;
  int bufLen;

  printf("%d %d\n", sport, dport);

  /* get buf form pbuf */
  if (!buf) {
    buf = MALLOC(MTU);
  }
  if (p->tot_len >= MTU) {
    ELOG("big udp packet");
    return;
  }
  bufLen = pbuf_copy_partial(p, buf, p->tot_len, 0);
  if (bufLen == 0) {
    ELOG("pbuf_copy_partial()");
    return;
  }
  pbuf_free(p);

  if (saddr->type != IPADDR_TYPE_V4 && saddr->type != IPADDR_TYPE_V6) {
    ELOG("unsupport address type");
    return;
  }

  /* filled struct and sendto */
  data = MALLOC(sizeof(tun_data_t));
  data->upcb = upcb;
  if (saddr->type == IPADDR_TYPE_V4) {
    struct sockaddr_in sai;

    sai.sin_family = AF_INET;
    memcpy(&sai.sin_addr, &daddr->u_addr, 4);
    sai.sin_port = htons(dport);

    data->type = TUN_UDP;
    memcpy(data->saddr, &saddr->u_addr, 4);
    memcpy(data->daddr, &daddr->u_addr, 4);
    data->sport = sport;
    data->dport = dport;

    data->fd = socket(AF_INET, SOCK_DGRAM, 0);
    ASSERT(data->fd != -1);
    epoll_ET_add(data, epollfd, EPOLLIN);

    sendto(data->fd, buf, bufLen, 0, (struct sockaddr *)&sai, sizeof(sai));
  } else if (saddr->type == IPADDR_TYPE_V6) {
    struct sockaddr_in6 sai;

    sai.sin6_family = AF_INET6;
    memcpy(&sai.sin6_addr, &daddr->u_addr, 16);
    sai.sin6_port = htons(dport);

    data->type = TUN_UDP6;
    memcpy(data->saddr, &saddr->u_addr, 16);
    memcpy(data->daddr, &daddr->u_addr, 16);
    data->sport = sport;
    data->dport = dport;

    data->fd = socket(AF_INET6, SOCK_DGRAM, 0);
    ASSERT(data->fd != -1);
    epoll_ET_add(data, epollfd, EPOLLIN);

    sendto(data->fd, buf, bufLen, 0, (struct sockaddr *)&sai, sizeof(sai));
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r9, (%rsp)
movl %r8d, %ebx
movq %rcx, %r15
movq %rdx, %r12
movq %rsi, %r13
movzwl 0x60(%rsp), %r14d
movq 0x199f9(%rip), %rbp     # 0x1cff0
movq (%rbp), %rdi
leaq 0x10a68(%rip), %rsi     # 0x1406a
leaq 0x1298b(%rip), %rdx     # 0x15f94
leaq 0x10c2b(%rip), %r8      # 0x1423b
pushq $0x8
popq %rcx
xorl %eax, %eax
callq 0x2170
movzwl %r14w, %edx
leaq 0x10c23(%rip), %rdi     # 0x14248
movl %ebx, %esi
xorl %eax, %eax
callq 0x20d0
movq 0x1a12b(%rip), %rsi     # 0x1d760
testq %rsi, %rsi
jne 0x364e
movl $0x5dc, %edi            # imm = 0x5DC
callq 0x2d3c
movq %rax, %rsi
movq %rax, 0x1a112(%rip)     # 0x1d760
movzwl 0x10(%r12), %eax
cmpw $0x5dc, %ax             # imm = 0x5DC
jae 0x37e1
movzwl %ax, %edx
movq %r12, %rdi
xorl %ecx, %ecx
callq 0x54e3
testw %ax, %ax
je 0x37fe
movl %eax, %ebp
movq %r12, %rdi
callq 0x4e16
movzbl 0x14(%r15), %eax
testl %eax, %eax
je 0x3690
cmpl $0x6, %eax
jne 0x3821
pushq $0x38
popq %rdi
callq 0x2d3c
movq %rax, %r12
movq %r13, 0x8(%rax)
movzbl 0x14(%r15), %eax
cmpl $0x6, %eax
je 0x373e
testl %eax, %eax
jne 0x37d2
movw $0x2, 0xc(%rsp)
movq (%rsp), %rcx
movl (%rcx), %eax
movl %eax, 0x10(%rsp)
movl %r14d, %eax
rolw $0x8, %ax
movw %ax, 0xe(%rsp)
movl $0x4, (%r12)
movl (%r15), %eax
movl %eax, 0x10(%r12)
movl (%rcx), %eax
movl %eax, 0x20(%r12)
movw %bx, 0x30(%r12)
movw %r14w, 0x32(%r12)
pushq $0x2
popq %rdi
movl %edi, %esi
xorl %edx, %edx
callq 0x2260
movl %eax, 0x4(%r12)
cmpl $-0x1, %eax
je 0x3858
leaq 0x19a5a(%rip), %rax     # 0x1d170
movl (%rax), %esi
pushq $0x1
popq %rdx
movq %r12, %rdi
callq 0x2bba
movl 0x4(%r12), %edi
movq 0x1a031(%rip), %rsi     # 0x1d760
movzwl %bp, %edx
leaq 0xc(%rsp), %r8
pushq $0x10
jmp 0x37c9
movw $0xa, 0xc(%rsp)
movq (%rsp), %rcx
movups (%rcx), %xmm0
movups %xmm0, 0x14(%rsp)
movl %r14d, %eax
rolw $0x8, %ax
movw %ax, 0xe(%rsp)
movl $0x5, (%r12)
movups (%r15), %xmm0
movups %xmm0, 0x10(%r12)
movups (%rcx), %xmm0
movups %xmm0, 0x20(%r12)
movw %bx, 0x30(%r12)
movw %r14w, 0x32(%r12)
pushq $0xa
popq %rdi
pushq $0x2
popq %rsi
xorl %edx, %edx
callq 0x2260
movl %eax, 0x4(%r12)
cmpl $-0x1, %eax
je 0x3880
leaq 0x199ca(%rip), %rax     # 0x1d170
movl (%rax), %esi
pushq $0x1
popq %rdx
movq %r12, %rdi
callq 0x2bba
movl 0x4(%r12), %edi
movq 0x19fa1(%rip), %rsi     # 0x1d760
movzwl %bp, %edx
leaq 0xc(%rsp), %r8
pushq $0x1c
popq %r9
xorl %ecx, %ecx
callq 0x2110
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%rbp), %rdi
leaq 0x1087e(%rip), %rsi     # 0x1406a
leaq 0x127a1(%rip), %rdx     # 0x15f94
leaq 0x10a55(%rip), %r8      # 0x1424f
pushq $0x15
jmp 0x3842
movq 0x197eb(%rip), %rax     # 0x1cff0
movq (%rax), %rdi
leaq 0x1085b(%rip), %rsi     # 0x1406a
leaq 0x1277e(%rip), %rdx     # 0x15f94
leaq 0x1096b(%rip), %r8      # 0x14188
pushq $0x1a
jmp 0x3842
movq 0x197c8(%rip), %rax     # 0x1cff0
movq (%rax), %rdi
leaq 0x10838(%rip), %rsi     # 0x1406a
leaq 0x1275b(%rip), %rdx     # 0x15f94
leaq 0x10a1e(%rip), %r8      # 0x1425e
pushq $0x20
popq %rcx
xorl %eax, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2170
movq 0x19791(%rip), %rax     # 0x1cff0
movq (%rax), %rbx
callq 0x2060
movl (%rax), %edi
callq 0x2220
leaq 0x1078f(%rip), %rsi     # 0x14004
leaq 0x12718(%rip), %rdx     # 0x15f94
pushq $0x35
jmp 0x38a6
movq 0x19769(%rip), %rax     # 0x1cff0
movq (%rax), %rbx
callq 0x2060
movl (%rax), %edi
callq 0x2220
leaq 0x10767(%rip), %rsi     # 0x14004
leaq 0x126f0(%rip), %rdx     # 0x15f94
pushq $0x47
popq %rcx
movq %rbx, %rdi
movq %rax, %r8
xorl %eax, %eax
callq 0x2170
callq 0x2050