A Guide to Using Raw Sockets(翻译)

2024-01-04 19:08
文章标签 翻译 using raw guide sockets

本文主要是介绍A Guide to Using Raw Sockets(翻译),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在本教程中,让我们来看一看,原始套接字如何被用来绕过传统的TCP/IP协议栈,接收数据包,然后把那些数据包发送给特定的用户程序。

如果你不具备Linux内核相关的知识,但是对网络报文的内容感兴趣,那么原始套接字就是你所需要的。一个原始套接字是用来接收原始报文的。这意味着在以太层接收到的报文将会直接传递给原始套接字。准确地说,一个原始套接字绕过通常的TCP/IP处理过程,将报文发送给特定的用户程序。
原始套接字图示

原始套接字 vs 其他套接字

其他套接字,例如字节流套接字和数据报套接字,从传输层接收数据。这些数据不包含头部(header),只包含净荷(payload)。这意味着,没有关于源IP地址和MAC地址的信息。运行在同一台机器或不同机器上的程序在通信时,只能交换数据。

原始套接字的用途是完全不同的。原始套接字允许程序直接访问更低层的协议。这意味着原始套接字接收未提取(un-extracted)的报文。与字节流/数据报套接字不同,没有必要给一个原始套接字提供端口和IP地址。
原始套接字 vs 其他套接字

网络报文与报文嗅探器

当一个应用程序向网络中发送数据时,数据会被许多的网络层次处理。在发送数据之前,它会被网络层次的各种头部包裹。包含所有的信息,例如原地址和目的地址,的被包裹的数据,被称为网络报文。根据以太网协议,有许多不同种类的网络报文,例如IP报文,Xerox PUP报文,Ethernet Loopback报文等。在Linux中,可以再if_ether.h中找到所有的协议。

网络报文的通用表示
IP报文
当我们连接到因特网时,我们接收网络报文,我们的机器提取所有的网络层头部,将数据发送给特定的的程序。例如,当我们在浏览器中输入www.google.com时,我们收到来自Google的报文,我们的机器提取所有的头部,将数据传送给浏览器。

默认情况下,一台机器只会接受目的地之是它自己的报文,这种模式成为非混杂(Non-promiscuous)模式。但是,如果我们想要接收所有的报文,我们就必须切换到混杂(Promiscuous)模式。通过使用ioctl,我们可以切换到混杂模式。

如果我们对不同网络层次头部的内容或者结构感兴趣,我们可以借助报文嗅探器来访问这些信息。在Linux中有许多可用的报文嗅探器,例如Wireshark、tcpdump。

一个使用原始套接字的报文嗅探器

要开发一个报文嗅探器,首先要打开一个原始套接字。只有effective user ID是0或者具有CAP_NET_RAW能力的进程才被允许打开原始套接字。

打开一个原始套接字

要打开一个套接字,要知道三样东西

  • 协议族
  • 类型
  • 协议

对于一个原始套接字,协议族是AF_PACKET,协议类型是SOCK_RAW,协议请参看if_ether.h头文件。要接受所有报文,可以将协议设置为宏ETH_P_ALL;要接受所有IP报文,可以将协议设置为宏ETH_P_IP。

