Question

I am an absolute beginner with winpcap and c++. I want to read dump files, change the MAC-address(es) of some packets and delete the other packets. So in the end, my file is only supposed to contain the changed packets (same file as before, only without the 'unimportant' packtes).

I use Qt Creator, mingw, c++ and winpcap (of course).

What works so far: Reading from the file, displaying the mac/ip/whatever I want. What does not work: Editing the packets.

I use some structs to read the data out of my packet:

struct pcap_hdr_s {
public:
uint32_t magic_number;   /* magic number */
uint16_t version_major;  /* major version number */
uint16_t version_minor;  /* minor version number */
int32_t  thiszone;       /* GMT to local correction */
uint32_t sigfigs;        /* accuracy of timestamps */
uint32_t snaplen;        /* max length of captured packets, in octets */
uint32_t network;        /* data link type */
};

struct pcaprec_hdr_s {
public:
uint32_t ts_sec;         /* timestamp seconds */
uint32_t ts_usec;        /* timestamp microseconds */
uint32_t incl_len;       /* number of octets of packet saved in file */
uint32_t orig_len;       /* actual length of packet */
} ;

struct ip_address{
public:
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
};

struct mac_adress{
public:
u_char mac1;
u_char mac2;
u_char mac3;
u_char mac4;
u_char mac5;
u_char mac6;
};

/*Ethernet header*/
struct eth_header{
public:
mac_adress dst_mac;
mac_adress src_mac;
uint16_t type;
};

/* IPv4 header */
struct ip_header{
public:
u_char  ver_ihl;        // Version (4 bits) + Internet header length (4 bits)
u_char  tos;            // Type of service
u_short tlen;           // Total length
u_short identification; // Identification
u_short flags_fo;       // Flags (3 bits) + Fragment offset (13 bits)
u_char  ttl;            // Time to live
u_char  proto;          // Protocol
u_short crc;            // Header checksum
ip_address* saddr;      // Source address
ip_address* daddr;      // Destination address
//u_int   op_pad;         // Option + Padding --> optional
};

/* UDP header*/
struct udp_header{
public:
u_short sport;          // Source port
u_short dport;          // Destination port
u_short len;            // Datagram length
u_short crc;            // Checksum
};

This is my code so far for editing the packets:

void changeMAC(QString wantedMac, QString file){
const u_char *pkt_data;
struct pcap_pkthdr *header;
pcap_t *pd;
pcap_dumper_t *pdumper;
eth_header *ethHeader;
ip_header *ipHeader;
int res = 0;
QString check;

pd = pcap_open_dead(DLT_EN10MB, 65535);

/*output file = input file*/
pdumper = pcap_dump_open(pd, qPrintable(file));

while((res = pcap_next_ex(pd, &header, &pkt_data)) >= 0){//iterate through the packets in the file
    ipHeader = (ip_header *)(pkt_data + 14);
    if(ipHeader->proto == 17){ //I only have a look at udp
        ethHeader = (eth_header *)(pkt_data); //check if this is the MAC I want to cahnge

        check.clear();
        check.append(ethHeader->dst_mac.mac1);
        check.append(ethHeader->dst_mac.mac2);
        check.append(ethHeader->dst_mac.mac3);
        check.append(ethHeader->dst_mac.mac4);
        check.append(ethHeader->dst_mac.mac5);
        check.append(ethHeader->dst_mac.mac6);//'check' contains the current MAC of the packet

        if(wantedMac.contains(check.toAscii().toHex())){ //if 'check' contains the MAC I was looking for
            /*
            * Create fake IP header and put UDP header
            * and payload in place
            * --> how to do this for all wanted packets?
            */

            pcap_dump((u_char *)pdumper, header, pkt_data); //write changed packet to file
         }
         else{
         //delete the packet --> how?
         }
    }
}
pcap_close(pd);
pcap_dump_close(pdumper);
}

I have had a look at this, and it helped, but just up to this point. My code is all I have so far.

Edit: As a first step, I would also be happy if I were able to save the edited packets in a second file, not in the file the packets come from. But how to edit them?

Was it helpful?

Solution

Ok, I figured out something by myself. It might not be the most elegant solution, but it works.

QString string;
QStringList mac;
int result=0;
bool ok;
QChar d

string=mac[0];//first part of mac address to string

for(int i=0; i<string.length();i++){//string to ascii hex and int
    d=string.toUInt(&ok,16);
    result=d.unicode();
}

ethHeader->dst_mac.macPart1=result;//allocate, go on for next part of macaddress
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top