17c478bd9Sstevel@tonic-gate /* 2*9525b14bSRao Shoaib * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 37c478bd9Sstevel@tonic-gate * Copyright (c) 1996-1999 by Internet Software Consortium. 47c478bd9Sstevel@tonic-gate * 57c478bd9Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any 67c478bd9Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above 77c478bd9Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies. 87c478bd9Sstevel@tonic-gate * 9*9525b14bSRao Shoaib * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 10*9525b14bSRao Shoaib * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11*9525b14bSRao Shoaib * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 12*9525b14bSRao Shoaib * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13*9525b14bSRao Shoaib * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14*9525b14bSRao Shoaib * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15*9525b14bSRao Shoaib * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 167c478bd9Sstevel@tonic-gate */ 177c478bd9Sstevel@tonic-gate 18*9525b14bSRao Shoaib /*! \file 19*9525b14bSRao Shoaib * \brief 207c478bd9Sstevel@tonic-gate * Based on the Dynamic DNS reference implementation by Viraj Bais 21*9525b14bSRao Shoaib * <viraj_bais@ccm.fm.intel.com> 227c478bd9Sstevel@tonic-gate */ 237c478bd9Sstevel@tonic-gate 247c478bd9Sstevel@tonic-gate #if !defined(lint) && !defined(SABER) 25*9525b14bSRao Shoaib static const char rcsid[] = "$Id: res_mkupdate.c,v 1.10 2008/12/11 09:59:00 marka Exp $"; 267c478bd9Sstevel@tonic-gate #endif /* not lint */ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include "port_before.h" 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate #include <sys/types.h> 317c478bd9Sstevel@tonic-gate #include <sys/param.h> 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #include <netinet/in.h> 347c478bd9Sstevel@tonic-gate #include <arpa/nameser.h> 357c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #include <errno.h> 387c478bd9Sstevel@tonic-gate #include <limits.h> 397c478bd9Sstevel@tonic-gate #include <netdb.h> 407c478bd9Sstevel@tonic-gate #include <resolv.h> 417c478bd9Sstevel@tonic-gate #include <res_update.h> 427c478bd9Sstevel@tonic-gate #include <stdio.h> 437c478bd9Sstevel@tonic-gate #include <stdlib.h> 447c478bd9Sstevel@tonic-gate #include <string.h> 457c478bd9Sstevel@tonic-gate #include <unistd.h> 467c478bd9Sstevel@tonic-gate #include <ctype.h> 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate #include "port_after.h" 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate /* Options. Leave them on. */ 517c478bd9Sstevel@tonic-gate #define DEBUG 527c478bd9Sstevel@tonic-gate #define MAXPORT 1024 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate static int getnum_str(u_char **, u_char *); 557c478bd9Sstevel@tonic-gate static int gethexnum_str(u_char **, u_char *); 567c478bd9Sstevel@tonic-gate static int getword_str(char *, int, u_char **, u_char *); 577c478bd9Sstevel@tonic-gate static int getstr_str(char *, int, u_char **, u_char *); 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate #define ShrinkBuffer(x) if ((buflen -= x) < 0) return (-2); 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate /* Forward. */ 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate int res_protocolnumber(const char *); 647c478bd9Sstevel@tonic-gate int res_servicenumber(const char *); 657c478bd9Sstevel@tonic-gate 66*9525b14bSRao Shoaib /*% 677c478bd9Sstevel@tonic-gate * Form update packets. 687c478bd9Sstevel@tonic-gate * Returns the size of the resulting packet if no error 69*9525b14bSRao Shoaib * 707c478bd9Sstevel@tonic-gate * On error, 71*9525b14bSRao Shoaib * returns 72*9525b14bSRao Shoaib *\li -1 if error in reading a word/number in rdata 737c478bd9Sstevel@tonic-gate * portion for update packets 74*9525b14bSRao Shoaib *\li -2 if length of buffer passed is insufficient 75*9525b14bSRao Shoaib *\li -3 if zone section is not the first section in 767c478bd9Sstevel@tonic-gate * the linked list, or section order has a problem 77*9525b14bSRao Shoaib *\li -4 on a number overflow 78*9525b14bSRao Shoaib *\li -5 unknown operation or no records 797c478bd9Sstevel@tonic-gate */ 807c478bd9Sstevel@tonic-gate int 817c478bd9Sstevel@tonic-gate res_nmkupdate(res_state statp, ns_updrec *rrecp_in, u_char *buf, int buflen) { 827c478bd9Sstevel@tonic-gate ns_updrec *rrecp_start = rrecp_in; 837c478bd9Sstevel@tonic-gate HEADER *hp; 84*9525b14bSRao Shoaib u_char *cp, *sp2, *startp, *endp; 857c478bd9Sstevel@tonic-gate int n, i, soanum, multiline; 867c478bd9Sstevel@tonic-gate ns_updrec *rrecp; 877c478bd9Sstevel@tonic-gate struct in_addr ina; 887c478bd9Sstevel@tonic-gate struct in6_addr in6a; 897c478bd9Sstevel@tonic-gate char buf2[MAXDNAME]; 907c478bd9Sstevel@tonic-gate u_char buf3[MAXDNAME]; 917c478bd9Sstevel@tonic-gate int section, numrrs = 0, counts[ns_s_max]; 927c478bd9Sstevel@tonic-gate u_int16_t rtype, rclass; 937c478bd9Sstevel@tonic-gate u_int32_t n1, rttl; 947c478bd9Sstevel@tonic-gate u_char *dnptrs[20], **dpp, **lastdnptr; 957c478bd9Sstevel@tonic-gate int siglen, keylen, certlen; 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate /* 987c478bd9Sstevel@tonic-gate * Initialize header fields. 997c478bd9Sstevel@tonic-gate */ 1007c478bd9Sstevel@tonic-gate if ((buf == NULL) || (buflen < HFIXEDSZ)) 1017c478bd9Sstevel@tonic-gate return (-1); 1027c478bd9Sstevel@tonic-gate memset(buf, 0, HFIXEDSZ); 1037c478bd9Sstevel@tonic-gate hp = (HEADER *) buf; 104*9525b14bSRao Shoaib statp->id = res_nrandomid(statp); 105*9525b14bSRao Shoaib hp->id = htons(statp->id); 1067c478bd9Sstevel@tonic-gate hp->opcode = ns_o_update; 1077c478bd9Sstevel@tonic-gate hp->rcode = NOERROR; 1087c478bd9Sstevel@tonic-gate cp = buf + HFIXEDSZ; 1097c478bd9Sstevel@tonic-gate buflen -= HFIXEDSZ; 1107c478bd9Sstevel@tonic-gate dpp = dnptrs; 1117c478bd9Sstevel@tonic-gate *dpp++ = buf; 1127c478bd9Sstevel@tonic-gate *dpp++ = NULL; 1137c478bd9Sstevel@tonic-gate lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0]; 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate if (rrecp_start == NULL) 1167c478bd9Sstevel@tonic-gate return (-5); 1177c478bd9Sstevel@tonic-gate else if (rrecp_start->r_section != S_ZONE) 1187c478bd9Sstevel@tonic-gate return (-3); 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate memset(counts, 0, sizeof counts); 1217c478bd9Sstevel@tonic-gate for (rrecp = rrecp_start; rrecp; rrecp = NEXT(rrecp, r_glink)) { 1227c478bd9Sstevel@tonic-gate numrrs++; 1237c478bd9Sstevel@tonic-gate section = rrecp->r_section; 1247c478bd9Sstevel@tonic-gate if (section < 0 || section >= ns_s_max) 1257c478bd9Sstevel@tonic-gate return (-1); 1267c478bd9Sstevel@tonic-gate counts[section]++; 1277c478bd9Sstevel@tonic-gate for (i = section + 1; i < ns_s_max; i++) 1287c478bd9Sstevel@tonic-gate if (counts[i]) 1297c478bd9Sstevel@tonic-gate return (-3); 1307c478bd9Sstevel@tonic-gate rtype = rrecp->r_type; 1317c478bd9Sstevel@tonic-gate rclass = rrecp->r_class; 1327c478bd9Sstevel@tonic-gate rttl = rrecp->r_ttl; 1337c478bd9Sstevel@tonic-gate /* overload class and type */ 1347c478bd9Sstevel@tonic-gate if (section == S_PREREQ) { 1357c478bd9Sstevel@tonic-gate rttl = 0; 1367c478bd9Sstevel@tonic-gate switch (rrecp->r_opcode) { 1377c478bd9Sstevel@tonic-gate case YXDOMAIN: 1387c478bd9Sstevel@tonic-gate rclass = C_ANY; 1397c478bd9Sstevel@tonic-gate rtype = T_ANY; 1407c478bd9Sstevel@tonic-gate rrecp->r_size = 0; 1417c478bd9Sstevel@tonic-gate break; 1427c478bd9Sstevel@tonic-gate case NXDOMAIN: 1437c478bd9Sstevel@tonic-gate rclass = C_NONE; 1447c478bd9Sstevel@tonic-gate rtype = T_ANY; 1457c478bd9Sstevel@tonic-gate rrecp->r_size = 0; 1467c478bd9Sstevel@tonic-gate break; 1477c478bd9Sstevel@tonic-gate case NXRRSET: 1487c478bd9Sstevel@tonic-gate rclass = C_NONE; 1497c478bd9Sstevel@tonic-gate rrecp->r_size = 0; 1507c478bd9Sstevel@tonic-gate break; 1517c478bd9Sstevel@tonic-gate case YXRRSET: 1527c478bd9Sstevel@tonic-gate if (rrecp->r_size == 0) 1537c478bd9Sstevel@tonic-gate rclass = C_ANY; 1547c478bd9Sstevel@tonic-gate break; 1557c478bd9Sstevel@tonic-gate default: 1567c478bd9Sstevel@tonic-gate fprintf(stderr, 1577c478bd9Sstevel@tonic-gate "res_mkupdate: incorrect opcode: %d\n", 1587c478bd9Sstevel@tonic-gate rrecp->r_opcode); 1597c478bd9Sstevel@tonic-gate fflush(stderr); 1607c478bd9Sstevel@tonic-gate return (-1); 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate } else if (section == S_UPDATE) { 1637c478bd9Sstevel@tonic-gate switch (rrecp->r_opcode) { 1647c478bd9Sstevel@tonic-gate case DELETE: 1657c478bd9Sstevel@tonic-gate rclass = rrecp->r_size == 0 ? C_ANY : C_NONE; 1667c478bd9Sstevel@tonic-gate break; 1677c478bd9Sstevel@tonic-gate case ADD: 1687c478bd9Sstevel@tonic-gate break; 1697c478bd9Sstevel@tonic-gate default: 1707c478bd9Sstevel@tonic-gate fprintf(stderr, 1717c478bd9Sstevel@tonic-gate "res_mkupdate: incorrect opcode: %d\n", 1727c478bd9Sstevel@tonic-gate rrecp->r_opcode); 1737c478bd9Sstevel@tonic-gate fflush(stderr); 1747c478bd9Sstevel@tonic-gate return (-1); 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate } 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate /* 1797c478bd9Sstevel@tonic-gate * XXX appending default domain to owner name is omitted, 1807c478bd9Sstevel@tonic-gate * fqdn must be provided 1817c478bd9Sstevel@tonic-gate */ 1827c478bd9Sstevel@tonic-gate if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs, 1837c478bd9Sstevel@tonic-gate lastdnptr)) < 0) 1847c478bd9Sstevel@tonic-gate return (-1); 1857c478bd9Sstevel@tonic-gate cp += n; 1867c478bd9Sstevel@tonic-gate ShrinkBuffer(n + 2*INT16SZ); 1877c478bd9Sstevel@tonic-gate PUTSHORT(rtype, cp); 1887c478bd9Sstevel@tonic-gate PUTSHORT(rclass, cp); 1897c478bd9Sstevel@tonic-gate if (section == S_ZONE) { 1907c478bd9Sstevel@tonic-gate if (numrrs != 1 || rrecp->r_type != T_SOA) 1917c478bd9Sstevel@tonic-gate return (-3); 1927c478bd9Sstevel@tonic-gate continue; 1937c478bd9Sstevel@tonic-gate } 1947c478bd9Sstevel@tonic-gate ShrinkBuffer(INT32SZ + INT16SZ); 1957c478bd9Sstevel@tonic-gate PUTLONG(rttl, cp); 196*9525b14bSRao Shoaib sp2 = cp; /*%< save pointer to length byte */ 1977c478bd9Sstevel@tonic-gate cp += INT16SZ; 1987c478bd9Sstevel@tonic-gate if (rrecp->r_size == 0) { 1997c478bd9Sstevel@tonic-gate if (section == S_UPDATE && rclass != C_ANY) 2007c478bd9Sstevel@tonic-gate return (-1); 2017c478bd9Sstevel@tonic-gate else { 2027c478bd9Sstevel@tonic-gate PUTSHORT(0, sp2); 2037c478bd9Sstevel@tonic-gate continue; 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate startp = rrecp->r_data; 2077c478bd9Sstevel@tonic-gate endp = startp + rrecp->r_size - 1; 2087c478bd9Sstevel@tonic-gate /* XXX this should be done centrally. */ 2097c478bd9Sstevel@tonic-gate switch (rrecp->r_type) { 2107c478bd9Sstevel@tonic-gate case T_A: 2117c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, endp)) 2127c478bd9Sstevel@tonic-gate return (-1); 2137c478bd9Sstevel@tonic-gate if (!inet_aton(buf2, &ina)) 2147c478bd9Sstevel@tonic-gate return (-1); 2157c478bd9Sstevel@tonic-gate n1 = ntohl(ina.s_addr); 2167c478bd9Sstevel@tonic-gate ShrinkBuffer(INT32SZ); 2177c478bd9Sstevel@tonic-gate PUTLONG(n1, cp); 2187c478bd9Sstevel@tonic-gate break; 2197c478bd9Sstevel@tonic-gate case T_CNAME: 2207c478bd9Sstevel@tonic-gate case T_MB: 2217c478bd9Sstevel@tonic-gate case T_MG: 2227c478bd9Sstevel@tonic-gate case T_MR: 2237c478bd9Sstevel@tonic-gate case T_NS: 2247c478bd9Sstevel@tonic-gate case T_PTR: 225*9525b14bSRao Shoaib case ns_t_dname: 2267c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, endp)) 2277c478bd9Sstevel@tonic-gate return (-1); 2287c478bd9Sstevel@tonic-gate n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr); 2297c478bd9Sstevel@tonic-gate if (n < 0) 2307c478bd9Sstevel@tonic-gate return (-1); 2317c478bd9Sstevel@tonic-gate cp += n; 2327c478bd9Sstevel@tonic-gate ShrinkBuffer(n); 2337c478bd9Sstevel@tonic-gate break; 2347c478bd9Sstevel@tonic-gate case T_MINFO: 2357c478bd9Sstevel@tonic-gate case T_SOA: 2367c478bd9Sstevel@tonic-gate case T_RP: 2377c478bd9Sstevel@tonic-gate for (i = 0; i < 2; i++) { 2387c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, 2397c478bd9Sstevel@tonic-gate endp)) 2407c478bd9Sstevel@tonic-gate return (-1); 2417c478bd9Sstevel@tonic-gate n = dn_comp(buf2, cp, buflen, 2427c478bd9Sstevel@tonic-gate dnptrs, lastdnptr); 2437c478bd9Sstevel@tonic-gate if (n < 0) 2447c478bd9Sstevel@tonic-gate return (-1); 2457c478bd9Sstevel@tonic-gate cp += n; 2467c478bd9Sstevel@tonic-gate ShrinkBuffer(n); 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate if (rrecp->r_type == T_SOA) { 2497c478bd9Sstevel@tonic-gate ShrinkBuffer(5 * INT32SZ); 2507c478bd9Sstevel@tonic-gate while (isspace(*startp) || !*startp) 2517c478bd9Sstevel@tonic-gate startp++; 2527c478bd9Sstevel@tonic-gate if (*startp == '(') { 2537c478bd9Sstevel@tonic-gate multiline = 1; 2547c478bd9Sstevel@tonic-gate startp++; 2557c478bd9Sstevel@tonic-gate } else 2567c478bd9Sstevel@tonic-gate multiline = 0; 2577c478bd9Sstevel@tonic-gate /* serial, refresh, retry, expire, minimum */ 2587c478bd9Sstevel@tonic-gate for (i = 0; i < 5; i++) { 2597c478bd9Sstevel@tonic-gate soanum = getnum_str(&startp, endp); 2607c478bd9Sstevel@tonic-gate if (soanum < 0) 2617c478bd9Sstevel@tonic-gate return (-1); 2627c478bd9Sstevel@tonic-gate PUTLONG(soanum, cp); 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate if (multiline) { 2657c478bd9Sstevel@tonic-gate while (isspace(*startp) || !*startp) 2667c478bd9Sstevel@tonic-gate startp++; 2677c478bd9Sstevel@tonic-gate if (*startp != ')') 2687c478bd9Sstevel@tonic-gate return (-1); 2697c478bd9Sstevel@tonic-gate } 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate break; 2727c478bd9Sstevel@tonic-gate case T_MX: 2737c478bd9Sstevel@tonic-gate case T_AFSDB: 2747c478bd9Sstevel@tonic-gate case T_RT: 2757c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 2767c478bd9Sstevel@tonic-gate if (n < 0) 2777c478bd9Sstevel@tonic-gate return (-1); 2787c478bd9Sstevel@tonic-gate ShrinkBuffer(INT16SZ); 2797c478bd9Sstevel@tonic-gate PUTSHORT(n, cp); 2807c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, endp)) 2817c478bd9Sstevel@tonic-gate return (-1); 2827c478bd9Sstevel@tonic-gate n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr); 2837c478bd9Sstevel@tonic-gate if (n < 0) 2847c478bd9Sstevel@tonic-gate return (-1); 2857c478bd9Sstevel@tonic-gate cp += n; 2867c478bd9Sstevel@tonic-gate ShrinkBuffer(n); 2877c478bd9Sstevel@tonic-gate break; 2887c478bd9Sstevel@tonic-gate case T_SRV: 2897c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 2907c478bd9Sstevel@tonic-gate if (n < 0) 2917c478bd9Sstevel@tonic-gate return (-1); 2927c478bd9Sstevel@tonic-gate ShrinkBuffer(INT16SZ); 2937c478bd9Sstevel@tonic-gate PUTSHORT(n, cp); 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 2967c478bd9Sstevel@tonic-gate if (n < 0) 2977c478bd9Sstevel@tonic-gate return (-1); 2987c478bd9Sstevel@tonic-gate ShrinkBuffer(INT16SZ); 2997c478bd9Sstevel@tonic-gate PUTSHORT(n, cp); 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 3027c478bd9Sstevel@tonic-gate if (n < 0) 3037c478bd9Sstevel@tonic-gate return (-1); 3047c478bd9Sstevel@tonic-gate ShrinkBuffer(INT16SZ); 3057c478bd9Sstevel@tonic-gate PUTSHORT(n, cp); 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, endp)) 3087c478bd9Sstevel@tonic-gate return (-1); 3097c478bd9Sstevel@tonic-gate n = dn_comp(buf2, cp, buflen, NULL, NULL); 3107c478bd9Sstevel@tonic-gate if (n < 0) 3117c478bd9Sstevel@tonic-gate return (-1); 3127c478bd9Sstevel@tonic-gate cp += n; 3137c478bd9Sstevel@tonic-gate ShrinkBuffer(n); 3147c478bd9Sstevel@tonic-gate break; 3157c478bd9Sstevel@tonic-gate case T_PX: 3167c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 3177c478bd9Sstevel@tonic-gate if (n < 0) 3187c478bd9Sstevel@tonic-gate return (-1); 3197c478bd9Sstevel@tonic-gate PUTSHORT(n, cp); 3207c478bd9Sstevel@tonic-gate ShrinkBuffer(INT16SZ); 3217c478bd9Sstevel@tonic-gate for (i = 0; i < 2; i++) { 3227c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, 3237c478bd9Sstevel@tonic-gate endp)) 3247c478bd9Sstevel@tonic-gate return (-1); 3257c478bd9Sstevel@tonic-gate n = dn_comp(buf2, cp, buflen, dnptrs, 3267c478bd9Sstevel@tonic-gate lastdnptr); 3277c478bd9Sstevel@tonic-gate if (n < 0) 3287c478bd9Sstevel@tonic-gate return (-1); 3297c478bd9Sstevel@tonic-gate cp += n; 3307c478bd9Sstevel@tonic-gate ShrinkBuffer(n); 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate break; 3337c478bd9Sstevel@tonic-gate case T_WKS: { 3347c478bd9Sstevel@tonic-gate char bm[MAXPORT/8]; 3357c478bd9Sstevel@tonic-gate unsigned int maxbm = 0; 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, endp)) 3387c478bd9Sstevel@tonic-gate return (-1); 3397c478bd9Sstevel@tonic-gate if (!inet_aton(buf2, &ina)) 3407c478bd9Sstevel@tonic-gate return (-1); 3417c478bd9Sstevel@tonic-gate n1 = ntohl(ina.s_addr); 3427c478bd9Sstevel@tonic-gate ShrinkBuffer(INT32SZ); 3437c478bd9Sstevel@tonic-gate PUTLONG(n1, cp); 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, endp)) 3467c478bd9Sstevel@tonic-gate return (-1); 3477c478bd9Sstevel@tonic-gate if ((i = res_protocolnumber(buf2)) < 0) 3487c478bd9Sstevel@tonic-gate return (-1); 3497c478bd9Sstevel@tonic-gate ShrinkBuffer(1); 3507c478bd9Sstevel@tonic-gate *cp++ = i & 0xff; 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate for (i = 0; i < MAXPORT/8 ; i++) 3537c478bd9Sstevel@tonic-gate bm[i] = 0; 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate while (getword_str(buf2, sizeof buf2, &startp, endp)) { 356*9525b14bSRao Shoaib if ((n = res_servicenumber(buf2)) <= 0) 3577c478bd9Sstevel@tonic-gate return (-1); 3587c478bd9Sstevel@tonic-gate 359*9525b14bSRao Shoaib if (n < MAXPORT) { 360*9525b14bSRao Shoaib bm[n/8] |= (0x80>>(n%8)); 361*9525b14bSRao Shoaib if ((unsigned)n > maxbm) 362*9525b14bSRao Shoaib maxbm = n; 3637c478bd9Sstevel@tonic-gate } else 3647c478bd9Sstevel@tonic-gate return (-1); 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate maxbm = maxbm/8 + 1; 3677c478bd9Sstevel@tonic-gate ShrinkBuffer(maxbm); 3687c478bd9Sstevel@tonic-gate memcpy(cp, bm, maxbm); 3697c478bd9Sstevel@tonic-gate cp += maxbm; 3707c478bd9Sstevel@tonic-gate break; 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate case T_HINFO: 3737c478bd9Sstevel@tonic-gate for (i = 0; i < 2; i++) { 3747c478bd9Sstevel@tonic-gate if ((n = getstr_str(buf2, sizeof buf2, 3757c478bd9Sstevel@tonic-gate &startp, endp)) < 0) 3767c478bd9Sstevel@tonic-gate return (-1); 3777c478bd9Sstevel@tonic-gate if (n > 255) 3787c478bd9Sstevel@tonic-gate return (-1); 3797c478bd9Sstevel@tonic-gate ShrinkBuffer(n+1); 3807c478bd9Sstevel@tonic-gate *cp++ = n; 3817c478bd9Sstevel@tonic-gate memcpy(cp, buf2, n); 3827c478bd9Sstevel@tonic-gate cp += n; 3837c478bd9Sstevel@tonic-gate } 3847c478bd9Sstevel@tonic-gate break; 3857c478bd9Sstevel@tonic-gate case T_TXT: 386*9525b14bSRao Shoaib for (;;) { 3877c478bd9Sstevel@tonic-gate if ((n = getstr_str(buf2, sizeof buf2, 3887c478bd9Sstevel@tonic-gate &startp, endp)) < 0) { 3897c478bd9Sstevel@tonic-gate if (cp != (sp2 + INT16SZ)) 3907c478bd9Sstevel@tonic-gate break; 3917c478bd9Sstevel@tonic-gate return (-1); 3927c478bd9Sstevel@tonic-gate } 3937c478bd9Sstevel@tonic-gate if (n > 255) 3947c478bd9Sstevel@tonic-gate return (-1); 3957c478bd9Sstevel@tonic-gate ShrinkBuffer(n+1); 3967c478bd9Sstevel@tonic-gate *cp++ = n; 3977c478bd9Sstevel@tonic-gate memcpy(cp, buf2, n); 3987c478bd9Sstevel@tonic-gate cp += n; 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate break; 4017c478bd9Sstevel@tonic-gate case T_X25: 402*9525b14bSRao Shoaib /* RFC1183 */ 4037c478bd9Sstevel@tonic-gate if ((n = getstr_str(buf2, sizeof buf2, &startp, 4047c478bd9Sstevel@tonic-gate endp)) < 0) 4057c478bd9Sstevel@tonic-gate return (-1); 4067c478bd9Sstevel@tonic-gate if (n > 255) 4077c478bd9Sstevel@tonic-gate return (-1); 4087c478bd9Sstevel@tonic-gate ShrinkBuffer(n+1); 4097c478bd9Sstevel@tonic-gate *cp++ = n; 4107c478bd9Sstevel@tonic-gate memcpy(cp, buf2, n); 4117c478bd9Sstevel@tonic-gate cp += n; 4127c478bd9Sstevel@tonic-gate break; 4137c478bd9Sstevel@tonic-gate case T_ISDN: 414*9525b14bSRao Shoaib /* RFC1183 */ 4157c478bd9Sstevel@tonic-gate if ((n = getstr_str(buf2, sizeof buf2, &startp, 4167c478bd9Sstevel@tonic-gate endp)) < 0) 4177c478bd9Sstevel@tonic-gate return (-1); 4187c478bd9Sstevel@tonic-gate if ((n > 255) || (n == 0)) 4197c478bd9Sstevel@tonic-gate return (-1); 4207c478bd9Sstevel@tonic-gate ShrinkBuffer(n+1); 4217c478bd9Sstevel@tonic-gate *cp++ = n; 4227c478bd9Sstevel@tonic-gate memcpy(cp, buf2, n); 4237c478bd9Sstevel@tonic-gate cp += n; 4247c478bd9Sstevel@tonic-gate if ((n = getstr_str(buf2, sizeof buf2, &startp, 4257c478bd9Sstevel@tonic-gate endp)) < 0) 4267c478bd9Sstevel@tonic-gate n = 0; 4277c478bd9Sstevel@tonic-gate if (n > 255) 4287c478bd9Sstevel@tonic-gate return (-1); 4297c478bd9Sstevel@tonic-gate ShrinkBuffer(n+1); 4307c478bd9Sstevel@tonic-gate *cp++ = n; 4317c478bd9Sstevel@tonic-gate memcpy(cp, buf2, n); 4327c478bd9Sstevel@tonic-gate cp += n; 4337c478bd9Sstevel@tonic-gate break; 4347c478bd9Sstevel@tonic-gate case T_NSAP: 4357c478bd9Sstevel@tonic-gate if ((n = inet_nsap_addr((char *)startp, (u_char *)buf2, sizeof(buf2))) != 0) { 4367c478bd9Sstevel@tonic-gate ShrinkBuffer(n); 4377c478bd9Sstevel@tonic-gate memcpy(cp, buf2, n); 4387c478bd9Sstevel@tonic-gate cp += n; 4397c478bd9Sstevel@tonic-gate } else { 4407c478bd9Sstevel@tonic-gate return (-1); 4417c478bd9Sstevel@tonic-gate } 4427c478bd9Sstevel@tonic-gate break; 4437c478bd9Sstevel@tonic-gate case T_LOC: 4447c478bd9Sstevel@tonic-gate if ((n = loc_aton((char *)startp, (u_char *)buf2)) != 0) { 4457c478bd9Sstevel@tonic-gate ShrinkBuffer(n); 4467c478bd9Sstevel@tonic-gate memcpy(cp, buf2, n); 4477c478bd9Sstevel@tonic-gate cp += n; 4487c478bd9Sstevel@tonic-gate } else 4497c478bd9Sstevel@tonic-gate return (-1); 4507c478bd9Sstevel@tonic-gate break; 4517c478bd9Sstevel@tonic-gate case ns_t_sig: 4527c478bd9Sstevel@tonic-gate { 4537c478bd9Sstevel@tonic-gate int sig_type, success, dateerror; 4547c478bd9Sstevel@tonic-gate u_int32_t exptime, timesigned; 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate /* type */ 4577c478bd9Sstevel@tonic-gate if ((n = getword_str(buf2, sizeof buf2, 4587c478bd9Sstevel@tonic-gate &startp, endp)) < 0) 4597c478bd9Sstevel@tonic-gate return (-1); 4607c478bd9Sstevel@tonic-gate sig_type = sym_ston(__p_type_syms, buf2, &success); 4617c478bd9Sstevel@tonic-gate if (!success || sig_type == ns_t_any) 4627c478bd9Sstevel@tonic-gate return (-1); 4637c478bd9Sstevel@tonic-gate ShrinkBuffer(INT16SZ); 4647c478bd9Sstevel@tonic-gate PUTSHORT(sig_type, cp); 4657c478bd9Sstevel@tonic-gate /* alg */ 4667c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 4677c478bd9Sstevel@tonic-gate if (n < 0) 4687c478bd9Sstevel@tonic-gate return (-1); 4697c478bd9Sstevel@tonic-gate ShrinkBuffer(1); 4707c478bd9Sstevel@tonic-gate *cp++ = n; 4717c478bd9Sstevel@tonic-gate /* labels */ 4727c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 4737c478bd9Sstevel@tonic-gate if (n <= 0 || n > 255) 4747c478bd9Sstevel@tonic-gate return (-1); 4757c478bd9Sstevel@tonic-gate ShrinkBuffer(1); 4767c478bd9Sstevel@tonic-gate *cp++ = n; 4777c478bd9Sstevel@tonic-gate /* ottl & expire */ 4787c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, endp)) 4797c478bd9Sstevel@tonic-gate return (-1); 4807c478bd9Sstevel@tonic-gate exptime = ns_datetosecs(buf2, &dateerror); 4817c478bd9Sstevel@tonic-gate if (!dateerror) { 4827c478bd9Sstevel@tonic-gate ShrinkBuffer(INT32SZ); 4837c478bd9Sstevel@tonic-gate PUTLONG(rttl, cp); 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate else { 4867c478bd9Sstevel@tonic-gate char *ulendp; 4877c478bd9Sstevel@tonic-gate u_int32_t ottl; 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate errno = 0; 4907c478bd9Sstevel@tonic-gate ottl = strtoul(buf2, &ulendp, 10); 4917c478bd9Sstevel@tonic-gate if (errno != 0 || 4927c478bd9Sstevel@tonic-gate (ulendp != NULL && *ulendp != '\0')) 4937c478bd9Sstevel@tonic-gate return (-1); 4947c478bd9Sstevel@tonic-gate ShrinkBuffer(INT32SZ); 4957c478bd9Sstevel@tonic-gate PUTLONG(ottl, cp); 4967c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, 4977c478bd9Sstevel@tonic-gate endp)) 4987c478bd9Sstevel@tonic-gate return (-1); 4997c478bd9Sstevel@tonic-gate exptime = ns_datetosecs(buf2, &dateerror); 5007c478bd9Sstevel@tonic-gate if (dateerror) 5017c478bd9Sstevel@tonic-gate return (-1); 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate /* expire */ 5047c478bd9Sstevel@tonic-gate ShrinkBuffer(INT32SZ); 5057c478bd9Sstevel@tonic-gate PUTLONG(exptime, cp); 5067c478bd9Sstevel@tonic-gate /* timesigned */ 5077c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, endp)) 5087c478bd9Sstevel@tonic-gate return (-1); 5097c478bd9Sstevel@tonic-gate timesigned = ns_datetosecs(buf2, &dateerror); 5107c478bd9Sstevel@tonic-gate if (!dateerror) { 5117c478bd9Sstevel@tonic-gate ShrinkBuffer(INT32SZ); 5127c478bd9Sstevel@tonic-gate PUTLONG(timesigned, cp); 5137c478bd9Sstevel@tonic-gate } 5147c478bd9Sstevel@tonic-gate else 5157c478bd9Sstevel@tonic-gate return (-1); 5167c478bd9Sstevel@tonic-gate /* footprint */ 5177c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 5187c478bd9Sstevel@tonic-gate if (n < 0) 5197c478bd9Sstevel@tonic-gate return (-1); 5207c478bd9Sstevel@tonic-gate ShrinkBuffer(INT16SZ); 5217c478bd9Sstevel@tonic-gate PUTSHORT(n, cp); 5227c478bd9Sstevel@tonic-gate /* signer name */ 5237c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, endp)) 5247c478bd9Sstevel@tonic-gate return (-1); 5257c478bd9Sstevel@tonic-gate n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr); 5267c478bd9Sstevel@tonic-gate if (n < 0) 5277c478bd9Sstevel@tonic-gate return (-1); 5287c478bd9Sstevel@tonic-gate cp += n; 5297c478bd9Sstevel@tonic-gate ShrinkBuffer(n); 5307c478bd9Sstevel@tonic-gate /* sig */ 5317c478bd9Sstevel@tonic-gate if ((n = getword_str(buf2, sizeof buf2, 5327c478bd9Sstevel@tonic-gate &startp, endp)) < 0) 5337c478bd9Sstevel@tonic-gate return (-1); 5347c478bd9Sstevel@tonic-gate siglen = b64_pton(buf2, buf3, sizeof(buf3)); 5357c478bd9Sstevel@tonic-gate if (siglen < 0) 5367c478bd9Sstevel@tonic-gate return (-1); 5377c478bd9Sstevel@tonic-gate ShrinkBuffer(siglen); 5387c478bd9Sstevel@tonic-gate memcpy(cp, buf3, siglen); 5397c478bd9Sstevel@tonic-gate cp += siglen; 5407c478bd9Sstevel@tonic-gate break; 5417c478bd9Sstevel@tonic-gate } 5427c478bd9Sstevel@tonic-gate case ns_t_key: 5437c478bd9Sstevel@tonic-gate /* flags */ 5447c478bd9Sstevel@tonic-gate n = gethexnum_str(&startp, endp); 5457c478bd9Sstevel@tonic-gate if (n < 0) 5467c478bd9Sstevel@tonic-gate return (-1); 5477c478bd9Sstevel@tonic-gate ShrinkBuffer(INT16SZ); 5487c478bd9Sstevel@tonic-gate PUTSHORT(n, cp); 5497c478bd9Sstevel@tonic-gate /* proto */ 5507c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 5517c478bd9Sstevel@tonic-gate if (n < 0) 5527c478bd9Sstevel@tonic-gate return (-1); 5537c478bd9Sstevel@tonic-gate ShrinkBuffer(1); 5547c478bd9Sstevel@tonic-gate *cp++ = n; 5557c478bd9Sstevel@tonic-gate /* alg */ 5567c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 5577c478bd9Sstevel@tonic-gate if (n < 0) 5587c478bd9Sstevel@tonic-gate return (-1); 5597c478bd9Sstevel@tonic-gate ShrinkBuffer(1); 5607c478bd9Sstevel@tonic-gate *cp++ = n; 5617c478bd9Sstevel@tonic-gate /* key */ 5627c478bd9Sstevel@tonic-gate if ((n = getword_str(buf2, sizeof buf2, 5637c478bd9Sstevel@tonic-gate &startp, endp)) < 0) 5647c478bd9Sstevel@tonic-gate return (-1); 5657c478bd9Sstevel@tonic-gate keylen = b64_pton(buf2, buf3, sizeof(buf3)); 5667c478bd9Sstevel@tonic-gate if (keylen < 0) 5677c478bd9Sstevel@tonic-gate return (-1); 5687c478bd9Sstevel@tonic-gate ShrinkBuffer(keylen); 5697c478bd9Sstevel@tonic-gate memcpy(cp, buf3, keylen); 5707c478bd9Sstevel@tonic-gate cp += keylen; 5717c478bd9Sstevel@tonic-gate break; 5727c478bd9Sstevel@tonic-gate case ns_t_nxt: 5737c478bd9Sstevel@tonic-gate { 5747c478bd9Sstevel@tonic-gate int success, nxt_type; 5757c478bd9Sstevel@tonic-gate u_char data[32]; 5767c478bd9Sstevel@tonic-gate int maxtype; 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate /* next name */ 5797c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, endp)) 5807c478bd9Sstevel@tonic-gate return (-1); 5817c478bd9Sstevel@tonic-gate n = dn_comp(buf2, cp, buflen, NULL, NULL); 5827c478bd9Sstevel@tonic-gate if (n < 0) 5837c478bd9Sstevel@tonic-gate return (-1); 5847c478bd9Sstevel@tonic-gate cp += n; 5857c478bd9Sstevel@tonic-gate ShrinkBuffer(n); 5867c478bd9Sstevel@tonic-gate maxtype = 0; 5877c478bd9Sstevel@tonic-gate memset(data, 0, sizeof data); 588*9525b14bSRao Shoaib for (;;) { 5897c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, 5907c478bd9Sstevel@tonic-gate endp)) 5917c478bd9Sstevel@tonic-gate break; 5927c478bd9Sstevel@tonic-gate nxt_type = sym_ston(__p_type_syms, buf2, 5937c478bd9Sstevel@tonic-gate &success); 5947c478bd9Sstevel@tonic-gate if (!success || !ns_t_rr_p(nxt_type)) 5957c478bd9Sstevel@tonic-gate return (-1); 5967c478bd9Sstevel@tonic-gate NS_NXT_BIT_SET(nxt_type, data); 5977c478bd9Sstevel@tonic-gate if (nxt_type > maxtype) 5987c478bd9Sstevel@tonic-gate maxtype = nxt_type; 5997c478bd9Sstevel@tonic-gate } 6007c478bd9Sstevel@tonic-gate n = maxtype/NS_NXT_BITS+1; 6017c478bd9Sstevel@tonic-gate ShrinkBuffer(n); 6027c478bd9Sstevel@tonic-gate memcpy(cp, data, n); 6037c478bd9Sstevel@tonic-gate cp += n; 6047c478bd9Sstevel@tonic-gate break; 6057c478bd9Sstevel@tonic-gate } 6067c478bd9Sstevel@tonic-gate case ns_t_cert: 6077c478bd9Sstevel@tonic-gate /* type */ 6087c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 6097c478bd9Sstevel@tonic-gate if (n < 0) 6107c478bd9Sstevel@tonic-gate return (-1); 6117c478bd9Sstevel@tonic-gate ShrinkBuffer(INT16SZ); 6127c478bd9Sstevel@tonic-gate PUTSHORT(n, cp); 6137c478bd9Sstevel@tonic-gate /* key tag */ 6147c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 6157c478bd9Sstevel@tonic-gate if (n < 0) 6167c478bd9Sstevel@tonic-gate return (-1); 6177c478bd9Sstevel@tonic-gate ShrinkBuffer(INT16SZ); 6187c478bd9Sstevel@tonic-gate PUTSHORT(n, cp); 6197c478bd9Sstevel@tonic-gate /* alg */ 6207c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 6217c478bd9Sstevel@tonic-gate if (n < 0) 6227c478bd9Sstevel@tonic-gate return (-1); 6237c478bd9Sstevel@tonic-gate ShrinkBuffer(1); 6247c478bd9Sstevel@tonic-gate *cp++ = n; 6257c478bd9Sstevel@tonic-gate /* cert */ 6267c478bd9Sstevel@tonic-gate if ((n = getword_str(buf2, sizeof buf2, 6277c478bd9Sstevel@tonic-gate &startp, endp)) < 0) 6287c478bd9Sstevel@tonic-gate return (-1); 6297c478bd9Sstevel@tonic-gate certlen = b64_pton(buf2, buf3, sizeof(buf3)); 6307c478bd9Sstevel@tonic-gate if (certlen < 0) 6317c478bd9Sstevel@tonic-gate return (-1); 6327c478bd9Sstevel@tonic-gate ShrinkBuffer(certlen); 6337c478bd9Sstevel@tonic-gate memcpy(cp, buf3, certlen); 6347c478bd9Sstevel@tonic-gate cp += certlen; 6357c478bd9Sstevel@tonic-gate break; 6367c478bd9Sstevel@tonic-gate case ns_t_aaaa: 6377c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, endp)) 6387c478bd9Sstevel@tonic-gate return (-1); 6397c478bd9Sstevel@tonic-gate if (inet_pton(AF_INET6, buf2, &in6a) <= 0) 6407c478bd9Sstevel@tonic-gate return (-1); 6417c478bd9Sstevel@tonic-gate ShrinkBuffer(NS_IN6ADDRSZ); 6427c478bd9Sstevel@tonic-gate memcpy(cp, &in6a, NS_IN6ADDRSZ); 6437c478bd9Sstevel@tonic-gate cp += NS_IN6ADDRSZ; 6447c478bd9Sstevel@tonic-gate break; 6457c478bd9Sstevel@tonic-gate case ns_t_naptr: 6467c478bd9Sstevel@tonic-gate /* Order Preference Flags Service Replacement Regexp */ 6477c478bd9Sstevel@tonic-gate /* Order */ 6487c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 6497c478bd9Sstevel@tonic-gate if (n < 0 || n > 65535) 6507c478bd9Sstevel@tonic-gate return (-1); 6517c478bd9Sstevel@tonic-gate ShrinkBuffer(INT16SZ); 6527c478bd9Sstevel@tonic-gate PUTSHORT(n, cp); 6537c478bd9Sstevel@tonic-gate /* Preference */ 6547c478bd9Sstevel@tonic-gate n = getnum_str(&startp, endp); 6557c478bd9Sstevel@tonic-gate if (n < 0 || n > 65535) 6567c478bd9Sstevel@tonic-gate return (-1); 6577c478bd9Sstevel@tonic-gate ShrinkBuffer(INT16SZ); 6587c478bd9Sstevel@tonic-gate PUTSHORT(n, cp); 6597c478bd9Sstevel@tonic-gate /* Flags */ 6607c478bd9Sstevel@tonic-gate if ((n = getstr_str(buf2, sizeof buf2, 6617c478bd9Sstevel@tonic-gate &startp, endp)) < 0) { 6627c478bd9Sstevel@tonic-gate return (-1); 6637c478bd9Sstevel@tonic-gate } 6647c478bd9Sstevel@tonic-gate if (n > 255) 6657c478bd9Sstevel@tonic-gate return (-1); 6667c478bd9Sstevel@tonic-gate ShrinkBuffer(n+1); 6677c478bd9Sstevel@tonic-gate *cp++ = n; 6687c478bd9Sstevel@tonic-gate memcpy(cp, buf2, n); 6697c478bd9Sstevel@tonic-gate cp += n; 6707c478bd9Sstevel@tonic-gate /* Service Classes */ 6717c478bd9Sstevel@tonic-gate if ((n = getstr_str(buf2, sizeof buf2, 6727c478bd9Sstevel@tonic-gate &startp, endp)) < 0) { 6737c478bd9Sstevel@tonic-gate return (-1); 6747c478bd9Sstevel@tonic-gate } 6757c478bd9Sstevel@tonic-gate if (n > 255) 6767c478bd9Sstevel@tonic-gate return (-1); 6777c478bd9Sstevel@tonic-gate ShrinkBuffer(n+1); 6787c478bd9Sstevel@tonic-gate *cp++ = n; 6797c478bd9Sstevel@tonic-gate memcpy(cp, buf2, n); 6807c478bd9Sstevel@tonic-gate cp += n; 6817c478bd9Sstevel@tonic-gate /* Pattern */ 6827c478bd9Sstevel@tonic-gate if ((n = getstr_str(buf2, sizeof buf2, 6837c478bd9Sstevel@tonic-gate &startp, endp)) < 0) { 6847c478bd9Sstevel@tonic-gate return (-1); 6857c478bd9Sstevel@tonic-gate } 6867c478bd9Sstevel@tonic-gate if (n > 255) 6877c478bd9Sstevel@tonic-gate return (-1); 6887c478bd9Sstevel@tonic-gate ShrinkBuffer(n+1); 6897c478bd9Sstevel@tonic-gate *cp++ = n; 6907c478bd9Sstevel@tonic-gate memcpy(cp, buf2, n); 6917c478bd9Sstevel@tonic-gate cp += n; 6927c478bd9Sstevel@tonic-gate /* Replacement */ 6937c478bd9Sstevel@tonic-gate if (!getword_str(buf2, sizeof buf2, &startp, endp)) 6947c478bd9Sstevel@tonic-gate return (-1); 6957c478bd9Sstevel@tonic-gate n = dn_comp(buf2, cp, buflen, NULL, NULL); 6967c478bd9Sstevel@tonic-gate if (n < 0) 6977c478bd9Sstevel@tonic-gate return (-1); 6987c478bd9Sstevel@tonic-gate cp += n; 6997c478bd9Sstevel@tonic-gate ShrinkBuffer(n); 7007c478bd9Sstevel@tonic-gate break; 7017c478bd9Sstevel@tonic-gate default: 7027c478bd9Sstevel@tonic-gate return (-1); 7037c478bd9Sstevel@tonic-gate } /*switch*/ 7047c478bd9Sstevel@tonic-gate n = (u_int16_t)((cp - sp2) - INT16SZ); 7057c478bd9Sstevel@tonic-gate PUTSHORT(n, sp2); 7067c478bd9Sstevel@tonic-gate } /*for*/ 7077c478bd9Sstevel@tonic-gate 7087c478bd9Sstevel@tonic-gate hp->qdcount = htons(counts[0]); 7097c478bd9Sstevel@tonic-gate hp->ancount = htons(counts[1]); 7107c478bd9Sstevel@tonic-gate hp->nscount = htons(counts[2]); 7117c478bd9Sstevel@tonic-gate hp->arcount = htons(counts[3]); 7127c478bd9Sstevel@tonic-gate return (cp - buf); 7137c478bd9Sstevel@tonic-gate } 7147c478bd9Sstevel@tonic-gate 715*9525b14bSRao Shoaib /*% 7167c478bd9Sstevel@tonic-gate * Get a whitespace delimited word from a string (not file) 7177c478bd9Sstevel@tonic-gate * into buf. modify the start pointer to point after the 7187c478bd9Sstevel@tonic-gate * word in the string. 7197c478bd9Sstevel@tonic-gate */ 7207c478bd9Sstevel@tonic-gate static int 7217c478bd9Sstevel@tonic-gate getword_str(char *buf, int size, u_char **startpp, u_char *endp) { 7227c478bd9Sstevel@tonic-gate char *cp; 7237c478bd9Sstevel@tonic-gate int c; 7247c478bd9Sstevel@tonic-gate 7257c478bd9Sstevel@tonic-gate for (cp = buf; *startpp <= endp; ) { 7267c478bd9Sstevel@tonic-gate c = **startpp; 7277c478bd9Sstevel@tonic-gate if (isspace(c) || c == '\0') { 728*9525b14bSRao Shoaib if (cp != buf) /*%< trailing whitespace */ 7297c478bd9Sstevel@tonic-gate break; 730*9525b14bSRao Shoaib else { /*%< leading whitespace */ 7317c478bd9Sstevel@tonic-gate (*startpp)++; 7327c478bd9Sstevel@tonic-gate continue; 7337c478bd9Sstevel@tonic-gate } 7347c478bd9Sstevel@tonic-gate } 7357c478bd9Sstevel@tonic-gate (*startpp)++; 7367c478bd9Sstevel@tonic-gate if (cp >= buf+size-1) 7377c478bd9Sstevel@tonic-gate break; 7387c478bd9Sstevel@tonic-gate *cp++ = (u_char)c; 7397c478bd9Sstevel@tonic-gate } 7407c478bd9Sstevel@tonic-gate *cp = '\0'; 7417c478bd9Sstevel@tonic-gate return (cp != buf); 7427c478bd9Sstevel@tonic-gate } 7437c478bd9Sstevel@tonic-gate 744*9525b14bSRao Shoaib /*% 7457c478bd9Sstevel@tonic-gate * get a white spae delimited string from memory. Process quoted strings 746*9525b14bSRao Shoaib * and \\DDD escapes. Return length or -1 on error. Returned string may 7477c478bd9Sstevel@tonic-gate * contain nulls. 7487c478bd9Sstevel@tonic-gate */ 7497c478bd9Sstevel@tonic-gate static char digits[] = "0123456789"; 7507c478bd9Sstevel@tonic-gate static int 7517c478bd9Sstevel@tonic-gate getstr_str(char *buf, int size, u_char **startpp, u_char *endp) { 7527c478bd9Sstevel@tonic-gate char *cp; 7537c478bd9Sstevel@tonic-gate int c, c1 = 0; 7547c478bd9Sstevel@tonic-gate int inquote = 0; 7557c478bd9Sstevel@tonic-gate int seen_quote = 0; 7567c478bd9Sstevel@tonic-gate int escape = 0; 7577c478bd9Sstevel@tonic-gate int dig = 0; 7587c478bd9Sstevel@tonic-gate 7597c478bd9Sstevel@tonic-gate for (cp = buf; *startpp <= endp; ) { 7607c478bd9Sstevel@tonic-gate if ((c = **startpp) == '\0') 7617c478bd9Sstevel@tonic-gate break; 7627c478bd9Sstevel@tonic-gate /* leading white space */ 7637c478bd9Sstevel@tonic-gate if ((cp == buf) && !seen_quote && isspace(c)) { 7647c478bd9Sstevel@tonic-gate (*startpp)++; 7657c478bd9Sstevel@tonic-gate continue; 7667c478bd9Sstevel@tonic-gate } 7677c478bd9Sstevel@tonic-gate 7687c478bd9Sstevel@tonic-gate switch (c) { 7697c478bd9Sstevel@tonic-gate case '\\': 7707c478bd9Sstevel@tonic-gate if (!escape) { 7717c478bd9Sstevel@tonic-gate escape = 1; 7727c478bd9Sstevel@tonic-gate dig = 0; 7737c478bd9Sstevel@tonic-gate c1 = 0; 7747c478bd9Sstevel@tonic-gate (*startpp)++; 7757c478bd9Sstevel@tonic-gate continue; 7767c478bd9Sstevel@tonic-gate } 7777c478bd9Sstevel@tonic-gate goto do_escape; 7787c478bd9Sstevel@tonic-gate case '"': 7797c478bd9Sstevel@tonic-gate if (!escape) { 7807c478bd9Sstevel@tonic-gate inquote = !inquote; 7817c478bd9Sstevel@tonic-gate seen_quote = 1; 7827c478bd9Sstevel@tonic-gate (*startpp)++; 7837c478bd9Sstevel@tonic-gate continue; 7847c478bd9Sstevel@tonic-gate } 7857c478bd9Sstevel@tonic-gate /* fall through */ 7867c478bd9Sstevel@tonic-gate default: 7877c478bd9Sstevel@tonic-gate do_escape: 7887c478bd9Sstevel@tonic-gate if (escape) { 7897c478bd9Sstevel@tonic-gate switch (c) { 7907c478bd9Sstevel@tonic-gate case '0': 7917c478bd9Sstevel@tonic-gate case '1': 7927c478bd9Sstevel@tonic-gate case '2': 7937c478bd9Sstevel@tonic-gate case '3': 7947c478bd9Sstevel@tonic-gate case '4': 7957c478bd9Sstevel@tonic-gate case '5': 7967c478bd9Sstevel@tonic-gate case '6': 7977c478bd9Sstevel@tonic-gate case '7': 7987c478bd9Sstevel@tonic-gate case '8': 7997c478bd9Sstevel@tonic-gate case '9': 8007c478bd9Sstevel@tonic-gate c1 = c1 * 10 + 8017c478bd9Sstevel@tonic-gate (strchr(digits, c) - digits); 8027c478bd9Sstevel@tonic-gate 8037c478bd9Sstevel@tonic-gate if (++dig == 3) { 8047c478bd9Sstevel@tonic-gate c = c1 &0xff; 8057c478bd9Sstevel@tonic-gate break; 8067c478bd9Sstevel@tonic-gate } 8077c478bd9Sstevel@tonic-gate (*startpp)++; 8087c478bd9Sstevel@tonic-gate continue; 8097c478bd9Sstevel@tonic-gate } 8107c478bd9Sstevel@tonic-gate escape = 0; 8117c478bd9Sstevel@tonic-gate } else if (!inquote && isspace(c)) 8127c478bd9Sstevel@tonic-gate goto done; 8137c478bd9Sstevel@tonic-gate if (cp >= buf+size-1) 8147c478bd9Sstevel@tonic-gate goto done; 8157c478bd9Sstevel@tonic-gate *cp++ = (u_char)c; 8167c478bd9Sstevel@tonic-gate (*startpp)++; 8177c478bd9Sstevel@tonic-gate } 8187c478bd9Sstevel@tonic-gate } 8197c478bd9Sstevel@tonic-gate done: 8207c478bd9Sstevel@tonic-gate *cp = '\0'; 8217c478bd9Sstevel@tonic-gate return ((cp == buf)? (seen_quote? 0: -1): (cp - buf)); 8227c478bd9Sstevel@tonic-gate } 823*9525b14bSRao Shoaib 824*9525b14bSRao Shoaib /*% 8257c478bd9Sstevel@tonic-gate * Get a whitespace delimited base 16 number from a string (not file) into buf 8267c478bd9Sstevel@tonic-gate * update the start pointer to point after the number in the string. 8277c478bd9Sstevel@tonic-gate */ 8287c478bd9Sstevel@tonic-gate static int 8297c478bd9Sstevel@tonic-gate gethexnum_str(u_char **startpp, u_char *endp) { 8307c478bd9Sstevel@tonic-gate int c, n; 8317c478bd9Sstevel@tonic-gate int seendigit = 0; 8327c478bd9Sstevel@tonic-gate int m = 0; 8337c478bd9Sstevel@tonic-gate 8347c478bd9Sstevel@tonic-gate if (*startpp + 2 >= endp || strncasecmp((char *)*startpp, "0x", 2) != 0) 8357c478bd9Sstevel@tonic-gate return getnum_str(startpp, endp); 8367c478bd9Sstevel@tonic-gate (*startpp)+=2; 8377c478bd9Sstevel@tonic-gate for (n = 0; *startpp <= endp; ) { 8387c478bd9Sstevel@tonic-gate c = **startpp; 8397c478bd9Sstevel@tonic-gate if (isspace(c) || c == '\0') { 840*9525b14bSRao Shoaib if (seendigit) /*%< trailing whitespace */ 8417c478bd9Sstevel@tonic-gate break; 842*9525b14bSRao Shoaib else { /*%< leading whitespace */ 8437c478bd9Sstevel@tonic-gate (*startpp)++; 8447c478bd9Sstevel@tonic-gate continue; 8457c478bd9Sstevel@tonic-gate } 8467c478bd9Sstevel@tonic-gate } 8477c478bd9Sstevel@tonic-gate if (c == ';') { 8487c478bd9Sstevel@tonic-gate while ((*startpp <= endp) && 8497c478bd9Sstevel@tonic-gate ((c = **startpp) != '\n')) 8507c478bd9Sstevel@tonic-gate (*startpp)++; 8517c478bd9Sstevel@tonic-gate if (seendigit) 8527c478bd9Sstevel@tonic-gate break; 8537c478bd9Sstevel@tonic-gate continue; 8547c478bd9Sstevel@tonic-gate } 8557c478bd9Sstevel@tonic-gate if (!isxdigit(c)) { 8567c478bd9Sstevel@tonic-gate if (c == ')' && seendigit) { 8577c478bd9Sstevel@tonic-gate (*startpp)--; 8587c478bd9Sstevel@tonic-gate break; 8597c478bd9Sstevel@tonic-gate } 8607c478bd9Sstevel@tonic-gate return (-1); 8617c478bd9Sstevel@tonic-gate } 8627c478bd9Sstevel@tonic-gate (*startpp)++; 8637c478bd9Sstevel@tonic-gate if (isdigit(c)) 8647c478bd9Sstevel@tonic-gate n = n * 16 + (c - '0'); 8657c478bd9Sstevel@tonic-gate else 8667c478bd9Sstevel@tonic-gate n = n * 16 + (tolower(c) - 'a' + 10); 8677c478bd9Sstevel@tonic-gate seendigit = 1; 8687c478bd9Sstevel@tonic-gate } 8697c478bd9Sstevel@tonic-gate return (n + m); 8707c478bd9Sstevel@tonic-gate } 8717c478bd9Sstevel@tonic-gate 872*9525b14bSRao Shoaib /*% 8737c478bd9Sstevel@tonic-gate * Get a whitespace delimited base 10 number from a string (not file) into buf 8747c478bd9Sstevel@tonic-gate * update the start pointer to point after the number in the string. 8757c478bd9Sstevel@tonic-gate */ 8767c478bd9Sstevel@tonic-gate static int 8777c478bd9Sstevel@tonic-gate getnum_str(u_char **startpp, u_char *endp) { 8787c478bd9Sstevel@tonic-gate int c, n; 8797c478bd9Sstevel@tonic-gate int seendigit = 0; 8807c478bd9Sstevel@tonic-gate int m = 0; 8817c478bd9Sstevel@tonic-gate 8827c478bd9Sstevel@tonic-gate for (n = 0; *startpp <= endp; ) { 8837c478bd9Sstevel@tonic-gate c = **startpp; 8847c478bd9Sstevel@tonic-gate if (isspace(c) || c == '\0') { 885*9525b14bSRao Shoaib if (seendigit) /*%< trailing whitespace */ 8867c478bd9Sstevel@tonic-gate break; 887*9525b14bSRao Shoaib else { /*%< leading whitespace */ 8887c478bd9Sstevel@tonic-gate (*startpp)++; 8897c478bd9Sstevel@tonic-gate continue; 8907c478bd9Sstevel@tonic-gate } 8917c478bd9Sstevel@tonic-gate } 8927c478bd9Sstevel@tonic-gate if (c == ';') { 8937c478bd9Sstevel@tonic-gate while ((*startpp <= endp) && 8947c478bd9Sstevel@tonic-gate ((c = **startpp) != '\n')) 8957c478bd9Sstevel@tonic-gate (*startpp)++; 8967c478bd9Sstevel@tonic-gate if (seendigit) 8977c478bd9Sstevel@tonic-gate break; 8987c478bd9Sstevel@tonic-gate continue; 8997c478bd9Sstevel@tonic-gate } 9007c478bd9Sstevel@tonic-gate if (!isdigit(c)) { 9017c478bd9Sstevel@tonic-gate if (c == ')' && seendigit) { 9027c478bd9Sstevel@tonic-gate (*startpp)--; 9037c478bd9Sstevel@tonic-gate break; 9047c478bd9Sstevel@tonic-gate } 9057c478bd9Sstevel@tonic-gate return (-1); 9067c478bd9Sstevel@tonic-gate } 9077c478bd9Sstevel@tonic-gate (*startpp)++; 9087c478bd9Sstevel@tonic-gate n = n * 10 + (c - '0'); 9097c478bd9Sstevel@tonic-gate seendigit = 1; 9107c478bd9Sstevel@tonic-gate } 9117c478bd9Sstevel@tonic-gate return (n + m); 9127c478bd9Sstevel@tonic-gate } 9137c478bd9Sstevel@tonic-gate 914*9525b14bSRao Shoaib /*% 9157c478bd9Sstevel@tonic-gate * Allocate a resource record buffer & save rr info. 9167c478bd9Sstevel@tonic-gate */ 9177c478bd9Sstevel@tonic-gate ns_updrec * 9187c478bd9Sstevel@tonic-gate res_mkupdrec(int section, const char *dname, 9197c478bd9Sstevel@tonic-gate u_int class, u_int type, u_long ttl) { 9207c478bd9Sstevel@tonic-gate ns_updrec *rrecp = (ns_updrec *)calloc(1, sizeof(ns_updrec)); 9217c478bd9Sstevel@tonic-gate 9227c478bd9Sstevel@tonic-gate if (!rrecp || !(rrecp->r_dname = strdup(dname))) { 9237c478bd9Sstevel@tonic-gate if (rrecp) 9247c478bd9Sstevel@tonic-gate free((char *)rrecp); 9257c478bd9Sstevel@tonic-gate return (NULL); 9267c478bd9Sstevel@tonic-gate } 9277c478bd9Sstevel@tonic-gate INIT_LINK(rrecp, r_link); 9287c478bd9Sstevel@tonic-gate INIT_LINK(rrecp, r_glink); 929*9525b14bSRao Shoaib rrecp->r_class = (ns_class)class; 930*9525b14bSRao Shoaib rrecp->r_type = (ns_type)type; 9317c478bd9Sstevel@tonic-gate rrecp->r_ttl = ttl; 932*9525b14bSRao Shoaib rrecp->r_section = (ns_sect)section; 9337c478bd9Sstevel@tonic-gate return (rrecp); 9347c478bd9Sstevel@tonic-gate } 9357c478bd9Sstevel@tonic-gate 936*9525b14bSRao Shoaib /*% 9377c478bd9Sstevel@tonic-gate * Free a resource record buffer created by res_mkupdrec. 9387c478bd9Sstevel@tonic-gate */ 9397c478bd9Sstevel@tonic-gate void 9407c478bd9Sstevel@tonic-gate res_freeupdrec(ns_updrec *rrecp) { 9417c478bd9Sstevel@tonic-gate /* Note: freeing r_dp is the caller's responsibility. */ 9427c478bd9Sstevel@tonic-gate if (rrecp->r_dname != NULL) 9437c478bd9Sstevel@tonic-gate free(rrecp->r_dname); 9447c478bd9Sstevel@tonic-gate free(rrecp); 9457c478bd9Sstevel@tonic-gate } 9467c478bd9Sstevel@tonic-gate 9477c478bd9Sstevel@tonic-gate struct valuelist { 9487c478bd9Sstevel@tonic-gate struct valuelist * next; 9497c478bd9Sstevel@tonic-gate struct valuelist * prev; 9507c478bd9Sstevel@tonic-gate char * name; 9517c478bd9Sstevel@tonic-gate char * proto; 9527c478bd9Sstevel@tonic-gate int port; 9537c478bd9Sstevel@tonic-gate }; 9547c478bd9Sstevel@tonic-gate static struct valuelist *servicelist, *protolist; 9557c478bd9Sstevel@tonic-gate 9567c478bd9Sstevel@tonic-gate static void 9577c478bd9Sstevel@tonic-gate res_buildservicelist() { 9587c478bd9Sstevel@tonic-gate struct servent *sp; 9597c478bd9Sstevel@tonic-gate struct valuelist *slp; 9607c478bd9Sstevel@tonic-gate 9617c478bd9Sstevel@tonic-gate #ifdef MAYBE_HESIOD 9627c478bd9Sstevel@tonic-gate setservent(0); 9637c478bd9Sstevel@tonic-gate #else 9647c478bd9Sstevel@tonic-gate setservent(1); 9657c478bd9Sstevel@tonic-gate #endif 9667c478bd9Sstevel@tonic-gate while ((sp = getservent()) != NULL) { 9677c478bd9Sstevel@tonic-gate slp = (struct valuelist *)malloc(sizeof(struct valuelist)); 9687c478bd9Sstevel@tonic-gate if (!slp) 9697c478bd9Sstevel@tonic-gate break; 9707c478bd9Sstevel@tonic-gate slp->name = strdup(sp->s_name); 9717c478bd9Sstevel@tonic-gate slp->proto = strdup(sp->s_proto); 9727c478bd9Sstevel@tonic-gate if ((slp->name == NULL) || (slp->proto == NULL)) { 9737c478bd9Sstevel@tonic-gate if (slp->name) free(slp->name); 9747c478bd9Sstevel@tonic-gate if (slp->proto) free(slp->proto); 9757c478bd9Sstevel@tonic-gate free(slp); 9767c478bd9Sstevel@tonic-gate break; 9777c478bd9Sstevel@tonic-gate } 978*9525b14bSRao Shoaib slp->port = ntohs((u_int16_t)sp->s_port); /*%< host byt order */ 9797c478bd9Sstevel@tonic-gate slp->next = servicelist; 9807c478bd9Sstevel@tonic-gate slp->prev = NULL; 9817c478bd9Sstevel@tonic-gate if (servicelist) 9827c478bd9Sstevel@tonic-gate servicelist->prev = slp; 9837c478bd9Sstevel@tonic-gate servicelist = slp; 9847c478bd9Sstevel@tonic-gate } 9857c478bd9Sstevel@tonic-gate endservent(); 9867c478bd9Sstevel@tonic-gate } 9877c478bd9Sstevel@tonic-gate 9887c478bd9Sstevel@tonic-gate void 9897c478bd9Sstevel@tonic-gate res_destroyservicelist() { 9907c478bd9Sstevel@tonic-gate struct valuelist *slp, *slp_next; 9917c478bd9Sstevel@tonic-gate 9927c478bd9Sstevel@tonic-gate for (slp = servicelist; slp != NULL; slp = slp_next) { 9937c478bd9Sstevel@tonic-gate slp_next = slp->next; 9947c478bd9Sstevel@tonic-gate free(slp->name); 9957c478bd9Sstevel@tonic-gate free(slp->proto); 9967c478bd9Sstevel@tonic-gate free(slp); 9977c478bd9Sstevel@tonic-gate } 9987c478bd9Sstevel@tonic-gate servicelist = (struct valuelist *)0; 9997c478bd9Sstevel@tonic-gate } 10007c478bd9Sstevel@tonic-gate 10017c478bd9Sstevel@tonic-gate void 10027c478bd9Sstevel@tonic-gate res_buildprotolist(void) { 10037c478bd9Sstevel@tonic-gate struct protoent *pp; 10047c478bd9Sstevel@tonic-gate struct valuelist *slp; 10057c478bd9Sstevel@tonic-gate 10067c478bd9Sstevel@tonic-gate #ifdef MAYBE_HESIOD 10077c478bd9Sstevel@tonic-gate setprotoent(0); 10087c478bd9Sstevel@tonic-gate #else 10097c478bd9Sstevel@tonic-gate setprotoent(1); 10107c478bd9Sstevel@tonic-gate #endif 10117c478bd9Sstevel@tonic-gate while ((pp = getprotoent()) != NULL) { 10127c478bd9Sstevel@tonic-gate slp = (struct valuelist *)malloc(sizeof(struct valuelist)); 10137c478bd9Sstevel@tonic-gate if (!slp) 10147c478bd9Sstevel@tonic-gate break; 10157c478bd9Sstevel@tonic-gate slp->name = strdup(pp->p_name); 10167c478bd9Sstevel@tonic-gate if (slp->name == NULL) { 10177c478bd9Sstevel@tonic-gate free(slp); 10187c478bd9Sstevel@tonic-gate break; 10197c478bd9Sstevel@tonic-gate } 1020*9525b14bSRao Shoaib slp->port = pp->p_proto; /*%< host byte order */ 10217c478bd9Sstevel@tonic-gate slp->next = protolist; 10227c478bd9Sstevel@tonic-gate slp->prev = NULL; 10237c478bd9Sstevel@tonic-gate if (protolist) 10247c478bd9Sstevel@tonic-gate protolist->prev = slp; 10257c478bd9Sstevel@tonic-gate protolist = slp; 10267c478bd9Sstevel@tonic-gate } 10277c478bd9Sstevel@tonic-gate endprotoent(); 10287c478bd9Sstevel@tonic-gate } 10297c478bd9Sstevel@tonic-gate 10307c478bd9Sstevel@tonic-gate void 10317c478bd9Sstevel@tonic-gate res_destroyprotolist(void) { 10327c478bd9Sstevel@tonic-gate struct valuelist *plp, *plp_next; 10337c478bd9Sstevel@tonic-gate 10347c478bd9Sstevel@tonic-gate for (plp = protolist; plp != NULL; plp = plp_next) { 10357c478bd9Sstevel@tonic-gate plp_next = plp->next; 10367c478bd9Sstevel@tonic-gate free(plp->name); 10377c478bd9Sstevel@tonic-gate free(plp); 10387c478bd9Sstevel@tonic-gate } 10397c478bd9Sstevel@tonic-gate protolist = (struct valuelist *)0; 10407c478bd9Sstevel@tonic-gate } 10417c478bd9Sstevel@tonic-gate 10427c478bd9Sstevel@tonic-gate static int 10437c478bd9Sstevel@tonic-gate findservice(const char *s, struct valuelist **list) { 10447c478bd9Sstevel@tonic-gate struct valuelist *lp = *list; 10457c478bd9Sstevel@tonic-gate int n; 10467c478bd9Sstevel@tonic-gate 10477c478bd9Sstevel@tonic-gate for (; lp != NULL; lp = lp->next) 10487c478bd9Sstevel@tonic-gate if (strcasecmp(lp->name, s) == 0) { 10497c478bd9Sstevel@tonic-gate if (lp != *list) { 10507c478bd9Sstevel@tonic-gate lp->prev->next = lp->next; 10517c478bd9Sstevel@tonic-gate if (lp->next) 10527c478bd9Sstevel@tonic-gate lp->next->prev = lp->prev; 10537c478bd9Sstevel@tonic-gate (*list)->prev = lp; 10547c478bd9Sstevel@tonic-gate lp->next = *list; 10557c478bd9Sstevel@tonic-gate *list = lp; 10567c478bd9Sstevel@tonic-gate } 1057*9525b14bSRao Shoaib return (lp->port); /*%< host byte order */ 10587c478bd9Sstevel@tonic-gate } 10597c478bd9Sstevel@tonic-gate if (sscanf(s, "%d", &n) != 1 || n <= 0) 10607c478bd9Sstevel@tonic-gate n = -1; 10617c478bd9Sstevel@tonic-gate return (n); 10627c478bd9Sstevel@tonic-gate } 10637c478bd9Sstevel@tonic-gate 1064*9525b14bSRao Shoaib /*% 10657c478bd9Sstevel@tonic-gate * Convert service name or (ascii) number to int. 10667c478bd9Sstevel@tonic-gate */ 10677c478bd9Sstevel@tonic-gate int 10687c478bd9Sstevel@tonic-gate res_servicenumber(const char *p) { 10697c478bd9Sstevel@tonic-gate if (servicelist == (struct valuelist *)0) 10707c478bd9Sstevel@tonic-gate res_buildservicelist(); 10717c478bd9Sstevel@tonic-gate return (findservice(p, &servicelist)); 10727c478bd9Sstevel@tonic-gate } 10737c478bd9Sstevel@tonic-gate 1074*9525b14bSRao Shoaib /*% 10757c478bd9Sstevel@tonic-gate * Convert protocol name or (ascii) number to int. 10767c478bd9Sstevel@tonic-gate */ 10777c478bd9Sstevel@tonic-gate int 10787c478bd9Sstevel@tonic-gate res_protocolnumber(const char *p) { 10797c478bd9Sstevel@tonic-gate if (protolist == (struct valuelist *)0) 10807c478bd9Sstevel@tonic-gate res_buildprotolist(); 10817c478bd9Sstevel@tonic-gate return (findservice(p, &protolist)); 10827c478bd9Sstevel@tonic-gate } 10837c478bd9Sstevel@tonic-gate 10847c478bd9Sstevel@tonic-gate static struct servent * 1085*9525b14bSRao Shoaib cgetservbyport(u_int16_t port, const char *proto) { /*%< Host byte order. */ 10867c478bd9Sstevel@tonic-gate struct valuelist **list = &servicelist; 10877c478bd9Sstevel@tonic-gate struct valuelist *lp = *list; 10887c478bd9Sstevel@tonic-gate static struct servent serv; 10897c478bd9Sstevel@tonic-gate 10907c478bd9Sstevel@tonic-gate port = ntohs(port); 10917c478bd9Sstevel@tonic-gate for (; lp != NULL; lp = lp->next) { 1092*9525b14bSRao Shoaib if (port != (u_int16_t)lp->port) /*%< Host byte order. */ 10937c478bd9Sstevel@tonic-gate continue; 10947c478bd9Sstevel@tonic-gate if (strcasecmp(lp->proto, proto) == 0) { 10957c478bd9Sstevel@tonic-gate if (lp != *list) { 10967c478bd9Sstevel@tonic-gate lp->prev->next = lp->next; 10977c478bd9Sstevel@tonic-gate if (lp->next) 10987c478bd9Sstevel@tonic-gate lp->next->prev = lp->prev; 10997c478bd9Sstevel@tonic-gate (*list)->prev = lp; 11007c478bd9Sstevel@tonic-gate lp->next = *list; 11017c478bd9Sstevel@tonic-gate *list = lp; 11027c478bd9Sstevel@tonic-gate } 11037c478bd9Sstevel@tonic-gate serv.s_name = lp->name; 11047c478bd9Sstevel@tonic-gate serv.s_port = htons((u_int16_t)lp->port); 11057c478bd9Sstevel@tonic-gate serv.s_proto = lp->proto; 11067c478bd9Sstevel@tonic-gate return (&serv); 11077c478bd9Sstevel@tonic-gate } 11087c478bd9Sstevel@tonic-gate } 11097c478bd9Sstevel@tonic-gate return (0); 11107c478bd9Sstevel@tonic-gate } 11117c478bd9Sstevel@tonic-gate 11127c478bd9Sstevel@tonic-gate static struct protoent * 1113*9525b14bSRao Shoaib cgetprotobynumber(int proto) { /*%< Host byte order. */ 11147c478bd9Sstevel@tonic-gate struct valuelist **list = &protolist; 11157c478bd9Sstevel@tonic-gate struct valuelist *lp = *list; 11167c478bd9Sstevel@tonic-gate static struct protoent prot; 11177c478bd9Sstevel@tonic-gate 11187c478bd9Sstevel@tonic-gate for (; lp != NULL; lp = lp->next) 1119*9525b14bSRao Shoaib if (lp->port == proto) { /*%< Host byte order. */ 11207c478bd9Sstevel@tonic-gate if (lp != *list) { 11217c478bd9Sstevel@tonic-gate lp->prev->next = lp->next; 11227c478bd9Sstevel@tonic-gate if (lp->next) 11237c478bd9Sstevel@tonic-gate lp->next->prev = lp->prev; 11247c478bd9Sstevel@tonic-gate (*list)->prev = lp; 11257c478bd9Sstevel@tonic-gate lp->next = *list; 11267c478bd9Sstevel@tonic-gate *list = lp; 11277c478bd9Sstevel@tonic-gate } 11287c478bd9Sstevel@tonic-gate prot.p_name = lp->name; 1129*9525b14bSRao Shoaib prot.p_proto = lp->port; /*%< Host byte order. */ 11307c478bd9Sstevel@tonic-gate return (&prot); 11317c478bd9Sstevel@tonic-gate } 11327c478bd9Sstevel@tonic-gate return (0); 11337c478bd9Sstevel@tonic-gate } 11347c478bd9Sstevel@tonic-gate 11357c478bd9Sstevel@tonic-gate const char * 11367c478bd9Sstevel@tonic-gate res_protocolname(int num) { 11377c478bd9Sstevel@tonic-gate static char number[8]; 11387c478bd9Sstevel@tonic-gate struct protoent *pp; 11397c478bd9Sstevel@tonic-gate 11407c478bd9Sstevel@tonic-gate if (protolist == (struct valuelist *)0) 11417c478bd9Sstevel@tonic-gate res_buildprotolist(); 11427c478bd9Sstevel@tonic-gate pp = cgetprotobynumber(num); 11437c478bd9Sstevel@tonic-gate if (pp == 0) { 11447c478bd9Sstevel@tonic-gate (void) sprintf(number, "%d", num); 11457c478bd9Sstevel@tonic-gate return (number); 11467c478bd9Sstevel@tonic-gate } 11477c478bd9Sstevel@tonic-gate return (pp->p_name); 11487c478bd9Sstevel@tonic-gate } 11497c478bd9Sstevel@tonic-gate 11507c478bd9Sstevel@tonic-gate const char * 1151*9525b14bSRao Shoaib res_servicename(u_int16_t port, const char *proto) { /*%< Host byte order. */ 11527c478bd9Sstevel@tonic-gate static char number[8]; 11537c478bd9Sstevel@tonic-gate struct servent *ss; 11547c478bd9Sstevel@tonic-gate 11557c478bd9Sstevel@tonic-gate if (servicelist == (struct valuelist *)0) 11567c478bd9Sstevel@tonic-gate res_buildservicelist(); 11577c478bd9Sstevel@tonic-gate ss = cgetservbyport(htons(port), proto); 11587c478bd9Sstevel@tonic-gate if (ss == 0) { 11597c478bd9Sstevel@tonic-gate (void) sprintf(number, "%d", port); 11607c478bd9Sstevel@tonic-gate return (number); 11617c478bd9Sstevel@tonic-gate } 11627c478bd9Sstevel@tonic-gate return (ss->s_name); 11637c478bd9Sstevel@tonic-gate } 1164