/* * Copyright (C) 1998-2007 Luca Deri * * http://www.ntop.org/ * * This program 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. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ntop.h" #include "globals-report.h" /* Forward */ static void sendMenuFooter(int itm1Idx, int itm2Idx); static void encodeWebFormURL(char *in, char *buf, int buflen); static void decodeWebFormURL(char *buf); static int processNtopConfigData (char *buf, int savePref); /* *******************************/ void showUsers(void) { u_int numUsers=0; char buf[LEN_GENERAL_WORK_BUFFER]; datum key_data, return_data; printHTMLheader("Registered ntop Users", NULL, BITFLAG_HTML_NO_REFRESH); sendString("


\n"); return_data = gdbm_firstkey(myGlobals.pwFile); while (return_data.dptr != NULL) { /* traceEvent(CONST_TRACE_INFO, "1) -> %s", return_data.dptr); */ key_data = return_data; if(key_data.dptr[0] == '1') /* 1 = user */{ if(numUsers == 0) { sendString("

\n" ""TABLE_ON"\n"); sendString("\n"); } if(strcmp(key_data.dptr, "1admin") == 0) { safe_snprintf(__FILE__, __LINE__, buf, LEN_GENERAL_WORK_BUFFER, "\n", &key_data.dptr[1], CONST_MODIFY_USERS, key_data.dptr); } else{ char ebuf[256]; encodeWebFormURL(key_data.dptr, ebuf, sizeof(ebuf)); safe_snprintf(__FILE__, __LINE__, buf, LEN_GENERAL_WORK_BUFFER, "\n", &key_data.dptr[1], CONST_MODIFY_USERS, ebuf, CONST_DELETE_USER, ebuf); } sendString(buf); numUsers++; } return_data = gdbm_nextkey(myGlobals.pwFile, key_data); free(key_data.dptr); } if(numUsers > 0) { sendString("
UsersActions
" " %s" "\"Modify" " 
" " %s" "\"Modify" " " "\"Delete" "
"TABLE_OFF"\n

\n"); sendString("

\n"); } sendMenuFooter(1, 2); } /* *******************************/ void clearUserUrlList(void) { int i; /* * We just changed the database. * Delete the in-memory copy so next time we reference it, * it will be reloaded with the new values */ traceEvent(CONST_TRACE_NOISY, "SECURITY: Loading items table"); if(myGlobals.securityItemsMutex.isInitialized == 1) accessMutex(&myGlobals.securityItemsMutex, "clear"); for (i=0; i

\n"); if((user != NULL) && ((strlen(user) < 2) || (user[0] != '1'))) { printFlagedWarning("The specified username is invalid."); } else { sendString("

\n"); sendString("\n"); sendString("
\n"); sendString("\n"); sendString("\n\n\n"); sendString("" "\n"); sendString("" "\n"); /*********** Communities **********/ { int i, numUsers=0, len = strlen(COMMUNITY_PREFIX); datum key_data, return_data; char *aubuf=NULL, *userCommunities[20], communities[128], key[256]; sendString("" "\n"); } sendString("
User: "); if(user != NULL) { decodeWebFormURL(user); safe_snprintf(__FILE__, __LINE__, tmpStr, sizeof(tmpStr), "%s\n", &user[1], &user[1]); sendString(tmpStr); } else sendString("\n"); sendString("
Password: 
Verify Password: 
Authorised Communities: \n\n
"TABLE_OFF"\n"); safe_snprintf(__FILE__, __LINE__, tmpStr, sizeof(tmpStr), "   \n", (user != NULL) ? "Modify User" : "Add User"); sendString(tmpStr); sendString("
\n"); sendString("
\n"); } sendMenuFooter(0, 2); } /* *******************************/ void deleteUser(char* user) { if(user == NULL) { returnHTTPredirect(CONST_SHOW_USERS_HTML); return; } else if((strlen(user) < 2) || (user[0] != '1')) { sendHTTPHeader(FLAG_HTTP_TYPE_HTML, 0, 1); printHTMLheader("Delete ntop User", NULL, BITFLAG_HTML_NO_REFRESH); sendString("


\n"); printFlagedWarning("The specified username is invalid."); } else { int rc; datum key_data; decodeWebFormURL(user); key_data.dptr = user; key_data.dsize = strlen(user)+1; /* Delete a URL - clear the list */ clearUserUrlList(); rc = gdbm_delete(myGlobals.pwFile, key_data); if(rc != 0) { sendHTTPHeader(FLAG_HTTP_TYPE_HTML, 0, 1); printHTMLheader("Delete ntop User", NULL, BITFLAG_HTML_NO_REFRESH); sendString("


\n"); printFlagedWarning("ERROR: unable to delete specified user."); } else { returnHTTPredirect(CONST_SHOW_USERS_HTML); return; } } sendMenuFooter(1, 2); printHTMLtrailer(); } /* *******************************/ #define MAX_NUM_COMMUNITIES 32 void doAddUser(int len) { char *err=NULL, key_str[64], value_str[256]; int j; if(len <= 0) { err = "ERROR: both user and password must be non empty fields."; } else { char postData[256], *key, *user=NULL, *pw=NULL, *communities[MAX_NUM_COMMUNITIES]; int i, idx, badChar=0, num_communities = 0; if((idx = readHTTPpostData(len, postData, sizeof(postData))) < 0) return; /* FIXME (DL): an HTTP error code should be sent here */ for(i=0,key=postData; i 0) { strcat(value_str, communities[0]); for(j=1; j [%s][%s]", key_str, value_str); storePwValue(key_str, value_str); } if(gdbm_store(myGlobals.pwFile, key_data, data_data, GDBM_REPLACE) != 0) err = "FATAL ERROR: unable to add the new user."; /* Added user, clear the list */ clearUserUrlList(); #ifdef HAVE_CRYPTGETFORMAT /* If we have the routine, store the crypt type too */ { char cgf[LEN_MEDIUM_WORK_BUFFER]; safe_snprintf(__FILE__, __LINE__, tmpBuf, sizeof(tmpBuf), "3%s", user); key_data.dptr = tmpBuf; key_data.dsize = strlen(tmpBuf)+1; strncpy(cgf, (char*)crypt_get_format(), sizeof(cgf)); cgf[sizeof(cgf)-1] = '\0'; data_data.dptr = cgf; data_data.dsize = strlen(data_data.dptr)+1; gdbm_store(myGlobals.pwFile, key_data, data_data, GDBM_REPLACE); } #endif } } if(err != NULL) { sendHTTPHeader(FLAG_HTTP_TYPE_HTML, 0, 1); printHTMLheader("ntop: Add/Modify User", NULL, BITFLAG_HTML_NO_REFRESH); sendString("


\n"); printFlagedWarning(err); sendMenuFooter(1, 2); printHTMLtrailer(); } else { returnHTTPredirect(CONST_SHOW_USERS_HTML); } } /* *********************************** *********************************** */ void showURLs(void) { u_int numUsers=0; char buf[LEN_GENERAL_WORK_BUFFER], ebuf[256]; datum key_data, return_data; printHTMLheader("Restricted ntop URLs", NULL, BITFLAG_HTML_NO_REFRESH); sendString("


\n"); return_data = gdbm_firstkey(myGlobals.pwFile); while (return_data.dptr != NULL) { /* traceEvent(CONST_TRACE_INFO, "1) -> %s", return_data.dptr); */ key_data = return_data; if(key_data.dptr[0] == '2') { /* 2 = URL */ if(numUsers == 0) { sendString("

\n" ""TABLE_ON"\n"); sendString("\n"); } encodeWebFormURL(key_data.dptr, ebuf, sizeof(ebuf)); safe_snprintf(__FILE__, __LINE__, buf, LEN_GENERAL_WORK_BUFFER, "\n", &key_data.dptr[1], CONST_MODIFY_URL, ebuf, CONST_DELETE_URL, ebuf); sendString(buf); numUsers++; } return_data = gdbm_nextkey(myGlobals.pwFile, key_data); free(key_data.dptr); } if(numUsers > 0) { sendString("
URLsActions
" " '%s*'" "\"Modify" " \"Delete" "
"TABLE_OFF"\n

\n"); sendString("

\n"); } sendMenuFooter(3, 0); } /* *******************************/ void addURL(char* url) { int i, numUsers=0; datum key_data, return_data; char *aubuf=NULL, *authorisedUser[20]; char tmpStr[128]; printHTMLheader("Manage ntop URLs", NULL, BITFLAG_HTML_NO_REFRESH); sendString("


\n"); if((url != NULL) && ((strlen(url) < 1) || (url[0] != '2'))) { printFlagedWarning("The specified URL is invalid."); } else { sendString("

\n"); sendString("
\n"); sendString("\n"); if(url != NULL) sendString("\n"); else sendString("\n"); sendString("\n\n"); /*********** Users **********/ sendString("\n" "\n"); sendString("
URL
URLhttp://<" "ntop host>:<ntop port>/"); if(url != NULL) { decodeWebFormURL(url); safe_snprintf(__FILE__, __LINE__, tmpStr, sizeof(tmpStr), "" "%s * [Initial URL string]", &url[1], &url[1]); sendString(tmpStr); } else { sendString(" *"); } sendString("
Authorised Users: \n
"TABLE_OFF"\n"); if(url == NULL) sendString("
\n
\n" "NOTE: if you leave the URL field empty then the " "access is restricted to all ntop pages, otherwise, this " "entry matches all the pages begining with the specified string.\n" "
\n
\n"); safe_snprintf(__FILE__, __LINE__, tmpStr, sizeof(tmpStr), "   \n", (url != NULL) ? "Modify URL" : "Add URL"); sendString(tmpStr); sendString("
\n"); sendString("
\n"); } sendMenuFooter(0, 2); } /* *******************************/ void deleteURL(char* url) { if(url == NULL) { returnHTTPredirect(CONST_SHOW_URLS_HTML); return; } else if((strlen(url) < 1) || (url[0] != '2')) { sendHTTPHeader(FLAG_HTTP_TYPE_HTML, 0, 1); printHTMLheader("Delete ntop URL", NULL, BITFLAG_HTML_NO_REFRESH); sendString("


\n"); printFlagedWarning("The specified URL is invalid."); } else { int rc; datum key_data; decodeWebFormURL(url); key_data.dptr = url; key_data.dsize = strlen(url)+1; /* Delete URL, clear the list */ clearUserUrlList(); rc = gdbm_delete(myGlobals.pwFile, key_data); if(rc != 0) { sendHTTPHeader(FLAG_HTTP_TYPE_HTML, 0, 1); printHTMLheader("Delete ntop URL", NULL, BITFLAG_HTML_NO_REFRESH); sendString("


\n"); printFlagedWarning("ERROR: unable to delete specified URL."); } else { returnHTTPredirect(CONST_SHOW_URLS_HTML); return; } } sendMenuFooter(3, 0); printHTMLtrailer(); } /* *******************************/ void doAddURL(int len) { char *err=NULL; char postData[256], *key, *url=NULL, *users=NULL, authorizedUsers[256]; int i, idx, alen=0, badChar=0; /* Authorization fix courtesy of David Brown */ if((idx = readHTTPpostData(len, postData, sizeof(postData))) < 0) return; /* FIXME (DL): an HTTP error code should be sent here */ memset(authorizedUsers, 0, sizeof(authorizedUsers)); for(i=0,key=postData; i<=idx; i++) { if((i==idx) || (postData[i] == '&')) { if(users != NULL) { decodeWebFormURL(users); safe_snprintf(__FILE__, __LINE__, &authorizedUsers[alen], sizeof(authorizedUsers)-alen, "%susers=%s", (alen>0) ? "&" : "", users); alen = strlen(authorizedUsers); users = NULL; } if(i==idx) break; postData[i] = '\0'; key = &postData[i+1]; } else if((key != NULL) && (postData[i] == '=')) { postData[i] = '\0'; if(strcmp(key, "url") == 0) { url = &postData[i+1]; } else if(strcmp(key, "users") == 0) { users = &postData[i+1]; } key = NULL; } } if(url != NULL) { decodeWebFormURL(url); for(i=0; i 0 ? authorizedUsers : "(not given)"); fflush(stdout); #endif if(authorizedUsers[0] == '\0') { err = "ERROR: user must be a non empty field."; } else if(badChar) { err = "ERROR: the specified URL contains invalid characters."; } else { char tmpBuf[64]; datum data_data, key_data; safe_snprintf(__FILE__, __LINE__, tmpBuf, sizeof(tmpBuf), "2%s", url); key_data.dptr = tmpBuf; key_data.dsize = strlen(tmpBuf)+1; data_data.dptr = authorizedUsers; data_data.dsize = strlen(authorizedUsers)+1; if(gdbm_store(myGlobals.pwFile, key_data, data_data, GDBM_REPLACE) != 0) err = "FATAL ERROR: unable to add the new URL."; /* Added url, clear the list */ clearUserUrlList(); } if(err != NULL) { sendHTTPHeader(FLAG_HTTP_TYPE_HTML, 0, 1); printHTMLheader("ntop URL add", NULL, BITFLAG_HTML_NO_REFRESH); sendString("


\n"); printFlagedWarning(err); sendMenuFooter(3, 0); printHTMLtrailer(); } else { returnHTTPredirect(CONST_SHOW_URLS_HTML); } } /* *******************************/ /* Courtesy of Michael Weidel */ int doChangeFilter(int len) { int i,idx,badChar=0; struct bpf_program fcode; char *currentFilterExpressionSav; char buf[LEN_GENERAL_WORK_BUFFER],postData[256],*key,*err=NULL; currentFilterExpressionSav = strdup(myGlobals.runningPref.currentFilterExpression); /* Backup */ if((idx = readHTTPpostData(len, postData, sizeof(postData))) < 0) return 1; for(i=0,key=postData; i<=idx; i++) { if(postData[i] == '&') { postData[i] = '\0'; key = &postData[i+1]; } else if((key != NULL) && (postData[i] == '=')) { postData[i] = '\0'; if(strcmp(key, "filter") == 0) { myGlobals.runningPref.currentFilterExpression = strdup(&postData[i+1]); } key = NULL; } } if(key == NULL) { decodeWebFormURL(myGlobals.runningPref.currentFilterExpression); for(i=0; i<=\\\":[]() ", myGlobals.runningPref.currentFilterExpression[i]) != NULL))) { badChar = 1; /* Perhaps we don't have to use this check? */ break; } } } else err = "ERROR: The HTTP Post Data was invalid."; if(badChar) err = "ERROR: the specified filter expression contains invalid characters."; if(err==NULL) { traceEvent(CONST_TRACE_INFO, "Changing the kernel (libpcap) filter..."); for(i=0; i


\n

"); sendString("\n"); if(err == NULL) { if(*myGlobals.runningPref.currentFilterExpression != '\0'){ safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "Filter changed to %s.\n", myGlobals.runningPref.currentFilterExpression); sendString(buf); } else { sendString("Kernel (libpcap) filtering disabled.\n"); } sendString("

\n"); printHTMLtrailer(); if(currentFilterExpressionSav != NULL) free(currentFilterExpressionSav); return 0; } if(myGlobals.runningPref.currentFilterExpression != NULL) free(myGlobals.runningPref.currentFilterExpression); myGlobals.runningPref.currentFilterExpression = currentFilterExpressionSav; for(i=0; i */ void changeFilter(void) { char buf[LEN_GENERAL_WORK_BUFFER]; printHTMLheader("Change kernel (libpcap) filter expression", NULL, BITFLAG_HTML_NO_REFRESH); sendString("

\n"); sendString("\n\n"); sendString("\n\n"); sendString("\n"); sendString("\n"); sendString("\n\n"); sendString("
Old Filter Expression: "); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "%s", myGlobals.runningPref.currentFilterExpression); sendString(buf); if(*myGlobals.runningPref.currentFilterExpression == '\0') sendString("<No filter defined>"); sendString("
\n
New Filter Expression: \n"); sendString("
   "); sendString("
"TABLE_OFF"\n"); sendString("

\n\n"); sendString("You can use all filter expressions libpcap can handle, \n"); sendString("like the ones you pass to tcpdump.
\n"); sendString("If \"new filter expression\" is left empty, no filtering is performed.
\n"); sendString("If you want the statistics to be reset, you have to do that manually "); sendString("with Reset Stats.
\n"); sendString("Be careful: That can take quite a long time!"); sendString("
\n"); } /* *******************************/ struct _menuData { char *text, *anchor; }; static struct _menuData menuItem[] = { { "Show Users", CONST_SHOW_USERS_HTML }, { "Add User", CONST_ADD_USERS_HTML }, { "Show URLs", CONST_SHOW_URLS_HTML }, { "Add URL", CONST_ADD_URLS_HTML } }; /* *******************************/ static void sendMenuFooter(int itm1Idx, int itm2Idx) { char buf[128]; sendString("
\n"); sendString("\n"); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "[ %s ] [ %s ]\n", menuItem[itm1Idx].anchor, menuItem[itm1Idx].text, menuItem[itm2Idx].anchor, menuItem[itm2Idx].text); sendString(buf); sendString("\n
\n"); } /* *******************************/ static void encodeWebFormURL(char *in, char *buf, int buflen) { int i, j, c, d; for(i=j=0; (in[i]!='\0') && (j<(buflen-4)); i++) { c = (unsigned int)in[i]; if(isalpha(c) || isdigit(c)) { buf[j++] = (char)c; } else if(c == ' ') { buf[j++] = '+'; } else { buf[j++] = '%'; d = (c>>4) & 0x0f; buf[j++] = (d < 10) ? '0'+d : 'A'+(d-10); d = c & 0x0f; buf[j++] = (d < 10) ? '0'+d : 'A'+(d-10); } } buf[j] = '\0'; } /* *******************************/ static void decodeWebFormURL(char *buf) { int i, j; for(i=j=0; buf[i]!='\0'; i++,j++) { buf[j] = buf[i]; if(buf[j] == '+') { buf[j] = ' '; } else if(buf[j] == '%') { buf[j] = ((buf[i+1] >= 'A' ? ((buf[i+1] & 0xdf) - 'A')+10 : (buf[i+1] - '0')) & 0x0f) << 4 | ((buf[i+2] >= 'A' ? ((buf[i+2] & 0xdf) - 'A')+10 : (buf[i+2] - '0')) & 0x0f); i += 2; } } buf[j] = '\0'; } /* ****************************** */ /* Fixes below courtesy of C C Magnus Gustavsson */ static void addKeyIfMissing(char* key, char* value, int encryptValue, int existingOK, char *userQuestion) { datum key_data, return_data, data_data; #ifndef WIN32 /* 14 is ok for traditional crypt, but the enhanced crypt() in FreeBSD * (and others?) can be much larger. Just us a big buffer for ALL OSes * in case others change too... */ char cpw[LEN_MEDIUM_WORK_BUFFER]; #endif /* Check existence of user 'admin' */ key_data.dptr = key; key_data.dsize = strlen(key_data.dptr)+1; return_data = gdbm_fetch(myGlobals.pwFile, key_data); if((return_data.dptr == NULL) || (existingOK != 0)) { char *thePw, pw1[16], pw2[16]; /* If not existing, then add user 'admin' and ask for password */ if(userQuestion != NULL) { if (myGlobals.runningPref.daemonMode) { /* * We need a password for the admin user, but the user requested * daemon mode. stdin is already detached; getpass() would fail. * * Courtesy of Ambrose Li * */ traceEvent(CONST_TRACE_FATALERROR, "No password for admin user - please re-run ntop in non-daemon mode first"); exit(1); /* Just in case */ } memset(pw1, 0, sizeof(pw1)); memset(pw2, 0, sizeof(pw2)); while(pw1[0] == '\0') { thePw = getpass(userQuestion); #ifdef WIN32 if ( (isWinNT()) || (strlen(thePw) >= 5) ) { #else if (strlen(thePw) >= 5) { #endif if(strlen(thePw) > (sizeof(pw1)-1)) thePw[sizeof(pw1)-1] = '\0'; strcpy(pw1, thePw); thePw = getpass("Please enter the password again: "); if(strlen(thePw) > (sizeof(pw2)-1)) thePw[sizeof(pw2)-1] = '\0'; strcpy(pw2, thePw); if(strcmp(pw1, pw2)) { printf("Passwords don't match. Please try again.\n"); memset(pw1, 0, sizeof(pw1)); memset(pw2, 0, sizeof(pw2)); sleep(1); /* It avoids message loops */ } } else { printf("Password too short (5 characters or more). Please try again.\n"); } } value = pw1; } if(encryptValue) { #ifdef WIN32 data_data.dptr = value; #else strncpy(cpw, (char*)crypt(value, (const char*)CONST_CRYPT_SALT), sizeof(cpw)); cpw[sizeof(cpw)-1] = '\0'; data_data.dptr = cpw; #endif } else data_data.dptr = value; #ifdef DEBUG traceEvent(CONST_TRACE_INFO, "'%s' <-> '%s'", key, data_data.dptr); #endif data_data.dsize = strlen(data_data.dptr)+1; gdbm_store(myGlobals.pwFile, key_data, data_data, GDBM_REPLACE); /* Added user, clear the list */ clearUserUrlList(); /* print notice to the user */ if(memcmp(key,"1admin",6) == 0) traceEvent(CONST_TRACE_ALWAYSDISPLAY, "Admin user password has been set"); #ifdef HAVE_CRYPTGETFORMAT if(memcmp(key,"1",1) == 0) { /* If we have the routine, store the crypt type too */ char cgf[LEN_MEDIUM_WORK_BUFFER]; key_data.dptr = "3admin"; key_data.dsize = strlen(key_data.dptr)+1; strncpy(cgf, (char*)crypt_get_format(), sizeof(cgf)); cgf[sizeof(cgf)-1] = '\0'; data_data.dptr = cgf; data_data.dsize = strlen(data_data.dptr)+1; gdbm_store(myGlobals.pwFile, key_data, data_data, GDBM_REPLACE); } #endif } else free(return_data.dptr); } /* *******************************/ void setAdminPassword(char* pass) { if (pass == NULL) addKeyIfMissing("1admin", NULL, 1, 1, CONST_ADMINPW_QUESTION); else addKeyIfMissing("1admin", pass, 1, 1, NULL); } /* *******************************/ void addDefaultAdminUser(void) { /* Add user 'admin' and ask for password if not existing */ addKeyIfMissing("1admin", NULL, 1, 0, CONST_ADMINPW_QUESTION); /* Add user 'admin' for URL 'show...' if not existing */ addKeyIfMissing("2showU", "users=1admin", 0, 0, NULL); addKeyIfMissing("2modifyU", "users=1admin", 0, 0, NULL); addKeyIfMissing("2deleteU", "users=1admin", 0, 0, NULL); addKeyIfMissing("2shut", "users=1admin", 0, 0, NULL); addKeyIfMissing("2resetStats", "users=1admin", 0, 0, NULL); addKeyIfMissing("2chang", "users=1admin", 0, 0, NULL); addKeyIfMissing("2configNtop", "users=1admin", 0, 0, NULL); addKeyIfMissing("2privacyFlag","users=1admin", 0, 0, NULL); addKeyIfMissing("2"CONST_EDIT_PREFS,"users=1admin", 0, 0, NULL); addKeyIfMissing("2"CONST_PURGE_HOST,"users=1admin", 0, 0, NULL); } /* ************************************ */ #define NTOP_SAVE_PREFS "SP" #define NTOP_RESTORE_DEF "RD" #define CONFIG_STR_ENTRY(bg,title,name,size,configvalue,descr) \ safe_snprintf (__FILE__, __LINE__, buf, sizeof (buf), "%s
%s\n", bg, title, name, size, (configvalue != NULL) ? configvalue : "", descr); \ sendString (buf); #define CONFIG_FILE_ENTRY(bg,title,name,size,value,descr) \ safe_snprintf (__FILE__, __LINE__, buf, sizeof (buf), "%s
%s\n", bg, title, name, size, (value != NULL) ? value : "(null)", descr); \ sendString (buf); #define CONFIG_INT_ENTRY(bg,title,name,size,value,descr) \ safe_snprintf (__FILE__, __LINE__, buf, sizeof (buf), "%s
%s\n", bg, title, name, size, value, descr); \ sendString (buf); #define CONFIG_CHKBOX_ENTRY(bg,title,name,value,descr) \ safe_snprintf (__FILE__, __LINE__, buf, sizeof (buf), "%s
%s\n", bg, title, name, value, value ? "CHECKED" : "", descr); \ sendString (buf); #define CONFIG_RADIO_ENTRY(bg,title,name,value,descr) \ safe_snprintf (__FILE__, __LINE__, buf, sizeof (buf), "%sYesNo
%s\n", bg, title, name, value ? "CHECKED" : "", name, !value ? "CHECKED" : "", descr); \ sendString (buf); /* ************************************************* */ int processNtopConfigData (char *buf, int savePref) { char *strtokState, *mainState; int startCap = FALSE, action; UserPref tmpPrefs; char *devices = NULL, *foundDevices = NULL, *token; char basic_prefs = 0, display_prefs = 0, ip_prefs = 0, advanced_prefs = 0, debug_prefs = 0, db_prefs = 0; /* traceEvent(CONST_TRACE_INFO, "RRD: buf='%s'", buf); */ token = strtok_r(buf, "&", &mainState); tmpPrefs = myGlobals.savedPref; /* however, switch off all chkbox fields. If they've been set, they'll get * processed. If they stay turned off, it is a sign that they've been * unchecked and we need to handle this. */ tmpPrefs.enableSessionHandling = tmpPrefs.enablePacketDecoding = 0; tmpPrefs.stickyHosts = tmpPrefs.trackOnlyLocalHosts = 0; tmpPrefs.disablePromiscuousMode = tmpPrefs.disableMutexExtraInfo = 0; tmpPrefs.disableInstantSessionPurge = tmpPrefs.disableStopcap = 0; tmpPrefs.debugMode = tmpPrefs.daemonMode = tmpPrefs.w3c = 0; tmpPrefs.numericFlag = tmpPrefs.mergeInterfaces = tmpPrefs.enableL7 = 0; tmpPrefs.dontTrustMACaddr = 0; tmpPrefs.enableOtherPacketDump = tmpPrefs.enableSuspiciousPacketDump = 0; tmpPrefs.enableSessionHandling = 0; #ifdef MAKE_WITH_SSLWATCHDOG_RUNTIME tmpPrefs.useSSLwatchdog = 0; #endif #ifdef MAKE_WITH_SCHED_YIELD tmpPrefs.disableSchedYield = 0; #endif devices = tmpPrefs.devices; tmpPrefs.devices = NULL; while(token != NULL) { char *key, *value; key = strtok_r(token, "=", &strtokState); if(key != NULL) value = strtok_r(NULL, "=", &strtokState); else value = NULL; /* traceEvent(CONST_TRACE_INFO, "RRD: key(%s)=%s", key, value); */ if(key) { action = processNtopPref(key, value, savePref, &tmpPrefs); if (action) { startCap = TRUE; } if(!strcmp(key, "BASIC_PREFS")) basic_prefs = 1; else if(!strcmp(key, "DISPLAY_PREFS")) display_prefs = 1; else if(!strcmp(key, "IP_PREFS")) ip_prefs = 1; else if(!strcmp(key, "ADVANCED_PREFS")) advanced_prefs = 1; else if(!strcmp(key, "DEBUG_PREFS")) debug_prefs = 1; else if(!strcmp(key, "DB_PREFS")) db_prefs = 1; if(!strcmp(key, NTOP_PREF_DEVICES)) foundDevices = value; } token = strtok_r(NULL, "&", &mainState); } if((!foundDevices) && basic_prefs) { delPrefsValue(NTOP_PREF_DEVICES); if(tmpPrefs.devices) free(tmpPrefs.devices); tmpPrefs.devices = NULL; } if(devices) { free(devices); } /* Now we need to delete all the preferences that were unchecked. * Radio box & checkbox preferences that were set in a previous instance * but cleared in this instance will not appear in the POST data. So, if * the value has changed from what existed before, we need to remove them * from the saved preferences file. */ if (basic_prefs && myGlobals.savedPref.enableSessionHandling && !tmpPrefs.enableSessionHandling) { /* default for enableSessionHandling is TRUE */ processNtopPref(NTOP_PREF_EN_SESSION, FALSE, savePref, &tmpPrefs); } if (basic_prefs && myGlobals.savedPref.enablePacketDecoding && !tmpPrefs.enablePacketDecoding) { processNtopPref(NTOP_PREF_EN_PROTO_DECODE, FALSE, savePref, &tmpPrefs); } if (basic_prefs && myGlobals.savedPref.stickyHosts && !tmpPrefs.stickyHosts) { processNtopPref(NTOP_PREF_STICKY_HOSTS, FALSE, savePref, &tmpPrefs); } if (basic_prefs && myGlobals.savedPref.trackOnlyLocalHosts && !tmpPrefs.trackOnlyLocalHosts) { processNtopPref(NTOP_PREF_TRACK_LOCAL, FALSE, savePref, &tmpPrefs); } if (basic_prefs && myGlobals.savedPref.disablePromiscuousMode && !tmpPrefs.disablePromiscuousMode) { processNtopPref(NTOP_PREF_NO_PROMISC, FALSE, savePref, &tmpPrefs); } if (basic_prefs && myGlobals.savedPref.daemonMode && !tmpPrefs.daemonMode) { processNtopPref(NTOP_PREF_DAEMON, FALSE, savePref, &tmpPrefs); } if (display_prefs && myGlobals.savedPref.noInvalidLunDisplay && !tmpPrefs.noInvalidLunDisplay) { processNtopPref(NTOP_PREF_NO_INVLUN, FALSE, savePref, &tmpPrefs); } if (display_prefs && myGlobals.savedPref.w3c && !tmpPrefs.w3c) { processNtopPref(NTOP_PREF_W3C, FALSE, savePref, &tmpPrefs); } if (ip_prefs && myGlobals.savedPref.numericFlag && !tmpPrefs.numericFlag) { processNtopPref(NTOP_PREF_NUMERIC_IP, FALSE, savePref, &tmpPrefs); } if (advanced_prefs && myGlobals.savedPref.mergeInterfaces && !tmpPrefs.mergeInterfaces) { processNtopPref(NTOP_PREF_MERGEIF, FALSE, savePref, &tmpPrefs); } if (advanced_prefs && myGlobals.savedPref.enableL7 && !tmpPrefs.enableL7) { processNtopPref(NTOP_PREF_ENABLE_L7PROTO, FALSE, savePref, &tmpPrefs); } if (advanced_prefs && myGlobals.savedPref.disableInstantSessionPurge && !tmpPrefs.disableInstantSessionPurge) { processNtopPref(NTOP_PREF_NO_ISESS_PURGE, FALSE, savePref, &tmpPrefs); } if (advanced_prefs && myGlobals.savedPref.dontTrustMACaddr && !tmpPrefs.dontTrustMACaddr) { processNtopPref(NTOP_PREF_NO_TRUST_MAC, FALSE, savePref, &tmpPrefs); } #ifdef MAKE_WITH_SSLWATCHDOG_RUNTIME if (advanced_prefs && myGlobals.savedPref.useSSLwatchdog && !tmpPrefs.useSSLwatchdog) { processNtopPref(NTOP_PREF_USE_SSLWATCH, FALSE, savePref, &tmpPrefs); } #endif #ifdef MAKE_WITH_SCHED_YIELD if (advanced_prefs && myGlobals.savedPref.disableSchedYield && !tmpPrefs.disableSchedYield) { processNtopPref(NTOP_PREF_NO_SCHEDYLD, FALSE, savePref, &tmpPrefs); } #endif if (debug_prefs && myGlobals.savedPref.debugMode && !tmpPrefs.debugMode) { processNtopPref(NTOP_PREF_DBG_MODE, FALSE, savePref, &tmpPrefs); } if (debug_prefs && myGlobals.savedPref.enableOtherPacketDump && !tmpPrefs.enableOtherPacketDump) { processNtopPref(NTOP_PREF_DUMP_OTHER, FALSE, savePref, &tmpPrefs); } if (debug_prefs && myGlobals.savedPref.enableSuspiciousPacketDump && !tmpPrefs.enableSuspiciousPacketDump) { processNtopPref(NTOP_PREF_DUMP_SUSP, FALSE, savePref, &tmpPrefs); } if (debug_prefs && myGlobals.savedPref.disableMutexExtraInfo && !tmpPrefs.disableMutexExtraInfo) { processNtopPref(NTOP_PREF_NO_MUTEX_EXTRA, FALSE, savePref, &tmpPrefs); } if (db_prefs && myGlobals.savedPref.saveRecordsIntoDb && !tmpPrefs.saveRecordsIntoDb) { processNtopPref(NTOP_PREF_SAVE_REC_INTO_DB, FALSE, savePref, &tmpPrefs); } if (db_prefs && myGlobals.savedPref.saveSessionsIntoDb && !tmpPrefs.saveSessionsIntoDb) { processNtopPref(NTOP_PREF_SAVE_SESSIONS_INTO_DB, FALSE, savePref, &tmpPrefs); } /* Copy over the preferences now */ myGlobals.savedPref = tmpPrefs; /* Handle immediates */ myGlobals.runningPref.traceLevel = myGlobals.savedPref.traceLevel; return (startCap); } /* ************************************************* */ void printNtopConfigHeader (char *url, UserPrefDisplayPage configScr) { char buf[1024]; char theLink[32]; safe_snprintf (__FILE__, __LINE__, theLink, sizeof(theLink), "/configNtop.html?&showD="); switch (configScr) { case showPrefBasicPref: safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Basic Prefs ] " "[ Display Prefs ] " "[ IP Prefs ] " "[ FC Prefs ] " "[ Advanced Prefs ] " "[ Debugging Prefs ] " "[ DB Prefs

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); break; case showPrefDisplayPref: safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Basic Prefs ] " "[ Display Prefs ] " "[ IP Prefs ] " "[ FC Prefs ] " "[ Advanced Prefs ] " "[ Debugging Prefs ] " "[ DB Prefs

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); break; case showPrefIPPref: safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Basic Prefs ] " "[ Display Prefs ] " "[ IP Prefs ] " "[ FC Prefs ] " "[ Advanced Prefs ] " "[ Debugging Prefs ] " "[ DB Prefs

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); break; case showPrefFCPref: safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Basic Prefs ] " "[ Display Prefs ] " "[ IP Prefs ] " "[ FC Prefs ] " "[ Advanced Prefs ] " "[ Debugging Prefs ] " "[ DB Prefs

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); break; case showPrefAdvPref: safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Basic Prefs ] " "[ Display Prefs ] " "[ IP Prefs ] " "[ FC Prefs ] " "[ Advanced Prefs ] " "[ Debugging Prefs ] " "[ DB Prefs

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); break; case showPrefDbgPref: safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Basic Prefs ] " "[ Display Prefs ] " "[ IP Prefs ] " "[ FC Prefs ] " "[ Advanced Prefs ] " "[ Debugging Prefs ] " "[ DB Prefs

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); break; case showPrefDBPref: safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "

" "[ Basic Prefs ] " "[ Display Prefs ] " "[ IP Prefs ] " "[ FC Prefs ] " "[ Advanced Prefs ] " "[ Debugging Prefs ] " "[ DB Prefs

", theLink, theLink, theLink, theLink, theLink, theLink, theLink); break; } sendString (buf); safe_snprintf (__FILE__, __LINE__, buf, sizeof (buf), "
" " \n" "" "\n", theLink, configScr); sendString (buf); } /* ***************************************************** */ #ifdef WIN32 char * rindex(const char *p, int ch); /* Prototype */ char * rindex(const char *p, int ch) { union { const char *cp; char *p; } u; char *save; u.cp = p; for (save = NULL;; ++u.p) { if (*u.p == ch) save = u.p; if (*u.p == '\0') return(save); } /* NOTREACHED */ } #endif /* ***************************************************** */ void handleNtopConfig(char* url, UserPrefDisplayPage configScr, int postLen) { char buf[1024], hostStr[MAXHOSTNAMELEN+16]; bool startCap = FALSE; int len; UserPref defaults, *pref = &myGlobals.savedPref; /* * Configuration is dealt with via POST method. So read the data first. */ if (postLen) { if((len = readHTTPpostData (postLen, buf, 1024)) != postLen) { traceEvent (CONST_TRACE_WARNING, "handleNtopConfig: Unable to retrieve " "all POST data (%d, expecting %d). Aborting processing\n", len, postLen); } else { /* ============================================= * Parse input URI & store specified preferences * ============================================= */ char *token; int savePref = FALSE, restoreDef = FALSE; /* ============================================= * Parse input URI & store specified preferences * ============================================= */ if((buf != NULL) && (buf [0] != '\0')) { unescape_url(buf); /* traceEvent (CONST_TRACE_INFO, "BUF='%s'\n", buf); */ /* locate the last parameter which tells us which button got pressed */ if ((token = rindex (buf, '&')) != NULL) { token++; if (strncmp (token, NTOP_SAVE_PREFS, strlen (NTOP_SAVE_PREFS)) == 0) { savePref = TRUE; } else if (strncmp (token, NTOP_RESTORE_DEF, strlen (NTOP_RESTORE_DEF)) == 0) { restoreDef = TRUE; } } if (restoreDef) { initUserPrefs (&defaults); defaults.samplingRate = myGlobals.savedPref.samplingRate; pref = &defaults; } else { /* process preferences and start capture if necessary */ processNtopConfigData (buf, savePref); if (startCap) { /* TBD */ } } } } } /* ========================================= * Display preferences page & current values * ========================================= */ sendHTTPHeader(FLAG_HTTP_TYPE_HTML, 0, 1); printHTMLheader("Configure ntop", NULL, 0); sendString ("
\n"); printNtopConfigHeader(url, configScr); switch (configScr) { case showPrefBasicPref: { pcap_if_t *devpointer; int i, rc; char ebuf[CONST_SIZE_PCAP_ERR_BUF]; sendString("
" "\n"); } default: CONFIG_STR_ENTRY(DARK_BG, "Capture File Path (-f)", NTOP_PREF_CAPFILE, 50, pref->rFileName, "Capture file to read from (takes precedence over " "interface specification)"); CONFIG_STR_ENTRY(DARK_BG, "Capture Filter Expression (-B)", NTOP_PREF_FILTER, 50, pref->currentFilterExpression, "Restrict the traffic seen by ntop. BPF syntax."); CONFIG_INT_ENTRY(DARK_BG, "Packet sampling rate (-C)", NTOP_PREF_SAMPLING, 50, pref->samplingRate, "Sampling rate [1 = no sampling]"); if (pref->webAddr == NULL) { safe_snprintf (__FILE__, __LINE__, hostStr, sizeof (hostStr), "%d", pref->webPort); } else { safe_snprintf (__FILE__, __LINE__, hostStr, sizeof (hostStr), "%s:%d", pref->webAddr, pref->webPort); } CONFIG_STR_ENTRY(DARK_BG, "HTTP Server (-w)", NTOP_PREF_WEBPORT, 50, hostStr, "HTTP Server [Address:]Port of ntop's web interface"); #ifdef HAVE_OPENSSL if (pref->sslAddr == NULL) { safe_snprintf (__FILE__, __LINE__, hostStr, sizeof (hostStr), "%d", pref->sslPort); } else { safe_snprintf (__FILE__, __LINE__, hostStr, sizeof (hostStr), "%s:%d", pref->sslAddr, pref->sslPort); } CONFIG_STR_ENTRY(DARK_BG, "HTTPS Server (-W)", NTOP_PREF_SSLPORT, 50, hostStr, "HTTPS Server [Address:]Port of ntop's web " "interface"); #endif CONFIG_RADIO_ENTRY(DARK_BG, "Enable Session Handling (-z)", NTOP_PREF_EN_SESSION, pref->enableSessionHandling, ""); CONFIG_RADIO_ENTRY(DARK_BG, "Enable Protocol Decoders (-b)", NTOP_PREF_EN_PROTO_DECODE, pref->enablePacketDecoding, ""); CONFIG_STR_ENTRY(DARK_BG, "Flow Spec (-F)", NTOP_PREF_FLOWSPECS, 50, pref->flowSpecs, "Flow is a stream of captured packets that match a specified rule"); CONFIG_STR_ENTRY(DARK_BG, "Local Subnet Address (-m)", NTOP_PREF_LOCALADDR, 50, pref->localAddresses, "Local subnets in ntop reports (use , to separate them). Mandatory for packet capture files"); CONFIG_RADIO_ENTRY(DARK_BG, "Sticky Hosts (-c)", NTOP_PREF_STICKY_HOSTS, pref->stickyHosts, "Don't purge idle hosts from memory"); CONFIG_RADIO_ENTRY(DARK_BG, "Track Local Hosts (-g)", NTOP_PREF_TRACK_LOCAL, pref->trackOnlyLocalHosts, "Capture data only about local hosts"); CONFIG_RADIO_ENTRY(DARK_BG, "Disable Promiscuous Mode (-s)", NTOP_PREF_NO_PROMISC, pref->disablePromiscuousMode, "Don't set the interface(s) into promiscuous mode"); CONFIG_RADIO_ENTRY(DARK_BG, "Run as daemon (-d)", NTOP_PREF_DAEMON, pref->daemonMode, "Run Ntop as a daemon"); break; case showPrefDisplayPref: sendString(""); CONFIG_INT_ENTRY(DARK_BG, "Refresh Time (-r)", NTOP_PREF_REFRESH_RATE, 5, pref->refreshRate, "Delay (in secs) between automatic screen updates for " "supported HTML pages"); CONFIG_INT_ENTRY(DARK_BG, "Max Table Rows (-e)", NTOP_PREF_MAXLINES, 5, pref->maxNumLines, "Max number of lines that ntop will display on each " " generated HTML page"); sendString(""); CONFIG_RADIO_ENTRY(DARK_BG, "No Info On Invalid LUNs", NTOP_PREF_NO_INVLUN, pref->noInvalidLunDisplay, "Don't display info about non-existent LUNs"); CONFIG_RADIO_ENTRY(DARK_BG, "Use W3C", NTOP_PREF_W3C, pref->w3c, "Generate 'BETTER' (but not perfect) w3c " "compliant html 4.01 output"); break; case showPrefIPPref: sendString(""); sendString("
PreferenceConfigured Value
Capture Interfaces (-i)\n"); if(((rc = pcap_findalldevs(&devpointer, ebuf)) >= 0) && (devpointer != NULL)) { for (i = 0; devpointer != 0; i++) { if(strcmp(devpointer->name, "any")) { safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "%s
\n", NTOP_PREF_DEVICES, devpointer->name, (pref->devices && strstr(pref->devices, devpointer->name)) ? "CHECKED" : "", devpointer->description ? devpointer->description : devpointer->name); sendString(buf); } devpointer = devpointer->next; } pcap_freealldevs(devpointer); } else { sendString(""); #ifndef WIN32 if(myGlobals.userId == 0) traceEvent(CONST_TRACE_INFO, "pcap_findalldevs failed [rc=%d][%s]\n", rc, ebuf); else sendString("You cannot set the capture interface: missing privileges.
" "You need to start ntop with super-user privileges [-u]"); #endif } sendString("
Show Menus For"); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "IP
\n", NTOP_PREF_PRINT_FCORIP, NTOP_PREF_VALUE_PRINT_IPONLY, (pref->printIpOnly) ? "CHECKED" : ""); sendString(buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "FC
\n", NTOP_PREF_PRINT_FCORIP, NTOP_PREF_VALUE_PRINT_FCONLY, (pref->printFcOnly) ? "CHECKED" : ""); sendString(buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "Both\n", NTOP_PREF_PRINT_FCORIP, NTOP_PREF_VALUE_PRINT_BOTH, (!pref->printIpOnly && !pref->printFcOnly) ? "CHECKED" : ""); sendString(buf); sendString("
Use IPv4 or IPv6 (-4/-6)"); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "v4
\n", NTOP_PREF_IPV4V6, NTOP_PREF_VALUE_AF_INET, (pref->ipv4or6 == AF_INET) ? "CHECKED" : ""); sendString(buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "v6
\n", NTOP_PREF_IPV4V6, NTOP_PREF_VALUE_AF_INET6, (pref->ipv4or6 == AF_INET6) ? "CHECKED" : ""); sendString(buf); safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf), "Both\n", NTOP_PREF_IPV4V6, NTOP_PREF_VALUE_AF_BOTH, (pref->ipv4or6 == AF_UNSPEC) ? "CHECKED" : ""); sendString(buf); CONFIG_STR_ENTRY(DARK_BG, "Local Domain Name (-D)", NTOP_PREF_DOMAINNAME, 10, pref->domainName, "Only if ntop is having difficulty determining it " "from the interface or in case of capture files"); CONFIG_RADIO_ENTRY(DARK_BG, "No DNS (-n)", NTOP_PREF_NUMERIC_IP, pref->numericFlag, "Skip DNS resolution, showing " "only numeric IP addresses"); CONFIG_STR_ENTRY(DARK_BG, "TCP/UDP Protocols To Monitor (-p)", NTOP_PREF_PROTOSPECS, 50, pref->protoSpecs, "format is <label>=<protocol list> [, <" "label>=<protocol list>] OR a filename" "of a file containing such a format"); CONFIG_STR_ENTRY(DARK_BG, "P3P-CP", NTOP_PREF_P3PCP, 50, pref->P3Pcp, "Return value for p3p compact policy header"); CONFIG_STR_ENTRY(DARK_BG, "P3P-URI", NTOP_PREF_P3PURI, 50, pref->P3Puri, "Return value for p3p policyref header"); break; case showPrefFCPref: sendString(""); CONFIG_STR_ENTRY(DARK_BG, "WWN Mapper File (-N)", NTOP_PREF_WWN_MAP, 50, pref->fcNSCacheFile, "Location of file mapping VSAN/FC_ID to WWN/Alias"); break; case showPrefAdvPref: sendString(""); CONFIG_INT_ENTRY(DARK_BG, "Max Hashes (-x)", NTOP_PREF_MAXHASH, 5, pref->maxNumHashEntries, "Limit number of host hash entries created in order" " to limit memory used by ntop"); CONFIG_INT_ENTRY(DARK_BG, "Max Sessions (-X)", NTOP_PREF_MAXSESSIONS, 5, pref->maxNumSessions, "Limit number of IP sessions entries created in order" " to limit memory used by ntop"); CONFIG_RADIO_ENTRY(DARK_BG, "Don't Merge Interfaces (-M)", NTOP_PREF_MERGEIF, pref->mergeInterfaces, "Yes = merge data from all interfaces (if possible), No = do not merge data from all interfaces"); #ifdef HAVE_LIBPCRE CONFIG_RADIO_ENTRY(DARK_BG, "Enable Protocol Guessing", NTOP_PREF_ENABLE_L7PROTO, pref->enableL7, "Enabling patterm matching, ntop will be able to guess the protocol being used. " "Neverthelss this practice has a little performance penalty."); #endif CONFIG_RADIO_ENTRY(DARK_BG, "No Instant Session Purge", NTOP_PREF_NO_ISESS_PURGE, pref->disableInstantSessionPurge, "Makes ntop respect the timeouts for completed " "sessions"); CONFIG_RADIO_ENTRY(DARK_BG, "Don't Trust MAC Address (-o)", NTOP_PREF_NO_TRUST_MAC, pref->dontTrustMACaddr, "Situations which may require this option include " "port/VLAN mirror"); CONFIG_STR_ENTRY(DARK_BG, "Pcap Log Base Path (-O)", NTOP_PREF_PCAP_LOGBASE, 50, pref->pcapLogBasePath, "Directory where packet dump files are created"); #ifdef MAKE_WITH_SSLWATCHDOG_RUNTIME CONFIG_RADIO_ENTRY(DARK_BG, "Use SSL Watchdog", NTOP_PREF_USE_SSLWATCH, pref->useSSLwatchdog, ""); #endif #ifdef MAKE_WITH_SCHED_YIELD CONFIG_RADIO_ENTRY(DARK_BG, "Disable SchedYield", NTOP_PREF_NO_SCHEDYLD, pref->disableSchedYield, ""); #endif break; case showPrefDbgPref: sendString(""); CONFIG_RADIO_ENTRY(DARK_BG, "Run in debug mode (-K)", NTOP_PREF_DBG_MODE, pref->debugMode, "Simplifies debugging Ntop"); CONFIG_INT_ENTRY(DARK_BG, "Trace Level (-t)
   (takes effect immediately)", NTOP_PREF_TRACE_LVL, 5, pref->traceLevel, "Level of detailed messages ntop will display"); CONFIG_RADIO_ENTRY(DARK_BG, "Save Other Packets (-j)", NTOP_PREF_DUMP_OTHER, pref->enableOtherPacketDump, "Useful for understanding packets unclassified by " "Ntop"); CONFIG_RADIO_ENTRY(DARK_BG, "Save Suspicious Packets (-q)", NTOP_PREF_DUMP_SUSP, pref->enableSuspiciousPacketDump, "Create a dump file (pcap) of suspicious packets"); CONFIG_STR_ENTRY(DARK_BG, "Log HTTP Requests (-a)", NTOP_PREF_ACCESS_LOG, 50, pref->accessLogFile, "Request HTTP logging and specify the location of the " "log file"); #ifndef WIN32 CONFIG_INT_ENTRY(DARK_BG, "Use Syslog (-L)", NTOP_PREF_USE_SYSLOG, 5, pref->useSyslog, "Send log messages to the system log instead of stdout"); #endif CONFIG_STR_ENTRY(DARK_BG, "Write captured frames to (-l)", NTOP_PREF_PCAP_LOG, 50, pref->pcapLog, "Causes a dump file to be created of the captured by " "ntop in libpcap format"); CONFIG_RADIO_ENTRY(DARK_BG, "Disable Extra Mutex Info", NTOP_PREF_NO_MUTEX_EXTRA, pref->disableMutexExtraInfo, "Disables storing of extra information about the locks" " and unlocks of the protective mutexes Ntop uses"); break; case showPrefDBPref: sendString(""); CONFIG_RADIO_ENTRY(DARK_BG, "Save Data into DB", NTOP_PREF_SAVE_REC_INTO_DB, pref->saveRecordsIntoDb, "Enable/disable ntop to save data (sessions and NetFlow flows) into the SQL (MySQL) database."); if(pref->saveRecordsIntoDb) { CONFIG_RADIO_ENTRY(DARK_BG, "Save Sessions into DB", NTOP_PREF_SAVE_SESSIONS_INTO_DB, pref->saveSessionsIntoDb, "Enable/disable ntop to save TCP/UDP sessiond into the SQL (MySQL) database."); } else pref->saveSessionsIntoDb = 0; CONFIG_STR_ENTRY(DARK_BG, "DB Configuration", NTOP_PREF_SQL_DB_CONFIG, 20, pref->sqlDbConfig, "Database (MySQL) database configuration: format <Db host>:<DB user>:<DB User Pw>.
" "Note that the credentials must allow this user to create tables,
" " hence make sure that the user privileges are properly specified.

" "Note: changes will have effect at the next ntop restart"); CONFIG_INT_ENTRY(DARK_BG, "DB Max record lifetime", NTOP_PREF_SQL_REC_LIFETIME, 5, pref->sqlRecDaysLifetime, "Maximum database (MySQL) records (flows and netflows) persistence [days] in the database after which
" "will be automatically removed. Set this parameter to 0 (zero) to disable record purge."); break; } sendString ("

"); /* Save Prefs */ if (configScr == showPrefDisplayPref) { sendString(" 

" " " " " "" "\n" "

\n

\n"); } else { sendString(" 

" " " "" "\n" "\n

\n"); } sendString ("

Except as indicated, settings take effect at next startup

"); sendString ("

See Show Configuration" " for runtime values

"); printHTMLtrailer(); }