利用socket raw抓包

RAW SOCKET能够对较低层次的协议直接访问,网络监听技术很大程度上依赖于它。该文介绍了利用RAW SOCKET捕获网络底层数据包的步骤和方法

【原理】网卡对数据帧进行硬过滤(根据网卡的模式不同采取不同的操作,如果设置了混杂模式,则不做任何过滤直接交给下一层,否则非本机mac或者广播mac的会被直接丢弃)。在进入ip层之前,系统会检查系统中是否有通过socket(AP_PACKET,SOCK_RAW,…)创建的套接字,如果有并且协议相符,系统就给每个这样的socket接收缓冲区发送一个数据帧的拷贝。如果数据的校验和出错的话,内核直接丢弃该数据包,而不会拷贝给sock_raw的套接字。

创建套接字

发送接收ip数据包

socket(AF_INET, SOCK_RAW, IPPROTO_TCP|IPPROTO_UDP|IPPROTO_ICMP) 

发送接收以太网数据帧

socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL)) 

使用SOCK_RAW发送接受的数据包含链路层的协议头。

设置网卡混杂模式
struct ifreq ifr;
strcpy(ifr.ifr_name, "eth0");
ifr.ifr_flags |= IFF_PROMISC;
ioctl(sock, SIOCGIFFLAGS, ifr);

SIOCGIFFLAGS, SIOCSIFFLAGS 读取 或 设置 设备的 活动标志字

设备标志
IFF_UP接口正在运行.
IFF_BROADCAST有效的广播地址集.
IFF_DEBUG内部调试标志.
IFF_LOOPBACK这是自环接口.
IFF_POINTOPOINT这是点到点的链路接口.
IFF_RUNNING资源已分配.
IFF_NOARP无arp协议, 没有设置第二层目的地址.
IFF_PROMISC接口为杂凑(promiscuous)模式.
IFF_NOTRAILERS避免使用trailer .
IFF_ALLMULTI接收所有组播(multicast)报文.
IFF_MASTER主负载平衡群(bundle).
IFF_SLAVE从负载平衡群(bundle).
IFF_MULTICAST支持组播(multicast).
IFF_PORTSEL可以通过ifmap选择介质(media)类型.
IFF_AUTOMEDIA自动选择介质.
IFF_DYNAMIC接口关闭时丢弃地址.
抓包
recvfrom(sock, buffer, BUF_SIZE, 0, NULL, NULL)

最后两个参数置为NULL,表示不绑定地址,来了的数据包都接收

示例代码
#include<stdio.h>
#include<net/if.h>
#include<netinet/in.h>
#include<netinet/ether.h>
#include<netinet/tcp.h>
#include<netinet/ip.h>
#include<netinet/udp.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/ioctl.h>

int main(int argc, char *argv[])
{
    int socketfd;
    ssize_t recvlen;
    unsigned char buffer[1024];
    
    socketfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (socketfd < 0)
    {
        print("sock create fail!\n");
        return socketfd;
    }
    
    int id = 1;
    while (1)
    {
        recvlen = recvfrom(socketfd, buffer, sizeof(buffer), 0, NULL, NULL);
        if (recvlen < 42)
        {
            continue;
        }
        
        int i = 0;
        
        print("id: %d\n",id);
        for (i; i < sizeof(buffer); i++)
        {
            print(" %02x",buffer[i]);
             if ((i + 1) % 16 == 0)
            {
                print("\n");
            }
       }
       id ++;
       print("\n\n");
   }
}

运行结果截图:
在这里插入图片描述

然后就可以根据ethernet,ip,tcp等各协议头部字段对报文进行解析,
例如:这个报文的前6个字节目的mac:
在这里插入图片描述
接下来的6个字节源mac:
在这里插入图片描述
再接下来的两个字节为3层协议类型:
在这里插入图片描述
0x0800 即 IP协议

以太网头部就解析完成,接下来的报文就是ip头部了,以此类推。

具体解析过程详情附代码可参照另一篇使用libpcap抓包文章。
https://blog.csdn.net/Sophisticated_/article/details/83339483

  • 2
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的使用 socket 抓包的 C 代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/tcp.h> #define BUFFER_SIZE 65536 void print_packet(unsigned char* buffer, int size) { struct iphdr *iph = (struct iphdr*)buffer; unsigned short iphdrlen = iph->ihl * 4; struct tcphdr *tcph = (struct tcphdr*)(buffer + iphdrlen); printf("Source IP: %s\n", inet_ntoa(*(struct in_addr*) &iph->saddr)); printf("Destination IP: %s\n", inet_ntoa(*(struct in_addr*) &iph->daddr)); printf("Source Port: %d\n", ntohs(tcph->source)); printf("Destination Port: %d\n", ntohs(tcph->dest)); printf("Data: "); for(int i = iphdrlen + tcph->doff * 4; i < size; i++) { printf("%c", buffer[i]); } printf("\n\n"); } int main() { int sock_raw = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); if(sock_raw < 0) { printf("Socket creation error\n"); return 1; } unsigned char buffer[BUFFER_SIZE]; int buffer_len; while(1) { buffer_len = recvfrom(sock_raw, buffer, BUFFER_SIZE, 0, NULL, NULL); if(buffer_len < 0) { printf("Packet receive error\n"); return 1; } print_packet(buffer, buffer_len); } close(sock_raw); return 0; } ``` 该程序使用原始套接字(raw socket)来监听所有传入的 TCP 数据包。当接收到一个数据包时,程序会打印出源 IP 地址、目标 IP 地址、源端口、目标端口以及数据内容。 请注意,使用原始套接字需要在 root 权限下运行。另外,这只是一个简单的示例,实际使用时需要考虑更多的细节和安全问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值