Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wl_profile.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Agere Systems Inc.
3  * Wireless device driver for Linux (wlags49).
4  *
5  * Copyright (c) 1998-2003 Agere Systems Inc.
6  * All rights reserved.
7  * http://www.agere.com
8  *
9  * Initially developed by TriplePoint, Inc.
10  * http://www.triplepoint.com
11  *
12  *------------------------------------------------------------------------------
13  *
14  * This file defines routines required to parse configuration parameters
15  * listed in a config file, if that config file exists.
16  *
17  *------------------------------------------------------------------------------
18  *
19  * SOFTWARE LICENSE
20  *
21  * This software is provided subject to the following terms and conditions,
22  * which you should read carefully before using the software. Using this
23  * software indicates your acceptance of these terms and conditions. If you do
24  * not agree with these terms and conditions, do not use the software.
25  *
26  * Copyright © 2003 Agere Systems Inc.
27  * All rights reserved.
28  *
29  * Redistribution and use in source or binary forms, with or without
30  * modifications, are permitted provided that the following conditions are met:
31  *
32  * . Redistributions of source code must retain the above copyright notice, this
33  * list of conditions and the following Disclaimer as comments in the code as
34  * well as in the documentation and/or other materials provided with the
35  * distribution.
36  *
37  * . Redistributions in binary form must reproduce the above copyright notice,
38  * this list of conditions and the following Disclaimer in the documentation
39  * and/or other materials provided with the distribution.
40  *
41  * . Neither the name of Agere Systems Inc. nor the names of the contributors
42  * may be used to endorse or promote products derived from this software
43  * without specific prior written permission.
44  *
45  * Disclaimer
46  *
47  * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
48  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
49  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
50  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
51  * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
52  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55  * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
57  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
58  * DAMAGE.
59  *
60  ******************************************************************************/
61 
62 /* Only include this file if USE_PROFILE is defined */
63 #ifdef USE_PROFILE
64 
65 
66 
67 
68 /*******************************************************************************
69  * constant definitions
70  ******************************************************************************/
71 
72 
73 /* Allow support for calling system fcns to parse config file */
74 #define __KERNEL_SYSCALLS__
75 
76 
77 
78 
79 /*******************************************************************************
80  * include files
81  ******************************************************************************/
82 #include <wl_version.h>
83 
84 #include <linux/netdevice.h>
85 #include <linux/etherdevice.h>
86 #include <linux/unistd.h>
87 #include <asm/uaccess.h>
88 #include <limits.h>
89 
90 #define BIN_DL 1
91 
92 #include <debug.h>
93 #include <hcf.h>
94 /* #include <hcfdef.h> */
95 
96 #include <wl_if.h>
97 #include <wl_internal.h>
98 #include <wl_util.h>
99 #include <wl_enc.h>
100 #include <wl_main.h>
101 #include <wl_profile.h>
102 
103 
104 /*******************************************************************************
105  * global variables
106  ******************************************************************************/
107 
108 /* Definition needed to prevent unresolved external in unistd.h */
109 static int errno;
110 
111 #if DBG
112 extern p_u32 DebugFlag;
113 extern dbg_info_t *DbgInfo;
114 #endif
115 
116 int parse_yes_no(char *value);
117 
118 
119 int parse_yes_no(char *value)
120 {
121 int rc = 0; /* default to NO for invalid parameters */
122 
123  if (strlen(value) == 1) {
124  if ((value[0] | ('Y'^'y')) == 'y')
125  rc = 1;
126  /* } else { */
127  /* this should not be debug time info, it is an enduser data entry error ;? */
128  /* DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MICROWAVE_ROBUSTNESS); */
129  }
130  return rc;
131 } /* parse_yes_no */
132 
133 
134 /*******************************************************************************
135  * parse_config()
136  *******************************************************************************
137  *
138  * DESCRIPTION:
139  *
140  * This function opens the device's config file and parses the options from
141  * it, so that it can properly configure itself. If no configuration file
142  * or configuration is present, then continue to use the options already
143  * parsed from config.opts or wireless.opts.
144  *
145  * PARAMETERS:
146  *
147  * dev - a pointer to the device's net_device structure
148  *
149  * RETURNS:
150  *
151  * N/A
152  *
153  ******************************************************************************/
154 void parse_config(struct net_device *dev)
155 {
156  int file_desc;
157 #if 0 /* BIN_DL */
158  int rc;
159  char *cp = NULL;
160 #endif /* BIN_DL */
161  char buffer[MAX_LINE_SIZE];
162  char filename[MAX_LINE_SIZE];
164  struct wl_private *wvlan_config = NULL;
165  ENCSTRCT sEncryption;
166  /*------------------------------------------------------------------------*/
167 
168  DBG_FUNC("parse_config");
169  DBG_ENTER(DbgInfo);
170 
171  /* Get the wavelan specific info for this device */
172  wvlan_config = dev->priv;
173  if (wvlan_config == NULL) {
174  DBG_ERROR(DbgInfo, "Wavelan specific info struct not present?\n");
175  return;
176  }
177 
178  /* setup the default encryption string */
179  strcpy(wvlan_config->szEncryption, DEF_CRYPT_STR);
180 
181  /* Obtain a user-space process context, storing the original context */
182  fs = get_fs();
183  set_fs(get_ds());
184 
185  /* Determine the filename for this device and attempt to open it */
186  sprintf(filename, "%s%s", ROOT_CONFIG_FILENAME, dev->name);
187  file_desc = open(filename, O_RDONLY, 0);
188  if (file_desc != -1) {
189  DBG_TRACE(DbgInfo, "Wireless config file found. Parsing options...\n");
190 
191  /* Read out the options */
192  while (readline(file_desc, buffer))
193  translate_option(buffer, wvlan_config);
194  /* Close the file */
195  close(file_desc); /* ;?even if file_desc == -1 ??? */
196  } else {
197  DBG_TRACE(DbgInfo, "No iwconfig file found for this device; "
198  "config.opts or wireless.opts will be used\n");
199  }
200  /* Return to the original context */
201  set_fs(fs);
202 
203  /* convert the WEP keys, if read in as key1, key2, type of data */
204  if (wvlan_config->EnableEncryption) {
205  memset(&sEncryption, 0, sizeof(sEncryption));
206 
207  wl_wep_decode(CRYPT_CODE, &sEncryption,
208  wvlan_config->szEncryption);
209 
210  /* the Linux driver likes to use 1-4 for the key IDs, and then
211  convert to 0-3 when sending to the card. The Windows code
212  base used 0-3 in the API DLL, which was ported to Linux. For
213  the sake of the user experience, we decided to keep 0-3 as the
214  numbers used in the DLL; and will perform the +1 conversion here.
215  We could have converted the entire Linux driver, but this is
216  less obtrusive. This may be a "todo" to convert the whole driver */
217  sEncryption.wEnabled = wvlan_config->EnableEncryption;
218  sEncryption.wTxKeyID = wvlan_config->TransmitKeyID - 1;
219 
220  memcpy(&sEncryption.EncStr, &wvlan_config->DefaultKeys,
221  sizeof(CFG_DEFAULT_KEYS_STRCT));
222 
223  memset(wvlan_config->szEncryption, 0, sizeof(wvlan_config->szEncryption));
224 
225  wl_wep_code(CRYPT_CODE, wvlan_config->szEncryption, &sEncryption,
226  sizeof(sEncryption));
227  }
228 
229  /* decode the encryption string for the call to wl_commit() */
230  wl_wep_decode(CRYPT_CODE, &sEncryption, wvlan_config->szEncryption);
231 
232  wvlan_config->TransmitKeyID = sEncryption.wTxKeyID + 1;
233  wvlan_config->EnableEncryption = sEncryption.wEnabled;
234 
235  memcpy(&wvlan_config->DefaultKeys, &sEncryption.EncStr,
236  sizeof(CFG_DEFAULT_KEYS_STRCT));
237 
238 #if 0 /* BIN_DL */
239  /* Obtain a user-space process context, storing the original context */
240  fs = get_fs();
241  set_fs(get_ds());
242 
243  /* ;?just to fake something */
244  strcpy(/*wvlan_config->fw_image_*/filename, "/etc/agere/fw.bin");
245  file_desc = open(/*wvlan_config->fw_image_*/filename, 0, 0);
246  if (file_desc == -1) {
247  DBG_ERROR(DbgInfo, "No image file found\n");
248  } else {
249  DBG_TRACE(DbgInfo, "F/W image file found\n");
250 #define DHF_ALLOC_SIZE 96000 /* just below 96K, let's hope it suffices for now and for the future */
251  cp = vmalloc(DHF_ALLOC_SIZE);
252  if (cp == NULL) {
253  DBG_ERROR(DbgInfo, "error in vmalloc\n");
254  } else {
255  rc = read(file_desc, cp, DHF_ALLOC_SIZE);
256  if (rc == DHF_ALLOC_SIZE) {
257  DBG_ERROR(DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE);
258  } else if (rc > 0) {
259  DBG_TRACE(DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp);
260  rc = read(file_desc, &cp[rc], 1);
261  if (rc == 0)
262  DBG_TRACE(DbgInfo, "no more to read\n");
263  }
264  if (rc != 0) {
265  DBG_ERROR(DbgInfo, "file not read in one swoop or other error"\
266  ", give up, too complicated, rc = %0X\n", rc);
267  }
268  vfree(cp);
269  }
270  close(file_desc);
271  }
272  set_fs(fs); /* Return to the original context */
273 #endif /* BIN_DL */
274 
275  DBG_LEAVE(DbgInfo);
276  return;
277 } /* parse_config */
278 
279 /*******************************************************************************
280  * readline()
281  *******************************************************************************
282  *
283  * DESCRIPTION:
284  *
285  * This function reads in data from a given file one line at a time,
286  * converting the detected newline character '\n' to a null '\0'. Note that
287  * the file descriptor must be valid before calling this function.
288  *
289  * PARAMETERS:
290  *
291  * filedesc - the file descriptor for the open configuration file
292  * buffer - a buffer pointer, passed in by the caller, to which the
293  * line will be stored.
294  *
295  * RETURNS:
296  *
297  * the number of bytes read
298  * -1 on error
299  *
300  ******************************************************************************/
301 int readline(int filedesc, char *buffer)
302 {
303  int result = -1;
304  int bytes_read = 0;
305  /*------------------------------------------------------------------------*/
306 
307  /* Make sure the file descriptor is good */
308  if (filedesc != -1) {
309  /* Read in from the file byte by byte until a newline is reached */
310  while ((result = read(filedesc, &buffer[bytes_read], 1)) == 1) {
311  if (buffer[bytes_read] == '\n') {
312  buffer[bytes_read] = '\0';
313  bytes_read++;
314  break;
315  }
316  bytes_read++;
317  }
318  }
319 
320  /* Return the number of bytes read */
321  if (result == -1)
322  return result;
323  else
324  return bytes_read;
325 } /* readline */
326 /*============================================================================*/
327 
328 /*******************************************************************************
329  * translate_option()
330  *******************************************************************************
331  *
332  * DESCRIPTION:
333  *
334  * This function takes a line read in from the config file and parses out
335  * the key/value pairs. It then determines which key has been parsed and sets
336  * the card's configuration based on the value given.
337  *
338  * PARAMETERS:
339  *
340  * buffer - a buffer containing a line to translate
341  * config - a pointer to the device's private adapter structure
342  *
343  * RETURNS:
344  *
345  * N/A
346  *
347  ******************************************************************************/
348 void translate_option(char *buffer, struct wl_private *lp)
349 {
350  unsigned int value_convert = 0;
351  int string_length = 0;
352  char *key = NULL;
353  char *value = NULL;
355  /*------------------------------------------------------------------------*/
356 
357  DBG_FUNC("translate_option");
358 
359  if (buffer == NULL || lp == NULL) {
360  DBG_ERROR(DbgInfo, "Config file buffer and/or wavelan buffer ptr NULL\n");
361  return;
362  }
363 
364  ParseConfigLine(buffer, &key, &value);
365 
366  if (key == NULL || value == NULL)
367  return;
368 
369  /* Determine which key it is and perform the appropriate action */
370 
371  /* Configuration parameters used in all scenarios */
372 #if DBG
373  /* handle DebugFlag as early as possible so it starts its influence as early
374  * as possible
375  */
376  if (strcmp(key, PARM_NAME_DEBUG_FLAG) == 0) {
377  if (DebugFlag == ~0) { /* if DebugFlag is not specified on the command line */
378  if (DbgInfo->DebugFlag == 0) { /* if pc_debug did not set DebugFlag (i.e.pc_debug is
379  * not specified or specified outside the 4-8 range
380  */
381  DbgInfo->DebugFlag |= DBG_DEFAULTS;
382  }
383  } else {
384  DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); /* ;?DebugFlag; */
385  }
386  DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); /* ;?Delete ASAP */
387  }
388 #endif /* DBG */
389  if (strcmp(key, PARM_NAME_AUTH_KEY_MGMT_SUITE) == 0) {
390  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_AUTH_KEY_MGMT_SUITE, value);
391 
392  value_convert = simple_strtoul(value, NULL, 0);
393  if ((value_convert >= PARM_MIN_AUTH_KEY_MGMT_SUITE) || (value_convert <= PARM_MAX_AUTH_KEY_MGMT_SUITE))
394  lp->AuthKeyMgmtSuite = value_convert;
395  else
396  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTH_KEY_MGMT_SUITE);
397  } else if (strcmp(key, PARM_NAME_BRSC_2GHZ) == 0) {
398  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_2GHZ, value);
399 
400  value_convert = simple_strtoul(value, NULL, 0);
401  if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC))
402  lp->brsc[0] = value_convert;
403  else
404  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_BRSC_2GHZ);
405  } else if (strcmp(key, PARM_NAME_BRSC_5GHZ) == 0) {
406  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value);
407 
408  value_convert = simple_strtoul(value, NULL, 0);
409  if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC))
410  lp->brsc[1] = value_convert;
411  else
412  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_BRSC_5GHZ);
413  } else if ((strcmp(key, PARM_NAME_DESIRED_SSID) == 0) || (strcmp(key, PARM_NAME_OWN_SSID) == 0)) {
414  DBG_TRACE(DbgInfo, "SSID, value: %s\n", value);
415 
416  memset(lp->NetworkName, 0, (PARM_MAX_NAME_LEN + 1));
417 
418  /* Make sure the value isn't too long */
419  string_length = strlen(value);
420  if (string_length > PARM_MAX_NAME_LEN) {
421  DBG_WARNING(DbgInfo, "SSID too long; will be truncated\n");
422  string_length = PARM_MAX_NAME_LEN;
423  }
424 
425  memcpy(lp->NetworkName, value, string_length);
426  }
427 #if 0
428  else if (strcmp(key, PARM_NAME_DOWNLOAD_FIRMWARE) == 0) {
429  DBG_TRACE(DbgInfo, "DOWNLOAD_FIRMWARE, value: %s\n", value);
430  memset(lp->fw_image_filename, 0, (MAX_LINE_SIZE + 1));
431  /* Make sure the value isn't too long */
432  string_length = strlen(value);
433  if (string_length > MAX_LINE_SIZE)
434  DBG_WARNING(DbgInfo, "F/W image file name too long; will be ignored\n");
435  else
436  memcpy(lp->fw_image_filename, value, string_length);
437  }
438 #endif
439  else if (strcmp(key, PARM_NAME_ENABLE_ENCRYPTION) == 0) {
440  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_ENABLE_ENCRYPTION, value);
441 
442  value_convert = simple_strtoul(value, NULL, 0);
443  if ((value_convert >= PARM_MIN_ENABLE_ENCRYPTION) && (value_convert <= PARM_MAX_ENABLE_ENCRYPTION))
444  lp->EnableEncryption = value_convert;
445  else
446  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_ENABLE_ENCRYPTION);
447  } else if (strcmp(key, PARM_NAME_ENCRYPTION) == 0) {
448  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_ENCRYPTION, value);
449 
450  memset(lp->szEncryption, 0, sizeof(lp->szEncryption));
451 
452  /* Make sure the value isn't too long */
453  string_length = strlen(value);
454  if (string_length > sizeof(lp->szEncryption)) {
455  DBG_WARNING(DbgInfo, "%s too long; will be truncated\n", PARM_NAME_ENCRYPTION);
456  string_length = sizeof(lp->szEncryption);
457  }
458 
459  memcpy(lp->szEncryption, value, string_length);
460  } else if (strcmp(key, PARM_NAME_KEY1) == 0) {
461  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY1, value);
462 
463  if (is_valid_key_string(value)) {
464  memset(lp->DefaultKeys.key[0].key, 0, MAX_KEY_SIZE);
465 
466  key_string2key(value, &lp->DefaultKeys.key[0]);
467  } else {
468  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY1);
469  }
470  } else if (strcmp(key, PARM_NAME_KEY2) == 0) {
471  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY2, value);
472 
473  if (is_valid_key_string(value)) {
474  memset(lp->DefaultKeys.key[1].key, 0, MAX_KEY_SIZE);
475 
476  key_string2key(value, &lp->DefaultKeys.key[1]);
477  } else {
478  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY2);
479  }
480  } else if (strcmp(key, PARM_NAME_KEY3) == 0) {
481  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY3, value);
482 
483  if (is_valid_key_string(value)) {
484  memset(lp->DefaultKeys.key[2].key, 0, MAX_KEY_SIZE);
485 
486  key_string2key(value, &lp->DefaultKeys.key[2]);
487  } else {
488  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY3);
489  }
490  } else if (strcmp(key, PARM_NAME_KEY4) == 0) {
491  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY4, value);
492 
493  if (is_valid_key_string(value)) {
494  memset(lp->DefaultKeys.key[3].key, 0, MAX_KEY_SIZE);
495 
496  key_string2key(value, &lp->DefaultKeys.key[3]);
497  } else {
498  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY4);
499  }
500  }
501  /* New Parameters for WARP */
502  else if (strcmp(key, PARM_NAME_LOAD_BALANCING) == 0) {
503  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_LOAD_BALANCING, value);
504  lp->loadBalancing = parse_yes_no(value);
505  } else if (strcmp(key, PARM_NAME_MEDIUM_DISTRIBUTION) == 0) {
506  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MEDIUM_DISTRIBUTION, value);
507  lp->mediumDistribution = parse_yes_no(value);
508  } else if (strcmp(key, PARM_NAME_MICROWAVE_ROBUSTNESS) == 0) {
509  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MICROWAVE_ROBUSTNESS, value);
510  lp->MicrowaveRobustness = parse_yes_no(value);
511  } else if (strcmp(key, PARM_NAME_MULTICAST_RATE) == 0) {
512  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RATE, value);
513 
514  value_convert = simple_strtoul(value, NULL, 0);
515 
516  if ((value_convert >= PARM_MIN_MULTICAST_RATE) && (value_convert <= PARM_MAX_MULTICAST_RATE))
517  lp->MulticastRate[0] = value_convert;
518  else
519  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MULTICAST_RATE);
520  } else if (strcmp(key, PARM_NAME_OWN_CHANNEL) == 0) {
521  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_CHANNEL, value);
522 
523  value_convert = simple_strtoul(value, NULL, 0);
524  if (wl_is_a_valid_chan(value_convert)) {
525  if (value_convert > 14)
526  value_convert = value_convert | 0x100;
527  lp->Channel = value_convert;
528  } else {
529  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_CHANNEL);
530  }
531  } else if (strcmp(key, PARM_NAME_OWN_NAME) == 0) {
532  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_NAME, value);
533 
534  memset(lp->StationName, 0, (PARM_MAX_NAME_LEN + 1));
535 
536  /* Make sure the value isn't too long */
537  string_length = strlen(value);
538  if (string_length > PARM_MAX_NAME_LEN) {
539  DBG_WARNING(DbgInfo, "%s too long; will be truncated\n", PARM_NAME_OWN_NAME);
540  string_length = PARM_MAX_NAME_LEN;
541  }
542 
543  memcpy(lp->StationName, value, string_length);
544  } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD) == 0) {
545  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD, value);
546 
547  value_convert = simple_strtoul(value, NULL, 0);
548  if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
549  lp->RTSThreshold = value_convert;
550  else
551  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD);
552  } else if (strcmp(key, PARM_NAME_SRSC_2GHZ) == 0) {
553  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_2GHZ, value);
554 
555  value_convert = simple_strtoul(value, NULL, 0);
556  if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC))
557  lp->srsc[0] = value_convert;
558  else
559  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SRSC_2GHZ);
560  } else if (strcmp(key, PARM_NAME_SRSC_5GHZ) == 0) {
561  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value);
562 
563  value_convert = simple_strtoul(value, NULL, 0);
564  if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC))
565  lp->srsc[1] = value_convert;
566  else
567  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SRSC_5GHZ);
568  } else if (strcmp(key, PARM_NAME_SYSTEM_SCALE) == 0) {
569  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value);
570 
571  value_convert = simple_strtoul(value, NULL, 0);
572  if ((value_convert >= PARM_MIN_SYSTEM_SCALE) && (value_convert <= PARM_MAX_SYSTEM_SCALE))
573  lp->DistanceBetweenAPs = value_convert;
574  else
575  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SYSTEM_SCALE);
576  } else if (strcmp(key, PARM_NAME_TX_KEY) == 0) {
577  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_KEY, value);
578 
579  value_convert = simple_strtoul(value, NULL, 0);
580  if ((value_convert >= PARM_MIN_TX_KEY) && (value_convert <= PARM_MAX_TX_KEY))
581  lp->TransmitKeyID = simple_strtoul(value, NULL, 0);
582  else
583  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_KEY);
584  } else if (strcmp(key, PARM_NAME_TX_RATE) == 0) {
585  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE, value);
586 
587  value_convert = simple_strtoul(value, NULL, 0);
588  if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
589  lp->TxRateControl[0] = value_convert;
590  else
591  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE);
592  } else if (strcmp(key, PARM_NAME_TX_POW_LEVEL) == 0) {
593  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_POW_LEVEL, value);
594 
595  value_convert = simple_strtoul(value, NULL, 0);
596  if ((value_convert >= PARM_MIN_TX_POW_LEVEL) || (value_convert <= PARM_MAX_TX_POW_LEVEL))
597  lp->txPowLevel = value_convert;
598  else
599  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_POW_LEVEL);
600  }
601 
602  /* Need to add? : Country code, Short/Long retry */
603 
604  /* Configuration parameters specific to STA mode */
605 #if 1 /* ;? (HCF_TYPE) & HCF_TYPE_STA */
606 /* ;?seems reasonable that even an AP-only driver could afford this small additional footprint */
607  if (CNV_INT_TO_LITTLE(lp->hcfCtx.IFB_FWIdentity.comp_id) == COMP_ID_FW_STA) {
608  /* ;?should we return an error status in AP mode */
609  if (strcmp(key, PARM_NAME_PORT_TYPE) == 0) {
610  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PORT_TYPE, value);
611 
612  value_convert = simple_strtoul(value, NULL, 0);
613  if ((value_convert == PARM_MIN_PORT_TYPE) || (value_convert == PARM_MAX_PORT_TYPE))
614  lp->PortType = value_convert;
615  else
616  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PORT_TYPE);
617  } else if (strcmp(key, PARM_NAME_PM_ENABLED) == 0) {
618  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PM_ENABLED, value);
619  value_convert = simple_strtoul(value, NULL, 0);
620  /* ;? how about wl_main.c containing
621  * VALID_PARAM(PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
622  * (PARM_PM_ENABLED & 0x7FFF) <= WVLAN_PM_STATE_STANDARD);
623  */
624  if ((value_convert & 0x7FFF) <= PARM_MAX_PM_ENABLED) {
625  lp->PMEnabled = value_convert;
626  } else {
627  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_ENABLED);
628  /* ;?this is a data entry error, hence not a DBG_WARNING */
629  }
630  } else if (strcmp(key, PARM_NAME_CREATE_IBSS) == 0) {
631  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_CREATE_IBSS, value);
632  lp->CreateIBSS = parse_yes_no(value);
633  } else if (strcmp(key, PARM_NAME_MULTICAST_RX) == 0) {
634  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RX, value);
635  lp->MulticastReceive = parse_yes_no(value);
636  } else if (strcmp(key, PARM_NAME_MAX_SLEEP) == 0) {
637  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MAX_SLEEP, value);
638 
639  value_convert = simple_strtoul(value, NULL, 0);
640  if ((value_convert >= 0) && (value_convert <= 65535))
641  lp->MaxSleepDuration = value_convert;
642  else
643  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MAX_SLEEP);
644  } else if (strcmp(key, PARM_NAME_NETWORK_ADDR) == 0) {
645  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_NETWORK_ADDR, value);
646 
647  if (parse_mac_address(value, mac_value) == ETH_ALEN)
648  memcpy(lp->MACAddress, mac_value, ETH_ALEN);
649  else
650  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_NETWORK_ADDR);
651  } else if (strcmp(key, PARM_NAME_AUTHENTICATION) == 0) {
652  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_AUTHENTICATION, value);
653 
654  value_convert = simple_strtoul(value, NULL, 0);
655  if ((value_convert >= PARM_MIN_AUTHENTICATION) && (value_convert <= PARM_MAX_AUTHENTICATION))
656  lp->authentication = value_convert;
657  else
658  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTHENTICATION);
659  } else if (strcmp(key, PARM_NAME_OWN_ATIM_WINDOW) == 0) {
660  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_ATIM_WINDOW, value);
661 
662  value_convert = simple_strtoul(value, NULL, 0);
663  if ((value_convert >= PARM_MIN_OWN_ATIM_WINDOW) && (value_convert <= PARM_MAX_OWN_ATIM_WINDOW))
664  lp->atimWindow = value_convert;
665  else
666  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_ATIM_WINDOW);
667  } else if (strcmp(key, PARM_NAME_PM_HOLDOVER_DURATION) == 0) {
668  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PM_HOLDOVER_DURATION, value);
669 
670  value_convert = simple_strtoul(value, NULL, 0);
671  if ((value_convert >= PARM_MIN_PM_HOLDOVER_DURATION) && (value_convert <= PARM_MAX_PM_HOLDOVER_DURATION))
672  lp->holdoverDuration = value_convert;
673  else
674  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_HOLDOVER_DURATION);
675  } else if (strcmp(key, PARM_NAME_PROMISCUOUS_MODE) == 0) {
676  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PROMISCUOUS_MODE, value);
677  lp->promiscuousMode = parse_yes_no(value);
678  } else if (strcmp(key, PARM_NAME_CONNECTION_CONTROL) == 0) {
679  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_CONNECTION_CONTROL, value);
680 
681  value_convert = simple_strtoul(value, NULL, 0);
682  if ((value_convert >= PARM_MIN_CONNECTION_CONTROL) && (value_convert <= PARM_MAX_CONNECTION_CONTROL))
683  lp->connectionControl = value_convert;
684  else
685  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_CONNECTION_CONTROL);
686  }
687 
688  /* Need to add? : Probe Data Rate */
689  }
690 #endif /* (HCF_TYPE) & HCF_TYPE_STA */
691 
692  /* Configuration parameters specific to AP mode */
693 #if 1 /* ;? (HCF_TYPE) & HCF_TYPE_AP */
694  /* ;?should we restore this to allow smaller memory footprint */
695  if (CNV_INT_TO_LITTLE(lp->hcfCtx.IFB_FWIdentity.comp_id) == COMP_ID_FW_AP) {
696  if (strcmp(key, PARM_NAME_OWN_DTIM_PERIOD) == 0) {
697  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD, value);
698 
699  value_convert = simple_strtoul(value, NULL, 0);
700  if (value_convert >= PARM_MIN_OWN_DTIM_PERIOD)
701  lp->DTIMPeriod = value_convert;
702  else
703  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_DTIM_PERIOD);
704  } else if (strcmp(key, PARM_NAME_REJECT_ANY) == 0) {
705  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_REJECT_ANY, value);
706  lp->RejectAny = parse_yes_no(value);
707  } else if (strcmp(key, PARM_NAME_EXCLUDE_UNENCRYPTED) == 0) {
708  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_EXCLUDE_UNENCRYPTED, value);
709  lp->ExcludeUnencrypted = parse_yes_no(value);
710  } else if (strcmp(key, PARM_NAME_MULTICAST_PM_BUFFERING) == 0) {
711  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_PM_BUFFERING, value);
712  lp->ExcludeUnencrypted = parse_yes_no(value);
713  } else if (strcmp(key, PARM_NAME_INTRA_BSS_RELAY) == 0) {
714  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_INTRA_BSS_RELAY, value);
715  lp->ExcludeUnencrypted = parse_yes_no(value);
716  } else if (strcmp(key, PARM_NAME_OWN_BEACON_INTERVAL) == 0) {
717  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_BEACON_INTERVAL, value);
718 
719  value_convert = simple_strtoul(value, NULL, 0);
720  if (value_convert >= PARM_MIN_OWN_BEACON_INTERVAL)
721  lp->ownBeaconInterval = value_convert;
722  else
723  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_BEACON_INTERVAL);
724  } else if (strcmp(key, PARM_NAME_COEXISTENCE) == 0) {
725  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_COEXISTENCE, value);
726 
727  value_convert = simple_strtoul(value, NULL, 0);
728  if (value_convert >= PARM_MIN_COEXISTENCE)
729  lp->coexistence = value_convert;
730  else
731  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_COEXISTENCE);
732  }
733 
734 #ifdef USE_WDS
735  else if (strcmp(key, PARM_NAME_RTS_THRESHOLD1) == 0) {
736  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD1, value);
737 
738  value_convert = simple_strtoul(value, NULL, 0);
739  if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
740  lp->wds_port[0].rtsThreshold = value_convert;
741  else
742  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD1);
743  } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD2) == 0) {
744  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD2, value);
745 
746  value_convert = simple_strtoul(value, NULL, 0);
747  if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
748  lp->wds_port[1].rtsThreshold = value_convert;
749  else
750  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD2);
751  } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD3) == 0) {
752  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD3, value);
753 
754  value_convert = simple_strtoul(value, NULL, 0);
755  if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
756  lp->wds_port[2].rtsThreshold = value_convert;
757  else
758  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD3);
759  } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD4) == 0) {
760  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD4, value);
761 
762  value_convert = simple_strtoul(value, NULL, 0);
763  if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
764  lp->wds_port[3].rtsThreshold = value_convert;
765  else
766  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD4);
767  } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD5) == 0) {
768  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD5, value);
769 
770  value_convert = simple_strtoul(value, NULL, 0);
771  if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
772  lp->wds_port[4].rtsThreshold = value_convert;
773  else
774  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD5);
775  } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD6) == 0) {
776  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD6, value);
777 
778  value_convert = simple_strtoul(value, NULL, 0);
779  if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
780  lp->wds_port[5].rtsThreshold = value_convert;
781  else
782  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD6);
783  } else if (strcmp(key, PARM_NAME_TX_RATE1) == 0) {
784  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE1, value);
785 
786  value_convert = simple_strtoul(value, NULL, 0);
787  if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
788  lp->wds_port[0].txRateCntl = value_convert;
789  else
790  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE1);
791  } else if (strcmp(key, PARM_NAME_TX_RATE2) == 0) {
792  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE2, value);
793 
794  value_convert = simple_strtoul(value, NULL, 0);
795  if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
796  lp->wds_port[1].txRateCntl = value_convert;
797  else
798  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE2);
799  } else if (strcmp(key, PARM_NAME_TX_RATE3) == 0) {
800  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE3, value);
801 
802  value_convert = simple_strtoul(value, NULL, 0);
803  if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
804  lp->wds_port[2].txRateCntl = value_convert;
805  else
806  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE3);
807  } else if (strcmp(key, PARM_NAME_TX_RATE4) == 0) {
808  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE4, value);
809 
810  value_convert = simple_strtoul(value, NULL, 0);
811  if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
812  lp->wds_port[3].txRateCntl = value_convert;
813  else
814  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE4);
815  } else if (strcmp(key, PARM_NAME_TX_RATE5) == 0) {
816  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE5, value);
817 
818  value_convert = simple_strtoul(value, NULL, 0);
819  if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
820  lp->wds_port[4].txRateCntl = value_convert;
821  else
822  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE5);
823  } else if (strcmp(key, PARM_NAME_TX_RATE6) == 0) {
824  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE6, value);
825 
826  value_convert = simple_strtoul(value, NULL, 0);
827  if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
828  lp->wds_port[5].txRateCntl = value_convert;
829  else
830  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE6);
831  } else if (strcmp(key, PARM_NAME_WDS_ADDRESS1) == 0) {
832  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS1, value);
833 
834  if (parse_mac_address(value, mac_value) == ETH_ALEN)
835  memcpy(lp->wds_port[0].wdsAddress, mac_value, ETH_ALEN);
836  else
837  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS1);
838  } else if (strcmp(key, PARM_NAME_WDS_ADDRESS2) == 0) {
839  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS2, value);
840 
841  if (parse_mac_address(value, mac_value) == ETH_ALEN)
842  memcpy(lp->wds_port[1].wdsAddress, mac_value, ETH_ALEN);
843  else
844  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS2);
845  } else if (strcmp(key, PARM_NAME_WDS_ADDRESS3) == 0) {
846  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS3, value);
847 
848  if (parse_mac_address(value, mac_value) == ETH_ALEN)
849  memcpy(lp->wds_port[2].wdsAddress, mac_value, ETH_ALEN);
850  else
851  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS3);
852  } else if (strcmp(key, PARM_NAME_WDS_ADDRESS4) == 0) {
853  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS4, value);
854 
855  if (parse_mac_address(value, mac_value) == ETH_ALEN)
856  memcpy(lp->wds_port[3].wdsAddress, mac_value, ETH_ALEN);
857  else
858  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS4);
859  } else if (strcmp(key, PARM_NAME_WDS_ADDRESS5) == 0) {
860  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS5, value);
861 
862  if (parse_mac_address(value, mac_value) == ETH_ALEN)
863  memcpy(lp->wds_port[4].wdsAddress, mac_value, ETH_ALEN);
864  else
865  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS5);
866  } else if (strcmp(key, PARM_NAME_WDS_ADDRESS6) == 0) {
867  DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS6, value);
868 
869  if (parse_mac_address(value, mac_value) == ETH_ALEN)
870  memcpy(lp->wds_port[5].wdsAddress, mac_value, ETH_ALEN);
871  else
872  DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS6);
873  }
874 #endif /* USE_WDS */
875  }
876 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
877 
878  return;
879 } /* translate_option */
880 /*============================================================================*/
881 
882 /*******************************************************************************
883  * parse_mac_address()
884  *******************************************************************************
885  *
886  * DESCRIPTION:
887  *
888  * This function will parse a mac address string and convert it to a byte
889  * array.
890  *
891  * PARAMETERS:
892  *
893  * value - the MAC address, represented as a string
894  * byte_array - the MAC address, represented as a byte array of length
895  * ETH_ALEN
896  *
897  * RETURNS:
898  *
899  * The number of bytes in the final MAC address, should equal to ETH_ALEN.
900  *
901  ******************************************************************************/
902 int parse_mac_address(char *value, u_char *byte_array)
903 {
904  int value_offset = 0;
905  int array_offset = 0;
906  int field_offset = 0;
907  char byte_field[3];
908  /*------------------------------------------------------------------------*/
909 
910  memset(byte_field, '\0', 3);
911 
912  while (value[value_offset] != '\0') {
913  /* Skip over the colon chars separating the bytes, if they exist */
914  if (value[value_offset] == ':') {
915  value_offset++;
916  continue;
917  }
918 
919  byte_field[field_offset] = value[value_offset];
920  field_offset++;
921  value_offset++;
922 
923  /* Once the byte_field is filled, convert it and store it */
924  if (field_offset == 2) {
925  byte_field[field_offset] = '\0';
926  byte_array[array_offset] = simple_strtoul(byte_field, NULL, 16);
927  field_offset = 0;
928  array_offset++;
929  }
930  }
931 
932  /* Use the array_offset as a check; 6 bytes should be written to the
933  byte_array */
934  return array_offset;
935 } /* parse_mac_address */
936 /*============================================================================*/
937 
938 /*******************************************************************************
939  * ParseConfigLine()
940  *******************************************************************************
941  *
942  * DESCRIPTION:
943  *
944  * Parses a line from the configuration file into an L-val and an R-val,
945  * representing a key/value pair.
946  *
947  * PARAMETERS:
948  *
949  * pszLine - the line from the config file to parse
950  * ppszLVal - the resulting L-val (Key)
951  * ppszRVal - the resulting R-val (Value)
952  *
953  * RETURNS:
954  *
955  * N/A
956  *
957  ******************************************************************************/
958 void ParseConfigLine(char *pszLine, char **ppszLVal, char **ppszRVal)
959 {
960  int i;
961  int size;
962  /*------------------------------------------------------------------------*/
963 
964  DBG_FUNC("ParseConfigLine");
965  DBG_ENTER(DbgInfo);
966 
967  /* get a snapshot of our string size */
968  size = strlen(pszLine);
969  *ppszLVal = NULL;
970  *ppszRVal = NULL;
971 
972  if (pszLine[0] != '#' && /* skip the line if it is a comment */
973  pszLine[0] != '\n' && /* if it's an empty UNIX line, do nothing */
974  !(pszLine[0] == '\r' && pszLine[1] == '\n') /* if it's an empty MS-DOS line, do nothing */
975  ) {
976  /* advance past any whitespace, and assign the L-value */
977  for (i = 0; i < size; i++) {
978  if (pszLine[i] != ' ') {
979  *ppszLVal = &pszLine[i];
980  break;
981  }
982  }
983  /* advance to the end of the l-value*/
984  for (i++; i < size; i++) {
985  if (pszLine[i] == ' ' || pszLine[i] == '=') {
986  pszLine[i] = '\0';
987  break;
988  }
989  }
990  /* make any whitespace and the equal sign a NULL character, and
991  advance to the R-Value */
992  for (i++; i < size; i++) {
993  if (pszLine[i] == ' ' || pszLine[i] == '=') {
994  pszLine[i] = '\0';
995  continue;
996  }
997  *ppszRVal = &pszLine[i];
998  break;
999  }
1000  /* make the line ending character(s) a NULL */
1001  for (i++; i < size; i++) {
1002  if (pszLine[i] == '\n')
1003  pszLine[i] = '\0';
1004  if ((pszLine[i] == '\r') && (pszLine[i+1] == '\n'))
1005  pszLine[i] = '\0';
1006  }
1007  }
1008  DBG_LEAVE(DbgInfo);
1009 } /* ParseConfigLine */
1010 /*============================================================================*/
1011 
1012 #endif /* USE_PROFILE */