~ubuntu-branches/ubuntu/hardy/dnstracer/hardy

« back to all changes in this revision

Viewing changes to dnstracer.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Seyrat
  • Date: 2004-09-23 00:01:07 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040923000107-vlegx616agkdzci0
Tags: 1.8-1
* New upstream release (closes: #262480)
* Bumped Standards-Version to 3.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
//
2
 
// $Id: dnstracer.c,v 1.40 2003/02/14 09:58:54 mavetju Exp $
 
2
// $Id: dnstracer.c,v 1.48 2004/07/08 11:15:17 mavetju Exp $
3
3
//
4
4
 
5
5
//
60
60
#include "config.h"
61
61
 
62
62
#define DEFAULT_RETRIES 3
63
 
#define DEFAULT_TIMEOUT 15
64
63
#define DEFAULT_CACHING 1
 
64
#define DEFAULT_NEGATIVE_CACHING        0
65
65
#define DEFAULT_OVERVIEW        0
66
66
#define DEFAULT_QUERYTYPE       ns_t_a
67
67
#define DEFAULT_NOIPV6  0
68
68
 
 
69
#ifdef NOIPV6
 
70
#define gethostbyname2(a,b) gethostbyname(a)
 
71
#endif
 
72
 
69
73
int     verbose=0;
70
74
int     global_overview=DEFAULT_OVERVIEW;
71
75
int     global_retries=DEFAULT_RETRIES;
72
 
int     global_timeout=DEFAULT_TIMEOUT;
73
76
int     global_caching=DEFAULT_CACHING;
 
77
int     global_negative_caching=DEFAULT_NEGATIVE_CACHING;
74
78
int     global_querytype=DEFAULT_QUERYTYPE;
75
79
int     global_noipv6=DEFAULT_NOIPV6;
76
80
char *  global_source_address=NULL;
172
176
        struct dnsrr *  next;
173
177
};
174
178
 
 
179
char *rr_types[256]={
 
180
        "#0x00", "a", "ns", "#0x03", "#0x04", "cname", "soa", "#0x07",
 
181
        "#0x08", "#0x09", "#0x0a", "#0x0b", "#ptr", "#hinfo", "#0x0e", "#mx",
 
182
        "#txt", "#0x11", "#0x12", "#0x13", "#0x14", "#0x15", "#0x16", "#0x17",
 
183
        "#0x18", "#0x19", "#0x1a", "#0x1b", "#0x1c", "#0x1d", "#0x1e", "#0x1f",
 
184
        "#0x20", "#0x21", "#0x22", "#0x23", "#0x24", "#0x25", "#0x26", "#0x27",
 
185
        "#0x28", "#0x29", "#0x2a", "#0x2b", "#0x2c", "#0x2d", "#0x2e", "#0x2f",
 
186
        "#0x30", "#0x31", "#0x32", "#0x33", "#0x34", "#0x35", "#0x36", "#0x37",
 
187
        "#0x38", "#0x39", "#0x3a", "#0x3b", "#0x3c", "#0x3d", "#0x3e", "#0x3f",
 
188
        "#0x40", "#0x41", "#0x42", "#0x43", "#0x44", "#0x45", "#0x46", "#0x47",
 
189
        "#0x48", "#0x49", "#0x4a", "#0x4b", "#0x4c", "#0x4d", "#0x4e", "#0x4f",
 
190
        "#0x50", "#0x51", "#0x52", "#0x53", "#0x54", "#0x55", "#0x56", "#0x57",
 
191
        "#0x58", "#0x59", "#0x5a", "#0x5b", "#0x5c", "#0x5d", "#0x5e", "#0x5f",
 
192
        "#0x60", "#0x61", "#0x62", "#0x63", "#0x64", "#0x65", "#0x66", "#0x67",
 
193
        "#0x68", "#0x69", "#0x6a", "#0x6b", "#0x6c", "#0x6d", "#0x6e", "#0x6f",
 
194
        "#0x70", "#0x71", "#0x72", "#0x73", "#0x74", "#0x75", "#0x76", "#0x77",
 
195
        "#0x78", "#0x79", "#0x7a", "#0x7b", "#0x7c", "#0x7d", "#0x7e", "#0x7f",
 
196
        "#0x80", "#0x81", "#0x82", "#0x83", "#0x84", "#0x85", "#0x86", "#0x87",
 
197
        "#0x88", "#0x89", "#0x8a", "#0x8b", "#0x8c", "#0x8d", "#0x8e", "#0x8f",
 
198
        "#0x90", "#0x91", "#0x92", "#0x93", "#0x94", "#0x95", "#0x96", "#0x97",
 
199
        "#0x98", "#0x99", "#0x9a", "#0x9b", "#0x9c", "#0x9d", "#0x9e", "#0x9f",
 
200
        "#0xa0", "#0xa1", "#0xa2", "#0xa3", "#0xa4", "#0xa5", "#0xa6", "#0xa7",
 
201
        "#0xa8", "#0xa9", "#0xaa", "#0xab", "#0xac", "#0xad", "#0xae", "#0xaf",
 
202
        "#0xb0", "#0xb1", "#0xb2", "#0xb3", "#0xb4", "#0xb5", "#0xb6", "#0xb7",
 
203
        "#0xb8", "#0xb9", "#0xba", "#0xbb", "#0xbc", "#0xbd", "#0xbe", "#0xbf",
 
204
        "#0xc0", "#0xc1", "#0xc2", "#0xc3", "#0xc4", "#0xc5", "#0xc6", "#0xc7",
 
205
        "#0xc8", "#0xc9", "#0xca", "#0xcb", "#0xcc", "#0xcd", "#0xce", "#0xcf",
 
206
        "#0xd0", "#0xd1", "#0xd2", "#0xd3", "#0xd4", "#0xd5", "#0xd6", "#0xd7",
 
207
        "#0xd8", "#0xd9", "#0xda", "#0xdb", "#0xdc", "#0xdd", "#0xde", "#0xdf",
 
208
        "#0xe0", "#0xe1", "#0xe2", "#0xe3", "#0xe4", "#0xe5", "#0xe6", "#0xe7",
 
209
        "#0xe8", "#0xe9", "#0xea", "#0xeb", "#0xec", "#0xed", "#0xee", "#0xef",
 
210
        "#0xf0", "#0xf1", "#0xf2", "#0xf3", "#0xf4", "#0xf5", "#0xf6", "#0xf7",
 
211
        "#0xf8", "#0xf9", "#0xfa", "#0xfb", "#0xfc", "#0xfd", "#0xfe", "#0xff"
 
212
};
 
213
 
175
214
/*****************************************************************************/
176
215
 
177
216
char *get_resource(int type,struct dnssession *session,char *buffer,int dots);
522
561
        static char retval[3*NS_MAXDNAME];
523
562
        char mname[NS_MAXDNAME];
524
563
        char rname[NS_MAXDNAME];
525
 
        unsigned short us;
 
564
        unsigned long ul;
526
565
 
527
566
        strcpy(mname,printablename(getname(session,&buffer),dots));
528
567
        strcpy(rname,printablename(getname(session,&buffer),dots));
529
568
 
530
 
        us=getshort(buffer);
531
 
        sprintf(retval,"serial: %hu mname: %s rname: %s",us,mname,rname);
 
569
        ul=getlong(buffer);
 
570
        sprintf(retval,"serial: %ld mname: %s rname: %s",ul,mname,rname);
532
571
        return retval;
533
572
    }
534
573
        
729
768
        hints.ai_family = PF_INET;
730
769
        hints.ai_socktype = SOCK_DGRAM;
731
770
        error = getaddrinfo(global_source_address, 0, &hints, &src_res);
732
 
        if (error == EAI_NODATA) {
 
771
        if (error == EAI_NONAME) {
733
772
            hints.ai_flags = 0;
734
773
            error = getaddrinfo(global_source_address, 0, &hints, &src_res);
735
774
        }
796
835
    return cc;
797
836
}
798
837
 
799
 
int receive_data(struct dnssession *session) {
 
838
int receive_data(struct dnssession *session,int retry) {
800
839
    char                buffer[2048];
801
840
    int                 len;
802
841
    fd_set              in_set;
803
842
    struct timeval      timeout;
804
843
 
805
 
    timeout.tv_sec=global_timeout;
 
844
    timeout.tv_sec=5*(1<<retry);
806
845
    timeout.tv_usec=0;
807
846
 
808
847
    FD_ZERO(&in_set);
1020
1059
    struct dnssession * session;
1021
1060
    struct dnsrr *      rrauth;
1022
1061
    struct dnsrr *      rradd;
1023
 
    int                 i,retval,errorcode;
 
1062
    int                 i,retval,errorcode,refersbackwards=0;
1024
1063
    char                s[NS_MAXDNAME];
1025
1064
 
1026
1065
    //
1097
1136
    errorcode=0;
1098
1137
    for (i=0;i<global_retries;i++) {
1099
1138
        send_data(server_ip,session);
1100
 
        if ((errorcode=receive_data(session))==0)
 
1139
        if ((errorcode=receive_data(session,i))==0)
1101
1140
            break;
1102
1141
        printf("* ");
1103
1142
        fflush(stdout);
1109
1148
    //
1110
1149
    if (errorcode!=0) {
1111
1150
        remove_busy(server_ip);
 
1151
        if (global_negative_caching) add_answer(server_ip);
1112
1152
        return 1;
1113
1153
    }
1114
1154
 
1126
1166
 
1127
1167
        answer=session->answer;
1128
1168
        while (answer!=NULL) {
 
1169
            if (answer->type!=global_querytype)
 
1170
                printf("[received type is %s] ",rr_types[answer->type]);
1129
1171
            add_arecord(session,answer,server_name,server_ip);
1130
1172
            answer=answer->next;
1131
1173
        }
1183
1225
        // of what we have, don't go there. This might happen if we are
1184
1226
        // looking through cnames from different domains.
1185
1227
        //
1186
 
        if (strcmp(rrauth->domainname_string,".") &&
1187
 
                strcasecmp(rrauth->domainname_string,
1188
 
                    host+strlen(host)-strlen(rrauth->domainname_string))!=0) {
 
1228
        if (strcmp(rrauth->domainname_string,".")==0) {
 
1229
            rrauth=rrauth->next;
 
1230
            if (!refersbackwards++)
 
1231
                printf("Refers backwards ");
 
1232
            continue;
 
1233
        }
 
1234
 
 
1235
        if (server_authfor!=NULL && strcmp(server_authfor,".")!=0 &&
 
1236
            (unsigned char *)strcasestr(rrauth->domainname_string,server_authfor)!=rrauth->domainname_string+strlen(rrauth->domainname_string)-strlen(server_authfor)) {
 
1237
            if (!refersbackwards++)
 
1238
                printf("Refers backwards ");
1189
1239
            rrauth=rrauth->next;
1190
1240
            continue;
1191
1241
        }
1233
1283
                strcpy(nextserver_name,printablename(rradd->domainname,1));
1234
1284
                strcpy(nextserver_ip,rradd->data_string);
1235
1285
                retval+=create_session(host,
1236
 
                            nextserver_ip,rradd->type==ns_t_aaaa,
 
1286
                            nextserver_ip,(rradd->type==ns_t_aaaa)?1:0,
1237
1287
                            nextserver_name,rrauth->domainname_string,
1238
1288
                            depth+1,s,(rrauth->next==NULL && found<=1)?1:0);
1239
1289
            } else {
1241
1291
 
1242
1292
                strcpy(nextserver_name,rrauth->data_string);
1243
1293
 
 
1294
#ifdef NOIPV6
 
1295
                for (ip=0;ip<1;ip++) {
 
1296
#else
1244
1297
                for (ip=0;ip<2;ip++) {
 
1298
#endif
1245
1299
                    int count,i;
1246
1300
                    struct hostent *h;
1247
1301
                    char **addr_list=NULL;
1333
1387
 
1334
1388
void usage(void) {
1335
1389
    fprintf(stderr,
1336
 
        "DNSTRACER version 1.7 - (c) Edwin Groothuis - http://www.mavetju.org\n"
 
1390
        "DNSTRACER version 1.8 - (c) Edwin Groothuis - http://www.mavetju.org\n"
1337
1391
        "Usage: dnstracer [options] [host]\n"
1338
1392
        "\t-c: disable local caching, default enabled\n"
 
1393
        "\t-C: enable negative caching, default disabled\n"
1339
1394
        "\t-o: enable overview of received answers, default disabled\n"
1340
1395
        "\t-q <querytype>: query-type to use for the DNS requests, default A\n"
1341
1396
        "\t-r <retries>: amount of retries for DNS requests, default 3\n"
1342
1397
        "\t-s <server>: use this server for the initial request, default localhost\n"
1343
1398
        "\t             If . is specified, A.ROOT-SERVERS.NET will be used.\n"
1344
 
        "\t-t <timeout>: timeout for DNS requests, default 15 seconds\n"
1345
1399
        "\t-v: verbose\n"
 
1400
        "\t-S <ip address>: use this source address.\n"
 
1401
    );
 
1402
#ifndef NOIPV6
 
1403
    fprintf(stderr,
1346
1404
        "\t-4: don't query IPv6 servers\n"
1347
 
        "\t-S <ip address>: use this source address.\n"
1348
1405
    );
 
1406
#endif
1349
1407
    exit(1);
1350
1408
}
1351
1409
 
1390
1448
    wsockinit();
1391
1449
#endif
1392
1450
 
1393
 
    while ((ch=getopt(argc,argv,"4coq:r:S:s:t:v"))!=-1) {
 
1451
#ifndef NOIPV6
 
1452
    while ((ch=getopt(argc,argv,"4cCoq:r:S:s:v"))!=-1) {
 
1453
#else
 
1454
    while ((ch=getopt(argc,argv,"cCoq:r:S:s:v"))!=-1) {
 
1455
#endif
1394
1456
        switch (ch) {
 
1457
#ifndef NOIPV6
1395
1458
        case '4':
1396
1459
            global_noipv6=1;
1397
1460
            break;
 
1461
#endif
1398
1462
 
1399
1463
        case 'c':
1400
1464
            global_caching=0;
1401
1465
            break;
1402
1466
 
 
1467
        case 'C':
 
1468
            global_negative_caching=1;
 
1469
            break;
 
1470
 
1403
1471
        case 'o':
1404
1472
            global_overview=1;
1405
1473
            break;
1448
1516
            }
1449
1517
            break;
1450
1518
 
1451
 
        case 't':
1452
 
            if ((global_timeout=atoi(optarg))<1) {
1453
 
                fprintf(stderr,
1454
 
                    "Strange timeout, setting to default\n");
1455
 
                global_timeout=DEFAULT_TIMEOUT;
1456
 
            }
1457
 
            break;
1458
 
 
1459
1519
        case 'v':
1460
1520
            verbose=1;
1461
1521
            break;
1473
1533
    strcpy(argv0,argv[0]);
1474
1534
    if (argv0[strlen(argv[0])-1]=='.') argv0[strlen(argv[0])-1]=0;
1475
1535
 
1476
 
    printf("Tracing to %s via %s, timeout %d seconds\n",
1477
 
        argv0,server_name,global_timeout);
 
1536
    printf("Tracing to %s[%s] via %s, maximum of %d retries\n",
 
1537
        argv0,rr_types[global_querytype],server_name,global_retries);
1478
1538
 
1479
1539
    srandom(time(NULL));
1480
1540