The Assimilation Project
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ipportframe.c
Go to the documentation of this file.
1 
28 #include <string.h>
29 #include <projectcommon.h>
30 #include <frameset.h>
31 #include <ipportframe.h>
32 #include <frametypes.h>
33 #include <generic_tlv_min.h>
34 #include <tlvhelper.h>
35 #include <address_family_numbers.h>
36 
37 FSTATIC gboolean _ipportframe_default_isvalid(const Frame *, gconstpointer, gconstpointer);
38 FSTATIC void _ipportframe_setaddr(IpPortFrame* self, guint16 frametype, guint16 port, gconstpointer addr, gsize addrlen);
42 FSTATIC IpPortFrame* ipportframe_new(guint16 frame_type, gsize framesize);
43 FSTATIC gchar* _ipportframe_toString(gconstpointer aself);
45 
63 #define TLVOVERHEAD (sizeof(guint16)+sizeof(guint16))
64 #define TLVIPV4SIZE (TLVOVERHEAD+4)
65 #define TLVIPV6SIZE (TLVOVERHEAD+16)
66 
67 
74 FSTATIC gboolean
76  gconstpointer tlvptr,
77  gconstpointer pktend)
78 {
79  guint16 address_family = 0;
80  guint16 portnumber;
81  const guint16* int16ptr;
82  guint16 pktsize;
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  int16ptr = (const guint16*)self->value;
90  pktsize = self->length;
91  }else{
92  pktsize = get_generic_tlv_len(tlvptr, pktend);
93  int16ptr = (const guint16*)get_generic_tlv_value(tlvptr, pktend);
94  }
95 
96  if (pktsize < TLVIPV4SIZE || int16ptr == NULL) {
97  return FALSE;
98  }
99 
100  // First field -- port number: 16-bit unsigned integer - network byte order
101  portnumber = tlv_get_guint16(int16ptr, pktend);
102  if (portnumber == 0) {
103  g_warning("%s.%d: Port is zero", __FUNCTION__, __LINE__);
104  return FALSE;
105  }
106 
107  // Second field -- address family: 16-bit unsigned integer - network byte order
108  address_family = tlv_get_guint16(int16ptr+1, pktend);
109 
110  switch(address_family) {
111  case ADDR_FAMILY_IPV4: // IPv4
112  return (TLVIPV4SIZE == pktsize);
113 
114  case ADDR_FAMILY_IPV6: // IPv6
115  return (TLVIPV6SIZE == pktsize);
116 
117  default:
118  break;
119 
120  }
121  return FALSE;
122 }
123 
124 FSTATIC void
125 _ipportframe_setaddr(IpPortFrame* f, //<[in/out] Frame to set the address type for
126  guint16 addrtype, //<[in] IANA address type
127  guint16 port, //<[in] port
128  gconstpointer addr,//<[in] Address blob
129  gsize addrlen) //<[in] size of address
130 {
131  gsize blobsize = addrlen + (2*sizeof(guint16));
132  guint8* blob = MALLOC(blobsize);
133  guint8* blobend = blob + blobsize;
134 
135  g_return_if_fail(blob != NULL);
136 
137  if (f->baseclass.value != NULL) {
138  FREE(f->baseclass.value);
139  f->baseclass.value = NULL;
140  }
141 
142  tlv_set_guint16(blob, port, blobend);
143  tlv_set_guint16(blob+sizeof(guint16), addrtype, blobend);
144  memcpy(blob+sizeof(guint16)+sizeof(guint16), addr, addrlen);
145  f->baseclass.length = blobsize;
146  f->baseclass.value = blob;
147  f->port = port;
148  f->_addr = netaddr_new(0, 0, addrtype, addr, addrlen);
149  f->_addr->setport(f->_addr, port);
150 }
151 
152 
155 {
156  return self->_addr;
157 }
158 
159 
161 FSTATIC void
163 {
164  IpPortFrame* self = CASTTOCLASS(IpPortFrame, obj);
165  if (self->_addr) {
166  UNREF(self->_addr);
167  }
168  if (self->baseclass.value) {
169  FREE(self->baseclass.value);
170  self->baseclass.value = NULL;
171  }
172  self->_basefinal(CASTTOCLASS(AssimObj, self)); self = NULL;
173 }
174 
178 ipportframe_new(guint16 frame_type,
179  gsize framesize)
180 {
181  IpPortFrame* aframe;
182 
183  if (framesize < sizeof(IpPortFrame)){
184  framesize = sizeof(IpPortFrame);
185  }
186 
187  aframe = NEWSUBCLASS(IpPortFrame, frame_new(frame_type, framesize));
189 
191  aframe->_basefinal = aframe->baseclass.baseclass._finalize;
194  return aframe;
195 }
196 
199 ipportframe_ipv4_new(guint16 frame_type,
200  guint16 port,
202  gconstpointer addr)
203 {
204  IpPortFrame* ret;
205  g_return_val_if_fail(addr != NULL, NULL);
206  if (port == 0) {
207  return NULL;
208  }
209  ret = ipportframe_new(frame_type, 0);
210  g_return_val_if_fail(ret != NULL, NULL);
211  _ipportframe_setaddr(ret, ADDR_FAMILY_IPV4, port, addr, 4);
212  return ret;
213 }
214 
217 ipportframe_ipv6_new(guint16 frame_type,
218  guint16 port,
219  gconstpointer addr)
220 {
221  IpPortFrame* ret;
222  g_return_val_if_fail(addr != NULL, NULL);
223  if (port == 0) {
224  return NULL;
225  }
226  ret = ipportframe_new(frame_type, 0);
227  g_return_val_if_fail(ret != NULL, NULL);
228  _ipportframe_setaddr(ret, ADDR_FAMILY_IPV6, port, addr, 16);
229  return ret;
230 }
231 
234 ipportframe_netaddr_new(guint16 frame_type, NetAddr* addr)
235 {
236  guint16 port = addr->port(addr);
237  gpointer body = addr->_addrbody;
238 
239  if (port == 0) {
240  return NULL;
241  }
242 
243  switch(addr->addrtype(addr)) {
244  case ADDR_FAMILY_IPV4:
245  return ipportframe_ipv4_new(frame_type, port, body);
246  break;
247  case ADDR_FAMILY_IPV6:
248  return ipportframe_ipv6_new(frame_type, port, body);
249  break;
250  }
251  return NULL;
252 }
253 
254 
259 ipportframe_tlvconstructor(gconstpointer tlvstart,
260  gconstpointer pktend,
261  gpointer* ignorednewpkt,
262  gpointer* ignoredpktend)
263 
264 {
265  guint16 frametype = get_generic_tlv_type(tlvstart, pktend);
266  guint32 framelength = get_generic_tlv_len(tlvstart, pktend);
267  const guint8* framevalue = get_generic_tlv_value(tlvstart, pktend);
268  IpPortFrame * ret;
269  guint16 addr_family;
270  guint16 port;
271 
272 // +-------------+----------------+-------------+---------------+--------------------+
273 // | frametype | f_length | Port Number | Address Type | address-data |
274 // | 16 bits) | (24-bits) | 2 bytes | 2 bytes | (f_length-4 bytes) |
275 // +-------------+----------------+-------------+---------------+--------------------+
276  (void)ignorednewpkt; (void)ignoredpktend;
277  port = tlv_get_guint16(framevalue, pktend);
278  if (port == 0) {
279  return NULL;
280  }
281 
282  addr_family = tlv_get_guint16(framevalue+sizeof(guint16), pktend);
283 
284  switch (addr_family) {
285  case ADDR_FAMILY_IPV4:
286  g_return_val_if_fail(framelength == TLVIPV4SIZE, NULL);
287  break;
288  case ADDR_FAMILY_IPV6:
289  g_return_val_if_fail(framelength == TLVIPV6SIZE, NULL);
290  break;
291  default:
292  g_return_val_if_reached(NULL);
293  break;
294  }
295 
296  ret = ipportframe_new(frametype, 0);
297  ret->baseclass.length = framelength;
298  _ipportframe_setaddr(ret, addr_family, port, framevalue+TLVOVERHEAD
299  , framelength-TLVOVERHEAD);
300  if (!_ipportframe_default_isvalid(&ret->baseclass, tlvstart, pktend)) {
301  UNREF2(ret);
302  g_return_val_if_reached(NULL);
303  }
304  return &ret->baseclass;
305 }
307 FSTATIC gchar*
308 _ipportframe_toString(gconstpointer aself)
309 {
310  const IpPortFrame* self = CASTTOCONSTCLASS(IpPortFrame, aself);
311  char * selfstr = self->_addr->baseclass.toString(&self->_addr->baseclass);
312  char * ret;
313 
314  ret = g_strdup_printf("IpPortFrame(%d, %s)", self->baseclass.type, selfstr);
315  g_free(selfstr);
316  return ret;
317 }
Frame baseclass
Definition: ipportframe.h:41
guint32 length
Frame Length.
Definition: frame.h:46
guint16(* port)(const NetAddr *self)
Return port from this address.
Definition: netaddr.h:46
IETF/IANA Address family assignments.
FSTATIC void _ipportframe_setaddr(IpPortFrame *self, guint16 frametype, guint16 port, gconstpointer addr, gsize addrlen)
Definition: ipportframe.c:125
guint16(* addrtype)(const NetAddr *self)
Return IANA Address Family Numbers address type.
Definition: netaddr.h:47
WINEXPORT IpPortFrame * ipportframe_ipv6_new(guint16 frame_type, guint16 port, gconstpointer addr)
Construct and initialize an IPv6 IpPortFrame class.
Definition: ipportframe.c:217
AssimObj baseclass
Base object class for our Class system.
Definition: frame.h:44
#define TLVIPV6SIZE
IPv4 addresses are 16 bytes.
Definition: ipportframe.c:65
Implements minimal client-oriented Frame and Frameset capabilities.
WINEXPORT IpPortFrame * ipportframe_netaddr_new(guint16 frame_type, NetAddr *addr)
Construct and initialize an IpPortFrame class from a IP NetAddr class.
Definition: ipportframe.c:234
This is the base Frame class object (in-memory TLV (type, length, value)) for every general component...
Definition: frame.h:43
#define WINEXPORT
Definition: projectcommon.h:45
#define FSTATIC
Definition: projectcommon.h:31
gpointer value
Frame Value (pointer)
Definition: frame.h:47
guint16 port
Definition: ipportframe.h:43
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
guint16 get_generic_tlv_type(gconstpointer tlv_vp, gconstpointer pktend)
Return the 'Type' of the given TLV TLV entry (first two bytes)
void(* setport)(NetAddr *, guint16)
Set port for this NetAddr.
Definition: netaddr.h:45
#define __FUNCTION__
struct _IpPortFrame IpPortFrame
This is our IpPortFrame class object - used for holding NetAddr class network addresses with non-zero...
Definition: ipportframe.h:39
FSTATIC IpPortFrame * ipportframe_new(guint16 frame_type, gsize framesize)
Construct a new IpPortFrame class - allowing for "derived" frame types...
Definition: ipportframe.c:178
Frame * frame_new(guint16 frame_type, gsize framesize)
Construct a new frame - allowing for "derived" frame types...
Definition: frame.c:124
FSTATIC gchar * _ipportframe_toString(gconstpointer aself)
Convert IPaddrPortFrame object into a printable string.
Definition: ipportframe.c:308
#define TLVIPV4SIZE
IPv4 addresses are 4 bytes.
Definition: ipportframe.c:64
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
WINEXPORT Frame * ipportframe_tlvconstructor(gconstpointer tlvstart, gconstpointer pktend, gpointer *ignorednewpkt, gpointer *ignoredpktend)
Given marshalled packet data corresponding to an IpPortFrame (address), return the corresponding Fram...
Definition: ipportframe.c:259
#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.
#define TLVOVERHEAD
Definition: ipportframe.c:63
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 (IpPortFrame) C-Class.
FSTATIC void _ipportframe_setnetaddr(IpPortFrame *self, NetAddr *netaddr)
#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
gchar *(* toString)(gconstpointer)
Produce malloc-ed string representation.
Definition: assimobj.h:58
WINEXPORT IpPortFrame * ipportframe_ipv4_new(guint16 frame_type, guint16 port, gconstpointer addr)
Construct and initialize an IPv4 IpPortFrame class.
Definition: ipportframe.c:199
NetAddr *(* getnetaddr)(IpPortFrame *f)
Definition: ipportframe.h:45
NetAddr * _addr
Definition: ipportframe.h:42
FSTATIC void _ipportframe_finalize(AssimObj *)
Finalize an IpPortFrame.
Definition: ipportframe.c:162
#define ADDR_FAMILY_IPV4
IPv4.
FSTATIC gboolean _ipportframe_default_isvalid(const Frame *, gconstpointer, gconstpointer)
IpPortFrame class 'isvalid' member function - checks address type and length.
Definition: ipportframe.c:75
#define UNREF2(obj)
Definition: assimobj.h:36
FSTATIC NetAddr * _ipportframe_getnetaddr(IpPortFrame *self)
Definition: ipportframe.c:154
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: ipportframe.h:44
#define NEWSUBCLASS(Cclass, obj)
Definition: proj_classes.h:67
gpointer _addrbody
private: Address body
Definition: netaddr.h:58