// File: /workspace/github_c_makefile_star2_O3/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 0x191cd(%rip), %rbp     # 0x1bff0
movq (%rbp), %rdi
leaq 0x1123c(%rip), %rsi     # 0x1406a
leaq 0x13147(%rip), %rdx     # 0x15f7c
leaq 0x113ff(%rip), %r8      # 0x1423b
pushq $0x8
popq %rcx
xorl %eax, %eax
callq 0x2170
movzwl %r14w, %edx
leaq 0x113f7(%rip), %rdi     # 0x14248
movl %ebx, %esi
xorl %eax, %eax
callq 0x20d0
movq 0x198ff(%rip), %rsi     # 0x1c760
testq %rsi, %rsi
jne 0x2e7a
movl $0x5dc, %edi            # imm = 0x5DC
callq 0x3b24
movq %rax, %rsi
movq %rax, 0x198e6(%rip)     # 0x1c760
movzwl 0x10(%r12), %eax
cmpw $0x5dc, %ax             # imm = 0x5DC
jae 0x300d
movzwl %ax, %edx
movq %r12, %rdi
xorl %ecx, %ecx
callq 0x56cf
testw %ax, %ax
je 0x302a
movl %eax, %ebp
movq %r12, %rdi
callq 0x4fdf
movzbl 0x14(%r15), %eax
testl %eax, %eax
je 0x2ebc
cmpl $0x6, %eax
jne 0x304d
pushq $0x38
popq %rdi
callq 0x3b24
movq %rax, %r12
movq %r13, 0x8(%rax)
movzbl 0x14(%r15), %eax
cmpl $0x6, %eax
je 0x2f6a
testl %eax, %eax
jne 0x2ffe
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 0x3084
leaq 0x1922e(%rip), %rax     # 0x1c170
movl (%rax), %esi
pushq $0x1
popq %rdx
movq %r12, %rdi
callq 0x3a3a
movl 0x4(%r12), %edi
movq 0x19805(%rip), %rsi     # 0x1c760
movzwl %bp, %edx
leaq 0xc(%rsp), %r8
pushq $0x10
jmp 0x2ff5
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 0x30ac
leaq 0x1919e(%rip), %rax     # 0x1c170
movl (%rax), %esi
pushq $0x1
popq %rdx
movq %r12, %rdi
callq 0x3a3a
movl 0x4(%r12), %edi
movq 0x19775(%rip), %rsi     # 0x1c760
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 0x11052(%rip), %rsi     # 0x1406a
leaq 0x12f5d(%rip), %rdx     # 0x15f7c
leaq 0x11229(%rip), %r8      # 0x1424f
pushq $0x15
jmp 0x306e
movq 0x18fbf(%rip), %rax     # 0x1bff0
movq (%rax), %rdi
leaq 0x1102f(%rip), %rsi     # 0x1406a
leaq 0x12f3a(%rip), %rdx     # 0x15f7c
leaq 0x1113f(%rip), %r8      # 0x14188
pushq $0x1a
jmp 0x306e
movq 0x18f9c(%rip), %rax     # 0x1bff0
movq (%rax), %rdi
leaq 0x1100c(%rip), %rsi     # 0x1406a
leaq 0x12f17(%rip), %rdx     # 0x15f7c
leaq 0x111f2(%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 0x18f65(%rip), %rax     # 0x1bff0
movq (%rax), %rbx
callq 0x2060
movl (%rax), %edi
callq 0x2220
leaq 0x10f63(%rip), %rsi     # 0x14004
leaq 0x12ed4(%rip), %rdx     # 0x15f7c
pushq $0x35
jmp 0x30d2
movq 0x18f3d(%rip), %rax     # 0x1bff0
movq (%rax), %rbx
callq 0x2060
movl (%rax), %edi
callq 0x2220
leaq 0x10f3b(%rip), %rsi     # 0x14004
leaq 0x12eac(%rip), %rdx     # 0x15f7c
pushq $0x47
popq %rcx
movq %rbx, %rdi
movq %rax, %r8
xorl %eax, %eax
callq 0x2170
callq 0x2050