9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] bug or feature ?  --- ip/ping -6
@ 2015-12-28  9:04 arisawa
  2015-12-29  0:10 ` Anthony Martin
  2015-12-30 12:48 ` arisawa
  0 siblings, 2 replies; 24+ messages in thread
From: arisawa @ 2015-12-28  9:04 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

hello 9fans,

I have once posted the message below to 9front mailing list.
however looking the origin of the problem, now I think better place is 9fans.

== message posted to 9front mailing list ==

I am feeling weird that ip/ping -6 does not ping to ipv6 address with /lib/ndb/local.

#	sys=io
#		ip=192.168.0.5
#		ip=2402:6b00:22cd:bf80::5
#
hebe% ip/ping -6a io
sending 32 64 byte messages 1000 ms apart to icmpv6!io!1
	2402:6b00:22cd:bf80::6 -> 192.168.0.5
0: 192.168.0.5 -> 192.168.0.6 rtt 104 µs, avg rtt 104 µs, ttl = 255
1: 192.168.0.5 -> 192.168.0.6 rtt 85 µs, avg rtt 94 µs, ttl = 255
2: 192.168.0.5 -> 192.168.0.6 rtt 85 µs, avg rtt 91 µs, ttl = 255
3: 192.168.0.5 -> 192.168.0.6 rtt 85 µs, avg rtt 89 µs, ttl = 255

this weirdness comes from the order of ip attributes.

#	sys=io
#		ip=2402:6b00:22cd:bf80::5
#		ip=192.168.0.5
#
hebe% ip/ping -6a io
sending 32 64 byte messages 1000 ms apart to icmpv6!io!1
	2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5
0: 2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6 rtt 102 µs, avg rtt 102 µs, ttl = 255
1: 2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6 rtt 88 µs, avg rtt 95 µs, ttl = 255
2: 2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6 rtt 84 µs, avg rtt 91 µs, ttl = 255
3: 2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6 rtt 104 µs, avg rtt 94 µs, ttl = 255

is this a feature or a bug?

Kenji Arisawa


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ?  --- ip/ping -6
  2015-12-28  9:04 [9fans] bug or feature ? --- ip/ping -6 arisawa
@ 2015-12-29  0:10 ` Anthony Martin
  2015-12-30 12:48 ` arisawa
  1 sibling, 0 replies; 24+ messages in thread
From: Anthony Martin @ 2015-12-29  0:10 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

arisawa <arisawa@ar.aichi-u.ac.jp> once said:
> is this a feature or a bug?

It looks like a bug to me. The code in

  /sys/src/cmd/ip/ping.c:/^isv4name

is too clever for it's own good.

  Anthony



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [9fans]  bug or feature ?  --- ip/ping -6
  2015-12-28  9:04 [9fans] bug or feature ? --- ip/ping -6 arisawa
  2015-12-29  0:10 ` Anthony Martin
@ 2015-12-30 12:48 ` arisawa
  2015-12-30 13:21   ` Charles Forsyth
                     ` (3 more replies)
  1 sibling, 4 replies; 24+ messages in thread
From: arisawa @ 2015-12-30 12:48 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

hello,

is the following output of ping reasonable enough?


io% 6.ping -an3 hebe
sending 3 64 byte messages 1000 ms apart to icmp!192.168.0.6!1
	192.168.0.5 -> 192.168.0.6
0: 192.168.0.6 -> 192.168.0.5 rtt 88 µs, avg rtt 88 µs, ttl = 255
1: 192.168.0.6 -> 192.168.0.5 rtt 83 µs, avg rtt 85 µs, ttl = 255
2: 192.168.0.6 -> 192.168.0.5 rtt 80 µs, avg rtt 83 µs, ttl = 255

io% 6.ping -an3 192.168.0.6
sending 3 64 byte messages 1000 ms apart to icmp!192.168.0.6!1
	192.168.0.5 -> 192.168.0.6
0: 192.168.0.6 -> 192.168.0.5 rtt 107 µs, avg rtt 107 µs, ttl = 255
1: 192.168.0.6 -> 192.168.0.5 rtt 84 µs, avg rtt 95 µs, ttl = 255
2: 192.168.0.6 -> 192.168.0.5 rtt 95 µs, avg rtt 95 µs, ttl = 255

io% 6.ping -an3 2402:6b00:22cd:bf80::6
sending 3 64 byte messages 1000 ms apart to icmpv6!2402:6b00:22cd:bf80::6!1
	2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6
0: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 103 µs, avg rtt 103 µs, ttl = 255
1: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 96 µs, avg rtt 99 µs, ttl = 255
2: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 83 µs, avg rtt 94 µs, ttl = 255

io% 6.ping -6an3 hebe
sending 3 64 byte messages 1000 ms apart to icmpv6!2402:6b00:22cd:bf80::6!1
	2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6
0: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 101 µs, avg rtt 101 µs, ttl = 255
1: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 82 µs, avg rtt 91 µs, ttl = 255
2: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 89 µs, avg rtt 90 µs, ttl = 255

io% 6.ping -6an3 192.168.0.6
sending 3 64 byte messages 1000 ms apart to icmp!192.168.0.6!1
	192.168.0.5 -> 192.168.0.6
0: 192.168.0.6 -> 192.168.0.5 rtt 90 µs, avg rtt 90 µs, ttl = 255
1: 192.168.0.6 -> 192.168.0.5 rtt 94 µs, avg rtt 92 µs, ttl = 255
2: 192.168.0.6 -> 192.168.0.5 rtt 90 µs, avg rtt 91 µs, ttl = 255

io% 6.ping -6an3 2402:6b00:22cd:bf80::6
sending 3 64 byte messages 1000 ms apart to icmpv6!2402:6b00:22cd:bf80::6!1
	2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6
0: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 101 µs, avg rtt 101 µs, ttl = 255
1: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 272 µs, avg rtt 186 µs, ttl = 255
2: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 102 µs, avg rtt 158 µs, ttl = 255

code is simplified.

io% ls -l
--rw-rw-r-- M 327 arisawa arisawa  9942 Dec 30 21:27 ping.c
--rw-rw-r-- M 327 arisawa arisawa 10943 Dec 28 15:59 ping.c.orig
io% 

Kenji Arisawa



> 2015/12/28 18:04、arisawa <arisawa@ar.aichi-u.ac.jp> のメール:
> 
> hello 9fans,
> 
> I have once posted the message below to 9front mailing list.
> however looking the origin of the problem, now I think better place is 9fans.
> 
> == message posted to 9front mailing list ==
> 
> I am feeling weird that ip/ping -6 does not ping to ipv6 address with /lib/ndb/local.
> 
> #	sys=io
> #		ip=192.168.0.5
> #		ip=2402:6b00:22cd:bf80::5
> #
> hebe% ip/ping -6a io
> sending 32 64 byte messages 1000 ms apart to icmpv6!io!1
> 	2402:6b00:22cd:bf80::6 -> 192.168.0.5
> 0: 192.168.0.5 -> 192.168.0.6 rtt 104 µs, avg rtt 104 µs, ttl = 255
> 1: 192.168.0.5 -> 192.168.0.6 rtt 85 µs, avg rtt 94 µs, ttl = 255
> 2: 192.168.0.5 -> 192.168.0.6 rtt 85 µs, avg rtt 91 µs, ttl = 255
> 3: 192.168.0.5 -> 192.168.0.6 rtt 85 µs, avg rtt 89 µs, ttl = 255
> 
> this weirdness comes from the order of ip attributes.
> 
> #	sys=io
> #		ip=2402:6b00:22cd:bf80::5
> #		ip=192.168.0.5
> #
> hebe% ip/ping -6a io
> sending 32 64 byte messages 1000 ms apart to icmpv6!io!1
> 	2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5
> 0: 2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6 rtt 102 µs, avg rtt 102 µs, ttl = 255
> 1: 2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6 rtt 88 µs, avg rtt 95 µs, ttl = 255
> 2: 2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6 rtt 84 µs, avg rtt 91 µs, ttl = 255
> 3: 2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6 rtt 104 µs, avg rtt 94 µs, ttl = 255
> 
> is this a feature or a bug?
> 
> Kenji Arisawa




^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ? --- ip/ping -6
  2015-12-30 12:48 ` arisawa
@ 2015-12-30 13:21   ` Charles Forsyth
  2015-12-30 15:05   ` Steve Simon
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 24+ messages in thread
From: Charles Forsyth @ 2015-12-30 13:21 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 174 bytes --]

On 30 December 2015 at 12:48, arisawa <arisawa@ar.aichi-u.ac.jp> wrote:

> code is simplified.


It works better, but it's smaller? With luck, you might start a trend!

[-- Attachment #2: Type: text/html, Size: 467 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ?  --- ip/ping -6
  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
  2016-01-02  1:12   ` erik quanstrom
  2016-01-04  1:31   ` erik quanstrom
  3 siblings, 1 reply; 24+ messages in thread
From: Steve Simon @ 2015-12-30 15:05 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

If I where redesigning ping I wouldn't repeat any info that is common on each line - I.e. ip addresses or the column titles: rtt, ave etc.

consider plan9's ps(1) which has no column titles. they are described in the man page and are obvious from the context once you have read the man page once.

Having said this, I understand that tradition is also a strong guiding principal.

-Steve

> On 30 Dec 2015, at 12:48, arisawa <arisawa@ar.aichi-u.ac.jp> wrote:
> 
> hello,
> 
> is the following output of ping reasonable enough?
> 
> 
> io% 6.ping -an3 hebe
> sending 3 64 byte messages 1000 ms apart to icmp!192.168.0.6!1
>    192.168.0.5 -> 192.168.0.6
> 0: 192.168.0.6 -> 192.168.0.5 rtt 88 µs, avg rtt 88 µs, ttl = 255
> 1: 192.168.0.6 -> 192.168.0.5 rtt 83 µs, avg rtt 85 µs, ttl = 255
> 2: 192.168.0.6 -> 192.168.0.5 rtt 80 µs, avg rtt 83 µs, ttl = 255
> 
> io% 6.ping -an3 192.168.0.6
> sending 3 64 byte messages 1000 ms apart to icmp!192.168.0.6!1
>    192.168.0.5 -> 192.168.0.6
> 0: 192.168.0.6 -> 192.168.0.5 rtt 107 µs, avg rtt 107 µs, ttl = 255
> 1: 192.168.0.6 -> 192.168.0.5 rtt 84 µs, avg rtt 95 µs, ttl = 255
> 2: 192.168.0.6 -> 192.168.0.5 rtt 95 µs, avg rtt 95 µs, ttl = 255
> 
> io% 6.ping -an3 2402:6b00:22cd:bf80::6
> sending 3 64 byte messages 1000 ms apart to icmpv6!2402:6b00:22cd:bf80::6!1
>    2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6
> 0: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 103 µs, avg rtt 103 µs, ttl = 255
> 1: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 96 µs, avg rtt 99 µs, ttl = 255
> 2: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 83 µs, avg rtt 94 µs, ttl = 255
> 
> io% 6.ping -6an3 hebe
> sending 3 64 byte messages 1000 ms apart to icmpv6!2402:6b00:22cd:bf80::6!1
>    2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6
> 0: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 101 µs, avg rtt 101 µs, ttl = 255
> 1: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 82 µs, avg rtt 91 µs, ttl = 255
> 2: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 89 µs, avg rtt 90 µs, ttl = 255
> 
> io% 6.ping -6an3 192.168.0.6
> sending 3 64 byte messages 1000 ms apart to icmp!192.168.0.6!1
>    192.168.0.5 -> 192.168.0.6
> 0: 192.168.0.6 -> 192.168.0.5 rtt 90 µs, avg rtt 90 µs, ttl = 255
> 1: 192.168.0.6 -> 192.168.0.5 rtt 94 µs, avg rtt 92 µs, ttl = 255
> 2: 192.168.0.6 -> 192.168.0.5 rtt 90 µs, avg rtt 91 µs, ttl = 255
> 
> io% 6.ping -6an3 2402:6b00:22cd:bf80::6
> sending 3 64 byte messages 1000 ms apart to icmpv6!2402:6b00:22cd:bf80::6!1
>    2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6
> 0: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 101 µs, avg rtt 101 µs, ttl = 255
> 1: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 272 µs, avg rtt 186 µs, ttl = 255
> 2: 2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5 rtt 102 µs, avg rtt 158 µs, ttl = 255
> 
> code is simplified.
> 
> io% ls -l
> --rw-rw-r-- M 327 arisawa arisawa  9942 Dec 30 21:27 ping.c
> --rw-rw-r-- M 327 arisawa arisawa 10943 Dec 28 15:59 ping.c.orig
> io% 
> 
> Kenji Arisawa
> 
> 
> 
>> 2015/12/28 18:04、arisawa <arisawa@ar.aichi-u.ac.jp> のメール:
>> 
>> hello 9fans,
>> 
>> I have once posted the message below to 9front mailing list.
>> however looking the origin of the problem, now I think better place is 9fans.
>> 
>> == message posted to 9front mailing list ==
>> 
>> I am feeling weird that ip/ping -6 does not ping to ipv6 address with /lib/ndb/local.
>> 
>> #    sys=io
>> #        ip=192.168.0.5
>> #        ip=2402:6b00:22cd:bf80::5
>> #
>> hebe% ip/ping -6a io
>> sending 32 64 byte messages 1000 ms apart to icmpv6!io!1
>>    2402:6b00:22cd:bf80::6 -> 192.168.0.5
>> 0: 192.168.0.5 -> 192.168.0.6 rtt 104 µs, avg rtt 104 µs, ttl = 255
>> 1: 192.168.0.5 -> 192.168.0.6 rtt 85 µs, avg rtt 94 µs, ttl = 255
>> 2: 192.168.0.5 -> 192.168.0.6 rtt 85 µs, avg rtt 91 µs, ttl = 255
>> 3: 192.168.0.5 -> 192.168.0.6 rtt 85 µs, avg rtt 89 µs, ttl = 255
>> 
>> this weirdness comes from the order of ip attributes.
>> 
>> #    sys=io
>> #        ip=2402:6b00:22cd:bf80::5
>> #        ip=192.168.0.5
>> #
>> hebe% ip/ping -6a io
>> sending 32 64 byte messages 1000 ms apart to icmpv6!io!1
>>    2402:6b00:22cd:bf80::6 -> 2402:6b00:22cd:bf80::5
>> 0: 2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6 rtt 102 µs, avg rtt 102 µs, ttl = 255
>> 1: 2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6 rtt 88 µs, avg rtt 95 µs, ttl = 255
>> 2: 2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6 rtt 84 µs, avg rtt 91 µs, ttl = 255
>> 3: 2402:6b00:22cd:bf80::5 -> 2402:6b00:22cd:bf80::6 rtt 104 µs, avg rtt 94 µs, ttl = 255
>> 
>> is this a feature or a bug?
>> 
>> Kenji Arisawa
> 



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ?  --- ip/ping -6
  2015-12-30 15:05   ` Steve Simon
@ 2015-12-30 15:26     ` Kurt H Maier
  2015-12-30 19:05       ` Steve Simon
  0 siblings, 1 reply; 24+ messages in thread
From: Kurt H Maier @ 2015-12-30 15:26 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

On Wed, Dec 30, 2015 at 03:05:33PM +0000, Steve Simon wrote:
> If I where redesigning ping I wouldn't repeat any info that is common on each line - I.e. ip addresses or the column titles: rtt, ave etc.
>
> consider plan9's ps(1) which has no column titles. they are described in the man page and are obvious from the context once you have read the man page once.
>
> Having said this, I understand that tradition is also a strong guiding principal.
>
> -Steve

I have no opinion on the labeling, but dropping the IPs from the output
would make this tool useless for logging data.

khm



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ?  --- ip/ping -6
  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-31  3:44         ` Dave Eckhardt
  0 siblings, 2 replies; 24+ messages in thread
From: Steve Simon @ 2015-12-30 19:05 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

I would display the IP address once only, rather on every line; as it is a common factor.

-Steve


> On 30 Dec 2015, at 15:26, Kurt H Maier <khm@sciops.net> wrote:
> 
>> On Wed, Dec 30, 2015 at 03:05:33PM +0000, Steve Simon wrote:
>> If I where redesigning ping I wouldn't repeat any info that is common on each line - I.e. ip addresses or the column titles: rtt, ave etc.
>> 
>> consider plan9's ps(1) which has no column titles. they are described in the man page and are obvious from the context once you have read the man page once.
>> 
>> Having said this, I understand that tradition is also a strong guiding principal.
>> 
>> -Steve
> 
> I have no opinion on the labeling, but dropping the IPs from the output
> would make this tool useless for logging data.
> 
> khm



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ?  --- ip/ping -6
  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  1:36           ` arisawa
  2015-12-31  3:44         ` Dave Eckhardt
  1 sibling, 2 replies; 24+ messages in thread
From: Kenny Lasse Hoff Levinsen @ 2015-12-30 22:43 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

It is not a common factor if you ping broadcast. That is, the local address is common, the remote is not.

joushou

> On 30 Dec 2015, at 20:05, Steve Simon <steve@quintile.net> wrote:
> 
> I would display the IP address once only, rather on every line; as it is a common factor.
> 
> -Steve
> 
> 
>> On 30 Dec 2015, at 15:26, Kurt H Maier <khm@sciops.net> wrote:
>> 
>>> On Wed, Dec 30, 2015 at 03:05:33PM +0000, Steve Simon wrote:
>>> If I where redesigning ping I wouldn't repeat any info that is common on each line - I.e. ip addresses or the column titles: rtt, ave etc.
>>> 
>>> consider plan9's ps(1) which has no column titles. they are described in the man page and are obvious from the context once you have read the man page once.
>>> 
>>> Having said this, I understand that tradition is also a strong guiding principal.
>>> 
>>> -Steve
>> 
>> I have no opinion on the labeling, but dropping the IPs from the output
>> would make this tool useless for logging data.
>> 
>> khm
> 




^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ?  --- ip/ping -6
  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
  1 sibling, 1 reply; 24+ messages in thread
From: Steve Simon @ 2015-12-30 23:36 UTC (permalink / raw)
  To: 9fans

> It is not a common factor if you ping broadcast.

Yep, fair point.

I admit I have never done a ping broadcast.

I did hear a story of somone who (in the early days of ethernet)
built a ping broadcast packet, with the source address of the broadcast address.

This resulted in the mother of all packet storms.

Maybe apocryphal, but a nice story none the less.

-Steve



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ? --- ip/ping -6
  2015-12-30 23:36           ` Steve Simon
@ 2015-12-31  0:16             ` Bakul Shah
  0 siblings, 0 replies; 24+ messages in thread
From: Bakul Shah @ 2015-12-31  0:16 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

On Wed, 30 Dec 2015 23:36:22 GMT "Steve Simon" <steve@quintile.net> wrote:
> > It is not a common factor if you ping broadcast.
>
> Yep, fair point.

If you're pinging plan9 machines, printing source address is
not useful as they sebd ping replies with source = broadcast
ip address.  You have to look at the source ether addr to find
out which machine responded.

> I admit I have never done a ping broadcast.
>
> I did hear a story of somone who (in the early days of ethernet)
> built a ping broadcast packet, with the source address of the broadcast addre
> ss.
>
> This resulted in the mother of all packet storms.
>
> Maybe apocryphal, but a nice story none the less.

Seems apocryphal or must've been very early days!  Ping
consists of sending an ICMP request packet, followed by the
responder(s) sending back ICMP reply packat(s).  No ICMP
errors are sent in response to any ICMP message to avoid just
such a storm.

Ages ago you could send a *directed* broadcast to a place far
away, which would get routed to the right subnet and many or
all machines on that subnet would respond.  Back then the 'Net
was a friendlier place and people didn't use NAT and script
kiddies were rather rare. All that changed a couple decades
ago.



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ?  --- ip/ping -6
  2015-12-30 22:43         ` Kenny Lasse Hoff Levinsen
  2015-12-30 23:36           ` Steve Simon
@ 2015-12-31  1:36           ` arisawa
  1 sibling, 0 replies; 24+ messages in thread
From: arisawa @ 2015-12-31  1:36 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

[-- Attachment #1: Type: text/plain, Size: 170 bytes --]

hello,

I did nothing about original ping options, so they should work as they have been.
I am afraid I have removed too much.
the new ping is here. test, please.


[-- Attachment #2: ping.c --]
[-- Type: application/octet-stream, Size: 10501 bytes --]

/* ping for ip v4 and v6 */
#include <u.h>
#include <libc.h>
#include <ctype.h>
#include <ip.h>
#include <bio.h>
#include <ndb.h>
#include "icmp.h"

enum {
	MAXMSG		= 32,
	SLEEPMS		= 1000,

	SECOND		= 1000000000LL,
	MINUTE		= 60*SECOND,
};

typedef struct Req Req;
struct Req
{
	ushort	seq;	/* sequence number */
	vlong	time;	/* time sent */
	vlong	rtt;
	int	ttl;
	int	replied;
	Req	 *next;
};

typedef struct {
	int	version;
	char	*net;
	int	echocmd;
	int	echoreply;
	unsigned iphdrsz;

	void	(*prreply)(Req *r, void *v);
	void	(*prlost)(ushort seq, void *v);
} Proto;


Req	*first;		/* request list */
Req	*last;		/* ... */
Lock	listlock;

char *argv0;

int addresses;
int debug;
int done;
int flood;
int lostmsgs;
int lostonly;
int quiet;
int rcvdmsgs;
int rint;
ushort firstseq;
vlong sum;
int waittime = 5000;

static char *network, *target;

void lost(Req*, void*);
void reply(Req*, void*);

static void
usage(void)
{
	fprint(2,
	    "usage: %s [-6alq] [-s msgsize] [-i millisecs] [-n #pings] dest\n",
		argv0);
	exits("usage");
}

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

static void
prlost4(ushort seq, void *v)
{
	Ip4hdr *ip4 = v;

	print("lost %ud: %V -> %V\n", seq, ip4->src, ip4->dst);
}

static void
prlost6(ushort seq, void *v)
{
	Ip6hdr *ip6 = v;

	print("lost %ud: %I -> %I\n", seq, ip6->src, ip6->dst);
}

static void
prreply4(Req *r, void *v)
{
	Ip4hdr *ip4 = v;

	print("%ud: %V -> %V rtt %lld µs, avg rtt %lld µs, ttl = %d\n",
		r->seq - firstseq, ip4->src, ip4->dst, r->rtt, sum/rcvdmsgs,
		r->ttl);
}

static void
prreply6(Req *r, void *v)
{
	Ip6hdr *ip6 = v;

	print("%ud: %I -> %I rtt %lld µs, avg rtt %lld µs, ttl = %d\n",
		r->seq - firstseq, ip6->src, ip6->dst, r->rtt, sum/rcvdmsgs,
		r->ttl);
}

static Proto v4pr = {
	4,		"icmp",
	EchoRequest,	EchoReply,
	IPV4HDR_LEN,
	prreply4,	prlost4,
};
static Proto v6pr = {
	6,		"icmpv6",
	EchoRequestV6,	EchoReplyV6,
	IPV6HDR_LEN,
	prreply6,	prlost6,
};

static Proto *proto = &v4pr;


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

	return (Icmphdr *)(p + proto->iphdrsz);
}

void
clean(ushort seq, vlong now, void *v)
{
	int ttl;
	Req **l, *r;

	ttl = 0;
	if (v) {
		if (proto->version == 4)
			ttl = ((Ip4hdr *)v)->ttl;
		else
			ttl = ((Ip6hdr *)v)->ttl;
	}
	lock(&listlock);
	last = nil;
	for(l = &first; *l; ){
		r = *l;

		if(v && r->seq == seq){
			r->rtt = now-r->time;
			r->ttl = ttl;
			reply(r, v);
		}

		if(now-r->time > MINUTE){
			*l = r->next;
			r->rtt = now-r->time;
			if(v)
				r->ttl = ttl;
			if(r->replied == 0)
				lost(r, v);
			free(r);
		}else{
			last = r;
			l = &r->next;
		}
	}
	unlock(&listlock);
}

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, Proto *proto, char *net)
{
	int ipisv4, wantv4;
	Ipifc *nifc;
	Iplifc *lifc;
	uchar mynet[IPaddrlen], linklocal[IPaddrlen];
	static Ipifc *ifc;

	ipmove(linklocal, IPnoaddr);
	wantv4 = proto->version == 4;
	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;
			}
			ipisv4 = isv4(lifc->ip) != 0;
			if(ipcmp(lifc->ip, IPnoaddr) != 0 && wantv4 == ipisv4){
				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;
}

void
sender(int fd, int msglen, int interval, int n)
{
	int i, extra;
	ushort seq;
	char buf[64*1024+512];
	uchar me[IPaddrlen], mev4[IPv4addrlen];
	Icmphdr *icmp;
	Req *r;

	srand(time(0));
	firstseq = seq = rand();

	icmp = geticmp(buf);
	memset(buf, 0, proto->iphdrsz + ICMP_HDRSIZE);
	for(i = proto->iphdrsz + ICMP_HDRSIZE; i < msglen; i++)
		buf[i] = i;
	icmp->type = proto->echocmd;
	icmp->code = 0;

	/* arguably the kernel should fill in the right src addr. */
	myipvnaddr(me, proto, network);
	if (proto->version == 4) {
		v6tov4(mev4, me);
		memmove(((Ip4hdr *)buf)->src, mev4, IPv4addrlen);
	} else
		ipmove(((Ip6hdr *)buf)->src, me);
	if (addresses)
		print("\t%I -> %s\n", me, target);

	if(rint != 0 && interval <= 0)
		rint = 0;
	extra = 0;
	for(i = 0; i < n; i++){
		if(i != 0){
			if(rint != 0)
				extra = nrand(interval);
			sleep(interval + extra);
		}
		r = malloc(sizeof *r);
		if (r == nil)
			continue;
		hnputs(icmp->seq, seq);
		r->seq = seq;
		r->next = nil;
		r->replied = 0;
		r->time = nsec();	/* avoid early free in reply! */
		lock(&listlock);
		if(first == nil)
			first = r;
		else
			last->next = r;
		last = r;
		unlock(&listlock);
		r->time = nsec();
		if(write(fd, buf, msglen) < msglen){
			fprint(2, "%s: write failed: %r\n", argv0);
			return;
		}
		seq++;
	}
	done = 1;
}

void
rcvr(int fd, int msglen, int interval, int nmsg)
{
	int i, n, munged;
	ushort x;
	vlong now;
	char err[ERRMAX];
	uchar buf[64*1024+512];
	Icmphdr *icmp;
	Req *r;

	sum = 0;
	while(lostmsgs+rcvdmsgs < nmsg){
		alarm((nmsg-lostmsgs-rcvdmsgs)*interval+waittime);
		n = read(fd, buf, sizeof buf);
		alarm(0);
		if(n == 0)
			strcpy(err, "got eof");
		else if(n < 0)
			rerrstr(err, sizeof(err));
		now = nsec();
		if(n <= 0){
			print("%s\n", err);
			clean(0, now+MINUTE, nil);
			if(strstr(err, "interrupted") == nil)
				sleep(waittime);
			continue;
		}
		if(n < msglen){
			print("bad len %d/%d\n", n, msglen);
			continue;
		}
		icmp = geticmp(buf);
		munged = 0;
		for(i = proto->iphdrsz + ICMP_HDRSIZE; i < msglen; i++)
			if(buf[i] != (uchar)i)
				munged++;
		if(munged)
			print("corrupted reply\n");
		x = nhgets(icmp->seq);
		if(icmp->type != proto->echoreply || icmp->code != 0) {
			print("bad type/code/sequence %d/%d/%d (want %d/%d/%d)\n",
				icmp->type, icmp->code, x,
				proto->echoreply, 0, x);
			continue;
		}
		clean(x, now, buf);
	}

	lock(&listlock);
	for(r = first; r; r = r->next)
		if(r->replied == 0)
			lostmsgs++;
	unlock(&listlock);

	if(!quiet && lostmsgs)
		print("%d out of %d messages lost\n", lostmsgs,
			lostmsgs+rcvdmsgs);
}

static int
isdottedquad(char *name)
{
	int dot = 0, digit = 0;

	for (; *name != '\0'; name++)
		if (*name == '.')
			dot++;
		else if (isdigit(*name))
			digit++;
		else
			return 0;
	return dot && digit;
}

static int
isv6lit(char *name)
{
	int colon = 0, hex = 0;

	for (; *name != '\0'; name++)
		if (*name == ':')
			colon++;
		else if (isxdigit(*name))
			hex++;
		else
			return 0;
	return colon;
}

char *
nametoip(char *cs, char *name, int ipver)
{
	int n,fd;
	char buf[128], *p, *addr, *ip;

	if(isdottedquad(name) || isv6lit(name))
		return strdup(name);
	if(cs == nil)
		cs = "/net/cs";
	fd = open(cs, ORDWR);
	if(fd < 0)
		sysfatal("cannot open %s: %r", 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(ipver == 4 && isdottedquad(ip)){
			close(fd);
			return strdup(ip);
		}
		if(ipver == 6 && isv6lit(ip)){
			close(fd);
			return strdup(ip);
		}
	}
	close(fd);
	return nil;
}

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

	nsec();		/* make sure time file is already open */

	fmtinstall('V', eipfmt);
	fmtinstall('I', eipfmt);

	msglen = interval = 0;
	nmsg = MAXMSG;
	ARGBEGIN {
	case '6':
		proto = &v6pr;
		break;
	case 'a':
		addresses = 1;
		break;
	case 'd':
		debug++;
		break;
	case 'f':
		flood = 1;
		break;
	case 'i':
		interval = atoi(EARGF(usage()));
		if(interval < 0)
			usage();
		break;
	case 'l':
		lostonly++;
		break;
	case 'n':
		nmsg = atoi(EARGF(usage()));
		if(nmsg < 0)
			usage();
		break;
	case 'q':
		quiet = 1;
		break;
	case 'r':
		rint = 1;
		break;
	case 's':
		msglen = atoi(EARGF(usage()));
		break;
	case 'w':
		waittime = atoi(EARGF(usage()));
		if(waittime < 0)
			usage();
		break;
	default:
		usage();
		break;
	} ARGEND;

	if(msglen < proto->iphdrsz + ICMP_HDRSIZE)
		msglen = proto->iphdrsz + ICMP_HDRSIZE;
	if(msglen < 64)
		msglen = 64;
	if(msglen >= 64*1024)
		msglen = 64*1024-1;
	if(interval <= 0 && !flood)
		interval = SLEEPMS;

	if(argc < 1)
		usage();

	notify(catch);

	target = nametoip(nil,argv[0],proto->version);

	if(isdottedquad(target))
		proto = &v4pr;
	else
	if(isv6lit(target))
		proto = &v6pr;

	ds = netmkaddr(target, proto->net, "1");
	fd = dial(ds, 0, 0, 0);
	if(fd < 0){
		fprint(2, "%s: couldn't dial %s: %r\n", argv0, ds);
		exits("dialing");
	}

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

	switch(rfork(RFPROC|RFMEM|RFFDG)){
	case -1:
		fprint(2, "%s: can't fork: %r\n", argv0);
		exits("forking");
	case 0:
		rcvr(fd, msglen, interval, nmsg);
		exits(0);
	default:
		sender(fd, msglen, interval, nmsg);
		wait();
		exits(lostmsgs ? "lost messages" : "");
	}
}

