get libsmi into the picture
[obnox/wireshark/wip.git] / version_info.c
1 /* version_info.c
2  * Routines to report version information for stuff used by Wireshark
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <glib.h>
30
31 #include <stdlib.h>
32 #include <string.h>
33 #include <errno.h>
34
35 #ifdef HAVE_LIBZ
36 #include <zlib.h>       /* to get the libz version number */
37 #endif
38
39 #ifdef HAVE_LIBPCRE
40 #include <pcre.h>       /* to get the libpcre version number */
41 #endif /* HAVE_LIBPCRE */
42
43 #ifdef HAVE_NET_SNMP
44 #include <net-snmp/version.h>
45 #endif /* HAVE_NET_SNMP */
46
47 #if (defined(HAVE_LIBGCRYPT) || defined(HAVE_LIBGNUTLS)) && defined(_WIN32)
48 #include <winposixtype.h>
49 #endif
50
51 #ifdef HAVE_LIBGCRYPT
52 #include <gcrypt.h>
53 #endif /* HAVE_LIBGCRYPT */
54
55 #ifdef HAVE_LIBGNUTLS
56 #include <gnutls/gnutls.h>
57 #endif /* HAVE_LIBGNUTLS */
58
59 #ifdef HAVE_SYS_UTSNAME_H
60 #include <sys/utsname.h>
61 #endif
62
63 #include "version_info.h"
64 #include "capture-pcap-util.h"
65 #include "epan/unicode-utils.h"
66
67 #include "svnversion.h"
68
69 #ifdef HAVE_WINDOWS_H
70 #include <windows.h>
71 #endif
72
73 #ifdef HAVE_LUA_5_1
74 #include <lua.h>
75 #endif
76
77 #ifdef SVNVERSION
78         const char *wireshark_svnversion = " (" SVNVERSION ")";
79 #else
80         const char *wireshark_svnversion = "";
81 #endif
82
83 /*
84  * If the string doesn't end with a newline, append one.
85  * Then word-wrap it to 80 columns.
86  */
87 static void
88 end_string(GString *str)
89 {
90         size_t point;
91         char *p, *q;
92
93         point = strlen(str->str);
94         if (point == 0 || str->str[point - 1] != '\n')
95                 g_string_append(str, "\n");
96         p = str->str;
97         while (*p != '\0') {
98                 q = strchr(p, '\n');
99                 if (q - p > 80) {
100                         /*
101                          * Break at or before this point.
102                          */
103                         q = p + 80;
104                         while (q > p && *q != ' ')
105                                 q--;
106                         if (q != p)
107                                 *q = '\n';
108                 }
109                 p = q + 1;
110         }
111 }
112
113 /*
114  * Get various library compile-time versions and append them to
115  * the specified GString.
116  *
117  * "additional_info" is called at the end to append any additional
118  * information; this is required in order to, for example, put the
119  * Portaudio information at the end of the string, as we currently
120  * don't use Portaudio in TShark.
121  */
122 void
123 get_compiled_version_info(GString *str, void (*additional_info)(GString *))
124 {
125         /* GLIB */
126         g_string_append(str, "with ");
127         g_string_sprintfa(str,
128 #ifdef GLIB_MAJOR_VERSION
129             "GLib %d.%d.%d", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
130             GLIB_MICRO_VERSION);
131 #else
132             "GLib (version unknown)");
133 #endif
134
135         /* Libpcap */
136         g_string_append(str, ", ");
137         get_compiled_pcap_version(str);
138
139         /* LIBZ */
140         g_string_append(str, ", ");
141 #ifdef HAVE_LIBZ
142         g_string_append(str, "with libz ");
143 #ifdef ZLIB_VERSION
144         g_string_append(str, ZLIB_VERSION);
145 #else /* ZLIB_VERSION */
146         g_string_append(str, "(version unknown)");
147 #endif /* ZLIB_VERSION */
148 #else /* HAVE_LIBZ */
149         g_string_append(str, "without libz");
150 #endif /* HAVE_LIBZ */
151
152         /* Additional application-dependent information */
153         if (additional_info)
154                 (*additional_info)(str);
155         g_string_append(str, ".");
156
157 #ifndef HAVE_LIBPCRE
158         g_string_append(str,
159         "\nNOTE: this build doesn't support the \"matches\" operator for Wireshark filter syntax");
160         g_string_append(str, ".");
161 #endif  /* HAVE_LIBPCRE */
162
163         end_string(str);
164 }
165
166 /*
167  * Get compile-time information used only by applications that use
168  * libwireshark.
169  */
170 void
171 get_epan_compiled_version_info(GString *str)
172 {
173         /* PCRE */
174         g_string_append(str, ", ");
175 #ifdef HAVE_LIBPCRE
176         g_string_append(str, "with libpcre ");
177 #ifdef PCRE_MAJOR
178 #ifdef PCRE_MINOR
179         g_string_sprintfa(str, "%u.%u", PCRE_MAJOR, PCRE_MINOR);
180 #else                   /* PCRE_MINOR */
181         g_string_sprintfa(str, "%u", PCRE_MAJOR);
182 #endif                  /* PCRE_MINOR */
183 #else           /* PCRE_MAJOR */
184         g_string_append(str, "(version unknown)");
185 #endif          /* PCRE_MAJOR */
186 #else   /* HAVE_LIBPCRE */
187         g_string_append(str, "without libpcre");
188 #endif  /* HAVE_LIBPCRE */
189
190         /* SNMP */
191         g_string_append(str, ", ");
192 #ifdef HAVE_NET_SNMP
193         g_string_append(str, "with Net-SNMP ");
194         g_string_append(str, netsnmp_get_version());
195 #else /* no SNMP library */
196         g_string_append(str, "without Net-SNMP");
197 #endif /* HAVE_NET_SNMP */
198
199         /* ADNS */
200         g_string_append(str, ", ");
201 #ifdef HAVE_GNU_ADNS
202         g_string_append(str, "with ADNS");
203 #else
204         g_string_append(str, "without ADNS");
205 #endif /* HAVE_GNU_ADNS */
206
207         /* LUA */
208         g_string_append(str, ", ");
209 #ifdef HAVE_LUA_5_1
210         g_string_append(str, "with ");
211         g_string_append(str, LUA_VERSION);
212 #else
213         g_string_append(str, "without Lua");
214 #endif /* HAVE_LUA_5_1 */
215
216         /* GnuTLS */
217         g_string_append(str, ", ");
218 #ifdef HAVE_LIBGNUTLS
219         g_string_append(str, "with GnuTLS " LIBGNUTLS_VERSION);
220 #else
221         g_string_append(str, "without GnuTLS");
222 #endif /* HAVE_LIBGNUTLS */
223
224         /* Gcrypt */
225         g_string_append(str, ", ");
226 #ifdef HAVE_LIBGCRYPT
227         g_string_append(str, "with Gcrypt " GCRYPT_VERSION);
228 #else
229         g_string_append(str, "without Gcrypt");
230 #endif /* HAVE_LIBGCRYPT */
231
232         /* Kerberos */
233         /* XXX - I don't see how to get the version number, at least for KfW */
234         g_string_append(str, ", ");
235 #ifdef HAVE_KERBEROS
236 #ifdef HAVE_MIT_KERBEROS
237         g_string_append(str, "with MIT Kerberos");
238 #else
239         /* HAVE_HEIMDAL_KERBEROS */
240         g_string_append(str, "with Heimdal Kerberos");
241 #endif
242 #else
243         g_string_append(str, "without Kerberos");
244 #endif /* HAVE_KERBEROS */
245 }
246
247 /*
248  * Get various library run-time versions, and the OS version, and append
249  * them to the specified GString.
250  */
251 void
252 get_runtime_version_info(GString *str, void (*additional_info)(GString *))
253 {
254 #if defined(_WIN32)
255         OSVERSIONINFO info;
256 #elif defined(HAVE_SYS_UTSNAME_H)
257         struct utsname name;
258 #endif
259
260         g_string_append(str, "on ");
261
262 #if defined(_WIN32)
263         /*
264          * See
265          *
266          *      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getting_the_system_version.asp
267          *
268          * for more than you ever wanted to know about determining the
269          * flavor of Windows on which you're running.  Implementing more
270          * of that is left as an exercise to the reader - who should
271          * check any copyright information about code samples on MSDN
272          * before cutting and pasting into Wireshark.
273          *
274          * They should also note that you need an OSVERSIONINFOEX structure
275          * to get some of that information, and that not only is that
276          * structure not supported on older versions of Windows, you might
277          * not even be able to compile code that *uses* that structure with
278          * older versions of the SDK.
279          */
280         info.dwOSVersionInfoSize = sizeof info;
281         if (!GetVersionEx(&info)) {
282                 /*
283                  * XXX - get the failure reason.
284                  */
285                 g_string_append(str, "unknown Windows version");
286                 return;
287         }
288         switch (info.dwPlatformId) {
289
290         case VER_PLATFORM_WIN32s:
291                 /* Shyeah, right. */
292                 g_string_sprintfa(str, "Windows 3.1 with Win32s");
293                 break;
294
295         case VER_PLATFORM_WIN32_WINDOWS:
296                 /* Windows OT */
297                 switch (info.dwMajorVersion) {
298
299                 case 4:
300                         /* 3 cheers for Microsoft marketing! */
301                         switch (info.dwMinorVersion) {
302
303                         case 0:
304                                 g_string_sprintfa(str, "Windows 95");
305                                 break;
306
307                         case 10:
308                                 g_string_sprintfa(str, "Windows 98");
309                                 break;
310
311                         case 90:
312                                 g_string_sprintfa(str, "Windows Me");
313                                 break;
314
315                         default:
316                                 g_string_sprintfa(str, "Windows OT, unknown version %lu.%lu",
317                                     info.dwMajorVersion, info.dwMinorVersion);
318                                 break;
319                         }
320                         break;
321
322                 default:
323                         g_string_sprintfa(str, "Windows OT, unknown version %lu.%lu",
324                             info.dwMajorVersion, info.dwMinorVersion);
325                         break;
326                 }
327                 break;
328
329         case VER_PLATFORM_WIN32_NT:
330                 /* Windows NT */
331                 switch (info.dwMajorVersion) {
332
333                 case 3:
334                 case 4:
335                         g_string_sprintfa(str, "Windows NT %lu.%lu",
336                             info.dwMajorVersion, info.dwMinorVersion);
337                         break;
338
339                 case 5:
340                         /* 3 cheers for Microsoft marketing! */
341                         switch (info.dwMinorVersion) {
342
343                         case 0:
344                                 g_string_sprintfa(str, "Windows 2000");
345                                 break;
346
347                         case 1:
348                                 g_string_sprintfa(str, "Windows XP");
349                                 break;
350
351                         case 2:
352                                 g_string_sprintfa(str, "Windows Server 2003");
353                                 break;
354
355                         default:
356                                 g_string_sprintfa(str, "Windows NT, unknown version %lu.%lu",
357                                     info.dwMajorVersion, info.dwMinorVersion);
358                                 break;
359                         }
360                         break;
361
362                 case 6:
363                         g_string_sprintfa(str, "Windows Vista");
364                         break;
365
366                 default:
367                         g_string_sprintfa(str, "Windows NT, unknown version %lu.%lu",
368                             info.dwMajorVersion, info.dwMinorVersion);
369                         break;
370                 }
371                 break;
372
373         default:
374                 g_string_sprintfa(str, "Unknown Windows platform %lu version %lu.%lu",
375                     info.dwPlatformId, info.dwMajorVersion, info.dwMinorVersion);
376                 break;
377         }
378         if (info.szCSDVersion[0] != '\0')
379                 g_string_sprintfa(str, " %s", utf_16to8(info.szCSDVersion));
380         g_string_sprintfa(str, ", build %lu", info.dwBuildNumber);
381 #elif defined(HAVE_SYS_UTSNAME_H)
382         /*
383          * We have <sys/utsname.h>, so we assume we have "uname()".
384          */
385         if (uname(&name) < 0) {
386                 g_string_sprintfa(str, "unknown OS version (uname failed - %s)",
387                     strerror(errno));
388                 return;
389         }
390
391         if (strcmp(name.sysname, "AIX") == 0) {
392                 /*
393                  * Yay, IBM!  Thanks for doing something different
394                  * from most of the other UNIXes out there, and
395                  * making "name.version" apparently be the major
396                  * version number and "name.release" be the minor
397                  * version number.
398                  */
399                 g_string_sprintfa(str, "%s %s.%s", name.sysname, name.version,
400                     name.release);
401         } else {
402                 /*
403                  * XXX - get "version" on any other platforms?
404                  *
405                  * On Digital/Tru65 UNIX, it's something unknown.
406                  * On Solaris, it's some kind of build information.
407                  * On HP-UX, it appears to be some sort of subrevision
408                  * thing.
409                  */
410                 g_string_sprintfa(str, "%s %s", name.sysname, name.release);
411         }
412 #else
413         g_string_append(str, "an unknown OS");
414 #endif
415
416         /* Libpcap */
417         g_string_append(str, ", ");
418         get_runtime_pcap_version(str);
419
420         /* Additional application-dependent information */
421         if (additional_info)
422                 (*additional_info)(str);
423
424         g_string_append(str, ".");
425
426         /* Compiler info */
427
428         /*
429          * See http://predef.sourceforge.net/precomp.html for
430          * information on various defined strings.
431          *
432          * GCC's __VERSION__ is a nice text string for humans to
433          * read.  The page at predef.sourceforge.net largely
434          * describes numeric #defines that encode the version;
435          * if the compiler doesn't also offer a nice printable
436          * string, we should probably prettify the number somehow.
437          */
438 #if defined(__GNUC__) && defined(__VERSION__)
439         g_string_sprintfa(str, "\n\nBuilt using gcc %s.\n", __VERSION__);
440 #elif defined(__HP_aCC)
441         g_string_sprintfa(str, "\n\nBuilt using HP aCC %d.\n", __HP_aCC);
442 #elif defined(__xlC__)
443         g_string_sprintfa(str, "\n\nBuilt using IBM XL C %d.%d\n",
444             (__xlC__ >> 8) & 0xFF, __xlC__ & 0xFF);
445 #ifdef __IBMC__
446         if ((__IBMC__ % 10) != 0)
447                 g_string_sprintfa(str, " patch %d", __IBMC__ % 10);
448 #endif /* __IBMC__ */
449         g_string_sprintfa(str, "\n");
450 #elif defined(__INTEL_COMPILER)
451         g_string_sprintfa(str, "\n\nBuilt using Intel C %d.%d",
452             __INTEL_COMPILER / 100, (__INTEL_COMPILER / 10) % 10);
453         if ((__INTEL_COMPILER % 10) != 0)
454                 g_string_sprintfa(str, " patch %d", __INTEL_COMPILER % 10);
455 #ifdef __INTEL_COMPILER_BUILD_DATE
456         g_string_sprinta(str, ", compiler built %04d-%02d-%02d",
457             __INTEL_COMPILER_BUILD_DATE / 10000,
458             (__INTEL_COMPILER_BUILD_DATE / 100) % 100,
459             __INTEL_COMPILER_BUILD_DATE % 100);
460 #endif /* __INTEL_COMPILER_BUILD_DATE */
461         g_string_sprintfa(str, "\n");
462 #elif defined(_MSC_FULL_VER)
463         if (_MSC_FULL_VER > 99999999) {
464                 g_string_sprintfa(str, "\n\nBuilt using Microsoft Visual C++ %d.%d",
465                     (_MSC_FULL_VER / 10000000) - 6,
466                     (_MSC_FULL_VER / 100000) % 100);
467                 if ((_MSC_FULL_VER % 100000) != 0)
468                         g_string_sprintfa(str, " build %d",
469                             _MSC_FULL_VER % 100000);
470         } else {
471                 g_string_sprintfa(str, "\n\nBuilt using Microsoft Visual C++ %d.%d",
472                     (_MSC_FULL_VER / 1000000) - 6,
473                     (_MSC_FULL_VER / 10000) % 100);
474                 if ((_MSC_FULL_VER % 10000) != 0)
475                         g_string_sprintfa(str, " build %d",
476                             _MSC_FULL_VER % 10000);
477         }
478         g_string_sprintfa(str, "\n");
479 #elif defined(_MSC_VER)
480         /* _MSC_FULL_VER not defined, but _MSC_VER defined */
481         g_string_sprintfa(str, "\n\nBuilt using Microsoft Visual C++ %d.%d\n",
482             (_MSC_VER / 100) - 6, _MSC_VER % 100);
483 #elif defined(__SUNPRO_C)
484         g_string_sprintfa(str, "\n\nBuilt using Sun C %d.%d",
485             (__SUNPRO_C >> 8) & 0xF, (__SUNPRO_C >> 4) & 0xF);
486         if ((__SUNPRO_C & 0xF) != 0)
487                 g_string_sprintfa(str, " patch %d", __SUNPRO_C & 0xF);
488         g_string_sprintfa(str, "\n");
489 #endif
490
491         end_string(str);
492 }
493
494 /*
495  * Get copyright information.
496  */
497 const char *
498 get_copyright_info(void)
499 {
500         return
501 "Copyright 1998-2007 Gerald Combs <gerald@wireshark.org> and contributors.\n"
502 "This is free software; see the source for copying conditions. There is NO\n"
503 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
504 }