int kmod_coova_sync() { char file[128]; char * line = 0; size_t len = 0; ssize_t read; FILE *fp; char ip[256]; unsigned int maci[6]; unsigned int state; unsigned long long int bin; unsigned long long int bout; unsigned long long int pin; unsigned long long int pout; struct dhcp_conn_t *conn; if (!_options.kname) return -1; safe_snprintf(file, sizeof(file), kname_fmt, _options.kname); fp = fopen(file, "r"); if (fp == NULL) return -1; while ((read = getline(&line, &len, fp)) != -1) { if (len > 256) { log_err(errno, "problem"); continue; } if (sscanf(line, "mac=%X-%X-%X-%X-%X-%X " "src=%s state=%u " "bin=%llu bout=%llu " "pin=%llu pout=%llu", &maci[0], &maci[1], &maci[2], &maci[3], &maci[4], &maci[5], ip, &state, &bin, &bout, &pin, &pout) == 12) { uint8_t mac[6]; int i; for (i=0;i<6;i++) mac[i]=maci[i]&0xFF; if (!dhcp_hashget(dhcp, &conn, mac)) { struct app_conn_t *appconn = conn->peer; if (appconn) { if (_options.swapoctets) { appconn->s_state.input_octets = bin; appconn->s_state.output_octets = bout; appconn->s_state.input_packets = pin; appconn->s_state.output_packets = pout; } else { appconn->s_state.output_octets = bin; appconn->s_state.input_octets = bout; appconn->s_state.output_packets = pin; appconn->s_state.input_packets = pout; } } else { log_dbg("Unknown entry"); } } } else { log_err(errno, "Error parsing %s", line); } } if (line) free(line); fclose(fp); return 0; }
int loadstatus() { char filedest[512]; FILE *file; char c; struct dhcp_conn_t dhcpconn; struct app_conn_t appconn; time_t r_wall, r_rt, r_rtoffset; time_t wall, rt, rtoffset; has_loaded = 1; if (!_options.usestatusfile) return 1; statedir_file(filedest, sizeof(filedest), _options.usestatusfile, 0); log_dbg("Loading file %s", filedest); file = fopen(filedest, "r"); if (!file) { log_err(errno, "could not open file %s", filedest); return -1; } while ((c = fgetc(file)) != MARK_START) { if (c == EOF) { log_err(errno, "end of file"); fclose(file); return -1; } } time(&wall); if (fread(&r_wall, sizeof(time_t), 1, file) != 1) { log_err(errno, "bad binary file"); if (c == EOF) { fclose(file); return -1; } } rt = mainclock_tick(); if (fread(&r_rt, sizeof(time_t), 1, file) != 1) { log_err(errno, "bad binary file"); if (c == EOF) { fclose(file); return -1; } } if ((c = fgetc(file)) != MARK_START) { log_err(errno, "bad binary file"); fclose(file); return -1; } rtoffset = wall - rt; log_dbg("now: wall = %d, rt = %d, wall at rt=0 %d", (int)wall, (int)rt, (int)rtoffset); r_rtoffset = r_wall - r_rt; log_dbg("file: wall = %d, rt = %d, wall at rt=0 %d", (int)r_wall, (int)r_rt, (int)r_rtoffset); while (fread(&dhcpconn, sizeof(struct dhcp_conn_t), 1, file) == 1) { struct dhcp_conn_t *conn = 0; struct ippoolm_t *newipm = 0; int n; /* todo: read a md5 checksum or magic token */ if ((c = fgetc(file)) != MARK_NEXT) { log_err(errno, "bad binary file"); fclose(file); return -1; } if (dhcp_hashget(dhcp, &conn, dhcpconn.hismac)) { log_info ("Loading dhcp connection %.2X-%.2X-%.2X-%.2X-%.2X-%.2X", dhcpconn.hismac[0], dhcpconn.hismac[1], dhcpconn.hismac[2], dhcpconn.hismac[3], dhcpconn.hismac[4], dhcpconn.hismac[5]); /* not already known */ dhcp_lnkconn(dhcp, &conn); /* set/copy all the pointers */ dhcpconn.nexthash = conn->nexthash; dhcpconn.next = conn->next; dhcpconn.prev = conn->prev; dhcpconn.parent = dhcp; dhcpconn.is_reserved = 0; /* never a reserved ip if added here */ /* * Fix time_t values: * lasttime */ #define localizetime(t) \ /* to it's local real time */ \ t = r_rtoffset + t; \ /* now to our local rt offset */ \ t = t - rtoffset; \ if (t < 0) t = 0; localizetime(dhcpconn.lasttime); /* initialize dhcp_conn_t */ memcpy(conn, &dhcpconn, sizeof(struct dhcp_conn_t)); for (n = 0; n < DHCP_DNAT_MAX; n++) { memset(conn->dnat[n].mac, 0, PKT_ETH_ALEN); } log_dbg("checking IP %s", inet_ntoa(dhcpconn.hisip)); /* add into ippool */ if (ippool_getip(ippool, &newipm, &dhcpconn.hisip)) { if (ippool_newip (ippool, &newipm, &dhcpconn.hisip, 1)) { if (ippool_newip (ippool, &newipm, &dhcpconn.hisip, 0)) { log_err(0, "Failed to allocate either static or dynamic IP address"); conn->hisip.s_addr = 0; } } } dhcp_hashadd(dhcp, conn); if (conn->peer) { conn->peer = 0; if (fread (&appconn, sizeof(struct app_conn_t), 1, file) == 1) { struct app_conn_t *aconn = 0; if ((c = fgetc(file)) != MARK_NEXT) { log_err(errno, "bad binary file"); fclose(file); return -1; } if (chilli_new_conn(&aconn) == 0) { /* set/copy all the pointers/internals */ appconn.unit = aconn->unit; appconn.next = aconn->next; appconn.prev = aconn->prev; appconn.uplink = newipm; appconn.dnlink = conn; /* * Fix time_t values: * start_time, interim_time, * last_sent_time, last_time, * uamtime */ localizetime(appconn.s_state. start_time); localizetime(appconn.s_state. interim_time); localizetime(appconn.s_state. last_sent_time); localizetime(appconn.s_state. last_time); localizetime(appconn.s_state. uamtime); /* initialize app_conn_t */ memcpy(aconn, &appconn, sizeof(struct app_conn_t)); conn->peer = aconn; if (newipm) { newipm->peer = aconn; #ifdef ENABLE_UAMANYIP if (aconn->natip.s_addr) chilli_assign_snat (aconn, 1); #endif dhcp_set_addrs(conn, &newipm-> addr, &_options. mask, &aconn-> ourip, &aconn-> mask, &_options. dns1, &_options. dns2); } #if defined(ENABLE_SESSGARDEN) && defined(HAVE_PATRICIA) if (aconn->s_params. pass_through_count) { garden_patricia_load_list (&aconn->ptree, aconn->s_params. pass_throughs, aconn->s_params. pass_through_count); } #endif } /* todo: read a md5 checksum or magic token */ } else { log_err(errno, "Problem loading state file %s", filedest); break; } } } else { log_info ("Known dhcp connection %.2X-%.2X-%.2X-%.2X-%.2X-%.2X", dhcpconn.hismac[0], dhcpconn.hismac[1], dhcpconn.hismac[2], dhcpconn.hismac[3], dhcpconn.hismac[4], dhcpconn.hismac[5]); conn->authstate = dhcpconn.authstate; if (dhcpconn.peer) { log_info("Reading appconn (peer)"); if (fread (&appconn, sizeof(struct app_conn_t), 1, file) == 1) { if ((c = fgetc(file)) != MARK_NEXT) { log_err(errno, "bad binary file"); fclose(file); return -1; } if (conn->peer) { /* * Already have an appconn. */ struct app_conn_t *aconn = (struct app_conn_t *)conn-> peer; log_info ("Overwriting existing appconn %d", appconn.s_state. authenticated); memcpy(&aconn->s_params, &appconn.s_params, sizeof(struct session_params)); memcpy(&aconn->s_state, &appconn.s_state, sizeof(struct session_state)); } else { /* * No peer (appconn), then create it just as above. */ struct app_conn_t *aconn = 0; log_info ("Creating new appconn (peer)"); if (ippool_getip (ippool, &newipm, &conn->hisip)) { if (ippool_newip (ippool, &newipm, &conn->hisip, 1)) { if (ippool_newip (ippool, &newipm, &conn-> hisip, 0)) { log_err (0, "Failed to allocate either static or dynamic IP address"); fclose (file); return -1; } } } if (chilli_new_conn(&aconn) == 0) { /* set/copy all the pointers/internals */ appconn.unit = aconn->unit; appconn.next = aconn->next; appconn.prev = aconn->prev; appconn.uplink = newipm; appconn.dnlink = conn; /* initialize app_conn_t */ memcpy(aconn, &appconn, sizeof(struct app_conn_t)); conn->peer = aconn; newipm->peer = aconn; #ifdef ENABLE_UAMANYIP if (appconn.natip. s_addr) chilli_assign_snat (aconn, 1); #endif dhcp_set_addrs(conn, &newipm-> addr, &_options. mask, &aconn-> ourip, &aconn-> mask, &_options. dns1, &_options. dns2); } } } } } } fclose(file); printstatus(); return 0; }