Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


updates for user space utilities
[palacios.git] / misc / network_servers / vtl / raw_ethernet_packet.cc
1 #include <malloc.h>
2 #include <string.h>
3
4 #ifdef linux
5 #include <sys/socket.h>
6 #include <netinet/in.h>
7 #endif
8
9 #include "raw_ethernet_packet.h"
10 #include "util.h"
11 #include "debug.h"
12
13
14
15
16 RawEthernetPacket::RawEthernetPacket(){
17   type = pkt;
18   size = (size_t*)(pkt + (sizeof(char) * 2));
19   data = pkt + (sizeof(char) * 2) + sizeof(size_t);
20 }
21
22
23 RawEthernetPacket::RawEthernetPacket(const RawEthernetPacket &rhs) 
24 {
25   this->type = pkt;
26   this->size = (size_t*)(pkt + (sizeof(char) * 2));
27   this->data = pkt + (sizeof(char) * 2) + sizeof(size_t);
28   //  *(this->size)=*(rhs.size);
29   this->set_size(rhs.get_size());
30   memcpy(this->type, rhs.type, sizeof(char) * 2);
31   memcpy(this->data,rhs.data,*(this->size));
32 }
33
34 RawEthernetPacket::RawEthernetPacket(const char *data, const size_t size)
35 {
36   this->type = pkt;
37   this->size = (size_t*)(pkt + (sizeof(char) * 2));
38   this->data = pkt + (sizeof(char) * 2) + sizeof(size_t);
39   this->set_size(size);
40   memcpy(this->data,data,size);
41 }
42   
43
44 const RawEthernetPacket & RawEthernetPacket::operator= (const RawEthernetPacket &rhs)
45 {
46   this->type = pkt;
47   this->size = (size_t*)(pkt + (sizeof(char) * 2));
48   this->data = pkt + (sizeof(char) * 2) + sizeof(size_t);
49   this->set_size(rhs.get_size());
50   memcpy(data, rhs.data, *(size_t*)(this->size));
51
52   return *this;
53 }
54
55
56 RawEthernetPacket::~RawEthernetPacket() 
57 {} 
58
59
60 size_t RawEthernetPacket::get_size() const {
61   size_t t_size;
62   memcpy(&t_size, pkt+2, sizeof(size_t));
63   return t_size;
64 }
65
66 void RawEthernetPacket::set_size(size_t new_size) {
67   memcpy(this->pkt + (sizeof(char) * 2), &new_size, sizeof(size_t));
68 }
69
70 char * RawEthernetPacket::get_type() {
71   return pkt;
72 }
73
74 void RawEthernetPacket::set_type (const char * new_type)  {
75   memcpy(this->pkt, new_type, sizeof(char) * 2);
76 }
77
78 char * RawEthernetPacket::get_data() {
79   return this->pkt + (sizeof(char) * 2) + sizeof(size_t);
80 }
81
82
83 #ifdef USE_SSL
84 int RawEthernetPacket::Serialize(const SOCK fd, SSL * ssl) const {
85   int length = (sizeof(char)*2) + this->get_size() + sizeof(size_t); 
86   int ret = 0;
87
88   ret = Send(fd, ssl, pkt, length, true);
89   if (ret != (int)length) {
90     return -1;
91   }
92   return ret;
93 }
94
95
96 int RawEthernetPacket::Unserialize(const SOCK fd, SSL * ssl) {
97   int ret;
98   
99   ret = Receive(fd, ssl, pkt, sizeof(char) * 2 + sizeof(size_t), true);
100   if (ret == 0) {
101     vtl_debug("TCP socket closed\n");
102     return 0;
103   } else if (ret != (sizeof(char) * 2 + sizeof(size_t))) {
104     vtl_debug("Error unserializing packet header from tcp socket\n");
105     return -1;
106   }
107
108   vtl_debug("Receiving TCP data. size=%lu, offset=%d\n", this->get_size(), *(pkt + 2));
109
110   ret = Receive(fd, ssl, data, this->get_size(), true);
111   if (ret == 0) {
112     vtl_debug("TCP Socket closed\n");
113     return 0;
114   } else if (ret != (int)this->get_size()) {
115     vtl_debug("Error unserializing packet from tcp socket\n");
116     return -1;
117   }
118
119   return ret;
120 }
121 #endif
122 int RawEthernetPacket::Serialize(const SOCK fd) const {
123   int length = (sizeof(char)*2) + this->get_size() + sizeof(size_t); 
124   int ret = 0;
125
126   ret = Send(fd, pkt, length, true);
127   if (ret != (int)length) {
128     return -1;
129   }
130   return ret;
131 }
132
133
134 int RawEthernetPacket::Unserialize(const SOCK fd) {
135   int ret;
136   
137   ret = Receive(fd, pkt, sizeof(char) * 2 + sizeof(size_t), true);
138   if (ret == 0) {
139     vtl_debug("TCP socket closed\n");
140     return 0;
141   } else if (ret != (sizeof(char) * 2 + sizeof(size_t))) {
142     vtl_debug("Error unserializing packet header from tcp socket\n");
143     return -1;
144   }
145
146   vtl_debug("Receiving TCP data. size=%lu, offset=%d\n", this->get_size(), *(pkt + 2));
147
148   ret = Receive(fd, data, this->get_size(), true);
149   if (ret == 0) {
150     vtl_debug("TCP Socket closed\n");
151     return 0;
152   } else if (ret != (int)this->get_size()) {
153     vtl_debug("Error unserializing packet from tcp socket\n");
154     return -1;
155   }
156
157   return ret;
158 }
159
160
161
162 /* SRC_ROUTING: We need to add a long * to the arguments that we will
163    write the client address (int form) into */
164 int RawEthernetPacket::UdpUnserialize(const SOCK fd) {
165   struct sockaddr_in clientaddr; /*the client  address strcuture */
166   int clientlen = sizeof(clientaddr);
167
168   int length = 2 + sizeof(size_t)+ ETHERNET_PACKET_LEN;
169   int rcvd = 0;
170   
171   rcvd = recvfrom(fd, pkt,length,0,(struct sockaddr *)&clientaddr,(socklen_t *)&clientlen);
172   
173   return rcvd;
174 }
175
176 int RawEthernetPacket::UdpSerialize(const SOCK fd, struct sockaddr * serveraddr) const {
177   int len = sizeof(*serveraddr); 
178   int length;
179
180   int sent = 0;
181   length = sizeof(char)* 2 + this->get_size() + sizeof(size_t);
182
183   sent = sendto(fd,pkt,length,0,serveraddr,len);
184
185   return sent;
186 }
187
188 // JRL VTP
189 int RawEthernetPacket::VtpUnserialize(const SOCK fd, struct in_addr * serveraddr) {
190   int ret;
191   this->set_size((unsigned int)(-1));
192
193   ret = Receive(fd, pkt, sizeof(char) * 2, true);
194   if (ret == 0) {
195     vtl_debug("VTP connection has Closed\n");
196     return 0;
197   } else if (ret != (int)sizeof(char) * 2) {
198     vtl_debug("Could not read type from VTP packet\n");
199     return -1;
200   }
201
202   ret = Receive(fd, (char *)serveraddr, sizeof(struct in_addr), true);
203   if (ret == 0) {
204     vtl_debug("VTP connection has closed\n");
205     return 0;
206   } else if (ret != (int)sizeof(struct in_addr))  {
207     vtl_debug("Could not read VTP address info\n");
208     return -1;
209   }
210
211   ret = Receive(fd, (char *)size, sizeof(size_t), true);
212   if (ret == 0) {
213     vtl_debug("VTP connection has closed\n");
214     return 0;
215   } else if (ret != sizeof(size_t)) {
216     vtl_debug("Could not read VTP size\n");
217     return -1;
218   }
219   
220   ret = Receive(fd, data, this->get_size(), true);
221   if (ret == 0) {
222     vtl_debug("VTP connection has closed\n");
223     return 0;
224   } else if (ret != (int)this->get_size()) {
225     vtl_debug("Could not read VTP packet data\n");
226     return -1;
227   }
228
229   return ret;
230 }
231
232 int RawEthernetPacket::VtpSerialize(const SOCK fd, struct in_addr * serveraddr ) const {
233   int length;
234   int ret;
235
236   ret = Send(fd, type, sizeof(char) * 2, true);  
237   if (ret != sizeof(char) * 2) {
238     vtl_debug("Error writing type to VTP socket\n");
239     return -1;
240   }
241
242   ret = Send(fd, (char *)serveraddr, sizeof(struct in_addr), true);
243   if (ret != sizeof(struct in_addr)) {
244     vtl_debug("Error writing dest addr to VTP socket\n");
245     return -1;
246   }
247
248   length = this->get_size() + sizeof(size_t);
249
250   ret = Send(fd, pkt + (sizeof(char) * 2), length, true);
251   if (ret != (int)length) {
252     vtl_debug("ERROR writing packet length and data to VTP socket\n");
253     return -1;
254   }
255   
256   return ret;
257 }
258
259 // END JRL
260
261
262
263 #define MIN(x,y) ((x)<(y) ? (x) : (y))
264
265 void RawEthernetPacket::Print(unsigned size, FILE *out) const
266 {
267   fprintf(out,"raw_ethernet_packet: size %-4lu first %lu bytes: ", *(this->size), MIN(*(this->size), size));
268   printhexbuffer(out, data, MIN(*(this->size),size));
269   fprintf(out,"\n");
270 }
271
272 ostream & RawEthernetPacket::Print(ostream &os) const
273 {
274   char buf[10240];
275   unsigned n;
276   unsigned i;
277
278   snprintf(buf,2048,"RawEthernetPacket(size=%lu, bytes=",  this->get_size());
279   n=strlen(buf);
280   for (i=0;i<this->get_size();i++) { 
281     bytetohexbyte(data[i],&(buf[n+2*i]));
282   }
283   buf[n+2*i]=0;
284   os<<(char*)buf;
285   os<<", text=\"";
286   for (i=0;i<this->get_size();i++) {
287     char c= data[i];
288     if (c>=32 && c<=126) { 
289       os<<c;
290     } else {
291       os<<'.';
292     }
293   }
294   os << "\")";
295
296   return os;
297 }
298