X-Git-Url: http://git.onelab.eu/?p=ipfw.git;a=blobdiff_plain;f=dummynet2%2Fip_fw_nat.c;fp=dummynet2%2Fip_fw_nat.c;h=41fe919fe9920e9a8221b6ec263d46a3ddbdc998;hp=ead46a76f7141b65671a9b9f4059eb180786f0d1;hb=28a7fe9d930667786b902af6697c01eb87694173;hpb=2a8b6c544cf5ea3c84f763144c7ecfa79daea969 diff --git a/dummynet2/ip_fw_nat.c b/dummynet2/ip_fw_nat.c index ead46a7..41fe919 100644 --- a/dummynet2/ip_fw_nat.c +++ b/dummynet2/ip_fw_nat.c @@ -55,7 +55,7 @@ __FBSDID("$FreeBSD: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_nat.c 200975 20 static VNET_DEFINE(eventhandler_tag, ifaddr_event_tag); #define V_ifaddr_event_tag VNET(ifaddr_event_tag) -static void +static void ifaddr_change(void *arg __unused, struct ifnet *ifp) { struct cfg_nat *ptr; @@ -69,18 +69,18 @@ ifaddr_change(void *arg __unused, struct ifnet *ifp) /* ...using nic 'ifp->if_xname' as dynamic alias address. */ if (strncmp(ptr->if_name, ifp->if_xname, IF_NAMESIZE) != 0) continue; - if_addr_rlock(ifp); - TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - if (ifa->ifa_addr == NULL) - continue; - if (ifa->ifa_addr->sa_family != AF_INET) - continue; - ptr->ip = ((struct sockaddr_in *) - (ifa->ifa_addr))->sin_addr; - LibAliasSetAddress(ptr->lib, ptr->ip); - } - if_addr_runlock(ifp); + if_addr_rlock(ifp); + TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { + if (ifa->ifa_addr == NULL) + continue; + if (ifa->ifa_addr->sa_family != AF_INET) + continue; + ptr->ip = ((struct sockaddr_in *) + (ifa->ifa_addr))->sin_addr; + LibAliasSetAddress(ptr->lib, ptr->ip); } + if_addr_runlock(ifp); + } IPFW_WUNLOCK(chain); } @@ -131,9 +131,9 @@ del_redir_spool_cfg(struct cfg_nat *n, struct redir_chain *head) free(r, M_IPFW); break; default: - printf("unknown redirect mode: %u\n", r->mode); + printf("unknown redirect mode: %u\n", r->mode); /* XXX - panic?!?!? */ - break; + break; } } } @@ -166,7 +166,7 @@ add_redir_spool_cfg(char *buf, struct cfg_nat *ptr) remotePortCopy = 0; r->alink[i] = LibAliasRedirectPort(ptr->lib, r->laddr, htons(r->lport + i), r->raddr, - htons(remotePortCopy), r->paddr, + htons(remotePortCopy), r->paddr, htons(r->pport + i), r->proto); if (r->alink[i] == NULL) { r->alink[0] = NULL; @@ -180,22 +180,22 @@ add_redir_spool_cfg(char *buf, struct cfg_nat *ptr) break; default: printf("unknown redirect mode: %u\n", r->mode); - break; + break; } /* XXX perhaps return an error instead of panic ? */ if (r->alink[0] == NULL) panic("LibAliasRedirect* returned NULL"); /* LSNAT handling. */ - for (i = 0; i < r->spool_cnt; i++) { - ser_s = (struct cfg_spool *)&buf[off]; + for (i = 0; i < r->spool_cnt; i++) { + ser_s = (struct cfg_spool *)&buf[off]; s = malloc(SOF_REDIR, M_IPFW, M_WAITOK | M_ZERO); - memcpy(s, ser_s, SOF_SPOOL); - LibAliasAddServer(ptr->lib, r->alink[0], - s->addr, htons(s->port)); - off += SOF_SPOOL; - /* Hook spool entry. */ + memcpy(s, ser_s, SOF_SPOOL); + LibAliasAddServer(ptr->lib, r->alink[0], + s->addr, htons(s->port)); + off += SOF_SPOOL; + /* Hook spool entry. */ LIST_INSERT_HEAD(&r->spool_chain, s, _next); - } + } /* And finally hook this redir entry. */ LIST_INSERT_HEAD(&ptr->redir_chain, r, _next); } @@ -220,9 +220,9 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m) } ip = mtod(mcl, struct ip *); - /* + /* * XXX - Libalias checksum offload 'duct tape': - * + * * locally generated packets have only pseudo-header checksum * calculated and libalias will break it[1], so mark them for * later fix. Moreover there are cases when libalias modifies @@ -252,20 +252,20 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m) * it can handle delayed checksum and tso) */ - if (mcl->m_pkthdr.rcvif == NULL && + if (mcl->m_pkthdr.rcvif == NULL && mcl->m_pkthdr.csum_flags & CSUM_DELAY_DATA) ldt = 1; c = mtod(mcl, char *); if (args->oif == NULL) - retval = LibAliasIn(t->lib, c, + retval = LibAliasIn(t->lib, c, mcl->m_len + M_TRAILINGSPACE(mcl)); else - retval = LibAliasOut(t->lib, c, + retval = LibAliasOut(t->lib, c, mcl->m_len + M_TRAILINGSPACE(mcl)); if (retval == PKT_ALIAS_RESPOND) { - m->m_flags |= M_SKIP_FIREWALL; - retval = PKT_ALIAS_OK; + m->m_flags |= M_SKIP_FIREWALL; + retval = PKT_ALIAS_OK; } if (retval != PKT_ALIAS_OK && retval != PKT_ALIAS_FOUND_HEADER_FRAGMENT) { @@ -276,17 +276,17 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m) } mcl->m_pkthdr.len = mcl->m_len = ntohs(ip->ip_len); - /* - * XXX - libalias checksum offload - * 'duct tape' (see above) + /* + * XXX - libalias checksum offload + * 'duct tape' (see above) */ - if ((ip->ip_off & htons(IP_OFFMASK)) == 0 && + if ((ip->ip_off & htons(IP_OFFMASK)) == 0 && ip->ip_p == IPPROTO_TCP) { - struct tcphdr *th; + struct tcphdr *th; th = (struct tcphdr *)(ip + 1); - if (th->th_x2) + if (th->th_x2) ldt = 1; } @@ -295,37 +295,35 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m) struct udphdr *uh; u_short cksum; - /* XXX check if ip_len can stay in net format */ - cksum = in_pseudo( - ip->ip_src.s_addr, - ip->ip_dst.s_addr, - htons(ip->ip_p + ntohs(ip->ip_len) - (ip->ip_hl << 2)) - ); - + ip->ip_len = ntohs(ip->ip_len); + cksum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, + htons(ip->ip_p + ip->ip_len - (ip->ip_hl << 2))); + switch (ip->ip_p) { case IPPROTO_TCP: th = (struct tcphdr *)(ip + 1); - /* - * Maybe it was set in - * libalias... + /* + * Maybe it was set in + * libalias... */ th->th_x2 = 0; th->th_sum = cksum; - mcl->m_pkthdr.csum_data = + mcl->m_pkthdr.csum_data = offsetof(struct tcphdr, th_sum); break; case IPPROTO_UDP: uh = (struct udphdr *)(ip + 1); uh->uh_sum = cksum; - mcl->m_pkthdr.csum_data = + mcl->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); - break; + break; } /* No hw checksum offloading: do it ourselves */ if ((mcl->m_pkthdr.csum_flags & CSUM_DELAY_DATA) == 0) { in_delayed_cksum(mcl); mcl->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; } + ip->ip_len = htons(ip->ip_len); } args->m = mcl; return (IP_FW_NAT); @@ -343,7 +341,7 @@ lookup_nat(struct nat_list *l, int nat_id) return res; } -static int +static int ipfw_nat_cfg(struct sockopt *sopt) { struct cfg_nat *ptr, *ser_n; @@ -355,14 +353,14 @@ ipfw_nat_cfg(struct sockopt *sopt) ser_n = (struct cfg_nat *)buf; /* check valid parameter ser_n->id > 0 ? */ - /* + /* * Find/create nat rule. */ IPFW_WLOCK(chain); ptr = lookup_nat(&chain->nat, ser_n->id); if (ptr == NULL) { /* New rule: allocate and init new instance. */ - ptr = malloc(sizeof(struct cfg_nat), + ptr = malloc(sizeof(struct cfg_nat), M_IPFW, M_NOWAIT | M_ZERO); if (ptr == NULL) { IPFW_WUNLOCK(chain); @@ -384,13 +382,13 @@ ipfw_nat_cfg(struct sockopt *sopt) } IPFW_WUNLOCK(chain); - /* + /* * Basic nat configuration. */ ptr->id = ser_n->id; - /* - * XXX - what if this rule doesn't nat any ip and just - * redirect? + /* + * XXX - what if this rule doesn't nat any ip and just + * redirect? * do we set aliasaddress to 0.0.0.0? */ ptr->ip = ser_n->ip; @@ -400,7 +398,7 @@ ipfw_nat_cfg(struct sockopt *sopt) LibAliasSetAddress(ptr->lib, ptr->ip); memcpy(ptr->if_name, ser_n->if_name, IF_NAMESIZE); - /* + /* * Redir and LSNAT configuration. */ /* Delete old cfgs. */ @@ -420,7 +418,7 @@ ipfw_nat_del(struct sockopt *sopt) struct cfg_nat *ptr; struct ip_fw_chain *chain = &V_layer3_chain; int i; - + sooptcopyin(sopt, &i, sizeof i, sizeof i); /* XXX validate i */ IPFW_WLOCK(chain); @@ -440,7 +438,7 @@ ipfw_nat_del(struct sockopt *sopt) static int ipfw_nat_get_cfg(struct sockopt *sopt) -{ +{ uint8_t *data; struct cfg_nat *n; struct cfg_redir *r; @@ -448,7 +446,7 @@ ipfw_nat_get_cfg(struct sockopt *sopt) int nat_cnt, off; struct ip_fw_chain *chain; int err = ENOSPC; - + chain = &V_layer3_chain; nat_cnt = 0; off = sizeof(nat_cnt); @@ -460,30 +458,30 @@ ipfw_nat_get_cfg(struct sockopt *sopt) nat_cnt++; if (off + SOF_NAT >= NAT_BUF_LEN) goto nospace; - bcopy(n, &data[off], SOF_NAT); - off += SOF_NAT; - LIST_FOREACH(r, &n->redir_chain, _next) { + bcopy(n, &data[off], SOF_NAT); + off += SOF_NAT; + LIST_FOREACH(r, &n->redir_chain, _next) { if (off + SOF_REDIR >= NAT_BUF_LEN) goto nospace; bcopy(r, &data[off], SOF_REDIR); - off += SOF_REDIR; + off += SOF_REDIR; LIST_FOREACH(s, &r->spool_chain, _next) { if (off + SOF_SPOOL >= NAT_BUF_LEN) - goto nospace; + goto nospace; bcopy(s, &data[off], SOF_SPOOL); off += SOF_SPOOL; - } } + } } err = 0; /* all good */ nospace: IPFW_RUNLOCK(chain); if (err == 0) { - bcopy(&nat_cnt, data, sizeof(nat_cnt)); - sooptcopyout(sopt, data, NAT_BUF_LEN); + bcopy(&nat_cnt, data, sizeof(nat_cnt)); + sooptcopyout(sopt, data, NAT_BUF_LEN); } else { - printf("serialized data buffer not big enough:" - "please increase NAT_BUF_LEN\n"); + printf("serialized data buffer not big enough:" + "please increase NAT_BUF_LEN\n"); } free(data, M_IPFW); return (err); @@ -503,16 +501,16 @@ ipfw_nat_get_log(struct sockopt *sopt) /* one pass to count, one to copy the data */ i = 0; LIST_FOREACH(ptr, &chain->nat, _next) { - if (ptr->lib->logDesc == NULL) + if (ptr->lib->logDesc == NULL) continue; i++; } size = i * (LIBALIAS_BUF_SIZE + sizeof(int)); data = malloc(size, M_IPFW, M_NOWAIT | M_ZERO); - if (data == NULL) { + if (data == NULL) { IPFW_RUNLOCK(chain); - return (ENOSPC); - } + return (ENOSPC); + } i = 0; LIST_FOREACH(ptr, &chain->nat, _next) { if (ptr->lib->logDesc == NULL) @@ -551,7 +549,7 @@ ipfw_nat_destroy(void) { struct cfg_nat *ptr, *ptr_temp; struct ip_fw_chain *chain; - + chain = &V_layer3_chain; IPFW_WLOCK(chain); LIST_FOREACH_SAFE(ptr, &chain->nat, _next, ptr_temp) {