📄 natinit.c
字号:
/* natInit.c - WIND NET NAT initialization and timer API *//* Copyright 2000-2003 Wind River Systems, Inc. *//* @format.tab-size 4, @format.use-tabs true, @format.new-line lf *//*modification history--------------------01f,29aug03,zhu updated the format for refgen01e,29apr03,myz incorporate Sady's review suggestions. 01d,25apr03,myz created the event dispatcher to provide the timer facility.01c,25apr03,svk Implement version number01b,23apr03,zhu updated copyright01a,21apr03,myz Replaced RWOS task layer with direct vxWorks's task creation.030901 tk Create natInitSync semaphore*//* DESCRIPTIONThis library supplies the WIND NET NAT initialization function. It also supplies a NAT-dedicated timer facility. WIND NET NAT uses this timer facility internally to prune expired translation entries. However, it is also available for external use. If you are writing your own ALG to work with WIND NET NAT, you will find this NAT-dedicated timer facility easier to use than a generic timer facility. The call to natInit() automatically initializes the NAT-dedicated timer facility. To add events to the timer facility, call natTimerEvtCreate() or natOneShotTimerEvtCreate(). Each event you add to the queue remains dormant until you call natEvtActivate() for that event. To remove a timer event from the queue, call natEvtRemove(). *//* ANSI Headers */#include <stdio.h>#include <string.h>#include "dllLib.h"#include "taskLib.h"#include "msgQLib.h"#include "sysLib.h"#include "tickLib.h"#include "nat.h"/* globals */char * natVersion = NAT_VERSION; /* NAT version number string *//* local defines */#define TYPE_TIMER_EVENT 0x20#define TYPE_ACTIVATE_EVENT 0x25#define TYPE_REMOVE_EVENT 0x30#define TYPE_SHUTDOWN_EVENT 0x35#define OPTION_ONE_SHOT 0x1#define OPTION_PERIODIC_TIMER 0x2#define OPTION_STAY_UNTIL_REMOVED 0x4#define TIMER_START 0x200#define TIMER_STOP 0x210#define NAT_TASK_PRIORITY 70#define NAT_TASK_STACK 10000#define NAT_TASK_OPTION 0#define NAT_MESSAGE_NUM_MAX 100/* event dispatcher descriptor */typedef struct { DL_LIST timerEvtList; /* a list of timer events */ MSG_Q_ID msgQId; /* the message Q to receive the events */ int msgQTimeOutTicks; int taskId; ULONG lastTick; /* the last system tick when task is running*/ } EVT_DISPATCHER_DESC;/* event node */typedef struct EVT_NODE_S { DL_NODE node; int msgId; } EVT_NODE;typedef struct EVT_NODE_S SHUTDOWN_EVENT_DESC;typedef struct { EVT_NODE evtNode; /* event node */ int state; /* the running state, start or stopped */ ULONG duration; /* periodic time interval, a constant */ ULONG expireInterval; /* current time to expire */ FUNCPTR pEvtFunc; /* the event function associated with this event */ void * evtFuncContext; /* the event function's argument */ int option; } TIMER_EVENT_DESC;typedef struct { EVT_NODE evtNode; void * eventId; } ACTIVATE_EVENT_DESC,REMOVE_EVENT_DESC;LOCAL EVT_DISPATCHER_DESC natDispatcher;/* local functions */LOCAL void * timerEvtCreate (EVT_DISPATCHER_DESC *,ULONG,FUNCPTR,void *,int);LOCAL void dispatchTask (EVT_DISPATCHER_DESC *);LOCAL void timerUpdateAndEvtFuncExec (EVT_DISPATCHER_DESC *);LOCAL BOOL nodeSearch (DL_LIST *, DL_NODE *);LOCAL STATUS natDispatcherInit (void);/***************************************************************************** natInit - initialize WIND NET NAT** Call this function to initialize WIND NET NAT. This call should follow * a call to natcfg(), a function that initializes the array at the global * variable, 'nat_configuration_text'. This array supplies the * configuration parameters for WIND NET NAT. After the call to natInit() * completes, WIND NET NAT ignores the array at 'nat_configuration_text'. * Thus, if you change the configuration information in that array, you * need to disable WIND_NET_NAT entirely (see the natEnable() reference * entry), and then call natInit() again before the changes take effect. * For more information, see the <WIND NET NAT User's Guide> and the * comments in your natcfg.c file. * * This function also initializes the WIND NET NAT timer facility. * */STATUS natInit (void) { /* create semaphore for NAT sync with ALGs */ natInitSync = semBCreate (SEM_Q_FIFO, SEM_EMPTY); if (natInitSync == NULL) { nat_printf (NAT_PRINTF_ERROR,"Failed to create natInitSync semaphore\n"); return (ERROR); } return natDispatcherInit(); }/******************************************************************************* natDispatcherInit - initialize the NAT event dispatcher** Call this function to initialize the message queue and task that comprise * the NAT event dispatcher. ** NOMANUAL**/LOCAL STATUS natDispatcherInit (void) { dllInit(&natDispatcher.timerEvtList); if ((natDispatcher.msgQId = msgQCreate(NAT_MESSAGE_NUM_MAX, sizeof(void *), MSG_Q_FIFO)) == NULL) { nat_printf(NAT_PRINTF_ERROR, "Fail to create the message Q\n"); return ERROR; } /* set the clock rate(resolution) 500ms by default */ natDispatcher.msgQTimeOutTicks = (sysClkRateGet() * 500)/1000; natDispatcher.taskId = taskSpawn("tNAT",NAT_TASK_PRIORITY, NAT_TASK_OPTION, NAT_TASK_STACK, (FUNCPTR)dispatchTask, (int)&natDispatcher, 0, 0,0,0,0,0,0,0,0); if (natDispatcher.taskId == ERROR) return ERROR; else return OK; }/******************************************************************************** natOneShotTimerEvtCreate - create a one-shot timer event** This routine is similar to natTimerEvtCreate(), but it sets up a one-time * event instead of a recurring event. This event remains dormant in the * queue until you call natEvtActivate() for the event and thus start the clock * on the event. After the <interval> has expired, the function at <pFunc> * executes in the context of the 'tNAT' task. When control returns from * the function at <pFunc>, the event is automatically deleted from the * message queue and does not repeat. * * RETURNS: 'eventId', upon success; or NULL, upon failure. * * Save the 'eventId' for use in the natEvtActivate() call you must make to * activate the event. ***/void * natOneShotTimerEvtCreate ( ULONG interval, /* the expire time interval */ FUNCPTR pFunc, /* event function called when the time expired */ void * pArg /* event function's argument */ ) { return timerEvtCreate(&natDispatcher,interval,pFunc,pArg,OPTION_ONE_SHOT); }/******************************************************************************** natTimerEvtCreate - create a repeating timer event** This routine creates a timer event and stores it in an internal message * queue processed by 'tNAT' task. After you activate the event (see the * netEvtActivate() reference entry), the registered function, <pFunc> executes * in the context of the 'tNAT' task every <interval> milliseconds. ** RETURNS: NULL, upon failure; or 'eventId', upon success. * * Save the 'eventId' for use in the natEvtActivate() call you must make to * activate the event. **/void * natTimerEvtCreate ( ULONG interval, /* the expire time interval, in msec */ FUNCPTR pFunc, /* event function called when the time expired */ void * pArg /* event function's argument */ ) { return timerEvtCreate(&natDispatcher,interval,pFunc,pArg, OPTION_PERIODIC_TIMER); }/******************************************************************************** timerEvtCreate - perform the timer event creation** Internal implementation of natTimerEvtCreate(). ** NOMANUAL* */LOCAL void * timerEvtCreate ( EVT_DISPATCHER_DESC * pDesc, /* event dispatcher descriptor */ ULONG interval, FUNCPTR pFunc, void * pArg, /* event function's argument */ int option ) { TIMER_EVENT_DESC * pEvt; if ((pEvt = (TIMER_EVENT_DESC *)malloc(sizeof(TIMER_EVENT_DESC))) == NULL) { nat_printf(NAT_PRINTF_ERROR, "Fail to allocate the memory for NAT timer event\n"); return NULL; } if (interval == 0) { nat_printf(NAT_PRINTF_ERROR, "Wrong time interval value: 0\n"); return NULL; } pEvt->evtNode.msgId = TYPE_TIMER_EVENT; pEvt->pEvtFunc = pFunc; pEvt->evtFuncContext = pArg; pEvt->option = option; pEvt->state = TIMER_STOP; /* convert to vxWorks ticks */ pEvt->duration = (interval * sysClkRateGet())/1000; pEvt->expireInterval = pEvt->duration; if (msgQSend(pDesc->msgQId,(char *)&pEvt,sizeof(void *), sysClkRateGet() >> 2, /*wait for 0.5 sec, not to hang forever in case */ MSG_PRI_NORMAL) != OK) { free((void *)pEvt); return NULL; } return ((void *)pEvt); }/******************************************************************************** natEvtActivate - activate an event** Call this routine to activate an event already registered with the NAT * timer facility. To register a recurring event, call natTimerEvtCreate(). * To register a one-time event, call natOneShotTimerEvtCreate(). The call * back functions registered with these events execute in the context of * the 'tNAT' task. ** RETURNS: OK, upon success; or ERROR, upon failure.**/STATUS natEvtActivate ( void * eventId /* From a successful event creation. */ ) { ACTIVATE_EVENT_DESC * pEvt; if ((pEvt = (ACTIVATE_EVENT_DESC *)malloc(sizeof(ACTIVATE_EVENT_DESC))) == NULL) { nat_printf(NAT_PRINTF_ERROR, "Fail to allocate the memory for activation event\n"); return ERROR; } pEvt->evtNode.msgId = TYPE_ACTIVATE_EVENT; pEvt->eventId = eventId; if (msgQSend(natDispatcher.msgQId,(char *)&pEvt,sizeof(void *), sysClkRateGet() >> 2, /*wait for 0.5 sec, not to hang forever in case */ MSG_PRI_NORMAL) != OK) { free((void *)pEvt); return ERROR; } return (OK); }/******************************************************************************** natEvtRemove - remove an event from the NAT message queue*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -