source: packages/net/mtr/patches/501-dns.patch @ 22280

Last change on this file since 22280 was 22280, checked in by swalker, 6 years ago

[packages] mtr: update to 0.80

  • Property svn:eol-style set to native
File size: 18.1 KB
  • dns.c

    a b void restell(char *s) 
    880880  fputs("\r",stderr); 
    881881} 
    882882 
     883#ifdef __UCLIBC__ 
     884 
     885static const char       digits[] = "0123456789"; 
     886#define __set_errno(e) (errno = (e)) 
     887 
     888#define NS_PUT16(s, cp) do { \ 
     889        register u_int16_t t_s = (u_int16_t)(s); \ 
     890        register u_char *t_cp = (u_char *)(cp); \ 
     891        *t_cp++ = t_s >> 8; \ 
     892        *t_cp   = t_s; \ 
     893        (cp) += NS_INT16SZ; \ 
     894} while (0) 
     895 
     896 
     897 
     898#define NS_PUT32(l, cp) do { \ 
     899        register u_int32_t t_l = (u_int32_t)(l); \ 
     900        register u_char *t_cp = (u_char *)(cp); \ 
     901        *t_cp++ = t_l >> 24; \ 
     902        *t_cp++ = t_l >> 16; \ 
     903        *t_cp++ = t_l >> 8; \ 
     904        *t_cp   = t_l; \ 
     905        (cp) += NS_INT32SZ; \ 
     906} while (0) 
     907 
     908 
     909void 
     910ns_put16(u_int src, u_char *dst) { 
     911        NS_PUT16(src, dst); 
     912} 
     913 
     914void 
     915ns_put32(u_long src, u_char *dst) { 
     916        NS_PUT32(src, dst); 
     917} 
     918 
     919void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); } 
     920void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); } 
     921 
     922int 
     923mklower(int ch) { 
     924        if (ch >= 0x41 && ch <= 0x5A) 
     925                return (ch + 0x20); 
     926        return (ch); 
     927} 
     928 
     929 
     930static int 
     931dn_find(const u_char *domain, const u_char *msg, 
     932        const u_char * const *dnptrs, 
     933        const u_char * const *lastdnptr) 
     934{ 
     935        const u_char *dn, *cp, *sp; 
     936        const u_char * const *cpp; 
     937        u_int n; 
     938 
     939        for (cpp = dnptrs; cpp < lastdnptr; cpp++) { 
     940                sp = *cpp; 
     941                /* 
     942                 * terminate search on: 
     943                 * root label 
     944                 * compression pointer 
     945                 * unusable offset 
     946                 */ 
     947                while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 && 
     948                       (sp - msg) < 0x4000) { 
     949                        dn = domain; 
     950                        cp = sp; 
     951                        while ((n = *cp++) != 0) { 
     952                                /* 
     953                                 * check for indirection 
     954                                 */ 
     955                                switch (n & NS_CMPRSFLGS) { 
     956                                case 0:         /* normal case, n == len */ 
     957                                        if (n != *dn++) 
     958                                                goto next; 
     959                                        for ((void)NULL; n > 0; n--) 
     960                                                if (mklower(*dn++) != 
     961                                                    mklower(*cp++)) 
     962                                                        goto next; 
     963                                        /* Is next root for both ? */ 
     964                                        if (*dn == '\0' && *cp == '\0') 
     965                                                return (sp - msg); 
     966                                        if (*dn) 
     967                                                continue; 
     968                                        goto next; 
     969 
     970                                case NS_CMPRSFLGS:      /* indirection */ 
     971                                        cp = msg + (((n & 0x3f) << 8) | *cp); 
     972                                        break; 
     973 
     974                                default:        /* illegal type */ 
     975                                        __set_errno (EMSGSIZE); 
     976                                        return (-1); 
     977                                } 
     978                        } 
     979 next: 
     980                        sp += *sp + 1; 
     981                } 
     982        } 
     983        __set_errno (ENOENT); 
     984        return (-1); 
     985} 
     986 
     987 
     988int 
     989ns_name_pack(const u_char *src, u_char *dst, int dstsiz, 
     990             const u_char **dnptrs, const u_char **lastdnptr) 
     991{ 
     992        u_char *dstp; 
     993        const u_char **cpp, **lpp, *eob, *msg; 
     994        const u_char *srcp; 
     995        int n, l, first = 1; 
     996 
     997        srcp = src; 
     998        dstp = dst; 
     999        eob = dstp + dstsiz; 
     1000        lpp = cpp = NULL; 
     1001        if (dnptrs != NULL) { 
     1002                if ((msg = *dnptrs++) != NULL) { 
     1003                        for (cpp = dnptrs; *cpp != NULL; cpp++) 
     1004                                (void)NULL; 
     1005                        lpp = cpp;      /* end of list to search */ 
     1006                } 
     1007        } else 
     1008                msg = NULL; 
     1009 
     1010        /* make sure the domain we are about to add is legal */ 
     1011        l = 0; 
     1012        do { 
     1013                n = *srcp; 
     1014                if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) { 
     1015                        __set_errno (EMSGSIZE); 
     1016                        return (-1); 
     1017                } 
     1018                if (n == 0x41) 
     1019                        n = *++srcp / 8; 
     1020                l += n + 1; 
     1021                if (l > MAXCDNAME) { 
     1022                        __set_errno (EMSGSIZE); 
     1023                        return (-1); 
     1024                } 
     1025                srcp += n + 1; 
     1026        } while (n != 0); 
     1027 
     1028        /* from here on we need to reset compression pointer array on error */ 
     1029        srcp = src; 
     1030        do { 
     1031                /* Look to see if we can use pointers. */ 
     1032                n = *srcp; 
     1033                if (n != 0 && n != 0x41 && msg != NULL) { 
     1034                        l = dn_find(srcp, msg, (const u_char * const *)dnptrs, 
     1035                                    (const u_char * const *)lpp); 
     1036                        if (l >= 0) { 
     1037                                if (dstp + 1 >= eob) { 
     1038                                        goto cleanup; 
     1039                                } 
     1040                                *dstp++ = (l >> 8) | NS_CMPRSFLGS; 
     1041                                *dstp++ = l % 256; 
     1042                                return (dstp - dst); 
     1043                        } 
     1044                        /* Not found, save it. */ 
     1045                        if (lastdnptr != NULL && cpp < lastdnptr - 1 && 
     1046                            (dstp - msg) < 0x4000 && first) { 
     1047                                *cpp++ = dstp; 
     1048                                *cpp = NULL; 
     1049                                first = 0; 
     1050                        } 
     1051                } 
     1052                /* copy label to buffer */ 
     1053                if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) {             /* Should not happen. */ 
     1054                        goto cleanup; 
     1055                } 
     1056                if (n == 0x41) { 
     1057                        n = *++srcp / 8; 
     1058                        if (dstp + 1 >= eob) 
     1059                                goto cleanup; 
     1060                        *dstp++ = 0x41; 
     1061                } 
     1062                if (dstp + 1 + n >= eob) { 
     1063                        goto cleanup; 
     1064                } 
     1065                memcpy(dstp, srcp, n + 1); 
     1066                srcp += n + 1; 
     1067                dstp += n + 1; 
     1068        } while (n != 0); 
     1069 
     1070        if (dstp > eob) { 
     1071cleanup: 
     1072                if (msg != NULL) 
     1073                        *lpp = NULL; 
     1074                __set_errno (EMSGSIZE); 
     1075                return (-1); 
     1076        } 
     1077        return (dstp - dst); 
     1078} 
     1079 
     1080 
     1081int 
     1082ns_name_pton(const char *src, u_char *dst, size_t dstsiz) { 
     1083        u_char *label, *bp, *eom; 
     1084        int c, n, escaped; 
     1085        char *cp; 
     1086 
     1087        escaped = 0; 
     1088        bp = dst; 
     1089        eom = dst + dstsiz; 
     1090        label = bp++; 
     1091 
     1092        while ((c = *src++) != 0) { 
     1093                if (escaped) { 
     1094                        if ((cp = strchr(digits, c)) != NULL) { 
     1095                                n = (cp - digits) * 100; 
     1096                                if ((c = *src++) == 0 || 
     1097                                    (cp = strchr(digits, c)) == NULL) { 
     1098                                        __set_errno (EMSGSIZE); 
     1099                                        return (-1); 
     1100                                } 
     1101                                n += (cp - digits) * 10; 
     1102                                if ((c = *src++) == 0 || 
     1103                                    (cp = strchr(digits, c)) == NULL) { 
     1104                                        __set_errno (EMSGSIZE); 
     1105                                        return (-1); 
     1106                                } 
     1107                                n += (cp - digits); 
     1108                                if (n > 255) { 
     1109                                        __set_errno (EMSGSIZE); 
     1110                                        return (-1); 
     1111                                } 
     1112                                c = n; 
     1113                        } else if (c == '[' && label == bp - 1 && *src == 'x') { 
     1114                                /* Theoretically we would have to handle \[o 
     1115                                   as well but we do not since we do not need 
     1116                                   it internally.  */ 
     1117                                *label = 0x41; 
     1118                                label = bp++; 
     1119                                ++src; 
     1120                                while (isxdigit (*src)) { 
     1121                                        n = *src > '9' ? *src - 'a' + 10 : *src - '0'; 
     1122                                        ++src; 
     1123                                        if (! isxdigit(*src)) { 
     1124                                                __set_errno (EMSGSIZE); 
     1125                                                return (-1); 
     1126                                        } 
     1127                                        n <<= 4; 
     1128                                        n += *src > '9' ? *src - 'a' + 10 : *src - '0'; 
     1129                                        if (bp + 1 >= eom) { 
     1130                                                __set_errno (EMSGSIZE); 
     1131                                                return (-1); 
     1132                                        } 
     1133                                        *bp++ = n; 
     1134                                        ++src; 
     1135                                } 
     1136                                *label = (bp - label - 1) * 8; 
     1137                                if (*src++ != ']' || *src++ != '.') { 
     1138                                        __set_errno (EMSGSIZE); 
     1139                                        return (-1); 
     1140                                } 
     1141                                escaped = 0; 
     1142                                label = bp++; 
     1143                                if (bp >= eom) { 
     1144                                        __set_errno (EMSGSIZE); 
     1145                                        return (-1); 
     1146                                } 
     1147                                continue; 
     1148                        } 
     1149                        escaped = 0; 
     1150                } else if (c == '\\') { 
     1151                        escaped = 1; 
     1152                        continue; 
     1153                } else if (c == '.') { 
     1154                        c = (bp - label - 1); 
     1155                        if ((c & NS_CMPRSFLGS) != 0) {  /* Label too big. */ 
     1156                                __set_errno (EMSGSIZE); 
     1157                                return (-1); 
     1158                        } 
     1159                        if (label >= eom) { 
     1160                                __set_errno (EMSGSIZE); 
     1161                                return (-1); 
     1162                        } 
     1163                        *label = c; 
     1164                        /* Fully qualified ? */ 
     1165                        if (*src == '\0') { 
     1166                                if (c != 0) { 
     1167                                        if (bp >= eom) { 
     1168                                                __set_errno (EMSGSIZE); 
     1169                                                return (-1); 
     1170                                        } 
     1171                                        *bp++ = '\0'; 
     1172                                } 
     1173                                if ((bp - dst) > MAXCDNAME) { 
     1174                                        __set_errno (EMSGSIZE); 
     1175                                        return (-1); 
     1176                                } 
     1177                                return (1); 
     1178                        } 
     1179                        if (c == 0 || *src == '.') { 
     1180                                __set_errno (EMSGSIZE); 
     1181                                return (-1); 
     1182                        } 
     1183                        label = bp++; 
     1184                        continue; 
     1185                } 
     1186                if (bp >= eom) { 
     1187                        __set_errno (EMSGSIZE); 
     1188                        return (-1); 
     1189                } 
     1190                *bp++ = (u_char)c; 
     1191        } 
     1192        c = (bp - label - 1); 
     1193        if ((c & NS_CMPRSFLGS) != 0) {          /* Label too big. */ 
     1194                __set_errno (EMSGSIZE); 
     1195                return (-1); 
     1196        } 
     1197        if (label >= eom) { 
     1198                __set_errno (EMSGSIZE); 
     1199                return (-1); 
     1200        } 
     1201        *label = c; 
     1202        if (c != 0) { 
     1203                if (bp >= eom) { 
     1204                        __set_errno (EMSGSIZE); 
     1205                        return (-1); 
     1206                } 
     1207                *bp++ = 0; 
     1208        } 
     1209        if ((bp - dst) > MAXCDNAME) {   /* src too big */ 
     1210                __set_errno (EMSGSIZE); 
     1211                return (-1); 
     1212        } 
     1213        return (0); 
     1214} 
     1215 
     1216 
     1217 
     1218int 
     1219ns_name_compress(const char *src, u_char *dst, size_t dstsiz, 
     1220                 const u_char **dnptrs, const u_char **lastdnptr) 
     1221{ 
     1222        u_char tmp[NS_MAXCDNAME]; 
     1223 
     1224        if (ns_name_pton(src, tmp, sizeof tmp) == -1) 
     1225                return (-1); 
     1226        return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr)); 
     1227} 
     1228 
     1229 
     1230int 
     1231dn_comp(const char *src, u_char *dst, int dstsiz, 
     1232        u_char **dnptrs, u_char **lastdnptr) 
     1233{ 
     1234        return (ns_name_compress(src, dst, (size_t)dstsiz, 
     1235                                 (const u_char **)dnptrs, 
     1236                                 (const u_char **)lastdnptr)); 
     1237} 
     1238 
     1239 
     1240 
     1241 
     1242int 
     1243res_nmkquery(res_state statp, 
     1244             int op,                    /* opcode of query */ 
     1245             const char *dname,         /* domain name */ 
     1246             int class, int type,       /* class and type of query */ 
     1247             const u_char *data,        /* resource record data */ 
     1248             int datalen,               /* length of data */ 
     1249             const u_char *newrr_in,    /* new rr for modify or append */ 
     1250             u_char *buf,               /* buffer to put query */ 
     1251             int buflen)                /* size of buffer */ 
     1252{ 
     1253        register HEADER *hp; 
     1254        register u_char *cp; 
     1255        register int n; 
     1256        u_char *dnptrs[20], **dpp, **lastdnptr; 
     1257 
     1258#ifdef DEBUG 
     1259        if (statp->options & RES_DEBUG) 
     1260                printf(";; res_nmkquery(%s, %s, %s, %s)\n", 
     1261                       _res_opcodes[op], dname, p_class(class), p_type(type)); 
     1262#endif 
     1263        /* 
     1264         * Initialize header fields. 
     1265         */ 
     1266        if ((buf == NULL) || (buflen < HFIXEDSZ)) 
     1267                return (-1); 
     1268        memset(buf, 0, HFIXEDSZ); 
     1269        hp = (HEADER *) buf; 
     1270        /* We randomize the IDs every time.  The old code just 
     1271           incremented by one after the initial randomization which 
     1272           still predictable if the application does multiple 
     1273           requests.  */ 
     1274#if 0 
     1275        hp->id = htons(++statp->id); 
     1276#else 
     1277        hp->id = htons(statp->id); 
     1278        int randombits; 
     1279        do 
     1280          { 
     1281#ifdef RANDOM_BITS 
     1282            RANDOM_BITS (randombits); 
     1283#else 
     1284            struct timeval tv; 
     1285            gettimeofday (&tv, NULL); 
     1286            randombits = (tv.tv_sec << 8) ^ tv.tv_usec; 
     1287#endif 
     1288          } 
     1289        while ((randombits & 0xffff) == 0); 
     1290        statp->id = (statp->id + randombits) & 0xffff; 
     1291#endif 
     1292        hp->opcode = op; 
     1293        hp->rd = (statp->options & RES_RECURSE) != 0; 
     1294        hp->rcode = NOERROR; 
     1295        cp = buf + HFIXEDSZ; 
     1296        buflen -= HFIXEDSZ; 
     1297        dpp = dnptrs; 
     1298        *dpp++ = buf; 
     1299        *dpp++ = NULL; 
     1300        lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0]; 
     1301        /* 
     1302         * perform opcode specific processing 
     1303         */ 
     1304        switch (op) { 
     1305        case QUERY:     /*FALLTHROUGH*/ 
     1306        case NS_NOTIFY_OP: 
     1307                if ((buflen -= QFIXEDSZ) < 0) 
     1308                        return (-1); 
     1309                if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) 
     1310                        return (-1); 
     1311                cp += n; 
     1312                buflen -= n; 
     1313                __putshort(type, cp); 
     1314                cp += INT16SZ; 
     1315                __putshort(class, cp); 
     1316                cp += INT16SZ; 
     1317                hp->qdcount = htons(1); 
     1318                if (op == QUERY || data == NULL) 
     1319                        break; 
     1320                /* 
     1321                 * Make an additional record for completion domain. 
     1322                 */ 
     1323                buflen -= RRFIXEDSZ; 
     1324                n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr); 
     1325                if (n < 0) 
     1326                        return (-1); 
     1327                cp += n; 
     1328                buflen -= n; 
     1329                __putshort(T_NULL, cp); 
     1330                cp += INT16SZ; 
     1331                __putshort(class, cp); 
     1332                cp += INT16SZ; 
     1333                __putlong(0, cp); 
     1334                cp += INT32SZ; 
     1335                __putshort(0, cp); 
     1336                cp += INT16SZ; 
     1337                hp->arcount = htons(1); 
     1338                break; 
     1339 
     1340        case IQUERY: 
     1341                /* 
     1342                 * Initialize answer section 
     1343                 */ 
     1344                if (buflen < 1 + RRFIXEDSZ + datalen) 
     1345                        return (-1); 
     1346                *cp++ = '\0';   /* no domain name */ 
     1347                __putshort(type, cp); 
     1348                cp += INT16SZ; 
     1349                __putshort(class, cp); 
     1350                cp += INT16SZ; 
     1351                __putlong(0, cp); 
     1352                cp += INT32SZ; 
     1353                __putshort(datalen, cp); 
     1354                cp += INT16SZ; 
     1355                if (datalen) { 
     1356                        memcpy(cp, data, datalen); 
     1357                        cp += datalen; 
     1358                } 
     1359                hp->ancount = htons(1); 
     1360                break; 
     1361 
     1362        default: 
     1363                return (-1); 
     1364        } 
     1365        return (cp - buf); 
     1366} 
     1367 
     1368int 
     1369res_mkquery(int op,                     /* opcode of query */ 
     1370            const char *dname,          /* domain name */ 
     1371            int class, int type,        /* class and type of query */ 
     1372            const u_char *data,         /* resource record data */ 
     1373            int datalen,                /* length of data */ 
     1374            const u_char *newrr_in,     /* new rr for modify or append */ 
     1375            u_char *buf,                /* buffer to put query */ 
     1376            int buflen)                 /* size of buffer */ 
     1377{ 
     1378        return (res_nmkquery(&_res, op, dname, class, type, 
     1379                             data, datalen, 
     1380                             newrr_in, buf, buflen)); 
     1381} 
     1382 
     1383#endif 
    8831384 
    8841385void dorequest(char *s,int type,word id) 
    8851386{ 
Note: See TracBrowser for help on using the repository browser.