summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/base/inet.cc67
-rw-r--r--src/base/inet.hh59
-rw-r--r--src/python/m5/params.py158
-rw-r--r--src/python/m5/util/convert.py49
-rw-r--r--src/python/swig/inet.i19
5 files changed, 352 insertions, 0 deletions
diff --git a/src/base/inet.cc b/src/base/inet.cc
index 1a280e993..93501018e 100644
--- a/src/base/inet.cc
+++ b/src/base/inet.cc
@@ -117,6 +117,73 @@ operator<<(ostream &stream, const EthAddr &ea)
return stream;
}
+string
+IpAddress::string() const
+{
+ stringstream stream;
+ stream << *this;
+ return stream.str();
+}
+
+bool
+operator==(const IpAddress &left, const IpAddress &right)
+{
+ return left.ip() == right.ip();
+}
+
+ostream &
+operator<<(ostream &stream, const IpAddress &ia)
+{
+ uint32_t ip = ia.ip();
+ ccprintf(stream, "%x.%x.%x.%x",
+ (uint8_t)(ip >> 0), (uint8_t)(ip >> 8),
+ (uint8_t)(ip >> 16), (uint8_t)(ip >> 24));
+ return stream;
+}
+
+string
+IpNetmask::string() const
+{
+ stringstream stream;
+ stream << *this;
+ return stream.str();
+}
+
+bool
+operator==(const IpNetmask &left, const IpNetmask &right)
+{
+ return (left.ip() == right.ip()) &&
+ (left.netmask() == right.netmask());
+}
+
+ostream &
+operator<<(ostream &stream, const IpNetmask &in)
+{
+ ccprintf(stream, "%s/%d", (const IpAddress &)in, in.netmask());
+ return stream;
+}
+
+string
+IpWithPort::string() const
+{
+ stringstream stream;
+ stream << *this;
+ return stream.str();
+}
+
+bool
+operator==(const IpWithPort &left, const IpWithPort &right)
+{
+ return (left.ip() == right.ip()) && (left.port() == right.port());
+}
+
+ostream &
+operator<<(ostream &stream, const IpWithPort &iwp)
+{
+ ccprintf(stream, "%s:%d", (const IpAddress &)iwp, iwp.port());
+ return stream;
+}
+
uint16_t
cksum(const IpPtr &ptr)
{
diff --git a/src/base/inet.hh b/src/base/inet.hh
index ef9a7d81c..12387087b 100644
--- a/src/base/inet.hh
+++ b/src/base/inet.hh
@@ -147,6 +147,65 @@ class EthPtr
/*
* IP Stuff
*/
+struct IpAddress
+{
+ protected:
+ uint32_t _ip;
+
+ public:
+ IpAddress() : _ip(0)
+ {}
+ IpAddress(const uint32_t __ip) : _ip(__ip)
+ {}
+
+ uint32_t ip() const { return _ip; }
+
+ std::string string() const;
+};
+
+std::ostream &operator<<(std::ostream &stream, const IpAddress &ia);
+bool operator==(const IpAddress &left, const IpAddress &right);
+
+struct IpNetmask : public IpAddress
+{
+ protected:
+ uint8_t _netmask;
+
+ public:
+ IpNetmask() : IpAddress(), _netmask(0)
+ {}
+ IpNetmask(const uint32_t __ip, const uint8_t __netmask) :
+ IpAddress(__ip), _netmask(__netmask)
+ {}
+
+ uint8_t netmask() const { return _netmask; }
+
+ std::string string() const;
+};
+
+std::ostream &operator<<(std::ostream &stream, const IpNetmask &in);
+bool operator==(const IpNetmask &left, const IpNetmask &right);
+
+struct IpWithPort : public IpAddress
+{
+ protected:
+ uint16_t _port;
+
+ public:
+ IpWithPort() : IpAddress(), _port(0)
+ {}
+ IpWithPort(const uint32_t __ip, const uint16_t __port) :
+ IpAddress(__ip), _port(__port)
+ {}
+
+ uint8_t port() const { return _port; }
+
+ std::string string() const;
+};
+
+std::ostream &operator<<(std::ostream &stream, const IpWithPort &iwp);
+bool operator==(const IpWithPort &left, const IpWithPort &right);
+
struct IpOpt;
struct IpHdr : public ip_hdr
{
diff --git a/src/python/m5/params.py b/src/python/m5/params.py
index 33ac742c8..4e646d3f5 100644
--- a/src/python/m5/params.py
+++ b/src/python/m5/params.py
@@ -675,6 +675,163 @@ class EthernetAddr(ParamValue):
def ini_str(self):
return self.value
+# When initializing an IpAddress, pass in an existing IpAddress, a string of
+# the form "a.b.c.d", or an integer representing an IP.
+class IpAddress(ParamValue):
+ cxx_type = 'Net::IpAddress'
+
+ @classmethod
+ def cxx_predecls(cls, code):
+ code('#include "base/inet.hh"')
+
+ @classmethod
+ def swig_predecls(cls, code):
+ code('%include "python/swig/inet.i"')
+
+ def __init__(self, value):
+ if isinstance(value, IpAddress):
+ self.ip = value.ip
+ else:
+ try:
+ self.ip = convert.toIpAddress(value)
+ except TypeError:
+ self.ip = long(value)
+ self.verifyIp()
+
+ def verifyIp(self):
+ if self.ip < 0 or self.ip >= (1 << 32):
+ raise TypeError, "invalid ip address %#08x" % ip
+
+ def getValue(self):
+ from m5.internal.params import IpAddress
+ return IpAddress(self.ip)
+
+ def ini_str(self):
+ return self.ip
+
+# When initializing an IpNetmask, pass in an existing IpNetmask, a string of
+# the form "a.b.c.d/n" or "a.b.c.d/e.f.g.h", or an ip and netmask as
+# positional or keyword arguments.
+class IpNetmask(IpAddress):
+ cxx_type = 'Net::IpNetmask'
+
+ @classmethod
+ def cxx_predecls(cls, code):
+ code('#include "base/inet.hh"')
+
+ @classmethod
+ def swig_predecls(cls, code):
+ code('%include "python/swig/inet.i"')
+
+ def __init__(self, *args, **kwargs):
+ def handle_kwarg(self, kwargs, key, elseVal = None):
+ if key in kwargs:
+ setattr(self, key, kwargs.pop(key))
+ elif elseVal:
+ setattr(self, key, elseVal)
+ else:
+ raise TypeError, "No value set for %s" % key
+
+ if len(args) == 0:
+ handle_kwarg(self, kwargs, 'ip')
+ handle_kwarg(self, kwargs, 'netmask')
+
+ elif len(args) == 1:
+ if kwargs:
+ if not 'ip' in kwargs and not 'netmask' in kwargs:
+ raise TypeError, "Invalid arguments"
+ handle_kwarg(self, kwargs, 'ip', args[0])
+ handle_kwarg(self, kwargs, 'netmask', args[0])
+ elif isinstance(args[0], IpNetmask):
+ self.ip = args[0].ip
+ self.netmask = args[0].netmask
+ else:
+ (self.ip, self.netmask) = convert.toIpNetmask(args[0])
+
+ elif len(args) == 2:
+ self.ip = args[0]
+ self.netmask = args[1]
+ else:
+ raise TypeError, "Too many arguments specified"
+
+ if kwargs:
+ raise TypeError, "Too many keywords: %s" % kwargs.keys()
+
+ self.verify()
+
+ def verify(self):
+ self.verifyIp()
+ if self.netmask < 0 or self.netmask > 32:
+ raise TypeError, "invalid netmask %d" % netmask
+
+ def getValue(self):
+ from m5.internal.params import IpNetmask
+ return IpNetmask(self.ip, self.netmask)
+
+ def ini_str(self):
+ return "%08x/%d" % (self.ip, self.netmask)
+
+# When initializing an IpWithPort, pass in an existing IpWithPort, a string of
+# the form "a.b.c.d:p", or an ip and port as positional or keyword arguments.
+class IpWithPort(IpAddress):
+ cxx_type = 'Net::IpWithPort'
+
+ @classmethod
+ def cxx_predecls(cls, code):
+ code('#include "base/inet.hh"')
+
+ @classmethod
+ def swig_predecls(cls, code):
+ code('%include "python/swig/inet.i"')
+
+ def __init__(self, *args, **kwargs):
+ def handle_kwarg(self, kwargs, key, elseVal = None):
+ if key in kwargs:
+ setattr(self, key, kwargs.pop(key))
+ elif elseVal:
+ setattr(self, key, elseVal)
+ else:
+ raise TypeError, "No value set for %s" % key
+
+ if len(args) == 0:
+ handle_kwarg(self, kwargs, 'ip')
+ handle_kwarg(self, kwargs, 'port')
+
+ elif len(args) == 1:
+ if kwargs:
+ if not 'ip' in kwargs and not 'port' in kwargs:
+ raise TypeError, "Invalid arguments"
+ handle_kwarg(self, kwargs, 'ip', args[0])
+ handle_kwarg(self, kwargs, 'port', args[0])
+ elif isinstance(args[0], IpWithPort):
+ self.ip = args[0].ip
+ self.port = args[0].port
+ else:
+ (self.ip, self.port) = convert.toIpWithPort(args[0])
+
+ elif len(args) == 2:
+ self.ip = args[0]
+ self.port = args[1]
+ else:
+ raise TypeError, "Too many arguments specified"
+
+ if kwargs:
+ raise TypeError, "Too many keywords: %s" % kwargs.keys()
+
+ self.verify()
+
+ def verify(self):
+ self.verifyIp()
+ if self.port < 0 or self.port > 0xffff:
+ raise TypeError, "invalid port %d" % self.port
+
+ def getValue(self):
+ from m5.internal.params import IpWithPort
+ return IpWithPort(self.ip, self.port)
+
+ def ini_str(self):
+ return "%08x:%d" % (self.ip, self.port)
+
time_formats = [ "%a %b %d %H:%M:%S %Z %Y",
"%a %b %d %H:%M:%S %Z %Y",
"%Y/%m/%d %H:%M:%S",
@@ -1317,6 +1474,7 @@ __all__ = ['Param', 'VectorParam',
'Int32', 'UInt32', 'Int64', 'UInt64',
'Counter', 'Addr', 'Tick', 'Percent',
'TcpPort', 'UdpPort', 'EthernetAddr',
+ 'IpAddress', 'IpNetmask', 'IpWithPort',
'MemorySize', 'MemorySize32',
'Latency', 'Frequency', 'Clock',
'NetworkBandwidth', 'MemoryBandwidth',
diff --git a/src/python/m5/util/convert.py b/src/python/m5/util/convert.py
index bb9e3e1f1..5d4ae92b9 100644
--- a/src/python/m5/util/convert.py
+++ b/src/python/m5/util/convert.py
@@ -248,3 +248,52 @@ def toMemorySize(value):
return long(value[:-1])
raise ValueError, "cannot convert '%s' to memory size" % value
+
+def toIpAddress(value):
+ if not isinstance(value, str):
+ raise TypeError, "wrong type '%s' should be str" % type(value)
+
+ bytes = value.split('.')
+ if len(bytes) != 4:
+ raise ValueError, 'invalid ip address %s' % value
+
+ for byte in bytes:
+ if not 0 <= int(byte) <= 0xff:
+ raise ValueError, 'invalid ip address %s' % value
+
+ return (int(bytes[0]) << 24) | (int(bytes[1]) << 16) | \
+ (int(bytes[2]) << 8) | (int(bytes[3]) << 0)
+
+def toIpNetmask(value):
+ if not isinstance(value, str):
+ raise TypeError, "wrong type '%s' should be str" % type(value)
+
+ (ip, netmask) = value.split('/')
+ ip = toIpAddress(ip)
+ netmaskParts = netmask.split('.')
+ if len(netmaskParts) == 1:
+ if not 0 <= int(netmask) <= 32:
+ raise ValueError, 'invalid netmask %s' % netmask
+ return (ip, int(netmask))
+ elif len(netmaskParts) == 4:
+ netmaskNum = toIpAddress(netmask)
+ if netmaskNum == 0:
+ return (ip, 0)
+ testVal = 0
+ for i in range(32):
+ testVal |= (1 << (31 - i))
+ if testVal == netmaskNum:
+ return (ip, i + 1)
+ raise ValueError, 'invalid netmask %s' % netmask
+ else:
+ raise ValueError, 'invalid netmask %s' % netmask
+
+def toIpWithPort(value):
+ if not isinstance(value, str):
+ raise TypeError, "wrong type '%s' should be str" % type(value)
+
+ (ip, port) = value.split(':')
+ ip = toIpAddress(ip)
+ if not 0 <= int(port) <= 0xffff:
+ raise ValueError, 'invalid port %s' % port
+ return (ip, int(port))
diff --git a/src/python/swig/inet.i b/src/python/swig/inet.i
index e92b44597..bad5488e6 100644
--- a/src/python/swig/inet.i
+++ b/src/python/swig/inet.i
@@ -42,5 +42,24 @@ struct EthAddr
EthAddr(const uint8_t ea[6]);
EthAddr(const std::string &addr);
};
+
+struct IpAddress
+{
+ IpAddress();
+ IpAddress(const uint32_t __addr);
+};
+
+struct IpNetmask : IpAddress
+{
+ IpNetmask();
+ IpNetmask(const uint32_t __addr, const uint8_t __netmask);
+};
+
+struct IpWithPort : IpAddress
+{
+ IpWithPort();
+ IpWithPort(const uint32_t __addr, const uint16_t __port);
+};
+
}