1 /* $OpenBSD: print-pfsync.c,v 1.35 2009/03/31 01:21:29 dlg 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 #ifndef lint 30 static const char rcsid[] = 31 "@(#) $Id: print-pfsync.c,v 1.35 2009/03/31 01:21:29 dlg Exp $"; 32 #endif 33 34 #include <sys/param.h> 35 #include <sys/time.h> 36 #include <sys/socket.h> 37 #include <sys/file.h> 38 #include <sys/ioctl.h> 39 #include <sys/mbuf.h> 40 41 #ifdef __STDC__ 42 struct rtentry; 43 #endif 44 #include <net/if.h> 45 46 #include <netinet/in.h> 47 #include <netinet/in_systm.h> 48 #include <netinet/ip.h> 49 50 #include <net/pfvar.h> 51 #include <net/if_pfsync.h> 52 53 #include <ctype.h> 54 #include <netdb.h> 55 #include <pcap.h> 56 #include <signal.h> 57 #include <stdio.h> 58 #include <string.h> 59 60 #include "interface.h" 61 #include "addrtoname.h" 62 #include "pfctl_parser.h" 63 #include "pfctl.h" 64 65 void pfsync_print(struct pfsync_header *, const u_char *, int); 66 67 void 68 pfsync_if_print(u_char *user, const struct pcap_pkthdr *h, 69 register const u_char *p) 70 { 71 u_int caplen = h->caplen; 72 73 ts_print(&h->ts); 74 75 if (caplen < PFSYNC_HDRLEN) { 76 printf("[|pfsync]"); 77 goto out; 78 } 79 80 pfsync_print((struct pfsync_header *)p, 81 p + sizeof(struct pfsync_header), 82 caplen - sizeof(struct pfsync_header)); 83 out: 84 if (xflag) { 85 default_print((const u_char *)p, caplen); 86 } 87 putchar('\n'); 88 } 89 90 void 91 pfsync_ip_print(const u_char *bp, u_int len, const u_char *bp2) 92 { 93 struct pfsync_header *hdr = (struct pfsync_header *)bp; 94 struct ip *ip = (struct ip *)bp2; 95 96 if (vflag) 97 printf("%s > %s: ", ipaddr_string(&ip->ip_src), 98 ipaddr_string(&ip->ip_dst)); 99 else 100 printf("%s: ", ipaddr_string(&ip->ip_src)); 101 102 if (len < PFSYNC_HDRLEN) 103 printf("[|pfsync]"); 104 else 105 pfsync_print(hdr, bp + sizeof(struct pfsync_header), 106 len - sizeof(struct pfsync_header)); 107 putchar('\n'); 108 } 109 110 const char *actnames[] = { PFSYNC_ACTIONS }; 111 112 struct pfsync_actions { 113 size_t len; 114 int (*print)(int, const void *); 115 }; 116 117 int pfsync_print_clr(int, const void *); 118 int pfsync_print_state(int, const void *); 119 int pfsync_print_ins_ack(int, const void *); 120 int pfsync_print_upd_c(int, const void *); 121 int pfsync_print_upd_req(int, const void *); 122 int pfsync_print_del_c(int, const void *); 123 int pfsync_print_bus(int, const void *); 124 int pfsync_print_tdb(int, const void *); 125 int pfsync_print_eof(int, const void *); 126 127 struct pfsync_actions actions[] = { 128 { sizeof(struct pfsync_clr), pfsync_print_clr }, 129 { sizeof(struct pfsync_state), pfsync_print_state }, 130 { sizeof(struct pfsync_ins_ack), pfsync_print_ins_ack }, 131 { sizeof(struct pfsync_state), pfsync_print_state }, 132 { sizeof(struct pfsync_upd_c), pfsync_print_upd_c }, 133 { sizeof(struct pfsync_upd_req), pfsync_print_upd_req }, 134 { sizeof(struct pfsync_state), pfsync_print_state }, 135 { sizeof(struct pfsync_del_c), pfsync_print_del_c }, 136 { 0, NULL }, 137 { 0, NULL }, 138 { sizeof(struct pfsync_bus), pfsync_print_bus }, 139 { sizeof(struct pfsync_tdb), pfsync_print_tdb }, 140 { 0, pfsync_print_eof } 141 }; 142 143 void 144 pfsync_print(struct pfsync_header *hdr, const u_char *bp, int len) 145 { 146 struct pfsync_subheader *subh; 147 int count, plen, alen, flags = 0; 148 int i; 149 150 plen = ntohs(hdr->len); 151 152 printf("PFSYNCv%d len %d", hdr->version, plen); 153 154 if (hdr->version != PFSYNC_VERSION) 155 return; 156 157 plen -= sizeof(*hdr); 158 159 if (vflag) 160 flags |= PF_OPT_VERBOSE; 161 if (vflag > 1) 162 flags |= PF_OPT_VERBOSE2; 163 if (!nflag) 164 flags |= PF_OPT_USEDNS; 165 166 while (plen > 0) { 167 if (len < sizeof(*subh)) 168 break; 169 170 subh = (struct pfsync_subheader *)bp; 171 bp += sizeof(*subh); 172 len -= sizeof(*subh); 173 plen -= sizeof(*subh); 174 175 if (subh->action >= PFSYNC_ACT_MAX) { 176 printf("\n act UNKNOWN id %d", subh->action); 177 return; 178 } 179 180 count = ntohs(subh->count); 181 printf("\n act %s count %d", actnames[subh->action], count); 182 alen = actions[subh->action].len; 183 184 if (actions[subh->action].print == NULL) { 185 printf("\n unimplemented action"); 186 return; 187 } 188 189 for (i = 0; i < count; i++) { 190 if (len < alen) { 191 len = 0; 192 break; 193 } 194 195 if (actions[subh->action].print(flags, bp) != 0) 196 return; 197 198 bp += alen; 199 len -= alen; 200 plen -= alen; 201 } 202 } 203 204 if (plen > 0) { 205 printf("\n ..."); 206 return; 207 } 208 if (plen < 0) { 209 printf("\n invalid header length"); 210 return; 211 } 212 if (len > 0) 213 printf("\n invalid packet length"); 214 } 215 216 int 217 pfsync_print_clr(int flags, const void *bp) 218 { 219 const struct pfsync_clr *clr = bp; 220 221 printf("\n\tcreatorid: %08x", htonl(clr->creatorid)); 222 if (clr->ifname[0] != '\0') 223 printf(" interface: %s", clr->ifname); 224 225 return (0); 226 } 227 228 int 229 pfsync_print_state(int flags, const void *bp) 230 { 231 struct pfsync_state *st = (struct pfsync_state *)bp; 232 putchar('\n'); 233 print_state(st, flags); 234 return (0); 235 } 236 237 int 238 pfsync_print_ins_ack(int flags, const void *bp) 239 { 240 const struct pfsync_ins_ack *iack = bp; 241 242 printf("\n\tid: %016llx creatorid: %08x", betoh64(iack->id), 243 ntohl(iack->creatorid)); 244 245 return (0); 246 } 247 248 int 249 pfsync_print_upd_c(int flags, const void *bp) 250 { 251 const struct pfsync_upd_c *u = bp; 252 253 printf("\n\tid: %016llx creatorid: %08x", betoh64(u->id), 254 ntohl(u->creatorid)); 255 256 return (0); 257 } 258 259 int 260 pfsync_print_upd_req(int flags, const void *bp) 261 { 262 const struct pfsync_upd_req *ur = bp; 263 264 printf("\n\tid: %016llx creatorid: %08x", betoh64(ur->id), 265 ntohl(ur->creatorid)); 266 267 return (0); 268 } 269 270 int 271 pfsync_print_del_c(int flags, const void *bp) 272 { 273 const struct pfsync_del_c *d = bp; 274 275 printf("\n\tid: %016llx creatorid: %08x", betoh64(d->id), 276 ntohl(d->creatorid)); 277 278 return (0); 279 } 280 281 int 282 pfsync_print_bus(int flags, const void *bp) 283 { 284 const struct pfsync_bus *b = bp; 285 u_int32_t endtime; 286 int min, sec; 287 const char *status; 288 289 endtime = ntohl(b->endtime); 290 sec = endtime % 60; 291 endtime /= 60; 292 min = endtime % 60; 293 endtime /= 60; 294 295 switch (b->status) { 296 case PFSYNC_BUS_START: 297 status = "start"; 298 break; 299 case PFSYNC_BUS_END: 300 status = "end"; 301 break; 302 default: 303 status = "UNKNOWN"; 304 break; 305 } 306 307 printf("\n\tcreatorid: %08x age: %.2u:%.2u:%.2u status: %s", 308 htonl(b->creatorid), endtime, min, sec, status); 309 310 return (0); 311 } 312 313 int 314 pfsync_print_tdb(int flags, const void *bp) 315 { 316 const struct pfsync_tdb *t = bp; 317 318 printf("\n\tspi: %08x rpl: %u cur_bytes: %llu", 319 htonl(t->spi), htonl(t->rpl), betoh64(t->cur_bytes)); 320 321 return (0); 322 } 323 324 int 325 pfsync_print_eof(int flags, const void *bp) 326 { 327 return (1); 328 } 329