9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: erik quanstrom <quanstro@quanstro.net>
To: arisawa@ar.aichi-u.ac.jp, 9fans@9fans.net
Subject: Re: [9fans] bug or feature ?  --- ip/ping -6
Date: Sun,  3 Jan 2016 17:31:41 -0800	[thread overview]
Message-ID: <703dcf90537aeb1ea61012d823f833e5@mule> (raw)
In-Reply-To: <2F96B09F-7524-473A-B883-9A7B7DD09978@ar.aichi-u.ac.jp>

unfortunately, the simlification removes the code that solves an important
use case.  it's important to be able to specify the protocol or network stack,
such as in

	ip/ping /net.alt/icmp!someaddress

the diff is here and i'll be working on a patch.

the basic idea is to translate only the dns names to ip addresses, and then
reassemble the string.  this way we can keep any decorations such as /net.alt/icmpv6!...

- erik

---

lilly; diff -c `{yesterday -n20 /sys/src/cmd/ip/ping.c} /sys/src/cmd/ip/ping.c
/n/dump/2015/1214/sys/src/cmd/ip/ping.c:28,34 - /sys/src/cmd/ip/ping.c:28,34

  typedef struct {
  	int	version;
- 	char	*net;
+ 	char	*protoname;
  	int	echocmd;
  	int	echoreply;
  	unsigned iphdrsz;
/n/dump/2015/1214/sys/src/cmd/ip/ping.c:393,398 - /sys/src/cmd/ip/ping.c:393,401

  /* from /sys/src/libc/9sys/dial.c */

+ static char defnet[] = "/net";
+ static char defproto[] = "icmp";
+
  enum
  {
  	Maxstring	= 128,
/n/dump/2015/1214/sys/src/cmd/ip/ping.c:406,416 - /sys/src/cmd/ip/ping.c:409,414
  	char	*netdir;
  	char	*proto;
  	char	*rem;
-
- 	/* other args */
- 	char	*local;
- 	char	*dir;
- 	int	*cfdp;
  };

  /*
/n/dump/2015/1214/sys/src/cmd/ip/ping.c:417,423 - /sys/src/cmd/ip/ping.c:415,421
   *  parse a dial string
   */
  static void
- _dial_string_parse(char *str, DS *ds)
+ dsparse(char *str, char *defproto, DS *ds)
  {
  	char *p, *p2;

/n/dump/2015/1214/sys/src/cmd/ip/ping.c:425,437 - /sys/src/cmd/ip/ping.c:423,435
  	ds->buf[Maxstring-1] = 0;

  	p = strchr(ds->buf, '!');
- 	if(p == 0) {
- 		ds->netdir = 0;
- 		ds->proto = "net";
+ 	if(p == nil) {
+ 		ds->netdir = nil;
+ 		ds->proto = defproto;
  		ds->rem = ds->buf;
  	} else {
  		if(*ds->buf != '/' && *ds->buf != '#'){
- 			ds->netdir = 0;
+ 			ds->netdir = nil;
  			ds->proto = ds->buf;
  		} else {
  			for(p2 = p; *p2 != '/'; p2--)
/n/dump/2015/1214/sys/src/cmd/ip/ping.c:443,506 - /sys/src/cmd/ip/ping.c:441,560
  		*p = 0;
  		ds->rem = p + 1;
  	}
+ 	if(ds->netdir == nil || ds->netdir[0] == 0)
+ 		ds->netdir = defnet;
  }

  /* end excerpt from /sys/src/libc/9sys/dial.c */

- /* side effect: sets network & target */
- static int
- isv4name(char *name)
+ char*
+ dstopretty(DS *ds, char *name)
  {
- 	int r = 1;
- 	char *root, *ip, *pr;
+ 	char *port;
+
+ 	port = strchr(ds->rem, '!');
+ 	if(port == nil)
+ 		port = "";
+
+ 	if(ds->netdir == defnet)
+ 		return smprint("%s!%s%s", ds->proto, name, port);
+ 	else
+ 		return smprint("%s/%s!%s%s", ds->netdir, ds->proto, name, port);
+ }
+
+ char*
+ nametoip(char *name0, int *ipver, char **target, char **pretty)
+ {
+ 	int n,fd;
+ 	char buf[128], ip6[128], ip4[128], *cs, *s, *p, *name, *addr, *ip;
  	DS ds;

- 	_dial_string_parse(name, &ds);
+ 	*target = nil;
+ 	dsparse(name0, defproto, &ds);

- 	/* cope with leading /net.alt/icmp! and the like */
- 	root = nil;
- 	if (ds.netdir != nil) {
- 		pr = strrchr(ds.netdir, '/');
- 		if (pr == nil)
- 			pr = ds.netdir;
- 		else {
- 			*pr++ = '\0';
- 			root = ds.netdir;
- 			network = strdup(root);
+ 	/* do not override protocol specified */
+ 	if(*ipver == -1 && ds.proto != defproto){
+ 		if(strcmp(ds.proto, v4pr.protoname) == 0)
+ 			*ipver = 4;
+ 		else if (strcmp(ds.proto, v6pr.protoname) == 0)
+ 			*ipver = 6;
+ 	}
+
+ 	name = ds.rem;
+ 	ip6[0] = 0;
+ 	ip4[0] = 0;
+ 	if(isdottedquad(name)){
+ 		snprint(ip4, sizeof ip4, "%s", name);
+ 		goto match;
+ 	}
+ 	if(isv6lit(name)){
+ 		snprint(ip6, sizeof ip6, "%s", name);
+ 		goto match;
+ 	}
+
+
+ 	cs = smprint("%s/cs", ds.netdir);
+ 	fd = open(cs, ORDWR);
+ 	if(fd < 0)
+ 		sysfatal("cannot open %s: %r", cs);
+ 	free(cs);
+
+ 	addr = smprint("tcp!%s!1", name);
+ 	if(write(fd, addr, strlen(addr)) != strlen(addr)){
+ 		close(fd);
+ 		sysfatal("cannot write %s to %s: %r", addr, cs);
+ 	}
+ 	free(addr);
+ 	seek(fd, 0, 0);
+ 	while((n = read(fd, buf, sizeof(buf)-1)) > 0){
+ 		buf[n] = 0;
+ 		ip = strchr(buf,' ');
+ 		ip++;
+ 		p = strchr(ip,'!');
+ 		*p = 0;
+ 		if(isdottedquad(ip)){
+ 			if(ip4[0] == 0)
+ 				snprint(ip4, sizeof ip4, "%s", ip);
+ 		}else if(isv6lit(ip)){
+ 			if(ip6[0] == 0)
+ 				snprint(ip6, sizeof ip6, "%s", ip);
  		}
- 		if (strcmp(pr, v4pr.net) == 0)
- 			return 1;
- 		if (strcmp(pr, v6pr.net) == 0)
- 			return 0;
  	}
+ 	close(fd);

- 	/* if it's a literal, it's obvious from syntax which proto it is */
- 	free(target);
- 	target = strdup(ds.rem);
- 	if (isdottedquad(ds.rem))
- 		return 1;
- 	else if (isv6lit(ds.rem))
- 		return 0;
+ match:
+ 	s = nil;
+ 	if((*ipver == 4 || *ipver == -1) && ip4[0] != 0){
+ 		*ipver = 4;
+ 		s = ip4;
+ 	}else if((*ipver == 6 || *ipver == -1) && ip6[0] != 0){
+ 		*ipver = 6;
+ 		s = ip6;
+ 	}else if(*ipver == 6 && ip4[0] != 0)
+ 		s = ip4;
+ 	else if(ip4[0] != 0 || ip6[0] != 0)
+ 		werrstr("address %s does not match proto %d", ip4[0]? ip4: ip6, *ipver);

- 	/* map name to ip and look at its syntax */
- 	ip = csgetvalue(root, "sys", ds.rem, "ip", nil);
- 	if (ip == nil)
- 		ip = csgetvalue(root, "dom", ds.rem, "ip", nil);
- 	if (ip == nil)
- 		ip = csgetvalue(root, "sys", ds.rem, "ipv6", nil);
- 	if (ip == nil)
- 		ip = csgetvalue(root, "dom", ds.rem, "ipv6", nil);
- 	if (ip != nil)
- 		r = isv4name(ip);
- 	free(ip);
- 	return r;
+ 	if(s == nil || *ipver == -1){
+ 		*ipver = -1;
+ 		return nil;
+ 	}
+
+ 	/* fixup protocol if never specified */
+ 	if(*ipver == 6 && ds.proto == defproto)
+ 		ds.proto = v6pr.protoname;
+
+ 	*pretty = dstopretty(&ds, s);
+
+ 	*target = smprint("%s/%s!%s", ds.netdir, ds.proto, s);
+ 	return netmkaddr(*target, ds.netdir, "1");
  }

  void
  main(int argc, char **argv)
  {
- 	int fd, msglen, interval, nmsg;
- 	char *ds;
+ 	int fd, msglen, interval, nmsg, ipver;
+ 	char *ds, *pretty;

  	nsecfd = bintime(-1, nil, nil, nil);

/n/dump/2015/1214/sys/src/cmd/ip/ping.c:509,517 - /sys/src/cmd/ip/ping.c:563,573

  	msglen = interval = 0;
  	nmsg = MAXMSG;
+ 	ipver = -1;
  	ARGBEGIN {
+ 	case '4':
  	case '6':
- 		proto = &v6pr;
+ 		ipver = ARGC() - '0';
  		break;
  	case 'a':
  		addresses = 1;
/n/dump/2015/1214/sys/src/cmd/ip/ping.c:568,576 - /sys/src/cmd/ip/ping.c:624,636

  	notify(catch);

- 	if (!isv4name(argv[0]))
- 		proto = &v6pr;
- 	ds = netmkaddr(argv[0], proto->net, "1");
+ 	ds = nametoip(argv[0], &ipver, &target, &pretty);
+ 	if(ds == nil)
+ 		sysfatal("%s: nametoip: %r", argv0);
+ 	proto = ipver==4? &v4pr: &v6pr;
+
+ 	if(0)fprint(2, "ds %s\n", ds);
+
  	fd = dial(ds, 0, 0, 0);
  	if(fd < 0){
  		fprint(2, "%s: couldn't dial %s: %r\n", argv0, ds);
/n/dump/2015/1214/sys/src/cmd/ip/ping.c:579,590 - /sys/src/cmd/ip/ping.c:639,650

  	if (!quiet)
  		print("sending %d %d byte messages %d ms apart to %s\n",
- 			nmsg, msglen, interval, ds);
+ 			nmsg, msglen, interval, pretty);
+ 	free(pretty);

  	switch(rfork(RFPROC|RFMEM|RFFDG)){
  	case -1:
- 		fprint(2, "%s: can't fork: %r\n", argv0);
- 		/* fallthrough */
+ 		sysfatal("%s: can't fork: %r\n", argv0);
  	case 0:
  		rcvr(fd, msglen, interval, nmsg);
  		exits(0);



  parent reply	other threads:[~2016-01-04  1:31 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-28  9:04 arisawa
2015-12-29  0:10 ` Anthony Martin
2015-12-30 12:48 ` arisawa
2015-12-30 13:21   ` Charles Forsyth
2015-12-30 15:05   ` Steve Simon
2015-12-30 15:26     ` Kurt H Maier
2015-12-30 19:05       ` Steve Simon
2015-12-30 22:43         ` Kenny Lasse Hoff Levinsen
2015-12-30 23:36           ` Steve Simon
2015-12-31  0:16             ` Bakul Shah
2015-12-31  1:36           ` arisawa
2015-12-31  3:44         ` Dave Eckhardt
2016-01-02  1:12   ` erik quanstrom
2016-01-02  1:54     ` erik quanstrom
2016-01-03 19:58       ` hiro
2016-01-03 20:04         ` erik quanstrom
2016-01-03 20:31           ` erik quanstrom
2016-01-03 21:40             ` hiro
2016-01-03 21:43               ` hiro
2016-01-03 21:47               ` erik quanstrom
2016-01-04  1:31   ` erik quanstrom [this message]
2016-01-04 10:51     ` Anthony Martin
2016-01-04 13:04       ` erik quanstrom
2016-01-04 13:58         ` erik quanstrom

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=703dcf90537aeb1ea61012d823f833e5@mule \
    --to=quanstro@quanstro.net \
    --cc=9fans@9fans.net \
    --cc=arisawa@ar.aichi-u.ac.jp \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).