当前位置: 首页 > news >正文

网站建设哪家性价比高厦门百度关键词推广

网站建设哪家性价比高,厦门百度关键词推广,做一个购物平台需要多少钱,有什么字体设计网站好一. 前言 内核提供了大量实用的操作sk_buff的函数,在开发网络设备驱动程序和修改网络协议栈代码时需要用到。这些函数从功能上可以分为三类:创建,释放和复制socket buffer;操作sk_buff结构中的参数和指针;管理socket b…

一. 前言

        内核提供了大量实用的操作sk_buff的函数,在开发网络设备驱动程序和修改网络协议栈代码时需要用到。这些函数从功能上可以分为三类:创建,释放和复制socket buffer;操作sk_buff结构中的参数和指针;管理socket buffer的队列。本文主要介绍其中一些典型的函数。本文使用的内核版本是3.18.45。

二. 创建和释放socket buffer

1. alloc_skb

        alloc_skb是__alloc_skb函数的封装,是为socket buffer分配内存的主要函数。其中具体的实现不再分析了,主要介绍调用alloc_skb函数后,sk_buff各个参数和指针的情况。其中,skb->head,skb->data和skb->tail都指向分配内存的开始地址,skb->end指向分配内存的结束地址,分配的数据大小是4字节对齐的。如下图所示。

        注意:调用alloc_skb分配的skb,由于实际数据长度还不确定,其中skb->len = 0。

2. kree_skb

        kree_skb函数是__kfree_skb函数的封装,由于同一个socket buffer可能被多个地方使用,所以kfree_skb只有在skb->users = 1时,才会完全释放socket buffer,其他情况只会将skb->users减1。

三. 操作sk_buff参数和指针的函数

1. skb_reserve

skb_reserve的函数原型:

static inline void skb_reserve(struct sk_buff *skb, int len)
{skb->data += len;skb->tail += len;
}

        skb_reserve函数的使用是在alloc_skb函数之后,作用是为网络协议栈的二层,三层以及数据负载留出空间。如下图所示:

         上图中,留出的reserve len就是为协议栈的其他数据压入预留空间,从中也可以看出,skb->data到skb->tail之间保存的是真实负载数据的内容。

2. skb_put

skb_put的函数原型:

unsigned char *skb_put(struct sk_buff *skb, unsigned int len)
{unsigned char *tmp = skb_tail_pointer(skb);SKB_LINEAR_ASSERT(skb);skb->tail += len;skb->len  += len;if (unlikely(skb->tail > skb->end))skb_over_panic(skb, len, __builtin_return_address(0));return tmp;
}

        从函数实现可知,skb_put函数将skb->tail加了len,表示将skb的实际负载数据的长度加len,要实现这一点,alloc_skb分配的len减去skb_reserve的len应该要大于等于skb_put的len,这样才能保证skb_put函数运行没问题。示意图如下:

3. skb_push

skb_push的函数原型:

unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
{skb->data -= len;skb->len  += len;if (unlikely(skb->data<skb->head))skb_under_panic(skb, len, __builtin_return_address(0));return skb->data;
}

        从函数实现可以看出,skb_push将data指针往低地址移动len长度,同时skb->len长度加len,然后程序将向该地址压入长度为len长度的数据。示意图如下:

4. skb_pull

skb_pull的函数原型:

static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
{skb->len -= len;BUG_ON(skb->len < skb->data_len);return skb->data += len;
}static inline unsigned char *skb_pull_inline(struct sk_buff *skb, unsigned int len)
{return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len);
}unsigned char *skb_pull(struct sk_buff *skb, unsigned int len)
{return skb_pull_inline(skb, len);
}

        从函数实现可以看出,skb_pull是__skb_pull函数的封装,skb_pull_inline判断len要小于skb->len。skb_pull函数就是skb_push的反向操作函数,作用是将skb->data指针向高地址移动len,同时,skb->len减len,相当于从skb中删除了长度为len的数据。

5. skb_trim

skb_trim函数的原型:

static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset)
{skb->tail = skb->data + offset;
}static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
{if (unlikely(skb_is_nonlinear(skb))) {WARN_ON(1);return;}skb->len = len;skb_set_tail_pointer(skb, len);
}void skb_trim(struct sk_buff *skb, unsigned int len)
{if (skb->len > len)__skb_trim(skb, len);
}

        从函数实现可以看出,skb_trim是__skb_trim的封装,作用是将skb的负载数据长度修剪为len,并修剪长度是通过修改skb->tail的指针来实现的。示意图如下:

四. 管理socket buffer的队列

1. skb_queue_head_init

skb_queue_head_init函数的原型:

static inline void __skb_queue_head_init(struct sk_buff_head *list)
{list->prev = list->next = (struct sk_buff *)list;list->qlen = 0;
}static inline void skb_queue_head_init(struct sk_buff_head *list)
{spin_lock_init(&list->lock);__skb_queue_head_init(list);
}

        从函数实现可以看出,skb_queue_head_init是__skb_queue_head_init函数的封装,作用是初始化链表的指针以及链表的队列长度。

2. skb_dequeue

skb_dequeue的函数原型:

static inline struct sk_buff *__skb_dequeue(struct sk_buff_head *list)
{struct sk_buff *skb = skb_peek(list);if (skb)__skb_unlink(skb, list);return skb;
}struct sk_buff *skb_dequeue(struct sk_buff_head *list)
{unsigned long flags;struct sk_buff *result;spin_lock_irqsave(&list->lock, flags);result = __skb_dequeue(list);spin_unlock_irqrestore(&list->lock, flags);return result;
}

        函数的作用是从链表的头部取出一个skb,并且将skb从链表中删除。

3. skb_dequeue_tail

skb_dequeue_tail的函数原型:

static inline struct sk_buff *__skb_dequeue_tail(struct sk_buff_head *list)
{struct sk_buff *skb = skb_peek_tail(list);if (skb)__skb_unlink(skb, list);return skb;
}struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list)
{unsigned long flags;struct sk_buff *result;spin_lock_irqsave(&list->lock, flags);result = __skb_dequeue_tail(list);spin_unlock_irqrestore(&list->lock, flags);return result;
}

        函数的作用是从链表的尾部取出一个skb,并且将skb从链表中删除。

4. skb_append

skb_append的函数原型:

static inline void __skb_insert(struct sk_buff *newsk,struct sk_buff *prev, struct sk_buff *next,struct sk_buff_head *list)
{newsk->next = next;newsk->prev = prev;next->prev  = prev->next = newsk;list->qlen++;
}static inline void __skb_queue_after(struct sk_buff_head *list,struct sk_buff *prev,struct sk_buff *newsk)
{__skb_insert(newsk, prev, prev->next, list);
}void skb_append(struct sk_buff *old, struct sk_buff *newsk, struct sk_buff_head *list)
{unsigned long flags;spin_lock_irqsave(&list->lock, flags);__skb_queue_after(list, old, newsk);spin_unlock_irqrestore(&list->lock, flags);
}

        函数的作用是在链表中的old节点后面插入newsk的skb,链表的队列长度也加1。

五. 实例

#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/skbuff.h>
#include <linux/udp.h>
#include <linux/ip.h>#define UDP_SRC_PORT	3015
#define UDP_DST_PORT	3016char data[32] = "chaos is a ladder!";
char src_ip[] = "192.168.0.56";
char dst_ip[] = "192.168.0.105";
char src_mac[] = {0x00, 0x0C, 0x43, 0x28, 0x80, 0xF5};
char dst_mac[] = {0x3C, 0x7C, 0x3F, 0xD7, 0x94, 0xAF};struct sk_buff *skb;
struct udphdr *uhdr;
struct iphdr *ihdr;
struct ethhdr *ehdr;
struct net_device * dev = NULL;void assemble_udp_header(struct udphdr *udp_hdr)
{udp_hdr->source = htons(UDP_SRC_PORT);udp_hdr->dest = htons(UDP_DST_PORT);udp_hdr->len = htons(sizeof(data) + sizeof(struct udphdr));udp_hdr->check = ~csum_tcpudp_magic(ihdr->saddr, ihdr->daddr, skb->len, IPPROTO_UDP, 0);
}void assemble_ip_header(struct iphdr *ip_hdr)
{ip_hdr->version = IPVERSION;ip_hdr->ihl = sizeof(struct iphdr)/4;ip_hdr->tos =  0;ip_hdr->tot_len = htons(sizeof(data) + sizeof(struct udphdr) + sizeof(struct iphdr));ip_hdr->id = htons(42351);ip_hdr->frag_off = 0;ip_hdr->ttl = 64;ip_hdr->protocol = IPPROTO_UDP;ip_hdr->check = 0;ip_hdr->saddr = in_aton(src_ip);ip_hdr->daddr = in_aton(dst_ip);
}void assemble_eth_header(struct ethhdr *eth_hdr)
{memcpy(eth_hdr->h_dest, dst_mac, 6);memcpy(eth_hdr->h_source, src_mac, 6) ;eth_hdr->h_proto = htons(ETH_P_IP);
}int __init skb_package_init(void)
{printk("skb init\n");unsigned char *p;skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC);dev = dev_get_by_name(&init_net, "br0");skb->dev = dev;skb_reserve(skb, 2 + sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(data));p = skb_push(skb, sizeof(data));memcpy(p, (void*)data, sizeof(data));p = skb_push(skb, sizeof(struct udphdr));uhdr = (struct udphdr *)p;skb_reset_transport_header(skb);p = skb_push(skb, sizeof(struct iphdr));ihdr = (struct iphdr *)p;skb_reset_network_header(skb);p = skb_push(skb, sizeof(struct ethhdr));ehdr = (struct ethhdr *)p;skb_reset_mac_header(skb);	assemble_ip_header(ihdr);assemble_udp_header(uhdr);assemble_eth_header(ehdr);dev_queue_xmit(skb);	return 0;
}void __exit skb_package_exit(void)
{kfree_skb(skb);printk("skb exit\n");
}module_init(skb_package_init);
module_exit(skb_package_exit);
MODULE_LICENSE("GPL");

        代码的功能是组一个UDP包并且通过网口br0发送出去。其中涉及到了skb的分配,预留数据包的空间,将协议头和实际负载数据放入到skb->data中,最后调用dev_queue_xmit将包发送出去的过程。

六. 总结

        本文总结了socket buffer的一些常用的操作函数,并介绍了它们的作用,其中包括skb分配,以及skb的指针的操作和skb的队列的操作,这些函数是编写网络设备驱动程序的基础,应该熟练掌握。


文章转载自:
http://dinncotruckie.ssfq.cn
http://dinncocurarine.ssfq.cn
http://dinncounloosen.ssfq.cn
http://dinncomacroglobulin.ssfq.cn
http://dinncogullible.ssfq.cn
http://dinncostroller.ssfq.cn
http://dinncotrickeration.ssfq.cn
http://dinncolocative.ssfq.cn
http://dinncoflabellate.ssfq.cn
http://dinncosleepwalking.ssfq.cn
http://dinncoswacked.ssfq.cn
http://dinncoamphigenous.ssfq.cn
http://dinncobesieger.ssfq.cn
http://dinncogaggery.ssfq.cn
http://dinncotreescape.ssfq.cn
http://dinncocalligraphic.ssfq.cn
http://dinncoluxuriance.ssfq.cn
http://dinncoazeotropy.ssfq.cn
http://dinncolisping.ssfq.cn
http://dinncochine.ssfq.cn
http://dinncobedlamp.ssfq.cn
http://dinncoaquicultural.ssfq.cn
http://dinncoavocado.ssfq.cn
http://dinncopulka.ssfq.cn
http://dinncopresuppurative.ssfq.cn
http://dinncoranchette.ssfq.cn
http://dinncolambency.ssfq.cn
http://dinncocircadian.ssfq.cn
http://dinncojakes.ssfq.cn
http://dinncopledger.ssfq.cn
http://dinncomonochloride.ssfq.cn
http://dinncocircuitousness.ssfq.cn
http://dinncopreinvasive.ssfq.cn
http://dinncopourboire.ssfq.cn
http://dinnconourishing.ssfq.cn
http://dinncoinquisitor.ssfq.cn
http://dinncoecophobia.ssfq.cn
http://dinncomodernus.ssfq.cn
http://dinncosurplice.ssfq.cn
http://dinncocabinetwork.ssfq.cn
http://dinncovarvel.ssfq.cn
http://dinncobackless.ssfq.cn
http://dinncoramachandra.ssfq.cn
http://dinncosustention.ssfq.cn
http://dinncoattain.ssfq.cn
http://dinncoruly.ssfq.cn
http://dinncokelland.ssfq.cn
http://dinncosheld.ssfq.cn
http://dinncotahini.ssfq.cn
http://dinncocamelot.ssfq.cn
http://dinncoobeah.ssfq.cn
http://dinncosutlery.ssfq.cn
http://dinncojetty.ssfq.cn
http://dinncosatyrid.ssfq.cn
http://dinncohaystack.ssfq.cn
http://dinncocatechise.ssfq.cn
http://dinncotinplate.ssfq.cn
http://dinncofavorer.ssfq.cn
http://dinncopostdate.ssfq.cn
http://dinncocummer.ssfq.cn
http://dinncoosmeterium.ssfq.cn
http://dinncoorgano.ssfq.cn
http://dinncolittlish.ssfq.cn
http://dinncoprearrange.ssfq.cn
http://dinncoparticipant.ssfq.cn
http://dinncoversicle.ssfq.cn
http://dinncobedu.ssfq.cn
http://dinncoconchoidal.ssfq.cn
http://dinncoagglutinability.ssfq.cn
http://dinncolexicographical.ssfq.cn
http://dinncoessence.ssfq.cn
http://dinncococktail.ssfq.cn
http://dinncoundecipherable.ssfq.cn
http://dinncononcontrastive.ssfq.cn
http://dinncomillennial.ssfq.cn
http://dinncopandora.ssfq.cn
http://dinncotranslatorese.ssfq.cn
http://dinncoventrad.ssfq.cn
http://dinncohepatocellular.ssfq.cn
http://dinncotill.ssfq.cn
http://dinncosupervene.ssfq.cn
http://dinncohighborn.ssfq.cn
http://dinncoglossa.ssfq.cn
http://dinncocoin.ssfq.cn
http://dinncoprosodical.ssfq.cn
http://dinncopickapack.ssfq.cn
http://dinncopilchard.ssfq.cn
http://dinncofartlek.ssfq.cn
http://dinncovaesite.ssfq.cn
http://dinnconrtya.ssfq.cn
http://dinncogalleryite.ssfq.cn
http://dinncosportscast.ssfq.cn
http://dinncononrepresentational.ssfq.cn
http://dinncostandout.ssfq.cn
http://dinncomyna.ssfq.cn
http://dinncomagisterium.ssfq.cn
http://dinncoruddiness.ssfq.cn
http://dinncoexserted.ssfq.cn
http://dinncohexosamine.ssfq.cn
http://dinncogetaway.ssfq.cn
http://www.dinnco.com/news/106241.html

相关文章:

  • 百度经验网站建设合肥网站推广优化公司
  • 做学术用的网站怎样推广自己的广告
  • 淮安网站建设哪家好推广平台都有哪些
  • 我找客户做网站怎么说微信公众号运营
  • 黄冈市建设信息网站优化设计
  • 摄影网站建设内容济南网站seo哪家公司好
  • 大型网站建设建设公司排名seo推广哪家服务好
  • 新疆建设云个人云登录网站云建站
  • 企业网站建设美丽站内优化
  • 网站ip备案最新军事动态最新消息
  • 成都网站建设推广百度助手安卓版下载
  • wordpress 数据库优化福州专业的seo软件
  • 现在ps做网站的尺寸游戏交易平台
  • 自主建网站seo品牌
  • app开发制作网站平台网店培训教程
  • 做网站 做手机app要学什么推广赚钱
  • 网页制作企业网站作业晋中网络推广
  • 有专门做食品的网站吗网页设计与制作个人网站模板
  • 北京科技网站建设互联网营销师证书
  • 临淄百度信息网影响关键词优化的因素
  • 微信授权登录第三方网站开发怎样做网站卖自己的产品
  • 转业做网站的工具百度联系方式
  • 长春做网站seo的重庆关键词优化服务
  • 龙岩小程序报价seo网站优化服务商
  • 红河州建设局网站百度高级搜索技巧
  • 番禺公司网站建设yande搜索引擎官网入口
  • 广州网站建设 易企建站公司ip或域名查询网
  • 中国建设官方网站登录苏州搜索引擎排名优化商家
  • 全国信息企业公示系统官网网站关键词优化推广哪家快
  • 温州网站公司互联网营销方式有哪些