?? skbuff.h
字號:
#ifndef _LINUX_SKBUFF_H
#define _LINUX_SKBUFF_H
#include <linux/timer.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include "irda2k_globals.h"
typedef int wait_queue_head_t; // dummy
struct sk_buff_head {
struct sk_buff* next;
struct sk_buff* prev;
__u32 qlen;
spinlock_t lock;
};
struct skb_shared_info {
__u32 dataref;
};
struct sk_buff {
struct sk_buff* next;
struct sk_buff* prev;
struct sk_buff_head* list;
void* sk;
struct net_device* dev;
union
{
struct tcphdr* th;
struct udphdr* uh;
struct icmphdr* icmph;
struct igmphdr* igmph;
struct iphdr* ipiph;
struct spxhdr* spxh;
unsigned char* raw;
} h;
union
{
struct iphdr* iph;
struct ipv6hdr* ipv6h;
struct arphdr* arph;
struct ipxhdr* ipxh;
unsigned char* raw;
} nh;
union
{
struct ethhdr* ethernet;
unsigned char* raw;
} mac;
char cb[48];
unsigned int len;
unsigned char cloned;
__u32 priority;
__u32 users;
unsigned short protocol;
unsigned int truesize;
unsigned char* head;
unsigned char* data;
unsigned char* tail;
unsigned char* end;
void (*destructor)(struct sk_buff *);
PNDIS_PACKET pNdisPacket;
struct {
UINT nextEntryOffset;
NDIS_CLASS_ID classId;
UINT size;
UINT extraBOFs;
UINT minTurnAroundTime;
UINT zero[3];
} irdaPacketInfo;
};
#define skb_shinfo(SKB) ((struct skb_shared_info*)((SKB)->end))
//
// private data in NDIS packets
//
typedef struct _IRDA_PACKET_RESERVED {
PNDIS_PACKET pOrigPacket;
struct sk_buff skb;
} IRDA_PACKET_RESERVED, *PIRDA_PACKET_RESERVED;
__inline __u32 skb_queue_len(struct sk_buff_head* list)
{
return list->qlen;
}
__inline int skb_queue_empty(struct sk_buff_head* list)
{
return (list->next == (struct sk_buff*)list);
}
__inline void skb_queue_head(struct sk_buff_head* list, struct sk_buff* newsk)
{
unsigned long dummy;
struct sk_buff* prev;
struct sk_buff* next;
spin_lock_irqsave(&list->lock, dummy);
newsk->list = list;
list->qlen++;
prev = (struct sk_buff*)list;
next = prev->next;
newsk->next = next;
newsk->prev = prev;
next->prev = newsk;
prev->next = newsk;
spin_unlock_irqrestore(&list->lock, dummy);
}
__inline void skb_queue_tail(struct sk_buff_head* list, struct sk_buff* newsk)
{
unsigned long dummy;
struct sk_buff* prev;
struct sk_buff* next;
spin_lock_irqsave(&list->lock, dummy);
newsk->list = list;
list->qlen++;
next = (struct sk_buff *)list;
prev = next->prev;
newsk->next = next;
newsk->prev = prev;
next->prev = newsk;
prev->next = newsk;
spin_unlock_irqrestore(&list->lock, dummy);
}
__inline struct sk_buff* skb_dequeue(struct sk_buff_head* list)
{
unsigned long dummy;
struct sk_buff* next;
struct sk_buff* prev;
struct sk_buff* result;
spin_lock_irqsave(&list->lock, dummy);
prev = (struct sk_buff *) list;
next = prev->next;
result = NULL;
if (next != prev)
{
result = next;
next = next->next;
list->qlen--;
next->prev = prev;
prev->next = next;
result->next = NULL;
result->prev = NULL;
result->list = NULL;
}
spin_unlock_irqrestore(&list->lock, dummy);
return result;
}
__inline int skb_is_nonlinear(const struct sk_buff* skb)
{
return 0;
}
__inline struct sk_buff* skb_peek_tail(struct sk_buff_head* list)
{
struct sk_buff* prev = ((struct sk_buff*)list)->prev;
if (prev == (struct sk_buff*)list)
prev = NULL;
return prev;
}
__inline void skb_queue_head_init(struct sk_buff_head* list)
{
spin_lock_init(&list->lock);
list->prev = (struct sk_buff*)list;
list->next = (struct sk_buff*)list;
list->qlen = 0;
}
__inline struct sk_buff* skb_get(struct sk_buff* skb)
{
//if (((PIRDA_PACKET_RESERVED)(skb->pNdisPacket->ProtocolReserved))->pOrigPacket)
//KdPrint(("skb_get(%08X)\n", skb));
NdisInterlockedIncrement(&skb->users);
return skb;
}
__inline unsigned char* skb_put(struct sk_buff* skb, unsigned int len)
{
unsigned char* tmp = skb->tail;
skb->tail+=len;
skb->len+=len;
return tmp;
}
__inline unsigned char* skb_push(struct sk_buff* skb, unsigned int len)
{
skb->data-=len;
skb->len+=len;
return skb->data;
}
__inline unsigned char* skb_pull(struct sk_buff* skb, unsigned int len)
{
if (len > skb->len)
return NULL;
skb->len-=len;
return skb->data+=len;
}
__inline int skb_headroom(const struct sk_buff* skb)
{
return skb->data-skb->head;
}
__inline int skb_tailroom(const struct sk_buff *skb)
{
return skb->end - skb->tail;
}
__inline struct sk_buff* skb_peek(struct sk_buff_head* list)
{
struct sk_buff* next = ((struct sk_buff*)list)->next;
if (next == (struct sk_buff*)list)
next = NULL;
return next;
}
__inline void skb_reserve(struct sk_buff* skb, unsigned int len)
{
skb->data+=len;
skb->tail+=len;
}
__inline void skb_trim(struct sk_buff* skb, unsigned int len)
{
if (skb->len > len)
{
skb->len = len;
skb->tail = skb->data+len;
}
}
__inline void skb_orphan(struct sk_buff *skb)
{
if (skb->destructor)
skb->destructor(skb);
skb->destructor = NULL;
if (skb->sk != NULL)
*(int*)5 = 0;
}
__inline struct sk_buff* dev_alloc_skb(unsigned int length)
{
NDIS_STATUS status;
PNDIS_PACKET pPacket;
struct sk_buff* skb;
__u8* data;
length += 16;
NdisAllocatePacket(&status, &pPacket, globals.packetPool);
if (status != STATUS_SUCCESS)
return NULL;
if (NdisAllocateMemoryWithTag(&data, length + sizeof(struct skb_shared_info),
'SKBd') != STATUS_SUCCESS)
{
NdisFreePacket(pPacket);
return NULL;
}
((PIRDA_PACKET_RESERVED)(pPacket->ProtocolReserved))->pOrigPacket = NULL;
skb = &(((PIRDA_PACKET_RESERVED)(pPacket->ProtocolReserved))->skb);
skb->sk = NULL;
skb->truesize = length + sizeof(struct sk_buff);
skb->head = data;
skb->data = data + 16;
skb->tail = data + 16;
skb->end = data + length;
skb->len = 0;
skb->cloned = 0;
skb->destructor = NULL;
skb->users = 1;
skb->pNdisPacket = pPacket;
skb_shinfo(skb)->dataref = 1;
// KdPrint(("*** NEW SKB: %p / %p (data) ***\n", skb, skb->head));
return skb;
}
__inline struct sk_buff* skb_copy(const struct sk_buff* skb, int priority)
{
struct sk_buff *n;
int headerlen = skb->data-skb->head;
unsigned long offset;
n = dev_alloc_skb(skb->end - skb->head);
if (n == NULL)
return NULL;
skb_reserve(n, headerlen);
skb_put(n,skb->len);
// n->csum = skb->csum;
// n->ip_summed = skb->ip_summed;
memcpy(n->data - headerlen, skb->head, headerlen+skb->len);
offset = n->data - skb->data;
n->list=NULL;
n->sk=NULL;
n->dev=skb->dev;
n->priority=skb->priority;
n->protocol=skb->protocol;
// n->dst=dst_clone(skb->dst);
n->h.raw=skb->h.raw+offset;
n->nh.raw=skb->nh.raw+offset;
n->mac.raw=skb->mac.raw+offset;
memcpy(n->cb, skb->cb, sizeof(skb->cb));
n->users = 1;
// n->pkt_type=skb->pkt_type;
// n->stamp=skb->stamp;
n->destructor = NULL;
// n->security=skb->security;
//KdPrint(("copy %08X - %08X\n", ((PIRDA_PACKET_RESERVED)(skb->pNdisPacket->ProtocolReserved))->pOrigPacket, skb));
return n;
}
__inline struct sk_buff* skb_clone(struct sk_buff* skb, int priority)
{
NDIS_STATUS status;
PNDIS_PACKET pPacket;
struct sk_buff* n;
NdisAllocatePacket(&status, &pPacket, globals.packetPool);
if (status != STATUS_SUCCESS)
return NULL;
((PIRDA_PACKET_RESERVED)(pPacket->ProtocolReserved))->pOrigPacket = NULL;
n = &(((PIRDA_PACKET_RESERVED)(pPacket->ProtocolReserved))->skb);
#define C(x) n->x = skb->x
n->next = n->prev = NULL;
n->list = NULL;
n->sk = NULL;
// C(stamp);
C(dev);
C(h);
C(nh);
C(mac);
// C(dst);
// dst_clone(n->dst);
memcpy(n->cb, skb->cb, sizeof(skb->cb));
C(len);
// C(csum);
n->cloned = 1;
// C(pkt_type);
// C(ip_summed);
C(priority);
n->users = 1;
C(protocol);
// C(security);
C(truesize);
C(head);
C(data);
C(tail);
C(end);
n->destructor = NULL;
n->pNdisPacket = pPacket;
NdisInterlockedIncrement(&skb_shinfo(skb)->dataref);
skb->cloned = 1;
//KdPrint(("clone %08X - %08X->%08X\n", ((PIRDA_PACKET_RESERVED)(skb->pNdisPacket->ProtocolReserved))->pOrigPacket, skb, n));
return n;
}
__inline void kfree_skb(struct sk_buff* skb)
{
PNDIS_BUFFER pBuffer;
//if (((PIRDA_PACKET_RESERVED)(skb->pNdisPacket->ProtocolReserved))->pOrigPacket)
//KdPrint(("!%08X (%08X, %d) - %08X, %d\n", ((PIRDA_PACKET_RESERVED)(skb->pNdisPacket->ProtocolReserved))->pOrigPacket, skb->destructor, skb->cloned, skb, skb->users));
if ((skb->users == 1) || (NdisInterlockedDecrement(&skb->users) == 0))
{
// KdPrint(("*** FREE SKB: %p / %p (data) / %p (packet) ***\n", skb, skb->head, skb->pNdisPacket));
if (skb->destructor)
skb->destructor(skb);
NdisUnchainBufferAtFront(skb->pNdisPacket, &pBuffer);
if (pBuffer != NULL)
NdisFreeBuffer(pBuffer);
if (!skb->cloned || (skb_shinfo(skb)->dataref == 1) ||
(NdisInterlockedDecrement(&skb_shinfo(skb)->dataref) == 0))
{
NdisFreeMemory(skb->head, skb->truesize - sizeof(struct sk_buff) +
sizeof(struct skb_shared_info), 0);
}
NdisFreePacket(skb->pNdisPacket);
}
}
#define dev_kfree_skb(a) kfree_skb(a)
/**
* skb_share_check - check if buffer is shared and if so clone it
* @skb: buffer to check
* @pri: priority for memory allocation
*
* If the buffer is shared the buffer is cloned and the old copy
* drops a reference. A new clone with a single reference is returned.
* If the buffer is not shared the original buffer is returned. When
* being called from interrupt status or with spinlocks held pri must
* be GFP_ATOMIC.
*
* NULL is returned on a memory allocation failure.
*/
__inline struct sk_buff* skb_share_check(struct sk_buff* skb, int pri)
{
if (skb->users != 1)
{
struct sk_buff *nskb = skb_clone(skb, pri);
kfree_skb(skb);
skb = nskb;
}
return skb;
}
/**
* skb_linearize - convert paged skb to linear one
* @skb: buffer to linarize
* @gfp: allocation mode
*
* Here, this function does nothing because skbs are always linear
*/
__inline int skb_linearize(struct sk_buff *skb, int gfp)
{
return 0;
}
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -