Use PCAP to write your own Snifer (2)

zhaozj2021-02-16  59

How to use (handle) Packet pointer variables? The structure referred to by a Packet pointer contains a lot of properties, which is not a real string, but a collection of multiple structures (such as: a TCP / IP packet includes Ethernet head, IP header, TCP head and data A valid data load in the package).

First need to define these structures:? / * Ethernet header * / struct sniff_ethernet {u_char ether_dhost [ETHER_ADDR_LEN]; / * Destination host address * / u_char ether_shost [ETHER_ADDR_LEN]; / * Source host address * / u_short ether_type; / * IP ARP? RARP? Etc * /}; / * ip header * / struct sniff_ip {#if byte_order == little_endian u_int ip_hl: 4, / * header length * / ip_v: 4; / * version * / #if byte_order == BIG_ENDIAN U_INT IP_V : 4, / * Version * / ip_hl: 4; / * Header length * / #ndif #ENDIF / * NOT _IP_VHL * / U_CHAR IP_TOS; / * TYPE OF Service * / u_short ip_len; / * total length * / u_short ip_id; / * identification * / u_short ip_off; / * fragment offset field * / #define IP_RF 0x8000 / * reserved fragment flag * / #define IP_DF 0x4000 / * dont fragment flag * / #define IP_MF 0x2000 / * more fragments flag * / #define Ip_offmask 0x1fff / * mask for fragmenting bits * / u_char ip_ttl; / * time to live * / u_char ip_p_p; / * protocol * / u_short ip_sum; / * checksum * / struct in_addr ip_src, ip_dst; / * source and dest address * /}; / * TCP header * / struct sniff_tcp {u_short th_sport; / * source port * / u_short th_dport; / * destination port * / tcp_seq th_seq; / * sequence number * / tcp_seq th_ack; / * acknowledgement Number * / #if byte_order == little_endian u_int TH_X2: 4, / * (unused) * / TH_OFF: 4; / * Data Offset * / #ENDIF #IF BYTE_ORDER == BIG_ENDIAN U_INT TH_OFF: 4, / * DATA Offset * / TH_X2: 4; / * (unused) * / #ndif u_char th_flags;

#define TH_FIN 0x01 #define TH_SYN 0x02 #define TH_RST 0x04 #define TH_PUSH 0x08 #define TH_ACK 0x10 #define TH_URG 0x20 #define TH_ECE 0x40 #define TH_CWR 0x80 #define TH_FLAGS (TH_FIN | TH_SYN | TH_RST | TH_ACK | TH_URG | TH_ECE | TH_CWR) U_SHORT TH_WIN; / * WINDOW * / U_SHORT TH_SUM; / * CHECKSUM * / U_SHORT TH_URP; / * Urgent Pointer * /}; Note: These structures define that there may be differences in different system implementations, please refer to the relevant documentation. Another: I don't understand what the author means. Why do you have to define these structures yourself, why don't you use your own implementation? The original author's description of these structures is omitted ... Suppose we process the TCP / IP packet (similar to other physical networks) by Ethernet, the following code decomposes the structure referred to by the Packet pointer into different structures: const struct sniff_ethernet * ethernet; / * The ethernet header * / const struct sniff_ip * ip; / * The IP header * / const struct sniff_tcp * tcp; / * The TCP header * / const char * payload; / * Packet payload * / / * For readability , we'll make variables for the sizes of each of the structures * / int size_ethernet = sizeof (struct sniff_ethernet); int size_ip = sizeof (struct sniff_ip); int size_tcp = sizeof (struct sniff_tcp); And now we do our magical typecasting : ethernet = (struct sniff_ethernet *) (packet); ip = (struct sniff_ip *) (packet size_ethernet); tcp = (struct sniff_tcp *) (packet size_ethernet size_ip); payload = (u_char *) (packet size_ethernet SIZE_IP SIZE_TCP); If the packet value (the address refers to this pointer variable) is x, the layout of the structure described above is as follows: variable location (in Bytes) Sniff_Thernet X SNIFF_IP X 14 SNIFF_TCP X 14 20 PayLoad X 14 20 20 Wrapping Up to this, we can use PCAP to write a Sniffer application. We have already understood the basics of PCAP programming, including opening a PCAP session handle, processing properties of the PCAP session handle, listens packet, applying filtering rules, and uses the callback function to define our own processing.

The sample program supplied with the original: sniffer.c This document is Copyright 2002 Tim Carstens All rights reserved Redistribution and use, with or without modification, are permitted provided that the following conditions are met:.. 1. Redistribution must retain the above copyright notice and this list of conditions 2. The name of Tim Carstens may not be used to endorse or promote products derived from this document without specific prior written permission / * Insert 'wh00t' for the BSD license here * / Appendix: Example with pcap Sample program / * compile: gcc -wall -o testpcap testpcap.c -lpcap * / #include #include #include #include # Include #include #include #include #include #include #include #include / * macro to print debug info * / // # Define debug 1 #ifdef debug #define debug (stderr, msg) FPRINTF (stderr , MSG) #define _, #else / * if no define debug * / #define debug (stderr , MSG) #ENDIF / * END OF BEBUG * / #DEfine lookupdev_err -1 #define open_live_err -2 #define compile_err -3 / * protocol id's * / #define ippro 8 / * ip protocol * / / / / / * CALL Back Function Invoke By pcap_loop, major process for ourselves * / void got_packet (u_char * args, const struct pcap_pkthdr * header, const u_char * packet); / * handle ethernet header * / u_int16_t handle_ethernet (u_char * args, const struct pcap_pkthdr * pkthdr, const u_char * Packet); / * handle ip header * / void handle_ip (u_char * args, const struct pcap_pkthdr * pkthdr, const u_char * packet); int Main (int Argc, char * argv []) {char * dev = null;

/ * Device to sniff on * / char errbuf [PCAP_ERRBUF_SIZE]; / * buffer to store error msg * / pcap_t * handle = NULL; / * pcap session handle * / struct bpf_program filter; // compiled filter expression char filter_app [] = "port 23"; / * filter ruler for sniffing * / bpf_u_int32 mask; // netmask of our sniffing device bpf_u_int32 net; // the ip of our sniffing device int num = 0; / * number of packets captured * / / * variables For getopt * / long total = -1; / * Total packets to Sniff * / char * flter = filter_app; / * filter ruler for sniffing * / int C; / * tempr grar variable * / while ((c = getopt (argc , Argv, "N: f:")))))))))))))))))))))! = -1) {Switch (c) {CASE 'N': Total = ATOI (OPTARG); Break; Case 'F': flter = OPTARG; BREAK; CASE '? ': Fprintf (stderr, "Usage:% s -n -f / n", argv [0]); exit (1); default: fprintf (stdout, "Using Fitler: port 23 and Sniffing UT Il interrupt by console! / n ");}}} (null == (dev = pcap_lookupdev (errbuf))) {fprintf (stderr," pcap_lookupdev () error:% s / n ", errbuf); EXIT (LookupDev_err) FPRINTF (Stdout, "Sniffing On Device: S / N / N", DEV); PCAP_LOOKUPNET (dev, & net, & mask, errbuf); / * Open a new PCAP session * / if (null == (Handle = PCAP_Open_Live (dev, bufsiz, 1, 0, errbuf)) {fprintf (stderr, "pcap_open_live () error:% s / n", errbuf); EXIT (Open_LIVE_ERR);} / * compile capture rule * / if (- 1 == PCAP_Compile (Handle, &)

filter, flter, 1, net)) {fprintf (stderr, "pcap_compile () error / n!"); exit (COMPILE_ERR);} pcap_setfilter (handle, & filter); / * using while pcap_next instead of pcap_loop or pcap_dispatch * / / * While (1) {debug (stderr, "in pcap_next while / n"); packet = pcap_next (handle, & head); Printf ("Captured a packet with length of [% d] / n", Header.len Debug (stderr, "the packet capture:% s / n" _ packet header.caplen;} * / num = PCAP_LOOP (Handle, Total, Got_Packet, NULL); if (-1 == Num) {PCAP_PERROR (Handle, "PCAP_LOOP ERROR:");} if (-2 == Num) {PCAP_PERROR (Handle, "PCAP_LOOP BREAK BY PCAP_BREAKLOOP:");} PCAP_CLOSE (Handle); Return 0;} void got_packet (u_char * args, const struct pcap_pkthdr * header, const u_char * packet) {u_int16_t type; type = handle_ethernet (args, header, packet); debug (stderr, "protocol type:% i / n" _ type); switch (type) {case IPPRO : Debug (stderr, "protocol type: IP / n"); handle_IP (args, header, packet); break; case ETHERTYPE_ARP: / * handle arp protocol * / break; case ETHERTYPE_REVARP: / * handle rarp protocol * / break; default: fprintf (stdout, "Protocol is ignored / n"); } fprintf (stdout, "/ n"); return;} // end of got_packet u_int16_t handle_ethernet (u_char * args, const struct pcap_pkthdr * pkthdr, const u_char * packet) {struct ether_header * eptr; / * net / ethernet.h * / / * Lets start with the ether header ... * / eptr = (struct ether_header *) packet; fprintf (stdout, "eth:% s ->"

, Ether_NTOA (EPTR-> Ether_SHOST)))); FPRINTF (stdout, "% s", ether_ntoa ((struct ether_addr *))); / * Check to See IF We Have An ip packet * / if (ntoHS (EPTR-> Ether_TYPE) == ETHERTYPE_IP) {fprintf (stdout, "(ip)");} else if (ntohs (ePTR-> Ether_TYPE) == ethertype_arp) {fprintf (stdout, "(ARP)");} else if (ntoHs (eptr-> ether_type) == ethertype_revarp) {fprintf (stdout, "(rarp)");} else {fprintf (stdout, "(?)"); Exit 1);} return eptr-> ether_type;} // end of handle_ethernet void handle_IP (u_char * args, const struct pcap_pkthdr * pkthdr, const u_char * packet) {const struct iphdr * ip = (const struct iphdr *) (packet SIZEOF (STRUCT Ether_Header); u_int length = pkthdr-> le; u_int hlen, OFF, version; int Len; struct in_addr in; debug (stderr, "Total PCAP PKT length:% I / N" _ length); debug Stderr, "Total PCAP PKT Header Length:% I / N" _ pkthdr-> caplen; / * jump pass the Ethernet header * / length = - sizeof (strunt ether_header); / * Check to see we have a packet of valid length * / if (length TOT_LEN); Debug (stderr, "Total IP Pkt Length:% I / N" _ len); hlen = ip-> hl; / * header length * / debug (stderr, "ip header length:% i / n "_ hlen); version = ip-> version; / * ip version * / debug (stderr," ip version:% I / n "_ version); / * check version * / if (version! = 4) {FPRINTF (stdout, "unknown version% D / N", version;

转载请注明原文地址:https://www.9cbs.com/read-21827.html

New Post(0)