Witam. Mam problem z snifferem w języku C. Moj program ma za zadanie przechwytywać dane i wyłapywac pakiety TCP z sieci, wypisujac poszczegolne pola nagłówka. na razie udało mi sie ulepić coś takiego:
/* ============================================================================
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;
void TCP(unsigned char* recivedPocket)
{
struct lista* pomoc;
pomoc = (struct lista*) malloc(sizeof(struct lista));
pomoc->portZrodlowy[0] = *recivedPocket;
pomoc->portZrodlowy[1] = *(recivedPocket+1);
pomoc->portDocelowy[0] = *(recivedPocket + 2);
pomoc->portDocelowy[1] = *(recivedPocket + 3);
pomoc->nrsekwencyjny[0] = *(recivedPocket + 4);
pomoc->nrsekwencyjny[1] = *(recivedPocket + 5);
pomoc->nrsekwencyjny[2] = *(recivedPocket + 6);
pomoc->nrsekwencyjny[3] = *(recivedPocket + 7);
pomoc->nrpotwbajtu[0] = *(recivedPocket + 8);
pomoc->nrpotwbajtu[1] = *(recivedPocket + 9);
pomoc->nrpotwbajtu[2] = *(recivedPocket + 10);
pomoc->nrpotwbajtu[3] = *(recivedPocket + 11);
pomoc->dlnaglowka[0] = *(recivedPocket + 12);
pomoc->dlnaglowka[1] = *(recivedPocket + 13);
pomoc->rozmiarokna[0] = *(recivedPocket + 14);
pomoc->rozmiarokna[0] = *(recivedPocket + 15);
pomoc->sumakontrolna[0] = *(recivedPocket + 16);
pomoc->sumakontrolna[1] = *(recivedPocket + 17);
pomoc->wskpilnych[0] = *(recivedPocket + 18);
pomoc->wskpilnych[1] = *(recivedPocket + 19);
pomoc->opcje[0] = *(recivedPocket + 20);
pomoc->opcje[1] = *(recivedPocket + 21);
pomoc->opcje[2] = *(recivedPocket + 22);
pomoc->sumakontrolna2[0] = *(recivedPocket + 23);
pomoc->dane[0] = *(recivedPocket + 24);
pomoc->dane[1] = *(recivedPocket + 25);
pomoc->dane[2] = *(recivedPocket + 26);
pomoc->dane[3] = *(recivedPocket + 27);
pomoc->poprzedni = NULL;
pomoc->nastepny= NULL;
if (pierwszy == NULL) //lista pusta
{
pierwszy = pomoc;
}
else
{
struct lista* pomoc2;
pomoc2 = pierwszy;
while (pomoc2->nastepny != NULL)
{
pomoc2 = pomoc2->nastepny;
}
pomoc2->nastepny = pomoc;
}
}
void wyswietl(unsigned char* buffer) {
licznik = 0;
struct lista* pomoc;
pomoc = (struct lista*) malloc(sizeof(struct lista));
pomoc = pierwszy;
if (pomoc == NULL) {
printf("\nLista jest pusta\n");
} else {
while (pomoc != NULL) {
printf("Numer ramki w buforze: %d \n", licznik + 1);
printf("Rozmiar licznika: %li \n", sizeof(licznik));
printf("Postac heksadecymalna pakietu: %x \n", buffer);
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("Opcje: %02x %02x %02x\n", pomoc->opcje[0],pomoc->opcje[1],pomoc->opcje[2]);
printf("Suma kontrolna 2: %02x\n", pomoc->sumakontrolna2[0]);
printf("Dane: %02x %02x %02x %02x\n\n", pomoc->dane[0],pomoc->dane[1],pomoc->dane[2],pomoc->dane[3]);
licznik = licznik + 1;
pomoc = pomoc->nastepny;
}
printf("\n\n");
}
}
void usun()
{
struct lista* pomoc;
pomoc = (struct lista*) malloc(sizeof(struct lista));
if (licznik == 1) {
pierwszy = NULL;
free(pierwszy);
}
else //ostatni wezel
{
struct lista *koniec;
koniec = (struct lista*) malloc(sizeof(struct lista));
pomoc = pierwszy;
while (pomoc->nastepny->nastepny != NULL) {
pomoc = pomoc->nastepny;
}
koniec = pomoc->nastepny;
pomoc->nastepny = NULL;
free(koniec);
};
licznik--;
}
void typ(unsigned char* buffer,int iDataLen)
{
if ((*(buffer + 12) == 0x08) && (*(buffer + 13) == 0x00) && (*(buffer + 23) == 0x08))
{
printf("Odebrano pakiet EGP : %x o rozmiarze [B] %d \n",buffer,iDataLen);
}
else if ((*(buffer + 12) == 0x08) && (*(buffer + 13) == 0x00) && (*(buffer + 23) == 0x02))
{
printf("Odebrano pakiet IGMP: %x o rozmiarze [B] %d \n",buffer,iDataLen);
}
else if ((*(buffer + 12) == 0x08) && (*(buffer + 13) == 0x00) && (*(buffer + 23) == 0x01))
{
printf("Odebrano pakiet ICMP: %x o rozmiarze [B] %d \n",buffer,iDataLen);
}
else
{
printf("Odebrano inny pakiet: %x o rozmiarze [B] %d \n",buffer, iDataLen);
}
}
int main(void)
{
int i = 1;
printf("Uruchamiam odbieranie ramek Ethernet.\n"); /* prints */
//Utworzenie bufora dla odbieranych ramek Ethernet
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: %x o rozmiarze %d [B]: \n",buffer,iDataLen);
i = i + 1;
if (i <= 20)
{
TCP(buffer + 34);
}
else if (i > 20 && i <= 21)
{
printf("\n\n BUFOR TCP PEŁNY, OTO JEGO ZAWARTOŚĆ: \n\n");
wyswietl(buffer);
} else
{
while (licznik > 1)
{
usun();
}
i = 1;
}
}
}
}
return EXIT_SUCCESS;
}
Plik nagłówkowy:
/*
* tcph.h
*
* Created on: 28 maj 2018
* Author: kicaj
*/
#ifndef UDPHEADER_H_
#define UDPHEADER_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];
unsigned char opcje[3];
unsigned char sumakontrolna2[1];
unsigned char dane[4];
struct lista* poprzedni;
struct lista* nastepny;
struct lista* pierwszy;
};
#endif /* TCPH_H_ */
Zadanie polegało na tym aby poszczegolne pola naglowka byly przechowywane w strukturze w polu nagłówkowym. Dodatkowo nalezalo przygotowac strukture do utworzenia listy wiazanej, i w tej liscie zapisac 20 datagramow TCP, wyswietlic je, a nastepnie dalej pracować.
Sęk w tym że ja utworzyłem jedną strukture w pliku nagłówkowym, a mają być tam dwie struktury( jedna tylko do przechowywania danych a druga do utworzenia listy wiązanej). Próbowałem kombinować z dodatkowymi wskaźnikami w pliku C aby operować na dwóch strukturach jednak nie wychodzi.
Z góry dziękuję