GNS3 Docker Images
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ethloop.c 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * ethloop loops back all received frames.
  3. *
  4. * ethloop is the virtual equivalence of a RJ45 loopback plug.
  5. * It's main objective is to see, how a network behaves with a
  6. * loop in it's topology.
  7. *
  8. * This program is put into the public domain, use it as you like.
  9. */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <signal.h>
  13. #include <pcap.h>
  14. pcap_t *pcap = NULL; /* pcap handle */
  15. /* print pcap error/warning and exit on error */
  16. void handle_pcap_err(char *prefix, int err) {
  17. char *msg = NULL;
  18. switch(err) {
  19. case 0: /* no error */
  20. break;
  21. case PCAP_ERROR:
  22. fprintf(stderr, "%s: error: %s\n", prefix, pcap_geterr(pcap));
  23. break;
  24. case PCAP_ERROR_BREAK:
  25. msg = "pcap_loop terminated by pcap_break";
  26. break;
  27. case PCAP_ERROR_NOT_ACTIVATED:
  28. msg = "pcap not activated";
  29. break;
  30. case PCAP_ERROR_ACTIVATED:
  31. msg = "pcap is already activated";
  32. break;
  33. case PCAP_ERROR_NO_SUCH_DEVICE:
  34. msg = "no such device";
  35. break;
  36. case PCAP_ERROR_RFMON_NOTSUP:
  37. msg = "rfmon mode not supported";
  38. break;
  39. case PCAP_ERROR_NOT_RFMON:
  40. msg = "rfmon mode not activated";
  41. break;
  42. case PCAP_ERROR_PERM_DENIED:
  43. msg = "permission denied";
  44. break;
  45. case PCAP_ERROR_IFACE_NOT_UP:
  46. msg = "interface isn't up";
  47. break;
  48. case PCAP_ERROR_CANTSET_TSTAMP_TYPE:
  49. msg = "device can't set the time stamp type";
  50. break;
  51. case PCAP_ERROR_PROMISC_PERM_DENIED:
  52. msg = "no permission to capture in promiscuous mode";
  53. break;
  54. case PCAP_ERROR_TSTAMP_PRECISION_NOTSUP:
  55. msg = "requested time stamp precision not supported";
  56. break;
  57. case PCAP_WARNING:
  58. fprintf(stderr, "%s: warning: %s\n", prefix, pcap_geterr(pcap));
  59. break;
  60. case PCAP_WARNING_PROMISC_NOTSUP:
  61. msg = "warning: promiscuous mode not supported";
  62. break;
  63. case PCAP_WARNING_TSTAMP_TYPE_NOTSUP:
  64. msg = "warning: requested time stamp type not supported";
  65. break;
  66. default:
  67. if (err > 0)
  68. fprintf(stderr, "%s: unknown warning, err = %d\n", prefix, err);
  69. else
  70. fprintf(stderr, "%s: unknown error, err = %d\n", prefix, err);
  71. break;
  72. }
  73. if (msg != NULL)
  74. fprintf(stderr, "%s: %s\n", prefix, msg);
  75. if (err < 0)
  76. exit(1);
  77. }
  78. /* break pcap loop by a signal */
  79. void break_pcap_loop(int signum) {
  80. if (pcap != NULL) pcap_breakloop(pcap);
  81. }
  82. /* print packet counter */
  83. void print_counter(int counter) {
  84. printf("\r%6d", counter); fflush(stdout);
  85. }
  86. /* callback on received packet */
  87. void echo_packet(u_char *user, const struct pcap_pkthdr *pkthdr,
  88. const u_char *packet) {
  89. static int counter = 0;
  90. int ret;
  91. ret = pcap_inject(pcap, packet, pkthdr->len);
  92. if (ret < 0) {
  93. printf("\n");
  94. handle_pcap_err("pcap_inject", ret);
  95. }
  96. print_counter(++counter);
  97. }
  98. int main(int argc, char *argv[]) {
  99. char errbuf[PCAP_ERRBUF_SIZE];
  100. sig_t old_sighup, old_sigint, old_sigquit, old_sigterm;
  101. char *device;
  102. int ret;
  103. /* first (and only) argument is device name */
  104. if (argc != 2 || argv[1][0] == '-') {
  105. fprintf(stderr, "ethloop loops back all received frames.\n\n"
  106. "Usage: ethloop <network device>\n");
  107. exit(1);
  108. }
  109. device = argv[1];
  110. /* open capture device */
  111. if ((pcap = pcap_create(device, errbuf)) == NULL) {
  112. fprintf(stderr, "pcap_create: can't open network device: %s\n", errbuf);
  113. exit(1);
  114. }
  115. /* set capture options */
  116. handle_pcap_err("pcap_set_snaplen", pcap_set_snaplen(pcap, 65535));
  117. handle_pcap_err("pcap_set_promisc", pcap_set_promisc(pcap, 1));
  118. /* activate capture */
  119. handle_pcap_err("pcap_activate", pcap_activate(pcap));
  120. handle_pcap_err("pcap_setdirection", pcap_setdirection(pcap, PCAP_D_IN));
  121. /* receive packets until HUP, INT, QUIT or TERM signal */
  122. old_sighup = signal(SIGHUP, break_pcap_loop);
  123. old_sigint = signal(SIGINT, break_pcap_loop);
  124. old_sigquit = signal(SIGQUIT, break_pcap_loop);
  125. old_sigterm = signal(SIGTERM, break_pcap_loop);
  126. print_counter(0);
  127. ret = pcap_loop(pcap, -1, echo_packet, NULL);
  128. printf("\n");
  129. if (ret != PCAP_ERROR_BREAK)
  130. handle_pcap_err("pcap_loop", ret);
  131. signal(SIGHUP, old_sighup);
  132. signal(SIGINT, old_sigint);
  133. signal(SIGQUIT, old_sigquit);
  134. signal(SIGTERM, old_sigterm);
  135. pcap_close(pcap);
  136. return 0;
  137. }