IMA3/IMA4 2019/2021 P1 : Différence entre versions

De Wiki de Projets IMA
(Le protocole applicatif)
(Le protocole applicatif)
Ligne 143 : Ligne 143 :
 
|-
 
|-
 
| 0x24
 
| 0x24
| T||0x10
+
| T|0x10
 
| 0x2a
 
| 0x2a
| T||0x10
+
| T|0x10
 
| 0x0d 0x0a
 
| 0x0d 0x0a
 
|-
 
|-
 
|}
 
|}

Version du 7 janvier 2021 à 22:42

Introduction

L'idée était d'avoir un serveur de temps pour synchroniser l'heure sur les stations de travail sans avoir à se reposer sur un serveur NTP d'Internet.

Actuellement des systèmes embarqués sont vendus sur divers sites à bas prix. Ce matériel est désigné sous une appellation à rallonge : "Network Time Server NTP Time Server for GPS Beidou GLONASS Galileo QZSS Desktop Version". Son manuel le désigne sous la référence FC-NTP-100.

A priori ce matériel arrive prêt à l'emploi mais sa configuration IP nécessite l'utilisation d'un logiciel windows donc graphique. C'est assez peu pratique quand vous le connectez sur un VLAN de serveurs sur lequel vous n'avez aucune station de travail et aucun serveur sous windows. La configuration du système embarqué s'est donc transformé en un exercice d'ingénierie inverse et de codage réseau.

Matériel

Le système embarqué est livré avec un adapteur secteur non française, de plus il est assez compliqué d'accumuler les adaptateurs dans une baie. Un boitier d'alimentation 12V a été acquis pour l'alimentation. Ce type de boitier est plutôt destiné à alimenter des caméras mais convient très bien pour le système embarqué NTP. Le boitier d'alimentation se compose d'un transformateur utilisable au travers de fusibles et de borniers. Pour le modèle acheté 4 borniers sont disponibles et se partagent les 5A de l'alimentation.

Installation

thumbs

L'installation physique est assez triviale. Pour éviter de poser des éléments sur des tablettes dans la baie, l'alimentation et le système embarqué sont vissés sur le mur. Le cordon de l'alimentation a été récupéré et connecté aux borniers. Le système embarqué est relié à un commutateur via une jarretière RJ45. La LED du port du commutateur s'allume prouvant la présence d'une porteuse Ethernet. Par contre la commande ci-dessous montre qu'aucun paquet Ethernet n'est envoyé par le périphérique.

#show mac address-table interface gigabitEthernet 0/44
          Mac Address Table
-------------------------------------------
Vlan    Mac Address       Type        Ports
----    -----------       --------    -----

L'antenne est positionnée près d'une fenêtre. La longueur du câble est largement suffisante pour ce faire.

Configuration

Fc-ntp-100-p1.png

C'est au niveau de la configuration que cela se corse.

Le système embarqué sort d'usine avec comme adresse IPv4 192.168.0.100. Pour changer cette adresse, une application windows est fournie.

Pas de port série sur la version bon marché du système embarqué NTP (FC-NTP-100). Une documentation fait état d'une autre version du système embarqué avec une connexion série bizarrement accessible sur une broche DB15.

Comme décrit dans l'introduction le but est d'écrire une application Linux texte avec les mêmes fonctionnalités que l'application graphique. Pour cela le principal est d'arriver à trouver le protocole utilisé par le périphérique.

Ingénierie inverse

C'est aussi simple que de lancer l'application windows sous wine, de lancer un tcpdump dans une console et de cliquer sur tous les boutons de l'application graphique.

Il est possible de compliquer un peu et de tenter une partie de l'ingénierie inverse sans le système embarqué en ligne. Dans ce cas ajouter une entrée dans la table ARP :

# arp -s 192.168.0.100 00:11:22:33:44:55

Après ça si vous appuyez sur le bouton NET Connect puis sur le bouton Query, la console vous indiquera :

# tcpdump -vvv -n -Xe host 192.168.0.100
19:46:37.410925 24:77:03:24:8e:30 > 00:11:22:33:44:55, ethertype IPv4 (0x0800), length 49: (tos 0x0, ttl 64, id 26566, offset 0, flags [none], proto UDP (17), length 35)
    192.168.0.101.58025 > 192.168.0.100.23: [udp sum ok] UDP, length 7 
       0x0000:  4500 0023 67c6 0000 4011 90ea c0a8 0065  E..#g...@......e
       0x0010:  c0a8 0064 e2a9 0017 000f 12a7 2410 2a31  ...d........$.*1
       0x0020:  300d 0a

Nous savons donc que la communication avec le périphérique se fait en UDP sur le port 23. Vérifions en changeant le filtre de tcpdump et en appuyant sur le bouton Search :

# tcpdump -vvv -n -Xe port 23
20:55:37.788646 24:77:03:24:8e:30 > ff:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 49: (tos 0x0, ttl 64, id 26376, offset 0, flags [none], proto UDP (17), length 35)
    192.168.0.101.35413 > 255.255.255.255.23: [udp sum ok] UDP, length 7
       0x0000:  4500 0023 6708 0000 4011 52b5 c0a8 0065  E..#g...@.R....e
       0x0010:  ffff ffff 8a55 0017 000f 19fd 241b 2a31  .....U......$.*1
       0x0020:  420d 0a

Bien vu, la recherche du périphérique, si jamais son adresse IPv4 est inconnue, se fait avec une simple diffusion UDP encore sur le port 23.

Quelques essais supplémentaires en renseignant divers champs dans l'application graphique puis en appuyant sur les boutons Set correspondants (pour le type d'adresse IP, pour l'adresse IP et pour le masque réseau) :

# tcpdump -vvv -n -Xe port 23
21:44:26.529704 24:77:03:24:8e:30 > ff:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 50: (tos 0x0, ttl 64, id 6680, offset 0, flags [none], proto UDP (17), length 36)
    192.168.0.101.35413 > 255.255.255.255.23: [udp sum ok] UDP, length 8
       0x0000:  4500 0024 1a18 0000 4011 9fa4 c0a8 0065  E..$....@......e
       0x0010:  ffff ffff 8a55 0017 0010 52f0 2400 002a  .....U....R.$..*
       0x0020:  3030 0d0a                                00..
21:44:40.843945 24:77:03:24:8e:30 > ff:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 53: (tos 0x0, ttl 64, id 7396, offset 0, flags [none], proto UDP (17), length 39)
    192.168.0.101.35413 > 255.255.255.255.23: [udp sum ok] UDP, length 11
       0x0000:  4500 0027 1ce4 0000 4011 9cd5 c0a8 0065  E..'....@......e
       0x0010:  ffff ffff 8a55 0017 0013 5703 2401 c0a8  .....U....W.$...
       0x0020:  0064 2a30 440d 0a                        .d*0D..
21:44:49.432484 24:77:03:24:8e:30 > ff:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 53: (tos 0x0, ttl 64, id 8621, offset 0, flags [none], proto UDP (17), length 39)
    192.168.0.101.35413 > 255.255.255.255.23: [udp sum ok] UDP, length 11
       0x0000:  4500 0027 21ad 0000 4011 980c c0a8 0065  E..'!...@......e
       0x0010:  ffff ffff 8a55 0017 0013 181e 2402 ffff  .....U......$...
       0x0020:  fff0 2a30 440d 0a

Pour pouvoir cerner le protocole il faut obtenir une réponse du périphérique. Là pas d'autre solution que de connecter le système embarqué NTP sur le même réseau que la station de travail. Essayons de modifier le type de l'adresse IP, voila ce qui arrive sur la sortie standard de tcpdump :

# tcpdump -vvv -n -Xe port 23
22:21:39.072053 00:16:3e:aa:10:56 > d8:b0:4c:ff:01:76, ethertype IPv4 (0x0800), length 50: (tos 0x0, ttl 64, id 20379, offset 0, flags [DF], proto UDP (17), length 36)
    172.26.189.7.42350 > 172.26.191.100.23: [bad udp cksum 0xd4c2 -> 0x2443!] UDP, length 8
       0x0000:  4500 0024 4f9b 4000 4011 168d ac1a bd07  E..$O.@.@.......
       0x0010:  ac1a bf64 a56e 0017 0010 d4c2 2400 002a  ...d.n......$..*
       0x0020:  3030 0d0a                                00..
22:21:39.097510 d8:b0:4c:ff:01:76 > 00:16:3e:aa:10:56, ethertype IPv4 (0x0800), length 47: (tos 0x0, ttl 255, id 42738, offset 0, flags [none], proto UDP (17), length 33)
    172.26.191.100.23 > 172.26.189.7.42350: [udp sum ok] UDP, length 5
       0x0000:  4500 0021 a6f2 0000 ff11 4038 ac1a bf64  E..!......@8...d
       0x0010:  ac1a bd07 0017 a56e 000d 57a0 2400 000d  .......n..W.$...
       0x0020:  0a

Le protocole applicatif

Regardons d'un peu plus près les données UDP envoyées par l'application. Déjà toutes ces données commencent par la valeur 0x25 soit le caractère $. L'octet suivant semble correspondre au type de données envoyées (0x00 pour le type d'adresse, 0x01 pour l'adresse IPv4, 0x02 pour le masque réseau, etc). Suivent les octets de données (1 octet pour le type, 4 octets pour l'adresse IPv4 et le masque réseau, etc). Suit un octet de séparation 0x2a soit le caractère *. Les deux derniers octets semble bien être un saut de ligne à la mode windows soit 0x0d et 0x0a (CR et LF). Restent les deux octets entre le caractère de séparation *. Sur les différents exemples ces deux octets semblent devoir être lus en ASCII et semblent être la représentation en hexadécimal d'un octet.

Après quelques essais et erreurs cet octet se révèle être une somme de contrôle basique sur les octets entre les caractères $ et * non inclus. La somme est calculée par le simple opérateur ou exclusif bit à bit. Les différents essais ont été réalisés sur l'envoi de l'adresse IPv4 en commençant par mettre tous les bits à zéro (résultat 00) puis en modifiant bit à bit le 0.0.0.0 initial.

Pour les demandes d'information le format semble être le même (voir le premier paquet des tests) mais sans octets de données et avec un code correspondant au type de l'information auquel on applique un ou bit à bit avec 0x10.

Donc pour les requêtes au périphérique le format est synthétisé dans les tableaux ci-dessous :

Modification de configuration
1 octet 1 octet n octet(s) 1 octet 2 octets 2 octets
'$' Type de configuration Données '*' Somme de contrôle Saut de ligne
0x24 T D1 ... Dn 0x2a T ^ D1 ^ ... ^ Dn 0x0d 0x0a
Lecture de configuration
1 octet 1 octet 1 octet 2 octets 2 octets
'$' Type de configuration '*' Somme de contrôle Saut de ligne
0x24 T|0x10 0x2a T|0x10 0x0d 0x0a