~ubuntu-branches/ubuntu/trusty/ntop/trusty

« back to all changes in this revision

Viewing changes to hash.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2008-06-15 14:38:28 UTC
  • mfrom: (2.1.11 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080615143828-oalh84nda2hje4do
Tags: 3:3.3-11
Correction of Polish translation encoding, closes: #479490. Thanks
to Christian Perrier <bubulle@debian.org> for the help.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 *  Copyright (C) 1998-2005 Luca Deri <deri@ntop.org>
 
2
 *  Copyright (C) 1998-2007 Luca Deri <deri@ntop.org>
3
3
 *
4
4
 *                          http://www.ntop.org/
5
5
 *
51
51
 
52
52
  if(((*useIPAddressForSearching) == 1) || ((ether_addr == NULL) && (hostIpAddress != NULL))) {
53
53
    if(myGlobals.runningPref.trackOnlyLocalHosts
54
 
       && (!isLocalAddress(hostIpAddress, actualDeviceId))
55
 
       && (!_pseudoLocalAddress(hostIpAddress))) {
 
54
       && (!isLocalAddress(hostIpAddress, actualDeviceId, NULL, NULL))
 
55
       && (!_pseudoLocalAddress(hostIpAddress, NULL, NULL))) {
56
56
      *el = myGlobals.otherHostEntry;
57
57
      return(OTHER_HOSTS_ENTRY);
58
58
    } else {
73
73
  } else if(hostIpAddress == NULL) {
74
74
    memcpy(&idx, &ether_addr[LEN_ETHERNET_ADDRESS-sizeof(u_int)], sizeof(u_int));
75
75
    (*useIPAddressForSearching) = 0;
76
 
  } else if(isBroadcastAddress(hostIpAddress)) {
 
76
  } else if(isBroadcastAddress(hostIpAddress, NULL, NULL)) {
77
77
    *el = myGlobals.broadcastEntry;
78
78
    return(BROADCAST_HOSTS_ENTRY);
79
 
  } else if(isPseudoLocalAddress(hostIpAddress, actualDeviceId)) {
 
79
  } else if(isPseudoLocalAddress(hostIpAddress, actualDeviceId, NULL, NULL)) {
80
80
    memcpy(&idx, &ether_addr[LEN_ETHERNET_ADDRESS-sizeof(u_int)], sizeof(u_int));
81
81
    (*useIPAddressForSearching) = 0;
82
82
  } else {
83
83
    if(hostIpAddress != NULL) {
84
84
      if(myGlobals.runningPref.trackOnlyLocalHosts
85
 
         && (!isPseudoLocalAddress(hostIpAddress, actualDeviceId))) {
 
85
         && (!isPseudoLocalAddress(hostIpAddress, actualDeviceId, NULL, NULL))) {
86
86
        *el = myGlobals.otherHostEntry;
87
87
        return(OTHER_HOSTS_ENTRY);
88
88
      } else {
113
113
 
114
114
/* ************************************ */
115
115
 
116
 
u_int hashFcHost (FcAddress *fcaddr, u_short vsanId, HostTraffic **el,
117
 
                  int actualDeviceId)
 
116
u_int hashFcHost(FcAddress *fcaddr, u_short vsanId, HostTraffic **el,
 
117
                 int actualDeviceId)
118
118
{
119
119
  u_int idx = 0;
120
120
 
277
277
    return;
278
278
  }
279
279
 
280
 
  if(host->magic != CONST_MAGIC_NUMBER) {
 
280
  if((host->magic != CONST_MAGIC_NUMBER) && (host->magic != CONST_UNMAGIC_NUMBER)) {
281
281
    traceEvent(CONST_TRACE_ERROR, "Bad magic number (expected=%d/real=%d) freeHostInfo()",
282
282
               CONST_MAGIC_NUMBER, host->magic);
283
283
    return;
313
313
    else
314
314
      key_data.dsize = 0;
315
315
 
316
 
    if(key_data.dsize) {
 
316
    if(key_data.dsize && (key_data.dptr != NULL)) {
317
317
      gdbm_delete(myGlobals.addressQueueFile, key_data);
318
318
 
319
319
#ifdef DNS_DEBUG
473
473
  host->dnsTLDValue = NULL;
474
474
  if(host->description != NULL) free(host->description);
475
475
  if(host->hwModel != NULL) free(host->hwModel);
 
476
  if(host->community != NULL) free(host->community);
476
477
  if(host->ip2ccValue != NULL) free(host->ip2ccValue);
477
478
  host->ip2ccValue = NULL;
478
479
 
483
484
    #endif
484
485
  */
485
486
 
486
 
  /*
487
 
    Do not free the host pointer but add it to
488
 
    a list of 'ready to use' pointers.
489
 
 
490
 
    Memory Recycle
491
 
  */
492
 
 
493
 
#if RECYCLE_MEMORY
494
 
  if(myGlobals.hostsCacheLen < (MAX_HOSTS_CACHE_LEN-1)) {
495
 
    host->magic = 0;
496
 
    myGlobals.hostsCache[myGlobals.hostsCacheLen++] = host;
497
 
    if(myGlobals.hostsCacheLen > myGlobals.hostsCacheLenMax)
498
 
      myGlobals.hostsCacheLenMax = myGlobals.hostsCacheLen;
499
 
  } else
500
 
#endif
501
 
    {
502
 
      /* No room left: it's time to free the bucket */
503
 
      memset(host, 0, sizeof(HostTraffic)); /* Debug code */
504
 
      free(host);
505
 
    }
 
487
  memset(host, 0, sizeof(HostTraffic)); /* Debug code */
 
488
  free(host);
506
489
 
507
490
  myGlobals.numPurgedHosts++;
508
491
 
541
524
    for(idx=FIRST_HOSTS_ENTRY; idx<myGlobals.device[actualDeviceId].actualHashSize; idx++) {
542
525
      HostTraffic *el = myGlobals.device[actualDeviceId].hash_hostTraffic[idx];
543
526
 
 
527
    if(myGlobals.ntopRunState >= FLAG_NTOPSTATE_SHUTDOWN) break;
 
528
 
544
529
      while(el != NULL) {
545
530
        HostTraffic *nextEl = el->next;
546
531
        el->next = NULL;
563
548
 
564
549
/* ************************************ */
565
550
 
 
551
int is_host_ready_to_purge(int actDevice, HostTraffic *el, time_t now) {
 
552
  /* Time used to decide whether a host need to be purged */
 
553
  time_t noSessionPurgeTime   = now-PARM_HOST_PURGE_MINIMUM_IDLE_NOACTVSES;
 
554
  time_t withSessionPurgeTime = now-PARM_HOST_PURGE_MINIMUM_IDLE_ACTVSES;
 
555
  
 
556
  if(el->to_be_deleted
 
557
     || (
 
558
         (el->refCount == 0)
 
559
         && ((!myGlobals.runningPref.rFileName) 
 
560
             &&  (((el->numHostSessions == 0) && (el->lastSeen < noSessionPurgeTime))
 
561
                  || ((el->numHostSessions > 0)  && (el->lastSeen < withSessionPurgeTime))))
 
562
         && (!broadcastHost(el)) && (el != myGlobals.otherHostEntry)
 
563
         && (myGlobals.device[actDevice].virtualDevice /* e.g. sFlow/NetFlow */
 
564
             || (!myGlobals.runningPref.stickyHosts)
 
565
             || ((el->l2Family == FLAG_HOST_TRAFFIC_AF_ETH) &&
 
566
                 ((el->hostNumIpAddress[0] == '\0') /* Purge MAC addresses too */
 
567
                  || (!subnetPseudoLocalHost(el)))) /* Purge remote hosts only */
 
568
             || ((el->l2Family == FLAG_HOST_TRAFFIC_AF_FC) &&
 
569
                 (el->fcCounters->hostNumFcAddress[0] == '\0')))))
 
570
    return(1);
 
571
  else
 
572
    return(0);
 
573
}
 
574
 
 
575
/* ************************************ */
 
576
 
566
577
int purgeIdleHosts(int actDevice) {
567
578
  u_int idx, numFreedBuckets=0, numHosts = 0;
568
 
  time_t startTime = time(NULL), noSessionPurgeTime, withSessionPurgeTime;
 
579
  time_t now = time(NULL);
569
580
  static time_t lastPurgeTime[MAX_NUM_DEVICES];
570
581
  static char firstRun = 1;
571
582
  HostTraffic **theFlaggedHosts = NULL;
573
584
  float hiresDeltaTime;
574
585
  struct timeval hiresTimeStart, hiresTimeEnd;
575
586
  HostTraffic *el, *prev, *next;
576
 
 
 
587
  
577
588
  /* if(myGlobals.runningPref.rFileName != NULL) return; */
578
589
 
579
590
#ifdef IDLE_PURGE_DEBUG
587
598
 
588
599
  gettimeofday(&hiresTimeStart, NULL);
589
600
 
590
 
  if(startTime < (lastPurgeTime[actDevice]+PARM_HOST_PURGE_INTERVAL))
 
601
  if(now < (lastPurgeTime[actDevice]+PARM_HOST_PURGE_INTERVAL))
591
602
    return(0); /* Too short */
592
603
  else
593
 
    lastPurgeTime[actDevice] = startTime;
 
604
    lastPurgeTime[actDevice] = now;
594
605
 
595
606
  maxHosts = myGlobals.device[actDevice].hostsno; /* save it as it can change */
596
607
  myGlobals.piMem = maxHosts*sizeof(HostTraffic*);
597
608
  theFlaggedHosts = (HostTraffic**)calloc(1, myGlobals.piMem);
598
609
 
599
 
  /* Time used to decide whether a host need to be purged */
600
 
  noSessionPurgeTime   = startTime-PARM_HOST_PURGE_MINIMUM_IDLE_NOACTVSES;
601
 
  withSessionPurgeTime = startTime-PARM_HOST_PURGE_MINIMUM_IDLE_ACTVSES;
602
 
 
603
 
#ifdef IDLE_PURGE_DEBUG
604
 
  traceEvent(CONST_TRACE_INFO, "IDLE_PURGE_DEBUG: Beginning noS < %d, wS < %d",
605
 
             noSessionPurgeTime, withSessionPurgeTime);
606
 
#endif
607
 
 
608
610
  purgeOldFragmentEntries(actDevice); /* let's do this too */
609
611
 
610
612
#ifdef IDLE_PURGE_DEBUG
622
624
  accessMutex(&myGlobals.hostsHashLockMutex, "scanIdleLoop");
623
625
 
624
626
  for(idx=0; idx<myGlobals.device[actDevice].actualHashSize; idx++) {
 
627
    if(myGlobals.ntopRunState >= FLAG_NTOPSTATE_SHUTDOWN) break;
 
628
 
625
629
    if((el = myGlobals.device[actDevice].hash_hostTraffic[idx]) != NULL) {
626
 
      prev = NULL;
 
630
      prev = NULL;     
627
631
 
628
632
      while(el) {
629
 
        if((el->refCount == 0)
630
 
           && (   ((el->numHostSessions == 0) && (el->lastSeen < noSessionPurgeTime))
631
 
               || ((el->numHostSessions > 0)  && (el->lastSeen < withSessionPurgeTime)))
632
 
           && (!broadcastHost(el)) && (el != myGlobals.otherHostEntry)
633
 
           && (myGlobals.device[actDevice].virtualDevice /* e.g. sFlow/NetFlow */
634
 
               || (!myGlobals.runningPref.stickyHosts)
635
 
               || ((el->l2Family == FLAG_HOST_TRAFFIC_AF_ETH) &&
636
 
                   ((el->hostNumIpAddress[0] == '\0') /* Purge MAC addresses too */
637
 
                    || (!subnetPseudoLocalHost(el)))) /* Purge remote hosts only */
638
 
               || ((el->l2Family == FLAG_HOST_TRAFFIC_AF_FC) &&
639
 
                   (el->fcCounters->hostNumFcAddress[0] == '\0')))) {
 
633
        if(is_host_ready_to_purge(actDevice, el, now)) {
 
634
          if(!el->to_be_deleted) {
 
635
            el->to_be_deleted = 1; /* Delete it at the next run */
 
636
 
 
637
            /* Skip it and move to next host */
 
638
            prev = el;
 
639
            el = el->next;          
 
640
          } else {
640
641
          /* Host selected for deletion */
641
642
          theFlaggedHosts[numHosts++] = el;
 
643
          el->magic = CONST_UNMAGIC_NUMBER;
 
644
          purgeQueuedV4HostAddress(el->hostIpAddress.Ip4Address.s_addr);
 
645
          remove_valid_ptr(el);
642
646
          next = el->next;
643
647
 
644
648
          if(prev != NULL)
648
652
 
649
653
          el->next = NULL;
650
654
          el = next;
 
655
          }
651
656
        } else {
652
657
          /* Move to next host */
653
658
          prev = el;
681
686
  traceEvent(CONST_TRACE_INFO, "IDLE_PURGE_DEBUG: releaseMutex(purgeMutex)...released");
682
687
#endif
683
688
 
684
 
  traceEvent(CONST_TRACE_NOISY, "IDLE_PURGE: Device %d [%s] FINISHED selection, %d [out of %d] hosts selected",
 
689
  traceEvent(CONST_TRACE_NOISY, "IDLE_PURGE: Device %d [%s] FINISHED selection, "
 
690
             "%d [out of %d] hosts selected",
685
691
             actDevice, myGlobals.device[actDevice].name, numHosts, scannedHosts);
686
692
 
687
693
  /* Now free the entries */
757
763
  Searches a host and returns it. If the host is not
758
764
  present in the hash a new bucket is created
759
765
*/
760
 
HostTraffic* _lookupHost(HostAddr *hostIpAddress, u_char *ether_addr, short vlanId,
761
 
                        u_char checkForMultihoming, u_char forceUsingIPaddress,
762
 
                        int actualDeviceId, char *file, int line) {
 
766
HostTraffic* _lookupHost(HostAddr *hostIpAddress, u_char *ether_addr, u_int16_t vlanId,
 
767
                         u_char checkForMultihoming, u_char forceUsingIPaddress,
 
768
                         int actualDeviceId, char *file, int line) {
763
769
  u_int idx, isMultihomed = 0;
764
770
  HostTraffic *el=NULL;
765
771
  char buf[MAX_LEN_SYM_HOST_NAME_HTML];
766
772
  short useIPAddressForSearching = forceUsingIPaddress;
767
773
  char* symEthName = NULL, *ethAddr;
768
 
  u_char setSpoofingFlag = 0;
 
774
  u_char setSpoofingFlag = 0, locked_mutex = 0;
769
775
  u_short numRuns=0;
770
776
  u_int hostFound = 0;
771
777
  u_int updateIPinfo = 0;
 
778
  u_int32_t the_local_network, the_local_network_mask;
772
779
 
773
780
  if((hostIpAddress == NULL) && (ether_addr == NULL)) {
774
 
    traceEvent(CONST_TRACE_WARNING, "Both Ethernet and IP addresses are NULL in lookupHost()[%s/%d]", file, line);
 
781
    traceEvent(CONST_TRACE_WARNING, "Both Ethernet and IP addresses are NULL in lookupHost()[%s:%d]", file, line);
775
782
    return(NULL);
776
783
  }
777
784
 
799
806
    return(el); /* Found */
800
807
  else if(idx == FLAG_NO_PEER)
801
808
    return(NULL);
802
 
  else
 
809
  else {
803
810
    el = myGlobals.device[actualDeviceId].hash_hostTraffic[idx];
 
811
    if(el) {
 
812
      lockHostsHashMutex(el, "_lookupHost");
 
813
      accessMutex(&myGlobals.hostsHashLockMutex, "lookupHost");
 
814
      el = myGlobals.device[actualDeviceId].hash_hostTraffic[idx];
 
815
      locked_mutex = 1;
 
816
    }
 
817
  }
804
818
 
805
819
  while (el != NULL) {
806
820
    if(el->magic != CONST_MAGIC_NUMBER) {
807
821
      traceEvent(CONST_TRACE_ERROR,
808
 
                 "Bad magic number (expected=%d/real=%d) [deviceId=%d] lookupHost()[%s/%d]",
 
822
                 "Bad magic number (expected=%d/real=%d) [deviceId=%d] lookupHost()[%s:%d]",
809
823
                 CONST_MAGIC_NUMBER, el->magic, actualDeviceId,
810
824
                 file, line);
811
825
      break; /* Can't trust this chain ... */
813
827
 
814
828
    if(el->hostTrafficBucket != idx) {
815
829
      traceEvent(CONST_TRACE_WARNING,
816
 
                 "Error: wrong bucketIdx %s/%s (expected=%d/real=%d) [deviceId=%d] lookupHost()[%s/%d]",
 
830
                 "Error: wrong bucketIdx %s/%s (expected=%d/real=%d) [deviceId=%d] lookupHost()[%s:%d]",
817
831
                 el->ethAddressString, el->hostNumIpAddress,
818
832
                 idx, el->hostTrafficBucket, actualDeviceId,
819
833
                 file, line);
820
834
    }
821
835
 
822
 
    if(useIPAddressForSearching == 0) {
823
 
      /* compare with the ethernet-address then the IP address */
824
 
      if(memcmp(el->ethAddress, ether_addr, LEN_ETHERNET_ADDRESS) == 0) {
825
 
        if((hostIpAddress != NULL) &&
826
 
           (hostIpAddress->hostFamily == el->hostIpAddress.hostFamily)) {
827
 
          if((!isMultihomed) && checkForMultihoming) {
828
 
            /* This is a local address hence this is a potential multihomed host. */
829
 
 
830
 
            if(!(addrnull(&el->hostIpAddress)) &&
831
 
                (addrcmp(&el->hostIpAddress,hostIpAddress) != 0)) {
832
 
              isMultihomed = 1;
833
 
              FD_SET(FLAG_HOST_TYPE_MULTIHOMED, &el->flags);
834
 
            } else {
835
 
              updateIPinfo = 1;
836
 
            }
837
 
          }
838
 
          hostFound = 1;
839
 
          break;
840
 
        } else if(hostIpAddress == NULL){  /* Only Mac Addresses */
841
 
          hostFound = 1;
842
 
          break;
843
 
        } else { /* MAC match found and we have the IP - need to update... */
844
 
          updateIPinfo = 1;
845
 
          hostFound = 1;
846
 
          break;
847
 
        }
848
 
      } else if((hostIpAddress != NULL) &&
849
 
                (addrcmp(&el->hostIpAddress, hostIpAddress) == 0)) {
850
 
        /* Spoofing or duplicated MAC address:
851
 
           two hosts with the same IP address and different MAC
852
 
           addresses
853
 
        */
854
 
 
855
 
        if(!hasDuplicatedMac(el)) {
856
 
          FD_SET(FLAG_HOST_DUPLICATED_MAC, &el->flags);
857
 
 
858
 
          if(myGlobals.runningPref.enableSuspiciousPacketDump) {
859
 
            char etherbuf[LEN_ETHERNET_ADDRESS_DISPLAY];
860
 
 
861
 
            traceEvent(CONST_TRACE_WARNING,
862
 
                       "Two MAC addresses found for the same IP address "
863
 
                       "%s: [%s/%s] (spoofing detected?)",
864
 
                       el->hostNumIpAddress,
865
 
                       etheraddr_string(ether_addr, etherbuf), el->ethAddressString);
866
 
            dumpSuspiciousPacket(actualDeviceId);
867
 
          }
868
 
        }
869
 
 
870
 
        setSpoofingFlag = 1;
871
 
        hostFound = 1;
872
 
        break;
873
 
      }
874
 
    } else {
875
 
      /* -o | --no-mac (or NetFlow, which doesn't have MACs) - compare with only the IP address */
876
 
      if(addrcmp(&el->hostIpAddress, hostIpAddress) == 0) {
877
 
        hostFound = 1;
878
 
        break;
 
836
    if(!is_host_ready_to_purge(actualDeviceId, el, myGlobals.actTime)) {
 
837
      if(useIPAddressForSearching == 0) {
 
838
        /* compare with the ethernet-address then the IP address */
 
839
        if(memcmp(el->ethAddress, ether_addr, LEN_ETHERNET_ADDRESS) == 0) {
 
840
          if((hostIpAddress != NULL) &&
 
841
             (hostIpAddress->hostFamily == el->hostIpAddress.hostFamily)) {
 
842
            if((!isMultihomed) && checkForMultihoming) {
 
843
              /* This is a local address hence this is a potential multihomed host. */
 
844
 
 
845
              if(!(addrnull(&el->hostIpAddress)) &&
 
846
                 (addrcmp(&el->hostIpAddress,hostIpAddress) != 0)) {
 
847
                isMultihomed = 1;
 
848
                FD_SET(FLAG_HOST_TYPE_MULTIHOMED, &el->flags);
 
849
              } else {
 
850
                updateIPinfo = 1;
 
851
              }
 
852
            }
 
853
            hostFound = 1;
 
854
            break;
 
855
          } else if(hostIpAddress == NULL){  /* Only Mac Addresses */
 
856
            hostFound = 1;
 
857
            break;
 
858
          } else { /* MAC match found and we have the IP - need to update... */
 
859
            updateIPinfo = 1;
 
860
            hostFound = 1;
 
861
            break;
 
862
          }
 
863
        } else if((hostIpAddress != NULL) &&
 
864
                  (addrcmp(&el->hostIpAddress, hostIpAddress) == 0)) {
 
865
          /* Spoofing or duplicated MAC address:
 
866
             two hosts with the same IP address and different MAC
 
867
             addresses
 
868
          */
 
869
 
 
870
          if(!hasDuplicatedMac(el)) {
 
871
            FD_SET(FLAG_HOST_DUPLICATED_MAC, &el->flags);
 
872
 
 
873
            if(myGlobals.runningPref.enableSuspiciousPacketDump) {
 
874
              char etherbuf[LEN_ETHERNET_ADDRESS_DISPLAY];
 
875
 
 
876
              traceEvent(CONST_TRACE_WARNING,
 
877
                         "Two MAC addresses found for the same IP address "
 
878
                         "%s: [%s/%s] (spoofing detected?)",
 
879
                         el->hostNumIpAddress,
 
880
                         etheraddr_string(ether_addr, etherbuf), el->ethAddressString);
 
881
              dumpSuspiciousPacket(actualDeviceId);
 
882
            }
 
883
          }
 
884
 
 
885
          setSpoofingFlag = 1;
 
886
          hostFound = 1;
 
887
          break;
 
888
        }
 
889
      } else {
 
890
        /* -o | --no-mac (or NetFlow, which doesn't have MACs) - compare with only the IP address */
 
891
        if(addrcmp(&el->hostIpAddress, hostIpAddress) == 0) {
 
892
          hostFound = 1;
 
893
          break;
 
894
        }
879
895
      }
880
896
    }
881
 
 
882
897
    el = el->next;
883
898
    numRuns++;
884
899
  } /* while */
885
900
 
886
 
  if((hostFound == 1) && (vlanId > 0) && (vlanId != el->vlanId) && (!isMultivlaned(el))) {
 
901
  if(locked_mutex) releaseMutex(&myGlobals.hostsHashLockMutex);
 
902
 
 
903
  if((hostFound == 1) && (vlanId != NO_VLAN) && (vlanId != el->vlanId) && (!isMultivlaned(el))) {
887
904
    FD_SET(FLAG_HOST_TYPE_MULTIVLANED, &el->flags);
888
905
    if(myGlobals.multipleVLANedHostCount == 0) {
889
906
      traceEvent(CONST_TRACE_ERROR, "mVLAN: Host (identical IP/MAC) found on multiple VLANs");
921
938
      if(myGlobals.runningPref.numericFlag == 0)
922
939
        ipaddr2str(el->hostIpAddress, 1);
923
940
 
924
 
      if(isBroadcastAddress(&el->hostIpAddress))
 
941
      if(isBroadcastAddress(&el->hostIpAddress, NULL, NULL))
925
942
        FD_SET(FLAG_BROADCAST_HOST, &el->flags);
926
943
    }
927
944
  } else {
937
954
                   myGlobals.runningPref.maxNumHashEntries);
938
955
      }
939
956
 
940
 
      return(NULL);
941
 
    }
942
 
 
943
 
#if RECYCLE_MEMORY
944
 
    if(myGlobals.hostsCacheLen > 0) {
945
 
      el = myGlobals.hostsCache[--myGlobals.hostsCacheLen];
946
 
      myGlobals.hostsCacheReused++;
947
 
      /*
948
 
        traceEvent(CONST_TRACE_INFO, "Fetched host from pointers cache (len=%d)",
949
 
        (int)myGlobals.hostsCacheLen);
950
 
      */
951
 
    } else
952
 
#endif
953
 
      {   
954
 
        if((el = (HostTraffic*)malloc(sizeof(HostTraffic))) == NULL)
955
 
          return(NULL);
956
 
      }
 
957
      if(locked_mutex) unlockHostsHashMutex(myGlobals.device[actualDeviceId].hash_hostTraffic[idx]);
 
958
      return(NULL);
 
959
    }
 
960
        
 
961
    if((el = (HostTraffic*)malloc(sizeof(HostTraffic))) == NULL) {
 
962
      if(locked_mutex) unlockHostsHashMutex(myGlobals.device[actualDeviceId].hash_hostTraffic[idx]);
 
963
      return(NULL);
 
964
    }
 
965
     
957
966
    memset(el, 0, sizeof(HostTraffic));
958
967
    el->firstSeen = myGlobals.actTime;
959
968
 
967
976
      freePortsUsage(el);
968
977
 
969
978
    len = (size_t)myGlobals.numIpProtosList*sizeof(ShortProtoTrafficInfo**);
970
 
    if((el->ipProtosList = (ShortProtoTrafficInfo**)malloc(len)) == NULL) return(NULL);
 
979
    if((el->ipProtosList = (ShortProtoTrafficInfo**)malloc(len)) == NULL) {
 
980
      if(locked_mutex) unlockHostsHashMutex(myGlobals.device[actualDeviceId].hash_hostTraffic[idx]);
 
981
      return(NULL);
 
982
    }
971
983
    memset(el->ipProtosList, 0, len);
972
984
 
973
985
    len = (size_t)myGlobals.numIpProtosToMonitor*sizeof(ProtoTrafficInfo**);
974
 
    if((el->protoIPTrafficInfos = (ProtoTrafficInfo**)malloc(len)) == NULL) return(NULL);
 
986
    if((el->protoIPTrafficInfos = (ProtoTrafficInfo**)malloc(len)) == NULL) {
 
987
      if(locked_mutex) unlockHostsHashMutex(myGlobals.device[actualDeviceId].hash_hostTraffic[idx]);
 
988
      return(NULL);
 
989
    }
975
990
    memset(el->protoIPTrafficInfos, 0, len);
976
991
 
977
992
    el->magic = CONST_MAGIC_NUMBER;
985
1000
    myGlobals.device[actualDeviceId].hash_hostTraffic[el->hostTrafficBucket] = el;  /* Insert a new entry */
986
1001
    myGlobals.device[actualDeviceId].hostsno++;
987
1002
 
 
1003
    if(0) 
 
1004
      traceEvent(CONST_TRACE_INFO, "-> Allocated(%d) [tot=%d]", 
 
1005
                 actualDeviceId, myGlobals.device[actualDeviceId].hostsno);
 
1006
 
 
1007
    the_local_network = 0, the_local_network_mask = 0;
 
1008
 
988
1009
    if(ether_addr != NULL) {
989
1010
      if((hostIpAddress == NULL)
990
1011
         || ((hostIpAddress != NULL)
991
 
             && isPseudoLocalAddress(hostIpAddress, actualDeviceId)
992
 
             /* && (!isBroadcastAddress(hostIpAddress))*/
 
1012
             && isPseudoLocalAddress(hostIpAddress, actualDeviceId, &the_local_network, &the_local_network_mask)
 
1013
             /* && (!isBroadcastAddress(hostIpAddress, &the_local_network, &the_local_network_mask))*/
993
1014
             )) {
994
1015
        char etherbuf[LEN_ETHERNET_ADDRESS_DISPLAY];
995
1016
 
1002
1023
        symEthName = getSpecialMacInfo(el, (short)(!myGlobals.separator[0]));
1003
1024
        FD_SET(FLAG_SUBNET_LOCALHOST, &el->flags);
1004
1025
        FD_SET(FLAG_SUBNET_PSEUDO_LOCALHOST, &el->flags);
 
1026
        /* traceEvent(CONST_TRACE_WARNING, "-> %u/%u", the_local_network, the_local_network_mask); */
1005
1027
      } else if(hostIpAddress != NULL) {
1006
1028
        /* This is packet that's being routed or belonging to a
1007
1029
           remote network that uses the same physical wire (or forged)*/
1017
1039
 
1018
1040
          FD_CLR(FLAG_SUBNET_LOCALHOST, &el->flags);
1019
1041
 
1020
 
          if(isPrivateAddress(hostIpAddress)) FD_SET(FLAG_PRIVATE_IP_ADDRESS, &el->flags);
 
1042
          if(isPrivateAddress(hostIpAddress, &the_local_network, &the_local_network_mask)) FD_SET(FLAG_PRIVATE_IP_ADDRESS, &el->flags);
1021
1043
 
1022
 
          if(!isBroadcastAddress(hostIpAddress)) {
1023
 
            if(isPseudoLocalAddress(hostIpAddress, actualDeviceId))
 
1044
          if(!isBroadcastAddress(hostIpAddress, &the_local_network, &the_local_network_mask)) {
 
1045
            if(isPseudoLocalAddress(hostIpAddress, actualDeviceId, &the_local_network, &the_local_network_mask))
1024
1046
              FD_SET(FLAG_SUBNET_PSEUDO_LOCALHOST, &el->flags);
1025
1047
            else
1026
1048
              FD_CLR(FLAG_SUBNET_PSEUDO_LOCALHOST, &el->flags);
1047
1069
        }
1048
1070
 
1049
1071
        FD_SET(FLAG_BROADCAST_HOST, &el->flags);
1050
 
        if(isMulticastAddress(&el->hostIpAddress))
 
1072
        if(isMulticastAddress(&el->hostIpAddress, &the_local_network, &the_local_network_mask))
1051
1073
          FD_SET(FLAG_MULTICAST_HOST, &el->flags);
1052
1074
        strncpy(el->hostNumIpAddress,
1053
1075
                _addrtostr(&el->hostIpAddress, buf, sizeof(buf)),
1056
1078
 
1057
1079
        if((!addrnull(&el->hostIpAddress)) /* 0.0.0.0 */
1058
1080
           && (!addrfull(&el->hostIpAddress)) /* 255.255.255.255 */
1059
 
           && isBroadcastAddress(&el->hostIpAddress)) {
 
1081
           && isBroadcastAddress(&el->hostIpAddress, &the_local_network, &the_local_network_mask)) {
1060
1082
          /*
1061
1083
            The sender of this packet has obviously a wrong netmask because:
1062
1084
            - it is a local host
1098
1120
      strncpy(el->hostNumIpAddress,
1099
1121
              _addrtostr(hostIpAddress, buf, sizeof(buf)),
1100
1122
              sizeof(el->hostNumIpAddress));
1101
 
      if(isBroadcastAddress(&el->hostIpAddress)) FD_SET(FLAG_BROADCAST_HOST, &el->flags);
1102
 
      if(isMulticastAddress(&el->hostIpAddress)) FD_SET(FLAG_MULTICAST_HOST, &el->flags);
1103
 
      if(isPrivateAddress(hostIpAddress))        FD_SET(FLAG_PRIVATE_IP_ADDRESS,  &el->flags);
1104
 
      if((ether_addr == NULL) && (isPseudoLocalAddress(hostIpAddress, actualDeviceId)))
 
1123
      if(isBroadcastAddress(&el->hostIpAddress, &the_local_network, &the_local_network_mask)) FD_SET(FLAG_BROADCAST_HOST, &el->flags);
 
1124
      if(isMulticastAddress(&el->hostIpAddress, &the_local_network, &the_local_network_mask)) FD_SET(FLAG_MULTICAST_HOST, &el->flags);
 
1125
      if(isPrivateAddress(hostIpAddress, &the_local_network, &the_local_network_mask))        FD_SET(FLAG_PRIVATE_IP_ADDRESS,  &el->flags);
 
1126
      if((ether_addr == NULL) && (isPseudoLocalAddress(hostIpAddress, actualDeviceId, &the_local_network, &the_local_network_mask)))
1105
1127
        FD_SET(FLAG_SUBNET_PSEUDO_LOCALHOST, &el->flags);
1106
1128
 
1107
1129
      setResolvedName(el, el->hostNumIpAddress, FLAG_HOST_SYM_ADDR_TYPE_IP);
1110
1132
      if(myGlobals.runningPref.numericFlag == 0)
1111
1133
        ipaddr2str(el->hostIpAddress, 1);
1112
1134
 
 
1135
      getHostAS(el);
1113
1136
    } else {
1114
1137
      /* This is a new entry and hostIpAddress was NOT set.  Fill in MAC address, if we have it */
1115
1138
      if(symEthName[0] != '\0') {
1116
1139
        /* This is a local address so we have the MAC address */
1117
 
        safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "%s%s", symEthName, &el->ethAddressString[8]);
 
1140
        safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "%s%s", 
 
1141
                      symEthName, &el->ethAddressString[8]);
1118
1142
 
1119
1143
        buf[MAX_LEN_SYM_HOST_NAME-1] = '\0';
1120
1144
        setResolvedName(el, buf, FLAG_HOST_SYM_ADDR_TYPE_MAC);
1122
1146
    }
1123
1147
 
1124
1148
#ifdef HASH_DEBUG
1125
 
      traceEvent(CONST_TRACE_INFO, "HASH_DEBUG: Adding %s/%s [idx=%d][device=%d][actualHashSize=%d][#hosts=%d]",
 
1149
      traceEvent(CONST_TRACE_INFO, "HASH_DEBUG: Adding %s/%s [idx=%d][device=%d]"
 
1150
                 "[actualHashSize=%d][#hosts=%d]",
1126
1151
                 el->ethAddressString, el->hostNumIpAddress, idx, actualDeviceId,
1127
 
                 myGlobals.device[actualDeviceId].actualHashSize, myGlobals.device[actualDeviceId].hostsno);
 
1152
                 myGlobals.device[actualDeviceId].actualHashSize, 
 
1153
                 myGlobals.device[actualDeviceId].hostsno);
1128
1154
#endif
1129
1155
 
1130
1156
    setHostSerial(el);
1131
1157
    handlePluginHostCreationDeletion(el, (u_short)actualDeviceId, 1 /* host creation */);
1132
1158
  }
1133
1159
 
1134
 
 
1135
1160
  if(el != NULL) {
1136
1161
    el->lastSeen = myGlobals.actTime;
1137
1162
 
1161
1186
  hashSanityCheck();
1162
1187
#endif
1163
1188
 
 
1189
  if(locked_mutex) unlockHostsHashMutex(myGlobals.device[actualDeviceId].hash_hostTraffic[idx]);
 
1190
  
1164
1191
  return(el);
1165
1192
}
1166
1193
 
1171
1198
  u_int idx;
1172
1199
  HostTraffic *el=NULL;
1173
1200
  FcNameServerCacheEntry *fcnsEntry;
 
1201
  u_char locked_mutex = 0;
1174
1202
  u_short numRuns=0;
1175
1203
  u_int hostFound = 0;
1176
1204
 
1188
1216
  }
1189
1217
  else if(idx == FLAG_NO_PEER)
1190
1218
    return(NULL);
1191
 
  else
 
1219
  else {
1192
1220
    el = myGlobals.device[actualDeviceId].hash_hostTraffic[idx];
1193
 
 
 
1221
    if(el) {
 
1222
      lockHostsHashMutex(el, "lookupFcHost");
 
1223
      el = myGlobals.device[actualDeviceId].hash_hostTraffic[idx];
 
1224
      locked_mutex = 1;
 
1225
    }
 
1226
  }
1194
1227
 
1195
1228
  hostFound = 0;  /* This is the same type as the one of HashList */
1196
1229
 
1233
1266
                   myGlobals.runningPref.maxNumHashEntries);
1234
1267
      }
1235
1268
 
 
1269
      if(locked_mutex) unlockHostsHashMutex(myGlobals.device[actualDeviceId].hash_hostTraffic[idx]);
1236
1270
      return(NULL);
1237
1271
    }
1238
1272
 
1239
 
#if RECYCLE_MEMORY
1240
 
    if(myGlobals.hostsCacheLen > 0) {
1241
 
      el = myGlobals.hostsCache[--myGlobals.hostsCacheLen];
1242
 
      myGlobals.hostsCacheReused++;
1243
 
      /*
1244
 
        traceEvent(CONST_TRACE_INFO, "Fetched host from pointers cache (len=%d)",
1245
 
        (int)myGlobals.hostsCacheLen);
1246
 
      */
1247
 
    } else
1248
 
#endif
1249
 
      {
1250
 
        if((el = (HostTraffic*)malloc(sizeof(HostTraffic))) == NULL)
1251
 
          return(NULL);
1252
 
      }
 
1273
    if((el = (HostTraffic*)malloc(sizeof(HostTraffic))) == NULL) {
 
1274
      if(locked_mutex) unlockHostsHashMutex(myGlobals.device[actualDeviceId].hash_hostTraffic[idx]);
 
1275
      return(NULL);
 
1276
    }
1253
1277
 
1254
1278
    memset(el, 0, sizeof(HostTraffic));
1255
1279
    el->firstSeen = myGlobals.actTime;
1256
1280
 
1257
1281
    resetHostsVariables(el);
1258
1282
 
1259
 
    if(allocFcScsiCounters(el) == NULL) return(NULL);
 
1283
    if(allocFcScsiCounters(el) == NULL) {
 
1284
      if(locked_mutex) unlockHostsHashMutex(myGlobals.device[actualDeviceId].hash_hostTraffic[idx]);
 
1285
      return(NULL);
 
1286
    }
1260
1287
    el->l2Family = FLAG_HOST_TRAFFIC_AF_FC;
1261
1288
    el->fcCounters->devType = SCSI_DEV_UNINIT;
1262
1289
    el->magic = CONST_MAGIC_NUMBER;
1309
1336
  hashSanityCheck();
1310
1337
#endif
1311
1338
 
 
1339
  if(locked_mutex) unlockHostsHashMutex(myGlobals.device[actualDeviceId].hash_hostTraffic[idx]);
1312
1340
  return(el);
1313
1341
}
1314
1342
 
1369
1397
 
1370
1398
#endif /* HASH_DEBUG */
1371
1399
 
 
1400
/* ****************************** 
 
1401
   
 
1402
   Utility functions used by the remote plugin
 
1403
   
 
1404
   ****************************** */
 
1405
 
 
1406
#define MAX_NUM_VALID_PTRS   8
 
1407
static void* valid_ptrs[MAX_NUM_VALID_PTRS] = { NULL };
 
1408
 
 
1409
void add_valid_ptr(void* ptr) {
 
1410
  int i;
 
1411
  
 
1412
  traceEvent(CONST_TRACE_INFO, "add_valid_ptr(%p)", ptr);
 
1413
 
 
1414
  for(i=0; i<MAX_NUM_VALID_PTRS; i++) {
 
1415
    if(valid_ptrs[i] == NULL) {
 
1416
      valid_ptrs[i] = ptr;
 
1417
      break;
 
1418
    }
 
1419
  }
 
1420
 
 
1421
  valid_ptrs[MAX_NUM_VALID_PTRS-1] = ptr;
 
1422
}
 
1423
 
 
1424
/* ****************************** */
 
1425
 
 
1426
void remove_valid_ptr(void* ptr) {
 
1427
  int i;  
 
1428
 
 
1429
  for(i=0; i<MAX_NUM_VALID_PTRS; i++) {
 
1430
    if(valid_ptrs[i] == ptr) {
 
1431
      valid_ptrs[i] = NULL;
 
1432
      return;
 
1433
    }
 
1434
  } 
 
1435
 
 
1436
  /* traceEvent(CONST_TRACE_ERROR, "remove_valid_ptr(%p) failed", ptr); */
 
1437
}
 
1438
 
 
1439
/* ****************************** */
 
1440
 
 
1441
int is_valid_ptr(void* ptr) {
 
1442
  int i;
 
1443
 
 
1444
  for(i=0; i<MAX_NUM_VALID_PTRS; i++) {
 
1445
    if(valid_ptrs[i] == ptr) {
 
1446
      if(i > 0) {
 
1447
        /* Move towards the top */
 
1448
        void *swap = valid_ptrs[i-1];
 
1449
        valid_ptrs[i-1] = valid_ptrs[i];
 
1450
        valid_ptrs[i] = swap;
 
1451
      }
 
1452
      
 
1453
      traceEvent(CONST_TRACE_INFO, "is_valid_ptr(%p): 1", ptr);
 
1454
      return(1);
 
1455
    }
 
1456
  }
 
1457
 
 
1458
  traceEvent(CONST_TRACE_INFO, "is_valid_ptr(%p): 0", ptr);
 
1459
  return(0);
 
1460
}
 
1461