int sock_r;
sock_r = socket(AP_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if(sock_r < 0)
{printf("error in socket\n");return -1;
}
/* Note: run this program as root user* Author:Subodh Saxena */
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<signal.h>
#include<stdbool.h>
#include<sys/socket.h>
#include<sys/types.h>#include<linux/if_packet.h>
#include<netinet/in.h>		 
#include<netinet/if_ether.h>    // for ethernet header
#include<netinet/ip.h>		// for ip header
#include<netinet/udp.h>		// for udp header
#include<netinet/tcp.h>
#include<arpa/inet.h>           // to avoid warning at inet_ntoaFILE* log_txt;
int total,tcp,udp,icmp,igmp,other,iphdrlen;struct sockaddr saddr;
struct sockaddr_in source,dest;void ethernet_header(unsigned char* buffer,int buflen)
{struct ethhdr *eth = (struct ethhdr *)(buffer);fprintf(log_txt,"\nEthernet Header\n");fprintf(log_txt,"\t|-Source Address	: %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",eth->h_source[0],eth->h_source[1],eth->h_source[2],eth->h_source[3],eth->h_source[4],eth->h_source[5]);fprintf(log_txt,"\t|-Destination Address	: %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",eth->h_dest[0],eth->h_dest[1],eth->h_dest[2],eth->h_dest[3],eth->h_dest[4],eth->h_dest[5]);fprintf(log_txt,"\t|-Protocol		: %d\n",eth->h_proto);}void ip_header(unsigned char* buffer,int buflen)
{struct iphdr *ip = (struct iphdr*)(buffer + sizeof(struct ethhdr));iphdrlen =ip->ihl*4;memset(&source, 0, sizeof(source));source.sin_addr.s_addr = ip->saddr;     memset(&dest, 0, sizeof(dest));dest.sin_addr.s_addr = ip->daddr;     fprintf(log_txt , "\nIP Header\n");fprintf(log_txt , "\t|-Version              : %d\n",(unsigned int)ip->version);fprintf(log_txt , "\t|-Internet Header Length  : %d DWORDS or %d Bytes\n",(unsigned int)ip->ihl,((unsigned int)(ip->ihl))*4);fprintf(log_txt , "\t|-Type Of Service   : %d\n",(unsigned int)ip->tos);fprintf(log_txt , "\t|-Total Length      : %d  Bytes\n",ntohs(ip->tot_len));fprintf(log_txt , "\t|-Identification    : %d\n",ntohs(ip->id));fprintf(log_txt , "\t|-Time To Live	    : %d\n",(unsigned int)ip->ttl);fprintf(log_txt , "\t|-Protocol 	    : %d\n",(unsigned int)ip->protocol);fprintf(log_txt , "\t|-Header Checksum   : %d\n",ntohs(ip->check));fprintf(log_txt , "\t|-Source IP         : %s\n", inet_ntoa(source.sin_addr));fprintf(log_txt , "\t|-Destination IP    : %s\n",inet_ntoa(dest.sin_addr));
}void payload(unsigned char* buffer,int buflen)
{int i=0;unsigned char * data = (buffer + iphdrlen  + sizeof(struct ethhdr) + sizeof(struct udphdr));fprintf(log_txt,"\nData\n");int remaining_data = buflen - (iphdrlen  + sizeof(struct ethhdr) + sizeof(struct udphdr));for(i=0;i<remaining_data;i++){if(i!=0 && i%16==0)fprintf(log_txt,"\n");fprintf(log_txt," %.2X ",data[i]);}fprintf(log_txt,"\n");}void tcp_header(unsigned char* buffer,int buflen)
{fprintf(log_txt,"\n*************************TCP Packet******************************");ethernet_header(buffer,buflen);ip_header(buffer,buflen);struct tcphdr *tcp = (struct tcphdr*)(buffer + iphdrlen + sizeof(struct ethhdr));fprintf(log_txt , "\nTCP Header\n");fprintf(log_txt , "\t|-Source Port          : %u\n",ntohs(tcp->source));fprintf(log_txt , "\t|-Destination Port     : %u\n",ntohs(tcp->dest));fprintf(log_txt , "\t|-Sequence Number      : %u\n",ntohl(tcp->seq));fprintf(log_txt , "\t|-Acknowledge Number   : %u\n",ntohl(tcp->ack_seq));fprintf(log_txt , "\t|-Header Length        : %d DWORDS or %d BYTES\n" ,(unsigned int)tcp->doff,(unsigned int)tcp->doff*4);fprintf(log_txt , "\t|----------Flags-----------\n");fprintf(log_txt , "\t\t|-Urgent Flag          : %d\n",(unsigned int)tcp->urg);fprintf(log_txt , "\t\t|-Acknowledgement Flag : %d\n",(unsigned int)tcp->ack);fprintf(log_txt , "\t\t|-Push Flag            : %d\n",(unsigned int)tcp->psh);fprintf(log_txt , "\t\t|-Reset Flag           : %d\n",(unsigned int)tcp->rst);fprintf(log_txt , "\t\t|-Synchronise Flag     : %d\n",(unsigned int)tcp->syn);fprintf(log_txt , "\t\t|-Finish Flag          : %d\n",(unsigned int)tcp->fin);fprintf(log_txt , "\t|-Window size          : %d\n",ntohs(tcp->window));fprintf(log_txt , "\t|-Checksum             : %d\n",ntohs(tcp->check));fprintf(log_txt , "\t|-Urgent Pointer       : %d\n",tcp->urg_ptr);payload(buffer,buflen);fprintf(log_txt,"*****************************************************************\n\n\n");
}void udp_header(unsigned char* buffer, int buflen)
{fprintf(log_txt,"\n*************************UDP Packet******************************");ethernet_header(buffer,buflen);ip_header(buffer,buflen);fprintf(log_txt,"\nUDP Header\n");struct udphdr *udp = (struct udphdr*)(buffer + iphdrlen + sizeof(struct ethhdr));fprintf(log_txt , "\t|-Source Port    	: %d\n" , ntohs(udp->source));fprintf(log_txt , "\t|-Destination Port	: %d\n" , ntohs(udp->dest));fprintf(log_txt , "\t|-UDP Length      	: %d\n" , ntohs(udp->len));fprintf(log_txt , "\t|-UDP Checksum   	: %d\n" , ntohs(udp->check));payload(buffer,buflen);fprintf(log_txt,"*****************************************************************\n\n\n");}void data_process(unsigned char* buffer,int buflen)
{struct iphdr *ip = (struct iphdr*)(buffer + sizeof (struct ethhdr));++total;/* we will se UDP Protocol only*/ switch (ip->protocol)    //see /etc/protocols file {case 6:++tcp;tcp_header(buffer,buflen);break;case 17:++udp;udp_header(buffer,buflen);break;default:++other;}printf("TCP: %d  UDP: %d  Other: %d  Toatl: %d  \r",tcp,udp,other,total);}int main()
{int sock_r,saddr_len,buflen;unsigned char* buffer = (unsigned char *)malloc(65536); memset(buffer,0,65536);log_txt=fopen("log.txt","w");if(!log_txt){printf("unable to open log.txt\n");return -1;}printf("starting .... \n");sock_r=socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL)); if(sock_r<0){printf("error in socket\n");return -1;}while(1){saddr_len=sizeof saddr;buflen=recvfrom(sock_r,buffer,65536,0,&saddr,(socklen_t *)&saddr_len);if(buflen<0){printf("error in reading recvfrom function\n");return -1;}fflush(log_txt);data_process(buffer,buflen);}close(sock_r);// use signals to close socket printf("DONE!!!!\n");}
/* Note: run this program as root user* Author:Subodh Saxena */
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<errno.h>#include<sys/socket.h>
#include<sys/types.h>
#include<sys/ioctl.h>#include<net/if.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<netinet/if_ether.h>
#include<netinet/udp.h>#include<linux/if_packet.h>#include<arpa/inet.h>
struct ifreq ifreq_c,ifreq_i,ifreq_ip; /// for each ioctl keep diffrent ifreq structure otherwise error may come in sending(sendto )
int sock_raw;
unsigned char *sendbuff;#define DESTMAC0	0xd0#define DESTMAC1	0x67#define DESTMAC2	0xe5#define DESTMAC3	0x12#define DESTMAC4	0x6f#define DESTMAC5	0x8f#define destination_ip 10.240.253.10int total_len=0,send_len;void get_eth_index()
{memset(&ifreq_i,0,sizeof(ifreq_i));strncpy(ifreq_i.ifr_name,"wlan0",IFNAMSIZ-1);if((ioctl(sock_raw,SIOCGIFINDEX,&ifreq_i))<0)printf("error in index ioctl reading");printf("index=%d\n",ifreq_i.ifr_ifindex);}void get_mac()
{memset(&ifreq_c,0,sizeof(ifreq_c));strncpy(ifreq_c.ifr_name,"wlan0",IFNAMSIZ-1);if((ioctl(sock_raw,SIOCGIFHWADDR,&ifreq_c))<0)printf("error in SIOCGIFHWADDR ioctl reading");printf("Mac= %.2X-%.2X-%.2X-%.2X-%.2X-%.2X\n",(unsigned char)(ifreq_c.ifr_hwaddr.sa_data[0]),(unsigned char)(ifreq_c.ifr_hwaddr.sa_data[1]),(unsigned char)(ifreq_c.ifr_hwaddr.sa_data[2]),(unsigned char)(ifreq_c.ifr_hwaddr.sa_data[3]),(unsigned char)(ifreq_c.ifr_hwaddr.sa_data[4]),(unsigned char)(ifreq_c.ifr_hwaddr.sa_data[5]));printf("ethernet packaging start ... \n");struct ethhdr *eth = (struct ethhdr *)(sendbuff);eth->h_source[0] = (unsigned char)(ifreq_c.ifr_hwaddr.sa_data[0]);eth->h_source[1] = (unsigned char)(ifreq_c.ifr_hwaddr.sa_data[1]);eth->h_source[2] = (unsigned char)(ifreq_c.ifr_hwaddr.sa_data[2]);eth->h_source[3] = (unsigned char)(ifreq_c.ifr_hwaddr.sa_data[3]);eth->h_source[4] = (unsigned char)(ifreq_c.ifr_hwaddr.sa_data[4]);eth->h_source[5] = (unsigned char)(ifreq_c.ifr_hwaddr.sa_data[5]);eth->h_dest[0]    =  DESTMAC0;eth->h_dest[1]    =  DESTMAC1;eth->h_dest[2]    =  DESTMAC2;eth->h_dest[3]    =  DESTMAC3;eth->h_dest[4]    =  DESTMAC4;eth->h_dest[5]    =  DESTMAC5;eth->h_proto = htons(ETH_P_IP);   //0x800printf("ethernet packaging done.\n");total_len+=sizeof(struct ethhdr);}void get_data()
{sendbuff[total_len++]	=	0xAA;sendbuff[total_len++]	=	0xBB;sendbuff[total_len++]	=	0xCC;sendbuff[total_len++]	=	0xDD;sendbuff[total_len++]	=	0xEE;}void get_udp()
{struct udphdr *uh = (struct udphdr *)(sendbuff + sizeof(struct iphdr) + sizeof(struct ethhdr));uh->source	= htons(23451);uh->dest	= htons(23452);uh->check	= 0;total_len+= sizeof(struct udphdr);get_data();uh->len		= htons((total_len - sizeof(struct iphdr) - sizeof(struct ethhdr)));}unsigned short checksum(unsigned short* buff, int _16bitword)
{unsigned long sum;for(sum=0;_16bitword>0;_16bitword--)sum+=htons(*(buff)++);do{sum = ((sum >> 16) + (sum & 0xFFFF));}while(sum & 0xFFFF0000);return (~sum);}void get_ip()
{memset(&ifreq_ip,0,sizeof(ifreq_ip));strncpy(ifreq_ip.ifr_name,"wlan0",IFNAMSIZ-1);if(ioctl(sock_raw,SIOCGIFADDR,&ifreq_ip)<0){printf("error in SIOCGIFADDR \n");}printf("%s\n",inet_ntoa((((struct sockaddr_in*)&(ifreq_ip.ifr_addr))->sin_addr)));/****** ORint i;for(i=0;i<14;i++)printf("%d\n",(unsigned char)ifreq_ip.ifr_addr.sa_data[i]); ******/struct iphdr *iph = (struct iphdr*)(sendbuff + sizeof(struct ethhdr));iph->ihl	= 5;iph->version	= 4;iph->tos	= 16;iph->id		= htons(10201);iph->ttl	= 64;iph->protocol	= 17;iph->saddr	= inet_addr(inet_ntoa((((struct sockaddr_in *)&(ifreq_ip.ifr_addr))->sin_addr)));iph->daddr	= inet_addr("destination_ip"); // put destination IP addresstotal_len += sizeof(struct iphdr); get_udp();iph->tot_len	= htons(total_len - sizeof(struct ethhdr));iph->check	= htons(checksum((unsigned short*)(sendbuff + sizeof(struct ethhdr)), (sizeof(struct iphdr)/2)));}int main()
{sock_raw=socket(AF_PACKET,SOCK_RAW,IPPROTO_RAW);if(sock_raw == -1)printf("error in socket");sendbuff=(unsigned char*)malloc(64); // increase in case of large data.Here data is --> AA  BB  CC  DD  EEmemset(sendbuff,0,64);get_eth_index();  // interface numberget_mac();get_ip();struct sockaddr_ll sadr_ll;sadr_ll.sll_ifindex = ifreq_i.ifr_ifindex;sadr_ll.sll_halen   = ETH_ALEN;sadr_ll.sll_addr[0]  = DESTMAC0;sadr_ll.sll_addr[1]  = DESTMAC1;sadr_ll.sll_addr[2]  = DESTMAC2;sadr_ll.sll_addr[3]  = DESTMAC3;sadr_ll.sll_addr[4]  = DESTMAC4;sadr_ll.sll_addr[5]  = DESTMAC5;printf("sending...\n");while(1){send_len = sendto(sock_raw,sendbuff,64,0,(const struct sockaddr*)&sadr_ll,sizeof(struct sockaddr_ll));if(send_len<0){printf("error in sending....sendlen=%d....errno=%d\n",send_len,errno);return -1;}}}

https://opensourceforu.com/2015/03/a-guide-to-using-raw-sockets/

这篇关于A Guide to Using Raw Sockets(翻译)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/570310

相关文章

论文翻译:arxiv-2024 Benchmark Data Contamination of Large Language Models: A Survey

Benchmark Data Contamination of Large Language Models: A Survey https://arxiv.org/abs/2406.04244 大规模语言模型的基准数据污染:一项综述 文章目录 大规模语言模型的基准数据污染:一项综述摘要1 引言 摘要 大规模语言模型(LLMs),如GPT-4、Claude-3和Gemini的快

论文翻译:ICLR-2024 PROVING TEST SET CONTAMINATION IN BLACK BOX LANGUAGE MODELS

PROVING TEST SET CONTAMINATION IN BLACK BOX LANGUAGE MODELS https://openreview.net/forum?id=KS8mIvetg2 验证测试集污染在黑盒语言模型中 文章目录 验证测试集污染在黑盒语言模型中摘要1 引言 摘要 大型语言模型是在大量互联网数据上训练的,这引发了人们的担忧和猜测,即它们可能已

excel翻译软件有哪些?如何高效提翻译?

你是否曾在面对满屏的英文Excel表格时感到头疼?项目报告、数据分析、财务报表... 当这些重要的信息被语言壁垒阻挡时,效率和理解度都会大打折扣。别担心,只需3分钟,我将带你轻松解锁excel翻译成中文的秘籍。 无论是职场新人还是老手,这一技巧都将是你的得力助手,让你在信息的海洋中畅游无阻。 方法一:使用同声传译王软件 同声传译王是一款专业的翻译软件,它支持多种语言翻译,可以excel

MonoHuman: Animatable Human Neural Field from Monocular Video 翻译

MonoHuman:来自单目视频的可动画人类神经场 摘要。利用自由视图控制来动画化虚拟化身对于诸如虚拟现实和数字娱乐之类的各种应用来说是至关重要的。已有的研究试图利用神经辐射场(NeRF)的表征能力从单目视频中重建人体。最近的工作提出将变形网络移植到NeRF中,以进一步模拟人类神经场的动力学,从而动画化逼真的人类运动。然而,这种流水线要么依赖于姿态相关的表示,要么由于帧无关的优化而缺乏运动一致性

linux dlopen手册翻译

名称 dlclose, dlopen, dlmopen 打开和关闭一个共享对象 简介 #include <dlfcn.h>void *dlopen(const char*filename, int flags);int dlclose(void *handle);#define _GNU_SOURCE#include <dlfcn.h>void *dlmoopen(Lmid_t lm

从计组中从重温C中浮点数表示及C程序翻译过程

目录 移码​编辑  传统浮点表示格式 浮点数的存储(ieee 754)->修炼内功 例子:   ​编辑 浮点数取的过程   C程序翻译过程 移码  传统浮点表示格式 浮点数的存储(ieee 754)->修炼内功 根据国际标准IEEE(电⽓和电⼦⼯程协会)  32位 例子:    64位    IEEE754对有效数字M和

论文精读-Supervised Raw Video Denoising with a Benchmark Dataset on Dynamic Scenes

论文精读-Supervised Raw Video Denoising with a Benchmark Dataset on Dynamic Scenes 优势 1、构建了一个用于监督原始视频去噪的基准数据集。为了多次捕捉瞬间,我们手动为对象s创建运动。在高ISO模式下捕获每一时刻的噪声帧,并通过对多个噪声帧进行平均得到相应的干净帧。 2、有效的原始视频去噪网络(RViDeNet),通过探

HumanNeRF:Free-viewpoint Rendering of Moving People from Monocular Video 翻译

HumanNeRF:单目视频中运动人物的自由视点绘制 引言。我们介绍了一种自由视点渲染方法- HumanNeRF -它适用于一个给定的单眼视频ofa人类执行复杂的身体运动,例如,从YouTube的视频。我们的方法可以在任何帧暂停视频,并从任意新的摄像机视点或甚至针对该特定帧和身体姿势的完整360度摄像机路径渲染主体。这项任务特别具有挑战性,因为它需要合成身体的照片级真实感细节,如从输入视频中可能

深度评测热门翻译工具,携手你的翻译得力助手

随着互联网技术的飞速发展,全球化交流日益频繁,跨语言沟通的需求也随之激增。对于外语水平有限的朋友来说,翻译器是一个必不可少的工具。今天我就分享几款我用的翻译器吧。 1.福晰在线翻译  链接直达>>https://fanyi.pdf365.cn/doc  该网站以其高度的专业性著称,专为翻译需求而精心打造。它不仅支持用户粘贴部分文字进行即时翻译,更贴心地提供了整份PDF文档的导入翻译功能,极大

idea中配置Translation插件完成翻译功能

文章目录 idea下载插件配置有道云阿里云百度翻译开放平台 idea下载插件 idea中安装Translation插件 使用方法:右下角选择翻译引擎,鼠标选中想翻译的部分,右键翻译即可 之前一直用的微软的翻译,不需要配置,但是最近微软服务器总是抽风,无法使用,故打算配置一下国内的翻译服务。 配置 有道云 只有初始的一点额度,用完就要收费了,不推荐