The Assimilation Project
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
AssimCclasses.py
Go to the documentation of this file.
1 #pylint: disable=C0302
2 # vim: smartindent tabstop=4 shiftwidth=4 expandtab
3 #C0302: too many lines in module
4 #
5 #
6 # This file is part of the Assimilation Project.
7 #
8 # Copyright (C) 2011, 2012 - Alan Robertson <alanr@unix.sh>
9 #
10 # The Assimilation software is free software: you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation, either version 3 of the License, or
13 # (at your option) any later version.
14 #
15 # The Assimilation software is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License
21 # along with the Assimilation Project software. If not, see http://www.gnu.org/licenses/
22 #
23 #
24 #pylint: disable=C0302,W0212
25 '''
26 A collection of classes which wrap our @ref C-Classes and provide Pythonic interfaces
27 to these C-classes.
28 '''
29 
30 #pylint: disable=W0611
31 from AssimCtypes import AddrFrame, CstringFrame, UnknownFrame, ConfigValue, IpPortFrame, \
32  FrameSet, PacketDecoder, guint8, IntFrame, ConfigContext, SignFrame, CompressFrame, \
33  proj_class_live_object_count, proj_class_dump_live_objects, CONFIGNAME_CMAPORT
34 #pylint: enable=W0611
35 from AssimCtypes import POINTER, cast, addressof, pointer, string_at, create_string_buffer, \
36  c_char_p, byref, memmove, badfree, \
37  g_free, GSList, GDestroyNotify, g_slist_length, g_slist_next, struct__GSList, \
38  g_slist_free, \
39  MALLOC, memmove, \
40  FRAMETYPE_SIG, \
41  Frame, AssimObj, NetAddr, SeqnoFrame, ReliableUDP, \
42  frame_new, addrframe_new, \
43  nvpairframe_new, frameset_new, frameset_append_frame, frameset_prepend_frame, \
44  seqnoframe_new, cstringframe_new, unknownframe_new, \
45  ipportframe_netaddr_new, ipportframe_ipv4_new, ipportframe_ipv6_new, \
46  frameset_construct_packet, frameset_get_flags, frameset_set_flags, frameset_clear_flags, \
47  frameset_dump, \
48  LLDP_TLV_END, LLDP_TLV_CHID, LLDP_TLV_PID, LLDP_TLV_TTL, LLDP_TLV_PORT_DESCR, \
49  LLDP_TLV_SYS_NAME, LLDP_TLV_SYS_DESCR, LLDP_TLV_SYS_CAPS, LLDP_TLV_MGMT_ADDR, \
50  LLDP_TLV_ORG_SPECIFIC, \
51  LLDP_ORG802_1_VLAN_PVID, LLDP_ORG802_1_VLAN_PORTPROTO, LLDP_ORG802_1_VLAN_NAME, \
52  LLDP_ORG802_1_VLAN_PROTOID, LLDP_ORG802_3_PHY_CONFIG, LLDP_ORG802_3_POWERVIAMDI, \
53  LLDP_ORG802_3_LINKAGG, LLDP_ORG802_3_MTU, \
54  LLDP_PIDTYPE_ALIAS, LLDP_PIDTYPE_IFNAME, LLDP_PIDTYPE_LOCAL, LLDP_CHIDTYPE_ALIAS, \
55  LLDP_CHIDTYPE_IFNAME, LLDP_CHIDTYPE_LOCAL, LLDP_CHIDTYPE_MACADDR, \
56  LLDP_CHIDTYPE_COMPONENT, LLDP_CHIDTYPE_NETADDR, \
57  ADDR_FAMILY_IPV4, ADDR_FAMILY_IPV6, ADDR_FAMILY_802, \
58  is_valid_lldp_packet, is_valid_cdp_packet, \
59  netaddr_ipv4_new, netaddr_ipv6_new, netaddr_dns_new, netaddr_mac48_new, netaddr_mac64_new, \
60  proj_class_classname, \
61  assimobj_new, intframe_new, signframe_new, packetdecoder_new, configcontext_new, \
62  configcontext_new_JSON_string, netio_new, netioudp_new, reliableudp_new,\
63  netio_is_dual_ipv4v6_stack, create_setconfig, create_sendexpecthb, \
64  get_lldptlv_first, \
65  get_lldptlv_next, \
66  get_lldptlv_type, \
67  get_lldptlv_len, \
68  get_lldptlv_body, \
69  get_lldptlv_next, \
70  CFG_EEXIST, CFG_CFGCTX, CFG_CFGCTX, CFG_STRING, CFG_NETADDR, CFG_FRAME, CFG_INT64, CFG_ARRAY, \
71  CFG_FLOAT, CFG_BOOL, DEFAULT_FSP_QID, CFG_NULL, \
72  COMPRESS_ZLIB, FRAMETYPE_COMPRESS, compressframe_new
73 
74 from consts import CMAconsts
75 
76 from frameinfo import FrameTypes, FrameSetTypes
77 import collections
78 import traceback
79 import sys, gc
80 
81 #pylint: disable=R0903
82 class cClass (object):
83  'Just a handy collection of POINTER() objects'
84  def __init__(self):
85  pass
86  NetAddr = POINTER(NetAddr)
87  Frame = POINTER(Frame)
88  AddrFrame = POINTER(AddrFrame)
89  IntFrame = POINTER(IntFrame)
90  SeqnoFrame = POINTER(SeqnoFrame)
91  CstringFrame = POINTER(CstringFrame)
92  UnknownFrame = POINTER(UnknownFrame)
93  SignFrame = POINTER(SignFrame)
94  FrameSet = POINTER(FrameSet)
95  ConfigContext = POINTER(ConfigContext)
96  ConfigValue = POINTER(ConfigValue)
97  IpPortFrame = POINTER(IpPortFrame)
98  CompressFrame = POINTER(CompressFrame)
99  guint8 = POINTER(guint8)
100  GSList = POINTER(GSList)
101 
102 def CCref(obj):
103  '''
104  Increment the reference count to an AssimObj (_not_ a pyAssimObj)
105  Need to call CCref under the following circumstances:
106  When we are creating an object that points to another underlying C-class object
107  which already has a permanent reference to it somewhere else
108  For example, if we're returning a pyNetAddr object that points to a NetAddr object
109  that's in a ConfigContext object. If we don't, then when our pyNetAddr object goes
110  out of scope, then the underlying NetAddr object will be freed, even though there's
111  a reference to it in the ConfigContext object. Conversely, if the ConfigContext
112  object goes out of scope first, then the our pyNetAddr object could become invalid.
113 
114  Do not call it when you've constructed a new object that there were no previous pointers
115  to.
116  '''
117  base = obj[0]
118  while (type(base) is not AssimObj):
119  base = base.baseclass
120  base.ref(obj)
121 
122 def CCunref(obj):
123  'Unref an AssimObj object (or subclass)'
124  base = obj[0]
125  while (type(base) is not AssimObj):
126  base = base.baseclass
127  base.unref(obj)
128 
129 class pySwitchDiscovery(object):
130  '''
131  Class for interpreting switch discovery data via LLDP or CDP
132  Currently only LLDP is fully implemented.
133  '''
134  lldpnames = {
135  LLDP_TLV_END: ('END', True),
136  LLDP_TLV_CHID: ('ChassisId', True),
137  LLDP_TLV_PID: ('PortId', True),
138  LLDP_TLV_TTL: ('TTL', True),
139  LLDP_TLV_PORT_DESCR: ('PortDescription', False),
140  LLDP_TLV_SYS_NAME: ('SystemName', True),
141  LLDP_TLV_SYS_DESCR: ('SystemDescription', True),
142  LLDP_TLV_SYS_CAPS: ('SystemCapabilities', True),
143  LLDP_TLV_MGMT_ADDR: ('ManagementAddress', True),
144  LLDP_TLV_ORG_SPECIFIC: ('(OrgSpecific)', True),
145  }
146  lldp802_1names = {
147  LLDP_ORG802_1_VLAN_PVID: ('VlanPvId', False),
148  LLDP_ORG802_1_VLAN_PORTPROTO: ('VlanPortProtocol', False),
149  LLDP_ORG802_1_VLAN_NAME: ('VlanName', False),
150  LLDP_ORG802_1_VLAN_PROTOID: ('VlanProtocolId', False),
151  }
152  lldp802_3names = {
153  LLDP_ORG802_3_PHY_CONFIG: ('PhysicalConfiguration', False),
154  LLDP_ORG802_3_POWERVIAMDI: ('PowerViaMDI', False),
155  LLDP_ORG802_3_LINKAGG: ('LinkAggregation', False),
156  LLDP_ORG802_3_MTU: ('MTU', False),
157  }
158 
159  def __init__(self):
160  pass
161 
162  @staticmethod
163  def _byte0(pktstart):
164  'Return the first (zeroth) byte from a memory blob'
165  return int(cast(pktstart, cClass.guint8)[0])
166 
167  @staticmethod
168  def _byte1addr(pktstart):
169  'Return the address of byte 1 in a memory blob'
170  addr = addressof(pktstart.contents) + 1
171  return pointer(type(pktstart.contents).from_address(addr))
172 
173  @staticmethod
174  def _byteN(pktstart, n):
175  'Return the Nth byte from a memory blob'
176  return int(cast(pktstart, cClass.guint8)[n])
177 
178  @staticmethod
179  def _byteNaddr(pktstart, n):
180  'Return the address of the Nth byte in a memory blob'
181  addr = addressof(pktstart.contents) + n
182  return pointer(type(pktstart.contents).from_address(addr))
183 
184  @staticmethod
185  def _decode_netaddr(addrstart, addrlen):
186  'Return an appropriate pyNetAddr object corresponding to the given memory blob'
187  byte0 = pySwitchDiscovery._byte0(addrstart)
188  byte1addr = pySwitchDiscovery._byte1addr(addrstart)
189  Cnetaddr = None
190  if byte0 == ADDR_FAMILY_IPV6:
191  if addrlen != 17:
192  return None
193  Cnetaddr = netaddr_ipv6_new(byte1addr, 0)
194  elif byte0 == ADDR_FAMILY_IPV4:
195  if addrlen != 5:
196  return None
197  Cnetaddr = netaddr_ipv4_new(byte1addr, 0)
198  elif byte0 == ADDR_FAMILY_802:
199  if addrlen == 7:
200  Cnetaddr = netaddr_mac48_new(byte1addr)
201  elif addrlen == 9:
202  Cnetaddr = netaddr_mac64_new(byte1addr)
203  if Cnetaddr is not None:
204  return str(pyNetAddr(None, Cstruct=Cnetaddr))
205  return None
206 
207  @staticmethod
208  def decode_discovery(host, interface, wallclock, pktstart, pktend):
209  'Return a JSON packet corresponding to the given switch discovery packet'
210  if is_valid_lldp_packet(pktstart, pktend):
211  return pySwitchDiscovery._decode_lldp(host, interface, wallclock, pktstart, pktend)
212  if is_valid_cdp_packet(pktstart, pktend):
213  return pySwitchDiscovery._decode_cdp(host, interface, wallclock, pktstart, pktend)
214  raise ValueError('Malformed Switch Discovery Packet')
215 
216  @staticmethod
217  def _decode_lldp_chid(tlvptr, tlvlen):
218  'Decode the LLDP CHID field, and return an appropriate value'
219  chidtype = pySwitchDiscovery._byte0(tlvptr)
220 
221  if (chidtype == LLDP_CHIDTYPE_COMPONENT or chidtype == LLDP_CHIDTYPE_ALIAS
222  or chidtype == LLDP_CHIDTYPE_IFNAME or chidtype == LLDP_CHIDTYPE_LOCAL):
223  sloc = pySwitchDiscovery._byte1addr(tlvptr)
224  value = string_at(sloc, tlvlen-1)
225  elif chidtype == LLDP_CHIDTYPE_MACADDR:
226  byte1addr = pySwitchDiscovery._byte1addr(tlvptr)
227  Cmacaddr = None
228  if tlvlen == 7:
229  Cmacaddr = netaddr_mac48_new(byte1addr)
230  elif tlvlen == 9:
231  Cmacaddr = netaddr_mac64_new(byte1addr)
232  if Cmacaddr is not None:
233  value = pyNetAddr(None, Cstruct=Cmacaddr)
234  elif chidtype == LLDP_CHIDTYPE_NETADDR:
235  byte1addr = pySwitchDiscovery._byte1addr(tlvptr)
236  value = pySwitchDiscovery._decode_netaddr(byte1addr, tlvlen-1)
237  return value
238 
239  #pylint: disable=R0914,R0912
240  @staticmethod
241  def _decode_lldp(host, interface, wallclock, pktstart, pktend):
242  'Decode LLDP packet into a JSON discovery packet'
243  #print >> sys.stderr, 'DECODING LLDP PACKET!<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'
244  thisportinfo = pyConfigContext(init={
245  'ConnectsToHost': host,
246  'ConnectsToInterface': interface,
247  }
248  )
249  switchinfo = pyConfigContext(init = {'ports': pyConfigContext()})
250  metadata = pyConfigContext(init={
251  'discovertype': '__LinkDiscovery',
252  'description': 'Link Level Switch Discovery (lldp)',
253  'source': '_decode_lldp()',
254  'host': host,
255  'localtime': str(wallclock),
256  'data': switchinfo,
257  }
258  )
259  capnames = [ None, CMAconsts.ROLE_repeater
260  , CMAconsts.ROLE_bridge, CMAconsts.ROLE_AccessPoint
261  , CMAconsts.ROLE_router, CMAconsts.ROLE_phone
262  , CMAconsts.ROLE_DOCSIS, CMAconsts.ROLE_Station
263  ]
264 
265  sourcemacptr = pySwitchDiscovery._byteNaddr(cast(pktstart, cClass.guint8), 6)
266  if not sourcemacptr:
267  return metadata
268  Cmacaddr = netaddr_mac48_new(sourcemacptr)
269  sourcemac = pyNetAddr(None, Cstruct=Cmacaddr)
270 
271 
272  this = get_lldptlv_first(pktstart, pktend)
273  while this and this < pktend:
274  tlvtype = get_lldptlv_type(this, pktend)
275  tlvlen = get_lldptlv_len(this, pktend)
276  tlvptr = cast(get_lldptlv_body(this, pktend), cClass.guint8)
277  value = None
278  if tlvtype not in pySwitchDiscovery.lldpnames:
279  print >> sys.stderr, 'Cannot find tlvtype %d' % tlvtype
280  tlvtype = None
281  else:
282  (tlvname, isswitchinfo) = pySwitchDiscovery.lldpnames[tlvtype]
283 
284  if (tlvtype == LLDP_TLV_PORT_DESCR or tlvtype == LLDP_TLV_SYS_NAME or
285  tlvtype == LLDP_TLV_SYS_DESCR): #########################################
286  value = string_at(tlvptr, tlvlen)
287 
288  elif tlvtype == LLDP_TLV_PID: ###############################################
289  pidtype = pySwitchDiscovery._byte0(tlvptr)
290  if (pidtype == LLDP_PIDTYPE_ALIAS or pidtype == LLDP_PIDTYPE_IFNAME
291  or pidtype == LLDP_PIDTYPE_LOCAL):
292  sloc = pySwitchDiscovery._byte1addr(tlvptr)
293  value = string_at(sloc, tlvlen-1)
294 
295  elif tlvtype == LLDP_TLV_CHID: #############################################
296  value = pySwitchDiscovery._decode_lldp_chid(tlvptr, tlvlen)
297 
298  elif tlvtype == LLDP_TLV_MGMT_ADDR: #########################################
299  addrlen = pySwitchDiscovery._byte0(tlvptr)
300  byte1addr = pySwitchDiscovery._byte1addr(tlvptr)
301  value = pySwitchDiscovery._decode_netaddr(byte1addr, addrlen)
302 
303  elif tlvtype == LLDP_TLV_SYS_CAPS: #########################################
304  byte0 = pySwitchDiscovery._byte0(tlvptr)
305  byte1 = pySwitchDiscovery._byteN(tlvptr, 1)
306  byte2 = pySwitchDiscovery._byteN(tlvptr, 2)
307  byte3 = pySwitchDiscovery._byteN(tlvptr, 3)
308  caps0 = (byte0 << 8 | byte1)
309  caps1 = (byte2 << 8 | byte3)
310  value = pyConfigContext()
311  mask = 2
312  for j in range(1, 7):
313  if (caps0 & mask):
314  value[capnames[j]] = ((caps1 & mask) != 0)
315  mask <<= 1
316 
317 
318  elif tlvtype == LLDP_TLV_ORG_SPECIFIC: ######################################
319  print >> sys.stderr, 'Found LLDP org-specific extensions (not processed)'
320 
321  if value is not None:
322  if tlvtype == LLDP_TLV_PID:
323  switchinfo['ports'][value] = thisportinfo
324  thisportinfo['PortId'] = value
325  numericpart = value
326  while len(numericpart) > 0 and not numericpart.isdigit():
327  numericpart = numericpart[1:]
328  if len > 0 and numericpart.isdigit():
329  thisportinfo['PORTNUM'] = int(numericpart)
330  else:
331  if isswitchinfo:
332  switchinfo[tlvname] = value
333  else:
334  thisportinfo[tlvname] = value
335  this = get_lldptlv_next(this, pktend)
336  thisportinfo['sourceMAC'] = sourcemac
337  return metadata
338 
339 
340  @staticmethod
341  def _decode_cdp(host, interface, wallclock, pktstart, pktend):
342  'Decode CDP packet into a JSON discovery packet'
343  thisportinfo = pyConfigContext(init={
344  'ConnectsToHost': host,
345  'ConnectsToInterface': interface,
346  }
347  )
348  switchinfo = pyConfigContext(init = {'ports': pyConfigContext()})
349  metadata = pyConfigContext(init={
350  'discovertype': '__LinkDiscovery',
351  'description': 'Link Level Switch Discovery (cdp)',
352  'source': '_decode_cdp()',
353  'host': host,
354  'localtime': str(wallclock),
355  'data': switchinfo,
356  }
357  )
358  thisportinfo = thisportinfo
359  pktstart = pktstart
360  pktend = pktend
361  return metadata
362 
363 
364 
365 
366 class pyAssimObj(object):
367  'The base object for all the C-class objects'
368  def __init__(self, Cstruct=None):
369  'Create a base pyAssimObj object'
370  self._Cstruct = None
371  if (Cstruct is not None):
372  assert type(Cstruct) is not int
373  self._Cstruct = Cstruct
374  else:
375  self._Cstruct = assimobj_new(0)
376  #print 'ASSIMOBJ:init: %s' % (Cstruct)
377 
378  def cclassname(self):
379  "Return the 'C' class name for this object"
380  return proj_class_classname(self._Cstruct)
381 
382  def __str__(self):
383  'Convert this AssimObj into a printable string'
384  if not self._Cstruct:
385  return "[None]"
386  base = self._Cstruct[0]
387  while (type(base) is not AssimObj):
388  base = base.baseclass
389  cstringret = cast(base.toString(self._Cstruct), c_char_p)
390  ret = string_at(cstringret)
391  g_free(cstringret)
392  return ret
393 
394  #pylint: disable=W0603
395  def __del__(self):
396  'Free up the underlying Cstruct for this pyAssimObj object.'
397  if not self._Cstruct or self._Cstruct is None:
398  return
399  # I have no idea why the type(base) is not Frame doesn't work here...
400  # This 'hasattr' construct only works because we are a base C-class
401  global badfree
402  badfree = 0
403  CCunref(self._Cstruct)
404  if badfree != 0:
405  print >> sys.stderr, "Attempt to free something already freed(%s)" % str(self._Cstruct)
406  traceback.print_stack()
407  badfree = 0
408  self._Cstruct = None
409 
410  def refcount(self):
411  'Return the reference count for this object'
412  base = self._Cstruct[0]
413  while (hasattr(base, 'baseclass')):
414  base = base.baseclass
415  return base._refcount
416 
418  '''This class represents the Python version of our C-class @ref NetAddr
419  - represented by the struct _NetAddr.
420  '''
421  def __init__(self, addrstring, port=None, Cstruct=None):
422  '''This constructor needs a list of integers of the right length as its first argument.
423  The length of the list determines the type of address generated.
424  4 bytes == ipv4
425  6 bytes == MAC address
426  8 bytes == MAC address
427  16 bytes == ipv6 address
428  This is slightly sleazy but it should work for the forseeable future.
429  '''
430 
431  self._Cstruct = None # Silence error messages in failure cases
432 
433  if (Cstruct is not None):
434  assert type(Cstruct) is not int
435  pyAssimObj.__init__(self, Cstruct=Cstruct)
436  if port is not None:
437  self.setport(port)
438  return
439 
440  if port is None:
441  port = 0
442 
443  if isinstance(addrstring, unicode) or isinstance(addrstring, pyNetAddr):
444  addrstring = str(addrstring)
445  if isinstance(addrstring, str):
446  cs = netaddr_dns_new(addrstring)
447  if not cs:
448  raise ValueError('Illegal NetAddr initial value: "%s"' % addrstring)
449  if port != 0:
450  cs[0].setport(cs, port)
451  pyAssimObj.__init__(self, Cstruct=cs)
452  return
453 
454  self._init_from_binary(addrstring, port)
455 
456  def _init_from_binary(self, addrstring, port):
457  'Initialize an addrstring from a binary argument'
458  alen = len(addrstring)
459  addr = create_string_buffer(alen)
460  #print >> sys.stderr, "ADDRTYPE:", type(addr)
461  #print >> sys.stderr, "ADDRSTRINGTYPE:", type(addrstring)
462  for i in range(0, alen):
463  asi = addrstring[i]
464  #print >> sys.stderr, "ASI_TYPE: (%s,%s)" % (type(asi), asi)
465  if type(asi) is str:
466  addr[i] = asi
467  elif type(asi) is unicode:
468  addr[i] = str(asi)
469  else:
470  addr[i] = chr(asi)
471  #print >> sys.stderr, 'ADDR = %s' % addr
472  if alen == 4: # ipv4
473  NA = netaddr_ipv4_new(addr, port)
474  pyAssimObj.__init__(self, Cstruct=NA)
475  elif alen == 16: # ipv6
476  pyAssimObj.__init__(self, netaddr_ipv6_new(addr, port))
477  elif alen == 6: # "Normal" 48-bit MAC address
478  assert port == 0
479  pyAssimObj.__init__(self, netaddr_mac48_new(addr, port))
480  elif alen == 8: # Extended 64-bit MAC address
481  assert port == 0
482  pyAssimObj.__init__(self, netaddr_mac64_new(addr, port))
483  else:
484  raise ValueError('Invalid address length - not 4, 6, 8, or 16')
485 
486  def port(self):
487  'Return the port (if any) for this pyNetAddr object'
488  base = self._Cstruct[0]
489  while (type(base) is not NetAddr):
490  base = base.baseclass
491  return base.port(self._Cstruct)
492 
493  def setport(self, port):
494  'Return the port (if any) for this pyNetAddr object'
495  base = self._Cstruct[0]
496  while (type(base) is not NetAddr):
497  base = base.baseclass
498  base.setport(self._Cstruct, port)
499 
500  def addrtype(self):
501  'Return the type of address for this pyNetAddr object'
502  base = self._Cstruct[0]
503  while (type(base) is not NetAddr):
504  base = base.baseclass
505  return base.addrtype(self._Cstruct)
506 
507  def addrlen(self):
508  "Return the number of bytes necessary to represent this pyNetAddr object on the wire."
509  base = self._Cstruct[0]
510  while (type(base) is not NetAddr):
511  base = base.baseclass
512  return base._addrlen
513 
514  def islocal(self):
515  'Return True if this address is a local address'
516  base = self._Cstruct[0]
517  while (type(base) is not NetAddr):
518  base = base.baseclass
519  return base.islocal(self._Cstruct)
520 
521  def isanyaddr(self):
522  'Return True if this address is a local address'
523  base = self._Cstruct[0]
524  while (type(base) is not NetAddr):
525  base = base.baseclass
526  return base.isanyaddr(self._Cstruct)
527 
528  def toIPv6(self, port=None):
529  'Return an equivalent IPv6 address to the one that was given. Guaranteed to be a copy'
530  base = self._Cstruct[0]
531  while (type(base) is not NetAddr):
532  base = base.baseclass
533  newcs = cast(base.toIPv6(self._Cstruct), cClass.NetAddr)
534  return pyNetAddr(None, Cstruct=newcs, port=port)
535 
536  def __repr__(self):
537  'Return a canonical representation of this NetAddr'
538  base = self._Cstruct[0]
539  while (type(base) is not NetAddr):
540  base = base.baseclass
541  cstringret = base.canonStr(self._Cstruct)
542  ret = string_at(cstringret)
543  g_free(cstringret)
544  return ret
545 
546 
547  def __eq__(self, other):
548  "Return True if the two pyNetAddrs are equal"
549  if not other._Cstruct or not self._Cstruct:
550  return False
551  base = self._Cstruct[0]
552  while (type(base) is not NetAddr):
553  base = base.baseclass
554  return base.equal(self._Cstruct, other._Cstruct)
555 
556  def __hash__(self):
557  'Return a hash value for the given pyNetAddr'
558  if not self._Cstruct:
559  return 0
560  base = self._Cstruct[0]
561  while (type(base) is not NetAddr):
562  base = base.baseclass
563  return base.hash(self._Cstruct)
564 
565 
567  '''This class represents the Python version of our C-class @ref Frame
568  - represented by the struct _Frame.
569  This class is a base class for several different pyFrame subclasses.
570  Each of these various pyFrame subclasses have a corresponding C-class @ref Frame subclass.
571  The purpose of these pyFrames and their subclasses is to talk on the wire with our C code in our
572  nanoprobes.
573 
574  Deliberately leaving out the updatedata() C-class member function - at least for now.
575  I suspect that the Python code will only need the corresponding calls in a @ref FrameSet
576  - which would then update the corresponding @ref Frame member functions...
577  '''
578  #
579  # Our subclasses need to implement these methods:
580  # __init__ - subclass initializer
581  # from_Cstruct classmethod - call the corresponding xxxframe_tlvconstructor() function
582  # to act as a pseudo-constructor. This method/constructor is used to create
583  # Python objects from incoming packet data.
584  #
585  def __init__(self, initval, Cstruct=None):
586  "Initializer for the pyFrame object."
587  if Cstruct is None:
588  try:
589  frametype = initval.tlvtype
590  except(AttributeError):
591  frametype = int(initval)
592  # If we don't do this, then a subclass __init__ function must do it instead...
593  pyAssimObj.__init__(self, Cstruct=frame_new(frametype, 0))
594  else:
595  pyAssimObj.__init__(self, Cstruct=Cstruct)
596 
597  def frametype(self):
598  "Return the TLV type for the pyFrame object."
599  base = self._Cstruct[0]
600  while (type(base)is not Frame):
601  base = base.baseclass
602  return base.type
603 
604  def framelen(self):
605  "Return the length of this frame in bytes (TLV length)."
606  base = self._Cstruct[0]
607  while (type(base)is not Frame):
608  base = base.baseclass
609  return base.length
610 
611  def framevalue(self):
612  'Return a C-style pointer to the underlying raw TLV data (if any)'
613  base = self._Cstruct[0]
614  while (type(base)is not Frame):
615  base = base.baseclass
616  return cast(base.value, c_char_p)
617 
618  def frameend(self):
619  'Return a C-style pointer to the underlying raw TLV data (if any)'
620  base = self._Cstruct[0]
621  while (type(base)is not Frame):
622  base = base.baseclass
623  return cast(base.value+base.length, c_char_p)
624 
625  def dataspace(self):
626  'Return the amount of space this frame needs - including type and length'
627  base = self._Cstruct[0]
628  while (type(base) is not Frame):
629  base = base.baseclass
630  return base.dataspace(self._Cstruct)
631 
632  def isvalid(self):
633  "Return True if this Frame is valid"
634  base = self._Cstruct[0]
635  while (type(base) is not Frame):
636  base = base.baseclass
637 # pstart = pointer(cast(base.value, c_char_p))
638 # if pstart[0] is None:
639 # return False
640  return (int(base.isvalid(self._Cstruct, None, None)) != 0)
641 
642  def setvalue(self, value):
643  'Assign a chunk of memory to the Value portion of this Frame'
644  vlen = len(value)
645  if type(value) is str:
646  valbuf = create_string_buffer(vlen+1)
647  for i in range(0, vlen):
648  vi = value[i]
649  valbuf[i] = vi
650  valbuf[vlen] = chr(0)
651  vlen += 1
652  else:
653  valbuf = create_string_buffer(vlen)
654  for i in range(0, vlen):
655  vi = value[i]
656  valbuf[i] = int(vi)
657  base = self._Cstruct[0]
658  valptr = MALLOC(vlen)
659  memmove(valptr, valbuf, vlen)
660  while (type(base) is not Frame):
661  base = base.baseclass
662  base.setvalue(self._Cstruct, valptr, vlen, cast(None, GDestroyNotify))
663 
664  def dump(self, prefix):
665  'Dump out this Frame (using C-class "dump" member function)'
666  base = self._Cstruct[0]
667  while (type(base) is not Frame):
668  base = base.baseclass
669  base.dump(self._Cstruct, cast(prefix, c_char_p))
670 
671  def __str__(self):
672  'Convert this Frame to a string'
673  base = self._Cstruct[0]
674  while (type(base) is not AssimObj):
675  base = base.baseclass
676  cstringret = cast(base.toString(self._Cstruct), c_char_p)
677  ret = string_at(cstringret)
678  g_free(cstringret)
679  return '%s: %s' % (FrameTypes.get(self.frametype())[1] , ret)
680 
681  @staticmethod
682  def Cstruct2Frame(frameptr):
683  'Unmarshalls a binary blob (Cstruct) into a Frame'
684  frameptr = cast(frameptr, cClass.Frame)
685  CCref(frameptr)
686  frametype = frameptr[0].type
687  Cclassname = proj_class_classname(frameptr)
688  pyclassname = "py" + Cclassname
689  if Cclassname == 'NetAddr':
690  statement = "%s(%d, None, Cstruct=cast(frameptr, cClass.%s))" \
691  % (pyclassname, frametype, Cclassname)
692  elif Cclassname == Cclassname == 'IpPortFrame':
693  statement = "%s(%d, None, None, Cstruct=cast(frameptr, cClass.%s))" \
694  % (pyclassname, frametype, Cclassname)
695  else:
696  statement = "%s(%d, Cstruct=cast(frameptr, cClass.%s))" \
697  % (pyclassname, frametype, Cclassname)
698  #print >> sys.stderr, "EVAL:", statement
699  return eval(statement)
700 
702  '''This class represents the Python version of our C-class CompressFrame
703  - represented by the struct _CompressFrame. It is used to tell us that
704  what kind of compression we want in our communication stream.
705  '''
706  def __init__(self, frametype=FRAMETYPE_COMPRESS, compression_method=COMPRESS_ZLIB
707  , Cstruct=None):
708  self._Cstruct = None # Keep error legs from complaining.
709  if Cstruct is None:
710  self._Cstruct = compressframe_new(frametype, compression_method)
711  else:
712  self._Cstruct = Cstruct
713  pyFrame.__init__(self, frametype, Cstruct=Cstruct)
714 
715 
717  '''This class represents the Python version of our C-class AddrFrame
718  - represented by the struct _AddrFrame.
719  '''
720  def __init__(self, frametype, addrstring=None, port=None, Cstruct=None):
721  "Initializer for the pyAddrFrame object."
722  self._Cstruct = None # Keep error legs from complaining.
723  if Cstruct is None:
724  if isinstance(addrstring, pyNetAddr):
725  self._pyNetAddr = addrstring
726  else:
727  self._pyNetAddr = pyNetAddr(addrstring, port=port)
728  Cstruct = addrframe_new(frametype, 0)
729  if addrstring is not None:
730  Cstruct[0].setnetaddr(Cstruct, self._pyNetAddr._Cstruct)
731  else:
732  assert port is None
733  assert addrstring is None
734  # Allow for prefixed address type - two bytes
735  addrlen = Cstruct[0].baseclass.length - 2
736  assert addrlen == 4 or addrlen == 6 or addrlen == 8 or addrlen == 16 \
737  , ("addrlen is %d" % addrlen)
738  addrstr = Cstruct[0].baseclass.value+2
739  addrstring = create_string_buffer(addrlen)
740  memmove(addrstring, addrstr, addrlen)
741  self._pyNetAddr = pyNetAddr(addrstring, port=None)
742  pyFrame.__init__(self, frametype, Cstruct=Cstruct)
743 
744  def addrtype(self):
745  'Return the Address type for this AddrFrame'
746  return self._pyNetAddr.addrtype()
747 
748  def getnetaddr(self):
749  'Return the pyNetAddr for this AddrFrame'
750  return self._pyNetAddr
751 
752  def __str__(self):
753  return ("pyAddrFrame(%s, (%s))" \
754  % (FrameTypes.get(self.frametype())[1], str(self._pyNetAddr)))
755 
757  '''This class represents the Python version of our C-class IpPortFrame
758  - represented by the struct _IpPortFrame.
759  '''
760  def __init__(self, frametype, addrstring, port=None, Cstruct=None):
761  "Initializer for the pyIpPortFrame object."
762  self._Cstruct = None # Keep error legs from complaining.
763  if Cstruct is None:
764  if isinstance(addrstring, pyNetAddr):
765  self._pyNetAddr = addrstring
766  Cstruct = ipportframe_netaddr_new(frametype, addrstring._Cstruct)
767  if not Cstruct:
768  raise ValueError("invalid initializer")
769  self.port = addrstring.port()
770  else:
771  Cstruct = self._init_from_binary(frametype, addrstring, port)
772  else:
773  assert port is None
774  assert addrstring is None
775  addrlen = Cstruct[0].baseclass.length - 4 # Allow for prefixed port and address type
776  if addrlen != 4 and addrlen != 16:
777  raise ValueError("Bad addrlen: %d" % addrlen)
778  port = Cstruct[0].port
779  self.port = port
780  addrstr = Cstruct[0].baseclass.value+4
781  addrstring = create_string_buffer(addrlen)
782  memmove(addrstring, addrstr, addrlen)
783  self._pyNetAddr = pyNetAddr(addrstring, port=port)
784  pyFrame.__init__(self, frametype, Cstruct=Cstruct)
785 
786  def _init_from_binary(self, frametype, addrstring, port):
787  'Initialize a pyIpAddrFrame from a binary argument'
788  addrlen = len(addrstring)
789  self._pyNetAddr = pyNetAddr(addrstring, port=port)
790  if self._pyNetAddr is None:
791  raise ValueError("Invalid initializer.")
792  addrstr = create_string_buffer(addrlen)
793  for j in range(0, addrlen):
794  addrstr[j] = chr(addrstring[j])
795  if addrlen == 4:
796  Cstruct = ipportframe_ipv4_new(frametype, port, addrstr)
797  elif addrlen == 16:
798  Cstruct = ipportframe_ipv6_new(frametype, port, addrstr)
799  else:
800  raise ValueError('Bad address length: %d' % addrlen)
801  self.port = port
802  if port == 0:
803  raise ValueError("zero port")
804  if not Cstruct:
805  raise ValueError("invalid initializer")
806  return Cstruct
807 
808  def addrtype(self):
809  'Return the Address type of this pyIpPortFrame'
810  return self._pyNetAddr.addrtype()
811 
812  def getnetaddr(self):
813  'Return the NetAddr of this pyIpPortFrame'
814  return self._pyNetAddr
815 
816  def getport(self):
817  'Return the port of this pyIpPortFrame'
818  return self._pyNetAddr.port()
819 
820 
822  '''This class represents the Python version of our C-class CstringFrame
823  - represented by the struct _CstringFrame.
824  This class represents a Frame standard NUL-terminated C string.
825  '''
826  def __init__(self, frametype, initval=None, Cstruct=None):
827  '''Constructor for pyCstringFrame object - initial value should be something
828  that looks a lot like a Python string'''
829  if Cstruct is None:
830  Cstruct = cstringframe_new(frametype, 0)
831  pyFrame.__init__(self, frametype, Cstruct)
832  if initval is not None:
833  self.setvalue(initval)
834 
835  def getstr(self):
836  'Return the String part of this pyCstringFrame'
837  base = self._Cstruct[0]
838  while (not hasattr(base, 'value')):
839  base = base.baseclass
840  return string_at(base.value)
841 
843  '''This class represents the Python version of our IntFrame C-class
844  - represented by the struct _IntFrame.
845  This class represents an integer of 1, 2, 3, 4 or 8 bytes.
846  '''
847  def __init__(self, frametype, initval=None, intbytes=4, Cstruct=None):
848  '''Constructor for pyIntFrame object
849  - initial value should be something that looks a lot like an integer'''
850  self._Cstruct = None
851  if Cstruct is None:
852  Cstruct = intframe_new(frametype, intbytes)
853  if not Cstruct:
854  raise ValueError("Invalid integer size (%d) in pyIntFrame constructor" % intbytes)
855  pyFrame.__init__(self, frametype, Cstruct=Cstruct)
856  if initval is not None:
857  self.setint(initval)
858 
859  def __int__(self):
860  '''Return the integer value of this pyIntFrame. (implemented by the
861  underlying IntFrame object)'''
862  return self._Cstruct[0].getint(self._Cstruct)
863 
864  def __str__(self):
865  'Return a string representation of this pyIntFrame (the integer value).'
866  return ("pyIntFrame(%s, (%d))" % (FrameTypes.get(self.frametype())[1], int(self)))
867 
868  def getint(self):
869  'Return the integer value of this pyIntFrame - same as __int__.'
870  return int(self)
871 
872  def setint(self, intval):
873  '''Set the value of this pyIntFrame to the given integer value.
874  Note that this value is range checked by the underlying IntFrame implementation.
875  '''
876  self._Cstruct[0].setint(self._Cstruct, int(intval))
877 
878  def intlength(self):
879  '''Return the number of bytes in the integer underlying this pyIntFrame object.
880  (implemented by underlying IntFrame object)'''
881  return self._Cstruct[0].intlength(self._Cstruct)
882 
884  "Class for a Frame type we don't recognize"
885  def __init__(self, frametype, Cstruct=None):
886  'Initializer for pyUnknownFrame'
887  if Cstruct is None:
888  Cstruct = unknownframe_new(frametype)
889  pyFrame.__init__(self, frametype, Cstruct)
890 
892  'Class for a Sequence Number Frame - for reliable UDP packet transmission.'
893  def __init__(self, frametype, initval=None, Cstruct=None):
894  'Initializer for pySeqnoFrame'
895  self._Cstruct = None
896  # TODO(?): Need to allow for initialization of seqno frames.
897  if Cstruct is None:
898  Cstruct = seqnoframe_new(frametype, 0)
899  if not Cstruct:
900  raise ValueError("Constructor error for PySeqnoFrame()")
901  pyFrame.__init__(self, frametype, Cstruct=Cstruct)
902  if initval is not None:
903  self.setqid(initval[0])
904  self.setreqid(initval[1])
905 
906  def setreqid(self, reqid):
907  'Set the request ID portion of this SeqnoFrame'
908  self._Cstruct[0].setreqid(self._Cstruct, reqid)
909 
910  def setqid(self, qid):
911  'Set the Queue ID portion of this SeqnoFrame'
912  self._Cstruct[0].setqid(self._Cstruct, qid)
913 
914  def getreqid(self):
915  'Get the request ID portion of this SeqnoFrame'
916  return self._Cstruct[0].getreqid(self._Cstruct)
917 
918  def getqid(self):
919  'Get the Queue ID portion of this SeqnoFrame'
920  return self._Cstruct[0].getqid(self._Cstruct)
921 
922  def __eq__(self, rhs):
923  'Compare this pySeqnoFrame to another pySeqnoFrame'
924  lhsbase = self._Cstruct[0]
925  while (type(lhsbase) is not SeqnoFrame):
926  lhsbase = lhsbase.baseclass
927  return lhsbase.equal(self._Cstruct, rhs._Cstruct)
928 
929  def __str__(self):
930  'Convert this pySeqnoFrame to a String'
931  return ("pySeqNo(%s: (%d, %d))" \
932  % (FrameTypes.get(self.frametype())[1], self.getqid(), self.getreqid()))
933 
935  '''Class for Digital Signature Frames
936  - for authenticating data (subclasses will authenticate senders)'''
937  def __init__(self, gchecksumtype, Cstruct=None):
938  'Initializer for pySignFrame'
939  self._Cstruct = None
940  if Cstruct is None:
941  Cstruct = signframe_new(gchecksumtype, 0)
942  if not Cstruct:
943  raise ValueError("Invalid checksum type (%s) for PySignFrame()" % gchecksumtype)
944  pyFrame.__init__(self, initval=FRAMETYPE_SIG, Cstruct=Cstruct)
945 
947  'Class for a Frame containing a single name/value pair'
948  def __init__(self, frametype, name, value, Cstruct=None):
949  'Initializer for pyNVpairFrame'
950  self._Cstruct = None
951  if Cstruct is None:
952  Cstruct = nvpairframe_new(frametype, name, value, 0)
953  if not Cstruct:
954  raise ValueError("Invalid NVpair initializer for pyNVPairFrame()")
955  pyFrame.__init__(self, initval=frametype, Cstruct=Cstruct)
956 
957  def name(self):
958  'Return the name portion of a pyNVpairFrame'
959  return string_at(self._Cstruct[0].name)
960 
961  def value(self):
962  'Return the name portion of a pyNVpairFrame'
963  return string_at(self._Cstruct[0].value)
964 
965 
966 
967 #pylint: disable=R0921
969  'Class for Frame Sets - for collections of Frames making up a logical packet'
970  def __init__(self, framesettype, Cstruct=None):
971  'Initializer for pyFrameSet'
972  if Cstruct is None:
973  Cstruct = frameset_new(framesettype)
974  pyAssimObj.__init__(self, Cstruct=Cstruct)
975 
976  def append(self, frame):
977  'Append a frame to the end of a @ref FrameSet'
978  frameset_append_frame(self._Cstruct, frame._Cstruct)
979 
980  def prepend(self, frame):
981  'Prepend a frame before the first frame in a @ref FrameSet'
982  frameset_prepend_frame(self._Cstruct, frame._Cstruct)
983 
984  def construct_packet(self, signframe, cryptframe=None, compressframe=None):
985  'Construct packet from curent frameset + special prefix frames'
986  cf = None
987  cmpf = None
988  if cryptframe is not None:
989  cf = cryptframe._Cstruct
990  if compressframe is not None:
991  cmpf = compressframe._Cstruct
992  frameset_construct_packet(self._Cstruct, signframe._Cstruct, cf, cmpf)
993 
994  def get_framesettype(self):
995  'Return frameset type of this FrameSet'
996  return self._Cstruct[0].fstype
997 
998  def get_flags(self):
999  'Return current flags for this FrameSet'
1000  return frameset_get_flags(self._Cstruct)
1001 
1002  def set_flags(self, flags):
1003  "'OR' the given flags into the set of flags for this FrameSet"
1004  return frameset_set_flags(self._Cstruct, int(flags))
1005 
1006  def clear_flags(self, flags):
1007  "Clear the given flags for this FrameSet"
1008  return frameset_clear_flags(self._Cstruct, int(flags))
1009 
1010  def dump(self):
1011  'Dump out the given frameset'
1012  frameset_dump(self._Cstruct)
1013 
1014  def getpacket(self):
1015  'Return the constructed packet for this pyFrameSet'
1016  if not self._Cstruct[0].packet:
1017  raise ValueError("No packet constructed for frameset")
1018  return (self._Cstruct[0].packet, self._Cstruct[0].pktend)
1019 
1020  def __len__(self):
1021  'Return the number of Frames in this pyFrameSet'
1022  # This next statement OUGHT to work - and indeed it returns the right value
1023  # But somehow, 'self' doesn't get freed like it ought to :-(
1024  # BUG??
1025  #return g_slist_length(self._Cstruct[0].framelist)
1026  # So, let's do this instead...
1027  curframe = self._Cstruct[0].framelist
1028  count = 0
1029  while curframe:
1030  count += 1
1031  curframe = g_slist_next(curframe)
1032  return int(count)
1033 
1034  def __delitem__(self, key):
1035  "Fail - we don't implement this"
1036  raise NotImplementedError("FrameSet does not implement __delitem__()")
1037 
1038  def __getitem__(self, key):
1039  "Fail - we don't implement this"
1040  raise NotImplementedError("FrameSet does not implement __getitem__()")
1041 
1042  def __setitem__(self, key, value):
1043  "Fail - we don't implement this"
1044  raise NotImplementedError("FrameSet does not implement __setitem__()")
1045 
1046  def iter(self):
1047  'Generator yielding the set of pyFrames in this pyFrameSet'
1048  curframe = self._Cstruct[0].framelist
1049  while curframe:
1050  cast(curframe[0].data, struct__GSList._fields_[0][1])
1051  yieldval = pyFrame.Cstruct2Frame(cast(curframe[0].data, cClass.Frame))
1052  #print >> sys.stderr, ("Constructed frame IS [%s]" % str(yieldval))
1053  if not yieldval.isvalid():
1054  print >> sys.stderr \
1055  , "OOPS! Constructed %d byte frame from iter() is not valid [%s]" \
1056  % (yieldval.framelen(), str(yieldval))
1057  raise ValueError("Constructed %d byte frame from iter() is not valid [%s]"
1058  % (yieldval.framelen(), str(yieldval)))
1059  #print "Yielding:", str(yieldval), "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
1060  yield yieldval
1061  curframe = g_slist_next(curframe)
1062 
1063  def __str__(self):
1064  'Convert this pyFrameSet to a String'
1065  result = '%s:{' % FrameSetTypes.get(self.get_framesettype())[0]
1066  comma = ''
1067  for frame in self.iter():
1068  result += '%s[%d]%s' % (comma, frame.framelen(), str(frame))
1069  comma = ', '
1070  result += "}"
1071  return result
1072 
1073 
1075  'Class for Decoding packets - for returning an array of FrameSets from a physical packet.'
1076  def __init__(self, Cstruct=None):
1077  'Initializer for pyPacketDecoder'
1078  if Cstruct is None:
1079  Cstruct = packetdecoder_new(0, None, 0)
1080  pyAssimObj.__init__(self, Cstruct=Cstruct)
1081 
1082  def fslist_from_pktdata(self, pktlocation):
1083  'Make a list of FrameSets out of a packet.'
1084  base = self._Cstruct[0]
1085  while (type(base)is not PacketDecoder):
1086  base = base.baseclass
1087  fs_gslistint = base.pktdata_to_framesetlist(self._Cstruct, pktlocation[0], pktlocation[1])
1088  return pyPacketDecoder.fslist_to_pyfs_array(fs_gslistint)
1089 
1090  @staticmethod
1091  def fslist_to_pyfs_array(listheadint):
1092  'Converts a GSList of FrameSets to a python array of pyFrameSets'
1093  fs_gslist = cast(listheadint, cClass.GSList)
1094  frameset_list = []
1095  curfs = fs_gslist
1096  while curfs:
1097  cfs = cast(curfs[0].data, cClass.FrameSet)
1098  fs = pyFrameSet(None, Cstruct=cfs)
1099  frameset_list.append(fs)
1100  curfs = g_slist_next(curfs)
1101  g_slist_free(fs_gslist)
1102  return frameset_list
1103 
1104 # R0904: Too many public methods
1105 #pylint: disable=R0904
1107  'Class for Holding configuration information - now a general JSON-compatible data bag'
1108  #pylint: disable=R0921
1109 
1110  def __init__(self, init=None, filename=None, Cstruct=None):
1111  'Initializer for pyConfigContext'
1112  self._Cstruct = None # Keep error legs from complaining.
1113  if not Cstruct:
1114  # Cstruct overrides init and filename
1115  if filename is not None:
1116  f = open(filename, 'r')
1117  # filename overrides init
1118  init = f.read()
1119  f.close()
1120  if (isinstance(init, str) or isinstance(init, unicode)):
1121  Cstruct = configcontext_new_JSON_string(str(init))
1122  if not Cstruct:
1123  raise ValueError('Bad JSON [%s]' % str(init))
1124  init = None
1125  else:
1126  Cstruct = configcontext_new(0)
1127  pyAssimObj.__init__(self, Cstruct=Cstruct)
1128  if init is not None:
1129  for key in init.keys():
1130  self[key] = init[key]
1131 
1132 
1133  def getint(self, name):
1134  'Return the integer associated with "name"'
1135  return self._Cstruct[0].getint(self._Cstruct, name)
1136 
1137  def setint(self, name, value):
1138  'Set the integer associated with "name"'
1139  self._Cstruct[0].setint(self._Cstruct, name, value)
1140 
1141  def getbool(self, name):
1142  'Return the boolean associated with "name"'
1143  return self._Cstruct[0].getbool(self._Cstruct, name) != 0
1144 
1145  def setbool(self, name, value):
1146  'Set the boolean associated with "name"'
1147  self._Cstruct[0].setbool(self._Cstruct, name, bool(value))
1148 
1149  def getfloat(self, name):
1150  'Return the floating point value associated with "name"'
1151  return self._Cstruct[0].getfloat(self._Cstruct, name)
1152 
1153  def setfloat(self, name, value):
1154  'Set the floating point value associated with "name"'
1155  self._Cstruct[0].setfloat(self._Cstruct, name, float(value))
1156 
1157  def getaddr(self, name):
1158  'Return the NetAddr associated with "name"'
1159  naddr = self._Cstruct[0].getaddr(self._Cstruct, name)
1160  if naddr:
1161  naddr = cast(naddr, cClass.NetAddr)
1162  # We're creating a new reference to the pre-existing NetAddr
1163  CCref(naddr)
1164  return pyNetAddr(None, Cstruct=naddr)
1165  raise IndexError("No such NetAddr value [%s]" % name)
1166 
1167  def setaddr(self, name, value):
1168  'Set the @ref NetAddr associated with "name"'
1169  self._Cstruct[0].setaddr(self._Cstruct, name, value._Cstruct)
1170 
1171  def getframe(self, name):
1172  'Return the Frame associated with "name"'
1173  faddr = self._Cstruct[0].getframe(self._Cstruct, name)
1174  if faddr:
1175  # Cstruct2Frame already calls CCref()
1176  return pyFrame.Cstruct2Frame(faddr)
1177  raise IndexError("No such Frame value [%s]" % name)
1178 
1179  def setframe(self, name, value):
1180  'Set the @ref Frame associated with "name"'
1181  self._Cstruct[0].setframe(self._Cstruct, name, value._Cstruct)
1182 
1183  def getconfig(self, name):
1184  'Return the pyConfigContext object associated with "name"'
1185  caddr = self._Cstruct[0].getconfig(self._Cstruct, name)
1186  if caddr:
1187  caddr = cast(caddr, cClass.ConfigContext)
1188  # We're creating a new reference to the pre-existing NetAddr
1189  CCref(caddr)
1190  return pyConfigContext(Cstruct=caddr)
1191  raise IndexError("No such ConfigContext value [%s]" % name)
1192 
1193  def setconfig(self, name, value):
1194  'Set the @ref ConfigContext associated with "name"'
1195  self._Cstruct[0].setconfig(self._Cstruct, name, value._Cstruct)
1196 
1197  def getstring(self, name):
1198  'Return the string associated with "name"'
1199  ret = self._Cstruct[0].getstring(self._Cstruct, name)
1200  if ret:
1201  return string_at(ret)
1202  raise IndexError("No such String value [%s]" % name)
1203 
1204  def setstring(self, name, value):
1205  'Set the string associated with "name"'
1206  self._Cstruct[0].setstring(self._Cstruct, name, value)
1207 
1208  def getarray(self, name):
1209  'Return the array value associated with "name"'
1210  curlist = cast(self._Cstruct[0].getarray(self._Cstruct, name), cClass.GSList)
1211  #print >> sys.stderr, "CURLIST(initial) = %s" % curlist
1212  ret = []
1213  while curlist:
1214  #print >> sys.stderr, "CURLIST = %s" % curlist
1215  #cfgval = pyConfigValue(cast(cClass.ConfigValue, curlist[0].data).get())
1216  data = cast(curlist[0].data, cClass.ConfigValue)
1217  #print >> sys.stderr, "CURLIST->data = %s" % data
1218  CCref(data)
1219  cfgval = pyConfigValue(data).get()
1220  #print >> sys.stderr, "CURLIST->data->get() = %s" % cfgval
1221  ret.append(cfgval)
1222  curlist = g_slist_next(curlist)
1223  return ret
1224 
1225  def setarray(self, name, value):
1226  'Set a ConfigContext key value to be a sequence of values from an iterable'
1227  self._Cstruct[0].setarray(self._Cstruct, name, None)
1228  for elem in value:
1229  if isinstance(elem, (int, long)):
1230  self._Cstruct[0].appendint(self._Cstruct, name, elem)
1231  continue
1232  if isinstance(elem, bool):
1233  self._Cstruct[0].appendbool(self._Cstruct, name, elem)
1234  continue
1235  if isinstance(elem, float):
1236  self._Cstruct[0].appendfloat(self._Cstruct, name, elem)
1237  continue
1238  if isinstance(elem, str):
1239  self._Cstruct[0].appendstring(self._Cstruct, name, elem)
1240  continue
1241  if isinstance(elem, pyNetAddr):
1242  self._Cstruct[0].appendaddr(self._Cstruct, name, elem)
1243  continue
1244  if isinstance(elem, pyConfigContext):
1245  self._Cstruct[0].appendconfig(self._Cstruct, name, elem._Cstruct)
1246  continue
1247  if isinstance(elem, dict):
1248  cfgctx = pyConfigContext.from_dict(elem)
1249  self._Cstruct[0].appendconfig(self._Cstruct, name, cfgctx._Cstruct)
1250  continue
1251  raise ValueError("Cannot append/include array elements of type %s" % type(elem))
1252 
1253  @staticmethod
1254  def from_dict(dictval):
1255  'Construct a pyConfigContext from a dict-like object'
1256  newobj = pyConfigContext()
1257  for key in dictval.keys():
1258  keyval = dictval[key]
1259  if hasattr(keyval, 'keys'):
1260  keyval = pyConfigContext.from_dict(dictval[key])
1261  newobj[key] = dictval[key]
1262  return newobj
1263 
1264  def keys(self):
1265  'Return the set of keys for this object'
1266  l = []
1267  keylist = cast(self._Cstruct[0].keys(self._Cstruct), POINTER(GSList))
1268  curkey = keylist
1269  while curkey:
1270  l.append(string_at(curkey[0].data))
1271  curkey = g_slist_next(curkey)
1272  g_slist_free(keylist)
1273  return l
1274 
1275  def __iter__(self):
1276  'Iterate over self.keys()'
1277  for key in self.keys():
1278  yield key
1279 
1280  def gettype(self, name):
1281  '''Return the enumeration type of this particular key
1282  @todo Convert these enums to python types'''
1283  #print >> sys.stderr, 'gettype(%s)' % str(name)
1284  return self._Cstruct[0].gettype(self._Cstruct, str(name))
1285 
1286  def get(self, key, alternative=None):
1287  '''return value if object contains the given key - 'alternative' if not'''
1288  if self._Cstruct[0].gettype(self._Cstruct, str(key)) == CFG_EEXIST:
1289  return alternative
1290  return self[key]
1291 
1292  # pylint R0911: too many returns (9)
1293  # pylint: disable=R0911
1294  def deepget(self, key, alternative=None):
1295  '''return value if object contains the given *structured* key - 'alternative' if not'''
1296  try:
1297  (prefix, suffix) = key.split('.', 1)
1298  except ValueError:
1299  suffix = None
1300  prefix = key
1301  if prefix not in self:
1302  # Note that very similar code exists in GraphNodes get member function
1303  if not prefix.endswith(']'):
1304  return alternative
1305  else:
1306  # Looks like we have an array index
1307  proper = prefix[0:len(prefix)-1]
1308  try:
1309  (preprefix, idx) = proper.split('[', 1)
1310  except ValueError:
1311  return alternative
1312  if preprefix not in self:
1313  return alternative
1314  try:
1315  array = self[preprefix]
1316  idx = int(idx) # Possible ValueError
1317  value = array[idx] # possible IndexError or TypeError
1318  if suffix is None:
1319  return value
1320  except (TypeError, IndexError, ValueError):
1321  return alternative
1322  return value.deepget(suffix, alternative)
1323 
1324  prefixvalue = self[prefix]
1325  if suffix is None:
1326  return prefixvalue
1327  if not isinstance(prefixvalue, pyConfigContext):
1328  return alternative
1329  gotten = prefixvalue.deepget(suffix, alternative)
1330  return gotten
1331 
1332  def has_key(self, key):
1333  'return True if it has the given key'
1334  return self.__contains__(key)
1335 
1336  def __contains__(self, key):
1337  'return True if our object contains the given key'
1338  ktype = self._Cstruct[0].gettype(self._Cstruct, str(key))
1339  return ktype != CFG_EEXIST
1340 
1341  def __len__(self):
1342  'Return the number of items in this pyConfigContext'
1343  keylist = cast(self._Cstruct[0].keys(self._Cstruct), POINTER(GSList))
1344  llen = g_slist_length(keylist)
1345  g_slist_free(keylist)
1346  return llen
1347 
1348  def __delitem__(self, key):
1349  "Delete the given item"
1350  self._Cstruct[0].delkey(self._Cstruct, str(key))
1351 
1352  def __getitem__(self, name):
1353  'Return a value associated with "name"'
1354  ktype = self.gettype(name)
1355  ret = None
1356  #print >> sys.stderr, '************ GETITEM[%s] => %d *********************' % (name, ktype)
1357  if ktype == CFG_EEXIST:
1358  traceback.print_stack()
1359  raise IndexError("No such value [%s] in [%s]" % (name, str(self)))
1360  elif ktype == CFG_CFGCTX:
1361  ret = self.getconfig(name)
1362  elif ktype == CFG_STRING:
1363  ret = self.getstring(name)
1364  elif ktype == CFG_NETADDR:
1365  ret = self.getaddr(name)
1366  elif ktype == CFG_FRAME:
1367  ret = self.getframe(name)
1368  elif ktype == CFG_INT64:
1369  ret = self.getint(name)
1370  elif ktype == CFG_BOOL:
1371  ret = self.getbool(name)
1372  elif ktype == CFG_ARRAY:
1373  #print >> sys.stderr, '************ GETITEM[%s] => getarray(%s) *********************' \
1374  # % (name, name)
1375  ret = self.getarray(name)
1376  return ret
1377 
1378  def __setitem__(self, name, value):
1379  'Set a value associated with "name" - in the appropriate table'
1380  if isinstance(value, str):
1381  return self.setstring(name, value)
1382  if isinstance(value, pyNetAddr):
1383  return self.setaddr(name, value)
1384  if isinstance(value, pyFrame):
1385  return self.setframe(name, value)
1386  if isinstance(value, pyConfigContext):
1387  return self.setconfig(name, value)
1388  if isinstance(value, dict):
1389  return self.setconfig(name, pyConfigContext(value))
1390  if isinstance(value, (list, tuple)) or hasattr(value, '__iter__'):
1391  return self.setarray(name, value)
1392  if isinstance(value, float):
1393  return self.setfloat(name, value)
1394  if isinstance(value, dict):
1395  return self.setconfig(name, pyConfigContext.from_dict(value))
1396  self.setint(name, int(value))
1397 
1399  'A Python wrapper for a C implementation of something like a Python Dictionary'
1400  def __init__(self, Cstruct):
1401  'Initializer for pyConfigValue - now a subclass of pyAssimObj'
1402  pyAssimObj.__init__(self, Cstruct=Cstruct)
1403 
1404  def __str__(self):
1405  'Convert the given pyConfigValue to a String'
1406  str(self.get())
1407 
1408  def get(self):
1409  'Return the value of this object'
1410  ret = None
1411  vtype = self._Cstruct[0].valtype
1412  if vtype == CFG_BOOL:
1413  ret = self._Cstruct[0].u.intvalue != 0
1414  elif vtype == CFG_INT64:
1415  ret = int(self._Cstruct[0].u.intvalue)
1416  elif vtype == CFG_STRING:
1417  ret = str(self._Cstruct[0].u.strvalue)
1418  elif vtype == CFG_FLOAT:
1419  ret = float(self._Cstruct[0].u.floatvalue)
1420  elif vtype == CFG_CFGCTX:
1421  # We're creating a new reference to the pre-existing NetAddr
1422  CCref(self._Cstruct[0].u.cfgctxvalue)
1423  ret = pyConfigContext(Cstruct=self._Cstruct[0].u.cfgctxvalue)
1424  elif vtype == CFG_NETADDR:
1425  ret = pyNetAddr(None, Cstruct=self._Cstruct[0].u.addrvalue)
1426  # We're creating a new reference to the pre-existing NetAddr
1427  CCref(ret._Cstruct)
1428  elif vtype == CFG_FRAME:
1429  # Cstruct2Frame calls CCref() - so we don't need to
1430  ret = pyFrame.Cstruct2Frame(self._Cstruct[0].u.framevalue)
1431  elif vtype == CFG_ARRAY:
1432  # An Array is a linked list (GSList) of ConfigValue objects...
1433  ret = []
1434  this = self._Cstruct[0].u.arrayvalue
1435  while this:
1436  dataptr = cast(this[0].data, struct__GSList._fields_[0][1])
1437  dataptr = cast(dataptr, cClass.ConfigValue)
1438  CCref(dataptr)
1439  thisobj = pyConfigValue(cast(dataptr, cClass.ConfigValue)).get()
1440  ret.append(thisobj)
1441  this = g_slist_next(this)
1442  elif vtype == CFG_NULL:
1443  return None
1444  if ret is None:
1445  raise ValueError('Invalid valtype (%s)in pyConfigValue object' % self._Cstruct.valtype)
1446  return ret
1447 
1449  'A Network I/O object - with a variety of subclasses'
1450  def __init__(self, configobj, packetdecoder, Cstruct=None):
1451  'Initializer for pyNetIO'
1452  self._Cstruct = None # Keep error legs from complaining.
1453  if Cstruct is None:
1454  Cstruct = netio_new(0, configobj._Cstruct, packetdecoder._Cstruct)
1455  self.config = configobj
1456  else:
1457  self._Cstruct = Cstruct
1458  base = self._Cstruct[0]
1459  while (not hasattr(base, '_configinfo')):
1460  base = base.baseclass
1461  self.config = pyConfigContext(Cstruct=base._configinfo)
1462  CCref(base._configinfo)
1463  pyAssimObj.__init__(self, Cstruct=Cstruct)
1464 
1465  def setblockio(self, mode):
1466  'Set this NetIO object to blocking IO mode'
1467  base = self._Cstruct[0]
1468  while (not hasattr(base, 'setblockio')):
1469  base = base.baseclass
1470  return base.setblockio(self._Cstruct, int(mode))
1471 
1472  def fileno(self):
1473  'Return the file descriptor for this pyNetIO object'
1474  base = self._Cstruct[0]
1475  while (not hasattr(base, 'getfd')):
1476  base = base.baseclass
1477  return base.getfd(self._Cstruct)
1478 
1479  def bindaddr(self, addr, silent=False):
1480  'Bind the socket underneath this NetIO object to the given address'
1481  base = self._Cstruct[0]
1482  while (not hasattr(base, 'bindaddr')):
1483  base = base.baseclass
1484  return base.bindaddr(self._Cstruct, addr._Cstruct, silent)
1485 
1486  def boundaddr(self):
1487  'Return the socket underlying this NetIO object'
1488  base = self._Cstruct[0]
1489  while (not hasattr(base, 'bindaddr')):
1490  base = base.baseclass
1491  boundaddr = base.boundaddr(self._Cstruct)
1492  # We're creating a new reference to the pre-existing NetAddr
1493  ret = pyNetAddr(None, Cstruct=boundaddr)
1494  CCref(boundaddr)
1495  return ret
1496 
1497  def mcastjoin(self, addr):
1498  'Join the underlying socket to the given multicast address'
1499  base = self._Cstruct[0]
1500  while (not hasattr(base, 'mcastjoin')):
1501  base = base.baseclass
1502  return base.mcastjoin(self._Cstruct, addr._Cstruct, None)
1503 
1504  def getmaxpktsize(self):
1505  'Return the max packet size for this pyNetIO'
1506  base = self._Cstruct[0]
1507  while (not hasattr(base, 'getmaxpktsize')):
1508  base = base.baseclass
1509  return base.getmaxpktsize(self._Cstruct)
1510 
1511  def setmaxpktsize(self, size):
1512  'Set the max packet size for this pyNetIO'
1513  base = self._Cstruct[0]
1514  while (not hasattr(base, 'setmaxpktsize')):
1515  base = base.baseclass
1516  return base.setmaxpktsize(self._Cstruct, int(size))
1517 
1518  def compressframe(self):
1519  'Return the compression frame for this pyNetIO - may be None'
1520  # Doesn't make a py class object out of it yet...
1521  base = self._Cstruct[0]
1522  while (not hasattr(base, 'compressframe')):
1523  base = base.baseclass
1524  return base.compressframe(self._Cstruct)
1525 
1526  def cryptframe(self):
1527  'Return the encryption frame for this pyNetIO - may be None'
1528  # Doesn't make a py class object out of it yet...
1529  base = self._Cstruct[0]
1530  while (not hasattr(base, 'cryptframe')):
1531  base = base.baseclass
1532  return base.cryptframe(self._Cstruct)
1533 
1534  def signframe(self):
1535  'Return the digital signature frame for this pyNetIO'
1536  base = self._Cstruct[0]
1537  while (not hasattr(base, 'signframe')):
1538  base = base.baseclass
1539  return pySignFrame(0, Cstruct=cast(base.signframe(self._Cstruct), cClass.SignFrame))
1540 
1541  def sendframesets(self, destaddr, framesetlist):
1542  'Send the (collection of) frameset(s) out on this pyNetIO'
1543  if destaddr.port() == 0:
1544  raise ValueError("Zero Port in sendframesets: destaddr=%s" % str(destaddr))
1545  if not isinstance(framesetlist, collections.Sequence):
1546  framesetlist = (framesetlist, )
1547  base = self._Cstruct[0]
1548  while (not hasattr(base, 'sendaframeset')):
1549  base = base.baseclass
1550  # We ought to eventually construct a GSList of them and then call sendframesets
1551  # But this is easy for now...
1552  for frameset in framesetlist:
1553  base.sendaframeset(self._Cstruct, destaddr._Cstruct, frameset._Cstruct)
1554 
1555  def sendreliablefs(self, destaddr, framesetlist, qid = DEFAULT_FSP_QID):
1556  'Reliably send the (collection of) frameset(s) out on this pyNetIO (if possible)'
1557  if destaddr.port() == 0:
1558  raise ValueError("Zero Port in sendreliablefs: destaddr=%s" % str(destaddr))
1559  if not isinstance(framesetlist, collections.Sequence):
1560  framesetlist = (framesetlist, )
1561  base = self._Cstruct[0]
1562  while (not hasattr(base, 'sendaframeset')):
1563  base = base.baseclass
1564  for frameset in framesetlist:
1565  success = base.sendareliablefs(self._Cstruct, destaddr._Cstruct, qid, frameset._Cstruct)
1566  if not success:
1567  raise IOError("sendareliablefs(%s, %s) failed." % (destaddr, frameset))
1568 
1569  def ackmessage(self, destaddr, frameset):
1570  'ACK (acknowledge) this frameset - (presumably sent reliably).'
1571 
1572  base = self._Cstruct[0]
1573  while (not hasattr(base, 'ackmessage')):
1574  base = base.baseclass
1575  base.ackmessage(self._Cstruct, destaddr._Cstruct, frameset._Cstruct)
1576 
1577  def closeconn(self, qid, destaddr):
1578  'Close (reset) our connection to this address'
1579  base = self._Cstruct[0]
1580  while (not hasattr(base, 'closeconn')):
1581  base = base.baseclass
1582  print >> sys.stderr, ('CLOSING CONNECTION (closeconn) TO %s' % str(destaddr))
1583  base.closeconn(self._Cstruct, qid, destaddr._Cstruct)
1584 
1585  def addalias(self, fromaddr, toaddr):
1586  'Close (reset) our connection to this address'
1587 
1588  base = self._Cstruct[0]
1589  while (not hasattr(base, 'addalias')):
1590  base = base.baseclass
1591  base.addalias(self._Cstruct, fromaddr._Cstruct, toaddr._Cstruct)
1592 
1593  def recvframesets(self):
1594  '''Receive a collection of framesets read from this pyNetIO - all from the same Address.
1595  @return The return value is a tuple (address, framesetlist). '''
1596  #GSList * _netio_recvframesets (NetIO *self,NetAddr **src)
1597 
1598  base = self._Cstruct[0]
1599  while (not hasattr(base, 'recvframesets')):
1600  base = base.baseclass
1601  netaddrint = netaddr_ipv4_new(create_string_buffer(4), 101)
1602  netaddr = cast(netaddrint, cClass.NetAddr)
1603  netaddr[0].baseclass.unref(netaddr) # We're about to replace it...
1604  # Basically we needed a pointer to pass, and this seemed like a good way to do it...
1605  # Maybe it was -- maybe it wasn't... It's a pretty expensive way to get this effect...
1606  fs_gslistint = base.recvframesets(self._Cstruct, byref(netaddr))
1607  fslist = pyPacketDecoder.fslist_to_pyfs_array(fs_gslistint)
1608  if netaddr and len(fslist) > 0:
1609  # recvframesets gave us that 'netaddr' for us to dispose of - there are no other refs
1610  # to it so we should NOT 'CCref' it. It's a new object - not a pointer to an old one.
1611  address = pyNetAddr(None, Cstruct=netaddr)
1612  else:
1613  address = None
1614  return (address, fslist)
1615 
1616  @staticmethod
1618  'Return True if our OS supports a dual IPv4/IPv6 stack'
1620 
1622  'UDP version of the pyNetIO abstract base class'
1623  def __init__(self, config, packetdecoder, Cstruct=None):
1624  'Initializer for pyNetIOudp'
1625  self._Cstruct = None # Keep error legs from complaining.
1626  if Cstruct is None:
1627  Cstruct = netioudp_new(0, config._Cstruct, packetdecoder._Cstruct)
1628  if not Cstruct:
1629  raise ValueError("Invalid parameters to pyNetIOudp constructor")
1630  pyNetIO.__init__(self, config, packetdecoder, Cstruct=Cstruct)
1631 
1633  'Reliable UDP version of the pyNetIOudp abstract base class'
1634  def __init__(self, config, packetdecoder, rexmit_timer_uS=0, Cstruct=None):
1635  'Initializer for pyReliableUDP'
1636  self._Cstruct = None # Keep error legs from complaining.
1637  if Cstruct is None:
1638  Cstruct = reliableudp_new(0, config._Cstruct, packetdecoder._Cstruct, rexmit_timer_uS)
1639  if not Cstruct:
1640  raise ValueError("Invalid parameters to pyReliableUDP constructor")
1641  pyNetIOudp.__init__(self, config, packetdecoder, Cstruct=Cstruct)
1642 
1643  def log_conn(self, destaddr, qid=DEFAULT_FSP_QID):
1644  'Log connection status/info to system logs'
1645  base = self._Cstruct[0]
1646  while (type(base) is not ReliableUDP):
1647  base = base.baseclass
1648  base.log_conn(self._Cstruct, qid, destaddr._Cstruct)
1649 
1650 class CMAlib(object):
1651  'Miscellaneous functions to create certain useful pyFrameSets'
1652 
1653  def __init__(self):
1654  'Do-nothing init function'
1655  pass
1656 
1657  @staticmethod
1659  'Create a setconfig FrameSet'
1660  fs = cast(create_setconfig(cfg._Cstruct), cClass.FrameSet)
1661  return pyFrameSet(None, Cstruct=fs)
1662 
1663  @staticmethod
1664  def create_sendexpecthb(cfg, msgtype, address):
1665  'Create a Send/Expect heartbeat FrameSet'
1666  ucfs = create_sendexpecthb(cfg._Cstruct, int(msgtype)
1667  , address._Cstruct, 1)
1668  fs = cast(ucfs, cClass.FrameSet)
1669  return pyFrameSet(None, Cstruct=fs)
1670 
1672  'Dump out live objects to help locate memory leaks'
1673  print >> sys.stderr, 'GC Garbage: [%s]' % str(gc.garbage)
1674  print >> sys.stderr, '***************LOOKING FOR pyAssimObjs***********'
1675  get_referrers = True
1676  cobjcount = 0
1677  gc.collect()
1678  for obj in gc.get_objects():
1679  if isinstance(obj, (pyAssimObj, pyCstringFrame)):
1680  cobjcount += 1
1681  cobj = 'None'
1682  if hasattr(obj, '_Cstruct') and obj._Cstruct is not None:
1683  cobj = ('0x%x' % addressof(getattr(obj, '_Cstruct')[0]))
1684  print >> sys.stderr, ('FOUND C object class(%s): %s -> %s'
1685  % (obj.__class__.__name__, str(obj)[:512], cobj))
1686  if get_referrers:
1687  for referrer in gc.get_referrers(obj):
1688  print >> sys.stderr, ('++++Referred to by(%s): %s'
1689  % (type(referrer), str(referrer)[:512]))
1690 
1691  print >> sys.stderr, ('%d python wrappers referring to %d C-objects'
1692  % (cobjcount, proj_class_live_object_count()))
guint16 frameset_set_flags(FrameSet *fs, guint16 flagbits)
Set (OR in) the given set of FrameSet flags.
Definition: frameset.c:309
void frameset_dump(const FrameSet *fs)
Dump out a FrameSet.
Definition: frameset.c:355
ConfigContext * configcontext_new_JSON_string(const char *jsontext)
Construct a ConfigContext object from the given JSON string.
SeqnoFrame * seqnoframe_new(guint16 frametype, int objsize)
Construct new SeqnoFrame object.
Definition: seqnoframe.c:205
WINEXPORT AddrFrame * addrframe_new(guint16 frame_type, gsize framesize)
Construct a new AddrFrame class - allowing for "derived" frame types...
Definition: addrframe.c:201
guint16 frameset_get_flags(FrameSet *fs)
Return the flags currently set on this FrameSet.
Definition: frameset.c:301
guint16 frameset_clear_flags(FrameSet *fs, guint16 flagbits)
Clear the given set of FrameSet flags (& ~flagbits)
Definition: frameset.c:319
WINEXPORT gboolean is_valid_cdp_packet(const void *packet, const void *pktend)
Check to see if this is a valid CDP packet.
Definition: cdp_min.c:93
NetIOudp * netioudp_new(gsize objsize, ConfigContext *config, PacketDecoder *decoder)
Construct new UDP NetIO object (and its socket, etc)
Definition: netioudp.c:49
WINEXPORT IpPortFrame * ipportframe_ipv6_new(guint16 frame_type, guint16 port, gconstpointer addr)
Construct and initialize an IPv6 IpPortFrame class.
Definition: ipportframe.c:217
WINEXPORT IpPortFrame * ipportframe_netaddr_new(guint16 frame_type, NetAddr *addr)
Construct and initialize an IpPortFrame class from a IP NetAddr class.
Definition: ipportframe.c:234
NetAddr * netaddr_dns_new(const char *sysname_or_addr)
Create a NetAddr from a DNS name or an ipv4 or ipv6 constant string.
Definition: netaddr.c:943
IntFrame * intframe_new(guint16 frametype, int intbytes)
Construct new IntFrame object.
Definition: intframe.c:181
NetAddr * netaddr_mac64_new(gconstpointer macbuf)
Create new NetAddr from a MAC64 address.
Definition: netaddr.c:1017
FrameSet * frameset_new(guint16 frameset_type)
Construct a new frameset of the given type.
Definition: frameset.c:110
NetAddr * netaddr_ipv4_new(gconstpointer ipbuf, guint16 port)
Create new NetAddr from a IPv4 address.
Definition: netaddr.c:1024
UnknownFrame * unknownframe_new(guint16 frame_type)
Construct a new UnknownFrame - disallowing for "derived" frame types...
Definition: unknownframe.c:55
PacketDecoder * packetdecoder_new(guint objsize, const FrameTypeToFrame *framemap, gint mapsize)
Initialize our frame type map.
Definition: packetdecoder.c:76
NetAddr * netaddr_mac48_new(gconstpointer macbuf)
Create new NetAddr from a MAC48 address.
Definition: netaddr.c:1010
void frameset_append_frame(FrameSet *fs, Frame *f)
Append frame to the front of the end of the frame list.
Definition: frameset.c:143
guint8 get_lldptlv_type(const void *tlv_vp, const void *pktend)
Return the 'Type' of the given LLDP TLV entry The Type is the high order 7 bits from the zeroth byte ...
Definition: lldp_min.c:83
CompressFrame * compressframe_new(guint16 frame_type, guint16 compression_method)
Frame * frame_new(guint16 frame_type, gsize framesize)
Construct a new frame - allowing for "derived" frame types...
Definition: frame.c:124
gboolean netio_is_dual_ipv4v6_stack(void)
Definition: netio.c:750
void frameset_construct_packet(FrameSet *fs, SignFrame *sigframe, Frame *cryptframe, CompressFrame *compressframe)
Construct packet to go correspond to this frameset.
Definition: frameset.c:159
NetAddr * netaddr_ipv6_new(gconstpointer ipbuf, guint16 port)
Create new NetAddr from a IPv6 address.
Definition: netaddr.c:1032
guint32 proj_class_live_object_count(void)
Return the count of live C class objects.
Definition: proj_classes.c:406
SignFrame * signframe_new(GChecksumType sigtype, gsize framesize)
Construct a new SignFrame - allowing for "derived" frame types...
Definition: signframe.c:208
ReliableUDP * reliableudp_new(gsize objsize, ConfigContext *config, PacketDecoder *decoder, guint rexmit_timer_uS)
Construct new UDP NetIO object (and its socket, etc)
Definition: reliableudp.c:69
AssimObj * assimobj_new(guint objsize)
Definition: assimobj.c:74
const char * proj_class_classname(gconstpointer object)
Return the class name of one of our managed objects.
Definition: proj_classes.c:324
NVpairFrame * nvpairframe_new(guint16 frame_type, gchar *name, gchar *value, gsize framesize)
Construct a new NVpairFrame - allowing for "derived" frame types...
Definition: nvpairframe.c:97
const void * get_lldptlv_first(const void *packet, const void *pktend)
Definition: lldp_min.c:174
void frameset_prepend_frame(FrameSet *fs, Frame *f)
Prepend frame to the front of the frame list.
Definition: frameset.c:132
#define MALLOC(nbytes)
should it just call g_malloc?
Definition: projectcommon.h:26
gboolean is_valid_lldp_packet(const void *tlv_vp, const void *pktend)
Definition: lldp_min.c:116
WINEXPORT IpPortFrame * ipportframe_ipv4_new(guint16 frame_type, guint16 port, gconstpointer addr)
Construct and initialize an IPv4 IpPortFrame class.
Definition: ipportframe.c:199
NetIO * netio_new(gsize objsize, ConfigContext *config, PacketDecoder *decoder)
NetIO constructor.
Definition: netio.c:368
const void * get_lldptlv_next(const void *tlv_vp, const void *pktend)
Return pointer to the next LLDP TLV entry after the current location.
Definition: lldp_min.c:188
gsize get_lldptlv_len(const void *tlv_vp, const void *pktend)
Return the 'Length' of the given LLDP TLV entry.
Definition: lldp_min.c:93
void proj_class_dump_live_objects(void)
Dump all live C class objects (address and Class)
Definition: proj_classes.c:356
ConfigContext * configcontext_new(gsize objsize)
Construct a new ConfigContext object - with no values defaulted.
WINEXPORT CstringFrame * cstringframe_new(guint16 frame_type, gsize framesize)
Construct a new CstringFrame - allowing for "derived" frame types...
Definition: cstringframe.c:101
const void * get_lldptlv_body(const void *tlv_vp, const void *pktend)
Return the 'Value' of the given LLDP TLV entry.
Definition: lldp_min.c:106