Groupe de travail Réseau	Karl Auerbach, Epilogue Technology Corporation	
Request for Comments : 1002	mars 1987	
STD 19		
Traduction Claude Brière de L’Isle		

Protocole standard pour un service NetBIOS 
sur transport TCP/UDP : Spécifications détaillées

Résumé
La présente RFC définit une proposition de norme de protocole pour la prise en charge des services NetBIOS dans un environnement TCP/IP. Le fonctionnement en réseau local et sur internet sont tous deux pris en charge. Divers types de nœud sont définis pour s’accommoder des topologies locale et internet et permettre le fonctionnement avec ou sans l’utilisation de la diffusion IP.

La présente RFC donne les spécifications détaillées des paquets NetBIOS sur TCP, des protocoles, et définit les constantes et les variables. Une vision plus générale se trouve dans la RFC 1001 , "Protocole standard pour un service NetBIOS sur un transport TCP/UDP : Concepts et méthodes".

Table des matières

1.	Statut du présent mémoire
2.	Remerciements
3.	Introduction
4.	Descriptions des paquets
4.1	Format de nom
4.2	Paquets du service de noms
4.2.1	Format général des paquets du service de noms
4.2.2	Demande d’enregistrement de nom
4.2.3.	Demande et instruction de substitution de nom
4.2.4	Demande de rafraîchissement de nom
4.2.5	Réponse positive d’enregistrement de nom
4.2.6	Réponse négative d’enregistrement de nom
4.2.7	Réponse d’enregistrement de mise en cause de nœud d’extrémité
4.2.8	Instruction de conflit de nom
4.2.9	Demande et instruction de libération de nom
4.2.10	Réponse positive de libération de nom
4.2.11	Réponse négative de libération de nom
4.2.12	Demande d’interrogation de nom
4.2.13	Réponse positive d’interrogation de nom
4.2.14	Réponse négative d’interrogation de nom
4.2.15	Redirection de la réponse d’interrogation de nom
4.2.16	Attente d’une réponse d’accusé de réception (WACK)
4.2.17	Demande d’état de nœud
4.2.18	Réponse d’état de nœud
4.3	Paquets du service de session
4.3.1	Format général des paquets de session
4.3.2	Paquet de demande de session
4.3.3	Paquet de réponse positive de session
4.3.4	Paquet de réponse négative de session
4.3.5	Paquet de réponse de reciblage de session
4.3.6	Paquet de message de session
4.3.7	Paquet de maintien en vie de session
4.4	Paquets du service de datagrammes
4.4.1	En-tête de datagramme NetBIOS
4.4.2	Datagramme direct_unique, direct_groupe, & de diffusion
4.4.3	Datagramme d’erreur de paquet
4.4.4	Datagramme de demande d’interrogation
4.4.5	Datagramme de réponse positive et négative d’interrogation
5.	Descriptions des protocoles
5.1	Protocoles du service de noms
5.1.1	Activité de nœud B
5.1.2	Activité du nœud P
5.1.3	Activité de nœud M
5.1.4	Activité du NBNS
5.2	Protocoles de service de session
5.2.1	Protocoles d’établissement de session
5.2.2	Protocoles de transfert de données de session
5.2.3	Protocoles de terminaison de session
5.3	Protocoles du service de datagrammes NetBIOS
5.3.1	Transmission de datagrammes NetBIOS par le nœud B
5.3.2	Transmission de datagrammes NetBIOS par les nœuds P et M
5.3.3	Réception des datagrammes NetBIOS par tous les nœuds
5.3.4	Protocoles pour le NBDD
6.	Définition des constantes et des variables
Références

1.	Statut du présent mémoire

La présente RFC spécifie une proposition de norme pour la communauté DARPA Internet. Comme ce sujet est nouveau pour la communauté de l’Internet, des discussions et suggestions sont particulièrement bienvenues.

Prière d’envoyer les commentaires écrits à :
Karl Auerbach
Epilogue Technology Corporation
P.O. Box 5432
Redwood City, CA   94063

Prière d’envoyer les commentaires en ligne à :
Avnish Aggarwal
Internet : mtxinu!excelan!avnish@ucbvax.berkeley.edu
Usenet : ucbvax!mtxinu!excelan!avnish

La distribution du présent mémorandum n’est soumise à aucune restriction.

2.	Remerciements

La présente RFC a été développée sous les auspices du Bureau des activités de l’Internet.

Les personnes suivantes ont contribué à la rédaction de la présente RFC :

Avnish Aggarwal	Arvind Agrawal	Karl Auerbach	Lorenzo Aguilar	
Geoffrey Arnold	David Kaufman	Steve Holmgren	Vint Cerf	
Keith Ball	Dan Lynch	Lee LaBarre	Steve Deering	
Richard Cherry	David Crocker	Jay Israel	James Lau	
Greg Ennis	K. Ramesh Babu	Gaylord Miyata	David Stevens	
Steve Thomas	Amatzia Ben-Artzi	Ishan Wu		

Le système proposé par la présente RFC ne reflète aucune mise en œuvre Netbios sur TCP existante. Cependant, sa conception incorpore des connaissances considérables obtenues à partir de mises en œuvre antérieures. Des remerciements tout particuliers s’adressent aux organisations suivantes qui ont fourni ces très précieuses informations :

CMC/Syros, Excelan, Sytek, Ungermann-Bass

3.	Introduction

La présente RFC contient la spécification détaillée des formats et protocoles de paquet pour NetBIOS sur TCP. La présente RFC est inséparable de la RFC 1001, "Protocole standard pour un service NetBIOS sur un transport TCP/UDP : Concepts et méthodes" [1].

4.	Descriptions des paquets

L’ordre des bits et des octets est défini par la version la plus récente de "Numéros alloués" [2].

4.1	Format de nom

La représentation du nom NetBIOS dans tous les paquets NetBIOS (pour les services de noms, de session, et de datagrammes) est définie dans le service de noms de domaine (RFC 883 [3]) comme un message de nom "compressé". Ce format est appelé "codage de second niveau" au paragraphe intitulé "Représentation des noms NetBIOS" du document Concepts et méthodes [1].

Pour faciliter la description, les deux premiers alinéas du paragraphe intitulé "Représentation et compression des noms de domaine", de la RFC 883 sont reproduits ici :

Les messages de noms de domaine sont exprimés en termes de séquence d’étiquettes. Chaque étiquette est représentée par un champ long d’un octet suivi par ce nombre d’octets. Comme chaque nom de domaine se termine par l’étiquette nulle de la racine, un nom de domaine compressé est terminé par un octet de longueur de zéro. Les deux bits de plus fort poids du champ longueur doivent être zéro, et les six bits restants du champ de longueur limitent l’étiquette à 63 octets ou moins.

Pour simplifier les mises en œuvre, la longueur totale des octets d’étiquette et des octets de longueur d’étiquette qui constituent un nom de domaine est restreinte à 255 octets ou moins.

Ce qui suit est la représentation non compressée du nom NetBIOS "FRED ", qui est les quatre caractères ASCII, F, R, E, D, suivis par douze caractères espace (0x20). Ce nom a l’identifiant de domaine d’application (SCOPE_ID) : "NETBIOS.COM"

EGFCEFEECACACACACACACACACACACACA.NETBIOS.COM

Cette représentation non compressée des noms est appelée "codage de premier niveau" au paragraphe intitulé "Représentation des noms NetBIOS" dans le document Concepts et méthodes [1].

Ce qui suit est une représentation pictographique de la représentation compressée de la représentation de nom de domaine précédemment non compressée.

	      1 1 1 1 1 1	1 1 1 1 2 2 2 2	2 2 2 2 2 2 3 3	
0 1 2 3 4 5 6 7	8 9 0 1 2 3 4 5	6 7 8 9 0 1 2 3	4 5 6 7 8 9 0 1	
0x20	E (0x45)	G (0x47)	F (0x46)	
C (0x43)	E (0x45)	F (0x46)	E (0x45)	
E (0x45)	C (0x43)	A (0x41)	C (0x43)	
A (0x41)	C (0x43)	A (0x41)	C (0x43)	
A (0x41)	C (0x43)	A (0x41)	C (0x43)	
A (0x41)	C (0x43)	A (0x41)	C (0x43)	
A (0x41)	C (0x43)	A (0x41)	C (0x43)	
A (0x41)	C (0x43)	A (0x41)	C (0x43)	
A (0X41)	0x07	N (0x4E)	E (0x45)	
T (0x54)	B (0x42)	I (0x49)	O (0x4F)	
S (0x53)	0x03	C (0x43)	O (0x4F)	
M (0x4D)	0x00			

Chaque section d’un nom de domaine est appelée une étiquette [7 (page 31)]. Une étiquette a un maximum de 63 octets. Le premier octet d’une étiquette en représentation compressée est le nombre d’octets de l’étiquette. Pour l’exemple ci-dessus, le premier 0x20 est le nombre d’octets dans l’étiquette la plus à gauche, EGFCEFEECACACACACACACACACACACACA, du nom de domaine. Les octets qui suivent le compte de longueur de l’étiquette sont les caractères de l’étiquette. Les étiquettes suivantes sont en séquence après la première étiquette, qui est le nom NetBIOS codé, jusqu’à un compte de longueur zéro (0x00). Le compte de longueur zéro représente l’étiquette racine, qui est toujours nulle.

Un compte de longueur d’étiquette est en réalité un champ de 6 bits dans le champ de longueur d’étiquette. Les deux bits de plus fort poids du champ, les bits 7 et 6, sont des fanions qui permettent de s’échapper de la représentation compressée ci-dessus. Si les bits 7 et 6 sont tous deux mis à un (11), les 14 bits suivants sont un pointeur de décalage du message complet vers la chaîne d’étiquette réelle d’un autre nom de domaine qui possède ce nom. Ce pointeur d’étiquette permet une compression ultérieure d’un nom de domaine dans un paquet.

Les mises en œuvre NetBIOS peuvent seulement utiliser les pointeurs de chaîne d’étiquette dans les paquets du Service de noms. Ils ne peuvent pas être utilisés dans les paquets du service de session ou de datagrammes.

Les deux autres valeurs possibles pour les bits 7 et 6 (01 et 10) du champ de longueur d’étiquette sont réservés pour une utilisation future par la RFC 883 [2 (page 32)].

Noter que le premier octet d’un nom compressé doit contenir un des schémas binaires du gabarit binaire suivant. (Un "x" indique un bit dont la valeur peut être 0 ou 1.) :
00100000 – Nom Netbios, la longueur doit être 32 (en décimal)
11xxxxxx – Pointeur de chaîne d’étiquette
10xxxxxx -  Réservé
01xxxxxx -  Réservé

4.2	Paquets du service de noms
4.2.1	Format général des paquets du service de noms
Les paquets du service de noms NetBIOS suivent la structure de paquet définie dans la RFC 883 Service de noms de domaine (DNS) [7 (pages 26-31)]. Les structures sont compatibles avec les formats de paquet DNS existants, cependant, des types et codes supplémentaires ont été ajoutés pour fonctionner avec NetBIOS.

Si les paquets du service de noms sont envoyés sur une connexion TCP, ils sont précédés par un entier non signé de 16 bits représentant la longueur du paquet du service de noms.

	 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3	
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1	
------                                                                            -------
En-tête
------                                                                            -------	
Entrées de questions	
Réponses d’enregistrements de ressources	
Autorité d’enregistrement de ressources	
Enregistrements de ressource supplémentaires	

4.2.1.1	En-tête

1 1 1 1 1 1 	1 1 1 1 2	2 2 2 2 2 2 2	2 2 3 3	
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5	6 7 8 9 0	1 2 3 4 5 6 7	8 9 0 1	
NAME_TRN_ID	OPCODE	NM_FLAGS	RCODE	
QDCOUNT	ANCOUNT	
NSCOUNT	ARCOUNT	

Champ	Description	
NAME_TRN_ID	Identifiant de transaction pour une transaction du service de noms. Le demandeur place une valeur unique pour chaque transaction active. Le répondant met la valeur NAME_TRN_ID tirée du paquet de demande dans le paquet de réponse.	
OPCODE	Code de type de paquet, voir le tableau ci-dessous.	
NM_FLAGS	Fanions pour le fonctionnement, voir le tableau ci-dessous.	
RCODE	Codes de résultat de la demande. Le tableau des valeurs de RCODE pour chaque paquet de réponse figure ci-dessous.	
QDCOUNT	Entier non signé de 16 bits qui spécifie le nombre d’entrées dans la section question d’un paquet du service de noms. Toujours zéro (0) pour les réponses. Doit être différent de zéro pour toutes les demandes de nom NetBIOS.	
ANCOUNT	Entier non signé de 16 bits qui spécifie le nombre des enregistrements de ressource de la section réponse d’un paquet du service de noms.	
NSCOUNT	Entier non signé de 16 bits qui spécifie le nombre des enregistrements de ressource de la section autorité d’un paquet du service de noms.	
ARCOUNT	Entier non signé de 16 bits qui spécifie le nombre des enregistrements de ressource de la section enregistrements supplémentaires d’un paquet du service de noms.	

Le champ OPCODE est défini par :

0	1	2	3	4	
R	OPCODE	

Symbole	Bit(s)	Description	
OPCODE	1 à 4	Spécifie l’opération :	
		0 = interrogation	
		5 = enregistrement	
		6 = libération	
		7 = WACK	
		8 = rafraîchissement	
R	0	Fanion de réponse :	
		si le bit = 0 c’est un paquet de demande	
		si le bit = 1 c’est un paquet de réponse.	

Le champ NM_FLAGS est défini par :

0	1	2	3	4	5	6	
AA	TC	RD	RA	0	0	B	

Symbole	Bit(s)	Description	
B	6	Fanion de diffusion.
= 1 : paquet en diffusion ou diffusion groupée
= 0 : envoi individuel	
RA	3	Fanion de récurrence disponible.
Seulement valide dans les réponses provenant d’un serveur de nom NetBIOS -- doit être à zéro dans toutes les autres réponses. S’il est à un (1) le NBNS prend en charge l’interrogation récursive, l’enregistrement, et la libération. À zéro (0) le nœud d’extrémité doit faire une itération d’interrogation et mise en cause pour l’enregistrement.	
RD	2	Fanion de récurrence désirée.
Ne peut être mis que sur une demande à un serveur de nom NetBIOS. Le NBNS va copier son état dans le paquet de réponse. À un (1) le NBNS fera une itération sur l’interrogation, l’enregistrement ou la libération.	
TC	1	Fanion de troncature.
Mis si ce message a été tronqué parce que le datagramme qui le porte aurait été supérieur à 576 octets. Utiliser TCP pour obtenir les informations du serveur de nom NetBIOS.	
AA	0	Fanion de réponse d’autorisation.
Doit être à zéro (0) si le fanion R de OPCODE est à zéro (0). Si le fanion R est à un (1), si AA est à un (1) alors le nœud répondant est une autorité pour le nom de domaine. Les nœuds qui répondent aux interrogations établissent toujours ce bit dans les réponses.	

4.2.1.2	Section question

1 1 1 1 1 1 	1 1 1 1 2	2 2 2 2 2 2 2	2 2 3 3	
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5	6 7 8 9 0	1 2 3 4 5 6 7	8 9 0 1	

QUESTION_NAME	
QUESTION_TYPE 	QUESTION_CLASS	

Champ	Description	
QUESTION_NAME	Représentation de nom compressée du nom NetBIOS pour la demande.	
QUESTION_TYPE	Type de demande. Les valeurs pour ce champ sont spécifiées pour chaque demande.	
QUESTION_CLASS	Classe de la demande. Les valeurs pour ce champ sont spécifiées pour chaque demande.	

QUESTION_TYPE est défini par :
Symbole	Valeur	Description :	
NB	0x0020	Enregistrement de ressource du service de noms général NetBIOS	
NBSTAT	0x0021	Enregistrement de ressource d’état de nœud NetBIOS (voir la Demande d’état de nœud)	

QUESTION_CLASS est défini par :
Symbole	Valeur	Description :	
IN	0x0001	Classe Internet	

4.2.1.3	Enregistrement de ressource

1 1 1 1 1 1 	1 1 1 1 2	2 2 2 2 2 2 2	2 2 3 3	
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5	6 7 8 9 0	1 2 3 4 5 6 7	8 9 0 1	

RR_NAME	
RR_TYPE	RR_CLASS	
TTL	
RDLENGTH		
RDATA	

Champ	Description	
RR_NAME	Représentation compressée du nom NetBIOS correspondant à cet enregistrement de ressource.	
RR_TYPE	Code de type d’enregistrement de ressource	
RR_CLASS	Code de classe d’enregistrement de ressource	
TTL	Durée de vie (Time To Live) du nom d’un enregistrement de ressource.	
RDLENGTH	Entier non signé de 16 bits qui spécifie le nombre d’octets dans le champ RDATA.	
RDATA	Champ dépendant de RR_CLASS et de RR_TYPE. Contient les informations de ressource pour le nom NetBIOS.	

Définitions du champ RESOURCE RECORD RR_TYPE :
Symbole	Valeur	Description :	
A	0x0001	Enregistrement de ressource d’adresse IP (voir Rediriger la réponse d’interrogation de nom)	
NS	0x0002	Enregistrement de ressource de serveur de nom (voir Rediriger la réponse d’interrogation de nom)	
NULL	0x000A	Enregistrement de ressource NULL (voir Attendre une Réponse d’accusé de réception)	
NB	0x0020	Enregistrement de ressource de service de noms NetBIOS général(voir NB_FLAGS et NB_ADDRESS, ci-dessous)	
NBSTAT	0x0021	Enregistrement de ressource État de nœud NetBIOS (voir Réponse d’état de nœud)	

Définitions du champ RR_CLASS d’enregistrement de ressource :
Symbole	Valeur	Description :	
IN	0x0001	Classe Internet	

Champ NB_FLAGS du champ RDATA d’enregistrement de ressource pour le RR_TYPE de "NB" :
	1	1	1	1	1	1	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	
G	ONT	réservé	

Symbole	Bit(s)	Description :	
Réservé	3-15	Réservé pour utilisation future. Doit être à zéro (0).	
ONT	1, 2	Type du nœud détenteur :
00 = nœud B
01 = nœud P
10 = nœud M
11 = Réservé pour utilisation future
Pour les demandes d’enregistrement, c’est le type du réclamant.
Pour les réponses, c’est le type du détenteur réel.	
G	0	Fanion de nom de groupe
À un (1) le RR_NAME est alors un nom NetBIOS GROUP.
À zéro (0) le RR_NAME est alors un nom NetBIOS UNIQUE.	

Le champ NB_ADDRESS du champ RDATA d’enregistrement de ressource pour le RR_TYPE de "NB" est l’adresse IP du détenteur du nom.

4.2.2	Demande d’enregistrement de nom

1 1 1 1 1 1 	1 1 1 1 2	2 2 2 2 2 2 2	2 2 3 3	
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5	6 7 8 9 0	1 2 3 4 5 6 7	8 9 0 1	
NAME_TRN_ID	0	0x5	1	0	1	0	0 0	B	0x0	
0x0001	0x0000	
0x0000	0x0001	

QUESTION_NAME
	
NB (0x0020)	IN (0x0001)	

RR_NAME
	
NB (0x0020)	IN (0x0001) 	
TTL	
0x0006	NB-FLAGS	
NB-ADDRESS	

Comme le RR_NAME est le même nom que le QUESTION_NAME, la représentation du RR_NAME doit utiliser des pointeurs sur les étiquettes du nom QUESTION_NAME pour garantir que la longueur du datagramme est inférieure au maximum de 576 octets. Voir ci-dessus le paragraphe sur les formats de noms et aussi les pages 31 et 32 de la RFC 883, Noms de domaines – Mise en œuvre et spécification, une description complète des pointeurs d’étiquette de nom compressé.

4.2.3.	Demande et instruction de substitution de nom

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	0	0x5	0	0	0	0	0	0	B	0x0	
0x0001	0x0000	
0x0000	0x0001	
QUESTION_NAME	
NB (0x0020)	IN (0x0001)	

RR_NAME
	
NB (0x0020)	IN (0x0001)	
TTL	
0x0006	Fanions NB	
NB_ADDRESS	

4.2.4	Demande de rafraîchissement de nom

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	0	0x5	0	0	0	0	0	0	B	0x0	
0x0001	0x0000	
0x0000	0x0001	
QUESTION_NAME	
NB (0x0020)	IN (0x0001)	

RR_NAME
	
NB (0x0020)	IN (0x0001)	
TTL	
0x0006	Fanions NB	
NB_ADDRESS	

4.2.5	Réponse positive d’enregistrement de nom

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	0	0x5	0	0	0	0	0	0	B	0x0	
0x0001	0x0000	
0x0000	0x0001	
QUESTION_NAME	
NB (0x0020)	IN (0x0001)	

RR_NAME
	
NB (0x0020)	IN (0x0001)	
TTL	
0x0006	Fanions NB	
NB_ADDRESS	

4.2.6	Réponse négative d’enregistrement de nom

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	0	0x5	0	0	0	0	0	0	B	0x0	
0x0001	0x0000	
0x0000	0x0001	
QUESTION_NAME	
NB (0x0020)	IN (0x0001)	

RR_NAME
	
NB (0x0020)	IN (0x0001)	
TTL	
0x0006	Fanions NB	
NB_ADDRESS	

Valeurs du champ RCODE :
Symbole	Valeur	Description :	
FMT_ERR	0x1	Erreur de format. La demande est formatée d’une façon qui n’est pas valide.	
SRV_ERR	0x2	Défaillance du serveur. Problème avec NBNS, qui ne peut traiter le nom.	
IMP_ERR	0x4	Erreur de demande non prise en charge. Admissible seulement pour mettre en cause le NBNS lorsqu’on obtient une demande d’enregistrement de type de mise à jour.	
RFS_ERR	0x5	Erreur de refus. Pour des raisons de politique le serveur ne veut pas enregistrer ce nom à partir de cet hôte.	
ACT_ERR	0x6	Erreur active. Le nom est en la possession d’un autre nœud.	
CFT_ERR	0x7	Erreur de noms en conflit. Un nom UNIQUE est la possession de plus d’un nœud.	

4.2.7	Réponse d’enregistrement de mise en cause de nœud d’extrémité

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	0	0x5	0	0	0	0	0	0	0	0x0	
0x0000	0x0001	
0x0000	0x0000	

RR_NAME
	
NB (0x0020)	IN (0x0001)	
TTL	
0x0006	Fanions NB	
NB_ADDRESS	

4.2.8	Instruction de conflit de nom

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	1	0x5	1	0	1	1	0	0	0	0x7	
0x0001	0x0001	
0x0000	0x0000	

RR_NAME
	
NB (0x0020)	IN (0x0001)	
0x0000000	
0x0006	0	ONT	0	0x000	
0x00000000	

Ce paquet est identique à une Réponse négative d’enregistrement de nom avec RCODE = CFT_ERR.

4.2.9	Demande et instruction de libération de nom

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	0	0x6	0	0	0	0	0	0	B	0x0	
0x0001	0x0000	
0x0000	0x0001	

QUESTION_NAME
	
NB (0x0020)	IN (0x0001)	

RR_NAME
	
NB (0x0020)	IN (0x0001)	
0x0000000	
0x0006	Fanions NB	
NB_ADDRESS	

Comme le RR_NAME est le même nom que le QUESTION_NAME, la représentation du RR_NAME doit utiliser les pointeurs de chaîne d’étiquette sur les étiquettes QUESTION_NAME pour garantir que la longueur du datagramme est inférieure au maximum de 576 octets. C’est la même condition qu’avec la Demande d’enregistrement de nom.

4.2.10	Réponse positive de libération de nom

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	1	0x6	1	0	0	0	0	0	0	0x0	
0x0000	0x0001	
0x0000	0x0000	

RR_NAME
	
NB (0x0020)	IN (0x0001)	
TTL	
0x0006	Fanions NB	
NB_ADDRESS	

4.2.11	Réponse négative de libération de nom

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	0	0x6	0	0	0	0	0	0	B	0x0	
0x0001	0x0000	
0x0000	0x0001	

QUESTION_NAME
	
NB (0x0020)	IN (0x0001)	

RR_NAME
	
NB (0x0020)	IN (0x0001)	
0x0000000	
0x0006	Fanions NB	
NB_ADDRESS	

Valeurs du champ RCODE :
Symbole	Valeur	Description :	
FMT_ERR	0x1	Erreur de format. Le format de la demande est invalide.	
SRV_ERR	0x2	Défaillance du serveur. Il y a un problème avec le NBNS, il ne peut pas traiter le nom.	
RFS_ERR	0x5	Erreur de refus. Pour des raisons de politique, le serveur ne va pas libérer ce nom auprès de l’hôte.	
ACT_ERR	0x6	Erreur active. Le nom est possédé par un autre nœud. Seul ce nœud peut le libérer. Un serveur de nom NetBIOS peut facultativement permettre à un nœud de libérer un nom qu’il ne possède pas. Cela faciliterait la détection de noms inactifs provenant de nom désactivés en silence.	

4.2.12	Demande d’interrogation de nom

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	0	0x0	0	0	1	0	0	0	B	0x0	
0x0001	0x0000	
0x0000	0x0000	

QUESTION_NAME
	
NB (0x0020)	IN (0x0001)	

4.2.13	Réponse positive d’interrogation de nom

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	1	0x0	1	T	1	?	0	0	0	0x0	
0x0000	0x0001	
0x0000	0x0000	

RR_NAME
	
NB (0x0020)	IN (0x0001)	
TTL	
RDLENGTH		

Matrice ADDR_ENTRY

La matrice ADDR_ENTRY est une séquence de zéro un ou plusieurs enregistrements de ADDR_ENTRY. Chaque enregistrement de ADDR_ENTRY représente un possesseur d’un nom. Pour les noms de groupe, il peut y avoir plusieurs entrées. Cependant, la liste peut être incomplète à cause des limites de taille de paquet. Le bit 22, "T", sera mis à un pour indiquer la troncature des données.

Chaque ADDR_ENTRY a le format suivant :

NB_FLAGS	NB_ADDRESS	
NB_ADDRESS (suite)	

4.2.14	Réponse négative d’interrogation de nom

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	1	0x06	1	0	1	?	0	0	0	RCODE	
0x0000	0x0000	
0x0000	0x0000	

RR_NAME
	
NULL (0x000A)	IN (0x0001)	
0x0000000	
0x0000		

Valeurs du champ RCODE :
Symbole	Valeur	Description	
FMT_ERR	0x1	Erreur de format. Le format de la demande est invalide.	
SRV_ERR	0x2	Défaillance du serveur. Il y a un problème avec le NBNS, qui ne peut pas traiter le nom.	
NAM_ERR	0x3	Erreur de nom. Le nom demandé n’existe pas.	
IMP_ERR	0x4	Erreur de demande non prise en charge. N’est admis que pour la mise en cause du NBNS quand on obtient une demande d’enregistrement de type de mise à jour.	
RFS_ERR	0x5	Erreur de refus. Pour des raisons de politique, le serveur ne veut pas enregistrer ce nom provenant de cet hôte.	

4.2.15	Redirection de la réponse d’interrogation de nom

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	1	0x0	0	0	1	0	0	0	0	0x0	
0x0000	0x0000	
0x0001	0x0001	

RR_NAME
	
NS (0x0002)	IN (0x0001)	
TTL	
RDLENGTH		

NSD_NAME

RR_NAME
	
A (0x0001)	IN (0x0001)	
TTL	
0x0004	NSD_IP_ADDR	
NSD_IP_ADDR, (suite)	

Un nœud d’extrémité qui répond à une Demande d’interrogation de nom répond toujours avec les bits AA et RA établis (mis à un) pour les deux paquets Réponse positive et Réponse négative d’interrogation de nom. Un nœud d’extrémité n’envoie jamais de paquet Réponse de redirection d’interrogation de nom.

Lorsque le demandeur reçoit la Réponse de redirection d’interrogation de nom, il doit réitérer sa Demande d’interrogation de nom au NBNS spécifié par le champ NSD_IP_ADDR de l’enregistrement de ressource de type A dans le paragraphe supplémentaire du paquet de réponse. C’est un paquet facultatif pour le NBNS.

Le NSD_NAME et le RR_NAME dans le paragraphe supplémentaire du paquet de réponse ont le même nom. L’espace peut être optimisé si les pointeurs de chaîne d’étiquette sont utilisés dans le RR_NAME qui pointe sur les étiquettes dans le NSD_NAME.

Le RR_NAME dans le paragraphe Autorité est le nom de domaine sur lequel le NBNS appelé par NSD_NAME a autorité.

4.2.16	Attente d’une réponse d’accusé de réception (WACK)

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	1	0x7	1	0	1	0	0	0	0	0x0	
0x0000	0x0001	
0x0000	0x0000	

RR_NAME
	
NULL (0x0020)	IN (0x0001)	
TTL	
0x0002	OPCODE	Fanions NM	0x0	

Le NAME_TRN_ID du paquet de la réponse WACK est le même que le NAME_TRN_ID de la demande dont le NBNS est en train de dire au demandeur d’attendre encore un peu qu’elle se termine. Le RR_NAME est le nom provenant de la demande, s’il en est. Si aucun nom n’est disponible à partir de la demande, c’est alors un nom nul, simple octet de zéros.

Le champ TTL de l’enregistrement de ressource (ResourceRecord) est la nouvelle durée de l’attente, en secondes, pour l’achèvement de la demande. Le champ RDATA contient le OPCODE et les fanions NM (NM_FLAGS) de la demande.

Une valeur de TTL de 0 signifie que le NBNS ne peut pas estimer le délai nécessaire pour l’achèvement d’une réponse.

4.2.17	Demande d’état de nœud

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	0	0x0	0	0	0	0	0	0	B	0x0	
0x0001	0x0000	
0x0000	0x0000	

QUESTION_NAME
	
NBSTAT (0x0021)	IN (0x0001)	

4.2.18	Réponse d’état de nœud

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
NAME_TRN_ID	1	0x0	1	0	0	0	0	0	0	0x0	
0x0000	0x0001	
0x0000	0x0000	

RR_NAME
	
NB (0x0020)	IN (0x0001)	

RR_NAME
	
NBSTAT (0x0021)	IN (0x0001)	
0x0000000	
RDLENGTH	NUM_NAMES	

Matrice NODE_NAME

Statistiques

La matrice NODE_NAME est un dispositif de zéro, une ou plusieurs entrées de NUM_NAMES d’enregistrements de NODE_NAME. Chaque entrée de NODE_NAME représente un nom actif dans le même domaine d’application NetBIOS que le nom demandeur dans le tableau local des noms du répondant. RR_NAME est le nom demandeur.

Entrées de NODE_NAME :

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	

Nom de format NetBIOS
	
NAME_FLAGS		

Le champ NAME_FLAGS :

										1	1	1	1	1	1	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	
G	ONT	DRG	CNF	ACT	PRM	Réservé	

Le champ NAME_FLAGS est défini par :
Symbole	Bit(s)	Description:	
Réservé	7-15	Réservé pour utilisation future. Doit être à zéro (0).	
PRM	6	Fanion de nom permanent. À un (1) l’entrée est alors le nom permanent de nœud. Le fanion est à zéro (0) pour tous les autres noms.	
ACT	5	Fanion de nom actif. Toutes les entrées ont ce fanion mis à un (1).	
CNF	4	Fanion de conflit. Mis à un (1) le nom qui est sur ce nœud est alors en conflit.	
DRG	3	Fanion de désenregistrement. Mis à un (1) ce nom est alors en cours de suppression.	
ONT	1,2	Type de nœud possesseur :	
		00 = nœud B	
		01 = nœud P	
		10 = nœud M	
		11 = Réservé pour utilisation future	
G	0	Fanion de nom de groupe.	
		Mis à un (1) le nom est alors un nom de groupe NetBIOS.	
		À zéro (0) c’est alors un nom NetBIOS unique.	

Champ Statistiques de la Réponse d’état de nœud :

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
UNIT_ID (Identifiant d’unité unique)	
UNIT_ID (suite)	JUMPERS	RÉSULTATS_D’ESSAIS	
NUMÉRO_DE_VERSION	PÉRIODE_DE_STATISTIQUES	
NOMBRE_DE_CRC	NOMBRE_D’ERREURS_D’ALIGNEMENT	
NOMBRE_DE_COLLISIONS	NOMBRE_D’INTERRUPTIONS_D’ENVOI	
NOMBRE_DE_BONS_ENVOIS	
NOMBRE_DE_BONNES_RÉCEPTIONS	
NOMBRE_DE_RETRANSMISSIONS	NOMBRE_DE_CONDITIONS_PAS_DE_RESSOURCE	
NOMBRE_BLOCS_COMMANDE_LIBRES	NOMBRE_TOTAL_DE_BLOCS_DE_COMMANDE	
TOTAL_MAXI_NOMBRE_BLOCS_DE_COMMANDE	NOMBRE_DE_SESSIONS_EN_COURS	
NOMBRE_MAXI_DE_SESSIONS_EN_COURS	TOTAL_MAXIMUM_DE_SESSIONS_POSSIBLES	
TAILLE_DE_PAQUET_DE_DONNÉES_DE_SESSION		

4.3	Paquets du service de session
4.3.1	Format général des paquets de session

Tous les messages du service de session sont envoyés sur une connexion TCP.

Tous les paquets de session ont la structure générale suivante :

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
Type	Fanions	Longueur	
En-queue (selon le type de paquet)	

Les champs Type, Fanions, et Longueur sont présents dans chaque paquet de session.

Le champ Longueur est le nombre d’octets qui suivent le champ Longueur. En d’autres termes, Longueur est la taille combinée du ou des champs En-queue. Par exemple, le paquet Réponse positive de session a une valeur de champ Longueur de zéro (0000) alors que la Réponse de reciblage de session a toujours une valeur de champ Longueur de six (0006).

Un des bits du champ Fanions agit comme un bit additionnel de plus fort poids pour le champ Longueur. Et donc la taille cumulée du ou des champs d’en-queue peut aller de 0 à 128 koctet.

Types de paquet de session (en hexadécimal) :
00 -  Message de session
81 -  Demande de session
82 -  Réponse positive de session
83 -  Réponse négative de session
84 -  Réponse de reciblage de session
85 -  Garder la session en vie

Définitions binaires du champ Fanions :
0	1	2	3	4	5	6	7	
0	0	0	0	0	0	0	E	

Symbole	Bit(s)	Description	
E	7	Extension de longueur, utilisée comme bit additionnel, de plus fort poids, sur le champ Longueur.	
Réservé	0-6	Réservé, doit être à zéro (0)	

4.3.2	Paquet de demande de session

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
Type	Fanions	Longueur	
Nom appelé
	
Nom appelant

4.3.3	Paquet de réponse positive de session

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
Type	Fanions	Longueur	

4.3.4	Paquet de réponse négative de session

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
Type	Fanions	Longueur	
CODE_D’ERREUR	

Valeurs de code d’erreur de paquet Réponse négative de session (en hexadécimal) :
80 -  Pas d’écoute du nom appelé
81 -  Pas d’écoute du nom appelant
82 -  Nom appelé absent
83 -  Nom appelé présent, mais ressources insuffisantes
8F -  Erreur non spécifiée

4.3.5	Paquet de réponse de reciblage de session

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
Type	Fanions	Longueur	
Adresse_IP_de_reciblage	
Accès	

4.3.6	Paquet de message de session

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
Type	Fanions	Longueur	

Données_d’utilisateur

4.3.7	Paquet de maintien en vie de session

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
Type	Fanions	Longueur	

4.4	Paquets du service de datagrammes
4.4.1	En-tête de datagramme NetBIOS

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
Type_de_message	Fanions	DGM_ID	
Source_IP	
SOURCE_PORT	DGM_LENGTH	
PACKET_OFFSET	

Valeurs de Type_de_message (en hexadécimal) :
10 - Datagramme DIRECT_UNIQUE
11 - Datagramme DIRECT_GROUP
12 - Datagramme de diffusion
13 - Datagramme d’erreur
14 - Datagramme de demande d’interrogation
15 - Datagramme de réponse positive d’interrogation
16 - Datagramme de réponse négative d’interrogation

Définitions binaires du champ Fanions :
0	1	2	3	4	5	6	7	
0	0	0	0	SNT	F	M	

Symbole	Bit(s)	Description	
M	7	Fanion MORE (plus), s’il est mis (à un) d’autres fragments de datagramme NetBIOS suivent.	
F	6	Fanion de premier paquet, mis à un, c’est le premier (et éventuellement le seul) fragment de datagramme NetBIOS.	
SNT	4, 5	Type de nœud d’extrémité de source:	
		00 = nœud B	
		01 = nœud P	
		10 = nœud M	
		11 = NBDD	
Réservé	0-3	Réservé, doit être à zéro (0)	

4.4.2	Datagramme direct_unique, direct_groupe, & de diffusion

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
Type_de_message	Fanions	DGM_ID	
Source_IP	
SOURCE_PORT	DGM_LENGTH	
PACKET_OFFSET		

Nom_de_source

Nom_de_destination

Données_d’utilisateur

4.4.3	Datagramme d’erreur de paquet

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
Type_de_message	Fanions	DGM_ID	
Source_IP	
SOURCE_PORT	Code_d’erreur	

Valeurs de Code_d’erreur (en hexadécimal) :
82 – Nom de destination absent
83 – Format de nom de source invalide
84 – Format de nom de destination invalide

4.4.4	Datagramme de demande d’interrogation

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
Type_de_message	Fanions	DGM_ID	
Source_IP	
SOURCE_PORT		

Nom_de_destination

4.4.5	Datagramme de réponse positive et négative d’interrogation

										1	1	1	1	1	1	1	1	1	1	2	2	2	2	2	2	2	2	2	2	3	3	
0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	2	3	4	5	6	7	8	9	0	1	
Type_de_message	Fanions	DGM_ID	
Source_IP	
SOURCE_PORT		

Nom_de_destination

5.	Descriptions des protocoles
5.1	Protocoles du service de noms

Un paquet Demande est toujours envoyé à l’accès UDP bien connu - NAME_SERVICE_UDP_PORT (accès UDP du service de noms). L’adresse de destination est normalement soit l’adresse de diffusion IP, soit l’adresse du NBNS – l’adresse du serveur NBNS qu’il a établie au moment de l’initialisation. Dans de rares cas, un paquet Demande sera envoyé à un nœud d’extrémité, par exemple. une demande d’interrogation de nom envoyée pour "mettre en cause" un nœud.

Un paquet Réponse est toujours envoyé à l’accès UDP de source et à l’adresse IP de source du paquet de demande.

Un paquet Instruction doit toujours être envoyé à l’accès UDP bien connu - NAME_SERVICE_UDP_PORT. Il n’y a pas de contraintes sur l’adresse IP cible.

Termes utilisés dans la présente section :
tid – Identifiant de transaction. C’est une valeur composée à partir de l’adresse IP du demandeur et d’une valeur unique de 16 bits générée par l’origine de la transaction.

5.1.1	Activité de nœud B

5.1.1.1	Ajout de nom au nœud B

Procédure add_name(newname)

/* L’hôte a initié le traitement pour un nœud B */
COMMENCER
     RÉPÉTER
          /* construit un paquet de service de noms */
          ONT = B_NODE; /* nœud de diffusion */
          G = UNIQUE;   /* nom unique */
          TTL = 0;

paquet de diffusion Demande d’enregistrement de nom ;
             /* le ou les nœuds distants vont envoyer le paquet de réponse s’il y a lieu */
             pause(BCAST_REQ_RETRY_TIMEOUT);
JUSQU’à ce que le paquet de réponse soit reçu ou que le compte de retransmission soit dépassé
        SI aucun paquet de réponse n’est reçu, ALORS
        COMMENCER /* pas de réponse */
             /* construire le paquet */
             ONT = B_NODE; /* nœud de diffusion */
             G = UNIQUE;   /* nom unique */
             TTL = 0;
             /* Faire connaître aux autres nœuds que vous avez le nom */
             diffuser le paquet Demande de mise à jour de nom ;
             /* le nom peut être ajouté au tableau local des noms */
             retourner l’information de succès ;
        FIN /* de pas de réponse */
        AUTREMENT
        COMMENCER /* réponse obtenue */
             /* Confronter l’identifiant de transaction retourné au tid envoyé dans la demande */
            SI tid de réponse ≠ tid de demande ALORS
            COMMENCER
             ignorer le paquet de réponse ;
         FIN
            AUTREMENT
            CAS du type de paquet de Réponse négative d’enregistrement de nom :
                 retourner un échec ; /* le nom ne peut être ajouté */
            Réponse positive d’enregistrement de nom :
            Le nœud d’extrémité met en cause la Réponse d’enregistrement de nom :
                 /* les nœuds B ne devraient normalement pas obtenir cette réponse. */
                  ignorer le paquet ;

         FIN /* du cas */;
     FIN /* de réponse obtenue */
FIN /* de la procédure */

5.1.1.2	Ajout de nom de groupe au nœud B
Procédure add_group_name(newname)

/* L’hôte a initié le traitement pour un nœud B */
COMMENCER
        /* comme pour un nom unique sauf que le bit groupe (G) doit être établi dans les paquets de demande. */
        ...
        G = GROUP;
        ...
        ...
        /* demande en diffusion ... */
FIN

5.1.1.3	Le nœud B trouve un nom

Procédure find_name(name)

/* L’hôte a initié le traitement pour un nœud B */

COMMENCER
     RÉPÉTER
             /* construire le paquet */
             ONT = B;
             TTL = 0;
             G = NE PAS TENIR COMPTE;
         paquet Demande d’interrogation de nom en diffusion ;
             /* un nœud peut envoyer un paquet de réponse */
             pause(BCAST_REQ_RETRY_TIMEOUT) ;
        JUSQUE à réception d’un paquet de réponse OU
             dépassement du seuil maximum de transmission
        SI aucun paquet de réponse n’est reçu, ALORS
             retourner échec ;
        AUTREMENT
        SI tid de réponse ≠ tid de demande ALORS
             ignorer le paquet ;
        AUTREMENT
        CAS du type de paquet de Réponse positive d’interrogation de nom :
             /* Lancer un temporisateur pour détecter un conflit. *
              * Être prêt à détecter un conflit si d’autres paquets de réponse sont reçus. */
             sauvegarder la réponse comme réponse d’autorisation ;
             start_timer(CONFLICT_TIMER) ;
             retourner une information de réussite ;
        Réponse négative d’interrogation de nom :
        Rediriger la réponse d’interrogation de nom :
             /* Le nœud B devrait ne normalement obtenir ni l’une ni l’autre réponse. */
         ignorer le paquet de réponse ;
        FIN /* du cas */
   FIN /* de la procédure */

5.1.1.4	Le nœud B libère le nom

Procédure delete_name (name)
COMMENCER
     RÉPÉTER
             /* construire le paquet */
             ...
             /* envoyer la demande */
          paquet Demande de libération de nom en diffusion ;

          /* pas de paquet de réponse attendu */
          pause(BCAST_REQ_RETRY_TIMEOUT);
     JUSQUE à dépassement du compte de retransmission
FIN /* de la procédure */

5.1.1.5	Le nœud B traite le paquet entrant

Le traitement suivant est effectué lorsque des paquets en envoi individuel ou en diffusion son reçus à l’accès NAME_SERVICE_UDP_PORT.

Procédure process_incoming_packet(packet)
/* Processus initié par les paquets entrants pour un nœud B */

COMMENCER
        /* Note : les paquets de réponse sont toujours envoyés à :
         * l’adresse IP de source du paquet de demande
         * à l’accès UDP de source du paquet de demande */

CAS du type de paquet de 
Demande d’enregistrement de nom (UNIQUE) :
             Si le nom existe dans le tableau local des noms ALORS
                  envoyer une Réponse négative d’enregistrement de nom ;
Demande d’enregistrement de nom (GROUPE) :
             SI le nom existe dans le tableau local des noms ALORS
             COMMENCER
                  SI l’entrée locale est un nom unique ALORS
                      envoyer une Réponse négative d’enregistrement de nom ;
             FIN
Demande d’interrogation de nom :
             SI le nom existe dans le tableau local des noms ALORS
             COMMENCER
                  construire le paquet de réponse ;
                  envoyer une Réponse positive d’interrogation de nom
Réponse positive d’interrogation de nom :
             Si le temporisateur de conflit de nom n’est pas actif ALORS
             COMMENCER
                  /* le temporisateur est déjà arrivé à expiration... ignorer ce paquet */
                  retourner ;
             FIN
             AUTREMENT /* le temporisateur est actif */
             SI une réponse pour ce nom a été reçue précédemment ALORS
             COMMENCER /* entrée existante */
                  /* on a envoyé un paquet de demande, et on a déjà reçu (au moins) une réponse *
                   * Vérifier s’il existe un conflit.
                   * Si oui, envoyer un paquet de conflit. *
                   * Note : la détection d’un conflit N’AFFECTE PAS les sessions existantes. */
                  /* Rechercher un conflit de nom. Voir "Conflit de nom" dans Concepts et méthodes */
                  confronter la réponse d’autorisation sauvegardée et les informations de ce paquet de réponse ;
                  SI un conflit est détecté ALORS
                  COMMENCER
                       paquet d’Instruction de conflit de nom en envoi individuel ;
                       SI une entrée existe dans la mémoire cache ALORS
                       COMMENCER
                            retirer l’entrée de la mémoire cache ;
                       FIN
                  FIN
             FIN /* de entrée existante */
             AUTREMENT
             COMMENCER
                  /* Note : Si c’était la première réponse à une interrogation de nom, 
                   * elle aurait été traitée dans la procédure find_name(). */
                  ignorer le paquet ;
             FIN

Instruction de conflit de nom :
             SI le nom existe dans le tableau local des noms ALORS
             COMMENCER
                  marquer le nom comme conflit détecté ;
                  /* un nom dans l’état "conflit détecté" n’existe pas "logiquement" sur ce nœud.
                   * Aucune autre session ne sera acceptée sur ce nom.
                   * Aucun datagramme ne peut être envoyé contre ce nom.
                   * Une telle entrée ne sera pas utilisée pour les besoins du traitement des paquets de demande entrants.
                   * La seule opération d’utilisateur NetBIOS valide contre un tel nom est Supprimer le nom. */
             FIN
Demande de libération du nom :
             Si la mise en mémoire cache est faite ALORS
             COMMENCER
                  retirer l’entrée de la mémoire cache ;
             FIN
Demande de mise à jour de nom :
             Si la mise en mémoire cache est faite ALORS
             COMMENCER
                  SI l’entrée existe déjà dans la mémoire cache ,
                       mettre à jour la mémoire cache
                  AUTREMENT SI le nom est "intéressant" ALORS
                  COMMENCER
                       ajouter l’entrée à la mémoire cache ;
                  FIN
             FIN

Demande d’état de nœud :
             Si le nom existe dans le tableau local des noms ALORS
             COMMENCER
                  /* envoyer seulement les noms qui sont dans le même domaine d’application 
                   * que le champ Domaine d’application dans le paquet de demande */
                  envoyer la Réponse d’état de nœud ;
             FIN
   FIN

5.1.2	Activité du nœud P

Tous les paquets envoyés ou reçus par les nœuds P sont des paquets UDP en envoi individuel. Un nœud P envoie les demandes de service de noms au nœud NBNS qui est spécifié dans la configuration de nœud P.

5.1.2.1	Ajout de nom par le nœud P

Procédure add_name(newname)

/* L’hôte a initié le traitement pour un nœud P */

COMMENCER
        RÉPÉTER
             /* construire le paquet */
             ONT = P;
             G = UNIQUE;
             ...
             /* envoyer la demande */

Paquet Demande d’enregistrement de nom en envoi individuel
             /* le NBNS va envoyer le paquet de réponse */
             SI il reçoit une Réponse WACK ALORS 
                  pause(pendant la durée du champ TTL de la réponse) ;
             AUTREMENT
                  pause(UCAST_REQ_RETRY_TIMEOUT);
        JUSQUE au moment où le paquet de réponse est reçu OU
             que le compte de retransmission soit dépassé

        SI aucun paquet de réponse n’est reçu ALORS
        COMMENCER /* pas de réponse */
             /* le NBNS est en panne. Il ne peut pas revendiquer le nom. */
             retourner un échec ; /* le nom ne peut pas être revendiqué */
        FIN /* pas de réponse */
        AUTREMENT
        COMMENCER /* réponse */
            SI le tid de réponse ≠ du tid de demande ALORS
            COMMENCER
             /*  Le paquet peut appartenir à une autre transaction  */
             ignorer le paquet de réponse ;
            FIN
            AUTREMENT
            CAS du type de paquet de

Réponse positive d’enregistrement de nom :
                 /* le nom peut être ajouté */
                 ajuster la valeur de temporisation de rafraîchissement et le TTL, pour ce nom ;
                 retourner une information de succès;      /* le nom peut être ajouté */

Réponse négative d’enregistrement de nom :
                 retourner un échec ; /* le nom ne peut pas être ajouté  */

Demande d’enregistrement de mise en cause de nœud d’extrémité :
            COMMENCER /* mise en cause de nœud d’extrémité */

                 /* Le paquet de réponse possède en lui l’adresse du détenteur présumé du nom. Mettre en cause ce détenteur.
                  * Si le détenteur ne répond pas ou indique qu’il ne détient plus le nom, revendiquer le nom.
                  * Autrement, le nom ne peut pas être revendiqué. */

                 RÉPÉTER
                  /* construire le paquet */
                  ...

Paquet Demande d’interrogation de nom en envoi individuel à l’adresse contenue dans le paquet Réponse de mise en cause de nœud d’extrémité ;

                  /* le nœud distant peut envoyer un paquet de réponse */

                  pause(UCAST_REQ_RETRY_TIMEOUT);
                 JUSQU’à réception d’un paquet de réponse ou 
                     dépassement du compte de retransmission
                 SI aucun paquet de réponse n’est reçu OU
                       si un paquet Réponse négative d’interrogation de nom est reçu ALORS
                 COMMENCER /* mise à jour */

                  /* le nom peut être revendiqué */

                  RÉPÉTER
                      /* construire le paquet */
                       ...

Demande de mise à jour de nom en envoi individuel au NBNS ;

                      /* Le nœud NBNS va envoyer le paquet de réponse */

                      SI on reçoit une Réponse WACK ALORS
                            pause(durée du champ TTL de réponse);
                      AUTREMENT
                            pause(UCAST_REQ_RETRY_TIMEOUT);
                  JUSQU’à réception du paquet de réponse ou
                      dépassement du compte de retransmission
                  SI aucun paquet de réponse n’est reçu ALORS
                  COMMENCER /* pas de réponse */
                       /* le nom ne pourra pas être revendiqué */
                       retourner un échec;
                  FIN /* pas de réponse */
                  AUTREMENT
CAS du type de paquet de 
Réponse positive d’enregistrement de nom :
                            /* ajouter le nom */
                            retourner une information de succès ;
Réponse négative d’enregistrement de nom :
                            /* perdu  ... */
                            retourner un échec;
                       FIN /* du cas */
                 FIN /* de la mise à jour */
                 AUTREMENT
                 /* on a reçu une réponse positive à la "mise en cause"
                  * Le nœud distant a toujours le nom */
                  retourner un échec;
            FIN /* fin de la mise en cause du nœud */
        FIN /* de la réponse */
   FIN /* de la procédure */

5.1.2.2	Ajout de nom de groupe par le nœud P

Procédure add_group_name(newname)
/* L’hôte a initié le traitement pour un nœud P */

COMMENCER
        /* comme pour un nom unique, sauf que le paquet de demande doit indiquer que 
         * c’est une revendication de nom de groupe qui est faite. */

        ...
        G = GROUP;
        ...

        /* envoyer le paquet */
         ...

FIN

5.1.2.3	Le nœud P trouve le nom

Procédure find_name(name)

/* L’hôte a initié le traitement pour un nœud P */

COMMENCER
     RÉPÉTER
          /* construire le paquet */

             ONT = P ;
             G = Ne pas s’en soucier

Paquet Demande d’interrogation de nom en envoi individuel

             /* un nœud NBNS peut envoyer un paquet de réponse */

             SI on reçoit une Réponse WACK ALORS
                  pause(durée du champ TTL de la réponse) ;
             AUTREMENT
                  pause(UCAST_REQ_RETRY_TIMEOUT);
        JUSQU’à réception du paquet de réponse OU
             dépassement du seuil maximum de transmission

        SI aucun paquet de réponse n’est reçu ALORS
             retourner un échec;
        AUTREMENT
        SI le tid de réponse ≠ tid de demande ALORS
             ignorer le paquet;
        AUTREMENT
CAS du type de paquet de
Réponse positive d’interrogation de nom :
             retourner une information de succès ;

Réponse de redirection d’interrogation de nom :
             /* Le nœud NBNS veut que ce nœud d’extrémité utilise un autre nœud NBNS pour résoudre l’interrogation. */
           répéter l’interrogation avec l’adresse de NBNS qui est dans le paquet de réponse ;
