~andreserl/ubuntu/lucid/bind9/bind9-apport-533601

« back to all changes in this revision

Viewing changes to bin/dig/dig.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones, LaMont Jones, Internet Software Consortium, Inc, localization folks
  • Date: 2008-08-02 14:20:20 UTC
  • mfrom: (1.2.1 upstream) (6.1.24 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080802142020-l1hon9jy8lbbjxmg
[LaMont Jones]

* default to using resolvconf if it is installed
* fix sonames and dependencies.  Closes: #149259, #492418
* Do not build-depend libcap2-dev on non-linux.  Closes: #493392
* drop unused query-loc manpage.  Closes: #492564
* lwresd: Deliver /etc/bind directory.  Closes: #490027
* fix query-source comment in default install

[Internet Software Consortium, Inc]

* 9.5.0-P2.  Closes: #492949

[localization folks]

* l10n: Spanish debconf translation.  Closes: #492425 (Ignacio Mondino)
* l10n: Swedish debconf templates.  Closes: #491369 (Martin Ågren)
* l10n: Japanese debconf translations.  Closes: #492048 (Hideki Yamane
  (Debian-JP))
* l10n: Finnish translation.  Closes: #490630 (Esko Arajärvi)
* l10n: Italian debconf translations.  Closes: #492587 (Alessandro Vietta)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2004, 2005  Internet Systems Consortium, Inc. ("ISC")
 
2
 * Copyright (C) 2004-2008  Internet Systems Consortium, Inc. ("ISC")
3
3
 * Copyright (C) 2000-2003  Internet Software Consortium.
4
4
 *
5
 
 * Permission to use, copy, modify, and distribute this software for any
 
5
 * Permission to use, copy, modify, and/or distribute this software for any
6
6
 * purpose with or without fee is hereby granted, provided that the above
7
7
 * copyright notice and this permission notice appear in all copies.
8
8
 *
15
15
 * PERFORMANCE OF THIS SOFTWARE.
16
16
 */
17
17
 
18
 
/* $Id: dig.c,v 1.157.2.13.2.29 2005/10/14 01:38:40 marka Exp $ */
 
18
/* $Id: dig.c,v 1.218.12.3 2008/04/03 02:12:21 marka Exp $ */
 
19
 
 
20
/*! \file */
19
21
 
20
22
#include <config.h>
21
23
#include <stdlib.h>
40
42
#include <dns/rdatatype.h>
41
43
#include <dns/rdataclass.h>
42
44
#include <dns/result.h>
 
45
#include <dns/tsig.h>
43
46
 
44
47
#include <bind9/getaddresses.h>
45
48
 
47
50
 
48
51
#define ADD_STRING(b, s) {                              \
49
52
        if (strlen(s) >= isc_buffer_availablelength(b)) \
50
 
                return (ISC_R_NOSPACE);                 \
 
53
                return (ISC_R_NOSPACE);                 \
51
54
        else                                            \
52
55
                isc_buffer_putstr(b, s);                \
53
56
}
67
70
        ip6_int = ISC_FALSE, plusquest = ISC_FALSE, pluscomm = ISC_FALSE,
68
71
        multiline = ISC_FALSE, nottl = ISC_FALSE, noclass = ISC_FALSE;
69
72
 
 
73
/*% opcode text */
70
74
static const char *opcodetext[] = {
71
75
        "QUERY",
72
76
        "IQUERY",
86
90
        "RESERVED15"
87
91
};
88
92
 
 
93
/*% return code text */
89
94
static const char *rcodetext[] = {
90
95
        "NOERROR",
91
96
        "FORMERR",
106
111
        "BADVERS"
107
112
};
108
113
 
 
114
/*% print usage */
109
115
static void
110
116
print_usage(FILE *fp) {
111
117
        fputs(
122
128
        exit(1);
123
129
}
124
130
 
 
131
/*% version */
125
132
static void
126
133
version(void) {
127
134
        fputs("DiG " VERSION "\n", stderr);
128
135
}
129
136
 
 
137
/*% help */
130
138
static void
131
139
help(void) {
132
140
        print_usage(stdout);
136
144
"        q-type   is one of (a,any,mx,ns,soa,hinfo,axfr,txt,...) [default:a]\n"
137
145
"                 (Use ixfr=version for type ixfr)\n"
138
146
"        q-opt    is one of:\n"
139
 
"                 -x dot-notation     (shortcut for in-addr lookups)\n"
140
 
"                 -i                  (IP6.INT reverse IPv6 lookups)\n"
 
147
"                 -x dot-notation     (shortcut for reverse lookups)\n"
 
148
"                 -i                  (use IP6.INT for IPv6 reverse lookups)\n"
141
149
"                 -f filename         (batch mode)\n"
142
150
"                 -b address[#port]   (bind to source address/port)\n"
143
151
"                 -p port             (specify port number)\n"
 
152
"                 -q name             (specify query name)\n"
144
153
"                 -t type             (specify query type)\n"
145
154
"                 -c class            (specify query class)\n"
146
155
"                 -k keyfile          (specify tsig key file)\n"
147
 
"                 -y name:key         (specify named base64 tsig key)\n"
 
156
"                 -y [hmac:]name:key  (specify named base64 tsig key)\n"
148
157
"                 -4                  (use IPv4 query transport only)\n"
149
158
"                 -6                  (use IPv6 query transport only)\n"
150
159
"        d-opt    is of the form +keyword[=value], where keyword is:\n"
156
165
"                 +domain=###         (Set default domainname)\n"
157
166
"                 +bufsize=###        (Set EDNS0 Max UDP packet size)\n"
158
167
"                 +ndots=###          (Set NDOTS value)\n"
 
168
"                 +edns=###           (Set EDNS version)\n"
159
169
"                 +[no]search         (Set whether to use searchlist)\n"
 
170
"                 +[no]showsearch     (Search with intermediate results)\n"
160
171
"                 +[no]defname        (Ditto)\n"
161
172
"                 +[no]recurse        (Recursive mode)\n"
162
173
"                 +[no]ignore         (Don't revert to TCP for TC responses.)"
183
194
"                 +[no]identify       (ID responders in short answers)\n"
184
195
"                 +[no]trace          (Trace delegation down from root)\n"
185
196
"                 +[no]dnssec         (Request DNSSEC records)\n"
 
197
"                 +[no]nsid           (Request Name Server ID)\n"
186
198
#ifdef DIG_SIGCHASE
187
199
"                 +[no]sigchase       (Chase DNSSEC signatures)\n"
188
200
"                 +trusted-key=####   (Trusted Key when chasing DNSSEC sigs)\n"
198
210
        stdout);
199
211
}
200
212
 
201
 
/*
 
213
/*%
202
214
 * Callback from dighost.c to print the received message.
203
215
 */
204
216
void
219
231
                time(&tnow);
220
232
                printf(";; WHEN: %s", ctime(&tnow));
221
233
                if (query->lookup->doing_xfr) {
222
 
                        printf(";; XFR size: %u records (messages %u)\n",
223
 
                               query->rr_count, query->msg_count);
 
234
                        printf(";; XFR size: %u records (messages %u, "
 
235
                               "bytes %" ISC_PRINT_QUADFORMAT "u)\n",
 
236
                               query->rr_count, query->msg_count,
 
237
                               query->byte_count);
224
238
                } else {
225
 
                        printf(";; MSG SIZE  rcvd: %d\n", bytes);
 
239
                        printf(";; MSG SIZE  rcvd: %u\n", bytes);
226
240
 
227
241
                }
228
242
                if (key != NULL) {
236
250
                puts("");
237
251
        } else if (query->lookup->identify && !short_form) {
238
252
                diff = isc_time_microdiff(&now, &query->time_sent);
239
 
                printf(";; Received %u bytes from %s(%s) in %d ms\n\n",
240
 
                       bytes, fromtext, query->servname,
 
253
                printf(";; Received %" ISC_PRINT_QUADFORMAT "u bytes "
 
254
                       "from %s(%s) in %d ms\n\n",
 
255
                       query->lookup->doing_xfr ?
 
256
                                query->byte_count : (isc_uint64_t)bytes,
 
257
                       fromtext, query->servname,
241
258
                       (int)diff/1000);
242
259
        }
243
260
}
253
270
        UNUSED(lookup);
254
271
}
255
272
 
256
 
/*
 
273
/*%
257
274
 * Internal print routine used to print short form replies.
258
275
 */
259
276
static isc_result_t
283
300
        return (ISC_R_SUCCESS);
284
301
}
285
302
 
286
 
/*
 
303
/*%
287
304
 * short_form message print handler.  Calls above say_message()
288
305
 */
289
306
static isc_result_t
367
384
        else if (nottl || noclass)
368
385
                result = dns_master_stylecreate(&style, styleflags,
369
386
                                                24, 24, 32, 40, 80, 8, mctx);
370
 
        else 
 
387
        else
371
388
                result = dns_master_stylecreate(&style, styleflags,
372
389
                                                24, 32, 40, 48, 80, 8, mctx);
373
390
        check_result(result, "dns_master_stylecreate");
376
393
 
377
394
        if (style != NULL)
378
395
                dns_master_styledestroy(&style, mctx);
379
 
  
 
396
 
380
397
        return(result);
381
398
}
382
399
#endif
413
430
        else if (nottl || noclass)
414
431
                result = dns_master_stylecreate(&style, styleflags,
415
432
                                                24, 24, 32, 40, 80, 8, mctx);
416
 
        else 
 
433
        else
417
434
                result = dns_master_stylecreate(&style, styleflags,
418
435
                                                24, 32, 40, 48, 80, 8, mctx);
419
436
        check_result(result, "dns_master_stylecreate");
475
492
                               msg->counts[DNS_SECTION_ANSWER],
476
493
                               msg->counts[DNS_SECTION_AUTHORITY],
477
494
                               msg->counts[DNS_SECTION_ADDITIONAL]);
 
495
 
 
496
                        if (msg != query->lookup->sendmsg &&
 
497
                            (msg->flags & DNS_MESSAGEFLAG_RD) != 0 &&
 
498
                            (msg->flags & DNS_MESSAGEFLAG_RA) == 0)
 
