Sniffer w C - zawieszona praca programu

0

Witam. Napisałem sniffer w C, który przechwytuje ramki ethernet a takze zapisuje pakiety TCP do bufora i wydziela poszczegolne elementy nagłówka. Wszystko się kompiluje, 20 pakietów zapisuje mi się do listy wiązanej i jest wyświetlana, jednak program ma działać dalej po wypisaniu pierwszych 20 pakietow a przy drugim zapisie pakeitu TCP się zawiesza. Proszę o pomoc ;)

/* ============================================================================
 Name        : Laborka.c
 Author      : Kicaj
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================*/


#include <stdio.h> // in/out
#include <stdlib.h> // malloc itp
#include <errno.h> // numer bledu
#include <string.h> // memcpy
#include <sys/socket.h> // deifniuje socklen_t
#include <linux/if_ether.h> // ethernet
#include "tcph.h" //naglowek

struct lista* pierwszy = NULL;
int licznik;
int iDataLen = 0;
int d=0;
int e=0;

struct listaprzejscie *adres_zakotwiczenia = NULL;
  struct listaprzejscie *adres_obecny = NULL;
  struct listaprzejscie *adres_ostatni = NULL;
  struct listaprzejscie *usun = NULL;

  unsigned char dane[1500];
  //memset(dane, 0, 1500);


void TCP(unsigned char* recivedPocket[1500],int iDataLen)
{
	struct lista* pomoc;
	pomoc = (struct lista*) malloc(sizeof(struct lista));


    for (int i=0;i<20;i++)
     {
         if(adres_zakotwiczenia == NULL) //jeśli lista jest pusta
         {
             adres_zakotwiczenia = (struct listaprzejscie*) malloc(sizeof(struct listaprzejscie)); //przydzielenie pamieci dla elementu listy
             adres_obecny = adres_zakotwiczenia;
             adres_obecny->pierwszy = adres_zakotwiczenia;
             adres_obecny->nastepny = NULL;
             adres_obecny->poprzedni = NULL;
             memcpy (adres_obecny->bufor, recivedPocket, 1500);
             adres_obecny= NULL;

         }
         else
         {
             adres_ostatni = adres_zakotwiczenia;
             for (int j=0;j<20;j++)
             {
                 if (adres_ostatni->nastepny != NULL)
                 {
                     adres_ostatni = adres_ostatni->nastepny;
                 }
                 else
                     break;
             }
         adres_obecny = (struct listaprzejscie*) malloc(sizeof(struct listaprzejscie));
         adres_ostatni->nastepny = adres_obecny;
         adres_obecny->pierwszy = adres_zakotwiczenia;
         adres_obecny->nastepny = NULL;
         adres_obecny->poprzedni = adres_ostatni;
         memcpy (adres_obecny->bufor, recivedPocket, 1500);

         }
     }

}
void wyswietl(int iDataLen)
{
    	licznik = 0;
        struct lista* pomoc;
        pomoc = (struct lista*) malloc(sizeof(struct lista));
        struct dane* dane;
                dane = (struct dane*) malloc(sizeof(struct dane));
    	adres_obecny= adres_zakotwiczenia;
    	for (int ce=0;ce<20;ce++)
    	{


            pomoc->portZrodlowy[0] = adres_obecny->bufor[0];
            	pomoc->portZrodlowy[1] = adres_obecny->bufor[1];
            	pomoc->portDocelowy[0] = adres_obecny->bufor[2];
            	pomoc->portDocelowy[1] = adres_obecny->bufor[3];
            	pomoc->nrsekwencyjny[0] = adres_obecny->bufor[4];
            	pomoc->nrsekwencyjny[1] = adres_obecny->bufor[5];
            	pomoc->nrsekwencyjny[2] = adres_obecny->bufor[6];
            	pomoc->nrsekwencyjny[3] = adres_obecny->bufor[7];
            	pomoc->nrpotwbajtu[0] = adres_obecny->bufor[8];
            	pomoc->nrpotwbajtu[1] = adres_obecny->bufor[9];
            	pomoc->nrpotwbajtu[2] = adres_obecny->bufor[10];
            	pomoc->nrpotwbajtu[3] = adres_obecny->bufor[11];
            	pomoc->dlnaglowka[0] = adres_obecny->bufor[12];
            	pomoc->dlnaglowka[1] = adres_obecny->bufor[13];
            	pomoc->rozmiarokna[0] = adres_obecny->bufor[14];
            	pomoc->rozmiarokna[0] = adres_obecny->bufor[15];
            	pomoc->sumakontrolna[0] = adres_obecny->bufor[16];
            	pomoc->sumakontrolna[1] = adres_obecny->bufor[17];
            	pomoc->wskpilnych[0] = adres_obecny->bufor[18];
            	pomoc->wskpilnych[1] = adres_obecny->bufor[19];
            	for(int b=20;b<iDataLen;b++)
            	{
            		dane->bufor[d]=adres_obecny->bufor[b];
            		d=d+1;
            	}
    		printf("Numer ramki w buforze: %d \n", licznik=licznik + 1);
    					printf("Rozmiar licznika: %li \n", sizeof(licznik));
    					printf("Rozmiar struktury naglowka:%d \n", sizeof(struct lista));
    					printf("Port zrodlowy: %02x %02x\n", pomoc->portZrodlowy[0],pomoc->portZrodlowy[1]);
    					printf("Port docelowy: %02x %02x\n", pomoc->portDocelowy[0],pomoc->portDocelowy[1]);
    					printf("Nr sekwencyjny: %02x %02x %02x %02x\n", pomoc->nrsekwencyjny[0], pomoc->nrsekwencyjny[1],pomoc->nrsekwencyjny[2],pomoc->nrsekwencyjny[3]);
    					printf("Nr potwierdzenia bajtu: %02x %02x %02x %02x\n", pomoc->nrpotwbajtu[0], pomoc->nrpotwbajtu[1],pomoc->nrpotwbajtu[2],pomoc->nrpotwbajtu[3]);
    					printf("Dl naglowka: %02x %02x\n", pomoc->dlnaglowka[0],pomoc->dlnaglowka[1]);
    					printf("Rozmiar okna: %02x %02x\n", pomoc->rozmiarokna[0],pomoc->rozmiarokna[1]);
    					printf("Suma kontrolna: %02x %02x\n", pomoc->sumakontrolna[0],pomoc->sumakontrolna[1]);
    					printf("Wsk pilnych: %02x %02x\n", pomoc->wskpilnych[0],pomoc->wskpilnych[1]);
    					printf("Dane: ");
    					for(int a=20;a<iDataLen;a++)
    					{
    						printf("%02x ",dane->bufor[a]);
    					}
    					printf("\n\n");

    	}






}


void usuwanie()

{

	if (licznik == 1) {
		adres_zakotwiczenia = NULL;
		free(pierwszy);
	}
	else //ostatni wezel
	{
		adres_obecny = adres_zakotwiczenia;
		while (adres_obecny->nastepny->nastepny != NULL) {
			adres_obecny = adres_obecny->nastepny;
		}
		adres_ostatni= adres_obecny->nastepny;
		adres_obecny->nastepny = NULL;
		free(adres_obecny);
	};
	printf("usuwanie wykonane");
	licznik--;
}
void typ(unsigned char* buffer,int iDataLen)
{
	if ((*(buffer + 12) == 0x08) && (*(buffer + 13) == 0x00) && (*(buffer + 23) == 0x08))
	{
		printf("Odebrano pakiet EGP o rozmiarze [B] %d \n",iDataLen);
	}
	else if ((*(buffer + 12) == 0x08) && (*(buffer + 13) == 0x00) && (*(buffer + 23) == 0x02))
		{
			printf("Odebrano pakiet IGMP  o rozmiarze [B] %d \n",iDataLen);
		}
	else if ((*(buffer + 12) == 0x08) && (*(buffer + 13) == 0x00) && (*(buffer + 23) == 0x01))
		{
			printf("Odebrano pakiet ICMP o rozmiarze [B] %d \n",iDataLen);
		}
	else
			{
				printf("Odebrano inny pakiet o rozmiarze [B] %d \n", iDataLen);
			}

}
int main(void)
{
	int i = 1;
	printf("Uruchamiam odbieranie ramek Ethernet.\n"); /* prints */
	//Utworzenie bufora dla odbieranych ramek Ethernet

	unsigned char* buffer = (void*) malloc(ETH_FRAME_LEN);
	//Otwarcie gniazda pozwalającego na odbiór wszystkich ramek Ethernet
	int iEthSockHandl = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
	//Kontrola czy gniazdo zostało otwarte poprawnie, w przypadku bledu wyświetlenie komunikatu.
		if (iEthSockHandl<0)
		printf("Problem z otwarciem gniazda : %s!\n", strerror(errno));
		//Zmienna do przechowywania rozmiaru odebranych danych
		int iDataLen = 0;
		//Pętla nieskończona do odbierania ramek Ethernet
			while (1) {
			//Odebranie ramki z utworzonego wcześniej gniazda i zapisanie jej do bufora
			iDataLen = recvfrom(iEthSockHandl, buffer, ETH_FRAME_LEN, 0, NULL, NULL);
			//Kontrola czy nie było bledu podczas odbierania ramki
				if (iDataLen == -1)
				printf("Nie moge odebrac ramki: %s! \n", strerror(errno));
				else { //jeśli ramka odebrana poprawnie wyświetlenie jej zawartości
					typ(buffer,iDataLen);
					if ((*(buffer + 12) == 0x08) && (*(buffer + 13) == 0x00) && (*(buffer + 23) == 0x06))
					{
						printf("Odebrano pakiet TCP o rozmiarze %d [B]: \n",iDataLen);
						i = i + 1;
							if (i <= 20)
							{
								TCP(buffer + 34,iDataLen);
							}
							else if (i > 20 && i <= 21)
							{
								printf("\n\n BUFOR TCP PEŁNY, OTO JEGO ZAWARTOŚĆ: \n\n");
								wyswietl(iDataLen);
							} else
							{
								while (licznik > 1)
								{
								usuwanie();
								}
							i = 1;
							}

					}

			}
	}
return EXIT_SUCCESS;
}



