Commit | Line | Data |
---|---|---|
165db1a8 | 1 | /* -*-c-*- |
2 | * | |
3cdc3f3a | 3 | * $Id$ |
165db1a8 | 4 | * |
28461f0e | 5 | * TrIPE protocol dissector for Wireshark |
165db1a8 | 6 | * |
7 | * (c) 2003 Straylight/Edgeware | |
8 | */ | |
9 | ||
10 | /*----- Licensing notice --------------------------------------------------* | |
11 | * | |
12 | * This file is part of Trivial IP Encryption (TrIPE). | |
13 | * | |
14 | * TrIPE is free software; you can redistribute it and/or modify | |
15 | * it under the terms of the GNU General Public License as published by | |
16 | * the Free Software Foundation; either version 2 of the License, or | |
17 | * (at your option) any later version. | |
18 | * | |
19 | * TrIPE is distributed in the hope that it will be useful, | |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 | * GNU General Public License for more details. | |
23 | * | |
24 | * You should have received a copy of the GNU General Public License | |
25 | * along with TrIPE; if not, write to the Free Software Foundation, | |
26 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
27 | */ | |
28 | ||
165db1a8 | 29 | /*----- Header files ------------------------------------------------------*/ |
30 | ||
31 | #include "config.h" | |
32 | ||
33 | #include <stdio.h> | |
34 | #include <stdlib.h> | |
35 | #include <string.h> | |
36 | ||
37 | #include <netinet/in.h> | |
38 | ||
39 | #include <glib.h> | |
40 | #include <gmodule.h> | |
28461f0e MW |
41 | #include <wireshark/config.h> |
42 | #include <wireshark/epan/packet.h> | |
43 | #include <wireshark/epan/prefs.h> | |
165db1a8 | 44 | |
45 | #include "tripe-protocol.h" | |
46 | ||
47 | /*----- Static variables --------------------------------------------------*/ | |
48 | ||
49 | static int proto_tripe = -1; | |
50 | ||
b5c45da1 | 51 | static guint hashsz = 20, tagsz = 10, ivsz = 8; |
52 | ||
52c03a2a | 53 | typedef struct hfmp { |
54 | int hf, hf_len, hf_val, tt; | |
55 | } hfmp; | |
56 | typedef struct hfge { | |
57 | int hf, hf_len, hf_val, hfx_len, hfx_val, hfy_len, hfy_val, tt; | |
58 | } hfge; | |
165db1a8 | 59 | |
60 | static int hf_tripe_cat = -1; | |
61 | static int hf_tripe_packet_type = -1; | |
62 | static int hf_tripe_ct = -1; | |
63 | static int hf_tripe_ct_seq = -1; | |
64 | static int hf_tripe_ct_iv = -1; | |
b5c45da1 | 65 | static int hf_tripe_ct_ct = -1; |
66 | static int hf_tripe_ct_tag = -1; | |
0ba8de86 | 67 | static int hf_tripe_misc_type = -1; |
68 | static int hf_tripe_misc_payload = -1; | |
165db1a8 | 69 | static int hf_tripe_kx_type = -1; |
52c03a2a | 70 | static hfge hf_tripe_kx_mychal = { -1, -1, -1, -1, -1, -1, -1, -1 }; |
165db1a8 | 71 | static int hf_tripe_kx_mycookie = -1; |
72 | static int hf_tripe_kx_yourcookie = -1; | |
73 | static hfmp hf_tripe_kx_check = { -1, -1, -1, -1 }; | |
74 | static int hf_tripe_huh = -1; | |
75 | ||
76 | static int tt_tripe = -1; | |
77 | static int tt_tripe_ct = -1; | |
78 | ||
79 | G_MODULE_EXPORT const gchar version[] = VERSION; | |
80 | ||
81 | /*----- Main code ---------------------------------------------------------*/ | |
82 | ||
b5c45da1 | 83 | static void prefcb(void) { } |
84 | ||
165db1a8 | 85 | static gint gethash(proto_tree *tt, int hf, tvbuff_t *b, gint off) |
86 | { | |
b5c45da1 | 87 | proto_tree_add_item(tt, hf, b, off, hashsz, FALSE); |
88 | return (off + hashsz); | |
165db1a8 | 89 | } |
90 | ||
91 | static gint getmp(proto_tree *tt, const hfmp *hf, tvbuff_t *b, gint off) | |
92 | { | |
93 | guint16 len = tvb_get_ntohs(b, off); | |
94 | proto_item *ti = proto_tree_add_item(tt, hf->hf, b, off, len + 2, FALSE); | |
95 | tt = proto_item_add_subtree(ti, hf->tt); | |
96 | proto_tree_add_item(tt, hf->hf_len, b, off, 2, FALSE); | |
97 | proto_tree_add_item(tt, hf->hf_val, b, off + 2, len, FALSE); | |
98 | return (off + 2 + len); | |
99 | } | |
100 | ||
52c03a2a | 101 | static gint getge(proto_tree *tt, const hfge *hf, tvbuff_t *b, gint off) |
102 | { | |
103 | guint16 len = tvb_get_ntohs(b, off), len2; | |
104 | guint r; | |
105 | proto_item *ti; | |
106 | r = tvb_length_remaining(b, off); | |
107 | if (r < 4 + len || | |
108 | (len2 = tvb_get_ntohs(b, off + 2 + len), r < 4 + len + len2)) { | |
109 | ti = proto_tree_add_item(tt, hf->hf, b, off, len + 2, FALSE); | |
110 | tt = proto_item_add_subtree(ti, hf->tt); | |
111 | proto_tree_add_item(tt, hf->hf_len, b, off, 2, FALSE); | |
112 | proto_tree_add_item(tt, hf->hf_val, b, off + 2, len, FALSE); | |
113 | r = off + len + 2; | |
114 | } else { | |
115 | ti = proto_tree_add_item(tt, hf->hf, b, off, len + len2 + 4, FALSE); | |
116 | tt = proto_item_add_subtree(ti, hf->tt); | |
117 | proto_tree_add_item(tt, hf->hfx_len, b, off, 2, FALSE); | |
118 | proto_tree_add_item(tt, hf->hfx_val, b, off + 2, len, FALSE); | |
119 | proto_tree_add_item(tt, hf->hfy_len, b, off + 2 + len, 2, FALSE); | |
120 | proto_tree_add_item(tt, hf->hfy_val, b, off + 4 + len, len2, FALSE); | |
121 | r = off + len + len2 + 4; | |
122 | } | |
123 | return (r); | |
124 | } | |
125 | ||
165db1a8 | 126 | static void dissect_tripe(tvbuff_t *b, packet_info *p, proto_tree *t) |
127 | { | |
128 | proto_item *ti; | |
129 | proto_tree *tt; | |
130 | guint8 ty; | |
3cdc3f3a | 131 | gint off = 0; |
165db1a8 | 132 | guint32 seq; |
133 | ||
134 | /* --- Initialize the summary cells --- */ | |
135 | ||
136 | if (check_col(p->cinfo, COL_PROTOCOL)) | |
137 | col_set_str(p->cinfo, COL_PROTOCOL, "TrIPE"); | |
3cdc3f3a | 138 | if (check_col(p->cinfo, COL_INFO)) |
139 | col_clear(p->cinfo, COL_INFO); | |
165db1a8 | 140 | ty = tvb_get_guint8(b, 0); |
141 | if (check_col(p->cinfo, COL_INFO)) { | |
142 | col_clear(p->cinfo, COL_INFO); | |
143 | switch (ty & MSG_CATMASK) { | |
144 | case MSG_PACKET: | |
145 | switch (ty & MSG_TYPEMASK) { | |
146 | case 0: | |
147 | col_set_str(p->cinfo, COL_INFO, "Packet data"); | |
148 | break; | |
149 | default: | |
150 | col_add_fstr(p->cinfo, COL_INFO, | |
151 | "Packet data, unknown type code %u", | |
152 | ty & MSG_TYPEMASK); | |
153 | break; | |
154 | } | |
155 | break; | |
156 | case MSG_KEYEXCH: | |
157 | switch (ty & MSG_TYPEMASK) { | |
158 | case KX_PRECHAL: | |
159 | col_set_str(p->cinfo, COL_INFO, "Key exchange, prechallenge"); | |
160 | break; | |
165db1a8 | 161 | case KX_CHAL: |
162 | col_set_str(p->cinfo, COL_INFO, "Key exchange, challenge"); | |
163 | break; | |
164 | case KX_REPLY: | |
165 | col_set_str(p->cinfo, COL_INFO, "Key exchange, reply"); | |
166 | break; | |
167 | case KX_SWITCH: | |
168 | col_set_str(p->cinfo, COL_INFO, "Key exchange, switch request"); | |
169 | break; | |
170 | case KX_SWITCHOK: | |
171 | col_set_str(p->cinfo, COL_INFO, "Key exchange, switch response"); | |
172 | break; | |
173 | default: | |
174 | col_add_fstr(p->cinfo, COL_INFO, | |
175 | "Key exchange, unknown type code %u", | |
176 | ty & MSG_TYPEMASK); | |
177 | break; | |
178 | } | |
179 | break; | |
0ba8de86 | 180 | case MSG_MISC: |
181 | switch (ty & MSG_TYPEMASK) { | |
182 | case MISC_NOP: | |
183 | col_set_str(p->cinfo, COL_INFO, "Miscellaneous, no-operation"); | |
184 | break; | |
185 | case MISC_PING: | |
186 | col_set_str(p->cinfo, COL_INFO, "Miscellaneous, transport ping"); | |
187 | break; | |
188 | case MISC_PONG: | |
189 | col_set_str(p->cinfo, COL_INFO, | |
190 | "Miscellaneous, transport ping reply"); | |
191 | break; | |
192 | case MISC_EPING: | |
193 | col_set_str(p->cinfo, COL_INFO, "Miscellaneous, encrypted ping"); | |
194 | break; | |
195 | case MISC_EPONG: | |
196 | col_set_str(p->cinfo, COL_INFO, | |
197 | "Miscellaneous, encrypted ping reply"); | |
198 | break; | |
37941236 | 199 | case MISC_GREET: |
200 | col_set_str(p->cinfo, COL_INFO, | |
201 | "Miscellaneous, greeting"); | |
202 | break; | |
0ba8de86 | 203 | default: |
204 | col_add_fstr(p->cinfo, COL_INFO, | |
205 | "Miscellaneous, unknown type code %u", | |
206 | ty & MSG_TYPEMASK); | |
207 | break; | |
208 | } | |
209 | break; | |
165db1a8 | 210 | default: |
211 | col_add_fstr(p->cinfo, COL_INFO, | |
212 | "Unknown category code %u, unknown type code %u", | |
213 | ty & MSG_CATMASK, ty & MSG_TYPEMASK); | |
214 | break; | |
215 | } | |
216 | } | |
217 | ||
218 | /* --- Fill in the tree --- */ | |
219 | ||
220 | if (t) { | |
221 | ti = proto_tree_add_item(t, proto_tripe, b, 0, -1, FALSE); | |
222 | tt = proto_item_add_subtree(ti, tt_tripe); | |
223 | ||
224 | proto_tree_add_item(tt, hf_tripe_cat, b, 0, 1, FALSE); | |
225 | ||
226 | off = 1; | |
227 | switch (ty & MSG_CATMASK) { | |
228 | case MSG_PACKET: | |
229 | proto_tree_add_item(tt, hf_tripe_packet_type, b, 0, 1, FALSE); | |
230 | switch (ty & MSG_TYPEMASK) { | |
231 | case 0: | |
232 | goto ct; | |
233 | default: | |
234 | goto huh; | |
235 | } | |
236 | break; | |
237 | case MSG_KEYEXCH: | |
238 | proto_tree_add_item(tt, hf_tripe_kx_type, b, 0, 1, FALSE); | |
239 | switch (ty & MSG_TYPEMASK) { | |
240 | case KX_PRECHAL: | |
52c03a2a | 241 | off = getge(tt, &hf_tripe_kx_mychal, b, off); |
165db1a8 | 242 | goto tail; |
165db1a8 | 243 | case KX_CHAL: |
52c03a2a | 244 | off = getge(tt, &hf_tripe_kx_mychal, b, off); |
165db1a8 | 245 | off = gethash(tt, hf_tripe_kx_yourcookie, b, off); |
246 | off = getmp(tt, &hf_tripe_kx_check, b, off); | |
247 | goto tail; | |
248 | case KX_REPLY: | |
28461f0e | 249 | off = getge(tt, &hf_tripe_kx_mychal, b, off); |
165db1a8 | 250 | off = gethash(tt, hf_tripe_kx_yourcookie, b, off); |
251 | off = getmp(tt, &hf_tripe_kx_check, b, off); | |
252 | goto ct; | |
253 | case KX_SWITCH: | |
254 | off = gethash(tt, hf_tripe_kx_mycookie, b, off); | |
255 | off = gethash(tt, hf_tripe_kx_yourcookie, b, off); | |
256 | goto ct; | |
257 | case KX_SWITCHOK: | |
258 | goto ct; | |
259 | default: | |
260 | goto huh; | |
261 | } | |
262 | break; | |
0ba8de86 | 263 | case MSG_MISC: |
264 | proto_tree_add_item(tt, hf_tripe_misc_type, b, 0, 1, FALSE); | |
265 | switch (ty & MSG_TYPEMASK) { | |
266 | case MISC_NOP: | |
267 | case MISC_PING: | |
268 | case MISC_PONG: | |
37941236 | 269 | case MISC_GREET: |
0ba8de86 | 270 | proto_tree_add_item(tt, hf_tripe_misc_payload, |
271 | b, off, -1, FALSE); | |
272 | goto done; | |
273 | case MISC_EPING: | |
274 | case MISC_EPONG: | |
275 | goto ct; | |
276 | default: | |
277 | goto huh; | |
278 | } | |
279 | break; | |
165db1a8 | 280 | default: |
281 | goto huh; | |
282 | } | |
283 | tail: | |
284 | if (tvb_offset_exists(b, off)) | |
285 | goto huh; | |
286 | goto done; | |
287 | huh: | |
288 | proto_tree_add_item(tt, hf_tripe_huh, b, off, -1, FALSE); | |
289 | goto done; | |
290 | ct: | |
291 | ti = proto_tree_add_item(tt, hf_tripe_ct, b, off, -1, FALSE); | |
b5c45da1 | 292 | seq = tvb_get_ntohl(b, off + tagsz); |
165db1a8 | 293 | proto_item_set_text(ti, "Encrypted ciphertext (sequence number %lu)", |
294 | (unsigned long)seq); | |
295 | tt = proto_item_add_subtree(ti, tt_tripe_ct); | |
b5c45da1 | 296 | if (tagsz) { |
297 | proto_tree_add_item(tt, hf_tripe_ct_tag, b, off, tagsz, FALSE); | |
298 | off += tagsz; | |
299 | } | |
165db1a8 | 300 | proto_tree_add_item(tt, hf_tripe_ct_seq, b, off, 4, FALSE); |
301 | off += 4; | |
b5c45da1 | 302 | if (ivsz) { |
303 | proto_tree_add_item(tt, hf_tripe_ct_iv, b, off, ivsz, FALSE); | |
304 | off += ivsz; | |
305 | } | |
306 | proto_tree_add_item(ti, hf_tripe_ct_ct, b, off, -1, FALSE); | |
165db1a8 | 307 | goto done; |
308 | done:; | |
309 | } | |
310 | } | |
311 | ||
312 | void proto_register_tripe(void) | |
313 | { | |
b5c45da1 | 314 | module_t *mod; |
315 | ||
165db1a8 | 316 | static value_string vs_kxtype[] = { |
317 | { KX_PRECHAL, "KX_PRECHAL (prechallenge)" }, | |
165db1a8 | 318 | { KX_CHAL, "KX_CHAL (challenge)" }, |
319 | { KX_REPLY, "KX_REPLY (reply)" }, | |
320 | { KX_SWITCH, "KX_SWITCH (switch request)" }, | |
321 | { KX_SWITCHOK, "KX_SWITCHOK (switch response)" }, | |
322 | { 0, 0 } | |
323 | }; | |
324 | ||
325 | static hf_register_info hfs[] = { | |
3cdc3f3a | 326 | { &hf_tripe_cat, { |
165db1a8 | 327 | "Message category", "tripe.cat", |
328 | FT_UINT8, BASE_HEX, 0, MSG_CATMASK | |
3cdc3f3a | 329 | } }, |
330 | { &hf_tripe_packet_type, { | |
165db1a8 | 331 | "Packet message type", "tripe.packet.type", |
332 | FT_UINT8, BASE_HEX, 0, MSG_TYPEMASK, | |
333 | "This is the TrIPE packet type subcode." | |
3cdc3f3a | 334 | } }, |
335 | { &hf_tripe_ct, { | |
165db1a8 | 336 | "Encrypted ciphertext", "tripe.ct", |
337 | FT_BYTES, BASE_NONE, 0, 0, | |
338 | "This is an encrypted message." | |
3cdc3f3a | 339 | } }, |
340 | { &hf_tripe_ct_seq, { | |
165db1a8 | 341 | "Ciphertext sequence number", "tripe.ct.seq", |
342 | FT_UINT32, BASE_DEC, 0, 0, | |
343 | "This is the unique sequence number for the ciphertext." | |
3cdc3f3a | 344 | } }, |
345 | { &hf_tripe_ct_iv, { | |
165db1a8 | 346 | "Ciphertext initialization vector", "tripe.ct.iv", |
347 | FT_BYTES, BASE_NONE, 0, 0, | |
348 | "This is the initialization vector used for the actual encryption." | |
3cdc3f3a | 349 | } }, |
350 | { &hf_tripe_ct_ct, { | |
b5c45da1 | 351 | "Actual encrypted data", "tripe.ct.ct", |
165db1a8 | 352 | FT_BYTES, BASE_NONE, 0, 0, |
b5c45da1 | 353 | "This is the encrypted message. Reading it ought to be hard." |
3cdc3f3a | 354 | } }, |
355 | { &hf_tripe_ct_tag, { | |
b5c45da1 | 356 | "Message authentication code", "tripe.ct.tag", |
165db1a8 | 357 | FT_BYTES, BASE_NONE, 0, 0, |
b5c45da1 | 358 | "This is the message authentication code tag for the ciphertext." |
3cdc3f3a | 359 | } }, |
0ba8de86 | 360 | { &hf_tripe_misc_type, { |
361 | "Miscellaneous message type", "tripe.misc.type", | |
362 | FT_UINT8, BASE_HEX, 0, MSG_TYPEMASK, | |
363 | "This is the TrIPE miscellaneous message type subcode." | |
364 | } }, | |
365 | { &hf_tripe_misc_payload, { | |
37941236 | 366 | "Miscellaneous message payload", "tripe.misc.payload", |
0ba8de86 | 367 | FT_BYTES, BASE_NONE, 0, 0, |
368 | "This is the miscellaneous message payload." | |
369 | } }, | |
3cdc3f3a | 370 | { &hf_tripe_kx_type, { |
165db1a8 | 371 | "Key-exchange message type", "tripe.kx.type", |
372 | FT_UINT8, BASE_HEX, vs_kxtype, MSG_TYPEMASK, | |
373 | "This is the TrIPE key-exchange type subcode." | |
3cdc3f3a | 374 | } }, |
375 | { &hf_tripe_kx_mychal.hf, { | |
165db1a8 | 376 | "Sender's challenge data", "tripe.kx.mychal", |
377 | FT_BYTES, BASE_NONE, 0, 0, | |
52c03a2a | 378 | "This is the sender's challenge." |
3cdc3f3a | 379 | } }, |
380 | { &hf_tripe_kx_mychal.hf_len, { | |
165db1a8 | 381 | "Challenge length", "tripe.kx.mychal.len", |
382 | FT_UINT16, BASE_DEC, 0, 0, | |
52c03a2a | 383 | "This is the length of the sender's challenge." |
3cdc3f3a | 384 | } }, |
385 | { &hf_tripe_kx_mychal.hf_val, { | |
52c03a2a | 386 | "Challenge", "tripe.kx.mychal.val", |
387 | FT_BYTES, BASE_NONE, 0, 0, | |
388 | "This is the value of the sender's challenge." | |
3cdc3f3a | 389 | } }, |
390 | { &hf_tripe_kx_mychal.hfx_len, { | |
52c03a2a | 391 | "Challenge x length", "tripe.kx.mychal.x.len", |
392 | FT_UINT16, BASE_DEC, 0, 0, | |
393 | "This is the length of the sender's challenge x-coordinate." | |
3cdc3f3a | 394 | } }, |
e94fafe4 | 395 | { &hf_tripe_kx_mychal.hfx_val, { |
52c03a2a | 396 | "Challenge x value", "tripe.kx.mychal.x.val", |
397 | FT_BYTES, BASE_NONE, 0, 0, | |
398 | "This is the value of the sender's challenge x-coordinate." | |
3cdc3f3a | 399 | } }, |
400 | { &hf_tripe_kx_mychal.hfy_len, { | |
52c03a2a | 401 | "Challenge y length", "tripe.kx.mychal.y.len", |
402 | FT_UINT16, BASE_DEC, 0, 0, | |
403 | "This is the length of the sender's challenge x-coordinate." | |
3cdc3f3a | 404 | } }, |
e94fafe4 | 405 | { &hf_tripe_kx_mychal.hfy_val, { |
52c03a2a | 406 | "Challenge y value", "tripe.kx.mychal.y.val", |
165db1a8 | 407 | FT_BYTES, BASE_NONE, 0, 0, |
52c03a2a | 408 | "This is the value of the sender's challenge x-coordinate." |
3cdc3f3a | 409 | } }, |
410 | { &hf_tripe_kx_mycookie, { | |
165db1a8 | 411 | "Sender's hashed cookie", "tripe.kx.mycookie", |
412 | FT_BYTES, BASE_NONE, 0, 0, | |
413 | "This is the hash of the sender's challenge." | |
3cdc3f3a | 414 | } }, |
415 | { &hf_tripe_kx_yourcookie, { | |
165db1a8 | 416 | "Recipient's hashed cookie", "tripe.kx.yourcookie", |
417 | FT_BYTES, BASE_NONE, 0, 0, | |
418 | "This is the hash of the recipient's challenge." | |
3cdc3f3a | 419 | } }, |
420 | { &hf_tripe_kx_check.hf, { | |
165db1a8 | 421 | "Challenge check-value", "tripe.kx.check", |
422 | FT_BYTES, BASE_NONE, 0, 0, | |
423 | "This is an encrypted check-value which proves that the sender " | |
424 | "knows the answer to the challenge, and that it is therefore honest." | |
3cdc3f3a | 425 | } }, |
426 | { &hf_tripe_kx_check.hf_len, { | |
165db1a8 | 427 | "Check-value length", "tripe.kx.check.len", |
428 | FT_UINT16, BASE_DEC, 0, 0, | |
429 | "This is the length of the encrypted check-value." | |
3cdc3f3a | 430 | } }, |
431 | { &hf_tripe_kx_check.hf_val, { | |
165db1a8 | 432 | "Check-value data", "tripe.kx.check.val", |
433 | FT_BYTES, BASE_NONE, 0, 0, | |
434 | "This is the actual encrypted check-value." | |
3cdc3f3a | 435 | } }, |
436 | { &hf_tripe_huh, { | |
165db1a8 | 437 | "Unknown data", "tripe.huh", |
438 | FT_BYTES, BASE_NONE, 0, 0, | |
439 | "I don't know what's meant to appear here." | |
3cdc3f3a | 440 | } }, |
165db1a8 | 441 | }; |
442 | ||
443 | static gint *tts[] = { | |
444 | &tt_tripe, | |
445 | &tt_tripe_ct, | |
446 | &hf_tripe_kx_mychal.tt, | |
447 | &hf_tripe_kx_check.tt, | |
448 | }; | |
449 | ||
450 | proto_tripe = proto_register_protocol("TrIPE", "TrIPE", "tripe"); | |
451 | proto_register_field_array(proto_tripe, hfs, array_length(hfs)); | |
452 | proto_register_subtree_array(tts, array_length(tts)); | |
b5c45da1 | 453 | |
454 | mod = prefs_register_protocol(proto_tripe, prefcb); | |
455 | prefs_register_uint_preference(mod, "hashsz", "Hash length", | |
456 | "hash function output length (in octets)", | |
457 | 10, &hashsz); | |
458 | prefs_register_uint_preference(mod, "tagsz", "MAC tag length", | |
459 | "MAC tag length (in octets)", 10, &tagsz); | |
460 | prefs_register_uint_preference(mod, "ivsz", "IV length", | |
461 | "block cipher initialization vector length" | |
462 | " (in octets)", | |
463 | 10, &ivsz); | |
165db1a8 | 464 | } |
465 | ||
466 | void proto_reg_handoff_tripe(void) | |
467 | { | |
468 | dissector_handle_t dh; | |
469 | ||
470 | dh = create_dissector_handle(dissect_tripe, proto_tripe); | |
471 | dissector_add("udp.port", 22003, dh); | |
472 | } | |
473 | ||
474 | G_MODULE_EXPORT void plugin_reg_handoff(void) | |
475 | { | |
476 | proto_reg_handoff_tripe(); | |
477 | } | |
478 | ||
3cdc3f3a | 479 | G_MODULE_EXPORT void plugin_register(void) |
165db1a8 | 480 | { |
165db1a8 | 481 | if (proto_tripe == -1) |
482 | proto_register_tripe(); | |
483 | } | |
484 | ||
485 | /*----- That's all, folks -------------------------------------------------*/ |