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