Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

protoent struct example

89 views
Skip to first unread message

Bill Cunningham

unread,
May 2, 2013, 5:33:08 PM5/2/13
to
Can someone show me how to use the struct protoent from netdb.h ? I
believe UDP port 69 is tftp but my /etc/protocols list doesn't list it. I
want to use getprotoentbynumber() and any other functions needed to read the
database.

stuck
Bill


Alan Curry

unread,
May 3, 2013, 1:21:30 AM5/3/13
to
In article <5182db8a$0$12762$bbae...@news.suddenlink.net>,
/etc/protocols lists the protocol numbers for protocols running on top of IP,
including UDP which is protocol 17.

/etc/services lists the port numbers for protocols running on top of TCP
and/or UDP, including bootp which is ports 67 and 68. (I'm not sure why it
needs two ports; I've never really looked at it.)

A bootp packet will have 17 in the protocol slot of its IP header,
identifying the next header as UDP, and 67 or 68 in the destination
and/or source port of the UDP header.

When you create a UDP socket, you do something like this:

s = socket(AF_INET, SOCK_DGRAM, 0);

and the kernel knows that the protocol will be UDP, because that's the
only protocol that can be used with the combination of AF_INET and
SOCK_DGRAM. You can pass IPPROTO_UDP as the third argument instead, if
you want to be explicit.

The point is... if you're not using raw sockets, you don't need to know
the protocol number. And even if you are making your own IP packets from
scratch, you don't need to use /etc/protocols or any of the the
getprotoby* functions. Just hardcode 17. Seriously, it's not like it can
ever change. If you want to make it look pretty use the IPPROTO_UDP
macro.

The same applies to port numbers you want to look up in /etc/services
with getservbyname(). They're all set in stone before they show up in
your /etc/services file.

You can call getprotobyname("udp") and getservbyname("bootps", "udp")
and you'll probably get structs with p_proto==17 and s_port==htons(67).
But you shouldn't do that. Just use the IPPROTO_UDP and 67. The get*by*
functions just add pointless overhead and an additional point of
potential failure.

--
Alan Curry

Bill Cunningham

unread,
May 5, 2013, 1:29:10 PM5/5/13
to
So if I want a TFTP socket should I use 69 as the 3 argument to socket()
?

Bill


Jorgen Grahn

unread,
May 5, 2013, 2:52:49 PM5/5/13
to
On Sun, 2013-05-05, Bill Cunningham wrote:
...
> So if I want a TFTP socket should I use 69 as the 3 argument to socket()?

No. 69 is a just port number. And you can't use it directly, since
the functions which *do* want it expect it to be in network byte order.

Do yourself a favor and learn to use getaddrinfo() instead. The Linux
man page even has examples for UDP client and server.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Nobody

unread,
May 9, 2013, 2:48:45 PM5/9/13
to
On Sun, 05 May 2013 13:29:10 -0400, Bill Cunningham wrote:

> So if I want a TFTP socket should I use 69 as the 3 argument to socket()
> ?

No. The third argument to socket() would be the IP protocol, i.e. 17
(IPPROTO_UDP) for UDP, but is normally zero (the protocol is inferred
to be TCP if the second argument is SOCK_STREAM or UDP if it is SOCK_DGRAM).

For TFTP (which is a UDP-based protocol), you should use 69 as the port
number in the sockaddr_in structure passed to sendto() or connect(). E.g.:

struct sockaddr_in dst_addr;

dst_addr.sin_family = AF_INET;
dst_addr.sin_port = htons(69);
inet_aton("192.168.0.99", &dst_addr.sin_addr);

connect(sockfd, (const struct sockaddr *)&dst_addr, sizeof dst_addr);

Nobody

unread,
May 9, 2013, 3:04:51 PM5/9/13
to
On Fri, 03 May 2013 05:21:30 +0000, Alan Curry wrote:

> /etc/services lists the port numbers for protocols running on top of TCP
> and/or UDP, including bootp which is ports 67 and 68. (I'm not sure why it
> needs two ports; I've never really looked at it.)

67 is for the server, 68 for the client.

BOOTP requests are broadcast, so using the same port for both client and
server would cause requests to be received by both BOOTP servers and other
BOOTP clients.

BOOTP replies *may* be broadcast, so using an ephemeral port risks having
BOOTP replies received by whatever happens to be using that port on
unrelated hosts.

0 new messages