Plan 9 from Bell Labs’s /usr/web/sources/contrib/steve/misc/maskquery.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/* icmp netmask request: useful but sadly appears to be widely blocked */
#include <u.h>
#include <libc.h>
#include <ctype.h>
#include <ip.h>
#include <bio.h>
#include <ndb.h>
#include "/sys/src/cmd/ip/icmp.h"

enum {
	IPV4MASK_LEN = 4
};

static int Timeout = 0;

static uchar loopbacknet[IPaddrlen] = {
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0xff, 0xff,
	127, 0, 0, 0
};
static uchar loopbackmask[IPaddrlen] = {
	0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff,
	0xff, 0, 0, 0
};

/*
 * find first ip addr suitable for proto and
 * that isn't the friggin loopback address.
 * deprecate link-local and multicast addresses.
 */
static int
myipvnaddr(uchar *ip, char *net)
{
	Ipifc *nifc;
	Iplifc *lifc;
	uchar mynet[IPaddrlen], linklocal[IPaddrlen];
	static Ipifc *ifc;

	ipmove(linklocal, IPnoaddr);
	ifc = readipifc(net, ifc, -1);
	for(nifc = ifc; nifc; nifc = nifc->next)
		for(lifc = nifc->lifc; lifc; lifc = lifc->next){
			maskip(lifc->ip, loopbackmask, mynet);
			if(ipcmp(mynet, loopbacknet) == 0)
				continue;
			if(ISIPV6MCAST(lifc->ip) || ISIPV6LINKLOCAL(lifc->ip)) {
				ipmove(linklocal, lifc->ip);
				continue;
			}
			if(ipcmp(lifc->ip, IPnoaddr) != 0){
				ipmove(ip, lifc->ip);
				return 0;
			}
		}
	/* no global unicast addrs found, fall back to link-local, if any */
	ipmove(ip, linklocal);
	return ipcmp(ip, IPnoaddr) == 0? -1: 0;
}

Icmphdr *
geticmp(void *v)
{
	char *p = v;

	return (Icmphdr *)(p + IPV4HDR_LEN);
}

static void
ding(void *a, char *msg)
{
	USED(a);
	if(strstr(msg, "alarm")){
		Timeout = 1;
		noted(NCONT);
	}
	else if(strstr(msg, "die"))
		exits("errors");
	else
		noted(NDFLT);
}

void
main(int argc, char *argv[])
{
	char *ds;
	int n, msglen, fd;
	Icmphdr *icmp;
	char buf[64*1024+512];
	uchar me[IPaddrlen], mev4[IPv4addrlen];

	ARGBEGIN{
	}ARGEND

	if(argc != 1){
		fprint(2, "usage: %s host\n", argv0);
		exits("usage");
	}

	ds = netmkaddr(argv[0], "icmp", "1");
	if((fd = dial(ds, 0, 0, 0)) == -1)
		sysfatal("dial(%s) failed - %r\n", argv[0]);

	icmp = geticmp(buf);
	msglen = IPV4HDR_LEN + ICMP_HDRSIZE + IPV4MASK_LEN;

	memset(buf, 0, msglen);
	icmp->type = AddrMaskRequest;
	icmp->code = 0;

	myipvnaddr(me, "/net");
	v6tov4(mev4, me);
	memmove(((Ip4hdr *)buf)->src, mev4, IPv4addrlen);
	memset(icmp->data, 0x5a, IPv4addrlen);

	notify(ding);
	alarm(2000);
	if(write(fd, buf, msglen) < msglen)
		sysfatal("write failed: %r\n");
	n = read(fd, buf, sizeof buf);
	if(Timeout)
		sysfatal("timeout\n");
	if(n < 0)
		sysfatal("read failed: %r\n");

	if(n < msglen)
		sysfatal("receive - bad length (%d != %d)\n", n, msglen);

	if(icmp->type != AddrMaskReply)
		sysfatal("%d!=%d bad reply message type\n", icmp->type, AddrMaskReply);

	print("%-48s %02x%02x%02x%02x\n",
		argv[0], icmp->data[0], icmp->data[1],
		icmp->data[2], icmp->data[3]);
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.