int usb_get_driver_np(usb_dev_handle *dev, int interface, char *name, unsigned int namelen) { // Get remote fd Packet* pkt = pkt_claim(); int fd = session_get(); // Send packet pkt_init(pkt, UsbGetKernelDriver); pkt_addint(pkt, dev->fd); pkt_addint(pkt, interface); pkt_adduint(pkt, namelen); pkt_send(pkt, fd); // Get response int res = -1; if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbGetKernelDriver) { Iterator it; pkt_begin(pkt, &it); res = iter_getint(&it); // Error if(res) { error_msg("%s: could not get bound driver", __func__); } // Save string strncpy(name, iter_getstr(&it), namelen - 1); name[namelen - 1] = '\0'; } pkt_release(); debug_msg("returned %d (%s)", res, name); return res; }
/* libusb(5): * Interrupt transfers. */ int usb_interrupt_write(usb_dev_handle *dev, int ep, usb_buf_t bytes, int size, int timeout) { // Get remote fd Packet* pkt = pkt_claim(); int fd = session_get(); // Prepare packet pkt_init(pkt, UsbInterruptWrite); pkt_addint(pkt, dev->fd); pkt_addint(pkt, ep); pkt_addstr(pkt, size, bytes); pkt_addint(pkt, timeout); pkt_send(pkt, fd); // Get response int res = -1; if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbInterruptWrite) { Iterator it; pkt_begin(pkt, &it); res = iter_getint(&it); } // Return response pkt_release(); debug_msg("returned %d", res); return res; }
int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) { // Get remote fd Packet* pkt = pkt_claim(); int fd = session_get(); // Prepare packet pkt_init(pkt, UsbInterruptRead); pkt_addint(pkt, dev->fd); pkt_addint(pkt, ep); pkt_addint(pkt, size); pkt_addint(pkt, timeout); pkt_send(pkt, fd); // Get response int res = -1; if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbInterruptRead) { Iterator it; pkt_begin(pkt, &it); res = iter_getint(&it); if(res > 0) { int minlen = (res > size) ? size : res; memcpy(bytes, it.val, minlen); } } // Return response pkt_release(); debug_msg("returned %d", res); return res; }
int usb_reset(usb_dev_handle *dev) { // Get remote fd Packet* pkt = pkt_claim(); int fd = session_get(); // Prepare packet pkt_init(pkt, UsbReset); pkt_addint(pkt, dev->fd); pkt_send(pkt, fd); // Get response int res = -1; if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbReset) { Iterator it; pkt_begin(pkt, &it); // Read result res = iter_getint(&it); } // Return response pkt_release(); debug_msg("returned %d", res); return res; }
int usb_close(usb_dev_handle *dev) { // Get remote fd Packet* pkt = pkt_claim(); int fd = session_get(); // Send packet pkt_init(pkt, UsbClose); pkt_addint(pkt, dev->fd); pkt_send(pkt, fd); // Free device free(dev); // Get response int res = -1; if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbClose) { Iterator it; pkt_begin(pkt, &it); res = iter_getint(&it); } pkt_release(); debug_msg("returned %d", res); return res; }
int usb_set_altinterface(usb_dev_handle *dev, int alternate) { // Get remote fd Packet* pkt = pkt_claim(); int fd = session_get(); // Prepare packet pkt_init(pkt, UsbSetAltInterface); pkt_addint(pkt, dev->fd); pkt_addint(pkt, alternate); pkt_send(pkt, fd); // Get response int res = -1; if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbSetAltInterface) { Iterator it; pkt_begin(pkt, &it); // Read result res = iter_getint(&it); // Read callback configuration alternate = iter_getint(&it); } // Save configuration dev->altsetting = alternate; // Return response pkt_release(); debug_msg("returned %d", res); return res; }
usb_dev_handle *usb_open(struct usb_device *dev) { // Get remote fd Packet* pkt = pkt_claim(); int fd = session_get(); // Send packet pkt_init(pkt, UsbOpen); pkt_adduint(pkt, dev->bus->location); pkt_adduint(pkt, dev->devnum); pkt_send(pkt, fd); // Get response int res = -1, devfd = -1; if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbOpen) { Iterator it; pkt_begin(pkt, &it); res = iter_getint(&it); devfd = iter_getint(&it); } // Evaluate usb_dev_handle* udev = NULL; if(res >= 0) { udev = malloc(sizeof(usb_dev_handle)); udev->fd = devfd; udev->device = dev; udev->bus = dev->bus; udev->config = udev->interface = udev->altsetting = -1; } pkt_release(); debug_msg("returned %d (fd %d)", res, devfd); return udev; }
/** * Release the hardware driver. */ void _eth_release (void) { if (!_eth_is_init) return; /* Set original MAC address (if not fatal-error or serial-driver) */ if (!_watt_fatal_error) { if (!_pktserial) { if (memcmp(&_eth_addr, &_eth_real_addr, sizeof(_eth_addr))) pkt_set_addr (&_eth_real_addr); #if defined(USE_MULTICAST) || defined(USE_IPV6) /* restore startup Rx mode */ if (_pkt_rxmode0 > -1 && _pkt_rxmode0 != _pkt_rxmode) pkt_set_rcv_mode (_pkt_rxmode0); #endif } #if defined(USE_DEBUG) if (debug_on > 0) { DWORD drops = pkt_dropped(); if (drops) (*_printf) ("%lu packets dropped\n", drops); } #endif } _eth_is_init = FALSE; /* in case we crash in pkt_release() */ pkt_release(); }
/** Initialize USB subsystem. */ void usb_init(void) { // Initialize packet & remote fd Packet* pkt = pkt_claim(); int fd = session_get(); // Create buffer pkt_init(pkt, UsbInit); pkt_send(pkt, fd); pkt_release(); // Initialize locally debug_msg("called"); }
int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout) { // Get remote fd Packet* pkt = pkt_claim(); int fd = session_get(); // Prepare packet pkt_init(pkt, UsbControlMsg); pkt_addint(pkt, dev->fd); pkt_addint(pkt, requesttype); pkt_addint(pkt, request); pkt_addint(pkt, value); pkt_addint(pkt, index); pkt_addstr(pkt, size, bytes); pkt_addint(pkt, timeout); pkt_send(pkt, fd); // Get response int res = -1; if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbControlMsg) { Iterator it; pkt_begin(pkt, &it); res = iter_getint(&it); if(res > 0) { int minlen = (res > size) ? size : res; memcpy(bytes, it.val, minlen); } } // Return response pkt_release(); debug_msg("returned %d", res); return res; }
int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface) { // Get remote fd Packet* pkt = pkt_claim(); int fd = session_get(); // Send packet pkt_init(pkt, UsbDetachKernelDriver); pkt_addint(pkt, dev->fd); pkt_addint(pkt, interface); pkt_send(pkt, fd); // Get response int res = -1; if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbDetachKernelDriver) { Iterator it; pkt_begin(pkt, &it); res = iter_getint(&it); } pkt_release(); debug_msg("returned %d", res); return res; }
/** Find busses on remote host. \warning Does not transfer busses to local virtual bus list. */ int usb_find_busses(void) { // Get remote fd Packet* pkt = pkt_claim(); int fd = session_get(); // Initialize pkt pkt_init(pkt, UsbFindBusses); pkt_send(pkt, fd); // Get number of changes int res = 0; Iterator it; if(pkt_recv(fd, pkt) > 0 && pkt_op(pkt) == UsbFindBusses) { if(pkt_begin(pkt, &it) != NULL) { res = iter_getint(&it); } } // Return remote result pkt_release(); debug_msg("returned %d", res); return res; }
/** * Initialise WinPcap and return our MAC address. */ int pkt_eth_init (mac_address *mac_addr) { struct { PACKET_OID_DATA oidData; char descr[512]; } oid; const ADAPTER *adapter = NULL; DWORD thread_id; BOOL is_up; if (_watt_is_win9x) /**< \todo Support Win-9x too */ { (*_printf) (_LANG("Win-NT or later reqired.\n")); _pkt_errno = PDERR_GEN_FAIL; return (WERR_ILL_DOSX); } if (!_watt_no_config || _watt_user_config_fn) parse_config_pass_1(); _pkt_inf = calloc (sizeof(*_pkt_inf), 1); if (!_pkt_inf) { (*_printf) (_LANG("Failed to allocate WinPcap DRIVER data.\n")); _pkt_errno = PDERR_GEN_FAIL; return (WERR_NO_MEM); } if (debug_on >= 2 && dump_fname[0]) dump_file = fopen_excl (ExpandVarStr(dump_fname), "w+t"); if (!PacketInitModule(TRUE, dump_file)) { (*_printf) (_LANG("Failed to initialise WinPcap.\n")); pkt_release(); _pkt_errno = PDERR_NO_DRIVER; return (WERR_PKT_ERROR); } if (!_pktdrvrname[0] && !find_adapter(_pktdrvrname,sizeof(_pktdrvrname))) { (*_printf) (_LANG("No WinPcap driver found.\n")); _pkt_errno = PDERR_NO_DRIVER; return (WERR_NO_DRIVER); } TCP_CONSOLE_MSG (2, ("device %s\n", _pktdrvrname)); adapter = PacketOpenAdapter (_pktdrvrname); if (!adapter) { if (debug_on > 0) (*_printf) (_LANG("PacketOpenAdapter (\"%s\") failed; %s\n"), _pktdrvrname, win_strerror(GetLastError())); pkt_release(); return (WERR_NO_DRIVER); } _pkt_inf->adapter = adapter; #if defined(USE_DYN_PACKET) _pkt_inf->adapter_info = NULL; #else _pkt_inf->adapter_info = PacketFindAdInfo (_pktdrvrname); #endif /* Query the NIC driver for the adapter description */ memset (&oid, 0, sizeof(oid)); oid.oidData.Oid = OID_GEN_VENDOR_DESCRIPTION; oid.oidData.Length = sizeof(oid.descr); if (PacketRequest (adapter, FALSE, &oid.oidData)) StrLcpy (_pktdrvr_descr, (char*)oid.oidData.Data, sizeof(_pktdrvr_descr)); else { (*_printf) (_LANG("PacketRequest() failed; %s\n"), win_strerror(GetLastError())); pkt_release(); return (WERR_PKT_ERROR); } if (!get_interface_type(&_pktdevclass)) { pkt_release(); return (WERR_PKT_ERROR); } if (get_connected_status(&is_up) && !is_up) (*_printf) (_LANG("Warning: the adapter %s is down\n"), _pktdrvrname); switch (_pktdevclass) { case PDCLASS_TOKEN: _pkt_ip_ofs = sizeof(tok_Header); break; case PDCLASS_ETHER: _pkt_ip_ofs = sizeof(eth_Header); break; case PDCLASS_FDDI: _pkt_ip_ofs = sizeof(fddi_Header); break; case PDCLASS_ARCNET: _pkt_ip_ofs = ARC_HDRLEN; break; default: pkt_release(); (*_printf) (_LANG("WinPcap-ERROR: Unsupported driver class %dh\n"), _pktdevclass); _pkt_errno = PDERR_NO_CLASS; return (WERR_PKT_ERROR); } if (!pkt_get_addr(mac_addr)) /* get our MAC address */ { pkt_release(); return (WERR_PKT_ERROR); } pktq_init (&_pkt_inf->pkt_queue, sizeof(_pkt_inf->rx_buf[0]), /* RX_SIZE */ DIM(_pkt_inf->rx_buf), /* RX_BUFS */ (char*)&_pkt_inf->rx_buf); _pkt_inf->npf_buf_size = RX_SIZE * pkt_num_rx_bufs; _pkt_inf->npf_buf = malloc (_pkt_inf->npf_buf_size); if (!_pkt_inf->npf_buf) { (*_printf) (_LANG("Failed to allocate %d byte Rx buffer.\n"), _pkt_inf->npf_buf_size); pkt_release(); _pkt_errno = PDERR_GEN_FAIL; return (WERR_NO_MEM); } PacketSetMode (adapter, PACKET_MODE_CAPT); PacketSetBuff (adapter, _pkt_inf->npf_buf_size); PacketSetMinToCopy (adapter, ETH_MIN); /* PacketReceivePacket() blocks until something is received */ PacketSetReadTimeout ((ADAPTER*)adapter, 0); /* Set Rx-mode forced via config. */ if (_pkt_forced_rxmode != -1) { _pkt_forced_rxmode &= 0xFFFF; /* clear bits not set via ARG_ATOX_W */ if (_pkt_forced_rxmode == 0 || /* check illegal bit-values */ (_pkt_forced_rxmode & 0x10) || (_pkt_forced_rxmode & 0x40) || (_pkt_forced_rxmode > 0x80)) { TCP_CONSOLE_MSG (0, ("Illegal Rx-mode (0x%02X) specified\n", _pkt_forced_rxmode)); _pkt_forced_rxmode = -1; } } if (pkt_get_rcv_mode()) _pkt_rxmode0 = _pkt_rxmode; if (_pkt_forced_rxmode != -1) pkt_set_rcv_mode (_pkt_forced_rxmode); else pkt_set_rcv_mode (RXMODE_DEFAULT); #if 1 _pkt_inf->recv_thread = CreateThread (NULL, 2048, pkt_recv_thread, NULL, 0, &thread_id); #else _pkt_inf->recv_thread = _beginthreadex (NULL, 2048, pkt_recv_thread, NULL, 0, &thread_id); #endif if (!_pkt_inf->recv_thread) { (*_printf) (_LANG("Failed to create receiver thread; %s\n"), win_strerror(GetLastError())); pkt_release(); _pkt_errno = PDERR_GEN_FAIL; return (WERR_PKT_ERROR); } if (thr_realtime) SetThreadPriority (_pkt_inf->recv_thread, THREAD_PRIORITY_TIME_CRITICAL); TCP_CONSOLE_MSG (2, ("capture thread-id %lu\n", thread_id)); #if defined(USE_DEBUG) if (debug_on >= 2) { (*_printf) ("link-details:\n"); show_link_details(); } #endif return (0); }
/** Find devices on remote host. * Create new devices on local virtual bus. * \warning Function replaces global usb_busses variable from libusb. */ int usb_find_devices(void) { // Get remote fd Packet* pkt = pkt_claim(); int fd = session_get(); // Create buffer pkt_init(pkt, UsbFindDevices); pkt_send(pkt, fd); // Get number of changes int res = 0; Iterator it; if(pkt_recv(fd, pkt) > 0) { pkt_begin(pkt, &it); // Get return value res = iter_getint(&it); // Allocate virtualbus struct usb_bus vbus; vbus.next = __remote_bus; struct usb_bus* rbus = &vbus; // Get busses while(!iter_end(&it)) { // Evaluate if(it.type == StructureType) { iter_enter(&it); // Allocate bus if(rbus->next == NULL) { // Allocate next item struct usb_bus* nbus = malloc(sizeof(struct usb_bus)); memset(nbus, 0, sizeof(struct usb_bus)); rbus->next = nbus; nbus->prev = rbus; rbus = nbus; } else rbus = rbus->next; // Read dirname strcpy(rbus->dirname, iter_getstr(&it)); // Read location rbus->location = iter_getuint(&it); // Read devices struct usb_device vdev; vdev.next = rbus->devices; struct usb_device* dev = &vdev; while(it.type == SequenceType) { iter_enter(&it); // Initialize if(dev->next == NULL) { dev->next = malloc(sizeof(struct usb_device)); memset(dev->next, 0, sizeof(struct usb_device)); dev->next->bus = rbus; if(dev != &vdev) dev->next->prev = dev; if(rbus->devices == NULL) rbus->devices = dev->next; } dev = dev->next; // Read filename strcpy(dev->filename, iter_getstr(&it)); // Read devnum dev->devnum = iter_getuint(&it); // Read descriptor // Apply byte-order conversion for 16/32bit integers memcpy(&dev->descriptor, it.val, it.len); dev->descriptor.bcdUSB = ntohs(dev->descriptor.bcdUSB); dev->descriptor.idVendor = ntohs(dev->descriptor.idVendor); dev->descriptor.idProduct = ntohs(dev->descriptor.idProduct); dev->descriptor.bcdDevice = ntohs(dev->descriptor.bcdDevice); iter_next(&it); // Alloc configurations unsigned cfgid = 0, cfgnum = dev->descriptor.bNumConfigurations; dev->config = NULL; if(cfgnum > 0) { dev->config = malloc(cfgnum * sizeof(struct usb_config_descriptor)); memset(dev->config, 0, cfgnum * sizeof(struct usb_config_descriptor)); } // Read config while(it.type == RawType && cfgid < cfgnum) { struct usb_config_descriptor* cfg = &dev->config[cfgid]; ++cfgid; // Ensure struct under/overlap int szlen = sizeof(struct usb_config_descriptor); if(szlen > it.len) szlen = it.len; // Read config and apply byte-order conversion memcpy(cfg, it.val, szlen); cfg->wTotalLength = ntohs(cfg->wTotalLength); // Allocate interfaces cfg->interface = NULL; if(cfg->bNumInterfaces > 0) { cfg->interface = malloc(cfg->bNumInterfaces * sizeof(struct usb_interface)); } //! \test Implement usb_device extra interfaces - are they needed? cfg->extralen = 0; cfg->extra = NULL; iter_next(&it); // Load interfaces unsigned i, j, k; for(i = 0; i < cfg->bNumInterfaces; ++i) { struct usb_interface* iface = &cfg->interface[i]; // Read altsettings count iface->num_altsetting = iter_getint(&it); // Allocate altsettings if(iface->num_altsetting > 0) { iface->altsetting = malloc(iface->num_altsetting * sizeof(struct usb_interface_descriptor)); } // Load altsettings for(j = 0; j < iface->num_altsetting; ++j) { // Ensure struct under/overlap struct usb_interface_descriptor* as = &iface->altsetting[j]; int szlen = sizeof(struct usb_interface_descriptor); if(szlen > it.len) szlen = it.len; // Read altsettings - no conversions apply memcpy(as, it.val, szlen); iter_next(&it); // Allocate endpoints as->endpoint = NULL; if(as->bNumEndpoints > 0) { size_t epsize = as->bNumEndpoints * sizeof(struct usb_endpoint_descriptor); as->endpoint = malloc(epsize); memset(as->endpoint, 0, epsize); } // Load endpoints for(k = 0; k < as->bNumEndpoints; ++k) { struct usb_endpoint_descriptor* endpoint = &as->endpoint[k]; int szlen = sizeof(struct usb_endpoint_descriptor); if(szlen > it.len) szlen = it.len; // Read endpoint and apply conversion memcpy(endpoint, it.val, szlen); endpoint->wMaxPacketSize = ntohs(endpoint->wMaxPacketSize); iter_next(&it); // Null extra descriptors. endpoint->extralen = 0; endpoint->extra = NULL; } // Read extra interface descriptors as->extralen = as_int(it.val, it.len); iter_next(&it); if(as->extralen > 0){ as->extra = malloc(as->extralen); int szlen = as->extralen; if(szlen > it.len) szlen = it.len; memcpy(as->extra, it.val, szlen); iter_next(&it); } else as->extra = NULL; } } } //log_msg("Bus %s Device %s: ID %04x:%04x", rbus->dirname, dev->filename, dev->descriptor.idVendor, dev->descriptor.idProduct); } // Free unused devices while(dev->next != NULL) { struct usb_device* ddev = dev->next; debug_msg("deleting device %03d", ddev->devnum); dev->next = ddev->next; free(ddev); } } else { debug_msg("unexpected item identifier 0x%02x", it.type); iter_next(&it); } } // Deallocate unnecessary busses while(rbus->next != NULL) { debug_msg("deleting bus %03d", rbus->next->location); struct usb_bus* bus = rbus->next; rbus->next = bus->next; } // Save busses if(__remote_bus == NULL) { __orig_bus = usb_busses; debug_msg("overriding global usb_busses from %p to %p", usb_busses, vbus.next); } __remote_bus = vbus.next; usb_busses = __remote_bus; } // Return remote result pkt_release(); debug_msg("returned %d", res); return res; }