首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux 原始套接字将数据包

Linux原始套接字(Raw Socket)是一种允许应用程序直接与网络协议栈交互的套接字类型。通过原始套接字,应用程序可以发送和接收原始的网络数据包,而不经过操作系统内核的协议处理。以下是关于Linux原始套接字的基础概念、优势、类型、应用场景以及常见问题及其解决方法。

基础概念

原始套接字提供了一种直接访问网络层的方式,允许应用程序发送和接收未经过任何协议处理的IP数据包。这意味着你可以构造自己的IP头部,并且可以选择性地处理传输层的协议(如TCP或UDP)。

优势

  1. 灵活性:可以直接控制数据包的构造和处理。
  2. 低延迟:绕过内核协议栈,减少了处理时间。
  3. 协议定制:可以创建和使用自定义的网络协议。

类型

  • IP层原始套接字:允许发送和接收IP数据包,包括IP头部。
  • 链路层原始套接字:允许发送和接收以太网帧,包括MAC地址。

应用场景

  • 网络抓包工具:如Wireshark,使用原始套接字捕获网络流量。
  • 入侵检测系统(IDS):分析网络数据包以检测潜在的安全威胁。
  • 自定义协议实现:开发和测试新的网络协议。

示例代码

以下是一个简单的Linux原始套接字示例,用于发送一个ICMP Echo请求(Ping):

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define PACKET_SIZE 64

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <IP address>\n", argv[0]);
        exit(1);
    }

    int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    if (sockfd < 0) {
        perror("socket");
        exit(1);
    }

    struct sockaddr_in dest_addr;
    memset(&dest_addr, 0, sizeof(dest_addr));
    dest_addr.sin_family = AF_INET;
    inet_pton(AF_INET, argv[1], &dest_addr.sin_addr);

    char packet[PACKET_SIZE];
    memset(packet, 0, PACKET_SIZE);
    struct icmp *icmp_header = (struct icmp *)packet;
    icmp_header->icmp_type = ICMP_ECHO;
    icmp_header->icmp_code = 0;
    icmp_header->icmp_cksum = 0;
    icmp_header->icmp_id = getpid();
    icmp_header->icmp_sequence = 0;

    icmp_header->icmp_cksum = in_cksum((unsigned short *)icmp_header, PACKET_SIZE);

    if (sendto(sockfd, packet, PACKET_SIZE, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) < 0) {
        perror("sendto");
        close(sockfd);
        exit(1);
    }

    printf("ICMP Echo Request sent to %s\n", argv[1]);

    close(sockfd);
    return 0;
}

unsigned short in_cksum(unsigned short *addr, int len) {
    int nleft = len;
    int sum = 0;
    unsigned short *w = addr;
    unsigned short answer = 0;

    while (nleft > 1) {
        sum += *w++;
        nleft -= 2;
    }

    if (nleft == 1) {
        *(unsigned char *)(&answer) = *(unsigned char *)w;
        sum += answer;
    }

    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    answer = ~sum;
    return answer;
}

常见问题及解决方法

1. 权限问题

问题:创建原始套接字时可能会遇到权限不足的问题。 原因:通常需要root权限才能创建原始套接字。 解决方法:以root用户运行程序或使用sudo命令。

2. 数据包丢失

问题:发送的数据包没有收到预期的响应。 原因:可能是网络配置问题、防火墙阻止或目标主机未响应。 解决方法:检查网络连接,确保防火墙允许ICMP流量,并验证目标主机是否正常运行。

3. 数据包构造错误

问题:构造的数据包格式不正确,导致无法被正确解析。 原因:可能是IP头部或协议头部字段设置错误。 解决方法:仔细检查数据包构造代码,确保所有字段符合协议规范。

通过以上信息,你应该对Linux原始套接字有了全面的了解,并能够解决常见的使用问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

原始套接字 IP_HDRINCL 转

原始套接字可以访问ICMP和ICMP等协议包,可以读写内核不处理的IP数据包。可以创建自定义的IP数据包首部。一句话,使用原始套接字可以   编写基于IP协议的通讯程序。   ...IP协议第二个参数:SOCKET类型第三个参数:协议类型注意:@如果指定协议为0时,原始套接字可以接收内核传递给原始套接字的任何IP数据包,且只有超级用户才可以创建原始套接字。   ...@当需要编写自己的IP数据包首部时,可以在原始套接字上设置套接字选项IP_HDRINCL.在不设置这个选项的情况下,IP协议自动填充IP数据包的首部。   ...2.大多数ICMP数据包的一个拷贝传送给匹配的原始套接字。   3.内核处理的所有其它类型的数据包的一个拷贝都传给匹配的原始套接字。   ...在将一个IP数据包传送给原始套接字之前,内核需要选择匹配的原始套接字1.数据包的协议域必须与接收原始套接字的协议类型匹配。