Naglowek

/*
 * tcph.h
 *
 *  Created on: 28 maj 2018
 *      Author: kicaj
 */


#ifndef TCPHEADER_H_
#define TCPHEADER_H_

struct lista {
	unsigned char portZrodlowy[2];
	unsigned char portDocelowy[2];
	unsigned char nrsekwencyjny[4];
	unsigned char nrpotwbajtu[4];
	unsigned char dlnaglowka[2];
	unsigned char rozmiarokna[2];
	unsigned char sumakontrolna[2];
	unsigned char wskpilnych[2];

};
struct listaprzejscie
{
	struct listaprzejscie* pierwszy;
	struct listaprzejscie* poprzedni;
	struct listaprzejscie* nastepny;
	unsigned char bufor[1500];
};
struct dane
{
	unsigned char bufor[1500];
};


#endif /* TCPH_H_ */
0

A debugger posiadasz?

0

Korzystałem z debuggera, i wyskakuje mi błąd malloca: Can't find a source file at "/build/glibc-itYbWN/glibc-2.26/malloc/malloc.c" .
Zaznaczona jest przy tym linia

adres_zakotwiczenia = (struct listaprzejscie*) malloc(sizeof(struct listaprzejscie)); //przydzielenie pamieci dla elementu listy

Nie rozumiem o co chodzi, zmieniłem w paru miejscach kod i teraz wygląda tak.

/* ============================================================================
 Name        : Laborka.c
 Author      : Kicaj
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================*/


#include <stdio.h> // in/out
#include <stdlib.h> // malloc itp
#include <errno.h> // numer bledu
#include <string.h> // memcpy
#include <sys/socket.h> // deifniuje socklen_t
#include <linux/if_ether.h> // ethernet
#include "tcph.h" //naglowek

struct lista* pierwszy = NULL;
int licznik;
int iDataLen = 0;
int d=0;
int e=0;

struct listaprzejscie *adres_zakotwiczenia = NULL;
  struct listaprzejscie *adres_obecny = NULL;
  struct listaprzejscie *adres_ostatni = NULL;
  struct listaprzejscie *usun = NULL;
  struct lista* pomoc=NULL;

  unsigned char dane[1500];
  //memset(dane, 0, 1500);


