久しぶりにGNS3（その20：スクリプトその1）

# スクリプトTCL
今さらながら、シスコルーターでプログラミングもどきができないか調べると、TCLという、コマンドライン上で簡単なスクリプトをつくることができることがわかったので、その記録。

## TCL情報
下記サイトを参照。他にもいくつか見つかるが、TCLに関する情報はそれほど多くないように思える。
- [シスコ本家サイト　Chapter: Cisco IOS Scripting with Tcl](https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/ios_tcl/configuration/12-4t/ios-tcl-12-4t-book/nm-script-tcl.html)
- [Cisco command - PC search / tclsh](https://www.infraexpert.com/study/tea7.html)
- [TCLSH and Macro Ping Test on Cisco IOS](https://networklessons.com/cisco/ccie-routing-switching/tclsh-ping-test-on-cisco-routers-and-switches)

## ネットワーク環境（GNS3）
スクリプトで外部の複数箇所への疎通確認（ping）を行うのがわかりやすいので、実ネットワーク環境との接続を実施。[「その13：リアルネットワークへ接続その４」](https://qiita.com/infinite1oop/items/165b64a84d3da8239732)の環境と同じ。詳細はそちらも参照されたい。
![topology.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/3a15d7af-e2f1-ea99-76a9-518241c73d6d.png)
Routerにてスクリプトを実行する。

### Router
NATであるGNS3-VMから、DHCPでIPアドレスを取得する。
```
ip domain-lookup

interface Ethernet0/0
 ip address dhcp
```

### L2Switch
本稿では不要であるが、あえて設けている。何も設定していないので、すべての物理ポートが同一ネットワークセグメントにある状態。

## スクリプト
### マニュアル実行
上記参考サイトをもとに、マニュアルで実行。
```
Router#tclsh
Router(tcl)#foreach addr {
+>google.com
+>yahoo.com
+>abc.com
+>} { ping $addr repeat 3 size 100 }
Translating "google.com"...domain server (192.168.122.1) [OK]

Type escape sequence to abort.
Sending 3, 100-byte ICMP Echos to 142.251.42.174, timeout is 2 seconds:
!!!
Success rate is 100 percent (3/3), round-trip min/avg/max = 8/9/13 ms
Translating "yahoo.com"...domain server (192.168.122.1) [OK]

Type escape sequence to abort.
Sending 3, 100-byte ICMP Echos to 74.6.231.21, timeout is 2 seconds:
!!!
Success rate is 100 percent (3/3), round-trip min/avg/max = 139/141/143 ms
Translating "abc.com"...domain server (192.168.122.1) [OK]

Type escape sequence to abort.
Sending 3, 100-byte ICMP Echos to 99.84.140.33, timeout is 2 seconds:
!!!
Success rate is 100 percent (3/3), round-trip min/avg/max = 9/10/12 ms
Router(tcl)#
```
”foreach”で変数”addr”の繰り返し、"addr"の列挙、繰り返し実行のコマンド”ping”となっている。直接、手（マニュアル）で、これらを入力している。

### 保存＆実行
スクリプトを保存してから実行する。
- [CiscoルータでHello, World!](https://qiita.com/yakimeron/items/d3cc351f186dc14aea48)
- [Tclsh を使い、ルータ上でスクリプトを実行する](https://cephas.hatenadiary.org/entry/20110117/1295229038)

これらを参考にしたのであるが、小生の環境では、保存する領域が、これらと異なっていた。

```
Router#show file systems
File Systems:

       Size(b)       Free(b)      Type  Flags  Prefixes
             -             -    opaque     rw   archive:
*            -             -    opaque     rw   system:
         32768         26728     nvram     rw   nvram:
             -             -    opaque     rw   tmpsys:
    2147479552    2147479552      disk     rw   unix:
             -             -   network     rw   snmp:
             -             -    opaque     rw   null:
             -             -   network     rw   tftp:
             -             -    opaque     ro   xmodem:
             -             -    opaque     ro   ymodem:
             -             -    opaque     wo   syslog:
             -             -      disk     rw   disk0:
             -             -      disk     rw   disk1:
             -             -   network     rw   rcp:
             -             -   network     rw   pram:
             -             -   network     rw   ftp:
             -             -   network     rw   http:
             -             -   network     rw   scp:
             -             -    opaque     ro   tar:
             -             -   network     rw   https:
             -             -    opaque     ro   cns:
             -             -    opaque     rw   security:
```
上記情報から、”nvram:”に保存できると推測。
```
Router#dir nvram:
Directory of nvram:/

   29  -rw-        1892                    <no date>  startup-config
   30  ----           0                    <no date>  private-config
    1  ----          23                    <no date>  persistent-data
    2  -rw-          17                    <no date>  ecfm_ieee_mib

32768 bytes total (28776 bytes free)
```

#### Hello World
まずは、”Hello World”を表示するスクリプト（Hello.tcl）を保存してみる。
```
Router#tclsh
Router(tcl)#puts [open "nvram:Hello.tcl" w+] {
+>puts " Hello World !! "
+>}
Router(tcl)#exit
Router#
Router#dir nvram:
Directory of nvram:/

   29  -rw-        1892                    <no date>  startup-config
   30  ----           0                    <no date>  private-config
    1  ----          23                    <no date>  persistent-data
    2  -rw-          17                    <no date>  ecfm_ieee_mib
    3  -rw-          26                    <no date>  Hello.tcl

32768 bytes total (27752 bytes free)
```
保存できたようだ。次に実行。
```
Router#tclsh Hello.tcl
couldn't read file "Hello.tcl": No such file or directory

Router#tclsh nvram:Hello.tcl
 Hello World !! 
```
実行には、”nvram:”という場所およびスクリプトの指定が必要。

#### ping
作成＆保存。
```
Router#tclsh
Router(tcl)#puts [open "nvram:pingTest.tcl" w+] {
+>foreach addr {
+>google.co.jp
+>yahoo.co.jp
+>amazon.co.jp
+>} {ping $addr repeat 4 size 983}
+>}
Router(tcl)#exit
```
NVRAM状況。
```
Router#dir nvram:
Directory of nvram:/

   29  -rw-        1892                    <no date>  startup-config
   30  ----           0                    <no date>  private-config
    1  ----          23                    <no date>  persistent-data
    2  -rw-          17                    <no date>  ecfm_ieee_mib
    3  -rw-          26                    <no date>  Hello.tcl
    4  -rw-          88                    <no date>  pingTest.tcl

32768 bytes total (26728 bytes free)
```
”pingTest.tcl”が保存できている。次に実行。
```
Router#tclsh nvram:pingTest.tcl
Translating "google.co.jp"...domain server (192.168.122.1) [OK]

Type escape sequence to abort.
Sending 4, 983-byte ICMP Echos to 172.217.26.227, timeout is 2 seconds:
!!!!
Success rate is 100 percent (4/4), round-trip min/avg/max = 7/9/13 ms
Translating "yahoo.co.jp"...domain server (192.168.122.1) [OK]

Type escape sequence to abort.
Sending 4, 983-byte ICMP Echos to 183.79.219.252, timeout is 2 seconds:
!!!!
Success rate is 100 percent (4/4), round-trip min/avg/max = 14/15/17 ms
Translating "amazon.co.jp"...domain server (192.168.122.1) [OK]

Type escape sequence to abort.
Sending 4, 983-byte ICMP Echos to 52.119.168.48, timeout is 2 seconds:
!!!!
Success rate is 100 percent (4/4), round-trip min/avg/max = 132/134/142 ms
```
成功。

### 保存された内容を確認
わかってしまえば簡単であったが、本内容を見つけるのに時間を要した（helpや？で情報が出てこないので）。結論的には、Linuxのコマンド（cat）。
```
Router#cat nvram:pingTest.tcl
The command you have entered is available in the IOS.sh.
However, the shell is currently disabled. You can enable
it on this terminal by typing
   'term shell'
You can also enable it for all terminals by configuring the
   'shell processing full'
command. There is additional information in the man command.
For more information, enable shell, and then enter:
'man IOS.sh'
Router#
Router#term shell
Router#
Router#cat nvram:pingTest.tcl

foreach addr {
google.co.jp
yahoo.co.jp
amazon.co.jp
} {ping $addr repeat 4 size 983}

```
Linuxシェルを実行することができるらしい。

## 終わりに
その２以降（他の方法）に続く。きっと、奥が深い。