| Mark's profileMark's spacePhotosBlogLists | Help |
|
用java调用linux的操作系统命令import java.io.BufferedInputStream; import java.io.IOException; public class ExecLs { static public void main(String[] args) { String cmd = "ls" try { Process ps = Runtime.getRuntime().exec(cmds); System.out.print(loadStream(ps.getInputStream())); System.err.print(loadStream(ps.getErrorStream())); } catch(IOException ioe) { ioe.printStackTrace(); } } // read an input-stream into a String static String loadStream(InputStream in) throws IOException { int ptr = 0; in = new BufferedInputStream(in); StringBuffer buffer = new StringBuffer(); while( (ptr = in.read()) != -1 ) { buffer.append((char)ptr); } return buffer.toString(); } } May 14 有关raw socket的一些知识有关raw socket的一些知识
众所周知,通过socket编程,我们能够实现机器之间的通信.在TCP/IP协议簇(PF_INET)中,可以建立面向连接的SOCK_STREAM类型的socket,非连接的SOCK_DGRAM类型的socket.事实上,在所有的网络程序中,也是这两种socket用的最为广泛.除此之外,还有一些不常用的socket类型,它们却是在某些网络通信中担当重要的角色.这里要讲的就是这么一种socket,称之为raw socket.raw socket的作用主要在三个方面:
1.通过raw socket来接受发向本机的ICMP,IGMP协议包,或者用来发送这些协议包.
2.接受发向本机的但TCP/IP栈不能够处理的IP包.
3.用来发送一些自己制定源地址特殊作用的IP包(自己写IP头,TCP头等等)
我们知道,平时我们想看一看网络是否通达,就用ping命令测试一些.ping 命令用的是ICMP协议.因此,我们不能够通过建立一个SOCK_STREAM或SOCK_DGRAM来发送这个包,只能够自己亲自来构建ICMP包来发送.这是一种情况.另一种情况是:现在许多操作系统在实现网络部分的时候,通常只实现了常用的几种协议, 如tcp,udp,icmp等,但象其它的如ospf,ggp等协议,操作系统往往没有实现,如果自己有必要编写位于其上的应用,就必须借助raw socket来实现,这是因为操作 系统遇到自己不能够处理的数据包(ip头中的protocol所指定的上层协议不能处理).就将这个包交给raw socket.而最后一种使用raw socket的目的主要是用来构建一些特殊的协议头,比如我们想对某台机器进行denial of service类型的攻击,但是有不想留下痕迹,让别人知道IP包的来源,这时候就可以使用rawsocket来发送这些伪造源地址信息的包,这其实也是这种攻击所采用的主要技术手段.当然了,我说的是HACKER行为,之所以想要处理这些特殊的IP包,通常也是为了诊断网络的目的.
raw socket的建立是通过如下方式的:
sockfd = socket(PF_INET, SOCK_RAW, protocol);
第一个参数就不必讲了,第二个参数说明建立的是一个raw socket,第三个参数倒是需要详细解说一下.这里分三种情况:
1.参数protocol用来指明所要接收的协议包,如果是象IPPROTO_TCP(6)这种非0,非255的协议,则内核碰到ip头中 protocol域和创建socket所使用参数protocol相同的IP包,就会交给这个rawsocket来处理.因此,一般说来,要想接收什么样的数据包,就应该在参数protocol里来指定相应的协议.当内核向此raw socket交付数据包的时候,是包括整个IP头的,并且已经是重组好的IP包. 如下:
---------------------------------------------------------------
|ip header|tcp header(or x header)| data |
---------------------------------------------------------------
用recvfrom收到的数据包括一个IP头,一个相应的协议头,然后是数据(数据也可以为空,就看实际情况了). 但当我们发送IP包的时候,却不用亲自处理IP包头,只需要填充参数protocol所指定的相应的协议头即可.也就是说,用sendto的时候,我们提供给它的缓冲区数据是从IP包头的第一个字节开始,如下,只需要构造这么一个缓冲区就可以了.
--------------------------------------------------------------
|tcp header(or udp header or x header)| data |
--------------------------------------------------------------
如果想自己也想亲自处理IP头,则需要IP_HDRINCL的socket选项.如下:
int flag = 1;
setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &flag, sizeof(int));
这样,发送时所要提供的缓冲区有成如下形式:
---------------------------------------------------------------
|ip header|tcp header(or x header)| data |
---------------------------------------------------------------
但是,即时是这种情况,在我们发送IP包的时候.也不是填充ip头的所有字段,而是应该将ip头的id(identification)字段设置为0,表示让内核来处理这个字段.同时,内核还帮你完成ip头的校验和的计算,并随后填充check字段.
2.如果protocol是IPPROTO_RAW(255),这时候,这个socket只能用来发送IP包,而不能接收任何数据.发送的数据需要自己填充IP包头,并且自己计算校验和.
3.对于protocol为0(IPPROTO_IP)的raw socket. 在linux和sco unix上是不允许建立的.我没有再试过其他操作系统,谁能给我一个答案:)
对于raw socket,只有root权限才能够创建.
这里对raw socket总结一下: 当内核接收到IP包的时候,首先检查ip包的protocol域,当存在与此域匹配的raw socket时,就将包先传给此raw socket,然后交给相应的上层协议处理.交给raw socket的数据是包括IP头并且已经重组完成后的.当使用raw socket发送包的时候,如果raw socket创建时的protocol不是0或255,并且没有设置IP_HDRINCL选项,则发送的数据不包括IP头.如果此选项置位,则需要自己构件IP头.如果创建protocol为255的raw socket,此rawsocket只能用来发送包括IP头,自己构建IP包.
附录:
IP头结构:
struct iphdr
|-------|--------|---------------|-------------------------------|
|version| ihl | tos | tot_len |
|-------|--------|---------------|-------------------------------|
| id | | frag_off |
|----------------|---------------|-------------------------------|
| ttl | protocol | check |
|----------------|---------------|-------------------------------|
| saddr |
|----------------------------------------------------------------|
| daddr |
|----------------------------------------------------------------|
参考书籍:
Unix Network Programming (Volume 1 SECOND EDITION P655-P702) April 04 nesC ModuleModule 问题 ledi 发表于 2006-5-16 19:29:00 接口PeriodicReaderC: March 20 BNF范式和EBNF范式BNF范式和EBNF范式关键字: BNF 范式1、什么是BNF范式,什么又是EBNF范式?(在学习中经常会碰到用BNF范式描述的规则,老是忘记每个符号确切的作用,现在把他们一一罗列如下,亲手记录的东西应该能记住吧。。。-__-|||) 答:巴科斯范式及其扩展(BNF & Augmented BNF) 1)巴科斯范式:巴科斯范式(BNF: Backus-Naur Form 的缩写)是由 John Backus 和 Peter Naur 首先引入的用来描述计算机语言语法的符号集。现在,几乎每一位新编程语言书籍的作者都使用巴科斯范式来定义编程语言的语法规则。 2)巴科斯范式的内容: 在双引号中的字("word")代表着这些字符本身。而double_quote用来代表双引号。 在双引号外的字(有可能有下划线)代表着语法部分。 < > : 内包含的为必选项。 [ ] : 内包含的为可选项。 { } : 内包含的为可重复0至无数次的项。 | : 表示在其左右两边任选一项,相当于"OR"的意思。 ::= : 是“被定义为”的意思 3)扩展的巴科斯范式(Augmented BNF):RFC2234 定义了扩展的巴科斯范式(ABNF)。近年来在Internet的定义中ABNF被广泛使用。ABNF做了更多的改进,比如说,在ABNF中,尖括号不再需要。 4)EBNF的基本内容: "..." : 术语符号 [...] : 选项:最多出现一次 {...} : 重复项: 任意次数,包括 0 次 (...) : 分组 | : 并列选项,只能选一个 斜体字: 参数,在其它地方有解释 例子BNF应用较多,以下给出一个简单例子,这是用BNF来定义的Java语言中的For语句的实例: FOR_STATEMENT ::= "for" "(" ( variable_declaration | ( expression ";" ) | ";" ) [ expression ] ";" [ expression ] ";" ")" statement August 26 java的转义字符\n 回车(\u000a) 上周发现还有其它需要转义的字符,例如 String sName = "Java转义字符(补遗)"; 如果你以为会输出“Java转义字符”,那你就错了,事实上输出“Java转义字符()”,我也很奇怪,以为是中英文括号的问题,可是并不是,我不确定是否转义问题,解决方法是 sName = sName.replaceFirst("\\(补遗\\)",""); April 23 MRTG流量监控MRTG (Multi Router Traffic Grapher)是一款监控网络流量负载的免费软件,目前利用MRTG已经开发出了各式各样的统计系统: |
|||
|
|