
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://livre.g6.asso.fr/index.php?action=history&amp;feed=atom&amp;title=L%27exemple_%C2%AB_mini-ping_%C2%BB_revisit%C3%A9</id>
		<title>L'exemple « mini-ping » revisité - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://livre.g6.asso.fr/index.php?action=history&amp;feed=atom&amp;title=L%27exemple_%C2%AB_mini-ping_%C2%BB_revisit%C3%A9"/>
		<link rel="alternate" type="text/html" href="http://livre.g6.asso.fr/index.php?title=L%27exemple_%C2%AB_mini-ping_%C2%BB_revisit%C3%A9&amp;action=history"/>
		<updated>2026-05-25T07:18:59Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.25.2</generator>

	<entry>
		<id>http://livre.g6.asso.fr/index.php?title=L%27exemple_%C2%AB_mini-ping_%C2%BB_revisit%C3%A9&amp;diff=2963&amp;oldid=prev</id>
		<title>Bruno Deniaud at 12:52, 27 February 2006</title>
		<link rel="alternate" type="text/html" href="http://livre.g6.asso.fr/index.php?title=L%27exemple_%C2%AB_mini-ping_%C2%BB_revisit%C3%A9&amp;diff=2963&amp;oldid=prev"/>
				<updated>2006-02-27T12:52:49Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;tr style='vertical-align: top;'&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Revision as of 12:52, 27 February 2006&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;L1&quot; &gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{{suivi| L'implémentation | L'implémentation | Supervision | Supervision }}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Le programme &amp;lt;tt&amp;gt;one_ping6.c&amp;lt;/tt&amp;gt; va être repris afin de lui ajouter deux fonctionnalités dont l'implémentation s'appuiera sur l'usage de données auxiliaires. On souhaite d'une part afficher le nombre de sauts (''hop limit'') du paquet ECHO_REPLY (éventuellement) reçu et d'autre part de permettre, à l'instar de la commande &amp;lt;tt&amp;gt;ping6&amp;lt;/tt&amp;gt;, de passer une liste de relais par lesquels le paquet ECHO_REQUEST devra transiter avant d'être envoyé à l'hôte destinataire (routage par la source).&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Le programme &amp;lt;tt&amp;gt;one_ping6.c&amp;lt;/tt&amp;gt; va être repris afin de lui ajouter deux fonctionnalités dont l'implémentation s'appuiera sur l'usage de données auxiliaires. On souhaite d'une part afficher le nombre de sauts (''hop limit'') du paquet ECHO_REPLY (éventuellement) reçu et d'autre part de permettre, à l'instar de la commande &amp;lt;tt&amp;gt;ping6&amp;lt;/tt&amp;gt;, de passer une liste de relais par lesquels le paquet ECHO_REQUEST devra transiter avant d'être envoyé à l'hôte destinataire (routage par la source).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;L214&quot; &gt;Line 214:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 215:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;D'autre part, les fonctions &amp;lt;tt&amp;gt;inet6_rth_xxx&amp;lt;/tt&amp;gt;, définies dans le RFC 3542 sont encore souvent absentes de la librairie système (c'est le cas pour Solaris 9, FreeBSD4.x, NetBSD1.x, et Linux). Le lecteur peut les remplacer par un codage à la main, ou récupérer leur texte, par exemple dans la distribution KAME.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;D'autre part, les fonctions &amp;lt;tt&amp;gt;inet6_rth_xxx&amp;lt;/tt&amp;gt;, définies dans le RFC 3542 sont encore souvent absentes de la librairie système (c'est le cas pour Solaris 9, FreeBSD4.x, NetBSD1.x, et Linux). Le lecteur peut les remplacer par un codage à la main, ou récupérer leur texte, par exemple dans la distribution KAME.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;#160;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{{suivi| L'implémentation | L'implémentation | Supervision | Supervision }}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Bruno Deniaud</name></author>	</entry>

	<entry>
		<id>http://livre.g6.asso.fr/index.php?title=L%27exemple_%C2%AB_mini-ping_%C2%BB_revisit%C3%A9&amp;diff=2359&amp;oldid=prev</id>
		<title>Laurent Toutain at 07:04, 20 December 2005</title>
		<link rel="alternate" type="text/html" href="http://livre.g6.asso.fr/index.php?title=L%27exemple_%C2%AB_mini-ping_%C2%BB_revisit%C3%A9&amp;diff=2359&amp;oldid=prev"/>
				<updated>2005-12-20T07:04:40Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;http://livre.g6.asso.fr/index.php?title=L%27exemple_%C2%AB_mini-ping_%C2%BB_revisit%C3%A9&amp;amp;diff=2359&amp;amp;oldid=2358&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Laurent Toutain</name></author>	</entry>

	<entry>
		<id>http://livre.g6.asso.fr/index.php?title=L%27exemple_%C2%AB_mini-ping_%C2%BB_revisit%C3%A9&amp;diff=2358&amp;oldid=prev</id>
		<title>Laurent Toutain at 06:49, 20 December 2005</title>
		<link rel="alternate" type="text/html" href="http://livre.g6.asso.fr/index.php?title=L%27exemple_%C2%AB_mini-ping_%C2%BB_revisit%C3%A9&amp;diff=2358&amp;oldid=prev"/>
				<updated>2005-12-20T06:49:22Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;tr style='vertical-align: top;'&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Revision as of 06:49, 20 December 2005&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;L203&quot; &gt;Line 203:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 203:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#160; $ '''xapi_ping6 www.kame.net relais.imag.fr ipv6.imag.fr'''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;#160; $ '''xapi_ping6 www.kame.net relais.imag.fr ipv6.imag.fr'''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;la donnée auxiliaire sera maintenant comme représentée à la figure Adjonction des deux relais dans l'en-tête de routage, (avec les mêmes hypothèses sur l'architecture et l'alignement). Le message ainsi construit est expédié tout en gérant les erreurs &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;éventuelles54&lt;/del&gt;.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;la donnée auxiliaire sera maintenant comme représentée à la figure Adjonction des deux relais dans l'en-tête de routage, (avec les mêmes hypothèses sur l'architecture et l'alignement). Le message ainsi construit est expédié tout en gérant les erreurs &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;éventuelles (nous laissons le soin au lecteur l'adaptation de la fonction main afin de prendre en compte les nouveaux arguments (optionnels) du programme one_ping6)&lt;/ins&gt;.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[image:CS198.gif]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[image:CS198.gif]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;On remarque que la donnée auxiliaire contient les adresses des relais intermédiaires, alors que dans un paquet IPv6, [[Les extensions#routage|l'en-tête de routage]] contient les adresses à partir du deuxième relais et l'adresse destination finale, l'adresse du premier relais étant dans l'en-tête IPv6. Le noyau lors du sendmsg va permuter les adresses pour rétablir l'ordre correct.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;On remarque que la donnée auxiliaire contient les adresses des relais intermédiaires, alors que dans un paquet IPv6, [[Les extensions#routage|l'en-tête de routage]] contient les adresses à partir du deuxième relais et l'adresse destination finale, l'adresse du premier relais étant dans l'en-tête IPv6. Le noyau lors du &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;tt&amp;gt;&lt;/ins&gt;sendmsg&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/tt&amp;gt; &lt;/ins&gt;va permuter les adresses pour rétablir l'ordre correct.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===Portabilité du code===&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===Portabilité du code===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Laurent Toutain</name></author>	</entry>

	<entry>
		<id>http://livre.g6.asso.fr/index.php?title=L%27exemple_%C2%AB_mini-ping_%C2%BB_revisit%C3%A9&amp;diff=2357&amp;oldid=prev</id>
		<title>Laurent Toutain at 06:47, 20 December 2005</title>
		<link rel="alternate" type="text/html" href="http://livre.g6.asso.fr/index.php?title=L%27exemple_%C2%AB_mini-ping_%C2%BB_revisit%C3%A9&amp;diff=2357&amp;oldid=prev"/>
				<updated>2005-12-20T06:47:50Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;tr style='vertical-align: top;'&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Revision as of 06:47, 20 December 2005&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;L207&quot; &gt;Line 207:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 207:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[image:CS198.gif]]&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[image:CS198.gif]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;On remarque que la donnée auxiliaire contient les adresses des relais intermédiaires, alors que dans un paquet IPv6, l'en-tête de routage &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;(voir [[Routage&lt;/del&gt;]]&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;) &lt;/del&gt;contient les adresses à partir du deuxième relais et l'adresse destination finale, l'adresse du premier relais étant dans l'en-tête IPv6. Le noyau lors du sendmsg va permuter les adresses pour rétablir l'ordre correct.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;On remarque que la donnée auxiliaire contient les adresses des relais intermédiaires, alors que dans un paquet IPv6, &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;[[Les extensions#routage|&lt;/ins&gt;l'en-tête de routage]] contient les adresses à partir du deuxième relais et l'adresse destination finale, l'adresse du premier relais étant dans l'en-tête IPv6. Le noyau lors du sendmsg va permuter les adresses pour rétablir l'ordre correct.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===Portabilité du code===&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;===Portabilité du code===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Laurent Toutain</name></author>	</entry>

	<entry>
		<id>http://livre.g6.asso.fr/index.php?title=L%27exemple_%C2%AB_mini-ping_%C2%BB_revisit%C3%A9&amp;diff=2354&amp;oldid=prev</id>
		<title>Laurent Toutain at 06:44, 20 December 2005</title>
		<link rel="alternate" type="text/html" href="http://livre.g6.asso.fr/index.php?title=L%27exemple_%C2%AB_mini-ping_%C2%BB_revisit%C3%A9&amp;diff=2354&amp;oldid=prev"/>
				<updated>2005-12-20T06:44:39Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Le programme &amp;lt;tt&amp;gt;one_ping6.c&amp;lt;/tt&amp;gt; va être repris afin de lui ajouter deux fonctionnalités dont l'implémentation s'appuiera sur l'usage de données auxiliaires. On souhaite d'une part afficher le nombre de sauts (''hop limit'') du paquet ECHO_REPLY (éventuellement) reçu et d'autre part de permettre, à l'instar de la commande &amp;lt;tt&amp;gt;ping6&amp;lt;/tt&amp;gt;, de passer une liste de relais par lesquels le paquet ECHO_REQUEST devra transiter avant d'être envoyé à l'hôte destinataire (routage par la source).&lt;br /&gt;
&lt;br /&gt;
Par exemple, pour envoyer un paquet ECHO_REQUEST à la machine &amp;lt;tt&amp;gt;ipv6.imag.fr&amp;lt;/tt&amp;gt; tout en transitant tout d'abord par les machines &amp;lt;tt&amp;gt;www.kame.net&amp;lt;/tt&amp;gt; et &amp;lt;tt&amp;gt;relai.imag.fr&amp;lt;/tt&amp;gt;, la commande &amp;lt;tt&amp;gt;xapi_ping6&amp;lt;/tt&amp;gt; sera :&lt;br /&gt;
&lt;br /&gt;
 $ '''xapi_ping6 www.kame.net relais.imag.fr ipv6.imag.fr'''&lt;br /&gt;
 Sending ECHO REQUEST to: ipv6.imag.fr via:&lt;br /&gt;
 www.kame.net&lt;br /&gt;
 relais.imag.fr&lt;br /&gt;
 Waiting for answer (timeout = 5s)...&lt;br /&gt;
 Got answer from 2001:660:9510:25::632 (seq = 0, hoplimit = 241)&lt;br /&gt;
&lt;br /&gt;
L'affichage du nombre de sauts a déjà été en grande partie traité dans l'exemple du paragraphe consacré à l'implémentation de l'API avancée. Nous indiquerons donc seulement les changements significatifs par rapport à la version originale. Ces changements concernent essentiellement la routine &amp;lt;tt&amp;gt;wait_for_echo_reply6&amp;lt;/tt&amp;gt;. La première tâche à effectuer est, comme dans l'exemple précédent, de positionner l'option &amp;lt;tt&amp;gt;IPV6_RECVHOPLIMIT&amp;lt;/tt&amp;gt;, juste après avoir mis en place le filtrage ICMPv6. L'instruction :&lt;br /&gt;
&lt;br /&gt;
 noc = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) from, &amp;amp;from_len);&lt;br /&gt;
&lt;br /&gt;
est remplacée par la nouvelle instruction :&lt;br /&gt;
&lt;br /&gt;
 noc = recv_data(sock, buf, sizeof(buf), 0, (struct sockaddr *) from, &amp;amp;from_len, &amp;amp;hoplimit);&lt;br /&gt;
&lt;br /&gt;
où &amp;lt;tt&amp;gt;hoplimit&amp;lt;/tt&amp;gt; est un entier qui a été précédemment déclaré dans le corps de la fonction &amp;lt;tt&amp;gt;wait_for_echo_reply6&amp;lt;/tt&amp;gt; et &amp;lt;tt&amp;gt;recv_data&amp;lt;/tt&amp;gt; a pour texte :&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 #ifdef sun /* For Solaris */&lt;br /&gt;
 #define _XOPEN_SOURCE 500 /* correct recvmsg/sendmsg/msg/CMSG_xx syntax */&lt;br /&gt;
 #define __EXTENSIONS__&lt;br /&gt;
 #endif&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;sys/uio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;netinet/in.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;netinet/ip6.h&amp;gt;&lt;br /&gt;
 #ifndef CMSG_SPACE /* Solaris &amp;lt;= 9 */&lt;br /&gt;
 #define CMSG_SPACE(l) ((size_t)_CMSG_HDR_ALIGN(sizeof (struct cmsghdr) + (l)))&lt;br /&gt;
 #define CMSG_LEN(l) ((size_t)_CMSG_DATA_ALIGN(sizeof (struct cmsghdr)) + (l))&lt;br /&gt;
 #endif&lt;br /&gt;
  &lt;br /&gt;
 int recv_data(int sock, void *buf, int len, unsigned int flags,&lt;br /&gt;
               struct sockaddr *from, socklen_t *fromlen, int *hoplimit)&lt;br /&gt;
 {&lt;br /&gt;
 int ret, found = 0, cmsgspace = CMSG_SPACE(sizeof(int));&lt;br /&gt;
 struct iovec iov = {buf, len};&lt;br /&gt;
 struct cmsghdr *cmsg = (struct cmsghdr *) malloc(cmsgspace), *ptr;&lt;br /&gt;
 struct msghdr msg = {&lt;br /&gt;
    (caddr_t) from, *fromlen, &amp;amp;iov, 1,&lt;br /&gt;
    (caddr_t) cmsg, cmsgspace&lt;br /&gt;
 };&lt;br /&gt;
  &lt;br /&gt;
 if (cmsg == NULL) {&lt;br /&gt;
    perror(&amp;quot;recv_data: malloc&amp;quot;);&lt;br /&gt;
    return -1;&lt;br /&gt;
 }&lt;br /&gt;
 ret = recvmsg(sock, &amp;amp;msg, flags);&lt;br /&gt;
 if (ret &amp;lt; 0) {&lt;br /&gt;
    perror(&amp;quot;recv_data: recvmsg&amp;quot;);&lt;br /&gt;
    goto done;&lt;br /&gt;
 }&lt;br /&gt;
 if (msg.msg_flags &amp;amp; MSG_TRUNC) {&lt;br /&gt;
    fprintf(stderr, &amp;quot;recv_data: recvmsg: data discarded before delivery\n&amp;quot;);&lt;br /&gt;
    goto bad;&lt;br /&gt;
 }&lt;br /&gt;
 if (msg.msg_flags &amp;amp; MSG_CTRUNC) {&lt;br /&gt;
    fprintf(stderr,&lt;br /&gt;
            &amp;quot;recv_data: recvmsg: control data lost before delivery\n&amp;quot;);&lt;br /&gt;
    goto bad;&lt;br /&gt;
 }&lt;br /&gt;
 if (msg.msg_controllen)&lt;br /&gt;
    for (ptr = CMSG_FIRSTHDR(&amp;amp;msg); ptr; ptr = CMSG_NXTHDR(&amp;amp;msg, ptr)) {&lt;br /&gt;
       if (ptr-&amp;gt;cmsg_level==IPPROTO_IPV6 &amp;amp;&amp;amp; ptr-&amp;gt;cmsg_type==IPV6_HOPLIMIT) {&lt;br /&gt;
          if (ptr-&amp;gt;cmsg_len != CMSG_LEN(sizeof(int))) {&lt;br /&gt;
             fprintf(stderr,&lt;br /&gt;
                     &amp;quot;recvmsg: ancillary data with invalid length\n&amp;quot;);&lt;br /&gt;
             goto bad;&lt;br /&gt;
          }&lt;br /&gt;
          *hoplimit = *((int *) CMSG_DATA(ptr));&lt;br /&gt;
          goto done;&lt;br /&gt;
       }&lt;br /&gt;
    }&lt;br /&gt;
    fprintf(stderr,&lt;br /&gt;
            &amp;quot;recv_data: recvmsg: hoplimit not found in ancillary data\n&amp;quot;);&lt;br /&gt;
  bad:&lt;br /&gt;
    ret = -1;&lt;br /&gt;
  done:&lt;br /&gt;
    free(cmsg);&lt;br /&gt;
    return ret;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Le code de la fonction &amp;lt;tt&amp;gt;recv_data&amp;lt;/tt&amp;gt; ne sera pas commenté car la réception du nombre de sauts via une donnée auxiliaire a été étudiée dans un précédent exemple, la seule différence étant que la gestion des erreurs est ici plus détaillée.&lt;br /&gt;
&lt;br /&gt;
Il faut enfin modifier trivialement le code de la routine &amp;lt;tt&amp;gt;recv_icmp_pkt&amp;lt;/tt&amp;gt; afin que celle-ci imprime le nombre de sauts du paquet ECHO_REPLY (éventuellement) reçu. Nous en laissons le soin au lecteur.&lt;br /&gt;
&lt;br /&gt;
Pour l'autre donnée auxiliaire (cette fois ci en émission), à savoir le routage par la source, il faut naturellement tout d'abord modifier la fonction &amp;lt;tt&amp;gt;send_echo_request6&amp;lt;/tt&amp;gt; et en premier lieu son prototype qui devient :&lt;br /&gt;
&lt;br /&gt;
 int send_echo_request6(int sock, struct sockaddr_in6 *dst, uint16_t id,&lt;br /&gt;
                        uint16_t seq, char *opt_data, int opt_data_size,&lt;br /&gt;
                        struct in6_addr *seg, int nseg)&lt;br /&gt;
&lt;br /&gt;
La routine &amp;lt;tt&amp;gt;send_echo_request6&amp;lt;/tt&amp;gt; modifié possède deux arguments supplémentaires ajoutés à la fin. Le premier de ces nouveaux arguments est un pointeur vers un tableau contenant les adresses IPv6 des relais par lesquels on souhaite effectuer le routage par la source. Le dernier argument est le nombre d'éléments de ce tableau, c'est-à-dire le nombre de relais.&lt;br /&gt;
&lt;br /&gt;
Il faut ensuite substituer dans le corps de la fonction &amp;lt;tt&amp;gt;send_echo_request6&amp;lt;/tt&amp;gt; l'instruction suivante :&lt;br /&gt;
&lt;br /&gt;
 noc = sendto(sock, (char *) icmp, icmp_pkt_size, 0, (struct sockaddr *) dst,&lt;br /&gt;
&lt;br /&gt;
par :&lt;br /&gt;
&lt;br /&gt;
 noc = send_data(sock, (void *) icmp, icmp_pkt_size, 0, &lt;br /&gt;
                 (struct sockaddr *) dst, sizeof(struct sockaddr_in6),&lt;br /&gt;
                 seg, nseg);&lt;br /&gt;
&lt;br /&gt;
Si la variable &amp;lt;tt&amp;gt;seg&amp;lt;/tt&amp;gt; est le pointeur &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;, la liste des relais est vide. On fait appel à la fonction &amp;lt;tt&amp;gt;send_data&amp;lt;/tt&amp;gt;, dont le code va être commenté en détails :&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 #ifdef sun /* For Solaris */&lt;br /&gt;
 #define _XOPEN_SOURCE 500 /* correct recvmsg/sendmsg/msg/CMSG_xx syntax */&lt;br /&gt;
 #define __EXTENSIONS__&lt;br /&gt;
 #endif&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;sys/uio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;sys/socket.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;netinet/in.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;netinet/ip6.h&amp;gt;&lt;br /&gt;
 #ifndef CMSG_SPACE /* Solaris &amp;lt;= 9 */&lt;br /&gt;
 #define CMSG_SPACE(l) ((size_t)_CMSG_HDR_ALIGN(sizeof (struct cmsghdr) + (l)))&lt;br /&gt;
 #define CMSG_LEN(l) ((size_t)_CMSG_DATA_ALIGN(sizeof (struct cmsghdr)) + (l))&lt;br /&gt;
 #endif&lt;br /&gt;
 #ifndef IPV6_RECVHOPLIMIT&lt;br /&gt;
 #define IPV6_RECVHOPLIMIT IPV6_HOPLIMIT&lt;br /&gt;
 #endif&lt;br /&gt;
  &lt;br /&gt;
 extern void * inet6_rth_init(); /* sometimes not in ip6.h */&lt;br /&gt;
 &lt;br /&gt;
 int send_data(int sock, void *buf, int len, unsigned int flags,&lt;br /&gt;
               struct sockaddr *to, socklen_t tolen,&lt;br /&gt;
               struct in6_addr *seg, int nseg)&lt;br /&gt;
 {&lt;br /&gt;
 int ret = -1, rthsp, cmsgspace;&lt;br /&gt;
 void *data;&lt;br /&gt;
 struct in6_addr *in6;&lt;br /&gt;
 struct iovec iov = {buf, len};&lt;br /&gt;
 struct cmsghdr *cmsg = NULL;&lt;br /&gt;
 struct msghdr msg = {&lt;br /&gt;
                     (caddr_t) to, tolen, &amp;amp;iov, 1,&lt;br /&gt;
                     NULL, 0, 0&lt;br /&gt;
                     };&lt;br /&gt;
  &lt;br /&gt;
    if (seg != NULL) {&lt;br /&gt;
       rthsp = inet6_rth_space(IPV6_RTHDR_TYPE_0, nseg);&lt;br /&gt;
       cmsgspace = CMSG_SPACE(rthsp);&lt;br /&gt;
       msg.msg_control = cmsg = (struct cmsghdr *) malloc(cmsgspace);&lt;br /&gt;
       if (cmsg == NULL) {&lt;br /&gt;
          perror(&amp;quot;recv_data: malloc&amp;quot;);&lt;br /&gt;
          goto bad;&lt;br /&gt;
       }&lt;br /&gt;
       cmsg-&amp;gt;cmsg_level = IPPROTO_IPV6;&lt;br /&gt;
       msg.msg_controllen = cmsg-&amp;gt;cmsg_len = CMSG_LEN(rthsp);&lt;br /&gt;
       cmsg-&amp;gt;cmsg_type = IPV6_RTHDR;&lt;br /&gt;
       data = CMSG_DATA(cmsg);&lt;br /&gt;
       data = (void *)inet6_rth_init(data, rthsp, IPV6_RTHDR_TYPE_0, nseg);&lt;br /&gt;
       if (!data) {&lt;br /&gt;
          fprintf(stderr, &amp;quot;send_data: inet6_rth_init failed\n&amp;quot;);&lt;br /&gt;
          goto bad;&lt;br /&gt;
       }&lt;br /&gt;
       for (in6 = seg; in6 - seg &amp;lt; nseg; in6++)&lt;br /&gt;
          if (inet6_rth_add(data, in6) == -1) {&lt;br /&gt;
             fprintf(stderr, &amp;quot;send_data: inet6_rth_add failed\n&amp;quot;);&lt;br /&gt;
             goto bad;&lt;br /&gt;
          }&lt;br /&gt;
    }&lt;br /&gt;
    ret = sendmsg(sock, &amp;amp;msg, flags);&lt;br /&gt;
    if (ret &amp;lt; 0) {&lt;br /&gt;
       perror(&amp;quot;send_data: sendmsg&amp;quot;);&lt;br /&gt;
       goto bad;&lt;br /&gt;
    }&lt;br /&gt;
 bad:&lt;br /&gt;
    if (cmsg)&lt;br /&gt;
    free(cmsg);&lt;br /&gt;
    return ret;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Les six premiers paramètres de la fonction &amp;lt;tt&amp;gt;send_data&amp;lt;/tt&amp;gt; sont identiques à ceux de la primitive système &amp;lt;tt&amp;gt;sendto&amp;lt;/tt&amp;gt;, les deux derniers étant quant à eux identiques aux deux derniers arguments de la routine &amp;lt;tt&amp;gt;send_echo_request6&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Si la liste de relais est vide, on appelle &amp;lt;tt&amp;gt;sendmsg&amp;lt;/tt&amp;gt; sans données auxiliaires (&amp;lt;tt&amp;gt;msg.msg_control&amp;lt;/tt&amp;gt; est nul). Sinon on alloue (ligne [[See]] ) un tampon pour contenir les données auxiliaires.&lt;br /&gt;
&lt;br /&gt;
La routine &amp;lt;tt&amp;gt;inet6_rth_space&amp;lt;/tt&amp;gt; est l'une des six nouvelles routines proposées par l'API avancée afin de faciliter la tâche du programmeur lors de la manipulation des en-têtes de routage. Elle prend en arguments le type de l'extension de routage (en l'occurrence la constante &amp;lt;tt&amp;gt;IPV6_RTHDR_TYPE_0&amp;lt;/tt&amp;gt; dont la valeur numérique est 0 est qui est définie dans &amp;lt;tt&amp;gt;&amp;lt;netinet/in.h&amp;gt;&amp;lt;/tt&amp;gt;) et le nombre de relais contenus dans cette extension (pour ce type d'extension, ce nombre doit être compris entre 0 et 127 inclus). Elle retourne la taille en octets nécessaire pour contenir cette en-tête de routage. Ici cette routine va permettre d'initialiser, via la variable &amp;lt;tt&amp;gt;rthsp&amp;lt;/tt&amp;gt; et à l'aide de la macro &amp;lt;tt&amp;gt;CMSG_SPACE&amp;lt;/tt&amp;gt;, la variable &amp;lt;tt&amp;gt;cmsgspace&amp;lt;/tt&amp;gt; à la taille en octets de la donnée auxiliaire associée à cette extension de routage.&lt;br /&gt;
&lt;br /&gt;
En lignes [[See à See]] , la longueur des données auxiliaires et la structure &amp;lt;tt&amp;gt;cmsg&amp;lt;/tt&amp;gt; sont initialisés au moyen de la macro &amp;lt;tt&amp;gt;CMSG_LEN&amp;lt;/tt&amp;gt; pour le champ &amp;lt;tt&amp;gt;cmsg_len&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Il faut maintenant initialiser les données transmises par la donnée auxiliaire avec l'en-tête routage (lignes [[See à See]] ). Nous allons nous servir de la routine &amp;lt;tt&amp;gt;inet6_rth_init&amp;lt;/tt&amp;gt; fournie par l'API avancée. Celle-ci prend en premier argument un pointeur vers la zone mémoire qui contiendra l'en-tête de routage, le deuxième argument étant la taille en octets de cette zone mémoire. Les deux derniers arguments sont identiques à ceux de la routine &amp;lt;tt&amp;gt;inet6_rth_space&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;inet6_rth_init&amp;lt;/tt&amp;gt; retourne un pointeur vers cette zone mémoire ou le pointeur &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt; si la taille de celle-ci est insuffisante.&lt;br /&gt;
&lt;br /&gt;
Après ces diverses initialisations, la donnée auxiliaire est représentée à la figure Initialisation de l'en-tête de routage où l'on a supposé, afin de fixer les idées, que l'on est en présence d'une architecture 32 bits et que l'alignement se fait sur 32 bits également (autrement dit il n'y a pas de bourrage entre la structure cmsg et le début des données transmises, cf. [[figure Structure des données auxiliaires]]).&lt;br /&gt;
&lt;br /&gt;
[[image:CS197.gif]]&lt;br /&gt;
&lt;br /&gt;
Dans la boucle qui suit (lignes [[See à See]] ), l'initialisation de l'en-tête de routage se termine en ajoutant successivement les adresses IPv6 des relais du routage par la source. Ces ajouts se font au moyen de la fonction inet6_rth_add qui prend en premier argument la zone mémoire contenant l'en-tête de routage et en deuxième argument un pointeur (de type &amp;lt;tt&amp;gt;struct in6_addr *&amp;lt;/tt&amp;gt;) vers l'adresse du relais à ajouter.&lt;br /&gt;
&lt;br /&gt;
A l'issue de cette boucle, si l'on reprend l'exemple qui nous a servi à présenter la nouvelle version de la commande one_ping6 :&lt;br /&gt;
&lt;br /&gt;
 $ '''xapi_ping6 www.kame.net relais.imag.fr ipv6.imag.fr'''&lt;br /&gt;
&lt;br /&gt;
la donnée auxiliaire sera maintenant comme représentée à la figure Adjonction des deux relais dans l'en-tête de routage, (avec les mêmes hypothèses sur l'architecture et l'alignement). Le message ainsi construit est expédié tout en gérant les erreurs éventuelles54.&lt;br /&gt;
&lt;br /&gt;
[[image:CS198.gif]]&lt;br /&gt;
&lt;br /&gt;
On remarque que la donnée auxiliaire contient les adresses des relais intermédiaires, alors que dans un paquet IPv6, l'en-tête de routage (voir [[Routage]]) contient les adresses à partir du deuxième relais et l'adresse destination finale, l'adresse du premier relais étant dans l'en-tête IPv6. Le noyau lors du sendmsg va permuter les adresses pour rétablir l'ordre correct.&lt;br /&gt;
&lt;br /&gt;
===Portabilité du code===&lt;br /&gt;
&lt;br /&gt;
Solaris définit des prototypes de &amp;lt;tt&amp;gt;sendmsg&amp;lt;/tt&amp;gt; et &amp;lt;tt&amp;gt;recvmsg&amp;lt;/tt&amp;gt; variables selon les modes de compilation. De plus, jusqu'à la version 9 incluse, il ne définit pas les macros &amp;lt;tt&amp;gt;CMSG_SPACE&amp;lt;/tt&amp;gt; et &amp;lt;tt&amp;gt;CMSG_LEN&amp;lt;/tt&amp;gt;. Les lignes [[See à See]] et [[See à See]] du programme [[(See )]] servent à éviter ces problèmes de compatibilité.&lt;br /&gt;
&lt;br /&gt;
D'autre part, les fonctions &amp;lt;tt&amp;gt;inet6_rth_xxx&amp;lt;/tt&amp;gt;, définies dans le RFC 3542 sont encore souvent absentes de la librairie système (c'est le cas pour Solaris 9, FreeBSD4.x, NetBSD1.x, et Linux). Le lecteur peut les remplacer par un codage à la main, ou récupérer leur texte, par exemple dans la distribution KAME.&lt;/div&gt;</summary>
		<author><name>Laurent Toutain</name></author>	</entry>

	</feed>