// File: Distrotech[P]stund/stun.cxx
// Function: stunParseMessage(char*, unsigned int, StunMessage&, bool)
bool
stunParseMessage( char* buf, unsigned int bufLen, StunMessage& msg, bool verbose)
{
   if (verbose) clog << "Received stun message: " << bufLen << " bytes" << endl;
   memset(&msg, 0, sizeof(msg));
	
   if (sizeof(StunMsgHdr) > bufLen)
   {
      clog << "Bad message" << endl;
      return false;
   }
	
   memcpy(&msg.msgHdr, buf, sizeof(StunMsgHdr));
   msg.msgHdr.msgType = ntohs(msg.msgHdr.msgType);
   msg.msgHdr.msgLength = ntohs(msg.msgHdr.msgLength);
	
   if (msg.msgHdr.msgLength + sizeof(StunMsgHdr) != bufLen)
   {
      clog << "Message header length doesn't match message size: "
           << msg.msgHdr.msgLength << " - " << bufLen << endl;
      return false;
   }
	
   char* body = buf + sizeof(StunMsgHdr);
   unsigned int size = msg.msgHdr.msgLength;
	
   //clog << "bytes after header = " << size << endl;
	
   while ( size > 0 )
   {
      // !jf! should check that there are enough bytes left in the buffer
		
      StunAtrHdr* attr = reinterpret_cast<StunAtrHdr*>(body);
		
      unsigned int attrLen = ntohs(attr->length);
      int atrType = ntohs(attr->type);
		
      //if (verbose) clog << "Found attribute type=" << AttrNames[atrType] << " length=" << attrLen << endl;
      if ( attrLen+4 > size ) 
      {
         clog << "claims attribute is larger than size of message " 
              <<"(attribute type="<<atrType<<")"<< endl;
         return false;
      }
		
      body += 4; // skip the length and type in attribute header
      size -= 4;
		
      switch ( atrType )
      {
         case MappedAddress:
            msg.hasMappedAddress = true;
            if ( stunParseAtrAddress(  body,  attrLen,  msg.mappedAddress )== false )
            {
               clog << "problem parsing MappedAddress" << endl;
               return false;
            }
            else
            {
               if (verbose) clog << "MappedAddress = " << msg.mappedAddress.ipv4 << endl;
            }
					
            break;  

         case ResponseAddress:
            msg.hasResponseAddress = true;
            if ( stunParseAtrAddress(  body,  attrLen,  msg.responseAddress )== false )
            {
               clog << "problem parsing ResponseAddress" << endl;
               return false;
            }
            else
            {
               if (verbose) clog << "ResponseAddress = " << msg.responseAddress.ipv4 << endl;
            }
            break;  
				
         case ChangeRequest:
            msg.hasChangeRequest = true;
            if (stunParseAtrChangeRequest( body, attrLen, msg.changeRequest) == false)
            {
               clog << "problem parsing ChangeRequest" << endl;
               return false;
            }
            else
            {
               if (verbose) clog << "ChangeRequest = " << msg.changeRequest.value << endl;
            }
            break;
				
         case SourceAddress:
            msg.hasSourceAddress = true;
            if ( stunParseAtrAddress(  body,  attrLen,  msg.sourceAddress )== false )
            {
               clog << "problem parsing SourceAddress" << endl;
               return false;
            }
            else
            {
               if (verbose) clog << "SourceAddress = " << msg.sourceAddress.ipv4 << endl;
            }
            break;  
				
         case ChangedAddress:
            msg.hasChangedAddress = true;
            if ( stunParseAtrAddress(  body,  attrLen,  msg.changedAddress )== false )
            {
               clog << "problem parsing ChangedAddress" << endl;
               return false;
            }
            else
            {
               if (verbose) clog << "ChangedAddress = " << msg.changedAddress.ipv4 << endl;
            }
            break;  
				
         case Username: 
            msg.hasUsername = true;
            if (stunParseAtrString( body, attrLen, msg.username) == false)
            {
               clog << "problem parsing Username" << endl;
               return false;
            }
            else
            {
               if (verbose) clog << "Username = " << msg.username.value << endl;
            }
					
            break;
				
         case Password: 
            msg.hasPassword = true;
            if (stunParseAtrString( body, attrLen, msg.password) == false)
            {
               clog << "problem parsing Password" << endl;
               return false;
            }
            else
            {
               if (verbose) clog << "Password = " << msg.password.value << endl;
            }
            break;
				
         case MessageIntegrity:
            msg.hasMessageIntegrity = true;
            if (stunParseAtrIntegrity( body, attrLen, msg.messageIntegrity) == false)
            {
               clog << "problem parsing MessageIntegrity" << endl;
               return false;
            }
            else
            {
               //if (verbose) clog << "MessageIntegrity = " << msg.messageIntegrity.hash << endl;
            }
					
            // read the current HMAC
            // look up the password given the user of given the transaction id 
            // compute the HMAC on the buffer
            // decide if they match or not
            break;
				
         case ErrorCode:
            msg.hasErrorCode = true;
            if (stunParseAtrError(body, attrLen, msg.errorCode) == false)
            {
               clog << "problem parsing ErrorCode" << endl;
               return false;
            }
            else
            {
               if (verbose) clog << "ErrorCode = " << int(msg.errorCode.errorClass) 
                                 << " " << int(msg.errorCode.number) 
                                 << " " << msg.errorCode.reason << endl;
            }
					
            break;
				
         case UnknownAttribute:
            msg.hasUnknownAttributes = true;
            if (stunParseAtrUnknown(body, attrLen, msg.unknownAttributes) == false)
            {
               clog << "problem parsing UnknownAttribute" << endl;
               return false;
            }
            break;
				
         case ReflectedFrom:
            msg.hasReflectedFrom = true;
            if ( stunParseAtrAddress(  body,  attrLen,  msg.reflectedFrom ) == false )
            {
               clog << "problem parsing ReflectedFrom" << endl;
               return false;
            }
            break;  
				
         case XorMappedAddress:
            msg.hasXorMappedAddress = true;
            if ( stunParseAtrAddress(  body,  attrLen,  msg.xorMappedAddress ) == false )
            {
               clog << "problem parsing XorMappedAddress" << endl;
               return false;
            }
            else
            {
               if (verbose) clog << "XorMappedAddress = " << msg.mappedAddress.ipv4 << endl;
            }
            break;  

         case XorOnly:
            msg.xorOnly = true;
            if (verbose) 
            {
               clog << "xorOnly = true" << endl;
            }
            break;  
				
         case ServerName: 
            msg.hasServerName = true;
            if (stunParseAtrString( body, attrLen, msg.serverName) == false)
            {
               clog << "problem parsing ServerName" << endl;
               return false;
            }
            else
            {
               if (verbose) clog << "ServerName = " << msg.serverName.value << endl;
            }
            break;
				
         case SecondaryAddress:
            msg.hasSecondaryAddress = true;
            if ( stunParseAtrAddress(  body,  attrLen,  msg.secondaryAddress ) == false )
            {
               clog << "problem parsing secondaryAddress" << endl;
               return false;
            }
            else
            {
               if (verbose) clog << "SecondaryAddress = " << msg.secondaryAddress.ipv4 << endl;
            }
            break;  
					
         default:
            if (verbose) clog << "Unknown attribute: " << atrType << endl;
            if ( atrType <= 0x7FFF ) 
            {
               return false;
            }
      }
		
      body += attrLen;
      size -= attrLen;
   }
    
   return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movb %cl, %al
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
andb $0x1, %al
movb %al, -0x21(%rbp)
testb $0x1, -0x21(%rbp)
je 0x33dc
movq 0xac09(%rip), %rdi      # 0xdfb0
leaq 0x7086(%rip), %rsi      # 0xa434
callq 0x21f0
movq %rax, %rdi
movl -0x14(%rbp), %esi
callq 0x2260
movq %rax, %rdi
leaq 0x7f21(%rip), %rsi      # 0xb2e9
callq 0x21f0
movq %rax, %rdi
movq 0xabe9(%rip), %rsi      # 0xdfc0
callq 0x2200
movq -0x20(%rbp), %rdi
xorl %esi, %esi
movl $0x4c8, %edx            # imm = 0x4C8
callq 0x2130
movl -0x14(%rbp), %eax
movl %eax, %ecx
movl $0x14, %eax
cmpq %rcx, %rax
jbe 0x3426
movq 0xabae(%rip), %rdi      # 0xdfb0
leaq 0x7043(%rip), %rsi      # 0xa44c
callq 0x21f0
movq %rax, %rdi
movq 0xaba8(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
movq -0x20(%rbp), %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rdx
movq %rdx, (%rax)
movq 0x8(%rcx), %rdx
movq %rdx, 0x8(%rax)
movl 0x10(%rcx), %ecx
movl %ecx, 0x10(%rax)
movq -0x20(%rbp), %rax
movzwl (%rax), %edi
callq 0x2330
movw %ax, %cx
movq -0x20(%rbp), %rax
movw %cx, (%rax)
movq -0x20(%rbp), %rax
movzwl 0x2(%rax), %edi
callq 0x2330
movw %ax, %cx
movq -0x20(%rbp), %rax
movw %cx, 0x2(%rax)
movq -0x20(%rbp), %rax
movzwl 0x2(%rax), %eax
addq $0x14, %rax
movl -0x14(%rbp), %ecx
cmpq %rcx, %rax
je 0x34d9
movq 0xab25(%rip), %rdi      # 0xdfb0
leaq 0x6fc6(%rip), %rsi      # 0xa458
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rax
movzwl 0x2(%rax), %esi
callq 0x22f0
movq %rax, %rdi
leaq 0x6fda(%rip), %rsi      # 0xa48b
callq 0x21f0
movq %rax, %rdi
movl -0x14(%rbp), %esi
callq 0x2260
movq %rax, %rdi
movq 0xaaf5(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
movq -0x10(%rbp), %rax
addq $0x14, %rax
movq %rax, -0x30(%rbp)
movq -0x20(%rbp), %rax
movzwl 0x2(%rax), %eax
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
jbe 0x3ee1
movq -0x30(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movzwl 0x2(%rax), %edi
callq 0x2330
movzwl %ax, %eax
movl %eax, -0x44(%rbp)
movq -0x40(%rbp), %rax
movzwl (%rax), %edi
callq 0x2330
movzwl %ax, %eax
movl %eax, -0x48(%rbp)
movl -0x44(%rbp), %eax
addl $0x4, %eax
cmpl -0x34(%rbp), %eax
jbe 0x3586
movq 0xaa77(%rip), %rdi      # 0xdfb0
leaq 0x6f4f(%rip), %rsi      # 0xa48f
callq 0x21f0
movq %rax, %rdi
leaq 0x6f71(%rip), %rsi      # 0xa4c0
callq 0x21f0
movq %rax, %rdi
movl -0x48(%rbp), %esi
callq 0x2300
movq %rax, %rdi
leaq 0x74f4(%rip), %rsi      # 0xaa5d
callq 0x21f0
movq %rax, %rdi
movq 0xaa48(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
movq -0x30(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x30(%rbp)
movl -0x34(%rbp), %eax
addl $-0x4, %eax
movl %eax, -0x34(%rbp)
movl -0x48(%rbp), %eax
movl %eax, -0x4c(%rbp)
subl $0x1, %eax
je 0x3679
jmp 0x35ac
movl -0x4c(%rbp), %eax
subl $0x2, %eax
je 0x370d
jmp 0x35ba
movl -0x4c(%rbp), %eax
subl $0x3, %eax
je 0x37a1
jmp 0x35c8
movl -0x4c(%rbp), %eax
subl $0x4, %eax
je 0x3830
jmp 0x35d6
movl -0x4c(%rbp), %eax
subl $0x5, %eax
je 0x38c4
jmp 0x35e4
movl -0x4c(%rbp), %eax
subl $0x6, %eax
je 0x3958
jmp 0x35f2
movl -0x4c(%rbp), %eax
subl $0x7, %eax
je 0x39e8
jmp 0x3600
movl -0x4c(%rbp), %eax
subl $0x8, %eax
je 0x3a81
jmp 0x360e
movl -0x4c(%rbp), %eax
subl $0x9, %eax
je 0x3adf
jmp 0x361c
movl -0x4c(%rbp), %eax
subl $0xa, %eax
je 0x3bc0
jmp 0x362a
movl -0x4c(%rbp), %eax
subl $0xb, %eax
je 0x3c1c
jmp 0x3638
movl -0x4c(%rbp), %eax
subl $0x21, %eax
je 0x3d12
jmp 0x3646
movl -0x4c(%rbp), %eax
subl $0x8020, %eax           # imm = 0x8020
je 0x3c78
jmp 0x3656
movl -0x4c(%rbp), %eax
subl $0x8022, %eax           # imm = 0x8022
je 0x3d4a
jmp 0x3666
movl -0x4c(%rbp), %eax
subl $0x8050, %eax           # imm = 0x8050
je 0x3de3
jmp 0x3e7d
movq -0x20(%rbp), %rax
movb $0x1, 0x14(%rax)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x20(%rbp), %rdx
addq $0x18, %rdx
callq 0x3ef0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x36ca
movq 0xa90a(%rip), %rdi      # 0xdfb0
leaq 0x6e24(%rip), %rsi      # 0xa4d1
callq 0x21f0
movq %rax, %rdi
movq 0xa904(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
testb $0x1, -0x21(%rbp)
je 0x3706
movq 0xa8d9(%rip), %rdi      # 0xdfb0
leaq 0x6fc8(%rip), %rsi      # 0xa6a6
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
addq $0x18, %rsi
addq $0x4, %rsi
callq 0x4040
movq %rax, %rdi
movq 0xa8bf(%rip), %rsi      # 0xdfc0
callq 0x2200
jmp 0x3708
jmp 0x3ec1
movq -0x20(%rbp), %rax
movb $0x1, 0x24(%rax)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x20(%rbp), %rdx
addq $0x28, %rdx
callq 0x3ef0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x375e
movq 0xa876(%rip), %rdi      # 0xdfb0
leaq 0x6dae(%rip), %rsi      # 0xa4ef
callq 0x21f0
movq %rax, %rdi
movq 0xa870(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
testb $0x1, -0x21(%rbp)
je 0x379a
movq 0xa845(%rip), %rdi      # 0xdfb0
leaq 0x6d9d(%rip), %rsi      # 0xa50f
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
addq $0x28, %rsi
addq $0x4, %rsi
callq 0x4040
movq %rax, %rdi
movq 0xa82b(%rip), %rsi      # 0xdfc0
callq 0x2200
jmp 0x379c
jmp 0x3ec1
movq -0x20(%rbp), %rax
movb $0x1, 0x34(%rax)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x20(%rbp), %rdx
addq $0x38, %rdx
callq 0x4110
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x37f2
movq 0xa7e2(%rip), %rdi      # 0xdfb0
leaq 0x6d4d(%rip), %rsi      # 0xa522
callq 0x21f0
movq %rax, %rdi
movq 0xa7dc(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
testb $0x1, -0x21(%rbp)
je 0x3829
movq 0xa7b1(%rip), %rdi      # 0xdfb0
leaq 0x6d3a(%rip), %rsi      # 0xa540
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rax
movl 0x38(%rax), %esi
callq 0x2260
movq %rax, %rdi
movq 0xa79c(%rip), %rsi      # 0xdfc0
callq 0x2200
jmp 0x382b
jmp 0x3ec1
movq -0x20(%rbp), %rax
movb $0x1, 0x3c(%rax)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x20(%rbp), %rdx
addq $0x40, %rdx
callq 0x3ef0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x3881
movq 0xa753(%rip), %rdi      # 0xdfb0
leaq 0x6ced(%rip), %rsi      # 0xa551
callq 0x21f0
movq %rax, %rdi
movq 0xa74d(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
testb $0x1, -0x21(%rbp)
je 0x38bd
movq 0xa722(%rip), %rdi      # 0xdfb0
leaq 0x6cda(%rip), %rsi      # 0xa56f
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
addq $0x40, %rsi
addq $0x4, %rsi
callq 0x4040
movq %rax, %rdi
movq 0xa708(%rip), %rsi      # 0xdfc0
callq 0x2200
jmp 0x38bf
jmp 0x3ec1
movq -0x20(%rbp), %rax
movb $0x1, 0x4c(%rax)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x20(%rbp), %rdx
addq $0x50, %rdx
callq 0x3ef0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x3915
movq 0xa6bf(%rip), %rdi      # 0xdfb0
leaq 0x6c88(%rip), %rsi      # 0xa580
callq 0x21f0
movq %rax, %rdi
movq 0xa6b9(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
testb $0x1, -0x21(%rbp)
je 0x3951
movq 0xa68e(%rip), %rdi      # 0xdfb0
leaq 0x6c76(%rip), %rsi      # 0xa59f
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
addq $0x50, %rsi
addq $0x4, %rsi
callq 0x4040
movq %rax, %rdi
movq 0xa674(%rip), %rsi      # 0xdfc0
callq 0x2200
jmp 0x3953
jmp 0x3ec1
movq -0x20(%rbp), %rax
movb $0x1, 0x5c(%rax)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x20(%rbp), %rdx
addq $0x5e, %rdx
callq 0x41d0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x39a9
movq 0xa62b(%rip), %rdi      # 0xdfb0
leaq 0x6c25(%rip), %rsi      # 0xa5b1
callq 0x21f0
movq %rax, %rdi
movq 0xa625(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
testb $0x1, -0x21(%rbp)
je 0x39e1
movq 0xa5fa(%rip), %rdi      # 0xdfb0
leaq 0x6c0d(%rip), %rsi      # 0xa5ca
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
addq $0x5e, %rsi
callq 0x21f0
movq %rax, %rdi
movq 0xa5e4(%rip), %rsi      # 0xdfc0
callq 0x2200
jmp 0x39e3
jmp 0x3ec1
movq -0x20(%rbp), %rax
movb $0x1, 0x160(%rax)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x20(%rbp), %rdx
addq $0x162, %rdx            # imm = 0x162
callq 0x41d0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x3a3f
movq 0xa595(%rip), %rdi      # 0xdfb0
leaq 0x6bb4(%rip), %rsi      # 0xa5d6
callq 0x21f0
movq %rax, %rdi
movq 0xa58f(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
testb $0x1, -0x21(%rbp)
je 0x3a7a
movq 0xa564(%rip), %rdi      # 0xdfb0
leaq 0x6b9c(%rip), %rsi      # 0xa5ef
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
addq $0x162, %rsi            # imm = 0x162
callq 0x21f0
movq %rax, %rdi
movq 0xa54b(%rip), %rsi      # 0xdfc0
callq 0x2200
jmp 0x3a7c
jmp 0x3ec1
movq -0x20(%rbp), %rax
movb $0x1, 0x264(%rax)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x20(%rbp), %rdx
addq $0x265, %rdx            # imm = 0x265
callq 0x4290
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x3ad8
movq 0xa4fc(%rip), %rdi      # 0xdfb0
leaq 0x6b40(%rip), %rsi      # 0xa5fb
callq 0x21f0
movq %rax, %rdi
movq 0xa4f6(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
jmp 0x3ada
jmp 0x3ec1
movq -0x20(%rbp), %rax
movb $0x1, 0x279(%rax)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x20(%rbp), %rdx
addq $0x27a, %rdx            # imm = 0x27A
callq 0x4300
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x3b36
movq 0xa49e(%rip), %rdi      # 0xdfb0
leaq 0x6b03(%rip), %rsi      # 0xa61c
callq 0x21f0
movq %rax, %rdi
movq 0xa498(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
testb $0x1, -0x21(%rbp)
je 0x3bb9
movq 0xa46d(%rip), %rdi      # 0xdfb0
leaq 0x6aec(%rip), %rsi      # 0xa636
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rax
movzbl 0x27c(%rax), %esi
callq 0x2300
movq %rax, %rdi
leaq 0x6921(%rip), %rsi      # 0xa48d
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rax
movzbl 0x27d(%rax), %esi
callq 0x2300
movq %rax, %rdi
leaq 0x68ff(%rip), %rsi      # 0xa48d
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
addq $0x27a, %rsi            # imm = 0x27A
addq $0x4, %rsi
callq 0x21f0
movq %rax, %rdi
movq 0xa40c(%rip), %rsi      # 0xdfc0
callq 0x2200
jmp 0x3bbb
jmp 0x3ec1
movq -0x20(%rbp), %rax
movb $0x1, 0x380(%rax)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x20(%rbp), %rdx
addq $0x382, %rdx            # imm = 0x382
callq 0x4400
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x3c17
movq 0xa3bd(%rip), %rdi      # 0xdfb0
leaq 0x6a49(%rip), %rsi      # 0xa643
callq 0x21f0
movq %rax, %rdi
movq 0xa3b7(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
jmp 0x3ec1
movq -0x20(%rbp), %rax
movb $0x1, 0x394(%rax)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x20(%rbp), %rdx
addq $0x398, %rdx            # imm = 0x398
callq 0x3ef0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x3c73
movq 0xa361(%rip), %rdi      # 0xdfb0
leaq 0x6a0e(%rip), %rsi      # 0xa664
callq 0x21f0
movq %rax, %rdi
movq 0xa35b(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
jmp 0x3ec1
movq -0x20(%rbp), %rax
movb $0x1, 0x3a4(%rax)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x20(%rbp), %rdx
addq $0x3a8, %rdx            # imm = 0x3A8
callq 0x3ef0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x3ccf
movq 0xa305(%rip), %rdi      # 0xdfb0
leaq 0x69d0(%rip), %rsi      # 0xa682
callq 0x21f0
movq %rax, %rdi
movq 0xa2ff(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
testb $0x1, -0x21(%rbp)
je 0x3d0b
movq 0xa2d4(%rip), %rdi      # 0xdfb0
leaq 0x69c0(%rip), %rsi      # 0xa6a3
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
addq $0x18, %rsi
addq $0x4, %rsi
callq 0x4040
movq %rax, %rdi
movq 0xa2ba(%rip), %rsi      # 0xdfc0
callq 0x2200
jmp 0x3d0d
jmp 0x3ec1
movq -0x20(%rbp), %rax
movb $0x1, 0x3b4(%rax)
testb $0x1, -0x21(%rbp)
je 0x3d45
movq 0xa286(%rip), %rdi      # 0xdfb0
leaq 0x6986(%rip), %rsi      # 0xa6b7
callq 0x21f0
movq %rax, %rdi
movq 0xa280(%rip), %rsi      # 0xdfc0
callq 0x2200
jmp 0x3ec1
movq -0x20(%rbp), %rax
movb $0x1, 0x3b5(%rax)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x20(%rbp), %rdx
addq $0x3b6, %rdx            # imm = 0x3B6
callq 0x41d0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x3da1
movq 0xa233(%rip), %rdi      # 0xdfb0
leaq 0x6942(%rip), %rsi      # 0xa6c6
callq 0x21f0
movq %rax, %rdi
movq 0xa22d(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
testb $0x1, -0x21(%rbp)
je 0x3ddc
movq 0xa202(%rip), %rdi      # 0xdfb0
leaq 0x692c(%rip), %rsi      # 0xa6e1
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
addq $0x3b6, %rsi            # imm = 0x3B6
callq 0x21f0
movq %rax, %rdi
movq 0xa1e9(%rip), %rsi      # 0xdfc0
callq 0x2200
jmp 0x3dde
jmp 0x3ec1
movq -0x20(%rbp), %rax
movb $0x1, 0x4b8(%rax)
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
movq -0x20(%rbp), %rdx
addq $0x4bc, %rdx            # imm = 0x4BC
callq 0x3ef0
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x3e3a
movq 0xa19a(%rip), %rdi      # 0xdfb0
leaq 0x68d2(%rip), %rsi      # 0xa6ef
callq 0x21f0
movq %rax, %rdi
movq 0xa194(%rip), %rsi      # 0xdfc0
callq 0x2200
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
testb $0x1, -0x21(%rbp)
je 0x3e79
movq 0xa169(%rip), %rdi      # 0xdfb0
leaq 0x68c2(%rip), %rsi      # 0xa710
callq 0x21f0
movq %rax, %rdi
movq -0x20(%rbp), %rsi
addq $0x4bc, %rsi            # imm = 0x4BC
addq $0x4, %rsi
callq 0x4040
movq %rax, %rdi
movq 0xa14c(%rip), %rsi      # 0xdfc0
callq 0x2200
jmp 0x3e7b
jmp 0x3ec1
testb $0x1, -0x21(%rbp)
je 0x3eb0
movq 0xa126(%rip), %rdi      # 0xdfb0
leaq 0x6893(%rip), %rsi      # 0xa724
callq 0x21f0
movq %rax, %rdi
movl -0x48(%rbp), %esi
callq 0x2300
movq %rax, %rdi
movq 0xa115(%rip), %rsi      # 0xdfc0
callq 0x2200
cmpl $0x7fff, -0x48(%rbp)    # imm = 0x7FFF
jg 0x3ebf
movb $0x0, -0x1(%rbp)
jmp 0x3ee5
jmp 0x3ec1
movl -0x44(%rbp), %ecx
movq -0x30(%rbp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movl -0x44(%rbp), %ecx
movl -0x34(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x34(%rbp)
jmp 0x34f0
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x50, %rsp
popq %rbp
retq