1

I am creating a small utillity which has to serve an IP address and parameters over BOOTP on my MacBook Pro.

I have used the AsyncUdpSocket library from GitHub (thanks RobbieHanson) and when I have my machine configured with just the wired ethernet connected (Airport Off) then it works. However, as soon as I enable my Wifi as well, all the broadcast replys go down the Wifi interface instead. This causes the wired clients to get no answer.

Initialise/Receive Code:

if (![socket bindToAddress:@"0.0.0.0" port:67 error:&err])
    NSLog(@"Error: unable to bind (%@)", [err localizedDescription]);
[socket enableBroadcast:YES error:&err];
[socket receiveWithTimeout:-1 tag:0];

Send Code:

[sock sendData:packetData toHost:@"255.255.255.255" port:68 withTimeout:-1 tag:0];

I am sure there must be a way to do this, but this is my first OS X program and I am struggling to master my google-search etiquette to suit the frameworks :)

UPDATE

I have messed about with my code tonight and inspected what the AsyncUdpSocket is doing when I am calling it. Essentially I have the following situation; if I call bindToAddress and supply 10.0.0.1 (the address assigned to my ETH NIC) then I neither receive any packets NOR can I send them. However, if I pass nil into the method then I can send a message AND receive the broadcasts - the downside being that the sending goes out over my WIFI NIC (default route)

In the background - the AsyncUdpSocket library is calling CFSocketSetAddress with either IFADDR_ANY when supplied a nil value OR a populated IFADDR struct of 10.0.0.1 if that is supplied. No errors are thrown and so it should be expected to work.

Any ideas? I am going up the wall and just want this solved. I really like the async nature of teh library so I don't want to throw it out.

justacodemonkey
  • 620
  • 1
  • 8
  • 20

1 Answers1

0

I think you have to

  1. Get the list of all network interfaces on your machine,
  2. For each interface, create a socket and bind it to the interface address.
  3. Send/receive on all sockets, one for each interface.

Part 1 can e.g. done with getifaddrs() (type "man getifaddrs" in the Terminal). I don't know if there is also a easier-to-use function in CoreFoundation.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • I only really need the packets to be bound to a single interface - I can get the user to pick the one they will be using. If I do this, presumably I just call `CFSetSocketAddress()` method to force broadcasts to 255.255.255.255 down that interface? – justacodemonkey Oct 09 '12 at 21:54
  • @richbayliss: What happens if you send packets to the broadcast address of the specific interface? For example 10.255.255.255 for the 10.0.0.1 interface. – Martin R Oct 10 '12 at 08:25
  • this does send the packet down the correct interface when bound to the ANY address. It does send the destination to 10.255.255.255 though, which in my case seems to work fine but what about cases where the endpoint is looking for 255.255.255.255? – justacodemonkey Oct 10 '12 at 10:02
  • @richbayliss: It is my understanding that if you sent a packet to 10.255.255.255 then this packet is received by all clients *on that network* listing to 255.255.255.255. See also http://stackoverflow.com/questions/2267538/which-adapter-did-i-just-receive-this-udp-packet-on , where it is also recommended to bind separated sockets for each interface. – Martin R Oct 10 '12 at 17:16
  • I agree on the multiple interface binding approach - however it seems that on my machine (MacBook Pro Retina w/10.8) that break my solution entirely. – justacodemonkey Oct 11 '12 at 09:08