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