I am having trouble troubleshooting this OP script. When I run the following script and include an IP address, I get the following error:
{primary:node1}
user@fwB> op tpol source-address x.x.x.x destination-address x.x.x.0 destination-port 2002 (Real IPs redacted)
error: jcs:execute: null argument
error: xmlXPathCompiledEval: evaluation failed
error: runtime error: file /var/db/scripts/op/policy-test-v2.slax line 104 element variable
error: Failed to evaluate the expression of variable 'get-route'.
I ran traceoptions for op-scripts and it looks like it is actually failing at line 111:
Feb 21 13:29:54 reading op script 'policy-test-v2.slax'
Feb 21 13:29:57 jcs:execute: null argument
Feb 21 13:29:57 xmlXPathCompiledEval: evaluation failed
Feb 21 13:29:57 runtime error: file /var/db/scripts/op/policy-test-v2.slax line 111 element variable
Feb 21 13:29:57 Failed to evaluate the expression of variable 'get-int'.
Feb 21 13:29:57 op script output
Feb 21 13:29:57 begin dump
<?xml version="1.0"?>
Feb 21 13:29:57 end dump
Feb 21 13:29:57 inspecting op output 'policy-test-v2.slax'
Feb 21 13:29:57 finished op script 'policy-test-v2.slax'
I'm having trouble figuring out what piece of the evaluation is missing, it seems like everything is called as necessary, but I am not an expert with these scripts.
(As a side question, is it possible to edit an op-script on-box instead of deleting and re-uploading a script?)
1 /* Machine Crafted with Care (tm) by slaxWriter */
2 version 1.0;
3
4 ns junos = "http://xml.juniper.net/junos/*/junos";
5 ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
6 ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
7
8
9 /*
10 This is a simple script that looks up all the entries in the policy table that match a particular query
11 It is useful to debug polcy configurations
12 */
13 import "../import/junos.xsl";
14 var $arguments = {
15 <argument> {
16 <name> "source-address";
17 <description> "Source IP address of the initial session creation packet";
18 }
19 <argument> {
20 <name> "destination-address";
21 <description> "Destination IP address of the initial session creation packet";
22 }
23 <argument> {
24 <name> "source-port";
25 <description> "Source port of the packet";
26 }
27 <argument> {
28 <name> "destination-port";
29 <description> "Destination port of the packet";
30 }
31 <argument> {
32 <name> "from-zone";
33 <description> "Ingress zone of the packet";
34 }
35 <argument> {
36 <name> "to-zone";
37 <description> "Egress zone of the packet";
38 }
39 }
40 /* Open a persistent connection */
41 var $connection = jcs:open();
42 param $source-address = {
43 expr "0.0.0.0/0";
44 }
45 param $destination-address = {
46 expr "0.0.0.0/0";
47 }
48 param $source-port = {
49 expr "0";
50 }
51 param $destination-port = {
52 expr "0";
53 }
54 param $protocol = {
55 expr "0";
56 }
57 param $from-zone = {
58 call find-zone($ip = $source-address);
59 }
60 param $to-zone = {
61 call find-zone($ip = $destination-address);
62 }
63
64
65 /* print-policy: Displays the policy info */
66 template print-policy ($name, $from-zone, $to-zone, $source-address, $destination-address, $application, $action, $comment, $row = number("1"), $header = false()) {
67 var $format-string = "%-15.14s %-15.14s %-25.24j1s %-25.24s %-25.24s %-15.14s %-10.9s %s \n";
68
69 if ($header) {
70 expr jcs:printf($format-string, "From-Zone", "To-Zone", "Name", "Src-Addr", "Dst-Addr", "Application", "Action", "");
71
72 } else {
73 var $num-rows = {
74 if (count($application) >= count($source-address) && count($application) >= count($destination-address)) {
75 expr count($application);
76
77 } else if (count($source-address) > count($application) && count($source-address) > count($destination-address)) {
78 expr count($source-address);
79
80 } else {
81 expr count($destination-address);
82 }
83 }
84
85 if ($row <= $num-rows) {
86 expr jcs:printf($format-string, $from-zone, $to-zone, $name, $source-address[$row] , $destination-address[$row] , $application[$row] , $action, $comment);
87 call print-policy($row = $row + 1, $num-rows, $source-address, $destination-address, $application);
88 }
89 }
90 }
91
92 /* find-zone: Returns the zone where a given IP is */
93 template find-zone ($ip) {
94
95 if ($ip == "0.0.0.0/0") {
96 expr "any";
97
98 } else {
99 var $get-route-rpc = <command> {
100 expr "show route ";
101 expr $ip;
102 expr " active-path best";
103 }
104 var $get-route = jcs:execute($connection, $get-route-rpc);
105 var $zone = {
106 if ($get-route//via) {
107 var $get-int-rpc = <command> {
108 expr "show interface ";
109 expr $get-route//via;
110 }
111 var $get-int = jcs:execute($connection, $get-int-rpc);
112
113 expr $get-int//logical-interface-zone-name;
114
115 } else {
116 expr "any";
117 }
118 }
119
120 expr $zone;
121 }
122 }
123
124 /* rshift: Shifts bits to the right. Used to do an IP/MASK comparision */
125 template rshift ($number, $count) {
126
127 /* <output>
128 <xsl:value-of select="jcs:printf('Shifting %i %i times\n',$number, $count)"/>
129 </output> */
130 if ($count <= 0) {
131 expr $number;
132
133 } else {
134 call rshift($number = floor($number div 2), $count = ($count) - 1);
135 }
136 }
137
138 /* match-ip: Returns true if the ip is in the prefix */
139 template match-ip ($prefix, $ip) {
140 var $bytes-network = jcs:regex("([0-9]+).([0-9]+).([0-9]+).([0-9]+)/([0-9]+)", $prefix);
141 var $subnet = {
142 call rshift($number = $bytes-network[2] * 16777216 + $bytes-network[3] * 65536 + $bytes-network[4] * 256 + $bytes-network[5], $count = 32 -($bytes-network[6]));
143 }
144 var $bytes-ip = jcs:regex("([0-9]+).([0-9]+).([0-9]+).([0-9]+)", $ip);
145 var $ipnet = {
146 call rshift($number = $bytes-ip[2] * 16777216 + $bytes-ip[3] * 65536 + $bytes-ip[4] * 256 + $bytes-ip[5], $count = 32 - $bytes-network[6]);
147 }
148
149 if ($ipnet == $subnet) {
150 expr true();
151
152 } else {
153 expr false();
154 }
155 }
156
157 /* match-prefix-list: Returns true if the ip is in the prefix list */
158 template match-prefix-list ($ip, $prefix-list) {
159
160 if ($ip == "0.0.0.0/0") {
161 expr true();
162 } else {
163 if (not($prefix-list)) {
164 expr false();
165
166 } else {
167 var $match-prefix = {
168 call match-ip($ip, $prefix = $prefix-list);
169 }
170
171 if ($match-prefix == "true") {
172 expr true();
173
174 } else {
175 call match-prefix-list($ip, $prefix-list = $prefix-list[position() > 1 ] );
176 }
177 }
178 }
179 }
180
181 match / {
182 <op-script-results> {
183 /* First, check parameters passed */
184 if (not(jcs:parse-ip($source-address))) {
185 <output> jcs:printf("Bad IP address format: %s", $source-address);
186
187 } else if (not(jcs:parse-ip($destination-address))) {
188 <output> jcs:printf("Bad IP address format: %s", $destination-address);
189
190 } else if (not($source-port >= 0 && $source-port <= 65535)) {
191 <output> jcs:printf("Bad IP port number: %s", $source-port);
192
193 } else if (not($destination-port >= 0 && $destination-port <= 65535)) {
194 <output> jcs:printf("Bad IP port number: %s ", $destination-port);
195
196 } else {
197 <output> {
198 call print-policy($header = true());
199 expr jcs:trace( "from-zone ",$from-zone);
200 expr jcs:trace( "to-zone ",$to-zone);
201 }
202 var $filters = {
203 if ($from-zone != "any") {
204 expr " from-zone ";
205 expr $from-zone;
206 }
207 if ($to-zone != "any") {
208 expr " to-zone ";
209 expr $to-zone;
210 }
211 }
212
213 var $get-policies-rpc = <command> {
214 expr " show security policies ";
215 expr $filters;
216 expr " detail ";
217 }
218 expr jcs:trace( "command ", $get-policies-rpc );
219 /* Get the list of possible policies */
220 var $connection2 = jcs:open();
221 var $policies = jcs:execute( $connection2 , $get-policies-rpc );
222 /* Loop throught the policies to find the matching ones */
223
224 for-each ($policies//policy-information) {
225 var $match-source = {
226 call match-prefix-list($ip = $source-address, $prefix-list = .//source-address//address-prefix);
227 }
228 expr jcs:trace( "source-address ", $source-address," prefix-list ", .//source-address//address-prefix ," ", $match-source );
229
230 var $match-destination = {
231 call match-prefix-list($ip = $destination-address, $prefix-list = .//destination-address//address-prefix);
232 }
233 expr jcs:trace( "dest-address ", $destination-address," prefix-list ", .//destination-address//address-prefix ," ", $match-destination );
234
235 var $match-destination-port = {
236 if ($destination-port == "0") {
237 expr true();
238
239 } else if (./applications/application/application-term/destination-port-range[low == "0" && high == "0"]) {
240 expr true();
241
242 } else if (./applications/application/application-term/destination-port-range[low <= $destination-port && high >= $destination-port]) {
243 expr true();
244
245 } else {
246 expr false();
247 }
248 }
249 var $match-source-port = {
250 if ($source-port == "0") {
251 expr true();
252
253 } else if (./applications/application/application-term/source-port-range[low == "0" && high == "0"]) {
254 expr true();
255
256 } else if (./applications/application/application-term/source-port-range[low <= $source-port && high >= $source-port]) {
257 expr true();
258
259 } else {
260 expr false();
261 }
262 }
263
264 /* <output>
265 <xsl:value-of select="jcs:printf('Policy name: %s\n',./policy-name)"/>
266 <xsl:value-of select="jcs:printf(' match source: %s\n', $match-source)"/>
267 <xsl:value-of select="jcs:printf(' match destination: %s\n', $match-destination)"/>
268 <xsl:value-of select="jcs:printf(' match source port: %s\n', $match-source-port)"/>
269 <xsl:value-of select="jcs:printf(' match destination port: %s\n', $match-destination-port)"/>
270 </output> */
271 if ($match-source == "true" && $match-destination == "true" && $match-source-port == "true" && $match-destination-port == "true") {
272 <output> {
273 call print-policy($from-zone = ../../context-information/source-zone-name, $to-zone = ../../context-information/destination-zone-name, $name = ./policy-name, $destination-address = ./destination-addresses/destination-address/address-name, $source-address = ./source-addresses/source-address/address-name, $application = ./applications/application/application-name, $action = ./policy-action/action-type);
274 }
275 }
276 }
277 }
278 }
279 }