1 /* $OpenBSD: print-pflog.c,v 1.19 2009/04/06 12:09:06 henning 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 "@(#) $Id: print-pflog.c,v 1.19 2009/04/06 12:09:06 henning 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_MATCH: 130 printf("match"); 131 break; 132 case PF_SCRUB: 133 printf("scrub"); 134 break; 135 case PF_PASS: 136 printf("pass"); 137 break; 138 case PF_DROP: 139 printf("block"); 140 break; 141 case PF_NAT: 142 case PF_NONAT: 143 printf("nat"); 144 break; 145 case PF_BINAT: 146 case PF_NOBINAT: 147 printf("binat"); 148 break; 149 case PF_RDR: 150 case PF_NORDR: 151 printf("rdr"); 152 break; 153 } 154 printf(" %s on %s: ", 155 hdr->dir == PF_OUT ? "out" : "in", 156 hdr->ifname); 157 if (vflag && hdr->pid != NO_PID) 158 printf("[uid %u, pid %u] ", (unsigned)hdr->uid, 159 (unsigned)hdr->pid); 160 } 161 af = hdr->af; 162 length -= hdrlen; 163 if (af == AF_INET) { 164 ip = (struct ip *)(p + hdrlen); 165 ip_print((const u_char *)ip, length); 166 if (xflag) 167 default_print((const u_char *)ip, 168 caplen - hdrlen); 169 } else { 170 #ifdef INET6 171 ip6 = (struct ip6_hdr *)(p + hdrlen); 172 ip6_print((const u_char *)ip6, length); 173 if (xflag) 174 default_print((const u_char *)ip6, 175 caplen - hdrlen); 176 #endif 177 } 178 179 out: 180 putchar('\n'); 181 } 182 183 184 void 185 pflog_old_if_print(u_char *user, const struct pcap_pkthdr *h, 186 register const u_char *p) 187 { 188 u_int length = h->len; 189 u_int caplen = h->caplen; 190 const struct ip *ip; 191 #ifdef INET6 192 const struct ip6_hdr *ip6; 193 #endif 194 const struct old_pfloghdr *hdr; 195 u_short res; 196 char reason[128], *why; 197 u_int8_t af; 198 199 ts_print(&h->ts); 200 201 if (caplen < OLD_PFLOG_HDRLEN) { 202 printf("[|pflog]"); 203 goto out; 204 } 205 206 /* 207 * Some printers want to get back at the link level addresses, 208 * and/or check that they're not walking off the end of the packet. 209 * Rather than pass them all the way down, we set these globals. 210 */ 211 packetp = p; 212 snapend = p + caplen; 213 214 hdr = (struct old_pfloghdr *)p; 215 if (eflag) { 216 res = ntohs(hdr->reason); 217 why = (res < PFRES_MAX) ? pf_reasons[res] : "unkn"; 218 219 snprintf(reason, sizeof(reason), "%d(%s)", res, why); 220 221 printf("rule %d/%s: ", 222 (short)ntohs(hdr->rnr), reason); 223 switch (ntohs(hdr->action)) { 224 case PF_MATCH: 225 printf("match"); 226 break; 227 case PF_SCRUB: 228 printf("scrub"); 229 break; 230 case PF_PASS: 231 printf("pass"); 232 break; 233 case PF_DROP: 234 printf("block"); 235 break; 236 case PF_NAT: 237 case PF_NONAT: 238 printf("nat"); 239 break; 240 case PF_BINAT: 241 case PF_NOBINAT: 242 printf("binat"); 243 break; 244 case PF_RDR: 245 case PF_NORDR: 246 printf("rdr"); 247 break; 248 } 249 printf(" %s on %s: ", 250 ntohs(hdr->dir) == PF_OUT ? "out" : "in", 251 hdr->ifname); 252 } 253 af = ntohl(hdr->af); 254 length -= OLD_PFLOG_HDRLEN; 255 if (af == AF_INET) { 256 ip = (struct ip *)(p + OLD_PFLOG_HDRLEN); 257 ip_print((const u_char *)ip, length); 258 if (xflag) 259 default_print((const u_char *)ip, 260 caplen - OLD_PFLOG_HDRLEN); 261 } else { 262 #ifdef INET6 263 ip6 = (struct ip6_hdr *)(p + OLD_PFLOG_HDRLEN); 264 ip6_print((const u_char *)ip6, length); 265 if (xflag) 266 default_print((const u_char *)ip6, 267 caplen - OLD_PFLOG_HDRLEN); 268 #endif 269 } 270 271 out: 272 putchar('\n'); 273 } 274