~ubuntu-branches/ubuntu/edgy/hwinfo/edgy

« back to all changes in this revision

Viewing changes to src/hd/net.c

  • Committer: Bazaar Package Importer
  • Author(s): James Vega
  • Date: 2006-09-28 20:56:06 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060928205606-bgxl69hts04xbx51
Tags: 13.4-1
* New upstream version.
* Switch from dbs to quilt
  - Revamp debian/rules
  - Add quilt and remove dbs from Build-Depends in debian/control
* Remove reference to hwscan(8) from manpage. (closes: #388245)
* Re-wrote manpage from scratch.  Drop docbook-to-man from Build-Depends.
* Remove NEWS.Debian since it is no longer applicable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <string.h>
 
4
#include <unistd.h>
 
5
#include <fcntl.h>
 
6
#include <inttypes.h>
 
7
#include <errno.h>
 
8
#include <sys/stat.h>
 
9
#include <sys/types.h>
 
10
#include <sys/ioctl.h>
 
11
#include <sys/socket.h>
 
12
 
 
13
#define u8 uint8_t
 
14
#define u16 uint16_t
 
15
#define u32 uint32_t
 
16
#define u64 uint64_t
 
17
#include <linux/if.h>
 
18
#include <linux/sockios.h>
 
19
#include <linux/ethtool.h>
 
20
#include <linux/if_arp.h>
 
21
 
 
22
#include "hd.h"
 
23
#include "hd_int.h"
 
24
#include "net.h"
 
25
 
 
26
/**
 
27
 * @defgroup NETint Network devices
 
28
 * @ingroup libhdDEVint
 
29
 * @brief Network device scan functions
 
30
 *
 
31
 * Gather network interface info
 
32
 *
 
33
 * @{
 
34
 */
 
35
 
 
36
static void get_driverinfo(hd_data_t *hd_data, hd_t *hd);
 
37
static void get_linkstate(hd_data_t *hd_data, hd_t *hd);
 
38
static void add_xpnet(hd_data_t *hdata);
 
39
static void add_mv(hd_data_t *hdata);
 
40
static void add_iseries(hd_data_t *hdata);
 
41
static void add_uml(hd_data_t *hdata);
 
42
static void add_kma(hd_data_t *hdata);
 
43
static void add_xen(hd_data_t *hdata);
 
44
static void add_if_name(hd_t *hd_card, hd_t *hd);
 
45
 
 
46
/*
 
47
 * This is independent of the other scans.
 
48
 */
 
49
 
 
50
void hd_scan_net(hd_data_t *hd_data)
 
51
{
 
52
  unsigned u;
 
53
  int if_type;
 
54
  hd_t *hd, *hd_card;
 
55
  char *s, *hw_addr;
 
56
  hd_res_t *res, *res1;
 
57
  uint64_t ul0;
 
58
  str_list_t *sf_class, *sf_class_e;
 
59
  char *sf_cdev = NULL, *sf_dev = NULL;
 
60
  char *sf_drv_name, *sf_drv;
 
61
 
 
62
  if(!hd_probe_feature(hd_data, pr_net)) return;
 
63
 
 
64
  hd_data->module = mod_net;
 
65
 
 
66
  /* some clean-up */
 
67
  remove_hd_entries(hd_data);
 
68
  hd_data->net = free_str_list(hd_data->net);
 
69
 
 
70
  PROGRESS(1, 0, "get network data");
 
71
 
 
72
  sf_class = reverse_str_list(read_dir("/sys/class/net", 'd'));
 
73
 
 
74
  if(!sf_class) {
 
75
    ADD2LOG("sysfs: no such class: net\n");
 
76
    return;
 
77
  }
 
78
 
 
79
  for(sf_class_e = sf_class; sf_class_e; sf_class_e = sf_class_e->next) {
 
80
    str_printf(&sf_cdev, 0, "/sys/class/net/%s", sf_class_e->str);
 
81
 
 
82
    hd_card = NULL;
 
83
 
 
84
    ADD2LOG(
 
85
      "  net interface: name = %s, path = %s\n",
 
86
      sf_class_e->str,
 
87
      hd_sysfs_id(sf_cdev)
 
88
    );
 
89
 
 
90
    if_type = -1;
 
91
    if(hd_attr_uint(get_sysfs_attr_by_path(sf_cdev, "type"), &ul0, 0)) {
 
92
      if_type = ul0;
 
93
      ADD2LOG("    type = %d\n", if_type);
 
94
    }
 
95
 
 
96
    hw_addr = NULL;
 
97
    if((s = get_sysfs_attr_by_path(sf_cdev, "address"))) {
 
98
      hw_addr = canon_str(s, strlen(s));
 
99
      ADD2LOG("    hw_addr = %s\n", hw_addr);
 
100
    }
 
101
 
 
102
    sf_dev = new_str(hd_read_sysfs_link(sf_cdev, "device"));
 
103
    if(sf_dev) {
 
104
      ADD2LOG("    net device: path = %s\n", hd_sysfs_id(sf_dev));
 
105
    }
 
106
 
 
107
    sf_drv_name = NULL;
 
108
    sf_drv = hd_read_sysfs_link(sf_dev, "driver");
 
109
    if(sf_drv) {
 
110
      sf_drv_name = strrchr(sf_drv, '/');
 
111
      if(sf_drv_name) sf_drv_name++;
 
112
      ADD2LOG(
 
113
        "    net driver: name = %s, path = %s\n",
 
114
        sf_drv_name,
 
115
        hd_sysfs_id(sf_drv)
 
116
      );
 
117
    }
 
118
 
 
119
    hd = add_hd_entry(hd_data, __LINE__, 0);
 
120
    hd->base_class.id = bc_network_interface;
 
121
    hd->sub_class.id = sc_nif_other;
 
122
 
 
123
    res1 = NULL;
 
124
    if(hw_addr && strspn(hw_addr, "0:") != strlen(hw_addr)) {
 
125
      res1 = new_mem(sizeof *res1);
 
126
      res1->hwaddr.type = res_hwaddr;
 
127
      res1->hwaddr.addr = new_str(hw_addr);
 
128
      add_res_entry(&hd->res, res1);
 
129
    }
 
130
 
 
131
    hw_addr = free_mem(hw_addr);
 
132
 
 
133
    hd->unix_dev_name = new_str(sf_class_e->str);
 
134
    hd->sysfs_id = new_str(hd_sysfs_id(sf_cdev));
 
135
 
 
136
    if(sf_drv_name) {
 
137
      add_str_list(&hd->drivers, sf_drv_name);
 
138
    }
 
139
    else if(hd->res) {
 
140
      get_driverinfo(hd_data, hd);
 
141
    }
 
142
 
 
143
    if(sf_dev) {
 
144
      hd->sysfs_device_link = new_str(hd_sysfs_id(sf_dev)); 
 
145
 
 
146
      hd_card = hd_find_sysfs_id(hd_data, hd_sysfs_id(sf_dev));
 
147
      if(hd_card) {
 
148
        hd->attached_to = hd_card->idx;
 
149
 
 
150
        /* for cards with strange pci classes */
 
151
        hd_set_hw_class(hd_card, hw_network_ctrl);
 
152
 
 
153
        /* add hw addr to network card */
 
154
        if(res1) {
 
155
          u = 0;
 
156
          for(res = hd_card->res; res; res = res->next) {
 
157
            if(
 
158
              res->any.type == res_hwaddr &&
 
159
              !strcmp(res->hwaddr.addr, res1->hwaddr.addr)
 
160
            ) {
 
161
              u = 1;
 
162
              break;
 
163
            }
 
164
          }
 
165
          if(!u) {
 
166
            res = new_mem(sizeof *res);
 
167
            res->hwaddr.type = res_hwaddr;
 
168
            res->hwaddr.addr = new_str(res1->hwaddr.addr);
 
169
            add_res_entry(&hd_card->res, res);
 
170
          }
 
171
        }
 
172
        /* add interface names */
 
173
        add_if_name(hd_card, hd);
 
174
      }
 
175
    }
 
176
 
 
177
#if 0
 
178
    "ctc"       sc_nif_ctc
 
179
    "iucv"      sc_nif_iucv
 
180
    "hsi"       sc_nif_hsi
 
181
    "qeth"      sc_nif_qeth
 
182
    "escon"     sc_nif_escon
 
183
    "myri"      sc_nif_myrinet
 
184
    "wlan"      sc_nif_wlan
 
185
    "xp"        sc_nif_xp
 
186
    "usb"       sc_nif_usb
 
187
#endif
 
188
 
 
189
    switch(if_type) {
 
190
      case ARPHRD_ETHER:        /* eth */
 
191
        hd->sub_class.id = sc_nif_ethernet;
 
192
        break;
 
193
      case ARPHRD_LOOPBACK:     /* lo */
 
194
        hd->sub_class.id = sc_nif_loopback;
 
195
        break;
 
196
      case ARPHRD_SIT:          /* sit */
 
197
        hd->sub_class.id = sc_nif_sit;
 
198
        break;
 
199
      case ARPHRD_FDDI:         /* fddi */
 
200
        hd->sub_class.id = sc_nif_fddi;
 
201
        break;
 
202
      case ARPHRD_IEEE802_TR:   /* tr */
 
203
        hd->sub_class.id = sc_nif_tokenring;
 
204
        break;
 
205
#if 0
 
206
      case ARPHRD_IEEE802:      /* fc */
 
207
        hd->sub_class.id = sc_nif_fc;
 
208
        break;
 
209
#endif
 
210
    }
 
211
 
 
212
    if(!strcmp(hd->unix_dev_name, "lo")) {
 
213
      hd->sub_class.id = sc_nif_loopback;
 
214
    }
 
215
    else if(sscanf(hd->unix_dev_name, "eth%u", &u) == 1) {
 
216
      hd->sub_class.id = sc_nif_ethernet;
 
217
      hd->slot = u;
 
218
    }
 
219
    else if(sscanf(hd->unix_dev_name, "tr%u", &u) == 1) {
 
220
      hd->sub_class.id = sc_nif_tokenring;
 
221
      hd->slot = u;
 
222
    }
 
223
    else if(sscanf(hd->unix_dev_name, "fddi%u", &u) == 1) {
 
224
      hd->sub_class.id = sc_nif_fddi;
 
225
      hd->slot = u;
 
226
    }
 
227
    else if(sscanf(hd->unix_dev_name, "ctc%u", &u) == 1) {
 
228
      hd->sub_class.id = sc_nif_ctc;
 
229
      hd->slot = u;
 
230
    }
 
231
    else if(sscanf(hd->unix_dev_name, "iucv%u", &u) == 1) {
 
232
      hd->sub_class.id = sc_nif_iucv;
 
233
      hd->slot = u;
 
234
    }
 
235
    else if(sscanf(hd->unix_dev_name, "hsi%u", &u) == 1) {
 
236
      hd->sub_class.id = sc_nif_hsi;
 
237
      hd->slot = u;
 
238
    }
 
239
    else if(sscanf(hd->unix_dev_name, "qeth%u", &u) == 1) {
 
240
      hd->sub_class.id = sc_nif_qeth;
 
241
      hd->slot = u;
 
242
    }
 
243
    else if(sscanf(hd->unix_dev_name, "escon%u", &u) == 1) {
 
244
      hd->sub_class.id = sc_nif_escon;
 
245
      hd->slot = u;
 
246
    }
 
247
    else if(sscanf(hd->unix_dev_name, "myri%u", &u) == 1) {
 
248
      hd->sub_class.id = sc_nif_myrinet;
 
249
      hd->slot = u;
 
250
    }
 
251
    else if(sscanf(hd->unix_dev_name, "sit%u", &u) == 1) {
 
252
      hd->sub_class.id = sc_nif_sit;    /* ipv6 over ipv4 tunnel */
 
253
      hd->slot = u;
 
254
    }
 
255
    else if(sscanf(hd->unix_dev_name, "wlan%u", &u) == 1) {
 
256
      hd->sub_class.id = sc_nif_wlan;
 
257
      hd->slot = u;
 
258
    }
 
259
    else if(sscanf(hd->unix_dev_name, "xp%u", &u) == 1) {
 
260
      hd->sub_class.id = sc_nif_xp;
 
261
      hd->slot = u;
 
262
    }
 
263
    else if(sscanf(hd->unix_dev_name, "usb%u", &u) == 1) {
 
264
      hd->sub_class.id = sc_nif_usb;
 
265
      hd->slot = u;
 
266
    }
 
267
    /* ##### add more interface names here */
 
268
 
 
269
    hd->bus.id = bus_none;
 
270
 
 
271
    /* fix card type */
 
272
    if(hd_card) {
 
273
      if(
 
274
        (hd_card->base_class.id == 0 && hd_card->sub_class.id == 0) ||
 
275
        (hd_card->base_class.id == bc_network && hd_card->sub_class.id == 0x80)
 
276
      ) {
 
277
        switch(hd->sub_class.id) {
 
278
          case sc_nif_ethernet:
 
279
            hd_card->base_class.id = bc_network;
 
280
            hd_card->sub_class.id = 0;
 
281
            break;
 
282
 
 
283
          case sc_nif_usb:
 
284
            hd_card->base_class.id = bc_network;
 
285
            hd_card->sub_class.id = 0x91;
 
286
            break;
 
287
        }
 
288
      }
 
289
    }
 
290
 
 
291
    sf_dev = free_mem(sf_dev);
 
292
  }
 
293
 
 
294
  sf_cdev = free_mem(sf_cdev);
 
295
  sf_class = free_str_list(sf_class);
 
296
 
 
297
  if(hd_is_sgi_altix(hd_data)) add_xpnet(hd_data);
 
298
  if(hd_is_iseries(hd_data)) add_iseries(hd_data);
 
299
  add_uml(hd_data);
 
300
  add_xen(hd_data);
 
301
  add_kma(hd_data);
 
302
  add_mv(hd_data);
 
303
 
 
304
  /* add link status info */
 
305
  for(hd = hd_data->hd ; hd; hd = hd->next) {
 
306
    if(
 
307
      hd->module == hd_data->module &&
 
308
      hd->base_class.id == bc_network_interface
 
309
    ) {
 
310
      get_linkstate(hd_data, hd);
 
311
 
 
312
      if(!(hd_card = hd_get_device_by_idx(hd_data, hd->attached_to))) continue;
 
313
 
 
314
      for(res = hd->res; res; res = res->next) {
 
315
        if(res->any.type == res_link) break;
 
316
      }
 
317
 
 
318
      if(res) {
 
319
        for(res1 = hd_card->res; res1; res1 = res1->next) {
 
320
          if(res1->any.type == res_link) break;
 
321
        }
 
322
        if(res && !res1) {
 
323
          res1 = new_mem(sizeof *res1);
 
324
          res1->link.type = res_link;
 
325
          res1->link.state = res->link.state;
 
326
          add_res_entry(&hd_card->res, res1);
 
327
        }
 
328
      }
 
329
    }
 
330
  }
 
331
}
 
332
 
 
333
 
 
334
/*
 
335
 * Get it the classical way, for drivers that don't support sysfs (veth).
 
336
 */
 
337
void get_driverinfo(hd_data_t *hd_data, hd_t *hd)
 
338
{
 
339
  int fd;
 
340
  struct ethtool_drvinfo drvinfo = { cmd:ETHTOOL_GDRVINFO };
 
341
  struct ifreq ifr;
 
342
 
 
343
  if(!hd->unix_dev_name) return;
 
344
 
 
345
  if(strlen(hd->unix_dev_name) > sizeof ifr.ifr_name - 1) return;
 
346
 
 
347
  if((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1) return;
 
348
 
 
349
  /* get driver info */
 
350
  memset(&ifr, 0, sizeof ifr);
 
351
  strcpy(ifr.ifr_name, hd->unix_dev_name);
 
352
  ifr.ifr_data = (caddr_t) &drvinfo;
 
353
  if(ioctl(fd, SIOCETHTOOL, &ifr) == 0) {
 
354
    ADD2LOG("    ethtool driver: %s\n", drvinfo.driver);
 
355
    ADD2LOG("    ethtool    bus: %s\n", drvinfo.bus_info);
 
356
 
 
357
    add_str_list(&hd->drivers, drvinfo.driver);
 
358
  }
 
359
  else {
 
360
    ADD2LOG("    GDRVINFO ethtool error: %s\n", strerror(errno));
 
361
  }
 
362
 
 
363
  close(fd);
 
364
}
 
365
 
 
366
 
 
367
/*
 
368
 * Check network link status.
 
369
 */
 
370
void get_linkstate(hd_data_t *hd_data, hd_t *hd)
 
371
{
 
372
  int fd;
 
373
  struct ethtool_value linkstatus = { cmd:ETHTOOL_GLINK };
 
374
  struct ifreq ifr;
 
375
  hd_res_t *res;
 
376
 
 
377
  if(!hd->unix_dev_name) return;
 
378
 
 
379
  if(strlen(hd->unix_dev_name) > sizeof ifr.ifr_name - 1) return;
 
380
 
 
381
  if((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1) return;
 
382
 
 
383
  /* get driver info */
 
384
  memset(&ifr, 0, sizeof ifr);
 
385
  strcpy(ifr.ifr_name, hd->unix_dev_name);
 
386
  ifr.ifr_data = (caddr_t) &linkstatus;
 
387
  if(ioctl(fd, SIOCETHTOOL, &ifr) == 0) {
 
388
    ADD2LOG("  %s: ethtool link state: %d\n", hd->unix_dev_name, linkstatus.data);
 
389
    res = new_mem(sizeof *res);
 
390
    res->link.type = res_link;
 
391
    res->link.state = linkstatus.data ? 1 : 0;
 
392
    add_res_entry(&hd->res, res);
 
393
  }
 
394
  else {
 
395
    ADD2LOG("  %s: GLINK ethtool error: %s\n", hd->unix_dev_name, strerror(errno));
 
396
  }
 
397
 
 
398
  close(fd);
 
399
}
 
400
 
 
401
 
 
402
/*
 
403
 * SGI Altix cross partition network.
 
404
 */
 
405
void add_xpnet(hd_data_t *hd_data)
 
406
{
 
407
  hd_t *hd, *hd_card;
 
408
  hd_res_t *res, *res2;
 
409
 
 
410
  hd_card = add_hd_entry(hd_data, __LINE__, 0);
 
411
  hd_card->base_class.id = bc_network;
 
412
  hd_card->sub_class.id = 0x83;
 
413
 
 
414
  hd_card->vendor.id = MAKE_ID(TAG_SPECIAL, 0x4002);
 
415
  hd_card->device.id = MAKE_ID(TAG_SPECIAL, 1);
 
416
 
 
417
  if(hd_module_is_active(hd_data, "xpnet")) {
 
418
    add_str_list(&hd_card->drivers, "xpnet");
 
419
  }
 
420
 
 
421
  for(hd = hd_data->hd ; hd; hd = hd->next) {
 
422
    if(
 
423
      hd->module == hd_data->module &&
 
424
      hd->base_class.id == bc_network_interface &&
 
425
      hd->sub_class.id == sc_nif_xp
 
426
    ) {
 
427
      hd->attached_to = hd_card->idx;
 
428
 
 
429
      for(res = hd->res; res; res = res->next) {
 
430
        if(res->any.type == res_hwaddr) break;
 
431
      }
 
432
 
 
433
      if(res) {
 
434
        res2 = new_mem(sizeof *res2);
 
435
        res2->hwaddr.type = res_hwaddr;
 
436
        res2->hwaddr.addr = new_str(res->hwaddr.addr);
 
437
        add_res_entry(&hd_card->res, res2);
 
438
      }
 
439
 
 
440
      add_if_name(hd_card, hd);
 
441
 
 
442
      break;
 
443
    }
 
444
  }
 
445
}
 
446
 
 
447
 
 
448
/*
 
449
 * Marvell Gigabit Ethernet thing
 
450
 */
 
451
void add_mv(hd_data_t *hd_data)
 
452
{
 
453
  hd_t *hd, *hd_card;
 
454
  hd_res_t *res, *res2;
 
455
  struct stat sbuf;
 
456
  char *s, *sf_dev, *sf_dev_name, *module;
 
457
 
 
458
  /*
 
459
   * Actually there are two (.0 & .1), but only one seems to be used - so we
 
460
   * don't care.
 
461
   */
 
462
  sf_dev = "/sys/devices/platform/mv643xx_eth.0";
 
463
  sf_dev_name = "mv643xx_eth.0";
 
464
  module = "mv643xx_eth";
 
465
 
 
466
  if(stat(sf_dev, &sbuf) || !S_ISDIR(sbuf.st_mode)) return;
 
467
 
 
468
  for(hd = hd_data->hd ; hd; hd = hd->next) {
 
469
    if(
 
470
      hd->vendor.id == MAKE_ID(TAG_PCI, 0x11ab) &&
 
471
      hd->device.id == MAKE_ID(TAG_PCI, 0x6460)
 
472
    ) break;
 
473
  }
 
474
 
 
475
  hd_card = add_hd_entry(hd_data, __LINE__, 0);
 
476
  hd_card->base_class.id = bc_network;
 
477
  hd_card->sub_class.id = 0;
 
478
 
 
479
  hd_card->sysfs_id = new_str(hd_sysfs_id(sf_dev));
 
480
  hd_card->sysfs_bus_id = new_str(sf_dev_name);
 
481
 
 
482
  if((s = get_sysfs_attr_by_path(sf_dev, "modalias"))) {
 
483
    hd_card->modalias = canon_str(s, strlen(s));
 
484
    ADD2LOG("    modalias = \"%s\"\n", hd_card->modalias);
 
485
  }
 
486
  else {
 
487
    hd_card->modalias = new_str(module);
 
488
  }
 
489
 
 
490
  if(hd) {
 
491
    hd_card->attached_to = hd->idx;
 
492
    hd_card->vendor.id = hd->vendor.id;
 
493
    hd_card->device.id = hd->device.id;
 
494
  }
 
495
  else {
 
496
    hd_card->vendor.name = new_str("Marvell");
 
497
    hd_card->device.name = new_str("Gigabit Ethernet");
 
498
  }
 
499
 
 
500
  if(hd_module_is_active(hd_data, module)) {
 
501
    add_str_list(&hd_card->drivers, module);
 
502
  }
 
503
 
 
504
  for(hd = hd_data->hd ; hd; hd = hd->next) {
 
505
    if(
 
506
      hd->module == hd_data->module &&
 
507
      hd->base_class.id == bc_network_interface &&
 
508
      hd->sub_class.id == sc_nif_ethernet &&
 
509
      search_str_list(hd->drivers, "mv643xx_eth")
 
510
    ) {
 
511
      hd->attached_to = hd_card->idx;
 
512
 
 
513
      for(res = hd->res; res; res = res->next) {
 
514
        if(res->any.type == res_hwaddr) break;
 
515
      }
 
516
 
 
517
      if(res) {
 
518
        res2 = new_mem(sizeof *res2);
 
519
        res2->hwaddr.type = res_hwaddr;
 
520
        res2->hwaddr.addr = new_str(res->hwaddr.addr);
 
521
        add_res_entry(&hd_card->res, res2);
 
522
      }
 
523
 
 
524
      add_if_name(hd_card, hd);
 
525
 
 
526
      break;
 
527
    }
 
528
  }
 
529
}
 
530
 
 
531
 
 
532
/*
 
533
 * iSeries veth devices.
 
534
 */
 
535
void add_iseries(hd_data_t *hd_data)
 
536
{
 
537
  hd_t *hd, *hd_card;
 
538
  hd_res_t *res, *res2;
 
539
  unsigned i, cardmask = 0, card_cnt = 0;
 
540
  str_list_t *sl0, *sl;
 
541
 
 
542
  for(hd = hd_data->hd ; hd; hd = hd->next) {
 
543
    if(
 
544
      hd->module == hd_data->module &&
 
545
      hd->base_class.id == bc_network_interface &&
 
546
      (
 
547
        search_str_list(hd->drivers, "veth") ||
 
548
        search_str_list(hd->drivers, "iseries_veth")
 
549
      )
 
550
    ) {
 
551
      hd_card = add_hd_entry(hd_data, __LINE__, 0);
 
552
      hd_card->base_class.id = bc_network;
 
553
      hd_card->sub_class.id = 0x00;
 
554
      hd_card->vendor.id = MAKE_ID(TAG_SPECIAL, 0x6001);        // IBM
 
555
      hd_card->device.id = MAKE_ID(TAG_SPECIAL, 0x1000);
 
556
      add_str_list(&hd_card->drivers, "iseries_veth");
 
557
      hd_card->slot = card_cnt++;
 
558
      str_printf(&hd_card->device.name, 0, "Virtual Ethernet card");
 
559
      hd->attached_to = hd_card->idx;
 
560
 
 
561
      for(res = hd->res; res; res = res->next) {
 
562
        if(res->any.type == res_hwaddr) break;
 
563
      }
 
564
 
 
565
      if(res) {
 
566
        unsigned int slotno;
 
567
 
 
568
        res2 = new_mem(sizeof *res2);
 
569
        res2->hwaddr.type = res_hwaddr;
 
570
        res2->hwaddr.addr = new_str(res->hwaddr.addr);
 
571
        add_res_entry(&hd_card->res, res2);
 
572
        if (sscanf(res->hwaddr.addr, "02:01:ff:%x:ff:", &slotno)) {
 
573
          hd_card->slot = slotno;
 
574
          str_printf(&hd_card->device.name, 0, "Virtual Ethernet card %d", hd_card->slot);
 
575
        }
 
576
      }
 
577
 
 
578
      add_if_name(hd_card, hd);
 
579
    }
 
580
  }
 
581
 
 
582
  if(!card_cnt) {
 
583
    sl0 = read_file("/proc/iSeries/config", 0, 0);
 
584
    for(sl = sl0; sl; sl = sl->next) {
 
585
      if(sscanf(sl->str, "AVAILABLE_VETH=%x", &cardmask) == 1)
 
586
         break;
 
587
    }
 
588
    free_str_list(sl0);
 
589
 
 
590
    for (i = 0; i < 16; i++) {
 
591
      if ((0x8000 >> i) & cardmask) {
 
592
        hd_card = add_hd_entry(hd_data, __LINE__, 0);
 
593
        hd_card->base_class.id = bc_network;
 
594
        hd_card->sub_class.id = 0x00;
 
595
        hd_card->vendor.id = MAKE_ID(TAG_SPECIAL, 0x6001);      // IBM
 
596
        hd_card->device.id = MAKE_ID(TAG_SPECIAL, 0x1000);
 
597
        hd_card->slot = i;
 
598
        str_printf(&hd_card->device.name, 0, "Virtual Ethernet card %d", i);
 
599
      }
 
600
    }
 
601
  }
 
602
}
 
603
 
 
604
 
 
605
/*
 
606
 * UML veth devices.
 
607
 */
 
608
void add_uml(hd_data_t *hd_data)
 
609
{
 
610
  hd_t *hd, *hd_card;
 
611
  hd_res_t *res, *res2;
 
612
  unsigned card_cnt = 0;
 
613
 
 
614
  for(hd = hd_data->hd ; hd; hd = hd->next) {
 
615
    if(
 
616
      hd->module == hd_data->module &&
 
617
      hd->base_class.id == bc_network_interface &&
 
618
      search_str_list(hd->drivers, "uml virtual ethernet")
 
619
    ) {
 
620
      hd_card = add_hd_entry(hd_data, __LINE__, 0);
 
621
      hd_card->base_class.id = bc_network;
 
622
      hd_card->sub_class.id = 0x00;
 
623
      hd_card->vendor.id = MAKE_ID(TAG_SPECIAL, 0x6010);        // UML
 
624
      hd_card->device.id = MAKE_ID(TAG_SPECIAL, 0x0001);
 
625
      hd_card->slot = card_cnt++;
 
626
      str_printf(&hd_card->device.name, 0, "Virtual Ethernet card %d", hd_card->slot);
 
627
 
 
628
      hd->attached_to = hd_card->idx;
 
629
 
 
630
      for(res = hd->res; res; res = res->next) {
 
631
        if(res->any.type == res_hwaddr) break;
 
632
      }
 
633
 
 
634
      if(res) {
 
635
        res2 = new_mem(sizeof *res2);
 
636
        res2->hwaddr.type = res_hwaddr;
 
637
        res2->hwaddr.addr = new_str(res->hwaddr.addr);
 
638
        add_res_entry(&hd_card->res, res2);
 
639
      }
 
640
 
 
641
      add_if_name(hd_card, hd);
 
642
    }
 
643
  }
 
644
}
 
645
 
 
646
 
 
647
/*
 
648
 * KMA veth devices.
 
649
 */
 
650
void add_kma(hd_data_t *hd_data)
 
651
{
 
652
  hd_t *hd, *hd_card;
 
653
  hd_res_t *res, *res2;
 
654
  unsigned card_cnt = 0;
 
655
 
 
656
  for(hd = hd_data->hd ; hd; hd = hd->next) {
 
657
    if(
 
658
      hd->module == hd_data->module &&
 
659
      hd->base_class.id == bc_network_interface &&
 
660
      search_str_list(hd->drivers, "kveth2")
 
661
    ) {
 
662
      hd_card = add_hd_entry(hd_data, __LINE__, 0);
 
663
      hd_card->base_class.id = bc_network;
 
664
      hd_card->sub_class.id = 0x00;
 
665
      hd_card->vendor.id = MAKE_ID(TAG_SPECIAL, 0x6012);        // VirtualIron
 
666
      hd_card->device.id = MAKE_ID(TAG_SPECIAL, 0x0001);
 
667
      hd_card->slot = card_cnt++;
 
668
      str_printf(&hd_card->device.name, 0, "Ethernet card %d", hd_card->slot);
 
669
 
 
670
      hd->attached_to = hd_card->idx;
 
671
 
 
672
      for(res = hd->res; res; res = res->next) {
 
673
        if(res->any.type == res_hwaddr) break;
 
674
      }
 
675
 
 
676
      if(res) {
 
677
        res2 = new_mem(sizeof *res2);
 
678
        res2->hwaddr.type = res_hwaddr;
 
679
        res2->hwaddr.addr = new_str(res->hwaddr.addr);
 
680
        add_res_entry(&hd_card->res, res2);
 
681
      }
 
682
 
 
683
      add_if_name(hd_card, hd);
 
684
    }
 
685
  }
 
686
}
 
687
 
 
688
 
 
689
/*
 
690
 * XEN veth devices.
 
691
 */
 
692
void add_xen(hd_data_t *hd_data)
 
693
{
 
694
  hd_t *hd, *hd_card;
 
695
  hd_res_t *res, *res2;
 
696
  unsigned card_cnt = 0;
 
697
  char *s = NULL;
 
698
  struct stat sbuf;
 
699
 
 
700
  for(hd = hd_data->hd ; hd; hd = hd->next) {
 
701
    if(
 
702
      hd->module == hd_data->module &&
 
703
      hd->base_class.id == bc_network_interface
 
704
    ) {
 
705
      str_printf(&s, 0, "/proc/xen/net/%s", hd->unix_dev_name);
 
706
      if(stat(s, &sbuf) || !S_ISDIR(sbuf.st_mode)) continue;
 
707
 
 
708
      hd_card = add_hd_entry(hd_data, __LINE__, 0);
 
709
      hd_card->base_class.id = bc_network;
 
710
      hd_card->sub_class.id = 0x00;
 
711
      hd_card->vendor.id = MAKE_ID(TAG_SPECIAL, 0x6011);        // Xen
 
712
      hd_card->device.id = MAKE_ID(TAG_SPECIAL, 0x0001);
 
713
      hd_card->slot = card_cnt++;
 
714
      str_printf(&hd_card->device.name, 0, "Virtual Ethernet card %d", hd_card->slot);
 
715
 
 
716
      hd->attached_to = hd_card->idx;
 
717
 
 
718
      for(res = hd->res; res; res = res->next) {
 
719
        if(res->any.type == res_hwaddr) break;
 
720
      }
 
721
 
 
722
      if(res) {
 
723
        res2 = new_mem(sizeof *res2);
 
724
        res2->hwaddr.type = res_hwaddr;
 
725
        res2->hwaddr.addr = new_str(res->hwaddr.addr);
 
726
        add_res_entry(&hd_card->res, res2);
 
727
      }
 
728
 
 
729
      add_if_name(hd_card, hd);
 
730
    }
 
731
  }
 
732
 
 
733
  free_mem(s);
 
734
}
 
735
 
 
736
 
 
737
/*
 
738
 * add interface name to card
 
739
 */
 
740
void add_if_name(hd_t *hd_card, hd_t *hd)
 
741
{
 
742
  if(hd->unix_dev_name) {
 
743
    if(!search_str_list(hd_card->unix_dev_names, hd->unix_dev_name)) {
 
744
      add_str_list(&hd_card->unix_dev_names, hd->unix_dev_name);
 
745
    }
 
746
    if(!hd_card->unix_dev_name) {
 
747
      hd_card->unix_dev_name = new_str(hd->unix_dev_name);
 
748
    }
 
749
  }
 
750
}
 
751
 
 
752
/** @} */
 
753