Forum: PC-Programmierung Netzwerkprogrammierung - RawSocket


von Andre (Gast)


Lesenswert?

Hallo zusammen.

Ich hoffe, Ihr könnt mir helfen. Ich schreibe gerade eine Software für 
einen 32-Bit embedded-Controller. Diese werden später Teilnehmer in 
einem Netzwerk sein und untereinander kommunizieren. Die Kommunikation 
soll schon vor Vergabe von IP-Adressen möglich sein. Soll über die 
MAC-Adressen gehen. Soviel dazu. die Kommunikation klappt auch schon 
soweit. Um an dem MAC-Adressen Änderungen vornehmen zu können, muss ich 
sog. Packet-Sockets verwenden und auf OSI-Layer 2 arbeiten.

Schicke ich eine Nachricht allerdings per Broadcast ins Netz, kommt sie 
nirgends an. Schicke ich die Nachricht an eine bestimmte Adresse, wird 
sie auch empfangen.

Jetzt kommt das kuriose. Arbeite ich mit einem normalen Socket und 
schicke eine Nachricht per Broadcast heraus, werden sämtliche 
Informationen (MAC, IP etc.) vom System gesetzt. Diese Nachricht kommt 
allerdings an.

Die Mitschnitte in Wireshark sehen allerdings 100% identisch aus 
(Vergleich der Rohdaten). Kann mir da wirklich nicht mehr helfen.

von Klaus W. (mfgkw)


Lesenswert?

Andre schrieb:
> Schicke ich eine Nachricht allerdings per Broadcast ins Netz, kommt sie
> nirgends an.

Andre schrieb:
> Die Mitschnitte in Wireshark sehen allerdings 100% identisch aus
> (Vergleich der Rohdaten).

D.h. es ist im Netz mit wireshark sichtbar, nur der Empfänger merkt 
nichts davon?

Dann liegt es offenbar an der Empfängerseite.
Wer ist jetzt der Empfänger? Dein MC, oder ein PC?
Wie sieht der Empfang denn aus?

Für welche Protokollnummer soll das denn gemacht werden?

von Andre (Gast)


Lesenswert?

Hallo Klaus

Das Kuriose an der Sache ist, dass lt. Wireshark alle Pakete den 
Empfänger verlassen. auf dem Zielrechner läuft auch Wireshark. Dort 
kommen aber nur die Pakete mit direkter Adresse an. Broadcast-Telegramme 
erreichen ihr Ziel nicht. Werden aber alle über den selben RAW-Socket 
gesendet.

Beispiel:

Folgendes funktioniert:
Rechner A |---------Message an 192.168.1.3 --------> Ziel (192.168.1.3)

Folgendes funktioniert nicht:
Rechner A |---------Message an 255.255.255.255-----> Ziel (192.168.1.3)

Ich kann mir nur nicht erklären wieso?

von Klaus W. (mfgkw)


Lesenswert?

Hast du einen Switch dazwischen?

Außerdem: wenn du ein Broadcast an dein lokales Netz senden willst, geht 
das doch an 192.168.1.255, oder nicht?

Ein Broadcast an das Internet wird hoffentlich nicht weit kommen :-)

von Phil (Gast)


Lesenswert?

Hi Andre,

deine Beschreibung ist ein klein wenig verworren. Du schreibst du 
arbeitest mit SOCK_PACKET. Aber wieso sendest du nun Broadcastpackets 
mit IPv4 heraus.
Das tolle an Sock_Packet ist doch das du lediglich SRC MAC Adresse 
brauchst 48 Bit also 6 Byte Länge und die Dest Mac Adresse mit ebenfalls 
48 Bit Länge um eine direkte Kommunikation zu realisieren. Jetzt folgt 
noch 2 Byte Typ im Ethernetframe und fertig ist die Grundstruktur des 
Ethernetframes. Das nächste Feld sind die Nutzdaten mit einer 
Mindestlänge von 46 Byte bis zu den üblichen 1500 Byte. Ist deine 
Nachricht die du verschicken willst kleiner als die 46 byte musst du auf 
die 46 byte Länge padden.
Aber vielleicht magst du mal deinen code schicken. Ich habe das Gefühl 
dass du den IPv4 Header selber baust was man gar nicht bräuchte. Ich 
kann mir sonst nicht erklären warum dein Wireshark IPv4 Broadcastpakete 
ausgibt wenn du nur Ethernet Frames versendest.

