Browse Source

map: fix psidlen becoming negative (FS#1430)

Fix psidlen becomes negative in case embedded address bit lenght is smaller than
IPv4 suffix length.
While at it improve parameter checking making the code more logical and
easier to read.

Signed-off-by: Hans Dedecker <[email protected]>
Hans Dedecker 8 years ago
parent
commit
479aaf6375
2 changed files with 17 additions and 11 deletions
  1. 1 1
      package/network/ipv6/map/Makefile
  2. 16 10
      package/network/ipv6/map/src/mapcalc.c

+ 1 - 1
package/network/ipv6/map/Makefile

@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=map
 PKG_VERSION:=4
-PKG_RELEASE:=9
+PKG_RELEASE:=10
 PKG_LICENSE:=GPL-2.0
 
 include $(INCLUDE_DIR)/package.mk

+ 16 - 10
package/network/ipv6/map/src/mapcalc.c

@@ -4,6 +4,7 @@
  * Author: Steven Barth <[email protected]>
  * Copyright (c) 2014-2015 cisco Systems, Inc.
  * Copyright (c) 2015 Steven Barth <[email protected]>
+ * Copyright (c) 2018 Hans Dedecker <[email protected]>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2
@@ -311,25 +312,30 @@ int main(int argc, char *argv[])
 
 		if (psidlen <= 0) {
 			psidlen = ealen - (32 - prefix4len);
+			if (psidlen < 0)
+				psidlen = 0;
+
 			psid = -1;
 		}
 
-		if (psid < 0 && psidlen <= 16 && psidlen >= 0 && pdlen >= 0 && ealen >= psidlen) {
+		if (prefix4len < 0 || prefix6len < 0 || ealen < 0 || psidlen > 16 || ealen < psidlen) {
+			fprintf(stderr, "Skipping invalid or incomplete rule: %s\n", argv[i]);
+			status = 1;
+			continue;
+		}
+
+		if (psid < 0 && psidlen >= 0 && pdlen >= 0) {
 			bmemcpys64(&psid16, &pd, prefix6len + ealen - psidlen, psidlen);
 			psid = be16_to_cpu(psid16);
 		}
 
-		psid = psid >> (16 - psidlen);
-		psid16 = cpu_to_be16(psid);
-		psid = psid << (16 - psidlen);
-
-		if (prefix4len < 0 || prefix6len < 0 || ealen < 0 || ealen < psidlen) {
-			fprintf(stderr, "Skipping invalid or incomplete rule: %s\n", argv[i]);
-			status = 1;
-			continue;
+		if (psidlen > 0) {
+			psid = psid >> (16 - psidlen);
+			psid16 = cpu_to_be16(psid);
+			psid = psid << (16 - psidlen);
 		}
 
-		if ((pdlen >= 0 || ealen == psidlen) && ealen >= psidlen) {
+		if (pdlen >= 0 || ealen == psidlen) {
 			bmemcpys64(&ipv4addr, &pd, prefix6len, ealen - psidlen);
 			ipv4addr.s_addr = htonl(ntohl(ipv4addr.s_addr) >> prefix4len);
 			bmemcpy(&ipv4addr, &ipv4prefix, prefix4len);