AVM-interne Datenbank von FREETZ aus editieren, ergänzen und steuern

hermann72pb

IPPF-Promi
Mitglied seit
6 Nov 2005
Beiträge
3,727
Punkte für Reaktionen
16
Punkte
38
Ich bin seit mehreren Tagen dran, den DNS/DHCP-Server von AVM (multid) mit dem dnsmasq soweit es geht zu "verheiraten", damit man z.B. auch die Wirkung von dnsmasq in AVM-WebIF sehen kann. Die eigentliche Problematik mit dnsmasq und multid wird in einem separaten Thread behandelt, ich will hier vielmehr die allgemeine Thematik der AVM-Datenbank für diverse Einstellungen zur Diskussion stellen und eine (oder vielleicht mehrere) geeignete Methoden dazu finden, wie wir aus FREETZ heraus diese Datenbank ansprechen können.
Zunächst mal zur Vorgeschichte und zum aktuellen Stand der Dinge:
a) Früher hat man normalerweise ar7.cfg und Co. direkt editiert und mit diversen Tricks die Änderungen wirksam gemacht. Manchmal musste man dafür die Box rebooten.
b) Die Zeiten sind nun vorbei. AVM verwaltet alles über eine interne Datenbank, die von closed-source Binaries von AVM angesteuert wird. Ein direktes Editieren in ar7.cfg un Co. führt heutzutage oft dazu, dass die Datenbank und ar7.cfg "auseinander laufen". Das ist also nicht mehr der "sicherste" Weg, wie früher. Außerdem bekommt man solche Änderungen nicht mehr direkt in AVM-WebIF dargestellt, weil AVM-WebIF mit der Datenbank und nicht mit ar7.cfg "verbunden" ist.
c) Es gibt das Tool "ctlmgr_ctl" mit dem man diverse Parameter einzeln auslesen und verändern kann. Das Problem dabei ist allerdings, dass nicht alle Befehle "durchgehen". Manchmal muss man eine bestimmte Reihenfolge an den abgegebenen Befehlen einhalten, um gewünschte Ergebnisse zu erzielen.
d) Die Seite http://www.wehavemorefun.de/fritzbox/AVM_Wiki gibt eine relativ gute Auskunft über mehrere "versteckte" Commandos, die man mit "ctlmgr_ctl" ansteuern kann. Die klassischen Sachen sind dort gut dokumentiert und funktionieren sofort, will man aber etwas tiefer graben (wie in meinem Fall mit DNS/DHCP), so kommt man an die Grenzen der Seite. Die Informationen werden nicht mehr vollständig, nicht mehr aktuell oder fehlen einfach, weil es noch keiner ausprobiert hat.
e) Also, bleibt es nur selbst zu forschen und nach weiteren Informationen in Tiefen von AVM-Binaries zu suchen, was ich auch aktiv letzte Zeit getan hatte. Wenn man nämlich die Binaries von multid, ctlmgr und Co. nach bekannten Zeichenketten durchsucht, wird man relativ schnell fündig, und findet die versteckten Befehle. So habe ich z.B. herausgefunden, wie man über ctlmgr_ctl die Hosts aus der AVM-Liste löschen kann.

Soweit so gut. Oben hatte ich aber schon eingedeutet, dass es mir eigentlich nicht ausreicht. Über ctlmgr_ctl sind sehr viele Dinge gesperrt und können nicht verändert werden. Zunächst dachte ich, dass dies prinzipbedingt ist und dass man sich damit abfinden müsste, bis ich gestern mir die LUA-Skripte von AVM angeschaut hatte. Und dort arbeitet AVM sehr oft mit den ganzen Sektionen, anstatt mit einzelnen Variablen, wie es unter ctlmgr_ctl üblich ist. Ich habe dort schon eine Passage gesehen, wo die komplette Sektion aus der Datenbank eingelesen wird, einige Teile davon bearbeitet werden und dann wieder als Sektion zurückgespielt, wenn sogar nicht direkt "Operation am offenen Herzen". Also, grundsätzlich sind solche "uneingeschränkte" Manipulationen an der AVM-Datenbank möglich. Die Frage ist nur, wie wir dran kommen könnten, um sie zu verwenden. Leider stecken diese Funktionen, die AVM dafür in LUA verwendet, in der geschlossenen LUA-Bibliothek und man kommt nicht an die Quellen dran (AVM hat nicht umsonst LUA gewählt, alleine schon wegen BSD/MIT-Lizenz). Man weiß aber, wie man die Funktionen ansteuern muss, weil alle Aufrufe ja in den LUA-Skripten zu sehen sind.
Nun meine Fragen / Ideen:

