28 29/* 30 * Logging support for ipfw 31 */ 32 33#if !defined(KLD_MODULE) 34#include "opt_ipfw.h" 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 106void 107ipfw_log_bpf(int onoff) 108{ 109 struct ifnet *ifp; 110 111 if (onoff) { 112 if (log_if) 113 return; 114 ifp = if_alloc(IFT_ETHER); 115 if (ifp == NULL) 116 return; 117 if_initname(ifp, "ipfw", 0); 118 ifp->if_mtu = 65536; 119 ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST; 120 ifp->if_init = (void *)log_dummy; 121 ifp->if_ioctl = log_dummy; 122 ifp->if_start = (void *)log_dummy; 123 ifp->if_output = (void *)log_dummy; 124 ifp->if_addrlen = 6; 125 ifp->if_hdrlen = 14; 126 if_attach(ifp); 127 ifp->if_baudrate = IF_Mbps(10); 128 bpfattach(ifp, DLT_EN10MB, 14); 129 log_if = ifp; 130 } else { 131 if (log_if) { 132 ether_ifdetach(log_if); 133 if_free(log_if); 134 } 135 log_if = NULL; 136 } 137} 138#endif /* !WITHOUT_BPF */ 139 140/* 141 * We enter here when we have a rule with O_LOG. 142 * XXX this function alone takes about 2Kbytes of code! 143 */ 144void 145ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args, 146 struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg, 147 struct ip *ip) 148{ 149 char *action; 150 int limit_reached = 0; 151 char action2[40], proto[128], fragment[32]; 152 153 if (V_fw_verbose == 0) { 154#ifndef WITHOUT_BPF 155 struct m_hdr mh; 156 157 if (log_if == NULL || log_if->if_bpf == NULL) 158 return; 159 /* BPF treats the "mbuf" as read-only */ 160 mh.mh_next = m; 161 mh.mh_len = ETHER_HDR_LEN; 162 if (args->eh) { /* layer2, use orig hdr */ 163 mh.mh_data = (char *)args->eh; 164 } else { 165 /* add fake header. Later we will store 166 * more info in the header 167 */ 168 mh.mh_data = "DDDDDDSSSSSS\x08\x00"; 169 } 170 BPF_MTAP(log_if, (struct mbuf *)&mh); 171#endif /* !WITHOUT_BPF */ 172 return; 173 } 174 /* the old 'log' function */ 175 fragment[0] = '\0'; 176 proto[0] = '\0'; 177 178 if (f == NULL) { /* bogus pkt */ 179 if (V_verbose_limit != 0 && V_norule_counter >= V_verbose_limit) 180 return; 181 V_norule_counter++; 182 if (V_norule_counter == V_verbose_limit) 183 limit_reached = V_verbose_limit; 184 action = "Refuse"; 185 } else { /* O_LOG is the first action, find the real one */ 186 ipfw_insn *cmd = ACTION_PTR(f); 187 ipfw_insn_log *l = (ipfw_insn_log *)cmd; 188 189 if (l->max_log != 0 && l->log_left == 0) 190 return; 191 l->log_left--; 192 if (l->log_left == 0) 193 limit_reached = l->max_log; 194 cmd += F_LEN(cmd); /* point to first action */ 195 if (cmd->opcode == O_ALTQ) { 196 ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd; 197 198 snprintf(SNPARGS(action2, 0), "Altq %d", 199 altq->qid); 200 cmd += F_LEN(cmd); 201 } 202 if (cmd->opcode == O_PROB) 203 cmd += F_LEN(cmd); 204 205 if (cmd->opcode == O_TAG) 206 cmd += F_LEN(cmd); 207 208 action = action2; 209 switch (cmd->opcode) { 210 case O_DENY: 211 action = "Deny"; 212 break; 213 214 case O_REJECT: 215 if (cmd->arg1==ICMP_REJECT_RST) 216 action = "Reset"; 217 else if (cmd->arg1==ICMP_UNREACH_HOST) 218 action = "Reject"; 219 else 220 snprintf(SNPARGS(action2, 0), "Unreach %d", 221 cmd->arg1); 222 break; 223 224 case O_UNREACH6: 225 if (cmd->arg1==ICMP6_UNREACH_RST) 226 action = "Reset"; 227 else 228 snprintf(SNPARGS(action2, 0), "Unreach %d", 229 cmd->arg1); 230 break; 231 232 case O_ACCEPT: 233 action = "Accept"; 234 break; 235 case O_COUNT: 236 action = "Count"; 237 break; 238 case O_DIVERT: 239 snprintf(SNPARGS(action2, 0), "Divert %d", 240 cmd->arg1); 241 break; 242 case O_TEE: 243 snprintf(SNPARGS(action2, 0), "Tee %d", 244 cmd->arg1); 245 break; 246 case O_SETFIB: 247 snprintf(SNPARGS(action2, 0), "SetFib %d", 248 cmd->arg1); 249 break; 250 case O_SKIPTO: 251 snprintf(SNPARGS(action2, 0), "SkipTo %d", 252 cmd->arg1); 253 break; 254 case O_PIPE: 255 snprintf(SNPARGS(action2, 0), "Pipe %d", 256 cmd->arg1); 257 break; 258 case O_QUEUE: 259 snprintf(SNPARGS(action2, 0), "Queue %d", 260 cmd->arg1); 261 break; 262 case O_FORWARD_IP: { 263 ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd; 264 int len; 265 struct in_addr dummyaddr; 266 if (sa->sa.sin_addr.s_addr == INADDR_ANY) 267 dummyaddr.s_addr = htonl(tablearg); 268 else 269 dummyaddr.s_addr = sa->sa.sin_addr.s_addr; 270 271 len = snprintf(SNPARGS(action2, 0), "Forward to %s", 272 inet_ntoa(dummyaddr)); 273 274 if (sa->sa.sin_port) 275 snprintf(SNPARGS(action2, len), ":%d", 276 sa->sa.sin_port); 277 } 278 break; 279 case O_NETGRAPH: 280 snprintf(SNPARGS(action2, 0), "Netgraph %d", 281 cmd->arg1); 282 break; 283 case O_NGTEE: 284 snprintf(SNPARGS(action2, 0), "Ngtee %d", 285 cmd->arg1); 286 break; 287 case O_NAT: 288 action = "Nat"; 289 break; 290 case O_REASS: 291 action = "Reass"; 292 break; 293 default: 294 action = "UNKNOWN"; 295 break; 296 } 297 } 298 299 if (hlen == 0) { /* non-ip */ 300 snprintf(SNPARGS(proto, 0), "MAC"); 301 302 } else { 303 int len; 304#ifdef INET6 305 char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2]; 306#else 307 char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN]; 308#endif 309 struct icmphdr *icmp; 310 struct tcphdr *tcp; 311 struct udphdr *udp; 312#ifdef INET6 313 struct ip6_hdr *ip6 = NULL; 314 struct icmp6_hdr *icmp6; 315#endif 316 src[0] = '\0'; 317 dst[0] = '\0'; 318#ifdef INET6 319 if (IS_IP6_FLOW_ID(&(args->f_id))) { 320 char ip6buf[INET6_ADDRSTRLEN]; 321 snprintf(src, sizeof(src), "[%s]", 322 ip6_sprintf(ip6buf, &args->f_id.src_ip6)); 323 snprintf(dst, sizeof(dst), "[%s]", 324 ip6_sprintf(ip6buf, &args->f_id.dst_ip6)); 325 326 ip6 = (struct ip6_hdr *)ip; 327 tcp = (struct tcphdr *)(((char *)ip) + hlen); 328 udp = (struct udphdr *)(((char *)ip) + hlen); 329 } else 330#endif 331 { 332 tcp = L3HDR(struct tcphdr, ip); 333 udp = L3HDR(struct udphdr, ip); 334 335 inet_ntoa_r(ip->ip_src, src); 336 inet_ntoa_r(ip->ip_dst, dst); 337 } 338 339 switch (args->f_id.proto) { 340 case IPPROTO_TCP: 341 len = snprintf(SNPARGS(proto, 0), "TCP %s", src); 342 if (offset == 0) 343 snprintf(SNPARGS(proto, len), ":%d %s:%d", 344 ntohs(tcp->th_sport), 345 dst, 346 ntohs(tcp->th_dport)); 347 else 348 snprintf(SNPARGS(proto, len), " %s", dst); 349 break; 350 351 case IPPROTO_UDP: 352 len = snprintf(SNPARGS(proto, 0), "UDP %s", src); 353 if (offset == 0) 354 snprintf(SNPARGS(proto, len), ":%d %s:%d", 355 ntohs(udp->uh_sport), 356 dst, 357 ntohs(udp->uh_dport)); 358 else 359 snprintf(SNPARGS(proto, len), " %s", dst); 360 break; 361 362 case IPPROTO_ICMP: 363 icmp = L3HDR(struct icmphdr, ip); 364 if (offset == 0) 365 len = snprintf(SNPARGS(proto, 0), 366 "ICMP:%u.%u ", 367 icmp->icmp_type, icmp->icmp_code); 368 else 369 len = snprintf(SNPARGS(proto, 0), "ICMP "); 370 len += snprintf(SNPARGS(proto, len), "%s", src); 371 snprintf(SNPARGS(proto, len), " %s", dst); 372 break; 373#ifdef INET6 374 case IPPROTO_ICMPV6: 375 icmp6 = (struct icmp6_hdr *)(((char *)ip) + hlen); 376 if (offset == 0) 377 len = snprintf(SNPARGS(proto, 0), 378 "ICMPv6:%u.%u ", 379 icmp6->icmp6_type, icmp6->icmp6_code); 380 else 381 len = snprintf(SNPARGS(proto, 0), "ICMPv6 "); 382 len += snprintf(SNPARGS(proto, len), "%s", src); 383 snprintf(SNPARGS(proto, len), " %s", dst); 384 break; 385#endif 386 default: 387 len = snprintf(SNPARGS(proto, 0), "P:%d %s", 388 args->f_id.proto, src); 389 snprintf(SNPARGS(proto, len), " %s", dst); 390 break; 391 } 392 393#ifdef INET6 394 if (IS_IP6_FLOW_ID(&(args->f_id))) { 395 if (offset & (IP6F_OFF_MASK | IP6F_MORE_FRAG)) 396 snprintf(SNPARGS(fragment, 0), 397 " (frag %08x:%d@%d%s)", 398 args->f_id.frag_id6, 399 ntohs(ip6->ip6_plen) - hlen, 400 ntohs(offset & IP6F_OFF_MASK) << 3, 401 (offset & IP6F_MORE_FRAG) ? "+" : ""); 402 } else 403#endif 404 { 405 int ipoff, iplen; 406 ipoff = ntohs(ip->ip_off); 407 iplen = ntohs(ip->ip_len); 408 if (ipoff & (IP_MF | IP_OFFMASK)) 409 snprintf(SNPARGS(fragment, 0), 410 " (frag %d:%d@%d%s)", 411 ntohs(ip->ip_id), iplen - (ip->ip_hl << 2), 412 offset << 3, 413 (ipoff & IP_MF) ? "+" : ""); 414 } 415 }
| 28 29/* 30 * Logging support for ipfw 31 */ 32 33#if !defined(KLD_MODULE) 34#include "opt_ipfw.h" 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 106void 107ipfw_log_bpf(int onoff) 108{ 109 struct ifnet *ifp; 110 111 if (onoff) { 112 if (log_if) 113 return; 114 ifp = if_alloc(IFT_ETHER); 115 if (ifp == NULL) 116 return; 117 if_initname(ifp, "ipfw", 0); 118 ifp->if_mtu = 65536; 119 ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST; 120 ifp->if_init = (void *)log_dummy; 121 ifp->if_ioctl = log_dummy; 122 ifp->if_start = (void *)log_dummy; 123 ifp->if_output = (void *)log_dummy; 124 ifp->if_addrlen = 6; 125 ifp->if_hdrlen = 14; 126 if_attach(ifp); 127 ifp->if_baudrate = IF_Mbps(10); 128 bpfattach(ifp, DLT_EN10MB, 14); 129 log_if = ifp; 130 } else { 131 if (log_if) { 132 ether_ifdetach(log_if); 133 if_free(log_if); 134 } 135 log_if = NULL; 136 } 137} 138#endif /* !WITHOUT_BPF */ 139 140/* 141 * We enter here when we have a rule with O_LOG. 142 * XXX this function alone takes about 2Kbytes of code! 143 */ 144void 145ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args, 146 struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg, 147 struct ip *ip) 148{ 149 char *action; 150 int limit_reached = 0; 151 char action2[40], proto[128], fragment[32]; 152 153 if (V_fw_verbose == 0) { 154#ifndef WITHOUT_BPF 155 struct m_hdr mh; 156 157 if (log_if == NULL || log_if->if_bpf == NULL) 158 return; 159 /* BPF treats the "mbuf" as read-only */ 160 mh.mh_next = m; 161 mh.mh_len = ETHER_HDR_LEN; 162 if (args->eh) { /* layer2, use orig hdr */ 163 mh.mh_data = (char *)args->eh; 164 } else { 165 /* add fake header. Later we will store 166 * more info in the header 167 */ 168 mh.mh_data = "DDDDDDSSSSSS\x08\x00"; 169 } 170 BPF_MTAP(log_if, (struct mbuf *)&mh); 171#endif /* !WITHOUT_BPF */ 172 return; 173 } 174 /* the old 'log' function */ 175 fragment[0] = '\0'; 176 proto[0] = '\0'; 177 178 if (f == NULL) { /* bogus pkt */ 179 if (V_verbose_limit != 0 && V_norule_counter >= V_verbose_limit) 180 return; 181 V_norule_counter++; 182 if (V_norule_counter == V_verbose_limit) 183 limit_reached = V_verbose_limit; 184 action = "Refuse"; 185 } else { /* O_LOG is the first action, find the real one */ 186 ipfw_insn *cmd = ACTION_PTR(f); 187 ipfw_insn_log *l = (ipfw_insn_log *)cmd; 188 189 if (l->max_log != 0 && l->log_left == 0) 190 return; 191 l->log_left--; 192 if (l->log_left == 0) 193 limit_reached = l->max_log; 194 cmd += F_LEN(cmd); /* point to first action */ 195 if (cmd->opcode == O_ALTQ) { 196 ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd; 197 198 snprintf(SNPARGS(action2, 0), "Altq %d", 199 altq->qid); 200 cmd += F_LEN(cmd); 201 } 202 if (cmd->opcode == O_PROB) 203 cmd += F_LEN(cmd); 204 205 if (cmd->opcode == O_TAG) 206 cmd += F_LEN(cmd); 207 208 action = action2; 209 switch (cmd->opcode) { 210 case O_DENY: 211 action = "Deny"; 212 break; 213 214 case O_REJECT: 215 if (cmd->arg1==ICMP_REJECT_RST) 216 action = "Reset"; 217 else if (cmd->arg1==ICMP_UNREACH_HOST) 218 action = "Reject"; 219 else 220 snprintf(SNPARGS(action2, 0), "Unreach %d", 221 cmd->arg1); 222 break; 223 224 case O_UNREACH6: 225 if (cmd->arg1==ICMP6_UNREACH_RST) 226 action = "Reset"; 227 else 228 snprintf(SNPARGS(action2, 0), "Unreach %d", 229 cmd->arg1); 230 break; 231 232 case O_ACCEPT: 233 action = "Accept"; 234 break; 235 case O_COUNT: 236 action = "Count"; 237 break; 238 case O_DIVERT: 239 snprintf(SNPARGS(action2, 0), "Divert %d", 240 cmd->arg1); 241 break; 242 case O_TEE: 243 snprintf(SNPARGS(action2, 0), "Tee %d", 244 cmd->arg1); 245 break; 246 case O_SETFIB: 247 snprintf(SNPARGS(action2, 0), "SetFib %d", 248 cmd->arg1); 249 break; 250 case O_SKIPTO: 251 snprintf(SNPARGS(action2, 0), "SkipTo %d", 252 cmd->arg1); 253 break; 254 case O_PIPE: 255 snprintf(SNPARGS(action2, 0), "Pipe %d", 256 cmd->arg1); 257 break; 258 case O_QUEUE: 259 snprintf(SNPARGS(action2, 0), "Queue %d", 260 cmd->arg1); 261 break; 262 case O_FORWARD_IP: { 263 ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd; 264 int len; 265 struct in_addr dummyaddr; 266 if (sa->sa.sin_addr.s_addr == INADDR_ANY) 267 dummyaddr.s_addr = htonl(tablearg); 268 else 269 dummyaddr.s_addr = sa->sa.sin_addr.s_addr; 270 271 len = snprintf(SNPARGS(action2, 0), "Forward to %s", 272 inet_ntoa(dummyaddr)); 273 274 if (sa->sa.sin_port) 275 snprintf(SNPARGS(action2, len), ":%d", 276 sa->sa.sin_port); 277 } 278 break; 279 case O_NETGRAPH: 280 snprintf(SNPARGS(action2, 0), "Netgraph %d", 281 cmd->arg1); 282 break; 283 case O_NGTEE: 284 snprintf(SNPARGS(action2, 0), "Ngtee %d", 285 cmd->arg1); 286 break; 287 case O_NAT: 288 action = "Nat"; 289 break; 290 case O_REASS: 291 action = "Reass"; 292 break; 293 default: 294 action = "UNKNOWN"; 295 break; 296 } 297 } 298 299 if (hlen == 0) { /* non-ip */ 300 snprintf(SNPARGS(proto, 0), "MAC"); 301 302 } else { 303 int len; 304#ifdef INET6 305 char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2]; 306#else 307 char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN]; 308#endif 309 struct icmphdr *icmp; 310 struct tcphdr *tcp; 311 struct udphdr *udp; 312#ifdef INET6 313 struct ip6_hdr *ip6 = NULL; 314 struct icmp6_hdr *icmp6; 315#endif 316 src[0] = '\0'; 317 dst[0] = '\0'; 318#ifdef INET6 319 if (IS_IP6_FLOW_ID(&(args->f_id))) { 320 char ip6buf[INET6_ADDRSTRLEN]; 321 snprintf(src, sizeof(src), "[%s]", 322 ip6_sprintf(ip6buf, &args->f_id.src_ip6)); 323 snprintf(dst, sizeof(dst), "[%s]", 324 ip6_sprintf(ip6buf, &args->f_id.dst_ip6)); 325 326 ip6 = (struct ip6_hdr *)ip; 327 tcp = (struct tcphdr *)(((char *)ip) + hlen); 328 udp = (struct udphdr *)(((char *)ip) + hlen); 329 } else 330#endif 331 { 332 tcp = L3HDR(struct tcphdr, ip); 333 udp = L3HDR(struct udphdr, ip); 334 335 inet_ntoa_r(ip->ip_src, src); 336 inet_ntoa_r(ip->ip_dst, dst); 337 } 338 339 switch (args->f_id.proto) { 340 case IPPROTO_TCP: 341 len = snprintf(SNPARGS(proto, 0), "TCP %s", src); 342 if (offset == 0) 343 snprintf(SNPARGS(proto, len), ":%d %s:%d", 344 ntohs(tcp->th_sport), 345 dst, 346 ntohs(tcp->th_dport)); 347 else 348 snprintf(SNPARGS(proto, len), " %s", dst); 349 break; 350 351 case IPPROTO_UDP: 352 len = snprintf(SNPARGS(proto, 0), "UDP %s", src); 353 if (offset == 0) 354 snprintf(SNPARGS(proto, len), ":%d %s:%d", 355 ntohs(udp->uh_sport), 356 dst, 357 ntohs(udp->uh_dport)); 358 else 359 snprintf(SNPARGS(proto, len), " %s", dst); 360 break; 361 362 case IPPROTO_ICMP: 363 icmp = L3HDR(struct icmphdr, ip); 364 if (offset == 0) 365 len = snprintf(SNPARGS(proto, 0), 366 "ICMP:%u.%u ", 367 icmp->icmp_type, icmp->icmp_code); 368 else 369 len = snprintf(SNPARGS(proto, 0), "ICMP "); 370 len += snprintf(SNPARGS(proto, len), "%s", src); 371 snprintf(SNPARGS(proto, len), " %s", dst); 372 break; 373#ifdef INET6 374 case IPPROTO_ICMPV6: 375 icmp6 = (struct icmp6_hdr *)(((char *)ip) + hlen); 376 if (offset == 0) 377 len = snprintf(SNPARGS(proto, 0), 378 "ICMPv6:%u.%u ", 379 icmp6->icmp6_type, icmp6->icmp6_code); 380 else 381 len = snprintf(SNPARGS(proto, 0), "ICMPv6 "); 382 len += snprintf(SNPARGS(proto, len), "%s", src); 383 snprintf(SNPARGS(proto, len), " %s", dst); 384 break; 385#endif 386 default: 387 len = snprintf(SNPARGS(proto, 0), "P:%d %s", 388 args->f_id.proto, src); 389 snprintf(SNPARGS(proto, len), " %s", dst); 390 break; 391 } 392 393#ifdef INET6 394 if (IS_IP6_FLOW_ID(&(args->f_id))) { 395 if (offset & (IP6F_OFF_MASK | IP6F_MORE_FRAG)) 396 snprintf(SNPARGS(fragment, 0), 397 " (frag %08x:%d@%d%s)", 398 args->f_id.frag_id6, 399 ntohs(ip6->ip6_plen) - hlen, 400 ntohs(offset & IP6F_OFF_MASK) << 3, 401 (offset & IP6F_MORE_FRAG) ? "+" : ""); 402 } else 403#endif 404 { 405 int ipoff, iplen; 406 ipoff = ntohs(ip->ip_off); 407 iplen = ntohs(ip->ip_len); 408 if (ipoff & (IP_MF | IP_OFFMASK)) 409 snprintf(SNPARGS(fragment, 0), 410 " (frag %d:%d@%d%s)", 411 ntohs(ip->ip_id), iplen - (ip->ip_hl << 2), 412 offset << 3, 413 (ipoff & IP_MF) ? "+" : ""); 414 } 415 }
|