Advertisement
Guest User

Untitled

a guest
Mar 28th, 2017
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.91 KB | None | 0 0
  1. // ================================================================
  2. // Katedra: Katedra za racunarsku tehniku i racunarske komunikacije
  3. // Predmet: Osnovi racunarskih mreza 2
  4. // Godina studija: III godina
  5. // Semestar: Letnji (VI)
  6. // Skolska godina: 2016/2017
  7. // Datoteka: vezba6.c
  8. // ================================================================
  9.  
  10. // Include libraries
  11. // We do not want the warnings about the old deprecated and unsecure CRT functions since these examples can be compiled under *nix as well
  12. #ifdef _MSC_VER
  13. #define _CRT_SECURE_NO_WARNINGS
  14. #else
  15. #include <netinet/in.h>
  16. #include <time.h>
  17. #endif
  18.  
  19. #include <pcap.h>
  20. #include "protocol_headers.h"
  21.  
  22. // Function declarations
  23. pcap_if_t* select_device(pcap_if_t* devices);
  24. void print_raw_data(unsigned char* data, int data_length);
  25.  
  26. // Print packet headers
  27. void print_winpcap_header(const struct pcap_pkthdr *packet_header, int packet_counter);
  28. void print_ethernet_header(ethernet_header* eh);
  29. void print_ip_header(ip_header * ih);
  30. void print_udp_header(udp_header * uh);
  31. void print_application_data(unsigned char* data, long data_length);
  32.  
  33.  
  34. int main()
  35. {
  36. pcap_if_t* devices;
  37. pcap_if_t* device;
  38. pcap_t* device_handle;
  39. char error_buffer[PCAP_ERRBUF_SIZE];
  40. unsigned int netmask;
  41. char filter_exp[] = "udp and ip";
  42. struct bpf_program fcode;
  43.  
  44. int result; // result of pcap_next_ex function
  45. int packet_counter = 0; // counts packets in order to have numerated packets
  46. struct pcap_pkthdr* packet_header; // header of packet (timestamp and length)
  47. const unsigned char* packet_data; // packet content
  48.  
  49. /* Retrieve the device list on the local machine */
  50. if(pcap_findalldevs(&devices, error_buffer) == -1)
  51. {
  52. printf("Error in pcap_findalldevs: %s\n", error_buffer);
  53. return -1;
  54. }
  55.  
  56. // Chose one device from the list
  57. device = select_device(devices);
  58.  
  59. // Check if device is valid
  60. if(device == NULL)
  61. {
  62. pcap_freealldevs(devices);
  63. return -1;
  64. }
  65.  
  66. // Open the capture device
  67. if ((device_handle = pcap_open_live( device->name, // name of the device
  68. 65536, // portion of the packet to capture (65536 guarantees that the whole packet will be captured on all the link layers)
  69. 1, // promiscuous mode
  70. 500, // read timeout
  71. error_buffer // buffer where error message is stored
  72. ) ) == NULL)
  73. {
  74. printf("\nUnable to open the adapter. %s is not supported by libpcap/WinPcap\n", device->name);
  75. pcap_freealldevs(devices);
  76. return -1;
  77. }
  78.  
  79. // Check the link layer. We support only Ethernet for simplicity.
  80. if(pcap_datalink(device_handle) != DLT_EN10MB)
  81. {
  82. printf("\nThis program works only on Ethernet networks.\n");
  83. return -1;
  84. }
  85.  
  86. #ifdef _WIN32
  87. if(device->addresses != NULL)
  88. /* Retrieve the mask of the first address of the interface */
  89. netmask=((struct sockaddr_in *)(device->addresses->netmask))->sin_addr.S_un.S_addr;
  90. else
  91. /* If the interface is without addresses we suppose to be in a C class network */
  92. netmask=0xffffff;
  93. #else
  94. if (!device->addresses->netmask)
  95. netmask = 0;
  96. else
  97. netmask = ((struct sockaddr_in *)(device->addresses->netmask))->sin_addr.s_addr;
  98. #endif
  99.  
  100. // Compile the filter
  101. if (pcap_compile(device_handle, &fcode, filter_exp, 1, netmask) < 0)
  102. {
  103. printf("\n Unable to compile the packet filter. Check the syntax.\n");
  104. return -1;
  105. }
  106.  
  107. // Set the filter
  108. if (pcap_setfilter(device_handle, &fcode) < 0)
  109. {
  110. printf("\n Error setting the filter.\n");
  111. return -1;
  112. }
  113.  
  114. printf("\nListening on %s...\n", device->description);
  115.  
  116. // At this point, we don't need any more the device list. Free it
  117. pcap_freealldevs(devices);
  118.  
  119. // Retrieve the packets
  120. while((result = pcap_next_ex(device_handle, &packet_header, &packet_data)) >= 0){
  121. ethernet_header * eh;
  122. ip_header* ih;
  123. int ip_len;
  124. udp_header* uh;
  125. unsigned char * app_data;
  126. int app_length;
  127.  
  128. // Check if timeout has elapsed
  129. if(result == 0)
  130. continue;
  131.  
  132. // Print libpcap/WinPcap pseudo header
  133. print_winpcap_header(packet_header, ++packet_counter);
  134.  
  135. /* DATA LINK LAYER - Ethernet */
  136. // Retrive the position of the ethernet header
  137. eh = (ethernet_header *)packet_data;
  138. // Print ethernet header
  139. print_ethernet_header(eh);
  140.  
  141. /* NETWORK LAYER - IPv4 */
  142. // Retrieve the position of the ip header
  143. ih = (ip_header*) (packet_data + sizeof(ethernet_header));
  144. // Print ip header
  145. print_ip_header(ih);
  146.  
  147. /* TRANSPORT LAYER - UDP */
  148. // Retrieve the position of the udp header
  149. ip_len = ih->header_length * 4; // header length is calculated using words (1 word = 4 bytes)
  150. uh = (udp_header*) ((unsigned char*)ih + ip_len);
  151. print_udp_header(uh);
  152.  
  153. printf("\n-------------------------------------------------------------\n\t");
  154. app_data = (unsigned char*)(uh + sizeof(uh));
  155. app_length = ntohs(uh->datagram_length) - sizeof(uh);
  156.  
  157. printf("\n\nData:\n");
  158.  
  159. print_application_data(app_data, app_length);
  160.  
  161.  
  162. printf("\n-------------------------------------------------------------\n\t");
  163.  
  164. // For demonstration purpose
  165. printf("\n\nPress enter to receive new packet\n");
  166. getchar();
  167. }
  168.  
  169. if(result == -1){
  170. printf("Error reading the packets: %s\n", pcap_geterr(device_handle));
  171. return -1;
  172. }
  173.  
  174. return 0;
  175. }
  176.  
  177. // This function provide possibility to choose device from the list of available devices
  178. pcap_if_t* select_device(pcap_if_t* devices)
  179. {
  180. int device_number;
  181. int i=0; // Count devices and provide jumping to the selected device
  182. pcap_if_t* device; // Iterator for device list
  183.  
  184. // Print the list
  185. for(device=devices; device; device=device->next)
  186. {
  187. printf("%d. %s", ++i, device->name);
  188. if (device->description)
  189. printf(" (%s)\n", device->description);
  190. else
  191. printf(" (No description available)\n");
  192. }
  193.  
  194. // Check if list is empty
  195. if(i==0)
  196. {
  197. printf("\nNo interfaces found! Make sure libpcap/WinPcap is installed.\n");
  198. return NULL;
  199. }
  200.  
  201. // Pick one device from the list
  202. printf("Enter the interface number (1-%d):",i);
  203. scanf("%d", &device_number);
  204.  
  205. if(device_number < 1 || device_number > i)
  206. {
  207. printf("\nInterface number out of range.\n");
  208. return NULL;
  209. }
  210.  
  211. // Jump to the selected device
  212. for(device=devices, i=0; i< device_number-1 ;device=device->next, i++);
  213.  
  214. return device;
  215. }
  216.  
  217. // Print raw data of headers and applications
  218. void print_raw_data(unsigned char* data, int data_length)
  219. {
  220. int i;
  221. printf("\n-------------------------------------------------------------\n\t");
  222. for(i = 0; i < data_length; i=i+1)
  223. {
  224. printf("%.2x ", ((unsigned char*)data)[i]);
  225.  
  226. // 16 bytes per line
  227. if ((i+1) % 16 == 0)
  228. printf("\n\t");
  229. }
  230. printf("\n-------------------------------------------------------------");
  231. }
  232.  
  233. // Print pseudo header which is generated by libpcap/WinPcap driver
  234. void print_winpcap_header(const struct pcap_pkthdr* packet_header, int packet_counter)
  235. {
  236. time_t timestamp; // Raw time (bits) when packet is received
  237. struct tm* local_time; // Local time when packet is received
  238. char time_string[16]; // Local time converted to string
  239.  
  240. printf("\n\n=============================================================");
  241. printf("\n\tlibpcap/WinPcap PSEUDO LAYER");
  242. printf("\n-------------------------------------------------------------");
  243.  
  244. // Convert the timestamp to readable format
  245. timestamp = packet_header->ts.tv_sec;
  246. local_time = localtime(&timestamp);
  247. strftime( time_string, sizeof time_string, "%H:%M:%S", local_time);
  248.  
  249. // Print timestamp and length of the packet
  250. printf("\n\tPacket number:\t\t%u", packet_counter);
  251. printf("\n\tTimestamp:\t\t%s.", time_string);
  252. printf("\n\tPacket length:\t\t%u ", packet_header->len);
  253. printf("\n=============================================================");
  254. return;
  255. }
  256.  
  257. //Print content of Ethernet header
  258. void print_ethernet_header(ethernet_header * eh)
  259. {
  260. printf("\n=============================================================");
  261. printf("\n\tDATA LINK LAYER - Ethernet");
  262.  
  263. print_raw_data((unsigned char*)eh, 14);
  264.  
  265. printf("\n\tDestination address:\t%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", eh->dest_address[0], eh->dest_address[1], eh->dest_address[2], eh->dest_address[3], eh->dest_address[4], eh->dest_address[5]);
  266. printf("\n\tSource address:\t\t%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", eh->src_address[0], eh->src_address[1], eh->src_address[2], eh->src_address[3], eh->src_address[4], eh->src_address[5]);
  267. printf("\n\tNext protocol:\t\t0x%.4x", ntohs(eh->type));
  268.  
  269. printf("\n=============================================================");
  270.  
  271. return;
  272. }
  273.  
  274. // Print content of ip header
  275. void print_ip_header(ip_header * ih)
  276. {
  277. printf("\n=============================================================");
  278. printf("\n\tNETWORK LAYER - Internet Protocol (IP)");
  279.  
  280. print_raw_data((unsigned char*)ih, ih->header_length * 4);
  281.  
  282. printf("\n\tVersion:\t\t%u", ih->version);
  283. printf("\n\tHeader Length:\t\t%u", ih->header_length*4);
  284. printf("\n\tType of Service:\t%u", ih->tos);
  285. printf("\n\tTotal length:\t\t%u", ntohs(ih->length));
  286. printf("\n\tIdentification:\t\t%u", ntohs(ih->identification));
  287. printf("\n\tFlags:\t\t\t%u", ntohs(ih->fragm_flags));
  288. printf("\n\tFragment offset:\t%u", ntohs(ih->fragm_offset));
  289. printf("\n\tTime-To-Live:\t\t%u", ih->ttl);
  290. printf("\n\tNext protocol:\t\t%u", ih->next_protocol);
  291. printf("\n\tHeader checkSum:\t%u", ntohs(ih->checksum));
  292. printf("\n\tSource:\t\t\t%u.%u.%u.%u", ih->src_addr[0], ih->src_addr[1], ih->src_addr[2], ih->src_addr[3]);
  293. printf("\n\tDestination:\t\t%u.%u.%u.%u", ih->dst_addr[0], ih->dst_addr[1], ih->dst_addr[2], ih->dst_addr[3]);
  294.  
  295. printf("\n=============================================================");
  296.  
  297. return;
  298. }
  299.  
  300.  
  301. void print_udp_header(udp_header * uh)
  302. {
  303. printf("\n=============================================================");
  304. printf("\n\tNETWORK LAYER - User Datagram Protocol (UDP)");
  305.  
  306. printf("\n\tSource port:\t\t%u", ntohs(uh->src_port));
  307. printf("\n\tDestination port:\t\t%u", ntohs(uh->dest_port));
  308. printf("\n\tLength of datagram including UDP header and data:\t\t%u", ntohs(uh->datagram_length));
  309. printf("\n\tHeader checksum:\t\t%u", ntohs(uh->checksum));
  310.  
  311. printf("\n=============================================================");
  312.  
  313. return;
  314. }
  315.  
  316.  
  317. void print_application_data(unsigned char* data, int data_length)
  318. {
  319. int i;
  320. printf("\n-------------------------------------------------------------\n\t");
  321. for(i = 0; i < data_length; i=i+1)
  322. {
  323. printf("%.2x ", ((unsigned char*)data)[i]);
  324.  
  325. // 16 bytes per line
  326. if ((i+1) % 16 == 0)
  327. printf("\n\t");
  328. }
  329. printf("\n-------------------------------------------------------------");
  330. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement