// File: 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
movq %rsp, %rbp
subq $0x560, %rsp            # imm = 0x560
movb 0x38(%rbp), %al
movq 0x30(%rbp), %r10
movq 0x28(%rbp), %r10
movq 0x20(%rbp), %r10
movq 0x18(%rbp), %r10
movq 0x10(%rbp), %r10
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq %r9, -0x38(%rbp)
andb $0x1, %al
movb %al, -0x39(%rbp)
movq 0x10(%rbp), %rdi
xorl %esi, %esi
movl $0x4c8, %edx            # imm = 0x4C8
callq 0x2130
movq 0x30(%rbp), %rax
movb $0x0, (%rax)
movq 0x28(%rbp), %rax
movb $0x0, (%rax)
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
movb -0x39(%rbp), %al
leaq -0x504(%rbp), %rdx
andb $0x1, %al
movzbl %al, %ecx
callq 0x3380
andb $0x1, %al
movb %al, -0x505(%rbp)
testb $0x1, -0x505(%rbp)
jne 0x57f9
testb $0x1, -0x39(%rbp)
je 0x57f0
movq 0x87db(%rip), %rdi      # 0xdfb0
leaq 0x5283(%rip), %rsi      # 0xaa5f
callq 0x21f0
movq %rax, %rdi
movq 0x87d5(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x604b
testb $0x1, -0x39(%rbp)
je 0x5821
movq 0x87aa(%rip), %rdi      # 0xdfb0
leaq 0x5268(%rip), %rsi      # 0xaa75
callq 0x21f0
movq %rax, %rdi
movq 0x87a4(%rip), %rsi      # 0xdfc0
callq 0x2200
movq -0x4e8(%rbp), %rax
movq %rax, -0x510(%rbp)
movq -0x4d8(%rbp), %rax
movq %rax, -0x518(%rbp)
movl -0x4cc(%rbp), %eax
movl %eax, -0x51c(%rbp)
movzwl -0x504(%rbp), %eax
movl %eax, -0x558(%rbp)
subl $0x1, %eax
je 0x58b3
jmp 0x585d
movl -0x558(%rbp), %eax
subl $0x2, %eax
jne 0x601f
jmp 0x586e
testb $0x1, -0x39(%rbp)
je 0x5896
movq 0x8735(%rip), %rdi      # 0xdfb0
leaq 0x5205(%rip), %rsi      # 0xaa87
callq 0x21f0
movq %rax, %rdi
movq 0x872f(%rip), %rsi      # 0xdfc0
callq 0x2200
movq -0x20(%rbp), %rsi
movq 0x10(%rbp), %rdx
leaq -0x504(%rbp), %rdi
callq 0x6060
movb $0x1, -0x1(%rbp)
jmp 0x604b
testb $0x1, -0x2a0(%rbp)
jne 0x58e9
testb $0x1, -0x39(%rbp)
je 0x58e4
movq 0x86e7(%rip), %rdi      # 0xdfb0
leaq 0x51ef(%rip), %rsi      # 0xaabf
callq 0x21f0
movq %rax, %rdi
movq 0x86e1(%rip), %rsi      # 0xdfc0
callq 0x2200
jmp 0x5ad1
testb $0x1, -0x4a8(%rbp)
jne 0x593d
testb $0x1, -0x39(%rbp)
je 0x591a
movq 0x86b1(%rip), %rdi      # 0xdfb0
leaq 0x51e7(%rip), %rsi      # 0xaaed
callq 0x21f0
movq %rax, %rdi
movq 0x86ab(%rip), %rsi      # 0xdfc0
callq 0x2200
movq 0x10(%rbp), %rdi
movl $0x4, %esi
movl $0x20, %edx
leaq 0x51d5(%rip), %rcx      # 0xab04
callq 0x60e0
movb $0x1, -0x1(%rbp)
jmp 0x604b
testb $0x1, -0x39(%rbp)
je 0x5978
movq 0x8666(%rip), %rdi      # 0xdfb0
leaq 0x51dd(%rip), %rsi      # 0xab2e
callq 0x21f0
movq %rax, %rdi
leaq -0x504(%rbp), %rsi
addq $0x5e, %rsi
callq 0x21f0
movq %rax, %rdi
movq 0x864d(%rip), %rsi      # 0xdfc0
callq 0x2200
leaq -0x504(%rbp), %rdi
addq $0x5e, %rdi
leaq 0x51ba(%rip), %rsi      # 0xab44
callq 0x2270
cmpl $0x0, %eax
jne 0x5a81
testb $0x1, -0x39(%rbp)
je 0x59c0
movq 0x860b(%rip), %rdi      # 0xdfb0
leaq 0x519d(%rip), %rsi      # 0xab49
callq 0x21f0
movq %rax, %rdi
movq 0x8605(%rip), %rsi      # 0xdfc0
callq 0x2200
movq -0x10(%rbp), %rdi
leaq -0x530(%rbp), %rsi
movl $0x14, %edx
callq 0x20f0
cmpl $0x0, %eax
je 0x5a25
testb $0x1, -0x39(%rbp)
je 0x5a02
movq 0x85c9(%rip), %rdi      # 0xdfb0
leaq 0x5177(%rip), %rsi      # 0xab65
callq 0x21f0
movq %rax, %rdi
movq 0x85c3(%rip), %rsi      # 0xdfc0
callq 0x2200
movq 0x10(%rbp), %rdi
movl $0x4, %esi
movl $0x3, %edx
leaq 0x5170(%rip), %rcx      # 0xab87
callq 0x60e0
movb $0x1, -0x1(%rbp)
jmp 0x604b
movq 0x10(%rbp), %rax
movb $0x1, 0x264(%rax)
testb $0x1, -0x4a8(%rbp)
je 0x5a3b
jmp 0x5a5a
leaq 0x5173(%rip), %rdi      # 0xabb5
leaq 0x4d0c(%rip), %rsi      # 0xa755
movl $0x45f, %edx            # imm = 0x45F
leaq 0x5170(%rip), %rcx      # 0xabc5
callq 0x2140
movq 0x10(%rbp), %rax
movb $0x1, 0x5c(%rax)
leaq -0x504(%rbp), %rsi
addq $0x5e, %rsi
movq 0x10(%rbp), %rdi
addq $0x5e, %rdi
movl $0x102, %edx            # imm = 0x102
callq 0x2190
jmp 0x5acd
testb $0x1, -0x39(%rbp)
je 0x5acb
movq 0x8522(%rip), %rdi      # 0xdfb0
leaq 0x51e6(%rip), %rsi      # 0xac7b
callq 0x21f0
movq %rax, %rdi
leaq -0x504(%rbp), %rsi
addq $0x5e, %rsi
callq 0x21f0
movq %rax, %rdi
leaq 0x51d7(%rip), %rsi      # 0xac8e
callq 0x21f0
movq %rax, %rdi
movq 0x84fa(%rip), %rsi      # 0xdfc0
callq 0x2200
jmp 0x5acd
jmp 0x5acf
jmp 0x5ad1
movzwl -0x518(%rbp), %eax
cmpl $0x0, %eax
jne 0x5aeb
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x518(%rbp)
movzwl -0x510(%rbp), %eax
cmpl $0x0, %eax
jne 0x5b05
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x510(%rbp)
movl -0x51c(%rbp), %eax
andl $0x4, %eax
shrl $0x2, %eax
movb %al, %cl
movq 0x30(%rbp), %rax
movb %cl, (%rax)
xorl %eax, %eax
movl -0x51c(%rbp), %ecx
btl $0x1, %ecx
sbbl %eax, %eax
movb %al, %cl
movq 0x28(%rbp), %rax
andb $0x1, %cl
movb %cl, (%rax)
testb $0x1, -0x39(%rbp)
je 0x5c88
movq 0x846d(%rip), %rdi      # 0xdfb0
leaq 0x514e(%rip), %rsi      # 0xac98
callq 0x21f0
movq %rax, %rdi
movq 0x8467(%rip), %rsi      # 0xdfc0
callq 0x2200
movq 0x844b(%rip), %rdi      # 0xdfb0
leaq 0x513e(%rip), %rsi      # 0xacaa
callq 0x21f0
movq %rax, %rdi
movl -0x51c(%rbp), %esi
callq 0x2260
movq %rax, %rdi
movq 0x8437(%rip), %rsi      # 0xdfc0
callq 0x2200
movq 0x841b(%rip), %rdi      # 0xdfb0
leaq 0x5117(%rip), %rsi      # 0xacb3
callq 0x21f0
movq %rax, %rdi
movq 0x30(%rbp), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %esi
callq 0x2320
movq %rax, %rdi
movq 0x8402(%rip), %rsi      # 0xdfc0
callq 0x2200
movq 0x83e6(%rip), %rdi      # 0xdfb0
leaq 0x50ee(%rip), %rsi      # 0xacbf
callq 0x21f0
movq %rax, %rdi
movq 0x28(%rbp), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %esi
callq 0x2320
movq %rax, %rdi
movq 0x83cd(%rip), %rsi      # 0xdfc0
callq 0x2200
movq 0x83b1(%rip), %rdi      # 0xdfb0
leaq 0x50c7(%rip), %rsi      # 0xaccd
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
callq 0x4040
movq %rax, %rdi
movq 0x839f(%rip), %rsi      # 0xdfc0
callq 0x2200
movq 0x8383(%rip), %rdi      # 0xdfb0
leaq 0x50a3(%rip), %rsi      # 0xacd7
callq 0x21f0
movq %rax, %rdi
leaq -0x518(%rbp), %rsi
callq 0x4040
movq %rax, %rdi
movq 0x836e(%rip), %rsi      # 0xdfc0
callq 0x2200
movq 0x8352(%rip), %rdi      # 0xdfb0
leaq 0x5082(%rip), %rsi      # 0xace7
callq 0x21f0
movq %rax, %rdi
leaq -0x510(%rbp), %rsi
callq 0x4040
movq %rax, %rdi
movq 0x833d(%rip), %rsi      # 0xdfc0
callq 0x2200
movq 0x10(%rbp), %rax
movw $0x101, (%rax)          # imm = 0x101
movl $0x0, -0x534(%rbp)
cmpl $0x10, -0x534(%rbp)
jge 0x5cd2
movslq -0x534(%rbp), %rax
movb -0x500(%rbp,%rax), %dl
movq 0x10(%rbp), %rax
movslq -0x534(%rbp), %rcx
movb %dl, 0x4(%rax,%rcx)
movl -0x534(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x534(%rbp)
jmp 0x5c9b
movb -0x150(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x5d06
movq 0x10(%rbp), %rax
movb $0x1, 0x14(%rax)
movw -0x510(%rbp), %cx
movq 0x10(%rbp), %rax
movw %cx, 0x1c(%rax)
movl -0x50c(%rbp), %ecx
movq 0x10(%rbp), %rax
movl %ecx, 0x20(%rax)
movq 0x10(%rbp), %rax
movb $0x1, 0x3a4(%rax)
movzbl -0x500(%rbp), %eax
shll $0x8, %eax
movzbl -0x4ff(%rbp), %ecx
orl %ecx, %eax
movw %ax, -0x536(%rbp)
movzbl -0x500(%rbp), %eax
shll $0x18, %eax
movzbl -0x4ff(%rbp), %ecx
shll $0x10, %ecx
orl %ecx, %eax
movzbl -0x4fe(%rbp), %ecx
shll $0x8, %ecx
orl %ecx, %eax
movzbl -0x4fd(%rbp), %ecx
orl %ecx, %eax
movl %eax, -0x53c(%rbp)
movzwl -0x510(%rbp), %eax
movzwl -0x536(%rbp), %ecx
xorl %ecx, %eax
movw %ax, %cx
movq 0x10(%rbp), %rax
movw %cx, 0x3ac(%rax)
movl -0x50c(%rbp), %ecx
xorl -0x53c(%rbp), %ecx
movq 0x10(%rbp), %rax
movl %ecx, 0x3b0(%rax)
movq 0x10(%rbp), %rax
movb $0x1, 0x3c(%rax)
movq 0x28(%rbp), %rax
testb $0x1, (%rax)
je 0x5db1
movq -0x38(%rbp), %rax
movw (%rax), %ax
movw %ax, -0x55a(%rbp)
jmp 0x5dbf
movq -0x30(%rbp), %rax
movw (%rax), %ax
movw %ax, -0x55a(%rbp)
movw -0x55a(%rbp), %cx
movq 0x10(%rbp), %rax
movw %cx, 0x44(%rax)
movq 0x30(%rbp), %rax
testb $0x1, (%rax)
je 0x5de6
movq -0x38(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x560(%rbp)
jmp 0x5df3
movq -0x30(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x560(%rbp)
movl -0x560(%rbp), %ecx
movq 0x10(%rbp), %rax
movl %ecx, 0x48(%rax)
movq 0x10(%rbp), %rax
movb $0x1, 0x4c(%rax)
movq -0x38(%rbp), %rax
movw (%rax), %cx
movq 0x10(%rbp), %rax
movw %cx, 0x54(%rax)
movq -0x38(%rbp), %rax
movl 0x4(%rax), %ecx
movq 0x10(%rbp), %rax
movl %ecx, 0x58(%rax)
movq -0x28(%rbp), %rax
movzwl (%rax), %eax
cmpl $0x0, %eax
je 0x5e5f
movq 0x10(%rbp), %rax
movb $0x1, 0x4b8(%rax)
movq -0x28(%rbp), %rax
movw (%rax), %cx
movq 0x10(%rbp), %rax
movw %cx, 0x4c0(%rax)
movq -0x28(%rbp), %rax
movl 0x4(%rax), %ecx
movq 0x10(%rbp), %rax
movl %ecx, 0x4c4(%rax)
testb $0x1, -0x4a8(%rbp)
je 0x5f1b
movzwl -0x3a6(%rbp), %eax
cmpl $0x0, %eax
jle 0x5f1b
movq 0x10(%rbp), %rax
movb $0x1, 0x5c(%rax)
movzwl -0x3a6(%rbp), %eax
movl $0x4, %ecx
cltd
idivl %ecx
cmpl $0x0, %edx
jne 0x5e9a
jmp 0x5eb9
leaq 0x4e52(%rip), %rdi      # 0xacf3
leaq 0x48ad(%rip), %rsi      # 0xa755
movl $0x4ad, %edx            # imm = 0x4AD
leaq 0x4d11(%rip), %rcx      # 0xabc5
callq 0x2140
movzwl -0x3a6(%rbp), %eax
cmpl $0x100, %eax            # imm = 0x100
jge 0x5ec9
jmp 0x5ee8
leaq 0x4e43(%rip), %rdi      # 0xad13
leaq 0x487e(%rip), %rsi      # 0xa755
movl $0x4ae, %edx            # imm = 0x4AE
leaq 0x4ce2(%rip), %rcx      # 0xabc5
callq 0x2140
movq 0x10(%rbp), %rdi
addq $0x5e, %rdi
leaq -0x504(%rbp), %rsi
addq $0x5e, %rsi
movzwl -0x3a6(%rbp), %eax
movl %eax, %edx
callq 0x2190
movw -0x3a6(%rbp), %cx
movq 0x10(%rbp), %rax
movw %cx, 0x15e(%rax)
movq 0x10(%rbp), %rax
movb $0x1, 0x3b5(%rax)
movq 0x54c3(%rip), %rax      # 0xb3f0
movq %rax, -0x550(%rbp)
movq 0x54bd(%rip), %rax      # 0xb3f8
movq %rax, -0x548(%rbp)
movq 0x10(%rbp), %rax
movq -0x550(%rbp), %rcx
movq %rcx, 0x3b6(%rax)
movq -0x548(%rbp), %rcx
movq %rcx, 0x3be(%rax)
movq 0x10(%rbp), %rax
movw $0x10, 0x4b6(%rax)
movb -0x2a0(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movb -0x4a8(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x5fa1
leaq -0x504(%rbp), %rdi
addq $0x5e, %rdi
movq 0x20(%rbp), %rsi
callq 0x53e0
testb $0x1, -0x4a8(%rbp)
je 0x5ffe
movzwl -0x3a6(%rbp), %eax
cmpl $0x40, %eax
jle 0x5ffe
leaq -0x504(%rbp), %rdi
addq $0x5e, %rdi
leaq 0x4d74(%rip), %rsi      # 0xad3c
leaq -0x554(%rbp), %rdx
movb $0x0, %al
callq 0x21e0
movq 0x10(%rbp), %rax
movb $0x1, 0x394(%rax)
movq 0x10(%rbp), %rax
movw $0x0, 0x39c(%rax)
movl -0x554(%rbp), %ecx
movq 0x10(%rbp), %rax
movl %ecx, 0x3a0(%rax)
movw -0x518(%rbp), %cx
movq 0x18(%rbp), %rax
movw %cx, (%rax)
movl -0x514(%rbp), %ecx
movq 0x18(%rbp), %rax
movl %ecx, 0x4(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x604b
testb $0x1, -0x39(%rbp)
je 0x6047
movq 0x7f84(%rip), %rdi      # 0xdfb0
leaq 0x4d0c(%rip), %rsi      # 0xad3f
callq 0x21f0
movq %rax, %rdi
movq 0x7f7e(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x560, %rsp            # imm = 0x560
popq %rbp
retq
nopl (%rax)