Add some additional sanity checking.
[obnox/wireshark/wip.git] / packet-llc.c
1 /* packet-llc.c
2  * Routines for IEEE 802.2 LLC layer
3  * Gilbert Ramirez <gram@alumni.rice.edu>
4  *
5  * $Id: packet-llc.c,v 1.116 2003/10/01 07:11:44 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <glib.h>
31 #include <epan/packet.h>
32 #include "oui.h"
33 #include "xdlc.h"
34 #include "etypes.h"
35 #include "llcsaps.h"
36 #include "bridged_pids.h"
37 #include "ppptypes.h"
38 #include "arcnet_pids.h"
39 #include "packet-fc.h"
40 #include "packet-ip.h"
41 #include "packet-ipx.h"
42 #include "packet-netbios.h"
43 #include "packet-vines.h"
44 #include <epan/sna-utils.h>
45
46 #include "packet-llc.h"
47
48 #define UDP_PORT_LLC1   12000
49 #define UDP_PORT_LLC2   12001
50 #define UDP_PORT_LLC3   12002
51 #define UDP_PORT_LLC4   12003
52 #define UDP_PORT_LLC5   12004
53
54 static int proto_llc = -1;
55 static int hf_llc_dsap = -1;
56 static int hf_llc_ssap = -1;
57 static int hf_llc_dsap_ig = -1;
58 static int hf_llc_ssap_cr = -1;
59 static int hf_llc_ctrl = -1;
60 static int hf_llc_type = -1;
61 static int hf_llc_oui = -1;
62 static int hf_llc_pid = -1;
63
64 static gint ett_llc = -1;
65 static gint ett_llc_ctrl = -1;
66
67 static dissector_table_t subdissector_table;
68 static dissector_table_t xid_subdissector_table;
69
70 static dissector_handle_t bpdu_handle;
71 static dissector_handle_t eth_handle;
72 static dissector_handle_t fddi_handle;
73 static dissector_handle_t tr_handle;
74 static dissector_handle_t data_handle;
75
76 /*
77  * Group/Individual bit, in the DSAP.
78  */
79 #define DSAP_GI_BIT     0x01
80
81 /*
82  * Command/Response bit, in the SSAP.
83  *
84  * The low-order bit of the SSAP apparently determines whether this
85  * is a request or a response.  (RFC 1390, "Transmission of IP and
86  * ARP over FDDI Networks", says
87  *
88  *      Command frames are identified by having the low order
89  *      bit of the SSAP address reset to zero.  Response frames
90  *      have the low order bit of the SSAP address set to one.
91  *
92  * and a page I've seen seems to imply that's part of 802.2.)
93  */
94 #define SSAP_CR_BIT     0x01
95
96 /*
97  * Mask to extrace the SAP number from the DSAP or the SSAP.
98  */
99 #define SAP_MASK        0xFE
100
101 /*
102  * These are for SSAP and DSAP, wth last bit always zero.
103  * XXX - some DSAPs come in separate "individual" and "group" versions,
104  * with the last bit 0 and 1, respectively (e.g., LLC Sub-layer Management,
105  * IBM SNA Path Control, IBM Net Management), but, whilst 0xFE is
106  * the ISO Network Layer Protocol, 0xFF is the Global LSAP.
107  */
108 const value_string sap_vals[] = {
109         { SAP_NULL,           "NULL LSAP" },
110         { SAP_LLC_SLMGMT,     "LLC Sub-Layer Management" },
111         { SAP_SNA_PATHCTRL,   "SNA Path Control" },
112         { SAP_IP,             "TCP/IP" },
113         { SAP_SNA1,           "SNA" },
114         { SAP_SNA2,           "SNA" },
115         { SAP_PROWAY_NM_INIT, "PROWAY (IEC955) Network Management and Initialization" },
116         { SAP_NETWARE1,       "NetWare (unofficial?)" },
117         { SAP_OSINL1,         "ISO Network Layer (OSLAN 1)" },
118         { SAP_TI,             "Texas Instruments" },
119         { SAP_OSINL2,         "ISO Network Layer (unofficial?)" },
120         { SAP_OSINL3,         "ISO Network Layer (unofficial?)" },
121         { SAP_BPDU,           "Spanning Tree BPDU" },
122         { SAP_RS511,          "EIA RS-511 Manufacturing Message Service" },
123         { SAP_OSINL4,         "ISO Network Layer (OSLAN 2)" },
124         { SAP_X25,            "ISO 8208 (X.25 over 802.2)" },
125         /*
126          * XXX - setting the group bit of SAP_X25 make 0x7F; is this just
127          * a group version of that?
128          */
129         { 0x7F,               "ISO 802.2" },
130         { SAP_XNS,            "XNS" },
131         { SAP_BACNET,         "BACnet" },
132         { SAP_NESTAR,         "Nestar" },
133         { SAP_PROWAY_ASLM,    "PROWAY (IEC955) Active Station List Maintenance" },
134         { SAP_ARP,            "ARP" },  /* XXX - hand to "dissect_arp()"? */
135         { SAP_SNAP,           "SNAP" },
136         { SAP_VINES1,         "Banyan Vines" },
137         { SAP_VINES2,         "Banyan Vines" },
138         { SAP_NETWARE2,       "NetWare" },
139         { SAP_NETBIOS,        "NetBIOS" },
140         { SAP_IBMNM,          "IBM Net Management" },
141         { SAP_HPEXT,          "HP Extended LLC" },
142         { SAP_UB,             "Ungermann-Bass" },
143         { SAP_RPL,            "Remote Program Load" },
144         { SAP_OSINL5,         "ISO Network Layer" },
145         { SAP_GLOBAL,         "Global LSAP" },
146         { 0x00,               NULL }
147 };
148
149 /*
150  * See
151  *
152  * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/vlan.htm
153  *
154  * for the PIDs for VTP and DRiP that go with an OUI of OUI_CISCO.
155  */
156 const value_string oui_vals[] = {
157         { OUI_ENCAP_ETHER, "Encapsulated Ethernet" },
158 /*
159 http://www.cisco.com/univercd/cc/td/doc/product/software/ios113ed/113ed_cr/ibm_r/brprt1/brsrb.htm
160 */
161         { OUI_CISCO,       "Cisco" },
162         { OUI_CISCO_90,    "Cisco IOS 9.0 Compatible" },
163         { OUI_BRIDGED,     "Frame Relay or ATM bridged frames" },
164                                 /* RFC 2427, RFC 2684 */
165         { OUI_ATM_FORUM,   "ATM Forum" },
166         { OUI_CABLE_BPDU,  "DOCSIS Spanning Tree" }, /* DOCSIS spanning tree BPDU */
167         { OUI_APPLE_ATALK, "Apple (AppleTalk)" },
168         { OUI_NORTEL,      "Nortel Networks SONMP" },
169         { 0,               NULL }
170 };
171
172 /*
173  * Hash table for translating OUIs to a dissector table/field info pair;
174  * the dissector table maps PID values to dissectors, and the field
175  * corresponds to the PID for that OUI.
176  */
177 typedef struct {
178         dissector_table_t table;
179         hf_register_info *field_info;
180 } oui_info_t;
181
182 static GHashTable *oui_info_table = NULL;
183
184 /*
185  * Add an entry for a new OUI.
186  */
187 void
188 llc_add_oui(guint32 oui, const char *table_name, char *table_ui_name,
189     hf_register_info *hf_item)
190 {
191         oui_info_t *new_info;
192
193         new_info = g_malloc(sizeof (oui_info_t));
194         new_info->table = register_dissector_table(table_name,
195             table_ui_name, FT_UINT16, BASE_HEX);
196         new_info->field_info = hf_item;
197
198         /*
199          * Create the hash table for OUI information, if it doesn't
200          * already exist.
201          */
202         if (oui_info_table == NULL) {
203                 oui_info_table = g_hash_table_new(g_direct_hash,
204                     g_direct_equal);
205         }
206         g_hash_table_insert(oui_info_table, (gpointer)oui, new_info);
207 }
208
209 void
210 capture_llc(const guchar *pd, int offset, int len, packet_counts *ld) {
211
212         int             is_snap;
213         guint16         control;
214         int             llc_header_len;
215         guint32         oui;
216         guint16         etype;
217
218         if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
219                 ld->other++;
220                 return;
221         }
222         is_snap = (pd[offset] == SAP_SNAP) && (pd[offset+1] == SAP_SNAP);
223         llc_header_len = 2;     /* DSAP + SSAP */
224
225         /*
226          * XXX - the page referred to in the comment above about the
227          * Command/Response bit also implies that LLC Type 2 always
228          * uses extended operation, so we don't need to determine
229          * whether it's basic or extended operation; is that the case?
230          */
231         control = get_xdlc_control(pd, offset+2, pd[offset+1] & SSAP_CR_BIT);
232         llc_header_len += XDLC_CONTROL_LEN(control, TRUE);
233         if (is_snap)
234                 llc_header_len += 5;    /* 3 bytes of OUI, 2 bytes of protocol ID */
235         if (!BYTES_ARE_IN_FRAME(offset, len, llc_header_len)) {
236                 ld->other++;
237                 return;
238         }
239
240         if (is_snap) {
241                 oui = pd[offset+3] << 16 | pd[offset+4] << 8 | pd[offset+5];
242                 if (XDLC_IS_INFORMATION(control)) {
243                         etype = pntohs(&pd[offset+6]);
244                         switch (oui) {
245
246                         case OUI_ENCAP_ETHER:
247                         case OUI_CISCO_90:
248                         case OUI_APPLE_ATALK:
249                                 /* No, I have no idea why Apple used
250                                    one of their own OUIs, rather than
251                                    OUI_ENCAP_ETHER, and an Ethernet
252                                    packet type as protocol ID, for
253                                    AppleTalk data packets - but used
254                                    OUI_ENCAP_ETHER and an Ethernet
255                                    packet type for AARP packets. */
256                                 capture_ethertype(etype, pd, offset+8, len,
257                                     ld);
258                                 break;
259                         case OUI_CISCO:
260                                 capture_ethertype(etype, pd, offset + 8, len,
261                                     ld);
262                                 break;
263                         default:
264                                 ld->other++;
265                                 break;
266                         }
267                 }
268         }
269         else {
270                 /* non-SNAP */
271                 if (XDLC_IS_INFORMATION(control)) {
272                         switch (pd[offset]) {
273
274                         case SAP_IP:
275                                 capture_ip(pd, offset + llc_header_len, len,
276                                     ld);
277                                 break;
278
279                         case SAP_NETWARE1:
280                         case SAP_NETWARE2:
281                                 capture_ipx(ld);
282                                 break;
283
284                         case SAP_NETBIOS:
285                                 capture_netbios(ld);
286                                 break;
287
288                         case SAP_VINES1:
289                         case SAP_VINES2:
290                                 capture_vines(ld);
291                                 break;
292
293                         default:
294                                 ld->other++;
295                                 break;
296                         }
297                 }
298         }
299 }
300
301 static void
302 dissect_llc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
303 {
304         proto_tree      *llc_tree = NULL;
305         proto_item      *ti = NULL;
306         int             is_snap;
307         guint16         control;
308         int             llc_header_len;
309         guint8          dsap, ssap;
310         tvbuff_t        *next_tvb;
311
312         if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
313                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LLC");
314         }
315         if (check_col(pinfo->cinfo, COL_INFO)) {
316                 col_clear(pinfo->cinfo, COL_INFO);
317         }
318
319         dsap = tvb_get_guint8(tvb, 0);
320         if (tree) {
321                 ti = proto_tree_add_item(tree, proto_llc, tvb, 0, -1, FALSE);
322                 llc_tree = proto_item_add_subtree(ti, ett_llc);
323                 proto_tree_add_uint(llc_tree, hf_llc_dsap, tvb, 0,
324                         1, dsap & SAP_MASK);
325                 proto_tree_add_boolean(llc_tree, hf_llc_dsap_ig, tvb, 0,
326                         1, dsap & DSAP_GI_BIT);
327         } else
328                 llc_tree = NULL;
329
330         ssap = tvb_get_guint8(tvb, 1);
331         if (tree) {
332                 proto_tree_add_uint(llc_tree, hf_llc_ssap, tvb, 1,
333                         1, ssap & SAP_MASK);
334                 proto_tree_add_boolean(llc_tree, hf_llc_ssap_cr, tvb, 1,
335                         1, ssap & SSAP_CR_BIT);
336         } else
337                 llc_tree = NULL;
338
339         is_snap = (dsap == SAP_SNAP) && (ssap == SAP_SNAP);
340         llc_header_len = 2;     /* DSAP + SSAP */
341
342         /*
343          * XXX - the page referred to in the comment above about the
344          * Command/Response bit also implies that LLC Type 2 always
345          * uses extended operation, so we don't need to determine
346          * whether it's basic or extended operation; is that the case?
347          */
348         control = dissect_xdlc_control(tvb, 2, pinfo, llc_tree,
349                                 hf_llc_ctrl, ett_llc_ctrl,
350                                 ssap & SSAP_CR_BIT, TRUE, FALSE);
351         llc_header_len += XDLC_CONTROL_LEN(control, TRUE);
352         if (is_snap)
353                 llc_header_len += 5;    /* 3 bytes of OUI, 2 bytes of protocol ID */
354
355         if (tree)
356                 proto_item_set_len(ti, llc_header_len);
357
358         if (is_snap) {
359                 dissect_snap(tvb, 3, pinfo, tree, llc_tree, control,
360                     hf_llc_oui, hf_llc_type, hf_llc_pid, 2);
361         }
362         else {
363                 if (check_col(pinfo->cinfo, COL_INFO)) {
364                         col_append_fstr(pinfo->cinfo, COL_INFO,
365                             "; DSAP %s %s, SSAP %s %s",
366                             val_to_str(dsap & SAP_MASK, sap_vals, "%02x"),
367                             dsap & DSAP_GI_BIT ?
368                               "Group" : "Individual",
369                             val_to_str(ssap & SAP_MASK, sap_vals, "%02x"),
370                             ssap & SSAP_CR_BIT ?
371                               "Response" : "Command"
372                         );
373                 }
374
375                 if (tvb_length_remaining(tvb, llc_header_len) > 0) {
376                         next_tvb = tvb_new_subset(tvb, llc_header_len, -1, -1);
377                         if (XDLC_IS_INFORMATION(control)) {
378                                 /*
379                                  * Non-SNAP I or UI frame.
380                                  * Try the regular LLC subdissector table
381                                  * with the DSAP.
382                                  */
383                                 if (!dissector_try_port(subdissector_table,
384                                     dsap, next_tvb, pinfo, tree)) {
385                                         call_dissector(data_handle, next_tvb,
386                                             pinfo, tree);
387                                 }
388                         } else if ((control & (XDLC_U_MODIFIER_MASK|XDLC_U))
389                             == (XDLC_XID|XDLC_U)) {
390                                 /*
391                                  * Non-SNAP XID frame.
392                                  * Try the XID LLC subdissector table
393                                  * with the DSAP.
394                                  */
395                                 if (!dissector_try_port(xid_subdissector_table,
396                                     dsap, next_tvb, pinfo, tree)) {
397                                         call_dissector(data_handle, next_tvb,
398                                             pinfo, tree);
399                                 }
400                         } else {
401                                 call_dissector(data_handle, next_tvb, pinfo,
402                                     tree);
403                         }
404                 }
405         }
406 }
407
408 /*
409  * Dissect SNAP header; used elsewhere, e.g. in the Frame Relay dissector.
410  */
411 void
412 dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
413     proto_tree *snap_tree, int control, int hf_oui, int hf_type, int hf_pid,
414     int bridge_pad)
415 {
416         guint32         oui;
417         guint16         etype;
418         tvbuff_t        *next_tvb;
419         oui_info_t      *oui_info;
420         dissector_table_t subdissector_table;
421         int             hf;
422
423         oui =   tvb_get_ntoh24(tvb, offset);
424         etype = tvb_get_ntohs(tvb, offset+3);
425
426         if (check_col(pinfo->cinfo, COL_INFO)) {
427                 col_append_fstr(pinfo->cinfo, COL_INFO,
428                     "; SNAP, OUI 0x%06X (%s), PID 0x%04X",
429                     oui, val_to_str(oui, oui_vals, "Unknown"), etype);
430         }
431         if (tree) {
432                 proto_tree_add_uint(snap_tree, hf_oui, tvb, offset, 3, oui);
433         }
434
435         switch (oui) {
436
437         case OUI_ENCAP_ETHER:
438         case OUI_CISCO_90:
439         case OUI_APPLE_ATALK:
440                 /* No, I have no idea why Apple used
441                    one of their own OUIs, rather than
442                    OUI_ENCAP_ETHER, and an Ethernet
443                    packet type as protocol ID, for
444                    AppleTalk data packets - but used
445                    OUI_ENCAP_ETHER and an Ethernet
446                    packet type for AARP packets. */
447                 if (XDLC_IS_INFORMATION(control)) {
448                         ethertype(etype, tvb, offset+5,
449                             pinfo, tree, snap_tree, hf_type, -1, 0);
450                 } else {
451                         next_tvb = tvb_new_subset(tvb, offset+5, -1, -1);
452                         call_dissector(data_handle,next_tvb, pinfo, tree);
453                 }
454                 break;
455
456         case OUI_BRIDGED:
457                 /*
458                  * MAC frames bridged over ATM (RFC 2684) or Frame Relay
459                  * (RFC 2427).
460                  *
461                  * We have to figure out how much padding to put
462                  * into the frame.  We were handed a "bridge_pad"
463                  * argument which should be 0 for Frame Relay and
464                  * 2 for ATM; we add to that the amount of padding
465                  * common to both bridging types.
466                  */
467                 if (tree) {
468                         proto_tree_add_uint(snap_tree, hf_pid, tvb, offset+3, 2,
469                             etype);
470                 }
471
472                 switch (etype) {
473
474                 case BPID_ETH_WITH_FCS:
475                 case BPID_ETH_WITHOUT_FCS:
476                         next_tvb = tvb_new_subset(tvb, offset+5+bridge_pad,
477                             -1, -1);
478                         call_dissector(eth_handle, next_tvb, pinfo, tree);
479                         break;
480
481                 case BPID_802_5_WITH_FCS:
482                 case BPID_802_5_WITHOUT_FCS:
483                         /*
484                          * We treat the last padding byte as the Access
485                          * Control byte, as that's what the Token
486                          * Ring dissector expects the first byte to
487                          * be.
488                          */
489                         next_tvb = tvb_new_subset(tvb, offset+5+bridge_pad,
490                             -1, -1);
491                         call_dissector(tr_handle, next_tvb, pinfo, tree);
492                         break;
493
494                 case BPID_FDDI_WITH_FCS:
495                 case BPID_FDDI_WITHOUT_FCS:
496                         next_tvb = tvb_new_subset(tvb, offset+5+1+bridge_pad,
497                             -1, -1);
498                         call_dissector(fddi_handle, next_tvb, pinfo, tree);
499                         break;
500
501                 case BPID_BPDU:
502                         next_tvb = tvb_new_subset(tvb, offset+5, -1, -1);
503                         call_dissector(bpdu_handle, next_tvb, pinfo, tree);
504                         break;
505
506                 default:
507                         next_tvb = tvb_new_subset(tvb, offset+5, -1, -1);
508                         call_dissector(data_handle,next_tvb, pinfo, tree);
509                         break;
510                 }
511                 break;
512
513         case OUI_CABLE_BPDU:    /* DOCSIS cable modem spanning tree BPDU */
514                 if (tree) {
515                         proto_tree_add_uint(snap_tree, hf_pid, tvb, offset+3, 2,
516                             etype);
517                 }
518                 next_tvb = tvb_new_subset(tvb, offset+5, -1, -1);
519                 call_dissector(bpdu_handle, next_tvb, pinfo, tree);
520                 break;
521
522         default:
523                 /*
524                  * Do we have information for this OUI?
525                  */
526                 oui_info = g_hash_table_lookup(oui_info_table, (gpointer)oui);
527                 if (oui_info != NULL) {
528                         /*
529                          * Yes - use it.
530                          */
531                         hf = *oui_info->field_info->p_id;
532                         subdissector_table = oui_info->table;
533                 } else {
534                         /*
535                          * No, use hf_pid for the PID and just dissect
536                          * the payload as data.
537                          */
538                         hf = hf_pid;
539                         subdissector_table = NULL;
540                 }
541                 if (tree) {
542                         proto_tree_add_uint(snap_tree, hf, tvb, offset+3, 2,
543                             etype);
544                 }
545                 next_tvb = tvb_new_subset(tvb, offset+5, -1, -1);
546                 if (XDLC_IS_INFORMATION(control)) {
547                         if (subdissector_table != NULL) {
548                                 /* do lookup with the subdissector table */
549                                 if (dissector_try_port(subdissector_table,
550                                     etype, next_tvb, pinfo, tree))
551                                         break;
552                         }
553                 }
554                 call_dissector(data_handle, next_tvb, pinfo, tree);
555                 break;
556         }
557 }
558
559 void
560 proto_register_llc(void)
561 {
562         static struct true_false_string ig_bit = { "Group", "Individual" };
563         static struct true_false_string cr_bit = { "Response", "Command" };
564
565         static hf_register_info hf[] = {
566                 { &hf_llc_dsap,
567                 { "DSAP",       "llc.dsap", FT_UINT8, BASE_HEX,
568                         VALS(sap_vals), 0x0, "", HFILL }},
569
570                 { &hf_llc_dsap_ig,
571                 { "IG Bit",     "llc.dsap.ig", FT_BOOLEAN, BASE_HEX,
572                         &ig_bit, 0x0, "Individual/Group", HFILL }},
573
574                 { &hf_llc_ssap,
575                 { "SSAP", "llc.ssap", FT_UINT8, BASE_HEX,
576                         VALS(sap_vals), 0x0, "", HFILL }},
577
578                 { &hf_llc_ssap_cr,
579                 { "CR Bit", "llc.ssap.cr", FT_BOOLEAN, BASE_HEX,
580                         &cr_bit, 0x0, "Command/Response", HFILL }},
581
582                 { &hf_llc_ctrl,
583                 { "Control", "llc.control", FT_UINT16, BASE_HEX,
584                         NULL, 0x0, "", HFILL }},
585
586                 /* registered here but handled in ethertype.c */
587                 { &hf_llc_type,
588                 { "Type", "llc.type", FT_UINT16, BASE_HEX,
589                         VALS(etype_vals), 0x0, "", HFILL }},
590
591                 { &hf_llc_oui,
592                 { "Organization Code",  "llc.oui", FT_UINT24, BASE_HEX,
593                         VALS(oui_vals), 0x0, "", HFILL }},
594
595                 { &hf_llc_pid,
596                 { "Protocol ID", "llc.pid", FT_UINT16, BASE_HEX,
597                         NULL, 0x0, "", HFILL }}
598         };
599         static gint *ett[] = {
600                 &ett_llc,
601                 &ett_llc_ctrl,
602         };
603
604         proto_llc = proto_register_protocol("Logical-Link Control", "LLC", "llc");
605         proto_register_field_array(proto_llc, hf, array_length(hf));
606         proto_register_subtree_array(ett, array_length(ett));
607
608 /* subdissector code */
609         subdissector_table = register_dissector_table("llc.dsap",
610           "LLC SAP", FT_UINT8, BASE_HEX);
611         xid_subdissector_table = register_dissector_table("llc.xid_dsap",
612           "LLC XID SAP", FT_UINT8, BASE_HEX);
613
614         register_dissector("llc", dissect_llc, proto_llc);
615 }
616
617 static void
618 register_hf(gpointer key _U_, gpointer value, gpointer user_data _U_)
619 {
620         oui_info_t *info = value;
621
622         proto_register_field_array(proto_llc, info->field_info, 1);
623 }
624
625 void
626 proto_reg_handoff_llc(void)
627 {
628         dissector_handle_t llc_handle;
629
630         /*
631          * Get handles for the BPDU, Ethernet, FDDI, and Token Ring
632          * dissectors.
633          */
634         bpdu_handle = find_dissector("bpdu");
635         eth_handle = find_dissector("eth");
636         fddi_handle = find_dissector("fddi");
637         tr_handle = find_dissector("tr");
638         data_handle = find_dissector("data");
639
640         llc_handle = find_dissector("llc");
641         dissector_add("wtap_encap", WTAP_ENCAP_ATM_RFC1483, llc_handle);
642         /* RFC 2043 */
643         dissector_add("ppp.protocol", PPP_LLC, llc_handle);
644         /* RFC 2353 */
645         dissector_add("udp.port", UDP_PORT_LLC1, llc_handle);
646         dissector_add("udp.port", UDP_PORT_LLC2, llc_handle);
647         dissector_add("udp.port", UDP_PORT_LLC3, llc_handle);
648         dissector_add("udp.port", UDP_PORT_LLC4, llc_handle);
649         dissector_add("udp.port", UDP_PORT_LLC5, llc_handle);
650         /* IP-over-FC when we have the full FC frame */
651         dissector_add("fc.ftype", FC_FTYPE_IP, llc_handle);
652
653         /*
654          * BACNET-over-ARCNET is really BACNET-over-802.2 LLC-over-ARCNET,
655          * apparently.
656          */
657         dissector_add("arcnet.protocol_id", ARCNET_PROTO_BACNET, llc_handle);
658
659         /*
660          * Register all the fields for PIDs for various OUIs.
661          */
662         g_hash_table_foreach(oui_info_table, register_hf, NULL);
663 }