12

Well, my question may look like a basic stuff, but i am new to network programming side. I wish to know:

1) Is it always required to bind a socket in order to receive message from that? I saw a sniffer code (raw socket) one in which directly it is invoking recvfrom and another piece of code in which it is invoking bind and then a receive.

2) What is the difference between the AF_* and PF_* family? Is the later related to POSIX? Which is the one recommended ?

RajSanpui
  • 11,556
  • 32
  • 79
  • 146
  • 1) No, binding for UDP receiving is optional. – Kerrek SB Dec 26 '11 at 14:44
  • http://stackoverflow.com/questions/2549461/what-is-the-difference-between-af-inet-and-pf-inet-constants. IIRC, P stands for protocol (family) whereas A stands for Address. – Aif Dec 26 '11 at 14:44
  • @Kerrek SB: But the sniffer code i am referring captures packets from other protocols too like but still it was not invoked `bind` – RajSanpui Dec 26 '11 at 14:46
  • @Aif: Protocol family is okay, but what is an address type? – RajSanpui Dec 26 '11 at 14:52
  • @kingsmasher1: AF_INET, AF_INET6, AF_UNIX and so on... `man socket` for details. – Aif Dec 26 '11 at 15:08
  • @Aif: Ahh thanks. please help me with the first part too. – RajSanpui Dec 26 '11 at 15:10
  • @kingsmasher: KerrekSB has already done! – Aif Dec 26 '11 at 15:12
  • @Aif: See my comments after that. – RajSanpui Dec 26 '11 at 15:15
  • @KerrekSB: http://www.binarytides.com/blog/packet-sniffer-code-in-c-using-linux-sockets-bsd-part-2/ now what do u say? There is no bind, and this code is not limited to only UDP. – RajSanpui Dec 26 '11 at 15:17
  • @kingsmasher1: Maybe my comment was unclear. I meant, "no, you do not need to say `bind()` in order to receive data." This is true for both TCP and UDP, though I was only referring to your example which uses UDP. – Kerrek SB Dec 26 '11 at 15:25
  • @KerrekSB: Ahh ok, so according to you in this second example http://security-freak.net/raw-sockets/sniffer_eth.c this `bind` invocation is totally unnecessary, and would have worked without it as well. One more thing, is your statement only limited to raw sockets or all? – RajSanpui Dec 26 '11 at 15:35

3 Answers3

13

No, you don't need to bind().

If you're using a TCP or UDP socket where you are planning to either connect() or send a packet to a destination with sendto(), the kernel will automatically bind the socket to a suitable port number when you try to connect or send. This is generally the preferred way. bind()ing client sockets is considered harmful.

The same is also true of AF_UNIX sockets - the client side does not need to bind, and should not do so normally.

MarkR
  • 62,604
  • 14
  • 116
  • 151
  • So you disagree with KerrekSB where he says it's only for receiving packets. Right? Even connect is not required as you can see from the above links. Just a call to `socket` followed by `recvfrom` – RajSanpui Dec 26 '11 at 16:16
  • I was talking about TCP or UDP sockets. What happens in raw sockets is not really relevant. – MarkR Dec 26 '11 at 18:05
  • 2
    Can you explain why binding client sockets is considered harmful? – Pacerier Jan 27 '12 at 12:09
  • Binding client sockets is harmful because 1) You may choose a local port number which is in use and 2) Your application may then be incompatible with NAT which changes the apparent source port number at the destination. – MarkR Jan 27 '12 at 12:40
  • what about ICMP packets? Is binding necessary before using sendto() and recvfrom()? – tez Aug 14 '13 at 10:32
1

For a client that only sends data, a bind is not necessary.

For a client that is sending a request to a server, and then receiving a response, a bind is not necessary. The server can use the IP address and port number that the incoming data came from.

For a client that is only receiving data, or is receiving data before it sends out data back to the server, a bind is necessary. How will the server know where to send data to? In this sense the "client" is acting like a "server" that needs a place (bound port) for the data to come to.

0

I don't know about Linux, but on Windows, if recvfrom() is called on an unbound socket, it will fail with an WSAEINVAL error.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I don't think it's useful to try to receive packets on a UDP socket which is not bound to a specific port, unless you sent some already. It is possible to bind a socket to a "don't care" port, then find the port with getsockname. For example, if I wanted to use UDP to receive packets from a server, but use TCP to send commands (at the same time) - for example, in some streaming situation where I only ever receive in UDP, never send. I would have to bind to port 0 (don't care) and then pass the port number over my protocol (TCP) to the server. – MarkR Dec 27 '11 at 09:53