tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
receiving all-one broadcasts from INADDR_ANY
I'm tracking down a weird problem (on a self-written Captive Portal including
a DHCP server) which works on -6, but doesn't on -8.
It seems to boil down to being unable to receive an UDP packet sent from
the Unspecified Address to the all-one address in case it gets redirected
by a NAT rdr rule. If I send from/to a unicast address, it works (I'm unable
to test changing only the source or only the destination address). If I
don't rdr, it works. On -6 it work with rdr and all-one.
Am I doing anything wrong?
I've got these rules in ipnat.conf (or not in the working case):
rdr vlan14 255.255.255.255/32 port 67 -> 192.168.24.22 port 7641 udp
rdr vlan14 192.168.24.22/32 port 67 -> 192.168.24.22 port 7641 udp
where 192.68.24.22 is the server's address on vlan14 (of course, I have
adapted local addresses on the other server)
I've these rules in ipf.conf:
pass in on vlan14 proto udp from any to any port=bootps
pass in on vlan14 proto udp from any to any port=7641
and use the attached progam for testing (changing the port number from
67 to 7641).
Is this a regression between -6 and -8? Am I doing something that worked
only by accident?
As I learnt I can tell dhcpd to listen ony on a sub-set of interfaces by
specifying them on the command line, I probably can drop the rdr rule,
but nevertheless would like to know what the problem is.
#include <err.h>
#include <unistd.h>
#include <stdio.h>
#include <strings.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(void) {
int s;
struct sockaddr_in sa;
ssize_t len;
char buf[1024];
socklen_t sa_len;
int one = 1;
if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) err(1, "socket");
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) == -1) err(1, "setsockopt(broadcast)");
if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) == -1) err(1, "setsockopt(reuseport)");
bzero(&sa, sizeof(sa));
sa.sin_len = sizeof(sa);
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = INADDR_ANY;
sa.sin_port = htons(67);
if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) == -1) err(1, "bind");
bzero(&sa, sizeof(sa));
sa_len = sizeof(sa);
if ((len = recvfrom(s, &buf, sizeof(buf), 0, (struct sockaddr *)&sa, &sa_len)) == -1) err(1, "recvfrom");
printf("%d\n", len);
close(s);
}
Home |
Main Index |
Thread Index |
Old Index