1# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12# implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import struct
17from struct import calcsize
18
19
20class SfTimeval32(object):
21    _PACK_STR = '!II'
22    _SIZE = 8
23
24    def __init__(self, tv_sec, tv_usec):
25        self.tv_sec = tv_sec
26        self.tv_usec = tv_usec
27
28    @classmethod
29    def parser(cls, buf, offset):
30        (tv_sec, tv_usec) = struct.unpack_from(
31            cls._PACK_STR, buf, offset)
32
33        msg = cls(tv_sec, tv_usec)
34
35        return msg
36
37
38class Event(object):
39    _PACK_STR = '!IIIIIII'
40    _SIZE = 36
41
42    def __init__(self, sig_generator, sig_id, sig_rev, classification,
43                 priority, event_id, event_reference, ref_time):
44        self.sig_generator = sig_generator
45        self.sig_id = sig_id
46        self.sig_rev = sig_rev
47        self.classification = classification
48        self.priority = priority
49        self.event_id = event_id
50        self.event_reference = event_reference
51        self.ref_time = ref_time
52
53    @classmethod
54    def parser(cls, buf, offset):
55        (sig_generator, sig_id, sig_rev, classification, priority,
56         event_id, event_reference) = struct.unpack_from(
57             cls._PACK_STR, buf, offset)
58        offset += calcsize(cls._PACK_STR)
59
60        ref_time = SfTimeval32.parser(buf, offset)
61
62        msg = cls(sig_generator, sig_id, sig_rev, classification,
63                  priority, event_id, event_reference, ref_time)
64
65        return msg
66
67
68class PcapPktHdr32(object):
69    _PACK_STR = '!II'
70    _SIZE = 16
71
72    def __init__(self, ts, caplen, len_):
73        self.ts = ts
74        self.caplen = caplen
75        self.len = len_
76
77    @classmethod
78    def parser(cls, buf, offset):
79        ts = SfTimeval32.parser(buf, offset)
80        offset += SfTimeval32._SIZE
81
82        (caplen, len_) = struct.unpack_from(
83            cls._PACK_STR, buf, offset)
84
85        msg = cls(ts, caplen, len_)
86
87        return msg
88
89
90class AlertPkt(object):
91    _ALERTMSG_PACK_STR = '!256s'
92    _ALERTPKT_PART_PACK_STR = '!IIIII65535s'
93    _ALERTPKT_SIZE = 65863
94
95    def __init__(self, alertmsg, pkth, dlthdr, nethdr, transhdr, data,
96                 val, pkt, event):
97        self.alertmsg = alertmsg
98        self.pkth = pkth
99        self.dlthdr = dlthdr
100        self.nethdr = nethdr
101        self.transhdr = transhdr
102        self.data = data
103        self.val = val
104        self.pkt = pkt
105        self.event = event
106
107    @classmethod
108    def parser(cls, buf):
109        alertmsg = struct.unpack_from(cls._ALERTMSG_PACK_STR, buf)
110        offset = calcsize(cls._ALERTMSG_PACK_STR)
111
112        pkth = PcapPktHdr32.parser(buf, offset)
113        offset += PcapPktHdr32._SIZE
114
115        (dlthdr, nethdr, transhdr, data, val, pkt) = \
116            struct.unpack_from(cls._ALERTPKT_PART_PACK_STR, buf,
117                               offset)
118        offset += calcsize(cls._ALERTPKT_PART_PACK_STR)
119
120        event = Event.parser(buf, offset)
121
122        msg = cls(alertmsg, pkth, dlthdr, nethdr, transhdr, data, val,
123                  pkt, event)
124
125        return msg
126