499
                                printf(";; WARNING: recursion requested "
 
500
                                       "but not available\n");
478
501
                }
 
502
                if (msg != query->lookup->sendmsg && extrabytes != 0U)
 
503
                        printf(";; WARNING: Messages has %u extra byte%s at "
 
504
                               "end\n", extrabytes, extrabytes != 0 ? "s" : "");
479
505
        }
480
506
 
481
507
repopulate_buffer:
578
604
        return (result);
579
605
}
580
606
 
581
 
/*
 
607
/*%
582
608
 * print the greeting message when the program first starts up.
583
609
 */
584
610
static void
613
639
                        strncat(lookup->cmdline, append, remaining);
614
640
                }
615
641
                if (first) {
616
 
                        snprintf(append, sizeof(append), 
 
642
                        snprintf(append, sizeof(append),
617
643
                                 ";; global options: %s %s\n",
618
644
                               short_form ? "short_form" : "",
619
645
                               printcmd ? "printcmd" : "");
625
651
        }
626
652
}
627
653
 
628
 
/*
629
 
 * Reorder an argument list so that server names all come at the end.
630
 
 * This is a bit of a hack, to allow batch-mode processing to properly
631
 
 * handle the server options.
632
 
 */
633
 
static void
634
 
reorder_args(int argc, char *argv[]) {
635
 
        int i, j;
636
 
        char *ptr;
637
 
        int end;
638
 
 
639
 
        debug("reorder_args()");
640
 
        end = argc - 1;
641
 
        while (argv[end][0] == '@') {
642
 
                end--;
643
 
                if (end == 0)
644
 
                        return;
645
 
        }
646
 
        debug("arg[end]=%s", argv[end]);
647
 
        for (i = 1; i < end - 1; i++) {
648
 
                if (argv[i][0] == '@') {
649
 
                        debug("arg[%d]=%s", i, argv[i]);
650
 
                        ptr = argv[i];
651
 
                        for (j = i + 1; j < end; j++) {
652
 
                                debug("Moving %s to %d", argv[j], j - 1);
653
 
                                argv[j - 1] = argv[j];
654
 
                        }
655
 
                        debug("moving %s to end, %d", ptr, end - 1);
656
 
                        argv[end - 1] = ptr;
657
 
                        end--;
658
 
                        if (end < 1)
659
 
                                return;
660
 
                }
661
 
        }
662
 
}
663
 
 
664
654
static isc_uint32_t
665
655
parse_uint(char *arg, const char *desc, isc_uint32_t max) {
666
656
        isc_result_t result;
674
664
        return (tmp);
675
665
}
676
666
 
677
 
/*
 
667
/*%
678
668
 * We're not using isc_commandline_parse() here since the command line
679
669
 * syntax of dig is quite a bit different from that which can be described
680
670
 * by that routine.
727
717
                        FULLCHECK2("aaonly", "aaflag");
728
718
                        lookup->aaonly = state;
729
719
                        break;
730
 
                case 'd': 
 
720
                case 'd':
731
721
                        switch (cmd[2]) {
732
722
                        case 'd': /* additional */
733
723
                                FULLCHECK("additional");
812
802
                        FULLCHECK("defname");
813
803
                        usesearch = state;
814
804
                        break;
815
 
                case 'n': /* dnssec */  
 
805
                case 'n': /* dnssec */
816
806
                        FULLCHECK("dnssec");
 
807
                        if (state && lookup->edns == -1)
 
808
                                lookup->edns = 0;
817
809
                        lookup->dnssec = state;
818
810
                        break;
819
 
                case 'o': /* domain */  
 
811
                case 'o': /* domain */
820
812
                        FULLCHECK("domain");
821
813
                        if (value == NULL)
822
814
                                goto need_value;
829
821
                        goto invalid_option;
830
822
                }
831
823
                break;
 
824
        case 'e':
 
825
                FULLCHECK("edns");
 
826
                if (!state) {
 
827
                        lookup->edns = -1;
 
828
                        break;
 
829
                }
 
830
                if (value == NULL)
 
831
                        goto need_value;
 
832
                lookup->edns = (isc_int16_t) parse_uint(value, "edns", 255);
 
833
                break;
832
834
        case 'f': /* fail */
833
835
                FULLCHECK("fail");
834
836
                lookup->servfail_stops = state;
859
861
                                goto invalid_option;
860
862
                        ndots = parse_uint(value, "ndots", MAXNDOTS);
861
863
                        break;
862
 
                case 's': /* nssearch */
863
 
                        FULLCHECK("nssearch");
864
 
                        lookup->ns_search_only = state;
