Forum: PC-Programmierung Elegantes Füllen von Arrays (Netzwerk-Pakete)


von Dennis S. (eltio)


Lesenswert?

Guten Morgen,

ich bin dabei mir mit WinPCAP eigene Netzwerkpakete zusammenzusetzen, 
jedoch finde ich die jetzige Umsetzung etwas unschön und schwer zu 
warten.
1
char destination_mac[] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
2
char source_mac[] = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02};
3
memcpy(&packet[0], destination_mac, 6);
4
memcpy(&packet[6], source_mac, 6);
5
6
/* Ehternet Frame */
7
packet[12] = 0x08; /* Type IP */
8
packet[13] = 0x00;
9
packet[14] = 0x45; /* Version and Header-length */
10
packet[15] = 0x00; /* Differentiated Services Field */
11
packet[16] = 0x00; /* Total length */
12
packet[17] = 0x34;
13
...

Hat jemand eine Empfehlung wie ich das eleganter lösen kann?

Dank und Gruß
Dennis

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dennis S. schrieb:
> memcpy(&packet[0], destination_mac, 6);
> memcpy(&packet[6], source_mac, 6);
1
memcpy(packet, destination_mac, sizeof (destination_mac));
2
memcpy(packet + 6, source_mac, sizeof (source_mac));

Und das gleiche Konzept kannst Du natürlich auch für Dein Ethernet-Frame 
anwenden.
1
char ethernet_frame = {0x08, 0x00, 0x45, 0x00, 0x00, 0x34};
2
3
memcpy(packet + 12, ethernet_frame, sizeof (ethernet_frame));

Die numerischen Konstanten 0, 6 und 12 könntest Du natürlich auch noch 
durch #defines ersetzen:
1
#define OFFSET_DESTINATION_MAC 0
2
#define OFFSET_SOURCE_MAC 6
3
#define OFFSET_ETHERNET_FRAME 12
4
5
char destination_mac[] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
6
char source_mac[] = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02};
7
char ethernet_frame = {0x08, 0x00, 0x45, 0x00, 0x00, 0x34};
8
9
memcpy(packet + OFFSET_DESTINATION_MAC, destination_mac, sizeof (destination_mac));
10
memcpy(packet + OFFSET_SOURCE_MAC, source_mac, sizeof (source_mac));
11
memcpy(packet + OFFSET_ETHERNET_FRAME, ethernet_frame, sizeof (ethernet_frame));

von Vlad T. (vlad_tepesch)


Lesenswert?

was spricht gegen die definition entsprechender structs?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Vlad Tepesch schrieb:
> was spricht gegen die definition entsprechender structs?

Vermutlich auch nichts, man muss nur aufpassen, daß diese gepackt 
sind, wenn Datentypen > Byte darin verwendet werden - und dann auch auf 
die Byte-Order.

von Dennis S. (eltio)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Vlad Tepesch schrieb:
>> was spricht gegen die definition entsprechender structs?
>
> Vermutlich auch nichts, man muss nur aufpassen, daß diese gepackt
> sind, wenn Datentypen > Byte darin verwendet werden - und dann auch auf
> die Byte-Order.

Das ist der Grund, warum ich das nicht gemacht habe..

von Karl H. (kbuchegg)


Lesenswert?

Dennis S. schrieb:
> Rufus Τ. Firefly schrieb:
>> Vlad Tepesch schrieb:
>>> was spricht gegen die definition entsprechender structs?
>>
>> Vermutlich auch nichts, man muss nur aufpassen, daß diese gepackt
>> sind, wenn Datentypen > Byte darin verwendet werden - und dann auch auf
>> die Byte-Order.
>
> Das ist der Grund, warum ich das nicht gemacht habe..

Kein guter Grund.
Dazu gibt es in jedem noch so schmuftigen Compiler ein paar Pragmas, mit 
denen man packing erzwingen kann. Und wenn die Struktur letzten endes 
nur dazu dient, den unsigned chars aus dem Array einen Namen zu 
verpassen, so dass man nicht mehr
1
  packet[12] = 0x08; /* Type IP */
2
  packet[13] = 0x00;
3
  packet[14] = 0x45; /* Version and Header-length */
4
  packet[15] = 0x00; /* Differentiated Services Field */
5
  packet[16] = 0x00; /* Total length */
6
  packet[17] = 0x34;
schreiben muss, sondern (mit der Hilfe von ein paar enums oder Makros) 
schreiben kann
1
  packet.Type           = IP_TYPE;
2
  packet.VersionLength  = 69;
3
  packet.DiffServices   = 0
4
  packet.TotalLength    = 0;
5
  packet.SchiessMichTot = 52;

und das ist dann doch schon um einiges übersichtlicher, als die 
ursprüngliche Byteebene, in der eben alles einfach nur ein Byte war und 
man sich mit zusätzlichen Kommentaren behelfen mus, um zu wissen, was 
man da jetzt gerade eigentlich im Array befüllt.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Karl Heinz schrieb:
>> Das ist der Grund, warum ich das nicht gemacht habe..
>
> Kein guter Grund.
> Dazu gibt es in jedem noch so schmuftigen Compiler ein paar Pragmas

Möglicherweise hat sich Dennis auf den Teil mit der Byte-Order 
bezogen, da muss man beim Befüllen der Struktur halt aufpassen 
(natürlich nur, sofern diese Datentypen > Byte enthält).

von Dennis S. (eltio)


Lesenswert?

Nein, nein es ging schon um das Packen der Struktur. Ich meine irgendwo 
mal gelesen zu haben, dass das auf einigen Systemen zu Problemen führen 
kann. Das Programm ist eigentlich auch nur ein "schneller" Hack deswegen 
mache ich es erstmal wie von Rufus beschrieben. Danke an alle.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dennis S. schrieb:
> Ich meine irgendwo mal gelesen zu haben, dass das auf
> einigen Systemen zu Problemen führen kann.

Nö, das tut es im Normalfall nicht. Wenn die Prozessorarchitektur keine 
misalignten Zugriffe auf Operanden > Byte zulässt, muss der Compiler 
entsprechend korrekten Code für den Strukturzugriff erzeugen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.