1# vim: set fileencoding=utf-8 :
2
3# ***********************IMPORTANT NMAP LICENSE TERMS************************
4# *                                                                         *
5# * The Nmap Security Scanner is (C) 1996-2020 Insecure.Com LLC ("The Nmap  *
6# * Project"). Nmap is also a registered trademark of the Nmap Project.     *
7# *                                                                         *
8# * This program is distributed under the terms of the Nmap Public Source   *
9# * License (NPSL). The exact license text applying to a particular Nmap    *
10# * release or source code control revision is contained in the LICENSE     *
11# * file distributed with that version of Nmap or source code control       *
12# * revision. More Nmap copyright/legal information is available from       *
13# * https://nmap.org/book/man-legal.html, and further information on the    *
14# * NPSL license itself can be found at https://nmap.org/npsl. This header  *
15# * summarizes some key points from the Nmap license, but is no substitute  *
16# * for the actual license text.                                            *
17# *                                                                         *
18# * Nmap is generally free for end users to download and use themselves,    *
19# * including commercial use. It is available from https://nmap.org.        *
20# *                                                                         *
21# * The Nmap license generally prohibits companies from using and           *
22# * redistributing Nmap in commercial products, but we sell a special Nmap  *
23# * OEM Edition with a more permissive license and special features for     *
24# * this purpose. See https://nmap.org/oem                                  *
25# *                                                                         *
26# * If you have received a written Nmap license agreement or contract       *
27# * stating terms other than these (such as an Nmap OEM license), you may   *
28# * choose to use and redistribute Nmap under those terms instead.          *
29# *                                                                         *
30# * The official Nmap Windows builds include the Npcap software             *
31# * (https://npcap.org) for packet capture and transmission. It is under    *
32# * separate license terms which forbid redistribution without special      *
33# * permission. So the official Nmap Windows builds may not be              *
34# * redistributed without special permission (such as an Nmap OEM           *
35# * license).                                                               *
36# *                                                                         *
37# * Source is provided to this software because we believe users have a     *
38# * right to know exactly what a program is going to do before they run it. *
39# * This also allows you to audit the software for security holes.          *
40# *                                                                         *
41# * Source code also allows you to port Nmap to new platforms, fix bugs,    *
42# * and add new features.  You are highly encouraged to submit your         *
43# * changes as a Github PR or by email to the dev@nmap.org mailing list     *
44# * for possible incorporation into the main distribution. Unless you       *
45# * specify otherwise, it is understood that you are offering us very       *
46# * broad rights to use your submissions as described in the Nmap Public    *
47# * Source License Contributor Agreement. This is important because we      *
48# * fund the project by selling licenses with various terms, and also       *
49# * because the inability to relicense code has caused devastating          *
50# * problems for other Free Software projects (such as KDE and NASM).       *
51# *                                                                         *
52# * The free version of Nmap is distributed in the hope that it will be     *
53# * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of  *
54# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Warranties,        *
55# * indemnification and commercial support are all available through the    *
56# * Npcap OEM program--see https://nmap.org/oem.                            *
57# *                                                                         *
58# ***************************************************************************/
59
60
61class Node(object):
62    """
63    Node class
64    """
65    def __init__(self):
66        """
67        Constructor method of Node class
68        @type  : integer
69        @param : Node identifier
70        """
71        self.__data = None
72        """User-controlled data pointer"""
73        self.__edges = []
74        """List of edges to other nodes"""
75
76    def get_data(self):
77        return self.__data
78
79    def set_data(self, data):
80        self.__data = data
81
82    def get_edge(self, dest):
83        """
84        Return the edge connecting to dest, or None if none
85        """
86        for edge in self.__edges:
87            if dest in edge.get_nodes():
88                return edge
89        return None
90
91    def get_edges(self):
92        """
93        Return the list of edges
94        """
95        return self.__edges
96
97    def add_edge(self, edge):
98        self.__edges.append(edge)
99
100
101class Edge:
102    """
103    """
104    def __init__(self, nodes):
105        """
106        """
107        self.__weights = []
108        self.__nodes = nodes
109        self.__weights_mean = None
110
111    def get_nodes(self):
112        """
113        """
114        return self.__nodes
115
116    def get_weights(self):
117        """
118        """
119        return self.__weights
120
121    def set_weights(self, weights):
122        """
123        """
124        self.__weights = weights
125        self.__weights_mean = sum(self.__weights) / len(self.__weights)
126
127    def add_weight(self, weight):
128        """
129        """
130        self.__weights.append(weight)
131        self.__weights_mean = sum(self.__weights) / len(self.__weights)
132
133    def get_weights_mean(self):
134        """
135        """
136        return self.__weights_mean
137
138
139class Graph:
140    """
141    Network Graph class
142    """
143
144    def __init__(self):
145        """
146        Constructor method of Graph class
147        @type  : list
148        @param : List of nodes
149        """
150        self.__main_node = None
151        self.__nodes = []
152        self.__max_edge_mean_value = None
153        self.__min_edge_mean_value = None
154
155    def set_nodes(self, nodes):
156        """
157        """
158        self.__nodes = nodes
159
160    def get_nodes(self):
161        """
162        """
163        return self.__nodes
164
165    def get_number_of_nodes(self):
166        """
167        Get the number of nodes in graph
168        @rtype: number
169        @return: The number of nodes in the graph
170        """
171        return len(self.__nodes)
172
173    def set_main_node(self, node):
174        """
175        Set the main node
176        @type  : number
177        @param : The node
178        """
179        self.__main_node = node
180
181    def get_main_node(self):
182        """
183        Get the main node
184        @rtype: Node
185        @return: The main node
186        """
187        return self.__main_node
188
189    def set_connection(self, a, b, weight=None):
190        """
191        Set node connections
192        @type  : list
193        @param : List of connections
194        """
195
196        # if is a new connection make it
197        edge = a.get_edge(b)
198        if edge is None:
199            edge = Edge((a, b))
200            a.add_edge(edge)
201            b.add_edge(edge)
202
203        # then add new weight value
204        if weight is not None:
205
206            edge.add_weight(weight)
207
208            mean_weight = edge.get_weights_mean()
209            if (self.__min_edge_mean_value is None or
210                    mean_weight < self.__min_edge_mean_value):
211                self.__min_edge_mean_value = mean_weight
212            if (self.__max_edge_mean_value is None or
213                    mean_weight > self.__max_edge_mean_value):
214                self.__max_edge_mean_value = mean_weight
215
216    def get_edges(self):
217        """
218        An iterator that yields all edges
219        """
220        for node in self.__nodes:
221            for edge in node.get_edges():
222                if edge.get_nodes()[0] == node:
223                    yield edge
224
225    def get_node_connections(self, node):
226        """
227        """
228        connections = []
229
230        for edge in node.get_edges():
231
232            (a, b) = edge.get_nodes()
233
234            if a == node:
235                connections.append(b)
236            if b == node:
237                connections.append(a)
238
239        return connections
240
241    def get_max_edge_mean_weight(self):
242        """
243        """
244        return self.__max_edge_mean_value
245
246    def get_min_edge_mean_weight(self):
247        """
248        """
249        return self.__min_edge_mean_value
250