linux:
// clang -o raw raw.c && ./raw
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#define BUFFER_SIZE 65536
int main(int argc, char *argv[])
{
printf("Starting raw socket\n");
int sockfd, n;
char buffer[BUFFER_SIZE];
struct sockaddr_in addr;
struct iphdr *ip_header;
// 创建 socket
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (sockfd < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
// 设置 socket 选项
int on = 1;
if (setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
// 绑定地址
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
exit(EXIT_FAILURE);
}
// 接收数据
printf("Waiting for packet\n");
while (1) {
n = recv(sockfd, buffer, BUFFER_SIZE, 0);
if (n < 0) {
perror("recv");
exit(EXIT_FAILURE);
}
// 解析 IP 头部
ip_header = (struct iphdr *)buffer;
printf("Received packet from %s\n", inet_ntoa(*(struct in_addr *)&ip_header->saddr));
}
return 0;
}