当前位置:网站首页>Raw socket usage
Raw socket usage
2022-06-12 10:04:00 【wlf_ go】
One 、 What can a raw socket do ?
Usually, programmers connect to the socket they touch (Socket) There are two types :
- Streaming socket (SOCK_STREAM): A connection oriented Socket, For connection oriented TCP Service application ;
- Datagram socket (SOCK_DGRAM): A connectionless Socket, Corresponds to unconnected UDP Service application .
From the user's point of view ,SOCK_STREAM、SOCK_DGRAM These two types of sockets do seem to cover TCP/IP All of the applications , Because it is based on TCP/IP Application , At the protocol stack level , In the transport layer, it can only be built on TCP or UDP The agreement above , and SOCK_STREAM、SOCK_DGRAM And corresponding to TCP and UDP, Therefore, almost all applications can be implemented with these two types of sockets .

however , When we face the following problems ,SOCK_STREAM、SOCK_DGRAM Will appear so helpless :
1. How to send a custom IP package ?
2. How to send a ICMP Agreement package ?
3. How to analyze all packets passing through the network , And whether or not the bag was sent to you ?
4. How to disguise local IP Address ?
This makes us have to face another profound theme —— Raw socket (SOCK_RAW).
Raw sockets are widely used in advanced network programming , It is also a broad means of hacking . The famous Internet sniffer( A network analysis method based on the principle of passive interception )、 Denial of service attacks (DOS)、IP Spoofing and so on can be realized through the original socket . Raw socket (SOCK_RAW) It can be used to self assemble packets , It can receive all the data frames on the local network card ( Data packets ), It is very useful for monitoring network traffic and analyzing network data . The original socket is based on IP Packet programming (SOCK_PACKET It's based on data link layer programming ). in addition , You must have administrator privileges to use raw sockets . Raw socket (SOCK_RAW) With standard sockets (SOCK_STREAM、SOCK_DGRAM) The difference is that the original socket is set directly “ root ” At the core of the operating system network (Network Core), and SOCK_STREAM、SOCK_DGRAM be “ suspension ” On TCP and UDP The periphery of the agreement .

Streaming sockets can only send and receive TCP Protocol data , Datagram socket can only send and receive UDP Protocol data , The original socket can send and receive packets that are not processed by the kernel .
Two 、 Raw socket programming
Raw socket programming and before UDP Programming is almost , After creating a socket , Receive data or send data through this socket . The difference lies in , The raw socket can self assemble packets ( Camouflage local IP, Local MAC), It can receive all the data frames on the local network card ( Data packets ). in addition , You must have administrator privileges to use raw sockets .
The creation of the original socket :
int socket ( int family, int type, int protocol );
Parameters :
family: Protocol family Write here PF_PACKET
type: Socket class , Write here SOCK_RAW
protocol: Type of agreement , Specifies the type of packet that can be received or sent , Can't write “0”, The values are as follows , Be careful , You need to use
htons() Do byte order conversion .
ETH_P_IP:IPV4 Data packets
ETH_P_ARP:ARP Data packets
ETH_P_ALL: Packets of any protocol type
Return value :
success ( >0 ): Socket , Here is the socket of the link layer
Failure ( <0 ): error
Examples are as follows :
// Required header file
#include <sys/socket.h>
#include <netinet/ether.h>
#include <stdio.h> // perror
int main(int argc,charchar *argv[])
{
int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL) );
if(sock_raw_fd < 0){
perror("socket");
return -1;
}
return 0;
}【 Article Welfare 】 need C/C++ Linux Background server architect and audio and video learning materials plus group 812855908( The information includes C/C++,Linux,golang technology , kernel ,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK, Streaming media , Audio and video ,CDN,P2P,K8S,Docker,TCP/IP, coroutines ,DPDK,ffmpeg, Interview questions of Dachang etc. )

Get the packet function of the link layer :
ssize_t recvfrom( int sockfd, void *buf, size_t nbytes,
int flags, struct sockaddr *from,
socklen_t *addrlen );Parameters :
sockfd: Raw socket
buf: Receive data buffer
nbytes: The size of the receive data buffer
flags: Socket flag ( Often 0)
from: It's not useful here , Write NULL
addrlen: It's not useful here , Write NULL
Return value :
success : Number of characters received
Failure :-1
Examples are as follows :
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netinet/ether.h>
int main(int argc,charchar *argv[])
{
unsigned char buf[1024] = {0};
int sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
// Get the data packet of link layer
int len = recvfrom(sock_raw_fd, buf, sizeof(buf), 0, NULL, NULL);
printf("len = %d\n", len);
return 0;
}Hybrid mode
By default , We receive data , The destination address is a local address , Will receive . Sometimes we want to receive all the data streams that pass through the network card , Whether or not the destination address is it , At this time, we need to set the network card to hybrid mode .
The hybrid mode of network card is usually used by network administrator when analyzing network data as a means of network fault diagnosis , At the same time, this mode is also used by network hackers as the entrance of network data eavesdropping . stay Linux When setting network card hybrid mode in the operating system, administrator's permission is required . stay Windows Operating system and Linux The operating system has the use of hybrid mode packet capture tools , Like the famous open source software Wireshark.
By order to Linux Network card set hybrid mode ( Administrator privileges required )
Set hybrid mode :ifconfig eth0 promisc

Cancel hybrid mode :ifconfig eth0 -promisc

Give to by code Linux Network card set hybrid mode
The core code is as follows :
struct ifreq ethreq; // Network interface address
strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ); // Specify the network card name
if(-1 == ioctl(sock_raw_fd, SIOCGIFINDEX, ðreq)) // Get the network interface
{
perror("ioctl");
close(sock_raw_fd);
exit(-1);
}
ethreq.ifr_flags |= IFF_PROMISC;
if(-1 == ioctl(sock_raw_fd, SIOCSIFINDEX, ðreq)) // Network card set hybrid mode
{
perror("ioctl");
close(sock_raw_fd);
exit(-1);
}Send custom packets :
ssize_t sendto( int sockfd,const void *buf,
size_t nbytes,int flags,
const struct sockaddr *to,socklen_t addrlen );Parameters :
sockfd: Raw socket
buf: Send data buffer
nbytes: The size of the send data buffer
flags: It's usually 0
to: Local network interface , It refers to the network card from which the data should be sent out , Instead of the previous destination address
addrlen:to The length of the pointed content
Return value :
success : Number of characters to send data
Failure : -1
Send the complete code as follows :
struct sockaddr_ll sll; // Original socket address structure
struct ifreq ethreq; // Network interface address
strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ); // Specify the network card name
if(-1 == ioctl(sock_raw_fd, SIOCGIFINDEX, ðreq)) // Get the network interface
{
perror("ioctl");
close(sock_raw_fd);
exit(-1);
}
/* Assign the network interface to the original socket address structure */
bzero(&sll, sizeof(sll));
sll.sll_ifindex = ethreq.ifr_ifindex;
// send data
// send_msg, msg_len There is no definition here , Simulate
int len = sendto(sock_raw_fd, send_msg, msg_len, 0 , (struct sockaddr *)&sll, sizeof(sll));
if(len == -1)
{
perror("sendto");
}Here the header file is as follows :
#include <net/if.h>// struct ifreq
#include <sys/ioctl.h> // ioctl、SIOCGIFADDR
#include <sys/socket.h> // socket
#include <netinet/ether.h> // ETH_P_ALL
#include <netpacket/packet.h> // struct sockaddr_ll 3、 ... and 、 Original socket instance :MAC Header message analysis
I know from the above , We can use the original socket and recvfrom( ) You can get the data packets of the link layer , What kind of link layer packets do we receive ?
Link layer packet format

MAC Head ( Wired LAN )

Be careful :CRC、PAD It can be ignored when packaging
One of the cases of link layer packets :
unsigned char msg[1024] = {
//-------------- Group MAC--------14------
0xb8, 0x88, 0xe3, 0xe1, 0x10, 0xe6, // dst_mac: b8:88:e3:e1:10:e6
0xc8, 0x9c, 0xdc, 0xb7, 0x0f, 0x19, // src_mac: c8:9c:dc:b7:0f:19
0x08, 0x00, // type :0x0800 IP agreement
// …… ……
// …… ……
};Received link layer packets , And make a simple analysis of it :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ether.h>
int main(int argc,charchar *argv[])
{
int i = 0;
unsigned char buf[1024] = "";
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] = "";
// Get the data frame of link layer
recvfrom(sock_raw_fd, buf, sizeof(buf),0,NULL,NULL);
// from buf To extract the purpose of mac、 Source mac
sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x", buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);
// Judge whether it is IP Data packets
if(buf[12]==0x08 && buf[13]==0x00)
{
printf("______________IP The datagram _______________\n");
printf("MAC:%s >> %s\n",src_mac,dst_mac);
}// Judge whether it is ARP Data packets
else if(buf[12]==0x08 && buf[13]==0x06)
{
printf("______________ARP The datagram _______________\n");
printf("MAC:%s >> %s\n",src_mac,dst_mac);
}// Judge whether it is RARP Data packets
else if(buf[12]==0x80 && buf[13]==0x35)
{
printf("______________RARP The datagram _______________\n");
printf("MAC:%s>>%s\n",src_mac,dst_mac);
}
}
return 0;
}Remember to run the program with administrator privileges :

边栏推荐
- 【ParquetEncodingException: empty fields are illegal, the field should be ommited completely instead
- 003:what does AWS think is a data lake?
- Implementation of fruit mall wholesale platform based on SSM
- SAP HANA 错误消息 SYS_XSA authentication failed SQLSTATE - 28000
- How to implement Web3.0 and digital fashion?
- CentOS 7 installing MySQL 8
- 奇葩错误 -- 轮廓检测检测到边框、膨胀腐蚀开闭运算效果颠倒
- Spark complex structure data retrieval method
- 2021-02-12
- QQ, wechat chat depends on it (socket)?
猜你喜欢

SAP HANA 错误消息 SYS_XSA authentication failed SQLSTATE - 28000

Research on autojs wechat: the control IP in wechat on different versions of wechat or simulators is different.
![[cloud native] establishment of Eureka service registration](/img/da/0a700081be767db91edd5f3d49b5d0.png)
[cloud native] establishment of Eureka service registration

2026年中国软件定义存储市场容量将接近45.1亿美元

Auto. JS debugging: use the network mode of lightning simulator for debugging
![[cloud native] what exactly does it mean? This article shares the answer with you](/img/82/f268adcbdbe8195a066d065eb560d7.jpg)
[cloud native] what exactly does it mean? This article shares the answer with you

基于 Ceph 对象存储的实战兵法

极速搭建元宇宙画廊 #oncyber.io

MySQL v Index and algorithm

Explication du principe d'appariement le plus à gauche de MySQL
随机推荐
一文读懂Dfinity生态中的首个NFT平台:IMPOSSIBLE THINGS
2021-09-15
SAP HANA 错误消息 SYS_XSA authentication failed SQLSTATE - 28000
HALCON联合C#检测表面缺陷——仿射变换(三)
Shen Min, CIO of science and technology innovator Digital China Group: the best practice model is failing, and open source accelerates Distributed Innovation
《要领》读书笔记
postgresql 使用存储过程,拼接多张表,查询数据
2021-02-12
2026年中国软件定义存储市场容量将接近45.1亿美元
[cloud native] establishment of Eureka service registration
奇葩错误 -- 轮廓检测检测到边框、膨胀腐蚀开闭运算效果颠倒
There is always a negative line (upper shadow line) that will stop the advance of many armies, and there is always a positive line (lower shadow line) that will stop the rampant bombing of the air for
2021-03-26
004:aws data Lake solution
7-5 zhe zhe playing games
003:what does AWS think is a data lake?
在线电路仿真以及开源电子硬件设计介绍
Yarn scheduling
[path of system analyst] Chapter 18 security analysis and design of double disk system
原始套接字使用