// File: /workspace/github_c_makefile_star2_O0/FH0[P]tun_direct/lwip-2.1.2/src/core/ipv4/icmp.c
// Function: icmp_input
void
icmp_input(struct pbuf *p, struct netif *inp)
{
  u8_t type;
#ifdef LWIP_DEBUG
  u8_t code;
#endif /* LWIP_DEBUG */
  struct icmp_echo_hdr *iecho;
  const struct ip_hdr *iphdr_in;
  u16_t hlen;
  const ip4_addr_t *src;

  ICMP_STATS_INC(icmp.recv);
  MIB2_STATS_INC(mib2.icmpinmsgs);

  iphdr_in = ip4_current_header();
  hlen = IPH_HL_BYTES(iphdr_in);
  if (hlen < IP_HLEN) {
    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short IP header (%"S16_F" bytes) received\n", hlen));
    goto lenerr;
  }
  if (p->len < sizeof(u16_t) * 2) {
    LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));
    goto lenerr;
  }

  type = *((u8_t *)p->payload);
#ifdef LWIP_DEBUG
  code = *(((u8_t *)p->payload) + 1);
  /* if debug is enabled but debug statement below is somehow disabled: */
  LWIP_UNUSED_ARG(code);
#endif /* LWIP_DEBUG */
  switch (type) {
    case ICMP_ER:
      /* This is OK, echo reply might have been parsed by a raw PCB
         (as obviously, an echo request has been sent, too). */
      MIB2_STATS_INC(mib2.icmpinechoreps);
      break;
    case ICMP_ECHO:
      MIB2_STATS_INC(mib2.icmpinechos);
      src = ip4_current_dest_addr();
      /* multicast destination address? */
      if (ip4_addr_ismulticast(ip4_current_dest_addr())) {
#if LWIP_MULTICAST_PING
        /* For multicast, use address of receiving interface as source address */
        src = netif_ip4_addr(inp);
#else /* LWIP_MULTICAST_PING */
        LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast pings\n"));
        goto icmperr;
#endif /* LWIP_MULTICAST_PING */
      }
      /* broadcast destination address? */
      if (ip4_addr_isbroadcast(ip4_current_dest_addr(), ip_current_netif())) {
#if LWIP_BROADCAST_PING
        /* For broadcast, use address of receiving interface as source address */
        src = netif_ip4_addr(inp);
#else /* LWIP_BROADCAST_PING */
        LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to broadcast pings\n"));
        goto icmperr;
#endif /* LWIP_BROADCAST_PING */
      }
      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
      if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
        LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
        goto lenerr;
      }
#if CHECKSUM_CHECK_ICMP
      IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP) {
        if (inet_chksum_pbuf(p) != 0) {
          LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
          pbuf_free(p);
          ICMP_STATS_INC(icmp.chkerr);
          MIB2_STATS_INC(mib2.icmpinerrors);
          return;
        }
      }
#endif
#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
      if (pbuf_add_header(p, hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN)) {
        /* p is not big enough to contain link headers
         * allocate a new one and copy p into it
         */
        struct pbuf *r;
        u16_t alloc_len = (u16_t)(p->tot_len + hlen);
        if (alloc_len < p->tot_len) {
          LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed (tot_len overflow)\n"));
          goto icmperr;
        }
        /* allocate new packet buffer with space for link headers */
        r = pbuf_alloc(PBUF_LINK, alloc_len, PBUF_RAM);
        if (r == NULL) {
          LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n"));
          goto icmperr;
        }
        if (r->len < hlen + sizeof(struct icmp_echo_hdr)) {
          LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("first pbuf cannot hold the ICMP header"));
          pbuf_free(r);
          goto icmperr;
        }
        /* copy the ip header */
        MEMCPY(r->payload, iphdr_in, hlen);
        /* switch r->payload back to icmp header (cannot fail) */
        if (pbuf_remove_header(r, hlen)) {
          LWIP_ASSERT("icmp_input: moving r->payload to icmp header failed\n", 0);
          pbuf_free(r);
          goto icmperr;
        }
        /* copy the rest of the packet without ip header */
        if (pbuf_copy(r, p) != ERR_OK) {
          LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("icmp_input: copying to new pbuf failed"));
          pbuf_free(r);
          goto icmperr;
        }
        /* free the original p */
        pbuf_free(p);
        /* we now have an identical copy of p that has room for link headers */
        p = r;
      } else {
        /* restore p->payload to point to icmp header (cannot fail) */
        if (pbuf_remove_header(p, hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN)) {
          LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0);
          goto icmperr;
        }
      }
