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, (
320  'Found %d bytes of LLDP org-specific extensions (not processed)'
321  % tlvlen)
322 
323  if value is not None:
324  if tlvtype == LLDP_TLV_PID:
325  switchinfo['ports'][value] = thisportinfo
326  thisportinfo['PortId'] = value
327  numericpart = value
328  while len(numericpart) > 0 and not numericpart.isdigit():
329  numericpart = numericpart[1:]
330  if len > 0 and numericpart.isdigit():
331  thisportinfo['PORTNUM'] = int(numericpart)
332  else:
333  if isswitchinfo:
334  switchinfo[tlvname] = value
335  else:
336  thisportinfo[tlvname] = value
337  this = get_lldptlv_next(this, pktend)
338  thisportinfo['sourceMAC'] = sourcemac
339  return metadata
340 
341 
342  @staticmethod
343  def _decode_cdp(host, interface, wallclock, pktstart, pktend):
344  'Decode CDP packet into a JSON discovery packet'
345  thisportinfo = pyConfigContext(init={
346  'ConnectsToHost': host,
347  'ConnectsToInterface': interface,
348  }
349  )
350  switchinfo = pyConfigContext(init = {'ports': pyConfigContext()})
351  metadata = pyConfigContext(init={
352  'discovertype': '__LinkDiscovery',
353  'description': 'Link Level Switch Discovery (cdp)',
354  'source': '_decode_cdp()',
355  'host': host,
356  'localtime': str(wallclock),
357  'data': switchinfo,
358  }
359  )
360  thisportinfo = thisportinfo
361  pktstart = pktstart
362  pktend = pktend
363  return metadata
364 
365 
366 
367 
368 class pyAssimObj(object):
369  'The base object for all the C-class objects'
370  def __init__(self, Cstruct=None):
371  'Create a base pyAssimObj object'
372  self._Cstruct = None
373  if (Cstruct is not None):
374  assert type(Cstruct) is not int
375  self._Cstruct = Cstruct
376  else:
377  self._Cstruct = assimobj_new(0)
378  #print 'ASSIMOBJ:init: %s' % (Cstruct)
379 
380  def cclassname(self):
381  "Return the 'C' class name for this object"
382  return proj_class_classname(self._Cstruct)
383 
384  def __str__(self):
385  'Convert this AssimObj into a printable string'
386  if not self._Cstruct:
387  return "[None]"
388  base = self._Cstruct[0]
389  while (type(base) is not AssimObj):
390  base = base.baseclass
391  cstringret = cast(base.toString(self._Cstruct), c_char_p)
392  ret = string_at(cstringret)
393  g_free(cstringret)
394  return ret
395 
396  #pylint: disable=W0603
397  def __del__(self):
398  'Free up the underlying Cstruct for this pyAssimObj object.'
399  if not self._Cstruct or self._Cstruct is None:
400  return
401  # I have no idea why the type(base) is not Frame doesn't work here...
402  # This 'hasattr' construct only works because we are a base C-class
403  global badfree
404  badfree = 0
405  CCunref(self._Cstruct)
406  if badfree != 0:
407  print >> sys.stderr, "Attempt to free something already freed(%s)" % str(self._Cstruct)
408  traceback.print_stack()
409  badfree = 0
410  self._Cstruct = None
411 
412  def refcount(self):
413  'Return the reference count for this object'
414  base = self._Cstruct[0]
415  while (hasattr(base, 'baseclass')):
416  base = base.baseclass
417  return base._refcount
418 
420  '''This class represents the Python version of our C-class @ref NetAddr
421  - represented by the struct _NetAddr.
422  '''
423  def __init__(self, addrstring, port=None, Cstruct=None):
424  '''This constructor needs a list of integers of the right length as its first argument.
425  The length of the list determines the type of address generated.
426  4 bytes == ipv4
427  6 bytes == MAC address
428  8 bytes == MAC address
429  16 bytes == ipv6 address
430  This is slightly sleazy but it should work for the forseeable future.
431  '''
432 
433  self._Cstruct = None # Silence error messages in failure cases
434 
435  if (Cstruct is not None):
436  assert type(Cstruct) is not int
437  pyAssimObj.__init__(self, Cstruct=Cstruct)
438  if port is not None:
439  self.setport(port)
440  return
441 
442  if port is None:
443  port = 0
444 
445  if isinstance(addrstring, unicode) or isinstance(addrstring, pyNetAddr):
446  addrstring = str(addrstring)
447  if isinstance(addrstring, str):
448  cs = netaddr_dns_new(addrstring)
449  if not cs:
450  raise ValueError('Illegal NetAddr initial value: "%s"' % addrstring)
451  if port != 0:
452  cs[0].setport(cs, port)
453  pyAssimObj.__init__(self, Cstruct=cs)
454  return
455 
456  self._init_from_binary(addrstring, port)
457 
458  def _init_from_binary(self, addrstring, port):
459  'Initialize an addrstring from a binary argument'
460  alen = len(addrstring)
461  addr = create_string_buffer(alen)
462  #print >> sys.stderr, "ADDRTYPE:", type(addr)
463  #print >> sys.stderr, "ADDRSTRINGTYPE:", type(addrstring)
464  for i in range(0, alen):
465  asi = addrstring[i]
466  #print >> sys.stderr, "ASI_TYPE: (%s,%s)" % (type(asi), asi)
467  if type(asi) is str:
468  addr[i] = asi
469  elif type(asi) is unicode:
470  addr[i] = str(asi)
471  else:
472  addr[i] = chr(asi)
473  #print >> sys.stderr, 'ADDR = %s' % addr
474  if alen == 4: # ipv4
475  NA = netaddr_ipv4_new(addr, port)
476  pyAssimObj.__init__(self, Cstruct=NA)
477  elif alen == 16: # ipv6
478  pyAssimObj.__init__(self, netaddr_ipv6_new(addr, port))
479  elif alen == 6: # "Normal" 48-bit MAC address
480  assert port == 0
481  pyAssimObj.__init__(self, netaddr_mac48_new(addr, port))
482  elif alen == 8: # Extended 64-bit MAC address
483  assert port == 0
484  pyAssimObj.__init__(self, netaddr_mac64_new(addr, port))
485  else:
486  raise ValueError('Invalid address length - not 4, 6, 8, or 16')
487 
488  def port(self):
489  'Return the port (if any) for this pyNetAddr object'
490  base = self._Cstruct[0]
491  while (type(base) is not NetAddr):
492  base = base.baseclass
493  return base.port(self._Cstruct)
494 
495  def setport(self, port):
496  'Return the port (if any) for this pyNetAddr object'
497  base = self._Cstruct[0]
498  while (type(base) is not NetAddr):
499  base = base.baseclass
500  base.setport(self._Cstruct, port)
501 
502  def addrtype(self):
503  'Return the type of address for this pyNetAddr object'
504  base = self._Cstruct[0]
505  while (type(base) is not NetAddr):
506  base = base.baseclass
507  return base.addrtype(self._Cstruct)
508 
509  def addrlen(self):
510  "Return the number of bytes necessary to represent this pyNetAddr object on the wire."
511  base = self._Cstruct[0]
512  while (type(base) is not NetAddr):
513  base = base.baseclass
514  return base._addrlen
515 
516  def islocal(self):
517  'Return True if this address is a local address'
518  base = self._Cstruct[0]
519  while (type(base) is not NetAddr):
520  base = base.baseclass
521  return base.islocal(self._Cstruct)
522 
523  def isanyaddr(self):
524  'Return True if this address is a local address'
525  base = self._Cstruct[0]
526  while (type(base) is not NetAddr):
527  base = base.baseclass
528  return base.isanyaddr(self._Cstruct)
529 
530  def toIPv6(self, port=None):
531  'Return an equivalent IPv6 address to the one that was given. Guaranteed to be a copy'
532  base = self._Cstruct[0]
533  while (type(base) is not NetAddr):
534  base = base.baseclass
535  newcs = cast(base.toIPv6(self._Cstruct), cClass.NetAddr)
536  return pyNetAddr(None, Cstruct=newcs, port=port)
537 
538  def __repr__(self):
539  'Return a canonical representation of this NetAddr'
540  base = self._Cstruct[0]
541  while (type(base) is not NetAddr):
542  base = base.baseclass
543  cstringret = base.canonStr(self._Cstruct)
544  ret = string_at(cstringret)
545  g_free(cstringret)
546  return ret
547 
548 
549  def __eq__(self, other):
550  "Return True if the two pyNetAddrs are equal"
551  if not other._Cstruct or not self._Cstruct:
552  return False
553  base = self._Cstruct[0]
554  while (type(base) is not NetAddr):
555  base = base.baseclass
556  return base.equal(self._Cstruct, other._Cstruct)
557 
558  def __hash__(self):
559  'Return a hash value for the given pyNetAddr'
560  if not self._Cstruct:
561  return 0
562  base = self._Cstruct[0]
563  while (type(base) is not NetAddr):
564  base = base.baseclass
565  return base.hash(self._Cstruct)
566 
567 
569  '''This class represents the Python version of our C-class @ref Frame
570  - represented by the struct _Frame.
571  This class is a base class for several different pyFrame subclasses.
572  Each of these various pyFrame subclasses have a corresponding C-class @ref Frame subclass.
573  The purpose of these pyFrames and their subclasses is to talk on the wire with our C code in our
574  nanoprobes.
575 
576  Deliberately leaving out the updatedata() C-class member function - at least for now.
577  I suspect that the Python code will only need the corresponding calls in a @ref FrameSet
578  - which would then update the corresponding @ref Frame member functions...
579  '''
580  #
581  # Our subclasses need to implement these methods:
582  # __init__ - subclass initializer
583  # from_Cstruct classmethod - call the corresponding xxxframe_tlvconstructor() function
584  # to act as a pseudo-constructor. This method/constructor is used to create
585  # Python objects from incoming packet data.
586  #
587  def __init__(self, initval, Cstruct=None):
588  "Initializer for the pyFrame object."
589  if Cstruct is None:
590  try:
591  frametype = initval.tlvtype
592  except(AttributeError):
593  frametype = int(initval)
594  # If we don't do this, then a subclass __init__ function must do it instead...
595  pyAssimObj.__init__(self, Cstruct=frame_new(frametype, 0))
596  else:
597  pyAssimObj.__init__(self, Cstruct=Cstruct)
598 
599  def frametype(self):
600  "Return the TLV type for the pyFrame object."
601  base = self._Cstruct[0]
602  while (type(base)is not Frame):
603  base = base.baseclass
604  return base.type
605 
606  def framelen(self):
607  "Return the length of this frame in bytes (TLV length)."
608  base = self._Cstruct[0]
609  while (type(base)is not Frame):
610  base = base.baseclass
611  return base.length
612 
613  def framevalue(self):
614  'Return a C-style pointer to the underlying raw TLV data (if any)'
615  base = self._Cstruct[0]
616  while (type(base)is not Frame):
617  base = base.baseclass
618  return cast(base.value, c_char_p)
619 
620  def frameend(self):
621  'Return a C-style pointer to the underlying raw TLV data (if any)'
622  base = self._Cstruct[0]
623  while (type(base)is not Frame):
624  base = base.baseclass
625  return cast(base.value+base.length, c_char_p)
626 
627  def dataspace(self):
628  'Return the amount of space this frame needs - including type and length'
629  base = self._Cstruct[0]
630  while (type(base) is not Frame):
631  base = base.baseclass
632  return base.dataspace(self._Cstruct)
633 
634  def isvalid(self):
635  "Return True if this Frame is valid"
636  base = self._Cstruct[0]
637  while (type(base) is not Frame):
638  base = base.baseclass
639 # pstart = pointer(cast(base.value, c_char_p))
640 # if pstart[0] is None:
641 # return False
642  return (int(base.isvalid(self._Cstruct, None, None)) != 0)
643 
644  def setvalue(self, value):
645  'Assign a chunk of memory to the Value portion of this Frame'
646  vlen = len(value)
647  if type(value) is str:
648  valbuf = create_string_buffer(vlen+1)
649  for i in range(0, vlen):
650  vi = value[i]
651  valbuf[i] = vi
652  valbuf[vlen] = chr(0)
653  vlen += 1
654  else:
655  valbuf = create_string_buffer(vlen)
656  for i in range(0, vlen):
657  vi = value[i]
658  valbuf[i] = int(vi)
659  base = self._Cstruct[0]
660  valptr = MALLOC(vlen)
661  memmove(valptr, valbuf, vlen)
662  while (type(base) is not Frame):
663  base = base.baseclass
664  base.setvalue(self._Cstruct, valptr, vlen, cast(None, GDestroyNotify))
665 
666  def dump(self, prefix):
667  'Dump out this Frame (using C-class "dump" member function)'
668  base = self._Cstruct[0]
669  while (type(base) is not Frame):
670  base = base.baseclass
671  base.dump(self._Cstruct, cast(prefix, c_char_p))
672 
673  def __str__(self):
674  'Convert this Frame to a string'
675  base = self._Cstruct[0]
676  while (type(base) is not AssimObj):
677  base = base.baseclass
678  cstringret = cast(base.toString(self._Cstruct), c_char_p)
679  ret = string_at(cstringret)
680  g_free(cstringret)
681  return '%s: %s' % (FrameTypes.get(self.frametype())[1] , ret)
682 
683  @staticmethod
684  def Cstruct2Frame(frameptr):
685  'Unmarshalls a binary blob (Cstruct) into a Frame'
686  frameptr = cast(frameptr, cClass.Frame)
687  CCref(frameptr)
688  frametype = frameptr[0].type
689  Cclassname = proj_class_classname(frameptr)
690  pyclassname = "py" + Cclassname
691  if Cclassname == 'NetAddr':
692  statement = "%s(%d, None, Cstruct=cast(frameptr, cClass.%s))" \
693  % (pyclassname, frametype, Cclassname)
694  elif Cclassname == Cclassname == 'IpPortFrame':
695  statement = "%s(%d, None, None, Cstruct=cast(frameptr, cClass.%s))" \
696  % (pyclassname, frametype, Cclassname)
697  else:
698  statement = "%s(%d, Cstruct=cast(frameptr, cClass.%s))" \
699  % (pyclassname, frametype, Cclassname)
700  #print >> sys.stderr, "EVAL:", statement
701  return eval(statement)
702 
704  '''This class represents the Python version of our C-class CompressFrame
705  - represented by the struct _CompressFrame. It is used to tell us that
706  what kind of compression we want in our communication stream.
707  '''
708  def __init__(self, frametype=FRAMETYPE_COMPRESS, compression_method=COMPRESS_ZLIB
709  , Cstruct=None):
710  self._Cstruct = None # Keep error legs from complaining.
711  if Cstruct is None:
712  self._Cstruct = compressframe_new(frametype, compression_method)
713  else:
714  self._Cstruct = Cstruct
715  pyFrame.__init__(self, frametype, Cstruct=Cstruct)
716 
717 
719  '''This class represents the Python version of our C-class AddrFrame
720  - represented by the struct _AddrFrame.
721  '''
722  def __init__(self, frametype, addrstring=None, port=None, Cstruct=None):
723  "Initializer for the pyAddrFrame object."
724  self._Cstruct = None # Keep error legs from complaining.
725  if Cstruct is None:
726  if isinstance(addrstring, pyNetAddr):
727  self._pyNetAddr = addrstring
728  else:
729  self._pyNetAddr = pyNetAddr(addrstring, port=port)
730  Cstruct = addrframe_new(frametype, 0)
731  if addrstring is not None:
732  Cstruct[0].setnetaddr(Cstruct, self._pyNetAddr._Cstruct)
733  else:
734  assert port is None
735  assert addrstring is None
736  # Allow for prefixed address type - two bytes
737  addrlen = Cstruct[0].baseclass.length - 2
738  assert addrlen == 4 or addrlen == 6 or addrlen == 8 or addrlen == 16 \
739  , ("addrlen is %d" % addrlen)
740  addrstr = Cstruct[0].baseclass.value+2
741  addrstring = create_string_buffer(addrlen)
742  memmove(addrstring, addrstr, addrlen)
743  self._pyNetAddr = pyNetAddr(addrstring, port=None)
744  pyFrame.__init__(self, frametype, Cstruct=Cstruct)
745 
746  def addrtype(self):
747  'Return the Address type for this AddrFrame'
748  return self._pyNetAddr.addrtype()
749 
750  def getnetaddr(self):
751  'Return the pyNetAddr for this AddrFrame'
752  return self._pyNetAddr
753 
754  def __str__(self):
755  return ("pyAddrFrame(%s, (%s))" \
756  % (FrameTypes.get(self.frametype())[1], str(self._pyNetAddr)))
757 
759  '''This class represents the Python version of our C-class IpPortFrame
760  - represented by the struct _IpPortFrame.
761  '''
762  def __init__(self, frametype, addrstring, port=None, Cstruct=None):
763  "Initializer for the pyIpPortFrame object."
764  self._Cstruct = None # Keep error legs from complaining.
765  if Cstruct is None:
766  if isinstance(addrstring, pyNetAddr):
767  self._pyNetAddr = addrstring
768  Cstruct = ipportframe_netaddr_new(frametype, addrstring._Cstruct)
769  if not Cstruct:
770  raise ValueError("invalid initializer")
771  self.port = addrstring.port()
772  else:
773  Cstruct = self._init_from_binary(frametype, addrstring, port)
774  else:
775  assert port is None
776  assert addrstring is None
777  addrlen = Cstruct[0].baseclass.length - 4 # Allow for prefixed port and address type
778  if addrlen != 4 and addrlen != 16:
779  raise ValueError("Bad addrlen: %d" % addrlen)
780  port = Cstruct[0].port
781  self.port = port
782  addrstr = Cstruct[0].baseclass.value+4
783  addrstring = create_string_buffer(addrlen)
784  memmove(addrstring, addrstr, addrlen)
785  self._pyNetAddr = pyNetAddr(addrstring, port=port)
786  pyFrame.__init__(self, frametype, Cstruct=Cstruct)
787 
788  def _init_from_binary(self, frametype, addrstring, port):
789  'Initialize a pyIpAddrFrame from a binary argument'
790  addrlen = len(addrstring)
791  self._pyNetAddr = pyNetAddr(addrstring, port=port)
792  if self._pyNetAddr is None:
793  raise ValueError("Invalid initializer.")
794  addrstr = create_string_buffer(addrlen)
795  for j in range(0, addrlen):
796  addrstr[j] = chr(addrstring[j])
797  if addrlen == 4:
798  Cstruct = ipportframe_ipv4_new(frametype, port, addrstr)
799  elif addrlen == 16:
800  Cstruct = ipportframe_ipv6_new(frametype, port, addrstr)
801  else:
802  raise ValueError('Bad address length: %d' % addrlen)
803  self.port = port
804  if port == 0:
805  raise ValueError("zero port")
806  if not Cstruct:
807  raise ValueError("invalid initializer")
808  return Cstruct
809 
810  def addrtype(self):
811  'Return the Address type of this pyIpPortFrame'
812  return self._pyNetAddr.addrtype()
813 
814  def getnetaddr(self):
815  'Return the NetAddr of this pyIpPortFrame'
816  return self._pyNetAddr
817 
818  def getport(self):
819  'Return the port of this pyIpPortFrame'
820  return self._pyNetAddr.port()
821 
822 
824  '''This class represents the Python version of our C-class CstringFrame
825  - represented by the struct _CstringFrame.
826  This class represents a Frame standard NUL-terminated C string.
827  '''
828  def __init__(self, frametype, initval=None, Cstruct=None):
829  '''Constructor for pyCstringFrame object - initial value should be something
830  that looks a lot like a Python string'''
831  if Cstruct is None:
832  Cstruct = cstringframe_new(frametype, 0)
833  pyFrame.__init__(self, frametype, Cstruct)
834  if initval is not None:
835  self.setvalue(initval)
836 
837  def getstr(self):
838  'Return the String part of this pyCstringFrame'
839  base = self._Cstruct[0]
840  while (not hasattr(base, 'value')):
841  base = base.baseclass
842  return string_at(base.value)
843 
845  '''This class represents the Python version of our IntFrame C-class
846  - represented by the struct _IntFrame.
847  This class represents an integer of 1, 2, 3, 4 or 8 bytes.
848  '''
849  def __init__(self, frametype, initval=None, intbytes=4, Cstruct=None):
850  '''Constructor for pyIntFrame object
851  - initial value should be something that looks a lot like an integer'''
852  self._Cstruct = None
853  if Cstruct is None:
854  Cstruct = intframe_new(frametype, intbytes)
855  if not Cstruct:
856  raise ValueError("Invalid integer size (%d) in pyIntFrame constructor" % intbytes)
857  pyFrame.__init__(self, frametype, Cstruct=Cstruct)
858  if initval is not None:
859  self.setint(initval)
860 
861  def __int__(self):
862  '''Return the integer value of this pyIntFrame. (implemented by the
863  underlying IntFrame object)'''
864  return self._Cstruct[0].getint(self._Cstruct)
865 
866  def __str__(self):
867  'Return a string representation of this pyIntFrame (the integer value).'
868  return ("pyIntFrame(%s, (%d))" % (FrameTypes.get(self.frametype())[1], int(self)))
869 
870  def getint(self):
871  'Return the integer value of this pyIntFrame - same as __int__.'
872  return int(self)
873 
874  def setint(self, intval):
875  '''Set the value of this pyIntFrame to the given integer value.
876  Note that this value is range checked by the underlying IntFrame implementation.
877  '''
878  self._Cstruct[0].setint(self._Cstruct, int(intval))
879 
880  def intlength(self):
881  '''Return the number of bytes in the integer underlying this pyIntFrame object.
882  (implemented by underlying IntFrame object)'''
883  return self._Cstruct[0].intlength(self._Cstruct)
884 
886  "Class for a Frame type we don't recognize"
887  def __init__(self, frametype, Cstruct=None):
888  'Initializer for pyUnknownFrame'
889  if Cstruct is None:
890  Cstruct = unknownframe_new(frametype)
891  pyFrame.__init__(self, frametype, Cstruct)
892 
894  'Class for a Sequence Number Frame - for reliable UDP packet transmission.'
895  def __init__(self, frametype, initval=None, Cstruct=None):
896  'Initializer for pySeqnoFrame'
897  self._Cstruct = None
898  # TODO(?): Need to allow for initialization of seqno frames.
899  if Cstruct is None:
900  Cstruct = seqnoframe_new(frametype, 0)
901  if not Cstruct:
902  raise ValueError("Constructor error for PySeqnoFrame()")
903  pyFrame.__init__(self, frametype, Cstruct=Cstruct)
904  if initval is not None:
905  self.setqid(initval[0])
906  self.setreqid(initval[1])
907 
908  def setreqid(self, reqid):
909  'Set the request ID portion of this SeqnoFrame'
910  self._Cstruct[0].setreqid(self._Cstruct, reqid)
911 
912  def setqid(self, qid):
913  'Set the Queue ID portion of this SeqnoFrame'
914  self._Cstruct[0].setqid(self._Cstruct, qid)
915 
916  def getreqid(self):
917  'Get the request ID portion of this SeqnoFrame'
918  return self._Cstruct[0].getreqid(self._Cstruct)
919 
920  def getqid(self):
921  'Get the Queue ID portion of this SeqnoFrame'
922  return self._Cstruct[0].getqid(self._Cstruct)
923 
924  def __eq__(self, rhs):
925  'Compare this pySeqnoFrame to another pySeqnoFrame'
926  lhsbase = self._Cstruct[0]
927  while (type(lhsbase) is not SeqnoFrame):
928  lhsbase = lhsbase.baseclass
929  return lhsbase.equal(self._Cstruct, rhs._Cstruct)
930 
931  def __str__(self):
932  'Convert this pySeqnoFrame to a String'
933  return ("pySeqNo(%s: (%d, %d))" \
934  % (FrameTypes.get(self.frametype())[1], self.getqid(), self.getreqid()))
935 
937  '''Class for Digital Signature Frames
938  - for authenticating data (subclasses will authenticate senders)'''
939  def __init__(self, gchecksumtype, Cstruct=None):
940  'Initializer for pySignFrame'
941  self._Cstruct = None
942  if Cstruct is None:
943  Cstruct = signframe_new(gchecksumtype, 0)
944  if not Cstruct:
945  raise ValueError("Invalid checksum type (%s) for PySignFrame()" % gchecksumtype)
946  pyFrame.__init__(self, initval=FRAMETYPE_SIG, Cstruct=Cstruct)
947 
949  'Class for a Frame containing a single name/value pair'
950  def __init__(self, frametype, name, value, Cstruct=None):
951  'Initializer for pyNVpairFrame'
952  self._Cstruct = None
953  if Cstruct is None:
954  Cstruct = nvpairframe_new(frametype, name, value, 0)
955  if not Cstruct:
956  raise ValueError("Invalid NVpair initializer for pyNVPairFrame()")
957  pyFrame.__init__(self, initval=frametype, Cstruct=Cstruct)
958 
959  def name(self):
960  'Return the name portion of a pyNVpairFrame'
961  return string_at(self._Cstruct[0].name)
962 
963  def value(self):
964  'Return the name portion of a pyNVpairFrame'
965  return string_at(self._Cstruct[0].value)
966 
967 
968 
969 #pylint: disable=R0921
971  'Class for Frame Sets - for collections of Frames making up a logical packet'
972  def __init__(self, framesettype, Cstruct=None):
973  'Initializer for pyFrameSet'
974  if Cstruct is None:
975  Cstruct = frameset_new(framesettype)
976  pyAssimObj.__init__(self, Cstruct=Cstruct)
977 
978  def append(self, frame):
979  'Append a frame to the end of a @ref FrameSet'
980  frameset_append_frame(self._Cstruct, frame._Cstruct)
981 
982  def prepend(self, frame):
983  'Prepend a frame before the first frame in a @ref FrameSet'
984  frameset_prepend_frame(self._Cstruct, frame._Cstruct)
985 
986  def construct_packet(self, signframe, cryptframe=None, compressframe=None):
987  'Construct packet from curent frameset + special prefix frames'
988  cf = None
989  cmpf = None
990  if cryptframe is not None:
991  cf = cryptframe._Cstruct
992  if compressframe is not None:
993  cmpf = compressframe._Cstruct
994  frameset_construct_packet(self._Cstruct, signframe._Cstruct, cf, cmpf)
995 
996  def get_framesettype(self):
997  'Return frameset type of this FrameSet'
998  return self._Cstruct[0].fstype
999 
1000  def get_flags(self):
1001  'Return current flags for this FrameSet'
1002  return frameset_get_flags(self._Cstruct)
1003 
1004  def set_flags(self, flags):
1005  "'OR' the given flags into the set of flags for this FrameSet"
1006  return frameset_set_flags(self._Cstruct, int(flags))
1007 
1008  def clear_flags(self, flags):
1009  "Clear the given flags for this FrameSet"
1010  return frameset_clear_flags(self._Cstruct, int(flags))
1011 
1012  def dump(self):
1013  'Dump out the given frameset'
1014  frameset_dump(self._Cstruct)
1015 
1016  def getpacket(self):
1017  'Return the constructed packet for this pyFrameSet'
1018  if not self._Cstruct[0].packet:
1019  raise ValueError("No packet constructed for frameset")
1020  return (self._Cstruct[0].packet, self._Cstruct[0].pktend)
1021 
1022  def __len__(self):
1023  'Return the number of Frames in this pyFrameSet'
1024  # This next statement OUGHT to work - and indeed it returns the right value
1025  # But somehow, 'self' doesn't get freed like it ought to :-(
1026  # BUG??
1027  #return g_slist_length(self._Cstruct[0].framelist)
1028  # So, let's do this instead...
1029  curframe = self._Cstruct[0].framelist
1030  count = 0
1031  while curframe:
1032  count += 1
1033  curframe = g_slist_next(curframe)
1034  return int(count)
1035 
1036  def __delitem__(self, key):
1037  "Fail - we don't implement this"
1038  raise NotImplementedError("FrameSet does not implement __delitem__()")
1039 
1040  def __getitem__(self, key):
1041  "Fail - we don't implement this"
1042  raise NotImplementedError("FrameSet does not implement __getitem__()")
1043 
1044  def __setitem__(self, key, value):
1045  "Fail - we don't implement this"
1046  raise NotImplementedError("FrameSet does not implement __setitem__()")
1047 
1048  def iter(self):
1049  'Generator yielding the set of pyFrames in this pyFrameSet'
1050  curframe = self._Cstruct[0].framelist
1051  while curframe:
1052  cast(curframe[0].data, struct__GSList._fields_[0][1])
1053  yieldval = pyFrame.Cstruct2Frame(cast(curframe[0].data, cClass.Frame))
1054  #print >> sys.stderr, ("Constructed frame IS [%s]" % str(yieldval))
1055  if not yieldval.isvalid():
1056  print >> sys.stderr \
1057  , "OOPS! Constructed %d byte frame from iter() is not valid [%s]" \
1058  % (yieldval.framelen(), str(yieldval))
1059  raise ValueError("Constructed %d byte frame from iter() is not valid [%s]"
1060  % (yieldval.framelen(), str(yieldval)))
1061  #print "Yielding:", str(yieldval), "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
1062  yield yieldval
1063  curframe = g_slist_next(curframe)
1064 
1065  def __str__(self):
1066  'Convert this pyFrameSet to a String'
1067  result = '%s:{' % FrameSetTypes.get(self.get_framesettype())[0]
1068  comma = ''
1069  for frame in self.iter():
1070  result += '%s[%d]%s' % (comma, frame.framelen(), str(frame))
1071  comma = ', '
1072  result += "}"
1073  return result
1074 
1075 
1077  'Class for Decoding packets - for returning an array of FrameSets from a physical packet.'
1078  def __init__(self, Cstruct=None):
1079  'Initializer for pyPacketDecoder'
1080  if Cstruct is None:
1081  Cstruct = packetdecoder_new(0, None, 0)
1082  pyAssimObj.__init__(self, Cstruct=Cstruct)
1083 
1084  def fslist_from_pktdata(self, pktlocation):
1085  'Make a list of FrameSets out of a packet.'
1086  base = self._Cstruct[0]
1087  while (type(base)is not PacketDecoder):
1088  base = base.baseclass
1089  fs_gslistint = base.pktdata_to_framesetlist(self._Cstruct, pktlocation[0], pktlocation[1])
1090  return pyPacketDecoder.fslist_to_pyfs_array(fs_gslistint)
1091 
1092  @staticmethod
1093  def fslist_to_pyfs_array(listheadint):
1094  'Converts a GSList of FrameSets to a python array of pyFrameSets'
1095  fs_gslist = cast(listheadint, cClass.GSList)
1096  frameset_list = []
1097  curfs = fs_gslist
1098  while curfs:
1099  cfs = cast(curfs[0].data, cClass.FrameSet)
1100  fs = pyFrameSet(None, Cstruct=cfs)
1101  frameset_list.append(fs)
1102  curfs = g_slist_next(curfs)
1103  g_slist_free(fs_gslist)
1104  return frameset_list
1105 
1106 # R0904: Too many public methods
1107 #pylint: disable=R0904
1109  'Class for Holding configuration information - now a general JSON-compatible data bag'
1110  #pylint: disable=R0921
1111 
1112  def __init__(self, init=None, filename=None, Cstruct=None):
1113  'Initializer for pyConfigContext'
1114  self._Cstruct = None # Keep error legs from complaining.
1115  if not Cstruct:
1116  # Cstruct overrides init and filename
1117  if filename is not None:
1118  f = open(filename, 'r')
1119  # filename overrides init
1120  init = f.read()
1121  f.close()
1122  if (isinstance(init, str) or isinstance(init, unicode)):
1123  Cstruct = configcontext_new_JSON_string(str(init))
1124  if not Cstruct:
1125  raise ValueError('Bad JSON [%s]' % str(init))
1126  init = None
1127  else:
1128  Cstruct = configcontext_new(0)
1129  pyAssimObj.__init__(self, Cstruct=Cstruct)
1130  if init is not None:
1131  for key in init.keys():
1132  self[key] = init[key]
1133 
1134 
1135  def getint(self, name):
1136  'Return the integer associated with "name"'
1137  return self._Cstruct[0].getint(self._Cstruct, name)
1138 
1139  def setint(self, name, value):
1140  'Set the integer associated with "name"'
1141  self._Cstruct[0].setint(self._Cstruct, name, value)
1142 
1143  def getbool(self, name):
1144  'Return the boolean associated with "name"'
1145  return self._Cstruct[0].getbool(self._Cstruct, name) != 0
1146 
1147  def setbool(self, name, value):
1148  'Set the boolean associated with "name"'
1149  self._Cstruct[0].setbool(self._Cstruct, name, bool(value))
1150 
1151  def getfloat(self, name):
1152  'Return the floating point value associated with "name"'
1153  return self._Cstruct[0].getfloat(self._Cstruct, name)
1154 
1155  def setfloat(self, name, value):
1156  'Set the floating point value associated with "name"'
1157  self._Cstruct[0].setfloat(self._Cstruct, name, float(value))
1158 
1159  def getaddr(self, name):
1160  'Return the NetAddr associated with "name"'
1161  naddr = self._Cstruct[0].getaddr(self._Cstruct, name)
1162  if naddr:
1163  naddr = cast(naddr, cClass.NetAddr)
1164  # We're creating a new reference to the pre-existing NetAddr
1165  CCref(naddr)
1166  return pyNetAddr(None, Cstruct=naddr)
1167  raise IndexError("No such NetAddr value [%s]" % name)
1168 
1169  def setaddr(self, name, value):
1170  'Set the @ref NetAddr associated with "name"'
1171  self._Cstruct[0].setaddr(self._Cstruct, name, value._Cstruct)
1172 
1173  def getframe(self, name):
1174  'Return the Frame associated with "name"'
1175  faddr = self._Cstruct[0].getframe(self._Cstruct, name)
1176  if faddr:
1177  # Cstruct2Frame already calls CCref()
1178  return pyFrame.Cstruct2Frame(faddr)
1179  raise IndexError("No such Frame value [%s]" % name)
1180 
1181  def setframe(self, name, value):
1182  'Set the @ref Frame associated with "name"'
1183  self._Cstruct[0].setframe(self._Cstruct, name, value._Cstruct)
1184 
1185  def getconfig(self, name):
1186  'Return the pyConfigContext object associated with "name"'
1187  caddr = self._Cstruct[0].getconfig(self._Cstruct, name)
1188  if caddr:
1189  caddr = cast(caddr, cClass.ConfigContext)
1190  # We're creating a new reference to the pre-existing NetAddr
1191  CCref(caddr)
1192  return pyConfigContext(Cstruct=caddr)
1193  raise IndexError("No such ConfigContext value [%s]" % name)
1194 
1195  def setconfig(self, name, value):
1196  'Set the @ref ConfigContext associated with "name"'
1197  self._Cstruct[0].setconfig(self._Cstruct, name, value._Cstruct)
1198 
1199  def getstring(self, name):
1200  'Return the string associated with "name"'
1201  ret = self._Cstruct[0].getstring(self._Cstruct, name)
1202  if ret:
1203  return string_at(ret)
1204  raise IndexError("No such String value [%s]" % name)
1205 
1206  def setstring(self, name, value):
1207  'Set the string associated with "name"'
1208  self._Cstruct[0].setstring(self._Cstruct, name, value)
1209 
1210  def getarray(self, name):
1211  'Return the array value associated with "name"'
1212  curlist = cast(self._Cstruct[0].getarray(self._Cstruct, name), cClass.GSList)
1213  #print >> sys.stderr, "CURLIST(initial) = %s" % curlist
1214  ret = []
1215  while curlist:
1216  #print >> sys.stderr, "CURLIST = %s" % curlist
1217  #cfgval = pyConfigValue(cast(cClass.ConfigValue, curlist[0].data).get())
1218  data = cast(curlist[0].data, cClass.ConfigValue)
1219  #print >> sys.stderr, "CURLIST->data = %s" % data
1220  CCref(data)
1221  cfgval = pyConfigValue(data).get()
1222  #print >> sys.stderr, "CURLIST->data->get() = %s" % cfgval
1223  ret.append(cfgval)
1224  curlist = g_slist_next(curlist)
1225  return ret
1226 
1227  def setarray(self, name, value):
1228  'Set a ConfigContext key value to be a sequence of values from an iterable'
1229  self._Cstruct[0].setarray(self._Cstruct, name, None)
1230  for elem in value:
1231  if isinstance(elem, (int, long)):
1232  self._Cstruct[0].appendint(self._Cstruct, name, elem)
1233  continue
1234  if isinstance(elem, bool):
1235  self._Cstruct[0].appendbool(self._Cstruct, name, elem)
1236  continue
1237  if isinstance(elem, float):
1238  self._Cstruct[0].appendfloat(self._Cstruct, name, elem)
1239  continue
1240  if isinstance(elem, str):
1241  self._Cstruct[0].appendstring(self._Cstruct, name, elem)
1242  continue
1243  if isinstance(elem, pyNetAddr):
1244  self._Cstruct[0].appendaddr(self._Cstruct, name, elem)
1245  continue
1246  if isinstance(elem, pyConfigContext):
1247  self._Cstruct[0].appendconfig(self._Cstruct, name, elem._Cstruct)
1248  continue
1249  if isinstance(elem, dict):
1250  cfgctx = pyConfigContext.from_dict(elem)
1251  self._Cstruct[0].appendconfig(self._Cstruct, name, cfgctx._Cstruct)
1252  continue
1253  raise ValueError("Cannot append/include array elements of type %s" % type(elem))
1254 
1255  @staticmethod
1256  def from_dict(dictval):
1257  'Construct a pyConfigContext from a dict-like object'
1258  newobj = pyConfigContext()
1259  for key in dictval.keys():
1260  keyval = dictval[key]
1261  if hasattr(keyval, 'keys'):
1262  keyval = pyConfigContext.from_dict(dictval[key])
1263  newobj[key] = dictval[key]
1264  return newobj
1265 
1266  def keys(self):
1267  'Return the set of keys for this object'
1268  l = []
1269  keylist = cast(self._Cstruct[0].keys(self._Cstruct), POINTER(GSList))
1270  curkey = keylist
1271  while curkey:
1272  l.append(string_at(curkey[0].data))
1273  curkey = g_slist_next(curkey)
1274  g_slist_free(keylist)
1275  return l
1276 
1277  def __iter__(self):
1278  'Iterate over self.keys()'
1279  for key in self.keys():
1280  yield key
1281 
1282  def gettype(self, name):
1283  '''Return the enumeration type of this particular key
1284  @todo Convert these enums to python types'''
1285  #print >> sys.stderr, 'gettype(%s)' % str(name)
1286  return self._Cstruct[0].gettype(self._Cstruct, str(name))
1287 
1288  def get(self, key, alternative=None):
1289  '''return value if object contains the given key - 'alternative' if not'''
1290  if self._Cstruct[0].gettype(self._Cstruct, str(key)) == CFG_EEXIST:
1291  return alternative
1292  return self[key]
1293 
1294  # pylint R0911: too many returns (9)
1295  # pylint: disable=R0911
1296  def deepget(self, key, alternative=None):
1297  '''return value if object contains the given *structured* key - 'alternative' if not'''
1298  try:
1299  (prefix, suffix) = key.split('.', 1)
1300  except ValueError:
1301  suffix = None
1302  prefix = key
1303  if prefix not in self:
1304  # Note that very similar code exists in GraphNodes get member function
1305  if not prefix.endswith(']'):
1306  return alternative
1307  else:
1308  # Looks like we have an array index
1309  proper = prefix[0:len(prefix)-1]
1310  try:
1311  (preprefix, idx) = proper.split('[', 1)
1312  except ValueError:
1313  return alternative
1314  if preprefix not in self:
1315  return alternative
1316  try:
1317  array = self[preprefix]
1318  idx = int(idx) # Possible ValueError
1319  value = array[idx] # possible IndexError or TypeError
1320  if suffix is None:
1321  return value
1322  except (TypeError, IndexError, ValueError):
1323  return alternative
1324  return value.deepget(suffix, alternative)
1325 
1326  prefixvalue = self[prefix]
1327  if suffix is None:
1328  return prefixvalue
1329  if not isinstance(prefixvalue, pyConfigContext):
1330  return alternative
1331  gotten = prefixvalue.deepget(suffix, alternative)
1332  return gotten
1333 
1334  def has_key(self, key):
1335  'return True if it has the given key'
1336  return self.__contains__(key)
1337 
1338  def __contains__(self, key):
1339  'return True if our object contains the given key'
1340  ktype = self._Cstruct[0].gettype(self._Cstruct, str(key))
1341  return ktype != CFG_EEXIST
1342 
1343  def __len__(self):
1344  'Return the number of items in this pyConfigContext'
1345  keylist = cast(self._Cstruct[0].keys(self._Cstruct), POINTER(GSList))
1346  llen = g_slist_length(keylist)
1347  g_slist_free(keylist)
1348  return llen
1349 
1350  def __delitem__(self, key):
1351  "Delete the given item"
1352  self._Cstruct[0].delkey(self._Cstruct, str(key))
1353 
1354  def __getitem__(self, name):
1355  'Return a value associated with "name"'
1356  ktype = self.gettype(name)
1357  ret = None
1358  #print >> sys.stderr, '************ GETITEM[%s] => %d *********************' % (name, ktype)
1359  if ktype == CFG_EEXIST:
1360  traceback.print_stack()
1361  raise IndexError("No such value [%s] in [%s]" % (name, str(self)))
1362  elif ktype == CFG_CFGCTX:
1363  ret = self.getconfig(name)
1364  elif ktype == CFG_STRING:
1365  ret = self.getstring(name)
1366  elif ktype == CFG_NETADDR:
1367  ret = self.getaddr(name)
1368  elif ktype == CFG_FRAME:
1369  ret = self.getframe(name)
1370  elif ktype == CFG_INT64:
1371  ret = self.getint(name)
1372  elif ktype == CFG_BOOL:
1373  ret = self.getbool(name)
1374  elif ktype == CFG_ARRAY:
1375  #print >> sys.stderr, '************ GETITEM[%s] => getarray(%s) *********************' \
1376  # % (name, name)
1377  ret = self.getarray(name)
1378  return ret
1379 
1380  def __setitem__(self, name, value):
1381  'Set a value associated with "name" - in the appropriate table'
1382  if isinstance(value, str):
1383  return self.setstring(name, value)
1384  if isinstance(value, pyNetAddr):
1385  return self.setaddr(name, value)
1386  if isinstance(value, pyFrame):
1387  return self.setframe(name, value)
1388  if isinstance(value, pyConfigContext):
1389  return self.setconfig(name, value)
1390  if isinstance(value, dict):
1391  return self.setconfig(name, pyConfigContext(value))
1392  if isinstance(value, (list, tuple)) or hasattr(value, '__iter__'):
1393  return self.setarray(name, value)
1394  if isinstance(value, float):
1395  return self.setfloat(name, value)
1396  if isinstance(value, dict):
1397  return self.setconfig(name, pyConfigContext.from_dict(value))
1398  self.setint(name, int(value))
1399 
1401  'A Python wrapper for a C implementation of something like a Python Dictionary'
1402  def __init__(self, Cstruct):
1403  'Initializer for pyConfigValue - now a subclass of pyAssimObj'
1404  pyAssimObj.__init__(self, Cstruct=Cstruct)
1405 
1406  def __str__(self):
1407  'Convert the given pyConfigValue to a String'
1408  str(self.get())
1409 
1410  def get(self):
1411  'Return the value of this object'
1412  ret = None
1413  vtype = self._Cstruct[0].valtype
1414  if vtype == CFG_BOOL:
1415  ret = self._Cstruct[0].u.intvalue != 0
1416  elif vtype == CFG_INT64:
1417  ret = int(self._Cstruct[0].u.intvalue)
1418  elif vtype == CFG_STRING:
1419  ret = str(self._Cstruct[0].u.strvalue)
1420  elif vtype == CFG_FLOAT:
1421  ret = float(self._Cstruct[0].u.floatvalue)
1422  elif vtype == CFG_CFGCTX:
1423  # We're creating a new reference to the pre-existing NetAddr
1424  CCref(self._Cstruct[0].u.cfgctxvalue)
1425  ret = pyConfigContext(Cstruct=self._Cstruct[0].u.cfgctxvalue)
1426  elif vtype == CFG_NETADDR:
1427  ret = pyNetAddr(None, Cstruct=self._Cstruct[0].u.addrvalue)
1428  # We're creating a new reference to the pre-existing NetAddr
1429  CCref(ret._Cstruct)
1430  elif vtype == CFG_FRAME:
1431  # Cstruct2Frame calls CCref() - so we don't need to
1432  ret = pyFrame.Cstruct2Frame(self._Cstruct[0].u.framevalue)
1433  elif vtype == CFG_ARRAY:
1434  # An Array is a linked list (GSList) of ConfigValue objects...
1435  ret = []
1436  this = self._Cstruct[0].u.arrayvalue
1437  while this:
1438  dataptr = cast(this[0].data, struct__GSList._fields_[0][1])
1439  dataptr = cast(dataptr, cClass.ConfigValue)
1440  CCref(dataptr)
1441  thisobj = pyConfigValue(cast(dataptr, cClass.ConfigValue)).get()
1442  ret.append(thisobj)
1443  this = g_slist_next(this)
1444  elif vtype == CFG_NULL:
1445  return None
1446  if ret is None:
1447  raise ValueError('Invalid valtype (%s)in pyConfigValue object' % self._Cstruct.valtype)
1448  return ret
1449 
1451  'A Network I/O object - with a variety of subclasses'
1452  def __init__(self, configobj, packetdecoder, Cstruct=None):
1453  'Initializer for pyNetIO'
1454  self._Cstruct = None # Keep error legs from complaining.
1455  if Cstruct is None:
1456  Cstruct = netio_new(0, configobj._Cstruct, packetdecoder._Cstruct)
1457  self.config = configobj
1458  else:
1459  self._Cstruct = Cstruct
1460  base = self._Cstruct[0]
1461  while (not hasattr(base, '_configinfo')):
1462  base = base.baseclass
1463  self.config = pyConfigContext(Cstruct=base._configinfo)
1464  CCref(base._configinfo)
1465  pyAssimObj.__init__(self, Cstruct=Cstruct)
1466 
1467  def setblockio(self, mode):
1468  'Set this NetIO object to blocking IO mode'
1469  base = self._Cstruct[0]
1470  while (not hasattr(base, 'setblockio')):
1471  base = base.baseclass
1472  return base.setblockio(self._Cstruct, int(mode))
1473 
1474  def fileno(self):
1475  'Return the file descriptor for this pyNetIO object'
1476  base = self._Cstruct[0]
1477  while (not hasattr(base, 'getfd')):
1478  base = base.baseclass
1479  return base.getfd(self._Cstruct)
1480 
1481  def bindaddr(self, addr, silent=False):
1482  'Bind the socket underneath this NetIO object to the given address'
1483  base = self._Cstruct[0]
1484  while (not hasattr(base, 'bindaddr')):
1485  base = base.baseclass
1486  return base.bindaddr(self._Cstruct, addr._Cstruct, silent)
1487 
1488  def boundaddr(self):
1489  'Return the socket underlying this NetIO object'
1490  base = self._Cstruct[0]
1491  while (not hasattr(base, 'bindaddr')):
1492  base = base.baseclass
1493  boundaddr = base.boundaddr(self._Cstruct)
1494  # We're creating a new reference to the pre-existing NetAddr
1495  ret = pyNetAddr(None, Cstruct=boundaddr)
1496  CCref(boundaddr)
1497  return ret
1498 
1499  def mcastjoin(self, addr):
1500  'Join the underlying socket to the given multicast address'
1501  base = self._Cstruct[0]
1502  while (not hasattr(base, 'mcastjoin')):
1503  base = base.baseclass
1504  return base.mcastjoin(self._Cstruct, addr._Cstruct, None)
1505 
1506  def getmaxpktsize(self):
1507  'Return the max packet size for this pyNetIO'
1508  base = self._Cstruct[0]
1509  while (not hasattr(base, 'getmaxpktsize')):
1510  base = base.baseclass
1511  return base.getmaxpktsize(self._Cstruct)
1512 
1513  def setmaxpktsize(self, size):
1514  'Set the max packet size for this pyNetIO'
1515  base = self._Cstruct[0]
1516  while (not hasattr(base, 'setmaxpktsize')):
1517  base = base.baseclass
1518  return base.setmaxpktsize(self._Cstruct, int(size))
1519 
1520  def compressframe(self):
1521  'Return the compression frame for this pyNetIO - may be None'
1522  # Doesn't make a py class object out of it yet...
1523  base = self._Cstruct[0]
1524  while (not hasattr(base, 'compressframe')):
1525  base = base.baseclass
1526  return base.compressframe(self._Cstruct)
1527 
1528  def cryptframe(self):
1529  'Return the encryption frame for this pyNetIO - may be None'
1530  # Doesn't make a py class object out of it yet...
1531  base = self._Cstruct[0]
1532  while (not hasattr(base, 'cryptframe')):
1533  base = base.baseclass
1534  return base.cryptframe(self._Cstruct)
1535 
1536  def signframe(self):
1537  'Return the digital signature frame for this pyNetIO'
1538  base = self._Cstruct[0]
1539  while (not hasattr(base, 'signframe')):
1540  base = base.baseclass
1541  return pySignFrame(0, Cstruct=cast(base.signframe(self._Cstruct), cClass.SignFrame))
1542 
1543  def sendframesets(self, destaddr, framesetlist):
1544  'Send the (collection of) frameset(s) out on this pyNetIO'
1545  if destaddr.port() == 0:
1546  raise ValueError("Zero Port in sendframesets: destaddr=%s" % str(destaddr))
1547  if not isinstance(framesetlist, collections.Sequence):
1548  framesetlist = (framesetlist, )
1549  base = self._Cstruct[0]
1550  while (not hasattr(base, 'sendaframeset')):
1551  base = base.baseclass
1552  # We ought to eventually construct a GSList of them and then call sendframesets
1553  # But this is easy for now...
1554  for frameset in framesetlist:
1555  base.sendaframeset(self._Cstruct, destaddr._Cstruct, frameset._Cstruct)
1556 
1557  def sendreliablefs(self, destaddr, framesetlist, qid = DEFAULT_FSP_QID):
1558  'Reliably send the (collection of) frameset(s) out on this pyNetIO (if possible)'
1559  if destaddr.port() == 0:
1560  raise ValueError("Zero Port in sendreliablefs: destaddr=%s" % str(destaddr))
1561  if not isinstance(framesetlist, collections.Sequence):
1562  framesetlist = (framesetlist, )
1563  base = self._Cstruct[0]
1564  while (not hasattr(base, 'sendaframeset')):
1565  base = base.baseclass
1566  for frameset in framesetlist:
1567  success = base.sendareliablefs(self._Cstruct, destaddr._Cstruct, qid, frameset._Cstruct)
1568  if not success:
1569  raise IOError("sendareliablefs(%s, %s) failed." % (destaddr, frameset))
1570 
1571  def ackmessage(self, destaddr, frameset):
1572  'ACK (acknowledge) this frameset - (presumably sent reliably).'
1573 
1574  base = self._Cstruct[0]
1575  while (not hasattr(base, 'ackmessage')):
1576  base = base.baseclass
1577  base.ackmessage(self._Cstruct, destaddr._Cstruct, frameset._Cstruct)
1578 
1579  def closeconn(self, qid, destaddr):
1580  'Close (reset) our connection to this address'
1581  base = self._Cstruct[0]
1582  while (not hasattr(base, 'closeconn')):
1583  base = base.baseclass
1584  print >> sys.stderr, ('CLOSING CONNECTION (closeconn) TO %s' % str(destaddr))
1585  base.closeconn(self._Cstruct, qid, destaddr._Cstruct)
1586 
1587  def addalias(self, fromaddr, toaddr):
1588  'Close (reset) our connection to this address'
1589 
1590  base = self._Cstruct[0]
1591  while (not hasattr(base, 'addalias')):
1592  base = base.baseclass
1593  base.addalias(self._Cstruct, fromaddr._Cstruct, toaddr._Cstruct)
1594 
1595  def recvframesets(self):
1596  '''Receive a collection of framesets read from this pyNetIO - all from the same Address.
1597  @return The return value is a tuple (address, framesetlist). '''
1598  #GSList * _netio_recvframesets (NetIO *self,NetAddr **src)
1599 
1600  base = self._Cstruct[0]
1601  while (not hasattr(base, 'recvframesets')):
1602  base = base.baseclass
1603  netaddrint = netaddr_ipv4_new(create_string_buffer(4), 101)
1604  netaddr = cast(netaddrint, cClass.NetAddr)
1605  netaddr[0].baseclass.unref(netaddr) # We're about to replace it...
1606  # Basically we needed a pointer to pass, and this seemed like a good way to do it...
1607  # Maybe it was -- maybe it wasn't... It's a pretty expensive way to get this effect...
1608  fs_gslistint = base.recvframesets(self._Cstruct, byref(netaddr))
1609  fslist = pyPacketDecoder.fslist_to_pyfs_array(fs_gslistint)
1610  if netaddr and len(fslist) > 0:
1611  # recvframesets gave us that 'netaddr' for us to dispose of - there are no other refs
1612  # to it so we should NOT 'CCref' it. It's a new object - not a pointer to an old one.
1613  address = pyNetAddr(None, Cstruct=netaddr)
1614  else:
1615  address = None
1616  return (address, fslist)
1617 
1618  @staticmethod
1620  'Return True if our OS supports a dual IPv4/IPv6 stack'
1622 
1624  'UDP version of the pyNetIO abstract base class'
1625  def __init__(self, config, packetdecoder, Cstruct=None):
1626  'Initializer for pyNetIOudp'
1627  self._Cstruct = None # Keep error legs from complaining.
1628  if Cstruct is None:
1629  Cstruct = netioudp_new(0, config._Cstruct, packetdecoder._Cstruct)
1630  if not Cstruct:
1631  raise ValueError("Invalid parameters to pyNetIOudp constructor")
1632  pyNetIO.__init__(self, config, packetdecoder, Cstruct=Cstruct)
1633 
1635  'Reliable UDP version of the pyNetIOudp abstract base class'
1636  def __init__(self, config, packetdecoder, rexmit_timer_uS=0, Cstruct=None):
1637  'Initializer for pyReliableUDP'
1638  self._Cstruct = None # Keep error legs from complaining.
1639  if Cstruct is None:
1640  Cstruct = reliableudp_new(0, config._Cstruct, packetdecoder._Cstruct, rexmit_timer_uS)
1641  if not Cstruct:
1642  raise ValueError("Invalid parameters to pyReliableUDP constructor")
1643  pyNetIOudp.__init__(self, config, packetdecoder, Cstruct=Cstruct)
1644 
1645  def log_conn(self, destaddr, qid=DEFAULT_FSP_QID):
1646  'Log connection status/info to system logs'
1647  base = self._Cstruct[0]
1648  while (type(base) is not ReliableUDP):
1649  base = base.baseclass
1650  base.log_conn(self._Cstruct, qid, destaddr._Cstruct)
1651 
1652 class CMAlib(object):
1653  'Miscellaneous functions to create certain useful pyFrameSets'
1654 
1655  def __init__(self):
1656  'Do-nothing init function'
1657  pass
1658 
1659  @staticmethod
1661  'Create a setconfig FrameSet'
1662  fs = cast(create_setconfig(cfg._Cstruct), cClass.FrameSet)
1663  return pyFrameSet(None, Cstruct=fs)
1664 
1665  @staticmethod
1666  def create_sendexpecthb(cfg, msgtype, address):
1667  'Create a Send/Expect heartbeat FrameSet'
1668  ucfs = create_sendexpecthb(cfg._Cstruct, int(msgtype)
1669  , address._Cstruct, 1)
1670  fs = cast(ucfs, cClass.FrameSet)
1671  return pyFrameSet(None, Cstruct=fs)
1672 
1674  'Dump out live objects to help locate memory leaks'
1675  print >> sys.stderr, 'GC Garbage: [%s]' % str(gc.garbage)
1676  print >> sys.stderr, '***************LOOKING FOR pyAssimObjs***********'
1677  get_referrers = True
1678  cobjcount = 0
1679  gc.collect()
1680  for obj in gc.get_objects():
1681  if isinstance(obj, (pyAssimObj, pyCstringFrame)):
1682  cobjcount += 1
1683  cobj = 'None'
1684  if hasattr(obj, '_Cstruct') and obj._Cstruct is not None:
1685  cobj = ('0x%x' % addressof(getattr(obj, '_Cstruct')[0]))
1686  print >> sys.stderr, ('FOUND C object class(%s): %s -> %s'
1687  % (obj.__class__.__name__, str(obj)[:512], cobj))
1688  if get_referrers:
1689  for referrer in gc.get_referrers(obj):
1690  print >> sys.stderr, ('++++Referred to by(%s): %s'
1691  % (type(referrer), str(referrer)[:512]))
1692 
1693  print >> sys.stderr, ('%d python wrappers referring to %d C-objects'
1694  % (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:751
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