sendcap.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
  3. * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  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. * 3. Neither the name of the Politecnico di Torino, CACE Technologies
  16. * nor the names of its contributors may be used to endorse or promote
  17. * products derived from this software without specific prior written
  18. * permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. */
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #include <pcap.h>
  36. #include <time.h>
  37. #ifdef _WIN32
  38. #include <tchar.h>
  39. BOOL LoadNpcapDlls()
  40. {
  41. TCHAR npcap_dir[512];
  42. UINT len;
  43. len = GetSystemDirectory(npcap_dir, 480);
  44. if (!len) {
  45. fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
  46. return FALSE;
  47. }
  48. _tcscat_s(npcap_dir, 512, TEXT("\\Npcap"));
  49. if (SetDllDirectory(npcap_dir) == 0) {
  50. fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
  51. return FALSE;
  52. }
  53. return TRUE;
  54. }
  55. #endif
  56. void usage();
  57. int main(int argc, char **argv)
  58. {
  59. pcap_t *indesc,*outdesc;
  60. char errbuf[PCAP_ERRBUF_SIZE];
  61. char source[PCAP_BUF_SIZE];
  62. FILE *capfile;
  63. int caplen, sync;
  64. u_int res;
  65. pcap_send_queue *squeue;
  66. struct pcap_pkthdr *pktheader;
  67. u_char *pktdata;
  68. float cpu_time;
  69. u_int npacks = 0;
  70. errno_t fopen_error;
  71. int rval = 0;
  72. #ifdef _WIN32
  73. /* Load Npcap and its functions. */
  74. if (!LoadNpcapDlls())
  75. {
  76. fprintf(stderr, "Couldn't load Npcap\n");
  77. exit(1);
  78. }
  79. #endif
  80. /* Check the validity of the command line */
  81. if (argc <= 2 || argc >= 5)
  82. {
  83. usage();
  84. return 1;
  85. }
  86. /* Retrieve the length of the capture file */
  87. fopen_error = fopen_s(&capfile, argv[1],"rb");
  88. if(fopen_error != 0){
  89. printf("Error opening the file, errno %d.\n", fopen_error);
  90. return 1;
  91. }
  92. fseek(capfile , 0, SEEK_END);
  93. caplen= ftell(capfile)- sizeof(struct pcap_file_header);
  94. fclose(capfile);
  95. /* Chek if the timestamps must be respected */
  96. if(argc == 4 && argv[3][0] == 's')
  97. sync = TRUE;
  98. else
  99. sync = FALSE;
  100. /* Open the capture */
  101. /* Create the source string according to the new WinPcap syntax */
  102. if ( pcap_createsrcstr( source, // variable that will keep the source string
  103. PCAP_SRC_FILE, // we want to open a file
  104. NULL, // remote host
  105. NULL, // port on the remote host
  106. argv[1], // name of the file we want to open
  107. errbuf // error buffer
  108. ) != 0)
  109. {
  110. fprintf(stderr,"\nError creating a source string\n");
  111. return 1;
  112. }
  113. /* Open the capture file */
  114. if ( (indesc= pcap_open(source, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL)
  115. {
  116. fprintf(stderr,"\nUnable to open the file %s: %s.\n", source, errbuf);
  117. return 1;
  118. }
  119. /* Open the output adapter */
  120. if ( (outdesc= pcap_open(argv[2], 100, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL)
  121. {
  122. fprintf(stderr,"\nUnable to open adapter %s: %s.\n", argv[2], errbuf);
  123. return 1;
  124. }
  125. /* Check the MAC type */
  126. if (pcap_datalink(indesc) != pcap_datalink(outdesc))
  127. {
  128. printf("Warning: the datalink of the capture differs from the one of the selected interface.\n");
  129. printf("Press a key to continue, or CTRL+C to stop.\n");
  130. getchar();
  131. }
  132. /* Allocate a send queue */
  133. squeue = pcap_sendqueue_alloc(caplen);
  134. /* Fill the queue with the packets from the file */
  135. while ((res = pcap_next_ex( indesc, &pktheader, &pktdata)) == 1)
  136. {
  137. if (pcap_sendqueue_queue(squeue, pktheader, pktdata) == -1)
  138. {
  139. printf("Warning: packet buffer too small, not all the packets will be sent.\n");
  140. break;
  141. }
  142. npacks++;
  143. }
  144. if (res == -1)
  145. {
  146. printf("Corrupted input file.\n");
  147. pcap_sendqueue_destroy(squeue);
  148. return 1;
  149. }
  150. /* Transmit the queue */
  151. cpu_time = (float)clock ();
  152. if ((res = pcap_sendqueue_transmit(outdesc, squeue, sync)) < squeue->len)
  153. {
  154. printf("An error occurred sending the packets: %s. Only %d bytes were sent\n", pcap_geterr(outdesc), res);
  155. rval = 1;
  156. }
  157. else
  158. {
  159. cpu_time = (clock() - cpu_time)/CLOCKS_PER_SEC;
  160. printf ("\n\nElapsed time: %5.3f\n", cpu_time);
  161. printf ("\nTotal packets generated = %d", npacks);
  162. printf ("\nAverage packets per second = %d", (int)((double)npacks/cpu_time));
  163. printf ("\n");
  164. }
  165. /* free the send queue */
  166. pcap_sendqueue_destroy(squeue);
  167. /* Close the input file */
  168. pcap_close(indesc);
  169. /*
  170. * lose the output adapter
  171. * IMPORTANT: remember to close the adapter, otherwise there will be no guarantee that all the
  172. * packets will be sent!
  173. */
  174. pcap_close(outdesc);
  175. return rval;
  176. }
  177. void usage()
  178. {
  179. printf("\nSendcap, sends a libpcap/tcpdump capture file to the net. Copyright (C) 2002 Loris Degioanni.\n");
  180. printf("\nUsage:\n");
  181. printf("\t sendcap file_name adapter [s]\n");
  182. printf("\nParameters:\n");
  183. printf("\nfile_name: the name of the dump file that will be sent to the network\n");
  184. printf("\nadapter: the device to use. Use \"WinDump -D\" for a list of valid devices\n");
  185. printf("\ns: if present, forces the packets to be sent synchronously, i.e. respecting the timestamps in the dump file. This option will work only under Windows NTx.\n\n");
  186. exit(0);
  187. }