1. Ob der Weg wirklich über LUA gehen muss, weiß ich nicht. Der LUA-Interpreter von AVM ist erstmal mit dem AVM-WebIF und multid "fest verdrahtet". Ich kenne leider nicht den Weg, wie man LUA-Programme außerhalb von AVM-WebIF laufen lassen könnte und zwar so, dass sie auch die AVM-Bibliothek verwenden.
2. Vielleicht muss man gar nicht komplett über LUA gehen, und es reicht nur die LUA-Bibliothek von AVM in ein C-Programm von uns einzubinden. Würde sowas prinzipiell gehen?
3. Vielleicht lassen wir uns zwar von LUA insperieren, gehen aber komplett andere Wege, um die Datenbank anzusprechen. Z.B. über "Message Endpoints":
http://www.wehavemorefun.de/fritzbox/Message_Endpoint
Ich habe leider dort aus den Beispielen nicht so ganz verstanden, wie man sein C-Programm gestalten soll, um so ein "Message Endpoint" anzusprechen. Auf der Webseite gab es irgendwo ein Beispiel (finde ich gerade nicht mehr), wo so eine xml-artige Kommunikation dargestellt wurde. Also rein theoretisch wäre es zumindest möglich, wenn man genau weiß, was man senden muss und in welchem Format.

Was ist eure Meinung dazu? Ich brauche ein Paar Tipps, damit ich an der Baustelle noch tiefer graben könnte.
Wenn wir das Problem mit dem Ansprechen der AVM-Datenbank generell lösen könnten, hätten wir uns das Leben an sehr vielen weiteren Stellen deutlich einfacher gemacht, wo es darum geht, auf die AVM-Sachen von FREETZ aus zuzugreifen.

MfG
 
Strace auf den ctlmgr und feststellen, wie diese messages aussehen.
Am Besten vorher mit strace ctlmgr_ctl anschauen, es wird vermutlich das gleiche Prinzip verwendet und man weiß, wonach man sucht.
 
Reicht einfaches strace, oder muss man die kernel-messages (oder wie es auch immer heißt) in strace mitintegrieren? Für Letzteres ist nämlich replace kernel erforderlich, was ich erstmal gerne vermeiden würde.
Findet man in den messages die Funktionsaufrufe? Weiß man dann, wie man die Funktion aufrufen kann?
Geht dann die Suche in Richtung "Message Endpoint", oder habe ich dich falsch verstanden, Ralf? Ziel wäre dann nachher diese Kommunikation über "Message Endpoint" nachzubauen? Oder denke ich in die falsche Richtung?

MfG
 
Replace Kernel ist nicht für kernel-messages notwendig, sondern damit die Option -f "follow forks" funktioniert.

Für ctlmgr_ctl braucht man kein -f, um sich an die laufenden ctlmgr Prozesse zu hängen vermutlich auch nicht. Ansonsten tut es irgend eine Box, auf der man Replace Kernel nutzen kann.

So sieht zum Beispiel ein Aufruf aus:
Code:
# strace -s2000 -e socket,bind,sendto,recvfrom ctlmgr_ctl r box settings/upnp/activated
socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP) = -1 EAFNOSUPPORT (Address family not supported by protocol)
socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 3
socket(PF_FILE, SOCK_DGRAM, 0)          = 3
bind(3, {sa_family=AF_FILE, path="/var/tmp/me_ctlmgr_ctl1966.ctl"}, 110) = 0
sendto(3, "<message><to>box</to><from>ctlmgr_ctl1966</from><sequence>2</sequence><transaction><type>query</type><key>settings/upnp/activated</key><error>0</error></transaction></message>\0", 176, 0, {sa_family=AF_FILE, path="/var/tmp/me_logic.ctl"}, 110) = 176
recvfrom(3, "<message><to>ctlmgr_ctl1966</to><from>box</from><sequence>6971</sequence><transaction><type>response</type><key>settings/upnp/activated</key><sequence>2</sequence><error>0</error><values><r><v>1</v></r></values></transaction></message>\0", 236, 0, {sa_family=AF_FILE, path="/var/tmp/me_logic.ctl"}, [24]) = 236
1
Die ersten beiden Socket-Aufrufe interessieren hier nicht, der Rest zeigt die geendeten Daten. Die 1 in der letzten Zeile ist die Ausgabe von ctlmgr_ctl.

Und so sieht es von der anderen Seite aus, auch ohne die Option -f:
Code:
# strace -s2000 -e recvfrom,sendto $(for i in $(pidof ctlmgr); do echo -p $i; done)
recvfrom(23, "<message><to>box</to><from>ctlmgr_ctl1966</from><sequence>2</sequence><transaction><type>query</type><key>settings/upnp/activated</key><error>0</error></transaction></message>\0", 176, 0, {sa_family=AF_FILE, path="/var/tmp/me_ctlmgr_ctl1966.ctl"}, [33]) = 176
sendto(23, "<message><to>ctlmgr_ctl1966</to><from>box</from><sequence>6971</sequence><transaction><type>response</type><key>settings/upnp/activated</key><sequence>2</sequence><error>0</error><values><r><v>1</v></r></values></transaction></message>\0", 236, MSG_DONTWAIT, {sa_family=AF_FILE, path="/var/tmp/me_ctlmgr_ctl1966.ctl"}, 110) = 236
Das bedeutet, dass Du Dich mit dem obigen Befehl an den ctlmgr hängen kannst und dann beliebige Aufrufe im Web-Interface ausführen. Du solltest dann den genauen Inhalt der Nachrichten angezeigt bekommen. Schlimmstenfalls ist noch etwas andere Ausgabe dazwischen.
 
Danke für die ausführliche Aufklärung, Ralf. Ich wäre nie alleine auf die -e - Option von strace gekommen. Und die zweite Geschichte ist noch genialer. Vielen Dank! Damit kann ich nun wirklich meine Forschungen weiter betreiben und werde hier darüber berichten.
Wie man es vereinzelt von http://www.wehavemorefun.de entnehmen kann, handelt es sich tatsächlich um eine XML-Kommunikation, wie wir hier aus dem Auszug von Ralf sehen können. D.h., das ist jetzt wirklich nur die Sache der Technik und der Beobachtung, herauszufinden, welche Befehle wofür gebraucht werden.

Während ich meine Untersuchungen zum genaueren XML-Syntax betreibe, habe ich eine weiterführende Frage an diejenigen unter uns, die sich gut mit C-Programmierung auskennen: Wie können wir von uns aus so einen Socket ansteuern? Wie würde es in C aussehen? Welche Bibliotheken braucht man dafür? Ich habe leider noch kaum was Socket-artiges in C programmiert.
Auf http://www.wehavemorefun.de ist eigentlich schon sehr viel zur Benennung von diesen "Message Endpoints" gesagt. Sprich, der Name "me_ctlmgr_ctl11966.ctl" ist geläufig.

Noch eine Idee am Rande. Kann man eigentlich die Kommunikation auch über Shell-Skripting aufbauen? Wenn man z.B. die Standard-Eingabe bzw. Standard-Ausgabe zu diesen "Endpoints" leitet? Theoretisch dürfte es ja gehen, oder?

MfG
 
Ein C Programm, das die Daten über den Socket sendet und empfängt, ergibt sich direkt aus dem strace oben. Spezielle Libraries sind dafür nicht notwendig.
Allenfalls für die XML-Formatierung, aber das wäre vermutlich etwas viel Platzbedarf für das, was hier benötigt wird. Vielleicht hat auch AVM etwas brauchbares für den Zweck auf der Box, schließlich verwenden sie ja XML.

Mir ist nicht bekannt, dass man mit der Shell bzw, den normal vorhandenen Programmen so etwas machen könnte, aber ein Programm, das eine XML-Nachricht liest und die Antwort schreibt wäre einfach zu erstellen.
 
Ich bin nun deutlich weiter mit meinen Untersuchungen und meine zu behaupten, dass wir auf dem richtigen Weg sind. Meine Vermutung von oben hat sich so gut wie bestätigt: ctlmgr_ctl kann die Änderungen in der Datenbank nur begrenzt und bedingt durchführen. Die Kommunikation zwischen der LUA-cgi und dem ctlmgr sieht deutlich ausführlicher aus. Dort werden die Parameter tatsächlich in Gruppen geändert.
Hier ist ein Beispiel, wie ich über AVM-WebIF den Namen von einem Netzwerkteilnehmer ändere:
Code:
<message><to>landevice</to><from>luacgi6964</from><sequence>3</sequence>
	<transaction>
		<type>query</type>
		<key>settings/landevice/list(name,ip,mac,UID,dhcp,wlan,ethernet,active,static_dhcp,manu_name,wakeup,deleteable,source,online,speed,wlan_UIDs,auto_wakeup,guest,url)</key>
		<error>0</error>
	</transaction>
</message>


<message><to>manager</to><from>luacgi5502</from><sequence>26</sequence>
	<transaction>
		<type>group_begin</type>
		<group>luacgi_group</group>
		<error>0</error>
	</transaction>
</message>

<message><to>landevice</to><from>luacgi5502</from><sequence>27</sequence>
	<transaction>
		<type>set</type>
		<key>settings/landevice[landevice1154]/auto_wakeup</key>
		<group>luacgi_group</group>
		<error>0</error>
		<values><r><v>0</v></r></values>
	</transaction>
</message>

<message><to>landevice</to><from>luacgi5502</from><sequence>28</sequence>
	<transaction>
		<type>set</type>
		<key>settings/landevice[landevice1154]/static_dhcp</key>
		<group>luacgi_group</group>
		<error>0</error>
		<values><r><v>0</v></r></values>
	</transaction>
</message>

<message><to>landevice</to><from>luacgi5502</from><sequence>29</sequence>
	<transaction>
		<type>set</type>
		<key>settings/landevice[landevice1154]/name</key>
		<group>luacgi_group</group>
		<error>0</error>
		<values><r><v>test-83b</v></r></values>
	</transaction>
</message>

<message><to>manager</to><from>luacgi5502</from><sequence>30</sequence>
	<transaction>
		<type>group_end</type>
		<group>luacgi_group</group>
		<error>0</error>
	</transaction>
</message>

Wenn ich das Gleiche "zufuss" mit dem ctlmgr_ctl ausführe:
Code:
root@fritz:/var/mod/root# ctlmgr_ctl r landevice settings/landevice/count
15
root@fritz:/var/mod/root# ctlmgr_ctl r landevice settings/landevice14/name
test-83b
root@fritz:/var/mod/root# ctlmgr_ctl w landevice settings/landevice14/name test-83c
root@fritz:/var/mod/root# ctlmgr_ctl r landevice settings/landevice14/name
test-83c
dann sieht es so aus:
Code:
<message><to>landevice</to><from>ctlmgr_ctl6041</from><sequence>2</sequence>
	<transaction>
		<type>query</type>
		<key>settings/landevice/count</key>
		<error>0</error>
	</transaction>
</message>

<message><to>landevice</to><from>ctlmgr_ctl6042</from><sequence>2</sequence>
	<transaction>
		<type>query</type>
		<key>settings/landevice14/name</key>
		<error>0</error>
	</transaction>
</message>

<message><to>manager</to><from>ctlmgr_ctl6043</from><sequence>1</sequence>
	<transaction>
		<type>group_begin</type>
		<group>ctlmgr_ctl6043_group</group>
		<error>0</error>
	</transaction>
</message>

<message><to>landevice</to><from>ctlmgr_ctl6043</from><sequence>2</sequence>
	<transaction>
		<type>set</type>
		<key>settings/landevice14/name</key>
		<group>ctlmgr_ctl6043_group</group>
		<error>0</error>
		<values><r><v>test-83c</v></r></values>
	</transaction>
</message>

<message><to>manager</to><from>ctlmgr_ctl6043</from><sequence>3</sequence>
	<transaction>
		<type>group_end</type>
		<group>ctlmgr_ctl6043_group</group>
		<error>0</error>
	</transaction>
</message>

<message><to>landevice</to><from>ctlmgr_ctl6121</from><sequence>2</sequence>
	<transaction>
		<type>query</type>
		<key>settings/landevice14/name</key>
		<error>0</error>
	</transaction>
</message>
Deutlich zu erkennen ist, dass alle set's mit einem "group_begin" und "group_end" umrandet sind. Im Falle von ctlmgr_ctl beinhaltet die Gruppe nur eine Eintragung. Die "Umrandung" wird von ctlmgr_ctl automatisch "dazugedichtet". D.h., wenn man mehrere Parameter gleichzeitig ändern will, kann man ctlmgr_ctl nicht dazu verwenden.

Also, es lohnt sich, mich wieder in die C-Thematik reinzudenken und ein C-Programmchen für die Kommunikation mit ctlmgr zu schreiben.

MfG
 
Lassen sich die Kommandos für ctlmgr_ctl vllt. verketten um diese zusätzlichen begin/end loszuwerden?
 
Der ctlmgr_ctl kann übrigens auch eine Anfrage nach einer Liste senden, das Problem ist aber, dass er nur den ersten Wert zurück gibt.
Code:
# ctlmgr_ctl r landevice 'settings/landevice/list(name,ip)'
landevice0
 
Zuletzt bearbeitet:
@Silent-Tears: Nein, meines wissens kannst du es nicht machen. Aber so, wie es aussieht, kann man den ctlmgr_ctl relativ leicht in C nachbilden, wenn man es natürlich will... Nein, wir gehen dann schon ein Stückchen weiter.
@Ralf: So weit war ich schon auch, Ralf. Vergiss es, diese Missentwicklung von AVM (ich meine den ctlmgr_ctl) ist dafür nicht in der Lage. Ich weiß nicht, ob das Ding überhaupt dann so eine Listen-Anfrage weitersendet. Mag sogar sein, bringt uns aber nicht weiter, weil die Ausgabe/Auswerte-Routine von dem Ding vermutlich nicht mit mehrzeiligen Ausgaben klar kommt, bzw. sie dann unsauber weitergibt.
ctlmgr_ctl ist übrigens nur als Aushilfe für AVM-Entwickler angedacht. Ich weiß nicht, ob AVM selbst das Ding irgendwo einsetzt. Es kann uns ganz schnell passieren, dass diese Binary früher oder später aus dem Image verschwindet. Und weil das Ding eigentlich nur für interne Zwecke gedacht ist (so die Vermutung), ist es relativ buggy und macht überhaupt keinen Check auf falsche Eingaben oder Ähnliches. Wer mit dem ctlmgr_ctl genug gespielt hat, weiß, dass es zumindest zwei unsauber definierte Zustände von der Ausgabe gibt: Manchmal kommt eine leere Antwort zurück, obwohl die Eingabe definitiv falsh war. In bestimmten Fällen kann man den ctlmgr_ctl zum Aufhängen bringen. In sehr seltenen Fällen, kommt "er" als Antwort für den "Fehler", ich hatte aber auch schon eine andere Antwort gesehen, die ich auch als "Fehler" eingeordnet hatte.
Wenn man dies alles betrachtet, dann ist die Idee sich direkt an ctlmgr zu hängen und ctlmgr_ctl nicht zu nutzen eigentlich nicht ganz verkehrt.
Ich mache noch weitere Untersuchungen bzgl. multid, denn mit dem multid kann man ähnlich reden, wie mit ctlmgr. Ich vermute nämlich, dass einige Sachen in der Datenbank sich nur per multid und nicht per ctlmgr ändern lassen. Z.B. zuweisen von IPs, ändern von MACs und ähnliches. Denn ursprünglich (und von der Idee her) macht es multid. Es kann sein, dass AVM diese Funktionen zwischen dem ctlmgr und dem multid so aufgeteilt hat, dass bestimmte Sachen nur multid ändern darf und evtl. auch umgekehrt.

