NVT (Network Virtual Terminal) popis protokolu

NVT (Network Virtual Terminal) je dost komplikovaná záležitost z hlediska jednotlivých navazujících terminálů, jejich modifikací atd. = v použití s klasickým serverem. V našich aplikacích však používáme z NVT jenom zlomek možností a z hlediska pochopení principu není NVT nic složitého. Jedná se o řídící sekvence v datovém toku po TCP/IP, kdy znak „FF“ v datovém toku uvozuje následnou řídící sekvenci, která má předepsaný formát, popsaný podrobněji v kapitole o Telnetu. Je-li v datech potřeba přenést tento znak „FF“ (hodnotu bytu 255 decimálně), musí jej vysílací strana zdvojit, jinak budou data za tímto znakem považována za řídící sekvenci, a dojde ke kolizi. NVT lze proto vypnout a pokud jej používáte, musí minimálně toto zdvojení znaku „FF“ respektovat obě strany síťového spojení.
Pomocí řídících sekvencí v NVT lze nastavovat rychlost RS232, 9. bit, vyčítat sériové číslo modulu nebo přímo ovládat binární vstupy a výstupy.
 

Zde je nutné uvést, že česká verze této dokumentace je pouze zkratkou anglické verze, byla vytvořena pouze jednorázově a nadále nebude updatována. Pro 100% ověření informací prosím prostudujte anglickou verzi této dokumentace, nebo se zeptejte..

Article content :

- Popis implementovaných příkazů NVT v našich zařízeních
- Základní podporované funkce NVT
- Podporované RFC2217 funkce
- Podporované funkce General Purpose Input Output (GPIO) rozhraní
- Příklady pouřití NVT

- The Telnet Protocol

- Datasheety & Odkazy

 

Popis implementovaných příkazů NVT v našich zařízeních

V našich zařízeních se snažíme zůstávat kompatibilní s již existujícími normami, ale mnohdy je třeba kombinovat norem několik, protože některá rozšíření jsou pro naše aplikace zbytečná, zatímco jiné funkce potřebujeme, a proto je daná funkce jediná, co z nějaké normy podporujeme. Většinou se však jedná o rozšíření z RFC2217 (ovládání vlastností sériového asynchronního přenosu) o ovládáni GPIO (I/O piny procesoru, nebo dalších zařízení), případně některé další.

Kompletní norma RFC 2217 - rfc2217.txt

 

Základní podporované funkce NVT

Základní principy a funkce TELNET protokolu jsou posané v RFC854 (rfc0854.txt). Podrobnější popis TELNETu najdete v druhé polovině tohoto článku - "The Telnet Protocol".

 

Dec HEX Shortcut Description
240 F0 SE End of sub negotiation parameters
Konec parametrů příkazu zavírá párový příkaz, uvedený SB
241 F1 NOP No Operation
Používá se např. pro udržení spojení při výpadku datového toku.
246 F6 AYT Are You There
Vrací typ zařízení (+ např. verzi fw, MAC adresu atd..) nebo jen „YES“.
250 FA SB Indicates that what follows is sub negotiation of the indicated option.
Následuje po IAC, uvozuje začátek párového příkazu ukončeného SE.
255 FF IAC Data Byte 255
Prefix označující začátek NVT příkazu. Není-li následován dalším znakem FF, je následující sekvenc vždy zpracovávána jako NVT příkaz.
  

Podporované RFC2217 funkce

RFC2217 je standard definovaný v roce 1997 panem G. Clarkem z Cisco Systems, Inc. Je to návrh normy vzdáleného ovládání sériového portu přes TCP/IP. Případně si nastudujte originální RCF 2217 dokumentaci - rfc2217.txt

 

Podporujeme :

Com Port Control Client to Access Server constants
CAS_SIGNATURE, 0
CAS_SET_BAUDRATE, 1
CAS_SET_DATASIZE, 2
CAS_SET_PARITY, 3
CAS_SET_STOPSIZE, 4
CAS_SET_CONTROL, 5
CAS_NOTIFY_LINESTATE, 6
CAS_NOTIFY_MODEMSTATE, 7
CAS_FLOWCONTROL_SUSPEND,8
CAS_FLOWCONTROL_RESUME, 9
CAS_SET_LINESTATE_MASK, 10
CAS_SET_MODEMSTATE_MASK,11
CAS_PURGE_DATA, 12
CAS_OPT_GPIO, 50
CAS_SET_GPIO, 51

Com Port Control Access Server to Client constants
ASC_SIGNATURE, 100
ASC_SET_BAUDRATE, 101
ASC_SET_DATASIZE, 102
ASC_SET_PARITY, 103
ASC_SET_STOPSIZE, 104
ASC_SET_CONTROL, 105
ASC_NOTIFY_LINESTATE, 106
ASC_NOTIFY_MODEMSTATE, 107
ASC_FLOWCONTROL_SUSPEND,108
ASC_FLOWCONTROL_RESUME, 109
ASC_SET_LINESTATE_MASK, 110
ASC_SET_MODEMSTATE_MASK,111
ASC_PURGE_DATA, 112
ASC_OPT_GPIO, 150
ASC_SET_GPIO, 151

 

Podporované funkce General Purpose Input Output (GPIO) rozhraní

Rozšířili jsme standard RFC2217 o několik GPIO (General Purpose Input Output) funkcí, které jsou dále uvedeny. Nejedná se o žádný standard, ale v roce 2001 kdy jsme tato rozšíření implementovali nám žádný podobný standard nebyl znám..

 

COM-PORT-OPTION - 44 (2C hex)

Za popsanou sekvencí IAC SB může navazovat i v RFC2217 popsaný rozšiřující příkaz COM-PORT-OPTION (příkaz je samozřejmě ukončen sekvencí IAC SE), jehož některé podpříkazy dále popíšeme, ale detaily najdete ze zmíněném RFC2217.

Hodnoty do 100 decimálně platí pro směr komunikace Client >> Server
Hodnoty nad 100 decimálně platí pro směr komunikace Server >> Client

Dec HEX Description
0 00  CAS_SIGNATURE
1 01  CAS_SET_BAUDRATE
2 02  CAS_SET_DATASIZE
3 03  CAS_SET_PARITY
4 04  CAS_SET_STOPSIZE
5 05  CAS_SET_CONTROL
6 06  CAS_NOTIFY_LINESTATE
7 07  CAS_NOTIFY_MODEMSTATE
8 08  CAS_FLOWCONTROL_SUSPEND
9 09  CAS_FLOWCONTROL_RESUME
10 0A  CAS_SET_LINESTATE_MASK
11 0B  CAS_SET_MODEMSTATE_MASK
12 0C  CAS_PURGE_DATA
50 32  CAS_OPT_GPIO
51 33  CAS_SET_GPIO
52 34  CAS_SET_GPIOM
: :  
+100 +64  ASC_
150 96  ASC_OPT_GPIO
151 97  ASC_SET_GPIO
152 98  Not implemented, one way "answer" only


Supported NVT commands

CAS_ výzva pro zařízení k provedení nějakého příkazu, ASC_ je naopak odpověď zařízení, že příkaz byl proveden a potvrzení nastavených hodnot.

 


 

COM-PORT-GPIO SUBOPTION - 50, 51, 52 (32 .. 34 hex)

Pro přímé ovládání I/O pinů používáme pevně dvoubajtový podpříkaz GPIO – 50 nebo 51 (řazený za příkaz COM-PORT-OPTION 44) následovaný dále popsanou sekvencí suboption.

Sub option 50 (32 hex)

  • 0 (00 hex) - Žádost o přečtení stavu vstupů, v odpovědi na tento příkaz je tedy uvedena hodnota vstupního portu (piny CPU nebo vstupní posuvný registr)
  • 16 .. 23 (10 .. 17 hex) – nastav výstupní bit 0..7 na log. 1
  • 32 .. 39 (20 .. 27 hex) – nastav výstupní bit 0..7 na log. 0
  • 48 (30 hex) - Žádost o přečtení stavu výstupů, v odpovědi na tento příkaz je tedy uvedena hodnotav výstupního portu (respektive jeho vnitřní pseudoregistr)

 

Sub option 51 (33 hex)
Nastaví odeslanou hodnotu XX na výstupní port, viz příklad. V odpovědi vrátí tutéž hodnotu, protože ji přečte pouze z vnitřního pseudoregistru.

Prakticky tak odesláním sekvence „FF FA 2C 32 XX FF F0“ do datového toku ovládáme znakem XX GPIO port. Například XX = 11 hex nastaví P1.1 na log. 1 a ostatní piny zachová.

 

Sub option 52 (34 hex)
Posílá samočině hodnotu na vstupech, pokud došlo ke změně stavu, nebo po zapnutí napájení. Tento příkaz neočekává odpověď, proto není v tabulce uvedena hodnota pro 152 (98 HEX), protože samotné hlášení je vlastně nevyžádanou odpovědí, které nepředcházela žádná výzva!
Před tímto příkazem, ale vždy předchází sekvence „FF FA 2C 32 00 FF F0“, která jej v podstatě uvozuje. Tento příkaz se používá když jsou použita dvě zařízení proti sobě pro synchronizaci jejich binárních vstupů a výstupů.

Prakticky tak přijetím sekvence „FF FA 2C 34 XX FF F0“ v datovém toku získáváme informaci o nov0 platné hodnotě XX vstupního portu.

