summaryrefslogtreecommitdiff
path: root/accel-pppd/shaper/shaper.c
diff options
context:
space:
mode:
authorVladislav Grishenko <themiron@mail.ru>2020-09-11 20:49:57 +0500
committerVladislav Grishenko <themiron@mail.ru>2020-09-11 20:49:57 +0500
commitf18b6016ec9c96738f54fbb1f833de862edc6bee (patch)
treef23557630611494e93371fbc7707feb1fbe76e6b /accel-pppd/shaper/shaper.c
parent59f8e1bc3f199c8d0d985253e19a74ad87130179 (diff)
downloadaccel-ppp-f18b6016ec9c96738f54fbb1f833de862edc6bee.tar.gz
accel-ppp-f18b6016ec9c96738f54fbb1f833de862edc6bee.zip
shaper: add support for speed suffixes (B/K/M/G)
Diffstat (limited to 'accel-pppd/shaper/shaper.c')
-rw-r--r--accel-pppd/shaper/shaper.c60
1 files changed, 45 insertions, 15 deletions
diff --git a/accel-pppd/shaper/shaper.c b/accel-pppd/shaper/shaper.c
index 13f75c0f..55bec4fc 100644
--- a/accel-pppd/shaper/shaper.c
+++ b/accel-pppd/shaper/shaper.c
@@ -2,6 +2,7 @@
#include <errno.h>
#include <string.h>
#include <stdio.h>
+#include <ctype.h>
#include <netinet/in.h>
#include <linux/if.h>
#include <sys/ioctl.h>
@@ -193,29 +194,58 @@ static struct shaper_pd_t *find_pd(struct ap_session *ses, int create)
return NULL;
}
+static long int parse_integer(const char *str, char **endptr, double *multiplier)
+{
+ const static struct {
+ char suffix;
+ double multiplier;
+ } table[] = {
+ { 'B', 0.001 },
+ { 'K', 1.0 },
+ { 'M', 1000.0 },
+ { 'G', 10000000.0 }
+ };
+ long int val;
+ int i;
+
+ val = strtol(str, endptr, 10);
+ if (multiplier) {
+ *multiplier = 1;
+ if (endptr && **endptr) {
+ char suffix = toupper(**endptr);
+ for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) {
+ if (table[i].suffix == suffix) {
+ *multiplier = table[i].multiplier;
+ (*endptr)++;
+ break;
+ }
+ }
+ }
+ }
+
+ return val;
+}
+
static void parse_string_simple(const char *str, int dir, int *speed, int *burst, int *tr_id)
{
char *endptr;
long int val;
+ double mult = 1;
- val = strtol(str, &endptr, 10);
- if (*endptr == 0) {
- *speed = conf_multiplier * val;
- return;
- }
+ val = parse_integer(str, &endptr, &mult);
if (*endptr == ',') {
*tr_id = val;
- val = strtol(endptr + 1, &endptr, 10);
+ val = parse_integer(endptr + 1, &endptr, &mult);
}
- if (*endptr == 0) {
- *speed = conf_multiplier * val;
- return;
- } else {
- if (*endptr == '/' || *endptr == '\\' || *endptr == ':') {
- if (dir == ATTR_DOWN)
- *speed = conf_multiplier * val;
- else
- *speed = conf_multiplier * strtol(endptr + 1, &endptr, 10);
+ if (*endptr == '\0')
+ *speed = conf_multiplier * mult * val;
+ else if (*endptr == '/' || *endptr == '\\' || *endptr == ':') {
+ if (dir == ATTR_DOWN)
+ *speed = conf_multiplier * mult * val;
+ else {
+ val = parse_integer(endptr + 1, &endptr, &mult);
+ if (*endptr == '\0')
+ *speed = conf_multiplier * mult * val;
}
}
}