OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-newlib/] [newlib-1.17.0/] [newlib/] [libc/] [sys/] [linux/] [net/] [ns_print.c] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 jlechner
/*
2
 * Copyright (c) 1996-1999 by Internet Software Consortium.
3
 *
4
 * Permission to use, copy, modify, and distribute this software for any
5
 * purpose with or without fee is hereby granted, provided that the above
6
 * copyright notice and this permission notice appear in all copies.
7
 *
8
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
9
 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
10
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
11
 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
13
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
14
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15
 * SOFTWARE.
16
 */
17
 
18
#if !defined(_LIBC) && !defined(lint)
19
static const char rcsid[] = "$BINDId: ns_print.c,v 8.18 2000/02/29 05:48:12 vixie Exp $";
20
#endif
21
 
22
/* Import. */
23
 
24
#include <sys/types.h>
25
#include <sys/socket.h>
26
 
27
#include <netinet/in.h>
28
#include <arpa/nameser.h>
29
#include <arpa/inet.h>
30
 
31
#include <assert.h>
32
#include <errno.h>
33
#include <resolv.h>
34
#include <string.h>
35
#include <ctype.h>
36
 
37
#include "libc-symbols.h"
38
 
39
#ifdef SPRINTF_CHAR
40
# define SPRINTF(x) strlen(sprintf/**/x)
41
#else
42
# define SPRINTF(x) ((size_t)sprintf x)
43
#endif
44
 
45
/* Forward. */
46
 
47
static size_t   prune_origin(const char *name, const char *origin);
48
static int      charstr(const u_char *rdata, const u_char *edata,
49
                        char **buf, size_t *buflen);
50
static int      addname(const u_char *msg, size_t msglen,
51
                        const u_char **p, const char *origin,
52
                        char **buf, size_t *buflen);
53
static void     addlen(size_t len, char **buf, size_t *buflen);
54
static int      addstr(const char *src, size_t len,
55
                       char **buf, size_t *buflen);
56
static int      addtab(size_t len, size_t target, int spaced,
57
                       char **buf, size_t *buflen);
58
 
59
/* Proto. */
60
 
61
#ifndef _LIBC
62
u_int16_t       dst_s_dns_key_id(const u_char *, const int);
63
#endif
64
 
65
/* Macros. */
66
 
67
#define T(x) \
68
        do { \
69
                if ((x) < 0) \
70
                        return (-1); \
71
        } while (0)
72
 
73
/* Public. */
74
 
75
/*
76
 * int
77
 * ns_sprintrr(handle, rr, name_ctx, origin, buf, buflen)
78
 *      Convert an RR to presentation format.
79
 * return:
80
 *      Number of characters written to buf, or -1 (check errno).
81
 */
82
int
83
ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
84
            const char *name_ctx, const char *origin,
85
            char *buf, size_t buflen)
86
{
87
        int n;
88
 
89
        n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
90
                         ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
91
                         ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
92
                         name_ctx, origin, buf, buflen);
93
        return (n);
94
}
95
 
96
/*
97
 * int
98
 * ns_sprintrrf(msg, msglen, name, class, type, ttl, rdata, rdlen,
99
 *             name_ctx, origin, buf, buflen)
100
 *      Convert the fields of an RR into presentation format.
101
 * return:
102
 *      Number of characters written to buf, or -1 (check errno).
103
 */
104
int
105
ns_sprintrrf(const u_char *msg, size_t msglen,
106
            const char *name, ns_class class, ns_type type,
107
            u_long ttl, const u_char *rdata, size_t rdlen,
108
            const char *name_ctx, const char *origin,
109
            char *buf, size_t buflen)
