1import socket 2from pr2modules.common import map_namespace 3from pr2modules.netlink import nlmsg 4from pr2modules.netlink import nla 5 6# address attributes 7# 8# Important comment: 9# For IPv4, IFA_ADDRESS is a prefix address, not a local interface 10# address. It makes no difference for normal interfaces, but 11# for point-to-point ones IFA_ADDRESS means DESTINATION address, 12# and the local address is supplied in IFA_LOCAL attribute. 13# 14 15IFA_F_SECONDARY = 0x01 16# IFA_F_TEMPORARY IFA_F_SECONDARY 17IFA_F_NODAD = 0x02 18IFA_F_OPTIMISTIC = 0x04 19IFA_F_DADFAILED = 0x08 20IFA_F_HOMEADDRESS = 0x10 21IFA_F_DEPRECATED = 0x20 22IFA_F_TENTATIVE = 0x40 23IFA_F_PERMANENT = 0x80 24IFA_F_MANAGETEMPADDR = 0x100 25IFA_F_NOPREFIXROUTE = 0x200 26IFA_F_MCAUTOJOIN = 0x400 27IFA_F_STABLE_PRIVACY = 0x800 28 29(IFA_F_NAMES, IFA_F_VALUES) = map_namespace('IFA_F', globals()) 30# 8<---------------------------------------------- 31IFA_F_TEMPORARY = IFA_F_SECONDARY 32IFA_F_NAMES['IFA_F_TEMPORARY'] = IFA_F_TEMPORARY 33IFA_F_VALUES6 = IFA_F_VALUES 34IFA_F_VALUES6[IFA_F_TEMPORARY] = 'IFA_F_TEMPORARY' 35# 8<---------------------------------------------- 36 37 38class ifaddrmsg(nlmsg): 39 ''' 40 IP address information 41 42 C structure:: 43 44 struct ifaddrmsg { 45 unsigned char ifa_family; /* Address type */ 46 unsigned char ifa_prefixlen; /* Prefixlength of address */ 47 unsigned char ifa_flags; /* Address flags */ 48 unsigned char ifa_scope; /* Address scope */ 49 int ifa_index; /* Interface index */ 50 }; 51 52 ''' 53 prefix = 'IFA_' 54 55 sql_constraints = {'IFA_LOCAL': "NOT NULL DEFAULT ''"} 56 57 fields = (('family', 'B'), 58 ('prefixlen', 'B'), 59 ('flags', 'B'), 60 ('scope', 'B'), 61 ('index', 'I')) 62 63 nla_map = (('IFA_UNSPEC', 'hex'), 64 ('IFA_ADDRESS', 'ipaddr'), 65 ('IFA_LOCAL', 'ipaddr'), 66 ('IFA_LABEL', 'asciiz'), 67 ('IFA_BROADCAST', 'ipaddr'), 68 ('IFA_ANYCAST', 'ipaddr'), 69 ('IFA_CACHEINFO', 'cacheinfo'), 70 ('IFA_MULTICAST', 'ipaddr'), 71 ('IFA_FLAGS', 'uint32')) 72 73 class cacheinfo(nla): 74 fields = (('ifa_preferred', 'I'), 75 ('ifa_valid', 'I'), 76 ('cstamp', 'I'), 77 ('tstamp', 'I')) 78 79 @staticmethod 80 def flags2names(flags, family=socket.AF_INET): 81 if family == socket.AF_INET6: 82 ifa_f_values = IFA_F_VALUES6 83 else: 84 ifa_f_values = IFA_F_VALUES 85 ret = [] 86 for f in ifa_f_values: 87 if f & flags: 88 ret.append(ifa_f_values[f]) 89 return ret 90 91 @staticmethod 92 def names2flags(flags): 93 ret = 0 94 for f in flags: 95 if f[0] == '!': 96 f = f[1:] 97 else: 98 ret |= IFA_F_NAMES[f] 99 return ret 100