我的代码有问题。我的全局变量没有改变。我已将其地址分配给指针。这是我的struct初始化:
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
指向了它的地址。但为什么不呢?
答案 0 :(得分:2)
您正尝试在链接列表Record
中插入新项目。您尝试通过编写:
newnode = (struct PortData*) malloc(sizeof (struct PortData));
// initialise newnode
newnode->Next = portdt;
portdt = newnode;
问题是portdt
是局部变量,它包含Record
结构的IPData
成员的地址。因此,分配给局部变量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
声明为本地变量,而不是当前看似的全局变量。答案 1 :(得分:0)
而不是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
指向的东西。