链接列表数据检索/显示问题

时间:2014-05-22 18:30:07

标签: c linux list kernel-module arp

我需要获取当前设备的arp数据。我按照在线示例 - http://rikiji.it/2011/04/17/Linux-kernel-programming-exercises-1.html来执行此任务。此示例解决了识别arp欺骗的解决方案。

但我使用其必要的函数来获取存储的arp详细信息,例如ipmac地址。我的问题是,函数获取数据,但是,当我将这些信息添加到list并在遍历时打印数据时,我会显示虚假数据。不是我存储的那些。

我不知道发生了什么,我尽我所能解决但没有运气。

以下是使用的struct

struct neigh_list_t {
    unsigned char   ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))];
    u8 primary_key[0];
    struct list_head list;
} neigh_list;

以下是实现initializationstoringdisplaying数据的方法。

static struct workqueue_struct * workq;
static DECLARE_DELAYED_WORK(work, arp_tbl_check);

void neigh_print(struct neigh_list_t * n, void * null)
{
    char tbuf[16], hbuffer[HBUFFERLEN];

    sprintf(tbuf, "%pI4", n->primary_key);
    printk(KERN_ALERT "%-16s\n",tbuf);
}

void neigh_handler(struct neighbour * n, void * null)
{
    struct neigh_list_t *tmp;

    int found = 0;
    char hbuffer[HBUFFERLEN];


    /* search */
    list_for_each_entry(tmp, &neigh_list.list, list) {      
        neigh_print(tmp, NULL);
        if(memcmp(n->ha,tmp->ha,n->dev->addr_len)==0) {
              format_hwaddr(n->ha, n->dev->addr_len, hbuffer);
              printk(KERN_ALERT "duplicated entry: %s\n", hbuffer);
              found = 1;
            }

    }   


    /* add an entry */
    if(!found) {
        struct neigh_list_t * new_entry = (struct neigh_list_t *) kmalloc(sizeof(struct neigh_list_t), GFP_KERNEL);
        memcpy(new_entry->ha,n->ha,n->dev->addr_len);
        memcpy(new_entry->primary_key,n->primary_key,sizeof(u8 *));
        list_add(&(new_entry->list), &(neigh_list.list));
    }
}

void arp_tbl_check(struct work_struct * w)
{


    struct list_head *pos, *q;
    struct neigh_list_t * tmp;

    neigh_for_each(&arp_tbl, neigh_handler, NULL);

    /* empty list */
    list_for_each_safe(pos, q, &neigh_list.list){
            tmp= list_entry(pos, struct neigh_list_t, list);
            list_del(pos);
            kfree(tmp);
    }
    queue_delayed_work(workq, &work, HZ * 5);

}

static int arp_init(void)
{

    INIT_LIST_HEAD(&neigh_list.list);   
    printk(KERN_ALERT "arpcheck init\n");

    workq = create_singlethread_workqueue("arp_tbl_check_wq");
    queue_delayed_work(workq, &work, HZ * 5);
    return 0;
}

P.S

对于IP地址192.168.1.1127.0.0.1,该功能会打印0.195.27.160224.39.125.54

我的猜测是存储(memcpy)或尝试显示数据时出现问题。我不知道如何解决这个问题。

编辑 - 测试打印链表的内容

  char tbuf[16];//newly added to print IP

  /* search */
  list_for_each_entry(tmp, &neigh_list.list, list) {

        sprintf(tbuf, "%pI4", tmp->primary_key);//newly added to print IP
        printk(KERN_ALERT "-----IP - %-16s\n",tbuf);//newly added to print IP

        if(memcmp(n->ha,tmp->ha,n->dev->addr_len)==0) {
            format_hwaddr(n->ha, n->dev->addr_len, hbuffer);
            printk(KERN_ALERT "duplicated entry: %s\n", hbuffer);
            found = 1;
        }
  }

1 个答案:

答案 0 :(得分:1)

修改neigh_list_t结构字段,如下所述

struct neigh_list_t {
  struct list_head list;
  unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))];
  u8 primary_key[0];
} neigh_list;

O / p使用printk    ================

[ 1456.124639] 192.168.1.1      4c:60:de:42:81:55 wlo1
[ 1456.124652] -----IP - 192.168.1.1     
[ 1456.124658] 127.0.0.1        00:00:00:00:00:00 lo
[ 1456.124661] -----IP - 127.0.0.1       
[ 1456.124665] -----IP - 192.168.1.1     
[ 1456.124669] 224.0.0.251      01:00:5e:00:00:fb wlo1
[ 1456.124673] -----IP - 224.0.0.251     
[ 1456.124677] -----IP - 127.0.0.1       
[ 1456.124680] -----IP - 192.168.1.1     
[ 1456.124684] 224.0.0.22       01:00:5e:00:00:16 wlo1