The design and ideas behind many of the MRT libraries draws heavily on the architecture pioneered in GateD.
NOTE: The MRT libraries may undergo significant changes prior to the 2.0 release of MRT. After the 2.0 public release, we expect the library API will remain stable.
cc [flag ...] file... [library...] -lmrt
#include <mrt.h>
int init_mrt(trace_t* trace);
Thread Support
schedule_t *New_Schedule (char *description, trace_t *trace);
int schedule_event (schedule_t *schedule, void (*call_fn)(),
int narg, ...);
int schedule_wait_for_event (schedule_t *schedule);
void Delete_Event (event_t *event)
int clear_schedule (schedule_t *schedule);
int mrt_thread_exit (mrt_thread_t *thread);
mrt_thread_t* mrt_thread_create (char *name, schedule_t *schedule, void
(*call_fn) (), void *arg);
Gateways
char *gateway_toa (char *tmp, gateway_t *gateway);
gateway_t *find_gateway (prefix_t *prefix, int AS, interface_t *interface);
gateway_t *New_Gateway (prefix_t *prefix, int AS);
Prefix
void Delete_Prefix (prefix_t *prefix);
prefix_t* ascii2prefix (int family, char *string);
char *prefix_toa (prefix_t *prefix);
char *prefix_toa2 (prefix_t *prefix, char *tmp);
u_char *prefix_tochar (prefix_t *prefix);
int prefix_compare (prefix_t *p1, prefix_t *p2);
prefix_t *New_Prefix (int family, u_char *dest, int bitlen);
User Interactive Interface (UII)
int parse_line (u_char *line, char *format, ...);
set_uii (uii_t *tmp, int first, ...);
int uii_send_data (uii_connection_t *uii, ...);
int uii_destroy_connection (uii_connection_t *connection);
int uii_add_command (int state, char *string, int *call_fn);
The I/O library provides an easy-to-use, standardized abstract interface to IPC. Several different IPC methods (file, stdin/stdout, and System V message queues) are supported. A message-queue key registry is provided, to allow processes to communicate without knowledge of each other's keys.
cc [flag ...] file... [library...] -lio -lstruct -lmrt
#include <mrt.h>
#include <io.h>
int io_init();
int io_set(int key, int val, ...);
int io_write(long tstamp, short type, short subtype, int length, char *value);
MRT_MSG_STRUCT *io_read(void);
io_init
and
io_set
before any io_write
or
io_read
calls are performed. In addition, the key
registry server (IO_INMSGQ
and IO_OUTMSGQ
I/O types to
work.
io_set
is used to set up the input and output channels
for the I/O library. The arguments to io_set
are a
sequence of key-value pairs, with the key being an I/O attribute, and
the value being attribute-specific. Available keys are specified in
table 1.
After io_set
has been used to configure the I/O channels,
io_read
and io_write
can be used to read and
write data, respectively.
The MRT Timer libary provides easy programming interfaces to create, destrory, set nad manuipulate timers.
cc [flag...] file... -ltimer -lutil -lstruct [library...] #include <timer.h> void init_timer_master(); Timer *New_Timer (void (*call_fn)(), int interval, char *name, void *arg); void Timer_Turn_ON (Timer *timer); void Timer_Turn_OFF (Timer *timer); void Timer_Reset_Time (Timer *timer);
All programs making use of the MRT timer library MUST call init_timer_master() before calling any timer routines. Failure to call init_timer_master will result in unitialized timer structures and lead to segment faults
After initializing the master timer information, individual timers are created by calling New_Timer (). The New_Timer () function intitializes a new timer that calls the user-defined call_fn function after the timer fires every interval number of seconds. After the call_fn is executed, the timer automatically resets to expire interval seconds in the future. The name argument is a descriptive string used in logging timer events. New_Timer returns a pointer to a Timer data structure. The call_fn is called with two arguments, a pointer to the Timer data structure that fired, and a pointer to the user-defined data pointer arg. The user-defined call function has the form:
void my_call_fn (Timer *timer, void *my_data);New_Timer returns a NULL pointer upon failure.
All timers are intially created in the OFF state. In this state, the timer is not scheduled, and the call_fn will not execute. To turn a timer ON, you must call the function Timer_Turn_ON ().
Similarly, if a timer is no longer needed, Timer_Turn_OFF () will remove timer from the timer queue and prevent the timer from firing in the future.
The Timer_Reset_Time function resets the timer to fire after the timer's original interval number of seconds expires. This function is used by protocols like BGP which need to reset KeepAlive timers after receiving a KeepAlive from a peer. If a timer is OFF, the Timer_Reset_Time call will turn the timer on. Timer_Set_Time changes the interval value of an initialized timer. After calling Timer_Set_Time, timer will fire after every interval seconds. If a timer is OFF, the Timer_Set_Time call will turn the timer on.
Finally, a protocol that no longer has need of any timer may clear all memory associated with timers by calling Destroy_Timer_Master. Most protocols will not make use of this function. Protocols MUST not call other timer library routines after invoking Destroy_Timer_Master.
#include <stdio.h> #include <timer.h> void my_timer_fire1() { printf("10 I have fired\n"); } void my_timer_fire2() { printf("60 I have fired\n"); } main () { Timer *timer1, *timer2; init_timer_master(); timer1 = New_Timer (my_timer_fire1, 60, "timer1"); timer2 = New_Timer (my_timer_fire2, 10, "timer2"); Timer_Turn_ON (timer1); Timer_Turn_ON (timer2); /* loop forever */ while (1); }
INCDIR=-I$(HOME)/mrt/include LIBDIR=-L$(HOME)/mrt/lib LIBS=-lstruct -lutil -ltimer all: my_file my_file: my_file.o $(CC) -o my_file $(LIBDIR) $(LIBS) my_file.0: my_file.c $(CC) $(INCDIR) -c my_file.c
typedef struct _Timer { int time_interval; /* seconds between firing */ int time_next_fire; /* real time after which should fire */ void (*call_fn)(); u_char on; /* timer is turned ON if this set to 1 */ char *name; /* used for logging and debugging */ } Timer; typedef struct _Timer_Master { int time_interval; /* seconds btwn firing (debugging purposes) */ int time_next_fire; /* real time after which should fire */ LINKED_LIST *ll_timers; } Timer_Master;
The MRT Trace library provides simple programing interface for programs and protocols to log trace information either to disk, or to the console.
cc [flag...] file... -ltrace [library...] #include <trace.h> void trace (int severity, Trace_Struct *trace_struct, ...); Trace_Struct *New_Trace_Struct (int first, ...); int Set_Trace_Struct (Trace_Struct *tmp, int first, ...)Protocols making use of the MRT Trace library must first call New_Trace_Struct to allocate memory and initalize the trace information. As argumets, New_Trace_Struct takes a null terminated list of option flag, option value pairs. Possible options, their associated type of argument, and their default value include:
TR_LOGFILE char* "/tmp/mrt.log" TR_FLAGS int NORM TR_APPEND boolean TRUE TR_FLOCK boolean TRUETR_LOGFILE speicifes the name of the file to which trace calls will write logging information. If this flag is followed by an argument of "stdout", trace calls will write to standard out.
The TR_FLAGS argument specifies the level, or verbosity, of tracing information that will be generated. Possible arguments include:
FATAL /* fatal error -- die after receiving */ TRACE /* verbose tracing, like keepalives */ NORM /* normal events to trace */ TR_PARSE /* trace parsing of config files */ TR_PACKET /* trace packet comming and goings */ TR_STATE /* trace state changes and events */ TR_TIMER /* trace timer changes and events */ TR_POLICY /* trace policy changes and events */ TR_ALL /* trace everything */
TR_APPEND specifies whether the trace library should append (argument of TRUE) new tracing information onto the end of an existant file, or overwrite an existant file (argument of FALSE).
TR_FLOCK controls whether the trace library uses the flock library (see flock(2)).
The trace function writes logging information of severity to disk. The trace_struct arguments specified as a format string followed by format
#include#include #include main () { Trace_Struct *protocol_trace; protocol_trace = New_Trace_Struct (TRACE_LOGFILE, "/tmp/my_logfile", TRACE_FLAGS, NORM, NULL); trace (NORM, protocol_trace, "This is a trace message"); trace (TR_POLICY, protocol_trace, "This will not show up"); Set_Trace_Struct (protocol_trace, TRACE_FLAGS, TR_ALL, TRACE_LOGFILE, "stdout", NULL); trace (TR_POLICY, protocol_trace, "This will show up on the console"); trace (FATAL, protocol_trace, "Now I will die... (this shows up in syslog)"); }
cc [flag ...] file... [library...] -lnterface -lmrt
#include <mrt.h>
#include <interface.h>
int init_interfaces (trace_t *ltrace);
interface_t *find_interface (prefix_t *prefix);
interface_t *find_interface_byname (char *name);
LINKED_LIST *find_network (prefix_t *prefix);
interface_t *find_interface_local (prefix_t *prefix);
int local_interface (int family, u_char *cp);
interface_t *interface_iter (interface_iter_t **iter);
cc [flag ...] file... [library...] -lselect -lmrt
#include <mrt.h>
#include <select.h>
int select_enable_fd (int fd);
select_disable_fd (int fd);
int select_delete_fd (int fd);
int select_add_fd (int fd, int type_mask, void (*call_fn)(), void *arg);
int init_select ();