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