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

```asm
<hash_information_elements>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x30,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %esi,-0x2c(%rbp)
  mov    %edx,-0x30(%rbp)
  movl   $0x0,-0x18(%rbp)
  jmp    L176
L125:
  mov    -0x2c(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x2c(%rbp)
  mov    %eax,%edx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,-0x10(%rbp)
  mov    -0x2c(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x2c(%rbp)
  mov    %eax,%edx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,-0x14(%rbp)
  mov    -0x2c(%rbp),%eax
  mov    %eax,-0xc(%rbp)
  movl   $0x0,-0x8(%rbp)
  movl   $0x0,-0x4(%rbp)
  mov    -0x30(%rbp),%eax
  sub    -0x2c(%rbp),%eax
  cmp    %eax,-0x14(%rbp)
  jbe    L221
  mov    -0x30(%rbp),%eax
  sub    -0x2c(%rbp),%eax
  cmp    $0x2,%eax
  je     L198
  mov    -0x30(%rbp),%eax
  sub    -0x2c(%rbp),%eax
  mov    %eax,-0x14(%rbp)
L221:
  mov    -0x14(%rbp),%eax
  add    %eax,-0x2c(%rbp)
  cmpl   $0xdd,-0x10(%rbp)
  je     L94
  cmpl   $0xdd,-0x10(%rbp)
  ja     L158
  cmpl   $0x0,-0x10(%rbp)
  je     L176
  cmpl   $0x3,-0x10(%rbp)
  jne    L158
  jmp    L176
L94:
  cmpl   $0x3,-0x14(%rbp)
  jbe    L102
  mov    -0xc(%rbp),%edx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x10,%eax
  mov    %eax,%edx
  mov    -0xc(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%ecx
  mov    -0x28(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x8,%eax
  or     %eax,%edx
  mov    -0xc(%rbp),%eax
  add    $0x2,%eax
  mov    %eax,%ecx
  mov    -0x28(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  or     %edx,%eax
  mov    %eax,-0x8(%rbp)
  mov    -0xc(%rbp),%eax
  add    $0x3,%eax
  mov    %eax,%edx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,-0x4(%rbp)
  cmpl   $0x50f2,-0x8(%rbp)
  jne    L22
  cmpl   $0x8,-0x4(%rbp)
  jne    L157
  cmpl   $0x5,-0x14(%rbp)
  jbe    L220
  mov    -0xc(%rbp),%eax
  add    $0x4,%eax
  mov    %eax,%edx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  test   %eax,%eax
  jne    L44
  cmpl   $0x5,-0x14(%rbp)
  jbe    L93
  movl   $0x5,-0x14(%rbp)
  jmp    L93
L44:
  nop
  jmp    L220
L93:
  nop
  jmp    L220
L157:
  nop
  jmp    L143
L220:
  nop
  jmp    L143
L22:
  nop
L143:
  jmp    L102
L158:
  nop
  jmp    L49
L102:
  nop
L49:
  mov    -0x14(%rbp),%eax
  lea    0x2(%rax),%edx
  mov    -0xc(%rbp),%eax
  lea    -0x2(%rax),%rcx
  mov    -0x28(%rbp),%rax
  add    %rax,%rcx
  mov    -0x18(%rbp),%eax
  mov    %rcx,%rsi
  mov    %eax,%edi
  call   <fnv1a_32@plt>
  mov    %eax,-0x18(%rbp)
L176:
  mov    -0x2c(%rbp),%eax
  add    $0x2,%eax
  cmp    %eax,-0x30(%rbp)
  ja     L125
  jmp    L81
L198:
  nop
L81:
  mov    -0x18(%rbp),%eax
  leave
  ret
```

assistant: ```c
unsigned hash_information_elements(const unsigned char *px, unsigned offset, unsigned length) {
  unsigned hash = 0;
  while (offset + 2 < length) {
    unsigned tlv_tag = px[offset++];
    unsigned tlv_length = px[offset++];
    unsigned tlv_offset = offset;
    unsigned oui = 0;
    unsigned oui_type = 0;
    if (tlv_length > length - offset) {
      if (length - offset == 2)
        break;
      tlv_length = length - offset;
    }
    offset += tlv_length;
    switch (tlv_tag) {
    case 0x00:
    case 0x03:
      continue;
    case 0xdd:
      if (tlv_length >= 4) {
        oui = px[tlv_offset] << 16 | px[tlv_offset + 1] << 8 | px[tlv_offset + 2];
        oui_type = px[tlv_offset + 3];
        switch (oui) {
        case 0x0050f2:
          switch (oui_type) {
          case 8:
            if (tlv_length > 5) {
              switch (px[tlv_offset + 4]) {
              case 0x00:
                if (tlv_length > 5)
                  tlv_length = 5;
                break;
              default:
                break;
              }
            }
            break;
          default:
            break;
          }
          break;
        default:
          break;
        }
      }
      break;
    default:
      break;
    }
    hash = fnv1a_32(hash, px + tlv_offset - 2, tlv_length + 2);
  }
  return hash;
}
```