Laboratorium programowania zad 4

Zadanie 4 z laboratorium programowania na Informatyce UW.

Zadanie 4 (termin wysylania rozwiazan: 8 II 2008, godz. 23:59)

(Samotnik)

Gra logiczna o nazwie Samotnik jest rozgrywana przez jedna osobe
na planszy, ktorej czesc pol zajmuja pionki.

Pojedynczy ruch polega na przeskoczeniu pionkiem pionka znajdujacego
sie na jednym z czterech sasiednich pol, zdjeciu przeskoczonego pionka
z planszy i umieszczeniu pionka, ktory przeskoczyl, bezposrednio
za polem przeskoczonym (wczesniej musi byc ono puste).

Np. ze stanu (kropka oznacza puste pole, gwiazdka to pionek):

**.

przejdziemy do:

..*

ze stanu:

.**

przejdziemy do:

*..

ze stanu:

.
*
*

przejdziemy do:

*
.
.


ze stanu:

*
*
.

przejdziemy do:

.
.
*

Napisz program, ktory dla zadanego stanu planszy S i wartosci n
wypisze wszystkie stany, z ktorych po n ruchach dojdziemy do
stanu S.

Postac danych:

Program jest wywolywany z jednym argumentem bedacym nieujemna
liczba calkowita, a ze standardowego wejscia wczytuje stan
planszy. Reprezentacja stanu sklada sie z siedmiu wierszy, kazdy
po siedem znakow. Znak kropki '.' reprezentuje puste pole
planszy, znak gwiazdki '*' reprezentuje pionka a znak spacji
reprezentuje miejsce poza plansza - tam pionek nigdy znalezc sie
nie moze.

Np. ciag znakow:

  ***  
  ***  
*******
***.***
*******
  ***  
  ***  

jest zapisem stanu poczatkowego Samotnika w jego klasycznej wersji.

Postac wyniku:

Program wypisuje na wyjscie wszystkie stany planszy, z ktorych
po n ruchach mozna osiagnac stan zadany na wejsciu. Kazdy stan
wypisujemy w takim formacie, w jakim byly dane na wejsciu (siedem
wierszy po siedem znakow). Dodatkowo, po kazdym stanie planszy
wypisujemy jeden pusty wiersz.

Np. dla danych postaci:

  ...  
  ...  
.......
...*...
.......
  ...  
  ...  

program wywolany poleceniem:

./rozwiazanie 1 < dane

powinien wypisac:

  ...  
  ...  
.......
.......
...*...
  .*.  
  ...  
    
  ...  
  .*.  
...*...
.......
.......
  ...  
  ...  
                
  ...  
  ...  
.......
....**.
.......
  ...  
  ...  
                        
  ...  
  ...  
.......
.**....
.......
  ...  
  ...  


Dla tych samych danych, program wywolany z argumentem 3 powinien
wypisac, miedzy innymi, stan:

  ...  
  ...  
...*...
.**....
.......
  .*.  
  ...  

Pelny wynik programu wywolanego z argumentem 3 jest zalacznikiem do
tresci zadania.

(Uwaga: Kolejnosc stanow wypisywanych na wyjscie nie musi byc taka,
jak w tym przykladzie, ale gdyby udalo sie Panstwu ja zachowac,
ulatwiloby mi to sprawdzanie rozwiazan.)

Mozna zalozyc, ze dane na wejsciu programu, oraz argument wywolania,
beda poprawne.

Wskazowka 1:

Zacznij od rozwiazania problemu cofniecia stanu planszy o jeden,
czyli do stanu bezposrednio poprzedzajacego zadany. Nastepnie
zastanow sie, jak zastosowac rekurencje do rozwiazania problemu
w wersji pelnej.

Wskazowka 2:

Liczbe argumentow, z ktorymi wywolano program, mozemy poznac wywolujac
funkcje ParamCount. Funcja ParamStr(i) zwroci nam i-ty argument
wywolania programu w postaci wartosci typu string.

Wartosc liczbowa reprezentowana przez wartosc typu string mozemy
obliczyc samodzielnie, lub skorzystac z procedury Val. Wywolanie
Val(s,x,w) umiesci na zmiennej x typu integer wartosc liczby, ktorej
ciag cyfr znajduje sie na zmiennej s typu string. Gdyby postac s
byla bledna, na zmiennej w typu word znajdzie sie kod bledu.

A oto rozwiązanie:

program zad3;
//Program napisany na zajęcia z Laboratorium Języka Pascal i C. Zadania nr 4.

type
//plansza
plan=array [1..7,1..7] of char;

var start:plan;
argumentow,iteracji,i,j,blad:integer;
parametr,wiersz:string;


procedure wypisz(plansza:plan);
//Jak nietrudno sie domyslic, procedura wypisuje plansze
var i,j:integer;
begin
		for i:=1 to 7 do
		begin
			for j:=1 to 7 do
			begin
				write(plansza[i,j]);
			end;
			writeln();
		end;
		writeln();
end;



procedure ruch(plansza:plan;iteracja:integer);
//Rekurencyjna procedura. Wykonuje ruchy az iteracja spadnie do 0
var i,j:integer;
plansza2:plan;
begin

	//Doszlismy do odpowiedniej liczby ruchow
	if (iteracja=0) then
	begin
		wypisz(plansza);
	end
	else
	begin
		iteracja:=iteracja-1;
		//Idziemy po planszy. Dla kazdego pionka zaklada ze znalazl sie tam w wyniku ruchu
		for i:=1 to 7 do
		begin
			for j:=1 to 7 do
			begin
				//Mamy pionek
				if (plansza[i,j]='*') then
				begin
				
					//No i teraz zakladamy ze pionek znalazl sie tam w wyniku:
				
					//skok z dolu
					if ((i2) AND (plansza[i-1,j]='.') AND (plansza[i-2,j]='.')) then
					begin
						plansza2:=plansza;
						plansza2[i,j]:='.';
						plansza2[i-1,j]:='*';
						plansza2[i-2,j]:='*';
						ruch(plansza2,iteracja);
					end;
					
					//skok z prawej
					if ((j2) AND (plansza[i,j-1]='.') AND (plansza[i,j-2]='.')) then
					begin
						plansza2:=plansza;
						plansza2[i,j]:='.';
						plansza2[i,j-1]:='*';
						plansza2[i,j-2]:='*';
						ruch(plansza2,iteracja);
					end;					

				end
			end
		end
	end
	
end;







begin

	//Przechwutujemy liczbe argumentow
	argumentow:=ParamCount();

	if (argumentow=1) then
	begin
		//Czytamy parametr
		parametr:=ParamStr(1);
		Val(parametr,iteracji,blad);

		//Wczytujemy wejscie
		for i:=1 to 7 do
		begin
			readln(wiersz);
			for j:=1 to 7 do
			begin
				start[i,j]:=wiersz[j];
			end
		end;
		
		//wczytane.
		//Wywyolujemy
		ruch(start,iteracji);
	end
end.

Laboratorium programowania zad 3

Zadanie 3 z laboratorium programowania na Informatyce UW.

Zadanie 3 (termin wysylania rozwiazan: 1 II 2008, godz. 23:59)

(wyrazenia logiczne w ONP)

Dana jest gramatyka bezkontekstowa wyrazen logicznych w Odwrotnej
Notacji Polskiej (obok kazdej produkcji podano jej znaczenie):

E -> 0        falsz
E -> 1        prawda
E -> E E &    koniunkcja
E -> E E |    alternatywa
E -> E E =    rownowaznosc
E -> E E >    implikacja (pierwsze E implikuje drugie)
E -> E !      negacja

Napisz program, ktory wczyta z wejscia wyrazenie opisane powyzsza
gramatyka i wypisze na wyjscie 1 lub 0 w zaleznosci od tego, czy
wartoscia wyrazenia jest prawda czy falsz.

Dla danych niepoprawnych program powinien wypisac slowo BLAD.

Postac danych:

Na wejsciu znajdzie sie jeden wiersz tekstu zbudowanego ze znakow 0, 1,
&, |, =, >, ! i zakonczonego kropka. Pomiedzy kolejnymi znakami wyrazenia
nie bedzie spacji.

