|
|
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 this notice is preserved and that due credit is given ! 7: * to the University of California at Berkeley. The name of the University ! 8: * may not be used to endorse or promote products derived from this ! 9: * software without specific prior written permission. This software ! 10: * is provided ``as is'' without express or implied warranty. ! 11: */ ! 12: ! 13: #if defined(LIBC_SCCS) && !defined(lint) ! 14: static char sccsid[] = "@(#)res_mkquery.c 6.7 (Berkeley) 3/7/88"; ! 15: #endif /* LIBC_SCCS and not lint */ ! 16: ! 17: #include <stdio.h> ! 18: #include <sys/types.h> ! 19: #include <netinet/in.h> ! 20: #include <arpa/nameser.h> ! 21: #include <resolv.h> ! 22: ! 23: /* ! 24: * Form all types of queries. ! 25: * Returns the size of the result or -1. ! 26: */ ! 27: res_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen) ! 28: int op; /* opcode of query */ ! 29: char *dname; /* domain name */ ! 30: int class, type; /* class and type of query */ ! 31: char *data; /* resource record data */ ! 32: int datalen; /* length of data */ ! 33: struct rrec *newrr; /* new rr for modify or append */ ! 34: char *buf; /* buffer to put query */ ! 35: int buflen; /* size of buffer */ ! 36: { ! 37: register HEADER *hp; ! 38: register char *cp; ! 39: register int n; ! 40: char dnbuf[MAXDNAME]; ! 41: char *dnptrs[10], **dpp, **lastdnptr; ! 42: extern char *index(); ! 43: ! 44: #ifdef DEBUG ! 45: if (_res.options & RES_DEBUG) ! 46: printf("res_mkquery(%d, %s, %d, %d)\n", op, dname, class, type); ! 47: #endif DEBUG ! 48: /* ! 49: * Initialize header fields. ! 50: */ ! 51: hp = (HEADER *) buf; ! 52: hp->id = htons(++_res.id); ! 53: hp->opcode = op; ! 54: hp->qr = hp->aa = hp->tc = hp->ra = 0; ! 55: hp->pr = (_res.options & RES_PRIMARY) != 0; ! 56: hp->rd = (_res.options & RES_RECURSE) != 0; ! 57: hp->rcode = NOERROR; ! 58: hp->qdcount = 0; ! 59: hp->ancount = 0; ! 60: hp->nscount = 0; ! 61: hp->arcount = 0; ! 62: cp = buf + sizeof(HEADER); ! 63: buflen -= sizeof(HEADER); ! 64: dpp = dnptrs; ! 65: *dpp++ = buf; ! 66: *dpp++ = NULL; ! 67: lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]); ! 68: /* ! 69: * If the domain name contains no dots (single label), then ! 70: * append the default domain name to the one given. ! 71: */ ! 72: if ((_res.options & RES_DEFNAMES) && dname != 0 && dname[0] != '\0' && ! 73: index(dname, '.') == NULL) { ! 74: if (!(_res.options & RES_INIT)) ! 75: if (res_init() == -1) ! 76: return(-1); ! 77: if (_res.defdname[0] != '\0') { ! 78: (void)sprintf(dnbuf, "%s.%s", dname, _res.defdname); ! 79: dname = dnbuf; ! 80: } ! 81: } ! 82: /* ! 83: * perform opcode specific processing ! 84: */ ! 85: switch (op) { ! 86: case QUERY: ! 87: buflen -= QFIXEDSZ; ! 88: if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) ! 89: return (-1); ! 90: cp += n; ! 91: buflen -= n; ! 92: putshort(type, cp); ! 93: cp += sizeof(u_short); ! 94: putshort(class, cp); ! 95: cp += sizeof(u_short); ! 96: hp->qdcount = htons(1); ! 97: if (op == QUERY || data == NULL) ! 98: break; ! 99: /* ! 100: * Make an additional record for completion domain. ! 101: */ ! 102: buflen -= RRFIXEDSZ; ! 103: if ((n = dn_comp(data, cp, buflen, dnptrs, lastdnptr)) < 0) ! 104: return (-1); ! 105: cp += n; ! 106: buflen -= n; ! 107: putshort(T_NULL, cp); ! 108: cp += sizeof(u_short); ! 109: putshort(class, cp); ! 110: cp += sizeof(u_short); ! 111: putlong(0, cp); ! 112: cp += sizeof(u_long); ! 113: putshort(0, cp); ! 114: cp += sizeof(u_short); ! 115: hp->arcount = htons(1); ! 116: break; ! 117: ! 118: case IQUERY: ! 119: /* ! 120: * Initialize answer section ! 121: */ ! 122: if (buflen < 1 + RRFIXEDSZ + datalen) ! 123: return (-1); ! 124: *cp++ = '\0'; /* no domain name */ ! 125: putshort(type, cp); ! 126: cp += sizeof(u_short); ! 127: putshort(class, cp); ! 128: cp += sizeof(u_short); ! 129: putlong(0, cp); ! 130: cp += sizeof(u_long); ! 131: putshort(datalen, cp); ! 132: cp += sizeof(u_short); ! 133: if (datalen) { ! 134: bcopy(data, cp, datalen); ! 135: cp += datalen; ! 136: } ! 137: hp->ancount = htons(1); ! 138: break; ! 139: ! 140: #ifdef ALLOW_UPDATES ! 141: /* ! 142: * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA ! 143: * (Record to be modified is followed by its replacement in msg.) ! 144: */ ! 145: case UPDATEM: ! 146: case UPDATEMA: ! 147: ! 148: case UPDATED: ! 149: /* ! 150: * The res code for UPDATED and UPDATEDA is the same; user ! 151: * calls them differently: specifies data for UPDATED; server ! 152: * ignores data if specified for UPDATEDA. ! 153: */ ! 154: case UPDATEDA: ! 155: buflen -= RRFIXEDSZ + datalen; ! 156: if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) ! 157: return (-1); ! 158: cp += n; ! 159: putshort(type, cp); ! 160: cp += sizeof(u_short); ! 161: putshort(class, cp); ! 162: cp += sizeof(u_short); ! 163: putlong(0, cp); ! 164: cp += sizeof(u_long); ! 165: putshort(datalen, cp); ! 166: cp += sizeof(u_short); ! 167: if (datalen) { ! 168: bcopy(data, cp, datalen); ! 169: cp += datalen; ! 170: } ! 171: if ( (op == UPDATED) || (op == UPDATEDA) ) { ! 172: hp->ancount = htons(0); ! 173: break; ! 174: } ! 175: /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */ ! 176: ! 177: case UPDATEA: /* Add new resource record */ ! 178: buflen -= RRFIXEDSZ + datalen; ! 179: if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) ! 180: return (-1); ! 181: cp += n; ! 182: putshort(newrr->r_type, cp); ! 183: cp += sizeof(u_short); ! 184: putshort(newrr->r_class, cp); ! 185: cp += sizeof(u_short); ! 186: putlong(0, cp); ! 187: cp += sizeof(u_long); ! 188: putshort(newrr->r_size, cp); ! 189: cp += sizeof(u_short); ! 190: if (newrr->r_size) { ! 191: bcopy(newrr->r_data, cp, newrr->r_size); ! 192: cp += newrr->r_size; ! 193: } ! 194: hp->ancount = htons(0); ! 195: break; ! 196: ! 197: #endif ALLOW_UPDATES ! 198: } ! 199: return (cp - buf); ! 200: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.