AMS/ADS protokoll implementálása php-ben

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!

Hozzászólások

Senki? :(
Vagy kéne egy kis kód is (nem akartam ezzel traktálni a népet...)?

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.

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?

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?

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

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 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/

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 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.