Showing posts with label TCL. Show all posts
Showing posts with label TCL. Show all posts

Tuesday, 24 January 2017

B-ACD with Work & After Hour Schedule Using TCL Script

Recently, I had a request for a B-ACD to play a menu on a voice gateway at 8:00 a.m. and a different menu after 4:30 p.m.  At the time, I knew that Event Manager could do the schedule, and actually, it worked, but the menu(b-acd, not aa) session was struck and stayed with old one. Using “call application session stop id [id]” can stop it, but a question came up with how could I use “show call application sessions” to extract the session id?
R4331#show call application sessions
Session ID 5D
           App: queue
          Type: Service
           Url: flash:/bacd/app-b-acd-3.0.0.4.tcl

Anyhow, it took me a while and here are the steps:

Step 1 - Create two folder for work hour and after hour audio files

R4331#dir flash:
Directory of bootflash:/
353409  drwx             4096  Jan 23 2017 09:40:49 +00:00  bacd
16065  drwx             4096  Jan 22 2017 23:11:47 +00:00  bacd-ah

Step 2 - upload b-acd scripts and audio files to each folder:

Work hour folder
R4331#cd bacd   
R4331#dir
Directory of bootflash:/bacd/

353410  -rw-            33880  Jan 22 2017 21:34:07 +00:00  app-b-acd-3.0.0.4.tcl
353411  -rw-            61527  Jan 22 2017 21:34:30 +00:00  app-b-acd-aa-3.0.0.4.tcl
353412  -rw-            75650  Jan 22 2017 21:35:03 +00:00  en_bacd_allagentsbusy.au
353413  -rw-            83291  Jan 22 2017 21:35:32 +00:00  en_bacd_disconnect.au
353414  -rw-            63055  Jan 22 2017 21:36:03 +00:00  en_bacd_enter_dest.au
353415  -rw-            37952  Jan 22 2017 21:36:16 +00:00  en_bacd_invalidoption.au
353416  -rw-           496521  Jan 22 2017 21:36:29 +00:00  en_bacd_music_on_hold.au
353417  -rw-           103017  Jan 23 2017 09:42:05 +00:00  en_bacd_options_menu.au
353419  -rw-            50391  Jan 23 2017 09:40:49 +00:00  en_bacd_welcome.au

After hour folder
R4331#cd ../bacd-ah
R4331#dir
Directory of bootflash:/bacd-ah/

16066  -rw-            33880  Jan 22 2017 23:10:08 +00:00  app-b-acd-3.0.0.4.tcl
16067  -rw-            61527  Jan 22 2017 23:10:18 +00:00  app-b-acd-aa-3.0.0.4.tcl
16068  -rw-            75650  Jan 22 2017 23:10:27 +00:00  en_bacd_allagentsbusy.au
16069  -rw-            83291  Jan 22 2017 23:10:36 +00:00  en_bacd_disconnect.au
16070  -rw-            63055  Jan 22 2017 23:10:46 +00:00  en_bacd_enter_dest.au
16071  -rw-            37952  Jan 22 2017 23:10:56 +00:00  en_bacd_invalidoption.au
16072  -rw-           496521  Jan 22 2017 23:11:06 +00:00  en_bacd_music_on_hold.au
16073  -rw-           122896  Jan 23 2017 09:43:03 +00:00  en_bacd_options_menu.au
16074  -rw-            51472  Jan 23 2017 09:42:30 +00:00  en_bacd_welcome.au

Step 3 - inbound dial-peer to divert to b-acd application:

dial-peer voice 225 voip
service aa   ← it’s work-hour application temporary  
destination-pattern 5037526652
session protocol sipv2
session target ipv4:10.1.1.190  ←CME IP address
incoming called-number 5037526652
dtmf-relay rtp-nte
codec g711ulaw
no vad

Step 4 - outbound dial-peer to CUCM for extensions:

dial-peer voice 221 voip
destination-pattern 503[06]49....
session protocol sipv2
session target ipv4:10.1.1.10  ←pub
dtmf-relay rtp-nte
codec g711ulaw
no vad
!
dial-peer voice 220 voip
preference 1
destination-pattern 503[06]49....
session protocol sipv2
session target ipv4:10.1.1.20  ← sub
dtmf-relay rtp-nte
codec g711ulaw
no vad

Step 5 - music on-hold must be setup on the CME:

telephony-service
max-ephones 5
max-dn 10
ip source-address 10.1.1.190 port 2000
max-conferences 8 gain -6
call-forward pattern .T
call-forward system redirecting-expanded
moh enable-g711 "flash:/bacd/en_bacd_music_on_hold.au"
transfer-system full-consult
create cnf-files version-stamp Jan 01 2002 00:00:00

Step 6 - work hour and after hour voice applications:

!
application
service aa-ah flash:/bacd-ah/app-b-acd-aa-3.0.0.4.tcl
 paramspace english index 1
 param dial-by-extension-option 5
 param handoff-string aa-ah
 param welcome-prompt _bacd_welcome.au
 param operator 0
 param call-retry-timer 15
 paramspace english language en
 param service-name queue-ah
 param menu-timeout 6
 param second-greeting-time 60
 paramspace english location flash:/bacd-ah/
 param max-time-vm-retry 2
 param max-time-call-retry 5037526652
 param voice-mail 5003
 param aa-pilot
 param max-extension-length 10
 param number-of-hunt-grps 3
!
service aa flash:/bacd/app-b-acd-aa-3.0.0.4.tcl
 paramspace english index 1
 param number-of-hunt-grps 4
 param menu-timeout 6
 param dial-by-extension-option 5
 param handoff-string aa
 param operator 0
 paramspace english language en
 param max-time-vm-retry 2
 param max-extension-length 10
 param aa-pilot 5037526652
 paramspace english location flash:/bacd/
 param second-greeting-time 60
 param welcome-prompt _bacd_welcome.au
 param call-retry-timer 15
 param voice-mail 5003
 param max-time-call-retry 700
 param service-name queue
!
service queue flash:/bacd/app-b-acd-3.0.0.4.tcl
 group-name queue
 param name queue
 param queue-len 15
 param aa-hunt3 5036495533
 param aa-hunt4 5030495505
 param aa-hunt1 5036495503
 param number-of-hunt-grps 4
 param queue-manager-debugs 1
 param aa-hunt2 5036495586
!
service queue-ah flash:/bacd-ah/app-b-acd-3.0.0.4.tcl
 param aa-hunt1 5036495503
 param number-of-hunt-grps 3
 param queue-manager-debugs 1
 param aa-hunt2 5036495586
 param name ah
 param queue-len 15
 param aa-hunt3 5030495505

Step 7 - Tcl scripts to clean up stuck call application session and change service on the inbound dial-peer:


work-hour.tcl
set session [exec "show call application session"]
set id [string range $session 11 20]
if { $id == "" } {  } else { exec "call application session stop id $id"}
ios_config "dial-peer voice 225 voip" "service aa"
ios_config "end"
ios_config "write memory" 

after-hour.tcl
set session [exec "show call application session"]
set id [string range $session 11 20]
if { $id == "" } {  } else { exec "call application session stop id $id"}
ios_config "dial-peer voice 225 voip" "service aa-ah"
ios_config "end"
ios_config "write memory"



Upload them to flash:
R4331#dir
Directory of bootflash:/
  21  -rw-              230  Jan 24 2017 09:31:10 +00:00  work-hour.tcl
  22  -rw-              233  Jan 24 2017 09:31:16 +00:00  after-hour.tcl

Step 8 - Event Manager scheduling with Tcl scripts:

 event manager applet WEEKDAY_START
 event timer cron name WEEKDAY_START cron-entry "1 8 * * 1-5"
 action 1.0 cli command "enable"
 action 1.1 cli command "tclsh flash:work-hour.tcl"

 event manager applet WEEKDAY_END
 event timer cron name WEEKDAY_END cron-entry "30 16 * * 1-5"
 action 1.0 cli command "enable"
 action 1.1 cli command "tclsh flash:after-hour.tcl"

Wednesday, 6 August 2014

Customize TCL webpage on Cisco router

Complete a customized webpage on cisco router using TCL script.
First,  you need a tcl script running http server:
Download from here:
or write piece of code here:
::cisco::eem::event_register_none maxrun 4294967295.000

# Created on Monday, April 7, 2008 using IDEEM(TM) Software--Nidus Software Corp.

namespace import ::cisco::eem::*
namespace import ::cisco::lib::*

set svcPort 80
global events
set events 0
global parameters
global httpsock
set httpsock ""

# Handles the input from the client and  client shutdown
proc  svcHandler {sock} {
 global events
 global httpsock
 set httpsock $sock
 fconfigure $sock -encoding binary -translation
 set events 1
}

# Accept-Connection handler for Server.
# called When client makes a connection to the server
# Its passed the channel we're to communicate with the client on,
# The address of the client and the port we're using
#
# Setup a handler for (incoming) communication on
# the client channel - send connection Reply and log connection
proc accept {sock addr port} {
 # Setup handler for future communication on client socket
 fileevent $sock readable [list svcHandler $sock]

 # Read  # Readinput in lines, disable blocking I/O
 fconfigure $sock -buffering line -blocking 0 -encoding binary

 # log the connection
#  puts "Accepted connection from $addr:$port"
}


