代码之家  ›  专栏  ›  技术社区  ›  Eli Bendersky

在数据库中存储数据包

  •  4
  • Eli Bendersky  · 技术社区  · 17 年前

    问题描述: 在我的应用程序中,我必须以某种格式显示数据包的内容。例如:

    一个例子

    以前,我做了一些自制的实现,将数据存储在一个二进制文件中(固定的记录长度允许快速查找),但随着时间的推移,我意识到我正在发明某种数据库。例如,我正在为非常大的数据文件实现自己的高效二进制存储格式。我还实现了自己的索引,以便在某些字段上快速运行搜索。我认为一个真正的DB(甚至是简单的SQLite)可以让这个东西变得非常简单。

    问题#1:

    问题#2:

    更高级的。。。现在假设数据包的长度和内容可以不同。也就是说,对于类型#2包,有一些字段,对于类型#3,有一些其他字段,依此类推。但我仍然希望我的应用程序能够处理它,很好地显示所有内容,并允许用户在配置文件中指定格式。怎么做的?

    提前谢谢。

    6 回复  |  直到 17 年前
        1
  •  1
  •   Community Mohan Dere    9 年前

    问题#1:DBs是否有助于 怎么办?

    当然,数据库对于这个应用程序很有用。您可以实现自己的专用数据存储,而且对于您的特定应用程序来说,它可能会更有效,因为您可以为这种专门化设计它。关系数据库更具通用性,但使用数据库可以避免数周或数月的开发时间。

    " product table, many kind of product, each product have many parameters

    Concrete Table Inheritance 设计

    他自己可以指定他的文件的格式 数据包,即在配置文件中: 每个字段的长度及其类型, 其值的含义(在 扩展数据库支持的实现 这

    我还将存储“分解”的数据包,这样数据包的每个字段都存储在单独的数据库列中。通过这种方式,您可以单独索引每一列,以支持高效搜索。

    NOT NULL )或其值受查找表约束。同样,利用数据库的功能使用元数据在需要的地方实施一致的结构。

    SQL已经支持一种标准的声明性语言,用于指定具有数据类型、约束等的字段。为什么要开发一种不同的语言,然后必须将其转换为SQL?

    问题3:更高级的。。。现在 长度和内容不同。

    给定数据包类型中可选的字段应允许 NULL 在相应的列中。

        2
  •  1
  •   Will Hartung    17 年前

    这就是说,如果您想从BLOB派生“元数据”,并对其进行索引,那么您也可以很容易地做到这一点。

    如果您的数据类型与数据库可以支持的数据类型一致(或者可以准确地转换),那么将BLOB分解为其组件部分(可以很好地映射到DB列)可能会有一些价值。

    如果数据定义是相当静态的,那么创建一个映射工具,允许用户描述BLOB,然后使用该定义创建一个兼容的表,并在导入期间适当地转换BLOB。

    至于“不同类型的不同行”,您仍然可以将数据填充到单个表中。与其他行相比,某些行具有“未使用”的列,每一行都按类型标识。如果您有很多行定义和大量差异,那么这样做会浪费大量空间。然后,您可能希望为每种行类型创建一个表,并创建一个主表,用于保存行类型和对实际表中实际行的引用。如果您关心原始数据包之间的关系,那么您只需要这个主表(然后您可以将它们存储在收据顺序中,例如,等等)。

        3
  •  1
  •   joev    17 年前

    你可能想考虑的另一个选择是 Berkeley DB

        4
  •  1
  •   Adam Robinson    17 年前

    尽管事实上你说没有一对多的关系,但有:)

    我建议为数据包存储创建两个表。一个用来存储“头”或“标量”信息的方法,这是数据包的公共信息,虽然它可以定义存在什么数据,但它不是数据包中存储的实际数据。

    create table packet
    (
        packet_id int identity(1, 1) primary key,
        destination varchar(50),
        sender varchar(50),
        packet_type_id int not null
    )
    
    create table packet_field
    (
        packet_field_id int identity(1, 1) primary key,
        packet_id int not null references packet (packet_id),
        field_id int not null,
        data varbinary(500)
    )
    

    显然,这两个表对所存储的数据的类型和大小做出了假设,并且没有详尽地说明它们需要存储什么。然而,这个基本结构将允许动态定义的数据包格式,并且是一个易于索引的模式(例如,在 packet_id+field_id 在里面 packet_field

    然后,您的应用程序所要负责的就是解包并将其存储在此模式中的数据库中,然后重新打包(如有必要)。

    当然,从这一点开始,您将需要存储数据包实际格式的表。类似于。。。

    create table packet_type
    (
        packet_type_id int identity(1, 1) primary key,
        name varchar(200) not null
    )
    
    create table packet_type_field
    (
        field_id int identity(1, 1) primary key,
        packet_type_id int not null references packet_type (packet_type_id)
        field_offset int not null,
        name varchar(200) not null
    )
    

    packet_type 表中的每种数据包格式和一行 packet_type_field 对于给定数据包中的每个字段。这将为您提供将任意二进制数据块处理到上述数据包存储模式所需的大部分信息。

        5
  •  1
  •   user418427    16 年前

    我想到了三种方法。

    另一个更有针对性的方法是编写非常简单的snort规则,如源地址或目标地址。然后让snort捕获数据包的有效负载。这样,您只能获得所需的实际数据。例如,您可以只获取数据包中的数据字段。e、 g.密码等。

    ngrep还可以直接从网络上获取选择性数据。

    当然,如果您不是在服务器/工作站本身上进行捕获,则每个端口都可能需要一个tap或monitor会话。

        6
  •  0
  •   SqlRyan    17 年前

    1. 具有列定义的表-称之为tblColumnDefs。此表包含“名称”、“类型”、“长度”和“说明”等列
    2. 实例主表(tblPacketNames)。本质上,对于您定义的每个数据包类型,只需“PacketTypeID”、“PacketName”和“Description”
    3. 实例定义表(对于您来说,这将是TBLPacktColumns)。此表将预定义的列收集在一起,形成要存储的数据结构。例如,它可能包含“PacketTypeID”、“ColumnNumber”、“ColumnID”。在数据库规范化中,这是一个多对多表,因为它将列映射到使用它们的数据包。

    注意:我并不特别喜欢步骤4的SQL注入含义。如果安全性设计不正确,并且应用程序中任何用户输入字段的输入未正确清理,则动态创建表可能会导致一些后果,特别是如果此应用程序具有可供不受信任的调用方(即Internet)使用的接口。

    使用此功能,您可以在创建表时创建任何您想要的索引(可能在步骤1中有一列,您将某些列标记为“可索引”,并且在创建表时在这些列的顶部创建索引)。