void TCP(unsigned char* recivedPocket[1500],int iDataLen)
{

	pomoc = (struct lista*) malloc(sizeof(struct lista));


    for (int i=0;i<20;i++)
     {
         if(adres_zakotwiczenia == NULL) //jeśli lista jest pusta
         {
             adres_zakotwiczenia = (struct listaprzejscie*) malloc(sizeof(struct listaprzejscie)); //przydzielenie pamieci dla elementu listy
             adres_obecny = adres_zakotwiczenia;
             adres_obecny->pierwszy = adres_zakotwiczenia;
             adres_obecny->nastepny = NULL;
             adres_obecny->poprzedni = NULL;
             memcpy (adres_obecny->bufor, recivedPocket, 1500);
             adres_obecny= NULL;


         }
         else
         {
             adres_ostatni = adres_zakotwiczenia;
             for (int j=0;j<20;j++)
             {
                 if (adres_ostatni->nastepny != NULL)
                 {
                     adres_ostatni = adres_ostatni->nastepny;
                 }
                 else
                     break;
             }
         adres_obecny = (struct listaprzejscie*) malloc(sizeof(struct listaprzejscie));
         adres_ostatni->nastepny = adres_obecny;
         adres_obecny->pierwszy = adres_zakotwiczenia;
         adres_obecny->nastepny = NULL;
         adres_obecny->poprzedni = adres_ostatni;
         memcpy (adres_obecny->bufor, recivedPocket, 1500);

         }
     }

}
void wyswietl(int iDataLen)
{
    	licznik = 0;

        pomoc = (struct lista*) malloc(sizeof(struct lista));
        struct dane* dane;
                dane = (struct dane*) malloc(sizeof(struct dane));
    	adres_obecny= adres_zakotwiczenia;
    	for (int ce=0;ce<20;ce++)
    	{


            pomoc->portZrodlowy[0] = adres_obecny->bufor[0];
            	pomoc->portZrodlowy[1] = adres_obecny->bufor[1];
            	pomoc->portDocelowy[0] = adres_obecny->bufor[2];
            	pomoc->portDocelowy[1] = adres_obecny->bufor[3];
            	pomoc->nrsekwencyjny[0] = adres_obecny->bufor[4];
            	pomoc->nrsekwencyjny[1] = adres_obecny->bufor[5];
            	pomoc->nrsekwencyjny[2] = adres_obecny->bufor[6];
            	pomoc->nrsekwencyjny[3] = adres_obecny->bufor[7];
            	pomoc->nrpotwbajtu[0] = adres_obecny->bufor[8];
            	pomoc->nrpotwbajtu[1] = adres_obecny->bufor[9];
            	pomoc->nrpotwbajtu[2] = adres_obecny->bufor[10];
            	pomoc->nrpotwbajtu[3] = adres_obecny->bufor[11];
            	pomoc->dlnaglowka[0] = adres_obecny->bufor[12];
            	pomoc->dlnaglowka[1] = adres_obecny->bufor[13];
            	pomoc->rozmiarokna[0] = adres_obecny->bufor[14];
            	pomoc->rozmiarokna[0] = adres_obecny->bufor[15];
            	pomoc->sumakontrolna[0] = adres_obecny->bufor[16];
            	pomoc->sumakontrolna[1] = adres_obecny->bufor[17];
            	pomoc->wskpilnych[0] = adres_obecny->bufor[18];
            	pomoc->wskpilnych[1] = adres_obecny->bufor[19];
            	for(int b=20;b<iDataLen;b++)
            	{
            		dane->bufor[d]=adres_obecny->bufor[b];
            		d=d+1;
            	}
    		printf("Numer ramki w buforze: %d \n", licznik=licznik + 1);
    					printf("Rozmiar licznika: %li \n", sizeof(licznik));
    					printf("Rozmiar struktury naglowka:%d \n", sizeof(struct lista));
    					printf("Port zrodlowy: %02x %02x\n", pomoc->portZrodlowy[0],pomoc->portZrodlowy[1]);
    					printf("Port docelowy: %02x %02x\n", pomoc->portDocelowy[0],pomoc->portDocelowy[1]);
    					printf("Nr sekwencyjny: %02x %02x %02x %02x\n", pomoc->nrsekwencyjny[0], pomoc->nrsekwencyjny[1],pomoc->nrsekwencyjny[2],pomoc->nrsekwencyjny[3]);
    					printf("Nr potwierdzenia bajtu: %02x %02x %02x %02x\n", pomoc->nrpotwbajtu[0], pomoc->nrpotwbajtu[1],pomoc->nrpotwbajtu[2],pomoc->nrpotwbajtu[3]);
    					printf("Dl naglowka: %02x %02x\n", pomoc->dlnaglowka[0],pomoc->dlnaglowka[1]);
    					printf("Rozmiar okna: %02x %02x\n", pomoc->rozmiarokna[0],pomoc->rozmiarokna[1]);
    					printf("Suma kontrolna: %02x %02x\n", pomoc->sumakontrolna[0],pomoc->sumakontrolna[1]);
    					printf("Wsk pilnych: %02x %02x\n", pomoc->wskpilnych[0],pomoc->wskpilnych[1]);
    					printf("Dane: ");
    					for(int a=20;a<iDataLen;a++)
    					{
    						printf("%02x ",dane->bufor[a]);
    					}
    					printf("\n\n");

    	}






}

