// File: /workspace/github_cpp_makefile_star2_O3/Distrotech[P]stund/stun.cxx
// Function: stunNatType(StunAddress4&, bool, bool*, bool*, int, StunAddress4*)
NatType
stunNatType( StunAddress4& dest, 
             bool verbose,
             bool* preservePort, // if set, is return for if NAT preservers ports or not
             bool* hairpin,  // if set, is the return for if NAT will hairpin packets
             int port, // port to use for the test, 0 to choose random port
             StunAddress4* sAddr // NIC to use 
   )
{ 
   assert( dest.addr != 0 );
   assert( dest.port != 0 );
	
   if ( hairpin ) 
   {
      *hairpin = false;
   }
	
   if ( port == 0 )
   {
      port = stunRandomPort();
   }
   UInt32 interfaceIp=0;
   if (sAddr)
   {
      interfaceIp = sAddr->addr;
   }
   Socket myFd1 = openPort(port,interfaceIp,verbose);
   Socket myFd2 = openPort(port+1,interfaceIp,verbose);

   if ( ( myFd1 == INVALID_SOCKET) || ( myFd2 == INVALID_SOCKET) )
   {
        cerr << "Some problem opening port/interface to send on" << endl;
       return StunTypeFailure; 
   }

   assert( myFd1 != INVALID_SOCKET );
   assert( myFd2 != INVALID_SOCKET );
    
   bool respTestI=false;
   bool isNat=true;
   StunAddress4 testIchangedAddr;
   StunAddress4 testImappedAddr;
   bool respTestI2=false; 
   bool mappedIpSame = true;
   StunAddress4 testI2mappedAddr;
   StunAddress4 testI2dest=dest;
   bool respTestII=false;
   bool respTestIII=false;

   bool respTestHairpin=false;
   bool respTestPreservePort=false;
	
   memset(&testImappedAddr,0,sizeof(testImappedAddr));
	
   StunAtrString username;
   StunAtrString password;
	
   username.sizeValue = 0;
   password.sizeValue = 0;
	
#ifdef USE_TLS 
   stunGetUserNameAndPassword( dest, username, password );
#endif
	
   int count=0;
   while ( count < 7 )
   {
      struct timeval tv;
      fd_set fdSet; 
#ifdef WIN32
      unsigned int fdSetSize;
#else
      int fdSetSize;
#endif
      FD_ZERO(&fdSet); fdSetSize=0;
      FD_SET(myFd1,&fdSet); fdSetSize = (myFd1+1>fdSetSize) ? myFd1+1 : fdSetSize;
      FD_SET(myFd2,&fdSet); fdSetSize = (myFd2+1>fdSetSize) ? myFd2+1 : fdSetSize;
      tv.tv_sec=0;
      tv.tv_usec=150*1000; // 150 ms 
      if ( count == 0 ) tv.tv_usec=0;
		
      int  err = select(fdSetSize, &fdSet, NULL, NULL, &tv);
      int e = getErrno();
      if ( err == SOCKET_ERROR )
      {
         // error occured
         cerr << "Error " << e << " " << strerror(e) << " in select" << endl;
        return StunTypeFailure; 
     }
      else if ( err == 0 )
      {
         // timeout occured 
         count++;
			
         if ( !respTestI ) 
         {
            stunSendTest( myFd1, dest, username, password, 1 ,verbose );
         }         
			
         if ( (!respTestI2) && respTestI ) 
         {
            // check the address to send to if valid 
            if (  ( testI2dest.addr != 0 ) &&
                  ( testI2dest.port != 0 ) )
            {
               stunSendTest( myFd1, testI2dest, username, password, 10  ,verbose);
            }
         }
			
         if ( !respTestII )
         {
            stunSendTest( myFd2, dest, username, password, 2 ,verbose );
         }
			
         if ( !respTestIII )
         {
            stunSendTest( myFd2, dest, username, password, 3 ,verbose );
         }
			
         if ( respTestI && (!respTestHairpin) )
         {
            if (  ( testImappedAddr.addr != 0 ) &&
                  ( testImappedAddr.port != 0 ) )
            {
               stunSendTest( myFd1, testImappedAddr, username, password, 11 ,verbose );
            }
         }
      }
      else
      {
         //if (verbose) clog << "-----------------------------------------" << endl;
         assert( err>0 );
         // data is avialbe on some fd 
			
         for ( int i=0; i<2; i++)
         {
            Socket myFd;
            if ( i==0 ) 
            {
               myFd=myFd1;
            }
            else
            {
               myFd=myFd2;
            }
				
            if ( myFd!=INVALID_SOCKET ) 
            {					
               if ( FD_ISSET(myFd,&fdSet) )
               {
                  char msg[STUN_MAX_MESSAGE_SIZE];
                  int msgLen = sizeof(msg);
                  						
                  StunAddress4 from;
						
                  getMessage( myFd,
                              msg,
                              &msgLen,
                              &from.addr,
                              &from.port,verbose );
						
                  StunMessage resp;
                  memset(&resp, 0, sizeof(StunMessage));
						
                  stunParseMessage( msg,msgLen, resp,verbose );
						
                  if ( verbose )
                  {
                     clog << "Received message of type " << resp.msgHdr.msgType 
                          << "  id=" << (int)(resp.msgHdr.id.octet[0]) << endl;
                  }
						
                  switch( resp.msgHdr.id.octet[0] )
                  {
                     case 1:
                     {
                        if ( !respTestI )
                        {
									
                           testIchangedAddr.addr = resp.changedAddress.ipv4.addr;
                           testIchangedAddr.port = resp.changedAddress.ipv4.port;
                           testImappedAddr.addr = resp.mappedAddress.ipv4.addr;
                           testImappedAddr.port = resp.mappedAddress.ipv4.port;
			
                           respTestPreservePort = ( testImappedAddr.port == port ); 
                           if ( preservePort )
                           {
                              *preservePort = respTestPreservePort;
                           }								
									
                           testI2dest.addr = resp.changedAddress.ipv4.addr;
									
                           if (sAddr)
                           {
                              sAddr->port = testImappedAddr.port;
                              sAddr->addr = testImappedAddr.addr;
                           }
									
                           count = 0;
                        }		
                        respTestI=true;
                     }
                     break;
                     case 2:
                     {  
                        respTestII=true;
                     }
                     break;
                     case 3:
                     {
                        respTestIII=true;
                     }
                     break;
                     case 10:
                     {
                        if ( !respTestI2 )
                        {
                           testI2mappedAddr.addr = resp.mappedAddress.ipv4.addr;
                           testI2mappedAddr.port = resp.mappedAddress.ipv4.port;
								
                           mappedIpSame = false;
                           if ( (testI2mappedAddr.addr  == testImappedAddr.addr ) &&
                                (testI2mappedAddr.port == testImappedAddr.port ))
                           { 
                              mappedIpSame = true;
                           }
								
							
                        }
                        respTestI2=true;
                     }
                     break;
                     case 11:
                     {
							
                        if ( hairpin ) 
                        {
                           *hairpin = true;
                        }
                        respTestHairpin = true;
                     }
                     break;
                  }
               }
            }
         }
      }
   }
	
   // see if we can bind to this address 
   //cerr << "try binding to " << testImappedAddr << endl;
   Socket s = openPort( 0/*use ephemeral*/, testImappedAddr.addr, false );
   if ( s != INVALID_SOCKET )
   {
      closesocket(s);
      isNat = false;
      //cerr << "binding worked" << endl;
   }
   else
   {
      isNat = true;
      //cerr << "binding failed" << endl;
   }
	
   if (verbose)
   {
      clog << "test I = " << respTestI << endl;
      clog << "test II = " << respTestII << endl;
      clog << "test III = " << respTestIII << endl;
      clog << "test I(2) = " << respTestI2 << endl;
      clog << "is nat  = " << isNat <<endl;
      clog << "mapped IP same = " << mappedIpSame << endl;
      clog << "hairpin = " << respTestHairpin << endl;
      clog << "preserver port = " << respTestPreservePort << endl;
   }
	
#if 0
   // implement logic flow chart from draft RFC
   if ( respTestI )
   {
      if ( isNat )
      {
         if (respTestII)
         {
            return StunTypeConeNat;
         }
         else
         {
            if ( mappedIpSame )
            {
               if ( respTestIII )
               {
                  return StunTypeRestrictedNat;
               }
               else
               {
                  return StunTypePortRestrictedNat;
               }
            }
            else
            {
               return StunTypeSymNat;
            }
         }
      }
      else
      {
         if (respTestII)
         {
            return StunTypeOpen;
         }
         else
         {
            return StunTypeSymFirewall;
         }
      }
   }
   else
   {
      return StunTypeBlocked;
   }
#else
   if ( respTestI ) // not blocked 
   {
      if ( isNat )
      {
         if ( mappedIpSame )
         {
            if (respTestII)
            {
               return StunTypeIndependentFilter;
            }
            else
            {
               if ( respTestIII )
               {
                  return StunTypeDependentFilter;
               }
               else
               {
                  return StunTypePortDependedFilter;
               }
            }
         }
         else // mappedIp is not same 
         {
            return StunTypeDependentMapping;
         }
      }
      else  // isNat is false
      {
         if (respTestII)
         {
            return StunTypeOpen;
         }
         else
         {
            return StunTypeFirewall;
         }
      }
   }
   else
   {
      return StunTypeBlocked;
   }
#endif
	
   return StunTypeUnknown;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1038, %rsp           # imm = 0x1038
movq %r8, 0x38(%rsp)
movq %rdx, 0x98(%rsp)
cmpl $0x0, 0x4(%rdi)
je 0x770a
movq %rdi, %r15
cmpw $0x0, (%rdi)
je 0x7729
movq %r9, %r14
movl %esi, %ebx
testq %rcx, %rcx
je 0x6d26
movb $0x0, (%rcx)
cmpl $0x0, 0x38(%rsp)
movq %rcx, 0xc0(%rsp)
jne 0x6d49
callq 0x4b28
andl $0x3fff, %eax           # imm = 0x3FFF
orl $0x4000, %eax           # imm = 0x4000
movq %rax, 0x38(%rsp)
testq %r14, %r14
movq %r14, 0x90(%rsp)
je 0x6d5c
movl 0x4(%r14), %ebp
jmp 0x6d5e
xorl %ebp, %ebp
movl $0xffff, %r14d          # imm = 0xFFFF
movq 0x38(%rsp), %r12
movl %r12d, %edi
andl %r14d, %edi
movl %ebx, 0x64(%rsp)
movzbl %bl, %ebx
movl %ebp, %esi
movl %ebx, %edx
callq 0x7c14
movl %eax, %r13d
leal 0x1(%r12), %edi
andl %r14d, %edi
movl %ebp, %esi
movl %ebx, %edx
callq 0x7c14
movl %eax, %r12d
movq %r13, 0x28(%rsp)
cmpl $-0x1, %r13d
setne %al
cmpl $-0x1, %r12d
setne %cl
testb %cl, %al
jne 0x6dc5
movq 0x623c(%rip), %rbx      # 0xcff0
leaq 0x3245(%rip), %rsi      # 0xa000
movl $0x2e, %edx
jmp 0x767c
movq (%r15), %rdi
leaq 0x78(%rsp), %rax
movq %rdi, (%rax)
leaq 0x58(%rsp), %rax
movq $0x0, (%rax)
xorl %r8d, %r8d
leaq 0x266(%rsp), %rax
movw %r8w, 0x100(%rax)
movq 0x28(%rsp), %rcx
leal 0x3f(%rcx), %eax
testl %ecx, %ecx
cmovnsl %ecx, %eax
movl $0xffffffff, %r9d       # imm = 0xFFFFFFFF
cmovnsl %ecx, %r9d
movl %eax, %edx
andl $-0x40, %edx
subl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, 0xb8(%rsp)
leaq 0x164(%rsp), %r10
movl $0x1, %r11d
sarl $0x6, %eax
incl %r9d
leal 0x3f(%r12), %edx
testl %r12d, %r12d
cmovnsl %r12d, %edx
movl %edx, %esi
andl $-0x40, %esi
movl %r12d, %ecx
subl %esi, %ecx
shlq %cl, %r11
movq %r11, 0xb0(%rsp)
movw %r8w, 0x100(%r10)
cltq
movq %rax, 0xa8(%rsp)
sarl $0x6, %edx
movslq %edx, %rax
movq %rax, 0xa0(%rsp)
leal 0x1(%r12), %eax
cmpl %r9d, %eax
cmovgl %eax, %r9d
movl %r9d, 0x68(%rsp)
movq %rdi, 0x80(%rsp)
shrq $0x20, %rdi
movq %rdi, 0x48(%rsp)
movb $0x1, %al
movl %eax, 0x8(%rsp)
xorl %edx, %edx
movq $0x0, 0x70(%rsp)
movq $0x0, 0x50(%rsp)
movq $0x0, 0x40(%rsp)
movq $0x0, 0x18(%rsp)
xorl %r14d, %r14d
movq $0x0, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
movl $0x0, 0x4(%rsp)
movq %r15, 0x88(%rsp)
movl %ebx, 0x6c(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x150(%rsp)
movaps %xmm0, 0x140(%rsp)
movaps %xmm0, 0x130(%rsp)
movaps %xmm0, 0x120(%rsp)
movaps %xmm0, 0x110(%rsp)
movaps %xmm0, 0x100(%rsp)
movaps %xmm0, 0xf0(%rsp)
movaps %xmm0, 0xe0(%rsp)
movq 0xb8(%rsp), %rax
movq 0xa8(%rsp), %rcx
orq %rax, 0xe0(%rsp,%rcx,8)
movq 0xb0(%rsp), %rax
movq 0xa0(%rsp), %rcx
orq %rax, 0xe0(%rsp,%rcx,8)
xorl %ecx, %ecx
movq %rcx, 0xd0(%rsp)
movl %edx, 0xc(%rsp)
testl %edx, %edx
movl $0x249f0, %eax          # imm = 0x249F0
cmoveq %rcx, %rax
movq %rax, 0xd8(%rsp)
movl 0x68(%rsp), %edi
leaq 0xe0(%rsp), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
leaq 0xd0(%rsp), %r8
callq 0x21a0
testl %eax, %eax
je 0x7200
cmpl $-0x1, %eax
je 0x75ed
testl %eax, %eax
jle 0x76eb
movb $0x1, %r15b
testb $0x1, %r15b
movl %r12d, %edi
cmovnel 0x28(%rsp), %edi
leal 0x3f(%rdi), %eax
testl %edi, %edi
cmovnsl %edi, %eax
sarl $0x6, %eax
cltq
movq 0xe0(%rsp,%rax,8), %rax
btq %rdi, %rax
jae 0x71c4
movl $0x800, 0x34(%rsp)      # imm = 0x800
leaq 0x830(%rsp), %rbp
movq %rbp, %rsi
leaq 0x34(%rsp), %rdx
leaq 0xcc(%rsp), %rcx
leaq 0xc8(%rsp), %r8
movl %ebx, %r9d
callq 0x7f81
movl $0x4c8, %edx            # imm = 0x4C8
leaq 0x368(%rsp), %r13
movq %r13, %rdi
xorl %esi, %esi
callq 0x2110
movl 0x34(%rsp), %esi
movq %rbp, %rdi
movq %r13, %rdx
movl %ebx, %ecx
callq 0x31ac
testb %bl, %bl
je 0x70c1
movl $0x19, %edx
movq 0x5f6b(%rip), %r13      # 0xcfb8
movq %r13, %rdi
leaq 0x2ff0(%rip), %rsi      # 0xa047
callq 0x21f0
movzwl 0x368(%rsp), %esi
movq %r13, %rdi
callq 0x2130
movq %rax, %rbp
movl $0x5, %edx
movq %rax, %rdi
leaq 0x2fe3(%rip), %rsi      # 0xa061
callq 0x21f0
movzbl 0x36c(%rsp), %esi
movq %rbp, %rdi
callq 0x2290
movq %rax, %rbp
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbp, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %rbp, %rdi
movl 0x6c(%rsp), %ebx
callq 0x2030
movq %rax, %rdi
callq 0x2140
movzbl 0x36c(%rsp), %eax
decl %eax
cmpl $0xa, %eax
ja 0x71be
leaq 0x2325(%rip), %rcx      # 0x9400
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb $0x1, %al
testb $0x1, %r14b
jne 0x71c1
movzwl 0x384(%rsp), %ecx
movq %rcx, 0x20(%rsp)
movzwl %cx, %ecx
movq 0x38(%rsp), %rdi
cmpl %ecx, %edi
sete %dl
movq %rdx, 0x70(%rsp)
movq 0x98(%rsp), %rsi
testq %rsi, %rsi
movq 0x90(%rsp), %rdx
je 0x7129
cmpl %ecx, %edi
sete (%rsi)
movl 0x388(%rsp), %esi
movl $0x0, 0xc(%rsp)
movl 0x3c0(%rsp), %ecx
movq %rcx, 0x48(%rsp)
testq %rdx, %rdx
movl %esi, 0x4(%rsp)
je 0x71c1
movq 0x20(%rsp), %rcx
movw %cx, (%rdx)
movl %esi, 0x4(%rdx)
jmp 0x71c1
movb $0x1, %al
movq %rax, 0x40(%rsp)
jmp 0x71be
movb $0x1, %al
movq %rax, 0x18(%rsp)
jmp 0x71be
testb $0x1, 0x10(%rsp)
jne 0x71b7
movl 0x4(%rsp), %eax
cmpl %eax, 0x388(%rsp)
jne 0x71af
movq 0x20(%rsp), %rax
cmpw %ax, 0x384(%rsp)
sete %al
movl %eax, 0x8(%rsp)
jmp 0x71b7
movb $0x1, %al
movq %rax, 0x50(%rsp)
movq 0xc0(%rsp), %rax
testq %rax, %rax
je 0x71be
movb $0x1, (%rax)
jmp 0x71be
movl $0x0, 0x8(%rsp)
movb $0x1, %al
movq %rax, 0x10(%rsp)
movl %r14d, %eax
movl %eax, %r14d
testb $0x1, %r15b
movl $0x0, %r15d
jne 0x6fb6
movl 0x4(%rsp), %eax
movl %eax, 0x5c(%rsp)
movq 0x48(%rsp), %rax
movl %eax, 0x7c(%rsp)
movq 0x20(%rsp), %rax
movw %ax, 0x58(%rsp)
movq 0x88(%rsp), %r15
movl 0xc(%rsp), %edx
jmp 0x7316
testb $0x1, %r14b
je 0x724c
cmpw $0x0, 0x80(%rsp)
setne %al
movq 0x10(%rsp), %rcx
notb %cl
cmpl $0x0, 0x48(%rsp)
setne %dl
andb %cl, %dl
andb %al, %dl
cmpb $0x1, %dl
jne 0x7272
movq 0x28(%rsp), %rdi
leaq 0x78(%rsp), %rsi
leaq 0x266(%rsp), %rdx
leaq 0x164(%rsp), %rcx
movl $0xa, %r8d
jmp 0x726a
movq 0x28(%rsp), %rdi
movq %r15, %rsi
leaq 0x266(%rsp), %rdx
leaq 0x164(%rsp), %rcx
movl $0x1, %r8d
movl %ebx, %r9d
callq 0x6af5
testb $0x1, 0x18(%rsp)
jne 0x729d
movl %r12d, %edi
movq %r15, %rsi
leaq 0x266(%rsp), %rdx
leaq 0x164(%rsp), %rcx
movl $0x2, %r8d
movl %ebx, %r9d
callq 0x6af5
testb $0x1, 0x40(%rsp)
jne 0x72c8
movl %r12d, %edi
movq %r15, %rsi
leaq 0x266(%rsp), %rdx
leaq 0x164(%rsp), %rcx
movl $0x3, %r8d
movl %ebx, %r9d
callq 0x6af5
movl 0xc(%rsp), %edx
incl %edx
testb $0x1, %r14b
je 0x7316
testb $0x1, 0x50(%rsp)
jne 0x7316
cmpl $0x0, 0x4(%rsp)
je 0x7316
cmpw $0x0, 0x20(%rsp)
je 0x7316
movl %edx, %ebp
movq 0x28(%rsp), %rdi
leaq 0x58(%rsp), %rsi
leaq 0x266(%rsp), %rdx
leaq 0x164(%rsp), %rcx
movl $0xb, %r8d
movl %ebx, %r9d
callq 0x6af5
movl %ebp, %edx
cmpl $0x7, %edx
jl 0x6ee9
xorl %edi, %edi
movl 0x4(%rsp), %esi
xorl %edx, %edx
callq 0x7c14
movl %eax, %ebx
cmpl $-0x1, %eax
je 0x733a
movl %ebx, %edi
callq 0x22b0
cmpb $0x0, 0x64(%rsp)
je 0x75be
xorl %ebp, %ebp
cmpl $-0x1, %ebx
sete %bpl
movq 0x5c63(%rip), %r12      # 0xcfb8
leaq 0x2d0b(%rip), %rsi      # 0xa067
movl $0x9, %edx
movq %r12, %rdi
callq 0x21f0
movzbl %r14b, %esi
andl $0x1, %esi
movq %r12, %rdi
callq 0x2270
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
leaq 0x2cc8(%rip), %rsi      # 0xa071
movl $0xa, %edx
movq %r12, %rdi
callq 0x21f0
movzbl 0x18(%rsp), %esi
andl $0x1, %esi
movq %r12, %rdi
callq 0x2270
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
leaq 0x2c85(%rip), %rsi      # 0xa07c
movl $0xb, %edx
movq %r12, %rdi
callq 0x21f0
movzbl 0x40(%rsp), %esi
andl $0x1, %esi
movq %r12, %rdi
callq 0x2270
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
leaq 0x2c43(%rip), %rsi      # 0xa088
movl $0xc, %edx
movq %r12, %rdi
callq 0x21f0
movzbl 0x10(%rsp), %esi
andl $0x1, %esi
movq %r12, %rdi
callq 0x2270
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
leaq 0x2c02(%rip), %rsi      # 0xa095
movl $0xa, %edx
movq %r12, %rdi
callq 0x21f0
movq %r12, %rdi
movl %ebp, %esi
callq 0x2270
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
leaq 0x2bc5(%rip), %rsi      # 0xa0a0
movl $0x11, %edx
movq %r12, %rdi
callq 0x21f0
movzbl 0x8(%rsp), %esi
andl $0x1, %esi
movq %r12, %rdi
callq 0x2270
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
leaq 0x2b89(%rip), %rsi      # 0xa0b2
movl $0xa, %edx
movq %r12, %rdi
callq 0x21f0
movzbl 0x50(%rsp), %esi
andl $0x1, %esi
movq %r12, %rdi
callq 0x2270
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
leaq 0x2b46(%rip), %rsi      # 0xa0bd
movl $0x11, %edx
movq %r12, %rdi
callq 0x21f0
movzbl 0x70(%rsp), %esi
andl $0x1, %esi
movq %r12, %rdi
callq 0x2270
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
movl $0x3, %eax
testb $0x1, %r14b
je 0x76b0
cmpl $-0x1, %ebx
je 0x76c2
testb $0x1, 0x18(%rsp)
movl $0x2, %ecx
movl $0x8, %eax
cmovnel %ecx, %eax
jmp 0x76b0
callq 0x2040
movl (%rax), %ebp
movq 0x59f5(%rip), %rbx      # 0xcff0
leaq 0x2a2d(%rip), %rsi      # 0xa02f
movl $0x6, %edx
movq %rbx, %rdi
callq 0x21f0
movq %rbx, %rdi
movl %ebp, %esi
callq 0x2290
movq %rax, %rbx
leaq 0x1e62(%rip), %rsi      # 0x9485
movl $0x1, %edx
movq %rax, %rdi
callq 0x21f0
movl %ebp, %edi
callq 0x20a0
testq %rax, %rax
je 0x7657
movq %rax, %r14
movq %rax, %rdi
callq 0x20c0
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rdx
callq 0x21f0
jmp 0x7670
movq (%rbx), %rax
movq -0x18(%rax), %rax
movq %rbx, %rdi
addq %rax, %rdi
movl 0x20(%rbx,%rax), %esi
orl $0x1, %esi
callq 0x2280
leaq 0x29bf(%rip), %rsi      # 0xa036
movl $0xa, %edx
movq %rbx, %rdi
callq 0x21f0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
movl $0x1, %eax
addq $0x1038, %rsp           # imm = 0x1038
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x7, %eax
testb $0x1, 0x8(%rsp)
je 0x76b0
movl $0x4, %eax
testb $0x1, 0x18(%rsp)
jne 0x76b0
movzbl 0x40(%rsp), %ecx
andl $0x1, %ecx
movl $0x6, %eax
subl %ecx, %eax
jmp 0x76b0
leaq 0x294f(%rip), %rdi      # 0xa041
leaq 0x2054(%rip), %rsi      # 0x974d
leaq 0x28b1(%rip), %rcx      # 0x9fb1
movl $0x7d5, %edx            # imm = 0x7D5
callq 0x2120
leaq 0x27b5(%rip), %rdi      # 0x9ec6
leaq 0x2035(%rip), %rsi      # 0x974d
leaq 0x2892(%rip), %rcx      # 0x9fb1
movl $0x75b, %edx            # imm = 0x75B
callq 0x2120
leaq 0x27a5(%rip), %rdi      # 0x9ed5
leaq 0x2016(%rip), %rsi      # 0x974d
leaq 0x2873(%rip), %rcx      # 0x9fb1
movl $0x75c, %edx            # imm = 0x75C
callq 0x2120