void
reply(Req *r, void *v)
{
	r->rtt /= 1000LL;
	sum += r->rtt;
	if(!r->replied)
		rcvdmsgs++;
	if(!quiet && !lostonly)
		if(addresses)
			(*proto->prreply)(r, v);
		else
			print("%ud: rtt %lld µs, avg rtt %lld µs, ttl = %d\n",
				r->seq - firstseq, r->rtt, sum/rcvdmsgs, r->ttl);
	r->replied = 1;
}

void
lost(Req *r, void *v)
{
	if(!quiet)
		if(addresses && v != nil)
			(*proto->prlost)(r->seq - firstseq, v);
		else
			print("lost %ud\n", r->seq - firstseq);
	lostmsgs++;
}

[-- Attachment #3: Type: text/plain, Size: 1160 bytes --]





> 2015/12/31 7:43、Kenny Lasse Hoff Levinsen <kennylevinsen@gmail.com> のメール:
> 
> It is not a common factor if you ping broadcast. That is, the local address is common, the remote is not.
> 
> joushou
> 
>> On 30 Dec 2015, at 20:05, Steve Simon <steve@quintile.net> wrote:
>> 
>> I would display the IP address once only, rather on every line; as it is a common factor.
>> 
>> -Steve
>> 
>> 
>>> On 30 Dec 2015, at 15:26, Kurt H Maier <khm@sciops.net> wrote:
>>> 
>>>> On Wed, Dec 30, 2015 at 03:05:33PM +0000, Steve Simon wrote:
>>>> If I where redesigning ping I wouldn't repeat any info that is common on each line - I.e. ip addresses or the column titles: rtt, ave etc.
>>>> 
>>>> consider plan9's ps(1) which has no column titles. they are described in the man page and are obvious from the context once you have read the man page once.
>>>> 
>>>> Having said this, I understand that tradition is also a strong guiding principal.
>>>> 
>>>> -Steve
>>> 
>>> I have no opinion on the labeling, but dropping the IPs from the output
>>> would make this tool useless for logging data.
>>> 
>>> khm
>> 
> 
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ?  --- ip/ping -6
  2015-12-30 19:05       ` Steve Simon
  2015-12-30 22:43         ` Kenny Lasse Hoff Levinsen
@ 2015-12-31  3:44         ` Dave Eckhardt
  1 sibling, 0 replies; 24+ messages in thread
From: Dave Eckhardt @ 2015-12-31  3:44 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

> I would display the IP address once only, rather on every line; as it
> is a common factor.

It's common only until it isn't.  If an intermediate router doesn't
like your packet it might choose to respond, in which case your
intended target doesn't get to.  At least that's why the Unix version
of ping reports the identity of the machine who issued the ICMP response.

Dave Eckhardt



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ?  --- ip/ping -6
  2015-12-30 12:48 ` arisawa
  2015-12-30 13:21   ` Charles Forsyth
  2015-12-30 15:05   ` Steve Simon
@ 2016-01-02  1:12   ` erik quanstrom
  2016-01-02  1:54     ` erik quanstrom
  2016-01-04  1:31   ` erik quanstrom
  3 siblings, 1 reply; 24+ messages in thread
From: erik quanstrom @ 2016-01-02  1:12 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 6817 bytes --]

on reading the man page, i found a small flaw in the implementation.  according to
the man page, -6 forces is of icmp6, even if the address is icmp4.  i changed ping to
do that.as a result, i added a -4 flag which forces the ping to use icmp4.  obviously, there is no
native 6-in-4, so this is an error.

also, i corrected an indirection of a nil pointer when a name lookup fails.

my pathetic excuse for unit testing, and a diff are below.  my version (hacks and all)
is attached.

- erik

ps.  the hand-implementation of csquery seems to be a result of not trusting
ndb/cs to be running.  odd.  does anyone have context on why this would be useful?

---

; ip/ping -6an1 bwc
sending 1 64 byte messages 1000 ms apart to icmpv6!2402:6b00:22cd:bf80::9!1
	2402:6b00:22cd:bf80::7 -> 2402:6b00:22cd:bf80::9
0: 2402:6b00:22cd:bf80::9 -> 2402:6b00:22cd:bf80::7 rtt 78 µs, avg rtt 78 µs, ttl = 255
; ip/ping -4an1 bwc
sending 1 64 byte messages 1000 ms apart to icmp!10.1.1.9!1
	10.1.1.7 -> 10.1.1.9
0: 10.1.1.9 -> 10.1.1.7 rtt 70 µs, avg rtt 70 µs, ttl = 255
; ip/ping -an1 bwc
sending 1 64 byte messages 1000 ms apart to icmp!10.1.1.9!1
	10.1.1.7 -> 10.1.1.9
0: 10.1.1.9 -> 10.1.1.7 rtt 72 µs, avg rtt 72 µs, ttl = 255
; ip/ping -4an1 10.1.1.7
sending 1 64 byte messages 1000 ms apart to icmp!10.1.1.7!1
	10.1.1.7 -> 10.1.1.7
0: 10.1.1.7 -> 10.1.1.7 rtt 15 µs, avg rtt 15 µs, ttl = 255
; ip/ping -6an1 10.1.1.7
sending 1 64 byte messages 1000 ms apart to icmpv6!10.1.1.7!1
	2402:6b00:22cd:bf80::7 -> 10.1.1.7
0: 10.1.1.7 -> 10.1.1.7 rtt 18 µs, avg rtt 18 µs, ttl = 255
; ip/ping -4an1 2402:6b00:22cd:bf80::7
ip/ping: ip/ping: nametoip: address 2402:6b00:22cd:bf80::7 does not match proto 4
; ip/ping -an1 missing
ip/ping: cannot write tcp!missing!1 to/net/cs: cs: can't translate address: dns: resource does not exist; negrcode


; diffy -c ping.c
/n/dump/2016/0101/sys/src/cmd/ip/ping.c:391,505 - ping.c:391,461
  	return colon;
  }
  
- /* from /sys/src/libc/9sys/dial.c */
- 
- enum
+ char*
+ nametoip(char *cs, char *name, int *ipver)
  {
- 	Maxstring	= 128,
- 	Maxpath		= 256,
- };
+ 	int n,fd;
+ 	char buf[128], ip6[128], ip4[128], *p, *addr, *ip;
  
- typedef struct DS DS;
- struct DS {
- 	/* dist string */
- 	char	buf[Maxstring];
- 	char	*netdir;
- 	char	*proto;
- 	char	*rem;
- 
- 	/* other args */
- 	char	*local;
- 	char	*dir;
- 	int	*cfdp;
- };
- 
- /*
-  *  parse a dial string
-  */
- static void
- _dial_string_parse(char *str, DS *ds)
- {
- 	char *p, *p2;
- 
- 	strncpy(ds->buf, str, Maxstring);
- 	ds->buf[Maxstring-1] = 0;
- 
- 	p = strchr(ds->buf, '!');
- 	if(p == 0) {
- 		ds->netdir = 0;
- 		ds->proto = "net";
- 		ds->rem = ds->buf;
- 	} else {
- 		if(*ds->buf != '/' && *ds->buf != '#'){
- 			ds->netdir = 0;
- 			ds->proto = ds->buf;
- 		} else {
- 			for(p2 = p; *p2 != '/'; p2--)
- 				;
- 			*p2++ = 0;
- 			ds->netdir = ds->buf;
- 			ds->proto = p2;
- 		}
- 		*p = 0;
- 		ds->rem = p + 1;
+ 	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;
+ 	}
  
- /* end excerpt from /sys/src/libc/9sys/dial.c */
- 
- /* side effect: sets network & target */
- static int
- isv4name(char *name)
- {
- 	int r = 1;
- 	char *root, *ip, *pr;
- 	DS ds;
- 
- 	_dial_string_parse(name, &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);
+ 	if(cs == nil)
+ 		cs = "/net/cs";
+ 	fd = open(cs, ORDWR);
+ 	if(fd < 0)
+ 		sysfatal("cannot open %s: %r", 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:
+ 	if((*ipver == 4 || *ipver == -1) && ip4[0] != 0){
+ 		*ipver = 4;
+ 		return strdup(ip4);
+ 	}else if((*ipver == 6 || *ipver == -1) && ip6[0] != 0){
+ 		*ipver = 6;
+ 		return strdup(ip6);
+ 	}else if(*ipver == 6 && ip4[0] != 0)
+ 		return strdup(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;
+ 	*ipver = -1;
+ 	return nil;
  }
  
  void
  main(int argc, char **argv)
  {
- 	int fd, msglen, interval, nmsg;
+ 	int fd, msglen, interval, nmsg, ipver;
  	char *ds;
  
  	nsecfd = bintime(-1, nil, nil, nil);
/n/dump/2016/0101/sys/src/cmd/ip/ping.c:509,517 - ping.c:465,475
  
  	msglen = interval = 0;
  	nmsg = MAXMSG;
+ 	ipver = -1;
  	ARGBEGIN {
+ 	case '4':
  	case '6':
- 		proto = &v6pr;
+ 		ipver = ARGC() - '0';
  		break;
  	case 'a':
  		addresses = 1;
/n/dump/2016/0101/sys/src/cmd/ip/ping.c:568,576 - ping.c:526,537
  
  	notify(catch);
  
- 	if (!isv4name(argv[0]))
- 		proto = &v6pr;
- 	ds = netmkaddr(argv[0], proto->net, "1");
+ 	target = nametoip(nil, argv[0], &ipver);
+ 	if(target == nil)
+ 		sysfatal("%s: nametoip: %r", argv0);
+ 	proto = ipver==4? &v4pr: &v6pr;
+ 
+ 	ds = netmkaddr(target, proto->net, "1");
  	fd = dial(ds, 0, 0, 0);
  	if(fd < 0){
  		fprint(2, "%s: couldn't dial %s: %r\n", argv0, ds);
/n/dump/2016/0101/sys/src/cmd/ip/ping.c:583,590 - ping.c:544,550
  
  	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);

[-- Attachment #2: ping.c --]
[-- Type: text/plain, Size: 11200 bytes --]

/* ping for ip v4 and v6 */
#include <u.h>
#include <libc.h>
#include <ctype.h>
#include <ip.h>
#include <bio.h>
#include <ndb.h>
#include "icmp.h"

enum {
	MAXMSG		= 32,
	SLEEPMS		= 1000,

	SECOND		= 1000000000LL,
	MINUTE		= 60*SECOND,
};

typedef struct Req Req;
struct Req
{
	ushort	seq;	/* sequence number */
	vlong	time;	/* time sent */
	vlong	rtt;
	int	ttl;
	int	replied;
	Req	 *next;
};

typedef struct {
	int	version;
	char	*net;
	int	echocmd;
	int	echoreply;
	unsigned iphdrsz;

	void	(*prreply)(Req *r, void *v);
	void	(*prlost)(ushort seq, void *v);
} Proto;


Req	*first;		/* request list */
Req	*last;		/* ... */
Lock	listlock;

char *argv0;

int addresses;
int debug;
int done;
int flood;
int lostmsgs;
int lostonly;
int quiet;
int rcvdmsgs;
int rint;
int nsecfd;
ushort firstseq;
vlong sum;
int waittime = 5000;

static char *network, *target;

void lost(Req*, void*);
void reply(Req*, void*);

static void
usage(void)
{
	fprint(2,
	    "usage: %s [-6alq] [-s msgsize] [-i millisecs] [-n #pings] dest\n",
		argv0);
	exits("usage");
}

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

static void
prlost4(ushort seq, void *v)
{
	Ip4hdr *ip4 = v;

	print("lost %ud: %V -> %V\n", seq, ip4->src, ip4->dst);
}

static void
prlost6(ushort seq, void *v)
{
	Ip6hdr *ip6 = v;

	print("lost %ud: %I -> %I\n", seq, ip6->src, ip6->dst);
}

static void
prreply4(Req *r, void *v)
{
	Ip4hdr *ip4 = v;

	print("%ud: %V -> %V rtt %lld µs, avg rtt %lld µs, ttl = %d\n",
		r->seq - firstseq, ip4->src, ip4->dst, r->rtt, sum/rcvdmsgs,
		r->ttl);
}

static void
prreply6(Req *r, void *v)
{
	Ip6hdr *ip6 = v;

	print("%ud: %I -> %I rtt %lld µs, avg rtt %lld µs, ttl = %d\n",
		r->seq - firstseq, ip6->src, ip6->dst, r->rtt, sum/rcvdmsgs,
		r->ttl);
}

static Proto v4pr = {
	4,		"icmp",
	EchoRequest,	EchoReply,
	IPV4HDR_LEN,
	prreply4,	prlost4,
};
static Proto v6pr = {
	6,		"icmpv6",
	EchoRequestV6,	EchoReplyV6,
	IPV6HDR_LEN,
	prreply6,	prlost6,
};

static Proto *proto = &v4pr;


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

	return (Icmphdr *)(p + proto->iphdrsz);
}

void
clean(ushort seq, vlong now, void *v)
{
	int ttl;
	Req **l, *r, *rlost, **rr;

	ttl = 0;
	if (v) {
		if (proto->version == 4)
			ttl = ((Ip4hdr *)v)->ttl;
		else
			ttl = ((Ip6hdr *)v)->ttl;
	}
	rlost = nil;
	rr = &rlost;
	lock(&listlock);
	last = nil;
	for(l = &first; *l; ){
		r = *l;

		if(v && r->seq == seq){
			r->rtt = now-r->time;
			r->ttl = ttl;
			reply(r, v);
		}

		if(now-r->time >= MINUTE){
			*l = r->next;
			r->next = nil;
			*rr = r;
			rr = &(*rr)->next;
		}else{
			last = r;
			l = &r->next;
		}
	}
	unlock(&listlock);

	for(; (r = rlost) != nil;){
		rlost = rlost->next;
		r->rtt = now-r->time;
		if(v)
			r->ttl = ttl;
		if(r->replied == 0)
			lost(r, v);
		free(r);
	}
}

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, Proto *proto, char *net)
{
	int ipisv4, wantv4;
	Ipifc *nifc;
	Iplifc *lifc;
	uchar mynet[IPaddrlen], linklocal[IPaddrlen];
	static Ipifc *ifc;

	ipmove(linklocal, IPnoaddr);
	wantv4 = proto->version == 4;
	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;
			}
			ipisv4 = isv4(lifc->ip) != 0;
			if(ipcmp(lifc->ip, IPnoaddr) != 0 && wantv4 == ipisv4){
				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;
}

void
sender(int fd, int msglen, int interval, int n)
{
	int i, extra;
	ushort seq;
	char buf[64*1024+512];
	uchar me[IPaddrlen], mev4[IPv4addrlen];
	Icmphdr *icmp;
	Req *r;

	srand(time(0));
	firstseq = seq = rand();

	icmp = geticmp(buf);
	memset(buf, 0, proto->iphdrsz + ICMP_HDRSIZE);
	for(i = proto->iphdrsz + ICMP_HDRSIZE; i < msglen; i++)
		buf[i] = i;
	icmp->type = proto->echocmd;
	icmp->code = 0;

	/* arguably the kernel should fill in the right src addr. */
	myipvnaddr(me, proto, network);
	if (proto->version == 4) {
		v6tov4(mev4, me);
		memmove(((Ip4hdr *)buf)->src, mev4, IPv4addrlen);
	} else
		ipmove(((Ip6hdr *)buf)->src, me);
	if (addresses)
		print("\t%I -> %s\n", me, target);

	if(rint != 0 && interval <= 0)
		rint = 0;
	extra = 0;
	for(i = 0; i < n; i++){
		if(i != 0){
			if(rint != 0)
				extra = nrand(interval);
			sleep(interval + extra);
		}
		r = malloc(sizeof *r);
		if (r == nil)
			continue;
		hnputs(icmp->seq, seq);
		r->seq = seq;
		r->next = nil;
		r->replied = 0;
//		nsecfd = bintime(nsecfd, &r->time, nil, nil);	/* avoid early free in reply! */
		r->time = 1ull<<62;
		lock(&listlock);
		if(first == nil)
			first = r;
		else
			last->next = r;
		last = r;
		unlock(&listlock);
		nsecfd = bintime(nsecfd, &r->time, nil, nil);
		if(write(fd, buf, msglen) < msglen){
			fprint(2, "%s: write failed: %r\n", argv0);
			return;
		}
		seq++;
	}
	done = 1;
}

void
rcvr(int fd, int msglen, int interval, int nmsg)
{
	int i, n, munged;
	ushort x;
	vlong now;
	uchar buf[64*1024+512];
	Icmphdr *icmp;
	Req *r;

	sum = 0;
	while(lostmsgs+rcvdmsgs < nmsg){
		alarm((nmsg-lostmsgs-rcvdmsgs)*interval+waittime);
//		alarm(interval+waittime);
		n = read(fd, buf, sizeof buf);
		alarm(0);
		nsecfd = bintime(nsecfd, &now, nil, nil);
		if(n <= 0){	/* read interrupted - time to go */
			clean(0, now+MINUTE, nil);
			continue;
		}
		if(n < msglen){
			print("bad len %d/%d\n", n, msglen);
			continue;
		}
		icmp = geticmp(buf);
		munged = 0;
		for(i = proto->iphdrsz + ICMP_HDRSIZE; i < msglen; i++)
			if(buf[i] != (uchar)i)
				munged++;
		if(munged)
			print("corrupted reply\n");
		x = nhgets(icmp->seq);
		if(icmp->type != proto->echoreply || icmp->code != 0) {
			print("bad type/code/sequence %d/%d/%d (want %d/%d/%d)\n",
				icmp->type, icmp->code, x,
				proto->echoreply, 0, x);
			continue;
		}
		clean(x, now, buf);
	}

	lock(&listlock);
	for(r = first; r; r = r->next)
		if(r->replied == 0)
			lostmsgs++;
	unlock(&listlock);

	if(!quiet && lostmsgs)
		print("%d out of %d messages lost\n", lostmsgs,
			lostmsgs+rcvdmsgs);
}

static int
isdottedquad(char *name)
{
	int dot = 0, digit = 0;

	for (; *name != '\0'; name++)
		if (*name == '.')
			dot++;
		else if (isdigit(*name))
			digit++;
		else
			return 0;
	return dot && digit;
}

static int
isv6lit(char *name)
{
	int colon = 0, hex = 0;

	for (; *name != '\0'; name++)
		if (*name == ':')
			colon++;
		else if (isxdigit(*name))
			hex++;
		else
			return 0;
	return colon;
}

char*
nametoip(char *cs, char *name, int *ipver)
{
	int n,fd;
	char buf[128], ip6[128], ip4[128], *p, *addr, *ip;

	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;
	}

	if(cs == nil)
		cs = "/net/cs";
	fd = open(cs, ORDWR);
	if(fd < 0)
		sysfatal("cannot open %s: %r", 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);
		}
	}
	close(fd);

match:
	if((*ipver == 4 || *ipver == -1) && ip4[0] != 0){
		*ipver = 4;
		return strdup(ip4);
	}else if((*ipver == 6 || *ipver == -1) && ip6[0] != 0){
		*ipver = 6;
		return strdup(ip6);
	}else if(*ipver == 6 && ip4[0] != 0)
		return strdup(ip4);
	else if(ip4[0] != 0 || ip6[0] != 0)
		werrstr("address %s does not match proto %d", ip4[0]? ip4: ip6, *ipver);

	*ipver = -1;
	return nil;
}

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

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

	fmtinstall('V', eipfmt);
	fmtinstall('I', eipfmt);

	msglen = interval = 0;
	nmsg = MAXMSG;
	ipver = -1;
	ARGBEGIN {
	case '4':
	case '6':
		ipver = ARGC() - '0';
		break;
	case 'a':
		addresses = 1;
		break;
	case 'd':
		debug++;
		break;
	case 'f':
		flood = 1;
		break;
	case 'i':
		interval = atoi(EARGF(usage()));
		if(interval < 0)
			usage();
		break;
	case 'l':
		lostonly++;
		break;
	case 'n':
		nmsg = atoi(EARGF(usage()));
		if(nmsg < 0)
			usage();
		break;
	case 'q':
		quiet = 1;
		break;
	case 'r':
		rint = 1;
		break;
	case 's':
		msglen = atoi(EARGF(usage()));
		break;
	case 'w':
		waittime = atoi(EARGF(usage()));
		if(waittime < 0)
			usage();
		break;
	default:
		usage();
		break;
	} ARGEND;

	if(msglen < proto->iphdrsz + ICMP_HDRSIZE)
		msglen = proto->iphdrsz + ICMP_HDRSIZE;
	if(msglen < 64)
		msglen = 64;
	if(msglen >= 64*1024)
		msglen = 64*1024-1;
	if(interval <= 0 && !flood)
		interval = SLEEPMS;

	if(argc < 1)
		usage();

	notify(catch);

	target = nametoip(nil, argv[0], &ipver);
	if(target == nil)
		sysfatal("%s: nametoip: %r", argv0);
	proto = ipver==4? &v4pr: &v6pr;

	ds = netmkaddr(target, proto->net, "1");
	fd = dial(ds, 0, 0, 0);
	if(fd < 0){
		fprint(2, "%s: couldn't dial %s: %r\n", argv0, ds);
		exits("dialing");
	}

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

	switch(rfork(RFPROC|RFMEM|RFFDG)){
	case -1:
		sysfatal("%s: can't fork: %r\n", argv0);
	case 0:
		rcvr(fd, msglen, interval, nmsg);
		exits(0);
	default:
		sender(fd, msglen, interval, nmsg);
		wait();
		exits(lostmsgs ? "lost messages" : "");
	}
}

void
reply(Req *r, void *v)
{
	r->rtt /= 1000LL;
	sum += r->rtt;
	if(!r->replied)
		rcvdmsgs++;
	if(!quiet && !lostonly)
		if(addresses)
			(*proto->prreply)(r, v);
		else
			print("%ud: rtt %lld µs, avg rtt %lld µs, ttl = %d\n",
				r->seq - firstseq, r->rtt, sum/rcvdmsgs, r->ttl);
	r->replied = 1;
}

void
lost(Req *r, void *v)
{
	if(!quiet)
		if(addresses && v != nil)
			(*proto->prlost)(r->seq - firstseq, v);
		else
			print("lost %ud\n", r->seq - firstseq);
	lostmsgs++;
}

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ?  --- ip/ping -6
  2016-01-02  1:12   ` erik quanstrom
@ 2016-01-02  1:54     ` erik quanstrom
  2016-01-03 19:58       ` hiro
  0 siblings, 1 reply; 24+ messages in thread
From: erik quanstrom @ 2016-01-02  1:54 UTC (permalink / raw)
  To: 9fans

unfortunately, there is some imprecision when mixing -4 and -6 with names,
and i don't have a tidy solution.

also, the man page claims that the biggest an icmp packet could possibly be is 8192 bytes, which
is incorrect.  icmp is fragmented like any other ip packet, so the maximum payload is 64k.

- erik



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ? --- ip/ping -6
  2016-01-02  1:54     ` erik quanstrom
@ 2016-01-03 19:58       ` hiro
  2016-01-03 20:04         ` erik quanstrom
  0 siblings, 1 reply; 24+ messages in thread
From: hiro @ 2016-01-03 19:58 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

-4 and -6 should error when used with an ip of the wrong type. when
used with domains correct behavior should be trivial and if there's no
dns response for A or AAAA it should error once again.



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ? --- ip/ping -6
  2016-01-03 19:58       ` hiro
@ 2016-01-03 20:04         ` erik quanstrom
  2016-01-03 20:31           ` erik quanstrom
  0 siblings, 1 reply; 24+ messages in thread
From: erik quanstrom @ 2016-01-03 20:04 UTC (permalink / raw)
  To: 9fans

On Sun Jan  3 12:00:39 PST 2016, 23hiro@gmail.com wrote:
> -4 and -6 should error when used with an ip of the wrong type. when
> used with domains correct behavior should be trivial and if there's no
> dns response for A or AAAA it should error once again.

i spent some time thinking about this problem.

the purpose of -6 is to force icmpv6.  (one can use a v4 address
with icmpv6, that works due to ipv4 embedding.)  this is not the same as
controlling name lookup.  since there are better more flexible tools
for doing that by hand.  the result can be fead to ip/ping.

it's kind of an ugly problem.

- erik



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ? --- ip/ping -6
  2016-01-03 20:04         ` erik quanstrom
@ 2016-01-03 20:31           ` erik quanstrom
  2016-01-03 21:40             ` hiro
  0 siblings, 1 reply; 24+ messages in thread
From: erik quanstrom @ 2016-01-03 20:31 UTC (permalink / raw)
  To: 9fans

> i spent some time thinking about this problem.
>
> the purpose of -6 is to force icmpv6.  (one can use a v4 address
> with icmpv6, that works due to ipv4 embedding.)  this is not the same as
> controlling name lookup.  since there are better more flexible tools
> for doing that by hand.  the result can be fead to ip/ping.
>
> it's kind of an ugly problem.

and it turns out that the patch as given breaks things like
ip/ping /net.alt/icmpv6!hostname

- erik



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ? --- ip/ping -6
  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
  0 siblings, 2 replies; 24+ messages in thread
From: hiro @ 2016-01-03 21:40 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

your ipv4 "embedding" doesn't need to be part of the ping tool. it's
not commonly used anyway.
allowing the ping tool to do dns lookups on the other hand are a
common convenience.



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ? --- ip/ping -6
  2016-01-03 21:40             ` hiro
@ 2016-01-03 21:43               ` hiro
  2016-01-03 21:47               ` erik quanstrom
  1 sibling, 0 replies; 24+ messages in thread
From: hiro @ 2016-01-03 21:43 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs

perhaps i misunderstand. i'm not against adding zeros at the front.



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ? --- ip/ping -6
  2016-01-03 21:40             ` hiro
  2016-01-03 21:43               ` hiro
@ 2016-01-03 21:47               ` erik quanstrom
  1 sibling, 0 replies; 24+ messages in thread
From: erik quanstrom @ 2016-01-03 21:47 UTC (permalink / raw)
  To: 9fans

On Sun Jan  3 13:42:21 PST 2016, 23hiro@gmail.com wrote:
> your ipv4 "embedding" doesn't need to be part of the ping tool. it's
> not commonly used anyway.

i think the attribution here is false.  i read the man page for that information.

in any event, ping as patched is wrong.  addresses like icmpv6!address must
be accepted.  this may make the -4 flag silly in it's current form.

> allowing the ping tool to do dns lookups on the other hand are a
> common convenience.

but as such, one loses precision.  for example if i use a name, i can't
easily force the name lookup to find the ip i'm thinking of.

> perhaps i misunderstand. i'm not against adding zeros at the front.

see /sys/src/libip/ipaux.c^/uchar v4prefix

- erik



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ?  --- ip/ping -6
  2015-12-30 12:48 ` arisawa
                     ` (2 preceding siblings ...)
  2016-01-02  1:12   ` erik quanstrom
@ 2016-01-04  1:31   ` erik quanstrom
  2016-01-04 10:51     ` Anthony Martin
  3 siblings, 1 reply; 24+ messages in thread
From: erik quanstrom @ 2016-01-04  1:31 UTC (permalink / raw)
  To: arisawa, 9fans

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);



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ?  --- ip/ping -6
  2016-01-04  1:31   ` erik quanstrom
@ 2016-01-04 10:51     ` Anthony Martin
  2016-01-04 13:04       ` erik quanstrom
  0 siblings, 1 reply; 24+ messages in thread
From: Anthony Martin @ 2016-01-04 10:51 UTC (permalink / raw)
  To: Fans of the OS Plan 9 from Bell Labs; +Cc: arisawa

erik quanstrom <quanstro@quanstro.net> once said:
> 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

Most commands use an -x option and setnetmtpt(2) to arrange
an alternate network root. Is there any reason not to do the
same for ip/ping?

  Anthony



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ?  --- ip/ping -6
  2016-01-04 10:51     ` Anthony Martin
@ 2016-01-04 13:04       ` erik quanstrom
  2016-01-04 13:58         ` erik quanstrom
  0 siblings, 1 reply; 24+ messages in thread
From: erik quanstrom @ 2016-01-04 13:04 UTC (permalink / raw)
  To: 9fans

> erik quanstrom <quanstro@quanstro.net> once said:
> > 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
>
> Most commands use an -x option and setnetmtpt(2) to arrange
> an alternate network root. Is there any reason not to do the
> same for ip/ping?

"most" commands do not.  for example,

	cpu -h /net.alt/tcp!ladd.quanstro.net

sorry i haven't the time to do statistics, but i'm pretty sure that
only programs lib ndb/dnsquery that do not take dial strings are
exceptions here.  and they are self-inconsistent.  some take -x
(bare option) and some take -x /mnt/pt.

that notwithstanding, it seems logical to allow icmpv6!host
as a proper dial string for ping, and this requires the same code.

i think it makes sense to do it as ping and traceroute have done.

- erik



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [9fans] bug or feature ?  --- ip/ping -6
  2016-01-04 13:04       ` erik quanstrom
@ 2016-01-04 13:58         ` erik quanstrom
  0 siblings, 0 replies; 24+ messages in thread
From: erik quanstrom @ 2016-01-04 13:58 UTC (permalink / raw)
  To: 9fans

> "most" commands do not.  for example,
>
> 	cpu -h /net.alt/tcp!ladd.quanstro.net
>

it turns out i had a bit of extra time since it's too icy to leave the
house.  :-(

anyway, here are all the programs that take -x mntpt, as determined by
the man pages.

	vnc(1) vncs
	httpfile(4)
	6in4(8)
	ndb(8) ndb/cs, csquery, dns, dnstcp, dnsquery, dnsdebug
	ppp(8) ip/ppp, pppoe, pptp, pptpd
	secstore(8) secstored
	syslogd(8)
	udpecho(8)

none of these programs take a dial string.

however, some of them could (see nettest(8), http://sources.9atom.org/magic/man2html/8/nettest)
such as syslogd, udpecho, secstored and vncs.

httpfile, well, rob has already made the point.

- erik



^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2016-01-04 13:58 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-28  9:04 [9fans] bug or feature ? --- ip/ping -6 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
2016-01-04 10:51     ` Anthony Martin
2016-01-04 13:04       ` erik quanstrom
2016-01-04 13:58         ` erik quanstrom

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).