* Copyright (c) 1985 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid
[] = "@(#)send.c 5.10 (Berkeley) 1/28/89";
*******************************************************************************
* Routine to send request packets to a name server.
* Modified version of 4.3BSD BIND res_send.c 5.5 (Berkeley) 9/14/85
*******************************************************************************
#include <arpa/nameser.h>
* Initialize the socket address info struct.
static struct sockaddr_in sin
;
*******************************************************************************
* Sends a request packet to a name server whose address
* is specified by the first argument and returns with
* SUCCESS - the request was sent and an answer
* TIME_OUT - the virtual circuit connection timed-out
* or a reply to a datagram wasn't received.
*******************************************************************************
SendRequest(nsAddrPtr
, buf
, buflen
, answer
, anslen
, trueLenPtr
)
struct in_addr
*nsAddrPtr
;
int retry
, v_circuit
, resplen
;
HEADER
*requestPtr
= (HEADER
*) buf
;
HEADER
*answerPtr
= (HEADER
*) answer
;
if (_res
.options
& RES_DEBUG2
) {
printf("------------\nSendRequest(), len %d\n", buflen
);
Print_query(buf
, buf
+buflen
, 1);
* See if a virtual circuit is required or desired.
v_circuit
= (_res
.options
& RES_USEVC
) || buflen
> PACKETSZ
;
packetId
= requestPtr
->id
;
sin
.sin_family
= AF_INET
;
sin
.sin_port
= htons(NAMESERVER_PORT
);
sin
.sin_addr
= *nsAddrPtr
;
* Send request, RETRY times, or until successful
for (retry
= _res
.retry
; --retry
>= 0; ) {
sockFD
= socket(AF_INET
, SOCK_STREAM
, 0);
if (connect(sockFD
, &sin
, sizeof(sin
)) < 0) {
if (_res
.options
& RES_DEBUG
) {
if (write(sockFD
, &len
, sizeof(len
)) != sizeof(len
) ||
write(sockFD
, buf
, buflen
) != buflen
) {
if (_res
.options
& RES_DEBUG
) {
* Receive length & response
while(length
> 0 && (n
= read(sockFD
, cp
, length
)) > 0){
if (_res
.options
& RES_DEBUG
) {
resplen
= length
= ntohs(*(short *)cp
);
while(length
> 0 && (n
= read(sockFD
, cp
, length
)) > 0){
if (_res
.options
& RES_DEBUG
) {
sockFD
= socket(AF_INET
, SOCK_DGRAM
, 0);
if (sendto(sockFD
, buf
, buflen
, 0, &sin
,
sizeof(sin
)) != buflen
) {
perror("SendRequest: sendto");
timeout
.tv_sec
= _res
.retrans
;
n
= select(sockFD
+1, &dsmask
, 0, 0, &timeout
);
if (_res
.options
& RES_DEBUG
) {
perror("SendRequest: select");
if (_res
.options
& RES_DEBUG
) {
printf("Timeout %d\n", ++numTimeOuts
);
if ((resplen
= recv(sockFD
, answer
, anslen
, 0)) <= 0) {
if (_res
.options
& RES_DEBUG
) {
perror("SendRequest: recv");
if (packetId
!= answerPtr
->id
) {
* response from old query, ignore it
if (_res
.options
& RES_DEBUG2
) {
printf("------------\nOld answer:\n");
Print_query(answer
, answer
+resplen
, 1);
if (!(_res
.options
& RES_IGNTC
) && answerPtr
->tc
) {
if (_res
.options
& RES_DEBUG
) {
printf("truncated answer\n");
if (_res
.options
& RES_DEBUG
) {
if (_res
.options
& RES_DEBUG2
)
printf("------------\nGot answer (%d bytes):\n",
printf("------------\nGot answer:\n");
Print_query(answer
, answer
+resplen
, 1);