Написал я тут программку, под Линух, она ловит eth-фреймы (которые все-таки иногда приходят :)))!), после чего через полденька понял, что ловятся они почему-то БЕЗ преамбулы :), но вот пошарив по полям, я был сильно озадачен...1) Кто бы мог мне дать список frame type'ов? (ip, вроде,=0800, а вот 0806? или, к примеру, 00e7?)
2) Почему поле TOTAL LENGTH IP датаграммы ну ОЧЕНь велико по сравнению с длиной eth-фрейма (237 и 192 соответственно), при этом FRAG.OFFSET=0, FLAGS=000(binary)???
ЗЫ: ааа, еще, программку писал на работе (сетка пока дома не проведена), и протоколов там... дохрена - слабо сказано, потому и интересует меня список frame type'ов...
Я только начинаю этом заниматься, если не жалко, кинь исходник.
Заранее спасибо.
смотри header-ы.
И почитай
TCP/IP Illustrated,
Volume 1
The Protocols
W. Richard Stevens
Ну нету у меня такой книжки, бум искать по инету...
Вообще-то, есть другая -
Internetworking with tcp/ip, vol1
by Douglas E.ComerВ общем, я маленько разобрался, просто программка была косо нарисована :).
Однако осталась пара проблем...1) Ну часть фрейм тайпов я нашел, которые к IP относятся, а остальные - ? Периодически приходят очень странные пакеты, с типом 0х0031, к примеру - чего это такое? Естессно, в нашей сетке есть разные протоколы, но это - отнюдь не единственный случай. А может, просто некие программы используют нестандартные протоколы? Или это результат того, что у нас поддерживается и юзается 100-Мбитка?
2) А почему, собственно, пакеты ARP'а бывают 2-х размеров? 46 и 28??? Причем оба вида - явно для TCP?
Кому там нада исходник было? Кидаю как есть:) не бейте ногами, мой линуксовый нафигатор не хотит от КДевелопа с клипбоарда брать текст :)
Кроме того, посоветуйте, плз, как брать ВЕСЬ доступный траффик, а не только мне или MAC=FFFFFF?
/***************************************************************************
main.cpp - description
-------------------
begin : Вск Июл 22 18:52:50 YEKST 2001
copyright : (C) 2001 by Cheshir* under GNU license rules
***************************************************************************/#ifdef HAVE_CONFIG_H
#include <config.h>
#endif#include <iostream.h>
#include <stdlib.h>#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if_ether.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <errno.h>
#include <stdio.h>#include <net/ethernet.h>
#define DEFAULT_UPDATE_DELAY 2000000
#define ETHER_HEADER_SIZE sizeof(ether_header)int open_raw_socket(){
int fd;
fd=socket(PF_INET,SOCK_PACKET,htons(ETH_P_ALL)); return fd;
}int readpacket(int fd, ether_header *hdr,unsigned char *buf, int len){
static int fromlen;
static fd_set set;
static struct timeval dt;
static int ss;
static unsigned char a,b,c;
static int i;
FD_ZERO(&set);FD_SET(0,&set);FD_SET(fd,&set);dt.tv_sec=0,dt.tv_usec=DEFAULT_UPDATE_DELAY;
do{
ss=select(fd 1,&set,0,0,&dt);
}while((ss<0) && (errno=EINTR));if(FD_ISSET(fd,&set)){
fromlen=recv(fd,buf,len,0);
hdr[0]=((ether_header*)buf)[0];
a=((char*)&hdr->ether_type)[0];
b=((char*)&hdr->ether_type)[1];
c=b;b=a;a=c;
((char*)&hdr->ether_type)[0]=a;
((char*)&hdr->ether_type)[1]=b;for(i=0;i<fromlen-ETHER_HEADER_SIZE;i )
buf[i]=buf[i ETHER_HEADER_SIZE];
return fromlen-ETHER_HEADER_SIZE;
}
return -1;
}const int buflen=65536;
int main(int argc, char** argv){
int sock;cout << "Testing" << endl;
sock=open_raw_socket();
cout <<"Sock N:"<<sock<<endl;
if(sock<0){
cout <<"Can't create socket."<<endl;
return EXIT_SUCCESS;
}
while(1){
static int len;
static int i,j;
static ether_header header;
static unsigned char buf[buflen];len=readpacket(sock,&header,buf,buflen);
if(len>=0){
cout <<"Packet len : "<<len<<endl;
cout <<"Destination: ";
for(i=0;i<6;i )printf(" x",header.ether_dhost[i]);cout <<endl;
cout <<"Source : ";
for(i=0;i<6;i )printf(" x",header.ether_shost[i]);cout <<endl;
cout <<"Frame Type : ";
if(header.ether_type==ETHERTYPE_IP)cout<<"IP";
else if(header.ether_type==ETHERTYPE_ARP)cout<<"ARP";
else if(header.ether_type==ETHERTYPE_REVARP)cout<<"RARP";
else printf("0x x",header.ether_type);cout <<endl;
cout <<"Frame : ";
i=0;
while(i<len){
for(j=0;(j<4 && i<len);j++,i++)printf(" x ",buf[i]);
cout <<endl;if(i<len)cout<<" ";
}
cout<<endl<<"Press a key..."<<endl;
getchar();
}
}
return EXIT_SUCCESS;
}
Народ, ну баловство это пока, конечно, но ну сильно охота мне это дело покурочить. Ответьте, плз, кто знает чего-нить по этому поводу...
А может, recvfrom вместо recv использовать? Тогда как?
И еще, а под другими осями никто не пробовал эту штуку запустить?
По поводу протоколов смотри rfc1700.
Spasiba i na etom...
Что бы весь траффик перехватить, тебе надо интерфейс перевести в неразборчивый режим, тогда он будет забирать на себя ВСЕ пакеты из сети.
Если тебе интересно это, запроси по e-mailу (ubob@mail.ru), я тебе исходник проги скину, она небольшая, просто сейчас лежит далеко, и мне за ней облом лезть.Кстати, а не разбирался ли ты , как перехватывать IP-пакеты, которые идут через твой eth во внешнюю сеть (это к вопросу о шифровании IP-пакетов, интересно разобраться).