Réponse négative d’interrogation de nom :
             retourner un échec;
     FIN /* du cas */
FIN /* de la procédure */

5.1.2.4	Suppression de nom par un nœud P

Procédure delete_name (name)

   /* L’hôte a initié le traitement pour un nœud P */

COMMENCER
     RÉPÉTER
          /* construire le paquet */
             ...
             /* envoyer la demande */

Paquet Demande de libération de nom en envoi individuel
             SI on reçoit une Réponse WACK ALORS
                  pause(durée du champ TTL de la réponse);
             AUTREMENT
                  pause(UCAST_REQ_RETRY_TIMEOUT);
        JUSQU’au dépassement du compte de retransmission
             ou la réception d’une réponse

        SI une réponse a été reçue ALORS
CAS du type de paquet de
Réponse positive de libération du nom :
             retourner une information de succès ;
Réponse négative de libération du nom :
             /* le NBNS ne veut pas que le nœud supprime ce nom !!! */
             retourner un échec;
     FIN /* du cas */
FIN /* de la procédure */

5.1.2.5	Traitement du paquet entrant par le nœud P

Processus initié par la réception de paquets au nœud P

Procédure process_incoming_packet(packet)

   /* Traitement initié par des paquets entrants à un nœud P */

COMMENCER
     /* toujours ignorer les paquets UDP en diffusion */
        SI le paquet a été envoyé en diffusion ALORS
        COMMENCER
             ignorer le paquet;
             retourner ;
        FIN

CAS du type de paquet de
Instruction de conflit de nom :
             Si le paquet existe dans le tableau local des noms ALORS
                  marquer le nom comme étant en conflit ;
             retourner;
Demande d’interrogation de nom :
             Si le paquet existe dans le tableau local des noms ALORS
             COMMENCER /* le nom existe */
                  /* construire le paquet */
                  ...
                  /* envoyer la réponse à l’adresse IP et au numéro d’accès d’où la demande a été reçue. */
                  envoyer une Réponse positive d’interrogation de nom ;
                  retourner ;
             FIN /* le nom existe */
             AUTREMENT
             COMMENCER /* le nom n’existe pas */
                  /* envoyer une réponse au demandeur */
                  envoyer une Réponse négative d’interrogation de nom ;
                  retourner ;
             FIN /* le nom n’existe pas */
Demande d’état de nœud :
          /* Le nom de "*" peut être utilisé pour forcer le nœud à divulguer l’état pour des besoins administratifs */
          SI le nom est dans le tableau local des noms OU nom = "*" ALORS
          COMMENCER
               /* Construire le paquet de réponse et l’envoyer au nœud demandeur.
                * Envoyer seulement les noms qui sont dans le même domaine d’application que celui du paquet de demande. */
                  envoyer la Réponse d’état du nœud ;
          FIN

Demande de libération de nom :
             /* Ce sera reçu si le NBNS veut vider le nom du tableau local des noms, ou de la mémoire cache locale. */
             SI le nom existe dans le tableau local des noms ALORS
             COMMENCER
                  supprimer le nom du tableau local des noms ;
                  informer l’utilisateur de la suppression du nom ;
             FIN
             AUTREMENT
                  SI le nom a été mis en mémoire cache locale ALORS
                  COMMENCER
                       retirer l’entrée de la mémoire cache :
               FIN
    FIN /* du cas */
FIN /* de la procédure */

5.1.2.6	Processus initié par un temporisateur de nœud P

Processus initié par l’expiration du temporisateur.

Procédure timer_expired()
   /* Le traitement est initié par l’expiration d’un temporisateur sur un nœud P */
   COMMENCER
        /* Envoyer une Demande de rafraîchissement de nom pour chaque nom dont le TTL est arrivé a expiration. */
        RÉPÉTER
             construire le paquet Demande de rafraîchissement de nom ;
             RÉPÉTER
                  envoyer le paquet au NBNS ;
                  SI on reçoit une Réponse WACK ALORS
                       pause(durée du champ TTL de la réponse);
                  AUTREMENT
                       pause(UCAST_REQ_RETRY_TIMEOUT);
             JUSQU’à réception d’un paquet ou dépassement du compte de retransmission

CAS du type de paquet de
Réponse positive d’enregistrement de nom :
                  /* rafraîchissement réussi */
                  remettre le temporisateur de TTL à zéro pour ce nom ;

Réponse négative d’enregistrement de nom :
                  /* refusé, le nom ne peut être gardé, il est supposé en conflit */
                  marque le nom comme étant en conflit ;
          FIN /* du cas */

     JUSQU’à l’envoi de la demande pour tous les noms pour lesquels le TTL est arrivé à expiration
FIN /* de la procédure */

5.1.3	Activité de nœud M

Le comportement des nœuds M est similaire à celui des nœuds P avec l’ajout de certaines actions de diffusion du type de celles des nœuds B. Le service de noms de nœud M procède en deux étapes :

1.	Utiliser le service de noms en diffusion fondé sur UDP. Selon l’opération, passer à l’étape 2.
2.	Utiliser le service de noms UDP dirigé.

Le code suivant pour les nœuds M est exactement le même que pour un nœud P, sauf que les opérations de diffusion sont faites avant de tenter les opérations de type P.

5.1.3.1	Le nœud M ajoute le nom

Procédure add_name(newname)

/* L’hôte a initié le traitement pour un nœud M */

COMMENCER
     /* vérifier si le nom existe sur la zone de diffusion */

     RÉPÉTER
         /* construire le paquet */

            ....
            paquet Demande d’enregistrement de nom en diffusion ;
            pause(BCAST_REQ_RETRY_TIMEOUT);
        JUSQU’à réception d’un paquet de réponse ou dépassement du compte de retransmission
        SI une réponse valide est reçue ALORS
        COMMENCER
             /* ne peut pas revendiquer le nom */
             retourner un échec;
     FIN

        /* Pas d’objections reçues au sein de la zone de diffusion.
         * Envoyer la demande au serveur de nom. */

     RÉPÉTER
             /* construire le paquet */

             ONT = M ; 
             ...

Paquet Demande d’enregistrement de nom en envoi individuel
             /* le NBNS distant va envoyer le paquet de réponse */
          Si on reçoit une Réponse WACK ALORS
               pause(durée du champ TTL de la réponse);
          AUTREMENT
               pause(UCAST_REQ_RETRY_TIMEOUT);
     JUSQU’à réception d’un paquet de réponse ou dépassement du compte des retransmissions
      SI aucun paquet de réponse n’a été reçu ALORS
     COMMENCER /* pas de réponse */
          /* le NBNS est en panne. Il ne peut pas revendiquer le nom */
          retourner un échec; /* le nom ne peut pas être revendiqué */
     FIN /* de pas de réponse */
     AUTREMENT
     COMMENCER /* réponse */
         Si le tid de réponse ≠ tid de demande ALORS
         COMMENCER
          ignorer le paquet de réponse ;
      FIN
         AUTREMENT
         CAS du type de paquet de
Réponse positive d’enregistrement de nom :
              /* le nom peut être ajouté */
              ajuster la valeur de temporisation de rafraîchissement et le TTL ;
              retourner une information de succès;      /* le nom peut être ajouté */

Réponse négative d’enregistrement de nom :
              retourner un échec ; /* le nom ne peut pas être ajouté */

Demande  d’enregistrement de mise en cause de nœud d’extrémité :
         COMMENCER /* mise en cause de nœud d’extrémité */
              /* Le paquet de réponse a en lui l’adresse du détenteur présumé du nom. Mettre en cause ce détenteur.
                  * Si le détenteur ne répond pas ou indique qu’il ne détient plus le nom, revendiquer le nom.
                  * Autrement, le nom ne peut pas être revendiqué. */

              RÉPÉTER
               /* construire le paquet */
                  ...
               /* envoyer le paquet à l’adresse contenue dans le paquet de réponse */

paquet Demande d’interrogation de nom en envoi individuel
               /* le nœud distant peut envoyer le paquet de réponse */
               pause(UCAST_REQ_RETRY_TIMEOUT);
              JUSQU‘à réception du paquet de réponse ou dépassement du compte de retransmissions
              SI aucun paquet de réponse n’est reçu ALORS
              COMMENCER /* pas de réponse */
                  /* le nom peut être revendiqué */
               RÉPÉTER
                   /* construire le paquet */
                    ...

Demande de mise à jour de nom en envoi individuel au NBNS ;
                   /* le nœud NBNS va envoyer le paquet de réponse */
                  SI on reçoit une Réponse WACK ALORS
                         pause(durée du champ TTL de la réponse);
               AUTREMENT
                    pause(UCAST_REQ_RETRY_TIMEOUT);
               JUSQU’à réception d’un paquet de réponse ou dépassement du compte de retransmissions
               Si aucun paquet de réponse n’est reçu ALORS
               COMMENCER /* pas de réponse */
                    /* le nom n’a pas pu être revendiqué */
                    retourner un échec;
               FIN /* pas de réponse */
               AUTREMENT
               CAS du type de paquet de
Réponse positive d’enregistrement de nom :
                    /* ajouter le nom */
                    retourner une information de succès ;
Réponse négative d’enregistrement de nom :
                    /* perdu  ... */
                    retourner un échec;
               FIN /* du cas */
              FIN /* pas de réponse */
              AUTREMENT
              SI le tid de réponse ≠ tid de demande ALORS
              COMMENCER
               ignorer le paquet de réponse ;
              FIN
              /* une réponse au paquet de "mise en cause" est reçue */

CAS du type de paquet de
Interrogation positive de nom :
               /* le nœud distant a toujours le nom. */
               retourner un échec;
Interrogation négative de nom :
               /* le nœud distant n’a plus le nom */
               retourner une information de succès ;
              FIN /* du cas */
           FIN /* de la mise en cause du nœud d’extrémité */
         FIN /* du cas */ 
     FIN /* de réponse */
FIN /* de la procédure */

5.1.3.2	Ajout de nom de groupe par le nœud M

Procédure add_group_name(newname)
/* L’hôte a initié le traitement pour un nœud P */

COMMENCER
/* comme pour un nom unique, sauf que le paquet de demande doit indiquer qu’on fait une revendication de nom de groupe
 */
        ...
        G = GROUP;
        ...
     /* envoyer le paquet */
      ...
FIN

5.1.3.3	Le nœud M trouve le nom

Procédure find_name(name)
/* L’hôte a initié un traitement pour un nœud M */

COMMENCER
     /* vérifier si un nœud de la zone de diffusion a le nom */
     RÉPÉTER
          /* construire le paquet */
          ...

paquet de Demande d’interrogation de nom en diffusion
             pause(BCAST_REQ_RETRY_TIMEOUT);
        JUSQU’à réception d’un paquet de réponse OU
             dépassement du seuil maximum de transmission

        SI une réponse valide est reçue ALORS
        COMMENCER
             sauvegarder la réponse comme réponse d’autorisation ;
             start_timer(CONFLICT_TIMER);
             retourner une information de succès ;
        FIN

        /* pas de réponse valide sur le segment de diffusion. Essayer le serveur de noms. */

     RÉPÉTER
          /* construire le paquet */
          ONT = M;
          G = Ne pas s’en soucier ;

Paquet de Demande d’interrogation de nom en envoi individuel au NBNS ;
          /* un nœud NBNS pourrait envoyer un paquet de réponse */
          SI il reçoit une Réponse WACK ALORS
               pause(durée du champ TTL de la réponse);
          AUTREMENT               pause(UCAST_REQ_RETRY_TIMEOUT);
     JUSQU’à réception d’un paquet de réponse OU
          dépassement du seuil maximum de transmission

     Si aucun paquet de réponse n’est reçu ALORS
          retourner un échec;
     AUTREMENT
     SI le tid de réponse ≠ tid de demande ALORS
          ignorer le paquet;
     AUTREMENT
     CAS du type de paquet de
Réponse positive d’interrogation de nom :
          retourner une information de succès ;
Réponse de redirection d’interrogation de nom :
          /* le nœud NBNS veut que ce nœud d’extrémité utilise un autre nœud NBNS pour résoudre l’interrogation. */
           répéter l’interrogation avec l’adresse de NBNS du paquet de réponse ;
Réponse négative d’interrogation de nom :
          retourner un échec;
     FIN /* du cas */
FIN /* de la procédure */

5.1.3.4	Le nœud M supprime le nom

Procédure delete_name (name)
/* L’hôte a initié le traitement pour un nœud P */

COMMENCER
     /* D’abord, supprimer le nom sur le NBNS */

     RÉPÉTER
          /* construire le paquet */
             ...
          /* envoyer la demande */

paquet de Demande de libération de nom en envoi individuel au NBNS ;

          SI on reçoit une Réponse WACK ALORS
               pause(durée du champ TTL de la réponse);
          AUTREMENT
               pause(UCAST_REQ_RETRY_TIMEOUT);
     JUSQU’au dépassement du compte de retransmission
          ou la réception d’une réponse

        SI une réponse a été reçue ALORS
        CAS du type de paquet de
Réponse positive de libération de nom :
          /* La suppression du nom sur le segment de diffusion est différée jusqu’après que le NBNS a supprimé le nom */
          RÉPÉTER
               /* construire le paquet */
               ...
Demande de libération de nom en diffusion ;
               pause(BCAST_REQ_RETRY_TIMEOUT);
          JUSQU’à dépassement du seuil rexmt
             retourner une information de succès ;
Réponse négative de libération de nom :
          /* Le NBNS veut que le nœud supprime ce nom */
          retourner un échec;
     FIN /* du cas */
FIN /* de la procédure */

5.1.3.5	Traitement de paquet entrant de nœud M

Processus initié par la réception de paquets au nœud M

Procédure process_incoming_packet(packet)
/* Processus initié par des paquets entrants au nœud M */

COMMENCER
     CAS du type de paquet de
Instruction de conflit de nom :
          Si le paquet existe dans le tableau local des noms ALORS
               marquer le nom comme en conflit ;
          retourner ;

Demande d’interrogation de nom :
          Si le paquet existe dans le tableau local des noms ALORS
          COMMENCER /* le nom existe */

               /* construire le paquet */
                  ...
               /* envoyer la réponse au numéro d’adresse et accès IP d’où la demande a été reçue. */
               envoyer une Réponse positive d’interrogation de nom ;
               retourner ;
          FIN /* le nom existe */
          AUTREMENT
          COMMENCER /* le nom n’existe pas */
               /* envoyer la réponse au demandeur */
               SI la demande N’EST PAS en diffusion ALORS
                    /* Ne pas envoyer de réponses négatives aux interrogation envoyées par les nœuds B */
                    envoi d’une Réponse négative d’interrogation de nom ;
               retourner;
          FIN /* le nom n’existe pas */
     Demande d’état de nœud :
          COMMENCER
          /* Le nom de "*" peut être utilisé pour forcer le nœud à divulguer l’état pour des besoins administratifs */
          SI le nom dans le tableau local des noms OU si le nom = "*" ALORS
               /* Construire le paquet de réponse et l’envoyer au nœud demandeur
                * N’envoyer que les noms qui sont dans le même domaine d’application que celui du paquet de demande. */
               envoi d’une Réponse d’état de nœud ;
          FIN

Demande de libération de nom :
          /* Cela sera reçu si le NBNS veut vider le nom du tableau local des noms, ou de la mémoire cache locale. */
          SI le nom existe dans le tableau local des noms ALORS
          COMMENCER
              supprimer le nom du tableau local des noms ;
              informer l’usager de la suppression du nom ;
          FIN
          AUTREMENT
              SI le nom a été mis en mémoire cache locale ALORS
               COMMENCER
                    retirer l’entrée de la mémoire cache :
               FIN

Demande d’enregistrement de nom (unique) :
          Si le paquet existe dans le tableau local des noms ALORS
               envoi d’une Demande négative d’enregistrement de nom  ;
Demande d’enregistrement de nom (groupe):
         SI le paquet existe dans le tableau local des noms ALORS
             COMMENCER
         SI l’entrée locale est un nom unique ALORS
                   envoi d’une Réponse négative d’enregistrement de nom  ;
         FIN
     FIN /* du cas */
FIN /* de la procédure */

5.1.3.6	Traitement initié par un temporisateur de nœud M
Traitement initié par l’expiration du temporisateur :

Procédure timer_expired()
/* Traitement initié par l’expiration d’un temporisateur sur un nœud M */
COMMENCER
     /* Envoyer une Demande de rafraîchissement de nom pour chaque nom dont le TTL est arrivé à expiration. */
     RÉPÉTER
          construire le paquet de Demande de rafraîchissement de nom ;
          RÉPÉTER
               envoyer le paquet au NBNS ;
              SI on reçoit une Réponse WACK ALORS
                    pause(durée du champ TTL de la réponse);
               AUTREMENT
                    pause(UCAST_REQ_RETRY_TIMEOUT);
          JUSQU’à réception d’un paquet de réponse ou
               dépassement du compte de retransmissions

          CAS du type de paquet de
Réponse positive d’enregistrement de nom :
               /* rafraîchissement réussi */
               remettre le temporisateur de TTL à zéro pour ce nom ;

Réponse négative d’enregistrement de nom :
               /* refusé, ne peut garder le nom supposé en conflit */
               marquer le nom comme étant en conflit ;
          FIN /* du cas */
     JUSQU’à l’envoi d’une demande pour tous les noms dont le TTL est arrivé à expiration
FIN /* de la procédure */

5.1.4	Activité du NBNS

Un nœud NBNS va recevoir des paquets dirigés provenant des nœuds P et M. Les paquets de réponse sont toujours envoyés comme paquets dirigés à l’adresse IP de source et au numéro d’accès UDP. Les paquets en diffusion reçus doivent être ignorés.

5.1.4.1	Traitement du paquet entrant au NBNS

Procédure process_incoming_packet(packet)
/* Traitement du paquet entrant sur un nœud du service de noms */

COMMENCER
     SI le paquet a été envoyé comme étant en diffusion ALORS
     COMMENCER
          éliminer le paquet ;
          retourner ;
     FIN
CAS du type de paquet de
Demande d’enregistrement de nom (unique) :
          SI le nom unique existe dans la base de données ALORS
          COMMENCER /* le nom unique existe */
               /* Le nœud NBNS peut être un serveur "passif" en ce qu’il s’attend 
                   * à ce que le nœud d’extrémité fasse le serveur de mise en cause.
                   * Un tel nœud NBNS est appelé serveur "non sécurisé".
                   * Un serveur "sécurisé" fera la mise en cause avant de renvoyer un paquet de réponse. */

               SI le serveur est non sécurisé ALORS
               COMMENCER
                    /* construire le paquet de réponse */
                       ...

                       /* que le nœud d’extrémité fasse la mise en cause */
                    envoi de Réponse de mise en cause d’enregistrement de nom de nœud d’extrémité ;
                    retourne ;
               FIN
               AUTREMENT
               /* serveur sécurisé - faire l’opération de mise en cause du nom */

               RÉPÉTER
                   envoi de la Demande d’interrogation de nom ;
                   pause(UCAST_REQ_RETRY_TIMEOUT);
               JUSQU’à réception d’une réponse ou
                    dépassement du compte de retransmissions
               SI on ne reçoit pas de réponse ALORS
               COMMENCER
                    /* nœud en panne */
                    mettre à jour la base de données - retirer l’entrée ;
                    mettre à jour la base de données - ajouter une nouvelle entrée ;
                    envoi d’une Réponse positive d’enregistrement de nom ;
                    retourner ;
               FIN
               AUTREMENT
               COMMENCER /* le nœud de mise en cause a répondu */
                   /* le nœud de mise en cause a répondu par un paquet de réponse */

CAS du type de paquet
Réponse positive d’interrogation de nom :
                    /* le nom est toujours détenu par le nœud mis en cause 
                     * construire le paquet et envoyer la réponse */
                     ...
                    /* Note : Le NBNS aura besoin de garder la trace (sur la base de l’id de transaction) de l’adresse IP
                        * et du numéro d’accès du demandeur d’origine. */
                    envoi d’une Réponse négative d’enregistrement de nom ;
                    retourner ;

Réponse négative d’interrogation de nom :
                    mettre à jour la base de données - retirer l’entrée ;
                    mettre à jour la base de données – ajout d’une nouvelle entrée ;
                    /* construire le paquet de réponse et envoi de la réponse */
                    envoi d’une Réponse positive d’enregistrement de nom ;
                    retourner ;
                   FIN /* du cas */
               FIN /* de la réponse du nœud mis en cause */
          FIN /* le  nom unique existe dans la base de données */
          AUTREMENT
          SI le nom de groupe existe dans la base de données ALORS
          COMMENCER /* le nom de groupe existe */
               /* Les membres d’un nom de groupe NE SONT PAS mis en cause.
                * On suppose qu’au moins quelques membres du groupe sont toujours en vie.
                * Le mécanisme de rafraîchissement permettra au NBNS de détecter 
                * quand les membres d’un groupe n’utilisent plus le nom. */
                envoi d’une Réponse négative d’enregistrement de nom ;
          FIN /* le nom de groupe existe */
          AUTREMENT
          COMMENCER /* le nom n’existe pas */
               /* Le nom n’existe pas dans la base de données
                * Ce code s’applique à la fois au serveur non sécurisé et au serveur sécurisé. */
               mettre à jour la base de données - ajout d’une nouvelle entrée ;
               envoi d’une Réponse positive d’enregistrement de nom ;
               retourner ;
          FIN

Demande d’interrogation de nom :
          SI le nom existe dans la base de données ALORS
          COMMENCER
               /* construire le paquet de réponse et l’envoyer au demandeur */
                ...
               envoi d’une Réponse positive d’interrogation de nom ;
               retourner ;
          AUTREMENT
          COMMENCER
               /* construire le paquet de réponse et l’envoyer au demandeur */
                ...
               envoi d’une Réponse négative d’interrogation de nom ;
               retourner ;
          FIN

Demande d’enregistrement de nom (groupe) :
          SI le nom existe dans la base de données ALORS
          COMMENCER
              SI l’entrée locale est un nom unique ALORS
               COMMENCER /* local est unique */
              SI le serveur est non sécurisé ALORS
                COMMENCER
                   envoi de la Réponse d’enregistrement de nom de mise en cause de nœud d’extrémité ;
                   retourner ;
                   FIN

                   RÉPÉTER
                    envoi d’une Demande d’interrogation de nom ;
                    pause(UCAST_REQ_RETRY_TIMEOUT);
                   JUSQU’à réception d’une réponse ou dépassement du compte de retransmission
                   SI il n’y a pas de réponse reçue ou
                        réception de Réponse négative d’interrogation de nom ALORS
                   COMMENCER
                    mettre à jour la base de données - retirer l’entrée ;
                    mettre à jour la base de données - ajouter une nouvelle entrée ;
                    envoi d’une Réponse positive d’enregistrement de nom ;
                    retourner ;
                   FIN
                   AUTREMENT
                   COMMENCER
                    /* le nom est toujours détenu par le nœud mis en cause */
                     envoi d’une Réponse négative d’enregistrement de nom ;
                   FIN
               FIN /* le nom local est unique */
               AUTREMENT
               COMMENCER /* le nom local est un nom de groupe */
                    /* l’entrée existante est un nom de groupe */
                    mettre à jour la base de données - retirer l’entrée ;
                    mettre à jour la base de données - ajouter une nouvelle entrée ;
                    envoi d’une Réponse positive d’enregistrement de nom ;
                    retourner ;
               FIN /* le nom local est un nom de groupe */
          FIN /* le nom existe */
          AUTREMENT
          COMMENCER /* le nom n’existe pas */
               /* le nom n’existe pas dans la base de données */
               mettre à jour la base de données - ajouter une nouvelle entrée ;
               envoi d’une Réponse positive d’enregistrement de nom ;
               retourner ;
          FIN /* de n’existe pas */

Demande de libération de nom :
          /* le serveur sécurisé peut choisir d’interdire à un nœud de supprimer un nom */
          mettre à jour la base de données - retirer l’entrée ;
          envoi d’une Réponse positive de libération de nom ;
          retourner ;

Demande de mise à jour de nom :
          /* Le nœud d’extrémité a achevé avec succès la mise en cause, il n’y a pas de mise à jour de la base de données */
         SI le serveur est sécurisé ALORS
               envoi d’une Réponse négative d’enregistrement de nom ;
          AUTREMENT
          COMMENCER /* nouvelle entrée */
               SI une entrée existe déjà ALORS
                 mettre à jour la base de données - retirer l’entrée ;
                 mettre à jour la base de données - ajouter une nouvelle entrée ;
                 envoi d’une Réponse positive d’enregistrement de nom ;
                 start_timer(TTL);
          FIN

Demande de rafraîchissement de nom :
          vérifier la cohérence ;
         SI le nœud n’est pas autorisé à avoir le nom ALORS
          COMMENCER
               /* dire au nœud d’extrémité qu’il ne peut avoir le nom */
               envoi d’une Réponse négative d’enregistrement de nom ;
          FIN
          AUTREMENT
          COMMENCER
               /* envoi d’une réponse de confirmation au nœud d’extrémité. */
               envoi d’un Enregistrement positif de nom ;
               start_timer(TTL);
          FIN
          retourner ;
     FIN /* du cas */
FIN /* de la procédure */

5.1.4.2	Traitement initié par le temporisateur de NBNS

Un nœud de service de noms utilise des temporisateurs pour vider les entrées de la base de données. Chaque entrée de la base de données est retirée lorsque le temporisateur arrive à expiration. Cette valeur temporelle est un multiple du TTL de rafraîchissement établi lors de l’enregistrement du nom.

Procédure timer_expired()
/* traitement initié par l’expiration du TTL pour un nom donné */

COMMENCER
    /* Le NBNS peut (facultativement) s’assurer que le nœud est réellement en panne 
     * en envoyant une Demande d’état de nœud.
     * Si une telle demande est envoyée, et qu’il n’est pas reçu de réponse, on peut supposer que le nœud est en panne. */
    retirer l’entrée de la base de données;
FIN

5.2	Protocoles de service de session

Ci-après figurent des variables qui devraient être configurables par l’utilisateur NetBIOS. (Les valeurs par défaut de ces variables se trouvent dans "Constantes et variables définies" dans la Spécification détaillée) :

- SSN_RETRY_COUNT - Nombre maximum de tentatives de connexion TCP admissible pour une seule demande d’appel NetBIOS.

- SSN_CLOSE_TIMEOUT est la période d’attente des envois de session en instance lors de la clôture de la session NetBIOS avant de tuer la connexion TCP.

Ci-après sont les constantes définies pour le service de session NetBIOS. (Voir les valeurs de ces constantes dans "Constantes et variables définies" des Spécifications détaillées) :

