MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / wireless / rtlink / Utility / rt_tool.cpp
blobb165f6cfbb77f0d53f0948474868b4ad5e0c073f
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <sys/socket.h>
5 #include <sys/ioctl.h>
6 #include <linux/wireless.h>
8 #include "rt_tool.h"
9 #include "sha1.h"
11 /*------------------------------------------------------------------*/
13 * Open a socket.
14 * Depending on the protocol present, open the right socket. The socket
15 * will allow us to talk to the driver.
17 int Open_Socket(void)
19 static const int families[] = {
20 AF_INET, AF_IPX, AF_AX25, AF_APPLETALK
22 unsigned int i;
23 int sock;
26 * Now pick any (exisiting) useful socket family for generic queries
27 * Note : don't open all the socket, only returns when one matches,
28 * all protocols might not be valid.
29 * Workaround by Jim Kaba <jkaba@sarnoff.com>
30 * Note : in 99% of the case, we will just open the inet_sock.
31 * The remaining 1% case are not fully correct...
34 /* Try all families we support */
35 for(i = 0; i < sizeof(families)/sizeof(int); ++i)
37 /* Try to open the socket, if success returns it */
38 sock = socket(families[i], SOCK_DGRAM, 0);
39 if(sock >= 0)
40 return sock;
43 return -1;
46 int OidQueryInformation(USHORT OidQueryCode, int socket_id, char *DeviceName, void *ptr, ULONG PtrLength)
48 struct iwreq wrq;
50 strcpy(wrq.ifr_name, DeviceName);
51 wrq.u.data.length = PtrLength;
52 wrq.u.data.pointer = (caddr_t) ptr;
53 wrq.u.data.flags = OidQueryCode;
55 return (ioctl(socket_id, RT_PRIV_IOCTL, &wrq));
58 int OidSetInformation(USHORT OidQueryCode, int socket_id, char *DeviceName, void *ptr, ULONG PtrLength)
60 struct iwreq wrq;
62 strcpy(wrq.ifr_name, DeviceName);
63 wrq.u.data.length = PtrLength;
64 wrq.u.data.pointer = (caddr_t) ptr;
65 wrq.u.data.flags = OidQueryCode | OID_GET_SET_TOGGLE;
67 return (ioctl(socket_id, RT_PRIV_IOCTL, &wrq));
70 UINT ConvertRssiToSignalQuality(NDIS_802_11_RSSI RSSI)
72 UINT signal_quality;
73 if (RSSI >= -50)
74 signal_quality = 100;
75 else if (RSSI >= -80) // between -50 ~ -80dbm
76 signal_quality = (UINT)(24 + (RSSI + 80) * 2.6);
77 else if (RSSI >= -90) // between -80 ~ -90dbm
78 signal_quality = (UINT)((RSSI + 90) * 2.6);
79 else // < -84 dbm
80 signal_quality = 0;
82 return signal_quality;
86 // FUNCTION: BtoH(char *, char *, int)
88 // PURPOSE: Converts ascii byte to numeric
90 // PARAMETERS:
91 // ch - ascii byte to convert
93 // RETURNS:
94 // associated numeric value
96 // COMMENTS:
98 // Will convert any hex ascii digit to its numeric counterpart.
99 // Puts in 0xff if not a valid hex digit.
102 unsigned char BtoH(char ch)
104 if (ch >= '0' && ch <= '9') return (ch - '0'); // Handle numerals
105 if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA); // Handle capitol hex digits
106 if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 0xA); // Handle small hex digits
107 return(255);
111 // FUNCTION: AtoH(char *, UCHAR *, int)
113 // PURPOSE: Converts ascii string to network order hex
115 // PARAMETERS:
116 // src - pointer to input ascii string
117 // dest - pointer to output hex
118 // destlen - size of dest
120 // COMMENTS:
122 // 2 ascii bytes make a hex byte so must put 1st ascii byte of pair
123 // into upper nibble and 2nd ascii byte of pair into lower nibble.
126 void AtoH(char * src, UCHAR * dest, int destlen)
128 char * srcptr;
130 srcptr = src;
131 PUCHAR destTemp = dest;
133 while(destlen--)
135 *destTemp = BtoH(*srcptr++) << 4; // Put 1st ascii byte in upper nibble.
136 *destTemp += BtoH(*srcptr++); // Add 2nd ascii byte to above.
137 destTemp++;
141 static void hmac_sha1(unsigned char *text, int text_len, unsigned char *key, int key_len, unsigned char *digest)
143 A_SHA_CTX context;
144 unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */
145 unsigned char k_opad[65]; /* outer padding - key XORd with opad */
146 int i;
148 /* if key is longer than 64 bytes reset it to key=SHA1(key) */
149 if (key_len > 64)
151 A_SHA_CTX tctx;
153 A_SHAInit(&tctx);
154 A_SHAUpdate(&tctx, key, key_len);
155 A_SHAFinal(&tctx, key);
157 key_len = 20;
161 * the HMAC_SHA1 transform looks like:
163 * SHA1(K XOR opad, SHA1(K XOR ipad, text))
165 * where K is an n byte key
166 * ipad is the byte 0x36 repeated 64 times
167 * opad is the byte 0x5c repeated 64 times
168 * and text is the data being protected
171 /* start out by storing key in pads */
172 memset(k_ipad, 0, sizeof k_ipad);
173 memset(k_opad, 0, sizeof k_opad);
174 memcpy(k_ipad, key, key_len);
175 memcpy(k_opad, key, key_len);
177 /* XOR key with ipad and opad values */
178 for (i = 0; i < 64; i++)
180 k_ipad[i] ^= 0x36;
181 k_opad[i] ^= 0x5c;
184 /* perform inner SHA1*/
185 A_SHAInit(&context); /* init context for 1st pass */
186 A_SHAUpdate(&context, k_ipad, 64); /* start with inner pad */
187 A_SHAUpdate(&context, text, text_len); /* then text of datagram */
188 A_SHAFinal(&context, digest); /* finish up 1st pass */
190 /* perform outer SHA1 */
191 A_SHAInit(&context); /* init context for 2nd pass */
192 A_SHAUpdate(&context, k_opad, 64); /* start with outer pad */
193 A_SHAUpdate(&context, digest, 20); /* then results of 1st hash */
194 A_SHAFinal(&context, digest); /* finish up 2nd pass */
198 * F(P, S, c, i) = U1 xor U2 xor ... Uc
199 * U1 = PRF(P, S || Int(i))
200 * U2 = PRF(P, U1)
201 * Uc = PRF(P, Uc-1)
204 static void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output)
206 unsigned char digest[36], digest1[A_SHA_DIGEST_LEN];
207 int i, j;
209 /* U1 = PRF(P, S || int(i)) */
210 memcpy(digest, ssid, ssidlength);
211 digest[ssidlength] = (unsigned char)((count>>24) & 0xff);
212 digest[ssidlength+1] = (unsigned char)((count>>16) & 0xff);
213 digest[ssidlength+2] = (unsigned char)((count>>8) & 0xff);
214 digest[ssidlength+3] = (unsigned char)(count & 0xff);
215 hmac_sha1(digest, ssidlength+4, (unsigned char*) password, (int) strlen(password), digest1); // for WPA update
217 /* output = U1 */
218 memcpy(output, digest1, A_SHA_DIGEST_LEN);
220 for (i = 1; i < iterations; i++)
222 /* Un = PRF(P, Un-1) */
223 hmac_sha1(digest1, A_SHA_DIGEST_LEN, (unsigned char*) password, (int) strlen(password), digest); // for WPA update
224 memcpy(digest1, digest, A_SHA_DIGEST_LEN);
226 /* output = output xor Un */
227 for (j = 0; j < A_SHA_DIGEST_LEN; j++)
229 output[j] ^= digest[j];
234 * password - ascii string up to 63 characters in length
235 * ssid - octet string up to 32 octets
236 * ssidlength - length of ssid in octets
237 * output must be 40 octets in length and outputs 256 bits of key
239 int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output)
241 if ((strlen(password) > 63) || (ssidlength > 32))
242 return 0;
244 F(password, ssid, ssidlength, 4096, 1, output);
245 F(password, ssid, ssidlength, 4096, 2, &output[A_SHA_DIGEST_LEN]);
246 return 1;