void usuwanie()

{
	

	if (licznik == 1) {
		adres_zakotwiczenia = NULL;

		free(pomoc);
		free(adres_obecny);

	}
	else //ostatni wezel
	{
		adres_obecny = adres_zakotwiczenia;
		while (adres_obecny->nastepny->nastepny != NULL) {
			adres_obecny = adres_obecny->nastepny;
		}
		adres_ostatni= adres_obecny->nastepny;
		adres_obecny->nastepny = NULL;
		free(adres_ostatni);



	};
	printf("usuwanie wykonane");
	licznik--;
}
void typ(unsigned char* buffer,int iDataLen)
{
	if ((*(buffer + 12) == 0x08) && (*(buffer + 13) == 0x00) && (*(buffer + 23) == 0x08))
	{
		printf("Odebrano pakiet EGP o rozmiarze [B] %d \n",iDataLen);
	}
	else if ((*(buffer + 12) == 0x08) && (*(buffer + 13) == 0x00) && (*(buffer + 23) == 0x02))
		{
			printf("Odebrano pakiet IGMP  o rozmiarze [B] %d \n",iDataLen);
		}
	else if ((*(buffer + 12) == 0x08) && (*(buffer + 13) == 0x00) && (*(buffer + 23) == 0x01))
		{
			printf("Odebrano pakiet ICMP o rozmiarze [B] %d \n",iDataLen);
		}
	else
			{
				printf("Odebrano inny pakiet o rozmiarze [B] %d \n", iDataLen);
			}

}
int main(void)
{
	int i = 1;
	printf("Uruchamiam odbieranie ramek Ethernet.\n"); /* prints */
	//Utworzenie bufora dla odbieranych ramek Ethernet

	unsigned char* buffer = (void*) malloc(ETH_FRAME_LEN);
	//Otwarcie gniazda pozwalającego na odbiór wszystkich ramek Ethernet
	int iEthSockHandl = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
	//Kontrola czy gniazdo zostało otwarte poprawnie, w przypadku bledu wyświetlenie komunikatu.
		if (iEthSockHandl<0)
		printf("Problem z otwarciem gniazda : %s!\n", strerror(errno));
		//Zmienna do przechowywania rozmiaru odebranych danych
		int iDataLen = 0;
		//Pętla nieskończona do odbierania ramek Ethernet
			while (1) {
			//Odebranie ramki z utworzonego wcześniej gniazda i zapisanie jej do bufora
			iDataLen = recvfrom(iEthSockHandl, buffer, ETH_FRAME_LEN, 0, NULL, NULL);
			//Kontrola czy nie było bledu podczas odbierania ramki
				if (iDataLen == -1)
				printf("Nie moge odebrac ramki: %s! \n", strerror(errno));
				else { //jeśli ramka odebrana poprawnie wyświetlenie jej zawartości
					typ(buffer,iDataLen);
					if ((*(buffer + 12) == 0x08) && (*(buffer + 13) == 0x00) && (*(buffer + 23) == 0x06))
					{
						printf("Odebrano pakiet TCP o rozmiarze %d [B]: \n",iDataLen);
						i = i + 1;
							if (i <= 20)
							{
								TCP(buffer + 34,iDataLen);
							}
							/*else if (i > 20 && i <= 21)
							{
								printf("\n\n BUFOR TCP PEŁNY, OTO JEGO ZAWARTOŚĆ: \n\n");
								wyswietl(iDataLen);*/
							//}
							else
							{
								wyswietl(iDataLen);
								while (licznik > 1)
								{
								usuwanie();
								}
							i = 1;
							}

					}

			}
	}
return EXIT_SUCCESS;
}


Za drugim przejsciem pętli zapisuje mi 3 pakiety po czym sie zawiesza. Dodam ze jak w debuggerze przeleciałem cały program to zapisało mi po raz drugi 20 pozycji do listy, tylko nie usuwało mi w ogóle pól. Moze ktoś poratowac ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1