Proč dvě sekvence ?
V korektní komunikaci dvou I/O Controllerů proti sobě, ale pošle první I/O Controller sekvenci „FF FA 2C 32 00 FF F0“ pouze jednou, protože druhý (tázaný) I/O Controller mu příkazem „FF FA 2C 97 XX FF F0“ odpoví stav (XX) svých vstupů a nadále je již oběma stranami posílána pouze sekvence „FF FA 2C 34 XX FF F0“, pokud došlo ke změně stavu na jejich vstupech.

Poznámka: pro to, aby byla funkce posílání změn na vstupech aktivní, je třeba na našich zařízeních nastavit rozsah přenášenách vstupů proměnnou "#T: Trigger AND mask".

  • Pro přenos všech vstupů nastavte #T=255
  • Pro vypnutí funkce přenosu změny vstupů nastavte #T=0


 

Příklady použití NVT

Většina příkazů NVT počítá s pevným počtem znaků. Pokud je tedy nastavení hodnoty ve formátu 4 byte s tím, že se lze zeptat na aktuální nastavenou hodnotu „nastavením“ hodnoty 0, je třeba odeslat tuto 0 jako sekvenci 00 00 00 00 hex.


Nastavování výstupního bytu

Následující příkaz nastaví výstupní port na hodnotu AA (10101010 bin)

<IAC><SB><COM_PORT_OPTION><CAS_SET_GPIO><byte to output)><IAC><SE>
 FF   FA        2C              33            AA          FF   F0

Jako odpověď přijde následující sekvence potvrzující nastavení portu:
<IAC><SB><COM_PORT_OPTION><ACS_SET_GPIO><byte to output)><IAC><SE>
 FF   FA        2C              97            AA          FF   F0

 

 

Přečtení vstupů

Odešlu sekvenci FF FA 2C 32 00 FF F0 >> Embedded server vrátí : FF FA 2C 96 XX FF F0
- kde XX je okamžitá hodnota na vstupních pinech,

 

Přečtení výstupu

Odešlu sekvenci FF FA 2C 32 30 FF F0 >> Embedded server vrátí : FF FA 2C 97 XX FF F0
- kde XX je okamžitá hodnota na registru, podle něhož se nastavují výstupní piny.

 

Vynulování výstupu P1.5 (nebo D5 datového výstupu)

Odešlu sekvenci FF FA 2C 32 25 FF F0 >> Embedded server vrátí : FF FA 2C 97 DF FF F0

Kde DF je skutečná hodnota na výstupním portu (záleží také na předchozím stavu portu). Emberred server tedy změní pouze jeden bit, ale vrátí potvrzení celého nastavení i se skutečnou hodnotou na portu.

 

Hlášení o změně stavu na vstupech

Neodesílám z PC žádnou výzvu, při změně hodnoty vstupu přijmu sekvenci FF FA 2C 32 00 FF F0 a sekvenci FF FA 2C 34 XX FF F0

Kde hodnota XX je aktuálně platná hodnota na vstupním binárním portu.

Funkce samozřejmě funguje stejně jako vstupní data ze sériového portu, to znamená, že pokud je nastaven režim TCP Client/Server (uvedena IP adresa protistrany) a zapnuté NVT, při přijetí 1 bytu z sériového portu, stějně tak jako při změně na bin. vstupech, se zařízení pokusí sestavit TCP spojení s odeslat informaci o změně stavu vstupu. Po otevření TCP spojení, ale pošle POUZE v té chvíli aktuální stav vstupů, nikoliv celý záznam změn během neotevřeného TCP spojení!

Poznámka: pro to, aby byla funkce posílání změn na vstupech aktivní, je třeba na našich zařízeních nastavit rozsah přenášenách vstupů proměnnou "#T: Trigger AND mask".

  • Pro přenos všech vstupů nastavte #T=255
  • Pro vypnutí funkce přenosu změny vstupů nastavte #T=0

 

 

Jak změnit Baudovou rychlost sériového portu RS-232 / RS-485

Aktuální rychlost sériového portu zjistíte odesláním hodnoty 00 00 00 00. Pokud odešlete jakoukoliv jinou hodnotu, server na ní nastaví rychlost sériového portu. Hodnota převedená do desítkové soustavy udává přímo rychlost v baudech.

Odešlu FF FA 2C 01 00 00 00 00 FF F0 >> server vrátí : FF FA 2C 65 00 00 25 80 FF F0
Po převodu 00 00 25 80 na desítkovou soustavy => aktuální rychlost je 9600 Bd.

 

Keep Connection

Pro udržení aktivního spojení, pokud neběží datový tok, lze použít volbu “K: Keep connection” v setupu Embedded zařízení. Volba funguje pouze, je-li zapnuta podpora NVT.
Spojení je udržováno posíláním příkazu NOP (sekvence FF F1) ze strany Embedded zařízení každých cca 5s.

 

Jak na 9. bit

Od verze firmwaru 2.3 je implementována podpora přepínání parity „space/mark“ pomocí NVT příkazů. Toho lze využít k nastavení a opětovnému shození pomyslného 9. bitu, který využívají některé starší aplikace z počátku 90. let, kdy se jednalo o časté řešení, jak oddělit adresu od dat.

Pozor, změna parity se projevuje asynchronně = nebufferuje se, ale vykonává se ihned po přijetí příkazu.
Synchronně (a bufferovaně) to bude možné až v dalších verzích firmware, zasláním 0xFE 'P', který reverzuje paritu. Totéž je při příjmu dat, pokud je přijat znak s chybou parity, tak se v datech objeví 0xFE 'P'. Samotné 0xFE se musí v datech zdvojovat. Jedná se o obdobu NVT, ale zde nad daty v bufferu. Příznak reverzované parity je samozřejmě před bytem, který ji má mít otočenou.

 

Are You There ?

Pro ověření, zda je na druhé straně nějaké zařízení, existuje v Telnet standardu výzva „Are you there“, na kterou standardní unixové zařízení umí odpovědět většinou ve formátu “Yes”.
Tuto hlášku jsme rozšířili tak, že na výzvu : FF F6 náš Embedded server odpoví v následujícím formátu :

<WEB51 HW 4.5 SW 2.3 SN 01A03B #01>

It means :
<WEB51 HW XXX SW XXX SN 1035EE #0F *OvErr *ParErr *FlErr>

Je uveden název zařízení, verze hardware, verze firmware a 6 znaků za výzvou „S/N“, je sériové číslo zařízení (poslední 3 byty MAC adresy v HEXu). Sekvence z hvězdičkou na začátku jsou nepovinné a uvádějí čísla případných chybových hlášení.

 

 

 

The Telnet Protocol

Co to je NVT (Network Virtual Terminal)

Následující text jsme poskládal z nejrůznějších zdrojů na internetu. Můj dík patří především panu Hlavenkovi, který se velmi rozepsal o této problematice, a mnoho detailů lze najít na serveru www.zive.cz. Text je zveřejněn prakticky v původní podobě, místy zkrácen o témata, která již zcela nesouvisejí s tématikou.

Jedná se pouze o uvedení do "filozofie" a embedded server vzhledem k tomu, že je pouze mezičlánkem mezi aplikací a serverem, nemůže všech těchto funkcí využít a využívá především funkce popsané v RFC2217. Ty ostatní pouze korektně zpracovává, případně ignoruje.

NVT je zkratka vzniklá z network virtual terminal. NVT je podmnožinou protokolu Telnet, tj. jakoby se protokol Telnet skládal ze dvou vrstev: ze spodní vrstvy – NVT a horní vrstvy – vlastního protokolu Telnet. Protokol NVT se zabývá prezentací dat, tj. v jaký bajt se má změnit písmeno A, aby na druhém konci síťového spojení bylo interpretováno opět jako A, či jaký příkaz protokolu Telnet se má vygenerovat po stisku známého ^C pro abnormální ukončení programu spouštěného z terminálu.Právě protokol NVT je použit v omezené míře pro prezentaci dat v mnoha dalších protokolech jako jsou FTP, POP3, SMTP, NNTP i HTTP apod. V podstatě MIME je rozšířením této filosofie.

NVT dále předpokládá, že přenos dat bude tzv. bufferován - tedy že data nebudou vysílána po jednotlivých znacích, ale že se budou nejprve hromadit ve vhodných vyrovnávacích pamětech (anglicky: buffers), a skutečně vysílány pak budou až větší celky. Jaké celky to ale mají být?

U řádkového terminálu, jakým je NVT, je jednoznačným kandidátem řádka. Délka řádky ovšem není pevně stanovena, a to ani u tiskárny. Na straně klienta určuje skutečnou délku každé jednotlivé řádky uživatel, který pracuje na příslušném terminálu - tím, že v určitý okamžik zmáčkne tlačítko ENTER, RETURN, NEW LINE či jak se na jeho terminálu jmenuje klávesa, kterou se zadává konec řádky. Klientská složka protokolu TELNET, která zpracovává uživatelův vstup z klávesnice, může na základě zmáčknutí této klávesy obdržet různý kód (např. jen znak CR, jen znak LF, dvojici znaků CR a LF apod.), podle konkrétního použitého terminálu. Sama však musí na jeho základě vygenerovat dvojici znaků CR a LF, neboť virtuální terminál NVT počítá s tím, že řádky budou zakončovány právě tímto způsobem. Analogicky je tomu i na straně serveru - aplikační proces, který generuje data určená k zobrazení na terminálu, je člení na jednotlivé řádky takovým způsobem, jaký předpokládá příslušná "místní" konvence. Serverová složka protokolu TELNET je však před odesláním překládá do takového tvaru, aby byly zakončeny dvojicí CR LF.

