|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #if defined(LIBC_SCCS) && !defined(lint) ! 21: static char sccsid[] = "@(#)res_mkquery.c 6.12 (Berkeley) 6/1/90"; ! 22: #endif /* LIBC_SCCS and not lint */ ! 23: ! 24: #include <stdio.h> ! 25: #include <sys/types.h> ! 26: #include <netinet/in.h> ! 27: #include <arpa/nameser.h> ! 28: #include <resolv.h> ! 29: ! 30: /* ! 31: * Form all types of queries. ! 32: * Returns the size of the result or -1. ! 33: */ ! 34: res_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen) ! 35: int op; /* opcode of query */ ! 36: char *dname; /* domain name */ ! 37: int class, type; /* class and type of query */ ! 38: char *data; /* resource record data */ ! 39: int datalen; /* length of data */ ! 40: struct rrec *newrr; /* new rr for modify or append */ ! 41: char *buf; /* buffer to put query */ ! 42: int buflen; /* size of buffer */ ! 43: { ! 44: register HEADER *hp; ! 45: register char *cp; ! 46: register int n; ! 47: char *dnptrs[10], **dpp, **lastdnptr; ! 48: extern char *index(); ! 49: ! 50: #ifdef DEBUG ! 51: if (_res.options & RES_DEBUG) ! 52: printf("res_mkquery(%d, %s, %d, %d)\n", op, dname, class, type); ! 53: #endif DEBUG ! 54: /* ! 55: * Initialize header fields. ! 56: */ ! 57: if ((buf == NULL) || (buflen < sizeof(HEADER))) ! 58: return(-1); ! 59: bzero(buf, sizeof(HEADER)); ! 60: hp = (HEADER *) buf; ! 61: hp->id = htons(++_res.id); ! 62: hp->opcode = op; ! 63: hp->pr = (_res.options & RES_PRIMARY) != 0; ! 64: hp->rd = (_res.options & RES_RECURSE) != 0; ! 65: hp->rcode = NOERROR; ! 66: cp = buf + sizeof(HEADER); ! 67: buflen -= sizeof(HEADER); ! 68: dpp = dnptrs; ! 69: *dpp++ = buf; ! 70: *dpp++ = NULL; ! 71: lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]); ! 72: /* ! 73: * perform opcode specific processing ! 74: */ ! 75: switch (op) { ! 76: case QUERY: ! 77: if ((buflen -= QFIXEDSZ) < 0) ! 78: return(-1); ! 79: if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) ! 80: return (-1); ! 81: cp += n; ! 82: buflen -= n; ! 83: putshort(type, cp); ! 84: cp += sizeof(u_short); ! 85: putshort(class, cp); ! 86: cp += sizeof(u_short); ! 87: hp->qdcount = htons(1); ! 88: if (op == QUERY || data == NULL) ! 89: break; ! 90: /* ! 91: * Make an additional record for completion domain. ! 92: */ ! 93: buflen -= RRFIXEDSZ; ! 94: if ((n = dn_comp(data, cp, buflen, dnptrs, lastdnptr)) < 0) ! 95: return (-1); ! 96: cp += n; ! 97: buflen -= n; ! 98: putshort(T_NULL, cp); ! 99: cp += sizeof(u_short); ! 100: putshort(class, cp); ! 101: cp += sizeof(u_short); ! 102: putlong(0, cp); ! 103: cp += sizeof(u_long); ! 104: putshort(0, cp); ! 105: cp += sizeof(u_short); ! 106: hp->arcount = htons(1); ! 107: break; ! 108: ! 109: case IQUERY: ! 110: /* ! 111: * Initialize answer section ! 112: */ ! 113: if (buflen < 1 + RRFIXEDSZ + datalen) ! 114: return (-1); ! 115: *cp++ = '\0'; /* no domain name */ ! 116: putshort(type, cp); ! 117: cp += sizeof(u_short); ! 118: putshort(class, cp); ! 119: cp += sizeof(u_short); ! 120: putlong(0, cp); ! 121: cp += sizeof(u_long); ! 122: putshort(datalen, cp); ! 123: cp += sizeof(u_short); ! 124: if (datalen) { ! 125: bcopy(data, cp, datalen); ! 126: cp += datalen; ! 127: } ! 128: hp->ancount = htons(1); ! 129: break; ! 130: ! 131: #ifdef ALLOW_UPDATES ! 132: /* ! 133: * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA ! 134: * (Record to be modified is followed by its replacement in msg.) ! 135: */ ! 136: case UPDATEM: ! 137: case UPDATEMA: ! 138: ! 139: case UPDATED: ! 140: /* ! 141: * The res code for UPDATED and UPDATEDA is the same; user ! 142: * calls them differently: specifies data for UPDATED; server ! 143: * ignores data if specified for UPDATEDA. ! 144: */ ! 145: case UPDATEDA: ! 146: buflen -= RRFIXEDSZ + datalen; ! 147: if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) ! 148: return (-1); ! 149: cp += n; ! 150: putshort(type, cp); ! 151: cp += sizeof(u_short); ! 152: putshort(class, cp); ! 153: cp += sizeof(u_short); ! 154: putlong(0, cp); ! 155: cp += sizeof(u_long); ! 156: putshort(datalen, cp); ! 157: cp += sizeof(u_short); ! 158: if (datalen) { ! 159: bcopy(data, cp, datalen); ! 160: cp += datalen; ! 161: } ! 162: if ( (op == UPDATED) || (op == UPDATEDA) ) { ! 163: hp->ancount = htons(0); ! 164: break; ! 165: } ! 166: /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */ ! 167: ! 168: case UPDATEA: /* Add new resource record */ ! 169: buflen -= RRFIXEDSZ + datalen; ! 170: if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) ! 171: return (-1); ! 172: cp += n; ! 173: putshort(newrr->r_type, cp); ! 174: cp += sizeof(u_short); ! 175: putshort(newrr->r_class, cp); ! 176: cp += sizeof(u_short); ! 177: putlong(0, cp); ! 178: cp += sizeof(u_long); ! 179: putshort(newrr->r_size, cp); ! 180: cp += sizeof(u_short); ! 181: if (newrr->r_size) { ! 182: bcopy(newrr->r_data, cp, newrr->r_size); ! 183: cp += newrr->r_size; ! 184: } ! 185: hp->ancount = htons(0); ! 186: break; ! 187: ! 188: #endif ALLOW_UPDATES ! 189: } ! 190: return (cp - buf); ! 191: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.