Show link.h syntax highlighted
/*
*
* Copyright (c) 2003 The Regents of the University of California. All
* rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/*
* link.h -- Header for defining link-layer interfaces in our system
*
* $Id: link.h,v 1.74 2005/09/22 03:10:13 girod Exp $
*/
#include "libdev/packet_dev.h"
#include "libdev/status_dev.h"
#include "libdev/command_dev.h"
#include "libdev/packet_client.h"
/* needed for "remote timestamp" structure */
#include "timesync/sync.h"
#include <link/link_structs.h>
#include <link/link_headers.h>
#include <link/link_ioctls.h>
#include <link/link_parse.h>
#ifndef __LINK_H__
#define __LINK_H__
/********
******** SEE link_structs.h FOR LINK_PKT_TYPE_T AND LINK_PKT_T
********/
/*
* Link Library Interface
*
* The link library API contains several classes of objects
* for creating and using link interfaces:
*
* - link providers (lp_*)
* - link users (lu_*)
* - link passthrus (link_pass_*)
*
* See documentation for more details
*/
/*
* common options that describe a link: the name, queuing options,
* private data pointer, etc.
*
* Note, interface class is only used by link providers, to group
* interfaces into classes, e.g. link layer, network layer, etc.
*/
typedef struct link_opts {
char *name; /* the link name (e.g. udp0) */
char *if_class; /* the interface class (e.g. raw, link, network, etc) */
pd_queue_opts_t q_opts; /* Queue length and loopback options */
link_pkt_type_t pkt_type; /* packet type assoc with this link,
* if any. used to filter for uses,
* for debug purposes in provides */
void *data; /* Data pointer used by apps */
} link_opts_t;
char *link_name(link_opts_t *l_opts, char *suffix);
char *link_name_s(char *name, char *suffix);
/* does NOT run sim_path on the name.. used rarely */
char *link_name_s_nosim(char *name, char *suffix);
/********************************************************************/
/******************** Link Provider Interface ***********************/
/********************************************************************/
/* typedef link provider context */
typedef struct _lp_context lp_context_t;
#define LP_BLOCKED PD_BLOCKED
/*
* all memory is statically allocated, do not free
* data_len does not include header
*/
typedef int (*lp_send_cb_t)(lp_context_t *lp, link_pkt_t *link_pkt,
int data_len, int loop_needed);
typedef int (*lp_enqueue_cb_t)(lp_context_t *lp, link_pkt_t *link_pkt,
int data_len);
/* optional ioctl() handler */
typedef int (* lp_ioctl_cb_t)(lp_context_t *lp, int cmd, void *arg);
/* optional notification of status request */
typedef int (*lp_status_cb_t)(lp_context_t *lp);
/* optional command callback function
* system will free parser state
* return EVENT_RENEW or EVENT_ERROR(errno) */
typedef int (*lp_command_cb_t)(lp_context_t *lp, parser_state_t *cmd_input);
/* optional notificaiton callback to set promisc mode */
typedef void (*lp_notify_cb_t)(lp_context_t *lp, int mode);
/*
* when reporting usage, report one entry per line, in the form
* " option: description\n"
* or " option=<argdesc>: description\n"
*/
typedef void (*lp_command_usage_cb_t)(lp_context_t *lp, buf_t *fill_usage);
/* options available for link providers */
typedef struct lp_opts {
link_opts_t opts; /* common options */
char *description; /* our module's description */
lp_send_cb_t send; /* send callback */
lp_enqueue_cb_t enqueue; /* enqueue callback */
lp_ioctl_cb_t ioctl; /* ioctl callback */
lp_status_cb_t status_request; /* status callback */
lp_command_cb_t command_request; /* command callback */
lp_command_usage_cb_t usage; /* command usage callback */
lp_notify_cb_t promisc_mode; /* notification of change of promisc_mode */
/* Default status:
*
* + If you don't need the status info to be dynamic, set the values
* here in initial_status. ***Be sure to set MTU and if_id.***
* The link device will filter your packets based on destination
* set to if_id. If if_id is zero, (or if clients request promisc
* mode) it will allow all packets
*
* + If you want the status to be dynamic, e.g. reflecting changing
* characteristics of the underlying layers, or of hardware that
* can be dynamic, then you need not set this; use push_status to
* push new status info as needed and optionally implement a status
* handler callback which will be called every time status is
* requested.
*/
link_status_t initial_status; /* initial/default status info */
/* options */
int no_auto_mtu_check:1; /* disable auto MTU check */
int we_are_root:1; /* we are the root dev */
int stat_notify_all_requests:1; /* if we want notification on all
* requests, not just periodic
* refreshes.. */
int root_refresh_interval; /* if root, defaults to 10000(ms) */
char *root_trace; /* lowest level device, e.g. eth0 */
loc_t antenna_offset; /* position offset of antenna */
} lp_opts_t;
int lp_register(lp_opts_t *opts, lp_context_t **ref);
void lp_destroy(lp_context_t *context);
/* generally used only by ceiling array */
void lp_register_in_class(char *class_name, char *link_name);
/* if a channel model is active, lp_register will report
* a retval of LP_CHANNEL_MODEL_ACTIVE, indicating that your
* driver should go "dormant" because the devices are provided
* by the channel simulator */
#define LP_CHANNEL_MODEL_ACTIVE -2
/* lp_check_sim() returns true if we are overridden by a sim component */
int lp_check_sim(lp_opts_t *opts);
/* upcalls to pass data to clients */
void lp_receive(lp_context_t *lp, const link_pkt_t *data, int data_len);
void lp_loop_receive(lp_context_t *lp, const link_pkt_t *data, int data_len);
int lp_loop_needed(lp_context_t *lp);
void lp_unblock(lp_context_t *lp, int retval);
/* accessors */
lp_opts_t *lp_opts(lp_context_t *lp);
void *lp_data(lp_context_t *lp);
link_pkt_t *lp_get_outgoing_pkt(lp_context_t *lp);
int lp_get_outgoing_datalen(lp_context_t *lp);
int lp_get_promisc_state(lp_context_t *lp);
/* push updated status info to the link provider instance */
void lp_push_status(lp_context_t *lp, link_status_t *new_status);
/* update the root trace string */
void lp_update_root_trace(lp_context_t *context, const char *trace, const char *description);
/* get the name of the link subdevice */
char *lp_name(lp_context_t *lp, char *suffix);
/* used to append usage information for standard commands */
void lp_add_standard_usage(buf_t *buf, char *cmd);
/* report error counts */
void lp_report_tx_error(lp_context_t *lp);
void lp_report_rx_error(lp_context_t *lp);
/********************************************************************/
/*********************** Link User Interface ************************/
/********************************************************************/
/* typedef link user context */
typedef struct _lu_context lu_context_t;
/* reception of new data
* NOTE: link_pkt_t is allocated, the callback is expected to free it! */
typedef int (*lu_pkt_receive_cb_t)(lu_context_t *lu, link_pkt_t *pkt, ssize_t data_len);
/* notification of new status / writability */
typedef int (*lu_notify_cb_t)(lu_context_t *lu);
/* options struct for opening a link user connection */
typedef struct lu_opts {
link_opts_t opts; /* common options */
lu_pkt_receive_cb_t receive; /* Callback when packets arrive */
lu_notify_cb_t writable; /* ...when the dev is writable */
lu_notify_cb_t status_notify; /* ...when the status changes */
lu_notify_cb_t configure; /* ...when the link is opened */
int promisc; /* set promisc mode to active, passive, or none
* (see link_ioctls.h) */
int blocking_writes; /* enable send() to block */
} lu_opts_t;
/* connecting and disconnecting from a link */
int lu_open(lu_opts_t *opts, lu_context_t **ref);
void lu_destroy(lu_context_t *lu);
/* return current poll flags for this link user, or -1 if error */
int lu_poll(lu_context_t *lu);
/* send a packet to the link, data_len is length of the payload */
int lu_send(lu_context_t *lu, link_pkt_t *pkt, ssize_t data_len);
int lu_set_blocking_mode(lu_context_t *lu, int blocking);
/* Simpler function to send a packet if user does not have to set too many
* fields in the link_pkt struct.
* Returns -1 on failure, and 0 on success */
gint lu_send_simple(lu_context_t *lu, if_id_t dst, if_id_t src,
int pkt_type, void* pkt, ssize_t data_len);
/* control event enable */
void lu_writable_cb_set_enable(lu_context_t *lu, int enable);
void lu_readable_cb_set_enable(lu_context_t *lu, int enable);
int lu_writable_cb_get_enable(lu_context_t *lu);
int lu_readable_cb_get_enable(lu_context_t *lu);
/* retrieve link status, or just mtu or interface id */
int lu_status(lu_context_t *lu, link_status_t *status_return);
int lu_force_status(lu_context_t *lu, link_status_t *status_return);
int lu_get_mtu(lu_context_t *lu, uint16_t *mtu);
int lu_get_if_id(lu_context_t *lu, if_id_t *if_id);
int lu_get_root_link_dev(lu_context_t *lu, char *device);
/* issue command to link command device */
int lu_printf_command(lu_context_t *lu, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
/* issue ioctl command */
int lu_ioctl(lu_context_t *lu, int cmd, void *arg);
/* setting promiscuous mode to active, passive,
* or none (see link_ioctls.h) */
int lu_set_promisc(lu_context_t *lu, int enable);
/* accessor functions */
lu_opts_t *lu_opts(lu_context_t *lu);
void *lu_data(lu_context_t *lu);
/* create link device name */
char *lu_name(lu_context_t *lu, char *suffix);
/*
* link_status_t related functions
*/
int link_status_to_buf(buf_t *buf, link_status_t *stat);
int link_hdr_to_buf(buf_t *buf, link_pkt_t *hdr);
int link_type_to_buf(buf_t *buf, link_pkt_t *hdr);
/********************************************************************/
/****************** Command Line Helper Functions *******************/
/********************************************************************/
/*
* Simple command line helper functions
*/
/* parses out the --uses flag, or uses default if not found */
char *link_parse_uses(int *argc, char **argv, char *default_name);
char **link_parse_uses_multi(int *argc, char **argv, char *default_name);
char *link_parse_provides(int *argc, char **argv, char *default_name);
char **link_parse_provides_multi(int *argc, char **argv, char *default_name);
char *link_parse_if_class(int *argc, char **argv, char *default_class);
char *link_parse_uses_class(int *argc, char **argv, char *default_class);
/* Translates the link->type field based on pre-defined enum in
* link_structs.h */
char *link_translate_pkt_type(int link_type);
int link_parse_pkt_type(char *type);
/******************** CL Helper Data Structures *********************/
/* helper struct to parse command line arguments for used and provided
* link interfaces */
typedef struct link_ifs {
link_opts_t *provides; /* link interfaces provided */
int num_provided; /* number of interfaces provided */
link_opts_t *uses; /* link interfaces used */
int num_used; /* number of interfaces used */
} link_ifs_t;
void link_config(link_ifs_t *ifs, int *argc, char **argv);
int link_addone(link_opts_t **opts, char *string);
void link_usage(char **usage, char **expl);
/*********** Various utilities for dealing with a link_pkt **********/
/*
* Link receipts.. metadata about a previously sent packet
*/
int link_receipt_is_requested(link_pkt_t *pkt);
int link_receipt_request(link_pkt_t *pkt, void *info);
int link_receipt_for_us(link_pkt_t *pkt);
#endif /* __LINK_H__ */
See more files for this project here