Pawan_Yadav Ответов: 2

Как решить проблему извлечения данных из текстового файла tcpdump на языке C++


Файл содержит множество подобных пакетов, вычисляет время между TCP-пакетом, отправленным клиентом, и соответствующим сообщением ICMP "Time exceeded in-transit".

1485649766.851430 IP (tos 0x0, ttl 1, id 32177, смещение 0, флаги [нет], proto TCP (6), Длина 60)
172.17.152.112.42006 > 188.184.9.235.80: флаги [S], cksum 0x7315 (правильно), seq 139241346, win 5840, опции [mss 1460, sackOK, TS val 2376913176 ecr 0, nop,wscale 2], Длина 0
1485649766.851437 IP (tos 0x0, ttl 1, id 32178, смещение 0, флаги [нет], proto TCP (6), Длина 60)
1485649766.851727 IP (tos 0x0, ttl 63, id 44002, смещение 0, флаги [нет], proto ICMP (1), длина 56)
128.192.0.5 > 172.17.152.112: превышение времени ICMP в пути, длина 36
IP (tos 0x0, ttl 1, id 32180, offset 0, flags [none], proto TCP (6), Длина 60)
172.17.152.112.53542 &ГТ; 188.184.9.235.80: [|ПТС]

Я хочу извлечь
метка времени = 1485649766.851430
ttl = 1
id = 32177
proto = ICMP
Ip отправителя = 172.17.152.112.42006
Ip приемника = 188.184.9.235.80

Спасибо.

Что я уже пробовал:

Я пробовал работать со Stringstream, но это ни к чему не привело.

2 Ответов

Рейтинг:
14

Daniel Pfeffer

Я предполагаю, что:

1. Файл представляет собой обычный текстовый файл
2. каждая запись имеет заголовок, состоящий из одной строки, за которой, возможно, следуют другие строки)
3. Заголовок этого формата:
1485649766.851430 IP (tos 0x0, ttl 1, id 32177, смещение 0, флаги [нет], proto TCP (6), Длина 60)

В таком случае вам следует:

a. прочитайте первую строку в строку. Если это не заголовок (то есть если он не содержит строки ' IP ('), отбросьте его и вернитесь к (a).
б. извлеките метку времени: это все, что находится перед маркером "IP".
c. извлеките часть строки внутри круглых скобок (например, 'tos 0x0,..., длина 60)
d. у вас есть список, разделенный запятыми. Разделите это на части. Это даст вам "ttl", " id " и т. д.
e. прочитайте следующую строку. Если это заголовок, перейдите к (b).
f.у вас есть IP-адреса в начале строки. Извлеките все, что было перед первым ':', и отделите эту строку от '>'. Первая часть-это адрес "от", а вторая-адрес "до".
е) если вы не дошли до конца, вернитесь к пункту (а).

Вы можете найти такие функции, как строка:: найти() и строка:: substr() чтобы быть более полезным для этой задачи, чем istringstream. Использовать только istringstream если вам нужно преобразовать значения из string в int или double (например).


CPallini

5.

Stefan_Lang

5 Кроме того, я хотел бы добавить, что шаг c может быть немного сложным, так как строка для извлечения сама может содержать скобки. Поэтому вам нужно следить за количеством открывающихся и закрывающихся скобок, чтобы правильно определить конец этой строки.

Рейтинг:
1

Pawan_Yadav

/* 
 * File:   main.cpp
 * Author: Pawan
 *
 * Created on 30 January, 2017, 9:19 PM
 */

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <iomanip>

using namespace std;

    string trim(const string& str)
    {   string s;
        size_t first = str.find_first_not_of(' ');
         if (string::npos == first)
             {
               return str;
             }
        size_t last = str.find_last_not_of(' ');
        s = str.substr(first, (last - first + 1));
        size_t second = s.find_first_not_of('\t');
        if (string::npos == second)
             {
               return s;
             }
        size_t slast = s.find_last_not_of(' ');
        return s.substr(second, (slast - second + 1));
    }
  
    
int main(int argc, char** argv) {

    string line;
    ifstream myfile;
    ofstream tmpfile ("temp.txt");                  // Making a temp file with proper formatting
    if (tmpfile.is_open())
	{	if (argv[1] == NULL)
		{
		cout << "Please Enter the File name with location as Command Line Argument";
		}
		else {
             myfile.open(argv[1]);
             int i = 0;
             while(!myfile.eof())
                {   
                    getline(myfile, line);
                    line = trim(line);
                    tmpfile<<line<<"\n";
                    i++;
                }   
     
		}
		
	}
    myfile.close();
    tmpfile.close();
    
    string incoming[80][4];
    string outgoing[100][3];
    
    int i = 0;
    int j = 0;
    
    ifstream uyfile ("temp.txt");
    if (uyfile.is_open())                           // Logic for Extraction of specific information
    {
        while(!uyfile.eof())  
        {
        getline(uyfile, line);
        size_t found = line.find(" proto ICMP (1),");
        
             if(found != string::npos)
                 {
                     size_t l = line.find_first_of(' ');
                     incoming[i][0] = line.substr(0,l);
                     getline(uyfile, line);
                     size_t k = line.find_first_of(' ');
                     incoming[i][1] = line.substr(0,k);
                     getline(uyfile, line);
                     incoming[i][2] = line.substr(line.find("id")+3,line.find(", of")-line.find("id")-3); 
                     i++;
                }  
             else{
            size_t found1 = line.find(" proto TCP (6),");
            
            if(found1 != string::npos)
                 {
                    size_t m = line.find_first_of(' ');
                    outgoing[j][0] = line.substr(0,m);
                    outgoing[j][1] = line.substr(line.find("ttl ")+3,line.find(", id")-line.find("ttl ")-3);
                    outgoing[j][2] = line.substr(line.find("id")+3,line.find(", of")-line.find("id")-3);
                    getline(uyfile, line);
                    size_t k = line.find_first_of(' ');
                     outgoing[j][3] = line.substr(0,k);
                    j++;
            }
             }
         }  
    }   
    uyfile.close();
    
    cout<<"\n\n Outgoing Packet Information \n";
    for (int p = 0;  p<j; p++)                          // Printing Outgoing packet information
    { cout<<"Outgoing Packet : "<<p<<"\n";
        cout<<"TimeStamp : "<<outgoing[p][0]<<"\n";
        cout<<"TTL : "<<outgoing[p][1]<<"\n";
        cout<<"ID : "<<outgoing[p][2]<<"\n";
        cout<<"Sender's ID : "<<outgoing[p][3]<<"\n\n";
    }
    
    cout<<"\n\n Incoming Packet Information \n";
    
    for (int a = 0;  a<i; a++)                        // Printing Incoming packet information
    { 
        cout<<"Incoming Packet : "<<a<<"\n";
        cout<<"TimeStamp : "<<incoming[a][0]<<"\n";
        cout<<"Router's IP Address : "<<incoming[a][1]<<"\n";
        cout<<"ID : "<<incoming[a][2]<<"\n\n";
    }    
    
    for (int a=0; a<i; a++)                           // For Consecutive Packets related to same ICMP Source
    {  for (int b=0; b<i; b++)
         { if (incoming[a][1]==incoming[b][1])
                incoming[b][2] = incoming[a][2];
         }
    }
    cout<<"===================================================================";
    cout<<"\n\n REQUIRED OUTPUT - TCPDUMP ANALYSIS";
    
    int d;
    cout<<setprecision(10);
    for (int a=0; a<j; a++)
        { d=0;
        for (int b=0; b<i; b++)
            {
                if(outgoing[a][2] == incoming[b][2])
                    {
                        if (d == 0)
                            {   d = 1;
                                cout<<"\n";
                                cout<<"TTL : "<<outgoing[a][1]<<"\n";
                                cout<<"Router's IP : "<<incoming[b][1]<<"\n";
                                cout<<"RTT : "<<(atof(incoming[b][0].c_str())- atof(outgoing[a][0].c_str()))*1000<<" ms"<<"\n";
                        
                            }
                        else {
                            cout<<"RTT : "<<(atof(incoming[b][0].c_str())- atof(outgoing[a][0].c_str()))*1000<<" ms"<<"\n";
                            }
                    }
            }
        }
        
    return 0;
}