/* ipmip_dhcp.h - ipmip_dhcp.h */ /* ****************************************************************************** * HEADER FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip_dhcp.h,v $ $Revision: 1.8 $ * $Source: /home/interpeak/CVSRoot/ipmip/include/private/ipmip_dhcp.h,v $ * $Author: jhorteli $ $Date: 2010-12-07 09:55:01 $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Joel Hortelius ****************************************************************************** */ #ifndef IPMIP_DHCP_H #define IPMIP_DHCP_H /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* DESCRIPTION DHCP proxy and server implementation used to integrate DHCP with various MIP DHCP requirements.These routines allow for a DHCP proxy and/or server to create, parse and act on DHCP messages sent by a DHCP server, relay or client. Proxy Mobility, for example, uses DHCP heavily to configure nodes on its domains. EXAMPLE: This example shows a bare bone DHCP context usage, from creating the DHCP context registering a lease and sending a reply. .CS static int ipmip_my_dhcp_server(int event, struct Ipmip_my_context *ctx, Ipmip_proc_t *proc, struct Ipmip_my_entities *node, Ipmip_pktbuf_t *pbuf) { /@ Did it invoce correctly? @/ if (event == IPMIP_TIMER_EVENT_RUN) { Ipmip_dhcp_hdr_t *pkt = (Ipmip_dhcp_hdr_t *)IPMIP_BUFFER_PTR(&pbuf->packet); if (pkt->op == IPMIP_DHCP_OP_BOOTREQUEST) { Ip_u8 *opt; /@ Check the giaddr and the relay agent option @/ if (IP_GET_32ON8(&pkt->giaddr) != 0 || ipmip_dhcp_option_buffer_find(&pbuf->packet, IPMIP_DHCP_OPTCODE_RELAY_AGENT_INFO) 1= IP_NULL) { /@ Relay packet, dont deal with this in this example @/ goto done_out; } /@ Must have the message type option @/ if ((opt = ipmip_dhcp_option_buffer_find(&pbuf->packet, IPMIP_DHCP_OPTCODE_DHCP_MESSAGE_TYPE)) == IP_NULL) goto done_out; else { Ipmip_pktbuf_t *rpkt = (Ipmip_pktbuf_t*)ipmip_pktbuf_alloc(&ctx->ipmip, proc, 512); Ipmip_buffer_t *buf = &rpkt->packet; Ip_u8 type; Ip_u32 tmp32; /@ Add the header of the request to the packet @/ ipmip_buffer_append(buf, pkt, sizeof(*pkt)); /@ Verify the message type @/ switch(opt[IPMIP_DHCP_OPT_DATA]) { case IPMIP_DHCP_MSG_DISCOVER: type = IPMIP_DHCP_MSG_OFFER; break; case IPMIP_DHCP_MSG_REQUEST: { Ip_u32 req_addr = 0; /@ We dont really do everything according to spec; but this is merely an example after all @/ req_addr = ipmip_dhcp_option_buffer_find_ip(&pbuf->packet, IPMIP_DHCP_OPTCODE_DHCP_REQUESTED_ADDRESS); if (req_addr == 0) req_addr = IP_GET_32ON8(&pkt->ciaddr); if (req_addr != 0) type = IPMIP_DHCP_MSG_ACK; else type = IPMIP_DHCP_MSG_NAK; } break; case IPMIP_DHCP_MSG_DECLINE: goto done_out; case IPMIP_DHCP_MSG_RELEASE: goto done_out; case IPMIP_DHCP_MSG_INFORM: type = IPMIP_DHCP_MSG_NAK; break; default: goto done_out; } /@ Add DHCP message type @/ ipmip_dhcp_option_buffer_append_u8(buf, IPMIP_DHCP_OPTCODE_DHCP_MESSAGE_TYPE, type); if (type != IPMIP_DHCP_MSG_NAK) { /@ Add lease time @/ ipmip_dhcp_option_buffer_append_u32(buf, IPMIP_DHCP_OPTCODE_DHCP_LEASE_TIME, 5); /@ Add SUBNET option - Do a 24 but mask @/ tmp32 = 0; ipmip_util_create_mask((Ip_u8 *)&tmp32, 24); ipmip_dhcp_option_buffer_append_ip(buf, IPMIP_DHCP_OPTCODE_SUBNET_MASK, tmp32); } ipmip_dhcp_option_buffer_close(buf); /@ Retrieve the buffer pointer to the DHCP packet header @/ pkt = (Ipmip_dhcp_hdr_t *)IPMIP_BUFFER_PTR(buf); pkt->op = IPMIP_DHCP_OP_BOOTREPLY; pkt->hops = 0; /@ Unless its a NAK, set the yiaddr @/ if (type != IPMIP_DHCP_MSG_NAK) IP_SET_32ON8(&pkt->yiaddr, node->my_ip_address); /@ Do write the message @/ ipmip_dhcp_write_to_client(&ctx->ipmip, proc, rpkt, ctx->my_dhcp_server_address, node->iff, type == IPMIP_DHCP_MSG_NAK); } } else { /@ BOOT REPLY @/ } } done_out: ipmip_pktbuf_release(&ctx->ipmip6.ipmip, proc, &pbuf->ipmip6.ipmip); return IPMIP_TIMER_RET_DONE; } static int my_mip_dhcp_handle(int event, struct Ipmip_my_context *ctx, Ipmip_proc_t *proc, Ipmip_dhcp_node_t *dnode, Ipmip_pktbuf_t *pbuf) { /@ Successful invocation? @/ if (event == IPMIP_TIMER_EVENT_RUN) { /@ Get the DHCP header @/ Ipmip_dhcp_hdr_t *pkt = (Ipmip_dhcp_hdr_t *)IPMIP_BUFFER_PTR(&pbuf->packet); struct Ip_iovec naiv; if (pkt->op == IPMIP_DHCP_OP_BOOTREQUEST) { const char *nai; struct Ip_iovec vec; /@ Retrieve the client ID @/ if (ipmip_dhcp_retrieve_client_id(&pbuf->packet, &vec) && ((Ip_u8 *)vec.iov_base)[0] == 0) { /@ Get the CLIENT ID, and make certain its terminated @/ nai = ipmip_ntop_strn(proc, &((char *)vec.iov_base)[1], vec.iov_len - 1); naiv->iov_len = ipcom_strlen(nai); naiv->iov_base = (void *)nai; } else { /@ MAC ADDRESS, we do not bother in this example with this. Only real CLIENT ID. @/ goto done_out; } } /@ This function needs to lookup a node based on NAI and invoke the server function with it. It is not implemented here however. Usually it would be done by creating a hash table with the nodes name as key and add the appropriate locking mechanisms to it @/ my_dhcp_find_node_by_client_id(ctx, proc, &naiv, ipmip_my_dhcp_server, pbuf); return IPMIP_TIMER_RET_DONE; } done_out: ipmip_pktbuf_release(&ctx->ipmip4.ipmip, proc, &pbuf->ipmip4.ipmip); return IPMIP_TIMER_RET_DONE; } void my_init_func(struct Ipmip_my_context *ctx, Ipmip_proc_t *proc, struct Ipmip_my_iff *iff, Ip_u32 server_addr) { /@ Create the DHCP context - Can be done during context initialization, or later for example depending on configuration @/ /@ This context will create the required UDP sockets for retrieving and sending DHCP datagrams @/ ipmip_dhcp_context_create(&ctx->ipmip, proc); /@ Setup the DHCP callback structure, specify the interface we are interested in receiving replies from and what callback to be invoked @/ cfg->my_dhcp.ifindex = iff->ipmip.ifindex; cfg->my_dhcp.opaque = iff; cfg->my_dhcp.lock = ctx->my_lock; cfg->my_dhcp.process_func = (Ipmip_timer_func_t)my_mip_dhcp_handle; cfg->my_dhcp_server_address = server_addr; /@ Register the DHCP callback function @/ ipmip_dhcp_register(&ctx->ipmip, proc, &ctx->my_dhcp); } .CE */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #include #include #include #include #ifdef __cplusplus extern "C" { #endif #ifdef IPMIP_USE_INET /* **************************************************************************** * 4 DEFINES **************************************************************************** */ #define IPMIP_DHCP_OP_BOOTREQUEST 1 #define IPMIP_DHCP_OP_BOOTREPLY 2 #define IPMIP_DHCP_MSG_DISCOVER 1 #define IPMIP_DHCP_MSG_OFFER 2 #define IPMIP_DHCP_MSG_REQUEST 3 #define IPMIP_DHCP_MSG_DECLINE 4 #define IPMIP_DHCP_MSG_ACK 5 #define IPMIP_DHCP_MSG_NAK 6 #define IPMIP_DHCP_MSG_RELEASE 7 #define IPMIP_DHCP_MSG_INFORM 8 #define IPMIP_DHCP_MSG_INFORM_ACK 0x15 #define IPMIP_DHCP_OPT_CODE (0) #define IPMIP_DHCP_OPT_LEN (1) #define IPMIP_DHCP_OPT_DATA (2) #define IPMIP_DHCP_OPTCODE_PAD 0 #define IPMIP_DHCP_OPTCODE_END 255 #define IPMIP_DHCP_PKT_HDR_SNAME_LEN (64) #define IPMIP_DHCP_PKT_HDR_FILE_LEN (128) #define IPMIP_DHCP_OPTCODE_SUBNET_MASK 1 #define IPMIP_DHCP_OPTCODE_TIME_OFFSET 2 #define IPMIP_DHCP_OPTCODE_ROUTERS 3 #define IPMIP_DHCP_OPTCODE_TIME_SERVERS 4 #define IPMIP_DHCP_OPTCODE_NAME_SERVERS 5 #define IPMIP_DHCP_OPTCODE_DOMAIN_NAME_SERVERS 6 #define IPMIP_DHCP_OPTCODE_LOG_SERVERS 7 #define IPMIP_DHCP_OPTCODE_COOKIE_SERVERS 8 #define IPMIP_DHCP_OPTCODE_LPR_SERVERS 9 #define IPMIP_DHCP_OPTCODE_IMPRESS_SERVERS 10 #define IPMIP_DHCP_OPTCODE_RESOURCE_LOCATION_SERVERS 11 #define IPMIP_DHCP_OPTCODE_HOST_NAME 12 #define IPMIP_DHCP_OPTCODE_BOOT_SIZE 13 #define IPMIP_DHCP_OPTCODE_MERIT_DUMP 14 #define IPMIP_DHCP_OPTCODE_DOMAIN_NAME 15 #define IPMIP_DHCP_OPTCODE_SWAP_SERVER 16 #define IPMIP_DHCP_OPTCODE_ROOT_PATH 17 #define IPMIP_DHCP_OPTCODE_EXTENSIONS_PATH 18 #define IPMIP_DHCP_OPTCODE_IP_FORWARDING 19 #define IPMIP_DHCP_OPTCODE_NON_LOCAL_SOURCE_ROUTING 20 #define IPMIP_DHCP_OPTCODE_POLICY_FILTER 21 #define IPMIP_DHCP_OPTCODE_MAX_DGRAM_REASSEMBLY 22 #define IPMIP_DHCP_OPTCODE_DEFAULT_IP_TTL 23 #define IPMIP_DHCP_OPTCODE_PATH_MTU_AGING_TIMEOUT 24 #define IPMIP_DHCP_OPTCODE_PATH_MTU_PLATEAU_TABLE 25 #define IPMIP_DHCP_OPTCODE_INTERFACE_MTU 26 #define IPMIP_DHCP_OPTCODE_ALL_SUBNETS_LOCAL 27 #define IPMIP_DHCP_OPTCODE_BROADCAST_ADDRESS 28 #define IPMIP_DHCP_OPTCODE_PERFORM_MASK_DISCOVERY 29 #define IPMIP_DHCP_OPTCODE_MASK_SUPPLIER 30 #define IPMIP_DHCP_OPTCODE_ROUTER_DISCOVERY 31 #define IPMIP_DHCP_OPTCODE_ROUTER_SOLICITATION_ADDRESS 32 #define IPMIP_DHCP_OPTCODE_STATIC_ROUTES 33 #define IPMIP_DHCP_OPTCODE_TRAILER_ENCAPSULATION 34 #define IPMIP_DHCP_OPTCODE_ARP_CACHE_TIMEOUT 35 #define IPMIP_DHCP_OPTCODE_IEEE802_3_ENCAPSULATION 36 #define IPMIP_DHCP_OPTCODE_DEFAULT_TCP_TTL 37 #define IPMIP_DHCP_OPTCODE_TCP_KEEPALIVE_INTERVAL 38 #define IPMIP_DHCP_OPTCODE_TCP_KEEPALIVE_GARBAGE 39 #define IPMIP_DHCP_OPTCODE_NIS_DOMAIN 40 #define IPMIP_DHCP_OPTCODE_NIS_SERVERS 41 #define IPMIP_DHCP_OPTCODE_NTP_SERVERS 42 #define IPMIP_DHCP_OPTCODE_VENDOR_ENCAPSULATED_OPTIONS 43 #define IPMIP_DHCP_OPTCODE_NETBIOS_NAME_SERVERS 44 #define IPMIP_DHCP_OPTCODE_NETBIOS_DD_SERVER 45 #define IPMIP_DHCP_OPTCODE_NETBIOS_NODE_TYPE 46 #define IPMIP_DHCP_OPTCODE_NETBIOS_SCOPE 47 #define IPMIP_DHCP_OPTCODE_FONT_SERVERS 48 #define IPMIP_DHCP_OPTCODE_X_DISPLAY_MANAGER 49 #define IPMIP_DHCP_OPTCODE_DHCP_REQUESTED_ADDRESS 50 #define IPMIP_DHCP_OPTCODE_DHCP_LEASE_TIME 51 #define IPMIP_DHCP_OPTCODE_DHCP_OPTION_OVERLOAD 52 #define IPMIP_DHCP_OPTCODE_DHCP_MESSAGE_TYPE 53 #define IPMIP_DHCP_OPTCODE_DHCP_SERVER_IDENTIFIER 54 #define IPMIP_DHCP_OPTCODE_DHCP_PARAMETER_REQUEST_LIST 55 #define IPMIP_DHCP_OPTCODE_DHCP_MESSAGE 56 #define IPMIP_DHCP_OPTCODE_DHCP_MAX_MESSAGE_SIZE 57 #define IPMIP_DHCP_OPTCODE_DHCP_RENEWAL_TIME 58 #define IPMIP_DHCP_OPTCODE_DHCP_REBINDING_TIME 59 #define IPMIP_DHCP_OPTCODE_VENDOR_CLASS_IDENTIFIER 60 #define IPMIP_DHCP_OPTCODE_VENDOR_CLASS 60 #define IPMIP_DHCP_OPTCODE_CLIENT_IDENTIFIER 61 #define IPMIP_DHCP_OPTCODE_NWIP_DOMAIN 62 #define IPMIP_DHCP_OPTCODE_NISPLUS_DOMAIN 64 #define IPMIP_DHCP_OPTCODE_NISPLUS_SERVERS 65 #define IPMIP_DHCP_OPTCODE_TFTP_SERVER_NAME 66 #define IPMIP_DHCP_OPTCODE_BOOTFILE_NAME 67 #define IPMIP_DHCP_OPTCODE_HOME_AGENTS 68 #define IPMIP_DHCP_OPTCODE_SMTP_SERVERS 69 #define IPMIP_DHCP_OPTCODE_POP3_SERVERS 70 #define IPMIP_DHCP_OPTCODE_NNTP_SERVERS 71 #define IPMIP_DHCP_OPTCODE_WWW_SERVERS 72 #define IPMIP_DHCP_OPTCODE_FINGER_SERVERS 73 #define IPMIP_DHCP_OPTCODE_IRC_SERVERS 74 #define IPMIP_DHCP_OPTCODE_STREETTALK_SERVERS 75 #define IPMIP_DHCP_OPTCODE_STDA_SERVERS 76 #define IPMIP_DHCP_OPTCODE_USER_CLASS 77 #define IPMIP_DHCP_OPTCODE_RELAY_AGENT_INFO 82 /* *=========================================================================== * DHCP RELAY AGENT IFNO SUBOPTIONS *=========================================================================== * DHCP sub options used with IPMIP_DHCP_OPTCODE_RELAY_AGENT_INFO (82) */ #define IPMIP_DHCP_SUBOPTCODE_RA_CIRCUIT_ID 1 #define IPMIP_DHCP_SUBOPTCODE_RA_REMOTE_ID 2 #define IPMIP_DHCP_SUBOPTCODE_RA_LINK_SELECTION 5 /* RFC3527 */ #define IPMIP_DHCP_SUBOPTCODE_RA_SERVER_OVERRIDE 11 /* RFC5107 */ #define IPMIP_DHCP_BROADCAST_FLAG (0x8000) enum { IPMIP_DHCP_TYPE_BOOL = 0, IPMIP_DHCP_TYPE_U32, IPMIP_DHCP_TYPE_U16, IPMIP_DHCP_TYPE_U8, IPMIP_DHCP_TYPE_STRING, IPMIP_DHCP_TYPE_IP, IPMIP_DHCP_TYPE_IP_PAIR, IPMIP_DHCP_TYPE_MAX }; enum { IPMIP_DHCP_ALLOC_ANY, IPMIP_DHCP_ALLOC_EXACT, IPMIP_DHCP_ALLOC_NETWORK }; extern const char *ipmip_dhcp_type_name[]; /* **************************************************************************** * 5 TYPES **************************************************************************** */ struct Ipmip_context; struct Ipmip_proc; struct Ip_sockaddr_in; struct Ipmip_buffer; struct Ipcom_route; struct Ipmip_dhcp_lease; #include typedef struct IP_PACKED1 Ipmip_dhcp_hdr { Ip_u8 op; /* Message operation code */ Ip_u8 htype; /* Link-layer address type */ Ip_u8 hlen; /* Link-layer address length */ Ip_u8 hops; /* Number of relay agents between client and server */ Ip_u32 xid; /* Transaction ID */ Ip_u16 secs; /* Elapsed time since a client began the dhcp process */ Ip_u16 flags; /* Flags field. The least significant bit is the broadcast bit */ Ip_u32 ciaddr; /* Client IP address if client in bound,renew or rebinding. */ Ip_u32 yiaddr; /* 'your' (client) IP address. */ Ip_u32 siaddr; /* IP address of next server to use in bootstrap */ Ip_u32 giaddr; /* Relay agent IP address, used in booting via a relay agent. */ Ip_u8 chaddr[16]; /* Client hardware address. */ Ip_u8 sname[IPMIP_DHCP_PKT_HDR_SNAME_LEN]; /* Optional server host name, null terminated string. */ Ip_u8 file[IPMIP_DHCP_PKT_HDR_FILE_LEN]; /* Boot file name, null terminated string */ Ip_u32 cookie; /* DHCP/BOOTP magic cookie */ } IP_PACKED2 Ipmip_dhcp_hdr_t; #include struct Ipmip_lladdr; typedef struct Ipmip_dhcp_node { /* HASH parameters */ Ip_u32 ifindex; Ip_u32 remote_id; struct Ip_iovec clientid; Ipmip_timer_lock_t *lock; Ipmip_timer_func_t process_func; void *opaque; } Ipmip_dhcp_node_t; typedef struct Ipmip_dhcp_context { /**/ Ipcom_mutex mutex; Ip_fd fd_udp; Ip_fd fd_pkt; Ip_fd fd_raw; Ipcom_hash *ifindex_table; Ipcom_hash *clientid_table; Ipcom_hash *remote_id_table; } Ipmip_dhcp_context_t; typedef struct Ipmip_dhcp_option { Ipcom_list next; Ip_u8 type; Ip_u8 option[1]; } Ipmip_dhcp_option_t; typedef struct Ipmip_dhcp_option_def { const char *name; Ip_u8 code; Ip_u8 type; } Ipmip_dhcp_option_def_t; typedef void (*Ipmip_dhcp_lease_free_t) ( struct Ipmip_context *ctx, struct Ipmip_proc *proc, struct Ipmip_dhcp_lease *lease ); typedef struct Ipmip_dhcp_rtab { Ipmip_dhcp_lease_free_t rtab_free; Ipcom_mutex rtab_lock; Ipmip_rtab_t *rtab; struct Ipmip_context *rtab_ctx; struct Ipmip_proc *rtab_proc; } Ipmip_dhcp_rtab_t; typedef struct Ipmip_dhcp_pool { Ipcom_list next; char *name; Ipcom_list slices; struct Ipmip_context *ctx; Ipmip_dhcp_rtab_t *rtab; Ipmip_dhcp_option_def_t *options; } Ipmip_dhcp_pool_t; typedef struct Ipmip_dhcp_lease { Ipmip_route_t ipmip; /* Key & Mask */ Ip_u32 mask; Ip_u32 prefix; Ip_u8 netmask_bits; Ip_u8 prefix_len; void *opaque; Ipmip_dhcp_pool_t *pool; Ipmip_dhcp_rtab_t *rtab; } Ipmip_dhcp_lease_t; typedef struct Ipmip_dhcp_slice { Ipcom_list next; Ip_u32 network; Ip_u32 mask; Ip_u32 start; Ip_u32 end; Ip_u8 netmask_bits; Ip_u8 slice_size; Ip_u32 remain; Ip_u32 last; } Ipmip_dhcp_slice_t; /* **************************************************************************** * 6 FUNCTIONS **************************************************************************** */ /* **************************************************************************** * 6 FUNCTIONS **************************************************************************** */ /******************************************************************************* * * ipmip_dhcp_context_create - ipmip_dhcp_context_create * * Allocate the DHCP context * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \ie * * RETURNS: No return value * * ERRNO: * */ IP_GLOBAL void ipmip_dhcp_context_create ( struct Ipmip_context *ctx, struct Ipmip_proc *proc ); /******************************************************************************* * * ipmip_dhcp_context_destroy - ipmip_dhcp_context_destroy * * Free an DHCP context * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \ie * * RETURNS: No return value * * ERRNO: * */ IP_GLOBAL void ipmip_dhcp_context_destroy ( struct Ipmip_context *ctx, struct Ipmip_proc *proc ); /******************************************************************************* * * ipmip_dhcp_option_find - ipmip_dhcp_option_find * * Find a particular option * * Parameters: * \is * \i options * Options array * \i optsize * Size of options array * \i code * Code we're looking for * \ie * * RETURNS: The option if found, otherwise IP_NULL * * ERRNO: * */ IP_GLOBAL Ip_u8 *ipmip_dhcp_option_find ( Ip_u8 *options, int optsize, Ip_u8 code ); /******************************************************************************* * * ipmip_dhcp_option_buffer_find - ipmip_dhcp_option_buffer_find * * Find a particular option in a dhcp packet * * Parameters: * \is * \i buf * A pointer to an initialized dynamic mobility buffer containing a DHCP frame. * See ipmip_buffer.h for more information regarding dynamic buffers and their * capabilities. * \i code * Code we're looking for * \ie * * RETURNS: The option if found, otherwise IP_NULL * * ERRNO: * */ IP_GLOBAL Ip_u8 *ipmip_dhcp_option_buffer_find ( struct Ipmip_buffer *buf, Ip_u8 code ); /******************************************************************************* * * ipmip_dhcp_option_buffer_find_ip - ipmip_dhcp_option_buffer_find_ip * * Find a particular option in a dhcp packet and return its value as a ip * * Parameters: * \is * \i buf * A pointer to an initialized dynamic mobility buffer containing a DHCP frame. * See ipmip_buffer.h for more information regarding dynamic buffers and their * capabilities. * \i code * Code we're looking for * \ie * * RETURNS: The ip data value of the option if found, otherwise 0 * * ERRNO: * */ IP_GLOBAL Ip_u32 ipmip_dhcp_option_buffer_find_ip ( struct Ipmip_buffer *buf, Ip_u8 code ); /******************************************************************************* * * ipmip_dhcp_option_buffer_find_u32 - ipmip_dhcp_option_buffer_find_u32 * * Find a particular option in a dhcp packet and return its value as a u32 * * Parameters: * \is * \i buf * A pointer to an initialized dynamic mobility buffer containing a DHCP frame. * See ipmip_buffer.h for more information regarding dynamic buffers and their * capabilities. * \i code * Code we're looking for * \ie * * RETURNS: The u32 data value of the option if found, otherwise 0 * * ERRNO: * */ IP_GLOBAL Ip_u32 ipmip_dhcp_option_buffer_find_u32 ( struct Ipmip_buffer *buf, Ip_u8 code ); /******************************************************************************* * * ipmip_dhcp_option_get_next - ipmip_dhcp_option_get_next * * Get next option * * Parameters: * \is * \i options * Options array * \i optsize * Size of options array * \ie * * RETURNS: The next option, otherwise IP_NULL * * ERRNO: * */ IP_GLOBAL Ip_u8 *ipmip_dhcp_option_get_next ( Ip_u8 *options, int optsize ); /******************************************************************************* * * ipmip_dhcp_option_buffer_open - ipmip_dhcp_option_buffer_open * * Remove the END option in case it exists. * * Parameters: * \is * \i buf * A pointer to an initialized dynamic mobility buffer containing a DHCP frame. * See ipmip_buffer.h for more information regarding dynamic buffers and their * capabilities. * \i code * The DHCP code to terminate at * \ie * * RETURNS: IP_TRUE if the buffer was terminated * * ERRNO: * */ IP_GLOBAL Ip_bool ipmip_dhcp_option_buffer_open ( struct Ipmip_buffer *buf, Ip_u8 code ); /******************************************************************************* * * ipmip_dhcp_option_buffer_close - ipmip_dhcp_option_buffer_close * * Add the END option * * Parameters: * \is * \i buf * A pointer to an initialized dynamic mobility buffer containing a DHCP frame. * See ipmip_buffer.h for more information regarding dynamic buffers and their * capabilities. * \ie * * RETURNS: No return value * * ERRNO: * */ IP_GLOBAL void ipmip_dhcp_option_buffer_close ( struct Ipmip_buffer *buf ); /******************************************************************************* * * ipmip_dhcp_option_buffer_init - ipmip_dhcp_option_buffer_init * * Init a new option (add opt/len) * * Parameters: * \is * \i buf * A pointer to an initialized dynamic mobility buffer containing a DHCP frame. * See ipmip_buffer.h for more information regarding dynamic buffers and their * capabilities. * \i opt * The option number * \ie * * RETURNS: The offset of the new option * * ERRNO: * */ IP_GLOBAL int ipmip_dhcp_option_buffer_init ( struct Ipmip_buffer *buf, Ip_u8 opt ); /******************************************************************************* * * ipmip_dhcp_option_buffer_end - ipmip_dhcp_option_buffer_end * * Close an option begun by using ipmip_dhcp_option_buffer_init * * Parameters: * \is * \i buf * A pointer to an initialized dynamic mobility buffer containing a DHCP frame. * See ipmip_buffer.h for more information regarding dynamic buffers and their * capabilities. * \i opt_start * The option offset returned by init * \ie * * RETURNS: No return value * * ERRNO: * */ IP_GLOBAL void ipmip_dhcp_option_buffer_end ( struct Ipmip_buffer *buf, int opt_start ); /******************************************************************************* * * ipmip_dhcp_option_buffer_append - ipmip_dhcp_option_buffer_append * * Add a new option * * Parameters: * \is * \i buf * A pointer to an initialized dynamic mobility buffer containing a DHCP frame. * See ipmip_buffer.h for more information regarding dynamic buffers and their * capabilities. * \i opt * The option number * \i opt_size * The option size * \i opt_data * The option data * \ie * * RETURNS: The offset of the new option * * ERRNO: * */ IP_GLOBAL int ipmip_dhcp_option_buffer_append ( struct Ipmip_buffer *buf, Ip_u8 opt, Ip_u8 opt_size, void *opt_data ); /******************************************************************************* * * ipmip_dhcp_option_buffer_append_u8 - ipmip_dhcp_option_buffer_append_u8 * * Add a new u8 option * * Parameters: * \is * \i buf * A pointer to an initialized dynamic mobility buffer containing a DHCP frame. * See ipmip_buffer.h for more information regarding dynamic buffers and their * capabilities. * \i opt * The option number * \i opt_data * The option data * \ie * * RETURNS: The offset of the new option * * ERRNO: * */ IP_GLOBAL int ipmip_dhcp_option_buffer_append_u8 ( struct Ipmip_buffer *buf, Ip_u8 opt, Ip_u8 opt_data ); /******************************************************************************* * * ipmip_dhcp_option_buffer_append_u32 - ipmip_dhcp_option_buffer_append_u32 * * Add a new u32 option * * Parameters: * \is * \i buf * A pointer to an initialized dynamic mobility buffer containing a DHCP frame. * See ipmip_buffer.h for more information regarding dynamic buffers and their * capabilities. * \i opt * The option number * \i opt_data * The option data * \ie * * RETURNS: The offset of the new option * * ERRNO: * */ IP_GLOBAL int ipmip_dhcp_option_buffer_append_u32 ( struct Ipmip_buffer *buf, Ip_u8 opt, Ip_u32 opt_data ); /******************************************************************************* * * ipmip_dhcp_option_buffer_append_ip - ipmip_dhcp_option_buffer_append_ip * * Add a new ip option * * Parameters: * \is * \i buf * A pointer to an initialized dynamic mobility buffer containing a DHCP frame. * See ipmip_buffer.h for more information regarding dynamic buffers and their * capabilities. * \i opt * The option number * \i opt_data * The option data * \ie * * RETURNS: The offset of the new option * * ERRNO: * */ IP_GLOBAL int ipmip_dhcp_option_buffer_append_ip ( struct Ipmip_buffer *buf, Ip_u8 opt, Ip_u32 opt_data ); /******************************************************************************* * * ipmip_dhcp_register - ipmip_dhcp_register * * Register a forwarding structure * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \i node * Node to register * \ie * * RETURNS: No return value * * ERRNO: * */ IP_GLOBAL void ipmip_dhcp_register ( struct Ipmip_context *ctx, struct Ipmip_proc *proc, Ipmip_dhcp_node_t *node ); /******************************************************************************* * * ipmip_dhcp_unregister - ipmip_dhcp_unregister * * Unregister a forwarding structure * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \i node * Node to register * \ie * * RETURNS: No return value * * ERRNO: * */ IP_GLOBAL void ipmip_dhcp_unregister ( struct Ipmip_context *ctx, struct Ipmip_proc *proc, Ipmip_dhcp_node_t *node ); /******************************************************************************* * * ipmip_dhcp_process - ipmip_dhcp_process * * Process DHCP messages * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \ie * * RETURNS: No return value * * ERRNO: * */ IP_GLOBAL void ipmip_dhcp_process ( struct Ipmip_context *ctx, struct Ipmip_proc *proc ); /******************************************************************************* * * ipmip_dhcp_retrieve_client_id - ipmip_dhcp_retrieve_client_id * * Retrieve the client id * * Parameters: * \is * \i pbuf * Packet * \i vec * Vector * \ie * * RETURNS: IP_TRUE if the retrieved id is a client ID. * * ERRNO: * */ IP_GLOBAL Ip_bool ipmip_dhcp_retrieve_client_id ( struct Ipmip_buffer *pbuf, struct Ip_iovec *vec ); /******************************************************************************* * * ipmip_dhcp_relay_to_server - ipmip_dhcp_relay_to_server * * Forward a DHCP request to the server * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \i pbuf * The DHCP request * \i src * Source address for this frame * \i server * The DHCP server to forward to * \ie * * RETURNS: No return value * * ERRNO: * */ IP_GLOBAL void ipmip_dhcp_relay_to_server ( struct Ipmip_context *ctx, struct Ipmip_proc *proc, struct Ipmip_pktbuf *pbuf, Ip_u32 src, Ip_u32 server ); /******************************************************************************* * * ipmip_dhcp_write_to_client - ipmip_dhcp_write_to_client * * Forward a DHCP request to the client * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \i pbuf * The DHCP request * \i ifinet * Optional source address for the forwarded message * \i iff * Outgoing interface * \i broadcast * Force broadcast * \ie * * RETURNS: No return value * * ERRNO: * */ IP_GLOBAL void ipmip_dhcp_write_to_client ( struct Ipmip_context *ctx, struct Ipmip_proc *proc, struct Ipmip_pktbuf *pbuf, Ip_u32 ifinet, struct Ipmip_if *iff, Ip_bool broadcast ); /******************************************************************************* * * ipmip_dhcp_server_reply - ipmip_dhcp_server_reply * * Send a server DHCP request to the client * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \i pbuf * The DHCP request * \i ifinet * Optional source address for the forwarded message * \i iff * Outgoing interface * \i broadcast * Force broadcast * \ie * * RETURNS: No return value * * ERRNO: * */ IP_GLOBAL void ipmip_dhcp_server_reply ( struct Ipmip_context *ctx, struct Ipmip_proc *proc, struct Ipmip_pktbuf *pbuf, Ip_u32 ifinet, struct Ipmip_if *iff, Ip_bool broadcast ); /******************************************************************************* * * ipmip_dhcp_option_parse_type - ipmip_dhcp_option_parse_type * * Parse a DHCP option * * Parameters: * \is * \i code * The DHCP option code * \i value * Value * \i type * Type of option * \ie * * RETURNS: The option * * ERRNO: * */ IP_GLOBAL Ipmip_dhcp_option_t *ipmip_dhcp_option_parse_type ( Ip_u8 code, const char *value, int type ); /******************************************************************************* * * ipmip_dhcp_option_parse_name - ipmip_dhcp_option_parse_name * * Parse a DHCP option based on name * * Parameters: * \is * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \i name * Name of option * \i value * Value * \i endptr * End of matching * \ie * * RETURNS: The option if known, otherwise IP_NULL * * ERRNO: * */ IP_GLOBAL Ipmip_dhcp_option_t *ipmip_dhcp_option_parse_name ( struct Ipmip_proc *proc, const char *name, const char *value, char **endptr ); /******************************************************************************* * * ipmip_dhcp_option_def_name_get - ipmip_dhcp_option_def_name_get * * Parse a DHCP option definition based on name * * Parameters: * \is * \i name * Name of option * \ie * * RETURNS: The option definition if known, otherwise IP_NULL * * ERRNO: * */ IP_GLOBAL const Ipmip_dhcp_option_def_t *ipmip_dhcp_option_def_name_get ( const char *name ); /******************************************************************************* * * ipmip_dhcp_option_def_code_get - ipmip_dhcp_option_def_code_get * * Parse a DHCP option definition based on code * * Parameters: * \is * \i code * Code of option * \ie * * RETURNS: The option definition if known, otherwise IP_NULL * * ERRNO: * */ IP_GLOBAL const Ipmip_dhcp_option_def_t *ipmip_dhcp_option_def_code_get ( Ip_u8 code ); /******************************************************************************* * * ipmip_dhcp_pool_create - ipmip_dhcp_pool_create * * Create a pool * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \i name * Name of pool * \i rtab * Routing table * \ie * * RETURNS: The pool * * ERRNO: * */ IP_GLOBAL Ipmip_dhcp_pool_t *ipmip_dhcp_pool_create ( struct Ipmip_context *ctx, struct Ipmip_proc *proc, const char *name, Ipmip_dhcp_rtab_t *rtab ); /******************************************************************************* * * ipmip_dhcp_pool_destroy - ipmip_dhcp_pool_destroy * * Destroy a pool * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \i pool * Pool * \ie * * RETURNS: No return value * * ERRNO: * */ IP_GLOBAL void ipmip_dhcp_pool_destroy ( struct Ipmip_context *ctx, struct Ipmip_proc *proc, Ipmip_dhcp_pool_t *pool ); /******************************************************************************* * * ipmip_dhcp_rtab_create - ipmip_dhcp_rtab_create * * Create a pool rtab * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \i rtab_free * Routing table free function * \ie * * RETURNS: The pool rtab * * ERRNO: * */ IP_GLOBAL Ipmip_dhcp_rtab_t *ipmip_dhcp_rtab_create ( struct Ipmip_context *ctx, struct Ipmip_proc *proc, Ipmip_dhcp_lease_free_t rtab_free ); /******************************************************************************* * * ipmip_dhcp_rtab_destroy - ipmip_dhcp_rtab_destroy * * Free an pool rtab * * Parameters: * \is * \i rtab * Rtab to free * \ie * * RETURNS: No return value * * ERRNO: * */ IP_GLOBAL void ipmip_dhcp_rtab_destroy ( Ipmip_dhcp_rtab_t *rtab ); /******************************************************************************* * * ipmip_dhcp_pool_lease_alloc - ipmip_dhcp_pool_lease_alloc * * Allocate a lease. If addr is specified, that will be attempted to allocate. * The RTAB mutex MUST be locked * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \i pool * DHCP pool * \i addr * address * \i prefix_len * Prefix length * \i alloc_rule * Method of allocation * \i opaque * Opaque data to store * \ie * * RETURNS: The allocated lease or IP_NULL * * ERRNO: * */ IP_GLOBAL Ipmip_dhcp_lease_t *ipmip_dhcp_pool_lease_alloc ( struct Ipmip_context *ctx, struct Ipmip_proc *proc, Ipmip_dhcp_pool_t *pool, Ip_u32 addr, Ip_u8 prefix_len, int alloc_rule, void *opaque ); /******************************************************************************* * * ipmip_dhcp_lease_alloc - ipmip_dhcp_lease_alloc * * Allocate a specific lease. The RTAB mutex MUST be locked * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \i pool * DHCP pool. May be IP_NULL * \i rtab * DHCP rtab * \i addr * address * \i prefix_len * Prefix length * \i netmask_bits * Number of bits in the netmask associated with this address * \i opaque * Opaque data to store * \ie * * RETURNS: The allocated lease or IP_NULL * * ERRNO: * */ IP_GLOBAL Ipmip_dhcp_lease_t *ipmip_dhcp_lease_alloc ( struct Ipmip_context *ctx, struct Ipmip_proc *proc, Ipmip_dhcp_pool_t *pool, Ipmip_dhcp_rtab_t *rtab, Ip_u32 addr, Ip_u8 prefix_len, Ip_u8 netmask_bits, void *opaque ); /******************************************************************************* * * ipmip_dhcp_lease_lookup - ipmip_dhcp_lease_lookup * * Find a specific lease. The RTAB mutex MUST be locked * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \i rtab * DHCP rtab * \i addr * address * \i prefix_len * Prefix length * \ie * * RETURNS: The lease if it exists * * ERRNO: * */ IP_GLOBAL Ipmip_dhcp_lease_t *ipmip_dhcp_lease_lookup ( struct Ipmip_context *ctx, struct Ipmip_proc *proc, Ipmip_dhcp_rtab_t *rtab, Ip_u32 addr, Ip_u8 prefix_len ); /******************************************************************************* * * ipmip_dhcp_lease_delete - ipmip_dhcp_lease_delete * * Delete a specific lease. The RTAB mutex MUST be locked * * Parameters: * \is * \i ctx * The generic mobility singleton context for IPMIP. For each started mobility * entity, there exists a mobility context which tracks configuration, system * events, available features and started processes. The mobility context is * created using ipmip_context_create(). See ipmip_context.h for more information * regarding the mobility entity context singleton. * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \i lease * DHCP lease * \ie * * RETURNS: No return value * * ERRNO: * */ IP_GLOBAL void ipmip_dhcp_lease_delete ( struct Ipmip_context *ctx, struct Ipmip_proc *proc, Ipmip_dhcp_lease_t *lease ); /******************************************************************************* * * ipmip_dhcp_pool_add_slice - ipmip_dhcp_pool_add_slice * * Add a slice to a pool. The RTAB mutex MUST be locked * * Parameters: * \is * \i pool * The pool * \i start_addr * Start address * \i end_addr * End address; if not specified will be calculated based on start and plen * \i plen * Prefix len for this slice * \i slice_size * Size of slices to be allocated * \ie * * RETURNS: No return value * * ERRNO: * */ IP_GLOBAL void ipmip_dhcp_pool_add_slice ( Ipmip_dhcp_pool_t *pool, Ip_u32 start_addr, Ip_u32 end_addr, Ip_u8 plen, Ip_u8 slice_size ); /******************************************************************************* * * ipmip_dhcp_option_print - ipmip_dhcp_option_print * * Print an option array based on type * * Parameters: * \is * \i proc * The process context associated with the currently executing thread. Each * thread and/or process in MIP must have its own unique process context. * If a process is started using ipmip_proc_start, the process context will * be allocated automatically by the IPMIP framework. Otherwise it must * be allocated using ipmip_proc_alloc(). * \i opt * Option block * \i type * Type * \ie * * RETURNS: The option value in human readable form * * ERRNO: * */ IP_GLOBAL const char *ipmip_dhcp_option_print ( struct Ipmip_proc *proc, Ip_u8 *opt, int type ); /******************************************************************************* * * ipmip_dhcp_option_entry_find - ipmip_dhcp_option_entry_find * * Return a specific option in an array * * Parameters: * \is * \i opts * Options * \i code * code * \ie * * RETURNS: The option if found * * ERRNO: * */ IP_GLOBAL Ipmip_dhcp_option_t *ipmip_dhcp_option_entry_find ( Ipcom_list *options, Ip_u8 code ); /******************************************************************************* * * ipmip_dhcp_buffer_append_option_entry - ipmip_dhcp_buffer_append_option_entry * * Add a specific option to a buffer, unless that code already exists. * * Parameters: * \is * \i buf * A pointer to an initialized dynamic mobility buffer containing a DHCP frame. * See ipmip_buffer.h for more information regarding dynamic buffers and their * capabilities. * \i opt * Option * \ie * * RETURNS: The option offset if added, -1 otherwise. * * ERRNO: * */ IP_GLOBAL int ipmip_dhcp_buffer_append_option_entry ( struct Ipmip_buffer *buf, Ipmip_dhcp_option_t *opt ); #endif #ifdef __cplusplus } #endif #endif /* **************************************************************************** * END OF FILE **************************************************************************** */