Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ///usage:
- //
- // $ gcc counter.c -o counter
- // $ ./counter --interface eth0 --host localhost
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <getopt.h>
- #include <signal.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #define CMDLEN 1024
- #define TCPDUMPLEN 4096
- int show_stats;
- long counter;
- void alarm_handler(int signum)
- {
- show_stats = 1;
- }
- void install_handler(void)
- {
- struct sigaction sa;
- memset(&sa, 0, sizeof(sa));
- sigemptyset(&sa.sa_mask);
- sa.sa_handler = &alarm_handler;
- if (sigaction(SIGALRM, &sa, NULL) == -1) {
- perror("Can't install alarm handler");
- exit(1);
- }
- }
- int count_lines(char *p, int bytes)
- {
- int counter = 0;
- char *i;
- for (i=p; i < p+bytes ; i++) {
- if (*i == '\n')
- counter++;
- }
- return counter;
- }
- int spawn_tcpdump(char *host, char *interface)
- {
- int fd[2];
- pid_t child;
- if (pipe(fd) == -1) {
- perror("Can't create pipes");
- exit(1);
- }
- child = fork();
- if (child == -1) {
- perror("Can't fork(2) for tcpdump");
- exit(1);
- }
- if (child == 0) {
- int null;
- int len;
- char paramss[CMDLEN];
- len = snprintf(paramss, CMDLEN, "tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420 and dst %s", host);
- if (len > CMDLEN) {
- perror("host argument too long");
- exit(1);
- }
- /* child writes into pipe */
- close(fd[0]);
- dup2(fd[1], STDOUT_FILENO);
- /* throw away first two lines of tcpdump output */
- null = open("/dev/null", O_WRONLY);
- if (null == -1) {
- perror("Can't open /dev/null");
- exit(1);
- }
- dup2(null, STDERR_FILENO);
- execl("/usr/sbin/tcpdump", "tcpdump", "-A", "-n", "-s 0", "-i", interface, paramss, (char *) NULL);
- /* can't reach */
- perror("Cannot execute tcpdump");
- exit(1);
- } else {
- /* parent reads from pipe */
- close(fd[1]);
- return fd[0];
- }
- }
- int main(int argc, char *argv[])
- {
- int tcpdump;
- char *host;
- char *interface;
- long interval;
- while (1) {
- int option_index;
- int c;
- static struct option opts[] = {
- {"host", required_argument, NULL, 'h'},
- {"interface", required_argument, NULL, 'i'},
- {"interval", required_argument, NULL, 'n'},
- {0, 0, 0, 0},
- };
- c = getopt_long(argc, argv, "", opts, &option_index);
- if (c == -1)
- break;
- switch (c) {
- case 'h':
- host = strdup(optarg);
- break;
- case 'i':
- interface = strdup(optarg);
- break;
- case 'n': {
- char *endptr;
- interval = strtol(optarg, &endptr, 10);
- if (!(optarg[0] != '\0' && endptr[0] == '\0')) {
- fprintf(stderr, "Expected integer; invalid"
- " input '%s'\n", optarg);
- exit(1);
- }
- }
- break;
- default:
- fprintf(stderr, "Option parsing error\n");
- exit(1);
- }
- }
- if (optind < argc) {
- fprintf(stderr, "unexpected arguments: ");
- while (optind < argc) {
- fprintf(stderr, "%s ", argv[optind++]);
- }
- fprintf(stderr, "\n");
- }
- tcpdump = spawn_tcpdump(host, interface);
- install_handler();
- alarm(interval);
- while(1) {
- if (show_stats) {
- printf("%ld requests in %ld seconds; average %2.2f req/seq\n",
- counter, interval, (double)counter / (double)interval);
- counter = 0;
- show_stats = 0;
- alarm(interval);
- } else {
- char buffer[TCPDUMPLEN];
- int ret;
- memset(buffer, 0, TCPDUMPLEN);
- ret = read(tcpdump, buffer, TCPDUMPLEN);
- if (ret == -1 && errno == EINTR) {
- /* nop */
- } else if (ret == -1) {
- perror("read");
- exit(1);
- } else {
- counter += count_lines(buffer, ret);
- }
- }
- }
- exit(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement