35#include "opt_ipdivert.h" 36#include "opt_ipdn.h" 37#include "opt_inet.h" 38#ifndef INET 39#error IPFIREWALL requires INET. 40#endif /* INET */ 41#endif 42#include "opt_inet6.h" 43#include "opt_ipsec.h" 44 45#include <sys/param.h> 46#include <sys/systm.h> 47#include <sys/mbuf.h> 48#include <sys/kernel.h> 49#include <sys/socket.h> 50#include <sys/sysctl.h> 51#include <sys/syslog.h> 52#include <net/ethernet.h> /* for ETHERTYPE_IP */ 53#include <net/if.h> 54#include <net/vnet.h> 55#include <net/if_types.h> /* for IFT_ETHER */ 56#include <net/bpf.h> /* for BPF */ 57 58#include <netinet/in.h> 59#include <netinet/ip.h> 60#include <netinet/ip_icmp.h> 61#include <netinet/ip_var.h> 62#include <netinet/ip_fw.h> 63#include <netinet/ipfw/ip_fw_private.h> 64#include <netinet/tcp_var.h> 65#include <netinet/udp.h> 66 67#include <netinet/ip6.h> 68#include <netinet/icmp6.h> 69#ifdef INET6 70#include <netinet6/in6_var.h> /* ip6_sprintf() */ 71#endif 72 73#ifdef MAC 74#include <security/mac/mac_framework.h> 75#endif 76 77/* 78 * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T 79 * Other macros just cast void * into the appropriate type 80 */ 81#define L3HDR(T, ip) ((T *)((u_int32_t *)(ip) + (ip)->ip_hl)) 82#define TCP(p) ((struct tcphdr *)(p)) 83#define SCTP(p) ((struct sctphdr *)(p)) 84#define UDP(p) ((struct udphdr *)(p)) 85#define ICMP(p) ((struct icmphdr *)(p)) 86#define ICMP6(p) ((struct icmp6_hdr *)(p)) 87 88#define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0 89#define SNP(buf) buf, sizeof(buf) 90 91#ifdef WITHOUT_BPF 92void 93ipfw_log_bpf(int onoff) 94{ 95} 96#else /* !WITHOUT_BPF */ 97static struct ifnet *log_if; /* hook to attach to bpf */ 98 99/* we use this dummy function for all ifnet callbacks */ 100static int 101log_dummy(struct ifnet *ifp, u_long cmd, caddr_t addr) 102{ 103 return EINVAL; 104} 105 106static int 107ipfw_log_output(struct ifnet *ifp, struct mbuf *m, 108 struct sockaddr *dst, struct route *ro) 109{ 110 if (m != NULL) 111 m_freem(m); 112 return EINVAL; 113} 114 115static void 116ipfw_log_start(struct ifnet* ifp) 117{ 118 panic("ipfw_log_start() must not be called"); 119} 120 121static const u_char ipfwbroadcastaddr[6] = 122 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 123 124void 125ipfw_log_bpf(int onoff) 126{ 127 struct ifnet *ifp; 128 129 if (onoff) { 130 if (log_if) 131 return; 132 ifp = if_alloc(IFT_ETHER); 133 if (ifp == NULL) 134 return; 135 if_initname(ifp, "ipfw", 0); 136 ifp->if_mtu = 65536; 137 ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST; 138 ifp->if_init = (void *)log_dummy; 139 ifp->if_ioctl = log_dummy; 140 ifp->if_start = ipfw_log_start; 141 ifp->if_output = ipfw_log_output; 142 ifp->if_addrlen = 6; 143 ifp->if_hdrlen = 14; 144 if_attach(ifp); 145 ifp->if_broadcastaddr = ipfwbroadcastaddr; 146 ifp->if_baudrate = IF_Mbps(10); 147 bpfattach(ifp, DLT_EN10MB, 14); 148 log_if = ifp; 149 } else { 150 if (log_if) { 151 ether_ifdetach(log_if); 152 if_free(log_if); 153 } 154 log_if = NULL; 155 } 156} 157#endif /* !WITHOUT_BPF */ 158 159/* 160 * We enter here when we have a rule with O_LOG. 161 * XXX this function alone takes about 2Kbytes of code! 162 */ 163void 164ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args, 165 struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg, 166 struct ip *ip) 167{ 168 char *action; 169 int limit_reached = 0; 170 char action2[92], proto[128], fragment[32]; 171 172 if (V_fw_verbose == 0) { 173#ifndef WITHOUT_BPF 174 175 if (log_if == NULL || log_if->if_bpf == NULL) 176 return; 177 178 if (args->eh) /* layer2, use orig hdr */ 179 BPF_MTAP2(log_if, args->eh, ETHER_HDR_LEN, m); 180 else 181 /* Add fake header. Later we will store 182 * more info in the header. 183 */ 184 BPF_MTAP2(log_if, "DDDDDDSSSSSS\x08\x00", ETHER_HDR_LEN, m); 185#endif /* !WITHOUT_BPF */ 186 return; 187 } 188 /* the old 'log' function */ 189 fragment[0] = '\0'; 190 proto[0] = '\0'; 191 192 if (f == NULL) { /* bogus pkt */ 193 if (V_verbose_limit != 0 && V_norule_counter >= V_verbose_limit) 194 return; 195 V_norule_counter++; 196 if (V_norule_counter == V_verbose_limit) 197 limit_reached = V_verbose_limit; 198 action = "Refuse"; 199 } else { /* O_LOG is the first action, find the real one */ 200 ipfw_insn *cmd = ACTION_PTR(f); 201 ipfw_insn_log *l = (ipfw_insn_log *)cmd; 202 203 if (l->max_log != 0 && l->log_left == 0) 204 return; 205 l->log_left--; 206 if (l->log_left == 0) 207 limit_reached = l->max_log; 208 cmd += F_LEN(cmd); /* point to first action */ 209 if (cmd->opcode == O_ALTQ) { 210 ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd; 211 212 snprintf(SNPARGS(action2, 0), "Altq %d", 213 altq->qid); 214 cmd += F_LEN(cmd); 215 } 216 if (cmd->opcode == O_PROB) 217 cmd += F_LEN(cmd); 218 219 if (cmd->opcode == O_TAG) 220 cmd += F_LEN(cmd); 221 222 action = action2; 223 switch (cmd->opcode) { 224 case O_DENY: 225 action = "Deny"; 226 break; 227 228 case O_REJECT: 229 if (cmd->arg1==ICMP_REJECT_RST) 230 action = "Reset"; 231 else if (cmd->arg1==ICMP_UNREACH_HOST) 232 action = "Reject"; 233 else 234 snprintf(SNPARGS(action2, 0), "Unreach %d", 235 cmd->arg1); 236 break; 237 238 case O_UNREACH6: 239 if (cmd->arg1==ICMP6_UNREACH_RST) 240 action = "Reset"; 241 else 242 snprintf(SNPARGS(action2, 0), "Unreach %d", 243 cmd->arg1); 244 break; 245 246 case O_ACCEPT: 247 action = "Accept"; 248 break; 249 case O_COUNT: 250 action = "Count"; 251 break; 252 case O_DIVERT: 253 snprintf(SNPARGS(action2, 0), "Divert %d", 254 cmd->arg1); 255 break; 256 case O_TEE: 257 snprintf(SNPARGS(action2, 0), "Tee %d", 258 cmd->arg1); 259 break; 260 case O_SETFIB: 261 snprintf(SNPARGS(action2, 0), "SetFib %d", 262 cmd->arg1); 263 break; 264 case O_SKIPTO: 265 snprintf(SNPARGS(action2, 0), "SkipTo %d", 266 cmd->arg1); 267 break; 268 case O_PIPE: 269 snprintf(SNPARGS(action2, 0), "Pipe %d", 270 cmd->arg1); 271 break; 272 case O_QUEUE: 273 snprintf(SNPARGS(action2, 0), "Queue %d", 274 cmd->arg1); 275 break; 276 case O_FORWARD_IP: { 277 ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd; 278 int len; 279 struct in_addr dummyaddr; 280 if (sa->sa.sin_addr.s_addr == INADDR_ANY) 281 dummyaddr.s_addr = htonl(tablearg); 282 else 283 dummyaddr.s_addr = sa->sa.sin_addr.s_addr; 284 285 len = snprintf(SNPARGS(action2, 0), "Forward to %s", 286 inet_ntoa(dummyaddr)); 287 288 if (sa->sa.sin_port) 289 snprintf(SNPARGS(action2, len), ":%d", 290 sa->sa.sin_port); 291 } 292 break; 293#ifdef INET6 294 case O_FORWARD_IP6: { 295 char buf[INET6_ADDRSTRLEN]; 296 ipfw_insn_sa6 *sa = (ipfw_insn_sa6 *)cmd; 297 int len; 298 299 len = snprintf(SNPARGS(action2, 0), "Forward to [%s]", 300 ip6_sprintf(buf, &sa->sa.sin6_addr)); 301 302 if (sa->sa.sin6_port) 303 snprintf(SNPARGS(action2, len), ":%u", 304 sa->sa.sin6_port); 305 } 306 break; 307#endif 308 case O_NETGRAPH: 309 snprintf(SNPARGS(action2, 0), "Netgraph %d", 310 cmd->arg1); 311 break; 312 case O_NGTEE: 313 snprintf(SNPARGS(action2, 0), "Ngtee %d", 314 cmd->arg1); 315 break; 316 case O_NAT: 317 action = "Nat"; 318 break; 319 case O_REASS: 320 action = "Reass"; 321 break; 322 case O_CALLRETURN: 323 if (cmd->len & F_NOT) 324 action = "Return"; 325 else 326 snprintf(SNPARGS(action2, 0), "Call %d", 327 cmd->arg1); 328 break; 329 default: 330 action = "UNKNOWN"; 331 break; 332 } 333 } 334 335 if (hlen == 0) { /* non-ip */ 336 snprintf(SNPARGS(proto, 0), "MAC"); 337 338 } else { 339 int len; 340#ifdef INET6 341 char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2]; 342#else 343 char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN]; 344#endif 345 struct icmphdr *icmp; 346 struct tcphdr *tcp; 347 struct udphdr *udp; 348#ifdef INET6 349 struct ip6_hdr *ip6 = NULL; 350 struct icmp6_hdr *icmp6; 351 u_short ip6f_mf; 352#endif 353 src[0] = '\0'; 354 dst[0] = '\0'; 355#ifdef INET6 356 ip6f_mf = offset & IP6F_MORE_FRAG; 357 offset &= IP6F_OFF_MASK; 358 359 if (IS_IP6_FLOW_ID(&(args->f_id))) { 360 char ip6buf[INET6_ADDRSTRLEN]; 361 snprintf(src, sizeof(src), "[%s]", 362 ip6_sprintf(ip6buf, &args->f_id.src_ip6)); 363 snprintf(dst, sizeof(dst), "[%s]", 364 ip6_sprintf(ip6buf, &args->f_id.dst_ip6)); 365 366 ip6 = (struct ip6_hdr *)ip; 367 tcp = (struct tcphdr *)(((char *)ip) + hlen); 368 udp = (struct udphdr *)(((char *)ip) + hlen); 369 } else 370#endif 371 { 372 tcp = L3HDR(struct tcphdr, ip); 373 udp = L3HDR(struct udphdr, ip); 374 375 inet_ntoa_r(ip->ip_src, src); 376 inet_ntoa_r(ip->ip_dst, dst); 377 } 378 379 switch (args->f_id.proto) { 380 case IPPROTO_TCP: 381 len = snprintf(SNPARGS(proto, 0), "TCP %s", src); 382 if (offset == 0) 383 snprintf(SNPARGS(proto, len), ":%d %s:%d", 384 ntohs(tcp->th_sport), 385 dst, 386 ntohs(tcp->th_dport)); 387 else 388 snprintf(SNPARGS(proto, len), " %s", dst); 389 break; 390 391 case IPPROTO_UDP: 392 len = snprintf(SNPARGS(proto, 0), "UDP %s", src); 393 if (offset == 0) 394 snprintf(SNPARGS(proto, len), ":%d %s:%d", 395 ntohs(udp->uh_sport), 396 dst, 397 ntohs(udp->uh_dport)); 398 else 399 snprintf(SNPARGS(proto, len), " %s", dst); 400 break; 401 402 case IPPROTO_ICMP: 403 icmp = L3HDR(struct icmphdr, ip); 404 if (offset == 0) 405 len = snprintf(SNPARGS(proto, 0), 406 "ICMP:%u.%u ", 407 icmp->icmp_type, icmp->icmp_code); 408 else 409 len = snprintf(SNPARGS(proto, 0), "ICMP "); 410 len += snprintf(SNPARGS(proto, len), "%s", src); 411 snprintf(SNPARGS(proto, len), " %s", dst); 412 break; 413#ifdef INET6 414 case IPPROTO_ICMPV6: 415 icmp6 = (struct icmp6_hdr *)(((char *)ip) + hlen); 416 if (offset == 0) 417 len = snprintf(SNPARGS(proto, 0), 418 "ICMPv6:%u.%u ", 419 icmp6->icmp6_type, icmp6->icmp6_code); 420 else 421 len = snprintf(SNPARGS(proto, 0), "ICMPv6 "); 422 len += snprintf(SNPARGS(proto, len), "%s", src); 423 snprintf(SNPARGS(proto, len), " %s", dst); 424 break; 425#endif 426 default: 427 len = snprintf(SNPARGS(proto, 0), "P:%d %s", 428 args->f_id.proto, src); 429 snprintf(SNPARGS(proto, len), " %s", dst); 430 break; 431 } 432 433#ifdef INET6 434 if (IS_IP6_FLOW_ID(&(args->f_id))) { 435 if (offset & (IP6F_OFF_MASK | IP6F_MORE_FRAG)) 436 snprintf(SNPARGS(fragment, 0), 437 " (frag %08x:%d@%d%s)", 438 args->f_id.extra, 439 ntohs(ip6->ip6_plen) - hlen, 440 ntohs(offset) << 3, ip6f_mf ? "+" : ""); 441 } else 442#endif 443 { 444 int ipoff, iplen; 445 ipoff = ntohs(ip->ip_off); 446 iplen = ntohs(ip->ip_len); 447 if (ipoff & (IP_MF | IP_OFFMASK)) 448 snprintf(SNPARGS(fragment, 0), 449 " (frag %d:%d@%d%s)", 450 ntohs(ip->ip_id), iplen - (ip->ip_hl << 2), 451 offset << 3, 452 (ipoff & IP_MF) ? "+" : ""); 453 } 454 } 455#ifdef __FreeBSD__ 456 if (oif || m->m_pkthdr.rcvif) 457 log(LOG_SECURITY | LOG_INFO, 458 "ipfw: %d %s %s %s via %s%s\n", 459 f ? f->rulenum : -1, 460 action, proto, oif ? "out" : "in", 461 oif ? oif->if_xname : m->m_pkthdr.rcvif->if_xname, 462 fragment); 463 else 464#endif 465 log(LOG_SECURITY | LOG_INFO, 466 "ipfw: %d %s %s [no if info]%s\n", 467 f ? f->rulenum : -1, 468 action, proto, fragment); 469 if (limit_reached) 470 log(LOG_SECURITY | LOG_NOTICE, 471 "ipfw: limit %d reached on entry %d\n", 472 limit_reached, f ? f->rulenum : -1); 473} 474/* end of file */
| 35#include "opt_ipdivert.h" 36#include "opt_ipdn.h" 37#include "opt_inet.h" 38#ifndef INET 39#error IPFIREWALL requires INET. 40#endif /* INET */ 41#endif 42#include "opt_inet6.h" 43#include "opt_ipsec.h" 44 45#include <sys/param.h> 46#include <sys/systm.h> 47#include <sys/mbuf.h> 48#include <sys/kernel.h> 49#include <sys/socket.h> 50#include <sys/sysctl.h> 51#include <sys/syslog.h> 52#include <net/ethernet.h> /* for ETHERTYPE_IP */ 53#include <net/if.h> 54#include <net/vnet.h> 55#include <net/if_types.h> /* for IFT_ETHER */ 56#include <net/bpf.h> /* for BPF */ 57 58#include <netinet/in.h> 59#include <netinet/ip.h> 60#include <netinet/ip_icmp.h> 61#include <netinet/ip_var.h> 62#include <netinet/ip_fw.h> 63#include <netinet/ipfw/ip_fw_private.h> 64#include <netinet/tcp_var.h> 65#include <netinet/udp.h> 66 67#include <netinet/ip6.h> 68#include <netinet/icmp6.h> 69#ifdef INET6 70#include <netinet6/in6_var.h> /* ip6_sprintf() */ 71#endif 72 73#ifdef MAC 74#include <security/mac/mac_framework.h> 75#endif 76 77/* 78 * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T 79 * Other macros just cast void * into the appropriate type 80 */ 81#define L3HDR(T, ip) ((T *)((u_int32_t *)(ip) + (ip)->ip_hl)) 82#define TCP(p) ((struct tcphdr *)(p)) 83#define SCTP(p) ((struct sctphdr *)(p)) 84#define UDP(p) ((struct udphdr *)(p)) 85#define ICMP(p) ((struct icmphdr *)(p)) 86#define ICMP6(p) ((struct icmp6_hdr *)(p)) 87 88#define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0 89#define SNP(buf) buf, sizeof(buf) 90 91#ifdef WITHOUT_BPF 92void 93ipfw_log_bpf(int onoff) 94{ 95} 96#else /* !WITHOUT_BPF */ 97static struct ifnet *log_if; /* hook to attach to bpf */ 98 99/* we use this dummy function for all ifnet callbacks */ 100static int 101log_dummy(struct ifnet *ifp, u_long cmd, caddr_t addr) 102{ 103 return EINVAL; 104} 105 106static int 107ipfw_log_output(struct ifnet *ifp, struct mbuf *m, 108 struct sockaddr *dst, struct route *ro) 109{ 110 if (m != NULL) 111 m_freem(m); 112 return EINVAL; 113} 114 115static void 116ipfw_log_start(struct ifnet* ifp) 117{ 118 panic("ipfw_log_start() must not be called"); 119} 120 121static const u_char ipfwbroadcastaddr[6] = 122 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 123 124void 125ipfw_log_bpf(int onoff) 126{ 127 struct ifnet *ifp; 128 129 if (onoff) { 130 if (log_if) 131 return; 132 ifp = if_alloc(IFT_ETHER); 133 if (ifp == NULL) 134 return; 135 if_initname(ifp, "ipfw", 0); 136 ifp->if_mtu = 65536; 137 ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST; 138 ifp->if_init = (void *)log_dummy; 139 ifp->if_ioctl = log_dummy; 140 ifp->if_start = ipfw_log_start; 141 ifp->if_output = ipfw_log_output; 142 ifp->if_addrlen = 6; 143 ifp->if_hdrlen = 14; 144 if_attach(ifp); 145 ifp->if_broadcastaddr = ipfwbroadcastaddr; 146 ifp->if_baudrate = IF_Mbps(10); 147 bpfattach(ifp, DLT_EN10MB, 14); 148 log_if = ifp; 149 } else { 150 if (log_if) { 151 ether_ifdetach(log_if); 152 if_free(log_if); 153 } 154 log_if = NULL; 155 } 156} 157#endif /* !WITHOUT_BPF */ 158 159/* 160 * We enter here when we have a rule with O_LOG. 161 * XXX this function alone takes about 2Kbytes of code! 162 */ 163void 164ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args, 165 struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg, 166 struct ip *ip) 167{ 168 char *action; 169 int limit_reached = 0; 170 char action2[92], proto[128], fragment[32]; 171 172 if (V_fw_verbose == 0) { 173#ifndef WITHOUT_BPF 174 175 if (log_if == NULL || log_if->if_bpf == NULL) 176 return; 177 178 if (args->eh) /* layer2, use orig hdr */ 179 BPF_MTAP2(log_if, args->eh, ETHER_HDR_LEN, m); 180 else 181 /* Add fake header. Later we will store 182 * more info in the header. 183 */ 184 BPF_MTAP2(log_if, "DDDDDDSSSSSS\x08\x00", ETHER_HDR_LEN, m); 185#endif /* !WITHOUT_BPF */ 186 return; 187 } 188 /* the old 'log' function */ 189 fragment[0] = '\0'; 190 proto[0] = '\0'; 191 192 if (f == NULL) { /* bogus pkt */ 193 if (V_verbose_limit != 0 && V_norule_counter >= V_verbose_limit) 194 return; 195 V_norule_counter++; 196 if (V_norule_counter == V_verbose_limit) 197 limit_reached = V_verbose_limit; 198 action = "Refuse"; 199 } else { /* O_LOG is the first action, find the real one */ 200 ipfw_insn *cmd = ACTION_PTR(f); 201 ipfw_insn_log *l = (ipfw_insn_log *)cmd; 202 203 if (l->max_log != 0 && l->log_left == 0) 204 return; 205 l->log_left--; 206 if (l->log_left == 0) 207 limit_reached = l->max_log; 208 cmd += F_LEN(cmd); /* point to first action */ 209 if (cmd->opcode == O_ALTQ) { 210 ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd; 211 212 snprintf(SNPARGS(action2, 0), "Altq %d", 213 altq->qid); 214 cmd += F_LEN(cmd); 215 } 216 if (cmd->opcode == O_PROB) 217 cmd += F_LEN(cmd); 218 219 if (cmd->opcode == O_TAG) 220 cmd += F_LEN(cmd); 221 222 action = action2; 223 switch (cmd->opcode) { 224 case O_DENY: 225 action = "Deny"; 226 break; 227 228 case O_REJECT: 229 if (cmd->arg1==ICMP_REJECT_RST) 230 action = "Reset"; 231 else if (cmd->arg1==ICMP_UNREACH_HOST) 232 action = "Reject"; 233 else 234 snprintf(SNPARGS(action2, 0), "Unreach %d", 235 cmd->arg1); 236 break; 237 238 case O_UNREACH6: 239 if (cmd->arg1==ICMP6_UNREACH_RST) 240 action = "Reset"; 241 else 242 snprintf(SNPARGS(action2, 0), "Unreach %d", 243 cmd->arg1); 244 break; 245 246 case O_ACCEPT: 247 action = "Accept"; 248 break; 249 case O_COUNT: 250 action = "Count"; 251 break; 252 case O_DIVERT: 253 snprintf(SNPARGS(action2, 0), "Divert %d", 254 cmd->arg1); 255 break; 256 case O_TEE: 257 snprintf(SNPARGS(action2, 0), "Tee %d", 258 cmd->arg1); 259 break; 260 case O_SETFIB: 261 snprintf(SNPARGS(action2, 0), "SetFib %d", 262 cmd->arg1); 263 break; 264 case O_SKIPTO: 265 snprintf(SNPARGS(action2, 0), "SkipTo %d", 266 cmd->arg1); 267 break; 268 case O_PIPE: 269 snprintf(SNPARGS(action2, 0), "Pipe %d", 270 cmd->arg1); 271 break; 272 case O_QUEUE: 273 snprintf(SNPARGS(action2, 0), "Queue %d", 274 cmd->arg1); 275 break; 276 case O_FORWARD_IP: { 277 ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd; 278 int len; 279 struct in_addr dummyaddr; 280 if (sa->sa.sin_addr.s_addr == INADDR_ANY) 281 dummyaddr.s_addr = htonl(tablearg); 282 else 283 dummyaddr.s_addr = sa->sa.sin_addr.s_addr; 284 285 len = snprintf(SNPARGS(action2, 0), "Forward to %s", 286 inet_ntoa(dummyaddr)); 287 288 if (sa->sa.sin_port) 289 snprintf(SNPARGS(action2, len), ":%d", 290 sa->sa.sin_port); 291 } 292 break; 293#ifdef INET6 294 case O_FORWARD_IP6: { 295 char buf[INET6_ADDRSTRLEN]; 296 ipfw_insn_sa6 *sa = (ipfw_insn_sa6 *)cmd; 297 int len; 298 299 len = snprintf(SNPARGS(action2, 0), "Forward to [%s]", 300 ip6_sprintf(buf, &sa->sa.sin6_addr)); 301 302 if (sa->sa.sin6_port) 303 snprintf(SNPARGS(action2, len), ":%u", 304 sa->sa.sin6_port); 305 } 306 break; 307#endif 308 case O_NETGRAPH: 309 snprintf(SNPARGS(action2, 0), "Netgraph %d", 310 cmd->arg1); 311 break; 312 case O_NGTEE: 313 snprintf(SNPARGS(action2, 0), "Ngtee %d", 314 cmd->arg1); 315 break; 316 case O_NAT: 317 action = "Nat"; 318 break; 319 case O_REASS: 320 action = "Reass"; 321 break; 322 case O_CALLRETURN: 323 if (cmd->len & F_NOT) 324 action = "Return"; 325 else 326 snprintf(SNPARGS(action2, 0), "Call %d", 327 cmd->arg1); 328 break; 329 default: 330 action = "UNKNOWN"; 331 break; 332 } 333 } 334 335 if (hlen == 0) { /* non-ip */ 336 snprintf(SNPARGS(proto, 0), "MAC"); 337 338 } else { 339 int len; 340#ifdef INET6 341 char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2]; 342#else 343 char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN]; 344#endif 345 struct icmphdr *icmp; 346 struct tcphdr *tcp; 347 struct udphdr *udp; 348#ifdef INET6 349 struct ip6_hdr *ip6 = NULL; 350 struct icmp6_hdr *icmp6; 351 u_short ip6f_mf; 352#endif 353 src[0] = '\0'; 354 dst[0] = '\0'; 355#ifdef INET6 356 ip6f_mf = offset & IP6F_MORE_FRAG; 357 offset &= IP6F_OFF_MASK; 358 359 if (IS_IP6_FLOW_ID(&(args->f_id))) { 360 char ip6buf[INET6_ADDRSTRLEN]; 361 snprintf(src, sizeof(src), "[%s]", 362 ip6_sprintf(ip6buf, &args->f_id.src_ip6)); 363 snprintf(dst, sizeof(dst), "[%s]", 364 ip6_sprintf(ip6buf, &args->f_id.dst_ip6)); 365 366 ip6 = (struct ip6_hdr *)ip; 367 tcp = (struct tcphdr *)(((char *)ip) + hlen); 368 udp = (struct udphdr *)(((char *)ip) + hlen); 369 } else 370#endif 371 { 372 tcp = L3HDR(struct tcphdr, ip); 373 udp = L3HDR(struct udphdr, ip); 374 375 inet_ntoa_r(ip->ip_src, src); 376 inet_ntoa_r(ip->ip_dst, dst); 377 } 378 379 switch (args->f_id.proto) { 380 case IPPROTO_TCP: 381 len = snprintf(SNPARGS(proto, 0), "TCP %s", src); 382 if (offset == 0) 383 snprintf(SNPARGS(proto, len), ":%d %s:%d", 384 ntohs(tcp->th_sport), 385 dst, 386 ntohs(tcp->th_dport)); 387 else 388 snprintf(SNPARGS(proto, len), " %s", dst); 389 break; 390 391 case IPPROTO_UDP: 392 len = snprintf(SNPARGS(proto, 0), "UDP %s", src); 393 if (offset == 0) 394 snprintf(SNPARGS(proto, len), ":%d %s:%d", 395 ntohs(udp->uh_sport), 396 dst, 397 ntohs(udp->uh_dport)); 398 else 399 snprintf(SNPARGS(proto, len), " %s", dst); 400 break; 401 402 case IPPROTO_ICMP: 403 icmp = L3HDR(struct icmphdr, ip); 404 if (offset == 0) 405 len = snprintf(SNPARGS(proto, 0), 406 "ICMP:%u.%u ", 407 icmp->icmp_type, icmp->icmp_code); 408 else 409 len = snprintf(SNPARGS(proto, 0), "ICMP "); 410 len += snprintf(SNPARGS(proto, len), "%s", src); 411 snprintf(SNPARGS(proto, len), " %s", dst); 412 break; 413#ifdef INET6 414 case IPPROTO_ICMPV6: 415 icmp6 = (struct icmp6_hdr *)(((char *)ip) + hlen); 416 if (offset == 0) 417 len = snprintf(SNPARGS(proto, 0), 418 "ICMPv6:%u.%u ", 419 icmp6->icmp6_type, icmp6->icmp6_code); 420 else 421 len = snprintf(SNPARGS(proto, 0), "ICMPv6 "); 422 len += snprintf(SNPARGS(proto, len), "%s", src); 423 snprintf(SNPARGS(proto, len), " %s", dst); 424 break; 425#endif 426 default: 427 len = snprintf(SNPARGS(proto, 0), "P:%d %s", 428 args->f_id.proto, src); 429 snprintf(SNPARGS(proto, len), " %s", dst); 430 break; 431 } 432 433#ifdef INET6 434 if (IS_IP6_FLOW_ID(&(args->f_id))) { 435 if (offset & (IP6F_OFF_MASK | IP6F_MORE_FRAG)) 436 snprintf(SNPARGS(fragment, 0), 437 " (frag %08x:%d@%d%s)", 438 args->f_id.extra, 439 ntohs(ip6->ip6_plen) - hlen, 440 ntohs(offset) << 3, ip6f_mf ? "+" : ""); 441 } else 442#endif 443 { 444 int ipoff, iplen; 445 ipoff = ntohs(ip->ip_off); 446 iplen = ntohs(ip->ip_len); 447 if (ipoff & (IP_MF | IP_OFFMASK)) 448 snprintf(SNPARGS(fragment, 0), 449 " (frag %d:%d@%d%s)", 450 ntohs(ip->ip_id), iplen - (ip->ip_hl << 2), 451 offset << 3, 452 (ipoff & IP_MF) ? "+" : ""); 453 } 454 } 455#ifdef __FreeBSD__ 456 if (oif || m->m_pkthdr.rcvif) 457 log(LOG_SECURITY | LOG_INFO, 458 "ipfw: %d %s %s %s via %s%s\n", 459 f ? f->rulenum : -1, 460 action, proto, oif ? "out" : "in", 461 oif ? oif->if_xname : m->m_pkthdr.rcvif->if_xname, 462 fragment); 463 else 464#endif 465 log(LOG_SECURITY | LOG_INFO, 466 "ipfw: %d %s %s [no if info]%s\n", 467 f ? f->rulenum : -1, 468 action, proto, fragment); 469 if (limit_reached) 470 log(LOG_SECURITY | LOG_NOTICE, 471 "ipfw: limit %d reached on entry %d\n", 472 limit_reached, f ? f->rulenum : -1); 473} 474/* end of file */
|