user: Translate the below assembly code into C programming language:

```asm
<sendto_icmp_ipv4_l2>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x60,%rsp
  mov    %edi,-0x34(%rbp)
  mov    %esi,-0x38(%rbp)
  mov    %rdx,-0x40(%rbp)
  mov    %rcx,-0x48(%rbp)
  mov    %r8,-0x50(%rbp)
  mov    %r9,-0x58(%rbp)
  mov    0x18(%rbp),%rax
  add    $0x58,%eax
  mov    %eax,%edi
  call   <malloc@plt>
  mov    %rax,-0x20(%rbp)
  mov    -0x20(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  add    $0x18,%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x10(%rbp),%rax
  add    $0x40,%rax
  mov    %rax,-0x8(%rbp)
  movl   $0x0,-0x28(%rbp)
  movl   $0x0,-0x24(%rbp)
  mov    -0x18(%rbp),%rax
  mov    (%rax),%rax
  mov    -0x40(%rbp),%rcx
  mov    $0x6,%edx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  mov    -0x18(%rbp),%rax
  mov    0x8(%rax),%rax
  mov    -0x48(%rbp),%rcx
  mov    $0x6,%edx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  mov    D24(%rip),%rax
  mov    (%rax),%eax
  mov    %eax,%edi
  call   <htons@plt>
  mov    -0x18(%rbp),%rdx
  mov    %rax,0x10(%rdx)
  mov    -0x10(%rbp),%rax
  movl   $0x5,(%rax)
  mov    -0x10(%rbp),%rax
  movl   $0x4,0x4(%rax)
  mov    -0x10(%rbp),%rax
  movq   $0x0,0x38(%rax)
  mov    -0x10(%rbp),%rax
  mov    (%rax),%eax
  shl    $0x2,%eax
  mov    %eax,%edx
  mov    0x18(%rbp),%rax
  add    %edx,%eax
  mov    %eax,%edi
  call   <htons@plt>
  mov    -0x10(%rbp),%rdx
  mov    %rax,0x30(%rdx)
  mov    D6(%rip),%eax
  lea    0x1(%rax),%edx
  mov    %edx,D42(%rip)
  mov    %eax,%edi
  call   <htons@plt>
  mov    -0x10(%rbp),%rdx
  mov    %rax,0x28(%rdx)
  mov    $0x4000,%edi
  call   <htons@plt>
  mov    -0x10(%rbp),%rdx
  mov    %rax,0x20(%rdx)
  mov    -0x10(%rbp),%rax
  mov    0x20(%rbp),%edx
  mov    %edx,0x8(%rax)
  mov    -0x10(%rbp),%rax
  movl   $0x1,0xc(%rax)
  mov    -0x10(%rbp),%rax
  movq   $0x0,0x10(%rax)
  mov    -0x58(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x10(%rbp),%rax
  mov    %edx,0x1c(%rax)
  mov    -0x50(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x10(%rbp),%rax
  mov    %edx,0x18(%rax)
  mov    0x18(%rbp),%rdx
  mov    -0x8(%rbp),%rax
  mov    0x10(%rbp),%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  mov    -0x10(%rbp),%rax
  mov    (%rax),%eax
  lea    0x0(,%rax,4),%edx
  mov    -0x10(%rbp),%rax
  mov    %edx,%esi
  mov    %rax,%rdi
  call   <calc_ipchksum@plt>
  mov    -0x10(%rbp),%rdx
  mov    %rax,0x10(%rdx)
  mov    0x18(%rbp),%rax
  add    $0x58,%eax
  mov    %eax,%ecx
  mov    -0x18(%rbp),%rdx
  mov    -0x38(%rbp),%esi
  mov    -0x34(%rbp),%eax
  mov    %eax,%edi
  call   <sendto_l2@plt>
  mov    %eax,-0x28(%rbp)
  mov    D42(%rip),%rax
  mov    (%rax),%eax
  mov    %eax,-0x24(%rbp)
  mov    -0x20(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  mov    D42(%rip),%rax
  mov    -0x24(%rbp),%edx
  mov    %edx,(%rax)
  mov    -0x28(%rbp),%eax
  leave
  ret
```

assistant: ```c
int sendto_icmp_ipv4_l2(int ifidx, int sock, const unsigned char dst_mac[6], const unsigned char src_mac[6], const struct sockaddr_in *dst_ip, const struct sockaddr_in *src_ip, const struct icmphdr *in_icmp, size_t icmp_len, int ttl) {
  void *mem = malloc(sizeof(struct ethhdr) + sizeof(struct iphdr) + icmp_len);
  struct ethhdr *ether = mem;
  struct iphdr *ip = (struct iphdr *)(ether + 1);
  struct icmphdr *icmp = (struct icmphdr *)(ip + 1);
  int result = 0, ret_errno = 0;
  static int id_base = 0;
  memcpy(ether->h_dest, dst_mac, 6);
  memcpy(ether->h_source, src_mac, 6);
  ether->h_proto = htons(ETHERTYPE_IP);
  ip->ihl = 5;
  ip->version = 4;
  ip->tos = 0;
  ip->tot_len = htons(ip->ihl * 4 + icmp_len);
  ip->id = htons(id_base++);
  ip->frag_off = htons(0x4000);
  ip->ttl = ttl;
  ip->protocol = 1;
  ip->check = 0;
  ip->saddr = src_ip->sin_addr.s_addr;
  ip->daddr = dst_ip->sin_addr.s_addr;
  memcpy(icmp, in_icmp, icmp_len);
  ip->check = calc_ipchksum(ip, ip->ihl * 4);
  result = sendto_l2(ifidx, sock, ether, sizeof(struct ethhdr) + sizeof(struct iphdr) + icmp_len);
  ret_errno = errno;
  free(mem);
  errno = ret_errno;
  return result;
}
```