Postac wyniku:

Program wypisuje na wyjscie jeden wiersz z liczba 0 lub 1 albo ze
slowem BLAD.

Np. dla danych:

01>1!0|>110&&!=.

reprezentujacych wyrazenie logiczne:

((false => true) => ((not true) or false))  not (true and (true  and false))

program powinien wypisac:

0

A oto rozwiązanie:

program zad3;
//Program napisany na zajęcia z Laboratorium Języka Pascal i C. Zadania nr 3.
var i,ile:integer;
wynik,blad:boolean;
zdanie:string;



function wczytaj:boolean;
//Funkcja wczytuje operator lub wartosc i decyduje co robic dalej.
var znak:char;
wynik,wynik1,wynik2:boolean;
begin
wynik:=false;

	if (blad=false) then
	begin
		//Jesli nie bylo bledu
		znak:=zdanie[i];
		i+=-1;

		//male zabezpieczenie jesli wykroczylismy poza zakres
		if i') then
			begin //Liczymy implikacje

			wynik1:=wczytaj();
			wynik2:=wczytaj();
			wynik:=NOT (wynik2 AND NOT wynik1);

			end
		else if (znak='!') then
			begin //Liczymy zaprzeczenie

			wynik1:=wczytaj();
			wynik:=NOT wynik1;

			end
		else //Podano znak spoza zakresu
			blad:=true;


	end;
wczytaj:=wynik;
end;





begin

	blad:=false;
	//Wczytujemy zdanie:
	readln(zdanie);
	ile:=length(zdanie);
	i:=ile;
	//Jesli zdanie ma jak powinno kropke na koncu:
	if (zdanie[ile]='.') then
		begin
			i+=-1;
			wynik:=wczytaj;
		end
	else //No jesli nie ma to blad
		blad:=true;


	//Teraz wypiszemy wynik

	//Jesli wystapil blad:
	if blad then
		writeln('BLAD')
	else
		if wynik then
			writeln('1')
		else
			writeln('0');


end.

Laboratorium programowania zad 2

Zadanie 2 z laboratorium programowania na Informatyce UW.

Zadanie 2 (termin wysylania rozwiazan: 25 I 2008, godz. 23:59)

(Liczby Fibonacciego)

Ciag liczb Fibonacciego jest okreslony nastepujaco:

* pierwsza liczba Fibonacciego jest 0
* druga liczba Fibonacciego jest 1
* liczba Fibonacciego o numerze N (wiekszym niz 2) jest suma liczb
  Fibonacciego o numerach N-1 i N-2

Oto kilkanascie poczatkowych wyrazow ciagu liczb Fibonacciego:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, ...

Napisz program, ktory wczyta z wejscia liczbe calkowita N i wypisze
na wyjscie, w kolejnych wierszach, N poczatkowych wyrazow ciagu liczb
Fibonacciego.

Program powinien wypisac liczby w zapisie pozycyjnym o podstawie 26
poslugujac sie malymi literami alfabetu lacinskiego jako cyframi.
Litera 'a' ma wiec reprezentowac cyfre 0, 'z' to 25. Cyfry nalezy
wypisywac w kolejnosci od najbardziej znaczacych.

Program nie moze zakladac, ze wartosc N bedzie na tyle mala, by liczby
Fibonacciego zmiescily sie w zakresie typow integer, longint itp.
Wolno jedynie zalozyc, ze liczby Fibonacciego, ktore program ma obliczyc,
nie beda mialy wiecej, niz 100 cyfr (w zapisie o podstawie 26).

Np. dla danej:

30

program powinien wypisac:

a
b
c
d
f
i
n
v
bi
cd
dl
fo
iz
on
xm
blz
cjl
dvk
gev
kaf
qfa
baff
bqkf
cqpk
egzp
gxoz
leoo
scdn
bdgsb
bvivo

Wskazowka:

W rozwiazaniu liczby nalezy reprezentowac jako ciagi cyfr w ukladzie
o podstawie 26, zapisane w tablicy.

A oto rozwiązanie:

