~canonical-livepatch-dependencies/canonical-livepatch-service-dependencies/twisted

« back to all changes in this revision

Viewing changes to twisted/internet/test/_win32ifaces.py

  • Committer: Free Ekanayaka
  • Date: 2016-07-01 12:22:33 UTC
  • Revision ID: free.ekanayaka@canonical.com-20160701122233-nh55w514zwzoz1ip
Tags: upstream-16.2.0
ImportĀ upstreamĀ versionĀ 16.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) Twisted Matrix Laboratories.
 
2
# See LICENSE for details.
 
3
 
 
4
"""
 
5
Windows implementation of local network interface enumeration.
 
6
"""
 
7
 
 
8
from socket import socket, AF_INET6, SOCK_STREAM
 
9
from ctypes import (
 
10
    WinDLL, byref, create_string_buffer, c_int, c_void_p,
 
11
    POINTER, Structure, cast, string_at)
 
12
 
 
13
WS2_32 = WinDLL('ws2_32')
 
14
 
 
15
SOCKET = c_int
 
16
DWORD = c_int
 
17
LPVOID = c_void_p
 
18
LPSOCKADDR = c_void_p
 
19
LPWSAPROTOCOL_INFO = c_void_p
 
20
LPTSTR = c_void_p
 
21
LPDWORD = c_void_p
 
22
LPWSAOVERLAPPED = c_void_p
 
23
LPWSAOVERLAPPED_COMPLETION_ROUTINE = c_void_p
 
24
 
 
25
# http://msdn.microsoft.com/en-us/library/ms741621(v=VS.85).aspx
 
26
# int WSAIoctl(
 
27
#         __in   SOCKET s,
 
28
#         __in   DWORD dwIoControlCode,
 
29
#         __in   LPVOID lpvInBuffer,
 
30
#         __in   DWORD cbInBuffer,
 
31
#         __out  LPVOID lpvOutBuffer,
 
32
#         __in   DWORD cbOutBuffer,
 
33
#         __out  LPDWORD lpcbBytesReturned,
 
34
#         __in   LPWSAOVERLAPPED lpOverlapped,
 
35
#         __in   LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
 
36
#       );
 
37
WSAIoctl = WS2_32.WSAIoctl
 
38
WSAIoctl.argtypes = [
 
39
    SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD,
 
40
    LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE]
 
41
WSAIoctl.restype = c_int
 
42
 
 
43
# http://msdn.microsoft.com/en-us/library/ms741516(VS.85).aspx
 
44
# INT WSAAPI WSAAddressToString(
 
45
#         __in      LPSOCKADDR lpsaAddress,
 
46
#         __in      DWORD dwAddressLength,
 
47
#         __in_opt  LPWSAPROTOCOL_INFO lpProtocolInfo,
 
48
#         __inout   LPTSTR lpszAddressString,
 
49
#         __inout   LPDWORD lpdwAddressStringLength
 
50
#       );
 
51
WSAAddressToString = WS2_32.WSAAddressToStringA
 
52
WSAAddressToString.argtypes = [
 
53
    LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFO, LPTSTR, LPDWORD]
 
54
WSAAddressToString.restype = c_int
 
55
 
 
56
 
 
57
SIO_ADDRESS_LIST_QUERY = 0x48000016
 
58
WSAEFAULT = 10014
 
59
 
 
60
class SOCKET_ADDRESS(Structure):
 
61
    _fields_ = [('lpSockaddr', c_void_p),
 
62
                ('iSockaddrLength', c_int)]
 
63
 
 
64
 
 
65
 
 
66
def make_SAL(ln):
 
67
    class SOCKET_ADDRESS_LIST(Structure):
 
68
        _fields_ = [('iAddressCount', c_int),
 
69
                    ('Address', SOCKET_ADDRESS * ln)]
 
70
    return SOCKET_ADDRESS_LIST
 
71
 
 
72
 
 
73
 
 
74
def win32GetLinkLocalIPv6Addresses():
 
75
    """
 
76
    Return a list of strings in colon-hex format representing all the link local
 
77
    IPv6 addresses available on the system, as reported by
 
78
    I{WSAIoctl}/C{SIO_ADDRESS_LIST_QUERY}.
 
79
    """
 
80
    s = socket(AF_INET6, SOCK_STREAM)
 
81
    size = 4096
 
82
    retBytes = c_int()
 
83
    for i in range(2):
 
84
        buf = create_string_buffer(size)
 
85
        ret = WSAIoctl(
 
86
            s.fileno(),
 
87
            SIO_ADDRESS_LIST_QUERY, 0, 0, buf, size, byref(retBytes), 0, 0)
 
88
 
 
89
        # WSAIoctl might fail with WSAEFAULT, which means there was not enough
 
90
        # space in the buffer we gave it.  There's no way to check the errno
 
91
        # until Python 2.6, so we don't even try. :/ Maybe if retBytes is still
 
92
        # 0 another error happened, though.
 
93
        if ret and retBytes.value:
 
94
            size = retBytes.value
 
95
        else:
 
96
            break
 
97
 
 
98
    # If it failed, then we'll just have to give up.  Still no way to see why.
 
99
    if ret:
 
100
        raise RuntimeError("WSAIoctl failure")
 
101
 
 
102
    addrList = cast(buf, POINTER(make_SAL(0)))
 
103
    addrCount = addrList[0].iAddressCount
 
104
    addrList = cast(buf, POINTER(make_SAL(addrCount)))
 
105
 
 
106
    addressStringBufLength = 1024
 
107
    addressStringBuf = create_string_buffer(addressStringBufLength)
 
108
 
 
109
    retList = []
 
110
    for i in range(addrList[0].iAddressCount):
 
111
        retBytes.value = addressStringBufLength
 
112
        address = addrList[0].Address[i]
 
113
        ret = WSAAddressToString(
 
114
            address.lpSockaddr, address.iSockaddrLength, 0, addressStringBuf,
 
115
            byref(retBytes))
 
116
        if ret:
 
117
            raise RuntimeError("WSAAddressToString failure")
 
118
        retList.append(string_at(addressStringBuf))
 
119
    return [addr for addr in retList if '%' in addr]