// File: /workspace/github_cpp_makefile_star2_O1/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, 0x50(%rsp)
movq %rdx, 0x98(%rsp)
movl %esi, 0x2c(%rsp)
cmpl $0x0, 0x4(%rdi)
je 0x76fe
movq %rdi, %rbx
cmpw $0x0, (%rdi)
je 0x771d
movq %r9, %r14
testq %rcx, %rcx
je 0x6c87
movb $0x0, (%rcx)
cmpl $0x0, 0x50(%rsp)
movq %rcx, 0xc0(%rsp)
jne 0x6caa
callq 0x4b17
andl $0x3fff, %eax           # imm = 0x3FFF
orl $0x4000, %eax           # imm = 0x4000
movq %rax, 0x50(%rsp)
testq %r14, %r14
movq %rbx, 0x48(%rsp)
je 0x6cba
movl 0x4(%r14), %ebx
jmp 0x6cbc
xorl %ebx, %ebx
movl $0xffff, %ebp           # imm = 0xFFFF
movq 0x50(%rsp), %r15
movl %r15d, %edi
andl %ebp, %edi
movzbl 0x2c(%rsp), %r13d
movl %ebx, %esi
movl %r13d, %edx
callq 0x7c10
movl %eax, %r12d
leal 0x1(%r15), %edi
andl %ebp, %edi
movl %ebx, %esi
movl %r13d, 0x8(%rsp)
movl %r13d, %edx
callq 0x7c10
movl %eax, %ebp
cmpl $-0x1, %r12d
setne %al
cmpl $-0x1, %ebp
setne %cl
testb %cl, %al
jne 0x6d4d
movq 0x62e3(%rip), %rbx      # 0xcff0
leaq 0x32f4(%rip), %rsi      # 0xa008
movl $0x2e, %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
jmp 0x73c8
movq %r14, 0x90(%rsp)
movq 0x48(%rsp), %rax
movq (%rax), %rcx
leaq 0x80(%rsp), %rsi
movq %rcx, 0x88(%rsp)
movq %rcx, (%rsi)
leaq 0x60(%rsp), %rdi
movq $0x0, (%rdi)
xorl %eax, %eax
leaq 0x266(%rsp), %rcx
movw %ax, 0x100(%rcx)
leaq 0x164(%rsp), %rcx
movw %ax, 0x100(%rcx)
leal 0x3f(%r12), %eax
testl %r12d, %r12d
cmovnsl %r12d, %eax
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
cmovnsl %r12d, %r8d
movl %eax, %edx
andl $-0x40, %edx
movl %r12d, %ecx
subl %edx, %ecx
movl $0x1, %r9d
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, 0xb0(%rsp)
sarl $0x6, %eax
cltq
movq %rax, 0xa8(%rsp)
incl %r8d
leal 0x3f(%rbp), %eax
testl %ebp, %ebp
cmovnsl %ebp, %eax
movl %eax, %edx
andl $-0x40, %edx
movl %ebp, %ecx
subl %edx, %ecx
shlq %cl, %r9
movq %r9, 0xb8(%rsp)
sarl $0x6, %eax
leal 0x1(%rbp), %ecx
cmpl %r8d, %ecx
cmovgl %ecx, %r8d
movl %r8d, 0x74(%rsp)
cltq
movq %rax, 0xa0(%rsp)
movl 0x4(%rsi), %eax
movl %eax, 0x24(%rsp)
movb $0x1, %al
movl %eax, 0x1c(%rsp)
movl 0x4(%rdi), %eax
movl %eax, 0x20(%rsp)
movl $0x0, 0xc(%rsp)
movq $0x0, 0x30(%rsp)
xorl %r14d, %r14d
movq $0x0, 0x38(%rsp)
movq $0x0, 0x58(%rsp)
movq $0x0, 0x68(%rsp)
movq $0x0, 0x78(%rsp)
xorl %ebx, %ebx
cmpl $0x6, %ebx
jg 0x73df
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 0xb0(%rsp), %rax
movq 0xa8(%rsp), %rcx
orq %rax, 0xe0(%rsp,%rcx,8)
movq 0xb8(%rsp), %rax
movq 0xa0(%rsp), %rcx
orq %rax, 0xe0(%rsp,%rcx,8)
xorl %ecx, %ecx
movq %rcx, 0xd0(%rsp)
testl %ebx, %ebx
movl $0x249f0, %eax          # imm = 0x249F0
cmoveq %rcx, %rax
movq %rax, 0xd8(%rsp)
movl 0x74(%rsp), %edi
leaq 0xe0(%rsp), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
leaq 0xd0(%rsp), %r8
callq 0x21a0
movl %eax, %r15d
cmpl $-0x1, %eax
je 0x71ba
testl %r15d, %r15d
je 0x7236
movl %r15d, 0x28(%rsp)
movl %ebx, 0x40(%rsp)
jle 0x76df
movl $0x1, %r15d
cmpl $0x1, %r15d
movl %ebp, %edi
cmovel %r12d, %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 0x718c
movq %r14, 0x10(%rsp)
movq %rbp, %r14
movq %r12, %rbp
movl $0x800, 0x44(%rsp)      # imm = 0x800
leaq 0x830(%rsp), %rbx
movq %rbx, %rsi
leaq 0x44(%rsp), %rdx
leaq 0xcc(%rsp), %rcx
leaq 0xc8(%rsp), %r8
movl 0x8(%rsp), %r13d
movl %r13d, %r9d
callq 0x7f4a
movl $0x4c8, %edx            # imm = 0x4C8
leaq 0x368(%rsp), %r12
movq %r12, %rdi
xorl %esi, %esi
callq 0x2110
movl 0x44(%rsp), %esi
movq %rbx, %rdi
movq %r12, %rdx
movl %r13d, %ecx
callq 0x3248
cmpb $0x0, 0x2c(%rsp)
je 0x705d
movl $0x19, %edx
movq 0x5fcb(%rip), %rbx      # 0xcfb8
movq %rbx, %rdi
leaq 0x3058(%rip), %rsi      # 0xa04f
callq 0x21f0
movzwl 0x368(%rsp), %esi
movq %rbx, %rdi
callq 0x2130
movq %rax, %rbx
movl $0x5, %edx
movq %rax, %rdi
leaq 0x304b(%rip), %rsi      # 0xa069
callq 0x21f0
movzbl 0x36c(%rsp), %esi
movq %rbx, %rdi
callq 0x22a0
movq %rax, %rbx
movq (%rax), %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
movzbl 0x36c(%rsp), %eax
decl %eax
cmpl $0xa, %eax
ja 0x7146
leaq 0x2391(%rip), %rcx      # 0x9408
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
movq %rbp, %r12
jmpq *%rax
movb $0x1, %al
testb $0x1, 0x10(%rsp)
movq %r14, %rbp
jne 0x7189
movzwl 0x384(%rsp), %ecx
movl %ecx, 0xc(%rsp)
cmpl %ecx, 0x50(%rsp)
sete %cl
movq 0x98(%rsp), %rsi
testq %rsi, %rsi
movq 0x90(%rsp), %rdx
je 0x70bd
movb %cl, (%rsi)
movq %rcx, 0x78(%rsp)
movl 0x388(%rsp), %ecx
movl $0x0, 0x40(%rsp)
movl 0x3c0(%rsp), %esi
movl %esi, 0x24(%rsp)
testq %rdx, %rdx
movl %ecx, 0x20(%rsp)
je 0x7189
movl 0xc(%rsp), %esi
movw %si, (%rdx)
movl %ecx, 0x4(%rdx)
jmp 0x7189
movb $0x1, %al
movq %rax, 0x58(%rsp)
jmp 0x7108
movb $0x1, %al
movq %rax, 0x38(%rsp)
movq 0x10(%rsp), %rax
movq %r14, %rbp
jmp 0x7189
testb $0x1, 0x30(%rsp)
movq %r14, %rbp
je 0x7150
movb $0x1, %al
movq %rax, 0x30(%rsp)
jmp 0x713f
movb $0x1, %al
movq %rax, 0x68(%rsp)
movq 0xc0(%rsp), %rax
testq %rax, %rax
movq %r14, %rbp
je 0x713f
movb $0x1, (%rax)
movq 0x10(%rsp), %rax
jmp 0x7189
movq 0x10(%rsp), %rax
movq %rbp, %r12
jmp 0x710d
movl 0x20(%rsp), %eax
cmpl %eax, 0x388(%rsp)
movq 0x10(%rsp), %r13
jne 0x7177
movl 0xc(%rsp), %eax
cmpw %ax, 0x384(%rsp)
sete %al
movl %eax, 0x1c(%rsp)
jmp 0x717f
movl $0x0, 0x1c(%rsp)
movb $0x1, %al
movq %rax, 0x30(%rsp)
movl %r13d, %eax
movl %eax, %r14d
decl %r15d
je 0x6f48
movl 0x20(%rsp), %eax
movl %eax, 0x64(%rsp)
movl 0x24(%rsp), %eax
movl %eax, 0x84(%rsp)
movl 0xc(%rsp), %eax
movw %ax, 0x60(%rsp)
movl 0x40(%rsp), %ebx
jmp 0x73b9
movl %r15d, 0x28(%rsp)
movl %ebx, %r13d
callq 0x2040
movl (%rax), %r15d
movl $0x6, %edx
movq 0x5e1a(%rip), %rbx      # 0xcff0
movq %rbx, %rdi
leaq 0x2e57(%rip), %rsi      # 0xa037
callq 0x21f0
movq %rbx, %rdi
movl %r15d, %esi
callq 0x22a0
movq %rax, %rbx
movl $0x1, %edx
movq %rax, %rdi
leaq 0x228b(%rip), %rsi      # 0x948d
callq 0x21f0
movl %r15d, %edi
callq 0x20a0
testq %rax, %rax
je 0x7362
movq %rax, %r15
movq %rax, %rdi
callq 0x20c0
movq %rbx, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x21f0
jmp 0x737b
testb $0x1, %r14b
jne 0x7264
movl %r12d, %edi
movq 0x48(%rsp), %rsi
leaq 0x266(%rsp), %rdx
leaq 0x164(%rsp), %rcx
movl $0x1, %r8d
movl 0x8(%rsp), %r9d
callq 0x6a54
testb $0x1, %r14b
je 0x72ae
testb $0x1, 0x30(%rsp)
jne 0x72ae
cmpl $0x0, 0x24(%rsp)
je 0x72ae
cmpw $0x0, 0x88(%rsp)
je 0x72ae
movl %r12d, %edi
leaq 0x80(%rsp), %rsi
leaq 0x266(%rsp), %rdx
leaq 0x164(%rsp), %rcx
movl $0xa, %r8d
movl 0x8(%rsp), %r9d
callq 0x6a54
testb $0x1, 0x38(%rsp)
jne 0x72dc
movl %ebp, %edi
movq 0x48(%rsp), %rsi
leaq 0x266(%rsp), %rdx
leaq 0x164(%rsp), %rcx
movl $0x2, %r8d
movl 0x8(%rsp), %r9d
callq 0x6a54
testb $0x1, 0x58(%rsp)
jne 0x730a
movl %ebp, %edi
movq 0x48(%rsp), %rsi
leaq 0x266(%rsp), %rdx
leaq 0x164(%rsp), %rcx
movl $0x3, %r8d
movl 0x8(%rsp), %r9d
callq 0x6a54
incl %ebx
testb $0x1, %r14b
je 0x73be
testb $0x1, 0x68(%rsp)
jne 0x73be
cmpl $0x0, 0x20(%rsp)
je 0x73be
cmpw $0x0, 0xc(%rsp)
je 0x73be
movl %r12d, %edi
leaq 0x60(%rsp), %rsi
leaq 0x266(%rsp), %rdx
leaq 0x164(%rsp), %rcx
movl $0xb, %r8d
movl 0x8(%rsp), %r9d
callq 0x6a54
jmp 0x73be
movq (%rbx), %rax
movq -0x18(%rax), %rax
movq %rbx, %rdi
addq %rax, %rdi
movl 0x20(%rbx,%rax), %esi
orl $0x1, %esi
callq 0x2290
movl $0xa, %edx
movq %rbx, %rdi
leaq 0x2cb4(%rip), %rsi      # 0xa03e
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 %r13d, %ebx
movl 0x28(%rsp), %r15d
cmpl $-0x1, %r15d
jne 0x6e68
movl $0x1, %eax
addq $0x1038, %rsp           # imm = 0x1038
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl 0x64(%rsp), %esi
xorl %edi, %edi
xorl %edx, %edx
callq 0x7c10
movl %eax, %ebp
cmpl $-0x1, %eax
je 0x73fa
movl %ebp, %edi
callq 0x22c0
cmpb $0x0, 0x2c(%rsp)
je 0x7680
xorl %r12d, %r12d
cmpl $-0x1, %ebp
sete %r12b
movq 0x5ba2(%rip), %rbx      # 0xcfb8
leaq 0x2c52(%rip), %rsi      # 0xa06f
movl $0x9, %edx
movq %rbx, %rdi
callq 0x21f0
movzbl %r14b, %esi
andl $0x1, %esi
movq %rbx, %rdi
callq 0x2280
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 0x2c0f(%rip), %rsi      # 0xa079
movl $0xa, %edx
movq %rbx, %rdi
callq 0x21f0
movzbl 0x38(%rsp), %esi
andl $0x1, %esi
movq %rbx, %rdi
callq 0x2280
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 0x2bcc(%rip), %rsi      # 0xa084
movl $0xb, %edx
movq %rbx, %rdi
callq 0x21f0
movzbl 0x58(%rsp), %esi
andl $0x1, %esi
movq %rbx, %rdi
callq 0x2280
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 0x2b8a(%rip), %rsi      # 0xa090
movl $0xc, %edx
movq %rbx, %rdi
callq 0x21f0
movzbl 0x30(%rsp), %esi
andl $0x1, %esi
movq %rbx, %rdi
callq 0x2280
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 0x2b49(%rip), %rsi      # 0xa09d
movl $0xa, %edx
movq %rbx, %rdi
callq 0x21f0
movq %rbx, %rdi
movl %r12d, %esi
callq 0x2280
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 0x2b0b(%rip), %rsi      # 0xa0a8
movl $0x11, %edx
movq %rbx, %rdi
callq 0x21f0
movzbl 0x1c(%rsp), %esi
andl $0x1, %esi
movq %rbx, %rdi
callq 0x2280
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 0x2acf(%rip), %rsi      # 0xa0ba
movl $0xa, %edx
movq %rbx, %rdi
callq 0x21f0
movzbl 0x68(%rsp), %esi
andl $0x1, %esi
movq %rbx, %rdi
callq 0x2280
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 0x2a8c(%rip), %rsi      # 0xa0c5
movl $0x11, %edx
movq %rbx, %rdi
callq 0x21f0
movzbl 0x78(%rsp), %esi
andl $0x1, %esi
movq %rbx, %rdi
callq 0x2280
movq %rax, %rbx
movq (%rax), %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 $0x3, %eax
testb $0x1, %r14b
je 0x73cd
cmpl $-0x1, %ebp
je 0x76ab
testb $0x1, 0x38(%rsp)
movl $0x2, %ecx
movl $0x8, %eax
cmovnel %ecx, %eax
jmp 0x73cd
movl $0x7, %eax
testb $0x1, 0x1c(%rsp)
je 0x73cd
movl $0x4, %eax
testb $0x1, 0x38(%rsp)
jne 0x73cd
movzbl 0x58(%rsp), %ecx
andl $0x1, %ecx
movl $0x6, %eax
subl %ecx, %eax
jmp 0x73cd
leaq 0x2963(%rip), %rdi      # 0xa049
leaq 0x2068(%rip), %rsi      # 0x9755
leaq 0x28c5(%rip), %rcx      # 0x9fb9
movl $0x7d5, %edx            # imm = 0x7D5
callq 0x2120
leaq 0x27c9(%rip), %rdi      # 0x9ece
leaq 0x2049(%rip), %rsi      # 0x9755
leaq 0x28a6(%rip), %rcx      # 0x9fb9
movl $0x75b, %edx            # imm = 0x75B
callq 0x2120
leaq 0x27b9(%rip), %rdi      # 0x9edd
leaq 0x202a(%rip), %rsi      # 0x9755
leaq 0x2887(%rip), %rcx      # 0x9fb9
movl $0x75c, %edx            # imm = 0x75C
callq 0x2120