gpt4 book ai didi

c - BSD 操作系统上的原始套接字

转载 作者:太空狗 更新时间:2023-10-29 15:30:28 25 4
gpt4 key购买 nike

我一直在用 C 编写一些套接字代码。我需要修改数据包 header 并控制它们的发送方式,所以我采用了原始套接字方法。但是,我写的代码无法在 BSD 系统(Mac OS X/Darwin、FreeBSD 等)上编译。

我对此进行了大量研究,发现 BSD 系统无法像 Linux(甚至 Windows)那样处理原始套接字。从我读到的内容来看,我似乎需要使用 bpf(berkley 数据包过滤器),但我无法弄清楚 bpf 是如何工作的,也不知道我将如何将它与原始套接字一起使用。

如果有人能阐明这一点,我会非常兴奋 :D

附言我什至会对一些显示原始套接字在 BSD 环境中如何处理的源代码感到满意。它不一定是指南或解释。我只是想看看它是如何工作的。

最佳答案

使用原始套接字并不难,但它不是完全可移植的。例如,在 BSD 和 Linux 中你都可以发送你想要的任何东西,但在 BSD 中你不能接收任何有处理程序的东西(比如 TCPUDP)。

这是一个发送 SYN 的示例程序。

#include <sys/socket.h>
#include <sys/types.h>

#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>

#include <err.h>
#include <stdio.h>
#include <string.h>
#include <sysexits.h>

int
main(int argc, char *argv[])
{
int s, rc;
struct protoent *p;
struct sockaddr_in sin;
struct tcphdr tcp;

if (argc != 2)
errx(EX_USAGE, "%s addr", argv[0]);

memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = 0;

/* Parse command line address. */
if (inet_pton(AF_INET, argv[1], &sin.sin_addr) <= 0)
err(EX_USAGE, "Parse address");

/* Look up tcp although it's 6. */
p = getprotobyname("tcp");
if (p == NULL)
err(EX_UNAVAILABLE, "getprotobyname");

/* Make a new shiny (Firefly) socket. */
s = socket(AF_INET, SOCK_RAW, p->p_proto);
if (s < 0)
err(EX_OSERR, "socket");

memset(&tcp, 0, sizeof(tcp));

/* Fill in some random stuff. */
tcp.th_sport = htons(4567);
tcp.th_dport = htons(80);
tcp.th_seq = 4; /* Chosen by fair dice roll. */
tcp.th_ack = 0;
tcp.th_off = 5;
tcp.th_flags = TH_SYN;
tcp.th_win = htonl(65535);

rc = sendto(s, &tcp, sizeof(tcp), 0, (struct sockaddr *)&sin,
sizeof(sin));

printf("Wrote %d bytes\n", rc);

return 0;
}

当然,还有更多特定于 BSD 的解决方案可用。例如,您可以使用 divert(4) 在数据包穿过您的系统并更改它们时拦截它们。

关于c - BSD 操作系统上的原始套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7048448/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com