unsigned smellslike_bittorrent_uTP_v0(const unsigned char *px,
                                      unsigned length) {
  unsigned type;
  unsigned extension;
  unsigned difference;
  unsigned ack_nr;
  unsigned offset = 23;
  if (length < 23)
    return 0;
  type = px[18];
  if (type > 4) {
    return 0;
  }
  extension = px[17];
  if (extension > 2)
    return 0;
  difference = (*((unsigned char *)(px + 12) + 0) << 24 |
                *((unsigned char *)(px + 12) + 1) << 16 |
                *((unsigned char *)(px + 12) + 2) << 8 |
                *((unsigned char *)(px + 12) + 3) << 0);
  ack_nr = (*((unsigned char *)(px + 21) + 0) << 8 |
            *((unsigned char *)(px + 21) + 1) << 0);
  switch (type) {
  case 4:
    if (difference != 0 && difference != 0x7fffffff)
      return 0;
    if (ack_nr != 0)
      return 0;
    break;
  }
  while (extension) {
    unsigned x;
    unsigned len;
    if (offset + 2 > length)
      return 0;
    x = extension;
    extension = px[offset++];
    len = px[offset++];
    switch (x) {
    case 1:
      if (len != 4)
        return 0;
      break;
    case 2:
      if (len < 4)
        return 0;
      if (len & 0x3)
        return 0;
      break;
      break;
    default:
      return 0;
    }
    offset += len;
  }
  return 1;
}


