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

linux 原始socket

Linux中的原始套接字(Raw Socket)是一种特殊的套接字类型,它允许应用程序直接访问网络层的数据包,而不经过传输层的处理。以下是关于原始套接字的基础概念、优势、类型、应用场景以及可能遇到的问题和解决方法。

基础概念

原始套接字提供了一种机制,使得应用程序可以直接发送和接收IP数据包。这意味着应用程序可以完全控制数据包的头部信息,包括IP头部和传输层协议头部(如TCP或UDP)。原始套接字通常用于实现一些高级网络功能,如网络抓包、自定义协议实现等。

优势

  1. 灵活性:应用程序可以完全控制数据包的格式和内容。
  2. 低层次访问:可以直接操作网络层和传输层的数据包。
  3. 自定义协议:适合实现一些非标准的或自定义的网络协议。

类型

  • IP层原始套接字:允许发送和接收IP数据包,但不解析传输层协议。
  • TCP层原始套接字:允许发送和接收TCP数据包。
  • UDP层原始套接字:允许发送和接收UDP数据包。

应用场景

  1. 网络抓包工具:如Wireshark,使用原始套接字捕获网络流量。
  2. 防火墙和入侵检测系统(IDS):通过分析原始数据包来检测异常行为。
  3. 自定义协议实现:如实现一些特定的网络应用或游戏协议。

示例代码

以下是一个简单的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>
#include <netinet/ip_icmp.h>

#define PACKET_SIZE 64

