Reads IP address with netmask bits (a.b.c.d/x) from variable ip and convert it to the network address (a.b.c.D/x). This template can be used to make prefix lists based on ip addresses.
Only masks /24 to /31 are supported.
<?xml version="1.0" standalone="yes"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:version6="http://xml.version6.net/"> <xsl:template name="version6:ip-to-network"> <xsl:param name="ip"/> <xsl:variable name="tmp1" select="$ip"/> <xsl:variable name="ip1" select="substring-before($tmp1,'.')"/> <xsl:variable name="tmp2" select="substring-after($tmp1,'.')"/> <xsl:variable name="ip2" select="substring-before($tmp2,'.')"/> <xsl:variable name="tmp3" select="substring-after($tmp2,'.')"/> <xsl:variable name="ip3" select="substring-before($tmp3,'.')"/> <xsl:variable name="tmp4" select="substring-after($tmp3,'.')"/> <xsl:variable name="ip4" select="substring-before($tmp4,'/')"/> <xsl:variable name="bits" select="substring-after($tmp4,'/')"/> <xsl:choose> <xsl:when test="($bits >= 24) and ($bits <= 31)"> <xsl:call-template name="version6:_ip-to-network"> <xsl:with-param name="ip123" select="concat($ip1, '.', $ip2, '.', $ip3, '.')"/> <xsl:with-param name="ip4" select="$ip4"/> <xsl:with-param name="bits" select="$bits"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:message terminate="yes"><xsl:value-of select="$ip"/>: only /24 - /31 allowed</xsl:message> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="version6:_ip-to-network"> <xsl:param name="ip123"/> <xsl:param name="ip4"/> <xsl:param name="wildcard" select="'1'"/> <xsl:param name="bits"/> <xsl:param name="remainingbits" select="'32'"/> <xsl:choose> <xsl:when test="$remainingbits > $bits"> <xsl:call-template name="version6:_ip-to-network"> <xsl:with-param name="ip123" select="$ip123"/> <xsl:with-param name="ip4" select="$ip4"/> <xsl:with-param name="wildcard" select="$wildcard * 2"/> <xsl:with-param name="remainingbits" select="$remainingbits - 1"/> <xsl:with-param name="bits" select="$bits"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$ip123"/><xsl:value-of select="$ip4 - ($ip4 mod $wildcard)"/>/<xsl:value-of select="$bits"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
<?xml version="1.0" standalone="yes"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:version6="http://xml.version6.net/"> <xsl:import href="version6.xsl"/> <xsl:template match="iplist"> <iplist> <xsl:for-each select="ip"> <entry> <xsl:variable name="ip" select="."/> <ip> <xsl:value-of select="$ip"/> </ip> <net> <xsl:call-template name="version6:ip-to-network"> <xsl:with-param name="ip" select="$ip"/> </xsl:call-template> </net> </entry> </xsl:for-each> </iplist> </xsl:template> </xsl:stylesheet>
<iplist> <ip>10.0.0.205/24</ip> <ip>10.0.0.205/26</ip> <ip>10.0.0.205/31</ip> </iplist>
You can test this stylesheet using command line XSLT processor like this (XMLStarlet Toolkit is used to get nice indented output)
shell> xsltproc ip-to-network.xsl input.xml | xml fo -t
<?xml version="1.0"?>
<iplist xmlns:version6="http://xml.version6.net/">
<entry>
<ip>10.0.0.205/24</ip>
<net>10.0.0.0/24</net>
</entry>
<entry>
<ip>10.0.0.205/26</ip>
<net>10.0.0.192/26</net>
</entry>
<entry>
<ip>10.0.0.205/31</ip>
<net>10.0.0.204/31</net>
</entry>
</iplist>