865
 
                        if (state) {
866
 
                                lookup->trace_root = ISC_TRUE;
867
 
                                lookup->recurse = ISC_TRUE;
868
 
                                lookup->identify = ISC_TRUE;
869
 
                                lookup->stats = ISC_FALSE;
870
 
                                lookup->comments = ISC_FALSE;
871
 
                                lookup->section_additional = ISC_FALSE;
872
 
                                lookup->section_authority = ISC_FALSE;
873
 
                                lookup->section_question = ISC_FALSE;
874
 
                                lookup->rdtype = dns_rdatatype_ns;
875
 
                                lookup->rdtypeset = ISC_TRUE;
876
 
                                short_form = ISC_TRUE;
 
864
                case 's':
 
865
                        switch (cmd[2]) {
 
866
                        case 'i': /* nsid */
 
867
                                FULLCHECK("nsid");
 
868
                                if (state && lookup->edns == -1)
 
869
                                        lookup->edns = 0;
 
870
                                lookup->nsid = state;
 
871
                                break;
 
872
                        case 's': /* nssearch */
 
873
                                FULLCHECK("nssearch");
 
874
                                lookup->ns_search_only = state;
 
875
                                if (state) {
 
876
                                        lookup->trace_root = ISC_TRUE;
 
877
                                        lookup->recurse = ISC_TRUE;
 
878
                                        lookup->identify = ISC_TRUE;
 
879
                                        lookup->stats = ISC_FALSE;
 
880
                                        lookup->comments = ISC_FALSE;
 
881
                                        lookup->section_additional = ISC_FALSE;
 
882
                                        lookup->section_authority = ISC_FALSE;
 
883
                                        lookup->section_question = ISC_FALSE;
 
884
                                        lookup->rdtype = dns_rdatatype_ns;
 
885
                                        lookup->rdtypeset = ISC_TRUE;
 
886
                                        short_form = ISC_TRUE;
 
887
                                }
 
888
                                break;
 
889
                        default:
 
890
                                goto invalid_option;
877
891
                        }
878
892
                        break;
879
893
                default:
880
894
                        goto invalid_option;
881
895
                }
882
896
                break;
883
 
        case 'q': 
 
897
        case 'q':
884
898
                switch (cmd[1]) {
885
899
                case 'r': /* qr */
886
900
                        FULLCHECK("qr");
928
942
                        FULLCHECK("search");
929
943
                        usesearch = state;
930
944
                        break;
931
 
                case 'h': /* short */
932
 
                        FULLCHECK("short");
933
 
                        short_form = state;
934
 
                        if (state) {
935
 
                                printcmd = ISC_FALSE;
936
 
                                lookup->section_additional = ISC_FALSE;
937
 
                                lookup->section_answer = ISC_TRUE;
938
 
                                lookup->section_authority = ISC_FALSE;
939
 
                                lookup->section_question = ISC_FALSE;
940
 
                                lookup->comments = ISC_FALSE;
941
 
                                lookup->stats = ISC_FALSE;
 
945
                case 'h':
 
946
                        if (cmd[2] != 'o')
 
947
                                goto invalid_option;
 
948
                        switch (cmd[3]) {
 
949
                        case 'r': /* short */
 
950
                                FULLCHECK("short");
 
951
                                short_form = state;
 
952
                                if (state) {
 
953
                                        printcmd = ISC_FALSE;
 
954
                                        lookup->section_additional = ISC_FALSE;
 
955
                                        lookup->section_answer = ISC_TRUE;
 
956
                                        lookup->section_authority = ISC_FALSE;
 
957
                                        lookup->section_question = ISC_FALSE;
 
958
                                        lookup->comments = ISC_FALSE;
 
959
                                        lookup->stats = ISC_FALSE;
 
960
                                }
 
961
                                break;
 
962
                        case 'w': /* showsearch */
 
963
                                FULLCHECK("showsearch");
 
964
                                showsearch = state;
 
965
                                usesearch = state;
 
966
                                break;
 
967
                        default:
 
968
                                goto invalid_option;
942
969
                        }
943
970
                        break;
944
971
#ifdef DIG_SIGCHASE
945
972
                case 'i': /* sigchase */
946
 
                        FULLCHECK("sigchase");
 
973
                        FULLCHECK("sigchase");
947
974
                        lookup->sigchase = state;
948
975
                        if (lookup->sigchase)
949
976
                                lookup->dnssec = ISC_TRUE;
950
 
                        break;  
 
977
                        break;
951
978
#endif
952
979
                case 't': /* stats */
953
980
                        FULLCHECK("stats");
975
1002
                                timeout = 1;
976
1003
                        break;
977
1004
#if DIG_SIGCHASE_TD
978
 
                case 'o': /* topdown */ 
 
1005
                case 'o': /* topdown */
979
1006
                        FULLCHECK("topdown");
980
1007
                        lookup->do_topdown = state;
981
1008
                        break;
1010
1037
#ifdef DIG_SIGCHASE
1011
1038
                        case 'u': /* trusted-key */
1012
1039
                                FULLCHECK("trusted-key");
1013
 
                                if (value == NULL) 
 
1040
                                if (value == NULL)
1014
1041
                                        goto need_value;
1015
1042
                                if (!state)
1016
1043
                                        goto invalid_option;
1047
1074
        return;
1048
1075
}
1049
1076
 
1050
 
/*
1051
 
 * ISC_TRUE returned if value was used
 
1077
/*%
 
1078
 * #ISC_TRUE returned if value was used
1052
1079
 */
1053
1080
static const char *single_dash_opts = "46dhimnv";
1054
1081
static const char *dash_opts = "46bcdfhikmnptvyx";
1055
1082
static isc_boolean_t
1056
1083
dash_option(char *option, char *next, dig_lookup_t **lookup,
1057
 
            isc_boolean_t *open_type_class)
 
1084
            isc_boolean_t *open_type_class, isc_boolean_t *need_clone,
 
1085
            isc_boolean_t config_only, int argc, char **argv,
 
1086
            isc_boolean_t *firstarg)
1058
1087
{
1059
 
        char opt, *value, *ptr;
 
1088
        char opt, *value, *ptr, *ptr2, *ptr3;
1060
1089
        isc_result_t result;
1061
1090
        isc_boolean_t value_from_next;
1062
1091
        isc_textregion_t tr;
1142
1171
                hash = strchr(value, '#');
1143
1172
                if (hash != NULL) {
1144
1173
                        srcport = (in_port_t)
1145
 
                                parse_uint(hash + 1,
 
1174
                                parse_uint(hash + 1,
1146
1175
                                           "port number", MAXPORT);
1147
1176
                        *hash = '\0';
1148
1177
                } else
1189
1218
        case 'p':
1190
1219
                port = (in_port_t) parse_uint(value, "port number", MAXPORT);
1191
1220
                return (value_from_next);
 
1221
        case 'q':
 
1222
                if (!config_only) {
 
1223
                        if (*need_clone)
 
1224
                                (*lookup) = clone_lookup(default_lookup,
 
1225
                                                         ISC_TRUE);
 
1226
                        *need_clone = ISC_TRUE;
 
1227
                        strncpy((*lookup)->textname, value,
 
1228
                                sizeof((*lookup)->textname));
 
1229
                        (*lookup)->textname[sizeof((*lookup)->textname)-1]=0;
 
1230
                        (*lookup)->trace_root = ISC_TF((*lookup)->trace  ||
 
1231
                                                     (*lookup)->ns_search_only);
 
1232
                        (*lookup)->new_search = ISC_TRUE;
 
1233
                        if (*firstarg) {
 
1234
                                printgreeting(argc, argv, *lookup);
 
1235
                                *firstarg = ISC_FALSE;
 
1236
                        }
 
1237
                        ISC_LIST_APPEND(lookup_list, (*lookup), link);
 
1238
                        debug("looking up %s", (*lookup)->textname);
 
1239
                }
 
1240
                return (value_from_next);
1192
1241
        case 't':
1193
1242
                *open_type_class = ISC_FALSE;
1194
1243
                if (strncasecmp(value, "ixfr=", 5) == 0) {
1214
1263
                                (*lookup)->rdtypeset = ISC_TRUE;
1215
1264
                                (*lookup)->ixfr_serial =
1216
1265
                                        parse_uint(&value[5], "serial number",
1217
 
                                                MAXSERIAL);
 
1266
                                                MAXSERIAL);
1218
1267
                                (*lookup)->section_question = plusquest;
1219
1268
                                (*lookup)->comments = pluscomm;
 
1269
                                (*lookup)->tcp_mode = ISC_TRUE;
1220
1270
                        } else {
1221
1271
                                (*lookup)->rdtype = rdtype;
1222
1272
                                (*lookup)->rdtypeset = ISC_TRUE;
1232
1282
                                 value);
1233
1283
                return (value_from_next);
1234
1284
        case 'y':
1235
 
                ptr = next_token(&value,":");
 
1285
                ptr = next_token(&value,":");   /* hmac type or name */
1236
1286
                if (ptr == NULL) {
1237
1287
                        usage();
1238
1288
                }
 
1289
                ptr2 = next_token(&value, ":"); /* name or secret */
 
1290
                if (ptr2 == NULL)
 
1291
                        usage();
 
1292
                ptr3 = next_token(&value,":"); /* secret or NULL */
 
1293
                if (ptr3 != NULL) {
 
1294
                        if (strcasecmp(ptr, "hmac-md5") == 0) {
 
1295
                                hmacname = DNS_TSIG_HMACMD5_NAME;
 
1296
                                digestbits = 0;
 
1297
                        } else if (strncasecmp(ptr, "hmac-md5-", 9) == 0) {
 
1298
                                hmacname = DNS_TSIG_HMACMD5_NAME;
 
1299
                                digestbits = parse_uint(&ptr[9],
 
1300
                                                        "digest-bits [0..128]",
 
1301
                                                        128);
 
1302
                                digestbits = (digestbits + 7) & ~0x7U;
 
1303
                        } else if (strcasecmp(ptr, "hmac-sha1") == 0) {
 
1304
                                hmacname = DNS_TSIG_HMACSHA1_NAME;
 
1305
                                digestbits = 0;
 
1306
                        } else if (strncasecmp(ptr, "hmac-sha1-", 10) == 0) {
 
1307
                                hmacname = DNS_TSIG_HMACSHA1_NAME;
 
1308
                                digestbits = parse_uint(&ptr[10],
 
1309
                                                        "digest-bits [0..160]",
 
1310
                                                        160);
 
1311
                                digestbits = (digestbits + 7) & ~0x7U;
 
1312
                        } else if (strcasecmp(ptr, "hmac-sha224") == 0) {
 
1313
                                hmacname = DNS_TSIG_HMACSHA224_NAME;
 
1314
                                digestbits = 0;
 
1315
                        } else if (strncasecmp(ptr, "hmac-sha224-", 12) == 0) {
 
1316
                                hmacname = DNS_TSIG_HMACSHA224_NAME;
 
1317
                                digestbits = parse_uint(&ptr[12],
 
1318
                                                        "digest-bits [0..224]",
 
1319
                                                        224);
 
1320
                                digestbits = (digestbits + 7) & ~0x7U;
 
1321
                        } else if (strcasecmp(ptr, "hmac-sha256") == 0) {
 
1322
                                hmacname = DNS_TSIG_HMACSHA256_NAME;
 
1323
                                digestbits = 0;
 
1324
                        } else if (strncasecmp(ptr, "hmac-sha256-", 12) == 0) {
 
1325
                                hmacname = DNS_TSIG_HMACSHA256_NAME;
 
1326
                                digestbits = parse_uint(&ptr[12],
 
1327
                                                        "digest-bits [0..256]",
 
1328
                                                        256);
 
1329
                                digestbits = (digestbits + 7) & ~0x7U;
 
1330
                        } else if (strcasecmp(ptr, "hmac-sha384") == 0) {
 
1331
                                hmacname = DNS_TSIG_HMACSHA384_NAME;
 
1332
                                digestbits = 0;
 
1333
                        } else if (strncasecmp(ptr, "hmac-sha384-", 12) == 0) {
 
1334
                                hmacname = DNS_TSIG_HMACSHA384_NAME;
 
1335
                                digestbits = parse_uint(&ptr[12],
 
1336
                                                        "digest-bits [0..384]",
 
1337
                                                        384);
 
1338
                                digestbits = (digestbits + 7) & ~0x7U;
 
1339
                        } else if (strcasecmp(ptr, "hmac-sha512") == 0) {
 
1340
                                hmacname = DNS_TSIG_HMACSHA512_NAME;
 
1341
                                digestbits = 0;
 
1342
                        } else if (strncasecmp(ptr, "hmac-sha512-", 12) == 0) {
 
1343
                                hmacname = DNS_TSIG_HMACSHA512_NAME;
 
1344
                                digestbits = parse_uint(&ptr[12],
 
1345
                                                        "digest-bits [0..512]",
 
1346
                                                        512);
 
1347
                                digestbits = (digestbits + 7) & ~0x7U;
 
1348
                        } else {
 
1349
                                fprintf(stderr, ";; Warning, ignoring "
 
1350
                                        "invalid TSIG algorithm %s\n", ptr);
 
1351
                                return (value_from_next);
 
1352
                        }
 
1353
                        ptr = ptr2;
 
1354
                        ptr2 = ptr3;
 
1355
                } else  {
 
1356
                        hmacname = DNS_TSIG_HMACMD5_NAME;
 
1357
                        digestbits = 0;
 
1358
                }
1239
1359
                strncpy(keynametext, ptr, sizeof(keynametext));
1240
1360
                keynametext[sizeof(keynametext)-1]=0;
1241
 
                ptr = next_token(&value, "");
1242
 
                if (ptr == NULL)
1243
 
                        usage();
1244
 
                strncpy(keysecret, ptr, sizeof(keysecret));
 
1361
                strncpy(keysecret, ptr2, sizeof(keysecret));
1245
1362
                keysecret[sizeof(keysecret)-1]=0;
1246
1363
                return (value_from_next);
1247
1364
        case 'x':
1248
 
                *lookup = clone_lookup(default_lookup, ISC_TRUE);
 
1365
                if (*need_clone)
 
1366
                        *lookup = clone_lookup(default_lookup, ISC_TRUE);
 
1367
                *need_clone = ISC_TRUE;
1249
1368
                if (get_reverse(textname, sizeof(textname), value,
1250
1369
                                ip6_int, ISC_FALSE) == ISC_R_SUCCESS) {
1251
1370
                        strncpy((*lookup)->textname, textname,
1259
1378
                        if (!(*lookup)->rdclassset)
1260
1379
                                (*lookup)->rdclass = dns_rdataclass_in;
1261
1380
                        (*lookup)->new_search = ISC_TRUE;
 
1381
                        if (*firstarg) {
 
1382
                                printgreeting(argc, argv, *lookup);
 
1383
                                *firstarg = ISC_FALSE;
 
1384
                        }
1262
1385
                        ISC_LIST_APPEND(lookup_list, *lookup, link);
1263
1386
                } else {
1264
1387
                        fprintf(stderr, "Invalid IP address %s\n", value);
1273
1396
        return (ISC_FALSE);
1274
1397
}
1275
1398
 
1276
 
/*
 
1399
/*%
1277
1400
 * Because we may be trying to do memory allocation recording, we're going
1278
1401
 * to need to parse the arguments for the -m *before* we start the main
1279
1402
 * argument parsing routine.
 
1403
 *
1280
1404
 * I'd prefer not to have to do this, but I am not quite sure how else to
1281
1405
 * fix the problem.  Argument parsing in dig involves memory allocation
1282
1406
 * by its nature, so it can't be done in the main argument parser.
1315
1439
        char tmp[ISC_NETADDR_FORMATSIZE];
1316
1440
 
1317
1441
        result = bind9_getaddresses(host, 0, sockaddrs,
1318
 
                                    DIG_MAX_ADDRESSES, &count);   
 
1442
                                    DIG_MAX_ADDRESSES, &count);
1319
1443
        if (result != ISC_R_SUCCESS)
1320
1444
        fatal("couldn't get address for '%s': %s",
1321
1445
              host, isc_result_totext(result));
1349
1473
        char rcfile[256];
1350
1474
#endif
1351
1475
        char *input;
 
1476
        int i;
 
1477
        isc_boolean_t need_clone = ISC_TRUE;
1352
1478
 
1353
1479
        /*
1354
1480
         * The semantics for parsing the args is a bit complex; if
1375
1501
                if (homedir != NULL) {
1376
1502
                        unsigned int n;
1377
1503
                        n = snprintf(rcfile, sizeof(rcfile), "%s/.digrc",
1378
 
                                     homedir);
 
1504
                                     homedir);
1379
1505
                        if (n < sizeof(rcfile))
1380
1506
                                batchfp = fopen(rcfile, "r");
1381
1507
                }
1396
1522
                                bargv[0] = argv[0];
1397
1523
                                argv0 = argv[0];
1398
1524
 
1399
 
                                reorder_args(bargc, (char **)bargv);
 
1525
                                for(i = 0; i < bargc; i++)
 
1526
                                        debug(".digrc argv %d: %s",
 
1527
                                              i, bargv[i]);
1400
1528
                                parse_args(ISC_TRUE, ISC_TRUE, bargc,
1401
1529
                                           (char **)bargv);
1402
1530
                        }
1405
1533
#endif
1406
1534
        }
1407
1535
 
1408
 
        lookup = default_lookup;
 
1536
        if (is_batchfile && !config_only) {
 
1537
                /* Processing '-f batchfile'. */
 
1538
                lookup = clone_lookup(default_lookup, ISC_TRUE);
 
1539
                need_clone = ISC_FALSE;
 
1540
        } else
 
1541
                lookup = default_lookup;
1409
1542
 
1410
1543
        rc = argc;
1411
1544
        rv = argv;
1421
1554
                } else if (rv[0][0] == '-') {
1422
1555
                        if (rc <= 1) {
1423
1556
                                if (dash_option(&rv[0][1], NULL,
1424
 
                                                &lookup, &open_type_class)) {
 
1557
                                                &lookup, &open_type_class,
 
1558
                                                &need_clone, config_only,
 
1559
                                                argc, argv, &firstarg)) {
1425
1560
                                        rc--;
1426
1561
                                        rv++;
1427
1562
                                }
1428
1563
                        } else {
1429
1564
                                if (dash_option(&rv[0][1], rv[1],
1430
 
                                                &lookup, &open_type_class)) {
 
1565
                                                &lookup, &open_type_class,
 
1566
                                                &need_clone, config_only,
 
1567
                                                argc, argv, &firstarg)) {
1431
1568
                                        rc--;
1432
1569
                                        rv++;
1433
1570
                                }
