From: Ted Lemon Date: Sat, 29 Mar 1997 01:25:32 +0000 (+0000) Subject: Adjust indentation; fix up calling conventions X-Git-Tag: DHCP-970328~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9557deb6daf4c2a43b280bab401683fc661352e8;p=thirdparty%2Fdhcp.git Adjust indentation; fix up calling conventions --- diff --git a/common/dns.c b/common/dns.c index cf178ce5e..e694faba1 100644 --- a/common/dns.c +++ b/common/dns.c @@ -1,6 +1,6 @@ /* dns.c - Domain Name Service subroutine. */ + Domain Name Service subroutines. */ /* * Copyright (C) 1992 by Ted Lemon. @@ -39,51 +39,52 @@ * substantially modified for use in the Internet Software Consortium * DHCP suite. * - * These later modifications were done on behalf of the Internet Software Consortium - * by Ted Lemon in cooperation with Vixie - * Enterprises. To learn more about the Internet Software Consortium, - * see ``http://www.vix.com/isc''. To learn more about Vixie - * Enterprises, see ``http://www.vix.com''. + * These later modifications were done on behalf of the Internet + * Software Consortium by Ted Lemon in cooperation + * with Vixie Enterprises. To learn more about the Internet Software + * Consortium, see ``http://www.vix.com/isc''. To learn more about + * Vixie Enterprises, see ``http://www.vix.com''. */ #ifndef lint static char copyright[] = -"$Id: dns.c,v 1.1 1997/03/08 02:24:16 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n"; +"$Id: dns.c,v 1.2 1997/03/29 01:25:32 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" #include "arpa/nameser.h" +int dns_protocol_initialized; +int dns_protocol_fd; + +static int addlabel PROTO ((u_int8_t *, char *)); +static int skipname PROTO ((u_int8_t *)); +static int copy_out_name PROTO ((u_int8_t *, u_int8_t *, char *)); + /* Initialize the DNS protocol. */ -void dns_startup (handler) - void (*handler) PROTO ((struct iaddr, u_int8_t *, int)); +void dns_startup () { - struct protoent *proto; - int protocol = 1; + struct servent *srv; + u_int16_t dns_port = htons (53); struct sockaddr_in from; - int fd; /* Only initialize icmp once. */ - if (icmp_protocol_initialized) - error ("attempted to reinitialize icmp protocol"); - icmp_protocol_initialized = 1; + if (dns_protocol_initialized) + error ("attempted to reinitialize dns protocol"); + dns_protocol_initialized = 1; /* Get the protocol number (should be 1). */ - proto = getprotobyname ("icmp"); - if (proto) - protocol = proto -> p_proto; + srv = getsrvbyname ("domain", "tcp"); + if (srv) + port = srv -> s_port; /* Get a raw socket for the ICMP protocol. */ - icmp_protocol_fd = socket (AF_INET, SOCK_RAW, protocol); - if (!icmp_protocol_fd) - error ("unable to create icmp socket: %m"); - - if (setsockopt (icmp_protocol_fd, SOL_SOCKET, SO_DONTROUTE, - (char *)&routep, sizeof routep)) - error ("Can't set SO_DONTROUTE on ICMP socket: %m"); + dns_protocol_fd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (!dns_protocol_fd) + error ("unable to create dns socket: %m"); - add_protocol ("icmp", icmp_protocol_fd, icmp_echoreply, handler); + add_protocol ("dns", dns_protocol_fd, dns_packet, 0); } /* Label manipulation stuff; see RFC1035, page 28 section 4.1.2 and @@ -93,50 +94,49 @@ void dns_startup (handler) the label in the first character, the contents of the label in subsequent characters, and returning the length of the conglomeration. */ -addlabel (buf, label) - unsigned char *buf; - unsigned char *label; +static int addlabel (buf, label) + u_int8_t *buf; + char *label; { - *buf = strlen (label); - strcpy (buf + 1, label); - return *buf + 1; + *buf = strlen (label); + memcpy (buf + 1, label, *buf); + return *buf + 1; } /* skipname skips over all of the labels in a single domain name, returning the length of the domain name. */ -skipname (label) - unsigned char *label; +static int skipname (label) + u_int8_t *label; { - if (*label & INDIR_MASK) - return 2; - if (*label == 0) - return 1; - return *label + 1 + skipname (label + *label + 1); + if (*label & INDIR_MASK) + return 2; + if (*label == 0) + return 1; + return *label + 1 + skipname (label + *label + 1); } /* copy_out_name copies out the name appearing at the specified location into a string, stored as fields seperated by dots rather than lengths and labels. The length of the label-formatted name is returned. */ -copy_out_name (base, name, buf) - unsigned char *base; - unsigned char *name; - unsigned char *buf; +static int copy_out_name (base, name, buf) + u_int8_t *base; + u_int8_t *name; + char *buf; { - if (*name & INDIR_MASK) - { - int offset = (*name & ~INDIR_MASK) + (*name + 1); - return copy_out_name (base, base + offset, buf); - } - if (!*name) - { - *buf = 0; - return 1; - } - memcpy (buf, name + 1, *name); - *(buf + *name) = '.'; - return *name + 1 + copy_out_name (base, name + *name + 1, buf + *name + 1); + if (*name & INDIR_MASK) { + int offset = (*name & ~INDIR_MASK) + (*name + 1); + return copy_out_name (base, base + offset, buf); + } + if (!*name) { + *buf = 0; + return 1; + } + memcpy (buf, name + 1, *name); + *(buf + *name) = '.'; + return (*name + 1 + + copy_out_name (base, name + *name + 1, buf + *name + 1)); } /* ns_inaddr_lookup constructs a PTR lookup query for an internet address - @@ -145,188 +145,153 @@ copy_out_name (base, name, buf) called with a null pointer. Otherwise, the callback is called with the address of the string returned by the name server. */ -ns_inaddr_lookup (inaddr, timeout, callback) - Address *inaddr; - int timeout; - void (*callback) (char *); +int ns_inaddr_lookup (server, id, inaddr) + struct sockaddr_in *server; + u_int16_t id; + struct iaddr inaddr; { - unsigned char namebuf [MAXDNAME]; - unsigned char *s = namebuf; - unsigned char *label; - int i; - unsigned char c; - - for (i = 3; i >= 0; --i) - { - label = s++; - *label = 1; - c = inaddr -> addr [i]; - if (c > 100) - { - ++*label; - *s++ = '0' + c / 100; + unsigned char namebuf [512]; + unsigned char *s = namebuf; + unsigned char *label; + int i; + unsigned char c; + + for (i = 3; i >= 0; --i) { + label = s++; + *label = 1; + c = inaddr -> addr [i]; + if (c > 100) { + ++*label; + *s++ = '0' + c / 100; + } + if (c > 10) { + ++*label; + *s++ = '0' + ((c / 10) % 10); + } + *s++ = '0' + (c % 10); } - if (c > 10) - { - ++*label; - *s++ = '0' + ((c / 10) % 10); - } - *s++ = '0' + (c % 10); - } - s += addlabel (s, "in-addr"); - s += addlabel (s, "arpa"); - *s = 0; - nslookup (namebuf, T_PTR, C_IN, timeout, callback); + s += addlabel (s, "in-addr"); + s += addlabel (s, "arpa"); + *s++ = 0; + return nslookup (server, id, namebuf, s - namebuf, T_PTR, C_IN); } -nslookup (qname, qtype, qclass, timeout, callback) - char *qname; - int qtype; - int qclass; - int timeout; - void (*callback) (char *); -{ - HEADER hdr; - unsigned char buf [MTUSIZE]; - unsigned char query [PACKETSZ]; - unsigned char *s; - int len; - void ns_timeout (); - int i; - - /* Construct a query ID... */ - do - ns_query_id = random (); - while (ns_query_id < 2048); - - memset (&hdr, 0, sizeof hdr); - hdr.id = ns_query_id; - hdr.rd = 1; - hdr.opcode = QUERY; - hdr.qdcount = 1; - nsswap (&hdr); - - memcpy (query, &hdr, sizeof hdr); - len = sizeof hdr; - - strcpy (&query [len], qname); - len += strlen (qname) + 1; - - s = &query [len]; - PUTSHORT (qtype, s); - len += sizeof (short); - PUTSHORT (qclass, s); - len += sizeof (short); - /* Tack on an extra zero for the checksummer... */ - *s++ = 0; - - /* Create the packet header... */ - len = build_udp_packet (buf, sizeof buf, query, len, - ns_query_id, NAMESERVER_PORT, - &myiaddr, &nsiaddr); - - /* Save the callback vector... */ - ns_callback = callback; - - /* Push a packet out, retrying in an exponential decay starting - with one second, and time out when the user specifies... */ - pushpacket (buf, len, (void (*) (char *, int))0, ns_timeout, timeout, 1); -} +/* Construct and transmit a name server query. */ -void ns_timeout () +int nslookup (server, id, qname, namelen, qtype, qclass) + struct sockaddr_in *server; + u_int8_t id; + char *qname; + int namelen; + u_int16_t qtype; + u_int16_t qclass; { - void (*callback) (char *) = ns_callback; - ns_callback = (void (*) (char *))0; - ns_query_id = 0; - (*callback) ((char *)0); + HEADER *hdr; + unsigned char query [512]; + unsigned char *s; + int len; + int i; + + /* Construct a header... */ + hdr = (HEADER *)query; + memset (&hdr, 0, sizeof hdr); + hdr -> id = htons (id); + hdr -> rd = 1; + hdr -> opcode = QUERY; + hdr -> qdcount = htons (1); + + /* Copy in the name we're looking up. */ + s = (u_int8_t)(hdr + 1); + memcpy (s, qname, namelen); + s += namelen; + + /* Set the query type. */ + putUShort (s, qtype); + s += sizeof (u_int16_t); + + /* Set the query class. */ + putUShort (s, qclass); + s += sizeof (u_int16_t); + + /* Send the query. */ + status = sendto (dns_protocol_fd, query, s - query, 0, + (struct sockaddr *)server, sizeof *server); + + /* If the send failed, report the failure. */ + if (status < 0) + return 0; + return 1; } -ns_packet (ns_header, udp, ip, machine_header) - HEADER *ns_header; - struct udphdr *udp; - struct ip *ip; - unsigned char *machine_header; +/* Process a reply from a name server. */ + +dns_packet (protocol) + struct protocol *protocol; { - unsigned char *base = (unsigned char *)(ns_header + 1); - unsigned char *dptr; - void (*callback) (char *) = ns_callback; - int type; - int class; - int ttl; - int rdlength; - char nbuf [MAXDNAME]; + HEADER *ns_header; + struct sockaddr_in from; + int fl; + unsigned char buf [4096]; + unsigned char nbuf [512]; + unsigned char *base; + unsigned char *dptr; + int type; + int class; + int ttl; + int rdlength; + char nbuf [MAXDNAME]; + + len = sizeof from; + status = recvfrom (protocol -> fd, icbuf, sizeof icbuf, 0, + (struct sockaddr *)&from, &len); + if (status < 0) { + warn ("icmp_echoreply: %m"); + return; + } - nsswap (ns_header); + ns_header = (HEADER *)buf; + base = (unsigned char *)(ns_header + 1); /* Ignore invalid packets... */ - if (ns_header -> id != ns_query_id) - { - printf ("Unexpected NS message; id = %d\n", ns_header -> id); - return; - } - - /* We have our response, so shut down the protocol... */ - ns_callback = (void (*) (char *))0; - ns_query_id = 0; - stop_pushing (); + if (ntohs (ns_header -> id) > ns_query_max) { + printf ("Out-of-range NS message; id = %d\n", + ntohs (ns_header -> id)); + return; + } /* Parse the response... */ - dptr = base; + dptr = base; /* Skip over the query name... */ - dptr += skipname (dptr); + dptr += skipname (dptr); /* Skip over the query type and the query class. */ - dptr += 2 * sizeof (short); + dptr += 2 * sizeof (short); /* Skip over the reply name... */ - dptr += skipname (dptr); + dptr += skipname (dptr); /* Extract the numeric fields: */ - GETSHORT (type, dptr); - GETSHORT (class, dptr); - GETLONG (ttl, dptr); - GETSHORT (rdlength, dptr); - - switch (type) - { - case T_A: - printf ("A record; value is "); - printiaddr (dptr); - if (callback) - (*callback) (dptr); - break; - - case T_CNAME: - case T_PTR: - copy_out_name (base, dptr, nbuf); - printf ("Domain name; value is %s\n", nbuf); - if (callback) - (*callback) (nbuf); - return; - -#ifdef T_TXT - case T_TXT: - printf ("Text string; value is %s\n", dptr); - if (callback) - (*callback) (dptr); - break; -#endif /* T_TXT */ - - default: - printf ("unhandled type: %x\n", type); - } - - if (callback) - (*callback) ((char *)1); -} - -#if BYTE_ORDER == LITTLE_ENDIAN -nsswap (hdr) - HEADER *hdr; -{ - shortswap (hdr -> opcode); - shortswap (hdr -> qdcount); - shortswap (hdr -> ancount); - shortswap (hdr -> nscount); - shortswap (hdr -> arcount); + getUShort (dptr, (u_int8_t *)&type); + dptr += sizeof type; + getULong (dptr, (u_int8_t *)&class); + dptr += sizeof class; + getULong (dptr, (u_int8_t *)&ttl); + dptr += sizeof ttl; + getUShort (dptr, (u_int8_t *)&rdlength); + dptr += sizeof rdlength; + + switch (type) { + case T_A: + printf ("A record; value is %d.%d.%d.%d", + dptr [0], dptr [1], dptr [2], dptr [3]); + break; + + case T_CNAME: + case T_PTR: + copy_out_name (base, dptr, nbuf); + printf ("Domain name; value is %s\n", nbuf); + return; + + default: + printf ("unhandled type: %x\n", type); + } } -#endif