program zad2;
//Program napisany na zajęcia z Laboratorium Języka Pascal i C. Zadania nr 2.
type tablica=array [1..100] of char;
var n,i:integer;
//Tablice z liczbami
a,b,c : tablica;




procedure dodaj;
//Dodaje tablice a i b, w wsyniku dajac c. Operacja w ukladzie 26
var i,tmp_a,tmp_b,wynik,przeniesienie:integer;
begin
	przeniesienie:=0;
	//Liczby przedstawiamy od prawej strony tablicy.
	for i:=100 downto 1 do
	begin
		wynik:=0;
		tmp_a:=ord(a[i])-97;
		tmp_b:=ord(b[i])-97;
		wynik:=przeniesienie+tmp_a+tmp_b;
		c[i]:=char((wynik mod 26)+97);
		przeniesienie:=wynik div 26;
	end;
	
	//tutaj dodawanie powinno sie zakonczyc.
end;

procedure wypisz(t:tablica);
//Wypisuje tablice
var i:integer;
znak:char;
begin
	
	i:=2;
	znak:=t[1];
	//Pomijamy poczatkowe 0 - czyli a.
	
	while (znak='a') AND (i<101) do
	begin
		znak:=t[i];
		i+=1;
	end;
		
	i:=i-1;

	while i0 then
		writeln('a');

	if n>1 then
		writeln('b');
	
	for i:=3 to n do
	begin
		dodaj;
		wypisz(c);
		a:=b;
		b:=c;
	end;

end.

Lab Pascal zadanie 1

Zadanie 1 z laboratorium programowania na Informatyce UW.

 Zadanie 1 (termin wysylania rozwiazan: 18 I 2008, godz. 23:59)

(Lamiglowka "Pietnascie")

Dana jest plansza o rozmiarach cztery na cztery, na ktorej znajduje sie
pietnascie "klockow" oznaczonych duzymi literami. W pierwszym wierszu
planszy sa cztery klocki: "A", "B", "C" i "D", w drugim "E", "F", "G" i
"H", w trzecim "I", "J", "K", "L", w czwartym "M", "N", "O". Pole
w czwartym wierszu i czwartej kolumnie jest puste.

Klocek mozna przesunac na sasiadujace z nim wolne pole, zwalniajac tym
samym pole, na ktorym klocek znajdowal sie do tej pory.

W kazdej chwili na planszy jest co najwyzej jeden klocek, ktory mozna
przesunac w dol (ten, ktory znajduje sie nad pustym polem), co najwyzej
jeden, ktory mozna przesunac w prawo itd.

Napisz program, ktory umozliwi przesuwanie klockow na planszy i bedzie
wypisywal na wyjscie wynik.

Program wczyta z wejscia ciag liter ze zbioru {'l', 'p', 'g', 'd'}
zakonczony znakiem, ktory do tego zbioru nie nalezy. Kazda litera
jest poleceniem przesuniecia klocka na planszy:

'l' - w lewo
'p' - w prawo
'g' - w gore
'd' - w dol

Program wypisze na wyjscie stan poczatkowy planszy, a nastepnie dla kazdej
litery z wejscia bedzie probowal wykonac reprezentowane przez nia
przesuniecie klocka. Jesli przesuniecie nie bedzie mozliwe, bo np. puste
pole jest w ostatnim wierszu planszy, a wczytana litera to 'g', stan planszy
sie nie zmieni. Dla kazdej litery wczytanej z wejscia, niezaleznie od tego,
czy spowodowala ona przesuniecie klocka, wypisujemy wynikowy stan planszy.

Stan planszy wypisujemy w pieciu wierszach. W czterech pierwszych podajemy
znaki z klockow znajdujacych w kolejnych wierszach planszy, oznaczajac
spacja miejsce puste; piaty wiersz ma byc pusty.

Np. dla danych, znajdujacych sie w dolaczonym do tresci tego zadania pliku
zsi07z01.dane, program powinien wypisac to, co jest w pliku zsi07z01.wynik.

I oto rozwiązanie:

Sieci komputerowe zadanie

Zadanie zaliczeniowe z Sieci Komputerowych

Oto treść:

