xref: /onnv-gate/usr/src/cmd/agents/snmp/snmprelayd/subtree.c (revision 3820:8adf9090a487)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  *
24  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
29 
30 /*
31  * HISTORY
32  * 5-21-96	Jerry Yeung	export first_subtree
33  * 5-24-96	Jerry Yeung	skip invalid subtree
34  */
35 
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <sys/types.h>
40 #include <netinet/in.h>
41 
42 #include "impl.h"
43 #include "error.h"
44 #include "trace.h"
45 #include "asn1.h"
46 #include "snmp.h"
47 #include "pdu.h"
48 
49 #include "agent.h"
50 #include "subtree.h"
51 #include "session.h"
52 
53 
54 extern Session *first_session;
55 Subtree *first_subtree = NULL;
56 int sap_reg_tree_index=1;
57 
58 
59 void subtree_remove_from_agent_list(Subtree *subtree);
60 
61 
longest_subtree_match(Oid * one,Oid * two)62 static int longest_subtree_match (Oid * one, Oid * two)
63 {
64 	int	i, min;
65 
66 	if (one == NULL || two == NULL)
67 		return (-1);
68 
69 	if (one->len > two->len)
70 		return two->len - one->len;
71 
72 	for (i = 0;i < one->len;i ++) {
73 		if (one->subids[i] > two->subids[i])
74 			return (-1);
75 		if (one->subids[i] < two->subids[i])
76 			return (-1);
77 	}
78 	return two->len - one->len;
79 }
80 
81 /****************************************************************/
subtree_find(Subid * subids,int len)82 Subtree*  subtree_find(Subid *subids, int len)
83 {
84 	Subtree *sp;
85 	int ret;
86 	Oid name;
87 
88 
89 	name.subids = (Subid *) malloc(len * sizeof(Subid));
90 	if(name.subids == NULL)
91 	{
92 		error("malloc() failed");
93 		return NULL;
94 	}
95 	memcpy(name.subids, subids, len * sizeof(Subid));
96 	name.len = len;
97 
98 	for(sp = first_subtree; sp; sp = sp->next_subtree)
99 	{
100 		ret = SSAOidCmp(&(name), &(sp->name));
101 		if(ret == 0)
102 		{
103 			free(name.subids);
104 			name.subids=NULL;
105 			return sp;
106 		}
107 		else
108 		if(ret < 0)
109 		{
110 			break;
111 		}
112 
113 	}
114 
115 	free(name.subids);
116 	name.subids=NULL;
117 	return NULL;
118 }
119 
subtree_purge(Subid * subids,int len)120 int subtree_purge(Subid *subids, int len)
121 {
122 	Subtree *sp;
123 	int ret;
124 	Oid name;
125 
126 
127 	name.subids = (Subid *) malloc(len * sizeof(Subid));
128 	if(name.subids == NULL)
129 	{
130 		error("malloc() failed");
131 		return FALSE;
132 	}
133 	memcpy(name.subids, subids, len * sizeof(Subid));
134 	name.len = len;
135 
136 	for(sp = first_subtree; sp; sp = sp->next_subtree)
137 	{
138 		ret = SSAOidCmp(&(name), &(sp->name));
139 		if(ret == 0)
140 		{
141 			free(name.subids);
142 			name.subids=NULL;
143 			subtree_detach(sp);
144 			subtree_free(sp);
145 			return TRUE;
146 		}
147 		else
148 		if(ret < 0)
149 		{
150 			break;
151 		}
152 
153 	}
154 	free(name.subids);
155 	name.subids=NULL;
156 
157 	return TRUE;
158 }
159 
160 
subtree_add(Agent * agent,Subid * subids,int len,TblTag * tbl_tag)161 int subtree_add(Agent *agent, Subid *subids, int len, TblTag *tbl_tag)
162 {
163 	Subtree *sp;
164 	Subtree *new;
165 	Subtree *last = NULL;
166 	int ret;
167 
168 
169 	if(agent == NULL)
170 	{
171 		error("BUG: subtree_add(): agent is NULL");
172 		return -1;
173 	}
174 
175 	new = (Subtree *) calloc(1,sizeof(Subtree));
176 	if(new == NULL)
177 	{
178 		error("malloc() failed");
179 		return -1;
180 	}
181 	new->next_subtree = NULL;
182 	new->agent = agent;
183 	new->next_agent_subtree = NULL;
184 	new->name.subids = (Subid *) malloc(len * sizeof(Subid));
185 	if(new->name.subids == NULL)
186 	{
187 		error("malloc() failed");
188 		subtree_free(new);
189 		return -1;
190 	}
191 	memcpy(new->name.subids, subids, len * sizeof(Subid));
192 	new->name.len = len;
193 
194   	new->regTreeAgentID = agent->agentID;
195 	new->regTreeIndex = ++agent->agentTreeIndex;
196 	new->regTreeStatus =  SSA_OPER_STATUS_ACTIVE;
197 	new->tbl_tag = tbl_tag;
198 
199 	for(sp = first_subtree; sp; sp = sp->next_subtree)
200 	{
201 		ret = SSAOidCmp(&(new->name), &(sp->name));
202 		if(ret == 0)
203 		{
204 			error("The subtree %s already belongs to the agent %s",
205 				SSAOidString(&(sp->name)),
206 				sp->agent->name);
207 			subtree_free(new);
208 			return -1;
209 		}
210 		else
211 		if(ret < 0)
212 		{
213 			break;
214 		}
215 
216 		last = sp;
217 	}
218 
219 	if(last == NULL)
220 	{
221 		new->next_subtree = first_subtree;
222 		first_subtree = new;
223 	}
224 	else
225 	{
226 		new->next_subtree = last->next_subtree;
227 		last->next_subtree = new;
228 	}
229 
230 	new->next_agent_subtree = agent->first_agent_subtree;
231 	agent->first_agent_subtree = new;
232 
233 
234 	return 0;
235 }
236 
237 
238 /****************************************************************/
239 
subtree_match(u_char type,Oid * name)240 Subtree *subtree_match(u_char type, Oid *name)
241 {
242 	Subtree *sp;
243 	Subtree *last, *good;
244 	Subtree *first_valid_subtree;
245 	int ret;
246 
247 
248 	if(name == NULL)
249 	{
250 		error("subtree_match(): name is NULL");
251 		return NULL;
252 	}
253 
254 	if(first_subtree == NULL)
255 	{
256 		if(trace_level > 1)
257 		{
258 			trace("subtree_match() returned NULL\n\n");
259 		}
260 
261 		return NULL;
262 	}
263 
264 
265 	if(type == GETNEXT_REQ_MSG)
266 	{
267 		/* grep the first valid subtree (vsb)*/
268 		if( (first_valid_subtree = subtree_next(first_subtree))
269 			== NULL) return NULL;
270 		if(SSAOidCmp(name, &(first_valid_subtree->name)) < 0)
271 		{
272 			if(trace_level > 1)
273 			{
274 				trace("subtree_match() returned %s supported by %s\n\n",
275 					SSAOidString(&(first_subtree->name)),
276 					first_subtree->agent->name);
277 			}
278 
279 			return first_valid_subtree;
280 		}
281 	}
282 
283 	last = NULL;
284 	good = NULL;
285 	for (sp = first_subtree; sp; sp = sp->next_subtree) {
286 	 	/* subtree is invalid skip (vsb)*/
287 		if(subtree_is_valid (sp) == FALSE)
288 			continue;
289 		ret = longest_subtree_match (&(sp->name), name);
290 		if (ret == 0) {
291 			if (trace_level > 1)
292 				trace("subtree_match() full match returned %s supported by %s\n\n",
293 					SSAOidString(&(sp->name)),
294 					sp->agent->name);
295 			return sp;
296 
297 		}
298 		if (ret < 0)
299 			continue;
300 		if (good == NULL)
301 			good = sp;
302 		else if (good->name.len < sp->name.len)
303 			good = sp;
304 	}
305 	if(trace_level > 1) {
306 		if (good) {
307 			trace("subtree_match() returned %s supported by %s\n\n",
308 				SSAOidString(&(good->name)),
309 				good->agent->name);
310 		}
311 		else {
312 			trace("subtree_match() returned NULL\n\n");
313 		}
314 	}
315 
316 	return good;
317 }
318 
319 
320 /****************************************************************/
321 
trace_subtrees()322 void trace_subtrees()
323 {
324 	Subtree *sp;
325 
326 
327 	trace("SUBTREES:\n");
328 	for(sp = first_subtree; sp; sp = sp->next_subtree)
329 	{
330 		if(sp->agent)
331 		{
332 			trace("\t%-30s %d %d %-30s %d %d\n",
333 				SSAOidString(&(sp->name)),
334 				sp->regTreeIndex,
335 				sp->regTreeStatus,
336 				sp->agent->name,
337 				sp->agent->address.sin_port,
338 				sp->regTreeAgentID);
339 		}
340 		else
341 		{
342 			trace("\t%-30s %d %d %-30s\n",
343 				SSAOidString(&(sp->name)),
344 				sp->regTreeIndex,
345 				sp->regTreeStatus,
346 				"NO AGENT!");
347 		}
348 	}
349 	trace("\n");
350 }
351 
352 
353 /****************************************************************/
354 
subtree_free(Subtree * sp)355 void subtree_free(Subtree *sp)
356 {
357 	if(sp == NULL)
358 	{
359 		return;
360 	}
361 
362 	if(sp->name.subids)
363 	{
364 		free(sp->name.subids);
365 		sp->name.subids=NULL;
366 	}
367 
368 	if(sp->regTreeView.chars != NULL &&
369 	   sp->regTreeView.len != 0 )
370 		free(sp->regTreeView.chars);
371 
372 	if(sp->tbl_tag){
373 		free(sp->tbl_tag);
374 		sp->tbl_tag=NULL;
375 	}
376 
377 	free(sp);
378 }
379 
380 
381 /****************************************************************/
382 
subtree_list_delete()383 void subtree_list_delete()
384 {
385 	Subtree *sp = first_subtree;
386 	Subtree *next;
387 
388 
389 	while(sp)
390 	{
391 		next = sp->next_subtree;
392 
393 		subtree_remove_from_agent_list(sp);
394 
395 		subtree_free(sp);
396 
397 		sp = next;
398 	}
399 
400 	first_subtree = NULL;
401 
402 	return;
403 }
404 
405 
406 /****************************************************************/
407 /* the subtree  will be detached from both the agent_subtree list
408  * and the main subtree list
409  */
delete_all_subtree_from_agent(Agent * agent)410 void delete_all_subtree_from_agent(Agent* agent)
411 {
412 	Subtree *sp = first_subtree;
413 	Subtree *next, *last=NULL;
414 	Session *spp;
415 	Request *rp;
416 
417 	while(sp)
418 	{
419 		next = sp->next_subtree;
420 
421 		if(sp->agent != NULL && sp->agent == agent){
422 			if(last == NULL){
423 			  first_subtree = next;
424 			}else{
425 			  last->next_subtree = next;
426 			}
427 
428 			for (spp = first_session; spp; spp = spp->next_session) {
429 				for (rp = spp->first_request; rp; rp = rp->next_request) {
430 					if (rp->subtree->agent == sp->agent)
431 						session_close(spp);
432 				}
433 			}
434 
435 			subtree_remove_from_agent_list(sp);
436 			subtree_free(sp);
437 		}else{
438 		  last = sp;
439 		}
440 
441 		sp = next;
442 	}
443 
444 
445 }
446 
subtree_remove_from_agent_list(Subtree * subtree)447 void subtree_remove_from_agent_list(Subtree *subtree)
448 {
449 	Agent *agent = subtree->agent;
450 	Subtree *sp;
451 	Subtree *osp;
452 	Table *table;
453 
454 
455         if(agent == NULL) return;
456 	osp = NULL;
457 	for(sp = agent->first_agent_subtree; sp; sp = sp->next_agent_subtree)
458 	{
459 		if(sp == subtree)
460 		{
461 			break;
462 		}
463 
464 		osp = sp;
465 	}
466 
467 	if(sp == NULL)
468 	{
469 		error("subtree_remove_from_agent_list() : subtree (0x%x) not found", subtree);
470 		return;
471 	}
472 
473 	if(osp == NULL)
474 	{
475 		agent->first_agent_subtree = sp->next_agent_subtree;
476 	}
477 	else
478 	{
479 		osp->next_agent_subtree = sp->next_agent_subtree;
480 	}
481 
482 	subtree->agent = NULL;
483 
484 	/*(mibpatch) */
485 	if(subtree->mirror_tag!=NULL){
486 /*
487 		table = subtree->mirror_tag->table;
488 		if(table!=NULL){
489 			table_detach(table);
490 			table_free(table);
491 		}
492 */
493 	}
494 
495 	return;
496 }
497 
subtree_detach(Subtree * tgt)498 void subtree_detach(Subtree *tgt)
499 {
500   Subtree *sp, *last=NULL;
501 
502 	if(tgt == NULL) return;
503 	for(sp = first_subtree; sp; sp = sp->next_subtree)
504 	{
505 		if(sp == tgt)
506 		{
507 			break;
508 		}
509 
510 		last = sp;
511 	}
512 	if(sp==NULL) return;
513 
514 	if(last == NULL)
515 	{
516 		first_subtree = tgt->next_subtree;
517 		tgt->next_subtree = NULL;
518 	}
519 	else
520 	{
521 		last->next_subtree = tgt->next_subtree;
522 		tgt->next_subtree = NULL;
523 	}
524 
525 	subtree_remove_from_agent_list(tgt);
526 
527 }
528 
529 
subtree_is_valid(Subtree * t)530 int subtree_is_valid(Subtree *t)
531 {
532   if(t==NULL || t->agent==NULL ||
533      t->agent->agentStatus != SSA_OPER_STATUS_ACTIVE ||
534      t->regTreeStatus != SSA_OPER_STATUS_ACTIVE) return FALSE;
535   return TRUE;
536 }
537 
subtree_next(Subtree * subtree)538 Subtree *subtree_next(Subtree *subtree)
539 {
540   Subtree* sp;
541   for(sp=subtree; sp; sp=sp->next_subtree){
542 	if(subtree_is_valid(sp)) return sp;
543   }
544   return NULL;
545 }
546 
sync_subtrees_with_agent(Agent * agent)547 int sync_subtrees_with_agent(Agent *agent)
548 {
549   Subtree *sp;
550   if(agent == NULL) return -1;
551   for(sp=agent->first_agent_subtree;sp;sp=sp->next_agent_subtree)
552 	sp->regTreeStatus = agent->agentStatus;
553 
554   return 0;
555 }
556 
557