- SSN_SRVC_TCP_PORT – est l’accès TCP mondialement bien connu alloué au service de session NetBIOS. Le service accepte les connexions TCP sur cet accès pour établir les sessions NetBIOS. La connexion TCP établie sur cet accès par l’appelant est initialement utilisée pour l’échange des informations de commande NetBIOS. La connexion de données NetBIOS réelles peut aussi passer par cet accès, ou, avec des dispositifs de reciblage, par un autre accès.

5.2.1	Protocoles d’établissement de session

5.2.1.1	Traitement de la demande de l’utilisateur

Procédure listen(nom de celui qui écoute, nom de l’appelant)
/* Processus initié par l’utilisateur pour les nœuds B, P et M *
 * Cette procédure suppose qu’une session entrante sera reciblée ici par un serveur de session. */
COMMENCER
     Effectuer l’écoute TCP ; /* Retourne l’accès TCP utilisé */
     Enregistrer l’écoute avec le Service de session, qui donne les noms et l’accès TCP ;
     Attendre l’ouverture de la connexion TCP ;   /* Appel entrant */
     Lire le paquet Demande de session provenant de la connexion
    Traiter la demande de session (voir le paragraphe sur le processus initié à réception des paquets de service de session) ;
     Informer le service de session que l’écoute NetBIOS est achevée ;
     SI la session est établie ALORS
          retourner les informations de succès et de session à l’utilisateur ;
     AUTREMENT
          retourner un échec;
FIN /* de la procédure */

Procédure call(nom appelant, nom appelé)
/* traitement initié par l’utilisateur pour les nœuds B, P et M */

/* Cet algorithme suppose que le nom appelé est un nom unique.
 * Si le nom appelé est un nom de groupe, la procédure call() doit effectuer un cycle à travers les membres du groupe
 * jusqu’à ce que (retry_count == SSN_RETRY_COUNT) ou la liste, ait été effectué. */
COMMENCER
     retry_count = 0;
     retarget = FAUX ;   /* VRAI : l’appelant est reciblé */
     name_query = VRAI ;  /* VRAI : l’appelant doit recommencer avec l’interrogation de nom. */

     RÉPÉTER
         SI name_query ALORS
          COMMENCER
               faire la découverte de nom, retourne l’adresse IP ;
               accès TCP = SSN_SRVC_TCP_PORT ;

               SI la découverte du nom échoue ALORS
                    retourner un échec ;
               AUTREMENT
                    name_query = FAUX ;
          FIN

          /* on a maintenant l’adresse IP et l’accès TCP de la partie distante. */

          établir la connexion TCP avec la partie distante, utiliser un accès éphémère comme accès TCP de source ;
          SI la connexion est refusée ALORS
          COMMENCER
               SI il y a reciblage ALORS
               COMMENCER
                    /* réessayer */
                    reciblage = FAUX ;
                    utiliser l’adresse IP et l’accès TCP original ;
                    goto LOOP ;
               FIN

                  /* réessayer pour l’écoute TCP manquée */

               pause(SESSION_RETRY_TIMER);
               établir la connexion TCP, utiliser à nouveau l’accès éphémère comme accès TCP de source ;

               SI la connexion est refusée OU
                  la connexion est arrivée en fin de temporisation ALORS
                    retourner un échec ;
          FIN
          AUTREMENT
          SI la connexion est arrivée en fin de temporisation ALORS
          COMMENCER
               SI il y a reciblage ALORS
               COMMENCER
                     /* réessayer */
                    reciblage = FAUX ;
                    utiliser l’adresse IP et l’accès TCP original ;
                    goto LOOP ;
               FIN
               AUTREMENT
               COMMENCER
                    /* une découverte de nom incorrecte a été faite, essayer à nouveau */
                    informer le processus de découverte de nom de possibles erreurs ;
                    name_query = VRAI ;
                    goto LOOP;
               FIN
          FIN

          /* La connexion TCP a été établie */
          attendre le paquet de réponse de session ;
          CAS du type de paquet de
Réponse positive de session :
               retourner une information de succès et de session établie ;

Réponse négative de session :
             COMMENCER
               CAS d’erreur DE
                  Pas d’écoute sur le nom appelé :
                  Pas d’écoute pour le nom appelant :
                  COMMENCER
                    tuer la connexion TCP ;
                    retourner un échec;
                  FIN

      Nom appelé absent :
         COMMENCER
        /* le nom appelé n’existe pas sur le nœud distant */
      informer la procédure de découverte de nom de possibles erreurs ;

           SI c’est un nœud P ou M ALORS
        COMMENCER
           /* Informer le serveur de noms NetBIOS qu’il a retourné des informations incorrectes. */
          envoi d’une Demande de libération de nom pour le nom appelé et l’adresse IP au serveur de nom NetBIOS Server;
                    FIN
                   /* réessayer depuis le début */
                    reciblage = FAUX ;
                    name_query = VRAI ;
                    goto LOOP;
                  FIN /* le nom appelé est absent */
               FIN /* du cas */
             FIN /* réponse négative */

Réponse de reciblage de session :
             COMMENCER
               fermer la connexion TCP ;
               extraire l’adresse IP et l’accès TCP de la réponse ;
               reciblage = VRAI ;
             FIN /* de la réponse de reciblage */
          FIN /* du cas */

LOOP :          retry_count = retry_count + 1 ;

     JUSQU’à (retry_count > SSN_RETRY_COUNT) ;
     retourner un échec;
FIN /* de la procédure */

5.2.1.2	Traitement du paquet reçu

Ce sont des paquets reçus sur une connexion TCP avant l’établissement d’une session. Les routines d’écoute attachées à un processus d’utilisateur NetBIOS n’ont pas besoin de mettre en œuvre la section de réponse RETARGET (reciblage). La version de processus d’utilisateur, séparée d’un service de session partagé, a seulement besoin d’accepter (Réponse de session positive) ou rejeter (Réponse de session négative) une demande de session.

Procédure session_packet(packet)
/* processus initié par la réception d’un paquet de service de session pour une session 
* dans la phase d’établissement de session. On suppose que la connexion TCP a été acceptée. */
COMMENCER
     CAS du type de paquet
Demande de session :
        COMMENCER
          SI le nom appelé n’existe pas sur le nœud ALORS
          COMMENCER
               envoi d’une Réponse négative de session avec le code d’erreur Nom appelé absent;
               clore la connexion TCP ;
          FIN

          Recherche d’une écoute avec le Nom appelant ou le Nom appelé ;
          SI on trouve une correspondance d’écoute ALORS
          COMMENCER
              SI l’accès du processus écoutant est l’accès TCP la connexion est active ALORS
               COMMENCER
                    envoi d’une Réponse positive de session ;

                    Raccrocher la connexion au processus client et/ou informer l’usager que la session est établie ;
               FIN
               AUTREMENT
               COMMENCER
                    envoi d’une Réponse de reciblage de session avec l’adresse IP et l’accès TCP de celui qui écoute ;
                    clore la connexion TCP ;
               FIN
          FIN
          AUTREMENT
          COMMENCER
               /* pas d’écoute correspondante en cours */

              envoi d’une Réponse de session négative avec le code d’erreur Pas d’écoute sur le nom appelé ou
                   Pas d’écoute pour le nom appelant ;
                   clore la connexion TCP;
          FIN
        FIN /* de la demande de session */
     FIN /* du cas */
FIN /* de la procédure */

5.2.2	Protocoles de transfert de données de session

5.2.2.1	Traitement de la demande de l’utilisateur

Procédure send_message(user_message)
COMMENCER
     construire l’en-tête de Message de session ;
     envoi de l’en-tête de Message de session ;
     envoi de user_message ;
     remise à zéro et relance du temporisateur de maintien en vie ;
     SI l’envoi échoue ALORS
     COMMENCER
          /* la connexion TCP a échoué */
          clore la session NetBIOS ;
          informer l’usager de la perte de la session ;
          retourner un échec ;
     FIN
     AUTREMENT
          retourner une information de succès ;
FIN

5.2.2.2	Traitement du paquet reçu

Ce sont des paquets reçus après l’établissement d’une session.

Procédure session_packet(packet)
/* processus initié par la réception d’un paquet de service de session pour une session dans la phase de transfert des données. */
COMMENCER
     CAS du type de paquet de
Message de session :
        COMMENCER
          traiter l’en-tête de message ;
             lire les données d’utilisateur ;
             remettre à zéro et relancer le temporisateur de maintien en vie ;
             livrer les données à l’utilisateur ;
        FIN /* du message de session*/
Maintien en vie de session :
       éliminer le paquet ;
  FIN /* du cas */
FIN /* de la procédure */

5.2.2.3	Traitement initié par un temporisateur

Procédure session_ka_timer()
/* traitement initié à l’expiration du temporisateur de maintien en vie de session */
COMMENCER
         envoi du Maintien en vie de session, s’il est configuré ;
         SI l’envoi échoue ALORS
         COMMENCER
          /* Le nœud distant, ou le chemin qui y mène, est en panne */
          interrompre la connexion TCP ;
          clore la session NetBIOS ;
          informer l’usager de la perte de la session ;
          retourner ;
         FIN
FIN /* de la procédure */

5.2.3	Protocoles de terminaison de session

5.2.3.1	Traitement de la demande de l’utilisateur

Procédure close_session()

/* initiée par la demande d’usager de clore une session */

COMMENCER
        clore volontairement la connexion TCP ;        attendre la clôture de la connexion ou l’expiration de SSN_CLOSE_TIMEOUT ;
        SI la temporisation est expirée ALORS
             interrompre la connexion TCP ;
FIN /* de la procédure */

5.2.3.2	Traitement de l’indication de réception

Procédure close_indication()
/* initiée par une indication TCP d’une demande de clôture de la part du partenaire distant de la connexion. */
COMMENCER
     clore volontairement la connexion TCP ;     clore la session NetBIOS ;
     informer l’usager de la clôture de la session par le partenaire distant ;
FIN /* de la procédure */

5.3	Protocoles du service de datagrammes NetBIOS

Les variables ci-après sont mondiales et ne devraient pas être configurables par l’usager NetBIOS :

- SCOPE_ID : la section non terminale du nom de domaine, précédée par un '.' qui représente le domaine d’application NetBIOS pour le nom NetBIOS. La description de protocole suivante ne prend en charge le fonctionnement que d’un seul domaine d’application.

- MAX_DATAGRAM_LENGTH : longueur maximale d’un datagramme IP. La longueur maximum minimale définie pour IP est de 576 octets. Cette valeur est utilisée lors de la détermination de la nécessité de fragmenter un datagramme NetBIOS. Les mises en œuvre sont supposées capables de recevoir des datagramme NetBIOS non fragmentés jusqu’à leur taille maximale.

- BROADCAST_ADDRESS : adresse IP des nœuds B utilisée pour envoyer des datagrammes avec des destinations de nom de groupe et des datagrammes en diffusion. La valeur par défaut est l’adresse de diffusion IP pour un seul réseau IP.

Les constantes définies pour le service de datagrammes NetBIOS sont données ci-après :

- DGM_SRVC_UDP_PORT : l’accès UDP bien connu mondialement sur lequel le service de datagrammes NetBIOS reçoit les paquets UDP. Voir sa valeur à la section 6, "Constantes définies".

5.3.1	Transmission de datagrammes NetBIOS par le nœud B

Procédure send_datagram(données, source, destination, diffusion)
/* traitement initié par l’usager sur le nœud B */

COMMENCER
     groupe = FAUX ;
     faire une découverte de nom sur le nom de destination, retourne le type de nom et l’adresse IP ;
     SI le type de nom est un nom de groupe ALORS
     COMMENCER
          groupe = VRAI ;
     FIN

     /* construire le paquet de service de datagramme UDP ; */
     convertir les noms de source et destination NetBIOS en noms codés en semi-ASCII avec biais ;
     SOURCE_NAME = cat(source, SCOPE_ID) ;
     SOURCE_IP = l’adresse IP de ces nœuds ;
     SOURCE_PORT =  DGM_SRVC_UDP_PORT ;

     SI diffusion NetBIOS ALORS
     COMMENCER
          DESTINATION_NAME = cat("*", SCOPE_ID)
     FIN
     AUTREMENT
     COMMENCER
          DESTINATION_NAME = cat(destination, SCOPE_ID)
     FIN

     MSG_TYPE = select_one_from_set
          {BROADCAST, DIRECT_UNIQUE, DIRECT_GROUP}
     DGM_ID = nouvel identifiant de transaction pour les datagrammes ;
     DGM_LENGTH = longueur des données + longueur des noms de source et destination codés en second niveau ;

     SI (longueur du datagramme NetBIOS, incluant les en-têtes UDP et IP, > MAX_DATAGRAM_LENGTH) ALORS
     COMMENCER
          /* fragmenter le datagramme NetBIOS en deux paquets UDP */
          Mettre les noms dans le premier paquet UDP et toutes les données qui vont après les noms ;
          Mettre les bits MORE et FIRST à 1 dans le champ Fanions du premier paquet UDP ;
          OFFSET dans le premier paquet UDP = 0 ;
          Dupliquer l’en-tête de datagramme NetBIOS du premier paquet UDP au second paquet UDP ;
          Mettre le reste des données dans le second paquet UDP ;
          Mettre à zéro les bits MORE et FIRST dans le champ Fanions du second paquet UDP ;
          OFFSET du 2ème paquet UDP = DGM_LENGTH - nombre des octets de nom et de données du 1er paquet UDP ;
     FIN
     COMMENCER
          /* Il y a seulement besoin d’un paquet UDP */

          USER_DATA = données ;
          Mettre le bit MORE à zéro et le bit FIRST à un dans Fanions ;
          OFFSET = 0 ;
     FIN

     SI (groupe == VRAI) OU (diffusion NetBIOS) ALORS
     COMMENCER
          envoi de paquets UDP à BROADCAST_ADDRESS ;
     FIN
     AUTREMENT
     COMMENCER
          envoi de paquets UDP à l’adresse IP retournée par la découverte de nom ;
     FIN
