Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/networking/udhcp/domain_codec.c

    r1765 r2725  
    55 * Loosely based on the isc-dhcpd implementation by dhankins@isc.org
    66 *
    7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    8  */
    9 
    10 #if ENABLE_FEATURE_RFC3397
    11 
    12 #include "common.h"
    13 #include "options.h"
     7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
     8 */
     9#ifdef DNS_COMPR_TESTING
     10# define FAST_FUNC /* nothing */
     11# define xmalloc malloc
     12# include <stdlib.h>
     13# include <stdint.h>
     14# include <string.h>
     15# include <stdio.h>
     16#else
     17# include "common.h"
     18#endif
    1419
    1520#define NS_MAXDNAME  1025   /* max domain name length */
     
    2025
    2126
    22 /* expand a RFC1035-compressed list of domain names "cstr", of length "clen";
     27/* Expand a RFC1035-compressed list of domain names "cstr", of length "clen";
    2328 * returns a newly allocated string containing the space-separated domains,
    2429 * prefixed with the contents of string pre, or NULL if an error occurs.
    2530 */
    26 char *dname_dec(const uint8_t *cstr, int clen, const char *pre)
    27 {
    28     const uint8_t *c;
    29     int crtpos, retpos, depth, plen = 0, len = 0;
     31char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre)
     32{
     33    char *ret = ret; /* for compiler */
    3034    char *dst = NULL;
    31 
    32     if (!cstr)
    33         return NULL;
    34 
    35     if (pre)
    36         plen = strlen(pre);
    3735
    3836    /* We make two passes over the cstr string. First, we compute
     
    4341     * buffer, then having to check if it's sufficiently large, etc.
    4442     */
    45 
    46     while (!dst) {
    47 
    48         if (len > 0) {  /* second pass? allocate dst buffer and copy pre */
    49             dst = xmalloc(len + plen);
    50             memcpy(dst, pre, plen);
    51         }
     43    while (1) {
     44        /* note: "return NULL" below are leak-safe since
     45         * dst isn't yet allocated */
     46        const uint8_t *c;
     47        unsigned crtpos, retpos, depth, len;
    5248
    5349        crtpos = retpos = depth = len = 0;
    54 
    5550        while (crtpos < clen) {
    5651            c = cstr + crtpos;
    5752
    58             if ((*c & NS_CMPRSFLGS) != 0) { /* pointer */
    59                 if (crtpos + 2 > clen)      /* no offset to jump to? abort */
     53            if ((*c & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
     54                /* pointer */
     55                if (crtpos + 2 > clen) /* no offset to jump to? abort */
    6056                    return NULL;
    61                 if (retpos == 0)            /* toplevel? save return spot */
     57                if (retpos == 0) /* toplevel? save return spot */
    6258                    retpos = crtpos + 2;
    6359                depth++;
    64                 crtpos = ((*c & 0x3f) << 8) | (*(c + 1) & 0xff); /* jump */
    65             } else if (*c) {            /* label */
    66                 if (crtpos + *c + 1 > clen)     /* label too long? abort */
     60                crtpos = ((c[0] & 0x3f) << 8) | c[1]; /* jump */
     61            } else if (*c) {
     62                /* label */
     63                if (crtpos + *c + 1 > clen) /* label too long? abort */
    6764                    return NULL;
    6865                if (dst)
    69                     memcpy(dst + plen + len, c + 1, *c);
     66                    memcpy(dst + len, c + 1, *c);
    7067                len += *c + 1;
    7168                crtpos += *c + 1;
    7269                if (dst)
    73                     *(dst + plen + len - 1) = '.';
    74             } else {                    /* null: end of current domain name */
    75                 if (retpos == 0) {          /* toplevel? keep going */
     70                    dst[len - 1] = '.';
     71            } else {
     72                /* NUL: end of current domain name */
     73                if (retpos == 0) {
     74                    /* toplevel? keep going */
    7675                    crtpos++;
    77                 } else {                    /* return to toplevel saved spot */
     76                } else {
     77                    /* return to toplevel saved spot */
    7878                    crtpos = retpos;
    7979                    retpos = depth = 0;
    8080                }
    8181                if (dst)
    82                     *(dst + plen + len - 1) = ' ';
    83             }
    84 
    85             if (depth > NS_MAXDNSRCH || /* too many jumps? abort, it's a loop */
    86                 len > NS_MAXDNAME * NS_MAXDNSRCH) /* result too long? abort */
     82                    dst[len - 1] = ' ';
     83            }
     84
     85            if (depth > NS_MAXDNSRCH /* too many jumps? abort, it's a loop */
     86             || len > NS_MAXDNAME * NS_MAXDNSRCH /* result too long? abort */
     87            ) {
    8788                return NULL;
    88         }
    89 
    90         if (!len)           /* expanded string has 0 length? abort */
     89            }
     90        }
     91
     92        if (!len) /* expanded string has 0 length? abort */
    9193            return NULL;
    9294
    93         if (dst)
    94             *(dst + plen + len - 1) = '\0';
    95     }
    96 
    97     return dst;
     95        if (!dst) { /* first pass? */
     96            /* allocate dst buffer and copy pre */
     97            unsigned plen = strlen(pre);
     98            ret = dst = xmalloc(plen + len);
     99            memcpy(dst, pre, plen);
     100            dst += plen;
     101        } else {
     102            dst[len - 1] = '\0';
     103            break;
     104        }
     105    }
     106
     107    return ret;
    98108}
    99109
     
    104114static uint8_t *convert_dname(const char *src)
    105115{
    106     uint8_t c, *res, *lp, *rp;
     116    uint8_t c, *res, *lenptr, *dst;
    107117    int len;
    108118
    109119    res = xmalloc(strlen(src) + 2);
    110     rp = lp = res;
    111     rp++;
     120    dst = lenptr = res;
     121    dst++;
    112122
    113123    for (;;) {
    114124        c = (uint8_t)*src++;
    115         if (c == '.' || c == '\0') {    /* end of label */
    116             len = rp - lp - 1;
     125        if (c == '.' || c == '\0') {  /* end of label */
     126            len = dst - lenptr - 1;
    117127            /* label too long, too short, or two '.'s in a row? abort */
    118128            if (len > NS_MAXLABEL || len == 0 || (c == '.' && *src == '.')) {
     
    120130                return NULL;
    121131            }
    122             *lp = len;
    123             lp = rp++;
    124             if (c == '\0' || *src == '\0')  /* end of dname */
     132            *lenptr = len;
     133            if (c == '\0' || *src == '\0')  /* "" or ".": end of src */
    125134                break;
    126         } else {
    127             if (c >= 0x41 && c <= 0x5A)     /* uppercase? convert to lower */
    128                 c += 0x20;
    129             *rp++ = c;
    130         }
    131     }
    132 
    133     *lp = 0;
    134     if (rp - res > NS_MAXCDNAME) {  /* dname too long? abort */
     135            lenptr = dst++;
     136            continue;
     137        }
     138        if (c >= 'A' && c <= 'Z')  /* uppercase? convert to lower */
     139            c += ('a' - 'A');
     140        *dst++ = c;
     141    }
     142
     143    if (dst - res >= NS_MAXCDNAME) {  /* dname too long? abort */
    135144        free(res);
    136145        return NULL;
    137146    }
     147
     148    *dst = 0;
    138149    return res;
    139150}
    140151
    141 /* returns the offset within cstr at which dname can be found, or -1
    142  */
     152/* Returns the offset within cstr at which dname can be found, or -1 */
    143153static int find_offset(const uint8_t *cstr, int clen, const uint8_t *dname)
    144154{
    145155    const uint8_t *c, *d;
    146     int off, inc;
     156    int off;
    147157
    148158    /* find all labels in cstr */
     
    151161        c = cstr + off;
    152162
    153         if ((*c & NS_CMPRSFLGS) != 0) { /* pointer, skip */
     163        if ((*c & NS_CMPRSFLGS) == NS_CMPRSFLGS) {  /* pointer, skip */
    154164            off += 2;
    155         } else if (*c) {    /* label, try matching dname */
    156             inc = *c + 1;
     165            continue;
     166        }
     167        if (*c) {  /* label, try matching dname */
    157168            d = dname;
    158             while (*c == *d && memcmp(c + 1, d + 1, *c) == 0) {
    159                 if (*c == 0)    /* match, return offset */
     169            while (1) {
     170                unsigned len1 = *c + 1;
     171                if (memcmp(c, d, len1) != 0)
     172                    break;
     173                if (len1 == 1)  /* at terminating NUL - match, return offset */
    160174                    return off;
    161                 d += *c + 1;
    162                 c += *c + 1;
    163                 if ((*c & NS_CMPRSFLGS) != 0)   /* pointer, jump */
    164                     c = cstr + (((*c & 0x3f) << 8) | (*(c + 1) & 0xff));
    165             }
    166             off += inc;
    167         } else {    /* null, skip */
    168             off++;
    169         }
     175                d += len1;
     176                c += len1;
     177                if ((*c & NS_CMPRSFLGS) == NS_CMPRSFLGS)  /* pointer, jump */
     178                    c = cstr + (((c[0] & 0x3f) << 8) | c[1]);
     179            }
     180            off += cstr[off] + 1;
     181            continue;
     182        }
     183        /* NUL, skip */
     184        off++;
    170185    }
    171186
     
    173188}
    174189
    175 /* computes string to be appended to cstr so that src would be added to
     190/* Computes string to be appended to cstr so that src would be added to
    176191 * the compression (best case, it's a 2-byte pointer to some offset within
    177  * cstr; worst case, it's all of src, converted to rfc3011 format).
     192 * cstr; worst case, it's all of src, converted to <4>host<3>com<0> format).
    178193 * The computed string is returned directly; its length is returned via retlen;
    179194 * NULL and 0, respectively, are returned if an error occurs.
    180195 */
    181 uint8_t *dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen)
     196uint8_t* FAST_FUNC dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen)
    182197{
    183198    uint8_t *d, *dname;
     
    190205    }
    191206
    192     for (d = dname; *d != 0; d += *d + 1) {
    193         off = find_offset(cstr, clen, d);
    194         if (off >= 0) { /* found a match, add pointer and terminate string */
    195             *d++ = NS_CMPRSFLGS;
    196             *d = off;
    197             break;
    198         }
     207    d = dname;
     208    while (*d) {
     209        if (cstr) {
     210            off = find_offset(cstr, clen, d);
     211            if (off >= 0) { /* found a match, add pointer and return */
     212                *d++ = NS_CMPRSFLGS | (off >> 8);
     213                *d = off;
     214                break;
     215            }
     216        }
     217        d += *d + 1;
    199218    }
    200219
     
    203222}
    204223
    205 #endif /* ENABLE_FEATURE_RFC3397 */
     224#ifdef DNS_COMPR_TESTING
     225/* gcc -Wall -DDNS_COMPR_TESTING domain_codec.c -o domain_codec && ./domain_codec */
     226int main(int argc, char **argv)
     227{
     228    int len;
     229    uint8_t *encoded;
     230
     231#define DNAME_DEC(encoded,pre) dname_dec((uint8_t*)(encoded), sizeof(encoded), (pre))
     232    printf("'%s'\n",       DNAME_DEC("\4host\3com\0", "test1:"));
     233    printf("test2:'%s'\n", DNAME_DEC("\4host\3com\0\4host\3com\0", ""));
     234    printf("test3:'%s'\n", DNAME_DEC("\4host\3com\0\xC0\0", ""));
     235    printf("test4:'%s'\n", DNAME_DEC("\4host\3com\0\xC0\5", ""));
     236    printf("test5:'%s'\n", DNAME_DEC("\4host\3com\0\xC0\5\1z\xC0\xA", ""));
     237
     238#define DNAME_ENC(cache,source,lenp) dname_enc((uint8_t*)(cache), sizeof(cache), (source), (lenp))
     239    encoded = dname_enc(NULL, 0, "test.net", &len);
     240    printf("test6:'%s' len:%d\n", dname_dec(encoded, len, ""), len);
     241    encoded = DNAME_ENC("\3net\0", "test.net", &len);
     242    printf("test7:'%s' len:%d\n", dname_dec(encoded, len, ""), len);
     243    encoded = DNAME_ENC("\4test\3net\0", "test.net", &len);
     244    printf("test8:'%s' len:%d\n", dname_dec(encoded, len, ""), len);
     245    return 0;
     246}
     247#endif
Note: See TracChangeset for help on using the changeset viewer.