1437
1574
                         * Anything which isn't an option
1438
1575
                         */
1439
1576
                        if (open_type_class) {
1440
 
                                if (strncmp(rv[0], "ixfr=", 5) == 0) {
 
1577
                                if (strncasecmp(rv[0], "ixfr=", 5) == 0) {
1441
1578
                                        rdtype = dns_rdatatype_ixfr;
1442
1579
                                        result = ISC_R_SUCCESS;
1443
1580
                                } else {
1444
1581
                                        tr.base = rv[0];
1445
1582
                                        tr.length = strlen(rv[0]);
1446
1583
                                        result = dns_rdatatype_fromtext(&rdtype,
1447
 
                                                (isc_textregion_t *)&tr);
 
1584
                                                (isc_textregion_t *)&tr);
1448
1585
                                        if (result == ISC_R_SUCCESS &&
1449
1586
                                            rdtype == dns_rdatatype_ixfr) {
1450
1587
                                                result = DNS_R_UNKNOWN;
1465
1602
                                                lookup->rdtypeset = ISC_TRUE;
1466
1603
                                                lookup->ixfr_serial =
1467
1604
                                                        parse_uint(&rv[0][5],
1468
 
                                                                "serial number",
1469
 
                                                                MAXSERIAL);
 
1605
                                                                "serial number",
 
1606
                                                                MAXSERIAL);
1470
1607
                                                lookup->section_question =
1471
1608
                                                        plusquest;
1472
1609
                                                lookup->comments = pluscomm;
 
1610
                                                lookup->tcp_mode = ISC_TRUE;
1473
1611
                                        } else {
1474
1612
                                                lookup->rdtype = rdtype;
1475
1613
                                                lookup->rdtypeset = ISC_TRUE;
1495
1633
                                        continue;
1496
1634
                                }
1497
1635
                        }
 
1636
 
1498
1637
                        if (!config_only) {
1499
 
                                lookup = clone_lookup(default_lookup,
1500
 
                                                      ISC_TRUE);
1501
 
                                strncpy(lookup->textname, rv[0], 
 
1638
                                if (need_clone)
 
1639
                                        lookup = clone_lookup(default_lookup,
 
1640
                                                                      ISC_TRUE);
 
1641
                                need_clone = ISC_TRUE;
 
1642
                                strncpy(lookup->textname, rv[0],
1502
1643
                                        sizeof(lookup->textname));
1503
1644
                                lookup->textname[sizeof(lookup->textname)-1]=0;
1504
1645
                                lookup->trace_root = ISC_TF(lookup->trace  ||
1505
1646
                                                     lookup->ns_search_only);
1506
1647
                                lookup->new_search = ISC_TRUE;
 
1648
                                if (firstarg) {
 
1649
                                        printgreeting(argc, argv, lookup);
 
1650
                                        firstarg = ISC_FALSE;
 
1651
                                }
1507
1652
                                ISC_LIST_APPEND(lookup_list, lookup, link);
1508
1653
                                debug("looking up %s", lookup->textname);
1509
1654
                        }
1510
1655
                        /* XXX Error message */
1511
1656
                }
1512
1657
        }
 
