pflogd.c (22d6889b4d3eb8a5cb2aaaefe5bedb40e885b425) | pflogd.c (61a1372b419ef876d7a8948241bc561a1866448c) |
---|---|
1/* $OpenBSD: pflogd.c,v 1.27 2004/02/13 19:01:57 otto Exp $ */ | 1/* $OpenBSD: pflogd.c,v 1.33 2005/02/09 12:09:30 henning Exp $ */ |
2 3/* 4 * Copyright (c) 2001 Theo de Raadt 5 * Copyright (c) 2001 Can Erkin Acar 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 15 unchanged lines hidden (view full) --- 25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 | 2 3/* 4 * Copyright (c) 2001 Theo de Raadt 5 * Copyright (c) 2001 Can Erkin Acar 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 15 unchanged lines hidden (view full) --- 25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 |
33#include <sys/cdefs.h> 34__FBSDID("$FreeBSD$"); 35 | |
36#include <sys/types.h> 37#include <sys/ioctl.h> 38#include <sys/file.h> 39#include <sys/stat.h> 40#include <stdio.h> 41#include <stdlib.h> 42#include <string.h> 43#include <unistd.h> 44#include <pcap-int.h> 45#include <pcap.h> 46#include <syslog.h> 47#include <signal.h> 48#include <errno.h> 49#include <stdarg.h> 50#include <fcntl.h> | 33#include <sys/types.h> 34#include <sys/ioctl.h> 35#include <sys/file.h> 36#include <sys/stat.h> 37#include <stdio.h> 38#include <stdlib.h> 39#include <string.h> 40#include <unistd.h> 41#include <pcap-int.h> 42#include <pcap.h> 43#include <syslog.h> 44#include <signal.h> 45#include <errno.h> 46#include <stdarg.h> 47#include <fcntl.h> |
51#ifdef __FreeBSD__ 52#include "pidfile.h" 53#else | |
54#include <util.h> | 48#include <util.h> |
55#endif 56 | |
57#include "pflogd.h" 58 59pcap_t *hpcap; 60static FILE *dpcap; 61 62int Debug = 0; 63static int snaplen = DEF_SNAPLEN; 64static int cur_snaplen = DEF_SNAPLEN; --- 82 unchanged lines hidden (view full) --- 147 if (log_debug) { 148 vfprintf(stderr, message, ap); 149 fprintf(stderr, "\n"); 150 } else 151 vsyslog(pri, message, ap); 152 va_end(ap); 153} 154 | 49#include "pflogd.h" 50 51pcap_t *hpcap; 52static FILE *dpcap; 53 54int Debug = 0; 55static int snaplen = DEF_SNAPLEN; 56static int cur_snaplen = DEF_SNAPLEN; --- 82 unchanged lines hidden (view full) --- 139 if (log_debug) { 140 vfprintf(stderr, message, ap); 141 fprintf(stderr, "\n"); 142 } else 143 vsyslog(pri, message, ap); 144 va_end(ap); 145} 146 |
155#ifdef __FreeBSD__ 156__dead2 void 157#else | |
158__dead void | 147__dead void |
159#endif | |
160usage(void) 161{ 162 fprintf(stderr, "usage: pflogd [-Dx] [-d delay] [-f filename] "); 163 fprintf(stderr, "[-s snaplen] [expression]\n"); 164 exit(1); 165} 166 167void --- 43 unchanged lines hidden (view full) --- 211 hpcap = NULL; 212 return (-1); 213 } 214 215 set_pcap_filter(); 216 217 cur_snaplen = snaplen = pcap_snapshot(hpcap); 218 | 148usage(void) 149{ 150 fprintf(stderr, "usage: pflogd [-Dx] [-d delay] [-f filename] "); 151 fprintf(stderr, "[-s snaplen] [expression]\n"); 152 exit(1); 153} 154 155void --- 43 unchanged lines hidden (view full) --- 199 hpcap = NULL; 200 return (-1); 201 } 202 203 set_pcap_filter(); 204 205 cur_snaplen = snaplen = pcap_snapshot(hpcap); 206 |
219#ifdef __FreeBSD__ 220 /* We can not lock bpf devices ... yet */ 221#else | |
222 /* lock */ 223 if (ioctl(pcap_fileno(hpcap), BIOCLOCK) < 0) { 224 logmsg(LOG_ERR, "BIOCLOCK: %s", strerror(errno)); 225 return (-1); 226 } | 207 /* lock */ 208 if (ioctl(pcap_fileno(hpcap), BIOCLOCK) < 0) { 209 logmsg(LOG_ERR, "BIOCLOCK: %s", strerror(errno)); 210 return (-1); 211 } |
227#endif | |
228 229 return (0); 230} 231 232int 233set_snaplen(int snap) 234{ 235 if (priv_set_snaplen(snap)) --- 30 unchanged lines hidden (view full) --- 266 */ 267 fd = priv_open_log(); 268 if (fd < 0) 269 return (1); 270 271 fp = fdopen(fd, "a+"); 272 273 if (fp == NULL) { | 212 213 return (0); 214} 215 216int 217set_snaplen(int snap) 218{ 219 if (priv_set_snaplen(snap)) --- 30 unchanged lines hidden (view full) --- 250 */ 251 fd = priv_open_log(); 252 if (fd < 0) 253 return (1); 254 255 fp = fdopen(fd, "a+"); 256 257 if (fp == NULL) { |
258 close(fd); |
|
274 logmsg(LOG_ERR, "Error: %s: %s", filename, strerror(errno)); 275 return (1); 276 } 277 if (fstat(fileno(fp), &st) == -1) { | 259 logmsg(LOG_ERR, "Error: %s: %s", filename, strerror(errno)); 260 return (1); 261 } 262 if (fstat(fileno(fp), &st) == -1) { |
263 fclose(fp); |
|
278 logmsg(LOG_ERR, "Error: %s: %s", filename, strerror(errno)); 279 return (1); 280 } 281 282 /* set FILE unbuffered, we do our own buffering */ 283 if (setvbuf(fp, NULL, _IONBF, 0)) { | 264 logmsg(LOG_ERR, "Error: %s: %s", filename, strerror(errno)); 265 return (1); 266 } 267 268 /* set FILE unbuffered, we do our own buffering */ 269 if (setvbuf(fp, NULL, _IONBF, 0)) { |
270 fclose(fp); |
|
284 logmsg(LOG_ERR, "Failed to set output buffers"); 285 return (1); 286 } 287 288#define TCPDUMP_MAGIC 0xa1b2c3d4 289 290 if (st.st_size == 0) { 291 if (snaplen != cur_snaplen) { 292 logmsg(LOG_NOTICE, "Using snaplen %d", snaplen); 293 if (set_snaplen(snaplen)) { | 271 logmsg(LOG_ERR, "Failed to set output buffers"); 272 return (1); 273 } 274 275#define TCPDUMP_MAGIC 0xa1b2c3d4 276 277 if (st.st_size == 0) { 278 if (snaplen != cur_snaplen) { 279 logmsg(LOG_NOTICE, "Using snaplen %d", snaplen); 280 if (set_snaplen(snaplen)) { |
281 fclose(fp); |
|
294 logmsg(LOG_WARNING, 295 "Failed, using old settings"); 296 } 297 } 298 hdr.magic = TCPDUMP_MAGIC; 299 hdr.version_major = PCAP_VERSION_MAJOR; 300 hdr.version_minor = PCAP_VERSION_MINOR; 301 hdr.thiszone = hpcap->tzoff; --- 18 unchanged lines hidden (view full) --- 320 321 return (0); 322} 323 324int 325scan_dump(FILE *fp, off_t size) 326{ 327 struct pcap_file_header hdr; | 282 logmsg(LOG_WARNING, 283 "Failed, using old settings"); 284 } 285 } 286 hdr.magic = TCPDUMP_MAGIC; 287 hdr.version_major = PCAP_VERSION_MAJOR; 288 hdr.version_minor = PCAP_VERSION_MINOR; 289 hdr.thiszone = hpcap->tzoff; --- 18 unchanged lines hidden (view full) --- 308 309 return (0); 310} 311 312int 313scan_dump(FILE *fp, off_t size) 314{ 315 struct pcap_file_header hdr; |
328#ifdef __FreeBSD__ 329 struct pcap_sf_pkthdr ph; 330#else | |
331 struct pcap_pkthdr ph; | 316 struct pcap_pkthdr ph; |
332#endif | |
333 off_t pos; 334 335 /* 336 * Must read the file, compare the header against our new 337 * options (in particular, snaplen) and adjust our options so 338 * that we generate a correct file. Furthermore, check the file 339 * for consistency so that we can append safely. 340 * --- 53 unchanged lines hidden (view full) --- 394 return (1); 395} 396 397/* dump a packet directly to the stream, which is unbuffered */ 398void 399dump_packet_nobuf(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 400{ 401 FILE *f = (FILE *)user; | 317 off_t pos; 318 319 /* 320 * Must read the file, compare the header against our new 321 * options (in particular, snaplen) and adjust our options so 322 * that we generate a correct file. Furthermore, check the file 323 * for consistency so that we can append safely. 324 * --- 53 unchanged lines hidden (view full) --- 378 return (1); 379} 380 381/* dump a packet directly to the stream, which is unbuffered */ 382void 383dump_packet_nobuf(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 384{ 385 FILE *f = (FILE *)user; |
402#ifdef __FreeBSD__ 403 struct pcap_sf_pkthdr sh; 404#endif | |
405 406 if (suspended) { 407 packets_dropped++; 408 return; 409 } 410 | 386 387 if (suspended) { 388 packets_dropped++; 389 return; 390 } 391 |
411#ifdef __FreeBSD__ 412 sh.ts.tv_sec = (bpf_int32)h->ts.tv_sec; 413 sh.ts.tv_usec = (bpf_int32)h->ts.tv_usec; 414 sh.caplen = h->caplen; 415 sh.len = h->len; 416 417 if (fwrite((char *)&sh, sizeof(sh), 1, f) != 1) { 418#else | |
419 if (fwrite((char *)h, sizeof(*h), 1, f) != 1) { | 392 if (fwrite((char *)h, sizeof(*h), 1, f) != 1) { |
420#endif 421 /* try to undo header to prevent corruption */ | |
422 off_t pos = ftello(f); | 393 off_t pos = ftello(f); |
423#ifdef __FreeBSD__ 424 if (pos < sizeof(sh) || 425 ftruncate(fileno(f), pos - sizeof(sh))) { 426#else | 394 395 /* try to undo header to prevent corruption */ |
427 if (pos < sizeof(*h) || 428 ftruncate(fileno(f), pos - sizeof(*h))) { | 396 if (pos < sizeof(*h) || 397 ftruncate(fileno(f), pos - sizeof(*h))) { |
429#endif | |
430 logmsg(LOG_ERR, "Write failed, corrupted logfile!"); 431 set_suspended(1); 432 gotsig_close = 1; 433 return; 434 } 435 goto error; 436 } 437 --- 52 unchanged lines hidden (view full) --- 490 bufpkt = 0; 491} 492 493/* append packet to the buffer, flushing if necessary */ 494void 495dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 496{ 497 FILE *f = (FILE *)user; | 398 logmsg(LOG_ERR, "Write failed, corrupted logfile!"); 399 set_suspended(1); 400 gotsig_close = 1; 401 return; 402 } 403 goto error; 404 } 405 --- 52 unchanged lines hidden (view full) --- 458 bufpkt = 0; 459} 460 461/* append packet to the buffer, flushing if necessary */ 462void 463dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 464{ 465 FILE *f = (FILE *)user; |
498#ifdef __FreeBSD__ 499 struct pcap_sf_pkthdr sh; 500 size_t len = sizeof(sh) + h->caplen; 501#else | |
502 size_t len = sizeof(*h) + h->caplen; | 466 size_t len = sizeof(*h) + h->caplen; |
503#endif | |
504 505 if (len < sizeof(*h) || h->caplen > (size_t)cur_snaplen) { 506 logmsg(LOG_NOTICE, "invalid size %u (%u/%u), packet dropped", 507 len, cur_snaplen, snaplen); 508 packets_dropped++; 509 return; 510 } 511 --- 10 unchanged lines hidden (view full) --- 522 return; 523 } 524 525 if (len > bufleft) { 526 dump_packet_nobuf(user, h, sp); 527 return; 528 } 529 | 467 468 if (len < sizeof(*h) || h->caplen > (size_t)cur_snaplen) { 469 logmsg(LOG_NOTICE, "invalid size %u (%u/%u), packet dropped", 470 len, cur_snaplen, snaplen); 471 packets_dropped++; 472 return; 473 } 474 --- 10 unchanged lines hidden (view full) --- 485 return; 486 } 487 488 if (len > bufleft) { 489 dump_packet_nobuf(user, h, sp); 490 return; 491 } 492 |
530 append: 531#ifdef __FreeBSD__ 532 sh.ts.tv_sec = (bpf_int32)h->ts.tv_sec; 533 sh.ts.tv_usec = (bpf_int32)h->ts.tv_usec; 534 sh.caplen = h->caplen; 535 sh.len = h->len; 536 537 memcpy(bufpos, &sh, sizeof(sh)); 538 memcpy(bufpos + sizeof(sh), sp, h->caplen); 539#else | 493 append: |
540 memcpy(bufpos, h, sizeof(*h)); 541 memcpy(bufpos + sizeof(*h), sp, h->caplen); | 494 memcpy(bufpos, h, sizeof(*h)); 495 memcpy(bufpos + sizeof(*h), sp, h->caplen); |
542#endif | |
543 544 bufpos += len; 545 bufleft -= len; 546 bufpkt++; 547 548 return; 549} 550 551int 552main(int argc, char **argv) 553{ 554 struct pcap_stat pstat; 555 int ch, np, Xflag = 0; 556 pcap_handler phandler = dump_packet; | 496 497 bufpos += len; 498 bufleft -= len; 499 bufpkt++; 500 501 return; 502} 503 504int 505main(int argc, char **argv) 506{ 507 struct pcap_stat pstat; 508 int ch, np, Xflag = 0; 509 pcap_handler phandler = dump_packet; |
510 const char *errstr = NULL; |
|
557 | 511 |
558#ifdef __FreeBSD__ 559 /* another ?paranoid? safety measure we do not have */ 560#else | |
561 closefrom(STDERR_FILENO + 1); | 512 closefrom(STDERR_FILENO + 1); |
562#endif | |
563 564 while ((ch = getopt(argc, argv, "Dxd:s:f:")) != -1) { 565 switch (ch) { 566 case 'D': 567 Debug = 1; 568 break; 569 case 'd': | 513 514 while ((ch = getopt(argc, argv, "Dxd:s:f:")) != -1) { 515 switch (ch) { 516 case 'D': 517 Debug = 1; 518 break; 519 case 'd': |
570 delay = atoi(optarg); 571 if (delay < 5 || delay > 60*60) | 520 delay = strtonum(optarg, 5, 60*60, &errstr); 521 if (errstr) |
572 usage(); 573 break; 574 case 'f': 575 filename = optarg; 576 break; 577 case 's': | 522 usage(); 523 break; 524 case 'f': 525 filename = optarg; 526 break; 527 case 's': |
578 snaplen = atoi(optarg); | 528 snaplen = strtonum(optarg, 0, PFLOGD_MAXSNAPLEN, 529 &errstr); |
579 if (snaplen <= 0) 580 snaplen = DEF_SNAPLEN; | 530 if (snaplen <= 0) 531 snaplen = DEF_SNAPLEN; |
581 if (snaplen > PFLOGD_MAXSNAPLEN) | 532 if (errstr) |
582 snaplen = PFLOGD_MAXSNAPLEN; 583 break; 584 case 'x': 585 Xflag++; 586 break; 587 default: 588 usage(); 589 } --- 8 unchanged lines hidden (view full) --- 598 openlog("pflogd", LOG_PID | LOG_CONS, LOG_DAEMON); 599 if (daemon(0, 0)) { 600 logmsg(LOG_WARNING, "Failed to become daemon: %s", 601 strerror(errno)); 602 } 603 pidfile(NULL); 604 } 605 | 533 snaplen = PFLOGD_MAXSNAPLEN; 534 break; 535 case 'x': 536 Xflag++; 537 break; 538 default: 539 usage(); 540 } --- 8 unchanged lines hidden (view full) --- 549 openlog("pflogd", LOG_PID | LOG_CONS, LOG_DAEMON); 550 if (daemon(0, 0)) { 551 logmsg(LOG_WARNING, "Failed to become daemon: %s", 552 strerror(errno)); 553 } 554 pidfile(NULL); 555 } 556 |
557 tzset(); |
|
606 (void)umask(S_IRWXG | S_IRWXO); 607 608 /* filter will be used by the privileged process */ 609 if (argc) { 610 filter = copy_argv(argv); 611 if (filter == NULL) 612 logmsg(LOG_NOTICE, "Failed to form filter expression"); 613 } --- 36 unchanged lines hidden (view full) --- 650 651 logmsg(LOG_ERR, "Logging suspended: open error"); 652 set_suspended(1); 653 } else if (Xflag) 654 return (0); 655 656 while (1) { 657 np = pcap_dispatch(hpcap, PCAP_NUM_PKTS, | 558 (void)umask(S_IRWXG | S_IRWXO); 559 560 /* filter will be used by the privileged process */ 561 if (argc) { 562 filter = copy_argv(argv); 563 if (filter == NULL) 564 logmsg(LOG_NOTICE, "Failed to form filter expression"); 565 } --- 36 unchanged lines hidden (view full) --- 602 603 logmsg(LOG_ERR, "Logging suspended: open error"); 604 set_suspended(1); 605 } else if (Xflag) 606 return (0); 607 608 while (1) { 609 np = pcap_dispatch(hpcap, PCAP_NUM_PKTS, |
658 dump_packet, (u_char *)dpcap); 659 if (np < 0) { 660#ifdef __FreeBSD__ 661 if (errno == ENXIO) { 662 logmsg(LOG_ERR, 663 "Device not/no longer configured"); 664 break; 665 } 666#endif | 610 phandler, (u_char *)dpcap); 611 if (np < 0) |
667 logmsg(LOG_NOTICE, "%s", pcap_geterr(hpcap)); | 612 logmsg(LOG_NOTICE, "%s", pcap_geterr(hpcap)); |
668 } | |
669 670 if (gotsig_close) 671 break; 672 if (gotsig_hup) { 673 if (reset_dump()) { 674 logmsg(LOG_ERR, 675 "Logging suspended: open error"); 676 set_suspended(1); --- 31 unchanged lines hidden --- | 613 614 if (gotsig_close) 615 break; 616 if (gotsig_hup) { 617 if (reset_dump()) { 618 logmsg(LOG_ERR, 619 "Logging suspended: open error"); 620 set_suspended(1); --- 31 unchanged lines hidden --- |