⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 436.htm

📁 unix高级编程原吗
💻 HTM
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>apue</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center">               ● UNIX网络编程                       (BM: clown)                </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p   align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="317.htm">上一层</a>][<a href="437.htm">下一篇</a>]
<hr><p align="left"><small>:发信人: ghxiang (henry), 信区: Security <br>

:标  题: 一个sniffer的程序 <br>

:发信站: 武汉白云黄鹤站 (Sat Nov 18 16:12:39 2000), 站内信件 <br>

main中 <br>

  <br>

ip=(struct iphdr *)(((unsigned long)&ep.ip)-2); <br>

  <br>

tcp=(struct tcphdr *)(((unsigned long)&ep.tcp)-2); <br>

  <br>

这里-2起的是什么作用? <br>

  <br>

  <br>

  <br>

以下是sniffer的源文件: <br>

  <br>

  <br>

  <br>

#include ... <br>

  <br>

int openintf(char *); <br>

  <br>

int read_tcp(int); <br>

  <br>

  <br>

int filter(void); <br>

  <br>

int print_header(void); <br>

  <br>

int print_data(int, char *); <br>

  <br>

char *hostlookup(unsigned long int); <br>

  <br>

void clear_victim(void); <br>

  <br>

void cleanup(int); <br>

  <br>

struct etherpacket <br>

  <br>

{ <br>

  <br>

struct ethhdr eth; <br>

  <br>

struct iphdr ip; <br>

  <br>

struct tcphdr tcp; <br>

  <br>

  <br>

char buff[8192]; <br>

  <br>

}ep; <br>

  <br>

struct <br>

  <br>

{ <br>

  <br>

unsigned long saddr; <br>

  <br>

unsigned long daddr; <br>

  <br>

unsigned short sport; <br>

  <br>

unsigned short dport; <br>

  <br>

int bytes_read; <br>

  <br>

char active; <br>

  <br>

time_t start_time; <br>

  <br>

  <br>

} victim; <br>

  <br>

struct iphdr *ip; <br>

  <br>

struct tcphdr *tcp; <br>

  <br>

int s; <br>

  <br>

FILE *fp; <br>

  <br>

#define CAPTLEN 512 <br>

  <br>

#define TIMEOUT 30 <br>

  <br>

#define TCPLOG "tcp.log" <br>

  <br>

int openintf(char *d) <br>

  <br>

{ <br>

  <br>

int fd; <br>

  <br>

  <br>

struct ifreq ifr; <br>

  <br>

int s; <br>

  <br>

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

  <br>

if(fd < 0) <br>

  <br>

{ <br>

  <br>

perror("cant get SOCK_PACKET socket"); <br>

  <br>

exit(0); <br>

  <br>

} <br>

  <br>

strcpy(ifr.ifr_name, d); <br>

  <br>

s=ioctl(fd, SIOCGIFFLAGS, &ifr); <br>

  <br>

if(s < 0) <br>

  <br>

  <br>

{ <br>

  <br>

close(fd); <br>

  <br>

perror("cant get flags"); <br>

  <br>

exit(0); <br>

  <br>

} <br>

  <br>

ifr.ifr_flags |= IFF_PROMISC; <br>

  <br>

s=ioctl(fd, SIOCSIFFLAGS, &ifr); <br>

  <br>

if(s < 0) perror("can not set promiscuous mode"); <br>

  <br>

return fd; <br>

  <br>

} <br>

  <br>

int read_tcp(int s) <br>

  <br>

  <br>

{ <br>

  <br>

int x; <br>

  <br>

while(1) <br>

  <br>

{ <br>

  <br>

x=read(s, (struct etherpacket *)&ep, sizeof(ep)); <br>

  <br>

if(x > 1) <br>

  <br>

{ <br>

  <br>

if(filter()==0) continue; <br>

  <br>

x=x-54; <br>

  <br>

if(x < 1) continue; <br>

  <br>

return x; <br>

  <br>

  <br>

} <br>

  <br>

} <br>

  <br>

} <br>

  <br>

