// File: /workspace/github_c_makefile_star2_O1/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 0x1a1c2(%rip), %rbp     # 0x1cff0
movq (%rbp), %rdi
leaq 0x12231(%rip), %rsi     # 0x1506a
leaq 0x14174(%rip), %rdx     # 0x16fb4
leaq 0x123f4(%rip), %r8      # 0x1523b
pushq $0x8
popq %rcx
xorl %eax, %eax
callq 0x2170
movzwl %r14w, %edx
leaq 0x123ec(%rip), %rdi     # 0x15248
movl %ebx, %esi
xorl %eax, %eax
callq 0x20d0
cmpq $0x0, 0x1a8f3(%rip)     # 0x1d760
jne 0x2e80
movl $0x5dc, %edi            # imm = 0x5DC
callq 0x3b54
movq %rax, 0x1a8e0(%rip)     # 0x1d760
movzwl 0x10(%r12), %eax
cmpw $0x5dc, %ax             # imm = 0x5DC
jae 0x301a
movq 0x1a8c9(%rip), %rsi     # 0x1d760
movzwl %ax, %edx
movq %r12, %rdi
xorl %ecx, %ecx
callq 0x575a
testw %ax, %ax
je 0x3037
movl %eax, %ebp
movq %r12, %rdi
callq 0x5069
movzbl 0x14(%r15), %eax
testl %eax, %eax
je 0x2ec9
cmpl $0x6, %eax
jne 0x305a
pushq $0x38
popq %rdi
callq 0x3b54
movq %rax, %r12
movq %r13, 0x8(%rax)
movzbl 0x14(%r15), %eax
cmpl $0x6, %eax
je 0x2f77
testl %eax, %eax
jne 0x300b
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 0x3091
leaq 0x1a221(%rip), %rax     # 0x1d170
movl (%rax), %esi
pushq $0x1
popq %rdx
movq %r12, %rdi
callq 0x3a69
movl 0x4(%r12), %edi
movq 0x1a7f8(%rip), %rsi     # 0x1d760
movzwl %bp, %edx
leaq 0xc(%rsp), %r8
pushq $0x10
jmp 0x3002
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 0x30b9
leaq 0x1a191(%rip), %rax     # 0x1d170
movl (%rax), %esi
pushq $0x1
popq %rdx
movq %r12, %rdi
callq 0x3a69
movl 0x4(%r12), %edi
movq 0x1a768(%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 0x12045(%rip), %rsi     # 0x1506a
leaq 0x13f88(%rip), %rdx     # 0x16fb4
leaq 0x1221c(%rip), %r8      # 0x1524f
pushq $0x15
jmp 0x307b
movq 0x19fb2(%rip), %rax     # 0x1cff0
movq (%rax), %rdi
leaq 0x12022(%rip), %rsi     # 0x1506a
leaq 0x13f65(%rip), %rdx     # 0x16fb4
leaq 0x12132(%rip), %r8      # 0x15188
pushq $0x1a
jmp 0x307b
movq 0x19f8f(%rip), %rax     # 0x1cff0
movq (%rax), %rdi
leaq 0x11fff(%rip), %rsi     # 0x1506a
leaq 0x13f42(%rip), %rdx     # 0x16fb4
leaq 0x121e5(%rip), %r8      # 0x1525e
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 0x19f58(%rip), %rax     # 0x1cff0
movq (%rax), %rbx
callq 0x2060
movl (%rax), %edi
callq 0x2220
leaq 0x11f56(%rip), %rsi     # 0x15004
leaq 0x13eff(%rip), %rdx     # 0x16fb4
pushq $0x35
jmp 0x30df
movq 0x19f30(%rip), %rax     # 0x1cff0
movq (%rax), %rbx
callq 0x2060
movl (%rax), %edi
callq 0x2220
leaq 0x11f2e(%rip), %rsi     # 0x15004
leaq 0x13ed7(%rip), %rdx     # 0x16fb4
pushq $0x47
popq %rcx
movq %rbx, %rdi
movq %rax, %r8
xorl %eax, %eax
callq 0x2170
callq 0x2050