<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://blog.section9.be/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Section9</title>
  <link>http://blog.section9.be/</link>
  <atom:link href="http://blog.section9.be:82/feed/rss2" rel="self" type="application/rss+xml"/>
  <description></description>
  <language>fr</language>
  <pubDate>Mon, 24 Oct 2011 11:58:27 +0200</pubDate>
  <copyright></copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Wake Up SharePoint Sites on multiple Front Ends</title>
    <link>http://blog.section9.be/post/2009/09/02/Wake-Up-SharePoint-Sites-on-multiple-Front-Ends</link>
    <guid isPermaLink="false">urn:md5:cd8700627ba8f268e8852db01b0e7cca</guid>
    <pubDate>Wed, 02 Sep 2009 19:57:00 +0200</pubDate>
    <dc:creator>Mathieu</dc:creator>
        <category>Development</category>    
    <description>    So, you have multiple Front Ends behind a Load Balancer and you want to wake up
each front end to enable the content to be served as fast as possible. 
&lt;div&gt;Here is a small architecture with 3 Front Ends (click to zoom):&lt;/div&gt;
&lt;div&gt;  &lt;a href=&quot;http://blog.section9.be/public/uploads/200909image.png&quot;&gt;&lt;img style=&quot;border-bottom: 0; border-left: 0; display: inline; border-top: 0; border-right: 0&quot; title=&quot;SharePoint Architecture&quot; src=&quot;http://blog.section9.be/public/uploads/200909image_thumb.png&quot; border=&quot;0&quot; alt=&quot;SharePoint Architecture&quot; width=&quot;447&quot; height=&quot;480&quot; /&gt;&lt;/a&gt; 
&lt;div&gt;Front End A: 10.0.0.1 &lt;/div&gt;
&lt;div&gt;Front End B: 10.0.0.2 &lt;/div&gt;
&lt;div&gt;Front End C: 10.0.0.3 &lt;/div&gt;
&lt;div&gt;Each Front Ends will respond to &lt;a href=&quot;http://intranet.fabrikam.com&quot;&gt;http://intranet.fabrikam.com&lt;/a&gt; because their
IIS Host Headers are configured to “intranet.fabrikam.com”, but if you use this
URL its the “Load Balancer” which is going to reply. &lt;/div&gt;
&lt;div&gt;So, How can you access &lt;a href=&quot;http://intranet.fabrikam.com&quot;&gt;http://intranet.fabrikam.com&lt;/a&gt; on Front End A
? &lt;/div&gt;
&lt;div&gt;You have to send the HTTP Request to the Front End A’s IP Address
(10.0.0.1) using “intranet.fabrikam.com” as the &lt;ins&gt;host&lt;/ins&gt; value in the
HTTP Request. &lt;/div&gt;
&lt;div&gt;Here is the HTTP Request you must build to access &lt;a href=&quot;http://intranet.fabrika.com&quot;&gt;http://intranet.fabrika.com&lt;/a&gt; :&lt;/div&gt;
&lt;pre&gt;
GET / HTTP/1.1 &lt;br /&gt;Accept: application/x-ms-application, */* &lt;br /&gt;Accept-Language: en,fr-BE;q=0.5 &lt;br /&gt;User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729 &lt;br /&gt;Accept-Encoding: gzip, deflate &lt;br /&gt;Host: intranet.fabrikam.com &lt;br /&gt;Connection: Keep-Alive
&lt;/pre&gt;
&lt;div&gt;Then you have to send it to Front End A’s IP Address (10.0.0.1)  How
to send that request to that IP Address ? There are many ways to do that:
&lt;ol&gt;
&lt;li&gt;Using System.Net.Sockets.Socket&lt;/li&gt;
&lt;li&gt;Using WebClient or WebRequest (method A)&lt;/li&gt;
&lt;li&gt;Using WebClient or WebRequest (method B)&lt;/li&gt;
&lt;/ol&gt;
&lt;ins&gt;First Method (Using System.Net.Sockets.Socket):&lt;/ins&gt; &lt;/div&gt;
&lt;div&gt;There is a major drawback with this method, you’ll have to handle
authentication manually (easy with Basic Authentication, pretty hard with Ntlm
or Kerberos)  
&lt;div&gt;&lt;br /&gt;
&lt;div&gt;
&lt;div style=&quot;background: #ffffff; overflow:auto;width:auto;color:black;background:white;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;&quot;&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre style=&quot;margin: 0; line-height: 125%&quot;&gt;
 1
2
3
4
5
6
7
8
9
10
11
12
13
&lt;/pre&gt;&lt;/td&gt;
&lt;td&gt;
&lt;pre style=&quot;margin: 0; line-height: 125%&quot;&gt;
&lt;span style=&quot;color: #2b91af&quot;&gt;string&lt;/span&gt; strHttpRequest = String.Concat(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;GET / HTTP/1.1rn&amp;quot;&lt;/span&gt;, &lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;Accept: application/x-ms-application, */*rn&amp;quot;&lt;/span&gt;, &lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;Accept-Language: en,fr-BE;q=0.5rn&amp;quot;&lt;/span&gt;, &lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729rn&amp;quot;&lt;/span&gt;, &lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;Accept-Encoding: gzip, deflatern&amp;quot;&lt;/span&gt;, &lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;Host: intranet.fabrikam.comrn&amp;quot;&lt;/span&gt;, &lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;Connection: Keep-Alivernrn&amp;quot;&lt;/span&gt;); &lt;span style=&quot;color: #008000&quot;&gt;//Create a IPv4 TCP Socket &lt;/span&gt;
Socket socketClient = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
&lt;span style=&quot;color: #008000&quot;&gt;//Connect to the Front End A's IP address on HTTP Port (80) &lt;/span&gt;
socketClient.Connect(IPAddress.Parse(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;10.0.0.1&amp;quot;&lt;/span&gt;), 80);
&lt;span style=&quot;color: #008000&quot;&gt;//Send the Http Request &lt;/span&gt;
socketClient.Send(Encoding.Default.GetBytes(strHttpRequest));
StringBuilder sbHttpResponse = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; StringBuilder();
&lt;span style=&quot;color: #2b91af&quot;&gt;byte&lt;/span&gt;[] bReceiveBuffer = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;byte&lt;/span&gt;[4096]; &lt;span style=&quot;color: #2b91af&quot;&gt;int&lt;/span&gt; iReceivedBytes = 0;
&lt;span style=&quot;color: #008000&quot;&gt;//Process the Http Response &lt;/span&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;while&lt;/span&gt; ((iReceivedBytes = socketClient.Receive(bReceiveBuffer)) &amp;gt; 0)
sbHttpResponse.Append(Encoding.Default.GetString(bReceiveBuffer, 0, iReceivedBytes));
&lt;span style=&quot;color: #008000&quot;&gt;//Output the Http Response &lt;/span&gt;
Console.WriteLine(sbHttpResponse.ToString());
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;ins&gt;
&lt;div&gt;&lt;ins&gt;&lt;ins&gt;&lt;br /&gt;&lt;/ins&gt;&lt;/ins&gt;&lt;/div&gt;
Second Method (Using WebClient or WebRequest (method A)):&lt;/ins&gt; &lt;/div&gt;
&lt;div&gt;Apparently this method will only work with .NET FrameWork 4.0, actually it
doesn't (.NET 3.5) because you cannot alter the “Host” header value(&lt;a title=&quot;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=384456&quot; href=&quot;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=384456&quot;&gt;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=384456&lt;/a&gt;) &lt;/div&gt;
&lt;div&gt;Additionally, there is a way (hack) to access the internal collection of
headers to bypass the validation: &lt;a title=&quot;http://blog.scoftware.com/post/2009/07/28/SOLUTION-HttpWebRequest-raw-headers.aspx&quot; href=&quot;http://blog.scoftware.com/post/2009/07/28/SOLUTION-HttpWebRequest-raw-headers.aspx&quot;&gt;
http://blog.scoftware.com/post/2009/07/28/SOLUTION-HttpWebRequest-raw-headers.aspx&lt;/a&gt; &lt;/div&gt;
&lt;div&gt;&lt;ins&gt;&lt;br /&gt;&lt;/ins&gt;&lt;/div&gt;

&lt;div style=&quot;background: #ffffff; overflow:auto;width:auto;color:black;background:white;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;&quot;&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre style=&quot;margin: 0; line-height: 125%&quot;&gt;
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
&lt;/pre&gt;&lt;/td&gt;
&lt;td&gt;
&lt;pre style=&quot;margin: 0; line-height: 125%&quot;&gt;
&lt;span style=&quot;color: #008000&quot;&gt;//Create a HttpWebRequest to Front End A's IP Address &lt;/span&gt;
HttpWebRequest myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;http://10.0.0.1&amp;quot;&lt;/span&gt;);
&lt;span style=&quot;color: #008000&quot;&gt;//Modify Host header to reach intranet.fabrikam.com &lt;/span&gt;
myHttpWebRequest.Headers[HttpRequestHeader.Host] = &lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;intranet.fabrikam.com&amp;quot;&lt;/span&gt;;
&lt;span style=&quot;color: #008000&quot;&gt;//Process Response HttpWebResponse &lt;/span&gt;
myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
Stream streamResponse = myHttpWebResponse.GetResponseStream();
StreamReader streamReader = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; StreamReader(streamResponse);
&lt;span style=&quot;color: #2b91af&quot;&gt;string&lt;/span&gt; strHttpResponse = streamReader.ReadToEnd();
&lt;span style=&quot;color: #008000&quot;&gt;//Output Response &lt;/span&gt;
Console.WriteLine(strHttpResponse);
streamResponse.Close();
streamReader.Close();
myHttpWebResponse.Close();
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div&gt;&lt;ins&gt;&lt;br /&gt;&lt;/ins&gt;&lt;/div&gt;
&lt;div&gt;&lt;ins&gt;Third Method (Using WebClient or WebRequest (method
B)):&lt;/ins&gt; &lt;/div&gt;
&lt;div&gt;Using the Proxy property of WebClient you can target &lt;a href=&quot;http://intranet.fabrikam.com&quot;&gt;http://intranet.fabrikam.com&lt;/a&gt; and connect to
10.0.0.1&lt;/div&gt;

&lt;div style=&quot;background: #ffffff; overflow:auto;width:auto;color:black;background:white;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;&quot;&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre style=&quot;margin: 0; line-height: 125%&quot;&gt;
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
&lt;/pre&gt;&lt;/td&gt;
&lt;td&gt;
&lt;pre style=&quot;margin: 0; line-height: 125%&quot;&gt;
&lt;span style=&quot;color: #008000&quot;&gt;//Create a WebClient &lt;/span&gt;
WebClient webClient = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; WebClient();
&lt;span style=&quot;color: #008000&quot;&gt;//You can eventulay set a Username / Password as NetworkCredentials &lt;/span&gt;
webClient.Credentials = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; NetworkCredential(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;, &lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;password&amp;quot;&lt;/span&gt;);
&lt;span style=&quot;color: #008000&quot;&gt;//The Front End A's IP Address to connect to &lt;/span&gt;
webClient.Proxy = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; WebProxy(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;10.0.0.1&amp;quot;&lt;/span&gt;);
&lt;span style=&quot;color: #008000&quot;&gt;//Will set the correct Host Header &lt;/span&gt;
Stream streamResponse = webClient.OpenRead(&lt;span style=&quot;color: #a31515&quot;&gt;&amp;quot;http://intranet.fabrikam.com&amp;quot;&lt;/span&gt;);
&lt;span style=&quot;color: #008000&quot;&gt;//Process the HttpResponse &lt;/span&gt;
StreamReader streamReader = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; StreamReader(streamResponse);
&lt;span style=&quot;color: #2b91af&quot;&gt;string&lt;/span&gt; strHttpResponse = streamReader.ReadToEnd();
&lt;span style=&quot;color: #008000&quot;&gt;//Output the HttpResponse &lt;/span&gt;
Console.WriteLine(strHttpResponse);
streamResponse.Close(); webClient.Dispose();
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div&gt;That’s all for today !&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>Silverlight 3 in SharePoint 2007 with Document Preview (Part 0)</title>
    <link>http://blog.section9.be/post/2009/08/30/Silverlight-3-in-SharePoint-2007-with-Document-Preview-%28Part-0%29</link>
    <guid isPermaLink="false">urn:md5:320a9d4f7e40aaa0af956fd7f703200c</guid>
    <pubDate>Sun, 30 Aug 2009 15:54:00 +0200</pubDate>
    <dc:creator>Mathieu</dc:creator>
        <category>Development</category>    
    <description>    &lt;p&gt;Here is the first part of my guide to add Document Preview in SharePoint
2007 and Silverlight 3 to preview them.&lt;/p&gt;
&lt;p&gt;To achieve this, I’ll be using these technologies/components (more will
come):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Silverlight 3.0&lt;/li&gt;
&lt;li&gt;SharePoint 2007 (either WSS 3.0 or MOSS)&lt;/li&gt;
&lt;li&gt;Microsoft SharePoint &lt;a href=&quot;http://code.msdn.microsoft.com/ssv&quot;&gt;SilverView&lt;/a&gt; (available on
CodePlex)&lt;/li&gt;
&lt;li&gt;Windows Communication Foundation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The big picture (subject to updates along the posts):&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.section9.be/public/uploads/200908image.png&quot;&gt;&lt;img style=&quot;border-right-width: 0; display: inline; border-top-width: 0; border-bottom-width: 0; border-left-width: 0&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;http://blog.section9.be/public/uploads/200908image_thumb.png&quot; width=&quot;524&quot; height=&quot;480&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So, We’ll take a standard SharePoint architecture and extends it to generate
Document Preview and allow Silverlight to upload files to a document
library.&lt;/p&gt;
&lt;p&gt;Things we’ll do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add some WCF in SharePoint&lt;/li&gt;
&lt;li&gt;Extend the Microsoft SharePoint Silverview sample to get thumbnails of
Documents in SharePoint&lt;/li&gt;
&lt;li&gt;Create Document Preview of (at least) Microsoft Office Documents&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;What are new in that big pictures ?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Thumbnails Service WCF&lt;/li&gt;
&lt;li style=&quot;list-style: none; display: inline&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Allow Document Preview generation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Upload Helper WCF&lt;/li&gt;
&lt;li style=&quot;list-style: none; display: inline&quot;&gt;
&lt;ul&gt;
&lt;li&gt;Enable Silverlight application to upload file to a document library (we’ll
review why i choose this way)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The extended Microsoft SharePoint Silverview&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;In the next post, I’ll briefly introduce Microsoft SharePoint Silverview and
extend it to handle more than Image preview.&lt;/p&gt;</description>
    
    
    
      </item>
    
  <item>
    <title>CISCO IOS (Partie 6)</title>
    <link>http://blog.section9.be/post/2008/03/06/CISCO-IOS-%28Partie-6%29</link>
    <guid isPermaLink="false">urn:md5:059b4d05e014b66270b5836c92af2a0a</guid>
    <pubDate>Thu, 06 Mar 2008 18:30:00 +0100</pubDate>
    <dc:creator>Mathieu</dc:creator>
        <category>Networking</category>    
    <description>    Examinons de plus près la commande « show buffers » :
&lt;pre&gt;
#show buffers
Buffer elements:
1116 in free list (1119 max allowed)
14344198 hits, 0 misses, 619 created
Public buffer pools:
Small buffers, 104 bytes (total 50, permanent 50, peak 80 @ 7w0d):
45 in free list (20 min, 150 max allowed)
4382143 hits, 14 misses, 30 trims, 30 created
0 failures (0 no memory)
Middle buffers, 600 bytes (total 75, permanent 25, peak 104 @ 1w5d):
40 in free list (10 min, 150 max allowed)
4410481 hits, 11530 misses, 7219 trims, 7269 created
2618 failures (0 no memory)
Big buffers, 1536 bytes (total 50, permanent 50, peak 110 @ 2w3d):
45 in free list (5 min, 150 max allowed)
3756688 hits, 546 misses, 1539 trims, 1539 created
8 failures (0 no memory)
VeryBig buffers, 4520 bytes (total 10, permanent 10):
10 in free list (0 min, 100 max allowed)
8 hits, 0 misses, 0 trims, 0 created
0 failures (0 no memory)
Large buffers, 5024 bytes (total 0, permanent 0):
0 in free list (0 min, 10 max allowed)
0 hits, 0 misses, 0 trims, 0 created
0 failures (0 no memory)
Huge buffers, 18024 bytes (total 0, permanent 0):
0 in free list (0 min, 4 max allowed)
0 hits, 0 misses, 0 trims, 0 created
0 failures (0 no memory)
&lt;/pre&gt;
On Remarque la présence de plusieurs Pool de buffers : « Small buffers, Middle
buffers, … ». La commande nous renseigne les champs suivants :
&lt;ul&gt;
&lt;li&gt;Nom du pool de buffer + taille des buffers dans ce pool
&lt;ul&gt;
&lt;li&gt;Total : nombre total de buffers dans le pool (actuellement)&lt;/li&gt;
&lt;li&gt;Permanent : nombre de buffers permanent et minimum du pool (on ne descendra
jamais en dessous de cette valeur)&lt;/li&gt;
&lt;li&gt;Peak : nombre maximal de buffers atteint dans ce pool @ quand&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;In free list : nombre de buffers libres dans le pool
&lt;ul&gt;
&lt;li&gt;Min : nombre minimum de buffers libres dans le pool (si il venait a y en
avoir moins, l’IOS en allouerait de nouveaux)&lt;/li&gt;
&lt;li&gt;Max allowed : nombre maximum de buffers libres dans le pool (si il venait a
y en avoir plus l’IOS essaierait d’en supprimer tout en ne descendant jamais en
dessous de la limite « Permanent »)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Hits : nombre de buffers qui ont été demandé dans ce pool
&lt;ul&gt;
&lt;li&gt;Misses : nombre de fois qu’un buffer a été demandé alors que la valeur de «
In Free List » était inférieure à « Min »&lt;/li&gt;
&lt;li&gt;Trims : nombre de buffers qui ont été supprimé par l’IOS dans le pool (par
exemple lorsque « Max allowed » était dépassé)&lt;/li&gt;
&lt;li&gt;Created : nombre de buffers qui ont été ajouté au pool parce que la taille
du pool ne suffisait plus.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Failures : nombre de fois qu’un buffer a été demandé et qu’il n’a pu être
fourni. (si une demande de buffer intervient pendant une interrupt, on ne sait
pas augmenter la taille du pool de buffers et on ne sait pas satisfaire la
demande)
&lt;ul&gt;
&lt;li&gt;No memory : nombre de fois qu’un buffer a été demandé et qu’il n’y avait
pas assez de buffers libres ni assez de mémoire libre pour satisfaire la
demande.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
Prenons un exemple pour mieux comprendre ces informations : &lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospartie6-a4cimage-11c82b8e-ee70-46cd-a782-3a8d83cacb18.png&quot; alt=&quot;image&quot; height=&quot;236&quot; width=&quot;188&quot; /&gt; Le pool Small buffers contient 10
buffers (10 libres / 10 buffers en permanence).
&lt;pre&gt;
#show buffers
Small buffers, 104 bytes (total 10, permanent 10)
10 in free list (5 min, 8 max allowed)
0 hits, 0 misses, 0 trims, 0 created
0 failures (0 no memory)
&lt;/pre&gt;
&lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospartie6-a4cimage-958e8ffb-02d5-4d05-934d-d357f0d62ff5.png&quot; alt=&quot;image&quot; height=&quot;236&quot; width=&quot;188&quot; /&gt; On reçoit 5 paquets, l’IOS alloue 5
buffers « 5 hits ».
&lt;pre&gt;
#show buffers
Small buffers, 104 bytes (total 10, permanent 10)
5 in free list (5 min, 8 max allowed)
5 hits, 0 misses, 0 trims, 0 created
0 failures (0 no memory)
&lt;/pre&gt;
&lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospartie6-a4cimage-15155631-c9c4-486a-b4fd-a5b5b9cf0dc6.png&quot; alt=&quot;image&quot; height=&quot;236&quot; width=&quot;196&quot; /&gt; On reçoit 4 paquets supplémentaires
(hits+=4) « 9 hits ». La demande de 4 buffers provoque « 4 misses » car les 4
buffers font tomber le compteur de buffers libres en dessous du minimum de ce
pool « 1 in free list / 5 min »
&lt;pre&gt;
#show buffers
Small buffers, 104 bytes (total 10, permanent 10)
1 in free list (5 min, 8 max allowed)
9 hits, 4 misses, 0 trims, 0 created
0 failures (0 no memory)
&lt;/pre&gt;
&lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospartie6-a4cimage-8d180a35-4940-494d-b0be-04781714c7e3.png&quot; alt=&quot;image&quot; height=&quot;311&quot; width=&quot;188&quot; /&gt; Vu que le nombre de buffers libre est
inférieur au minimum, l’IOS alloue 4 buffers supplémentaires pour le satisfaire
« 4 created ».
&lt;pre&gt;
#show buffers
Small buffers, 104 bytes (total 14, permanent 10)
5 in free list (5 min, 8 max allowed)
9 hits, 4 misses, 0 trims, 4 created
0 failures (0 no memory)
&lt;/pre&gt;
&lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospartie6-a4cimage-989971d9-caaa-4585-b576-47e270ee6abc.png&quot; alt=&quot;image&quot; height=&quot;324&quot; width=&quot;181&quot; /&gt; On reçoit 6 paquets supplémentaires. Il
n’y a de place que pour 5 de ces paquets (hits+5) « 14 hits ». Le paquet
n’ayant pas eu de buffer est perdu « 1 failure ». La demande de 6 buffers a
provoqué (4+6 misses) « 10 misses » car le minimum n’est plus respecté.
&lt;pre&gt;
#show buffers
Small buffers, 104 bytes (total 14, permanent 10)
0 in free list (5 min, 8 max allowed)
14 hits, 10 misses, 0 trims, 4 created
1 failures (0 no memory)
&lt;/pre&gt;
&lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospartie6-a4cimage-35284c2d-d493-4e8a-8ec5-5a641552b12e.png&quot; alt=&quot;image&quot; height=&quot;311&quot; width=&quot;188&quot; /&gt; Certains buffers qui étaient utilisés
sont libérés « 12 in free list »
&lt;pre&gt;
#show buffers
Small buffers, 104 bytes (total 14, permanent 10)
12 in free list (5 min, 8 max allowed)
14 hits, 10 misses, 0 trims, 4 created
1 failures (0 no memory)
&lt;/pre&gt;
&lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospartie6-a4cimage-7b7465e0-6a2a-485a-b365-825ce24ed5f8.png&quot; alt=&quot;image&quot; height=&quot;311&quot; width=&quot;188&quot; /&gt; Le nombre de buffers libre est
supérieur au maximum autorisé. L’IOS supprime l’excédant de buffers « 4 trims
».
&lt;pre&gt;
#show buffers
Small buffers, 104 bytes (total 10, permanent 10)
8 in free list (5 min, 8 max allowed)
14 hits, 10 misses, 4 trims, 4 created
1 failures (0 no memory)
&lt;/pre&gt;
L’exemple ci-dessus montre le fonctionnement d’un pool de buffers dynamique.
Certains pool de buffers sont statiques (pas d’allocation / suppression de
buffers à la demande). Tous les buffers d’un pool de buffers donné possèdent la
même taille. Cette taille est légèrement plus grande que le MTU typique d’un
paquet provenant d’une interface. Grâce à cet espace supplémentaire, un
processus peut ajouter des données au header du paquet lors de son traitement.
&lt;pre&gt;
Small buffers, 104 bytes
Middle buffers, 600 bytes
Big buffers, 1536 bytes
VeryBig buffers, 4520 bytes
Large buffers, 5024 bytes
Huge buffers, 18024 bytes
&lt;/pre&gt;
Une interface possède un pool de buffer privé « Private particle pools » dont
elle est seule à profiter. Lorsque son pool est plein, elle peut se servir dans
un des publics pools (Small buffers, Middle buffers, …).
&lt;pre&gt;
#show buffers
Private particle pools:
FastEthernet0/0 buffers, 1552 bytes (total 512, permanent 512):
0 in free list (0 min, 512 max allowed)
512 hits, 0 fallbacks
512 max cache size, 256 in cache
62643951 hits in cache, 0 misses in cache
&lt;/pre&gt;
N’importe quel processus peut demander un buffer provenant d’un public pool. Le
traitement d’un paquet n’est pas nécessaire pour pouvoir effectuer cette
demande. Un particle pool est un pool spécial, permettant à un paquet plus
grand que la taille d’un des buffers de ce pool, de prendre plusieurs buffers
contigus grâce à un chaînage. Cela permet d’accepter un paquet de virtuellement
n’importe quelle taille. (buffer overflow difficile !). Dans le prochain post
de cette lignée : Les méthodes de « packet switching ».</description>
    
    
    
      </item>
    
  <item>
    <title>CISCO IOS (Part 5)</title>
    <link>http://blog.section9.be/post/2008/02/24/CISCO-IOS-%28Part-5%29</link>
    <guid isPermaLink="false">urn:md5:8387c58f09445ba67d926993e97b5238</guid>
    <pubDate>Sun, 24 Feb 2008 19:00:00 +0100</pubDate>
    <dc:creator>Mathieu</dc:creator>
        <category>Networking</category>    
    <description>    When we allocate memory to a process “&lt;em&gt;malloc&lt;/em&gt;”, the Pool Manager takes
a free memory block and attaches it to a process. The Pool Manager maintains a
table of contiguous memory blocks. When a process frees a memory block, the
Pool Manager tries to concatenate it with its neighbors. Despite of this
concatenation, fragmentation is unavoidable. An extremely fragmented memory can
lead to “&lt;em&gt;malloc&lt;/em&gt;” errors &lt;a href=&quot;http://www.cisco.com/warp/public/63/mallocfail.shtml&quot;&gt;“%SYS-2-MALLOCFAIL&lt;/a&gt;”.
Indeed, the memory available can be sufficient, but not enough contiguous free
blocks available to allow a requested “&lt;em&gt;malloc&lt;/em&gt;”. &lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospart5-e70bimage-3.png&quot; alt=&quot;image&quot; style=&quot;border: 0&quot; height=&quot;324&quot; width=&quot;508&quot; /&gt; &lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospart5-e70bimage-2575d16b-472f-4a71-81e3-c37841665870.png&quot; alt=&quot;image&quot; height=&quot;324&quot; width=&quot;508&quot; /&gt; &lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospart5-e70bimage-dfa737ac-4857-4981-b603-b8f9945e9255.png&quot; alt=&quot;image&quot; height=&quot;324&quot; width=&quot;508&quot; /&gt; In the last figure, there are only
small non-contiguous freed blocks: Now, if a process wants to allocate a larger
memory area, it will not be able to do it and it’ll have a “MALLOCFAIL” error.
The Chunk Manager will try to avoid this kind of situation by allocating the
memory to processes cleverly. The Chunk Manager is responsible of the Chunks
Allocation. A Chunk contains a finished number of memory blocks of equal size.
If we use every memory blocks of a Chunk, the Chunk Manager will allocate a new
memory area (Sibling). If no more blocks of this “Sibling” are used, it is
freed “Freed/Trimmed”. A process now has a larger allocated memory area split
into smaller memory blocks. When a process frees a memory block, it does in its
Chunk. There is no more fragmentation due to different processes freeing
memory. &lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospart5-e70bimage-f60b012d-652a-4f81-9cfc-70788fcde221.png&quot; alt=&quot;image&quot; height=&quot;308&quot; width=&quot;380&quot; /&gt;
&lt;pre&gt;
#show chunk
Chunk Manager:  407660 chunks created, 406281 chunks destroyed  9349 siblings created, 406279 siblings trimmed
Chunk          element  Block   Maximum  Element  Element
Total Cfgsize   Ohead    size   element    inuse   freed  Ohead    Name
16               4       940       33        2      31     360   String-DB owne 0x654C2408
16               4       940       33        0      33     360   String-DB cont 0x654C27B4
312              16    65588      197       38     159    4072   Extended ACL e 0x654C3484
96               16    20052      171        9     162    3584   ACL Header 0x654D34B8
8536             0     65588        7        1       6    5784   Parseinfo Bloc 0x654DA14C
16               0       456       15        1      14     164   tokenQ node 0x654EA180
20               0       456       13       13       0     144   Chain Cache No 0x654EA348
20               0       456       13        6       7     144   (sibling) 0x66BD0E50
20               0       460       13       13       0     148   (sibling) 0x66F33EE0
&lt;/pre&gt;
Within a Chunk, the memory blocks have a header (or not, size = 0). The header
size per chunk is fixed (0, 4, 16, 20, 24). Example: ACL Header is a Chunk of
171 elements max, with 96 elements since creation. Each block have a header of
16Bytes and weight 20,052Bytes. Actually there are only 9 memory blocks in use
within this Chunk. Next post: The Buffers.</description>
    
    
    
      </item>
    
  <item>
    <title>CISCO IOS (Part 4)</title>
    <link>http://blog.section9.be/post/2008/02/23/CISCO-IOS-%28Part-4%29</link>
    <guid isPermaLink="false">urn:md5:e11ec7f78bcffd0aba090c7ebf259b9d</guid>
    <pubDate>Sat, 23 Feb 2008 19:07:00 +0100</pubDate>
    <dc:creator>Mathieu</dc:creator>
        <category>Networking</category>    
    <description>    Every OS includes a memory manager. Current OS uses protected memory
