-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauxiliary.cs
254 lines (220 loc) · 9.98 KB
/
auxiliary.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
using System;
using System.Collections;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace GNS3sharp {
/// <summary>
/// Class that defines some methods and propertiesthat are helpful for
/// the other classes of the namespace
/// </summary>
internal static class Aux{
private static Dictionary<string,object>[] nodesAvailables = CreateNodesAvailable();
/// <summary>
/// Array of dictionaries. Every dictionary contains two keys: "class" and "label". If you create
/// a new appliance class, you must add its label and type here
/// </summary>
/// <value>Values of the dictionaries are the 'type' related to the chosen label</value>
internal static Dictionary<string,object>[] NodesAvailables { get => nodesAvailables; }
/// <summary>
/// Generate the dictionary for NodesAvailable property
/// </summary>
/// <returns>A map between the type of a node and its label</returns>
private static Dictionary<string,object>[] CreateNodesAvailable(){
/// <summary>
/// List of all nodes defined in the API
/// </summary>
/// <returns>IEnumerable with the <c>Type</c> of the nodes</returns>
IEnumerable<Type> GetNodesTypes(){
/// <summary>
/// Find the children classes of a class
/// </summary>
/// <typeparam name="TBaseType">Type whose children types must be found</typeparam>
/// <returns>IEnumerable with the <c>Type</c> of the nodes</returns>
IEnumerable<Type> FindSubClassesOf<TBaseType>() {
var baseType = typeof(TBaseType);
var assembly = baseType.Assembly;
return assembly.GetTypes().Where(t => t.IsSubclassOf(baseType));
}
var routers = FindSubClassesOf<Router>();
var guests = FindSubClassesOf<Switch>();
var switches = FindSubClassesOf<Guest>();
return routers.Concat(guests).Concat(switches);
}
List<Dictionary<string,object>> typesOfNodes = new List<Dictionary<string,object>>();
foreach (var nodeType in GetNodesTypes()){
typesOfNodes.Add(
new Dictionary<string,object>(){
{"class", nodeType},
{"label", nodeType.GetProperty("Label", BindingFlags.Static | BindingFlags.Public).GetValue(null)}
}
);
}
return typesOfNodes.ToArray();
}
/// <summary>
/// Return the right class type for a certain node. Try to match the label of the node
/// with once of those defined in <c>nodesAvailable</c>
/// </summary>
/// <param name="nodeName">Name set to a node in GNS3</param>
/// <returns>The type of the node. If it can not find the certain type
/// of node, returns <c>typeof(Node)</c></returns>
internal static Type NodeType(string nodeName){
// If something goes wrong and the label is not properly set on the
// name, it returns the generic Node class
Type newNode = typeof(Node);
Match match = Regex.Match(nodeName, @"(?<=\[).+?(?=\])");
if (match.Success) {
string label = match.Groups[0].Value.ToUpperInvariant();
foreach(Dictionary<string,object> typeOfNode in nodesAvailables){
if (label.Equals(typeOfNode["label"].ToString())){
newNode = (Type)typeOfNode["class"];
break;
}
}
}
return newNode;
}
/// <summary>
/// Guess whether a string is an IP or not
/// </summary>
/// <param name="IP">String to check</param>
/// <returns>True if the string is an IP, False otherwise</returns>
internal static bool IsIP(string IP) =>
Regex.IsMatch(IP, @"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");
/// <summary>
/// Guess whether a string is a netmask or not
/// </summary>
/// <param name="netmask">String to check</param>
/// <returns>True if the string is a netmask, False otherwise</returns>
internal static bool IsNetmask(string netmask) =>
Regex.IsMatch(netmask, @"^(((255\.){3}(255|254|252|248|240|224|192|128|0+))|((255\.){2}(255|254|252|248|240|224|192|128|0+)\.0)|((255\.)(255|254|252|248|240|224|192|128|0+)(\.0+){2})|((255|254|252|248|240|224|192|128|0+)(\.0+){3}))$");
/// <summary>
/// Convert a mask written in numbers and dots into its CIDR notation
/// </summary>
/// <param name="netmaskDecimals">Mask written in numbers and dots</param>
/// <returns>Mask in CIDR notation</returns>
internal static short NetmaskCIDR(string netmaskDecimals){
short result = 0;
if (Aux.IsNetmask(netmaskDecimals)){
// Split the mask by its dots
string[] netmaskSplit = netmaskDecimals.Split('.');
BitArray bits;
foreach (string numberStr in netmaskSplit){
// Turn every number into a bit array
bits = new BitArray(BitConverter.GetBytes(ushort.Parse(numberStr)));
foreach (bool bit in bits){
// Run over the array and add 1 to the value for every true found
if (bit == true) result++;
}
}
} else{
result = -1;
}
return result;
}
}
/// <summary>
/// Structure for gathering routing tables
/// <remarks>
/// It is just a structure for better handling routing tables
/// </remarks>
/// </summary>
public class RoutingTable{
/// <summary>
/// Class that represents a row (a route) of a routing table
/// </summary>
public struct RoutingTableRow{
private string destination;
/// <summary>
/// Destination of the route
/// </summary>
/// <value>Address as a string</value>
public string Destination{ get => destination;}
private string gateway;
/// <summary>
/// Gateway of the route
/// </summary>
/// <value>Address as a string</value>
public string Gateway{ get => gateway;}
private string netmask;
/// <summary>
/// Netmask of the route
/// </summary>
/// <value>Netmask as a string</value>
public string Netmask{ get => netmask;}
private string iface;
/// <summary>
/// Interface related to the route
/// </summary>
/// <value>Interface as a string</value>
public string Iface{ get => iface;}
private int metric;
/// <summary>
/// Metric of the route
/// </summary>
/// <value>Metric as an integer</value>
public int Metric{ get => metric;}
/// <summary>
/// Constructor that initializes every parameter
/// </summary>
/// <param name="_destination">Destination of the route</param>
/// <param name="_gateway">Gateway of the route</param>
/// <param name="_netmask">Netmask of the route</param>
/// <param name="_iface">Interface related to the route</param>
/// <param name="_metric">Metric of the route</param>
public RoutingTableRow(
string _destination, string _gateway, string _netmask,
string _iface, int _metric
){
if (_gateway.Equals('*'))
_gateway = "0.0.0.0";
this.destination = _destination;
this.gateway = _gateway;
this.netmask = _netmask;
this.iface = _iface;
this.metric = _metric;
}
}
private List<RoutingTableRow> routes;
/// <summary>
/// List of the routes the table contains
/// </summary>
/// <returns>List of <c>RoutingTableRow</c></returns>
public RoutingTableRow[] Routes{ get => routes.ToArray();}
/// <summary>
/// Initialize the object
/// </summary>
public RoutingTable(){
this.routes = new List<RoutingTableRow>();
}
/// <summary>
/// Initialize the object with a fixed size
/// </summary>
/// <param name="numberOfRoutes">Number of routes the table contains</param>
public RoutingTable(ushort numberOfRoutes){
this.routes = new List<RoutingTableRow>(numberOfRoutes);
}
/// <summary>
/// Add a new route to the table
/// </summary>
/// <param name="_destination">Destination of the route</param>
/// <param name="_gateway">Gateway of the route</param>
/// <param name="_netmask">Netmask of the route</param>
/// <param name="_iface">Interface related to the route</param>
/// <param name="_metric">Metric of the route</param>
public void AddRoute(
string destination, string gateway, string netmask,
string iface, int metric
){
if (Aux.IsIP(destination) && Aux.IsIP(gateway) && Aux.IsNetmask(netmask)){
routes.Add(new RoutingTableRow(
destination, gateway, netmask, iface, metric
));
} else{
Console.Error.WriteLine("Impossible to add the new row: some of the parameters were not valid");
}
}
}
}