diff --git a/src/ckernelwifi.cc b/src/ckernelwifi.cc index 2a2d1df..cf83af3 100644 --- a/src/ckernelwifi.cc +++ b/src/ckernelwifi.cc @@ -44,24 +44,19 @@ void CKernelWifi::cout_mac_address(struct ether_addr *src) std::cout << addr; } -int CKernelWifi::send_tx_info_frame_nl(struct ether_addr *src, unsigned int flags, int signal, struct hwsim_tx_rate *tx_attempts, unsigned long cookie) +struct nl_msg *CKernelWifi::build_tx_info(struct ether_addr *src, unsigned int flags, int signal, struct hwsim_tx_rate *tx_attempts, unsigned long cookie) { struct nl_msg *msg = nullptr; msg = nlmsg_alloc(); - if (!msg) { - - std::cerr << "Error allocating new message MSG !" << std::endl ; - nlmsg_free(msg); - return 0; - } + if (!msg) + return nullptr; if (m_family_id < 0){ - std::cerr << __func__ << "m_family_id < 0" << std::endl ; nlmsg_free(msg); - return 0; + return nullptr; } genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, m_family_id, 0, NLM_F_REQUEST, HWSIM_CMD_TX_INFO_FRAME, VERSION_NR); @@ -77,10 +72,21 @@ int CKernelWifi::send_tx_info_frame_nl(struct ether_addr *src, unsigned int flag { std::cerr << "Error filling payload" << std::endl; nlmsg_free(msg); - return 0; + return NULL; } - //nl_send_auto_complete(_netlink_socket, msg); //deprecated + return msg; +} + +int CKernelWifi::send_tx_info_frame_nl(struct ether_addr *src, unsigned int flags, int signal, struct hwsim_tx_rate *tx_attempts, unsigned long cookie) +{ + struct nl_msg *msg = build_tx_info(src, flags, signal, tx_attempts, cookie); + + if (!msg) { + std::cerr << "Error allocating new message MSG !" << std::endl ; + nlmsg_free(msg); + return 0; + } if (nl_send_auto(_netlink_socket, msg) < 0) { @@ -137,31 +143,6 @@ int CKernelWifi::process_messages(struct nl_msg *msg) struct ether_addr macsrchwsim; memcpy(&macsrchwsim,src,sizeof(macsrchwsim)); // backup the original mac src - /* Let's flag this frame as ACK'ed */ - /* whatever that means... */ - unsigned int flags = nla_get_u32(attrs[HWSIM_ATTR_FLAGS]); - flags |= HWSIM_TX_STAT_ACK; - - /* this is the signal sent to the sender, not the receiver */ - int signal = -10; - - /* We get the tx_rates struct */ - struct hwsim_tx_rate* tx_rates = (struct hwsim_tx_rate *)nla_data(attrs[HWSIM_ATTR_TX_INFO]); - - u64 cookie = nla_get_u64(attrs[HWSIM_ATTR_COOKIE]); - - /* this has to be an ack the driver expects */ - /* what does the driver do with these values? can i remove them? */ - send_tx_info_frame_nl(src, flags, signal, tx_rates, cookie); - - /* - * no need to send a tx info frame indicating failure with a - * signal of 0 - that was done in the tx code i took this from - * if i check for ack messages than i could add a failure message - */ - - /* we are now done with our code addition which sends the ack */ - /* we get the attributes*/ char* data = (char *)nla_data(attrs[HWSIM_ATTR_FRAME]); unsigned int data_len = nla_len(attrs[HWSIM_ATTR_FRAME]); @@ -198,8 +179,10 @@ int CKernelWifi::process_messages(struct nl_msg *msg) } int value=_SendSignal(&power, (char*)nlh, msg_len); - if( value == SOCKET_ERROR ) + if( value == SOCKET_ERROR ) { + printf("Error sending to server\n"); manage_server_crash(); + } // Send also on the others interfaces on the same VM : // -------------------> @@ -454,6 +437,7 @@ int CKernelWifi::send_cloned_frame_msg(struct ether_addr *dst, char *data, int d } void CKernelWifi::recv_from_server(){ + uint8_t dropped; if ( ! is_connected_to_server()) return ; @@ -467,8 +451,10 @@ void CKernelWifi::recv_from_server(){ return ; TPower power; - if( _RecvSignal(&power, &Buffer) == SOCKET_ERROR ) + if( _RecvSignal(&power, &dropped, &Buffer) == SOCKET_ERROR ) { + printf("Error receiving from server\n"); manage_server_crash(); + } int signal = power ; @@ -478,6 +464,33 @@ void CKernelWifi::recv_from_server(){ /* generic netlink header */ struct genlmsghdr* gnlh = (struct genlmsghdr*)nlmsg_data(nlh); + /* we get the attributes*/ + struct nlattr *attrs[HWSIM_ATTR_MAX + 1]; + genlmsg_parse(nlh, 0, attrs, HWSIM_ATTR_MAX, NULL); + + struct hwsim_tx_rate* tx_rates = (struct hwsim_tx_rate *)nla_data(attrs[HWSIM_ATTR_TX_INFO]); + u64 cookie = nla_get_u64(attrs[HWSIM_ATTR_COOKIE]); + unsigned int flags = nla_get_u32(attrs[HWSIM_ATTR_FLAGS]); + if (gnlh->cmd == HWSIM_CMD_TX_INFO_FRAME) { + // TX_INFO receved from server, send to kernel + std::vector &inets = _list_winterfaces.list_devices(); + + for (auto & inet : inets) + { + struct ether_addr macdsthwsim = inet.getMachwsim(); + + send_tx_info_frame_nl(&macdsthwsim, + flags, + (int)signal, + tx_rates, + cookie); + } + + delete &inets; + + return; + } + /* exit if the message does not contain frame data */ if (gnlh->cmd != HWSIM_CMD_FRAME) { @@ -485,9 +498,7 @@ void CKernelWifi::recv_from_server(){ return ; } - /* we get the attributes*/ - struct nlattr *attrs[HWSIM_ATTR_MAX + 1]; - genlmsg_parse(nlh, 0, attrs, HWSIM_ATTR_MAX, NULL); + /* we get frequence */ TFrequency freq; @@ -526,8 +537,31 @@ void CKernelWifi::recv_from_server(){ #endif /* copy mac dst address from frame */ - struct ether_addr framedst; - memcpy(&framedst, data + 4, ETH_ALEN); + struct ether_addr framesrc; + memcpy(&framesrc, data + 10, ETH_ALEN); + + if (!dropped) + flags |= HWSIM_TX_STAT_ACK; + +#if 0 + struct nl_msg *tx_info = build_tx_info(&framesrc, flags, + (int)signal, + tx_rates, + cookie); + struct nlmsghdr *hdr = nlmsg_hdr(tx_info); + + // Send TX_Info back to server + int value=_SendSignal(&power, (char*)hdr, hdr->nlmsg_len); + + nlmsg_free(tx_info); + if( value == SOCKET_ERROR ) { + printf("Error sending tx info to server\n"); + manage_server_crash(); + } +#endif + + if (dropped) + return; #ifdef _DEBUG std::cout << "frame dst: "; cout_mac_address(&framedst);std::cout<Send(descriptor, (char*)power, sizeof(TPower)); if( val <= 0 ) return val; + val=socket->Send(descriptor, (char*)dropped, sizeof(uint8_t)); + if( val <= 0 ) + return val; + // std::cout<<"send big data of size : "<Send(descriptor, buffer, sizeOfBuffer); } -ssize_t CWifi::RecvSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, CDynBuffer* buffer) +ssize_t CWifi::RecvSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, uint8_t *dropped, CDynBuffer* buffer) { int valread; // read the power valread = socket->Read(descriptor, (char*)power, sizeof(TPower)); - if ( valread <= 0 ) + if ( valread <= 0 ) { + printf("cannot read power %d\n", valread); + return valread; + } + + // read dropped + valread = socket->Read(descriptor, (char*)dropped, sizeof(uint8_t)); + if ( valread <= 0 ) { + printf("cannot read dropped %d\n", valread); return valread; + } // read the signal // "nlmsg_len" (type "uint32_t") is the first attribut of the "struct nlmsghdr" in "libnl3/netlink/netlink-kernel.h" ssize_t sizeRead = socket->ReadEqualSize(descriptor, buffer, 0, sizeof(struct nlmsghdr)); - if( sizeRead == SOCKET_ERROR ) + if( sizeRead == SOCKET_ERROR ) { + printf("Cannot read nlmsg_len\n"); return SOCKET_ERROR; + } int sizeTotal=((struct nlmsghdr *)(buffer->GetBuffer()))->nlmsg_len; - if( sizeTotal > MTU ) // to avoid that a error packet overfulls the memory + if( sizeTotal > MTU ) { // to avoid that a error packet overfulls the memory + printf("Size greater than MTU %d\n", sizeTotal); return SOCKET_ERROR; + } return socket->ReadEqualSize(descriptor, buffer, sizeRead, sizeTotal); } diff --git a/src/cwifi.h b/src/cwifi.h index b7517f9..02c9327 100644 --- a/src/cwifi.h +++ b/src/cwifi.h @@ -18,8 +18,8 @@ class CWifi bool PacketIsLost(TPower signalLevel); - ssize_t SendSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, const char* buffer, int sizeOfBuffer); - ssize_t RecvSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, CDynBuffer* buffer); + ssize_t SendSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, uint8_t *dropped, const char* buffer, int sizeOfBuffer); + ssize_t RecvSignalWithSocket(CSocket* socket, TDescriptor descriptor, TPower* power, uint8_t *dropped, CDynBuffer* buffer); }; #endif diff --git a/src/cwificlient.h b/src/cwificlient.h index 80a99ff..dbc7325 100644 --- a/src/cwificlient.h +++ b/src/cwificlient.h @@ -22,10 +22,13 @@ class CWifiClient : public CKernelWifi, public CWifi, public TypeCSocketClient } ssize_t _SendSignal(TPower* power, const char* buffer, int sizeOfBuffer) override - { return SendSignalWithSocket(this, this->GetDescriptor(), power, buffer, sizeOfBuffer); } + { + uint8_t dropped = 0; + return SendSignalWithSocket(this, this->GetDescriptor(), power, &dropped, buffer, sizeOfBuffer); + } - ssize_t _RecvSignal(TPower* power, CDynBuffer* buffer) override - { return RecvSignalWithSocket(this, this->GetDescriptor(), power, buffer); } + ssize_t _RecvSignal(TPower* power, uint8_t *dropped, CDynBuffer* buffer) override + { return RecvSignalWithSocket(this, this->GetDescriptor(), power, dropped, buffer); } void _Close() override { TypeCSocketClient::Close(); }; }; diff --git a/src/cwifiserver.cc b/src/cwifiserver.cc index 3ec459d..58f02ad 100644 --- a/src/cwifiserver.cc +++ b/src/cwifiserver.cc @@ -180,14 +180,14 @@ void CWifiServer::CloseAllClient() CloseClient(0); // we can Close the 0 because we use the shift } -ssize_t CWifiServer::SendSignal(TDescriptor descriptor, TPower* power, const char* buffer, int sizeOfBuffer) +ssize_t CWifiServer::SendSignal(TDescriptor descriptor, TPower* power, uint8_t *dropped, const char* buffer, int sizeOfBuffer) { - return SendSignalWithSocket(this, descriptor, power, buffer, sizeOfBuffer); + return SendSignalWithSocket(this, descriptor, power, dropped, buffer, sizeOfBuffer); } -ssize_t CWifiServer::RecvSignal(TDescriptor descriptor, TPower* power, CDynBuffer* buffer) +ssize_t CWifiServer::RecvSignal(TDescriptor descriptor, TPower* power, uint8_t *dropped, CDynBuffer* buffer) { - return RecvSignalWithSocket(this, descriptor, power, buffer); + return RecvSignalWithSocket(this, descriptor, power, dropped, buffer); } void CWifiServer::SendAllOtherClients(TIndex index,TPower power, const char* data, ssize_t sizeOfData) @@ -202,30 +202,34 @@ void CWifiServer::SendAllOtherClients(TIndex index,TPower power, const char* dat { TFrequency frequency=GetFrequency((struct nlmsghdr*)data); TPower signalLevel=BoundedPower(power-Attenuation(coo.DistanceWith((*InfoWifis)[i]),frequency)); + uint8_t dropped = CanLostPackets && PacketIsLost(signalLevel); - if( ! CanLostPackets || ! PacketIsLost(signalLevel) ) - if( SendSignal((*InfoSockets)[i].GetDescriptor(), &signalLevel, data, sizeOfData) < 0 ) - (*InfoSockets)[i].DisableIt(); + if( SendSignal((*InfoSockets)[i].GetDescriptor(), &signalLevel, &dropped, data, sizeOfData) < 0 ) + (*InfoSockets)[i].DisableIt(); } } } void CWifiServer::SendAllOtherClientsWithoutLoss(TIndex index, TPower power, const char* data, ssize_t sizeOfData) { + uint8_t dropped = 0; + for (TIndex i = 0; i < GetNumberClient(); i++) { if( i != index ) if( IsEnable(i) ) - if( SendSignal((*InfoSockets)[i].GetDescriptor(), &power, data, sizeOfData) < 0 ) + if( SendSignal((*InfoSockets)[i].GetDescriptor(), &power, &dropped, data, sizeOfData) < 0 ) (*InfoSockets)[i].DisableIt(); } } void CWifiServer::SendAllClientsWithoutLoss(TPower power, const char* data, ssize_t sizeOfData) { + uint8_t dropped = 0; + for (TIndex i = 0; i < GetNumberClient(); i++) if( IsEnable(i) ) - if( SendSignal((*InfoSockets)[i].GetDescriptor(), &power, data, sizeOfData) < 0 ) + if( SendSignal((*InfoSockets)[i].GetDescriptor(), &power, &dropped, data, sizeOfData) < 0 ) (*InfoSockets)[i].DisableIt(); } diff --git a/src/cwifiserver.h b/src/cwifiserver.h index 40d45b1..d303237 100644 --- a/src/cwifiserver.h +++ b/src/cwifiserver.h @@ -44,9 +44,9 @@ class CWifiServer : public CSocketServer, public CWifi void CloseAllClient(); - ssize_t SendSignal(TDescriptor descriptor, TPower* power, const char* buffer, int sizeOfBuffer); + ssize_t SendSignal(TDescriptor descriptor, TPower* power, uint8_t *dropped, const char* buffer, int sizeOfBuffer); - ssize_t RecvSignal(TDescriptor descriptor, TPower* power, CDynBuffer* buffer); + ssize_t RecvSignal(TDescriptor descriptor, TPower* power, uint8_t *dropped, CDynBuffer* buffer); void SendAllOtherClients(TIndex index,TPower power, const char* data, ssize_t sizeOfData); diff --git a/src/vwifi-server.cc b/src/vwifi-server.cc index 242b089..67e1490 100644 --- a/src/vwifi-server.cc +++ b/src/vwifi-server.cc @@ -40,6 +40,7 @@ void ForwardData(bool srcIsSpy, CWifiServer* src, CWifiServer* otherDst) { int valread; TPower power; + uint8_t dropped; for ( TIndex i = 0 ; i < src->GetNumberClient() ; ) { @@ -57,7 +58,7 @@ void ForwardData(bool srcIsSpy, CWifiServer* src, CWifiServer* otherDst) //Check if it was for closing , and also read the //incoming message - valread=src->RecvSignal(socket,&power,&Buffer); + valread=src->RecvSignal(socket,&power,&dropped,&Buffer); if( valread <=0 ) { RemoveClient(src, srcIsSpy , i, socket);