The Assimilation Project
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
addrframe.c
Go to the documentation of this file.
1 
27 #include <string.h>
28 #include <projectcommon.h>
29 #include <frameset.h>
30 #include <addrframe.h>
31 #include <frametypes.h>
32 #include <generic_tlv_min.h>
33 #include <tlvhelper.h>
34 #include <address_family_numbers.h>
35 
36 FSTATIC gboolean _addrframe_default_isvalid(const Frame *, gconstpointer, gconstpointer);
37 FSTATIC void _addrframe_setaddr(AddrFrame* self, guint16 frametype, gconstpointer addr, gsize addrlen);
39 FSTATIC void _addrframe_setnetaddr(AddrFrame* self, NetAddr*netaddr);
40 FSTATIC void _addrframe_setport(AddrFrame *, guint16 port);
42 FSTATIC char* _addrframe_toString(gconstpointer);
44 
61 
74 FSTATIC gboolean
76  gconstpointer tlvptr,
77  gconstpointer pktend)
78 {
79  guint32 tlvlen = 0;
80  guint16 address_family = 0;
81  gconstpointer valueptr = NULL;
82  guint32 addrlen;
83 
84  if (tlvptr == NULL) {
85  // Validate the local copy instead of the TLV version.
86  tlvptr = self->value;
87  g_return_val_if_fail(tlvptr != NULL, FALSE);
88  pktend = (const guint8*)tlvptr + self->length;
89  address_family = tlv_get_guint16(tlvptr, pktend);
90  addrlen = self->length - sizeof(guint16);;
91  }else{
92  tlvlen = get_generic_tlv_len(tlvptr, pktend);
93  if (tlvlen <= sizeof(guint16)) {
94  return FALSE;
95  }
96  addrlen = tlvlen - sizeof(guint16);
97 
98  valueptr = get_generic_tlv_value(tlvptr, pktend);
99  if (valueptr == NULL) {
100  return FALSE;
101  }
102 
103  address_family = tlv_get_guint16(valueptr, pktend);
104  }
105 
106  switch(address_family) {
107  case ADDR_FAMILY_IPV4: // IPv4
108  return (4 == addrlen);
109 
110  case ADDR_FAMILY_IPV6: // IPv6
111  return (16 == addrlen);
112 
113  case ADDR_FAMILY_802: // IEEE 802 MAC addresses
114  // MAC-48/EUI-48 OR EUI-64
115  // See http://en.wikipedia.org/wiki/MAC_address
116  return (6 == addrlen || 8 == addrlen);
117  }
118  if (address_family < ADDR_FAMILY_IPV4 || address_family >= 32) {
119  // Probably a mangled address type -- could be changed if we need
120  // to support some odd protocol in the future...
121  return FALSE;
122  }
123  // WAG...
124  return (addrlen >= 4 && addrlen <= 32); // Or we could just disallow them...
125 }
126 
128 FSTATIC void
129 _addrframe_setaddr(AddrFrame* f, //<[in/out] Frame to set the address type for
130  guint16 addrtype, //<[in] IANA address type
131  gconstpointer addr, //<[in] Address blob
132  gsize addrlen) //<[in] size of address
133 {
134  gsize blobsize = addrlen + sizeof(guint16);
135  guint8* blob = MALLOC(blobsize);
136 
137  g_return_if_fail(blob != NULL);
138 
139  if (f->baseclass.value != NULL) {
140  FREE(f->baseclass.value);
141  f->baseclass.value = NULL;
142  }
143 
144  tlv_set_guint16(blob, addrtype, blob+blobsize);
145  memcpy(blob+sizeof(guint16), addr, addrlen);
146  f->baseclass.length = blobsize;
147  f->baseclass.value = blob;
148  f->_addr = netaddr_new(0, 0, addrtype, addr, addrlen);
149 }
150 
151 FSTATIC void
152 _addrframe_setport(AddrFrame* self, guint16 port)
153 {
154  if (self && self->_addr) {
155  self->_addr->_addrport = port;
156  }
157 
158 }
159 
160 
163 {
164  return self->_addr;
165 }
166 
168 FSTATIC void
170  NetAddr* naddr)
171 {
173  if (self->_addr) {
174  UNREF(self->_addr);
175  }
176  self->setaddr(self, naddr->addrtype(naddr), naddr->_addrbody, naddr->_addrlen);
177  if (!_addrframe_default_isvalid((Frame*)self, NULL, NULL)) {
178  g_error("supplied netaddr for addrframe is invalid");
179  }
180 }
181 
182 
183 
184 FSTATIC void
186 {
187  AddrFrame* self = CASTTOCLASS(AddrFrame, obj);
188  if (self->_addr) {
189  UNREF(self->_addr);
190  }
191  if (self->baseclass.value) {
192  FREE(self->baseclass.value);
193  self->baseclass.value = NULL;
194  }
195  self->_basefinal(CASTTOCLASS(AssimObj, self)); self = NULL;
196 }
197 
201 addrframe_new(guint16 frame_type,
202  gsize framesize)
203 {
204  Frame* baseframe;
205  AddrFrame* aframe;
206 
207  if (framesize < sizeof(AddrFrame)){
208  framesize = sizeof(AddrFrame);
209  }
210 
211  baseframe = frame_new(frame_type, framesize);
212  baseframe->isvalid = _addrframe_default_isvalid;
213  proj_class_register_subclassed (baseframe, "AddrFrame");
214  aframe = CASTTOCLASS(AddrFrame, baseframe);
215 
216  aframe->setaddr = _addrframe_setaddr;
219  aframe->setport = _addrframe_setport;
220  aframe->_basefinal = baseframe->baseclass._finalize;
223  aframe->_addr = NULL;
224  return aframe;
225 }
226 
229 addrframe_ipv4_new(guint16 frame_type,
230  gconstpointer addr)
231 {
232  AddrFrame* ret;
233  ret = addrframe_new(frame_type, 0);
234  g_return_val_if_fail(ret != NULL, NULL);
235  ret->setaddr(ret, ADDR_FAMILY_IPV4, addr, 4);
236  return ret;
237 }
238 
241 addrframe_ipv6_new(guint16 frame_type,
242  gconstpointer addr)
243 {
244  AddrFrame* ret;
245  ret = addrframe_new(frame_type, 0);
246  g_return_val_if_fail(ret != NULL, NULL);
247  ret->setaddr(ret, ADDR_FAMILY_IPV6, addr, 16);
248  return ret;
249 }
250 
253 addrframe_mac48_new(guint16 frame_type,
254  gconstpointer addr)
255 {
256  AddrFrame* ret;
257  ret = addrframe_new(frame_type, 0);
258  g_return_val_if_fail(ret != NULL, NULL);
259  ret->setaddr(ret, ADDR_FAMILY_802, addr, 6);
260  return ret;
261 }
264 addrframe_mac64_new(guint16 frame_type,
265  gconstpointer addr)
266 {
267  AddrFrame* ret;
268  ret = addrframe_new(frame_type, 0);
269  g_return_val_if_fail(ret != NULL, NULL);
270  ret->setaddr(ret, ADDR_FAMILY_802, addr, 8);
271  return ret;
272 }
273 
278 addrframe_tlvconstructor(gconstpointer tlvstart,
279  gconstpointer pktend,
280  gpointer* ignorednewpkt,
281  gpointer* ignoredpktend)
282 
283 {
284  guint16 frametype = get_generic_tlv_type(tlvstart, pktend);
285  guint16 framelength = get_generic_tlv_len(tlvstart, pktend);
286  const guint8* framevalue = get_generic_tlv_value(tlvstart, pktend);
287  AddrFrame * ret = addrframe_new(frametype, 0);
288  guint16 address_family;
289 
290  (void)ignorednewpkt; (void)ignoredpktend;
291  g_return_val_if_fail(ret != NULL, NULL);
292 
293  address_family = tlv_get_guint16(framevalue, pktend);
294 
295  ret->baseclass.length = framelength;
296  ret->setaddr(ret, address_family, framevalue+sizeof(guint16), framelength-sizeof(guint16));
297  if (!_addrframe_default_isvalid(&ret->baseclass, tlvstart, pktend)) {
298  UNREF2(ret);
299  g_return_val_if_reached(NULL);
300  }
301  return &ret->baseclass;
302 }
303 
304 
306 FSTATIC gchar*
307 _addrframe_toString(gconstpointer aself)
308 {
309  const AddrFrame* self = CASTTOCONSTCLASS(AddrFrame, aself);
310  char * selfstr = self->_addr->baseclass.toString(&self->_addr->baseclass);
311  char * ret;
312 
313  ret = g_strdup_printf("AddrFrame(type=%d, %s)", self->baseclass.type, selfstr);
314  g_free(selfstr);
315  return ret;
316 }
guint32 length
Frame Length.
Definition: frame.h:46
IETF/IANA Address family assignments.
WINEXPORT AddrFrame * addrframe_new(guint16 frame_type, gsize framesize)
Construct a new AddrFrame class - allowing for "derived" frame types...
Definition: addrframe.c:201
void(* setport)(AddrFrame *f, guint16 port)
Definition: addrframe.h:45
FSTATIC char * _addrframe_toString(gconstpointer)
Convert AddrFrame object into a printable string.
Definition: addrframe.c:307
guint16(* addrtype)(const NetAddr *self)
Return IANA Address Family Numbers address type.
Definition: netaddr.h:47
WINEXPORT AddrFrame * addrframe_ipv6_new(guint16 frame_type, gconstpointer addr)
Construct and initialize an IPv6 AddrFrame class.
Definition: addrframe.c:241
AssimObj baseclass
Base object class for our Class system.
Definition: frame.h:44
FSTATIC void _addrframe_setnetaddr(AddrFrame *self, NetAddr *netaddr)
Assign a NetAddr to this AddrFrame class object.
Definition: addrframe.c:169
Implements minimal client-oriented Frame and Frameset capabilities.
This is the base Frame class object (in-memory TLV (type, length, value)) for every general component...
Definition: frame.h:43
WINEXPORT AddrFrame * addrframe_mac48_new(guint16 frame_type, gconstpointer addr)
Construct and initialize a 48-bit MAC address AddrFrame class.
Definition: addrframe.c:253
#define WINEXPORT
Definition: projectcommon.h:45
#define FSTATIC
Definition: projectcommon.h:31
gpointer value
Frame Value (pointer)
Definition: frame.h:47
struct _AddrFrame AddrFrame
Definition: addrframe.h:31
void tlv_set_guint16(void *vitem, guint16 item, const void *bufend)
Set an unsigned 16 bit integer to the given location with error checking and without caring about byt...
Definition: tlvhelper.c:68
Frame baseclass
Definition: addrframe.h:39
guint16 get_generic_tlv_type(gconstpointer tlv_vp, gconstpointer pktend)
Return the 'Type' of the given TLV TLV entry (first two bytes)
void(* setaddr)(AddrFrame *f, guint16 addrtype, gconstpointer addr, gsize addrlen)
Definition: addrframe.h:42
NetAddr * _addr
Definition: addrframe.h:40
Frame * frame_new(guint16 frame_type, gsize framesize)
Construct a new frame - allowing for "derived" frame types...
Definition: frame.c:124
gpointer proj_class_register_subclassed(gpointer object, const char *static_subclassname)
Log the creation of a subclassed object from a superclassed object.
Definition: proj_classes.c:192
gboolean(* isvalid)(const Frame *self, gconstpointer tlvptr, gconstpointer pktend)
TRUE if TLV data looks valid...
Definition: frame.h:50
#define FREE(m)
Our interface to free.
Definition: projectcommon.h:29
FSTATIC void _addrframe_setaddr(AddrFrame *self, guint16 frametype, gconstpointer addr, gsize addrlen)
Assign an address to this AddrFrame class object.
Definition: addrframe.c:129
#define ADDR_FAMILY_IPV6
IPv6.
#define CASTTOCONSTCLASS(Cclass, obj)
Safely cast 'obj' to const C-class 'class' - verifying that it was registered as being of type class ...
Definition: proj_classes.h:71
guint32 get_generic_tlv_len(gconstpointer tlv_vp, gconstpointer pktend)
Return the 'Length' of the given generic TLV entry (first 3 bytes after type)
Project common header file.
Header file defining the data layouts for our Frames.
TLV helper interfaces definitions.
NetAddr *(* getnetaddr)(AddrFrame *f)
Definition: addrframe.h:44
FSTATIC void _addrframe_finalize(AssimObj *)
Definition: addrframe.c:185
WINEXPORT AddrFrame * addrframe_mac64_new(guint16 frame_type, gconstpointer addr)
Construct and initialize a 64-bit MAC address AddrFrame class.
Definition: addrframe.c:264
void(* setnetaddr)(AddrFrame *f, NetAddr *addr)
Definition: addrframe.h:43
void(* _finalize)(AssimObj *)
Free object (private)
Definition: assimobj.h:55
Provides definitions for using our generic TLV capabilities.
The NetAddr class class represents a general network address - whether IP, MAC, or any other type of ...
Definition: netaddr.h:43
gconstpointer get_generic_tlv_value(gconstpointer tlv_vp, gconstpointer pktend)
Return a const pointer to the 'Value' of the given generic TLV entry.
Describes interfaces to Address Frame (AddrFrame) C-Class.
WINEXPORT Frame * addrframe_tlvconstructor(gconstpointer tlvstart, gconstpointer pktend, gpointer *ignorednewpkt, gpointer *ignoredpktend)
Given marshalled packet data corresponding to an AddrFrame (address), return the corresponding Frame ...
Definition: addrframe.c:278
WINEXPORT AddrFrame * addrframe_ipv4_new(guint16 frame_type, gconstpointer addr)
Construct and initialize an IPv4 AddrFrame class.
Definition: addrframe.c:229
#define MALLOC(nbytes)
should it just call g_malloc?
Definition: projectcommon.h:26
NetAddr * netaddr_new(gsize objsize, guint16 port, guint16 addrtype, gconstpointer addrbody, guint16 addrlen)
Generic NetAddr constructor.
Definition: netaddr.c:501
guint16 _addrlen
private: Length of _addrbody
Definition: netaddr.h:60
gchar *(* toString)(gconstpointer)
Produce malloc-ed string representation.
Definition: assimobj.h:58
#define ADDR_FAMILY_802
Level 2 physical (MAC) addresses.
FSTATIC gboolean _addrframe_default_isvalid(const Frame *, gconstpointer, gconstpointer)
AddrFrame class 'isvalid' member function - checks address type and length.
Definition: addrframe.c:75
This is our AddrFrame class object - used for holding NetAddr class network addresses.
Definition: addrframe.h:38
FSTATIC void _addrframe_setport(AddrFrame *, guint16 port)
Definition: addrframe.c:152
#define ADDR_FAMILY_IPV4
IPv4.
#define UNREF2(obj)
Definition: assimobj.h:36
guint16 tlv_get_guint16(const void *vitem, const void *bufend)
Retrieve an unsigned 16 bit integer from the given location with error checking and without caring ab...
Definition: tlvhelper.c:53
#define CASTTOCLASS(Cclass, obj)
Safely cast 'obj' to C-class 'class' - verifying that it was registerd as being of type class ...
Definition: proj_classes.h:66
#define UNREF(obj)
Definition: assimobj.h:35
void(* _basefinal)(AssimObj *)
Free object (private)
Definition: addrframe.h:41
FSTATIC NetAddr * _addrframe_getnetaddr(AddrFrame *self)
Definition: addrframe.c:162
gpointer _addrbody
private: Address body
Definition: netaddr.h:58