Annotation of qemu/hw/usb-net.c, revision 1.1.1.10

1.1       root        1: /*
                      2:  * QEMU USB Net devices
                      3:  *
                      4:  * Copyright (c) 2006 Thomas Sailer
                      5:  * Copyright (c) 2008 Andrzej Zaborowski
                      6:  *
                      7:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      8:  * of this software and associated documentation files (the "Software"), to deal
                      9:  * in the Software without restriction, including without limitation the rights
                     10:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     11:  * copies of the Software, and to permit persons to whom the Software is
                     12:  * furnished to do so, subject to the following conditions:
                     13:  *
                     14:  * The above copyright notice and this permission notice shall be included in
                     15:  * all copies or substantial portions of the Software.
                     16:  *
                     17:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     18:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     19:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     20:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     21:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     22:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     23:  * THE SOFTWARE.
                     24:  */
                     25: 
                     26: #include "qemu-common.h"
                     27: #include "usb.h"
1.1.1.8   root       28: #include "usb-desc.h"
1.1       root       29: #include "net.h"
1.1.1.4   root       30: #include "qemu-queue.h"
1.1.1.8   root       31: #include "sysemu.h"
1.1.1.10! root       32: #include "iov.h"
1.1       root       33: 
                     34: /*#define TRAFFIC_DEBUG*/
                     35: /* Thanks to NetChip Technologies for donating this product ID.
                     36:  * It's for devices with only CDC Ethernet configurations.
                     37:  */
                     38: #define CDC_VENDOR_NUM          0x0525  /* NetChip */
                     39: #define CDC_PRODUCT_NUM         0xa4a1  /* Linux-USB Ethernet Gadget */
                     40: /* For hardware that can talk RNDIS and either of the above protocols,
                     41:  * use this ID ... the windows INF files will know it.
                     42:  */
                     43: #define RNDIS_VENDOR_NUM        0x0525  /* NetChip */
                     44: #define RNDIS_PRODUCT_NUM       0xa4a2  /* Ethernet/RNDIS Gadget */
                     45: 
                     46: enum usbstring_idx {
                     47:     STRING_MANUFACTURER                = 1,
                     48:     STRING_PRODUCT,
                     49:     STRING_ETHADDR,
                     50:     STRING_DATA,
                     51:     STRING_CONTROL,
                     52:     STRING_RNDIS_CONTROL,
                     53:     STRING_CDC,
                     54:     STRING_SUBSET,
                     55:     STRING_RNDIS,
                     56:     STRING_SERIALNUMBER,
                     57: };
                     58: 
                     59: #define DEV_CONFIG_VALUE               1       /* CDC or a subset */
                     60: #define DEV_RNDIS_CONFIG_VALUE         2       /* RNDIS; optional */
                     61: 
                     62: #define USB_CDC_SUBCLASS_ACM           0x02
                     63: #define USB_CDC_SUBCLASS_ETHERNET      0x06
                     64: 
                     65: #define USB_CDC_PROTO_NONE             0
                     66: #define USB_CDC_ACM_PROTO_VENDOR       0xff
                     67: 
                     68: #define USB_CDC_HEADER_TYPE            0x00    /* header_desc */
                     69: #define USB_CDC_CALL_MANAGEMENT_TYPE   0x01    /* call_mgmt_descriptor */
                     70: #define USB_CDC_ACM_TYPE               0x02    /* acm_descriptor */
                     71: #define USB_CDC_UNION_TYPE             0x06    /* union_desc */
                     72: #define USB_CDC_ETHERNET_TYPE          0x0f    /* ether_desc */
                     73: 
                     74: #define USB_DT_CS_INTERFACE            0x24
                     75: #define USB_DT_CS_ENDPOINT             0x25
                     76: 
                     77: #define USB_CDC_SEND_ENCAPSULATED_COMMAND      0x00
                     78: #define USB_CDC_GET_ENCAPSULATED_RESPONSE      0x01
                     79: #define USB_CDC_REQ_SET_LINE_CODING            0x20
                     80: #define USB_CDC_REQ_GET_LINE_CODING            0x21
                     81: #define USB_CDC_REQ_SET_CONTROL_LINE_STATE     0x22
                     82: #define USB_CDC_REQ_SEND_BREAK                 0x23
                     83: #define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40
                     84: #define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER 0x41
                     85: #define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42
                     86: #define USB_CDC_SET_ETHERNET_PACKET_FILTER     0x43
                     87: #define USB_CDC_GET_ETHERNET_STATISTIC         0x44
                     88: 
                     89: #define LOG2_STATUS_INTERVAL_MSEC      5    /* 1 << 5 == 32 msec */
                     90: #define STATUS_BYTECOUNT               16   /* 8 byte header + data */
                     91: 
                     92: #define ETH_FRAME_LEN                  1514 /* Max. octets in frame sans FCS */
                     93: 
1.1.1.8   root       94: static const USBDescStrings usb_net_stringtable = {
                     95:     [STRING_MANUFACTURER]       = "QEMU",
                     96:     [STRING_PRODUCT]            = "RNDIS/QEMU USB Network Device",
                     97:     [STRING_ETHADDR]            = "400102030405",
                     98:     [STRING_DATA]               = "QEMU USB Net Data Interface",
                     99:     [STRING_CONTROL]            = "QEMU USB Net Control Interface",
                    100:     [STRING_RNDIS_CONTROL]      = "QEMU USB Net RNDIS Control Interface",
                    101:     [STRING_CDC]                = "QEMU USB Net CDC",
                    102:     [STRING_SUBSET]             = "QEMU USB Net Subset",
                    103:     [STRING_RNDIS]              = "QEMU USB Net RNDIS",
                    104:     [STRING_SERIALNUMBER]       = "1",
                    105: };
                    106: 
                    107: static const USBDescIface desc_iface_rndis[] = {
                    108:     {
                    109:         /* RNDIS Control Interface */
                    110:         .bInterfaceNumber              = 0,
                    111:         .bNumEndpoints                 = 1,
                    112:         .bInterfaceClass               = USB_CLASS_COMM,
                    113:         .bInterfaceSubClass            = USB_CDC_SUBCLASS_ACM,
                    114:         .bInterfaceProtocol            = USB_CDC_ACM_PROTO_VENDOR,
                    115:         .iInterface                    = STRING_RNDIS_CONTROL,
                    116:         .ndesc                         = 4,
                    117:         .descs = (USBDescOther[]) {
                    118:             {
                    119:                 /* Header Descriptor */
                    120:                 .data = (uint8_t[]) {
                    121:                     0x05,                       /*  u8    bLength */
                    122:                     USB_DT_CS_INTERFACE,        /*  u8    bDescriptorType */
                    123:                     USB_CDC_HEADER_TYPE,        /*  u8    bDescriptorSubType */
                    124:                     0x10, 0x01,                 /*  le16  bcdCDC */
                    125:                 },
                    126:             },{
                    127:                 /* Call Management Descriptor */
                    128:                 .data = (uint8_t[]) {
                    129:                     0x05,                       /*  u8    bLength */
                    130:                     USB_DT_CS_INTERFACE,        /*  u8    bDescriptorType */
                    131:                     USB_CDC_CALL_MANAGEMENT_TYPE, /*  u8    bDescriptorSubType */
                    132:                     0x00,                       /*  u8    bmCapabilities */
                    133:                     0x01,                       /*  u8    bDataInterface */
                    134:                 },
                    135:             },{
                    136:                 /* ACM Descriptor */
                    137:                 .data = (uint8_t[]) {
                    138:                     0x04,                       /*  u8    bLength */
                    139:                     USB_DT_CS_INTERFACE,        /*  u8    bDescriptorType */
                    140:                     USB_CDC_ACM_TYPE,           /*  u8    bDescriptorSubType */
                    141:                     0x00,                       /*  u8    bmCapabilities */
                    142:                 },
                    143:             },{
                    144:                 /* Union Descriptor */
                    145:                 .data = (uint8_t[]) {
                    146:                     0x05,                       /*  u8    bLength */
                    147:                     USB_DT_CS_INTERFACE,        /*  u8    bDescriptorType */
                    148:                     USB_CDC_UNION_TYPE,         /*  u8    bDescriptorSubType */
                    149:                     0x00,                       /*  u8    bMasterInterface0 */
                    150:                     0x01,                       /*  u8    bSlaveInterface0 */
                    151:                 },
                    152:             },
                    153:         },
                    154:         .eps = (USBDescEndpoint[]) {
                    155:             {
                    156:                 .bEndpointAddress      = USB_DIR_IN | 0x01,
                    157:                 .bmAttributes          = USB_ENDPOINT_XFER_INT,
                    158:                 .wMaxPacketSize        = STATUS_BYTECOUNT,
                    159:                 .bInterval             = 1 << LOG2_STATUS_INTERVAL_MSEC,
                    160:             },
                    161:         }
                    162:     },{
                    163:         /* RNDIS Data Interface */
                    164:         .bInterfaceNumber              = 1,
                    165:         .bNumEndpoints                 = 2,
                    166:         .bInterfaceClass               = USB_CLASS_CDC_DATA,
                    167:         .iInterface                    = STRING_DATA,
                    168:         .eps = (USBDescEndpoint[]) {
                    169:             {
                    170:                 .bEndpointAddress      = USB_DIR_IN | 0x02,
                    171:                 .bmAttributes          = USB_ENDPOINT_XFER_BULK,
                    172:                 .wMaxPacketSize        = 0x40,
                    173:             },{
                    174:                 .bEndpointAddress      = USB_DIR_OUT | 0x02,
                    175:                 .bmAttributes          = USB_ENDPOINT_XFER_BULK,
                    176:                 .wMaxPacketSize        = 0x40,
                    177:             }
                    178:         }
                    179:     }
                    180: };
                    181: 
                    182: static const USBDescIface desc_iface_cdc[] = {
                    183:     {
                    184:         /* CDC Control Interface */
                    185:         .bInterfaceNumber              = 0,
                    186:         .bNumEndpoints                 = 1,
                    187:         .bInterfaceClass               = USB_CLASS_COMM,
                    188:         .bInterfaceSubClass            = USB_CDC_SUBCLASS_ETHERNET,
                    189:         .bInterfaceProtocol            = USB_CDC_PROTO_NONE,
                    190:         .iInterface                    = STRING_CONTROL,
                    191:         .ndesc                         = 3,
                    192:         .descs = (USBDescOther[]) {
                    193:             {
                    194:                 /* Header Descriptor */
                    195:                 .data = (uint8_t[]) {
                    196:                     0x05,                       /*  u8    bLength */
                    197:                     USB_DT_CS_INTERFACE,        /*  u8    bDescriptorType */
                    198:                     USB_CDC_HEADER_TYPE,        /*  u8    bDescriptorSubType */
                    199:                     0x10, 0x01,                 /*  le16  bcdCDC */
                    200:                 },
                    201:             },{
                    202:                 /* Union Descriptor */
                    203:                 .data = (uint8_t[]) {
                    204:                     0x05,                       /*  u8    bLength */
                    205:                     USB_DT_CS_INTERFACE,        /*  u8    bDescriptorType */
                    206:                     USB_CDC_UNION_TYPE,         /*  u8    bDescriptorSubType */
                    207:                     0x00,                       /*  u8    bMasterInterface0 */
                    208:                     0x01,                       /*  u8    bSlaveInterface0 */
                    209:                 },
                    210:             },{
                    211:                 /* Ethernet Descriptor */
                    212:                 .data = (uint8_t[]) {
                    213:                     0x0d,                       /*  u8    bLength */
                    214:                     USB_DT_CS_INTERFACE,        /*  u8    bDescriptorType */
                    215:                     USB_CDC_ETHERNET_TYPE,      /*  u8    bDescriptorSubType */
                    216:                     STRING_ETHADDR,             /*  u8    iMACAddress */
                    217:                     0x00, 0x00, 0x00, 0x00,     /*  le32  bmEthernetStatistics */
                    218:                     ETH_FRAME_LEN & 0xff,
                    219:                     ETH_FRAME_LEN >> 8,         /*  le16  wMaxSegmentSize */
                    220:                     0x00, 0x00,                 /*  le16  wNumberMCFilters */
                    221:                     0x00,                       /*  u8    bNumberPowerFilters */
                    222:                 },
                    223:             },
                    224:         },
                    225:         .eps = (USBDescEndpoint[]) {
                    226:             {
                    227:                 .bEndpointAddress      = USB_DIR_IN | 0x01,
                    228:                 .bmAttributes          = USB_ENDPOINT_XFER_INT,
                    229:                 .wMaxPacketSize        = STATUS_BYTECOUNT,
                    230:                 .bInterval             = 1 << LOG2_STATUS_INTERVAL_MSEC,
                    231:             },
                    232:         }
                    233:     },{
                    234:         /* CDC Data Interface (off) */
                    235:         .bInterfaceNumber              = 1,
                    236:         .bAlternateSetting             = 0,
                    237:         .bNumEndpoints                 = 0,
                    238:         .bInterfaceClass               = USB_CLASS_CDC_DATA,
                    239:     },{
                    240:         /* CDC Data Interface */
                    241:         .bInterfaceNumber              = 1,
                    242:         .bAlternateSetting             = 1,
                    243:         .bNumEndpoints                 = 2,
                    244:         .bInterfaceClass               = USB_CLASS_CDC_DATA,
                    245:         .iInterface                    = STRING_DATA,
                    246:         .eps = (USBDescEndpoint[]) {
                    247:             {
                    248:                 .bEndpointAddress      = USB_DIR_IN | 0x02,
                    249:                 .bmAttributes          = USB_ENDPOINT_XFER_BULK,
                    250:                 .wMaxPacketSize        = 0x40,
                    251:             },{
                    252:                 .bEndpointAddress      = USB_DIR_OUT | 0x02,
                    253:                 .bmAttributes          = USB_ENDPOINT_XFER_BULK,
                    254:                 .wMaxPacketSize        = 0x40,
                    255:             }
                    256:         }
                    257:     }
1.1       root      258: };
                    259: 
1.1.1.8   root      260: static const USBDescDevice desc_device_net = {
                    261:     .bcdUSB                        = 0x0200,
                    262:     .bDeviceClass                  = USB_CLASS_COMM,
                    263:     .bMaxPacketSize0               = 0x40,
                    264:     .bNumConfigurations            = 2,
                    265:     .confs = (USBDescConfig[]) {
                    266:         {
                    267:             .bNumInterfaces        = 2,
                    268:             .bConfigurationValue   = DEV_RNDIS_CONFIG_VALUE,
                    269:             .iConfiguration        = STRING_RNDIS,
                    270:             .bmAttributes          = 0xc0,
                    271:             .bMaxPower             = 0x32,
                    272:             .nif = ARRAY_SIZE(desc_iface_rndis),
                    273:             .ifs = desc_iface_rndis,
                    274:         },{
                    275:             .bNumInterfaces        = 2,
                    276:             .bConfigurationValue   = DEV_CONFIG_VALUE,
                    277:             .iConfiguration        = STRING_CDC,
                    278:             .bmAttributes          = 0xc0,
                    279:             .bMaxPower             = 0x32,
                    280:             .nif = ARRAY_SIZE(desc_iface_cdc),
                    281:             .ifs = desc_iface_cdc,
                    282:         }
                    283:     },
1.1       root      284: };
                    285: 
1.1.1.8   root      286: static const USBDesc desc_net = {
                    287:     .id = {
                    288:         .idVendor          = RNDIS_VENDOR_NUM,
                    289:         .idProduct         = RNDIS_PRODUCT_NUM,
                    290:         .bcdDevice         = 0,
                    291:         .iManufacturer     = STRING_MANUFACTURER,
                    292:         .iProduct          = STRING_PRODUCT,
                    293:         .iSerialNumber     = STRING_SERIALNUMBER,
                    294:     },
                    295:     .full = &desc_device_net,
                    296:     .str  = usb_net_stringtable,
1.1       root      297: };
                    298: 
                    299: /*
                    300:  * RNDIS Definitions - in theory not specific to USB.
                    301:  */
                    302: #define RNDIS_MAXIMUM_FRAME_SIZE       1518
                    303: #define RNDIS_MAX_TOTAL_SIZE           1558
                    304: 
                    305: /* Remote NDIS Versions */
                    306: #define RNDIS_MAJOR_VERSION            1
                    307: #define RNDIS_MINOR_VERSION            0
                    308: 
                    309: /* Status Values */
                    310: #define RNDIS_STATUS_SUCCESS           0x00000000U /* Success */
                    311: #define RNDIS_STATUS_FAILURE           0xc0000001U /* Unspecified error */
                    312: #define RNDIS_STATUS_INVALID_DATA      0xc0010015U /* Invalid data */
                    313: #define RNDIS_STATUS_NOT_SUPPORTED     0xc00000bbU /* Unsupported request */
                    314: #define RNDIS_STATUS_MEDIA_CONNECT     0x4001000bU /* Device connected */
                    315: #define RNDIS_STATUS_MEDIA_DISCONNECT  0x4001000cU /* Device disconnected */
                    316: 
                    317: /* Message Set for Connectionless (802.3) Devices */
                    318: enum {
                    319:     RNDIS_PACKET_MSG           = 1,
                    320:     RNDIS_INITIALIZE_MSG       = 2,    /* Initialize device */
                    321:     RNDIS_HALT_MSG             = 3,
                    322:     RNDIS_QUERY_MSG            = 4,
                    323:     RNDIS_SET_MSG              = 5,
                    324:     RNDIS_RESET_MSG            = 6,
                    325:     RNDIS_INDICATE_STATUS_MSG  = 7,
                    326:     RNDIS_KEEPALIVE_MSG                = 8,
                    327: };
                    328: 
                    329: /* Message completion */
                    330: enum {
                    331:     RNDIS_INITIALIZE_CMPLT     = 0x80000002U,
                    332:     RNDIS_QUERY_CMPLT          = 0x80000004U,
                    333:     RNDIS_SET_CMPLT            = 0x80000005U,
                    334:     RNDIS_RESET_CMPLT          = 0x80000006U,
                    335:     RNDIS_KEEPALIVE_CMPLT      = 0x80000008U,
                    336: };
                    337: 
                    338: /* Device Flags */
                    339: enum {
                    340:     RNDIS_DF_CONNECTIONLESS    = 1,
                    341:     RNDIS_DF_CONNECTIONORIENTED        = 2,
                    342: };
                    343: 
                    344: #define RNDIS_MEDIUM_802_3             0x00000000U
                    345: 
                    346: /* from drivers/net/sk98lin/h/skgepnmi.h */
                    347: #define OID_PNP_CAPABILITIES           0xfd010100
                    348: #define OID_PNP_SET_POWER              0xfd010101
                    349: #define OID_PNP_QUERY_POWER            0xfd010102
                    350: #define OID_PNP_ADD_WAKE_UP_PATTERN    0xfd010103
                    351: #define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xfd010104
                    352: #define OID_PNP_ENABLE_WAKE_UP         0xfd010106
                    353: 
                    354: typedef uint32_t le32;
                    355: 
                    356: typedef struct rndis_init_msg_type {
                    357:     le32 MessageType;
                    358:     le32 MessageLength;
                    359:     le32 RequestID;
                    360:     le32 MajorVersion;
                    361:     le32 MinorVersion;
                    362:     le32 MaxTransferSize;
                    363: } rndis_init_msg_type;
                    364: 
                    365: typedef struct rndis_init_cmplt_type {
                    366:     le32 MessageType;
                    367:     le32 MessageLength;
                    368:     le32 RequestID;
                    369:     le32 Status;
                    370:     le32 MajorVersion;
                    371:     le32 MinorVersion;
                    372:     le32 DeviceFlags;
                    373:     le32 Medium;
                    374:     le32 MaxPacketsPerTransfer;
                    375:     le32 MaxTransferSize;
                    376:     le32 PacketAlignmentFactor;
                    377:     le32 AFListOffset;
                    378:     le32 AFListSize;
                    379: } rndis_init_cmplt_type;
                    380: 
                    381: typedef struct rndis_halt_msg_type {
                    382:     le32 MessageType;
                    383:     le32 MessageLength;
                    384:     le32 RequestID;
                    385: } rndis_halt_msg_type;
                    386: 
                    387: typedef struct rndis_query_msg_type {
                    388:     le32 MessageType;
                    389:     le32 MessageLength;
                    390:     le32 RequestID;
                    391:     le32 OID;
                    392:     le32 InformationBufferLength;
                    393:     le32 InformationBufferOffset;
                    394:     le32 DeviceVcHandle;
                    395: } rndis_query_msg_type;
                    396: 
                    397: typedef struct rndis_query_cmplt_type {
                    398:     le32 MessageType;
                    399:     le32 MessageLength;
                    400:     le32 RequestID;
                    401:     le32 Status;
                    402:     le32 InformationBufferLength;
                    403:     le32 InformationBufferOffset;
                    404: } rndis_query_cmplt_type;
                    405: 
                    406: typedef struct rndis_set_msg_type {
                    407:     le32 MessageType;
                    408:     le32 MessageLength;
                    409:     le32 RequestID;
                    410:     le32 OID;
                    411:     le32 InformationBufferLength;
                    412:     le32 InformationBufferOffset;
                    413:     le32 DeviceVcHandle;
                    414: } rndis_set_msg_type;
                    415: 
                    416: typedef struct rndis_set_cmplt_type {
                    417:     le32 MessageType;
                    418:     le32 MessageLength;
                    419:     le32 RequestID;
                    420:     le32 Status;
                    421: } rndis_set_cmplt_type;
                    422: 
                    423: typedef struct rndis_reset_msg_type {
                    424:     le32 MessageType;
                    425:     le32 MessageLength;
                    426:     le32 Reserved;
                    427: } rndis_reset_msg_type;
                    428: 
                    429: typedef struct rndis_reset_cmplt_type {
                    430:     le32 MessageType;
                    431:     le32 MessageLength;
                    432:     le32 Status;
                    433:     le32 AddressingReset;
                    434: } rndis_reset_cmplt_type;
                    435: 
                    436: typedef struct rndis_indicate_status_msg_type {
                    437:     le32 MessageType;
                    438:     le32 MessageLength;
                    439:     le32 Status;
                    440:     le32 StatusBufferLength;
                    441:     le32 StatusBufferOffset;
                    442: } rndis_indicate_status_msg_type;
                    443: 
                    444: typedef struct rndis_keepalive_msg_type {
                    445:     le32 MessageType;
                    446:     le32 MessageLength;
                    447:     le32 RequestID;
                    448: } rndis_keepalive_msg_type;
                    449: 
                    450: typedef struct rndis_keepalive_cmplt_type {
                    451:     le32 MessageType;
                    452:     le32 MessageLength;
                    453:     le32 RequestID;
                    454:     le32 Status;
                    455: } rndis_keepalive_cmplt_type;
                    456: 
                    457: struct rndis_packet_msg_type {
                    458:     le32 MessageType;
                    459:     le32 MessageLength;
                    460:     le32 DataOffset;
                    461:     le32 DataLength;
                    462:     le32 OOBDataOffset;
                    463:     le32 OOBDataLength;
                    464:     le32 NumOOBDataElements;
                    465:     le32 PerPacketInfoOffset;
                    466:     le32 PerPacketInfoLength;
                    467:     le32 VcHandle;
                    468:     le32 Reserved;
                    469: };
                    470: 
                    471: struct rndis_config_parameter {
                    472:     le32 ParameterNameOffset;
                    473:     le32 ParameterNameLength;
                    474:     le32 ParameterType;
                    475:     le32 ParameterValueOffset;
                    476:     le32 ParameterValueLength;
                    477: };
                    478: 
                    479: /* implementation specific */
                    480: enum rndis_state
                    481: {
                    482:     RNDIS_UNINITIALIZED,
                    483:     RNDIS_INITIALIZED,
                    484:     RNDIS_DATA_INITIALIZED,
                    485: };
                    486: 
                    487: /* from ndis.h */
                    488: enum ndis_oid {
                    489:     /* Required Object IDs (OIDs) */
                    490:     OID_GEN_SUPPORTED_LIST             = 0x00010101,
                    491:     OID_GEN_HARDWARE_STATUS            = 0x00010102,
                    492:     OID_GEN_MEDIA_SUPPORTED            = 0x00010103,
                    493:     OID_GEN_MEDIA_IN_USE               = 0x00010104,
                    494:     OID_GEN_MAXIMUM_LOOKAHEAD          = 0x00010105,
                    495:     OID_GEN_MAXIMUM_FRAME_SIZE         = 0x00010106,
                    496:     OID_GEN_LINK_SPEED                 = 0x00010107,
                    497:     OID_GEN_TRANSMIT_BUFFER_SPACE      = 0x00010108,
                    498:     OID_GEN_RECEIVE_BUFFER_SPACE       = 0x00010109,
                    499:     OID_GEN_TRANSMIT_BLOCK_SIZE                = 0x0001010a,
                    500:     OID_GEN_RECEIVE_BLOCK_SIZE         = 0x0001010b,
                    501:     OID_GEN_VENDOR_ID                  = 0x0001010c,
                    502:     OID_GEN_VENDOR_DESCRIPTION         = 0x0001010d,
                    503:     OID_GEN_CURRENT_PACKET_FILTER      = 0x0001010e,
                    504:     OID_GEN_CURRENT_LOOKAHEAD          = 0x0001010f,
                    505:     OID_GEN_DRIVER_VERSION             = 0x00010110,
                    506:     OID_GEN_MAXIMUM_TOTAL_SIZE         = 0x00010111,
                    507:     OID_GEN_PROTOCOL_OPTIONS           = 0x00010112,
                    508:     OID_GEN_MAC_OPTIONS                        = 0x00010113,
                    509:     OID_GEN_MEDIA_CONNECT_STATUS       = 0x00010114,
                    510:     OID_GEN_MAXIMUM_SEND_PACKETS       = 0x00010115,
                    511:     OID_GEN_VENDOR_DRIVER_VERSION      = 0x00010116,
                    512:     OID_GEN_SUPPORTED_GUIDS            = 0x00010117,
                    513:     OID_GEN_NETWORK_LAYER_ADDRESSES    = 0x00010118,
                    514:     OID_GEN_TRANSPORT_HEADER_OFFSET    = 0x00010119,
                    515:     OID_GEN_MACHINE_NAME               = 0x0001021a,
                    516:     OID_GEN_RNDIS_CONFIG_PARAMETER     = 0x0001021b,
                    517:     OID_GEN_VLAN_ID                    = 0x0001021c,
                    518: 
                    519:     /* Optional OIDs */
                    520:     OID_GEN_MEDIA_CAPABILITIES         = 0x00010201,
                    521:     OID_GEN_PHYSICAL_MEDIUM            = 0x00010202,
                    522: 
                    523:     /* Required statistics OIDs */
                    524:     OID_GEN_XMIT_OK                    = 0x00020101,
                    525:     OID_GEN_RCV_OK                     = 0x00020102,
                    526:     OID_GEN_XMIT_ERROR                 = 0x00020103,
                    527:     OID_GEN_RCV_ERROR                  = 0x00020104,
                    528:     OID_GEN_RCV_NO_BUFFER              = 0x00020105,
                    529: 
                    530:     /* Optional statistics OIDs */
                    531:     OID_GEN_DIRECTED_BYTES_XMIT                = 0x00020201,
                    532:     OID_GEN_DIRECTED_FRAMES_XMIT       = 0x00020202,
                    533:     OID_GEN_MULTICAST_BYTES_XMIT       = 0x00020203,
                    534:     OID_GEN_MULTICAST_FRAMES_XMIT      = 0x00020204,
                    535:     OID_GEN_BROADCAST_BYTES_XMIT       = 0x00020205,
                    536:     OID_GEN_BROADCAST_FRAMES_XMIT      = 0x00020206,
                    537:     OID_GEN_DIRECTED_BYTES_RCV         = 0x00020207,
                    538:     OID_GEN_DIRECTED_FRAMES_RCV                = 0x00020208,
                    539:     OID_GEN_MULTICAST_BYTES_RCV                = 0x00020209,
                    540:     OID_GEN_MULTICAST_FRAMES_RCV       = 0x0002020a,
                    541:     OID_GEN_BROADCAST_BYTES_RCV                = 0x0002020b,
                    542:     OID_GEN_BROADCAST_FRAMES_RCV       = 0x0002020c,
                    543:     OID_GEN_RCV_CRC_ERROR              = 0x0002020d,
                    544:     OID_GEN_TRANSMIT_QUEUE_LENGTH      = 0x0002020e,
                    545:     OID_GEN_GET_TIME_CAPS              = 0x0002020f,
                    546:     OID_GEN_GET_NETCARD_TIME           = 0x00020210,
                    547:     OID_GEN_NETCARD_LOAD               = 0x00020211,
                    548:     OID_GEN_DEVICE_PROFILE             = 0x00020212,
                    549:     OID_GEN_INIT_TIME_MS               = 0x00020213,
                    550:     OID_GEN_RESET_COUNTS               = 0x00020214,
                    551:     OID_GEN_MEDIA_SENSE_COUNTS         = 0x00020215,
                    552:     OID_GEN_FRIENDLY_NAME              = 0x00020216,
                    553:     OID_GEN_MINIPORT_INFO              = 0x00020217,
                    554:     OID_GEN_RESET_VERIFY_PARAMETERS    = 0x00020218,
                    555: 
                    556:     /* IEEE 802.3 (Ethernet) OIDs */
                    557:     OID_802_3_PERMANENT_ADDRESS                = 0x01010101,
                    558:     OID_802_3_CURRENT_ADDRESS          = 0x01010102,
                    559:     OID_802_3_MULTICAST_LIST           = 0x01010103,
                    560:     OID_802_3_MAXIMUM_LIST_SIZE                = 0x01010104,
                    561:     OID_802_3_MAC_OPTIONS              = 0x01010105,
                    562:     OID_802_3_RCV_ERROR_ALIGNMENT      = 0x01020101,
                    563:     OID_802_3_XMIT_ONE_COLLISION       = 0x01020102,
                    564:     OID_802_3_XMIT_MORE_COLLISIONS     = 0x01020103,
                    565:     OID_802_3_XMIT_DEFERRED            = 0x01020201,
                    566:     OID_802_3_XMIT_MAX_COLLISIONS      = 0x01020202,
                    567:     OID_802_3_RCV_OVERRUN              = 0x01020203,
                    568:     OID_802_3_XMIT_UNDERRUN            = 0x01020204,
                    569:     OID_802_3_XMIT_HEARTBEAT_FAILURE   = 0x01020205,
                    570:     OID_802_3_XMIT_TIMES_CRS_LOST      = 0x01020206,
                    571:     OID_802_3_XMIT_LATE_COLLISIONS     = 0x01020207,
                    572: };
                    573: 
                    574: static const uint32_t oid_supported_list[] =
                    575: {
                    576:     /* the general stuff */
                    577:     OID_GEN_SUPPORTED_LIST,
                    578:     OID_GEN_HARDWARE_STATUS,
                    579:     OID_GEN_MEDIA_SUPPORTED,
                    580:     OID_GEN_MEDIA_IN_USE,
                    581:     OID_GEN_MAXIMUM_FRAME_SIZE,
                    582:     OID_GEN_LINK_SPEED,
                    583:     OID_GEN_TRANSMIT_BLOCK_SIZE,
                    584:     OID_GEN_RECEIVE_BLOCK_SIZE,
                    585:     OID_GEN_VENDOR_ID,
                    586:     OID_GEN_VENDOR_DESCRIPTION,
                    587:     OID_GEN_VENDOR_DRIVER_VERSION,
                    588:     OID_GEN_CURRENT_PACKET_FILTER,
                    589:     OID_GEN_MAXIMUM_TOTAL_SIZE,
                    590:     OID_GEN_MEDIA_CONNECT_STATUS,
                    591:     OID_GEN_PHYSICAL_MEDIUM,
                    592: 
                    593:     /* the statistical stuff */
                    594:     OID_GEN_XMIT_OK,
                    595:     OID_GEN_RCV_OK,
                    596:     OID_GEN_XMIT_ERROR,
                    597:     OID_GEN_RCV_ERROR,
                    598:     OID_GEN_RCV_NO_BUFFER,
                    599: 
                    600:     /* IEEE 802.3 */
                    601:     /* the general stuff */
                    602:     OID_802_3_PERMANENT_ADDRESS,
                    603:     OID_802_3_CURRENT_ADDRESS,
                    604:     OID_802_3_MULTICAST_LIST,
                    605:     OID_802_3_MAC_OPTIONS,
                    606:     OID_802_3_MAXIMUM_LIST_SIZE,
                    607: 
                    608:     /* the statistical stuff */
                    609:     OID_802_3_RCV_ERROR_ALIGNMENT,
                    610:     OID_802_3_XMIT_ONE_COLLISION,
                    611:     OID_802_3_XMIT_MORE_COLLISIONS,
                    612: };
                    613: 
                    614: #define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA    (1 << 0)
                    615: #define NDIS_MAC_OPTION_RECEIVE_SERIALIZED     (1 << 1)
                    616: #define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND     (1 << 2)
                    617: #define NDIS_MAC_OPTION_NO_LOOPBACK            (1 << 3)
                    618: #define NDIS_MAC_OPTION_FULL_DUPLEX            (1 << 4)
                    619: #define NDIS_MAC_OPTION_EOTX_INDICATION                (1 << 5)
                    620: #define NDIS_MAC_OPTION_8021P_PRIORITY         (1 << 6)
                    621: 
                    622: struct rndis_response {
1.1.1.4   root      623:     QTAILQ_ENTRY(rndis_response) entries;
1.1       root      624:     uint32_t length;
                    625:     uint8_t buf[0];
                    626: };
                    627: 
                    628: typedef struct USBNetState {
                    629:     USBDevice dev;
                    630: 
                    631:     enum rndis_state rndis_state;
                    632:     uint32_t medium;
                    633:     uint32_t speed;
                    634:     uint32_t media_state;
                    635:     uint16_t filter;
                    636:     uint32_t vendorid;
                    637: 
                    638:     unsigned int out_ptr;
                    639:     uint8_t out_buf[2048];
                    640: 
                    641:     USBPacket *inpkt;
                    642:     unsigned int in_ptr, in_len;
                    643:     uint8_t in_buf[2048];
                    644: 
                    645:     char usbstring_mac[13];
1.1.1.4   root      646:     NICState *nic;
                    647:     NICConf conf;
                    648:     QTAILQ_HEAD(rndis_resp_head, rndis_response) rndis_resp;
1.1       root      649: } USBNetState;
                    650: 
1.1.1.8   root      651: static int is_rndis(USBNetState *s)
                    652: {
                    653:     return s->dev.config->bConfigurationValue == DEV_RNDIS_CONFIG_VALUE;
                    654: }
                    655: 
1.1       root      656: static int ndis_query(USBNetState *s, uint32_t oid,
                    657:                       uint8_t *inbuf, unsigned int inlen, uint8_t *outbuf,
                    658:                       size_t outlen)
                    659: {
                    660:     unsigned int i;
                    661: 
                    662:     switch (oid) {
                    663:     /* general oids (table 4-1) */
                    664:     /* mandatory */
                    665:     case OID_GEN_SUPPORTED_LIST:
                    666:         for (i = 0; i < ARRAY_SIZE(oid_supported_list); i++)
                    667:             ((le32 *) outbuf)[i] = cpu_to_le32(oid_supported_list[i]);
                    668:         return sizeof(oid_supported_list);
                    669: 
                    670:     /* mandatory */
                    671:     case OID_GEN_HARDWARE_STATUS:
                    672:         *((le32 *) outbuf) = cpu_to_le32(0);
                    673:         return sizeof(le32);
                    674: 
                    675:     /* mandatory */
                    676:     case OID_GEN_MEDIA_SUPPORTED:
                    677:         *((le32 *) outbuf) = cpu_to_le32(s->medium);
                    678:         return sizeof(le32);
                    679: 
                    680:     /* mandatory */
                    681:     case OID_GEN_MEDIA_IN_USE:
                    682:         *((le32 *) outbuf) = cpu_to_le32(s->medium);
                    683:         return sizeof(le32);
                    684: 
                    685:     /* mandatory */
                    686:     case OID_GEN_MAXIMUM_FRAME_SIZE:
                    687:         *((le32 *) outbuf) = cpu_to_le32(ETH_FRAME_LEN);
                    688:         return sizeof(le32);
                    689: 
                    690:     /* mandatory */
                    691:     case OID_GEN_LINK_SPEED:
                    692:         *((le32 *) outbuf) = cpu_to_le32(s->speed);
                    693:         return sizeof(le32);
                    694: 
                    695:     /* mandatory */
                    696:     case OID_GEN_TRANSMIT_BLOCK_SIZE:
                    697:         *((le32 *) outbuf) = cpu_to_le32(ETH_FRAME_LEN);
                    698:         return sizeof(le32);
                    699: 
                    700:     /* mandatory */
                    701:     case OID_GEN_RECEIVE_BLOCK_SIZE:
                    702:         *((le32 *) outbuf) = cpu_to_le32(ETH_FRAME_LEN);
                    703:         return sizeof(le32);
                    704: 
                    705:     /* mandatory */
                    706:     case OID_GEN_VENDOR_ID:
                    707:         *((le32 *) outbuf) = cpu_to_le32(s->vendorid);
                    708:         return sizeof(le32);
                    709: 
                    710:     /* mandatory */
                    711:     case OID_GEN_VENDOR_DESCRIPTION:
                    712:         pstrcpy((char *)outbuf, outlen, "QEMU USB RNDIS Net");
                    713:         return strlen((char *)outbuf) + 1;
                    714: 
                    715:     case OID_GEN_VENDOR_DRIVER_VERSION:
                    716:         *((le32 *) outbuf) = cpu_to_le32(1);
                    717:         return sizeof(le32);
                    718: 
                    719:     /* mandatory */
                    720:     case OID_GEN_CURRENT_PACKET_FILTER:
                    721:         *((le32 *) outbuf) = cpu_to_le32(s->filter);
                    722:         return sizeof(le32);
                    723: 
                    724:     /* mandatory */
                    725:     case OID_GEN_MAXIMUM_TOTAL_SIZE:
                    726:         *((le32 *) outbuf) = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
                    727:         return sizeof(le32);
                    728: 
                    729:     /* mandatory */
                    730:     case OID_GEN_MEDIA_CONNECT_STATUS:
                    731:         *((le32 *) outbuf) = cpu_to_le32(s->media_state);
                    732:         return sizeof(le32);
                    733: 
                    734:     case OID_GEN_PHYSICAL_MEDIUM:
                    735:         *((le32 *) outbuf) = cpu_to_le32(0);
                    736:         return sizeof(le32);
                    737: 
                    738:     case OID_GEN_MAC_OPTIONS:
                    739:         *((le32 *) outbuf) = cpu_to_le32(
                    740:                         NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
                    741:                         NDIS_MAC_OPTION_FULL_DUPLEX);
                    742:         return sizeof(le32);
                    743: 
                    744:     /* statistics OIDs (table 4-2) */
                    745:     /* mandatory */
                    746:     case OID_GEN_XMIT_OK:
                    747:         *((le32 *) outbuf) = cpu_to_le32(0);
                    748:         return sizeof(le32);
                    749: 
                    750:     /* mandatory */
                    751:     case OID_GEN_RCV_OK:
                    752:         *((le32 *) outbuf) = cpu_to_le32(0);
                    753:         return sizeof(le32);
                    754: 
                    755:     /* mandatory */
                    756:     case OID_GEN_XMIT_ERROR:
                    757:         *((le32 *) outbuf) = cpu_to_le32(0);
                    758:         return sizeof(le32);
                    759: 
                    760:     /* mandatory */
                    761:     case OID_GEN_RCV_ERROR:
                    762:         *((le32 *) outbuf) = cpu_to_le32(0);
                    763:         return sizeof(le32);
                    764: 
                    765:     /* mandatory */
                    766:     case OID_GEN_RCV_NO_BUFFER:
                    767:         *((le32 *) outbuf) = cpu_to_le32(0);
                    768:         return sizeof(le32);
                    769: 
                    770:     /* ieee802.3 OIDs (table 4-3) */
                    771:     /* mandatory */
                    772:     case OID_802_3_PERMANENT_ADDRESS:
1.1.1.4   root      773:         memcpy(outbuf, s->conf.macaddr.a, 6);
1.1       root      774:         return 6;
                    775: 
                    776:     /* mandatory */
                    777:     case OID_802_3_CURRENT_ADDRESS:
1.1.1.4   root      778:         memcpy(outbuf, s->conf.macaddr.a, 6);
1.1       root      779:         return 6;
                    780: 
                    781:     /* mandatory */
                    782:     case OID_802_3_MULTICAST_LIST:
                    783:         *((le32 *) outbuf) = cpu_to_le32(0xe0000000);
                    784:         return sizeof(le32);
                    785: 
                    786:     /* mandatory */
                    787:     case OID_802_3_MAXIMUM_LIST_SIZE:
                    788:         *((le32 *) outbuf) = cpu_to_le32(1);
                    789:         return sizeof(le32);
                    790: 
                    791:     case OID_802_3_MAC_OPTIONS:
                    792:         return 0;
                    793: 
                    794:     /* ieee802.3 statistics OIDs (table 4-4) */
                    795:     /* mandatory */
                    796:     case OID_802_3_RCV_ERROR_ALIGNMENT:
                    797:         *((le32 *) outbuf) = cpu_to_le32(0);
                    798:         return sizeof(le32);
                    799: 
                    800:     /* mandatory */
                    801:     case OID_802_3_XMIT_ONE_COLLISION:
                    802:         *((le32 *) outbuf) = cpu_to_le32(0);
                    803:         return sizeof(le32);
                    804: 
                    805:     /* mandatory */
                    806:     case OID_802_3_XMIT_MORE_COLLISIONS:
                    807:         *((le32 *) outbuf) = cpu_to_le32(0);
                    808:         return sizeof(le32);
                    809: 
                    810:     default:
                    811:         fprintf(stderr, "usbnet: unknown OID 0x%08x\n", oid);
                    812:         return 0;
                    813:     }
                    814:     return -1;
                    815: }
                    816: 
                    817: static int ndis_set(USBNetState *s, uint32_t oid,
                    818:                 uint8_t *inbuf, unsigned int inlen)
                    819: {
                    820:     switch (oid) {
                    821:     case OID_GEN_CURRENT_PACKET_FILTER:
                    822:         s->filter = le32_to_cpup((le32 *) inbuf);
                    823:         if (s->filter) {
                    824:             s->rndis_state = RNDIS_DATA_INITIALIZED;
                    825:         } else {
                    826:             s->rndis_state = RNDIS_INITIALIZED;
                    827:         }
                    828:         return 0;
                    829: 
                    830:     case OID_802_3_MULTICAST_LIST:
                    831:         return 0;
                    832:     }
                    833:     return -1;
                    834: }
                    835: 
                    836: static int rndis_get_response(USBNetState *s, uint8_t *buf)
                    837: {
                    838:     int ret = 0;
                    839:     struct rndis_response *r = s->rndis_resp.tqh_first;
                    840: 
                    841:     if (!r)
                    842:         return ret;
                    843: 
1.1.1.4   root      844:     QTAILQ_REMOVE(&s->rndis_resp, r, entries);
1.1       root      845:     ret = r->length;
                    846:     memcpy(buf, r->buf, r->length);
1.1.1.10! root      847:     g_free(r);
1.1       root      848: 
                    849:     return ret;
                    850: }
                    851: 
                    852: static void *rndis_queue_response(USBNetState *s, unsigned int length)
                    853: {
                    854:     struct rndis_response *r =
1.1.1.10! root      855:             g_malloc0(sizeof(struct rndis_response) + length);
1.1       root      856: 
1.1.1.4   root      857:     QTAILQ_INSERT_TAIL(&s->rndis_resp, r, entries);
1.1       root      858:     r->length = length;
                    859: 
                    860:     return &r->buf[0];
                    861: }
                    862: 
                    863: static void rndis_clear_responsequeue(USBNetState *s)
                    864: {
                    865:     struct rndis_response *r;
                    866: 
                    867:     while ((r = s->rndis_resp.tqh_first)) {
1.1.1.4   root      868:         QTAILQ_REMOVE(&s->rndis_resp, r, entries);
1.1.1.10! root      869:         g_free(r);
1.1       root      870:     }
                    871: }
                    872: 
                    873: static int rndis_init_response(USBNetState *s, rndis_init_msg_type *buf)
                    874: {
                    875:     rndis_init_cmplt_type *resp =
                    876:             rndis_queue_response(s, sizeof(rndis_init_cmplt_type));
                    877: 
                    878:     if (!resp)
                    879:         return USB_RET_STALL;
                    880: 
                    881:     resp->MessageType = cpu_to_le32(RNDIS_INITIALIZE_CMPLT);
                    882:     resp->MessageLength = cpu_to_le32(sizeof(rndis_init_cmplt_type));
                    883:     resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
                    884:     resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
                    885:     resp->MajorVersion = cpu_to_le32(RNDIS_MAJOR_VERSION);
                    886:     resp->MinorVersion = cpu_to_le32(RNDIS_MINOR_VERSION);
                    887:     resp->DeviceFlags = cpu_to_le32(RNDIS_DF_CONNECTIONLESS);
                    888:     resp->Medium = cpu_to_le32(RNDIS_MEDIUM_802_3);
                    889:     resp->MaxPacketsPerTransfer = cpu_to_le32(1);
                    890:     resp->MaxTransferSize = cpu_to_le32(ETH_FRAME_LEN +
                    891:                     sizeof(struct rndis_packet_msg_type) + 22);
                    892:     resp->PacketAlignmentFactor = cpu_to_le32(0);
                    893:     resp->AFListOffset = cpu_to_le32(0);
                    894:     resp->AFListSize = cpu_to_le32(0);
                    895:     return 0;
                    896: }
                    897: 
                    898: static int rndis_query_response(USBNetState *s,
                    899:                 rndis_query_msg_type *buf, unsigned int length)
                    900: {
                    901:     rndis_query_cmplt_type *resp;
                    902:     /* oid_supported_list is the largest data reply */
                    903:     uint8_t infobuf[sizeof(oid_supported_list)];
                    904:     uint32_t bufoffs, buflen;
                    905:     int infobuflen;
                    906:     unsigned int resplen;
                    907: 
                    908:     bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
                    909:     buflen = le32_to_cpu(buf->InformationBufferLength);
                    910:     if (bufoffs + buflen > length)
                    911:         return USB_RET_STALL;
                    912: 
                    913:     infobuflen = ndis_query(s, le32_to_cpu(buf->OID),
                    914:                             bufoffs + (uint8_t *) buf, buflen, infobuf,
                    915:                             sizeof(infobuf));
                    916:     resplen = sizeof(rndis_query_cmplt_type) +
                    917:             ((infobuflen < 0) ? 0 : infobuflen);
                    918:     resp = rndis_queue_response(s, resplen);
                    919:     if (!resp)
                    920:         return USB_RET_STALL;
                    921: 
                    922:     resp->MessageType = cpu_to_le32(RNDIS_QUERY_CMPLT);
                    923:     resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
                    924:     resp->MessageLength = cpu_to_le32(resplen);
                    925: 
                    926:     if (infobuflen < 0) {
                    927:         /* OID not supported */
                    928:         resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED);
                    929:         resp->InformationBufferLength = cpu_to_le32(0);
                    930:         resp->InformationBufferOffset = cpu_to_le32(0);
                    931:         return 0;
                    932:     }
                    933: 
                    934:     resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
                    935:     resp->InformationBufferOffset =
                    936:             cpu_to_le32(infobuflen ? sizeof(rndis_query_cmplt_type) - 8 : 0);
                    937:     resp->InformationBufferLength = cpu_to_le32(infobuflen);
                    938:     memcpy(resp + 1, infobuf, infobuflen);
                    939: 
                    940:     return 0;
                    941: }
                    942: 
                    943: static int rndis_set_response(USBNetState *s,
                    944:                 rndis_set_msg_type *buf, unsigned int length)
                    945: {
                    946:     rndis_set_cmplt_type *resp =
                    947:             rndis_queue_response(s, sizeof(rndis_set_cmplt_type));
                    948:     uint32_t bufoffs, buflen;
                    949:     int ret;
                    950: 
                    951:     if (!resp)
                    952:         return USB_RET_STALL;
                    953: 
                    954:     bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
                    955:     buflen = le32_to_cpu(buf->InformationBufferLength);
                    956:     if (bufoffs + buflen > length)
                    957:         return USB_RET_STALL;
                    958: 
                    959:     ret = ndis_set(s, le32_to_cpu(buf->OID),
                    960:                     bufoffs + (uint8_t *) buf, buflen);
                    961:     resp->MessageType = cpu_to_le32(RNDIS_SET_CMPLT);
                    962:     resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
                    963:     resp->MessageLength = cpu_to_le32(sizeof(rndis_set_cmplt_type));
                    964:     if (ret < 0) {
                    965:         /* OID not supported */
                    966:         resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED);
                    967:         return 0;
                    968:     }
                    969:     resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
                    970: 
                    971:     return 0;
                    972: }
                    973: 
                    974: static int rndis_reset_response(USBNetState *s, rndis_reset_msg_type *buf)
                    975: {
                    976:     rndis_reset_cmplt_type *resp =
                    977:             rndis_queue_response(s, sizeof(rndis_reset_cmplt_type));
                    978: 
                    979:     if (!resp)
                    980:         return USB_RET_STALL;
                    981: 
                    982:     resp->MessageType = cpu_to_le32(RNDIS_RESET_CMPLT);
                    983:     resp->MessageLength = cpu_to_le32(sizeof(rndis_reset_cmplt_type));
                    984:     resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
                    985:     resp->AddressingReset = cpu_to_le32(1); /* reset information */
                    986: 
                    987:     return 0;
                    988: }
                    989: 
                    990: static int rndis_keepalive_response(USBNetState *s,
                    991:                 rndis_keepalive_msg_type *buf)
                    992: {
                    993:     rndis_keepalive_cmplt_type *resp =
                    994:             rndis_queue_response(s, sizeof(rndis_keepalive_cmplt_type));
                    995: 
                    996:     if (!resp)
                    997:         return USB_RET_STALL;
                    998: 
                    999:     resp->MessageType = cpu_to_le32(RNDIS_KEEPALIVE_CMPLT);
                   1000:     resp->MessageLength = cpu_to_le32(sizeof(rndis_keepalive_cmplt_type));
                   1001:     resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
                   1002:     resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
                   1003: 
                   1004:     return 0;
                   1005: }
                   1006: 
                   1007: static int rndis_parse(USBNetState *s, uint8_t *data, int length)
                   1008: {
1.1.1.7   root     1009:     uint32_t msg_type;
1.1       root     1010:     le32 *tmp = (le32 *) data;
                   1011: 
1.1.1.7   root     1012:     msg_type = le32_to_cpup(tmp);
1.1       root     1013: 
                   1014:     switch (msg_type) {
                   1015:     case RNDIS_INITIALIZE_MSG:
                   1016:         s->rndis_state = RNDIS_INITIALIZED;
                   1017:         return rndis_init_response(s, (rndis_init_msg_type *) data);
                   1018: 
                   1019:     case RNDIS_HALT_MSG:
                   1020:         s->rndis_state = RNDIS_UNINITIALIZED;
                   1021:         return 0;
                   1022: 
                   1023:     case RNDIS_QUERY_MSG:
                   1024:         return rndis_query_response(s, (rndis_query_msg_type *) data, length);
                   1025: 
                   1026:     case RNDIS_SET_MSG:
                   1027:         return rndis_set_response(s, (rndis_set_msg_type *) data, length);
                   1028: 
                   1029:     case RNDIS_RESET_MSG:
                   1030:         rndis_clear_responsequeue(s);
                   1031:         s->out_ptr = s->in_ptr = s->in_len = 0;
                   1032:         return rndis_reset_response(s, (rndis_reset_msg_type *) data);
                   1033: 
                   1034:     case RNDIS_KEEPALIVE_MSG:
                   1035:         /* For USB: host does this every 5 seconds */
                   1036:         return rndis_keepalive_response(s, (rndis_keepalive_msg_type *) data);
                   1037:     }
                   1038: 
                   1039:     return USB_RET_STALL;
                   1040: }
                   1041: 
                   1042: static void usb_net_handle_reset(USBDevice *dev)
                   1043: {
                   1044: }
                   1045: 
1.1.1.9   root     1046: static int usb_net_handle_control(USBDevice *dev, USBPacket *p,
                   1047:                int request, int value, int index, int length, uint8_t *data)
1.1       root     1048: {
                   1049:     USBNetState *s = (USBNetState *) dev;
1.1.1.8   root     1050:     int ret;
1.1       root     1051: 
1.1.1.9   root     1052:     ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
1.1.1.8   root     1053:     if (ret >= 0) {
                   1054:         return ret;
                   1055:     }
1.1       root     1056: 
1.1.1.8   root     1057:     ret = 0;
                   1058:     switch(request) {
1.1       root     1059:     case ClassInterfaceOutRequest | USB_CDC_SEND_ENCAPSULATED_COMMAND:
1.1.1.8   root     1060:         if (!is_rndis(s) || value || index != 0) {
1.1       root     1061:             goto fail;
1.1.1.8   root     1062:         }
1.1       root     1063: #ifdef TRAFFIC_DEBUG
                   1064:         {
                   1065:             unsigned int i;
                   1066:             fprintf(stderr, "SEND_ENCAPSULATED_COMMAND:");
                   1067:             for (i = 0; i < length; i++) {
                   1068:                 if (!(i & 15))
                   1069:                     fprintf(stderr, "\n%04x:", i);
                   1070:                 fprintf(stderr, " %02x", data[i]);
                   1071:             }
                   1072:             fprintf(stderr, "\n\n");
                   1073:         }
                   1074: #endif
                   1075:         ret = rndis_parse(s, data, length);
                   1076:         break;
                   1077: 
                   1078:     case ClassInterfaceRequest | USB_CDC_GET_ENCAPSULATED_RESPONSE:
1.1.1.8   root     1079:         if (!is_rndis(s) || value || index != 0) {
1.1       root     1080:             goto fail;
1.1.1.8   root     1081:         }
1.1       root     1082:         ret = rndis_get_response(s, data);
                   1083:         if (!ret) {
                   1084:             data[0] = 0;
                   1085:             ret = 1;
                   1086:         }
                   1087: #ifdef TRAFFIC_DEBUG
                   1088:         {
                   1089:             unsigned int i;
                   1090:             fprintf(stderr, "GET_ENCAPSULATED_RESPONSE:");
                   1091:             for (i = 0; i < ret; i++) {
                   1092:                 if (!(i & 15))
                   1093:                     fprintf(stderr, "\n%04x:", i);
                   1094:                 fprintf(stderr, " %02x", data[i]);
                   1095:             }
                   1096:             fprintf(stderr, "\n\n");
                   1097:         }
                   1098: #endif
                   1099:         break;
                   1100: 
                   1101:     case DeviceRequest | USB_REQ_GET_INTERFACE:
                   1102:     case InterfaceRequest | USB_REQ_GET_INTERFACE:
                   1103:         data[0] = 0;
                   1104:         ret = 1;
                   1105:         break;
                   1106: 
                   1107:     case DeviceOutRequest | USB_REQ_SET_INTERFACE:
                   1108:     case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
                   1109:         ret = 0;
                   1110:         break;
                   1111: 
                   1112:     default:
                   1113:     fail:
                   1114:         fprintf(stderr, "usbnet: failed control transaction: "
                   1115:                         "request 0x%x value 0x%x index 0x%x length 0x%x\n",
                   1116:                         request, value, index, length);
                   1117:         ret = USB_RET_STALL;
                   1118:         break;
                   1119:     }
                   1120:     return ret;
                   1121: }
                   1122: 
                   1123: static int usb_net_handle_statusin(USBNetState *s, USBPacket *p)
                   1124: {
1.1.1.10! root     1125:     le32 buf[2];
1.1       root     1126:     int ret = 8;
                   1127: 
1.1.1.10! root     1128:     if (p->iov.size < 8) {
1.1       root     1129:         return USB_RET_STALL;
1.1.1.10! root     1130:     }
1.1       root     1131: 
1.1.1.10! root     1132:     buf[0] = cpu_to_le32(1);
        !          1133:     buf[1] = cpu_to_le32(0);
        !          1134:     usb_packet_copy(p, buf, 8);
1.1       root     1135:     if (!s->rndis_resp.tqh_first)
                   1136:         ret = USB_RET_NAK;
                   1137: 
                   1138: #ifdef TRAFFIC_DEBUG
1.1.1.10! root     1139:     fprintf(stderr, "usbnet: interrupt poll len %zu return %d",
        !          1140:             p->iov.size, ret);
        !          1141:     iov_hexdump(p->iov.iov, p->iov.niov, stderr, "usbnet", ret);
1.1       root     1142: #endif
                   1143: 
                   1144:     return ret;
                   1145: }
                   1146: 
                   1147: static int usb_net_handle_datain(USBNetState *s, USBPacket *p)
                   1148: {
                   1149:     int ret = USB_RET_NAK;
                   1150: 
                   1151:     if (s->in_ptr > s->in_len) {
                   1152:         s->in_ptr = s->in_len = 0;
                   1153:         ret = USB_RET_NAK;
                   1154:         return ret;
                   1155:     }
                   1156:     if (!s->in_len) {
                   1157:         ret = USB_RET_NAK;
                   1158:         return ret;
                   1159:     }
                   1160:     ret = s->in_len - s->in_ptr;
1.1.1.10! root     1161:     if (ret > p->iov.size) {
        !          1162:         ret = p->iov.size;
        !          1163:     }
        !          1164:     usb_packet_copy(p, &s->in_buf[s->in_ptr], ret);
1.1       root     1165:     s->in_ptr += ret;
                   1166:     if (s->in_ptr >= s->in_len &&
1.1.1.8   root     1167:                     (is_rndis(s) || (s->in_len & (64 - 1)) || !ret)) {
1.1       root     1168:         /* no short packet necessary */
                   1169:         s->in_ptr = s->in_len = 0;
                   1170:     }
                   1171: 
                   1172: #ifdef TRAFFIC_DEBUG
1.1.1.10! root     1173:     fprintf(stderr, "usbnet: data in len %zu return %d", p->iov.size, ret);
        !          1174:     iov_hexdump(p->iov.iov, p->iov.niov, stderr, "usbnet", ret);
1.1       root     1175: #endif
                   1176: 
                   1177:     return ret;
                   1178: }
                   1179: 
                   1180: static int usb_net_handle_dataout(USBNetState *s, USBPacket *p)
                   1181: {
1.1.1.10! root     1182:     int ret = p->iov.size;
1.1       root     1183:     int sz = sizeof(s->out_buf) - s->out_ptr;
                   1184:     struct rndis_packet_msg_type *msg =
                   1185:             (struct rndis_packet_msg_type *) s->out_buf;
                   1186:     uint32_t len;
                   1187: 
                   1188: #ifdef TRAFFIC_DEBUG
1.1.1.10! root     1189:     fprintf(stderr, "usbnet: data out len %zu\n", p->iov.size);
        !          1190:     iov_hexdump(p->iov.iov, p->iov.niov, stderr, "usbnet", p->iov.size);
1.1       root     1191: #endif
                   1192: 
                   1193:     if (sz > ret)
                   1194:         sz = ret;
1.1.1.10! root     1195:     usb_packet_copy(p, &s->out_buf[s->out_ptr], sz);
1.1       root     1196:     s->out_ptr += sz;
                   1197: 
1.1.1.8   root     1198:     if (!is_rndis(s)) {
1.1       root     1199:         if (ret < 64) {
1.1.1.4   root     1200:             qemu_send_packet(&s->nic->nc, s->out_buf, s->out_ptr);
1.1       root     1201:             s->out_ptr = 0;
                   1202:         }
                   1203:         return ret;
                   1204:     }
                   1205:     len = le32_to_cpu(msg->MessageLength);
                   1206:     if (s->out_ptr < 8 || s->out_ptr < len)
                   1207:         return ret;
                   1208:     if (le32_to_cpu(msg->MessageType) == RNDIS_PACKET_MSG) {
                   1209:         uint32_t offs = 8 + le32_to_cpu(msg->DataOffset);
                   1210:         uint32_t size = le32_to_cpu(msg->DataLength);
                   1211:         if (offs + size <= len)
1.1.1.4   root     1212:             qemu_send_packet(&s->nic->nc, s->out_buf + offs, size);
1.1       root     1213:     }
                   1214:     s->out_ptr -= len;
                   1215:     memmove(s->out_buf, &s->out_buf[len], s->out_ptr);
                   1216: 
                   1217:     return ret;
                   1218: }
                   1219: 
                   1220: static int usb_net_handle_data(USBDevice *dev, USBPacket *p)
                   1221: {
                   1222:     USBNetState *s = (USBNetState *) dev;
                   1223:     int ret = 0;
                   1224: 
                   1225:     switch(p->pid) {
                   1226:     case USB_TOKEN_IN:
                   1227:         switch (p->devep) {
                   1228:         case 1:
                   1229:             ret = usb_net_handle_statusin(s, p);
                   1230:             break;
                   1231: 
                   1232:         case 2:
                   1233:             ret = usb_net_handle_datain(s, p);
                   1234:             break;
                   1235: 
                   1236:         default:
                   1237:             goto fail;
                   1238:         }
                   1239:         break;
                   1240: 
                   1241:     case USB_TOKEN_OUT:
                   1242:         switch (p->devep) {
                   1243:         case 2:
                   1244:             ret = usb_net_handle_dataout(s, p);
                   1245:             break;
                   1246: 
                   1247:         default:
                   1248:             goto fail;
                   1249:         }
                   1250:         break;
                   1251: 
                   1252:     default:
                   1253:     fail:
                   1254:         ret = USB_RET_STALL;
                   1255:         break;
                   1256:     }
                   1257:     if (ret == USB_RET_STALL)
                   1258:         fprintf(stderr, "usbnet: failed data transaction: "
1.1.1.10! root     1259:                         "pid 0x%x ep 0x%x len 0x%zx\n",
        !          1260:                         p->pid, p->devep, p->iov.size);
1.1       root     1261:     return ret;
                   1262: }
                   1263: 
1.1.1.4   root     1264: static ssize_t usbnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
1.1       root     1265: {
1.1.1.4   root     1266:     USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
1.1       root     1267:     struct rndis_packet_msg_type *msg;
                   1268: 
1.1.1.8   root     1269:     if (is_rndis(s)) {
1.1       root     1270:         msg = (struct rndis_packet_msg_type *) s->in_buf;
                   1271:         if (!s->rndis_state == RNDIS_DATA_INITIALIZED)
1.1.1.3   root     1272:             return -1;
1.1       root     1273:         if (size + sizeof(struct rndis_packet_msg_type) > sizeof(s->in_buf))
1.1.1.3   root     1274:             return -1;
1.1       root     1275: 
                   1276:         memset(msg, 0, sizeof(struct rndis_packet_msg_type));
                   1277:         msg->MessageType = cpu_to_le32(RNDIS_PACKET_MSG);
                   1278:         msg->MessageLength = cpu_to_le32(size + sizeof(struct rndis_packet_msg_type));
                   1279:         msg->DataOffset = cpu_to_le32(sizeof(struct rndis_packet_msg_type) - 8);
                   1280:         msg->DataLength = cpu_to_le32(size);
                   1281:         /* msg->OOBDataOffset;
                   1282:          * msg->OOBDataLength;
                   1283:          * msg->NumOOBDataElements;
                   1284:          * msg->PerPacketInfoOffset;
                   1285:          * msg->PerPacketInfoLength;
                   1286:          * msg->VcHandle;
                   1287:          * msg->Reserved;
                   1288:          */
                   1289:         memcpy(msg + 1, buf, size);
                   1290:         s->in_len = size + sizeof(struct rndis_packet_msg_type);
                   1291:     } else {
                   1292:         if (size > sizeof(s->in_buf))
1.1.1.3   root     1293:             return -1;
1.1       root     1294:         memcpy(s->in_buf, buf, size);
                   1295:         s->in_len = size;
                   1296:     }
                   1297:     s->in_ptr = 0;
1.1.1.3   root     1298:     return size;
1.1       root     1299: }
                   1300: 
1.1.1.4   root     1301: static int usbnet_can_receive(VLANClientState *nc)
1.1       root     1302: {
1.1.1.4   root     1303:     USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
1.1       root     1304: 
1.1.1.8   root     1305:     if (is_rndis(s) && !s->rndis_state == RNDIS_DATA_INITIALIZED) {
1.1       root     1306:         return 1;
1.1.1.8   root     1307:     }
1.1       root     1308: 
                   1309:     return !s->in_len;
                   1310: }
                   1311: 
1.1.1.4   root     1312: static void usbnet_cleanup(VLANClientState *nc)
1.1.1.2   root     1313: {
1.1.1.4   root     1314:     USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
1.1.1.2   root     1315: 
1.1.1.4   root     1316:     s->nic = NULL;
1.1.1.2   root     1317: }
                   1318: 
1.1       root     1319: static void usb_net_handle_destroy(USBDevice *dev)
                   1320: {
                   1321:     USBNetState *s = (USBNetState *) dev;
                   1322: 
                   1323:     /* TODO: remove the nd_table[] entry */
1.1.1.4   root     1324:     rndis_clear_responsequeue(s);
                   1325:     qemu_del_vlan_client(&s->nic->nc);
1.1       root     1326: }
                   1327: 
1.1.1.4   root     1328: static NetClientInfo net_usbnet_info = {
                   1329:     .type = NET_CLIENT_TYPE_NIC,
                   1330:     .size = sizeof(NICState),
                   1331:     .can_receive = usbnet_can_receive,
                   1332:     .receive = usbnet_receive,
                   1333:     .cleanup = usbnet_cleanup,
                   1334: };
1.1       root     1335: 
1.1.1.4   root     1336: static int usb_net_initfn(USBDevice *dev)
                   1337: {
                   1338:     USBNetState *s = DO_UPCAST(USBNetState, dev, dev);
1.1       root     1339: 
1.1.1.8   root     1340:     usb_desc_init(dev);
1.1       root     1341: 
                   1342:     s->rndis_state = RNDIS_UNINITIALIZED;
1.1.1.4   root     1343:     QTAILQ_INIT(&s->rndis_resp);
                   1344: 
1.1       root     1345:     s->medium = 0;     /* NDIS_MEDIUM_802_3 */
                   1346:     s->speed = 1000000; /* 100MBps, in 100Bps units */
                   1347:     s->media_state = 0;        /* NDIS_MEDIA_STATE_CONNECTED */;
                   1348:     s->filter = 0;
                   1349:     s->vendorid = 0x1234;
                   1350: 
1.1.1.4   root     1351:     qemu_macaddr_default_if_unset(&s->conf.macaddr);
                   1352:     s->nic = qemu_new_nic(&net_usbnet_info, &s->conf,
                   1353:                           s->dev.qdev.info->name, s->dev.qdev.id, s);
                   1354:     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
                   1355:     snprintf(s->usbstring_mac, sizeof(s->usbstring_mac),
                   1356:              "%02x%02x%02x%02x%02x%02x",
                   1357:              0x40,
                   1358:              s->conf.macaddr.a[1],
                   1359:              s->conf.macaddr.a[2],
                   1360:              s->conf.macaddr.a[3],
                   1361:              s->conf.macaddr.a[4],
                   1362:              s->conf.macaddr.a[5]);
1.1.1.8   root     1363:     usb_desc_set_string(dev, STRING_ETHADDR, s->usbstring_mac);
1.1       root     1364: 
1.1.1.8   root     1365:     add_boot_device_path(s->conf.bootindex, &dev->qdev, "/ethernet@0");
1.1.1.4   root     1366:     return 0;
                   1367: }
1.1       root     1368: 
1.1.1.4   root     1369: static USBDevice *usb_net_init(const char *cmdline)
                   1370: {
                   1371:     USBDevice *dev;
                   1372:     QemuOpts *opts;
                   1373:     int idx;
                   1374: 
1.1.1.8   root     1375:     opts = qemu_opts_parse(qemu_find_opts("net"), cmdline, 0);
1.1.1.4   root     1376:     if (!opts) {
                   1377:         return NULL;
                   1378:     }
                   1379:     qemu_opt_set(opts, "type", "nic");
                   1380:     qemu_opt_set(opts, "model", "usb");
1.1       root     1381: 
1.1.1.4   root     1382:     idx = net_client_init(NULL, opts, 0);
                   1383:     if (idx == -1) {
                   1384:         return NULL;
                   1385:     }
1.1       root     1386: 
1.1.1.4   root     1387:     dev = usb_create(NULL /* FIXME */, "usb-net");
1.1.1.6   root     1388:     if (!dev) {
                   1389:         return NULL;
                   1390:     }
1.1.1.4   root     1391:     qdev_set_nic_properties(&dev->qdev, &nd_table[idx]);
1.1.1.5   root     1392:     qdev_init_nofail(&dev->qdev);
1.1.1.4   root     1393:     return dev;
                   1394: }
                   1395: 
1.1.1.10! root     1396: static const VMStateDescription vmstate_usb_net = {
        !          1397:     .name = "usb-net",
        !          1398:     .unmigratable = 1,
        !          1399: };
        !          1400: 
1.1.1.4   root     1401: static struct USBDeviceInfo net_info = {
                   1402:     .product_desc   = "QEMU USB Network Interface",
                   1403:     .qdev.name      = "usb-net",
1.1.1.8   root     1404:     .qdev.fw_name    = "network",
1.1.1.4   root     1405:     .qdev.size      = sizeof(USBNetState),
1.1.1.10! root     1406:     .qdev.vmsd      = &vmstate_usb_net,
1.1.1.8   root     1407:     .usb_desc       = &desc_net,
1.1.1.4   root     1408:     .init           = usb_net_initfn,
                   1409:     .handle_packet  = usb_generic_handle_packet,
                   1410:     .handle_reset   = usb_net_handle_reset,
                   1411:     .handle_control = usb_net_handle_control,
                   1412:     .handle_data    = usb_net_handle_data,
                   1413:     .handle_destroy = usb_net_handle_destroy,
                   1414:     .usbdevice_name = "net",
                   1415:     .usbdevice_init = usb_net_init,
                   1416:     .qdev.props     = (Property[]) {
                   1417:         DEFINE_NIC_PROPERTIES(USBNetState, conf),
                   1418:         DEFINE_PROP_END_OF_LIST(),
                   1419:     }
                   1420: };
                   1421: 
                   1422: static void usb_net_register_devices(void)
                   1423: {
                   1424:     usb_qdev_register(&net_info);
1.1       root     1425: }
1.1.1.4   root     1426: device_init(usb_net_register_devices)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.