在BSD操作系统原始套接字 [英] Raw Sockets on BSD Operating Systems

查看:131
本文介绍了在BSD操作系统原始套接字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写在C一些插座code,我需要修改数据包报头和控制他们是如何发出的,所以我把原始套接字的方法。然而,code我写不会在BSD系统(Mac OS X中/达尔文,FreeBSD的,等等)

I've been writing some sockets code in C. I need modify packet headers and control how they're sent out, so I took the raw sockets approach. However, the code I wrote will not compile on BSD systems (Mac OS X/Darwin, FreeBSD, etc.)

我已经做了一堆研究这一点,并发现BSD系统不能处理原始套接字的方式Linux(甚至是Windows操作系统)。从我读过的东西,看来我需要使用BPF(伯克利包过滤器),但我想不通我是如何工作的BPF或如何会去使用它与原始套接字。

I've done a bunch of research on this and have found that BSD systems can't handle raw sockets the way Linux (or even Windows) does. From what I've read, it seems I need to use bpf (berkley packet filter), but I can't figure out how bpf works or how I would go about using it with raw sockets.

如果有人能在这一个闪耀光芒,我会非常激动:D

If someone could shed some light on this one, I'd be very excited :D

P.S。我甚至会发现一些源$ C ​​$ C显示原始套接字是如何在一个BSD环境中处理。它并不必须是一个导向或解释。我只是想看看它是如何工作的。

P.S. I'll even be happy with some source code showing how raw sockets are handled in a BSD environment. It doesn't have to be a guide or explanation. I just want to see how it works.

推荐答案

使用原始套接字并不难,但它不是的完全的便携性。举例来说,无论是在BSD和Linux中,您可以发送任何你想要的,但在BSD您无法接收任何有一个处理程序(如 TCP UDP )。

Using raw sockets isn't hard but it's not entirely portable. For instance, both in BSD and in Linux you can send whatever you want, but in BSD you can't receive anything that has a handler (like TCP and UDP).

下面是发送 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的解决方案可供选择。例如,你可以使用 转接(4) ,因为他们穿越你的系统,并改变它们的拦截数据包。

Of course, more BSD-specific solutions are available. For instance you could use divert(4) to intercept packets as they traverse your system and alter them.

这篇关于在BSD操作系统原始套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