PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C -> char - Zeiger ? will nicht



ac3x
19-07-2005, 11:29
Guten morgen,
ich hab mal wieder ein Problem mit C und Zeigern.
Ich möchte gerne die IP von einem Raw-Socket ausgeben oder besser, die IP soll in einen String rein.
gcc gibt auch bei mir keine Fehler aus.
Die Funktion inet_ntoa(); gibt einen "char *" zurück.



#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
int main(int argc, char *argv[])
{

char *zwischenspeicher;
char *srcip, *dstip;
char buffer[1024];
struct in_addr addr;
int r, bytes;
struct iphdr *ip;

r = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
if (r == -1)
{
perror("socket() failed");
return 1;
}
bytes = recv(r, buffer, sizeof(buffer), 0);
ip = (struct iphdr *) buffer;
addr.s_addr = ip->saddr;
srcip = inet_ntoa(addr);
printf("IP-Address S \t%s\n", srcip);

}


Wenn ich das Programm ausführe bekomme ich die korrekte IP-Address von einem IP-Packet.
Wenn ich jedoch noch 3 Zeilen hinzufüge und das printf() in der letzten Zeile verschiebe sieht das so aus :


#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
int main(int argc, char *argv[])
{

char *zwischenspeicher;
char *srcip, *dstip;
char buffer[1024];
struct in_addr addr;
int r, bytes;
struct iphdr *ip;
r = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
if (r == -1)
{
perror("socket() failed");
return 1;
}
bytes = recv(r, buffer, sizeof(buffer), 0);
ip = (struct iphdr *) buffer;
addr.s_addr = ip->saddr;
srcip = inet_ntoa(addr);
addr.s_addr = ip->daddr;
dstip = inet_ntoa(addr);
printf("IP-Address S \t%s\n", srcip);
printf("IP-Address D \t%s\n", dstip);
}

bekomme ich sowohl beim der SourceIP meine Lokale IP z.b 192.168.1.2 als auch bei der DestinationIP die gleiche.

Was mache ich falsch ?
Kann mir jemand helfen ?


Gruß ac3x

Corcovado
19-07-2005, 12:45
Hallo, ich weiss nich ob ich Dir viel weiterhelfen kann, ich versuchs mal..
Kann es sein, dass Du addr bei inet_ntoa(addr) per Reference uebergibst? - Danach aendert sich eben die Membervariable von addr, jedesmal wenn Du sie extern abaenderst, an der Stelle mit. Abhilfe waere, by Value zu uebergeben!?

almoeli
19-07-2005, 15:31
Hallo,

die man page von inet_ntoa weisst extra darauf hin, dass inet_ntoa einen STATISCH allokierten Buffer für den Ergebnisstring benutzt.
Das heisst, es schreibt beim ersten und beim zweiten Aufruf in den selben Buffer. Es überschreibst also mit dem zweiten Aufruf das Ergebnis des ersten Aufrufs. Da die printf erst beide NACH dem zweiten Aufruf ausgeführt werden, erhälst du nur die IP Adresse, welche vom zweiten Aufruf erzeugt wurde.
Besser funktionierts wenn du den printf gleich nach jedem inet_ntoa Aufruf plazierst:



addr.s_addr = ip->saddr;
srcip = inet_ntoa(addr);
printf("IP-Address S \t%s\n", srcip);
addr.s_addr = ip->daddr;
dstip = inet_ntoa(addr);
printf("IP-Address D \t%s\n", dstip);


Viele Grüsse

almoeli

ac3x
19-07-2005, 16:28
ok, danke !

ich habs jetzt per strncpy gemacht, es geht.


Gruß ac3x ;)