pcap_compile(pcap_t *p, struct bpf_program *program,
const char *buf, int optimize, bpf_u_int32 mask)
{
-#ifdef _WIN32
- static int done = 0;
-#endif
compiler_state_t cstate;
const char * volatile xbuf = buf;
yyscan_t scanner = NULL;
return (PCAP_ERROR);
}
-#ifdef _WIN32
- if (!done) {
- pcap_wsockinit();
- done = 1;
+ if(0 != pcapint_sockinit()) {
+ return (PCAP_ERROR);
}
-#endif
#ifdef ENABLE_REMOTE
/*
*/
freechunks(&cstate);
+ pcapint_sockcleanup();
+
return (rc);
}
}
}
- /* Init Winsock if it hasn't already been initialized */
- pcap_wsockinit();
-
pw->adapter = PacketOpenAdapter(p->opt.device);
if (pw->adapter == NULL)
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP 3PCAP "4 March 2024"
+.TH PCAP 3PCAP "18 September 2024"
.SH NAME
pcap \- Packet Capture library
.SH SYNOPSIS
UTF-16LE string - note that this attempt is unsafe, as it may run past
the end of the string - to handle
.BR pcap_lookupdev ()
-returning a UTF-16LE string. Programs that don't call
-.BR pcap_init ()
-should, on Windows, call
-.BR pcap_wsockinit ()
-to initialize Winsock; this is not necessary if
-.BR pcap_init ()
-is called, as
-.BR pcap_init ()
-will initialize Winsock itself on Windows.
+returning a UTF-16LE string.
.TP
.B Routines
.RS
*
* So we don't initialize Winsock in a DllMain() routine.
*
- * pcap_init() should be called to initialize pcap on both UN*X and
- * Windows; it will initialize Winsock on Windows. (It will also be
- * initialized as needed if pcap_init() hasn't been called.)
+ * Similarly, we cannot register an atexit() handler to call WSACleanup()
+ * because that handler will be run in the context of DllMain. Therefore, we
+ * call WSAStartup each time Winsock is needed and WSACleanup as soon as it is
+ * no longer needed.
*/
/*
static int
internal_wsockinit(char *errbuf)
{
- WORD wVersionRequested;
- WSADATA wsaData;
- static int err = -1;
- static int done = 0;
- int status;
-
- if (done)
- return (err);
-
- /*
- * Versions of Windows that don't support Winsock 2.2 are
- * too old for us.
- */
- wVersionRequested = MAKEWORD(2, 2);
- status = WSAStartup(wVersionRequested, &wsaData);
- done = 1;
- if (status != 0) {
- if (errbuf != NULL) {
- pcapint_fmt_errmsg_for_win32_err(errbuf, PCAP_ERRBUF_SIZE,
- status, "WSAStartup() failed");
- }
- return (err);
- }
- atexit(internal_wsockfini);
- err = 0;
- return (err);
+ return 0;
}
/*
return (0);
}
-#ifdef _WIN32
- /*
- * Now set up Winsock.
- */
- if (internal_wsockinit(errbuf) == -1) {
- /* Failed. */
- return (PCAP_ERROR);
- }
-#endif
-
/*
* We're done.
*/
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.TH PCAP_INIT 3PCAP "30 November 2023"
+.TH PCAP_INIT 3PCAP "18 September 2024"
.SH NAME
pcap_init \- initialize the library
.SH SYNOPSIS
UTF-16LE string - note that this attempt is unsafe, as it may run past
the end of the string - to handle
.BR pcap_lookupdev ()
-returning a UTF-16LE string. Programs that don't call
-.BR pcap_init ()
-should, on Windows, call
-.BR pcap_wsockinit ()
-to initialize Winsock; this is not necessary if
-.BR pcap_init ()
-is called, as
-.BR pcap_init ()
-will initialize Winsock itself on Windows.
+returning a UTF-16LE string.
.SH RETURN VALUE
.BR pcap_init ()
returns
#if !defined(__cplusplus)
#define inline __inline
#endif
+#include <winsock2.h>
#endif /* _WIN32 */
+static inline int pcapint_sockinit(void)
+{
+#ifdef _WIN32
+ WSADATA wsaData;
+ return WSAStartup(MAKEWORD(2,2), &wsaData);
+#else
+ return 0;
+#endif /* _WIN32 */
+}
+
+static inline void pcapint_sockcleanup(void)
+{
+#ifdef _WIN32
+ WSACleanup();
+#endif /* _WIN32 */
+}
+
#ifdef __cplusplus
}
#endif
#include <stdlib.h>
#ifdef _WIN32
+/* Prevent inclusion of winsock.h, which causes redefinition errors when
+ * winsock2.h is included later */
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <syslog.h>
struct bpf_program fcode;
#ifdef _WIN32
- if (pcap_wsockinit() != 0)
+ WSADATA wsaData;
+ if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData))
return 1;
+ atexit ((void(*)(void))WSACleanup);
#endif /* _WIN32 */
dflag = 1;