1 /* $OpenBSD: print-pfsync.c,v 1.38 2012/09/19 13:50:36 mikeb Exp $ */ 2 3 /* 4 * Copyright (c) 2002 Michael Shalayeff 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26 * THE POSSIBILITY OF SUCH DAMAGE. 27 */ 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 36 #ifdef __STDC__ 37 struct rtentry; 38 #endif 39 #include <net/if.h> 40 41 #include <netinet/in.h> 42 #include <netinet/in_systm.h> 43 #include <netinet/ip.h> 44 45 #include <net/pfvar.h> 46 #include <net/if_pfsync.h> 47 48 #include <ctype.h> 49 #include <netdb.h> 50 #include <pcap.h> 51 #include <signal.h> 52 #include <stdio.h> 53 #include <string.h> 54 55 #include "interface.h" 56 #include "addrtoname.h" 57 #include "pfctl_parser.h" 58 #include "pfctl.h" 59 60 void pfsync_print(struct pfsync_header *, const u_char *, int); 61 62 void 63 pfsync_if_print(u_char *user, const struct pcap_pkthdr *h, 64 register const u_char *p) 65 { 66 u_int caplen = h->caplen; 67 68 ts_print(&h->ts); 69 70 if (caplen < PFSYNC_HDRLEN) { 71 printf("[|pfsync]"); 72 goto out; 73 } 74 75 pfsync_print((struct pfsync_header *)p, 76 p + sizeof(struct pfsync_header), 77 caplen - sizeof(struct pfsync_header)); 78 out: 79 if (xflag) { 80 default_print((const u_char *)p, caplen); 81 } 82 putchar('\n'); 83 } 84 85 void 86 pfsync_ip_print(const u_char *bp, u_int len, const u_char *bp2) 87 { 88 struct pfsync_header *hdr = (struct pfsync_header *)bp; 89 struct ip *ip = (struct ip *)bp2; 90 91 if (vflag) 92 printf("%s > %s: ", ipaddr_string(&ip->ip_src), 93 ipaddr_string(&ip->ip_dst)); 94 else 95 printf("%s: ", ipaddr_string(&ip->ip_src)); 96 97 if (len < PFSYNC_HDRLEN) 98 printf("[|pfsync]"); 99 else 100 pfsync_print(hdr, bp + sizeof(struct pfsync_header), 101 len - sizeof(struct pfsync_header)); 102 putchar('\n'); 103 } 104 105 const char *actnames[] = { PFSYNC_ACTIONS }; 106 107 struct pfsync_actions { 108 size_t len; 109 int (*print)(int, const void *); 110 }; 111 112 int pfsync_print_clr(int, const void *); 113 int pfsync_print_state(int, const void *); 114 int pfsync_print_ins_ack(int, const void *); 115 int pfsync_print_upd_c(int, const void *); 116 int pfsync_print_upd_req(int, const void *); 117 int pfsync_print_del_c(int, const void *); 118 int pfsync_print_bus(int, const void *); 119 int pfsync_print_tdb(int, const void *); 120 int pfsync_print_eof(int, const void *); 121 122 struct pfsync_actions actions[] = { 123 { sizeof(struct pfsync_clr), pfsync_print_clr }, 124 { 0, NULL }, 125 { sizeof(struct pfsync_ins_ack), pfsync_print_ins_ack }, 126 { 0, NULL }, 127 { sizeof(struct pfsync_upd_c), pfsync_print_upd_c }, 128 { sizeof(struct pfsync_upd_req), pfsync_print_upd_req }, 129 { sizeof(struct pfsync_state), pfsync_print_state }, 130 { sizeof(struct pfsync_del_c), pfsync_print_del_c }, 131 { 0, NULL }, 132 { 0, NULL }, 133 { sizeof(struct pfsync_bus), pfsync_print_bus }, 134 { 0, NULL }, 135 { 0, pfsync_print_eof }, 136 { sizeof(struct pfsync_state), pfsync_print_state }, 137 { sizeof(struct pfsync_state), pfsync_print_state }, 138 { sizeof(struct pfsync_tdb), pfsync_print_tdb }, 139 }; 140 141 void 142 pfsync_print(struct pfsync_header *hdr, const u_char *bp, int len) 143 { 144 struct pfsync_subheader *subh; 145 int count, plen, alen, flags = 0; 146 int i; 147 148 plen = ntohs(hdr->len); 149 150 printf("PFSYNCv%d len %d", hdr->version, plen); 151 152 if (hdr->version != PFSYNC_VERSION) 153 return; 154 155 plen -= sizeof(*hdr); 156 157 if (vflag) 158 flags |= PF_OPT_VERBOSE; 159 if (vflag > 1) 160 flags |= PF_OPT_VERBOSE2; 161 if (!nflag) 162 flags |= PF_OPT_USEDNS; 163 164 while (plen > 0) { 165 if (len < sizeof(*subh)) 166 break; 167 168 subh = (struct pfsync_subheader *)bp; 169 bp += sizeof(*subh); 170 len -= sizeof(*subh); 171 plen -= sizeof(*subh); 172 173 if (subh->action >= PFSYNC_ACT_MAX) { 174 printf("\n act UNKNOWN id %d", subh->action); 175 return; 176 } 177 178 count = ntohs(subh->count); 179 printf("\n act %s count %d", actnames[subh->action], count); 180 alen = actions[subh->action].len; 181 182 if (actions[subh->action].print == NULL) { 183 printf("\n unimplemented action"); 184 return; 185 } 186 187 for (i = 0; i < count; i++) { 188 if (len < alen) { 189 len = 0; 190 break; 191 } 192 193 if (actions[subh->action].print(flags, bp) != 0) 194 return; 195 196 bp += alen; 197 len -= alen; 198 plen -= alen; 199 } 200 } 201 202 if (plen > 0) { 203 printf("\n ..."); 204 return; 205 } 206 if (plen < 0) { 207 printf("\n invalid header length"); 208 return; 209 } 210 if (len > 0) 211 printf("\n invalid packet length"); 212 } 213 214 int 215 pfsync_print_clr(int flags, const void *bp) 216 { 217 const struct pfsync_clr *clr = bp; 218 219 printf("\n\tcreatorid: %08x", htonl(clr->creatorid)); 220 if (clr->ifname[0] != '\0') 221 printf(" interface: %s", clr->ifname); 222 223 return (0); 224 } 225 226 int 227 pfsync_print_state(int flags, const void *bp) 228 { 229 struct pfsync_state *st = (struct pfsync_state *)bp; 230 putchar('\n'); 231 print_state(st, flags); 232 return (0); 233 } 234 235 int 236 pfsync_print_ins_ack(int flags, const void *bp) 237 { 238 const struct pfsync_ins_ack *iack = bp; 239 240 printf("\n\tid: %016llx creatorid: %08x", betoh64(iack->id), 241 ntohl(iack->creatorid)); 242 243 return (0); 244 } 245 246 int 247 pfsync_print_upd_c(int flags, const void *bp) 248 { 249 const struct pfsync_upd_c *u = bp; 250 251 printf("\n\tid: %016llx creatorid: %08x", betoh64(u->id), 252 ntohl(u->creatorid)); 253 254 return (0); 255 } 256 257 int 258 pfsync_print_upd_req(int flags, const void *bp) 259 { 260 const struct pfsync_upd_req *ur = bp; 261 262 printf("\n\tid: %016llx creatorid: %08x", betoh64(ur->id), 263 ntohl(ur->creatorid)); 264 265 return (0); 266 } 267 268 int 269 pfsync_print_del_c(int flags, const void *bp) 270 { 271 const struct pfsync_del_c *d = bp; 272 273 printf("\n\tid: %016llx creatorid: %08x", betoh64(d->id), 274 ntohl(d->creatorid)); 275 276 return (0); 277 } 278 279 int 280 pfsync_print_bus(int flags, const void *bp) 281 { 282 const struct pfsync_bus *b = bp; 283 u_int32_t endtime; 284 int min, sec; 285 const char *status; 286 287 endtime = ntohl(b->endtime); 288 sec = endtime % 60; 289 endtime /= 60; 290 min = endtime % 60; 291 endtime /= 60; 292 293 switch (b->status) { 294 case PFSYNC_BUS_START: 295 status = "start"; 296 break; 297 case PFSYNC_BUS_END: 298 status = "end"; 299 break; 300 default: 301 status = "UNKNOWN"; 302 break; 303 } 304 305 printf("\n\tcreatorid: %08x age: %.2u:%.2u:%.2u status: %s", 306 htonl(b->creatorid), endtime, min, sec, status); 307 308 return (0); 309 } 310 311 int 312 pfsync_print_tdb(int flags, const void *bp) 313 { 314 const struct pfsync_tdb *t = bp; 315 316 printf("\n\tspi: 0x%08x rpl: %llu cur_bytes: %llu", 317 ntohl(t->spi), betoh64(t->rpl), betoh64(t->cur_bytes)); 318 319 return (0); 320 } 321 322 int 323 pfsync_print_eof(int flags, const void *bp) 324 { 325 return (1); 326 } 327