summaryrefslogtreecommitdiff
path: root/libopie2/opienet/onetwork.cpp
Unidiff
Diffstat (limited to 'libopie2/opienet/onetwork.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/onetwork.cpp203
1 files changed, 182 insertions, 21 deletions
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp
index ae1865d..546be9e 100644
--- a/libopie2/opienet/onetwork.cpp
+++ b/libopie2/opienet/onetwork.cpp
@@ -1,18 +1,18 @@
1/* 1/*
2                 This file is part of the Opie Project 2                 This file is part of the Opie Project
3              Copyright (C) 2003-2004 by Michael 'Mickey' Lauer 3              Copyright (C) 2003-2005 by Michael 'Mickey' Lauer <mickey@Vanille.de>
4 =. <mickey@Vanille.de> 4 =.
5 .=l. 5 .=l.
6           .>+-= 6           .>+-=
7 _;:,     .>    :=|. This program is free software; you can 7 _;:,     .>    :=|. This program is free software; you can
8.> <`_,   >  .   <= redistribute it and/or modify it under 8.> <`_,   >  .   <= redistribute it and/or modify it under
9:`=1 )Y*s>-.--   : the terms of the GNU Library General Public 9:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
10.="- .-=="i,     .._ License as published by the Free Software 10.="- .-=="i,     .._ License as published by the Free Software
11 - .   .-<_>     .<> Foundation; version 2 of the License. 11 - .   .-<_>     .<> Foundation; version 2 of the License.
12     ._= =}       : 12     ._= =}       :
13    .%`+i>       _;_. 13    .%`+i>       _;_.
14    .i_,=:_.      -<s. This program is distributed in the hope that 14    .i_,=:_.      -<s. This program is distributed in the hope that
15     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY; 15     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
16    : ..    .:,     . . . without even the implied warranty of 16    : ..    .:,     . . . without even the implied warranty of
17    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A 17    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
18  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU 18  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
@@ -55,13 +55,12 @@
55#include <net/if_arp.h> 55#include <net/if_arp.h>
56#include <stdarg.h> 56#include <stdarg.h>
57 57
58#ifndef NODEBUG 58#ifndef NODEBUG
59#include <opie2/odebugmapper.h> 59#include <opie2/odebugmapper.h>
60 60
61
62using namespace Opie::Core; 61using namespace Opie::Core;
63using namespace Opie::Net::Internal; 62using namespace Opie::Net::Internal;
64DebugMapper* debugmapper = new DebugMapper(); 63DebugMapper* debugmapper = new DebugMapper();
65#endif 64#endif
66 65
67/*====================================================================================== 66/*======================================================================================
@@ -862,13 +861,13 @@ QString OWirelessNetworkInterface::SSID() const
862} 861}
863 862
864 863
865void OWirelessNetworkInterface::setSSID( const QString& ssid ) 864void OWirelessNetworkInterface::setSSID( const QString& ssid )
866{ 865{
867 _iwr.u.essid.pointer = const_cast<char*>( (const char*) ssid ); 866 _iwr.u.essid.pointer = const_cast<char*>( (const char*) ssid );
868 _iwr.u.essid.length = ssid.length(); 867 _iwr.u.essid.length = ssid.length()+1; // zero byte
869 wioctl( SIOCSIWESSID ); 868 wioctl( SIOCSIWESSID );
870} 869}
871 870
872 871
873OStationList* OWirelessNetworkInterface::scanNetwork() 872OStationList* OWirelessNetworkInterface::scanNetwork()
874{ 873{
@@ -878,13 +877,13 @@ OStationList* OWirelessNetworkInterface::scanNetwork()
878 { 877 {
879 return 0; 878 return 0;
880 } 879 }
881 880
882 OStationList* stations = new OStationList(); 881 OStationList* stations = new OStationList();
883 882
884 int timeout = 1000000; 883 int timeout = 10000000;
885 884
886 odebug << "ONetworkInterface::scanNetwork() - scan started." << oendl; 885 odebug << "ONetworkInterface::scanNetwork() - scan started." << oendl;
887 886
888 bool results = false; 887 bool results = false;
889 struct timeval tv; 888 struct timeval tv;
890 tv.tv_sec = 0; 889 tv.tv_sec = 0;
@@ -932,20 +931,186 @@ OStationList* OWirelessNetworkInterface::scanNetwork()
932 } 931 }
933 932
934 odebug << " - results are in!" << oendl; 933 odebug << " - results are in!" << oendl;
935 dumpBytes( (const unsigned char*) &buffer[0], _iwr.u.data.length ); 934 dumpBytes( (const unsigned char*) &buffer[0], _iwr.u.data.length );
936 935
937 // parse results 936 // parse results
937 struct iw_event iwe;
938 struct iw_stream_descr stream;
939 unsigned int cmd_index, event_type, event_len;
940 char *pointer;
941
942 const char standard_ioctl_hdr[] = {
943 IW_HEADER_TYPE_NULL, /* SIOCSIWCOMMIT */
944 IW_HEADER_TYPE_CHAR, /* SIOCGIWNAME */
945 IW_HEADER_TYPE_PARAM, /* SIOCSIWNWID */
946 IW_HEADER_TYPE_PARAM, /* SIOCGIWNWID */
947 IW_HEADER_TYPE_FREQ, /* SIOCSIWFREQ */
948 IW_HEADER_TYPE_FREQ, /* SIOCGIWFREQ */
949 IW_HEADER_TYPE_UINT, /* SIOCSIWMODE */
950 IW_HEADER_TYPE_UINT, /* SIOCGIWMODE */
951 IW_HEADER_TYPE_PARAM, /* SIOCSIWSENS */
952 IW_HEADER_TYPE_PARAM, /* SIOCGIWSENS */
953 IW_HEADER_TYPE_NULL, /* SIOCSIWRANGE */
954 IW_HEADER_TYPE_POINT, /* SIOCGIWRANGE */
955 IW_HEADER_TYPE_NULL, /* SIOCSIWPRIV */
956 IW_HEADER_TYPE_POINT, /* SIOCGIWPRIV */
957 IW_HEADER_TYPE_NULL, /* SIOCSIWSTATS */
958 IW_HEADER_TYPE_POINT, /* SIOCGIWSTATS */
959 IW_HEADER_TYPE_POINT, /* SIOCSIWSPY */
960 IW_HEADER_TYPE_POINT, /* SIOCGIWSPY */
961 IW_HEADER_TYPE_POINT, /* SIOCSIWTHRSPY */
962 IW_HEADER_TYPE_POINT, /* SIOCGIWTHRSPY */
963 IW_HEADER_TYPE_ADDR, /* SIOCSIWAP */
964 IW_HEADER_TYPE_ADDR, /* SIOCGIWAP */
965 IW_HEADER_TYPE_NULL, /* -- hole -- */
966 IW_HEADER_TYPE_POINT, /* SIOCGIWAPLIST */
967 IW_HEADER_TYPE_PARAM, /* SIOCSIWSCAN */
968 IW_HEADER_TYPE_POINT, /* SIOCGIWSCAN */
969 IW_HEADER_TYPE_POINT, /* SIOCSIWESSID */
970 IW_HEADER_TYPE_POINT, /* SIOCGIWESSID */
971 IW_HEADER_TYPE_POINT, /* SIOCSIWNICKN */
972 IW_HEADER_TYPE_POINT, /* SIOCGIWNICKN */
973 IW_HEADER_TYPE_NULL, /* -- hole -- */
974 IW_HEADER_TYPE_NULL, /* -- hole -- */
975 IW_HEADER_TYPE_PARAM, /* SIOCSIWRATE */
976 IW_HEADER_TYPE_PARAM, /* SIOCGIWRATE */
977 IW_HEADER_TYPE_PARAM, /* SIOCSIWRTS */
978 IW_HEADER_TYPE_PARAM, /* SIOCGIWRTS */
979 IW_HEADER_TYPE_PARAM, /* SIOCSIWFRAG */
980 IW_HEADER_TYPE_PARAM, /* SIOCGIWFRAG */
981 IW_HEADER_TYPE_PARAM, /* SIOCSIWTXPOW */
982 IW_HEADER_TYPE_PARAM, /* SIOCGIWTXPOW */
983 IW_HEADER_TYPE_PARAM, /* SIOCSIWRETRY */
984 IW_HEADER_TYPE_PARAM, /* SIOCGIWRETRY */
985 IW_HEADER_TYPE_POINT, /* SIOCSIWENCODE */
986 IW_HEADER_TYPE_POINT, /* SIOCGIWENCODE */
987 IW_HEADER_TYPE_PARAM, /* SIOCSIWPOWER */
988 IW_HEADER_TYPE_PARAM, /* SIOCGIWPOWER */
989 };
990
991 const char standard_event_hdr[] = {
992 IW_HEADER_TYPE_ADDR, /* IWEVTXDROP */
993 IW_HEADER_TYPE_QUAL, /* IWEVQUAL */
994 IW_HEADER_TYPE_POINT, /* IWEVCUSTOM */
995 IW_HEADER_TYPE_ADDR, /* IWEVREGISTERED */
996 IW_HEADER_TYPE_ADDR, /* IWEVEXPIRED */
997 IW_HEADER_TYPE_POINT, /* IWEVGENIE */
998 IW_HEADER_TYPE_POINT, /* IWEVMICHAELMICFAILURE */
999 IW_HEADER_TYPE_POINT, /* IWEVASSOCREQIE */
1000 IW_HEADER_TYPE_POINT, /* IWEVASSOCRESPIE */
1001 IW_HEADER_TYPE_POINT, /* IWEVPMKIDCAND */
1002 };
1003
1004
1005 const int event_type_size[] = {
1006 IW_EV_LCP_LEN, /* IW_HEADER_TYPE_NULL */
1007 0,
1008 IW_EV_CHAR_LEN, /* IW_HEADER_TYPE_CHAR */
1009 0,
1010 IW_EV_UINT_LEN, /* IW_HEADER_TYPE_UINT */
1011 IW_EV_FREQ_LEN, /* IW_HEADER_TYPE_FREQ */
1012 IW_EV_ADDR_LEN, /* IW_HEADER_TYPE_ADDR */
1013 0,
1014 IW_EV_POINT_LEN, /* Without variable payload */
1015 IW_EV_PARAM_LEN, /* IW_HEADER_TYPE_PARAM */
1016 IW_EV_QUAL_LEN, /* IW_HEADER_TYPE_QUAL */
1017 };
1018
1019
1020 //Initialize the stream
1021 memset( &stream, 0, sizeof(struct iw_stream_descr) );
1022 stream.current = buffer;
1023 stream.end = buffer + _iwr.u.data.length;
1024
1025 do
1026 {
1027 if ((stream.current + IW_EV_LCP_LEN) > stream.end)
1028 break;
1029 memcpy((char *) &iwe, stream.current, IW_EV_LCP_LEN);
938 1030
939 int offset = 0; 1031 if (iwe.len <= IW_EV_LCP_LEN) //If yes, it is an invalid event
940 struct iw_event* we = (struct iw_event*) &buffer[0]; 1032 break;
1033 if (iwe.cmd <= SIOCIWLAST) {
1034 cmd_index = iwe.cmd - SIOCIWFIRST;
941 1035
942 while ( offset < _iwr.u.data.length ) 1036 if(cmd_index < sizeof(standard_ioctl_hdr))
943 { 1037 event_type = standard_ioctl_hdr[cmd_index];
944 //const char* cmd = *(*_ioctlmap)[we->cmd]; 1038 }
945 //if ( !cmd ) cmd = "<unknown>"; 1039 else {
1040 cmd_index = iwe.cmd - IWEVFIRST;
1041
1042 if(cmd_index < sizeof(standard_event_hdr))
1043 event_type = standard_event_hdr[cmd_index];
1044 }
1045
1046 /* Unknown events -> event_type=0 => IW_EV_LCP_LEN */
1047 event_len = event_type_size[event_type];
1048
1049 /* Fixup for later version of WE */
1050 if((_range.we_version_compiled > 18) && (event_type == IW_HEADER_TYPE_POINT))
1051 event_len -= IW_EV_POINT_OFF;
1052
1053 /* Check if we know about this event */
1054 if(event_len <= IW_EV_LCP_LEN) {
1055 /* Skip to next event */
1056 stream.current += iwe.len;
1057 continue;
1058 }
1059
1060 event_len -= IW_EV_LCP_LEN;
1061
1062 /* Set pointer on data */
1063 if(stream.value != NULL)
1064 pointer = stream.value; /* Next value in event */
1065 else
1066 pointer = stream.current + IW_EV_LCP_LEN; /* First value in event */
1067
1068 if((pointer + event_len) > stream.end) {
1069 /* Go to next event */
1070 stream.current += iwe.len;
1071 break;
1072 }
1073
1074 /* Fixup for later version of WE */
1075 if((_range.we_version_compiled > 18) && (event_type == IW_HEADER_TYPE_POINT))
1076 memcpy((char *) &iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF, pointer, event_len);
1077 else
1078 memcpy((char *) &iwe + IW_EV_LCP_LEN, pointer, event_len);
1079
1080 /* Skip event in the stream */
1081 pointer += event_len;
1082
1083 /* Special processing for iw_point events */
1084 if(event_type == IW_HEADER_TYPE_POINT) {
1085 /* Check the length of the payload */
1086
1087 if((iwe.len - (event_len + IW_EV_LCP_LEN)) > 0)
1088 /* Set pointer on variable part (warning : non aligned) */
1089 iwe.u.data.pointer = pointer;
1090 else
1091 /* No data */
1092 iwe.u.data.pointer = NULL;
1093 /* Go to next event */
1094 stream.current += iwe.len;
1095 }
1096
1097 else {
1098 /* Is there more value in the event ? */
1099 if((pointer + event_len) <= (stream.current + iwe.len))
1100 /* Go to next value */
1101 stream.value = pointer;
1102 else {
1103 /* Go to next event */
1104 stream.value = NULL;
1105 stream.current += iwe.len;
1106 }
1107 }
1108
1109 struct iw_event *we = &iwe;
1110 //------
946 odebug << " - reading next event... cmd=" << we->cmd << ", len=" << we->len << oendl; 1111 odebug << " - reading next event... cmd=" << we->cmd << ", len=" << we->len << oendl;
947 switch (we->cmd) 1112 switch (we->cmd)
948 { 1113 {
949 case SIOCGIWAP: 1114 case SIOCGIWAP:
950 { 1115 {
951 odebug << "SIOCGIWAP" << oendl; 1116 odebug << "SIOCGIWAP" << oendl;
@@ -965,38 +1130,34 @@ OStationList* OWirelessNetworkInterface::scanNetwork()
965 stations->last()->channel = _channels[ static_cast<int>(double( we->u.freq.m ) * pow( 10.0, we->u.freq.e ) / 1000000) ]; 1130 stations->last()->channel = _channels[ static_cast<int>(double( we->u.freq.m ) * pow( 10.0, we->u.freq.e ) / 1000000) ];
966 break; 1131 break;
967 } 1132 }
968 case SIOCGIWESSID: 1133 case SIOCGIWESSID:
969 { 1134 {
970 odebug << "SIOCGIWESSID" << oendl; 1135 odebug << "SIOCGIWESSID" << oendl;
971 stations->last()->ssid = static_cast<const char*>( we->u.essid.pointer ); 1136 we->u.essid.length = '\0'; // make sure it is zero terminated
1137 stations->last()->ssid = static_cast<const char*> (we->u.essid.pointer);
1138 odebug << "ESSID: " << stations->last()->ssid << oendl;
972 break; 1139 break;
973 } 1140 }
974 case SIOCGIWSENS: odebug << "SIOCGIWSENS" << oendl; break; 1141 case SIOCGIWSENS: odebug << "SIOCGIWSENS" << oendl; break;
975 case SIOCGIWENCODE: odebug << "SIOCGIWENCODE" << oendl; break; 1142 case SIOCGIWENCODE: odebug << "SIOCGIWENCODE" << oendl; break;
976 case IWEVTXDROP: odebug << "IWEVTXDROP" << oendl; break; /* Packet dropped to excessive retry */ 1143 case IWEVTXDROP: odebug << "IWEVTXDROP" << oendl; break; /* Packet dropped to excessive retry */
977 case IWEVQUAL: odebug << "IWEVQUAL" << oendl; break; /* Quality part of statistics (scan) */ 1144 case IWEVQUAL: odebug << "IWEVQUAL" << oendl; break; /* Quality part of statistics (scan) */
978 case IWEVCUSTOM: odebug << "IWEVCUSTOM" << oendl; break; /* Driver specific ascii string */ 1145 case IWEVCUSTOM: odebug << "IWEVCUSTOM" << oendl; break; /* Driver specific ascii string */
979 case IWEVREGISTERED: odebug << "IWEVREGISTERED" << oendl; break; /* Discovered a new node (AP mode) */ 1146 case IWEVREGISTERED: odebug << "IWEVREGISTERED" << oendl; break; /* Discovered a new node (AP mode) */
980 case IWEVEXPIRED: odebug << "IWEVEXPIRED" << oendl; break; /* Expired a node (AP mode) */ 1147 case IWEVEXPIRED: odebug << "IWEVEXPIRED" << oendl; break; /* Expired a node (AP mode) */
981 default: odebug << "unhandled event" << oendl; 1148 default: odebug << "unhandled event" << oendl;
982 } 1149 }
983 1150
984 offset += we->len; 1151 } while (true);
985 we = (struct iw_event*) &buffer[offset];
986 }
987 return stations;
988
989 return stations;
990
991 } 1152 }
992 else 1153 else
993 { 1154 {
994 odebug << " - no results (timeout) :(" << oendl; 1155 odebug << " - no results (timeout) :(" << oendl;
995 return stations;
996 } 1156 }
1157 return stations;
997} 1158}
998 1159
999 1160
1000int OWirelessNetworkInterface::signalStrength() const 1161int OWirelessNetworkInterface::signalStrength() const
1001{ 1162{
1002 iw_statistics stat; 1163 iw_statistics stat;