原始套接字SOCK_RAW

实际上,我们常用的网络编程都是在应用层的报文的收发操作,也就是大多数程序员接触到的流式套接字(SOCK_STREAM)和数据包式套接字(SOCK_DGRAM)。而这些数据包都是由系统提供的协议栈实现,用户只需要填充应用层报文即可,由系统完成底层报文头的填充并发送。然而在某些情况下需要执行更底层的操作,比如修改报文头、避开系统协议栈等。这个时候就需要使用其他的方式来实现。

一 原始套接字

原始套接字(SOCK_RAW)是一种不同于SOCK_STREAM、SOCK_DGRAM的套接字,它实现于系统核心。然而,原始套接字能做什么呢?首先来说,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。总体来说,SOCK_RAW可以处理普通的网络报文之外,还可以处理一些特殊协议报文以及操作IP层及其以上的数据。

既然SOCK_RAW有以上特性,所以在某些处理流程上它区别于普通套接字。

·  若设置IP_HDRINCL选项,SOCK_RAW可以操作IP头数据(也就是用户需用填充IP头及其以上的payload);否则SOCK_RAW无法操作IP头数据

·  端口对于SOCK_RAW而言没有任何意义

·  如果使用bind函数绑定本地IP,那么如果IP_HDRINCL未设置,则用此IP填充源IP地址;若不调用bind则将源IP地址设置为外出接口的主IP地址

·  如果使用connect函数设置目标IP,则可以使用send或者write函数发送报文,而不需要使用sendto函数

·  内核处理流程:

·   接收到的TCP、UDP分组不会传递给任何SOCK_RAW

·  ICMP、IGMP报文分组传递给SOCK_RAW

·  内核不识别的IP报文传递给SOCK_RAW

·  SOCK_RAW是否接收报文:

·      Protocol指定类型需要匹配,否则不传递给该SOCK_RAW

·       如果使用bind函数绑定了源IP,则报文目的IP必须和绑定的IP匹配,否则不传递给该SOCK_RAW

·       如果使用connect函数绑定了目的IP,则报文源IP必须和指定的IP匹配,否则不传递给该SOCK_RAW

综上所述,原始套接字处理的只是IP层及其以上的数据,比如实现SYN FLOOD攻击、处理PING报文等。当需要操作更底层的数据的时候,就需要采用其他的方式。

二 链路层处理报文

如果需要从链路层处理报文,那么就需要采用更加底层的套接字。还是先看下套接字函数的原型吧:

#include <sys/socket.h>

int socket(int domain, int type, int protocol);

这个函数中,domain表示协议簇,type表示套接字类型,而protocol表示的是处理的协议类型。在Linux下提供了多种底层套接字。下面分别进行简单介绍。

1 PF_INET协议簇

通过PF_INET可以构造原始套接字,如下所示:

int fd = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);

正如前面所讲的,它工作在IP层及其以上各层协议上(当然是在使用IP_HDRINCL选项之后才能操作IP层数据啦),但是这种套接字无法接收从本地发送出去的报文。而使用SOCK_PACKET类型的套接字,则可以操作链路层数据了:

int fd = socket (PF_INET, SOCK_PACKET, IPPROTO_TCP);

不过据说这种方式存在一定的缺陷,而且也不能保证后续版本的系统上一定支持这种方式,因此不推荐使用

2 PF_PACKET协议簇

PF_PACKET协议簇是用来取代SOCK_PACKET的一种编程接口。作为一种协议簇,它可以对应两种不同的套接字类型:SOCK_RAW和SOCK_DGRAM。当使用SOCK_RAW时,用户操作链路层数据,但是如果使用后者,则由系统处理链路层协议头。这种套接字支持四种协议(ETH_P_IP、ETH_P_ARP、ETH_P_RARP、ETH_P_ALL)(未确认)

int fd = socket (PF_PACKET, SOCK_RAW, IPPROTO_TCP);

int fd = socket (PF_PACKET, SOCK_DGRAM, IPPROTO_TCP);

3 NETLINK协议簇

这种方式是用户模式和kernel的IP网络配置之间的推荐接口

综上所述,真正能够实现操作链路层数据的只有三种方式:

int fd = socket (PF_INET, SOCK_PACKET, IPPROTO_TCP);

int fd = socket (PF_PACKET, SOCK_RAW, IPPROTO_TCP);

int fd = socket (PF_PACKET, SOCK_DGRAM, IPPROTO_TCP);

