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