Annotation of 43BSDTahoe/lib/libc/net/res_mkquery.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.