static char sccsid
[] = "@(#)res_comp.c 4.1 (Berkeley) %G%";
* Expand compressed domain name format to full domain name.
* Return size of compressed name or -1 if there was an error.
dn_expand(msg
, comp_dn
, exp_dn
, length
)
char *msg
, *comp_dn
, *exp_dn
;
eom
= exp_dn
+ length
- 1;
* fetch next label in domain name
switch (n
& INDIR_MASK
) {
cp
= msg
+ (((n
& 0x3f) << 8) | (*cp
& 0xff));
return (-1); /* flag error */
* Compress domain name. Return the size of the compressed name or -1.
* 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.
dn_comp(exp_dn
, comp_dn
, length
, dnptrs
, lastdnptr
)
char **dnptrs
, **lastdnptr
;
char **cpp
, **lpp
, *sp
, *eob
;
if ((msg
= *dnptrs
++) != NULL
) {
for (cpp
= dnptrs
; *cpp
!= NULL
; cpp
++)
lpp
= cpp
; /* end of list to search */
for (c
= *dn
++; c
!= '\0'; ) {
/* look to see if we can use pointers */
if ((l
= dn_find(dn
-1, msg
, dnptrs
, lpp
)) >= 0) {
*cp
++ = (l
>> 8) | INDIR_MASK
;
if (lastdnptr
!= NULL
&& cpp
< lastdnptr
-1) {
sp
= cp
++; /* save ptr to length byte */
} while ((c
= *dn
++) != '\0');
if ((l
= cp
- sp
- 1) <= 0 || l
> MAXLABEL
)
* Skip over a compressed domain name. Return the size.
switch (n
& INDIR_MASK
) {
case 0: /* normal case, n == len */
default: /* illegal type */
case INDIR_MASK
: /* indirection */
* Search for expanded name from a list of previously compressed names.
* Return the offset from msg if found or -1.
dn_find(exp_dn
, msg
, dnptrs
, lastdnptr
)
char **dnptrs
, **lastdnptr
;
register char *dn
, *cp
, **cpp
;
for (cpp
= dnptrs
; cpp
< lastdnptr
; cpp
++) {
switch (n
& INDIR_MASK
) {
case 0: /* normal case, n == len */
if ((n
= *dn
++) == '\0' && *cp
== '\0')
default: /* illegal type */
case INDIR_MASK
: /* indirection */
cp
= msg
+ (((n
& 0x3f) << 8) | (*cp
& 0xff));