The Assimilation Project
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
packetdecoder.c
Go to the documentation of this file.
1 
26 #include <memory.h>
27 #include <projectcommon.h>
28 #include <assimobj.h>
29 #include <generic_tlv_min.h>
30 #include <frameset.h>
31 #include <frametypes.h>
32 #include <signframe.h>
33 #include <cryptframe.h>
34 #include <compressframe.h>
35 #include <tlvhelper.h>
36 #include <packetdecoder.h>
37 #include <intframe.h>
38 #include <addrframe.h>
39 #include <ipportframe.h>
40 #include <signframe.h>
41 #include <cstringframe.h>
42 #include <seqnoframe.h>
43 #include <nvpairframe.h>
44 #include <unknownframe.h>
45 #include <frametypes.h>
51 
52 
53 
54 FSTATIC Frame* _framedata_to_frameobject(PacketDecoder*, gconstpointer, gconstpointer gconstpointer);
55 FSTATIC FrameSet* _decode_packet_get_frameset_data(gconstpointer, gconstpointer, void const **);
56 FSTATIC Frame* _decode_packet_framedata_to_frameobject(PacketDecoder*, gconstpointer, gconstpointer, void const **);
57 FSTATIC GSList* _pktdata_to_framesetlist(PacketDecoder*, gconstpointer, gconstpointer);
58 
60 
62 FSTATIC void
64 {
65  PacketDecoder* self = CASTTOCLASS(PacketDecoder, selfobj);
66 
67  FREE(self->_frametypemap); self->_frametypemap = NULL;
68  self->_pfinalize(selfobj);
69 }
70 
71 static FrameTypeToFrame _defaultmap[] = FRAMETYPEMAP;
72 
76 packetdecoder_new(guint objsize, const FrameTypeToFrame* framemap, gint mapsize)
77 {
78  gint j;
79  AssimObj* baseobj;
80  PacketDecoder* self;
81 
82  if (objsize < sizeof(PacketDecoder)) {
83  objsize = sizeof(PacketDecoder);
84  }
85  if (NULL == framemap) {
86  framemap = _defaultmap;
87  mapsize = DIMOF(_defaultmap);
88  }
89 
90  baseobj = assimobj_new(objsize);
91  proj_class_register_subclassed(baseobj, "PacketDecoder");
92  self = CASTTOCLASS(PacketDecoder, baseobj);
93 
94 
95  self->_pfinalize = baseobj->_finalize;
97  self->pktdata_to_framesetlist = _pktdata_to_framesetlist;
98  self->_maxframetype = 0;
99  self->_framemap = framemap;
100  self->_framemaplen = mapsize;
101 
102  for (j=0; j < self->_framemaplen; ++j) {
103  if (self->_framemap[j].frametype > self->_maxframetype) {
104  self->_maxframetype = self->_framemap[j].frametype;
105  }
106  }
107  self->_frametypemap = MALLOC0((self->_maxframetype+1)*sizeof(gpointer));
108  for (j=0; j <= self->_maxframetype; ++j) {
109  self->_frametypemap[j] = unknownframe_tlvconstructor;
110  }
111  for (j=0; j < self->_framemaplen; ++j) {
112  self->_frametypemap[self->_framemap[j].frametype] = self->_framemap[j].constructor;
113  }
114  return self;
115 }
116 
119 FSTATIC Frame*
121  gconstpointer pktstart,
122  gconstpointer pktend,
123  void const ** nextframe)
124 {
125  guint16 frametype = get_generic_tlv_type(pktstart, pktend);
126  Frame* ret;
127 
128  if (frametype <= self->_maxframetype) {
129  ret = self->_frametypemap[frametype](pktstart, pktend);
130  }else{
131  ret = unknownframe_tlvconstructor(pktstart, pktend);
132  }
133  g_return_val_if_fail(ret != NULL, NULL);
134  *nextframe = (gconstpointer) ((const guint8*)pktstart + ret->dataspace(ret));
135  return ret;
136 }
137 
140 _decode_packet_get_frameset_data(gconstpointer vfsstart,
141  gconstpointer vpktend,
142  const void ** fsnext)
143 {
145  const guint8* fsstart = vfsstart;
146  const guint8* pktend = vpktend;
147  gssize bytesleft = pktend - fsstart;
148  guint16 fstype;
149  guint16 fslen;
150  guint16 fsflags;
151  FrameSet* ret;
152 
153  *fsnext = vpktend;
154  if (bytesleft < (gssize)FRAMESET_INITSIZE) {
155  return NULL;
156  }
157  fstype = get_generic_tlv_type(fsstart, pktend);
158  fslen = get_generic_tlv_len(fsstart, pktend);
159  fsflags = tlv_get_guint16(fsstart + GENERICTLV_HDRSZ, pktend);
160  ret = frameset_new(fstype);
161  g_return_val_if_fail(ret != NULL, NULL);
162  frameset_set_flags(ret, fsflags);
163  *fsnext = (gconstpointer) (fsstart + FRAMESET_INITSIZE + fslen);
164  return ret;
165 }
166 
167 
171 GSList*
173  gconstpointer pktstart,
174  gconstpointer pktend)
175 {
176  gconstpointer curframeset = pktstart;
177  GSList* ret = NULL;
178 
179  while (curframeset < pktend) {
180  gconstpointer nextframeset = pktend;
181  gconstpointer curframe = (gconstpointer)((const guint8*)curframeset + FRAMESET_INITSIZE);
182  FrameSet* fs = _decode_packet_get_frameset_data(curframeset, pktend, &nextframeset);
183 
184  g_return_val_if_fail(fs != NULL && nextframeset <= pktend, ret);
185 
186  while (curframe < nextframeset) {
187  gconstpointer nextframe = nextframeset;
188  Frame* newframe;
189  newframe = _decode_packet_framedata_to_frameobject(self, curframe, nextframeset, &nextframe);
190  if (NULL == newframe) {
191  UNREF(fs);
192  // What should we do about 'ret'?
194  return NULL;
195  }
196  if (nextframe > nextframeset) {
197  UNREF(newframe);
198  UNREF(fs);
199  return ret;
200  }
201  frameset_append_frame(fs, newframe);
202  UNREF(newframe);
203  curframe = nextframe;
204  }
205  ret = g_slist_append(ret, fs); fs = NULL;
206  curframeset = nextframeset;
207  }
208  return ret;
209 }