mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Added interface to Windows' WSAIoctl and a simple example for a network sniffer.
This commit is contained in:
parent
951300e39f
commit
04ae916fa2
5 changed files with 953 additions and 865 deletions
|
@ -161,6 +161,14 @@ The module :mod:`socket` exports the following constants and functions:
|
||||||
in the Unix header files are defined; for a few symbols, default values are
|
in the Unix header files are defined; for a few symbols, default values are
|
||||||
provided.
|
provided.
|
||||||
|
|
||||||
|
.. data:: SIO_*
|
||||||
|
RCVALL_*
|
||||||
|
|
||||||
|
Constants for Windows' WSAIoctl(). The constants are used as arguments to the
|
||||||
|
:meth:`ioctl` method of socket objects.
|
||||||
|
|
||||||
|
.. versionadded:: 2.6
|
||||||
|
|
||||||
|
|
||||||
.. data:: has_ipv6
|
.. data:: has_ipv6
|
||||||
|
|
||||||
|
@ -551,6 +559,16 @@ correspond to Unix system calls applicable to sockets.
|
||||||
to decode C structures encoded as strings).
|
to decode C structures encoded as strings).
|
||||||
|
|
||||||
|
|
||||||
|
.. method:: socket.ioctl(control, option)
|
||||||
|
|
||||||
|
:platform: Windows
|
||||||
|
|
||||||
|
The `meth:ioctl` method is a limited interface to the WSAIoctl system
|
||||||
|
interface. Please refer to the MSDN documentation for more information.
|
||||||
|
|
||||||
|
.. versionadded:: 2.6
|
||||||
|
|
||||||
|
|
||||||
.. method:: socket.listen(backlog)
|
.. method:: socket.listen(backlog)
|
||||||
|
|
||||||
Listen for connections made to the socket. The *backlog* argument specifies the
|
Listen for connections made to the socket. The *backlog* argument specifies the
|
||||||
|
@ -861,3 +879,28 @@ sends traffic to the first one connected successfully. ::
|
||||||
s.close()
|
s.close()
|
||||||
print 'Received', repr(data)
|
print 'Received', repr(data)
|
||||||
|
|
||||||
|
|
||||||
|
The last example shows how to write a very simple network sniffer with raw
|
||||||
|
sockets on Windows. The example requires administrator priviliges to modify
|
||||||
|
the interface::
|
||||||
|
|
||||||
|
import socket
|
||||||
|
|
||||||
|
# the public network interface
|
||||||
|
HOST = socket.gethostbyname(socket.gethostname())
|
||||||
|
|
||||||
|
# create a raw socket and bind it to the public interface
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
|
||||||
|
s.bind((HOST, 0))
|
||||||
|
|
||||||
|
# Include IP headers
|
||||||
|
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
|
||||||
|
|
||||||
|
# receive all packages
|
||||||
|
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
|
||||||
|
|
||||||
|
# receive a package
|
||||||
|
print s.recvfrom(65565)
|
||||||
|
|
||||||
|
# disabled promiscous mode
|
||||||
|
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
|
||||||
|
|
|
@ -141,7 +141,7 @@ _socketmethods = (
|
||||||
'bind', 'connect', 'connect_ex', 'fileno', 'listen',
|
'bind', 'connect', 'connect_ex', 'fileno', 'listen',
|
||||||
'getpeername', 'getsockname', 'getsockopt', 'setsockopt',
|
'getpeername', 'getsockname', 'getsockopt', 'setsockopt',
|
||||||
'sendall', 'setblocking',
|
'sendall', 'setblocking',
|
||||||
'settimeout', 'gettimeout', 'shutdown')
|
'settimeout', 'gettimeout', 'shutdown', 'ioctl')
|
||||||
|
|
||||||
if sys.platform == "riscos":
|
if sys.platform == "riscos":
|
||||||
_socketmethods = _socketmethods + ('sleeptaskw',)
|
_socketmethods = _socketmethods + ('sleeptaskw',)
|
||||||
|
|
|
@ -920,6 +920,9 @@ Library
|
||||||
Extension Modules
|
Extension Modules
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Added interface for Windows' WSAIoctl to socket object and added an example
|
||||||
|
for a simple network sniffer.
|
||||||
|
|
||||||
- Bug #1301: Bad assert in _tkinter fixed.
|
- Bug #1301: Bad assert in _tkinter fixed.
|
||||||
|
|
||||||
- Added bdist_wininst executable for VS 2008.
|
- Added bdist_wininst executable for VS 2008.
|
||||||
|
|
|
@ -2687,6 +2687,31 @@ PyDoc_STRVAR(shutdown_doc,
|
||||||
Shut down the reading side of the socket (flag == SHUT_RD), the writing side\n\
|
Shut down the reading side of the socket (flag == SHUT_RD), the writing side\n\
|
||||||
of the socket (flag == SHUT_WR), or both ends (flag == SHUT_RDWR).");
|
of the socket (flag == SHUT_WR), or both ends (flag == SHUT_RDWR).");
|
||||||
|
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
static PyObject*
|
||||||
|
sock_ioctl(PySocketSockObject *s, PyObject *arg)
|
||||||
|
{
|
||||||
|
unsigned long cmd = SIO_RCVALL;
|
||||||
|
unsigned int option = RCVALL_ON;
|
||||||
|
DWORD recv;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(arg, "kI:ioctl", &cmd, &option))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (WSAIoctl(s->sock_fd, cmd, &option, sizeof(option),
|
||||||
|
NULL, 0, &recv, NULL, NULL) == SOCKET_ERROR) {
|
||||||
|
return set_error();
|
||||||
|
}
|
||||||
|
return PyLong_FromUnsignedLong(recv);
|
||||||
|
}
|
||||||
|
PyDoc_STRVAR(sock_ioctl_doc,
|
||||||
|
"ioctl(cmd, option) -> long\n\
|
||||||
|
\n\
|
||||||
|
Control the socket with WSAIoctl syscall. Currently only socket.SIO_RCVALL\n\
|
||||||
|
is supported as control. Options must be one of the socket.RCVALL_*\n\
|
||||||
|
constants.");
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* List of methods for socket objects */
|
/* List of methods for socket objects */
|
||||||
|
|
||||||
|
@ -2715,6 +2740,10 @@ static PyMethodDef sock_methods[] = {
|
||||||
METH_NOARGS, getsockname_doc},
|
METH_NOARGS, getsockname_doc},
|
||||||
{"getsockopt", (PyCFunction)sock_getsockopt, METH_VARARGS,
|
{"getsockopt", (PyCFunction)sock_getsockopt, METH_VARARGS,
|
||||||
getsockopt_doc},
|
getsockopt_doc},
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
{"ioctl", (PyCFunction)sock_ioctl, METH_VARARGS,
|
||||||
|
sock_ioctl_doc},
|
||||||
|
#endif
|
||||||
{"listen", (PyCFunction)sock_listen, METH_O,
|
{"listen", (PyCFunction)sock_listen, METH_O,
|
||||||
listen_doc},
|
listen_doc},
|
||||||
#ifndef NO_DUP
|
#ifndef NO_DUP
|
||||||
|
@ -4194,7 +4223,7 @@ See the socket module for documentation.");
|
||||||
PyMODINIT_FUNC
|
PyMODINIT_FUNC
|
||||||
init_socket(void)
|
init_socket(void)
|
||||||
{
|
{
|
||||||
PyObject *m, *has_ipv6;
|
PyObject *m, *has_ipv6, *tmp;
|
||||||
|
|
||||||
if (!os_init())
|
if (!os_init())
|
||||||
return;
|
return;
|
||||||
|
@ -5033,6 +5062,18 @@ init_socket(void)
|
||||||
PyModule_AddIntConstant(m, "SHUT_RDWR", 2);
|
PyModule_AddIntConstant(m, "SHUT_RDWR", 2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SIO_RCVALL
|
||||||
|
tmp = PyLong_FromUnsignedLong(SIO_RCVALL);
|
||||||
|
if (tmp == NULL)
|
||||||
|
return;
|
||||||
|
PyModule_AddObject(m, "SIO_RCVALL", tmp);
|
||||||
|
PyModule_AddIntConstant(m, "RCVALL_OFF", RCVALL_OFF);
|
||||||
|
PyModule_AddIntConstant(m, "RCVALL_ON", RCVALL_ON);
|
||||||
|
PyModule_AddIntConstant(m, "RCVALL_SOCKETLEVELONLY", RCVALL_SOCKETLEVELONLY);
|
||||||
|
PyModule_AddIntConstant(m, "RCVALL_IPLEVEL", RCVALL_IPLEVEL);
|
||||||
|
PyModule_AddIntConstant(m, "RCVALL_MAX", RCVALL_MAX);
|
||||||
|
#endif /* _MSTCPIP_ */
|
||||||
|
|
||||||
/* Initialize gethostbyname lock */
|
/* Initialize gethostbyname lock */
|
||||||
#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
|
#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
|
||||||
netdb_lock = PyThread_allocate_lock();
|
netdb_lock = PyThread_allocate_lock();
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#if _MSC_VER >= 1300
|
#if _MSC_VER >= 1300
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
# include <ws2tcpip.h>
|
# include <ws2tcpip.h>
|
||||||
|
# include <MSTcpIP.h> /* for SIO_RCVALL */
|
||||||
# define HAVE_ADDRINFO
|
# define HAVE_ADDRINFO
|
||||||
# define HAVE_SOCKADDR_STORAGE
|
# define HAVE_SOCKADDR_STORAGE
|
||||||
# define HAVE_GETADDRINFO
|
# define HAVE_GETADDRINFO
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue