Ticket #620 (closed defect: fixed)

Opened 3 years ago

Last modified 3 years ago

getmenu fails

Reported by: stefan Owned by: alexander
Priority: critical Milestone: All Platforms
Component: getmenu Version: IPv6
Keywords: Cc:

Description

(ipv6 code branch) getmenu won't work with ipv6 both getmenu and ipv6 use colons as delimiters suggestion... use a space as a delimiter instead of a colon.

Attachments

parse_ip_address.h (3.2 KB) - added by baker 3 years ago.
parse_ip_address.c (17.1 KB) - added by baker 3 years ago.
parse_ipv4_address.c (6.6 KB) - added by baker 3 years ago.
parse_ipv6_address.c (13.0 KB) - added by baker 3 years ago.
parse_ip_port.c (4.1 KB) - added by baker 3 years ago.
get_ip_format_string.c (3.4 KB) - added by baker 3 years ago.
test_parse_ip_address.c (2.9 KB) - added by baker 3 years ago.
test_parse_ip_address.txt (6.7 KB) - added by baker 3 years ago.

Change History

comment:1 Changed 3 years ago by stefan

Hi Larry -

getmenu is just a command line tool. No dot d. It takes a single argument and perhaps internally parses it out, I haven't gone into the source to look.

getmenu 10.196.144.18:16022

But there's never a reason that a space would be in the argument even for IPv4. I think replacing the : with a space on the command line is perfectly reasonable... internally I don't know what the program will do... perhaps it keeps ip:port which will need to be fixed.

  • Stefan

comment:2 Changed 3 years ago by quintiliani

Just remember that getmenu can accept a list of waveservers.

See ticket #194

$ getmenu
Usage: getmenu server:port [ server:port [ server:port ] ... ]
               Max number of servers: 10.

comment:3 Changed 3 years ago by quintiliani

From RFC3986 https://www.ietf.org/rfc/rfc3986.txt at section 3.2.2 "Host":

   The host subcomponent of authority is identified by an IP literal
   encapsulated within square brackets, an IPv4 address in dotted-
   decimal form, or a registered name.
...
   A host identified by an Internet Protocol literal address, version 6
   [RFC3513] or later, is distinguished by enclosing the IP literal
   within square brackets ("[" and "]").  This is the only place where
   square bracket characters are allowed in the URI syntax.  In
   anticipation of future, as-yet-undefined IP literal address formats,
   an implementation may use an optional version flag to indicate such a
   format explicitly rather than rely on heuristic determination.

An example for using the square brackets notation to to encode the IPv6 IP then could be:

getmenu [2001:db8::1]:16021 [2001:db8::1]:16022

comment:4 Changed 3 years ago by baker

Eddie's suggestion to use the RFC3986 syntax is excellent.

By my reading of RFC3986, square bracket are only used for IP literals, i.e., IPv6 and future IP's, not for IPv4 dotted notation. Thus, [192.168.0.1]:16022 would not be legal.

RFC3986 also does not mandate their use. Square brackets are only necessary (though, always allowed) to disambiguate the syntax. Another place in RFC3986 specifies that pattern matching is greedy, that is, the first match is made. Thus, 2001:db8::1:16022 would not have to be encapsulated, since 16022 is not a legal component of an IPv6 address (RFC3513). However, 2001:db8::1:80 would have to be encapsulated, since the syntax is a legal IPv6 address and thus is missing the required getmenu port field. [2001:db8::1]:80 would be the required syntax in that case.

I think Eddie's suggestion for handling IP addresses should be universally adopted in Earthworm. It is likely that a couple parsing routines in the Earthworm library will take care of it. Something like strtol() in stdlib.h that returns a pointer to the first invalid character for parsing.

comment:5 follow-up: ↓ 6 Changed 3 years ago by baker

Hunting around for an IP address parser, I found https://rosettacode.org/wiki/Parse_an_IP_Address, which does what I suggested. I didn't read it very carefully—it seems rather lengthy to me. I was thinking more of something state driven. But, free code is free code. :)

comment:6 in reply to: ↑ 5 Changed 3 years ago by alexander

Replying to baker:

Hunting around for an IP address parser, I found https://rosettacode.org/wiki/Parse_an_IP_Address, which does what I suggested. I didn't read it very carefully—it seems rather lengthy to me. I was thinking more of something state driven. But, free code is free code. :)

Thanks, this ought to save me quite a bit of time!

comment:7 Changed 3 years ago by alexander

  • Owner changed from somebody to alexander

comment:8 Changed 3 years ago by alexander

This is ready for test... using the Rosetta Code for now, Larry Baker pointed out some potential issues with that code but it works for now. Larry has written a parser himself, which will eventually be dropped in once sufficient testing has been done.

Changed 3 years ago by baker

Changed 3 years ago by baker

Changed 3 years ago by baker

Changed 3 years ago by baker

Changed 3 years ago by baker

Changed 3 years ago by baker

Changed 3 years ago by baker

Changed 3 years ago by baker

comment:9 Changed 3 years ago by baker

Attached are my IPv4/IPv6 address with optional port number parsing routines and a test program:

• parse_ip_address.h — header file

• parse_ip_address.c — parsers
• parse_ipv4_address.c
• parse_ipv6_address.c
• parse_ip_port.c

• get_ip_format_string.c — explanatory text

• test parse_ip_address.c — test driver
• test parse_ip_address.txt — compile and run of test driver with output

The test driver prints a side-by-side comparison of the results from calling parse_ip_address_with_port() and the Rosetta code, ParseIPv4OrIPv6(). I found one bug in ParseIPv4OrIPv6(): when it parses "0123:4567:89AB:CDEF:FEDC:BA98:7654:3210:80", it fails to recognize the :80 port number after the IPv6 address. The other differences are due to choices I made to allow any IPv6 prefix when there is an embedded IPv4 address. And, I return any valid IP address and optional port number found prior to a syntax error, such as for "::FFFF:130.80", which has a valid IPv6 address with port number prefix, "::FFFF:130". I leave it up to the caller to care whether the entire input string must be consumed by the parser. Or, for the example I gave previously of "2001:DB8::1:16022", which has a valid IPv6 address, "2001:DB8::1", followed by a port number, "16022". ParseIPv4OrIPv6() returns a parsing error for both of these examples. There are also differences in the location of the endptr (the character where parsing stopped). I return an accurate location endptr when a syntax error occurs as well as a specific reason for the error.

These should be library routines. They are separate files because object modules in C are files. User programs will only pull in the code they use from the library.

Give them a whirl.

comment:10 Changed 3 years ago by alexander

Great, thanks Larry!

comment:11 Changed 3 years ago by alexander

  • Status changed from new to closed
  • Resolution set to fixed
Note: See TracTickets for help on using tickets.