MfG
 
Nachdem ich Einiges durchprobiert habe, gebe ich hier eine Zwischenmeldung und stelle noch ein Paar Fragen, um einige Anregungen von euch wieder zu bekommen.
1. Ich habe noch kein C-Programm geschrieben, um über die "Message Endpoints" mit ctlmgr und Co. zu reden, sondern habe mich damit beschäftigt mit strace und lua die ganze Kommunikation zwischen den AVM-daemons zu beobachten und die Zusammenhänge besser verstehen. Leider ist es mir nicht vollständig gelungen.
2. Ich habe ein der AVM-lua-Skripte so modifiziert, dass ich mehrere Parameter gleichzeitig dem ctlmgr übergeben konnte. Es handelte sich um die Abarbeitung des AVM-WebIF-Aufrufes zur Namensänderung eines Netzwerkteilnehmers. Neben der Namensänderung habe ich da die Änderung der MAC-Adresse und der IP-Adresse "dazugedichtet". Strace zeigte, dass die Parameter von "luacgi" Richtung "ctlmgr" erfolgreich versandt wurden. Und jetzt kommt es: MAC-Adresse lässt sich über ctlmgr nicht ändern. Änderung der IP-Adresse fürht zum Klonen vom Netzwerkteilnehmers, allerdings mit einer leeren MAC-Adresse.
Fazit:
a) ctlmgr untersucht schon ganz genau, was man ihm per "Message Endpoint" zusendet. Man kann somit also nicht uneingeschränkt die Einträge in der Datenbank modifizieren.
b) Es ist sicherlich per direktes Ansprechen von "Message Endpoints" Einiges mehr möglich, als nur mit ctlmgr_ctl, aber leider auch nicht alles.

Weitere Beobachtungen:
- ich konnte mit strace keinerlei Kommunikation zwischen ctlmgr und multid beobachten. Meine Vermutung vorher war, dass sich die beiden in irgendeiner Art und Weise unterhalten. Dies war jedoch auch beim vollständigen strace (allerdings ohne -f) nicht zu sehen.

Fragen:
I. Wo befindet sich denn diese verdammte Datenbank von AVM, wo die ganzen Einstellungen gespeichert werden? Gibt es sie denn überhaupt? Sowohl multid, als auch ctlmgr MÜSSEN einen Zugriff auf die gleichen Positionen in der Datenbank haben.
II. Ich habe dnsmasq gestoppt und den DHCP-Server von AVM aktiviert, um zu beobachten, WIE die Vergabe einer IP über den multid erfolgt. Mit strace auf multid-Instanzen habe ich das Ganze gelogt und von einem W7-Rechner heraus "ipconfig /renew" abgesandt. Man konnte im strace-Log sehen, wie multid.leases beschrieben wurde, man konnte auch die ganze Kommunikation zwischen dem DHCP-Server und dem DHCP-Client beobachten, wo z.B. der Client dem Server sagt, wie er heißt und daraufhin die IP vom Server bekommt. Man konnte sehen, dass der Kindersicherung ein "neighbour_changed" versandt wurde, damit sie sich reloadet. Auch /var/tmp/dnsddyns.cfg wurde entsprechend beschrieben. Ich konnte aber nirgendswo sehen, WIE die entsprechenden Daten in die dubiöse "Datenbank" landen. Entweder macht multid es nicht selbst, oder ich weiß es nicht. Die Fragen dazu: Kann es sein, dass dies an fehlenden forks von strace liegt? Gibt es irgendwelche Co-Piloten von multid, die die Bearbeitung von der "Datenbank" übernehmen?

Wie gesagt, ctlmgr bequem zu bedienen ist eine Sache, die andere Geschichte ist aber, wie gelangt man an die anderen Bereiche der Datenbank, die für ctlmgr "Tabu" sind.

Edit: Ich bin kurz davor an der Stelle aufzugeben. Immerhin sitze ich schon seit einer Woche dran, um zu verstehen, wie AVM ihre ganzen Parameter abspeichert. Und ich bin kein Stückchen weiter gekommen.
Heute habe ich die ganze Box durchforstet, um irgendeine Datei zu finden, die zumindest näherungsweise einer Datenbank ähnelt und wo die ganzen MAC-Adressen und IPs zwischengespeichert sind. Vergebens. Bei WLAN-Geräten findet tatsächlich eine Speicherung der "nackten" MACs in einer temporären Datei, für LAN-Geräte und für die Namen gibt es sowas nicht.
Ich bin mittlerweile fast fest davon überzeugt, dass es keine zentrale Datenbank existiert und dass die besagten Daten von einem laufenden ctlmgr intern in statischen Variablen / Arrays / Strukturen gespeichert werden.
Mir ist aber bis jetzt immer noch nicht klar, wie multid dem ctlmgr dann sagen kann, dass ein neuer Netzwerkteilnehmer im Netz aufgetaucht ist.

MfG
 
