1/* 2 * Copyright (c) 2001-2003 3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus). 4 * All rights reserved. 5 * 6 * Author: Harti Brandt <harti@freebsd.org> 7 * 8 * Redistribution and use in source and binary forms, with or without --- 91 unchanged lines hidden (view full) --- 100uint64_t mibarpticks; 101 102/* info on system clocks */ 103struct clockinfo clockinfo; 104 105/* list of all New if registrations */ 106static struct newifreg_list newifreg_list = TAILQ_HEAD_INITIALIZER(newifreg_list); 107 |
108/* baud rate of fastest interface */ 109uint64_t mibif_maxspeed; 110 111/* user-forced update interval */ 112u_int mibif_force_hc_update_interval; 113 114/* current update interval */ 115u_int mibif_hc_update_interval; 116 117/* HC update timer handle */ 118static void *hc_update_timer; 119 |
120/*****************************/ 121 122static const struct asn_oid oid_ifMIB = OIDX_ifMIB; 123static const struct asn_oid oid_ipMIB = OIDX_ipMIB; 124static const struct asn_oid oid_tcpMIB = OIDX_tcpMIB; 125static const struct asn_oid oid_udpMIB = OIDX_udpMIB; 126static const struct asn_oid oid_ipForward = OIDX_ipForward; 127static const struct asn_oid oid_linkDown = OIDX_linkDown; --- 159 unchanged lines hidden (view full) --- 287 ifindex.var.subs[ifindex.var.len++] = ifp->index; 288 ifindex.syntax = SNMP_SYNTAX_INTEGER; 289 ifindex.v.integer = ifp->index; 290 291 snmp_send_trap(up ? &oid_linkUp : &oid_linkDown, &ifindex, 292 (struct snmp_value *)NULL); 293} 294 |
295/** 296 * Fetch the GENERIC IFMIB and update the HC counters |
297 */ |
298static int 299fetch_generic_mib(struct mibif *ifp, const struct ifmibdata *old) |
300{ 301 int name[6]; 302 size_t len; |
303 struct mibif_private *p = ifp->private; |
304 305 name[0] = CTL_NET; 306 name[1] = PF_LINK; 307 name[2] = NETLINK_GENERIC; 308 name[3] = IFMIB_IFDATA; 309 name[4] = ifp->sysindex; 310 name[5] = IFDATA_GENERAL; 311 312 len = sizeof(ifp->mib); 313 if (sysctl(name, 6, &ifp->mib, &len, NULL, 0) == -1) { 314 if (errno != ENOENT) 315 syslog(LOG_WARNING, "sysctl(ifmib, %s) failed %m", 316 ifp->name); 317 return (-1); 318 } 319 320 /* |
321 * Assume that one of the two following compounds is optimized away 322 */ 323 if (ULONG_MAX >= 0xffffffffffffffffULL) { 324 p->hc_inoctets = ifp->mib.ifmd_data.ifi_ibytes; 325 p->hc_outoctets = ifp->mib.ifmd_data.ifi_obytes; 326 p->hc_omcasts = ifp->mib.ifmd_data.ifi_omcasts; 327 p->hc_opackets = ifp->mib.ifmd_data.ifi_opackets; 328 p->hc_imcasts = ifp->mib.ifmd_data.ifi_imcasts; 329 p->hc_ipackets = ifp->mib.ifmd_data.ifi_ipackets; 330 331 } else if (ULONG_MAX >= 0xffffffff) { 332 333#define UPDATE(HC, MIB) \ 334 if (old->ifmd_data.MIB > ifp->mib.ifmd_data.MIB) \ 335 p->HC += (0x100000000ULL + \ 336 ifp->mib.ifmd_data.MIB) - \ 337 old->ifmd_data.MIB; \ 338 else \ 339 p->HC += ifp->mib.ifmd_data.MIB - \ 340 old->ifmd_data.MIB; 341 342 UPDATE(hc_inoctets, ifi_ibytes) 343 UPDATE(hc_outoctets, ifi_obytes) 344 UPDATE(hc_omcasts, ifi_omcasts) 345 UPDATE(hc_opackets, ifi_opackets) 346 UPDATE(hc_imcasts, ifi_imcasts) 347 UPDATE(hc_ipackets, ifi_ipackets) 348 349#undef UPDATE 350 } else 351 abort(); 352 return (0); 353} 354 355/** 356 * Update the 64-bit interface counters 357 */ 358static void 359update_hc_counters(void *arg __unused) 360{ 361 struct mibif *ifp; 362 struct ifmibdata oldmib; 363 364 TAILQ_FOREACH(ifp, &mibif_list, link) { 365 oldmib = ifp->mib; 366 (void)fetch_generic_mib(ifp, &oldmib); 367 } 368} 369 370/** 371 * Recompute the poll timer for the HC counters 372 */ 373void 374mibif_reset_hc_timer(void) 375{ 376 u_int ticks; 377 378 if ((ticks = mibif_force_hc_update_interval) == 0) { 379 if (mibif_maxspeed <= 10000000) { 380 /* at 10Mbps overflow needs 3436 seconds */ 381 ticks = 3000 * 100; /* 50 minutes */ 382 } else if (mibif_maxspeed <= 100000000) { 383 /* at 100Mbps overflow needs 343 seconds */ 384 ticks = 300 * 100; /* 5 minutes */ 385 } else if (mibif_maxspeed < 650000000) { 386 /* at 622Mbps overflow needs 53 seconds */ 387 ticks = 40 * 100; /* 40 seconds */ 388 } else if (mibif_maxspeed <= 1000000000) { 389 /* at 1Gbps overflow needs 34 seconds */ 390 ticks = 20 * 100; /* 20 seconds */ 391 } else { 392 /* at 10Gbps overflow needs 3.4 seconds */ 393 ticks = 100; /* 1 seconds */ 394 } 395 } 396 397 if (ticks == mibif_hc_update_interval) 398 return; 399 400 if (hc_update_timer != NULL) { 401 timer_stop(hc_update_timer); 402 hc_update_timer = NULL; 403 } 404 update_hc_counters(NULL); 405 if ((hc_update_timer = timer_start_repeat(ticks * 10, ticks * 10, 406 update_hc_counters, NULL, module)) == NULL) { 407 syslog(LOG_ERR, "timer_start(%u): %m", ticks); 408 return; 409 } 410 mibif_hc_update_interval = ticks; 411} 412 413/* 414 * Fetch new MIB data. 415 */ 416int 417mib_fetch_ifmib(struct mibif *ifp) 418{ 419 int name[6]; 420 size_t len; 421 void *newmib; 422 struct ifmibdata oldmib = ifp->mib; 423 424 if (fetch_generic_mib(ifp, &oldmib) == -1) 425 return (-1); 426 427 /* |
428 * Quoting RFC2863, 3.1.15: "... LinkUp and linkDown traps are 429 * generated just after ifOperStatus leaves, or just before it 430 * enters, the down state, respectively;" 431 */ 432 if (ifp->trap_enable && ifp->mib.ifmd_data.ifi_link_state != 433 oldmib.ifmd_data.ifi_link_state && 434 (ifp->mib.ifmd_data.ifi_link_state == LINK_STATE_DOWN || 435 oldmib.ifmd_data.ifi_link_state == LINK_STATE_DOWN)) 436 link_trap(ifp, ifp->mib.ifmd_data.ifi_link_state == 437 LINK_STATE_UP ? 1 : 0); 438 439 ifp->flags &= ~(MIBIF_HIGHSPEED | MIBIF_VERYHIGHSPEED); 440 if (ifp->mib.ifmd_data.ifi_baudrate > 20000000) { 441 ifp->flags |= MIBIF_HIGHSPEED; 442 if (ifp->mib.ifmd_data.ifi_baudrate > 650000000) 443 ifp->flags |= MIBIF_VERYHIGHSPEED; 444 } |
445 if (ifp->mib.ifmd_data.ifi_baudrate > mibif_maxspeed) { 446 mibif_maxspeed = ifp->mib.ifmd_data.ifi_baudrate; 447 mibif_reset_hc_timer(); 448 } |
449 450 /* 451 * linkspecific MIB 452 */ |
453 name[0] = CTL_NET; 454 name[1] = PF_LINK; 455 name[2] = NETLINK_GENERIC; 456 name[3] = IFMIB_IFDATA; 457 name[4] = ifp->sysindex; |
458 name[5] = IFDATA_LINKSPECIFIC; 459 if (sysctl(name, 6, NULL, &len, NULL, 0) == -1) { 460 syslog(LOG_WARNING, "sysctl linkmib estimate (%s): %m", 461 ifp->name); 462 if (ifp->specmib != NULL) { 463 ifp->specmib = NULL; 464 ifp->specmiblen = 0; 465 } --- 175 unchanged lines hidden (view full) --- 641} 642 643/* 644 * Free an interface 645 */ 646static void 647mibif_free(struct mibif *ifp) 648{ |
649 struct mibif *ifp1; |
650 struct mibindexmap *map; 651 struct mibifa *ifa, *ifa1; 652 struct mibrcvaddr *rcv, *rcv1; 653 struct mibarp *at, *at1; 654 655 if (ifp->xnotify != NULL) 656 (*ifp->xnotify)(ifp, MIBIF_NOTIFY_DESTROY, ifp->xnotify_data); 657 658 (void)mib_ifstack_delete(ifp, NULL); 659 (void)mib_ifstack_delete(NULL, ifp); 660 661 TAILQ_REMOVE(&mibif_list, ifp, link); |
662 663 /* if this was the fastest interface - recompute this */ 664 if (ifp->mib.ifmd_data.ifi_baudrate == mibif_maxspeed) { 665 mibif_maxspeed = ifp->mib.ifmd_data.ifi_baudrate; 666 TAILQ_FOREACH(ifp1, &mibif_list, link) 667 if (ifp1->mib.ifmd_data.ifi_baudrate > mibif_maxspeed) 668 mibif_maxspeed = 669 ifp1->mib.ifmd_data.ifi_baudrate; 670 mibif_reset_hc_timer(); 671 } 672 673 free(ifp->private); |
674 if (ifp->physaddr != NULL) 675 free(ifp->physaddr); 676 if (ifp->specmib != NULL) 677 free(ifp->specmib); 678 679 STAILQ_FOREACH(map, &mibindexmap_list, link) 680 if (map->mibif == ifp) { 681 map->mibif = NULL; --- 42 unchanged lines hidden (view full) --- 724 struct mibif *ifp; 725 struct mibindexmap *map; 726 727 if ((ifp = malloc(sizeof(*ifp))) == NULL) { 728 syslog(LOG_WARNING, "%s: %m", __func__); 729 return (NULL); 730 } 731 memset(ifp, 0, sizeof(*ifp)); |
732 if ((ifp->private = malloc(sizeof(struct mibif_private))) == NULL) { 733 syslog(LOG_WARNING, "%s: %m", __func__); 734 free(ifp); 735 return (NULL); 736 } 737 memset(ifp->private, 0, sizeof(struct mibif_private)); 738 |
739 ifp->sysindex = sysindex; 740 strcpy(ifp->name, name); 741 strcpy(ifp->descr, name); 742 ifp->spec_oid = oid_zeroDotZero; 743 744 map = NULL; 745 if (!mib_if_is_dyn(ifp->name)) { 746 /* non-dynamic. look whether we know the interface */ --- 1043 unchanged lines hidden --- |