Ok, thanks for the heads up. I am almost ready with my own setup here.
I looked at the guts of l4check.c, for the ioctl() calls. (btw, it doesn't build as-is in v4.1.3 - but not important).
I was under the impression I had most things correct, but unfortunately I am getting EINVAL. I was hoping for your (or anyone clued in) help in working out what field I am not filling in correctly:
Source function is:
static void nat_add(cluster_t *cluster, member_t *member)
{
struct ipnat l4_nat;
unsigned long addr; // ipv4 only :( if (main_harmless)
return;memset(&l4_nat, 0, sizeof(l4_nat));
l4_nat.in_flags = IPN_TCP|IPN_ROUNDR;
l4_nat.in_redir = NAT_REDIRECT; debugf("[nat] ifname '%s'\n", cluster->ifname); strncpy(l4_nat.in_ifname, cluster->ifname,
MIN(sizeof(l4_nat.in_ifname),
strlen(cluster->ifname)+1));
l4_nat.in_ifname[sizeof(l4_nat.in_ifname)-1] = 0; //probably not needed addr = lion_addr(cluster->listen_ip); // char * -> ulong
addr = htonl(addr);
memcpy(&l4_nat.in_outip, &addr,
sizeof(l4_nat.in_outip));
l4_nat.in_pmin = htons(cluster->listen_port);
l4_nat.in_pmax = l4_nat.in_pmin;
l4_nat.in_outmsk = 0xffffffff;
l4_nat.in_pnext = 0; addr = lion_addr(member->ip); // char * -> ulong
addr = htonl(addr);
memcpy(&l4_nat.in_inip, &addr,
sizeof(l4_nat.in_inip));
l4_nat.in_pnext = htons(member->port);
l4_nat.in_inmsk = 0xffffffff; if (!l4_nat.in_pnext)
l4_nat.in_pnext = l4_nat.in_pmin; printf("Add NAT rule '%s' for %s/%#x,%u -> ", l4_nat.in_ifname,
inet_ntoa(l4_nat.in_out[0]),
l4_nat.in_outmsk, ntohs(l4_nat.in_pmin));
printf("%s,%u\n", inet_ntoa(l4_nat.in_in[0]), ntohs(l4_nat.in_pnext));
if (ioctl(nat_fd, SIOCADNAT, &l4_nat) == -1) perror("ioctl(SIOCADNAT)");
}
Output looks like:
[service] cluster 'mywww' member '192.168.30.97:80' is UP [nat] ifname 'fxp0' Add NAT rule 'fxp0' for 0.0.0.0/0xffffffff,8000 -> 192.168.30.97,80 ioctl(SIOCADNAT): Invalid argument
Manually adding said rule appears to work:
# ipnat -f - rdr fxp0 0/32 port 8000 -> 192.168.30.97 port 80 tcp round-robin ^D ipnat -l List of active MAP/Redirect filters: rdr fxp0 0.0.0.0/32 port 8000 -> 192.168.30.97 port 80 tcp round-robin
gdb reports my structure looks like this just before calling ioctl():
148 if (ioctl(nat_fd, SIOCADNAT, &l4_nat) == -1) (gdb) p l4_nat $13 = {in_next = 0x0, in_rnext = 0x0, in_prnext = 0x0, in_mnext = 0x0, in_pmnext = 0x0, in_tqehead = {0x0, 0x0}, in_ifps = {0x0, 0x0}, in_apr = 0x0, in_comment = 0x0, in_next6 = {i6 = {0, 0, 0, 0}, in4 = { s_addr = 0}, vptr = {0x0, 0x0}, lptr = {0, 0}}, in_space = 0, in_hits = 0, in_use = 0, in_hv = 0, in_flineno = 0, in_pnext = 20480, in_xxx1 = "\0", in_flags = 257, in_mssclamp = 0, in_age = {0, 0}, in_redir = 2, in_p = 0, in_in = {{i6 = {1629399232, 0, 0, 0}, in4 = { s_addr = 1629399232}, vptr = {0x611ea8c0, 0x0}, lptr = {0x611ea8c0, 0}}, {i6 = {4294967295, 0, 0, 0}, in4 = {s_addr = 4294967295}, vptr = { 0xffffffff, 0x0}, lptr = {0xffffffff, 0}}}, in_out = {{i6 = {0, 0, 0, 0}, in4 = {s_addr = 0}, vptr = {0x0, 0x0}, lptr = {0, 0}}, {i6 = { 4294967295, 0, 0, 0}, in4 = {s_addr = 4294967295}, vptr = {0xffffffff, 0x0}, lptr = {0xffffffff, 0}}}, in_src = {{i6 = {0, 0, 0, 0}, in4 = { s_addr = 0}, vptr = {0x0, 0x0}, lptr = {0, 0}}, {i6 = {0, 0, 0, 0}, in4 = {s_addr = 0}, vptr = {0x0, 0x0}, lptr = {0, 0}}}, in_tuc = { ftu_tcpfm = 0 '\0', ftu_tcpf = 0 '\0', ftu_src = {frp_cmp = 0, frp_port = 0, frp_top = 0}, ftu_dst = {frp_cmp = 0, frp_port = 0, frp_top = 0}}, in_port = {16415, 16415}, in_ppip = 0, in_ippip = 0, in_ifnames = {"fxp0", '\0' <repeats 11 times>, '\0' <repeats 15 times>}, in_plabel = '\0' <repeats 15 times>, in_tag = {ipt_un = {iptu_num = {0, 0, 0, 0}, iptu_tag = '\0' <repeats 15 times>}, ipt_not = 0}}
Any help is very much appreciated!
Lund
-- Jorgen Lundman | <[EMAIL PROTECTED]> Unix Administrator | +81 (0)3 -5456-2687 ext 1017 (work) Shibuya-ku, Tokyo | +81 (0)90-5578-8500 (cell) Japan | +81 (0)3 -3375-1767 (home)
