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