void packet_decoder_db(u_char * useless, const struct pcap_pkthdr *pkthdr, const u_char * packet) { char ssid[32], *temp; sqlite3 *db = (sqlite3 *) useless; char *zErrMsg = 0; int rc; char sql[100]={0}; int count=0; //there is a radiotap header of 18 bits struct mac_header *p = (struct mac_header *) (packet+18); //struct mac_header *p = (struct mac_header *) packet+18; struct frame_control *control = (struct frame_control *)p->fc; //temp = (char *)(packet + sizeof(struct mac_header)+sizeof(struct beacon_header)); temp = (char *)(packet +18 + sizeof(struct mac_header)+sizeof(struct beacon_header)); memset (ssid, '\0', 32); if ((control->protocol==0)&&(control->type==0)&&(control->subtype==4)) { printf ("\n\nFound SSID : \n"); printf ("Destination Add : %s\n", ether_ntoa_z (p->add1)); printf ("Source Add : %s\n", ether_ntoa_z (p->add2)); printf ("BSSID : %s\n", ether_ntoa_z (p->add3)); //squery sprintf(sql," select * from mac_log where mac='%s' and date > datetime('now','-5 minute') ;",ether_ntoa_z (p->add2)); rc = sqlite3_exec(db, (char *)sql, callback_getnumber, (void *)&count, &zErrMsg); if( rc != SQLITE_OK ){ printf("SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ //printf("insert db success\n"); } if(count <= 0 ) { //write database sprintf(sql," insert into mac_log values(NULL ,'%s' ,datetime('now')) ;",ether_ntoa_z (p->add2)); //printf("%s",sql); rc = sqlite3_exec(db, (char *)sql, callback, 0, &zErrMsg); if( rc != SQLITE_OK ){ printf("SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ //printf("insert db success\n"); } } } }
void pgsql_update_lease(const uint8_t* mac, const struct in_addr* yip, const char* ifname, const uint32_t expiresAt, const enum t_lease_update_src reason) { /* only write DHCP ACK packet changes back */ if (reason != UPDATED_LEASE_FROM_DHCP) return; /* the pgsql commands are both run always, as the initial entry might have been created on another device. */ /* though, we restrict ACKs to be received on APs that saw the request - no roaming between REQ/ACK */ /* add to pgsql */ if (!pgsql_connected()) return; const uint32_t now = reltime(); eprintf(DEBUG_VERBOSE, "sql: update lease: MAC: %s IP: %s VLAN: %s expiresIn: %d", ether_ntoa_z((struct ether_addr *)mac), inet_ntoa(*yip), ifname, expiresAt - now); char *sql_esc_bridge = PQescapeLiteral(pgsql, ifname, strlen(ifname)); if (!sql_esc_bridge) return; char sql[2048]; if (expiresAt > now) { snprintf(sql, sizeof(sql), "INSERT INTO " PGSQLLEASETABLE " (bridge, mac, ip, validUntil) VALUES(%s, '%s', '%s', CURRENT_TIMESTAMP + interval '%d seconds') ON CONFLICT (bridge, mac, ip) DO UPDATE SET validUntil = CURRENT_TIMESTAMP + interval '%d seconds';", sql_esc_bridge, ether_ntoa_z((struct ether_addr *)mac), inet_ntoa(*yip), expiresAt - now, expiresAt - now); } else { snprintf(sql, sizeof(sql), "UPDATE " PGSQLLEASETABLE " SET validUntil = CURRENT_TIMESTAMP WHERE bridge = %s AND mac = '%s';", sql_esc_bridge, ether_ntoa_z((struct ether_addr *)mac)); } PQfreemem(sql_esc_bridge); sql_esc_bridge = NULL; eprintf(DEBUG_GENERAL, "write sql: %s", sql); pgsql_query_errprint(sql); }
void dump_fdb(int s) { struct cache_fdb_entry* entry = globalFdbCache; while (entry != NULL) { eprintf(DEBUG_GENERAL | DEBUG_VERBOSE, "fdb: MAC: %s BRIDGE: %s %s" , ether_ntoa_z((struct ether_addr *)entry->mac), entry->bridge, (entry->enabled ? "enabled" : "disabled")); entry = entry->next; } }
void dump_req(int s) { uint32_t now = time(NULL); struct cache_req_entry* entry = globalReqCache; while (entry != NULL) { eprintf(DEBUG_GENERAL | DEBUG_VERBOSE, "req: MAC: %s BRIDGE: %s expires in %d" , ether_ntoa_z((struct ether_addr *)entry->mac), entry->bridge, (int) entry->expiresAt - (int) now); entry = entry->next; } }
void packet_decoder(u_char * useless, const struct pcap_pkthdr *pkthdr, const u_char * packet) { //printf("Got Packet\n"); char ssid[32], *temp; //there is a radiotap header of 18 bits struct mac_header *p = (struct mac_header *) (packet+18); //struct mac_header *p = (struct mac_header *) packet+18; struct frame_control *control = (struct frame_control *)p->fc; //temp = (char *)(packet + sizeof(struct mac_header)+sizeof(struct beacon_header)); temp = (char *)(packet +18 + sizeof(struct mac_header)+sizeof(struct beacon_header)); memset (ssid, '\0', 32); //print_my(packet,pkthdr->len); // check if frame is beacon frame /* printf("protocole:%x \ttype:%x\tsubtype:%x",control->protocol,control->type,control->subtype); printf("%x %x %x %x %x %x %x %x %x %x %x ",control->protocol,control->type,control->subtype ,control->to_ds,control->from_ds,control->more_frag, control->retry,control->pwr_mgt,control->more_data, control->wep,control->order); printf("\txxx%o, %x, %u",control,control,control); printf("\txxx%x, %x, %x\n",p->fc,control->type,control->subtype); */ if ((control->protocol==0)&&(control->type==0)&&(control->subtype==4)) { //temp[1] contains the size of the ssid field and temp[2] the beginning ofthe ssid string . //memcpy (ssid, &temp[2], temp[1]); printf ("\n\nFound SSID : \n"); printf ("Destination Add : %s\n", ether_ntoa_z (p->add1)); printf ("Source Add : %s\n", ether_ntoa_z (p->add2)); printf ("BSSID : %s\n", ether_ntoa_z (p->add3)); //printf ("ssid = %s\n", ssid); } }
void pgsql_iterate_lease_for_ifname_and_mac(const char* ifname, const uint8_t* mac, lease_cb cb) { /* query sql for lease and add local rules*/ PGresult * res; char sql[1024]; char *sql_esc_bridge; const uint32_t now = reltime(); if (!pgsql_connected()) return; eprintf(DEBUG_NEIGH, "query pgsql\n"); sql_esc_bridge = PQescapeLiteral(pgsql, ifname, strlen(ifname)); snprintf(sql, sizeof(sql), "SELECT ip::varchar as ip, ceil(extract('epoch' from MAX(validUntil) - CURRENT_TIMESTAMP))::varchar as expiresin FROM " PGSQLLEASETABLE " WHERE validUntil > CURRENT_TIMESTAMP AND bridge = %s AND mac = '%s' GROUP BY ip;", sql_esc_bridge, ether_ntoa_z((struct ether_addr *)mac)); PQfreemem(sql_esc_bridge); sql_esc_bridge = NULL; eprintf(DEBUG_NEIGH, "query: %s", sql); res = pgsql_query_errprint_query(sql); if (res == NULL) goto out; /* pgsql query sucessfull */ int colIp = PQfnumber(res, "ip"); int colExpiresIn = PQfnumber(res, "expiresin"); for (int row = 0; row < PQntuples(res); row++) { char *ip = PQgetvalue(res, row, colIp); char *expiresIn = PQgetvalue(res, row, colExpiresIn); eprintf(DEBUG_NEIGH, "query pgsql: got row ip = %s, expiresAt = %s", ip ? ip : "NULL", expiresIn ? expiresIn : "NULL"); if (!ip || !expiresIn) continue; struct in_addr yip; if (!inet_aton(ip, &yip)) { eprintf(DEBUG_NEIGH, "cannot parse ip"); continue; } uint32_t expiresAt = atoi(expiresIn) + now; cb (mac, &yip, ifname, expiresAt, UPDATED_LEASE_FROM_EXTERNAL); } PQclear(res); res = NULL; out: eprintf(DEBUG_NEIGH, "pgsql completed"); }
int pgsql_update_lease_from_sql(const char* ifname, const uint8_t* mac, const struct in_addr* ip, uint32_t* expiresAt) { PGresult * res; char sql[1024]; char *sql_esc_bridge; if (!pgsql_connected()) return -1; sql_esc_bridge = PQescapeLiteral(pgsql, ifname, strlen(ifname)); snprintf(sql, sizeof(sql), "SELECT ceil(extract('epoch' from (validUntil - CURRENT_TIMESTAMP)))::varchar as expiresin FROM " PGSQLLEASETABLE " WHERE validUntil > CURRENT_TIMESTAMP AND bridge = %s AND mac = '%s' AND ip = '%s';", sql_esc_bridge, ether_ntoa_z((struct ether_addr *)mac), inet_ntoa(*ip)); PQfreemem(sql_esc_bridge); sql_esc_bridge = NULL; res = pgsql_query_errprint_query(sql); if (res == NULL) return -1; /* pgsql query sucessfull */ int col = -1; if (PQntuples(res) > 0) { col = PQfnumber(res, "expiresin"); if (col == -1) eprintf(DEBUG_ERROR, "sql: update lease from sql did not find column expiresin"); } if (col != -1) { char *val = PQgetvalue(res, 0, col); const int now = reltime(); int expiresIn = atoi(val); eprintf(DEBUG_VERBOSE, "sql: update lease from sql: MAC: %s IP: %s VLAN: %s expiresIn (old): %d expiresIn (new): %d raw: %s", ether_ntoa_z((struct ether_addr *)mac), inet_ntoa(*ip), ifname, *expiresAt - now, expiresIn, val); *expiresAt = expiresIn + now; } else { *expiresAt = 0; } PQclear(res); res = NULL; return 0; }