Zadanie zaliczeniowe z Laboratorium z Sieci Komputerowych 2007

Należy napisać program filtrujacy strumień pakietów wywoływany z pięcioma argumentami:
- nazwš wej?ciowego pliku zawierajšcego pakiety (zrzut tcpdump),
- nazwš pliku wyj?ciowego, do którego należy zapisać wszystkie przepuszczone pakiety,
- nazwš pliku wyj?ciowego z informacjami na temat przepuszczanych i odrzuconych pakietów,
- nazwš pliku z "czarnš" listš adresów ip,
- nazwš pliku z "białš" listš adresów ip i portów TCP,
    nazwa_programu plik_in plik_out plik_admin plik_bad plik_good

Plik plik_bad ma następujšcy format. W kolejnych linijkach umieszczone sš:
    adres_ip niepusty_cišg_białych_znaków kierunek
gdzie kierunek jest jednym ze słów SRC lub DEST okre?lajšcymi czy chodzi o ?ródłowy czy docelowy adres ip.

Plik plik_good ma następujšcy format. W kolejnych linijkach umieszczone sš:
    adres_ip niepusty_cišg_białych_znaków kierunek niepusty_cišg_białych_znaków port_begin,port_end
gdzie:
    - kierunek jest jednym ze słów SRC lub DEST okre?lajšcymi czy chodzi o ?ródłowy czy docelowy adres ip,
    - port_begin,port_end oznaczajš zakres portów (okre?lony tylko dla protokołów TCP i UDP)
    ?ródłowych lub docelowych (w zależno?ci od parametru kierunek).

Każdy pakiet należy poddać analizie. Pakiet odrzucamy jeżeli spełniony jest przynajmniej jeden z warunków:
1) ?ródłowy lub docelowy adres ip znajduje się w plik_bad i zgadza się kierunek przesyłu danych,
2) pakiet jest wysyłany za pomocš protokołu TCP lub UDP i jego ?ródłowy lub docelowy adres ip
    znajduje się w plik_good, ale numer portu nie należy do podanego zakresu,
3) pakiet jest wysyłany za pomocš protokołu TCP, ale nie dane w nim zawarte nie pasujš do następujšcego formatu:
    pierwszym znakiem jest cyfra od 1 do 9 mówišca ile razy powinny być w danym pakiecie powtórzone dane,
    na przykład:
        2_tresc_tresc
        3_tresc_tresc_tresc
        7_tresc_tresc_tresc_tresc_tresc_tresc_tresc
W przypadku odrzucenia pakietu należy wpisać nowš linię do plik_admin w następujšcym formacie:
    ip_nadawcy ip_odbiorcy nazwa_protokołu komunikat
przy czym komunikat jest jednym spo?ród:
    - BAD SRC/DEST IP
        w przypadku niespełnienia warunku 1,
    - BAD SRC/DEST PORT
        w przypadku niespełnienia warunku 2,
    - BAD PACKET FORMAT, MISSING NUMBER
      BAD PACKET FORMAT, NOT MATCHING DATA
        w przypadku niespełnienia warunku 3 z powodu odpowiednio braku cyfry na poczštku lub braku pasujšcych danych.

Pozostałe pakiety należy przepu?cić wpisujšc do plik_out oraz wpisać nowš linię do plik_admin w następujšcym formacie:
    ip_nadawcy ip_odbiorcy nazwa_protokołu PACKET OK

Program należy przesłać na adres mailowy prowadzšcego grupę ćwiczeniowš:
    piotr.sawicki@mimuw.edu.pl
    michal.bernardelli@mimuw.edu.pl
do 2 grudnia 2007 roku do godziny 23:59.
Ocena rozwišzań wysłanych po tym terminie (wliczajšc w to sesję poprawkowš) będzie obniżona o jeden stopień.
Program powinien być skompresowany wraz z zaprojektowanym przez siebie kompletem testów.
Nazwa spakowanego pliku powinna być taka sama jak wydziałowy login.
Program ma się kompilować i działać na komputerach w laboratorium komputerowym MIM.
Za brak lub niewystarczajšcš liczbę komentarzy w kodzie ?ródłowym programu będzie obniżana ocena.
Na ostatnich ćwiczeniach należy przyj?ć i zaprezentować działanie swojego programu.

A oto rozwiazanie:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 



/* default snap length (maximum bytes per packet to capture) */
#define SNAP_LEN 1518

/* ethernet headers are always exactly 14 bytes [1] */
#define SIZE_ETHERNET 14

/* Ethernet addresses are 6 bytes */
#define ETHER_ADDR_LEN	6

pcap_dumper_t *plik;

/* 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 {
        u_char  ip_vhl;                 /* version <> 2 */
        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;                   /* protocol */
        u_short ip_sum;                 /* checksum */
        struct  in_addr ip_src,ip_dst;  /* source and dest address */
};

#define IP_HL(ip)               (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip)                (((ip)->ip_vhl) >> 4)

/* TCP header */
typedef u_int tcp_seq;

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 */
        u_char  th_offx2;               /* data offset, rsvd */
	#define TH_OFF(th)      (((th)->th_offx2 & 0xf0) >> 4)
        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 */
};

struct sniff_udp {
        u_short uh_sport;               /* source port */
        u_short uh_dport;               /* destination port */
        u_short uh_length;				/*length header+data*/
        u_short uh_checksum;            /* chechsum */
      
};

//Struktura listy white i black

typedef struct Adresy {
	char Adres[15];
	char kierunek[4];
	int port_start;
	int port_stop;
	struct Adresy * nastepny;
};

//plik admin
FILE *admin;
struct Adresy *biala;
struct Adresy *czarna;

//funkcje operujace na listach black i white.

struct Adresy * wczytaj_adresy(char* plik,int porty)
{//wczytuje adresy z pliku i zwraca wskaznik do listy.
	FILE *f;
	struct Adresy *start;
	struct Adresy *teraz;
	int wynik;
	char ciag[128];
	char * tmp;
	char znak;

	f=fopen(plik,"r");
	wynik=fscanf(f,"%15s",ciag);



	if(wynik!=EOF)
	{
		start=malloc(sizeof(struct Adresy));
		start->nastepny=NULL;
		start->port_start=0;
		start->port_stop=0;

		strcpy(start->Adres,ciag);

		//powinno wczytac spacje:
		wynik=fscanf(f,"(space)");

		//powinno wczytac src lub dest
		wynik=fscanf(f,"%4s",ciag);

		
		if(strcmp(ciag,"SRC")||strcmp(ciag,"DEST"))
		{
			strcpy(start->kierunek,ciag);
		}
		
		//jesli mamy tez czytac numery portow.
		if (porty==1)
		{
			wynik=fscanf(f,"(space)");
			//przeczytalismy puste znaki
			wynik=fscanf(f,"%s,",ciag);
			//wczytalismy porty. Rozbijemy je.
			tmp = strtok (ciag,",");
			start->port_start=atoi(tmp);
			tmp = strtok (NULL, ",");
			start->port_stop=atoi(tmp);
		}

		while(znak!='n')
		{
			//czytamy wszystko do konca linii.
			wynik=fscanf(f,"%c",&znak);
		}

		teraz=start;
		wynik=fscanf(f,"%s",ciag);

		while(wynik!=EOF)
		{
			teraz->nastepny=malloc(sizeof(struct Adresy));
			teraz=teraz->nastepny;
			teraz->nastepny=NULL;
			teraz->port_start=0;
			teraz->port_stop=0;
			strcpy(teraz->Adres,ciag);

			//powinno wczytac spacje:
			wynik=fscanf(f,"(space)");

			//powinno wczytac src lub dest
			wynik=fscanf(f,"%s",ciag);

			if((strcmp(ciag,"SRC"))||(strcmp(ciag,"DEST")))
			{
				strcpy(teraz->kierunek,ciag);
			}
			
			//jesli mamy tez czytac numery portow.
			//jesli mamy tez czytac numery portow.
			if (porty==1)
			{
				wynik=fscanf(f,"(space)");
				//przeczytalismy puste znaki
				wynik=fscanf(f,"%s,",ciag);
				//wczytalismy porty. Rozbijemy je.
				tmp = strtok (ciag,",");
				teraz->port_start=atoi(tmp);
				tmp = strtok (NULL, ",");
				teraz->port_stop=atoi(tmp);
			}

			while(znak!='n')
			{
				//czytamy wszystko do konca linii.
				wynik=fscanf(f,"%c",&znak);
			}

			wynik=fscanf(f,"%s",ciag);
		}

		return start;
	}
	else
	{
		return NULL;
		//blad. plik pusty albo co.
	}
	fclose(f);
}


int lista(struct Adresy * lista,char* source,char* destination, int port_zrodlo,int port_docelowy)
{
	//zwraca 1 jesli zrodlowy lub docelowy ip sa na liscie.
	//+1 jesli kierunek sie zgadza
	//+2 jesli port sie zgadza.
	//0 jesli adresu nie ma.
	int zwroc,naj_zwroc;
	struct Adresy *teraz;
	teraz=lista;
	zwroc=0;
	naj_zwroc=0;

	//szukamy
	while ((teraz!=NULL)&&(zwrocAdres,source)==0)||(strcmp(teraz->Adres,destination)==0))
		{
			if(zwroc==0)
			{
				//ip jest na liscie
				zwroc=1;
				
			}

			if((zwroc==1)&&(((strcmp(teraz->Adres,source)==0)&&(strcmp(teraz->kierunek,"SRC")==0))||((strcmp(teraz->Adres,destination)==0)&&(strcmp(teraz->kierunek,"DEST")==0))))
			{
				//odkrylismy wlasnie wpis w ktorym kierunek sie zgadza.
				zwroc=zwroc+1;
			}

			if(((port_zrodlo!=0)||(port_docelowy!=0))&&((zwroc==1)||(zwroc==2))&&(((strcmp(teraz->kierunek,"DEST")==0)&&(port_docelowy>=teraz->port_start)&&(port_docelowyport_stop))||((strcmp(teraz->kierunek,"SRC")==0)&&(port_zrodlo>=teraz->port_start)&&(port_zrodloport_stop))))
			{
				//Odkrylismy wlasnie ze i port sie zgadza.
				zwroc=zwroc+2;
			}

		}
		
		if(zwroc>naj_zwroc)
		{
			naj_zwroc=zwroc;
		}
		
		teraz=teraz->nastepny;
	}

	return naj_zwroc;
}

int posprzataj(struct Adresy * lista)
{
	struct Adresy* tmp;
	
	while(lista!=NULL)
	{
		tmp=lista;
		lista=lista->nastepny;
		free(tmp);
	}
	
	return 0;
}

//zapisuje do pliku admin.
int zapisz(char *source,char *destination,char *prot,char *komunikat)
{
	fprintf(admin,"%s %s %s %sn",source,destination,prot,komunikat);
}

//Funkcje zwiazane z wlasciwa analiza.


void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);



int check_payload(const u_char *payload, int len)
{
	int dlugosc,i,j;

	if((payload[0]'9'))
	{
		//liczba ma byc z przedzialu 0-9
		return 1;
	}
	else
	{
		dlugosc=(len-1)/(payload[0]-48);
		j=1;
		for(i=dlugosc+1;idlugosc)
			{
				j=1;
			}
		}
	}
	
	return 0;
}



/*
 * dissect/print packet
 */

void
got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
	/* declare pointers to packet headers */
	const struct sniff_ethernet *ethernet;  /* The ethernet header [1] */
	const struct sniff_ip *ip;              /* The IP header */
	const struct sniff_tcp *tcp;            /* The TCP header */
	//const struct sniff_udp *udp;			/* The UDP header */
	const char *payload;                    /* Packet payload */
	char *source,*destination;
	char prot[10];						//nazwa protokolu

	int size_ip;
	int size_tcp;
	int size_payload;
	int wynik_biala,wynik_czarna,port_zrodlowy,port_docelowy,wynik_payload;
	
	/* define ethernet header */
	ethernet = (struct sniff_ethernet*)(packet);
	/* define/compute ip header offset */
	ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
	size_ip = IP_HL(ip)*4;
	if (size_ip ip_p) {
		case IPPROTO_TCP:
			strncpy(prot,"TCP",4);
			break;
		case IPPROTO_UDP:
			strncpy(prot,"UDP",4);
			break;
		case IPPROTO_ICMP:
			strncpy(prot,"ICMP",5);
			break;
		case IPPROTO_IP:
			strncpy(prot,"IP",3);
			break;
		default:
			strncpy(prot,"OTHER",6);
			break;
	}


	//Rozpoznajemy adresy zrodlowy i docelowy
	destination=inet_ntoa(ip->ip_src);
	source=(char*)malloc(sizeof(char)*strlen(destination));
	strncpy(source,destination,strlen(destination));
	source[strlen(destination)]='';
	destination=inet_ntoa(ip->ip_dst);
	
	//testujemy.
	wynik_czarna=lista(czarna,source,destination,0,0);
	
	if(wynik_czarna>1)
	{
		//odrzucamy z powodu warunku 1 - jest w pliku_bad
		zapisz(source,destination,prot,"BAD SRC/DEST IP");
	}
	else
	{
		if (ip->ip_p==IPPROTO_TCP || ip->ip_p==IPPROTO_UDP) //tcp lub udp
		{
			tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
			port_zrodlowy=ntohs(tcp->th_sport);
			port_docelowy=ntohs(tcp->th_dport);
			//testujemy.
			wynik_biala=lista(biala,source,destination,port_zrodlowy,port_docelowy);
			
			if((wynik_biala==1)||(wynik_biala==2)) //jest na liscie, ale nie zgadza sie port. (jesli by sie zgadzal byloby 3 albo 4)
			{
				//odrzucamy z powodu niespelnienia warunku 2.
				zapisz(source,destination,prot,"BAD SRC/DEST PORT");
			}
			else
			{
				//ok. przeszlismy pierwsze dwa testy. teraz czy format pliku sie zgadza.
				wynik_payload=0;
				
				if (ip->ip_p==IPPROTO_TCP)
				{
					size_tcp = TH_OFF(tcp)*4;
					if (size_tcp ip_len) - (size_ip + size_tcp);
					
					if (size_payload > 0) 
					{
						wynik_payload=check_payload(payload,size_payload);
						//if(wynik_payload==2)
						//	printf("%snnnn---------n",payload);
						
					}
				}
				
				if(wynik_payload==1)
				{
					zapisz(source,destination,prot,"BAD PACKET FORMAT, MISSING NUMBER");
				}
				else if (wynik_payload==2)
				{
					zapisz(source,destination,prot,"BAD PACKET FORMAT, NOT MATCHING DATA");
				}
				else
				{
					//PAKIET OK!!
					pcap_dump(plik, header, packet);//przepuszaczamy
					zapisz(source,destination,prot,"PACKET OK");
				}
			}
		}
		
	}
	
	return;
}




/*main-----------------------------------------------------------------*/
/*main-----------------------------------------------------------------*/
/*main-----------------------------------------------------------------*/
int main(int argc, char **argv)
{
	//char *dev = NULL;			/* capture device name */
	char errbuf[PCAP_ERRBUF_SIZE];		/* error buffer */
	pcap_t *handle;				/* packet capture handle */

	if(argc==6)
	{

		//wczytujemy dane z odpowiednich list.
		czarna=wczytaj_adresy(argv[4],0);
		biala=wczytaj_adresy(argv[5],1);

	  	if (!(handle=pcap_open_offline(argv[1], errbuf)))
		 {
			perror(errbuf);
			exit(1);
		 }

	  	if (!(plik=pcap_dump_open(handle, argv[2])))
		 {
			printf("BLADn");
			exit(1);
		 }
		
		admin=fopen(argv[3],"w");

		if (pcap_dispatch(handle, -1/*num_packets*/, got_packet,(u_char *) admin));

		fclose(admin);
		pcap_dump_close(plik);
		pcap_close(handle);
		//sprzatamy pamiec:
		posprzataj(biala);
		posprzataj(czarna);
		
	}
	else
	{
		printf("Podaj 5 parametrow!!n");
		return 1;
	}
	return 0;
}