View previous topic :: View next topic |
Author |
Message |
dermund Apprentice


Joined: 28 Aug 2007 Posts: 205 Location: Sprawl
|
Posted: Fri Dec 14, 2007 10:32 pm Post subject: komisches udp-socket problem / multicasts [gelöst] |
|
|
Hi
Ich poste hier nur aus reiner Verzweiflung, ist ja eigentlich kein Programmierforum hier - versuch trotzdem mal mein Glück (woanders weiss keiner Bescheid)
Ich hab das alles am Anfang auch unter Linux probiert. Bitte lasst euch also von den paar window$ system calls nicht stören Ist unter Linux bis auf den WSA-Schmand das gleiche.
Das Programm soll nur einen UDP-Socket öffnen und dann zehnmal hintereinander Pakete vom Port 1900 empfangen und den Payload davon anzeigen, aber er empfängt einfach nichts.
- Unter netstat sehe ich wie mein Programm auf dem richtigen Port lauscht - aber er zeigt nichts an - bleibt immer bei dem recvfrom()-call stehen.
- Ich generiere UDP-Datagramme für den Port 1900 mit pktgen unter linux und schicke sie intervallweise an meinen Rechner.
- Ich sehe im Wireshark das die Pakete am richtigen Port ankommen (und dass die in Ordnung sind) - aber das Programm zeigt nichts an! Nie!
Hier mein Programm:
Code: |
#include <winsock2.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <iphlpapi.h>
#include <errno.h>
#pragma argsused
int main(void)
{
WSADATA wsaData;
SOCKET upnp_sock;
int i=0;
int j=0;
int bytes=0;
int remo_addr_len;
struct sockaddr_in remo_addr;
struct sockaddr_in listen_addr;
char buff[500];
WSAStartup(MAKEWORD(2, 2), &wsaData) ;
upnp_sock = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_IP, NULL, 0, 0);
printf("\nSOCKET ERROR:%i\n",WSAGetLastError());
listen_addr.sin_addr.s_addr = inet_addr("192.168.0.5");
listen_addr.sin_port = htons(1900);
listen_addr.sin_family = AF_INET;
bind(upnp_sock, (struct sockaddr*) &listen_addr, sizeof(listen_addr));
printf("\nBIND ERROR:%i\n",WSAGetLastError());
printf("Versuche irgendetwas zu empfangen...\n");
remo_addr_len = sizeof(remo_addr);
while (j<10)
{
i=0;
bytes=recvfrom(upnp_sock, buff, 30, 0, (struct sockaddr *) &remo_addr, &remo_addr_len);
if (bytes == -1)
{
printf("\nRECVFROMERROR:%i\n",WSAGetLastError());
}
printf("Bytes:%d\n", bytes);
buff[bytes]='\0';
bytes=0;
while (buff[i] != '\0' )
{
printf("%c", buff[i++]);
}
printf("\n\n#############\n\n");
memset(&buff, '\0', sizeof(buff)-1);
j++;
}
printf("Feddish\n");
closesocket (upnp_sock);
getchar();
return 0;
}
|
Auch verrückte Ideen sind herzlichst willkommen!
Last edited by dermund on Sun Dec 16, 2007 1:38 pm; edited 1 time in total |
|
Back to top |
|
 |
sirro Veteran


Joined: 20 Jul 2003 Posts: 1472 Location: aachen.nrw.de.eu
|
Posted: Sat Dec 15, 2007 10:37 am Post subject: |
|
|
Probier das mal, so geht es bei mir mit netcat + dem code hier.
Code: | #include <stdio.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
int main(void) {
int j, sd, rem_addr_len;
struct sockaddr_in loc_addr;
struct sockaddr_in rem_addr;
loc_addr.sin_family = AF_INET;
loc_addr.sin_port = htons(1900);
loc_addr.sin_addr.s_addr = htonl(INADDR_ANY);
sd = socket(AF_INET, SOCK_DGRAM, 0);
bind(sd, (struct sockaddr*)&loc_addr, sizeof(loc_addr));
for(j=0; j<10; ++j){
ssize_t rec;
char buffer[512];
char address[INET_ADDRSTRLEN];
rec = recvfrom(sd, buffer, sizeof(buffer), 0, (struct sockaddr*)&rem_addr, &rem_addr_len);
if(rec==-1) {
fprintf(stderr, "recv failed!\n");
continue;
}
buffer[rec]= '\0';
inet_ntop(AF_INET, &(rem_addr.sin_addr), address, INET_ADDRSTRLEN);
printf("Got from %s: %s\n", address, buffer);
}
return 0;
} |
Wenn das bei dir geht kannst du ihn langsam zu dem ausbauen was du hast und gucken wann es scheitert. |
|
Back to top |
|
 |
