2011-08-13 9 views
4

私はCでソケットコードを書いています。パケットヘッダを変更して送信する方法を制御する必要があるので、rawソケットアプローチをとっています。しかし、私が書いたコードはBSDシステム(Mac OS X/Darwin、FreeBSDなど)でコンパイルされません。BSDオペレーティングシステムのRawソケット

私はこのことについてたくさんの研究をしており、BSDシステムではrawソケットLinux(あるいはWindows)のやり方。私が読んだところでは、bpf(berkley packet filter)を使う必要があるようですが、bpfがどのように動作するか、あるいはrawソケットでどのように使用するかはわかりません。

誰かがこの1にいくつかの光を当てることができれば、私は非常に興奮するだろう:D

P.S.私はBSD環境でrawソケットをどのように扱うかを示すソースコードに満足しています。それはガイドまたは説明である必要はありません。私はちょうどそれがどのように動作するか見たいです。

答えて

5

rawソケットの使用は難しくありませんが、は完全にではありません。たとえば、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)を使って、パケットを横断してシステムを横断してパケットを変更することができます。

+0

ありがとうございました。あなたはちょうど私の日を作った:) – GhostCode

関連する問題