ip_nat.c (172776) | ip_nat.c (173181) |
---|---|
1/* $FreeBSD: head/sys/contrib/ipfilter/netinet/ip_nat.c 172776 2007-10-18 21:52:14Z darrenr $ */ | 1/* $FreeBSD: head/sys/contrib/ipfilter/netinet/ip_nat.c 173181 2007-10-30 15:23:27Z darrenr $ */ |
2 3/* 4 * Copyright (C) 1995-2003 by Darren Reed. 5 * 6 * See the IPFILTER.LICENCE file for details on licencing. 7 */ 8#if defined(KERNEL) || defined(_KERNEL) 9# undef KERNEL --- 102 unchanged lines hidden (view full) --- 112#endif 113/* END OF INCLUDES */ 114 115#undef SOCKADDR_IN 116#define SOCKADDR_IN struct sockaddr_in 117 118#if !defined(lint) 119static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed"; | 2 3/* 4 * Copyright (C) 1995-2003 by Darren Reed. 5 * 6 * See the IPFILTER.LICENCE file for details on licencing. 7 */ 8#if defined(KERNEL) || defined(_KERNEL) 9# undef KERNEL --- 102 unchanged lines hidden (view full) --- 112#endif 113/* END OF INCLUDES */ 114 115#undef SOCKADDR_IN 116#define SOCKADDR_IN struct sockaddr_in 117 118#if !defined(lint) 119static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed"; |
120static const char rcsid[] = "@(#)$FreeBSD: head/sys/contrib/ipfilter/netinet/ip_nat.c 172776 2007-10-18 21:52:14Z darrenr $"; | 120static const char rcsid[] = "@(#)$FreeBSD: head/sys/contrib/ipfilter/netinet/ip_nat.c 173181 2007-10-30 15:23:27Z darrenr $"; |
121/* static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.195.2.102 2007/10/16 10:08:10 darrenr Exp $"; */ 122#endif 123 124 125/* ======================================================================== */ 126/* How the NAT is organised and works. */ 127/* */ 128/* Inside (interface y) NAT Outside (interface x) */ --- 56 unchanged lines hidden (view full) --- 185 186static int nat_flush_entry __P((void *)); 187static int nat_flushtable __P((void)); 188static int nat_clearlist __P((void)); 189static void nat_addnat __P((struct ipnat *)); 190static void nat_addrdr __P((struct ipnat *)); 191static void nat_delrdr __P((struct ipnat *)); 192static void nat_delnat __P((struct ipnat *)); | 121/* static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.195.2.102 2007/10/16 10:08:10 darrenr Exp $"; */ 122#endif 123 124 125/* ======================================================================== */ 126/* How the NAT is organised and works. */ 127/* */ 128/* Inside (interface y) NAT Outside (interface x) */ --- 56 unchanged lines hidden (view full) --- 185 186static int nat_flush_entry __P((void *)); 187static int nat_flushtable __P((void)); 188static int nat_clearlist __P((void)); 189static void nat_addnat __P((struct ipnat *)); 190static void nat_addrdr __P((struct ipnat *)); 191static void nat_delrdr __P((struct ipnat *)); 192static void nat_delnat __P((struct ipnat *)); |
193static int fr_natgetent __P((caddr_t)); 194static int fr_natgetsz __P((caddr_t)); | 193static int fr_natgetent __P((caddr_t, int)); 194static int fr_natgetsz __P((caddr_t, int)); |
195static int fr_natputent __P((caddr_t, int)); 196static int nat_extraflush __P((int)); 197static int nat_gettable __P((char *)); 198static void nat_tabmove __P((nat_t *)); 199static int nat_match __P((fr_info_t *, ipnat_t *)); 200static INLINE int nat_newmap __P((fr_info_t *, nat_t *, natinfo_t *)); 201static INLINE int nat_newrdr __P((fr_info_t *, nat_t *, natinfo_t *)); 202static hostmap_t *nat_hostmap __P((ipnat_t *, struct in_addr, --- 612 unchanged lines hidden (view full) --- 815 nat_stats.ns_ticks = fr_ticks; 816 error = fr_outobj(data, &nat_stats, IPFOBJ_NATSTAT); 817 break; 818 819 case SIOCGNATL : 820 { 821 natlookup_t nl; 822 | 195static int fr_natputent __P((caddr_t, int)); 196static int nat_extraflush __P((int)); 197static int nat_gettable __P((char *)); 198static void nat_tabmove __P((nat_t *)); 199static int nat_match __P((fr_info_t *, ipnat_t *)); 200static INLINE int nat_newmap __P((fr_info_t *, nat_t *, natinfo_t *)); 201static INLINE int nat_newrdr __P((fr_info_t *, nat_t *, natinfo_t *)); 202static hostmap_t *nat_hostmap __P((ipnat_t *, struct in_addr, --- 612 unchanged lines hidden (view full) --- 815 nat_stats.ns_ticks = fr_ticks; 816 error = fr_outobj(data, &nat_stats, IPFOBJ_NATSTAT); 817 break; 818 819 case SIOCGNATL : 820 { 821 natlookup_t nl; 822 |
823 if (getlock) { 824 READ_ENTER(&ipf_nat); 825 } | |
826 error = fr_inobj(data, &nl, IPFOBJ_NATLOOKUP); 827 if (error == 0) { | 823 error = fr_inobj(data, &nl, IPFOBJ_NATLOOKUP); 824 if (error == 0) { |
828 if (nat_lookupredir(&nl) != NULL) { | 825 void *ptr; 826 827 if (getlock) { 828 READ_ENTER(&ipf_nat); 829 } 830 ptr = nat_lookupredir(&nl); 831 if (getlock) { 832 RWLOCK_EXIT(&ipf_nat); 833 } 834 if (ptr != NULL) { |
829 error = fr_outobj(data, &nl, IPFOBJ_NATLOOKUP); 830 } else { 831 error = ESRCH; 832 } 833 } | 835 error = fr_outobj(data, &nl, IPFOBJ_NATLOOKUP); 836 } else { 837 error = ESRCH; 838 } 839 } |
834 if (getlock) { 835 RWLOCK_EXIT(&ipf_nat); 836 } | |
837 break; 838 } 839 840 case SIOCIPFFL : /* old SIOCFLNAT & SIOCCNATL */ 841 if (!(mode & FWRITE)) { 842 error = EPERM; 843 break; 844 } --- 38 unchanged lines hidden (view full) --- 883 error = fr_natputent(data, getlock); 884 } else { 885 error = EACCES; 886 } 887 break; 888 889 case SIOCSTGSZ : 890 if (fr_nat_lock) { | 840 break; 841 } 842 843 case SIOCIPFFL : /* old SIOCFLNAT & SIOCCNATL */ 844 if (!(mode & FWRITE)) { 845 error = EPERM; 846 break; 847 } --- 38 unchanged lines hidden (view full) --- 886 error = fr_natputent(data, getlock); 887 } else { 888 error = EACCES; 889 } 890 break; 891 892 case SIOCSTGSZ : 893 if (fr_nat_lock) { |
891 if (getlock) { 892 READ_ENTER(&ipf_nat); 893 } 894 error = fr_natgetsz(data); 895 if (getlock) { 896 RWLOCK_EXIT(&ipf_nat); 897 } | 894 error = fr_natgetsz(data, getlock); |
898 } else 899 error = EACCES; 900 break; 901 902 case SIOCSTGET : 903 if (fr_nat_lock) { | 895 } else 896 error = EACCES; 897 break; 898 899 case SIOCSTGET : 900 if (fr_nat_lock) { |
904 if (getlock) { 905 READ_ENTER(&ipf_nat); 906 } 907 error = fr_natgetent(data); 908 if (getlock) { 909 RWLOCK_EXIT(&ipf_nat); 910 } | 901 error = fr_natgetent(data, getlock); |
911 } else 912 error = EACCES; 913 break; 914 915 case SIOCGENITER : 916 { 917 ipfgeniter_t iter; 918 ipftoken_t *token; --- 278 unchanged lines hidden (view full) --- 1197/* Parameters: data(I) - pointer to natget structure with kernel pointer */ 1198/* get the size of. */ 1199/* */ 1200/* Handle SIOCSTGSZ. */ 1201/* Return the size of the nat list entry to be copied back to user space. */ 1202/* The size of the entry is stored in the ng_sz field and the enture natget */ 1203/* structure is copied back to the user. */ 1204/* ------------------------------------------------------------------------ */ | 902 } else 903 error = EACCES; 904 break; 905 906 case SIOCGENITER : 907 { 908 ipfgeniter_t iter; 909 ipftoken_t *token; --- 278 unchanged lines hidden (view full) --- 1188/* Parameters: data(I) - pointer to natget structure with kernel pointer */ 1189/* get the size of. */ 1190/* */ 1191/* Handle SIOCSTGSZ. */ 1192/* Return the size of the nat list entry to be copied back to user space. */ 1193/* The size of the entry is stored in the ng_sz field and the enture natget */ 1194/* structure is copied back to the user. */ 1195/* ------------------------------------------------------------------------ */ |
1205static int fr_natgetsz(data) | 1196static int fr_natgetsz(data, getlock) |
1206caddr_t data; | 1197caddr_t data; |
1198int getlock; |
|
1207{ 1208 ap_session_t *aps; 1209 nat_t *nat, *n; 1210 natget_t ng; 1211 1212 if (BCOPYIN(data, &ng, sizeof(ng)) != 0) 1213 return EFAULT; 1214 | 1199{ 1200 ap_session_t *aps; 1201 nat_t *nat, *n; 1202 natget_t ng; 1203 1204 if (BCOPYIN(data, &ng, sizeof(ng)) != 0) 1205 return EFAULT; 1206 |
1207 if (getlock) { 1208 READ_ENTER(&ipf_nat); 1209 } 1210 |
|
1215 nat = ng.ng_ptr; 1216 if (!nat) { 1217 nat = nat_instances; 1218 ng.ng_sz = 0; 1219 /* 1220 * Empty list so the size returned is 0. Simple. 1221 */ 1222 if (nat == NULL) { | 1211 nat = ng.ng_ptr; 1212 if (!nat) { 1213 nat = nat_instances; 1214 ng.ng_sz = 0; 1215 /* 1216 * Empty list so the size returned is 0. Simple. 1217 */ 1218 if (nat == NULL) { |
1219 if (getlock) { 1220 RWLOCK_EXIT(&ipf_nat); 1221 } |
|
1223 if (BCOPYOUT(&ng, data, sizeof(ng)) != 0) 1224 return EFAULT; 1225 return 0; 1226 } 1227 } else { 1228 /* 1229 * Make sure the pointer we're copying from exists in the 1230 * current list of entries. Security precaution to prevent 1231 * copying of random kernel data. 1232 */ 1233 for (n = nat_instances; n; n = n->nat_next) 1234 if (n == nat) 1235 break; | 1222 if (BCOPYOUT(&ng, data, sizeof(ng)) != 0) 1223 return EFAULT; 1224 return 0; 1225 } 1226 } else { 1227 /* 1228 * Make sure the pointer we're copying from exists in the 1229 * current list of entries. Security precaution to prevent 1230 * copying of random kernel data. 1231 */ 1232 for (n = nat_instances; n; n = n->nat_next) 1233 if (n == nat) 1234 break; |
1236 if (!n) | 1235 if (n == NULL) { 1236 if (getlock) { 1237 RWLOCK_EXIT(&ipf_nat); 1238 } |
1237 return ESRCH; | 1239 return ESRCH; |
1240 } |
|
1238 } 1239 1240 /* 1241 * Incluse any space required for proxy data structures. 1242 */ 1243 ng.ng_sz = sizeof(nat_save_t); 1244 aps = nat->nat_aps; 1245 if (aps != NULL) { 1246 ng.ng_sz += sizeof(ap_session_t) - 4; 1247 if (aps->aps_data != 0) 1248 ng.ng_sz += aps->aps_psiz; 1249 } | 1241 } 1242 1243 /* 1244 * Incluse any space required for proxy data structures. 1245 */ 1246 ng.ng_sz = sizeof(nat_save_t); 1247 aps = nat->nat_aps; 1248 if (aps != NULL) { 1249 ng.ng_sz += sizeof(ap_session_t) - 4; 1250 if (aps->aps_data != 0) 1251 ng.ng_sz += aps->aps_psiz; 1252 } |
1253 if (getlock) { 1254 RWLOCK_EXIT(&ipf_nat); 1255 } |
|
1250 1251 if (BCOPYOUT(&ng, data, sizeof(ng)) != 0) 1252 return EFAULT; 1253 return 0; 1254} 1255 1256 1257/* ------------------------------------------------------------------------ */ 1258/* Function: fr_natgetent */ 1259/* Returns: int - 0 == success, != 0 is the error value. */ 1260/* Parameters: data(I) - pointer to natget structure with kernel pointer */ 1261/* to NAT structure to copy out. */ 1262/* */ 1263/* Handle SIOCSTGET. */ 1264/* Copies out NAT entry to user space. Any additional data held for a */ 1265/* proxy is also copied, as to is the NAT rule which was responsible for it */ 1266/* ------------------------------------------------------------------------ */ | 1256 1257 if (BCOPYOUT(&ng, data, sizeof(ng)) != 0) 1258 return EFAULT; 1259 return 0; 1260} 1261 1262 1263/* ------------------------------------------------------------------------ */ 1264/* Function: fr_natgetent */ 1265/* Returns: int - 0 == success, != 0 is the error value. */ 1266/* Parameters: data(I) - pointer to natget structure with kernel pointer */ 1267/* to NAT structure to copy out. */ 1268/* */ 1269/* Handle SIOCSTGET. */ 1270/* Copies out NAT entry to user space. Any additional data held for a */ 1271/* proxy is also copied, as to is the NAT rule which was responsible for it */ 1272/* ------------------------------------------------------------------------ */ |
1267static int fr_natgetent(data) | 1273static int fr_natgetent(data, getlock) |
1268caddr_t data; | 1274caddr_t data; |
1275int getlock; |
|
1269{ 1270 int error, outsize; 1271 ap_session_t *aps; 1272 nat_save_t *ipn, ipns; 1273 nat_t *n, *nat; 1274 1275 error = fr_inobj(data, &ipns, IPFOBJ_NATSAVE); 1276 if (error != 0) 1277 return error; 1278 1279 if ((ipns.ipn_dsize < sizeof(ipns)) || (ipns.ipn_dsize > 81920)) 1280 return EINVAL; 1281 1282 KMALLOCS(ipn, nat_save_t *, ipns.ipn_dsize); 1283 if (ipn == NULL) 1284 return ENOMEM; 1285 | 1276{ 1277 int error, outsize; 1278 ap_session_t *aps; 1279 nat_save_t *ipn, ipns; 1280 nat_t *n, *nat; 1281 1282 error = fr_inobj(data, &ipns, IPFOBJ_NATSAVE); 1283 if (error != 0) 1284 return error; 1285 1286 if ((ipns.ipn_dsize < sizeof(ipns)) || (ipns.ipn_dsize > 81920)) 1287 return EINVAL; 1288 1289 KMALLOCS(ipn, nat_save_t *, ipns.ipn_dsize); 1290 if (ipn == NULL) 1291 return ENOMEM; 1292 |
1293 if (getlock) { 1294 READ_ENTER(&ipf_nat); 1295 } 1296 |
|
1286 ipn->ipn_dsize = ipns.ipn_dsize; 1287 nat = ipns.ipn_next; 1288 if (nat == NULL) { 1289 nat = nat_instances; 1290 if (nat == NULL) { 1291 if (nat_instances == NULL) 1292 error = ENOENT; 1293 goto finished; --- 54 unchanged lines hidden (view full) --- 1348 s += sizeof(*aps); 1349 outsize -= sizeof(*aps); 1350 if ((aps->aps_data != NULL) && (outsize >= aps->aps_psiz)) 1351 bcopy(aps->aps_data, s, aps->aps_psiz); 1352 else 1353 error = ENOBUFS; 1354 } 1355 if (error == 0) { | 1297 ipn->ipn_dsize = ipns.ipn_dsize; 1298 nat = ipns.ipn_next; 1299 if (nat == NULL) { 1300 nat = nat_instances; 1301 if (nat == NULL) { 1302 if (nat_instances == NULL) 1303 error = ENOENT; 1304 goto finished; --- 54 unchanged lines hidden (view full) --- 1359 s += sizeof(*aps); 1360 outsize -= sizeof(*aps); 1361 if ((aps->aps_data != NULL) && (outsize >= aps->aps_psiz)) 1362 bcopy(aps->aps_data, s, aps->aps_psiz); 1363 else 1364 error = ENOBUFS; 1365 } 1366 if (error == 0) { |
1367 if (getlock) { 1368 RWLOCK_EXIT(&ipf_nat); 1369 getlock = 0; 1370 } |
|
1356 error = fr_outobjsz(data, ipn, IPFOBJ_NATSAVE, ipns.ipn_dsize); 1357 } 1358 1359finished: | 1371 error = fr_outobjsz(data, ipn, IPFOBJ_NATSAVE, ipns.ipn_dsize); 1372 } 1373 1374finished: |
1375 if (getlock) { 1376 RWLOCK_EXIT(&ipf_nat); 1377 } |
|
1360 if (ipn != NULL) { 1361 KFREES(ipn, ipns.ipn_dsize); 1362 } 1363 return error; 1364} 1365 1366 1367/* ------------------------------------------------------------------------ */ --- 4093 unchanged lines hidden --- | 1378 if (ipn != NULL) { 1379 KFREES(ipn, ipns.ipn_dsize); 1380 } 1381 return error; 1382} 1383 1384 1385/* ------------------------------------------------------------------------ */ --- 4093 unchanged lines hidden --- |