我用来分析QQ协议的简单sniffer
[anda@thinkpad ~]$ cat qqmonitor.c
/*
* OICQ Simple sniffer programme for UNIX.
* Author < missanda@hotmail.com> QQ 8907673
*
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void usage(void);
void usage(void)
{
fprintf(stderr,"qqmonitor usage:/n");
fprintf(stderr,"qqmonitor /n");
fprintf(stderr,"example:/n");
fprintf(stderr,"1. qqmonitor eth0/n");
return;
}
static int sniffer_fd = 0;
void sniffer_exit(int signo);
void sniffer_exit(int signo)
{
printf("sniffer signal %d recvied exiting .../n",signo);
close(sniffer_fd);
exit(0);
}
#define BUFFER_SIZE 65536 /*64K*/
static unsigned char buff[BUFFER_SIZE];
#define HWADDR(addr) /
((unsigned char *)&addr)[0], /
((unsigned char *)&addr)[1], /
((unsigned char *)&addr)[2], /
((unsigned char *)&addr)[3], /
((unsigned char *)&addr)[4], /
((unsigned char *)&addr)[5]
#define NIPQUAD(addr) /
((unsigned char *)&addr)[0], /
((unsigned char *)&addr)[1], /
((unsigned char *)&addr)[2], /
((unsigned char *)&addr)[3]
void parse_packet(unsigned char*buff,int len);
void parse_packet_arp(unsigned char*buff,int len);
void parse_packet_ip(unsigned char*buff,int len);
void parse_qq_login(unsigned char*buff,int len,int direction);
void parse_qq_login_token(unsigned char*buff,int len,int direction);
void parse_qq_unknown(unsigned char *buff,int len,int direction);
void parse_qq_login_token(unsigned char*buff,int len,int direction)
{
unsigned char*p = NULL;
int i = 0;
uint32_t tmp32 = 0;
if(!buff||len==0){
return;
}
p = buff;
printf("qq login token data %d bytes:/n",len);
for(i=0;i printf("%02X ",p );
if(i&&((i%8)==0))
printf("/n");
}
printf("/n");
if(direction == 1){
printf("reply data:/n");
printf("request token %s/n",p[0]==0?"succeed":"failed");
if(p[0] == 0x00){
printf("token length %d bytes/n",p[1]);
printf("login token : ");
for(i=0;i printf("%02X ",p[i+1]);
}
}
}
else
{
printf("request data:/n");
tmp32 = ntohl(*((uint32_t*)&p[0]));
printf("request QQ %d/n",tmp32);
}
return ;
}
void parse_packet_ip(unsigned char*buff,int len)
{
struct iphdr *ip = (struct iphdr *)buff;
struct in_addr in;
unsigned char *p = NULL;
int data_len = 0;
uint16_t cmd = 0;
uint16_t seq = 0;
uint16_t ver = 0;
uint32_t id = 0;
int port = 0;
int direction = 0; /*1 = server -> client 0 = client -> server*/
int i = 0;
#if 0
printf("ip protocol/n");
printf("version : %d/n",ip->version);
printf("header length : %d bytes/n",ip->ihl*4);
printf("tos : 0x%02X/n",ip->tos);
printf("total length : %d/n",ntohs(ip->tot_len));
printf("identification : %d/n",ntohs(ip->id));
printf("flags: %02X %02X/n",((unsigned char*)&ip->frag_off)[0],((unsigned char*)&ip->frag_off)[1]);
printf("ttl : %d/n",ip->ttl);
printf("protocol : %d/n",ip->protocol);
printf("checksum : 0x%02X%02X/n",((unsigned char*)&ip->check)[0],((unsigned char*)&ip->check)[1]);
#endif
//printf("ip->protocol = %d/n",ip->protocol);
switch(ip->protocol){
case IPPROTO_TCP:
/*TCP data*/
p = buff + sizeof(struct iphdr) + sizeof(struct tcphdr);
data_len = len - sizeof(struct iphdr) - sizeof(struct tcphdr);
port = ((struct tcphdr*)(buff+sizeof(struct iphdr)))->source;
port = ntohs(port);
case IPPROTO_UDP:
/*UDP data.*/
p = buff + sizeof(struct iphdr) + sizeof(struct udphdr);
data_len = len - sizeof(struct iphdr) - sizeof(struct udphdr);
port = ((struct udphdr*)(buff+sizeof(struct iphdr)))->source;
port = ntohs(port);
break;
default:
//printf("unknow protocol./n");
return;
break;
}
// printf("data_len = %d p[0] = %02x p[%d] = %02x/n",data_len,p[0],data_len-1,p[data_len-1]);
if(p[0]!=0x02 || p[data_len-1]!=0x03){
//not oicq data.
return;
}
printf("oicq data %s :/n",(ip->protocol==IPPROTO_TCP)?"tcp":"udp");
printf("*source ip address : %d.%d.%d.%d:%d/n",NIPQUAD(ip->saddr),port);
printf("*destination ip address : %d.%d.%d.%d:%d/n",NIPQUAD(ip->daddr));
// oicq 7 bytes header.
ver = ntohs(*((uint16_t*)&p[1]));
cmd = ntohs(*((uint16_t*)&p[3]));
seq = ntohs(*((uint16_t*)&p[5]));
printf("oicq version : 0x%04x/n",ver);
printf("oicq command : 0x%04x/n",cmd);
printf("oicq sequence : 0x%04x/n",seq);
printf("data length : %d/n",data_len);
if(ver == 0x0100 || ver == 0x0000){
direction = 1; /*server to client*/
}
else
{
direction = 0; /*client to server*/
}
p = &p[7];
switch(cmd){
//pre-login command -- high verion
case 0x0062:
printf("* login token %d bytes/n",data_len);
parse_qq_login_token(p,data_len,direction);
break;
//logout command
case 0x0001:
printf("* logout/n");
id = ntohl(*((uint32_t*)&p[0]));
printf(" %d logouted /n",id);
printf(" server address %d.%d.%d.%d/n",NIPQUAD(ip->daddr));
printf(" client address %d.%d.%d.%d:%d/n/n",NIPQUAD(ip->saddr),port);
break;
//login command
case 0x0022:
printf("* login/n");
parse_qq_login(p,data_len,direction);
break;
case 0x0002:
printf("* keep alive/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0004:
printf("* modify information/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0005:
printf("* search onlines/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0006:
printf("* get user information/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0009:
printf("* add friend/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x000A:
printf("* delete friend/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x000B:
printf("* add friend authorize/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x000D:
printf("* change status/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0012:
printf("* ACK : system message/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0016:
printf("* IM send/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0017:
printf("* IM recv/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x001C:
printf("* delete me./n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x001D:
printf("* request key./n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0021:
printf("* ????1/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0026:
printf("* get friends list/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0027:
printf("* get online friends list/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0029:
printf("* ????2/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0030:
printf("* group command/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0031:
printf("* test./n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x003C:
printf("* group name command./n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x003D:
printf("* group members upload command./n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x003E:
printf("* friends remark command./n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0058:
printf("* group members upload command./n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x005C:
printf("* get level/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0080:
printf("* system message/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0081:
printf("* friend change status/n");
parse_qq_unknown(p,data_len,direction);
break;
default:
printf("qq cmd = 0x%04x %d bytes/n",cmd,data_len);
parse_qq_unknown(p,data_len,direction);
break;
}
return ;
}
void parse_qq_unknown(unsigned char *buff,int len,int direction)
{
int i = 0;
if(!buff||len == 0)
return;
printf("dump data direction = %s:/n",direction?"s -> c":"c -> s");
for(i=0;i printf("%02X ",buff);
if(i&&(i%16 == 0))
printf("/n");
}
printf("/n");
return ;
}
void parse_qq_login(unsigned char*buff,int len,int direction)
{
uint32_t id = 0;
unsigned char tea_key[16];
unsigned char*p = NULL;
unsigned char x[1];
unsigned char data[65535];
int len2 = 0;
int e = -1;
bzero(data,sizeof(data));
if(len%4){
return;
}
p = buff;
if(direction == 0){
//client to server
printf(" login request data./n");
// 4 bytes qq id
id = ntohl(*((uint32_t*)&p[0]));
printf(" id = /"%d/"/n",id);
// 16 bytes TEA key
bcopy(&p[4],tea_key,16);
x[0] = p[20];
printf(" TEA key %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x/n",tea_key[0],tea_key[1],tea_key[2],tea_key[3],tea_key[4],tea_key[5],tea_key[6],tea_key[7],tea_key[8],tea_key[9],tea_key[10],tea_key[11],tea_key[12],tea_key[13],tea_key[14],tea_key[15]);
len2 = len - 4 - 16;
}
else
{
printf(" login respond data./n");
}
return ;
}
void parse_packet_arp(unsigned char*buff,int len)
{
struct ether_arp *arp = (struct ether_arp *)buff;
#if 0
printf("arp packet - time = %u/n",time(0));
printf("hardware type : %d/n", ntohs(arp->arp_hrd));
printf("protocol type : %02X-%02X/n", ((unsigned char*)&arp->arp_pro)[0],((unsigned char*)&arp->arp_pro)[1]);
printf("hardware address length : %d/n", arp->arp_hln);
printf("protocol address length : %d/n", arp->arp_pln);
printf("operation code : %d/n", ntohs(arp->arp_op));
printf("request hardware address : %02X:%02X:%02X:%02X:%02X:%02X/n",HWADDR(arp->arp_sha));
printf("request ip address : %d.%d.%d.%d", NIPQUAD(arp->arp_spa));
printf("target hardware address : %02X:%02X:%02X:%02X:%02X:%02X/n",HWADDR(arp->arp_tha));
printf("target ip address : %d.%d.%d.%d/n",NIPQUAD(arp->arp_tpa));
#endif
return;
}
void parse_packet(unsigned char*buff,int len)
{
struct ethhdr *eth = (struct ethhdr *)buff;
#if 0
/*DEBUG only*/
printf("MAC header/n");
printf("destination : %02X:%02X:%02X:%02X:%02X:%02X/n",HWADDR(eth->h_dest));
printf("source : %02X:%02X:%02X:%02X:%02X:%02X/n",HWADDR(eth->h_source));
printf("protocol : %02X-%02X/n",((unsigned char*)e->h_proto)[0],((unsigned char*)e->h_proto)[1]);
#endif
switch(ntohs(eth->h_proto)){
case ETH_P_IP:
/*QQ data in it.*/
//printf("ip protocol./n");
parse_packet_ip(&buff[sizeof(struct ethhdr)],len - sizeof(struct ethhdr));
break;
case ETH_P_ARP:
/*ARP request.*/
//printf("arp protocol./n");
parse_packet_arp(&buff[sizeof(struct ethhdr)],len - sizeof(struct ethhdr)); break;
default:
//printf("unknow protocol./n");
return;
}
return;
}
int main(int argc,char**argv)
{
char ch = 0;
int e = -1;
int len = 0;
char ifdev[256];
struct ifreq ifr;
if(argc!=2){
usage();
exit(-1);
}
if(getuid()!=0){
fprintf(stderr,"only root can open SOCK_PACKET - frame type 0x800/n");
exit(-1);
}
signal(SIGINT,sniffer_exit);
signal(SIGTERM,sniffer_exit);
signal(SIGCHLD,SIG_IGN);
bzero(ifdev,sizeof(ifdev));
bcopy(argv[1],ifdev,strlen(argv[1]));
//only monitor local ethernet work
//sniffer_fd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
/*set NIC to promisc mode.*/
sniffer_fd = socket(AF_INET, SOCK_PACKET, htons(0x800));
if(sniffer_fd<0){
fprintf(stderr,"failed to create socket - PF_PACKET %0x/n",0x800);
return -EFAULT;
}
bzero(&ifr,sizeof(ifr));
sprintf(ifr.ifr_name,ifdev);
#if 1
e = ioctl(sniffer_fd, SIOCGIFFLAGS, &ifr);
if(e){
fprintf(stderr,"failed to ioctl - SIOCGIFFLAGS - /"%s/"/n",ifdev);
close(sniffer_fd);
return -EFAULT;
}
ifr.ifr_flags |= IFF_PROMISC;
e = ioctl(sniffer_fd, SIOCSIFFLAGS, &ifr);
if(e){
fprintf(stderr,"failed to ioctl - SIOCGIFFLAGS - /"%s/" - IFF_PROMISC/n",ifdev);
close(sniffer_fd);
return -EFAULT;
}
#endif
printf("oicq packet sniffer is starting .../n");
while(1){
bzero(buff,BUFFER_SIZE);
//len = recv(sniffer_fd,buff,BUFFER_SIZE,0);
len = read(sniffer_fd,buff,BUFFER_SIZE);
if(len<=0){
continue;
}
//printf("==>> %d bytes recevied./n",len);
parse_packet(buff,len);
}
/*maybe never run to here. but make gcc happy.*/
close(sniffer_fd);
return 0;
}
/*
* OICQ Simple sniffer programme for UNIX.
* Author < missanda@hotmail.com> QQ 8907673
*
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void usage(void);
void usage(void)
{
fprintf(stderr,"qqmonitor usage:/n");
fprintf(stderr,"qqmonitor /n");
fprintf(stderr,"example:/n");
fprintf(stderr,"1. qqmonitor eth0/n");
return;
}
static int sniffer_fd = 0;
void sniffer_exit(int signo);
void sniffer_exit(int signo)
{
printf("sniffer signal %d recvied exiting .../n",signo);
close(sniffer_fd);
exit(0);
}
#define BUFFER_SIZE 65536 /*64K*/
static unsigned char buff[BUFFER_SIZE];
#define HWADDR(addr) /
((unsigned char *)&addr)[0], /
((unsigned char *)&addr)[1], /
((unsigned char *)&addr)[2], /
((unsigned char *)&addr)[3], /
((unsigned char *)&addr)[4], /
((unsigned char *)&addr)[5]
#define NIPQUAD(addr) /
((unsigned char *)&addr)[0], /
((unsigned char *)&addr)[1], /
((unsigned char *)&addr)[2], /
((unsigned char *)&addr)[3]
void parse_packet(unsigned char*buff,int len);
void parse_packet_arp(unsigned char*buff,int len);
void parse_packet_ip(unsigned char*buff,int len);
void parse_qq_login(unsigned char*buff,int len,int direction);
void parse_qq_login_token(unsigned char*buff,int len,int direction);
void parse_qq_unknown(unsigned char *buff,int len,int direction);
void parse_qq_login_token(unsigned char*buff,int len,int direction)
{
unsigned char*p = NULL;
int i = 0;
uint32_t tmp32 = 0;
if(!buff||len==0){
return;
}
p = buff;
printf("qq login token data %d bytes:/n",len);
for(i=0;i printf("%02X ",p );
if(i&&((i%8)==0))
printf("/n");
}
printf("/n");
if(direction == 1){
printf("reply data:/n");
printf("request token %s/n",p[0]==0?"succeed":"failed");
if(p[0] == 0x00){
printf("token length %d bytes/n",p[1]);
printf("login token : ");
for(i=0;i printf("%02X ",p[i+1]);
}
}
}
else
{
printf("request data:/n");
tmp32 = ntohl(*((uint32_t*)&p[0]));
printf("request QQ %d/n",tmp32);
}
return ;
}
void parse_packet_ip(unsigned char*buff,int len)
{
struct iphdr *ip = (struct iphdr *)buff;
struct in_addr in;
unsigned char *p = NULL;
int data_len = 0;
uint16_t cmd = 0;
uint16_t seq = 0;
uint16_t ver = 0;
uint32_t id = 0;
int port = 0;
int direction = 0; /*1 = server -> client 0 = client -> server*/
int i = 0;
#if 0
printf("ip protocol/n");
printf("version : %d/n",ip->version);
printf("header length : %d bytes/n",ip->ihl*4);
printf("tos : 0x%02X/n",ip->tos);
printf("total length : %d/n",ntohs(ip->tot_len));
printf("identification : %d/n",ntohs(ip->id));
printf("flags: %02X %02X/n",((unsigned char*)&ip->frag_off)[0],((unsigned char*)&ip->frag_off)[1]);
printf("ttl : %d/n",ip->ttl);
printf("protocol : %d/n",ip->protocol);
printf("checksum : 0x%02X%02X/n",((unsigned char*)&ip->check)[0],((unsigned char*)&ip->check)[1]);
#endif
//printf("ip->protocol = %d/n",ip->protocol);
switch(ip->protocol){
case IPPROTO_TCP:
/*TCP data*/
p = buff + sizeof(struct iphdr) + sizeof(struct tcphdr);
data_len = len - sizeof(struct iphdr) - sizeof(struct tcphdr);
port = ((struct tcphdr*)(buff+sizeof(struct iphdr)))->source;
port = ntohs(port);
case IPPROTO_UDP:
/*UDP data.*/
p = buff + sizeof(struct iphdr) + sizeof(struct udphdr);
data_len = len - sizeof(struct iphdr) - sizeof(struct udphdr);
port = ((struct udphdr*)(buff+sizeof(struct iphdr)))->source;
port = ntohs(port);
break;
default:
//printf("unknow protocol./n");
return;
break;
}
// printf("data_len = %d p[0] = %02x p[%d] = %02x/n",data_len,p[0],data_len-1,p[data_len-1]);
if(p[0]!=0x02 || p[data_len-1]!=0x03){
//not oicq data.
return;
}
printf("oicq data %s :/n",(ip->protocol==IPPROTO_TCP)?"tcp":"udp");
printf("*source ip address : %d.%d.%d.%d:%d/n",NIPQUAD(ip->saddr),port);
printf("*destination ip address : %d.%d.%d.%d:%d/n",NIPQUAD(ip->daddr));
// oicq 7 bytes header.
ver = ntohs(*((uint16_t*)&p[1]));
cmd = ntohs(*((uint16_t*)&p[3]));
seq = ntohs(*((uint16_t*)&p[5]));
printf("oicq version : 0x%04x/n",ver);
printf("oicq command : 0x%04x/n",cmd);
printf("oicq sequence : 0x%04x/n",seq);
printf("data length : %d/n",data_len);
if(ver == 0x0100 || ver == 0x0000){
direction = 1; /*server to client*/
}
else
{
direction = 0; /*client to server*/
}
p = &p[7];
switch(cmd){
//pre-login command -- high verion
case 0x0062:
printf("* login token %d bytes/n",data_len);
parse_qq_login_token(p,data_len,direction);
break;
//logout command
case 0x0001:
printf("* logout/n");
id = ntohl(*((uint32_t*)&p[0]));
printf(" %d logouted /n",id);
printf(" server address %d.%d.%d.%d/n",NIPQUAD(ip->daddr));
printf(" client address %d.%d.%d.%d:%d/n/n",NIPQUAD(ip->saddr),port);
break;
//login command
case 0x0022:
printf("* login/n");
parse_qq_login(p,data_len,direction);
break;
case 0x0002:
printf("* keep alive/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0004:
printf("* modify information/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0005:
printf("* search onlines/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0006:
printf("* get user information/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0009:
printf("* add friend/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x000A:
printf("* delete friend/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x000B:
printf("* add friend authorize/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x000D:
printf("* change status/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0012:
printf("* ACK : system message/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0016:
printf("* IM send/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0017:
printf("* IM recv/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x001C:
printf("* delete me./n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x001D:
printf("* request key./n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0021:
printf("* ????1/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0026:
printf("* get friends list/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0027:
printf("* get online friends list/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0029:
printf("* ????2/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0030:
printf("* group command/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0031:
printf("* test./n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x003C:
printf("* group name command./n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x003D:
printf("* group members upload command./n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x003E:
printf("* friends remark command./n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0058:
printf("* group members upload command./n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x005C:
printf("* get level/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0080:
printf("* system message/n");
parse_qq_unknown(p,data_len,direction);
break;
case 0x0081:
printf("* friend change status/n");
parse_qq_unknown(p,data_len,direction);
break;
default:
printf("qq cmd = 0x%04x %d bytes/n",cmd,data_len);
parse_qq_unknown(p,data_len,direction);
break;
}
return ;
}
void parse_qq_unknown(unsigned char *buff,int len,int direction)
{
int i = 0;
if(!buff||len == 0)
return;
printf("dump data direction = %s:/n",direction?"s -> c":"c -> s");
for(i=0;i printf("%02X ",buff);
if(i&&(i%16 == 0))
printf("/n");
}
printf("/n");
return ;
}
void parse_qq_login(unsigned char*buff,int len,int direction)
{
uint32_t id = 0;
unsigned char tea_key[16];
unsigned char*p = NULL;
unsigned char x[1];
unsigned char data[65535];
int len2 = 0;
int e = -1;
bzero(data,sizeof(data));
if(len%4){
return;
}
p = buff;
if(direction == 0){
//client to server
printf(" login request data./n");
// 4 bytes qq id
id = ntohl(*((uint32_t*)&p[0]));
printf(" id = /"%d/"/n",id);
// 16 bytes TEA key
bcopy(&p[4],tea_key,16);
x[0] = p[20];
printf(" TEA key %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x/n",tea_key[0],tea_key[1],tea_key[2],tea_key[3],tea_key[4],tea_key[5],tea_key[6],tea_key[7],tea_key[8],tea_key[9],tea_key[10],tea_key[11],tea_key[12],tea_key[13],tea_key[14],tea_key[15]);
len2 = len - 4 - 16;
}
else
{
printf(" login respond data./n");
}
return ;
}
void parse_packet_arp(unsigned char*buff,int len)
{
struct ether_arp *arp = (struct ether_arp *)buff;
#if 0
printf("arp packet - time = %u/n",time(0));
printf("hardware type : %d/n", ntohs(arp->arp_hrd));
printf("protocol type : %02X-%02X/n", ((unsigned char*)&arp->arp_pro)[0],((unsigned char*)&arp->arp_pro)[1]);
printf("hardware address length : %d/n", arp->arp_hln);
printf("protocol address length : %d/n", arp->arp_pln);
printf("operation code : %d/n", ntohs(arp->arp_op));
printf("request hardware address : %02X:%02X:%02X:%02X:%02X:%02X/n",HWADDR(arp->arp_sha));
printf("request ip address : %d.%d.%d.%d", NIPQUAD(arp->arp_spa));
printf("target hardware address : %02X:%02X:%02X:%02X:%02X:%02X/n",HWADDR(arp->arp_tha));
printf("target ip address : %d.%d.%d.%d/n",NIPQUAD(arp->arp_tpa));
#endif
return;
}
void parse_packet(unsigned char*buff,int len)
{
struct ethhdr *eth = (struct ethhdr *)buff;
#if 0
/*DEBUG only*/
printf("MAC header/n");
printf("destination : %02X:%02X:%02X:%02X:%02X:%02X/n",HWADDR(eth->h_dest));
printf("source : %02X:%02X:%02X:%02X:%02X:%02X/n",HWADDR(eth->h_source));
printf("protocol : %02X-%02X/n",((unsigned char*)e->h_proto)[0],((unsigned char*)e->h_proto)[1]);
#endif
switch(ntohs(eth->h_proto)){
case ETH_P_IP:
/*QQ data in it.*/
//printf("ip protocol./n");
parse_packet_ip(&buff[sizeof(struct ethhdr)],len - sizeof(struct ethhdr));
break;
case ETH_P_ARP:
/*ARP request.*/
//printf("arp protocol./n");
parse_packet_arp(&buff[sizeof(struct ethhdr)],len - sizeof(struct ethhdr)); break;
default:
//printf("unknow protocol./n");
return;
}
return;
}
int main(int argc,char**argv)
{
char ch = 0;
int e = -1;
int len = 0;
char ifdev[256];
struct ifreq ifr;
if(argc!=2){
usage();
exit(-1);
}
if(getuid()!=0){
fprintf(stderr,"only root can open SOCK_PACKET - frame type 0x800/n");
exit(-1);
}
signal(SIGINT,sniffer_exit);
signal(SIGTERM,sniffer_exit);
signal(SIGCHLD,SIG_IGN);
bzero(ifdev,sizeof(ifdev));
bcopy(argv[1],ifdev,strlen(argv[1]));
//only monitor local ethernet work
//sniffer_fd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
/*set NIC to promisc mode.*/
sniffer_fd = socket(AF_INET, SOCK_PACKET, htons(0x800));
if(sniffer_fd<0){
fprintf(stderr,"failed to create socket - PF_PACKET %0x/n",0x800);
return -EFAULT;
}
bzero(&ifr,sizeof(ifr));
sprintf(ifr.ifr_name,ifdev);
#if 1
e = ioctl(sniffer_fd, SIOCGIFFLAGS, &ifr);
if(e){
fprintf(stderr,"failed to ioctl - SIOCGIFFLAGS - /"%s/"/n",ifdev);
close(sniffer_fd);
return -EFAULT;
}
ifr.ifr_flags |= IFF_PROMISC;
e = ioctl(sniffer_fd, SIOCSIFFLAGS, &ifr);
if(e){
fprintf(stderr,"failed to ioctl - SIOCGIFFLAGS - /"%s/" - IFF_PROMISC/n",ifdev);
close(sniffer_fd);
return -EFAULT;
}
#endif
printf("oicq packet sniffer is starting .../n");
while(1){
bzero(buff,BUFFER_SIZE);
//len = recv(sniffer_fd,buff,BUFFER_SIZE,0);
len = read(sniffer_fd,buff,BUFFER_SIZE);
if(len<=0){
continue;
}
//printf("==>> %d bytes recevied./n",len);
parse_packet(buff,len);
}
/*maybe never run to here. but make gcc happy.*/
close(sniffer_fd);
return 0;
}
385

被折叠的 条评论
为什么被折叠?