2.4K10
  • 原始套接字和流量嗅探

    ---- 原始套接字和流量嗅探 前言 《Python黑帽子:黑客与渗透测试编程之道》的读书笔记,会包括书中源码,并自己将其中一些改写成Python3版本。...书是比较老了,anyway,还是本很好的书 本篇是第3章原始套接字和流量嗅探 1、Windows和Linux上的包嗅探 为了多平台使用,先创建SOCKET,再判断平台 windows允许嗅探所有协议 linux...coding:utf8 -*- import socket import os # 监听主机,即监听那个网络接口,下面的为我的kali的ip host = "10.10.10.145" # 创建原始套接字...socket.IPPROTO_ICMP sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol) #raw的中文是生的意思,大概就是原始套接字的意思吧...self.protocol_num] except: self.protocol = str(self.protocol_num) # 下面的代码类似于之前的例子 # 创建原始套接字

    1.8K20

    Go中原始套接字的深度实践

    介绍 原始套接字(raw socket)是一种网络套接字,允许直接发送/接收更底层的数据包而不需要任何传输层协议格式。...平常我们使用较多的套接字(socket)都是基于传输层,发送/接收的数据包都是不带TCP/UDP等协议头部的。...当使用套接字发送数据时,传输层在数据包前填充上面格式的协议头部数据,然后整个发送到网络层,接收时去掉协议头部,把应用数据抛给上层。...如果想自己封装头部或定义协议的话,就需要使用原始套接字,直接向网络层发送数据包。 为了便于后面理解,这里统一称应用数据为 payload,协议头部为 header,套接字为socket。...表示服务器之间的网络通信 syscall.AF_UNIX表示同一台机器上的进程通信 syscall.AF_INET6表示以IPv6的方式进行服务器之间的网络通信 其他 第二个参数 syscall.SOCK_RAW,表示使用原始套接字

    3K30

    《Python黑帽子》:原始套接字和流量嗅探

    在本文中,我们将使用原始套接字来访问诸如IP 和ICMP 头等底层的网络信息。在下面的例子中,我们只对IP 层和更高层感兴趣,因此我们不会去解码以太网头中的信息。...Windows 和Linux 上的包嗅探 在Windows 和Linux 上访问原始套接字有些许不同,但我们更中意于在多平台部署同样的嗅探器以实现更大的灵活性。...我们将先创建套接字对象,然后再判断程序在哪个平台上运行。在Windows 平台上,我们需要通过套接字输入/输出控制(IOCTL)1设置一些额外的标志,它允许在网络接口上启用混杂模式。...在第一个例子中,我们只需设置原始套接字嗅探器,读取一个数据包,然后退出即可。 首先,我们通过构建套接字对象对网络接口上的数据包嗅探进行必要的参数设置①。...如果你是在Linux 上运行的这段代码,那么你将接收到nostarch.com 的ICMP 响应包。仅嗅探一个数据包并没有多少实际用处,因此,我们将添加一些功能来处理更多的数据包并解码其中的内容。

    1.3K20

    CC++ 原生套接字抓取FTP数据包

    本文将深入介绍基于原始套接字的网络数据包捕获与分析工具,通过实时监控网络流量,实现抓取流量包内的FTP通信数据,并深入了解数据传输的细节,捕捉潜在的网络问题以及进行安全性分析。...原始套接字是一种底层的网络编程方式,允许程序直接访问网络协议栈,无需操作系统进行任何处理。在Windows平台,可以通过SOCK_RAW套接字类型来创建原始套接字。...本文的代码示例基于Winsock2库实现,允许我们以最底层的方式捕获网络数据包。 Winsock2库与套接字初始化 在使用原始套接字之前,我们首先需要初始化Winsock2库。...校验和字段用于检测数据包的完整性。 创建原始套接字 使用socket函数创建原始套接字,指定协议为IPPROTO_IP,表示接收所有的IP包。...= 0) return -1; // 创建原始套接字,过滤IP数据包 SOCKET SockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_IP);

    38910

    Linux网络套接字(二)

    返回值:返回一个新的套接字描述符。...首先是写出服务器的代码,代码的思路是这样的: ①首先为服务器创建套接字,因为这个是TCP协议,TCP是面向连接的,因此服务器是需要进入监听状态才能让客户端连接,所以使用socket接口创建出来的套接字是属于监听套接字...=2) { Usage(argv[0]); return 1; } //tcp_server //1.创建套接字,此套接字为监听套接字,用于绑定和监听 int listen_sock...=2) { Usage(argv[0]); return 1; } //tcp_server //1.创建套接字,此套接字为监听套接字,用于绑定和监听 int listen_sock...=2) { Usage(argv[0]); return 1; } //tcp_server //1.创建套接字,此套接字为监听套接字,用于绑定和监听 int listen_sock

    2K30

    Linux网络-套接字编程基础

    Linux网络编程套接字 零、前言 一、网络基础知识 1、源IP地址和目的IP地址 2、源MAC地址和目的MAC地址 3、认识端口号 4、PORT VS PID 5、TCP和UDP协议 6、网络字节序...二、socket编程接口 1、sockaddr结构 2、socket 常见API 零、前言 本章就Linux网络编程进行概念及接口学习,下一篇则是简单的进行上手网络套接字编程 一、网络基础知识 1...、源IP地址和目的IP地址 在数据传输时各网络协议栈会对数据进行报头封装,而在IP数据包头部中, 有两个IP地址, 分别叫做源IP地址, 和目的IP地址 网络中每台计算机都有一个唯一的IP地址,也就是说网络中用...结构 套接字不仅支持跨网络的进程间通信,还支持本地的进程间通信(域间套接字) 因此套接字提供了sockaddr_in结构体和sockaddr_un结构体,其中sockaddr_in结构体是用于跨网络通信的...,而sockaddr_un结构体是用于本地通信的 为了让套接字的网络通信和本地通信能够使用同一套函数接口,于是就出现了sockeaddr结构体,该结构体与sockaddr_in和sockaddr_un的结构都不相同

    1.5K20

    Linux网络-TCPUDP套接字编程

    零、前言 本章主要是对套接字网络编程的一个学习,目标是能够基本的进行套接字编程 一、UDP套接字 1、创建套接字 无论是服务端还是客户端,进行网络编程需要做的第一件事就是创建套接字 socket...使用命令行参数+网络字节序转化接口 local.sin_addr.s_addr=htons(INADDR_ANY);//云服务器不建议绑定明确的ip,建议使用INADDR_ANY绑定该主机所有设备 //将网络文件与套接字进行绑定...+网络字节序转化 local.sin_addr.s_addr=htons(INADDR_ANY);//云服务器不建议绑定明确的ip,建议使用INADDR_ANY绑定该主机所有设备 //将网络文件与套接字进行绑定...;小于0,则表示读取时遇到了错误 注:如果客户端将连接关闭了,那么此时服务端将套接字当中的信息读完后就会读取到0,不必再为该客户端提供服务了 write函数原型: ssize_t write(int...fd, const void *buf, size_t count); 解释: fd:特定的文件描述符,表示将数据写入该文件描述符对应的套接字 buf:需要写入的数据 count:需要写入数据的字节个数

    3.7K10

    Linux:网络编程套接字及UDP

    套接字的种类: 1、域间套接字(同一个机器内) struct sockaddr_un 2、原始套接字(网络工具)  原始套接字一般不关心传输层的东西,他一般是绕过传输层去考虑网络层和链路层,所以他一般被用来封装一些网络工具...类型 (1)我们先创建出来之后,然后可以用bzero(有点像C语言的memset)将指针内容先清空然后再填充 (2)local.sin_family  表明这个通用类型是属于网络套接字还是域间套接字 (...sizeof(local)); //将类型都清空 然后我们再填 local.sin_family=AF_INET;//family是用来表明这个类型是网络套接字还是域间套接字 local.sin_port...(可以获取客户端的ip和端口号) 2、将接受到的数据加工一下然后再发回给客户端  第五个和第六个是输入型数,通过客户端套接字信息将处理后的数据发送过去  当然,其实这里我们其实可以将这些数据交给一个回调函数去处理...首次发送数据的时候 2、用户输入数据,然后将数据和套接字类型发给服务端 3、从服务端将信息接收回来 代码:  #include #include #include

    11710

    Linux实验八:流式套接字编程

    二、实验内容 在网络环境中使用流式套接字完成以下内容:客户端进程 A 向服务器进程 B 发送一个字符,B进程将接收到 A 进程的字符,反之亦然。...接着,使用memset函数将buffer数组的所有元素初始化为0。创建一个 TCP 套接字,并将其文件描述符存储在listen_fd中。...将listen_fd套接字与指定的server_addr绑定,使服务器能够接收客户端连接请求。   然后,开始监听传入的连接请求,允许最多5个等待连接的队列。...接着使用read函数读取服务器的响应,将响应打印到控制台。   最后,在程序结束时关闭客户端套接字server_fd,释放资源。 步骤2....六、实验结果 运行结果如下: 七、实验总结   在本次实验中,我们深入学习了如何在Linux环境下使用流式套接字(TCP套接字)来进行客户端-服务器通信。

    10510

    【Linux】网络基础+UDP网络套接字编程

    地址确认出数据包的下一跳位置,所以数据包首先要进行以太网协议层的解包分用,将数据包交付给网络层的路由器,路由器会通过自己的路由表确定出数据包要发送的主机的ip地址,然后再向下进行封装,将数据包向下交付给指定...套接字编程中,常见的有网络套接字编程,原始套接字编程,unix域间套接字编程。 网络套接字支持多主机跨网络通信,下面讲到的都是这个套接字编程。...原始套接字比较难,它可以绕过传输层直接访问网络层以及下面的层,抓包和网络监测工具就是通过原始套接字来完成的,文章不谈论原始套接字和unix域间套接字,只谈论网络套接字编程。...unix域间套接字只能进行本地通信,无法进行网络通信,这个套接字只要在学习网络套接字过后,找篇unix域间套接字的相关源代码一看就能懂了。 3....第一个参数代表你创建套接字的域,是用inet网络套接字通信呢?又或是用unix域间套接字通信呢?

    40110

    Linux进程通信之Unix套接字(一)

    Linux进程通信之Unix套接字(一) 什么是套接字 所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。...一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。...) AF_INET6(IPV6) AF_UNIX(本地通讯协议,一般用于进程通信,不需要经过网卡) 套接字类型 流套接字(SOCK_STREAM),提供一个顺序化的、可靠的、全双工的、基于连接的字节流。...TCP 协议即基于这种流式套接字。 数据报套接字(SOCK_DGRAM)即提供数据报文的支持。(无连接,不可靠、固定最大长度).UDP协议即基于这种数据报文套接字。...原始套接字(SOCK_RAW)即提供读取原始的网络协议。这种特殊的套接字可用于手工构建任意类型的协议。一般使用这个套接字来实现 ICMP 请求(例如 ping)。

    2.8K30

    【Linux网络】Linux网络编程套接字,UDP与TCP

    在众多网络编程技术中,套接字(Socket)编程无疑是核心与基石,它不仅支撑着Web服务、即时通讯、在线游戏等日常应用,还是实现分布式系统、云计算服务的关键技术之一。...在套接字编程的世界里,UDP(用户数据报协议)与TCP(传输控制协议)如同双生子,各自以其独特的优势占据着不同的应用场景。...本文旨在深入探讨Linux环境下,如何通过套接字编程技术,驾驭UDP与TCP这两种强大的网络传输协议,从零开始构建基础的网络通信能力。...struct sockaddr *dest_addr, socklen_t addrlen); // 用于从套接字接收数据的方法,特别是在使用UDP协议进行数据传输时 ssize_t recvfrom...通过这段旅程,我们一同见证了从基础概念到实践应用的华丽蜕变,从最初的套接字创建、绑定、监听,到数据的发送与接收,每一步都充满了挑战与收获。

    16410

    Linux内核编程--网络协议与套接字编程

    类型描述SOCK_DGRAM数据报套接字SOCK_RAW原始套接字SOCK_SEQPACKET有序分组套接字SOCK_STREAM字节流套接字 --protocol参数:选择所给定domain和type...将套接字与地址关联--bind() bind()操作把一个本地协议地址和一个套接字进行了绑定,为了方便客户端根据地址找到服务器的位置。...如果调用connect()或listen(),但没有将地址绑定到套接字上,系统会选一个默认地址去绑定。 套接字地址的获得: a.可以调用getsockname()来发现绑定到套接字上的地址。...监听套接字--listen() 仅在套接字协议为TCP时调用listen(),调用listen()将导致套接字从CLOSED状态变为LISTEN状态。...https://www.binarytides.com/socket-programming-c-linux-tutorial/

    2.2K20

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

    真正从网卡进来的数据是完整的以太网帧,底层用sk_buff 数据结构描述,最终进入接收缓冲区recv buffer,而我们应用层调用read / recv /recvfrom 从接收缓冲区拷贝数据到应用层提供的buffer,对一般的套接字...0 , &saddr , &saddr_size);     //Now process the packet     ProcessPacket(buffer , data_size); } 即创建原始套接字...Error message : %s \n" , errno , strerror(errno));         exit(0);     } } 创建一个原始套接字s,开启IP_HDRINCL 选项...另开一个线程创建另一个原始套接字,仿照packet sniffer 进行数据包的接收,分解tcp 头部看是否syn == 1 && ack == 1 && dest_addr == src_addr,...如果不追求效率,很简单的做法是直接用普通的套接字,循环端口去connect,成功就表明端口是打开的,只是三次握手完整了一回。

    3.6K00
    领券