[bwm-tools-devel] COMMIT - r67 - in trunk: . bwm_firewall doc lib
Brought to you by:
nkukard
From: <sv...@li...> - 2005-04-06 09:15:20
|
Author: nkukard Date: 2005-04-06 09:14:20 +0000 (Wed, 06 Apr 2005) New Revision: 67 Modified: trunk/TODO trunk/bwm_firewall/bwm_firewall.c trunk/doc/bwmtools.texi trunk/doc/stamp-vti trunk/doc/version.texi trunk/lib/xmlConf.c Log: * Added support for masq tag in NAT section for MASQUERADE support * Fixed some memory cleanup issues in xml parser * Removed xml library version checking * Added check for configuration file presense * Throw an error for invalid tags in <nat> section * Added checks for NAT tag parameter validity * Fixed some error messages that didn't have newlines at the end * Fixed bug where comments in the NAT section create an endless loop in bwm_firewall * Updated documentation to reflect changes * Updated TODO appropriately Modified: trunk/TODO =================================================================== --- trunk/TODO 2005-01-30 16:03:38 UTC (rev 66) +++ trunk/TODO 2005-04-06 09:14:20 UTC (rev 67) @@ -4,12 +4,8 @@ * Add limits on number of packets * Add graphing support to bwm_monitor * Add multiple views to bwm_monitor -* to-destination is invalid in snat section -* to-source is invalid in dnat section * Add checking for the port param in the xml file, proto must be specified * Totals option on graphing, aswell as a few more options: avg, time from, time to, totals -* Add a queue to bwmd of the incomming and one of the outgoing/dropped packets so we keep - netlink syn, not async * Add maxRate graphing to graph.c * Add shared mem resizing to stats.c * Add menu to bwm_monitor to which IP it wants to connect to, authentication aswell and default Modified: trunk/bwm_firewall/bwm_firewall.c =================================================================== --- trunk/bwm_firewall/bwm_firewall.c 2005-01-30 16:03:38 UTC (rev 66) +++ trunk/bwm_firewall/bwm_firewall.c 2005-04-06 09:14:20 UTC (rev 67) @@ -64,8 +64,9 @@ char *tableName; int i; char counters[7] = ""; + struct stat fstat; + - // Loop with a table void processTable(gpointer p_key, gpointer p_value, gpointer p_user_data) { @@ -128,12 +129,25 @@ } - + /* Don't test version, it displays a nasty error + LIBXML_TEST_VERSION + */ // COMPAT: Do not genrate nodes for formatting spaces - LIBXML_TEST_VERSION xmlKeepBlanksDefault(0); - - // FIXME - check if file exists + + /* Check if file exists */ + if (stat(filename,&fstat) != 0) + { + fprintf(stderr,"ERROR: Failed to stat configuration path \"%s\": %s",filename,strerror(errno)); + return NULL; + } + else + if (!S_ISREG(fstat.st_mode)) + { + fprintf(stderr,"ERROR: Specified configuration path \"%s\" is not a regular file",filename); + return NULL; + } + // Build an XML tree from a the file doc = xmlParseFile(filename); if (doc == NULL) @@ -184,13 +198,16 @@ // Try find sections if (!xmlStrcmp(cur->name, (const xmlChar *) "global")) classHash = parseGlobal(doc,cur); - if (!xmlStrcmp(cur->name, (const xmlChar *) "acl")) + else if (!xmlStrcmp(cur->name, (const xmlChar *) "acl")) parseACL(doc,cur,fwHash,classHash); - if (!xmlStrcmp(cur->name, (const xmlChar *) "nat")) + else if (!xmlStrcmp(cur->name, (const xmlChar *) "nat")) parseNAT(doc,cur,fwHash,classHash); - if (!xmlStrcmp(cur->name, (const xmlChar *) "traffic")) + else if (!xmlStrcmp(cur->name, (const xmlChar *) "traffic")) parseTraffic(doc,cur,fwHash,classHash); - + // Make sure this isn't a comment + else if (xmlStrcmp(cur->name, (const xmlChar *) "text")) + fprintf(stderr,"ERROR: Section <%s> not recognised, ignoring",cur->name); + // Next plz!! cur = cur->next; } Modified: trunk/doc/bwmtools.texi =================================================================== --- trunk/doc/bwmtools.texi 2005-01-30 16:03:38 UTC (rev 66) +++ trunk/doc/bwmtools.texi 2005-04-06 09:14:20 UTC (rev 67) @@ -499,6 +499,11 @@ traffic_to_webserver </rule> </dnat> + <masq> + <rule name="traf_to_from_inside"> + internal_dsl_ips + </rule> + </masq> </nat> . . @@ -506,11 +511,11 @@ </firewall> @end smallexample @* -There are 2 tags available, @code{<snat>} and @code{<dnat>}, these two -tags are used for soure network address translation and destination -address translation respectively. +There are 3 tags available, @code{<snat>}, @code{<dnat>} and @code{<masq>}, +these three tags are used for source network address translation, destination +address translation and masquerading respectively. @*@* -Valid options for these two tags are as follows@dots{} +Valid options for these tags are as follows@dots{} @* @itemize @item @@ -523,10 +528,10 @@ internet comming from the webservers internal IP 192.168.1.100 which is not going to work, the firewall translates 192.168.1.100 to a globally routable IP address. -@* +@*@* There are no parameters for this tag, although the following sub-tags and parameters are available@dots{} -@* +@*@* @itemize @item @cindex rule @@ -568,7 +573,7 @@ @*@* There are no parameters for this tag, although the following sub-tags and parameters are available@dots{} -@* +@*@* @itemize @item @cindex rule @@ -594,7 +599,48 @@ @*@* Multiple classes can be listed, one per line. @end itemize + +@* +@item +@cindex masq +Masquerading using @code{<masq>} +@*@* +Masquerading is normally used for source address translation in the +scenario where you have a dynamic IP and never know what address to do the +translation to. An example of which is a home PC acting as a DSL router. +@*@* +There are no parameters for this tag, although the following sub-tags and +parameters are available@dots{} +@*@* +@itemize +@item +@cindex rule +Specify a rule with @code{<rule> @dots{} </rule>} +@*@* +The @code{<rule>} tag is used to specify what classes apply to what rule, +and are in order inserted into the actual iptables chains as iptables rules. + +The @code{<rule>} tag takes the following parameters@dots{} +@* +@itemize +@item +@code{name="@dots{}"} - Optional name of rule +@* +@item +@cindex to-ports +@code{to-ports"@dots{}"} - This specifies a range of source ports to use, +overriding the default SNAT source port-selection heuristics. For this +parameter to work you MUST have defined a protocol in all the classes +specified. For example @code{proto="tcp"}. @end itemize + +Between the opening and closing tags, classes defined in the @code{<global>} +section are listed, these classify which traffic applies to which rule. +@*@* +Multiple classes can be listed, one per line. +@end itemize + +@end itemize @* An example using the above definitions would look something like this@dots{} @* @@ -626,8 +672,31 @@ </firewall> @end smallexample +@* +Here is an example if you pc is acting as a DSL router@dots{} +@* +@smallexample +<firewall> + # Global configuration and access classes + <global> + <class name="traf_going_to_dsl"> + <address src="192.168.0.0/24"/> + </class> + </global> + # Network address translation + <nat> + <masq> + <rule name="masq_traffic_going_out"> + traf_going_to_dsl + </rule> + </masq> + </nat> +</firewall> +@end smallexample + + @node Traffic @section The @code{<traffic>} section @cindex shaping Modified: trunk/doc/stamp-vti =================================================================== --- trunk/doc/stamp-vti 2005-01-30 16:03:38 UTC (rev 66) +++ trunk/doc/stamp-vti 2005-04-06 09:14:20 UTC (rev 67) @@ -1,4 +1,4 @@ -@set UPDATED 21 January 2005 -@set UPDATED-MONTH January 2005 +@set UPDATED 6 April 2005 +@set UPDATED-MONTH April 2005 @set EDITION devel @set VERSION devel Modified: trunk/doc/version.texi =================================================================== --- trunk/doc/version.texi 2005-01-30 16:03:38 UTC (rev 66) +++ trunk/doc/version.texi 2005-04-06 09:14:20 UTC (rev 67) @@ -1,4 +1,4 @@ -@set UPDATED 21 January 2005 -@set UPDATED-MONTH January 2005 +@set UPDATED 6 April 2005 +@set UPDATED-MONTH April 2005 @set EDITION devel @set VERSION devel Modified: trunk/lib/xmlConf.c =================================================================== --- trunk/lib/xmlConf.c 2005-01-30 16:03:38 UTC (rev 66) +++ trunk/lib/xmlConf.c 2005-04-06 09:14:20 UTC (rev 67) @@ -201,11 +201,14 @@ className = (char *) data; found = 0; - // Loop with class hash - g_hash_table_foreach(classHash,processClassHash,NULL); + // First check we have a classHash, if use didn't specify any, this will be NULL */ + if (classHash) + // Loop with class hash + g_hash_table_foreach(classHash,processClassHash,NULL); + // Check if we found it if (!found) - fprintf(stderr,"ERROR: Class %s invalid\n",className); + fprintf(stderr,"ERROR: Class %s invalid, ignoring\n",className); } @@ -334,7 +337,7 @@ } // Function which creates our "special" nat extra cmd_line options -static char *createNATRuleset(GHashTable *properties) +static char *createNATRuleset(char *target, GHashTable *properties) { char *buffer; char *tmp; @@ -353,16 +356,46 @@ // Processing time... if (!xmlStrcmp(key,"to-src") && !done) { - snprintf(tmp,BUFFER_SIZE,"--to-source %s ",value); - strncat(buffer,tmp,BUFFER_SIZE); + // Make sure to-src is only used in SNAT section + if ((strcmp(target, "SNAT") == 0)) + { + snprintf(tmp,BUFFER_SIZE,"--to-source %s ",value); + strncat(buffer,tmp,BUFFER_SIZE); + } + else + fprintf(stderr,"ERROR: Tag parameter \"to-src\" is only valid in the <snat> tag, ignoring\n"); + done = 1; } + if (!xmlStrcmp(key,"to-dst") && !done) { - snprintf(tmp,BUFFER_SIZE,"--to-destination %s ",value); - strncat(buffer,tmp,BUFFER_SIZE); + // Make sure to-dst is only used in DNAT section + if ((strcmp(target, "DNAT") == 0)) + { + snprintf(tmp,BUFFER_SIZE,"--to-destination %s ",value); + strncat(buffer,tmp,BUFFER_SIZE); + } + else + fprintf(stderr,"ERROR: Tag parameter \"to-dst\" is only valid in the <dnat> tag, ignoring\n"); + done = 1; } + + if (!xmlStrcmp(key,"to-ports") && !done) + { + // Make sure to-ports is only used in DNAT section + if ((strcmp(target, "MASQUERADE") == 0)) + { + snprintf(tmp,BUFFER_SIZE,"--to-ports %s ",value); + strncat(buffer,tmp,BUFFER_SIZE); + } + else + fprintf(stderr,"ERROR: Tag parameter \"to-ports\" is only valid in the <masq> tag, ignoring\n"); + + done = 1; + } + if (!xmlStrcmp(key,"name") && !done) // Ignore this one done = 1; @@ -383,7 +416,7 @@ // Free sum mem free(tmp); - // Return the string FIXME - free mem in parent? + // Return the string return buffer; } @@ -452,7 +485,7 @@ // Free sum mem free(tmp); - // Return the string FIXME - free mem in parent? + // Return the string return buffer; } @@ -508,19 +541,34 @@ xmlDocPtr doc; xmlNodePtr cur; GHashTable *moduleHash = NULL; - + struct stat fstat; + moduleHash = g_hash_table_new_full(g_str_hash,g_str_equal,free,free); + /* Don't test version, it displays a nasty error + LIBXML_TEST_VERSION + */ // COMPAT: Do not genrate nodes for formatting spaces - LIBXML_TEST_VERSION xmlKeepBlanksDefault(0); - // FIXME - check if file exists + // Check if config file exists + if (stat(filename,&fstat) != 0) + { + fprintf(stderr,"ERROR: Failed to stat configuration path \"%s\": %s\n",filename,strerror(errno)); + return NULL; + } + else + if (!S_ISREG(fstat.st_mode)) + { + fprintf(stderr,"ERROR: Specified configuration path \"%s\" is not a regular file\n",filename); + return NULL; + } + // Build an XML tree from a the file doc = xmlParseFile(filename); if (doc == NULL) - return(NULL); + return NULL; // Check the document is of the right kind cur = xmlDocGetRootElement(doc); @@ -528,15 +576,15 @@ { fprintf(stderr,"ERROR: Empty document\n"); xmlFreeDoc(doc); - return(NULL); + return NULL; } // Check if we have the right root element & block if (xmlStrcmp(cur->name, (const xmlChar *) "firewall")) { - fprintf(stderr,"ERROR: Document of the wrong type, root node != firewall"); + fprintf(stderr,"ERROR: Document of the wrong type, root node != firewall\n"); xmlFreeDoc(doc); - return(NULL); + return NULL; } @@ -1135,7 +1183,7 @@ // Check if we have the right root element & block if (xmlStrcmp(cur->name, (const xmlChar *) "firewall")) { - fprintf(stderr,"ERROR: Document of the wrong type, root node != firewall"); + fprintf(stderr,"ERROR: Document of the wrong type, root node != firewall\n"); xmlFreeDoc(doc); return(ret); } @@ -1232,6 +1280,12 @@ target = NULL; // Check if we found a table... + if (!xmlStrcmp(cur->name, (const xmlChar *) "masq")) + { + tableName = "nat"; + chainName = "POSTROUTING"; + target = "MASQUERADE"; + } if (!xmlStrcmp(cur->name, (const xmlChar *) "snat")) { tableName = "nat"; @@ -1276,13 +1330,13 @@ // Check if everything is ok if (tmpRule->target == NULL) { - fprintf(stderr,"ERROR: All rules MUST have a target!"); - // FIXME - add memory cleanup here + fprintf(stderr,"ERROR: Internal error, tag <%s> has no target!\n",cur->name); + free(tmpRule); } else { // Get our extra params - cmd_line = createNATRuleset(tmpProp); + cmd_line = createNATRuleset(tmpRule->target,tmpProp); // Build our ruleSet tmpChain->ruleset = g_list_concat(tmpChain->ruleset, createRuleset(classHash,tmpRule->classList, @@ -1290,13 +1344,15 @@ // Voila! we got it! ruleList = g_list_append(ruleList,tmpRule); } + } - // Advance table - chainNode = chainNode->next; - } - + // Advance table + chainNode = chainNode->next; } } + else + fprintf(stderr,"ERROR: Invalid tag used \"<%s>\" in NAT section, ignored\n",cur->name); + // Advance our NAT node cur = cur->next; } @@ -1363,8 +1419,8 @@ // Check if everything is ok if (tmpRule->target == NULL) { - fprintf(stderr,"ERROR: All rules MUST have a target!"); - // FIXME - add memory cleanup here + fprintf(stderr,"ERROR: All rules MUST have a target!\n"); + free(tmpRule); } else { @@ -1402,8 +1458,8 @@ // Check if everything is ok if (tmpRule->target == NULL) { - fprintf(stderr,"ERROR: All rules MUST have a target!"); - // FIXME - add memory cleanup here + fprintf(stderr,"ERROR: All rules MUST have a target!\n"); + free(tmpRule); } else { @@ -1612,8 +1668,8 @@ // Check if everything is ok if (tmpRule->target == NULL) { - fprintf(stderr,"ERROR: All rules MUST have a target!"); - // FIXME - add memory cleanup here + fprintf(stderr,"ERROR: All rules MUST have a target!\n"); + free(tmpRule); } else { |