u_int32_t Was ist das?



  • In der C Standardbiblithek - nein.

    Aber hier im Forum dürften inzwischen einige Funktionen dafür gepostet worden sein, schau dich einfach mal auf den ersten Seiten des Boards nach "binär" um.

    Edit: Eine Möglichkeit ist z.B. das hier (ist zwar C++, aber das kannst du sicher auch auf C umsetzen)



  • Oh das hab ich zu spät gesehen habs nun schon selber geschrieben allerdings gibts Probleme. Und zwar wenn ein Byte eingelesen wird bei dem das Vorzeichenbit 1 ist (Alle Bytes bei dennen das High Nibble >7 ist).
    Ich denke es liegt an der Zeile. Ein char Array kann ja leider nicht unsigned sein.

    tmp_int=(unsigned int)tmp[i];
    

    Ich hab mir mal ausgeben lassen was in dem Char Array an der Stelle steht bei 0xFF ist -1. Ich hab nun leider gar keine Idee wie ich das da rausbekommen soll der Typcast auf unsigned Int hat nichts gebracht.

    Gekürzter Quellcode

    void hdr_reader2(struct tcphdr *hdr)
    {
    	unsigned int 	size = (int)sizeof(struct tcphdr),
    			i=0,
    			tmp_int;
    
    	char 	tmp_hdr[160],
    		tmp_char[50],
    		date[20],
    		tab[1],
    		tmp2[200],
    		tmp[50];
    
    	memmove(tmp,hdr,20);
    	//printf("%d\n",size);
    	while(size)
    	{
    		tmp_int=(unsigned int)tmp[i];
    
    		tmp_hdr[i]=0;
    		tmp_hdr[i+1]=0;
    		tmp_hdr[i+2]=0;
    		tmp_hdr[i+3]=0;
    		tmp_hdr[i+4]=0;
    		tmp_hdr[i+5]=0;
    		tmp_hdr[i+6]=0;
    		tmp_hdr[i+7]=0;
    
    		printf("%d %d %d\n\n",tmp[i],tmp_int,i);
    
    		if(tmp_int>=128)
    		{
    			tmp_hdr[i*8+7]=1;
    			tmp_int-=128;
    		}if(tmp_int>=64)
    		{
    			tmp_hdr[i*8+6]=1;
    			tmp_int-=64;
    		}if(tmp_int>=32)
    		{
    			tmp_hdr[i*8+5]=1;
    			tmp_int-=32;
    		}if(tmp_int>=16)
    		{
    			tmp_hdr[i*8+4]=1;
    			tmp_int-=16;
    		}if(tmp_int>=8)
    		{
    			tmp_hdr[i*8+3]=1;
    			tmp_int-=8;
    		}if(tmp_int>=4)
    		{
    			tmp_hdr[i*8+2]=1;
    			tmp_int-=4;
    		}if(tmp_int>=2)
    		{
    			tmp_hdr[i*8+1]=1;
    			tmp_int-=2;
    		}if(tmp_int>=1)
    		{
    			tmp_hdr[i*8]=1;
    			tmp_int-=1;
    		}	
    
    		i++;
    		printf("Byte %d Fertig\n",i);
    		size--;
    	}
    }
    


  • HiFish schrieb:

    unsigned int 	size = (int)sizeof(struct tcphdr),
    

    überprüf' mal, ob da auch die erwartete länge drin steht.

    btw: ich würde ja auf die 'struct tcphdr' ganz verzichten und stattdessen immer ein 'unsigned char array' nehmen. bei einem tcp header ist genau festgelegt, wo die einzelnen felder sind, welche länge sie haben, welche byte order usw. ein c-compiler kann zwischen die struct-members füllbytes setzen, multibyte-werte falsch herum speichern, bitfields verdrehen und ähnliche schweinereien, so dass garnix mehr passt...



  • ja da kommt 20 raus so groß wie die Struktur definiert ist aber ich werds dann ma direkt auf 20 setzen 🙂

    Edit: Ja die Struktur is ja so vordefiniert die kann ich net einfach austauschen.



  • HiFish schrieb:

    Edit: Ja die Struktur is ja so vordefiniert die kann ich net einfach austauschen.

    warum das? welch mieses programm braucht so eine struct mit endian-abhängigen bitfields? 😮



  • Der Linux Kernel.



  • Hi Fish schrieb:

    Der Linux Kernel.

    hätt' ich mir denken können 😞 😡



  • Ja kann halt schlecht das ganze THCP Protokoll da umschreiben 😉 Ist allerdings auch schon ein recht alter Kernel (2.4.21).

    So nach ein bißchen rumprobieren habe ich herausgefunden das dieser "Bug", daraus resultiert das ich den Memorybereich in ein Char Array kopiere, wenn ich ihn in ein unsigned short int kopiere gibt er die richtigen Zahlen aus, allerdings ist der short 2 Byte lang.
    Ich werds jetztmal probieren indem ich das High bzw Low Byte mittels eines Logischen Unds maskiere.



  • HiFish schrieb:

    ...das dieser "Bug", daraus resultiert das ich den Memorybereich in ein Char Array kopiere, wenn ich ihn in ein unsigned short int kopiere gibt er die richtigen Zahlen aus...

    dann nimm doch 'unsigned char'
    im tcp header sind sowieso keine signed werte.
    beispiel:

    typedef unsigned long ul;
    #define READ32(p) (((ul)*(p))<<24|((ul)*(p+1))<<16|((ul)*(p+2))<<8|((ul)*(p+3)))
    
    void hdr_reader (struct tcphdr *hdr)
    { 
       unsigned char *p = (unsigned char*)hdr;         // als unsigned char array interpretieren
    
       // ip adressen
       unsigned long source_a = *(unsigned long*)p;    // architekturabhängig
       unsigned long dest_a = *(unsigned long*)(p+4);  // architekturabhängig
       // nochmal, aber...
       unsigned long source_b = READ32(p);             // network byte order 
       unsigned long dest_b = READ32(p+4);             // network byte order
       // ^^
       // was davon richtig ist, haengt davon ab, wie die struct gefüllt wird...
    ...
    ...
    }
    


  • Irgendwie steh ich grad auf Schlauch un stell mich zu blöd an aber wie zur hölle krieg ich das short int Array nun in ne Datei? Ich probier da jetzt schon Stunden dran rum un verlier solangsam jeden Nerv.

    Das hier gibt die Bytes schön ordentlich aus Versuche mit fprintf und putc sind fehlgeschlagen. Kann ich net irgendwie mit printf den stdout in die Datei umleiten?

    unsigned char 	tmp_hdr[160];
    	for(j=0;j<160;j++)
    	{
    		printf("%d",tmp_hdr[j]);
    		if(x==8) {printf(" ");x=0;}
    		if(j==79){printf("\n");}
    		x++;
    	}
    

    Wo ich versucht habe mit fprintf den tmp_hdr auszugeben kam ein Warning

    headerreader.c:118: warning: pointer targets in passing argument 2 of 'fprintf' differ in signedness
    

    Heut morgen mit nem klaren Kopf hats geklappt hat sich also erledigt 😉



  • Wo taucht denn in diesem Ausschnitt fprintf() auf? Wenn du das anstelle von printf() verwenden willst, mußt du als ersten Parameter das Ziel-FILE* angeben (entweder ein eigenes per fopen() angelegtes Objekt oder eins der Standard-Files stdout (normale Konsolen-Ausgabe) oder stderr (Fehlerausgabe)).



  • Mit welcher Funktion kann ich den Zahlen in einen Char schreiben?

    z.b. sprintf(string, "%d", number);

    oder
    strtod()


Anmelden zum Antworten