Funktionsumbau von char zu String macht Probleme (UDP-Packete haben nur die hälfte der Daten >.<)
-
Hallo ich habe folgendes Problem,
Ich wollte mal ganz nett fragen, ob mir jemand bei folgender Funktion helfen kann. Diese Funktion Sendet einen Klartext (OSC_WELCOME[1024]) zurzeit als Char[]... (funktioniert auch wie es soll, ist aber nicht die Lösung bzgl dem verketten)
Das Problem was ich jedoch damit habe, ich MUSS das Paket und Nachricht mit 1024 bzw 4096 aufblähen (Speicher-verschwenung).
Naja nicht ganz, der Zeiger (_offset) steht am "ende der Nachricht im Paket". Nur macht sich das ersetzen des Textes, weil es ein Template sein soll als Char (daher wollte ich Strings nutzen) ziemlich doof.
Dies bezlüglich wollte mal fragen, wie ich die stellen (mit "//****//") vermerkt umstellen kann, so dass die Nachricht als string im Klartext gesendet wird.wenn ich das mit "String" mache, ist die Nachricht statt 745 Byte nur etwas über 40 Byte (obwohl sie 100%tig größer sein müsste bei 750 Zeichen) groß

Die Dateien, die das Windows Netzwerkinstallations-Setup nutzt sehen so aus:
<OSCML> <META KEY=ENTER HREF="LOGIN"> <META KEY=F3 ACTION="REBOOT"> <META KEY=ESC HREF="LOGIN"> <META KEY=F1 HREF="LOGIN"> <TITLE> Client Installation Wizard Welcome</TITLE> <FOOTER> [ENTER] continue </FOOTER> <BODY left=5 right=75> <BR> <BR> <BR> Welcome to the Client Installation wizard. This wizard helps you quickly and easily set up a new operating system on your computer. You can also use this wizard to keep your computer up-to-date and to troubleshoot computer hardware problems. <BR> <BR> In the wizard, you are asked to use a valid user name, password, and domain name to log on to the network. If you do not have this information, contact your network administrator before continuing. </BODY> </OSCML>Und Der Client zeigt nur ein Blaues Bild ohne den Text im Body (ist ja sein hintergrund XD).
In WireShark ist nur ... der Kopf enthalten und das Windows Setup ist jedoch ohne Text =(.
http://i.technet.microsoft.com/dynimg/IC197888.gif
Das Template ist für das anzeigen dieses Textes zuständig.
Kann mir da jemand helfen?
int Handle_OSC_File_Request(int con, char * data) { uint32_t _type = 0, _value = 0; char unk[28]; uint32_t _offset = 0; // Dummy-Text :) char OSC_WELCOME[1024] = "<OSCML><META KEY=F3 ACTION=\"REBOOT\"><TITLE> [OSC_HEADER_TITLE] </TITLE><FOOTER>[FOOTER_TEXT]</FOOTER><BODY left=5 right=75>[OSC_MESSAGE_BODY]</BODY></OSCML>"; cout << "Angeforderte Datei: " << SWAB32(&data[0x28]) << endl; // funktioniert auch net =( char * _end = 0; char packet[4096]; memset(packet, 0, sizeof(packet)); memcpy(&unk, &data[0x08], sizeof(unk)); _type = SWAB32(PKT_OSC_RES); // SWAB32 tut folgendes: "0x87654321" -> "0x12345678" memcpy(packet, &_type, sizeof(_type)); _offset += sizeof(_type); /* Packetlänge wird wegen der Message am ende gesetzt, da wir nicht wissen wie groß das Packet wirklich ist =/ */ _offset += 0x4; memcpy(&packet[_offset], &unk, sizeof(unk)); /* OSC-Datei einfügen als Klartext einfügen (ohne umzudrehen) */ _offset += sizeof(unk); memcpy(&packet[_offset],OSC_WELCOME,sizeof(OSC_WELCOME)); // OSC_WELCOME Message hier einfügen <.<" //****// /* das "\n" "End of Packet" setzen */ _offset += sizeof(OSC_WELCOME); memcpy(&packet[_offset],&_end,sizeof(_end)); /* Jetzt die Paket-Größe (ohne Kopfdaten an 0x4 setzen), _offset gibt jetzt das ende des Pakets an :) */ _value = SWAB32(_offset); memcpy(&packet[0x4], &_value, sizeof(_value)); // Da _offset genau am Ende der ganzen Nachricht steht, schneide ich hier ab und nehme es als "Länge" ;) // Con gibt die aktuille "socketfd-int" an... Send_PKT(con,packet,_offset); return errno; }
-
Was ist denn dein Ansatz mit string?
Du hast hier nur ein sehr unlsebarer C-code, in den ich mich gar nicht erst einarbeiten will. Zeig mal, was du versucht hast.
-
Mache ich das so:
string OSC_WELCOME = "<OSCML><META KEY=F3 ACTION=\"REBOOT\"><TITLE> [OSC_HEADER_TITLE] </TITLE><FOOTER>[FOOTER_TEXT]</FOOTER><BODY left=5 right=75>[OSC_MESSAGE_BODY]</BODY></OSCML>";memcpy(&packet[_offset],OSC_WELCOME,sizeof(OSC_WELCOME));sagt der compiler: (mips-linux-g++):
In function ‘int Handle_OSC_File_Request(int, char*)’:| error: cannot convert ‘std::string {aka std::basic_string<char>}’ to ‘const void*’ for argument ‘2’ to ‘void* memcpy(void*, const void*, size_t)’| ||=== Build finished: 1 errors, 0 warnings (0 minutes, 0 seconds) ===|Versuche ich das gleiche jedoch mit:
memcpy(&packet[_offset],&OSC_WELCOME,sizeof(OSC_WELCOME));compiliert er fehlerfrei durch sendet aber nur 40 Bytes:
[DEBUG]: Received 37 Bytes from the client... [INFO]: GetPacketType: Got OSC-File Request! [INFO]: Angeforderte Datei: 188577089 <------ sollte eigentlich etwas anzeigen wie "LOGIN" [INFO]: send 40 Bytes.. <------ 40 Bytes (als Chars sind es 1060) ^Chab alles richtig addressiert so wie es hier unter "RSU-File Reply" beschrieben ist: http://oss.netfarm.it/guides/binl.php

in Wireshark sieht mein packet als String nur so aus:
00000000 82 52 53 55 a5 03 00 00 02 00 00 00 01 00 01 00 |.RSU............| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 00 3c 4f 53 43 00 00 00 00 00 00 00 00 |....<OSC........|
-
Du versuchst einen std::strings per memcpy zu kopieren, was nicht funktionieren kann. Strings haben ihre eigenen Kopierfunktionen. Ist packet jetzt auch ein string?
-
memcpy(&packet[_offset],OSC_WELCOME,sizeof(OSC_WELCOME));Du willst
memcpy(&packet[_offset],&OSC_WELCOME[0],OSC_WELCOME.length());vorausgesetzt
packetist einchar-Array.Warum? Zu den Grundlagen gehts hier lang =>
-
Eventuell möchtest du folgendes machen:
OSC_WELCOME.copy(&packet[_offset],OSC_WELCOME.length());
-
packet ist char[4096];
data ist ebenfalls char[1024];hab das extra schon in seperate Functione gepackt um die Übersicht zu behalten xD
(PAcket ermitteln, bauen und senden sowie empfangen ... hat mich auch einige nächte gekostet... da mal hinterzusteigen, wie man das macht
-
LipkeGu schrieb:
packet ist char[4024];
In den Fall funktioniert das was ich geschrieben habe.
-
Habe ich probiert, musste aber das offset FIX (0x24) angeben (ist eh immer bei 0x24)
OSC_WELCOME.copy(&packet[0x24],OSC_WELCOME.length());und zeigt auch den text in wireshark komplett an

-
Bei mir ergibt sich nicht ganz der Sinn, warum du von data nach unk kopierst und dann von unk in den buffer. Stattdessen kannst du doch direkt kopieren.
Zudem solltest du den Buffer gleich als string aufbauen.char packet[4096]; memset(packet, 0, sizeof(packet)); memcpy(&unk, &data[0x08], sizeof(unk)); _type = SWAB32(PKT_OSC_RES); // SWAB32 tut folgendes: "0x87654321" -> "0x12345678" memcpy(packet, &_type, sizeof(_type)); _offset += sizeof(_type);kannst du z.B. als
string packet; // memcpy(&unk, &data[0x08], sizeof(unk)); // ??? uint32_t _type = SWAB32(PKT_OSC_RES); // SWAB32 tut folgendes: "0x87654321" -> "0x12345678" packet += string(static_cast<const char*>(&_type), sizeof(_type)); // offset ist hier einfach packet.size()
-
Ja das kann man probieren, man sollte bedenken, der wurde mal in C geschrieben, da war das noch nicht so mit casten was die heide gibt!
Aber kurz mal um zu erklären was das fürn Programm ist:
Das ist ein BINL-Server der dem Windows 2000/XP/2003 sagt (wenn man das Setup über Netzwerk startet, welchen Netzwerkarten es zu laden hat (zu dem gleichen zeitpunkt wo auch SATA-Treiber geladen werden müssten (textmode-Setup).
Der BINL-Server ist gedacht, dass er auf nen Router mit openWRT läuft (MIPS.Architektur) 64 MB-Ram und 16MB Flash...
daher wollte ich da schon schauen, so gut wie möglich Speicher zu sparen. Der C-Code ist nebenher 7 jahre alt (Ich hab den nur mal weiter geschrieben)
Ich hab zumindest den code versucht zu erweitern (nach dem ursprünglichen Code Style damit der Wizard im PXE läuft.
Mit der Zeit kann man da fast alles "Runderneuern" Nur ich bin nicht nen fan von .NET C++ und c#. Da ich Linux zum Programmieren benutze, weil eben OpenWRT auf dem Router läuft... macht sich das besser.
Wenn du das packet so parst als String-Buffer kommt bei dir auch das gleiche ergenis, wie auf netfarm.it beschrieben?

-
Warum sollte ein char[] etwas können, das man mit string nicht lösen kann? Es ist doch eigentlich das gleiche, nur das string viel mehr FUnktionalität anbietet.
-
Das geht mir nicht um den Char, das geht mir um das INT16_T und INT32_T
das alles ist little Endian das meiste aber auch BIG-Endian.uint32_t... muss so gesendet werden...
#define PKT_NCQ_REQ 0x51434e81 /* Network Card Query */ #define PKT_NCR_RES 0x52434e82 /* Network Card Reply */ #define PKT_OSC_REQ 0x55515281 /* OSC File request */ #define PKT_OSC_RES 0x55535282 /* OSC File reply */SWAP32 wäre auch unütz, man müsste nur das umdrehen... bestimmt wegen BIG-Endian...
-
so gut wie möglich Speicher zu sparen
Und da nimmst du C++?
das alles ist little Endian das meiste aber auch BIG_Endian
Wo willst du was wie konvertieren? warum geht das nicht Inplace?