博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

原始套接字

Posted on 2015-02-26 09:56  bw_0927  阅读(286)  评论(0)    收藏  举报

http://blog.csdn.net/kzm2008/article/details/5372834

http://blog.csdn.net/kzm2008/article/details/5377117

http://bbs.chinaunix.net/thread-876233-1-1.html

 

 

1.原始套接字(raw socket)

  1.1 原始套接字工作原理与规则
         原始套接字是一个特殊的套接字类型,它的创建方式跟TCP/UDP创建方法几乎是
一摸一样,例如,通过

       int sockfd;
       sockfd = socktet(AF_INET, SOCK_RAW, IPPROTO_ICMP);

这两句程序你就可以创建一个原始套接字.然而这种类型套接字的功能却与TCP或者UDP类型套接字的功能有很大的不同:TCP/UDP类型的套接字 只能够访问传输层以及传输层以上的数据,因为当IP层把数据传递给传输层时,下层的数据包头已经被丢掉了.而原始套接字却可以访问传输层以下的数据,,所 以使用 raw套接字你可以实现上至应用层的数据操作,也可以实现下至链路层的数据操作.
         比如:通过

sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))

方式创建的raw socket就能直接读取链路层的数据.

 

什么是TCP/IPUDP

         TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。
         UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种。
        这里有一张图,表明了这些协议的关系。

                                                                               

                                                                        图1

       TCP/IP协议族包括运输层、网络层、链路层。现在你知道TCP/IP与UDP的关系了吧。
Socket在哪里呢?
       在图1中,我们没有看到Socket的影子,那么它到底在哪里呢?还是用图来说话,一目了然。

 



2

       原来Socket在这里。

Socket是什么呢?
       Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让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包的来源,这时候就可以使用raw 
socket来发送这些伪造源地址信息的包,这其实也是这种攻击所采用的主要技术
手段.当然了,我说的是HACKER行为,之所以想要处理这些特殊的IP包,通常也是
为了诊断网络的目的.

==================================================================================

于getsockopt()/setsockopt()函数的参数格式,相关的介绍很多,我只写设置缓冲区的形式:

SO_RCVBUF和SO_SNDBUF每个套接口都有一个发送缓冲区和一个接收缓冲区,使用这两个套接口选项可以改变缺省缓冲区大小。

// 接收缓冲区
int nRecvBuf=32*1024;         //设置为32K
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));

//发送缓冲区
int nSendBuf=32*1024;//设置为32K
setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));

注意:

当设置TCP套接口接收缓冲区的大小时,函数调用顺序是很重要的,因为TCP的窗口规模选项是在建立连接时用SYN与对方互换得到的。对于客户,SO_RCVBUF选项必须在connect之前设置;对于服务器,SO_RCVBUF选项必须在listen前设置。

===============================================

FTP是基于TCP协议的应用层协议,所以我们要能从传输层区分出TCP包和UDP包,但是,前面的规则已经讲到了,对于UDP或者TCP产生的IP层数 据包,内核将不会把它传递给任何原始套接字,而是交给对应的TCP/UDP处理函数,要能够让原始套接字接收UDP和TCP产生的IP数据包,或者说接收 传输层的UDP和TCP类型的数据,所创建的原始套接字必须为ETH_P_IP类型的,在程序里面体现出来就是将第三个参数指定为这个值.