// File: /workspace/github_cpp_makefile_star2_O3/Distrotech[P]stund/stun.cxx
// Function: stunServerProcessMsg(char*, unsigned int, StunAddress4&, StunAddress4&, StunAddress4&, StunAddress4&, StunMessage*, StunAddress4*, StunAtrString*, bool*, bool*, bool)
bool
stunServerProcessMsg( char* buf,
                      unsigned int bufLen,
                      StunAddress4& from, 
                      StunAddress4& secondary,
                      StunAddress4& myAddr,
                      StunAddress4& altAddr, 
                      StunMessage* resp,
                      StunAddress4* destination,
                      StunAtrString* hmacPassword,
                      bool* changePort,
                      bool* changeIp,
                      bool verbose)
{
    
   // set up information for default response 
	
   memset( resp, 0 , sizeof(*resp) );
	
   *changeIp = false;
   *changePort = false;
	
   StunMessage req;
   bool ok = stunParseMessage( buf,bufLen, req, verbose);
	
   if (!ok)      // Complete garbage, drop it on the floor
   {
      if (verbose) clog << "Request did not parse" << endl;
      return false;
   }
   if (verbose) clog << "Request parsed ok" << endl;
	
   StunAddress4 mapped = req.mappedAddress.ipv4;
   StunAddress4 respondTo = req.responseAddress.ipv4;
   UInt32 flags = req.changeRequest.value;
	
   switch (req.msgHdr.msgType)
   {
      case SharedSecretRequestMsg:
         if(verbose) clog << "Received SharedSecretRequestMsg on udp. send error 433." << endl;
         // !cj! - should fix so you know if this came over TLS or UDP
         stunCreateSharedSecretResponse(req, from, *resp);
         //stunCreateSharedSecretErrorResponse(*resp, 4, 33, "this request must be over TLS");
         return true;
			
      case BindRequestMsg:
         if (!req.hasMessageIntegrity)
         {
            if (verbose) clog << "BindRequest does not contain MessageIntegrity" << endl;
				
            if (0) // !jf! mustAuthenticate
            {
               if(verbose) clog << "Received BindRequest with no MessageIntegrity. Sending 401." << endl;
               stunCreateErrorResponse(*resp, 4, 1, "Missing MessageIntegrity");
               return true;
            }
         }
         else
         {
            if (!req.hasUsername)
            {
               if (verbose) clog << "No UserName. Send 432." << endl;
               stunCreateErrorResponse(*resp, 4, 32, "No UserName and contains MessageIntegrity");
               return true;
            }
            else
            {
               if (verbose) clog << "Validating username: " << req.username.value << endl;
               // !jf! could retrieve associated password from provisioning here
               if (strcmp(req.username.value, "test") == 0)
               {
                  if (0)
                  {
                     // !jf! if the credentials are stale 
                     stunCreateErrorResponse(*resp, 4, 30, "Stale credentials on BindRequest");
                     return true;
                  }
                  else
                  {
                     if (verbose) clog << "Validating MessageIntegrity" << endl;
                     // need access to shared secret
							
                     unsigned char hmac[20];
#ifndef NOSSL
                     unsigned int hmacSize=20;

                     HMAC(EVP_sha1(), 
                          "1234", 4, 
                          reinterpret_cast<const unsigned char*>(buf), bufLen-20-4, 
                          hmac, &hmacSize);
                     assert(hmacSize == 20);
#endif
							
                     if (memcmp(buf, hmac, 20) != 0)
                     {
                        if (verbose) clog << "MessageIntegrity is bad. Sending " << endl;
                        stunCreateErrorResponse(*resp, 4, 3, "Unknown username. Try test with password 1234");
                        return true;
                     }
							
                     // need to compute this later after message is filled in
                     resp->hasMessageIntegrity = true;
                     assert(req.hasUsername);
                     resp->hasUsername = true;
                     resp->username = req.username; // copy username in
                  }
               }
               else
               {
                  if (verbose) clog << "Invalid username: " << req.username.value << "Send 430." << endl; 
               }
            }
         }
			
         // TODO !jf! should check for unknown attributes here and send 420 listing the
         // unknown attributes. 
			
         if ( respondTo.port == 0 ) respondTo = from;
         if ( mapped.port == 0 ) mapped = from;
				
         *changeIp   = ( flags & ChangeIpFlag )?true:false;
         *changePort = ( flags & ChangePortFlag )?true:false;
			
         if (verbose)
         {
            clog << "Request is valid:" << endl;
            clog << "\t flags=" << flags << endl;
            clog << "\t changeIp=" << *changeIp << endl;
            clog << "\t changePort=" << *changePort << endl;
            clog << "\t from = " << from << endl;
            clog << "\t respond to = " << respondTo << endl;
            clog << "\t mapped = " << mapped << endl;
         }
				
         // form the outgoing message
         resp->msgHdr.msgType = BindResponseMsg;
         for ( int i=0; i<16; i++ )
         {
            resp->msgHdr.id.octet[i] = req.msgHdr.id.octet[i];
         }
		
         if ( req.xorOnly == false )
         {
            resp->hasMappedAddress = true;
            resp->mappedAddress.ipv4.port = mapped.port;
            resp->mappedAddress.ipv4.addr = mapped.addr;
         }

         if (1) // do xorMapped address or not 
         {
            resp->hasXorMappedAddress = true;
            UInt16 id16 = req.msgHdr.id.octet[0]<<8 
               | req.msgHdr.id.octet[1];
            UInt32 id32 = req.msgHdr.id.octet[0]<<24 
               | req.msgHdr.id.octet[1]<<16 
               | req.msgHdr.id.octet[2]<<8 
               | req.msgHdr.id.octet[3];
            resp->xorMappedAddress.ipv4.port = mapped.port^id16;
            resp->xorMappedAddress.ipv4.addr = mapped.addr^id32;
         }
         
         resp->hasSourceAddress = true;
         resp->sourceAddress.ipv4.port = (*changePort) ? altAddr.port : myAddr.port;
         resp->sourceAddress.ipv4.addr = (*changeIp)   ? altAddr.addr : myAddr.addr;
			
         resp->hasChangedAddress = true;
         resp->changedAddress.ipv4.port = altAddr.port;
         resp->changedAddress.ipv4.addr = altAddr.addr;
	
         if ( secondary.port != 0 )
         {
            resp->hasSecondaryAddress = true;
            resp->secondaryAddress.ipv4.port = secondary.port;
            resp->secondaryAddress.ipv4.addr = secondary.addr;
         }
         
         if ( req.hasUsername && req.username.sizeValue > 0 ) 
         {
            // copy username in
            resp->hasUsername = true;
            assert( req.username.sizeValue % 4 == 0 );
            assert( req.username.sizeValue < STUN_MAX_STRING );
            memcpy( resp->username.value, req.username.value, req.username.sizeValue );
            resp->username.sizeValue = req.username.sizeValue;
         }
		
         if (1) // add ServerName 
         {
            resp->hasServerName = true;
            const char serverName[] = "Vovida.org " STUN_VERSION; // must pad to mult of 4
            
            assert( sizeof(serverName) < STUN_MAX_STRING );
            //cerr << "sizeof serverName is "  << sizeof(serverName) << endl;
            assert( sizeof(serverName)%4 == 0 );
            memcpy( resp->serverName.value, serverName, sizeof(serverName));
            resp->serverName.sizeValue = sizeof(serverName);
         }
         
         if ( req.hasMessageIntegrity & req.hasUsername )  
         {
            // this creates the password that will be used in the HMAC when then
            // messages is sent
            stunCreatePassword( req.username, hmacPassword );
         }
				
         if (req.hasUsername && (req.username.sizeValue > 64 ) )
         {
            UInt32 source;
            assert( sizeof(int) == sizeof(UInt32) );
					
            sscanf(req.username.value, "%x", &source);
            resp->hasReflectedFrom = true;
            resp->reflectedFrom.ipv4.port = 0;
            resp->reflectedFrom.ipv4.addr = source;
         }
				
         destination->port = respondTo.port;
         destination->addr = respondTo.addr;
			
         return true;
			
      default:
         if (verbose) clog << "Unknown or unsupported request " << endl;
         return false;
   }
	
   assert(0);
   return false;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x528, %rsp            # imm = 0x528
movq %r9, 0x58(%rsp)
movq %r8, 0x50(%rsp)
movq %rcx, %r12
movq %rdx, 0x10(%rsp)
movl %esi, %r14d
movq %rdi, %rbp
movq 0x580(%rsp), %r13
movq 0x578(%rsp), %rbx
movq 0x560(%rsp), %rdi
xorl %r15d, %r15d
movl $0x4c8, %edx            # imm = 0x4C8
xorl %esi, %esi
callq 0x2110
movb %r15b, (%r13)
movq %rbx, %rax
movb 0x588(%rsp), %bl
movb %r15b, (%rax)
movzbl %bl, %ecx
leaq 0x60(%rsp), %rdx
movq %rbp, %r13
movq %rbp, %rdi
movl %r14d, %esi
callq 0x31ac
testb %al, %al
je 0x512b
movq %r12, 0x48(%rsp)
testb %bl, %bl
je 0x5026
movq 0x7fcd(%rip), %r14      # 0xcfb8
leaq 0x4a6e(%rip), %rsi      # 0x9a60
movl $0x11, %edx
movq %r14, %rdi
callq 0x21f0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
movq 0x7c(%rsp), %r15
movq 0x8c(%rsp), %r12
movq %r15, 0x28(%rsp)
movq %r12, 0x20(%rsp)
movzwl 0x60(%rsp), %eax
cmpl $0x1, %eax
movq 0x560(%rsp), %rbx
je 0x514b
cmpl $0x2, %eax
jne 0x5254
cmpb $0x0, 0x588(%rsp)
je 0x50a8
movq 0x7f4b(%rip), %r14      # 0xcfb8
leaq 0x49fe(%rip), %rsi      # 0x9a72
movl $0x37, %edx
movq %r14, %rdi
callq 0x21f0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
movw $0x102, (%rbx)          # imm = 0x102
movups 0x64(%rsp), %xmm0
movups %xmm0, 0x4(%rbx)
movb $0x1, %bpl
movb %bpl, 0x5c(%rbx)
leaq 0x5e(%rbx), %rsi
movq 0x10(%rsp), %rdi
callq 0x4b91
movb %bpl, 0x160(%rbx)
xorl %eax, %eax
leaq 0x5295(%rip), %rcx      # 0xa370
leaq 0x52ae(%rip), %rdx      # 0xa390
movzbl (%rax,%rcx), %esi
movl %esi, %edi
shrl $0x4, %edi
andl $0xf, %esi
movb (%rdi,%rdx), %dil
movb %dil, 0x162(%rbx,%rax,2)
movb (%rsi,%rdx), %sil
movb %sil, 0x163(%rbx,%rax,2)
incq %rax
cmpl $0x14, %eax
jne 0x50e2
xorl %ecx, %ecx
movb %cl, 0x162(%rbx,%rax,2)
movw $0x28, 0x262(%rbx)
movb %cl, 0x18a(%rbx)
jmp 0x5945
testb %bl, %bl
je 0x52a0
movq 0x7e7e(%rip), %rbx      # 0xcfb8
leaq 0x4909(%rip), %rsi      # 0x9a4a
movl $0x15, %edx
jmp 0x5271
movl 0x98(%rsp), %ebp
cmpb $0x0, 0x2c4(%rsp)
je 0x52a7
movb 0xbc(%rsp), %al
testb %al, %al
je 0x52fc
cmpb $0x0, 0x588(%rsp)
je 0x538c
movq 0x7e34(%rip), %rdi      # 0xcfb8
leaq 0x498e(%rip), %rsi      # 0x9b19
movl $0x15, %edx
callq 0x21f0
leaq 0xbe(%rsp), %r14
movq %r14, %rdi
callq 0x20c0
movq 0x7e0c(%rip), %rdi      # 0xcfb8
movq %r14, %rsi
movq %rax, %rdx
callq 0x21f0
movq 0x7dfa(%rip), %r14      # 0xcfb8
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
leaq 0xbe(%rsp), %r14
callq 0x2030
movq %rax, %rdi
callq 0x2140
movl $0x74736574, %eax       # imm = 0x74736574
xorl (%r14), %eax
movzbl 0x4(%r14), %ecx
orl %eax, %ecx
je 0x53d9
movq 0x7daf(%rip), %r13      # 0xcfb8
leaq 0x4a56(%rip), %rsi      # 0x9c66
movl $0x12, %edx
movq %r13, %rdi
callq 0x21f0
movq %r14, %rdi
callq 0x20c0
movq %r13, %rdi
movq %r14, %rsi
movq %rax, %rdx
callq 0x21f0
leaq 0x4a3f(%rip), %rsi      # 0x9c79
movl $0x9, %edx
movq %r13, %rdi
callq 0x21f0
movq %r13, %rdi
callq 0x20d0
jmp 0x54be
cmpb $0x0, 0x588(%rsp)
je 0x52a0
movq 0x7d53(%rip), %rbx      # 0xcfb8
leaq 0x4abe(%rip), %rsi      # 0x9d2a
movl $0x1f, %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
xorl %eax, %eax
jmp 0x5947
cmpb $0x0, 0x588(%rsp)
je 0x54be
movq 0x7cfc(%rip), %r14      # 0xcfb8
leaq 0x47e7(%rip), %rsi      # 0x9aaa
movl $0x2d, %edx
movq %r14, %rdi
callq 0x21f0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
jmp 0x54be
cmpb $0x0, 0x588(%rsp)
je 0x5348
movq 0x7cab(%rip), %r14      # 0xcfb8
leaq 0x47c4(%rip), %rsi      # 0x9ad8
movl $0x16, %edx
movq %r14, %rdi
callq 0x21f0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
movw $0x111, (%rbx)          # imm = 0x111
movb $0x1, 0x279(%rbx)
movw $0x2004, 0x27c(%rbx)    # imm = 0x2004
movups 0x478b(%rip), %xmm0     # 0x9aef
movups %xmm0, 0x27e(%rbx)
movups 0x478d(%rip), %xmm0     # 0x9aff
movups %xmm0, 0x28e(%rbx)
movups 0x4789(%rip), %xmm0     # 0x9b09
movups %xmm0, 0x298(%rbx)
jmp 0x5945
movl $0x74736574, %ecx       # imm = 0x74736574
xorl 0xbe(%rsp), %ecx
movzbl 0xc2(%rsp), %edx
orl %ecx, %edx
jne 0x54be
movdqu (%r13), %xmm0
movd 0x10(%r13), %xmm1
movd 0x40(%rsp), %xmm2
pcmpeqb 0x30(%rsp), %xmm0
pcmpeqb %xmm1, %xmm2
pand %xmm2, %xmm0
pmovmskb %xmm0, %ecx
cmpl $0xffff, %ecx           # imm = 0xFFFF
jne 0x544a
jmp 0x5495
movq 0x7bd8(%rip), %r14      # 0xcfb8
leaq 0x474d(%rip), %rsi      # 0x9b34
movl $0x1b, %edx
movq %r14, %rdi
callq 0x21f0
movq %r14, %rdi
callq 0x20d0
movdqu (%r13), %xmm0
movd 0x10(%r13), %xmm1
movd 0x40(%rsp), %xmm2
pcmpeqb 0x30(%rsp), %xmm0
pcmpeqb %xmm1, %xmm2
pand %xmm2, %xmm0
pmovmskb %xmm0, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
je 0x548e
movq 0x7b8a(%rip), %r14      # 0xcfb8
leaq 0x471b(%rip), %rsi      # 0x9b50
movl $0x21, %edx
movq %r14, %rdi
callq 0x21f0
movq %r14, %rdi
callq 0x20d0
movw $0x111, (%rbx)          # imm = 0x111
movb $0x1, 0x279(%rbx)
movw $0x304, 0x27c(%rbx)     # imm = 0x304
movups 0x470c(%rip), %xmm0     # 0x9b72
movups %xmm0, 0x27e(%rbx)
movups 0x470e(%rip), %xmm0     # 0x9b82
movups %xmm0, 0x28e(%rbx)
movups 0x470e(%rip), %xmm0     # 0x9b90
movups %xmm0, 0x29c(%rbx)
jmp 0x5945
movb 0xbc(%rsp), %al
leaq 0xbe(%rsp), %rsi
movb $0x1, 0x264(%rbx)
testb $0x1, %al
je 0x5997
movb $0x1, 0x5c(%rbx)
leaq 0x5e(%rbx), %rdi
movl $0x102, %edx            # imm = 0x102
callq 0x2170
movl %r12d, %eax
testw %r12w, %r12w
jne 0x54d7
movq 0x10(%rsp), %rax
movq (%rax), %r12
movq %r12, 0x20(%rsp)
movl %r12d, %eax
movw %ax, 0xe(%rsp)
movl %r15d, %edi
testw %r15w, %r15w
jne 0x54f5
movq 0x10(%rsp), %rax
movq (%rax), %r15
movq %r15, 0x28(%rsp)
movl %r15d, %edi
shrq $0x20, %r15
movl %ebp, %eax
shrb $0x2, %al
andb $0x1, %al
movq 0x580(%rsp), %rcx
movb %al, (%rcx)
movl %ebp, %eax
shrb %al
andb $0x1, %al
movq 0x578(%rsp), %rcx
movb %al, (%rcx)
cmpb $0x0, 0x588(%rsp)
je 0x573c
movq %rbp, %r14
movq 0x7a86(%rip), %rbp      # 0xcfb8
leaq 0x474a(%rip), %rsi      # 0x9c83
movl $0x11, %edx
movl %edi, 0x1c(%rsp)
movq %rbp, %rdi
callq 0x21f0
movq (%rbp), %rax
movq -0x18(%rax), %rdi
addq %rbp, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %rbp, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
leaq 0x471c(%rip), %rsi      # 0x9c95
movl $0x8, %edx
movq %rbp, %rdi
callq 0x21f0
movq %rbp, %rdi
movq %r14, %rsi
callq 0x2130
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
leaq 0x46dc(%rip), %rsi      # 0x9c9e
movl $0xb, %edx
movq %rbp, %rdi
callq 0x21f0
movq 0x580(%rsp), %rax
movzbl (%rax), %esi
movq %rbp, %rdi
callq 0x2270
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
leaq 0x4697(%rip), %rsi      # 0x9caa
movl $0xd, %edx
movq %rbp, %rdi
callq 0x21f0
movq 0x578(%rsp), %rax
movzbl (%rax), %esi
movq %rbp, %rdi
callq 0x2270
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
leaq 0x4654(%rip), %rsi      # 0x9cb8
movl $0x9, %edx
movq %rbp, %rdi
callq 0x21f0
movq %rbp, %rdi
movq 0x10(%rsp), %rsi
callq 0x3dbb
movq (%rbp), %rax
movq -0x18(%rax), %rdi
addq %rbp, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %rbp, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
leaq 0x4615(%rip), %rsi      # 0x9cc2
movl $0xf, %edx
movq %rbp, %rdi
callq 0x21f0
leaq 0x20(%rsp), %rsi
movq %rbp, %rdi
callq 0x3dbb
movq (%rbp), %rax
movq -0x18(%rax), %rdi
addq %rbp, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %rbp, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
leaq 0x45dc(%rip), %rsi      # 0x9cd2
movl $0xb, %edx
movq %rbp, %rdi
callq 0x21f0
leaq 0x28(%rsp), %rsi
movq %rbp, %rdi
callq 0x3dbb
movq (%rbp), %rax
movq -0x18(%rax), %rdi
addq %rbp, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %rbp, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2140
movl 0x1c(%rsp), %edi
movw $0x101, (%rbx)          # imm = 0x101
movups 0x64(%rsp), %xmm0
movups %xmm0, 0x4(%rbx)
cmpb $0x0, 0x414(%rsp)
jne 0x5760
movb $0x1, 0x14(%rbx)
movw %di, 0x1c(%rbx)
movl %r15d, 0x20(%rbx)
movb $0x1, %al
movb %al, 0x3a4(%rbx)
movzbl 0x64(%rsp), %ecx
movl %ecx, %edx
shll $0x8, %edx
movzbl 0x65(%rsp), %esi
orl %esi, %edx
shll $0x18, %ecx
shll $0x10, %esi
orl %ecx, %esi
movzbl 0x66(%rsp), %ecx
shll $0x8, %ecx
orl %esi, %ecx
movzbl 0x67(%rsp), %esi
orl %ecx, %esi
xorl %edx, %edi
movw %di, 0x3ac(%rbx)
xorl %r15d, %esi
movl %esi, 0x3b0(%rbx)
movb %al, 0x3c(%rbx)
movq 0x578(%rsp), %rcx
cmpb $0x0, (%rcx)
movq 0x50(%rsp), %rsi
movq %rsi, %rcx
movq 0x58(%rsp), %rdx
cmovneq %rdx, %rcx
movzwl (%rcx), %ecx
movw %cx, 0x44(%rbx)
movq 0x580(%rsp), %rcx
cmpb $0x0, (%rcx)
cmovneq %rdx, %rsi
movl 0x4(%rsi), %ecx
movl %ecx, 0x48(%rbx)
movb %al, 0x4c(%rbx)
movzwl (%rdx), %eax
movw %ax, 0x54(%rbx)
movl 0x4(%rdx), %eax
movl %eax, 0x58(%rbx)
movq 0x48(%rsp), %rcx
movzwl (%rcx), %eax
testw %ax, %ax
je 0x5813
movb $0x1, 0x4b8(%rbx)
movw %ax, 0x4c0(%rbx)
movl 0x4(%rcx), %eax
movl %eax, 0x4c4(%rbx)
leaq 0xbe(%rsp), %r9
movb -0x2(%r9), %bpl
movzwl 0x100(%r9), %r13d
testw %r13w, %r13w
setne %al
andb %bpl, %al
cmpb $0x1, %al
jne 0x5871
movb $0x1, 0x5c(%rbx)
testb $0x3, %r13b
jne 0x5959
movzwl %r13w, %r15d
cmpl $0x100, %r15d           # imm = 0x100
jae 0x5978
leaq 0x5e(%rbx), %rdi
movq %r9, %rsi
movq %r15, %rdx
movq %r9, %r14
callq 0x2170
movq %r14, %r9
movw %r15w, 0x15e(%rbx)
shrq $0x20, %r12
movb $0x1, 0x3b5(%rbx)
movaps 0x4add(%rip), %xmm0     # 0xa360
movups %xmm0, 0x3b6(%rbx)
movw $0x10, 0x4b6(%rbx)
testb %bpl, 0x2c4(%rsp)
je 0x58ed
movq 0x570(%rsp), %rax
xorl %ecx, %ecx
leaq 0x4ac2(%rip), %rdx      # 0xa370
leaq 0x4adb(%rip), %rsi      # 0xa390
movzbl (%rcx,%rdx), %edi
movl %edi, %r8d
shrl $0x4, %r8d
andl $0xf, %edi
movb (%r8,%rsi), %r8b
movb %r8b, (%rax,%rcx,2)
movb (%rdi,%rsi), %dil
movb %dil, 0x1(%rax,%rcx,2)
incq %rcx
cmpl $0x14, %ecx
jne 0x58b5
xorl %edx, %edx
movb %dl, (%rax,%rcx,2)
movw $0x28, 0x100(%rax)
movb %dl, 0x28(%rax)
movq 0x568(%rsp), %r14
cmpw $0x41, %r13w
setae %al
andb %al, %bpl
cmpb $0x1, %bpl
jne 0x5938
leaq 0x441a(%rip), %rsi      # 0x9d27
leaq 0x30(%rsp), %r15
movq %r9, %rdi
movq %r15, %rdx
xorl %eax, %eax
callq 0x21c0
movb $0x1, 0x394(%rbx)
movw $0x0, 0x39c(%rbx)
movl (%r15), %eax
movl %eax, 0x3a0(%rbx)
movzwl 0xe(%rsp), %eax
movw %ax, (%r14)
movl %r12d, 0x4(%r14)
movb $0x1, %al
addq $0x528, %rsp            # imm = 0x528
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x437e(%rip), %rdi      # 0x9cde
leaq 0x3de6(%rip), %rsi      # 0x974d
leaq 0x4242(%rip), %rcx      # 0x9bb0
movl $0x4ad, %edx            # imm = 0x4AD
callq 0x2120
leaq 0x437f(%rip), %rdi      # 0x9cfe
leaq 0x3dc7(%rip), %rsi      # 0x974d
leaq 0x4223(%rip), %rcx      # 0x9bb0
movl $0x4ae, %edx            # imm = 0x4AE
callq 0x2120
leaq 0x4202(%rip), %rdi      # 0x9ba0
leaq 0x3da8(%rip), %rsi      # 0x974d
leaq 0x4204(%rip), %rcx      # 0x9bb0
movl $0x45f, %edx            # imm = 0x45F
callq 0x2120