Sziasztok,
a következö a felállás: soha az életben nem csináltam még semmilyen "mélyebb" netes dolgot és mindig is érdekelt, hogyan müködik a kommunikáció valójában. Más okok miatt érdekelne az AMS/ADS protokoll implementációja (bal oldali frame-ben kell tovább lépegetni), amely nem tünik túl komplikáltnak és megoldhatatlannak.
Az egészet php parancssorban (CLI), mert az adatokra neten lenne szükségem és a php-t jól ismerem. Most ott tartok, hogy
- van wireshark-ban helyes mintám ADS-re (összehasonlítás végett) itt (a 3. frame-töl indul),
- összeraktam egy (szerintem) helyes AMS csomagot
- php-ban megnyitok egy raw TCP socket-et és beletolom a csomagot
- már volt olyan, hogy kaptam rá ACK-t, de választ nem (wireshark log itt)
- jelenleg csomag ki, nincs ACK és crtl+C és újrafuttatás után már csak RETRANSMIT-ot sikerül küldeni, amire megint nincs válasz.
- hiába adom meg a protokoll által megkövetelt port-ot (48898), nem azon, hanem mindig a 12336-on küldi a csomagot.
Kérdéseim:
1) hogyan lehet a php-t rábírni a megadott port kötelezö betartására?
2) hogyan tudom az OP-rendszert rávenni, hogy ha bázárok/kilövök egy csatornát, a következö küldemény ne RETRANSMIT legyen?
3) a helyes mintában lévö 3 és 5-ös frame kiküldésére szükség van, hogy létrejöjjön a kommunikáció? (192.168.10.96 -> állógép, .200 -> PLC)
4) a protokollleírásban szereplö AMS/TCP headert (2 bájt 0x00 + 4 bájt adathossz) kell a socket-re írandó adatsorban legelöször küldeni, ugye? A hosszat elég úgy számolni, hogy megszámolom hány bájt van az AMS-header elejétöl a DATA rész végéig?
Nézegettem a TCP/IP alapok pdf-et, de nem találtam mindenre választ és guglin sem találtam a sepciális problémáimra választ. Ha valakinek több tapasztalata van, kérem ossza meg, mert szivesen tanulnék belöle!
Elöre is köszi!
- 1481 megtekintés
Hozzászólások
Senki? :(
Vagy kéne egy kis kód is (nem akartam ezzel traktálni a népet...)?
- A hozzászóláshoz be kell jelentkezni
Csak egy ötlet a port problémára. A php programot próbáld root-ként elindítani és megnézni, hogy ott jó portot használ-e.
- A hozzászóláshoz be kell jelentkezni
köszi, igen sudo-val indítom, mert simán socket-et csak root tud létrehozni (ugyan találtam már rá vmi workaround-ot, de még nem próbáltam)
- A hozzászóláshoz be kell jelentkezni
Döntsd el mit szeretnél, mert ez így nem kerek sehogy sem.
Most vagy RAW socketet használsz, amikor te állítod össze az eth+tcp+ip headert, vagy TCP-t.
Ha RAW-al te állítod össze a csomagod teljes egészében, akkor mi köze van a php-nak ahhoz, hogy milyen portot raksz a protokoll fejlécébe?
- A hozzászóláshoz be kell jelentkezni
nah, témánál vagyunk....:) ez egy fontos kérdés számomra, hogy egyáltalán megértsem honnantól kell nekem összeraknom a csomagot!
a RAW-t illetöen: amikor megnyitom a socket-et, meg kell adnom a cél portot, ha jól értem - viszont azt sosem az általam kért portra nyitja, hanem a már említett 12363-ra - vagy még mindig keverek valamit?
- A hozzászóláshoz be kell jelentkezni
Egymásra épülő protokolokról beszélünk, esetedben valahogy így nézhet ki:
ethernet->ip->tcp->AMS
Ha TCP kapcsolatot nyitsz, akkor csak az AMS részével kell foglalkoznod, vagyis a TCP csomagokon belűli adatréteggel.
Ha RAW kapcsolattal próbálkozol, akkor ethernet-től kezdve fölfele mindegyikkel, ami nem túl szerencsés sok szempontból (egyrészt mert kalkulálnod kell a routing-al, a fragmentációval(ha szükséges), a TCP handshake-el és minden mással).
Azért nyit ugyanarra a portra, mert azt te magad definiálod az adatcsomagban (SOCK_RAW esetében nincs értelme a portnak, mivel azt később a csomagban te magad definiálod)
Szóval RAW socketet csak akkor használj, ha tényleg van értelme (jelen esetedben szerintem nincs).
Vagyis ami neked kell: AF_INET/SOCK_STREAM
- A hozzászóláshoz be kell jelentkezni
vagy AF_INET6! ;)
- A hozzászóláshoz be kell jelentkezni
nem tudja a PLC..:) (mégha az IP 192.168.10.200.1.1-nak van kódolva, akkor sem...:)
- A hozzászóláshoz be kell jelentkezni
ha már raw socket, legyünk merészek, AF_INET42
- A hozzászóláshoz be kell jelentkezni
köszi, így már kezd tisztulni a köd.
mindjárt lépek haza, és akkor nekiállok újra - ha jól értem, akkor a socket_create() maradjon AF_INET/SOCK_STREAM opciókkal, és nem az fsockopen() kell?
- A hozzászóláshoz be kell jelentkezni
fsockopen is jo, a lenyeg hogy neked tcp stream -re van szukseged, nem raw socketre
- A hozzászóláshoz be kell jelentkezni
na a csomag kapásból jó lett SOCK_STREAM-el, köszi.
már csak egy a bibi:
a socket_send így van meghatározva:
int socket_send ( resource $socket , string $buf , int $len , int $flags )
viszont ha én 0-át akarok küldeni, azt a $buf-ba kell beírni, ami ugye string. Viszont akkor "0" lesz belöle, ami az ASCII tabella szerint 0x30 hexben, és az nekem nem jó. Itt milyen trükköt kell használni, hogy össze tudjam füzni a különbözö mezöket és utána ne ASCII kódban küldjem az üzenetet?
- A hozzászóláshoz be kell jelentkezni
ne phpban ird... amugy sem ertem, miert akarnad abban irni :-)
- A hozzászóláshoz be kell jelentkezni
na megvan, pack("H*", $buf) a barát amd64 alatt.
azért, mert relative könnyen portolható és igazából csak kipróbálni akartam. Most jön a következö perverz ötletem: Haskell-be szeretném átrakni az egészet...:D:D:D:D
- A hozzászóláshoz be kell jelentkezni
A legegyszerűbb ha a $buf -ot a php beépített pack() függvényével rakod össze. Ez tipikusan bináris stringek létrehozására találták ki. Másrészt rengeteg dolgot leegyszerűsít, mivel oda-vissza konvertálja pl a számokat binárisba helyiérték szerint is akár (low endian/big endian, architektúrától függően).
url: http://hu.php.net/pack/
- A hozzászóláshoz be kell jelentkezni
köszi, 2-vel feljebb írtam, hogy végül is meg lett. Az endianness-t most kézzel oldottam meg, esetleg nem is baj, mert szeretném linux, XP Embedded, CE x86 és CE ARM plattformokon kipróbálni.
- A hozzászóláshoz be kell jelentkezni
köszi még 1x, nagyon jó útba igazítás volt. Már müködik is az írás és az olvasás!
Van még egy fura TCP csomag minden AMS válasz után a PLC-töl, ezt majd még meg kell vizsgálni.
- A hozzászóláshoz be kell jelentkezni
ha a működést nem korlátozza, akkor az szerintem valami ack csomag lesz a PLC felől, bár a dokumentációt nem futottam át
- A hozzászóláshoz be kell jelentkezni
szerintem sajnos még valami nem 100-as, mert a wireshark valami TCP Zerowindow csomagot mutat a PLC-töl és azt hiszem hibás csomagnak szinezi. Ha itt jól értem akkor ez csak annyit jelent, hogy "ne küldj több csomagot", de majd meg kell néznem, van-e ilyen akkor is, ha a hivatalos szoftver kommunikál a PLC-vel.
- A hozzászóláshoz be kell jelentkezni
A TCP protokollok esetén csak a szerver portot szokás definiálni, a kliens arról a portról kapcsolódik, amelyikről csak akar. Sőt az API-k úgy is működnek, hogy kliens esetén nem adunk meg portot, hanem random ad egyet az oprendszer az erre kijelölt poolból. Ha jól vettem le, akkor te klienst implementálsz a protokollhoz, nem?
Egyébként ilyen 3 betűs rövidítésekből nem egyértelmű az, hogy mi is ez a protokoll.
- A hozzászóláshoz be kell jelentkezni
azert az nem igaz, hogy az APIk nem engedik a forrasportot definialni. ha megsem engedik, akkor bizony br0ken.
- A hozzászóláshoz be kell jelentkezni
ugy remlik mintha kliens oldalon is bind-elhettel volna...
--
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!
- A hozzászóláshoz be kell jelentkezni
De nem szükséges, sőt, akár káros is lehet (pl. mert egy másik kliens pont használja.)
----------------
Lvl86 Troll
- A hozzászóláshoz be kell jelentkezni
igen, klienst implementálok és én a szerver portot akartam megadni, lásd feljebb.
ADS = Automation Device Specification
AMS = Automation Message Specification
ezért linkeltem be feljebb a teljes doksit hozzá
- A hozzászóláshoz be kell jelentkezni
Szerver portot a connect-nél kell, a bind az másra való, ha esetleg ez lenne a keveredés tárgya.
----------------
Lvl86 Troll
- A hozzászóláshoz be kell jelentkezni