Annotation of 43BSDTahoe/etc/named/tools/nslookup/send.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: #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.