Support for RPCAP features in GUI (from Boris Misenov, see Bug 1366)
[obnox/wireshark/wip.git] / capture-wpcap.c
1 /* capture-wpcap.c
2  * WinPcap-specific interfaces for capturing.  We load WinPcap at run
3  * time, so that we only need one Wireshark binary and one TShark binary
4  * for Windows, regardless of whether WinPcap is installed or not.
5  *
6  * $Id$
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 2001 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <stdio.h>
32 #include <glib.h>
33 #include <gmodule.h>
34
35 #ifdef HAVE_LIBPCAP
36 #include <pcap.h>
37 #endif
38
39 #include "capture-pcap-util.h"
40 #include "capture-pcap-util-int.h"
41
42 /* XXX - yes, I know, I should move cppmagic.h to a generic location. */
43 #include "tools/lemon/cppmagic.h"
44
45 #ifdef NEED_G_ASCII_STRCASECMP_H
46 #include "g_ascii_strcasecmp.h"
47 #endif
48
49
50 #define MAX_WIN_IF_NAME_LEN 511
51
52
53 gboolean has_wpcap = FALSE;
54
55 #ifdef HAVE_LIBPCAP
56
57 /*
58  * XXX - should we require at least WinPcap 3.1 both for building an
59  * for using Wireshark?
60  */
61
62 static char*   (*p_pcap_lookupdev) (char *);
63 static void    (*p_pcap_close) (pcap_t *);
64 static int     (*p_pcap_stats) (pcap_t *, struct pcap_stat *);
65 static int     (*p_pcap_dispatch) (pcap_t *, int, pcap_handler, guchar *);
66 static int     (*p_pcap_snapshot) (pcap_t *);
67 static int     (*p_pcap_datalink) (pcap_t *);
68 static int     (*p_pcap_setfilter) (pcap_t *, struct bpf_program *);
69 static char*   (*p_pcap_geterr) (pcap_t *);
70 static int     (*p_pcap_compile) (pcap_t *, struct bpf_program *, char *, int,
71                         bpf_u_int32);
72 #ifdef WPCAP_CONSTIFIED
73 static int     (*p_pcap_lookupnet) (const char *, bpf_u_int32 *, bpf_u_int32 *,
74                         char *);
75 static pcap_t* (*p_pcap_open_live) (const char *, int, int, int, char *);
76 #else
77 static int     (*p_pcap_lookupnet) (char *, bpf_u_int32 *, bpf_u_int32 *,
78                         char *);
79 static pcap_t* (*p_pcap_open_live) (char *, int, int, int, char *);
80 #endif
81 static int     (*p_pcap_loop) (pcap_t *, int, pcap_handler, guchar *);
82 static void    (*p_pcap_freecode) (struct bpf_program *);
83 #ifdef HAVE_PCAP_FINDALLDEVS
84 static int     (*p_pcap_findalldevs) (pcap_if_t **, char *);
85 static void    (*p_pcap_freealldevs) (pcap_if_t *);
86 #endif
87 #ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
88 static int (*p_pcap_datalink_name_to_val) (const char *);
89 #endif
90 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
91 static const char *(*p_pcap_datalink_val_to_name) (int);
92 #endif
93 #ifdef HAVE_PCAP_BREAKLOOP
94 static void    (*p_pcap_breakloop) (pcap_t *);
95 #endif
96 static const char *(*p_pcap_lib_version) (void);
97 static int     (*p_pcap_setbuff) (pcap_t *, int dim);
98 static int     (*p_pcap_next_ex) (pcap_t *, struct pcap_pkthdr **pkt_header, const u_char **pkt_data);
99 #ifdef HAVE_PCAP_REMOTE
100 static pcap_t* (*p_pcap_open) (const char *, int, int, int,
101                                struct pcap_rmtauth *, char *);
102 static int     (*p_pcap_findalldevs_ex) (char *, struct pcap_rmtauth *,
103                                          pcap_if_t **, char *);
104 static int     (*p_pcap_createsrcstr) (char *, int, const char *, const char *,
105                                        const char *, char *);
106 #endif
107 #ifdef HAVE_PCAP_SETSAMPLING
108 static struct pcap_samp* (*p_pcap_setsampling)(pcap_t *);
109 #endif
110
111 typedef struct {
112         const char      *name;
113         gpointer        *ptr;
114         gboolean        optional;
115 } symbol_table_t;
116
117 #define SYM(x, y)       { STRINGIFY(x) , (gpointer) &CONCAT(p_,x), y }
118
119 void
120 load_wpcap(void)
121 {
122
123         /* These are the symbols I need or want from Wpcap */
124         static const symbol_table_t     symbols[] = {
125                 SYM(pcap_lookupdev, FALSE),
126                 SYM(pcap_close, FALSE),
127                 SYM(pcap_stats, FALSE),
128                 SYM(pcap_dispatch, FALSE),
129                 SYM(pcap_snapshot, FALSE),
130                 SYM(pcap_datalink, FALSE),
131                 SYM(pcap_setfilter, FALSE),
132                 SYM(pcap_geterr, FALSE),
133                 SYM(pcap_compile, FALSE),
134                 SYM(pcap_lookupnet, FALSE),
135 #ifdef HAVE_PCAP_REMOTE
136                 SYM(pcap_open, FALSE),
137                 SYM(pcap_findalldevs_ex, FALSE),
138                 SYM(pcap_createsrcstr, FALSE),
139 #else
140                 SYM(pcap_open_live, FALSE),
141 #endif
142 #ifdef HAVE_PCAP_SETSAMPLING
143                 SYM(pcap_setsampling, TRUE),
144 #endif
145                 SYM(pcap_loop, FALSE),
146                 SYM(pcap_freecode, TRUE),
147 #ifdef HAVE_PCAP_FINDALLDEVS
148                 SYM(pcap_findalldevs, TRUE),
149                 SYM(pcap_freealldevs, TRUE),
150 #endif
151 #ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
152                 SYM(pcap_datalink_name_to_val, TRUE),
153 #endif
154 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
155                 SYM(pcap_datalink_val_to_name, TRUE),
156 #endif
157 #ifdef HAVE_PCAP_BREAKLOOP
158                 /*
159                  * We don't try to work around the lack of this at
160                  * run time; it's present in WinPcap 3.1, which is
161                  * the version we build with and ship with.
162                  */
163                 SYM(pcap_breakloop, FALSE),
164 #endif
165                 SYM(pcap_lib_version, TRUE),
166                 SYM(pcap_setbuff, TRUE),
167                 SYM(pcap_next_ex, TRUE),
168                 { NULL, NULL, FALSE }
169         };
170
171         GModule         *wh; /* wpcap handle */
172         const symbol_table_t    *sym;
173
174         wh = g_module_open("wpcap", 0);
175
176         if (!wh) {
177                 return;
178         }
179
180         sym = symbols;
181         while (sym->name) {
182                 if (!g_module_symbol(wh, sym->name, sym->ptr)) {
183                         if (sym->optional) {
184                                 /*
185                                  * We don't care if it's missing; we just
186                                  * don't use it.
187                                  */
188                                 *sym->ptr = NULL;
189                         } else {
190                                 /*
191                                  * We require this symbol.
192                                  */
193                                 return;
194                         }
195                 }
196                 sym++;
197         }
198
199
200         has_wpcap = TRUE;
201 }
202
203 char*
204 pcap_lookupdev (char *a)
205 {
206         g_assert(has_wpcap);
207         return p_pcap_lookupdev(a);
208 }
209
210 void
211 pcap_close(pcap_t *a)
212 {
213         g_assert(has_wpcap);
214         p_pcap_close(a);
215 }
216
217 int
218 pcap_stats(pcap_t *a, struct pcap_stat *b)
219 {
220         g_assert(has_wpcap);
221         return p_pcap_stats(a, b);
222 }
223
224 int
225 pcap_dispatch(pcap_t *a, int b, pcap_handler c, guchar *d)
226 {
227         g_assert(has_wpcap);
228         return p_pcap_dispatch(a, b, c, d);
229 }
230
231 int
232 pcap_snapshot(pcap_t *a)
233 {
234         g_assert(has_wpcap);
235         return p_pcap_snapshot(a);
236 }
237
238 int
239 pcap_datalink(pcap_t *a)
240 {
241         g_assert(has_wpcap);
242         return p_pcap_datalink(a);
243 }
244
245 int
246 pcap_setfilter(pcap_t *a, struct bpf_program *b)
247 {
248         g_assert(has_wpcap);
249         return p_pcap_setfilter(a, b);
250 }
251
252 char*
253 pcap_geterr(pcap_t *a)
254 {
255         g_assert(has_wpcap);
256         return p_pcap_geterr(a);
257 }
258
259 int
260 pcap_compile(pcap_t *a, struct bpf_program *b, char *c, int d,
261             bpf_u_int32 e)
262 {
263         g_assert(has_wpcap);
264         return p_pcap_compile(a, b, c, d, e);
265 }
266
267 int
268 #ifdef WPCAP_CONSTIFIED
269 pcap_lookupnet(const char *a, bpf_u_int32 *b, bpf_u_int32 *c, char *d)
270 #else
271 pcap_lookupnet(char *a, bpf_u_int32 *b, bpf_u_int32 *c, char *d)
272 #endif
273 {
274         g_assert(has_wpcap);
275         return p_pcap_lookupnet(a, b, c, d);
276 }
277
278 pcap_t*
279 #ifdef WPCAP_CONSTIFIED
280 pcap_open_live(const char *a, int b, int c, int d, char *e)
281 #else
282 pcap_open_live(char *a, int b, int c, int d, char *e)
283 #endif
284 {
285         g_assert(has_wpcap);
286         return p_pcap_open_live(a, b, c, d, e);
287 }
288
289 #ifdef HAVE_PCAP_REMOTE
290 pcap_t*
291 pcap_open(const char *a, int b, int c, int d, struct pcap_rmtauth *e, char *f)
292 {
293     g_assert(has_wpcap);
294     return p_pcap_open(a, b, c, d, e, f);
295 }
296
297 int
298 pcap_findalldevs_ex(char *a, struct pcap_rmtauth *b, pcap_if_t **c, char *d)
299 {
300     g_assert(has_wpcap);
301     return p_pcap_findalldevs_ex(a, b, c, d);
302 }
303
304 int
305 pcap_createsrcstr(char *a, int b, const char *c, const char *d, const char *e,
306                   char *f)
307 {
308     g_assert(has_wpcap);
309     return p_pcap_createsrcstr(a, b, c, d, e, f);
310 }
311 #endif
312
313 #ifdef HAVE_PCAP_SETSAMPLING
314 struct pcap_samp *
315 pcap_setsampling(pcap_t *a)
316 {
317     g_assert(has_wpcap);
318     if (p_pcap_setsampling != NULL) {
319         return p_pcap_setsampling(a);
320     }
321     return NULL;
322 }
323 #endif
324
325 int
326 pcap_loop(pcap_t *a, int b, pcap_handler c, guchar *d)
327 {
328         g_assert(has_wpcap);
329         return p_pcap_loop(a, b, c, d);
330 }
331
332 void
333 pcap_freecode(struct bpf_program *a)
334 {
335         g_assert(has_wpcap);
336     if(p_pcap_freecode) {
337             p_pcap_freecode(a);
338     }
339 }
340
341 #ifdef HAVE_PCAP_FINDALLDEVS
342 int
343 pcap_findalldevs(pcap_if_t **a, char *b)
344 {
345         g_assert(has_wpcap && p_pcap_findalldevs != NULL);
346         return p_pcap_findalldevs(a, b);
347 }
348
349 void
350 pcap_freealldevs(pcap_if_t *a)
351 {
352         g_assert(has_wpcap && p_pcap_freealldevs != NULL);
353         p_pcap_freealldevs(a);
354 }
355 #endif
356
357 #if defined(HAVE_PCAP_DATALINK_NAME_TO_VAL) || defined(HAVE_PCAP_DATALINK_VAL_TO_NAME)
358 /*
359  * Table of DLT_ types, names, and descriptions, for use if the version
360  * of WinPcap we have installed lacks "pcap_datalink_name_to_val()"
361  * or "pcap_datalink_val_to_name()".
362  */
363 struct dlt_choice {
364         const char *name;
365         const char *description;
366         int     dlt;
367 };
368
369 #define DLT_CHOICE(code, description) { #code, description, code }
370 #define DLT_CHOICE_SENTINEL { NULL, NULL, 0 }
371
372 static struct dlt_choice dlt_choices[] = {
373         DLT_CHOICE(DLT_NULL, "BSD loopback"),
374         DLT_CHOICE(DLT_EN10MB, "Ethernet"),
375         DLT_CHOICE(DLT_IEEE802, "Token ring"),
376         DLT_CHOICE(DLT_ARCNET, "ARCNET"),
377         DLT_CHOICE(DLT_SLIP, "SLIP"),
378         DLT_CHOICE(DLT_PPP, "PPP"),
379         DLT_CHOICE(DLT_FDDI, "FDDI"),
380         DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 IP-over-ATM"),
381         DLT_CHOICE(DLT_RAW, "Raw IP"),
382 #ifdef DLT_SLIP_BSDOS
383         DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"),
384 #endif
385 #ifdef DLT_PPP_BSDOS
386         DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"),
387 #endif
388 #ifdef DLT_ATM_CLIP
389         DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"),
390 #endif
391 #ifdef DLT_PPP_SERIAL
392         DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"),
393 #endif
394 #ifdef DLT_PPP_ETHER
395         DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"),
396 #endif
397 #ifdef DLT_C_HDLC
398         DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"),
399 #endif
400 #ifdef DLT_IEEE802_11
401         DLT_CHOICE(DLT_IEEE802_11, "802.11"),
402 #endif
403 #ifdef DLT_FRELAY
404         DLT_CHOICE(DLT_FRELAY, "Frame Relay"),
405 #endif
406 #ifdef DLT_LOOP
407         DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"),
408 #endif
409 #ifdef DLT_ENC
410         DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"),
411 #endif
412 #ifdef DLT_LINUX_SLL
413         DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"),
414 #endif
415 #ifdef DLT_LTALK
416         DLT_CHOICE(DLT_LTALK, "Localtalk"),
417 #endif
418 #ifdef DLT_PFLOG
419         DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"),
420 #endif
421 #ifdef DLT_PRISM_HEADER
422         DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"),
423 #endif
424 #ifdef DLT_IP_OVER_FC
425         DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"),
426 #endif
427 #ifdef DLT_SUNATM
428         DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"),
429 #endif
430 #ifdef DLT_IEEE802_11_RADIO
431         DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus radio information header"),
432 #endif
433 #ifdef DLT_ARCNET_LINUX
434         DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"),
435 #endif
436 #ifdef DLT_LINUX_IRDA
437         DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
438 #endif
439 #ifdef DLT_LINUX_LAPD
440         DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"),
441 #endif
442 #ifdef DLT_LANE8023
443         DLT_CHOICE(DLT_LANE8023, "Linux 802.3 LANE"),
444 #endif
445 #ifdef DLT_CIP
446         DLT_CHOICE(DLT_CIP, "Linux Classical IP-over-ATM"),
447 #endif
448 #ifdef DLT_HDLC
449         DLT_CHOICE(DLT_HDLC, "Cisco HDLC"),
450 #endif
451         DLT_CHOICE_SENTINEL
452 };
453 #endif /* defined(HAVE_PCAP_DATALINK_NAME_TO_VAL) || defined(HAVE_PCAP_DATALINK_VAL_TO_NAME) */
454
455 #ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
456 int
457 pcap_datalink_name_to_val(const char *name)
458 {
459         int i;
460
461         g_assert(has_wpcap);
462
463         if (p_pcap_datalink_name_to_val != NULL)
464                 return p_pcap_datalink_name_to_val(name);
465         else {
466                 /*
467                  * We don't have it in WinPcap; do it ourselves.
468                  */
469                 for (i = 0; dlt_choices[i].name != NULL; i++) {
470                         if (g_ascii_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1,
471                             name) == 0)
472                                 return dlt_choices[i].dlt;
473                 }
474                 return -1;
475         }
476 }
477 #endif
478
479 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
480 const char *
481 pcap_datalink_val_to_name(int dlt)
482 {
483         int i;
484
485         g_assert(has_wpcap);
486
487         if (p_pcap_datalink_val_to_name != NULL)
488                 return p_pcap_datalink_val_to_name(dlt);
489         else {
490                 /*
491                  * We don't have it in WinPcap; do it ourselves.
492                  */
493                 for (i = 0; dlt_choices[i].name != NULL; i++) {
494                         if (dlt_choices[i].dlt == dlt)
495                                 return dlt_choices[i].name + sizeof("DLT_") - 1;
496                 }
497                 return NULL;
498         }
499 }
500 #endif
501
502 #ifdef HAVE_PCAP_BREAKLOOP
503 void pcap_breakloop(pcap_t *a)
504 {
505         p_pcap_breakloop(a);
506 }
507 #endif
508
509 /* setbuff is win32 specific! */
510 int pcap_setbuff(pcap_t *a, int b)
511 {
512         g_assert(has_wpcap);
513         return p_pcap_setbuff(a, b);
514 }
515
516 /* pcap_next_ex is available since libpcap 0.8 / WinPcap 3.0! */
517 /* (if you get a declaration warning here, try to update to at least WinPcap 3.1b4 develpack) */
518 int pcap_next_ex (pcap_t *a, struct pcap_pkthdr **b, const u_char **c)
519 {
520         g_assert(has_wpcap);
521         return p_pcap_next_ex(a, b, c);
522 }
523
524 #ifdef HAVE_PCAP_REMOTE
525 GList *
526 get_remote_interface_list(const char *hostname, const char *port,
527                           int auth_type, const char *username,
528                           const char *passwd, int *err, char **err_str)
529 {
530     struct pcap_rmtauth auth;
531     char source[PCAP_BUF_SIZE];
532     char errbuf[PCAP_ERRBUF_SIZE];
533     GList *result;
534
535     if (pcap_createsrcstr(source, PCAP_SRC_IFREMOTE, hostname, port,
536                           NULL, errbuf) == -1) {
537         *err = CANT_GET_INTERFACE_LIST;
538         if (err_str != NULL)
539             *err_str = cant_get_if_list_error_message(errbuf);
540         return NULL;
541     }
542
543     auth.type = auth_type;
544     auth.username = g_strdup(username);
545     auth.password = g_strdup(passwd);
546
547     result = get_interface_list_findalldevs_ex(source, &auth, err, err_str);
548     g_free(auth.username);
549     g_free(auth.password);
550
551     return result;
552 }
553 #endif
554
555 /*
556  * This will use "pcap_findalldevs()" if we have it, otherwise it'll
557  * fall back on "pcap_lookupdev()".
558  */
559 GList *
560 get_interface_list(int *err, char **err_str)
561 {
562 #ifdef HAVE_PCAP_REMOTE
563         char source[PCAP_BUF_SIZE];
564 #else
565         GList  *il = NULL;
566         wchar_t *names;
567         char *win95names;
568         char ascii_name[MAX_WIN_IF_NAME_LEN + 1];
569         char ascii_desc[MAX_WIN_IF_NAME_LEN + 1];
570         int i, j;
571 #endif
572         char errbuf[PCAP_ERRBUF_SIZE];
573
574 #ifdef HAVE_PCAP_REMOTE
575     if (p_pcap_createsrcstr(source, PCAP_SRC_IFLOCAL, NULL, NULL,
576                             NULL, errbuf) == -1) {
577         *err = CANT_GET_INTERFACE_LIST;
578         if (err_str != NULL)
579             *err_str = cant_get_if_list_error_message(errbuf);
580         return NULL;
581     }
582     return get_interface_list_findalldevs_ex(source, NULL, err, err_str);
583 #else
584
585 #ifdef HAVE_PCAP_FINDALLDEVS
586         if (p_pcap_findalldevs != NULL)
587                 return get_interface_list_findalldevs(err, err_str);
588 #endif
589
590         /*
591          * In WinPcap, pcap_lookupdev is implemented by calling
592          * PacketGetAdapterNames.  According to the documentation
593          * I could find:
594          *
595          *      http://www.winpcap.org/docs/man/html/Packet32_8c.html#a43
596          *
597          * this means that:
598          *
599          * On Windows OT (95, 98, Me), pcap_lookupdev returns a sequence
600          * of bytes consisting of:
601          *
602          *      a sequence of null-terminated ASCII strings (i.e., each
603          *      one is terminated by a single 0 byte), giving the names
604          *      of the interfaces;
605          *
606          *      an empty ASCII string (i.e., a single 0 byte);
607          *
608          *      a sequence of null-terminated ASCII strings, giving the
609          *      descriptions of the interfaces;
610          *
611          *      an empty ASCII string.
612          *
613          * On Windows NT (NT 4.0, W2K, WXP, W2K3, etc.), pcap_lookupdev
614          * returns a sequence of bytes consisting of:
615          *
616          *      a sequence of null-terminated double-byte Unicode strings
617          *      (i.e., each one consits of a sequence of double-byte
618          *      characters, terminated by a double-byte 0), giving the
619          *      names of the interfaces;
620          *
621          *      an empty Unicode string (i.e., a double 0 byte);
622          *
623          *      a sequence of null-terminated ASCII strings, giving the
624          *      descriptions of the interfaces;
625          *
626          *      an empty ASCII string.
627          *
628          * The Nth string in the first sequence is the name of the Nth
629          * adapter; the Nth string in the second sequence is the
630          * description of the Nth adapter.
631          */
632
633         names = (wchar_t *)pcap_lookupdev(errbuf);
634         i = 0;
635
636         if (names) {
637                 char* desc = 0;
638                 int desc_pos = 0;
639
640                 if (names[0]<256) {
641                         /*
642                          * If names[0] is less than 256 it means the first
643                          * byte is 0.  This implies that we are using Unicode
644                          * characters.
645                          */
646                         while (*(names+desc_pos) || *(names+desc_pos-1))
647                                 desc_pos++;
648                         desc_pos++;     /* Step over the extra '\0' */
649                         desc = (char*)(names + desc_pos); /* cast *after* addition */
650
651                         while (names[i] != 0) {
652                                 /*
653                                  * Copy the Unicode description to an ASCII
654                                  * string.
655                                  */
656                                 j = 0;
657                                 while (*desc != 0) {
658                                         if (j < MAX_WIN_IF_NAME_LEN)
659                                                 ascii_desc[j++] = *desc;
660                                         desc++;
661                                 }
662                                 ascii_desc[j] = '\0';
663                                 desc++;
664
665                                 /*
666                                  * Copy the Unicode name to an ASCII string.
667                                  */
668                                 j = 0;
669                                 while (names[i] != 0) {
670                                         if (j < MAX_WIN_IF_NAME_LEN)
671                                         ascii_name[j++] = (char) names[i++];
672                                 }
673                                 ascii_name[j] = '\0';
674                                 i++;
675                                 il = g_list_append(il,
676                                     if_info_new(ascii_name, ascii_desc));
677                         }
678                 } else {
679                         /*
680                          * Otherwise we are in Windows 95/98 and using ASCII
681                          * (8-bit) characters.
682                          */
683                         win95names=(char *)names;
684                         while (*(win95names+desc_pos) || *(win95names+desc_pos-1))
685                                 desc_pos++;
686                         desc_pos++;     /* Step over the extra '\0' */
687                         desc = win95names + desc_pos;
688
689                         while (win95names[i] != '\0') {
690                                 /*
691                                  * "&win95names[i]" points to the current
692                                  * interface name, and "desc" points to
693                                  * that interface's description.
694                                  */
695                                 il = g_list_append(il,
696                                     if_info_new(&win95names[i], desc));
697
698                                 /*
699                                  * Skip to the next description.
700                                  */
701                                 while (*desc != 0)
702                                         desc++;
703                                 desc++;
704
705                                 /*
706                                  * Skip to the next name.
707                                  */
708                                 while (win95names[i] != 0)
709                                         i++;
710                                 i++;
711                         }
712                 }
713         }
714
715         if (il == NULL) {
716                 /*
717                  * No interfaces found.
718                  */
719                 *err = NO_INTERFACES_FOUND;
720                 if (err_str != NULL)
721                         *err_str = NULL;
722         }
723
724         return il;
725 #endif  /* HAVE_PCAP_REMOTE */
726 }
727
728 /*
729  * Get an error message string for a CANT_GET_INTERFACE_LIST error from
730  * "get_interface_list()".
731  */
732 gchar *
733 cant_get_if_list_error_message(const char *err_str)
734 {
735         /*
736          * If the error message includes "Not enough storage is available
737          * to process this command" or "The operation completed successfully",
738          * suggest that they install a WinPcap version later than 3.0.
739          */
740         if (strstr(err_str, "Not enough storage is available to process this command") != NULL ||
741             strstr(err_str, "The operation completed successfully") != NULL) {
742                 return g_strdup_printf("Can't get list of interfaces: %s\n"
743 "This might be a problem with WinPcap 3.0; you should try updating to\n"
744 "a later version of WinPcap - see the WinPcap site at www.winpcap.org",
745                     err_str);
746         }
747         return g_strdup_printf("Can't get list of interfaces: %s", err_str);
748 }
749
750 /*
751  * Append the version of WinPcap with which we were compiled to a GString.
752  */
753 void
754 get_compiled_pcap_version(GString *str)
755 {
756         g_string_append(str, "with WinPcap (version unknown)");
757 }
758
759 /*
760  * Append the version of WinPcap with which we we're running to a GString.
761  */
762 void
763 get_runtime_pcap_version(GString *str)
764 {
765         /*
766          * On Windows, we might have been compiled with WinPcap but
767          * might not have it loaded; indicate whether we have it or
768          * not and, if we have it and we have "pcap_lib_version()",
769          * what version we have.
770          */
771         GModule *handle;                /* handle returned by dlopen */
772         static gchar *packetVer;
773         gchar *blankp;
774
775         if (has_wpcap) {
776                 g_string_sprintfa(str, "with ");
777                 if (p_pcap_lib_version != NULL)
778                         g_string_sprintfa(str, p_pcap_lib_version());
779                 else {
780                         /*
781                          * An alternative method of obtaining the version
782                          * number, by using the PacketLibraryVersion
783                          * string from packet.dll.
784                          *
785                          * Unfortunately, in WinPcap 3.0, it returns
786                          * "3.0 alpha3", even in the final version of
787                          * WinPcap 3.0, so if there's a blank in the
788                          * string, we strip it and everything after
789                          * it from the string, so we don't misleadingly
790                          * report that 3.0 alpha3 is being used when
791                          * the final version is being used.
792                          */
793                         if (packetVer == NULL) {
794                                 packetVer = "version unknown";
795                                 handle = g_module_open("Packet.dll", 0);
796                                 if (handle != NULL) {
797                                         if (g_module_symbol(handle,
798                                             "PacketLibraryVersion",
799                                             (gpointer*)&packetVer)) {
800                                                 packetVer = g_strdup(packetVer);
801                                                 blankp = strchr(packetVer, ' ');
802                                                 if (blankp != NULL)
803                                                         *blankp = '\0';
804                                         } else {
805                                                 packetVer = "version unknown";
806                                         }
807                                         g_module_close(handle);
808                                 }
809                         }
810                         g_string_sprintfa(str, "WinPcap (%s)", packetVer);
811                 }
812         } else
813                 g_string_append(str, "without WinPcap");
814 }
815
816 #else /* HAVE_LIBPCAP */
817
818 void
819 load_wpcap(void)
820 {
821         return;
822 }
823
824 /*
825  * Append an indication that we were not compiled with WinPcap
826  * to a GString.
827  */
828 void
829 get_compiled_pcap_version(GString *str)
830 {
831         g_string_append(str, "without WinPcap");
832 }
833
834 /*
835  * Don't append anything, as we weren't even compiled to use WinPcap.
836  */
837 void
838 get_runtime_pcap_version(GString *str _U_)
839 {
840 }
841
842 #endif /* HAVE_LIBPCAP */