原始套接字SOCK_RAW的更多相关文章

  1. 原始套接字(SOCK_RAW)

    本文转载:http://www.cnblogs.com/duzouzhe/archive/2009/06/19/1506699.html,在此感谢 原始套接字(SOCK_RAW). 应用原始套接字,我 ...

  2. UNIX网络编程——原始套接字SOCK_RAW

    实际上,我们常用的网络编程都是在应用层的报文的收发操作,也就是大多数程序员接触到的流式套接字(SOCK_STREAM)和数据包式套接字(SOCK_DGRAM).而这些数据包都是由系统提供的协议栈实现, ...

  3. 浅谈原始套接字 SOCK_RAW 的内幕及其应用(port scan, packet sniffer, syn flood, icmp flood)

    一.SOCK_RAW 内幕 首先在讲SOCK_RAW 之前,先来看创建socket 的函数: int socket(int domain, int type, int protocol); domai ...

  4. 004.UDP--拼接UDP数据包,构造ip头和udp头通信(使用原始套接字)

    一.大致流程: 建立一个client端,一个server端,自己构建IP头和UDP头,写入数据(hello,world!)后通过原始套接字(SOCK_RAW)将包发出去. server端收到数据后,打 ...

  5. 原始套接字的简单tcp包嗅探

    原始套接字 sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_TCP); while(1) { data_size = recvfrom(sock_raw ...

  6. LINUX 网络编程 原始套接字

    一 原始套接字 原始套接字(SOCK_RAW)是一种不同于SOCK_STREAM.SOCK_DGRAM的套接字,它实现于系统核心.然而,原始套接字能做什么呢?首先来说,普通的套接字无法处理ICMP.I ...

  7. UNIX网络编程——原始套接字(dos攻击)

    原始套接字(SOCK_RAW).应用原始套接字,我们可以编写出由TCP和UDP套接字不能够实现的功能. 注意原始套接字只能够由有 root权限的人创建. 可以参考前面的博客<<UNIX网络 ...

  8. Linux网络编程:原始套接字简介

    Linux网络编程:原始套接字编程 一.原始套接字用途 通常情况下程序员接所接触到的套接字(Socket)为两类: 流式套接字(SOCK_STREAM):一种面向连接的Socket,针对于面向连接的T ...

  9. Linux Socket 原始套接字编程

    对于linux网络编程来说,可以简单的分为标准套接字编程和原始套接字编程,标准套接字主要就是应用层数据的传输,原始套接字则是可以获得不止是应用层的其他层不同协议的数据.与标准套接字相区别的主要是要开发 ...

随机推荐

  1. JS快速获取图片宽高的方法

    快速获取图片的宽高其实是为了预先做好排版样式布局做准备,通过快速获取图片宽高的方法比onload方法要节省很多时间,甚至一分钟以上都有可能,并且这种方法适用主流浏览器包括IE低版本浏览器. 我们一步一 ...

  2. tone mapping简介

    以下内容转自网络: tone Mapping原是摄影学中的一个术语,因为打印相片所能表现的亮度范围不足以表现现实世界中的亮度域,而如果简单的将真实世界的整个亮度域线性压缩到照片所能表现的亮度域内,则会 ...

  3. Js控制iFrame切换加载网址

    <html> <head> <title>Js控制 iFrame 切换加载网址</title> </head> <body> & ...

  4. linux 下安装ftp服务器

    最后重启    # service vsftpd restart   1.查看是否安装vsftp rpm -qa | grep ftp 如果出现    vsftpd-2.0.5-16.el5_5.1 ...

  5. Tip

    Windows 开栈命令 -Wl,--stack=1000000000 //stack-size B Linux 开栈命令 -ulimit -a -ulimit -s size //stack-siz ...

  6. 30 GroupSock(Port)——live555源码阅读(四)网络

    30 GroupSock(Port)——live555源码阅读(四)网络 30 GroupSock(Port)——live555源码阅读(四)网络 简介 Port类的定义 Port的构造与全局的 &l ...

  7. jQuery常用API

    jQuery API查询网址 http://jquery.cuishifeng.cn/ Dom和jquery相互装换 jquery对象[0] => Dom对象 Dom对象 => $(Dom ...

  8. treeiso

    主要包括了一些树同构的代码和一些树图生成器... download

  9. ios中json解析出现的null问题

    http://my.oschina.net/iq19900204/blog/408034 在iOS开发过程中经常需要与服务器进行数据通讯,Json就是一种常用的高效简洁的数据格式. 问题现象 但是几个 ...

  10. 《Head First Servlet JSP》学习笔记二

    一. 二. 三. 四. 五. 六. 七. 八. 九. 十. 十一. 十二.