Back to index

courier  0.68.2
Classes | Defines | Functions
rfc1035.c File Reference
#include "config.h"
#include <stdio.h>
#include "soxwrap/soxwrap.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <time.h>
#include <arpa/inet.h>
#include "rfc1035.h"

Go to the source code of this file.

Classes

struct  compresslist

Defines

#define ISSPACE(c)   (strchr(" \t\r\n", (int)(unsigned char)(c)) != NULL)

Functions

void rfc1035_init_timeout (struct rfc1035_res *res, unsigned s, unsigned n)
void rfc1035_init_ns (struct rfc1035_res *res, const RFC1035_ADDR *a, unsigned n)
int rfc1035_init_defaultdomain (struct rfc1035_res *res, const char *p)
void rfc1035_init_dnssec_enable (struct rfc1035_res *res, int flag)
void rfc1035_init_edns_payload (struct rfc1035_res *res, int payload_size)
static char tl (char c)
void rfc1035_init_resolv (struct rfc1035_res *res)
void rfc1035_destroy_resolv (struct rfc1035_res *res)
static int mkpacketq (void(*)(const char *, unsigned, void *), void *, unsigned *, const struct rfc1035_query *, unsigned, const char *, struct compresslist *, struct rfc1035_res *)
unsigned rfc1035_next_randid (struct rfc1035_res *res)
int rfc1035_mkquery (struct rfc1035_res *res, unsigned opcode, const struct rfc1035_query *questions, unsigned nquestions, void(*func)(const char *, unsigned, void *), void *arg)
int rfc1035_hostnamecmp (const char *p, const char *q)
static struct compresslistsearch (struct compresslist *cp, const char *name)
static int mkpacketq_full (void(*)(const char *, unsigned, void *), void *, unsigned *, const struct rfc1035_query *, unsigned, const char *, struct compresslist *, struct rfc1035_res *)
int rfc1035_wait_reply (int fd, unsigned nsecs)
int rfc1035_wait_query (int fd, unsigned nsecs)

Class Documentation

struct compresslist

Definition at line 183 of file rfc1035.c.

Collaboration diagram for compresslist:
Class Members
struct compresslist * next
unsigned offset
const char * ptr

Define Documentation

#define ISSPACE (   c)    (strchr(" \t\r\n", (int)(unsigned char)(c)) != NULL)

Definition at line 31 of file rfc1035.c.


Function Documentation

static int mkpacketq ( void(*)(const char *, unsigned, void *)  func,
void *  arg,
unsigned *  cnt,
const struct rfc1035_query qp,
unsigned  nqp,
const char *  nameptr,
struct compresslist comp_list,
struct rfc1035_res res 
) [static]

Definition at line 334 of file rfc1035.c.

{
char   *buf;
int    rc;


       if (!res->rfc1035_defaultdomain || strchr(nameptr, '.'))
              return (mkpacketq_full(func, arg, cnt, qp, nqp, nameptr,
                     comp_list, res));

       /* Append default domain */

       if ((buf=malloc(strlen(nameptr)+
              strlen(res->rfc1035_defaultdomain)+2)) == 0)
              return (-1);

       strcat(strcat(strcpy(buf, nameptr), "."),
              res->rfc1035_defaultdomain);

       rc=mkpacketq_full(func, arg, cnt, qp, nqp, buf, comp_list, res);
       free(buf);
       return (rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int mkpacketq_full ( void(*)(const char *, unsigned, void *)  func,
void *  arg,
unsigned *  cnt,
const struct rfc1035_query qp,
unsigned  nqp,
const char *  nameptr,
struct compresslist comp_list,
struct rfc1035_res res 
) [static]

Definition at line 364 of file rfc1035.c.

{
unsigned llen;
struct compresslist *cp;

       while (nameptr && *nameptr == '.')
              ++nameptr;

       if (!nameptr || !*nameptr)
       {
       struct {
              unsigned char padtail;
              unsigned char qtypehi, qtypelo;
              unsigned char qclasshi, qclasslo;
              } qtail;

              qtail.padtail=0;
              qtail.qtypehi=qp->qtype >> 8;
              qtail.qtypelo=qp->qtype;
              qtail.qclasshi=qp->qclass >> 8;
              qtail.qclasslo=qp->qclass;

              (*func)((const char *)&qtail, sizeof(qtail), arg);
              ++qp;
              --nqp;
              *cnt += sizeof(qtail);
              if (nqp)
                     return (mkpacketq(func, arg, cnt,
                            qp, nqp, qp->name, comp_list, res));
              return (0);
       }

       for (llen=0; nameptr[llen] && nameptr[llen] != '.'; llen++)
              ;
       cp=search(comp_list, nameptr);
       if (cp)
       {
       struct {
              unsigned char ptrhi, ptrlo;
              unsigned char qtypehi, qtypelo;
              unsigned char qclasshi, qclasslo;
              } qtail;

              qtail.ptrhi= (cp->offset >> 8) | 0xC0;
              qtail.ptrlo= cp->offset;
              qtail.qtypehi=qp->qtype >> 8;
              qtail.qtypelo=qp->qtype;
              qtail.qclasshi=qp->qclass >> 8;
              qtail.qclasslo=qp->qclass;

              (*func)( (const char *)&qtail, sizeof(qtail), arg);
              ++qp;
              --nqp;
              *cnt += sizeof(qtail);

              if (nqp)
                     return (mkpacketq(func, arg, cnt,
                            qp, nqp, qp->name, comp_list, res));
       }
       else
       {
       unsigned n=llen;
       unsigned char c;
       struct compresslist newc;

              if (n > 63)   return (-1);

              newc.next=comp_list;
              newc.offset= *cnt;
              newc.ptr=nameptr;

              c=(unsigned char)n;
              (*func)((const char *) &c, 1, arg);
              (*func)( nameptr, c, arg);
              *cnt += 1+c;
              return (mkpacketq_full(func, arg, cnt,
                            qp, nqp, nameptr+llen, &newc, res));
       }
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void rfc1035_destroy_resolv ( struct rfc1035_res res)

Definition at line 173 of file rfc1035.c.

{
       if (res->rfc1035_defaultdomain)
       {
              free(res->rfc1035_defaultdomain);
       }
}

Here is the caller graph for this function:

int rfc1035_hostnamecmp ( const char *  p,
const char *  q 
)

Definition at line 294 of file rfc1035.c.

{
       while (*p || *q)
       {
              if (*p == '.' || *q == '.' )
              {
                     if ( (*p && *p != '.') || (*q && *q != '.'))
                            return (1);
                     while (*p == '.')    ++p;
                     while (*q == '.')    ++q;
                     continue;
              }
              if (!*p || !*q)      return (1);
              if ( tl(*p) != tl(*q))      return (1);
              ++p;
              ++q;
       }
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int rfc1035_init_defaultdomain ( struct rfc1035_res res,
const char *  p 
)

Definition at line 86 of file rfc1035.c.

{
char   *q;

       if (res->rfc1035_defaultdomain)
              free(res->rfc1035_defaultdomain);

       if ((res->rfc1035_defaultdomain=malloc(strlen(p)+1)) == 0)
              return (-1);

       strcpy(res->rfc1035_defaultdomain, p);
       for (q=res->rfc1035_defaultdomain; *q; q++)
              if (ISSPACE(*q))
              {
                     *q=0;
                     break;
              }

       return (0);
}

Here is the caller graph for this function:

void rfc1035_init_dnssec_enable ( struct rfc1035_res res,
int  flag 
)

Definition at line 107 of file rfc1035.c.

{
       rfc1035_init_edns_payload(res, flag ? 1280:0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void rfc1035_init_edns_payload ( struct rfc1035_res res,
int  payload_size 
)

Definition at line 113 of file rfc1035.c.

{
       res->dnssec_payload_size=payload_size;
}

Here is the caller graph for this function:

void rfc1035_init_ns ( struct rfc1035_res res,
const RFC1035_ADDR *  a,
unsigned  n 
)

Definition at line 47 of file rfc1035.c.

{
unsigned i;
unsigned j;

       j=0;

       random128_binary(&res->randseed);
       md5_digest(&res->randseed, sizeof(res->randseed), res->randbuf);
       res->randptr=0;

       for (i=0; i == 0 || (i<n && i<RFC1035_MAXNS); i++)
       {
#if RFC1035_IPV6
       struct in6_addr sin;

              if (n == 0)
                     sin=in6addr_loopback;
              else
                     sin=a[(j+i)%n];

#else
       struct in_addr sin;

              if (n == 0)
              {
                     rfc1035_aton("127.0.0.1", &sin);
              }
              else
                     sin=a[(j+i)%n];
              memset(&res->nameservers[i], 0, sizeof(res->nameservers[i]));
              res->nameservers[i]=sin;
#endif
              res->nameservers[i]=sin;
       }
       res->rfc1035_nnameservers=i;

}

Here is the call graph for this function:

Here is the caller graph for this function:

void rfc1035_init_resolv ( struct rfc1035_res res)

Definition at line 126 of file rfc1035.c.

{
FILE   *fp=fopen("/etc/resolv.conf", "r");
char rfc1035_buf[512];
RFC1035_ADDR ns[RFC1035_MAXNS];
int nns=0;

       memset(res, 0, sizeof(*res));

       while (fp && fgets(rfc1035_buf, sizeof(rfc1035_buf), fp))
       {
       char   *p;

              for (p=rfc1035_buf; *p; p++)
                     *p=tl(*p);

              for (p=rfc1035_buf; *p; p++)
                     if (ISSPACE(*p))     break;
              if (*p)       *p++=0;

              if (strcmp(rfc1035_buf, "domain") == 0)
              {
                     while (p && ISSPACE(*p))
                            ++p;
                     rfc1035_init_defaultdomain(res, p);
                     continue;
              }

              if (strcmp(rfc1035_buf, "nameserver"))    continue;
              while (*p && ISSPACE(*p))   p++;
              if (nns < RFC1035_MAXNS)
              {
              char   *q;

                     for (q=p; *q && !ISSPACE(*q); q++)
                            ;
                     *q=0;

                     if (rfc1035_aton(p, &ns[nns++]) < 0)
                            --nns;
              }
       }
       if (fp) fclose(fp);

       rfc1035_init_ns(res, ns, nns);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void rfc1035_init_timeout ( struct rfc1035_res res,
unsigned  s,
unsigned  n 
)

Definition at line 41 of file rfc1035.c.

int rfc1035_mkquery ( struct rfc1035_res res,
unsigned  opcode,
const struct rfc1035_query questions,
unsigned  nquestions,
void(*)(const char *, unsigned, void *)  func,
void *  arg 
)

Definition at line 218 of file rfc1035.c.

{
struct {
       unsigned char idhi, idlo;
       unsigned char infohi, infolo;
       unsigned char qhi, qlo;
       unsigned char ahi, alo;
       unsigned char nhi, nlo;
       unsigned char auhi, aulo;
       } header;
unsigned cnt;

       unsigned id=rfc1035_next_randid(res);

       header.idhi= id >> 8;
       header.idlo= id;

       header.infohi= (opcode << 3) & 0x78;

       if (!res->norecursive)
              header.infohi |= 1; /* Want a recursive query */
       header.infolo=0;
       header.qhi=nquestions >> 8;
       header.qlo=nquestions;
       header.ahi=0;
       header.alo=0;
       header.nhi=0;
       header.nlo=0;
       header.auhi=0;
       header.aulo=0;

       if (res->dnssec_payload_size)
              header.aulo=1;

       (*func)( (const char *)&header, sizeof(header), arg);
       cnt=sizeof(header);
       if (nquestions)
              if (mkpacketq(func, arg, &cnt, questions, nquestions,
                     questions->name, 0, res))   return (-1);

       if (res->dnssec_payload_size)
       {
              /* RFC 2671, section 4.3 */

              struct {
                     char opt_root_domain_name;
                     char opt_type_hi;
                     char opt_type_lo;
                     char opt_class_hi;
                     char opt_class_lo;
                     char opt_extendedrcode;
                     char opt_version;
                     char opt_ttl_zhi;
                     char opt_ttl_zlo;
                     char opt_rdlen_hi;
                     char opt_rdlen_lo;
              } rfc2671_43;

              memset(&rfc2671_43, 0, sizeof(rfc2671_43));

              rfc2671_43.opt_type_lo=RFC1035_TYPE_OPT;

              rfc2671_43.opt_class_hi= res->dnssec_payload_size >> 8;
              rfc2671_43.opt_class_lo= res->dnssec_payload_size;
              rfc2671_43.opt_ttl_zhi |= 0x80; /* RFC 3225 */

              (*func)((char *)&rfc2671_43, sizeof(rfc2671_43), arg);
       }

       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned rfc1035_next_randid ( struct rfc1035_res res)

Definition at line 197 of file rfc1035.c.

{
       unsigned i;

       if (res->randptr >= sizeof(res->randbuf))
       {
              for (i=0; i<sizeof(res->randseed); i++)
                     if ( ++((unsigned char *)res->randseed)[i])
                            break;

              md5_digest(res->randseed, sizeof(res->randseed),
                        res->randbuf);
              res->randptr=0;
       }

       i= ((unsigned)((unsigned char *)res->randbuf)[res->randptr] << 8) |
              ((unsigned char *)res->randbuf)[res->randptr+1];
       res->randptr += 2;
       return i;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int rfc1035_wait_query ( int  fd,
unsigned  nsecs 
)

Definition at line 476 of file rfc1035.c.

{
fd_set fds;
struct timeval tv;
int    n;

       FD_ZERO(&fds);
       FD_SET(fd, &fds);
       tv.tv_sec=nsecs;
       tv.tv_usec=0;
       while ((n=sox_select(fd+1, 0, &fds, 0, &tv)) < 0)
       {
              if (errno != EINTR)
                     break;
       }

       if (n > 0 && FD_ISSET(fd, &fds))
              return (0);
       errno=ETIMEDOUT;
       return (-1);
}

Here is the caller graph for this function:

int rfc1035_wait_reply ( int  fd,
unsigned  nsecs 
)

Definition at line 454 of file rfc1035.c.

{
fd_set fds;
struct timeval tv;
int    n;

       FD_ZERO(&fds);
       FD_SET(fd, &fds);
       tv.tv_sec=nsecs;
       tv.tv_usec=0;
       while ((n=sox_select(fd+1, &fds, 0, 0, &tv)) < 0)
       {
              if (errno != EINTR)
                     break;
       }

       if (n > 0 && FD_ISSET(fd, &fds))
              return (0);
       errno=ETIMEDOUT;
       return (-1);
}

Here is the caller graph for this function:

static struct compresslist* search ( struct compresslist cp,
const char *  name 
) [static, read]

Definition at line 314 of file rfc1035.c.

{
       for ( ; cp; cp=cp->next)
       {
              if (rfc1035_hostnamecmp(name, cp->ptr) == 0 &&
                     (cp->offset & 0x3FFF) == cp->offset)
                     return (cp);
                     /* Packet compression uses the two high bits */
       }
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char tl ( char  c) [static]

Definition at line 118 of file rfc1035.c.

{
       if (c >= 'A' && c <= 'Z')
              c += 'a' - 'A';

       return c;
}

Here is the caller graph for this function: