预览加载中,请您耐心等待几秒...
1/8
2/8
3/8
4/8
5/8
6/8
7/8
8/8

在线预览结束,喜欢就下载吧,查找使用更方便

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

Linux网络编程:原始套接字编程及实例分析 一、原始套接字能干什么? 通常情况下程序员接所接触到的套接字(Socket)为两类: (1)流式套接字(SOCK_STREAM):一种面向连接的Socket,针对于面向连接的TCP服务应用; (2)数据报式套接字(SOCK_DGRAM):一种无连接的Socket,对应于无连接的UDP服务应用。 从用户的角度来看,SOCK_STREAM、SOCK_DGRAM这两类套接字似乎的确涵盖了TCP/IP应用的全部,因为基于TCP/IP的应用,从协议栈的层次上讲,在传输层的确只可能建立于TCP或UDP协议之上,而SOCK_STREAM、SOCK_DGRAM又分别对应于TCP和UDP,所以几乎所有的应用都可以用这两类套接字实现。 但是,当我们面对如下问题时,SOCK_STREAM、SOCK_DGRAM将显得这样无助: (1)怎样发送一个自定义的IP包? (2)怎样发送一个ICMP协议包? (3)怎样分析所有经过网络的包,而不管这样包是否是发给自己的? (4)怎样伪装本地的IP地址? 这使得我们必须面对另外一个深刻的主题——原始套接字(SOCK_RAW)。原始套接字广泛应用于高级网络编程,也是一种广泛的黑客手段。著名的网络sniffer(一种基于被动侦听原理的网络分析方式)、拒绝服务攻击(DOS)、IP欺骗等都可以通过原始套接字实现。 原始套接字(SOCK_RAW)可以用来自行组装数据包,可以接收本机网卡上所有的数据帧(数据包),对于监听网络流量和分析网络数据很有作用。 原始套接字是基于IP数据包的编程(SOCK_PACKET是基于数据链路层的编程)。另外,必须在管理员权限下才能使用原始套接字。 原始套接字(SOCK_RAW)与标准套接字(SOCK_STREAM、SOCK_DGRAM)的区别在于原始套接字直接置“根”于操作系统网络核心(NetworkCore),而SOCK_STREAM、SOCK_DGRAM则“悬浮”于TCP和UDP协议的外围。 流式套接字只能收发TCP协议的数据,数据报套接字只能收发UDP协议的数据,原始套接字可以收发内核没有处理的数据包。 二、原始套接字编程 原始套接字编程和之前的UDP编程差不多,无非就是创建一个套接字后,通过这个套接字接收数据或者发送数据。区别在于,原始套接字可以自行组装数据包(伪装本地IP,本地MAC),可以接收本机网卡上所有的数据帧(数据包)。另外,必须在管理员权限下才能使用原始套接字。 原始套接字的创建: intsocket(intfamily,inttype,intprotocol); 参数: family:协议族这里写PF_PACKET type:套接字类,这里写SOCK_RAW protocol:协议类别,指定可以接收或发送的数据包类型,不能写“0”,取值如下,注意,传参时需要用htons()进行字节序转换。 ETH_P_IP:IPV4数据包 ETH_P_ARP:ARP数据包 ETH_P_ALL:任何协议类型的数据包 返回值: 成功(>0):套接字,这里为链路层的套接字 失败(<0):出错 实例如下: //所需头文件 #include<sys/socket.h> #include<netinet/ether.h> #include<stdio.h>//perror intmain(intargc,charchar*argv[]) { intsock_raw_fd=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL)); if(sock_raw_fd<0){ perror("socket"); return-1; } return0; } 获取链路层的数据包: ssize_trecvfrom(intsockfd, void*buf, size_tnbytes, intflags, structsockaddr*from, socklen_t*addrlen); 参数: sockfd:原始套接字 buf:接收数据缓冲区 nbytes:接收数据缓冲区的大小 flags:套接字标志(常为0) from:这里没有用,写NULL addrlen:这里没有用,写NULL 返回值: 成功:接收到的字符数 失败:-1 实例如下: #include<stdio.h> #include<netinet/in.h> #include<sys/socket.h> #include<netinet/ether.h> intmain(intargc,charchar*argv[]) { unsignedcharbuf[1024]={0}; intsock_raw_fd=socket(PF_PACKET,SOCK_RAW,htons(