# Create a server socket on port $svcPort.
# Call proc accept when a client attempts a connection.
set srvrsock [socket -server accept $svcPort]
while {1} {
 vwait events
 set events 0
 global parameters
 catch {set l [gets $httpsock]}    ;# get the client packet
 if {$l != ""} {
   if {$l == "exit" || $l == "close" || $l == "GET /exit HTTP/1.1"} {
     catch {puts $httpsock "EEM HTTP server exited"}
     catch {close $httpsock}
     break
   } elseif {[regexp "GET /(.*) HTTP/1.1" $l temp request] != 0} {
       puts "$l"
       if {[regexp "(.*)\\?(.*)" $request temp filename param] == 0} {
           set param ""
           set filename $request
       }
       set ::parameters $param
       puts "file name:  $filename"
       puts "Parameters: $::parameters"
       if {$filename == ""} {set filename "index.html"}
       set ext ""
    set data ""

    catch {open [file join flash: $filename] r} output
    if {[string first "couldn't open" $output] != -1} {
        puts $output
         catch {puts $httpsock "HTTP/1.1 404 Not Found
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: binary

<html><head>
<title>File Not Found On Router gummyjoe</title>
</head>
<body>
<font face=\"arial\" size=\"4\" color=\"red\">404 File $filename Not Found On Router gummyjoe.<br></font>
</body>
</html>"}
        catch {close $httpsock}
    } else {
       # File was opened successfully
       set filehandle $output
       fconfigure $filehandle -encoding binary -translation binary
        while {1} {
            if {[catch {read $filehandle 1000} fileinput]} {
                puts "\nFile read failed: fd = $filehandle"
                catch {puts $httpsock "HTTP/1.1 500 Internal Server Error
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: binary

<html><head>
<title>Error reading file On router gummyjoe</title>
</head>
<body>
<font face=\"arial\" size=\"4\" color=\"red\">Error reading file $filename On Router gummyjoe.<br></font>
</body>
</html>"}
                break
            } else {
                if {$fileinput == ""} {break}
                append data $fileinput
            }
        }
        close $filehandle
    }

     if {$data != ""} {
           if {[regexp "(.*)\\.(.*)" $filename temp name ext] == 1 && $ext == "tcl"} {
               # The file is a tcl script.
               # Run it passing the parameters
               # Reply to client with output
               set parmlist [list]
               append parameters &
               set start 0
               while {1} {
                   set end [string first & $parameters $start]
                   if {$end == -1} {break}
                   set endname [string first = $parameters $start]
                   if {$endname == -1} {break}
                   incr endname -1
                   set paramname [string range $parameters $start $endname]
                   incr endname 2
                   if {$endname == $end} {
                       set paramval ""
                   } else {
                       incr end -1
                           set paramval [string range $parameters $endname $end]
                   }
                   incr end 2
                   set start $end
                   set paramval [string map {+ " "} $paramval]
                   # Remove special chars
                   while {1} {
                       if {[regexp "%(\[0-9a-fA-F\]\[0-9a-fA-F\])" $paramval temp Specialchar] != 0} {
                           set newchar [format "%c" "0x$Specialchar"]
                           set index [string first $temp $paramval]
                           set start1 $index
                           incr index 2
                           set paramval [string replace $paramval $start1 $index $newchar]
                    } else {
                        break
                    }
                   }
                   lappend parmlist $paramname $paramval
               }
             if {[catch {eval $data} output]} {
                 catch {puts $httpsock "HTTP/1.1 500 Internal Server Error
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: binary

Error in script:\n\n"}
                 catch {puts $httpsock $output}
             }
#            [eval $data]
            } else {
                set filelen [string bytelength $data]
                switch $ext {
                ico  {set ContentType "image/vnd.microsoft.icon"}
                png  {set ContentType "image/png"}
                jpeg {set ContentType "image/jpg"}
                jpg  {set ContentType "image/jpg"}
                gif  {set ContentType "image/gif"}
                html {set ContentType "text/html; charset=UTF-8"}
                htm  {set ContentType "text/html; charset=UTF-8"}
                default {set ContentType "application/octet-stream"}
               }
             catch {puts $httpsock "HTTP/1.1 200 OK
Content-Type: $ContentType
Content-Transfer-Encoding: binary
Content-Length: $filelen

$data"}
            }
    }
   } else {
     catch {puts $httpsock "HTTP/1.1 404 Not Found
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: binary

<html><head>
<title>File Not Found On Router gummyjoe</title>
</head>
<body>
<font face=\"arial\" size=\"4\" color=\"red\">404 File Not Found On Router gummyjoe.<br></font>
</body>
</html>"}
   }
   catch {close $httpsock}
 }
}
close $srvrsock
puts "EEM HTTP server exited"

Above is the script for the router to run http service on tcp 80 port. Next we will write a code for gleaning information from current configuration and display it on a webpage. Here is current configuration of the router:
Current configuration : 3320 bytes
!
version 12.4
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname sender
!
boot-start-marker
boot-end-marker
!
!
no aaa new-model
memory-size iomem 5
ip cef
!
!
!
!
ip vrf BLU
rd 1:4
route-target export 1:4
route-target import 1:4
!
ip vrf GREY
rd 1:1
route-target export 1:1
route-target export 1:2
route-target export 1:3
route-target import 1:1
route-target import 1:2
route-target import 1:3
!
ip vrf GRN
rd 1:2
route-target export 1:2
route-target import 1:2
!
ip vrf Orange
rd 1:3
route-target export 1:3
route-target import 1:3
!
ip vrf PURPLE
rd 1:1992
route-target export 1:1992
route-target import 1:1992
!
ip vrf RED
route-target export 1:1
route-target export 1:2
route-target export 1:3
route-target import 1:1
route-target import 1:2
route-target import 1:3
!
no ip domain lookup
ip auth-proxy max-nodata-conns 3
ip admission max-nodata-conns 3
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
interface Loopback3
ip vrf forwarding Orange
ip address 10.3.3.1 255.255.255.0
!
interface Loopback4
ip vrf forwarding BLU
ip address 10.4.4.1 255.255.255.0
!
interface Loopback5
ip vrf forwarding PURPLE
ip address 10.55.55.5 255.255.255.0
shutdown
!
interface Loopback1001
ip vrf forwarding RED
ip address 172.18.134.3 255.255.255.0
!
interface Loopback1004
ip vrf forwarding PURPLE
no ip address
!
interface Loopback1007
ip vrf forwarding GRN
ip address 192.168.92.38 255.255.255.0
!
interface Loopback1018
ip vrf forwarding GRN
ip address 172.17.123.9 255.255.255.0
!
interface FastEthernet0/0
ip address 142.100.64.254 255.255.255.0
duplex auto
speed auto
!
interface FastEthernet0/1
no ip address
duplex auto
speed auto
mpls label protocol ldp
mpls ip
!
interface FastEthernet1/0
no ip address
shutdown
duplex auto
speed auto
mpls label protocol ldp
mpls ip
!
router bgp 65065
no synchronization
bgp log-neighbor-changes
neighbor 10.93.130.225 remote-as 65065
neighbor 192.50.50.50 remote-as 65065
neighbor 192.50.50.50 route-reflector-client
neighbor 192.168.100.1 remote-as 65065
neighbor 192.168.100.1 route-reflector-client
neighbor 192.168.200.1 remote-as 65065
no auto-summary
!
address-family vpnv4
 neighbor 10.93.130.225 activate
 neighbor 10.93.130.225 send-community extended
 neighbor 192.50.50.50 activate
 neighbor 192.50.50.50 send-community extended
 neighbor 192.168.100.1 activate
 neighbor 192.168.100.1 send-community extended
 neighbor 192.168.100.1 route-reflector-client
 neighbor 192.168.200.1 activate
 neighbor 192.168.200.1 send-community extended
exit-address-family
!
address-family ipv4 vrf PURPLE
 no synchronization
exit-address-family
!
address-family ipv4 vrf Orange
 no synchronization
exit-address-family
!
address-family ipv4 vrf GRN
 no synchronization
exit-address-family
!
address-family ipv4 vrf GREY
 no synchronization
exit-address-family
!
address-family ipv4 vrf BLU
 no synchronization
exit-address-family
!
ip forward-protocol nd
!
!
no ip http server
no ip http secure-server
!
!
!
!
control-plane
!
!
!
!
!
!
!
!
!
!
line con 0
exec-timeout 0 0
line aux 0
line vty 0 4
no login
line vty 5 15
no login
!
!
event manager directory user policy flash:/
event manager policy http_server.tcl
!
End

Right now, we will build a file to execute TCL script to grasp information and display based on HTML format on webpage:


# catch {open [file join flash: $filename] r} output

#show vrfs
if [catch {cli_open} RESULT] {
    error $RESULT $errorInfo
        } else {
            array set cli1 $RESULT
}
if [catch {cli_exec $cli1(fd) "en"} RESULT] {
    cli_close $cli1(fd)
    error $RESULT $errorInfo
}
if [catch {cli_exec $cli1(fd) "show ip vrf detail | include ;" } RESULT] {
    error $RESULT $errorInfo
        } else {
            set VRFs $RESULT
}
if [catch {cli_close $cli1(fd) $cli1(tty_id)} RESULT] {
    error $RESULT $errorInfo
}

#VRF while loop
set COUNT 1
set ALL_VRF_INFO ""
while {[string length $VRFs] > 10} {
    set VRF($COUNT) [string range $VRFs [expr [string first "VRF " $VRFs] + 4] [expr [string first "; default RD" $VRFs] - 1]]
    set RD($COUNT) [string range $VRFs [expr [string first "; default RD" $VRFs] + 12] [expr [string first "; default VPNID" $VRFs] -1]]
    set ITEM "<b>$VRF($COUNT)</b><br /> $RD($COUNT)<br />"
    set ALL_VRF_INFO [concat $ALL_VRF_INFO $ITEM]
    set VRFs [string range $VRFs [expr [string first "\n" $VRFs] +1] [string length $VRFs]]
    incr COUNT
}
set COUNT [expr $COUNT - 1]
set NUM_OF_VRFS $COUNT


#show config
if [catch {cli_open} RESULT] {
    error $RESULT $errorInfo
        } else {
            array set cli1 $RESULT
}
if [catch {cli_exec $cli1(fd) "en"} RESULT] {
    error $RESULT $errorInfo
}
if [catch {cli_exec $cli1(fd) "show running-config" } RESULT] {
    error $RESULT $errorInfo
        } else {
            set CONFIG $RESULT
}
if [catch {cli_close $cli1(fd) $cli1(tty_id)} RESULT] {
    error $RESULT $errorInfo
}

#RT while loop
set COUNT 1
set IMPORT_EXPORT ""
while {$COUNT < $NUM_OF_VRFS} {
    set BEGIN [string first "\n" $CONFIG [string first "ip vrf $VRF($COUNT)" $CONFIG]]
    set END [string first "!" $CONFIG $BEGIN]
    set IMP_EXP_STRING [string range $CONFIG [expr $BEGIN +1] [expr $END -1]]
    if {[string first "route-target " $IMP_EXP_STRING]} {
        set BEGIN [string first "route-target " $IMP_EXP_STRING]
        set IMP_EXP_STRING [string range $IMP_EXP_STRING [expr $BEGIN -1] [expr $END -1]]
        regsub -all {route-target } $IMP_EXP_STRING "<br />" IMP_EXP_STRING
        regsub -all {route-target } $IMP_EXP_STRING "</b><br />" IMP_EXP_STRING
        set ITEM "<b> $VRF($COUNT) $IMP_EXP_STRING <br />"
        set IMPORT_EXPORT [concat $IMPORT_EXPORT $ITEM]
    }
    incr COUNT
}


#vrf interface
if [catch {cli_open} RESULT] {
    error $RESULT $errorInfo
        } else  {
            array set cli1 $RESULT
        }
if [catch {cli_exec $cli1(fd) "en"} RESULT] {
    error $RESULT $errorInfo
}
if [catch {cli_exec $cli1(fd) "show ip vrf interfaces" } RESULT] {
    error $RESULT $errorInfo
        } else {
        set VRF_INTERFACE_CONFIG $RESULT
        }
if [catch {cli_close $cli1(fd) $cli1(tty_id)} RESULT] {
    error $RESULT $errorInfo
}

# vrf interface while loop
set VRF_INTERFACE_OUTPUT ""
set COUNT 1

#vrf interface while loop
# while {$COUNT < $NUM_OF_VRFS} {  
    while {[regexp -all $VRF($COUNT) $VRF_INTERFACE_CONFIG] > 0} {
        set BEGIN [expr [string first "Protocol" $VRF_INTERFACE_CONFIG] + 10]
        set END [expr [string first "\n" $VRF_INTERFACE_CONFIG [expr [string first $VRF($COUNT) $VRF_INTERFACE_CONFIG $BEGIN]]]]
        set VRF_INTERFACES [string range $VRF_INTERFACE_CONFIG [expr $BEGIN -1] $END]
        regsub -all $VRF($COUNT) $VRF_INTERFACES " " VRF_INTERFACES
        regsub -all { } $VRF_INTERFACES " " VRF_INTERFACES
        set ITEM "<b> $VRF($COUNT)</b><br /> $VRF_INTERFACES </b><br />"
        set VRF_INTERFACE_OUTPUT [concat $VRF_INTERFACE_OUTPUT $ITEM]
        set VRF_INTERFACE_CONFIG [string replace $VRF_INTERFACE_CONFIG [expr $BEGIN -1] [expr $END]]
    incr COUNT
}
# }


#LDP interface
if [catch {cli_open} RESULT] {
error $RESULT $errorInfo
    } else {
        array set cli1 $RESULT
    }
if [catch {cli_exec $cli1(fd) "en"} RESULT] {
    error $RESULT $errorInfo
}
if [catch {cli_exec $cli1(fd) "show mpls interfaces | exc Operational" } RESULT] {
    error $RESULT $errorInfo
    } else {
        set LDP_INTERFACE_CONFIG $RESULT
    }
if [catch {cli_close $cli1(fd) $cli1(tty_id)} RESULT] {
error $RESULT $errorInfo
}

#LDP while loop
set LDP_INTERFACES ""
while {[regexp -all {Yes | No} $LDP_INTERFACE_CONFIG] > 0} {
    set END [string first "\n" $LDP_INTERFACE_CONFIG 12]
    set ITEM [string range $LDP_INTERFACE_CONFIG 0 $END]
    if {[expr [string last Yes $ITEM]] > [expr [string last No $ITEM]]} {
        set END [expr [string last Yes $ITEM] - 3]
    } else {
        set END [expr [string last No $ITEM] - 2 ]
        }
    set ITEM [string replace $ITEM [expr [string first " " $ITEM]] $END]
    set ITEM "$ITEM <br />"
    set LDP_INTERFACES [concat $LDP_INTERFACES $ITEM]
    set LDP_INTERFACE_CONFIG [string replace $LDP_INTERFACE_CONFIG 0 [string first "\n" $LDP_INTERFACE_CONFIG 3]]
}


#show ip bgp vpnv4
if [catch {cli_open} RESULT] {
    error $RESULT $errorInfo
        } else {
            array set cli1 $RESULT
}
if [catch {cli_exec $cli1(fd) "en"} RESULT] {
    error $RESULT $errorInfo
}
if [catch {cli_exec $cli1(fd) "show ip bgp vpnv4 all summary" } RESULT] {
    error $RESULT $errorInfo
        } else {
            set BGP_NEIGHBORS $RESULT
}
if [catch {cli_close $cli1(fd) $cli1(tty_id)} RESULT] {
    error $RESULT $errorInfo
}

#bgp vpnv4 while loop
set BGP_NEIGHBOR_OUTPUT ""
set BEGIN [expr [string first "PfxRcd" $BGP_NEIGHBORS 1] + 8]

while {[regexp -all {.} $BGP_NEIGHBORS] > 0} {
    if {$BEGIN < 10} {
        set BEGIN 0
        }
    if {[string first "\n" $BGP_NEIGHBORS [expr $BEGIN + 20]]} {
        set END [string first "\n" $BGP_NEIGHBORS [expr $BEGIN + 20]]
        } else {
            set END [expr [string length $BGP_NEIGHBORS] - 1]
        }
    set ITEM [string range $BGP_NEIGHBORS $BEGIN $END]
    if {[string length $ITEM] < 10} {break}
    if {[regexp -all {Active} $ITEM] == 0} {
        set ITEM [string replace $ITEM [expr [string first " " $ITEM]] $END]
        set ITEM "$ITEM UP <br />"
        set BGP_NEIGHBOR_OUTPUT [concat $BGP_NEIGHBOR_OUTPUT $ITEM]
        } else {
                set ITEM [string replace $ITEM [expr [string first " " $ITEM]] $END]
                set ITEM "$ITEM DOWN <br />"
                set BGP_NEIGHBOR_OUTPUT [concat $BGP_NEIGHBOR_OUTPUT $ITEM]
                }
set BGP_NEIGHBORS [string replace $BGP_NEIGHBORS 0 $END]               
set BEGIN -1
}

#BGP config
set BGP_CONFIG $CONFIG
if {[regexp -all {router bgp} $BGP_CONFIG] > 0} {
    if {[regexp -all {address-family} $BGP_CONFIG] > 0} {
        set BEGIN [string first "router bgp" $BGP_CONFIG]
        set END [string last exit-address-family $BGP_CONFIG]
        set BGP_CONFIG_RESULTS [string range $BGP_CONFIG $BEGIN [expr $END + 18]]
        regsub -all {\n} $BGP_CONFIG_RESULTS {<br />} BGP_CONFIG_RESULTS
    }
set BGP_AS [string range $BGP_CONFIG_RESULTS 11 [expr [string first "<br" $BGP_CONFIG_RESULTS] - 1]]
}


#Config HTML

set header "<html>
<head>
<title>MPLS-VPN Configuration Application:</title>
</head>
<div align='center'>
<font face='arial' size='6'>MPLS-VPN Configuration Application</font><br />
</div>
</html>
"

set config "
<div align='left' style='color: gray; font-family: arial; font-size: 18pt; MARGIN 10px 10px'>
    VRF Information:
</div>

<div align='left' style='overflow: scroll; border-right-style: solid; font-family: arial; font-size: 10pt; border-right-width:1px; WIDTH: 250px; FLOAT: left; HEIGHT: 200px; MARGIN: 10px 10px'>
<font face='arial' size='4'>VRF name / RD</font><br />
<ol>$ALL_VRF_INFO</ol>
</div>

<div align='left' style='overflow: scroll; border-right-style: solid; font-family: arial; font-size: 10pt; border-right-width:1px; WIDTH: 230px; FLOAT: left; HEIGHT: 200px; MARGIN: 10px 10px'>
<font face='arial' size='4'>Import / Export</font><br />
<ol>$IMPORT_EXPORT</ol>
</div>

<div align='left' style='overflow: scroll; border-right-style: solid; font-family: arial; font-size: 10pt; border-right-width:1px; WIDTH: 300px; FLOAT: left; HEIGHT: 200px; MARGIN: 10px 10px'>
<font face='arial' size='4'>VRF Interface Status</font><br />
<ol>$VRF_INTERFACE_OUTPUT</ol>
</div>

<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />

<div align='left' style='color: gray; font-family: arial; font-size: 18pt; MARGIN: 10px 10px'>
VRF Configuration:

</div>
    <font face='arial' size='4'>
<form name='MPLS-CFG' action='MPLS-CFG.tcl' method='GET' target='_blank'>
<input type='text' name='VRF_Name' value='VRF_Name' onblur='init_field(this,\"VRF_Name\");' onFocus='clear_field(this,\"VRF_Name\");' style='WIDTH: 200px; font-family: arial; font-size: 10pt'>
<font face='arial' size='4'>
<form name='MPLS-CFG' action='MPLS-CFG.tcl' method='GET' target='_blank'>
<input type='text' name='RD' value='RD' onblur='init_field(this,\"RD\");' onFocus='clear_field(this,\"RD\");' style='WIDTH: 200px; font-family: arial; font-size: 10pt'>
<font face='arial' size='4'>
<form name='MPLS-CFG' action='MPLS-CFG.tcl' method='GET' target='_blank'>
<input type='text' name='Import' value='Import' onblur='init_field(this,\"Import\");' onFocus='clear_field(this,\"Import\");' style='WIDTH: 200px; font-family: arial; font-size: 10pt'>
<font face='arial' size='4'>
<form name='MPLS-CFG' action='MPLS-CFG.tcl' method='GET' target='_blank'>
<input type='text' name='Export' value='Export' onblur='init_field(this,\"Export\");' onFocus='clear_field(this,\"Export\");' style='WIDTH: 200px; font-family: arial; font-size: 10pt'>

<br />

<div align='left'>
    <font face='arial' size='4'>
    <color='black'>
<form name='MPLS-CFG' action='MPLS-CFG.tcl' method='GET' target='_blank'>
<input type='text' name='Interface' value='Interface' onblur='init_field(this,\"Interface\");' onFocus='clear_field(this,\"Interface\");' style='WIDTH: 250px; font-family: arial; font-size: 10pt'>
<font-family: arial; font-size: 18pt>
<color='black'>
<form name='MPLS-CFG' action='MPLS-CFG.tcl' method='GET' target='_blank'>
<input type='text' name='IP_Address' value='IP_Address' onblur='init_field(this,\"IP_Address\");' onFocus='clear_field(this,\"IP_Address\");' style='WIDTH: 250px; color:#000000; font-family: arial; font-size: 10pt'>
<input type='text' name='Mask' value='Mask' onblur='init_field(this,\"Mask\");' onFocus='clear_field(this,\"Mask\");' style='WIDTH: 250px; color:#000000; font-family: arial; font-size: 10pt'>

<br />


<div align='left' style='color: black; font-family: arial; font-size: 12pt; MARGIN: 10px 10px'>
Redistribute Connected:
<input type='radio' name='Red_Connected' value='yes' /> yes
<input type='radio' name='Red_Connected' value='no' checked='checked' /> no
</div>

<br /><br />

<div align=left' style='color: gray; font-family: arial; font-size: 18pt; MARGIN: 10px 10px'>
BGP / LDP Information:
</div>
<div align=left' style='overflow: scroll; border-right-style: solid; font-family: arial; font-size: 10pt; border-right-width:1px; WIDTH: 220px; FLOAT: left; HEIGHT: 200px; MARGIN: 10px 10px'>
<font face='arial' size='4'>Label Int / Operational</font><br />
<ol>$LDP_INTERFACES</ol>
</div>
<div align='left' style='overflow: scroll; border-right-style: solid; font-family: arial; font-size: 10pt; border-right-width:1px; WIDTH: 220px; FLOAT: left; HEIGHT: 200px; MARGIN: 10px 10px'>
<font face='arial' size='4'>BGP Neighbors</font><br />
<ol>$BGP_NEIGHBOR_OUTPUT</ol>
</div>
<div align='left' style='overflow: scroll; border-right-style: solid; font-family: arial; font-size: 10pt; border-right-width:1px; WIDTH: 340px; FLOAT: left; HEIGHT: 200px; MARGIN: 10px 10px'>
<font face='arial' size='4'>BGP Configuration</font><br />
<ol>$BGP_CONFIG_RESULTS</ol>
</div>

<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />

<div align='left' style='color: gray; font-family: arial; font-size: 18pt; MARGIN: 10px 10px'>
BGP Configuration:
</div>
<div align='left'>
<font face='arial' size='4'>
<form name='MPLS-CFG' action='MPLS-CFG.tcl' method='GET' target='_blank'>
<input type='text' name='BGP_AS' value='$BGP_AS' onblur='init_field(this,\"$BGP_AS\");' onFocus='clear_field(this,\"$BGP_AS\");' style='WIDTH: 230px; font-family: arial; font-size: 10pt'>
<font face='arial' size='4'>
<form name='MPLS-CFG' action='MPLS-CFG.tcl' method='GET' target='_blank'>
<input type='text' name='Neighbor' value='Neighbor' onblur='init_field(this,\"Neighbor\");' onFocus='clear_field(this,\"Neighbor\");' style='WIDTH: 230px; font-family: arial; font-size: 10pt'>
<font face='arial' size='4'>
<form name='MPLS-CFG' action='MPLS-CFG.tcl' method='GET' target='_blank'>
<input type='text' name='Source_Int' value='Source_Int' onblur='init_field(this,\"Source_Int\");' onFocus='clear_field(this,\"Source_Int\");' style='WIDTH: 250px; font-family: arial; font-size: 10pt'>
</div>

<div align='left' style='color: black; font-family: arial; font-size: 12pt; MARGIN: 10px 10px'>
Route Reflector Client:
<input type='radio' name='RR_Client' value='yes' /> Yes
<input type='radio' name='RR_Client' value='no' checked='checked' /> No
</div>

<br /><br />

<div align='left' style='color: gray; font-family: arial; font-size: 18pt; MARGIN: 10px 10px'>
LDP Configuration:
</div>
<div align='left'>
<font face='arial' size='4'>
<form name='MPLS-CFG' action='MPLS-CFG.tcl' method='GET' target='_blank'>
<input type='text' name='Label_Int' value='Label_Int' onblur='init_field(this,\"Label_Int\");' onFocus='clear_field(this,\"Label_Int\"); ' style='WIDTH: 230px; font-family:arial; font-size: 10pt'>
<font face='arial' size='4'>
<form name='MPLS-CFG' action='MPLS-CFG.tcl' method='GET' target='_blank'>
<input type='text' name='IP_Address' value='IP_Address' onblur='init_field(this,\"IP_Address\");' onFocus='clear_field(this,\"IP_Address\");' style='WIDTH: 230px; font-family:arial; font-size: 10pt'>
<input type='text' name='Mask' value='Mask' onblur='init_field(this,\"Mask\");' onFocus='clear_field(this,\"Mask\");' style='WIDTH: 250px; font-family: arial; font-size: 10pt'>
</div>

<br /><br /><br /><br />

<div align='left' style='color: black; font-family: arial; font-size: 14pt; MARGIN: 10px 10px'>
Configuration:
<input type='radio' name='ADD_REMOVE' value='yes' checked='checked' /> Add
<input type='radio' name='ADD_REMOVE' value='no'/> Remove
</div>

<br />
"

set footer "
<script>
function clear_field(field, value) {if(field.value == value) field.value = '';}
function init_field(field, value) {if(field.value == '') field.value = value;}
</script>
<br />
<input type='submit' style='color: red value='Deploy Changes'>
"

set httpheader "HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: binary
"

puts $httpsock $httpheader$header$config$footer