FULL-C: ping functions

Verze z 8. 8. 2021, 16:26, kterou vytvořil Adamn (diskuse | příspěvky) (Založena nová stránka s textem „ Tato stránka popisuje programovací jazyk '''FULL-C''', který je dostupný na vybraných zařízeních SDS. Některá zařízení používají SDS-C,…“)
(rozdíl) ← Starší verze | zobrazit aktuální verzi (rozdíl) | Novější verze → (rozdíl)
Tato stránka popisuje programovací jazyk FULL-C, který je dostupný na vybraných zařízeních SDS. 
Některá zařízení používají SDS-C, pro který máme návody jinde na této WiKi.

Síťové funkce: odesílání ICMP PING paketů

Zařízení SDS umožňuje odeslat ICMP ECHO REQUEST paket, a přijmout ICMP ECHO REPLY paket.

Za tímto účelem jsou k dispozici tyto dvě funkce:

         void ping_send(unsigned int IP0, unsigned int IP1, unsigned int IP2, unsigned int IP3, unsigned int sendPingSequenceValue);
 unsigned int ping_send_status(unsigned int * pingReceivedSequence, unsigned int * pingReceivedRTTmsec);

Proměnné IP0 až IP3 skládají (po částech) dohromady konkrétní IPv4 adresu, na kterou je ICMP ECHO REQUEST poslán.

Princip

SDS odesílá jeden paket, tzv. ICMP REQUEST. Na tento paket má zareagovat cílový stroj (podle zvolené IP adresy) a odpovědět správně sestaveným ICMP ECHO REPLY (ECHO RESPONSE) paketem.

Aby se různé odpovědi navzájem nepomíchali, je v REQUEST paketu uvedena hodnota číselné sekvence, a tato hodnota je pak vrácena v REPLY (RESPONSE) paketu. Takto může (správně napsaný) FULL-C program srovnat obdrženou odpověď s tím, co poslal za dotaz.


Příklad

V tomto příkladu odesílá SDS jeden ICMP ECHO REQUEST paket na určenou IP (ip1.ip2.ip3.ip4) a čeká, dokud nepřijde odpověď - potom napíše do konzole hodnotu RTT (Round Trip Time) v milisekundách.


void main(void)
{

	unsigned int status, oldstatus;

	unsigned int pingSequence;
	unsigned int gotSeq;

	unsigned int gotRTT;

	unsigned char ip1, ip2, ip3, ip4;

	// PRO NAS PRIKLAD:
	// ip1, ip2, ip3, ip4 => jednotlive casti IP adresy cilového stroje (TRAP RECEIVER)  tzn.:  ip1.ip2.ip3.ip4 (např. zde v tomto příkladu 192.168.1.110)
	 ip1 = 192;
	 ip2 = 168;
	 ip3 = 1;
	 ip4 = 110;
	// sequence => zacneme na 1, postupne se zvysuje pro kazdy pokus
	 pingSequence = 1;
	// ---

	// musime zacit s hodnotou 2 (pozadavek na opakovane odeslani)
	status = 2;

	// "oldstatus" je zde pouze pro debug (printf)
	oldstatus = status + 1;

	// smycka pro obsluhu jednoho PINGu (dokud se to nepovede odeslat)
	while (status == 2)
	{

		printf("calling: ping_send(IP, %d)\n", pingSequence);

		// pozadame SDS o odeslani ICMP PING
		ping_send(ip1, ip2, ip3, ip4, pingSequence);

		// pockame, dokud neni PING odeslan a dokud nedostanem i odpoved (ECHO)
		while (status != 8)
		{
			gotSeq = 0;
			gotRTT = 0xFFFFFFFF;
			status = ping_send_status(&gotSeq, &gotRTT);

			if (status != oldstatus)
			{
				oldstatus = status;
				printf("PING: status=%d   gotSeq=%d   gotRTT=%u\n", status,
						gotSeq, gotRTT);
			}

			if (status == 8)
			{
				// hotovo - musime skoncit 'while' smycku uz tady
				break;
			}

			// stale cekam
			if (0) // if (timeout)  <--- toto si musite udelat sami
			{
				printf("vyprsel cas kdy jsme cekali na odpoved (echo) \n");
				break;
			}

			// posledni dulezity test:
			if (status == 2)
			{
				// misto ICMP PING byl odeslan ARP dotaz
				// takze musime chvili pockat a pak odeslat PING na stejnou IP znova
				// (doufame ze uz prisla ARP odpoved)
				continue;
			}

			//
			;// delej neco jiného, zatimco se ceka . . .
		}

		// v tuto chvili je 'status' vyplnen finalni hodnotou

		if (status == 8)
		{
			printf("ECHO received: ROUND TRIP TIME = %u msec\n", gotRTT);
		} else
		{
			printf("ECHO neprijato (PING bez odpovedi) \n");
		}

		// a pro dalsi pokus pouzijeme jinou sekvenci ! toto je dulezite.
		pingSequence++;

	}

	printf("-done-");
} 

Výstupem příkladu může být například toto (když se vše povedlo, a SDS obdrželo ECHO REPLY):

calling: ping_send(IP, 1)
PING: status=1 gotSeq=-1 gotRTT=65535
PING: status=4 gotSeq=-1 gotRTT=65535
PING: status=8 gotSeq=1 gotRTT=3
ECHO received: ROUND TRIP TIME = 3 msec
-done-


Stavové hodnoty

Program musí použít volání funkce ping_send_status pro zjištění okamžitého stavu.

 ping_send_status()         význam
-------------------------+-----------------------------------------------------------------------
 0                       |  klid, můžete odeslat ICMP PING REQUEST
 1                       |  pracuje, paket bude odeslán, čekejte
 2                       |  místo PING REQUEST paketu byl odeslán ARP, takže musíte zopakovat odesílání
 4                       |  PING REQUEST byl úspěšně odeslán (takže čekejte na příjem ECHO REPLY paketu)
 8                       |  odpověď (ECHO REPLY) se správnou sekvencí byla přijata, hodnota RTT je k dispozici
 128                     |  paket nebyl odeslán, protože byla zadána neplatá IP adresa