1 /* EtherApe
2 * Copyright (C) 2001 Juan Toledo, Riccardo Ghetta
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21
22 #include "appdata.h"
23 #include "node_id.h"
24 #include "util.h"
25
26 /***************************************************************************
27 *
28 * node_id_t implementation
29 *
30 **************************************************************************/
31
node_id_clear(node_id_t * a)32 void node_id_clear(node_id_t *a)
33 {
34 memset(a, 0, sizeof(*a));
35 a->node_type = APEMODE_DEFAULT;
36 }
37
38 /* Comparison function used to order the (GTree *) nodes
39 * and canvas_nodes heard on the network */
node_id_compare(const node_id_t * na,const node_id_t * nb)40 gint node_id_compare(const node_id_t *na, const node_id_t *nb)
41 {
42 const guint8 *ga;
43 const guint8 *gb;
44 int i;
45
46 g_assert(na != NULL);
47 g_assert(nb != NULL);
48 if (na->node_type < nb->node_type)
49 return -1;
50 else if (na->node_type > nb->node_type)
51 return 1;
52
53 /* same node type, compare */
54 switch (na->node_type)
55 {
56 case APEMODE_DEFAULT:
57 return 0; /* default has only one value */
58 case IP:
59 ga = na->addr.ip.all8;
60 gb = nb->addr.ip.all8;
61 i = sizeof(na->addr.ip.all8);
62 break;
63 case TCP:
64 ga = na->addr.tcp.host.all8;
65 gb = nb->addr.tcp.host.all8;
66 i = sizeof(na->addr.tcp.host.all8)+sizeof(na->addr.tcp.port);
67 break;
68 default:
69 g_error(_("Unsupported ape mode in node_id_compare"));
70 /* Fallthrough, default to compare-by-MAC */
71 case LINK6:
72 ga = na->addr.eth;
73 gb = nb->addr.eth;
74 i = sizeof(na->addr.eth);
75 break;
76 }
77
78 i = memcmp(ga, gb, i);
79 if (i > 1)
80 i = 1;
81 else if (i < -1)
82 i = -1;
83 return i;
84 } /* node_id_compare */
85
86 /* returns a newly allocated string with a human-readable id */
node_id_str(const node_id_t * id)87 gchar *node_id_str(const node_id_t *id)
88 {
89 gchar *msg;
90 g_assert(id);
91
92 switch (id->node_type)
93 {
94 case APEMODE_DEFAULT:
95 msg = g_strdup("00:00:00:00:00:00");
96 break;
97 case LINK6:
98 msg = g_strdup(ether_to_str(id->addr.eth));
99 break;
100 case IP:
101 msg = g_strdup(address_to_str(&id->addr.ip));
102 break;
103 case TCP:
104 msg = g_strdup_printf("%s:%u", address_to_str(&id->addr.tcp.host),
105 id->addr.tcp.port);
106 break;
107 default:
108 g_error("node_id_type %d unknown", (int)(id->node_type));
109 break;
110 }
111
112 return msg;
113 }
114
115
node_id_dump(const node_id_t * id)116 gchar *node_id_dump(const node_id_t *id)
117 {
118 gchar *msg;
119 g_assert(id);
120 switch (id->node_type)
121 {
122 case APEMODE_DEFAULT:
123 msg = g_strdup_printf("NONE: 00:00:00:00:00:00");
124 break;
125 case LINK6:
126 msg = g_strdup_printf("LINK: %s", ether_to_str(id->addr.eth));
127 break;
128 case IP:
129 msg = g_strdup_printf("%s: %s", type_to_str(&id->addr.ip),
130 address_to_str(&id->addr.ip));
131 break;
132 case TCP:
133 msg = g_strdup_printf("TCP/UDP: %s:%u",
134 address_to_str(&id->addr.tcp.host),
135 id->addr.tcp.port);
136 break;
137 default:
138 msg = g_strdup_printf("node_id_type %d unknown", (int)(id->node_type));
139 break;
140 }
141
142 return msg;
143 }
144
node_id_xml(const node_id_t * id)145 gchar *node_id_xml(const node_id_t *id)
146 {
147 gchar *msg;
148 gchar *msgb;
149 gchar *xml;
150 g_assert(id);
151 switch (id->node_type)
152 {
153 case APEMODE_DEFAULT:
154 msg = g_strdup_printf(" ");
155 break;
156 case LINK6:
157 msg = xmltag_escaped("link-id", "%s", ether_to_str(id->addr.eth));
158 break;
159 case IP:
160 msg = xmltag_escaped(type_to_str(&id->addr.ip), "%s", address_to_str(&id->addr.ip));
161 break;
162 case TCP:
163 xml = xmltag_escaped(type_to_str(&id->addr.tcp.host),
164 "%s",
165 address_to_str(&id->addr.tcp.host));
166 msgb = xmltag_escaped("port", "%u", id->addr.tcp.port);
167 msg = g_strdup_printf("%s %s", xml, msgb);
168 g_free(xml);
169 g_free(msgb);
170 break;
171 default:
172 msg = xmltag("unknown", "node_id_type %d unknown", (int)(id->node_type));
173 break;
174 }
175 xml = xmltag("id", "\n%s", msg);
176 g_free(msg);
177
178 return xml;
179 }
180
181 /***************************************************************************
182 *
183 * name_t implementation
184 *
185 **************************************************************************/
186 static long node_name_count = 0;
187
active_names(void)188 long active_names(void)
189 {
190 return node_name_count;
191 }
192
node_name_create(const node_id_t * node_id)193 name_t *node_name_create(const node_id_t *node_id)
194 {
195 name_t *name;
196
197 g_assert(node_id);
198
199 name = g_malloc(sizeof(name_t));
200 g_assert(name);
201
202 name->node_id = *node_id;
203 name->accumulated = 0;
204 name->numeric_name = NULL;
205 name->res_name = NULL;
206 ++node_name_count;
207 {
208 gchar *gg = node_id_dump(node_id);
209 g_my_debug("node name created (%p): >%s<, total %ld", name,
210 gg, node_name_count);
211 g_free(gg);
212 }
213 return name;
214 }
215
node_name_delete(name_t * name)216 void node_name_delete(name_t *name)
217 {
218 if (name) {
219 {
220 gchar *gg = node_id_dump(&name->node_id);
221 g_my_debug("node name delete (%p): >%s<, total %ld", name,
222 gg, node_name_count-1);
223 g_free(gg);
224 }
225 if (name->res_name)
226 g_string_free(name->res_name, TRUE);
227 if (name->numeric_name)
228 g_string_free(name->numeric_name, TRUE);
229 g_free(name);
230 --node_name_count;
231 }
232 }
233
node_name_assign(name_t * name,const gchar * nm,const gchar * num_nm,gdouble sz)234 void node_name_assign(name_t *name, const gchar *nm, const gchar *num_nm,
235 gdouble sz)
236 {
237 if (DEBUG_ENABLED) {
238 gchar *msgid = node_id_dump(&name->node_id);
239 g_my_debug(" node_name_assign: id %s, name %s, num.name %s\n",
240 msgid, (nm) ? nm : "<none>", num_nm);
241 g_free(msgid);
242 }
243 g_assert(name);
244 if (!name->numeric_name)
245 name->numeric_name = g_string_new(num_nm);
246 else
247 g_string_assign(name->numeric_name, num_nm);
248
249 if (nm) {
250 if (!name->res_name)
251 name->res_name = g_string_new(nm);
252 else
253 g_string_assign(name->res_name, nm);
254 }
255 name->accumulated += sz;
256 }
257
node_name_dump(const name_t * name)258 gchar *node_name_dump(const name_t *name)
259 {
260 gchar *msg;
261 gchar *nid;
262 if (!name)
263 return g_strdup("name_t NULL");
264
265 nid = node_id_dump(&name->node_id);
266 msg = g_strdup_printf("node id: %s, name: %s, numeric_name: %s, solved: %d, "
267 "accumulated %f",
268 nid,
269 (name->res_name) ? name->res_name->str : "<none>",
270 name->numeric_name->str,
271 name->res_name != NULL,
272 name->accumulated);
273 g_free(nid);
274 return msg;
275 }
276
node_name_xml(const name_t * name)277 gchar *node_name_xml(const name_t *name)
278 {
279 gchar *msg;
280 gchar *nid;
281 gchar *nres;
282
283 if (!name)
284 return xmltag("name", "");
285
286 nid = node_id_xml(&name->node_id);
287 if (name->res_name)
288 nres = xmltag_escaped("resolved_name", "%s", name->res_name->str);
289 else
290 nres = g_strdup("");
291 msg = xmltag("name",
292 "\n%s%s<numeric_name>%s</numeric_name>\n"
293 "<accumulated>%.0f</accumulated>",
294 nid,
295 nres,
296 name->numeric_name->str,
297 name->accumulated);
298 g_free(nid);
299 g_free(nres);
300 return msg;
301 }
302
303 /* compares by node id */
node_name_id_compare(const name_t * a,const name_t * b)304 gint node_name_id_compare(const name_t *a, const name_t *b)
305 {
306 g_assert(a != NULL);
307 g_assert(b != NULL);
308 return node_id_compare(&a->node_id, &b->node_id);
309 }
310
311 /* Comparison function to sort protocols by their accumulated traffic */
node_name_freq_compare(gconstpointer a,gconstpointer b)312 gint node_name_freq_compare(gconstpointer a, gconstpointer b)
313 {
314 const name_t *name_a, *name_b;
315
316 g_assert(a != NULL);
317 g_assert(b != NULL);
318
319 name_a = (const name_t *)a;
320 name_b = (const name_t *)b;
321
322 if (name_a->accumulated > name_b->accumulated)
323 return -1;
324 if (name_a->accumulated < name_b->accumulated)
325 return 1;
326 return 0;
327 }
328