Protokol TELNET tedy předpokládá, že data budou standardně přenášena po celých řádcích. To ale nemusí být vždy možné - není-li délka řádky předem omezena, může se stát, že pro ni nebude k dispozici dostatečně velká vyrovnávací paměť. Také to ale nemusí být vždy žádoucí - někdy může být vhodné, či dokonce nutné, odesílat menší celky než celé řádky, až např. po jednotlivé znaky. S touto možností protokol TELNET počítá a doporučuje ji realizovat. Přesný mechanismus, kterým by si zdroj dat mohl vynutit jejich odeslání ještě před zakončením řádky, je však ponechán na konkrétní implementaci. Ostatní je na vzájemné dohodě.

Pro správné pochopení smyslu a role virtuálního terminálu NVT je velmi důležité si uvědomit, že každý virtuální terminál vždy omezuje "individualitu" konkrétních terminálů a redukuje jejich vlastnosti a schopnosti na takovou úroveň, která může být společná prakticky všem fyzicky existujícím terminálům. Nejinak je tomu i v případě virtuálního terminálu NVT, který si proto můžeme představit jako největší společný jmenovatel všech ještě použitelných terminálů. Protokol TELNET jej však chápe jen jako "povinné minimum" a připouští, aby se obě strany mohly v konkrétním případě dohodnout "na lepším" - tedy na tom, že mají a jsou schopny používat nějaká rozšíření vůči tomu, co požaduje NVT.

Přitom ale platí zásada, že použití rozšíření (anglicky: options) si nelze vynucovat - každá strana má právo vznášet návrhy na jejich použití, ale druhá strana má vždy právo je odmítnout. Díky tomu je možné vystačit i s "hloupými" terminály, jejichž skutečné schopnosti nepřesahují minimum, požadované virtuálním terminálem NVT, a na druhé straně je možné efektivně využít možnosti a schopnosti lépe vybavených terminálů.

Bezprostředně po navázání spojení tedy obě strany mohou používat právě a pouze to, co jim zaručuje virtuální terminál NVT. Mohou však kdykoli zahájit "licitaci", v rámci které se dohodnou na použití oboustranně přijatelných rozšíření. Vzájemné domlouvání na použití různých rozšíření obvykle probíhá okamžitě po navázání spojení, ale není to nutnou podmínkou. Stejně tak se mohou obě strany kdykoli dohodnout na tom, že přestanou určité rozšíření používat. Zajímavá je v tomto ohledu také zásada rovnoprávnosti - každá ze stran má stejné právo navrhnout používání určitého rozšíření, a stejně tak může požadovat i ukončení používání určitého rozšíření (žádosti tohoto typu přitom nesmí být druhou stranou odmítnuty).

Protokol TELNET samozřejmě musí definovat konkrétní způsob, jakým mají obě strany postupovat při vzájemné "licitaci" (anglicky: options negotiation). Příslušný mechanismus je ovšem koncipován jako otevřený - nemůže totiž anticipovat všechna budoucí rozšíření, která budou připadat v úvahu, a tak pro ně nemůže přesně předepisovat konkrétní formu "licitace". Místo toho ponechává otevřený prostor pro individuální postupy vzájemného dohadování, ale současně s tím je umožňuje jednoznačně detekovat, tak aby druhá strana měla vždy možnost rozpoznat, že jde o nabídku používání rozšíření, a i když jí nerozumí, mohla ji odmítnout.

Sedmibitové znaky v osmibitových bytech

Pro kódování jednotlivých znaků používá protokol TELNET znakový kód ASCII. Požaduje, aby tiskárna (resp. zobrazovací zařízení) virtuálního terminálu NVT byla schopna znázornit všech 95 alfanumerických znaků ASCII (s kódy 32 až 127), a z 33 řídících znaků povinně vyžaduje interpretaci znaků NULL, CR a LF. Kromě toho stanovuje přesný význam i pro řídící znaky BEL (Bell), BS (Back Space), HT (Horizontal Tab), VT (Vertical Tab) a FF (Form Feed), a to v souladu s jejich významem v kódu ASCII - ovšem s tím, že interpretace těchto znaků není povinná (tj. tiskárna je nemusí interpretovat vůbec, ale pokud ano, pak jen stanoveným způsobem). Pro ostatní řídící znaky kódu ASCII je stanoveno, že nebudou mít na tiskárnu žádný efekt.

Po klávesnici virtuálního terminálu NVT je naopak požadováno, aby byla schopna generovat všech 128 znaků kódu ASCII (i když některé nemají na tiskárnu žádný efekt). Kromě toho je požadováno, aby klávesnice NVT generovala ještě i několik dalších znaků, které mají význam řídících příkazů protokolu TELNET (o nich bude řeč příště).

Jednotlivé znaky sedmibitového kódu ASCII jsou ovšem přenášeny zásadně v osmi bitech. Díky tomu je pak možné k nim "přidat" ještě i právě naznačené řídící příkazy (odlišené nastavením nejvyššího bitu). Jako jedno z možných rozšíření se ale obě strany mohou dohodnout na tom, že si budou předávat osmibitové znaky (tj. znaky, kódované v osmi bitech). Pak je ovšem nutné zajistit potřebnou transparenci - umožňující jednoznačně odlišit příkazy od "užitečných dat" - jiným způsobem.

Veškerá komunikace mezi klientskou a serverovou složkou protokolu TELNET má zásadně charakter přenosu znaku. Mají-li pak být v takovémto prostředí implementovány jakékoli řídící mechanismy a postupy, musí mít příslušné řídící příkazy i veškeré reakce na ně opět povahu znaku. Musí však být zajištěna také potřebná transparence dat - musí být možné jednoznačně rozlišit, které znaky představují "užitečná data" a které naopak představují řídící příkazy.

Tvůrci protokolu TELNET měli v zásadě dvě možnosti, jak tohoto cíle dosáhnout. Jednou bylo přisoudit význam řídících příkazu některým ASCII znakům. Tím by se ale připravili o možnost používat tytéž znaky v jejich původním významu, který mají v kódu ASCII, a navíc by si tím dosti omezili možný repertoár vlastních řídících příkazů (protože takto využitelných znaku ASCII je jen velmi omezený počet). Proto se autoři protokolu TELNET raději rozhodli pro druhou možnost, kterou představuje samostatné kódování řídících příkazů, nezávislé na kódu ASCII.

Zajištění transparence

Jak jsme si již uvedli, protokol TELNET přenáší jednotlivé znaky v osmibitových bytech. Znaky kódu ASCII jsou však jen sedmibitové, a pro potřeby přenosu se doplňují nejvyšším bitem, nastaveným na nulu. Pro kódování svých řídících příkazů se pak tvůrcům protokolu TELNET nabízelo všech 128 možných 8bitových hodnot, s nejvyšším bitem nastaveným na jedničku - a tuto možnost také skutečně využili. Zde je ovšem důležité si uvědomit, že virtuální terminál NVT sice předpokládá pouze přenos sedmibitových ASCII znaků, ale že jednou z možnosti rozšíření je přenos osmibitových znaků. Jakmile se ale toto rozšíření použije, okamžitě se tím ztrácí automatické rozlišení mezi "užitečnými" znaky a řídícími příkazy podle hodnoty nejvyššího (přesněji: nejvýznamnějšího) bitů.

Samotný způsob kódování řídících příkazu tedy ještě nemohl zajistit potřebnou transparenci dat, a proto tvůrcům protokolu TELNET nezbylo než použít řešení obvyklé např. u znakově orientovaných linkových protokolů či u řídících jazyků pro ovládání tiskáren a obdobných znakově orientovaných zařízení: před samotný řídící znak zařadit speciální znak, který změní interpretaci jednoho, resp. několika následujících znaků. V případě tiskáren jde o znak ESCAPE (s ASCII kódem 27, resp. 1B hexadecimálně), který uvozuje tzv. ESCAPE sekvence, zatímco u linkových protokolů jde o znak DLE (Data Link ESCAPE, s ASCII kódem 16, resp. 10 hexadecimálně), který prefixuje řídící znaky začátku a konce rámce apod. V případě protokolu TELNET byl zvolen znak s číselných kódem 255 (resp. FF hexadecimálně), označovány jako IAC (Interpret As Command, dolova: interpretuj jako řídící příkaz), který povinně uvozuje všechny řídící příkazy. Pokud by se číselný kód tohoto znaku (tj. kód 255) vyskytl v "užitečných" datech, musí být zdvojen, čímž se zamezí jeho interpretaci jako uvozujícího znaku řídícího příkazu.

Příkazy protokolu TELNET

Většina řídících příkazů protokolu TELNET je reprezentovaná jedním řídícím znakem, ke kterému se přidává povinný prefix - znak IAC - takže nejkratší příkaz je tvořen dvěma osmibitovými byty. Existují ovšem i příkazy, pro jejichž vyjádření jediný řídící znak nestačí a je nutné použít ještě jeden dodatečný znak. I v tomto případě se ale používá jediný uvozující znak IAC, takže výsledný příkaz je tvořen třemi byty. Pro ještě "delší" příkazy se pak již používá poněkud odlišný mechanismus, se kterým se seznámíme posléze.