x86 assembly (clang, -O0):
<smellslike_bittorrent_uTP_v0>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
movl   $0x17,-0x28(%rbp)
cmpl   $0x17,-0x14(%rbp)
jae    1128 <smellslike_bittorrent_uTP_v0+0x28>
movl   $0x0,-0x4(%rbp)
jmp    12c8 <smellslike_bittorrent_uTP_v0+0x1c8>
mov    -0x10(%rbp),%rax
movzbl 0x12(%rax),%eax
mov    %eax,-0x18(%rbp)
cmpl   $0x4,-0x18(%rbp)
jbe    1149 <smellslike_bittorrent_uTP_v0+0x49>
movl   $0x0,-0x4(%rbp)
jmp    12c8 <smellslike_bittorrent_uTP_v0+0x1c8>
mov    -0x10(%rbp),%rax
movzbl 0x11(%rax),%eax
mov    %eax,-0x1c(%rbp)
cmpl   $0x2,-0x1c(%rbp)
jbe    116a <smellslike_bittorrent_uTP_v0+0x6a>
movl   $0x0,-0x4(%rbp)
jmp    12c8 <smellslike_bittorrent_uTP_v0+0x1c8>
mov    -0x10(%rbp),%rax
mov    0xc(%rax),%eax
bswap  %eax
mov    %eax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movzwl 0x15(%rax),%eax
shl    $0x10,%eax
bswap  %eax
mov    %eax,-0x24(%rbp)
mov    -0x18(%rbp),%eax
sub    $0x4,%eax
jne    11d5 <smellslike_bittorrent_uTP_v0+0xd5>
jmp    1197 <smellslike_bittorrent_uTP_v0+0x97>
cmpl   $0x0,-0x20(%rbp)
je     11ba <smellslike_bittorrent_uTP_v0+0xba>
cmpl   $0x7fffffff,-0x20(%rbp)
je     11ba <smellslike_bittorrent_uTP_v0+0xba>
movl   $0x0,-0x4(%rbp)
jmp    12c8 <smellslike_bittorrent_uTP_v0+0x1c8>
cmpl   $0x0,-0x24(%rbp)
je     11d0 <smellslike_bittorrent_uTP_v0+0xd0>
movl   $0x0,-0x4(%rbp)
jmp    12c8 <smellslike_bittorrent_uTP_v0+0x1c8>
jmp    11d5 <smellslike_bittorrent_uTP_v0+0xd5>
jmp    11da <smellslike_bittorrent_uTP_v0+0xda>
cmpl   $0x0,-0x1c(%rbp)
je     12c1 <smellslike_bittorrent_uTP_v0+0x1c1>
mov    -0x28(%rbp),%eax
add    $0x2,%eax
cmp    -0x14(%rbp),%eax
jbe    11ff <smellslike_bittorrent_uTP_v0+0xff>
movl   $0x0,-0x4(%rbp)
jmp    12c8 <smellslike_bittorrent_uTP_v0+0x1c8>
mov    -0x1c(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x28(%rbp)
movzbl (%rax,%rcx,1),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x28(%rbp)
movzbl (%rax,%rcx,1),%eax
mov    %eax,-0x30(%rbp)
mov    -0x2c(%rbp),%eax
mov    %eax,-0x34(%rbp)
sub    $0x1,%eax
je     1256 <smellslike_bittorrent_uTP_v0+0x156>
jmp    1245 <smellslike_bittorrent_uTP_v0+0x145>
mov    -0x34(%rbp),%eax
sub    $0x2,%eax
je     1271 <smellslike_bittorrent_uTP_v0+0x171>
jmp    12a7 <smellslike_bittorrent_uTP_v0+0x1a7>
cmpl   $0x4,-0x30(%rbp)
je     126c <smellslike_bittorrent_uTP_v0+0x16c>
movl   $0x0,-0x4(%rbp)
jmp    12c8 <smellslike_bittorrent_uTP_v0+0x1c8>
jmp    12b3 <smellslike_bittorrent_uTP_v0+0x1b3>
cmpl   $0x4,-0x30(%rbp)
jae    1287 <smellslike_bittorrent_uTP_v0+0x187>
movl   $0x0,-0x4(%rbp)
jmp    12c8 <smellslike_bittorrent_uTP_v0+0x1c8>
mov    -0x30(%rbp),%eax
and    $0x3,%eax
cmp    $0x0,%eax
je     12a2 <smellslike_bittorrent_uTP_v0+0x1a2>
movl   $0x0,-0x4(%rbp)
jmp    12c8 <smellslike_bittorrent_uTP_v0+0x1c8>
jmp    12b3 <smellslike_bittorrent_uTP_v0+0x1b3>
movl   $0x0,-0x4(%rbp)
jmp    12c8 <smellslike_bittorrent_uTP_v0+0x1c8>
mov    -0x30(%rbp),%eax
add    -0x28(%rbp),%eax
mov    %eax,-0x28(%rbp)
jmp    11da <smellslike_bittorrent_uTP_v0+0xda>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<smellslike_bittorrent_uTP_v0>:
xor    %eax,%eax
cmp    $0x17,%esi
jb     11b5 <smellslike_bittorrent_uTP_v0+0xb5>
mov    0x12(%rdi),%cl
cmp    $0x4,%cl
ja     11b5 <smellslike_bittorrent_uTP_v0+0xb5>
mov    0x11(%rdi),%r9b
cmp    $0x2,%r9b
ja     11b5 <smellslike_bittorrent_uTP_v0+0xb5>
cmp    $0x4,%cl
jne    1148 <smellslike_bittorrent_uTP_v0+0x48>
movzwl 0x15(%rdi),%ecx
mov    0xc(%rdi),%edx
bswap  %edx
cmp    $0x7fffffff,%edx
je     113f <smellslike_bittorrent_uTP_v0+0x3f>
test   %edx,%edx
jne    11b5 <smellslike_bittorrent_uTP_v0+0xb5>
shl    $0x10,%ecx
bswap  %ecx
test   %ecx,%ecx
jne    11b5 <smellslike_bittorrent_uTP_v0+0xb5>
test   %r9b,%r9b
je     11b0 <smellslike_bittorrent_uTP_v0+0xb0>
mov    $0x17,%ecx
jmp    116d <smellslike_bittorrent_uTP_v0+0x6d>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
add    %r10d,%edx
mov    %r8d,%r9d
mov    %edx,%ecx
test   %r8b,%r8b
je     11b0 <smellslike_bittorrent_uTP_v0+0xb0>
lea    0x2(%rcx),%edx
cmp    %esi,%edx
ja     11b5 <smellslike_bittorrent_uTP_v0+0xb5>
mov    %ecx,%r8d
add    $0x1,%ecx
movzbl (%rdi,%r8,1),%r8d
movzbl (%rdi,%rcx,1),%r10d
cmp    $0x2,%r9b
je     11a0 <smellslike_bittorrent_uTP_v0+0xa0>
cmp    $0x1,%r9b
jne    11b5 <smellslike_bittorrent_uTP_v0+0xb5>
cmp    $0x4,%r10b
je     1160 <smellslike_bittorrent_uTP_v0+0x60>
jmp    11b5 <smellslike_bittorrent_uTP_v0+0xb5>
nopl   0x0(%rax,%rax,1)
cmp    $0x4,%r10b
jb     11b5 <smellslike_bittorrent_uTP_v0+0xb5>
mov    %r10d,%ecx
and    $0x3,%ecx
je     1160 <smellslike_bittorrent_uTP_v0+0x60>
jmp    11b5 <smellslike_bittorrent_uTP_v0+0xb5>
mov    $0x1,%eax
ret

LLVM IR (-O0):
define i32 @smellslike_bittorrent_uTP_v0(i8* %0, i32 %1) {
%3 = alloca i32
%4 = alloca i8*
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
store i8* %0, i8** %4
store i32 %1, i32* %5
store i32 23, i32* %10
%13 = load i32, i32* %5
%14 = icmp ult i32 %13, 23
br i1 %14, label %15, label %16
15: ; preds = %2
store i32 0, i32* %3
br label %134
16: ; preds = %2
%17 = load i8*, i8** %4
%18 = getelementptr inbounds i8, i8* %17, i64 18
%19 = load i8, i8* %18
%20 = zext i8 %19 to i32
store i32 %20, i32* %6
%21 = load i32, i32* %6
%22 = icmp ugt i32 %21, 4
br i1 %22, label %23, label %24
23: ; preds = %16
store i32 0, i32* %3
br label %134
24: ; preds = %16
%25 = load i8*, i8** %4
%26 = getelementptr inbounds i8, i8* %25, i64 17
%27 = load i8, i8* %26
%28 = zext i8 %27 to i32
store i32 %28, i32* %7
%29 = load i32, i32* %7
%30 = icmp ugt i32 %29, 2
br i1 %30, label %31, label %32
31: ; preds = %24
store i32 0, i32* %3
br label %134
32: ; preds = %24
%33 = load i8*, i8** %4
%34 = getelementptr inbounds i8, i8* %33, i64 12
%35 = getelementptr inbounds i8, i8* %34, i64 0
%36 = load i8, i8* %35
%37 = zext i8 %36 to i32
%38 = shl i32 %37, 24
%39 = load i8*, i8** %4
%40 = getelementptr inbounds i8, i8* %39, i64 12
%41 = getelementptr inbounds i8, i8* %40, i64 1
%42 = load i8, i8* %41
%43 = zext i8 %42 to i32
%44 = shl i32 %43, 16
%45 = or i32 %38, %44
%46 = load i8*, i8** %4
%47 = getelementptr inbounds i8, i8* %46, i64 12
%48 = getelementptr inbounds i8, i8* %47, i64 2
%49 = load i8, i8* %48
%50 = zext i8 %49 to i32
%51 = shl i32 %50, 8
%52 = or i32 %45, %51
%53 = load i8*, i8** %4
%54 = getelementptr inbounds i8, i8* %53, i64 12
%55 = getelementptr inbounds i8, i8* %54, i64 3
%56 = load i8, i8* %55
%57 = zext i8 %56 to i32
%58 = shl i32 %57, 0
%59 = or i32 %52, %58
store i32 %59, i32* %8
%60 = load i8*, i8** %4
%61 = getelementptr inbounds i8, i8* %60, i64 21
%62 = getelementptr inbounds i8, i8* %61, i64 0
%63 = load i8, i8* %62
%64 = zext i8 %63 to i32
%65 = shl i32 %64, 8
%66 = load i8*, i8** %4
%67 = getelementptr inbounds i8, i8* %66, i64 21
%68 = getelementptr inbounds i8, i8* %67, i64 1
%69 = load i8, i8* %68
%70 = zext i8 %69 to i32
%71 = shl i32 %70, 0
%72 = or i32 %65, %71
store i32 %72, i32* %9
%73 = load i32, i32* %6
switch i32 %73, label %86 [
i32 4, label %74
]
74: ; preds = %32
%75 = load i32, i32* %8
%76 = icmp ne i32 %75, 0
br i1 %76, label %77, label %81
77: ; preds = %74
%78 = load i32, i32* %8
%79 = icmp ne i32 %78, 2147483647
br i1 %79, label %80, label %81
80: ; preds = %77
store i32 0, i32* %3
br label %134
81: ; preds = %77, %74
%82 = load i32, i32* %9
%83 = icmp ne i32 %82, 0
br i1 %83, label %84, label %85
84: ; preds = %81
store i32 0, i32* %3
br label %134
85: ; preds = %81
br label %86
86: ; preds = %32, %85
br label %87
87: ; preds = %129, %86
%88 = load i32, i32* %7
%89 = icmp ne i32 %88, 0
br i1 %89, label %90, label %133
90: ; preds = %87
%91 = load i32, i32* %10
%92 = add i32 %91, 2
%93 = load i32, i32* %5
%94 = icmp ugt i32 %92, %93
br i1 %94, label %95, label %96
95: ; preds = %90
store i32 0, i32* %3
br label %134
96: ; preds = %90
%97 = load i32, i32* %7
store i32 %97, i32* %11
%98 = load i8*, i8** %4
%99 = load i32, i32* %10
%100 = add i32 %99, 1
store i32 %100, i32* %10
%101 = zext i32 %99 to i64
%102 = getelementptr inbounds i8, i8* %98, i64 %101
%103 = load i8, i8* %102
%104 = zext i8 %103 to i32
store i32 %104, i32* %7
%105 = load i8*, i8** %4
%106 = load i32, i32* %10
%107 = add i32 %106, 1
store i32 %107, i32* %10
%108 = zext i32 %106 to i64
%109 = getelementptr inbounds i8, i8* %105, i64 %108
%110 = load i8, i8* %109
%111 = zext i8 %110 to i32
store i32 %111, i32* %12
%112 = load i32, i32* %11
switch i32 %112, label %128 [
i32 1, label %113
i32 2, label %118
]
113: ; preds = %96
%114 = load i32, i32* %12
%115 = icmp ne i32 %114, 4
br i1 %115, label %116, label %117
116: ; preds = %113
store i32 0, i32* %3
br label %134
117: ; preds = %113
br label %129
118: ; preds = %96
%119 = load i32, i32* %12
%120 = icmp ult i32 %119, 4
br i1 %120, label %121, label %122
121: ; preds = %118
store i32 0, i32* %3
br label %134
122: ; preds = %118
%123 = load i32, i32* %12
%124 = and i32 %123, 3
%125 = icmp ne i32 %124, 0
br i1 %125, label %126, label %127
126: ; preds = %122
store i32 0, i32* %3
br label %134
127: ; preds = %122
br label %129
128: ; preds = %96
store i32 0, i32* %3
br label %134
129: ; preds = %127, %117
%130 = load i32, i32* %12
%131 = load i32, i32* %10
%132 = add i32 %131, %130
store i32 %132, i32* %10
br label %87
133: ; preds = %87
store i32 1, i32* %3
br label %134
134: ; preds = %133, %128, %126, %121, %116, %95, %84, %80, %31, %23, %15
%135 = load i32, i32* %3
ret i32 %135
}

LLVM IR (-O2):
define i32 @smellslike_bittorrent_uTP_v0(i8* nocapture %0, i32 %1) {
%3 = icmp ult i32 %1, 23
br i1 %3, label %69, label %4
4: ; preds = %2
%5 = getelementptr inbounds i8, i8* %0, i64 18
%6 = load i8, i8* %5
%7 = icmp ugt i8 %6, 4
br i1 %7, label %69, label %8
8: ; preds = %4
%9 = getelementptr inbounds i8, i8* %0, i64 17
%10 = load i8, i8* %9
%11 = icmp ugt i8 %10, 2
br i1 %11, label %69, label %12
12: ; preds = %8
%13 = getelementptr inbounds i8, i8* %0, i64 21
%14 = load i8, i8* %13
%15 = zext i8 %14 to i32
%16 = shl nuw nsw i32 %15, 8
%17 = getelementptr inbounds i8, i8* %0, i64 22
%18 = load i8, i8* %17
%19 = zext i8 %18 to i32
%20 = or i32 %16, %19
%21 = icmp eq i8 %6, 4
br i1 %21, label %22, label %43
22: ; preds = %12
%23 = getelementptr inbounds i8, i8* %0, i64 12
%24 = load i8, i8* %23
%25 = zext i8 %24 to i32
%26 = shl nuw i32 %25, 24
%27 = getelementptr inbounds i8, i8* %0, i64 13
%28 = load i8, i8* %27
%29 = zext i8 %28 to i32
%30 = shl nuw nsw i32 %29, 16
%31 = or i32 %30, %26
%32 = getelementptr inbounds i8, i8* %0, i64 14
%33 = load i8, i8* %32
%34 = zext i8 %33 to i32
%35 = shl nuw nsw i32 %34, 8
%36 = or i32 %31, %35
%37 = getelementptr inbounds i8, i8* %0, i64 15
%38 = load i8, i8* %37
%39 = zext i8 %38 to i32
%40 = or i32 %36, %39
switch i32 %40, label %69 [
i32 2147483647, label %41
i32 0, label %41
]
41: ; preds = %22, %22
%42 = icmp eq i32 %20, 0
br i1 %42, label %43, label %69
43: ; preds = %41, %12
%44 = icmp eq i8 %10, 0
br i1 %44, label %69, label %45
45: ; preds = %43, %66
%46 = phi i8 [ %54, %66 ], [ %10, %43 ]
%47 = phi i32 [ %67, %66 ], [ 23, %43 ]
%48 = add i32 %47, 2
%49 = icmp ugt i32 %48, %1
br i1 %49, label %69, label %50
50: ; preds = %45
%51 = add i32 %47, 1
%52 = zext i32 %47 to i64
%53 = getelementptr inbounds i8, i8* %0, i64 %52
%54 = load i8, i8* %53
%55 = zext i32 %51 to i64
%56 = getelementptr inbounds i8, i8* %0, i64 %55
%57 = load i8, i8* %56
%58 = zext i8 %57 to i32
switch i8 %46, label %69 [
i8 1, label %59
i8 2, label %61
]
59: ; preds = %50
%60 = icmp eq i8 %57, 4
br i1 %60, label %66, label %69
61: ; preds = %50
%62 = icmp ugt i8 %57, 3
%63 = and i32 %58, 3
%64 = icmp eq i32 %63, 0
%65 = select i1 %62, i1 %64, i1 false
br i1 %65, label %66, label %69
66: ; preds = %59, %61
%67 = add i32 %48, %58
%68 = icmp eq i8 %54, 0
br i1 %68, label %69, label %45
69: ; preds = %66, %45, %59, %61, %50, %43, %41, %22, %8, %4, %2
%70 = phi i32 [ 0, %2 ], [ 0, %4 ], [ 0, %8 ], [ 0, %22 ], [ 0, %41 ], [ 1, %43 ], [ 1, %66 ], [ 0, %45 ], [ 0, %59 ], [ 0, %61 ], [ 0, %50 ]
ret i32 %70
}