* Copyright (c) 1982, 1986 The Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
"@(#) Copyright (c) 1982, 1986 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)query.c 5.13 (Berkeley) 4/16/91";
#include <protocols/routed.h>
#define WTIME 5 /* Time to wait for all responses */
#define STIME 500000 /* usec to wait for another response */
char packet
[MAXPACKETSIZE
];
int fromlen
= sizeof(from
), size
= 32*1024;
struct timeval shorttime
;
while ((ch
= getopt(argc
, argv
, "n")) != EOF
)
usage
: printf("usage: query [-n] hosts...\n");
s
= socket(AF_INET
, SOCK_DGRAM
, 0);
if (setsockopt(s
, SOL_SOCKET
, SO_RCVBUF
, &size
, sizeof(size
)) < 0)
perror("setsockopt SO_RCVBUF");
* Listen for returning packets;
* may be more than one packet per host.
bzero(&shorttime
, sizeof(shorttime
));
shorttime
.tv_usec
= STIME
;
signal(SIGALRM
, timeout
);
while ((count
> 0 && !timedout
) ||
select(20, (fd_set
*)&bits
, NULL
, NULL
, &shorttime
) > 0) {
cc
= recvfrom(s
, packet
, sizeof (packet
), 0,
exit (count
> 0 ? count
: 0);
struct sockaddr_in router
;
register struct rip
*msg
= (struct rip
*)packet
;
bzero((char *)&router
, sizeof (router
));
router
.sin_family
= AF_INET
;
router
.sin_addr
.s_addr
= inet_addr(host
);
if (router
.sin_addr
.s_addr
== -1) {
hp
= gethostbyname(host
);
fprintf(stderr
, "query: %s: ", host
);
bcopy(hp
->h_addr
, &router
.sin_addr
, hp
->h_length
);
sp
= getservbyname("router", "udp");
printf("udp/router: service unknown\n");
router
.sin_port
= sp
->s_port
;
msg
->rip_cmd
= RIPCMD_REQUEST
;
msg
->rip_vers
= RIPVERSION
;
msg
->rip_nets
[0].rip_dst
.sa_family
= htons(AF_UNSPEC
);
msg
->rip_nets
[0].rip_metric
= htonl(HOPCNT_INFINITY
);
if (sendto(s
, packet
, sizeof (struct rip
), 0,
(struct sockaddr
*)&router
, sizeof(router
)) < 0)
* Handle an incoming routing packet.
struct sockaddr_in
*from
;
register struct rip
*msg
= (struct rip
*)packet
;
register struct netinfo
*n
;
if (msg
->rip_cmd
!= RIPCMD_RESPONSE
)
printf("%d bytes from ", size
);
printf("%s:\n", inet_ntoa(from
->sin_addr
));
hp
= gethostbyaddr((char *)&from
->sin_addr
,
sizeof (struct in_addr
), AF_INET
);
name
= hp
== 0 ? "???" : hp
->h_name
;
printf("%s(%s):\n", name
, inet_ntoa(from
->sin_addr
));
if (size
< sizeof (struct netinfo
))
ntohs(n
->rip_dst
.sa_family
);
n
->rip_metric
= ntohl(n
->rip_metric
);
switch (n
->rip_dst
.sa_family
) {
{ register struct sockaddr_in
*sin
;
sin
= (struct sockaddr_in
*)&n
->rip_dst
;
net
= inet_netof(sin
->sin_addr
);
subnet
= inet_subnetof(sin
->sin_addr
);
lna
= inet_lnaof(sin
->sin_addr
);
if (sin
->sin_addr
.s_addr
== 0)
else if (lna
== INADDR_ANY
) {
np
= getnetbyaddr(net
, AF_INET
);
} else if ((lna
& 0xff) == 0 &&
(np
= getnetbyaddr(subnet
, AF_INET
))) {
struct in_addr subnaddr
, inet_makeaddr();
subnaddr
= inet_makeaddr(subnet
, INADDR_ANY
);
if (bcmp(&sin
->sin_addr
, &subnaddr
,
hp
= gethostbyaddr((char *)&sin
->sin_addr
,
sizeof (struct in_addr
), AF_INET
);
printf("\t%-17s metric %2d name %s\n",
inet_ntoa(sin
->sin_addr
), n
->rip_metric
, name
);
printf("\t%-17s metric %2d\n",
inet_ntoa(sin
->sin_addr
), n
->rip_metric
);
{ u_short
*p
= (u_short
*)n
->rip_dst
.sa_data
;
printf("\t(af %d) %x %x %x %x %x %x %x, metric %d\n",
p
[0], p
[1], p
[2], p
[3], p
[4], p
[5], p
[6],
size
-= sizeof (struct netinfo
), n
++;
* Return the possible subnetwork number from an internet address.
* SHOULD FIND OUT WHETHER THIS IS A LOCAL NETWORK BEFORE LOOKING
* INSIDE OF THE HOST PART. We can only believe this if we have other
* information (e.g., we can find a name for this number).
register u_long i
= ntohl(in
.s_addr
);
return ((i
& IN_CLASSB_NET
) >> IN_CLASSB_NSHIFT
);
return ((i
& IN_CLASSC_NET
) >> IN_CLASSC_NSHIFT
);
return ((i
& 0xffffffc0) >> 28);