HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-lon.c
blobec69bb00311d217989d7666e98bec94034d9eebf
1 /* packet-lon.c
2 * Traffic analyzer for Lontalk/EIA-709.1 networks
3 * Daniel Willmann <daniel@totalueberwachung.de>
4 * (c) 2011 Daniel Willmann
6 * Used some code by habibi_khalid <khalidhabibi@gmx.de> and
7 * Honorine_KEMGNE_NGUIFFO <honorinekemgne@yahoo.fr> from
8 * http://bugs.wireshark.org/bugzilla/show_bug.cgi?id=4704
10 * $Id$
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include "config.h"
33 #include <glib.h>
35 #include <epan/packet.h>
36 #include <epan/expert.h>
39 static const value_string pdu_fmt_vs[]=
41 {0x00, "TPDU"},
42 {0x01, "SPDU"},
43 {0x02, "AuthPDU"},
44 {0x03, "APDU"},
45 {0, NULL}
48 static const value_string addr_fmt_vs[]=
50 {0x00, "Broadcast (0)"},
51 {0x01, "Multicast (1)"},
52 {0x02, "Unicast (2a)/Multicast (2b)"},
53 {0x03, "Unicast (3)"},
54 {0, NULL}
57 static const value_string domain_length_vs[]=
59 {0x00, "0 bit"},
60 {0x01, "8 bit"},
61 {0x02, "24 bit"},
62 {0x03, "48 bit"},
63 {0, NULL}
66 static const value_string tpdu_type_vs[]=
68 {0x00, "ACKD"},
69 {0x01, "UnACKD_RPT"},
70 {0x02, "ACK"},
71 {0x04, "REMINDER"},
72 {0x05, "REM/MSG"},
73 {0, NULL}
76 static const value_string spdu_type_vs[]=
78 {0x00, "REQUEST"},
79 {0x02, "RESPONSE"},
80 {0x04, "REMINDER"},
81 {0x05, "REM/MSG"},
82 {0, NULL}
85 static const value_string authpdu_type_vs[]=
87 {0x00, "CHALLENGE"},
88 {0x02, "REPLY"},
89 {0, NULL}
92 static const value_string nm_code_vs[]=
94 {0x61, "NM_QUERY_ID"},
95 {0x62, "NM_RESPOND_TO_QUERY"},
96 {0x63, "NM_UPDATE_DOMAIN"},
97 {0x64, "NM_LEAVE_DOMAIN"},
98 {0x65, "NM_UPDATE_KEY"},
99 {0x66, "NM_UPDATE_ADDR"},
100 {0x67, "NM_QUERY_ADDR"},
101 {0x68, "NM_QUERY_NV_CNFG"},
102 {0x69, "NM_UPDATE_GROUP_ADDR"},
103 {0x6A, "NM_QUERY_DOMAIN"},
104 {0x6B, "NM_UPDATE_NV_CNFG"},
105 {0x6C, "NM_SET_NODE_MODE"},
106 {0x6D, "NM_READ_MEMORY"},
107 {0x6E, "NM_WRITE_MEMORY"},
108 {0x6F, "NM_CHECKSUM_RECALC"},
109 {0x70, "NM_WINK"},
110 {0x71, "NM_MEMORY_REFRESH"},
111 {0x72, "NM_QUERY_SNVT"},
112 {0x73, "NM_NV_FETCH"},
113 {0x7F, "NM_MANUAL_SERVICE_REQUEST"},
114 { 0, NULL}
117 static const value_string nd_code_vs[]=
119 {0x51, "ND_QUERY_STATUS"},
120 {0x52, "ND_PROXY_COMMAND"},
121 {0x53, "ND_CLEAR_STATUS"},
122 {0x54, "ND_QUERY_XCVR"},
123 {0, NULL}
126 void proto_reg_handoff_lon(void);
128 static gint hf_lon_ppdu = -1;
129 static gint hf_lon_ppdu_prio = -1;
130 static gint hf_lon_ppdu_alt = -1;
131 static gint hf_lon_ppdu_deltabl = -1;
132 static gint hf_lon_npdu = -1;
133 static gint hf_lon_npdu_version = -1;
134 static gint hf_lon_npdu_pdu_fmt = -1;
135 static gint hf_lon_npdu_addr_fmt = -1;
136 static gint hf_lon_npdu_dom_len = -1;
137 static gint hf_lon_addr_srcsub = -1;
138 static gint hf_lon_addr_srcnode = -1;
139 static gint hf_lon_addr_dstsub = -1;
140 static gint hf_lon_addr_dstgrp = -1;
141 static gint hf_lon_addr_dstnode = -1;
142 static gint hf_lon_addr_grp = -1;
143 static gint hf_lon_addr_grpmem = -1;
144 static gint hf_lon_addr_uid = -1;
145 static gint hf_lon_name = -1;
146 static gint hf_lon_domain = -1;
147 static gint hf_lon_tpdu = -1;
148 static gint hf_lon_auth = -1;
149 static gint hf_lon_tpdu_tpdu_type = -1;
150 static gint hf_lon_trans_no = -1;
151 static gint hf_lon_spdu = -1;
152 static gint hf_lon_spdu_spdu_type = -1;
153 static gint hf_lon_mlen = -1;
154 static gint hf_lon_mlist = -1;
155 static gint hf_lon_authpdu = -1;
156 static gint hf_lon_authpdu_fmt = -1;
157 static gint hf_lon_authpdu_authpdu_type = -1;
158 static gint hf_lon_nv_dir = -1;
159 static gint hf_lon_nv_selector = -1;
160 static gint hf_lon_app_code = -1;
161 static gint hf_lon_nm_code = -1;
162 static gint hf_lon_nd_code = -1;
163 static gint hf_lon_ff_code = -1;
164 static gint hf_lon_nv = -1;
165 static gint hf_lon_app = -1;
166 static gint hf_lon_nm = -1;
167 static gint hf_lon_nd = -1;
168 static gint hf_lon_ff = -1;
169 /* static gint hf_lon_checksum = -1; */
170 static gint proto_lon = -1;
173 static gint ett_lon = -1;
174 static gint ett_ppdu = -1;
175 static gint ett_npdu = -1;
176 static gint ett_tpdu = -1;
177 static gint ett_spdu = -1;
178 static gint ett_authpdu = -1;
179 static gint ett_apdu = -1;
180 static gint ett_nv = -1;
181 static gint ett_app = -1;
182 static gint ett_nm = -1;
183 static gint ett_nd = -1;
184 static gint ett_ff = -1;
186 static gint ett_address = -1;
188 static expert_field ei_lon_tpdu_tpdu_type_unknown = EI_INIT;
189 static expert_field ei_lon_tpdu_spdu_type_unknown = EI_INIT;
190 static expert_field ei_lon_tpdu_authpdu_type_unknown = EI_INIT;
191 static expert_field ei_lon_tpdu_apdu_dest_type = EI_INIT;
193 static dissector_handle_t data_handle;
195 static gint dissect_apdu(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
196 gint offset);
198 static gint
199 dissect_lon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
201 gint offset = 0;
203 gint pdu_fmt, addr_fmt, dom_len, pdutype, length;
204 gint addr_a;
206 proto_tree *ti;
207 proto_item *pi;
208 proto_tree *lon_tree;
209 gint npdu, type;
211 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LON");
212 col_clear(pinfo->cinfo, COL_INFO);
214 npdu = tvb_get_guint8(tvb, 0);
215 type = tvb_get_guint8(tvb, 1);
216 type = (type&0x30)>>4;
217 col_add_fstr(pinfo->cinfo, COL_INFO,
218 "%sDelta_BL: %i Type: %s",
219 npdu&0x80?"Priority ":"",
220 npdu&0x3F,
221 val_to_str_const(type, pdu_fmt_vs, "Unknown"));
223 ti = proto_tree_add_item(tree, proto_lon, tvb, offset, -1, ENC_NA);
224 lon_tree = proto_item_add_subtree(ti, ett_lon);
227 static const gint *ppdu_fields[] = {
228 &hf_lon_ppdu_prio,
229 &hf_lon_ppdu_alt,
230 &hf_lon_ppdu_deltabl,
231 NULL
233 proto_tree_add_bitmask(lon_tree, tvb, offset, hf_lon_ppdu,
234 ett_ppdu, ppdu_fields, ENC_BIG_ENDIAN);
235 offset++;
238 static const gint *npdu_fields[] = {
239 &hf_lon_npdu_version,
240 &hf_lon_npdu_pdu_fmt,
241 &hf_lon_npdu_addr_fmt,
242 &hf_lon_npdu_dom_len,
243 NULL
245 proto_tree_add_bitmask(lon_tree, tvb, offset, hf_lon_npdu,
246 ett_npdu, npdu_fields, ENC_BIG_ENDIAN);
248 pdu_fmt = (tvb_get_guint8(tvb, offset) >> 4) & 0x03;
249 addr_fmt = (tvb_get_guint8(tvb, offset) >> 2) & 0x03;
250 dom_len = tvb_get_guint8(tvb, offset) & 0x03;
251 offset++;
253 /* Address part */
254 switch(addr_fmt)
256 case 0: /* Broadcast */
257 pi = proto_tree_add_text(lon_tree, tvb, offset, 3, "Address type 0 (broadcast)");
258 ti = proto_item_add_subtree(pi, ett_address);
259 proto_tree_add_item(ti, hf_lon_addr_srcsub, tvb, offset, 1, ENC_NA);
260 proto_tree_add_item(ti, hf_lon_addr_srcnode, tvb, offset+1, 1, ENC_NA);
261 proto_tree_add_item(ti, hf_lon_addr_dstsub, tvb, offset+2, 1, ENC_NA);
262 offset += 3;
263 break;
264 case 1: /* Multicast */
265 pi = proto_tree_add_text(lon_tree, tvb, offset, 3, "Address type 1 (multicast)");
266 ti = proto_item_add_subtree(pi, ett_address);
267 proto_tree_add_item(ti, hf_lon_addr_srcsub, tvb, offset, 1, ENC_NA);
268 proto_tree_add_item(ti, hf_lon_addr_srcnode, tvb, offset+1, 1, ENC_NA);
269 proto_tree_add_item(ti, hf_lon_addr_dstgrp, tvb, offset+2, 1, ENC_NA);
270 offset += 3;
271 break;
272 case 2: /* Unicast/Multicast */
273 addr_a = tvb_get_guint8(tvb, offset+1) >> 7;
274 if (addr_a) { /* Type 2a */
275 pi = proto_tree_add_text(lon_tree, tvb, offset, 4, "Address type 2a (unicast)");
276 ti = proto_item_add_subtree(pi, ett_address);
277 proto_tree_add_item(ti, hf_lon_addr_srcsub, tvb, offset, 1, ENC_NA);
278 proto_tree_add_item(ti, hf_lon_addr_srcnode, tvb, offset+1, 1, ENC_NA);
279 proto_tree_add_item(ti, hf_lon_addr_dstsub, tvb, offset+2, 1, ENC_NA);
280 proto_tree_add_item(ti, hf_lon_addr_dstnode, tvb, offset+3, 1, ENC_NA);
281 offset += 4;
282 } else { /* Type 2b */
283 pi = proto_tree_add_text(lon_tree, tvb, offset, 6, "Address type 2b (multicast)");
284 ti = proto_item_add_subtree(pi, ett_address);
285 proto_tree_add_item(ti, hf_lon_addr_srcsub, tvb, offset, 1, ENC_NA);
286 proto_tree_add_item(ti, hf_lon_addr_srcnode, tvb, offset+1, 1, ENC_NA);
287 proto_tree_add_item(ti, hf_lon_addr_dstgrp, tvb, offset+2, 1, ENC_NA);
288 proto_tree_add_item(ti, hf_lon_addr_dstnode, tvb, offset+3, 1, ENC_NA);
289 proto_tree_add_item(ti, hf_lon_addr_grp, tvb, offset+4, 1, ENC_NA);
290 proto_tree_add_item(ti, hf_lon_addr_grpmem, tvb, offset+5, 1, ENC_NA);
291 offset += 6;
293 break;
294 case 3: /* UID */
295 pi = proto_tree_add_text(lon_tree, tvb, offset, 9, "Address type 3 (UID)");
296 ti = proto_item_add_subtree(pi, ett_address);
297 proto_tree_add_item(ti, hf_lon_addr_srcsub, tvb, offset, 1, ENC_NA);
298 proto_tree_add_item(ti, hf_lon_addr_srcnode, tvb, offset+1, 1, ENC_NA);
299 proto_tree_add_item(ti, hf_lon_addr_dstsub, tvb, offset+2, 1, ENC_NA);
300 proto_tree_add_item(ti, hf_lon_addr_uid, tvb, offset+3, 6, ENC_NA);
301 offset += 9;
302 break;
304 /* END Address part */
305 /* Domain */
306 switch(dom_len)
308 case 0: /* Domain-wide */
309 proto_tree_add_text(lon_tree, tvb, offset, 0, "Domain wide addressing");
310 break;
311 case 1:
312 proto_tree_add_item(lon_tree, hf_lon_domain, tvb, offset, 1, ENC_NA);
313 offset++;
314 break;
315 case 2:
316 proto_tree_add_item(lon_tree, hf_lon_domain, tvb, offset, 3, ENC_NA);
317 offset += 3;
318 break;
319 case 3:
320 proto_tree_add_item(lon_tree, hf_lon_domain, tvb, offset, 6, ENC_NA);
321 offset += 6;
322 break;
324 /* END Domain */
325 /* *PDU */
326 switch(pdu_fmt)
328 case 0: /* TPDU */
330 static const gint *tpdu_fields[] = {
331 &hf_lon_auth,
332 &hf_lon_tpdu_tpdu_type,
333 &hf_lon_trans_no,
334 NULL
336 proto_tree_add_bitmask(lon_tree, tvb, offset, hf_lon_tpdu,
337 ett_tpdu, tpdu_fields, ENC_BIG_ENDIAN);
339 pdutype = (tvb_get_guint8(tvb, offset)>>4)& 0x07;
340 offset++;
341 switch(pdutype)
343 case 0:
344 case 1: /* ACKD and UnACKD_RPT */
345 offset += dissect_apdu(lon_tree, pinfo, tvb, offset);
346 break;
347 case 2: /* ACK */
348 break;
349 case 4: /* REMINDER */
350 length = tvb_get_guint8(tvb, offset);
351 proto_tree_add_item(lon_tree, hf_lon_mlen, tvb, offset, 1, ENC_NA);
352 offset++;
353 proto_tree_add_item(lon_tree, hf_lon_mlist, tvb, offset, length, ENC_NA);
354 offset += length;
355 break;
356 case 5: /* REM/MSG */
357 length = tvb_get_guint8(tvb, offset);
358 proto_tree_add_item(lon_tree, hf_lon_mlen, tvb, offset, 1, ENC_NA);
359 offset++;
360 if (length > 0)
361 proto_tree_add_item(lon_tree, hf_lon_mlist, tvb, offset, length, ENC_NA);
362 offset += length;
363 offset += dissect_apdu(lon_tree, pinfo, tvb, offset);
364 break;
365 default:
366 expert_add_info_format(pinfo, lon_tree, &ei_lon_tpdu_tpdu_type_unknown, "Unexpected TPDU type %i", pdutype);
367 break;
370 break;
371 case 1: /* SPDU */
373 static const gint *spdu_fields[] = {
374 &hf_lon_auth,
375 &hf_lon_spdu_spdu_type,
376 &hf_lon_trans_no,
377 NULL
379 proto_tree_add_bitmask(lon_tree, tvb, offset, hf_lon_spdu,
380 ett_spdu, spdu_fields, ENC_BIG_ENDIAN);
381 pdutype = (tvb_get_guint8(tvb, offset)>>4)& 0x07;
382 offset++;
383 switch(pdutype)
385 case 0: /* REQUEST */
386 offset += dissect_apdu(lon_tree, pinfo, tvb, offset);
387 break;
388 case 2: /* RESPONSE */
389 offset += dissect_apdu(lon_tree, pinfo, tvb, offset);
390 break;
391 case 4: /* REMINDER */
392 length = tvb_get_guint8(tvb, offset);
393 proto_tree_add_item(lon_tree, hf_lon_mlen, tvb, offset, 1, ENC_NA);
394 offset++;
395 proto_tree_add_item(lon_tree, hf_lon_mlist, tvb, offset, length, ENC_NA);
396 offset += length;
397 break;
398 case 5: /* REM/MSG */
399 length = tvb_get_guint8(tvb, offset);
400 proto_tree_add_item(lon_tree, hf_lon_mlen, tvb, offset, 1, ENC_NA);
401 offset++;
402 if (length > 0)
403 proto_tree_add_item(lon_tree, hf_lon_mlist, tvb, offset, length, ENC_NA);
404 offset += length;
405 offset += dissect_apdu(lon_tree, pinfo, tvb, offset);
406 break;
407 default:
408 expert_add_info_format(pinfo, lon_tree, &ei_lon_tpdu_spdu_type_unknown, "Unexpected SPDU type %i", pdutype);
409 break;
412 break;
413 case 2: /* AuthPDU */
415 static const gint *authpdu_fields[] = {
416 &hf_lon_authpdu_fmt,
417 &hf_lon_authpdu_authpdu_type,
418 &hf_lon_trans_no,
419 NULL
421 proto_tree_add_bitmask(lon_tree, tvb, offset, hf_lon_authpdu,
422 ett_authpdu, authpdu_fields, ENC_BIG_ENDIAN);
424 pdutype = (tvb_get_guint8(tvb, offset)>>4)& 0x03;
425 offset++;
426 switch(pdutype)
428 case 0: /* CHALLENGE */
429 case 2: /* REPLY */
430 offset += 9;
431 break;
432 default:
433 expert_add_info_format(pinfo, lon_tree, &ei_lon_tpdu_authpdu_type_unknown, "Unexpected AuthPDU type %i", pdutype);
434 break;
437 break;
438 case 3: /* APDU */
439 offset += dissect_apdu(lon_tree, pinfo, tvb, offset);
440 break;
442 /* END *PDU */
444 return offset;
447 static gint
448 dissect_apdu(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
449 gint offset)
451 tvbuff_t *next_tvb;
452 gint old_offset = offset, dest_type;
454 dest_type = tvb_get_guint8(tvb, offset);
456 if ((dest_type&0x80) == 0x80) { /* Network variable */
457 static const gint *nv_fields[] = {
458 &hf_lon_nv_dir,
459 &hf_lon_nv_selector,
460 NULL
462 proto_tree_add_bitmask(tree, tvb, offset, hf_lon_nv,
463 ett_nv, nv_fields, ENC_BIG_ENDIAN);
464 offset += 2;
465 } else if ((dest_type&0xc0) == 0) { /* Application */
466 static const gint *app_fields[] = {
467 &hf_lon_app_code,
468 NULL
470 proto_tree_add_bitmask(tree, tvb, offset, hf_lon_app,
471 ett_app, app_fields, ENC_BIG_ENDIAN);
472 offset++;
473 } else if ((dest_type&0xe0) == 0x60) { /* Network Management */
474 static const gint *nm_fields[] = {
475 &hf_lon_nm_code,
476 NULL
478 proto_tree_add_bitmask(tree, tvb, offset, hf_lon_nm,
479 ett_nm, nm_fields, ENC_BIG_ENDIAN);
480 offset++;
482 if (dest_type == 0x7F) {
483 proto_tree_add_item(tree, hf_lon_addr_uid, tvb, offset, 6, ENC_NA);
484 offset += 6;
485 proto_tree_add_item(tree, hf_lon_name, tvb, offset, 8, ENC_NA);
486 offset += 8;
489 } else if ((dest_type&0xf0) == 0x50) { /* Network Diagnostic */
490 static const gint *nd_fields[] = {
491 &hf_lon_nd_code,
492 NULL
494 proto_tree_add_bitmask(tree, tvb, offset, hf_lon_nd,
495 ett_nd, nd_fields, ENC_BIG_ENDIAN);
496 offset++;
497 } else if ((dest_type&0xf0) == 0x40) { /* Foreign Frame */
498 static const gint *ff_fields[] = {
499 &hf_lon_ff_code,
500 NULL
502 proto_tree_add_bitmask(tree, tvb, offset, hf_lon_ff,
503 ett_ff, ff_fields, ENC_BIG_ENDIAN);
504 offset++;
505 } else { /* Shouldn't get here */
506 expert_add_info_format(pinfo, tree, &ei_lon_tpdu_apdu_dest_type, "Malformed APDU destin&type %i", dest_type);
509 next_tvb = tvb_new_subset_remaining(tvb, offset);
511 return offset - old_offset + call_dissector(data_handle, next_tvb, pinfo, tree);
514 void
515 proto_register_lon(void)
517 static hf_register_info hf[] =
519 {&hf_lon_ppdu,
520 {"PPDU", "lon.ppdu",
521 FT_UINT8, BASE_HEX, NULL, 0,
522 NULL, HFILL }
524 {&hf_lon_ppdu_prio,
525 {"Priority", "lon.prio",
526 FT_UINT8, BASE_DEC, NULL, 0x80,
527 "Priority packet", HFILL }
529 {&hf_lon_ppdu_alt,
530 {"Alt path", "lon.alt_path",
531 FT_UINT8, BASE_DEC, NULL, 0x40,
532 "Alternate path", HFILL }
534 {&hf_lon_ppdu_deltabl,
535 {"Delta BL", "lon.delta_bl",
536 FT_UINT8, BASE_DEC, NULL, 0x3f,
537 "How many packets to expect from this one", HFILL }
539 {&hf_lon_npdu,
540 {"NPDU", "lon.npdu",
541 FT_UINT8, BASE_DEC, NULL, 0,
542 NULL, HFILL }
544 {&hf_lon_npdu_version,
545 {"version", "lon.vers",
546 FT_UINT8, BASE_HEX, NULL, 0xc0,
547 "LON protocol version", HFILL }
549 {&hf_lon_npdu_pdu_fmt,
550 {"PDU format", "lon.pdufmt",
551 FT_UINT8, BASE_HEX, VALS(pdu_fmt_vs), 0x30,
552 NULL, HFILL }
554 {&hf_lon_npdu_addr_fmt,
555 {"Address format", "lon.addrfmt",
556 FT_UINT8, BASE_HEX, VALS(addr_fmt_vs), 0x0c,
557 NULL, HFILL }
559 {&hf_lon_npdu_dom_len,
560 {"Domain length", "lon.domainlen",
561 FT_UINT8, BASE_HEX, VALS(domain_length_vs), 0x03,
562 NULL, HFILL }
564 {&hf_lon_addr_srcsub,
565 {"Source subnet", "lon.srcnet",
566 FT_UINT8, BASE_HEX, NULL, 0,
567 NULL, HFILL }
569 {&hf_lon_addr_srcnode,
570 {"Source node", "lon.srcnode",
571 FT_UINT8, BASE_HEX, NULL, 0x7f,
572 NULL, HFILL }
574 {&hf_lon_addr_dstsub,
575 {"Destination subnet", "lon.dstnet",
576 FT_UINT8, BASE_HEX, NULL, 0,
577 NULL, HFILL }
579 {&hf_lon_addr_dstgrp,
580 {"Destination group", "lon.dstgrp",
581 FT_UINT8, BASE_HEX, NULL, 0,
582 NULL, HFILL }
584 {&hf_lon_addr_dstnode,
585 {"Destination node", "lon.dstnode",
586 FT_UINT8, BASE_HEX, NULL, 0x7f,
587 NULL, HFILL }
589 {&hf_lon_addr_grp,
590 {"Group", "lon.grp",
591 FT_UINT8, BASE_HEX, NULL, 0,
592 NULL, HFILL }
594 {&hf_lon_addr_grpmem,
595 {"Group member", "lon.grpmem",
596 FT_UINT8, BASE_HEX, NULL, 0,
597 NULL, HFILL }
599 {&hf_lon_addr_uid,
600 {"Unique node ID", "lon.uid",
601 FT_BYTES, BASE_NONE, NULL, 0,
602 NULL, HFILL }
604 {&hf_lon_domain,
605 {"Domain", "lon.domain",
606 FT_BYTES, BASE_NONE, NULL , 0,
607 NULL, HFILL }
609 {&hf_lon_tpdu,
610 {"TPDU", "lon.tpdu",
611 FT_UINT8, BASE_HEX, NULL, 0,
612 NULL, HFILL }
614 {&hf_lon_auth,
615 {"Auth", "lon.auth",
616 FT_UINT8, BASE_HEX, NULL, 0x80,
617 NULL, HFILL }
619 {&hf_lon_tpdu_tpdu_type,
620 {"TPDU type", "lon.tpdu_type",
621 FT_UINT8, BASE_HEX, VALS(tpdu_type_vs), 0x70,
622 NULL, HFILL }
624 {&hf_lon_trans_no,
625 {"Transaction number", "lon.trans_no",
626 FT_UINT8, BASE_HEX, NULL, 0x0f,
627 NULL, HFILL }
629 {&hf_lon_spdu,
630 {"SPDU", "lon.spdu",
631 FT_UINT8, BASE_HEX, NULL, 0,
632 NULL, HFILL }
634 {&hf_lon_spdu_spdu_type,
635 {"SPDU type", "lon.spdu_type",
636 FT_UINT8, BASE_HEX, VALS(spdu_type_vs), 0x70,
637 NULL, HFILL }
639 {&hf_lon_mlen,
640 {"Length of M_List", "lon.spdu.mlen",
641 FT_UINT8, BASE_HEX, NULL, 0,
642 NULL, HFILL }
644 {&hf_lon_mlist,
645 {"M_List", "lon.spdu.mlist",
646 FT_UINT8, BASE_HEX, NULL, 0,
647 NULL, HFILL }
649 {&hf_lon_authpdu,
650 {"AuthPDU", "lon.authpdu",
651 FT_UINT8, BASE_HEX, NULL, 0,
652 NULL, HFILL }
654 {&hf_lon_authpdu_fmt,
655 {"FMT (same as AddrFmt)", "lon.authpdu_addrfmt",
656 FT_UINT8, BASE_HEX, NULL, 0xc,
657 NULL, HFILL }
659 {&hf_lon_authpdu_authpdu_type,
660 {"AuthPDU type", "lon.authpdu_type",
661 FT_UINT8, BASE_HEX, VALS(authpdu_type_vs), 0x2,
662 NULL, HFILL }
664 {&hf_lon_nv,
665 {"Network Variable", "lon.nv",
666 FT_UINT16, BASE_HEX, NULL, 0,
667 NULL, HFILL }
669 {&hf_lon_nv_dir,
670 {"NV direction", "lon.nv.dir",
671 FT_UINT16, BASE_HEX, NULL, 0x4000,
672 NULL, HFILL }
674 {&hf_lon_nv_selector,
675 {"NV selector", "lon.nv.selector",
676 FT_UINT16, BASE_HEX, NULL, 0x3fff,
677 NULL, HFILL }
679 {&hf_lon_app,
680 {"Application", "lon.application",
681 FT_UINT8, BASE_HEX, NULL, 0,
682 NULL, HFILL }
684 {&hf_lon_app_code,
685 {"Code", "lon.code",
686 FT_UINT8, BASE_HEX, NULL, 0x3f,
687 NULL, HFILL }
689 {&hf_lon_nm,
690 {"Network Management", "lon.nm",
691 FT_UINT8, BASE_HEX, NULL, 0,
692 NULL, HFILL }
694 {&hf_lon_nm_code,
695 {"Code", "lon.code",
696 FT_UINT8, BASE_HEX, VALS(nm_code_vs), 0xff,
697 NULL, HFILL }
699 {&hf_lon_nd,
700 {"Network Diagnostic", "lon.nd",
701 FT_UINT8, BASE_HEX, NULL, 0,
702 NULL, HFILL }
704 {&hf_lon_nd_code,
705 {"Code", "lon.code",
706 FT_UINT8, BASE_HEX, VALS(nd_code_vs), 0xff,
707 NULL, HFILL }
709 {&hf_lon_ff,
710 {"Foreign Frame", "lon.ff",
711 FT_UINT8, BASE_HEX, NULL, 0,
712 NULL, HFILL }
714 {&hf_lon_ff_code,
715 {"Code", "lon.code",
716 FT_UINT8, BASE_HEX, NULL, 0x0f,
717 NULL, HFILL }
719 {&hf_lon_name,
720 {"Node name", "lon.name",
721 FT_BYTES, BASE_NONE, NULL, 0,
722 NULL, HFILL }
724 #if 0
725 {&hf_lon_checksum,
726 {"Checksum", "lon.chksum",
727 FT_BYTES, BASE_NONE, NULL, 0,
728 NULL, HFILL }
730 #endif
733 static gint *ett[] =
735 &ett_lon,
736 &ett_address,
737 &ett_ppdu,
738 &ett_npdu,
739 &ett_tpdu,
740 &ett_spdu,
741 &ett_authpdu,
742 &ett_apdu,
743 &ett_nv,
744 &ett_app,
745 &ett_nm,
746 &ett_nd,
747 &ett_ff
750 static ei_register_info ei[] = {
751 { &ei_lon_tpdu_tpdu_type_unknown, { "lon.tpdu_type.unknown", PI_PROTOCOL, PI_WARN, "Unexpected TPDU type", EXPFILL }},
752 { &ei_lon_tpdu_spdu_type_unknown, { "lon.spdu_type.unknown", PI_PROTOCOL, PI_WARN, "Unexpected SPDU type", EXPFILL }},
753 { &ei_lon_tpdu_authpdu_type_unknown, { "lon.authpdu_type.unknown", PI_PROTOCOL, PI_WARN, "Unexpected AuthPDU type", EXPFILL }},
754 { &ei_lon_tpdu_apdu_dest_type, { "lon.authpdu_dest_type.unknown", PI_PROTOCOL, PI_WARN, "Malformed APDU destin&type", EXPFILL }},
757 expert_module_t* expert_lon;
759 proto_lon = proto_register_protocol("Local Operating Network",
760 "LON", "lon");
762 proto_register_field_array (proto_lon, hf, array_length (hf));
763 proto_register_subtree_array (ett, array_length (ett));
764 expert_lon = expert_register_protocol(proto_lon);
765 expert_register_field_array(expert_lon, ei, array_length(ei));
769 void
770 proto_reg_handoff_lon(void)
772 dissector_handle_t lon_handle;
774 lon_handle = new_create_dissector_handle(dissect_lon, proto_lon);
775 data_handle = find_dissector("data");
777 dissector_add_uint("cnip.protocol", 0, lon_handle);