2017-11-27 12 views
-1

Ich versuche, rohe Ethernet-Frames zu senden und zu empfangen, um ein Netzwerkgerät als Medienzugriffscontroller in einer Simulationsumgebung einzuschließen. Daher ist es wichtig, dass das Empfangen der Pakete durch nicht blockierende Anweisungen funktioniert.Ethernet-Framelänge auf Raw-Socket (nicht blockierend) erhalten

Jetzt funktioniert das Senden der rohen Ethernet-Frames, aber es gibt eine Sache über den Empfangspfad, der mich verwirrt: Woher weiß ich, wo der eine Frame endet und der andere Frame beginnt.

Was im Grunde ist ich tun, um eine Raw-Socket zu öffnen:

device.socket = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW); 

es sich als nicht blockierende Einstellung:

flags = fcntl(s,F_GETFL,0); 
assert(flags != -1); 
fcntl(s, F_SETFL, flags | O_NONBLOCK); 

und rufen dann die recv() Funktion zyklisch die Daten erhalten aus der Sockel:

Aber soweit ich weiß die recv() - Funktion gibt nur die Anzahl der Bytes zurück, das ist momentan im Empfangspuffer verfügbar und daher weiß ich nicht, ob ein anderer Frame startet oder ob ich noch das "alte" Paket lese.

Und wegen der Tatsache, dass die Länge des Ethernet-Rahmens nicht in der Kopfzeile enthalten ist, kann ich das nicht alleine machen.

Vielen Dank im Voraus!

+0

https://en.wikipedia.org/wiki/Ethernet_frame See. –

+0

Ich weiß, wie das Ethernet-Protokoll funktioniert, aber wie hilft mir das? Die einzige Information in der Kopfzeile ist der Typ, der die Länge des Rahmens enthalten kann, aber nicht notwendig wird! –

+0

Das Feld "EtherType" hat zwei Oktette mit der Payload-Länge. Damit können Sie die Gesamtbildgröße bestimmen. –

Antwort

0

Wenn jemand das gleiche Problem läuft in hier ist eine mögliche Lösung:

Sie können die libpcap-Bibliothek verwenden (in Windows winpcap) das Gerät als Aufnahmegerät zu öffnen:

char errbuf[PCAP_ERRBUF_SIZE];  /* error buffer */ 
Pcap_t *handle;      /* packet capture handle */ 

/* open capture device*/ 
/* max possible length, not in promiscous mode, no timeout!*/ 
handle = pcap_open_live(dev, 65536, 0, 0, errbuf); 
if (handle == NULL) { 
    fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf); 
} 

/* set capture device to non blocking*/ 
if(pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)){ 
    fprintf("Could not set pcap interface in non blocking mode: %s \n", errbuf); 
} 

Jetzt können Sie zyklischer Aufruf der pcap_dispatch Funktion Empfangspaket (e):

int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user); 

Sie haben eine Rückruffunktion zur Verfügung zu stellen, in dem die Daten umgegangen werden. Weitere Informationen finden Sie unter https://www.freebsd.org/cgi/man.cgi?query=pcap_dispatch&apropos=0&sektion=3&manpath=FreeBSD+11-current&format=html.

Sie können mithilfe der Funktion inject roh Ethernet-Frames senden:

pcap_inject(pcap,frame,sizeof(frame)); 
Verwandte Themen