]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Adjust indentation; fix up calling conventions
authorTed Lemon <source@isc.org>
Sat, 29 Mar 1997 01:25:32 +0000 (01:25 +0000)
committerTed Lemon <source@isc.org>
Sat, 29 Mar 1997 01:25:32 +0000 (01:25 +0000)
common/dns.c

index cf178ce5ea701cda1a6616d2e82c0f2a025fb575..e694faba18a4d1bf5ac55ad659f400299cb2305a 100644 (file)
@@ -1,6 +1,6 @@
 /* dns.c
 
-   Domain Name Service subroutine. */
+   Domain Name Service subroutines. */
 
 /*
  * Copyright (C) 1992 by Ted Lemon.
  * 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 <mellon@fugue.com> 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 <mellon@fugue.com> 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