1 /*
2 * fca-pkt.cc --
3 *
4 * FIXME: This file needs a description here.
5 *
6 * Copyright (c) 1997-2002 The Regents of the University of California.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * A. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * B. Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * C. Neither the names of the copyright holders nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
22 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <tclcl.h>
35 #include "config.h"
36 #include "misc/all-types.h"
37 #include "misc/debug.h"
38 #include "misc/nethost.h"
39 #include "fc.h"
40 #include "fca-pkt.h"
41
42
43 /*#define FCA_VERSION 1
44
45 #define PKT_FLOOR_REQUEST 1
46 #define PKT_FLOOR_CANCEL 2
47 #define PKT_FLOOR_RELEASE 3
48 #define PKT_GRANT_UPDATE 4
49 #define PKT_QUEUE_UPDATE 5
50 #define PKT_MODERATOR_SA 6
51 #define PKT_PARTICIPANT_SA 7
52 #define PKT_PARTICIPANT_RREQ 8
53 #define PKT_MODERATOR_RREQ 9
54 #define PKT_PARTICIPANT_RREPLY 10
55 #define PKT_MODERATOR_RREPLY 11
56
57
58 class FCA_Packet : public TclObject {
59 public:
60 static FCA_Packet *New();
61 static void Delete(FCA_Packet *packet);
62
63 FCA_Packet() { }
64
65 Bool Extract(u_char *&pb, int &len);
66 Bool ExtractFloorRequest (u_char *&pb, int &len);
67 Bool ExtractFloorCancel (u_char *&pb, int &len);
68 Bool ExtractFloorRelease (u_char *&pb, int &len);
69 Bool ExtractModeratorSA (u_char *&pb, int &len);
70 Bool ExtractParticipantSA(u_char *&pb, int &len);
71 Bool ExtractModeratorUpdate (u_char *&pb, int &len, u_int32_t pktType);
72 Bool ExtractGrantUpdateHelper(u_char *&pb, int &len);
73 Bool ExtractQueueUpdateHelper(u_char *&pb, int &len);
74
75 Bool Packetize(u_char *pb, int &len);
76 Bool PacketizeFloorRequest (u_char *&pb, int &len);
77 Bool PacketizeFloorCancel (u_char *&pb, int &len);
78 Bool PacketizeFloorRelease (u_char *&pb, int &len);
79 Bool PacketizeModeratorSA (u_char *&pb, int &len);
80 Bool PacketizeParticipantSA(u_char *&pb, int &len);
81 Bool PacketizeModeratorUpdate (u_char *&pb, int &len, u_int32_t pktType);
82 Bool PacketizeGrantUpdateHelper(u_char *&pb, int &len);
83 Bool PacketizeQueueUpdateHelper(u_char *&pb, int &len);
84
85 private:
86 void SetVar(const char *varname, const char *value);
87 void SetVar(const char *varname, u_int32_t value);
88 void SetVar(const char *varname, u_int16_t value);
89
90 void LAppendVar(const char *varname, const char *value);
91 void LAppendVar(const char *varname, u_int16_t value);
92
93 const char *GetVar(const char *varname);
94 void GetVar(const char *varname, u_int32_t &value);
95 void GetVar(const char *varname, u_int16_t &value);
96 void GetVar(const char *varname, SrcId &value);
97 void DGetVar(const char *varname, char *&value);
98
99 const char *LIndex(const char *varname, int index);
100 void LIndex(const char *varname, int index, u_int16_t &value);
101 void LIndex(const char *varname, int index, FCA_Packet *&value);
102
103 inline int roundoff(int value) {
104 return ((value % 4 == 0) ? value : (value/4 + 1) * 4);
105 }
106
107 inline void incr(u_char *&pb, int &len, int howMuch) {
108 pb += howMuch;
109 len -= howMuch;
110 }
111 };*/
112
113
114 static char *pktTypeStrings[] = {
115 "",
116 "PKT_FLOOR_REQUEST",
117 "PKT_FLOOR_CANCEL",
118 "PKT_FLOOR_RELEASE",
119 "PKT_GRANT_UPDATE",
120 "PKT_QUEUE_UPDATE",
121 "PKT_MODERATOR_SA",
122 "PKT_PARTICIPANT_SA",
123 "PKT_PARTICIPANT_RREQ",
124 "PKT_MODERATOR_RREQ",
125 "PKT_PARTICIPANT_RREPLY",
126 "PKT_MODERATOR_RREPLY",
127 "PKT_OBSOLETE"
128 };
129
130
131
132 static class FCA_PacketClass : public TclClass {
133 public:
134 FCA_PacketClass() : TclClass("FCA_Packet") { }
135 ~FCA_PacketClass() { }
136 TclObject *create(int /*argc*/, const char*const* /*argv*/) {
137 return new FCA_Packet;
138 }
139 } fca_PacketClass;
140
141
142
143
144
145 /*
146 * Format of the FloorControl packet header.
147 * The transport level header.
148 */
149 struct Pkt_FCA_Hdr {
150 u_int16_t version; /* version number */
151 u_int16_t pktType; /* the type of packet */
152 };
153
154
155 /*
156 * Packet header contains (paran contain the OTcl instvar name for the field):
157 * Version: 2 bytes (not stored)
158 * Packet Type: 2 bytes (pktType)
159 */
160
161 Bool
162 FCA_Packet::Extract(u_char *&pb, int &len)
163 {
164 if (len < int(sizeof(Pkt_FCA_Hdr))) {
165 Debug(dbgFCA, ("Warning: FCA packet is too small (%d bytes); ignoring",
166 len));
167 return FALSE;
168 }
169
170 Pkt_FCA_Hdr *pHdr = (Pkt_FCA_Hdr*)pb;
171 u_int16_t version = net2host(pHdr->version);
172 if (version!=FCA_VERSION) {
173 Debug(dbgFCA, ("Warning: Version mismatch: expected %d, got %d",
174 FCA_VERSION, version));
175 return FALSE;
176 }
177
178 u_int16_t pktType = net2host(pHdr->pktType);
179 this->SetVar("pktType", pktTypeStrings[pktType]); // <---
180
181 incr(pb, len, sizeof(Pkt_FCA_Hdr));
182
183
184 switch (pktType) {
185 case PKT_FLOOR_REQUEST:
186 return ExtractFloorRequest(pb, len);
187
188 case PKT_FLOOR_CANCEL:
189 return ExtractFloorCancel(pb, len);
190
191 case PKT_FLOOR_RELEASE:
192 return ExtractFloorRelease(pb, len);
193
194 case PKT_GRANT_UPDATE:
195 return ExtractModeratorUpdate(pb, len, pktType);
196
197 case PKT_QUEUE_UPDATE:
198 return ExtractModeratorUpdate(pb, len, pktType);
199
200 case PKT_MODERATOR_SA:
201 return ExtractModeratorSA(pb, len);
202
203 case PKT_PARTICIPANT_SA:
204 return ExtractParticipantSA(pb, len);
205
206 case PKT_PARTICIPANT_RREQ:
207 return ExtractParticipantRreq(pb, len);
208
209 case PKT_MODERATOR_RREQ:
210 return ExtractModeratorRreq(pb, len);
211
212 case PKT_PARTICIPANT_RREPLY:
213 return ExtractParticipantRreply(pb, len);
214
215 case PKT_MODERATOR_RREPLY:
216 return ExtractModeratorRreply(pb, len);
217
218 default:
219 Debug(dbgFCA, ("Invalid packet type; ignoring it"));
220 return FALSE;
221 }
222 }
223
224
225 Bool
226 FCA_Packet::Packetize(u_char *pb, int &len)
227 {
228 u_char *origPB = pb;
229 Bool returnValue;
230 if (len < int(sizeof(Pkt_FCA_Hdr))) {
231 Debug(dbgFCA, ("Warning: FCA packet is too small (%d bytes); ignoring",
232 len));
233 return FALSE;
234 }
235
236 const char *pktTypeStr = this->GetVar("pktType");
237 u_int16_t pktType = 0;
238 for (int i=0; i < int(sizeof(pktTypeStrings)/sizeof(char*)); i++) {
239 if (strcmp(pktTypeStr, pktTypeStrings[i])==0) {
240 pktType = i;
241 break;
242 }
243 }
244
245 Pkt_FCA_Hdr *pHdr = (Pkt_FCA_Hdr*) pb;
246 pHdr->version = host2net((u_int16_t)FCA_VERSION);
247 pHdr->pktType = host2net(pktType);
248
249 incr(pb, len, sizeof(Pkt_FCA_Hdr));
250
251 switch (pktType) {
252 case PKT_FLOOR_REQUEST:
253 returnValue = PacketizeFloorRequest(pb, len);
254 break;
255
256 case PKT_FLOOR_CANCEL:
257 returnValue = PacketizeFloorCancel(pb, len);
258 break;
259
260 case PKT_FLOOR_RELEASE:
261 returnValue = PacketizeFloorRelease(pb, len);
262 break;
263
264 case PKT_GRANT_UPDATE:
265 returnValue = PacketizeModeratorUpdate(pb, len, pktType);
266 break;
267
268 case PKT_QUEUE_UPDATE:
269 returnValue = PacketizeModeratorUpdate(pb, len, pktType);
270 break;
271
272 case PKT_MODERATOR_SA:
273 returnValue = PacketizeModeratorSA(pb, len);
274 break;
275
276 case PKT_PARTICIPANT_SA:
277 returnValue = PacketizeParticipantSA(pb, len);
278 break;
279
280 case PKT_PARTICIPANT_RREQ:
281 return PacketizeParticipantRreq(pb, len);
282
283 case PKT_MODERATOR_RREQ:
284 return PacketizeModeratorRreq(pb, len);
285
286 case PKT_PARTICIPANT_RREPLY:
287 return PacketizeParticipantRreply(pb, len);
288
289 case PKT_MODERATOR_RREPLY:
290 return PacketizeModeratorRreply(pb, len);
291
292 default:
293 Debug(dbgFCA, ("Invalid packet type; ignoring it"));
294 return FALSE;
295 }
296 if (returnValue==TRUE) {
297 len = pb - origPB;
298 }
299 return returnValue;
300 }
301
302
303
304 /*
305 * PKT_FLOORREQUEST:
306 * Request ID: 4 bytes (requestId)
307 * Comment: some multiple of 4 bytes (comment)
308 * number of floors: 4 bytes (numFloors)
309 * floor type: sequence of 1 bytes (floors - Tcl list)
310 * (extra padding required to get total # of floor types to be multiple of 4)
311 */
312 Bool
313 FCA_Packet::ExtractFloorRequest(u_char *&pb, int &len)
314 {
315 if (len < int(sizeof(u_int32_t))) {
316 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
317 return FALSE;
318 }
319
320 u_int32_t requestId = net2host(*(u_int32_t*)pb);
321 incr(pb, len, sizeof(u_int32_t));
322 this->SetVar("requestId", requestId); // <---
323 Debug (dbgFCA, ("requestId = %lu", requestId));
324 if (len==0) {
325 this->SetVar("comment", ""); // <---
326 } else {
327 this->SetVar("comment", (char*)pb); // <---
328 Debug (dbgFCA, ("comment = %s", (char*)pb));
329
330 incr(pb, len, roundoff(strlen((char*)pb) + 1));
331 }
332 if (len < int(sizeof(u_int32_t))) {
333 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
334 return FALSE;
335 }
336
337 u_int32_t numFloors = net2host(*(u_int32_t*)pb);
338 this->SetVar("numFloors", numFloors); // <---
339 Debug (dbgFCA, ("numFloors = %lu", numFloors));
340 incr(pb, len, sizeof(u_int32_t));
341 if (len < roundoff(numFloors)) {
342 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
343 return FALSE;
344 }
345
346 this->SetVar("floors", ""); // <--- (in case numFloors is 0)
347 for (int i=0; i < int(numFloors); i++) {
348 this->LAppendVar("floors", (u_int16_t) (*(pb+i))); // <---
349 Debug (dbgFCA, ("floor = %lu", (*(pb+i))));
350 }
351 incr(pb, len, roundoff(numFloors));
352 return TRUE;
353 }
354
355
356 Bool
357 FCA_Packet::PacketizeFloorRequest(u_char *&pb, int &len)
358 {
359 u_int32_t requestId, numFloors;
360 char *comment;
361
362 this->GetVar("requestId", requestId);
363 this->DGetVar("comment", comment);
364 this->GetVar("numFloors", numFloors);
365
366 if (len < int(sizeof(u_int32_t) + roundoff(strlen(comment)+1)
367 + sizeof(u_int32_t) + numFloors * sizeof(Byte)) ) {
368 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
369 return FALSE;
370 }
371
372 *((u_int32_t*) pb) = host2net(requestId); // <---
373 incr(pb, len, sizeof(u_int32_t));
374
375 strcpy((char*)pb, comment); // <---
376 incr(pb, len, roundoff(strlen(comment)+1));
377 delete [] comment;
378
379 *((u_int32_t*) pb) = host2net(numFloors); // <---
380 incr(pb, len, sizeof(u_int32_t));
381
382 u_int16_t floorType;
383 for (int i=0; i < int(numFloors); i++) {
384 this->LIndex("floors", i, floorType);
385 *(pb+i) = (u_char) floorType; // <---
386 }
387 incr(pb, len, roundoff(numFloors));
388 return TRUE;
389 }
390
391
392 /*
393 * PKT_FLOORCANCEL:
394 * Sequence no: 4 bytes (seqno)
395 * Request ID: 4 bytes (requestId)
396 */
397 Bool
398 FCA_Packet::ExtractFloorCancel(u_char *&pb, int &len)
399 {
400 if (len < int(2 * sizeof(u_int32_t))) {
401 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
402 return FALSE;
403 }
404
405 u_int32_t seqno = net2host(*(u_int32_t*)pb);
406 incr(pb, len, sizeof(u_int32_t));
407 this->SetVar("seqno", seqno); // <---
408
409 u_int32_t requestId = net2host(*(u_int32_t*)pb);
410 incr(pb, len, sizeof(u_int32_t));
411 this->SetVar("requestId", requestId); // <---
412
413 return TRUE;
414 }
415
416
417 Bool
418 FCA_Packet::PacketizeFloorCancel(u_char *&pb, int &len)
419 {
420 if (len < int(sizeof(u_int32_t))) {
421 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
422 return FALSE;
423 }
424
425 u_int32_t uint;
426 this->GetVar("seqno", uint);
427 *((u_int32_t*) pb) = host2net(uint); // <---
428 incr(pb, len, sizeof(u_int32_t));
429
430 this->GetVar("requestId", uint);
431 *((u_int32_t*) pb) = host2net(uint); // <---
432 incr(pb, len, sizeof(u_int32_t));
433
434 return TRUE;
435 }
436
437
438 struct Pkt_FloorRelease {
439 u_int32_t seqno;
440 u_int32_t grantSeqno;
441 Byte floorType;
442 Byte floorInstance;
443 u_int16_t padding;
444 };
445
446
447 /*
448 * PKT_FLOORRELEASE:
449 * struct Pkt_FloorRelease {
450 * u_int32_t seqno;
451 * u_int32_t grantSeqno;
452 * Byte floorType;
453 * Byte floorInstance;
454 * u_int16_t padding;
455 * };
456 */
457 Bool
458 FCA_Packet::ExtractFloorRelease(u_char *&pb, int &len)
459 {
460 if (len < int(sizeof(Pkt_FloorRelease))) {
461 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
462 return FALSE;
463 }
464
465 Pkt_FloorRelease *pRelease = (Pkt_FloorRelease*) pb;
466 incr(pb, len, sizeof(Pkt_FloorRelease));
467
468 this->SetVar("seqno", net2host(pRelease->seqno)); // <---
469 this->SetVar("grantSeqno", net2host(pRelease->grantSeqno)); // <---
470 this->SetVar("floorType", (u_int16_t) pRelease->floorType); // <---
471 this->SetVar("floorInstance", (u_int16_t) pRelease->floorInstance); // <---
472 return TRUE;
473 }
474
475
476 Bool
477 FCA_Packet::PacketizeFloorRelease(u_char *&pb, int &len)
478 {
479 if (len < int(sizeof(Pkt_FloorRelease))) {
480 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
481 return FALSE;
482 }
483
484 u_int16_t tmp;
485 Pkt_FloorRelease *pUpdate = (Pkt_FloorRelease*) pb;
486 this->GetVar("seqno", pUpdate->seqno); // <---
487 this->GetVar("grantSeqno", pUpdate->grantSeqno); // <---
488 this->GetVar("floorType", tmp);
489 pUpdate->floorType = (Byte) tmp; // <---
490 this->GetVar("floorInstance", tmp);
491 pUpdate->floorInstance = (Byte) tmp; // <---
492 incr(pb, len, sizeof(Pkt_FloorRelease));
493
494 pUpdate->seqno = host2net(pUpdate->seqno); // <---
495 pUpdate->grantSeqno = host2net(pUpdate->grantSeqno); // <---
496 pUpdate->floorType = host2net(pUpdate->floorType); // <---
497 pUpdate->floorInstance= host2net(pUpdate->floorInstance); // <---
498 return TRUE;
499 }
500
501
502
503
504
505 struct Pkt_ModeratorUpdate {
506 u_int32_t moderatorState;
507 u_int32_t numUpdates;
508 };
509
510
511 struct Pkt_GrantUpdate {
512 SrcId srcId;
513 u_int32_t grantSeqno;
514 u_int32_t requestId;
515 Byte floorType;
516 Byte floorInstance;
517 u_int16_t padding;
518 };
519
520
521 struct Pkt_QueueUpdate {
522 SrcId srcId;
523 u_int32_t requestId;
524 Byte isAdd;
525 Byte padding[3];
526 };
527
528
529 /*
530 * PKT_MODERATOR_UPDATE:
531 * struct Pkt_ModeratorUpdate {
532 * u_int32_t moderatorState; (moderatorState)
533 * u_int32_t numUpdates; (numUpdates)
534 * };
535 *
536 * a number of Pkt_GrantUpdate/Pkt_QueueUpdate's
537 * (pktUpdates - Tcl list of pkt objects)
538 */
539 Bool
540 FCA_Packet::ExtractModeratorUpdate(u_char *&pb, int &len, u_int32_t pktType)
541 {
542 Debug(dbgFCA, ("Got %d bytes in moderator update pkt", len));
543 if (len < int(sizeof(Pkt_ModeratorUpdate))) {
544 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
545 return FALSE;
546 }
547
548 Pkt_ModeratorUpdate *pUpdate = (Pkt_ModeratorUpdate*) pb;
549 u_int32_t numUpdates = net2host(pUpdate->numUpdates);
550 this->SetVar("moderatorState", net2host(pUpdate->moderatorState)); // <---
551 this->SetVar("numUpdates", numUpdates); // <---
552 incr(pb, len, sizeof(Pkt_ModeratorUpdate));
553
554 FCA_Packet *updatePkt;
555 for (int i=0; i < int(numUpdates); i++) {
556 updatePkt = FCA_Packet::New();
557 switch (pktType) {
558 case PKT_GRANT_UPDATE:
559 if (updatePkt->ExtractGrantUpdateHelper(pb, len)==FALSE) // <---
560 return FALSE;
561 break;
562
563 case PKT_QUEUE_UPDATE:
564 if (updatePkt->ExtractQueueUpdateHelper(pb, len)==FALSE) // <---
565 return FALSE;
566 break;
567 }
568 this->LAppendVar("pktUpdates", updatePkt->name()); // <---
569 }
570 return TRUE;
571 }
572
573
574 Bool
575 FCA_Packet::PacketizeModeratorUpdate(u_char *&pb, int &len, u_int32_t pktType)
576 {
577 if (len < int(sizeof(Pkt_ModeratorUpdate))) {
578 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
579 return FALSE;
580 }
581
582 u_int32_t moderatorState;
583 this->GetVar("moderatorState", moderatorState);
584 u_int32_t numUpdates;
585 this->GetVar("numUpdates", numUpdates);
586
587 Pkt_ModeratorUpdate *pUpdate = (Pkt_ModeratorUpdate*) pb;
588 pUpdate->moderatorState = host2net(moderatorState); // <---
589 pUpdate->numUpdates = host2net(numUpdates); // <---
590 incr(pb, len, sizeof(Pkt_ModeratorUpdate));
591
592 if (len < int(numUpdates * sizeof(Pkt_GrantUpdate))) {
593 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
594 return FALSE;
595 }
596
597 FCA_Packet *updatePkt;
598 for (int i=0; i < int(numUpdates); i++) {
599 this->LIndex("pktUpdates", i, updatePkt);
600
601 switch (pktType) {
602 case PKT_GRANT_UPDATE:
603 if (updatePkt->PacketizeGrantUpdateHelper(pb, len)==FALSE) // <---
604 return FALSE;
605 break;
606
607 case PKT_QUEUE_UPDATE:
608 if (updatePkt->PacketizeQueueUpdateHelper(pb, len)==FALSE) // <---
609 return FALSE;
610 break;
611 }
612 }
613 return TRUE;
614 }
615
616
617 /*
618 * struct Pkt_GrantUpdate {
619 * SrcId srcId; (srcId)
620 * u_int32_t grantSeqno; (grantSeqno)
621 * u_int32_t requestId; (requestId)
622 * Byte floorType; (floorType)
623 * Byte floorInstance; (floorInstance)
624 * u_int16_t padding;
625 * };
626 */
627 Bool
628 FCA_Packet::ExtractGrantUpdateHelper(u_char *&pb, int &len)
629 {
630 if (len < int(sizeof(Pkt_GrantUpdate))) {
631 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
632 return FALSE;
633 }
634
635 Pkt_GrantUpdate *pUpdate = (Pkt_GrantUpdate*) pb;
636 incr(pb, len, sizeof(Pkt_GrantUpdate));
637 SrcId sid = pUpdate->srcId;
638 sid.ss_uid = net2host(sid.ss_uid);
639
640 this->SetVar("srcId", (const char*) sid); // <---
641 this->SetVar("grantSeqno", net2host(pUpdate->grantSeqno)); // <---
642 this->SetVar("requestId", net2host(pUpdate->requestId)); // <---
643 this->SetVar("floorType", (u_int16_t) pUpdate->floorType); // <---
644 this->SetVar("floorInstance", (u_int16_t) pUpdate->floorInstance); // <---
645 //this->SetVar("isGrant", (u_int16_t) pUpdate->isGrant); // <---
646 return TRUE;
647 }
648
649
650
651 Bool
652 FCA_Packet::PacketizeGrantUpdateHelper(u_char *&pb, int &len)
653 {
654 if (len < int(sizeof(Pkt_GrantUpdate))) {
655 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
656 return FALSE;
657 }
658
659 u_int16_t tmp;
660 Pkt_GrantUpdate *pUpdate = (Pkt_GrantUpdate*) pb;
661 this->GetVar("srcId", pUpdate->srcId); // <---
662 this->GetVar("grantSeqno", pUpdate->grantSeqno); // <---
663 this->GetVar("requestId", pUpdate->requestId); // <---
664 this->GetVar("floorType", tmp);
665 pUpdate->floorType = (Byte) tmp; // <---
666 this->GetVar("floorInstance", tmp);
667 pUpdate->floorInstance = (Byte) tmp; // <---
668 /*this->GetVar("isGrant", tmp);
669 pUpdate->isGrant = (Byte) tmp; // <---*/
670
671 incr(pb, len, sizeof(Pkt_GrantUpdate));
672
673 pUpdate->srcId.ss_uid = host2net(pUpdate->srcId.ss_uid); // <---
674 pUpdate->grantSeqno = host2net(pUpdate->grantSeqno); // <---
675 pUpdate->requestId = host2net(pUpdate->requestId); // <---
676 pUpdate->floorType = host2net(pUpdate->floorType); // <---
677 pUpdate->floorInstance= host2net(pUpdate->floorInstance); // <---
678 //pUpdate->isGrant = host2net(pUpdate->isGrant); // <---
679 return TRUE;
680 }
681
682
683
684 /*
685 * PKT_QUEUEUPDATE
686 * struct Pkt_QueueUpdate {
687 * SrcId srcID; (srcId)
688 * u_int32_t requestId; (requestId)
689 * Byte isAdd; (isAdd) // isAdd=1 => I'm adding this
690 * // entry; 0 => deleting
691 * Byte padding[3];
692 * };
693 */
694 Bool
695 FCA_Packet::ExtractQueueUpdateHelper(u_char *&pb, int &len)
696 {
697 if (len < int(sizeof(Pkt_QueueUpdate))) {
698 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
699 return FALSE;
700 }
701
702 Pkt_QueueUpdate *pUpdate = (Pkt_QueueUpdate*) pb;
703 SrcId sid = pUpdate->srcId;
704 sid.ss_uid = net2host(sid.ss_uid);
705
706 this->SetVar("srcId", (const char*) sid); // <---
707 this->SetVar("requestId", net2host(pUpdate->requestId)); // <---
708 this->SetVar("isAdd", (u_int16_t) net2host(pUpdate->isAdd)); // <---
709
710 incr(pb, len, sizeof(Pkt_QueueUpdate));
711 return TRUE;
712 }
713
714
715 Bool
716 FCA_Packet::PacketizeQueueUpdateHelper(u_char *&pb, int &len)
717 {
718 if (len < int(sizeof(Pkt_QueueUpdate))) {
719 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
720 return FALSE;
721 }
722
723 u_int16_t tmpIsAdd;
724 Pkt_QueueUpdate *pUpdate = (Pkt_QueueUpdate*) pb;
725 this->GetVar("srcId", pUpdate->srcId); // <---
726 this->GetVar("requestId", pUpdate->requestId); // <---
727 this->GetVar("isAdd", tmpIsAdd); // <---
728
729 pUpdate->srcId.ss_uid = host2net(pUpdate->srcId.ss_uid); // <---
730 pUpdate->requestId = host2net(pUpdate->requestId); // <---
731 pUpdate->isAdd = host2net((Byte)tmpIsAdd); // <---
732
733 incr(pb, len, sizeof(Pkt_QueueUpdate));
734 return TRUE;
735 }
736
737
738 /*
739 * PKT_MODERATOR_SA:
740 * current moderator state: 4 bytes (currentState)
741 * followed by PKT_PARTICIPANT_SA
742 */
743 Bool
744 FCA_Packet::ExtractModeratorSA(u_char *&pb, int &len)
745 {
746 if (len < int(sizeof(u_int32_t))) {
747 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
748 return FALSE;
749 }
750
751 u_int32_t currentState = net2host(*(u_int32_t*)pb);
752 incr(pb, len, sizeof(u_int32_t));
753 this->SetVar("currentState", currentState); // <---
754 return this->ExtractParticipantSA(pb, len); // <--
755 }
756
757
758 Bool
759 FCA_Packet::PacketizeModeratorSA(u_char *&pb, int &len)
760 {
761 u_int32_t currentState;
762 if (len < int(sizeof(u_int32_t))) {
763 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
764 return FALSE;
765 }
766
767 this->GetVar("currentState", currentState);
768 currentState = host2net(currentState);
769 *((u_int32_t*)pb) = currentState; // <---
770 incr(pb, len, sizeof(u_int32_t));
771 return this->PacketizeParticipantSA(pb, len); // <---
772 }
773
774
775 struct Pkt_ParticipantSA {
776 u_int32_t maxRequestId;
777 u_int32_t maxImportantSeqno; /* cancel or release message */
778 };
779
780
781 /*
782 * PKT_PARTICIPANT_SA:
783 * struct Pkt_ParticipantSA {
784 * u_int32_t maxRequestId; (maxRequestId)
785 * u_int32_t maxImportantSeqno; (maxImportantSeqno)
786 * };
787 */
788 Bool
789 FCA_Packet::ExtractParticipantSA(u_char *&pb, int &len)
790 {
791 if (len < int(sizeof(Pkt_ParticipantSA))) {
792 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
793 return FALSE;
794 }
795
796 Pkt_ParticipantSA *pSA = (Pkt_ParticipantSA*) pb;
797 incr(pb, len, sizeof(Pkt_ParticipantSA));
798
799 this->SetVar("maxRequestId", net2host(pSA->maxRequestId)); // <---
800 this->SetVar("maxImportantSeqno", net2host(pSA->maxImportantSeqno)); //<---
801 return TRUE;
802 }
803
804
805 Bool
806 FCA_Packet::PacketizeParticipantSA(u_char *&pb, int &len)
807 {
808 if (len < int(sizeof(Pkt_ParticipantSA))) {
809 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
810 return FALSE;
811 }
812
813 Pkt_ParticipantSA *pSA = (Pkt_ParticipantSA*) pb;
814 incr(pb, len, sizeof(Pkt_ParticipantSA));
815
816 this->GetVar("maxRequestId", pSA->maxRequestId); // <---
817 this->GetVar("maxImportantSeqno", pSA->maxImportantSeqno); // <---
818 pSA->maxRequestId = host2net(pSA->maxRequestId); // <---
819 pSA->maxImportantSeqno = host2net(pSA->maxImportantSeqno); // <---
820 return TRUE;
821 }
822
823
824
825 struct Pkt_ParticipantRreq {
826 u_int32_t isImportant; // isImportant=0 => floor_request
827 u_int32_t start;
828 u_int32_t end;
829 };
830
831
832 /*
833 * PKT_PARTICIPANT_RREQ:
834 * number of requests: 4 bytes (numRequests)
835 * followed by a number of Pkt_Participant_Rreq's (list)
836 * (each element in "list" is a triple of <isImportant, start, end>)
837 */
838 Bool
839 FCA_Packet::ExtractParticipantRreq(u_char *&pb, int &len)
840 {
841
842 if (len < int(sizeof(u_int32_t))) {
843 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
844 return FALSE;
845 }
846
847 u_int32_t numRequests = net2host(*(u_int32_t*)pb);
848 incr(pb, len, sizeof(u_int32_t));
849 this->SetVar("numRequests", numRequests); // <---
850 Debug(dbgFCA, ("ExtractParticipantRreq, numRequests = %d", numRequests));
851 if (len < int(numRequests * sizeof(Pkt_ParticipantRreq))) {
852 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
853 }
854
855 this->SetVar("list", ""); // <---
856 static char buffer[256];
857 Pkt_ParticipantRreq *pRreq;
858 pRreq = (Pkt_ParticipantRreq*) pb;
859 incr(pb, len, numRequests * sizeof(Pkt_ParticipantRreq));
860
861 for (int i=0; i < int(numRequests); i++, pRreq++) {
862 sprintf(buffer, "%lu %lu %lu",
863 (unsigned long) net2host(pRreq->isImportant),
864 (unsigned long) net2host(pRreq->start),
865 (unsigned long) net2host(pRreq->end));
866 this->LAppendVar("list", buffer); // <---
867 Debug(dbgFCA, ("ExtractParticipantRreq, list buffer: %s",buffer));
868
869 }
870 return TRUE;
871 }
872
873
874 Bool
875 FCA_Packet::PacketizeParticipantRreq(u_char *&pb, int &len)
876 {
877 if (len < int(sizeof(u_int32_t))) {
878 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
879 return FALSE;
880 }
881
882 u_int32_t numRequests;
883 this->GetVar("numRequests", numRequests);
884 Debug(dbgFCA, ("PacketizeParticipantRreq, numRequests = %d", numRequests));
885 *((u_int32_t*) pb) = host2net(numRequests); // <---
886 incr(pb, len, sizeof(u_int32_t));
887
888 if (len < int(numRequests * sizeof(Pkt_ParticipantRreq))) {
889 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
890 }
891
892 Pkt_ParticipantRreq *pRreq;
893 pRreq = (Pkt_ParticipantRreq*) pb;
894 incr(pb, len, numRequests * sizeof(Pkt_ParticipantRreq));
895 const char *buffer;
896
897 for (int i=0; i < int(numRequests); i++, pRreq++) {
898 Debug(dbgFCA, ("About to call LIndex"));
899 buffer = this->LIndex("list", i);
900 Debug(dbgFCA, ("PacketizeParticipantRreq, list buffer: %s",buffer));
901 pRreq->isImportant = 0;
902 pRreq->start = 0;
903 pRreq->end = 0;
904 sscanf(buffer, "%lu %lu %lu", (unsigned long *) &pRreq->isImportant,
905 (unsigned long *) &pRreq->start,
906 (unsigned long *) &pRreq->end);
907 Debug(dbgFCA, ("PacketizeParticipantRreq: list %lu %lu %lu", pRreq->isImportant, pRreq->start, pRreq->end));
908 pRreq->isImportant = host2net(pRreq->isImportant);
909 pRreq->start = host2net(pRreq->start);
910 pRreq->end = host2net(pRreq->end);
911 Debug(dbgFCA, ("PacketizeParticipantRreq: list %lu %lu %lu", pRreq->isImportant, pRreq->start, pRreq->end));
912 }
913 return TRUE;
914 }
915
916
917 /*
918 * PKT_MODERATOR_RREQ:
919 * requestor's idea of the moderator's state #: 4 bytes (moderatorState)
920 */
921 Bool
922 FCA_Packet::ExtractModeratorRreq(u_char *&pb, int &len)
923 {
924 if (len < int(sizeof(u_int32_t))) {
925 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
926 return FALSE;
927 }
928
929 u_int32_t moderatorState = net2host(*(u_int32_t*)pb);
930 incr(pb, len, sizeof(u_int32_t));
931 this->SetVar("moderatorState", moderatorState); // <---
932 return TRUE;
933 }
934
935
936 Bool
937 FCA_Packet::PacketizeModeratorRreq(u_char *&pb, int &len)
938 {
939 if (len < int(sizeof(u_int32_t))) {
940 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
941 return FALSE;
942 }
943
944 u_int32_t moderatorState;
945 this->GetVar("moderatorState", moderatorState);
946 *((u_int32_t*) pb) = host2net(moderatorState); // <---
947 incr(pb, len, sizeof(u_int32_t));
948 return TRUE;
949 }
950
951
952
953 /*
954 * PKT_PARTICIPANT_RREPLY:
955 * number of sub-packets: 4 bytes (numReplies)
956 * followed by a bunch of PKT_FLOOR_REQUEST, PKT_FLOOR_CANCEL,
957 * PKT_FLOOR_RELEASE, or PKT_OBSOLETE (pktReplies)
958 * (each packet contains an initial 4-byte pktType entry in addition to the
959 * usual stuff)
960 */
961 Bool
962 FCA_Packet::ExtractParticipantRreply(u_char *&pb, int &len)
963 {
964 if (len < int(sizeof(u_int32_t))) {
965 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
966 return FALSE;
967 }
968
969 u_int32_t numReplies = net2host(*(u_int32_t*)pb);
970 incr(pb, len, sizeof(u_int32_t));
971 this->SetVar("numReplies", numReplies); // <---
972 Debug(dbgFCA, ("ExtractParticipantRreply, numReplies (%lu)",
973 numReplies));
974
975 u_int32_t pktType;
976 FCA_Packet *pkt;
977 this->SetVar("pktReplies", "");
978 for (int i=0; i < int(numReplies); i++) {
979 if (len < int(sizeof(u_int32_t))) {
980 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
981 return FALSE;
982 }
983 Debug(dbgFCA, ("about to new the packet"));
984 pkt = FCA_Packet::New();
985 pktType = net2host(*(u_int32_t*)pb);
986 incr(pb, len, sizeof(u_int32_t));
987 pkt->SetVar("pktType", pktTypeStrings[pktType]); // <---
988 Debug(dbgFCA, ("ExtractParticipantRreply, pktType (%lu)", pktType));
989 switch(pktType) {
990 case PKT_FLOOR_REQUEST:
991 Debug (dbgFCA, ("it is a floor request"));
992 if (pkt->ExtractFloorRequest(pb, len)==FALSE) {
993 Debug (dbgFCA, ("ExtractParticipantRreply, "
994 "unable to extract floor request"));
995 FCA_Packet::Delete(pkt);
996 return FALSE;
997 }
998 break;
999
1000 case PKT_FLOOR_CANCEL:
1001 if (pkt->ExtractFloorCancel(pb, len)==FALSE) {
1002 FCA_Packet::Delete(pkt);
1003 return FALSE;
1004 }
1005 break;
1006
1007 case PKT_FLOOR_RELEASE:
1008 if (pkt->ExtractFloorRelease(pb, len)==FALSE) {
1009 FCA_Packet::Delete(pkt);
1010 return FALSE;
1011 }
1012 break;
1013
1014 case PKT_OBSOLETE:
1015 if (pkt->ExtractObsolete(pb, len)==FALSE) {
1016 FCA_Packet::Delete(pkt);
1017 return FALSE;
1018 }
1019 break;
1020
1021 default:
1022 Debug (dbgFCA, ("PacketizeParticipantRreply, wrong pktType"));
1023 }
1024 this->LAppendVar("pktReplies", pkt->name());
1025 }
1026 return TRUE;
1027 }
1028
1029
1030 Bool
1031 FCA_Packet::PacketizeParticipantRreply(u_char *&pb, int &len)
1032 {
1033 Debug (dbgFCA, ("PacketizeParticipantRreply, "
1034 "should be called from fill_ADU"));
1035 if (len < int(sizeof(u_int32_t))) {
1036 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
1037 return FALSE;
1038 }
1039
1040 u_int32_t numReplies;
1041 this->GetVar("numReplies", numReplies);
1042 Debug (dbgFCA, ("PacketizeParticipantRreply, numReplies = %lu\n",
1043 numReplies));
1044 *((u_int32_t*) pb) = host2net(numReplies); // <---
1045 incr(pb, len, sizeof(u_int32_t));
1046
1047 //u_int32_t pktType = 0;
1048 FCA_Packet *pkt;
1049
1050 for (int i=0; i < int(numReplies); i++) {
1051 this->LIndex("pktReplies", i, pkt);
1052
1053
1054 const char *pktTypeStr = pkt->GetVar("pktType");
1055 u_int32_t pktType = 0;
1056 for (int j=0; j < int(sizeof(pktTypeStrings)/sizeof(char*)); j++) {
1057 if (strcmp(pktTypeStr, pktTypeStrings[j])==0) {
1058 Debug (dbgFCA, ("pktType j = %lu, string == %s",
1059 j, pktTypeStrings[j]));
1060 pktType = j;
1061 break;
1062 }
1063 }
1064
1065
1066 //pkt->GetVar("pktType", pktType);
1067 Debug (dbgFCA, ("PacketizeParticipantRreply, pktType = %lu\n",
1068 pktType));
1069 *((u_int32_t*) pb) = host2net(pktType); // <---
1070 Debug (dbgFCA, ("PacketizeParticipantRreply, "
1071 "after converting to net, pktType = %lu\n",
1072 *((u_int32_t*) pb)));
1073 incr(pb, len, sizeof(u_int32_t));
1074
1075 switch (pktType) {
1076 case PKT_FLOOR_REQUEST:
1077 Debug (dbgFCA,("PacketizeParticipantRreply, it is floor request"));
1078 if (pkt->PacketizeFloorRequest(pb, len)==FALSE) return FALSE;
1079 break;
1080
1081 case PKT_FLOOR_CANCEL:
1082 if (pkt->PacketizeFloorCancel(pb, len)==FALSE) return FALSE;
1083 break;
1084
1085 case PKT_FLOOR_RELEASE:
1086 if (pkt->PacketizeFloorRelease(pb, len)==FALSE) return FALSE;
1087 break;
1088
1089 case PKT_OBSOLETE:
1090 if (pkt->PacketizeObsolete(pb, len)==FALSE) return FALSE;
1091 break;
1092
1093 default:
1094 Debug (dbgFCA, ("PacketizeParticipantRreply, wrong pktType"));
1095 }
1096 }
1097 return TRUE;
1098 }
1099
1100
1101 /*
1102 * PKT_OBSOLETE:
1103 * seqno: 4 bytes (seqno)
1104 */
1105 Bool
1106 FCA_Packet::ExtractObsolete(u_char *&pb, int &len)
1107 {
1108 if (len < int(sizeof(u_int32_t))) {
1109 Debug(dbgFCA, ("Error in packet; too few bytes: %d", len));
1110 return FALSE;
1111 }
1112
1113 u_int32_t seqno = net2host(*(u_int32_t*)pb);
1114 incr(pb, len, sizeof(u_int32_t));
1115 this->SetVar("seqno", seqno); // <---
1116 return TRUE;
1117 }
1118
1119
1120 Bool
1121 FCA_Packet::PacketizeObsolete(u_char *&pb, int &len)
1122 {