Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays C中将结构复制到结构数组的正确方法_Arrays_C_Struct_Tcp_Libpcap - Fatal编程技术网

Arrays C中将结构复制到结构数组的正确方法

Arrays C中将结构复制到结构数组的正确方法,arrays,c,struct,tcp,libpcap,Arrays,C,Struct,Tcp,Libpcap,我想使用C中的libpcap库检查TCP数据包的重传。根据我的研究,推断数据包是否为重传的唯一方法是,我需要访问以前的流量行为,因为一个数据包不足以得出这个结论 因此,我解决问题的方法如下: 这是一个MRE,它读取pcap文件并分析IPv4上的任何TCP数据包(如果发现) #包括 #包括 #包括 #包括 #包括 #包括 #包括 无效进程数据包(u_char*,常量结构pcap_pkthdr*,常量u_char*); 无效查找重新传输(常量字符*,int); int main() { pcap_t

我想使用C中的libpcap库检查TCP数据包的重传。根据我的研究,推断数据包是否为重传的唯一方法是,我需要访问以前的流量行为,因为一个数据包不足以得出这个结论

因此,我解决问题的方法如下:

这是一个MRE,它读取pcap文件并分析IPv4上的任何TCP数据包(如果发现)

#包括
#包括
#包括
#包括
#包括
#包括
#包括
无效进程数据包(u_char*,常量结构pcap_pkthdr*,常量u_char*);
无效查找重新传输(常量字符*,int);
int main()
{
pcap_t*手柄;
字符errbuff[PCAP_ERRBUF_SIZE];
handle=pcap\u open\u offline(“smallFlows.pcap”,errbuff);
pcap_循环(句柄,-1,进程_数据包,NULL);
}
无效进程\数据包(u\字符*参数,常量结构pcap\ u pkthdr*头,常量u\字符*缓冲区)
{
int size=标题->长度;
结构ethhdr*eth=(结构ethhdr*)缓冲区;
if(eth->h_proto==8)//检查IPv4
{
结构iphdr*iph=(结构iphdr*)(缓冲区+sizeof(结构ethhdr));
if(iph->protocol==6)//检查TCP
{
查找_重传(缓冲区、大小);
}
}
}
find_retransmissions
函数中,我创建了两个任意长度的结构的静态数组,以存储以前捕获的数据包头,并使用它们查找可能的重新传输

void find_重传(const u_char*Buffer,int Size)
{
静态结构iphdr*以前的_数据包[20000];
静态结构tcphdr*先前的_tcp[20000];
静态int指数=0;
int重传=0;
无符号短iphdrlen;
结构iphdr*iph=(结构iphdr*)(缓冲区+sizeof(结构ethhdr));
先前的_数据包[索引]=malloc(sizeof(struct iphdr));
*以前的_数据包[索引]=*iph;
iphdrlen=iph->ihl*4;
结构tcphdr*tcph=(结构tcphdr*)(缓冲区+iphdrlen+sizeof(结构ethhdr));
先前的_tcp[index]=malloc(sizeof(struct tcphdr));
*以前的_tcp[索引]=*tcph;
索引++;
对于(inti=0;isaddr==iph->saddr)和&(以前的数据包[i]->daddr==iph->daddr)
&&(以前的_数据包[i]->protocol==iph->protocol))
{
如果((先前的\u tcp[i]->source==tcph->source)和&(先前的\u tcp[i]->dest==tcph->dest)
&&(先前的\u tcp[i]->th_seq==tcph->th_seq))
{
重传=1;
打破
}
}
}
if(重传==1)
{
printf(“重传:真”);
}
}
发现使用名为“smallFlows.pcap”的pcap文件

我很确定这种方法在做类似的事情时不仅仅是次优的,而且我也愿意接受关于如何实现这一点的新建议。正如我从调试中了解到的那样,我的代码目前存在的问题是,
*previous_packets[index]=*iph
*先前的\u tcp[索引]=*tcph
我的“深层”结构复制方法失败了,我认为源结构分别覆盖了
previous_数据包
previous_tcp
数组的所有元素。因此,我的实际问题是,如何将找到的数据包头结构可靠地复制到这些数组中?我尝试了更多的方法来处理我在SO中找到的深层结构副本,但都没有用


特定的pcap包含大约120个TCP重传(通过wireshark检查)。

在评论中解决此问题:
“可以在c中动态分配数组”

由于我没有确切的结构定义,让我使用您描述的近似值来说明如何“可以在c中动态分配数组”,从而提供“结构数组,而不是带有指向结构指针的数组”。我所演示的方法实际上不是数组本身,但在概念上是相同的。它实际上是一个分配的连续内存段,在本例中专用于
20000
您的
struct
实例

我将在这些示例中介绍
typedef
,但这是您可以选择使用或不使用的选项,它不是一个要求

举个例子:

//following defines typedef of struct that can be used to create single instances or pointer instances that can be dynamically allocated to whatever size you need


typedef struct {
  ...
} iphdr_s; 
例如,现在您可以更改此行:

static struct iphdr * previous_packets[20000];
为此:

static iphdr_s *iphdr = malloc(20000*sizeof(*iphdr));
if(!iphdr)
{
    //handle error 
}
当某个时候不再需要
iphdr
时,只需释放它:

free(iphdr);
如果对这一改编有任何疑问,请评论我

编辑
在评论中提出有关使用普通
struct
array和动态分配的数组指针以及将两种类型的元素从一个复制到另一个的问题:

以下是一个简单的演示:

typedef struct {
    int val;
} array_s;

int main()//-7,8,6,88,2,-7,10,-5
{
    
    array_s arr1[] = {1,2,3,4};//normal array
    array_s *arr2 = malloc(10*sizeof(*arr2));//pointer to allocated memory
    if(arr2)
    {
        for(int i=0;i<10;i++)
        {
            arr2[i].val = i+1;
        }
        arr1[3] = arr2[7];//copy element from allocated to normal array
    }
    array_s *arr3 = malloc(10*sizeof(*arr3));
    if(arr3)
    {
        arr3[0] = arr2[7];//copy element from allocated to allocated array           
    }
    
    printf("%d\n", arr1[3].val);
    printf("%d\n", arr3[0].val);
    

    return 0;
}
typedef结构{
int-val;
}数组_s;
int main()/-7,8,6,88,2,-7,10,-5
{
数组_s arr1[]={1,2,3,4};//正规数组
array_s*arr2=malloc(10*sizeof(*arr2));//指向已分配内存的指针
如果(arr2)
{

对于(int i=0;我不明白您是否正在复制数据,并且您似乎知道(或设置)一个上限,为什么你会有一个指针数组和mallocing数据,而你可以有一个结构数组。另外,一个想法是让缓冲区循环。我设置的上限是任意的,并且与pcap大小一致,因为我不知道如何或者甚至是否可以在c中动态分配数组。你知道什么假设我可以有一个结构数组,而不是一个带指向结构指针的数组?是的。上限不会改变是否为nx T*或nx T分配了数据。因此,只需使用
static struct iphdr previous_packets[MAX_packets]
static struct tcphdr previous_tcp[MAX_packets]
。然后您可以简单地复制数据:
previous_packets[index]=*iph
。其他数据也一样,避免所有这些
malloc
无意义。但是,如果您有效地