#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
      /* At this point, all checks are OK. */
      /* We generate an answer by switching the dest and src ip addresses,
       * setting the icmp type to ECHO_RESPONSE and updating the checksum. */
      iecho = (struct icmp_echo_hdr *)p->payload;
      if (pbuf_add_header(p, hlen)) {
        LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Can't move over header in packet"));
      } else {
        err_t ret;
        struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
        ip4_addr_copy(iphdr->src, *src);
        ip4_addr_copy(iphdr->dest, *ip4_current_src_addr());
        ICMPH_TYPE_SET(iecho, ICMP_ER);
#if CHECKSUM_GEN_ICMP
        IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP) {
          /* adjust the checksum */
          if (iecho->chksum > PP_HTONS(0xffffU - (ICMP_ECHO << 8))) {
            iecho->chksum = (u16_t)(iecho->chksum + PP_HTONS((u16_t)(ICMP_ECHO << 8)) + 1);
          } else {
            iecho->chksum = (u16_t)(iecho->chksum + PP_HTONS(ICMP_ECHO << 8));
          }
        }
#if LWIP_CHECKSUM_CTRL_PER_NETIF
        else {
          iecho->chksum = 0;
        }
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#else /* CHECKSUM_GEN_ICMP */
        iecho->chksum = 0;
#endif /* CHECKSUM_GEN_ICMP */

        /* Set the correct TTL and recalculate the header checksum. */
        IPH_TTL_SET(iphdr, ICMP_TTL);
        IPH_CHKSUM_SET(iphdr, 0);
#if CHECKSUM_GEN_IP
        IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) {
          IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, hlen));
        }
#endif /* CHECKSUM_GEN_IP */

        ICMP_STATS_INC(icmp.xmit);
        /* increase number of messages attempted to send */
        MIB2_STATS_INC(mib2.icmpoutmsgs);
        /* increase number of echo replies attempted to send */
        MIB2_STATS_INC(mib2.icmpoutechoreps);

        /* send an ICMP packet */
        ret = ip4_output_if(p, src, LWIP_IP_HDRINCL,
                            ICMP_TTL, 0, IP_PROTO_ICMP, inp);
        if (ret != ERR_OK) {
          LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %s\n", lwip_strerr(ret)));
        }
      }
      break;
    default:
      if (type == ICMP_DUR) {
        MIB2_STATS_INC(mib2.icmpindestunreachs);
      } else if (type == ICMP_TE) {
        MIB2_STATS_INC(mib2.icmpintimeexcds);
      } else if (type == ICMP_PP) {
        MIB2_STATS_INC(mib2.icmpinparmprobs);
      } else if (type == ICMP_SQ) {
        MIB2_STATS_INC(mib2.icmpinsrcquenchs);
      } else if (type == ICMP_RD) {
        MIB2_STATS_INC(mib2.icmpinredirects);
      } else if (type == ICMP_TS) {
        MIB2_STATS_INC(mib2.icmpintimestamps);
      } else if (type == ICMP_TSR) {
        MIB2_STATS_INC(mib2.icmpintimestampreps);
      } else if (type == ICMP_AM) {
        MIB2_STATS_INC(mib2.icmpinaddrmasks);
      } else if (type == ICMP_AMR) {
        MIB2_STATS_INC(mib2.icmpinaddrmaskreps);
      }
      LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n",
                               (s16_t)type, (s16_t)code));
      ICMP_STATS_INC(icmp.proterr);
      ICMP_STATS_INC(icmp.drop);
  }
  pbuf_free(p);
  return;
lenerr:
  pbuf_free(p);
  ICMP_STATS_INC(icmp.lenerr);
  MIB2_STATS_INC(mib2.icmpinerrors);
  return;
#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN || !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING
icmperr:
  pbuf_free(p);
  ICMP_STATS_INC(icmp.err);
  MIB2_STATS_INC(mib2.icmpinerrors);
  return;
#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN || !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq 0x166a9(%rip), %rax     # 0x2f770
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
andl $0xf, %eax
shll $0x2, %eax
movzbl %al, %eax
movw %ax, -0x2a(%rbp)
movzwl -0x2a(%rbp), %eax
cmpl $0x14, %eax
jge 0x190f5
jmp 0x190ee
jmp 0x190f0
jmp 0x194b8
movq -0x8(%rbp), %rax
movzwl 0x12(%rax), %eax
cmpq $0x4, %rax
jae 0x1910c
jmp 0x19105
jmp 0x19107
jmp 0x194b8
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movb (%rax), %al
movb %al, -0x11(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movb 0x1(%rax), %al
movb %al, -0x12(%rbp)
movzbl -0x11(%rbp), %eax
movl %eax, -0x54(%rbp)
testl %eax, %eax
je 0x19141
jmp 0x19134
movl -0x54(%rbp), %eax
subl $0x8, %eax
je 0x19146
jmp 0x19434
jmp 0x194ad
leaq 0x16623(%rip), %rax     # 0x2f770
addq $0x3c, %rax
movq %rax, -0x38(%rbp)
leaq 0x16614(%rip), %rax     # 0x2f770
movl 0x3c(%rax), %eax
andq $0xf0, %rax
cmpq $0xe0, %rax
jne 0x19176
jmp 0x1916f
jmp 0x19171
jmp 0x194c3
leaq 0x165f3(%rip), %rax     # 0x2f770
movl 0x3c(%rax), %edi
leaq 0x165e9(%rip), %rax     # 0x2f770
movq (%rax), %rsi
callq 0x1a140
cmpb $0x0, %al
je 0x1919c
jmp 0x19195
jmp 0x19197
jmp 0x194c3
jmp 0x1919e
jmp 0x191a0
movq -0x8(%rbp), %rax
movzwl 0x10(%rax), %eax
cmpq $0x8, %rax
jae 0x191b7
jmp 0x191b0
jmp 0x191b2
jmp 0x194b8
movq -0x8(%rbp), %rdi
movzwl -0x2a(%rbp), %eax
addl $0xe, %eax
addl $0x0, %eax
movslq %eax, %rsi
callq 0x7780
cmpb $0x0, %al
je 0x192e5
movq -0x8(%rbp), %rax
movzwl 0x10(%rax), %eax
movzwl -0x2a(%rbp), %ecx
addl %ecx, %eax
movw %ax, -0x42(%rbp)
movzwl -0x42(%rbp), %eax
movq -0x8(%rbp), %rcx
movzwl 0x10(%rcx), %ecx
cmpl %ecx, %eax
jge 0x19200
jmp 0x191f9
jmp 0x191fb
jmp 0x194c3
movl $0xe, %edi
movl $0x280, %edx            # imm = 0x280
movzwl -0x42(%rbp), %esi
callq 0x6e20
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x19227
jmp 0x19220
jmp 0x19222
jmp 0x194c3
movq -0x40(%rbp), %rax
movzwl 0x12(%rax), %eax
movzwl -0x2a(%rbp), %ecx
addq $0x8, %rcx
cmpq %rcx, %rax
jae 0x1924e
jmp 0x1923e
jmp 0x19240
movq -0x40(%rbp), %rdi
callq 0x7260
jmp 0x194c3
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x28(%rbp), %rsi
movzwl -0x2a(%rbp), %eax
movl %eax, %edx
callq 0x2180
movq -0x40(%rbp), %rdi
movzwl -0x2a(%rbp), %eax
movl %eax, %esi
callq 0x7950
cmpb $0x0, %al
je 0x192ab
jmp 0x1927a
jmp 0x1927c
leaq 0xe049(%rip), %rdi      # 0x272cc
leaq 0x103a1(%rip), %rsi     # 0x2962b
movl $0xb6, %edx
leaq 0x103ca(%rip), %rcx     # 0x29660
movb $0x0, %al
callq 0x20d0
xorl %eax, %eax
movl %eax, %edi
callq 0x21b0
callq 0x2040
movq -0x40(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0x7f70
movsbl %al, %eax
cmpl $0x0, %eax
je 0x192d2
jmp 0x192c2
jmp 0x192c4
movq -0x40(%rbp), %rdi
callq 0x7260
jmp 0x194c3
movq -0x8(%rbp), %rdi
callq 0x7260
movq -0x40(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x19334
movq -0x8(%rbp), %rdi
movzwl -0x2a(%rbp), %eax
addl $0xe, %eax
addl $0x0, %eax
movslq %eax, %rsi
callq 0x7950
cmpb $0x0, %al
je 0x19332
jmp 0x19301
jmp 0x19303
leaq 0xdfc2(%rip), %rdi      # 0x272cc
leaq 0x1036f(%rip), %rsi     # 0x29680
movl $0xc7, %edx
leaq 0x10343(%rip), %rcx     # 0x29660
movb $0x0, %al
callq 0x20d0
xorl %eax, %eax
movl %eax, %edi
callq 0x21b0
callq 0x2040
jmp 0x19334
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movzwl -0x2a(%rbp), %eax
movl %eax, %esi
callq 0x7780
cmpb $0x0, %al
je 0x1935c
jmp 0x19355
jmp 0x19357
jmp 0x19432
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x38(%rbp), %rax
movl (%rax), %ecx
movq -0x50(%rbp), %rax
movl %ecx, 0xc(%rax)
leaq 0x163f4(%rip), %rax     # 0x2f770
movl 0x24(%rax), %ecx
movq -0x50(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x20(%rbp), %rax
movb $0x0, (%rax)
movq -0x20(%rbp), %rax
movzwl 0x2(%rax), %eax
cmpl $0xfff7, %eax           # imm = 0xFFF7
jle 0x193b7
movq -0x20(%rbp), %rax
movzwl 0x2(%rax), %eax
addl $0x8, %eax
addl $0x1, %eax
movw %ax, %cx
movq -0x20(%rbp), %rax
movw %cx, 0x2(%rax)
jmp 0x193cd
movq -0x20(%rbp), %rax
movzwl 0x2(%rax), %eax
addl $0x8, %eax
movw %ax, %cx
movq -0x20(%rbp), %rax
movw %cx, 0x2(%rax)
movq -0x50(%rbp), %rax
movb $0x40, 0x8(%rax)
movq -0x50(%rbp), %rax
movw $0x0, 0xa(%rax)
movq -0x50(%rbp), %rdi
movzwl -0x2a(%rbp), %esi
callq 0x25f20
movw %ax, %cx
movq -0x50(%rbp), %rax
movw %cx, 0xa(%rax)
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq -0x10(%rbp), %rax
xorl %ecx, %ecx
movl %ecx, %edx
movl $0x40, %ecx
xorl %r8d, %r8d
movl $0x1, %r9d
movq %rax, (%rsp)
callq 0x19c10
movb %al, -0x43(%rbp)
movsbl -0x43(%rbp), %eax
cmpl $0x0, %eax
je 0x19430
jmp 0x1942c
jmp 0x1942e
jmp 0x19430
jmp 0x19432
jmp 0x194ad
movzbl -0x11(%rbp), %eax
cmpl $0x3, %eax
jne 0x1943f
jmp 0x194a7
movzbl -0x11(%rbp), %eax
cmpl $0xb, %eax
jne 0x1944a
jmp 0x194a5
movzbl -0x11(%rbp), %eax
cmpl $0xc, %eax
jne 0x19455
jmp 0x194a3
movzbl -0x11(%rbp), %eax
cmpl $0x4, %eax
jne 0x19460
jmp 0x194a1
movzbl -0x11(%rbp), %eax
cmpl $0x5, %eax
jne 0x1946b
jmp 0x1949f
movzbl -0x11(%rbp), %eax
cmpl $0xd, %eax
jne 0x19476
jmp 0x1949d
movzbl -0x11(%rbp), %eax
cmpl $0xe, %eax
jne 0x19481
jmp 0x1949b
movzbl -0x11(%rbp), %eax
cmpl $0x11, %eax
jne 0x1948c
jmp 0x19499
movzbl -0x11(%rbp), %eax
cmpl $0x12, %eax
jne 0x19497
jmp 0x19497
jmp 0x19499
jmp 0x1949b
jmp 0x1949d
jmp 0x1949f
jmp 0x194a1
jmp 0x194a3
jmp 0x194a5
jmp 0x194a7
jmp 0x194a9
jmp 0x194ab
jmp 0x194ad
movq -0x8(%rbp), %rdi
callq 0x7260
jmp 0x194cc
movq -0x8(%rbp), %rdi
callq 0x7260
jmp 0x194cc
movq -0x8(%rbp), %rdi
callq 0x7260
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)