diff --git a/docs/static/tutorial5/VM-network-settings.png b/docs/static/tutorial5/VM-network-settings.png new file mode 100644 index 00000000..5d47738e Binary files /dev/null and b/docs/static/tutorial5/VM-network-settings.png differ diff --git a/docs/static/tutorial5/configure-the-rj45.png b/docs/static/tutorial5/configure-the-rj45.png new file mode 100644 index 00000000..0e2b8f8b Binary files /dev/null and b/docs/static/tutorial5/configure-the-rj45.png differ diff --git a/docs/static/tutorial5/rj45-connector.png b/docs/static/tutorial5/rj45-connector.png new file mode 100644 index 00000000..8c8e86ef Binary files /dev/null and b/docs/static/tutorial5/rj45-connector.png differ diff --git a/docs/static/tutorial5/rj45-unassigned.png b/docs/static/tutorial5/rj45-unassigned.png new file mode 100644 index 00000000..eda4a3b6 Binary files /dev/null and b/docs/static/tutorial5/rj45-unassigned.png differ diff --git a/docs/tutorials/overview.md b/docs/tutorials/overview.md index 733157bd..6ec0d275 100644 --- a/docs/tutorials/overview.md +++ b/docs/tutorials/overview.md @@ -21,7 +21,7 @@ These are the items you should become familiar with for running all the tutorial * Covers mobility interactions when using a simple 3 node wireless network * [Tutorial 4 - Tests](tutorial4.md) * Covers automating scenarios as tests to validate software -* [Tutorial 5 - Access Windows](tutorial5.md) +* [Tutorial 5 - RJ45 Node](tutorial5.md) * Covers using the RJ45 node to connect a Windows OS * [Tutorial 6 - Improve Visuals](tutorial6.md) * Covers changing the look of a scenario within the CORE GUI diff --git a/docs/tutorials/tutorial5.md b/docs/tutorials/tutorial5.md new file mode 100644 index 00000000..4724544f --- /dev/null +++ b/docs/tutorials/tutorial5.md @@ -0,0 +1,166 @@ +# Tutorial 5 - RJ45 Node + +## Overview + +This tutorial will cover connecting CORE VM to a Windows host machine using a RJ45 node. + +## Files + +Below is the list of files used for this tutorial. + +* scenario.xml - the scenario with RJ45 unassigned +* scenario.py- grpc script to create the RJ45 in simple CORE scenario +* client_for_windows.py - chat app client modified for windows + +## Running with the Saved XML File + +This section covers using the saved **scenario.xml** file to get and up and running. + +* Configure the Windows host VM to have a bridged network adapter +

+ +

+* Make sure the **core-daemon** is running in a terminal + ```shell + sudop core-daemon + ``` +* In another terminal run the GUI + ```shell + core-gui + ``` +* Open the **scenario.xml** with the unassigned RJ45 node +

+ +

+* Configure the RJ45 node name to use the bridged interface +

+ +

+* After configuring the RJ45, run the scenario: +

+ +

+* Double click node **n1** to open a terminal and add a route to the Windows host + ```shell + ip route add 192.168.0.0/24 via 10.0.0.20 + ``` +* On the Windows host using Windows command prompt with administrator privilege, add a route that uses the interface connected to the associated interface assigned to the RJ45 node + ```shell + # if enp0s3 is ssigned 192.168.0.6/24 + route add 10.0.0.0 mask 255.255.255.0 192.168.0.6 + ``` +* Now you should be able to ping from the Windows host to **n1** + ```shell + C:\WINDOWS\system32>ping 10.0.0.20 + + Pinging 10.0.0.20 with 32 bytes of data: + Reply from 10.0.0.20: bytes=32 time<1ms TTL=64 + Reply from 10.0.0.20: bytes=32 time<1ms TTL=64 + Reply from 10.0.0.20: bytes=32 time<1ms TTL=64 + Reply from 10.0.0.20: bytes=32 time<1ms TTL=64 + + Ping statistics for 10.0.0.20: + Packets: Sent = 4, Received = 4, Lost = 0 (0% loss) + Approximate round trip times in milli-seconds: + Minimum = 0ms, Maximum = 0ms, Average = 0ms + ``` +* After pinging successfully, run the following in the **n1** terminal to start the chatapp server + ```shell + export PATH=$PATH:/usr/local/bin + chatapp-server + ``` +* On the Windows host, run the **client_for_windows.py** + ```shell + python3 client_for_windows.py -a 10.0.0.20 + connected to server(10.0.0.20:9001) as client(192.168.0.6:49960) + >> .Hello WORLD + .Hello WORLD Again + . + ``` +* Observe output on **n1** + ```shell + chat server listening on: :9001 + [server] 192.168.0.6:49960 joining + [192.168.0.6:49960] Hello WORLD + [192.168.0.6:49960] Hello WORLD Again + ``` +* When finished, you can stop the CORE scenario and cleanup +* On the Windows host remove the added route + ```shell + route delete 10.0.0.0 + ``` + +## Running with the gRPC Script + +This section covers leveraging the gRPC script to get up and running. + +* Configure the Windows host VM to have a bridged network adapter +

+ +

+* Make sure the **core-daemon** is running in a terminal + ```shell + sudop core-daemon + ``` +* In another terminal run the GUI + ```shell + core-gui + ``` +* Run the gRPC script in the VM + ```shell + # use the desired interface name, in this case enp0s3 + /opt/core/venv/bin/python scenario.py enp0s3 + ``` +* In the **core-gui** connect to the running session that was created +

+ +

+* Double click node **n1** to open a terminal and add a route to the Windows host + ```shell + ip route add 192.168.0.0/24 via 10.0.0.20 + ``` +* On the Windows host using Windows command prompt with administrator privilege, add a route that uses the interface connected to the associated interface assigned to the RJ45 node + ```shell + # if enp0s3 is ssigned 192.168.0.6/24 + route add 10.0.0.0 mask 255.255.255.0 192.168.0.6 + ``` +* Now you should be able to ping from the Windows host to **n1** + ```shell + C:\WINDOWS\system32>ping 10.0.0.20 + + Pinging 10.0.0.20 with 32 bytes of data: + Reply from 10.0.0.20: bytes=32 time<1ms TTL=64 + Reply from 10.0.0.20: bytes=32 time<1ms TTL=64 + Reply from 10.0.0.20: bytes=32 time<1ms TTL=64 + Reply from 10.0.0.20: bytes=32 time<1ms TTL=64 + + Ping statistics for 10.0.0.20: + Packets: Sent = 4, Received = 4, Lost = 0 (0% loss) + Approximate round trip times in milli-seconds: + Minimum = 0ms, Maximum = 0ms, Average = 0ms + ``` +* After pinging successfully, run the following in the **n1** terminal to start the chatapp server + ```shell + export PATH=$PATH:/usr/local/bin + chatapp-server + ``` +* On the Windows host, run the **client_for_windows.py** + ```shell + python3 client_for_windows.py -a 10.0.0.20 + connected to server(10.0.0.20:9001) as client(192.168.0.6:49960) + >> .Hello WORLD + .Hello WORLD Again + . + ``` +* Observe output on **n1** + ```shell + chat server listening on: :9001 + [server] 192.168.0.6:49960 joining + [192.168.0.6:49960] Hello WORLD + [192.168.0.6:49960] Hello WORLD Again + ``` +* When finished, you can stop the CORE scenario and cleanup +* On the Windows host remove the added route + ```shell + route delete 10.0.0.0 + ``` diff --git a/mkdocs.yml b/mkdocs.yml index b71a89bb..8f48bef1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -43,6 +43,7 @@ nav: - Setup: tutorials/setup.md - Tutorial 1: tutorials/tutorial1.md - Tutorial 4: tutorials/tutorial4.md + - Tutorial 5: tutorials/tutorial5.md - Tutorial 6: tutorials/tutorial6.md - Tutorial 7: tutorials/tutorial7.md - Detailed Topics: diff --git a/package/examples/tutorials/tutorial5/client_for_windows.py b/package/examples/tutorials/tutorial5/client_for_windows.py new file mode 100644 index 00000000..5f55680a --- /dev/null +++ b/package/examples/tutorials/tutorial5/client_for_windows.py @@ -0,0 +1,60 @@ +import argparse +import select +import socket +import sys + +DEFAULT_PORT: int = 9001 +READ_SIZE: int = 4096 + + +def prompt(): + sys.stdout.write(">> ") + sys.stdout.flush() + + +class ChatClient: + def __init__(self, address, port): + self.address = address + self.port = port + + def run(self): + server = socket.create_connection((self.address, self.port)) + sockname = server.getsockname() + print(f"connected to server({self.address}:{self.port}) as client({sockname[0]}:{sockname[1]})") + sockets = [server] + prompt() + try: + while True: + read_sockets, write_socket, error_socket = select.select(sockets, [], [], 10) + for sock in read_sockets: + if sock == server: + message = server.recv(READ_SIZE) + if not message: + print("server closed") + sys.exit(1) + else: + print("\x1b[2K\r", end="") + print(message.decode().strip()) + prompt() + # waiting for input + message = input(".") + server.sendall(f"{message}\n".encode()) + except KeyboardInterrupt: + print("client exiting") + server.close() + + +def main(): + parser = argparse.ArgumentParser( + description="chat app client", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + parser.add_argument("-a", "--address", help="address to listen on", required=True) + parser.add_argument("-p", "--port", type=int, help="port to listen on", default=DEFAULT_PORT) + args = parser.parse_args() + client = ChatClient(args.address, args.port) + client.run() + + +if __name__ == "__main__": + main() diff --git a/package/examples/tutorials/tutorial5/scenario.py b/package/examples/tutorials/tutorial5/scenario.py new file mode 100644 index 00000000..472208ab --- /dev/null +++ b/package/examples/tutorials/tutorial5/scenario.py @@ -0,0 +1,40 @@ +import sys + +from core.api.grpc import client, wrappers +from core.api.grpc.wrappers import NodeType, Position + + +def main(): + if (len(sys.argv) != 2): + print("usage core-python scenario.py ") + exit() + + # interface helper + iface_helper = client.InterfaceHelper(ip4_prefix="10.0.0.0/24", ip6_prefix="2001::/64") + + # create grpc client and connect + core = client.CoreGrpcClient() + core.connect() + + # add session + session = core.create_session() + + # create nodes + position = Position(x=100, y=100) + node1 = session.add_node(1, name="n1", position=position) + position = Position(x=300, y=100) + rj45 = session.add_node(2, name=sys.argv[1], _type=NodeType.RJ45, position=position) + + # create link + iface1 = iface_helper.create_iface(node1.id, 0) + iface1.ip4 = "10.0.0.20" + iface1.ip6 = "2001::14" + rj45_iface1 = wrappers.Interface(0) + session.add_link(node1=node1, node2=rj45, iface1=iface1, iface2=rj45_iface1) + + # start session + core.start_session(session) + + +if __name__ == "__main__": + main() diff --git a/package/examples/tutorials/tutorial5/scenario.xml b/package/examples/tutorials/tutorial5/scenario.xml new file mode 100644 index 00000000..05d93045 --- /dev/null +++ b/package/examples/tutorials/tutorial5/scenario.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +