// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x80, %rsp
movw %r8w, %ax
movw 0x10(%rbp), %r8w
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movw %ax, -0x22(%rbp)
movq %r9, -0x30(%rbp)
movq 0x2b185(%rip), %rax     # 0x2eff8
movq (%rax), %rdi
leaq 0x231ed(%rip), %rsi     # 0x2706a
leaq 0x254e0(%rip), %rdx     # 0x29364
movl $0x8, %ecx
leaq 0x233ab(%rip), %r8      # 0x2723b
movb $0x0, %al
callq 0x2170
movzwl -0x22(%rbp), %esi
movzwl 0x10(%rbp), %edx
leaq 0x233a2(%rip), %rdi     # 0x27248
movb $0x0, %al
callq 0x20d0
cmpq $0x0, 0x2b8ab(%rip)     # 0x2f760
jne 0x3ec8
movl $0x5dc, %edi            # imm = 0x5DC
callq 0x31e0
movq %rax, 0x2b898(%rip)     # 0x2f760
movq -0x18(%rbp), %rax
movzwl 0x10(%rax), %eax
cmpl $0x5dc, %eax            # imm = 0x5DC
jl 0x3f09
jmp 0x3ed9
movq 0x2b118(%rip), %rax     # 0x2eff8
movq (%rax), %rdi
leaq 0x23180(%rip), %rsi     # 0x2706a
leaq 0x25473(%rip), %rdx     # 0x29364
movl $0x15, %ecx
leaq 0x23352(%rip), %r8      # 0x2724f
movb $0x0, %al
callq 0x2170
jmp 0x4204
movq -0x18(%rbp), %rdi
movq 0x2b84c(%rip), %rsi     # 0x2f760
movq -0x18(%rbp), %rax
xorl %ecx, %ecx
movzwl 0x10(%rax), %edx
callq 0x8250
movzwl %ax, %eax
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x3c(%rbp)
jne 0x3f61
jmp 0x3f31
movq 0x2b0c0(%rip), %rax     # 0x2eff8
movq (%rax), %rdi
leaq 0x23128(%rip), %rsi     # 0x2706a
leaq 0x2541b(%rip), %rdx     # 0x29364
movl $0x1a, %ecx
leaq 0x23233(%rip), %r8      # 0x27188
movb $0x0, %al
callq 0x2170
jmp 0x4204
movq -0x18(%rbp), %rdi
callq 0x7260
movq -0x20(%rbp), %rax
movzbl 0x14(%rax), %eax
cmpl $0x0, %eax
je 0x3fb6
movq -0x20(%rbp), %rax
movzbl 0x14(%rax), %eax
cmpl $0x6, %eax
je 0x3fb6
jmp 0x3f86
movq 0x2b06b(%rip), %rax     # 0x2eff8
movq (%rax), %rdi
leaq 0x230d3(%rip), %rsi     # 0x2706a
leaq 0x253c6(%rip), %rdx     # 0x29364
movl $0x20, %ecx
leaq 0x232b4(%rip), %r8      # 0x2725e
movb $0x0, %al
callq 0x2170
jmp 0x4204
movl $0x38, %edi
callq 0x31e0
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
movzbl 0x14(%rax), %eax
cmpl $0x0, %eax
jne 0x40db
movw $0x2, -0x4c(%rbp)
movq -0x30(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x48(%rbp)
movzwl 0x10(%rbp), %edi
callq 0x20c0
movw %ax, -0x4a(%rbp)
movq -0x38(%rbp), %rax
movl $0x4, (%rax)
movq -0x38(%rbp), %rax
movq -0x20(%rbp), %rcx
movl (%rcx), %ecx
movl %ecx, 0x10(%rax)
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
movl (%rcx), %ecx
movl %ecx, 0x20(%rax)
movw -0x22(%rbp), %cx
movq -0x38(%rbp), %rax
movw %cx, 0x30(%rax)
movw 0x10(%rbp), %cx
movq -0x38(%rbp), %rax
movw %cx, 0x32(%rax)
movl $0x2, %esi
xorl %edx, %edx
movl %esi, %edi
callq 0x2260
movl %eax, %ecx
movq -0x38(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x38(%rbp), %rax
cmpl $-0x1, 0x4(%rax)
jne 0x409a
movq 0x2af97(%rip), %rax     # 0x2eff8
movq (%rax), %rax
movq %rax, -0x70(%rbp)
callq 0x2050
movl (%rax), %edi
callq 0x2220
movq -0x70(%rbp), %rdi
movq %rax, %r8
leaq 0x22f82(%rip), %rsi     # 0x27004
leaq 0x252db(%rip), %rdx     # 0x29364
movl $0x35, %ecx
movb $0x0, %al
callq 0x2170
callq 0x2040
jmp 0x409c
movq -0x38(%rbp), %rdi
leaq 0x2b0c9(%rip), %rax     # 0x2f170
movl (%rax), %esi
movl $0x1, %edx
callq 0x2f10
movq -0x38(%rbp), %rax
movl 0x4(%rax), %edi
movq 0x2b69f(%rip), %rsi     # 0x2f760
movslq -0x3c(%rbp), %rdx
xorl %ecx, %ecx
leaq -0x4c(%rbp), %r8
movl $0x10, %r9d
callq 0x2110
jmp 0x4204
movq -0x20(%rbp), %rax
movzbl 0x14(%rax), %eax
cmpl $0x6, %eax
jne 0x4202
movw $0xa, -0x68(%rbp)
movq -0x30(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x60(%rbp)
movq 0x8(%rax), %rax
movq %rax, -0x58(%rbp)
movzwl 0x10(%rbp), %edi
callq 0x20c0
movw %ax, -0x66(%rbp)
movq -0x38(%rbp), %rax
movl $0x5, (%rax)
movq -0x38(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rcx), %rdx
movq %rdx, 0x10(%rax)
movq 0x8(%rcx), %rcx
movq %rcx, 0x18(%rax)
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
movq (%rcx), %rdx
movq %rdx, 0x20(%rax)
movq 0x8(%rcx), %rcx
movq %rcx, 0x28(%rax)
movw -0x22(%rbp), %cx
movq -0x38(%rbp), %rax
movw %cx, 0x30(%rax)
movw 0x10(%rbp), %cx
movq -0x38(%rbp), %rax
movw %cx, 0x32(%rax)
movl $0xa, %edi
movl $0x2, %esi
xorl %edx, %edx
callq 0x2260
movl %eax, %ecx
movq -0x38(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x38(%rbp), %rax
cmpl $-0x1, 0x4(%rax)
jne 0x41c6
movq 0x2ae6b(%rip), %rax     # 0x2eff8
movq (%rax), %rax
movq %rax, -0x78(%rbp)
callq 0x2050
movl (%rax), %edi
callq 0x2220
movq -0x78(%rbp), %rdi
movq %rax, %r8
leaq 0x22e56(%rip), %rsi     # 0x27004
leaq 0x251af(%rip), %rdx     # 0x29364
movl $0x47, %ecx
movb $0x0, %al
callq 0x2170
callq 0x2040
jmp 0x41c8
movq -0x38(%rbp), %rdi
leaq 0x2af9d(%rip), %rax     # 0x2f170
movl (%rax), %esi
movl $0x1, %edx
callq 0x2f10
movq -0x38(%rbp), %rax
movl 0x4(%rax), %edi
movq 0x2b573(%rip), %rsi     # 0x2f760
movslq -0x3c(%rbp), %rdx
xorl %ecx, %ecx
leaq -0x68(%rbp), %r8
movl $0x1c, %r9d
callq 0x2110
jmp 0x4204
addq $0x80, %rsp
popq %rbp
retq
nopl (%rax)