freebsd-ports/dns/nsping/files/patch-ab
Pav Lucistnik 6f7d1a69e5 - Support IPv6
PR:		ports/77608
Submitted by:	Vladimir Kotal <vlada@devnull.cz>
Approved by:	maintainer timeout (5 months)
2005-07-20 14:30:17 +00:00

374 lines
8.7 KiB
Plaintext

--- nsping.c.orig Wed Jul 20 15:23:29 2005
+++ nsping.c Wed Feb 16 10:41:04 2005
@@ -14,6 +14,9 @@
#include <stdarg.h>
#include <assert.h>
+
+#define MAX_ID 65536
+
/* store state on sent queries */
struct nsq {
@@ -26,8 +29,17 @@
* too much stuff through globals. Sorry.
*/
+#if 0
u_int32_t Target_Address = INADDR_NONE;
+#endif
+struct in_addr sin_addr; /* XXX = INADDR_NONE; */
+struct in6_addr sin6_addr; /* XXX = ; IN6ADDR_ANY_INIT */
+#if 0
u_int16_t Target_Port = DNS_PORT;
+#endif
+char *Target_Port = NULL;
+char addr_string[255];
+struct addrinfo *ainfo;
char *Zone = NULL;
char *Hostname = NULL;
@@ -55,7 +67,7 @@
struct timeval *tvp;
struct itimerval itv;
u_int32_t address = INADDR_ANY;
- u_int32_t port = getpid() + 1024;
+ char Local_Port[6];
char *timearg = NULL;
char c;
int i;
@@ -65,6 +77,10 @@
Queries[i].found = 1;
}
+ Target_Port = xstrdup(DNS_PORT);
+ /* XXX check for result */
+ snprintf(Local_Port, sizeof(Local_Port), "%d", getpid() + 1024);
+
#define OPTS "z:h:t:p:dP:a:c:T:rR"
while((c = getopt(argc, argv, OPTS)) != EOF) {
@@ -105,15 +121,17 @@
break;
case 'p':
- Target_Port = atoi(optarg);
+ Target_Port = xstrdup(optarg);
break;
case 'P':
- port = atoi(optarg);
+ strncpy(Local_Port, optarg, sizeof(Local_Port));
break;
case 'a':
- address = resolve(optarg);
+#if 0
+ address = resolve(optarg, port);
+#endif
if(address == INADDR_NONE) {
fprintf(stderr, "Unable to resolve local address.\n");
exit(1);
@@ -135,7 +153,7 @@
exit(1);
}
- if((Target_Address = resolve(*argv)) == INADDR_NONE) {
+ if ((ainfo = resolve(*argv, Target_Port)) == 0) {
fprintf(stderr, "Unable to resolve target server address.\n");
fprintf(stderr, "Fatal error, exiting.\n");
exit(1);
@@ -147,7 +165,7 @@
exit(1);
}
- if((Sockfd = bind_udp_socket(address, port)) < 0) {
+ if((Sockfd = bind_udp_socket(Local_Port)) < 0) {
fprintf(stderr, "Fatal error, exiting.\n");
exit(1);
}
@@ -167,7 +185,7 @@
/* start the fun */
printf("NSPING %s (%s): %s = \"%s\", Type = \"IN %s\"\n",
- *argv, addr_string(Target_Address),
+ *argv, addr_string,
Hostname ? "Hostname" : "Domain",
Hostname ? Hostname : Zone,
type_int2string(Type));
@@ -189,10 +207,14 @@
int guess_zone() {
char lhn[MAXDNAME];
+ struct hostent *hp;
char *cp;
if(gethostname(lhn, MAXDNAME) < 0)
return(0);
+ if((hp = gethostbyname(lhn)) == NULL)
+ return(0);
+ strlcpy(lhn, hp->h_name, sizeof(lhn));
cp = strchr(lhn, '.');
if(!cp || !(*(++cp)))
@@ -261,15 +283,19 @@
static int Start = 0;
static int Pos = 0;
- struct sockaddr_in si;
+#if 0
+ struct sockaddr_storage si;
+#endif
int l;
int id;
u_char *qp;
signal(SIGALRM, probe);
- if(!Start)
- Start = getpid();
+ if(!Start) {
+ Start = getpid() % MAX_ID;
+ dprintf("Start = %d\n", Start);
+ }
/* we're overwriting state from a query we never got a response
* to, so at least note that we missed it.
@@ -278,18 +304,16 @@
if(!Queries[Pos].found)
Missed++;
- memset(&si, 0, sizeof(si));
- si.sin_addr.s_addr = Target_Address;
- si.sin_port = htons(Target_Port);
- si.sin_family = AF_INET;
-
/* get the DNS request */
- l = dns_packet(&qp, Start + Sent);
+ dprintf("sending with id = %d\n", (Start + Sent) % MAX_ID);
+ l = dns_packet(&qp, (Start + Sent) % MAX_ID);
do {
if(sendto(Sockfd, qp, l, 0,
- (struct sockaddr *)&si, sizeof(si)) < 0) {
+ (struct sockaddr *)ainfo->ai_addr,
+ ainfo->ai_addrlen) < 0) {
+
if(errno != EINTR) {
perror("sendto");
return;
@@ -299,7 +323,7 @@
/* if it was sent successfully, update state */
- Queries[Pos].id = Start + Sent;
+ Queries[Pos].id = (Start + Sent) % MAX_ID;
gettimeofday(&Queries[Pos].sent, NULL);
Queries[Pos].found = 0;
@@ -361,7 +385,10 @@
void handle_incoming() {
u_char buffer[1024];
+#if 0
struct sockaddr_in si;
+#endif
+ struct sockaddr_storage si;
int sil = sizeof(si);
int l;
@@ -378,6 +405,7 @@
/* descriminate real responses from spurious crud */
+#if 0
if(si.sin_addr.s_addr != Target_Address) {
dprintf("Received packet from unexpected address %s.\n",
inet_ntoa(si.sin_addr));
@@ -389,6 +417,7 @@
ntohs(si.sin_port));
continue;
}
+#endif
if(l < sizeof(HEADER)) {
dprintf("Short packet.\n");
@@ -420,7 +449,7 @@
double triptime;
if(!Start)
- Start = getpid();
+ Start = getpid() % MAX_ID;
gettimeofday(&tv, NULL);
@@ -437,8 +466,9 @@
Queries[i].found = 1;
/* figure out which query this was, using the DNS query ID */
-
+ dprintf("received with id = %d\n", ntohs(hp->id));
delta = ntohs(hp->id) - Start;
+ dprintf("delta = %d - %d = %d\n", ntohs(hp->id), Start, delta);
/* figure out how long it took */
@@ -494,7 +524,7 @@
hp->rcode == NOERROR ? "+" : "-",
delta,
l,
- addr_string(Target_Address),
+ addr_string,
triptime,
delta ? Ave : 0.0);
@@ -512,6 +542,9 @@
"Ave/Max/Min: %8.3f / %8.3f / %8.3f\n",
Sent, Count, Missed ? Missed : Sent - Count, Lagged, Ave, Max, Min);
+#if 0
+ freeaddrinfo();
+#endif
exit(0);
}
@@ -555,18 +588,6 @@
/* -------------------------------------------------------------------------- */
-/* binary address -> dotted quad string */
-
-char *addr_string(u_int32_t address) {
- static char as[20];
- u_char *cp = (u_char *) &address;
-
- sprintf(as, "%d.%d.%d.%d", cp[0], cp[1], cp[2], cp[3]);
- return(as);
-}
-
-/* -------------------------------------------------------------------------- */
-
/* map integer type codes to names, v/vrsa. Add new types here if you must. */
struct type2str {
@@ -625,22 +646,40 @@
/* return a bound UDP socket */
-int bind_udp_socket(u_int32_t address, u_int16_t port) {
- struct sockaddr_in si;
+int bind_udp_socket(char *port) {
int sockfd;
-
- sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if(sockfd < 0) {
+ char str[255];
+
+ struct sockaddr_storage sss;
+ struct in6_addr anyaddr = IN6ADDR_ANY_INIT;
+ socklen_t addrlen;
+
+ sockfd = socket(ainfo->ai_family, ainfo->ai_socktype,
+ ainfo->ai_protocol);
+ if (sockfd < 0) {
perror("socket");
return(-1);
}
- memset(&si, 0, sizeof(si));
- si.sin_addr.s_addr = address;
- si.sin_port = htons(port);
- si.sin_family = AF_INET;
+ memset(&sss, 0, sizeof(sss));
+ switch (ainfo->ai_family) {
+ case AF_INET:
+ (((struct sockaddr_in *)(&sss))->sin_addr).s_addr = INADDR_ANY;
+ ((struct sockaddr_in *)(&sss))->sin_port = htons(atoi(port));
+ ((struct sockaddr_in *)(&sss))->sin_family = AF_INET;
+ addrlen = sizeof(struct sockaddr_in);
+ break;
+
+ case AF_INET6:
+ ((struct sockaddr_in6 *)(&sss))->sin6_addr = anyaddr;
+ ((struct sockaddr_in6 *)(&sss))->sin6_port = htons(atoi(port));
+ ((struct sockaddr_in6 *)(&sss))->sin6_family = AF_INET6;
+ addrlen = sizeof(struct sockaddr_in6);
+ break;
+ }
- if(bind(sockfd, (struct sockaddr *)&si, sizeof(si)) < 0) {
+ if(bind(sockfd, (struct sockaddr *)&sss, addrlen) < 0)
+ {
perror("bind");
return(-1);
}
@@ -652,19 +691,45 @@
/* wrap hostname resolution */
-u_int32_t resolve(char *name) {
- u_long addr;
-
- addr = inet_addr(name);
- if(addr == INADDR_NONE) {
- struct hostent *hp = gethostbyname(name);
- if(!hp)
- return(INADDR_NONE);
-
- memcpy(&addr, hp->h_addr, 4);
+struct addrinfo* resolve(char *name, char *port) {
+ struct addrinfo hints, *res, *res0;
+ int error;
+ const char *cause = NULL;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ error = getaddrinfo(name, port, &hints, &res0);
+ if (error) {
+ errx(1, "%s", gai_strerror(error));
+ return(NULL);
+ }
+
+ res = res0;
+ switch (res->ai_family) {
+ case AF_INET:
+#if 0
+ sin_addr = (struct
+#endif
+ inet_ntop(res->ai_family,
+ &(((struct sockaddr_in *)(res->ai_addr))->sin_addr),
+ addr_string, sizeof(addr_string));
+ printf("%s\n", addr_string);
+ break;
+ case AF_INET6:
+#if 0
+ sin6_addr =
+#endif
+ inet_ntop(res->ai_family,
+ &(((struct sockaddr_in6 *)(res->ai_addr))->sin6_addr),
+ addr_string, sizeof(addr_string));
+ break;
+ default:
+ return(NULL);
+ break;
}
- return(addr);
+ return(res);
}
@@ -679,9 +744,7 @@
/* -------------------------------------------------------------------------- */
void usage() {
- fprintf(stderr, "nsping [ -z <zone> | -h <hostname> ] -p <port> -t <timeout>\n"
- "\t\t-a <local address> -P <local port>\n"
- "\t\t-T <type> <-r | -R, recurse?>\n");
+ fprintf(stderr, "Usage: nsping [-dR] [-c count] [-z zone | -h hostname] [-t timeout] [-p dport] [-P sport] [-a saddr] [-T querytype]\n");
return;
}