Subject: Re: Machines with several addresses
To: Peter Simons <simons@petium.rhein.de>
From: Bob Beck <beck@obtuse.com>
List: netbsd-users
Date: 04/23/1997 21:31:16
> two addresses, namely phoenix.rhein.de (193.175.27.172 -- which is the
> primary address) and 193.175.27.165. The problem I have is the
> following: The machine feeds news to another machine in the second
> ethernet.
> 
> What happens is that phoenix connects to the machine and says, it
> would be "phoenix.rhein.de". Because both computers are in the second
> ethernet, the .165 address is used. The other machine does a reverse
> name lookup, which yields phoenix.rhein.de, but then does a name
> lookup again to check whether somebody is trying to snoop with a
> hacked DNS server. And indeed, the name server lookup returns a
> different address than the specified one: The .172 address.
>
>  Is there any way I can force phoenix to use the .172 address even
> when it connects in the second ethernet? I am using NetBSD 1.2/i386.
> -peter
	
	What is doing this "lookup check"? The problem is either that it's
doing it wrong or you've got something wrong in your DNS. To verify it's not
your DNS, do an "nslookup" "set qu=any" "phoenix.rhein.de". you should see
*both* addresses for the machine. I suspect your DNS is ok, and the agent
doing the check is simply doing it wrong.

	What is probably wrong is that whatever is doing the
reverse/forward lookup is doing it wrong. a reverse lookup yields a
name, that is fine. Then your checker does a forward name lookup to
see if the address matches. However, from the sound of it, it is only
checking the *first* returned address. A gethostbyname() call returns
a *list* of addresses (not just one), so when an application is doing
this it needs to then check *all* of the returned addresses of the
machine against the one that connected to it to look for a match.

	If your app isn't doing it right you have two choices: disable
the check, or fix it. (Or you could kludge your DNS, but I don't
reccomend it).  

	The following (incomplete) code fragment does it right,
setting variable "ok" to 1 if the connection looks good, and 0
otherwise. To see this in context, grab a copy of smtpd 1.12 from
ftp://ftp.obtuse.com/pub/smptd/ It's taken starting at about line
1885. You can check your app to see if it's doing something like this.

	Cheers,
	-Bob

--------8<-------
    if (getpeername(0, (struct sockaddr *) &peer_sa, &slen)
	!= 0) {
      syslog(LOG_ERR, "ERROR - getpeername failed (%m)");
      exit(EX_OSERR);
    }
    client_ip_name = strdup(inet_ntoa(peer_sa.sin_addr));
    if (client_ip_name == NULL) {
      syslog(LOG_ERR, "Malloc failed during initialization - bye!");
      exit(EX_CONFIG);
    }
    /*
     * get reverse name 
     */

    tmp_he = gethostbyaddr((char *) &(peer_sa.sin_addr.s_addr),
			   sizeof(peer_sa.sin_addr.s_addr),
			   AF_INET);
    ok = 0;
    tmp_he = gethostbyname(client_reverse_dirty);
    if (tmp_he != NULL) {
      client_forward_dirty = strdup(tmp_he->h_name);
      if (client_forward_dirty != NULL) {
	for (pp = tmp_he->h_addr_list; *pp != NULL; pp += 1) {
	  if (bcmp(((struct in_addr *) *pp),
		   (struct in_addr *) &(peer_sa.sin_addr.s_addr),
		   sizeof(struct in_addr)) == 0) {
	    ok = 1;
	    break;
	  }
	}
      } else {
	client_forward_dirty = "UNKNOWN";
      }
    } else {
      client_forward_dirty = "UNKNOWN";
    }