⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netbuf.h

📁 一个tcp/ip协议栈,带有PPP、IP、TCP、UDP等协议
💻 H
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
* netbuf.h - Network Buffers header file.
*
* Copyright (c) 1998 Global Election Systems Inc.
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice and the following disclaimer are included verbatim in any 
* distributions. No written agreement, license, or royalty fee is required
* for any of the authorized uses.
*
* THIS SOFTWARE IS PROVIDED BY THE 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 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.
*
******************************************************************************
* REVISION HISTORY
*
* 98-01-30 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
*	Original based on BSD and ka9q mbufs.
******************************************************************************
* THEORY OF OPERATION
*
*	The network buffers (nBufs) form the basis for passing data between the
* protocols in the protocol stacks.  They are extensible in that they can be
* chained together when a data block is larger than the data area of a single
* buffer or if you need to prepend or append data that won't fit on the
* beginning or end (respectively) of a buffer.  This avoids expensive copy
* operations at the expense of consuming more memory.
*
*	This buffer structure is based on the mbuf structure in the BSD network
* codes except that it does not support clusters, types, or flags which were
* not needed in this stack.  Also, these are designed to be allocated from a
* static array rather than being malloc'd to avoid the overhead of heap memory
* management.  This design is for use in real-time embedded systems where the
* operating parameters are known beforehand and performance is critical.
*
*	To set up this buffer system, set the buffer size NBUFSZ in the header
* file and MAXNBUFS in the program file.  NBUFSZ should be set so that
* the link layer packets fit in a single buffer (normally).  You can monitor
* the minFreeBufs variable to ensure that your setting of MAXNBUFS is
* appropriate for your system.
*
*	Note that the prepend operation frees the current nBuf chain if it fails
* while the append operation does not.  This assumes that a prepend failure
* is catastrophic (if you can't add a header, you can't send it) while an
* append failure may mean that you send what you've got and try again.
*****************************************************************************/

#ifndef NETBUF_H
#define NETBUF_H


/*************************
*** PUBLIC DEFINITIONS ***
*************************/
/* 
 * By making NBUFSZ large enough to contain the largest mtu of all the
 * interfaces, no packet need ever be split across buffers.
 */
#if ETHER_SUPPORT
#define NBUFSZ 1580				/* Max data size of an nBuf. */
#else
#define NBUFSZ 128				/* Max data size of an nBuf. */
#endif

/************************
*** PUBLIC DATA TYPES ***
************************/
/* The network buffer structure. */
typedef struct NBuf_s {
	struct	NBuf_s *nextBuf;	/* Next buffer in chain. */
	struct	NBuf_s *nextChain;	/* Next chain in queue. */
	char *	data;				/* Location of data. */
	u_int	len;				/* Bytes (octets) of data in this nBuf. */
	u_int	chainLen;			/* Total bytes in this chain - valid on top only. */
	u_long	sortOrder;			/* Sort order value for sorted queues. */
	char	body[NBUFSZ];		/* Data area of the nBuf. */
} NBuf;

/* The chain queue header structure. */
typedef struct NBufQHdr_s {
	NBuf	*qHead;				/* The first nBuf chain in the queue. */
	NBuf	*qTail;				/* The last nBuf chain in the queue. */
	u_int	qLen;				/* The number of chains in the queue. */
} NBufQHdr;

/* Network buffer statistics. */
typedef struct NBufStats_s {
	DiagStat headLine;			/* Headline text. */
	DiagStat curFreeBufs;		/* The current number of free nBufs. */
	DiagStat minFreeBufs;		/* The minimum number of free nBufs during operation. */
	DiagStat maxFreeBufs;		/* The maximum number of free nBufs during operation. */
	DiagStat maxChainLen;		/* Size of largest chain (from nChainLen). */
	DiagStat endRec;
} NBufStats;


/*****************************
*** PUBLIC DATA STRUCTURES ***
*****************************/
extern NBuf *topNBuf;
#if STATS_SUPPORT > 0
extern NBufStats nBufStats;
#else
extern u_int curFreeBufs;
#endif


/***********************
*** PUBLIC FUNCTIONS ***
***********************/
/* Initialize the memory buffer sub-system. */
void nBufInit (void);

/* nBUFTOPTR - Return nBuf's data pointer casted to type t. */
#define	nBUFTOPTR(n, t)	((t)((n)->data))

#if STATS_SUPPORT > 0
/* nBUFSFREE - Return the number of free buffers. */
#define nBUFSFREE() nBufStats.curFreeBufs.val
#else
#define nBUFSFREE() curFreeBufs
#endif

/*
 * nGET - Allocate an nBuf off the free list.
 * Return n pointing to new nBuf on success, n set to NULL on failure.
 */
#if STATS_SUPPORT > 0
#define	nGET(n) { \
	OS_ENTER_CRITICAL(); \
	if (((n) = topNBuf) != NULL) { \
		topNBuf = (n)->nextBuf; \
		(n)->nextBuf = NULL; \
		(n)->nextChain = NULL; \
		(n)->data = (n)->body; \
		(n)->len = 0; \
		(n)->chainLen = 0; \
		if (--nBufStats.curFreeBufs.val < nBufStats.minFreeBufs.val) \
			nBufStats.minFreeBufs.val = nBufStats.curFreeBufs.val; \
	} \
	OS_EXIT_CRITICAL(); \
}
#else
#define	nGET(n) { \
	OS_ENTER_CRITICAL(); \
	if (((n) = topNBuf) != NULL) { \
		topNBuf = (n)->nextBuf; \
		(n)->nextBuf = NULL; \
		(n)->nextChain = NULL; \
		(n)->data = (n)->body; \
		(n)->len = 0; \
		(n)->chainLen = 0; \
		--curFreeBufs; \
	} \
	OS_EXIT_CRITICAL(); \
}
#endif

/*
 * nFREE - Free a single nBuf and place the successor, if any, in out.
 * The value of n is invalid but unchanged.  If the buffer is already
 * free (nextChain references self), do nothing.
 *
 * nFree - Free a single nBuf and associated external storage.
 * Return the next nBuf in the chain, if any.
 *
 * nFreeChain - Free all nBufs in a chain.  
 * Return the next chain in the queue, if any.
 */
#if STATS_SUPPORT > 0

#define	nFREE(n, out) { \
	OS_ENTER_CRITICAL(); \
	if (n) { \
        if ((n)->nextChain == (n)) { \
			panic("nFREE"); \
        } else { \
			if (((out) = (n)->nextBuf) != NULL) \
				(out)->nextChain = (n)->nextChain; \
			(n)->nextBuf = topNBuf; \
			topNBuf = (n); \
			nBufStats.curFreeBufs.val++; \
		} \
    } else (out) = NULL; \
	OS_EXIT_CRITICAL(); \
}

#else

#define	nFREE(n, out) { \
	OS_ENTER_CRITICAL(); \
	if (n) { \
		if ((n)->nextChain == (n)) \
			panic("nFREE"); \
		else { \
			if (((out) = (n)->nextBuf) != NULL) \
				(out)->nextChain = (n)->nextChain; \
			(n)->nextBuf = topNBuf; \
			topNBuf = (n); \
			curFreeBufs++; \
		} \
	} else (out) = NULL; \
	OS_EXIT_CRITICAL(); \
}

#endif

NBuf *nFree(NBuf *n);
NBuf *nFreeChain(NBuf *n);

/*
 * nALIGN - Position the data pointer of a new nBuf so that it is len bytes
 * away from the end of the data area.
 */
#define	nALIGN(n, len) ((n)->data = (n)->body + NBUFSZ - (len))

/*
 * nADVANCE - Advance the data pointer of a new nBuf so that it is len bytes
 * away from the beginning of the data area.
 */
#define nADVANCE(n, len) ((n)->data = (n)->body + (len))

/*
 * nLEADINGSPACE - Return the amount of space available before the current
 * start of data in an nBuf.
 */
#define	nLEADINGSPACE(n) ((n)->len > 0 ? (n)->data - (n)->body : NBUFSZ)
	    
/*
 * nTRAILINGSPACE - Return the amount of space available after the end of data
 * in an nBuf.
 */
#define	nTRAILINGSPACE(n) (NBUFSZ - (u_int)((n)->data - (n)->body) - (n)->len)

/*
 * nPREPEND - Prepend plen bytes to nBuf n and load data from s if non-null.
 * Note that plen must be <= NBUFSZ.
 * If a new nBuf must be allocated but if allocation fails, the original nBuf chain
 * is freed and n is set to NULL.  Otherwise n is set to the new top of the chain.
 * Note that the chain length is updated but the chain is assumed to not be in
 * a queue.
 *
 * nPrepend - Same as above except return the new nBuf chain on success, NULL

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -