/* This file is part of Kismet Kismet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Kismet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Kismet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include "manuf.h" #include "packetracker.h" int manuf_max_score = 8; macmap > ReadManufMap(FILE *in_file, int ap_map) { macmap > ret; vector rvec; manuf *manf; // Push an unknown record manf = new manuf; manf->name = "Unknown"; manf->model = "Unknown"; manf->ssid_default = ""; manf->mac_tag = "00:00:00:00:00:00"; manf->channel_default = 0; memset(&manf->ipdata, 0, sizeof(net_ip_data)); rvec.push_back(manf); ret.fast_insert(manf->mac_tag, rvec); int linenum = 0; // Read from the file char dline[8192]; while (!feof(in_file)) { fgets(dline, 8192, in_file); if (feof(in_file)) break; linenum++; // Cut the newline dline[strlen(dline) - 1] = '\0'; vector line_vec = StrTokenize(dline, "\t"); manf = new manuf; manf->name = ""; manf->model = ""; manf->mac_tag = ""; manf->ssid_default = ""; manf->channel_default = 0; memset(&manf->ipdata, 0, sizeof(net_ip_data)); // If we're loading a AP manuf map, we handle it this way if (line_vec.size() < 2) { delete manf; continue; } if (ap_map) { // If we're loading a AP manuf map, we handle it this way manf->mac_tag = line_vec[0].c_str(); manf->name = line_vec[1]; if (line_vec.size() >= 3) { manf->model = line_vec[2]; if (line_vec.size() >= 4) { manf->ssid_default = line_vec[3]; if (line_vec.size() >= 5) { int chan; if (sscanf(line_vec[4].c_str(), "%d", &chan) == 1) manf->channel_default = chan; if (line_vec.size() >= 6) { short int ipr[4]; if (sscanf(line_vec[5].c_str(), "%hd.%hd.%hd.%hd", &ipr[0], &ipr[1], &ipr[2], &ipr[3]) == 4) { manf->ipdata.atype = address_factory; manf->ipdata.octets = 4; for (unsigned int x = 0; x < 4; x++) manf->ipdata.range_ip[x] = ipr[x]; } } } } } if (ret.find(manf->mac_tag) != ret.end()) { ret[manf->mac_tag].push_back(manf); } else { rvec.clear(); rvec.push_back(manf); ret.fast_insert(manf->mac_tag, rvec); } } else { // Otherwise we handle clients this way manf->mac_tag = line_vec[0].c_str(); manf->name = line_vec[1]; if (line_vec.size() >= 3) manf->model = line_vec[2]; if (ret.find(manf->mac_tag) != ret.end()) { ret[manf->mac_tag].push_back(manf); } else { rvec.clear(); rvec.push_back(manf); ret.fast_insert(manf->mac_tag, rvec); } } } ret.reindex(); return ret; } // Find the best match for a likely manufacturer, based on tags (for clients) and // default SSIDs, channel, etc (for access points) // Returned in the parameters are the pointers to the best manufacturer record, the // score, and the modified mac address which matched it manuf *MatchBestManuf(macmap > in_manuf, mac_addr in_mac, string in_ssid, int in_channel, int in_wep, int in_cloaked, int *manuf_score) { manuf *best_manuf = NULL; int best_score = 0; int best_pos = 0; macmap >::iterator mitr = in_manuf.find(in_mac); if (mitr != in_manuf.end()) { vector manuf_list = *(mitr->second); for (unsigned int x = 0; x < manuf_list.size(); x++) { manuf *likely_manuf = manuf_list[x]; int score = 0; score += 6; if (in_ssid != "" && in_ssid == likely_manuf->ssid_default) score += 1; if (in_channel != 0 && in_channel == likely_manuf->channel_default) score += 1; if (in_wep) score -= 1; if (in_cloaked) score -= 1; if (score > best_score) { best_score = score; best_pos = x; best_manuf = likely_manuf; } } } *manuf_score = best_score; return best_manuf; }