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

« back to all changes in this revision

Viewing changes to util.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
2
 * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 
3
 *
3
4
 *                          http://www.ntop.org
4
5
 *
5
 
 * Copyright (C) 1998-2005 Luca Deri <deri@ntop.org>
 
6
 * Copyright (C) 1998-2007 Luca Deri <deri@ntop.org>
6
7
 *
7
8
 * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
8
9
 *
57
58
static HostTraffic* __getFirstHost(u_int actualDeviceId, u_int beginIdx, char *file, int line) {
58
59
  u_int idx;
59
60
 
60
 
  /* accessMutex(&myGlobals.hostsHashMutex, "__getFirstHost"); */
 
61
  accessMutex(&myGlobals.hostsHashLockMutex, "__getFirstHost");
61
62
 
62
63
  for(idx=beginIdx; idx<myGlobals.device[actualDeviceId].actualHashSize; idx++) {
63
64
    HostTraffic *el = myGlobals.device[actualDeviceId].hash_hostTraffic[idx];
64
65
 
65
 
    if(el != NULL) {
66
 
      if(el->magic != CONST_MAGIC_NUMBER) {
67
 
        traceEvent(CONST_TRACE_ERROR, 
68
 
                   "Bad magic number [expected=%d/real=%d][deviceId=%d] getFirstHost()[%s/%d]",
69
 
                   CONST_MAGIC_NUMBER, el->magic, actualDeviceId, file, line);
70
 
        /* releaseMutex(&myGlobals.hostsHashMutex); */
71
 
        return(NULL);
 
66
    while(el != NULL) {
 
67
      if(broadcastHost(el) || (el == myGlobals.otherHostEntry)) {
 
68
        el = el->next;
 
69
      } else {
 
70
        if(el->magic != CONST_MAGIC_NUMBER) {
 
71
          traceEvent(CONST_TRACE_ERROR,
 
72
                     "Bad magic number [expected=%d/real=%d][deviceId=%d] getFirstHost()[%s/%d]",
 
73
                     CONST_MAGIC_NUMBER, el->magic, actualDeviceId, file, line);
 
74
          releaseMutex(&myGlobals.hostsHashLockMutex);
 
75
          return(NULL);
 
76
        }
 
77
 
 
78
        if(!is_host_ready_to_purge(actualDeviceId, el, time(NULL))) {
 
79
          /* Do not return hosts that will soon be purged off memory */
 
80
          releaseMutex(&myGlobals.hostsHashLockMutex);
 
81
          return(el);
 
82
        } else {
 
83
          el = el->next;
 
84
        }
72
85
      }
73
 
 
74
 
      /* releaseMutex(&myGlobals.hostsHashMutex); */
75
 
      return(el);
76
86
    }
77
87
  }
78
88
 
79
 
  /* releaseMutex(&myGlobals.hostsHashMutex); */
 
89
  releaseMutex(&myGlobals.hostsHashLockMutex);
80
90
  return(NULL);
81
91
}
82
92
 
83
93
/* ************************************ */
84
94
 
85
95
HostTraffic* _getFirstHost(u_int actualDeviceId, char *file, int line) {
86
 
  return(__getFirstHost(actualDeviceId, FIRST_HOSTS_ENTRY, file, line));
 
96
  return(__getFirstHost(actualDeviceId, 0 /* FIRST_HOSTS_ENTRY */, file, line));
87
97
}
88
98
 
89
99
/* ************************************ */
90
100
 
91
101
HostTraffic* _getNextHost(u_int actualDeviceId, HostTraffic *host, char *file, int line) {
92
 
  if(host == NULL) return(NULL);
93
 
 
94
 
  /* accessMutex(&myGlobals.hostsHashMutex, "getNextHost"); */
95
 
 
96
 
  if(host->next != NULL) {
 
102
  u_int nextIdx;
 
103
  time_t now = time(NULL);
 
104
 
 
105
  accessMutex(&myGlobals.hostsHashLockMutex, "getNextHost");
 
106
 
 
107
  if((host == NULL) || (host->magic != CONST_MAGIC_NUMBER)) {
 
108
    releaseMutex(&myGlobals.hostsHashLockMutex);
 
109
    return(NULL);
 
110
  }
 
111
 
 
112
  nextIdx = host->hostTrafficBucket+1;
 
113
 
 
114
  while(host->next != NULL) {
97
115
    if(host->next->magic != CONST_MAGIC_NUMBER) {
98
116
      traceEvent(CONST_TRACE_ERROR, "Bad magic number (expected=%d/real=%d) getNextHost()[%s/%d]",
99
117
                 CONST_MAGIC_NUMBER, host->next->magic, file, line);
100
 
      /* releaseMutex(&myGlobals.hostsHashMutex); */
 
118
      releaseMutex(&myGlobals.hostsHashLockMutex);
101
119
      return(NULL);
102
120
    }
103
121
 
104
 
    /* releaseMutex(&myGlobals.hostsHashMutex); */
105
 
    return(host->next);
106
 
  } else {
107
 
    u_int nextIdx = host->hostTrafficBucket+1;
108
 
 
109
 
    /* releaseMutex(&myGlobals.hostsHashMutex); */
110
 
    if(nextIdx < myGlobals.device[actualDeviceId].actualHashSize)
111
 
      return(__getFirstHost(actualDeviceId, nextIdx, file, line));
112
 
    else
113
 
      return(NULL);
 
122
    if(!is_host_ready_to_purge(actualDeviceId, host->next, now)) {
 
123
      releaseMutex(&myGlobals.hostsHashLockMutex);
 
124
      return(host->next);
 
125
    } else
 
126
      host = host->next;
114
127
  }
 
128
 
 
129
  /* No host has been found: move to next bucket */
 
130
  releaseMutex(&myGlobals.hostsHashLockMutex);
 
131
  if(nextIdx < myGlobals.device[actualDeviceId].actualHashSize)
 
132
    return(__getFirstHost(actualDeviceId, nextIdx, file, line));
 
133
  else
 
134
    return(NULL);
115
135
}
116
136
 
117
137
/* ************************************ */
154
174
    }
155
175
  }
156
176
 
157
 
#ifdef DEBUG
158
 
  {
159
 
    char buf[48];
160
 
 
161
 
    traceEvent(CONST_TRACE_NOISY, "==>>> Unable to locate host %s",
162
 
               _intoa(hostIpAddress, buf, sizeof(buf)));
163
 
  }
164
 
#endif
165
 
 
166
177
  return(NULL);
167
178
}
168
179
 
172
183
  buf[0] = '\0';
173
184
 
174
185
  if(buf_len >= 2*sizeof(HostSerial)) {
175
 
    int len = 0, i;
 
186
    int i;
176
187
    char tmpStr[16];
177
188
    char *ptr = (char*)&theSerial;
178
 
           
 
189
 
179
190
    for(i=0; i<sizeof(HostSerial); i++) {
180
191
      snprintf(tmpStr, sizeof(tmpStr), "%02X", ptr[i] & 0xFF);
181
192
      strcat(buf, tmpStr);
189
200
 
190
201
void str2serial(HostSerial *theSerial, char *buf, int buf_len) {
191
202
  if(buf_len >= 2*sizeof(HostSerial)) {
192
 
    int len = 0, i, j;
 
203
    int i, j;
193
204
    char tmpStr[16];
194
 
    char *ptr = (char*)theSerial;
195
 
      
196
 
    for(i=0, j=0; i<2*sizeof(HostSerial);) {
 
205
    u_char *ptr = (u_char*)theSerial;
 
206
 
 
207
    for(i=0, j=0; j<sizeof(HostSerial); j++) {
 
208
          u_int c;
 
209
          
197
210
      tmpStr[0] = buf[i++];
198
211
      tmpStr[1] = buf[i++];
199
212
      tmpStr[2] = '\0';
200
 
      sscanf(tmpStr, "%02X", &ptr[j++]);
 
213
      sscanf(tmpStr, "%02X", &c);
 
214
          ptr[j] = c & 0xFF;
 
215
          
 
216
          /*
 
217
           ptr[j] = ((u_int8_t)buf[i]) * 16 + ((u_int8_t)buf[i+1]);
 
218
           i += 2;
 
219
           */
201
220
    }
202
221
  }
203
222
}
238
257
    el = myGlobals.device[actualDeviceId].hash_hostTraffic[idx];
239
258
 
240
259
  for(; el != NULL; el = el->next) {
241
 
    if(!strncmp((char*)el->ethAddress, macAddr, LEN_ETHERNET_ADDRESS)) {
 
260
    if(!memcmp((char*)el->ethAddress, macAddr, LEN_ETHERNET_ADDRESS)) {
242
261
      if((vlanId > 0) && (el->vlanId != vlanId))
243
262
        continue;
244
263
      else
540
559
 
541
560
  if(tmp != NULL) tmp->next = NULL;
542
561
  iface_destroy(ih);
543
 
#ifdef DEBUG
544
 
  traceEvent(CONST_TRACE_INFO, "DEBUG: Local address is: %s", intop(hostAddress));
545
 
#endif
546
 
  return addrs;
 
562
 
 
563
  return(addrs);
547
564
 
548
565
}
549
566
#endif
586
603
/**************************************/
587
604
 
588
605
#ifdef INET6
589
 
unsigned short isLinkLocalAddress(struct in6_addr *addr) {
 
606
unsigned short isLinkLocalAddress(struct in6_addr *addr,
 
607
                                  u_int32_t *the_local_network,
 
608
                                  u_int32_t *the_local_network_mask) {
590
609
  int i;
591
610
 
 
611
  if(the_local_network && the_local_network_mask)
 
612
    (*the_local_network) = 0,  (*the_local_network_mask) = 0;
 
613
 
592
614
  if(addr == NULL)
593
615
    return 1;
594
616
  else if(addr->s6_addr == 0x0)
609
631
/*******************************************/
610
632
 
611
633
#ifdef INET6
612
 
unsigned short in6_isMulticastAddress(struct in6_addr *addr) {
 
634
unsigned short in6_isMulticastAddress(struct in6_addr *addr,
 
635
                                      u_int32_t *the_local_network,
 
636
                                      u_int32_t *the_local_network_mask) {
 
637
 
 
638
  if(the_local_network && the_local_network_mask)
 
639
    (*the_local_network) = 0,  (*the_local_network_mask) = 0;
 
640
 
613
641
  if(IN6_IS_ADDR_MULTICAST(addr)) {
614
642
#ifdef DEBUG
615
643
    traceEvent(CONST_TRACE_INFO, "DEBUG: %s is multicast [%X/%X]",
624
652
/*******************************************/
625
653
 
626
654
#ifdef INET6
627
 
unsigned short in6_isLocalAddress(struct in6_addr *addr, u_int deviceId) {
 
655
unsigned short in6_isLocalAddress(struct in6_addr *addr, u_int deviceId,
 
656
                                  u_int32_t *the_local_network,
 
657
                                  u_int32_t *the_local_network_mask) {
 
658
 
 
659
  if(the_local_network && the_local_network_mask)
 
660
    (*the_local_network) = 0,  (*the_local_network_mask) = 0;
 
661
 
628
662
  if(deviceId >= myGlobals.numDevices) {
629
663
    traceEvent(CONST_TRACE_WARNING, "Index %u out of range [0..%u] - address treated as remote",
630
664
               deviceId, myGlobals.numDevices);
645
679
  traceEvent(CONST_TRACE_INFO, "DEBUG: %s is %s", intop(addr));
646
680
#endif
647
681
  /* Link Local Addresses are local */
648
 
  return(isLinkLocalAddress(addr));
 
682
  return(isLinkLocalAddress(addr, the_local_network, the_local_network_mask));
649
683
}
650
684
 
651
685
/* ******************************************* */
652
686
 
653
 
unsigned short in6_isPrivateAddress(struct in6_addr *addr) {
 
687
unsigned short in6_isPrivateAddress(struct in6_addr *addr,
 
688
                                    u_int32_t *the_local_network,
 
689
                                    u_int32_t *the_local_network_mask) {
654
690
  /* IPv6 have private addresses ?*/
 
691
 
 
692
  if(the_local_network && the_local_network_mask)
 
693
    (*the_local_network) = 0,  (*the_local_network_mask) = 0;
 
694
 
655
695
  return(0);
656
696
}
657
697
#endif
658
698
 
659
699
/* ********************************* */
660
700
 
661
 
unsigned short in_isBroadcastAddress(struct in_addr *addr) {
 
701
unsigned short in_isBroadcastAddress(struct in_addr *addr,
 
702
                                     u_int32_t *the_local_network,
 
703
                                     u_int32_t *the_local_network_mask) {
662
704
  int i;
663
705
 
 
706
  if(the_local_network && the_local_network_mask)
 
707
    (*the_local_network) = 0,  (*the_local_network_mask) = 0;
 
708
 
664
709
  if(addr == NULL)
665
710
    return 1;
666
711
  else if(addr->s_addr == 0x0)
689
734
      }
690
735
    }
691
736
 
692
 
    return(in_isPseudoBroadcastAddress(addr));
 
737
    return(in_isPseudoBroadcastAddress(addr, the_local_network, the_local_network_mask));
693
738
  }
694
739
}
695
740
 
696
741
/* ********************************* */
697
742
 
698
 
unsigned short in_isMulticastAddress(struct in_addr *addr) {
 
743
unsigned short in_isMulticastAddress(struct in_addr *addr,
 
744
                                     u_int32_t *the_local_network,
 
745
                                     u_int32_t *the_local_network_mask) {
 
746
 
 
747
  if(the_local_network && the_local_network_mask)
 
748
    (*the_local_network) = 0,  (*the_local_network_mask) = 0;
 
749
 
699
750
  if((addr->s_addr & CONST_MULTICAST_MASK) == CONST_MULTICAST_MASK) {
700
751
#ifdef DEBUG
701
752
    traceEvent(CONST_TRACE_INFO, "DEBUG: %s is multicast [%X/%X]",
711
762
 
712
763
/* ********************************* */
713
764
 
714
 
unsigned short in_isLocalAddress(struct in_addr *addr, u_int deviceId) {
 
765
u_int8_t num_network_bits(u_int32_t addr) {
 
766
  int num_bits;
 
767
 
 
768
  for(num_bits=0; addr > 0; num_bits++)
 
769
    addr = addr >> 2;
 
770
 
 
771
  /* traceEvent(CONST_TRACE_WARNING, "-> num_bits=%d", num_bits); */
 
772
 
 
773
  return(num_bits);
 
774
}
 
775
 
 
776
/* ********************************* */
 
777
 
 
778
unsigned short in_isLocalAddress(struct in_addr *addr, u_int deviceId,
 
779
                                 u_int32_t *the_local_network,
 
780
                                 u_int32_t *the_local_network_mask) {
 
781
 
 
782
  if(the_local_network && the_local_network_mask)
 
783
    (*the_local_network) = 0,  (*the_local_network_mask) = 0;
 
784
 
715
785
  if(deviceId >= myGlobals.numDevices) {
716
786
    traceEvent(CONST_TRACE_WARNING, "Index %u out of range [0..%u] - address treated as remote",
717
787
               deviceId, myGlobals.numDevices);
731
801
#ifdef ADDRESS_DEBUG
732
802
      traceEvent(CONST_TRACE_INFO, "ADDRESS_DEBUG: %s is local", intoa(*addr));
733
803
#endif
 
804
 
 
805
      if(the_local_network && the_local_network_mask)
 
806
        (*the_local_network) = myGlobals.device[deviceId].network.s_addr,
 
807
          (*the_local_network_mask) = num_network_bits(myGlobals.device[deviceId].netmask.s_addr);
734
808
      return 1;
735
809
    }
736
810
  } else {
741
815
#ifdef ADDRESS_DEBUG
742
816
        traceEvent(CONST_TRACE_INFO, "ADDRESS_DEBUG: %s is local", intoa(*addr));
743
817
#endif
 
818
        if(the_local_network && the_local_network_mask)
 
819
          (*the_local_network) = myGlobals.device[i].network.s_addr,
 
820
            (*the_local_network_mask) = num_network_bits(myGlobals.device[deviceId].netmask.s_addr);
744
821
        return 1;
745
822
      }
746
823
  }
748
825
  if(myGlobals.runningPref.trackOnlyLocalHosts)
749
826
    return(0);
750
827
 
751
 
#ifdef DEBUG
752
 
  traceEvent(CONST_TRACE_INFO, "DEBUG: %s is %s", intoa(*addr),
753
 
             isBroadcastAddress(addr) ? "pseudolocal" : "remote");
754
 
#endif
755
828
  /* Broadcast is considered a local address */
756
 
  return(in_isBroadcastAddress(addr));
 
829
  return(in_isBroadcastAddress(addr, the_local_network, the_local_network_mask));
757
830
}
758
831
 
759
832
/* ********************************* */
760
833
 
761
 
unsigned short in_isPrivateAddress(struct in_addr *addr) {
 
834
unsigned short in_isPrivateAddress(struct in_addr *addr,
 
835
                                   u_int32_t *the_local_network,
 
836
                                   u_int32_t *the_local_network_mask) {
762
837
  /* See http://www.isi.edu/in-notes/rfc1918.txt */
763
838
 
 
839
  if(the_local_network && the_local_network_mask)
 
840
    (*the_local_network) = 0,  (*the_local_network_mask) = 0;
 
841
 
764
842
  /* Fixes below courtesy of Wies-Software <wies@wiessoft.de> */
765
 
  if(((addr->s_addr & 0xFF000000) == 0x0A000000)    /* 10/8      */
766
 
     || ((addr->s_addr & 0xFFF00000) == 0xAC100000) /* 172.16/12  */
767
 
     || ((addr->s_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168/16 */
768
 
     )
 
843
  if(   ((addr->s_addr & 0xFF000000) == 0x0A000000) /* 10.0.0.0/8  */
 
844
        || ((addr->s_addr & 0xFFF00000) == 0xAC100000) /* 172.16/12   */
 
845
        || ((addr->s_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168/16  */
 
846
        || ((addr->s_addr & 0xFF000000) == 0x7F000000) /* 127.0.0.0/8 */
 
847
        )
769
848
    return(1);
770
849
  else
771
850
    return(0);
773
852
 
774
853
/***************************************/
775
854
 
776
 
unsigned short isBroadcastAddress(HostAddr *addr) {
 
855
unsigned short isBroadcastAddress(HostAddr *addr,
 
856
                                  u_int32_t *the_local_network,
 
857
                                  u_int32_t *the_local_network_mask) {
 
858
  if(the_local_network && the_local_network_mask)
 
859
    (*the_local_network) = 0,  (*the_local_network_mask) = 0;
 
860
 
777
861
  switch(addr->hostFamily) {
778
862
  case AF_INET:
779
 
    return (in_isBroadcastAddress(&addr->Ip4Address));
 
863
    return (in_isBroadcastAddress(&addr->Ip4Address, the_local_network, the_local_network_mask));
780
864
#ifdef INET6
781
865
  case AF_INET6:
782
 
    return (isLinkLocalAddress(&addr->Ip6Address));
 
866
    return (isLinkLocalAddress(&addr->Ip6Address, NULL, NULL));
783
867
#endif
784
868
  default: return(0);
785
869
  }
787
871
 
788
872
/* ******************************************** */
789
873
 
790
 
unsigned short isMulticastAddress(HostAddr *addr) {
 
874
unsigned short isMulticastAddress(HostAddr *addr,
 
875
                                  u_int32_t *the_local_network,
 
876
                                  u_int32_t *the_local_network_mask) {
 
877
  if(the_local_network && the_local_network_mask)
 
878
    (*the_local_network) = 0,  (*the_local_network_mask) = 0;
 
879
 
791
880
  switch(addr->hostFamily) {
792
881
  case AF_INET:
793
 
    return (in_isMulticastAddress(&addr->Ip4Address));
 
882
    return (in_isMulticastAddress(&addr->Ip4Address, the_local_network, the_local_network_mask));
794
883
#ifdef INET6
795
884
  case AF_INET6:
796
 
    return (in6_isMulticastAddress(&addr->Ip6Address));
 
885
    return (in6_isMulticastAddress(&addr->Ip6Address, NULL, NULL));
797
886
#endif
798
887
  default: return(0);
799
888
  }
801
890
 
802
891
/* ************************************************* */
803
892
 
804
 
unsigned short isLocalAddress(HostAddr *addr, u_int deviceId) {
 
893
unsigned short isLocalAddress(HostAddr *addr, u_int deviceId,
 
894
                              u_int32_t *the_local_network,
 
895
                              u_int32_t *the_local_network_mask) {
 
896
  if(the_local_network && the_local_network_mask)
 
897
    (*the_local_network) = 0,  (*the_local_network_mask) = 0;
 
898
 
805
899
  switch(addr->hostFamily) {
806
900
  case AF_INET:
807
 
    return (in_isLocalAddress(&addr->Ip4Address, deviceId));
 
901
    return (in_isLocalAddress(&addr->Ip4Address, deviceId, the_local_network, the_local_network_mask));
808
902
#ifdef INET6
809
903
  case AF_INET6:
810
 
    return (in6_isLocalAddress(&addr->Ip6Address, deviceId));
 
904
    return (in6_isLocalAddress(&addr->Ip6Address, deviceId, NULL, NULL));
811
905
#endif
812
906
  default: return(0);
813
907
  }
815
909
 
816
910
/* ************************************************** */
817
911
 
818
 
unsigned short isPrivateAddress(HostAddr *addr) {
 
912
unsigned short isPrivateAddress(HostAddr *addr,
 
913
                                u_int32_t *the_local_network,
 
914
                                u_int32_t *the_local_network_mask) {
 
915
  if(the_local_network && the_local_network_mask)
 
916
    (*the_local_network) = 0,  (*the_local_network_mask) = 0;
 
917
 
819
918
  switch(addr->hostFamily) {
820
919
  case AF_INET:
821
 
    return (in_isPrivateAddress(&addr->Ip4Address));
 
920
    return (in_isPrivateAddress(&addr->Ip4Address, the_local_network, the_local_network_mask));
822
921
#ifdef INET6
823
922
  case AF_INET6:
824
 
    return (in6_isPrivateAddress(&addr->Ip6Address));
 
923
    return (in6_isPrivateAddress(&addr->Ip6Address, NULL, NULL));
825
924
#endif
826
925
  default: return(0);
827
926
  }
963
1062
 
964
1063
/* Example: "131.114.0.0/16,193.43.104.0/255.255.255.0" */
965
1064
 
966
 
void handleAddressLists(char* addresses, u_int32_t theNetworks[MAX_NUM_NETWORKS][3],
 
1065
void handleAddressLists(char* addresses, u_int32_t theNetworks[MAX_NUM_NETWORKS][4],
967
1066
                        u_short *numNetworks, char *localAddresses,
968
1067
                        int localAddressesLen, int flagWhat) {
969
1068
  char *strtokState, *address;
972
1071
  if((addresses == NULL) || (addresses[0] == '\0'))
973
1072
    return;
974
1073
 
975
 
  traceEvent(CONST_TRACE_NOISY,
976
 
             "Processing %s parameter '%s'",
977
 
             flagWhat == CONST_HANDLEADDRESSLISTS_MAIN ? "-m | --local-subnets"  :
978
 
             flagWhat == CONST_HANDLEADDRESSLISTS_RRD ? "RRD" :
979
 
             flagWhat == CONST_HANDLEADDRESSLISTS_NETFLOW ? "Netflow white/black list" :
980
 
             flagWhat == CONST_HANDLEADDRESSLISTS_CLUSTERS ? "cluster" : "unknown",
981
 
             addresses);
 
1074
  if(0) traceEvent(CONST_TRACE_NOISY,
 
1075
                   "Processing %s parameter '%s'",
 
1076
                   flagWhat == CONST_HANDLEADDRESSLISTS_MAIN ? "-m | --local-subnets"  :
 
1077
                   flagWhat == CONST_HANDLEADDRESSLISTS_RRD ? "RRD" :
 
1078
                   flagWhat == CONST_HANDLEADDRESSLISTS_NETFLOW ? "Netflow white/black list" :
 
1079
                   flagWhat == CONST_HANDLEADDRESSLISTS_CLUSTERS ? "cluster" :
 
1080
                   flagWhat == CONST_HANDLEADDRESSLISTS_COMMUNITY ? "community" : "unknown",
 
1081
                   addresses);
982
1082
 
983
1083
  memset(localAddresses, 0, localAddressesLen);
984
1084
 
985
1085
  address = strtok_r(addresses, ",", &strtokState);
986
1086
 
987
1087
  while(address != NULL) {
 
1088
    u_int32_t network, networkMask, broadcast;
 
1089
    int bits, a, b, c, d;
988
1090
    char *mask = strchr(address, '/');
989
1091
 
990
1092
    if(mask == NULL) {
991
 
      if (flagWhat == CONST_HANDLEADDRESSLISTS_MAIN)
992
 
        traceEvent(CONST_TRACE_WARNING, "-m: Empty mask '%s' - ignoring entry", address);
 
1093
      bits = 32;
993
1094
    } else {
994
 
      u_int32_t network, networkMask, broadcast;
995
 
      int bits, a, b, c, d;
996
 
 
997
1095
      mask[0] = '\0';
998
1096
      mask++;
999
 
      bits = dotted2bits (mask);
1000
 
 
1001
 
      if(sscanf(address, "%d.%d.%d.%d", &a, &b, &c, &d) != 4) {
1002
 
        traceEvent(CONST_TRACE_WARNING, "%s: Bad format '%s' - ignoring entry",
1003
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_MAIN ? "-m"  :
1004
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_RRD ? "RRD" :
1005
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_NETFLOW ? "Netflow" :
1006
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_CLUSTERS ? "cluster" : "unknown",
1007
 
                   address);
1008
 
        address = strtok_r(NULL, ",", &strtokState);
1009
 
        continue;
1010
 
      }
1011
 
 
1012
 
      if(bits == CONST_INVALIDNETMASK) {
1013
 
        /* malformed netmask specification */
1014
 
        traceEvent(CONST_TRACE_WARNING, "%s: Net mask '%s' not valid - ignoring entry",
1015
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_MAIN ? "-m | --local-subnets"  :
1016
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_RRD ? "RRD" :
1017
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_NETFLOW ? "Netflow white/black list" :
1018
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_CLUSTERS ? "cluster" : "unknown",
1019
 
                   mask);
1020
 
        address = strtok_r(NULL, ",", &strtokState);
1021
 
        continue;
1022
 
      }
1023
 
 
1024
 
      network     = ((a & 0xff) << 24) + ((b & 0xff) << 16) + ((c & 0xff) << 8) + (d & 0xff);
1025
 
      /* Special case the /32 mask - yeah, we could probably do it with some fancy
1026
 
         u long long stuff, but this is simpler...
1027
 
         Burton Strauss <Burton@ntopsupport.com> Jun2002
1028
 
      */
1029
 
      if (bits == 32) {
1030
 
        networkMask = 0xffffffff;
1031
 
      } else {
1032
 
        networkMask = 0xffffffff >> bits;
1033
 
        networkMask = ~networkMask;
1034
 
      }
1035
 
 
1036
 
#ifdef DEBUG
1037
 
      traceEvent(CONST_TRACE_INFO, "DEBUG: Nw=%08X - Mask: %08X [%08X]",
1038
 
                 network, networkMask, (network & networkMask));
1039
 
#endif
1040
 
 
1041
 
      if((networkMask >= 0xFFFFFF00) /* Courtesy of Roy-Magne Mo <romo@interpost.no> */
1042
 
         && ((network & networkMask) != network))  {
1043
 
        /* malformed network specification */
1044
 
        traceEvent(CONST_TRACE_WARNING, "%s: %d.%d.%d.%d/%d is not a valid network - correcting mask",
1045
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_MAIN ? "-m | --local-subnets"  :
1046
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_RRD ? "RRD" :
1047
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_NETFLOW ? "Netflow white/black list" :
1048
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_CLUSTERS ? "cluster" : "unknown",
1049
 
                   a, b, c, d, bits);
1050
 
 
1051
 
        /* correcting network numbers as specified in the netmask */
1052
 
        network &= networkMask;
 
1097
      bits = dotted2bits(mask);
 
1098
    }
 
1099
 
 
1100
    if(sscanf(address, "%d.%d.%d.%d", &a, &b, &c, &d) != 4) {
 
1101
      traceEvent(CONST_TRACE_WARNING, "%s: Bad format '%s' - ignoring entry",
 
1102
                 flagWhat == CONST_HANDLEADDRESSLISTS_MAIN ? "-m"  :
 
1103
                 flagWhat == CONST_HANDLEADDRESSLISTS_RRD ? "RRD" :
 
1104
                 flagWhat == CONST_HANDLEADDRESSLISTS_NETFLOW ? "Netflow" :
 
1105
                 flagWhat == CONST_HANDLEADDRESSLISTS_CLUSTERS ? "cluster"  :
 
1106
                 flagWhat == CONST_HANDLEADDRESSLISTS_COMMUNITY ? "community" : "unknown",
 
1107
                 address);
 
1108
      address = strtok_r(NULL, ",", &strtokState);
 
1109
      continue;
 
1110
    }
 
1111
 
 
1112
    if(bits == CONST_INVALIDNETMASK) {
 
1113
      /* malformed netmask specification */
 
1114
      traceEvent(CONST_TRACE_WARNING, "%s: Net mask '%s' not valid - ignoring entry",
 
1115
                 flagWhat == CONST_HANDLEADDRESSLISTS_MAIN ? "-m | --local-subnets"  :
 
1116
                 flagWhat == CONST_HANDLEADDRESSLISTS_RRD ? "RRD" :
 
1117
                 flagWhat == CONST_HANDLEADDRESSLISTS_NETFLOW ? "Netflow white/black list" :
 
1118
                 flagWhat == CONST_HANDLEADDRESSLISTS_CLUSTERS ? "cluster"  :
 
1119
                 flagWhat == CONST_HANDLEADDRESSLISTS_COMMUNITY ? "community" : "unknown",
 
1120
                 mask);
 
1121
      address = strtok_r(NULL, ",", &strtokState);
 
1122
      continue;
 
1123
    }
 
1124
 
 
1125
    network     = ((a & 0xff) << 24) + ((b & 0xff) << 16) + ((c & 0xff) << 8) + (d & 0xff);
 
1126
    /* Special case the /32 mask - yeah, we could probably do it with some fancy
 
1127
       u long long stuff, but this is simpler...
 
1128
       Burton Strauss <Burton@ntopsupport.com> Jun2002
 
1129
    */
 
1130
    if (bits == 32) {
 
1131
      networkMask = 0xffffffff;
 
1132
    } else {
 
1133
      networkMask = 0xffffffff >> bits;
 
1134
      networkMask = ~networkMask;
 
1135
    }
 
1136
 
 
1137
#ifdef DEBUG
 
1138
    traceEvent(CONST_TRACE_INFO, "DEBUG: Nw=%08X - Mask: %08X [%08X]",
 
1139
               network, networkMask, (network & networkMask));
 
1140
#endif
 
1141
 
 
1142
    if((networkMask >= 0xFFFFFF00) /* Courtesy of Roy-Magne Mo <romo@interpost.no> */
 
1143
       && ((network & networkMask) != network))  {
 
1144
      /* malformed network specification */
 
1145
      traceEvent(CONST_TRACE_WARNING, "%s: %d.%d.%d.%d/%d is not a valid network - correcting mask",
 
1146
                 flagWhat == CONST_HANDLEADDRESSLISTS_MAIN ? "-m | --local-subnets"  :
 
1147
                 flagWhat == CONST_HANDLEADDRESSLISTS_RRD ? "RRD" :
 
1148
                 flagWhat == CONST_HANDLEADDRESSLISTS_NETFLOW ? "Netflow white/black list" :
 
1149
                 flagWhat == CONST_HANDLEADDRESSLISTS_CLUSTERS ? "cluster"  :
 
1150
                 flagWhat == CONST_HANDLEADDRESSLISTS_COMMUNITY ? "community" : "unknown",
 
1151
                 a, b, c, d, bits);
 
1152
 
 
1153
      /* correcting network numbers as specified in the netmask */
 
1154
      network &= networkMask;
 
1155
 
 
1156
      a = (int) ((network >> 24) & 0xff);
 
1157
      b = (int) ((network >> 16) & 0xff);
 
1158
      c = (int) ((network >>  8) & 0xff);
 
1159
      d = (int) ((network >>  0) & 0xff);
 
1160
 
 
1161
      traceEvent(CONST_TRACE_NOISY, "Assuming %d.%d.%d.%d/%d [0x%08x/0x%08x]",
 
1162
                 a, b, c, d, bits, network, networkMask);
 
1163
    }
 
1164
#ifdef DEBUG
 
1165
    traceEvent(CONST_TRACE_INFO, "DEBUG: %d.%d.%d.%d/%d [0x%08x/0x%08x]",
 
1166
               a, b, c, d, bits, network, networkMask);
 
1167
#endif
 
1168
 
 
1169
    broadcast = network | (~networkMask);
 
1170
 
 
1171
#ifdef DEBUG
 
1172
    a = (int) ((broadcast >> 24) & 0xff);
 
1173
    b = (int) ((broadcast >> 16) & 0xff);
 
1174
    c = (int) ((broadcast >>  8) & 0xff);
 
1175
    d = (int) ((broadcast >>  0) & 0xff);
 
1176
 
 
1177
    traceEvent(CONST_TRACE_INFO, "DEBUG: Broadcast: [net=0x%08x] [broadcast=%d.%d.%d.%d]",
 
1178
               network, a, b, c, d);
 
1179
#endif
 
1180
 
 
1181
    if((*numNetworks) < MAX_NUM_NETWORKS) {
 
1182
      int found = 0;
 
1183
      /* If this is the real list, we check against the actual network addresses
 
1184
       * and warn the user of superfluous entries - for the other lists, rrd and netflow
 
1185
       * the local address is valid, it's NOT assumed.
 
1186
       */
 
1187
      if (flagWhat == CONST_HANDLEADDRESSLISTS_MAIN) {
 
1188
        for(i=0; i<myGlobals.numDevices; i++) {
 
1189
          if((network == myGlobals.device[i].network.s_addr) &&
 
1190
             (myGlobals.device[i].netmask.s_addr == networkMask)) {
 
1191
            a = (int) ((network >> 24) & 0xff);
 
1192
            b = (int) ((network >> 16) & 0xff);
 
1193
            c = (int) ((network >>  8) & 0xff);
 
1194
            d = (int) ((network >>  0) & 0xff);
 
1195
 
 
1196
            traceEvent(CONST_TRACE_INFO,
 
1197
                       "-m: Discarded unnecessary parameter %d.%d.%d.%d/%d - this is the local network",
 
1198
                       a, b, c, d, bits);
 
1199
            found = 1;
 
1200
          }
 
1201
        }
 
1202
      }
 
1203
 
 
1204
      if(found == 0) {
 
1205
        theNetworks[(*numNetworks)][CONST_NETWORK_ENTRY]    = network;
 
1206
        theNetworks[(*numNetworks)][CONST_NETMASK_ENTRY]    = networkMask;
 
1207
        theNetworks[(*numNetworks)][CONST_NETMASK_V6_ENTRY] = bits;
 
1208
        theNetworks[(*numNetworks)][CONST_BROADCAST_ENTRY]  = broadcast;
1053
1209
 
1054
1210
        a = (int) ((network >> 24) & 0xff);
1055
1211
        b = (int) ((network >> 16) & 0xff);
1056
1212
        c = (int) ((network >>  8) & 0xff);
1057
1213
        d = (int) ((network >>  0) & 0xff);
1058
1214
 
1059
 
        traceEvent(CONST_TRACE_NOISY, "Assuming %d.%d.%d.%d/%d [0x%08x/0x%08x]",
1060
 
                   a, b, c, d, bits, network, networkMask);
1061
 
      }
1062
 
#ifdef DEBUG
1063
 
      traceEvent(CONST_TRACE_INFO, "DEBUG: %d.%d.%d.%d/%d [0x%08x/0x%08x]",
1064
 
                 a, b, c, d, bits, network, networkMask);
1065
 
#endif
1066
 
 
1067
 
      broadcast = network | (~networkMask);
1068
 
 
1069
 
#ifdef DEBUG
1070
 
      a = (int) ((broadcast >> 24) & 0xff);
1071
 
      b = (int) ((broadcast >> 16) & 0xff);
1072
 
      c = (int) ((broadcast >>  8) & 0xff);
1073
 
      d = (int) ((broadcast >>  0) & 0xff);
1074
 
 
1075
 
      traceEvent(CONST_TRACE_INFO, "DEBUG: Broadcast: [net=0x%08x] [broadcast=%d.%d.%d.%d]",
1076
 
                 network, a, b, c, d);
1077
 
#endif
1078
 
 
1079
 
      if((*numNetworks) < MAX_NUM_NETWORKS) {
1080
 
        int found = 0;
1081
 
        /* If this is the real list, we check against the actual network addresses
1082
 
         * and warn the user of superfluous entries - for the other lists, rrd and netflow
1083
 
         * the local address is valid, it's NOT assumed.
1084
 
         */
1085
 
        if (flagWhat == CONST_HANDLEADDRESSLISTS_MAIN) {
1086
 
          for(i=0; i<myGlobals.numDevices; i++) {
1087
 
            if((network == myGlobals.device[i].network.s_addr) &&
1088
 
               (myGlobals.device[i].netmask.s_addr == networkMask)) {
1089
 
              a = (int) ((network >> 24) & 0xff);
1090
 
              b = (int) ((network >> 16) & 0xff);
1091
 
              c = (int) ((network >>  8) & 0xff);
1092
 
              d = (int) ((network >>  0) & 0xff);
1093
 
 
1094
 
              traceEvent(CONST_TRACE_INFO,
1095
 
                         "-m: Discarded unnecessary parameter %d.%d.%d.%d/%d - this is the local network",
1096
 
                         a, b, c, d, bits);
1097
 
              found = 1;
1098
 
            }
1099
 
          }
1100
 
        }
1101
 
 
1102
 
        if(found == 0) {
1103
 
          theNetworks[(*numNetworks)][CONST_NETWORK_ENTRY]   = network;
1104
 
          theNetworks[(*numNetworks)][CONST_NETMASK_ENTRY]   = networkMask;
1105
 
          theNetworks[(*numNetworks)][CONST_BROADCAST_ENTRY] = broadcast;
1106
 
 
1107
 
          a = (int) ((network >> 24) & 0xff);
1108
 
          b = (int) ((network >> 16) & 0xff);
1109
 
          c = (int) ((network >>  8) & 0xff);
1110
 
          d = (int) ((network >>  0) & 0xff);
1111
 
 
1112
 
          laBufferUsed = safe_snprintf(__FILE__, __LINE__, &localAddresses[laBufferPosition],
1113
 
                                       localAddressesLen,
1114
 
                                       "%s%d.%d.%d.%d/%d",
1115
 
                                       (*numNetworks) == 0 ? "" : ", ",
1116
 
                                       a, b, c, d,
1117
 
                                       bits);
1118
 
          if(laBufferUsed > 0) {
1119
 
            laBufferPosition  += laBufferUsed;
1120
 
            localAddressesLen -= laBufferUsed;
1121
 
          }
1122
 
 
1123
 
          (*numNetworks)++;
1124
 
 
1125
 
        }
1126
 
      } else {
1127
 
        a = (int) ((network >> 24) & 0xff);
1128
 
        b = (int) ((network >> 16) & 0xff);
1129
 
        c = (int) ((network >>  8) & 0xff);
1130
 
        d = (int) ((network >>  0) & 0xff);
1131
 
 
1132
 
        traceEvent(CONST_TRACE_ERROR, "%s: %d.%d.%d.%d/%d - Too many networks (limit %d) - discarded",
1133
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_MAIN ? "-m"  :
1134
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_RRD ? "RRD" :
1135
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_NETFLOW ? "Netflow" :
1136
 
                   flagWhat == CONST_HANDLEADDRESSLISTS_CLUSTERS ? "cluster" : "unknown",
1137
 
                   a, b, c, d, bits,
1138
 
                   MAX_NUM_NETWORKS);
1139
 
      }
 
1215
        laBufferUsed = safe_snprintf(__FILE__, __LINE__,
 
1216
                                     &localAddresses[laBufferPosition],
 
1217
                                     localAddressesLen,
 
1218
                                     "%s%d.%d.%d.%d/%d",
 
1219
                                     (*numNetworks) == 0 ? "" : ", ",
 
1220
                                     a, b, c, d,
 
1221
                                     bits);
 
1222
        if(laBufferUsed > 0) {
 
1223
          laBufferPosition  += laBufferUsed;
 
1224
          localAddressesLen -= laBufferUsed;
 
1225
        }
 
1226
 
 
1227
        (*numNetworks)++;
 
1228
 
 
1229
      }
 
1230
    } else {
 
1231
      a = (int) ((network >> 24) & 0xff);
 
1232
      b = (int) ((network >> 16) & 0xff);
 
1233
      c = (int) ((network >>  8) & 0xff);
 
1234
      d = (int) ((network >>  0) & 0xff);
 
1235
 
 
1236
      traceEvent(CONST_TRACE_ERROR,
 
1237
                 "%s: %d.%d.%d.%d/%d - Too many networks (limit %d) - discarded",
 
1238
                 flagWhat == CONST_HANDLEADDRESSLISTS_MAIN ? "-m"  :
 
1239
                 flagWhat == CONST_HANDLEADDRESSLISTS_RRD ? "RRD" :
 
1240
                 flagWhat == CONST_HANDLEADDRESSLISTS_NETFLOW ? "Netflow" :
 
1241
                 flagWhat == CONST_HANDLEADDRESSLISTS_CLUSTERS ? "cluster"  :
 
1242
                 flagWhat == CONST_HANDLEADDRESSLISTS_COMMUNITY ? "community" : "unknown",
 
1243
                 a, b, c, d, bits,
 
1244
                 MAX_NUM_NETWORKS);
1140
1245
    }
1141
1246
 
1142
1247
    address = strtok_r(NULL, ",", &strtokState);
1163
1268
/* ********************************* */
1164
1269
 
1165
1270
#ifdef INET6
1166
 
unsigned short in6_pseudoLocalAddress(struct in6_addr *addr) {
 
1271
unsigned short in6_pseudoLocalAddress(struct in6_addr *addr,
 
1272
                                      u_int32_t *the_local_network,
 
1273
                                      u_int32_t *the_local_network_mask) {
1167
1274
  int i;
1168
1275
 
1169
1276
  for(i=0; i<myGlobals.numDevices; i++) {
1170
1277
    if (prefixlookup(addr,myGlobals.device[i].v6Addrs,0) == 1)
1171
 
      return (1);
 
1278
      return(1);
1172
1279
 
1173
1280
  }
1174
1281
  return(0);
1175
1282
}
1176
1283
#endif
1177
1284
 
 
1285
/* ******************************************************* */
 
1286
 
1178
1287
unsigned short __pseudoLocalAddress(struct in_addr *addr,
1179
 
                                    u_int32_t theNetworks[MAX_NUM_NETWORKS][3],
1180
 
                                    u_short numNetworks) {
 
1288
                                    u_int32_t theNetworks[MAX_NUM_NETWORKS][4],
 
1289
                                    u_short numNetworks,
 
1290
                                    u_int32_t *the_local_network,
 
1291
                                    u_int32_t *the_local_network_mask) {
1181
1292
  int i;
1182
1293
 
 
1294
  if(the_local_network && the_local_network_mask)
 
1295
    (*the_local_network) = 0,  (*the_local_network_mask) = 0;
 
1296
 
1183
1297
  for(i=0; i<numNetworks; i++) {
1184
1298
#ifdef ADDRESS_DEBUG
1185
1299
    char buf[32], buf1[32], buf2[32];
1197
1311
#ifdef ADDRESS_DEBUG
1198
1312
      traceEvent(CONST_TRACE_WARNING, "ADDRESS_DEBUG: %s is pseudolocal", intoa(*addr));
1199
1313
#endif
1200
 
      return 1;
 
1314
      if(the_local_network && the_local_network_mask) {
 
1315
        (*the_local_network)      = theNetworks[i][CONST_NETWORK_ENTRY];
 
1316
        (*the_local_network_mask) = theNetworks[i][CONST_NETMASK_V6_ENTRY];
 
1317
      }
 
1318
      return(1);
1201
1319
    } else {
1202
1320
#ifdef ADDRESS_DEBUG
1203
1321
      traceEvent(CONST_TRACE_WARNING, "ADDRESS_DEBUG: %s is NOT pseudolocal", intoa(*addr));
1210
1328
 
1211
1329
/* ********************************* */
1212
1330
 
1213
 
unsigned short in_pseudoLocalAddress(struct in_addr *addr) {
1214
 
  return(__pseudoLocalAddress(addr, myGlobals.localNetworks, myGlobals.numLocalNetworks));
 
1331
unsigned short in_pseudoLocalAddress(struct in_addr *addr,
 
1332
                                     u_int32_t *the_local_network,
 
1333
                                     u_int32_t *the_local_network_mask) {
 
1334
  return(__pseudoLocalAddress(addr, myGlobals.localNetworks, myGlobals.numLocalNetworks,
 
1335
                              the_local_network, the_local_network_mask));
1215
1336
}
1216
1337
 
1217
1338
/* ********************************* */
1218
1339
 
1219
1340
#ifdef INET6
1220
 
unsigned short in6_deviceLocalAddress(struct in6_addr *addr, u_int deviceId) {
 
1341
unsigned short in6_deviceLocalAddress(struct in6_addr *addr, u_int deviceId,
 
1342
                                      u_int32_t *the_local_network,
 
1343
                                      u_int32_t *the_local_network_mask) {
1221
1344
  int rc;
1222
1345
 
1223
1346
  if(addrlookup(addr,myGlobals.device[deviceId].v6Addrs))
1231
1354
 
1232
1355
/* ********************************* */
1233
1356
 
1234
 
unsigned short in_deviceLocalAddress(struct in_addr *addr, u_int deviceId) {
 
1357
unsigned short in_deviceLocalAddress(struct in_addr *addr, u_int deviceId,
 
1358
                                     u_int32_t *the_local_network,
 
1359
                                     u_int32_t *the_local_network_mask) {
1235
1360
  int rc;
1236
1361
 
1237
1362
  if((addr->s_addr & myGlobals.device[deviceId].netmask.s_addr) == myGlobals.device[deviceId].network.s_addr)
1254
1379
/* ********************************* */
1255
1380
 
1256
1381
#ifdef INET6
1257
 
unsigned short in6_isPseudoLocalAddress(struct in6_addr *addr, u_int deviceId) {
 
1382
unsigned short in6_isPseudoLocalAddress(struct in6_addr *addr, u_int deviceId,
 
1383
                                        u_int32_t *the_local_network,
 
1384
                                        u_int32_t *the_local_network_mask) {
1258
1385
  int i;
1259
1386
 
1260
 
  i = in6_isLocalAddress(addr, deviceId);
 
1387
  i = in6_isLocalAddress(addr, deviceId, the_local_network, the_local_network_mask);
1261
1388
 
1262
1389
  if(i == 1) {
1263
1390
#ifdef ADDRESS_DEBUG
1267
1394
    return 1; /* This is a real local address */
1268
1395
  }
1269
1396
 
1270
 
  if(in6_pseudoLocalAddress(addr))
 
1397
  if(in6_pseudoLocalAddress(addr, the_local_network, the_local_network_mask))
1271
1398
    return 1;
1272
1399
 
1273
1400
  /*
1285
1412
 
1286
1413
/* ******************************************** */
1287
1414
 
 
1415
/* #define ADDRESS_DEBUG */
 
1416
 
1288
1417
/* This function returns true when a host is considered local
1289
1418
   as specified using the 'm' flag */
1290
 
unsigned short in_isPseudoLocalAddress(struct in_addr *addr, u_int deviceId) {
 
1419
unsigned short in_isPseudoLocalAddress(struct in_addr *addr, u_int deviceId,
 
1420
                                       u_int32_t *the_local_network,
 
1421
                                       u_int32_t *the_local_network_mask) {
1291
1422
  int i;
1292
1423
 
1293
 
  i = in_isLocalAddress(addr, deviceId);
 
1424
  /* FIX */
 
1425
  i = in_isLocalAddress(addr, deviceId, the_local_network, the_local_network_mask);
1294
1426
 
1295
1427
  if(i == 1) {
1296
1428
#ifdef ADDRESS_DEBUG
1300
1432
    return 1; /* This is a real local address */
1301
1433
  }
1302
1434
 
1303
 
  if(in_pseudoLocalAddress(addr))
 
1435
  if(in_pseudoLocalAddress(addr, the_local_network, the_local_network_mask))
1304
1436
    return 1;
1305
1437
 
1306
1438
  /*
1316
1448
  return(0);
1317
1449
}
1318
1450
 
 
1451
/* #undef ADDRESS_DEBUG */
 
1452
 
1319
1453
/* ********************************* */
1320
1454
 
1321
1455
/* This function returns true when an address is the broadcast
1322
1456
   for the specified (-m flag subnets */
1323
1457
 
1324
 
unsigned short in_isPseudoBroadcastAddress(struct in_addr *addr) {
 
1458
unsigned short in_isPseudoBroadcastAddress(struct in_addr *addr,
 
1459
                                           u_int32_t *the_local_network,
 
1460
                                           u_int32_t *the_local_network_mask) {
1325
1461
  int i;
1326
1462
 
1327
1463
#ifdef ADDRESS_DEBUG
1346
1482
 
1347
1483
/*************************************/
1348
1484
 
1349
 
unsigned short deviceLocalAddress(HostAddr *addr, u_int deviceId) {
1350
 
  switch(addr->hostFamily) {
1351
 
  case AF_INET:
1352
 
    return (in_deviceLocalAddress(&addr->Ip4Address, deviceId));
1353
 
#ifdef INET6
1354
 
  case AF_INET6:
1355
 
    return (in6_deviceLocalAddress(&addr->Ip6Address, deviceId));
1356
 
#endif
1357
 
  default: return(0);
1358
 
  }
1359
 
}
1360
 
 
1361
 
/* ********************************* */
1362
 
 
1363
 
unsigned short isPseudoLocalAddress(HostAddr *addr, u_int deviceId) {
1364
 
  switch(addr->hostFamily) {
1365
 
  case AF_INET:
1366
 
    return (in_isPseudoLocalAddress(&addr->Ip4Address, deviceId));
1367
 
#ifdef INET6
1368
 
  case AF_INET6:
1369
 
    return (in6_isPseudoLocalAddress(&addr->Ip6Address, deviceId));
1370
 
#endif
1371
 
  default: return(0);
1372
 
  }
1373
 
}
1374
 
 
1375
 
/* ********************************* */
1376
 
 
1377
 
unsigned short isPseudoBroadcastAddress(HostAddr *addr) {
1378
 
  switch(addr->hostFamily) {
1379
 
  case AF_INET:
1380
 
    return (in_isPseudoBroadcastAddress(&addr->Ip4Address));
 
1485
unsigned short deviceLocalAddress(HostAddr *addr, u_int deviceId,
 
1486
                                  u_int32_t *the_local_network,
 
1487
                                  u_int32_t *the_local_network_mask) {
 
1488
  switch(addr->hostFamily) {
 
1489
  case AF_INET:
 
1490
    return (in_deviceLocalAddress(&addr->Ip4Address, deviceId, the_local_network, the_local_network_mask));
 
1491
#ifdef INET6
 
1492
  case AF_INET6:
 
1493
    return (in6_deviceLocalAddress(&addr->Ip6Address, deviceId, NULL, NULL));
 
1494
#endif
 
1495
  default: return(0);
 
1496
  }
 
1497
}
 
1498
 
 
1499
/* ********************************* */
 
1500
 
 
1501
unsigned short isPseudoLocalAddress(HostAddr *addr, u_int deviceId,
 
1502
                                    u_int32_t *the_local_network,
 
1503
                                    u_int32_t *the_local_network_mask) {
 
1504
 
 
1505
  if(the_local_network && the_local_network_mask)
 
1506
    (*the_local_network) = 0,  (*the_local_network_mask) = 0;
 
1507
 
 
1508
  switch(addr->hostFamily) {
 
1509
  case AF_INET:
 
1510
    return (in_isPseudoLocalAddress(&addr->Ip4Address, deviceId, the_local_network, the_local_network_mask));
 
1511
#ifdef INET6
 
1512
  case AF_INET6:
 
1513
    return (in6_isPseudoLocalAddress(&addr->Ip6Address, deviceId, NULL, NULL));
 
1514
#endif
 
1515
  default: return(0);
 
1516
  }
 
1517
}
 
1518
 
 
1519
/* ********************************* */
 
1520
 
 
1521
unsigned short isPseudoBroadcastAddress(HostAddr *addr,
 
1522
                                        u_int32_t *the_local_network,
 
1523
                                        u_int32_t *the_local_network_mask) {
 
1524
  switch(addr->hostFamily) {
 
1525
  case AF_INET:
 
1526
    return (in_isPseudoBroadcastAddress(&addr->Ip4Address, the_local_network, the_local_network_mask));
1381
1527
#ifdef INET6
1382
1528
  case AF_INET6:
1383
1529
    return 0;
1388
1534
 
1389
1535
/* ********************************* */
1390
1536
 
1391
 
unsigned short _pseudoLocalAddress(HostAddr *addr) {
 
1537
unsigned short _pseudoLocalAddress(HostAddr *addr,
 
1538
                                   u_int32_t *the_local_network,
 
1539
                                   u_int32_t *the_local_network_mask) {
1392
1540
  switch(addr->hostFamily) {
1393
1541
  case AF_INET:
1394
 
    return (in_pseudoLocalAddress(&addr->Ip4Address));
 
1542
    return (in_pseudoLocalAddress(&addr->Ip4Address, the_local_network, the_local_network_mask));
1395
1543
#ifdef INET6
1396
1544
  case AF_INET6:
1397
 
    return (in6_pseudoLocalAddress(&addr->Ip6Address));
 
1545
    return (in6_pseudoLocalAddress(&addr->Ip6Address, NULL, NULL));
1398
1546
#endif
1399
1547
  default: return(0);
1400
1548
  }
1551
1699
            newFlow->fcode = (struct bpf_program*)calloc(myGlobals.numDevices, sizeof(struct bpf_program));
1552
1700
 
1553
1701
            for(i=0; i<myGlobals.numDevices; i++) {
1554
 
              rc = pcap_compile(myGlobals.device[i].pcapPtr, &newFlow->fcode[i],
1555
 
                                flowSpec, 1, myGlobals.device[i].netmask.s_addr);
1556
 
 
1557
 
              if(rc < 0) {
1558
 
                traceEvent(CONST_TRACE_WARNING, "Wrong flow specification \"%s\" (syntax error). "
1559
 
                           "It has been ignored.", flowSpec);
1560
 
                free(newFlow);
1561
 
 
1562
 
                /* Not used anymore */
1563
 
                free(myGlobals.runningPref.flowSpecs);
1564
 
                myGlobals.runningPref.flowSpecs = strdup("Error, wrong flow specification");
1565
 
                return;
1566
 
              }
 
1702
              if(myGlobals.device[i].pcapPtr
 
1703
                 && (!myGlobals.device[i].virtualDevice)
 
1704
                 /* Fix courtesy of David Fabel <david.fabel@sudop.cz> */
 
1705
                 ) {
 
1706
                rc = pcap_compile(myGlobals.device[i].pcapPtr, &newFlow->fcode[i],
 
1707
                                  flowSpec, 1, myGlobals.device[i].netmask.s_addr);
 
1708
 
 
1709
                if(rc < 0) {
 
1710
                  traceEvent(CONST_TRACE_WARNING, "Wrong flow specification \"%s\" (syntax error). "
 
1711
                             "It has been ignored.", flowSpec);
 
1712
                  free(newFlow);
 
1713
 
 
1714
                  /* Not used anymore */
 
1715
                  free(myGlobals.runningPref.flowSpecs);
 
1716
                  myGlobals.runningPref.flowSpecs = strdup("Error, wrong flow specification");
 
1717
                  return;
 
1718
                }
 
1719
              }
1567
1720
            }
1568
1721
 
1569
1722
            newFlow->flowName = strdup(flowName);
1586
1739
 
1587
1740
/* ********************************* */
1588
1741
 
1589
 
int getLocalHostAddress(struct in_addr *hostAddress, char* device) {
 
1742
int getLocalHostAddress(struct in_addr *hostAddress, u_int8_t *netmask_v6, char* device) {
1590
1743
  int rc = 0;
1591
1744
#ifdef WIN32
1592
1745
  hostAddress->s_addr = GetHostIPAddr();
1593
1746
  return(0);
1594
1747
#else
1595
 
  int fd;
 
1748
  int fd, numHosts;
1596
1749
  struct sockaddr_in *sinAddr;
1597
1750
  struct ifreq ifr;
1598
1751
#ifdef DEBUG
1630
1783
 
1631
1784
  /* ******************************* */
1632
1785
 
1633
 
#ifdef DEBUG
1634
 
  {
1635
 
    int numHosts;
1636
 
 
1637
 
    if(ioctl(fd, SIOCGIFNETMASK, (char*)&ifr) >= 0) {
1638
 
      sinAddr = (struct sockaddr_in *)&ifr.ifr_broadaddr;
1639
 
      numHosts = 0xFFFFFFFF - ntohl(sinAddr->sin_addr.s_addr)+1;
1640
 
    } else
1641
 
      numHosts = 256; /* default C class */
1642
 
 
1643
 
    traceEvent(CONST_TRACE_INFO, "DEBUG: Num subnet hosts: %d", numHosts);
 
1786
  if(ioctl(fd, SIOCGIFNETMASK, (char*)&ifr) >= 0) {
 
1787
    sinAddr = (struct sockaddr_in *)&ifr.ifr_broadaddr;
 
1788
    numHosts = 0xFFFFFFFF - ntohl(sinAddr->sin_addr.s_addr)+1;
 
1789
  } else
 
1790
    numHosts = 256; /* default C class */
 
1791
 
 
1792
  (*netmask_v6) = 0;
 
1793
 
 
1794
  while(numHosts > 0) {
 
1795
    numHosts = numHosts >> 1;
 
1796
    (*netmask_v6)++;
1644
1797
  }
1645
 
#endif
 
1798
 
 
1799
  // traceEvent(CONST_TRACE_INFO, "DEBUG: Num subnet hosts: %d", numHosts);
1646
1800
 
1647
1801
  /* ******************************* */
1648
1802
 
1667
1821
 
1668
1822
  if(rc != 0)
1669
1823
    traceEvent(CONST_TRACE_NOISY, "THREADMGMT[t%lu]: pthread_create(), rc = %s(%d)",
1670
 
               threadId, strerror(rc), rc);
 
1824
               (long unsigned int)threadId, strerror(rc), rc);
1671
1825
  myGlobals.numThreads++;
1672
1826
  return(rc);
1673
1827
}
1685
1839
 
1686
1840
  if((rc = pthread_detach(*threadId)) != 0) {
1687
1841
    traceEvent(CONST_TRACE_NOISY, "THREADMGMT[t%lu]: pthread_detach(), rc = %s(%d)",
1688
 
               threadId, strerror(rc), rc);
 
1842
               (long unsigned int)threadId, strerror(rc), rc);
1689
1843
  }
1690
1844
 
1691
1845
  myGlobals.numThreads--;
1705
1859
 
1706
1860
  if((rc = pthread_join(*threadId, NULL)) != 0) {
1707
1861
    traceEvent(CONST_TRACE_NOISY, "THREADMGMT[t%lu]: pthread_join(), rc = %s(%d)",
1708
 
               threadId, strerror(rc), rc);
 
1862
               (long unsigned int)threadId, strerror(rc), rc);
1709
1863
  }
1710
1864
 
1711
1865
  return(rc);
1793
1947
    if(myGlobals.ntopRunState <= FLAG_NTOPSTATE_RUN)
1794
1948
      traceEvent(CONST_TRACE_ERROR,
1795
1949
                 "accessMutex() called '%s' with a NULL mutex [t%lu mNULL @%s:%d]",
1796
 
                 where, pthread_self(), (void*)&(mutexId->mutex), fileName, fileLine);
 
1950
                 where, pthread_self(), fileName, fileLine);
1797
1951
    return(-1);
1798
1952
  }
1799
1953
 
1867
2021
    if(myGlobals.ntopRunState <= FLAG_NTOPSTATE_RUN)
1868
2022
      traceEvent(CONST_TRACE_ERROR,
1869
2023
                 "tryLockMutex() called '%s' with a NULL mutex [t%lu mNULL @%s:%d]",
1870
 
                 where, pthread_self(), (void*)&(mutexId->mutex), fileName, fileLine);
 
2024
                 where, pthread_self(), fileName, fileLine);
1871
2025
    return(-1);
1872
2026
  }
1873
2027
 
1952
2106
  }
1953
2107
 
1954
2108
  if(!mutexId->isLocked) {
1955
 
    traceEvent(CONST_TRACE_WARNING, "releaseMutex() called with an UN-LOCKED mutex [t%lu m%p @%s:%d] last unlock [t%lu m%p @%s:%d]",
 
2109
    traceEvent(CONST_TRACE_WARNING, "releaseMutex() called with an UN-LOCKED mutex [t%lu m%p @%s:%d] last unlock [t%lu m%u @%s:%d]",
1956
2110
               pthread_self(), (void*)&(mutexId->mutex), fileName, fileLine,
1957
 
               mutexId->unlock.thread, mutexId->unlock.pid, mutexId->unlock.file, mutexId->unlock.line);
 
2111
               mutexId->unlock.thread, (int)mutexId->unlock.pid, 
 
2112
               mutexId->unlock.file, mutexId->unlock.line);
1958
2113
 
1959
2114
  }
1960
2115
 
2082
2237
#undef _lockHostsHashMutex
2083
2238
int _lockHostsHashMutex(HostTraffic *host, char *where, char *file, int line) {
2084
2239
  int rc = 0;
2085
 
  
 
2240
 
2086
2241
  if(host) {
 
2242
    if(0)
 
2243
      traceEvent(CONST_TRACE_INFO, "==> lockHostsHashMutex(idx=%d) [%s:%d]",
 
2244
                 host->hostTrafficBucket, file, line);
 
2245
 
2087
2246
    _accessMutex(&myGlobals.hostsHashLockMutex, "lockHostsHashMutex", file, line);
2088
2247
    if(myGlobals.hostsHashMutexNumLocks[host->hostTrafficBucket] == 0) {
2089
2248
      myGlobals.hostsHashMutexNumLocks[host->hostTrafficBucket]++;
2090
2249
      _accessMutex(&myGlobals.hostsHashMutex[host->hostTrafficBucket], where, file, line);
2091
2250
    } else {
2092
 
          /* Already locked */
2093
 
      myGlobals.hostsHashMutexNumLocks[host->hostTrafficBucket]++; 
 
2251
      /* Already locked */
 
2252
      myGlobals.hostsHashMutexNumLocks[host->hostTrafficBucket]++;
2094
2253
    }
2095
2254
    _releaseMutex(&myGlobals.hostsHashLockMutex, file, line);
2096
2255
  } else {
2107
2266
  int rc;
2108
2267
 
2109
2268
  if(host) {
 
2269
    if(0)
 
2270
      traceEvent(CONST_TRACE_INFO, "==> unlockHostsHashMutex(idx=%d) [%s:%d]",
 
2271
                 host->hostTrafficBucket, file, line);
 
2272
 
2110
2273
    accessMutex(&myGlobals.hostsHashLockMutex, "unlockHostsHashMutex");
2111
2274
    if(myGlobals.hostsHashMutexNumLocks[host->hostTrafficBucket] > 1) {
2112
2275
      myGlobals.hostsHashMutexNumLocks[host->hostTrafficBucket]--;
2116
2279
      rc = releaseMutex(&myGlobals.hostsHashMutex[host->hostTrafficBucket]);
2117
2280
    } else {
2118
2281
      /* myGlobals.hostsHashMutexNumLocks[host->hostTrafficBucket] == 0 */
2119
 
      traceEvent(CONST_TRACE_WARNING, "Error: attempting to unlock an unlocked mutex from %s(%d)",
 
2282
      traceEvent(CONST_TRACE_WARNING, "Error: attempting to unlock an unlocked mutex from %s:%d",
2120
2283
                 file, line);
2121
2284
      rc = 0;
2122
2285
    }
2291
2454
/* ******************************* */
2292
2455
 
2293
2456
char* getNwInterfaceType(int i) {
2294
 
  switch(myGlobals.device[i].datalink) {
2295
 
  case DLT_NULL:        return("No&nbsp;link-layer&nbsp;encapsulation");
2296
 
  case DLT_EN10MB:      return("Ethernet");
2297
 
  case DLT_EN3MB:       return("Experimental&nbsp;Ethernet&nbsp;(3Mb)");
2298
 
  case DLT_AX25:        return("Amateur&nbsp;Radio&nbsp;AX.25");
2299
 
  case DLT_PRONET:      return("Proteon&nbsp;ProNET&nbsp;Token&nbsp;Ring");
2300
 
  case DLT_CHAOS:       return("Chaos");
2301
 
  case DLT_IEEE802:     return("IEEE&nbsp;802&nbsp;Networks");
2302
 
  case DLT_ARCNET:      return("ARCNET");
2303
 
  case DLT_SLIP:        return("SLIP");
2304
 
  case DLT_PPP:         return("PPP");
2305
 
  case DLT_FDDI:        return("FDDI");
2306
 
  case DLT_ATM_RFC1483: return("LLC/SNAP&nbsp;encapsulated&nbsp;ATM");
2307
 
  case DLT_RAW:         return("Raw&nbsp;IP");
2308
 
  case DLT_SLIP_BSDOS:  return("BSD/OS&nbsp;SLIP");
2309
 
  case DLT_PPP_BSDOS:   return("BSD/OS&nbsp;PPP");
2310
 
  }
2311
 
 
2312
 
  return(""); /* NOTREACHED (I hope) */
 
2457
  return((char*)pcap_datalink_val_to_description(myGlobals.device[i].datalink));
2313
2458
}
2314
2459
 
2315
2460
/* ************************************ */
2331
2476
  resetUsageCounter(&el->contactedRcvdPeers);
2332
2477
  resetUsageCounter(&el->contactedRouters);
2333
2478
 
2334
 
  el->vlanId = -1;
 
2479
  el->vlanId = NO_VLAN;
 
2480
  el->ifId = NO_INTERFACE;
2335
2481
  el->hostAS = 0;
2336
2482
  if (el->dnsDomainValue != NULL)      free(el->dnsDomainValue);
2337
2483
  el->dnsDomainValue = NULL;
2535
2681
      mFile = strdup(file);
2536
2682
 
2537
2683
      if(mFile) {
 
2684
#ifdef WIN32
2538
2685
        for(beginFileIdx=strlen(mFile)-1; beginFileIdx>0; beginFileIdx--) {
2539
 
          if(mFile[beginFileIdx] == '.') mFile[beginFileIdx] = '\0'; /* Strip off .c */
 
2686
          // if(mFile[beginFileIdx] == '.') mFile[beginFileIdx] = '\0'; /* Strip off .c */
2540
2687
#if defined(WIN32)
2541
2688
          if(mFile[beginFileIdx-1] == '\\') break;  /* Start after \ (Win32)  */
2542
2689
#else
2543
2690
          if(mFile[beginFileIdx-1] == '/') break;   /* Start after / (!Win32) */
2544
2691
#endif
2545
2692
        }
 
2693
#endif
2546
2694
 
2547
2695
        if(myGlobals.runningPref.traceLevel >= CONST_DETAIL_TRACE_LEVEL) {
2548
2696
          unsigned int messageid = 0;
2549
2697
          int i;
2550
2698
 
2551
 
          safe_snprintf(__FILE__, __LINE__, bufLineID, sizeof(bufLineID), "[t%lu %s:%d] ", pthread_self(), &mFile[beginFileIdx], line);
 
2699
#ifdef LONG_FORMAT
 
2700
          safe_snprintf(__FILE__, __LINE__, bufLineID, sizeof(bufLineID), "[t%lu %s:%d] ",
 
2701
                        pthread_self(), &mFile[beginFileIdx], line);
 
2702
#else
 
2703
          safe_snprintf(__FILE__, __LINE__, bufLineID, sizeof(bufLineID), "[%s:%d] ",
 
2704
                        &mFile[beginFileIdx], line);
 
2705
#endif
2552
2706
 
 
2707
#if 0
2553
2708
          /* Hash the message format into an id */
2554
2709
          for (i=0; i<=strlen(format); i++) {
2555
2710
            messageid = (messageid << 1) ^ max(0,format[i]-32);
2558
2713
          /* 1st chars of file name for uniqueness */
2559
2714
          messageid += (file[0]-32) * 256 + file[1]-32;
2560
2715
          safe_snprintf(__FILE__, __LINE__, bufMsgID, sizeof(bufMsgID), "[MSGID%07d]", (messageid & 0x8fffff));
 
2716
#endif
2561
2717
        }
2562
2718
 
2563
2719
        free(mFile);
2585
2741
 
2586
2742
    /* Finished preparing message fields */
2587
2743
 
2588
 
    /* So, (INFO & above only) - post it to logView buffer. */
2589
 
    if ((eventTraceLevel <= CONST_INFO_TRACE_LEVEL) &&
2590
 
        (myGlobals.logView != NULL)) {
2591
 
 
2592
 
      if(myGlobals.logViewMutex.isInitialized) {
2593
 
#ifdef WIN32
2594
 
        WaitForSingleObject(myGlobals.logViewMutex.mutex, INFINITE);
2595
 
#else
2596
 
        pthread_mutex_lock(&myGlobals.logViewMutex.mutex);
2597
 
#endif
2598
 
      }
2599
 
 
2600
 
      if (myGlobals.logView[myGlobals.logViewNext] != NULL)
2601
 
        free(myGlobals.logView[myGlobals.logViewNext]);
2602
 
 
2603
 
      myGlobals.logView[myGlobals.logViewNext] = strdup(buf);
2604
 
 
2605
 
      myGlobals.logViewNext = (myGlobals.logViewNext + 1) % CONST_LOG_VIEW_BUFFER_SIZE;
2606
 
 
2607
 
      if(myGlobals.logViewMutex.isInitialized) {
2608
 
#ifdef WIN32
2609
 
        ReleaseMutex(myGlobals.logViewMutex.mutex);
2610
 
#else
2611
 
        pthread_mutex_unlock(&myGlobals.logViewMutex.mutex);
2612
 
#endif
 
2744
    if(myGlobals.ntopRunState < FLAG_NTOPSTATE_SHUTDOWN) {
 
2745
      /* So, (INFO & above only) - post it to logView buffer. */
 
2746
      if ((eventTraceLevel <= CONST_INFO_TRACE_LEVEL) &&
 
2747
          (myGlobals.logView != NULL)) {
 
2748
 
 
2749
        if(myGlobals.logViewMutex.isInitialized) {
 
2750
#ifdef WIN32
 
2751
          WaitForSingleObject(myGlobals.logViewMutex.mutex, INFINITE);
 
2752
#else
 
2753
          pthread_mutex_lock(&myGlobals.logViewMutex.mutex);
 
2754
#endif
 
2755
        }
 
2756
 
 
2757
        if (myGlobals.logView[myGlobals.logViewNext] != NULL)
 
2758
          free(myGlobals.logView[myGlobals.logViewNext]);
 
2759
 
 
2760
        myGlobals.logView[myGlobals.logViewNext] = strdup(buf);
 
2761
 
 
2762
        myGlobals.logViewNext = (myGlobals.logViewNext + 1) % CONST_LOG_VIEW_BUFFER_SIZE;
 
2763
 
 
2764
        if(myGlobals.logViewMutex.isInitialized) {
 
2765
#ifdef WIN32
 
2766
          ReleaseMutex(myGlobals.logViewMutex.mutex);
 
2767
#else
 
2768
          pthread_mutex_unlock(&myGlobals.logViewMutex.mutex);
 
2769
#endif
 
2770
        }
2613
2771
      }
2614
2772
    }
2615
2773
 
2708
2866
 
2709
2867
/* ******************************************** */
2710
2868
 
 
2869
#ifndef WIN32
2711
2870
/* Courtesy of Andreas Pfaller <apfaller@yahoo.com.au> */
2712
2871
#ifndef HAVE_STRTOK_R
2713
2872
/* Reentrant string tokenizer.  Generic myGlobals.version.
2758
2917
  return token;
2759
2918
}
2760
2919
#endif
 
2920
#endif
2761
2921
 
2762
2922
/* ********************************** */
2763
2923
 
2902
3062
void uriSanityCheck(char* string, char* parm, int allowParms) {
2903
3063
  int i, j;
2904
3064
 
2905
 
//      Our reduced BNF is:
2906
 
//            relativeURI    = ["/" ] fsegment *( "/" segment )
2907
 
//            fsegment       = 1*pchar
2908
 
//            segment        = *pchar
2909
 
//     
2910
 
//            pchar          = unreserved | ":" | "@" | "&" | "=" | "+"
2911
 
//            unreserved     = ALPHA | DIGIT | safe | extra | national
2912
 
//     
2913
 
//            reserved       = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"
2914
 
//                                    ^--- is legal character as segment sep.
2915
 
//            extra          = "!" | "*" | "'" | "(" | ")" | ","
2916
 
//            safe           = "$" | "-" | "_" | "."
2917
 
//            unsafe         = CTL | SP | <"> | "#" | "%" | "<" | ">"
2918
 
//            national       = <any OCTET excluding ALPHA, DIGIT,
2919
 
//                             reserved, extra, safe, and unsafe> 
2920
 
//      And we look for reserved or unsafe chars.
 
3065
  //      Our reduced BNF is:
 
3066
  //            relativeURI    = ["/" ] fsegment *( "/" segment )
 
3067
  //            fsegment       = 1*pchar
 
3068
  //            segment        = *pchar
 
3069
  //
 
3070
  //            pchar          = unreserved | ":" | "@" | "&" | "=" | "+"
 
3071
  //            unreserved     = ALPHA | DIGIT | safe | extra | national
 
3072
  //
 
3073
  //            reserved       = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"
 
3074
  //                                    ^--- is legal character as segment sep.
 
3075
  //            extra          = "!" | "*" | "'" | "(" | ")" | ","
 
3076
  //            safe           = "$" | "-" | "_" | "."
 
3077
  //            unsafe         = CTL | SP | <"> | "#" | "%" | "<" | ">"
 
3078
  //            national       = <any OCTET excluding ALPHA, DIGIT,
 
3079
  //                             reserved, extra, safe, and unsafe>
 
3080
  //      And we look for reserved or unsafe chars.
2921
3081
 
2922
 
// If this is a URI which we allow parms in, then we add ? & to the valid chars
2923
 
// We add : as legal for Port specification
 
3082
  // If this is a URI which we allow parms in, then we add ? & to the valid chars
 
3083
  // We add : as legal for Port specification
2924
3084
 
2925
3085
  if(string == NULL)  {
2926
3086
    traceEvent(CONST_TRACE_FATALERROR, "Invalid (empty) uri specified for option %s", parm);
2933
3093
      string[i]='.';
2934
3094
      j = 0;
2935
3095
    } else switch(string[i]) {
2936
 
      case ';':
2937
 
      case '@':
2938
 
      case '+':
2939
 
      case '"':
2940
 
      case '#':
2941
 
      case '%':
2942
 
      case '<':
2943
 
      case '>':
2944
 
      case '\\':  /* Add this one for directory traversal */
2945
 
        string[i]='.';
2946
 
        j=0;
2947
 
        break;
2948
 
      case '=':
2949
 
      case '?':
2950
 
      case '&':
2951
 
        if(allowParms == FALSE) {
2952
 
          string[i]='.';
2953
 
          j=0;
2954
 
        }
2955
 
        break;
 
3096
    case ';':
 
3097
    case '@':
 
3098
    case '+':
 
3099
    case '"':
 
3100
    case '#':
 
3101
    case '%':
 
3102
    case '<':
 
3103
    case '>':
 
3104
    case '\\':  /* Add this one for directory traversal */
 
3105
      string[i]='.';
 
3106
      j=0;
 
3107
      break;
 
3108
    case '=':
 
3109
    case '?':
 
3110
    case '&':
 
3111
      if(allowParms == FALSE) {
 
3112
        string[i]='.';
 
3113
        j=0;
 
3114
      }
 
3115
      break;
2956
3116
    }
2957
3117
  }
2958
3118
 
2972
3132
 
2973
3133
  static char paChar[256];
2974
3134
 
2975
 
// Common:
2976
 
//     Upper and lower case letters:  A - Z and a - z  
2977
 
//     Numbers  0 - 9  
2978
 
//     Period, underscore, hyphen  . _ -  
2979
 
 
2980
 
// Unix:
2981
 
//     Slash
2982
 
//     Comma
2983
 
 
2984
 
// Win
2985
 
//     Backslash
2986
 
//     Colon, quotes, space
 
3135
  // Common:
 
3136
  //     Upper and lower case letters:  A - Z and a - z
 
3137
  //     Numbers  0 - 9
 
3138
  //     Period, underscore, hyphen  . _ -
 
3139
 
 
3140
  // Unix:
 
3141
  //     Slash
 
3142
  //     Comma
 
3143
 
 
3144
  // Win
 
3145
  //     Backslash
 
3146
  //     Colon, quotes, space
2987
3147
 
2988
3148
  if(string == NULL)  {
2989
3149
    traceEvent(CONST_TRACE_FATALERROR, "Invalid (empty) path specified for option %s", parm);
3014
3174
  /* Strip "ed string for test */
3015
3175
  if((string[0] != '"') || (string[strlen(string)-1] != '"') )
3016
3176
    k=1;
 
3177
 
 
3178
        revertSlashIfWIN32(string, 0);
3017
3179
#endif
3018
3180
 
 
3181
  
3019
3182
  for(i=k, j=1; i<strlen(string)-k; i++) {
3020
 
    if(paChar[string[i]] == 0) {
 
3183
    int idx = string[i];
 
3184
 
 
3185
    if(paChar[idx] == 0) {
3021
3186
      string[i]='.';
3022
3187
      j = 0;
3023
3188
    }
3034
3199
 
3035
3200
/* ************************** */
3036
3201
 
 
3202
void sanitize_rrd_string(char* name) {
 
3203
  int i;
 
3204
 
 
3205
  /* Sanitize name for RRD */
 
3206
  for(i=0; i<strlen(name); i++) {
 
3207
    switch(name[i]) {
 
3208
    case ' ':
 
3209
    case ':':
 
3210
      name[i] = '_';
 
3211
    }
 
3212
  }
 
3213
}
 
3214
 
 
3215
/* ************************** */
 
3216
 
3037
3217
int fileSanityCheck(char* string, char* parm, int nonFatal) {
3038
3218
  int i, j, k;
3039
3219
 
3040
3220
  static char fnChar[256];
3041
3221
 
3042
 
// Common:
3043
 
//     Upper and lower case letters:  A - Z and a - z  
3044
 
//     Numbers  0 - 9  
3045
 
//     Period, underscore, hyphen  . _ -  
3046
 
 
3047
 
// Unix:
3048
 
//     Comma
3049
 
 
3050
 
// Win
3051
 
//     Colon, quotes, space
 
3222
  // Common:
 
3223
  //     Upper and lower case letters:  A - Z and a - z
 
3224
  //     Numbers  0 - 9
 
3225
  //     Period, underscore, hyphen  . _ -
 
3226
 
 
3227
  // Unix:
 
3228
  //     Comma
 
3229
 
 
3230
  // Win
 
3231
  //     Colon, quotes, space
3052
3232
 
3053
3233
  if(string == NULL)  {
3054
3234
 
3080
3260
 
3081
3261
  if(strlen(string) > 0) {
3082
3262
#ifdef WIN32
3083
 
  /* Strip "ed string for test */
3084
 
  if((string[0] != '"') || (string[strlen(string)-1] != '"') )
3085
 
    k=1;
3086
 
#endif
3087
 
 
3088
 
#ifdef DEBUG
3089
 
  traceEvent(CONST_TRACE_INFO, "Sanitizing string '%s'", string);
3090
 
#endif
3091
 
 
3092
 
  for(i=k, j=1; i<strlen(string)-k; i++) {
3093
 
    if(fnChar[string[i]] == 0) {
3094
 
#ifdef DEBUG
3095
 
      traceEvent(CONST_TRACE_INFO, "Sanitized invalid char '%c'", string[i]);
3096
 
#endif
3097
 
      string[i]='.';
3098
 
      j = 0;
 
3263
    /* Strip "ed string for test */
 
3264
    if((string[0] != '"') || (string[strlen(string)-1] != '"') )
 
3265
      k=1;
 
3266
#endif
 
3267
 
 
3268
#ifdef DEBUG
 
3269
    traceEvent(CONST_TRACE_INFO, "Sanitizing string '%s'", string);
 
3270
#endif
 
3271
 
 
3272
    for(i=k, j=1; i<strlen(string)-k; i++) {
 
3273
      int idx = string[i];
 
3274
 
 
3275
      if(fnChar[idx] == 0) {
 
3276
#ifdef DEBUG
 
3277
        traceEvent(CONST_TRACE_INFO, "Sanitized invalid char '%c'", idx);
 
3278
#endif
 
3279
        string[i]='.';
 
3280
        j = 0;
 
3281
      }
3099
3282
    }
3100
 
  }
3101
3283
  } else
3102
 
          j = 0;
 
3284
    j = 0;
3103
3285
 
3104
3286
  if(j == 0) {
3105
3287
    if(strlen(string) > 40) string[40] = '\0';
3116
3298
/* ************************** */
3117
3299
 
3118
3300
int ipSanityCheck(char* string, char* parm, int nonFatal) {
3119
 
  int i, j, rc = 0;
 
3301
  int i, j;
3120
3302
  static char ipChar[256];
3121
3303
 
3122
3304
  // Common:
3124
3306
  //     .
3125
3307
  //
3126
3308
  // INET6
3127
 
  //     Upper and lower case letters:  A - Z and a - z  
 
3309
  //     Upper and lower case letters:  A - Z and a - z
3128
3310
  //     :
3129
3311
 
3130
3312
  if(string == NULL)  {
3146
3328
  }
3147
3329
 
3148
3330
  for(i=0, j=1; i<strlen(string); i++) {
3149
 
    if(ipChar[string[i]] == 0) {
 
3331
    int idx = string[i];
 
3332
 
 
3333
    if(ipChar[idx] == 0) {
3150
3334
      string[i]='x';
3151
3335
      j = 0;
3152
3336
    }
3317
3501
    el->dnsTLDValue = strdup(&el->hostResolvedName[i+1]);
3318
3502
  else if (myGlobals.shortDomainName != NULL) {
3319
3503
    /* Walk back to the last . */
3320
 
    i = strlen(el->hostResolvedName)-1;
 
3504
    i = strlen(myGlobals.shortDomainName)-1;
3321
3505
    while(i > 0)
3322
3506
      if(myGlobals.shortDomainName[i] == '.')
3323
3507
        break;
3412
3596
        if(theHost->hostResolvedName[0] == '\0') {
3413
3597
          int i;
3414
3598
 
3415
 
          for(i=0; i<strlen(nbName); i++) if(isupper(nbName[i])) tolower(nbName[i]);
 
3599
          for(i=0; i<strlen(nbName); i++) {
 
3600
            if(isupper(nbName[i])) 
 
3601
              nbName[i] = tolower(nbName[i]);
 
3602
          }
 
3603
 
3416
3604
          setResolvedName(theHost, nbName, FLAG_HOST_SYM_ADDR_TYPE_NETBIOS);
3417
3605
        }
3418
3606
 
3457
3645
  traceEvent(CONST_TRACE_INFO, "DEBUG: Adding %ld:%d", theHost, thePort);
3458
3646
#endif
3459
3647
 
3460
 
  for(i=0; i<ptr_len; i++) {
3461
 
    if((ptr[i].sessionPort == 0)
3462
 
       || (ptr[i].creationTime < timeoutTime)) {
3463
 
      /* Autopurge */
3464
 
      addrcpy(&ptr[i].sessionHost,theHost),
3465
 
        ptr[i].sessionPort = thePort,
3466
 
        ptr[i].creationTime = myGlobals.actTime;
3467
 
 
3468
 
      if(ptr[i].session_info != NULL) free(ptr[i].session_info);
3469
 
      if(notes)
3470
 
        ptr[i].session_info = strdup(notes);
3471
 
      else
3472
 
        ptr[i].session_info = NULL;
3473
 
      break;
3474
 
    }
3475
 
  }
3476
 
 
3477
 
  if(i == ptr_len) {
3478
 
    /* Slot Not found */
3479
 
    static u_char is_hash_full = 0;
3480
 
 
3481
 
    if(!is_hash_full) {
3482
 
      traceEvent(CONST_TRACE_INFO, "addSessionInfo: hash full [size=%d]", ptr_len);
3483
 
      is_hash_full = 1;
3484
 
    }    
 
3648
  if(ptr != NULL) {
 
3649
    for(i=0; i<ptr_len; i++) {
 
3650
      if((ptr[i].sessionPort == 0)
 
3651
         || (ptr[i].creationTime < timeoutTime)) {
 
3652
        /* Autopurge */
 
3653
        addrcpy(&ptr[i].sessionHost,theHost),
 
3654
          ptr[i].sessionPort = thePort,
 
3655
          ptr[i].creationTime = myGlobals.actTime;
 
3656
 
 
3657
        if(ptr[i].session_info != NULL) free(ptr[i].session_info);
 
3658
        if(notes)
 
3659
          ptr[i].session_info = strdup(notes);
 
3660
        else
 
3661
          ptr[i].session_info = NULL;
 
3662
        break;
 
3663
      }
 
3664
    }
 
3665
 
 
3666
    if(i == ptr_len) {
 
3667
      /* Slot Not found */
 
3668
      static u_char is_hash_full = 0;
 
3669
 
 
3670
      if(!is_hash_full) {
 
3671
        traceEvent(CONST_TRACE_INFO, "addSessionInfo: hash full [size=%d]", ptr_len);
 
3672
        is_hash_full = 1;
 
3673
      }
 
3674
    }
3485
3675
  }
3486
3676
}
3487
3677
 
3495
3685
 
3496
3686
void addVoIPSessionInfo(HostAddr *theHost, u_short thePort, char *notes) {
3497
3687
#ifdef DEBUG_VOIP
3498
 
  traceEvent(CONST_TRACE_INFO, "DEBUG: addVoIPSessionInfo(%s:%d) [%s]", 
3499
 
             addrtostr(theHost), thePort, notes); 
 
3688
  traceEvent(CONST_TRACE_INFO, "DEBUG: addVoIPSessionInfo(%s:%d) [%s]",
 
3689
             addrtostr(theHost), thePort, notes);
3500
3690
#endif
3501
3691
  addSessionInfo(voipSessions, voipSessionsLen, theHost, thePort, notes);
3502
3692
}
3503
3693
 
3504
3694
/* ******************************************* */
3505
3695
 
3506
 
static int isKnownSession(SessionInfo *ptr, u_short ptr_len, 
 
3696
static int isKnownSession(SessionInfo *ptr, u_short ptr_len,
3507
3697
                          HostAddr *theHost, u_short thePort, char **notes) {
3508
3698
  int i;
3509
3699
 
3513
3703
 
3514
3704
  (*notes) = NULL;
3515
3705
 
3516
 
  for(i=0; i<ptr_len; i++) {
3517
 
    if((addrcmp(&ptr[i].sessionHost,theHost) == 0)
3518
 
       && (ptr[i].sessionPort == thePort)) {
3519
 
      addrinit(&ptr[i].sessionHost);
3520
 
      ptr[i].sessionPort = 0, ptr[i].creationTime = 0;
3521
 
      (*notes) = ptr[i].session_info;
 
3706
  if(ptr != NULL) {
 
3707
    for(i=0; i<ptr_len; i++) {
 
3708
      if((addrcmp(&ptr[i].sessionHost,theHost) == 0)
 
3709
         && (ptr[i].sessionPort == thePort)) {
 
3710
        addrinit(&ptr[i].sessionHost);
 
3711
        ptr[i].sessionPort = 0, ptr[i].creationTime = 0;
 
3712
        (*notes) = ptr[i].session_info;
3522
3713
 
3523
 
      /* NOTE: this memory will be freed by freeSessionInfo */
3524
 
      ptr[i].session_info = NULL;
 
3714
        /* NOTE: this memory will be freed by freeSessionInfo */
 
3715
        ptr[i].session_info = NULL;
3525
3716
 
3526
3717
#ifdef DEBUG
3527
 
      traceEvent(CONST_TRACE_INFO, "DEBUG: Found session");
 
3718
        traceEvent(CONST_TRACE_INFO, "DEBUG: Found session");
3528
3719
#endif
3529
 
      return(1);
 
3720
        return(1);
 
3721
      }
3530
3722
    }
3531
3723
  }
3532
3724
 
3545
3737
  int rc = isKnownSession(voipSessions, voipSessionsLen, theHost, thePort, notes);
3546
3738
 
3547
3739
#ifdef DEBUG_VOIP
3548
 
  traceEvent(CONST_TRACE_INFO, "DEBUG: isVoipSession(%s:%d)=%d", addrtostr(theHost), thePort, rc); 
 
3740
  traceEvent(CONST_TRACE_INFO, "DEBUG: isVoipSession(%s:%d)=%d", addrtostr(theHost), thePort, rc);
3549
3741
#endif
3550
3742
  return(rc);
3551
3743
}
3803
3995
  u_int i, found=0;
3804
3996
 
3805
3997
#ifdef DEBUG
3806
 
  traceEvent(CONST_TRACE_INFO, "DEBUG: incrementUsageCounter(%u) @ %s:%d",
3807
 
             peerIdx, file, line);
 
3998
  traceEvent(CONST_TRACE_INFO, "DEBUG: incrementUsageCounter() @ %s:%d", file, line);
3808
3999
#endif
3809
4000
 
3810
4001
  if(theHost == NULL) return(0);
3884
4075
 
3885
4076
/* ******************************** */
3886
4077
 
 
4078
#ifndef WIN32
3887
4079
#ifndef HAVE_LOCALTIME_R
3888
4080
#undef localtime
3889
4081
 
3911
4103
  return(tp);
3912
4104
}
3913
4105
#endif
 
4106
#endif
3914
4107
 
3915
4108
/* ************************************ */
3916
4109
 
3935
4128
  unsigned long ulSlice;
3936
4129
  short ntopRunStateSave;
3937
4130
 
3938
 
  /* This probably isn't necessary - 
 
4131
  /* This probably isn't necessary -
3939
4132
   *  But: It keeps the responsiveness of the Win32 version in that environment
3940
4133
   *  And: Puts less load on non Win32 systems
3941
4134
   */
3947
4140
 
3948
4141
  ntopRunStateSave = myGlobals.ntopRunState;
3949
4142
 
3950
 
  traceEvent(CONST_BEYONDNOISY_TRACE_LEVEL, file, line, "ntopSleepMS(%u)", ulDelay);
 
4143
  traceEvent(CONST_BEYONDNOISY_TRACE_LEVEL, file, line, "ntopSleepMS(%lu)", ulDelay);
3951
4144
 
3952
4145
  while(ulDelay > 0L) {
3953
4146
    if(ulDelay < ulSlice)
3965
4158
        memcpy(&sleepAmount, &remAmount, sizeof(sleepAmount));
3966
4159
        memset(&remAmount, 0, sizeof(remAmount));
3967
4160
 
3968
 
        traceEvent(CONST_BEYONDNOISY_TRACE_LEVEL, file, line, "nanosleep({%d, %d}, )", sleepAmount.tv_sec, sleepAmount.tv_nsec);
 
4161
        traceEvent(CONST_BEYONDNOISY_TRACE_LEVEL, file, line,
 
4162
                   "nanosleep({%d, %d}, )", 
 
4163
                   (int)sleepAmount.tv_sec, 
 
4164
                   (int)sleepAmount.tv_nsec);
3969
4165
 
3970
4166
        if((nanosleep(&sleepAmount, &remAmount) != 0) && (errno == EINTR)) {
3971
4167
 
4076
4272
  len = strlen(src);
4077
4273
  for (srcIdx = 0, destIdx = 0; srcIdx < len && destIdx < destLen; src++) {
4078
4274
    switch (src[srcIdx]) {
4079
 
      case ' ':
4080
 
        dest[destIdx++] = '%';
4081
 
        dest[destIdx++] = '2';
4082
 
        dest[destIdx++] = '0';
4083
 
        break;
4084
 
      default:
4085
 
        dest[destIdx++] = src[srcIdx];
 
4275
    case ' ':
 
4276
      dest[destIdx++] = '+';
 
4277
      break;
 
4278
    default:
 
4279
      dest[destIdx++] = src[srcIdx];
4086
4280
    }
4087
4281
  }
4088
4282
}
4444
4638
 
4445
4639
/* ******************************************
4446
4640
 *        For ntop_gdbm_xxxx see leaks.c
4447
 
/* ****************************************** */
 
4641
 * ****************************************** */
4448
4642
 
4449
4643
void handleWhiteBlackListAddresses(char* addresses,
4450
 
                                   u_int32_t theNetworks[MAX_NUM_NETWORKS][3],
 
4644
                                   u_int32_t theNetworks[MAX_NUM_NETWORKS][4],
4451
4645
                                   u_short *numNets,
4452
4646
                                   char* outAddresses,
4453
4647
                                   int outAddressesLen) {
4481
4675
 *  So we have to flip the whitelist code
4482
4676
 */
4483
4677
unsigned short isOKtoSave(u_int32_t addr,
4484
 
                          u_int32_t whiteNetworks[MAX_NUM_NETWORKS][3],
4485
 
                          u_int32_t blackNetworks[MAX_NUM_NETWORKS][3],
 
4678
                          u_int32_t whiteNetworks[MAX_NUM_NETWORKS][4],
 
4679
                          u_int32_t blackNetworks[MAX_NUM_NETWORKS][4],
4486
4680
                          u_short numWhiteNets, u_short numBlackNets) {
4487
4681
  int rc;
4488
4682
  struct in_addr workAddr;
4490
4684
  workAddr.s_addr = addr;
4491
4685
 
4492
4686
  if(numBlackNets > 0) {
4493
 
    rc = __pseudoLocalAddress(&workAddr, blackNetworks, numBlackNets);
 
4687
    rc = __pseudoLocalAddress(&workAddr, blackNetworks, numBlackNets, NULL, NULL);
4494
4688
    if(rc == 1)
4495
4689
      return 2;
4496
4690
  }
4497
4691
 
4498
4692
  if(numWhiteNets > 0) {
4499
 
    rc = __pseudoLocalAddress(&workAddr, whiteNetworks, numWhiteNets);
 
4693
    rc = __pseudoLocalAddress(&workAddr, whiteNetworks, numWhiteNets, NULL, NULL);
4500
4694
    return(1 - rc);
4501
4695
  }
4502
4696
 
4520
4714
    setRunState(FLAG_NTOPSTATE_INITNONROOT);
4521
4715
 
4522
4716
  traceEvent(CONST_TRACE_ALWAYSDISPLAY, "Now running as requested user '%s' (%d:%d)",
4523
 
             myGlobals.effectiveUserName, myGlobals.userId, myGlobals.groupId);
 
4717
             myGlobals.effectiveUserName ? myGlobals.effectiveUserName : "<unknown>", 
 
4718
             myGlobals.userId, myGlobals.groupId);
4524
4719
 
4525
4720
  if((myGlobals.userId != 0) || (myGlobals.groupId != 0)) {
4526
4721
#if defined(DARWIN) || defined(FREEBSD)
4576
4771
    i++;
4577
4772
  }
4578
4773
 
4579
 
 
4580
 
#ifdef DEBUG
4581
 
  {
4582
 
    char buf[64];
4583
 
 
4584
 
    traceEvent(CONST_TRACE_INFO, "%s: %d AS", _intoa(&addr, buf, sizeof(buf)), as);
4585
 
  }
4586
 
#endif
4587
 
 
4588
 
  return as;
 
4774
  return(as);
4589
4775
}
4590
4776
 
4591
4777
/* ************************************ */
4635
4821
    }
4636
4822
 
4637
4823
  if(!found) {
4638
 
    for(i = 0; i<(MAX_NUM_RECENT_PORTS-1); i++)
4639
 
      thePorts[i] =  thePorts[i+1];
 
4824
    for(i = 0; i<(MAX_NUM_RECENT_PORTS-2); i++)
 
4825
      thePorts[i] = thePorts[i+1];
4640
4826
 
4641
4827
    thePorts[MAX_NUM_RECENT_PORTS-1] = port;
4642
4828
  }
5047
5233
    if(f>=3) {
5048
5234
      prerc=1;
5049
5235
    } else {
5050
 
      f = sscanf(versionString, "%u.%u%1[a-z].%u", &n, &m, &l, &x);
 
5236
      f = sscanf(versionString, "%u.%u%1[a-z].%u", &n, &m, (char*)&l, &x);
5051
5237
      if(f >= 3) {
5052
5238
        if(l[0] > 0)
5053
5239
          l[0] = tolower(l[0]) - 'a' + 1;
5137
5323
  // information for the ntop-dev mailing list.
5138
5324
  // Normally you would enable this, run ntop, collect the values and
5139
5325
  // then shut ntop down.
5140
 
#define cNV2N(a, b) \
5141
 
{ \
5142
 
  unsigned int vv; \
5143
 
  vv = convertNtopVersionToNumber(a); \
5144
 
  if (vv != b) \
5145
 
    traceEvent(CONST_TRACE_INFO, "CHKVER_TEST: cNV2N %-10s -> %10u expected %10u", a, vv, b); \
5146
 
  else \
5147
 
    traceEvent(CONST_TRACE_INFO, "CHKVER_TEST: cNV2N %-10s -> %10u OK", a, vv); \
5148
 
}
 
5326
#define cNV2N(a, b)                                                     \
 
5327
  {                                                                     \
 
5328
    unsigned int vv;                                                    \
 
5329
    vv = convertNtopVersionToNumber(a);                                 \
 
5330
    if (vv != b)                                                        \
 
5331
      traceEvent(CONST_TRACE_INFO, "CHKVER_TEST: cNV2N %-10s -> %10u expected %10u", a, vv, b); \
 
5332
    else                                                                \
 
5333
      traceEvent(CONST_TRACE_INFO, "CHKVER_TEST: cNV2N %-10s -> %10u OK", a, vv); \
 
5334
  }
5149
5335
 
5150
5336
  cNV2N("1.3",     103000000);
5151
5337
  cNV2N("2.1",     201000000);
5199
5385
/* ********************************** */
5200
5386
 
5201
5387
/* pseudo-function to use stringification to find the xml tag */
5202
 
#define xmlextract(a) { \
5203
 
       a = strstr(next, "<" #a ">"); \
5204
 
       if (a != NULL) { \
5205
 
           a += sizeof( #a ) + 1; \
5206
 
           if (strchr(a, '<') != NULL) \
5207
 
               strchr(a, '<')[0] = '\0'; \
5208
 
       } \
5209
 
}
 
5388
#define xmlextract(a) {                         \
 
5389
    a = strstr(next, "<" #a ">");               \
 
5390
    if (a != NULL) {                            \
 
5391
      a += sizeof( #a ) + 1;                    \
 
5392
      if (strchr(a, '<') != NULL)               \
 
5393
        strchr(a, '<')[0] = '\0';               \
 
5394
    }                                           \
 
5395
  }
5210
5396
 
5211
5397
/* ********************************** */
5212
5398
 
5402
5588
  tokenizeCleanupAndAppend(userAgent, LEN_GENERAL_WORK_BUFFER, "config", configure_parameters);
5403
5589
  tokenizeCleanupAndAppend(userAgent, LEN_GENERAL_WORK_BUFFER, "run", myGlobals.startedAs);
5404
5590
 
5405
 
#ifdef HAVE_PCAP_LIB_VERSION
5406
5591
  extractAndAppend(userAgent, LEN_GENERAL_WORK_BUFFER, "libpcap", (char*)pcap_lib_version());
5407
 
#endif
5408
5592
 
5409
5593
#if defined(WIN32) && defined(__GNUC__)
5410
5594
  /* on mingw, gdbm_version not exported by library */
5412
5596
  extractAndAppend(userAgent, LEN_GENERAL_WORK_BUFFER, "gdbm", gdbm_version);
5413
5597
#endif
5414
5598
 
5415
 
  /*
5416
 
   * If we've guessed at the gd version, report it
5417
 
   */
5418
 
  if(myGlobals.gdVersionGuessValue != NULL)
5419
 
    extractAndAppend(userAgent, LEN_GENERAL_WORK_BUFFER, "gd", myGlobals.gdVersionGuessValue);
5420
 
 
5421
5599
#ifdef HAVE_OPENSSL
5422
5600
  extractAndAppend(userAgent, LEN_GENERAL_WORK_BUFFER, "openssl", (char*)SSLeay_version(0));
5423
5601
#endif
5456
5634
 
5457
5635
    memset(&small_buf, 0, sizeof(small_buf));
5458
5636
    safe_snprintf(__FILE__, __LINE__, small_buf,
5459
 
                  LEN_SMALL_WORK_BUFFER, " uptime(%d)", 
 
5637
                  LEN_SMALL_WORK_BUFFER, " uptime(%d)",
5460
5638
                  time(NULL)-myGlobals.initialSniffTime);
5461
5639
 
5462
5640
    strncat(userAgent, buf, (LEN_SMALL_WORK_BUFFER - strlen(userAgent) - 1));
6000
6178
 
6001
6179
    el->hostResolvedNameType = updateType;
6002
6180
  }
 
6181
 
 
6182
  setHostCommunity(el);
6003
6183
}
6004
6184
 
6005
6185
/* ********************************************* */
6317
6497
/* ********************************************* */
6318
6498
 
6319
6499
int cmpFctnLocationName(const void *_a, const void *_b) {
6320
 
 
6321
6500
  /* This function takes two HostTraffic entries and performs a
6322
6501
     standardized compare of the location, either the ip2ccValue field
6323
6502
     or the fallback dnsTLDValue fields, handling unvalued
6353
6532
  }
6354
6533
 
6355
6534
  rc = strcasecmp(nameA, nameB);
6356
 
  if(rc==0) {
 
6535
  if(rc == 0) {
6357
6536
    if((*a)->dnsTLDValue == NULL) {
6358
6537
      nameA = "\xFF\xFF";
6359
6538
    } else {
6367
6546
    rc = strcasecmp(nameA != NULL ? nameA : "", nameB != NULL ? nameB : "");
6368
6547
  }
6369
6548
 
6370
 
  if(rc==0) {
 
6549
  if(rc == 0) {
6371
6550
    rc = cmpFctnResolvedName(a, b);
6372
6551
  }
6373
6552
 
6457
6636
 
6458
6637
void freePortsUsage(HostTraffic *el) {
6459
6638
  PortUsage *act, *next;
6460
 
  
 
6639
 
6461
6640
  if(el->portsUsage == NULL) return;
6462
6641
 
6463
6642
  act = el->portsUsage;
6465
6644
    next = act->next;
6466
6645
    free(act);
6467
6646
    act = next;
6468
 
  } 
 
6647
  }
6469
6648
  el->portsUsage = NULL;
6470
6649
}
6471
6650
 
6491
6670
 *
6492
6671
 * Here, we:
6493
6672
 * 1. Scan list upto found/end/port > what we care about
6494
 
 * 2. (not found and createIfNecessary), allocate new one and insert 
 
6673
 * 2. (not found and createIfNecessary), allocate new one and insert
6495
6674
 *    into chain, thus keeping the list sorted.
6496
6675
 */
6497
6676
PortUsage* getPortsUsage(HostTraffic *el, u_int portIdx, int createIfNecessary) {
6511
6690
  if(el->portsUsage == NULL) {
6512
6691
    /* Previously empty chain */
6513
6692
    el->portsUsage = newPort;
6514
 
  } else if (ports == el->portsUsage) { 
 
6693
  } else if (ports == el->portsUsage) {
6515
6694
    /* 1st in chain */
6516
6695
    newPort->next = el->portsUsage;
6517
6696
    el->portsUsage = newPort;
6526
6705
 
6527
6706
/* *************************************************** */
6528
6707
 
6529
 
char* vlan2name(int vlanId, char *buf, int buf_len) {
 
6708
char* vlan2name(u_int16_t vlanId, char *buf, int buf_len) {
6530
6709
  char key[64];
6531
6710
 
6532
6711
  snprintf(key, sizeof(key), "vlan.%d", vlanId);
6541
6720
/* ******************************************* */
6542
6721
 
6543
6722
void mkdir_p(char *tag, char *path, int permission) {
6544
 
  int i, rc;
 
6723
  int i, rc = 0;
6545
6724
 
6546
6725
  if(path == NULL) {
6547
6726
    traceEvent(CONST_TRACE_ERROR, "%s: mkdir(null) skipped", tag);
6553
6732
  /* Start at 1 to skip the root */
6554
6733
  for(i=1; path[i] != '\0'; i++)
6555
6734
    if(path[i] == CONST_PATH_SEP) {
 
6735
#ifdef WIN32
 
6736
      /* Do not create devices directory */
 
6737
      if((i > 1) && (path[i-1] == ':')) continue;
 
6738
#endif
 
6739
 
6556
6740
      path[i] = '\0';
6557
6741
#if RRD_DEBUG >= 3
6558
6742
      if(strcmp(tag, "RRD") == 0)
6559
6743
        traceEvent(CONST_TRACE_INFO, "RRD_DEBUG: calling mkdir(%s)", path);
6560
6744
#endif
6561
 
      rc = _mkdir(path, permission);
 
6745
      rc = ntop_mkdir(path, permission);
6562
6746
      if((rc != 0) && (errno != EEXIST) )
6563
 
        traceEvent(CONST_TRACE_WARNING, "RRD: %s, error %d %s",
 
6747
        traceEvent(CONST_TRACE_WARNING, "RRD: [path=%s][error=%d/%s]",
6564
6748
                   path,
6565
6749
                   errno,
6566
6750
                   strerror(errno));
6571
6755
  if(strcmp(tag, "RRD") == 0)
6572
6756
    traceEvent(CONST_TRACE_INFO, "RRD_DEBUG: calling mkdir(%s)", path);
6573
6757
#endif
6574
 
  _mkdir(path, permission);
 
6758
  ntop_mkdir(path, permission);
 
6759
 
6575
6760
  if((rc != 0) && (errno != EEXIST) )
6576
6761
    traceEvent(CONST_TRACE_WARNING, "%s: mkdir(%s), error %d %s",
6577
6762
               tag,
6582
6767
 
6583
6768
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
6584
6769
 
6585
 
/*
6586
 
    Work-Arounds.  For things we just HAVE to have, code the work-around
6587
 
                   so we don't clutter mainline with #ifdef logic.
6588
 
 */
6589
 
 
6590
 
#ifndef HAVE_PCAP_OPEN_DEAD
6591
 
 
6592
 
#ifndef WIN32
6593
 
#warning using ntop work-around for missing pcap_open_dead ... strongly suggest upgrading!
6594
 
#endif
6595
 
 
6596
 
struct pcap_sf {
6597
 
  FILE *rfile;
6598
 
  int swapped;
6599
 
  int hdrsize;
6600
 
  int version_major;
6601
 
  int version_minor;
6602
 
  u_char *base;
6603
 
};
6604
 
 
6605
 
struct pcap_md {
6606
 
  struct pcap_stat stat;
6607
 
  /*XXX*/
6608
 
  int use_bpf;          /* using kernel filter */
6609
 
  u_long        TotPkts;        /* can't oflow for 79 hrs on ether */
6610
 
  u_long        TotAccepted;    /* count accepted by filter */
6611
 
  u_long        TotDrops;       /* count of dropped packets */
6612
 
  long  TotMissed;      /* missed by i/f during this run */
6613
 
  long  OrigMissed;     /* missed by i/f before this run */
6614
 
#ifdef linux
6615
 
  int   sock_packet;    /* using Linux 2.0 compatible interface */
6616
 
  int   timeout;        /* timeout specified to pcap_open_live */
6617
 
  int   clear_promisc;  /* must clear promiscuous mode when we close */
6618
 
  int   cooked;         /* using SOCK_DGRAM rather than SOCK_RAW */
6619
 
  int   lo_ifindex;     /* interface index of the loopback device */
6620
 
  char  *device;        /* device name */
6621
 
  struct pcap *next;    /* list of open promiscuous sock_packet pcaps */
6622
 
#endif
6623
 
};
6624
 
 
6625
 
struct pcap {
6626
 
  int fd;
6627
 
  int snapshot;
6628
 
  int linktype;
6629
 
  int tzoff;            /* timezone offset */
6630
 
  int offset;           /* offset for proper alignment */
6631
 
 
6632
 
  struct pcap_sf sf;
6633
 
  struct pcap_md md;
6634
 
 
6635
 
  /*
6636
 
   * Read buffer.
6637
 
   */
6638
 
  int bufsize;
6639
 
  u_char *buffer;
6640
 
  u_char *bp;
6641
 
  int cc;
6642
 
 
6643
 
  /*
6644
 
   * Place holder for pcap_next().
6645
 
   */
6646
 
  u_char *pkt;
6647
 
 
6648
 
 
6649
 
  /*
6650
 
   * Placeholder for filter code if bpf not in kernel.
6651
 
   */
6652
 
  struct bpf_program fcode;
6653
 
 
6654
 
  char errbuf[PCAP_ERRBUF_SIZE];
6655
 
};
6656
 
 
6657
 
pcap_t *pcap_open_dead(int linktype, int snaplen)
6658
 
{
6659
 
  pcap_t *p;
6660
 
 
6661
 
  p = malloc(sizeof(*p));
6662
 
  if (p == NULL)
6663
 
    return NULL;
6664
 
  memset (p, 0, sizeof(*p));
6665
 
  p->fd = -1;
6666
 
  p->snapshot = snaplen;
6667
 
  p->linktype = linktype;
6668
 
  return p;
6669
 
}
6670
 
#endif
6671
 
 
6672
6770
/* * * * * * * * * * * * * * * * * * */
6673
6771
 
6674
6772
#if !defined(WIN32)
6687
6785
         : sig == SIGTERM ? "SIGTERM"
6688
6786
         : sig == SIGUSR1 ? "SIGUSR1"
6689
6787
         : sig == SIGUSR2 ? "SIGUSR2"
6690
 
         : sig == SIGCHLD ? "SIGCHLD" 
 
6788
         : sig == SIGCHLD ? "SIGCHLD"
6691
6789
#ifdef SIGCONT
6692
6790
         : sig == SIGCONT ? "SIGCONT"
6693
6791
#endif
6706
6804
#ifdef SIGXFSZ
6707
6805
         : sig == SIGXFSZ ? "SIGXFSZ"
6708
6806
#endif
6709
 
          : "unable to determine");
6710
 
}
6711
 
#endif
6712
 
   
6713
 
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
6714
 
 
6715
 
/*
6716
 
    Dummies.  Instead of cluttering ntop with a bunch of #ifdef logic,
6717
 
              just define the function (or a work-around) here and in globals-core.h if we
6718
 
              don't have it.
6719
 
 */
6720
 
#ifndef WIN32
6721
 
 
6722
 
#ifndef HAVE_PCAP_FREECODE
6723
 
#warning using ntop work-around for missing pcap_freecode ... no worries
6724
 
void pcap_freecode(struct bpf_program *pgm) {
6725
 
}
6726
 
#endif
6727
 
 
6728
 
#ifndef HAVE_PCAP_FINDALLDEVS
6729
 
 #warning using ntop work-around for missing pcap_findalldevs... suggest you upgrade libpcap!
6730
 
int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) {
6731
 
  return(-1); /* failed */
6732
 
}
6733
 
#endif
6734
 
 
6735
 
#ifndef HAVE_PCAP_FREEALLDEVS
6736
 
 #warning using ntop work-around for missing pcap_freealldevs ... suggest you upgrade libpcap!
6737
 
void pcap_freealldevs(pcap_if_t *alldevs) {
6738
 
  return;
6739
 
}
6740
 
#endif
6741
 
 
6742
 
#endif /* WIN32 */
 
6807
         : "unable to determine");
 
6808
}
 
6809
#endif
6743
6810