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