Simple SNMP Query Tool - Open Source - C# (C-sharp)
RFC downloader and MIB extractor module
// Author: Toomas Kaljus
// http://www.digigrupp.com
namespace DG
{
public class Rfc2Mib
{
public void DownloadAndExtract(string RFCPath, string MIBPath, string RFCUrl, int RFCFirstNumber, int RFCLastNumber, bool ExtractOnly)
{
System.Net.WebClient WebClient = new System.Net.WebClient();
for (int rfc = RFCFirstNumber; rfc <= RFCLastNumber; rfc++)
{
// download rfc texts
string Filename = RFCPath + "\\rfc" + rfc + ".txt";
if ((ExtractOnly) || (!System.IO.File.Exists(Filename)))
{
if (!ExtractOnly) try
{
System.Console.Write(("Downloading RFC" + rfc).PadRight(79) + "\r");
WebClient.DownloadFile(RFCUrl.Replace("{n}", rfc.ToString()), Filename + ".~");
System.IO.File.Move(Filename + ".~", Filename);
}
catch
{
System.Console.Error.WriteLine(("Error downloading RFC" + rfc).PadRight(79));
}
if (System.IO.File.Exists(Filename))
{
System.Console.Write(("Reading RFC" + rfc).PadRight(79) + "\r");
string Buffer;
using (System.IO.StreamReader StreamReader = new System.IO.StreamReader(Filename)) Buffer = StreamReader.ReadToEnd();
// remove form-feeds (page breaks)
string[] Pages = Buffer.Split((char)0x0c);
for (int p = 0; p < Pages.Length; p++)
{
string[] Lines = Pages[p].Split((char)0x0a);
if (p > 0) for (int l = 0; l < 10; l++)
{
if (l >= Lines.Length) break;
if (Lines[l].Trim().StartsWith("RFC " + rfc))
{
Lines[l] = "";
break;
}
if (Lines[l].Trim() != "") break;
}
if (p < Pages.Length - 1) for (int l = Lines.Length - 1; l > Lines.Length - 10; l--)
{
if (l == -1) break;
if (Lines[l].Trim().EndsWith("]")) // "[Page " + (p + 1) + "]" is not working for some RFC-s as some pages have roman numbers
if (Lines[l].Trim().IndexOf("[Page ") > 0)
{
Lines[l] = "";
break;
}
if (Lines[l].Trim() != "") break;
}
Pages[p] = string.Join("\n", Lines);
}
Buffer = string.Join("\n", Pages);
string FileBuffer = "";
string Data = "";
string MIBName = "";
// search for DEFINITIONS
int i = Buffer.IndexOf("DEFINITIONS");
while (i > 0)
{
// search for BEGIN
int ib = SearchForBEGIN(Buffer, i + 11, 128);
if (ib < 0) break;
// search for END
int ie = SearchForEND(Buffer, ib + 5);
if (ie < 0) break;
// resolve MIB name
string Name = "";
int n = i - 1;
int Ident = 0;
do
{
while ((n > 0) && (Buffer[n] > ' ')) n--;
while ((n > 0) && (Buffer[n - 1] <= ' ')) n--;
if ((n > 0) && (Buffer[n - 1] == '}')) while ((n > 0) && Buffer[n] != '{') n--;
while ((n > 0) && (Buffer[n - 1] <= ' ')) n--;
int n2 = n;
while ((n > 0) && (Buffer[n - 1] >= ' ')) n--;
Name = Buffer.Substring(n, n2 - n);
while (Name[Ident] == ' ') Ident++;
Name = Name.Trim();
} while (Name.StartsWith("--"));
Data = Buffer.Substring(n + Ident, ie - n + 3 - Ident).Replace("\n" + ("".PadRight(Ident, ' ')), "\n");
int z = Data.LastIndexOf("\n\n\n");
while (z >= 0)
{
Data = Data.Remove(z, 1);
z = Data.LastIndexOf("\n\n\n", z + 3);
}
// older rfcs sometimes publish more than one mib with same name
if (Name != MIBName)
{
FileBuffer =
"-- Source: " + ((ExtractOnly) ? "rfc" + rfc + ".txt" : RFCUrl.Replace("{n}", rfc.ToString())) + "\n" +
"-- Date extracted: " + System.DateTime.Now.ToString("yyyy-MM-dd") + "\n" +
"-- " + Application.TitleForMibs + "\n" +
"-- " + Application.Url + "\n\n";
MIBName = Name;
}
else
{
FileBuffer += "\n\n";
}
FileBuffer += Data;
System.Console.Write(("Saving RFC" + (rfc.ToString().PadLeft(4, '0')) + "_" + Name).PadRight(79) + "\r");
string MIBFilename = MIBPath + "\\RFC" + (rfc.ToString().PadLeft(4, '0')) + "_" + Name + ".mib";
using (System.IO.StreamWriter StreamWriter = new System.IO.StreamWriter(MIBFilename)) StreamWriter.Write(FileBuffer);
i = Buffer.IndexOf("DEFINITIONS", ie);
}
}
}
}
}
private int SearchForBEGIN(string Buffer, int Start, int Len)
{
int Result = -1;
int Temp = -1;
int Test = -1;
// search for BEGIN
Temp = Buffer.IndexOf("BEGIN", Start, Len);
while (Temp >= 0)
{
// check if it is valid by checking if ::= is in front of BEGIN
int TestLen = Temp - Start;
if (TestLen > 50) TestLen = 50;
Test = Buffer.LastIndexOf("::=", Temp, TestLen);
if (Test >= 0)
{
// valid BEGIN found
Result = Temp;
break;
}
Len -= Temp - Start;
Start = Temp + 5;
Temp = Buffer.IndexOf("BEGIN", Start, Len);
}
return Result;
}
private int SearchForEND(string Buffer, int Start)
{
int Result = -1;
int Temp = -1;
int Test = Start;
int Count = 0;
// search for END
Temp = Buffer.IndexOf("END", Start);
// test if END is preceded with whitespace character
while ((Temp > 0) && (Buffer.Substring(Temp - 1, 1).Trim() != ""))
Temp = Buffer.IndexOf("END", Temp + 3);
while (Temp >= 0)
{
// count BEGINs in front of END
Test = SearchForBEGIN(Buffer, Test, Temp - Test);
while (Test >= 0)
{
Test += 5;
Count++;
Test = SearchForBEGIN(Buffer, Test, Temp - Test);
}
if (Count == 0)
{
// END is valid
Result = Temp;
break;
}
Test = Temp + 3;
// search for next END and decrease count
Temp = Buffer.IndexOf("END", Temp + 3);
// test if END is preceded with whitespace character
while ((Temp > 0) && (Buffer.Substring(Temp - 1, 1).Trim() != ""))
Temp = Buffer.IndexOf("END", Temp + 3);
if (Temp >= 0) Count--;
};
return Result;
}
}
}