# 2.11BSD#431 - /usr/src/lib/libc/net/res_comp.c

##### Functions

    _getlong          X
    _getshort         X
    dn_comp           X
    dn_expand         X
    dn_skipname       X
    putlong           X
    putshort          X

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

#### Defined functions

_getlong defined in line 278; used 35 times

- in /usr/include/arpa/nameser.h line 212
- in /usr/src/include/arpa/nameser.h line 212
- in /usr/src/lib/libc/net/res_debug.c line 208, 269-277(5), 303
- in /usr/src/usr.sbin/named/named/ns_req.c line 1230
- in /usr/src/usr.sbin/named/named/ns_sort.c line 179, 225-233(5), 250, 256
- in /usr/src/usr.sbin/named/tools/nslookup/debug.c line 235, 329-340(5), 380
- in /usr/src/usr.sbin/named/tools/nslookup/list.c line 577, 673, 725
- in /usr/src/usr.sbin/named/tools/nslookup/res_debug.c line 207, 265-273(5), 315

_getshort defined in line 260; used 31 times

- in /usr/include/arpa/nameser.h line 211
- in /usr/src/include/arpa/nameser.h line 211
- in /usr/src/lib/libc/net/named/gethnamadr.c line 123-127(3)
- in /usr/src/lib/libc/net/res_debug.c line 124-126(2), 204-210(3), 282
- in /usr/src/usr.sbin/named/named/ns_sort.c line 237
- in /usr/src/usr.sbin/named/tools/nslookup/debug.c line 125-127(2), 231-237(3), 297
- in /usr/src/usr.sbin/named/tools/nslookup/getinfo.c line 81
- in /usr/src/usr.sbin/named/tools/nslookup/list.c line 435, 568, 575-579(2), 681
- in /usr/src/usr.sbin/named/tools/nslookup/res_debug.c line 127-129(2), 203-209(3), 278
- in /usr/src/usr.sbin/named/tools/nslookup/skip.c line 167

dn_comp defined in line 108; used 11 times

- in /usr/src/lib/libc/net/res_mkquery.c line 88, 103, 156, 179
- in /usr/src/usr.sbin/named/named/ns_req.c line 453, 698, 712, 722, 734, 740, 764

dn_expand defined in line 29; used 33 times

- in /usr/src/lib/libc/net/named/gethnamadr.c line 91, 120, 140
- in /usr/src/lib/libc/net/res_debug.c line 178
- in /usr/src/usr.sbin/named/named/ns_maint.c line 391, 406
- in /usr/src/usr.sbin/named/named/ns_req.c line 126, 1059
- in /usr/src/usr.sbin/named/named/ns_resp.c line 468, 739, 778, 790, 800, 822, 942, 1073
- in /usr/src/usr.sbin/named/tools/nslookup/debug.c line 183
- in /usr/src/usr.sbin/named/tools/nslookup/getinfo.c line 200, 227, 349, 367, 421
- in /usr/src/usr.sbin/named/tools/nslookup/list.c line 436, 564, 626, 657, 664, 685
- in /usr/src/usr.sbin/named/tools/nslookup/res_debug.c line 179
- in /usr/src/usr.sbin/sendmail.MX/src/domain.c line 83, 99, 201, 219

dn_find defined in line 208; used 1 times

- in line 132

dn_skipname defined in line 177; used 24 times

- in /usr/src/lib/libc/net/named/gethnamadr.c line 102-104(2)
- in /usr/src/usr.sbin/named/named/ns_init.c line 407-408(2)
- in /usr/src/usr.sbin/named/named/ns_maint.c line 256-257(2), 373-375(2), 395-396(2)
- in /usr/src/usr.sbin/named/named/ns_req.c line 386
- in /usr/src/usr.sbin/named/named/ns_resp.c line 264, 301, 467, 477
- in /usr/src/usr.sbin/named/named/ns_sort.c line 95
- in /usr/src/usr.sbin/named/tools/nslookup/getinfo.c line 174
- in /usr/src/usr.sbin/named/tools/nslookup/list.c line 432-434(2), 559
- in /usr/src/usr.sbin/named/tools/nslookup/skip.c line 93, 159
- in /usr/src/usr.sbin/sendmail.MX/src/domain.c line 75, 192

putlong defined in line 301; used 7 times

- in /usr/src/lib/libc/net/res_mkquery.c line 111, 129, 163, 186
- in /usr/src/usr.sbin/named/named/ns_req.c line 1181
- in /usr/src/usr.sbin/named/tools/nstest.c line 112, 241

putshort defined in line 292; used 14 times

- in /usr/src/lib/libc/net/res_mkquery.c line 92-94(2), 107-113(3), 125-131(3), 159-165(3), 182-188(3)

#### Defined variables

sccsid defined in line 14; never used

Last modified: 1988-09-17 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 957 |