博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
libpcap 与 “port 80”
阅读量:5245 次
发布时间:2019-06-14

本文共 2945 字,大约阅读时间需要 9 分钟。

代码调用:

char filter_exp[] = "port 80";

1 "port 80" 作为字符串 参与编译  pcap_compile(handle, &fp, filter_exp, 0, net)

  2 netmask = mask; // 全局变量网络淹码赋值

   bpf_pcap = handle; //内部的全局变量指针

   snaplen = snaplen_arg; // capture最大的报文长度

   in_buffer =filter_exp; // flex变量赋值,flex就是解析in_buffer的tokens,然后调用yacc(bison)的语法对应的规则

    3 init_linktype(linktype_arg);

     linktype =linktype_arg;  //全局变量,链路层是什么?

      off_linktype = 12; //上层协议的类型, 6(源mac)+6(目的mac)+(linktype 上层协议类型)

      off_nl = 14; //上层链路的偏移, 网络层开始 ip

   4 (void)pcap_parse(); // 调用yacc 解析过滤语法 yacc->lex(flex)返回token

    port 80 ==>根据 80 (是一个NUM) ==>id ==> gen_ncode

      调用一个生成数字的指令输出

      gen_ncode (根据$0 发先前面的修饰符是 port)

        ==> gen_port

          ==> gen_linktype(ETHERTYPE_IP)

             ==> gen_cmp(off_linktype, BPF_H, (bpf_int32)proto);

              ==> s = new_stmt(BPF_LD|BPF_ABS|BPF_H);  绝对位置加载指令

                    s->s.k = off_linktype;  加载的位子是12 以太王报文头的上层协议字段 加载两个字节

                       b = new_block(JMP(BPF_JEQ));

                     b->stmts = s;
                                              b->s.k = #800;

--------------------------------------------------------------------------------------------------------------------------------------

(000) ldh      [12]

(001) jeq      #0x800           jt 2    jf 23

--------------------------------------------------------------------------------------------------------------------------------------

...

流图

-------------------------------------------------------------------------------------------------------------------------------------

深入一下流程图 过滤表达式 “port 80”

root(pcap中的全局变量) <struct block 的结构指针>

root->id=0

root->stmts /* side effect stmts  不太理解 */  <struct slist 链表>

  $3 = { 链表

    s = { 节点数据
      code = 40,   // 对照指令集: 40=8进制的 50 最低3bit是 "000" 加载指令 接着2bit 是"01"==>BPF_H (即加载半字16bit) 再接着3bit"001" 标识加载的值是BPF_ABS  绝对位置, 整条指令就是 加载决定位置12的half-word(半字) 到累加器A (也就是把以太网链路的协议字段加载到累加器, 用于后续比较)
      jt = 0x0,
      jf = 0x0,
      k = 12
    },
    next = 0x0 链表指针 表示后面没有链表节点了
  }
root->s /* branch stmt */  <struct stmt>

  s = {

      code = 21,  //  =25 (其中5标识跳转指令 接着2bit是“10” =BPF_JEQ 相等则跳转,跳转到哪里,现在还没有确定,与哪个值比,k值2048(0x800)(ip协议)网络序) <struct block>其他字段指定位置 如果是0x800 跳转到et (edge true) 如果不相等 ef( edge false)
      jt = 0x0,
      jf = 0x0,
      k = 2048
    },
  进到root->et.succ->stmts

  $7 = {

    s = {
      code = 48, // 48= 8进制60 加载决定位置为23的一个字节到累加器 23位置的值是什么呢? 以太网头ip前有14个字节(ip头的协议字段)
      jt = 0x0,
      jf = 0x0,
      k = 23
    },
    next = 0x0
  }

     加载这个标志位之后对应的指令是

    root->et.succ.s

     $8 = {

    code = 21,  // 相等跳转指令
    jt = 0x0,
    jf = 0x0,
    k = 6 // TCP协议
  }

    如果不相等

  s = {

      code = 21,
      jt = 0x0,
      jf = 0x0,
      k = 17 // udp
    },

 

   如果有一个不相等

  s = {

      code = 6,  // 返回指令
      jt = 0x0,
      jf = 0x0,
      k = 0 // 返回值 0 标识忽略此包
   }

就这样就一个建立一个 cfg control flow graph

....这样的graph 是可以优化的...

icode_to_fcode 就是将这样的graph 转换为 bpf虚拟机识别的指令数组

 

-------------------------------------------------------------------------------------------------------------------------------------

program->bf_insns = icode_to_fcode(root, &len);

指令数组

 

 

      

  

  

转载于:https://www.cnblogs.com/kwingmei/p/3632064.html

你可能感兴趣的文章
codeforces水题100道 第二十二题 Codeforces Beta Round #89 (Div. 2) A. String Task (strings)
查看>>
c++||template
查看>>
[BZOJ 5323][Jxoi2018]游戏
查看>>
编程面试的10大算法概念汇总
查看>>
Vue
查看>>
python-三级菜单和购物车程序
查看>>
条件断点 符号断点
查看>>
水平垂直居中
查看>>
MySQL简介
查看>>
设计模式之桥接模式(Bridge)
查看>>
jquery的$(document).ready()和onload的加载顺序
查看>>
Python Web框架Django (五)
查看>>
.net学习之继承、里氏替换原则LSP、虚方法、多态、抽象类、Equals方法、接口、装箱拆箱、字符串------(转)...
查看>>
【codevs1033】 蚯蚓的游戏问题
查看>>
【程序执行原理】
查看>>
python的多行注释
查看>>
连接Oracle需要jar包和javadoc文档的下载
查看>>
UVA 10976 - Fractions Again?!
查看>>
Dreamweaver cc新版本css单行显示
查看>>
【android】安卓的权限提示及版本相关
查看>>