Skip to content

Commit 7164512

Browse files
committed
bin: Add other functions of pynfdc
1 parent f33467a commit 7164512

File tree

14 files changed

+524
-68
lines changed

14 files changed

+524
-68
lines changed

src/ndn/app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,11 +407,11 @@ async def register(self, name: NonStrictName, func: Optional[Route], validator:
407407
ret = parse_response(reply)
408408
if ret['status_code'] != 200:
409409
logging.error(f'Registration for {Name.to_str(name)} failed: '
410-
f'{ret["status_code"]} {bytes(ret["status_text"]).decode()}')
410+
f'{ret["status_code"]} {ret["status_text"]}')
411411
return False
412412
else:
413413
logging.debug(f'Registration for {Name.to_str(name)} succeeded: '
414-
f'{ret["status_code"]} {bytes(ret["status_text"]).decode()}')
414+
f'{ret["status_code"]} {ret["status_text"]}')
415415
return True
416416
except (InterestNack, InterestTimeout, InterestCanceled, ValidationFailure) as e:
417417
logging.error(f'Registration for {Name.to_str(name)} failed: {e.__class__.__name__}')

src/ndn/app_support/nfd_mgmt.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class ControlParameters(TlvModel):
9090

9191
class ControlResponse(ControlParametersValue):
9292
status_code = UintField(0x66)
93-
status_text = BytesField(0x67)
93+
status_text = BytesField(0x67, is_string=True)
9494
body = IncludeBase(ControlParametersValue)
9595

9696

src/ndn/bin/nfdc/__init__.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
# limitations under the License.
1717
# -----------------------------------------------------------------------------
1818
import argparse
19-
from . import cmd_get_status, cmd_get_face
19+
from . import cmd_get_status, cmd_get_face, cmd_get_route, cmd_get_strategy, \
20+
cmd_remove_face, cmd_new_face, cmd_remove_route, cmd_new_route, cmd_remove_strategy, cmd_set_strategy
2021

2122

2223
CMD_LIST = '''
@@ -42,6 +43,14 @@ def main():
4243

4344
cmd_get_status.add_parser(subparsers)
4445
cmd_get_face.add_parser(subparsers)
46+
cmd_get_route.add_parser(subparsers)
47+
cmd_get_strategy.add_parser(subparsers)
48+
cmd_remove_face.add_parser(subparsers)
49+
cmd_new_face.add_parser(subparsers)
50+
cmd_remove_route.add_parser(subparsers)
51+
cmd_new_route.add_parser(subparsers)
52+
cmd_remove_strategy.add_parser(subparsers)
53+
cmd_set_strategy.add_parser(subparsers)
4554

4655
args = parser.parse_args()
4756
if 'executor' not in args:

src/ndn/bin/nfdc/cmd_get_face.py

Lines changed: 28 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
import argparse
1919
from ...app import NDNApp
2020
from ...encoding import Name, Component
21-
from ...types import InterestNack, InterestTimeout, InterestCanceled, ValidationFailure
22-
from ...app_support.nfd_mgmt import FaceStatusMsg, FaceQueryFilter, FaceQueryFilterValue, parse_response, FaceFlags
21+
from ...app_support.nfd_mgmt import FaceStatusMsg, FaceQueryFilter, FaceQueryFilterValue, parse_response
22+
from .utils import express_interest
2323

2424

2525
def add_parser(subparsers):
@@ -33,68 +33,44 @@ def execute(args: argparse.Namespace):
3333
app = NDNApp()
3434

3535
async def list_face():
36-
name = "/localhost/nfd/faces/list"
3736
try:
38-
_, _, data = await app.express_interest(
39-
name, lifetime=1000, can_be_prefix=True, must_be_fresh=True)
40-
37+
data = await express_interest(app, "/localhost/nfd/faces/list")
4138
msg = FaceStatusMsg.parse(data)
4239
# TODO: Should calculate the length instead of using a fixed number
4340
print(f'{"FaceID":7}{"RemoteURI":<30}\t{"LocalURI":<30}')
4441
print(f'{"------":7}{"---------":<30}\t{"--------":<30}')
4542
for f in msg.face_status:
4643
print(f'{f.face_id:<7}{f.uri:<30}\t{f.local_uri:<30}')
47-
48-
except InterestNack as e:
49-
print(f'Nacked with reason={e.reason}')
50-
except InterestTimeout:
51-
print('Timeout')
52-
except InterestCanceled:
53-
print('Local forwarder disconnected')
54-
except ValidationFailure:
55-
print('Data failed to validate')
5644
finally:
5745
app.shutdown()
5846

5947
async def inspect_face(face_id, face_uri):
6048
async def exec_query():
61-
try:
62-
_, _, data = await app.express_interest(
63-
data_name, lifetime=1000, can_be_prefix=True, must_be_fresh=True)
64-
65-
if not data:
66-
return False
67-
elif data[0] == 0x65:
68-
msg = parse_response(data)
69-
print('Query failed with response', msg['status_code'], msg['status_text'])
70-
else:
71-
msg = FaceStatusMsg.parse(data)
72-
for f in msg.face_status:
73-
print()
74-
print(f'{"Face ID":>12}\t{f.face_id}')
75-
print(f'{"Remote URI":>12}\t{f.uri}')
76-
print(f'{"Local URI":>12}\t{f.local_uri}')
77-
print(f'{"Scope":>12}\t{f.face_scope.name}')
78-
print(f'{"Persistency":>12}\t{f.face_persistency.name}')
79-
print(f'{"Link Type":>12}\t{f.link_type.name}')
80-
if f.mtu:
81-
print(f'{"MTU":>12}\t{f.mtu}')
82-
else:
83-
print(f'{"MTU":>12}\t-')
84-
print(f'{"Counter IN":>12}\t{f.n_in_interests}i {f.n_in_data}d '
85-
f'{f.n_in_nacks}n {f.n_in_bytes}B')
86-
print(f'{"Counter OUT":>12}\t{f.n_out_interests}i {f.n_out_data}d '
87-
f'{f.n_out_nacks}n {f.n_out_bytes}B')
88-
print(f'{"Flags":>12}\t{FaceFlags(f.flags)}')
89-
90-
except InterestNack as e:
91-
print(f'Nacked with reason={e.reason}')
92-
except InterestTimeout:
93-
print('Timeout')
94-
except InterestCanceled:
95-
print('Local forwarder disconnected')
96-
except ValidationFailure:
97-
print('Data failed to validate')
49+
data = await express_interest(app, data_name)
50+
if not data:
51+
return False
52+
elif data[0] == 0x65:
53+
msg = parse_response(data)
54+
print('Query failed with response', msg['status_code'], msg['status_text'])
55+
else:
56+
msg = FaceStatusMsg.parse(data)
57+
for f in msg.face_status:
58+
print()
59+
print(f'{"Face ID":>12}\t{f.face_id}')
60+
print(f'{"Remote URI":>12}\t{f.uri}')
61+
print(f'{"Local URI":>12}\t{f.local_uri}')
62+
print(f'{"Scope":>12}\t{f.face_scope.name}')
63+
print(f'{"Persistency":>12}\t{f.face_persistency.name}')
64+
print(f'{"Link Type":>12}\t{f.link_type.name}')
65+
if f.mtu:
66+
print(f'{"MTU":>12}\t{f.mtu}')
67+
else:
68+
print(f'{"MTU":>12}\t-')
69+
print(f'{"Counter IN":>12}\t{f.n_in_interests}i {f.n_in_data}d '
70+
f'{f.n_in_nacks}n {f.n_in_bytes}B')
71+
print(f'{"Counter OUT":>12}\t{f.n_out_interests}i {f.n_out_data}d '
72+
f'{f.n_out_nacks}n {f.n_out_bytes}B')
73+
print(f'{"Flags":>12}\t{f.flags}')
9874
return True
9975

10076
name = "/localhost/nfd/faces/query"

src/ndn/bin/nfdc/cmd_get_route.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# -----------------------------------------------------------------------------
2+
# Copyright (C) 2019-2021 The python-ndn authors
3+
#
4+
# This file is part of python-ndn.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
# -----------------------------------------------------------------------------
18+
import argparse
19+
from ...app import NDNApp
20+
from ...encoding import Name
21+
from ...app_support.nfd_mgmt import FibStatus, RibStatus
22+
from .utils import express_interest
23+
24+
25+
def add_parser(subparsers):
26+
parser = subparsers.add_parser('Get-Route', aliases=['route', 'gr'])
27+
parser.add_argument('route', metavar='ROUTE', nargs='?', default='',
28+
help='The prefix of the specified route to query')
29+
parser.set_defaults(executor=execute)
30+
31+
32+
def execute(args: argparse.Namespace):
33+
app = NDNApp()
34+
route = args.route
35+
36+
async def list_route():
37+
try:
38+
fib_data = await express_interest(app, "/localhost/nfd/fib/list")
39+
fib_msg = FibStatus.parse(fib_data)
40+
rib_data = await express_interest(app, "/localhost/nfd/rib/list")
41+
rib_msg = RibStatus.parse(rib_data)
42+
# TODO: Should calculate the length instead of using a fixed number
43+
print('Forwarding Table (FIB)')
44+
for ent in fib_msg.entries:
45+
prefix = Name.to_str(ent.name)
46+
if route and prefix != route:
47+
continue
48+
print(prefix)
49+
for nh in ent.next_hop_records:
50+
print(f'\tFaceID={nh.face_id:<5} Cost={nh.cost:<5}')
51+
print()
52+
print('Routing Table (RIB)')
53+
for ent in rib_msg.entries:
54+
prefix = Name.to_str(ent.name)
55+
if route and prefix != route:
56+
continue
57+
print(prefix)
58+
for nh in ent.routes:
59+
print(f'\tFaceID={nh.face_id:<5} Cost={nh.cost:<5} Origin={nh.origin:<3} Flags={nh.flags}')
60+
finally:
61+
app.shutdown()
62+
63+
app.run_forever(list_route())

src/ndn/bin/nfdc/cmd_get_status.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
import argparse
1919
import datetime
2020
from ...app import NDNApp
21-
from ...types import InterestNack, InterestTimeout, InterestCanceled, ValidationFailure
2221
from ...app_support.nfd_mgmt import GeneralStatus
22+
from .utils import express_interest
2323

2424

2525
def add_parser(subparsers):
@@ -31,10 +31,8 @@ def execute(_args: argparse.Namespace):
3131
app = NDNApp()
3232

3333
async def after_start():
34-
name = "/localhost/nfd/status/general"
3534
try:
36-
_, _, data = await app.express_interest(
37-
name, lifetime=1000, can_be_prefix=True, must_be_fresh=True)
35+
data = await express_interest(app, "/localhost/nfd/status/general")
3836

3937
msg = GeneralStatus.parse(data)
4038

@@ -59,14 +57,6 @@ async def after_start():
5957
print(f'{"nOutNacks":>25}\t{msg.n_out_nacks}')
6058
print(f'{"nSatisfiedInterests":>25}\t{msg.n_satisfied_interests}')
6159
print(f'{"nUnsatisfiedInterests":>25}\t{msg.n_unsatisfied_interests}')
62-
except InterestNack as e:
63-
print(f'Nacked with reason={e.reason}')
64-
except InterestTimeout:
65-
print('Timeout')
66-
except InterestCanceled:
67-
print('Local forwarder disconnected')
68-
except ValidationFailure:
69-
print('Data failed to validate')
7060
finally:
7161
app.shutdown()
7262

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# -----------------------------------------------------------------------------
2+
# Copyright (C) 2019-2021 The python-ndn authors
3+
#
4+
# This file is part of python-ndn.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
# -----------------------------------------------------------------------------
18+
import argparse
19+
from ...app import NDNApp
20+
from ...encoding import Name
21+
from ...app_support.nfd_mgmt import StrategyChoiceMsg
22+
from .utils import express_interest
23+
24+
25+
def add_parser(subparsers):
26+
parser = subparsers.add_parser('Get-Strategy', aliases=['strategy', 'gs'])
27+
parser.add_argument('prefix', metavar='PREFIX', nargs='?', default='',
28+
help='The specified route prefix')
29+
parser.set_defaults(executor=execute)
30+
31+
32+
def execute(args: argparse.Namespace):
33+
app = NDNApp()
34+
prefix = args.prefix
35+
36+
async def list_strategy():
37+
try:
38+
data = await express_interest(app, "/localhost/nfd/strategy-choice/list")
39+
msg = StrategyChoiceMsg.parse(data)
40+
for s in msg.strategy_choices:
41+
s_prefix = Name.to_str(s.name)
42+
if prefix and s_prefix != prefix:
43+
continue
44+
print(f'{s_prefix}\n\t{Name.to_str(s.strategy.name)}')
45+
finally:
46+
app.shutdown()
47+
48+
app.run_forever(list_strategy())

src/ndn/bin/nfdc/cmd_new_face.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# -----------------------------------------------------------------------------
2+
# Copyright (C) 2019-2021 The python-ndn authors
3+
#
4+
# This file is part of python-ndn.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
# -----------------------------------------------------------------------------
18+
import argparse
19+
from ...app import NDNApp
20+
from ...app_support.nfd_mgmt import parse_response, make_command
21+
from .utils import express_interest
22+
23+
24+
def add_parser(subparsers):
25+
parser = subparsers.add_parser('New-Face', aliases=['nf'])
26+
parser.add_argument('uri', metavar='URI',
27+
help='The URI or IP address of the face to create. '
28+
'Note: current version does not support DNS resolve.')
29+
parser.set_defaults(executor=execute)
30+
31+
32+
def execute(args: argparse.Namespace):
33+
app = NDNApp()
34+
uri = str(args.uri)
35+
if uri.find('://') < 0:
36+
uri = 'udp4://' + uri
37+
if len(uri.split(":")) < 3:
38+
uri = uri + ":6363"
39+
40+
async def create_face():
41+
cmd = make_command('faces', 'create', uri=uri.encode())
42+
res = await express_interest(app, cmd)
43+
msg = parse_response(res)
44+
print(f'{msg["status_code"]} {msg["status_text"]}')
45+
app.shutdown()
46+
47+
app.run_forever(after_start=create_face())

0 commit comments

Comments
 (0)