Podle svého významu spadají řídící příkazy protokolu TELNET do tří skupin mezi:
  • příkazy pro editaci (jsou jen dva: pro vymazání aktuální řádky a pro vymazání předchozího znaku);
  • příkazy pro řízení komunikace mezi oběma stranami (například pro přerušení aplikačního procesu na straně serverů, pro zastavení jeho výstupu, pro vzájemnou synchronizaci apod.);
  • příkazy, umožňující oběma stranám dohodnout se na použití konkrétních rozšíření.

Na poslední skupinu se nyní zaměříme podrobněji.

Licitace o rozšíření

Jak jsme si již naznačili, použití nejrůznějších rozšíření oproti virtuálnímu terminálu NVT je nepovinné. Každá ze stran má právo navrhnout použití takového rozšíření, jaké uzná za vhodné, ale druhá strana má plné právo je odmítnout. Výrazný prvek demokratičnosti je pak i v tom, že právo navrhovat použití rozšíření má nejen složka v roli klienta, ale i složka v roli serveru - obě strany mají v tomto ohledu rovnoprávné postavení.

Zajímavý je i konkrétní způsob vzájemné "licitace". Ta strana, která chce iniciovat použití určitého rozšíření, má dvě možnosti: navrhnout, že sama přijme nějaké opatření (tj. sama začne používat příslušné rozšíření), a ptát se druhé strany, zda s tím souhlasí, nebo naopak navrhnout druhé straně, aby ona přijala určitě opatření. Ukažme si na příkladu, v čem může spočívat rozdíl, a proč je vůbec nutné o něm uvažovat: Virtuální terminál NVT předpokládá, že každá strana bude používat tzv. lokální echo (local echo) - tedy že veškeré znaky, žádané z klávesnice, si bude sama ihned zobrazovat na svém displeji (resp. tisknout na tiskárně, kterou předpokládá NVT), a současně s tím je odesílat druhé straně. Díky tomu uživatel okamžitě vidí, co vlastně z klávesnice žádal a co se druhé straně odeslalo. Alternativa je taková, že žádaný znak je pouze odeslán druhé straně a teprve ta jej zase pošle zpět k zobrazení na displeji uživatelova terminálu. Používání této techniky označované jako tzv. vzdálené echo (remote echo) je jedním z možných rozšíření virtuálního terminálu NVT. Je ovšem zásadní rozdíl mezi tím, kdy jedna strana navrhne druhé, že ona bude provádět vzdálené echo (tj. že bude posílat zpět každý znak, který od druhé strany dostane), a kdy vzdálené echo požaduje na druhé straně.

Některá rozšíření virtuálního terminálu NVT, jako právě naznačené používání tzv. vzdáleného echa, mají asymetricky charakter a mohou být používaná oběma stranami současně, žádnou z nich, nebo jen jednou ze zúčastněných stran. Naproti tomu jiná rozšíření mají symetricky charakter a musí je používat buď obě strany současně, nebo žádná.

Protokol TELNET nabízí celkem čtyři příkazy, pomoci kterých mohou obě strany "licitovat" o použití rozšíření. Jsou to po příkazy:

  • WILL (doslova: budu), vysílající strana tímto příkazem signalizuje, že chce sama začít používat určitě rozšíření, a dotazuje se druhé strany na její souhlas.
  • DO (doslova: delej), vysílající strana tímto příkazem vyzývá druhou stranu, aby ona začala používat určité opatření.
  • WON'T (od: Will Not, doslova: nebudu), tímto příkazem vysílající strana odmítá výzvu druhé strany (vyjádřenou příkazem DO), případně signalizuje, že sama již nebude dále pokračovat v používání určitého rozšíření (pokud je dosud používala).
  • DON'T (od: Do Not, doslova: nedělej), tímto příkazem vysílající strana odmítá nabídku druhé strany (vyjádřenou příkazem WILL), případně signalizuje, že od druhé strany již neočekává, že bude nadále používat určité rozšíření.

Příkazy WON'T a DON'T jsou tedy zápornými odpověďmi na výzvu vyjádřenou po řadě příkazy DO a WILL. Jaké jsou ale kladné odpovědi? Kladnou odpovědí na příkaz DO (výzvu "dělej") je příkaz WILL (tj. "budu"), a naopak kladnou odpovědí na příkaz WILL (nabídku "budu") je příkaz DO (tj. "dělej").

Identifikace rozšíření

