// note: hd_data parameter is needed for ADD2LOG macro void add_joystick_details(hd_data_t *hd_data, hd_t *h, const char *key, const char *abso) { // replace existing details if (h->detail) { free_hd_detail(h->detail); } // add buttons and axis details h->detail = new_mem(sizeof *h->detail); h->detail->type = hd_detail_joystick; joystick_t *jt = new_mem(sizeof jt); unsigned u; if(key) { for(u = BTN_JOYSTICK; u < BTN_JOYSTICK + 16; u++) { if(test_bit(key, u)) jt->buttons++; } } ADD2LOG(" joystick buttons = %u\n", jt->buttons); if(abso) { for(u = ABS_X; u < ABS_VOLUME; u++) { if(test_bit(abso, u)) jt->axes++; } } ADD2LOG(" joystick axes = %u\n", jt->axes); h->detail->joystick.data = jt; }
static void parse_pado_tags (uint16_t type, uint16_t len, unsigned char* data, void* extra) { PacketCriteria* pc = (PacketCriteria*) extra; PPPoEConnection *conn = pc->conn; switch (type) { case TAG_AC_NAME: pc->acname_ok = 1; ADD2LOG ("%s: Service-Name is: %.*s\n", conn->ifname, (int) len, data); break; case TAG_SERVICE_NAME: pc->servicename_ok = len == 0; break; case TAG_SERVICE_NAME_ERROR: ADD2LOG ("%s: Service-Name-Error: %.*s\n", conn->ifname, (int) len, data); pc->error = 1; break; case TAG_AC_SYSTEM_ERROR: ADD2LOG ("%s: System-Error: %.*s\n", conn->ifname, (int) len, data); pc->error = 1; break; case TAG_GENERIC_ERROR: ADD2LOG ("%s: Generic-Error: %.*s\n", conn->ifname, (int) len, data); pc->error = 1; break; } }
/* * Add some klog data to the global log. */ void dump_klog(hd_data_t *hd_data) { str_list_t *sl; ADD2LOG("----- kernel log -----\n"); for(sl = hd_data->klog_raw; sl; sl = sl->next) { ADD2LOG(" %s", sl->str); } ADD2LOG("----- kernel log end -----\n"); }
/* * Add floppy data to the global log. */ void dump_floppy_data(hd_data_t *hd_data) { str_list_t *sl; ADD2LOG("----- /proc/nvram -----\n"); for(sl = hd_data->floppy; sl; sl = sl->next) { ADD2LOG(" %s", sl->str); } ADD2LOG("----- /proc/nvram end -----\n"); }
void at_cmd(hd_data_t *hd_data, char *at, int raw, int log_it) { static unsigned u = 1; char *s, *s0; ser_device_t *sm; str_list_t *sl; int modems = 0; for(sm = hd_data->ser_modem; sm; sm = sm->next) { if(sm->do_io) { sm->buf_len = 0; modems++; } } if(modems == 0) return; PROGRESS(9, u, "write at cmd"); write_modem(hd_data, at); PROGRESS(9, u, "read at resp"); usleep (200000); read_modem(hd_data); PROGRESS(9, u, "read ok"); u++; for(sm = hd_data->ser_modem; sm; sm = sm->next) { if(sm->do_io) { sm->at_resp = free_str_list(sm->at_resp); if(sm->buf_len == 0 || raw) continue; s0 = sm->buf; while((s = strsep(&s0, "\r\n"))) { if(*s) add_str_list(&sm->at_resp, s); } } } if(!(hd_data->debug & HD_DEB_MODEM) || !log_it) return; for(sm = hd_data->ser_modem; sm; sm = sm->next) { if(sm->do_io) { ADD2LOG("%s@%u: %s\n", sm->dev_name, sm->cur_baud, at); if(raw) { ADD2LOG(" "); hexdump(&hd_data->log, 1, sm->buf_len, sm->buf); ADD2LOG("\n"); } else { for(sl = sm->at_resp; sl; sl = sl->next) ADD2LOG(" %s\n", sl->str); } } } }
void dump_serial_data(hd_data_t *hd_data) { serial_t *ser; ADD2LOG("----- serial info -----\n"); for(ser = hd_data->serial; ser; ser = ser->next) { ADD2LOG( " uart %s, line %d, port 0x%03x, irq %d, baud %d\n", ser->name, ser->line, ser->port, ser->irq, ser->baud ); } ADD2LOG("----- serial info end -----\n"); }
/* * Tag ide soft raid disks. */ void int_softraid(hd_data_t *hd_data) { hd_t *hd; str_list_t *raid, *sl, *raid_sysfs = NULL, *sl1; size_t len; char *s; if(hd_data->flags.fast) return; for(hd = hd_data->hd; hd; hd = hd->next) { if( hd->base_class.id == bc_storage_device && hd->status.available != status_no ) break; } /* no disks -> no check necessary */ if(!hd) return; raid = read_file("| /sbin/dmraid -rc 2>/dev/null", 0, 0); for(sl = raid; sl; sl = sl->next) { s = *sl->str ? strchr(sl->str + 1, '/') : NULL; if(s) { sl1 = add_str_list(&raid_sysfs, NULL); str_printf(&sl1->str, 0, "/block%s", s); len = strlen(sl1->str); if(len) sl1->str[len - 1] = 0; } } free_str_list(raid); ADD2LOG("----- soft raid devices -----\n"); for(sl = raid_sysfs; sl; sl = sl->next) { ADD2LOG(" %s\n", sl->str); } ADD2LOG("----- soft raid devices end -----\n"); for(hd = hd_data->hd; hd; hd = hd->next) { if(search_str_list(raid_sysfs, hd->sysfs_id)) { hd->is.softraiddisk = 1; } } free_str_list(raid_sysfs); }
/* * Try to read block 0 for block devices. */ void int_media_check(hd_data_t *hd_data) { hd_t *hd; int i, j = 0; for(hd = hd_data->hd; hd; hd = hd->next) { if(!hd_report_this(hd_data, hd)) continue; if( hd->base_class.id == bc_storage_device && ( /* hd->sub_class.id == sc_sdev_cdrom || */ /* cf. cdrom.c */ hd->sub_class.id == sc_sdev_disk || hd->sub_class.id == sc_sdev_floppy ) && hd->unix_dev_name && !hd->block0 && !hd->is.notready && hd->status.available != status_no ) { i = 5; PROGRESS(4, ++j, hd->unix_dev_name); hd->block0 = read_block0(hd_data, hd->unix_dev_name, &i); hd->is.notready = hd->block0 ? 0 : 1; #if defined(__i386__) || defined(__x86_64__) if(hd->block0) { ADD2LOG(" mbr sig: 0x%08x\n", edd_disk_signature(hd)); } #endif } } }
static int parse_packet (PPPoEConnection* conn, PPPoEPacket* packet, parse_func* func, void* extra) { uint16_t len = ntohs (packet->length); unsigned char* curTag; uint16_t tagType, tagLen; if (packet->ver != 1) { ADD2LOG ("%s: Invalid PPPoE version (%d)\n", conn->ifname, (int) packet->ver); return 0; } if (packet->type != 1) { ADD2LOG ("%s: Invalid PPPoE type (%d)\n", conn->ifname, (int) packet->type); return 0; } /* Do some sanity checks on packet. */ if (len > ETH_DATA_LEN - 6) { /* 6-byte overhead for PPPoE header */ ADD2LOG ("%s: Invalid PPPoE packet length (%u)\n", conn->ifname, len); return 0; } /* Step through the tags. */ curTag = packet->payload; while (curTag - packet->payload < len) { /* Alignment is not guaranteed, so do this by hand. */ tagType = (((uint16_t) curTag[0]) << 8) + (uint16_t) curTag[1]; tagLen = (((uint16_t) curTag[2]) << 8) + (uint16_t) curTag[3]; if (tagType == TAG_END_OF_LIST) break; if ((curTag - packet->payload) + tagLen + TAG_HDR_SIZE > len) { ADD2LOG ("%s: Invalid PPPoE tag length (%u)\n", conn->ifname, tagLen); return 0; } func (tagType, tagLen, curTag + TAG_HDR_SIZE, extra); curTag = curTag + TAG_HDR_SIZE + tagLen; } return 1; }
static int send_packet (int fd, PPPoEPacket* pkt, size_t size) { if (send (fd, pkt, size, 0) < 0) { ADD2LOG ("send failed: %m\n"); return 0; } return 1; }
static int check_room (PPPoEConnection* conn, unsigned char* cursor, unsigned char* start, uint16_t len) { if (cursor - start + len > MAX_PPPOE_PAYLOAD) { ADD2LOG ("%s: Would create too-long packet\n", conn->ifname); return 0; } return 1; }
static int receive_packet (int fd, PPPoEPacket* pkt, size_t* size) { int r = recv (fd, pkt, sizeof (PPPoEPacket), 0); if (r < 0) { ADD2LOG ("recv failed: %m\n"); return 0; } *size = r; return 1; }
hal_prop_t *read_properties(hd_data_t *hd_data, const char *udi, const char *id) { hd_t *hd; hal_prop_t *prop = NULL; if(udi) { prop = hd_read_properties(udi); ADD2LOG(" prop read: %s (%s)\n", udi, prop ? "ok" : "failed"); } if(prop) return prop; if(id && !udi) { /* try to find udi entry */ for(hd = hd_data->hd; hd; hd = hd->next) { if(hd->udi && hd->unique_id && !strcmp(id, hd->unique_id)) { udi = hd->udi; break; } } if(udi) { prop = hd_read_properties(udi); ADD2LOG(" prop read: %s (%s)\n", udi, prop ? "ok" : "failed"); } } if(!prop) { prop = hd_read_properties(id); ADD2LOG(" prop read: %s (%s)\n", id, prop ? "ok" : "failed"); } if(!prop) { prop = hd_manual_read_entry_old(id); ADD2LOG(" old prop read: %s (%s)\n", id, prop ? "ok" : "failed"); } return prop; }
void write_modem(hd_data_t *hd_data, char *msg) { ser_device_t *sm; int i, len = strlen(msg); for(sm = hd_data->ser_modem; sm; sm = sm->next) { if(sm->do_io) { i = write(sm->fd, msg, len); if(i != len) { ADD2LOG("%s write oops: %d/%d (\"%s\")\n", sm->dev_name, i, len, msg); } } } }
unsigned read_data(hd_data_t *hd_data, int fd, unsigned char *buf, unsigned buf_size) { int k, len = 0; unsigned char *bp; while( (unsigned) len < buf_size && (k = read(fd, buf + len, buf_size - len)) >= 0 ) len += k; bp = buf; if(len && (*bp == 0xfe || *bp == 0xfa)) { bp++; len--; } for(k = 0; k < len; k++) buf[k] = bp[k]; if((hd_data->debug & HD_DEB_MOUSE)) { ADD2LOG("ps/2[%d]: ", len); hexdump(&hd_data->log, 1, len, buf); ADD2LOG("\n"); } return len; }
/* * Add some proc info to the global log. */ void dump_misc_proc_data(hd_data_t *hd_data) { str_list_t *sl; ADD2LOG("----- /proc/ioports -----\n"); for(sl = hd_data->misc->proc_io; sl; sl = sl->next) { ADD2LOG(" %s", sl->str); } ADD2LOG("----- /proc/ioports end -----\n"); ADD2LOG("----- /proc/interrupts -----\n"); for(sl = hd_data->misc->proc_irq; sl; sl = sl->next) { ADD2LOG(" %s", sl->str); } ADD2LOG("----- /proc/interrupts end -----\n"); ADD2LOG("----- /proc/dma -----\n"); for(sl = hd_data->misc->proc_dma; sl; sl = sl->next) { ADD2LOG(" %s", sl->str); } ADD2LOG("----- /proc/dma end -----\n"); }
void hd_scan_sysfs_block(hd_data_t *hd_data) { if(!hd_probe_feature(hd_data, pr_block)) return; hd_data->module = mod_block; /* some clean-up */ remove_hd_entries(hd_data); hd_data->disks = free_str_list(hd_data->disks); hd_data->partitions = free_str_list(hd_data->partitions); hd_data->cdroms = free_str_list(hd_data->cdroms); if(hd_probe_feature(hd_data, pr_block_mods)) { PROGRESS(1, 0, "block modules"); // load_module(hd_data, "ide-cd"); load_module(hd_data, "ide-cd_mod"); load_module(hd_data, "ide-disk"); load_module(hd_data, "sr_mod"); load_module(hd_data, "sd_mod"); #if !defined(__s390__) && !defined(__s390x__) load_module(hd_data, "st"); #endif } PROGRESS(2, 0, "sysfs drivers"); hd_sysfs_driver_list(hd_data); PROGRESS(3, 0, "cdrom"); read_cdroms(hd_data); PROGRESS(4, 0, "partition"); read_partitions(hd_data); PROGRESS(5, 0, "get sysfs block dev data"); get_block_devs(hd_data); if(hd_data->cdrom) { ADD2LOG("oops: cdrom list not empty\n"); } }
static void discovery (int n, PPPoEConnection* conns) { int a; if (open_interfaces (n, conns)) { for (a = 0; a < MAX_ATTEMPTS; a++) { ADD2LOG ("Attempt number %d\n", a + 1); if (!send_padi (n, conns)) break; if (wait_for_pado (n, conns)) break; } } close_intefaces (n, conns); }
/* * Add the resource usage to the global log. */ void dump_misc_data(hd_data_t *hd_data) { misc_t *m = hd_data->misc; int i, j; ADD2LOG("----- misc resources -----\n"); for(i = 0; (unsigned) i < m->io_len; i++) { ADD2LOG( "i/o:%u 0x%04"PRIx64" - 0x%04"PRIx64" (0x%02"PRIx64") \"%s\"\n", m->io[i].tag, m->io[i].addr, m->io[i].addr + m->io[i].size - 1, m->io[i].size, m->io[i].dev ); } for(i = 0; (unsigned) i < m->irq_len; i++) { ADD2LOG( "irq:%u %2u (%9u)", m->irq[i].tag, m->irq[i].irq, m->irq[i].events ); for(j = 0; j < m->irq[i].devs; j++) { ADD2LOG(" \"%s\"", m->irq[i].dev[j]); } ADD2LOG("\n"); } for(i = 0; (unsigned) i < m->dma_len; i++) { ADD2LOG( "dma:%u %u \"%s\"\n", m->dma[i].tag, m->dma[i].channel, m->dma[i].dev ); } ADD2LOG("----- misc resources end -----\n"); }
void get_usb_devs(hd_data_t *hd_data) { uint64_t ul0; unsigned u1, u2, u3; hd_t *hd, *hd1; usb_t *usb; str_list_t *sl, *usb_devs = NULL; char *s, *s1, *t; hd_res_t *res; size_t l; str_list_t *sf_bus, *sf_bus_e; char *sf_dev, *sf_dev_2; sf_bus = read_dir("/sys/bus/usb/devices", 'l'); if(!sf_bus) { ADD2LOG("sysfs: no such bus: usb\n"); return; } for(sf_bus_e = sf_bus; sf_bus_e; sf_bus_e = sf_bus_e->next) { sf_dev = hd_read_sysfs_link("/sys/bus/usb/devices", sf_bus_e->str); if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "bNumInterfaces"), &ul0, 0)) { add_str_list(&usb_devs, sf_dev); ADD2LOG(" usb dev: %s\n", hd_sysfs_id(sf_dev)); } } for(sf_bus_e = sf_bus; sf_bus_e; sf_bus_e = sf_bus_e->next) { sf_dev = new_str(hd_read_sysfs_link("/sys/bus/usb/devices", sf_bus_e->str)); ADD2LOG( " usb device: name = %s\n path = %s\n", sf_bus_e->str, hd_sysfs_id(sf_dev) ); if( hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "bInterfaceNumber"), &ul0, 16) ) { hd = add_hd_entry(hd_data, __LINE__, 0); hd->detail = new_mem(sizeof *hd->detail); hd->detail->type = hd_detail_usb; hd->detail->usb.data = usb = new_mem(sizeof *usb); hd->sysfs_id = new_str(hd_sysfs_id(sf_dev)); hd->sysfs_bus_id = new_str(sf_bus_e->str); hd->bus.id = bus_usb; hd->func = ul0; usb->ifdescr = ul0; if((s = get_sysfs_attr_by_path(sf_dev, "modalias"))) { s = canon_str(s, strlen(s)); ADD2LOG(" modalias = \"%s\"\n", s); if(s && *s) { hd->modalias = s; s = NULL; } s = free_mem(s); } ADD2LOG(" bInterfaceNumber = %u\n", hd->func); if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "bInterfaceClass"), &ul0, 16)) { usb->i_cls = ul0; ADD2LOG(" bInterfaceClass = %u\n", usb->i_cls); } if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "bInterfaceSubClass"), &ul0, 16)) { usb->i_sub = ul0; ADD2LOG(" bInterfaceSubClass = %u\n", usb->i_sub); } if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "bInterfaceProtocol"), &ul0, 16)) { usb->i_prot = ul0; ADD2LOG(" bInterfaceProtocol = %u\n", usb->i_prot); } /* device has longest matching sysfs id */ u2 = strlen(sf_dev); s = NULL; for(u3 = 0, sl = usb_devs; sl; sl = sl->next) { u1 = strlen(sl->str); if(u1 > u3 && u1 <= u2 && !strncmp(sf_dev, sl->str, u1)) { u3 = u1; s = sl->str; } } if(s) { ADD2LOG(" if: %s @ %s\n", hd->sysfs_bus_id, hd_sysfs_id(s)); sf_dev_2 = new_str(s); if(sf_dev_2) { if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev_2, "bDeviceClass"), &ul0, 16)) { usb->d_cls = ul0; ADD2LOG(" bDeviceClass = %u\n", usb->d_cls); } if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev_2, "bDeviceSubClass"), &ul0, 16)) { usb->d_sub = ul0; ADD2LOG(" bDeviceSubClass = %u\n", usb->d_sub); } if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev_2, "bDeviceProtocol"), &ul0, 16)) { usb->d_prot = ul0; ADD2LOG(" bDeviceProtocol = %u\n", usb->d_prot); } if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev_2, "idVendor"), &ul0, 16)) { usb->vendor = ul0; ADD2LOG(" idVendor = 0x%04x\n", usb->vendor); } if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev_2, "idProduct"), &ul0, 16)) { usb->device = ul0; ADD2LOG(" idProduct = 0x%04x\n", usb->device); } if((s = get_sysfs_attr_by_path(sf_dev_2, "manufacturer"))) { usb->manufact = canon_str(s, strlen(s)); ADD2LOG(" manufacturer = \"%s\"\n", usb->manufact); } if((s = get_sysfs_attr_by_path(sf_dev_2, "product"))) { usb->product = canon_str(s, strlen(s)); ADD2LOG(" product = \"%s\"\n", usb->product); } if((s = get_sysfs_attr_by_path(sf_dev_2, "serial"))) { usb->serial = canon_str(s, strlen(s)); ADD2LOG(" serial = \"%s\"\n", usb->serial); } if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev_2, "bcdDevice"), &ul0, 16)) { usb->rev = ul0; ADD2LOG(" bcdDevice = %04x\n", usb->rev); } if((s = get_sysfs_attr_by_path(sf_dev_2, "speed"))) { s = canon_str(s, strlen(s)); if(!strcmp(s, "1.5")) usb->speed = 15*100000; else if(!strcmp(s, "12")) usb->speed = 12*1000000; else if(!strcmp(s, "480")) usb->speed = 480*1000000; ADD2LOG(" speed = \"%s\"\n", s); s = free_mem(s); } sf_dev_2 = free_mem(sf_dev_2); } } if(usb->vendor || usb->device) { hd->vendor.id = MAKE_ID(TAG_USB, usb->vendor); hd->device.id = MAKE_ID(TAG_USB, usb->device); } if(usb->manufact) hd->vendor.name = new_str(usb->manufact); if(usb->product) hd->device.name = new_str(usb->product); if(usb->serial) hd->serial = new_str(usb->serial); if(usb->rev) str_printf(&hd->revision.name, 0, "%x.%02x", usb->rev >> 8, usb->rev & 0xff); if(usb->speed) { res = add_res_entry(&hd->res, new_mem(sizeof *res)); res->baud.type = res_baud; res->baud.speed = usb->speed; } s = hd_sysfs_find_driver(hd_data, hd->sysfs_id, 1); if(s) add_str_list(&hd->drivers, s); set_class_entries(hd_data, hd, usb); if(!hd_data->scanner_db) { hd_data->scanner_db = hd_module_list(hd_data, 1); } if( hd->drivers && search_str_list(hd_data->scanner_db, hd->drivers->str) ) { hd->base_class.id = bc_scanner; } // ###### FIXME if(hd->base_class.id == bc_modem) { hd->unix_dev_name = new_str("/dev/ttyACM0"); } } sf_dev = free_mem(sf_dev); }
void get_block_devs(hd_data_t *hd_data) { str_list_t *sl; char *s, *t; unsigned u1, u2, u3; uint64_t ul0; hd_t *hd, *hd1; hd_dev_num_t dev_num; str_list_t *sf_class, *sf_class_e; char *sf_cdev = NULL, *sf_dev = NULL, *sf_dev_ide; char *sf_drv_name, *sf_drv, *bus_id, *bus_name, *ide_bus_id; str_list_t *sf_bus, *sf_bus_e; sf_bus = reverse_str_list(read_dir("/sys/bus/ide/devices", 'l')); if(sf_bus) { for(sf_bus_e = sf_bus; sf_bus_e; sf_bus_e = sf_bus_e->next) { sf_dev = new_str(hd_read_sysfs_link("/sys/bus/ide/devices", sf_bus_e->str)); ADD2LOG( " ide: bus_id = %s path = %s\n", sf_bus_e->str, hd_sysfs_id(sf_dev) ); free_mem(sf_dev); } } sf_class = reverse_str_list(read_dir("/sys/block", 'd')); if(!sf_class) { ADD2LOG("sysfs: no such class: block\n"); return; } for(sf_class_e = sf_class; sf_class_e; sf_class_e = sf_class_e->next) { str_printf(&sf_cdev, 0, "/sys/block/%s", sf_class_e->str); ADD2LOG( " block: name = %s, path = %s\n", sf_class_e->str, hd_sysfs_id(sf_cdev) ); memset(&dev_num, 0, sizeof dev_num); if((s = get_sysfs_attr_by_path(sf_cdev, "dev"))) { if(sscanf(s, "%u:%u", &u1, &u2) == 2) { dev_num.type = 'b'; dev_num.major = u1; dev_num.minor = u2; dev_num.range = 1; } ADD2LOG(" dev = %u:%u\n", u1, u2); } if(hd_attr_uint(get_sysfs_attr_by_path(sf_cdev, "range"), &ul0, 0)) { dev_num.range = ul0; ADD2LOG(" range = %u\n", dev_num.range); } sf_dev = new_str(hd_read_sysfs_link(sf_cdev, "device")); sf_drv_name = NULL; sf_drv = hd_read_sysfs_link(sf_dev, "driver"); if(!sf_drv) { /* maybe older kernel */ sf_drv = hd_read_sysfs_link(sf_cdev, "driver"); } if(sf_drv) { sf_drv_name = strrchr(sf_drv, '/'); if(sf_drv_name) sf_drv_name++; } sf_drv_name = new_str(sf_drv_name); bus_id = sf_dev ? strrchr(sf_dev, '/') : NULL; if(bus_id) bus_id++; bus_name = NULL; if((s = hd_read_sysfs_link(sf_dev, "bus"))) { bus_name = strrchr(s, '/'); if(bus_name) bus_name++; bus_name = new_str(bus_name); } if(sf_dev) { ADD2LOG( " block device: bus = %s, bus_id = %s driver = %s\n path = %s\n", bus_name, bus_id, sf_drv_name, hd_sysfs_id(sf_dev) ); } hd = NULL; #if defined(__s390x__) || defined(__s390__) /* check if disk is DASD and has already been found by s390.c */ if(sf_drv_name && strstr(sf_drv_name,"dasd")) { char bid[9]; hd_res_t* res; //fprintf(stderr,"dn %s bi %s\n",sf_drv_name,bus_id); for(hd=hd_data->hd; hd; hd=hd->next) { //fprintf(stderr,"bcid %d\n",hd->base_class.id); if(hd->base_class.id == bc_storage_device && hd->detail && hd->detail->ccw.type == hd_detail_ccw) { for(res=hd->res; res; res=res->next) { if(res->io.type==res_io) { sprintf(bid,"%01x.%01x.%04x", hd->detail->ccw.data->lcss >> 8, hd->detail->ccw.data->lcss & 0xff, (unsigned short)res->io.base); //fprintf(stderr,"bid %s\n",bid); if (strcmp(bid,bus_id)==0) goto out; } } } } hd=NULL; out: ; }
void int_bios(hd_data_t *hd_data) { hd_t *hd, *hd_boot; unsigned *sctrl, *sctrl2; int sctrl_len, i, j; int bios_id, list_sorted; /* don't do anything if there is useful edd info */ if(hd_data->flags.edd_used) return; for(i = 0, hd = hd_data->hd; hd; hd = hd->next) { if( hd->base_class.id == bc_storage_device && hd->sub_class.id == sc_sdev_disk ) { i++; } } if(!i) return; sctrl = new_mem(i * sizeof *sctrl); /* sctrl: list of storage controllers with disks */ for(sctrl_len = 0, hd = hd_data->hd; hd; hd = hd->next) { if( hd->base_class.id == bc_storage_device && hd->sub_class.id == sc_sdev_disk ) { for(i = 0; i < sctrl_len; i++) { if(sctrl[i] == hd->attached_to) break; } if(i == sctrl_len) sctrl[sctrl_len++] = hd->attached_to; } } /* sort list, if possible */ list_sorted = bios_ctrl_order(hd_data, sctrl, sctrl_len); hd_boot = hd_get_device_by_idx(hd_data, hd_boot_disk(hd_data, &i)); /* if we know the boot device, make this controller the first */ if(hd_boot && hd_boot->attached_to && i == 1) { for(i = 0; i < sctrl_len; i++) { if(sctrl[i] == hd_boot->attached_to) break; } if(i < sctrl_len) { sctrl2 = new_mem(sctrl_len * sizeof *sctrl2); *sctrl2 = hd_boot->attached_to; for(i = 0, j = 1; i < sctrl_len; i++) { if(sctrl[i] != hd_boot->attached_to) sctrl2[j++] = sctrl[i]; } free_mem(sctrl); sctrl = sctrl2; } } else { hd_boot = NULL; } if(hd_boot) ADD2LOG(" bios boot dev: %d\n", hd_boot->idx); for(i = 0; i < sctrl_len; i++) { ADD2LOG(" bios ctrl %d: %d\n", i, sctrl[i]); } /* remove existing entries */ for(hd = hd_data->hd; hd; hd = hd->next) { if( hd->base_class.id == bc_storage_device && hd->sub_class.id == sc_sdev_disk ) { hd->rom_id = free_mem(hd->rom_id); } } if(!list_sorted && !hd_boot && sctrl_len > 1) { /* we have no info at all */ sctrl_len = 0; } else if(!list_sorted && hd_boot && sctrl_len > 2) { /* we know which controller has the boot device */ sctrl_len = 1; } bios_id = 0x80; /* rely on it */ if(hd_boot) { bios_id += set_bios_id(hd_data, hd_boot, bios_id); } /* assign all the others */ for(i = 0; i < sctrl_len; i++) { for(hd = hd_data->hd; hd; hd = hd->next) { if( hd->base_class.id == bc_storage_device && hd->sub_class.id == sc_sdev_disk && hd->attached_to == sctrl[i] && !hd->rom_id ) { bios_id += set_bios_id(hd_data, hd, bios_id); } } } free_mem(sctrl); }
int bios_ctrl_order(hd_data_t *hd_data, unsigned *sctrl, int sctrl_len) { hd_t *hd; bios_info_t *bt; int i, j, k, sctrl2_len = 0; unsigned pci_slot, pci_func; unsigned *sctrl2 = NULL, *sctrl3 = NULL; int order_info = 0; for(bt = NULL, hd = hd_data->hd; hd; hd = hd->next) { if( hd->base_class.id == bc_internal && hd->sub_class.id == sc_int_bios && hd->detail && hd->detail->type == hd_detail_bios && (bt = hd->detail->bios.data) ) { break; } } if(!bt || !bt->bios32.ok || !bt->bios32.compaq) return 0; sctrl2 = new_mem((sizeof bt->bios32.cpq_ctrl / sizeof *bt->bios32.cpq_ctrl) * sizeof *sctrl2); for(i = 0; (unsigned) i < sizeof bt->bios32.cpq_ctrl / sizeof *bt->bios32.cpq_ctrl; i++) { if( bt->bios32.cpq_ctrl[i].id && !(bt->bios32.cpq_ctrl[i].misc & 0x40) /* bios support ??????? */ ) { pci_slot = PCI_SLOT(bt->bios32.cpq_ctrl[i].devfn) + (bt->bios32.cpq_ctrl[i].bus << 8); pci_func = PCI_FUNC(bt->bios32.cpq_ctrl[i].devfn); for(hd = hd_data->hd; hd; hd = hd->next) { if(hd->bus.id == bus_pci && hd->slot == pci_slot && hd->func == pci_func) { sctrl2[sctrl2_len++] = hd->idx; break; } } } } if(sctrl2_len) order_info = 1; for(i = 0; i < sctrl2_len; i++) { ADD2LOG(" bios ord %d: %d\n", i, sctrl2[i]); } /* sort list */ sctrl3 = new_mem(sctrl_len * sizeof *sctrl3); k = 0 ; for(i = 0; i < sctrl2_len; i++) { for(j = 0; j < sctrl_len; j++) { if(sctrl[j] == sctrl2[i]) { sctrl3[k++] = sctrl[j]; sctrl[j] = 0; break; } } } for(i = 0; i < sctrl_len; i++) { if(sctrl[i] && k < sctrl_len) sctrl3[k++] = sctrl[i]; } memcpy(sctrl, sctrl3, sctrl_len * sizeof *sctrl); free_mem(sctrl2); free_mem(sctrl3); return order_info; }
void int_system(hd_data_t *hd_data) { hd_t *hd_sys; hd_smbios_t *sm; struct { unsigned notebook:1; unsigned notebook_by_mouse:1; unsigned chassis_info:1; enum { v_none = 0, v_ibm = 1, v_toshiba, v_sony } vendor; } is = { }; char *s; struct stat sbuf; sys_info_t *st; hd_sysfsdrv_t *sf; for(hd_sys = hd_data->hd; hd_sys; hd_sys = hd_sys->next) { if( hd_sys->base_class.id == bc_internal && hd_sys->sub_class.id == sc_int_sys ) break; } if(!hd_sys) return; st = hd_sys->detail && hd_sys->detail->type == hd_detail_sys ? hd_sys->detail->sys.data : NULL; if( hd_sys->vendor.name && !strncasecmp(hd_sys->vendor.name, "sony", sizeof "sony" - 1) ) { is.vendor = v_sony; } if( hd_sys->device.name && !strncmp(hd_sys->device.name, "PCG-", sizeof "PCG-" - 1) ) { is.notebook = 1; } for(sm = hd_data->smbios; sm; sm = sm->next) { if( sm->any.type == sm_sysinfo && sm->sysinfo.manuf && !strcasecmp(sm->sysinfo.manuf, "ibm") ) { is.vendor = v_ibm; } if( sm->any.type == sm_sysinfo && sm->sysinfo.manuf && !strcasecmp(sm->sysinfo.manuf, "toshiba") ) { is.vendor = v_toshiba; if(!hd_sys->device.name && !hd_sys->device.id && sm->sysinfo.product) { hd_sys->device.name = new_str(sm->sysinfo.product); } if(!hd_sys->vendor.name && !hd_sys->vendor.id) { hd_sys->vendor.name = new_str("Toshiba"); } } if( sm->any.type == sm_sysinfo && sm->sysinfo.manuf && !strncasecmp(sm->sysinfo.manuf, "sony", sizeof "sony" - 1) ) { is.vendor = v_sony; if(!hd_sys->device.name && !hd_sys->device.id && sm->sysinfo.product) { hd_sys->device.name = new_str(sm->sysinfo.product); if( (s = strchr(hd_sys->device.name, '(')) && hd_sys->device.name[strlen(hd_sys->device.name) - 1] == ')' ) { *s = 0; } } if(!hd_sys->vendor.name && !hd_sys->vendor.id) { hd_sys->vendor.name = new_str("Sony"); } } if(sm->any.type == sm_chassis) { is.chassis_info = 1; if( (sm->chassis.ch_type.id >= 8 && sm->chassis.ch_type.id <= 11) || sm->chassis.ch_type.id == 14 ) { is.notebook = 1; } } /* * bnc #591703 * in case chassis info is missing: assume it's a notebook if * it has track point or touch pad */ if( sm->any.type == sm_mouse && (sm->mouse.mtype.id == 5 || sm->mouse.mtype.id == 7) ) { is.notebook_by_mouse = 1; } } /* use is.notebook_by_mouse only if there's no usable chassis info (bsc #1117982) */ if(!is.notebook) { if(is.notebook_by_mouse && !is.chassis_info) is.notebook = 1; } /* check for battery, too (bnc #678456) */ if(!is.notebook) { for(sf = hd_data->sysfsdrv; sf; sf = sf->next) { if(sf->driver && !strcmp(sf->driver, "battery")) { is.notebook = 1; break; } } } ADD2LOG( " system type:%s%s\n", is.vendor == v_ibm ? " ibm" : is.vendor == v_toshiba ? " toshiba" : is.vendor == v_sony ? " sony" : "", is.notebook ? " notebook" : "" ); if(st && !st->formfactor) { st->formfactor = new_str(is.notebook ? "laptop" : "desktop"); } if(is.notebook && is.vendor) { hd_sys->compat_vendor.id = MAKE_ID(TAG_SPECIAL, 0xf001); hd_sys->compat_device.id = MAKE_ID(TAG_SPECIAL, is.vendor); } hd_sys->is.with_acpi = stat("/proc/acpi", &sbuf) ? 0 : 1; ADD2LOG(" acpi: %d\n", hd_sys->is.with_acpi); }
static int open_interfaces (int n, PPPoEConnection* conns) { int ret = 0, i; for (i = 0; i < n; i++) { PPPoEConnection* conn = &conns[i]; conn->fd = socket (PF_PACKET, SOCK_RAW, htons (ETH_PPPOE_DISCOVERY)); if (conn->fd < 0) { ADD2LOG ("%s: socket failed: %m\n", conn->ifname); continue; } int one = 1; if (setsockopt (conn->fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof (one)) < 0) { ADD2LOG ("%s: setsockopt failed: %m\n", conn->ifname); goto error; } /* Fill in hardware address */ struct ifreq ifr; struct sockaddr_ll sa; memset (&sa, 0, sizeof (sa)); strncpy (ifr.ifr_name, conn->ifname, sizeof (ifr.ifr_name)); if (ioctl (conn->fd, SIOCGIFHWADDR, &ifr) < 0) { ADD2LOG ("%s: ioctl (SIOCGIFHWADDR) failed: %m\n", conn->ifname); goto error; } memcpy (conn->my_mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN); if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { ADD2LOG ("%s: Interface is not ethernet\n", conn->ifname); goto error; } if (NOT_UNICAST (conn->my_mac)) { ADD2LOG ("%s: Interface has broadcast/multicast MAC address?\n", conn->ifname); goto error; } /* Sanity check on MTU */ strncpy (ifr.ifr_name, conn->ifname, sizeof (ifr.ifr_name)); if (ioctl (conn->fd, SIOCGIFMTU, &ifr) < 0) { ADD2LOG ("%s: ioctl (SIOCGIFMTU) failed: %m\n", conn->ifname); goto error; } if (ifr.ifr_mtu < ETH_DATA_LEN) { ADD2LOG ("%s: Interface has too low MTU\n", conn->ifname); goto error; } /* Skip interfaces that have the SLAVE flag set */ strncpy (ifr.ifr_name, conn->ifname, sizeof (ifr.ifr_name)); if (ioctl (conn->fd, SIOCGIFFLAGS, &ifr) < 0) { ADD2LOG ("%s: ioctl (SIOCGIFFLAGS) failed: %m\n", conn->ifname); goto error; } if (ifr.ifr_ifru.ifru_flags & IFF_SLAVE) { ADD2LOG ("%s: Interface has SLAVE flag set\n", conn->ifname); goto error; } /* Get interface index */ sa.sll_family = AF_PACKET; sa.sll_protocol = htons (ETH_PPPOE_DISCOVERY); strncpy (ifr.ifr_name, conn->ifname, sizeof (ifr.ifr_name)); if (ioctl (conn->fd, SIOCGIFINDEX, &ifr) < 0) { ADD2LOG ("%s: ioctl (SIOCFIGINDEX) failed: Could not get interface " "index\n", conn->ifname); goto error; } sa.sll_ifindex = ifr.ifr_ifindex; /* We're only interested in packets on specified interface */ if (bind (conn->fd, (struct sockaddr*) &sa, sizeof (sa)) < 0) { ADD2LOG ("%s: bind failed: %m\n", conn->ifname); goto error; } ret = 1; continue; error: close (conn->fd); conn->fd = -1; } return ret; }
static int send_padi (int n, PPPoEConnection* conns) { int ret = 0, i; for (i = 0; i < n; i++) { PPPoEConnection* conn = &conns[i]; if (conn->fd == -1 || conn->received_pado) continue; PPPoEPacket packet; unsigned char* cursor = packet.payload; PPPoETag* svc = (PPPoETag*) (&packet.payload); uint16_t namelen = 0; uint16_t plen; namelen = 0; plen = TAG_HDR_SIZE + namelen; if (!check_room (conn, cursor, packet.payload, TAG_HDR_SIZE)) continue; /* Set destination to Ethernet broadcast address */ memset (packet.ethHdr.h_dest, 0xFF, ETH_ALEN); memcpy (packet.ethHdr.h_source, conn->my_mac, ETH_ALEN); packet.ethHdr.h_proto = htons (ETH_PPPOE_DISCOVERY); packet.ver = 1; packet.type = 1; packet.code = CODE_PADI; packet.session = 0; svc->type = TAG_SERVICE_NAME; svc->length = htons (0); if (!check_room (conn, cursor, packet.payload, namelen + TAG_HDR_SIZE)) continue; cursor += namelen + TAG_HDR_SIZE; PPPoETag hostUniq; pid_t pid = getpid (); hostUniq.type = htons (TAG_HOST_UNIQ); hostUniq.length = htons (sizeof (pid)); memcpy (hostUniq.payload, &pid, sizeof (pid)); if (!check_room (conn, cursor, packet.payload, sizeof (pid) + TAG_HDR_SIZE)) continue; memcpy (cursor, &hostUniq, sizeof (pid) + TAG_HDR_SIZE); cursor += sizeof (pid) + TAG_HDR_SIZE; plen += sizeof (pid) + TAG_HDR_SIZE; packet.length = htons (plen); ADD2LOG ("%s: Sending PADI packet\n", conn->ifname); if (send_packet (conn->fd, &packet, (int) (plen + HDR_SIZE))) ret = 1; } return ret; }
void hd_scan_manual(hd_data_t *hd_data) { DIR *dir; struct dirent *de; int i, j; hd_t *hd, *hd1, *next, *hdm, **next2; char *s; char *udi_dir[] = { "/org/freedesktop/Hal/devices", "", "" }; if(!hd_probe_feature(hd_data, pr_manual)) return; hd_data->module = mod_manual; /* some clean-up */ remove_hd_entries(hd_data); for(hd = hd_data->manual; hd; hd = next) { next = hd->next; hd->next = NULL; hd_free_hd_list(hd); } hd_data->manual = NULL; next2 = &hd_data->manual; s = NULL; for(j = 0; j < sizeof udi_dir / sizeof *udi_dir; j++) { str_printf(&s, 0, "%s%s", j == 2 ? "unique-keys" : "udi", udi_dir[j]); if((dir = opendir(hd_get_hddb_path(s)))) { i = 0; while((de = readdir(dir))) { if(*de->d_name == '.') continue; PROGRESS(1, ++i, "read"); str_printf(&s, 0, "%s%s%s", udi_dir[j], *udi_dir[j] ? "/" : "", de->d_name); if((hd = hd_read_config(hd_data, s))) { if(hd->status.available != status_unknown) hd->status.available = status_no; ADD2LOG(" got %s\n", hd->unique_id); *next2 = hd; next2 = &hd->next; } } closedir(dir); } } s = free_mem(s); hd_data->flags.keep_kmods = 1; for(hdm = hd_data->manual; hdm; hdm = next) { next = hdm->next; for(hd = hd_data->hd; hd; hd = hd->next) { if(hd->unique_id && hdm->unique_id && !strcmp(hd->unique_id, hdm->unique_id)) break; } if(hd) { /* just update config status */ hd->status = hdm->status; if(hd->status.available != status_unknown) hd->status.available = status_yes; if(hdm->config_string) hd->config_string = new_str(hdm->config_string); if(hdm->persistent_prop) { hd->persistent_prop = hdm->persistent_prop; hdm->persistent_prop = NULL; } } else { /* add new entry */ hd = add_hd_entry(hd_data, __LINE__, 0); *hd = *hdm; hd->next = NULL; hd->tag.freeit = 0; hdm->tag.remove = 1; if(hd->status.available != status_unknown) hd->status.available = status_no; // FIXME: do it really here? if(hd->parent_id) { for(hd1 = hd_data->hd; hd1; hd1 = hd1->next) { if(hd1->unique_id && !strcmp(hd1->unique_id, hd->parent_id)) { hd->attached_to = hd1->idx; break; } } } } } hd_data->flags.keep_kmods = 0; for(hd = hd_data->manual; hd; hd = next) { next = hd->next; hd->next = NULL; if(!hd->tag.remove) { hd_free_hd_list(hd); } else { free_mem(hd); } } hd_data->manual = NULL; }
/* * Get the (raw) PCI data, taken from /sys/bus/pci. * * Note: non-root users can only read the first 64 bytes (of 256) * of the device headers. */ void hd_pci_read_data(hd_data_t *hd_data) { uint64_t ul0, ul1, ul2; unsigned u, u0, u1, u2, u3; unsigned char nxt; str_list_t *sl; char *s; pci_t *pci; int fd, i; str_list_t *sf_bus, *sf_bus_e; char *sf_dev; sf_bus = reverse_str_list(read_dir("/sys/bus/pci/devices", 'l')); if(!sf_bus) { ADD2LOG("sysfs: no such bus: pci\n"); return; } for(sf_bus_e = sf_bus; sf_bus_e; sf_bus_e = sf_bus_e->next) { sf_dev = new_str(hd_read_sysfs_link("/sys/bus/pci/devices", sf_bus_e->str)); ADD2LOG( " pci device: name = %s\n path = %s\n", sf_bus_e->str, hd_sysfs_id(sf_dev) ); if(sscanf(sf_bus_e->str, "%x:%x:%x.%x", &u0, &u1, &u2, &u3) != 4) continue; pci = add_pci_entry(hd_data, new_mem(sizeof *pci)); pci->sysfs_id = new_str(sf_dev); pci->sysfs_bus_id = new_str(sf_bus_e->str); pci->bus = (u0 << 8) + u1; pci->slot = u2; pci->func = u3; if((s = get_sysfs_attr_by_path(sf_dev, "modalias"))) { pci->modalias = canon_str(s, strlen(s)); ADD2LOG(" modalias = \"%s\"\n", pci->modalias); } if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "class"), &ul0, 0)) { ADD2LOG(" class = 0x%x\n", (unsigned) ul0); pci->prog_if = ul0 & 0xff; pci->sub_class = (ul0 >> 8) & 0xff; pci->base_class = (ul0 >> 16) & 0xff; } if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "vendor"), &ul0, 0)) { ADD2LOG(" vendor = 0x%x\n", (unsigned) ul0); pci->vend = ul0 & 0xffff; } if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "device"), &ul0, 0)) { ADD2LOG(" device = 0x%x\n", (unsigned) ul0); pci->dev = ul0 & 0xffff; } if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "subsystem_vendor"), &ul0, 0)) { ADD2LOG(" subvendor = 0x%x\n", (unsigned) ul0); pci->sub_vend = ul0 & 0xffff; } if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "subsystem_device"), &ul0, 0)) { ADD2LOG(" subdevice = 0x%x\n", (unsigned) ul0); pci->sub_dev = ul0 & 0xffff; } if(hd_attr_uint(get_sysfs_attr_by_path(sf_dev, "irq"), &ul0, 0)) { ADD2LOG(" irq = %d\n", (unsigned) ul0); pci->irq = ul0; } sl = hd_attr_list(get_sysfs_attr_by_path(sf_dev, "resource")); for(u = 0; sl; sl = sl->next, u++) { if( sscanf(sl->str, "0x%"SCNx64" 0x%"SCNx64" 0x%"SCNx64, &ul0, &ul1, &ul2) == 3 && ul1 && u < sizeof pci->base_addr / sizeof *pci->base_addr ) { ADD2LOG(" res[%u] = 0x%"PRIx64" 0x%"PRIx64" 0x%"PRIx64"\n", u, ul0, ul1, ul2); pci->base_addr[u] = ul0; pci->base_len[u] = ul1 + 1 - ul0; pci->addr_flags[u] = ul2; } } s = NULL; str_printf(&s, 0, "%s/config", sf_dev); if((fd = open(s, O_RDONLY)) != -1) { pci->data_len = pci->data_ext_len = read(fd, pci->data, 0x40); ADD2LOG(" config[%u]\n", pci->data_len); if(pci->data_len >= 0x40) { pci->hdr_type = pci->data[PCI_HEADER_TYPE] & 0x7f; pci->cmd = pci->data[PCI_COMMAND] + (pci->data[PCI_COMMAND + 1] << 8); if(pci->hdr_type == 1 || pci->hdr_type == 2) { /* PCI or CB bridge */ pci->secondary_bus = pci->data[PCI_SECONDARY_BUS]; /* PCI_SECONDARY_BUS == PCI_CB_CARD_BUS */ } for(u = 0; u < sizeof pci->base_addr / sizeof *pci->base_addr; u++) { if((pci->addr_flags[u] & IORESOURCE_IO)) { if(!(pci->cmd & PCI_COMMAND_IO)) pci->addr_flags[u] |= IORESOURCE_DISABLED; } if((pci->addr_flags[u] & IORESOURCE_MEM)) { if(!(pci->cmd & PCI_COMMAND_MEMORY)) pci->addr_flags[u] |= IORESOURCE_DISABLED; } } /* let's go through the capability list */ if( pci->hdr_type == PCI_HEADER_TYPE_NORMAL && (nxt = pci->data[PCI_CAPABILITY_LIST]) ) { /* * Cut out after 16 capabilities to avoid infinite recursion due * to (potentially) malformed data. 16 is more or less * arbitrary, though (the capabilities are bits in a byte, so 8 entries * should suffice). */ for(u = 0; u < 16 && nxt && nxt <= 0xfe; u++) { switch(pci_cfg_byte(pci, fd, nxt)) { case PCI_CAP_ID_PM: pci->flags |= (1 << pci_flag_pm); break; case PCI_CAP_ID_AGP: pci->flags |= (1 << pci_flag_agp); break; } nxt = pci_cfg_byte(pci, fd, nxt + 1); } } } close(fd); } str_printf(&s, 0, "%s/edid1", sf_dev); if((fd = open(s, O_RDONLY)) != -1) { pci->edid_len = read(fd, pci->edid, sizeof pci->edid); ADD2LOG(" edid[%u]\n", pci->edid_len); if(pci->edid_len > 0) { for(i = 0; i < sizeof pci->edid; i += 0x10) { ADD2LOG(" "); hexdump(&hd_data->log, 1, 0x10, pci->edid + i); ADD2LOG("\n"); } } close(fd); } s = free_mem(s); pci->rev = pci->data[PCI_REVISION_ID]; if((pci->addr_flags[6] & IORESOURCE_MEM)) { if(!(pci->data[PCI_ROM_ADDRESS] & PCI_ROM_ADDRESS_ENABLE)) { pci->addr_flags[6] |= IORESOURCE_DISABLED; } } pci->flags |= (1 << pci_flag_ok); free_mem(sf_dev); }
void hd_scan_pppoe(hd_data_t *hd_data2) { hd_t *hd; int cnt, interfaces; PPPoEConnection *conn; hd_data = hd_data2; if(!hd_probe_feature(hd_data, pr_pppoe)) return; hd_data->module = mod_pppoe; PROGRESS(1, 0, "looking for pppoe"); for(interfaces = 0, hd = hd_data->hd; hd; hd = hd->next) { if( hd->base_class.id == bc_network_interface && hd->sub_class.id == sc_nif_ethernet && hd->unix_dev_name ) { interfaces++; } } if(!interfaces) return; conn = new_mem(interfaces * sizeof *conn); for(cnt = 0, hd = hd_data->hd; hd && cnt < interfaces; hd = hd->next) { if( hd->base_class.id == bc_network_interface && hd->sub_class.id == sc_nif_ethernet && hd->unix_dev_name ) { conn[cnt].hd = hd; conn[cnt].fd = -1; conn[cnt].ifname = hd->unix_dev_name; cnt++; } } PROGRESS(2, 0, "discovery"); discovery(interfaces, conn); for(cnt = 0; cnt < interfaces; cnt++) { conn[cnt].hd->is.pppoe = 0; if(conn[cnt].received_pado) { conn[cnt].hd->is.pppoe = 1; ADD2LOG( "pppoe %s: my mac %02x:%02x:%02x:%02x:%02x:%02x, " "peer mac %02x:%02x:%02x:%02x:%02x:%02x\n", conn[cnt].ifname, conn[cnt].my_mac[0], conn[cnt].my_mac[1], conn[cnt].my_mac[2], conn[cnt].my_mac[3], conn[cnt].my_mac[4], conn[cnt].my_mac[5], conn[cnt].peer_mac[0], conn[cnt].peer_mac[1], conn[cnt].peer_mac[2], conn[cnt].peer_mac[3], conn[cnt].peer_mac[4], conn[cnt].peer_mac[5] ); } } }
static int wait_for_pado (int n, PPPoEConnection* conns) { int r, i, all; size_t len; fd_set readable; PPPoEPacket packet; PacketCriteria pc; struct timeval tv; tv.tv_sec = PADO_TIMEOUT; tv.tv_usec = 0; while (1) { FD_ZERO (&readable); for (i = 0; i < n; i++) if (conns[i].fd != -1) FD_SET (conns[i].fd, &readable); do { r = select (FD_SETSIZE, &readable, NULL, NULL, &tv); } while (r == -1 && errno == EINTR); if (r < 0) { ADD2LOG ("select: %m\n"); return 0; } if (r == 0) { ADD2LOG ("Timeout waiting for PADO packets\n"); return 0; } for (i = 0; i < n; i++) { PPPoEConnection* conn = &conns[i]; if (conn->fd == -1 || !FD_ISSET (conn->fd, &readable)) continue; pc.conn = conn; pc.acname_ok = 0; pc.servicename_ok = 0; pc.error = 0; /* Get the packet */ if (!receive_packet (conn->fd, &packet, &len)) continue; /* Check length */ if (ntohs (packet.length) + HDR_SIZE > len) { ADD2LOG ("%s: Bogus PPPoE length field (%u)\n", conn->ifname, (unsigned int) ntohs (packet.length)); continue; } /* If it's not for us, loop again */ if (!packet_for_me (conn, &packet)) continue; if (packet.code != CODE_PADO) continue; if (NOT_UNICAST (packet.ethHdr.h_source)) { ADD2LOG ("%s: Ignoring PADO packet from non-unicast MAC " "address\n", conn->ifname); continue; } parse_packet (conn, &packet, parse_pado_tags, &pc); if (!pc.acname_ok) { ADD2LOG ("%s: Wrong or missing AC-Name tag\n", conn->ifname); continue; } if (!pc.servicename_ok) { ADD2LOG ("%s: Wrong or missing Service-Name tag\n", conn->ifname); continue; } if (pc.error) { ADD2LOG ("%s: Ignoring PADO packet with some Error tag\n", conn->ifname); continue; } memcpy (conn->peer_mac, packet.ethHdr.h_source, ETH_ALEN); ADD2LOG ("%s: Received correct PADO packet\n", conn->ifname); conn->received_pado = 1; } all = 1; for (i = 0; i < n; i++) if (conns[i].fd != -1 && !conns[i].received_pado) all = 0; if (all) return 1; } }