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

南充网站建设与维护做网站js框架

南充网站建设与维护,做网站js框架,做网站设计工作的报告,企业网站框架一、用户空间 以Linux以及TPACKET_V3为例。 调用pcap_dispatch获取数据包#xff0c;然后回调用户传递的数据包处理函数。 read_op实际调用的是pcap_read_linux_mmap_v3 // pcap.c int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {return (p-…一、用户空间 以Linux以及TPACKET_V3为例。 调用pcap_dispatch获取数据包然后回调用户传递的数据包处理函数。 read_op实际调用的是pcap_read_linux_mmap_v3 // pcap.c int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) {return (p-read_op(p, cnt, callback, user)); }1.1 获取block 1.1.1 根据offset获取一个block #define RING_GET_FRAME_AT(h, offset) (((union thdr **)h-buffer)[(offset)]) #define RING_GET_CURRENT_FRAME(h) RING_GET_FRAME_AT(h, h-offset)h.raw RING_GET_CURRENT_FRAME(handle);1.1.2 判断当前block的状态 根据block_status值判断block的实际状态主要关注两个值 TP_STATUS_KERNEL - block正在内核使用用户不能使用 TP_STATUS_USER - block已经由内核填充了数据用户可以读取内核不能使用 if (h.h3-hdr.bh1.block_status TP_STATUS_KERNEL) {... }1.2 读取/处理数据 如果当前block的status为TP_STATUS_USER则开始读取数据 ...//偏移到实际的数据包部分 handlep-current_packet h.raw h.h3-hdr.bh1.offset_to_first_pkt; //当前block中数据包的个数 handlep-packets_left h.h3-hdr.bh1.num_pkts;while (packets_to_read-- !handle-break_loop) {struct tpacket3_hdr* tp3_hdr (struct tpacket3_hdr*) handlep-current_packet;ret pcap_handle_packet_mmap(handle,callback,user,handlep-current_packet,tp3_hdr-tp_len,tp3_hdr-tp_mac,tp3_hdr-tp_snaplen,tp3_hdr-tp_sec,handle-opt.tstamp_precision PCAP_TSTAMP_PRECISION_NANO ? tp3_hdr-tp_nsec : tp3_hdr-tp_nsec / 1000,VLAN_VALID(tp3_hdr, tp3_hdr-hv1),tp3_hdr-hv1.tp_vlan_tci,VLAN_TPID(tp3_hdr, tp3_hdr-hv1));...//移动到下一个包handlep-current_packet tp3_hdr-tp_next_offset;handlep-packets_left--; } ...回调用户处理函数 /* handle a single memory mapped packet */ static int pcap_handle_packet_mmap(pcap_t *handle,pcap_handler callback,u_char *user,unsigned char *frame,unsigned int tp_len,unsigned int tp_mac,unsigned int tp_snaplen,unsigned int tp_sec,unsigned int tp_usec,int tp_vlan_tci_valid,__u16 tp_vlan_tci,__u16 tp_vlan_tpid) {.../* pass the packet to the user */callback(user, pcaphdr, bp);return 1; }1.3 释放当前block 当前block的数据包处理完成后需要将当前block归还给内核让内核可以继续写数据只是将状态值设置为TP_STATUS_KERNEL即可。 if (handlep-packets_left 0) {h.h3-hdr.bh1.block_status TP_STATUS_KERNEL;.../* next block */if (handle-offset handle-cc)handle-offset 0;handlep-current_packet NULL; }1.4 等待数据 因为block是一个循环队列,只要当前block的状态是TP_STATUS_KERNEL则说明后面都没有数据只能等待。 libpcap通过poll进行数据的等待其中fd则是最开始创建的socket。 if (h.h3-hdr.bh1.block_status TP_STATUS_KERNEL) {ret pcap_wait_for_frames_mmap(handle);if (ret) {return ret;} }static int pcap_wait_for_frames_mmap(pcap_t *handle) {struct pcap_linux *handlep handle-priv;...struct pollfd pollinfo;int ret;pollinfo.fd handle-fd;pollinfo.events POLLIN;do {ret poll(pollinfo, 1, handlep-poll_timeout);...} while (ret 0);1.4.1 阻塞模式 默认是阻塞模式并且TPACKET3下超时为-1永不超时, 当没有流量时将不会被唤醒。 static void set_poll_timeout(struct pcap_linux *handlep) { ...if (handlep-tp_version TPACKET_V3 !broken_tpacket_v3)handlep-poll_timeout -1; /* block forever, let TPACKET_V3 wake us up */else... }如何提前唤醒 在 libpcap-1.10.4之前无法提前唤醒只能等待数据的到来在新版本中增加了一个fd专门用来提前唤醒。 https://github.com/the-tcpdump-group/libpcap/pull/741/commits/5c8b13d3e87542527ed9a3a79fb0f9b2edb74df1 在创建handle时同时创建了poll_breakloop_fd pcap_t * pcap_create_interface(const char *device, char *ebuf) {pcap_t *handle;handle PCAP_CREATE_COMMON(ebuf, struct pcap_linux);if (handle NULL)return NULL;...struct pcap_linux *handlep handle-priv;handlep-poll_breakloop_fd eventfd(0, EFD_NONBLOCK);return handle; }激活handle时设置对应的break_loop callback static int pcap_activate_linux(pcap_t *handle)...handle-breakloop_op pcap_breakloop_linux;... }poll时将poll_breakloop_fd也监听 static int pcap_wait_for_frames_mmap(pcap_t *handle) {struct pcap_linux *handlep handle-priv;...struct pollfd pollinfo[2];int numpollinfo;pollinfo[0].fd handle-fd;pollinfo[0].events POLLIN;...pollinfo[1].fd handlep-poll_breakloop_fd;pollinfo[1].events POLLIN;numpollinfo 2;...调用pcap_breakloop通知唤醒 void pcap_breakloop(pcap_t *p) {p-breakloop_op(p); }static void pcap_breakloop_linux(pcap_t *handle) {pcap_breakloop_common(handle);struct pcap_linux *handlep handle-priv;uint64_t value 1;/* XXX - what if this fails? */if (handlep-poll_breakloop_fd ! -1)(void)write(handlep-poll_breakloop_fd, value, sizeof(value)); }poll被poll_breakloop_fd唤醒 if (pollinfo[1].revents POLLIN) {ssize_t nread;uint64_t value;nread read(handlep-poll_breakloop_fd, value,sizeof(value));...if (handle-break_loop) {handle-break_loop 0;return PCAP_ERROR_BREAK;} }1.4.2 非阻塞模式 没有数据时立刻返回,通过如下API进行设置 int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)二、内核空间 内核在接收到数据包时将调用相应的处理函数进行处理 __netif_receive_skb_core()deliver_skb()static inline int deliver_skb(struct sk_buff *skb,struct packet_type *pt_prev,struct net_device *orig_dev) {...return pt_prev-func(skb, skb-dev, pt_prev, orig_dev); }而pt_prev-func实际为在设置rx ring时设置的函数tpacket_rcv 2.1 判断是否有可用空间 如果没有空间了则当前数据包被丢弃。 /* If we are flooded, just give up */if (__packet_rcv_has_room(po, skb) ROOM_NONE) {atomic_inc(po-tp_drops);goto drop_n_restore;}2.2 获取一个可用的block h.raw packet_current_rx_frame(po, skb,TP_STATUS_KERNEL, (macoffsnaplen));2.3 拷贝数据到block中 skb_copy_bits(skb, 0, h.raw macoff, snaplen);2.4 更新block属性 switch (po-tp_version) {...case TPACKET_V3:h.h3-tp_status | status;h.h3-tp_len skb-len;h.h3-tp_snaplen snaplen;h.h3-tp_mac macoff;h.h3-tp_net netoff;h.h3-tp_sec ts.tv_sec;h.h3-tp_nsec ts.tv_nsec;memset(h.h3-tp_padding, 0, sizeof(h.h3-tp_padding));hdrlen sizeof(*h.h3);break;default:BUG();}2.5 何时更新block状态 1. 当block写满时 在获取每次获取block时将判断当前block是否有足够的空间写入当前的数据包 static void *packet_current_rx_frame(struct packet_sock *po,struct sk_buff *skb,int status, unsigned int len) {char *curr NULL;switch (po-tp_version) {...case TPACKET_V3:return __packet_lookup_frame_in_block(po, skb, len);...} } static void *__packet_lookup_frame_in_block(struct packet_sock *po,struct sk_buff *skb,unsigned int len) {.../* 空间足够直接返回 */if (currTOTAL_PKT_LEN_INCL_ALIGN(len) end) {prb_fill_curr_block(curr, pkc, pbd, len);return (void *)curr;} 空间不足时将当前block 关闭即将状态设置为TP_STATUS_USER并通知socket fd有数据, 用户空间的poll则会被唤醒。 /* Ok, close the current block */prb_retire_current_block(pkc, po, 0);static void prb_retire_current_block(struct tpacket_kbdq_core *pkc,struct packet_sock *po, unsigned int status) {...prb_close_block(pkc, pbd, po, status);... }static void prb_close_block(struct tpacket_kbdq_core *pkc1,struct tpacket_block_desc *pbd1,struct packet_sock *po, unsigned int stat) {__u32 status TP_STATUS_USER | stat; .../* Flush the block */prb_flush_block(pkc1, pbd1, status);//通知socket 有数据poll将被唤醒sk-sk_data_ready(sk);pkc1-kactive_blk_num GET_NEXT_PRB_BLK_NUM(pkc1); }static void prb_flush_block(struct tpacket_kbdq_core *pkc1,struct tpacket_block_desc *pbd1, __u32 status) {/* Now update the block status. */BLOCK_STATUS(pbd1) status; }2. 当block超时时 当流量很小时block一直都不会被写满因此数据一直停留在block中上层应用无法获取数据因此增加了一个timer. 在建立ring buf时初始化timer并设置超时处理函数 static void init_prb_bdqc(struct packet_sock *po,struct packet_ring_buffer *rb,struct pgv *pg_vec,union tpacket_req_u *req_u) {...prb_setup_retire_blk_timer(po);... }static void prb_setup_retire_blk_timer(struct packet_sock *po) {struct tpacket_kbdq_core *pkc;pkc GET_PBDQC_FROM_RB(po-rx_ring);timer_setup(pkc-retire_blk_timer, prb_retire_rx_blk_timer_expired,0);pkc-retire_blk_timer.expires jiffies; }timer超时调用回调函数关闭当前block static void prb_retire_rx_blk_timer_expired(struct timer_list *t) {...if (pkc-last_kactive_blk_num pkc-kactive_blk_num) {...prb_retire_current_block(pkc, po, TP_STATUS_BLK_TMO);... } ... }
http://www.zqtcl.cn/news/322035/

相关文章:

  • 网站建设上动漫制作教学
  • 怎么用cms做网站计算机网络技术专业
  • 建设部颁发的证书网站请问注册公司怎么注册
  • 网站开发php和c语言区别网站开发教程大全
  • 建设银行通控件网站谷歌推广
  • 我要建网站需要什么付费wordpress
  • 网站收录查询情况wordpress主题仿
  • 网站单页生成器c 网站开发需要学什么
  • 什么网站是免费的免费图片链接生成器
  • 网站建设伍金手指下拉9服务器多少钱
  • 手机网站大全网站收费网站推广
  • 华企立方做网站自己动手做导航网站
  • 如何建设教师网上授课网站重庆建设网站哪家专业
  • 企业网站页头背景图建设三轮摩托车官网
  • 直播网站创做上海idc机房托管
  • 受欢迎自适应网站建设地址c2c二手车交易平台
  • 做个平台网站怎么做房价查询
  • 自学网站建设最快要多久asp.net 手机网站开发
  • 淮安做网站找哪家公司verycloud wordpress
  • 无法连接到wordpress站点网站建设的 几点
  • 网站免费空间购买wordpress支持页面模版
  • 腾讯建设网站视频宁波城乡住房建设厅网站
  • 乐清网站开发公司个人网站建设工作室
  • 网站空间升级通知手机端怎么看世界杯
  • 广西南宁网站推广建设网站视频教程
  • 福州专业网站建设推广费用nas可做网站服务器吗
  • 齐鲁建设网站福建省高速公路建设管理网站
  • 比格设计网站官网收录网站查询
  • 国外做直播网站淘宝电商网站怎么做的
  • 国外私人网站网站由那些组成