Line data Source code
1 : /* $Id: gmp_private.h 346474 2009-11-14 10:18:58Z ssiano $
2 : *
3 : * gmp_private.h - Private definitions for GMP Host/Router support
4 : *
5 : * Dave Katz, March 2008
6 : *
7 : * Copyright (c) 2008, Juniper Networks, Inc.
8 : * All rights reserved.
9 : *
10 : * This module defines the shared private data structures for GMP host
11 : * and router support. This file should only be used internally by GMP.
12 : */
13 :
14 : #ifndef __GMP_PRIVATE_H__
15 : #define __GMP_PRIVATE_H__
16 :
17 : #include "bitvector.h"
18 : #include "ordinal.h"
19 :
20 : /*
21 : * EMBEDDED_STRUCT_TO_STRUCT
22 : *
23 : * This macro creates an inline function to translate the address of
24 : * one structure embedded in another to an address of the enclosing
25 : * structure. The inline returns NULL if the address passed to it was
26 : * NULL.
27 : */
28 : #define EMBEDDED_STRUCT_TO_STRUCT(procname, outerstruct, innerstruct, field) \
29 : static inline outerstruct * procname (innerstruct *ptr) \
30 : { \
31 : if (ptr)\
32 : return ((outerstruct *) (((uint8_t *) ptr) - \
33 : offsetof(outerstruct, field))); \
34 : return NULL; \
35 : }
36 :
37 : /*
38 : * Generic GMP version. This refers to the *capabilities* of a version,
39 : * rather than the version number itself, since MLD and IGMP have different
40 : * protocol version numbers that correspond to the same functionality.
41 : */
42 : typedef enum {
43 : GMP_VERSION_INVALID = 0, /* Invalid version */
44 : GMP_VERSION_BASIC, /* Joins only */
45 : GMP_VERSION_LEAVES, /* Joins and leaves */
46 : GMP_VERSION_SOURCES /* Source information */
47 : } gmp_version;
48 :
49 : #define GMP_VERSION_DEFAULT GMP_VERSION_SOURCES /* Default version */
50 : #define GMP_ROBUSTNESS_DEFAULT 2 /* Retransmission count */
51 : #define GMP_UNSOL_RPT_IVL_DEFAULT 1000 /* Unsolicited report delay (msec) */
52 :
53 : #ifndef MSECS_PER_SEC
54 : #define MSECS_PER_SEC 1000 /* Milliseconds per second */
55 : #endif
56 :
57 :
58 : /*
59 : * Address list alloc entry callback type
60 : *
61 : * This defines the callback to allocate an address list entry.
62 : *
63 : * Returns a pointer to an address list entry, or NULL if out of memory.
64 : */
65 : typedef struct gmp_addr_list_entry_ * (*gmp_addr_list_alloc_func)(void *ctx);
66 :
67 :
68 : /*
69 : * Address list free entry callback type
70 : *
71 : * This defines the callback to free an address list entry.
72 : */
73 : typedef void
74 : (*gmp_addr_list_free_func)(struct gmp_addr_list_entry_ *addr_entry);
75 :
76 :
77 : /*
78 : * Address catalog
79 : *
80 : * For efficiency, and to make the use of bit vectors possible, all of the
81 : * addresses referenced by a group are stored in a catalog, and all references
82 : * to them are done by their ordinal numbers.
83 : *
84 : * The catalog consists of a set of entries with two patricia trees
85 : * intertwined--one by address and one by ordinal.
86 : *
87 : * Each entry contains the address, its ordinal, and a reference count. When
88 : * the reference count goes to zero, the entry is freed.
89 : *
90 : * Note that the address ordinal tree may not be in lexicographic order
91 : * for walking!
92 : */
93 : typedef struct gmp_addr_catalog_
94 : {
95 : gmpx_patroot *adcat_addr_root; /* Root of address tree */
96 : gmpx_patroot *adcat_ord_root; /* Root of ordinal tree */
97 : ordinal_handle adcat_ord_handle; /* Ordinal space handle */
98 : uint32_t adcat_addrlen; /* Address length */
99 : } gmp_addr_catalog;
100 :
101 : typedef struct gmp_addr_cat_entry_
102 : {
103 : gmpx_patnode adcat_ent_addr_node; /* Address tree node */
104 : gmpx_patnode adcat_ent_ord_node; /* Ordinal tree node */
105 : gmp_addr_string adcat_ent_addr; /* The address itself */
106 : ordinal_t adcat_ent_ord; /* Address ordinal */
107 : int32_t adcat_ent_refcount; /* Reference count */
108 : } gmp_addr_cat_entry;
109 :
110 122 : GMPX_PATNODE_TO_STRUCT(gmp_addr_patnode_to_addr_cat_entry, gmp_addr_cat_entry,
111 : adcat_ent_addr_node);
112 813 : GMPX_PATNODE_TO_STRUCT(gmp_ord_patnode_to_addr_cat_entry, gmp_addr_cat_entry,
113 : adcat_ent_ord_node);
114 :
115 :
116 : /*
117 : * Address vector
118 : *
119 : * An address vector is a bit vector representing a set of addresses.
120 : * Each address within a group is assigned an ordinal, and the bit
121 : * corresponding to that ordinal is set in the bit vector if that address
122 : * is part of the set.
123 : *
124 : * This vector alone is sufficient to represent a list of addresses in its
125 : * simplest form.
126 : *
127 : * If the catalog pointer is nonzero, vector operations will lock and unlock
128 : * catalog entries as necessary. If the catalog pointer is NULL, this vector
129 : * is a scratch vector, and no locking is done.
130 : */
131 : typedef struct gmp_addr_vect_
132 : {
133 : bit_vector av_vector; /* Bit vector of addresses */
134 : gmp_addr_catalog *av_catalog; /* Address catalog */
135 : } gmp_addr_vect;
136 :
137 :
138 : /*
139 : * gmp_addr_vector
140 : *
141 : * Returns a pointer to the bit vector in an address vector, or NULL if the
142 : * address vector pointer is NULL.
143 : */
144 : static inline bit_vector *
145 633 : gmp_addr_vector (gmp_addr_vect *addr_vect)
146 : {
147 633 : if (addr_vect)
148 422 : return &addr_vect->av_vector;
149 211 : return NULL;
150 : }
151 :
152 :
153 : /*
154 : * Address list
155 : *
156 : * An address list represents a set of addresses, along with some
157 : * application-specific other information. It is structured in two
158 : * ways--as a patricia tree (so that we can quickly find single
159 : * entries) and as a simple thread (so as to be able to traverse
160 : * unordered entries quickly.)
161 : *
162 : * The address list also has an embedded address vector; the vector and
163 : * the addresses on the list represent the same information (and thus must
164 : * remain consistent!)
165 : *
166 : * In addition, there is a second thread to act as a transmit list.
167 : * Callers to this code are responsible for manipulating this thread;
168 : * they are free to add and delete entries from the thread as they
169 : * wish. The only thing this module does is to delink an entry before
170 : * freeing it.
171 : *
172 : * The list contains pointers to entry allocation/free routines in order
173 : * to create specific entry types for eacy list.
174 : *
175 : * Each list entry contains the source address ordinal, a patricia
176 : * node, and two thread links and is typically embedded in a separate
177 : * data structure. Extreme care must be taken to ensure that the
178 : * varying types of entry are not confused.
179 : *
180 : * Address lists may be embedded in another structure, or may be allocated
181 : * independently.
182 : *
183 : * Note that any address list head MUST be initialized via
184 : * gmp_addr_list_init() before use!
185 : *
186 : * Note also that the patricia tree may not be in lexicographic order
187 : * for walking (due to endianness.)
188 : */
189 :
190 : /* Address list head */
191 :
192 : typedef struct gmp_addr_list_ {
193 : gmp_addr_list_alloc_func addr_alloc; /* Allocation routine */
194 : gmp_addr_list_free_func addr_free; /* Free function */
195 : void *addr_context; /* Context for alloc/free */
196 : gmp_addr_vect addr_vect; /* Address vector */
197 : gmpx_patroot *addr_list_root; /* Root of patricia tree */
198 : task_thread addr_list_head; /* Head of address thread */
199 : int addr_count; /* Number of addresses in list */
200 : task_thread addr_list_xmit_head; /* Head of transmit list */
201 : int xmit_addr_count; /* Number of addresses in xmit list */
202 : } gmp_addr_list;
203 :
204 : /* Address list entry */
205 :
206 : typedef struct gmp_addr_list_entry_ {
207 : gmp_addr_list *addr_ent_list; /* Pointer to owning address list */
208 : gmpx_patnode addr_ent_patnode; /* Patricia tree node */
209 : task_thread addr_ent_thread; /* Entry on list thread */
210 : task_thread addr_ent_xmit_thread; /* Entry on transmit thread */
211 : ordinal_t addr_ent_ord; /* Address ordinal */
212 : } gmp_addr_list_entry;
213 :
214 230 : GMPX_PATNODE_TO_STRUCT(gmp_patnode_to_addr_list_entry, gmp_addr_list_entry,
215 : addr_ent_patnode);
216 1085 : THREAD_TO_STRUCT(gmp_thread_to_addr_list_entry, gmp_addr_list_entry,
217 : addr_ent_thread);
218 53 : THREAD_TO_STRUCT(gmp_xmit_thread_to_addr_list_entry, gmp_addr_list_entry,
219 : addr_ent_xmit_thread);
220 :
221 :
222 : /*
223 : * Generic packet format
224 : *
225 : * This set of data structures represent the generic form of a GMP
226 : * packet, independent of protocol (IGMP/MLD) and version.
227 : */
228 :
229 :
230 : /*
231 : * Query packet
232 : *
233 : * The query packet refers to at most one group, and includes an
234 : * address list of sources (if any.)
235 : *
236 : * We use different methods for storing the source address list,
237 : * depending on whether the packet is being transmitted or being
238 : * received. On transmit we use a pointer to an address list; this
239 : * is both handy (because the address list already exists) and is
240 : * necessary (to keep track of which sources are transmitted and which
241 : * are not, since they may not all fit in a packet.)
242 : *
243 : * On receive we use a simple address thread, because we can't create
244 : * an address list until we are within the realm of the receiving client,
245 : * as the associated address catalog necessarily belongs to the client.
246 : */
247 : typedef struct gmp_query_packet_ {
248 : uint32_t gmp_query_max_resp; /* Max resp value, in msec */
249 : gmp_addr_string gmp_query_group; /* Group address */
250 : void *gmp_query_group_id; /* Opaque group ID */
251 : boolean gmp_query_group_query; /* TRUE if a group query */
252 : boolean gmp_query_suppress; /* Suppress router-side processing */
253 : uint32_t gmp_query_qrv; /* Querier's robustness variable */
254 : uint32_t gmp_query_qqi; /* Querier's query interval (msec) */
255 : gmp_addr_list *gmp_query_xmit_srcs; /* List of sources (xmit) */
256 : gmp_addr_thread *gmp_query_rcv_srcs; /* Sources (receive) */
257 : } gmp_query_packet;
258 :
259 :
260 : /*
261 : * Report packet
262 : *
263 : * The report packet consists of a linked list of group records.
264 : *
265 : * Each group record includes an address list of sources (if any.)
266 : */
267 : typedef struct gmp_report_packet_ {
268 : task_thread gmp_report_group_head; /* Head of thread of group records */
269 : uint32_t gmp_report_group_count; /* Number of group records */
270 : } gmp_report_packet;
271 :
272 :
273 : /*
274 : * Report record types
275 : *
276 : * We assume that these report type codes are identical in IGMP and MLD, and
277 : * use those protocol values as our internal form as well.
278 : */
279 : typedef enum {
280 : GMP_RPT_INVALID = 0, /* Invalid type */
281 : GMP_RPT_IS_IN = 1, /* MODE_IS_INCLUDE */
282 : GMP_RPT_IS_EX = 2, /* MODE_IS_EXCLUDE */
283 : GMP_RPT_TO_IN = 3, /* CHANGE_TO_INCLUDE_MODE */
284 : GMP_RPT_TO_EX = 4, /* CHANGE_TO_EXCLUDE_MODE */
285 : GMP_RPT_ALLOW = 5, /* ALLOW_NEW_SOURCES */
286 : GMP_RPT_BLOCK = 6, /* BLOCK_OLD_SOURCES */
287 : GMP_RPT_MIN = GMP_RPT_IS_IN, /* Minimum value */
288 : GMP_RPT_MAX = GMP_RPT_BLOCK, /* Maximum value */
289 : } gmp_report_rectype;
290 :
291 :
292 : /*
293 : * Report group record
294 : *
295 : * Like the query packet above, we use an address list to represent the
296 : * set of sources on transmit, and an address thread on receive.
297 : */
298 : typedef struct gmp_report_group_record_ {
299 : void *gmp_rpt_group_id; /* Opaque group ID */
300 : task_thread gmp_rpt_thread; /* Entry on thread */
301 : gmp_report_rectype gmp_rpt_type; /* Record type */
302 : gmp_addr_string gmp_rpt_group; /* Group address */
303 : gmp_addr_list *gmp_rpt_xmit_srcs; /* List of source addresses (xmit) */
304 : gmp_addr_thread *gmp_rpt_rcv_srcs; /* List of source addresses (rcv) */
305 : } gmp_report_group_record;
306 :
307 280 : THREAD_TO_STRUCT(gmp_thread_to_report_group_record, gmp_report_group_record,
308 : gmp_rpt_thread);
309 :
310 :
311 : typedef enum {
312 : GMP_QUERY_PACKET, /* Query */
313 : GMP_REPORT_PACKET, /* Report */
314 : GMP_NUM_PACKET_TYPES
315 : } gmp_message_type;
316 :
317 :
318 : /*
319 : * The generic packet type consists of a generic version, the packet type,
320 : * and a union of the other two structures. The correct structure can
321 : * be determined by the message type.
322 : */
323 : struct gmp_packet_ {
324 : gmp_version gmp_packet_version; /* Packet version (generic) */
325 : gmp_message_type gmp_packet_type; /* Packet type */
326 : gmp_addr_string gmp_packet_src_addr; /* Source address */
327 : gmp_addr_string gmp_packet_dest_addr; /* Destination address */
328 : gmp_proto gmp_packet_proto; /* Protocol (IGMP/MLD) */
329 : gmpx_packet_attr gmp_packet_attr; /* Opaque attribute */
330 : union {
331 : gmp_query_packet gmp_packet_query; /* Query packet */
332 : gmp_report_packet gmp_packet_report; /* Report packet */
333 : } gmp_packet_contents;
334 : };
335 :
336 :
337 : /*
338 : * Address thread
339 : *
340 : * This is a simple thread of addresses. It is primarily used by external
341 : * clients to pass a set of source addresses in and out. The packet parsing
342 : * routines use it as well.
343 : */
344 : struct gmp_addr_thread_ {
345 : task_thread gmp_addr_thread_head; /* Head of address thread */
346 : uint32_t gmp_addr_thread_count; /* Count of entries */
347 : };
348 :
349 :
350 : /*
351 : * Address thread entry
352 : *
353 : * An entry in an address thread.
354 : */
355 : struct gmp_addr_thread_entry_ {
356 : task_thread gmp_adth_thread; /* Entry on address thread */
357 : gmp_addr_string gmp_adth_addr; /* Address */
358 : };
359 386 : THREAD_TO_STRUCT(gmp_adth_thread_to_thread_entry, gmp_addr_thread_entry,
360 : gmp_adth_thread);
361 :
362 :
363 : /*
364 : * Packet interface transmit callback type
365 : *
366 : * This defines the callback made from the generic packet I/O routines
367 : * when the I/O routines are ready to transmit a packet.
368 : *
369 : * Returns a pointer to a packet to send (which must be returned with the
370 : * packet_free callback) or NULL if there's nothing to send.
371 : *
372 : * The size of the transmit buffer is passed down so that the generic
373 : * packet build routines can make an estimate of how much to put into
374 : * the generic packet (only an estimate, since the exact coding is
375 : * unknown at that point.)
376 : */
377 : typedef gmp_packet * (*gmp_xmit_callback_func)(gmpx_intf_id intf_id,
378 : gmp_proto proto,
379 : uint32_t buffer_len);
380 :
381 :
382 : /*
383 : * Packet interface release callback type
384 : *
385 : * This defines the callback made from the generic packet I/O routines
386 : * when they are done with a packet structure.
387 : */
388 : typedef void (*gmp_packet_free_callback_func)(gmp_packet *packet);
389 :
390 :
391 : /*
392 : * Packet interface receive callback type
393 : *
394 : * This defines the callback made from the generic packet I/O routines
395 : * when a packet has been received.
396 : */
397 : typedef void (*gmp_rcv_callback_func)(gmpx_intf_id intf_id, gmp_packet *pkt);
398 :
399 :
400 : /*
401 : * Packet interface group-done callback type
402 : *
403 : * This defines the callback made from the generic packet I/O routines when
404 : * transmit processing is done for a group.
405 : */
406 : typedef void (*gmp_group_done_callback_func)(void *group_id);
407 :
408 :
409 : /*
410 : * Inlines
411 : */
412 :
413 : /*
414 : * gmp_translate_version
415 : *
416 : * Translates from protocol ID and protocol version number to generic
417 : * version.
418 : */
419 : static inline gmp_version
420 1708 : gmp_translate_version (gmp_proto proto, uint32_t version)
421 : {
422 : /* Bloody dull. */
423 :
424 1708 : switch (proto) {
425 1708 : case GMP_PROTO_IGMP:
426 1708 : switch (version) {
427 2 : case GMP_IGMP_VERSION_1:
428 2 : return GMP_VERSION_BASIC;
429 30 : case GMP_IGMP_VERSION_2:
430 30 : return GMP_VERSION_LEAVES;
431 1676 : case GMP_IGMP_VERSION_3:
432 1676 : return GMP_VERSION_SOURCES;
433 0 : default:
434 0 : return GMP_VERSION_INVALID;
435 : }
436 :
437 0 : case GMP_PROTO_MLD:
438 0 : switch (version) {
439 0 : case GMP_MLD_VERSION_1:
440 0 : return GMP_VERSION_LEAVES;
441 0 : case GMP_MLD_VERSION_2:
442 0 : return GMP_VERSION_SOURCES;
443 0 : default:
444 0 : return GMP_VERSION_INVALID;
445 : }
446 :
447 0 : default:
448 0 : return GMP_VERSION_INVALID;
449 : }
450 : }
451 :
452 : /*
453 : * gmp_untranslate_version
454 : *
455 : * Untranslates from generic version to protocol version number.
456 : */
457 : static inline uint32_t
458 0 : gmp_untranslate_version (gmp_proto proto, gmp_version version)
459 : {
460 0 : switch (proto) {
461 0 : case GMP_PROTO_IGMP:
462 0 : switch (version) {
463 0 : case GMP_VERSION_BASIC:
464 0 : return GMP_IGMP_VERSION_1;
465 0 : case GMP_VERSION_LEAVES:
466 0 : return GMP_IGMP_VERSION_2;
467 0 : case GMP_VERSION_SOURCES:
468 0 : return GMP_IGMP_VERSION_3;
469 0 : default:
470 0 : return GMP_IGMP_VERSION_UNSPEC;
471 : }
472 : break;
473 0 : case GMP_PROTO_MLD:
474 0 : switch (version) {
475 0 : case GMP_VERSION_LEAVES:
476 0 : return GMP_MLD_VERSION_1;
477 0 : case GMP_VERSION_SOURCES:
478 0 : return GMP_MLD_VERSION_2;
479 0 : default:
480 0 : return GMP_MLD_VERSION_UNSPEC;
481 : }
482 : break;
483 0 : default:
484 0 : break;
485 : }
486 :
487 : /* Shouldn't reach here */
488 0 : return 0;
489 : }
490 :
491 : /*
492 : * gmp_addr_in_list
493 : *
494 : * Returns TRUE if the address ordinal is part of the specified address
495 : * list, or FALSE if not.
496 : */
497 : static inline boolean
498 236 : gmp_addr_in_list (gmp_addr_list *addr_list, ordinal_t ordinal)
499 : {
500 236 : return (bv_bit_is_set(&addr_list->addr_vect.av_vector, ordinal));
501 : }
502 :
503 :
504 : /*
505 : * Externals
506 : */
507 :
508 : /* gmp_addrlist.c */
509 :
510 : extern void gmp_common_init(void);
511 : extern int gmp_addr_vect_fill(gmp_addr_vect *addr_vect,
512 : gmp_addr_thread *addr_thread);
513 : extern void gmp_addr_list_clean(gmp_addr_list *addr_list);
514 : extern void
515 : gmp_free_generic_addr_list_entry(gmp_addr_list_entry *addr_entry);
516 : extern void gmp_flush_addr_list(gmp_addr_list *addr_list);
517 : extern int gmp_add_addr_list_entry(gmp_addr_list *addr_list,
518 : gmp_addr_list_entry *addr_entry);
519 : extern gmp_addr_list_entry *gmp_lookup_addr_entry(gmp_addr_list *addr_list,
520 : ordinal_t ordinal);
521 : extern gmp_addr_list_entry
522 : *gmp_addr_list_next_entry(gmp_addr_list *list, gmp_addr_list_entry *prev);
523 : extern void gmp_addr_list_init(gmp_addr_list *list, gmp_addr_catalog *catalog,
524 : gmp_addr_list_alloc_func alloc_func,
525 : gmp_addr_list_free_func free_func,
526 : void *context);
527 : extern void gmp_enqueue_xmit_addr_entry(gmp_addr_list_entry *addr_entry);
528 : extern void gmp_dequeue_xmit_addr_entry(gmp_addr_list_entry *addr_entry);
529 : extern gmp_addr_list_entry *
530 : gmp_first_xmit_addr_entry(gmp_addr_list *addr_list);
531 : extern void gmp_enqueue_xmit_addr_list(gmp_addr_list *addr_list);
532 : extern void gmp_flush_xmit_list(gmp_addr_list *addr_list);
533 : extern void gmp_delete_addr_list_entry(gmp_addr_list_entry *addr_entry);
534 : extern boolean gmp_addr_list_empty(gmp_addr_list *list);
535 : extern boolean gmp_xmit_addr_list_empty(gmp_addr_list *list);
536 : extern int gmp_addr_vect_set(gmp_addr_vect *vector, gmp_addr_string *addr);
537 : extern void gmp_addr_vect_clean(gmp_addr_vect *vector);
538 : extern void gmp_init_addr_vector(gmp_addr_vect *vector,
539 : gmp_addr_catalog *catalog);
540 : extern void gmp_destroy_addr_catalog(gmp_addr_catalog *catalog);
541 : extern int gmp_init_addr_catalog(gmp_addr_catalog *catalog,
542 : uint32_t addr_len);
543 : extern gmp_addr_cat_entry *
544 : gmp_get_addr_cat_by_ordinal(gmp_addr_catalog *catalog, ordinal_t ordinal);
545 : extern ordinal_t gmp_lookup_create_addr_cat_entry(gmp_addr_catalog *catalog,
546 : uint8_t *addr);
547 : extern gmp_addr_cat_entry *gmp_lookup_addr_cat_entry(gmp_addr_catalog *catalog,
548 : const uint8_t *addr);
549 : extern void gmp_lock_adcat_entry(gmp_addr_catalog *catalog, ordinal_t ordinal);
550 : extern void gmp_unlock_adcat_entry(gmp_addr_catalog *catalog,
551 : ordinal_t ordinal);
552 : extern int gmp_addr_vect_inter(gmp_addr_vect *src1, gmp_addr_vect *src2,
553 : gmp_addr_vect *dest, bv_callback callback,
554 : void *context, bv_callback_option cb_opt);
555 : extern int gmp_addr_vect_union(gmp_addr_vect *src1, gmp_addr_vect *src2,
556 : gmp_addr_vect *dest, bv_callback callback,
557 : void *context, bv_callback_option cb_opt);
558 : extern int gmp_addr_vect_minus(gmp_addr_vect *src1, gmp_addr_vect *src2,
559 : gmp_addr_vect *dest, bv_callback callback,
560 : void *context, bv_callback_option cb_opt);
561 : extern int gmp_addr_vect_compare (gmp_addr_vect *src1, gmp_addr_vect *src2,
562 : bv_callback callback, void *context);
563 : extern int gmp_addr_vect_walk(gmp_addr_vect *vect, bv_callback callback,
564 : void *context);
565 : extern int gmp_build_addr_list(gmp_addr_list *addr_list,
566 : gmp_addr_vect *vector);
567 : extern boolean gmp_addr_list_copy_cb(void *context, bv_bitnum_t bitnum,
568 : boolean new_val, boolean old_val);
569 : extern gmp_addr_list_entry *gmp_alloc_generic_addr_list_entry(void *context);
570 : extern gmp_addr_list_entry *
571 : gmp_create_addr_list_entry(gmp_addr_list *addr_list, ordinal_t ordinal);
572 : extern void gmp_move_addr_list_entry(gmp_addr_list *to_list,
573 : gmp_addr_list_entry *addr_entry);
574 : extern boolean gmp_addr_vect_empty(gmp_addr_vect *vector);
575 : extern boolean gmp_addr_is_zero(gmp_addr_string *addr, uint32_t addr_len);
576 :
577 : /* gmpp_proto.c */
578 :
579 : extern void gmpp_start_xmit(gmp_role role, gmp_proto proto,
580 : gmpx_intf_id intf_id);
581 : extern void gmpp_register(gmp_role role, gmp_xmit_callback_func xmit_callback,
582 : gmp_rcv_callback_func rcv_callback,
583 : gmp_group_done_callback_func group_done_callback,
584 : gmp_packet_free_callback_func packet_free_callback);
585 : extern void gmpp_deregister(gmp_role role);
586 : extern void gmpp_enab_disab_proto(gmp_role role, gmp_proto proto,
587 : boolean enabled);
588 : extern gmp_packet *gmpp_create_packet_header(gmp_version version,
589 : gmp_message_type message_type,
590 : gmp_proto proto);
591 : extern void gmpp_destroy_packet(gmp_packet *packet);
592 : extern gmp_report_group_record *
593 : gmpp_create_group_record(gmp_report_packet *report_packet, void *group_id,
594 : const uint8_t *group_addr, uint32_t addr_len);
595 : extern void gmpp_init(void);
596 : extern gmp_packet *gmpp_next_xmit_packet(gmp_role role, gmp_proto proto,
597 : gmpx_intf_id intf_id,
598 : uint32_t buffer_len);
599 : extern void gmpp_group_done(gmp_role role, gmp_proto proto, void *group_id);
600 : extern void gmpp_packet_done(gmp_role role, gmp_proto proto,
601 : gmp_packet *packet);
602 : extern void gmpp_process_rcv_packet(gmp_packet *packet, gmpx_intf_id intf_id);
603 : extern uint32_t gmpp_max_group_count(gmp_proto proto, gmp_version version,
604 : gmp_message_type msg_type, uint32_t buffer_len);
605 :
606 : #endif /* __GMP_PRIVATE_H__ */
|