von Andre (Gast)


Lesenswert?

Hallo Phil, Hallo Klaus

@Klaus
Alles läuft quasi Strenförmig in einem Router zusammen. Weitere Switche 
/ Hubs etc sind ncht vorhanden.

@Phil
Vielleicht hab ich mich ja etwas blöd ausgedrückt. Also ich erzeuge 
schon die jeweiligen Header (ETH + IPv4 + UDP). Das Protokoll soll 
nachher in einem Netzwerk fahren, wo nicht unbedingt jeder Teilnehmer 
eine IP besitzt. solange die Teilnehmer noch keine IP besitzen läuft 
halt die Kommunikation über die Ethernet-Adresse.

Ich bin aber mittlerweile etwas schlauer. Also ich habe jetzt Folgende 
Teilnehmer in meinem Testszenario:

PC Linux per Ethernet-Kabel an den Router
PC Linux per WLAN an den Router
Embedded Controller 32 Bit per Ethernet-Kabel an den Router
Embedded Controller 32 Bit per WLAN an den Router
Raspberry Pi per Ethernet-Kabel an den Router

Die Kommunikation über den Raw-Socket (Über IP und MAC) klappt 
einwandfrei über das kabelnetzwerk. auch mit meinen selbstgebauten 
Paketen. Liegt allerdings eine Kabellose Strecke dazwischen, gehen die 
Pakete nicht raus.

Anbei die Konfiguration der Socketeinstellungen wie ich sie verwende:


Initialisierung des Socket-Deskriptors:
1
  int _sockFD = 0;
2
  //creating the deskriptor
3
  _sockFD = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
4
  if(_sockFD == -1){
5
    log("Socketerror", ERROR);
6
    return ERROR;
7
  }

Initialisierung der Socketstruktur:
1
  //Getting ID of Networking-Device
2
  strncpy(ifr.ifr_name, NET_DEVICE_0, sizeof(ifr.ifr_name));
3
4
  if(ioctl(_sockFD, SIOCGIFINDEX, &ifr) != 0){
5
      log("IOCTL-ERROR - Index", ERROR);
6
      return ERROR;
7
  }
8
9
  sock->sll_protocol  = htons(ETH_P_IP); //Used Proto
10
  sock->sll_ifindex  = ifr.ifr_ifindex; //Index of NW-device
11
  sock->sll_halen    = ETH_ALEN;     
12
  sock->sll_family  = AF_PACKET;     //Packet-Family


Und vor dem Versenden der eigentlichen Pakete, binde ich an das Device 
(Diese werden dynamisch ermittelt, falls mehrere vorhanden). Wird aber 
immer das richtige genutzt
1
  if(setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void*)&ifr, sizeof(ifr)) < 0){
2
    log("Can't Bind to NW-Device", PROG_ERROR);
3
    return SYS_ERROR;
4
  }
5
6
  //Setting up Broadcast-Permissions
7
  if(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &on, 4) == -1){
8
    log("Can't set Broadcastpermission", PROG_ERROR);
9
    return SYS_ERROR;
10
  }



Verwende ich allerdings normale Sockets (oberhalb des Datalink-Layers), 
werden die Pakete ohne Probleme übers netz gesendet. Allerdings werden 
dort auch sämtliche Informationen vom Kernel ausserhalb des Userspaces 
gesetzt.

Scheinbar vertragen sich meine Raw-sockets mit der WLAN-Verbindung 
nicht. Wobei das doch eigentlich keinen Unterschied machen dürfte.

von Peter II (Gast)


Lesenswert?

was soll der ganze aufwand? Wenn du normale Packete (UDP und TCP) 
verschicktn willst dann gehört auch dazu eine IP. Es macht doch 
überhaupt keinen sinn selber alles neu zu Programmieren nur weil das 
gerät noch keine Offizelle IP hat.

Jeder Windows PC schafft es sich ohne selber eine IP zu vergeben wenn er 
alleine im Netzt ist.

http://de.wikipedia.org/wiki/Zeroconf

und in 95% alles Netze ist sowiso ein DHCP Server dann braucht du nicht 
mal das. Jedes Netzwerk gerät was man kauf hat eine Feste IP über die 
man es erreichen kann.

Warum du aber alles anders machen willst, versteh ich nicht.

von Andre (Gast)


Lesenswert?

Hallo Peter II

Ich arbeite zur Zeit ausschließlich in einer Unix/Windows-Umgebung.

Und die embedded-controller sollen sich nach Anschluss an ein Netzwerk 
Automatisch melden. Eine IP wird denen dann durch eine bestimmte 
Software zugewiesen, welche im Netzwerk läuft.

Dazu ist aber folgendes wichtig:

Schritt1: Controller startet im neuen Netzwerk (In dem durchaus kein 
DHCP sein kann (Im Bereich Homeautomation schon zu Hauf gesehen)

Schritt 2: Pero MAC-Broadcast und IP-Broadcast bei allen Teilnehmern 
melden (Raw-Socket nicht unbedingt benötigt)

Schritt 3: PC mit Software sendet an neuen Teilnehmer gerichtet (MAC!!) 
eine IP und ID. (Raw sockets auf Layer 2 unverzichtbar).

Schritt 4: Teilnehmer stellt sich neu ein

Das klappt auch alles. nur halt nicht mit einer WLAN-Strecke. Und darum 
geht es mir auch. Nicht um die sinnhaftigkeit des Aufbaus :)

von Andre (Gast)


Lesenswert?

Entschuldige, ich meinte natürlich ausschließlich unter Unix!

von Klaus W. (mfgkw)


Lesenswert?

Das, was du als Router bezeichnest, ist nebenbei auch ein Switch unf 
eine Bridge.

von Peter II (Gast)


Lesenswert?

Andre schrieb:
> Dazu ist aber folgendes wichtig:
>
> Schritt1: Controller startet im neuen Netzwerk (In dem durchaus kein
> DHCP sein kann (Im Bereich Homeautomation schon zu Hauf gesehen)

> Schritt 2: Pero MAC-Broadcast und IP-Broadcast bei allen Teilnehmern
> melden (Raw-Socket nicht unbedingt benötigt)
>
> Schritt 3: PC mit Software sendet an neuen Teilnehmer gerichtet (MAC!!)
> eine IP und ID. (Raw sockets auf Layer 2 unverzichtbar).

> Schritt 4: Teilnehmer stellt sich neu ein
> Das klappt auch alles. nur halt nicht mit einer WLAN-Strecke. Und darum

> geht es mir auch. Nicht um die sinnhaftigkeit des Aufbaus :)

und was ist wenn du mal ein richtiges netwerk mit Routern vorfindest, 
eventuell noch Firewalls? Das ganze ist doch schon wieder nur auf ein 
Netzsegment begrenzt.

Warum simuliert deine Software nicht einen DHCP-Server der nur antwortet 
wenn die anfrage von dem MAC Bereich deiner Gerät kommt (und kein andere 
DHCP server vorhanden ist). Dann kommt man komplett ohne Raw socket aus. 
Entweder bekommt dein Gerät die IP vom offizellen DHCP oder von deinem.

Und das du nur untern Unix arbeitest, heist ja nicht das du nicht 
offizelle RFC umsetzen darst.

von Robert L. (lrlr)


Lesenswert?

>Warum simuliert deine Software nicht einen DHCP-Server der nur antwortet
>wenn die anfrage von dem MAC Bereich deiner Gerät kommt (und kein andere
>DHCP server vorhanden ist). Dann kommt man komplett ohne Raw socket aus.

interessant,
mit was (wenn nicht Raw socket) arbeitete dieser "simmulierte" 
DHCP-Server dann??



zum Thema: die Meisten/Alle Sysadmins werden es nicht gerne sehen, wenn 
man sowas wie der TO vor hat "aufführt", deshalb sollte man das einfach 
so machen, wie es alle machen...

von Peter II (Gast)


Lesenswert?

Robert L. schrieb:
> interessant,
> mit was (wenn nicht Raw socket) arbeitete dieser "simmulierte"
> DHCP-Server dann??

UDP

http://de.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol

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.