linux网络编程高级篇-原始套接字【简单的抓包实现】
程序员文章站
2022-04-02 23:09:25
一.原始套接字(SOCK_RAW)【比较偏向物联网方面了,但是还是介绍一下,有兴趣的可以了解一下】一种不同于 SOCK_STREAM, SOCK_DGRAM的套接字,它实现于系统核心。可以介绍本机网卡上所有的数据帧(数据包),对于监听网络流量和分析网络数据很有作用。开发人员可以发送自己组装的数据包【前面都介绍过相关的协议了】到网络上。广泛应用于高级网络编程。网络专家,黑客通常会用此来编写奇特的网络程序。流式套接字只能收发:TCP SCTP 协议的数据报式套接字只能收发: ......
一.原始套接字(SOCK_RAW)【比较偏向物联网方面了,但是还是介绍一下,有兴趣的可以了解一下】
- 一种不同于 SOCK_STREAM, SOCK_DGRAM的套接字,它实现于系统核心。
- 可以介绍本机网卡上所有的数据帧(数据包),对于监听网络流量和分析网络数据很有作用。
- 开发人员可以发送自己组装的数据包【前面都介绍过相关的协议了】到网络上。
- 广泛应用于高级网络编程。
- 网络专家,黑客通常会用此来编写奇特的网络程序。
流式套接字只能收发:TCP SCTP 协议的数据
报式套接字只能收发: UDP协议的数据
原始套接字可以收发:1.内核内核没有处理过的数据包,因此要访问其他协议,2.发送的数据需要使用,原始套接字(SOCK_RAW)3.收发函数用recvfrom sendto如图
就是这样 原始套接字直接从网卡拿数据 直接通过绿色通道过去。
二.原始套接字(SOCK_RAW)创建
int socket(PF_PACKET, SOCK_RAW, protocol)
功能:
创建链路层的原始套接字
参数:
protocol:指定可以接收或发送的数据包类型
ETH_P_IP: IPV4数据包
ETH_P_ARP: ARP数据包
ETH_P_ALL: 任何协议类型的数据包
返回值:
成功(>0):链路层套接字,失败(<0):出错
sock_raw_fd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
已过时,不再使用 sock_raw_fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL));
头文件:
#include <sys/socket.h>
#include <netinet/ether.h>
简单的抓包实现【代码Demo】
#include <iostream>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netinet/ether.h>
#include <unistd.h>
#include <stdio.h>
using namespace std;
int32_t
main(int argc, const char* argv[])
{
unsigned char buf[1519]; // 1518 + 1
int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
while(1) {
unsigned char src_mac[18] = "";
unsigned char dst_mac[18] = "";
recvfrom(sock_raw_fd, buf, sizeof(buf), 0, NULL, NULL);
//"%x:%x:%x:%x:%x:%x"
sprintf((char*)dst_mac, "%02x:%02x:%02x:%02x:%02x:%02x",
buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
// dst_mac[18] = '\0';
sprintf((char*)src_mac, "%02x:%02x:%02x:%02x:%02x:%02x",
buf[6],buf[7],buf[8],buf[9],buf[10],buf[11]);
// src_mac[18] = '\0';
printf("dst_mac: %s\nsrc_mac: %s\n", dst_mac, src_mac);
}
return 0;
}
效果:
本文地址:https://blog.csdn.net/qq_44065088/article/details/109240668