Params: Add parameter types for IP addresses in various forms.
New parameter forms are: IP address in the format "a.b.c.d" where a-d are from decimal 0 to 255. IP address with netmask which is an IP followed by "/n" where n is a netmask length in bits from decimal 0 to 32 or by "/e.f.g.h" where e-h are from decimal 0 to 255 and which is all 1 bits followed by all 0 bits when represented in binary. These can also be specified as an integral IP and netmask passed in separately. IP address with port which is an IP followed by ":p" where p is a port index from decimal 0 to 65535. These can also be specified as an integral IP and port value passed in separately.
This commit is contained in:
parent
40d434d551
commit
b3de4855c3
5 changed files with 352 additions and 0 deletions
|
@ -117,6 +117,73 @@ operator<<(ostream &stream, const EthAddr &ea)
|
||||||
return stream;
|
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
|
uint16_t
|
||||||
cksum(const IpPtr &ptr)
|
cksum(const IpPtr &ptr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -147,6 +147,65 @@ class EthPtr
|
||||||
/*
|
/*
|
||||||
* IP Stuff
|
* 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 IpOpt;
|
||||||
struct IpHdr : public ip_hdr
|
struct IpHdr : public ip_hdr
|
||||||
{
|
{
|
||||||
|
|
|
@ -675,6 +675,163 @@ class EthernetAddr(ParamValue):
|
||||||
def ini_str(self):
|
def ini_str(self):
|
||||||
return self.value
|
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",
|
time_formats = [ "%a %b %d %H:%M:%S %Z %Y",
|
||||||
"%a %b %d %H:%M:%S %Z %Y",
|
"%a %b %d %H:%M:%S %Z %Y",
|
||||||
"%Y/%m/%d %H:%M:%S",
|
"%Y/%m/%d %H:%M:%S",
|
||||||
|
@ -1317,6 +1474,7 @@ __all__ = ['Param', 'VectorParam',
|
||||||
'Int32', 'UInt32', 'Int64', 'UInt64',
|
'Int32', 'UInt32', 'Int64', 'UInt64',
|
||||||
'Counter', 'Addr', 'Tick', 'Percent',
|
'Counter', 'Addr', 'Tick', 'Percent',
|
||||||
'TcpPort', 'UdpPort', 'EthernetAddr',
|
'TcpPort', 'UdpPort', 'EthernetAddr',
|
||||||
|
'IpAddress', 'IpNetmask', 'IpWithPort',
|
||||||
'MemorySize', 'MemorySize32',
|
'MemorySize', 'MemorySize32',
|
||||||
'Latency', 'Frequency', 'Clock',
|
'Latency', 'Frequency', 'Clock',
|
||||||
'NetworkBandwidth', 'MemoryBandwidth',
|
'NetworkBandwidth', 'MemoryBandwidth',
|
||||||
|
|
|
@ -248,3 +248,52 @@ def toMemorySize(value):
|
||||||
return long(value[:-1])
|
return long(value[:-1])
|
||||||
|
|
||||||
raise ValueError, "cannot convert '%s' to memory size" % value
|
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))
|
||||||
|
|
|
@ -42,5 +42,24 @@ struct EthAddr
|
||||||
EthAddr(const uint8_t ea[6]);
|
EthAddr(const uint8_t ea[6]);
|
||||||
EthAddr(const std::string &addr);
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue