1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2005-2016. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21%%---------------------------------------------------------------------- 22%% Purpose: Utility functions for the (snmp manager) user test(s). 23%%---------------------------------------------------------------------- 24 25-module(snmp_manager_user). 26 27-behaviour(snmpm_user). 28%% -behaviour(snmpm_user_old). 29 30 31%%---------------------------------------------------------------------- 32%% Include files 33%%---------------------------------------------------------------------- 34-include_lib("common_test/include/ct.hrl"). 35-include("snmp_test_lib.hrl"). 36 37 38%%---------------------------------------------------------------------- 39%% External exports 40%%---------------------------------------------------------------------- 41-export([ 42 start_link/0, start_link/1, start_link/2, 43 start/0, start/1, start/2, 44 stop/0, 45 info/0, 46 system_info/0, 47 simulate_crash/1, 48 register_agent/2, 49 unregister_agent/1, 50 agent_info/2, 51 update_agent_info/3, 52 which_all_agents/0, which_own_agents/0, 53 load_mib/1, unload_mib/1, 54 sync_get2/3, 55 async_get2/3, 56 sync_get_next2/3, 57 async_get_next2/3, 58 sync_set2/3, 59 async_set2/3, 60 sync_get_bulk2/5, 61 async_get_bulk2/5, 62 name_to_oid/1, oid_to_name/1, 63 purify_oid/1 64 ]). 65 66 67%%---------------------------------------------------------------------- 68%% Internal exports 69%%---------------------------------------------------------------------- 70 71-export([ 72 main/4 73 ]). 74 75-export([ 76 handle_error/3, 77 handle_agent/5, 78 handle_pdu/4, 79 handle_trap/3, 80 handle_inform/3, 81 handle_report/3 82 ]). 83 84 85-define(SERVER, ?MODULE). 86 87-record(state, {parent, id, reqs = []}). 88%% -record(request, {from, ref, tmr, req_id, type}). 89 90 91%%---------------------------------------------------------------------- 92%% The user API 93%%---------------------------------------------------------------------- 94 95start() -> 96 start(self()). 97 98start(Parent) -> 99 start(Parent, test_user). 100 101start(Parent, Id) -> 102 proc_lib:start(?MODULE, main, [true, Parent, self(), Id]). 103 104start_link() -> 105 start_link(self()). 106start_link(Parent) -> 107 start_link(Parent, test_user). 108 109start_link(Parent, Id) -> 110 proc_lib:start_link(?MODULE, main, [true, Parent, self(), Id]). 111 112stop() -> 113 MRef = erlang:monitor(process, ?SERVER), 114 cast(stop), 115 receive {'DOWN', MRef, _, _, Info} -> 116 case Info of 117 noproc -> 118 ok; 119 noconnection -> 120 ok; 121 normal -> 122 ok 123 end 124 end. 125 126info() -> 127 call(info). 128 129system_info() -> 130 call(system_info). 131 132simulate_crash(Reason) -> 133 call({simulate_crash, Reason}). 134 135register_agent(TargetName, Config) 136 when is_list(TargetName) andalso is_list(Config) -> 137 call({register_agent, TargetName, Config}). 138 139unregister_agent(TargetName) -> 140 call({unregister_agent, TargetName}). 141 142agent_info(TargetName, Item) -> 143 call({agent_info, TargetName, Item}). 144 145update_agent_info(TargetName, Item, Val) -> 146 call({update_agent_info, TargetName, Item, Val}). 147 148which_all_agents() -> 149 call(which_all_agents). 150 151which_own_agents() -> 152 call(which_own_agents). 153 154load_mib(Mib) -> 155 call({load_mib, Mib}). 156 157unload_mib(Mib) -> 158 call({unload_mib, Mib}). 159 160%% -- 161 162sync_get2(TargetName, Oids, SendOpts) -> 163 call({sync_get2, TargetName, Oids, SendOpts}). 164 165 166%% -- 167 168async_get2(TargetName, Oids, SendOpts) -> 169 call({async_get2, TargetName, Oids, SendOpts}). 170 171%% -- 172 173sync_get_next2(TargetName, Oids, SendOpts) -> 174 call({sync_get_next2, TargetName, Oids, SendOpts}). 175 176%% -- 177 178async_get_next2(TargetName, Oids, SendOpts) -> 179 call({async_get_next2, TargetName, Oids, SendOpts}). 180 181%% -- 182 183sync_set2(TargetName, VAV, SendOpts) -> 184 call({sync_set2, TargetName, VAV, SendOpts}). 185 186%% -- 187 188async_set2(TargetName, VAV, SendOpts) -> 189 call({async_set2, TargetName, VAV, SendOpts}). 190 191%% -- 192 193sync_get_bulk2(TargetName, NonRep, MaxRep, Oids, SendOpts) -> 194 call({sync_get_bulk2, TargetName, NonRep, MaxRep, Oids, SendOpts}). 195 196%% -- 197 198async_get_bulk2(TargetName, NonRep, MaxRep, Oids, SendOpts) -> 199 call({async_get_bulk2, TargetName, NonRep, MaxRep, Oids, SendOpts}). 200 201%% -- 202 203name_to_oid(Name) -> 204 call({name_to_oid, Name}). 205 206oid_to_name(Oid) -> 207 call({oid_to_name, Oid}). 208 209purify_oid(Oid) -> 210 call({purify_oid, Oid}). 211 212 213%%---------------------------------------------------------------------- 214 215main(Debug, Parent, Starter, Id) -> 216 put(debug, Debug), 217 d("main -> entry with" 218 "~n Parent: ~p" 219 "~n Starter: ~p" 220 "~n Id: ~p", [Parent, Starter, Id]), 221 case (catch do_init(Id)) of 222 ok -> 223 proc_lib:init_ack(Starter, {ok, self()}), 224 loop(#state{parent = Parent, id = Id}); 225 Error -> 226 d("main -> error: " 227 "~p", [Error]), 228 proc_lib:init_ack(Starter, Error) 229 end. 230 231do_init(Id) -> 232 erlang:register(?SERVER, self()), 233 snmpm:register_user(Id, ?MODULE, self()). 234 235 236%%---------------------------------------------------------------------- 237 238loop(#state{parent = Parent, id = Id} = S) -> 239 d("loop -> entry"), 240 receive 241 {stop, _From} -> 242 d("loop -> received stop request"), 243 exit(normal); 244 245 {{simulate_crash, Reason}, From, Ref} -> 246 d("loop -> received simulate_crash request"), 247 reply(From, ok, Ref), 248 exit(Reason); 249 250 {info, From, Ref} -> 251 d("loop -> received info request"), 252 Res = snmpm:info(), 253 reply(From, Res, Ref), 254 loop(S); 255 256 {system_info, From, Ref} -> 257 d("loop -> received system_info request"), 258 Res = snmpm_config:system_info(), 259 reply(From, Res, Ref), 260 loop(S); 261 262 {{register_agent, TargetName, Conf}, From, Ref} -> 263 d("loop -> received register_agent request"), 264 Res = snmpm:register_agent(Id, TargetName, Conf), 265 reply(From, Res, Ref), 266 loop(S); 267 268 {{unregister_agent, TargetName}, From, Ref} -> 269 d("loop -> received unregister_agent request"), 270 Res = snmpm:unregister_agent(Id, TargetName), 271 reply(From, Res, Ref), 272 loop(S); 273 274 {{agent_info, TargetName, Item}, From, Ref} -> 275 d("loop -> received agent_info request with" 276 "~n TargetName: ~p" 277 "~n Item: ~p", [TargetName, Item]), 278 Res = snmpm:agent_info(TargetName, Item), 279 d("loop -> agent_info for ~p" 280 "~n Res: ~p", [Item, Res]), 281 reply(From, Res, Ref), 282 loop(S); 283 284 {{update_agent_info, TargetName, Item, Val}, From, Ref} -> 285 d("loop -> received update_agent_info request with" 286 "~n TargetName: ~p" 287 "~n Item: ~p" 288 "~n Val: ~p", [TargetName, Item, Val]), 289 Res = snmpm:update_agent_info(Id, TargetName, Item, Val), 290 reply(From, Res, Ref), 291 loop(S); 292 293 {which_all_agents, From, Ref} -> 294 d("loop -> received which_all_agents request"), 295 Res = snmpm:which_agents(), 296 reply(From, Res, Ref), 297 loop(S); 298 299 {which_own_agents, From, Ref} -> 300 d("loop -> received which_own_agents request"), 301 Res = snmpm:which_agents(Id), 302 reply(From, Res, Ref), 303 loop(S); 304 305 {{load_mib, Mib}, From, Ref} -> 306 d("loop -> received load_mib request"), 307 Res = snmpm:load_mib(Mib), 308 reply(From, Res, Ref), 309 loop(S); 310 311 {{unload_mib, Mib}, From, Ref} -> 312 d("loop -> received unload_mib request"), 313 Res = snmpm:unload_mib(Mib), 314 reply(From, Res, Ref), 315 loop(S); 316 317 318 %% 319 %% -- (sync) get-request -- 320 %% 321 322 {{sync_get2, TargetName, Oids, SendOpts}, From, Ref} 323 when is_list(TargetName) -> 324 snmpm:verbosity(server, trace), 325 d("loop -> received sync_get2 request with" 326 "~n TargetName: ~p" 327 "~n Oids: ~p" 328 "~n SendOpts: ~p", [TargetName, Oids, SendOpts]), 329 Res = snmpm:sync_get2(Id, TargetName, Oids, SendOpts), 330 d("loop -> result:" 331 "~n ~p", [Res]), 332 reply(From, Res, Ref), 333 loop(S); 334 335 336 %% 337 %% -- (async) get-request -- 338 %% 339 340 {{async_get2, TargetName, Oids, SendOpts}, From, Ref} 341 when is_list(TargetName) -> 342 d("loop -> received async_get2 request with" 343 "~n TargetName: ~p" 344 "~n Oids: ~p" 345 "~n SendOpts: ~p", [TargetName, Oids, SendOpts]), 346 Res = snmpm:async_get2(Id, TargetName, Oids, SendOpts), 347 reply(From, Res, Ref), 348 loop(S); 349 350 351 %% 352 %% -- (sync) get_next-request -- 353 %% 354 355 {{sync_get_next2, TargetName, Oids, SendOpts}, From, Ref} 356 when is_list(TargetName) -> 357 d("loop -> received sync_get_next2 request with" 358 "~n TargetName: ~p" 359 "~n Oids: ~p" 360 "~n SendOpts: ~p", [TargetName, Oids, SendOpts]), 361 Res = snmpm:sync_get_next2(Id, TargetName, Oids, SendOpts), 362 reply(From, Res, Ref), 363 loop(S); 364 365 366 %% 367 %% -- (async) get_next-request -- 368 %% 369 370 {{async_get_next2, TargetName, Oids, SendOpts}, From, Ref} 371 when is_list(TargetName) -> 372 d("loop -> received async_get_next2 request with" 373 "~n TargetName: ~p" 374 "~n Oids: ~p" 375 "~n SendOpts: ~p", [TargetName, Oids, SendOpts]), 376 Res = snmpm:async_get_next2(Id, TargetName, Oids, SendOpts), 377 reply(From, Res, Ref), 378 loop(S); 379 380 381 %% 382 %% -- (sync) set-request -- 383 %% 384 385 {{sync_set2, TargetName, VAV, SendOpts}, From, Ref} 386 when is_list(TargetName) -> 387 d("loop -> received sync_set2 request with" 388 "~n TargetName: ~p" 389 "~n VAV: ~p" 390 "~n SendOpts: ~p", [TargetName, VAV, SendOpts]), 391 Res = snmpm:sync_set2(Id, TargetName, VAV, SendOpts), 392 reply(From, Res, Ref), 393 loop(S); 394 395 396 %% 397 %% -- (async) set-request -- 398 %% 399 400 {{async_set2, TargetName, VAV, SendOpts}, From, Ref} 401 when is_list(TargetName) -> 402 d("loop -> received async_set2 request with" 403 "~n TargetName: ~p" 404 "~n VAV: ~p" 405 "~n SendOpts: ~p", [TargetName, VAV, SendOpts]), 406 Res = snmpm:async_set2(Id, TargetName, VAV, SendOpts), 407 reply(From, Res, Ref), 408 loop(S); 409 410 411 %% 412 %% -- (sync) get-bulk-request -- 413 %% 414 415 {{sync_get_bulk2, TargetName, NonRep, MaxRep, Oids, SendOpts}, From, Ref} 416 when is_list(TargetName) -> 417 d("loop -> received sync_get_bulk request with" 418 "~n TargetName: ~p" 419 "~n NonRep: ~w" 420 "~n MaxRep: ~w" 421 "~n Oids: ~p" 422 "~n SendOpts: ~p", 423 [TargetName, NonRep, MaxRep, Oids, SendOpts]), 424 Res = snmpm:sync_get_bulk2(Id, TargetName, 425 NonRep, MaxRep, Oids, SendOpts), 426 reply(From, Res, Ref), 427 loop(S); 428 429 430 %% 431 %% -- (async) get-bulk-request -- 432 %% 433 434 {{async_get_bulk2, TargetName, NonRep, MaxRep, Oids, SendOpts}, 435 From, Ref} when is_list(TargetName) -> 436 d("loop -> received async_get_bulk2 request with" 437 "~n TargetName: ~p" 438 "~n NonRep: ~w" 439 "~n MaxRep: ~w" 440 "~n Oids: ~p" 441 "~n SendOpts: ~p", 442 [TargetName, NonRep, MaxRep, Oids, SendOpts]), 443 Res = snmpm:async_get_bulk2(Id, TargetName, 444 NonRep, MaxRep, Oids, SendOpts), 445 reply(From, Res, Ref), 446 loop(S); 447 448 449 %% 450 %% -- logical name translation -- 451 %% 452 453 {{name_to_oid, Name}, From, Ref} -> 454 d("loop -> received name_to_oid request for" 455 "~n Name: ~p", [Name]), 456 Res = snmpm:name_to_oid(Name), 457 reply(From, Res, Ref), 458 loop(S); 459 460 {{oid_to_name, Oid}, From, Ref} -> 461 d("loop -> received oid_to_name request for" 462 "~n Oid: ~p", [Oid]), 463 Res = snmpm:oid_to_name(Oid), 464 reply(From, Res, Ref), 465 loop(S); 466 467 {{purify_oid, Oid}, From, Ref} -> 468 d("loop -> received purify_oid request for" 469 "~n Oid: ~p", [Oid]), 470 Res = do_purify_oid(Oid), 471 reply(From, Res, Ref), 472 loop(S); 473 474 475 %% SNMP manager callback messages (from our callback API): 476 477 {handle_error, _Pid, ReqId, Reason} -> 478 d("loop -> received error callback from manager for ~w:" 479 "~n ~p", [ReqId, Reason]), 480 Parent ! {async_event, ReqId, {error, Reason}}, 481 loop(S); 482 483 {handle_agent, _Pid, Addr, Port, SnmpInfo} -> 484 d("loop -> received agent callback from manager for ~n ~p:~w", 485 [Addr, Port]), 486 Parent ! {async_event, {Addr, Port}, {agent, SnmpInfo}}, 487 loop(S); 488 489 {handle_pdu, _Pid, _TargetName, ReqId, SnmpResponse} -> 490 d("loop -> received pdu callback from manager for ~w", [ReqId]), 491 Parent ! {async_event, ReqId, {pdu, SnmpResponse}}, 492 loop(S); 493 494 {handle_trap, _Pid, TargetName, SnmpTrap} -> 495 d("loop -> received trap callback from manager for " 496 "~n ~p", 497 "~n ~p", 498 [TargetName, SnmpTrap]), 499 Parent ! {async_event, TargetName, {trap, SnmpTrap}}, 500 loop(S); 501 502 {handle_inform, Pid, TargetName, SnmpInform} -> 503 d("loop -> received inform callback from manager for " 504 "~n ~p", 505 "~n ~p", 506 [TargetName, SnmpInform]), 507 Parent ! {async_event, TargetName, {inform, Pid, SnmpInform}}, 508 loop(S); 509 510 {handle_report, _Pid, TargetName, SnmpReport} -> 511 d("loop -> received report callback from manager for " 512 "~n ~p", 513 "~n ~p", 514 [TargetName, SnmpReport]), 515 Parent ! {async_event, TargetName, {report, SnmpReport}}, 516 loop(S); 517 518 {handle_invalid_result, _Pid, In, Out} -> 519 d("loop -> received invalid result callback from manager for " 520 "~n In: ~p", 521 "~n Out: ~p", [In, Out]), 522 info("received invalid result message: " 523 "~n In: ~p" 524 "~n Out: ~p", [In, Out]), 525 loop(S); 526 527 {'EXIT', Parent, Reason} -> 528 d("received exit signal from parent: ~n~p", [Reason]), 529 info("received exit signal from parent: ~n~p", [Reason]), 530 exit(Reason); 531 532 Unknown -> 533 d("received unknown message: ~n~p", [Unknown]), 534 info("received unknown message: ~n~p", [Unknown]), 535 loop(S) 536 end. 537 538 539%% ------------- 540 541do_purify_oid([A|T]) when is_atom(A) -> 542 case snmpm:name_to_oid(A) of 543 {ok, [Oid|_]} -> 544 verify_pure_oid(lists:flatten([Oid|T])); 545 {error, not_found} -> 546 {error, {not_found, A}}; 547 {error, _} = Error -> 548 Error 549 end; 550do_purify_oid(L) when is_list(L) -> 551 verify_pure_oid(lists:flatten(L)); 552do_purify_oid(X) -> 553 {error, {unpure_oid, X}}. 554 555verify_pure_oid([]) -> 556 []; 557verify_pure_oid([H | T]) when is_integer(H) andalso (H >= 0) -> 558 [H | verify_pure_oid(T)]; 559verify_pure_oid([H | _]) -> 560 throw({error, {not_pure_oid, H}}). 561 562 563%% ------------- 564 565info(F, A) -> 566 error_logger:info_msg("TEST MGR USER " ++ F ++ "~n", A). 567 568 569%% ------------- 570 571call(Req) -> 572 call(Req, 5000). 573 574call(Req, To) when is_integer(To) -> 575 Ref = make_ref(), 576 ?SERVER ! {Req, self(), Ref}, 577 receive 578 {Reply, Ref} -> 579 Reply 580 after To -> 581 {error, timeout} 582 end. 583 584reply(Pid, Reply, Ref) -> 585 d("reply -> entry with" 586 "~n Pid: ~p" 587 "~n Reply: ~p" 588 "~n Ref: ~p", [Pid, Reply, Ref]), 589 Pid ! {Reply, Ref}. 590 591cast(Msg) -> 592 ?SERVER ! {Msg, self()}, 593 ok. 594 595 596%%---------------------------------------------------------------------- 597%% User callback functions: 598%%---------------------------------------------------------------------- 599 600handle_error(ReqId, Reason, UserPid) -> 601 UserPid ! {handle_error, self(), ReqId, Reason}, 602 ignore. 603 604 605handle_agent(Addr, Port, SnmpInfo, UserPid, UserData) -> 606 UserPid ! {handle_agent, self(), Addr, Port, SnmpInfo, UserData}, 607 ignore. 608 609 610handle_pdu(TargetName, ReqId, SnmpResponse, UserPid) -> 611 UserPid ! {handle_pdu, self(), TargetName, ReqId, SnmpResponse}, 612 ignore. 613 614handle_trap(TargetName, SnmpTrap, UserPid) -> 615 UserPid ! {handle_trap, self(), TargetName, SnmpTrap}, 616 ignore. 617 618handle_inform(TargetName, SnmpInform, UserPid) -> 619 UserPid ! {handle_inform, self(), TargetName, SnmpInform}, 620 receive 621 {handle_inform_no_response, TargetName} -> 622 no_reply; 623 {handle_inform_response, TargetName} -> 624 ignore 625 end. 626 627handle_report(TargetName, SnmpReport, UserPid) -> 628 UserPid ! {handle_report, self(), TargetName, SnmpReport}, 629 ignore. 630 631 632%%---------------------------------------------------------------------- 633%% Debug 634%%---------------------------------------------------------------------- 635 636d(F) -> 637 d(F, []). 638 639d(F, A) -> 640 d(get(debug), F, A). 641 642d(true, F, A) -> 643 ?IPRINT("~w:" ++ F, [?SERVER|A]); 644d(_, _, _) -> 645 ok. 646