dermund Apprentice


Joined: 28 Aug 2007 Posts: 205 Location: Sprawl
|
Posted: Sat Dec 15, 2007 3:04 pm Post subject: |
|
|
hi sirro,
Ich hab dein programm 1zu1 übernommen und auf zwei Maschinen laufen lassen - und jetzt die Magic: auf den netcat-schmand reagiert er!! Zwar mit "recv-failed" aber scheissegal - er reagiert. Ich hab einfach "nc 127.0.0.1 1900 -u" gemacht und dann Zeuch getippt und mit <Enter> bestätigt.
Magic2: Auf die "pktgen"-Pakete reagiert er nicht - obwohl die Pakete beinahe identisch sind - hier die Pakete im Vergleich:
Das netcat-paket:
Code: |
Ethernet II, Src: ViaTechn_d9:33:0a (00:40:63:d9:33:0a), Dst: HewlettP_47:a2:18
(00:17:08:47:a2:18)
Destination: HewlettP_47:a2:18 (00:17:08:47:a2:18)
Address: HewlettP_47:a2:18 (00:17:08:47:a2:18)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
Source: ViaTechn_d9:33:0a (00:40:63:d9:33:0a)
Address: ViaTechn_d9:33:0a (00:40:63:d9:33:0a)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
Type: IP (0x0800)
Trailer: 000000000000000000000000
Internet Protocol, Src: 192.168.0.3 (192.168.0.3), Dst: 127.0.0.1 (127.0.0.1)
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
0000 00.. = Differentiated Services Codepoint: Default (0x00)
.... ..0. = ECN-Capable Transport (ECT): 0
.... ...0 = ECN-CE: 0
Total Length: 34
Identification: 0xc092 (49298)
Flags: 0x04 (Don't Fragment)
0... = Reserved bit: Not set
.1.. = Don't fragment: Set
..0. = More fragments: Not set
Fragment offset: 0
Time to live: 64
Protocol: UDP (0x11)
Header checksum: 0xf8df [correct]
[Good: True]
[Bad : False]
Source: 192.168.0.3 (192.168.0.3)
Destination: 192.168.0.5 (192.168.0.5)
User Datagram Protocol, Src Port: 1028 (1028), Dst Port: 1900 (1900)
Source port: 1028 (1028)
Destination port: 1900 (1900)
Length: 14
Checksum: 0x2f31 [correct]
[Good Checksum: True]
[Bad Checksum: False]
Hypertext Transfer Protocol
Data (6 bytes)
0000 68 61 6c 6c 6f 0a hallo.
|
Das pktgen-Paket:
Code: |
Ethernet II, Src: ViaTechn_d9:33:0a (00:40:63:d9:33:0a), Dst: HewlettP_47:a2:18 (00:17:08:47:a2:18)
Destination: HewlettP_47:a2:18 (00:17:08:47:a2:18)
Address: HewlettP_47:a2:18 (00:17:08:47:a2:18)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
Source: ViaTechn_d9:33:0a (00:40:63:d9:33:0a)
Address: ViaTechn_d9:33:0a (00:40:63:d9:33:0a)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
Type: IP (0x0800)
Trailer: 0000
Internet Protocol, Src: 192.168.0.3 (192.168.0.3), Dst: 127.0.0.1 (127.0.0.1)
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
0000 00.. = Differentiated Services Codepoint: Default (0x00)
.... ..0. = ECN-Capable Transport (ECT): 0
.... ...0 = ECN-CE: 0
Total Length: 44
Identification: 0x1d00 (7424)
Flags: 0x00
0... = Reserved bit: Not set
.0.. = Don't fragment: Not set
..0. = More fragments: Not set
Fragment offset: 0
Time to live: 32
Protocol: UDP (0x11)
Header checksum: 0x3e15 [correct]
[Good: True]
[Bad : False]
Source: 192.168.0.3 (192.168.0.3)
Destination: 127.0.0.1 (127.0.0.1)
User Datagram Protocol, Src Port: 1028 (1028), Dst Port: 1900 (1900)
Source port: 1028 (1028)
Destination port: 1900 (1900)
Length: 24
Checksum: 0x0000 (none)
Good Checksum: False
Bad Checksum: False
Hypertext Transfer Protocol
Data (16 bytes)
0000 be 9b e9 55 00 00 00 01 47 63 e9 4e 00 0b 14 76 ...U....Gc.N...v
|
Ganz zu schweigen von den Paketen die das Programm eigentlich empfangen soll nämich von der X-Box360:
Code: |
Ethernet II, Src: Microsof_74:8a:50 (00:17:fa:74:8a:50), Dst: 01:00:5e:7f:ff:fa (01:00:5e:7f:ff:fa)
Destination: 01:00:5e:7f:ff:fa (01:00:5e:7f:ff:fa)
Address: 01:00:5e:7f:ff:fa (01:00:5e:7f:ff:fa)
.... ...1 .... .... .... .... = IG bit: Group address (multicast/broadcast)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
Source: Microsof_74:8a:50 (00:17:fa:74:8a:50)
Address: Microsof_74:8a:50 (00:17:fa:74:8a:50)
.... ...0 .... .... .... .... = IG bit: Individual address (unicast)
.... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
Type: IP (0x0800)
Internet Protocol, Src: 192.168.0.7 (192.168.0.7), Dst: 239.255.255.250 (239.255.255.250)
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
0000 00.. = Differentiated Services Codepoint: Default (0x00)
.... ..0. = ECN-Capable Transport (ECT): 0
.... ...0 = ECN-CE: 0
Total Length: 168
Identification: 0x30ce (12494)
Flags: 0x00
0... = Reserved bit: Not set
.0.. = Don't fragment: Not set
..0. = More fragments: Not set
Fragment offset: 0
Time to live: 1
Protocol: UDP (0x11)
Header checksum: 0xd7cd [correct]
[Good: True]
[Bad : False]
Source: 192.168.0.7 (192.168.0.7)
Destination: 239.255.255.250 (239.255.255.250)
User Datagram Protocol, Src Port: 31366 (31366), Dst Port: 1900 (1900)
Source port: 31366 (31366)
Destination port: 1900 (1900)
Length: 148
Checksum: 0x8d08 [correct]
[Good Checksum: True]
[Bad Checksum: False]
Hypertext Transfer Protocol
M-SEARCH * HTTP/1.1\r\n
Request Method: M-SEARCH
Request URI: *
Request Version: HTTP/1.1
Host: 239.255.255.250:1900\r\n
Man: "ssdp:discover"\r\n
MX: 2\r\n
ST: urn:schemas-microsoft-com:service:MSContentDirectory:1\r\n
\r\n
|
Der einzige Unterschied der mir zwischen den ersten beiden Beispielen aufgefallen ist, ist dass das "Don't fragment"-Bit im ersten Fall gesetzt ist. Soll es daran liegen??
Ich checks net und kotz bald an Strahl.
Ein relevanter Ausschnitt von "netstat -a" auf dem Rechner wo das Programm läuft - das sollte ja passen:
Code: |
...
udp 0 0 *:1900 *:*
...
|
|
|
Back to top |
|
 |
dermund Apprentice


Joined: 28 Aug 2007 Posts: 205 Location: Sprawl
|
Posted: Sun Dec 16, 2007 12:21 am Post subject: |
|
|
Ok, ich hab noch ein bisschen rumprobiert - und es ist nicht das "Don't Fragment"-Bit gewesen.
Es geht mit dem "pktgen" nur wenn ich die DEST-MAC mit angebe - ansonsten schreibt er das Feld mit Nullen zu !?! und das Paket kommt nicht an. (Wird das nicht eigentlich vom Switch gemacht ?!?)
Mit eingetragener MAC geht dass dann nicht nur mit sirro's code sondern auch mit meinem ursprünglichen.
Ausserdem darf ich mit den Programmen nicht auf 127.0.0.1 lauschen sondern nur auf dem jeweiligen Ethernetinterface (also z.B 192.168.0.5) das auch am Switch hängt. (das war die zweite Sache die ich nicht verstehe).
Vielleicht kann einer was dazu sagen..
Mein eigentliches Problem beschränkt sich jetzt darauf (wenn ich über den ganzen Kram nicht mehr nachdenke, was mir schon schwerfällt) die multicasts von der xbox-360 zu empfangen, denn dass geht nach wie vor nicht! Die werden ja auf sone Multicast-Address gesendet (239.255.255.250) und ich weiss nicht wie ich das in C lösen soll, denn auf dieser Addresse mit 'bind' abzuhören geht nicht. Oder ist es ganz einfach?
Ich mein .. ist das nicht auch ne Layer2-Sache, dass der Switch diesen Multicast richtig aufteilt und an jede Adresse sendet - hmm der Wireshark sagt ja eigentlich was anderes (s.o.)?
Vielleicht kann mir da jemand helfen..hab schon deswegen g€goog€lt. Infos sind aber rar gesät. Hat jmd. vlt. nen Link?
UPDATE:
Hab doch noch was gefunden, sogar mit Code http://www.tack.ch/multicast/
Probier das mal aus aber heut nich mehr (hab nämlich irgendwo gelesen, das man da n neues device - multicast device - anlegen muss und da hab ich heut ma kein' Bock mehr druff.) Das wär keine vernünftige Sache net. Wenn das stimmt fang ich lieber gleich an mich in libpcap einzulesen.  |
|
Back to top |
|
 |
sirro Veteran


Joined: 20 Jul 2003 Posts: 1472 Location: aachen.nrw.de.eu
|
Posted: Sun Dec 16, 2007 11:47 am Post subject: |
|
|
dermund wrote: | Ausserdem darf ich mit den Programmen nicht auf 127.0.0.1 lauschen sondern nur auf dem jeweiligen Ethernetinterface (also z.B 192.168.0.5) das auch am Switch hängt. (das war die zweite Sache die ich nicht verstehe). |
Ich glaube das kann ich erklären. Wenn du auf 127.0.0.1 horchst, dann bekommst du auch nur Pakete, die über loopback ankommen also nichts aus dem richtigen Netz.
Das Binden an 127.0.0.1 wird ja z.B. auch genutzt um Programme nur lokal nutzen zu können ohne sie gleich der Welt zu offenbaren.
Viel Glück bei deinem Multicast  |
|
Back to top |
|
 |
dermund Apprentice


Joined: 28 Aug 2007 Posts: 205 Location: Sprawl
|
Posted: Sun Dec 16, 2007 1:07 pm Post subject: |
|
|
Ah, ich dachte das wird immer durchgeschleift. Da hat ich wohl nen ziemlichen Bug im Kopf.
Auch wegen:
Code: | molari ~ # ip route
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.3
127.0.0.0/8 dev lo scope link
default via 192.168.0.1 dev eth0
|
Naja so Routing-Tabellen lesen, da hatte ich schon immer Probleme mit
Quote: | Viel Glück bei deinem Multicast  |
Danke. Ich werde natürlich über den "ersten Kontakt" mit der xbox-360 berichten  |
|
Back to top |
|
 |
dermund Apprentice


Joined: 28 Aug 2007 Posts: 205 Location: Sprawl
|
Posted: Sun Dec 16, 2007 1:37 pm Post subject: |
|
|
Juhuu, ging doch besser als gedacht, der erste Kontakt ist hergestellt. Ich kann jetzt die Multicasts empfangen und das alles ohne Rumgezicke und alles ohne Umkonfigurieren vom System.
Ich hab den Code vom o.g. Link modifiziert. In dem Zusammenhang ist vielleicht auch http://www.iana.org/assignments/multicast-addresses ganz interessant.
Danke nochmal sirro |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|