Linux: Beim senden von Ethernet-frames das ethertype wird neu geschrieben

Ich geschrieben habe ein C-Programm, das schreiben von Ethernet-frames direkt auf den Draht (die läuft in zwei Modi, dem Absender oder Empfänger). Der sender schickt die Rahmen mit zwei VLAN-tags auf Sie (QinQ), aber seltsam, wenn der frame erreicht den Empfänger das ethertype-hat sich zu einem standard (single) VLAN gekapselt Rahmen. Ist es möglich, die Netzwerkkarte ist, dies zu tun, oder macht Linux das nicht möglich? Wireshark zeigt das gleiche Verhalten wie tcpdump.

Erklären das Bild unten, der sender sendet Rahmen an die Ethernet-broadcast-Adresse FF:FF:FF:FF:FF:FF zu finden, die den Empfänger (dies sind die beiden test-Maschinen verbunden über ein crossover-Kabel, aber das Ergebnis unten ist das gleiche mit einem switch oder hub). Wie Sie sehen können die frames kommen in zwei VLAN-tags auf Sie, der äußere tag hat ein ethertype von 0x8100 und eine VLAN-ID von 40, die innere VLAN hat ethertype 0x8100 und eine VLAN-ID des 20. Wie wir alle wissen, obwohl, mit QinQ Rahmen in den äußeren Rahmen sollte ein ethertype von 0x88a8!

Wenn die frames gesendet werden, der Absender in meiner Anwendung haben Sie den äußeren ethertype von 0x88a8 aber gemäß dem Bild unten sind Sie erhalten mit 0x8100 auf sowohl den inneren und äußeren ethertypes. Der markierte text wird der Empfänger sendet zurück, eine Antwort, wie Sie sehen können die frames haben 0x88a8 auf den äußeren Rahmen und 0x8100 auf der inneren. tcpdump auf der anderen Maschine zeigt das gleiche (es ist derselbe code! Frames werden gesendet mit 0x88a8 äußeren 0x8100 inneren aber immer erhalten, wie 0x8100 äußeren und 0x8100 innen).

Linux: Beim senden von Ethernet-frames das ethertype wird neu geschrieben

void BuildHeaders(char* &txBuffer, unsigned char (&destMAC)[6], 
     unsigned char (&sourceMAC)[6], short &PCP, short &vlanID,
     short &qinqID, short &qinqPCP, int &headersLength)
{

int offset = 0;

short TPI = 0;
short TCI = 0;
short *p = &TPI;
short *c = &TCI;
short vlanIDtemp;

//Copy the destination and source MAC addresses
memcpy((void*)txBuffer, (void*)destMAC, ETH_ALEN);
memcpy((void*)(txBuffer+ETH_ALEN), (void*)sourceMAC, ETH_ALEN);
offset = (ETH_ALEN*2);

//Add on the QinQ Tag Protocol Identifier
vlanIDtemp = qinq
TPI = htons(0x88a8); //0x88a8 == IEEE802.1ad, 0x9100 == older IEEE802.1QinQ
memcpy((void*)(txBuffer+offset), p, 2);
offset+=2;

//Now build the QinQ Tag Control Identifier:
TCI = (qinqPCP & 0x07) << 5;
qinqID = qinqID >> 8;
TCI = TCI | (qinqID & 0x0f);
qinqID = vlanIDtemp;
qinqID = qinqID << 8;
TCI = TCI | (qinqID & 0xffff);

memcpy((void*)(txBuffer+offset), c, 2);
offset+=2;

//VLAN headers
vlanIDtemp = vlanID;
TPI = htons(0x8100);
memcpy((void*)(txBuffer+offset), p, 2);
offset+=2;

TCI = (PCP & 0x07) << 5;
vlanID = vlanID >> 8;
TCI = TCI | (vlanID & 0x0f);
vlanID = vlanIDtemp;
vlanID = vlanID << 8;
TCI = TCI | (vlanID & 0xffff);

memcpy((void*)(txBuffer+offset), c, 2);
offset+=2;

//Push on the Ethertype (IPv4) for the payload
TPI = htons(0x0800);
memcpy((void*)(txBuffer+offset), p, 2);
offset+=2;

headersLength = offset;

}

sendResult = sendto(sockFD, txBuffer, fSizeTotal, 0, (struct sockaddr*)&socket_address, sizeof(socket_address));
  • Verwenden ethtool um sicherzustellen, dass alle VLAN-Verschiebung ist deaktiviert, auf Ihre Netzwerkkarte(N). Auch, wie sind Sie zur Eröffnung sockFD?
  • sockFD = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
  • Ich werde prüfen, die ethtool Ausgabe nächste chance, die ich erhalten und zu aktualisieren.
  • Deaktivieren tx-vlan-offloading und rx-vlan-offloading mit ethtool auf beiden Maschinen noch nicht ändern, das Verhalten, aber das hat mir einige Denkanstöße. Ich verwendet sudo ethtool -K eth0 rxvlan off && sudo ethtool -K eth0 txvlan off - ich werde weiter stöbern ethtool, obwohl, und sehen, was ich finden kann.
  • die Adresse ist nicht geroutet (auf einem anderen Subnetz befindet) ist es?
  • Nein, es ist Ethernet 🙂
  • Wie pro meine post die zwei macines sind verbunden über ein crossover-Kabel, und gemäß der obigen Kommentare ethrool untersucht worden ist für den VLAN-Verschiebung - Bitte versuchen Sie es und Lesen Sie, was andere gelesen haben, die erste 🙂
  • Das problem tritt auf, weil der Linux-kernel verbraucht der 802.1 AD header (0x88a8 + service VLAN TCI) auf die Aufnahme, Verwendung für VLAN-routing, wenn aktiviert, ignoriert, wenn nicht aktiviert. libpcap, die packet capture-Bibliothek verwendet, die von tcpdump, wireshark und andere, synthetisiert die verbraucht header, aber fälschlicherweise als 802.1 Q-VLAN-header (0x8100 + service-VLAN-TCI). So, das Sortieren wird nicht neu geschrieben, es ist nur libpcap Synthese es falsch, nach dem kernel mit verzehrt Empfang und routing von der ethernet-frame. (Es gibt einige Chipsätze wie Broadcom, die strip-Header zu senden, auch.)
  • Testen von Ubuntu 3.13.0-29-generic #53 x86_64 kernel (genauer gesagt, mit dem 8021q-Modul), der kernel Pakete mit 802.1 Q-und/oder 802.1 AD VLAN-tags richtig; siehe meine Antwort unten für details. Es verbraucht nur den VLAN-tag, auch wenn keine VLANs konfiguriert sind. libpcap reinserts dem tag zurück, aber fest auf 802.1 Q, also der "bug" existiert in libpcap nur. Fix vorhanden ist, aber nicht von upstream akzeptiert. Mein umgeschrieben Antwort zeigt, wie alle bestätigen, für sich selbst, keine Notwendigkeit zu Vertrauen, mein Wort.

InformationsquelleAutor jwbensley | 2014-06-22
Schreibe einen Kommentar