diameter.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. """Diameter."""
  2. from pypacker import pypacker, triggerlist
  3. import logging
  4. logger = logging.getLogger("pypacker")
  5. # Diameter Base Protocol - RFC 3588
  6. # http://tools.ietf.org/html/rfc3588
  7. # Request/Answer Command Codes
  8. ABORT_SESSION = 274
  9. ACCOUTING = 271
  10. CAPABILITIES_EXCHANGE = 257
  11. DEVICE_WATCHDOG = 280
  12. DISCONNECT_PEER = 282
  13. RE_AUTH = 258
  14. SESSION_TERMINATION = 275
  15. class Diameter(pypacker.Packet):
  16. __hdr__ = (
  17. ("v", "B", 1),
  18. ("len", "3s", b"\x00" * 3),
  19. ("flags", "B", 0),
  20. ("cmd", "3s", b"\x00" * 3),
  21. ("app_id", "I", 0),
  22. ("hop_id", "I", 0),
  23. ("end_id", "I", 0),
  24. ("avps", None, triggerlist.TriggerList)
  25. )
  26. def __get_r(self):
  27. return (self.flags >> 7) & 0x1
  28. def __set_r(self, r):
  29. self.flags = (self.flags & ~0x80) | ((r & 0x1) << 7)
  30. request_flag = property(__get_r, __set_r)
  31. def __get_p(self):
  32. return (self.flags >> 6) & 0x1
  33. def __set_p(self, p):
  34. self.flags = (self.flags & ~0x40) | ((p & 0x1) << 6)
  35. proxiable_flag = property(__get_p, __set_p)
  36. def __get_e(self):
  37. return (self.flags >> 5) & 0x1
  38. def __set_e(self, e):
  39. self.flags = (self.flags & ~0x20) | ((e & 0x1) << 5)
  40. error_flag = property(__get_e, __set_e)
  41. def __get_t(self):
  42. return (self.flags >> 4) & 0x1
  43. def __set_t(self, t):
  44. self.flags = (self.flags & ~0x10) | ((t & 0x1) << 4)
  45. retransmit_flag = property(__get_t, __set_t)
  46. def _dissect(self, buf):
  47. self._init_triggerlist("avps", buf[20:], self._parse_avps)
  48. return len(buf)
  49. def _parse_avps(self, buf):
  50. off = 0
  51. avps = []
  52. buflen = len(buf)
  53. # parse AVPs
  54. while off < buflen:
  55. avplen = int.from_bytes(buf[off + 5: off + 8], "big")
  56. # REAL length of AVP is multiple of 4 Bytes
  57. mod_len = avplen % 4
  58. if mod_len != 0:
  59. avplen += 4 - mod_len
  60. avp = AVP(buf[off: off + avplen])
  61. avps.append(avp)
  62. off += avplen
  63. return avps
  64. class AVP(pypacker.Packet):
  65. __hdr__ = (
  66. ("code", "I", 0),
  67. ("flags", "B", 0),
  68. ("len", "3s", b""),
  69. )
  70. def __get_v(self):
  71. return (self.flags >> 7) & 0x1
  72. def __set_v(self, v):
  73. self.flags = (self.flags & ~0x80) | ((v & 0x1) << 7)
  74. vendor_flag = property(__get_v, __set_v)
  75. def __get_m(self):
  76. return (self.flags >> 6) & 0x1
  77. def __set_m(self, m):
  78. self.flags = (self.flags & ~0x40) | ((m & 0x1) << 6)
  79. mandatory_flag = property(__get_m, __set_m)
  80. def __get_p(self):
  81. return (self.flags >> 5) & 0x1
  82. def __set_p(self, p):
  83. self.flags = (self.flags & ~0x20) | ((p & 0x1) << 5)
  84. protected_flag = property(__get_p, __set_p)