2010-12-20 21 views
12

Przeglądałem przez net/core/dev.c i inne pliki, aby spróbować dowiedzieć się, jak uzyskać listę urządzeń sieciowych, które są obecnie skonfigurowane i które sprawdzają się trochę trudne do znalezienia.Uzyskiwanie listy urządzeń sieciowych w jądrze Linuksa

Ostatecznym celem jest uzyskanie statystyk urządzeń sieciowych za pomocą dev_get_stats w dev.c, ale muszę znać bieżące interfejsy, aby pobrać moduł net_device do przekazania. Muszę to zrobić wewnątrz jądro, kiedy piszę moduł, który dodaje nowy wpis/proc /, który odnosi się do niektórych statystyk z bieżących urządzeń sieciowych, więc z tego, co mogę zebrać, musi to być zrobione wewnątrz jądra.

Jeśli ktoś mógłby wskazać mi, jak uzyskać interfejsy, byłoby to bardzo cenne.

+0

Czy Adres My tego zapytania, jeśli masz odpowiedź: http://stackoverflow.com/questions/36917950/unable- to-fetch-mac-address-from-net-device-in-kernel-module –

Odpowiedz

14

To powinno załatwić sprawę:

#include <linux/netdevice.h> 

struct net_device *dev; 

read_lock(&dev_base_lock); 

dev = first_net_device(&init_net); 
while (dev) { 
    printk(KERN_INFO "found [%s]\n", dev->name); 
    dev = next_net_device(dev); 
} 

read_unlock(&dev_base_lock); 
+4

Blokowanie jest wymagane ('dev_base_lock') przeciw jednoczesnym aktualizacjom listy. – caf

+0

Doskonale! Działa jak urok, wygląda na to, że szukałem w złych okrzykach plików! –

+0

możesz również podać moje zapytanie, jeśli to możliwe, http://stackoverflow.com/questions/36917950/unable-to-fetch-mac-address-from-net-device-in-kernel-module –

14

otrzymał struct net *net identyfikacji nazw netto, która Cię interesuje, należy chwycić dev_base_lock i używać for_each_netdev():

read_lock(&dev_base_lock); 
for_each_netdev(net, dev) { 
    /* Inspect dev */ 
} 
read_unlock(&dev_base_lock); 

(W nowszych w jądrze można zamiast tego użyć RCU, ale w tym przypadku jest to prawdopodobnie nadmierna komplikacja).


Aby uzyskać nazw net w użyciu, powinieneś rejestracji plik proc z register_pernet_subsys():

static const struct file_operations foostats_seq_fops = { 
    .owner = THIS_MODULE, 
    .open = foostats_seq_open, 
    .read = seq_read, 
    .llseek = seq_lseek, 
    .release = foostats_seq_release, 
}; 

static int foo_proc_init_net(struct net *net) 
{ 
    if (!proc_net_fops_create(net, "foostats", S_IRUGO, 
      &foostats_seq_fops)) 
     return -ENOMEM; 
    return 0; 
} 

static void foo_proc_exit_net(struct net *net) 
{ 
    proc_net_remove(net, "foostats"); 
} 


static struct pernet_operations foo_proc_ops = { 
    .init = foo_proc_init_net, 
    .exit = foo_proc_exit_net, 
}; 

register_pernet_subsys(&foo_proc_ops) 

W funkcji foostats_seq_open(), wziąć odniesienie nazw net i upuść go w funkcja zwolnienia:

static int foostats_seq_open(struct inode *inode, struct file *file) 
{ 
    int err; 
    struct net *net; 

    err = -ENXIO; 
    net = get_proc_net(inode); 
    if (net == NULL) 
     goto err_net; 

    err = single_open(file, foostats_seq_show, net); 
    if (err < 0) 
     goto err_open; 

    return 0; 

err_open: 
    put_net(net); 
err_net: 
    return err; 
} 

static int foostats_seq_release(struct inode *inode, struct file *file) 
{ 
    struct net *net = ((struct seq_file *)file->private_data)->private; 

    put_net(net); 
    return single_release(inode, file); 
} 

Funkcja foostats_seq_show() może n uzyskać net, chodzić urządzeń, zbierać statystyki i produkować wyjście:

static int sockstat6_seq_show(struct seq_file *seq, void *v) 
{ 
    struct net *net = seq->private; 
    struct net_device *dev; 

    int foostat, barstat; 

    read_lock(&dev_base_lock); 
    for_each_netdev(net, dev) { 
     /* Inspect dev */ 
    } 
    read_unlock(&dev_base_lock); 

    seq_printf(seq, "Foo: %d\n", foostat); 
    seq_printf(seq, "Bar: %d\n", barstat); 

    return 0; 
} 
Powiązane problemy