📄 rndis.c
字号:
DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. stats->tx_packets/42; retval = 0; } else { *((u32 *) resp + 6) = 0; retval = 0; } break; case OID_GEN_DIRECTED_BYTES_RCV: DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__); *((u32 *) resp + 6) = 0; retval = 0; break; case OID_GEN_DIRECTED_FRAMES_RCV: DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__); *((u32 *) resp + 6) = 0; retval = 0; break; case OID_GEN_MULTICAST_BYTES_RCV: DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. stats->multicast*1111; retval = 0; } else { *((u32 *) resp + 6) = 0; retval = 0; } break; case OID_GEN_MULTICAST_FRAMES_RCV: DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. stats->multicast; retval = 0; } else { *((u32 *) resp + 6) = 0; retval = 0; } break; case OID_GEN_BROADCAST_BYTES_RCV: DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. stats->rx_packets/42*255; retval = 0; } else { *((u32 *) resp + 6) = 0; retval = 0; } break; case OID_GEN_BROADCAST_FRAMES_RCV: DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. stats->rx_packets/42; retval = 0; } else { *((u32 *) resp + 6) = 0; retval = 0; } break; case OID_GEN_RCV_CRC_ERROR: DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { *((u32 *) resp + 6) = rndis_per_dev_params [configNr]. stats->rx_crc_errors; retval = 0; } else { *((u32 *) resp + 6) = 0; retval = 0; } break; case OID_GEN_TRANSMIT_QUEUE_LENGTH: DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__); *((u32 *) resp + 6) = 0; retval = 0; break; case OID_GEN_GET_TIME_CAPS: DEBUG("%s: OID_GEN_GET_TIME_CAPS\n", __FUNCTION__); break; case OID_GEN_GET_NETCARD_TIME: DEBUG("%s: OID_GEN_GET_NETCARD_TIME\n", __FUNCTION__); break; case OID_GEN_NETCARD_LOAD: DEBUG("%s: OID_GEN_NETCARD_LOAD\n", __FUNCTION__); break; case OID_GEN_DEVICE_PROFILE: DEBUG("%s: OID_GEN_DEVICE_PROFILE\n", __FUNCTION__); break; case OID_GEN_INIT_TIME_MS: DEBUG("%s: OID_GEN_INIT_TIME_MS\n", __FUNCTION__); break; case OID_GEN_RESET_COUNTS: DEBUG("%s: OID_GEN_RESET_COUNTS\n", __FUNCTION__); break; case OID_GEN_MEDIA_SENSE_COUNTS: DEBUG("%s: OID_GEN_MEDIA_SENSE_COUNTS\n", __FUNCTION__); break; case OID_GEN_FRIENDLY_NAME: DEBUG("%s: OID_GEN_FRIENDLY_NAME\n", __FUNCTION__); break; case OID_GEN_MINIPORT_INFO: DEBUG("%s: OID_GEN_MINIPORT_INFO\n", __FUNCTION__); break; case OID_GEN_RESET_VERIFY_PARAMETERS: DEBUG("%s: OID_GEN_RESET_VERIFY_PARAMETERS\n", __FUNCTION__); break; /* mandatory */ case OID_802_3_PERMANENT_ADDRESS: DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__); if (rndis_per_dev_params [configNr].dev) { length = ETH_ALEN; memcpy ((u8 *) resp + 24, rndis_per_dev_params [configNr].host_mac, length); retval = 0; } else { *((u32 *) resp + 6) = 0; retval = 0; } break; /* mandatory */ case OID_802_3_CURRENT_ADDRESS: DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__); if (rndis_per_dev_params [configNr].dev) { length = ETH_ALEN; memcpy ((u8 *) resp + 24, rndis_per_dev_params [configNr].host_mac, length); retval = 0; } break; /* mandatory */ case OID_802_3_MULTICAST_LIST: DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); length = 4; /* Multicast base address only */ *((u32 *) resp + 6) = 0xE0000000; retval = 0; break; /* mandatory */ case OID_802_3_MAXIMUM_LIST_SIZE: DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__); length = 4; /* Multicast base address only */ *((u32 *) resp + 6) = 1; retval = 0; break; case OID_802_3_MAC_OPTIONS: DEBUG("%s: OID_802_3_MAC_OPTIONS\n", __FUNCTION__); break; /* mandatory */ case OID_802_3_RCV_ERROR_ALIGNMENT: DEBUG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__); if (rndis_per_dev_params [configNr].stats) { length = 4; *((u32 *) resp + 6) = rndis_per_dev_params [configNr] .stats->rx_frame_errors; retval = 0; } break; /* mandatory */ case OID_802_3_XMIT_ONE_COLLISION: DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__); length = 4; *((u32 *) resp + 6) = 0; retval = 0; break; /* mandatory */ case OID_802_3_XMIT_MORE_COLLISIONS: DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__); length = 4; *((u32 *) resp + 6) = 0; retval = 0; break; case OID_802_3_XMIT_DEFERRED: DEBUG("%s: OID_802_3_XMIT_DEFERRED\n", __FUNCTION__); /* TODO */ break; case OID_802_3_XMIT_MAX_COLLISIONS: DEBUG("%s: OID_802_3_XMIT_MAX_COLLISIONS\n", __FUNCTION__); /* TODO */ break; case OID_802_3_RCV_OVERRUN: DEBUG("%s: OID_802_3_RCV_OVERRUN\n", __FUNCTION__); /* TODO */ break; case OID_802_3_XMIT_UNDERRUN: DEBUG("%s: OID_802_3_XMIT_UNDERRUN\n", __FUNCTION__); /* TODO */ break; case OID_802_3_XMIT_HEARTBEAT_FAILURE: DEBUG("%s: OID_802_3_XMIT_HEARTBEAT_FAILURE\n", __FUNCTION__); /* TODO */ break; case OID_802_3_XMIT_TIMES_CRS_LOST: DEBUG("%s: OID_802_3_XMIT_TIMES_CRS_LOST\n", __FUNCTION__); /* TODO */ break; case OID_802_3_XMIT_LATE_COLLISIONS: DEBUG("%s: OID_802_3_XMIT_LATE_COLLISIONS\n", __FUNCTION__); /* TODO */ break; default: printk (KERN_ERR "%s: unknown OID 0x%08X\n", __FUNCTION__, OID); } resp->InformationBufferOffset = 16; resp->InformationBufferLength = length; resp->MessageLength = 24 + length; r->length = 24 + length; return retval;}static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, rndis_resp_t *r){ rndis_set_cmplt_type *resp; int i, retval = -ENOTSUPP; struct rndis_config_parameter *param; struct rndis_params *params; u8 *cp; if (!r) return -ENOMEM; resp = (rndis_set_cmplt_type *) r->buf; if (!resp) return -ENOMEM; cp = (u8 *)resp; switch (OID) { case OID_GEN_CURRENT_PACKET_FILTER: params = &rndis_per_dev_params [configNr]; retval = 0; /* FIXME use this NDIS_PACKET_TYPE_* bitflags to * filter packets in hard_start_xmit() * NDIS_PACKET_TYPE_x == CDC_PACKET_TYPE_x for x in: * PROMISCUOUS, DIRECTED, * MULTICAST, ALL_MULTICAST, BROADCAST */ params->filter = *(u32 *)buf; DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n", __FUNCTION__, params->filter); /* this call has a significant side effect: it's * what makes the packet flow start and stop, like * activating the CDC Ethernet altsetting. */ if (params->filter) { params->state = RNDIS_DATA_INITIALIZED; netif_carrier_on(params->dev); if (netif_running(params->dev)) netif_wake_queue (params->dev); } else { params->state = RNDIS_INITIALIZED; netif_carrier_off (params->dev); netif_stop_queue (params->dev); } break; case OID_802_3_MULTICAST_LIST: /* I think we can ignore this */ DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__); retval = 0; break; case OID_GEN_RNDIS_CONFIG_PARAMETER: DEBUG("%s: OID_GEN_RNDIS_CONFIG_PARAMETER\n", __FUNCTION__); param = (struct rndis_config_parameter *) buf; if (param) { for (i = 0; i < param->ParameterNameLength; i++) { DEBUG ("%c", *(buf + param->ParameterNameOffset + i)); } DEBUG ("\n"); } retval = 0; break; default: printk (KERN_ERR "%s: unknown OID 0x%08X\n", __FUNCTION__, OID); } return retval;}/* * Response Functions */static int rndis_init_response (int configNr, rndis_init_msg_type *buf){ rndis_init_cmplt_type *resp; rndis_resp_t *r; if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type)); if (!r) return -ENOMEM; resp = (rndis_init_cmplt_type *) r->buf; if (!resp) return -ENOMEM; resp->MessageType = REMOTE_NDIS_INITIALIZE_CMPLT; resp->MessageLength = 52; resp->RequestID = buf->RequestID; resp->Status = RNDIS_STATUS_SUCCESS; resp->MajorVersion = RNDIS_MAJOR_VERSION; resp->MinorVersion = RNDIS_MINOR_VERSION; resp->DeviceFlags = RNDIS_DF_CONNECTIONLESS; resp->Medium = RNDIS_MEDIUM_802_3; resp->MaxPacketsPerTransfer = 1; resp->MaxTransferSize = rndis_per_dev_params [configNr].dev->mtu + sizeof (struct ethhdr) + sizeof (struct rndis_packet_msg_type) + 22; resp->PacketAlignmentFactor = 0; resp->AFListOffset = 0; resp->AFListSize = 0; if (rndis_per_dev_params [configNr].ack) rndis_per_dev_params [configNr].ack ( rndis_per_dev_params [configNr].dev); return 0;}static int rndis_query_response (int configNr, rndis_query_msg_type *buf){ rndis_query_cmplt_type *resp; rndis_resp_t *r; DEBUG("%s: OID = %08X\n", __FUNCTION__, buf->OID); if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP; /* * we need more memory: * oid_supported_list is the largest answer */ r = rndis_add_response (configNr, sizeof (oid_supported_list)); if (!r) return -ENOMEM; resp = (rndis_query_cmplt_type *) r->buf; if (!resp) return -ENOMEM; resp->MessageType = REMOTE_NDIS_QUERY_CMPLT; resp->MessageLength = 24; resp->RequestID = buf->RequestID; if (gen_ndis_query_resp (configNr, buf->OID, r)) { /* OID not supported */ resp->Status = RNDIS_STATUS_NOT_SUPPORTED; resp->InformationBufferLength = 0; resp->InformationBufferOffset = 0; } else resp->Status = RNDIS_STATUS_SUCCESS; if (rndis_per_dev_params [configNr].ack) rndis_per_dev_params [configNr].ack ( rndis_per_dev_params [configNr].dev); return 0;}static int rndis_set_response (int configNr, rndis_set_msg_type *buf){ rndis_set_cmplt_type *resp; rndis_resp_t *r; int i; r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type)); if (!r) return -ENOMEM; resp = (rndis_set_cmplt_type *) r->buf; if (!resp) return -ENOMEM; DEBUG("%s: Length: %d\n", __FUNCTION__, buf->InformationBufferLength); DEBUG("%s: Offset: %d\n", __FUNCTION__, buf->InformationBufferOffset); DEBUG("%s: InfoBuffer: ", __FUNCTION__); for (i = 0; i < buf->InformationBufferLength; i++) { DEBUG ("%02x ", *(((u8 *) buf) + i + 12 + buf->InformationBufferOffset)); } DEBUG ("\n"); resp->MessageType = REMOTE_NDIS_SET_CMPLT; resp->MessageLength = 16; resp->RequestID = buf->RequestID; if (gen_ndis_set_resp (configNr, buf->OID, ((u8 *) buf) + 28, buf->InformationBufferLength, r)) resp->Status = RNDIS_STATUS_NOT_SUPPORTED; else resp->Status = RNDIS_STATUS_SUCCESS; if (rndis_per_dev_params [configNr].ack) rndis_per_dev_params [configNr].ack (rndis_per_dev_params [configNr].dev); return 0;}static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf){ rndis_reset_cmplt_type *resp; rndis_resp_t *r; r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type)); if (!r) return -ENOMEM; resp = (rndis_reset_cmplt_type *) r->buf; if (!resp) return -ENOMEM; resp->MessageType = REMOTE_NDIS_RESET_CMPLT; resp->MessageLength = 16; resp->Status = RNDIS_STATUS_SUCCESS; resp->AddressingReset = 1; /* resent information */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -