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 d("loop -> received sync_get2 request with" 325 "~n TargetName: ~p" 326 "~n Oids: ~p" 327 "~n SendOpts: ~p", [TargetName, Oids, SendOpts]), 328 Res = snmpm:sync_get2(Id, TargetName, Oids, SendOpts), 329 reply(From, Res, Ref), 330 loop(S); 331 332 333 %% 334 %% -- (async) get-request -- 335 %% 336 337 {{async_get2, TargetName, Oids, SendOpts}, From, Ref} 338 when is_list(TargetName) -> 339 d("loop -> received async_get2 request with" 340 "~n TargetName: ~p" 341 "~n Oids: ~p" 342 "~n SendOpts: ~p", [TargetName, Oids, SendOpts]), 343 Res = snmpm:async_get2(Id, TargetName, Oids, SendOpts), 344 reply(From, Res, Ref), 345 loop(S); 346 347 348 %% 349 %% -- (sync) get_next-request -- 350 %% 351 352 {{sync_get_next2, TargetName, Oids, SendOpts}, From, Ref} 353 when is_list(TargetName) -> 354 d("loop -> received sync_get_next2 request with" 355 "~n TargetName: ~p" 356 "~n Oids: ~p" 357 "~n SendOpts: ~p", [TargetName, Oids, SendOpts]), 358 Res = snmpm:sync_get_next2(Id, TargetName, Oids, SendOpts), 359 reply(From, Res, Ref), 360 loop(S); 361 362 363 %% 364 %% -- (async) get_next-request -- 365 %% 366 367 {{async_get_next2, TargetName, Oids, SendOpts}, From, Ref} 368 when is_list(TargetName) -> 369 d("loop -> received async_get_next2 request with" 370 "~n TargetName: ~p" 371 "~n Oids: ~p" 372 "~n SendOpts: ~p", [TargetName, Oids, SendOpts]), 373 Res = snmpm:async_get_next2(Id, TargetName, Oids, SendOpts), 374 reply(From, Res, Ref), 375 loop(S); 376 377 378 %% 379 %% -- (sync) set-request -- 380 %% 381 382 {{sync_set2, TargetName, VAV, SendOpts}, From, Ref} 383 when is_list(TargetName) -> 384 d("loop -> received sync_set2 request with" 385 "~n TargetName: ~p" 386 "~n VAV: ~p" 387 "~n SendOpts: ~p", [TargetName, VAV, SendOpts]), 388 Res = snmpm:sync_set2(Id, TargetName, VAV, SendOpts), 389 reply(From, Res, Ref), 390 loop(S); 391 392 393 %% 394 %% -- (async) set-request -- 395 %% 396 397 {{async_set2, TargetName, VAV, SendOpts}, From, Ref} 398 when is_list(TargetName) -> 399 d("loop -> received async_set2 request with" 400 "~n TargetName: ~p" 401 "~n VAV: ~p" 402 "~n SendOpts: ~p", [TargetName, VAV, SendOpts]), 403 Res = snmpm:async_set2(Id, TargetName, VAV, SendOpts), 404 reply(From, Res, Ref), 405 loop(S); 406 407 408 %% 409 %% -- (sync) get-bulk-request -- 410 %% 411 412 {{sync_get_bulk2, TargetName, NonRep, MaxRep, Oids, SendOpts}, From, Ref} 413 when is_list(TargetName) -> 414 d("loop -> received sync_get_bulk request with" 415 "~n TargetName: ~p" 416 "~n NonRep: ~w" 417 "~n MaxRep: ~w" 418 "~n Oids: ~p" 419 "~n SendOpts: ~p", 420 [TargetName, NonRep, MaxRep, Oids, SendOpts]), 421 Res = snmpm:sync_get_bulk2(Id, TargetName, 422 NonRep, MaxRep, Oids, SendOpts), 423 reply(From, Res, Ref), 424 loop(S); 425 426 427 %% 428 %% -- (async) get-bulk-request -- 429 %% 430 431 {{async_get_bulk2, TargetName, NonRep, MaxRep, Oids, SendOpts}, 432 From, Ref} when is_list(TargetName) -> 433 d("loop -> received async_get_bulk2 request with" 434 "~n TargetName: ~p" 435 "~n NonRep: ~w" 436 "~n MaxRep: ~w" 437 "~n Oids: ~p" 438 "~n SendOpts: ~p", 439 [TargetName, NonRep, MaxRep, Oids, SendOpts]), 440 Res = snmpm:async_get_bulk2(Id, TargetName, 441 NonRep, MaxRep, Oids, SendOpts), 442 reply(From, Res, Ref), 443 loop(S); 444 445 446 %% 447 %% -- logical name translation -- 448 %% 449 450 {{name_to_oid, Name}, From, Ref} -> 451 d("loop -> received name_to_oid request for" 452 "~n Name: ~p", [Name]), 453 Res = snmpm:name_to_oid(Name), 454 reply(From, Res, Ref), 455 loop(S); 456 457 {{oid_to_name, Oid}, From, Ref} -> 458 d("loop -> received oid_to_name request for" 459 "~n Oid: ~p", [Oid]), 460 Res = snmpm:oid_to_name(Oid), 461 reply(From, Res, Ref), 462 loop(S); 463 464 {{purify_oid, Oid}, From, Ref} -> 465 d("loop -> received purify_oid request for" 466 "~n Oid: ~p", [Oid]), 467 Res = do_purify_oid(Oid), 468 reply(From, Res, Ref), 469 loop(S); 470 471 472 %% SNMP manager callback messages (from our callback API): 473 474 {handle_error, _Pid, ReqId, Reason} -> 475 d("loop -> received error callback from manager for ~w:" 476 "~n ~p", [ReqId, Reason]), 477 Parent ! {async_event, ReqId, {error, Reason}}, 478 loop(S); 479 480 {handle_agent, _Pid, Addr, Port, SnmpInfo} -> 481 d("loop -> received agent callback from manager for ~n ~p:~w", 482 [Addr, Port]), 483 Parent ! {async_event, {Addr, Port}, {agent, SnmpInfo}}, 484 loop(S); 485 486 {handle_pdu, _Pid, _TargetName, ReqId, SnmpResponse} -> 487 d("loop -> received pdu callback from manager for ~w", [ReqId]), 488 Parent ! {async_event, ReqId, {pdu, SnmpResponse}}, 489 loop(S); 490 491 {handle_trap, _Pid, TargetName, SnmpTrap} -> 492 d("loop -> received trap callback from manager for " 493 "~n ~p", 494 "~n ~p", 495 [TargetName, SnmpTrap]), 496 Parent ! {async_event, TargetName, {trap, SnmpTrap}}, 497 loop(S); 498 499 {handle_inform, Pid, TargetName, SnmpInform} -> 500 d("loop -> received inform callback from manager for " 501 "~n ~p", 502 "~n ~p", 503 [TargetName, SnmpInform]), 504 Parent ! {async_event, TargetName, {inform, Pid, SnmpInform}}, 505 loop(S); 506 507 {handle_report, _Pid, TargetName, SnmpReport} -> 508 d("loop -> received report callback from manager for " 509 "~n ~p", 510 "~n ~p", 511 [TargetName, SnmpReport]), 512 Parent ! {async_event, TargetName, {report, SnmpReport}}, 513 loop(S); 514 515 {handle_invalid_result, _Pid, In, Out} -> 516 d("loop -> received invalid result callback from manager for " 517 "~n In: ~p", 518 "~n Out: ~p", [In, Out]), 519 info("received invalid result message: " 520 "~n In: ~p" 521 "~n Out: ~p", [In, Out]), 522 loop(S); 523 524 {'EXIT', Parent, Reason} -> 525 d("received exit signal from parent: ~n~p", [Reason]), 526 info("received exit signal from parent: ~n~p", [Reason]), 527 exit(Reason); 528 529 Unknown -> 530 d("received unknown message: ~n~p", [Unknown]), 531 info("received unknown message: ~n~p", [Unknown]), 532 loop(S) 533 end. 534 535 536%% ------------- 537 538do_purify_oid([A|T]) when is_atom(A) -> 539 case snmpm:name_to_oid(A) of 540 {ok, [Oid|_]} -> 541 verify_pure_oid(lists:flatten([Oid|T])); 542 {error, not_found} -> 543 {error, {not_found, A}}; 544 {error, _} = Error -> 545 Error 546 end; 547do_purify_oid(L) when is_list(L) -> 548 verify_pure_oid(lists:flatten(L)); 549do_purify_oid(X) -> 550 {error, {unpure_oid, X}}. 551 552verify_pure_oid([]) -> 553 []; 554verify_pure_oid([H | T]) when is_integer(H) andalso (H >= 0) -> 555 [H | verify_pure_oid(T)]; 556verify_pure_oid([H | _]) -> 557 throw({error, {not_pure_oid, H}}). 558 559 560%% ------------- 561 562info(F, A) -> 563 error_logger:info_msg("TEST MGR USER " ++ F ++ "~n", A). 564 565 566%% ------------- 567 568call(Req) -> 569 call(Req, 5000). 570 571call(Req, To) when is_integer(To) -> 572 Ref = make_ref(), 573 ?SERVER ! {Req, self(), Ref}, 574 receive 575 {Reply, Ref} -> 576 Reply 577 after To -> 578 {error, timeout} 579 end. 580 581reply(Pid, Reply, Ref) -> 582 d("reply -> entry with" 583 "~n Pid: ~p" 584 "~n Reply: ~p" 585 "~n Ref: ~p", [Pid, Reply, Ref]), 586 Pid ! {Reply, Ref}. 587 588cast(Msg) -> 589 ?SERVER ! {Msg, self()}, 590 ok. 591 592 593%%---------------------------------------------------------------------- 594%% User callback functions: 595%%---------------------------------------------------------------------- 596 597handle_error(ReqId, Reason, UserPid) -> 598 UserPid ! {handle_error, self(), ReqId, Reason}, 599 ignore. 600 601 602handle_agent(Addr, Port, SnmpInfo, UserPid, UserData) -> 603 UserPid ! {handle_agent, self(), Addr, Port, SnmpInfo, UserData}, 604 ignore. 605 606 607handle_pdu(TargetName, ReqId, SnmpResponse, UserPid) -> 608 UserPid ! {handle_pdu, self(), TargetName, ReqId, SnmpResponse}, 609 ignore. 610 611handle_trap(TargetName, SnmpTrap, UserPid) -> 612 UserPid ! {handle_trap, self(), TargetName, SnmpTrap}, 613 ignore. 614 615handle_inform(TargetName, SnmpInform, UserPid) -> 616 UserPid ! {handle_inform, self(), TargetName, SnmpInform}, 617 receive 618 {handle_inform_no_response, TargetName} -> 619 no_reply; 620 {handle_inform_response, TargetName} -> 621 ignore 622 end. 623 624handle_report(TargetName, SnmpReport, UserPid) -> 625 UserPid ! {handle_report, self(), TargetName, SnmpReport}, 626 ignore. 627 628 629%%---------------------------------------------------------------------- 630%% Debug 631%%---------------------------------------------------------------------- 632 633d(F) -> 634 d(F, []). 635 636d(F, A) -> 637 d(get(debug), F, A). 638 639d(true, F, A) -> 640 io:format("~w:" ++ F ++ "~n", [?SERVER|A]); 641d(_, _, _) -> 642 ok. 643