// File: Distrotech[P]stund/stun.cxx
// Function: stunParseHostName(char*, unsigned int&, unsigned short&, unsigned short)
bool 
stunParseHostName( char* peerName,
               UInt32& ip,
               UInt16& portVal,
               UInt16 defaultPort )
{
   in_addr sin_addr;
    
   char host[512];
   strncpy(host,peerName,512);
   host[512-1]='\0';
   char* port = NULL;
	
   int portNum = defaultPort;
	
   // pull out the port part if present.
   char* sep = strchr(host,':');
	
   if ( sep == NULL )
   {
      portNum = defaultPort;
   }
   else
   {
      *sep = '\0';
      port = sep + 1;
      // set port part
		
      char* endPtr=NULL;
		
      portNum = strtol(port,&endPtr,10);
		
      if ( endPtr != NULL )
      {
         if ( *endPtr != '\0' )
         {
            portNum = defaultPort;
         }
      }
   }
    
   if ( portNum < 1024 ) return false;
   if ( portNum >= 0xFFFF ) return false;
	
   // figure out the host part 
   struct hostent* h;
	
#ifdef WIN32
   assert( strlen(host) >= 1 );
   if ( isdigit( host[0] ) )
   {
      // assume it is a ip address 
      unsigned long a = inet_addr(host);
      //cerr << "a=0x" << hex << a << dec << endl;
		
      ip = ntohl( a );
   }
   else
   {
      // assume it is a host name 
      h = gethostbyname( host );
		
      if ( h == NULL )
      {
         int err = getErrno();
         std::cerr << "error was " << err << std::endl;
         assert( err != WSANOTINITIALISED );
			
         ip = ntohl( 0x7F000001L );
			
         return false;
      }
      else
      {
         sin_addr = *(struct in_addr*)h->h_addr;
         ip = ntohl( sin_addr.s_addr );
      }
   }
	
#else
   h = gethostbyname( host );
   if ( h == NULL )
   {
      int err = getErrno();
      std::cerr << "error was " << err << std::endl;
      ip = ntohl( 0x7F000001L );
      return false;
   }
   else
   {
      sin_addr = *(struct in_addr*)h->h_addr;
      ip = ntohl( sin_addr.s_addr );
   }
#endif
	
   portVal = portNum;
	
   return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x260, %rsp            # imm = 0x260
movw %cx, %ax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movw %ax, -0x22(%rbp)
leaq -0x230(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl $0x200, %edx            # imm = 0x200
callq 0x2120
movb $0x0, -0x31(%rbp)
movq $0x0, -0x238(%rbp)
movzwl -0x22(%rbp), %eax
movl %eax, -0x23c(%rbp)
leaq -0x230(%rbp), %rdi
movl $0x3a, %esi
callq 0x20d0
movq %rax, -0x248(%rbp)
cmpq $0x0, -0x248(%rbp)
jne 0x556a
movzwl -0x22(%rbp), %eax
movl %eax, -0x23c(%rbp)
jmp 0x55d6
movq -0x248(%rbp), %rax
movb $0x0, (%rax)
movq -0x248(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x238(%rbp)
movq $0x0, -0x250(%rbp)
movq -0x238(%rbp), %rdi
leaq -0x250(%rbp), %rsi
movl $0xa, %edx
callq 0x2280
movl %eax, -0x23c(%rbp)
cmpq $0x0, -0x250(%rbp)
je 0x55d4
movq -0x250(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
je 0x55d2
movzwl -0x22(%rbp), %eax
movl %eax, -0x23c(%rbp)
jmp 0x55d4
jmp 0x55d6
cmpl $0x400, -0x23c(%rbp)    # imm = 0x400
jge 0x55eb
movb $0x0, -0x1(%rbp)
jmp 0x56a7
cmpl $0xffff, -0x23c(%rbp)   # imm = 0xFFFF
jl 0x5600
movb $0x0, -0x1(%rbp)
jmp 0x56a7
leaq -0x230(%rbp), %rdi
callq 0x2220
movq %rax, -0x258(%rbp)
cmpq $0x0, -0x258(%rbp)
jne 0x5670
callq 0x8e80
movl %eax, -0x25c(%rbp)
movq 0x89c1(%rip), %rdi      # 0xdff0
leaq 0x53ed(%rip), %rsi      # 0xaa23
callq 0x21f0
movq %rax, %rdi
movl -0x25c(%rbp), %esi
callq 0x2300
movq %rax, %rdi
movq 0x896d(%rip), %rsi      # 0xdfc0
callq 0x2200
movl $0x7f000001, %edi       # imm = 0x7F000001
callq 0x2250
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x56a7
movq -0x258(%rbp), %rax
movq 0x18(%rax), %rax
movq (%rax), %rax
movl (%rax), %eax
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %edi
callq 0x2250
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, (%rax)
movl -0x23c(%rbp), %eax
movw %ax, %cx
movq -0x20(%rbp), %rax
movw %cx, (%rax)
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x260, %rsp            # imm = 0x260
popq %rbp
retq
nopw %cs:(%rax,%rax)