1658
 
1513
1659
        /*
1514
1660
         * If we have a batchfile, seed the lookup list with the
1515
1661
         * first entry, then trust the callback in dighost_shutdown
1544
1690
                        bargv[0] = argv[0];
1545
1691
                        argv0 = argv[0];
1546
1692
 
1547
 
                        reorder_args(bargc, (char **)bargv);
 
1693
                        for(i = 0; i < bargc; i++)
 
1694
                                debug("batch argv %d: %s", i, bargv[i]);
1548
1695
                        parse_args(ISC_TRUE, ISC_FALSE, bargc, (char **)bargv);
 
1696
                        return;
1549
1697
                }
 
1698
                return;
1550
1699
        }
1551
1700
        /*
1552
1701
         * If no lookup specified, search for root
1553
1702
         */
1554
1703
        if ((lookup_list.head == NULL) && !config_only) {
1555
 
                lookup = clone_lookup(default_lookup, ISC_TRUE);
 
1704
                if (need_clone)
 
1705
                        lookup = clone_lookup(default_lookup, ISC_TRUE);
 
1706
                need_clone = ISC_TRUE;
1556
1707
                lookup->trace_root = ISC_TF(lookup->trace ||
1557
1708
                                            lookup->ns_search_only);
1558
1709
                lookup->new_search = ISC_TRUE;
1564
1715
                        firstarg = ISC_FALSE;
1565
1716
                }
1566
1717
                ISC_LIST_APPEND(lookup_list, lookup, link);
1567
 
        } else if (!config_only && firstarg) {
1568
 
                        printgreeting(argc, argv, lookup);
1569
 
                        firstarg = ISC_FALSE;
1570
1718
        }
 
1719
        if (!need_clone)
 
1720
                destroy_lookup(lookup);
1571
1721
}
1572
1722
 
1573
1723
/*
1581
1731
        int bargc;
1582
1732
        char *bargv[16];
1583
1733
        char *input;
1584
 
 
 
1734
        int i;
1585
1735
 
1586
1736
        if (batchname == NULL) {
1587
1737
                isc_app_shutdown();
1609
1759
 
1610
1760
                bargv[0] = argv0;
1611
1761
 
1612
 
                reorder_args(bargc, (char **)bargv);
 
1762
                for(i = 0; i < bargc; i++)
 
1763
                        debug("batch argv %d: %s", i, bargv[i]);
1613
1764
                parse_args(ISC_TRUE, ISC_FALSE, bargc, (char **)bargv);
1614
1765
                start_lookup();
1615
1766
        } else {
1621
1772
        }
1622
1773
}
1623
1774
 
 
1775
/*% Main processing routine for dig */
1624
1776
int
1625
1777
main(int argc, char **argv) {
1626
1778
        isc_result_t result;
1627
 
        dig_server_t *s, *s2;
1628
1779
 
1629
1780
        ISC_LIST_INIT(lookup_list);
1630
1781
        ISC_LIST_INIT(server_list);
1645
1796
        result = isc_app_onrun(mctx, global_task, onrun_callback, NULL);
1646
1797
        check_result(result, "isc_app_onrun");
1647
1798
        isc_app_run();
1648
 
        s = ISC_LIST_HEAD(default_lookup->my_server_list);
1649
 
        while (s != NULL) {
1650
 
                debug("freeing server %p belonging to %p",
1651
 
                      s, default_lookup);
1652
 
                s2 = s;
1653
 
                s = ISC_LIST_NEXT(s, link);
1654
 
                ISC_LIST_DEQUEUE(default_lookup->my_server_list, s2, link);
1655
 
                isc_mem_free(mctx, s2);
1656
 
        }
1657
 
        isc_mem_free(mctx, default_lookup);
 
1799
        destroy_lookup(default_lookup);
1658
1800
        if (batchname != NULL) {
1659
1801
                if (batchfp != stdin)
1660
1802
                        fclose(batchfp);