Forum: PC-Programmierung Problem bei eigenem Protokoll auf Ethernet


von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Hallo,

ich bin grade dabei für die Kommunikation mit einem FPGA ein Protokoll 
zu basteln welches direkt in Ethernet Frames gekapselt ist, also ohne IP 
dazwischen.
Soweit ansich keine Kunst nur habe ich bei ersten Tests etwas 
merkwürdiges festgestellt. Beim Versuch im PC-Empfangsprogramm auf einen 
eigenen Ethertype (0x1234) zu filtern funktioniert es nicht:
1
// Empfangs Routine
2
void mac_recv(void){
3
 int sock;
4
 unsigned char ether_frame[ETH_FRAME_LEN]; // 1514
5
 struct ether_header *ethhdr = (struct ether_header*) ether_frame;
6
7
 // Socket Deskriptor
8
 if( ( sock = socket(AF_PACKET, SOCK_PACKET, htons(0x1234))) == -1 ){
9
  perror("socket");
10
  exit(1);
11
 }
12
13
 // Pakete aus dem Socket lesen und Header ausgeben
14
 while(1){
15
  read(sock, ether_frame, ETH_FRAME_LEN);
16
  printf("shost: %s", ether_ntoa((struct ether_addr *) ethhdr->ether_shost));
17
  printf(" -> ");
18
  printf("dhost: %s", ether_ntoa((struct ether_addr *) ethhdr->ether_dhost));
19
  printf(" type: 0x%04x\n",htons(ethhdr->ether_type));
20
 }
21
}


Wenn ich die Zeile:
 if( ( sock = socket(AF_PACKET, SOCK_PACKET, htons(0x1234))) == -1)

durch
 if( ( sock = socket(AF_PACKET, SOCK_PACKET, htons(0x0800))) == -1)
ersetze bekomme ich wie zu erwarten alle IPv4 Pakete angezeigt.

beim ersetzen durch
 if( ( sock = socket(AF_PACKET, SOCK_PACKET, htons(0x0806))) == -1)
die ARP Pakete

beim ersetzen durch
 if( ( sock = socket(AF_PACKET, SOCK_PACKET, htons(ETH_P_ALL))) == -1)
bekomme ich alles, inklusive der von mir gewünschten 0x1234 Pakete 
angezeigt.


Warum funktioniert also das Filtern auf IPv4 (0x0800) aber auf ein 
eigenes Protokoll (0x1234) nicht?


Wäre toll wenn mir da jemand weiterhelfen könnte.

von Timmo H. (masterfx)


Lesenswert?

Was ist wenn du anstatt dem obsoleten SOCK_PACKET 
(http://linux.die.net/man/7/packet) mal SOCK_RAW nimmst?
Bei BSD soll es glaub ich eh Probleme mit "Custom Protocols" geben.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Das hatte ich bewusst so gemacht da ich bei SOCK_RAW fürs Senden den 
ganzen Blödsinn aus dem Ethernet Header (smac, dmac, type) und alle 
Protokolleinstellungen nochmal zusätzlich in ein Struct packen musste, 
wobei mir in keiner Weise klar ist warum. Auch gibts wenig brauchbare 
Beispiele dazu wie das Struct exakt zu füllen ist, insbesondere wenn man 
kein IP will.
Was ich bislang dazu gefunden hab war bis auf 1-2 Ausnahmen nichtmal 
kompilierbar da irgendwelche Headerdateien sich geändert haben.

Ansonsten geht es mir um Linux nicht BSD aber das Gefühl das was bei 
Custom Protokollen nicht ok ist, habe ich auch.

von Robert L. (lrlr)


Lesenswert?

und dass du nur irgendwo die byteorder "vergessen" hast

also

htons(0x3412) funktionieren würde??

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Das war auch mein erster Gedanke, darum habe ich den Test mit dem 
Ethertype 0x1111 gemacht wo die Order dann egal wäre. Ergebnis war auch 
nix.

von Timmo H. (masterfx)


Lesenswert?

Versuch mal nicht über 0xFF00 hinauszugehen. Also Teste mal 0x1200 oder 
so. Irgendwo hatte ich mal gelesen, dass man bei Custom nicht höher als 
255 gehen darf.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Alles unter 0x05DC wird als Ethernet-Version 1 interpretiert, dort hat 
das Ethertype Feld jedoch die Bedeutung einer Längenangabe.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Habs trotzdem getestet sowohl 0x00FF als auch 0xFF00, beidesmal nix.

Werde mir jetzt mal den Kernelsource für ipx oder so ansehen, das als 
userspace tool zu machen war eigentlich nur als ein erster Test 
vorgesehen. -.-

von Axel L. (axel_5)


Lesenswert?

Was sagt den Wireshark ?

Kommt der Frame überhaupt im PC an ?

Da kann man dann auch schön sehen, ob die Byte Order stimmt.

Gruss
Axel

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Ja, Wireshark sieht das Paket, die Byteorder ist auch ok und wenn ich 
auf der Empfangsseite
1
if( ( sock = socket(AF_PACKET, SOCK_PACKET, htons(ETH_P_ALL))) == -1)
verwende und nachträglich auf 0x1234 filter bekomme ich exakt die 
entsprechenden Pakete.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Habe es testweise mal mit SOCK_RAW gebaut allerdings kommt das Paket 
wieder nur an wenn ETH_P_ALL benutzt wird.
So langsam habe ich die Vermutung das nur auf vordefinierte Ethertypes 
gefiltert werden kann bzw. solche für die ein übergeordnetes Protokoll 
existiert.

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.