Index: extensions/libipt_string.c
===================================================================
RCS file: /cvspublic/iptables/extensions/libipt_string.c,v
retrieving revision 1.11
diff -u -r1.11 libipt_string.c
--- extensions/libipt_string.c	5 Jan 2004 09:50:12 -0000	1.11
+++ extensions/libipt_string.c	23 Mar 2004 05:05:38 -0000
@@ -32,8 +32,10 @@
 {
 	printf(
 "STRING match v%s options:\n"
-"--string [!] string          Match a string in a packet\n"
-"--hex-string [!] string      Match a hex string in a packet\n",
+"--string [!] string          Match a string in a packet.\n"
+"--hex-string [!] string      Match a hex string in a packet.\n"
+"--replace-string             Replace matching string with a new string.\n"
+"--replace-hex-string         Replace matching string with a new hex string.\n",
 IPTABLES_VERSION);
 }
 
@@ -41,6 +43,8 @@
 static struct option opts[] = {
 	{ .name = "string",     .has_arg = 1, .flag = 0, .val = '1' },
 	{ .name = "hex-string", .has_arg = 1, .flag = 0, .val = '2' },
+	{ .name = "replace-string", .has_arg = 1, .flag = 0, .val = '3' },
+	{ .name = "replace-hex-string", .has_arg = 1, .flag = 0, .val = '4' },
 	{ .name = 0 }
 };
 
@@ -54,15 +58,15 @@
 
 
 static void
-parse_string(const unsigned char *s, struct ipt_string_info *info)
+parse_string(const unsigned char *s, char *string)
 {	
-	if (strlen(s) <= BM_MAX_NLEN) strcpy(info->string, s);
+	if (strlen(s) <= BM_MAX_NLEN) strcpy(string, s);
 	else exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s);
 }
 
 
 static void
-parse_hex_string(const unsigned char *s, struct ipt_string_info *info)
+parse_hex_string(const unsigned char *s, char *string, u_int16_t *len)
 {
 	int i=0, slen, sindex=0, schar;
 	short hex_f = 0, literal_f = 0;
@@ -101,7 +105,7 @@
 				exit_error(PARAMETER_PROBLEM,
 					"Bad literal placement at end of string");
 			}
-			info->string[sindex] = s[i+1];
+			string[sindex] = s[i+1];
 			i += 2;  /* skip over literal char */
 			literal_f = 0;
 		} else if (hex_f) {
@@ -123,20 +127,20 @@
 			if (! sscanf(hextmp, "%x", &schar))
 				exit_error(PARAMETER_PROBLEM,
 					"Invalid hex char `%c'", s[i]);
-			info->string[sindex] = (char) schar;
+			string[sindex] = (char) schar;
 			if (s[i+2] == ' ')
 				i += 3;  /* spaces included in the hex block */
 			else
 				i += 2;
 		} else {  /* the char is not part of hex data, so just copy */
-			info->string[sindex] = s[i];
+			string[sindex] = s[i];
 			i++;
 		}
 		if (sindex > BM_MAX_NLEN)
 			exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s);
 		sindex++;
 	}
-	info->len = sindex;
+	*len = sindex;
 }
 
 
@@ -157,7 +161,7 @@
 				   "Can't specify multiple strings");
 
 		check_inverse(optarg, &invert, &optind, 0);
-		parse_string(argv[optind-1], stringinfo);
+		parse_string(argv[optind-1], stringinfo->string);
 		if (invert)
 			stringinfo->invert = 1;
 		stringinfo->len=strlen((char *)&stringinfo->string);
@@ -167,15 +171,51 @@
 	case '2':
 		if (*flags)
 			exit_error(PARAMETER_PROBLEM,
-				   "Can't specify multiple strings");
+				   "Can't specify multiple hex strings");
 
 		check_inverse(optarg, &invert, &optind, 0);
-		parse_hex_string(argv[optind-1], stringinfo);  /* sets length */
+		parse_hex_string(argv[optind-1], stringinfo->string, &stringinfo->len);
 		if (invert)
 			stringinfo->invert = 1;
 		*flags = 1;
 		break;
 
+	case '3':
+		if (! *flags)
+			exit_error(PARAMETER_PROBLEM,
+				"Must specify a string to replace with --string or --hex-string");
+
+		check_inverse(optarg, &invert, &optind, 0);
+		if (invert)
+			exit_error(PARAMETER_PROBLEM,
+				"Can't negate --replace-string");
+		parse_string(argv[optind-1], stringinfo->replace_str);
+		stringinfo->replace_len=strlen((char *)&stringinfo->replace_str);
+		/* make absolutely sure the replace string length is less than
+		 * or equal to the length of the string to be replaced */
+		if (stringinfo->replace_len > stringinfo->len)
+			exit_error(PARAMETER_PROBLEM,
+				"Length of replace string must be <= length of string to be replaced");
+		break;
+
+	case '4':
+		if (! *flags)
+			exit_error(PARAMETER_PROBLEM,
+				"Must specify a string to replace with --string or --hex-string");
+
+		check_inverse(optarg, &invert, &optind, 0);
+		if (invert)
+			exit_error(PARAMETER_PROBLEM,
+				"Can't negate --replace-hex-string");
+		parse_hex_string(argv[optind-1], stringinfo->replace_str,
+			&stringinfo->replace_len);
+		/* make absolutely sure the replace string length is less than
+		 * or equal to the length of the string to be replaced */
+		if (stringinfo->replace_len > stringinfo->len)
+			exit_error(PARAMETER_PROBLEM,
+				"Length of replace string must be <= length of string to be replaced");
+		break;
+
 	default:
 		return 0;
 	}
@@ -253,6 +293,16 @@
 		printf("STRING match %s", (info->invert) ? "!" : "");
 		print_string(info->string, info->len);
 	}
+	/* print replace string (if any) */
+	if (info->replace_len > 0) {
+		if (is_hex_string(info->replace_str, info->replace_len)) {
+			printf("REPLACE ");
+			print_hex_string(info->replace_str, info->replace_len);
+		} else {
+			printf("REPLACE ");
+			print_string(info->replace_str, info->replace_len);
+		}
+	}
 }
 
 
@@ -269,6 +319,16 @@
 	} else {
 		printf("--string %s", (info->invert) ? "! ": "");
 		print_string(info->string, info->len);
+	}
+	/* print out --replace-string args (if necessary) */
+	if (info->replace_len > 0) {
+		if (is_hex_string(info->replace_str, info->replace_len)) {
+			printf("--replace-hex-string ");
+			print_hex_string(info->replace_str, info->replace_len);
+		} else {
+			printf("--replace-string ");
+			print_string(info->replace_str, info->replace_len);
+		}
 	}
 }
 