architecture. The process x cannot read/write the memory of a process y. To
enable communication between process x and y, it requires different techniques
(Shared Memory, Message Queues, Pipes, Network Connections …). These techniques
enhance inter-processes security but reduce performance. The IOS does not
implement Shared Memory; any process can access all the memory without
restrictions. A process is free to communicate with another one by writing
directly into its memory. (Buffer Overflow = Crash, I’ll come back later on
this by explaining the Memory Block Architecture). The IOS can mark memory as
R/O or R/W. The IOS has memory pools, driven by the Pool Manager:
&lt;pre&gt;
#show memory
Head       Total(b)     Used(b)    Free(b)    Lowest(b)   Largest(b)
Processor
653B8C20   155481056    86243592   69237464   68168948    67670028
I/O
EE800000    25165824     5269012   19896812   19819968    19871932
&lt;/pre&gt;
Above, a processor and an I/O memory pool:
&lt;ul&gt;
&lt;li&gt;Head : Start Address of the memory pool&lt;/li&gt;
&lt;li&gt;Total : Pool size in bytes&lt;/li&gt;
&lt;li&gt;Used : Total amount of bytes currently used in the pool&lt;/li&gt;
&lt;li&gt;Free : Total amount of bytes currently free in the pool&lt;/li&gt;
&lt;li&gt;Lowest : The history’s lowest amount of bytes free since last restart&lt;/li&gt;
&lt;li&gt;Largest : The Largest free contiguous memory block&lt;/li&gt;
&lt;/ul&gt;
These memory pools belong to Memory Regions driven by the Region Manager:
&lt;pre&gt;
#show region
Region Manager:
Start       End            Size(b)  Class  Media  Name
0x0E800000  0x0FFFFFFF    25165824  Iomem  R/W    iomem:(iomem)
0x60000000  0x6E7FFFFF   243269632  Local  R/W    main
0x6000F000  0x632FFFFF    53415936  IText  R/O    main:text
0x63300000  0x64DFFCFF    28310784  IData  R/W    main:data
0x64DFFD00  0x653B8C1F     6000416  IBss   R/W    main:bss
0x653B8C20  0x6E7FFFFF   155481056  Local  R/W    main:heap
0x80000000  0x8E7FFFFF   243269632  Local  R/W    main:(main_k0)
0xA0000000  0xAE7FFFFF   243269632  Local  R/W    main:(main_k1)
0xEE800000  0xEFFFFFFF    25165824  Iomem  R/W    iomem
&lt;/pre&gt;
The Processor Memory Pool belongs to &lt;em&gt;main:heap&lt;/em&gt; region. This region
belongs to the &lt;em&gt;main&lt;/em&gt; region starting at 0×60000000 and ending at
0×6E7FFFFF. The I/O Memory Pool belongs to &lt;em&gt;iomem&lt;/em&gt; region starting at
0xEE800000 and ending at 0xEFFFFFFF. Within the &lt;em&gt;main&lt;/em&gt; region:
&lt;ul&gt;
&lt;li&gt;main:text : contains IOS’s code in R/O (IText)&lt;/li&gt;
&lt;li&gt;main:data : contains Initialized variables R/W (IData)&lt;/li&gt;
&lt;li&gt;main:bss : contains Uninitialized variables R/W (IBss)&lt;/li&gt;
&lt;li&gt;main:heap : contains standard local memory structures R/W&lt;/li&gt;
&lt;li&gt;iomem : contains devices memory (I/O bus memory)&lt;/li&gt;
&lt;/ul&gt;
We can notice that some of the regions are redundant: &lt;em&gt;main:(main_k0);
main:(main_k1);&lt;/em&gt; They are all equals to the &lt;em&gt;main&lt;/em&gt; region. We’re
also able to find &lt;em&gt;iomem&lt;/em&gt; in two different addresses:
0×0E800000-&amp;gt;0×0FFFFFFF and 0xEE800000-&amp;gt;0xEFFFFFFF. But it’s still the
same memory area. From a CISCO device to another, the type of memory used for
each region may change. For a Router &lt;em&gt;x,&lt;/em&gt; the &lt;em&gt;iomem&lt;/em&gt; is SRAM,
but for another the same region is DRAM. The Pool Manager defines its memory
pools within the regions, regardless of the memory type used (hardware
abstraction). Let’s go back to the Pool Manager. By entering the “show memory
processor” command, we can notice that the memory is divided into memory
blocks:
&lt;pre&gt;
#show memory processor
Processor memory
Address      Bytes     Prev     Next Ref     PrevF    NextF  Alloc PC  what
65A817E0 0000000084 65A8175C 65A81864 001  -------- -------- 628215E8  Init
65A81864 0000001372 65A817E0 65A81DF0 001  -------- -------- 608E3218  Skinny Socket Server
65A81DF0 0000001156 65A81864 65A822A4 001  -------- -------- 608E3218  Skinny Socket Server
&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Address : Start of block&lt;/li&gt;
&lt;li&gt;Bytes : Size of block&lt;/li&gt;
&lt;li&gt;Prev : Previous block Address (linkage)&lt;/li&gt;
&lt;li&gt;Next : Next Block Address (linkage)&lt;/li&gt;
&lt;li&gt;Ref : How many process are using this block?&lt;/li&gt;
&lt;li&gt;PrevF : Previous free block&lt;/li&gt;
&lt;li&gt;NextF : Next free block&lt;/li&gt;
&lt;li&gt;Alloc PC : Allocating Process&lt;/li&gt;
&lt;li&gt;What : Block owner’s process name&lt;/li&gt;
&lt;/ul&gt;
Inside a Memory Block :
&lt;pre&gt;
#show memory 0x65A81864
65A81860:          AB1234CD 010B0000 66B4EBEC      +.4M....f4kl
65A81870: 6395634C 608E3218 65A81DF0 65A817F4  c.cL`.2.e(.pe(.t
65A81880: 800002AE 00000001 605C3DD4 00000112  ........`=T.... ...
65A81DE0:                            FD0110DF              }.._
&lt;/pre&gt;
After some researches we can guess some of the fields from the Block’s header:
&lt;pre&gt;
65A81860:            [MAGIC  ]  [PID   ] [?       ]
65A81870: [PTR_NAME] [ALLOCPC]  [NEXT  ] [PREV+20d]
65A81880: [SIZE*] [REF ] [?  ] [ DATA -&amp;gt;] ...
65A81DE0:                     [&amp;lt;- DATA] [MAGIC   ]
&lt;/pre&gt;
&lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospart4-1290aimage-3.png&quot; alt=&quot;image&quot; style=&quot;border: 0&quot; height=&quot;344&quot; width=&quot;115&quot; /&gt;
&lt;ul&gt;
&lt;li&gt;MAGIC_START is always 0xAB1234CD&lt;/li&gt;
&lt;li&gt;PID : Process ID&lt;/li&gt;
&lt;li&gt;[ PLACEHOLDER ]&lt;/li&gt;
&lt;li&gt;PTR PS_ NAME : Pointer to the Memory Block’s owner process name&lt;/li&gt;
&lt;li&gt;ALLOC_PC : Same value as in “show memory processor” command&lt;/li&gt;
&lt;li&gt;NEXT : Next Block Pointer&lt;/li&gt;
&lt;li&gt;PREV : Previous Block Pointer + 20d (pointing to the Next Block Pointer of
the previous block)&lt;/li&gt;
&lt;li&gt;SIZE : The MSB (Most Significant Bit) of this Field is a flag where 1
states that the block is in use. The value read in this field differ from the
one displayed using the “show memory processor” command. For both to be equals
I need to do : (value read)*2+4 ????&lt;/li&gt;
&lt;li&gt;REF : How many process are using this block?&lt;/li&gt;
&lt;li&gt;[ PLACEHOLDER ]&lt;/li&gt;
&lt;li&gt;DATA : …&lt;/li&gt;
&lt;li&gt;MAGIC_END is always 0xFD0110DF (palindrome in hexadecimal)&lt;/li&gt;
&lt;/ul&gt;
Starting with this Memory Block, if I want to go to the next block without
using the Next pointer, I must do: Block Address + sizeof(magic_start) +
sizeof(header) + (2*[value read in Size field]+4) + sizeof(magic_end) So:
0×65A81864+0×4+0×24+0×560+0×4=0×65A81DF0 Checking the PID field:
&lt;pre&gt;
#show process 0x0000010B [010B &amp;lt;&amp;gt; 0000]
Process ID 267 [Skinny Socket Server],
TTY 0
Memory usage [&lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; bytes] Holding: 89644, Maximum: 109468, Allocated: 6601380, Freed: 6514500
Getbufs: 0,
Retbufs: 0,
Stack: 8908/12000
CPU usage PC: 60846DE4, Invoked: 26, Giveups: 1, uSec: 9384 5Sec: 0.00%, 1Min: 0.00%, 5Min: 0.00%, Average: 0.00% Age: 5007208 msec,
Runtime: 244 msec
State: Waiting &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; Event, Priority: Normal
&lt;/pre&gt;
Checking the PTR PS_NAME field:
&lt;pre&gt;
#show memory 0x6395634C
63956340:                            536B696E              Skin
63956350: 6E792053 6F636B65 74205365 72766572  ny Socket Server
63956360: 00000000 0A496E76 616C6964 20736B69  .....Invalid ski
-&amp;gt;Skinny Socket Server
&lt;/pre&gt;
Checking that there is currently an end of block (must have the FD0110DF magic
number):
&lt;pre&gt;
0x65A81864 + 2*[SIZE]+4 + SIZEOF(MAGICSTART) + [HEADERSIZE] = 0x65A81864 + 0X560 + 0x4 + 0x24
#show memory 0x65A81DEC
65A81DE0:                            FD0110DF              }.._
&lt;/pre&gt;
Now let’s talk about the crash resulting from a Buffer Overflow: If we want to
make a buffer overflow in a memory area, so writing more bytes than allocated
for this area, we’ll overwrite the next block header thus breaking the IOS
memory linkage mechanism. What a pity! Or not! The IOS constantly checks the
memory structures, if it finds any inconsistency, it’s forcing a crash. So to
success with a buffer overflow (crash free), you need to re-write a coherent
header on the next block. Do not forget to add a “jmp” to your code to jump
just after the next block header! &lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospart4-1290aimage-6.png&quot; alt=&quot;image&quot; style=&quot;border: 0&quot; height=&quot;356&quot; width=&quot;581&quot; /&gt; In the next post: The
Chunk Manager!</description>
    
    
    
      </item>
    
  <item>
    <title>CISCO IOS (Part 3)</title>
    <link>http://blog.section9.be/post/2008/02/15/CISCO-IOS-%28Part-3%29</link>
    <guid isPermaLink="false">urn:md5:19dfa9871adc08fabb6f365ae0c7e9de</guid>
    <pubDate>Fri, 15 Feb 2008 20:45:00 +0100</pubDate>
    <dc:creator>Mathieu</dc:creator>
        <category>Networking</category>    
    <description>    Like I previously said, there are 4 process priorities, each with a dedicated
queue. A queue contains &lt;em&gt;n&lt;/em&gt; “Ready State” processes of priority
&lt;em&gt;x&lt;/em&gt;.
&lt;pre&gt;
#sh processes
PID     QTy PC          Runtime (ms) Invoked uSecs      Stacks          TTY     Process
22      Mwe 628250A4    0               1       0       2516/3000       0       RMI RM Notify Wa
23      Hwe 60092C38    0               2       0       5508/6000       0       SMART
24      Msp 612FAFB0    76              170778  0       5540/6000       0       GraphIt
25      Mwe 613B193C    0               2       0       11504/12000     0       Dialer event
26      Mwe 624E81B0    0               1       0       5540/6000       0       SERIAL A'detect
27      Mwe 62AC6984    0               2       0       11516/12000     0       XML Proxy Client
28      M*      0       456             153298  0       9356/12000      194     SSH Process
29      Mwe 602AFC70    0               1       0       2484/3000       0       Inode Table Dest
30      Cwe 62818F90    0               1       0       5548/6000       0       Critical Bkgnd
31      Mwe 6033D7D8    96              102962  0       10208/12000     0       Net Background
32      Mwe 6033DA68    0               2       0       11420/12000     0       IDB Work
33      Lwe 6128EEEC    2184            9209    237     10088/12000     0       Logger
&lt;/pre&gt;
In this “&lt;a href=&quot;http://www.cisco.com/warp/public/63/showproc_cpu.html#showproc&quot;&gt;show
processes&lt;/a&gt;” output, we can see the 4 priorities and a Running State process.
Within Q Column:
&lt;ul&gt;
&lt;li&gt;L : Low Priority (background process)&lt;/li&gt;
&lt;li&gt;M : Medium Priority (default priority)&lt;/li&gt;
&lt;li&gt;H : High Priority (Process processing received packets)&lt;/li&gt;
&lt;li&gt;C : Critical Priority (Resources allocation, core system processes)&lt;/li&gt;
&lt;li&gt;K : Killed&lt;/li&gt;
&lt;li&gt;D : Crashed&lt;/li&gt;
&lt;li&gt;X : Corrupted&lt;/li&gt;
&lt;/ul&gt;
Within Ty Column:
&lt;ul&gt;
&lt;li&gt;* : Running State Process&lt;/li&gt;
&lt;li&gt;S : Process that called Suspend&lt;/li&gt;
&lt;li&gt;E : Process waiting for events&lt;/li&gt;
&lt;li&gt;rd : Ready State Process&lt;/li&gt;
&lt;li&gt;we : Idle State Process waiting on events&lt;/li&gt;
&lt;li&gt;sa : Idle State Process waiting on specific time&lt;/li&gt;
&lt;li&gt;si : Idle State Process waiting on end of interval&lt;/li&gt;
&lt;li&gt;sp : Idle State Process waiting on periodic interval&lt;/li&gt;
&lt;li&gt;st : Idle State Process waiting on timer expiration&lt;/li&gt;
&lt;li&gt;hg : Hang Process&lt;/li&gt;
&lt;li&gt;xx : Dead Process&lt;/li&gt;
&lt;/ul&gt;
Other columns:
&lt;ul&gt;
&lt;li&gt;PID : Process ID …&lt;/li&gt;
&lt;li&gt;PC : Process current code Stack Pointer (0 = running)&lt;/li&gt;
&lt;li&gt;Runtime : Total amount of CPU time used since process creation&lt;/li&gt;
&lt;li&gt;Invoked : Number of time process was Invoked&lt;/li&gt;
&lt;li&gt;uSec : Average CPU time spent during each invoke&lt;/li&gt;
&lt;li&gt;Stacks : Current process stack use/Total process stack use&lt;/li&gt;
&lt;li&gt;TTY: Has process access to STDIN/STDOUT, if !0, points to specified TTY/VTY
(#show line).&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
#show line
Tty     Line    Typ Tx/Rx       A Modem Roty AccO AccI  Uses    Noise Overruns    Int
0       0       CTY             -     -          -       -      -       0       0       0/0     -
1       1       AUX 9600/9600   -     -          -       -      -       0       0       0/0     -
*194    194     VTY             -     -          -       -      -       3       0       0/0     -
195     195     VTY             -     -          -       -      -       0       0       0/0     -
196     196     VTY             -     -          -       -      -       0       0       0/0     -
&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Process : Process name&lt;/li&gt;
&lt;/ul&gt;
Let’s go back to the Scheduler: &lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospart3-1332aimage-3.png&quot; alt=&quot;image&quot; style=&quot;border: 0&quot; height=&quot;249&quot; width=&quot;560&quot; /&gt; 1. The Scheduler
starts with Critical Priority Stack and runs then removes all processes within.
2. If the Critical Stack is empty, the Scheduler moves on to High Priority
Stack and runs then removes the first process. Once the first process was run,
the scheduler checks that the Critical Stack is still empty. If it’s not, the
Scheduler runs then removes all processes within it. The Scheduler moves on to
the next High Priority Process. After each High Priority Process, the Scheduler
checks if there is a higher priority process (Critical). If so, it runs then
removes it. 3. If both Critical Stack and High Priority Stack are empty, the
Scheduler moves on to Medium Priority Stack. Between each Medium Priority
Process, the scheduler checks if there are any High Priority Processes to run.
If there are, it runs the first one and removes it, then checks if there are
any Critical Processes to run and runs then removes all of them. When the
Critical stack is empty, the scheduler moves on to the next High Priority
Process, and so on … 4. If the Critical/High/Medium Priority stacks are empty,
the scheduler moves on to the Low Priority Stack. (If we are coming from the
Medium Priority Stack, we do not move on to the Low Priority Stack. At the end
of the Medium Priority Stack, we move on to Critical Priority Stack. When we’ve
executed this step 15 times, we finally move to Low Priority Stack). Between
each Low Priority Process, the scheduler checks if there are any Medium
Priority Process to run. If there are, it runs and removes each Medium Priority
Process but between each of them the scheduler checks if there are any High
Priority Process to run. If there are, it runs then removes it, but between
every High Priority Process, it checks if there are any Critical processes to
run, to run and remove them all. 5. It goes back to step 1. If a process
forgets to release the CPU within 4sec, no worry! The WatchDog Timer will kill
it! The WatchDog Timer is refreshed by an Interrupt (every 4msec by the System
Timer). The Incoming Packet Notification is also done using an Interrupt. So
the IOS can instantaneously process the incoming packet. I will talk about the
Packet Switching Methods soon. Next Post: IOS uses of the Memory</description>
    
    
    
      </item>
    
  <item>
    <title>CISCO IOS (Part 2)</title>
    <link>http://blog.section9.be/post/2008/02/15/CISCO-IOS-%28Part-2%29</link>
    <guid isPermaLink="false">urn:md5:e1db4143fd5816e81bfe332ae22e519c</guid>
    <pubDate>Fri, 15 Feb 2008 18:07:00 +0100</pubDate>
    <dc:creator>Mathieu</dc:creator>
        <category>Networking</category>    
    <description>    Like any OS, the IOS must implement a set of elemental principles:
&lt;ul&gt;
&lt;li&gt;Process Management&lt;/li&gt;
&lt;li&gt;Memory Management&lt;/li&gt;
&lt;li&gt;Devices Management&lt;/li&gt;
&lt;li&gt;User Interface&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
Let’s talk about processes; the IOS is a multi-task cooperative Operating
System (not preemptive). Each process is responsible for giving back the CPU to
the next process. The IOS does not implement multithreading (1 Process = 1
Thread). The IOS uses the interrupt mechanism in order to achieve fast packet
switching between interfaces. Each time a packet comes to an interface, an
interrupt is launched. So, the CPU is able to process the packet in priority.
The fact that a process is responsible for its CPU time can lead to lot of
mayhem if, for example, a process enters an endless loop. The “WatchDog Timer”
is an IOS’s special process that can kill a process taking up too much CPU time
(default is 2*2sec). A process has 6 states:
&lt;ul&gt;
&lt;li&gt;Create State
&lt;ul&gt;
&lt;li&gt;The process is created by the Kernel or by the Parser (cli / config)&lt;/li&gt;
&lt;li&gt;Resources allocation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Modify State (optional)
&lt;ul&gt;
&lt;li&gt;A terminal can be added to the process (by default: no std::in /out/err in
Create State)&lt;/li&gt;
&lt;li&gt;Some parameters can be added&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ready State
&lt;ul&gt;
&lt;li&gt;The process is ready to run&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Running State
&lt;ul&gt;
&lt;li&gt;The process is on the CPU&lt;/li&gt;
&lt;li&gt;It can:
&lt;ul&gt;
&lt;li&gt;Let another process take the CPU (Suspend). Go back to Ready State.&lt;/li&gt;
&lt;li&gt;Run to completion then self-terminated&lt;/li&gt;
&lt;li&gt;Wait for an event (Idle State)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Idle State
&lt;ul&gt;
&lt;li&gt;The process is waiting for a specific event (Wait for External Event)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dead State
&lt;ul&gt;
&lt;li&gt;The process is self-terminated&lt;/li&gt;
&lt;li&gt;The process was killed by the Kernel&lt;/li&gt;
&lt;li&gt;The process has completed its job (Run to completion)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
Process Lifecycle: &lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospart2-11adaimage-3.png&quot; alt=&quot;image&quot; style=&quot;border: 0&quot; height=&quot;422&quot; width=&quot;583&quot; /&gt; There are 4 process
priorities (one queue FIFO/priority):
&lt;ul&gt;
&lt;li&gt;Critical&lt;/li&gt;
&lt;li&gt;High&lt;/li&gt;
&lt;li&gt;Medium&lt;/li&gt;
&lt;li&gt;Low&lt;/li&gt;
&lt;/ul&gt;
The scheduler takes care to remove a process in Ready State from a priority
queue and run it on the CPU (Running State). &lt;ins&gt;Notes:&lt;/ins&gt;I could only find
4 priorities among the sources I consulted. However when we use the “show list”
command:
&lt;pre class=&quot;csharpcode&quot;&gt;
#show list | inc Sched
8 650F2910 0/- Sched Preemptive
9 650F2310 0/- Sched Critical
10 650F21F0 0/- Sched High
11 650F1C10 2/- Sched Normal
12 650F1C60 0/- Sched Low
13 650F1E10 0/- Sched Preemptive ION
14 650F2180 262/- Sched Idle
15 650F0800 0/- Sched Dead
16 6535B660 0/- Sched Normal (Old)
17 6535B6C0 0/- Sched Low (Old)
&lt;/pre&gt;
We can see that there is a queue called “Sched Preemptive”. This queue is
against the fact that the IOS is not preemptive! (Maybe my sources are pretty
old …) This command also displays the number of processes on each of the
queues. There are 262 processes in Idle State and 2 “Normal” priority processes
in Ready State. A process moved to “Dead State” doesn’t automatically get its
resources freed, hence the necessity of a “Dead Queue”. In my next post, I’ll
explain the working of the IOS’s Scheduler.</description>
    
    
    
      </item>
    
  <item>
    <title>CISCO IOS (Part 1)</title>
    <link>http://blog.section9.be/post/2008/02/10/CISCO-IOS-%28Part-1%29</link>
    <guid isPermaLink="false">urn:md5:a24acf5704ae155acbf003af04a23c29</guid>
    <pubDate>Sun, 10 Feb 2008 06:16:00 +0100</pubDate>
    <dc:creator>Mathieu</dc:creator>
        <category>Networking</category>    
    <description>    I've been working with routers, switches and other CISCO’s peripherals for a
long time ago. The Operating System of these peripherals is IOS (InterNetwork
Operating System). I've always been using IOS without knowing the inner working
of it. However, I recently read an article about CISCO’s IOS going open soon
with an API for third party developers (&lt;a href=&quot;http://www.networkworld.com/news/2007/121207-cisco-ios.html&quot;&gt;http://www.networkworld.com/news/2007/121207-cisco-ios.html&lt;/a&gt;).
I thought, hey ! That would be interesting to know how the inner works take
place inside this O.S. Embedded Event Manager (&lt;a href=&quot;http://forums.cisco.com/eforum/servlet/EEM?page=main&quot;&gt;http://forums.cisco.com/eforum/servlet/EEM?page=main&lt;/a&gt;)
is already an API that enables developers to react on specific events of the
IOS: &lt;a href=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospart1-11d2bimage-2.png&quot;&gt;
&lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/windowslivewriterciscoiospart1-11d2bimage-thumb.png&quot; alt=&quot;image&quot; style=&quot;border-width: 0&quot; height=&quot;268&quot; width=&quot;360&quot; /&gt;&lt;/a&gt;
&lt;h6&gt;&lt;strong&gt;Figure from Cisco IOS Network Management Configuration Guide,
Release 12.4T (&lt;a href=&quot;http://www.cisco.com/en/US/products/ps6441/products_configuration_guide_chapter09186a00807c676c.html&quot;&gt;source&lt;/a&gt;)&lt;/strong&gt;&lt;/h6&gt;
As we can see on the figure above, we can react to an event (CLI, SYSLOG, OIR,
TIMER, …) or we can enhance the CLI by registering our script/applet as a
command:
&lt;blockquote&gt;
&lt;p&gt;Router(config)#alias exec &lt;strong&gt;my_cli_command&lt;/strong&gt; event manager run
&lt;strong&gt;my_eem_applet&lt;/strong&gt; Router#&lt;strong&gt;ma_cli_command&lt;/strong&gt; will
execute &lt;strong&gt;my_eem_applet&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
But with the IOS’s opening, we will be able to interact with the whole pieces
of the IOS (not only events) and perhaps act as a process. We may be able to
register as an Interrupt Handler … In the next post, I’ll detail the inner
working of the IOS.</description>
    
    
    
      </item>
    
  <item>
    <title>CISCO IOS (Partie 5)</title>
    <link>http://blog.section9.be/post/2008/01/20/CISCO-IOS-%28Partie-5%29</link>
    <guid isPermaLink="false">urn:md5:46d7c6a44704d885e3edc02fe1610679</guid>
    <pubDate>Sun, 20 Jan 2008 19:45:00 +0100</pubDate>
    <dc:creator>Mathieu</dc:creator>
        <category>Networking</category>    
    <description>    Lorsque l’on alloue de la mémoire à un processus (malloc), Le Pool Manager
prend une zone de mémoire libre et l’attribue à un processus. Le Pool Manager
tient donc une table de blocs de mémoire contigus. Lorsqu’un processus libère
une zone mémoire (free), le Pool Manager essaie de concaténer la zone de
mémoire fraichement libérée avec ses voisines. Malgré cette concaténation une
fragmentation est inévitable. Une mémoire extrêmement fragmentée peut mener à
des erreurs de malloc « &lt;a href=&quot;http://www.cisco.com/warp/public/63/mallocfail.shtml&quot;&gt;%SYS-2-MALLOCFAIL&lt;/a&gt; ».
En effet, il se peut qu’il y ait suffisamment de mémoire disponible, mais pas
de blocs contigus suffisant pour permettre la taille de malloc demandée.
&lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/WindowsLiveWriter_CISCOIOSPartie5_13EF5_image_3.png&quot; alt=&quot;image&quot; style=&quot;border-width: 0&quot; height=&quot;324&quot; width=&quot;508&quot; /&gt; &lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/WindowsLiveWriter_CISCOIOSPartie5_13EF5_image_6.png&quot; alt=&quot;image&quot; style=&quot;border-width: 0&quot; height=&quot;324&quot; width=&quot;508&quot; /&gt; &lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/WindowsLiveWriter_CISCOIOSPartie5_13EF5_image_9.png&quot; alt=&quot;image&quot; style=&quot;border-width: 0&quot; height=&quot;324&quot; width=&quot;508&quot; /&gt; Dans ce dernier
exemple, il n’y a que des petits blocs non contigus libérés, résultat : Si un
processus désire allouer une zone mémoire plus importante, il ne pourra pas le
faire et nous aurons un « MALLOCFAIL ». Le Chunk Manager va permettre de régler
ces soucis en allouant plus intelligemment la mémoire aux processus. Le Chunk
Manager est responsable de l’allocation de Chunk. Un Chunk contient un nombre
de blocs finis de taille égale. Si on utilise tous les blocs présents dans un
Chunk, le Chunk Manager alloue un nouvel espace (Sibling). Si plus aucun des
blocs de ce « Sibling » n’est utilisé, il est libéré « Freed/Trimmed ». Un
processus se voit donc attribuer une plus grande zone mémoire découpée en plus
petits blocs. Lorsque le processus libère un bloc, il le fait dans son Chunk.
Il n’y a donc plus de fragmentation entre différents processus. &lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/WindowsLiveWriter_CISCOIOSPartie5_13EF5_image_12.png&quot; alt=&quot;image&quot; style=&quot;border-width: 0&quot; height=&quot;304&quot; width=&quot;376&quot; /&gt;
&lt;pre&gt;
#show chunk
Chunk Manager:  407660 chunks created, 406281 chunks destroyed  9349 siblings created, 406279 siblings trimmed
Chunk          element  Block   Maximum  Element  Element
Total Cfgsize   Ohead    size   element    inuse   freed  Ohead    Name
16               4       940       33        2      31     360   String-DB owne 0x654C2408
16               4       940       33        0      33     360   String-DB cont 0x654C27B4
312              16    65588      197       38     159    4072   Extended ACL e 0x654C3484
96               16    20052      171        9     162    3584   ACL Header 0x654D34B8
8536             0     65588        7        1       6    5784   Parseinfo Bloc 0x654DA14C
16               0       456       15        1      14     164   tokenQ node 0x654EA180
20               0       456       13       13       0     144   Chain Cache No 0x654EA348
20               0       456       13        6       7     144   (sibling) 0x66BD0E50
20               0       460       13       13       0     148   (sibling) 0x66F33EE0
&lt;/pre&gt;
Au sein d’un Chunk, les blocs possèdent un header (ou non taille=0). La taille
du header par Chunk est fixe (0, 4, 16, 20, 24). Ex : ACL Header, un Chunk de
maximum 171 éléments avec 96 éléments au départ. Chaque bloc possède un header
de 16 Bytes et pèse 20.052 Bytes. J’ai actuellement 9 blocs utilisés dans ce
Chunk. Prochain post : Les Buffers.</description>
    
    
    
      </item>
    
  <item>
    <title>CISCO IOS (Partie 4)</title>
    <link>http://blog.section9.be/post/2008/01/06/CISCO-IOS-%28Partie-4%29</link>
    <guid isPermaLink="false">urn:md5:db409f57a2a6f3e978f44a81d75b9a11</guid>
    <pubDate>Sun, 06 Jan 2008 16:58:00 +0100</pubDate>
    <dc:creator>Mathieu</dc:creator>
        <category>Networking</category>    
    <description>    Tout Operating System possède un système de gestion mémoire. Les Operating
Systems récents travaillent avec de la mémoire protégée. Un processus x ne peut
pas accéder à la mémoire d’un processus y. Pour que le processus x dialogue
avec le processus y, ils vont devoir employer d’autres méthodes (Shared Memory,
Message Queues, Pipes, Network Connections, …). Ces méthodes sécurisent les
processus entre-euxs mais ralentissent néanmoins leurs fonctionnements. L’IOS
ne gère pas la mémoire partagée, tous les processus ont accès à la mémoire sans
restrictions. Un processus est donc libre de dialoguer avec un autre en
écrivant dans la mémoire de ce dernier (Buffer Overflow = Crash, j’y reviendrai
avec la notion de bloc). Il existe néanmoins une notion de mémoire R/O et R/W.
L’IOS travaille avec des pools de mémoire, c’est le Pool Manager qui en est
responsable :
&lt;pre&gt;
#show memory
Head       Total(b)     Used(b)    Free(b)    Lowest(b)   Largest(b)
Processor
653B8C20   155481056    86243592   69237464   68168948    67670028
I/O
EE800000    25165824     5269012   19896812   19819968    19871932
&lt;/pre&gt;
Ici, un pool réservé au processor et un pool réservé aux I/O:
&lt;ul&gt;
&lt;li&gt;Head : début du pool&lt;/li&gt;
&lt;li&gt;Total : taille du pool en bytes&lt;/li&gt;
&lt;li&gt;Used : utilisation actuelle du pool en bytes&lt;/li&gt;
&lt;li&gt;Free : mémoire libre actuelle du pool en bytes&lt;/li&gt;
&lt;li&gt;Lowest : mémoire libre historiquement la plus basse en bytes&lt;/li&gt;
&lt;li&gt;Largest : le plus grand bloc de mémoire libre contigüe&lt;/li&gt;
&lt;/ul&gt;
Ces mêmes pools appartiennent à des régions de mémoires gérées par le Region
Manager :
&lt;pre&gt;
#show region
Region Manager:
Start       End            Size(b)  Class  Media  Name
0x0E800000  0x0FFFFFFF    25165824  Iomem  R/W    iomem:(iomem)
0x60000000  0x6E7FFFFF   243269632  Local  R/W    main
0x6000F000  0x632FFFFF    53415936  IText  R/O    main:text
0x63300000  0x64DFFCFF    28310784  IData  R/W    main:data
0x64DFFD00  0x653B8C1F     6000416  IBss   R/W    main:bss
0x653B8C20  0x6E7FFFFF   155481056  Local  R/W    main:heap
0x80000000  0x8E7FFFFF   243269632  Local  R/W    main:(main_k0)
0xA0000000  0xAE7FFFFF   243269632  Local  R/W    main:(main_k1)
0xEE800000  0xEFFFFFFF    25165824  Iomem  R/W    iomem
&lt;/pre&gt;
Le pool de mémoire Processor est donc compris dans la région
&lt;em&gt;main:heap&lt;/em&gt;. Cette région fait partie de la région &lt;em&gt;main&lt;/em&gt; qui
commence en 0x60000000 et finit en 0x6E7FFFFF. Le pool de mémoire I/O
représente la région &lt;em&gt;iomem&lt;/em&gt; de 0xEE800000 à 0xEFFFFFFF. Dans la région
&lt;em&gt;main&lt;/em&gt;, on trouve :
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;main:text&lt;/em&gt; : contient le code de l’IOS en R/O (IText)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;main:data&lt;/em&gt; : contient les variables initialisées R/W (IData)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;main:bss&lt;/em&gt; : contient les variables non initialisées R/W (IBss)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;main:heap&lt;/em&gt; : contient les structures de mémoire standard locales
R/W&lt;/li&gt;
&lt;li&gt;&lt;em&gt;iomem&lt;/em&gt; : contient la mémoire des périphériques (mémoire pour le bus
I/O)&lt;/li&gt;
&lt;/ul&gt;
On peut remarquer que certaines régions sont redondantes: &lt;em&gt;main:(main_k0) ;
main:(main_k1) ;&lt;/em&gt; Elles correspondent toutes à la même région
&lt;em&gt;main&lt;/em&gt;. On peut aussi retrouver &lt;em&gt;iomem&lt;/em&gt; à deux endroits
différents : 0x0E800000-&amp;gt;0x0FFFFFFF et 0xEE800000-&amp;gt;0xEFFFFFFF, il s’agit
pourtant de la même zone mémoire. D’un périphérique CISCO à un autre, l’endroit
où est stocké tel ou tel type de mémoire diffère. Sur un type de routeur on
peut trouver de la mémoire SRAM pour &lt;em&gt;iomem&lt;/em&gt;, tandis que dans d’autres
pour la même zone on trouvera de la mémoire DRAM. Le Pool Manager définit des
zones mémoires indépendamment du type de mémoire utilisé (hardware
abstraction). Revenons au Pool Manager. En utilisant la commande « show memory
processor », on peut remarquer que la mémoire est subdivisée en blocs :
&lt;pre&gt;
#show memory processor
Processor memory
Address      Bytes     Prev     Next Ref     PrevF    NextF  Alloc PC  what
65A817E0 0000000084 65A8175C 65A81864 001  -------- -------- 628215E8  Init
65A81864 0000001372 65A817E0 65A81DF0 001  -------- -------- 608E3218  Skinny Socket Server
65A81DF0 0000001156 65A81864 65A822A4 001  -------- -------- 608E3218  Skinny Socket Server
&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Address : début du bloc&lt;/li&gt;
&lt;li&gt;Bytes : taille du bloc&lt;/li&gt;
&lt;li&gt;Prev : adresse du bloc précédent (chaînage)&lt;/li&gt;
&lt;li&gt;Next : adresse du bloc suivant (chaînage)&lt;/li&gt;
&lt;li&gt;Ref : par combien de processus ce bloc est-il utilisé ?&lt;/li&gt;
&lt;li&gt;PrevF : bloc libre précédent&lt;/li&gt;
&lt;li&gt;NextF : bloc libre suivant&lt;/li&gt;
&lt;li&gt;Alloc PC : processus ayant alloué ce bloc&lt;/li&gt;
&lt;li&gt;What : nom du processus détenant le bloc&lt;/li&gt;
&lt;/ul&gt;
Inspectons de plus près un bloc mémoire :
&lt;pre&gt;
#show memory 0x65A81864
65A81860:          AB1234CD 010B0000 66B4EBEC      +.4M....f4kl
65A81870: 6395634C 608E3218 65A81DF0 65A817F4  c.cL`.2.e(.pe(.t
65A81880: 800002AE 00000001 605C3DD4 00000112  ........`=T.... ...
65A81DE0:                            FD0110DF              }.._
&lt;/pre&gt;
Après quelques recherches on devine déjà les champs du header de bloc :
&lt;pre&gt;
65A81860:            [MAGIC  ]  [PID   ] [?       ]
65A81870: [PTR_NAME] [ALLOCPC]  [NEXT  ] [PREV+20d]
65A81880: [SIZE*] [REF ] [?  ] [ DATA -&amp;gt;] ...
65A81DE0:                     [&amp;lt;- DATA] [MAGIC   ]
&lt;/pre&gt;
&lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/WindowsLiveWriter_CISCOIOSPartie4_1391D_image_3.png&quot; alt=&quot;image&quot; style=&quot;border-width: 0&quot; height=&quot;340&quot; width=&quot;111&quot; /&gt;
&lt;ul&gt;
&lt;li&gt;MAGIC_START est toujours 0xAB1234CD&lt;/li&gt;
&lt;li&gt;PID : l’id du processus&lt;/li&gt;
&lt;li&gt;[ PLACEHOLDER ]&lt;/li&gt;
&lt;li&gt;PTR PS_ NAME : pointeur vers le nom du processus détenant le bloc&lt;/li&gt;
&lt;li&gt;ALLOC_PC : même valeur que dans la commande « show memory processor »&lt;/li&gt;
&lt;li&gt;NEXT : pointeur vers le prochain bloc&lt;/li&gt;
&lt;li&gt;PREV : pointeur vers le précédent bloc + 20d (directement sur le champ next
du précédent)&lt;/li&gt;
&lt;li&gt;SIZE : renferme une petite subtilité, le MSB (Most Significant Bit) de ce
champ est un flag qui positionné à 1 indique que ce bloc est utilisé. De plus
la valeur lue dans ce champ diffère de la valeur affichée avec la commande «
show memory processor ». Pour obtenir la valeur correcte je dois faire :
(valeur lue)*2+4 ????&lt;/li&gt;
&lt;li&gt;REF : combien de processus utilisent ce bloc&lt;/li&gt;
&lt;li&gt;[ PLACEHOLDER ]&lt;/li&gt;
&lt;li&gt;DATA : les données …&lt;/li&gt;
&lt;li&gt;MAGIC_END est toujours 0xFD0110DF (palindrome en hexa)&lt;/li&gt;
&lt;/ul&gt;
Par exemple en partant de ce bloc, si je veux atteindre le suivant sans
utiliser le pointeur Next, je dois faire : Adresse du bloc +
sizeof(magic_start) + sizeof(header) + (2*[valeur du champ
size]+4)+sizeof(magic_end) Soit: 0x65A81864+0x4+0x24+0x560+0x4=0x65A81DF0
Vérification du contenu du champ PID:
&lt;pre&gt;
#show process 0x0000010B [010B &amp;lt;&amp;gt; 0000]
Process ID 267 [Skinny Socket Server],
TTY 0
Memory usage [&lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; bytes] Holding: 89644, Maximum: 109468, Allocated: 6601380, Freed: 6514500
Getbufs: 0,
Retbufs: 0,
Stack: 8908/12000
CPU usage PC: 60846DE4, Invoked: 26, Giveups: 1, uSec: 9384 5Sec: 0.00%, 1Min: 0.00%, 5Min: 0.00%, Average: 0.00% Age: 5007208 msec,
Runtime: 244 msec
State: Waiting &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; Event, Priority: Normal
&lt;/pre&gt;
Vérification du contenu du champ PTR PS_NAME:
&lt;pre&gt;
#show memory 0x6395634C
63956340:                            536B696E              Skin
63956350: 6E792053 6F636B65 74205365 72766572  ny Socket Server
63956360: 00000000 0A496E76 616C6964 20736B69  .....Invalid ski
-&amp;gt;Skinny Socket Server
&lt;/pre&gt;
Vérification que nous arrivons bien à la fin du bloc (présence d’un magic
number FD0110DF) :
&lt;pre&gt;
0x65A81864 + 2*[SIZE]+4 + SIZEOF(MAGICSTART) + [HEADERSIZE] = 0x65A81864 + 0X560 + 0x4 + 0x24
#show memory 0x65A81DEC
65A81DE0:                            FD0110DF              }.._
&lt;/pre&gt;
S'il nous venait à l’idée de réaliser un buffer overflow dans une zone mémoire,
donc écrire plus de bytes prévu que ceux alloués pour cette zone mémoire, on
finirait par écraser le header de la prochaine zone mémoire et donc rompre le
chaînage mémoire IOS. Hélas, ou pas, l’IOS vérifie en permanence la structure
de sa mémoire et à la moindre incohérence, force un crash. Donc pour réussir un
buffer overflow sans crash, il faut s’arranger pour réécrire un header cohérant
sur la prochaine zone mémoire. Ne pas oublier non plus de faire un « jmp » pour
sauter à la suite de son code juste après le header ! &lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/WindowsLiveWriter_CISCOIOSPartie4bis_14E2C_image_6.png&quot; alt=&quot;image&quot; style=&quot;border: 0&quot; height=&quot;350&quot; width=&quot;575&quot; /&gt; Le post suivant
parlera du « chunk manager » de l’IOS.</description>
    
    
    
      </item>
    
  <item>
    <title>CISCO IOS (Partie 3)</title>
    <link>http://blog.section9.be/post/2008/01/05/CISCO-IOS-%28Partie-3%29</link>
    <guid isPermaLink="false">urn:md5:c4c2800993345d3b74f0a1ab2549a6d2</guid>
    <pubDate>Sat, 05 Jan 2008 20:57:00 +0100</pubDate>
    <dc:creator>Mathieu</dc:creator>
        <category>Networking</category>    
    <description>    Comme dit dans mon précédent post il existe 4 priorités de processus, et donc
une file par priorité. Une file représente un nombre &lt;em&gt;n&lt;/em&gt; de processus de
priorité &lt;em&gt;x&lt;/em&gt; en Ready State.
&lt;pre&gt;
#sh processes
PID     QTy PC          Runtime (ms) Invoked uSecs      Stacks          TTY     Process
22      Mwe 628250A4    0               1       0       2516/3000       0       RMI RM Notify Wa
23      Hwe 60092C38    0               2       0       5508/6000       0       SMART
24      Msp 612FAFB0    76              170778  0       5540/6000       0       GraphIt
25      Mwe 613B193C    0               2       0       11504/12000     0       Dialer event
26      Mwe 624E81B0    0               1       0       5540/6000       0       SERIAL A'detect
27      Mwe 62AC6984    0               2       0       11516/12000     0       XML Proxy Client
28      M*      0       456             153298  0       9356/12000      194     SSH Process
29      Mwe 602AFC70    0               1       0       2484/3000       0       Inode Table Dest
30      Cwe 62818F90    0               1       0       5548/6000       0       Critical Bkgnd
31      Mwe 6033D7D8    96              102962  0       10208/12000     0       Net Background
32      Mwe 6033DA68    0               2       0       11420/12000     0       IDB Work
33      Lwe 6128EEEC    2184            9209    237     10088/12000     0       Logger
&lt;/pre&gt;
Dans ce « &lt;a target=&quot;_blank&quot; href=&quot;http://www.cisco.com/warp/public/63/showproc_cpu.html#showproc&quot;&gt;show
processes&lt;/a&gt; » on peut voir les 4 priorités de processus ainsi que le
processus en Running State. Dans la colonne Q :
&lt;ul&gt;
&lt;li&gt;L : Low Priority (background process non utile au fonctionnement du
routeur)&lt;/li&gt;
&lt;li&gt;M : Medium Priority (priorité par défaut)&lt;/li&gt;
&lt;li&gt;H : High Priority (processus agissant par exemple sur les paquets
reçus)&lt;/li&gt;
&lt;li&gt;C : Critical Priority (allocation de ressources, processus cœur du
système)&lt;/li&gt;
&lt;li&gt;K : Killed&lt;/li&gt;
&lt;li&gt;D : Crashed&lt;/li&gt;
&lt;li&gt;X : Corrupted&lt;/li&gt;
&lt;/ul&gt;
Dans la colonne Ty :
&lt;ul&gt;
&lt;li&gt;* : Processus en Running State&lt;/li&gt;
&lt;li&gt;S : Processus qui a fait appel à un Suspend&lt;/li&gt;
&lt;li&gt;E : Processus qui attend un évènement&lt;/li&gt;
&lt;li&gt;rd : Processus en Ready State&lt;/li&gt;
&lt;li&gt;we : Processus en Idle State qui attend un évènement&lt;/li&gt;
&lt;li&gt;sa : Processus en Idle State qui attend une certaine heure&lt;/li&gt;
&lt;li&gt;si : Processus en Idle State qui attend la fin d’un intervalle&lt;/li&gt;
&lt;li&gt;sp : Processus en Idle State qui attend la fin d’un intervalle
périodique&lt;/li&gt;
&lt;li&gt;st : Processus en Idle State qui attend l’expiration d’un timer&lt;/li&gt;
&lt;li&gt;hg : Processus bloqué&lt;/li&gt;
&lt;li&gt;xx : Processus Dead&lt;/li&gt;
&lt;/ul&gt;
Les autres colonnes :
&lt;ul&gt;
&lt;li&gt;PID : Process ID …&lt;/li&gt;
&lt;li&gt;PC : pointeur vers le code du processus, là où le CPU s’était arrêté la
fois passée (0 = running)&lt;/li&gt;
&lt;li&gt;Runtime : temps total que le processus à occupé sur le CPU&lt;/li&gt;
&lt;li&gt;Invoked : nombre de fois que le processus est passé en Running State&lt;/li&gt;
&lt;li&gt;uSec : temps moyen sur le CPU à chaque passage&lt;/li&gt;
&lt;li&gt;Stacks : utilisation du stack par le processus /taille totale du stack pour
ce processus&lt;/li&gt;
&lt;li&gt;TTY : ce processus est-il relié à un STDIN/STDOUT, si oui, la valeur est
différente de 0 et pointe vers le TTY/VTY spécifié (#show line pour le
visualiser).&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
#show line
Tty     Line    Typ Tx/Rx       A Modem Roty AccO AccI  Uses    Noise Overruns    Int
0       0       CTY             -     -          -       -      -       0       0       0/0     -
1       1       AUX 9600/9600   -     -          -       -      -       0       0       0/0     -
*194    194     VTY             -     -          -       -      -       3       0       0/0     -
195     195     VTY             -     -          -       -      -       0       0       0/0     -
196     196     VTY             -     -          -       -      -       0       0       0/0     -
&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Process : nom du processus&lt;/li&gt;
&lt;/ul&gt;
Revenons au scheduler : &lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/WindowsLiveWriter_CISCOIOSPartie3_1484E_image_3.png&quot; alt=&quot;image&quot; style=&quot;border-width: 0&quot; height=&quot;245&quot; width=&quot;556&quot; /&gt; 1. Le scheduler
démarre avec le Critical Priority Stack et exécute tous les processus s’y
trouvant. 2. S’il n’y a plus rien dans Critical, le scheduler passe au High
Priority Stack et exécute le premier processus. Une fois le premier processus
exécuté, le scheduler vérifie la présence de processus dans la Critical Stack.
S’il y en a, le scheduler les exécute. Le scheduler peut donc passer au
processus suivant du High Priority Stack. Le scheduler vérifie après chaque
processus High Priority Stack la présence de processus de plus haut niveau pour
les exécuter. 3. S’il n’y a plus de processus Critical, ni de processus High,
le scheduler passe au Medium Priority Stack. Entre chaque processus du Medium
Priority Stack, le scheduler vérifie la présence de processus dans le High
Priority Stack. S’il y en a, il exécute le premier puis vérifie la présence de
processus dans le Critical Priority Stack et les exécute tous. Une fois le
Critical vide, il passe au High Priority suivant, etc … 4. S’il n’y a plus de
processus Critical, ni de processus High, ni de processus Medium, le scheduler
passe au Low Priority Stack. (A savoir que si l’on vient du Medium Priority
Stack on ne passe pas au Low Priority Stack. A la fin du Medium on passe au
Critical Priority Stack, lorsque cette étape a été réalisée 15 fois on passe
finalement au Low Priority Stack – Ca c’est du LOW). Entre chaque processus en
Low Priority le scheduler vérifie le Medium Stack et exécute les processus du
Medium Stack entre-lesquels le scheduler vérifie la présence de processus dans
le High Stack et les exécute tout en vérifiant entre chaque processus High la
présence de processus Critical pour les exécuter tous avant de passer au
suivant High. 5. On retourne à l’étape 1. Si un processus devient fou (&amp;gt;4sec
sur le CPU), pas de problèmes ! Le WatchDog Timer est là pour l’interrompre !
Le WatchDog Timer est exécuté via une interrupt (toutes les 4msec via le system
timer), donc plus prioritaire que n’importe quel processus. La notification
d’arrivée de paquet est aussi une interrupt. Ainsi l’IOS peut directement
traiter le paquet. Je reviendrai prochainement sur les méthodes existantes de
Switching de Paquets. Prochain post: l’organisation mémoire de l’IOS.</description>
    
    
    
      </item>
    
  <item>
    <title>CISCO IOS (Partie 2)</title>
    <link>http://blog.section9.be/post/2008/01/04/CISCO-IOS-%28Partie-2%29</link>
    <guid isPermaLink="false">urn:md5:0cf3f8a20d1f86ae51d0ee61f1b6027c</guid>
    <pubDate>Fri, 04 Jan 2008 20:05:00 +0100</pubDate>
    <dc:creator>Mathieu</dc:creator>
        <category>Networking</category>    
    <description>    Comme tout OS, l’IOS doit implémenter un certain nombre de principes
élémentaires :
&lt;ul&gt;
&lt;li&gt;Gestion de processus&lt;/li&gt;
&lt;li&gt;Gestion de la mémoire&lt;/li&gt;
&lt;li&gt;Gestion des périphériques&lt;/li&gt;
&lt;li&gt;Interface Utilisateur&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
Parlons des processus, l’IOS est un Operating System multitâches coopératif
(non préemptif). Chaque processus est donc responsable de laisser le processeur
au processus suivant. L’IOS ne connaît pas la notion de multithreading (1
processus = 1 thread). Afin de pouvoir rapidement switcher des paquets d’une
interface à une autre, l’IOS utilise le mécanisme des interruptions. Dès qu’un
paquet arrive sur une interface, une interruption est levée. Le processeur a
donc la possibilité de traiter le paquet en priorité. Le fait qu’un processus
soit responsable de son temps sur le processeur peut ouvrir la porte à beaucoup
de problèmes si ce processus entre, par exemple, dans une boucle infinie. L’IOS
a pour ce cas de figure un watchdog timer qui peut terminer un processus si
celui-ci prend trop de temps sur le CPU (par défaut 2*2sec). Un processus
possède 6 états:
&lt;ul&gt;
&lt;li&gt;Create State
&lt;ul&gt;
&lt;li&gt;Le processus est créé par le Kernel ou par le Parser (cli / config)&lt;/li&gt;
&lt;li&gt;Allocation de ressources&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Modify State (optionel)
&lt;ul&gt;
&lt;li&gt;On ajoute un terminal au processus (pas de std ::in/out/err par défaut lors
d’un create)&lt;/li&gt;
&lt;li&gt;On lui passe certains paramètres&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ready State
&lt;ul&gt;
&lt;li&gt;Le processus est prêt à être lancé sur le processeur&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Running State
&lt;ul&gt;
&lt;li&gt;Le processus est sur le processeur&lt;/li&gt;
&lt;li&gt;Il peut:
&lt;ul&gt;
&lt;li&gt;Cèder sa place volontairement (Suspend). Il retourne en Ready State.&lt;/li&gt;
&lt;li&gt;Terminer son exécution à la fin de sa tâche (Run to completion)&lt;/li&gt;
&lt;li&gt;Se mettre en attente d’un évènement (Idle State)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Idle State
&lt;ul&gt;
&lt;li&gt;Le processus attend un évènement spécifique (Wait for External Event)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dead State
&lt;ul&gt;
&lt;li&gt;Le processus s’est terminé lui-même (Self Termination)&lt;/li&gt;
&lt;li&gt;Le processus a été tué par le Kernel (Killed)&lt;/li&gt;
&lt;li&gt;Le processus a terminé son travail (Run to completion)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
Cycle de vie d’un processus : &lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/WindowsLiveWriter_CiscoIOSPartie2_D32_image_3.png&quot; alt=&quot;image&quot; height=&quot;418&quot; width=&quot;579&quot; /&gt; Il existe 4 priorités (une file
FIFO/priorité) de processus afin d’en favoriser certains par rapport à d’autres
:
&lt;ul&gt;
&lt;li&gt;Critical&lt;/li&gt;
&lt;li&gt;High&lt;/li&gt;
&lt;li&gt;Medium&lt;/li&gt;
&lt;li&gt;Low&lt;/li&gt;
&lt;/ul&gt;
Le scheduler est responsable de retirer un processus en Ready State d’une file
de priorité et de l’exécuter sur le CPU (Running State). &lt;strong&gt;&lt;ins&gt;Notes
:&lt;/ins&gt;&lt;/strong&gt; Sur toutes les sources que j’ai consultées il y a seulement 4
priorités, or, lorsque l’on utilise la commande :
&lt;pre&gt;
#show list | inc Sched
8 650F2910 0/- Sched Preemptive
9 650F2310 0/- Sched Critical
10 650F21F0 0/- Sched High
11 650F1C10 2/- Sched Normal
12 650F1C60 0/- Sched Low
13 650F1E10 0/- Sched Preemptive ION
14 650F2180 262/- Sched Idle
15 650F0800 0/- Sched Dead
16 6535B660 0/- Sched Normal (Old)
17 6535B6C0 0/- Sched Low (Old)
&lt;/pre&gt;
On se rend compte qu’il existe une file appelée « Sched Preemptive ». Cette
liste va à l’encontre du fait que l’IOS est non préemptif ! (Mes sources sont
peut-être aussi un peu anciennes !) La commande permet aussi de bien visualiser
les files et notamment le nombre de processus présents respectivement dans
chacune d’elles. J’ai donc 262 processus en Idle State et 2 processus de
priorité « Normal » en Ready State. Un processus passant à l’état « Dead » ne
voit pas automatiquement ses ressources libérées, ceci explique sans doute la
nécessité de garder une trace des processus « Dead » dans une file du même nom.
Dans mon prochain post, j’expliquerai le fonctionnement du scheduler IOS.</description>
    
    
    
      </item>
    
  <item>
    <title>CISCO IOS (Partie 1)</title>
    <link>http://blog.section9.be/post/2008/01/02/CISCO-IOS-%28Partie-1%29</link>
    <guid isPermaLink="false">urn:md5:85fef462e2ce50d6f7337dabf1e090e7</guid>
    <pubDate>Wed, 02 Jan 2008 08:53:00 +0100</pubDate>
    <dc:creator>Mathieu</dc:creator>
        <category>Networking</category>    
    <description>    Depuis déjà longtemps je travaille sur des routeurs, switches, et autres
périphériques CISCO. L’Operating System de ces périphériques est l’IOS
(InterNetwork Operating System). Bien que j’utilise cet IOS depuis le départ je
ne me suis jamais vraiment attardé sur son fonctionnement interne. Or, il y a
peu, j’ai lu un article sur le fait que CISCO allait probablement ouvrir
l’accès à l’IOS aux développeurs tiers via une API (&lt;a target=&quot;_blank&quot; href=&quot;http://www.networkworld.com/news/2007/121207-cisco-ios.html&quot;&gt;http://www.networkworld.com/news/2007/121207-cisco-ios.html&lt;/a&gt;),
je me suis dit qu’il serait donc intéressant de décortiquer un peu le
fonctionnement de cet O.S. Embedded Event Manager (&lt;a target=&quot;_blank&quot; href=&quot;http://forums.cisco.com/eforum/servlet/EEM?page=main&quot;&gt;http://forums.cisco.com/eforum/servlet/EEM?page=main&lt;/a&gt;)
est déjà une API qui permet aux développeurs de réagir sur certains évènements
de l’IOS : &lt;a href=&quot;http://blog.section9.be/public/uploads/WindowsLiveWriter_CISCOIOSPartie1_C158_clip_image001_2.jpg&quot;&gt;
&lt;img border=&quot;0&quot; src=&quot;http://blog.section9.be/public/uploads/WindowsLiveWriter_CISCOIOSPartie1_C158_clip_image001_thumb.jpg&quot; alt=&quot;clip_image001&quot; style=&quot;border-width: 0&quot; height=&quot;254&quot; width=&quot;340&quot; /&gt;&lt;/a&gt;
&lt;h6&gt;Schéma provenant du Cisco IOS Network Management Configuration Guide,
Release 12.4T (&lt;a target=&quot;_blank&quot; href=&quot;http://www.cisco.com/en/US/products/ps6441/products_configuration_guide_chapter09186a00807c676c.html&quot;&gt;source&lt;/a&gt;)&lt;/h6&gt;
Comme on peut le voir, soit on réagit à un évènement (CLI, SYSLOG, OIR, TIMER,
…) soit on enrichit le CLI en enregistrant son script/applet comme commande :
&lt;blockquote&gt;
&lt;p&gt;Router(config)#alias exec &lt;strong&gt;ma_commande_cli&lt;/strong&gt; event manager run
&lt;strong&gt;mon_applet_eem&lt;/strong&gt; Router#&lt;strong&gt;ma_commande_cli&lt;/strong&gt; à
exécution de l’applet &lt;strong&gt;mon_applet_eem&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
Mais avec l’ouverture de l’IOS on va théoriquement pouvoir interagir avec
l’ensemble des éléments de l’IOS, plus seulement avec des events, mais sans
doute en tant que processus. On pourra peut-être aussi s’enregistrer en tant
qu’Interrupt Handler… Dans les prochains posts je détaillerai le fonctionnement
de l’IOS.</description>
    
    
    
      </item>
    
</channel>
</rss>