FIN /* de la procédure */

5.3.2	Transmission de datagrammes NetBIOS par les nœuds P et M

Procédure send_datagram(données, source, destination, diffusion)

/* Traitement initié par l’utilisateur sur les nœuds P et M.
* Ce traitement est le même que pour les nœuds B sauf pour l’envoi des datagrammes NetBIOS en diffusion et en diffusion groupée. */

COMMENCER
     groupe = FAUX ;
        faire la découverte de nom sur le nom de destination, retourne le type de nom et l’adresse IP ;
        SI le type de nom est un nom de groupe ALORS
        COMMENCER
             groupe = VRAI ;
        FIN

        /* construire le paquet UDP de service de datagramme ; */
        convertir les noms de source et destination NetBIOS en noms codés en semi-ASCII avec biais ;
        SOURCE_NAME = cat(source, SCOPE_ID);
        SOURCE_IP = adresse IP de ce nœud ;
        SOURCE_PORT =  DGM_SRVC_UDP_PORT;

        SI c’est de la diffusion NetBIOS ALORS
        COMMENCER
             DESTINATION_NAME = cat("*", SCOPE_ID)
        FIN
        AUTREMENT
        COMMENCER
             DESTINATION_NAME = cat(destination, SCOPE_ID)
        FIN

        MSG_TYPE = select_one_from_set
             {BROADCAST, DIRECT_UNIQUE, DIRECT_GROUP}
        DGM_ID = nouvel identifiant de transaction pour les datagrammes ;
        DGM_LENGTH = longueur des données + longueur des noms de source et destination codés au second niveau ;

        SI (longueur de datagramme NetBIOS, incluant les en-têtes UDP et IP, > MAX_DATAGRAM_LENGTH) ALORS
        COMMENCER
             /*
              * fragmenter le datagramme NetBIOS en deux paquets UDP 
              */
             Mettre les noms dans le premier paquet UDP et toutes les données qui vont après les noms ;
             Mettre les bits MORE et FIRST à 1 dans le champ Fanions du premier paquet UDP ;
             OFFSET dans le premier paquet UDP = 0 ;
             Dupliquer l’en-tête de datagramme NetBIOS du premier paquet UDP au second paquet UDP ;
             Mettre le reste des données dans le second paquet UDP ;
             Mettre à zéro les bits MORE et FIRST dans le champ Fanions du second paquet UDP ;
             OFFSET du 2ème paquet UDP = DGM_LENGTH - nombre des octets de nom et de données du 1er paquet UDP ;
        FIN
        COMMENCER
             /*
              * Il y a seulement besoin d’un paquet UDP
              */
             USER_DATA = données ;
             Mettre le bit MORE à zéro et le bit FIRST à un dans le champ Fanions ;
             OFFSET = 0 ;
        FIN

        SI (groupe == VRAI) OU (diffusion NetBIOS) ALORS
        COMMENCER
             /*
              * L’envoi du questionnaire suivant est facultatif.
              * Le nœud peut envoyer immédiatement le datagramme au NBDD mais le NBDD peut éliminer le datagramme.
              */
             envoi de la Demande d’interrogation de datagramme au NBDD ;
             SI la réponse est Réponse positive d’interrogation ALORS
                  envoi du ou des paquets à l’adresse IP du serveur NBDD ;
             AUTREMENT
             COMMENCER
                  obtenir la liste des nœuds de destination de la part du NBNS ;

               POUR CHAQUE nœud de la liste
               COMMENCER
                    envoi du ou des paquets UDP à l’adresse IP de ce nœud ;
               FIN
          FIN
     FIN
     AUTREMENT
     COMMENCER
          envoi du ou des paquets UDP à l’adresse IP retournée par la découverte de nom ;
FIN /* de la procédure */

5.3.3	Réception des datagrammes NetBIOS par tous les nœuds

L’algorithme qui suit élimine les fragments de datagramme NetBIOS qui ne sont pas à leur place. Une mise en œuvre qui réassemble les fragments de datagramme NetBIOS déclassés est conforme à la présente spécification. Le temporisateur d’élimination de fragment est initialisé à la valeur FRAGMENT_TO. Cette valeur devrait être configurable par l’utilisateur. La valeur par défaut est donnée à la Section 6, "Constantes et variables définies".

Procédure datagram_packet(packet)
/* traitement initié par la réception de paquet de datagramme sur les nœuds B, P et M */
COMMENCER
  /* si ce nœud est un nœud P, ignorer les paquets en diffusion. */

  SI c’est un nœud P ET si le paquet entrant est un paquet en diffusion ALORS
  COMMENCER
       éliminer le paquet ;
  FIN

  CAS du type de paquet de
        Service de datagrammes :
        COMMENCER
          SI le bit FIRST du champ Fanions est mis à un ALORS
          COMMENCER
            SI le bit MORE du champ Fanions est mis à un ALORS
            COMMENCER
                    Sauvegarder le premier paquet UDP du datagramme ;
                    Régler le temporisateur d’élimination de fragment de ce datagramme à FRAGMENT_TO ;
                    retourner ;
               FIN
               AUTREMENT
                    Le datagramme se compose d’un seul paquet UDP ;
          FIN
          AUTREMENT
          COMMENCER
               /* Avoir le second fragment d’un datagramme */

               Recherche du premier fragment par l’adresse IP de source et le DGM_ID ;
               SI le premier fragment est trouvé ALORS
                    Traiter les deux paquets UDP ;
               AUTREMENT
               COMMENCER
                    éliminer le paquet UDP de second fragment ;
                    retourner ;
               FIN
          FIN

          SI DESTINATION_NAME est '*' ALORS
          COMMENCER
               /* diffusion NetBIOS */
               livrer USER_DATA provenant du ou des paquets UDP à toutes les demandes de datagramme en diffusion reçues en instance ;
               retourner ;
          FIN
          AUTREMENT
          COMMENCER /* non diffusion */
               /* Datagramme pour un nom unique ou de groupe */
              SI DESTINATION_NAME n’est pas présent dans le tableau local des noms ALORS
               COMMENCER
                    /* destination non présente */
                    construire le paquet Erreur de datagramme, mettre les bits FIRST et MORE à zéro, 
                         mettre cela dans l’adresse IP et l’accès de ces nœuds, mettre ERROR_CODE à un;
                    envoi du paquet Erreur de datagramme à l’adresse IP de source et l’accès UDP ;
                    éliminer le ou les paquets UDP ;
                    retourner ;
               FIN
               AUTREMENT
               COMMENCER /* c’est bon */
                    /* Dupliquer le datagramme NetBIOS reçu pour chaque receveur */
                    POUR CHAQUE opération de datagramme d’utilisateur NetBIOS reçue
                    COMMENCER
                         SI le nom de source de l’opération correspond au nom de destination du paquet ALORS
                         COMMENCER
                            livrer les USER_DATA provenant du ou des paquets UDP ;
                         FIN
                    FIN /* pour tous */
                    retourner ;
               FIN /* c’est bon */
          FIN /* de non diffusion */
         FIN /* du service de datagrammes */

Erreur de datagramme :
        COMMENCER
             /* le service de noms a retourné des informations incorrectes */
             informer le service de noms local que des informations incorrectes ont été fournies ;
            SI c’est un nœud P ou M ALORS
             COMMENCER
                 /* dire au serveur de nom NetBIOS qu’il pourrait avoir donné des informations incorrectes */
                envoi d’une Demande de libération de nom avec le nom et l’adresse IP incorrecte au serveur de nom NetBIOS ;
             FIN
        FIN /* erreur de datagramme */
     FIN /* fin du cas */
FIN

5.3.4	Protocoles pour le NBDD

La clé du service de retransmission de datagrammes NetBIOS est que le paquet livré au nœud d’extrémité de destination doit avoir le même en-tête NetBIOS que si le nœud d’extrémité de source avait envoyé le paquet directement au nœud d’extrémité de destination. Par conséquent, le NBDD ne réassemble pas les datagrammes NetBIOS. Il retransmet le paquet UDP comme il est.

Procédure datagram_packet(packet)
/* traitement initié par un paquet entrant du service de datagrammes sur un nœud NBDD. */

COMMENCER
     CAS du type de paquet de
Service de datagrammes :
     COMMENCER
         SI le paquet a été envoyé comme datagramme NetBIOS dirigé ALORS
          COMMENCER
            /* fournir le service de transmission de groupe *
             * Transmettre le datagramme à chaque membre du groupe. La transmission peut être via :
             * 1) obtenir la liste des membres et envoyer à chacun le paquet Service de datagramme en envoi individuel
             * 2) utiliser la diffusion groupée si elle est disponible
             * 3) une combinaison de 1) et 2) */
            ...
          FIN

             AUTREMENT
             COMMENCER
               /* fournir le service de transmission en diffusion *
                * Transmettre le datagramme à chaque nœud du domaine d’application NetBIOS. Peut être via :
                * 1) obtenir la liste des membre du groupe et envoyer en individuel à chacun le paquet service de datagramme
                * 2) utiliser la diffusion groupée si elle est disponible
                * 3) combinaison de 1) et 2) */
               ...
             FIN
        FIN /* du service de datagrammes */

Erreur de datagramme :
   COMMENCER
/* Ceci ne devrait jamais être reçu parce que les datagrammes transmis ont l’adresse IP et l’accès du nœud d’extrémité de source dans l’en-tête NetBIOS. */
       envoi d’une Demande de suppression de nom avec un nom et une adresse IP incorrecte au serveur de nom NetBIOS ;
       FIN /* de l’erreur de datagramme */

Demande d’interrogation de datagramme :
    COMMENCER
      SI on peut envoyer le paquet à DESTINATION_NAME ALORS
          COMMENCER
               /* Le NBDD est capable de relayer les datagrammes pour ce nom */
               envoi d’une Réponse positive d’interrogation de datagramme à l’adresse IP et à l’accès UDP de source de la demande avec le DGM_ID de la demande ;
          FIN
          AUTREMENT
          COMMENCER
               /* Le NBDD N’EST PAS capable de relayer les datagrammes pour ce nom */
               envoi d’une Réponse négative d’interrogation de datagramme à l’adresse IP et à l’accès UDP de source de la Demande avec le DGM_ID de la demande ;
          FIN
        FIN /* de la demande d’interrogation de datagramme */
     FIN /* du cas */
FIN /* de la procédure */

6.	Définition des constantes et des variables

Générales :

SCOPE_ID	Nom du domaine d’application NetBIOS.
C’est exprimé par une chaîne de caractères satisfaisant aux exigences du système de nom de domaine et sans "point" devant ou derrière.
Une mise en œuvre peut choisir d’en faire une seule valeur globale pour le nœud ou de lui permettre d’être spécifié avec chaque nom NetBIOS séparé (permettant ainsi des références de domaine d’application croisées.)

BROADCAST_ADDRESS	Adresse IP composée de numéros de réseau et de sous-réseau du nœud avec les bites restants réglés à un. C’est-à-dire l’adressage de diffusion "spécifique de sous réseau" conformément au paragraphe 2.3 de la RFC 950.

BCAST_REQ_RETRY_TIMEOUT	250 millisecondes. Un temporisateur adaptatif peut être utilisé.

BCAST_REQ_RETRY_COUNT	3

UCAST_REQ_RETRY_TIMEOUT	5 secondes. Un temporisateur adaptatif peut être utilisé.

UCAST_REQ_RETRY_COUNT	3

MAX_DATAGRAM_LENGTH	576 octets (par défaut)

Service de noms :

REFRESH_TIMER	Négocié avec le NBNS pour chaque nom.

CONFLICT_TIMER	1 seconde. Les mises en œuvre peuvent choisir une valeur plus longue.

NAME_SERVICE_TCP_PORT	137 (décimal)

NAME_SERVICE_UDP_PORT	137 (décimal)

INFINITE_TTL	0

Service de session :

SSN_SRVC_TCP_PORT	139 (décimal)

SSN_RETRY_COUNT	4 (par défaut). Reconfigurable par l’usager.

SSN_CLOSE_TIMEOUT	30 secondes (par défaut). Reconfigurable par l’usager.

SSN_KEEP_ALIVE_TIMEOUT	60 secondes, recommandé, peut être réglé à une valeur plus élevée.
	Les maintien-en-vie de session ne sont utilisés que s’ils sont configurés.)

Service de datagramme :

DGM_SRVC_UDP_PORT	138 (décimal)
FRAGMENT_TO	2 secondes (par défaut)

Références

[1]	"Protocole standard pour un service NetBIOS sur un transport TCP/UDP : concepts et méthodes", RFC 1001, mars 1987.

[2]	J. Reynolds, J. Postel, "Numéros alloués", RFC 990, novembre 1986. (Historique, voir www.iana.org/numbers)

[3]	P. Mockapetris, "Noms de domaines – Mise en œuvre et spécification", RFC 883, novembre 1983 (Rendue obsolète par la RFC 1034/1035, STD 13).