Příkazy WILL, DO, WON'T a DON'T samy o sobě ještě neurčují jednu velmi podstatnou věc - o jaké konkrétní rozšíření se jedná. Toto je určeno až dalším rozlišujícím parametrem (ve skutečnosti číselným kódem v rozsahu jednoho osmibitového bytu), který následuje bezprostředně za vlastními příkazy. Takže například nabídka jedné strany, že bude druhé straně zajišťovat vzdálené echo, se symbolicky zapisuje jako:
  • IAC WILL ECHO
    a ve skutečnosti se vysílá jako trojice bytů s hodnotami po řadě 255, 251 a 1 (kde 255 je kód uvozujícího znaku IAC, 251 je kód příkazu WILL, a 1 je kód rozšíření o vzdálené echo). Druhá strana v případě souhlasu odpoví sekvencí:
  • IAC DO ECHO
    (číselně: 255 253 1), a v případě nesouhlasu sekvencí:
  • IAC DON'T ECHO
    (číselně: 255 254 1).
    Obdobně požadavek jedné strany, aby pro ní druhá strana zajišťovala vzdálené echo, by měl tvar:
  • IAC DO ECHO
    (číselně: 255 253 1). Druha strana akceptuje tuto výzvu sekvencí:
  • IAC WILL ECHO
    (číselně: 255 251 1), resp. odmítá ji pomocí:
  • IAC WON'T ECHO
    (číselně: 255 252 1). Aby se zabránilo možnému zacyklení, kdyby jedna strana považovala odpověď druhé strany za novou žádost, je zavedeno následující pravidlo: na žádost o použití takového rozšíření, které již je používáno, se neodpovídá nijak.

Počet a význam jednotlivých rozšíření není předem stanoven. Nová rozšíření mohou vznikat a skutečně vznikají na základě skutečných potřeb a vývoje výpočetní techniky. Pro jejich koordinaci však musí existovat jediná centrální autorita, která jim přiděluje jejich číselné kódy. Tou je pan John Postel z University of Southern California, autor mnoha standardů internetu, vydávaných ve formě tzv. RFC dokumentu.

Podrobnější licitace

Z některých zajímavých rozšíření (které uvádí tabulka 69.1) stojí za zmínku např. možnost dohodnout se na použití konkrétního typu terminálu (s větším repertoárem schopností a možností, než jaké nabízí "základní NVT"). V současné době, kdy je velká část terminálových relací zajišťována prostřednictvím terminálové emulace (viz 65. díl) a příslušné emulátory jsou často schopny emulovat více různých terminálů, je dokonce žádoucí, aby se obě strany mohly dohodnout na použití nejvhodnějšího terminálu.

Pro tyto účely však již není výše naznačený mechanismus dostatečný. Umožňuje pouze to, aby se obě strany dohodly na tom, že se vůbec chtějí (a umějí) domlouvat na typu terminálu. Poté musí následovat druhá fáze "licitace" (v angličtině označována jako subnegotiation), v rámci které se již mohou podrobněji domlouvat na konkrétních parametrech. V případě volby typu terminálu by v rámci této druhé fáze složka v roli klienta předkládala složce v roli serveru jednotlivé typy terminálů, které je schopna emulovat, a server by si z nich vybíral tu, kterou považuje ze svého pohledu za nejvýhodnější.
Obdobná úvaha platí i pro jiná rozšíření: například pro stanovení velikosti displeje, kde se konkrétní počet řádek na stránce a počet znaků na řádce sděluje opět v druhé fázi (subnegotiation) "licitace".

Konkrétní forma této druhé fáze není předepsaná, neboť je určena až potřebami příslušného rozšíření. Závazný je pouze způsob zajištění transparence: posloupnost znaků, předávaných v rámci druhé fáze "licitace", musí být uvozena řídícím znakem SB (Start of Subnegotiation), a zakončena znakem SE (End of Subnegotiation). Oba tyto znaky přitom musí být samy prefixovány znakem IAC.

 

 

 

Name Decimal Code Meaning
SE 240 End of subnegotiation parameters.
NOP 241 No operation
DM 242 Data mark. Indicates the position of a Synch event within the data stream. This should always be accompanied by a TCP urgent notification.
BRK 243 Break. Indicates that the "break" or "attention" key was hit.
IP 244 Suspend, interrupt or abort the process to which the NVT is connected.
AO 245 Abort output. Allows the current process to run to completion but do not send its output to the user.
AYT 246 Are you there. Send back to the NVT some visible evidence that the AYT was received.
EC 247 Erase character. The receiver should delete the last preceding undeleted character from the data stream.
EL 248 Erase line. Delete characters from the data stream back to but not including the previous CRLF.
GA 249 Go ahead. Used, under certain circumstances, to tell the other end that it can transmit.
SB 250 Subnegotiation of the indicated option follows.
WILL 251 Indicates the desire to begin performing, or confirmation that you are now performing, the indicated option.
WONT 252 Indicates the refusal to perform, or continue performing, the indicated option.
DO 253 Indicates the request that the other party perform, or confirmation that you are expecting the other party to perform, the indicated option.
DONT 254 Indicates the demand that the other party stop performing, or confirmation that you are no longer expecting the other party to perform, the indicated option.
IAC 255 Interpret as command

 

Datasheety & Odkazy

  • Originally whole RCF 2217 standard documentation - rfc2217.txt