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;
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.