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

```asm
<option_alloc>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %rbx
  sub    $0x48,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %esi,-0x3c(%rbp)
  mov    %edx,-0x40(%rbp)
  mov    %ecx,-0x44(%rbp)
  cmpl   $0x1,-0x40(%rbp)
  je     L63
  cmpl   $0x2,-0x40(%rbp)
  je     L63
  cmpl   $0x4,-0x40(%rbp)
  je     L63
  cmpl   $0x8,-0x40(%rbp)
  jne    L32
L63:
  cmpl   $0x0,-0x44(%rbp)
  js     L32
  cmpl   $0x7,-0x44(%rbp)
  jle    L20
L32:
  mov    $0x0,%eax
  jmp    L33
L20:
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rax
  mov    %eax,%ebx
  mov    $0x0,%edi
  call   <CMSG_LEN@plt>
  mov    %eax,%edx
  mov    %ebx,%eax
  sub    %edx,%eax
  mov    %eax,-0x28(%rbp)
  cmpl   $0x0,-0x28(%rbp)
  sete   %al
  movzbl %al,%eax
  mov    $0x0,%esi
  mov    %eax,%edi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  je     L19
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rax
  add    $0x4,%rax
  mov    %rax,%rdx
  mov    -0x38(%rbp),%rax
  mov    %rdx,(%rax)
  movl   $0x4,-0x28(%rbp)
L19:
  mov    -0x40(%rbp),%eax
  sub    $0x1,%eax
  and    -0x28(%rbp),%eax
  mov    %eax,%edx
  mov    -0x40(%rbp),%eax
  sub    %edx,%eax
  mov    %eax,%ecx
  mov    -0x40(%rbp),%eax
  sub    $0x1,%eax
  and    %eax,%ecx
  mov    %ecx,%edx
  mov    -0x44(%rbp),%eax
  add    %eax,%edx
  mov    -0x38(%rbp),%rax
  mov    %edx,%esi
  mov    %rax,%rdi
  call   <add_pad@plt>
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <CMSG_DATA@plt>
  mov    %rax,%rdx
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rax
  lea    (%rdx,%rax,1),%rbx
  mov    $0x0,%edi
  call   <CMSG_LEN@plt>
  mov    %rax,%rdx
  mov    %rbx,%rax
  sub    %rdx,%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x3c(%rbp),%eax
  cltq
  add    %rax,%rdx
  mov    -0x38(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rax
  mov    %eax,%ebx
  mov    $0x0,%edi
  call   <CMSG_LEN@plt>
  mov    %eax,%edx
  mov    %ebx,%eax
  sub    %edx,%eax
  mov    %eax,-0x28(%rbp)
  mov    -0x28(%rbp),%eax
  neg    %eax
  and    $0x7,%eax
  mov    %eax,%edx
  mov    -0x38(%rbp),%rax
  mov    %edx,%esi
  mov    %rax,%rdi
  call   <add_pad@plt>
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rbx
  mov    $0x0,%edi
  call   <CMSG_LEN@plt>
  mov    %rax,%rdx
  mov    %rbx,%rax
  sub    %rdx,%rax
  and    $0x7,%eax
  test   %rax,%rax
  sete   %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rbx
  mov    $0x0,%edi
  call   <CMSG_LEN@plt>
  mov    %rax,%rdx
  mov    %rbx,%rax
  sub    %rdx,%rax
  lea    0x7(%rax),%rdx
  test   %rax,%rax
  cmovs  %rdx,%rax
  sar    $0x3,%rax
  sub    $0x1,%eax
  mov    %eax,-0x24(%rbp)
  cmpl   $0xff,-0x24(%rbp)
  jle    L23
  mov    $0x0,%eax
  jmp    L33
L23:
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <CMSG_DATA@plt>
  mov    %rax,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  mov    -0x24(%rbp),%edx
  mov    %edx,(%rax)
  mov    -0x20(%rbp),%rax
L33:
  mov    -0x8(%rbp),%rbx
  leave
  ret
```

assistant: ```c
uint8_t *option_alloc(struct cmsghdr *cmsg, int datalen, int multx, int plusy) {
  if ((multx != 1 && multx != 2 && multx != 4 && multx != 8) || !(plusy >= 0 && plusy <= 7))
    return NULL;
  int dsize = cmsg->cmsg_len - CMSG_LEN(0);
  if (__builtin_expect(dsize == 0, 0)) {
    cmsg->cmsg_len += sizeof(struct ip6_ext);
    dsize = sizeof(struct ip6_ext);
  }
  add_pad(cmsg, ((multx - (dsize & (multx - 1))) & (multx - 1)) + plusy);
  uint8_t *result = CMSG_DATA(cmsg) + cmsg->cmsg_len - CMSG_LEN(0);
  cmsg->cmsg_len += datalen;
  dsize = cmsg->cmsg_len - CMSG_LEN(0);
  add_pad(cmsg, (8 - (dsize & (8 - 1))) & (8 - 1));
  assert(((cmsg->cmsg_len - CMSG_LEN(0)) % 8) == 0);
  int len8b = (cmsg->cmsg_len - CMSG_LEN(0)) / 8 - 1;
  if (len8b >= 256)
    return NULL;
  struct ip6_ext *ie = (void *)CMSG_DATA(cmsg);
  ie->ip6e_len = len8b;
  return result;
}
```