1 /* $OpenBSD: print-pflog.c,v 1.17 2005/11/23 22:33:11 cloder Exp $ */ 2 3 /* 4 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 */ 23 24 #ifndef lint 25 static const char rcsid[] = 26 "@(#) $Header: /home/cvs/src/usr.sbin/tcpdump/print-pflog.c,v 1.17 2005/11/23 22:33:11 cloder Exp $ (LBL)"; 27 #endif 28 29 #include <sys/param.h> 30 #include <sys/time.h> 31 #include <sys/socket.h> 32 #include <sys/file.h> 33 #include <sys/ioctl.h> 34 #include <sys/mbuf.h> 35 #include <sys/proc.h> 36 37 #ifndef NO_PID 38 #define NO_PID (32766+1) 39 #endif 40 41 struct rtentry; 42 #include <net/if.h> 43 #include <net/if_pflog.h> 44 45 #include <netinet/in.h> 46 #include <netinet/in_systm.h> 47 #include <netinet/ip.h> 48 49 #include <net/pfvar.h> 50 51 #include <ctype.h> 52 #include <netdb.h> 53 #include <pcap.h> 54 #include <signal.h> 55 #include <stdio.h> 56 57 #include "interface.h" 58 #include "addrtoname.h" 59 60 char *pf_reasons[PFRES_MAX+2] = PFRES_NAMES; 61 62 void 63 pflog_if_print(u_char *user, const struct pcap_pkthdr *h, 64 register const u_char *p) 65 { 66 u_int length = h->len; 67 u_int hdrlen; 68 u_int caplen = h->caplen; 69 const struct ip *ip; 70 #ifdef INET6 71 const struct ip6_hdr *ip6; 72 #endif 73 const struct pfloghdr *hdr; 74 u_int8_t af; 75 76 ts_print(&h->ts); 77 78 /* check length */ 79 if (caplen < sizeof(u_int8_t)) { 80 printf("[|pflog]"); 81 goto out; 82 } 83 84 #define MIN_PFLOG_HDRLEN 45 85 hdr = (struct pfloghdr *)p; 86 if (hdr->length < MIN_PFLOG_HDRLEN) { 87 printf("[pflog: invalid header length!]"); 88 goto out; 89 } 90 hdrlen = BPF_WORDALIGN(hdr->length); 91 92 if (caplen < hdrlen) { 93 printf("[|pflog]"); 94 goto out; 95 } 96 97 /* 98 * Some printers want to get back at the link level addresses, 99 * and/or check that they're not walking off the end of the packet. 100 * Rather than pass them all the way down, we set these globals. 101 */ 102 packetp = p; 103 snapend = p + caplen; 104 105 hdr = (struct pfloghdr *)p; 106 if (eflag) { 107 printf("rule "); 108 if (ntohl(hdr->rulenr) == (u_int32_t) -1) 109 printf("def"); 110 else { 111 printf("%u", ntohl(hdr->rulenr)); 112 if (hdr->ruleset[0]) { 113 printf(".%s", hdr->ruleset); 114 if (ntohl(hdr->subrulenr) == (u_int32_t) -1) 115 printf(".def"); 116 else 117 printf(".%u", ntohl(hdr->subrulenr)); 118 } 119 } 120 if (hdr->reason < PFRES_MAX) 121 printf("/(%s) ", pf_reasons[hdr->reason]); 122 else 123 printf("/(unkn %u) ", (unsigned)hdr->reason); 124 if (vflag) 125 printf("[uid %u, pid %u] ", (unsigned)hdr->rule_uid, 126 (unsigned)hdr->rule_pid); 127 128 switch (hdr->action) { 129 case PF_SCRUB: 130 printf("scrub"); 131 break; 132 case PF_PASS: 133 printf("pass"); 134 break; 135 case PF_DROP: 136 printf("block"); 137 break; 138 case PF_NAT: 139 case PF_NONAT: 140 printf("nat"); 141 break; 142 case PF_BINAT: 143 case PF_NOBINAT: 144 printf("binat"); 145 break; 146 case PF_RDR: 147 case PF_NORDR: 148 printf("rdr"); 149 break; 150 } 151 printf(" %s on %s: ", 152 hdr->dir == PF_OUT ? "out" : "in", 153 hdr->ifname); 154 if (vflag && hdr->pid != NO_PID) 155 printf("[uid %u, pid %u] ", (unsigned)hdr->uid, 156 (unsigned)hdr->pid); 157 } 158 af = hdr->af; 159 length -= hdrlen; 160 if (af == AF_INET) { 161 ip = (struct ip *)(p + hdrlen); 162 ip_print((const u_char *)ip, length); 163 if (xflag) 164 default_print((const u_char *)ip, 165 caplen - hdrlen); 166 } else { 167 #ifdef INET6 168 ip6 = (struct ip6_hdr *)(p + hdrlen); 169 ip6_print((const u_char *)ip6, length); 170 if (xflag) 171 default_print((const u_char *)ip6, 172 caplen - hdrlen); 173 #endif 174 } 175 176 out: 177 putchar('\n'); 178 } 179 180 181 void 182 pflog_old_if_print(u_char *user, const struct pcap_pkthdr *h, 183 register const u_char *p) 184 { 185 u_int length = h->len; 186 u_int caplen = h->caplen; 187 const struct ip *ip; 188 #ifdef INET6 189 const struct ip6_hdr *ip6; 190 #endif 191 const struct old_pfloghdr *hdr; 192 u_short res; 193 char reason[128], *why; 194 u_int8_t af; 195 196 ts_print(&h->ts); 197 198 if (caplen < OLD_PFLOG_HDRLEN) { 199 printf("[|pflog]"); 200 goto out; 201 } 202 203 /* 204 * Some printers want to get back at the link level addresses, 205 * and/or check that they're not walking off the end of the packet. 206 * Rather than pass them all the way down, we set these globals. 207 */ 208 packetp = p; 209 snapend = p + caplen; 210 211 hdr = (struct old_pfloghdr *)p; 212 if (eflag) { 213 res = ntohs(hdr->reason); 214 why = (res < PFRES_MAX) ? pf_reasons[res] : "unkn"; 215 216 snprintf(reason, sizeof(reason), "%d(%s)", res, why); 217 218 printf("rule %d/%s: ", 219 (short)ntohs(hdr->rnr), reason); 220 switch (ntohs(hdr->action)) { 221 case PF_SCRUB: 222 printf("scrub"); 223 break; 224 case PF_PASS: 225 printf("pass"); 226 break; 227 case PF_DROP: 228 printf("block"); 229 break; 230 case PF_NAT: 231 case PF_NONAT: 232 printf("nat"); 233 break; 234 case PF_BINAT: 235 case PF_NOBINAT: 236 printf("binat"); 237 break; 238 case PF_RDR: 239 case PF_NORDR: 240 printf("rdr"); 241 break; 242 } 243 printf(" %s on %s: ", 244 ntohs(hdr->dir) == PF_OUT ? "out" : "in", 245 hdr->ifname); 246 } 247 af = ntohl(hdr->af); 248 length -= OLD_PFLOG_HDRLEN; 249 if (af == AF_INET) { 250 ip = (struct ip *)(p + OLD_PFLOG_HDRLEN); 251 ip_print((const u_char *)ip, length); 252 if (xflag) 253 default_print((const u_char *)ip, 254 caplen - OLD_PFLOG_HDRLEN); 255 } else { 256 #ifdef INET6 257 ip6 = (struct ip6_hdr *)(p + OLD_PFLOG_HDRLEN); 258 ip6_print((const u_char *)ip6, length); 259 if (xflag) 260 default_print((const u_char *)ip6, 261 caplen - OLD_PFLOG_HDRLEN); 262 #endif 263 } 264 265 out: 266 putchar('\n'); 267 } 268