Zuletzt bearbeitet:
..., wie man LUA-Programme außerhalb von AVM-WebIF laufen lassen könnte und zwar so, dass sie auch die AVM-Bibliothek verwenden.
Das ist möglich:
Code:
root@fritz:/var/media/ftp/uStor02/test# cat script.lua
print("This is the output of the lua script!")
Code:
root@fritz:/var/media/ftp/uStor02/test# ./mylua ./script.lua
This is the output of the lua script!
Code:
root@fritz:/var/media/ftp/uStor02/test# ldd ./mylua
        liblua.so.1 => /lib/liblua.so.1 (0x2aabe000)
        libdl.so.0 => /lib/libdl.so.0 (0x2aaf9000)
        libm.so.0 => /lib/libm.so.0 (0x2ab0c000)
        libtiinterpreter.so => /lib/libtiinterpreter.so (0x2ab34000)
        libluatextdb.so.1 => /lib/libluatextdb.so.1 (0x2ab58000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x2ab69000)
        libc.so.0 => /lib/libc.so.0 (0x2ab87000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x2ac02000)
        ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x2aaa8000)
Code:
diff -Naur '--exclude=.*' make/mylua.orig/Config.in make/mylua/Config.in
--- make/mylua.orig/Config.in	1970-01-01 01:00:00.000000000 +0100
+++ make/mylua/Config.in	2012-09-16 15:36:44.000000000 +0200
@@ -0,0 +1,7 @@
+config FREETZ_PACKAGE_MYLUA
+	bool "mylua 0.1 (binary only)"
+	default n
+	select FREETZ_LIB_libdl
+	select FREETZ_LIB_libm
+	help
+		There is no help at this time.
diff -Naur '--exclude=.*' make/mylua.orig/mylua.mk make/mylua/mylua.mk
--- make/mylua.orig/mylua.mk	1970-01-01 01:00:00.000000000 +0100
+++ make/mylua/mylua.mk	2012-09-16 15:24:18.000000000 +0200
@@ -0,0 +1,27 @@
+$(call PKG_INIT_BIN, 0.1)
+$(PKG)_BINARY:=$($(PKG)_DIR)/$(pkg)
+$(PKG)_TARGET_BINARY:=$($(PKG)_DEST_DIR)/usr/bin/$(pkg)
+
+$(PKG_LOCALSOURCE_PACKAGE)
+$(PKG_CONFIGURED_NOP)
+
+$($(PKG)_BINARY): $($(PKG)_DIR)/.configured
+	$(SUBMAKE) -C $(MYLUA_DIR) \
+		CC="$(TARGET_CC)" \
+		CFLAGS="$(TARGET_CFLAGS) \
+		-L$(TARGET_TOOLCHAIN_STAGING_DIR)/lib \
+		-I$(TARGET_TOOLCHAIN_STAGING_DIR)/include/lua"
+
+$($(PKG)_TARGET_BINARY): $($(PKG)_BINARY)
+	$(INSTALL_BINARY_STRIP)
+
+$(pkg)-precompiled: $($(PKG)_TARGET_BINARY)
+
+$(pkg)-clean:
+	-$(SUBMAKE) -C $(MYLUA_DIR) clean
+	 $(RM) $(MYLUA_DIR)/.configured
+
+$(pkg)-uninstall:
+	$(RM) $(MYLUA_TARGET_BINARY)
+
+$(PKG_FINISH)
diff -Naur '--exclude=.*' make/mylua.orig/src/Makefile make/mylua/src/Makefile
--- make/mylua.orig/src/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ make/mylua/src/Makefile	2012-09-16 15:35:30.000000000 +0200
@@ -0,0 +1,7 @@
+CC=
+CFLAGS=
+
+all: mylua
+
+mylua: mylua.c
+	${CC} ${CFLAGS} -o mylua mylua.c -Wl,-rpath,/usr/lib,-rpath,/lib -llua -ldl -lm -ltiinterpreter -lluatextdb 
diff -Naur '--exclude=.*' make/mylua.orig/src/mylua.c make/mylua/src/mylua.c
--- make/mylua.orig/src/mylua.c	1970-01-01 01:00:00.000000000 +0100
+++ make/mylua/src/mylua.c	2012-09-16 15:37:53.000000000 +0200
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+#include <luaconf.h>
+/*#include "tolua.h"*/
+
+int main (int argc, char **argv)
+{
+	int output;
+	lua_State *L = luaL_newstate();
+	luaL_openlibs ( L );
+	
+	if (argc < 2) {
+		fprintf(stderr, "%s: There is no lua script!\n", argv[0]);
+		lua_close(L);
+		exit (1);
+	}
+	
+	output = ( luaL_loadfile ( L, argv[1] ) || lua_pcall(L, 0, 0, 0) );
+	
+	if (output) {
+		fprintf(stderr, "%s: There is no lua script!\n", argv[0]);
+		lua_close(L);
+		exit (1);
+	}
+	
+	lua_close(L);
+	return 0;
+}
 
@sf3978: Danke! Ich glaube, man kann aus meiner Anfrage und deiner Antwort zu LUA ruhig einen separaten Thread machen, damit wir hier nicht durcheinander kommen. Ich glaube, das ist es auf jeden Fall Wert! Denn ich bin hier bestimmt nicht der erste und nicht der letzte, wer die AVM-LUA-Skripte analysieren will. Ferner würde ich empfehlen, deinen Patch in den trunk einzuchecken und als "AVM LUA-starter" oder ähnlich zu nennen. Diese Benennung ist notwendig, um es mit dem eigentlichen LUA-Paket nicht zu verwechseln. Binary könnte man ruhig auch als "avm-lua" benennen.

MfG
 
@sf3978:
Gehe ich recht in der Annahme, dass damit sich das mylua-Paket richtig übersetzen lässt, ich zwar die lua-Header aus dem freetz-lua-Paket verwenden soll, aber alle Libraries inklusive der liblua aus der original-Firmware ins $(TARGET_TOOLCHAIN_STAGING_DIR)/lib kopieren soll? Geht das gut? Header von einer Version (5.1.4) mit der Lib von einer anderen (AVM's Version ist 1.4.1 und der soname ist liblua.so.1).

Wofür ist libtiinterpreter zuständig? Wozu wird es dazu gelinkt?

p.s. Habe das Paket noch nicht ausprobiert, alles nur vom Lesen her, sorry wenn ich Blödsinn frage.
 
Wenn ich sf3978 richtig verstanden habe, hat er genau das gemacht, was AVM tun, wenn sie ihren "luacgi" zusammenbauen. Mit dem einzigen Unterschied, dass daraus kein luacgi, sondern ein lua-starter wird. Den Interpreter binden die AVMs auch ein. Außerdem meine ich irgendwo in den Binaries von AVM gesehen zu haben, dass deren LUA auch Version 5 hat.

Ziel dürfte hier sein, AVM-lua-cgis in Shell zu starten bzw. einige Aufrufe von dort ähnlich "nachzuaffen", ohne, dass man dazu über WebIF und cgi geht. Einige der Funktionen hat AVM bewußt in Librares versteckt (z.B. Bearbeitung der "Datenbank"). Darum ist die Einbindung aller denkbaren Libraries notwendig.

Aber ausprobiert habe ich es auch noch nicht...

MfG
 
Ich weiß nicht ob das gut geht. Alle Fragen, Zweifel, Vorbehalte, Einwände, Bedenken, etc. zu diesem Paket, sind z. Zt. berechtigt. Es ist lediglich ein Versuch. Weil so die Fragestellung von Hermann war, libs von AVM zu verwenden, habe ich diese zum dyn. Linken in das Build-System kopiert. Die AVM-liblua.so.1 basiert auch auf der Version 5.1.4:
Code:
# strings toolchain/build/mipsel_gcc-4.6.3_uClibc-0.9.32.1/mipsel-linux-uclibc/lib/liblua.so.1.4.1 | grep Copyright
$Lua: Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio $
Evtl. funktioniert es auch mit der liblua aus dem lua-Freetz-Paket.
Wofür ist libtiinterpreter zuständig? Wozu wird es dazu gelinkt?
libtiinterpreter ist der "Texas Instruments SSI Interpreter für das Webinterface". Evtl. ist dieser nicht für alle Boxen verfügbar. Welche AVM-libs hier geeignet, brauchbar, notwendig, zweckmäßig, ... sind, weiß ich nicht.
 
@sf3978: Ich kann leider nicht durchkompilieren. Sachen, die ich auf jeden Fall machen musste, bevor es mit dem "make" halbwegs lief:
a) Globale make\Config.in händisch um die enstprechende Zeile ergänzen
b) Lua als Paket händisch wählen

Trotzdem fehlen dem make AVM-Libs:
Code:
freetz@freetz-linux:~/7270v3$ make mylua-precompiled
mkdir -p packages/target-mipsel_uClibc-0.9.32.1/mylua-0.1/root
if test -d make/mylua/files; then tar -c -C make/mylua/files --exclude=.svn . | tar -x -C packages/target-mipsel_uClibc-0.9.32.1/mylua-0.1 ; fi
---> package/mylua: preparing... mkdir -p source/target-mipsel_uClibc-0.9.32.1/mylua-0.1
cp -a make/mylua/src/Makefile make/mylua/src/mylua.c source/target-mipsel_uClibc-0.9.32.1/mylua-0.1
cmd() { PATH="/home/freetz/7270v3/toolchain/build/mipsel_gcc-4.6.3_uClibc-0.9.32.1/mipsel-linux-uclibc/bin:/home/freetz/7270v3/toolchain/build/mipsel_gcc-4.6.3/mipsel-unknown-linux-gnu/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" LD_RUN_PATH="/usr/lib/freetz" make -j2  "$@"  || { printf "\n\\033[33m%s\\033[m\n" "ERROR: Build failed.";  exit 1; } };  if [ -e source/.echo_item_start -a ! -e source/.echo_item_build ]; then echo -n "building... "; touch source/.echo_item_build; fi; cmd -C source/target-mipsel_uClibc-0.9.32.1/mylua-0.1 \
                CC="/home/freetz/7270v3/toolchain/build/mipsel_gcc-4.6.3_uClibc-0.9.32.1/mipsel-linux-uclibc/bin/mipsel-linux-uclibc-gcc" \
                CFLAGS="-march=4kc -Os -pipe -Wa,--trap -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 \
                -L/home/freetz/7270v3/toolchain/build/mipsel_gcc-4.6.3_uClibc-0.9.32.1/mipsel-linux-uclibc/lib \
                -I/home/freetz/7270v3/toolchain/build/mipsel_gcc-4.6.3_uClibc-0.9.32.1/mipsel-linux-uclibc/include/lua"
