site_archiver@lists.apple.com Delivered-To: Macnetworkprog@lists.apple.com Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; bh=u/S+TFryFUMbeCkP4ILMNYqrW40Ex8PLaerCPBDBsSk=; b=cHlBIWOutBO5ijIAzfSuQ6DuxV00NevEshVXwFfLvlx1v1Jhv54zMPgQJHuxVJ4UT5WJMb00EP83mRqGAyrmgxE3wgHnnr4EB+n1ZCrcLVW/fAcdgvzvFPCvs7xVDHByhh3yHvWeGreMFFQP8rVEnQlzazPAIAAlPs5cYhcJ7VA= Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=JtHVbP2PEplbhJ0xiJV9aI0VDJIDOBudmHDoRYC8GKGekyYiU+WSoes2Hwbq6Acnxnob7l4jbuWHPd38CpP7ecPnDPubhwJ1ycFsr03yKIo33SMXr726ZRcLZaft0r+7hW9J7Yj7O9FHhMrPOtamLWLIGq8hDnyKZuUhCjF7qoo= On Jan 31, 2008 6:38 AM, Peter Sichel <psichel@sustworks.com> wrote:
There's a good example of using bpftransmit in the Darwin "bootp" project. That's where I cribbed mine from.
Wow Peter, copying that worked! I had no idea I'd be going that deep to port socket code from one platform to another. From doing further research I can't really find a published standard about what the "correct" behavior would be. The only thing I see mentioning how 255.255.255.255 should work is in RFC1700: "The "limited broadcast" destination address 255.255.255.255 should never be forwarded outside the (sub-)net of the source." [RFC1700, page 4] Without a formal specification I guess it's hard to say that the BSD way of not broadcasting to all adapters is "wrong"... it's just that it leaves no option but to go underneath the socket layer if one wishes to write a DHCP server. Probably a good idea anyway as it's sort of a meta-protocol, handing out addresses and such. But it would be nice if all socket layers were consistent in that case, treating 255.255.255.255 as an invalid address for outgoing sends. I was little troubled by the use of bpf functions directly, since they're not available on all platforms and I don't really want to #ifdef MACOSX in this code. Then I noticed that there are now cross-platform implementations of pcap_inject() and pcap_sendpacket()... http://winpcap.mirror.ethereal.com/301a/docs/group__wpcap__tut8.html So I decided to use that instead of bpf_write. It did not work at first, but after packet sniffing I realized that's because pcap_inject wasn't filling in the ethernet address of the source hardware. Darwin's BOOTP expects that, note the comment in this code: /* set ethernet dest and type, source is inserted automatically */ if (ntohl(dest_ip.s_addr) == INADDR_BROADCAST) { bcopy(ðer_broadcast, eh_p->ether_dhost, sizeof(ether_broadcast)); } else { bcopy(hwaddr, eh_p->ether_dhost, sizeof(eh_p->ether_dhost)); } eh_p->ether_type = htons(ETHERTYPE_IP); So by hacking the eh_p->ether_shost with the hardcoded address of the adapter I'm servicing, I was able to replace: status = bpf_write(bpf_fd, sendbuf, sizeof(*eh_p) + sizeof(*ip_udp) + len); with: status = pcap_inject(pcap_handle, reinterpret_cast<const u_char*>(sendbuf), sizeof(*eh_p)+sizeof(*ip_udp) + len); That let me pull out a lot of bpf dependencies, and I hope the resulting code will run on Linux and Windows without modification. Though I'll need to figure out a good cross-platform way to get the hardware ethernet address from pcap's device handle. I suppose I could send my own IP address a packet, capture it, and then read the data out of the header...but that seems roundabout! Better ideas appreciated... Thanks again for your help on this issue, I'm happy to be unblocked! --- http://hostilefork.com _______________________________________________ Do not post admin requests to the list. They will be ignored. Macnetworkprog mailing list (Macnetworkprog@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/macnetworkprog/site_archiver%40lists.... This email sent to site_archiver@lists.apple.com