1 // Routing classes - here we store the 'via' systems and the
2 // address we want to route.
3
4 // CViaHandler provides the basic functions for every via
5 class CViaHandler
6 {
7 int inited; // A viahandler is inited when its via system has been established
8 int locked; // Locked -> An error in the via system was produced
9 int Attrib; // Attribute
10 int SendDirect; // List of direct systems?
11 int RouteMail,RouteFiles; // What we route
12 int RouteEncrypted, RouteNonEncrypted, EncryptInfo;
13 S_FQAddress ViaSystem;
14 word RouteFromCount,RouteToCount;
15 S_WAddress **RouteToSystem,**RouteFromSystem;
16 union
17 {
18 unsigned char number;
19 struct
20 {
21 unsigned mon: 1;
22 unsigned tue: 1;
23 unsigned wed: 1;
24 unsigned thu: 1;
25 unsigned fri: 1;
26 unsigned sat: 1;
27 unsigned sun: 1;
28 unsigned waste: 1;
29 } x;
30 } DOWs;
31 public:
32 C_WildAddress WAHandler;
33 CViaHandler (void);
34 ~CViaHandler (void);
35 int SetViaSystem (S_FQAddress System);
36 int GetViaSystem (S_FQAddress *System);
37 int IsInited (void);
38 int Unlock (void);
39 int IsLocked (void);
40 int AddNewRoutedAddress (S_WAddress NewAddress,int From);
41 int GetRoutedToAddress (S_WAddress *storage,word count);
42 int GetRoutedFromAddress (S_WAddress *storage,word count);
43 int DoesMatch (S_FQAddress TargetAddress,S_FQAddress OriginAddress,int FileAttach, int Encrypted);
44 int SetAttribType (int NewAttrib);
45 int SetEncryption (int EncryptSpec);
46 int SetDayOfTheWeek (char *spec);
47 int GetAttribType (void);
48 void SetStatus (int WantDirect,int WantMail,int WantFiles);
49 int GetDirect (void);
50 word GetRouteFromCount (void);
51 word GetRouteToCount (void);
52 };
53
GetDirect(void)54 int CViaHandler::GetDirect (void)
55 {
56 return SendDirect;
57 }
58
SetStatus(int WantDirect,int WantMail,int WantFiles)59 void CViaHandler::SetStatus (int WantDirect,int WantMail,int WantFiles)
60 {
61 // A direct route doesn't need a via address, that's why we
62 // considered the via inited if it contains direct system.
63 SendDirect=WantDirect;
64 if (SendDirect==NV_Direct || SendDirect==NV_Noroute ||SendDirect==NV_NoPack)
65 inited=1;
66 RouteMail=WantMail;
67 RouteFiles=WantFiles;
68 }
69
DoesMatch(S_FQAddress TargetAddress,S_FQAddress OriginAddress,int FileAttach,int Encrypted)70 int CViaHandler::DoesMatch (S_FQAddress TargetAddress,S_FQAddress OriginAddress,int FileAttach, int Encrypted)
71 {
72 int cur_Tostatus=0,cur_Fromstatus=0; // No match
73 int count,last,except=0;
74 unsigned char value;
75 // Check if type of message match type of route
76 if (((FileAttach) && (RouteFiles==0)) ||
77 ((!FileAttach) && (RouteMail==0)))
78 return 0;
79 // Check encryption
80 if ((Encrypted) & (RouteEncrypted==0) ||
81 ((!Encrypted) && (RouteNonEncrypted==0)))
82 return 0;
83 // Day day of the week
84 value=1<<GetDOW(); //1 = Monday, 2=Tuesday, 4=Wednesday...
85 if ((DOWs.number&value)==0)
86 return 0;
87 // No data causes a mismatch.
88 if (RouteToCount==0 && RouteFromCount==0)
89 return 0;
90 if (RouteToCount>0)
91 {
92 for (count=0;count<RouteToCount;count++)
93 {
94 except = (RouteToSystem[count]->Reverse==1);
95 last=CompareAddress (TargetAddress,RouteToSystem[count]);
96 if (last)
97 if (except)
98 cur_Tostatus=0;
99 else
100 cur_Tostatus=1;
101 }
102 }
103 else
104 cur_Tostatus=1; // absence of a list means *!
105 if (!cur_Tostatus) // Not on the To: list
106 return 0;
107 except=0;
108 if (RouteFromCount>0)
109 {
110 for (count=0;count<RouteFromCount;count++)
111 {
112 except = (RouteFromSystem[count]->Reverse==1);
113 last=CompareAddress (OriginAddress,RouteFromSystem[count]);
114 if (last)
115 if (except)
116 cur_Fromstatus=0;
117 else
118 cur_Fromstatus=1;
119 }
120 }
121 else
122 cur_Fromstatus=1; // absence of a list means *!
123 return (cur_Fromstatus);
124 }
125
GetRoutedToAddress(S_WAddress * storage,word count)126 int CViaHandler::GetRoutedToAddress (S_WAddress *storage,word count)
127 {
128 if (count>RouteToCount)
129 return OUTRANGE;
130 memcpy (storage,RouteToSystem[count],sizeof (struct S_WAddress));
131 return SUCCESS;
132 }
133
GetRoutedFromAddress(S_WAddress * storage,word count)134 int CViaHandler::GetRoutedFromAddress (S_WAddress *storage,word count)
135 {
136 if (count>RouteFromCount)
137 return OUTRANGE;
138 memcpy (storage,RouteFromSystem[count],sizeof (struct S_WAddress));
139 return SUCCESS;
140 }
141
GetRouteFromCount(void)142 word CViaHandler::GetRouteFromCount (void)
143 {
144 return RouteFromCount;
145 }
146
GetRouteToCount(void)147 word CViaHandler::GetRouteToCount (void)
148 {
149 return RouteToCount;
150 }
151
AddNewRoutedAddress(S_WAddress NewAddress,int From)152 int CViaHandler::AddNewRoutedAddress (S_WAddress NewAddress,int From)
153 {
154 S_WAddress *NewSpec;
155 NewSpec=(S_WAddress *) malloc (sizeof (S_WAddress));
156 if (NewSpec==NULL)
157 return NOMEMORY;
158 memcpy (NewSpec,&NewAddress,sizeof (struct S_WAddress));
159 if (From==1)
160 {
161 RouteFromCount++;
162 /* if (RouteFromCount==1)
163 RouteFromSystem=(S_WAddress **) malloc (sizeof (struct S_WAddress *));
164 else */
165 RouteFromSystem=(S_WAddress **) realloc (RouteFromSystem,RouteFromCount*sizeof (struct S_WAddress *));
166 if (RouteFromSystem==NULL)
167 return NOMEMORY;
168 RouteFromSystem[RouteFromCount-1]=NewSpec;
169 }
170 else
171 {
172 RouteToCount++;
173 /* if (RouteToCount==1)
174 RouteToSystem=(S_WAddress **) malloc (sizeof (struct S_WAddress *));
175 else */
176 RouteToSystem=(S_WAddress **) realloc (RouteToSystem,RouteToCount*sizeof (struct S_WAddress *));
177 if (RouteToSystem==NULL)
178 return NOMEMORY;
179 RouteToSystem[RouteToCount-1]=NewSpec;
180 }
181 return SUCCESS;
182 }
183
IsInited(void)184 int CViaHandler::IsInited (void)
185 {
186 return inited;
187 }
188
Unlock(void)189 int CViaHandler::Unlock (void)
190 {
191 locked=0;
192 SendDirect=0;
193 return SUCCESS;
194 }
195
IsLocked(void)196 int CViaHandler::IsLocked (void)
197 {
198 return locked;
199 }
200
SetDayOfTheWeek(char * spec)201 int CViaHandler::SetDayOfTheWeek (char *spec)
202 {
203 char *p;
204 DOWs.number=0;
205 p=spec;
206 while (*p)
207 {
208 switch (*p)
209 {
210 case 'M':
211 DOWs.x.mon=1;
212 break;
213 case 'T':
214 DOWs.x.tue=1;
215 break;
216 case 'W':
217 DOWs.x.wed=1;
218 break;
219 case 'H':
220 DOWs.x.thu=1;
221 break;
222 case 'F':
223 DOWs.x.fri=1;
224 break;
225 case 'S':
226 DOWs.x.sat=1;
227 break;
228 case 'U':
229 DOWs.x.sun=1;
230 break;
231 }
232 p++;
233 }
234 return SUCCESS;
235 }
236
SetEncryption(int EncryptSpec)237 int CViaHandler::SetEncryption (int EncryptSpec)
238 {
239 switch (EncryptSpec)
240 {
241 case TT_ENCRYPTED:
242 if (RouteEncrypted==0)
243 return (EVH_NONSENSE);
244 RouteNonEncrypted=0;
245 break;
246 case TT_NONENCRYPTED:
247 if (RouteNonEncrypted==0)
248 return (EVH_NONSENSE);
249 RouteEncrypted=0;
250 break;
251 default:
252 return (EVH_INVALID);
253 }
254 return SUCCESS;
255 }
256
SetAttribType(int NewAttrib)257 int CViaHandler::SetAttribType (int NewAttrib)
258 {
259 if (NewAttrib!=TT_NORMAL && NewAttrib!=TT_HOLD && NewAttrib!=TT_CRASH &&
260 NewAttrib!=TT_DIR && NewAttrib!=TT_IMMEDIATE)
261 return EVH_INVALID;
262 else
263 {
264 Attrib=NewAttrib;
265 return SUCCESS;
266 }
267 }
268
GetAttribType(void)269 int CViaHandler::GetAttribType (void)
270 {
271 return Attrib;
272 }
273
CViaHandler(void)274 CViaHandler::CViaHandler (void)
275 {
276 inited=0;
277 locked=0;
278 SendDirect=0;
279 RouteFromCount=RouteToCount=0;
280 Attrib=TT_NORMAL;
281 DOWs.number=255;
282 RouteEncrypted=1;
283 RouteNonEncrypted=1;
284 EncryptInfo=0;
285 RouteToSystem=RouteFromSystem=NULL;
286 }
287
~CViaHandler(void)288 CViaHandler::~CViaHandler (void)
289 {
290 word count;
291 for (count=0;count<RouteToCount;count++)
292 free (RouteToSystem[count]);
293 for (count=0;count<RouteFromCount;count++)
294 free (RouteFromSystem[count]);
295 free (RouteToSystem);
296 free (RouteFromSystem);
297 }
298
SetViaSystem(S_FQAddress System)299 int CViaHandler::SetViaSystem (S_FQAddress System)
300 {
301 if (inited==1)
302 return EVH_TWOVIA;
303 memcpy (&ViaSystem,&System,sizeof (struct S_FQAddress));
304 inited=1;
305 return SUCCESS;
306 }
307
GetViaSystem(S_FQAddress * System)308 int CViaHandler::GetViaSystem (S_FQAddress *System)
309 {
310 if (inited==0)
311 return EVH_NOVIA;
312 if (SendDirect==NV_Routed)
313 {
314 memcpy (System,&ViaSystem,sizeof (struct S_FQAddress));
315 return SUCCESS;
316 }
317 if (SendDirect==NV_Direct)
318 return EVH_DIRECT;
319 if (SendDirect==NV_NoPack)
320 return EVH_NOPACK;
321 return EVH_NOROUTE;
322 }
323
324 // CRouteHandler provides the interface for external parts.
325 class CRouteHandler
326 {
327 word ViaCount;
328 CViaHandler **ViasArray;
329 int OnExcept,OnFrom,TopPriority,AssumePoints,AssumeWaypoints,SetAs;
330 public:
331 void SetTopDownMode (void);
332 int SetupNewVia (int SendDirect,int SendMail, int SendFiles);
333 CRouteHandler (void);
334 int Process (char *Address);
335 word GetViaCount (void);
336 int GetViaSystem (S_FQAddress *storage,int count);
337 word GetRouteToCount (word count);
338 word GetRouteFromCount (word count);
339 int GetRoutedFromAddress (S_WAddress *storage,word Viacount,word RouteCount);
340 int GetRoutedToAddress (S_WAddress *storage,word Viacount,word RouteCount);
341 void SetOnFrom (void);
342 void SwitchExcept (void);
343 int FindPackSystem (S_FQAddress NetTo,S_FQAddress NetFrom,int FileAttach,int Encrypted, S_FQAddress *storage,int *storeattrib);
344 int NoPack (S_FQAddress NetTo,S_FQAddress NetFrom,int FileAttach,int Encrypted);
345 int SetAttrib (int NewAttrib);
346 int SetDayOfTheWeek (char *DOWspec);
347 int SetEncryption (int EncryptSpec);
348 void SetAssumePoints (int Value);
349 void SetAssumeWaypoints (int Value);
350 };
351
SetAssumeWaypoints(int Value)352 void CRouteHandler::SetAssumeWaypoints (int Value)
353 {
354 AssumeWaypoints=Value;
355 }
356
SetAssumePoints(int Value)357 void CRouteHandler::SetAssumePoints (int Value)
358 {
359 AssumePoints=Value;
360 }
361
362 // Constructor
CRouteHandler(void)363 CRouteHandler::CRouteHandler (void)
364 {
365 ViaCount=0;
366 OnExcept=0;
367 OnFrom=0;
368 TopPriority=0;
369 AssumePoints=0;
370 AssumeWaypoints=0;
371 SetAs=0;
372 }
373
GetViaSystem(S_FQAddress * storage,int count)374 int CRouteHandler::GetViaSystem (S_FQAddress *storage, int count)
375 {
376 if (count>=ViaCount)
377 return OUTRANGE;
378 return (ViasArray[count]->GetViaSystem (storage));
379 }
380
GetRouteToCount(word count)381 word CRouteHandler::GetRouteToCount (word count)
382 {
383 if (count>=ViaCount)
384 return SPECIAL_OUTRANGE;
385 return (ViasArray[count]->GetRouteToCount ());
386 }
387
GetRoutedFromAddress(S_WAddress * storage,word Viacount,word RouteCount)388 int CRouteHandler::GetRoutedFromAddress (S_WAddress *storage,word Viacount,word RouteCount)
389 {
390 if (Viacount>=ViaCount)
391 return OUTRANGE;
392 return (ViasArray[Viacount]->GetRoutedFromAddress (storage,RouteCount));
393 }
394
GetRoutedToAddress(S_WAddress * storage,word Viacount,word RouteCount)395 int CRouteHandler::GetRoutedToAddress (S_WAddress *storage,word Viacount,word RouteCount)
396 {
397 if (Viacount>=ViaCount)
398 return OUTRANGE;
399 return (ViasArray[Viacount]->GetRoutedToAddress (storage,RouteCount));
400 }
401
402
GetRouteFromCount(word count)403 word CRouteHandler::GetRouteFromCount (word count)
404 {
405 if (count>=ViaCount)
406 return SPECIAL_OUTRANGE;
407 return (ViasArray[count]->GetRouteFromCount ());
408 }
409
GetViaCount(void)410 word CRouteHandler::GetViaCount (void)
411 {
412 CViaHandler *InUseViaHandler;
413 int correction=0;
414 if (ViaCount>0)
415 {
416 InUseViaHandler=ViasArray[ViaCount-1];
417 if (InUseViaHandler->IsInited()==0)
418 correction=1; // Uninited vias don't count
419 }
420 return ViaCount-correction;
421 }
422
423 // Process an address. It may be the via system or the routed systems
SetOnFrom(void)424 void CRouteHandler::SetOnFrom (void)
425 {
426 OnFrom=1;
427 }
428
SwitchExcept(void)429 void CRouteHandler::SwitchExcept (void)
430 {
431 OnExcept=!OnExcept;
432
433 // TE 990805: I commented out the following line because EXCEPT can be
434 // applied to either From or To statements.
435 // OnFrom=0;
436
437 }
438
Process(char * Address)439 int CRouteHandler::Process (char *Address)
440 {
441 CViaHandler *InUseViaHandler;
442 S_FQAddress FQA;
443 S_WAddress WA,Record;
444 int SetTarget=0;
445 if (ViaCount==0)
446 return EVH_NO_VIAHANDLER;
447 InUseViaHandler=ViasArray[ViaCount-1];
448 if (InUseViaHandler->IsLocked())
449 return EVH_LOCKED;
450 if (InUseViaHandler->IsInited()==0) // Incoming address is the via system
451 {
452 if (GetFullQualifiedAddress (Address,&FQA,NULL)!=SUCCESS)
453 {
454 printf ("%s is not a valid address for a waypoint specification. Must be 4D.\n",Address);
455 return FATAL;
456 }
457 InUseViaHandler->SetViaSystem (FQA);
458 // We do this to give a feed to the resolver
459 InUseViaHandler->WAHandler.ParseAddress (Address,&WA);
460 if (AssumeWaypoints)
461 SetTarget=1;
462 else
463 SetTarget=0;
464 }
465 else
466 SetTarget=1;
467 if (SetTarget)
468 {
469 if (InUseViaHandler->WAHandler.ParseAddress (Address,&WA)!=SUCCESS)
470 {
471 printf ("Warning: %s is invalid, ignored",Address);
472 return WARNING;
473 }
474 WA.Reverse=OnExcept;
475
476 // TE 990826: The following line was not in accordance with the docs
477 // OnExcept=0;
478
479 if (AssumePoints)
480 {
481 if (!strchr (Address,'.'))
482 strcpy (WA.Point,"*");
483 }
484 memcpy (&Record,&WA,sizeof (struct S_WAddress));
485 return (InUseViaHandler->AddNewRoutedAddress (WA,OnFrom));
486 }
487 return SUCCESS;
488 }
489
SetDayOfTheWeek(char * DOWspec)490 int CRouteHandler::SetDayOfTheWeek (char *DOWspec)
491 {
492 CViaHandler *InUseViaHandler;
493 if (ViaCount==0)
494 return EVH_NO_VIAHANDLER;
495 InUseViaHandler=ViasArray[ViaCount-1];
496 if (InUseViaHandler->IsLocked())
497 return EVH_LOCKED;
498 return (InUseViaHandler->SetDayOfTheWeek (DOWspec));
499 }
500
SetAttrib(int NewAttrib)501 int CRouteHandler::SetAttrib (int NewAttrib)
502 {
503 CViaHandler *InUseViaHandler;
504 if (ViaCount==0)
505 return EVH_NO_VIAHANDLER;
506 InUseViaHandler=ViasArray[ViaCount-1];
507 if (InUseViaHandler->IsLocked())
508 return EVH_LOCKED;
509 return (InUseViaHandler->SetAttribType (NewAttrib));
510 }
511
SetEncryption(int EncryptSpec)512 int CRouteHandler::SetEncryption (int EncryptSpec)
513 {
514 CViaHandler *InUseViaHandler;
515 if (ViaCount==0)
516 return EVH_NO_VIAHANDLER;
517 InUseViaHandler=ViasArray[ViaCount-1];
518 if (InUseViaHandler->IsLocked())
519 return EVH_LOCKED;
520 return (InUseViaHandler->SetEncryption (EncryptSpec));
521 }
522
523 // Add a new 'via' system in the array
SetupNewVia(int SendDirect,int RouteMail,int RouteFiles)524 int CRouteHandler::SetupNewVia (int SendDirect,int RouteMail,int RouteFiles)
525 {
526 CViaHandler *NewViaHandler;
527 OnFrom=0;
528 OnExcept=0;
529 if (ViaCount>0) // Let's see if we can use the previous via...
530 {
531 NewViaHandler=ViasArray[ViaCount-1];
532 if (NewViaHandler->IsLocked())
533 NewViaHandler->Unlock();
534 else
535 if (NewViaHandler->IsInited()) // Need a new via
536 {
537 ViaCount++;
538 NewViaHandler=new (CViaHandler);
539 if (NewViaHandler==NULL)
540 return NOMEMORY;
541 ViasArray=(CViaHandler **) realloc (ViasArray,ViaCount*sizeof (class CViaHandler *));
542 if (ViasArray==NULL)
543 return NOMEMORY;
544 ViasArray[ViaCount-1]=NewViaHandler;
545 }
546 }
547 else // No vias yet - array must be created
548 {
549 ViaCount++;
550 NewViaHandler=new (CViaHandler);
551 if (NewViaHandler==NULL)
552 return NOMEMORY;
553 ViasArray=(CViaHandler **) malloc (sizeof (class CViaHandler *));
554 if (ViasArray==NULL)
555 return NOMEMORY;
556 ViasArray[ViaCount-1]=NewViaHandler;
557 }
558 NewViaHandler->SetStatus (SendDirect,RouteMail,RouteFiles);
559 return SUCCESS;
560 }
561
SetTopDownMode(void)562 void CRouteHandler::SetTopDownMode (void)
563 {
564 TopPriority=1;
565 }
566
NoPack(S_FQAddress NetTo,S_FQAddress NetFrom,int FileAttach,int Encrypted)567 int CRouteHandler::NoPack (S_FQAddress NetTo,S_FQAddress NetFrom,int FileAttach,int Encrypted)
568 {
569 int count,Ignore=0;
570 CViaHandler *InUse;
571 for (count=0;count<GetViaCount ();count++)
572 {
573 InUse=ViasArray[count];
574 if (InUse->DoesMatch (NetTo,NetFrom,FileAttach,Encrypted)==1)
575 {
576 if (InUse->GetDirect ()==NV_NoPack)
577 Ignore=1;
578 else
579 Ignore=0;
580 }
581 }
582 return Ignore;
583 }
584
FindPackSystem(S_FQAddress NetTo,S_FQAddress NetFrom,int FileAttach,int Encrypted,S_FQAddress * storage,int * storeattrib)585 int CRouteHandler::FindPackSystem (S_FQAddress NetTo,S_FQAddress NetFrom,int FileAttach,int Encrypted, S_FQAddress *storage,int *storeattrib)
586 {
587 int count,GotAMatch=0;
588 CViaHandler *InUse;
589 for (count=0;count<GetViaCount ();count++)
590 {
591 InUse=ViasArray[count];
592 if (InUse->DoesMatch (NetTo,NetFrom,FileAttach,Encrypted)==1)
593 {
594 #ifndef DEBUG
595 if (RequestInfo)
596 #endif
597 {
598 printf ("To: %u:%u/%u.%u From: %u:%u/%u.%u matches definition %d",
599 NetTo.Zone,NetTo.Net,NetTo.Node,NetTo.Point,
600 NetFrom.Zone,NetFrom.Net,NetFrom.Node,NetFrom.Point,
601 count);
602 }
603 GotAMatch=1;
604 switch (InUse->GetViaSystem (storage))
605 {
606 case EVH_DIRECT:
607 #ifndef DEBUG
608 if (RequestInfo)
609 #endif
610 {
611 printf (" direct.\n");
612 }
613 memcpy (storage,&NetTo,sizeof (struct S_FQAddress));
614 break;
615 case EVH_NOROUTE:
616 #ifndef DEBUG
617 if (RequestInfo)
618 #endif
619 printf (" no-route.\n");
620
621 memcpy (storage,&NetTo,sizeof (struct S_FQAddress));
622 storage->Point=0;
623 break;
624 case EVH_NOPACK:
625 #ifndef DEBUG
626 if (RequestInfo)
627 #endif
628 printf (" no-pack.\n");
629
630 GotAMatch=0;
631 default:
632 {
633 #ifndef DEBUG
634 if (RequestInfo)
635 #endif
636 printf (" (via %u:%u/%u.%u)\n",
637 storage->Zone,storage->Net,
638 storage->Node,storage->Point);
639 }
640 ;
641 }
642 *storeattrib=InUse->GetAttribType ();
643 }
644 if (GotAMatch && TopPriority)
645 return 1;
646 }
647 return GotAMatch;
648 }
649