我的代码有问题。我的全局变量没有改变。我已将其地址分配给一个指针。这是我的结构初始化:
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 node\n");
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 bytes\n", 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
声明为局部变量,而不是当前看起来的全局变量。
关于使用指针更改全局变量值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21014837/