Annotation of 43BSDTahoe/etc/named/tools/nslookup/send.c, revision 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: #ifndef lint
        !            14: static char sccsid[] = "@(#)send.c     5.6 (Berkeley) 2/17/88";
        !            15: #endif /* not lint */
        !            16: 
        !            17: /*
        !            18:  *******************************************************************************
        !            19:  *
        !            20:  *  send.c --
        !            21:  *
        !            22:  *     Routine to send request packets to a name server.
        !            23:  *
        !            24:  *     Modified version of 4.3BSD BIND  res_send.c 5.5 (Berkeley) 9/14/85
        !            25:  *
        !            26:  *******************************************************************************
        !            27:  */
        !            28: 
        !            29: #include <sys/types.h>
        !            30: #include <sys/time.h>
        !            31: #include <sys/socket.h>
        !            32: #include <netinet/in.h>
        !            33: #include <stdio.h>
        !            34: #include <arpa/nameser.h>
        !            35: #include <resolv.h>
        !            36: #include "res.h"
        !            37: 
        !            38: /*
        !            39:  *  Initialize the socket address info struct.
        !            40:  */
        !            41: 
        !            42: static struct sockaddr_in sin = { 
        !            43:     AF_INET,  
        !            44: };
        !            45: 
        !            46: 
        !            47: /*
        !            48:  *******************************************************************************
        !            49:  *
        !            50:  *   SendRequest --
        !            51:  *
        !            52:  *     Sends a request packet to a name server whose address
        !            53:  *     is specified by the first argument and returns with
        !            54:  *     the answer packet.
        !            55:  *
        !            56:  *  Results:
        !            57:  *     SUCCESS         - the request was sent and an answer 
        !            58:  *                       was received.
        !            59:  *     TIME_OUT        - the virtual circuit connection timed-out 
        !            60:  *                       or a reply to a datagram wasn't received.
        !            61:  *
        !            62:  *
        !            63:  *******************************************************************************
        !            64:  */
        !            65: 
        !            66: int
        !            67: SendRequest(nsAddrPtr, buf, buflen, answer, anslen, trueLenPtr, printanswer)
        !            68:        struct in_addr  *nsAddrPtr;
        !            69:        char            *buf;
        !            70:        int             buflen;
        !            71:        char            *answer;
        !            72:        int             anslen;
        !            73:        int             *trueLenPtr;
        !            74:        int             printanswer;
        !            75: {
        !            76:        struct timeval  timeout;
        !            77:        register int    n;
        !            78:        u_short         packetId, len;
        !            79:        short           length;
        !            80:        char            *cp;
        !            81:        int             retry, v_circuit, resplen;
        !            82:        int             dsmask;
        !            83: 
        !            84:        int             numTimeOuts     = 0;
        !            85:        HEADER          *requestPtr     = (HEADER *) buf;
        !            86:        HEADER          *answerPtr      = (HEADER *) answer;
        !            87: 
        !            88: 
        !            89:        if (_res.options & RES_DEBUG2) {
        !            90:            printf("------------\nSendRequest(), len %d\n", buflen);
        !            91:            Print_query(buf, buf+buflen, 1);
        !            92:        }
        !            93:        sockFD = -1;
        !            94: 
        !            95:        /*
        !            96:         * See if a virtual circuit is required or desired.
        !            97:         */
        !            98:        v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
        !            99: 
        !           100:        packetId = requestPtr->id;
        !           101: 
        !           102:        sin.sin_port    = htons(NAMESERVER_PORT);
        !           103:        sin.sin_addr    = *nsAddrPtr;
        !           104: 
        !           105:        /*
        !           106:         * Send request, RETRY times, or until successful
        !           107:         */
        !           108:        for (retry = _res.retry; --retry >= 0; ) {
        !           109:                if (v_circuit) {
        !           110:                        /*
        !           111:                         * Use virtual circuit.
        !           112:                         */
        !           113:                        if (sockFD < 0)
        !           114:                                sockFD = socket(AF_INET, SOCK_STREAM, 0);
        !           115: 
        !           116:                        if (connect(sockFD, &sin, sizeof(sin)) < 0) {
        !           117:                                if (_res.options & RES_DEBUG) {
        !           118:                                    perror("SendRequest");
        !           119:                                }
        !           120:                                (void) close(sockFD);
        !           121:                                sockFD = -1;
        !           122:                                continue;
        !           123:                        }
        !           124:                        /*
        !           125:                         * Send length & message
        !           126:                         */
        !           127:                        len = htons(buflen);
        !           128:                        if (write(sockFD, &len, sizeof(len)) != sizeof(len) ||
        !           129:                            write(sockFD, buf, buflen) != buflen) {
        !           130:                                if (_res.options & RES_DEBUG) {
        !           131:                                    perror("SendRequest");
        !           132:                                }
        !           133:                                (void) close(sockFD);
        !           134:                                sockFD = -1;
        !           135:                                continue;
        !           136:                        }
        !           137:                        /*
        !           138:                         * Receive length & response
        !           139:                         */
        !           140:                        cp = answer;
        !           141:                        length = sizeof(short);
        !           142:                        while(length > 0 && (n = read(sockFD, cp, length)) > 0){
        !           143:                                cp += n;
        !           144:                                length -= n;
        !           145:                        }
        !           146:                        if (n <= 0) {
        !           147:                                if (_res.options & RES_DEBUG) {
        !           148:                                    perror("SendRequest");
        !           149:                                }
        !           150:                                (void) close(sockFD);
        !           151:                                sockFD = -1;
        !           152:                                continue;
        !           153:                        }
        !           154:                        cp = answer;
        !           155:                        resplen = length = ntohs(*(short *)cp);
        !           156:                        while(length > 0 && (n = read(sockFD, cp, length)) > 0){
        !           157:                                cp += n;
        !           158:                                length -= n;
        !           159:                        }
        !           160:                        if (n <= 0) {
        !           161:                                if (_res.options & RES_DEBUG) {
        !           162:                                    perror("SendRequest");
        !           163:                                }
        !           164:                                (void) close(sockFD);
        !           165:                                sockFD = -1;
        !           166:                                continue;
        !           167:                        }
        !           168:                } else {
        !           169:                        /*
        !           170:                         * Use datagrams.
        !           171:                         */
        !           172:                        if (sockFD < 0)
        !           173:                                sockFD = socket(AF_INET, SOCK_DGRAM, 0);
        !           174: 
        !           175:                        if (sendto(sockFD, buf, buflen, 0, &sin,
        !           176:                            sizeof(sin)) != buflen) {
        !           177:                                if (_res.options & RES_DEBUG) {
        !           178:                                    perror("SendRequest");
        !           179:                                }
        !           180:                        }
        !           181:                        /*
        !           182:                         * Wait for reply 
        !           183:                         */
        !           184:                        timeout.tv_sec = _res.retrans;
        !           185:                        timeout.tv_usec = 0;
        !           186:                        dsmask = 1 << sockFD;
        !           187:                        n = select(sockFD+1, &dsmask, 0, 0, &timeout);
        !           188:                        if (n < 0) {
        !           189:                                if (_res.options & RES_DEBUG) {
        !           190:                                    perror("SendRequest");
        !           191:                                }
        !           192:                                continue;
        !           193:                        }
        !           194:                        if (n == 0) {
        !           195:                                /*
        !           196:                                 * timeout
        !           197:                                 */
        !           198:                                if (_res.options & RES_DEBUG) {
        !           199:                                    printf("Timeout %d\n", ++numTimeOuts);
        !           200:                                }
        !           201:                                continue;
        !           202:                        }
        !           203:                        if ((resplen = recv(sockFD, answer, anslen, 0)) <= 0) {
        !           204:                                if (_res.options & RES_DEBUG) {
        !           205:                                    perror("SendRequest");
        !           206:                                }
        !           207:                                continue;
        !           208:                        }
        !           209:                        if (packetId != answerPtr->id) {
        !           210:                                /*
        !           211:                                 * response from old query, ignore it
        !           212:                                 */
        !           213:                                if (_res.options & RES_DEBUG2) {
        !           214:                                        printf("------------\nOld answer:\n");
        !           215:                                        Print_query(answer, answer+resplen, 1);
        !           216:                                }
        !           217:                                continue;
        !           218:                        }
        !           219:                        if (!(_res.options & RES_IGNTC) && answerPtr->tc) {
        !           220:                                /*
        !           221:                                 * get rest of answer
        !           222:                                 */
        !           223:                                if (_res.options & RES_DEBUG) {
        !           224:                                        printf("truncated answer\n");
        !           225:                                }
        !           226:                                (void) close(sockFD);
        !           227:                                sockFD = -1;
        !           228:                                retry = _res.retry;
        !           229:                                v_circuit = 1;
        !           230:                                continue;
        !           231:                        }
        !           232:                }
        !           233:                if (_res.options & RES_DEBUG && printanswer) {
        !           234:                    if (_res.options & RES_DEBUG2)
        !           235:                        printf("------------\nGot answer (%d bytes):\n",
        !           236:                            resplen);
        !           237:                    else
        !           238:                        printf("------------\nGot answer:\n");
        !           239:                    Print_query(answer, answer+resplen, 1);
        !           240:                }
        !           241:                (void) close(sockFD);
        !           242:                sockFD = -1;
        !           243:                *trueLenPtr = resplen;
        !           244:                return (SUCCESS);
        !           245:        }
        !           246:        (void) close(sockFD);
        !           247:        sockFD = -1;
        !           248:        return (TIME_OUT);
        !           249: }

unix.superglobalmegacorp.com

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