3939import os
4040import struct
4141import time
42- from typing import override
42+ from typing import Any , override
4343
4444import click
45+ from net_addr import Ip4Address
46+ from net_addr import Ip6Address
47+ from net_addr import IpVersion
4548
4649from examples .lib .client import Client
4750from net_addr import (
48- ClickTypeIp4Address ,
49- ClickTypeIp4Host ,
50- ClickTypeIp6Address ,
51- ClickTypeIp6Host ,
5251 ClickTypeIpAddress ,
53- ClickTypeMacAddress ,
54- Ip4Address ,
55- Ip4Host ,
56- Ip6Address ,
57- Ip6Host ,
58- IpAddress ,
59- MacAddress ,
6052)
61- from pytcp import socket , stack
53+ from pytcp import socket
54+ from run_stack import cli as stack_cli
6255
6356ICMP4__ECHO_REQUEST__TYPE = 8
6457ICMP4__ECHO_REQUEST__CODE = 0
@@ -78,8 +71,7 @@ class IcmpEchoClient(Client):
7871 def __init__ (
7972 self ,
8073 * ,
81- local_ip_address : IpAddress ,
82- remote_ip_address : IpAddress ,
74+ remote_ip_address : Ip6Address | Ip4Address ,
8375 message_count : int = - 1 ,
8476 message_delay : int = 1 ,
8577 message_size : int = 5 ,
@@ -88,7 +80,6 @@ def __init__(
8880 Class constructor.
8981 """
9082
91- self ._local_ip_address = local_ip_address
9283 self ._remote_ip_address = remote_ip_address
9384 self ._message_count = message_count
9485 self ._message_delay = message_delay
@@ -147,22 +138,17 @@ def _thread__client__sender(self) -> None:
147138 message_count = self ._message_count
148139
149140 while self ._run_thread and message_count :
150- match (
151- self ._local_ip_address .version ,
152- self ._remote_ip_address .version ,
153- ):
154- case 6 , 6 :
141+ match self ._remote_ip_address .version :
142+ case IpVersion .IP6 :
155143 icmp_message = self ._create_icmp6_message (
156144 identifier = identifier ,
157145 sequence = self ._message_count - message_count + 1 ,
158146 )
159- case 4 , 4 :
147+ case IpVersion . IP4 :
160148 icmp_message = self ._create_icmp4_message (
161149 identifier = identifier ,
162150 sequence = self ._message_count - message_count + 1 ,
163151 )
164- case _:
165- raise ValueError ("Invalid IP address versions." )
166152
167153 try :
168154 self ._client_socket .send (icmp_message )
@@ -212,110 +198,31 @@ def _thread__client__receiver(self) -> None:
212198
213199
214200@click .command ()
215- @click .option (
216- "--stack-interface" ,
217- "stack__interface" ,
218- default = "tap7" ,
219- help = "Name of the interface to be used by the stack." ,
220- )
221- @click .option (
222- "--stack-mac-address" ,
223- "stack__mac_address" ,
224- type = ClickTypeMacAddress (),
225- default = None ,
226- help = "MAC address to be assigned to the stack interface." ,
227- )
228- @click .option (
229- "--stack-ip6-address" ,
230- "stack__ip6_host" ,
231- type = ClickTypeIp6Host (),
232- default = None ,
233- help = "IPv6 address/mask to be assigned to the stack interface." ,
234- )
235- @click .option (
236- "--stack-ip6-gateway" ,
237- "stack__ip6_gateway" ,
238- type = ClickTypeIp6Address (),
239- default = None ,
240- help = "IPv6 gateway address to be assigned to the stack interface." ,
241- )
242- @click .option (
243- "--stack-ip4-address" ,
244- "stack__ip4_host" ,
245- type = ClickTypeIp4Host (),
246- default = None ,
247- help = "IPv4 address/mask to be assigned to the stack interface." ,
248- )
249- @click .option (
250- "--stack-ip4-gateway" ,
251- "stack__ip4_gateway" ,
252- type = ClickTypeIp4Address (),
253- default = None ,
254- help = "IPv4 gateway address to be assigned to the stack interface." ,
255- )
256201@click .argument (
257202 "remote_ip_address" ,
258203 type = ClickTypeIpAddress (),
259204 required = True ,
260205)
206+ @click .pass_context
261207def cli (
208+ ctx : click .Context ,
262209 * ,
263- stack__interface : str ,
264- stack__mac_address : MacAddress | None ,
265- stack__ip6_host : Ip6Host | None ,
266- stack__ip6_gateway : Ip6Address | None ,
267- stack__ip4_host : Ip4Host | None ,
268- stack__ip4_gateway : Ip4Address | None ,
269- remote_ip_address : IpAddress ,
210+ remote_ip_address : Ip6Address | Ip4Address ,
211+ ** kwargs : dict [str , Any ],
270212) -> None :
271213 """
272214 Start PyTCP stack and stop it when user presses Ctrl-C.
273215 Start ICMP Echo client.
274216 """
275217
276- if stack__ip6_host :
277- stack__ip6_host .gateway = stack__ip6_gateway
278-
279- if stack__ip4_host :
280- stack__ip4_host .gateway = stack__ip4_gateway
281-
282- stack .init (
283- * stack .initialize_interface (stack__interface ),
284- mac_address = stack__mac_address ,
285- ip6_host = stack__ip6_host ,
286- ip4_host = stack__ip4_host ,
287- )
288-
289218 match remote_ip_address .version :
290- case 6 :
291- client = IcmpEchoClient (
292- local_ip_address = (
293- stack__ip6_host .address if stack__ip6_host else Ip6Address ()
294- ),
295- remote_ip_address = remote_ip_address ,
296- )
297- case 4 :
298- client = IcmpEchoClient (
299- local_ip_address = (
300- stack__ip4_host .address if stack__ip4_host else Ip4Address ()
301- ),
302- remote_ip_address = remote_ip_address ,
303- )
304- case _:
305- raise ValueError (
306- f"Invalid remote IP address version: { remote_ip_address .version } "
307- )
308-
309- try :
310- stack .start ()
311- client .start ()
312- while True :
313- time .sleep (1 )
219+ case IpVersion .IP6 :
220+ client = IcmpEchoClient (remote_ip_address = remote_ip_address )
221+ case IpVersion .IP4 :
222+ client = IcmpEchoClient (remote_ip_address = remote_ip_address )
314223
315- except KeyboardInterrupt :
316- client .stop ()
317- stack .stop ()
224+ ctx .invoke (stack_cli , subsystem = client , ** kwargs )
318225
319226
320227if __name__ == "__main__" :
321- cli () # pylint: disable = missing-kwoa
228+ cli . main ()
0 commit comments