Commit 934f5e42 authored by Nigel Kukard's avatar Nigel Kukard
Browse files

* 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
parent 649ec1ea
......@@ -4,12 +4,8 @@ TO DO
* 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
......
......@@ -64,7 +64,8 @@ static GList *createFirewallRules(char *filename, char resetCounters)
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 @@ static GList *createFirewallRules(char *filename, char resetCounters)
}
/* 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 @@ static GList *createFirewallRules(char *filename, char resetCounters)
// 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;
}
......
......@@ -499,6 +499,11 @@ This section has the following syntax@dots{}
traffic_to_webserver
</rule>
</dnat>
<masq>
<rule name="traf_to_from_inside">
internal_dsl_ips
</rule>
</masq>
</nat>
.
.
......@@ -506,11 +511,11 @@ This section has the following syntax@dots{}
</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 @@ webserver makes a query through the firewall, instead of the traffic on the
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 @@ interferring with the webservers operation.
@*@*
There are no parameters for this tag, although the following sub-tags and
parameters are available@dots{}
@*
@*@*
@itemize
@item
@cindex rule
......@@ -594,6 +599,47 @@ section are listed, these classify which traffic applies to which rule.
@*@*
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,6 +672,29 @@ An example using the above definitions would look something like this@dots{}
</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
......
@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
@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
......@@ -201,11 +201,14 @@ static GList *createRuleset(GHashTable *classHash, GList *classList, char *chain
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 @@ static GList *createClassRuleset(struct confClass_t *confClass)
}
// 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 @@ static char *createNATRuleset(GHashTable *properties)
// 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 @@ static char *createNATRuleset(GHashTable *properties)
// Free sum mem
free(tmp);
// Return the string FIXME - free mem in parent?
// Return the string
return buffer;
}
......@@ -452,7 +485,7 @@ static char *createTrafficRuleset(GHashTable *properties)
// Free sum mem
free(tmp);
// Return the string FIXME - free mem in parent?
// Return the string
return buffer;
}
......@@ -508,19 +541,34 @@ GHashTable *getModuleLoadHash(char *filename)
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 @@ GHashTable *getModuleLoadHash(char *filename)
{
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 @@ struct flowData_t createFlowData(char *filename)
// 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 @@ void parseNAT(xmlDocPtr doc, xmlNodePtr cur, GHashTable *fwHash, GHashTable *cla
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 @@ void parseNAT(xmlDocPtr doc, xmlNodePtr cur, GHashTable *fwHash, GHashTable *cla
// 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 @@ void parseNAT(xmlDocPtr doc, xmlNodePtr cur, GHashTable *fwHash, GHashTable *cla
// 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 @@ void parseTraffic(xmlDocPtr doc, xmlNodePtr cur, GHashTable *fwHash, GHashTable
// 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 @@ void parseTraffic(xmlDocPtr doc, xmlNodePtr cur, GHashTable *fwHash, GHashTable
// 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 @@ GHashTable *parseACL(xmlDocPtr doc, xmlNodePtr cur, GHashTable *fwHash, GHashTab
// 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
{
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment