📄 rndis.c
字号:
case OID_GEN_VENDOR_DRIVER_VERSION: *INFBUF = 0x00001000; break; case OID_GEN_PHYSICAL_MEDIUM: *INFBUF = NDIS_MEDIUM_802_3; /*NDIS_MEDIUM_WIRELESS_LAN;*/ break; case OID_GEN_CURRENT_LOOKAHEAD: *INFBUF = (uint32_t) 1280; //102; /******* 802.3 (Ethernet) *******/ /*The address of the NIC encoded in the hardware.*/ case OID_802_3_PERMANENT_ADDRESS: //Clear unused bytes *(INFBUF + 1) = 0; //Set address *((uint8_t *)INFBUF + 0) = *(((uint8_t * ) &rndis_ethernet_addr) + 5); *((uint8_t *)INFBUF + 1) = *(((uint8_t * ) &rndis_ethernet_addr) + 4); *((uint8_t *)INFBUF + 2) = *(((uint8_t * ) &rndis_ethernet_addr) + 3); *((uint8_t *)INFBUF + 3) = *(((uint8_t * ) &rndis_ethernet_addr) + 2); *((uint8_t *)INFBUF + 4) = *(((uint8_t * ) &rndis_ethernet_addr) + 1); *((uint8_t *)INFBUF + 5) = *(((uint8_t * ) &rndis_ethernet_addr) + 0); /*4+2 = 6 Bytes of eth address */ c->InformationBufferLength += 2; break; /*The address the NIC is currently using.*/ case OID_802_3_CURRENT_ADDRESS: //Clear unused bytes *(INFBUF + 1) = 0; //Set address *((uint8_t *)INFBUF + 0) = *(((uint8_t * ) &rndis_ethernet_addr) + 5); *((uint8_t *)INFBUF + 1) = *(((uint8_t * ) &rndis_ethernet_addr) + 4); *((uint8_t *)INFBUF + 2) = *(((uint8_t * ) &rndis_ethernet_addr) + 3); *((uint8_t *)INFBUF + 3) = *(((uint8_t * ) &rndis_ethernet_addr) + 2); *((uint8_t *)INFBUF + 4) = *(((uint8_t * ) &rndis_ethernet_addr) + 1); *((uint8_t *)INFBUF + 5) = *(((uint8_t * ) &rndis_ethernet_addr) + 0); /*4+2 = 6 Bytes of eth address */ c->InformationBufferLength += 2; break; /* The multicast address list on the NIC enabled for packet reception. */ case OID_802_3_MULTICAST_LIST: *INFBUF = 0xE000000; break; /* The maximum number of multicast addresses the NIC driver can manage. */ case OID_802_3_MAXIMUM_LIST_SIZE: *INFBUF = 1; break; /* Features supported by the underlying driver, which could be emulating Ethernet. */ case OID_802_3_MAC_OPTIONS: *INFBUF = 0; break; /* Frames received with alignment error */ case OID_802_3_RCV_ERROR_ALIGNMENT: *INFBUF = 0; break; /* Frames transmitted with one collision */ case OID_802_3_XMIT_ONE_COLLISION: *INFBUF = 0; break; /* Frames transmitted with more than one collision */ case OID_802_3_XMIT_MORE_COLLISIONS: *INFBUF = 0; break; /*** 802.11 OIDs ***/ case OID_802_11_BSSID: *INFBUF = (uint32_t)panid; *(INFBUF + 1) = 0; /*4+2 = 6 Bytes of eth address */ c->InformationBufferLength += 2; break; case OID_802_11_SSID: /* Our SSID is *always* "PANID: 0xXXXX", length = 13 */ *INFBUF = 13; strncpy_P((char*)(INFBUF + 1), PSTR("PANID: 0xBAAD"), 13); break; case OID_802_11_NETWORK_TYPE_IN_USE: *INFBUF = 0; /* Ndis802_11FH - it's all lies anyway */ break; case OID_802_11_RSSI: *((int32_t *) INFBUF) = -20; //-20 dBm break; case OID_802_11_BSSID_LIST: break; /* todo: */ case OID_802_11_INFRASTRUCTURE_MODE: case OID_802_11_SUPPORTED_RATES: case OID_802_11_CONFIGURATION: case OID_802_11_WEP_STATUS: case OID_802_11_AUTHENTICATION_MODE: break; /*** Statistical ***/ /* Frames transmitted without errors */ case OID_GEN_XMIT_OK: *INFBUF = rndis_stat.txok; break; /* Frames received without errors */ case OID_GEN_RCV_OK: *INFBUF = rndis_stat.rxok; break; /* Frames received with errors */ case OID_GEN_RCV_ERROR: *INFBUF = rndis_stat.rxbad; break; /* Frames transmitted with errors */ case OID_GEN_XMIT_ERROR: *INFBUF = rndis_stat.txbad; break; /* Frames dropped due to lack of buffer space */ case OID_GEN_RCV_NO_BUFFER: *INFBUF = 0; /* Lies! */ break; /*** Power Managment ***/ case OID_PNP_CAPABILITIES: c->InformationBufferLength = sizeof(struct NDIS_PM_WAKE_UP_CAPABILITIES); //Sorry, I don't play ball. Power managment is for hippies memset((char *)INFBUF, 0, sizeof(struct NDIS_PM_WAKE_UP_CAPABILITIES)); break; case OID_PNP_QUERY_POWER: c->InformationBufferLength = 0; break; case OID_PNP_ENABLE_WAKE_UP: *INFBUF = 0; /* Nothing Supported */ break; default: status = RNDIS_STATUS_FAILURE; c->InformationBufferLength = 0; break; } //Set Status now that we are done with Oid c->Status = status; //Calculate message size c->MessageLength = sizeof (rndis_query_cmplt_t) + c->InformationBufferLength; //Check if we are sending no information buffer if (c->InformationBufferLength == 0) { c->InformationBufferOffset = 0; } //Set it up data_to_send = c->MessageLength; }#undef INFBUF#define INFBUF ((uint32_t *)((uint8_t *)&(m->RequestId) + m->InformationBufferOffset))#define CFGBUF ((rndis_config_parameter_t *) INFBUF)#define PARMNAME ((uint8_t *)CFGBUF + CFGBUF->ParameterNameOffset)#define PARMVALUE ((uint8_t *)CFGBUF + CFGBUF->ParameterValueOffset)#define PARM_NAME_LENGTH 25 /* Maximum parameter name length *//** * \brief Function to deal with a RNDIS "SET" command present in the * encapsulated_buffer */void rndis_set_process(void) { rndis_set_cmplt_t * c; rndis_set_msg_t * m; c = ((rndis_set_cmplt_t *)encapsulated_buffer); m = ((rndis_set_msg_t *)encapsulated_buffer); //Never have longer parameter names than PARM_NAME_LENGTH char parmname[PARM_NAME_LENGTH]; uint8_t i; int8_t parmlength; /* The parameter name seems to be transmitted in uint16_t, but we want this in uint8_t. Hence have to throw out some info... */ if (CFGBUF->ParameterNameLength > (PARM_NAME_LENGTH*2)) { parmlength = PARM_NAME_LENGTH * 2; } else { parmlength = CFGBUF->ParameterNameLength; } i = 0; while(parmlength > 0) { //Convert from uint16_t to char array. parmname[i] = (char)*(PARMNAME + 2*i); parmlength -= 2; i++; } switch(m->Oid) { /* Parameters set up in 'Advanced' tab */ case OID_GEN_RNDIS_CONFIG_PARAMETER: /* Parameter name: rawmode Parameter desc: Enables or disable raw capture of 802.15.4 Packets Parameter type: single octet Parameter values: '0' = disabled, '1' = enabled */ if (strncmp_P(parmname, PSTR("rawmode"), 7) == 0) { if (*PARMVALUE == '0') { usbstick_mode.raw = 0; } else { usbstick_mode.raw = 1; } } break; /* Mandatory general OIDs */ case OID_GEN_CURRENT_PACKET_FILTER: oid_packet_filter = *INFBUF; if (oid_packet_filter) { rndis_packetFilter(oid_packet_filter); rndis_state = rndis_data_initialized; } else { rndis_state = rndis_initialized; } break; case OID_GEN_CURRENT_LOOKAHEAD: break; case OID_GEN_PROTOCOL_OPTIONS: break; /* Mandatory 802_3 OIDs */ case OID_802_3_MULTICAST_LIST: break; /* Mandatory 802.11 OIDs */ case OID_802_11_BSSID: panid = *INFBUF; break; case OID_802_11_SSID: break; //TODO: rest of 802.11 /* Power Managment: fails for now */ case OID_PNP_ADD_WAKE_UP_PATTERN: case OID_PNP_REMOVE_WAKE_UP_PATTERN: case OID_PNP_ENABLE_WAKE_UP: default: //c->MessageID is same as before c->MessageType = REMOTE_NDIS_SET_CMPLT; c->MessageLength = sizeof(rndis_set_cmplt_t); c->Status = RNDIS_STATUS_FAILURE; data_to_send = c->MessageLength; return; break; } //c->MessageID is same as before c->MessageType = REMOTE_NDIS_SET_CMPLT; c->MessageLength = sizeof(rndis_set_cmplt_t); c->Status = RNDIS_STATUS_SUCCESS; data_to_send = c->MessageLength; return; }/** * \brief Handle "GET ENCAPSULATED COMMAND" * * \return True on success, false on failure. * * This function assumes the message has already set up in * the "encapsulated_buffer" variable. This will be done by * the "SEND ENCAPSULATED COMMAND" message, which will trigger * and interrupt on the host so it knows data is ready. */uint8_t get_encapsulated_command(void) { U8 nb_byte, zlp, i; //We assume this is already set up... //Received setup message OK Usb_ack_receive_setup(); if ((data_to_send % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; } else { zlp = FALSE; } //!< no need of zero length packet i = 0; while((data_to_send != 0) && (!Is_usb_receive_out())) { while(!Is_usb_read_control_enabled()); nb_byte=0; while(data_to_send != 0) //!< Send data until necessary { if(nb_byte++==EP_CONTROL_LENGTH) //!< Check endpoint 0 size { break; } Usb_write_byte(encapsulated_buffer[i]); i++; data_to_send--; } Usb_send_control_in(); } if(Is_usb_receive_out()) { Usb_ack_receive_out(); return TRUE; } //!< abort from Host if(zlp == TRUE) { while(!Is_usb_read_control_enabled()); Usb_send_control_in(); } while(!Is_usb_receive_out()); Usb_ack_receive_out(); return TRUE; }/** * \brief Send a status packet back to the host * * \return Sucess or Failure * \retval 1 Success * \retval 0 Failure */uint8_t rndis_send_status(rndis_Status_t stat) { uint8_t i; if(Is_usb_read_control_enabled() && !data_to_send) { rndis_indicate_status_t * m; m = (rndis_indicate_status_t *)encapsulated_buffer; m->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG; m->MessageLength = sizeof(rndis_indicate_status_t); m->Status = stat; for(i = 0; i < sizeof(rndis_indicate_status_t); i++) { Usb_write_byte(encapsulated_buffer[i]); } Usb_send_control_in(); while(!(Is_usb_read_control_enabled())); while(!Is_usb_receive_out()); Usb_ack_receive_out(); return 1; } return 0; }/****************** Radio Interface ****************//** * \brief Set the packet filter - currently distinguishes * between promiscuous mode and normal mode */void rndis_packetFilter(uint32_t newfilter){ if (newfilter & NDIS_PACKET_TYPE_PROMISCUOUS) { rxMode = RX_ON; radio_set_trx_state(RX_ON); } else { rxMode = RX_AACK_ON; radio_set_trx_state(RX_AACK_ON); }}/** @} */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -