Back to index

opendkim  2.6.6
ar-test00.c
Go to the documentation of this file.
00001 /*
00002 **  Copyright (c) 2010, 2011, The OpenDKIM Project.  All rights reserved.
00003 */
00004 
00005 #ifndef lint
00006 static char ar_test00_c_id[] = "@(#)$Id: ar-test00.c,v 1.2 2010/08/30 22:01:56 cm-msk Exp $";
00007 #endif /* !lint */
00008 
00009 /* system includes */
00010 #include <sys/types.h>
00011 #include <sys/select.h>
00012 #include <netinet/in.h>
00013 #include <arpa/nameser.h>
00014 #include <resolv.h>
00015 #include <netdb.h>
00016 #include <assert.h>
00017 #include <stdio.h>
00018 #include <string.h>
00019 
00020 /* libar includes */
00021 #include "../async-resolv.h"
00022 
00023 /* local definitions needed for DNS queries */
00024 #define MAXPACKET           8192
00025 #if defined(__RES) && (__RES >= 19940415)
00026 # define RES_UNC_T          char *
00027 #else /* __RES && __RES >= 19940415 */
00028 # define RES_UNC_T          unsigned char *
00029 #endif /* __RES && __RES >= 19940415 */
00030 
00031 #define       AR_MAXHOSTNAMELEN    256
00032 
00033 #define       TESTQUERY            "yahoo.com"
00034 
00035 /*
00036 **  MAIN -- program mainline
00037 **
00038 **  Parameters:
00039 **     The usual.
00040 **
00041 **  Return value:
00042 **     Exit status.
00043 */
00044 
00045 int
00046 main(int argc, char **argv)
00047 {
00048        int err = NOERROR;
00049        int n;
00050        size_t len;
00051        uint16_t qdcount;
00052        uint16_t ancount;
00053        uint16_t type;
00054        uint16_t class;
00055        uint16_t rrsize;
00056        uint32_t ttl;
00057        uint32_t addr;
00058        AR_LIB ar;
00059        AR_QUERY q;
00060        HEADER *hdr;
00061        unsigned char *cp;
00062        unsigned char *eom;
00063        struct timeval timeout;
00064        unsigned char name[AR_MAXHOSTNAMELEN + 1];
00065        unsigned char buf[MAXPACKET];
00066 
00067        printf("*** simple A query\n");
00068 
00069        /* initialize */
00070        ar = ar_init(NULL, NULL, NULL, 0);
00071        assert(ar != NULL);
00072 
00073        /* launch a query */
00074        timeout.tv_sec = 5;
00075        timeout.tv_usec = 0;
00076        q = ar_addquery(ar, TESTQUERY, C_IN, T_A, 0, buf, sizeof buf, &err,
00077                        &timeout);
00078        assert(q != NULL);
00079 
00080        /* wait for the reply */
00081        timeout.tv_sec = 5;
00082        timeout.tv_usec = 0;
00083        assert(ar_waitreply(ar, q, &len, &timeout) == AR_STAT_SUCCESS);
00084        assert(len <= sizeof buf);
00085        assert(err == NOERROR);
00086 
00087        /* verify it */
00088        hdr = (HEADER *) buf;
00089        cp = buf + HFIXEDSZ;
00090        eom = buf + len;
00091 
00092        /* skip over the name at the front of the answer */
00093        for (qdcount = ntohs((unsigned short) hdr->qdcount);
00094             qdcount > 0;
00095             qdcount--)
00096        {
00097               /* copy it first */
00098               memset(name, '\0', sizeof name);
00099               (void) dn_expand((unsigned char *) buf, eom, cp,
00100                                (RES_UNC_T) name, sizeof name);
00101 
00102               assert(strcasecmp(name, TESTQUERY) == 0);
00103 
00104               n = dn_skipname(cp, eom);
00105               assert(n > 0);
00106               cp += n;
00107 
00108               /* extract the type and class */
00109               GETSHORT(type, cp);
00110               assert(type == T_A);
00111               GETSHORT(class, cp);
00112               assert(class == C_IN);
00113        }
00114 
00115        assert(hdr->rcode == NOERROR);
00116 
00117        /* get the answer count */
00118        ancount = ntohs((unsigned short) hdr->ancount);
00119        assert(ancount != 0);
00120 
00121        printf("--- got %u answer(s)\n", ancount);
00122 
00123        while (ancount-- > 0 && cp < eom)
00124        {
00125               /* grab the label, even though we know what we asked... */
00126               memset(name, '\0', sizeof name);
00127               n = dn_expand((unsigned char *) buf, eom, cp,
00128                             (RES_UNC_T) name, sizeof name);
00129               assert(n > 0);
00130               assert(strcasecmp(name, TESTQUERY) == 0);
00131               
00132               /* ...and move past it */
00133               cp += n;
00134 
00135               /* extract the type and class */
00136               assert(cp + INT16SZ + INT16SZ + INT32SZ <= eom);
00137               GETSHORT(type, cp);
00138               assert(type == T_A);
00139               GETSHORT(class, cp);
00140               assert(class == C_IN);
00141               GETLONG(ttl, cp);
00142               assert(ttl >= 0);
00143 
00144               /* get payload length */
00145               assert(cp + INT16SZ <= eom);
00146               GETSHORT(n, cp);
00147 
00148               /* extract payload */
00149               assert(cp + INT32SZ <= eom);
00150               GETLONG(addr, cp);
00151 
00152               /* output it */
00153               addr = ntohl(addr);
00154               printf("--- '%s' has address %02u.%02u.%02u.%02u\n",
00155                      TESTQUERY,
00156                      (addr & 0x000000ff),
00157                      (addr & 0x0000ff00) >> 8,
00158                      (addr & 0x00ff0000) >> 16,
00159                      (addr & 0xff000000) >> 24);
00160        }
00161 
00162        /* free memory */
00163        ar_cancelquery(ar, q);
00164 
00165        /* shut down */
00166        assert(ar_shutdown(ar) == 0);
00167 
00168        return 0;
00169 }