Annotation of 43BSD/lib/libc/net/res_comp.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1985 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #if defined(LIBC_SCCS) && !defined(lint)
                      8: static char sccsid[] = "@(#)res_comp.c 6.7 (Berkeley) 3/11/86";
                      9: #endif LIBC_SCCS and not lint
                     10: 
                     11: #include <sys/types.h>
                     12: #include <stdio.h>
                     13: #include <arpa/nameser.h>
                     14: 
                     15: 
                     16: /*
                     17:  * Expand compressed domain name 'comp_dn' to full domain name.
                     18:  * 'msg' is a pointer to the begining of the message,
                     19:  * 'eomorig' points to the first location after the message,
                     20:  * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
                     21:  * Return size of compressed name or -1 if there was an error.
                     22:  */
                     23: dn_expand(msg, eomorig, comp_dn, exp_dn, length)
                     24:        char *msg, *eomorig, *comp_dn, *exp_dn;
                     25:        int length;
                     26: {
                     27:        register char *cp, *dn;
                     28:        register int n, c;
                     29:        char *eom;
                     30:        int len = -1;
                     31: 
                     32:        dn = exp_dn;
                     33:        cp = comp_dn;
                     34:        eom = exp_dn + length - 1;
                     35:        /*
                     36:         * fetch next label in domain name
                     37:         */
                     38:        while (n = *cp++) {
                     39:                /*
                     40:                 * Check for indirection
                     41:                 */
                     42:                switch (n & INDIR_MASK) {
                     43:                case 0:
                     44:                        if (dn != exp_dn) {
                     45:                                if (dn >= eom)
                     46:                                        return (-1);
                     47:                                *dn++ = '.';
                     48:                        }
                     49:                        if (dn+n >= eom)
                     50:                                return (-1);
                     51:                        while (--n >= 0) {
                     52:                                if ((c = *cp++) == '.') {
                     53:                                        if (dn+n+1 >= eom)
                     54:                                                return (-1);
                     55:                                        *dn++ = '\\';
                     56:                                }
                     57:                                *dn++ = c;
                     58:                                if (cp >= eomorig)      /* out of range */
                     59:                                        return(-1);
                     60:                        }
                     61:                        break;
                     62: 
                     63:                case INDIR_MASK:
                     64:                        if (len < 0)
                     65:                                len = cp - comp_dn + 1;
                     66:                        cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
                     67:                        if (cp < msg || cp >= eomorig)  /* out of range */
                     68:                                return(-1);
                     69:                        break;
                     70: 
                     71:                default:
                     72:                        return (-1);                    /* flag error */
                     73:                }
                     74:        }
                     75:        *dn = '\0';
                     76:        if (len < 0)
                     77:                len = cp - comp_dn;
                     78:        return (len);
                     79: }
                     80: 
                     81: /*
                     82:  * Compress domain name 'exp_dn' into 'comp_dn'.
                     83:  * Return the size of the compressed name or -1.
                     84:  * 'length' is the size of the array pointed to by 'comp_dn'.
                     85:  * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
                     86:  * is a pointer to the beginning of the message. The list ends with NULL.
                     87:  * 'lastdnptr' is a pointer to the end of the arrary pointed to
                     88:  * by 'dnptrs'. Side effect is to update the list of pointers for
                     89:  * labels inserted into the message as we compress the name.
                     90:  * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
                     91:  * is NULL, we don't update the list.
                     92:  */
                     93: dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
                     94:        char *exp_dn, *comp_dn;
                     95:        int length;
                     96:        char **dnptrs, **lastdnptr;
                     97: {
                     98:        register char *cp, *dn;
                     99:        register int c, l;
                    100:        char **cpp, **lpp, *sp, *eob;
                    101:        char *msg;
                    102: 
                    103:        dn = exp_dn;
                    104:        cp = comp_dn;
                    105:        eob = cp + length;
                    106:        if (dnptrs != NULL) {
                    107:                if ((msg = *dnptrs++) != NULL) {
                    108:                        for (cpp = dnptrs; *cpp != NULL; cpp++)
                    109:                                ;
                    110:                        lpp = cpp;      /* end of list to search */
                    111:                }
                    112:        } else
                    113:                msg = NULL;
                    114:        for (c = *dn++; c != '\0'; ) {
                    115:                /* look to see if we can use pointers */
                    116:                if (msg != NULL) {
                    117:                        if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
                    118:                                if (cp+1 >= eob)
                    119:                                        return (-1);
                    120:                                *cp++ = (l >> 8) | INDIR_MASK;
                    121:                                *cp++ = l % 256;
                    122:                                return (cp - comp_dn);
                    123:                        }
                    124:                        /* not found, save it */
                    125:                        if (lastdnptr != NULL && cpp < lastdnptr-1) {
                    126:                                *cpp++ = cp;
                    127:                                *cpp = NULL;
                    128:                        }
                    129:                }
                    130:                sp = cp++;      /* save ptr to length byte */
                    131:                do {
                    132:                        if (c == '.') {
                    133:                                c = *dn++;
                    134:                                break;
                    135:                        }
                    136:                        if (c == '\\') {
                    137:                                if ((c = *dn++) == '\0')
                    138:                                        break;
                    139:                        }
                    140:                        if (cp >= eob)
                    141:                                return (-1);
                    142:                        *cp++ = c;
                    143:                } while ((c = *dn++) != '\0');
                    144:                /* catch trailing '.'s but not '..' */
                    145:                if ((l = cp - sp - 1) == 0 && c == '\0') {
                    146:                        cp--;
                    147:                        break;
                    148:                }
                    149:                if (l <= 0 || l > MAXLABEL)
                    150:                        return (-1);
                    151:                *sp = l;
                    152:        }
                    153:        if (cp >= eob)
                    154:                return (-1);
                    155:        *cp++ = '\0';
                    156:        return (cp - comp_dn);
                    157: }
                    158: 
                    159: /*
                    160:  * Skip over a compressed domain name. Return the size or -1.
                    161:  */
                    162: dn_skip(comp_dn)
                    163:        char *comp_dn;
                    164: {
                    165:        register char *cp;
                    166:        register int n;
                    167: 
                    168:        cp = comp_dn;
                    169:        while (n = *cp++) {
                    170:                /*
                    171:                 * check for indirection
                    172:                 */
                    173:                switch (n & INDIR_MASK) {
                    174:                case 0:         /* normal case, n == len */
                    175:                        cp += n;
                    176:                        continue;
                    177:                default:        /* illegal type */
                    178:                        return (-1);
                    179:                case INDIR_MASK:        /* indirection */
                    180:                        cp++;
                    181:                }
                    182:                break;
                    183:        }
                    184:        return (cp - comp_dn);
                    185: }
                    186: 
                    187: /*
                    188:  * Search for expanded name from a list of previously compressed names.
                    189:  * Return the offset from msg if found or -1.
                    190:  */
                    191: dn_find(exp_dn, msg, dnptrs, lastdnptr)
                    192:        char *exp_dn, *msg;
                    193:        char **dnptrs, **lastdnptr;
                    194: {
                    195:        register char *dn, *cp, **cpp;
                    196:        register int n;
                    197:        char *sp;
                    198: 
                    199:        for (cpp = dnptrs + 1; cpp < lastdnptr; cpp++) {
                    200:                dn = exp_dn;
                    201:                sp = cp = *cpp;
                    202:                while (n = *cp++) {
                    203:                        /*
                    204:                         * check for indirection
                    205:                         */
                    206:                        switch (n & INDIR_MASK) {
                    207:                        case 0:         /* normal case, n == len */
                    208:                                while (--n >= 0) {
                    209:                                        if (*dn == '\\')
                    210:                                                dn++;
                    211:                                        if (*dn++ != *cp++)
                    212:                                                goto next;
                    213:                                }
                    214:                                if ((n = *dn++) == '\0' && *cp == '\0')
                    215:                                        return (sp - msg);
                    216:                                if (n == '.')
                    217:                                        continue;
                    218:                                goto next;
                    219: 
                    220:                        default:        /* illegal type */
                    221:                                return (-1);
                    222: 
                    223:                        case INDIR_MASK:        /* indirection */
                    224:                                cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
                    225:                        }
                    226:                }
                    227:                if (*dn == '\0')
                    228:                        return (sp - msg);
                    229:        next:   ;
                    230:        }
                    231:        return (-1);
                    232: }
                    233: 
                    234: /*
                    235:  * Routines to insert/extract short/long's. Must account for byte
                    236:  * order and non-alignment problems. This code at least has the
                    237:  * advantage of being portable.
                    238:  */
                    239: 
                    240: u_short
                    241: getshort(msgp)
                    242:        char *msgp;
                    243: {
                    244:        register u_char *p = (u_char *) msgp;
                    245: #ifdef vax
                    246:        /*
                    247:         * vax compiler doesn't put shorts in registers
                    248:         */
                    249:        register u_long u;
                    250: #else
                    251:        register u_short u;
                    252: #endif
                    253: 
                    254:        u = *p++ << 8;
                    255:        return ((u_short)(u | *p));
                    256: }
                    257: 
                    258: u_long
                    259: getlong(msgp)
                    260:        char *msgp;
                    261: {
                    262:        register u_char *p = (u_char *) msgp;
                    263:        register u_long u;
                    264: 
                    265:        u = *p++; u <<= 8;
                    266:        u |= *p++; u <<= 8;
                    267:        u |= *p++; u <<= 8;
                    268:        return (u | *p);
                    269: }
                    270: 
                    271: 
                    272: putshort(s, msgp)
                    273:        register u_short s;
                    274:        register char *msgp;
                    275: {
                    276: 
                    277:        msgp[1] = s;
                    278:        msgp[0] = s >> 8;
                    279: }
                    280: 
                    281: putlong(l, msgp)
                    282:        register u_long l;
                    283:        register char *msgp;
                    284: {
                    285: 
                    286:        msgp[3] = l;
                    287:        msgp[2] = (l >>= 8);
                    288:        msgp[1] = (l >>= 8);
                    289:        msgp[0] = l >> 8;
                    290: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.