"Fossies" - the Fresh Open Source Software Archive

Member "vnstat-2.9/src/ibw.c" (26 Jul 2021, 5150 Bytes) of package /linux/misc/vnstat-2.9.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ibw.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.7_vs_2.8.

    1 #include "common.h"
    2 #include "cfg.h"
    3 #include "ifinfo.h"
    4 #include "ibw.h"
    5 
    6 int ibwloadcfg(const char *cfgfile)
    7 {
    8     FILE *fd;
    9     int ret;
   10 
   11     ifacebw = NULL;
   12 
   13     ret = opencfgfile(cfgfile, &fd);
   14     if (ret != 2)
   15         return ret;
   16 
   17     rewind(fd);
   18     ibwcfgread(fd);
   19     fclose(fd);
   20 
   21     if (debug)
   22         ibwlist();
   23 
   24     return 1;
   25 }
   26 
   27 int ibwadd(const char *iface, const uint32_t limit)
   28 {
   29     ibwnode *n, *p = ifacebw;
   30 
   31     /* add new node if list is empty */
   32     if (p == NULL) {
   33 
   34         n = (ibwnode *)malloc(sizeof(ibwnode));
   35 
   36         if (n == NULL) {
   37             return 0;
   38         }
   39 
   40         n->next = ifacebw;
   41         ifacebw = n;
   42         strncpy_nt(n->interface, iface, 32);
   43         n->limit = limit;
   44         n->fallback = limit;
   45         n->retries = 0;
   46         n->detected = 0;
   47 
   48     } else {
   49 
   50         /* update previous value if already in list */
   51         while (p != NULL) {
   52             if (strcmp(p->interface, iface) == 0) {
   53                 p->limit = limit;
   54                 return 1;
   55             }
   56             p = p->next;
   57         }
   58 
   59         /* add new node if not found */
   60         n = (ibwnode *)malloc(sizeof(ibwnode));
   61 
   62         if (n == NULL) {
   63             return 0;
   64         }
   65 
   66         n->next = ifacebw;
   67         ifacebw = n;
   68         strncpy_nt(n->interface, iface, 32);
   69         n->limit = limit;
   70         n->fallback = limit;
   71         n->retries = 0;
   72         n->detected = 0;
   73     }
   74 
   75     return 1;
   76 }
   77 
   78 void ibwlist(void)
   79 {
   80     int i = 1;
   81     ibwnode *p = ifacebw;
   82 
   83     if (p == NULL) {
   84         printf("ibw list is empty.\n");
   85         return;
   86     }
   87 
   88     printf("ibw: ");
   89     while (p != NULL) {
   90         printf("%2d: i\"%s\" l%u f%u r%d d%u  ", i, p->interface, p->limit, p->fallback, p->retries, (unsigned int)p->detected);
   91         p = p->next;
   92         i++;
   93     }
   94     printf("\n");
   95 }
   96 
   97 int ibwget(const char *iface, uint32_t *limit)
   98 {
   99     ibwnode *p = ifacebw;
  100     time_t current;
  101     uint32_t speed;
  102 
  103     *limit = 0;
  104     current = time(NULL);
  105 
  106     /* search for interface specific limit */
  107     while (p != NULL) {
  108         if (strcasecmp(p->interface, iface) == 0) {
  109 
  110             /* never override manually configured limits */
  111             if (p->detected == 0 && p->limit > 0) {
  112                 *limit = p->limit;
  113                 return 1;
  114             }
  115 
  116             if (!istun(iface) && cfg.bwdetection && p->retries < 5) {
  117                 if (cfg.bwdetectioninterval > 0 && (current - p->detected) > (cfg.bwdetectioninterval * 60)) {
  118                     speed = getifspeed(iface);
  119                     if (speed > 0) {
  120                         if (p->detected > 0 && speed != p->limit) {
  121                             snprintf(errorstring, 1024, "Detected bandwidth limit for \"%s\" changed from %" PRIu32 " Mbit to %" PRIu32 " Mbit.", iface, p->limit, speed);
  122                             printe(PT_Info);
  123                         }
  124                         p->limit = speed;
  125                         p->retries = 0;
  126                         p->detected = current;
  127                         *limit = speed;
  128                         return 1;
  129                     }
  130                     p->retries++;
  131                 }
  132             }
  133 
  134             if (p->limit > 0) {
  135                 *limit = p->limit;
  136                 return 1;
  137             } else {
  138                 return 0;
  139             }
  140         }
  141         p = p->next;
  142     }
  143 
  144     if (!istun(iface) && cfg.bwdetection) {
  145         if (ibwadd(iface, (uint32_t)cfg.maxbw)) {
  146             p = ibwgetnode(iface);
  147             if (p != NULL) {
  148                 speed = getifspeed(iface);
  149                 if (speed > 0) {
  150                     p->limit = speed;
  151                     p->retries = 0;
  152                     p->detected = current;
  153                     *limit = speed;
  154                     return 1;
  155                 }
  156                 p->retries++;
  157             }
  158         }
  159     }
  160 
  161     /* return default limit if specified */
  162     if (cfg.maxbw > 0) {
  163         *limit = (uint32_t)cfg.maxbw;
  164         return 1;
  165     }
  166     return 0;
  167 }
  168 
  169 ibwnode *ibwgetnode(const char *iface)
  170 {
  171     ibwnode *p = ifacebw;
  172 
  173     while (p != NULL) {
  174         if (strcasecmp(p->interface, iface) == 0) {
  175             return p;
  176         }
  177         p = p->next;
  178     }
  179     return NULL;
  180 }
  181 
  182 void ibwflush(void)
  183 {
  184     ibwnode *f, *p = ifacebw;
  185 
  186     while (p != NULL) {
  187         f = p;
  188         p = p->next;
  189         free(f);
  190     }
  191 
  192     ifacebw = NULL;
  193 }
  194 
  195 int ibwcfgread(FILE *fd)
  196 {
  197     char cfgline[512], name[512], value[512];
  198     int i, j, linelen, count = 0;
  199     long ivalue;
  200 
  201     /* start from value search from first line */
  202     rewind(fd);
  203 
  204     /* cycle all lines */
  205     while (!feof(fd)) {
  206 
  207         cfgline[0] = '\0';
  208 
  209         /* get current line */
  210         if (fgets(cfgline, 512, fd) == NULL) {
  211             break;
  212         }
  213 
  214         linelen = (int)strlen(cfgline);
  215 
  216         if (linelen <= 8 || cfgline[0] == '#') {
  217             continue;
  218         }
  219 
  220         if (strncasecmp(cfgline, "MaxBW", 5) != 0) {
  221             continue;
  222         }
  223 
  224         /* clear name and value buffers */
  225         for (j = 0; j < 512; j++) {
  226             name[j] = value[j] = '\0';
  227         }
  228 
  229         /* get interface name */
  230         j = 0;
  231         for (i = 5; i < linelen; i++) {
  232             if (cfgline[i] == ' ' || cfgline[i] == '=' || cfgline[i] == '\t' || cfgline[i] == '\n' || cfgline[i] == '\r') {
  233                 break;
  234             } else {
  235                 name[j] = cfgline[i];
  236                 j++;
  237             }
  238         }
  239 
  240         /* get new line if no usable name was found */
  241         if (strlen(name) == 0) {
  242             continue;
  243         }
  244 
  245         /* search value */
  246         j = 0;
  247         for (i++; i < linelen; i++) {
  248             if (cfgline[i] == '\n' || cfgline[i] == '\r') {
  249                 break;
  250             } else if (cfgline[i] == '\"') {
  251                 if (j == 0) {
  252                     continue;
  253                 } else {
  254                     break;
  255                 }
  256             } else {
  257                 if (j == 0 && (cfgline[i] == ' ' || cfgline[i] == '=' || cfgline[i] == '\t')) {
  258                     continue;
  259                 } else {
  260                     value[j] = cfgline[i];
  261                     j++;
  262                 }
  263             }
  264         }
  265 
  266         /* get new line if no usable value was found */
  267         if ((strlen(value) == 0) || (!isdigit(value[0]))) {
  268             continue;
  269         }
  270 
  271         /* add interface and limit to list if value is within limits */
  272         ivalue = strtol(value, (char **)NULL, 0);
  273         if (ivalue < 0 || ivalue > BWMAX) {
  274             snprintf(errorstring, 1024, "Invalid value \"%ld\" for MaxBW%s, ignoring parameter.", ivalue, name);
  275             printe(PT_Config);
  276         } else {
  277             ibwadd(name, (uint32_t)ivalue);
  278         }
  279     }
  280 
  281     return count;
  282 }