Advertisement
Guest User

Untitled

a guest
Dec 1st, 2020
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.44 KB | None | 0 0
  1. ///usage:
  2. //
  3. // $ gcc counter.c -o counter
  4. // $ ./counter --interface eth0 --host localhost
  5.  
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10. #include <getopt.h>
  11. #include <signal.h>
  12. #include <errno.h>
  13. #include <fcntl.h>
  14. #include <sys/types.h>
  15.  
  16. #define CMDLEN 1024
  17. #define TCPDUMPLEN 4096
  18.  
  19.  
  20. int show_stats;
  21. long counter;
  22.  
  23. void alarm_handler(int signum)
  24. {
  25. show_stats = 1;
  26. }
  27.  
  28. void install_handler(void)
  29. {
  30. struct sigaction sa;
  31.  
  32. memset(&sa, 0, sizeof(sa));
  33.  
  34. sigemptyset(&sa.sa_mask);
  35. sa.sa_handler = &alarm_handler;
  36. if (sigaction(SIGALRM, &sa, NULL) == -1) {
  37. perror("Can't install alarm handler");
  38. exit(1);
  39. }
  40. }
  41.  
  42. int count_lines(char *p, int bytes)
  43. {
  44. int counter = 0;
  45. char *i;
  46. for (i=p; i < p+bytes ; i++) {
  47. if (*i == '\n')
  48. counter++;
  49. }
  50. return counter;
  51. }
  52.  
  53. int spawn_tcpdump(char *host, char *interface)
  54. {
  55. int fd[2];
  56. pid_t child;
  57.  
  58. if (pipe(fd) == -1) {
  59. perror("Can't create pipes");
  60. exit(1);
  61. }
  62.  
  63. child = fork();
  64.  
  65. if (child == -1) {
  66. perror("Can't fork(2) for tcpdump");
  67. exit(1);
  68. }
  69.  
  70. if (child == 0) {
  71. int null;
  72. int len;
  73. char paramss[CMDLEN];
  74.  
  75. len = snprintf(paramss, CMDLEN, "tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420 and dst %s", host);
  76.  
  77. if (len > CMDLEN) {
  78. perror("host argument too long");
  79. exit(1);
  80. }
  81.  
  82. /* child writes into pipe */
  83. close(fd[0]);
  84. dup2(fd[1], STDOUT_FILENO);
  85.  
  86. /* throw away first two lines of tcpdump output */
  87. null = open("/dev/null", O_WRONLY);
  88.  
  89. if (null == -1) {
  90. perror("Can't open /dev/null");
  91. exit(1);
  92. }
  93.  
  94. dup2(null, STDERR_FILENO);
  95.  
  96. execl("/usr/sbin/tcpdump", "tcpdump", "-A", "-n", "-s 0", "-i", interface, paramss, (char *) NULL);
  97. /* can't reach */
  98. perror("Cannot execute tcpdump");
  99. exit(1);
  100. } else {
  101. /* parent reads from pipe */
  102. close(fd[1]);
  103. return fd[0];
  104. }
  105. }
  106.  
  107. int main(int argc, char *argv[])
  108. {
  109. int tcpdump;
  110. char *host;
  111. char *interface;
  112. long interval;
  113.  
  114.  
  115. while (1) {
  116. int option_index;
  117. int c;
  118.  
  119. static struct option opts[] = {
  120. {"host", required_argument, NULL, 'h'},
  121. {"interface", required_argument, NULL, 'i'},
  122. {"interval", required_argument, NULL, 'n'},
  123. {0, 0, 0, 0},
  124. };
  125.  
  126. c = getopt_long(argc, argv, "", opts, &option_index);
  127.  
  128. if (c == -1)
  129. break;
  130.  
  131. switch (c) {
  132. case 'h':
  133. host = strdup(optarg);
  134. break;
  135. case 'i':
  136. interface = strdup(optarg);
  137. break;
  138. case 'n': {
  139. char *endptr;
  140. interval = strtol(optarg, &endptr, 10);
  141. if (!(optarg[0] != '\0' && endptr[0] == '\0')) {
  142. fprintf(stderr, "Expected integer; invalid"
  143. " input '%s'\n", optarg);
  144. exit(1);
  145. }
  146. }
  147. break;
  148. default:
  149. fprintf(stderr, "Option parsing error\n");
  150. exit(1);
  151. }
  152.  
  153. }
  154.  
  155. if (optind < argc) {
  156. fprintf(stderr, "unexpected arguments: ");
  157. while (optind < argc) {
  158. fprintf(stderr, "%s ", argv[optind++]);
  159. }
  160. fprintf(stderr, "\n");
  161. }
  162.  
  163. tcpdump = spawn_tcpdump(host, interface);
  164.  
  165. install_handler();
  166. alarm(interval);
  167.  
  168. while(1) {
  169. if (show_stats) {
  170. printf("%ld requests in %ld seconds; average %2.2f req/seq\n",
  171. counter, interval, (double)counter / (double)interval);
  172. counter = 0;
  173. show_stats = 0;
  174. alarm(interval);
  175. } else {
  176. char buffer[TCPDUMPLEN];
  177. int ret;
  178.  
  179. memset(buffer, 0, TCPDUMPLEN);
  180. ret = read(tcpdump, buffer, TCPDUMPLEN);
  181. if (ret == -1 && errno == EINTR) {
  182. /* nop */
  183. } else if (ret == -1) {
  184. perror("read");
  185. exit(1);
  186. } else {
  187. counter += count_lines(buffer, ret);
  188. }
  189. }
  190. }
  191.  
  192. exit(0);
  193. }
  194.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement