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

📄 skbuff.h

📁 红外接口串口仿真
💻 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 Qdisc
{
    struct sk_buff_head q;
};

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 pskb_may_pull(struct sk_buff *skb, unsigned int len)
{
    if (len <= skb->len)
        return 1;
    return 0;
}
 
__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 + -