The Assimilation Project
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
generic_tlv_min.c
Go to the documentation of this file.
1 
28 #include <stdio.h>
29 #include <string.h>
30 #include <tlvhelper.h>
31 #include <frametypes.h>
32 #include <generic_tlv_min.h>
33 
40 
41 
43 guint16
44 get_generic_tlv_type(gconstpointer tlv_vp,
45  gconstpointer pktend)
46 {
47  return tlv_get_guint16(tlv_vp, pktend);
48 }
49 
51 void
52 set_generic_tlv_type(gpointer tlv_vp,
53  guint16 newtype,
54  gconstpointer pktend)
55 {
56  tlv_set_guint16(tlv_vp, newtype, pktend);
57 }
58 
60 guint32
61 get_generic_tlv_len(gconstpointer tlv_vp,
62  gconstpointer pktend)
63 {
64  const guint8 * tlvp = tlv_vp;
65  return tlv_get_guint24(tlvp+sizeof(guint16), pktend);
66 }
67 
69 void
70 set_generic_tlv_len(gpointer tlv_vp,
71  guint32 newsize,
72  gconstpointer pktend)
73 {
74  guint8 * tlvp = tlv_vp;
75  tlv_set_guint24(tlvp+sizeof(guint16), newsize, pktend);
76 }
77 
79 gconstpointer
80 get_generic_tlv_value(gconstpointer tlv_vp,
81  gconstpointer pktend)
82 {
83  const guint8* tlvbytes = tlv_vp;
84  (void)pktend;
85  return (tlvbytes + GENERICTLV_HDRSZ);
86 }
87 
89 gpointer
91  gconstpointer pktend)
92 {
93  guint8* tlvbytes = tlv_vp;
94  (void)pktend;
95  return (tlvbytes + GENERICTLV_HDRSZ);
96 }
97 
100 void
101 set_generic_tlv_value(gpointer tlv_vp,
102  void* srcdata,
103  guint32 srcsize,
104  gconstpointer pktend)
105 {
106  guint8* tlvbytes = tlv_vp;
107  g_return_if_fail((gpointer)(tlvbytes+srcsize) <= pktend);
108  g_return_if_fail(srcsize == get_generic_tlv_len(tlv_vp, pktend));
109  memcpy(tlvbytes + GENERICTLV_HDRSZ, srcdata, srcsize);
110 }
111 
113 gboolean
114 is_valid_generic_tlv_packet(gconstpointer tlv_vp,//<[in] pointer to beginning of TLV packet
115  gconstpointer pktend) //<[in] pointer to first byte past the end of packet
116 {
117  const guint16 reqtypes [] = {FRAMETYPE_SIG};
118  unsigned j = 0;
119  int lasttype = -1;
120  if (NULL == tlv_vp || ((const guint8*)tlv_vp+GENERICTLV_HDRSZ) > (const guint8*)pktend) {
121  fprintf(stderr, "TLV Invalid because packet is too short\n");
122  return FALSE;
123  }
124  for (tlv_vp = get_generic_tlv_first(tlv_vp, pktend)
125  ; NULL != tlv_vp
126  ; tlv_vp = get_generic_tlv_next(tlv_vp, pktend)) {
127 
128  guint16 ttype;
129  guint32 length;
130  const guint8* next;
131 
132  if (tlv_vp >= pktend) {
133  return FALSE;
134  }
135  ttype = get_generic_tlv_type(tlv_vp, pktend);
136  lasttype = ttype;
137  length = get_generic_tlv_len(tlv_vp, pktend);
138  next = (const guint8*)tlv_vp + (length+GENERICTLV_HDRSZ);
139  if (next > (const guint8*) pktend) {
140  fprintf(stderr, "TLV Invalid because TLV entry extends past end\n");
141  return FALSE;
142  }
143  if (ttype == FRAMETYPE_END) {
144  if (get_generic_tlv_value(tlv_vp, pktend) == pktend) {
145  return length == 0;
146  }else{
147  fprintf(stderr, "TLV Invalid because END item isn't at end of packet\n");
148  return FALSE;
149  }
150  }
151  if (j < DIMOF(reqtypes) && ttype != reqtypes[j]) {
152  fprintf(stderr, "TLV Invalid because required TLV types aren't present in right order\n");
153  return FALSE;
154  }
155  j += 1;
156  }
157  if (lasttype != FRAMETYPE_END) {
158  fprintf(stderr, "TLV Invalid because final type wasn't FRAMETYPE_END (it was %d)\n"
159  , lasttype);
160  return FALSE;
161  }
162  return TRUE;
163 }
164 
165 gconstpointer
166 get_generic_tlv_first(gconstpointer packet,
167  gconstpointer pktend)
168 {
169  const guint8* inittlv = packet;
170  if (packet == NULL
171  || (inittlv + GENERICTLV_HDRSZ) > (const guint8*)pktend
172  || (inittlv + GENERICTLV_HDRSZ + get_generic_tlv_len(inittlv, pktend)) > (const guint8*)pktend) {
173  return NULL;
174  }
175  return inittlv;
176 }
177 
179 gconstpointer
180 get_generic_tlv_next(gconstpointer tlv_vp,
181  gconstpointer pktend)
182 {
183  const guint8* nexttlv;
184  const guint8* nextend;
185  if (tlv_vp == NULL
186  || ((const guint8*)tlv_vp+GENERICTLV_HDRSZ) > (const guint8*)pktend
187  || get_generic_tlv_type(tlv_vp, pktend) == FRAMETYPE_END) {
188  return NULL;
189  }
190  nexttlv = (const guint8*)tlv_vp + GENERICTLV_HDRSZ + get_generic_tlv_len(tlv_vp, pktend);
191  /* Watch out for malformed packets! (BLACKHAT, PARANOIA) */
192  nextend = nexttlv + GENERICTLV_HDRSZ + get_generic_tlv_len(nexttlv, pktend);
193  /* fprintf(stderr, "LOOK: cur:%p, next: %p, nextend: %p, vpend: %p\n"
194  , tlv_vp, nexttlv, nextend, pktend); */
195  return nextend > (const guint8*)pktend ? NULL : nexttlv;
196 }
197 
199 gconstpointer
200 find_next_generic_tlv_type(gconstpointer tlv_vp,
201  guint16 tlvtype,
202  gconstpointer pktend)
203 {
204  while (NULL != tlv_vp && ((const guint8*)tlv_vp+GENERICTLV_HDRSZ) <= (const guint8*)pktend) {
205  if (get_generic_tlv_type(tlv_vp, pktend) == tlvtype) {
206  return tlv_vp;
207  }
208  tlv_vp = get_generic_tlv_next(tlv_vp, pktend);
209  }
210  return NULL;
211 }