00001
00002
00003
00004
00005 #include <net-snmp/net-snmp-config.h>
00006 #include <errno.h>
00007 #ifdef HAVE_LIMITS_H
00008 #include <limits.h>
00009 #endif
00010 #include <stdio.h>
00011 #include <sys/types.h>
00012
00013 #if TIME_WITH_SYS_TIME
00014 # ifdef WIN32
00015 # include <sys/timeb.h>
00016 # else
00017 # include <sys/time.h>
00018 # endif
00019 # include <time.h>
00020 #else
00021 # if HAVE_SYS_TIME_H
00022 # include <sys/time.h>
00023 # else
00024 # include <time.h>
00025 # endif
00026 #endif
00027 #if HAVE_SYS_TIMES_H
00028 #include <sys/times.h>
00029 #endif
00030 #if HAVE_STRING_H
00031 #include <string.h>
00032 #else
00033 #include <strings.h>
00034 #endif
00035 #include <ctype.h>
00036 #if HAVE_NETINET_IN_H
00037 #include <netinet/in.h>
00038 #endif
00039 #if HAVE_UNISTD_H
00040 #include <unistd.h>
00041 #endif
00042 #if HAVE_WINSOCK_H
00043 #include <winsock.h>
00044 #endif
00045 #if HAVE_SYS_SOCKET_H
00046 #include <sys/socket.h>
00047 #endif
00048 #if HAVE_NETDB_H
00049 #include <netdb.h>
00050 #endif
00051 #if HAVE_STDLIB_H
00052 # include <stdlib.h>
00053 #endif
00054
00055
00056
00057
00058 #ifdef HAVE_SYS_IOCTL_H
00059 # include <sys/ioctl.h>
00060 #endif
00061 #ifdef HAVE_NET_IF_H
00062 # include <net/if.h>
00063 #endif
00064
00065 #if HAVE_DMALLOC_H
00066 #include <dmalloc.h>
00067 #endif
00068
00069 #include <net-snmp/types.h>
00070 #include <net-snmp/output_api.h>
00071 #include <net-snmp/config_api.h>
00072 #include <net-snmp/utilities.h>
00073
00074 #include <net-snmp/library/snmpv3.h>
00075 #include <net-snmp/library/callback.h>
00076 #include <net-snmp/library/snmp_api.h>
00077 #include <net-snmp/library/lcd_time.h>
00078 #include <net-snmp/library/scapi.h>
00079 #include <net-snmp/library/keytools.h>
00080 #include <net-snmp/library/lcd_time.h>
00081 #include <net-snmp/library/snmp_secmod.h>
00082 #include <net-snmp/library/snmpusm.h>
00083 #include <net-snmp/library/transform_oids.h>
00084
00085 static u_long engineBoots = 1;
00086 static unsigned int engineIDType = ENGINEID_TYPE_NETSNMP_RND;
00087 static unsigned char *engineID = NULL;
00088 static size_t engineIDLength = 0;
00089 static unsigned char *engineIDNic = NULL;
00090 static unsigned int engineIDIsSet = 0;
00091 static unsigned char *oldEngineID = NULL;
00092 static size_t oldEngineIDLength = 0;
00093 static struct timeval snmpv3starttime;
00094
00095
00096
00097
00098 static const oid *defaultAuthType = NULL;
00099 static size_t defaultAuthTypeLen = 0;
00100 static const oid *defaultPrivType = NULL;
00101 static size_t defaultPrivTypeLen = 0;
00102
00103
00104 #if defined(HAVE_SYS_TIMES_H) && defined(HAVE_UNISTD_H) && defined(HAVE_TIMES) && defined(_SC_CLK_TCK) && defined(HAVE_SYSCONF) && defined(UINT_MAX)
00105
00106 #define SNMP_USE_TIMES 1
00107
00108 static clock_t snmpv3startClock;
00109 static long clockticks = 0;
00110 static unsigned int lastcalltime = 0;
00111 static unsigned int wrapcounter = 0;
00112
00113 #endif
00114
00115 #if defined(IFHWADDRLEN) && defined(SIOCGIFHWADDR)
00116 static int getHwAddress(const char *networkDevice, char *addressOut);
00117 #endif
00118
00119 void
00120 snmpv3_authtype_conf(const char *word, char *cptr)
00121 {
00122 #ifndef DISABLE_MD5
00123 if (strcasecmp(cptr, "MD5") == 0)
00124 defaultAuthType = usmHMACMD5AuthProtocol;
00125 else
00126 #endif
00127 if (strcasecmp(cptr, "SHA") == 0)
00128 defaultAuthType = usmHMACSHA1AuthProtocol;
00129 else
00130 config_perror("Unknown authentication type");
00131 defaultAuthTypeLen = USM_LENGTH_OID_TRANSFORM;
00132 DEBUGMSGTL(("snmpv3", "set default authentication type: %s\n", cptr));
00133 }
00134
00135 const oid *
00136 get_default_authtype(size_t * len)
00137 {
00138 if (defaultAuthType == NULL) {
00139 defaultAuthType = SNMP_DEFAULT_AUTH_PROTO;
00140 defaultAuthTypeLen = SNMP_DEFAULT_AUTH_PROTOLEN;
00141 }
00142 if (len)
00143 *len = defaultAuthTypeLen;
00144 return defaultAuthType;
00145 }
00146
00147 void
00148 snmpv3_privtype_conf(const char *word, char *cptr)
00149 {
00150 int testcase = 0;
00151
00152 #ifndef DISABLE_DES
00153 if (strcasecmp(cptr, "DES") == 0) {
00154 testcase = 1;
00155 defaultPrivType = usmDESPrivProtocol;
00156 }
00157 #endif
00158
00159 #if HAVE_AES
00160
00161 if (strcasecmp(cptr, "AES128") == 0 ||
00162 strcasecmp(cptr, "AES") == 0) {
00163 testcase = 1;
00164 defaultPrivType = usmAES128PrivProtocol;
00165 }
00166 #endif
00167 if (testcase == 0)
00168 config_perror("Unknown privacy type");
00169 defaultPrivTypeLen = SNMP_DEFAULT_PRIV_PROTOLEN;
00170 DEBUGMSGTL(("snmpv3", "set default privacy type: %s\n", cptr));
00171 }
00172
00173 const oid *
00174 get_default_privtype(size_t * len)
00175 {
00176 if (defaultPrivType == NULL) {
00177 #ifndef DISABLE_DES
00178 defaultPrivType = usmDESPrivProtocol;
00179 #else
00180 defaultPrivType = usmAESPrivProtocol;
00181 #endif
00182 defaultPrivTypeLen = USM_LENGTH_OID_TRANSFORM;
00183 }
00184 if (len)
00185 *len = defaultPrivTypeLen;
00186 return defaultPrivType;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 int
00201 parse_secLevel_conf(const char *word, char *cptr) {
00202 if (strcasecmp(cptr, "noAuthNoPriv") == 0 || strcmp(cptr, "1") == 0 ||
00203 strcasecmp(cptr, "nanp") == 0) {
00204 return SNMP_SEC_LEVEL_NOAUTH;
00205 } else if (strcasecmp(cptr, "authNoPriv") == 0 || strcmp(cptr, "2") == 0 ||
00206 strcasecmp(cptr, "anp") == 0) {
00207 return SNMP_SEC_LEVEL_AUTHNOPRIV;
00208 } else if (strcasecmp(cptr, "authPriv") == 0 || strcmp(cptr, "3") == 0 ||
00209 strcasecmp(cptr, "ap") == 0) {
00210 return SNMP_SEC_LEVEL_AUTHPRIV;
00211 } else {
00212 return -1;
00213 }
00214 }
00215
00216 void
00217 snmpv3_secLevel_conf(const char *word, char *cptr)
00218 {
00219 char buf[1024];
00220 int secLevel;
00221
00222 if ((secLevel = parse_secLevel_conf( word, cptr )) >= 0 ) {
00223 netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID,
00224 NETSNMP_DS_LIB_SECLEVEL, secLevel);
00225 } else {
00226 snprintf(buf, sizeof(buf), "Unknown security level: %s", cptr);
00227 buf[ sizeof(buf)-1 ] = 0;
00228 config_perror(buf);
00229 }
00230 DEBUGMSGTL(("snmpv3", "default secLevel set to: %s = %d\n", cptr,
00231 netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
00232 NETSNMP_DS_LIB_SECLEVEL)));
00233 }
00234
00235
00236 int
00237 snmpv3_options(char *optarg, netsnmp_session * session, char **Apsz,
00238 char **Xpsz, int argc, char *const *argv)
00239 {
00240 char *cp = optarg;
00241 int testcase;
00242 optarg++;
00243
00244
00245
00246 if (*optarg == '=') {
00247 optarg++;
00248 }
00249
00250
00251
00252 while (*optarg && isspace(*optarg)) {
00253 optarg++;
00254 }
00255
00256
00257
00258
00259 if (!*optarg) {
00260
00261
00262
00263
00264 optarg = argv[optind++];
00265 if (optind > argc) {
00266 fprintf(stderr,
00267 "Missing argument after SNMPv3 '-3%c' option.\n", *cp);
00268 return (-1);
00269 }
00270 }
00271
00272 switch (*cp) {
00273
00274 case 'Z':
00275 errno=0;
00276 session->engineBoots = strtoul(optarg, &cp, 10);
00277 if (errno || cp == optarg) {
00278 fprintf(stderr, "Need engine boots value after -3Z flag.\n");
00279 return (-1);
00280 }
00281 if (*cp == ',') {
00282 char *endptr;
00283 cp++;
00284 session->engineTime = strtoul(cp, &endptr, 10);
00285 if (errno || cp == endptr) {
00286 fprintf(stderr, "Need engine time after \"-3Z engineBoot,\".\n");
00287 return (-1);
00288 }
00289 } else {
00290 fprintf(stderr, "Need engine time after \"-3Z engineBoot,\".\n");
00291 return (-1);
00292 }
00293 break;
00294
00295 case 'e':{
00296 size_t ebuf_len = 32, eout_len = 0;
00297 u_char *ebuf = (u_char *) malloc(ebuf_len);
00298
00299 if (ebuf == NULL) {
00300 fprintf(stderr, "malloc failure processing -3e flag.\n");
00301 return (-1);
00302 }
00303 if (!snmp_hex_to_binary
00304 (&ebuf, &ebuf_len, &eout_len, 1, optarg)) {
00305 fprintf(stderr, "Bad engine ID value after -3e flag.\n");
00306 SNMP_FREE(ebuf);
00307 return (-1);
00308 }
00309 session->securityEngineID = ebuf;
00310 session->securityEngineIDLen = eout_len;
00311 break;
00312 }
00313
00314 case 'E':{
00315 size_t ebuf_len = 32, eout_len = 0;
00316 u_char *ebuf = (u_char *) malloc(ebuf_len);
00317
00318 if (ebuf == NULL) {
00319 fprintf(stderr, "malloc failure processing -3E flag.\n");
00320 return (-1);
00321 }
00322 if (!snmp_hex_to_binary
00323 (&ebuf, &ebuf_len, &eout_len, 1, optarg)) {
00324 fprintf(stderr, "Bad engine ID value after -3E flag.\n");
00325 SNMP_FREE(ebuf);
00326 return (-1);
00327 }
00328 session->contextEngineID = ebuf;
00329 session->contextEngineIDLen = eout_len;
00330 break;
00331 }
00332
00333 case 'n':
00334 session->contextName = optarg;
00335 session->contextNameLen = strlen(optarg);
00336 break;
00337
00338 case 'u':
00339 session->securityName = optarg;
00340 session->securityNameLen = strlen(optarg);
00341 break;
00342
00343 case 'l':
00344 if (!strcasecmp(optarg, "noAuthNoPriv") || !strcmp(optarg, "1") ||
00345 !strcasecmp(optarg, "nanp")) {
00346 session->securityLevel = SNMP_SEC_LEVEL_NOAUTH;
00347 } else if (!strcasecmp(optarg, "authNoPriv")
00348 || !strcmp(optarg, "2") || !strcasecmp(optarg, "anp")) {
00349 session->securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
00350 } else if (!strcasecmp(optarg, "authPriv") || !strcmp(optarg, "3")
00351 || !strcasecmp(optarg, "ap")) {
00352 session->securityLevel = SNMP_SEC_LEVEL_AUTHPRIV;
00353 } else {
00354 fprintf(stderr,
00355 "Invalid security level specified after -3l flag: %s\n",
00356 optarg);
00357 return (-1);
00358 }
00359
00360 break;
00361
00362 case 'a':
00363 #ifndef DISABLE_MD5
00364 if (!strcasecmp(optarg, "MD5")) {
00365 session->securityAuthProto = usmHMACMD5AuthProtocol;
00366 session->securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
00367 } else
00368 #endif
00369 if (!strcasecmp(optarg, "SHA")) {
00370 session->securityAuthProto = usmHMACSHA1AuthProtocol;
00371 session->securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN;
00372 } else {
00373 fprintf(stderr,
00374 "Invalid authentication protocol specified after -3a flag: %s\n",
00375 optarg);
00376 return (-1);
00377 }
00378 break;
00379
00380 case 'x':
00381 testcase = 0;
00382 #ifndef DISABLE_DES
00383 if (!strcasecmp(optarg, "DES")) {
00384 session->securityPrivProto = usmDESPrivProtocol;
00385 session->securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN;
00386 testcase = 1;
00387 }
00388 #endif
00389 #ifdef HAVE_AES
00390 if (!strcasecmp(optarg, "AES128") ||
00391 strcasecmp(optarg, "AES")) {
00392 session->securityPrivProto = usmAES128PrivProtocol;
00393 session->securityPrivProtoLen = USM_PRIV_PROTO_AES128_LEN;
00394 testcase = 1;
00395 }
00396 #endif
00397 if (testcase == 0) {
00398 fprintf(stderr,
00399 "Invalid privacy protocol specified after -3x flag: %s\n",
00400 optarg);
00401 return (-1);
00402 }
00403 break;
00404
00405 case 'A':
00406 *Apsz = optarg;
00407 break;
00408
00409 case 'X':
00410 *Xpsz = optarg;
00411 break;
00412
00413 case 'm': {
00414 size_t bufSize = sizeof(session->securityAuthKey);
00415 u_char *tmpp = session->securityAuthKey;
00416 if (!snmp_hex_to_binary(&tmpp, &bufSize,
00417 &session->securityAuthKeyLen, 0, optarg)) {
00418 fprintf(stderr, "Bad key value after -3m flag.\n");
00419 return (-1);
00420 }
00421 break;
00422 }
00423
00424 case 'M': {
00425 size_t bufSize = sizeof(session->securityPrivKey);
00426 u_char *tmpp = session->securityPrivKey;
00427 if (!snmp_hex_to_binary(&tmpp, &bufSize,
00428 &session->securityPrivKeyLen, 0, optarg)) {
00429 fprintf(stderr, "Bad key value after -3M flag.\n");
00430 return (-1);
00431 }
00432 break;
00433 }
00434
00435 case 'k': {
00436 size_t kbuf_len = 32, kout_len = 0;
00437 u_char *kbuf = (u_char *) malloc(kbuf_len);
00438
00439 if (kbuf == NULL) {
00440 fprintf(stderr, "malloc failure processing -3k flag.\n");
00441 return (-1);
00442 }
00443 if (!snmp_hex_to_binary
00444 (&kbuf, &kbuf_len, &kout_len, 1, optarg)) {
00445 fprintf(stderr, "Bad key value after -3k flag.\n");
00446 SNMP_FREE(kbuf);
00447 return (-1);
00448 }
00449 session->securityAuthLocalKey = kbuf;
00450 session->securityAuthLocalKeyLen = kout_len;
00451 break;
00452 }
00453
00454 case 'K': {
00455 size_t kbuf_len = 32, kout_len = 0;
00456 u_char *kbuf = (u_char *) malloc(kbuf_len);
00457
00458 if (kbuf == NULL) {
00459 fprintf(stderr, "malloc failure processing -3K flag.\n");
00460 return (-1);
00461 }
00462 if (!snmp_hex_to_binary
00463 (&kbuf, &kbuf_len, &kout_len, 1, optarg)) {
00464 fprintf(stderr, "Bad key value after -3K flag.\n");
00465 SNMP_FREE(kbuf);
00466 return (-1);
00467 }
00468 session->securityPrivLocalKey = kbuf;
00469 session->securityPrivLocalKeyLen = kout_len;
00470 break;
00471 }
00472
00473 default:
00474 fprintf(stderr, "Unknown SNMPv3 option passed to -3: %c.\n", *cp);
00475 return -1;
00476 }
00477 return 0;
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 int
00506 setup_engineID(u_char ** eidp, const char *text)
00507 {
00508 int enterpriseid = htonl(ENTERPRISE_OID),
00509 netsnmpoid = htonl(NETSNMP_OID),
00510 localsetup = (eidp) ? 0 : 1;
00511
00512
00513
00514
00515 #ifdef HAVE_GETHOSTNAME
00516 u_char buf[SNMP_MAXBUF_SMALL];
00517 struct hostent *hent = NULL;
00518 #endif
00519 u_char *bufp = NULL;
00520 size_t len;
00521 int localEngineIDType = engineIDType;
00522 int tmpint;
00523 time_t tmptime;
00524
00525 engineIDIsSet = 1;
00526
00527 #ifdef HAVE_GETHOSTNAME
00528 #ifdef AF_INET6
00529
00530
00531
00532 if ((ENGINEID_TYPE_IPV6 == localEngineIDType) ||
00533 (ENGINEID_TYPE_IPV4 == localEngineIDType)) {
00534
00535
00536
00537 gethostname((char *) buf, sizeof(buf));
00538 hent = gethostbyname((char *) buf);
00539 if (hent && hent->h_addrtype == AF_INET6) {
00540 localEngineIDType = ENGINEID_TYPE_IPV6;
00541 } else {
00542
00543
00544
00545 localEngineIDType = ENGINEID_TYPE_IPV4;
00546 }
00547 }
00548 #else
00549
00550
00551
00552
00553 if (ENGINEID_TYPE_IPV6 == localEngineIDType) {
00554 localEngineIDType = ENGINEID_TYPE_IPV4;
00555 }
00556 if (ENGINEID_TYPE_IPV4 == localEngineIDType) {
00557
00558
00559
00560 gethostname((char *) buf, sizeof(buf));
00561 hent = gethostbyname((char *) buf);
00562 }
00563 #endif
00564 #endif
00565
00566
00567
00568
00569
00570 if (NULL != text) {
00571 engineIDType = localEngineIDType = ENGINEID_TYPE_TEXT;
00572 }
00573
00574
00575
00576 len = 5;
00577 switch (localEngineIDType) {
00578 case ENGINEID_TYPE_TEXT:
00579 if (NULL == text) {
00580 snmp_log(LOG_ERR,
00581 "Can't set up engineID of type text from an empty string.\n");
00582 return -1;
00583 }
00584 len += strlen(text);
00585 break;
00586 #if defined(IFHWADDRLEN) && defined(SIOCGIFHWADDR)
00587 case ENGINEID_TYPE_MACADDR:
00588 len += 6;
00589 break;
00590 #endif
00591 case ENGINEID_TYPE_IPV4:
00592 len += 4;
00593 break;
00594 case ENGINEID_TYPE_IPV6:
00595 len += 16;
00596 break;
00597 case ENGINEID_TYPE_NETSNMP_RND:
00598 if (engineID)
00599 return engineIDLength;
00600 if (oldEngineID) {
00601 len = oldEngineIDLength;
00602 } else {
00603 len += sizeof(int) + sizeof(time_t);
00604 }
00605 break;
00606 default:
00607 snmp_log(LOG_ERR,
00608 "Unknown EngineID type requested for setup (%d). Using IPv4.\n",
00609 localEngineIDType);
00610 localEngineIDType = ENGINEID_TYPE_IPV4;
00611 len += 4;
00612 break;
00613 }
00614
00615
00616
00617
00618
00619 if ((bufp = (u_char *) malloc(len)) == NULL) {
00620 snmp_log_perror("setup_engineID malloc");
00621 return -1;
00622 }
00623 if (localEngineIDType == ENGINEID_TYPE_NETSNMP_RND)
00624
00625
00626
00627 memcpy(bufp, &netsnmpoid, sizeof(netsnmpoid));
00628 else
00629 memcpy(bufp, &enterpriseid, sizeof(enterpriseid));
00630
00631 bufp[0] |= 0x80;
00632
00633
00634
00635
00636
00637
00638
00639 switch (localEngineIDType) {
00640 case ENGINEID_TYPE_NETSNMP_RND:
00641 if (oldEngineID) {
00642
00643
00644
00645 memcpy(bufp, oldEngineID, oldEngineIDLength);
00646 } else {
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 bufp[4] = ENGINEID_TYPE_NETSNMP_RND;
00659 tmpint = random();
00660 memcpy(bufp + 5, &tmpint, sizeof(tmpint));
00661 tmptime = time(NULL);
00662 memcpy(bufp + 5 + sizeof(tmpint), &tmptime, sizeof(tmptime));
00663 }
00664 break;
00665 case ENGINEID_TYPE_TEXT:
00666 bufp[4] = ENGINEID_TYPE_TEXT;
00667 memcpy((char *) bufp + 5, (text), strlen(text));
00668 break;
00669 #ifdef HAVE_GETHOSTNAME
00670 #ifdef AF_INET6
00671 case ENGINEID_TYPE_IPV6:
00672 bufp[4] = ENGINEID_TYPE_IPV6;
00673 memcpy(bufp + 5, hent->h_addr_list[0], hent->h_length);
00674 break;
00675 #endif
00676 #endif
00677 #if defined(IFHWADDRLEN) && defined(SIOCGIFHWADDR)
00678 case ENGINEID_TYPE_MACADDR:
00679 {
00680 int x;
00681 bufp[4] = ENGINEID_TYPE_MACADDR;
00682
00683
00684
00685 if (NULL == engineIDNic) {
00686 x = getHwAddress(DEFAULT_NIC, &bufp[5]);
00687 } else {
00688 x = getHwAddress(engineIDNic, &bufp[5]);
00689 }
00690 if (0 != x)
00691
00692
00693
00694 {
00695 memset(&bufp[5], 0, 6);
00696 }
00697 }
00698 break;
00699 #endif
00700 case ENGINEID_TYPE_IPV4:
00701 default:
00702 bufp[4] = ENGINEID_TYPE_IPV4;
00703 #ifdef HAVE_GETHOSTNAME
00704 if (hent && hent->h_addrtype == AF_INET) {
00705 memcpy(bufp + 5, hent->h_addr_list[0], hent->h_length);
00706 } else {
00707
00708 bufp[5] = 127;
00709 bufp[6] = 0;
00710 bufp[7] = 0;
00711 bufp[8] = 1;
00712 }
00713 #else
00714
00715
00716
00717 bufp[5] = 127;
00718 bufp[6] = 0;
00719 bufp[7] = 0;
00720 bufp[8] = 1;
00721 #endif
00722 break;
00723 }
00724
00725
00726
00727
00728
00729 if (localsetup) {
00730 SNMP_FREE(engineID);
00731 engineID = bufp;
00732 engineIDLength = len;
00733
00734 } else {
00735 *eidp = bufp;
00736 }
00737
00738
00739 return len;
00740
00741 }
00742
00743 int
00744 free_engineID(int majorid, int minorid, void *serverarg,
00745 void *clientarg)
00746 {
00747 SNMP_FREE(engineID);
00748 SNMP_FREE(engineIDNic);
00749 SNMP_FREE(oldEngineID);
00750 return 0;
00751 }
00752
00753 int
00754 free_enginetime_on_shutdown(int majorid, int minorid, void *serverarg,
00755 void *clientarg)
00756 {
00757 DEBUGMSGTL(("snmpv3", "free enginetime callback called\n"));
00758 if (engineID != NULL)
00759 free_enginetime(engineID, engineIDLength);
00760 return 0;
00761 }
00762
00763 void
00764 usm_parse_create_usmUser(const char *token, char *line)
00765 {
00766 char *cp;
00767 char buf[SNMP_MAXBUF_MEDIUM];
00768 struct usmUser *newuser;
00769 u_char userKey[SNMP_MAXBUF_SMALL], *tmpp;
00770 size_t userKeyLen = SNMP_MAXBUF_SMALL;
00771 size_t privKeyLen = 0;
00772 size_t ret;
00773 int ret2;
00774 int testcase;
00775
00776 newuser = usm_create_user();
00777
00778
00779
00780
00781 cp = copy_nword(line, buf, sizeof(buf));
00782
00783
00784
00785
00786 if (strcmp(buf, "-e") == 0) {
00787 size_t ebuf_len = 32, eout_len = 0;
00788 u_char *ebuf = (u_char *) malloc(ebuf_len);
00789
00790 if (ebuf == NULL) {
00791 config_perror("malloc failure processing -e flag");
00792 usm_free_user(newuser);
00793 return;
00794 }
00795
00796
00797
00798
00799 cp = copy_nword(cp, buf, sizeof(buf));
00800 if (!snmp_hex_to_binary(&ebuf, &ebuf_len, &eout_len, 1, buf)) {
00801 config_perror("invalid EngineID argument to -e");
00802 usm_free_user(newuser);
00803 SNMP_FREE(ebuf);
00804 return;
00805 }
00806
00807 newuser->engineID = ebuf;
00808 newuser->engineIDLen = eout_len;
00809 cp = copy_nword(cp, buf, sizeof(buf));
00810 } else {
00811 newuser->engineID = snmpv3_generate_engineID(&ret);
00812 if (ret == 0) {
00813 usm_free_user(newuser);
00814 return;
00815 }
00816 newuser->engineIDLen = ret;
00817 }
00818
00819 newuser->secName = strdup(buf);
00820 newuser->name = strdup(buf);
00821
00822 if (!cp)
00823 goto add;
00824
00825
00826
00827
00828 #ifndef DISABLE_MD5
00829 if (strncmp(cp, "MD5", 3) == 0) {
00830 memcpy(newuser->authProtocol, usmHMACMD5AuthProtocol,
00831 sizeof(usmHMACMD5AuthProtocol));
00832 } else
00833 #endif
00834 if (strncmp(cp, "SHA", 3) == 0) {
00835 memcpy(newuser->authProtocol, usmHMACSHA1AuthProtocol,
00836 sizeof(usmHMACSHA1AuthProtocol));
00837 } else {
00838 config_perror("Unknown authentication protocol");
00839 usm_free_user(newuser);
00840 return;
00841 }
00842
00843 cp = skip_token(cp);
00844
00845
00846
00847
00848 if (!cp) {
00849 config_perror("no authentication pass phrase");
00850 usm_free_user(newuser);
00851 return;
00852 }
00853 cp = copy_nword(cp, buf, sizeof(buf));
00854 if (strcmp(buf,"-m") == 0) {
00855
00856 cp = copy_nword(cp, buf, sizeof(buf));
00857 ret = sizeof(userKey);
00858 tmpp = userKey;
00859 userKeyLen = 0;
00860 if (!snmp_hex_to_binary(&tmpp, &ret, &userKeyLen, 0, buf)) {
00861 config_perror("invalid key value argument to -m");
00862 usm_free_user(newuser);
00863 return;
00864 }
00865 } else if (strcmp(buf,"-l") != 0) {
00866
00867 userKeyLen = sizeof(userKey);
00868 ret2 = generate_Ku(newuser->authProtocol, newuser->authProtocolLen,
00869 (u_char *) buf, strlen(buf), userKey, &userKeyLen);
00870 if (ret2 != SNMPERR_SUCCESS) {
00871 config_perror("could not generate the authentication key from the "
00872 "supplied pass phrase.");
00873 usm_free_user(newuser);
00874 return;
00875 }
00876 }
00877
00878
00879
00880
00881 ret2 = sc_get_properlength(newuser->authProtocol,
00882 newuser->authProtocolLen);
00883 if (ret2 <= 0) {
00884 config_perror("Could not get proper authentication protocol key length");
00885 return;
00886 }
00887 newuser->authKey = (u_char *) malloc(ret2);
00888
00889 if (strcmp(buf,"-l") == 0) {
00890
00891 cp = copy_nword(cp, buf, sizeof(buf));
00892 newuser->authKeyLen = 0;
00893 ret = ret2;
00894 if (!snmp_hex_to_binary(&newuser->authKey, &ret,
00895 &newuser->authKeyLen, 0, buf)) {
00896 config_perror("invalid key value argument to -l");
00897 usm_free_user(newuser);
00898 return;
00899 }
00900 if (ret != newuser->authKeyLen) {
00901 config_perror("improper key length to -l");
00902 usm_free_user(newuser);
00903 return;
00904 }
00905 } else {
00906 newuser->authKeyLen = ret2;
00907 ret2 = generate_kul(newuser->authProtocol, newuser->authProtocolLen,
00908 newuser->engineID, newuser->engineIDLen,
00909 userKey, userKeyLen,
00910 newuser->authKey, &newuser->authKeyLen);
00911 if (ret2 != SNMPERR_SUCCESS) {
00912 config_perror("could not generate localized authentication key "
00913 "(Kul) from the master key (Ku).");
00914 usm_free_user(newuser);
00915 return;
00916 }
00917 }
00918
00919 if (!cp)
00920 goto add;
00921
00922
00923
00924
00925 testcase = 0;
00926 #ifndef DISABLE_DES
00927 if (strncmp(cp, "DES", 3) == 0) {
00928 memcpy(newuser->privProtocol, usmDESPrivProtocol,
00929 sizeof(usmDESPrivProtocol));
00930 testcase = 1;
00931
00932 privKeyLen = 16;
00933 }
00934 #endif
00935 #ifdef HAVE_AES
00936 if (strncmp(cp, "AES128", 6) == 0 ||
00937 strncmp(cp, "AES", 3) == 0) {
00938 memcpy(newuser->privProtocol, usmAESPrivProtocol,
00939 sizeof(usmAESPrivProtocol));
00940 testcase = 1;
00941 privKeyLen = 16;
00942 }
00943 #endif
00944 if (testcase == 0) {
00945 config_perror("Unknown privacy protocol");
00946 usm_free_user(newuser);
00947 return;
00948 }
00949
00950 cp = skip_token(cp);
00951
00952
00953
00954 if (!cp) {
00955
00956
00957
00958 memdup(&newuser->privKey, newuser->authKey, newuser->authKeyLen);
00959 newuser->privKeyLen = newuser->authKeyLen;
00960 } else {
00961 cp = copy_nword(cp, buf, sizeof(buf));
00962
00963 if (strcmp(buf,"-m") == 0) {
00964
00965 cp = copy_nword(cp, buf, sizeof(buf));
00966 ret = sizeof(userKey);
00967 tmpp = userKey;
00968 userKeyLen = 0;
00969 if (!snmp_hex_to_binary(&tmpp, &ret, &userKeyLen, 0, buf)) {
00970 config_perror("invalid key value argument to -m");
00971 usm_free_user(newuser);
00972 return;
00973 }
00974 } else if (strcmp(buf,"-l") != 0) {
00975
00976 userKeyLen = sizeof(userKey);
00977 ret2 = generate_Ku(newuser->authProtocol, newuser->authProtocolLen,
00978 (u_char *) buf, strlen(buf), userKey, &userKeyLen);
00979 if (ret2 != SNMPERR_SUCCESS) {
00980 config_perror("could not generate the privacy key from the "
00981 "supplied pass phrase.");
00982 usm_free_user(newuser);
00983 return;
00984 }
00985 }
00986
00987
00988
00989
00990 ret2 = sc_get_properlength(newuser->authProtocol,
00991 newuser->authProtocolLen);
00992 if (ret2 < 0) {
00993 config_perror("could not get proper key length to use for the "
00994 "privacy algorithm.");
00995 usm_free_user(newuser);
00996 return;
00997 }
00998 newuser->privKey = (u_char *) malloc(ret2);
00999
01000 if (strcmp(buf,"-l") == 0) {
01001
01002 cp = copy_nword(cp, buf, sizeof(buf));
01003 ret = ret2;
01004 newuser->privKeyLen = 0;
01005 if (!snmp_hex_to_binary(&newuser->privKey, &ret,
01006 &newuser->privKeyLen, 0, buf)) {
01007 config_perror("invalid key value argument to -l");
01008 usm_free_user(newuser);
01009 return;
01010 }
01011 } else {
01012 newuser->privKeyLen = ret2;
01013 ret2 = generate_kul(newuser->authProtocol, newuser->authProtocolLen,
01014 newuser->engineID, newuser->engineIDLen,
01015 userKey, userKeyLen,
01016 newuser->privKey, &newuser->privKeyLen);
01017 if (ret2 != SNMPERR_SUCCESS) {
01018 config_perror("could not generate localized privacy key "
01019 "(Kul) from the master key (Ku).");
01020 usm_free_user(newuser);
01021 return;
01022 }
01023 }
01024 }
01025
01026 if ((newuser->privKeyLen >= privKeyLen) || (privKeyLen == 0)){
01027 newuser->privKeyLen = privKeyLen;
01028 }
01029 else {
01030
01031 usm_free_user(newuser);
01032 return;
01033 }
01034
01035 add:
01036 usm_add_user(newuser);
01037 DEBUGMSGTL(("usmUser", "created a new user %s at ", newuser->secName));
01038 DEBUGMSGHEX(("usmUser", newuser->engineID, newuser->engineIDLen));
01039 DEBUGMSG(("usmUser", "\n"));
01040 }
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052 void
01053 engineBoots_conf(const char *word, char *cptr)
01054 {
01055 engineBoots = atoi(cptr) + 1;
01056 DEBUGMSGTL(("snmpv3", "engineBoots: %d\n", engineBoots));
01057 }
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073 void
01074 engineIDType_conf(const char *word, char *cptr)
01075 {
01076 engineIDType = atoi(cptr);
01077
01078
01079
01080 switch (engineIDType) {
01081 case ENGINEID_TYPE_IPV4:
01082 case ENGINEID_TYPE_IPV6:
01083
01084
01085
01086 break;
01087 #if defined(IFHWADDRLEN) && defined(SIOCGIFHWADDR)
01088 case ENGINEID_TYPE_MACADDR:
01089 break;
01090 #endif
01091 default:
01092
01093
01094
01095 config_perror("Unsupported enginedIDType, forcing IPv4");
01096 engineIDType = ENGINEID_TYPE_IPV4;
01097 }
01098 DEBUGMSGTL(("snmpv3", "engineIDType: %d\n", engineIDType));
01099 }
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112 void
01113 engineIDNic_conf(const char *word, char *cptr)
01114 {
01115
01116
01117
01118
01119 if (0 == engineIDIsSet)
01120
01121
01122
01123 {
01124
01125
01126
01127 if (NULL != engineIDNic) {
01128 SNMP_FREE(engineIDNic);
01129 }
01130 engineIDNic = (u_char *) malloc(strlen(cptr) + 1);
01131 if (NULL != engineIDNic) {
01132 strcpy((char *) engineIDNic, cptr);
01133 DEBUGMSGTL(("snmpv3", "Initializing engineIDNic: %s\n",
01134 engineIDNic));
01135 } else {
01136 DEBUGMSGTL(("snmpv3",
01137 "Error allocating memory for engineIDNic!\n"));
01138 }
01139 } else {
01140 DEBUGMSGTL(("snmpv3",
01141 "NOT setting engineIDNic, engineID already set\n"));
01142 }
01143 }
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155 void
01156 engineID_conf(const char *word, char *cptr)
01157 {
01158 setup_engineID(NULL, cptr);
01159 DEBUGMSGTL(("snmpv3", "initialized engineID with: %s\n", cptr));
01160 }
01161
01162 void
01163 version_conf(const char *word, char *cptr)
01164 {
01165 int valid = 0;
01166 #ifndef DISABLE_SNMPV1
01167 if ((strcmp(cptr, "1") == 0) ||
01168 (strcmp(cptr, "v1") == 0)) {
01169 netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SNMPVERSION,
01170 NETSNMP_DS_SNMP_VERSION_1);
01171 valid = 1;
01172 }
01173 #endif
01174 #ifndef DISABLE_SNMPV2C
01175 if ((strcasecmp(cptr, "2c") == 0) ||
01176 (strcasecmp(cptr, "v2c") == 0)) {
01177 netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SNMPVERSION,
01178 NETSNMP_DS_SNMP_VERSION_2c);
01179 valid = 1;
01180 }
01181 #endif
01182 if ((strcasecmp(cptr, "3" ) == 0) ||
01183 (strcasecmp(cptr, "v3" ) == 0)) {
01184 netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SNMPVERSION,
01185 NETSNMP_DS_SNMP_VERSION_3);
01186 valid = 1;
01187 }
01188 if (!valid) {
01189 config_perror("Unknown version specification");
01190 return;
01191 }
01192 DEBUGMSGTL(("snmpv3", "set default version to %d\n",
01193 netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
01194 NETSNMP_DS_LIB_SNMPVERSION)));
01195 }
01196
01197
01198
01199
01200
01201
01202
01203 void
01204 oldengineID_conf(const char *word, char *cptr)
01205 {
01206 read_config_read_octet_string(cptr, &oldEngineID, &oldEngineIDLength);
01207 }
01208
01209
01210
01211
01212 void
01213 get_enginetime_alarm(unsigned int regnum, void *clientargs)
01214 {
01215
01216
01217 snmpv3_local_snmpEngineTime();
01218 }
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230 void
01231 init_snmpv3(const char *type)
01232 {
01233 #if SNMP_USE_TIMES
01234 struct tms dummy;
01235
01236
01237 snmpv3startClock = times(&dummy);
01238
01239
01240
01241 clockticks = sysconf(_SC_CLK_TCK);
01242
01243 #endif
01244
01245 gettimeofday(&snmpv3starttime, NULL);
01246
01247 if (!type)
01248 type = "__snmpapp__";
01249
01250
01251
01252
01253 snmp_register_callback(SNMP_CALLBACK_LIBRARY,
01254 SNMP_CALLBACK_POST_READ_CONFIG,
01255 init_snmpv3_post_config, NULL);
01256
01257 snmp_register_callback(SNMP_CALLBACK_LIBRARY,
01258 SNMP_CALLBACK_POST_PREMIB_READ_CONFIG,
01259 init_snmpv3_post_premib_config, NULL);
01260
01261
01262
01263 snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
01264 snmpv3_store, (void *) strdup(type));
01265
01266
01267
01268
01269 snmp_register_callback(SNMP_CALLBACK_LIBRARY,
01270 SNMP_CALLBACK_SHUTDOWN,
01271 free_enginetime_on_shutdown, NULL);
01272
01273
01274
01275
01276
01277
01278
01279
01280 init_secmod();
01281
01282
01283
01284
01285
01286
01287
01288
01289 register_prenetsnmp_mib_handler(type, "engineID", engineID_conf, NULL,
01290 "string");
01291 register_prenetsnmp_mib_handler(type, "oldEngineID", oldengineID_conf,
01292 NULL, NULL);
01293 register_prenetsnmp_mib_handler(type, "engineIDType",
01294 engineIDType_conf, NULL, "num");
01295 register_prenetsnmp_mib_handler(type, "engineIDNic", engineIDNic_conf,
01296 NULL, "string");
01297 register_config_handler(type, "engineBoots", engineBoots_conf, NULL,
01298 NULL);
01299
01300
01301
01302
01303 netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "defSecurityName",
01304 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_SECNAME);
01305 netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "defContext",
01306 NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_CONTEXT);
01307 netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "defPassphrase",
01308 NETSNMP_DS_LIBRARY_ID,
01309 NETSNMP_DS_LIB_PASSPHRASE);
01310 netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "defAuthPassphrase",
01311 NETSNMP_DS_LIBRARY_ID,
01312 NETSNMP_DS_LIB_AUTHPASSPHRASE);
01313 netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "defPrivPassphrase",
01314 NETSNMP_DS_LIBRARY_ID,
01315 NETSNMP_DS_LIB_PRIVPASSPHRASE);
01316 netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "defAuthMasterKey",
01317 NETSNMP_DS_LIBRARY_ID,
01318 NETSNMP_DS_LIB_AUTHMASTERKEY);
01319 netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "defPrivMasterKey",
01320 NETSNMP_DS_LIBRARY_ID,
01321 NETSNMP_DS_LIB_PRIVMASTERKEY);
01322 netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "defAuthLocalizedKey",
01323 NETSNMP_DS_LIBRARY_ID,
01324 NETSNMP_DS_LIB_AUTHLOCALIZEDKEY);
01325 netsnmp_ds_register_config(ASN_OCTET_STR, "snmp", "defPrivLocalizedKey",
01326 NETSNMP_DS_LIBRARY_ID,
01327 NETSNMP_DS_LIB_PRIVLOCALIZEDKEY);
01328 register_config_handler("snmp", "defVersion", version_conf, NULL,
01329 "1|2c|3");
01330
01331 register_config_handler("snmp", "defAuthType", snmpv3_authtype_conf,
01332 NULL, "MD5|SHA");
01333 register_config_handler("snmp", "defPrivType", snmpv3_privtype_conf,
01334 NULL,
01335 #ifdef HAVE_AES
01336 "DES|AES");
01337 #else
01338 "DES (AES support not available)");
01339 #endif
01340 register_config_handler("snmp", "defSecurityLevel",
01341 snmpv3_secLevel_conf, NULL,
01342 "noAuthNoPriv|authNoPriv|authPriv");
01343 register_config_handler(type, "userSetAuthPass", usm_set_password,
01344 NULL, NULL);
01345 register_config_handler(type, "userSetPrivPass", usm_set_password,
01346 NULL, NULL);
01347 register_config_handler(type, "userSetAuthKey", usm_set_password, NULL,
01348 NULL);
01349 register_config_handler(type, "userSetPrivKey", usm_set_password, NULL,
01350 NULL);
01351 register_config_handler(type, "userSetAuthLocalKey", usm_set_password,
01352 NULL, NULL);
01353 register_config_handler(type, "userSetPrivLocalKey", usm_set_password,
01354 NULL, NULL);
01355 }
01356
01357
01358
01359
01360
01361
01362 int
01363 init_snmpv3_post_config(int majorid, int minorid, void *serverarg,
01364 void *clientarg)
01365 {
01366
01367 size_t engineIDLen;
01368 u_char *c_engineID;
01369
01370 c_engineID = snmpv3_generate_engineID(&engineIDLen);
01371
01372 if (engineIDLen == 0 || !c_engineID) {
01373
01374
01375
01376 SNMP_FREE(c_engineID);
01377 return SNMPERR_GENERR;
01378 }
01379
01380
01381
01382
01383 if (engineIDLen != (int) oldEngineIDLength ||
01384 oldEngineID == NULL || c_engineID == NULL ||
01385 memcmp(oldEngineID, c_engineID, engineIDLen) != 0) {
01386 engineBoots = 1;
01387 }
01388
01389
01390
01391
01392 set_enginetime(c_engineID, engineIDLen,
01393 snmpv3_local_snmpEngineBoots(),
01394 snmpv3_local_snmpEngineTime(), TRUE);
01395
01396 SNMP_FREE(c_engineID);
01397 return SNMPERR_SUCCESS;
01398 }
01399
01400 int
01401 init_snmpv3_post_premib_config(int majorid, int minorid, void *serverarg,
01402 void *clientarg)
01403 {
01404 if (!engineIDIsSet)
01405 setup_engineID(NULL, NULL);
01406
01407 return SNMPERR_SUCCESS;
01408 }
01409
01410
01411
01412
01413
01414
01415
01416 int
01417 snmpv3_store(int majorID, int minorID, void *serverarg, void *clientarg)
01418 {
01419 char line[SNMP_MAXBUF_SMALL];
01420 u_char c_engineID[SNMP_MAXBUF_SMALL];
01421 int engineIDLen;
01422 const char *type = (const char *) clientarg;
01423
01424 if (type == NULL)
01425 type = "unknown";
01426
01427 sprintf(line, "engineBoots %ld", engineBoots);
01428 read_config_store(type, line);
01429
01430 engineIDLen = snmpv3_get_engineID(c_engineID, SNMP_MAXBUF_SMALL);
01431
01432 if (engineIDLen) {
01433
01434
01435
01436 sprintf(line, "oldEngineID ");
01437 read_config_save_octet_string(line + strlen(line), c_engineID,
01438 engineIDLen);
01439 read_config_store(type, line);
01440 }
01441 return SNMPERR_SUCCESS;
01442 }
01443
01444 u_long
01445 snmpv3_local_snmpEngineBoots(void)
01446 {
01447 return engineBoots;
01448 }
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466 size_t
01467 snmpv3_get_engineID(u_char * buf, size_t buflen)
01468 {
01469
01470
01471
01472 if (!buf || (buflen < engineIDLength)) {
01473 return 0;
01474 }
01475
01476 memcpy(buf, engineID, engineIDLength);
01477 return engineIDLength;
01478
01479 }
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498 int
01499 snmpv3_clone_engineID(u_char ** dest, size_t * destlen, u_char * src,
01500 size_t srclen)
01501 {
01502 if (!dest || !destlen)
01503 return 0;
01504
01505 if (*dest) {
01506 SNMP_FREE(*dest);
01507 *dest = NULL;
01508 }
01509 *destlen = 0;
01510
01511 if (srclen && src) {
01512 *dest = (u_char *) malloc(srclen);
01513 if (*dest == NULL)
01514 return 0;
01515 memmove(*dest, src, srclen);
01516 *destlen = srclen;
01517 }
01518 return *destlen;
01519 }
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537 u_char *
01538 snmpv3_generate_engineID(size_t * length)
01539 {
01540 u_char *newID;
01541 newID = (u_char *) malloc(engineIDLength);
01542
01543 if (newID) {
01544 *length = snmpv3_get_engineID(newID, engineIDLength);
01545 }
01546
01547 if (*length == 0) {
01548 SNMP_FREE(newID);
01549 newID = NULL;
01550 }
01551
01552 return newID;
01553
01554 }
01555
01556
01557
01558
01559
01560 u_long
01561 snmpv3_local_snmpEngineTime(void)
01562 {
01563 #ifdef SNMP_USE_TIMES
01564 struct tms dummy;
01565 clock_t now = times(&dummy);
01566
01567 unsigned int result;
01568
01569 if (now < snmpv3startClock) {
01570 result = UINT_MAX - (snmpv3startClock - now);
01571 } else {
01572 result = now - snmpv3startClock;
01573 }
01574 if (result < lastcalltime) {
01575
01576 wrapcounter++;
01577 }
01578 lastcalltime = result;
01579 result = (UINT_MAX/clockticks)*wrapcounter + result/clockticks;
01580
01581 return result;
01582 #else
01583 struct timeval now;
01584
01585 gettimeofday(&now, NULL);
01586 return calculate_sectime_diff(&now, &snmpv3starttime);
01587 #endif
01588 }
01589
01590
01591
01592
01593
01594
01595 #if defined(IFHWADDRLEN) && defined(SIOCGIFHWADDR)
01596 static int
01597 getHwAddress(const char *networkDevice,
01598 char *addressOut)
01599 {
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621 int sock;
01622 struct ifreq request;
01623
01624 if ((NULL == networkDevice) || (NULL == addressOut)) {
01625 return -1;
01626 }
01627
01628
01629
01630
01631
01632
01633 sock = socket(AF_INET, SOCK_DGRAM, 0);
01634 if (sock < 0) {
01635 return -1;
01636 }
01637
01638
01639
01640 memset(&request, 0, sizeof(request));
01641
01642
01643
01644 strncpy(request.ifr_name, networkDevice, IFNAMSIZ - 1);
01645
01646
01647
01648 if (ioctl(sock, SIOCGIFHWADDR, &request)) {
01649 close(sock);
01650 return -1;
01651 }
01652 close(sock);
01653 memcpy(addressOut, request.ifr_hwaddr.sa_data, IFHWADDRLEN);
01654 return 0;
01655 }
01656 #endif
01657
01658 #ifdef SNMP_TESTING_CODE
01659
01660
01661
01662
01663
01664
01665
01666 void
01667 snmpv3_set_engineBootsAndTime(int boots, int ttime)
01668 {
01669 engineBoots = boots;
01670 gettimeofday(&snmpv3starttime, NULL);
01671 snmpv3starttime.tv_sec -= ttime;
01672 }
01673 #endif