110
{
111
        const char *obuf = buf;
112
        const u_char *edata = rdata + rdlen;
113
        int spaced = 0;
114
 
115
        const char *comment;
116
        char tmp[100];
117
        int len, x;
118
 
119
        /*
120
         * Owner.
121
         */
122
        if (name_ctx != NULL && ns_samename(name_ctx, name) == 1) {
123
                T(addstr("\t\t\t", 3, &buf, &buflen));
124
        } else {
125
                len = prune_origin(name, origin);
126
                if (len == 0) {
127
                        T(addstr("@\t\t\t", 4, &buf, &buflen));
128
                } else {
129
                        T(addstr(name, len, &buf, &buflen));
130
                        /* Origin not used or not root, and no trailing dot? */
131
                        if (((origin == NULL || origin[0] == '\0') ||
132
                            (origin[0] != '.' && origin[1] != '\0' &&
133
                            name[len] == '\0')) && name[len - 1] != '.') {
134
                                T(addstr(".", 1, &buf, &buflen));
135
                                len++;
136
                        }
137
                        T(spaced = addtab(len, 24, spaced, &buf, &buflen));
138
                }
139
        }
140
 
141
        /*
142
         * TTL, Class, Type.
143
         */
144
        T(x = ns_format_ttl(ttl, buf, buflen));
145
        addlen(x, &buf, &buflen);
146
        len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
147
        T(addstr(tmp, len, &buf, &buflen));
148
        T(spaced = addtab(x + len, 16, spaced, &buf, &buflen));
149
 
150
        /*
151
         * RData.
152
         */
153
        switch (type) {
154
        case ns_t_a:
155
                if (rdlen != NS_INADDRSZ)
156
                        goto formerr;
157
                (void) inet_ntop(AF_INET, rdata, buf, buflen);
158
                addlen(strlen(buf), &buf, &buflen);
159
                break;
160
 
161
        case ns_t_cname:
162
        case ns_t_mb:
163
        case ns_t_mg:
164
        case ns_t_mr:
165
        case ns_t_ns:
166
        case ns_t_ptr:
167
                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
168
                break;
169
 
170
        case ns_t_hinfo:
171
        case ns_t_isdn:
172
                /* First word. */
173
                T(len = charstr(rdata, edata, &buf, &buflen));
174
                if (len == 0)
175
                        goto formerr;
176
                rdata += len;
177
                T(addstr(" ", 1, &buf, &buflen));
178
 
179
 
180
                /* Second word, optional in ISDN records. */
181
                if (type == ns_t_isdn && rdata == edata)
182
                        break;
183
 
184
                T(len = charstr(rdata, edata, &buf, &buflen));
185
                if (len == 0)
186
                        goto formerr;
187
                rdata += len;
188
                break;
189
 
190
        case ns_t_soa: {
191
                u_long t;
192
 
193
                /* Server name. */
194
                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
195
                T(addstr(" ", 1, &buf, &buflen));
196
 
197
                /* Administrator name. */
198
                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
199
                T(addstr(" (\n", 3, &buf, &buflen));
200
                spaced = 0;
201
 
202
                if ((edata - rdata) != 5*NS_INT32SZ)
203
                        goto formerr;
204
 
205
                /* Serial number. */
206
                t = ns_get32(rdata);  rdata += NS_INT32SZ;
207
                T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
208
                len = SPRINTF((tmp, "%lu", t));
209
                T(addstr(tmp, len, &buf, &buflen));
210
                T(spaced = addtab(len, 16, spaced, &buf, &buflen));
211
                T(addstr("; serial\n", 9, &buf, &buflen));
212
                spaced = 0;
213
 
214
                /* Refresh interval. */
215
                t = ns_get32(rdata);  rdata += NS_INT32SZ;
216
                T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
217
                T(len = ns_format_ttl(t, buf, buflen));
218
                addlen(len, &buf, &buflen);
219
                T(spaced = addtab(len, 16, spaced, &buf, &buflen));
220
                T(addstr("; refresh\n", 10, &buf, &buflen));
221
                spaced = 0;
222
 
223
                /* Retry interval. */
224
                t = ns_get32(rdata);  rdata += NS_INT32SZ;
225
                T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
226
                T(len = ns_format_ttl(t, buf, buflen));
227
                addlen(len, &buf, &buflen);
228
                T(spaced = addtab(len, 16, spaced, &buf, &buflen));
229
                T(addstr("; retry\n", 8, &buf, &buflen));
230
                spaced = 0;
231
 
232
                /* Expiry. */
233
                t = ns_get32(rdata);  rdata += NS_INT32SZ;
234
                T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
235
                T(len = ns_format_ttl(t, buf, buflen));
236
                addlen(len, &buf, &buflen);
237
                T(spaced = addtab(len, 16, spaced, &buf, &buflen));
238
                T(addstr("; expiry\n", 9, &buf, &buflen));
239
                spaced = 0;
240
 
241
                /* Minimum TTL. */
242
                t = ns_get32(rdata);  rdata += NS_INT32SZ;
243
                T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
244
                T(len = ns_format_ttl(t, buf, buflen));
245
                addlen(len, &buf, &buflen);
246
                T(addstr(" )", 2, &buf, &buflen));
247
                T(spaced = addtab(len, 16, spaced, &buf, &buflen));
248
                T(addstr("; minimum\n", 10, &buf, &buflen));
249
 
250
                break;
251
            }
252
 
253
        case ns_t_mx:
254
        case ns_t_afsdb:
255
        case ns_t_rt: {
256
                u_int t;
257
 
258
                if (rdlen < NS_INT16SZ)
259
                        goto formerr;
260
 
261
                /* Priority. */
262
                t = ns_get16(rdata);
263
                rdata += NS_INT16SZ;
264
                len = SPRINTF((tmp, "%u ", t));
265
                T(addstr(tmp, len, &buf, &buflen));
266
 
267
                /* Target. */
268
                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
269
 
270
                break;
271
            }
272
 
273
        case ns_t_px: {
274
                u_int t;
275
 
276
                if (rdlen < NS_INT16SZ)
277
                        goto formerr;
278
 
279
                /* Priority. */
280
                t = ns_get16(rdata);
281
                rdata += NS_INT16SZ;
282
                len = SPRINTF((tmp, "%u ", t));
283
                T(addstr(tmp, len, &buf, &buflen));
284
 
285
                /* Name1. */
286
                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
287
                T(addstr(" ", 1, &buf, &buflen));
288
 
289
                /* Name2. */
290
                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
291
 
292
                break;
293
            }
294
 
295
        case ns_t_x25:
296
                T(len = charstr(rdata, edata, &buf, &buflen));
297
                if (len == 0)
298
                        goto formerr;
299
                rdata += len;
300
                break;
301
 
302
        case ns_t_txt:
303
                while (rdata < edata) {
304
                        T(len = charstr(rdata, edata, &buf, &buflen));
305
                        if (len == 0)
306
                                goto formerr;
307
                        rdata += len;
308
                        if (rdata < edata)
309
                                T(addstr(" ", 1, &buf, &buflen));
310
                }
311
                break;
312
 
313
        case ns_t_nsap: {
314
                /* 2*255 for hex digits, 128 for '.' and '\0', 2 for
315
                   0x if inet_nsap_ntoa starts using it.  */
316
                char t[255*2 + 128 + 2];
317
 
318
                (void) inet_nsap_ntoa(rdlen, rdata, t);
319
                T(addstr(t, strlen(t), &buf, &buflen));
320
                break;
321
            }
322
 
323
        case ns_t_aaaa:
324
                if (rdlen != NS_IN6ADDRSZ)
325
                        goto formerr;
326
                (void) inet_ntop(AF_INET6, rdata, buf, buflen);
327
                addlen(strlen(buf), &buf, &buflen);
328
                break;
329
 
330
        case ns_t_loc: {
331
                char t[255];
332
 
333
                /* XXX protocol format checking? */
334
                (void) loc_ntoa(rdata, t);
335
                T(addstr(t, strlen(t), &buf, &buflen));
336
                break;
337
            }
338
 
339
        case ns_t_naptr: {
340
                u_int order, preference;
341
                char t[50];
342
 
343
                if (rdlen < 2*NS_INT16SZ)
344
                        goto formerr;
345
 
346
                /* Order, Precedence. */
347
                order = ns_get16(rdata);        rdata += NS_INT16SZ;
348
                preference = ns_get16(rdata);   rdata += NS_INT16SZ;
349
                len = SPRINTF((t, "%u %u ", order, preference));
350
                T(addstr(t, len, &buf, &buflen));
351
 
352
                /* Flags. */
353
                T(len = charstr(rdata, edata, &buf, &buflen));
354
                if (len == 0)
355
                        goto formerr;
356
                rdata += len;
357
                T(addstr(" ", 1, &buf, &buflen));
358
 
359
                /* Service. */
360
                T(len = charstr(rdata, edata, &buf, &buflen));
361
                if (len == 0)
362
                        goto formerr;
363
                rdata += len;
364
                T(addstr(" ", 1, &buf, &buflen));
365
 
366
                /* Regexp. */
367
                T(len = charstr(rdata, edata, &buf, &buflen));
368
                if (len < 0)
369
                        return (-1);
370
                if (len == 0)
371
                        goto formerr;
372
                rdata += len;
373
                T(addstr(" ", 1, &buf, &buflen));
374
 
375
                /* Server. */
376
                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
377
                break;
378
            }
379
 
380
        case ns_t_srv: {
381
                u_int priority, weight, port;
382
                char t[50];
383
 
384
                if (rdlen < NS_INT16SZ*3)
385
                        goto formerr;
386
 
387
                /* Priority, Weight, Port. */
388
                priority = ns_get16(rdata);  rdata += NS_INT16SZ;
389
                weight   = ns_get16(rdata);  rdata += NS_INT16SZ;
390
                port     = ns_get16(rdata);  rdata += NS_INT16SZ;
391
                len = SPRINTF((t, "%u %u %u ", priority, weight, port));
392
                T(addstr(t, len, &buf, &buflen));
393
 
394
                /* Server. */
395
                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
396
                break;
397
            }
398
 
399
        case ns_t_minfo:
400
        case ns_t_rp:
401
                /* Name1. */
402
                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
403
                T(addstr(" ", 1, &buf, &buflen));
404
 
405
                /* Name2. */
406
                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
407
 
408
                break;
409
 
410
        case ns_t_wks: {
411
                int n, lcnt;
412
 
413
                if (rdlen < NS_INT32SZ + 1)
414
                        goto formerr;
415
 
416
                /* Address. */
417
                (void) inet_ntop(AF_INET, rdata, buf, buflen);
418
                addlen(strlen(buf), &buf, &buflen);
419
                rdata += NS_INADDRSZ;
420
 
421
                /* Protocol. */
422
                len = SPRINTF((tmp, " %u ( ", *rdata));
423
                T(addstr(tmp, len, &buf, &buflen));
424
                rdata += NS_INT8SZ;
425
 
426
                /* Bit map. */
427
                n = 0;
428
                lcnt = 0;
429
                while (rdata < edata) {
430
                        u_int c = *rdata++;
431
                        do {
432
                                if (c & 0200) {
433
                                        if (lcnt == 0) {
434
                                                T(addstr("\n\t\t\t\t", 5,
435
                                                         &buf, &buflen));
436
                                                lcnt = 10;
437
                                                spaced = 0;
438
                                        }
439
                                        len = SPRINTF((tmp, "%d ", n));
440
                                        T(addstr(tmp, len, &buf, &buflen));
441
                                        lcnt--;
442
                                }
443
                                c <<= 1;
444
                        } while (++n & 07);
445
                }
446
                T(addstr(")", 1, &buf, &buflen));
447
 
448
                break;
449
            }
450
 
451
        case ns_t_key: {
452
#ifndef _LIBC
453
                char base64_key[NS_MD5RSA_MAX_BASE64];
454
                u_int keyflags, protocol, algorithm, key_id;
455
                const char *leader;
456
                int n;
457
 
458
                if (rdlen < NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
459
                        goto formerr;
460
 
461
                /* Key flags, Protocol, Algorithm. */
462
                key_id = dst_s_dns_key_id(rdata, edata-rdata);
463
                keyflags = ns_get16(rdata);  rdata += NS_INT16SZ;
464
                protocol = *rdata++;
465
                algorithm = *rdata++;
466
                len = SPRINTF((tmp, "0x%04x %u %u",
467
                               keyflags, protocol, algorithm));
468
                T(addstr(tmp, len, &buf, &buflen));
469
 
470
                /* Public key data. */
471
                len = b64_ntop(rdata, edata - rdata,
472
                               base64_key, sizeof base64_key);
473
                if (len < 0)
474
                        goto formerr;
475
                if (len > 15) {
476
                        T(addstr(" (", 2, &buf, &buflen));
477
                        leader = "\n\t\t";
478
                        spaced = 0;
479
                } else
480
                        leader = " ";
481
                for (n = 0; n < len; n += 48) {
482
                        T(addstr(leader, strlen(leader), &buf, &buflen));
483
                        T(addstr(base64_key + n, MIN(len - n, 48),
484
                                 &buf, &buflen));
485
                }
486
                if (len > 15)
487
                        T(addstr(" )", 2, &buf, &buflen));
488
                n = SPRINTF((tmp, " ; key_tag= %u", key_id));
489
                T(addstr(tmp, n, &buf, &buflen));
490
#endif /* !_LIBC */
491
 
492
                break;
493
            }
494
 
495
        case ns_t_sig: {
496
#ifndef _LIBC
497
                char base64_key[NS_MD5RSA_MAX_BASE64];
498
                u_int type, algorithm, labels, footprint;
499
                const char *leader;
500
                u_long t;
501
                int n;
502
 
503
                if (rdlen < 22)
504
                        goto formerr;
505
 
506
                /* Type covered, Algorithm, Label count, Original TTL. */
507
                type = ns_get16(rdata);  rdata += NS_INT16SZ;
508
                algorithm = *rdata++;
509
                labels = *rdata++;
510
                t = ns_get32(rdata);  rdata += NS_INT32SZ;
511
                len = SPRINTF((tmp, "%s %d %d %lu ",
512
                               p_type(type), algorithm, labels, t));
513
                T(addstr(tmp, len, &buf, &buflen));
514
                if (labels > (u_int)dn_count_labels(name))
515
                        goto formerr;
516
 
517
                /* Signature expiry. */
518
                t = ns_get32(rdata);  rdata += NS_INT32SZ;
519
                len = SPRINTF((tmp, "%s ", p_secstodate(t)));
520
                T(addstr(tmp, len, &buf, &buflen));
521
 
522
                /* Time signed. */
523
                t = ns_get32(rdata);  rdata += NS_INT32SZ;
524
                len = SPRINTF((tmp, "%s ", p_secstodate(t)));
525
                T(addstr(tmp, len, &buf, &buflen));
526
 
527
                /* Signature Footprint. */
528
                footprint = ns_get16(rdata);  rdata += NS_INT16SZ;
529
                len = SPRINTF((tmp, "%u ", footprint));
530
                T(addstr(tmp, len, &buf, &buflen));
531
 
532
                /* Signer's name. */
533
                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
534
 
535
                /* Signature. */
536
                len = b64_ntop(rdata, edata - rdata,
537
                               base64_key, sizeof base64_key);
538
                if (len > 15) {
539
                        T(addstr(" (", 2, &buf, &buflen));
540
                        leader = "\n\t\t";
541
                        spaced = 0;
542
                } else
543
                        leader = " ";
544
                if (len < 0)
545
                        goto formerr;
546
                for (n = 0; n < len; n += 48) {
547
                        T(addstr(leader, strlen(leader), &buf, &buflen));
548
                        T(addstr(base64_key + n, MIN(len - n, 48),
549
                                 &buf, &buflen));
550
                }
551
                if (len > 15)
552
                        T(addstr(" )", 2, &buf, &buflen));
553
#endif /* !_LIBC */
554
                break;
555
            }
556
 
557
        case ns_t_nxt: {
558
                int n, c;
559
 
560
                /* Next domain name. */
561
                T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
562
 
563
                /* Type bit map. */
564
                n = edata - rdata;
565
                for (c = 0; c < n*8; c++)
566
                        if (NS_NXT_BIT_ISSET(c, rdata)) {
567
                                len = SPRINTF((tmp, " %s", p_type(c)));
568
                                T(addstr(tmp, len, &buf, &buflen));
569
                        }
570
                break;
571
            }
572
 
573
        case ns_t_cert: {
574
                u_int c_type, key_tag, alg;
575
                int n, siz;
576
                char base64_cert[8192], *leader, tmp[40];
577
 
578
                c_type  = ns_get16(rdata); rdata += NS_INT16SZ;
579
                key_tag = ns_get16(rdata); rdata += NS_INT16SZ;
580
                alg = (u_int) *rdata++;
581
 
582
                len = SPRINTF((tmp, "%d %d %d ", c_type, key_tag, alg));
583
                T(addstr(tmp, len, &buf, &buflen));
584
                siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
585
                if (siz > sizeof(base64_cert) * 3/4) {
586
                        char *str = "record too long to print";
587
                        T(addstr(str, strlen(str), &buf, &buflen));
588
                }
589
                else {
590
                        len = b64_ntop(rdata, edata-rdata, base64_cert, siz);
591
 
592
                        if (len < 0)
593
                                goto formerr;
594
                        else if (len > 15) {
595
                                T(addstr(" (", 2, &buf, &buflen));
596
                                leader = "\n\t\t";
597
                                spaced = 0;
598
                        }
599
                        else
600
                                leader = " ";
601
 
602
                        for (n = 0; n < len; n += 48) {
603
                                T(addstr(leader, strlen(leader),
604
                                         &buf, &buflen));
605
                                T(addstr(base64_cert + n, MIN(len - n, 48),
606
                                         &buf, &buflen));
607
                        }
608
                        if (len > 15)
609
                                T(addstr(" )", 2, &buf, &buflen));
610
                }
611
                break;
612
            }
613
 
614
        case ns_t_tsig: {
615
                /* BEW - need to complete this */
616
                int n;
617
 
618
                T(len = addname(msg, msglen, &rdata, origin, &buf, &buflen));
619
                T(addstr(" ", 1, &buf, &buflen));
620
                rdata += 8; /* time */
621
                n = ns_get16(rdata); rdata += INT16SZ;
622
                rdata += n; /* sig */
623
                n = ns_get16(rdata); rdata += INT16SZ; /* original id */
624
                sprintf(buf, "%d", ns_get16(rdata));
625
                rdata += INT16SZ;
626
                addlen(strlen(buf), &buf, &buflen);
627
                break;
628
            }
629
 
630
        default:
631
                comment = "unknown RR type";
632
                goto hexify;
633
        }
634
        return (buf - obuf);
635
 formerr:
636
        comment = "RR format error";
637
 hexify: {
638
        int n, m;
639
        char *p;
640
 
641
        len = SPRINTF((tmp, "\\#(\t\t; %s", comment));
642
        T(addstr(tmp, len, &buf, &buflen));
643
        while (rdata < edata) {
644
                p = tmp;
645
                p += SPRINTF((p, "\n\t"));
646
                spaced = 0;
647
                n = MIN(16, edata - rdata);
648
                for (m = 0; m < n; m++)
649
                        p += SPRINTF((p, "%02x ", rdata[m]));
650
                T(addstr(tmp, p - tmp, &buf, &buflen));
651
                if (n < 16) {
652
                        T(addstr(")", 1, &buf, &buflen));
653
                        T(addtab(p - tmp + 1, 48, spaced, &buf, &buflen));
654
                }
655
                p = tmp;
656
                p += SPRINTF((p, "; "));
657
                for (m = 0; m < n; m++)
658
                        *p++ = (isascii(rdata[m]) && isprint(rdata[m]))
659
                                ? rdata[m]
660
                                : '.';
661
                T(addstr(tmp, p - tmp, &buf, &buflen));
662
                rdata += n;
663
        }
664
        return (buf - obuf);
665
    }
666
}
667
 
668
/* Private. */
669
 
670
/*
671
 * size_t
672
 * prune_origin(name, origin)
673
 *      Find out if the name is at or under the current origin.
674
 * return:
675
 *      Number of characters in name before start of origin,
676
 *      or length of name if origin does not match.
677
 * notes:
678
 *      This function should share code with samedomain().
679
 */
680
static size_t
681
prune_origin(const char *name, const char *origin) {
682
        const char *oname = name;
683
 
684
        while (*name != '\0') {
685
                if (origin != NULL && ns_samename(name, origin) == 1)
686
                        return (name - oname - (name > oname));
687
                while (*name != '\0') {
688
                        if (*name == '\\') {
689
                                name++;
690
                                /* XXX need to handle \nnn form. */
691
                                if (*name == '\0')
692
                                        break;
693
                        } else if (*name == '.') {
694
                                name++;
695
                                break;
696
                        }
697
                        name++;
698
                }
699
        }
700
        return (name - oname);
701
}
702
 
703
/*
704
 * int
705
 * charstr(rdata, edata, buf, buflen)
706
 *      Format a <character-string> into the presentation buffer.
707
 * return:
708
 *      Number of rdata octets consumed
709
 *      0 for protocol format error
710
 *      -1 for output buffer error
711
 * side effects:
712
 *      buffer is advanced on success.
713
 */
714
static int
715
charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {
716
        const u_char *odata = rdata;
717
        size_t save_buflen = *buflen;
718
        char *save_buf = *buf;
719
 
720
        if (addstr("\"", 1, buf, buflen) < 0)
721
                goto enospc;
722
        if (rdata < edata) {
723
                int n = *rdata;
724
 
725
                if (rdata + 1 + n <= edata) {
726
                        rdata++;
727
                        while (n-- > 0) {
728
                                if (strchr("\n\"\\", *rdata) != NULL)
729
                                        if (addstr("\\", 1, buf, buflen) < 0)
730
                                                goto enospc;
731
                                if (addstr((const char *)rdata, 1,
732
                                           buf, buflen) < 0)
733
                                        goto enospc;
734
                                rdata++;
735
                        }
736
                }
737
        }
738
        if (addstr("\"", 1, buf, buflen) < 0)
739
                goto enospc;
740
        return (rdata - odata);
741
 enospc:
742
        __set_errno (ENOSPC);
743
        *buf = save_buf;
744
        *buflen = save_buflen;
745
        return (-1);
746
}
747
 
748
static int
749
addname(const u_char *msg, size_t msglen,
750
        const u_char **pp, const char *origin,
751
        char **buf, size_t *buflen)
752
{
753
        size_t newlen, save_buflen = *buflen;
754
        char *save_buf = *buf;
755
        int n;
756
 
757
        n = dn_expand(msg, msg + msglen, *pp, *buf, *buflen);
758
        if (n < 0)
759
                goto enospc;    /* Guess. */
760
        newlen = prune_origin(*buf, origin);
761
        if (newlen == 0) {
762
                /* Use "@" instead of name. */
763
                if (newlen + 2 > *buflen)
764
                        goto enospc;        /* No room for "@\0". */
765
                (*buf)[newlen++] = '@';
766
                (*buf)[newlen] = '\0';
767
        } else {
768
                if (((origin == NULL || origin[0] == '\0') ||
769
                    (origin[0] != '.' && origin[1] != '\0' &&
770
                    (*buf)[newlen] == '\0')) && (*buf)[newlen - 1] != '.') {
771
                        /* No trailing dot. */
772
                        if (newlen + 2 > *buflen)
773
                                goto enospc;    /* No room for ".\0". */
774
                        (*buf)[newlen++] = '.';
775
                        (*buf)[newlen] = '\0';
776
                }
777
        }
778
        *pp += n;
779
        addlen(newlen, buf, buflen);
780
        **buf = '\0';
781
        return (newlen);
782
 enospc:
783
        __set_errno (ENOSPC);
784
        *buf = save_buf;
785
        *buflen = save_buflen;
786
        return (-1);
787
}
788
 
789
static void
790
addlen(size_t len, char **buf, size_t *buflen) {
791
        assert(len <= *buflen);
792
        *buf += len;
793
        *buflen -= len;
794
}
795
 
796
static int
797
addstr(const char *src, size_t len, char **buf, size_t *buflen) {
798
        if (len >= *buflen) {
799
                __set_errno (ENOSPC);
800
                return (-1);
801
        }
802
        memcpy(*buf, src, len);
803
        addlen(len, buf, buflen);
804
        **buf = '\0';
805
        return (0);
806
}
807
 
808
static int
809
addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {
810
        size_t save_buflen = *buflen;
811
        char *save_buf = *buf;
812
        int t;
813
 
814
        if (spaced || len >= target - 1) {
815
                T(addstr("  ", 2, buf, buflen));
816
                spaced = 1;
817
        } else {
818
                for (t = (target - len - 1) / 8; t >= 0; t--)
819
                        if (addstr("\t", 1, buf, buflen) < 0) {
820
                                *buflen = save_buflen;
821
                                *buf = save_buf;
822
                                return (-1);
823
                        }
824
                spaced = 0;
825
        }
826
        return (spaced);
827
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.