unsigned short calculate_checksum(unsigned short *buffer, int size) {
    unsigned long checksum = 0;
    while (size > 1) {
        checksum += *buffer++;
        size -= 2;
    }
    if (size) {
        checksum += *(unsigned char *)buffer;
    }
    checksum = (checksum >> 16) + (checksum & 0xffff);
    checksum += (checksum >> 16);
    return (unsigned short)(~checksum);
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        printf("Usage: %s <hostname>\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;
    dest_addr.sin_port = htons(0);
    inet_pton(AF_INET, argv[1], &dest_addr.sin_addr);

    char packet[PACKET_SIZE];
    memset(packet, 0, PACKET_SIZE);

    struct icmp *icmp = (struct icmp *)packet;
    icmp->icmp_type = ICMP_ECHO;
    icmp->icmp_code = 0;
    icmp->icmp_cksum = 0;
    icmp->icmp_id = getpid();
    icmp->icmp_seq = 1;

    memset(packet + sizeof(struct icmp), 'E', PACKET_SIZE - sizeof(struct icmp));
    icmp->icmp_cksum = calculate_checksum((unsigned short *)packet, PACKET_SIZE);

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

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

    close(sockfd);
    return 0;
}

可能遇到的问题和解决方法

  1. 权限问题:创建原始套接字通常需要root权限。
    • 解决方法:以root用户运行程序或使用setcap命令赋予程序必要的权限。
    • 解决方法:以root用户运行程序或使用setcap命令赋予程序必要的权限。
  • 数据包丢失:由于原始套接字直接操作网络层,可能会遇到数据包丢失的问题。
    • 解决方法:增加重传机制或优化网络环境。
  • IP头部校验和错误:手动构造IP头部时,可能会出现校验和错误。
    • 解决方法:确保正确计算和设置IP头部的校验和。

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

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

相关·内容

原始 socket 编程

原始套接字简介 普通 socket 的权力和原始 socket 权力对比。 1.原始 socket 可以和内核一样直接对所有层进行操作(除了物理层)。可以更改 mac 更改 ip 更改端口。...so dos 攻击就可以通过原始 socket 编程来伪造 ip 进行。 2.也可以访问经过网卡的所有数据.普通的 socket 只能访问发送给自己端口的数据。 ?...一种是处理IP层即其上的数据,通过指定socket第一个参数为AF_INET来创建这种套接字。有两种原始套接字。...另一种是处理数据链路层即其上的数据,通过指定socket第一个参数为AF_PACKET来创建这种套接字。 PF_PACKET支持SOCK_DGRAM和SOCK_RAW两种socket类型。...到linux/in.h看可以使用哪些传输层的协议 例子: socket(AF_INET, SOCK_RAW, IPPROTO_TCP|IPPROTO_UDP|IPPROTO_ICMP)发送接收ip数据包

2K20
  • 【Linux】: Socket 编程

    Socket 编程 6.1 socket 常见API Socket API 是一层网络编程接口,抽象了底层的网络协议,定义在 netinet/in.h 中。...实际上在网络上通信的时候套接字种类是比较多的,下面是常见的三种: unix 域间套接字编程--同一个机器内 原始套接字编程--网络工具 网络套接字编程--用户间的网络通信 设计者想将网络接口统一抽象化...--参数的类型必须是统一的,底层是一种多态的设计 运用场景: 网络套接字:运用于网络跨主机之间通信+本地通信 unix域间套接字: 本地通信 我们现在在使用网络编程通信时是应用层调传输层的接口,而原始套接字...Socket 接口 7.1 创建 Socket 文件描述符 在 TCP 和 UDP 通信中,首先要创建一个 Socket 文件描述符,它本质上是一个网络文件。...local.sin_addr.s_addr = INADDR_ANY; Listening Socket vs Connected Socket Listening Socket:服务器使用它来监听连接请求

    14010

    linux下socket编程

    Socket soket接口是TCP/IP网络的API。网络的socket数据传输是一种特别的I/O,socket也是一种文档描述符。...常用的socket类型有:流式socket(SOCK_STREAM)、数据报socket(SOCK_DGRAM)....其中流式socket是采用面向连接的TCP服务,而数据报socket则是无连接的UDP服务 Socket建立     调用: int socket(int domain, int type, int...type:指定socket的类型,分为:SOCK_STREAM(TCP)、SOCK_DGRAM(UDP),SOCK_RAW(原始socket,允许socket调用底层协议)     protocol:通常赋值为...收到连接请求时,socket执行体将建立一个新的socket,执行体将这个新socket和请求连接进程的地址联系起来,收到服务请求的初始socket仍能够继续在以前的 socket上监听,同时能够在新的

    4K70

    Linux Socket 收发Json

    如果对你有帮助,麻烦点个在看或点个赞,感谢~ 不管是Qt开发还是linux 嵌入式应用开发,一个人的核心竞争力还是不断思考,也就是不断琢磨。...下面的程序主要是Linux C Socket 读取JSON文件并传输,然后再写入文件,其中使用了cJSON库,关于cJSON库不过多介绍,主要介绍整体的思路。 1....Server 端 使用的是socket 阻塞式,没有使用select、poll、epoll等 接收端按照JSON格式解析数据,并提取感兴趣Key所对应的Value 程序功能挺快就可以做好,做完之后进行拆解...,将socket通信独立出来,JSON解析、写文件、响应客户端JSON数据等分别写成函数。...小结 编译JSON时需要链接linux的数学库 自己琢磨如何拆解函数功能 应用程序也主要是调用别人的api,那么你的核心竞争力是什么呢 ? 如需程序工程可在公众号后台留言。

    4.7K20

    Linux系统下socket编程socket接口介绍(二)

    前言 在上一篇文章里面我们介绍了TCP的三次握手和四次挥手过程的介绍以及网络编程里面的一些api接口函数的介绍——Linux系统下socket编程之socket接口介绍(一)。...函数介绍 - 发送和接收 - (1)send和write: 首先说明的一点,之前介绍的socket这个函数,非常类似我们之前介绍的open函数,他们都会返回一下文件描述符;所以这里的send函数和write...函数作用类似,我们用man手册来查看它的具体形式和用法: #include #include socket.h> ssize_t send(int...(这个转换完后不能用于网络传输,还需要调用htons或htonl函数才能将主机字节顺序转化为网络字节顺序,这两个函数先不讲,实战遇到的话,再进行解析),具体可以看下面Linux的源文: inet_aton...(2)struct sockaddr,这个结构体是linux的网络编程接口中用来表示IP地址的 标准结构体,bind、connect等函数中都需要这个结构体,这个结构体是兼容IPV4和IPV6的。

    3.8K20

    linux udp编程_linux中socket编程

    在前面的文件中,我们介绍了linux网络编程中与IP相关的知识和常用的函数总结,本文针对具体的UDP通信,来详细的介绍UDP通信的使用,包括UDP通信中的点对点通信,多播,广播等。...当然,在我们服务端创建socket后,主动往外发送一个数据,这样即使我们不进行绑定,我们依然可以收到数据,这只是系统通过我们的发送,自动的绑定了一个端口,这个并不是我们想要的,实际的使用中,也并不推荐这种方式...后,配置一下套接字,允许进行发送广播消息,上代码 int set_broadcast = 1; setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &set_broadcast...解决方法如下:(允许端口重用) int on = 1; ret = setsockopt(udp_net_sta.socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof...(int)); if (ret < 0) { perror("socket set SO_REUSEADDR failed"); } 2、服务端程序,在创建完socket后,有一个bind的操作

    11.1K10

    Linux C Socket Api详解

    套接字描述符 首先会先到的是文件描述符,对Linux一切皆文件的哲学又多懂了一点儿点儿。 套接字是通信端点的抽象。与应用程序使用文件描述符一样,访问套接字需要使用套接字描述符。...Linux系统是小端字节序。 2.2 地址格式 地址确定了特定通信域中的套接字端点,地址格式与特定的通信域相关。...注意:linux的man命令可以查看api的详细说明,而且还有例子,也挺不错的。 4....这个新的套接字描述符和原始套接字(sockfd)具有相同的套接字类型和地址族。传给accept的原始套接字没有关联到这个连接,而是继续保持可用状态并接受其他连接请求。...Linux Socket Server 与 Client 例子 个人觉得这只是套接字的入门,如果一个服务器要连接多个客户端呢?以后有机会和大家一起分享下select的套接字用法。

    5.6K10

    Linux的SOCKET编程详解

    Socket是什么 1、 socket套接字: socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –>...3、文件描述符和文件指针的区别: 文件描述符:在linux系统中打开文件就会获得文件描述符,它是个很小的正整数。...详细内容请看linux文件系统:http://blog.csdn.net/hguisu/article/details/6122513#t7 4....具体如何实现,可以看看linux的内核 4.1、socket()函数 int socket(int protofamily, int type, int protocol);//返回sockfd...socket函数对应于普通文件的打开操作。普通文件的打开操作返回一个文件描述字,而socket()用于创建一个socket描述符(socket descriptor),它唯一标识一个socket。

    2.6K10

    网络编程 - Linux Socket编程

    Linux Socket编程 ---- 目录 前言 Socket的功能 Socket基础 Socket类型 基本结构 基本转换函数 基本Socket使用 TCP Socket实例 UDP Socket实例...本篇不涉及太底层的网络原理,仅说明socket的基本使用方法。主要参考《Linux网络编程》。本篇源码获取方式见文底小字。...Socket基础 Socket类型   套接字有三种类型:流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM)和原始套接字。...原始套接字(SOCK_RAM)   原始套接字主要用于一些协议的开发,可以进行比较底层的操作。它功能强大,但是没有上面介绍的两种套接字使用方便,一般的程序也涉及不到原始套接字。...基本Socket使用   Linux同时支持面向连接和不连接类型的套接字。在面向连接的通讯中服务器和客户机在交换数据之前先要建立一个连接;在不连接通讯中数据被作为信息的一部分被交换。

    9.8K50
    领券