zoukankan      html  css  js  c++  java
  • 自定义IP协议

    1.         自定义包格式 ”Custom_IP”

      

     

    在节点编辑器的 Interfaces 菜单中选择 Model Attribute,添加节点属性“ Addr_IP”,它
    是 string 型的属性,标记节点的 IP 地址,格式为"xxx.xxx.xxx.xxx"

    2.         IP包的创建和高层数据包的封装

    Packet* ip_pkptr, ip_pkptr_tmp;
    char addr_ip[32];
    unsigned long int src_ip_addr,dest_ip_addr;
    
    //创建自定义格式的IP包
    ip_pkptr = op_pk_create_fmt("Custom_IP");
    //得到本节点的IP地址
    op_ima_obj_attr_get(op_id_self(),"Addr_IP",addr_ip);
    /*将字符串型的 IP 地址转成整型 IP 地址,这样符合标准 IP 协议的 
      IP 地址读写规范*/
    src_ip_addr = prg_ip_address_string_to_value(addr_ip);
    //设置IP源地址,IP样本包制作完成
    op_pk_nfd_set(ip_pkptr,"Source address",src_ip_addr);
    //得到高层数据包
    app_layer_pkptr = op_pk_get(op_intrpt_strm());
    //拷贝样本包
    ip_pkptr_tmp = op_pk_copy(ip_pkptr);
    //设置IP目的地址
    op_pk_nfd_set(ip_pkptr_tmp,"Destination address",dest_ip_addr);
    //封装高层数据包
    op_pk_nfd_set(ip_pkptr_tmp,"Extended packet",app_layer_pkptr);
    //最后将创建好的IP包发往低层
    op_pk_send(ip_pkptr,IP_LAYER_OUT_STRM);

    3.    IP 路由表初始化

      

    struct route{
        unsigned long int netprefix;
        int MAC_addr;
        struct route *nextunit;
    }
    
    //定义状态变量 route_table_ptr
    struct route *route_table_ptr;
    //路由表初始化所必需的变量
    struct route *table_item1 = route_table_ptr;
    struct route *table_item2;
    //路由发现所必需的变量
    Objid self_if;
    Objid IP_rte_id;
    Objid xmt_id;
    Objid remote_rcv_id;
    Objid remote_node_id;
    //IP 地址读取所必需的变量
    char addr_ip[32];
    unsigned long int addr;
    
    //初始化路由表,这里我们假设与路由器有线相连的节点为 2 个
    table_item1->nextunit = table_item1 + 1 ;
    table_item2 = table_item1->nextunit ;
    table_item2->nextunit = NULL ;

    接下来我们要根据每个有线发射机的连接关系自适应地查找到与之相连节点的 IP地址前缀

    首先查找与名称为"xmt0"有线发信机相连节点 Objid。

    //得到进程模块 Objid
    self_id = op_id_self ();
    //得到路由器节点 Objid
    IP_rte_id = op_topo_parent (self_id);
    //得到名称为"xmt0"有线发信机的 Objid
    xmt_id = op_id_from_name(IP_rte_id,OPC_OBJTYPE_PTTX, "xmt0");
    //得到与"xmt0"相连的有线收信机的 Objid
    remote_rcv_id = op_topo_assoc
        (xmt_id, OPC_TOPO_ASSOC_OUT, OPC_OBJMTYPE_RECV, 0);
    //得到与"xmt0"相连节点的 Objid
    remote_node_id = op_topo_parent(remote_rcv_id);

    接下来就可以根据这个 remote_node_id 得到其 IP 地址信息,我们假设节点 IP 信息已经存在节点的"Addr_IP"属性中。

    //得到节点的 IP 地址
    op_ima_obj_attr_get(remote_node_id, "Addr_IP" , addr_ip);
    //得到节点的名称
    op_ima_obj_attr_get(remote_node_id,"name",node_name);
    //将字符串型的 IP 地址转换成长整型以便存储
    addr=prg_ip_address_string_to_value(addr_ip);
    if (op_prg_odb_ltrace_active("ip_discover")==OPC_TRUE)
    {
        printf("IP address of Node %s is %s
    ",name,addr_ip);
    }

    最后将 IP 地址前缀以及与"xmt0"相对应的流索引号写入链表元素 table_item1 中

    //将 addr 以二进制的方式向右偏移 8 位,取得 IP 地址前缀,
    //它由 IP 地址前面三个字段组成
    addr=(addr)>>8;
    table_item1->netprefix = addr;
    table_item1->MAC_addr = XMT0_STRM_INDEX;

     

    4.     路由表的查找

    当路由器收到 IP 包时,必须根据其目的IP 地址前缀查找路由表,从而将其路由至相应的子网。

    Packet* pkptr;
    unsigned long int dest_ip_addr;
    int MAC_addr;
    
    //得到 IP 包
    pkptr = op_pk_get ( op_intrpt_strm() );
    //获取 IP 包的目的地址
    op_pk_nfd_get (pkptr,"Destination address",&dest_ip_addr);
    /*for debug*/
    addr_ip = str;
    prg_ip_address_value_to_string(dst_ip_addr,addr_ip);
    //得到 IP 地址前缀
    net_prefix = ( dest_ip_addr ) >> 8 ;
    
    //假设路由表的大小 RTE_TABLE_SIZE,搜索路由表找到与 IP 地址前缀对应的物理地址
    for ( i = 0 ; i <= RTE_TABLE_SIZE - 1 ; i++ )
    {
        if ( route_table_ptr->netprefix == net_prefix )
        {
            MAC_addr = route_table_ptr->MAC_addr ;
            break ;
        }
        route_table_ptr = route_table_ptr->nextunit ;
    }
    //将 IP 包发送至下一跳节点
    op_pk_send (pkptr, MAC_addr) ;

     

     

     

  • 相关阅读:
    IIS配置桌面上的文件报错,可能是含有中文字符
    GridView序号
    图片处理函数(自适应缩略图datatable中添加缩略图像)
    linqtoobject
    数据库存取图片二进制数据
    反射
    jquery
    加干扰字符
    Doc的窗口就创建一个,如果已经存在就激活那个窗口,不存在就建立Doc(转自CSDN)
    VC++中使用内存映射文件处理大文件(转)
  • 原文地址:https://www.cnblogs.com/liwei33/p/7344441.html
Copyright © 2011-2022 走看看