Home | History | Annotate | Download | only in netinet

Lines Matching defs:nat

142 	/* nat */
194 /* How the NAT is organised and works. */
196 /* Inside (interface y) NAT Outside (interface x) */
210 /* In the NAT table, internal source is recorded as "in" and externally */
272 /* The only global NAT structure that needs to be initialised is the filter */
303 /* Returns: void * - NULL = failure, else pointer to NAT context */
306 /* Allocate the initial soft context structure for NAT and populate it with */
382 /* Initialise all of the NAT locks, tables and other structures. */
477 "nat ipftq udp tab");
481 "nat ipftq udpack tab");
485 "nat icmp ipftq tab");
489 "nat icmpack ipftq tab");
493 "nat ip ipftq tab");
496 IPFTQ_INIT(&softn->ipf_nat_pending, 1, "nat pending ipftq tab");
515 MUTEX_INIT(&softn->ipf_nat_new, "ipf nat new mutex");
516 MUTEX_INIT(&softn->ipf_nat_io, "ipf nat io mutex");
529 /* Free all memory used by NAT structures allocated at runtime. */
542 * exist on the NAT list, ipf_proxy_unload is called after unload
614 /* Set the "lock status" of NAT to the value in tmp. */
628 /* Parameters: n(I) - pointer to NAT rule to add */
631 /* loaded NAT rules. Updates the bitmask indicating which netmasks are in */
668 /* Parameters: n(I) - pointer to NAT rule to add */
670 /* Adds a NAT map rule to the hash table of rules and the list of loaded */
671 /* NAT rules. Updates the bitmask indicating which netmasks are in use by */
708 /* Parameters: n(I) - pointer to NAT rule to delete */
731 /* Parameters: n(I) - pointer to NAT rule to delete */
733 /* Removes a NAT map rule from the hash table of NAT map rules. */
755 /* Parameters: np(I) - pointer to NAT rule */
763 /* create a new entry if a non-NULL NAT rule pointer has been supplied. */
939 /* The only situation in which you need to do this is when NAT'ing an */
977 /* Processes an ioctl call made to operate on the IP Filter NAT device. */
985 ipnat_t *nat, *nt, *n;
1015 nat = NULL;
1026 nat = natd;
1050 nat = nt;
1054 * For add/delete, look to see if the NAT entry is
1057 nat->in_flags &= IPN_USERFLAGS;
1058 if ((nat->in_redir & NAT_MAPBLK) == 0) {
1059 if (nat->in_osrcatype == FRI_NORMAL ||
1060 nat->in_osrcatype == FRI_NONE)
1061 nat->in_osrcaddr &= nat->in_osrcmsk;
1062 if (nat->in_odstatype == FRI_NORMAL ||
1063 nat->in_odstatype == FRI_NONE)
1064 nat->in_odstaddr &= nat->in_odstmsk;
1065 if ((nat->in_flags & (IPN_SPLIT|IPN_SIPRANGE)) == 0) {
1066 if (nat->in_nsrcatype == FRI_NORMAL)
1067 nat->in_nsrcaddr &= nat->in_nsrcmsk;
1068 if (nat->in_ndstatype == FRI_NORMAL)
1069 nat->in_ndstaddr &= nat->in_ndstmsk;
1073 error = ipf_nat_rule_init(softc, softn, nat);
1079 if (ipf_nat_cmp_rules(nat, n) == 0)
1157 if (nat != nt)
1158 bcopy((char *)nat, (char *)nt, sizeof(*n));
1162 nat = NULL;
1403 if (nat != NULL)
1404 ipf_nat_rule_fini(softc, nat);
1417 /* softn(I) - pointer to NAT context structure */
1418 /* n(I) - pointer to new NAT rule */
1419 /* np(I) - pointer to where to insert new NAT rule */
1423 /* Handle SIOCADNAT. Resolve and calculate details inside the NAT rule */
1425 /* NAT rule table(s). */
1526 /* softn(I) - pointer to NAT context structure */
1527 /* n(I) - pointer to NAT rule */
1529 /* Initialise all of the NAT address structures in a NAT rule. */
1594 /* n(I) - pointer to NAT rule */
1596 /* Handle SIOCADNAT. Resolve and calculate details inside the NAT rule */
1598 /* NAT rule table(s). */
1638 /* softn(I) - pointer to NAT context structure */
1639 /* n(I) - pointer to new NAT rule */
1643 /* Handle SIOCADNAT. Resolve and calculate details inside the NAT rule */
1645 /* NAT rule table(s). */
1677 /* Return the size of the nat list entry to be copied back to user space. */
1686 nat_t *nat, *n;
1700 nat = ng.ng_ptr;
1701 if (!nat) {
1702 nat = softn->ipf_nat_instances;
1707 if (nat == NULL) {
1725 if (n == nat)
1740 aps = nat->nat_aps;
1764 /* to NAT structure to copy out. */
1769 /* Copies out NAT entry to user space. Any additional data held for a */
1770 /* proxy is also copied, as to is the NAT rule which was responsible for it */
1779 nat_t *n, *nat;
1801 nat = ipns.ipn_next;
1802 if (nat == NULL) {
1803 nat = softn->ipf_nat_instances;
1804 if (nat == NULL) {
1818 if (n == nat)
1826 ipn->ipn_next = nat->nat_next;
1829 * Copy the NAT structure.
1831 bcopy((char *)nat, &ipn->ipn_nat, sizeof(*nat));
1834 * If we have a pointer to the NAT rule it belongs to, save that too.
1836 if (nat->nat_ptr != NULL)
1837 bcopy((char *)nat->nat_ptr, (char *)&ipn->ipn_ipnat,
1841 * If we also know the NAT entry has an associated filter rule,
1844 if (nat->nat_fr != NULL)
1845 bcopy((char *)nat->nat_fr, (char *)&ipn->ipn_fr,
1850 * up for this NAT entry, then copy that out too, including any
1853 aps = nat->nat_aps;
1899 /* data(I) - pointer to natget structure with NAT */
1905 /* Loads a NAT table entry from user space, including a NAT rule, proxy and */
1914 nat_t *n, *nat;
1933 nat = NULL;
1939 * New entry, copy in the rest of the NAT entry if it's size is more
1964 KMALLOC(nat, nat_t *);
1965 if (nat == NULL) {
1971 bcopy((char *)&ipnn->ipn_nat, (char *)nat, sizeof(*nat));
1973 switch (nat->nat_v[0])
1990 bzero((char *)nat, offsetof(struct nat, nat_tqe));
1991 nat->nat_tqe.tqe_pnext = NULL;
1992 nat->nat_tqe.tqe_next = NULL;
1993 nat->nat_tqe.tqe_ifq = NULL;
1994 nat->nat_tqe.tqe_parent = nat;
1997 * Restore the rule associated with this nat session
2002 nat->nat_ptr = in;
2023 * Check that the NAT entry doesn't already exist in the kernel.
2036 fin->fin_v = nat->nat_v[0];
2037 fin->fin_p = nat->nat_pr[0];
2038 fin->fin_rev = nat->nat_rev;
2039 fin->fin_ifp = nat->nat_ifps[0];
2040 fin->fin_data[0] = ntohs(nat->nat_ndport);
2041 fin->fin_data[1] = ntohs(nat->nat_nsport);
2043 switch (nat->nat_dir)
2051 fin->fin_v = nat->nat_v[1];
2052 if (nat->nat_v[1] == 4) {
2053 n = ipf_nat_inlookup(fin, nat->nat_flags, fin->fin_p,
2054 nat->nat_ndstip, nat->nat_nsrcip);
2056 } else if (nat->nat_v[1] == 6) {
2057 n = ipf_nat6_inlookup(fin, nat->nat_flags, fin->fin_p,
2058 &nat->nat_ndst6.in6,
2059 &nat->nat_nsrc6.in6);
2080 n = ipf_nat_outlookup(fin, nat->nat_flags, fin->fin_p,
2081 nat->nat_ndstip,
2082 nat->nat_nsrcip);
2085 n = ipf_nat6_outlookup(fin, nat->nat_flags, fin->fin_p,
2086 &nat->nat_ndst6.in6,
2087 &nat->nat_nsrc6.in6);
2111 aps = nat->nat_aps;
2114 nat->nat_aps = aps;
2149 fr = nat->nat_fr;
2151 if ((nat->nat_flags & SI_NEWFR) != 0) {
2153 nat->nat_fr = fr;
2170 MUTEX_INIT(&fr->fr_lock, "nat-filter rule lock");
2206 nat);
2209 error = ipf_nat6_finalise(fin, nat);
2234 if (nat != NULL) {
2246 KFREE(nat);
2256 /* nat(I) - pointer to NAT structure to delete */
2260 /* Delete a nat entry from the various lists and table. If NAT logging is */
2261 /* enabled then generate a NAT log record for this event. */
2264 ipf_nat_delete(ipf_main_softc_t *softc, struct nat *nat, int logtype)
2273 ipf_nat_log(softc, softn, nat, logtype);
2279 if (nat->nat_pnext != NULL) {
2282 bkt = nat->nat_hv[0] % softn->ipf_nat_table_sz;
2290 bkt = nat->nat_hv[1] % softn->ipf_nat_table_sz;
2298 *nat->nat_pnext = nat->nat_next;
2299 if (nat->nat_next != NULL) {
2300 nat->nat_next->nat_pnext = nat->nat_pnext;
2301 nat->nat_next = NULL;
2303 nat->nat_pnext = NULL;
2305 *nat->nat_phnext[0] = nat->nat_hnext[0];
2306 if (nat->nat_hnext[0] != NULL) {
2307 nat->nat_hnext[0]->nat_phnext[0] = nat->nat_phnext[0];
2308 nat->nat_hnext[0] = NULL;
2310 nat->nat_phnext[0] = NULL;
2312 *nat->nat_phnext[1] = nat->nat_hnext[1];
2313 if (nat->nat_hnext[1] != NULL) {
2314 nat->nat_hnext[1]->nat_phnext[1] = nat->nat_phnext[1];
2315 nat->nat_hnext[1] = NULL;
2317 nat->nat_phnext[1] = NULL;
2319 if ((nat->nat_flags & SI_WILDP) != 0) {
2325 if (nat->nat_me != NULL) {
2326 *nat->nat_me = NULL;
2327 nat->nat_me = NULL;
2328 nat->nat_ref--;
2329 ASSERT(nat->nat_ref >= 0);
2332 if (nat->nat_tqe.tqe_ifq != NULL) {
2337 (void) ipf_deletequeueentry(&nat->nat_tqe);
2340 if (nat->nat_sync) {
2341 ipf_sync_del_nat(softc->ipf_sync_soft, nat->nat_sync);
2342 nat->nat_sync = NULL;
2348 MUTEX_ENTER(&nat->nat_lock);
2351 * This happens when a nat'd packet is blocked and we want to throw
2352 * away the NAT session.
2355 if (nat->nat_ref > 2) {
2356 nat->nat_ref -= 2;
2357 MUTEX_EXIT(&nat->nat_lock);
2362 } else if (nat->nat_ref > 1) {
2363 nat->nat_ref--;
2364 MUTEX_EXIT(&nat->nat_lock);
2369 ASSERT(nat->nat_ref >= 0);
2370 MUTEX_EXIT(&nat->nat_lock);
2372 nat->nat_ref = 0;
2380 softn->ipf_nat_stats.ns_proto[nat->nat_pr[0]]--;
2382 if (nat->nat_fr != NULL) {
2383 (void) ipf_derefrule(softc, &nat->nat_fr);
2386 if (nat->nat_hm != NULL) {
2387 ipf_nat_hostmapdel(softc, &nat->nat_hm);
2391 * If there is an active reference from the nat entry to its parent
2395 ipn = nat->nat_ptr;
2396 nat->nat_ptr = NULL;
2403 if (nat->nat_aps != NULL) {
2404 ipf_proxy_free(softc, nat->nat_aps);
2405 nat->nat_aps = NULL;
2408 MUTEX_DESTROY(&nat->nat_lock);
2413 * If there's a fragment table entry too for this nat entry, then
2417 ipf_frag_natforget(softc, (void *)nat);
2419 KFREE(nat);
2425 /* Returns: int - number of NAT rules deleted */
2427 /* softn(I) - pointer to NAT context structure */
2430 /* Deletes all currently active NAT sessions. In deleting each NAT entry a */
2431 /* log record should be emitted in ipf_nat_delete() if NAT logging is */
2435 * nat_flushtable - clear the NAT table of all mapping entries.
2440 nat_t *nat;
2444 * ALL NAT mappings deleted, so lets just make the deletions
2456 while ((nat = softn->ipf_nat_instances) != NULL) {
2457 ipf_nat_delete(softc, nat, NL_FLUSH);
2467 /* Returns: int - number of NAT/RDR rules deleted */
2469 /* softn(I) - pointer to NAT context structure */
2473 /* clear out the tables used for hashed NAT rule lookups. */
2507 /* softn(I) - pointer to NAT context structure */
2508 /* np(I) - pointer to NAT rule to delete */
2512 /* Preventing "purge" from occuring is allowed because when all of the NAT */
2514 /* of NAT sessions, possibly multiple times, would be a large performance */
2532 nat_t *nat;
2534 for (next = softn->ipf_nat_instances; (nat = next) != NULL;) {
2535 next = nat->nat_next;
2536 if (nat->nat_ptr == np)
2537 ipf_nat_delete(softc, nat, NL_PURGE);
2579 /* nat(I) - pointer to NAT entry */
2581 /* to create new NAT entry. */
2583 /* Given an empty NAT structure, populate it with new information about a */
2584 /* new NAT session, as defined by the matching NAT rule. */
2589 ipf_nat_newmap(fr_info_t *fin, nat_t *nat, natinfo_t *ni)
2611 flags = nat->nat_flags;
2623 * a NAT mapping that isn't currently being used. This is done
2631 * Check to see if there is an existing NAT
2643 nat->nat_hm = hm;
2786 * NAT setup will cause an external conflict where
2812 /* Setup the NAT table */
2813 nat->nat_osrcip = fin->fin_src;
2814 nat->nat_nsrcaddr = htonl(in.s_addr);
2815 nat->nat_odstip = fin->fin_dst;
2816 nat->nat_ndstip = fin->fin_dst;
2817 if (nat->nat_hm == NULL)
2818 nat->nat_hm = ipf_nat_hostmap(softn, np, fin->fin_src,
2819 fin->fin_dst, nat->nat_nsrcip,
2823 nat->nat_osport = sport;
2824 nat->nat_nsport = port; /* sport */
2825 nat->nat_odport = dport;
2826 nat->nat_ndport = dport;
2829 nat->nat_oicmpid = fin->fin_data[1];
2831 nat->nat_nicmpid = port;
2842 /* nat(I) - pointer to NAT entry */
2844 /* to create new NAT entry. */
2850 ipf_nat_newrdr(fr_info_t *fin, nat_t *nat, natinfo_t *ni)
2867 flags = nat->nat_flags;
3013 nat->nat_ndstaddr = htonl(in.s_addr);
3014 nat->nat_odstip = fin->fin_dst;
3015 nat->nat_nsrcip = fin->fin_src;
3016 nat->nat_osrcip = fin->fin_src;
3017 if ((nat->nat_hm == NULL) && ((np->in_flags & IPN_STICKY) != 0))
3018 nat->nat_hm = ipf_nat_hostmap(softn, np, fin->fin_src,
3022 nat->nat_odport = dport;
3023 nat->nat_ndport = nport;
3024 nat->nat_osport = sport;
3025 nat->nat_nsport = sport;
3028 nat->nat_oicmpid = fin->fin_data[1];
3030 nat->nat_nicmpid = nport;
3038 /* Returns: nat_t* - NULL == failure to create new NAT structure, */
3039 /* else pointer to new NAT structure */
3041 /* np(I) - pointer to NAT rule */
3042 /* natsave(I) - pointer to where to store NAT struct pointer */
3047 /* Attempts to create a new NAT entry. Does not actually change the packet */
3050 /* This function is in three main parts: (1) deal with creating a new NAT */
3051 /* structure for a "MAP" rule (outgoing NAT translation); (2) deal with */
3052 /* creating a new NAT structure for a "RDR" rule (incoming NAT translation) */
3053 /* and (3) building that structure and putting it into the NAT table(s). */
3065 nat_t *nat, *natl;
3092 /* Give me a new nat */
3093 KMALLOC(nat, nat_t *);
3094 if (nat == NULL) {
3113 * In the ICMP query NAT code, we translate the ICMP id fields
3129 bzero((char *)nat, sizeof(*nat));
3130 nat->nat_flags = flags;
3131 nat->nat_redir = np->in_redir;
3132 nat->nat_dir = direction;
3133 nat->nat_pr[0] = fin->fin_p;
3134 nat->nat_pr[1] = fin->fin_p;
3141 move = ipf_nat_newdivert(fin, nat, &ni);
3144 move = ipf_nat_newrewrite(fin, nat, &ni);
3155 KFREE(nat);
3156 nat = natl;
3160 move = ipf_nat_newmap(fin, nat, &ni);
3168 KFREE(nat);
3169 nat = natl;
3173 move = ipf_nat_newrdr(fin, nat, &ni);
3180 nat->nat_mssclamp = np->in_mssclamp;
3181 nat->nat_me = natsave;
3182 nat->nat_fr = fin->fin_fr;
3183 nat->nat_rev = fin->fin_rev;
3184 nat->nat_ptr = np;
3185 nat->nat_dlocal = np->in_dlocal;
3187 if ((np->in_apr != NULL) && ((nat->nat_flags & NAT_SLAVE) == 0)) {
3188 if (ipf_proxy_new(fin, nat) == -1) {
3194 nat->nat_ifps[0] = np->in_ifps[0];
3196 COPYIFNAME(np->in_v[0], np->in_ifps[0], nat->nat_ifnames[0]);
3199 nat->nat_ifps[1] = np->in_ifps[1];
3201 COPYIFNAME(np->in_v[1], np->in_ifps[1], nat->nat_ifnames[1]);
3204 if (ipf_nat_finalise(fin, nat) == -1) {
3222 nsp->ns_proto[nat->nat_pr[0]]++;
3226 DT2(ns_badnatnew, fr_info_t *, fin, nat_t *, nat);
3228 if ((hm = nat->nat_hm) != NULL)
3230 KFREE(nat);
3231 nat = NULL;
3233 if (nat != NULL && np != NULL)
3236 *natsave = nat;
3237 return nat;
3245 /* nat(I) - pointer to NAT entry */
3248 /* This is the tail end of constructing a new NAT entry and is the same */
3253 ipf_nat_finalise(fr_info_t *fin, nat_t *nat)
3263 switch (nat->nat_pr[0])
3266 sum1 = LONG_SUM(ntohs(nat->nat_oicmpid));
3267 sum2 = LONG_SUM(ntohs(nat->nat_nicmpid));
3269 nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
3274 sum1 = LONG_SUM(ntohl(nat->nat_osrcaddr) + \
3275 ntohs(nat->nat_osport));
3276 sum2 = LONG_SUM(ntohl(nat->nat_nsrcaddr) + \
3277 ntohs(nat->nat_nsport));
3279 nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
3281 sum1 = LONG_SUM(ntohl(nat->nat_odstaddr) + \
3282 ntohs(nat->nat_odport));
3283 sum2 = LONG_SUM(ntohl(nat->nat_ndstaddr) + \
3284 ntohs(nat->nat_ndport));
3286 nat->nat_sumd[0] += (sumd & 0xffff) + (sumd >> 16);
3295 if (nat->nat_dir == NAT_OUTBOUND) {
3296 sum1 = LONG_SUM(ntohl(nat->nat_nsrcaddr));
3297 sum1 += LONG_SUM(ntohl(nat->nat_ndstaddr));
3299 sum1 = LONG_SUM(ntohl(nat->nat_osrcaddr));
3300 sum1 += LONG_SUM(ntohl(nat->nat_odstaddr));
3302 sum1 += nat->nat_pr[1];
3303 nat->nat_sumd[1] = (sum1 & 0xffff) + (sum1 >> 16);
3305 sum1 = LONG_SUM(ntohl(nat->nat_osrcaddr));
3306 sum2 = LONG_SUM(ntohl(nat->nat_nsrcaddr));
3308 nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16);
3310 sum1 = LONG_SUM(ntohl(nat->nat_odstaddr));
3311 nat->nat_ndstaddr));
3313 nat->nat_ipsumd += (sumd & 0xffff) + (sumd >> 16);
3315 nat->nat_v[0] = 4;
3316 nat->nat_v[1] = 4;
3318 if ((nat->nat_ifps[0] != NULL) && (nat->nat_ifps[0] != (void *)-1)) {
3319 nat->nat_mtu[0] = GETIFMTU_4(nat->nat_ifps[0]);
3322 if ((nat->nat_ifps[1] != NULL) && (nat->nat_ifps[1] != (void *)-1)) {
3323 nat->nat_mtu[1] = GETIFMTU_4(nat->nat_ifps[1]);
3326 if ((nat->nat_flags & SI_CLONE) == 0)
3327 nat->nat_sync = ipf_sync_new(softc, SMC_NAT, fin, nat);
3329 if (ipf_nat_insert(softc, softn, nat) == 0) {
3331 ipf_nat_log(softc, softn, nat, NL_NEW);
3332 fr = nat->nat_fr;
3345 if (nat->nat_sync != NULL)
3346 ipf_sync_del_nat(softc->ipf_sync_soft, nat->nat_sync);
3355 /* softn(I) - pointer to NAT context structure */
3356 /* nat(I) - pointer to NAT structure */
3359 /* Insert a NAT entry into the hash tables for searching and add it to the */
3360 /* list of active NAT entries. Adjust global counters when complete. */
3363 ipf_nat_insert(ipf_main_softc_t *softc, ipf_nat_softc_t *softn, nat_t *nat)
3374 if ((nat->nat_flags & (SI_W_SPORT|SI_W_DPORT)) == 0) {
3375 if ((nat->nat_flags & IPN_TCPUDP) != 0) {
3376 sp = nat->nat_osport;
3377 dp = nat->nat_odport;
3378 } else if ((nat->nat_flags & IPN_ICMPQUERY) != 0) {
3380 dp = nat->nat_oicmpid;
3385 hv0 = NAT_HASH_FN(nat->nat_osrcaddr, sp, 0xffffffff);
3386 hv0 = NAT_HASH_FN(nat->nat_odstaddr, hv0 + dp, 0xffffffff);
3392 if ((nat->nat_flags & IPN_TCPUDP) != 0) {
3393 sp = nat->nat_nsport;
3394 dp = nat->nat_ndport;
3395 } else if ((nat->nat_flags & IPN_ICMPQUERY) != 0) {
3397 dp = nat->nat_nicmpid;
3402 hv1 = NAT_HASH_FN(nat->nat_nsrcaddr, sp, 0xffffffff);
3403 hv1 = NAT_HASH_FN(nat->nat_ndstaddr, hv1 + dp, 0xffffffff);
3409 hv0 = NAT_HASH_FN(nat->nat_osrcaddr, 0, 0xffffffff);
3410 hv0 = NAT_HASH_FN(nat->nat_odstaddr, hv0, 0xffffffff);
3413 hv1 = NAT_HASH_FN(nat->nat_nsrcaddr, 0, 0xffffffff);
3414 hv1 = NAT_HASH_FN(nat->nat_ndstaddr, hv1, 0xffffffff);
3418 if ((nat->nat_dir & NAT_OUTBOUND) == NAT_OUTBOUND) {
3419 nat->nat_hv[0] = hv0;
3420 nat->nat_hv[1] = hv1;
3422 nat->nat_hv[0] = hv1;
3423 nat->nat_hv[1] = hv0;
3426 MUTEX_INIT(&nat->nat_lock, "nat entry lock");
3428 in = nat->nat_ptr;
3429 nat->nat_ref = nat->nat_me ? 2 : 1;
3431 nat->nat_ifnames[0][LIFNAMSIZ - 1] = '\0';
3432 nat->nat_ifps[0] = ipf_resolvenic(softc, nat->nat_ifnames[0], 4);
3434 if (nat->nat_ifnames[1][0] != '\0') {
3435 nat->nat_ifnames[1][LIFNAMSIZ - 1] = '\0';
3436 nat->nat_ifps[1] = ipf_resolvenic(softc,
3437 nat->nat_ifnames[1], 4);
3443 (void) strncpy(nat->nat_ifnames[1],
3444 nat->nat_ifnames[0], LIFNAMSIZ);
3445 nat->nat_ifnames[1][LIFNAMSIZ - 1] = '\0';
3446 nat->nat_ifps[1] = nat->nat_ifps[0];
3449 if ((nat->nat_ifps[0] != NULL) && (nat->nat_ifps[0] != (void *)-1)) {
3450 nat->nat_mtu[0] = GETIFMTU_4(nat->nat_ifps[0]);
3452 if ((nat->nat_ifps[1] != NULL) && (nat->nat_ifps[1] != (void *)-1)) {
3453 nat->nat_mtu[1] = GETIFMTU_4(nat->nat_ifps[1]);
3456 ret = ipf_nat_hashtab_add(softc, softn, nat);
3458 MUTEX_DESTROY(&nat->nat_lock);
3467 /* softn(I) - pointer to NAT context structure */
3468 /* nat(I) - pointer to NAT structure */
3471 /* Handle the insertion of a NAT entry into the table/list. */
3474 ipf_nat_hashtab_add(ipf_main_softc_t *softc, ipf_nat_softc_t *softn, nat_t *nat)
3480 hv0 = nat->nat_hv[0] % softn->ipf_nat_table_sz;
3481 hv1 = nat->nat_hv[1] % softn->ipf_nat_table_sz;
3506 * Global list of NAT instances
3508 nat->nat_next = softn->ipf_nat_instances;
3509 nat->nat_pnext = &softn->ipf_nat_instances;
3511 softn->ipf_nat_instances->nat_pnext = &nat->nat_next;
3512 softn->ipf_nat_instances = nat;
3518 nat->nat_phnext[0] = natp;
3519 nat->nat_hnext[0] = *natp;
3521 (*natp)->nat_phnext[0] = &nat->nat_hnext[0];
3525 *natp = nat;
3532 nat->nat_phnext[1] = natp;
3533 nat->nat_hnext[1] = *natp;
3535 (*natp)->nat_phnext[1] = &nat->nat_hnext[1];
3539 *natp = nat;
3542 ipf_nat_setqueue(softc, softn, nat);
3544 if (nat->nat_dir & NAT_OUTBOUND) {
3556 /* Returns: nat_t* - point to matching NAT structure */
3561 /* ICMP query nat entry. It is assumed that the packet is already of the */
3574 nat_t *nat;
3657 nat = ipf_nat_inlookup(fin, flags, p,
3661 nat = ipf_nat_outlookup(fin, flags, p,
3666 return nat;
3685 nat = ipf_nat_inlookup(fin, flags, p, oip->ip_dst,
3688 nat = ipf_nat_outlookup(fin, flags, p, oip->ip_dst,
3693 return nat;
3696 nat = ipf_nat_inlookup(fin, 0, p, oip->ip_dst, oip->ip_src);
3698 nat = ipf_nat_outlookup(fin, 0, p, oip->ip_dst, oip->ip_src);
3700 return nat;
3706 /* Returns: nat_t* - point to matching NAT structure */
3708 /* nflags(I) - NAT flags for this packet */
3711 /* Fix up an ICMP packet which is an error message for an existing NAT */
3715 /* a NAT'd ICMP packet gets correctly recognised. */
3728 nat_t *nat;
3740 if ((fin->fin_v != 4) || !(nat = ipf_nat_icmperrorlookup(fin, dir))) {
3838 if (((fin->fin_out == 0) && ((nat->nat_redir & NAT_MAP) != 0)) ||
3839 ((fin->fin_out == 1) && ((nat->nat_redir & NAT_REDIRECT) != 0))) {
3840 a1.s_addr = ntohl(nat->nat_osrcaddr);
3842 a3.s_addr = ntohl(nat->nat_odstaddr);
3848 a1.s_addr = ntohl(nat->nat_ndstaddr);
3850 a3.s_addr = ntohl(nat->nat_nsrcaddr);
3879 * well, based on the NAT specification. Of course such
3890 sum1 = ntohs(nat->nat_osport);
3892 sum3 = ntohs(nat->nat_odport);
3898 sum1 = ntohs(nat->nat_ndport);
3900 sum3 = ntohs(nat->nat_nsport);
3961 if (orgicmp->icmp_id != nat->nat_osport) {
3976 sum2 = ntohs(nat->nat_oicmpid);
3978 orgicmp->icmp_id = nat->nat_oicmpid;
3983 return nat;
4002 /* else pointer to matching NAT entry */
4004 /* flags(I) - NAT flags for this packet */
4009 /* Lookup a nat entry based on the mapped destination ip address/port and */
4029 nat_t *nat;
4062 nat = softn->ipf_nat_table[1][hv];
4063 /* TRACE dst, dport, src, sport, hv, nat */
4065 for (; nat; nat = nat->nat_hnext[1]) {
4066 if (nat->nat_ifps[0] != NULL) {
4067 if ((ifp != NULL) && (ifp != nat->nat_ifps[0]))
4071 if (nat->nat_pr[0] != p)
4074 switch (nat->nat_dir)
4078 if (nat->nat_v[0] != 4)
4080 if (nat->nat_osrcaddr != src.s_addr ||
4081 nat->nat_odstaddr != dst)
4083 if ((nat->nat_flags & IPN_TCPUDP) != 0) {
4084 if (nat->nat_osport != sport)
4086 if (nat->nat_odport != dport)
4090 if (nat->nat_oicmpid != dport) {
4096 if (nat->nat_dlocal)
4100 if (nat->nat_v[1] != 4)
4102 if (nat->nat_dlocal)
4104 if (nat->nat_dlocal)
4106 if (nat->nat_ndstaddr != src.s_addr ||
4107 nat->nat_nsrcaddr != dst)
4109 if ((nat->nat_flags & IPN_TCPUDP) != 0) {
4110 if (nat->nat_ndport != sport)
4112 if (nat->nat_nsport != dport)
4116 if (nat->nat_nicmpid != dport) {
4124 if ((nat->nat_flags & IPN_TCPUDP) != 0) {
4125 ipn = nat->nat_ptr;
4126 if ((ipn != NULL) && (nat->nat_aps != NULL))
4127 if (ipf_proxy_match(fin, nat) != 0)
4130 if ((nat->nat_ifps[0] == NULL) && (ifp != NULL)) {
4131 nat->nat_ifps[0] = ifp;
4132 nat->nat_mtu[0] = GETIFMTU_4(ifp);
4134 return nat;
4140 * because it is modifying the NAT table and we want to do this only
4160 nat = softn->ipf_nat_table[1][hv];
4161 /* TRACE dst, src, hv, nat */
4162 for (; nat; nat = nat->nat_hnext[1]) {
4163 if (nat->nat_ifps[0] != NULL) {
4164 if ((ifp != NULL) && (ifp != nat->nat_ifps[0]))
4168 if (nat->nat_pr[0] != fin->fin_p)
4171 switch (nat->nat_dir & (NAT_INBOUND|NAT_OUTBOUND))
4174 if (nat->nat_v[0] != 4)
4176 if (nat->nat_osrcaddr != src.s_addr ||
4177 nat->nat_odstaddr != dst)
4181 if (nat->nat_v[1] != 4)
4183 if (nat->nat_ndstaddr != src.s_addr ||
4184 nat->nat_nsrcaddr != dst)
4189 nflags = nat->nat_flags;
4193 if (ipf_nat_wildok(nat, (int)sport, (int)dport, nflags,
4198 nat = ipf_nat_clone(fin, nat);
4199 if (nat == NULL)
4207 if (nat->nat_dir == NAT_INBOUND) {
4208 if (nat->nat_osport == 0) {
4209 nat->nat_osport = sport;
4210 nat->nat_nsport = sport;
4212 if (nat->nat_odport == 0) {
4213 nat->nat_odport = dport;
4214 nat->nat_ndport = dport;
4216 } else if (nat->nat_dir == NAT_OUTBOUND) {
4217 if (nat->nat_osport == 0) {
4218 nat->nat_osport = dport;
4219 nat->nat_nsport = dport;
4221 if (nat->nat_odport == 0) {
4222 nat->nat_odport = sport;
4223 nat->nat_ndport = sport;
4226 if ((nat->nat_ifps[0] == NULL) && (ifp != NULL)) {
4227 nat->nat_ifps[0] = ifp;
4228 nat->nat_mtu[0] = GETIFMTU_4(ifp);
4230 nat->nat_flags &= ~(SI_W_DPORT|SI_W_SPORT);
4231 ipf_nat_tabmove(softn, nat);
4238 if (nat == NULL) {
4241 return nat;
4248 /* Parameters: softn(I) - pointer to NAT context structure */
4249 /* nat(I) - pointer to NAT structure */
4252 /* This function is only called for TCP/UDP NAT table entries where the */
4257 ipf_nat_tabmove(ipf_nat_softc_t *softn, nat_t *nat)
4263 if (nat->nat_flags & SI_CLONE)
4268 * Remove the NAT entry from the old location
4270 if (nat->nat_hnext[0])
4271 nat->nat_hnext[0]->nat_phnext[0] = nat->nat_phnext[0];
4272 *nat->nat_phnext[0] = nat->nat_hnext[0];
4273 hv0 = nat->nat_hv[0] % softn->ipf_nat_table_sz;
4274 hv1 = nat->nat_hv[1] % softn->ipf_nat_table_sz;
4279 if (nat->nat_hnext[1])
4280 nat->nat_hnext[1]->nat_phnext[1] = nat->nat_phnext[1];
4281 *nat->nat_phnext[1] = nat->nat_hnext[1];
4286 * Add into the NAT table in the new position
4288 rhv0 = NAT_HASH_FN(nat->nat_osrcaddr, nat->nat_osport, 0xffffffff);
4289 rhv0 = NAT_HASH_FN(nat->nat_odstaddr, rhv0 + nat->nat_odport,
4291 rhv1 = NAT_HASH_FN(nat->nat_nsrcaddr, nat->nat_nsport, 0xffffffff);
4292 rhv1 = NAT_HASH_FN(nat->nat_ndstaddr, rhv1 + nat->nat_ndport,
4295 if ((nat->nat_dir & NAT_OUTBOUND) == NAT_OUTBOUND) {
4296 nat->nat_hv[0] = rhv0;
4297 nat->nat_hv[1] = rhv1;
4299 nat->nat_hv[0] = rhv1;
4300 nat->nat_hv[1] = rhv0;
4303 hv0 = nat->nat_hv[0] % softn->ipf_nat_table_sz;
4304 hv1 = nat->nat_hv[1] % softn->ipf_nat_table_sz;
4311 (*natp)->nat_phnext[0] = &nat->nat_hnext[0];
4312 nat->nat_phnext[0] = natp;
4313 nat->nat_hnext[0] = *natp;
4314 *natp = nat;
4319 (*natp)->nat_phnext[1] = &nat->nat_hnext[1];
4320 nat->nat_phnext[1] = natp;
4321 nat->nat_hnext[1] = *natp;
4322 *natp = nat;
4330 /* else pointer to matching NAT entry */
4332 /* flags(I) - NAT flags for this packet */
4338 /* Lookup a nat entry based on the source 'real' ip address/port and */
4358 nat_t *nat;
4386 nat = softn->ipf_nat_table[0][hv];
4388 /* TRACE src, sport, dst, dport, hv, nat */
4390 for (; nat; nat = nat->nat_hnext[0]) {
4391 if (nat->nat_ifps[1] != NULL) {
4392 if ((ifp != NULL) && (ifp != nat->nat_ifps[1]))
4396 if (nat->nat_pr[1] != p)
4399 switch (nat->nat_dir)
4403 if (nat->nat_v[1] != 4)
4405 if (nat->nat_ndstaddr != src.s_addr ||
4406 nat->nat_nsrcaddr != dst.s_addr)
4409 if ((nat->nat_flags & IPN_TCPUDP) != 0) {
4410 if (nat->nat_ndport != sport)
4412 if (nat->nat_nsport != dport)
4416 if (nat->nat_nicmpid != dport) {
4423 if (nat->nat_v[0] != 4)
4425 if (nat->nat_osrcaddr != src.s_addr ||
4426 nat->nat_odstaddr != dst.s_addr)
4429 if ((nat->nat_flags & IPN_TCPUDP) != 0) {
4430 if (nat->nat_odport != dport)
4432 if (nat->nat_osport != sport)
4436 if (nat->nat_oicmpid != dport) {
4443 ipn = nat->nat_ptr;
4444 if ((ipn != NULL) && (nat->nat_aps != NULL))
4445 if (ipf_proxy_match(fin, nat) != 0)
4448 if ((nat->nat_ifps[1] == NULL) && (ifp != NULL)) {
4449 nat->nat_ifps[1] = ifp;
4450 nat->nat_mtu[1] = GETIFMTU_4(ifp);
4452 return nat;
4458 * because it is modifying the NAT table and we want to do this only
4479 nat = softn->ipf_nat_table[0][hv];
4480 for (; nat; nat = nat->nat_hnext[0]) {
4481 if (nat->nat_ifps[1] != NULL) {
4482 if ((ifp != NULL) && (ifp != nat->nat_ifps[1]))
4486 if (nat->nat_pr[1] != fin->fin_p)
4489 switch (nat->nat_dir & (NAT_INBOUND|NAT_OUTBOUND))
4492 if (nat->nat_v[1] != 4)
4494 if (nat->nat_ndstaddr != src.s_addr ||
4495 nat->nat_nsrcaddr != dst.s_addr)
4499 if (nat->nat_v[0] != 4)
4501 if (nat->nat_osrcaddr != src.s_addr ||
4502 nat->nat_odstaddr != dst.s_addr)
4507 if (!(nat->nat_flags & (NAT_TCPUDP|SI_WILDP)))
4510 if (ipf_nat_wildok(nat, (int)sport, (int)dport, nat->nat_flags,
4514 if ((nat->nat_flags & SI_CLONE) != 0) {
4515 nat = ipf_nat_clone(fin, nat);
4516 if (nat == NULL)
4524 if (nat->nat_dir == NAT_OUTBOUND) {
4525 if (nat->nat_osport == 0) {
4526 nat->nat_osport = sport;
4527 nat->nat_nsport = sport;
4529 if (nat->nat_odport == 0) {
4530 nat->nat_odport = dport;
4531 nat->nat_ndport = dport;
4533 } else if (nat->nat_dir == NAT_INBOUND) {
4534 if (nat->nat_osport == 0) {
4535 nat->nat_osport = dport;
4536 nat->nat_nsport = dport;
4538 if (nat->nat_odport == 0) {
4539 nat->nat_odport = sport;
4540 nat->nat_ndport = sport;
4543 if ((nat->nat_ifps[1] == NULL) && (ifp != NULL)) {
4544 nat->nat_ifps[1] = ifp;
4545 nat->nat_mtu[1] = GETIFMTU_4(ifp);
4547 nat->nat_flags &= ~(SI_W_DPORT|SI_W_SPORT);
4548 ipf_nat_tabmove(softn, nat);
4555 if (nat == NULL) {
4558 return nat;
4565 /* else pointer to matching NAT entry */
4567 /* np(I) - pointer to description of packet to find NAT */
4570 /* Lookup the NAT tables to search for a matching redirect */
4586 nat_t *nat;
4610 if ((nat = ipf_nat_inlookup(&fi, np->nl_flags, fi.fin_p,
4612 np->nl_inip = nat->nat_odstip;
4613 np->nl_inport = nat->nat_odport;
4620 if ((nat = ipf_nat_outlookup(&fi, np->nl_flags, fi.fin_p,
4626 fin.fin_p = nat->nat_pr[0];
4627 fin.fin_data[0] = ntohs(nat->nat_ndport);
4628 fin.fin_data[1] = ntohs(nat->nat_nsport);
4630 fin.fin_p, nat->nat_ndstip,
4631 nat->nat_nsrcip) != NULL) {
4636 np->nl_realip = nat->nat_odstip;
4637 np->nl_realport = nat->nat_odport;
4641 return nat;
4649 /* np(I) - pointer to NAT rule */
4651 /* Pull the matching of a packet against a NAT rule out of that complex */
4708 /* nat(I) - pointer to NAT structure */
4710 /* Updates the lifetime of a NAT table entry for non-TCP packets. Must be */
4717 ipf_nat_update(fr_info_t *fin, nat_t *nat)
4723 ipnat_t *np = nat->nat_ptr;
4725 tqe = &nat->nat_tqe;
4729 * We allow over-riding of NAT timeouts from NAT rules, even for
4740 if (nat->nat_pr[0] == IPPROTO_TCP && ifq2 == NULL) {
4741 (void) ipf_tcp_age(&nat->nat_tqe, fin, softn->ipf_nat_tcptq,
4745 if (nat->nat_pr[0] == IPPROTO_UDP)
4748 else if (nat->nat_pr[0] == IPPROTO_ICMP ||
4749 nat->nat_pr[0] == IPPROTO_ICMPV6)
4763 /* Returns: int - -1 == packet failed NAT checks so block it, */
4771 /* otherwise a search of the current NAT table is made. If neither results */
4772 /* in a match then a search for a matching NAT rule is made. Create a new */
4773 /* NAT entry if a we matched a NAT rule. Lastly, actually change the */
4789 nat_t *nat;
4848 (nat = ipf_nat_icmperror(fin, &nflags, NAT_OUTBOUND)))
4850 else if ((fin->fin_flx & FI_FRAG) && (nat = ipf_frag_natknown(fin)))
4852 else if ((nat = ipf_nat_outlookup(fin, nflags|NAT_SEARCH,
4855 nflags = nat->nat_flags;
4860 * If there is no current entry in the nat table for this IP#,
4924 nat = ipf_nat_add(fin, np, NULL, nflags, NAT_OUTBOUND);
4926 if (nat != NULL) {
4938 if (nat != NULL) {
4939 rval = ipf_nat_out(fin, nat, natadd, nflags);
4941 MUTEX_ENTER(&nat->nat_lock);
4942 ipf_nat_update(fin, nat);
4943 nat->nat_bytes[1] += fin->fin_plen;
4944 nat->nat_pkts[1]++;
4945 fin->fin_pktnum = nat->nat_pkts[1];
4946 MUTEX_EXIT(&nat->nat_lock);
4978 /* Returns: int - -1 == packet failed NAT checks so block it, */
4981 /* nat(I) - pointer to NAT structure */
4983 /* nflags(I) - NAT flags set for this packet */
4988 ipf_nat_out(fr_info_t *fin, nat_t *nat, int natadd, u_32_t nflags)
5000 np = nat->nat_ptr;
5003 (void) ipf_frag_natnew(softc, fin, 0, nat);
5017 if (nat->nat_dir == NAT_OUTBOUND) {
5018 s2 = LONG_SUM(ntohl(nat->nat_nsrcaddr));
5020 s2 = LONG_SUM(ntohl(nat->nat_odstaddr));
5026 if (nat->nat_dir == NAT_OUTBOUND) {
5027 s2 = LONG_SUM(ntohl(nat->nat_ndstaddr));
5029 s2 = LONG_SUM(ntohl(nat->nat_osrcaddr));
5043 * to do NAT as a bridge, that code doesn't exist.
5045 switch (nat->nat_dir)
5050 nat->nat_ipsumd, 0);
5056 nat->nat_ipsumd, 0);
5071 switch (nat->nat_dir)
5074 fin->fin_ip->ip_src = nat->nat_nsrcip;
5075 fin->fin_saddr = nat->nat_nsrcaddr;
5076 fin->fin_ip->ip_dst = nat->nat_ndstip;
5077 fin->fin_daddr = nat->nat_ndstaddr;
5081 fin->fin_ip->ip_src = nat->nat_odstip;
5082 fin->fin_saddr = nat->nat_ndstaddr;
5083 fin->fin_ip->ip_dst = nat->nat_osrcip;
5084 fin->fin_daddr = nat->nat_nsrcaddr;
5091 skip = ipf_nat_decap(fin, nat);
5111 MUTEX_ENTER(&nat->nat_lock);
5112 ipf_nat_update(fin, nat);
5113 MUTEX_EXIT(&nat->nat_lock);
5173 if ((nat->nat_nsport != 0) && (nflags & IPN_TCPUDP)) {
5176 switch (nat->nat_dir)
5179 tcp->th_sport = nat->nat_nsport;
5180 fin->fin_data[0] = ntohs(nat->nat_nsport);
5181 tcp->th_dport = nat->nat_ndport;
5182 fin->fin_data[1] = ntohs(nat->nat_ndport);
5186 tcp->th_sport = nat->nat_odport;
5187 fin->fin_data[0] = ntohs(nat->nat_odport);
5188 tcp->th_dport = nat->nat_osport;
5189 fin->fin_data[1] = ntohs(nat->nat_osport);
5194 if ((nat->nat_oicmpid != 0) && (nflags & IPN_ICMPQUERY)) {
5197 switch (nat->nat_dir)
5200 icmp->icmp_id = nat->nat_nicmpid;
5203 icmp->icmp_id = nat->nat_oicmpid;
5208 csump = ipf_nat_proto(fin, nat, nflags);
5215 if (nat->nat_dir == NAT_OUTBOUND)
5217 nat->nat_sumd[0],
5218 nat->nat_sumd[1] +
5222 nat->nat_sumd[0],
5223 nat->nat_sumd[1] +
5228 ipf_sync_update(softc, SMC_NAT, fin, nat->nat_sync);
5240 i = ipf_proxy_check(fin, nat);
5256 /* Returns: int - -1 == packet failed NAT checks so block it, */
5264 /* otherwise a search of the current NAT table is made. If neither results */
5265 /* in a match then a search for a matching NAT rule is made. Create a new */
5266 /* NAT entry if a we matched a NAT rule. Lastly, actually change the */
5282 nat_t *nat;
5337 (nat = ipf_nat_icmperror(fin, &nflags, NAT_INBOUND)))
5339 else if ((fin->fin_flx & FI_FRAG) && (nat = ipf_frag_natknown(fin)))
5341 else if ((nat = ipf_nat_inlookup(fin, nflags|NAT_SEARCH,
5344 nflags = nat->nat_flags;
5349 * If there is no current entry in the nat table for this IP#,
5415 nat = ipf_nat_add(fin, np, NULL, nflags, NAT_INBOUND);
5417 if (nat != NULL) {
5429 if (nat != NULL) {
5430 rval = ipf_nat_in(fin, nat, natadd, nflags);
5432 MUTEX_ENTER(&nat->nat_lock);
5433 ipf_nat_update(fin, nat);
5434 nat->nat_bytes[0] += fin->fin_plen;
5435 nat->nat_pkts[0]++;
5436 fin->fin_pktnum = nat->nat_pkts[0];
5437 MUTEX_EXIT(&nat->nat_lock);
5469 /* Returns: int - -1 == packet failed NAT checks so block it, */
5472 /* nat(I) - pointer to NAT structure */
5474 /* nflags(I) - NAT flags set for this packet */
5480 ipf_nat_in(fr_info_t *fin, nat_t *nat, int natadd, u_32_t nflags)
5492 np = nat->nat_ptr;
5493 fin->fin_fr = nat->nat_fr;
5497 (void) ipf_frag_natnew(softc, fin, 0, nat);
5510 i = ipf_proxy_check(fin, nat);
5518 ipf_sync_update(softc, SMC_NAT, fin, nat->nat_sync);
5520 ipsumd = nat->nat_ipsumd;
5532 switch (nat->nat_dir)
5536 fin->fin_ip->ip_src = nat->nat_nsrcip;
5537 fin->fin_saddr = nat->nat_nsrcaddr;
5539 sum1 = nat->nat_osrcaddr;
5540 sum2 = nat->nat_nsrcaddr;
5544 fin->fin_ip->ip_dst = nat->nat_ndstip;
5545 fin->fin_daddr = nat->nat_ndstaddr;
5554 fin->fin_ip->ip_src = nat->nat_odstip;
5555 fin->fin_saddr = nat->nat_odstaddr;
5557 sum1 = nat->nat_odstaddr;
5558 sum2 = nat->nat_ndstaddr;
5562 fin->fin_ip->ip_dst = nat->nat_osrcip;
5563 fin->fin_daddr = nat->nat_osrcaddr;
5616 skip = ipf_nat_decap(fin, nat);
5636 ipf_nat_update(fin, nat);
5651 if ((nat->nat_odport != 0) && (nflags & IPN_TCPUDP)) {
5652 switch (nat->nat_dir)
5655 tcp->th_sport = nat->nat_nsport;
5656 fin->fin_data[0] = ntohs(nat->nat_nsport);
5657 tcp->th_dport = nat->nat_ndport;
5658 fin->fin_data[1] = ntohs(nat->nat_ndport);
5662 tcp->th_sport = nat->nat_odport;
5663 fin->fin_data[0] = ntohs(nat->nat_odport);
5664 tcp->th_dport = nat->nat_osport;
5665 fin->fin_data[1] = ntohs(nat->nat_osport);
5671 if ((nat->nat_oicmpid != 0) && (nflags & IPN_ICMPQUERY)) {
5674 switch (nat->nat_dir)
5677 icmp->icmp_id = nat->nat_nicmpid;
5680 icmp->icmp_id = nat->nat_oicmpid;
5685 csump = ipf_nat_proto(fin, nat, nflags);
5692 if (nat->nat_dir == NAT_OUTBOUND)
5693 ipf_fix_incksum(0, csump, nat->nat_sumd[0], 0);
5695 ipf_fix_outcksum(0, csump, nat->nat_sumd[0], 0);
5712 /* nat(I) - pointer to NAT structure */
5713 /* nflags(I) - NAT flags set for this packet */
5721 ipf_nat_proto(fr_info_t *fin, nat_t *nat, u_int nflags)
5730 fin->fin_rev = (nat->nat_dir & NAT_OUTBOUND);
5732 fin->fin_rev = ((nat->nat_dir & NAT_OUTBOUND) == 0);
5747 if ((nat->nat_mssclamp != 0) && (tcp->th_flags & TH_SYN) != 0)
5748 ipf_nat_mssclamp(tcp, nat->nat_mssclamp, fin, csump);
5852 /* Walk through all of the currently active NAT sessions, looking for those */
5862 nat_t *nat;
5871 * Change IP addresses for NAT sessions for any protocol except TCP
5884 for (nat = softn->ipf_nat_instances; nat; nat = nat->nat_next) {
5885 if ((nat->nat_flags & IPN_TCP) != 0)
5888 n = nat->nat_ptr;
5916 if (((ifp == NULL) || (ifp == nat->nat_ifps[0]) ||
5917 (ifp == nat->nat_ifps[1]))) {
5918 nat->nat_ifps[0] = GETIFP(nat->nat_ifnames[0],
5919 nat->nat_v[0]);
5920 if ((nat->nat_ifps[0] != NULL) &&
5921 (nat->nat_ifps[0] != (void *)-1)) {
5922 nat->nat_mtu[0] = GETIFMTU_4(nat->nat_ifps[0]);
5924 if (nat->nat_ifnames[1][0] != '\0') {
5925 nat->nat_ifps[1] = GETIFP(nat->nat_ifnames[1],
5926 nat->nat_v[1]);
5928 nat->nat_ifps[1] = nat->nat_ifps[0];
5930 if ((nat->nat_ifps[1] != NULL) &&
5931 (nat->nat_ifps[1] != (void *)-1)) {
5932 nat->nat_mtu[1] = GETIFMTU_4(nat->nat_ifps[1]);
5934 ifp2 = nat->nat_ifps[0];
5942 sum1 = NATFSUM(nat, nat->nat_v[1], nat_nsrc6);
5943 if (ipf_ifpaddr(softc, nat->nat_v[0], FRI_NORMAL, ifp2,
5945 if (nat->nat_v[0] == 4)
5946 nat->nat_nsrcip = in.in4;
5948 sum2 = NATFSUM(nat, nat->nat_v[1], nat_nsrc6);
5960 sumd += nat->nat_sumd[0];
5961 nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16);
5962 nat->nat_sumd[1] = nat->nat_sumd[0];
6015 * For the ICMP query NAT code, it is essential that both the query
6016 * and the reply match on the NAT rule. Because the NAT structure
6017 * does not keep track of the icmptype, and a single NAT structure
6046 /* softn(I) - pointer to NAT context structure */
6047 /* nat(I) - pointer to NAT structure */
6048 /* action(I) - action related to NAT structure being performed */
6050 /* Creates a NAT log entry. */
6053 ipf_nat_log(ipf_main_softc_t *softc, ipf_nat_softc_t *softn, struct nat *nat,
6066 bcopy((char *)&nat->nat_osrc6, (char *)&natl.nl_osrcip,
6068 bcopy((char *)&nat->nat_nsrc6, (char *)&natl.nl_nsrcip,
6070 bcopy((char *)&nat->nat_odst6, (char *)&natl.nl_odstip,
6072 bcopy((char *)&nat->nat_ndst6, (char *)&natl.nl_ndstip,
6075 natl.nl_bytes[0] = nat->nat_bytes[0];
6076 natl.nl_bytes[1] = nat->nat_bytes[1];
6077 natl.nl_pkts[0] = nat->nat_pkts[0];
6078 natl.nl_pkts[1] = nat->nat_pkts[1];
6079 natl.nl_odstport = nat->nat_odport;
6080 natl.nl_osrcport = nat->nat_osport;
6081 natl.nl_nsrcport = nat->nat_nsport;
6082 natl.nl_ndstport = nat->nat_ndport;
6083 natl.nl_p[0] = nat->nat_pr[0];
6084 natl.nl_p[1] = nat->nat_pr[1];
6085 natl.nl_v[0] = nat->nat_v[0];
6086 natl.nl_v[1] = nat->nat_v[1];
6087 natl.nl_type = nat->nat_redir;
6091 bcopy(nat->nat_ifnames[0], natl.nl_ifnames[0],
6092 sizeof(nat->nat_ifnames[0]));
6093 bcopy(nat->nat_ifnames[1], natl.nl_ifnames[1],
6094 sizeof(nat->nat_ifnames[1]));
6097 if (nat->nat_ptr != NULL) {
6100 if (np == nat->nat_ptr) {
6142 /* inp(I) - pointer to pointer to NAT rule */
6209 /* natp(I) - pointer to pointer to NAT table entry */
6211 /* Decrement the reference counter for this NAT table entry and free it if */
6214 /* IF nat_ref == 1 when this function is called, then we have an orphan nat */
6220 /* called from a NAT flush ioctl with a deref happening because of a packet.*/
6225 nat_t *nat;
6227 nat = *natp;
6230 MUTEX_ENTER(&nat->nat_lock);
6231 if (nat->nat_ref > 1) {
6232 nat->nat_ref--;
6233 ASSERT(nat->nat_ref >= 0);
6234 MUTEX_EXIT(&nat->nat_lock);
6237 MUTEX_EXIT(&nat->nat_lock);
6240 ipf_nat_delete(softc, nat, NL_EXPIRE);
6256 ipf_nat_clone(fr_info_t *fin, nat_t *nat)
6269 bcopy((char *)nat, (char *)clone, sizeof(*clone));
6312 * state of the new NAT from here.
6329 /* Parameters: nat(I) - NAT entry */
6335 /* Use NAT entry and packet direction to determine which combination of */
6339 ipf_nat_wildok(nat_t *nat, int sport, int dport, int flags, int dir)
6347 * "intended" direction of that NAT entry in nat->nat_dir to decide
6350 switch ((dir << 1) | (nat->nat_dir & (NAT_INBOUND|NAT_OUTBOUND)))
6353 if (((nat->nat_osport == sport) ||
6355 ((nat->nat_odport == dport) ||
6360 if (((nat->nat_osport == dport) ||
6362 ((nat->nat_odport == sport) ||
6367 if (((nat->nat_osport == dport) ||
6369 ((nat->nat_odport == sport) ||
6374 if (((nat->nat_osport == sport) ||
6376 ((nat->nat_odport == dport) ||
6454 /* softn(I) - pointer to NAT context structure */
6455 /* nat(I)- pointer to NAT structure */
6458 /* Put the NAT entry on its default queue entry, using rev as a helped in */
6462 ipf_nat_setqueue(ipf_main_softc_t *softc, ipf_nat_softc_t *softn, nat_t *nat)
6465 int rev = nat->nat_rev;
6467 if (nat->nat_ptr != NULL)
6468 nifq = nat->nat_ptr->in_tqehead[rev];
6473 switch (nat->nat_pr[0])
6483 nat->nat_tqe.tqe_state[rev];
6491 oifq = nat->nat_tqe.tqe_ifq;
6497 ipf_movequeue(softc->ipf_ticks, &nat->nat_tqe, oifq, nifq);
6499 ipf_queueappend(softc->ipf_ticks, &nat->nat_tqe, nifq, nat);
6511 /* Fetch the next nat/ipnat structure pointer from the linked list and */
6522 nat_t *nat, *nextnat = NULL, zeronat;
6572 nat = t->ipt_data;
6573 if (nat == NULL) {
6576 nextnat = nat->nat_next;
6631 if (nat != NULL)
6632 ipf_nat_deref(softc, &nat);
6648 /* softn(I) - pointer to NAT context structure */
6649 /* which(I) - how to flush the active NAT table */
6652 /* Flush nat tables. Three actions currently defined: */
6653 /* which == 0 : flush all nat table entries */
6666 nat_t *nat, **natp;
6683 ((nat = *natp) != NULL); ) {
6684 ipf_nat_delete(softc, nat, NL_FLUSH);
6699 nat = tqn->tqe_parent;
6701 if (nat->nat_pr[0] != IPPROTO_TCP ||
6702 nat->nat_pr[1] != IPPROTO_TCP)
6704 ipf_nat_delete(softc, nat, NL_EXPIRE);
6715 nat = tqn->tqe_parent;
6717 if (nat->nat_pr[0] != IPPROTO_TCP ||
6718 nat->nat_pr[1] != IPPROTO_TCP)
6721 if ((nat->nat_tcpstate[0] >
6723 (nat->nat_tcpstate[1] >
6725 ipf_nat_delete(softc, nat, NL_EXPIRE);
6746 nat = tqn->tqe_parent;
6748 ipf_nat_delete(softc, nat, NL_FLUSH);
6765 ((nat = *natp) != NULL); ) {
6766 if (softc->ipf_ticks - nat->nat_touched > which) {
6767 ipf_nat_delete(softc, nat, NL_FLUSH);
6770 natp = &nat->nat_next;
6810 /* entry(I) - pointer to NAT entry */
6836 /* linked lists of NAT related information to go through: NAT rules, active */
6837 /* NAT mappings and the NAT fragment cache. */
6875 /* nat(I) - pointer to NAT structure */
6878 /* Put the NAT entry on to the pending queue - this queue has a very short */
6885 ipf_nat_setpending(ipf_main_softc_t *softc, nat_t *nat)
6890 oifq = nat->nat_tqe.tqe_ifq;
6892 ipf_movequeue(softc->ipf_ticks, &nat->nat_tqe, oifq,
6895 ipf_queueappend(softc->ipf_ticks, &nat->nat_tqe,
6896 &softn->ipf_nat_pending, nat);
6898 if (nat->nat_me != NULL) {
6899 *nat->nat_me = NULL;
6900 nat->nat_me = NULL;
6901 nat->nat_ref--;
6902 ASSERT(nat->nat_ref >= 0);
6912 /* nat(I) - pointer to NAT entry */
6914 /* to create new NAT entry. */
6917 /* This function is responsible for setting up an active NAT session where */
6926 ipf_nat_newrewrite(fr_info_t *fin, nat_t *nat, natinfo_t *nai)
6941 flags = nat->nat_flags;
6944 nat->nat_hm = NULL;
7071 * NAT setup will cause an external conflict where
7112 nat->nat_osrcip = fin->fin_src;
7113 nat->nat_odstip = fin->fin_dst;
7114 nat->nat_nsrcip = frnat.fin_src;
7115 nat->nat_ndstip = frnat.fin_dst;
7118 nat->nat_osport = htons(fin->fin_data[0]);
7119 nat->nat_odport = htons(fin->fin_data[1]);
7120 nat->nat_nsport = htons(frnat.fin_data[0]);
7121 nat
7123 nat->nat_oicmpid = fin->fin_data[1];
7124 nat->nat_nicmpid = frnat.fin_data[1];
7135 /* nat(I) - pointer to NAT entry */
7137 /* to create new NAT entry. */
7140 /* Create a new NAT divert session as defined by the NAT rule. This is */
7141 /* somewhat different to other NAT session creation routines because we */
7146 ipf_nat_newdivert(fr_info_t *fin, nat_t *nat, natinfo_t *nai)
7158 nat->nat_pr[0] = 0;
7159 nat->nat_osrcaddr = fin->fin_saddr;
7160 nat->nat_odstaddr = fin->fin_daddr;
7163 if ((nat->nat_flags & IPN_TCPUDP) != 0) {
7164 nat->nat_osport = htons(fin->fin_data[0]);
7165 nat->nat_odport = htons(fin->fin_data[1]);
7166 } else if ((nat->nat_flags & IPN_ICMPQUERY) != 0) {
7167 nat->nat_oicmpid = fin->fin_data[1];
7194 nat->nat_nsrcaddr = frnat.fin_saddr;
7195 nat->nat_ndstaddr = frnat.fin_daddr;
7196 if ((nat->nat_flags & IPN_TCPUDP) != 0) {
7197 nat->nat_nsport = htons(frnat.fin_data[0]);
7198 nat->nat_ndport = htons(frnat.fin_data[1]);
7199 } else if ((nat->nat_flags & IPN_ICMPQUERY) != 0) {
7200 nat->nat_nicmpid = frnat.fin_data[1];
7203 nat->nat_pr[fin->fin_out] = fin->fin_p;
7204 nat->nat_pr[1 - fin->fin_out] = p;
7207 nat->nat_dir = NAT_DIVERTIN;
7209 nat->nat_dir = NAT_DIVERTOUT;
7218 /* Parameters: softn(I) - pointer to NAT context structure */
7219 /* np(I) - pointer to a NAT rule */
7283 /* nat(I) - pointer to current NAT session */
7295 ipf_nat_decap(fr_info_t *fin, nat_t *nat)
7315 if (nat->nat_dir & NAT_OUTBOUND) {
7319 sum2 = ntohl(nat->nat_osrcaddr);
7321 fin->fin_ip->ip_dst = nat->nat_osrcip;
7322 fin->fin_daddr = nat->nat_osrcaddr;
7334 switch (nat->nat_dir)
7486 /* na(I) - NAT address information for generating new addr*/
7492 /* This function is expected to be called in two scenarious: when a new NAT */
7493 /* rule is loaded into the kernel and when the list of NAT rules is sync'd */
7583 /* softn(I) - pointer to NAT context structure */
7584 /* nat(I) - pointer to current NAT session */
7591 nat_t *nat, *natnext;
7600 for (nat = softn->ipf_nat_instances; nat != NULL; nat = natnext) {
7601 natnext = nat->nat_next;
7602 if (ipf_nat_matcharray(nat, array, softc->ipf_ticks) == 0) {
7603 ipf_nat_delete(softc, nat, NL_FLUSH);
7621 /* nat(I) - pointer to current NAT session */
7625 ipf_nat_matcharray(nat_t *nat, int *array, u_long ticks)
7643 if (p != 0 && p != nat->nat_pr[1])
7650 e |= (nat->nat_pr[1] == x[i + 3]);
7655 if (nat->nat_v[0] == 4) {
7657 e |= ((nat->nat_osrcaddr & x[i + 4]) ==
7661 if (nat->nat_v[1] == 4) {
7663 e |= ((nat->nat_nsrcaddr & x[i + 4]) ==
7670 if (nat->nat_v[0] == 4) {
7672 e |= ((nat->nat_odstaddr & x[i + 4]) ==
7676 if (nat->nat_v[1] == 4) {
7678 e |= ((nat->nat_ndstaddr & x[i + 4]) ==
7686 if (nat->nat_v[0] == 4) {
7687 e |= ((nat->nat_osrcaddr & x[i + 4]) ==
7690 if (nat->nat_v[1] == 4) {
7691 e |= ((nat->nat_nsrcaddr & x[i + 4]) ==
7694 if (nat->nat_v[0] == 4) {
7695 e |= ((nat->nat_odstaddr & x[i + 4]) ==
7698 if (nat->nat_v[1] == 4) {
7699 e |= ((nat->nat_ndstaddr & x[i + 4]) ==
7707 if (nat->nat_v[0] == 6) {
7709 e |= IP6_MASKEQ(&nat->nat_osrc6,
7713 if (nat->nat_v[1] == 6) {
7715 e |= IP6_MASKEQ(&nat->nat_nsrc6,
7722 if (nat->nat_v[0] == 6) {
7724 e |= IP6_MASKEQ(&nat->nat_odst6,
7729 if (nat->nat_v[1] == 6) {
7731 e |= IP6_MASKEQ(&nat->nat_ndst6,
7740 if (nat->nat_v[0] == 6) {
7741 e |= IP6_MASKEQ(&nat->nat_osrc6,
7745 if (nat->nat_v[0] == 6) {
7746 e |= IP6_MASKEQ(&nat->nat_odst6,
7750 if (nat->nat_v[1] == 6) {
7751 e |= IP6_MASKEQ(&nat->nat_nsrc6,
7755 if (nat->nat_v[1] == 6) {
7756 e |= IP6_MASKEQ(&nat->nat_ndst6,
7767 e |= (nat->nat_nsport == x[i + 3]) ||
7768 (nat->nat_ndport == x[i + 3]);
7775 e |= (nat->nat_nsport == x[i + 3]);
7782 e |= (nat->nat_ndport == x[i + 3]);
7788 e |= (nat->nat_tcpstate[0] == x[i + 3]) ||
7789 (nat->nat_tcpstate[1] == x[i + 3]);
7794 e |= (ticks - nat->nat_touched > x[3]);
7811 /* softn(I) - pointer to NAT context structure */
7814 /* This function handles ioctl requests for tables of nat information. */
7861 /* Apply the timeout change to the NAT timeout queues. */
7897 /* To change the size of the basic NAT table, we need to first allocate the */
7898 /* new tables (lest it fails and we've got nowhere to store all of the NAT */
7901 /* and an outbound one. Each NAT entry goes into each table once. */
7907 nat_t **newtab[2], *nat, **natp;
7927 * 4 tables depend on the NAT table size: the inbound looking table,
7997 * Walk through the entire list of NAT table entries and put them
7998 * in the new NAT table, somewhere. Because we have a new table,
8004 for (nat = softn->ipf_nat_instances; nat != NULL; nat = nat->nat_next) {
8005 nat->nat_hnext[0] = NULL;
8006 nat->nat_phnext[0] = NULL;
8007 hv = nat->nat_hv[0] % softn->ipf_nat_table_sz;
8011 (*natp)->nat_phnext[0] = &nat->nat_hnext[0];
8015 nat->nat_phnext[0] = natp;
8016 nat->nat_hnext[0] = *natp;
8017 *natp = nat;
8020 nat->nat_hnext[1] = NULL;
8021 nat->nat_phnext[1] = NULL;
8022 hv = nat->nat_hv[1] % softn->ipf_nat_table_sz;
8026 (*natp)->nat_phnext[1] = &nat->nat_hnext[1];
8030 nat->nat_phnext[1] = natp;
8031 nat->nat_hnext[1] = *natp;
8032 *natp = nat;
8064 /* All of the NAT rules hang off of a hash table that is searched with a */
8217 /* This function is used to remove a NAT entry from the NAT table when we */
8231 nat_t *nat;
8249 nat = ipf_nat_outlookup(fin, nflags, (u_int)fin->fin_p,
8252 nat = ipf_nat_inlookup(fin, nflags, (u_int)fin->fin_p,
8256 if (nat != NULL) {
8258 ipf_nat_delete(softc, nat, NL_DESTROY);
8328 /* softn(I) - pointer to NAT context structure */