X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/fbc82d3e4f7a1f432b7e147a0c4c706fe67da49e..9a89481fdded6ba5b0d60a1389dbd3e3e4200799:/usr/src/lib/libc/net/res_comp.c diff --git a/usr/src/lib/libc/net/res_comp.c b/usr/src/lib/libc/net/res_comp.c index 1084210c43..c1a0d9c35b 100644 --- a/usr/src/lib/libc/net/res_comp.c +++ b/usr/src/lib/libc/net/res_comp.c @@ -1,15 +1,24 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + #ifndef lint -static char sccsid[] = "@(#)res_comp.c 4.1 (Berkeley) %G%"; -#endif +static char sccsid[] = "@(#)res_comp.c 5.3 (Berkeley) %G%"; +#endif not lint #include #include #include -#include +#include /* - * Expand compressed domain name format to full domain name. + * Expand compressed domain name 'comp_dn' to full domain name. + * Expanded names are converted to upper case. + * 'msg' is a pointer to the begining of the message, + * 'exp_dn' is a pointer to a buffer of size 'length' for the result. * Return size of compressed name or -1 if there was an error. */ dn_expand(msg, comp_dn, exp_dn, length) @@ -19,7 +28,7 @@ dn_expand(msg, comp_dn, exp_dn, length) register char *cp, *dn; register int n, c; char *eom; - int len = 0; + int len = -1; dn = exp_dn; cp = comp_dn; @@ -33,19 +42,28 @@ dn_expand(msg, comp_dn, exp_dn, length) */ switch (n & INDIR_MASK) { case 0: - if (dn != exp_dn) + if (dn != exp_dn) { + if (dn >= eom) + return (-1); *dn++ = '.'; + } if (dn+n >= eom) return (-1); while (--n >= 0) if (islower(c = *cp++)) *dn++ = toupper(c); - else + else { + if (c == '.') { + if (dn+n+1 >= eom) + return (-1); + *dn++ = '\\'; + } *dn++ = c; + } break; case INDIR_MASK: - if (len == 0) + if (len < 0) len = cp - comp_dn + 1; cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff)); break; @@ -55,15 +73,22 @@ dn_expand(msg, comp_dn, exp_dn, length) } } *dn = '\0'; - if (len == 0) + if (len < 0) len = cp - comp_dn; return (len); } /* - * Compress domain name. Return the size of the compressed name or -1. - * Dnptrs is a list of pointers to previous compressed names. dnptrs[0] + * Compress domain name 'exp_dn' into 'comp_dn'. + * Return the size of the compressed name or -1. + * 'length' is the size of the array pointed to by 'comp_dn'. + * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0] * is a pointer to the beginning of the message. The list ends with NULL. + * 'lastdnptr' is a pointer to the end of the arrary pointed to + * by 'dnptrs'. Side effect is to update the list of pointers for + * labels inserted into the message as we compress the name. + * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' + * is NULL, we don't update the list. */ dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) char *exp_dn, *comp_dn; @@ -108,11 +133,20 @@ dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) c = *dn++; break; } + if (c == '\\') { + if ((c = *dn++) == '\0') + break; + } if (cp >= eob) return (-1); *cp++ = c; } while ((c = *dn++) != '\0'); - if ((l = cp - sp - 1) <= 0 || l > MAXLABEL) + /* catch trailing '.'s but not '..' */ + if ((l = cp - sp - 1) == 0 && c == '\0') { + cp--; + break; + } + if (l <= 0 || l > MAXLABEL) return (-1); *sp = l; } @@ -123,15 +157,15 @@ dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) } /* - * Skip over a compressed domain name. Return the size. + * Skip over a compressed domain name. Return the size or -1. */ -dn_skip(buf) - char *buf; +dn_skip(comp_dn) + char *comp_dn; { register char *cp; register int n; - cp = buf; + cp = comp_dn; while (n = *cp++) { /* * check for indirection @@ -147,7 +181,7 @@ dn_skip(buf) } break; } - return (cp - buf); + return (cp - comp_dn); } /* @@ -171,9 +205,12 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr) */ switch (n & INDIR_MASK) { case 0: /* normal case, n == len */ - while (--n >= 0) + while (--n >= 0) { + if (*dn == '\\') + dn++; if (*dn++ != *cp++) goto next; + } if ((n = *dn++) == '\0' && *cp == '\0') return (sp - msg); if (n == '.') @@ -193,3 +230,52 @@ dn_find(exp_dn, msg, dnptrs, lastdnptr) } return (-1); } + +/* + * Routines to insert/extract short/long's. Must account for byte + * order and non-alignment problems. This code at least has the + * advantage of being portable. + */ + +u_short +getshort(msgp) + char *msgp; +{ + register u_char *p = (u_char *) msgp; + + return ((*p++ << 8) | *p); +} + +u_long +getlong(msgp) + char *msgp; +{ + register u_char *p = (u_char *) msgp; + register u_long u; + + u = *p++; u <<= 8; + u |= *p++; u <<= 8; + u |= *p++; u <<= 8; + return (u | *p); +} + + +putshort(s, msgp) + register u_short s; + register char *msgp; +{ + + msgp[1] = s; + msgp[0] = s >> 8; +} + +putlong(l, msgp) + register u_long l; + register char *msgp; +{ + + msgp[3] = l; + msgp[2] = (l >>= 8); + msgp[1] = (l >>= 8); + msgp[0] = l >> 8; +}