common.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 
00020 
00021 #ifdef CONFIG_DEBUG_FILE
00022 static FILE *out_file = NULL;
00023 #endif /* CONFIG_DEBUG_FILE */
00024 int wpa_debug_use_file = 0;
00025 int wpa_debug_level = MSG_INFO;
00026 int wpa_debug_show_keys = 0;
00027 int wpa_debug_timestamp = 0;
00028 
00029 
00030 static int hex2num(char c)
00031 {
00032         if (c >= '0' && c <= '9')
00033                 return c - '0';
00034         if (c >= 'a' && c <= 'f')
00035                 return c - 'a' + 10;
00036         if (c >= 'A' && c <= 'F')
00037                 return c - 'A' + 10;
00038         return -1;
00039 }
00040 
00041 
00042 static int hex2byte(const char *hex)
00043 {
00044         int a, b;
00045         a = hex2num(*hex++);
00046         if (a < 0)
00047                 return -1;
00048         b = hex2num(*hex++);
00049         if (b < 0)
00050                 return -1;
00051         return (a << 4) | b;
00052 }
00053 
00054 
00062 int hwaddr_aton(const char *txt, u8 *addr)
00063 {
00064         int i;
00065 
00066         for (i = 0; i < 6; i++) {
00067                 int a, b;
00068 
00069                 a = hex2num(*txt++);
00070                 if (a < 0)
00071                         return -1;
00072                 b = hex2num(*txt++);
00073                 if (b < 0)
00074                         return -1;
00075                 *addr++ = (a << 4) | b;
00076                 if (i < 5 && *txt++ != ':')
00077                         return -1;
00078         }
00079 
00080         return 0;
00081 }
00082 
00083 
00093 int hexstr2bin(const char *hex, u8 *buf, size_t len)
00094 {
00095         size_t i;
00096         int a;
00097         const char *ipos = hex;
00098         u8 *opos = buf;
00099 
00100         for (i = 0; i < len; i++) {
00101                 a = hex2byte(ipos);
00102                 if (a < 0)
00103                         return -1;
00104                 *opos++ = a;
00105                 ipos += 2;
00106         }
00107         return 0;
00108 }
00109 
00110 
00121 void inc_byte_array(u8 *counter, size_t len)
00122 {
00123         int pos = len - 1;
00124         while (pos >= 0) {
00125                 counter[pos]++;
00126                 if (counter[pos] != 0)
00127                         break;
00128                 pos--;
00129         }
00130 }
00131 
00132 
00133 void wpa_get_ntp_timestamp(u8 *buf)
00134 {
00135         struct os_time now;
00136         u32 sec, usec;
00137 
00138         /* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */
00139         os_get_time(&now);
00140         sec = host_to_be32(now.sec + 2208988800U); /* Epoch to 1900 */
00141         /* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */
00142         usec = now.usec;
00143         usec = host_to_be32(4295 * usec - (usec >> 5) - (usec >> 9));
00144         os_memcpy(buf, (u8 *) &sec, 4);
00145         os_memcpy(buf + 4, (u8 *) &usec, 4);
00146 }
00147 
00148 
00149 
00150 #ifndef CONFIG_NO_STDOUT_DEBUG
00151 
00152 void wpa_debug_print_timestamp(void)
00153 {
00154         struct os_time tv;
00155 
00156         if (!wpa_debug_timestamp)
00157                 return;
00158 
00159         os_get_time(&tv);
00160 #ifdef CONFIG_DEBUG_FILE
00161         if (out_file) {
00162                 fprintf(out_file, "%ld.%06u: ", (long) tv.sec,
00163                         (unsigned int) tv.usec);
00164         } else
00165 #endif /* CONFIG_DEBUG_FILE */
00166         printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
00167 }
00168 
00169 
00182 void wpa_printf(int level, char *fmt, ...)
00183 {
00184         va_list ap;
00185 
00186         va_start(ap, fmt);
00187         if (level >= wpa_debug_level) {
00188                 wpa_debug_print_timestamp();
00189 #ifdef CONFIG_DEBUG_FILE
00190                 if (out_file) {
00191                         vfprintf(out_file, fmt, ap);
00192                         fprintf(out_file, "\n");
00193                 } else {
00194 #endif /* CONFIG_DEBUG_FILE */
00195                 vprintf(fmt, ap);
00196                 printf("\n");
00197 #ifdef CONFIG_DEBUG_FILE
00198                 }
00199 #endif /* CONFIG_DEBUG_FILE */
00200         }
00201         va_end(ap);
00202 }
00203 
00204 
00205 static void _wpa_hexdump(int level, const char *title, const u8 *buf,
00206                          size_t len, int show)
00207 {
00208         size_t i;
00209         if (level < wpa_debug_level)
00210                 return;
00211         wpa_debug_print_timestamp();
00212 #ifdef CONFIG_DEBUG_FILE
00213         if (out_file) {
00214                 fprintf(out_file, "%s - hexdump(len=%lu):",
00215                         title, (unsigned long) len);
00216                 if (buf == NULL) {
00217                         fprintf(out_file, " [NULL]");
00218                 } else if (show) {
00219                         for (i = 0; i < len; i++)
00220                                 fprintf(out_file, " %02x", buf[i]);
00221                 } else {
00222                         fprintf(out_file, " [REMOVED]");
00223                 }
00224                 fprintf(out_file, "\n");
00225         } else {
00226 #endif /* CONFIG_DEBUG_FILE */
00227         printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
00228         if (buf == NULL) {
00229                 printf(" [NULL]");
00230         } else if (show) {
00231                 for (i = 0; i < len; i++)
00232                         printf(" %02x", buf[i]);
00233         } else {
00234                 printf(" [REMOVED]");
00235         }
00236         printf("\n");
00237 #ifdef CONFIG_DEBUG_FILE
00238         }
00239 #endif /* CONFIG_DEBUG_FILE */
00240 }
00241 
00242 void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
00243 {
00244         _wpa_hexdump(level, title, buf, len, 1);
00245 }
00246 
00247 
00248 void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len)
00249 {
00250         _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
00251 }
00252 
00253 
00254 static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
00255                                size_t len, int show)
00256 {
00257         size_t i, llen;
00258         const u8 *pos = buf;
00259         const size_t line_len = 16;
00260 
00261         if (level < wpa_debug_level)
00262                 return;
00263         wpa_debug_print_timestamp();
00264 #ifdef CONFIG_DEBUG_FILE
00265         if (out_file) {
00266                 if (!show) {
00267                         fprintf(out_file,
00268                                 "%s - hexdump_ascii(len=%lu): [REMOVED]\n",
00269                                 title, (unsigned long) len);
00270                         return;
00271                 }
00272                 if (buf == NULL) {
00273                         fprintf(out_file,
00274                                 "%s - hexdump_ascii(len=%lu): [NULL]\n",
00275                                 title, (unsigned long) len);
00276                         return;
00277                 }
00278                 fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
00279                         title, (unsigned long) len);
00280                 while (len) {
00281                         llen = len > line_len ? line_len : len;
00282                         fprintf(out_file, "    ");
00283                         for (i = 0; i < llen; i++)
00284                                 fprintf(out_file, " %02x", pos[i]);
00285                         for (i = llen; i < line_len; i++)
00286                                 fprintf(out_file, "   ");
00287                         fprintf(out_file, "   ");
00288                         for (i = 0; i < llen; i++) {
00289                                 if (isprint(pos[i]))
00290                                         fprintf(out_file, "%c", pos[i]);
00291                                 else
00292                                         fprintf(out_file, "_");
00293                         }
00294                         for (i = llen; i < line_len; i++)
00295                                 fprintf(out_file, " ");
00296                         fprintf(out_file, "\n");
00297                         pos += llen;
00298                         len -= llen;
00299                 }
00300         } else {
00301 #endif /* CONFIG_DEBUG_FILE */
00302         if (!show) {
00303                 printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
00304                        title, (unsigned long) len);
00305                 return;
00306         }
00307         if (buf == NULL) {
00308                 printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
00309                        title, (unsigned long) len);
00310                 return;
00311         }
00312         printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
00313         while (len) {
00314                 llen = len > line_len ? line_len : len;
00315                 printf("    ");
00316                 for (i = 0; i < llen; i++)
00317                         printf(" %02x", pos[i]);
00318                 for (i = llen; i < line_len; i++)
00319                         printf("   ");
00320                 printf("   ");
00321                 for (i = 0; i < llen; i++) {
00322                         if (isprint(pos[i]))
00323                                 printf("%c", pos[i]);
00324                         else
00325                                 printf("_");
00326                 }
00327                 for (i = llen; i < line_len; i++)
00328                         printf(" ");
00329                 printf("\n");
00330                 pos += llen;
00331                 len -= llen;
00332         }
00333 #ifdef CONFIG_DEBUG_FILE
00334         }
00335 #endif /* CONFIG_DEBUG_FILE */
00336 }
00337 
00338 
00339 void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len)
00340 {
00341         _wpa_hexdump_ascii(level, title, buf, len, 1);
00342 }
00343 
00344 
00345 void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
00346                            size_t len)
00347 {
00348         _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
00349 }
00350 
00351 
00352 int wpa_debug_open_file(void)
00353 {
00354 #ifdef CONFIG_DEBUG_FILE
00355         static int count = 0;
00356         char fname[64];
00357         if (!wpa_debug_use_file)
00358                 return 0;
00359 #ifdef _WIN32
00360         os_snprintf(fname, sizeof(fname), "\\Temp\\wpa_supplicant-log-%d.txt",
00361                     count++);
00362 #else /* _WIN32 */
00363         os_snprintf(fname, sizeof(fname), "/tmp/wpa_supplicant-log-%d.txt",
00364                     count++);
00365 #endif /* _WIN32 */
00366         out_file = fopen(fname, "w");
00367         return out_file == NULL ? -1 : 0;
00368 #else /* CONFIG_DEBUG_FILE */
00369         return 0;
00370 #endif /* CONFIG_DEBUG_FILE */
00371 }
00372 
00373 
00374 void wpa_debug_close_file(void)
00375 {
00376 #ifdef CONFIG_DEBUG_FILE
00377         if (!wpa_debug_use_file)
00378                 return;
00379         fclose(out_file);
00380         out_file = NULL;
00381 #endif /* CONFIG_DEBUG_FILE */
00382 }
00383 
00384 #endif /* CONFIG_NO_STDOUT_DEBUG */
00385 
00386 
00387 #ifndef CONFIG_NO_WPA_MSG
00388 static wpa_msg_cb_func wpa_msg_cb = NULL;
00389 
00390 void wpa_msg_register_cb(wpa_msg_cb_func func)
00391 {
00392         wpa_msg_cb = func;
00393 }
00394 
00395 
00396 void wpa_msg(void *ctx, int level, char *fmt, ...)
00397 {
00398         va_list ap;
00399         char *buf;
00400         const int buflen = 2048;
00401         int len;
00402 
00403         buf = os_malloc(buflen);
00404         if (buf == NULL) {
00405                 wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
00406                            "buffer");
00407                 return;
00408         }
00409         va_start(ap, fmt);
00410         len = vsnprintf(buf, buflen, fmt, ap);
00411         va_end(ap);
00412         wpa_printf(level, "%s", buf);
00413         if (wpa_msg_cb)
00414                 wpa_msg_cb(ctx, level, buf, len);
00415         os_free(buf);
00416 }
00417 #endif /* CONFIG_NO_WPA_MSG */
00418 
00419 
00420 static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data,
00421                                     size_t len, int uppercase)
00422 {
00423         size_t i;
00424         char *pos = buf, *end = buf + buf_size;
00425         int ret;
00426         if (buf_size == 0)
00427                 return 0;
00428         for (i = 0; i < len; i++) {
00429                 ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x",
00430                                   data[i]);
00431                 if (ret < 0 || ret >= end - pos) {
00432                         end[-1] = '\0';
00433                         return pos - buf;
00434                 }
00435                 pos += ret;
00436         }
00437         end[-1] = '\0';
00438         return pos - buf;
00439 }
00440 
00450 int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
00451 {
00452         return _wpa_snprintf_hex(buf, buf_size, data, len, 0);
00453 }
00454 
00455 
00465 int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
00466                                size_t len)
00467 {
00468         return _wpa_snprintf_hex(buf, buf_size, data, len, 1);
00469 }
00470 
00471 
00472 #ifdef CONFIG_ANSI_C_EXTRA
00473 
00474 #ifdef _WIN32_WCE
00475 void perror(const char *s)
00476 {
00477         wpa_printf(MSG_ERROR, "%s: GetLastError: %d",
00478                    s, (int) GetLastError());
00479 }
00480 #endif /* _WIN32_WCE */
00481 
00482 
00483 int optind = 1;
00484 int optopt;
00485 char *optarg;
00486 
00487 int getopt(int argc, char *const argv[], const char *optstring)
00488 {
00489         static int optchr = 1;
00490         char *cp;
00491 
00492         if (optchr == 1) {
00493                 if (optind >= argc) {
00494                         /* all arguments processed */
00495                         return EOF;
00496                 }
00497 
00498                 if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
00499                         /* no option characters */
00500                         return EOF;
00501                 }
00502         }
00503 
00504         if (strcmp(argv[optind], "--") == 0) {
00505                 /* no more options */
00506                 optind++;
00507                 return EOF;
00508         }
00509 
00510         optopt = argv[optind][optchr];
00511         cp = strchr(optstring, optopt);
00512         if (cp == NULL || optopt == ':') {
00513                 if (argv[optind][++optchr] == '\0') {
00514                         optchr = 1;
00515                         optind++;
00516                 }
00517                 return '?';
00518         }
00519 
00520         if (cp[1] == ':') {
00521                 /* Argument required */
00522                 optchr = 1;
00523                 if (argv[optind][optchr + 1]) {
00524                         /* No space between option and argument */
00525                         optarg = &argv[optind++][optchr + 1];
00526                 } else if (++optind >= argc) {
00527                         /* option requires an argument */
00528                         return '?';
00529                 } else {
00530                         /* Argument in the next argv */
00531                         optarg = argv[optind++];
00532                 }
00533         } else {
00534                 /* No argument */
00535                 if (argv[optind][++optchr] == '\0') {
00536                         optchr = 1;
00537                         optind++;
00538                 }
00539                 optarg = NULL;
00540         }
00541         return *cp;
00542 }
00543 #endif /* CONFIG_ANSI_C_EXTRA */
00544 
00545 
00546 #ifdef CONFIG_NATIVE_WINDOWS
00547 
00556 void wpa_unicode2ascii_inplace(TCHAR *str)
00557 {
00558 #ifdef UNICODE
00559         char *dst = (char *) str;
00560         while (*str)
00561                 *dst++ = (char) *str++;
00562         *dst = '\0';
00563 #endif /* UNICODE */
00564 }
00565 
00566 
00567 TCHAR * wpa_strdup_tchar(const char *str)
00568 {
00569 #ifdef UNICODE
00570         TCHAR *buf;
00571         buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR));
00572         if (buf == NULL)
00573                 return NULL;
00574         wsprintf(buf, L"%S", str);
00575         return buf;
00576 #else /* UNICODE */
00577         return os_strdup(str);
00578 #endif /* UNICODE */
00579 }
00580 #endif /* CONFIG_NATIVE_WINDOWS */
00581 
00582 
00598 const char * wpa_ssid_txt(u8 *ssid, size_t ssid_len)
00599 {
00600         static char ssid_txt[33];
00601         char *pos;
00602 
00603         if (ssid_len > 32)
00604                 ssid_len = 32;
00605         os_memcpy(ssid_txt, ssid, ssid_len);
00606         ssid_txt[ssid_len] = '\0';
00607         for (pos = ssid_txt; *pos != '\0'; pos++) {
00608                 if ((u8) *pos < 32 || (u8) *pos >= 127)
00609                         *pos = '_';
00610         }
00611         return ssid_txt;
00612 }
00613 

Generated on Sun Dec 31 13:43:25 2006 for hostapd by  doxygen 1.4.2