"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "pcap-npf.c" between
libpcap-1.10.0.tar.gz and libpcap-1.10.1.tar.gz

About: libpcap is a packet filter library used by tools like tcpdump.

pcap-npf.c  (libpcap-1.10.0):pcap-npf.c  (libpcap-1.10.1)
skipping to change at line 546 skipping to change at line 546
* a copy of p->buffer, a copy of p->buflen, and the * a copy of p->buffer, a copy of p->buflen, and the
* actual number of bytes read returned from * actual number of bytes read returned from
* PacketReceivePacket(), none of which has to be * PacketReceivePacket(), none of which has to be
* retained from call to call, so we just keep one on * retained from call to call, so we just keep one on
* the stack. * the stack.
*/ */
PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize); PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) { if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
/* /*
* Did the device go away? * Did the device go away?
* If so, the error we get is ERROR_GEN_FAILURE. * If so, the error we get can either be
* ERROR_GEN_FAILURE or ERROR_DEVICE_REMOVED.
*/ */
DWORD errcode = GetLastError(); DWORD errcode = GetLastError();
if (errcode == ERROR_GEN_FAILURE) { if (errcode == ERROR_GEN_FAILURE ||
errcode == ERROR_DEVICE_REMOVED) {
/* /*
* The device on which we're capturing * The device on which we're capturing
* went away, or it became unusable * went away, or it became unusable
* by NPF due to a suspend/resume. * by NPF due to a suspend/resume.
* *
* ERROR_GEN_FAILURE comes from
* STATUS_UNSUCCESSFUL, as well as some
* other NT status codes that the Npcap
* driver is unlikely to return.
* XXX - hopefully no other error * XXX - hopefully no other error
* conditions are indicated by this. * conditions are indicated by this.
* *
* ERROR_DEVICE_REMOVED comes from
* STATUS_DEVICE_REMOVED.
*
* We report the Windows status code
* name and the corresponding NT status
* code name, for the benefit of attempts
* to debug cases where this error is
* reported when the device *wasn't*
* removed, either because it's not
* removable, it's removable but wasn't
* removed, or it's a device that doesn't
* correspond to a physical device.
*
* XXX - we really should return an * XXX - we really should return an
* appropriate error for that, but * appropriate error for that, but
* pcap_dispatch() etc. aren't * pcap_dispatch() etc. aren't
* documented as having error returns * documented as having error returns
* other than PCAP_ERROR or PCAP_ERROR_BREAK. * other than PCAP_ERROR or PCAP_ERROR_BREAK.
*/ */
const char *errcode_msg;
if (errcode == ERROR_GEN_FAILURE)
errcode_msg = "ERROR_GEN_FAILURE/STATUS_U
NSUCCESSFUL";
else
errcode_msg = "ERROR_DEVICE_REMOVED/STATU
S_DEVICE_REMOVED";
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"The interface disappeared"); "The interface disappeared (error code %s)",
errcode_msg);
} else { } else {
pcap_fmt_errmsg_for_win32_err(p->errbuf, pcap_fmt_errmsg_for_win32_err(p->errbuf,
PCAP_ERRBUF_SIZE, errcode, PCAP_ERRBUF_SIZE, errcode,
"PacketReceivePacket error"); "PacketReceivePacket error");
} }
return (PCAP_ERROR); return (PCAP_ERROR);
} }
cc = Packet.ulBytesReceived; cc = Packet.ulBytesReceived;
skipping to change at line 877 skipping to change at line 903
/* Send a packet to the network */ /* Send a packet to the network */
static int static int
pcap_inject_npf(pcap_t *p, const void *buf, int size) pcap_inject_npf(pcap_t *p, const void *buf, int size)
{ {
struct pcap_win *pw = p->priv; struct pcap_win *pw = p->priv;
PACKET pkt; PACKET pkt;
PacketInitPacket(&pkt, (PVOID)buf, size); PacketInitPacket(&pkt, (PVOID)buf, size);
if(PacketSendPacket(pw->adapter,&pkt,TRUE) == FALSE) { if(PacketSendPacket(pw->adapter,&pkt,TRUE) == FALSE) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPack pcap_fmt_errmsg_for_win32_err(p->errbuf, PCAP_ERRBUF_SIZE,
et failed"); GetLastError(), "send error: PacketSendPacket failed");
return (-1); return (-1);
} }
/* /*
* We assume it all got sent if "PacketSendPacket()" succeeded. * We assume it all got sent if "PacketSendPacket()" succeeded.
* "pcap_inject()" is expected to return the number of bytes * "pcap_inject()" is expected to return the number of bytes
* sent. * sent.
*/ */
return (size); return (size);
} }
skipping to change at line 915 skipping to change at line 942
static void static void
pcap_breakloop_npf(pcap_t *p) pcap_breakloop_npf(pcap_t *p)
{ {
pcap_breakloop_common(p); pcap_breakloop_common(p);
struct pcap_win *pw = p->priv; struct pcap_win *pw = p->priv;
/* XXX - what if this fails? */ /* XXX - what if this fails? */
SetEvent(PacketGetReadEvent(pw->adapter)); SetEvent(PacketGetReadEvent(pw->adapter));
} }
/*
* Vendor-specific error codes.
*
* These are NTSTATUS values:
*
* https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/87fb
a13e-bf06-450e-83b1-9241dc81e781
*
* with the "Customer" bit set. If a driver returns them, they are not
* mapped to Windows error values in userland; they're returned by
* GetLastError().
*
* Attempting to set non-promiscuous mode on a Microsoft Surface Pro's
* Mobile Broadband Adapter returns an error; that error can safely be
* ignored, as it's always in non-promiscuous mode.
*
* It is likely that there are other devices which throw spurious errors,
* at which point this will need refactoring to efficiently check against
* a list, but for now we can just check this one value.
*/
#define NPF_SURFACE_MOBILE_NONPROMISC 0xe00000bb
static int static int
pcap_activate_npf(pcap_t *p) pcap_activate_npf(pcap_t *p)
{ {
struct pcap_win *pw = p->priv; struct pcap_win *pw = p->priv;
NetType type; NetType type;
int res; int res;
int status = 0; int status = 0;
struct bpf_insn total_insn; struct bpf_insn total_insn;
struct bpf_program total_prog; struct bpf_program total_prog;
skipping to change at line 1178 skipping to change at line 1226
*/ */
if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
p->snapshot = MAXIMUM_SNAPLEN; p->snapshot = MAXIMUM_SNAPLEN;
/* Set promiscuous mode */ /* Set promiscuous mode */
if (p->opt.promisc) if (p->opt.promisc)
{ {
if (PacketSetHwFilter(pw->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) = = FALSE) if (PacketSetHwFilter(pw->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) = = FALSE)
{ {
pcap_fmt_errmsg_for_win32_err(p->errbuf, DWORD errcode = GetLastError();
PCAP_ERRBUF_SIZE, GetLastError(),
"failed to set hardware filter to promiscuous mode"); /*
goto bad; * Suppress spurious error generated by non-compiant
* MS Surface mobile adapters.
*
* If we knew that this meant "promiscuous mode
* isn't supported", we could add a "promiscuous
* mode isn't supported" error code and return
* that, but:
*
* 1) we don't know that it means that
* rather than meaning "we reject attempts
* to set the filter, even though the NDIS
* specifications say you shouldn't do that"
*
* and
*
* 2) other interface types that don't
* support promiscuous mode, at least
* on UN*Xes, just silently ignore
* attempts to set promiscuous mode
*
* and rejecting it with an error could disrupt
* attempts to capture, as many programs (tcpdump,
* *shark) default to promiscuous mode.
*/
if (errcode != NPF_SURFACE_MOBILE_NONPROMISC)
{
pcap_fmt_errmsg_for_win32_err(p->errbuf,
PCAP_ERRBUF_SIZE, errcode,
"failed to set hardware filter to promiscuous
mode");
goto bad;
}
} }
} }
else else
{ {
/* NDIS_PACKET_TYPE_ALL_LOCAL selects "All packets sent by instal /*
led * NDIS_PACKET_TYPE_ALL_LOCAL selects "All packets sent by
* protocols and all packets indicated by the NIC" but if no prot * installed protocols and all packets indicated by the NIC",
ocol * but if no protocol drivers (like TCP/IP) are installed,
* drivers (like TCP/IP) are installed, NDIS_PACKET_TYPE_DIRECTED * NDIS_PACKET_TYPE_DIRECTED, NDIS_PACKET_TYPE_BROADCAST,
, * and NDIS_PACKET_TYPE_MULTICAST are needed to capture
* NDIS_PACKET_TYPE_BROADCAST, and NDIS_PACKET_TYPE_MULTICAST are * incoming frames.
needed to
* capture incoming frames.
*/ */
if (PacketSetHwFilter(pw->adapter, if (PacketSetHwFilter(pw->adapter,
NDIS_PACKET_TYPE_ALL_LOCAL | NDIS_PACKET_TYPE_ALL_LOCAL |
NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_DIRECTED |
NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_BROADCAST |
NDIS_PACKET_TYPE_MULTICAST) == FALSE) NDIS_PACKET_TYPE_MULTICAST) == FALSE)
{ {
pcap_fmt_errmsg_for_win32_err(p->errbuf, DWORD errcode = GetLastError();
PCAP_ERRBUF_SIZE, GetLastError(),
"failed to set hardware filter to non-promiscuous mod /*
e"); * Suppress spurious error generated by non-compiant
goto bad; * MS Surface mobile adapters.
*/
if (errcode != NPF_SURFACE_MOBILE_NONPROMISC)
{
pcap_fmt_errmsg_for_win32_err(p->errbuf,
PCAP_ERRBUF_SIZE, errcode,
"failed to set hardware filter to non-promisc
uous mode");
goto bad;
}
} }
} }
/* Set the buffer size */ /* Set the buffer size */
p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE; p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE;
if(!(pw->adapter->Flags & INFO_FLAG_DAG_CARD)) if(!(pw->adapter->Flags & INFO_FLAG_DAG_CARD))
{ {
/* /*
* Traditional Adapter * Traditional Adapter
skipping to change at line 1511 skipping to change at line 1600
if (!PacketGetTimestampModes(adapter, modes)) { if (!PacketGetTimestampModes(adapter, modes)) {
pcap_fmt_errmsg_for_win32_err(ebuf, pcap_fmt_errmsg_for_win32_err(ebuf,
PCAP_ERRBUF_SIZE, GetLastError(), PCAP_ERRBUF_SIZE, GetLastError(),
"Error calling PacketGetTimestampModes"); "Error calling PacketGetTimestampModes");
free(modes); free(modes);
pcap_close(p); pcap_close(p);
return (NULL); return (NULL);
} }
if (modes[0] != num_ts_modes) { if (modes[0] != num_ts_modes) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, snprintf(ebuf, PCAP_ERRBUF_SIZE,
"First PacketGetTimestampModes() call gives % lu modes, second call gives %u modes", "First PacketGetTimestampModes() call gives % lu modes, second call gives %lu modes",
num_ts_modes, modes[0]); num_ts_modes, modes[0]);
free(modes); free(modes);
pcap_close(p); pcap_close(p);
return (NULL); return (NULL);
} }
if (num_ts_modes != 0) { if (num_ts_modes != 0) {
u_int num_ts_types; u_int num_ts_types;
/* /*
* Allocate a buffer big enough for * Allocate a buffer big enough for
 End of changes. 12 change blocks. 
24 lines changed or deleted 112 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)