summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pysnmp/carrier/asyncore/dgram/base.py7
-rw-r--r--pysnmp/carrier/sockmsg.py21
2 files changed, 28 insertions, 0 deletions
diff --git a/pysnmp/carrier/asyncore/dgram/base.py b/pysnmp/carrier/asyncore/dgram/base.py
index 274b1eba..4edae19b 100644
--- a/pysnmp/carrier/asyncore/dgram/base.py
+++ b/pysnmp/carrier/asyncore/dgram/base.py
@@ -75,8 +75,10 @@ class DgramSocketTransport(AbstractSocketTransport):
try:
if self.socket.family in (socket.AF_INET, socket.AF_INET6):
self.socket.setsockopt(socket.SOL_IP, socket.IP_PKTINFO, flag)
+
if self.socket.family == socket.AF_INET6:
self.socket.setsockopt(socket.SOL_IPV6, socket.IPV6_RECVPKTINFO, flag)
+
except socket.error:
raise error.CarrierError('setsockopt() for %s failed: %s' % (self.socket.family == socket.AF_INET6 and "IPV6_RECVPKTINFO" or "IP_PKTINFO", sys.exc_info()[1]))
@@ -96,8 +98,10 @@ class DgramSocketTransport(AbstractSocketTransport):
self.socket.setsockopt(
socket.SOL_IPV6, socket.IP_TRANSPARENT, flag
)
+
except socket.error:
raise error.CarrierError('setsockopt() for IP_TRANSPARENT failed: %s' % sys.exc_info()[1])
+
except OSError:
raise error.CarrierError('IP_TRANSPARENT socket option requires superusre previleges')
@@ -113,14 +117,17 @@ class DgramSocketTransport(AbstractSocketTransport):
def normalizeAddress(self, transportAddress):
if not isinstance(transportAddress, self.addressType):
transportAddress = self.addressType(transportAddress)
+
if not transportAddress.getLocalAddress():
transportAddress.setLocalAddress(self.getLocalAddress())
+
return transportAddress
def getLocalAddress(self):
# one evil OS does not seem to support getsockname() for DGRAM sockets
try:
return self.socket.getsockname()
+
except Exception:
return '0.0.0.0', 0
diff --git a/pysnmp/carrier/sockmsg.py b/pysnmp/carrier/sockmsg.py
index 0d79b2c7..0b21233b 100644
--- a/pysnmp/carrier/sockmsg.py
+++ b/pysnmp/carrier/sockmsg.py
@@ -17,6 +17,8 @@
#
import sys
+from pysnmp import debug
+
if sys.version_info[:2] < (3, 3):
# noinspection PyUnusedLocal
def getRecvFrom(addressType):
@@ -69,38 +71,57 @@ else:
def getRecvFrom(addressType):
+
def recvfrom(s, sz):
_to = None
+
data, ancdata, msg_flags, _from = s.recvmsg(sz, socket.CMSG_LEN(sz))
+
for anc in ancdata:
if anc[0] == socket.SOL_IP and anc[1] == socket.IP_PKTINFO:
addr = in_pktinfo.from_buffer_copy(anc[2])
addr = ipaddress.IPv4Address(memoryview(addr.ipi_addr).tobytes())
_to = (str(addr), s.getsockname()[1])
+ break
+
elif anc[0] == socket.SOL_IPV6 and anc[1] == socket.IPV6_PKTINFO:
addr = in6_pktinfo.from_buffer_copy(anc[2])
addr = ipaddress.ip_address(memoryview(addr.ipi6_addr).tobytes())
_to = (str(addr), s.getsockname()[1])
+ break
+
+ debug.logger & debug.flagIO and debug.logger(
+ 'recvfrom: received %d octets from %s to %s; '
+ 'iov blob %r' % (len(data), _from, _to, ancdata))
+
return data, addressType(_from).setLocalAddress(_to)
return recvfrom
def getSendTo(addressType):
+
def sendto(s, _data, _to):
ancdata = []
if type(_to) == addressType:
addr = ipaddress.ip_address(_to.getLocalAddress()[0])
+
else:
addr = ipaddress.ip_address(s.getsockname()[0])
+
if type(addr) == ipaddress.IPv4Address:
_f = in_pktinfo()
_f.ipi_spec_dst = in_addr.from_buffer_copy(addr.packed)
ancdata = [(socket.SOL_IP, socket.IP_PKTINFO, memoryview(_f).tobytes())]
+
elif s.family == socket.AF_INET6 and type(addr) == ipaddress.IPv6Address:
_f = in6_pktinfo()
_f.ipi6_addr = in6_addr.from_buffer_copy(addr.packed)
ancdata = [(socket.SOL_IPV6, socket.IPV6_PKTINFO, memoryview(_f).tobytes())]
+
+ debug.logger & debug.flagIO and debug.logger(
+ 'sendto: sending %d octets to %s; iov blob %r' % (len(data), _to, ancdata))
+
return s.sendmsg([_data], ancdata, 0, _to)
return sendto