int filter(void) <br>

  <br>

{ <br>

  <br>

int p; <br>

  <br>

p=0; <br>

  <br>

if(ip->protocol != 6) return 0; <br>

  <br>

return 0; <br>

  <br>

} <br>

  <br>

if(tcp->fin == 1) <br>

  <br>

  <br>

{ <br>

  <br>

victim.active=0; <br>

  <br>

alarm(0); <br>

  <br>

fprintf(fp, "\n----- [FIN]\n"); <br>

  <br>

clear_victim(); <br>

  <br>

return 0; <br>

  <br>

} <br>

  <br>

return 1; <br>

  <br>

} <br>

  <br>

int print_header(void) <br>

  <br>

{ <br>

  <br>

  <br>

fprintf(fp, "\n"); <br>

  <br>

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

  <br>

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

  <br>

} <br>

  <br>

int print_data(int datalen, char *data) <br>

  <br>

{ <br>

  <br>

int i=0; <br>

  <br>

int t=0; <br>

  <br>

victim.bytes_read=victim.bytes_read+datalen; <br>

  <br>

for(i=0;i != datalen;i++) <br>

  <br>

{ <br>

  <br>

  <br>

if(data[i] == 13) { fprintf(fp, "\n"); t=0; } <br>

  <br>

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

  <br>

if(t > 75) {t=0;fprintf(fp, "\n");} <br>

  <br>

} <br>

  <br>

} <br>

  <br>

main(int argc, char **argv) <br>

  <br>

{ <br>

  <br>

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

  <br>

s=openintf("eth0"); <br>

  <br>

ip=(struct iphdr *)(((unsigned long)&ep.ip)-2); <br>

  <br>

tcp=(struct tcphdr *)(((unsigned long)&ep.tcp)-2); <br>

  <br>

  <br>

  <br>

  <br>

signal(SIGHUP, SIG_IGN); <br>

  <br>

signal(SIGINT, cleanup); <br>

  <br>

signal(SIGTERM, cleanup); <br>

  <br>

signal(SIGKILL, cleanup); <br>

  <br>

signal(SIGQUIT, cleanup); <br>

  <br>

if(argc == 2) fp=stdout; <br>

  <br>

else fp=fopen(TCPLOG, "at"); <br>

  <br>

if(fp == NULL) { fprintf(stderr, "cant open log\n");exit(0);} <br>

clear_victim(); <br>

for(;;) <br>

{ <br>

read_tcp(s); <br>

if(victim.active != 0) print_data(htons(ip->tot_len)-sizeof(ep.ip)-sizeof(ep <br>



.tcp), ep.buff-2); <br>

fflush(fp); <br>

} <br>

} <br>

char *hostlookup(unsigned long int in) <br>

{ <br>

static char blah[1024]; <br>

struct in_addr i; <br>

struct hostent * he; <br>

i.s_addr=in; <br>

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

if(he == NULL) <br>

strcpy(blah, inet_ntoa(i)); <br>

else <br>

strcpy(blah,he->h_name); <br>

return blah; <br>

} <br>

void clear_victim(void) <br>

{ <br>

victim.saddr=0; <br>

victim.daddr=0; <br>

victim.sport=0; <br>



victim.dport=0; <br>

victim.active=0; <br>

victim.bytes_read=0; <br>

victim.start_time=0; <br>

} <br>

void cleanup(int sig) <br>

{ <br>

fprintf(fp, "Exiting...\n"); <br>

close(s); <br>

fclose(fp); <br>

exit(0); <br>

} <br>

  <br>

-- <br>

※ 来源:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: 202.120.1.63] <br>

:发信人: scz (小四), 信区: Security <br>

:标  题: Re: 一个sniffer的程序 <br>

:发信站: 武汉白云黄鹤站 (Sat Nov 18 16:21:38 2000), 站内信件 <br>

这个问题我看都够15天重新贴一次了,学习news的做法。 <br>

  <br>

结构定义中的字节对齐问题,记得你好象在清华Unix版 <br>

  <br>

  <br>

还是什么版问过吧。 <br>

  <br>

  <br>

  <br>

标题:Unix自定义结构在gcc下优化编译中对齐的解决办法 <br>

  <br>

  <br>

  <br>

这个问题在华中程序设计版讨论过的,主要是编译器优化对齐的问题。 <br>

  <br>

对于linux/solaris都有这样的问题,对于 linux一般解决办法是用 <br>

  <br>

如下宏封装自己的struct <br>

  <br>

  <br>

  <br>

#pragma pack(1) <br>

  <br>

  <br>

  <br>

struct myarphdr <br>

  <br>

  <br>

{ <br>

  <br>

}; <br>

  <br>

  <br>

  <br>

#pragma pack() <br>

  <br>

  <br>

  <br>

如果是solaris,可以这样 <br>

  <br>

  <br>

  <br>

struct myarphdr <br>

  <br>

{ <br>

  <br>

} __attribute__ ((packed)); <br>

  <br>

  <br>

  <br>

  <br>

两种办法其实都可以用在Unix系统下,gcc编译器中。 <br>

  <br>

  <br>

  <br>

mbuf发言: <br>

  <br>

  <br>

  <br>

关于字节对齐的问题,相应的编译器选项为 <br>

  <br>

gcc:   -fpack-struct <br>

  <br>

Sun Workshop cc/CC:  -misalign <br>

  <br>

  <br>

  <br>

不过最好不好这样,这会大大降低程序的效率,特别在某些体系中. <br>

  <br>

应该尝试用位操作来处理. <br>

  <br>

  <br>

  <br>

  <br>

#ragama pack(1) <br>

  <br>

struct ..... <br>

  <br>

#pragama pack() <br>

  <br>

  <br>

  <br>

: 看你用什么编译器 <br>

  <br>

发信人: scz (小四), 信区: Security <br>

  <br>

标  题: Re: 一个sniffer的程序 <br>

  <br>

发信站: 武汉白云黄鹤站 (Sat Nov 18 16:21:38 2000), 站内信件 <br>

  <br>

  <br>

  <br>

这个问题我看都够15天重新贴一次了,学习news的做法。 <br>

  <br>

结构定义中的字节对齐问题,记得你好象在清华Unix版 <br>

  <br>

  <br>

还是什么版问过吧。 <br>

  <br>

  <br>

  <br>

标题:Unix自定义结构在gcc下优化编译中对齐的解决办法 <br>

  <br>

  <br>

  <br>

这个问题在华中程序设计版讨论过的,主要是编译器优化对齐的问题。 <br>

  <br>

对于linux/solaris都有这样的问题,对于 linux一般解决办法是用 <br>

  <br>

如下宏封装自己的struct <br>

  <br>

  <br>

  <br>

#pragma pack(1) <br>

  <br>

  <br>

  <br>

struct myarphdr <br>

  <br>

  <br>

{ <br>

  <br>

}; <br>

  <br>

  <br>

  <br>

#pragma pack() <br>

  <br>

  <br>

  <br>

如果是solaris,可以这样 <br>

  <br>

  <br>

  <br>

struct myarphdr <br>

  <br>

{ <br>

  <br>

} __attribute__ ((packed)); <br>

  <br>

  <br>

  <br>

  <br>

两种办法其实都可以用在Unix系统下,gcc编译器中。 <br>

  <br>

  <br>

  <br>

mbuf发言: <br>

  <br>

  <br>

  <br>

关于字节对齐的问题,相应的编译器选项为 <br>

  <br>

gcc:   -fpack-struct <br>

  <br>

Sun Workshop cc/CC:  -misalign <br>

  <br>

  <br>

  <br>

不过最好不好这样,这会大大降低程序的效率,特别在某些体系中. <br>

  <br>

应该尝试用位操作来处理. <br>

  <br>

  <br>

  <br>

  <br>

#ragama pack(1) <br>

  <br>

struct ..... <br>

  <br>

#pragama pack() <br>

  <br>

  <br>

  <br>

: 看你用什么编译器 <br>

  <br>

: gcc可以这么解决 <br>

  <br>

: #ifdef __GCC__ <br>

  <br>

: #define PACKED __attribute__((__packed__)) <br>

  <br>

: #else <br>

  <br>

: #define PACKED <br>

  <br>

: #endif <br>

  <br>

  <br>

: struct msg{ <br>

  <br>

:   u_int16_t PACKED first; <br>

  <br>

:   ... <br>

  <br>

: }; <br>

  <br>

: 不知道那个高手能有更简单的办法 <br>

  <br>

: 还是 VC简单 <br>

  <br>

: #include <pshpack1.h>就搞定了 <br>

  <br>

  <br>

  <br>

标题:Alignment Problem (#pragma pack (1) ) <br>

  <br>

  <br>

  <br>

Healing <healing@softteleware.com> <br>

  <br>

  <br>

  <br>

  <br>

I Found the solution. <br>

  <br>

  <br>

  <br>

cc -misalign  option is solution. <br>

  <br>

This supports 1 byte alignment.. <br>

  <br>

if this is set , do not sen bus error signal.. <br>

  <br>

  <br>

-- <br>

>>SCZ: <br>

你贴的sniffer程序和rain当时写的那个很像是一个,丢包有很多可能, <br>

sock_pakcet本身负载就大,过滤统统在用户空间完成,sniffer本身 <br>

处理不过来。网络负载太大,网卡驱动处理不过来。你的程序自己过滤 <br>

了什么,而你没有意识到。顺便问一句,你看过本版精华区里的那几个 <br>

sniffer吗? <br>

  <br>

看来还是没看懂对齐,那么什么是对齐,一个结构 <br>



  <br>

struct <br>

{ <br>

   u_char  a; <br>

   u_short b; <br>

   u_long  c; <br>

} <br>

  <br>

如果不对齐是什么情况,如果四字节对齐又是什么情况? <br>

你自己写个C程序,二进制dump它们看看。 <br>

  <br>

资料资料,又是资料,info gcc看看。说程序设计版讨论 <br>

过,估计你就再没有去看过当时的讨论,rain当时告诉我 <br>

info gcc看的。 <br>

>>SCZ: <br>

  <br>

********** <br>

: 我说的没看懂对齐,指的不是对齐本身,而是sniffer中 <br>

: ip=(((struct iphdr *)&eth;packet.ip)-2);不论怎样对齐, <br>

: ethpacket.ip总是指向ip这个成员对象,为什么还要减2 ? <br>

  <br>

sigh,什么叫不是对齐本身,偏偏就是对齐本身。 <br>



  <br>

叫你把那个struct按照二进制dump一下看看a、b、c <br>

三个的位置和你想象的是否一样,结果你又没有去实验,实在是 <br>

不知道该怎么说你了,恨得牙痒痒,总是不肯自己多实验点。有 <br>

你问这个的时间答案都出来了。 <br>

  <br>

为什么减2,因为对齐后b不在你想象的位置上,a占的空间也不是 <br>

1,而可能是2、4、8(根据编译器不同的对齐要求和不同的芯片), <br>

而那个程序(显然也不是你自己写的)里减2是因为他把一个字节数 <br>

组的首部强制转换成了结构指针,用结构来访问这个字节数组, <br>

对于编译器来说struct->a、struct->b可能对应的是char[0]、 <br>

char[4],你想象的却是char[0]、char[1]。 <br>

</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="317.htm">上一层</a>][<a href="437.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</table>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -