Make get_rates be table based and go up to terrabits.

(Logical change 1.65)
diff --git a/tc/tc_util.c b/tc/tc_util.c
index 876f1d0..d87085c 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -97,44 +97,55 @@
 	return buf;
 }
 
-/*
- * NB: rates are scaled differently depending on bits or bytes.
- *     if bits are requested then k == 1000 
- *     for bytes k = 1024
- */
+/* See http://physics.nist.gov/cuu/Units/binary.html */
+static const struct rate_suffix {
+	const char *name;
+	double scale;
+} suffixes[] = {
+	{ "bit",	1. },
+	{ "Kibit",	1024. },
+	{ "kbit",	1000. },
+	{ "mibit",	1024.*1024. },
+	{ "mbit",	1000000. },
+	{ "gibit",	1024.*1024.*1024. },
+	{ "gbit",	1000000000. },
+	{ "tibit",	1024.*1024.*1024.*1024. },
+	{ "tbit",	1000000000000. },
+	{ "Bps",	8. },
+	{ "KiBps",	8.*1024. },
+	{ "KBps",	8000. },
+	{ "MiBps",	8.*1024*1024. },
+	{ "MBps",	8000000. },
+	{ "GiBps",	8.*1024.*1024.*1024. },
+	{ "GBps",	8000000000. },
+	{ "TiBps",	8.*1024.*1024.*1024.*1024. },
+	{ "TBps",	8000000000000. },
+	{ NULL }
+};
+
+
 int get_rate(unsigned *rate, const char *str)
 {
 	char *p;
 	double bps = strtod(str, &p);
+	const struct rate_suffix *s;
 
 	if (p == str)
 		return -1;
 
-	if (*p == 0 || strcasecmp(p, "bit") == 0)
-		bps /= 8;
-	else if (strcasecmp(p, "kbit") == 0)
-		bps = (bps * 1000.) / 8;
-	else if (strcasecmp(p, "mbit") == 0)
-		bps = (bps * 1000000.)/8;
-	else if (strcasecmp(p, "gbit") == 0)
-		bps = (bps * 1000000000.)/8;
-	else if (strcasecmp(p, "kibit") == 0)
-		bps *= 1024 / 8;
-	else if (strcasecmp(p, "mibit") == 0)
-		bps *= 1024*1024/8;
-	else if (strcasecmp(p, "gibit") == 0)
-		bps *= 1024*1024*1024/8;
-	else if (strcasecmp(p, "kbps") == 0)
-		bps *= 1024;
-	else if (strcasecmp(p, "mbps") == 0)
-		bps *= 1024*1024;
-	else if (strcasecmp(p, "gbps") == 0)
-		bps *= 1024*1024*1024;
-	else if (strcasecmp(p, "bps") != 0)
-		return -1;
+	if (*p == '\0') {
+		*rate = bps / 8.;	/* assume bytes/sec */
+		return 0;
+	}
 
-	*rate = bps;
-	return 0;
+	for (s = suffixes; s->name; ++s) {
+		if (strcasecmp(s->name, p) == 0) {
+			*rate = (bps * s->scale) / 8.;
+			return 0;
+		}
+	}
+
+	return -1;
 }
 
 int get_rate_and_cell(unsigned *rate, int *cell_log, char *str)
@@ -174,11 +185,11 @@
 	if (use_iec) {
 		if (tmp >= 1024*1023 && 
 		    fabs(1024*1024*rint(tmp/(1024*1024)) - tmp) < 1024)
-			snprintf(buf, len, "%gMibps", rint(tmp/(1024*1024)));
+			snprintf(buf, len, "%gMibit", rint(tmp/(1024*1024)));
 		else if (tmp >= 1024-16 && fabs(1024*rint(tmp/1024) - tmp) < 16)
-			snprintf(buf, len, "%gKibps", rint(tmp/1024));
+			snprintf(buf, len, "%gKibit", rint(tmp/1024));
 		else
-			snprintf(buf, len, "%ubps", rate);
+			snprintf(buf, len, "%ubit", rate);
 
 	} else { 
 		if (tmp >= 999999 &&