ip_fw_sockopt.c (231076) | ip_fw_sockopt.c (232865) |
---|---|
1/*- 2 * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa 3 * 4 * Supported by: Valeria Paoli 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 12 unchanged lines hidden (view full) --- 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa 3 * 4 * Supported by: Valeria Paoli 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 12 unchanged lines hidden (view full) --- 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> |
29__FBSDID("$FreeBSD: head/sys/netinet/ipfw/ip_fw_sockopt.c 231076 2012-02-06 11:35:29Z glebius $"); | 29__FBSDID("$FreeBSD: head/sys/netinet/ipfw/ip_fw_sockopt.c 232865 2012-03-12 14:07:57Z melifaro $"); |
30 31/* 32 * Sockopt support for ipfw. The routines here implement 33 * the upper half of the ipfw code. 34 */ 35 36#include "opt_ipfw.h" 37#include "opt_inet.h" --- 624 unchanged lines hidden (view full) --- 662 cmd->arg1); 663 return (EINVAL); 664 } 665 if (cmdlen != F_INSN_SIZE(ipfw_insn) && 666 cmdlen != F_INSN_SIZE(ipfw_insn_u32) + 1 && 667 cmdlen != F_INSN_SIZE(ipfw_insn_u32)) 668 goto bad_size; 669 break; | 30 31/* 32 * Sockopt support for ipfw. The routines here implement 33 * the upper half of the ipfw code. 34 */ 35 36#include "opt_ipfw.h" 37#include "opt_inet.h" --- 624 unchanged lines hidden (view full) --- 662 cmd->arg1); 663 return (EINVAL); 664 } 665 if (cmdlen != F_INSN_SIZE(ipfw_insn) && 666 cmdlen != F_INSN_SIZE(ipfw_insn_u32) + 1 && 667 cmdlen != F_INSN_SIZE(ipfw_insn_u32)) 668 goto bad_size; 669 break; |
670 | |
671 case O_MACADDR2: 672 if (cmdlen != F_INSN_SIZE(ipfw_insn_mac)) 673 goto bad_size; 674 break; 675 676 case O_NOP: 677 case O_IPID: 678 case O_IPTTL: --- 257 unchanged lines hidden (view full) --- 936 dst->timestamp += boot_seconds; 937 bp += l; 938 } 939 ipfw_get_dynamic(&bp, ep); /* protected by the dynamic lock */ 940 return (bp - (char *)buf); 941} 942 943 | 670 case O_MACADDR2: 671 if (cmdlen != F_INSN_SIZE(ipfw_insn_mac)) 672 goto bad_size; 673 break; 674 675 case O_NOP: 676 case O_IPID: 677 case O_IPTTL: --- 257 unchanged lines hidden (view full) --- 935 dst->timestamp += boot_seconds; 936 bp += l; 937 } 938 ipfw_get_dynamic(&bp, ep); /* protected by the dynamic lock */ 939 return (bp - (char *)buf); 940} 941 942 |
943#define IP_FW3_OPLENGTH(x) ((x)->sopt_valsize - sizeof(ip_fw3_opheader)) |
|
944/** 945 * {set|get}sockopt parser. 946 */ 947int 948ipfw_ctl(struct sockopt *sopt) 949{ 950#define RULE_MAXSIZE (256*sizeof(u_int32_t)) 951 int error; | 944/** 945 * {set|get}sockopt parser. 946 */ 947int 948ipfw_ctl(struct sockopt *sopt) 949{ 950#define RULE_MAXSIZE (256*sizeof(u_int32_t)) 951 int error; |
952 size_t size; | 952 size_t size, len, valsize; |
953 struct ip_fw *buf, *rule; 954 struct ip_fw_chain *chain; 955 u_int32_t rulenum[2]; | 953 struct ip_fw *buf, *rule; 954 struct ip_fw_chain *chain; 955 u_int32_t rulenum[2]; |
956 uint32_t opt; 957 char xbuf[128]; 958 ip_fw3_opheader *op3 = NULL; |
|
956 957 error = priv_check(sopt->sopt_td, PRIV_NETINET_IPFW); 958 if (error) 959 return (error); 960 961 /* 962 * Disallow modifications in really-really secure mode, but still allow 963 * the logging counters to be reset. 964 */ 965 if (sopt->sopt_name == IP_FW_ADD || 966 (sopt->sopt_dir == SOPT_SET && sopt->sopt_name != IP_FW_RESETLOG)) { 967 error = securelevel_ge(sopt->sopt_td->td_ucred, 3); 968 if (error) 969 return (error); 970 } 971 972 chain = &V_layer3_chain; 973 error = 0; 974 | 959 960 error = priv_check(sopt->sopt_td, PRIV_NETINET_IPFW); 961 if (error) 962 return (error); 963 964 /* 965 * Disallow modifications in really-really secure mode, but still allow 966 * the logging counters to be reset. 967 */ 968 if (sopt->sopt_name == IP_FW_ADD || 969 (sopt->sopt_dir == SOPT_SET && sopt->sopt_name != IP_FW_RESETLOG)) { 970 error = securelevel_ge(sopt->sopt_td->td_ucred, 3); 971 if (error) 972 return (error); 973 } 974 975 chain = &V_layer3_chain; 976 error = 0; 977 |
975 switch (sopt->sopt_name) { | 978 /* Save original valsize before it is altered via sooptcopyin() */ 979 valsize = sopt->sopt_valsize; 980 if ((opt = sopt->sopt_name) == IP_FW3) { 981 /* 982 * Copy not less than sizeof(ip_fw3_opheader). 983 * We hope any IP_FW3 command will fit into 128-byte buffer. 984 */ 985 if ((error = sooptcopyin(sopt, xbuf, sizeof(xbuf), 986 sizeof(ip_fw3_opheader))) != 0) 987 return (error); 988 op3 = (ip_fw3_opheader *)xbuf; 989 opt = op3->opcode; 990 } 991 992 switch (opt) { |
976 case IP_FW_GET: 977 /* 978 * pass up a copy of the current rules. Static rules 979 * come first (the last of which has number IPFW_DEFAULT_RULE), 980 * followed by a possibly empty list of dynamic rule. 981 * The last dynamic rule has NULL in the "next" field. 982 * 983 * Note that the calculated size is used to bound the --- 122 unchanged lines hidden (view full) --- 1106 { 1107 ipfw_table_entry ent; 1108 1109 error = sooptcopyin(sopt, &ent, 1110 sizeof(ent), sizeof(ent)); 1111 if (error) 1112 break; 1113 error = ipfw_add_table_entry(chain, ent.tbl, | 993 case IP_FW_GET: 994 /* 995 * pass up a copy of the current rules. Static rules 996 * come first (the last of which has number IPFW_DEFAULT_RULE), 997 * followed by a possibly empty list of dynamic rule. 998 * The last dynamic rule has NULL in the "next" field. 999 * 1000 * Note that the calculated size is used to bound the --- 122 unchanged lines hidden (view full) --- 1123 { 1124 ipfw_table_entry ent; 1125 1126 error = sooptcopyin(sopt, &ent, 1127 sizeof(ent), sizeof(ent)); 1128 if (error) 1129 break; 1130 error = ipfw_add_table_entry(chain, ent.tbl, |
1114 ent.addr, ent.masklen, ent.value); | 1131 &ent.addr, sizeof(ent.addr), ent.masklen, 1132 IPFW_TABLE_CIDR, ent.value); |
1115 } 1116 break; 1117 1118 case IP_FW_TABLE_DEL: 1119 { 1120 ipfw_table_entry ent; 1121 1122 error = sooptcopyin(sopt, &ent, 1123 sizeof(ent), sizeof(ent)); 1124 if (error) 1125 break; 1126 error = ipfw_del_table_entry(chain, ent.tbl, | 1133 } 1134 break; 1135 1136 case IP_FW_TABLE_DEL: 1137 { 1138 ipfw_table_entry ent; 1139 1140 error = sooptcopyin(sopt, &ent, 1141 sizeof(ent), sizeof(ent)); 1142 if (error) 1143 break; 1144 error = ipfw_del_table_entry(chain, ent.tbl, |
1127 ent.addr, ent.masklen); | 1145 &ent.addr, sizeof(ent.addr), ent.masklen, IPFW_TABLE_CIDR); |
1128 } 1129 break; 1130 | 1146 } 1147 break; 1148 |
1149 case IP_FW_TABLE_XADD: /* IP_FW3 */ 1150 case IP_FW_TABLE_XDEL: /* IP_FW3 */ 1151 { 1152 ipfw_table_xentry *xent = (ipfw_table_xentry *)(op3 + 1); 1153 1154 /* Check minimum header size */ 1155 if (IP_FW3_OPLENGTH(sopt) < offsetof(ipfw_table_xentry, k)) { 1156 error = EINVAL; 1157 break; 1158 } 1159 1160 /* Check if len field is valid */ 1161 if (xent->len > sizeof(ipfw_table_xentry)) { 1162 error = EINVAL; 1163 break; 1164 } 1165 1166 len = xent->len - offsetof(ipfw_table_xentry, k); 1167 1168 error = (opt == IP_FW_TABLE_XADD) ? 1169 ipfw_add_table_entry(chain, xent->tbl, &xent->k, 1170 len, xent->masklen, xent->type, xent->value) : 1171 ipfw_del_table_entry(chain, xent->tbl, &xent->k, 1172 len, xent->masklen, xent->type); 1173 } 1174 break; 1175 |
|
1131 case IP_FW_TABLE_FLUSH: 1132 { 1133 u_int16_t tbl; 1134 1135 error = sooptcopyin(sopt, &tbl, 1136 sizeof(tbl), sizeof(tbl)); 1137 if (error) 1138 break; | 1176 case IP_FW_TABLE_FLUSH: 1177 { 1178 u_int16_t tbl; 1179 1180 error = sooptcopyin(sopt, &tbl, 1181 sizeof(tbl), sizeof(tbl)); 1182 if (error) 1183 break; |
1139 IPFW_WLOCK(chain); | |
1140 error = ipfw_flush_table(chain, tbl); | 1184 error = ipfw_flush_table(chain, tbl); |
1141 IPFW_WUNLOCK(chain); | |
1142 } 1143 break; 1144 1145 case IP_FW_TABLE_GETSIZE: 1146 { 1147 u_int32_t tbl, cnt; 1148 1149 if ((error = sooptcopyin(sopt, &tbl, sizeof(tbl), --- 32 unchanged lines hidden (view full) --- 1182 free(tbl, M_TEMP); 1183 break; 1184 } 1185 error = sooptcopyout(sopt, tbl, size); 1186 free(tbl, M_TEMP); 1187 } 1188 break; 1189 | 1185 } 1186 break; 1187 1188 case IP_FW_TABLE_GETSIZE: 1189 { 1190 u_int32_t tbl, cnt; 1191 1192 if ((error = sooptcopyin(sopt, &tbl, sizeof(tbl), --- 32 unchanged lines hidden (view full) --- 1225 free(tbl, M_TEMP); 1226 break; 1227 } 1228 error = sooptcopyout(sopt, tbl, size); 1229 free(tbl, M_TEMP); 1230 } 1231 break; 1232 |
1233 case IP_FW_TABLE_XGETSIZE: /* IP_FW3 */ 1234 { 1235 uint32_t *tbl; 1236 1237 if (IP_FW3_OPLENGTH(sopt) < sizeof(uint32_t)) { 1238 error = EINVAL; 1239 break; 1240 } 1241 1242 tbl = (uint32_t *)(op3 + 1); 1243 1244 IPFW_RLOCK(chain); 1245 error = ipfw_count_xtable(chain, *tbl, tbl); 1246 IPFW_RUNLOCK(chain); 1247 if (error) 1248 break; 1249 error = sooptcopyout(sopt, op3, sopt->sopt_valsize); 1250 } 1251 break; 1252 1253 case IP_FW_TABLE_XLIST: /* IP_FW3 */ 1254 { 1255 ipfw_xtable *tbl; 1256 1257 if ((size = valsize) < sizeof(ipfw_xtable)) { 1258 error = EINVAL; 1259 break; 1260 } 1261 1262 tbl = malloc(size, M_TEMP, M_ZERO | M_WAITOK); 1263 memcpy(tbl, op3, sizeof(ipfw_xtable)); 1264 1265 /* Get maximum number of entries we can store */ 1266 tbl->size = (size - sizeof(ipfw_xtable)) / 1267 sizeof(ipfw_table_xentry); 1268 IPFW_RLOCK(chain); 1269 error = ipfw_dump_xtable(chain, tbl); 1270 IPFW_RUNLOCK(chain); 1271 if (error) { 1272 free(tbl, M_TEMP); 1273 break; 1274 } 1275 1276 /* Revert size field back to bytes */ 1277 tbl->size = tbl->size * sizeof(ipfw_table_xentry) + 1278 sizeof(ipfw_table); 1279 /* 1280 * Since we call sooptcopyin() with small buffer, sopt_valsize is 1281 * decreased to reflect supplied buffer size. Set it back to original value 1282 */ 1283 sopt->sopt_valsize = valsize; 1284 error = sooptcopyout(sopt, tbl, size); 1285 free(tbl, M_TEMP); 1286 } 1287 break; 1288 |
|
1190 /*--- NAT operations are protected by the IPFW_LOCK ---*/ 1191 case IP_FW_NAT_CFG: 1192 if (IPFW_NAT_LOADED) 1193 error = ipfw_nat_cfg_ptr(sopt); 1194 else { 1195 printf("IP_FW_NAT_CFG: %s\n", 1196 "ipfw_nat not present, please load it"); 1197 error = EINVAL; --- 156 unchanged lines hidden --- | 1289 /*--- NAT operations are protected by the IPFW_LOCK ---*/ 1290 case IP_FW_NAT_CFG: 1291 if (IPFW_NAT_LOADED) 1292 error = ipfw_nat_cfg_ptr(sopt); 1293 else { 1294 printf("IP_FW_NAT_CFG: %s\n", 1295 "ipfw_nat not present, please load it"); 1296 error = EINVAL; --- 156 unchanged lines hidden --- |