以前寫的一個sniffer網路監聽程式(作為備忘)
ethproto.h:
#ifndef ETHPROTO_H
#define ETHPROTO_H
#define ARP 0X0806
#define RARP 0X8035
#define IP 0X0800
#define IP_TCP 6
#define IP_UDP 17
#define IP_ICMP 1
#define IP_IGMP 2
#define IP_OSPF 89
typedefunsigned char uint8;
typedefunsigned shortint uint16;
typedefunsigned int uint32;
typedefcharint8;
typedefshort intint16;
typedefintint32;
typedefstruct _EtherHead
{
uint8 d_mac[6]; //ƒøµƒmac
uint8 s_mac[6]; //‘¥mac
uint16 proto_type; //…œ≤„–≠“È¿‡–Õ
}EtherHead;
typedefstruct _IpHead
{
uint8ver_headlen; //∞ʱæ+±®Õ∑≥§∂»
uint8 tos; //∑˛ŒÒ¿‡–Õ
uint16 total_len; //◊‹≥§∂»
uint16 ident; //±Í ∂
uint16 frag_offset; //±Í÷æ+∆¨∆´“∆
uint8 ttl; //…˙¥Ê÷‹∆⁄
uint8 proto; //–≠“È¿‡–Õ
uint16 checksum; //Õ∑≤ø–£—È
uint32 s_ip; //‘¥ip
uint32 d_ip; //ƒøµƒip
}IpHead;
typedefstruct _ArpHead
{
uint16 hard_type;//”≤º˛¿‡–Õ
uint16 proto_type;//–≠“È¿‡–Õ
uint8 hard_len;//”≤º˛µÿ÷∑≥§∂»
uint8 proto_len;//–≠“ȵÿ÷∑≥§∂»
uint16 action;//≤Ÿ◊˜¿‡–Õ
uint8 s_mac[6];//‘¥macµÿ÷∑
uint32 s_ip;//‘¥ip
uint8 d_mac[6];//ƒøµƒmacµÿ÷∑
uint32 d_ip;//ƒøµƒip
}ArpHead;
typedefstruct _TcpHead
{
uint16 s_port; //‘¥∂Àø⁄
uint16 d_port; //ƒøµƒ∂Àø⁄
uint32 seq; //–Ú∫≈
uint32 ack; //»∑»œ∫≈
uint16offset_flag; //Õ∑≤ø≥§∂»+±£¡Ù+±Í÷æ
uint16 win; //¥∞ø⁄¥Û–°
uint16 check_sum; //–£—È∫Õ
uint16 urp_pointer;//ΩÙº±÷∏’Î
uint32 option;//—°œÓ+ÃÓ≥‰ ˝æ› «16Œªµƒ±∂ ˝
}TcpHead;
typedefstruct _UdpHead
{
uint16s_port;//‘¥∂Àø⁄
uint16 d_port; //ƒøµƒ∂Àø⁄
uint16 len; //◊‹≥§∂»
uint16 check_sum; //–£—È∫Õ
}UdpHead;
char *get_eth_next(char*);
char *get_ip_next(char*);
void ethhead_do(char*);
void arphead_do(char*);
void rarphead_do(char*);
void iphead_do(char*);
void icmphead_do(char*);
void igmphead_do(char*);
void tcphead_do(char*);
void udphead_do(char*);
#endif
ethproto.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include "ethproto.h"
char *get_eth_next(char *ethhead)
{
char *ret;
ret = ethhead +14;
return ret;
}
char *get_ip_next(char *ethhead)
{
char *ret;
ret = ethhead +34;
return ret;
}
void ethhead_do(char *ethhead)
{
char *p=ethhead;
printf("SMAC: %02X:%02X:%02X:%02X:%02X:%02X ==> DMAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
p[6]&0XFF, p[7]&0XFF, p[8]&0XFF, p[9]&0XFF, p[10]&0XFF, p[11]&0XFF,/*‘¥MACµÿ÷∑*/
p[0]&0XFF, p[1]&0XFF, p[2]&0XFF,p[3]&0XFF, p[4]&0XFF, p[5]&0XFF);/*ƒø±ÍMACµÿ÷∑*/
return;
}
void arphead_do(char *arphead)
{
char *p=arphead+14;
printf("arp\n");
printf("SIP: %d.%d.%d.%d ==> DIP: %d.%d.%d.%d\n",
p[0]&0XFF, p[1]&0XFF, p[2]&0XFF, p[3]&0XFF,/*‘¥IP*/
p[10]&0XFF, p[11]&0XFF, p[12]&0XFF, p[13]&0XFF);/*ƒøµƒIP*/
return;
}
void rarphead_do(char *rarphead)
{
char *p=rarphead+14;
printf("rarp\n");
printf("SIP: %3d.%3d.%3d.%3d ==> DIP: %3d.%3d.%3d.%3d\n",
p[0]&0XFF, p[1]&0XFF, p[2]&0XFF, p[3]&0XFF,/*‘¥IP*/
p[10]&0XFF, p[11]&0XFF, p[12]&0XFF, p[13]&0XFF);/*ƒøµƒIP*/
return;
}
void iphead_do(char *iphead)
{
char *p=iphead+12;
printf("ip\n");
printf("SIP: %3d.%3d.%3d.%3d ==>DIP: %3d.%3d.%3d.%3d\n",
p[0]&0XFF, p[1]&0XFF, p[2]&0XFF, p[3]&0XFF,/*‘¥IP*/
p[4]&0XFF, p[5]&0XFF, p[6]&0XFF, p[7]&0XFF);/*ƒøµƒIP*/
return;
}
void icmphead_do(char *icmphead)
{
printf("icmp\n");
return;
}
void igmphead_do(char *igmphead)
{
printf("igmp\n");
return;
}
void tcphead_do(char *tcphead)
{
char *p=tcphead;
printf("tcp\n");
printf("SPORT: %5d ==> DPORT: %5d\n",
ntohs(((u_int16_t *)p)[0]), /*‘¥∂Àø⁄*/
ntohs(((u_int16_t *)p)[1]));/*ƒøµƒ∂Àø⁄*/
return;
}
void udphead_do(char *udphead)
{
char *p=udphead;
printf("udp\n");
printf("SPORT: %5d ==> DPORT: %5d\n",
ntohs(((u_int16_t *)p)[0]),/*‘¥∂Àø⁄*/
ntohs(((u_int16_t *)p)[1]));/*ƒøµƒ∂Àø⁄*/
return;
}
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/if_ether.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <time.h>
#include <errno.h>
#include "ethproto.h"
#define BUFFER_MAX 2048
void ether_packet_do(char* buffer)
{
staticint n_packet=0;
int proto;
char *ethhead,*headpoint;
time_t timep;
ethhead = buffer;
n_packet+=1;
time(&timep);
printf("\n[PACKETS]:%d\n",n_packet);
printf("[TIME]:%s",ctime(&timep));
ethhead_do(ethhead);
/*“‘ôկ…œ≤„–≠“È¿‡–Õ*/
proto = ntohs(((u_int16_t *)(ethhead +12))[0]);
switch(proto)
{
case IP:
headpoint = get_eth_next(ethhead);
iphead_do(headpoint);
/*IP…œ≤„–≠“È*/
proto = (int)(*(headpoint +9));
switch(proto)
{
case IP_TCP:
headpoint = get_ip_next(ethhead);
tcphead_do(headpoint);
break;
case IP_UDP:
headpoint = get_ip_next(ethhead);
udphead_do(headpoint);
break;
case IP_ICMP:
headpoint = get_ip_next(ethhead);
icmphead_do(headpoint);
break;
case IP_IGMP:
headpoint = get_ip_next(ethhead);
igmphead_do(headpoint);
break;
case IP_OSPF:printf("ospf\n");break;
default:printf("only know this is a IP packet\n");
}
break;
case ARP:
headpoint = get_eth_next(ethhead);
arphead_do(headpoint);
break;
case RARP:
headpoint = get_eth_next(ethhead);
rarphead_do(headpoint);
break;
default:printf("unknow protocol\n");
}
return;
}
int main(int argc,char *argv[])
{
int sock,n_read;
char buffer[BUFFER_MAX];
if((sock = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL))) <0)
{
perror("socket error!\n");
exit(1);
}
while(1)
{
n_read = recvfrom(sock,buffer,BUFFER_MAX,0,NULL,NULL);
if(n_read <14)
{
perror("this is not ethernet\n");
continue;
}
ether_packet_do(buffer);
}
}