building... make[1]: Betrete Verzeichnis '/home/freetz/7270v3/source/target-mipsel_uClibc-0.9.32.1/mylua-0.1'
/home/freetz/7270v3/toolchain/build/mipsel_gcc-4.6.3_uClibc-0.9.32.1/mipsel-linux-uclibc/bin/mipsel-linux-uclibc-gcc -march=4kc -Os -pipe -Wa,--trap -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64   -L/home/freetz/7270v3/toolchain/build/mipsel_gcc-4.6.3_uClibc-0.9.32.1/mipsel-linux-uclibc/lib  -I/home/freetz/7270v3/toolchain/build/mipsel_gcc-4.6.3_uClibc-0.9.32.1/mipsel-linux-uclibc/include/lua -o mylua mylua.c -Wl,-rpath,/usr/lib,-rpath,/lib -llua -ldl -lm -ltiinterpreter -lluatextdb
/home/freetz/7270v3/toolchain/build/mipsel_gcc-4.6.3_uClibc-0.9.32.1/mipsel-linux-uclibc/bin/../lib/gcc/mipsel-linux-uclibc/4.6.3/../../../../mipsel-linux-uclibc/bin/ld: cannot find -ltiinterpreter
/home/freetz/7270v3/toolchain/build/mipsel_gcc-4.6.3_uClibc-0.9.32.1/mipsel-linux-uclibc/bin/../lib/gcc/mipsel-linux-uclibc/4.6.3/../../../../mipsel-linux-uclibc/bin/ld: cannot find -lluatextdb
collect2: ld returned 1 exit status
make[1]: *** [mylua] Fehler 1
make[1]: Verlasse Verzeichnis '/home/freetz/7270v3/source/target-mipsel_uClibc-0.9.32.1/mylua-0.1'

ERROR: Build failed.
make: *** [source/target-mipsel_uClibc-0.9.32.1/mylua-0.1/mylua] Fehler 1

Was mache ich falsch?

MfG
 
a) Globale make\Config.in händisch um die enstprechende Zeile ergänzen
Wird für "make mylua-precompiled" nicht benötigt, schadet aber auch nicht.
b) Lua als Paket händisch wählen
Reicht nicht, da die Abhängigkeit vom lua-Paket (hier die header-Dateien) (noch) nicht in die mylua.mk eingetragen ist. Deshalb z. Zt. noch "make lua-precompiled" erforderlich.
Trotzdem fehlen dem make AVM-Libs:
Ja, die AVM-libs musst Du manuell von deiner Box in dein Build-System kopieren (d. h. nach "toolchain/build/mipsel_gcc-4.x.x_uClibc-0.9.xx.x/mipsel-linux-uclibc/lib") und dort symlinks auf diese AVM-Libs ändern/erstellen: liblua.so von liblua.so.5.4.1 auf liblua.so.1.4.1 ändern, libluatextdb.so auf libluatextdb.so.1.0.0, libtiinterpreter.so auf libtiinterpreter.so.0.0.0 und libtiinterpreter.so.0 auf libtiinterpreter.so.0.0.0.
 
ok, deine "Hello World!" läuft bei mir auf der Box. Sowohl mit mylua, als auch mit lua. Das Problem ist jetzt nur, dass ich die Passagen von AVM noch nicht zum Laufen gebracht hatte. Immer kommt die Meldung:
Code:
There is no lua script!
Die ist natürlich superaussagekräftig. Ich versuche die Programme mit dem normalen lua zum Laufen zu bekommen und melde mich dann.

Edit: Ich hatte mir ein von den vielen AVM-lua-Skripten genommen und wollte einen kleinen Abschnitt davon testen. Das Programm läuft definitiv nicht durch, sondern bricht mit der oben zitierten Meldung. Ich weiß, dass die Probleme darin liegen, dass eine oder andere Subfunktion nicht eingebunden ist, dass eine oder andere globale Variable vielleicht nicht definiert ist, ohne eine vernünftige Fehlermeldung komme ich aber nicht weiter. mylua scheint schon Probleme mit den ersten Zeilen haben, wo z.B. die ganzen "include"-Sachen stehen.

Gibt es die Möglichkeit, AVM-lua-libs mit unserem normalen lua-Paket und mit unserer normalen lua-binary zu "verheiraten", damit man eine aussagekräftigere Fehlermeldung bekommt?

MfG
 
Zuletzt bearbeitet:
Edit: Ich hatte mir ein von den vielen AVM-lua-Skripten genommen und wollte einen kleinen Abschnitt davon testen.
Welche AVM-lua-Scripte hast Du getestet. Kann es sein, dass diese evtl. Javascript-Code und/oder html-Elemente beinhalten?
 
Kostenlos!

Statistik des Forums

Themen
248,915
Beiträge
2,304,948
Mitglieder
378,626
Neuestes Mitglied
0xFaB1