!C99Shell v. 2.0 [PHP 7 Update] [25.02.2019]!

Software: Apache/2.4.18 (Ubuntu). PHP/7.0.33-0ubuntu0.16.04.16 

uname -a: Linux digifus 3.13.0-57-generic #95-Ubuntu SMP Fri Jun 19 09:28:15 UTC 2015 x86_64 

uid=33(www-data) gid=33(www-data) groups=33(www-data) 

Safe-mode: OFF (not secure)

/lib/firmware/carl9170fw/tools/carlu/src/   drwxr-xr-x
Free 9.65 GB of 29.4 GB (32.8%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     usb.c (16.75 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 * carlu - userspace testing utility for ar9170 devices
 *
 * USB back-end driver
 *
 * Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <errno.h>
#include <stdlib.h>
#include "libusb.h"

#include "carlu.h"
#include "usb.h"
#include "debug.h"
#include "list.h"
#include "cmd.h"

#define ADD_DEV(_vid, _pid, _vs, _ps)    {        \
    .idVendor = _vid,                \
    .idProduct = _pid,                \
    .vendor_name = _vs,                \
    .product_name = _ps                \
}

static const struct {
    uint16_t idVendor;
    uint16_t idProduct;
    char *vendor_name;
    char *product_name;
} dev_list[] = {
    ADD_DEV(0x0cf3, 0x9170, "Atheros", "9170"),
    ADD_DEV(0x0cf3, 0x1001, "Atheros", "TG121N"),
    ADD_DEV(0x0cf3, 0x1002, "TP-Link", "TL-WN821N v2"),
    ADD_DEV(0xcace, 0x0300, "Cace", "Airpcap NX"),
    ADD_DEV(0x07d1, 0x3c10, "D-Link", "DWA 160 A1"),
    ADD_DEV(0x07d1, 0x3a09, "D-Link", "DWA 160 A2"),
    ADD_DEV(0x0846, 0x9010, "Netgear", "WNDA3100"),
    ADD_DEV(0x0846, 0x9001, "Netgear", "WN111 v2"),
    ADD_DEV(0x0ace, 0x1221, "Zydas", "ZD1221"),
    ADD_DEV(0x0586, 0x3417, "ZyXEL", "NWD271N"),
    ADD_DEV(0x0cde, 0x0023, "Z-Com", "UB81 BG"),
    ADD_DEV(0x0cde, 0x0026, "Z-Com", "UB82 ABG"),
    ADD_DEV(0x0cde, 0x0027, "Sphairon", "Homelink 1202"),
    ADD_DEV(0x083a, 0xf522, "Arcadyan", "WN7512"),
    ADD_DEV(0x2019, 0x5304, "Planex", "GWUS300"),
    ADD_DEV(0x04bb, 0x093f, "IO-Data", "WNGDNUS2"),
    ADD_DEV(0x057C, 0x8401, "AVM", "FRITZ!WLAN USB Stick N"),
    ADD_DEV(0x057C, 0x8402, "AVM", "FRITZ!WLAN USB Stick N 2.4"),
};

static libusb_context *usb_ctx;
static LIST_HEAD(active_dev_list);

static int carlusb_event_thread(void *_ar)
{
    struct carlu *ar = (void *)_ar;
    dbg("event thread active and polling.\n");

    while (!ar->stop_event_polling)
        libusb_handle_events(ar->ctx);

    dbg("==> event thread desixed.\n");
    return 0;
}

static int carlusb_is_ar9170(struct libusb_device_descriptor *desc)
{
    unsigned int i;

    for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
        if ((desc->idVendor == dev_list[i].idVendor) &&
            (desc->idProduct == dev_list[i].idProduct)) {
            dbg("== found device \"%s %s\" [0x%04x:0x%04x]\n",
                dev_list[i].vendor_name, dev_list[i].product_name,
                desc->idVendor, desc->idProduct);

            return i;
        }
    }

    return -1;
}

static bool carlusb_is_dev(struct carlu *iter,
                   struct libusb_device *dev)
{
    libusb_device *list_dev;

    if (!iter->dev)
        return false;

    list_dev = libusb_get_device(iter->dev);

    if (libusb_get_bus_number(list_dev) == libusb_get_bus_number(dev) &&
        libusb_get_device_address(list_dev) == libusb_get_device_address(dev))
        return true;

    return false;
}

int carlusb_show_devinfo(struct carlu *ar)
{
    struct libusb_device_descriptor desc;
    libusb_device *dev;
    int err;

    dev = libusb_get_device(ar->dev);

    err = libusb_get_device_descriptor(dev, &desc);
    if (err)
        return err;

    info("USB Device Information:\n");
    info("\tUSB VendorID:%.4x(%s), ProductID:%.4x(%s)\n",
         dev_list[ar->idx].idVendor, dev_list[ar->idx].vendor_name,
         dev_list[ar->idx].idProduct, dev_list[ar->idx].product_name);
    info("\tBus:%d Address:%d\n", libusb_get_bus_number(dev),
         libusb_get_device_address(dev));

    return 0;
}

static int carlusb_get_dev(struct carlu *ar, bool reset)
{
    struct carlu *iter;
    libusb_device_handle *dev;
    libusb_device **list;
    int ret, err, i, idx = -1;

    ret = libusb_get_device_list(usb_ctx, &list);
    if (ret < 0) {
        err("usb device enum failed (%d)\n", ret);
        return ret;
    }

    for (i = 0; i < ret; i++) {
        struct libusb_device_descriptor desc;

        memset(&desc, 0, sizeof(desc));
        err = libusb_get_device_descriptor(list[i], &desc);
        if (err != 0)
            continue;

        idx = carlusb_is_ar9170(&desc);
        if (idx < 0)
            continue;

        list_for_each_entry(iter, &active_dev_list, dev_list) {
            if (carlusb_is_dev(iter, list[i])) {
                err = -EALREADY;
                break;
            }
        }

        if (err)
            continue;

        err = libusb_open(list[i], &dev);
        if (err != 0) {
            err("failed to open device (%d)\n", err);
            continue;
        }

        err = libusb_kernel_driver_active(dev, 0);
        switch (err) {
        case 0:
            break;
        default:
            err("failed to aquire exculusive access (%d).\n", err);
            goto skip;
        }

        if (reset) {
            err = libusb_reset_device(dev);
            if (err != 0) {
                err("failed to reset device (%d)\n", err);
                goto skip;
            }
        }

        err = libusb_claim_interface(dev, 0);
        if (err == 0) {
            dbg(">device is now under our control.\n");
            break;
        } else {
            err("failed to claim device (%d)\n", err);
            goto skip;
        }

skip:
        libusb_close(dev);
    }

    if (i != ret) {
        ar->idx = idx;
        ar->ctx = usb_ctx;
        ar->dev = dev;
        list_add_tail(&ar->dev_list, &active_dev_list);
        ret = 0;
    } else {
        ret = -ENODEV;
    }

    libusb_free_device_list(list, 1);
    return ret;
}

static void carlusb_tx_cb(struct carlu *ar,
                  struct frame *frame)
{
    if (ar->tx_cb)
        ar->tx_cb(ar, frame);

    ar->tx_octets += frame->len;

    carlu_free_frame(ar, frame);
}

static void carlusb_zap_queues(struct carlu *ar)
{
    struct frame *frame;

    BUG_ON(SDL_mutexP(ar->tx_queue_lock) != 0);
    while (!list_empty(&ar->tx_queue)) {
        frame = list_first_entry(&ar->tx_queue, struct frame, dcb.list);
        list_del(&frame->dcb.list);
        carlusb_tx_cb(ar, frame);
    }
    SDL_mutexV(ar->tx_queue_lock);
}

static void carlusb_free_driver(struct carlu *ar)
{
    if (!IS_ERR_OR_NULL(ar)) {
        if (ar->event_pipe[0] > -1)
            close(ar->event_pipe[0]);

        if (ar->event_pipe[1] > -1)
            close(ar->event_pipe[1]);

        carlusb_zap_queues(ar);
        carlfw_release(ar->fw);
        ar->fw = NULL;

        if (ar->dev) {
            libusb_release_interface(ar->dev, 0);
            libusb_close(ar->dev);
            ar->dev = NULL;
        }
        carlu_free_driver(ar);
    }
}

static int carlusb_init(struct carlu *ar)
{
    init_list_head(&ar->tx_queue);
    ar->tx_queue_lock = SDL_CreateMutex();
    ar->event_pipe[0] = ar->event_pipe[1] = -1;

    return 0;
}

static struct carlu *carlusb_open(void)
{
    struct carlu *tmp;
    int err;

    tmp = carlu_alloc_driver(sizeof(*tmp));
    if (tmp == NULL)
        return NULL;

    err = carlusb_init(tmp);
    if (err < 0)
        goto err_out;

    err = carlusb_get_dev(tmp, true);
    if (err < 0)
        goto err_out;

    return tmp;

err_out:
    carlusb_free_driver(tmp);
    return ERR_PTR(err);
}

static void carlusb_cancel_rings(struct carlu *ar)
{
    unsigned int i;

    for (i = 0; i < ARRAY_SIZE(ar->rx_ring); i++)
        libusb_cancel_transfer(ar->rx_ring[i]);

    libusb_cancel_transfer(ar->rx_interrupt);
}

static void carlusb_free_rings(struct carlu *ar)
{
    unsigned int i;

    for (i = 0; i < ARRAY_SIZE(ar->rx_ring); i++)
        libusb_free_transfer(ar->rx_ring[i]);

    libusb_free_transfer(ar->rx_interrupt);
}

static void carlusb_destroy(struct carlu *ar)
{
    int event_thread_status;

    dbg("==>release device.\n");

    ar->stop_event_polling = true;

    carlusb_cancel_rings(ar);

    SDL_WaitThread(ar->event_thread, &event_thread_status);

    carlusb_free_rings(ar);
    list_del(&ar->dev_list);
}

static void carlusb_tx_bulk_cb(struct libusb_transfer *transfer);

static void carlusb_tx_pending(struct carlu *ar)
{
    struct frame *frame;
    struct libusb_transfer *urb;
    int err;

    BUG_ON(SDL_mutexP(ar->tx_queue_lock) != 0);
    if (ar->tx_queue_len >= (AR9170_TX_MAX_ACTIVE_URBS) ||
        list_empty(&ar->tx_queue))
        goto out;

    ar->tx_queue_len++;

    urb = libusb_alloc_transfer(0);
    if (urb == NULL)
        goto out;

    frame = list_first_entry(&ar->tx_queue, struct frame, dcb.list);
    list_del(&frame->dcb.list);

    if (ar->tx_stream) {
        struct ar9170_stream *tx_stream;

        tx_stream = frame_push(frame, sizeof(*tx_stream));
        tx_stream->length = cpu_to_le16(frame->len);
        tx_stream->tag = cpu_to_le16(0x697e);
    }

    libusb_fill_bulk_transfer(urb, ar->dev, AR9170_EP_TX, (unsigned char *)
        frame->data, frame->len, carlusb_tx_bulk_cb, (void *)frame, 0);

    /* FIXME: ZERO_PACKET support! */
    urb->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
/*    urb->flags |= LIBUSB_TRANSFER_ZERO_PACKET; */
    frame->dev = (void *) ar;
    frame_get(frame);

    err = libusb_submit_transfer(urb);
    if (err != 0) {
        err("->usb bulk tx submit failed (%d).\n", err);
        libusb_free_transfer(urb);
    }

out:
    SDL_mutexV(ar->tx_queue_lock);
    return;
}

void carlusb_tx(struct carlu *ar, struct frame *frame)
{
    BUG_ON(SDL_mutexP(ar->tx_queue_lock) != 0);

    list_add_tail(&frame->dcb.list, &ar->tx_queue);
    SDL_mutexV(ar->tx_queue_lock);

    carlusb_tx_pending(ar);
}

static void carlusb_tx_bulk_cb(struct libusb_transfer *transfer)
{
    struct frame *frame = (void *) transfer->user_data;
    struct carlu *ar = (void *) frame->dev;

    BUG_ON(SDL_mutexP(ar->tx_queue_lock) != 0);
    ar->tx_queue_len--;
    SDL_mutexV(ar->tx_queue_lock);

    if (ar->tx_stream)
        frame_pull(frame, 4);

    carlusb_tx_cb(ar, frame);
    carlusb_tx_pending(ar);
}

static void carlusb_rx_interrupt_cb(struct libusb_transfer *transfer)
{
    struct carlu *ar = (void *) transfer->user_data;
    int err;

    switch (transfer->status) {
    case LIBUSB_TRANSFER_COMPLETED:
        carlu_handle_command(ar, transfer->buffer, transfer->actual_length);
        break;

    case LIBUSB_TRANSFER_CANCELLED:
        return;

    default:
        err("==>rx_irq urb died (%d)\n", transfer->status);
        break;
    }

    err = libusb_submit_transfer(transfer);
    if (err != 0)
        err("==>rx_irq urb resubmit failed (%d)\n", err);
}

static void carlusb_rx_bulk_cb(struct libusb_transfer *transfer)
{
    struct frame *frame = (void *) transfer->user_data;
    struct carlu *ar = (void *) frame->dev;
    int err;

    switch (transfer->status) {
    case LIBUSB_TRANSFER_COMPLETED:
        frame_put(frame, transfer->actual_length);

        carlu_rx(ar, frame);

        frame_trim(frame, 0);
        break;

    case LIBUSB_TRANSFER_CANCELLED:
        return;

    default:
        err("==>rx_bulk urb died (%d)\n", transfer->status);
        break;
    }

    err = libusb_submit_transfer(transfer);
    if (err != 0)
        err("->rx_bulk urb resubmit failed (%d)\n", err);
}

static int carlusb_initialize_rxirq(struct carlu *ar)
{
    int err;

    ar->rx_interrupt = libusb_alloc_transfer(0);
    if (ar->rx_interrupt == NULL) {
        err("==>cannot alloc rx interrupt urb\n");
        return -1;
    }

    libusb_fill_interrupt_transfer(ar->rx_interrupt, ar->dev, AR9170_EP_IRQ,
                       (unsigned char *)&ar->irq_buf, sizeof(ar->irq_buf),
                       carlusb_rx_interrupt_cb, (void *) ar, 0);

    err = libusb_submit_transfer(ar->rx_interrupt);
    if (err != 0) {
        err("==>failed to submit rx interrupt (%d)\n", err);
        return err;
    }

    dbg("rx interrupt is now operational.\n");
    return 0;
}

static int carlusb_initialize_rxrings(struct carlu *ar)
{
    struct frame *tmp;
    unsigned int i;
    int err;

    for (i = 0; i < ARRAY_SIZE(ar->rx_ring); i++) {
        tmp = frame_alloc(ar->rx_max);
        if (tmp == NULL)
            return -ENOMEM;

        tmp->dev = (void *) ar;

        ar->rx_ring[i] = libusb_alloc_transfer(0);
        if (ar->rx_ring[i] == NULL) {
            frame_free(tmp);
            return -ENOMEM;
        }

        libusb_fill_bulk_transfer(ar->rx_ring[i], ar->dev,
            AR9170_EP_RX, (unsigned char *)tmp->data,
            ar->rx_max, carlusb_rx_bulk_cb, (void *)tmp, 0);

        err = libusb_submit_transfer(ar->rx_ring[i]);
        if (err != 0) {
            err("==>failed to submit rx buld urb (%d)\n", err);
            return EXIT_FAILURE;
        }
    }

    dbg("rx ring is now ready to receive.\n");
    return 0;
}

static int carlusb_load_firmware(struct carlu *ar)
{
    int ret = 0;

    dbg("loading firmware...\n");

    ar->fw = carlfw_load(CARL9170_FIRMWARE_FILE);
    if (IS_ERR_OR_NULL(ar->fw))
        return PTR_ERR(ar->fw);

    ret = carlu_fw_check(ar);
    if (ret)
        return ret;

    ret = carlusb_fw_check(ar);
    if (ret)
        return ret;

    return 0;
}

static int carlusb_upload_firmware(struct carlu *ar, bool boot)
{
    uint32_t addr = 0x200000;
    size_t len;
    void *buf;
    int ret = 0;

    dbg("initiating firmware image upload procedure.\n");

    buf = carlfw_get_fw(ar->fw, &len);
    if (IS_ERR_OR_NULL(buf))
        return PTR_ERR(buf);

    if (ar->miniboot_size) {
        dbg("Miniboot firmware size:%d\n", ar->miniboot_size);
        len -= ar->miniboot_size;
        buf += ar->miniboot_size;
    }

    while (len) {
        int blocklen = len > 4096 ? 4096 : len;

        ret = libusb_control_transfer(ar->dev, 0x40, 0x30, addr >> 8, 0, buf, blocklen, 1000);
        if (ret != blocklen && ret != LIBUSB_ERROR_TIMEOUT) {
            err("==>firmware upload failed (%d)\n", ret);
            return -EXIT_FAILURE;
        }

        dbg("uploaded %d bytes to start address 0x%04x.\n", blocklen, addr);

        buf += blocklen;
        addr += blocklen;
        len -= blocklen;
    }

    if (boot) {
        ret = libusb_control_transfer(ar->dev, 0x40, 0x31, 0, 0, NULL, 0, 5000);
        if (ret < 0) {
            err("unable to boot firmware (%d)\n", ret);
            return -EXIT_FAILURE;
        }

        /* give the firmware some time to reset & reboot */
        SDL_Delay(100);

        /*
         * since the device did a full usb reset,
         * we have to get a new "dev".
         */
        libusb_release_interface(ar->dev, 0);
        libusb_close(ar->dev);
        ar->dev = NULL;
        list_del(&ar->dev_list);

        ret = carlusb_get_dev(ar, false);
    }

    return 0;
}

int carlusb_cmd_async(struct carlu *ar, struct carl9170_cmd *cmd,
              const bool free_buf)
{
    struct libusb_transfer *urb;
    int ret, send;

    if (cmd->hdr.len > (CARL9170_MAX_CMD_LEN - 4)) {
        err("|-> too much payload\n");
        ret = -EINVAL;
        goto out;
    }

    if (cmd->hdr.len % 4) {
        err("|-> invalid command length\n");
        ret = -EINVAL;
        goto out;
    }

    ret = libusb_interrupt_transfer(ar->dev, AR9170_EP_CMD, (void *) cmd, cmd->hdr.len + 4, &send, 32);
    if (ret != 0) {
        err("OID:0x%.2x failed due to (%d) (%d).\n", cmd->hdr.cmd, ret, send);
        print_hex_dump_bytes(ERROR, "CMD:", cmd, cmd->hdr.len);
    }

out:
    if (free_buf)
        free((void *)cmd);

    return ret;
}

int carlusb_cmd(struct carlu *ar, uint8_t oid,
              uint8_t *cmd, size_t clen,
              uint8_t *rsp, size_t rlen)
{
    int ret, send;

    if (clen > (CARL9170_MAX_CMD_LEN - 4)) {
        err("|-> OID:0x%.2x has too much payload (%d octs)\n", oid, (int)clen);
        return -EINVAL;
    }

    ret = SDL_mutexP(ar->resp_lock);
    if (ret != 0) {
        err("failed to acquire resp_lock.\n");
        print_hex_dump_bytes(ERROR, "CMD:", ar->cmd.buf, clen);
        return -1;
    }

    ar->cmd.cmd.hdr.len = clen;
    ar->cmd.cmd.hdr.cmd = oid;
    /* buf[2] & buf[3] are padding */
    if (clen && cmd != (uint8_t *)(&ar->cmd.cmd.data))
        memcpy(&ar->cmd.cmd.data, cmd, clen);

    ar->resp_buf = (uint8_t *)rsp;
    ar->resp_len = rlen;

    ret = carlusb_cmd_async(ar, &ar->cmd.cmd, false);
    if (ret != 0) {
        err("OID:0x%.2x failed due to (%d) (%d).\n", oid, ret, send);
        print_hex_dump_bytes(ERROR, "CMD:", ar->cmd.buf, clen);
        SDL_mutexV(ar->resp_lock);
        return ret;
    }

    ret = SDL_CondWaitTimeout(ar->resp_pend, ar->resp_lock, 100);
    if (ret != 0) {
        err("|-> OID:0x%.2x timed out %d.\n", oid, ret);
        ar->resp_buf = NULL;
        ar->resp_len = 0;
        ret = -ETIMEDOUT;
    }

    SDL_mutexV(ar->resp_lock);
    return ret;
}

struct carlu *carlusb_probe(void)
{
    struct carlu *ar;
    int ret = -ENOMEM;

    ar = carlusb_open();
    if (IS_ERR_OR_NULL(ar)) {
        if (IS_ERR(ar))
            ret = PTR_ERR(ar);
        goto err_out;
    }

    ret = carlusb_show_devinfo(ar);
    if (ret)
        goto err_out;

    ret = carlusb_load_firmware(ar);
    if (ret)
        goto err_out;

    ret = pipe(ar->event_pipe);
    if (ret)
        goto err_out;

    ar->stop_event_polling = false;
    ar->event_thread = SDL_CreateThread(carlusb_event_thread, ar);

    ret = carlusb_upload_firmware(ar, true);
    if (ret)
        goto err_kill;

    ret = carlusb_initialize_rxirq(ar);
    if (ret)
        goto err_kill;

    ret = carlusb_initialize_rxrings(ar);
    if (ret)
        goto err_kill;

    ret = carlu_cmd_echo(ar, 0x44110dee);
    if (ret) {
        err("echo test failed...\n");
        goto err_kill;
    }

    info("firmware is active and running.\n");

    carlu_fw_info(ar);

    return ar;

err_kill:
    carlusb_destroy(ar);

err_out:
    carlusb_free_driver(ar);
    err("usb device rendezvous failed (%d).\n", ret);
    return ERR_PTR(ret);
}

void carlusb_close(struct carlu *ar)
{
    carlu_cmd_reboot(ar);

    carlusb_destroy(ar);
    carlusb_free_driver(ar);
}

int carlusb_print_known_devices(void)
{
    unsigned int i;

    debug_level = INFO;

    info("==> dumping known device list <==\n");
    for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
        info("Vendor:\"%-9s\" Product:\"%-26s\" => USBID:[0x%04x:0x%04x]\n",
             dev_list[i].vendor_name, dev_list[i].product_name,
             dev_list[i].idVendor, dev_list[i].idProduct);
    }
    info("==> end of device list <==\n");

    return EXIT_SUCCESS;
}

int usb_init(void)
{
    int ret;

    ret = libusb_init(&usb_ctx);
    if (ret != 0) {
        err("failed to initialize usb subsystem (%d)\n", ret);
        return ret;
    }

    /* like a silent chatterbox! */
    libusb_set_debug(usb_ctx, 2);

    return 0;
}

void usb_exit(void)
{
    libusb_exit(usb_ctx);
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.0 [PHP 7 Update] [25.02.2019] maintained by KaizenLouie | C99Shell Github | Generation time: 0.0115 ]--