我的代码有问题。我的全局变量没有改变。我把它的地址分配给了一个指针。这是我的结构初始化:
struct PortData {
int port;
int sent;
int received;
int total;
struct PortData *Next;
};
struct IPData {
time_t timestamp;
uint32_t ip;
struct PortData Record;
};
这是我返回地址的函数:
inline struct IPData *FindIp(uint32_t ipaddr) {
unsigned int counter;
for (counter = 0; counter < IpCount; counter++)
if (IpTable[counter].ip == ipaddr)
return (&IpTable[counter]);
if (IpCount >= IP_NUM) {
syslog(LOG_ERR, "IP_NUM is too low, dropping ip....");
return (NULL);
}
memset(&IpTable[IpCount], 0, sizeof (struct IPData));
IpTable[IpCount].ip = ipaddr;
return (&IpTable[IpCount++]);
}
并且这里,分配给IpTable
:的地址的指针
struct IPData *ptrIPData;
for (Count = 0; Count < SubnetCount; Count++) {
if (SubnetTable[Count].ip == (iph->saddr & SubnetTable[Count].mask)) {
ptrIPData = FindIp(iph->saddr);
Credit(&(ptrIPData->Record), iph, tcph, srcip);
}
if (SubnetTable[Count].ip == (iph->daddr & SubnetTable[Count].mask)) {
ptrIPData = FindIp(iph->daddr);
Credit(&(ptrIPData->Record), iph, tcph, dstip);
}
}
这是我的Credit()函数:
inline void Credit(struct PortData *pordt, struct iphdr *iph, struct tcphdr *tcph, struct in_addr sipaddr) {
unsigned int sport, dport;
memset(&source, 0, sizeof (source));
source.sin_addr.s_addr = iph->saddr; //init source ip
sport = ntohs(tcph->source);
memset(&dest, 0, sizeof (dest));
dest.sin_addr.s_addr = iph->daddr; //init dest ip
dport = ntohs(tcph->dest);
packet_size = ntohs(iph->tot_len);
if (iph->protocol == 6) //6 is protocol TCP
{
prev = portdt;
int sameport = 0;
while (prev != NULL) {
if (dport == prev->port || sport == prev->port) {
if (dport == prev->port) {
prev->sent += packet_size;
}
if (sport == prev->port) {
prev->received += packet_size;
}
sameport = 1;
break;
}
}
if (sameport == 0) {
printf("create new noden");
newnode = (struct PortData*) malloc(sizeof (struct PortData));
newnode->received = 0;
newnode->sent = 0;
if (sipaddr.s_addr == source.sin_addr.s_addr) {
if (tcph->syn == 1 || tcph->ack == 1) {
newnode->port = dport;
newnode->sent = packet_size;
}
}
if (sipaddr.s_addr == dest.sin_addr.s_addr) {
if (tcph->syn == 1 && tcph->ack == 1) {
newnode->port = sport;
newnode->received = packet_size;
}
}
newnode->Next = portdt;
portdt = newnode;
}//==end-sameport==
}//iph->protocol//
prev = portdt;
while (prev != NULL) {
fprintf(logfile, "ip = %s port=%d sent=%d bytes received=%d bytesn", inet_ntoa(sipaddr), prev->port, prev->sent, prev->received);
prev = prev->Next;
}
}
我假设在执行Credit()
函数后,Iptable[Counter].Record
的值必须更改,因为ptrIPData
指向它的地址。但为什么没有呢?
您正试图将一个新项目插入到链表Record
中。你试图通过写:来做到这一点
newnode = (struct PortData*) malloc(sizeof (struct PortData));
// initialise newnode
newnode->Next = portdt;
portdt = newnode;
问题是portdt
是局部变量,它包含IPData
结构的Record
成员的地址。因此,分配给局部变量portdt
不会实现函数外可见的任何内容。
你需要做一些改变。首先,您需要将struct PortData Record
更改为struct PortData *Record
。这是列表的头指针,它必须声明为指向节点的指针,而不是像您作为节点值所做的那样。
然后仍然将&Record
传递给Credit
,但现在portdt
的类型是struct PortData **Record
。因此,节点插入分配变为
newnode = malloc(sizeof (struct PortData));
// initialise newnode
newnode->Next = *portdt;
*portdt = newnode;
您的代码还有其他问题。我不打算尝试将它们全部列出,但以下是我所看到的:
- 不要强制转换
malloc
的返回值 - 您应该检查
malloc
的返回值是否存在错误 - 将
prev
声明为局部变量,而不是当前显示的全局变量
您应该将行替换为:而不是portdt = newnode;
portdt->port = newnode->port;
portdt->sent = newnode->sent;
portdt->received = newnode->received;
portdt->total = newnode->total;
portdt->Next = newnode->Next;
就像@David说的,portdt = newnode;
只是改变局部变量,而不是改变portdt
所指向的东西。