rewrite local address detection code, to use getifaddrs(3), not gethostname(3).
gethostname(3) do not necessarily represent local host addrses. pointed out by: Chuck Cranor
This commit is contained in:
parent
14e83027c8
commit
f714bfb0d8
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: common.c,v 1.20 2000/04/25 02:34:49 itojun Exp $ */
|
/* $NetBSD: common.c,v 1.21 2000/08/09 14:28:50 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1983, 1993
|
* Copyright (c) 1983, 1993
|
||||||
@ -43,7 +43,7 @@
|
|||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)common.c 8.5 (Berkeley) 4/28/95";
|
static char sccsid[] = "@(#)common.c 8.5 (Berkeley) 4/28/95";
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: common.c,v 1.20 2000/04/25 02:34:49 itojun Exp $");
|
__RCSID("$NetBSD: common.c,v 1.21 2000/08/09 14:28:50 itojun Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
@ -62,6 +62,7 @@ __RCSID("$NetBSD: common.c,v 1.20 2000/04/25 02:34:49 itojun Exp $");
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
#include "lp.h"
|
#include "lp.h"
|
||||||
#include "pathnames.h"
|
#include "pathnames.h"
|
||||||
|
|
||||||
@ -303,68 +304,91 @@ compar(p1, p2)
|
|||||||
/*
|
/*
|
||||||
* Figure out whether the local machine is the same
|
* Figure out whether the local machine is the same
|
||||||
* as the remote machine (RM) entry (if it exists).
|
* as the remote machine (RM) entry (if it exists).
|
||||||
*
|
|
||||||
* XXX not really the right way to determine.
|
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
checkremote()
|
checkremote()
|
||||||
{
|
{
|
||||||
char hname[NI_MAXHOST];
|
char lname[NI_MAXHOST], rname[NI_MAXHOST];
|
||||||
struct addrinfo hints, *res;
|
struct addrinfo hints, *res, *res0;
|
||||||
static char errbuf[128];
|
static char errbuf[128];
|
||||||
int error;
|
int error;
|
||||||
|
struct ifaddrs *ifap, *ifa;
|
||||||
|
#ifdef NI_WITHSCOPEID
|
||||||
|
const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
|
||||||
|
#else
|
||||||
|
const int niflags = NI_NUMERICHOST;
|
||||||
|
#endif
|
||||||
|
#ifdef __KAME__
|
||||||
|
struct sockaddr_in6 sin6;
|
||||||
|
struct sockaddr_in6 *sin6p;
|
||||||
|
#endif
|
||||||
|
|
||||||
remote = 0; /* assume printer is local */
|
remote = 0; /* assume printer is local on failure */
|
||||||
if (RM != NULL) {
|
|
||||||
/* get the official name of the local host */
|
|
||||||
gethostname(hname, sizeof(hname));
|
|
||||||
hname[sizeof(hname)-1] = '\0';
|
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
if (RM == NULL)
|
||||||
hints.ai_flags = AI_CANONNAME;
|
return NULL;
|
||||||
hints.ai_family = PF_UNSPEC;
|
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
|
||||||
res = NULL;
|
|
||||||
error = getaddrinfo(hname, NULL, &hints, &res);
|
|
||||||
if (error || !res->ai_canonname) {
|
|
||||||
(void)snprintf(errbuf, sizeof(errbuf),
|
|
||||||
"unable to get official name for local machine %s: "
|
|
||||||
"%s", hname, gai_strerror(error));
|
|
||||||
if (res)
|
|
||||||
freeaddrinfo(res);
|
|
||||||
return errbuf;
|
|
||||||
} else {
|
|
||||||
(void)strncpy(hname, res->ai_canonname,
|
|
||||||
sizeof(hname) - 1);
|
|
||||||
hname[sizeof(hname) - 1] = '\0';
|
|
||||||
}
|
|
||||||
freeaddrinfo(res);
|
|
||||||
|
|
||||||
/* get the official name of RM */
|
/* get the local interface addresses */
|
||||||
memset(&hints, 0, sizeof(hints));
|
if (getifaddrs(&ifap) < 0) {
|
||||||
hints.ai_flags = AI_CANONNAME;
|
(void)snprintf(errbuf, sizeof(errbuf),
|
||||||
hints.ai_family = PF_UNSPEC;
|
"unable to get local interface address: %s",
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
strerror(errno));
|
||||||
res = NULL;
|
return errbuf;
|
||||||
error = getaddrinfo(RM, NULL, &hints, &res);
|
|
||||||
if (error || !res->ai_canonname) {
|
|
||||||
(void)snprintf(errbuf, sizeof(errbuf),
|
|
||||||
"unable to get official name for local machine %s: "
|
|
||||||
"%s", RM, gai_strerror(error));
|
|
||||||
if (res)
|
|
||||||
freeaddrinfo(res);
|
|
||||||
return errbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if the two hosts are not the same,
|
|
||||||
* then the printer must be remote.
|
|
||||||
*/
|
|
||||||
if (strcasecmp(hname, res->ai_canonname) != 0)
|
|
||||||
remote = 1;
|
|
||||||
|
|
||||||
freeaddrinfo(res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* get the remote host addresses (RM) */
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_flags = AI_CANONNAME;
|
||||||
|
hints.ai_family = PF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
res = NULL;
|
||||||
|
error = getaddrinfo(RM, NULL, &hints, &res0);
|
||||||
|
if (error) {
|
||||||
|
(void)snprintf(errbuf, sizeof(errbuf),
|
||||||
|
"unable to resolve remote machine %s: %s",
|
||||||
|
RM, gai_strerror(error));
|
||||||
|
freeifaddrs(ifap);
|
||||||
|
return errbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
remote = 1; /* assume printer is remote */
|
||||||
|
|
||||||
|
for (res = res0; res; res = res->ai_next) {
|
||||||
|
if (getnameinfo(res->ai_addr, res->ai_addrlen,
|
||||||
|
rname, sizeof(rname), NULL, 0, niflags) != 0)
|
||||||
|
continue;
|
||||||
|
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
|
||||||
|
#ifdef __KAME__
|
||||||
|
sin6p = (struct sockaddr_in6 *)ifa->ifa_addr;
|
||||||
|
if (ifa->ifa_addr->sa_family == AF_INET6 &&
|
||||||
|
ifa->ifa_addr->sa_len == sizeof(sin6) &&
|
||||||
|
IN6_IS_ADDR_LINKLOCAL(&sin6p->sin6_addr) &&
|
||||||
|
*(u_int16_t *)&sin6p->sin6_addr.s6_addr[2]) {
|
||||||
|
/* kame scopeid hack */
|
||||||
|
memcpy(&sin6, ifa->ifa_addr, sizeof(sin6));
|
||||||
|
sin6.sin6_scope_id =
|
||||||
|
ntohs(*(u_int16_t *)&sin6p->sin6_addr.s6_addr[2]);
|
||||||
|
sin6.sin6_addr.s6_addr[2] = 0;
|
||||||
|
sin6.sin6_addr.s6_addr[3] = 0;
|
||||||
|
if (getnameinfo((struct sockaddr *)&sin6,
|
||||||
|
sin6.sin6_len, lname, sizeof(lname),
|
||||||
|
NULL, 0, niflags) != 0)
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
if (getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len,
|
||||||
|
lname, sizeof(lname), NULL, 0, niflags) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(rname, lname) == 0) {
|
||||||
|
remote = 0;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
freeaddrinfo(res0);
|
||||||
|
freeifaddrs(ifap);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user