From 4a570bc77f39d096b75bc7fd461c387eed4b05b9 Mon Sep 17 00:00:00 2001 From: "Graydon, Tracy" Date: Mon, 24 Sep 2012 12:58:57 -0700 Subject: [PATCH 1/1] Initial commit --- CHANGES | 935 ++ CREDITS | 189 + INSTALL.txt | 255 + LICENSE | 19 + Makefile-devel-adds | 22 + Makefile.in | 445 + README | 233 + Readme.Win32 | 24 + VERSION | 1 + acconfig.h | 93 + aclocal.m4 | 1285 ++ addrtoname.c | 1183 ++ addrtoname.h | 55 + af.c | 63 + af.h | 57 + ah.h | 57 + aodv.h | 190 + appletalk.h | 168 + arcnet.h | 101 + atime.awk | 18 + atm.h | 33 + atmuni31.h | 87 + bgp.h | 17 + bootp.h | 231 + bpf_dump.c | 66 + chdlc.h | 27 + checksum.c | 196 + config.guess | 1502 ++ config.h.in | 338 + config.sub | 1708 +++ configure | 15345 +++++++++++++++++++ configure.in | 1105 ++ cpack.c | 144 + cpack.h | 51 + dccp.h | 139 + decnet.h | 461 + decode_prefix.h | 41 + enc.h | 47 + esp.h | 68 + ether.h | 59 + ethertype.h | 167 + extract.h | 130 + fddi.h | 76 + forces.h | 679 + gmpls.c | 197 + gmpls.h | 34 + gmt2local.c | 71 + gmt2local.h | 27 + icmp6.h | 464 + ieee802_11.h | 347 + ieee802_11_radio.h | 231 + igrp.h | 33 + install-sh | 250 + interface.h | 390 + ip.h | 164 + ip6.h | 205 + ipfc.h | 29 + ipnet.h | 13 + ipproto.c | 60 + ipproto.h | 144 + ipsec_doi.h | 151 + ipx.h | 31 + isakmp.h | 501 + l2tp.h | 62 + l2vpn.c | 58 + l2vpn.h | 17 + lane.h | 41 + lbl/os-osf4.h | 26 + lbl/os-solaris2.h | 30 + lbl/os-sunos4.h | 215 + lbl/os-ultrix4.h | 39 + llc.h | 123 + machdep.c | 67 + machdep.h | 27 + makemib | 249 + mib.h | 1460 ++ missing/addrinfo.h | 119 + missing/addrsize.h | 36 + missing/bittypes.h | 117 + missing/datalinks.c | 67 + missing/dlnames.c | 175 + missing/getnameinfo.c | 281 + missing/inet_aton.c | 60 + missing/inet_ntop.c | 219 + missing/inet_pton.c | 58 + missing/resolv6.h | 36 + missing/resolv_ext.h | 49 + missing/snprintf.c | 632 + missing/sockstorage.h | 38 + missing/strdup.c | 57 + missing/strlcat.c | 76 + missing/strlcpy.c | 73 + missing/strsep.c | 83 + mkdep | 109 + mpls.h | 41 + nameser.h | 315 + netbios.h | 16 + netdissect.h | 470 + nfs.h | 439 + nfsfh.h | 68 + nlpid.c | 45 + nlpid.h | 32 + ntp.h | 127 + oakley.h | 126 + ospf.h | 328 + ospf6.h | 265 + oui.c | 98 + oui.h | 81 + packaging/tcpdump-3.9.8-gethostby.patch | 93 + packaging/tcpdump-4.0.0-droproot.patch | 46 + packaging/tcpdump-4.0.0-icmp6msec.patch | 12 + packaging/tcpdump-4.0.0-portnumbers.patch | 37 + packaging/tcpdump.changes | 6 + packaging/tcpdump.spec | 93 + packaging/tcpslice-1.2a3-time.patch | 71 + packaging/tcpslice-1.2a3.tar.gz | Bin 0 -> 76879 bytes packaging/tcpslice-CVS.20010207-bpf.patch | 12 + packetdat.awk | 61 + parsenfsfh.c | 484 + pcap-missing.h | 60 + pcap_dump_ftell.c | 36 + pmap_prot.h | 89 + ppp.h | 71 + print-802_11.c | 1786 +++ print-ah.c | 71 + print-aodv.c | 455 + print-ap1394.c | 119 + print-arcnet.c | 298 + print-arp.c | 416 + print-ascii.c | 183 + print-atalk.c | 627 + print-atm.c | 449 + print-beep.c | 71 + print-bfd.c | 283 + print-bgp.c | 2602 ++++ print-bootp.c | 825 ++ print-bt.c | 79 + print-cdp.c | 379 + print-cfm.c | 645 + print-chdlc.c | 215 + print-cip.c | 116 + print-cnfp.c | 190 + print-dccp.c | 510 + print-decnet.c | 895 ++ print-dhcp6.c | 840 ++ print-domain.c | 751 + print-dtp.c | 123 + print-dvmrp.c | 369 + print-eap.c | 307 + print-egp.c | 362 + print-eigrp.c | 480 + print-enc.c | 98 + print-esp.c | 694 + print-ether.c | 359 + print-fddi.c | 309 + print-forces.c | 1043 ++ print-fr.c | 883 ++ print-frag6.c | 82 + print-gre.c | 403 + print-hsrp.c | 140 + print-icmp.c | 688 + print-icmp6.c | 1387 ++ print-igmp.c | 336 + print-igrp.c | 130 + print-ip.c | 741 + print-ip6.c | 265 + print-ip6opts.c | 329 + print-ipcomp.c | 91 + print-ipfc.c | 135 + print-ipnet.c | 109 + print-ipx.c | 221 + print-isakmp.c | 2570 ++++ print-isoclns.c | 2753 ++++ print-juniper.c | 1456 ++ print-krb.c | 261 + print-l2tp.c | 719 + print-lane.c | 118 + print-ldp.c | 623 + print-llc.c | 545 + print-lldp.c | 1107 ++ print-lmp.c | 883 ++ print-lspping.c | 896 ++ print-lwapp.c | 360 + print-lwres.c | 601 + print-mobile.c | 109 + print-mobility.c | 312 + print-mpcp.c | 274 + print-mpls.c | 189 + print-msdp.c | 108 + print-netbios.c | 91 + print-nfs.c | 1851 +++ print-ntp.c | 308 + print-null.c | 160 + print-olsr.c | 626 + print-ospf.c | 1157 ++ print-ospf6.c | 589 + print-pflog.c | 188 + print-pgm.c | 759 + print-pim.c | 1091 ++ print-ppp.c | 1757 +++ print-pppoe.c | 209 + print-pptp.c | 1060 ++ print-radius.c | 937 ++ print-raw.c | 53 + print-rip.c | 257 + print-ripng.c | 128 + print-rrcp.c | 143 + print-rsvp.c | 1944 +++ print-rt6.c | 105 + print-rx.c | 2798 ++++ print-sctp.c | 407 + print-sflow.c | 577 + print-sip.c | 64 + print-sl.c | 239 + print-sll.c | 231 + print-slow.c | 661 + print-smb.c | 1510 ++ print-snmp.c | 1904 +++ print-stp.c | 365 + print-sunatm.c | 117 + print-sunrpc.c | 172 + print-symantec.c | 120 + print-syslog.c | 163 + print-tcp.c | 811 + print-telnet.c | 267 + print-tftp.c | 161 + print-timed.c | 111 + print-token.c | 203 + print-udld.c | 173 + print-udp.c | 720 + print-usb.c | 174 + print-vjc.c | 119 + print-vqp.c | 209 + print-vrrp.c | 141 + print-vtp.c | 378 + print-wb.c | 444 + print-zephyr.c | 322 + route6d.h | 77 + rpc_auth.h | 79 + rpc_msg.h | 128 + rx.h | 113 + sctpConstants.h | 571 + sctpHeader.h | 323 + send-ack.awk | 68 + setsignal.c | 93 + setsignal.h | 27 + signature.c | 159 + signature.h | 26 + slcompress.h | 87 + slip.h | 34 + sll.h | 127 + smb.h | 122 + smbutil.c | 1889 +++ stime.awk | 19 + strcasecmp.c | 93 + tcp.h | 111 + tcpdump-stdinc.h | 193 + tcpdump.1.in | 1721 +++ tcpdump.c | 1833 +++ telnet.h | 348 + tests/02-sunrise-sunset-esp.puu | 34 + tests/08-sunrise-sunset-aes.puu | 36 + tests/08-sunrise-sunset-esp2.puu | 43 + tests/TESTLIST | 51 + tests/TESTonce | 46 + tests/TESTrun.sh | 63 + tests/bgp-infinite-loop.pcap | Bin 0 -> 554 bytes tests/bgp_vpn_attrset.out | 19 + tests/bgp_vpn_attrset.pcap | Bin 0 -> 217 bytes tests/chdlc-slarp-short.pcap | Bin 0 -> 58 bytes tests/chdlc-slarp.pcap | Bin 0 -> 62 bytes tests/dio.out | 1 + tests/dio.pcap | Bin 0 -> 120 bytes tests/e1000g.out | 20 + tests/e1000g.pcap | Bin 0 -> 2504 bytes tests/eapon1.gdbinit | 1 + tests/eapon1.out | 114 + tests/eapon1.puu | 368 + tests/eapon2.puu | 66 + tests/esp-secrets.txt | 5 + tests/esp0.out | 8 + tests/esp1.gdbinit | 1 + tests/esp1.out | 8 + tests/esp2.gdbinit | 1 + tests/esp2.out | 8 + tests/esp3.gdbinit | 1 + tests/esp4.gdbinit | 2 + tests/esp5.gdbinit | 3 + tests/esp5.out | 8 + tests/espudp1.out | 8 + tests/espudp1.puu | 35 + tests/forces1.out | 8 + tests/forces1.pcap | Bin 0 -> 476 bytes tests/forces1vvv.out | 52 + tests/forces1vvvv.out | 67 + tests/forces2.out | 491 + tests/forces2.pcap | Bin 0 -> 17566 bytes tests/forces2v.out | 982 ++ tests/forces2vv.out | 1966 +++ tests/ikev2.puu | 22231 ++++++++++++++++++++++++++++ tests/ikev2four.out | 107 + tests/ikev2four.puu | 134 + tests/ikev2fourv.out | 107 + tests/ikev2fourv4.out | 107 + tests/ikev2pI2-secrets.txt | 2 + tests/ikev2pI2.out | 41 + tests/ikev2pI2.puu | 24 + tests/isakmp-delete-segfault.puu | 20 + tests/isakmp-identification-segfault.puu | 11 + tests/isakmp-pointer-loop.puu | 6 + tests/isakmp1.out | 1 + tests/isakmp2.out | 1 + tests/isakmp3.out | 3 + tests/isakmp4.out | 35 + tests/isakmp4500.puu | 155 + tests/isis-infinite-loop.pcap | Bin 0 -> 454 bytes tests/ldp-infinite-loop.pcap | Bin 0 -> 414 bytes tests/lmp.out | 36 + tests/lmp.puu | 42 + tests/lmp.sh | 14 + tests/lspping-fec-ldp.pcap | Bin 0 -> 1190 bytes tests/lspping-fec-rsvp.pcap | Bin 0 -> 984 bytes tests/mpls-ldp-hello.out | 10 + tests/mpls-ldp-hello.puu | 6 + tests/mpls-traceroute.pcap | Bin 0 -> 1956 bytes tests/ospf-gmpls.out | 86 + tests/ospf-gmpls.puu | 18 + tests/print-A.out | 193 + tests/print-AA.out | 193 + tests/print-capX.out | 409 + tests/print-capXX.out | 419 + tests/print-flags.puu | 151 + tests/print-flags.sh | 12 + tests/print-x.out | 409 + tests/print-xx.out | 419 + tests/rsvp-infinite-loop.pcap | Bin 0 -> 384 bytes tftp.h | 82 + timed.h | 97 + token.h | 52 + udp.h | 93 + util.c | 608 + vfprintf.c | 59 + win32/Include/Arpa/tftp.h | 84 + win32/Include/Netinet/in_systm.h | 56 + win32/Include/Netinet/ip.h | 177 + win32/Include/errno.h | 132 + win32/Include/getopt.h | 138 + win32/Include/inetprivate.h | 40 + win32/Include/telnet.h | 320 + win32/Include/w32_fzs.h | 48 + win32/Src/getopt.c | 117 + win32/prj/GNUmakefile | 177 + win32/prj/WinDump.dsp | 635 + win32/prj/WinDump.dsw | 29 + 354 files changed, 144623 insertions(+) create mode 100644 CHANGES create mode 100644 CREDITS create mode 100644 INSTALL.txt create mode 100644 LICENSE create mode 100644 Makefile-devel-adds create mode 100644 Makefile.in create mode 100644 README create mode 100644 Readme.Win32 create mode 100644 VERSION create mode 100644 acconfig.h create mode 100644 aclocal.m4 create mode 100644 addrtoname.c create mode 100644 addrtoname.h create mode 100644 af.c create mode 100644 af.h create mode 100644 ah.h create mode 100644 aodv.h create mode 100644 appletalk.h create mode 100644 arcnet.h create mode 100644 atime.awk create mode 100644 atm.h create mode 100644 atmuni31.h create mode 100755 bgp.h create mode 100644 bootp.h create mode 100644 bpf_dump.c create mode 100644 chdlc.h create mode 100644 checksum.c create mode 100755 config.guess create mode 100644 config.h.in create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.in create mode 100644 cpack.c create mode 100644 cpack.h create mode 100644 dccp.h create mode 100644 decnet.h create mode 100644 decode_prefix.h create mode 100644 enc.h create mode 100644 esp.h create mode 100644 ether.h create mode 100644 ethertype.h create mode 100644 extract.h create mode 100644 fddi.h create mode 100644 forces.h create mode 100644 gmpls.c create mode 100644 gmpls.h create mode 100644 gmt2local.c create mode 100644 gmt2local.h create mode 100644 icmp6.h create mode 100644 ieee802_11.h create mode 100644 ieee802_11_radio.h create mode 100644 igrp.h create mode 100755 install-sh create mode 100644 interface.h create mode 100644 ip.h create mode 100644 ip6.h create mode 100644 ipfc.h create mode 100644 ipnet.h create mode 100755 ipproto.c create mode 100644 ipproto.h create mode 100644 ipsec_doi.h create mode 100644 ipx.h create mode 100644 isakmp.h create mode 100644 l2tp.h create mode 100755 l2vpn.c create mode 100755 l2vpn.h create mode 100644 lane.h create mode 100644 lbl/os-osf4.h create mode 100644 lbl/os-solaris2.h create mode 100644 lbl/os-sunos4.h create mode 100644 lbl/os-ultrix4.h create mode 100644 llc.h create mode 100644 machdep.c create mode 100644 machdep.h create mode 100755 makemib create mode 100644 mib.h create mode 100644 missing/addrinfo.h create mode 100644 missing/addrsize.h create mode 100644 missing/bittypes.h create mode 100644 missing/datalinks.c create mode 100644 missing/dlnames.c create mode 100644 missing/getnameinfo.c create mode 100644 missing/inet_aton.c create mode 100644 missing/inet_ntop.c create mode 100644 missing/inet_pton.c create mode 100644 missing/resolv6.h create mode 100644 missing/resolv_ext.h create mode 100644 missing/snprintf.c create mode 100644 missing/sockstorage.h create mode 100644 missing/strdup.c create mode 100644 missing/strlcat.c create mode 100644 missing/strlcpy.c create mode 100644 missing/strsep.c create mode 100755 mkdep create mode 100644 mpls.h create mode 100644 nameser.h create mode 100644 netbios.h create mode 100644 netdissect.h create mode 100644 nfs.h create mode 100644 nfsfh.h create mode 100755 nlpid.c create mode 100644 nlpid.h create mode 100644 ntp.h create mode 100644 oakley.h create mode 100644 ospf.h create mode 100644 ospf6.h create mode 100644 oui.c create mode 100644 oui.h create mode 100644 packaging/tcpdump-3.9.8-gethostby.patch create mode 100644 packaging/tcpdump-4.0.0-droproot.patch create mode 100644 packaging/tcpdump-4.0.0-icmp6msec.patch create mode 100644 packaging/tcpdump-4.0.0-portnumbers.patch create mode 100644 packaging/tcpdump.changes create mode 100644 packaging/tcpdump.spec create mode 100644 packaging/tcpslice-1.2a3-time.patch create mode 100644 packaging/tcpslice-1.2a3.tar.gz create mode 100644 packaging/tcpslice-CVS.20010207-bpf.patch create mode 100644 packetdat.awk create mode 100644 parsenfsfh.c create mode 100644 pcap-missing.h create mode 100644 pcap_dump_ftell.c create mode 100644 pmap_prot.h create mode 100644 ppp.h create mode 100644 print-802_11.c create mode 100644 print-ah.c create mode 100644 print-aodv.c create mode 100644 print-ap1394.c create mode 100644 print-arcnet.c create mode 100644 print-arp.c create mode 100644 print-ascii.c create mode 100644 print-atalk.c create mode 100644 print-atm.c create mode 100644 print-beep.c create mode 100644 print-bfd.c create mode 100644 print-bgp.c create mode 100644 print-bootp.c create mode 100644 print-bt.c create mode 100644 print-cdp.c create mode 100644 print-cfm.c create mode 100644 print-chdlc.c create mode 100644 print-cip.c create mode 100644 print-cnfp.c create mode 100644 print-dccp.c create mode 100644 print-decnet.c create mode 100644 print-dhcp6.c create mode 100644 print-domain.c create mode 100644 print-dtp.c create mode 100644 print-dvmrp.c create mode 100644 print-eap.c create mode 100644 print-egp.c create mode 100644 print-eigrp.c create mode 100644 print-enc.c create mode 100644 print-esp.c create mode 100644 print-ether.c create mode 100644 print-fddi.c create mode 100644 print-forces.c create mode 100644 print-fr.c create mode 100644 print-frag6.c create mode 100644 print-gre.c create mode 100644 print-hsrp.c create mode 100644 print-icmp.c create mode 100644 print-icmp6.c create mode 100644 print-igmp.c create mode 100644 print-igrp.c create mode 100644 print-ip.c create mode 100644 print-ip6.c create mode 100644 print-ip6opts.c create mode 100644 print-ipcomp.c create mode 100644 print-ipfc.c create mode 100644 print-ipnet.c create mode 100644 print-ipx.c create mode 100644 print-isakmp.c create mode 100644 print-isoclns.c create mode 100644 print-juniper.c create mode 100644 print-krb.c create mode 100644 print-l2tp.c create mode 100644 print-lane.c create mode 100644 print-ldp.c create mode 100644 print-llc.c create mode 100644 print-lldp.c create mode 100644 print-lmp.c create mode 100644 print-lspping.c create mode 100644 print-lwapp.c create mode 100644 print-lwres.c create mode 100644 print-mobile.c create mode 100644 print-mobility.c create mode 100644 print-mpcp.c create mode 100644 print-mpls.c create mode 100644 print-msdp.c create mode 100644 print-netbios.c create mode 100644 print-nfs.c create mode 100644 print-ntp.c create mode 100644 print-null.c create mode 100644 print-olsr.c create mode 100644 print-ospf.c create mode 100644 print-ospf6.c create mode 100644 print-pflog.c create mode 100644 print-pgm.c create mode 100644 print-pim.c create mode 100644 print-ppp.c create mode 100644 print-pppoe.c create mode 100644 print-pptp.c create mode 100644 print-radius.c create mode 100644 print-raw.c create mode 100644 print-rip.c create mode 100644 print-ripng.c create mode 100644 print-rrcp.c create mode 100644 print-rsvp.c create mode 100644 print-rt6.c create mode 100644 print-rx.c create mode 100644 print-sctp.c create mode 100644 print-sflow.c create mode 100644 print-sip.c create mode 100644 print-sl.c create mode 100644 print-sll.c create mode 100644 print-slow.c create mode 100644 print-smb.c create mode 100644 print-snmp.c create mode 100644 print-stp.c create mode 100644 print-sunatm.c create mode 100644 print-sunrpc.c create mode 100644 print-symantec.c create mode 100755 print-syslog.c create mode 100644 print-tcp.c create mode 100644 print-telnet.c create mode 100644 print-tftp.c create mode 100644 print-timed.c create mode 100644 print-token.c create mode 100644 print-udld.c create mode 100644 print-udp.c create mode 100644 print-usb.c create mode 100644 print-vjc.c create mode 100644 print-vqp.c create mode 100644 print-vrrp.c create mode 100644 print-vtp.c create mode 100644 print-wb.c create mode 100644 print-zephyr.c create mode 100644 route6d.h create mode 100644 rpc_auth.h create mode 100644 rpc_msg.h create mode 100644 rx.h create mode 100644 sctpConstants.h create mode 100644 sctpHeader.h create mode 100644 send-ack.awk create mode 100644 setsignal.c create mode 100644 setsignal.h create mode 100644 signature.c create mode 100644 signature.h create mode 100644 slcompress.h create mode 100644 slip.h create mode 100644 sll.h create mode 100644 smb.h create mode 100644 smbutil.c create mode 100644 stime.awk create mode 100644 strcasecmp.c create mode 100644 tcp.h create mode 100644 tcpdump-stdinc.h create mode 100644 tcpdump.1.in create mode 100644 tcpdump.c create mode 100644 telnet.h create mode 100644 tests/02-sunrise-sunset-esp.puu create mode 100644 tests/08-sunrise-sunset-aes.puu create mode 100644 tests/08-sunrise-sunset-esp2.puu create mode 100644 tests/TESTLIST create mode 100755 tests/TESTonce create mode 100755 tests/TESTrun.sh create mode 100644 tests/bgp-infinite-loop.pcap create mode 100644 tests/bgp_vpn_attrset.out create mode 100644 tests/bgp_vpn_attrset.pcap create mode 100644 tests/chdlc-slarp-short.pcap create mode 100644 tests/chdlc-slarp.pcap create mode 100644 tests/dio.out create mode 100644 tests/dio.pcap create mode 100644 tests/e1000g.out create mode 100644 tests/e1000g.pcap create mode 100644 tests/eapon1.gdbinit create mode 100644 tests/eapon1.out create mode 100644 tests/eapon1.puu create mode 100644 tests/eapon2.puu create mode 100644 tests/esp-secrets.txt create mode 100644 tests/esp0.out create mode 100644 tests/esp1.gdbinit create mode 100644 tests/esp1.out create mode 100644 tests/esp2.gdbinit create mode 100644 tests/esp2.out create mode 100644 tests/esp3.gdbinit create mode 100644 tests/esp4.gdbinit create mode 100644 tests/esp5.gdbinit create mode 100644 tests/esp5.out create mode 100644 tests/espudp1.out create mode 100644 tests/espudp1.puu create mode 100644 tests/forces1.out create mode 100644 tests/forces1.pcap create mode 100644 tests/forces1vvv.out create mode 100644 tests/forces1vvvv.out create mode 100644 tests/forces2.out create mode 100644 tests/forces2.pcap create mode 100644 tests/forces2v.out create mode 100644 tests/forces2vv.out create mode 100644 tests/ikev2.puu create mode 100644 tests/ikev2four.out create mode 100644 tests/ikev2four.puu create mode 100644 tests/ikev2fourv.out create mode 100644 tests/ikev2fourv4.out create mode 100644 tests/ikev2pI2-secrets.txt create mode 100644 tests/ikev2pI2.out create mode 100644 tests/ikev2pI2.puu create mode 100644 tests/isakmp-delete-segfault.puu create mode 100644 tests/isakmp-identification-segfault.puu create mode 100644 tests/isakmp-pointer-loop.puu create mode 100644 tests/isakmp1.out create mode 100644 tests/isakmp2.out create mode 100644 tests/isakmp3.out create mode 100644 tests/isakmp4.out create mode 100644 tests/isakmp4500.puu create mode 100644 tests/isis-infinite-loop.pcap create mode 100644 tests/ldp-infinite-loop.pcap create mode 100644 tests/lmp.out create mode 100644 tests/lmp.puu create mode 100755 tests/lmp.sh create mode 100644 tests/lspping-fec-ldp.pcap create mode 100644 tests/lspping-fec-rsvp.pcap create mode 100644 tests/mpls-ldp-hello.out create mode 100644 tests/mpls-ldp-hello.puu create mode 100644 tests/mpls-traceroute.pcap create mode 100644 tests/ospf-gmpls.out create mode 100644 tests/ospf-gmpls.puu create mode 100644 tests/print-A.out create mode 100644 tests/print-AA.out create mode 100644 tests/print-capX.out create mode 100644 tests/print-capXX.out create mode 100644 tests/print-flags.puu create mode 100755 tests/print-flags.sh create mode 100644 tests/print-x.out create mode 100644 tests/print-xx.out create mode 100644 tests/rsvp-infinite-loop.pcap create mode 100644 tftp.h create mode 100644 timed.h create mode 100644 token.h create mode 100644 udp.h create mode 100644 util.c create mode 100644 vfprintf.c create mode 100644 win32/Include/Arpa/tftp.h create mode 100644 win32/Include/Netinet/in_systm.h create mode 100644 win32/Include/Netinet/ip.h create mode 100644 win32/Include/errno.h create mode 100644 win32/Include/getopt.h create mode 100644 win32/Include/inetprivate.h create mode 100644 win32/Include/telnet.h create mode 100644 win32/Include/w32_fzs.h create mode 100644 win32/Src/getopt.c create mode 100644 win32/prj/GNUmakefile create mode 100644 win32/prj/WinDump.dsp create mode 100644 win32/prj/WinDump.dsw diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..33f453b --- /dev/null +++ b/CHANGES @@ -0,0 +1,935 @@ +Thu. April 1, 2010. guy@alum.mit.edu. + Summary for 4.1.1 tcpdump release + Fix build on systems with PF, such as FreeBSD and OpenBSD. + Don't blow up if a zero-length link-layer address is passed to + linkaddr_string(). + +Thu. March 11, 2010. ken@netfunctional.ca/guy@alum.mit.edu. + Summary for 4.1.0 tcpdump release + Fix printing of MAC addresses for VLAN frames with a length + field + Add some additional bounds checks and use the EXTRACT_ macros + more + Add a -b flag to print the AS number in BGP packets in ASDOT + notation rather than ASPLAIN notation + Add ICMPv6 RFC 5006 support + Decode the access flags in NFS access requests + Handle the new DLT_ for memory-mapped USB captures on Linux + Make the default snapshot (-s) the maximum + Print name of device (when -L is used) + Support for OpenSolaris (and SXCE build 125 and later) + Print new TCP flags + Add support for RPL DIO + Add support for TCP User Timeout (UTO) + Add support for non-standard Ethertypes used by 3com PPPoE gear + Add support for 802.11n and 802.11s + Add support for Transparent Ethernet Bridge ethertype in GRE + Add 4 byte AS support for BGP printer + Add support for the MDT SAFI 66 BG printer + Add basic IPv6 support to print-olsr + Add USB printer + Add printer for ForCES + Handle frames with an FCS + Handle 802.11n Control Wrapper, Block Acq Req and Block Ack frames + Fix TCP sequence number printing + Report 802.2 packets as 802.2 instead of 802.3 + Don't include -L/usr/lib in LDFLAGS + On x86_64 Linux, look in lib64 directory too + Lots of code clean ups + Autoconf clean ups + Update testcases to make output changes + Fix compiling with/out smi (--with{,out}-smi) + Fix compiling without IPv6 support (--disable-ipv6) + +Mon. October 27, 2008. ken@netfunctional.ca. Summary for 4.0.0 tcpdump release + Add support for Bluetooth Sniffing + Add support for Realtek Remote Control Protocol (openrrcp.org.ru) + Add support for 802.11 AVS + Add support for SMB over TCP + Add support for 4 byte BGP AS printing + Add support for compiling on case-insensitive file systems + Add support for ikev2 printing + Update support for decoding AFS + Update DHCPv6 printer + Use newer libpcap API's (allows -B option on all platforms) + Add -I to turn on monitor mode + Bugfixes in lldp, lspping, dccp, ESP, NFS printers + Cleanup unused files and various cruft + +Mon. September 10, 2007. ken@xelerance.com. Summary for 3.9.8 tcpdump release + Rework ARP printer + Rework OSPFv3 printer + Add support for Frame-Relay ARP + Decode DHCP Option 121 (RFC 3442 Classless Static Route) + Decode DHCP Option 249 (MS Classless Static Route) the same as Option 121 + TLV: Add support for Juniper .pcap extensions + Print EGP header in new-world-order style + Converted print-isakmp.c to NETDISSECT + Moved AF specific stuff into af.h + Test subsystem now table driven, and saves outputs and diffs to one place + Require for pf definitions - allows reading of pflog formatted + libpcap files on an OS other than where the file was generated + + +Wed. July 23, 2007. mcr@xelerance.com. Summary for 3.9.7 libpcap release + + NFS: Print unsigned values as such. + RX: parse safely. + BGP: fixes for IPv6-less builds. + 801.1ag: use standard codepoint. + use /dev/bpf on systems with such a device. + 802.11: print QoS data, avoid dissect of no-data frame, ignore padding. + smb: make sure that we haven't gone past the end of the captured data. + smb: squelch an uninitialized complaint from coverity. + NFS: from NetBSD; don't interpret the reply as a possible NFS reply + if it got MSG_DENIED. + BGP: don't print TLV values that didn't fit, from www.digit-labs.org. + revised INSTALL.txt about libpcap dependancy. + +Wed. April 25, 2007. ken@xelerance.com. Summary for 3.9.6 tcpdump release + Update man page to reflect changes to libpcap + Changes to both TCP and IP Printer Output + Fix a potential buffer overflow in the 802.11 printer + Print basic info about a few more Cisco LAN protocols. + mDNS cleanup + ICMP MPLS rework of the extension code + bugfix: use the correct codepoint for the OSPF simple text auth token + entry, and use safeputs to print the password. + Add support in pflog for additional values + Add support for OIF RSVP Extensions UNI 1.0 Rev. 2 and additional RSVP objects + Add support for the Message-id NACK c-type. + Add support for 802.3ah loopback ctrl msg + Add support for Multiple-STP as per 802.1s + Add support for rapid-SPT as per 802.1w + Add support for CFM Link-trace msg, Link-trace-Reply msg, + Sender-ID tlv, private tlv, port, interface status + Add support for unidirectional link detection as per + http://www.ietf.org/internet-drafts/draft-foschiano-udld-02.txt + Add support for the olsr protocol as per RFC 3626 plus the LQ + extensions from olsr.org + Add support for variable-length checksum in DCCP, as per section 9 of + RFC 4340. + Add support for per-VLAN spanning tree and per-VLAN rapid spanning tree + Add support for Multiple-STP as per 802.1s + Add support for the cisco propriatry 'dynamic trunking protocol' + Add support for the cisco proprietary VTP protocol + Update dhcp6 options table as per IETF standardization activities + + +Tue. September 19, 2006. ken@xelerance.com. Summary for 3.9.5 tcpdump release + + Fix compiling on AIX (, at end of ENUM) + Updated list of DNS RR typecodes + Use local Ethernet defs on WIN32 + Add support for Frame-Relay ARP + Fixes for compiling under MSVC++ + Add support for parsing Juniper .pcap files + Add support for FRF.16 Multilink Frame-Relay (DLT_MFR) + Rework the OSPFv3 printer + Fix printing for 4.4BSD/NetBSD NFS Filehandles + Add support for Cisco style NLPID encapsulation + Add cisco prop. eigrp related, extended communities + Add support for BGP signaled VPLS + Cleanup the bootp printer + Add support for PPP over Frame-Relay + Add some bounds checking to the IP options code, and clean up + the options output a bit. + Add additional modp groups to ISAKMP printer + Add support for Address-Withdraw and Label-Withdraw Msgs + Add support for the BFD Discriminator TLV + Fixes for 64bit compiling + Add support for PIMv2 checksum verification + Add support for further dissection of the IPCP Compression Option + Add support for Cisco's proposed VQP protocol + Add basic support for keyed authentication TCP option + Lots of minor cosmetic changes to output printers + + +Mon. September 19, 2005. ken@xelerance.com. Summary for 3.9.4 tcpdump release + Decoder support for more Juniper link-layer types + Fix a potential buffer overflow (although it can't occur in + practice). + Fix the handling of unknown management frame types in the 802.11 + printer. + Add FRF.16 support, fix various Frame Relay bugs. + Add support for RSVP integrity objects, update fast-reroute + object printer to latest spec. + Clean up documentation of vlan filter expression, document mpls + filter expression. + Document new pppoed and pppoes filter expressions. + Update diffserver-TE codepoints as per RFC 4124. + Spelling fixes in ICMPv6. + Don't require any fields other than flags to be present in IS-IS + restart signaling TLVs, and only print the system ID in + those TLVs as system IDs, not as node IDs. + Support for DCCP. + +Tue. July 5, 2005. ken@xelerance.com. Summary for 3.9.3 tcpdump release + + Option to chroot() when dropping privs + Fixes for compiling on nearly every platform, + including improved 64bit support + Many new testcases + Support for sending packets + Many compliation fixes on most platforms + Fixes for recent version of GCC to eliminate warnings + Improved Unicode support + + Decoders & DLT Changes, Updates and New: + AES ESP support + Juniper ATM, FRF.15, FRF.16, PPPoE, + ML-FR, ML-PIC, ML-PPP, PL-PPP, LS-PIC + GGSN,ES,MONITOR,SERVICES + L2VPN + Axent Raptor/Symantec Firewall + TCP-MD5 (RFC 2385) + ESP-in-UDP (RFC 3948) + ATM OAM + LMP, LMP Service Discovery + IP over FC + IP over IEEE 1394 + BACnet MS/TP + SS7 + LDP over TCP + LACP, MARKER as per 802.3ad + PGM (RFC 3208) + LSP-PING + G.7041/Y.1303 Generic Framing Procedure + EIGRP-IP, EIGRP-IPX + ICMP6 + Radio - via radiotap + DHCPv6 + HDLC over PPP + +Tue. March 30, 2004. mcr@sandelman.ottawa.on.ca. Summary for 3.8.3 release + + No changes from 3.8.2. Version bumped only to maintain consistency + with libpcap 0.8.3. + +Mon. March 29, 2004. mcr@sandelman.ottawa.on.ca. Summary for 3.8.2 release + + Fixes for print-isakmp.c CVE: CAN-2004-0183, CAN-2004-0184 + http://www.rapid7.com/advisories/R7-0017.html + IP-over-IEEE1394 printing. + some MINGW32 changes. + updates for autoconf 2.5 + fixes for print-aodv.c - check for too short packets + formatting changes to print-ascii for hex output. + check for too short packets: print-bgp.c, print-bootp.c, print-cdp.c, + print-chdlc.c, print-domain.c, print-icmp.c, print-icmp6.c, + print-ip.c, print-lwres.c, print-ospf.c, print-pim.c, + print-ppp.c,print-pppoe.c, print-rsvp.c, print-wb.c + print-ether.c - better handling of unknown types. + print-isoclns.c - additional decoding of types. + print-llc.c - strings for LLC names added. + print-pfloc.c - various enhancements + print-radius.c - better decoding to strings. + +Wed. November 12, 2003. mcr@sandelman.ottawa.on.ca. Summary for 3.8 release + + changed syntax of -E argument so that multiple SAs can be decrypted + fixes for Digital Unix headers and Documentation + __attribute__ fixes + CDP changes from Terry Kennedy . + IPv6 mobility updates from Kazushi Sugyo + Fixes for ASN.1 decoder for 2.100.3 forms. + Added a count of packets received and processed to clarify numbers. + Incorporated WinDUMP patches for Win32 builds. + PPPoE payload length headers. + Fixes for HP C compiler builds. + Use new pcap_breakloop() and pcap_findalldevs() if we can. + BGP output split into multiple lines. + Fixes to 802.11 decoding. + Fixes to PIM decoder. + SuperH is a CPU that can't handle unaligned access. Many fixes for + unaligned access work. + Fixes to Frame-Relay decoder for Q.933/922 frames. + Clarified when Solaris can do captures as non-root. + Added tests/ subdir for examples/regression tests. + New -U flag. -flush stdout after every packet + New -A flag -print ascii only + support for decoding IS-IS inside Cisco HDLC Frames + more verbosity for tftp decoder + mDNS decoder + new BFD decoder + cross compilation patches + RFC 3561 AODV support. + UDP/TCP pseudo-checksum properly for source-route options. + sanitized all files to modified BSD license + Add support for RFC 2625 IP-over-Fibre Channel. + fixes for DECnet support. + Support RFC 2684 bridging of Ethernet, 802.5 Token Ring, and FDDI. + RFC 2684 encapsulation of BPDUs. + +Tuesday, February 25, 2003. fenner@research.att.com. 3.7.2 release + + Fixed infinite loop when parsing malformed isakmp packets. + (reported by iDefense; already fixed in CVS) + Fixed infinite loop when parsing malformed BGP packets. + Fixed buffer overflow with certain malformed NFS packets. + Pretty-print unprintable network names in 802.11 printer. + Handle truncated nbp (appletalk) packets. + Updated DHCPv6 printer to match draft-ietf-dhc-dhcpv6-22.txt + Print IP protocol name even if we don't have a printer for it. + Print IP protocol name or number for fragments. + Print the whole MPLS label stack, not just the top label. + Print request header and file handle for NFS v3 FSINFO and PATHCONF + requests. + Fix NFS packet truncation checks. + Handle "old" DR-Priority and Bidir-Capable PIM HELLO options. + Handle unknown RADIUS attributes properly. + Fix an ASN.1 parsing error that would cause e.g. the OID + 2.100.3 to be misrepresented as 4.20.3 . + +Monday, January 21, 2002. mcr@sandelman.ottawa.on.ca. Summary for 3.7 release +see http://www.tcpdump.org/cvs-log/2002-01-21.10:16:48.html for commit log. + keyword "ipx" added. + Better OSI/802.2 support on Linux. + IEEE 802.11 support, from clenahan@fortresstech.com, achirica@ttd.net. + LLC SAP support for FDDI/token ring/RFC-1483 style ATM + BXXP protocol was replaced by the BEEP protocol; + improvements to SNAP demux. + Changes to "any" interface documentation. + Documentation on pcap_stats() counters. + Fix a memory leak found by Miklos Szeredi - pcap_ether_aton(). + Added MPLS encapsulation decoding per RFC3032. + DNS dissector handles TKEY, TSIG and IXFR. + adaptive SLIP interface patch from Igor Khristophorov + SMB printing has much improved bounds checks + OUI 0x0000f8 decoded as encapsulated ethernet for Cisco-custom bridging + Zephyr support, from Nickolai Zeldovich . + Solaris - devices with digits in them. Stefan Hudson + IPX socket 0x85be is for Cisco EIGRP over IPX. + Improvements to fragmented ESP handling. + SCTP support from Armando L. Caro Jr. + Linux ARPHDR_ATM support fixed. + Added a "netbeui" keyword, which selects NetBEUI packets. + IPv6 ND improvements, MobileIP dissector, 2292bis-02 for RA option. + Handle ARPHDR_HDLC from Marcus Felipe Pereira . + Handle IPX socket 0x553 -> NetBIOS-over-IPX socket, "nwlink-dgm" + Better Linux libc5 compat. + BIND9 lwres dissector added. + MIPS and SPARC get strict alignment macros (affects print-bgp.c) + Apple LocalTalk LINKTYPE_ reserved. + New time stamp formats documented. + DHCP6 updated to draft-22.txt spec. + ICMP types/codes now accept symbolic names. + Add SIGINFO handler from LBL + encrypted CIPE tunnels in IRIX, from Franz Schaefer . + now we are -Wstrict-prototype clean. + NetBSD DLT_PPP_ETHER; adapted from Martin Husemann . + PPPoE dissector cleaned up. + Support for LocalTalk hardware, from Uns Lider . + In dissector, now the caller prints the IP addresses rather than proto. + cjclark@alum.mit.edu: print the IP proto for non-initial fragments. + LLC frames with a DSAP and LSAP of 0xe0 are IPX frames. + Linux cooked frames with a type value of LINUX_SLL_P_802_3 are IPX. + captures on the "any" device won't be done in promiscuous mode + Token Ring support on DLPI - Onno van der Linden + ARCNet support, from NetBSD. + HSRP dissector, from Julian Cowley . + Handle (GRE-encapsulated) PPTP + added -C option to rotate save file every optarg * 1,000,000 bytes. + support for "vrrp" name - NetBSD, by Klaus Klein . + PPTP support, from Motonori Shindo . + IS-IS over PPP support, from Hannes Gredler . + CNFP support for IPv6,format. Harry Raaymakers . + ESP printing updated to RFC2406. + HP-UX can now handle large number of PPAs. + MSDP printer added. + L2TP dissector improvements from Motonori Shindo. + +Tuesday January 9, 2001. mcr@sandelman.ottawa.on.ca. Summary for 3.6 release + Cleaned up documentation. + Promisc mode fixes for Linux + IPsec changes/cleanups. + Alignment fixes for picky architectures + + Removed dependency on native headers for packet dissectors. + Removed Linux specific headers that were shipped + + libpcap changes provide for exchanging capture files between + systems. Save files now have well known PACKET_ values instead of + depending upon system dependant mappings of DLT_* types. + + Support for computing/checking IP and UDP/TCP checksums. + + Updated autoconf stock files. + + IPv6 improvements: dhcp (draft-15), mobile-ip6, ppp, ospf6, + + Added dissector support for: ISOCLNS, Token Ring, IGMPv3, bxxp, + timed, vrrp, radius, chdlc, cnfp, cdp, IEEE802.1d, raw-AppleTalk + + Added filtering support for: VLANs, ESIS, ISIS + + Improvements to: print-telnet, IPTalk, bootp/dhcp, ECN, PPP, + L2TP, PPPoE + + HP-UX 11.0 -- find the right dlpi device. + Solaris 8 - IPv6 works + Linux - Added support for an "any" device to capture on all interfaces + + Security fixes: buffer overrun audit done. Strcpy replaced with + strlcpy, sprintf replaced with snprintf. + Look for lex problems, and warn about them. + + +v3.5 Fri Jan 28 18:00:00 PST 2000 + +Bill Fenner +- switch to config.h for autoconf +- unify RCSID strings +- Updated PIMv1, PIMv2, DVMRP, IGMP parsers, add Cisco Auto-RP parser +- Really fix the RIP printer +- Fix MAC address -> name translation. +- some -Wall -Wformat fixes +- update makemib to parse much of SMIv2 +- Print TCP sequence # with -vv even if you normally wouldn't +- Print as much of IP/TCP/UDP headers as possible even if truncated. + +itojun@iijlab.net +- -X will make a ascii dump. from netbsd. +- telnet command sequence decoder (ff xx xx). from netbsd. +- print-bgp.c: improve options printing. ugly code exists for + unaligned option parsing (need some fix). +- const poisoning in SMB decoder. +- -Wall -Werror clean checks. +- bring in KAME IPv6/IPsec decoding code. + +Assar Westerlund +- SNMPv2 and SNMPv3 printer +- If compiled with libsmi, tcpdump can load MIBs on the fly to decode + SNMP packets. +- Incorporate NFS parsing code from NetBSD. Adds support for nfsv3. +- portability fixes +- permit building in different directories. + +Ken Hornstein +- bring in code at + /afs/transarc.com/public/afs-contrib/tools/tcpdump for parsing + AFS3 packets + +Andrew Tridgell +- SMB printing code + +Love +- print-rx.c: add code for printing MakeDir and StoreStatus. Also + change date format to the right one. + +Michael C. Richardson +- Created tcpdump.org repository + +v3.4 Sat Jul 25 12:40:55 PDT 1998 + +- Hardwire Linux slip support since it's too hard to detect. + +- Redo configuration of "network" libraries (-lsocket and -lnsl) to + deal with IRIX. Thanks to John Hawkinson (jhawk@mit.edu) + +- Added -a which tries to translate network and broadcast addresses to + names. Suggested by Rob van Nieuwkerk (robn@verdi.et.tudelft.nl) + +- Added a configure option to disable gcc. + +- Added a "raw" packet printer. + +- Not having an interface address is no longer fatal. Requested by John + Hawkinson. + +- Rework signal setup to accommodate Linux. + +- OSPF truncation check fix. Also display the type of OSPF packets + using MD5 authentication. Thanks to Brian Wellington + (bwelling@tis.com) + +- Fix truncation check bugs in the Kerberos printer. Reported by Ezra + Peisach (epeisach@mit.edu) + +- Don't catch SIGHUP when invoked with nohup(1). Thanks to Dave Plonka + (plonka@mfa.com) + +- Specify full install target as a way of detecting if install + directory does not exist. Thanks to Dave Plonka. + +- Bit-swap FDDI addresses for BSD/OS too. Thanks to Paul Vixie + (paul@vix.com) + +- Fix off-by-one bug when testing size of ethernet packets. Thanks to + Marty Leisner (leisner@sdsp.mc.xerox.com) + +- Add a local autoconf macro to check for routines in libraries; the + autoconf version is broken (it only puts the library name in the + cache variable name). Thanks to John Hawkinson. + +- Add a local autoconf macro to check for types; the autoconf version + is broken (it uses grep instead of actually compiling a code fragment). + +- Modified to support the new BSD/OS 2.1 PPP and SLIP link layer header + formats. + +- Extend OSF ip header workaround to versions 1 and 2. + +- Fix some signed problems in the nfs printer. As reported by David + Sacerdote (davids@silence.secnet.com) + +- Detect group wheel and use it as the default since BSD/OS' install + can't hack numeric groups. Reported by David Sacerdote. + +- AIX needs special loader options. Thanks to Jonathan I. Kamens + (jik@cam.ov.com) + +- Fixed the nfs printer to print port numbers in decimal. Thanks to + Kent Vander Velden (graphix@iastate.edu) + +- Find installed libpcap in /usr/local/lib when not using gcc. + +- Disallow network masks with non-network bits set. + +- Attempt to detect "egcs" versions of gcc. + +- Add missing closing double quotes when displaying bootp strings. + Reported by Viet-Trung Luu (vluu@picard.math.uwaterloo.ca) + +v3.3 Sat Nov 30 20:56:27 PST 1996 + +- Added Linux support. + +- GRE encapsulated packet printer thanks to John Hawkinson + (jhawk@mit.edu) + +- Rewrite gmt2local() to avoid problematic os dependencies. + +- Suppress nfs truncation message on errors. + +- Add missing m4 quoting in AC_LBL_UNALIGNED_ACCESS autoconf macro. + Reported by Joachim Ott (ott@ardala.han.de) + +- Enable "ip_hl vs. ip_vhl" workaround for OSF4 too. + +- Print arp hardware type in host order. Thanks to Onno van der Linden + (onno@simplex.nl) + +- Avoid solaris compiler warnings. Thanks to Bruce Barnett + (barnett@grymoire.crd.ge.com) + +- Fix rip printer to not print one more route than is actually in the + packet. Thanks to Jean-Luc Richier (Jean-Luc.Richier@imag.fr) and + Bill Fenner (fenner@parc.xerox.com) + +- Use autoconf endian detection since BYTE_ORDER isn't defined on all systems. + +- Fix dvmrp printer truncation checks and add a dvmrp probe printer. + Thanks to Danny J. Mitzel (mitzel@ipsilon.com) + +- Rewrite ospf printer to improve truncation checks. + +- Don't parse tcp options past the EOL. As noted by David Sacerdote + (davids@secnet.com). Also, check tcp options to make sure they ar + actually in the tcp header (in addition to the normal truncation + checks). Fix the SACK code to print the N blocks (instead of the + first block N times). + +- Don't say really small UDP packets are truncated just because they + aren't big enough to be a RPC. As noted by David Sacerdote. + +v3.2.1 Sun Jul 14 03:02:26 PDT 1996 + +- Added rfc1716 icmp codes as suggested by Martin Fredriksson + (martin@msp.se) + +- Print mtu for icmp unreach need frag packets. Thanks to John + Hawkinson (jhawk@mit.edu) + +- Decode icmp router discovery messages. Thanks to Jeffrey Honig + (jch@bsdi.com) + +- Added a printer entry for DLT_IEEE802 as suggested by Tak Kushida + (kushida@trl.ibm.co.jp) + +- Check igmp checksum if possible. Thanks to John Hawkinson. + +- Made changes for SINIX. Thanks to Andrej Borsenkow + (borsenkow.msk@sni.de) + +- Use autoconf's idea of the top level directory in install targets. + Thanks to John Hawkinson. + +- Avoid infinite loop in tcp options printing code. Thanks to Jeffrey + Mogul (mogul@pa.dec.com) + +- Avoid using -lsocket in IRIX 5.2 and earlier since it breaks snoop. + Thanks to John Hawkinson. + +- Added some more packet truncation checks. + +- On systems that have it, use sigset() instead of signal() since + signal() has different semantics on these systems. + +- Fixed some more alignment problems on the alpha. + +- Add code to massage unprintable characters in the domain and ipx + printers. Thanks to John Hawkinson. + +- Added explicit netmask support. Thanks to Steve Nuchia + (steve@research.oknet.com) + +- Add "sca" keyword (for DEC cluster services) as suggested by Terry + Kennedy (terry@spcvxa.spc.edu) + +- Add "atalk" keyword as suggested by John Hawkinson. + +- Added an igrp printer. Thanks to Francis Dupont + (francis.dupont@inria.fr) + +- Print IPX net numbers in hex a la Novell Netware. Thanks to Terry + Kennedy (terry@spcvxa.spc.edu) + +- Fixed snmp extended tag field parsing bug. Thanks to Pascal Hennequin + (pascal.hennequin@hugo.int-evry.fr) + +- Added some ETHERTYPEs missing on some systems. + +- Added truncated packet macros and various checks. + +- Fixed endian problems with the DECnet printer. + +- Use $CC when checking gcc version. Thanks to Carl Lindberg + (carl_lindberg@blacksmith.com) + +- Fixes for AIX (although this system is not yet supported). Thanks to + John Hawkinson. + +- Fix bugs in the autoconf misaligned accesses code fragment. + +- Include sys/param.h to get BYTE_ORDER in a few places. Thanks to + Pavlin Ivanov Radoslavov (pavlin@cs.titech.ac.jp) + +v3.2 Sun Jun 23 02:28:10 PDT 1996 + +- Print new icmp unreachable codes as suggested by Martin Fredriksson + (martin@msp.se). Also print code value when unknown for icmp redirect + and time exceeded. + +- Fix an alignment endian bug in getname(). Thanks to John Hawkinson. + +- Define "new" domain record types if not found in arpa/nameserv.h. + Resulted from a suggestion from John Hawkinson (jhawk@mit.edu). Also + fixed an endian bug when printing mx record and added some new record + types. + +- Added RIP V2 support. Thanks to Jeffrey Honig (jch@bsdi.com) + +- Added T/TCP options printing. As suggested by Richard Stevens + (rstevens@noao.edu) + +- Use autoconf to detect architectures that can't handle misaligned + accesses. + +v3.1 Thu Jun 13 20:59:32 PDT 1996 + +- Changed u_int32/int32 to u_int32_t/int32_t to be consistent with bsd + and bind (as suggested by Charles Hannum). + +- Port to GNU autoconf. + +- Add support for printing DVMRP and PIM traffic thanks to + Havard Eidnes (Havard.Eidnes@runit.sintef.no). + +- Fix AppleTalk, IPX and DECnet byte order problems due to wrong endian + define being referenced. Reported by Terry Kennedy. + +- Minor fixes to the man page thanks to Mark Andrews. + +- Endian fixes to RTP and vat packet dumpers, thanks to Bruce Mah + (bmah@cs.berkeley.edu). + +- Added support for new dns types, thanks to Rainer Orth. + +- Fixed tftp_print() to print the block number for ACKs. + +- Document -dd and -ddd. Resulted from a bug report from Charlie Slater + (cslater@imatek.com). + +- Check return status from malloc/calloc/etc. + +- Check return status from pcap_loop() so we can print an error and + exit with a bad status if there were problems. + +- Bail if ip option length is <= 0. Resulted from a bug report from + Darren Reed (darrenr@vitruvius.arbld.unimelb.edu.au). + +- Print out a little more information for sun rpc packets. + +- Add suport for Kerberos 4 thanks to John Hawkinson (jhawk@mit.edu). + +- Fixed the Fix EXTRACT_SHORT() and EXTRACT_LONG() macros (which were + wrong on little endian machines). + +- Fixed alignment bug in ipx_decode(). Thanks to Matt Crawford + (crawdad@fnal.gov). + +- Fix ntp_print() to not print garbage when the stratum is + "unspecified." Thanks to Deus Ex Machina (root@belle.bork.com). + +- Rewrote tcp options printer code to check for truncation. Added + selective acknowledgment case. + +- Fixed an endian bug in the ospf printer. Thanks to Jeffrey C Honig + (jch@bsdi.com) + +- Fix rip printer to handle 4.4 BSD sockaddr struct which only uses one + octet for the sa_family member. Thanks to Yoshitaka Tokugawa + (toku@dit.co.jp) + +- Don't checksum ip header if we don't have all of it. Thanks to John + Hawkinson (jhawk@mit.edu). + +- Print out hostnames if possible in egp printer. Thanks to Jeffrey + Honig (jhc@bsdi.com) + + +v3.1a1 Wed May 3 19:21:11 PDT 1995 + +- Include time.h when SVR4 is defined to avoid problems under Solaris + 2.3. + +- Fix etheraddr_string() in the ETHER_SERVICE to return the saved + strings, not the local buffer. Thanks to Stefan Petri + (petri@ibr.cs.tu-bs.de). + +- Detect when pcap raises the snaplen (e.g. with snit). Print a warning + that the selected value was not used. Thanks to Pascal Hennequin + (Pascal.Hennequin@hugo.int-evry.fr). + +- Add a truncated packet test to print-nfs.c. Thanks to Pascal Hennequin. + +- BYTEORDER -> BYTE_ORDER Thanks to Terry Kennedy (terry@spcvxa.spc.edu). + +v3.0.3 Sun Oct 1 18:35:00 GMT 1995 + +- Although there never was a 3.0.3 release, the linux boys cleverly + "released" one in late 1995. + +v3.0.2 Thu Apr 20 21:28:16 PDT 1995 + +- Change configuration to not use gcc v2 flags with gcc v1. + +- Redo gmt2local() so that it works under BSDI (which seems to return + an empty timezone struct from gettimeofday()). Based on report from + Terry Kennedy (terry@spcvxa.spc.edu). + +- Change configure to recognize IP[0-9]* as "mips" SGI hardware. Based + on report from Mark Andrews (mandrews@alias.com). + +- Don't pass cc flags to gcc. Resulted from a bug report from Rainer + Orth (ro@techfak.uni-bielefeld.de). + +- Fixed printout of connection id for uncompressed tcp slip packets. + Resulted from a bug report from Richard Stevens (rstevens@noao.edu). + +- Hack around deficiency in Ultrix's make. + +- Add ETHERTYPE_TRAIL define which is missing from irix5. + +v3.0.1 Wed Aug 31 22:42:26 PDT 1994 + +- Fix problems with gcc2 vs. malloc() and read() prototypes under SunOS 4. + +v3.0 Mon Jun 20 19:23:27 PDT 1994 + +- Added support for printing tcp option timestamps thanks to + Mark Andrews (mandrews@alias.com). + +- Reorganize protocol dumpers to take const pointers to packets so they + never change the contents (i.e., they used to do endian conversions + in place). Previously, whenever more than one pass was taken over + the packet, the packet contents would be dumped incorrectly (i.e., + the output form -x would be wrong on little endian machines because + the protocol dumpers would modify the data). Thanks to Charles Hannum + (mycroft@gnu.ai.mit.edu) for reporting this problem. + +- Added support for decnet protocol dumping thanks to Jeff Mogul + (mogul@pa.dec.com). + +- Fix bug that caused length of packet to be incorrectly printed + (off by ether header size) for unknown ethernet types thanks + to Greg Miller (gmiller@kayak.mitre.org). + +- Added support for IPX protocol dumping thanks to Brad Parker + (brad@fcr.com). + +- Added check to verify IP header checksum under -v thanks to + Brad Parker (brad@fcr.com). + +- Move packet capture code to new libpcap library (which is + packaged separately). + +- Prototype everything and assume an ansi compiler. + +- print-arp.c: Print hardware ethernet addresses if they're not + what we expect. + +- print-bootp.c: Decode the cmu vendor field. Add RFC1497 tags. + Many helpful suggestions from Gordon Ross (gwr@jericho.mc.com). + +- print-fddi.c: Improvements. Thanks to Jeffrey Mogul + (mogul@pa.dec.com). + +- print-icmp.c: Byte swap netmask before printing. Thanks to + Richard Stevens (rstevens@noao.edu). Print icmp type when unknown. + +- print-ip.c: Print the inner ip datagram of ip-in-ip encapsulated packets. + By default, only the inner packet is dumped, appended with the token + "(encap)". Under -v, both the inner and output packets are dumped + (on the same line). Note that the filter applies to the original packet, + not the encapsulated packet. So if you run tcpdump on a net with an + IP Multicast tunnel, you cannot filter out the datagrams using the + conventional syntax. (You can filter away all the ip-in-ip traffic + with "not ip proto 4".) + +- print-nfs.c: Keep pending rpc's in circular table. Add generic + nfs header and remove os dependences. Thanks to Jeffrey Mogul. + +- print-ospf.c: Improvements. Thanks to Jeffrey Mogul. + +- tcpdump.c: Add -T flag allows interpretation of "vat", "wb", "rpc" + (sunrpc) and rtp packets. Added "inbound" and "outbound" keywords + Add && and || operators + +v2.2.1 Tue Jun 6 17:57:22 PDT 1992 + +- Fix bug with -c flag. + +v2.2 Fri May 22 17:19:41 PDT 1992 + +- savefile.c: Remove hack that shouldn't have been exported. Add + truncate checks. + +- Added the 'icmp' keyword. For example, 'icmp[0] != 8 and icmp[0] != 0' + matches non-echo/reply ICMP packets. + +- Many improvements to filter code optimizer. + +- Added 'multicast' keyword and extended the 'broadcast' keyword can now be + so that protocol qualifications are allowed. For example, "ip broadcast" + and "ether multicast" are valid filters. + +- Added support for monitoring the loopback interface (i.e. 'tcpdump -i lo'). + Jeffrey Honig (jch@MITCHELL.CIT.CORNELL.EDU) contributed the kernel + patches to netinet/if_loop.c. + +- Added support for the Ungermann-Bass Ethernet on IBM/PC-RTs running AOS. + Contact Jeffrey Honig (jch@MITCHELL.CIT.CORNELL.EDU) for the diffs. + +- Added EGP and OSPF printers, thanks to Jeffrey Honig. + +v2.1 Tue Jan 28 11:00:14 PST 1992 + +- Internal release (never publically exported). + +v2.0.1 Sun Jan 26 21:10:10 PDT + +- Various byte ordering fixes. + +- Add truncation checks. + +- inet.c: Support BSD style SIOCGIFCONF. + +- nametoaddr.c: Handle multi addresses for single host. + +- optimize.c: Rewritten. + +- pcap-bpf.c: don't choke when we get ptraced. only set promiscuous + for broadcast nets. + +- print-atal.c: Fix an alignment bug (thanks to + stanonik@nprdc.navy.mil) Add missing printf() argument. + +- print-bootp.c: First attempt at decoding the vendor buffer. + +- print-domain.c: Fix truncation checks. + +- print-icmp.c: Calculate length of packets from the ip header. + +- print-ip.c: Print frag id in decimal (so it's easier to match up + with non-frags). Add support for ospf, egp and igmp. + +- print-nfs.c: Lots of changes. + +- print-ntp.c: Make some verbose output depend on -v. + +- print-snmp.c: New version from John LoVerso. + +- print-tcp.c: Print rfc1072 tcp options. + +- tcpdump.c: Print "0x" prefix for %x formats. Always print 6 digits + (microseconds) worth of precision. Fix uid bugs. + +- A packet dumper has been added (thanks to Jeff Mogul of DECWRL). + With this option, you can create an architecture independent binary + trace file in real time, without the overhead of the packet printer. + At a later time, the packets can be filtered (again) and printed. + +- BSD is supported. You must have BPF in your kernel. + Since the filtering is now done in the kernel, fewer packets are + dropped. In fact, with BPF and the packet dumper option, a measly + Sun 3/50 can keep up with a busy network. + +- Compressed SLIP packets can now be dumped, provided you use our + SLIP software and BPF. These packets are dumped as any other IP + packet; the compressed headers are dumped with the '-e' option. + +- Machines with little-endian byte ordering are supported (thanks to + Jeff Mogul). + +- Ultrix 4.0 is supported (also thanks to Jeff Mogul). + +- IBM RT and Stanford Enetfilter support has been added by + Rayan Zachariassen . Tcpdump has been tested under + both the vanilla Enetfilter interface, and the extended interface + (#ifdef'd by IBMRTPC) present in the MERIT version of the Enetfilter. + +- TFTP packets are now printed (requests only). + +- BOOTP packets are now printed. + +- SNMP packets are now printed. (thanks to John LoVerso of Xylogics). + +- Sparc architectures, including the Sparcstation-1, are now + supported thanks to Steve McCanne and Craig Leres. + +- SunOS 4 is now supported thanks to Micky Liu of Columbia + University (micky@cunixc.cc.columbia.edu). + +- IP options are now printed. + +- RIP packets are now printed. + +- There's a -v flag that prints out more information than the + default (e.g., it will enable printing of IP ttl, tos and id) + and -q flag that prints out less (e.g., it will disable + interpretation of AppleTalk-in-UDP). + +- The grammar has undergone substantial changes (if you have an + earlier version of tcpdump, you should re-read the manual + entry). + + The most useful change is the addition of an expression + syntax that lets you filter on arbitrary fields or values in the + packet. E.g., "ip[0] > 0x45" would print only packets with IP + options, "tcp[13] & 3 != 0" would print only TCP SYN and FIN + packets. + + The most painful change is that concatenation no longer means + "and" -- e.g., you have to say "host foo and port bar" instead + of "host foo port bar". The up side to this down is that + repeated qualifiers can be omitted, making most filter + expressions shorter. E.g., you can now say "ip host foo and + (bar or baz)" to look at ip traffic between hosts foo and bar or + between hosts foo and baz. [The old way of saying this was "ip + host foo and (ip host bar or ip host baz)".] + +v2.0 Sun Jan 13 12:20:40 PST 1991 + +- Initial public release. diff --git a/CREDITS b/CREDITS new file mode 100644 index 0000000..0a3b56e --- /dev/null +++ b/CREDITS @@ -0,0 +1,189 @@ +This file lists people who have contributed to tcpdump: + +The current maintainers: + Bill Fenner + David Young + Fulvio Risso + Guy Harris + Hannes Gredler + Michael Richardson + +Additional people who have contributed patches: + + Aaron Campbell + Alfredo Andres + Albert Chin + Ananth Suryanarayana + Andrea Bittau + Andrew Brown + Andrew Church + Andrew Hintz + Andrew Silent + Andrew Tridgell + Andy Heffernan + Arkadiusz Miskiewicz + Armando L. Caro Jr. + Arnaldo Carvalho de Melo + Ben Byer + Atsushi Onoe + Ben Smithurst + Bert Vermeulen + Bjoern A. Zeeb + Brent L. Bates + Brian Ginsbach + Bruce M. Simpson + Carles Kishimoto Bisbe + Charlie Lenahan + Charles M. Hannum + Chris Cogdon + Chris G. Demetriou + Christian Sievers + Chris Jepeway + Chris Larson + Craig Rodrigues + Crist J. Clark + Daniel Hagerty + Darren Reed + David Binderman + David Horn + David Smith + David Young + Don Ebright + Eddie Kohler + Elmar Kirchner + Fang Wang + Florent Drouin + Florian Forster + Francis Dupont + Francisco Matias Cuenca-Acuna + Francois-Xavier Le Bail + Frank Volf + Fulvio Risso + George Bakos + Gerald Combs + Gerrit Renker + Gert Doering + Greg Minshall + Greg Stark + Gilbert Ramirez Jr. + Gisle Vanem + Hannes Viertel + Hank Leininger + Harry Raaymakers + Heinz-Ado Arnolds + Hendrik Scholz + Ian McDonald + Ilpo Järvinen + Jacek Tobiasz + Jakob Schlyter + Jamal Hadi Salim + Jan Oravec + Jason R. Thorpe + Jefferson Ogata + Jeffrey Hutzelman + Jesper Peterson + Jim Hutchins + Jonathan Heusser + Tatuya Jinmei + João Medeiros + Joerg Mayer + Jørgen Thomsen + Julian Cowley + Kaarthik Sivakumar + Karl Norby + Kazushi Sugyo + Kelly Carmichael + Ken Hornstein + Kevin Steves + Klaus Klein + Kris Kennaway + Krzysztof Halasa + Larry Lile + Lennert Buytenhek + Loris Degioanni + Love Hörnquist-Åstrand + Lucas C. Villa Real + Luis Martin Garcia + Maciej W. Rozycki + Manu Pathak + Marc Binderberger + Marc A. Lehmann + Mark Ellzey Thomas + Marko Kiiskila + Markus Schöpflin + Marshall Rose + Martin Husemann + Max Laier + Michael A. Meffie III + Michael Madore + Michael Riepe + Michael Shalayeff + Michael Shields + Michael T. Stolarchuk + Michele "mydecay" Marchetto + Mike Frysinger + Monroe Williams + Motonori Shindo + Nathan J. Williams + Nathaniel Couper-Noles + Neil T. Spring + Niels Provos + Nickolai Zeldovich + Nicolas Ferrero + Noritoshi Demizu + Olaf Kirch + Onno van der Linden + Paolo Abeni + Pascal Hennequin + Pasvorn Boonmark + Paul Mundt + Paul S. Traina + Pavlin Radoslavov + Pekka Savola + Peter Fales + Peter Jeremy + + Peter Volkov + Phil Wood + Rafal Maszkowski + Randy Sofia + Raphael Raimbault + Rick Cheng + Rick Jones + Rick Watson + Rob Braun + Robert Edmonds + Roderick Schertler + Sagun Shakya + Sami Farin + Scott Rose + Sebastian Krahmer + Sebastien Raveau + Sebastien Vincent + Sepherosa Ziehau + Seth Webster + Shinsuke Suzuki + Steinar Haug + Swaminathan Chandrasekaran + Takashi Yamamoto + Terry Kennedy + Timo Koskiahde + Tony Li + Toshihiro Kanda + Uns Lider + Victor Oppleman + Wesley Griffin + Wesley Shields + Wilbert de Graaf + Will Drewry + William J. Hulley + Yen Yen Lim + Yoshifumi Nishida + +The original LBL crew: + Steve McCanne + Craig Leres + Van Jacobson + +Past maintainers: + Jun-ichiro itojun Hagino diff --git a/INSTALL.txt b/INSTALL.txt new file mode 100644 index 0000000..a03e2c0 --- /dev/null +++ b/INSTALL.txt @@ -0,0 +1,255 @@ +@(#) $Header: /tcpdump/master/tcpdump/INSTALL.txt,v 1.2 2008-02-06 10:47:53 guy Exp $ (LBL) + +If you have not built libpcap, and your system does not have libpcap +installed, install libpcap first. Your system might provide a version +of libpcap that can be installed; if so, to compile tcpdump you might +need to install a "developer" version of libpcap as well as the +"run-time" version. You can also install tcpdump.org's version of +libpcap; see the README file in this directory for the ftp location. + +You will need an ANSI C compiler to build tcpdump. The configure script +will abort if your compiler is not ANSI compliant. If this happens, use +the GNU C compiler, available via anonymous ftp: + + ftp://ftp.gnu.org/pub/gnu/gcc/ + +After libpcap has been built (either install it with "make install" or +make sure both the libpcap and tcpdump source trees are in the same +directory), run ./configure (a shell script). "configure" will +determine your system attributes and generate an appropriate Makefile +from Makefile.in. Now build tcpdump by running "make". + +If everything builds ok, su and type "make install". This will install +tcpdump and the manual entry. Any user will be able to use tcpdump to +read saved captures. Whether a user will be able to capture traffic +depends on the OS and the configuration of the system; see the tcpdump +man page for details. DO NOT give untrusted users the ability to +capture traffic. If a user can capture traffic, he or she could use +utilities such as tcpdump to capture any traffic on your net, including +passwords. + +Note that most systems ship tcpdump, but usually an older version. +Remember to remove or rename the installed binary when upgrading. + +If your system is not one which we have tested tcpdump on, you may have +to modify the configure script and Makefile.in. Please send us patches +for any modifications you need to make. + +Please see "PLATFORMS" for notes about tested platforms. + + +FILES +----- +CHANGES - description of differences between releases +CREDITS - people that have helped tcpdump along +FILES - list of files exported as part of the distribution +INSTALL.txt - this file +LICENSE - the license under which tcpdump is distributed +Makefile.in - compilation rules (input to the configure script) +README - description of distribution +Readme.Win32 - notes on building tcpdump on Win32 systems (with WinPcap) +VERSION - version of this release +acconfig.h - autoconf input +aclocal.m4 - autoconf macros +addrtoname.c - address to hostname routines +addrtoname.h - address to hostname definitions +ah.h - IPSEC Authentication Header definitions +aodv.h - AODV definitions +appletalk.h - AppleTalk definitions +arcnet.h - ARCNET definitions +atime.awk - TCP ack awk script +atm.h - ATM traffic type definitions +atmuni31.h - ATM Q.2931 definitions +bgp.h - BGP declarations +bootp.h - BOOTP definitions +bpf_dump.c - BPF program printing routines, in case libpcap doesn't + have them +chdlc.h - Cisco HDLC definitions +cpack.c - functions to extract packed data +cpack.h - declarations of functions to extract packed data +config.guess - autoconf support +config.h.in - autoconf input +config.sub - autoconf support +configure - configure script (run this first) +configure.in - configure script source +dccp.h - DCCP definitions +decnet.h - DECnet definitions +decode_prefix.h - Declarations of "decode_prefix{4,6}()" +enc.h - OpenBSD IPsec encapsulation BPF layer definitions +esp.h - IPSEC Encapsulating Security Payload definitions +ether.h - Ethernet definitions +ethertype.h - Ethernet type value definitions +extract.h - alignment definitions +fddi.h - Fiber Distributed Data Interface definitions +gmpls.c - GMPLS definitions +gmpls.h - GMPLS declarations +gmt2local.c - time conversion routines +gmt2local.h - time conversion prototypes +icmp6.h - ICMPv6 definitiions +ieee802_11.h - IEEE 802.11 definitions +ieee802_11_radio.h - radiotap header definitions +igrp.h - Interior Gateway Routing Protocol definitions +install-sh - BSD style install script +interface.h - globals, prototypes and definitions +ip.h - IP definitions +ip6.h - IPv6 definitions +ipfc.h - IP-over-Fibre Channel definitions +ipproto.c - IP protocol type value-to-name table +ipproto.h - IP protocol type value definitions +ipsec_doi.h - ISAKMP packet definitions - RFC2407 +ipx.h - IPX definitions +isakmp.h - ISAKMP packet definitions - RFC2408 +l2vpn.c - L2VPN encapsulation value-to-name table +l2vpn.h - L2VPN encapsulation definitions +l2tp.h - Layer Two Tunneling Protocol definitions +lane.h - ATM LANE definitions +lbl/os-*.h - OS-dependent defines and prototypes +llc.h - LLC definitions +machdep.c - machine dependent routines +machdep.h - machine dependent definitions +makemib - mib to header script +mib.h - mib definitions +missing/* - replacements for missing library functions +mkdep - construct Makefile dependency list +mpls.h - MPLS definitions +nameser.h - DNS definitions +netbios.h - NETBIOS definitions +netdissect.h - definitions and declarations for tcpdump-as-library + (under development) +nfs.h - Network File System V2 definitions +nfsfh.h - Network File System file handle definitions +nlpid.c - OSI NLPID value-to-name table +nlpid.h - OSI NLPID definitions +ntp.h - Network Time Protocol definitions +oakley.h - ISAKMP packet definitions - RFC2409 +ospf.h - Open Shortest Path First definitions +ospf6.h - IPv6 Open Shortest Path First definitions +packetdat.awk - TCP chunk summary awk script +parsenfsfh.c - Network File System file parser routines +pcap_dump_ftell.c - pcap_dump_ftell() implementation, in case libpcap + doesn't have it +pcap-missing.h - declarations of functions possibly missing from libpcap +pmap_prot.h - definitions for ONC RPC portmapper protocol +ppp.h - Point to Point Protocol definitions +print-802_11.c - IEEE 802.11 printer routines +print-ap1394.c - Apple IP-over-IEEE 1394 printer routines +print-ah.c - IPSEC Authentication Header printer routines +print-aodv.c - AODV printer routines +print-arcnet.c - ARCNET printer routines +print-arp.c - Address Resolution Protocol printer routines +print-ascii.c - ASCII packet dump routines +print-atalk.c - AppleTalk printer routines +print-atm.c - ATM printer routines +print-beep.c - BEEP printer routines +print-bgp.c - Border Gateway Protocol printer routines +print-bootp.c - BOOTP and IPv4 DHCP printer routines +print-bt.c - Bluetooth printer routines +print-cdp.c - Cisco Discovery Protocol printer routines +print-chdlc.c - Cisco HDLC printer routines +print-cip.c - Classical-IP over ATM routines +print-cnfp.c - Cisco NetFlow printer routines +print-dccp.c - DCCP printer routines +print-decnet.c - DECnet printer routines +print-dhcp6.c - IPv6 DHCP printer routines +print-domain.c - Domain Name System printer routines +print-dvmrp.c - Distance Vector Multicast Routing Protocol printer routines +print-eap.c - EAP printer routines +print-enc.c - OpenBSD IPsec encapsulation BPF layer printer routines +print-egp.c - External Gateway Protocol printer routines +print-esp.c - IPSEC Encapsulating Security Payload printer routines +print-ether.c - Ethernet printer routines +print-fddi.c - Fiber Distributed Data Interface printer routines +print-fr.c - Frame Relay printer routines +print-frag6.c - IPv6 fragmentation header printer routines +print-gre.c - Generic Routing Encapsulation printer routines +print-hsrp.c - Cisco Hot Standby Router Protocol printer routines +print-icmp.c - Internet Control Message Protocol printer routines +print-icmp6.c - IPv6 Internet Control Message Protocol printer routines +print-igmp.c - Internet Group Management Protocol printer routines +print-igrp.c - Interior Gateway Routing Protocol printer routines +print-ip.c - IP printer routines +print-ip6.c - IPv6 printer routines +print-ip6opts.c - IPv6 header option printer routines +print-ipcomp.c - IP Payload Compression Protocol printer routines +print-ipx.c - IPX printer routines +print-isakmp.c - Internet Security Association and Key Management Protocol +print-isoclns.c - ISO CLNS, ESIS, and ISIS printer routines +print-krb.c - Kerberos printer routines +print-l2tp.c - Layer Two Tunneling Protocol printer routines +print-lane.c - ATM LANE printer routines +print-llc.c - IEEE 802.2 LLC printer routines +print-lspping.c - LSPPING printer routines +print-lwres.c - Lightweight Resolver protocol printer routines +print-mobile.c - IPv4 mobility printer routines +print-mobility.c - IPv6 mobility printer routines +print-mpls.c - Multi-Protocol Label Switching printer routines +print-msdp.c - Multicast Source Discovery Protocol printer routines +print-netbios.c - NetBIOS frame protocol printer routines +print-nfs.c - Network File System printer routines +print-ntp.c - Network Time Protocol printer routines +print-null.c - BSD loopback device printer routines +print-ospf.c - Open Shortest Path First printer routines +print-ospf6.c - IPv6 Open Shortest Path First printer routines +print-pflog.c - OpenBSD packet filter log file printer routines +print-pgm.c - Pragmatic General Multicast printer routines +print-pim.c - Protocol Independent Multicast printer routines +print-ppp.c - Point to Point Protocol printer routines +print-pppoe.c - PPP-over-Ethernet printer routines +print-pptp.c - Point-to-Point Tunnelling Protocol printer routines +print-radius.c - Radius protocol printer routines +print-raw.c - Raw IP printer routines +print-rip.c - Routing Information Protocol printer routines +print-ripng.c - IPv6 Routing Information Protocol printer routines +print-rrcp.c - Realtek Remote Control Protocol routines +print-rsvp.c - Resource reSerVation Protocol (RSVP) printer routines +print-rt6.c - IPv6 routing header printer routines +print-rx.c - AFS RX printer routines +print-sctp.c - Stream Control Transmission Protocol printer routines +print-sip.c - SIP printer routines +print-sl.c - Compressed Serial Line Internet Protocol printer routines +print-sll.c - Linux "cooked" capture printer routines +print-slow.c - IEEE "slow protocol" (802.3ad) printer routines +print-smb.c - SMB/CIFS printer routines +print-snmp.c - Simple Network Management Protocol printer routines +print-stp.c - IEEE 802.1d spanning tree protocol printer routines +print-sunatm.c - SunATM DLPI capture printer routines +print-sunrpc.c - Sun Remote Procedure Call printer routines +print-symantec.c - Symantec Enterprise Firewall printer routines +print-tcp.c - TCP printer routines +print-telnet.c - Telnet option printer routines +print-tftp.c - Trivial File Transfer Protocol printer routines +print-timed.c - BSD time daemon protocol printer routines +print-token.c - Token Ring printer routines +print-udp.c - UDP printer routines +print-usb.c - USB printer routines +print-vjc.c - PPP Van Jacobson compression (RFC1144) printer routines +print-vrrp.c - Virtual Router Redundancy Protocol +print-wb.c - White Board printer routines +print-zephyr.c - Zephyr printer routines +route6d.h - packet definition for IPv6 Routing Information Protocol +rpc_auth.h - definitions for ONC RPC authentication +rpc_msg.h - definitions for ONC RPC messages +rx.h - AFS RX definitions +sctpConstants.h - Stream Control Transmission Protocol constant definitions +sctpHeader.h - Stream Control Transmission Protocol packet definitions +send-ack.awk - unidirectional tcp send/ack awk script +setsignal.c - OS-independent signal routines +setsignal.h - OS-independent signal prototypes +slcompress.h - SLIP/PPP Van Jacobson compression (RFC1144) definitions +slip.h - SLIP definitions +sll.h - Linux "cooked" capture definitions +smb.h - SMB/CIFS definitions +smbutil.c - SMB/CIFS utility routines +stime.awk - TCP send awk script +strcasecmp.c - missing routine +tcp.h - TCP definitions +tcpdump.1 - manual entry +tcpdump.c - main program +telnet.h - Telnet definitions +tftp.h - TFTP definitions +timed.h - BSD time daemon protocol definitions +token.h - Token Ring definitions +udp.h - UDP definitions +util.c - utility routines +vfprintf.c - emulation routine +win32 - headers and routines for building on Win32 systems diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..dea5f7d --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +License: BSD + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. diff --git a/Makefile-devel-adds b/Makefile-devel-adds new file mode 100644 index 0000000..512a119 --- /dev/null +++ b/Makefile-devel-adds @@ -0,0 +1,22 @@ +# +# Auto-regenerate configure script or Makefile when things change. +# From autoconf.info . Works best with GNU Make. +# +${srcdir}/configure: configure.in + cd ${srcdir} && autoconf + +# autoheader might not change config.h.in, so touch a stamp file. +${srcdir}/config.h.in: ${srcdir}/stamp-h.in +${srcdir}/stamp-h.in: configure.in acconfig.h + cd ${srcdir} && autoheader + echo timestamp > ${srcdir}/stamp-h.in + +config.h: stamp-h +stamp-h: ${srcdir}/config.h.in config.status + ./config.status + +Makefile: Makefile.in config.status + ./config.status + +config.status: ${srcdir}/configure + ./config.status --recheck diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..8e7b73b --- /dev/null +++ b/Makefile.in @@ -0,0 +1,445 @@ +# Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that: (1) source code distributions +# retain the above copyright notice and this paragraph in its entirety, (2) +# distributions including binary code include the above copyright notice and +# this paragraph in its entirety in the documentation or other materials +# provided with the distribution, and (3) all advertising materials mentioning +# features or use of this software display the following acknowledgement: +# ``This product includes software developed by the University of California, +# Lawrence Berkeley Laboratory and its contributors.'' Neither the name of +# the University nor the names of its contributors may be used to endorse +# or promote products derived from this software without specific prior +# written permission. +# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +# +# @(#) $Header: /tcpdump/master/tcpdump/Makefile.in,v 1.325 2008-11-21 23:17:26 guy Exp $ (LBL) + +# +# Various configurable paths (remember to edit Makefile.in, not Makefile) +# + +# Top level hierarchy +prefix = @prefix@ +exec_prefix = @exec_prefix@ +# Pathname of directory to install the binary +sbindir = @sbindir@ +# Pathname of directory to install the man page +mandir = @mandir@ + +# VPATH +srcdir = @srcdir@ +VPATH = @srcdir@ + +# +# You shouldn't need to edit anything below here. +# + +CC = @CC@ +PROG = tcpdump +CCOPT = @V_CCOPT@ +INCLS = -I. @V_INCLS@ +DEFS = @DEFS@ @CPPFLAGS@ @V_DEFS@ + +# Standard CFLAGS +CFLAGS = $(CCOPT) $(DEFS) $(INCLS) + +# Standard LDFLAGS +LDFLAGS = @LDFLAGS@ + +# Standard LIBS +LIBS = @LIBS@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +RANLIB = @RANLIB@ + +# Explicitly define compilation rule since SunOS 4's make doesn't like gcc. +# Also, gcc does not remove the .o before forking 'as', which can be a +# problem if you don't own the file but can write to the directory. +.c.o: + @rm -f $@ + $(CC) $(CFLAGS) -c $(srcdir)/$*.c + +CSRC = addrtoname.c af.c checksum.c cpack.c gmpls.c oui.c gmt2local.c ipproto.c \ + nlpid.c l2vpn.c machdep.c parsenfsfh.c \ + print-802_11.c print-ap1394.c print-ah.c print-arcnet.c \ + print-aodv.c print-arp.c print-ascii.c print-atalk.c print-atm.c \ + print-beep.c print-bfd.c print-bgp.c print-bootp.c print-bt.c \ + print-cdp.c print-cfm.c print-chdlc.c print-cip.c print-cnfp.c \ + print-dccp.c print-decnet.c \ + print-domain.c print-dtp.c print-dvmrp.c print-enc.c print-egp.c \ + print-eap.c print-eigrp.c\ + print-esp.c print-ether.c print-fddi.c print-fr.c \ + print-gre.c print-hsrp.c print-icmp.c print-igmp.c \ + print-igrp.c print-ip.c print-ipcomp.c print-ipfc.c print-ipnet.c \ + print-ipx.c print-isoclns.c print-juniper.c print-krb.c \ + print-l2tp.c print-lane.c print-ldp.c print-lldp.c print-llc.c \ + print-lmp.c print-lspping.c print-lwapp.c \ + print-lwres.c print-mobile.c print-mpcp.c print-mpls.c print-msdp.c \ + print-nfs.c print-ntp.c print-null.c print-olsr.c print-ospf.c \ + print-pgm.c print-pim.c print-ppp.c print-pppoe.c print-pptp.c \ + print-radius.c print-raw.c print-rip.c print-rrcp.c print-rsvp.c \ + print-rx.c print-sctp.c print-sflow.c print-sip.c print-sl.c print-sll.c \ + print-slow.c print-snmp.c print-stp.c print-sunatm.c print-sunrpc.c \ + print-symantec.c print-syslog.c print-tcp.c print-telnet.c print-tftp.c \ + print-timed.c print-token.c print-udld.c print-udp.c print-usb.c \ + print-vjc.c print-vqp.c print-vrrp.c print-vtp.c print-forces.c \ + print-wb.c print-zephyr.c signature.c setsignal.c tcpdump.c util.c + +LIBNETDISSECT_SRC=print-isakmp.c +LIBNETDISSECT_OBJ=$(LIBNETDISSECT_SRC:.c=.o) +LIBNETDISSECT=libnetdissect.a + +LOCALSRC = @LOCALSRC@ +GENSRC = version.c +LIBOBJS = @LIBOBJS@ + +SRC = $(CSRC) $(GENSRC) $(LOCALSRC) $(LIBNETDISSECT_SRC) + +# We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot +# hack the extra indirection +OBJ = $(CSRC:.c=.o) $(GENSRC:.c=.o) $(LOCALSRC:.c=.o) $(LIBOBJS) $(LIBNETDISSECT_OBJ) +HDR = \ + acconfig.h \ + addrtoname.h \ + af.h \ + ah.h \ + aodv.h \ + appletalk.h \ + arcnet.h \ + atm.h \ + atmuni31.h \ + bootp.h \ + bgp.h \ + chdlc.h \ + cpack.h \ + dccp.h \ + decnet.h \ + decode_prefix.h \ + enc.h \ + esp.h \ + ether.h \ + ethertype.h \ + extract.h \ + fddi.h \ + forces.h \ + gmpls.h \ + gmt2local.h \ + icmp6.h \ + ieee802_11.h \ + ieee802_11_radio.h \ + igrp.h \ + interface.h \ + interface.h \ + ip.h \ + ip6.h \ + ipfc.h \ + ipnet.h \ + ipproto.h \ + ipsec_doi.h \ + ipx.h \ + isakmp.h \ + l2tp.h \ + l2vpn.h \ + lane.h \ + llc.h \ + machdep.h \ + mib.h \ + mpls.h \ + nameser.h \ + netbios.h \ + netdissect.h \ + nfs.h \ + nfsfh.h \ + nlpid.h \ + ntp.h \ + oakley.h \ + ospf.h \ + ospf6.h \ + oui.h \ + pcap-missing.h \ + pmap_prot.h \ + ppp.h \ + route6d.h \ + rpc_auth.h \ + rpc_msg.h \ + rx.h \ + sctpConstants.h \ + sctpHeader.h \ + setsignal.h \ + signature.h \ + slcompress.h \ + slip.h \ + sll.h \ + smb.h \ + tcp.h \ + tcpdump-stdinc.h \ + telnet.h \ + tftp.h \ + timed.h \ + token.h \ + udp.h + +TAGHDR = \ + /usr/include/arpa/tftp.h \ + /usr/include/net/if_arp.h \ + /usr/include/net/slip.h \ + /usr/include/netinet/if_ether.h \ + /usr/include/netinet/in.h \ + /usr/include/netinet/ip_icmp.h \ + /usr/include/netinet/tcp.h \ + /usr/include/netinet/udp.h \ + /usr/include/protocols/routed.h + +TAGFILES = $(SRC) $(HDR) $(TAGHDR) + +CLEANFILES = $(PROG) $(OBJ) $(GENSRC) + +EXTRA_DIST = \ + CHANGES \ + CREDITS \ + INSTALL.txt \ + LICENSE \ + Makefile.in \ + Makefile-devel-adds \ + README \ + Readme.Win32 \ + VERSION \ + aclocal.m4 \ + atime.awk \ + bpf_dump.c \ + config.guess \ + config.h.in \ + config.sub \ + configure \ + configure.in \ + install-sh \ + lbl/os-osf4.h \ + lbl/os-solaris2.h \ + lbl/os-sunos4.h \ + lbl/os-ultrix4.h \ + makemib \ + missing/addrinfo.h \ + missing/addrsize.h \ + missing/bittypes.h \ + missing/dlnames.c \ + missing/datalinks.c \ + missing/getnameinfo.c \ + missing/inet_aton.c \ + missing/inet_ntop.c \ + missing/inet_pton.c \ + missing/resolv6.h \ + missing/resolv_ext.h \ + missing/snprintf.c \ + missing/sockstorage.h \ + missing/strdup.c \ + missing/strlcat.c \ + missing/strlcpy.c \ + missing/strsep.c \ + mkdep \ + packetdat.awk \ + pcap_dump_ftell.c \ + print-dhcp6.c \ + print-frag6.c \ + print-icmp6.c \ + print-ip6.c \ + print-ip6opts.c \ + print-mobility.c \ + print-netbios.c \ + print-ospf6.c \ + print-pflog.c \ + print-ripng.c \ + print-rt6.c \ + print-smb.c \ + send-ack.awk \ + smbutil.c \ + stime.awk \ + strcasecmp.c \ + tcpdump.1.in \ + tests/02-sunrise-sunset-esp.puu \ + tests/08-sunrise-sunset-aes.puu \ + tests/08-sunrise-sunset-esp2.puu \ + tests/TESTLIST \ + tests/TESTonce \ + tests/TESTrun.sh \ + tests/bgp-infinite-loop.pcap \ + tests/bgp_vpn_attrset.out \ + tests/bgp_vpn_attrset.pcap \ + tests/chdlc-slarp-short.pcap \ + tests/chdlc-slarp.pcap \ + tests/dio.out \ + tests/dio.pcap \ + tests/e1000g.out \ + tests/e1000g.pcap \ + tests/eapon1.gdbinit \ + tests/eapon1.out \ + tests/eapon1.puu \ + tests/eapon2.puu \ + tests/esp-secrets.txt \ + tests/esp0.out \ + tests/esp1.gdbinit \ + tests/esp1.out \ + tests/esp2.gdbinit \ + tests/esp2.out \ + tests/esp3.gdbinit \ + tests/esp4.gdbinit \ + tests/esp5.gdbinit \ + tests/esp5.out \ + tests/espudp1.out \ + tests/espudp1.puu \ + tests/forces1.out \ + tests/forces1.pcap \ + tests/forces1vvv.out \ + tests/forces1vvvv.out \ + tests/forces2.out \ + tests/forces2.pcap \ + tests/forces2v.out \ + tests/forces2vv.out \ + tests/ikev2.puu \ + tests/ikev2four.out \ + tests/ikev2four.puu \ + tests/ikev2fourv.out \ + tests/ikev2fourv4.out \ + tests/ikev2pI2-secrets.txt \ + tests/ikev2pI2.out \ + tests/ikev2pI2.puu \ + tests/isakmp-delete-segfault.puu \ + tests/isakmp-identification-segfault.puu \ + tests/isakmp-pointer-loop.puu \ + tests/isakmp1.out \ + tests/isakmp2.out \ + tests/isakmp3.out \ + tests/isakmp4.out \ + tests/isakmp4500.puu \ + tests/isis-infinite-loop.pcap \ + tests/ldp-infinite-loop.pcap \ + tests/lmp.out \ + tests/lmp.puu \ + tests/lmp.sh \ + tests/lspping-fec-ldp.pcap \ + tests/lspping-fec-rsvp.pcap \ + tests/mpls-ldp-hello.out \ + tests/mpls-ldp-hello.puu \ + tests/mpls-traceroute.pcap \ + tests/ospf-gmpls.out \ + tests/ospf-gmpls.puu \ + tests/print-A.out \ + tests/print-AA.out \ + tests/print-capX.out \ + tests/print-capXX.out \ + tests/print-flags.puu \ + tests/print-flags.sh \ + tests/print-x.out \ + tests/print-xx.out \ + tests/rsvp-infinite-loop.pcap \ + vfprintf.c \ + win32/Include/Arpa/tftp.h \ + win32/Include/errno.h \ + win32/Include/getopt.h \ + win32/Include/inetprivate.h \ + win32/Include/telnet.h \ + win32/Include/w32_fzs.h \ + win32/Include/Netinet/in_systm.h \ + win32/Include/Netinet/ip.h \ + win32/Src/getopt.c \ + win32/prj/GNUmakefile \ + win32/prj/WinDump.dsp \ + win32/prj/WinDump.dsw + +all: $(PROG) + +$(PROG): $(OBJ) @V_PCAPDEP@ + @rm -f $@ + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) + +$(LIBNETDISSECT): $(LIBNETDISSECT_OBJ) + @rm -f $@ + $(AR) cr $@ $(LIBNETDISSECT_OBJ) + $(RANLIB) $@ + +datalinks.o: $(srcdir)/missing/datalinks.c + $(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/datalinks.c +dlnames.o: $(srcdir)/missing/dlnames.c + $(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/dlnames.c +getnameinfo.o: $(srcdir)/missing/getnameinfo.c + $(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/getnameinfo.c +getaddrinfo.o: $(srcdir)/missing/getaddrinfo.c + $(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/getaddrinfo.c +inet_pton.o: $(srcdir)/missing/inet_pton.c + $(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/inet_pton.c +inet_ntop.o: $(srcdir)/missing/inet_ntop.c + $(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/inet_ntop.c +inet_aton.o: $(srcdir)/missing/inet_aton.c + $(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/inet_aton.c +snprintf.o: $(srcdir)/missing/snprintf.c + $(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c +strlcat.o: $(srcdir)/missing/strlcat.c + $(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/strlcat.c +strlcpy.o: $(srcdir)/missing/strlcpy.c + $(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/strlcpy.c +strsep.o: $(srcdir)/missing/strsep.c + $(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/strsep.c + +version.o: version.c + $(CC) $(CFLAGS) -c version.c + +version.c: $(srcdir)/VERSION + @rm -f $@ + if grep GIT ${srcdir}/VERSION >/dev/null; then \ + read ver <${srcdir}/VERSION; \ + echo $$ver | tr -d '\012'; \ + date +_%Y_%m_%d; \ + else \ + cat ${srcdir}/VERSION; \ + fi | sed -e 's/.*/const char version[] = "&";/' > $@ + +install: all + [ -d $(DESTDIR)$(sbindir) ] || \ + (mkdir -p $(DESTDIR)$(sbindir); chmod 755 $(DESTDIR)$(sbindir)) + $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) + $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG).`cat ${srcdir}/VERSION` + [ -d $(DESTDIR)$(mandir)/man1 ] || \ + (mkdir -p $(DESTDIR)$(mandir)/man1; chmod 755 $(DESTDIR)$(mandir)/man1) + $(INSTALL_DATA) $(PROG).1 $(DESTDIR)$(mandir)/man1/$(PROG).1 + +uninstall: + rm -f $(DESTDIR)$(sbindir)/$(PROG) + rm -f $(DESTDIR)$(mandir)/man1/$(PROG).1 + +lint: $(GENSRC) + lint -hbxn $(SRC) | \ + grep -v 'struct/union .* never defined' | \ + grep -v 'possible pointer alignment problem' + +clean: + rm -f $(CLEANFILES) $(PROG)-`cat VERSION`.tar.gz + +distclean: + rm -f $(CLEANFILES) Makefile config.cache config.log config.status \ + config.h gnuc.h os-proto.h stamp-h stamp-h.in $(PROG).1 + +check: tcpdump + uudecode --help || (echo "No uudecode program found, not running tests"; echo "apt-get/rpm install sharutils?"; exit 1) + (cd tests && ./TESTrun.sh) + +tags: $(TAGFILES) + ctags -wtd $(TAGFILES) + +TAGS: $(TAGFILES) + etags $(TAGFILES) + +releasetar: + @cwd=`pwd` ; dir=`basename $$cwd` ; name=$(PROG)-`cat VERSION` ; \ + mkdir $$name; \ + tar cf - $(CSRC) $(HDR) $(LIBNETDISSECT_SRC) $(EXTRA_DIST) | (cd $$name; tar xf -); \ + tar -c -z -f $$name.tar.gz $$name; \ + rm -rf $$name + +depend: $(GENSRC) + ${srcdir}/mkdep -c $(CC) $(DEFS) $(INCLS) $(SRC) diff --git a/README b/README new file mode 100644 index 0000000..ed657c1 --- /dev/null +++ b/README @@ -0,0 +1,233 @@ +@(#) $Header: /tcpdump/master/tcpdump/README,v 1.68 2008-12-15 00:05:27 guy Exp $ (LBL) + +TCPDUMP 4.x.y +Now maintained by "The Tcpdump Group" +See www.tcpdump.org + +Please send inquiries/comments/reports to: + tcpdump-workers@lists.tcpdump.org + +Anonymous Git is available via: + git clone git://bpf.tcpdump.org/tcpdump + +Version 4.x.y of TCPDUMP can be retrieved with the CVS tag "tcpdump_4_xrely": + cvs -d :pserver:cvs.tcpdump.org:/tcpdump/master checkout -r tcpdump_4_xrely tcpdump + +Please submit patches against the master copy to the tcpdump project on +sourceforge.net. + +formerly from Lawrence Berkeley National Laboratory + Network Research Group + ftp://ftp.ee.lbl.gov/tcpdump.tar.Z (3.4) + +This directory contains source code for tcpdump, a tool for network +monitoring and data acquisition. This software was originally +developed by the Network Research Group at the Lawrence Berkeley +National Laboratory. The original distribution is available via +anonymous ftp to ftp.ee.lbl.gov, in tcpdump.tar.Z. More recent +development is performed at tcpdump.org, http://www.tcpdump.org/ + +Tcpdump uses libpcap, a system-independent interface for user-level +packet capture. Before building tcpdump, you must first retrieve and +build libpcap, also originally from LBL and now being maintained by +tcpdump.org; see http://www.tcpdump.org/ . + +Once libpcap is built (either install it or make sure it's in +../libpcap), you can build tcpdump using the procedure in the INSTALL +file. + +The program is loosely based on SMI's "etherfind" although none of the +etherfind code remains. It was originally written by Van Jacobson as +part of an ongoing research project to investigate and improve tcp and +internet gateway performance. The parts of the program originally +taken from Sun's etherfind were later re-written by Steven McCanne of +LBL. To insure that there would be no vestige of proprietary code in +tcpdump, Steve wrote these pieces from the specification given by the +manual entry, with no access to the source of tcpdump or etherfind. + +Over the past few years, tcpdump has been steadily improved by the +excellent contributions from the Internet community (just browse +through the CHANGES file). We are grateful for all the input. + +Richard Stevens gives an excellent treatment of the Internet protocols +in his book ``TCP/IP Illustrated, Volume 1''. If you want to learn more +about tcpdump and how to interpret its output, pick up this book. + +Some tools for viewing and analyzing tcpdump trace files are available +from the Internet Traffic Archive: + + http://www.acm.org/sigcomm/ITA/ + +Another tool that tcpdump users might find useful is tcpslice: + + ftp://ftp.ee.lbl.gov/tcpslice.tar.Z + +It is a program that can be used to extract portions of tcpdump binary +trace files. See the above distribution for further details and +documentation. + +Problems, bugs, questions, desirable enhancements, etc. should be sent +to the address "tcpdump-workers@lists.tcpdump.org". Bugs, support +requests, and feature requests may also be submitted on the SourceForge +site for tcpdump at + + http://sourceforge.net/projects/tcpdump/ + +Source code contributions, etc. should be sent to the email address +submitted as patches on the SourceForge site for tcpdump. + +Current versions can be found at www.tcpdump.org, or the SourceForge +site for tcpdump. + + - The TCPdump team + +original text by: Steve McCanne, Craig Leres, Van Jacobson + +------------------------------------- +This directory also contains some short awk programs intended as +examples of ways to reduce tcpdump data when you're tracking +particular network problems: + +send-ack.awk + Simplifies the tcpdump trace for an ftp (or other unidirectional + tcp transfer). Since we assume that one host only sends and + the other only acks, all address information is left off and + we just note if the packet is a "send" or an "ack". + + There is one output line per line of the original trace. + Field 1 is the packet time in decimal seconds, relative + to the start of the conversation. Field 2 is delta-time + from last packet. Field 3 is packet type/direction. + "Send" means data going from sender to receiver, "ack" + means an ack going from the receiver to the sender. A + preceding "*" indicates that the data is a retransmission. + A preceding "-" indicates a hole in the sequence space + (i.e., missing packet(s)), a "#" means an odd-size (not max + seg size) packet. Field 4 has the packet flags + (same format as raw trace). Field 5 is the sequence + number (start seq. num for sender, next expected seq number + for acks). The number in parens following an ack is + the delta-time from the first send of the packet to the + ack. A number in parens following a send is the + delta-time from the first send of the packet to the + current send (on duplicate packets only). Duplicate + sends or acks have a number in square brackets showing + the number of duplicates so far. + + Here is a short sample from near the start of an ftp: + 3.00 0.20 send . 512 + 3.20 0.20 ack . 1024 (0.20) + 3.20 0.00 send P 1024 + 3.40 0.20 ack . 1536 (0.20) + 3.80 0.40 * send . 0 (3.80) [2] + 3.82 0.02 * ack . 1536 (0.62) [2] + Three seconds into the conversation, bytes 512 through 1023 + were sent. 200ms later they were acked. Shortly thereafter + bytes 1024-1535 were sent and again acked after 200ms. + Then, for no apparent reason, 0-511 is retransmitted, 3.8 + seconds after its initial send (the round trip time for this + ftp was 1sec, +-500ms). Since the receiver is expecting + 1536, 1536 is re-acked when 0 arrives. + +packetdat.awk + Computes chunk summary data for an ftp (or similar + unidirectional tcp transfer). [A "chunk" refers to + a chunk of the sequence space -- essentially the packet + sequence number divided by the max segment size.] + + A summary line is printed showing the number of chunks, + the number of packets it took to send that many chunks + (if there are no lost or duplicated packets, the number + of packets should equal the number of chunks) and the + number of acks. + + Following the summary line is one line of information + per chunk. The line contains eight fields: + 1 - the chunk number + 2 - the start sequence number for this chunk + 3 - time of first send + 4 - time of last send + 5 - time of first ack + 6 - time of last ack + 7 - number of times chunk was sent + 8 - number of times chunk was acked + (all times are in decimal seconds, relative to the start + of the conversation.) + + As an example, here is the first part of the output for + an ftp trace: + + # 134 chunks. 536 packets sent. 508 acks. + 1 1 0.00 5.80 0.20 0.20 4 1 + 2 513 0.28 6.20 0.40 0.40 4 1 + 3 1025 1.16 6.32 1.20 1.20 4 1 + 4 1561 1.86 15.00 2.00 2.00 6 1 + 5 2049 2.16 15.44 2.20 2.20 5 1 + 6 2585 2.64 16.44 2.80 2.80 5 1 + 7 3073 3.00 16.66 3.20 3.20 4 1 + 8 3609 3.20 17.24 3.40 5.82 4 11 + 9 4097 6.02 6.58 6.20 6.80 2 5 + + This says that 134 chunks were transferred (about 70K + since the average packet size was 512 bytes). It took + 536 packets to transfer the data (i.e., on the average + each chunk was transmitted four times). Looking at, + say, chunk 4, we see it represents the 512 bytes of + sequence space from 1561 to 2048. It was first sent + 1.86 seconds into the conversation. It was last + sent 15 seconds into the conversation and was sent + a total of 6 times (i.e., it was retransmitted every + 2 seconds on the average). It was acked once, 140ms + after it first arrived. + +stime.awk +atime.awk + Output one line per send or ack, respectively, in the form + J=9C~0 zYRDZOG3Y3^vO)g1048~`5r;`|POKDJodj(~(7KD$WISs*I7?7&7&@+Z)bg8Rv-q~K z!aomXUlnh^uGPP-s;`^PL9_WaY@Z3F20|;uP+=P21GO()WeWblX;4syL<)yvZ+HLa zMV#B9gZpCfO<@HEJMkh1zZH^M++v+Lpn1aWxT%azy`MgU-OU=KOBa`8cC+TmAY|RZJ|Yq?ZdrS$M|0bmHCLH+=L5rcO2n= zIXE`Z{91lHpL@W}Sd#n1taAY*!)|>T}! z02i0Rzut9w{c!O6FdB`ou5WJtUEg}L4aoobi`{?xy!Ued;PC$)9iP1V<=5B${9inC z>^1?)dn>InCr0zt{{MS*fS31zX({&2-YznlunwW8r5qg{Y4wRxynEJY*I@oNnFP_A z)YvtxL1i5lfVya^1cmj*f+sF7N%K*$vUzq>4!jCmnAoiD>^bbgCS65^{tbZKy2 z1nct^5Hdq`%h8;3Bq(`WKNR1}`b&^;>*yrbc0GTB;t_ zR@gF9)DOdf3}7TVdQgY}*pG);tQ7OPU-hBB5nS3we)ksTm;u{a<7ey|4Wn3)ku3j+ zH6=c|umx~W73 z!9-ZFnB1VAV}n^ek1d>%wiGsBEGSV|eB^xM@wmtaqTs$!;_gIaK&oD(oh{UsYirs; z0$EVynsK5|_I7I-%Uxc0qfj)Q(CK6Lu*N79uYm#5}ckE{DU{ZTRwM3*Ccd-b$Z%T7uhG% zc9+mnEiMMV+aR&0v|(GXj{`RV#Mws|@DLUn2FH0EH$;U)G{+JgyA_sCa!7M*wZ_;uv@%G{tV@2Q|t?E;KX~hY;J(PINKHC9C8b zn1EBew`9I;h>CygHnkt>MG5=0<_X%%P!8577aVhRP(M&Fah%dA6~5oYzNOl-Mte1Y~8qKMyh1^sNWqROn6J1TH4aUeuf z#p040V7&Mez)CtR6)%V(;BSjTQ@@%)|cxeKphPgTYO+kb!1I0mtG7bKoJbfJk9^7&6D2${lR|;`@gnB;V)JP z+W&p{@ZkjeziW@ySIGYZ1lCs`J$eNBAFeFj`+xXT{vLd#>gPef9$li(F+RTWWTq8B zOtF60$Fo~I87Idx=*!PG_Pb5Se&G^>zC+P-s5bnoo(+8;4k|G;`V3EXF{r!SZ?S8? z6YX@H?w6Qf8z$XU+Nl39Ht9|J*d>AKXtE5)yU+ zDoA)kAQ#A*Efh`~Oob7hX)hI7kiH&SfH7fgjjCT84Ig)-TEcN4lPEw)`(%_>%(Bd! zGl1cBL!c6b@fi={CKBL4$W~lOcFt@<>EsHmsE6OF6Cdebbx7n`6)ubjV0Cq=qMiUb zfLUK|sil?W<>l(~>e8c%dUd?T9ooV@LS|FZjrL8;H}Bii`%w{xd;r2)*v9?5?Y7=C zi-d2@+QA8W_cLBBsa7$D6uT-pzg1guy%2XEC{8D@Rj{P^+WsJBAUk%mc^grsSauva z7s(M%mN(MPtC15vF&7LqAHsrv0(Tr}jQakZ13$HHFZ$!C2KSF2YB|=I>v@s2H;jE} zjSxJ(#5_BGhP$GE3B+gpqK)3$(X4{Cm8AD_1&L-NF%<>900?os=IN2F!Q~ve7acaY z+iD?wRlyGug<-V~8wQU0s0~}KBK~>tQYCEpC4h9G?e7v0D{)!3+{ar0xrm8x`r^N_ z#g?4TZ&L=ZB5V1OMwhnSiyUmR=d0UET;WBeYwP?{MlCOK{RhbC@l?mZb}vWFfgtTg zeGNsYTbs~WvQL9@9dv(1Pr{4HMH{itQ4%6x0Z!Bs!6uVuHmXlg6;bxS0H>#|u^vrN z9p1uX3fgd?xnYI!;kd66B5KQw*+w=ULW>ud-oJyN`eCa!9FHy_8lSDynv-RSlz#JZmI|!g=KQ?aePI zuivsAE1It*Z7E}Ad1-xZ<5$?6;dRv9KiPP=w6R)BRRdS{{%E!KFj;)77hHJdjaU1- zuban&S(?9WtksrihzUk-{qehM>%3P5#B;T#%S&+&i*M}vBiQjgFN*%$l6`-49<`Gl z)LEVOFu;R>-=7K*O(x9^a@gBA+CAPbZ!Fi|EG@6R1*jh|au`Id;KqtI!#3kURteP54_HK&Fj?QU{i}b-Vlz^ zXEn9;4zQhZ9RPC=V2Ba7zq_|ni**I^XNz^lkBnhmWPmSlfDJ9{huEb7x3Q{!aWYqp z`aotD7++Q%aEB8cgWcL_x5DT~4_ONS)o?9Y60T-zwA~#I0oSln?e}VC`)=Ynud**9WbvN`lqL>(xQ)3shluZ{6Ui7ObPTFj`~c zr6TVROsN26hL01dM1i?96%_p2C$1zyTn8fMh1k|)a>>8(TF7U=MskGnn7aqMR_2=r zlqbCmjOpIW`wbEN#nW5p4;q&2)?2h4DCJ%$vcV~p}iH~;d zBOAB;;dqUN&l2abJ_ye&nOf}ZKfHn0_W|~v*S{E}^tXAA6DGFn&4GvE3}2mAtN++5 zX7qmC52Kk~uhyH{{a$tZ9iuS=dlGgr_-hu(j15N}YtN zvmrTXIt6MHj?NsT35~)*ny*O=W>Sj~&YbP(c`Yb0ag+u?Sj}OF`klAThFo=j;KqyUU)>>^fyX33AlcU|&nPu5R^sEN_ zvh`X+DcfMKyqh~f!Aj{cdi8Sm@EFb$6M@YPQ4*O%qJV;0K!N7(zgIg4&(se>3g<|X z1jUflBHX!J=sxP=szf3`_`NBX^UD~$iK-wE;1Je2>2z6ZVvQyB%{Os0Hf85YDUlgT zUb1WV&*NW6IFPkA)MB1Sj{ZS%BaFU|@N_0s4y^ah^4pS7>8#HoQcDxS|8lf86FeNw zp9mfn^4e+%FC3C&r_8Ds7StTo%CC@di`8XJ6%`hv!J_XnRk_Bn!)Ta=TAjZcW9O3# zD6h%tz6hV9q-puIR4cR9?K1-i?o7^w3FCP2X?02`+1>?Kr)MqTePqlwQLuC45ce?} zCV8E;yI~yy#43FP;dhhT36BBQY`?C*dcE<;-jxuo%eHRDH;*#Ql{escK3a22^}=N_$2DVIVYTfYRs!Tv`3Vtiwh_w-cu99l1;b&+JG+Y>n<0|Fr!`NXP- zOd%fJ!=nS#z&kiEyn)+rZFys*M7t8A)Jkoowv5jX{ILulaA`O?sUL1*lqQ;o zVQ)|k;Ck)_H+oZRew(_0%PKKZ9;-{BSjqR{_TeiP*u7NFA9JD<`)*`>UeuI-bXLp@ z%p$g`$k)6dAFpF4Hj+0yX;peaG4l#>OkiJ=HS_Z@T3va_&eenoUl)beiMHDek&#Vh zEVw>JcpD(&J(!;!^ zU@DrZDfQ3P;c1X&H4!PN!K3#_-1+i(RXj5 zoX&qa7`Nmj5-Wv-#u4KmM6Car%BZj!4dzXm=raN5e5cMPre} zttMW{mz((9DljC@ko>K1h$6dET!e-z>Jkts-~m>USs+4wF#%x_`lSspznAh#TZqQA z9G|VC8S6G^1EuLAxUtH_SK*@J!EFP6$2Zsh3LL4dLa;dj!g2z_@*N?pB-*etvkfBs z>Xe#V@hyMmJ$`;tWb!3^LTfTn*`pW> zTIdmQ2w)I9L1RZV!t@AYXXzQQl*VUJY8_oi`0otuK^lo8|1+6feR`{Q(!nbbWSTD{%y7;!1`O=;Bk~y(D9`HG8YhrDuwaof5reN~< z%5(BrH3opX|M~pa-Te$9iq`GLb*|oXm8la4dF%X$+M@VqX)M!tRP~M4_gT? zJpUJZ`|F5JwH`{Mqk)?cL3Dy4Dx|UzMJ=E{^1Em)q?TLgwwsrJchF>aD2=l&G_i^? z#O^vH8b;pI+^l)cCrb)w=8X{_<@d&2R(srl`$DG~)E=+rWBSp3qqFxmSzX4F%&Sd9 z@e?oci?jvXK~>zXFAB4_pI5>SyC5YM^3X{d5hcwF+nmZI}Tl{2+3n8ZS!VnGbc`cELX>zJ1n6ox*mF|d?1jN%9OgSGLZdh5J~Luy)V05{HJ`JGz%7vW0P>w}{DJ`2Lxv_=O}E51<) z=Cs8}UONlf3TCxy(JA?XePbW7!hl73*2)buu35r{Wfln@FReXZw`wEtGFLq%fE<&` z7k@*!K0r#f@*%47k9$Q27#aRdLwraOC(myybcbs8a#+oLh~4c2@yVixs~L9)6g^D6 zfT1z9i?Hu<6@tg>OI5U2(iO&GO5}S<_s zLQK>?l2em_Mgk^t51;`EUCl43x98a{Ax_@|wWam6;xxcZ{dPD+D>L2jTCp#pTS8H7 z6fFa^h1NfuhL~$mRy!1$ilB760qOaHe&ZeQWcM{ zah0+YyY~3uQXByl9~{$OEf%dd_@h?6HiW(3#;pOhNv4{GY2N&%-j)^rD^i2>Pb@j8 zzPBO4=61x;96TaKrnAS5+#$~YN7A)q~B=d1C1(ikHCm-Ee z%^}Qox8|H2WBP6;xCEg-7d)0taKOPlki_ZXc4jRi&2YDBj$gicvh(&>M)8-lczD~N zL|wQt<}b?|WFn`UA?wzkF#gFR?0F%*{wAN|DJ{`~t6DYjytCV6os0cwb>*E&%oa*Y zEV%N23AGzXtmD`%C=!3AuPZZ-}<-SV0>yzrZ8n9IqJ0j9I|O zl=O`WPoB{@as_FBgv-&tdWp9*$vJ71@qcb3Bj4+Heu}Q!t(ug@hSlt2dMZrZeC3U; z`m5I|Mlvfkc$wm_?vh!>1zy%8Sr%UM(b|%EQuwD?k^I0Z*TTNvQg7`yO~Zqy^#;jP zDdKdAX{Yd%C%nU*{gd5SFE_RiQNA1TsSqx&`T>AaXWKwY4iC{O(u zcC8K(eh2M9S$H({_drD+0Q&wY!24vo_OkZG8v^*pT3%a#!zaPQeJwN#62lvT? z4v8@}LuN4D1(KA3+aev~i~FH$K3E7nvR$W@VA)tbu>jzX7GCs&e*+y;DyrolzFCp- zUqo@3;N>#z+4}N)yz~EF!I(GU;y1z7i5ov2(Up%<_)@F|Z0JHBD@#OS|F+~tX`K*~ zu0f6ob2swmQ9DltD1EPuHWl)H|2hgIG?97e4==qzM7d*gf^3$w&8ENAuGkg81y_SV z5|K&jU|@5qtb5_8Tre}>LAFmf8whDoArNld*AcP^^f2!4{Ca$Fyk@Pt{90aM!{*56 zV-AA+B^ts0+xW*Fv}V&A_FUZ>h(g8OWF+pGlHKN{3U9LK8MTq990C5yiW|FdE#bKI zaApAA_g|mzQuxYhE{cNfp6qO&ygJ%xHX&Uc6DCs>)n|<$a)g9mfk;DwaA2V-63H0Y z>MgZ0R-Zdl)qr^BNlr&h)Tx#FKj+oSB8w_?6j**PPnhR8Bw>4tr+kp6?73>M8z-Er( z={Q*YW{j(c3Fr>`;T-l`y#WwlHCbB~mH%Z07T-!qH5%fODZ9^u(alP-oe1~i4Cu=a zbVSgvU%y74?JvukllUWv9!{)wd2+QA%Os0rkL8tjlSCh^8R<-zR+^lMQEeC7&_bAcZx+#10 z5DiMS57Uadr!DMy4iB$u%N{?UgPlL!j=tlP#-5K$QK~4mN-+Hcf5#d~c96w> zSE;ptK$yv2a~rL~RcXj#uXhIcGl* z4JnTrK1~l!6KzJfg)C~=H+A*gKL(Plvy))#mRjg*yh)Q_{fdkT(PWkev0I=cpf`1i zOJv-&80Rhc=}UQS7?H9`Y9pFErXGw3KpU+%NGOX5${=LAa=#vO%(0@`-9vY+aG4QG zhyhR!HWWgu139;a8>-fq7mIV_gYYMaGWYI?4^eS1`G}e0T^L}*DRDUSU*S&*R*a+! zSi$*Oz|IVtQ&*Z0dS>DT&p~uPA~GnlhWd%y0eYYZQpC={smdwlK^? zv80MYDV|U4EkSs?McLoZb-Fv)j@<#f<9Tc+y(^dHox)7z6}UFqVb`ZN#=npr#?L9^ z?VTMet`xm-5P%c;L6?D+GrtU@!+K)1gF}^l1g|DtOjduZ&9;Q)J1XUQZ0UvU-P{vCXC-is?oOh|)$In6Ho&hDl@>ueIL2_?W1Hw0v3uYRM^ z?p$^7P)x*{hj~ZuoqxqEdD)(pYo)v|(=fcqZan@QpUbVHK5(q%{SMs;8$H35o_F~M zp5F4}(z+%5VkdOJkyCVHY^sl_lT-`qbSOV7PV2fS61EQ@p`-mEfOBB8f;81-##$P_ zvz1?HJRu-D{|3}Sy^|xshnK9%KyxxS+H)4QMPK~`<-qGN1vU!cy?lrev-z@zUaB*@ z!N746RFZG4{tWa9Lte%fBZ{%+_bRH5e8!KjaA6?&|6w8`0W(jWj_ya_TZJuqGeQH<=p)bzX3*1NwZ8TOMqvxN8ix zElD*k1szgG2^4TAb40A^8&2FB`8EDg-2Nj$xZG6cYT5MtD+k+Y~j`a+v|CdF$dd{Y<@Jp1y;v zR;Vwu_efkY(L#Qg#9;I1x`RUc8D^_L zZ>!rWL9phq3fHaF>jpS_vcPt5B#;4>&B>La6yoVOV0g7^mdBh7cM_gMep-txkX_BQ zL7^_PJ5~FM(Euq2kiYE-NN9|D65gG*<9Cra_#r*2~dCq;C{K{f9xUD;`)nKJVk%FmckI(Ot{s*M9E-8 zHLTNNweC_?`dK!kz?SHp{nM?S8wjic(S-x->Vx0wtf-pVB-V~ z7Q>^LcZ!i7ynUamD z{@KZ5gd)0Sd{RLEyyuiePB=&S5O5^H8xuwUnoGp^@)*P&UsW9QUE~q7R%VExhBVuO za;)(R1;ynRCGU3y`Fgmg1Qe0Le%Gj>NuO%~i>Abf_q=v2{x);R@ik^4>{=F6r|w8X zEQl@O9pZF^*Y$a_gWPW_?0@)}j!v7^{+sBxyIi~(cx;>~8I}>aPoLML{Nw zMmdfM&s8XQTYx`&I2o~;D$jaDGP7~465(A2X>l6jeybN^%?oQ`u8a?@>mLEzeo*lY z(GrLa3h2zBBg)vy?)+3<0OAo7BR>2j8DD@(R`^klDZggtK0Cjwpw7-U^xvD>^l4%5 zu9bZ>rNg$yl7)9Ap5A75OvZUa;3BLhuvq^DPsQD#@j|2+U!DO>pr#mq^7oN9P7dTT z`-F_hpPn$7iq*q5pyDHktHcQFOx)WXvi9p92Gnhm^N(ba_W{Kicav?YKIzkvU*|7P zQC=B$OSGHrO3d1ToX~u0>W$G#aqLW}x}|T5Y-k&Ir?*#ZzRV>e_(fj}V%zzC0Mq(1 zg{2g;d{7V2TZ{Zj=Sc+!)XHGe9xt26H@-uTmmKsOIOAy!hqO6CtvX|lO2se`B_?bjH5kLi9s=6s5i@p; zP^kMQ(1CMm!dxMFl}F+~cFEs}?}sQBsEX-5z7f)}P`&&Z)tEuXHA8%R+_1FxZVoI? zs$?Wg#`0Z5Tg^9PHObWjcgD!G26pb%#9=o)sUb^OteAJLhND+KDX-yz0!<*fo~ppx;3!gUc*AbGGTG$l^pc4}-HS z{^M91nNz%IjE#UrAsWD{D8EysHHpDo>eDPYokH7`pkQXKn!jA7SlJk9jJRNHFsL|j-^WTYnMs?R*aXU-xB zJHGXzicq*WJERj3&e^#?pqCFK1xBwt+Zm5Hvfs_mC<#WfFk2=;-I^IO_jUvBDjyx!FD!kQFWW-po7GH%*O~r2qP+|X&PKH)^EHhrH_2V7t7}v= zpF}Hl&UlNMb^ zOB?Ab^t5VBXBf(0oI<|2NMmxc7?eC5j=?0Q*pKvjdfYby_Q*_=%ayDga2#2R*3Vrs z<$9}XaLiOd((BpUA^jK09HBBk?tMCfmbX)Gx7#zRjOP7&yL0sEKCFkB+gR6nEf%S+ z>Q(|iYX-nPdP;uUe{NvHz;vKa$&AwM}v|OVIBQr>C}MhLk-L$*+Lzi>L&TxGIf_<#9||sQ1mVk{+CG z9ti@*q6N(F7Sz6n6bDUmv9%-O8%2Gyb1`87X22Rl%t-kVx{ZH`Z3@kU`+mzfVRpP7 zu1@GfNiPC6Z@~feJg(iL&FQIIZkA2w#V{BL=)>CvB3HJHSwm}_V_m?PQU7)f2;z&2 z@Xw!*l0NC6vKN9G-c2{}yCe1;PpLkM*E?AVc=!pV2*Wp%J1=nNLImanc^La(XUsWC zPwtRnIwnLbSl0HL%L(=g?yrlxkaU+Xq^mZ%sQof}w!B@{$Lc?+8T{$i@O)$K)V_FY znFRfQxpuwOh&<%7=H`zjH(4GA!+51NYM*;dGK!$N@xjC)Vuc}{GjdrRGoni6nCjBC<_!vgBOS$!2qz$**8!X#N` zn!2YoHCQF8K%!I!#xYd{{_PRveGo!_^ejDgnG5i~E#yP-xr}Dr^(K&y)D*P`-%#43 z%S$7AaT9WuUUN*I-VhaFmuU|%g3C^gdY8db&an9sUkam=CE*~ zS5ZH}?riZdNX<~h%fb;;4SZ$@>#7RWf z41~c`DO(S1qwZ4Q+_rX6w6P;oZt1M3Q!c0~W0}r^@i!HzLUXc;vN1_V?S%(lWs2mr z-n8v*-}In(Gra5JDqG-K*S;~pUTgPc-R-XKr;ZHXzK{%9eh6I33RVmVn?n5( zgf*s0x_Z|P>aviAmXxqikX*9(IT*PcHWUz2Qr&L1GrzLDW?GSJVMG{&evfWgLCwA% zbY}MmTmQM5E@$FEmA(wNh_tq}(d!6CZ3BDpy=I9L3Z4j4jJXF@bmRP?4yV?GOzhm8 z^i@$R5YLB67weoB{SOo{o!>bmOLp>K&1mNAYILV4bEE)eyJPs zu(G7>(F%g&MvyW^!Fo|jUO2T+Zb^*Yqeo5Fot}rw=aS=DPu!2Od~0heLCfiAcCO3S z_yc@Npa_2HOc6o1?6nU(Vy|MkSH{V)Mf&x2$`n+TKfUPB#h4So4jM=38FtncRU6>h z*T6_bc+~rXvh!UBAj|$^?_kby;ye2mZKzO$n$kqbEVYSq?@y{}R(MfC9$Sb!H@Z-r z7Le;jV6jQW`>Daf>-AOh*)3L}>>Ujz|z{V;dOm4`^pjlas*H6 z$Oe|c)ML_sm)mukV1xl85n2RL>SCO>Lk4TQdPXtkbsT;xrxUFBUX=S6AJo9nRY)J# zF`qdQWKyV&%nV+ej#@<`Fl~JCunem*7JY|VSZFRsY!3PGQsD_THU)WP1ccaanQ!Q0 z4=aoS-IX8^30%Vfok%Mxa2?6u+Sj{%~>HUw=ChtDcwLROTJ#uq#Hcc}C!1+)N>-HM-j#GaR*r!2yGfU&k zMhk^-15IjOD0BL-<|_e`z$#QJD_9Ga7_~R(!gmT~#vG<^pyU-fL=y9)UE__hc*CeB zKoGO*wN@wjXct_pAC>BR_-Xb5P^yj~DFn=!!w4a9^;B~j%=F8@+u@jExAkoxVEnwN?+-uJk> z1dBZxb>KnKylb&6{|X6dKv}uKxIGqgitAyk3L@-1&r^{g3>I0%rU2-r%^A!cZ9;0* zCVCH$T{*}Y;@GZHsS)*}4XImmJJf~~wptqDPSN1m^71y=NnmT0GOah8Snwyd6K<6? z-brLGG9pcVGLrkBooyt*@TaBArl@SJ1~JN$!KpZk_80a3fU)7{O-tB)vgJv8-6MXMeRzU= z%>wg8a%4cUjegNnzgf2FreOvsMb?UeDjW6GtSV8vA8bJk$YFz@C3faT!a}jS6=(qo zb9h=nU%XNAQ}ywa^kaZiQe1nKxnKNJ94Y}u-I+}`eYbpp2*Z>W zj$7gd%tzn8Y~9B#zFBu6;r1P&UbQooRLpFBh)+;@6fz0;%W$%+`dlh}f|NSEUyu+* zfDu%Xw(}#s@AT1K0(}~t*~0n3nGrrmBRh|Hapo&kBE|Nf_!kzAvxoB|v%hQSPEyVb z&0}%n18Npza=YcgwQ-9b70KX-`HXbvq;ek}7fE`oZrp9-vgR6Y;{*eEj*c@A3OcI7 z-F@(v?@X5Vr;HH;3GazC4d3m)=`Xu_ncm}^b3dDf5-+>Bv~<-~Rll?MmUZFF67Oi`Q1H4+W>iQjpsA?RgJu2f~E5;E)v3E;I3890_T1Cdwp%) z>$R~qMsWG zr>865yo~{~&tH}ghOot3cqB|OJu38QB;xJ2!XrNd%%EOjXxD)Dg>KZ_ry+UW93mfZ zRRA57EwR)3RIuUryt2Ccy81ACgb`Do1cMZ(Sbg~Rcy^Rs+#m~zsV@bbeAR6hgx!dw zBIL254E3+g^$p8PDk}+`PXeGt*SVZc5*iDIZ{W{#IHV5J<~==-IknkPtsO6=ZCE54 zLbCbYZAaDdpN_hX_21wOfnRK!?5;5!TspQ0P?exQ$-*~a&=t&K zTLQn;`)xrF}AIFc=<&{UA=GN^kkB=t^nlpVnTR7hq zxR;j}S#o=EwSGr z`izazT{Sw_7?)NCw>D=8HB&&xhQ?OMH=sXrqc@Y;+FVoNFed1MwzjOsfZtljv#8$u z#ua_t7FL<=scDE@gd$V}BMaA0h#W2HLL7(wu}JzS8{%}Qar&R1?C1@U%nP?*ABoQy z^I}KS04$Ph%J)w5Tr?=9)o4?jeZE!8g7)_Y{X3R#6*-#TZRTs1hnJ1)nNGOhtUWcS z*O<;ZA+YK!narl;H;KQXCLQl=K9gqzb}}L1HS6_QPgI5d{p3=#ucmd6>g%1 z;ht*G-n}^G*F-(M*Vi|rRcD9A=>!4lZl=4urB%t6iM#ZakWxnR_pv#=NJU_C) z_Z{E%a)E1({B{J^r!i4c2tsF=-7)Y43QVIUSy=3h(}&rE)rHlGfkYe}Jr;ZM@VOC2 z;WQ;a4;SFXw10vzvlEl59<08p;Vciq$=aPEg#q=jjKvOEhbpk%Id?MRl|YFXO<-74 z$64RauEYLSoC55qUC~v10U`|eoB05l;s&e)-7JQe@XDa=JDa(J!>L*s&H7n1hlXi?^p2o1~T%|twAiWTY%gSHdV&9 zaNW8~9b0N`Esv@im0Ofe;7a*iia(;$SmI1f;vCYSY8k4xY*V9x65zhksS24>`;2vz&&5 zaJKp4s=%6xW>IlYvnYdFrC&k_u$-Z33yJSQwyfe{nZe__;jzZs-yt;vv5gD)M~|xP{*IGt&XPa4fl(jC$74`(j?}yB7CCqR>Wxo4f;F z<@iN~eEmo(!^8Qb^o|a~v4OERNEAp^Kr*Vsd}_Y-A+AMGiPWh3N1L!o4J<~+)UT2P%K{_f%dPUuT!6$o}w2} zL)Xb{fN=iQ$m&^UpC%S|;f50pA$j;@b5Zfw>D>wRM{BuGjP}YRUoo6&qO64O+)m4J zm7M@r2%*Cqk9W#mwVBZ+#?!2PFz|4D)vxN?#`Ps!glY5y<@jG^0N0fWayJp5Z9HX{ zhKH5{d3BFM5;&>5MV?T_B9&# z^f%bA4O>JzA-EjoaBzY8TX2_gv9vA#b-S~wHKh8TCE|&BrP-;G*XOZ2#0!hyE~(z~ z8GeK7`^Z-y4)FEaiwa9aqdEThqsrJkDr8Ar%UkwP~7w=cYSbzPWxc_{A{QS%riRdaE3f=toK zD*0KPh}lJVkQMeB%`QEweY4h|1S5T{eoKS8P1^yMRu=hXf5%uR31&MHQo8U*NCZdN z!jSoEEu;%&2>R1>g{;0EF5YDky=yR4sg6-KITe zLkPtO#sl{jqMefCD=c2_^eQoM+bM6-%SZ0UO?t;EG2pmD{YDl5y`kp9!K0VUhRL9} zk2zx@uWk(Q?~~RNZ|<(|j`wGg`x%;fIRaV7f=OY^o^KEOG*z+<5J1cvR<8e!l@UoF6_+}41b5Nj`3@VakW!dz@!m(VLGh;!K(iTdlg zSt5tTyHtDcUDTaW9mlW9c?;{}f){zpCXi2SX51Hv58f^S?5okYHo*_>125=qulZ~T z~1bA1B=B@pemszb@*D#4)`oI4+LpDKOYeNX5WMZA4vxm22wK;g#*tpo) z%ns}{{LjC8?SHa+R5QGU~s3~r~;ZKBS zM{?F=O@%J-36VN|?sP3a1gX78N(XK41`VY_Qz84D(9x0mWsX8z7gU`LVT}~Cli8`@ zV!zUUH~k5iJDhpf9`>A!p&=Jiu%yPb*c02|iBa=#A4HaSO2B}@3&8#j@k(F^%RjV9 zPL%?=i-j&*RovCW9gh22u-HXY2lnms6FY#E^?=F--&C&el}i_7725R4jC{nS5Mtr0 zv3Imv#7z(oU~+5XKKdv1)L@%CV}(VV5c61|bUbYq32#)!qEBePpr=#2`Tl)+Yt~wS z&tedK<6S~>AMNL?+1}?->zhHua5b${V@tVaV}i9&E>s{?K__3*1R(NO^r#8qMNVSl z{2gJ^LV*&32l8u_)S}yo$={El9B_NrHn(?l6*f05GVfY8JSTejdF%k>0u_)Luex^D z-MtH7bH0Fm<2u&*&-+V+w(37X8F8?4`fhK2UT}TzY;19OgRwh5{UBamGD5|`XJcD* zGj0#B3w6lz_;PKst;)NR{MDjTF(jm!Bc4z#VVUk75h6AA;=O&Sa95dgphW#zI|D=B z7k)C*_ZAHHFu^9pEXkw|Zd9MFFla9)^G9jnU`xfhfJ;ZEoQjr>-yc%ILAZ!49EDG- zRJPXm)^^9A2T6C$u+TvgjHjX}*VCT_XCopJ6`jY ziMO-eXX^TE@4DR~jEsyt{qXp4zQ@e=MN(0cUe8pM_$-#yJ2+Qxu9h95EHQ@%{>8}g z;#Vk63LwJ~ibu{Uk_8eXIQq5H`jJJuKh+Yib zMK*AVumIHoDg zNtCzQiF$w=7G>Oz1h%@~tM6O3^klJn3=P#<3{;l##4t;}+kCflpGI4VQw0Q$YC>BS zx$bB`^o4aRL;BF=6V=!1YM*%SrQg)Qisg5Y#vMrx8QJxSY(m7R#)j!^?B4< zHl936K7`lB1tG1wZ4RaLmte6WFHKpGoeXCnfP7*nU6HE#*P;RHx-B}cU5657M#Me^t$S?9A_@vt-;F zKA*ZwDIm_OuOr*SjbgY@i z#>2Ku_1+*P-5qLQ4XNiTfIrL)g&5t1-{<~x0ouXKkyvh#d+2HU<}+cRojiY1p945e z`@Y5t%fLt=YS3O@FjWC{=nQd}(D^rxg+I8;@2lf-^gv!*3SaPK6ec4sr>V_sBunE9 zftuxf@gERV6Z^O9|0uKfGFlP#X}B#o5ne(}gt&WC+MLEQBHJ=xFCUwzqQAn<@EA5p zJoq21@z9#YnHn)_>?68wL||3lSu z=F;_ZcO+IuR7tS^FfY}2OChO&+iO6LLQDP{j_SXBbOJB(>Nx&}%`LvaZ9?M2j;+Y{ zcNTR81n3{nihjhMq5l)X$rRiCC{jl>u;vK2$-=K#zZGsXQY8_cQo(w|bgYDEn#qX$P3fbtuev^3805L%*F$V4@%G5WgwuP_u~RAI!Ggj{ zOO#>a`hRr%m<(b{G9rMq0NBm9byC_I?rbRje;+;X6y_6}BIm2V{~vtvxai~IQ&T}( z*B1*F8BC0-$A(%z)32JpAq+fh*#@30Rf|}rUA#CgDgS9LHtSKC$sOeV-^Ch?6qG25 z7R!vtg4n84>o4D#PcU$;01Mx@h69POjc6B9^U1pIJG+c)N}9+5R#R7LkW_(uyEFMBloX-*UgFB4G^U)f4j zSvwIWGfLd6GnWG5B^2e~C?mAw-66k@>QsAYyr4;p@2Q9;vE>LkQ<-66B1ZgnjjaC& z>g1OWNH=Qb!*IkobFT*qpC3fVXvDusMPh!|w-Tih8Vvp)<+II)J84G4Wpc(65vy&!HxzzpX2Drea(_0tINXdLUg@ky7>xFj z)puh2uStNW?G4}cBma+4C|FgmQi!wEZq%C?M+molUF6iYxq8jT@&RPrXD?%DATduL z8D&!;a-ldT_3q47HDn+8Ux$FtVP`+=abyra=g?qZo@Nxpq>FuOV&8N1p9Of>AC(!0 zE7Qk^)UwuQtC3?uU9Z32zcqe`daX=H;gdoWfjB%@8d|R(3zIV43fInXEE-ku^@D;b zlMz%t<-YvZz#dV_LVf|IM_ww3%daz@g?^zlg9fEG%+e7Wa>J=rwBY`vY=-?}_4+)S z4I_0brW_>xDqgu=vyx&&oE`t>d}-$E`uh%+zKjYH1u5ZGSMY|@ZD7XEL`>aTG}R5itRnQC<* z4t?zN&09O^%tCEsgahO?AjX z!&nnKg;uLVm?uba9dO9lfVQB1K1cR|){rTmO_+H$+#k^E{Ze&hlF5ddB0xW55OzS( zN!BIA$YUflxXi!Rl3J`zL?*DZR<(jy=AE1D-Z6+V_xJZ48|;7WG=ChF>;*64tat(J zR{G$;b#kfs>y4R|gYbh02a7=078-$W?g;%bB7cTRP6oeBh=Oqhbc=4| znA{$SkwL~Y*sO0`QVi=a0)piohOirAk4gfYs|beu)=E?Q2~}|`KZ>S{ zidHOUJ9%D9_aAj0+VX0;f5O1Y5w%`4(X(M3TcZoOVo`DtQ9&)yk<~0 z4JLr2zmpP35ezepq@F$2*Mzf7(h-=pwyh4gt5{2-Sv6rq9HZ=&N-=Gb z7o*ec1Dr*vR-Nb_(_Nj^Qy3{YMz_}G#|O#`QKeWmHlTqDRVTymAy@(9>wP{5Y~r~5 zW3S0g0Ftcj*{H0#L}GwpbZ?CyStRkhFlxtd!ws-UJKTZeU(lg-+z1Cs`dh! z;+!~?JOxah$$&(7Tx;?NXe!J?<#Y!v5Yie_nT2Ad`UDwEv-Q;Sv$o};33Q`q?zZ-y zp1>vJAR&)Iu60KEu(RBE(uwJ@ic^Z{)KG+{mqG3;?(*VzzQk74=B2q?6d-0S&X%56iDHc#*ooQ)k5 z<|gJ6i$?e%OI#|;jcc6}#d(_RfL2@($koPkxo?_VQD}mtz`AljjU49(*cJ%|EAxtI zwP1}H{W)zzG2)y{Of#T;6Dipj{8R68HY~cC_^TcSi#3U8AZY z%?M_7ydf)SzlXIg{lUny?Q$o;^-q2+-=V=P3abe)&0-G+yKv*Vtz~nD$K&LR!eMH4 zw;I=5`eb&H<|$eT7kbEd&SirBe67wBrG;lFp$lA|aycOgIYJx{Kpd02{}SiRJhuT` zS4pP!rYU2>2qG5x2v~q$*lm=d4R*^1MIxwG)Nli7-^NwORdMAbJlLQZ7frkMW+bjA zLyfNL(}vy8h5+-KM=N()QdGl$(PT7}*)ie*iUjfk4Z}=KG#N_{3Yu_L-@%fU>{AF) z4R(mYuc3W{TRAz=P{0c7`4C=T1hE6ab@9Gr z&2oeXj93X>ipy2wb~g@5L}}N!p3Z`Hzm@y})_j9i@9;%yy{edJ^3NM+>QLtl_FD@k z)dqd#3j#m&x>d*Qb?TZOw;++YlLlioD(CU}O+4+AJ)PQ;iL?(ARWww)n+F*1J!@*> zciL8NdJ7H^Ux9I{F$G+#%ifHQW)%#(+u(|^ADVVq%^w&>TKTf)HDcPZo3JF0K=LUT zUXjBK^3vYNMICSH?J) zm9u-7g_}E;Y5GNJ2FHxnQnYIbuxSt~&6-l9@Zcbz=Ab)4`p0FA*}Kznk`1nN!yp~D4}5Gzy-tEssT!HViOsWXBlBM1>Aj|VF=&*!NT>HLLdgg zQ4Gr&u~#7LbQ;tnC804yh2bwYcCL75Si9PCl@Re@7zqWIe;Fq;KEzzv99F=1UJ#UL zgY%QusgZ*a^JapWwnMLgS;^*s_^|t4xVa*M$fBVm{}}k#yih)<+rOF%erlg?bAE4I z&{8udy$cv&Lf_l!@mNJ{&SegsYlBFmK}a2P4rk_%q8vov0Th(qVK1GqP)K9Jjzy7Q zFEd`w#GIiVE89{27Q>rb^wnW#D>ouy8hFUd@xFM{q2#*oYQ3D=laRUTcCUxR&twA77rJ!xTDfVDhFwSU`h}{d-SH^@)Kip{O`rUjQP7n?`{4B zF5(4dw7KnovJ$twxHe|4uqyFQ>yp-|juRCkot%0Y#v9`h#TGhKs|K^PNEE7u91Q`a z8;9q?Q+k4*Qhx zf;HaiBf-Z4Sx#Xj3w&COf?km4%8-inD0icP2t=`Mk7ZYMi{xEd%OQzM<*>z1e(Q3t zYSme#-Z62nF2$fnjKO3CjNrgFa~qk2`HH$3=q?9Pi}JljhbhPw%q$=&$En+(f$<{O z0ZquwEyxr8L@O+u3;EQwq#sBmks>t zd-AclLzDnK_Gzl7=ZA16L%t_cPlCb&*iRGM?VJFbd2QNw;mEeE@t{mIHxnL>Wuw%{ zYX3ri3rBhU$u^_{6_4P}h;Gamu%oFt_njIuCA%Z&?bdMve)d+7xGePLAsbHrz+y!r zKyd(6I*LZDJQ?CJL6QTW0yOmo?EWlvg++^bhct6LXErR@cwCA{cAHd(&Z8^jh6Kw| zuPP3lDRDWM<>1sZ57pUIvnU=|rOOIAO5ahy22>L8Z3Kq-asRrBZDWXripEcFKr0@F zJtS2DgIAd|tE?oJ$K17Z^JOwJuMGg=KO2F4wHGI0MYG@*n`?(+0XVxaFvIoZY@e6- zgqb@VF@KpmP_&+tsO*89sz4DwQELPwPO!RfMoy z@x*sbEn4#U>J@TYRAQ$0REc9pARTbO=ca<$Bp#|pR%);Sz(jZuLYjX3O|0*eNM zs1PPa^L)99^Q1HAIc0VcUyD0Cf4&K0eEDXtYngS=e+~+{B!juX1m5!gC6R>UeD7z5 zGQ7rP*648L)rku05;AY1mj5eo^}-%TTe_5TngV#;=KZT(yo=%?hA$R-dKd{+Fu=J| zhmQmweJ@li3J+4@;wnr?KIKs?>DC+u{8xHPN7{9zN)N22i92%ZeQg*XHRPUrFHvNl z%+b>=ckyfWP|XZ!)830ZCJxSDcz{Jiic^%-bZmr#Uub)p&#&mUEbm90ckrM)&rh<{z|^n)kufndZ>^pd^47{NyokDP{Z4OR_npo8iQOIxA#Eu(suBqFnzB@rFDbqDmLKqyykqPEP5Ri5gI`jGqxn|?L@D*s~3c%y8 ziB!I%N2s^k%tf|RTe;ufMex$##a-E64w_uroD|vJTpw;8o^QJj_mA&$xKh5H6S+v+ zNle_>@acez{N4n`KxRWKCV}`#l4OS2cR@}?lww8Il%WAC)x(5ILg1kWP{BVI3*B*= z+cQi?&|F(J9;owu8uTmETRN4XD%tQ7e8lhIc_t=)rWIj<7#2!;M7PS6zsagd?3%~JU69~yC*|9pEZ@Qeh{ zYqz%iCb$ofv0*tA;Dp4;W(nhB;Z|7}+CU%E3WFULdVWgwP}d5;vfg{$L`m7lm-uN^ zWsCYEY(|BE!Uwqft1{GY-q6}Cx-aHo%{~&^n8)|0I)0AOkpa$ciCSYiWGEvq_(U}P z@`a~X-bfSzHTClIJ~40=5@;+x2_kcNLEqeA{0LRO1b0XNXpv2r6X+FT2HvXrQlH)c z1^lm3`ks#`BvNdxvG;Grc4qzNC__~^Hmfhfib1%SUPJ^yV=bCJ*TIVw^5Y$!$gj=A zfC`#W(KazK8ZVRXflR-W@r)QZSfyE^1t6Rd$nfuie;8m)C;k`mvM(2pj@My@K#GD5 zBZjMorbSi)<*#|Uk4MKAd>$3FOGE+ZElmMZHud1U7bBUA7_`4Ptojm+}MH63AU!fF_EMy;TQy9y28){)Gh zSorwB#0fUoP+GaVViV_Vla#g>MQS6Ng1egjT+C8`{Uj$y$D=_I?4oB`iRdYUdz{d^ z;BU!sVZqkWeOZ2D!@tH^6)foF+?Yfn0Zo6x0uhwJj>N-^2+yrVQ&&U2BY^hLus0S% z#ikuBsPFOv2J_+Y;%!)&vZoXNHcgVl2)r4w}S#(276g4cnzWfQV$+bp%S%(*$WxEvv=2B2U^l3)ZpLMKr3zDr zH8l>=mJev4%~66Q!^C$J=!>~Amdg@3hw+-P+=LlU?8iWli;X;(@=BPDmHRO5z$&AL zRFHD`RFea=rrMxcQj)*k$0q`VySKlyzXM^`)*LbiM#ckUp@QbhBVA7^n|j8RqSg%G zs(%EQBgawy)QHYLh9lz!2eCk0>0j-Sqec;OaJj=11xGm2br@ar9D?dB44QoJrJ*zSupA)u5xTSyUzdtgPwl(N> zTe_%j&ZwUJg=wZydOw!MsT`EOpss&8xw(GY+S<#=rT^6)T7 zAnDnNJ38dLW`H~921L}cO8YCB3^3iNW|X=~5ww@?_=-Rq*@M03@v7brbpx*ZysNeR zYfY=tD^$o`w5&o^`0$YDM(U}K6szAVbAH4upVS?O1<>p>giJ-3RcXItj)6d~Sp05P zwsh+SWS8YDc(V3@#n!GEmRYolFM4UYSR_K&(O%W(w?lMJk!(d8gh+Kwcfr97ixqn4 zvm*Hcgs*1g%J4{8kIniNTpb{_m-r#J^2aQXw@{49Z)!bM@gcx6yWn2jJQLymVeZUE z|0n0KM}6{K82%&{r zv7-EoWAz^t5bt8)2@jjGP-#YLZ~ElV3Qb=E2$m64Eu{SlD%*E_3ptsw6GI2 z$WEE{tXzm_`=w6}Ymsc^`G0ME2|BXS;;D4VriI%EHG=?2$kk^D5ys!-%%4pMQLwp| z#nE%}*$PD?$s_v#Zhp$D^qhtwzn&xoCDK}|D`-eKpY3TK1!_^yaa|%J3Ti@=pk!!g zjtqO4$*ZYyLp1Q&9xxkHk}Uqk7-0x-w$`*)@M<>hWfG5fad?1fWUFBcmn>A_e{#F# zocD+o%;9g-Q97{xyvyl=EaB@F=Nax z-^`~8L`SCysxp51yn(X8n2HA_w(xTLG{H5+sIjk)fJy8OXKco`9p3&#h%ED1vu#S1(`IglRCIL3U`g+ZL|&N|SCqz9(AI^tyQnHFw+ zouNBLovoSF&OTdog_8QywPn-}^*uD51i2S^^(Tnen(FM)xn3G;R8iOiJN)7B%@xsq zd|lYpzsZ2$PwSjc-c)Pgkl}cjCwaE_GwnX3o(X8xz?eIj*_nHMi>!f+AJuE4!If2aSb)LBz6D4{RIB&n^AqANej z$TuoaY!1szYPMuu`26!~$Z#UuD95pZM=KmTQTe2+*zEhku=|%^Y{+tF$dZcv(si1x zsi`^M?m9Q9mwTLiOg$K?PR-8?^>qfGdm)uug&*ETy}k<(I>9pG&+V`%da+{lC^#cR zz=7PXPsHPm;?%-j<6_eL^>1^Vmz~@EuoB!oe06JQo6F|#A;t_&d0<60Wo2q*ACIHB zqVxA1S7gRRb7F&$35|RbsBl9QsO7~-u8Ki0lOql?41c#?(tI<5( zi$|+ugbk60h+Fi)L{%a=c3Car ziDG>o=#|^3Fr@u?TLPcnycmZ2VIKfTFhJcHl4SiIwe;=BBM`ph{pwuvI3qpF;?pGx zb(?$YSu$3+7T*K{2-9RyphcO51*qu0pZZ^mVS|wRI)6op_jQ{9R+}6P4Zf)pbt@q; zDHY2VJjCkRl zZ8UlSyZ(P9b$I%udleO>)WR@J1-Y)!z5>}a^Ri)7jR4=-95)h>8k6fiH0VsA_L0d@ zN|(fN_hkBa)a<^fNwi>zy(p}qBI&_ne{t^vy2WIcH@>%AltgS~@CR}@m z8(ZDDRejfcVp4rYxfD+f4Khyj^=`f740KKx=~^$sa~SGa)EhqyKz6a_K3#!AzW{^! z(F>rzIol3%s9&jeqof;lb0}Yt%LC*#R(-R*z2uNTlV4o9RbNQ@a|Mt{5QDbbds(nv zE%8qFVX!6P#y=Rj!aw-@L8uY$%`-dl?~Md4H#utuv7|AnUBGXa%d|R4OK5Czc~pG4 zXX<4(*=1zfu08!&8QTQqvP030s1jJvy5@}q!=KmHyzy00(%T@!cczHSbs|6$Xai@) zG<$==i?pqyNmSs3{Epd`xlWzD6sf|dN8tzYCXGVT4VCXuGb!O0BX6;=6$P67pwKl{ zpj0lrgrQLxvj2Gh;}tJw)ZsA1GTUyJ`&!)=%?|X<2f#>1krXs78& zJ-bTF>V28qK~uRi+#{2Uytfs+-g=8Et#%afweN10pRKR9_LJ`XZU=Ze|1P4^XD$11 zJjjujwmH0HarH&b;zy@!^=Hr5Y|+y~&I#i|VjE)4$vevqC*}pG_)MHd_Nf>7g(Zr#;z4q-It!smCwaFXYQBcilvthv~=SJW>g_VQ6-g zYbsPNdRi9p~=pfqfnKeSERC7GozskaD;3! zZq|j-up8}uJ?ga&F?(zlcU0Ug$tz24#A(5L(rP3-X0}bn(!^u#jYaj(>savWA<+uT zpH_*0A>=lqHr<%WoJ$&r^)rDcwcS=0Cry#|f(-q%>F(&za!pwKVf=bMviTA>`2qgu zKMqy|q8=HM@4ie!S32rwAr1nisTAfb@>5TVBprDExI+2Vp2I)#z`J}NR=nmZU_e>L zc`v-HgHPSt6x#yAX&Cgd8#Z?&Y>onyLkNF6O3z&c`1$v|BYYQMI* zow?Z_05XM@$FS$NB})6NSOPN}9vaY<^v%U6u0*A(|CYxP6^VeX&(o|`H%8Qax-{`; zI7f2cQDh}j6ac&|)Q+79_8(ap8z)KYf;>`pBnSzA%~)b%3%UZLAvWM!uSF!bZArL2 zB7RiU29|mvp@yrmQt=jphA8_*sL0Y$fGJn4tBY=KoV;E<&sRPcRZUvPvy<#(8=#+g zZay*6biyexiZ{&+stp=rdf`!*IYUZJ0Ds;^hfOb-jg52;>`ecKkFsN9#|Ex2dyg_O`!68BoHfOfY1N#f;UIz1Oxv> ztmdWsF@%koo7T09sS1Ef8B8fi=cvZp5-fJT%8y@$$;hV?HL}Nf{^!Wu(hu1ZwcDDE;}!?1E-Nr$AxR^#17{dYmzhP2(9 z3&wa_iz9-1Wh7U^!grh!$>_OIEMvy!k=&d;P*tHnJ$S9PGAWwj!@*cOV(oa)pg@NU zIs&J4uHJyB=;AE!ccz4qvnlOC9u_Qr%a;xCtCG#iUYh6H4eaB8q`bZRfC2oBsaUj zTvXdOc#8>~zZn)n5tkuf;aqsE*T9~2p?c*-IrZ_Pb`k)}Bnbe)cP#e{pQcr`F#H|I z93v@*F$vZw>HTJ#wD`b0o#7??9xW@*6lXZk>as)UWm@Y=q$RSceI1kABTnqP>F~O# zLGq8dmdV!rbRkh=K*<5Nvc$L`3lh9~2o2)K3z(J$0q<7e^RGK*)O z3_(yky_(BB%5{eSk5VVu1M`0czyNjAl!>vf*WdZR0 zvS2-j7ik9CS<*fPz0~H8yMM4&K#Y<1&##@@CJNdaI0c?7D3ouyN@Jgsvf7!lwAl>| z{(Wwxa#(+_cAV5hmPRj_;s8IGFFS6VXFS=*JQ;b1?2NeHg1B49Z)N$gH9=4zUIjGP zhP>Ss=vX}u;vVpqP!YsNpmbVBvay}Sd1*Ct|Mb#TNIJaeuY#sVndK5?W zmfyFc5&2I|&_;-gBGZ_-dGtB+nopeMLYi@#^zYxdP0&tT4v--By6r1*rrayCncY6zu^K54jBDTpsJ^mbFV zZZ;(nW;^n{czJf(n~+TW?$Bzxn`YxqK;RuLG1RsG8f8Ect|^cokRrRcmDPf(82C ziHx8cf(;dC*B9&198Pgw5Z%RvD`FN_1YBGgM|$<`R=Nabg^u^FZn-^im3fAeJ zHINtE7(M@crNE##AGdX|L}aeRj1{9r?94k7h&ZF>9N0$sV&!Tpmb_%(z8W#$ze86p zLS>41RCNlC9h58I(3Cz{n-_d76;g3oISfb=Muina1wSN(wTxnwuwls23vL_G>K4RB z&uI}4JeLre@E!L~31%kJFG-Ea91~HOK~=j3s~=Z$7?>SRt*Zj|Cn{Y3kFGp6A#C@S z5L5t-giF@saAkssf$%CX&PU*ZsYP{5QHwvyt&dtY8t+Serj^m_V3nIr(tY_qR*v2! z2Z2`$@pE5xh-~{_kxnSpNAe;_^jz`-+0fyTIDaMXZuh%_GTJZf^UM{jw;-oG9#di3 z5aIJYnHxHQODMWIa+dJYHmpMVC$lKLKb@_p9uW84taOO%`0uBj4nqO@5R;M0cO~Kh z4$mD>@1Ix|{i*=hq)Hh%`tTZ@e$A@<-l7)d z2s=eIr%==U7$nQK=R|k6>Z`U5_YK;W_N{cy9}Kg)49KMHXZ+`Z=`b4RHK{FBJw@)0 zwW(80ZY18-Y~?KaZVQ^zk>zjgo73|ujH?G{gl=x)@(WTV$$0|y*raSx6$54O9kQZ; znc^vZ^K$+nfl5Nk{4K9oi4BlRvFM*VHE#$Mgdk_ftnAw@;V&0Cd_C6@ZK);RMAgN9 zLO#t7YPk|h>m{Xt;+$M3>(5i`HlIKTi66(x{aDqVYu`C`j*> z=?9xcQSC#cwmaTjdUd9^`NG@s8|C2o=2~AK&0||Ca_A5+pYY#N228!x@8=Em)d(EA z2CshBtbk|$iP9y7_Uj`z#8aX z0!cD|T;kiJma|83{@%rulk673Y=I4Qdj=Z-%dYrcVfu(Apa_Mk-nr*_L>^UR4&bWk zj;kSC>S}@iuz~H5(33n1m)}#bow=Cn&IQdo^4X~I^7Z7s;toLL8NdB!2Vp36GsD1L zqAwjF`N3PPu*2VQJk%{BcpGo3((~Uc zn(R6xr66p%{Q)JEp?W5N_3TwWyqFwbr#Upbc*jyIl?H%5aHt)$7 z0;Y@?L@xPZ)TWpHf3z#cVL%%U4qVg9Z3`NqO7TR{H(4hq&0e~sVqxUlFwwue*#7lC zUzC1To#hO@($8atoIG=hoqfyq@Fo4g<4r8o4dPQ?Fy&9oqJ5@^#3N4~UXn^1QpwTA z_jM{gbk59`xH}d#P4>TrY;w#vE)$%D=OUeD(R=NRa0)2N`4p$$v%3PO@J6;xzi!Ui z5Q2qK%cZWrWuix(_!eyCn!S*%m*$u;n7lHs!s(lc4UCXEoThZ$Dpla?eNQ!XV#!9D2zyz&*N8K9?x@<+p)7w9GP^q!3TFo z+S*tfi%lg}Y=ze;+D->aYjmrQ9hXt`38FX`0P3=oMcWx5UDFF5w7*2~qUi3-vceB3 z?nG{Bx&7Spj1cq}PDum$g3f*v1|*Cyc;ZEQ$;^#3ZXc`GG!Or>V&0rpcy^rU)HKkK z<_f5;tNh?3sSvp$LCZ~D#;HEcVJR;YF~S5F&RRNZOG#eaPFLsJqv?gL zkduWTpRZ2s10WpH3#WhEb<78s|6!V9!h2l0Yr|Jj$0p!U_rNkis})m|73yVy3TP9IHXlQ%YeZHNp>TvNJ2yLR9)E0JsU9#0LLvD%$0!=uzZ3rqpO0f3 zbd8P)jYh((WItNRem=WJphFK!9m1ZVLfUT{dPy%bpg~ZaXftab!-c9D*froDGVk>p zX)5FX5LCeJgG;sAugR#Jmso>avsruD%0rKeTkk`B+m0mi4f9ZD=b1jf8(+9GK~7e8 zLvIxUNhDAg0mLnINcKH?Q3=aX>4}wOCrLI>mmN_A@1lMAS|LMKh7YI@ZpQi@*u58G zgc(IojhXH1L;!5|lZLwf!Kz3AsUbw|XpwR|8M-`*UGyWPo+{ zxUQE3mh_^5=aevkS}+IWbPZT-Pc<%`hNfX0RB>59CzG36hYh0$L7O=-Irge2b3ZJa z^AB%MyMT7@cTcsMAW7l-Bi`)P$Q}wqdSjDDH4%pv$8v;NSNu_JYT|=$nHkFU5Sh_f zB4EA}UsFF`9$yk*2XMR|WIOl{ zETbe$L9P z*tMfjw+Z2@HGdAG`z(D04(tM5<{Mrz4bn%jer3!KD*}Mwhyc(XZtissZq8MkYu=4D zu5JIpTo_~~2EYvv&fi6~{rY~}1jpsEUO{WHvSaS%YOagaJl+ff>-+=BhcRh2G;QOU zlCLFmRu^!>Vx~F^B!77r7GFS)cm&+#kV(-X-hRxCChFen_hL42RSs_ve|Hl@ zN$Y_>BQ=~5{B)ablP(XxoS!glhEi-5e@}25#r>$XNXO~Q=$wkvW7P;ry5b>w#T}}% zEnYmsre)PUU7x|^c+EI5l_N3pB~sP%l?)lHF5#XM&(>w#VV`X?*0OnBov{tgvvlX+MM3-N_b^-r!9Am)PJ}g`@HkDWO8}JJ9N5fXJgsYq6 zTjZa(jSed8dm~%h>$BWa@g0{7`voF1lfZ@j;#zBUq5L%r3$a^ z0g-0)>3tUhR<|H~W>_TG;?1I7iBjQ8PXb0X3F$D4!Fe))EfTP*wpa$W>}F|V&>6z( zgGNhhFg;L{Kx`4VR-u%NT;*|YPmH3~4@HU{4~88THMdwPYo>t1ZH~4<0lLMmUO7Wt zc*J$Qx2;ncM|VTdx&!!!C20nvq=D45j(LvZ5pNhk(b-GD!A#+gW~C&P1PMFPB+GmI zX|T7$kcZFpt6!@+iX)hm}WtIZ*-P_p1frUp_*{0%sSlLsWu`|XKgMPbi|{Im$@l(}g3X4XB&Dq@qS|j1B_f~H z-%Aiv6gTh~CpCr2XBmWs7SaCX-hAeW%B!YA!VC_67}m`R?xi;goHoeyo6QLfV+YS?tAYBPL8 zZbTuC9rCEot^R3J_L&gyWukEiQQ}5j16-$c3E!FTMfg1{aKHDH;6tv4ek}lgkyh%@ zc-4Kpe@~uomI&35Ay}*P4NlEL;YK-dwh95u=Fgwf_pf{(-?E<_?!{>bw%J)dT;xidB8?=g^1gH`35V-2zUJuZj^c5%sl+>! zb{gnG;y~8LT)Zp2=rte=?>(;}|95gJY>q4|jQxk*Rp|!eA#uH$2GBZMjL-m_8I)PH zmey*;ZM)=mtLJzj*4t(7EweAV(hEq5O=jtJxZF0p{rPTR*JR%|>?Qg}cJIX$jkx62Ju>^+YDoKf*^ShtI=Z=j(o8 zmFy2W9ydSGm`}itks?Dgl>3A&8$289pROmb()M2gQ!KwxR#|-)$hA^HGsK!Ez743h zsb%7TA_oiqvr;;8kmKNA@{sYS47_Jgul$H7O18SB%M_OkGr@ zK$qItmO9veIQ*8oKh&naHx)lnTDFPBHoYsqpQya@^)Es}fE1)?{Ny@@@&eCZ|)(W_?cxA6G zl9&1}<`fo8M?WYI&G46Ox3%auzd*QZY#JN;CShLX!@ll%dy$i4Kib^6ZrRJ)b*B%S}hI6)lL} z|2tiH4<2pJQCm`CnyU78zj&XfyML1CAR!SrC)vYH(t)~`0)QOe_RPpU;(rAGmsUiQ0gw)-QjB98V|CwbAx?c=-^zbt=X6w z{e?4q1%c&Uo}ZbGeP6&vinm$;v~A!QClNFu7qK~MMw#Npd&G4-)OZzRQscaQBFPA| zHd+%U4#)8+u@e=xvW1O$PIZdu%VidV%o-d^jm-b8k!tLF^pSt; zVw9`>6oBROPl6~&z;@_Pl6~%s9u(j^vmG}?W{@~5H$xlWh^}TBG*W1rX(BWFXb_Vl!9DS_YzzM)UKLam{Z2QzVelaa;MJ+Dx(Kgt9K|C!08-V5}a#1)D zK;q^zX4h@N*2ez|vrh4UaQ~+F#A5Aj-?{)ZZYkj>mcxe*bdm{NOT>919p-?v|5wSE z1(NQ9FrVa2v;xq9?NZBow0WHHkiC)h!e?jWIQ*g=_(A;fJ=Vk5@Y5N4Nlo$|ioceg z{QVSrS!FWI*+7;&&fU<+=*zgWYj*Ogf0HU*^Lry1mVN=v<3GnJe%TKpyf@BSM)>Rx zI~vO>r`2*u4$1jb-V|r5=2Fzl6NtV!+?C9`wv=NQ(Z@f8kjrkeKi377n+uSPl?m)Z z>dB7YHAxjA4sx5@$gM9!)k2b=cMj!>vwA`VEFy`bzAO%dJOtH2AC7n5+Fg9;Ot(k5Py7#Jx$%1M#wO1U8R_op zTGGey@8A>uo4Nm9fY4sVp1u^keU*3cmww9={H2ANHO*6+3$NsH1D z6nZ|qSGhvM8_sgz4+S75WaQ-n==v^Vq&slOnQ@Uq6Zb}sH~l=EFvfQ>&V$9;zMJc4 zHE6bpzv3HypqV1|-qwP29eeR{@c!K#c-`pjvGQ?T z;h6_322YEch%6BG=Za_TfQgFkjox7n65OX(0bgveqiam;$v;$C5IpX8y4^8GGqM4D zr5aad7sOhF#+)Es>4t{*CwS(^b8_q@CH_Ab)xn%jdcVa^;`&R`vtB;g@8>_uDe>r5 z6{~21i05tj_w?T*pSJ@>XGT0GwPQ-{@+;|vNfY(7el+LXB#zMe-OIB$ht6zPgcNi4 zVDCv;5@w~5MdCJ9IREJ74%U{h@x1AQ}MCS!O!ofdKHwAf1*%gZ0YMDU%C= zd@C0%oL>ch=%9J`E)8`2)OM&?xzDjWeZgd^L56#n*?#d~4 z4>Ax%Mte#2;*u~UdA$#+dOiF5o0maJ!zS#4Br^!klcuq zaO{WOrcADKs&u-jko?G%si)R#e8iDo#Wj*`M%ZKrefvG;qmA?I1h~p!DbmJ^@DLB8 zy`1nSGUES~pWxwPZ{=Zc;}8>Xc;Bf!>`jeqyJ1g|y*JnRxmH(KJRe3s$L3QM@2sEGYw@=&yolEk0IcoR;sN?$~#9`Ni~g#ATeaUy`95> zP>z)Txx-B3wQXH+c2kn{^RYHN#-lzr`|!q2V=Ll||J#;9QqBwg0L38jc=Y}6|5mHx z92SEPDORc^07v2_b~=oTax%A&iw9jr1z~hX31A5>a`fM@5TcgmpG%zyMHt9w$FYA< z6O*^XMW;M0v+rF}NnVkh<%%B}?>o{w1Vz)re9VS^j_sl?;t=vm)cxXR%Q$8V?H{hm z6h+gyawHBul+I$glK0Qr`BJZEi$5GGMp%7k#+kokb7T&Za4JbZrKFBXf*0zLflA1UZhO}&7~rb-%ssgr0KhXOjfA- z^{RaKzN+z%=bji+gqfnbkZO9 z<~G_6xvIWT9b2C#aFL)j=)&Sjs)m0+!=gk7^H>`88Ary9Z;c%X+L8x%O>ooyCa(Ks zAg$mbXfJ)AN7R@*Dn(=_WD*67b`f_n{4Fxxm42F$&ZSMj$r3+E-u?{n*KC*P(_sy; zHxgunCsqgV(u4>Hk*S{%2ii_Hzc^T%g+vp~0iR5aI_bB6xINuH%zGQqe5po5td{luxHz>QG$wHl5Bi|(&EFdn$_lGq zO7FLc1n+5W^cq6!J&o0(7sjH;x5Y`+v-86KDmecxQ%N;ZL9t&he8{UUq~B=swVR?))fHdm zS@*6^Xm6#bMO=cWI%2HIu|V{3*<03i`dGa&td+$EPApb? zRs#<7Vu}C{mfai3^GKBwAkVh4mXr(t&2Om45VX05 zujZh#Qo?&}_qjBQ@?&?;{+wemiet2jpt-_@_N9Rk4iI4?`dNvhnczkQLa5W)!tLyv=vZuG)d+!D7~`!A(}JnD zwq8Blg5?GZ<6O>`-1qwBh5`9JJ!9(HfA zpLd-PEv|OaK;pSex*Qah^L@6U*?GnLXN8UqI1KNe_THaw_qr6 zVyKRiBEO0#U=4%N$PffPQoigFBm#(Bq#obp0cIqTE`MfJXx)>3*yl1i&bDgQ)avO! zAsPb<_$yv4;sR9^%732dbqncVQPq1;_T+V0{@{l(N%-&Gw@^=^h#XF3Ff7og`T0A+ zPwq!6ibBLf|Dxjl00#1CF$(7jq`L}I+2c}ls;$Zie01yx(^U8Ot&lI;Iyby)bj`jl}J&o=LRFjuZlQlUwTSBG=MQPLnpXHv!U;`_She0?u})Ugj) zo0$s`MsY}8@d3sYk{LRT22gsJeAPxIC*hM(Q*%&LePfY3i$c735t@AtagzFB#E8%$ z(kNa(CsyJ;M>!X?|A;JuElW5kGN*9Uer%0*?~UIsl*Y#P5b;=q4YCgC6c8OT)UfK(-Upts0BBY|xs4{u+ z$<_qiz}G?RT~(0bEuhgc>tY%rG%C;&J3pw6EwceiY}`K01n?GN89K>!B#VJZGgKy8 zIsX!1E{ozU&Aby$6 zX)~tt*ru9M)`W6X)dj&TRusBOKd6OIVXo4~B!$&zJv>QD`#mp#^(*@z3k*JW`tJak z17eD|^=<9A8s)VESXgSSBf)iz_frl07#hK&P)CuQ(Bj$tQg|edJ{KY|{~S94s-}n! zcuX_EF@V~Ly*lDz)M0@RI@?gx-}y(dTP5^sQns*2JMH@4uz$FywUNPsV)4Zb$2E*- z2R%2=>9)ZK13b#{mLsONc7>yhNUl2Kfe-rDknV-TawOO~sEm6ow{M1`$?b51q-o?U z1ORxz4td2sDa#`;G9;%zbT-2{G)OUpT}8MQH~vhXQM^q+ldlhcDDkF~&>7UVQSH{T zo4VPR9ZaE0u^jNAXbqI!CXq9g?<*s=U>Q;2Jga$vVg)3G!QErLcY5skum_?PdgK$d z0gA}ej_faX$9#8b4x6dl%6HvOb3iFGlAV)+71tc%|9*Dn01Qx#azQj?Vw9rTojQ}Q ziwt=A!wVN84ULP3bJJ6jZx+fdc^78%yqmZIJuTCWc9t`}DVE{ok+f&Ted}dAhL8OW zzTEqI+zQq(h6V98{Sj-MAETIGbM|XIW%3TNb=jU{QDh^j{~ zB*!{$A&~2$#9-1mcE#*FYonef!jYrmi>EhLtgkLMrL~{xZU9h6$U*~-gcE_A0W1Jc zl8n2}JwqVdAGr{&X%cr@t9HoXGE#F|Gk4kJ*9VO@`GA>~&4ynn4!81+NhxI=+bMpgRamm;D zotXtVxY3_SdQ)8{%p+H$5+)PHboIdG+v_BNobbG+v9z}ZI*x}-bkC9AOS%Nz9ttT zz;M^FQE%ovWH^)WU$azB*+e(E*=~c;W0(`NYB->TuLefzRgI3EOxZQgY2d3JpkL#V@_mB$AsPmU$h`>p0&L_|X@Y>cdYof>H!_)r5t2h46ZB0h{B!OV zukFCq&*74Np{lD*I=;j{Se$h3&D)Tusjezc`WW%1Kf54m7UzAt#7#m|oyOEWMcf@F z$DfP$V=>V@n*?Kq6Dk$<-(#{?aOj`*otMyezz~0819q&J18ge2Sof7XYYXn8Qao?1 z=d{rWe(Oj;?zNY(cdJ+}m`&|!stjX(Rjtp5yJ1j6WGb;fbkUp$+J^4%)V`6I-FK;B zEL?am^72;xfe+S&4WChn~N3vsXu+`1av+PDDw zc|IgKYzjZhJCXZk9D*`4Y7Nj_KKB<#p@)9(dd*&}ZSN9`*;N`h$A0`c5`drlm}gz{iRoi`3TPgfQL62+y(HmGI)?IdIt_w#S*bY+2MJ4gA05H zyRc|W=uSZwriRx|u#dd<|G^u64M{d(c1of}$Y z^tLeOoo^1N7q3h6Gg9IQvj>KLl6ATRJZDB1r@0v0J024J&wAaz+U?fJ?%wj=Ogz~C z0vza6U+X^{LiIT8W$j>ky4Rv|*=C!#$)76ft&epKf^-t;G*UOt{#=hDL?>9XKxMRP@Hfxg8>Qb+I!s;z4Rl>8uCPLKC z?pytHN0D*YncZMH=Z3|tvtTu!QQRUU%!!#pdw;7-DSRlhSFM8@=+Onj+83%J_>%uG zs$p@0-0o59i{=}A(doaW2BZe1TIZ6L(#WTGb92FnYbTa_lGDVJu zx3G%xAF!aV{|z-b;VbtR-jk)T|6feQpHp2`I206NEXgl8666?Coys-O!DmDzGik#A z78*`%5U+Ng!Fjdvap3`UY%R~#aNWP4H+QDMFW!ks!m&kexys?95gjUlPNLv)y?Odc)5;2{(KLq0;8?B1M1t|4(ipCKEKh zlL^=m&`Nlw)OG)l+&~CYg4~&a*|`o-6rS0jpRBf1ag@;QIpe^9J~u&T#ZP4c3V%5@ zRY_lRHs$8mLpBj0JTHF?^7bf1LjD{VNO0-pBX^}=z)iR32|5h)H6k|&KV?bPv+yXC zP^>?n^k*>N*Uoue+VmNi8u!IGD!F#=pv*hO$f1z9_7P+tUoG6Rjkph*;pCLt~CyRDe4 zd1o|g@wc1*7HM1&f)B+qvxOeR#aduVq!WL>_)p8ge~^U&@YEm4PZg&M`y?I%hj<$n z@hVFZTJHsa_LC|iE3*bR7={YNF)$GzHy|5UaqtY_G2O7}!%cBK3R6=S3Lj{TW~F=S zoAge+qe~EyIGdvRW$6@V_#*@>KD>xN};rQMiVEG5>xefc}AiVnE=aOXYguGNT!KiF1bg-OTd! zxF>7@4dQWVYz`MYOLAx}sgl5y0u-ri-z!e7{y)eHQRGV?&yE@w%TvSCzfNIDOQ#RWHTgME z*>~)*Rt1`~)HP8BZ~WO_nUTqX^_AM;WWi$1_*hu47>qO&uNMl=B$N0upZ(Kbims#i zer*34ks^!wx928h4jo<{{~uMB%XsKc%`)Zv2*!#tDb7v6Ef(3Z(YbV+^-y?MPCzY8 z&oQ39*Z%Ccug2N_&cRG)tYd@uHN=Mmh}1q_F~|a`j)Ag)%;Mifp%vM}J-A|?{*;PL*c*~%nS5S55u%ei<2P%_pns3A90 z{6tAA(;9)FB9T#1E>j|kyAH`;1*PT=CQc9+a8K%gQh>cRXHrb#JQIbGKz;q={dINJ z&9^&<NQo$sCXE z9A;x$suPExeF<8oOZWc*Iuq&Tv_!bb4({n@pX%s%-@gNo-ATk5L6{NvRvG5tmLuzl zSmGYnXh57Ib3(saMkI*Z8HOa~e(pYR?Gj^f3>^NYUnD~ei=B4`IZ8hl(Z-G9(X+@V zNE6YqK1w8hPh0?b;}z($`-3=1Zi)@Lb<>V((>e@DTANoJB`)0!!*klikF;QLKBn9V zXSS_tFkU3+9i0h$>l8sw+w?-BKP>aBfX_@Xkj(d?raS%7wQl9Rp|`-;>S4*34UTCV zIm8@>yzCY-XyEkoX3eLan8)d((Xcq!vl#3NGTR|65pyKfCYE3{{<{? z{U2aqHNspoX8h<>Tpe84e+_Pq12})?Heig3fAKYkVxZ_eX|6|Lx8lUp8zXL}ZE|Rw ze2OsCPh2BK-T!z$6BYUokpUX#^V;?HO#QuBH5O0wyRKH9iyz%+!qx>rZS=4Nu}DIS zJa#?Jsr%$V924<)&e!%49gnfDKR#zfkix=R8AI)xQRj8C7wESizlVI4d~SKS*{A`* z9UixNJshiD{XY?p1FpZ}7ZzSN+~^N)5Bx(z2>c9^JL2q{$GN9zA?ikNX*s=mr~78~ zJ7oI}AM`~@?YNB2x?I?K^h6F^H4FG&p|zcFmDK`pdhaR*#PDFp30%!!wekR5)Dr}$ zKQ3_AT|tTd*@y*ThPIzH$2&7twaz>6eWLy}av3GeHUDLwsC2eyiT#hIxx-3!tOb%L*VGAi4)anhl0QU&s@T711rCE+O|X6$>qy+&Y49 zmx&_3W0Bv-0ib2Mw-a5>B}vl>g{yn;530>zi8hv?_j+^FFOG~*Aq+xD&&MoD!C7MY zeE1`YPkq@ybTjnzxZscp!!g3WiI>WNFfdkJMUV{~o;MpOJ1-CMq4F(jhFf#O0uA;+ zGY-UZx!iUtA==0l?7f!D9q}PTPqgS*5CTsY&t#7Tk<>xToV?C90`93(E<}g%!6n{ToAoOQ+~j zX=YVlR(3^Hp!j(ZbwbU{2Cf@KVS{ea3K$q(#bS9=mDwnj8eO^_I1EZ*Z|kBwx)0O~ zAprILUN&FNwh1?7fx$>=4EVvqhH*F!nvf32FaMa~wj`uBWG)Qm{~%#hjjsNpxQvA& z3_8jS*JepWkm@hB<}{*9a>}ap&g3w{orpoC8Rp|$dA)N$OX$&-hYn7?<=hFJ6L7FD z3D}}*vU%9!b8-s*>NBCv;9{9UfgXS00RCQPjVKWcsqy4v63ez}GTKs<#of%r5#IU0 z0r}-0$zIUACui~WiLh?u9XeaDT-XZv+>8~k=TEwZbgK^Oz_jXxYL6SBDf_!L;diWw zsgDna4$&bUkYD~GxgiL#C?LfpgC?W{^27L4O&FYj?5shEp? z@NdBAUvh6f0mA?6zFfp@g$!>)b1LVJ zTD2-o#ba?kO(o3SfI&K3GKq6@dz)#}ei?!J~Q2-Wd{SdV}%2C9gQG`5<$NkV2r zm?Uf%X*8lyR4Y?aEt#^Ji@m6p)rwkPRm%_YUCV0zVuWbOFDZoW&I-oRu+(zgw%(v| zwm9y2(L1&D=n=N0_YS*{loFivdDh;*CcUP=yesx$33Cw72;k+7a4dk}nA}HY1_LUL zVHOJ2!qL|L(}S0glxzk*Ct&dsDh_jLjekgA!+AN)UWl+r_ynGaGH~eTVp&NQ$>d=nVv}_f0-QkuwpXA zA0}PQk?I`wr^$n=n2?4)CXQtgAeIAe{JxIgcjHfVe7ri*6%WMXkJ~HVpG03M05vS|{U0i`*AohW@c#0x< zKp-C+KdZC(#}|jySFc5Bx#!(90Vv7(Mvb+{9E&lXp?A?(hFbO+E*k8T_dBFrrTn?i znVyk+DLsYLy(66yb`2>QJ2gVdJuJgw1|%&u4F)oHq^TQmOIy8m)WGK;dLbw{`HbyI z+b|+DnvG#wqD4$m<(DgD0}yh2Y;P(GL&HD*o>wmQ^F#cJ1I3I`Em$P5?p8WsTc5mO zxY?Z6x}(A3J&8uJR?%QQ9E6b{OXQvVEC47GZ0tg8O7c~XEhZQ!a3zN}j|U`aniW|tXt^f4KtNwed`oGP$IzZ;Xf2x0VUL?Z;C^GDfc*&Zn zYQfqVWYvJHa17{LE7BMdwO47L3@miiWT@I^6I;b}%G%JiHS>8u8EcsK&OQ@$f;bA* z3C`l2xU&nqfa6Hq#BoV<-t(Vb8!b?#NO7@P^N z9-GZ08xuB|q@fAswq@Fy(Av}aa6H0nZ#IB#w0>)~+S|AJie?}2D?UBe>k_q~pO4kG z;zl8R9cHw=A^&cm>ed4h+#=RVG-{)g3EMxQ8RrOr(G2>wH4E;9e)F!p`EBEEd81N6 z%l48wCHF?Hj9G=_NKN^}Yf&X$0lF4l00vAY6(_>p0AIninWKvOX%r5c=8LRF$?5$Q zADZKH&5Q`x&KjD+3WkldMJ-Mpx3H8{r;YV_t!}VZZmo=pw5O$dy==5<6S}>L5~$&e z*=A&!3IZjJ@1hB8kA6-cPDRw;H61`j-?$4?)q+JS7&A`L`?YdS2Q!!AFmjBqr3nS1u#V2DF~=zL_eN5c;6Gof1VS5G$75NgX9-e4gs1N78rm zDW6O%J?qJZwN3Eg#=AD_GFr;xvIkIb#<4qxTPhlN(1u^#!qz;`8d?8#S|g2OLhfYL zTIFlCdY;fLDRep9-hu;H5H2EV(=@jx$!JwrfAbq@Fjt_K$^}%ah3lOLr@)FtBOb2W zG9X#$FJYVaLwq0QXnsLvd)wYnow7qd=Y=zxqFJx5QVc*Q9+oOjsmQ6a+O6Qqy6AjO- zC##z5ag#IFtx7wr1EzhAZt-_&>ayIog4_O++Btst2(>S z6TsFJ1wLUFBzE6~&c;buGyjR5o>qNw!lw;DqM$tpvG}5PmO#zNmJ~8tWxN&W+*V6$ zPX-R2a`NiCi9Q`}EQ%YB+ncIm++mi9JX3U>V_@$hO$v zPkadDLn$1&j%hykU6b7ZW)Eay9Ail!x+FJjx<8p_pa6U`EXhoTL_|JrCSAbe6I$-5 zXfINn=;>1$=uNuQ+ExK;dA_y^gH($yka!DU?@2x)C6XcL^wG|&Br?l)*rH@1s-!Id zCu*Fb&KV0OV+|cmiAf&oO2fOOqpig#RV|64#GOwxsBX=g9!7IpHbyAH7fIV_b_$`{+d zc%Yud0yG$5fFaxk0FX^Se zWG{7N1H;wI^IWUD38TAY$cU7cV;?tgk{ib;p=DjR5*xd3kyEyW6j9Rk44HL7p*r*g zr`?gTHRXY}!sk>#E>2L+dNl5P=r6HCFOCPtVjk5Cx)B`WLObhL>r1`uMJS37fI=at^D&C;M`aE+vlNfYZSmNn=UMHl@} z2RnO(D&6P+N*=__NJb%<>|ifMgCVqg2ssyrehIsP?@r`xfCoyRxYFd!uQV4S*&9Fi zTJPfFq>f+Xja9#pkzWRBt#<`ONu4LrG21F&KWsAVh*tcqAKBa;lrtZ<@Uc!mn2HQ3 zw@9SYjV!82kBfI=k}8~3$QFCH;+!krqBHr$fnE(pT3bzaTl`})T9FIqI z2KM1Yg|7GCd{c?-$K%!`QB-Zp9Zl?!HKiY+tIM|KU#4bh=;Qr`>)6<952Dzz2~x|$ zvB)1PBiYZ*oqX1jDZ|N5)Tws1drAJ%2yx{8=l<_c`Wv+dQ8#G$)#ciXw_1-$`Jn&B z>R4J{T6*~K;r}cxEiFHKw1&S+ORMs`w6wCkzWhH+>yK8~RvxV{tv-VM50@V<{f}Du zVl9~RH-=p}RO)}a{?L!6gpmL>_YY)|T z-_@7a>np2j`O(Je(gp-*wA9YcKo!*D-jlsj4gleQ%2F+EmDKWg-#x70zw7kxBl`C{ z%(#H^8b|&G=|YH9#H)TlT8bl*li2pUX!ETfcxbr^ZS5df@3y&UGk!`0LZyJve+YACnLuz=1((N)=izOokX6lRulBc(7q2>`xZkm%a7rig{db}20I|{yOF3IA2%Xi9`#=|R7Cr-Y z+X2keoo8^hT6}iAv-5L>GnK@}d1h(}yO~)5RX(|b6BMG>ElgDqrRSv&9K1R?e08#@Rkcd@NBe*IU*i0~=#5rLJiYb>k2*a6*Vfi1 zo&ReqYd{;UuRK~=dbs*#z>O-9CJ{X`@P^*S&>P@;0Wl0v`Vz{+{eN+# zguoo=ij^+8*4EhXGt25t11cV{F!L zDKktKS4(7t(`&=Ljsju@7$92Glnl?7wFj7peCBE?TjW7#GcN#s(DhiKHFjqUSO0!^ z-SyiSK55w^sIxOtK4YqEq({dFg-1y^h;5}zT6q-&x943CQSVbd@rUpHu73+L=i$&J zAq~>q9Eq13?0h(kYQ>`3_X8R;vck)DMtS_5%KBlPgSJ5u6uq*a`|JW9jh>>$1YX_C zI8M;R9$L+no}$v`5Ma0U{oEctS?kI;nFqoy93miO0gcdsjWL#kTT7k1*gaOq2hUD^ z-8$M)5Qg*mm))m3Photwjv)eixwZdP{knVd0#0rS|5NR}J|zDy2S;l6<>B7$&QpX0 z0FJiyPj+{XD++0XS5HwX%oN<)eYtx=u3#!q>5eXG6;sHuE~}S2N82wTX6woB-tNgi zsrF~PC;M3AGpKS)9c~?+>~6o>+d5K*uZ|86j(4yt^<3^j(CN4R4$8!ja>yEi0YHa! zWIJ}KhOH=Qzj>=zm@V(#S*&A=t}H9+yGQk&5_Us>{-xd+JT>tNlo zJ-?4`qx$G};77H~ACl2Q&&OChdeja=&WS$Y6q4vo95lQvFu@*Y*5y-`=9yZ{YbYi@U|KZOpg`vDF_&z2+sl#j4^!n9mXn&iWGn^DP@sH`#kI zh;eTC;>_4yn3e_j5E}uvJ}hlO6aN}_1Fx^zfJy)(=!qI3mlREN_Tjp@v9zR~zdWJR zq;igyY|*7MOZ|?}RSaBj0Ypu0lc^z70UJagg zCW3~C`a*NFaKU%RLO|BSzT`v0E(zo-B2>Hq&Q{f}iQk@T0@B>mb_ z#w!F;Eczm0AT%#?57_&+6Q@a3l_XJ1=3?-l#?F8IU-JCF9`#m${Ez-j{@?2I!~a=& zwDj=d+RCGc50~)#f3$pm{{Ja|6VCq?dZ=5iI1hL$Fj@C>!987YPZ!+N1%Db}@Ke}= zyKSH!;**T%hjl_<^`({i%0spEXk+COGE}B91sOG3a8#9T45C{6sFxQW6&ovgKJ@+m zHEI4cts$ieG3%9gtlpLrd&9?>1@%{bmnV z^CgY#LcOg1;q}!s|6ILH(2h_&70=HAZMVe_9mTStq?X(}z8<`yWVzE*3*Z6as#5(8ug z*-A%YG@S{eh$&Ud<%IueCUnteGQxi)Xm4%-2Oy}>7*rIqw{i;vtpOQh9@w{VC@w7_ z9}E2#LlqFjg|Mgsl(YNp(b6V_zGo2X+iwGej}>r%ZyRcL{UMYg-kICgphS5WzWo-n zVxEsV8@NE0*1#;q@HK3A3WK+rQ<^cRWIWM;Qa`9=RYEP6W#mM{gb&AfSmA7%2IWjW zx*&7-mN&6rby>l20Z5lJk*O5z;}B^rwwXBs__!l9tB>-Q)#G)Xv2Qh8V!M`Mr0hs! zt}@qE$G~jDDBbf3KjAMy|C35ow_A*eL6hiVZB@H)_w-MUyK z)k_Qgr`OoBsUdXXdaU<9&yi8P{r{elIDp{RpM$a(pJ5!?bc3e zBuK8QRkCy()BPd(NE?jL$@9i7){d7XQIK$MaN4@nB+3<)4-CzUM66A@D%}(m91~;A z=o3%3Kf)m;M~!5|c^r(q^Pnq)zdNmo=|f*;q%C3QDUV)BqkQgxX`=Yw!^MrSnCPVi zK;dNH%5sJIqCQhi;`_#+ONQ=u{2`umF!MtdFZc>epu*Lqj}v=_9V~J+FrsQWHddo! zqtYzLimEI$A-owWPk=D=vz;+qtwr*H;`hWEqt!@8QfG92X-4 zK`;!Oh{nABNIgB+Jwf3^x;UZM-bf5rS)R%xi4A7o7n?1kQ7-*9I6o8q!maGM$E7*~5p@OG=V1NthZc;bD)YG9pU zTHB1WF}s||Xe76f6`lpnZY=aeOT#&KM+Wo5`dT8bP77BA)CsPv=y69bdu@e8afho|Wcq0w>B>qpCurVY z70bn1PIq7OS3?>J48p3BkzlMKgW%4O;=H7pYRvZJF&obg4w4>XoRw%~mZShr&v%>L zi8E1aPq=|8E#YRdpN-v)Qw)70Ic_OP?K5H30r%Oa9FlP0-bN$8M+B(!g-+deI7SjA z>UwY@lN|_M6nQOhx{|>nQ3*xSCiIr4WFL~w-Es7GZD5QdY9@MEZ{b@3W%rPJDF#+-)50S$M1pxj2XYp zAXiWHq2+;K9HE*wpLP3r&7U9 zIqcj=yeq!1!x zk2y?yP<}y4Y+)eAhB&}{z%~Re)gRz`uN4a9_vR%sR>;vV)ypJMISxR%`a+%pFa9=2#J zf{LN72diMrmdZ~V6+=SRJ`Jk?2x|jwemYv24(JYeWmb#kMl6|t$P?4Gi%Gg>DZ(k& zwGaJTyd>!sORG*+x!!8jJjq1&TC-qNIdeH_#3$-kCiwrc3h5W*G0%|ySzbk*Kj#0h zudb5(@5AMld;b5Q@mEjD-O=pRlliLp?qPj-slN1`T3Xpyd$h5%oPIE;S3H37l;3Qd z&BMhKprh6>tl)K^kM2Aoc|p`~`H%_2@Oymnbi3I!FTPls9;~C1;@{i@I!&@NESB_} zcKl)wM~e8=2&F=<@A>{KyB^8aY;qt`iHWr30A4T++xM^8p#)qO^KBTjyn=iE2#Zm> z=uKb5o1US;;2RH5+6|6cXg0BoA{7j1<01x1&<<}TFBQ$^B1ED^wys|)ZE~@Uj+l`| zc-HU;cm`m`Cy0xx@6`(W##4(XrqO_?Z@$r4UheK698t!HC95Kb4rP+fjZxQS@hWwo@t zvAndgvSQJy9I}-}kXAf21e>C9W0wf*)cT?5FfX({zZdq=h7j8i+T_?i`Zj^Jv&gcj z<0eU?mMd!JxBNP=qIbanm(UDoQlQffTkn!By6{JBVq2jfJ*F#70y>Fg@Ttlnb>Lk% zg)q}X84}QeIX#`HQm)&JPK$ye<_+JmDJ6m*_tfMxM66K#EPlB###?m`t5`r*e}7TL zGBKXZF@1*>K?c|ZiKY8`6q`~7=;(Xj$Leipx^=up@lJtq-LP4 zW*8OX<=C0~Z2HU0D^4Stv2uG*tJQRY(GWTRt=?ctmrF7kK=7nT2NM6&B+LEZ7yO$* z|Bw4&wDzT#K-2j@%WKQ44>kYi(b^-l|MYNeZS|i1|1Ho*y5w*WmnQ#}lr~mKi z|9krXp8o%jX@^^96tk*V)OYLk<>mUycWU|J#`0tM{{;2$S(N{p#cxHTjR+^SNAFN^ z9NCR9k_pR-auPdeSlxFEbUNK}beV_)a=Mj>5~_|PCsT8s!5E4XZJQ`R9z_WP&txD9 zeW8OsYly7JM4{T{$AyK~T}?~6VgEu?!~%${(@SM@z#Alng(%IT52&D>hy>y@9`TAx z>}S!{7(edQXr`;Zns-dEG)0|}9&6Cq?DU3OmJ0}ssB`gQW3mjFhbc2zgT=vJ@YdJ5 zNrHRAy(xm5gV$~kohyacYWaf^S0wi+olh<^W=zg;%%^13+2Y%Rp5Khw*0Xkw2Uj9{ zcE*3hh0(0QxVqNmFbp$qc)W5f5EKD7Li@H0<@$bW>HwIFY-@Ns7)`$jP38b}=wUb` zHoT7W>Lh9|Owt7!_0rANk%Q}uNFtHq=m|@}$0MrgEP_;uDoc0-oyh23ikmQLxdAod zEVT~CxC4#SW|LPerFWtD&_sE#J8kdQUJ~egr)=7& zi&Ax;!UO9Eql;lU9wd+6ctr$ZYt*%R+QKn0i_c=BnR7OSi$+-^Z^RQR5$}R-cW{x! zMqRX}*q>v*nFS|9HiZ*6nFU9?XrW8gLcFb<#t^!2hbDnwJ z>$uv_j3uakuQQm#-d_3 z9$j{Kx|w>;x+6U()IoYNnH9jgc;2Zhu zXFZ?qams98zfGN0*Wf8S+HzrH0IO>?`dO>VUt4{Omp86ck1t|Y2Iu*c!;eC;M2~z# zL=Wsr|8Dg<%r(i%x1C;1tYkYS7Bjc%Sws} zXU15$%qa1dHiktMeH89mHe*&UK;gMzVE_-;`}pSWb!P}=LzQeYEJe?2;R!=N)aTRF zs}yMr4{6bQ(^Z&KT7h{@WZ^hA39&C4C)q8sawhrX1*4u^CjQ!IzMY3?{Inlj0{*Al5kZ09@$4mjBVIYrPZ2Us67mdoUq@xT#}>7du) zM_c?Xqz2r%Z=yp@(cAOkl@W|}5qCeKs>tbwPG0=fIXXU${xly4KgDNFey^-l70of0 z+i3YU4xhaYYQXP8jiz7W#ZRw-3h=v7p%v*E|9o`(>gc6k|LMW$)8|18^d#Rz+xpkJ zs?T4)JPc~$gM7uUrAOYs%qM668^zs=UNXJS=#Mx0e{Z#$82@FvwcWnIwS%!BTifUc zxU~O$htC54Kk@ck+WD4tzNMXSY3KXb$O2=D7nuaNDPZ)&&8;R{1e;rXJ0)o=za|Ha zu&R@^PZuxzQt>`cZT*ir!J^D&+dVX@J`h1pVa zV_5NGHA0E^ZCDTUn>jgo@v8Io;3;hX)4F+!IsIPz^yAwTim6D^|4^pq5m%vb=ha`{ z9K1M&y;coc4O**Xj^HNzuVxYYl@IY7&o) zR*j*N0dYp{d)zgoLn?dI-o6Yu|T!QUnQ{~n(|-O)I7 z8@Zso!U=4P$M>IZgB`#gem64^l6nl#=@Wa#p+Z7A2rKvIqTTl96z#1yppaVUFk}o# zD)BiMO#!2sDm7`CQ!ij{SPSFKVbn4&e6Aw`Uq=Bj=IQk`po{=Wj900Mkz%~~w!i#B z0d4{Re{Fo*6-2*u{2S@T%1)!zGF6>_&FpOMY(97Z<)SwSr_UcF%)0z7+@1F4& z%B19d#Uc^(j^S>wauof1@aLn)8n1Q*BPL2bF$!bjg$GJaMT=FUr%xYuyDLHQrxeEs z-p;6Ow`-$&?nNsYq6dR{Qj|{&=Lr=zx*QTIrD$`oPrS^`VYt?y>_(SD@I$9}+Z1~V zgM#gII7UO!A+foBzBw}Pn>d^ZHrJ=-Xy(^6h{M>Jn*K087kB{*SCR0zdm1OV(Z$>o zS3~5IFccqfK7%Bs2GWUXOjb42?Rk=EGd&!{lm>Bfboh8R-T%;-?C-DIq2L%+R@SJ* z*(`}a(Sv-D$-95T`~wt5&5JO(N~SZQ*$6)7{l@eo{L?kvF8=M?#eiQpv-Bee$Z0eh zt2Xka4SaUTY+RbVxKJ*9B!@Mm*7q>hF&P-qO^+M;P@(c4DwUwQ)1Tiw-poc*CTe%@ zQncEsS(Qjn@ET^p3gyF5f&HCNms(B<;pHL6b7T}Rbk4)$2^|Ow7B2WKh7PMhDHe?k6lcW@;*p_|6 z92}H=^^-Yxc6xN|>H*hw3f$Vum*%I}=HT7I-x^UwT}lipipppY3r1zMVT?C^u2ZZ< z=*vh^4%=5}zBl<5aO@?9qC%JJ6c7qVQ5U{?mH@-wWw8d%A2e2hR!%kUkz|>rNQR25 zp&>M+N@&0y79;s29$!%mEG{`q{$oBs{w{_?70`d^StE_^?u;(@knTSl})z=`i{6UCdsxf|c+` zi_~=##?3Y{OvdNg1+{dyT?6R8|A5;Mn+w|ef?-BE7MwiCe=G1GqQEcFm*@z@18BrH z5q(*;XQce(AUHoWe|!BlJPyx~Pyh;#fI9#jD9#Jg=E!JDhaGVN9otC5z}a)p-F{ne zt$%?}j{oPgcDv@^8}xtM?X4!pe`)RP?r!hg-=h2J;vg;@aM--k=> z;8Hud)DAASga7Tb04hCWC8Fj4e7M{t=_)JJ6Hg*94*5mP*;^HCGZkT-PzgNq2^Bp|0y$&4lYQSjY#?IDocQK zPvUeyI0fbmJI{cVkYD+vUnN|tNQTl#f`}aX1CgGeA0A`xrYaTHg%ts(GyRlZ^kxP# z9)jqW%*Ny=kdEUi%y*v#illoaYmw##UH3>7A~T*tVL4g|=? zddgsNKA+4}UJwaqOdC%74J*aj7$~#RYHH5sG3DDznD|lRhGa}94LuKLBc^ch0!D_( zH7Yd5L6%hP>h}o_IKsZH?kpLMNlujz`zgr&eH8n64N^Gh9LIOY(Vd}J4znz#0Uk~j z+r^0(y41p}=rvQTyW8c^rbPt%5|JCvflNyi3IR->51=50<96j^$+rL$Vb)_whKM(= zC=8NUf#)V^2Do(;ys5=HDq(maWs3xB@eUiC4{1P{OaP8xj8Uv9@0p}lqS(?GiLe_o z8iDmesxo_z@x8uC!seaP{6}-Bg;Yxs5Z@rdS)``w|B!w3rqX9d14nZP;6yk% z9G<38QFdo6=LC=RC>a5#Rim)ys0*}w?B{qmN9HHVfR(yP`lyQbcjV;s_~6A)&tcb} z9=z(DJ_ptW{mp@ar>!W01@6L6sNaVbm*bB|2PVt+;zehOry8Gg@ODJBbk6FAU6at9 zFy6rX=>)_)O=)g8nS4qeSg|C4MVZCE9AI7zoP+bxid^Xqw^E9**WjPJk;@-6#t!FF zlSepMdZLMHF`cV>NXc+fzvDgfngOJ|h;Ht?EUYkujVD>!$Ub9ERr4fh0fUlD+KXJd zM~}UMvV~%lr|@?ZfKD-TQVtw3A+9Vxb;9Fg2SiIR|Kujoq>E z4LKZokLHU@&x7I!Gx>7Jx!3{%SNSshxTeXOK~7k~h~K#4XVd;Bu;w_g%@pW5Wo7K{ zVF4=i4*49w!mv`~^Mnbz^g>7p6aEa6ArLYkVBxyusgY3k0l6;Dci_0O}r|y$ZRqhh3)bLk^NxRn+zQV6;ge{eu3cI z8}tyg_$6jd1L%;+Fs2hZ_L&uUwWg~_3ss$uhv)>L zqpAS?xQM4|1!1B@bdq(hQD!%&Q)h#$u!62sZ;*Clz)HQ`@=zALMN6d9%P)~m!mSU^ zLq=Mh16LzXEj8))DPzdkM%6Nyj6R@|Dn`N8^5hM$?6 z?Z=-dGi83Y8Mi41%)#^6pjQB#xJNk$eGH(Gd+Jt00aTmzdq?ELy#wZgf*jaKRKk5q zg){~}VL-@$)^38q6Q*$T9mHUDZmI*V=m~@M`h;4=71>4|)wDH%BJCY@|{wU3ue3Jnrx2miF;H7S!|zVj4_r?;m1D!$ZJ>vS>CBl?T% z6NhA8z)7LRnsu_-Cvo?p0Q{_d!}Qj4fB?U-#D&&!;y_{~vV&g8>azX65tijI`~;RS}t z!xxafWVd0FatqESu;@lkyN8R0N4six*SO@q{(5BcTW8kSx@^T%}a6PTD0jfG_3G}hjT>)QTMbcapyEjymTux zi&!;zNjUVC6aWm4Nmb8WP5b&yzmSugcM$i=UdWN8cPshh>yR0_aIE+U#%`g!@=y!0 z)U;qLE2NLp6m*w~_@DI>vTl*C$5C9Wz-mt*#DpX&q8CfE`G^V53}_E(O|>wP4NN38 z!2?E5Xmv_XlMh10BekO5Z9MM$GP#xDl@hgxPb6GL@j~R190kQxFlDf;FQvD2)Sy-| zBrZ~2bd4dwk$%DIH5v^`EEkaev&s1!wb7T!>gNQ-Gs@q~9N{2aO{D=?AY`?eM`YeN z_IX*slD4#-3L1g9=(rO_j#*!Mu1evPU~?f{=D|;3)2_{8@T0dy2$VP8zAgfNS?qTT zpo0+{xB&^rhIX1j73dg%rk2OBeMHF45>6#8{2}hia3}-^X_jBZ<1Zz>G3f);Oj^jP_>hg zd!v-9)@YkV4iu@BlEQjM9hG57tD}Oy(-;FHiyXRwdUYd@&3x>hvYh0XQq{BY)Q-;< zae$a-Hv~(8nT-}^{uQHJ^@`WbbdLk#TJ>pBt1$ERYQm8uey8h1jiq-tyk;2q%-iBSS#k+`-$zxNs$%RIEm!Vtb96mJ% zxpp`2kT8>P#v*9+`DLIMQKcXSd51xom;d7c9es&CIgF8 zu3o+_%uDf<2moY=PZkQ+%%g6u6||Ej`da3V9AC6RmL|9fu(F7f0qF?D!+jm^ol-F~ zXsn)tRuvsL#g2Y9LGMU}p$*iSjFK1_30VhJ4+|b+26at@iqKZb+BEd_ROU24_05pI z@O?Nl)D{ld-Ay$&3VghG(i!?%XJprk9W*{MRvQJ2FKTnCX3OYqs)Bit23p17kZ@f( zDPmk8Z8S3cv8N$MH(Jz3S(xR^Mx@nAtT&i7zvMMlXUWyXc>!Y!k&3nIE@X=&J}y^N z?x2x0>bMp>Gp-GIAsP0|LAvCG24K>#CNfV^!a$OEZaR*Dm2B|=sZae`q1Fp2sYEJn19b;Y=aT|dIH_7ei`7u2_`yRb%2?9Pr7o2pGN;jwpY=<7;@KJUy*iWWvL&g>+TLBM}!U40g@*V`z!g_CBY|f)aVEA{hY@3#ecc z5oL-M%dTYR4!v#5yJEaeG&Emu0OZYq3ttJ(ikOy-ei6zjG(Hn`B5b8 zb+C4|z(!LG#fNR-mbneoz2eErne+q z+bxNTVKBIaJa#PPWGw_Q%qlUSU{LdJ%%Gg6V#jnP+q@(qS=bjHEZo7uB}-DaBDx?l z*38Zuz$J4_V(s4smcW$(+1M-Oxw&XV^PnYlXZYfKKPha8{SvU1SaVZ!8k}G%!xTOB zm@)~H9C$|3x?F>>@I;3GDdrVN#y4lG3R=^nW%q=vYUAV_01b6m6sU)X@PIH)u2%3)y7x41XiJCf#bjZ2W6j7Je@(8;m@Ff5ep? zbX-Q~g5W&4_H|SwDM>wTv9zk+U9LKh)%Mz9v@BzX<0Lb79rclefyIKxp)Lj+e;jtc z>00v`^?W5jeT^n2k}tk`Vp@$r-q>h)XIBOU)Jw5zwb;a(sq%1Z;nZsWnMcE_dhDt{ zqyc$uFl66Mx>m{#e!xIDppw}d&ul2p2-84&KwcuTDA_Iwr@$(R;MfR_1Xd0Y z0<8Ga>u1(0f|w0J+%O=3aK0wB8Rh&5d!6~TlTEJGdX#`@xk3S!G|V&0!W#n?gHEVn zC`ug#9B6%)k*{Eo%&Q7SnA>Mr1Pag_TwUU;oo&i8LC(pMRm=>T*1ReE+)pslFT!eF z$IXzO(kx?J3JgnOZZ2*g55YT#H>+Ipr>9KeD*AV2x7F*}JHzKt$9gXV2m%`qu$GaR zuD@Un6RzKgdGWBm#i8unlcv_Q$)RZ$Vnu9qE)^v6cC&fx?h80)2+<2Gk`p0?R>P9b zDqR|2OjpbKYVdThjvb-$;n1_9b!j%mi)nqigQnwF++(j--h_ZWtfeDFp^}9c>CtMK zU!NZBp^!H=$Vu@H7N`BKF9Lxz+yoFkX^r9`zMY-pawSj}g=5>eu{%!3cG9tJ+qP|+ z9lK*YxpBv~ZKspT{FoP*s$F$n;8g9i_xaXZEq+yEFMXwBm<94LeW$Uo`+9}>hAKCZ zD59sdVI_It6w(fhY;*(HJ19M1?@+bq^kv(N+}sIBdY{$n|9Ff z6g%hU6^1Rc#AYW^QQj_yVNfQ=n(FKyOX{PG+H2#CG)_Qyz=1kgO3N{FHoW1!TMt*piBf6VR|sHbSF1u?U5;HhYO z^bc~0-w@!AKYVwrKKN=~(2MzCHYznbalW)SnG*oGIE}o@#8Esf(a6b}Gjn2Op*a=!_cF<5r3cke*RX3<{w;a)C3k_78Wss6a6v)MI~w zRlyjF_Q_+H)HdtM?=_6}wxWSzIarhm(P9d+S~!5nCv6um&#=Ex7giC4C>(8ApyG{h z_{*qmg5&${cC1I(6^Q;(+?C+qVZ1TxU%|V%1;erpIuSW`n>ZKGkrui7A{EEQW7LvF zG?*?M94h+^rYqxYo*<8zo|N9?ZK;}F!4J?4Dd5DTbxAFwOX&BHhw{8lB#g! za82)olgJJ*$c0Mmh-k{DM#|$dLjCw>>1p}%~7LoGn%+QpjARAU6wM;RAYN(aHr`gk)sMuS93O*kXS!_23UNurWhIp ziEC`AGMJ$&2^Z}2d!8tTsbU#H3hDe6Vl(3^B+7!}>5+R@fIDQo_kjxgYjkVde$$9Z z?}I3&HzE2fSh4r|OZ)zFTF%+s++F*w_u|6m_(edFYGgU}oe1x%?6%NIrwyU?9|qGt z|Hy=eeM?sM6m;q4*1FYov->Q(BOqiml>O!_x(McSiRJv2BKcYVFaFXLDcMAXokv9p% zkZfQtM*fG*@_JVPRQP4aw)kq$w=DiZTFfNia6`q5mY4VYD-`w>#oiAhyZk=&R}0M*(u=KOpUjNHvkSquxOjuhH@;Z?RmJ<&=(I zK~H~U!4oq}yv|E3_&m7;PstQX48#jDs_d1)L6C>St|U@pPTvrBj~i7n>S-bLNy3y1 zGVM*O+JFJg!)ioOPsBZz#3d`*FW}ZzaqE(=!x7Jz=4>n5{5*e6_`_NYvYo%E6Si?p&bs7yIDI8~w8S5uaeNv%j ziyX~Oj}PtKeo%oryw?Su>av62pnwVeV?BC^tn8shhi1L&13yXT(b{SsXW`ahIx%;# zE37h98g=jFS=YW)yWb5S@qNLwRIXU{+Od-Z``y3(=GJH_4&G%o$Vj@?2JOvL!y%B( z5nkq+&`?I4+{*Q0oV*NEsN8`u2rW@71W#GYz}~Ro~`=i&3lwAA>%2$4$@HG{UHG% z>M^mg$F+K)=ffttWJMM$pp3H3I>v&;mGfYeVtnfx@|a^35r?bC)S#B-5Msr86&di4 z$Qc9>b!8Wnn_40@|I1y_BOQk^;2l+WmdG3%EyFW!daPfJL_lDV`t&)Op^_v6U5r=4 zR(FmN!nPkaNm;0y>`n>cO3)<@VXOgsrexn!cnDS1^8D}xs47jwwovp7c7SQv%9!Zi z0x2gE2-~J;SM}}?*!#RHQF245M+52SpB}utj1SI;kPnNcK->tOHprLMPFI}_L%u&G z9Sl?saMO|Da?Q+*J%`Oem1A11Sk}s&=_ynDEgIfR*dyhDuXC0^?g~jDX&;U(xJ_x1UWw?NekJ@l_XX6VYP&DYdqa<_eN!GYhDRPv{Of2sLhFFBTzHYnUjC_^PXk1^-G4LsTq!)n#gLx zpR<8KnzB2QJ-N0IcjDtoMzPJ0@CI*|+4SIZ{X_%NQHewO#T)cU9d5~Na4RR&U5@sJ z!a9G1ok@b(4rxk`Zl)>ewzJ2h8}~hzJERgG* zkG>)O_xgmpG^-Kh6}j_20U&#QfxAcAa`Kae1n_cFDx5SF9vvxOh*E;yY=?&TlK#*Z zgB_C8_4Z)0YfVp~n)bR)S!D6_2*gE;8`kWQKZFNs-hxY z)_}qha&qJ6%qZ#?qniBQ#5NO+xndL*RY%3XlPArrV$o6GM5frc7$Ecpm2!>(4c0b) zsinHc7`>G>J<4w9i&tV+-F8=mWxgm~Cn`McA`A$w2{6fEYgutf@Jf)xCim&dhIm=% z)K93~gC+1a4<6e{uRb(m%f-MU13D28oJwm{skhw$2t!2S=8zQNVwqvz)%4;r!aM=p zlG;Us2;G0E9hQ!TkPp%E#K|fv(S{Oks7aa~tmyV7FtUeYyX>+}JU4ptqOo=H*+@+2 z@(_#1R5r^K9?K_!b_#we2@)4ZxjZu>mIcaK0NN7g+%Tn6BcE7d{J(r?s4Sf4F2SOY zZ@JpGFzBP%7(v{|dtS8Vk^+ak2U2JuGVf0lIM*dd`=5;00#TYws*rUEN}rs9!{jIw z4K%t4NtsjAJmyq|`hU3YL`Ki-h=Q^%!;rOWv0yEfCUqA|VMhK1gIrO4(%ls{7QuLF&4zlc!#_ej^-R&#<(HOk;GA( zpmf3&ACan?qr-(&jvQKWP9!h7R)g%s>la7lErT%XRz|Ax4Vw&3!H>l{a{UPRQc>sz(^-uX@z%BE zFq(7EjYJw)j{pT2F03L@8!PGWU+wjb20NbZLu*Yu%p2fo&SZ-_rsc^}G@IFrtGdc@ z4gJ;)oe|w+VS&1a<@=5sl-5Lg+~$Q<%IUA6YleI zjG|eNpLo;5-0mxtP$HjpH68`IdxsNM)aCrcns&%P&+;RrZruQ(6n?1(HCbR6XpX9j zLNNS=jW25^symzE1Z7?*K>SSIL~V3HsRYGC@0=T?3J#5X8!FCk60|!O8w1XkS_4rX zpt>so<8snvI2eLXI!tDfS`va_&X88Lr;AV@nWCr2sI23%bYX<_2RD<(erpG)OsIrn zi&Tqp1y>0KHcY|uGt1}{m@A$1QtEz2&e^IR+$nO`eg{s4s1Ycki%Ztl7H$UwQD+Lp z#X$WYhLU zTE7$JWuiBGtMLI3T5g2ZP*UGI_;bn;MAms?8L^-Gfo4&c7E!0jy?kM4O5eD3 z(fAKESBhX;@kQ@`x}bz(M02cMVr$eg?v4ZX_7XstC1Sy+5mJa5xFd~(FV)IO!a^}< z0v>z%Fz)@njX8;C>zXil>9Xe&VlK3#n)g%LcLOTUczGr~2t7NuXG6mTmjf-`E8-M4$|A zQQ4tNHc5P-0fsQzG!Nt(K9f+1=Um@6PeL}yJ9QaxleoJv9=$Ki}Ty?xw^;oqKXq{<=b^2@~AOWo0irnvCE?PU4Ep{Q^|!U3!g?J zU^cH|<_35uiuB|8OmcY9kOll@UCZ*CLXM351jmSY#_of-p7jc`O`2qV6oKO)5I2l+*_)kA&zbLk96DHn|K+Q9Ax}P zs_t-sh88niGJyh-e&41qGk&H)A`b2jwjfQ0D@59xPqB?OS}f+wCddj}iYEXz!ccn} zN`##7B9?0i9!eNbsb8R9*r=Lh_UBQ(EKpc&Z0(a)>_Y4v<_IIW&NwLpbxnMF9)=k~ zX(O-f09BVdk3VJKp>I;=XWsG6T1bOrVt;70ZV6A0i@;dwwB!&^neJ0+P`h8jBXdbD za&9{L48VqgKx7Gkh)CJ6tc}Ev;P-7@Px^Je{@~I>@^$`i^Ju!aIZONU{W3SV=92x* z|C;@p@xIqDeum@Fzk5d0V7SgZ6W;BA_0;=|LBm_i>DAy17w~NOLGpI&xDoDX`gNYP z9G33L>23QCiew6Hzu(k)%l*w}7+|Ti!xd%>_8u5BQhs`60k-ZQl87*7; zq%@B;v-R zuwfSr2()cN*a@Y3-jOV2cO>d7Nk^3F!svx)eIBiivUEx-3mTM-Oe?aVXY z%%pFGaMb4BjI9&(It}25!p1;NuYg=!-#;YT#GY@f0MXK8xrZBPFr^i=XqF1QxmjD$gVf z2?@|7S;X1=GoqRNI=e-~h=Z#+C}(BUfrqfpULrlDulk({t~!W9i;?J>;o`w$5?1h% z;iM|;L&L9W3;xWYY5;@5Y%*Lo@Z&}Y5s9Pm4|_MIjTFNHR@Z>}jjyTfV<@2CG}IW; zf3@r{JEh2|f7G@Rc6oU6PnQH@S$1)XL{8r7c&J1|^~hpSGOYBTmudO%_kwEolaVt` zW(802T+M$^JzV@A;ZebGeNt;?bI z$Ng?9k*ew=3q%;%byt+Hoz0WT9Dnr=xKN5$T(6yP`EGUDnhZj1pPiqnjUf67|V~N$5{t0K6 z7X2cEUNqn|n`<<~6iWl)B65zA8tO)Ei`q95F^;g_-(3i>3S7I@xJG_D&3D1$L z6K|)G?JfCkyl({U>hAb*G;@5>C3g%xft{1r_s2K5^uf9Chmh5dHSj|{rkcS(gxh%w z-KN)Nk)ZQiTTux)pAEz#rHwY2}GSs;?qV!3Kc43J39Ag4d z_yOV!noDCC`)?QPWo>BXxr4+DHyoK$5bIK;@4h7qbf!*5Haio}?^=zZK=E4xonfeg z>{`1cypI>1XmYd_lOL!Z7P53|@dLVdc@6Z@>Wm&bD?-;bU>IT>d_)RQ_Jp$TKOjcK ziB}~p1-Ic4zQqBc)Lm6JDi-a$5K}FQXkIqLF}s5eO4=o*f-O6BPuV$B@7LSBd>-@P zi1p{~$$b><%X4vVL2Dt^KXKg!KT2QR%E!w0JZPF?ur*8XM6@dAWvJ_62XpDJC_I%^ ztIz?=1ymlIrV0aBXM)6Nxr5$uvy4IM$&_-PKQOH1YAs7D6wQ z+BXUCZ-3SG9DtA$hIL)z%<7u@&$}5?Tas$hTG_tZ*24GF*^@mLzb05xT0F;WvE(C- z3JT)#T_O_+C1}=vw?#9(l+DB=Wl}X4@`G33h|U>VoD@YKM>jj_aNsv`S7x#Q38K&v z#xYEefdSP(-LYa{O4>3nkS6gOoSK*hlKfkJPMzn|pv=RJP!PzC7;M(?W&Tn*2=5^J zZDMgeI0pU-6J8bO80I{~bg_K)W+hA7gNc%%?&JG!e_-sNayJ&reseCrr;Rrzg2DXk zLD!Y-kkSKr)!%7q(qlOVuYEP!5HoebOgjGuZqZ?T>74Dl&l;z^GUuPGPNk|Sz3 zo@mutZpV4O0N4B}SY_Q5N8`yu4^@wy(C*}F{h#X@qZHV1?-k5eND|PGy0FXUZO+ZW z^(mitL&bc#S-|hnZ710_rT5S5FlANVl}$VL{{n}aDIyhl_GDMta6n-kgu=bZUM+3W z*HVb_J=j-`0`Ybd8i&Ik*c}4pkh|cl66nd8O_4n<-%z!PZiUvdEx zf!{1)lyE+kx(jdA;O5m#56Kiy^QZ19Y^vRxJ5#((|=<_Q)v z@RoR_F+Fotuv8g=OHOcMLQ&o*uex6m86B>)9TayY9Y2Wx>#(6HjN6Z$1?>>e_-A?o z^vlk6f4%Glm4H?s+>v{no&jwwDVK7t#Lz-W3uw{x46HDwv!`trN{zJX?v)O-4b5Xn zwS2@@Qpbsgvi?C*kkSw*4(?kCFi^j?mBJuvV3BE9~PehtDH0TWBlA!froU zYcz7h&*0kOwqsB3LqWU?7bwo6Ym_3vgte$}?oeFg+7C2nP&dF;7dXa06XEyc?mjfd zS6c9qD@rQio_-V}SWhf3-*b_UtdaldfNe6Ab`Y6k(r`bv;8wNnYOL zR(ke5>Tx}}A6V&58W5WEv}$g}Tj%NYK}Ggk;mJHfve}VsT>b5vzI)Q|Dx#$iZS;qB z_tE(~-fq)}`LD5Ij%=#}XhHemF5z;yHxt74tD&qLy$rZ9O-Re=5C}3f;9L0D2gr%y zqS{kR<+|_im*}FFD3+=mm5wQ6A~U}#Jn3mvJoZTewXq%Gh&e!QSNOBHK#tvJ)s;f_ zl4YWbXyJ)$wk+yi_BHeXsW}yGm31pCbeCCOz(c%Hg_E?-IZy0lpW~Ls*!fu3=G-w+ zf?dLxlxSRIcq;+6{eTIR;a8&F^oDcob^bh-LH0Pucp$xlcyzmSl2hb`kQ%498`0P) zL93TcE?Y;Lj>hqhMzA=m$jk1Pk7>U*QsGaGacPzWmuR!Mnuwi$PeW@?Ul zjlJ7fv})cm2}VW=g%6jlQfP;p2IAvNXex$zn+_8-RdW$MY&frE&W+Z4n$9=|OHUw6 zWzV_@i^u!TpAeE-OeZD&ZGYu-7s~}{S-ol9y_OiQYd@WiHYZ3h>G#qN{&zF3da$~orqHTOhBTT3ti+SdG%d3p zU(@=+SgUpePg$HqG#P`JQ31)L=$bql3x` z;e6Av5ml%S-sl^te2$-B#kmj1SCl8`f{;Y3xtoxloR*)s$ zL>)BzQ}2CxaQfn|m{z{-@28g)<-Twzz2e`n6g~?j_9u`;m+2AZ3l-ZnY(E8o6-o1_ zD-5{rOO|=-8g)DX5x&t~ou$q85D$QIbI)$(yjpr34fx z5qm1m_dxgVqYiRP$nE&MEE+{WAa|jB2OO-bQx5ds-7M~&dL4MF(O~3pd0P`ACsjG= zG?=8$bzOI=lA82svkUyF>BMBKKG*oM*;*`=>ol_AK&1U+%sfZc=QC704wO~?;# zK5JXgECA(-)54&+MuA&avPThMcqPD{6(g3e4Tpr3xjUPTw3rB#lo~q6QLF{Rn7Z8P z72dn%1a^J(%c3T{#PjpYl9EMg_tzA6xowQ z1GirH*I2Jz8%r^$GWStb{dg>o5V!hx z_p$q#D;kcmUC)MS=YB28($g^R`HJ+=DJ?q|WI&>;D#tYIr;T#5rP9y2EQ8u9L?oE8 z*$^lX0vJ)HIEDHA85mO|-?(n6&l?xj2A#4;#5h16f7J<@sci4k6;C#O{fDsOZ;6dc zN_6rGNSIR`k-{_fWbN4;75B-7ZA#u>J>YaU<9cn(YXRV}>Fo+=*h|zjvOSu=WXPp8 zR@w)ywC%K$t$~3)n^f{X-7}$hrctql%nGwldzsrlb-bGu_D<=yuJOT4=D6Ct1#sgN zf#C#lA{zL%7RH0jn(%1J8`^)hHYuJfVGI9dkuVX6U9#{%?8q|`&|vQkJ}IO9ejRe) z1iVQYtpO;RY|%)_%UXFy_YH2BUAIJ=qVVPaTK=8!jEq;f?7ck*`pAZ0Zzq?>>`|tp zV{TB^m5LQh)kOM0JIqNf+TN`>uyvRYCjELj0w4Qf9Cx@VB!I_9*HbvhLz;R^9)Woz zGhgXnAnLfn=k3zyI3NJMXGm%`u`#gT0{`lz4vxYH3Q$6li(gw)z|#|BgU`70K(CKC`)Q zN#pfU`HC|KK1fVEXT+*Gmr(zVh2aA7!q=T)qH49h@~P8LbrwVsuIpEbvb!VoF!eX= zk%d84e>B&_>rJd|Ca5%*VOvFQ@^b%zj|`y7WN(Gb1ZtXz_(oquC91Pv&n#cP&$0n> zkCWJLyx)6YUG_=-FwW{o%!xc?fQM9jt&#BIvH@H~eGfZ)jE#>H%5WorcO-9BkgT4Q zbg#e{vHC#yS6$=SRU&SLx~s38TO}N+UA30+%I0pk0slg}{JR`AQW8c6sSc#o!7Y_z z{)}L_bv_cx_&ygD$h|QLB6rbRtvNk}^eZu!x}bzSs~OdVcVtCxJ4wj#24uH6qHUvy z?3Cj@(XSi-)QE8oO-lLLCGSDmv$u=GeAXh9qL>CI|E26Qb5tz%=wHicTJS&WZH|VE z4Q8|~O|X+U8HSJ7^?gsKx5*!>5^<>}%go_!CO9~|kaCPFge`siUv#Lhz}v5Uk{G)S zqsqlu5O&A$oehzh$f2IoA7;(+FJ<&Yfan9y$CCf!qNu z)B$mW<5Bx0vy;6t>!B=3Y0Z7!m+j*Dez5LFM>NL6(b1&R3MM#3&uLAw*ud!(c!ltg z@y%urpHMPBeKH0MxptY&80@=ePa{)_b1d?C8vr$%aXF9Ju17l-0f@phjb?{!TJTXTT)6Wc7Spa*`FEGq5z}yyz+cCCoK}w-J?`i+IDEalg() z{zD@@Zmc6a#t^p?%_ocj_M2POZo{&g?KZT9q)O|Pta-}rosSl!2>Ecp#A+lOG4IT9 zrC!&G_e>Cm%SO=6Fy-Ks2K3UctOS{qREN1fwu%OOtXGZ)&j-zbDpDG@H$53KdZXS;dZB4g}zg~rPa9)gY1z|6TwoXwfw zhvDegPTs4&$ zMW&V?AG3PT(H5ENCRx(vpNB`bT0U5lQ)Pm3DRxEGnKO2n=`+U^)LjRChwGGDcs$~( z@*5W$D`Rh>Zt%!$q56mVdXXj}NPW*Kne+%_Rt8O?HEPvY8Or_*x9)MawH2!~N(EM` z*WYiCk(6)BK{e-5^uzsL?E|O&t*83;HG||Mf!jcxBmaDr^-=PAUG3d2{}ymwKU`>m z9wC`s`)d2FN+m!H10UQC zxl{q)+&Kng+EBs9i$eupAy3FJTdNbMhiI=x&(!0m1-C$R6x@qK3&R<>F5S zMs|VO>)lmES(jTdU#GhQ*iYtB)&lA8CgXYYtM^6u#FIFK)lip|+K>OP0Hq z5xR*4SoWj4wxQdn!wnCs@agjwiEzH`6+cF!wJ!#vzaso(+h5|RYL48_x3fB@E_FTP z8;G-OF27+4o>Bjy>Zfli=!^EVct}Kh#7*aa^Ygn$nY~G`tzu%{CNa3ah4V5Rm)loSP zEiw|X7u$UfDoSb_V|E0dMl7vIOSUf&nYx;&7XXQ53)1qx=DzilgE&sDc<=ZE%cEa* zc9$&y$LqG=B5zwZ_Zwg9^UvvNme1$s7oC|eN8Swz?6w22be)|f_zypw9Ym5IX;QQ7 z&Y5JKrSHuKY;nTs`qA!{SylI{9Vp@Y`s(JoojyLJw@||Q9rdj5{Ao@OA^)Yz!1Ha) zph&XsT=y$NnTK0mns_-ww0MnS>6bOQWHH!1BlIZrs6g(@J4gRQ?JlBelul5dUmTAE zmh!{TCXEFmh5fXn`^?5s_V z(>>=NWIR^PAusA*H^{7gyDJn)bJT;ho@f!l-o|7EKK{M4ZxNs`Y63A_)EU!ed9GD2 zD8pbEv9c!B&t&J8B<1Vr0zu2uxBeZX+st3m&eqn?{I~wv8BeC(>36+0jIX`dci$R$ zdNzOQJo~YGde0tz)V!HQdb!jfAN~7XGwz{2j-NcE+0DKSi!}dOxAkGn+c-vlLSXLq zuz85;;P?*d7q`km-Bh<*4a&93Iq@%+3Sj<{ciQFg@9IT`L1k4s-!O3B9Y7*X^ts=l zBEmlbiApx{{>`91J(UJJb&t8QPglDAW%7&D7b$rk$XS~F8ptw>4}T4J(3+UJYy6-S V_ + #include + +-#include ++/* #include */ + + #include + #ifdef HAVE_FCNTL_H diff --git a/packetdat.awk b/packetdat.awk new file mode 100644 index 0000000..292e219 --- /dev/null +++ b/packetdat.awk @@ -0,0 +1,61 @@ +BEGIN { + # we need to know (usual) packet size to convert byte numbers + # to packet numbers + if (packetsize <= 0) + packetsize = 512 + } +$5 !~ /[SR]/ { + # print out per-packet data in the form: + # + # + # <1st send time> + # + # <1st ack time> + # + # <# sends> + # <# acks> + + n = split ($1,t,":") + tim = t[1]*3600 + t[2]*60 + t[3] + if ($6 != "ack") { + i = index($6,":") + strtSeq = substr($6,1,i-1) + id = 1.5 + (strtSeq - 1) / packetsize + id -= id % 1 + if (maxId < id) + maxId = id + if (firstSend[id] == 0) { + firstSend[id] = tim + seqNo[id] = strtSeq + } + lastSend[id] = tim + timesSent[id]++ + totalPackets++ + } else { + id = 1 + ($7 - 2) / packetsize + id -= id % 1 + timesAcked[id]++ + if (firstAck[id] == 0) + firstAck[id] = tim + lastAck[id] = tim + totalAcks++ + } + } +END { + print "# " maxId " chunks. " totalPackets " packets sent. " \ + totalAcks " acks." + # for packets that were implicitly acked, make the ack time + # be the ack time of next explicitly acked packet. + for (i = maxId-1; i > 0; --i) + while (i > 0 && firstAck[i] == 0) { + lastAck[i] = firstAck[i] = firstAck[i+1] + --i + } + tzero = firstSend[1] + for (i = 1; i <= maxId; i++) + printf "%d\t%d\t%.2f\t%.2f\t%.2f\t%.2f\t%d\t%d\n",\ + i, seqNo[i], \ + firstSend[i] - tzero, lastSend[i] - tzero,\ + firstAck[i] - tzero, lastAck[i] - tzero,\ + timesSent[i], timesAcked[i] + } diff --git a/parsenfsfh.c b/parsenfsfh.c new file mode 100644 index 0000000..d5f877d --- /dev/null +++ b/parsenfsfh.c @@ -0,0 +1,484 @@ +/* + * Copyright (c) 1993, 1994 Jeffrey C. Mogul, Digital Equipment Corporation, + * Western Research Laboratory. All rights reserved. + * Copyright (c) 2001 Compaq Computer Corporation. All rights reserved. + * + * Permission to use, copy, and modify this software and its + * documentation is hereby granted only under the following terms and + * conditions. Both the above copyright notice and this permission + * notice must appear in all copies of the software, derivative works + * or modified versions, and any portions thereof, and both notices + * must appear in supporting documentation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND COMPAQ COMPUTER CORPORATION + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL COMPAQ COMPUTER CORPORATION BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * parsenfsfh.c - portable parser for NFS file handles + * uses all sorts of heuristics + * + * Jeffrey C. Mogul + * Digital Equipment Corporation + * Western Research Laboratory + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/parsenfsfh.c,v 1.29 2006-06-13 22:21:38 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "nfsfh.h" + +/* + * This routine attempts to parse a file handle (in network byte order), + * using heuristics to guess what kind of format it is in. See the + * file "fhandle_layouts" for a detailed description of the various + * patterns we know about. + * + * The file handle is parsed into our internal representation of a + * file-system id, and an internal representation of an inode-number. + */ + +#define FHT_UNKNOWN 0 +#define FHT_AUSPEX 1 +#define FHT_DECOSF 2 +#define FHT_IRIX4 3 +#define FHT_IRIX5 4 +#define FHT_SUNOS3 5 +#define FHT_SUNOS4 6 +#define FHT_ULTRIX 7 +#define FHT_VMSUCX 8 +#define FHT_SUNOS5 9 +#define FHT_AIX32 10 +#define FHT_HPUX9 11 +#define FHT_BSD44 12 + +#ifdef ultrix +/* Nasty hack to keep the Ultrix C compiler from emitting bogus warnings */ +#define XFF(x) ((u_int32_t)(x)) +#else +#define XFF(x) (x) +#endif + +#define make_uint32(msb,b,c,lsb)\ + (XFF(lsb) + (XFF(c)<<8) + (XFF(b)<<16) + (XFF(msb)<<24)) + +#define make_uint24(msb,b, lsb)\ + (XFF(lsb) + (XFF(b)<<8) + (XFF(msb)<<16)) + +#define make_uint16(msb,lsb)\ + (XFF(lsb) + (XFF(msb)<<8)) + +#ifdef __alpha + /* or other 64-bit systems */ +#define make_uint48(msb,b,c,d,e,lsb)\ + ((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24) + ((b)<<32) + ((msb)<<40)) +#else + /* on 32-bit systems ignore high-order bits */ +#define make_uint48(msb,b,c,d,e,lsb)\ + ((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24)) +#endif + +static int is_UCX(const unsigned char *); + +void +Parse_fh(fh, len, fsidp, inop, osnamep, fsnamep, ourself) +register const unsigned char *fh; +int len _U_; +my_fsid *fsidp; +ino_t *inop; +const char **osnamep; /* if non-NULL, return OS name here */ +const char **fsnamep; /* if non-NULL, return server fs name here (for VMS) */ +int ourself; /* true if file handle was generated on this host */ +{ + register const unsigned char *fhp = fh; + u_int32_t temp; + int fhtype = FHT_UNKNOWN; + int i; + + if (ourself) { + /* File handle generated on this host, no need for guessing */ +#if defined(IRIX40) + fhtype = FHT_IRIX4; +#endif +#if defined(IRIX50) + fhtype = FHT_IRIX5; +#endif +#if defined(IRIX51) + fhtype = FHT_IRIX5; +#endif +#if defined(SUNOS4) + fhtype = FHT_SUNOS4; +#endif +#if defined(SUNOS5) + fhtype = FHT_SUNOS5; +#endif +#if defined(ultrix) + fhtype = FHT_ULTRIX; +#endif +#if defined(__osf__) + fhtype = FHT_DECOSF; +#endif +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) \ + || defined(__OpenBSD__) + fhtype = FHT_BSD44; +#endif + } + /* + * This is basically a big decision tree + */ + else if ((fhp[0] == 0) && (fhp[1] == 0)) { + /* bytes[0,1] == (0,0); rules out Ultrix, IRIX5, SUNOS5 */ + /* probably rules out HP-UX, AIX unless they allow major=0 */ + if ((fhp[2] == 0) && (fhp[3] == 0)) { + /* bytes[2,3] == (0,0); must be Auspex */ + /* XXX or could be Ultrix+MASSBUS "hp" disk? */ + fhtype = FHT_AUSPEX; + } + else { + /* + * bytes[2,3] != (0,0); rules out Auspex, could be + * DECOSF, SUNOS4, or IRIX4 + */ + if ((fhp[4] != 0) && (fhp[5] == 0) && + (fhp[8] == 12) && (fhp[9] == 0)) { + /* seems to be DECOSF, with minor == 0 */ + fhtype = FHT_DECOSF; + } + else { + /* could be SUNOS4 or IRIX4 */ + /* XXX the test of fhp[5] == 8 could be wrong */ + if ((fhp[4] == 0) && (fhp[5] == 8) && (fhp[6] == 0) && + (fhp[7] == 0)) { + /* looks like a length, not a file system typecode */ + fhtype = FHT_IRIX4; + } + else { + /* by elimination */ + fhtype = FHT_SUNOS4; + } + } + } + } + else { + /* + * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4 + * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5 + * could be AIX, HP-UX + */ + if ((fhp[2] == 0) && (fhp[3] == 0)) { + /* + * bytes[2,3] == (0,0); rules out OSF, probably not UCX + * (unless the exported device name is just one letter!), + * could be Ultrix, IRIX5, AIX, or SUNOS5 + * might be HP-UX (depends on their values for minor devs) + */ + if ((fhp[6] == 0) && (fhp[7] == 0)) { + fhtype = FHT_BSD44; + } + /*XXX we probably only need to test of these two bytes */ + else if ((fhp[21] == 0) && (fhp[23] == 0)) { + fhtype = FHT_ULTRIX; + } + else { + /* Could be SUNOS5/IRIX5, maybe AIX */ + /* XXX no obvious difference between SUNOS5 and IRIX5 */ + if (fhp[9] == 10) + fhtype = FHT_SUNOS5; + /* XXX what about AIX? */ + } + } + else { + /* + * bytes[2,3] != (0,0); rules out Ultrix, could be + * DECOSF, SUNOS5, IRIX5, AIX, HP-UX, or UCX + */ + if ((fhp[8] == 12) && (fhp[9] == 0)) { + fhtype = FHT_DECOSF; + } + else if ((fhp[8] == 0) && (fhp[9] == 10)) { + /* could be SUNOS5/IRIX5, AIX, HP-UX */ + if ((fhp[7] == 0) && (fhp[6] == 0) && + (fhp[5] == 0) && (fhp[4] == 0)) { + /* XXX is this always true of HP-UX? */ + fhtype = FHT_HPUX9; + } + else if (fhp[7] == 2) { + /* This would be MNT_NFS on AIX, which is impossible */ + fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ + } + else { + /* + * XXX Could be SUNOS5/IRIX5 or AIX. I don't + * XXX see any way to disambiguate these, so + * XXX I'm going with the more likely guess. + * XXX Sorry, Big Blue. + */ + fhtype = FHT_SUNOS5; /* or maybe IRIX5 */ + } + } + else { + if (is_UCX(fhp)) { + fhtype = FHT_VMSUCX; + } + else { + fhtype = FHT_UNKNOWN; + } + } + } + } + + /* XXX still needs to handle SUNOS3 */ + + switch (fhtype) { + case FHT_AUSPEX: + fsidp->Fsid_dev.Minor = fhp[7]; + fsidp->Fsid_dev.Major = fhp[6]; + fsidp->fsid_code = 0; + + temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = temp; + + if (osnamep) + *osnamep = "Auspex"; + break; + + case FHT_BSD44: + fsidp->Fsid_dev.Minor = fhp[0]; + fsidp->Fsid_dev.Major = fhp[1]; + fsidp->fsid_code = 0; + + temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]); + *inop = temp; + + if (osnamep) + *osnamep = "BSD 4.4"; + break; + + case FHT_DECOSF: + fsidp->fsid_code = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); + /* XXX could ignore 3 high-order bytes */ + + temp = make_uint32(fhp[3], fhp[2], fhp[1], fhp[0]); + fsidp->Fsid_dev.Minor = temp & 0xFFFFF; + fsidp->Fsid_dev.Major = (temp>>20) & 0xFFF; + + temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]); + *inop = temp; + if (osnamep) + *osnamep = "OSF"; + break; + + case FHT_IRIX4: + fsidp->Fsid_dev.Minor = fhp[3]; + fsidp->Fsid_dev.Major = fhp[2]; + fsidp->fsid_code = 0; + + temp = make_uint32(fhp[8], fhp[9], fhp[10], fhp[11]); + *inop = temp; + + if (osnamep) + *osnamep = "IRIX4"; + break; + + case FHT_IRIX5: + fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]); + fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]); + fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + + temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = temp; + + if (osnamep) + *osnamep = "IRIX5"; + break; + +#ifdef notdef + case FHT_SUNOS3: + /* + * XXX - none of the heuristics above return this. + * Are there any SunOS 3.x systems around to care about? + */ + if (osnamep) + *osnamep = "SUNOS3"; + break; +#endif + + case FHT_SUNOS4: + fsidp->Fsid_dev.Minor = fhp[3]; + fsidp->Fsid_dev.Major = fhp[2]; + fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + + temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = temp; + + if (osnamep) + *osnamep = "SUNOS4"; + break; + + case FHT_SUNOS5: + temp = make_uint16(fhp[0], fhp[1]); + fsidp->Fsid_dev.Major = (temp>>2) & 0x3FFF; + temp = make_uint24(fhp[1], fhp[2], fhp[3]); + fsidp->Fsid_dev.Minor = temp & 0x3FFFF; + fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + + temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = temp; + + if (osnamep) + *osnamep = "SUNOS5"; + break; + + case FHT_ULTRIX: + fsidp->fsid_code = 0; + fsidp->Fsid_dev.Minor = fhp[0]; + fsidp->Fsid_dev.Major = fhp[1]; + + temp = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]); + *inop = temp; + if (osnamep) + *osnamep = "Ultrix"; + break; + + case FHT_VMSUCX: + /* No numeric file system ID, so hash on the device-name */ + if (sizeof(*fsidp) >= 14) { + if (sizeof(*fsidp) > 14) + memset((char *)fsidp, 0, sizeof(*fsidp)); + /* just use the whole thing */ + memcpy((char *)fsidp, (char *)fh, 14); + } + else { + u_int32_t tempa[4]; /* at least 16 bytes, maybe more */ + + memset((char *)tempa, 0, sizeof(tempa)); + memcpy((char *)tempa, (char *)fh, 14); /* ensure alignment */ + fsidp->Fsid_dev.Minor = tempa[0] + (tempa[1]<<1); + fsidp->Fsid_dev.Major = tempa[2] + (tempa[3]<<1); + fsidp->fsid_code = 0; + } + + /* VMS file ID is: (RVN, FidHi, FidLo) */ + *inop = make_uint32(fhp[26], fhp[27], fhp[23], fhp[22]); + + /* Caller must save (and null-terminate?) this value */ + if (fsnamep) + *fsnamep = (char *)&(fhp[1]); + + if (osnamep) + *osnamep = "VMS"; + break; + + case FHT_AIX32: + fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]); + fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]); + fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + + temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = temp; + + if (osnamep) + *osnamep = "AIX32"; + break; + + case FHT_HPUX9: + fsidp->Fsid_dev.Major = fhp[0]; + temp = make_uint24(fhp[1], fhp[2], fhp[3]); + fsidp->Fsid_dev.Minor = temp; + fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]); + + temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]); + *inop = temp; + + if (osnamep) + *osnamep = "HPUX9"; + break; + + case FHT_UNKNOWN: +#ifdef DEBUG + /* XXX debugging */ + for (i = 0; i < 32; i++) + (void)fprintf(stderr, "%x.", fhp[i]); + (void)fprintf(stderr, "\n"); +#endif + /* Save the actual handle, so it can be display with -u */ + for (i = 0; i < 32; i++) + (void)snprintf(&(fsidp->Opaque_Handle[i*2]), 3, "%.2X", fhp[i]); + + /* XXX for now, give "bogus" values to aid debugging */ + fsidp->fsid_code = 0; + fsidp->Fsid_dev.Minor = 257; + fsidp->Fsid_dev.Major = 257; + *inop = 1; + + /* display will show this string instead of (257,257) */ + if (fsnamep) + *fsnamep = "Unknown"; + + if (osnamep) + *osnamep = "Unknown"; + break; + + } +} + +/* + * Is this a VMS UCX file handle? + * Check for: + * (1) leading code byte [XXX not yet] + * (2) followed by string of printing chars & spaces + * (3) followed by string of nulls + */ +static int +is_UCX(fhp) +const unsigned char *fhp; +{ + register int i; + int seen_null = 0; + + for (i = 1; i < 14; i++) { + if (isprint(fhp[i])) { + if (seen_null) + return(0); + else + continue; + } + else if (fhp[i] == 0) { + seen_null = 1; + continue; + } + else + return(0); + } + + return(1); +} diff --git a/pcap-missing.h b/pcap-missing.h new file mode 100644 index 0000000..5c0ece2 --- /dev/null +++ b/pcap-missing.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1988-2002 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/tcpdump/pcap-missing.h,v 1.3 2005-06-03 22:08:52 guy Exp $ (LBL) + */ + +#ifndef tcpdump_pcap_missing_h +#define tcpdump_pcap_missing_h + +/* + * Declarations of functions that might be missing from libpcap. + */ + +#ifndef HAVE_PCAP_LIST_DATALINKS +extern int pcap_list_datalinks(pcap_t *, int **); +#endif + +#ifndef HAVE_PCAP_DATALINK_NAME_TO_VAL +/* + * We assume no platform has one but not the other. + */ +extern int pcap_datalink_name_to_val(const char *); +extern const char *pcap_datalink_val_to_name(int); +#endif + +#ifndef HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION +extern const char *pcap_datalink_val_to_description(int); +#endif + +#ifndef HAVE_PCAP_DUMP_FTELL +extern long pcap_dump_ftell(pcap_dumper_t *); +#endif + +#endif + + + + + + + + + diff --git a/pcap_dump_ftell.c b/pcap_dump_ftell.c new file mode 100644 index 0000000..6eb3a4a --- /dev/null +++ b/pcap_dump_ftell.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/pcap_dump_ftell.c,v 1.1 2005-06-03 22:08:52 guy Exp $ (LBL)"; +#endif + +#include +#include + +#include "pcap-missing.h" + +long +pcap_dump_ftell(pcap_dumper_t *p) +{ + return (ftell((FILE *)p)); +} diff --git a/pmap_prot.h b/pmap_prot.h new file mode 100644 index 0000000..67ad626 --- /dev/null +++ b/pmap_prot.h @@ -0,0 +1,89 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/pmap_prot.h,v 1.3 2005-04-27 21:43:48 guy Exp $ (LBL) */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)pmap_prot.h 1.14 88/02/08 SMI + * from: @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD: src/include/rpc/pmap_prot.h,v 1.9.2.1 1999/08/29 14:39:05 peter Exp $ + */ + +/* + * pmap_prot.h + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The following procedures are supported by the protocol: + * + * PMAPPROC_NULL() returns () + * takes nothing, returns nothing + * + * PMAPPROC_SET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Registers the tuple + * [prog, vers, prot, port]. + * + * PMAPPROC_UNSET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Un-registers pair + * [prog, vers]. prot and port are ignored. + * + * PMAPPROC_GETPORT(struct pmap) returns (long unsigned). + * 0 is failure. Otherwise returns the port number where the pair + * [prog, vers] is registered. It may lie! + * + * PMAPPROC_DUMP() RETURNS (struct pmaplist *) + * + * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>) + * RETURNS (port, string<>); + * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs); + * Calls the procedure on the local machine. If it is not registered, + * this procedure is quite; ie it does not return error information!!! + * This procedure only is supported on rpc/udp and calls via + * rpc/udp. This routine only passes null authentication parameters. + * This file has no interface to xdr routines for PMAPPROC_CALLIT. + * + * The service supports remote procedure calls on udp/ip or tcp/ip socket 111. + */ + +#define SUNRPC_PMAPPORT ((u_int16_t)111) +#define SUNRPC_PMAPPROG ((u_int32_t)100000) +#define SUNRPC_PMAPVERS ((u_int32_t)2) +#define SUNRPC_PMAPVERS_PROTO ((u_int32_t)2) +#define SUNRPC_PMAPVERS_ORIG ((u_int32_t)1) +#define SUNRPC_PMAPPROC_NULL ((u_int32_t)0) +#define SUNRPC_PMAPPROC_SET ((u_int32_t)1) +#define SUNRPC_PMAPPROC_UNSET ((u_int32_t)2) +#define SUNRPC_PMAPPROC_GETPORT ((u_int32_t)3) +#define SUNRPC_PMAPPROC_DUMP ((u_int32_t)4) +#define SUNRPC_PMAPPROC_CALLIT ((u_int32_t)5) + +struct sunrpc_pmap { + u_int32_t pm_prog; + u_int32_t pm_vers; + u_int32_t pm_prot; + u_int32_t pm_port; +}; diff --git a/ppp.h b/ppp.h new file mode 100644 index 0000000..f1a2c48 --- /dev/null +++ b/ppp.h @@ -0,0 +1,71 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/ppp.h,v 1.16 2004-10-20 16:14:16 hannes Exp $ (LBL) */ +/* + * Point to Point Protocol (PPP) RFC1331 + * + * Copyright 1989 by Carnegie Mellon. + * + * Permission to use, copy, modify, and distribute this program for any + * purpose and without fee is hereby granted, provided that this copyright + * and permission notice appear on all copies and supporting documentation, + * the name of Carnegie Mellon not be used in advertising or publicity + * pertaining to distribution of the program without specific prior + * permission, and notice be given in supporting documentation that copying + * and distribution is by permission of Carnegie Mellon and Stanford + * University. Carnegie Mellon makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ +#define PPP_HDRLEN 4 /* length of PPP header */ + +#define PPP_ADDRESS 0xff /* The address byte value */ +#define PPP_CONTROL 0x03 /* The control byte value */ + +#define PPP_WITHDIRECTION_IN 0x00 /* non-standard for DLT_PPP_WITHDIRECTION */ +#define PPP_WITHDIRECTION_OUT 0x01 /* non-standard for DLT_PPP_WITHDIRECTION */ + +/* Protocol numbers */ +#define PPP_IP 0x0021 /* Raw IP */ +#define PPP_OSI 0x0023 /* OSI Network Layer */ +#define PPP_NS 0x0025 /* Xerox NS IDP */ +#define PPP_DECNET 0x0027 /* DECnet Phase IV */ +#define PPP_APPLE 0x0029 /* Appletalk */ +#define PPP_IPX 0x002b /* Novell IPX */ +#define PPP_VJC 0x002d /* Van Jacobson Compressed TCP/IP */ +#define PPP_VJNC 0x002f /* Van Jacobson Uncompressed TCP/IP */ +#define PPP_BRPDU 0x0031 /* Bridging PDU */ +#define PPP_STII 0x0033 /* Stream Protocol (ST-II) */ +#define PPP_VINES 0x0035 /* Banyan Vines */ +#define PPP_ML 0x003d /* Multi-Link PPP */ +#define PPP_IPV6 0x0057 /* IPv6 */ +#define PPP_COMP 0x00fd /* Compressed Datagram */ + +#define PPP_HELLO 0x0201 /* 802.1d Hello Packets */ +#define PPP_LUXCOM 0x0231 /* Luxcom */ +#define PPP_SNS 0x0233 /* Sigma Network Systems */ +#define PPP_MPLS_UCAST 0x0281 /* rfc 3032 */ +#define PPP_MPLS_MCAST 0x0283 /* rfc 3022 */ + +#define PPP_IPCP 0x8021 /* IP Control Protocol */ +#define PPP_OSICP 0x8023 /* OSI Network Layer Control Protocol */ +#define PPP_NSCP 0x8025 /* Xerox NS IDP Control Protocol */ +#define PPP_DECNETCP 0x8027 /* DECnet Control Protocol */ +#define PPP_APPLECP 0x8029 /* Appletalk Control Protocol */ +#define PPP_IPXCP 0x802b /* Novell IPX Control Protocol */ +#define PPP_STIICP 0x8033 /* Strean Protocol Control Protocol */ +#define PPP_VINESCP 0x8035 /* Banyan Vines Control Protocol */ +#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ +#define PPP_CCP 0x80fd /* Compress Control Protocol */ +#define PPP_MPLSCP 0x8281 /* rfc 3022 */ + +#define PPP_LCP 0xc021 /* Link Control Protocol */ +#define PPP_PAP 0xc023 /* Password Authentication Protocol */ +#define PPP_LQM 0xc025 /* Link Quality Monitoring */ +#define PPP_SPAP 0xc027 +#define PPP_CHAP 0xc223 /* Challenge Handshake Authentication Protocol */ +#define PPP_BACP 0xc02b /* Bandwidth Allocation Control Protocol */ +#define PPP_BAP 0xc02d /* BAP */ +#define PPP_MPCP 0xc03d /* Multi-Link */ +#define PPP_SPAP_OLD 0xc123 +#define PPP_EAP 0xc227 + +extern struct tok ppptype2str[]; diff --git a/print-802_11.c b/print-802_11.c new file mode 100644 index 0000000..088840a --- /dev/null +++ b/print-802_11.c @@ -0,0 +1,1786 @@ +/* + * Copyright (c) 2001 + * Fortress Technologies, Inc. All rights reserved. + * Charlie Lenahan (clenahan@fortresstech.com) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.49 2007-12-29 23:25:02 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "ethertype.h" + +#include "extract.h" + +#include "cpack.h" + +#include "ieee802_11.h" +#include "ieee802_11_radio.h" + +#define PRINT_SSID(p) \ + if (p.ssid_present) { \ + printf(" ("); \ + fn_print(p.ssid.ssid, NULL); \ + printf(")"); \ + } + +#define PRINT_RATE(_sep, _r, _suf) \ + printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf) +#define PRINT_RATES(p) \ + if (p.rates_present) { \ + int z; \ + const char *sep = " ["; \ + for (z = 0; z < p.rates.length ; z++) { \ + PRINT_RATE(sep, p.rates.rate[z], \ + (p.rates.rate[z] & 0x80 ? "*" : "")); \ + sep = " "; \ + } \ + if (p.rates.length != 0) \ + printf(" Mbit]"); \ + } + +#define PRINT_DS_CHANNEL(p) \ + if (p.ds_present) \ + printf(" CH: %u", p.ds.channel); \ + printf("%s", \ + CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "" ); + +static const int ieee80211_htrates[16] = { + 13, /* IFM_IEEE80211_MCS0 */ + 26, /* IFM_IEEE80211_MCS1 */ + 39, /* IFM_IEEE80211_MCS2 */ + 52, /* IFM_IEEE80211_MCS3 */ + 78, /* IFM_IEEE80211_MCS4 */ + 104, /* IFM_IEEE80211_MCS5 */ + 117, /* IFM_IEEE80211_MCS6 */ + 130, /* IFM_IEEE80211_MCS7 */ + 26, /* IFM_IEEE80211_MCS8 */ + 52, /* IFM_IEEE80211_MCS9 */ + 78, /* IFM_IEEE80211_MCS10 */ + 104, /* IFM_IEEE80211_MCS11 */ + 156, /* IFM_IEEE80211_MCS12 */ + 208, /* IFM_IEEE80211_MCS13 */ + 234, /* IFM_IEEE80211_MCS14 */ + 260, /* IFM_IEEE80211_MCS15 */ +}; +#define PRINT_HT_RATE(_sep, _r, _suf) \ + printf("%s%.1f%s", _sep, (.5 * ieee80211_htrates[(_r) & 0xf]), _suf) + +static const char *auth_alg_text[]={"Open System","Shared Key","EAP"}; +#define NUM_AUTH_ALGS (sizeof auth_alg_text / sizeof auth_alg_text[0]) + +static const char *status_text[] = { + "Succesful", /* 0 */ + "Unspecified failure", /* 1 */ + "Reserved", /* 2 */ + "Reserved", /* 3 */ + "Reserved", /* 4 */ + "Reserved", /* 5 */ + "Reserved", /* 6 */ + "Reserved", /* 7 */ + "Reserved", /* 8 */ + "Reserved", /* 9 */ + "Cannot Support all requested capabilities in the Capability " + "Information field", /* 10 */ + "Reassociation denied due to inability to confirm that association " + "exists", /* 11 */ + "Association denied due to reason outside the scope of the " + "standard", /* 12 */ + "Responding station does not support the specified authentication " + "algorithm ", /* 13 */ + "Received an Authentication frame with authentication transaction " + "sequence number out of expected sequence", /* 14 */ + "Authentication rejected because of challenge failure", /* 15 */ + "Authentication rejected due to timeout waiting for next frame in " + "sequence", /* 16 */ + "Association denied because AP is unable to handle additional" + "associated stations", /* 17 */ + "Association denied due to requesting station not supporting all of " + "the data rates in BSSBasicRateSet parameter", /* 18 */ + "Association denied due to requesting station not supporting " + "short preamble operation", /* 19 */ + "Association denied due to requesting station not supporting " + "PBCC encoding", /* 20 */ + "Association denied due to requesting station not supporting " + "channel agility", /* 21 */ + "Association request rejected because Spectrum Management " + "capability is required", /* 22 */ + "Association request rejected because the information in the " + "Power Capability element is unacceptable", /* 23 */ + "Association request rejected because the information in the " + "Supported Channels element is unacceptable", /* 24 */ + "Association denied due to requesting station not supporting " + "short slot operation", /* 25 */ + "Association denied due to requesting station not supporting " + "DSSS-OFDM operation", /* 26 */ + "Association denied because the requested STA does not support HT " + "features", /* 27 */ + "Reserved", /* 28 */ + "Association denied because the requested STA does not support " + "the PCO transition time required by the AP", /* 29 */ + "Reserved", /* 30 */ + "Reserved", /* 31 */ + "Unspecified, QoS-related failure", /* 32 */ + "Association denied due to QAP having insufficient bandwidth " + "to handle another QSTA", /* 33 */ + "Association denied due to excessive frame loss rates and/or " + "poor conditions on current operating channel", /* 34 */ + "Association (with QBSS) denied due to requesting station not " + "supporting the QoS facility", /* 35 */ + "Association denied due to requesting station not supporting " + "Block Ack", /* 36 */ + "The request has been declined", /* 37 */ + "The request has not been successful as one or more parameters " + "have invalid values", /* 38 */ + "The TS has not been created because the request cannot be honored. " + "However, a suggested TSPEC is provided so that the initiating QSTA" + "may attempt to set another TS with the suggested changes to the " + "TSPEC", /* 39 */ + "Invalid Information Element", /* 40 */ + "Group Cipher is not valid", /* 41 */ + "Pairwise Cipher is not valid", /* 42 */ + "AKMP is not valid", /* 43 */ + "Unsupported RSN IE version", /* 44 */ + "Invalid RSN IE Capabilities", /* 45 */ + "Cipher suite is rejected per security policy", /* 46 */ + "The TS has not been created. However, the HC may be capable of " + "creating a TS, in response to a request, after the time indicated " + "in the TS Delay element", /* 47 */ + "Direct Link is not allowed in the BSS by policy", /* 48 */ + "Destination STA is not present within this QBSS.", /* 49 */ + "The Destination STA is not a QSTA.", /* 50 */ + +}; +#define NUM_STATUSES (sizeof status_text / sizeof status_text[0]) + +static const char *reason_text[] = { + "Reserved", /* 0 */ + "Unspecified reason", /* 1 */ + "Previous authentication no longer valid", /* 2 */ + "Deauthenticated because sending station is leaving (or has left) " + "IBSS or ESS", /* 3 */ + "Disassociated due to inactivity", /* 4 */ + "Disassociated because AP is unable to handle all currently " + " associated stations", /* 5 */ + "Class 2 frame received from nonauthenticated station", /* 6 */ + "Class 3 frame received from nonassociated station", /* 7 */ + "Disassociated because sending station is leaving " + "(or has left) BSS", /* 8 */ + "Station requesting (re)association is not authenticated with " + "responding station", /* 9 */ + "Disassociated because the information in the Power Capability " + "element is unacceptable", /* 10 */ + "Disassociated because the information in the SupportedChannels " + "element is unacceptable", /* 11 */ + "Invalid Information Element", /* 12 */ + "Reserved", /* 13 */ + "Michael MIC failure", /* 14 */ + "4-Way Handshake timeout", /* 15 */ + "Group key update timeout", /* 16 */ + "Information element in 4-Way Handshake different from (Re)Association" + "Request/Probe Response/Beacon", /* 17 */ + "Group Cipher is not valid", /* 18 */ + "AKMP is not valid", /* 20 */ + "Unsupported RSN IE version", /* 21 */ + "Invalid RSN IE Capabilities", /* 22 */ + "IEEE 802.1X Authentication failed", /* 23 */ + "Cipher suite is rejected per security policy", /* 24 */ + "Reserved", /* 25 */ + "Reserved", /* 26 */ + "Reserved", /* 27 */ + "Reserved", /* 28 */ + "Reserved", /* 29 */ + "Reserved", /* 30 */ + "TS deleted because QoS AP lacks sufficient bandwidth for this " + "QoS STA due to a change in BSS service characteristics or " + "operational mode (e.g. an HT BSS change from 40 MHz channel " + "to 20 MHz channel)", /* 31 */ + "Disassociated for unspecified, QoS-related reason", /* 32 */ + "Disassociated because QoS AP lacks sufficient bandwidth for this " + "QoS STA", /* 33 */ + "Disassociated because of excessive number of frames that need to be " + "acknowledged, but are not acknowledged for AP transmissions " + "and/or poor channel conditions", /* 34 */ + "Disassociated because STA is transmitting outside the limits " + "of its TXOPs", /* 35 */ + "Requested from peer STA as the STA is leaving the BSS " + "(or resetting)", /* 36 */ + "Requested from peer STA as it does not want to use the " + "mechanism", /* 37 */ + "Requested from peer STA as the STA received frames using the " + "mechanism for which a set up is required", /* 38 */ + "Requested from peer STA due to time out", /* 39 */ + "Reserved", /* 40 */ + "Reserved", /* 41 */ + "Reserved", /* 42 */ + "Reserved", /* 43 */ + "Reserved", /* 44 */ + "Peer STA does not support the requested cipher suite", /* 45 */ + "Association denied due to requesting STA not supporting HT " + "features", /* 46 */ +}; +#define NUM_REASONS (sizeof reason_text / sizeof reason_text[0]) + +static int +wep_print(const u_char *p) +{ + u_int32_t iv; + + if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN)) + return 0; + iv = EXTRACT_LE_32BITS(p); + + printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv), + IV_KEYID(iv)); + + return 1; +} + +static int +parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset, + u_int length) +{ + struct ssid_t ssid; + struct challenge_t challenge; + struct rates_t rates; + struct ds_t ds; + struct cf_t cf; + struct tim_t tim; + + /* + * We haven't seen any elements yet. + */ + pbody->challenge_present = 0; + pbody->ssid_present = 0; + pbody->rates_present = 0; + pbody->ds_present = 0; + pbody->cf_present = 0; + pbody->tim_present = 0; + + while (length != 0) { + if (!TTEST2(*(p + offset), 1)) + return 0; + if (length < 1) + return 0; + switch (*(p + offset)) { + case E_SSID: + if (!TTEST2(*(p + offset), 2)) + return 0; + if (length < 2) + return 0; + memcpy(&ssid, p + offset, 2); + offset += 2; + length -= 2; + if (ssid.length != 0) { + if (ssid.length > sizeof(ssid.ssid) - 1) + return 0; + if (!TTEST2(*(p + offset), ssid.length)) + return 0; + if (length < ssid.length) + return 0; + memcpy(&ssid.ssid, p + offset, ssid.length); + offset += ssid.length; + length -= ssid.length; + } + ssid.ssid[ssid.length] = '\0'; + /* + * Present and not truncated. + * + * If we haven't already seen an SSID IE, + * copy this one, otherwise ignore this one, + * so we later report the first one we saw. + */ + if (!pbody->ssid_present) { + pbody->ssid = ssid; + pbody->ssid_present = 1; + } + break; + case E_CHALLENGE: + if (!TTEST2(*(p + offset), 2)) + return 0; + if (length < 2) + return 0; + memcpy(&challenge, p + offset, 2); + offset += 2; + length -= 2; + if (challenge.length != 0) { + if (challenge.length > + sizeof(challenge.text) - 1) + return 0; + if (!TTEST2(*(p + offset), challenge.length)) + return 0; + if (length < challenge.length) + return 0; + memcpy(&challenge.text, p + offset, + challenge.length); + offset += challenge.length; + length -= challenge.length; + } + challenge.text[challenge.length] = '\0'; + /* + * Present and not truncated. + * + * If we haven't already seen a challenge IE, + * copy this one, otherwise ignore this one, + * so we later report the first one we saw. + */ + if (!pbody->challenge_present) { + pbody->challenge = challenge; + pbody->challenge_present = 1; + } + break; + case E_RATES: + if (!TTEST2(*(p + offset), 2)) + return 0; + if (length < 2) + return 0; + memcpy(&rates, p + offset, 2); + offset += 2; + length -= 2; + if (rates.length != 0) { + if (rates.length > sizeof rates.rate) + return 0; + if (!TTEST2(*(p + offset), rates.length)) + return 0; + if (length < rates.length) + return 0; + memcpy(&rates.rate, p + offset, rates.length); + offset += rates.length; + length -= rates.length; + } + /* + * Present and not truncated. + * + * If we haven't already seen a rates IE, + * copy this one if it's not zero-length, + * otherwise ignore this one, so we later + * report the first one we saw. + * + * We ignore zero-length rates IEs as some + * devices seem to put a zero-length rates + * IE, followed by an SSID IE, followed by + * a non-zero-length rates IE into frames, + * even though IEEE Std 802.11-2007 doesn't + * seem to indicate that a zero-length rates + * IE is valid. + */ + if (!pbody->rates_present && rates.length != 0) { + pbody->rates = rates; + pbody->rates_present = 1; + } + break; + case E_DS: + if (!TTEST2(*(p + offset), 3)) + return 0; + if (length < 3) + return 0; + memcpy(&ds, p + offset, 3); + offset += 3; + length -= 3; + /* + * Present and not truncated. + * + * If we haven't already seen a DS IE, + * copy this one, otherwise ignore this one, + * so we later report the first one we saw. + */ + if (!pbody->ds_present) { + pbody->ds = ds; + pbody->ds_present = 1; + } + break; + case E_CF: + if (!TTEST2(*(p + offset), 8)) + return 0; + if (length < 8) + return 0; + memcpy(&cf, p + offset, 8); + offset += 8; + length -= 8; + /* + * Present and not truncated. + * + * If we haven't already seen a CF IE, + * copy this one, otherwise ignore this one, + * so we later report the first one we saw. + */ + if (!pbody->cf_present) { + pbody->cf = cf; + pbody->cf_present = 1; + } + break; + case E_TIM: + if (!TTEST2(*(p + offset), 2)) + return 0; + if (length < 2) + return 0; + memcpy(&tim, p + offset, 2); + offset += 2; + length -= 2; + if (!TTEST2(*(p + offset), 3)) + return 0; + if (length < 3) + return 0; + memcpy(&tim.count, p + offset, 3); + offset += 3; + length -= 3; + + if (tim.length <= 3) + break; + if (tim.length - 3 > (int)sizeof tim.bitmap) + return 0; + if (!TTEST2(*(p + offset), tim.length - 3)) + return 0; + if (length < (u_int)(tim.length - 3)) + return 0; + memcpy(tim.bitmap, p + (tim.length - 3), + (tim.length - 3)); + offset += tim.length - 3; + length -= tim.length - 3; + /* + * Present and not truncated. + * + * If we haven't already seen a TIM IE, + * copy this one, otherwise ignore this one, + * so we later report the first one we saw. + */ + if (!pbody->tim_present) { + pbody->tim = tim; + pbody->tim_present = 1; + } + break; + default: +#if 0 + printf("(1) unhandled element_id (%d) ", + *(p + offset)); +#endif + if (!TTEST2(*(p + offset), 2)) + return 0; + if (length < 2) + return 0; + if (!TTEST2(*(p + offset + 2), *(p + offset + 1))) + return 0; + if (length < (u_int)(*(p + offset + 1) + 2)) + return 0; + offset += *(p + offset + 1) + 2; + length -= *(p + offset + 1) + 2; + break; + } + } + + /* No problems found. */ + return 1; +} + +/********************************************************************************* + * Print Handle functions for the management frame types + *********************************************************************************/ + +static int +handle_beacon(const u_char *p, u_int length) +{ + struct mgmt_body_t pbody; + int offset = 0; + int ret; + + memset(&pbody, 0, sizeof(pbody)); + + if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + + IEEE802_11_CAPINFO_LEN)) + return 0; + if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + + IEEE802_11_CAPINFO_LEN) + return 0; + memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN); + offset += IEEE802_11_TSTAMP_LEN; + length -= IEEE802_11_TSTAMP_LEN; + pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset); + offset += IEEE802_11_BCNINT_LEN; + length -= IEEE802_11_BCNINT_LEN; + pbody.capability_info = EXTRACT_LE_16BITS(p+offset); + offset += IEEE802_11_CAPINFO_LEN; + length -= IEEE802_11_CAPINFO_LEN; + + ret = parse_elements(&pbody, p, offset, length); + + PRINT_SSID(pbody); + PRINT_RATES(pbody); + printf(" %s", + CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS"); + PRINT_DS_CHANNEL(pbody); + + return ret; +} + +static int +handle_assoc_request(const u_char *p, u_int length) +{ + struct mgmt_body_t pbody; + int offset = 0; + int ret; + + memset(&pbody, 0, sizeof(pbody)); + + if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)) + return 0; + if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN) + return 0; + pbody.capability_info = EXTRACT_LE_16BITS(p); + offset += IEEE802_11_CAPINFO_LEN; + length -= IEEE802_11_CAPINFO_LEN; + pbody.listen_interval = EXTRACT_LE_16BITS(p+offset); + offset += IEEE802_11_LISTENINT_LEN; + length -= IEEE802_11_LISTENINT_LEN; + + ret = parse_elements(&pbody, p, offset, length); + + PRINT_SSID(pbody); + PRINT_RATES(pbody); + return ret; +} + +static int +handle_assoc_response(const u_char *p, u_int length) +{ + struct mgmt_body_t pbody; + int offset = 0; + int ret; + + memset(&pbody, 0, sizeof(pbody)); + + if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN + + IEEE802_11_AID_LEN)) + return 0; + if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN + + IEEE802_11_AID_LEN) + return 0; + pbody.capability_info = EXTRACT_LE_16BITS(p); + offset += IEEE802_11_CAPINFO_LEN; + length -= IEEE802_11_CAPINFO_LEN; + pbody.status_code = EXTRACT_LE_16BITS(p+offset); + offset += IEEE802_11_STATUS_LEN; + length -= IEEE802_11_STATUS_LEN; + pbody.aid = EXTRACT_LE_16BITS(p+offset); + offset += IEEE802_11_AID_LEN; + length -= IEEE802_11_AID_LEN; + + ret = parse_elements(&pbody, p, offset, length); + + printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 , + CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "", + (pbody.status_code < NUM_STATUSES + ? status_text[pbody.status_code] + : "n/a")); + + return ret; +} + +static int +handle_reassoc_request(const u_char *p, u_int length) +{ + struct mgmt_body_t pbody; + int offset = 0; + int ret; + + memset(&pbody, 0, sizeof(pbody)); + + if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN + + IEEE802_11_AP_LEN)) + return 0; + if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN + + IEEE802_11_AP_LEN) + return 0; + pbody.capability_info = EXTRACT_LE_16BITS(p); + offset += IEEE802_11_CAPINFO_LEN; + length -= IEEE802_11_CAPINFO_LEN; + pbody.listen_interval = EXTRACT_LE_16BITS(p+offset); + offset += IEEE802_11_LISTENINT_LEN; + length -= IEEE802_11_LISTENINT_LEN; + memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN); + offset += IEEE802_11_AP_LEN; + length -= IEEE802_11_AP_LEN; + + ret = parse_elements(&pbody, p, offset, length); + + PRINT_SSID(pbody); + printf(" AP : %s", etheraddr_string( pbody.ap )); + + return ret; +} + +static int +handle_reassoc_response(const u_char *p, u_int length) +{ + /* Same as a Association Reponse */ + return handle_assoc_response(p, length); +} + +static int +handle_probe_request(const u_char *p, u_int length) +{ + struct mgmt_body_t pbody; + int offset = 0; + int ret; + + memset(&pbody, 0, sizeof(pbody)); + + ret = parse_elements(&pbody, p, offset, length); + + PRINT_SSID(pbody); + PRINT_RATES(pbody); + + return ret; +} + +static int +handle_probe_response(const u_char *p, u_int length) +{ + struct mgmt_body_t pbody; + int offset = 0; + int ret; + + memset(&pbody, 0, sizeof(pbody)); + + if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + + IEEE802_11_CAPINFO_LEN)) + return 0; + if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN + + IEEE802_11_CAPINFO_LEN) + return 0; + memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN); + offset += IEEE802_11_TSTAMP_LEN; + length -= IEEE802_11_TSTAMP_LEN; + pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset); + offset += IEEE802_11_BCNINT_LEN; + length -= IEEE802_11_BCNINT_LEN; + pbody.capability_info = EXTRACT_LE_16BITS(p+offset); + offset += IEEE802_11_CAPINFO_LEN; + length -= IEEE802_11_CAPINFO_LEN; + + ret = parse_elements(&pbody, p, offset, length); + + PRINT_SSID(pbody); + PRINT_RATES(pbody); + PRINT_DS_CHANNEL(pbody); + + return ret; +} + +static int +handle_atim(void) +{ + /* the frame body for ATIM is null. */ + return 1; +} + +static int +handle_disassoc(const u_char *p, u_int length) +{ + struct mgmt_body_t pbody; + + memset(&pbody, 0, sizeof(pbody)); + + if (!TTEST2(*p, IEEE802_11_REASON_LEN)) + return 0; + if (length < IEEE802_11_REASON_LEN) + return 0; + pbody.reason_code = EXTRACT_LE_16BITS(p); + + printf(": %s", + (pbody.reason_code < NUM_REASONS) + ? reason_text[pbody.reason_code] + : "Reserved" ); + + return 1; +} + +static int +handle_auth(const u_char *p, u_int length) +{ + struct mgmt_body_t pbody; + int offset = 0; + int ret; + + memset(&pbody, 0, sizeof(pbody)); + + if (!TTEST2(*p, 6)) + return 0; + if (length < 6) + return 0; + pbody.auth_alg = EXTRACT_LE_16BITS(p); + offset += 2; + length -= 2; + pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset); + offset += 2; + length -= 2; + pbody.status_code = EXTRACT_LE_16BITS(p + offset); + offset += 2; + length -= 2; + + ret = parse_elements(&pbody, p, offset, length); + + if ((pbody.auth_alg == 1) && + ((pbody.auth_trans_seq_num == 2) || + (pbody.auth_trans_seq_num == 3))) { + printf(" (%s)-%x [Challenge Text] %s", + (pbody.auth_alg < NUM_AUTH_ALGS) + ? auth_alg_text[pbody.auth_alg] + : "Reserved", + pbody.auth_trans_seq_num, + ((pbody.auth_trans_seq_num % 2) + ? ((pbody.status_code < NUM_STATUSES) + ? status_text[pbody.status_code] + : "n/a") : "")); + return ret; + } + printf(" (%s)-%x: %s", + (pbody.auth_alg < NUM_AUTH_ALGS) + ? auth_alg_text[pbody.auth_alg] + : "Reserved", + pbody.auth_trans_seq_num, + (pbody.auth_trans_seq_num % 2) + ? ((pbody.status_code < NUM_STATUSES) + ? status_text[pbody.status_code] + : "n/a") + : ""); + + return ret; +} + +static int +handle_deauth(const struct mgmt_header_t *pmh, const u_char *p, u_int length) +{ + struct mgmt_body_t pbody; + int offset = 0; + const char *reason = NULL; + + memset(&pbody, 0, sizeof(pbody)); + + if (!TTEST2(*p, IEEE802_11_REASON_LEN)) + return 0; + if (length < IEEE802_11_REASON_LEN) + return 0; + pbody.reason_code = EXTRACT_LE_16BITS(p); + offset += IEEE802_11_REASON_LEN; + length -= IEEE802_11_REASON_LEN; + + reason = (pbody.reason_code < NUM_REASONS) + ? reason_text[pbody.reason_code] + : "Reserved"; + + if (eflag) { + printf(": %s", reason); + } else { + printf(" (%s): %s", etheraddr_string(pmh->sa), reason); + } + return 1; +} + +#define PRINT_HT_ACTION(v) (\ + (v) == 0 ? printf("TxChWidth") : \ + (v) == 1 ? printf("MIMOPwrSave") : \ + printf("Act#%d", (v)) \ +) +#define PRINT_BA_ACTION(v) (\ + (v) == 0 ? printf("ADDBA Request") : \ + (v) == 1 ? printf("ADDBA Response") : \ + (v) == 2 ? printf("DELBA") : \ + printf("Act#%d", (v)) \ +) +#define PRINT_MESHLINK_ACTION(v) (\ + (v) == 0 ? printf("Request") : \ + (v) == 1 ? printf("Report") : \ + printf("Act#%d", (v)) \ +) +#define PRINT_MESHPEERING_ACTION(v) (\ + (v) == 0 ? printf("Open") : \ + (v) == 1 ? printf("Confirm") : \ + (v) == 2 ? printf("Close") : \ + printf("Act#%d", (v)) \ +) +#define PRINT_MESHPATH_ACTION(v) (\ + (v) == 0 ? printf("Request") : \ + (v) == 1 ? printf("Report") : \ + (v) == 2 ? printf("Error") : \ + (v) == 3 ? printf("RootAnnouncement") : \ + printf("Act#%d", (v)) \ +) + +static int +handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length) +{ + if (!TTEST2(*p, 2)) + return 0; + if (length < 2) + return 0; + if (eflag) { + printf(": "); + } else { + printf(" (%s): ", etheraddr_string(pmh->sa)); + } + switch (p[0]) { + case 0: printf("Spectrum Management Act#%d", p[1]); break; + case 1: printf("QoS Act#%d", p[1]); break; + case 2: printf("DLS Act#%d", p[1]); break; + case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break; + case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break; + case 13: printf("MeshLMetric "); PRINT_MESHLINK_ACTION(p[1]); break; + case 15: printf("Interwork Act#%d", p[1]); break; + case 16: printf("Resource Act#%d", p[1]); break; + case 17: printf("Proxy Act#%d", p[1]); break; + case 30: printf("MeshPeering "); PRINT_MESHPEERING_ACTION(p[1]); break; + case 32: printf("MeshPath "); PRINT_MESHPATH_ACTION(p[1]); break; + case 127: printf("Vendor Act#%d", p[1]); break; + default: + printf("Reserved(%d) Act#%d", p[0], p[1]); + break; + } + return 1; +} + + +/********************************************************************************* + * Print Body funcs + *********************************************************************************/ + + +static int +mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh, + const u_char *p, u_int length) +{ + switch (FC_SUBTYPE(fc)) { + case ST_ASSOC_REQUEST: + printf("Assoc Request"); + return handle_assoc_request(p, length); + case ST_ASSOC_RESPONSE: + printf("Assoc Response"); + return handle_assoc_response(p, length); + case ST_REASSOC_REQUEST: + printf("ReAssoc Request"); + return handle_reassoc_request(p, length); + case ST_REASSOC_RESPONSE: + printf("ReAssoc Response"); + return handle_reassoc_response(p, length); + case ST_PROBE_REQUEST: + printf("Probe Request"); + return handle_probe_request(p, length); + case ST_PROBE_RESPONSE: + printf("Probe Response"); + return handle_probe_response(p, length); + case ST_BEACON: + printf("Beacon"); + return handle_beacon(p, length); + case ST_ATIM: + printf("ATIM"); + return handle_atim(); + case ST_DISASSOC: + printf("Disassociation"); + return handle_disassoc(p, length); + case ST_AUTH: + printf("Authentication"); + if (!TTEST2(*p, 3)) + return 0; + if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) { + printf("Authentication (Shared-Key)-3 "); + return wep_print(p); + } + return handle_auth(p, length); + case ST_DEAUTH: + printf("DeAuthentication"); + return handle_deauth(pmh, p, length); + break; + case ST_ACTION: + printf("Action"); + return handle_action(pmh, p, length); + break; + default: + printf("Unhandled Management subtype(%x)", + FC_SUBTYPE(fc)); + return 1; + } +} + + +/********************************************************************************* + * Handles printing all the control frame types + *********************************************************************************/ + +static int +ctrl_body_print(u_int16_t fc, const u_char *p) +{ + switch (FC_SUBTYPE(fc)) { + case CTRL_CONTROL_WRAPPER: + printf("Control Wrapper"); + /* XXX - requires special handling */ + break; + case CTRL_BAR: + printf("BAR"); + if (!TTEST2(*p, CTRL_BAR_HDRLEN)) + return 0; + if (!eflag) + printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ", + etheraddr_string(((const struct ctrl_bar_t *)p)->ra), + etheraddr_string(((const struct ctrl_bar_t *)p)->ta), + EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)), + EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq))); + break; + case CTRL_BA: + printf("BA"); + if (!TTEST2(*p, CTRL_BA_HDRLEN)) + return 0; + if (!eflag) + printf(" RA:%s ", + etheraddr_string(((const struct ctrl_ba_t *)p)->ra)); + break; + case CTRL_PS_POLL: + printf("Power Save-Poll"); + if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN)) + return 0; + printf(" AID(%x)", + EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid))); + break; + case CTRL_RTS: + printf("Request-To-Send"); + if (!TTEST2(*p, CTRL_RTS_HDRLEN)) + return 0; + if (!eflag) + printf(" TA:%s ", + etheraddr_string(((const struct ctrl_rts_t *)p)->ta)); + break; + case CTRL_CTS: + printf("Clear-To-Send"); + if (!TTEST2(*p, CTRL_CTS_HDRLEN)) + return 0; + if (!eflag) + printf(" RA:%s ", + etheraddr_string(((const struct ctrl_cts_t *)p)->ra)); + break; + case CTRL_ACK: + printf("Acknowledgment"); + if (!TTEST2(*p, CTRL_ACK_HDRLEN)) + return 0; + if (!eflag) + printf(" RA:%s ", + etheraddr_string(((const struct ctrl_ack_t *)p)->ra)); + break; + case CTRL_CF_END: + printf("CF-End"); + if (!TTEST2(*p, CTRL_END_HDRLEN)) + return 0; + if (!eflag) + printf(" RA:%s ", + etheraddr_string(((const struct ctrl_end_t *)p)->ra)); + break; + case CTRL_END_ACK: + printf("CF-End+CF-Ack"); + if (!TTEST2(*p, CTRL_END_ACK_HDRLEN)) + return 0; + if (!eflag) + printf(" RA:%s ", + etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra)); + break; + default: + printf("Unknown Ctrl Subtype"); + } + return 1; +} + +/* + * Print Header funcs + */ + +/* + * Data Frame - Address field contents + * + * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4 + * 0 | 0 | DA | SA | BSSID | n/a + * 0 | 1 | DA | BSSID | SA | n/a + * 1 | 0 | BSSID | SA | DA | n/a + * 1 | 1 | RA | TA | DA | SA + */ + +static void +data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp, + const u_int8_t **dstp) +{ + u_int subtype = FC_SUBTYPE(fc); + + if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) || + DATA_FRAME_IS_QOS(subtype)) { + printf("CF "); + if (DATA_FRAME_IS_CF_ACK(subtype)) { + if (DATA_FRAME_IS_CF_POLL(subtype)) + printf("Ack/Poll"); + else + printf("Ack"); + } else { + if (DATA_FRAME_IS_CF_POLL(subtype)) + printf("Poll"); + } + if (DATA_FRAME_IS_QOS(subtype)) + printf("+QoS"); + printf(" "); + } + +#define ADDR1 (p + 4) +#define ADDR2 (p + 10) +#define ADDR3 (p + 16) +#define ADDR4 (p + 24) + + if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) { + if (srcp != NULL) + *srcp = ADDR2; + if (dstp != NULL) + *dstp = ADDR1; + if (!eflag) + return; + printf("DA:%s SA:%s BSSID:%s ", + etheraddr_string(ADDR1), etheraddr_string(ADDR2), + etheraddr_string(ADDR3)); + } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) { + if (srcp != NULL) + *srcp = ADDR3; + if (dstp != NULL) + *dstp = ADDR1; + if (!eflag) + return; + printf("DA:%s BSSID:%s SA:%s ", + etheraddr_string(ADDR1), etheraddr_string(ADDR2), + etheraddr_string(ADDR3)); + } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) { + if (srcp != NULL) + *srcp = ADDR2; + if (dstp != NULL) + *dstp = ADDR3; + if (!eflag) + return; + printf("BSSID:%s SA:%s DA:%s ", + etheraddr_string(ADDR1), etheraddr_string(ADDR2), + etheraddr_string(ADDR3)); + } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { + if (srcp != NULL) + *srcp = ADDR4; + if (dstp != NULL) + *dstp = ADDR3; + if (!eflag) + return; + printf("RA:%s TA:%s DA:%s SA:%s ", + etheraddr_string(ADDR1), etheraddr_string(ADDR2), + etheraddr_string(ADDR3), etheraddr_string(ADDR4)); + } + +#undef ADDR1 +#undef ADDR2 +#undef ADDR3 +#undef ADDR4 +} + +static void +mgmt_header_print(const u_char *p, const u_int8_t **srcp, + const u_int8_t **dstp) +{ + const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p; + + if (srcp != NULL) + *srcp = hp->sa; + if (dstp != NULL) + *dstp = hp->da; + if (!eflag) + return; + + printf("BSSID:%s DA:%s SA:%s ", + etheraddr_string((hp)->bssid), etheraddr_string((hp)->da), + etheraddr_string((hp)->sa)); +} + +static void +ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp, + const u_int8_t **dstp) +{ + if (srcp != NULL) + *srcp = NULL; + if (dstp != NULL) + *dstp = NULL; + if (!eflag) + return; + + switch (FC_SUBTYPE(fc)) { + case CTRL_BAR: + printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ", + etheraddr_string(((const struct ctrl_bar_t *)p)->ra), + etheraddr_string(((const struct ctrl_bar_t *)p)->ta), + EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)), + EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq))); + break; + case CTRL_BA: + printf("RA:%s ", + etheraddr_string(((const struct ctrl_ba_t *)p)->ra)); + break; + case CTRL_PS_POLL: + printf("BSSID:%s TA:%s ", + etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid), + etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta)); + break; + case CTRL_RTS: + printf("RA:%s TA:%s ", + etheraddr_string(((const struct ctrl_rts_t *)p)->ra), + etheraddr_string(((const struct ctrl_rts_t *)p)->ta)); + break; + case CTRL_CTS: + printf("RA:%s ", + etheraddr_string(((const struct ctrl_cts_t *)p)->ra)); + break; + case CTRL_ACK: + printf("RA:%s ", + etheraddr_string(((const struct ctrl_ack_t *)p)->ra)); + break; + case CTRL_CF_END: + printf("RA:%s BSSID:%s ", + etheraddr_string(((const struct ctrl_end_t *)p)->ra), + etheraddr_string(((const struct ctrl_end_t *)p)->bssid)); + break; + case CTRL_END_ACK: + printf("RA:%s BSSID:%s ", + etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra), + etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid)); + break; + default: + printf("(H) Unknown Ctrl Subtype"); + break; + } +} + +static int +extract_header_length(u_int16_t fc) +{ + int len; + + switch (FC_TYPE(fc)) { + case T_MGMT: + return MGMT_HDRLEN; + case T_CTRL: + switch (FC_SUBTYPE(fc)) { + case CTRL_BAR: + return CTRL_BAR_HDRLEN; + case CTRL_PS_POLL: + return CTRL_PS_POLL_HDRLEN; + case CTRL_RTS: + return CTRL_RTS_HDRLEN; + case CTRL_CTS: + return CTRL_CTS_HDRLEN; + case CTRL_ACK: + return CTRL_ACK_HDRLEN; + case CTRL_CF_END: + return CTRL_END_HDRLEN; + case CTRL_END_ACK: + return CTRL_END_ACK_HDRLEN; + default: + return 0; + } + case T_DATA: + len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24; + if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) + len += 2; + return len; + default: + printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc)); + return 0; + } +} + +static int +extract_mesh_header_length(const u_char *p) +{ + return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3)); +} + +/* + * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp" + * to point to the source and destination MAC addresses in any case if + * "srcp" and "dstp" aren't null. + */ +static void +ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, u_int hdrlen, + u_int meshdrlen, const u_int8_t **srcp, const u_int8_t **dstp) +{ + if (vflag) { + if (FC_MORE_DATA(fc)) + printf("More Data "); + if (FC_MORE_FLAG(fc)) + printf("More Fragments "); + if (FC_POWER_MGMT(fc)) + printf("Pwr Mgmt "); + if (FC_RETRY(fc)) + printf("Retry "); + if (FC_ORDER(fc)) + printf("Strictly Ordered "); + if (FC_WEP(fc)) + printf("WEP Encrypted "); + if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL) + printf("%dus ", + EXTRACT_LE_16BITS( + &((const struct mgmt_header_t *)p)->duration)); + } + if (meshdrlen != 0) { + const struct meshcntl_t *mc = + (const struct meshcntl_t *)&p[hdrlen - meshdrlen]; + int ae = mc->flags & 3; + + printf("MeshData (AE %d TTL %u seq %u", ae, mc->ttl, + EXTRACT_LE_32BITS(mc->seq)); + if (ae > 0) + printf(" A4:%s", etheraddr_string(mc->addr4)); + if (ae > 1) + printf(" A5:%s", etheraddr_string(mc->addr5)); + if (ae > 2) + printf(" A6:%s", etheraddr_string(mc->addr6)); + printf(") "); + } + + switch (FC_TYPE(fc)) { + case T_MGMT: + mgmt_header_print(p, srcp, dstp); + break; + case T_CTRL: + ctrl_header_print(fc, p, srcp, dstp); + break; + case T_DATA: + data_header_print(fc, p, srcp, dstp); + break; + default: + printf("(header) unknown IEEE802.11 frame type (%d)", + FC_TYPE(fc)); + *srcp = NULL; + *dstp = NULL; + break; + } +} + +#ifndef roundup2 +#define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ +#endif + +static u_int +ieee802_11_print(const u_char *p, u_int length, u_int orig_caplen, int pad, + u_int fcslen) +{ + u_int16_t fc; + u_int caplen, hdrlen, meshdrlen; + const u_int8_t *src, *dst; + u_short extracted_ethertype; + + caplen = orig_caplen; + /* Remove FCS, if present */ + if (length < fcslen) { + printf("[|802.11]"); + return caplen; + } + length -= fcslen; + if (caplen > length) { + /* Amount of FCS in actual packet data, if any */ + fcslen = caplen - length; + caplen -= fcslen; + snapend -= fcslen; + } + + if (caplen < IEEE802_11_FC_LEN) { + printf("[|802.11]"); + return orig_caplen; + } + + fc = EXTRACT_LE_16BITS(p); + hdrlen = extract_header_length(fc); + if (pad) + hdrlen = roundup2(hdrlen, 4); + if (FC_TYPE(fc) == T_DATA && DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) { + meshdrlen = extract_mesh_header_length(p+hdrlen); + hdrlen += meshdrlen; + } else + meshdrlen = 0; + + + if (caplen < hdrlen) { + printf("[|802.11]"); + return hdrlen; + } + + ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst); + + /* + * Go past the 802.11 header. + */ + length -= hdrlen; + caplen -= hdrlen; + p += hdrlen; + + switch (FC_TYPE(fc)) { + case T_MGMT: + if (!mgmt_body_print(fc, + (const struct mgmt_header_t *)(p - hdrlen), p, length)) { + printf("[|802.11]"); + return hdrlen; + } + break; + case T_CTRL: + if (!ctrl_body_print(fc, p - hdrlen)) { + printf("[|802.11]"); + return hdrlen; + } + break; + case T_DATA: + if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc))) + return hdrlen; /* no-data frame */ + /* There may be a problem w/ AP not having this bit set */ + if (FC_WEP(fc)) { + if (!wep_print(p)) { + printf("[|802.11]"); + return hdrlen; + } + } else if (llc_print(p, length, caplen, dst, src, + &extracted_ethertype) == 0) { + /* + * Some kinds of LLC packet we cannot + * handle intelligently + */ + if (!eflag) + ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen, + meshdrlen, NULL, NULL); + if (extracted_ethertype) + printf("(LLC %s) ", + etherproto_string( + htons(extracted_ethertype))); + if (!suppress_default_print) + default_print(p, caplen); + } + break; + default: + printf("unknown 802.11 frame type (%d)", FC_TYPE(fc)); + break; + } + + return hdrlen; +} + +/* + * This is the top level routine of the printer. 'p' points + * to the 802.11 header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + return ieee802_11_print(p, h->len, h->caplen, 0, 0); +} + +#define IEEE80211_CHAN_FHSS \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK) +#define IEEE80211_CHAN_A \ + (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) +#define IEEE80211_CHAN_B \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK) +#define IEEE80211_CHAN_PUREG \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM) +#define IEEE80211_CHAN_G \ + (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN) + +#define IS_CHAN_FHSS(flags) \ + ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS) +#define IS_CHAN_A(flags) \ + ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A) +#define IS_CHAN_B(flags) \ + ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B) +#define IS_CHAN_PUREG(flags) \ + ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG) +#define IS_CHAN_G(flags) \ + ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G) +#define IS_CHAN_ANYG(flags) \ + (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags)) + +static void +print_chaninfo(int freq, int flags) +{ + printf("%u MHz", freq); + if (IS_CHAN_FHSS(flags)) + printf(" FHSS"); + if (IS_CHAN_A(flags)) { + if (flags & IEEE80211_CHAN_HALF) + printf(" 11a/10Mhz"); + else if (flags & IEEE80211_CHAN_QUARTER) + printf(" 11a/5Mhz"); + else + printf(" 11a"); + } + if (IS_CHAN_ANYG(flags)) { + if (flags & IEEE80211_CHAN_HALF) + printf(" 11g/10Mhz"); + else if (flags & IEEE80211_CHAN_QUARTER) + printf(" 11g/5Mhz"); + else + printf(" 11g"); + } else if (IS_CHAN_B(flags)) + printf(" 11b"); + if (flags & IEEE80211_CHAN_TURBO) + printf(" Turbo"); + if (flags & IEEE80211_CHAN_HT20) + printf(" ht/20"); + else if (flags & IEEE80211_CHAN_HT40D) + printf(" ht/40-"); + else if (flags & IEEE80211_CHAN_HT40U) + printf(" ht/40+"); + printf(" "); +} + +static int +print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags) +{ + union { + int8_t i8; + u_int8_t u8; + int16_t i16; + u_int16_t u16; + u_int32_t u32; + u_int64_t u64; + } u, u2, u3, u4; + int rc; + + switch (bit) { + case IEEE80211_RADIOTAP_FLAGS: + rc = cpack_uint8(s, &u.u8); + *flags = u.u8; + break; + case IEEE80211_RADIOTAP_RATE: + case IEEE80211_RADIOTAP_DB_ANTSIGNAL: + case IEEE80211_RADIOTAP_DB_ANTNOISE: + case IEEE80211_RADIOTAP_ANTENNA: + rc = cpack_uint8(s, &u.u8); + break; + case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: + case IEEE80211_RADIOTAP_DBM_ANTNOISE: + rc = cpack_int8(s, &u.i8); + break; + case IEEE80211_RADIOTAP_CHANNEL: + rc = cpack_uint16(s, &u.u16); + if (rc != 0) + break; + rc = cpack_uint16(s, &u2.u16); + break; + case IEEE80211_RADIOTAP_FHSS: + case IEEE80211_RADIOTAP_LOCK_QUALITY: + case IEEE80211_RADIOTAP_TX_ATTENUATION: + rc = cpack_uint16(s, &u.u16); + break; + case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: + rc = cpack_uint8(s, &u.u8); + break; + case IEEE80211_RADIOTAP_DBM_TX_POWER: + rc = cpack_int8(s, &u.i8); + break; + case IEEE80211_RADIOTAP_TSFT: + rc = cpack_uint64(s, &u.u64); + break; + case IEEE80211_RADIOTAP_XCHANNEL: + rc = cpack_uint32(s, &u.u32); + if (rc != 0) + break; + rc = cpack_uint16(s, &u2.u16); + if (rc != 0) + break; + rc = cpack_uint8(s, &u3.u8); + if (rc != 0) + break; + rc = cpack_uint8(s, &u4.u8); + break; + default: + /* this bit indicates a field whose + * size we do not know, so we cannot + * proceed. Just print the bit number. + */ + printf("[bit %u] ", bit); + return -1; + } + + if (rc != 0) { + printf("[|802.11]"); + return rc; + } + + switch (bit) { + case IEEE80211_RADIOTAP_CHANNEL: + print_chaninfo(u.u16, u2.u16); + break; + case IEEE80211_RADIOTAP_FHSS: + printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff); + break; + case IEEE80211_RADIOTAP_RATE: + if (u.u8 & 0x80) + PRINT_HT_RATE("", u.u8, " Mb/s "); + else + PRINT_RATE("", u.u8, " Mb/s "); + break; + case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: + printf("%ddB signal ", u.i8); + break; + case IEEE80211_RADIOTAP_DBM_ANTNOISE: + printf("%ddB noise ", u.i8); + break; + case IEEE80211_RADIOTAP_DB_ANTSIGNAL: + printf("%ddB signal ", u.u8); + break; + case IEEE80211_RADIOTAP_DB_ANTNOISE: + printf("%ddB noise ", u.u8); + break; + case IEEE80211_RADIOTAP_LOCK_QUALITY: + printf("%u sq ", u.u16); + break; + case IEEE80211_RADIOTAP_TX_ATTENUATION: + printf("%d tx power ", -(int)u.u16); + break; + case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: + printf("%ddB tx power ", -(int)u.u8); + break; + case IEEE80211_RADIOTAP_DBM_TX_POWER: + printf("%ddBm tx power ", u.i8); + break; + case IEEE80211_RADIOTAP_FLAGS: + if (u.u8 & IEEE80211_RADIOTAP_F_CFP) + printf("cfp "); + if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE) + printf("short preamble "); + if (u.u8 & IEEE80211_RADIOTAP_F_WEP) + printf("wep "); + if (u.u8 & IEEE80211_RADIOTAP_F_FRAG) + printf("fragmented "); + if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS) + printf("bad-fcs "); + break; + case IEEE80211_RADIOTAP_ANTENNA: + printf("antenna %d ", u.u8); + break; + case IEEE80211_RADIOTAP_TSFT: + printf("%" PRIu64 "us tsft ", u.u64); + break; + case IEEE80211_RADIOTAP_XCHANNEL: + print_chaninfo(u2.u16, u.u32); + break; + } + return 0; +} + +static u_int +ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen) +{ +#define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x))) +#define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x))) +#define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x))) +#define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x))) +#define BITNO_2(x) (((x) & 2) ? 1 : 0) +#define BIT(n) (1U << n) +#define IS_EXTENDED(__p) \ + (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0 + + struct cpack_state cpacker; + struct ieee80211_radiotap_header *hdr; + u_int32_t present, next_present; + u_int32_t *presentp, *last_presentp; + enum ieee80211_radiotap_type bit; + int bit0; + const u_char *iter; + u_int len; + u_int8_t flags; + int pad; + u_int fcslen; + + if (caplen < sizeof(*hdr)) { + printf("[|802.11]"); + return caplen; + } + + hdr = (struct ieee80211_radiotap_header *)p; + + len = EXTRACT_LE_16BITS(&hdr->it_len); + + if (caplen < len) { + printf("[|802.11]"); + return caplen; + } + for (last_presentp = &hdr->it_present; + IS_EXTENDED(last_presentp) && + (u_char*)(last_presentp + 1) <= p + len; + last_presentp++); + + /* are there more bitmap extensions than bytes in header? */ + if (IS_EXTENDED(last_presentp)) { + printf("[|802.11]"); + return caplen; + } + + iter = (u_char*)(last_presentp + 1); + + if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) { + /* XXX */ + printf("[|802.11]"); + return caplen; + } + + /* Assume no flags */ + flags = 0; + /* Assume no Atheros padding between 802.11 header and body */ + pad = 0; + /* Assume no FCS at end of frame */ + fcslen = 0; + for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp; + presentp++, bit0 += 32) { + for (present = EXTRACT_LE_32BITS(presentp); present; + present = next_present) { + /* clear the least significant bit that is set */ + next_present = present & (present - 1); + + /* extract the least significant bit that is set */ + bit = (enum ieee80211_radiotap_type) + (bit0 + BITNO_32(present ^ next_present)); + + if (print_radiotap_field(&cpacker, bit, &flags) != 0) + goto out; + } + } + + if (flags & IEEE80211_RADIOTAP_F_DATAPAD) + pad = 1; /* Atheros padding */ + if (flags & IEEE80211_RADIOTAP_F_FCS) + fcslen = 4; /* FCS at end of packet */ +out: + return len + ieee802_11_print(p + len, length - len, caplen - len, pad, + fcslen); +#undef BITNO_32 +#undef BITNO_16 +#undef BITNO_8 +#undef BITNO_4 +#undef BITNO_2 +#undef BIT +} + +static u_int +ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen) +{ + u_int32_t caphdr_len; + + if (caplen < 8) { + printf("[|802.11]"); + return caplen; + } + + caphdr_len = EXTRACT_32BITS(p + 4); + if (caphdr_len < 8) { + /* + * Yow! The capture header length is claimed not + * to be large enough to include even the version + * cookie or capture header length! + */ + printf("[|802.11]"); + return caplen; + } + + if (caplen < caphdr_len) { + printf("[|802.11]"); + return caplen; + } + + return caphdr_len + ieee802_11_print(p + caphdr_len, + length - caphdr_len, caplen - caphdr_len, 0, 0); +} + +#define PRISM_HDR_LEN 144 + +#define WLANCAP_MAGIC_COOKIE_BASE 0x80211000 +#define WLANCAP_MAGIC_COOKIE_V1 0x80211001 +#define WLANCAP_MAGIC_COOKIE_V2 0x80211002 + +/* + * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header, + * containing information such as radio information, which we + * currently ignore. + * + * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or + * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS + * (currently, on Linux, there's no ARPHRD_ type for + * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM + * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for + * the AVS header, and the first 4 bytes of the header are used to + * indicate whether it's a Prism header or an AVS header). + */ +u_int +prism_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + u_int32_t msgcode; + + if (caplen < 4) { + printf("[|802.11]"); + return caplen; + } + + msgcode = EXTRACT_32BITS(p); + if (msgcode == WLANCAP_MAGIC_COOKIE_V1 || + msgcode == WLANCAP_MAGIC_COOKIE_V2) + return ieee802_11_avs_radio_print(p, length, caplen); + + if (caplen < PRISM_HDR_LEN) { + printf("[|802.11]"); + return caplen; + } + + return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN, + length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0); +} + +/* + * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra + * header, containing information such as radio information. + */ +u_int +ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + return ieee802_11_radio_print(p, h->len, h->caplen); +} + +/* + * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an + * extra header, containing information such as radio information, + * which we currently ignore. + */ +u_int +ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + return ieee802_11_avs_radio_print(p, h->len, h->caplen); +} diff --git a/print-ah.c b/print-ah.c new file mode 100644 index 0000000..ecd106b --- /dev/null +++ b/print-ah.c @@ -0,0 +1,71 @@ +/* $NetBSD: print-ah.c,v 1.4 1996/05/20 00:41:16 fvdl Exp $ */ + +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ah.c,v 1.22 2003-11-19 00:36:06 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "ah.h" + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +int +ah_print(register const u_char *bp) +{ + register const struct ah *ah; + register const u_char *ep; + int sumlen; + u_int32_t spi; + + ah = (const struct ah *)bp; + ep = snapend; /* 'ep' points to the end of available data. */ + + TCHECK(*ah); + + sumlen = ah->ah_len << 2; + spi = EXTRACT_32BITS(&ah->ah_spi); + + printf("AH(spi=0x%08x", spi); + if (vflag) + printf(",sumlen=%d", sumlen); + printf(",seq=0x%x", EXTRACT_32BITS(ah + 1)); + if (bp + sizeof(struct ah) + sumlen > ep) + fputs("[truncated]", stdout); + fputs("): ", stdout); + + return sizeof(struct ah) + sumlen; + trunc: + fputs("[|AH]", stdout); + return -1; +} diff --git a/print-aodv.c b/print-aodv.c new file mode 100644 index 0000000..c5f6622 --- /dev/null +++ b/print-aodv.c @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2003 Bruce M. Simpson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bruce M. Simpson. + * 4. Neither the name of Bruce M. Simpson nor the names of co- + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bruce M. Simpson AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Bruce M. Simpson OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-aodv.c,v 1.11 2004-03-24 00:30:19 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +#include "aodv.h" + +static void +aodv_extension(const struct aodv_ext *ep, u_int length) +{ + u_int i; + const struct aodv_hello *ah; + + switch (ep->type) { + case AODV_EXT_HELLO: + if (snapend < (u_char *) ep) { + printf(" [|hello]"); + return; + } + i = min(length, (u_int)(snapend - (u_char *)ep)); + if (i < sizeof(struct aodv_hello)) { + printf(" [|hello]"); + return; + } + i -= sizeof(struct aodv_hello); + ah = (void *)ep; + printf("\n\text HELLO %ld ms", + (unsigned long)EXTRACT_32BITS(&ah->interval)); + break; + + default: + printf("\n\text %u %u", ep->type, ep->length); + break; + } +} + +static void +aodv_rreq(const union aodv *ap, const u_char *dat, u_int length) +{ + u_int i; + + if (snapend < dat) { + printf(" [|aodv]"); + return; + } + i = min(length, (u_int)(snapend - dat)); + if (i < sizeof(ap->rreq)) { + printf(" [|rreq]"); + return; + } + i -= sizeof(ap->rreq); + printf(" rreq %u %s%s%s%s%shops %u id 0x%08lx\n" + "\tdst %s seq %lu src %s seq %lu", length, + ap->rreq.rreq_type & RREQ_JOIN ? "[J]" : "", + ap->rreq.rreq_type & RREQ_REPAIR ? "[R]" : "", + ap->rreq.rreq_type & RREQ_GRAT ? "[G]" : "", + ap->rreq.rreq_type & RREQ_DEST ? "[D]" : "", + ap->rreq.rreq_type & RREQ_UNKNOWN ? "[U] " : " ", + ap->rreq.rreq_hops, + (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_id), + ipaddr_string(&ap->rreq.rreq_da), + (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_ds), + ipaddr_string(&ap->rreq.rreq_oa), + (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_os)); + if (i >= sizeof(struct aodv_ext)) + aodv_extension((void *)(&ap->rreq + 1), i); +} + +static void +aodv_rrep(const union aodv *ap, const u_char *dat, u_int length) +{ + u_int i; + + if (snapend < dat) { + printf(" [|aodv]"); + return; + } + i = min(length, (u_int)(snapend - dat)); + if (i < sizeof(ap->rrep)) { + printf(" [|rrep]"); + return; + } + i -= sizeof(ap->rrep); + printf(" rrep %u %s%sprefix %u hops %u\n" + "\tdst %s dseq %lu src %s %lu ms", length, + ap->rrep.rrep_type & RREP_REPAIR ? "[R]" : "", + ap->rrep.rrep_type & RREP_ACK ? "[A] " : " ", + ap->rrep.rrep_ps & RREP_PREFIX_MASK, + ap->rrep.rrep_hops, + ipaddr_string(&ap->rrep.rrep_da), + (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_ds), + ipaddr_string(&ap->rrep.rrep_oa), + (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_life)); + if (i >= sizeof(struct aodv_ext)) + aodv_extension((void *)(&ap->rrep + 1), i); +} + +static void +aodv_rerr(const union aodv *ap, const u_char *dat, u_int length) +{ + u_int i; + const struct rerr_unreach *dp = NULL; + int n, trunc; + + if (snapend < dat) { + printf(" [|aodv]"); + return; + } + i = min(length, (u_int)(snapend - dat)); + if (i < offsetof(struct aodv_rerr, r)) { + printf(" [|rerr]"); + return; + } + i -= offsetof(struct aodv_rerr, r); + dp = &ap->rerr.r.dest[0]; + n = ap->rerr.rerr_dc * sizeof(ap->rerr.r.dest[0]); + printf(" rerr %s [items %u] [%u]:", + ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "", + ap->rerr.rerr_dc, length); + trunc = n - (i/sizeof(ap->rerr.r.dest[0])); + for (; i >= sizeof(ap->rerr.r.dest[0]); + ++dp, i -= sizeof(ap->rerr.r.dest[0])) { + printf(" {%s}(%ld)", ipaddr_string(&dp->u_da), + (unsigned long)EXTRACT_32BITS(&dp->u_ds)); + } + if (trunc) + printf("[|rerr]"); +} + +static void +#ifdef INET6 +aodv_v6_rreq(const union aodv *ap, const u_char *dat, u_int length) +#else +aodv_v6_rreq(const union aodv *ap _U_, const u_char *dat _U_, u_int length) +#endif +{ +#ifdef INET6 + u_int i; + + if (snapend < dat) { + printf(" [|aodv]"); + return; + } + i = min(length, (u_int)(snapend - dat)); + if (i < sizeof(ap->rreq6)) { + printf(" [|rreq6]"); + return; + } + i -= sizeof(ap->rreq6); + printf(" v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n" + "\tdst %s seq %lu src %s seq %lu", length, + ap->rreq6.rreq_type & RREQ_JOIN ? "[J]" : "", + ap->rreq6.rreq_type & RREQ_REPAIR ? "[R]" : "", + ap->rreq6.rreq_type & RREQ_GRAT ? "[G]" : "", + ap->rreq6.rreq_type & RREQ_DEST ? "[D]" : "", + ap->rreq6.rreq_type & RREQ_UNKNOWN ? "[U] " : " ", + ap->rreq6.rreq_hops, + (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_id), + ip6addr_string(&ap->rreq6.rreq_da), + (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_ds), + ip6addr_string(&ap->rreq6.rreq_oa), + (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_os)); + if (i >= sizeof(struct aodv_ext)) + aodv_extension((void *)(&ap->rreq6 + 1), i); +#else + printf(" v6 rreq %u", length); +#endif +} + +static void +#ifdef INET6 +aodv_v6_rrep(const union aodv *ap, const u_char *dat, u_int length) +#else +aodv_v6_rrep(const union aodv *ap _U_, const u_char *dat _U_, u_int length) +#endif +{ +#ifdef INET6 + u_int i; + + if (snapend < dat) { + printf(" [|aodv]"); + return; + } + i = min(length, (u_int)(snapend - dat)); + if (i < sizeof(ap->rrep6)) { + printf(" [|rrep6]"); + return; + } + i -= sizeof(ap->rrep6); + printf(" rrep %u %s%sprefix %u hops %u\n" + "\tdst %s dseq %lu src %s %lu ms", length, + ap->rrep6.rrep_type & RREP_REPAIR ? "[R]" : "", + ap->rrep6.rrep_type & RREP_ACK ? "[A] " : " ", + ap->rrep6.rrep_ps & RREP_PREFIX_MASK, + ap->rrep6.rrep_hops, + ip6addr_string(&ap->rrep6.rrep_da), + (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_ds), + ip6addr_string(&ap->rrep6.rrep_oa), + (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_life)); + if (i >= sizeof(struct aodv_ext)) + aodv_extension((void *)(&ap->rrep6 + 1), i); +#else + printf(" rrep %u", length); +#endif +} + +static void +#ifdef INET6 +aodv_v6_rerr(const union aodv *ap, u_int length) +#else +aodv_v6_rerr(const union aodv *ap _U_, u_int length) +#endif +{ +#ifdef INET6 + const struct rerr_unreach6 *dp6 = NULL; + int i, j, n, trunc; + + i = length - offsetof(struct aodv_rerr, r); + j = sizeof(ap->rerr.r.dest6[0]); + dp6 = &ap->rerr.r.dest6[0]; + n = ap->rerr.rerr_dc * j; + printf(" rerr %s [items %u] [%u]:", + ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "", + ap->rerr.rerr_dc, length); + trunc = n - (i/j); + for (; i -= j >= 0; ++dp6) { + printf(" {%s}(%ld)", ip6addr_string(&dp6->u_da), + (unsigned long)EXTRACT_32BITS(&dp6->u_ds)); + } + if (trunc) + printf("[|rerr]"); +#else + printf(" rerr %u", length); +#endif +} + +static void +#ifdef INET6 +aodv_v6_draft_01_rreq(const union aodv *ap, const u_char *dat, u_int length) +#else +aodv_v6_draft_01_rreq(const union aodv *ap _U_, const u_char *dat _U_, + u_int length) +#endif +{ +#ifdef INET6 + u_int i; + + if (snapend < dat) { + printf(" [|aodv]"); + return; + } + i = min(length, (u_int)(snapend - dat)); + if (i < sizeof(ap->rreq6_draft_01)) { + printf(" [|rreq6]"); + return; + } + i -= sizeof(ap->rreq6_draft_01); + printf(" rreq %u %s%s%s%s%shops %u id 0x%08lx\n" + "\tdst %s seq %lu src %s seq %lu", length, + ap->rreq6_draft_01.rreq_type & RREQ_JOIN ? "[J]" : "", + ap->rreq6_draft_01.rreq_type & RREQ_REPAIR ? "[R]" : "", + ap->rreq6_draft_01.rreq_type & RREQ_GRAT ? "[G]" : "", + ap->rreq6_draft_01.rreq_type & RREQ_DEST ? "[D]" : "", + ap->rreq6_draft_01.rreq_type & RREQ_UNKNOWN ? "[U] " : " ", + ap->rreq6_draft_01.rreq_hops, + (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_id), + ip6addr_string(&ap->rreq6_draft_01.rreq_da), + (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_ds), + ip6addr_string(&ap->rreq6_draft_01.rreq_oa), + (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_os)); + if (i >= sizeof(struct aodv_ext)) + aodv_extension((void *)(&ap->rreq6_draft_01 + 1), i); +#else + printf(" rreq %u", length); +#endif +} + +static void +#ifdef INET6 +aodv_v6_draft_01_rrep(const union aodv *ap, const u_char *dat, u_int length) +#else +aodv_v6_draft_01_rrep(const union aodv *ap _U_, const u_char *dat _U_, + u_int length) +#endif +{ +#ifdef INET6 + u_int i; + + if (snapend < dat) { + printf(" [|aodv]"); + return; + } + i = min(length, (u_int)(snapend - dat)); + if (i < sizeof(ap->rrep6_draft_01)) { + printf(" [|rrep6]"); + return; + } + i -= sizeof(ap->rrep6_draft_01); + printf(" rrep %u %s%sprefix %u hops %u\n" + "\tdst %s dseq %lu src %s %lu ms", length, + ap->rrep6_draft_01.rrep_type & RREP_REPAIR ? "[R]" : "", + ap->rrep6_draft_01.rrep_type & RREP_ACK ? "[A] " : " ", + ap->rrep6_draft_01.rrep_ps & RREP_PREFIX_MASK, + ap->rrep6_draft_01.rrep_hops, + ip6addr_string(&ap->rrep6_draft_01.rrep_da), + (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_ds), + ip6addr_string(&ap->rrep6_draft_01.rrep_oa), + (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_life)); + if (i >= sizeof(struct aodv_ext)) + aodv_extension((void *)(&ap->rrep6_draft_01 + 1), i); +#else + printf(" rrep %u", length); +#endif +} + +static void +#ifdef INET6 +aodv_v6_draft_01_rerr(const union aodv *ap, u_int length) +#else +aodv_v6_draft_01_rerr(const union aodv *ap _U_, u_int length) +#endif +{ +#ifdef INET6 + const struct rerr_unreach6_draft_01 *dp6 = NULL; + int i, j, n, trunc; + + i = length - offsetof(struct aodv_rerr, r); + j = sizeof(ap->rerr.r.dest6_draft_01[0]); + dp6 = &ap->rerr.r.dest6_draft_01[0]; + n = ap->rerr.rerr_dc * j; + printf(" rerr %s [items %u] [%u]:", + ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "", + ap->rerr.rerr_dc, length); + trunc = n - (i/j); + for (; i -= j >= 0; ++dp6) { + printf(" {%s}(%ld)", ip6addr_string(&dp6->u_da), + (unsigned long)EXTRACT_32BITS(&dp6->u_ds)); + } + if (trunc) + printf("[|rerr]"); +#else + printf(" rerr %u", length); +#endif +} + +void +aodv_print(const u_char *dat, u_int length, int is_ip6) +{ + const union aodv *ap; + + ap = (union aodv *)dat; + if (snapend < dat) { + printf(" [|aodv]"); + return; + } + if (min(length, (u_int)(snapend - dat)) < sizeof(ap->rrep_ack)) { + printf(" [|aodv]"); + return; + } + printf(" aodv"); + + switch (ap->rerr.rerr_type) { + + case AODV_RREQ: + if (is_ip6) + aodv_v6_rreq(ap, dat, length); + else + aodv_rreq(ap, dat, length); + break; + + case AODV_RREP: + if (is_ip6) + aodv_v6_rrep(ap, dat, length); + else + aodv_rrep(ap, dat, length); + break; + + case AODV_RERR: + if (is_ip6) + aodv_v6_rerr(ap, length); + else + aodv_rerr(ap, dat, length); + break; + + case AODV_RREP_ACK: + printf(" rrep-ack %u", length); + break; + + case AODV_V6_DRAFT_01_RREQ: + aodv_v6_draft_01_rreq(ap, dat, length); + break; + + case AODV_V6_DRAFT_01_RREP: + aodv_v6_draft_01_rrep(ap, dat, length); + break; + + case AODV_V6_DRAFT_01_RERR: + aodv_v6_draft_01_rerr(ap, length); + break; + + case AODV_V6_DRAFT_01_RREP_ACK: + printf(" rrep-ack %u", length); + break; + + default: + printf(" %u %u", ap->rreq.rreq_type, length); + } +} diff --git a/print-ap1394.c b/print-ap1394.c new file mode 100644 index 0000000..cb9d972 --- /dev/null +++ b/print-ap1394.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ap1394.c,v 1.5 2006-02-11 22:12:06 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ethertype.h" + +/* + * Structure of a header for Apple's IP-over-IEEE 1384 BPF header. + */ +#define FIREWIRE_EUI64_LEN 8 +struct firewire_header { + u_char firewire_dhost[FIREWIRE_EUI64_LEN]; + u_char firewire_shost[FIREWIRE_EUI64_LEN]; + u_short firewire_type; +}; + +/* + * Length of that header; note that some compilers may pad + * "struct firewire_header" to a multiple of 4 bytes, for example, so + * "sizeof (struct firewire_header)" may not give the right answer. + */ +#define FIREWIRE_HDRLEN 18 + +static inline void +ap1394_hdr_print(register const u_char *bp, u_int length) +{ + register const struct firewire_header *fp; + u_int16_t firewire_type; + + fp = (const struct firewire_header *)bp; + + (void)printf("%s > %s", + linkaddr_string(fp->firewire_dhost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN), + linkaddr_string(fp->firewire_shost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN)); + + firewire_type = EXTRACT_16BITS(&fp->firewire_type); + if (!qflag) { + (void)printf(", ethertype %s (0x%04x)", + tok2str(ethertype_values,"Unknown", firewire_type), + firewire_type); + } else { + (void)printf(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", firewire_type)); + } + + (void)printf(", length %u: ", length); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +ap1394_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int length = h->len; + u_int caplen = h->caplen; + struct firewire_header *fp; + u_short ether_type; + + if (caplen < FIREWIRE_HDRLEN) { + printf("[|ap1394]"); + return FIREWIRE_HDRLEN; + } + + if (eflag) + ap1394_hdr_print(p, length); + + length -= FIREWIRE_HDRLEN; + caplen -= FIREWIRE_HDRLEN; + fp = (struct firewire_header *)p; + p += FIREWIRE_HDRLEN; + + ether_type = EXTRACT_16BITS(&fp->firewire_type); + if (ethertype_print(ether_type, p, length, caplen) == 0) { + /* ether_type not known, print raw packet */ + if (!eflag) + ap1394_hdr_print((u_char *)fp, length + FIREWIRE_HDRLEN); + + if (!suppress_default_print) + default_print(p, caplen); + } + + return FIREWIRE_HDRLEN; +} diff --git a/print-arcnet.c b/print-arcnet.c new file mode 100644 index 0000000..a7b9f0d --- /dev/null +++ b/print-arcnet.c @@ -0,0 +1,298 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * From: NetBSD: print-arcnet.c,v 1.2 2000/04/24 13:02:28 itojun Exp + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-arcnet.c,v 1.20 2005-04-06 21:32:38 mcr Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "extract.h" +#include "arcnet.h" + +static int arcnet_encap_print(u_char arctype, const u_char *p, + u_int length, u_int caplen); + +struct tok arctypemap[] = { + { ARCTYPE_IP_OLD, "oldip" }, + { ARCTYPE_ARP_OLD, "oldarp" }, + { ARCTYPE_IP, "ip" }, + { ARCTYPE_ARP, "arp" }, + { ARCTYPE_REVARP, "rarp" }, + { ARCTYPE_ATALK, "atalk" }, + { ARCTYPE_BANIAN, "banyan" }, + { ARCTYPE_IPX, "ipx" }, + { ARCTYPE_INET6, "ipv6" }, + { ARCTYPE_DIAGNOSE, "diag" }, + { 0, 0 } +}; + +static inline void +arcnet_print(const u_char *bp, u_int length, int phds, int flag, u_int seqid) +{ + const struct arc_header *ap; + const char *arctypename; + + + ap = (const struct arc_header *)bp; + + + if (qflag) { + (void)printf("%02x %02x %d: ", + ap->arc_shost, + ap->arc_dhost, + length); + return; + } + + arctypename = tok2str(arctypemap, "%02x", ap->arc_type); + + if (!phds) { + (void)printf("%02x %02x %s %d: ", + ap->arc_shost, ap->arc_dhost, arctypename, + length); + return; + } + + if (flag == 0) { + (void)printf("%02x %02x %s seqid %04x %d: ", + ap->arc_shost, ap->arc_dhost, arctypename, seqid, + length); + return; + } + + if (flag & 1) + (void)printf("%02x %02x %s seqid %04x " + "(first of %d fragments) %d: ", + ap->arc_shost, ap->arc_dhost, arctypename, seqid, + (flag + 3) / 2, length); + else + (void)printf("%02x %02x %s seqid %04x " + "(fragment %d) %d: ", + ap->arc_shost, ap->arc_dhost, arctypename, seqid, + flag/2 + 1, length); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ARCNET header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +arcnet_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + const struct arc_header *ap; + + int phds, flag = 0, archdrlen = 0; + u_int seqid = 0; + u_char arc_type; + + if (caplen < ARC_HDRLEN) { + printf("[|arcnet]"); + return (caplen); + } + + ap = (const struct arc_header *)p; + arc_type = ap->arc_type; + + switch (arc_type) { + default: + phds = 1; + break; + case ARCTYPE_IP_OLD: + case ARCTYPE_ARP_OLD: + case ARCTYPE_DIAGNOSE: + phds = 0; + archdrlen = ARC_HDRLEN; + break; + } + + if (phds) { + if (caplen < ARC_HDRNEWLEN) { + arcnet_print(p, length, 0, 0, 0); + printf("[|phds]"); + return (caplen); + } + + if (ap->arc_flag == 0xff) { + if (caplen < ARC_HDRNEWLEN_EXC) { + arcnet_print(p, length, 0, 0, 0); + printf("[|phds extended]"); + return (caplen); + } + flag = ap->arc_flag2; + seqid = EXTRACT_16BITS(&ap->arc_seqid2); + archdrlen = ARC_HDRNEWLEN_EXC; + } else { + flag = ap->arc_flag; + seqid = EXTRACT_16BITS(&ap->arc_seqid); + archdrlen = ARC_HDRNEWLEN; + } + } + + + if (eflag) + arcnet_print(p, length, phds, flag, seqid); + + /* + * Go past the ARCNET header. + */ + length -= archdrlen; + caplen -= archdrlen; + p += archdrlen; + + if (phds && flag && (flag & 1) == 0) { + /* + * This is a middle fragment. + */ + return (archdrlen); + } + + if (!arcnet_encap_print(arc_type, p, length, caplen)) + default_print(p, caplen); + + return (archdrlen); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ARCNET header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. It is quite similar + * to the non-Linux style printer except that Linux doesn't ever + * supply packets that look like exception frames, it always supplies + * reassembled packets rather than raw frames, and headers have an + * extra "offset" field between the src/dest and packet type. + */ +u_int +arcnet_linux_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + const struct arc_linux_header *ap; + + int archdrlen = 0; + u_char arc_type; + + if (caplen < ARC_LINUX_HDRLEN) { + printf("[|arcnet]"); + return (caplen); + } + + ap = (const struct arc_linux_header *)p; + arc_type = ap->arc_type; + + switch (arc_type) { + default: + archdrlen = ARC_LINUX_HDRNEWLEN; + if (caplen < ARC_LINUX_HDRNEWLEN) { + printf("[|arcnet]"); + return (caplen); + } + break; + case ARCTYPE_IP_OLD: + case ARCTYPE_ARP_OLD: + case ARCTYPE_DIAGNOSE: + archdrlen = ARC_LINUX_HDRLEN; + break; + } + + if (eflag) + arcnet_print(p, length, 0, 0, 0); + + /* + * Go past the ARCNET header. + */ + length -= archdrlen; + caplen -= archdrlen; + p += archdrlen; + + if (!arcnet_encap_print(arc_type, p, length, caplen)) + default_print(p, caplen); + + return (archdrlen); +} + +/* + * Prints the packet encapsulated in an ARCnet data field, + * given the ARCnet system code. + * + * Returns non-zero if it can do so, zero if the system code is unknown. + */ + + +static int +arcnet_encap_print(u_char arctype, const u_char *p, + u_int length, u_int caplen) +{ + switch (arctype) { + + case ARCTYPE_IP_OLD: + case ARCTYPE_IP: + ip_print(gndo, p, length); + return (1); + +#ifdef INET6 + case ARCTYPE_INET6: + ip6_print(p, length); + return (1); +#endif /*INET6*/ + + case ARCTYPE_ARP_OLD: + case ARCTYPE_ARP: + case ARCTYPE_REVARP: + arp_print(gndo, p, length, caplen); + return (1); + + case ARCTYPE_ATALK: /* XXX was this ever used? */ + if (vflag) + fputs("et1 ", stdout); + atalk_print(p, length); + return (1); + + case ARCTYPE_IPX: + ipx_print(p, length); + return (1); + + default: + return (0); + } +} + +/* + * Local Variables: + * c-style: bsd + * End: + */ + diff --git a/print-arp.c b/print-arp.c new file mode 100644 index 0000000..0ca86cf --- /dev/null +++ b/print-arp.c @@ -0,0 +1,416 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-arp.c,v 1.66 2006-03-03 22:53:21 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "netdissect.h" +#include "addrtoname.h" +#include "ether.h" +#include "ethertype.h" +#include "extract.h" /* must come after interface.h */ + +/* + * Address Resolution Protocol. + * + * See RFC 826 for protocol description. ARP packets are variable + * in size; the arphdr structure defines the fixed-length portion. + * Protocol type values are the same as those for 10 Mb/s Ethernet. + * It is followed by the variable-sized fields ar_sha, arp_spa, + * arp_tha and arp_tpa in that order, according to the lengths + * specified. Field names used correspond to RFC 826. + */ +struct arp_pkthdr { + u_short ar_hrd; /* format of hardware address */ +#define ARPHRD_ETHER 1 /* ethernet hardware format */ +#define ARPHRD_IEEE802 6 /* token-ring hardware format */ +#define ARPHRD_ARCNET 7 /* arcnet hardware format */ +#define ARPHRD_FRELAY 15 /* frame relay hardware format */ +#define ARPHRD_ATM2225 19 /* ATM (RFC 2225) */ +#define ARPHRD_STRIP 23 /* Ricochet Starmode Radio hardware format */ +#define ARPHRD_IEEE1394 24 /* IEEE 1394 (FireWire) hardware format */ + u_short ar_pro; /* format of protocol address */ + u_char ar_hln; /* length of hardware address */ + u_char ar_pln; /* length of protocol address */ + u_short ar_op; /* one of: */ +#define ARPOP_REQUEST 1 /* request to resolve address */ +#define ARPOP_REPLY 2 /* response to previous request */ +#define ARPOP_REVREQUEST 3 /* request protocol address given hardware */ +#define ARPOP_REVREPLY 4 /* response giving protocol address */ +#define ARPOP_INVREQUEST 8 /* request to identify peer */ +#define ARPOP_INVREPLY 9 /* response identifying peer */ +#define ARPOP_NAK 10 /* NAK - only valif for ATM ARP */ + +/* + * The remaining fields are variable in size, + * according to the sizes above. + */ +#ifdef COMMENT_ONLY + u_char ar_sha[]; /* sender hardware address */ + u_char ar_spa[]; /* sender protocol address */ + u_char ar_tha[]; /* target hardware address */ + u_char ar_tpa[]; /* target protocol address */ +#endif +#define ar_sha(ap) (((const u_char *)((ap)+1))+0) +#define ar_spa(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln) +#define ar_tha(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln+(ap)->ar_pln) +#define ar_tpa(ap) (((const u_char *)((ap)+1))+2*(ap)->ar_hln+(ap)->ar_pln) +}; + +#define ARP_HDRLEN 8 + +#define HRD(ap) EXTRACT_16BITS(&(ap)->ar_hrd) +#define HRD_LEN(ap) ((ap)->ar_hln) +#define PROTO_LEN(ap) ((ap)->ar_pln) +#define OP(ap) EXTRACT_16BITS(&(ap)->ar_op) +#define PRO(ap) EXTRACT_16BITS(&(ap)->ar_pro) +#define SHA(ap) (ar_sha(ap)) +#define SPA(ap) (ar_spa(ap)) +#define THA(ap) (ar_tha(ap)) +#define TPA(ap) (ar_tpa(ap)) + + +struct tok arpop_values[] = { + { ARPOP_REQUEST, "Request" }, + { ARPOP_REPLY, "Reply" }, + { ARPOP_REVREQUEST, "Reverse Request" }, + { ARPOP_REVREPLY, "Reverse Reply" }, + { ARPOP_INVREQUEST, "Inverse Request" }, + { ARPOP_INVREPLY, "Inverse Reply" }, + { ARPOP_NAK, "NACK Reply" }, + { 0, NULL } +}; + +struct tok arphrd_values[] = { + { ARPHRD_ETHER, "Ethernet" }, + { ARPHRD_IEEE802, "TokenRing" }, + { ARPHRD_ARCNET, "ArcNet" }, + { ARPHRD_FRELAY, "FrameRelay" }, + { ARPHRD_STRIP, "Strip" }, + { ARPHRD_IEEE1394, "IEEE 1394" }, + { ARPHRD_ATM2225, "ATM" }, + { 0, NULL } +}; + +/* + * ATM Address Resolution Protocol. + * + * See RFC 2225 for protocol description. ATMARP packets are similar + * to ARP packets, except that there are no length fields for the + * protocol address - instead, there are type/length fields for + * the ATM number and subaddress - and the hardware addresses consist + * of an ATM number and an ATM subaddress. + */ +struct atmarp_pkthdr { + u_short aar_hrd; /* format of hardware address */ + u_short aar_pro; /* format of protocol address */ + u_char aar_shtl; /* length of source ATM number */ + u_char aar_sstl; /* length of source ATM subaddress */ +#define ATMARP_IS_E164 0x40 /* bit in type/length for E.164 format */ +#define ATMARP_LEN_MASK 0x3F /* length of {sub}address in type/length */ + u_short aar_op; /* same as regular ARP */ + u_char aar_spln; /* length of source protocol address */ + u_char aar_thtl; /* length of target ATM number */ + u_char aar_tstl; /* length of target ATM subaddress */ + u_char aar_tpln; /* length of target protocol address */ +/* + * The remaining fields are variable in size, + * according to the sizes above. + */ +#ifdef COMMENT_ONLY + u_char aar_sha[]; /* source ATM number */ + u_char aar_ssa[]; /* source ATM subaddress */ + u_char aar_spa[]; /* sender protocol address */ + u_char aar_tha[]; /* target ATM number */ + u_char aar_tsa[]; /* target ATM subaddress */ + u_char aar_tpa[]; /* target protocol address */ +#endif + +#define ATMHRD(ap) EXTRACT_16BITS(&(ap)->aar_hrd) +#define ATMSHRD_LEN(ap) ((ap)->aar_shtl & ATMARP_LEN_MASK) +#define ATMSSLN(ap) ((ap)->aar_sstl & ATMARP_LEN_MASK) +#define ATMSPROTO_LEN(ap) ((ap)->aar_spln) +#define ATMOP(ap) EXTRACT_16BITS(&(ap)->aar_op) +#define ATMPRO(ap) EXTRACT_16BITS(&(ap)->aar_pro) +#define ATMTHRD_LEN(ap) ((ap)->aar_thtl & ATMARP_LEN_MASK) +#define ATMTSLN(ap) ((ap)->aar_tstl & ATMARP_LEN_MASK) +#define ATMTPROTO_LEN(ap) ((ap)->aar_tpln) +#define aar_sha(ap) ((const u_char *)((ap)+1)) +#define aar_ssa(ap) (aar_sha(ap) + ATMSHRD_LEN(ap)) +#define aar_spa(ap) (aar_ssa(ap) + ATMSSLN(ap)) +#define aar_tha(ap) (aar_spa(ap) + ATMSPROTO_LEN(ap)) +#define aar_tsa(ap) (aar_tha(ap) + ATMTHRD_LEN(ap)) +#define aar_tpa(ap) (aar_tsa(ap) + ATMTSLN(ap)) +}; + +#define ATMSHA(ap) (aar_sha(ap)) +#define ATMSSA(ap) (aar_ssa(ap)) +#define ATMSPA(ap) (aar_spa(ap)) +#define ATMTHA(ap) (aar_tha(ap)) +#define ATMTSA(ap) (aar_tsa(ap)) +#define ATMTPA(ap) (aar_tpa(ap)) + +static u_char ezero[6]; + +static void +atmarp_addr_print(netdissect_options *ndo, + const u_char *ha, u_int ha_len, const u_char *srca, + u_int srca_len) +{ + if (ha_len == 0) + ND_PRINT((ndo, "")); + else { + ND_PRINT((ndo, "%s", linkaddr_string(ha, LINKADDR_ATM, ha_len))); + if (srca_len != 0) + ND_PRINT((ndo, ",%s", + linkaddr_string(srca, LINKADDR_ATM, srca_len))); + } +} + +static void +atmarp_print(netdissect_options *ndo, + const u_char *bp, u_int length, u_int caplen) +{ + const struct atmarp_pkthdr *ap; + u_short pro, hrd, op; + + ap = (const struct atmarp_pkthdr *)bp; + ND_TCHECK(*ap); + + hrd = ATMHRD(ap); + pro = ATMPRO(ap); + op = ATMOP(ap); + + if (!ND_TTEST2(*aar_tpa(ap), ATMTPROTO_LEN(ap))) { + ND_PRINT((ndo, "[|ARP]")); + ND_DEFAULTPRINT((const u_char *)ap, length); + return; + } + + if (!ndo->ndo_eflag) { + ND_PRINT((ndo, "ARP, ")); + } + + if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) || + ATMSPROTO_LEN(ap) != 4 || + ATMTPROTO_LEN(ap) != 4 || + ndo->ndo_vflag) { + ND_PRINT((ndo, "%s, %s (len %u/%u)", + tok2str(arphrd_values, "Unknown Hardware (%u)", hrd), + tok2str(ethertype_values, "Unknown Protocol (0x%04x)", pro), + ATMSPROTO_LEN(ap), + ATMTPROTO_LEN(ap))); + + /* don't know know about the address formats */ + if (!ndo->ndo_vflag) { + goto out; + } + } + + /* print operation */ + printf("%s%s ", + ndo->ndo_vflag ? ", " : "", + tok2str(arpop_values, "Unknown (%u)", op)); + + switch (op) { + + case ARPOP_REQUEST: + ND_PRINT((ndo, "who-has %s", ipaddr_string(ATMTPA(ap)))); + if (ATMTHRD_LEN(ap) != 0) { + ND_PRINT((ndo, " (")); + atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap), + ATMTSA(ap), ATMTSLN(ap)); + ND_PRINT((ndo, ")")); + } + ND_PRINT((ndo, "tell %s", ipaddr_string(ATMSPA(ap)))); + break; + + case ARPOP_REPLY: + ND_PRINT((ndo, "%s is-at ", ipaddr_string(ATMSPA(ap)))); + atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap), + ATMSSLN(ap)); + break; + + case ARPOP_INVREQUEST: + ND_PRINT((ndo, "who-is ")); + atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap), ATMTSA(ap), + ATMTSLN(ap)); + ND_PRINT((ndo, " tell ")); + atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap), + ATMSSLN(ap)); + break; + + case ARPOP_INVREPLY: + atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap), + ATMSSLN(ap)); + ND_PRINT((ndo, "at %s", ipaddr_string(ATMSPA(ap)))); + break; + + case ARPOP_NAK: + ND_PRINT((ndo, "for %s", ipaddr_string(ATMSPA(ap)))); + break; + + default: + ND_DEFAULTPRINT((const u_char *)ap, caplen); + return; + } + + out: + ND_PRINT((ndo, ", length %u", length)); + return; + +trunc: + ND_PRINT((ndo, "[|ARP]")); +} + +void +arp_print(netdissect_options *ndo, + const u_char *bp, u_int length, u_int caplen) +{ + const struct arp_pkthdr *ap; + u_short pro, hrd, op, linkaddr; + + ap = (const struct arp_pkthdr *)bp; + ND_TCHECK(*ap); + + hrd = HRD(ap); + pro = PRO(ap); + op = OP(ap); + + + /* if its ATM then call the ATM ARP printer + for Frame-relay ARP most of the fields + are similar to Ethernet so overload the Ethernet Printer + and set the linkaddr type for linkaddr_string() accordingly */ + + switch(hrd) { + case ARPHRD_ATM2225: + atmarp_print(ndo, bp, length, caplen); + return; + case ARPHRD_FRELAY: + linkaddr = LINKADDR_FRELAY; + default: + linkaddr = LINKADDR_ETHER; + break; + } + + if (!ND_TTEST2(*ar_tpa(ap), PROTO_LEN(ap))) { + ND_PRINT((ndo, "[|ARP]")); + ND_DEFAULTPRINT((const u_char *)ap, length); + return; + } + + if (!ndo->ndo_eflag) { + ND_PRINT((ndo, "ARP, ")); + } + + /* print hardware type/len and proto type/len */ + if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) || + PROTO_LEN(ap) != 4 || + HRD_LEN(ap) == 0 || + ndo->ndo_vflag) { + ND_PRINT((ndo, "%s (len %u), %s (len %u)", + tok2str(arphrd_values, "Unknown Hardware (%u)", hrd), + HRD_LEN(ap), + tok2str(ethertype_values, "Unknown Protocol (0x%04x)", pro), + PROTO_LEN(ap))); + + /* don't know know about the address formats */ + if (!ndo->ndo_vflag) { + goto out; + } + } + + /* print operation */ + printf("%s%s ", + ndo->ndo_vflag ? ", " : "", + tok2str(arpop_values, "Unknown (%u)", op)); + + switch (op) { + + case ARPOP_REQUEST: + ND_PRINT((ndo, "who-has %s", ipaddr_string(TPA(ap)))); + if (memcmp((const char *)ezero, (const char *)THA(ap), HRD_LEN(ap)) != 0) + ND_PRINT((ndo, " (%s)", + linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)))); + ND_PRINT((ndo, " tell %s", ipaddr_string(SPA(ap)))); + break; + + case ARPOP_REPLY: + ND_PRINT((ndo, "%s is-at %s", + ipaddr_string(SPA(ap)), + linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap)))); + break; + + case ARPOP_REVREQUEST: + ND_PRINT((ndo, "who-is %s tell %s", + linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), + linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap)))); + break; + + case ARPOP_REVREPLY: + ND_PRINT((ndo, "%s at %s", + linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), + ipaddr_string(TPA(ap)))); + break; + + case ARPOP_INVREQUEST: + ND_PRINT((ndo, "who-is %s tell %s", + linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), + linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap)))); + break; + + case ARPOP_INVREPLY: + ND_PRINT((ndo,"%s at %s", + linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)), + ipaddr_string(TPA(ap)))); + break; + + default: + ND_DEFAULTPRINT((const u_char *)ap, caplen); + return; + } + + out: + ND_PRINT((ndo, ", length %u", length)); + + return; +trunc: + ND_PRINT((ndo, "[|ARP]")); +} + +/* + * Local Variables: + * c-style: bsd + * End: + */ + diff --git a/print-ascii.c b/print-ascii.c new file mode 100644 index 0000000..fa8793c --- /dev/null +++ b/print-ascii.c @@ -0,0 +1,183 @@ +/* $NetBSD: print-ascii.c,v 1.1 1999/09/30 14:49:12 sjg Exp $ */ + +/*- + * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Alan Barrett and Simon J. Gerraty. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ascii.c,v 1.17 2005-07-06 20:53:32 guy Exp $"; +#endif +#include +#include + +#include "interface.h" + +#define ASCII_LINELENGTH 300 +#define HEXDUMP_BYTES_PER_LINE 16 +#define HEXDUMP_SHORTS_PER_LINE (HEXDUMP_BYTES_PER_LINE / 2) +#define HEXDUMP_HEXSTUFF_PER_SHORT 5 /* 4 hex digits and a space */ +#define HEXDUMP_HEXSTUFF_PER_LINE \ + (HEXDUMP_HEXSTUFF_PER_SHORT * HEXDUMP_SHORTS_PER_LINE) + +void +ascii_print(register const u_char *cp, register u_int length) +{ + register int s; + + putchar('\n'); + while (length > 0) { + s = *cp++; + length--; + if (!isgraph(s) && + (s != '\t' && s != ' ' && s != '\n' && s != '\r')) + putchar('.'); + else + putchar(s); + } +} + +void +hex_and_ascii_print_with_offset(register const char *ident, + register const u_char *cp, register u_int length, register u_int oset) +{ + register u_int i; + register int s1, s2; + register int nshorts; + char hexstuff[HEXDUMP_SHORTS_PER_LINE*HEXDUMP_HEXSTUFF_PER_SHORT+1], *hsp; + char asciistuff[ASCII_LINELENGTH+1], *asp; + + nshorts = length / sizeof(u_short); + i = 0; + hsp = hexstuff; asp = asciistuff; + while (--nshorts >= 0) { + s1 = *cp++; + s2 = *cp++; + (void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff), + " %02x%02x", s1, s2); + hsp += HEXDUMP_HEXSTUFF_PER_SHORT; + *(asp++) = (isgraph(s1) ? s1 : '.'); + *(asp++) = (isgraph(s2) ? s2 : '.'); + i++; + if (i >= HEXDUMP_SHORTS_PER_LINE) { + *hsp = *asp = '\0'; + (void)printf("%s0x%04x: %-*s %s", + ident, oset, HEXDUMP_HEXSTUFF_PER_LINE, + hexstuff, asciistuff); + i = 0; hsp = hexstuff; asp = asciistuff; + oset += HEXDUMP_BYTES_PER_LINE; + } + } + if (length & 1) { + s1 = *cp++; + (void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff), + " %02x", s1); + hsp += 3; + *(asp++) = (isgraph(s1) ? s1 : '.'); + ++i; + } + if (i > 0) { + *hsp = *asp = '\0'; + (void)printf("%s0x%04x: %-*s %s", + ident, oset, HEXDUMP_HEXSTUFF_PER_LINE, + hexstuff, asciistuff); + } +} + +void +hex_and_ascii_print(register const char *ident, register const u_char *cp, + register u_int length) +{ + hex_and_ascii_print_with_offset(ident, cp, length, 0); +} + +/* + * telnet_print() wants this. It is essentially default_print_unaligned() + */ +void +hex_print_with_offset(register const char *ident, register const u_char *cp, register u_int length, + register u_int oset) +{ + register u_int i, s; + register int nshorts; + + nshorts = (u_int) length / sizeof(u_short); + i = 0; + while (--nshorts >= 0) { + if ((i++ % 8) == 0) { + (void)printf("%s0x%04x: ", ident, oset); + oset += HEXDUMP_BYTES_PER_LINE; + } + s = *cp++; + (void)printf(" %02x%02x", s, *cp++); + } + if (length & 1) { + if ((i % 8) == 0) + (void)printf("%s0x%04x: ", ident, oset); + (void)printf(" %02x", *cp); + } +} + +/* + * just for completeness + */ +void +hex_print(register const char *ident, register const u_char *cp, register u_int length) +{ + hex_print_with_offset(ident, cp, length, 0); +} + +#ifdef MAIN +int +main(int argc, char *argv[]) +{ + hex_print("\n\t", "Hello, World!\n", 14); + printf("\n"); + hex_and_ascii_print("\n\t", "Hello, World!\n", 14); + printf("\n"); + ascii_print("Hello, World!\n", 14); + printf("\n"); +#define TMSG "Now is the winter of our discontent...\n" + hex_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100); + printf("\n"); + hex_and_ascii_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100); + printf("\n"); + exit(0); +} +#endif /* MAIN */ diff --git a/print-atalk.c b/print-atalk.c new file mode 100644 index 0000000..e7d6b5f --- /dev/null +++ b/print-atalk.c @@ -0,0 +1,627 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Format and print AppleTalk packets. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-atalk.c,v 1.81 2004-05-01 09:41:50 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "extract.h" /* must come after interface.h */ +#include "appletalk.h" + +static struct tok type2str[] = { + { ddpRTMP, "rtmp" }, + { ddpRTMPrequest, "rtmpReq" }, + { ddpECHO, "echo" }, + { ddpIP, "IP" }, + { ddpARP, "ARP" }, + { ddpKLAP, "KLAP" }, + { 0, NULL } +}; + +struct aarp { + u_int16_t htype, ptype; + u_int8_t halen, palen; + u_int16_t op; + u_int8_t hsaddr[6]; + u_int8_t psaddr[4]; + u_int8_t hdaddr[6]; + u_int8_t pdaddr[4]; +}; + +static char tstr[] = "[|atalk]"; + +static void atp_print(const struct atATP *, u_int); +static void atp_bitmap_print(u_char); +static void nbp_print(const struct atNBP *, u_int, u_short, u_char, u_char); +static const char *print_cstring(const char *, const u_char *); +static const struct atNBPtuple *nbp_tuple_print(const struct atNBPtuple *, + const u_char *, + u_short, u_char, u_char); +static const struct atNBPtuple *nbp_name_print(const struct atNBPtuple *, + const u_char *); +static const char *ataddr_string(u_short, u_char); +static void ddp_print(const u_char *, u_int, int, u_short, u_char, u_char); +static const char *ddpskt_string(int); + +/* + * Print LLAP packets received on a physical LocalTalk interface. + */ +u_int +ltalk_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + return (llap_print(p, h->caplen)); +} + +/* + * Print AppleTalk LLAP packets. + */ +u_int +llap_print(register const u_char *bp, u_int length) +{ + register const struct LAP *lp; + register const struct atDDP *dp; + register const struct atShortDDP *sdp; + u_short snet; + u_int hdrlen; + + /* + * Our packet is on a 4-byte boundary, as we're either called + * directly from a top-level link-layer printer (ltalk_if_print) + * or from the UDP printer. The LLAP+DDP header is a multiple + * of 4 bytes in length, so the DDP payload is also on a 4-byte + * boundary, and we don't need to align it before calling + * "ddp_print()". + */ + lp = (const struct LAP *)bp; + bp += sizeof(*lp); + length -= sizeof(*lp); + hdrlen = sizeof(*lp); + switch (lp->type) { + + case lapShortDDP: + if (length < ddpSSize) { + (void)printf(" [|sddp %d]", length); + return (length); + } + sdp = (const struct atShortDDP *)bp; + printf("%s.%s", + ataddr_string(0, lp->src), ddpskt_string(sdp->srcSkt)); + printf(" > %s.%s:", + ataddr_string(0, lp->dst), ddpskt_string(sdp->dstSkt)); + bp += ddpSSize; + length -= ddpSSize; + hdrlen += ddpSSize; + ddp_print(bp, length, sdp->type, 0, lp->src, sdp->srcSkt); + break; + + case lapDDP: + if (length < ddpSize) { + (void)printf(" [|ddp %d]", length); + return (length); + } + dp = (const struct atDDP *)bp; + snet = EXTRACT_16BITS(&dp->srcNet); + printf("%s.%s", ataddr_string(snet, dp->srcNode), + ddpskt_string(dp->srcSkt)); + printf(" > %s.%s:", + ataddr_string(EXTRACT_16BITS(&dp->dstNet), dp->dstNode), + ddpskt_string(dp->dstSkt)); + bp += ddpSize; + length -= ddpSize; + hdrlen += ddpSize; + ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt); + break; + +#ifdef notdef + case lapKLAP: + klap_print(bp, length); + break; +#endif + + default: + printf("%d > %d at-lap#%d %d", + lp->src, lp->dst, lp->type, length); + break; + } + return (hdrlen); +} + +/* + * Print EtherTalk/TokenTalk packets (or FDDITalk, or whatever it's called + * when it runs over FDDI; yes, I've seen FDDI captures with AppleTalk + * packets in them). + */ +void +atalk_print(register const u_char *bp, u_int length) +{ + register const struct atDDP *dp; + u_short snet; + + if(!eflag) + printf("AT "); + + if (length < ddpSize) { + (void)printf(" [|ddp %d]", length); + return; + } + dp = (const struct atDDP *)bp; + snet = EXTRACT_16BITS(&dp->srcNet); + printf("%s.%s", ataddr_string(snet, dp->srcNode), + ddpskt_string(dp->srcSkt)); + printf(" > %s.%s: ", + ataddr_string(EXTRACT_16BITS(&dp->dstNet), dp->dstNode), + ddpskt_string(dp->dstSkt)); + bp += ddpSize; + length -= ddpSize; + ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt); +} + +/* XXX should probably pass in the snap header and do checks like arp_print() */ +void +aarp_print(register const u_char *bp, u_int length) +{ + register const struct aarp *ap; + +#define AT(member) ataddr_string((ap->member[1]<<8)|ap->member[2],ap->member[3]) + + printf("aarp "); + ap = (const struct aarp *)bp; + if (EXTRACT_16BITS(&ap->htype) == 1 && + EXTRACT_16BITS(&ap->ptype) == ETHERTYPE_ATALK && + ap->halen == 6 && ap->palen == 4 ) + switch (EXTRACT_16BITS(&ap->op)) { + + case 1: /* request */ + (void)printf("who-has %s tell %s", + AT(pdaddr), AT(psaddr)); + return; + + case 2: /* response */ + (void)printf("reply %s is-at %s", + AT(psaddr), etheraddr_string(ap->hsaddr)); + return; + + case 3: /* probe (oy!) */ + (void)printf("probe %s tell %s", + AT(pdaddr), AT(psaddr)); + return; + } + (void)printf("len %u op %u htype %u ptype %#x halen %u palen %u", + length, EXTRACT_16BITS(&ap->op), EXTRACT_16BITS(&ap->htype), + EXTRACT_16BITS(&ap->ptype), ap->halen, ap->palen); +} + +/* + * Print AppleTalk Datagram Delivery Protocol packets. + */ +static void +ddp_print(register const u_char *bp, register u_int length, register int t, + register u_short snet, register u_char snode, u_char skt) +{ + + switch (t) { + + case ddpNBP: + nbp_print((const struct atNBP *)bp, length, snet, snode, skt); + break; + + case ddpATP: + atp_print((const struct atATP *)bp, length); + break; + + case ddpEIGRP: + eigrp_print(bp, length); + break; + + default: + (void)printf(" at-%s %d", tok2str(type2str, NULL, t), length); + break; + } +} + +static void +atp_print(register const struct atATP *ap, u_int length) +{ + char c; + u_int32_t data; + + if ((const u_char *)(ap + 1) > snapend) { + /* Just bail if we don't have the whole chunk. */ + fputs(tstr, stdout); + return; + } + length -= sizeof(*ap); + switch (ap->control & 0xc0) { + + case atpReqCode: + (void)printf(" atp-req%s %d", + ap->control & atpXO? " " : "*", + EXTRACT_16BITS(&ap->transID)); + + atp_bitmap_print(ap->bitmap); + + if (length != 0) + (void)printf(" [len=%d]", length); + + switch (ap->control & (atpEOM|atpSTS)) { + case atpEOM: + (void)printf(" [EOM]"); + break; + case atpSTS: + (void)printf(" [STS]"); + break; + case atpEOM|atpSTS: + (void)printf(" [EOM,STS]"); + break; + } + break; + + case atpRspCode: + (void)printf(" atp-resp%s%d:%d (%d)", + ap->control & atpEOM? "*" : " ", + EXTRACT_16BITS(&ap->transID), ap->bitmap, length); + switch (ap->control & (atpXO|atpSTS)) { + case atpXO: + (void)printf(" [XO]"); + break; + case atpSTS: + (void)printf(" [STS]"); + break; + case atpXO|atpSTS: + (void)printf(" [XO,STS]"); + break; + } + break; + + case atpRelCode: + (void)printf(" atp-rel %d", EXTRACT_16BITS(&ap->transID)); + + atp_bitmap_print(ap->bitmap); + + /* length should be zero */ + if (length) + (void)printf(" [len=%d]", length); + + /* there shouldn't be any control flags */ + if (ap->control & (atpXO|atpEOM|atpSTS)) { + c = '['; + if (ap->control & atpXO) { + (void)printf("%cXO", c); + c = ','; + } + if (ap->control & atpEOM) { + (void)printf("%cEOM", c); + c = ','; + } + if (ap->control & atpSTS) { + (void)printf("%cSTS", c); + c = ','; + } + (void)printf("]"); + } + break; + + default: + (void)printf(" atp-0x%x %d (%d)", ap->control, + EXTRACT_16BITS(&ap->transID), length); + break; + } + data = EXTRACT_32BITS(&ap->userData); + if (data != 0) + (void)printf(" 0x%x", data); +} + +static void +atp_bitmap_print(register u_char bm) +{ + register char c; + register int i; + + /* + * The '& 0xff' below is needed for compilers that want to sign + * extend a u_char, which is the case with the Ultrix compiler. + * (gcc is smart enough to eliminate it, at least on the Sparc). + */ + if ((bm + 1) & (bm & 0xff)) { + c = '<'; + for (i = 0; bm; ++i) { + if (bm & 1) { + (void)printf("%c%d", c, i); + c = ','; + } + bm >>= 1; + } + (void)printf(">"); + } else { + for (i = 0; bm; ++i) + bm >>= 1; + if (i > 1) + (void)printf("<0-%d>", i - 1); + else + (void)printf("<0>"); + } +} + +static void +nbp_print(register const struct atNBP *np, u_int length, register u_short snet, + register u_char snode, register u_char skt) +{ + register const struct atNBPtuple *tp = + (const struct atNBPtuple *)((u_char *)np + nbpHeaderSize); + int i; + const u_char *ep; + + if (length < nbpHeaderSize) { + (void)printf(" truncated-nbp %d", length); + return; + } + + length -= nbpHeaderSize; + if (length < 8) { + /* must be room for at least one tuple */ + (void)printf(" truncated-nbp %d", length + nbpHeaderSize); + return; + } + /* ep points to end of available data */ + ep = snapend; + if ((const u_char *)tp > ep) { + fputs(tstr, stdout); + return; + } + switch (i = np->control & 0xf0) { + + case nbpBrRq: + case nbpLkUp: + (void)printf(i == nbpLkUp? " nbp-lkup %d:":" nbp-brRq %d:", + np->id); + if ((const u_char *)(tp + 1) > ep) { + fputs(tstr, stdout); + return; + } + (void)nbp_name_print(tp, ep); + /* + * look for anomalies: the spec says there can only + * be one tuple, the address must match the source + * address and the enumerator should be zero. + */ + if ((np->control & 0xf) != 1) + (void)printf(" [ntup=%d]", np->control & 0xf); + if (tp->enumerator) + (void)printf(" [enum=%d]", tp->enumerator); + if (EXTRACT_16BITS(&tp->net) != snet || + tp->node != snode || tp->skt != skt) + (void)printf(" [addr=%s.%d]", + ataddr_string(EXTRACT_16BITS(&tp->net), + tp->node), tp->skt); + break; + + case nbpLkUpReply: + (void)printf(" nbp-reply %d:", np->id); + + /* print each of the tuples in the reply */ + for (i = np->control & 0xf; --i >= 0 && tp; ) + tp = nbp_tuple_print(tp, ep, snet, snode, skt); + break; + + default: + (void)printf(" nbp-0x%x %d (%d)", np->control, np->id, + length); + break; + } +} + +/* print a counted string */ +static const char * +print_cstring(register const char *cp, register const u_char *ep) +{ + register u_int length; + + if (cp >= (const char *)ep) { + fputs(tstr, stdout); + return (0); + } + length = *cp++; + + /* Spec says string can be at most 32 bytes long */ + if (length > 32) { + (void)printf("[len=%u]", length); + return (0); + } + while ((int)--length >= 0) { + if (cp >= (const char *)ep) { + fputs(tstr, stdout); + return (0); + } + putchar(*cp++); + } + return (cp); +} + +static const struct atNBPtuple * +nbp_tuple_print(register const struct atNBPtuple *tp, + register const u_char *ep, + register u_short snet, register u_char snode, + register u_char skt) +{ + register const struct atNBPtuple *tpn; + + if ((const u_char *)(tp + 1) > ep) { + fputs(tstr, stdout); + return 0; + } + tpn = nbp_name_print(tp, ep); + + /* if the enumerator isn't 1, print it */ + if (tp->enumerator != 1) + (void)printf("(%d)", tp->enumerator); + + /* if the socket doesn't match the src socket, print it */ + if (tp->skt != skt) + (void)printf(" %d", tp->skt); + + /* if the address doesn't match the src address, it's an anomaly */ + if (EXTRACT_16BITS(&tp->net) != snet || tp->node != snode) + (void)printf(" [addr=%s]", + ataddr_string(EXTRACT_16BITS(&tp->net), tp->node)); + + return (tpn); +} + +static const struct atNBPtuple * +nbp_name_print(const struct atNBPtuple *tp, register const u_char *ep) +{ + register const char *cp = (const char *)tp + nbpTupleSize; + + putchar(' '); + + /* Object */ + putchar('"'); + if ((cp = print_cstring(cp, ep)) != NULL) { + /* Type */ + putchar(':'); + if ((cp = print_cstring(cp, ep)) != NULL) { + /* Zone */ + putchar('@'); + if ((cp = print_cstring(cp, ep)) != NULL) + putchar('"'); + } + } + return ((const struct atNBPtuple *)cp); +} + + +#define HASHNAMESIZE 4096 + +struct hnamemem { + int addr; + char *name; + struct hnamemem *nxt; +}; + +static struct hnamemem hnametable[HASHNAMESIZE]; + +static const char * +ataddr_string(u_short atnet, u_char athost) +{ + register struct hnamemem *tp, *tp2; + register int i = (atnet << 8) | athost; + char nambuf[MAXHOSTNAMELEN + 20]; + static int first = 1; + FILE *fp; + + /* + * if this is the first call, see if there's an AppleTalk + * number to name map file. + */ + if (first && (first = 0, !nflag) + && (fp = fopen("/etc/atalk.names", "r"))) { + char line[256]; + int i1, i2, i3; + + while (fgets(line, sizeof(line), fp)) { + if (line[0] == '\n' || line[0] == 0 || line[0] == '#') + continue; + if (sscanf(line, "%d.%d.%d %256s", &i1, &i2, &i3, + nambuf) == 4) + /* got a hostname. */ + i3 |= ((i1 << 8) | i2) << 8; + else if (sscanf(line, "%d.%d %256s", &i1, &i2, + nambuf) == 3) + /* got a net name */ + i3 = (((i1 << 8) | i2) << 8) | 255; + else + continue; + + for (tp = &hnametable[i3 & (HASHNAMESIZE-1)]; + tp->nxt; tp = tp->nxt) + ; + tp->addr = i3; + tp->nxt = newhnamemem(); + tp->name = strdup(nambuf); + } + fclose(fp); + } + + for (tp = &hnametable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) + if (tp->addr == i) + return (tp->name); + + /* didn't have the node name -- see if we've got the net name */ + i |= 255; + for (tp2 = &hnametable[i & (HASHNAMESIZE-1)]; tp2->nxt; tp2 = tp2->nxt) + if (tp2->addr == i) { + tp->addr = (atnet << 8) | athost; + tp->nxt = newhnamemem(); + (void)snprintf(nambuf, sizeof(nambuf), "%s.%d", + tp2->name, athost); + tp->name = strdup(nambuf); + return (tp->name); + } + + tp->addr = (atnet << 8) | athost; + tp->nxt = newhnamemem(); + if (athost != 255) + (void)snprintf(nambuf, sizeof(nambuf), "%d.%d.%d", + atnet >> 8, atnet & 0xff, athost); + else + (void)snprintf(nambuf, sizeof(nambuf), "%d.%d", atnet >> 8, + atnet & 0xff); + tp->name = strdup(nambuf); + + return (tp->name); +} + +static struct tok skt2str[] = { + { rtmpSkt, "rtmp" }, /* routing table maintenance */ + { nbpSkt, "nis" }, /* name info socket */ + { echoSkt, "echo" }, /* AppleTalk echo protocol */ + { zipSkt, "zip" }, /* zone info protocol */ + { 0, NULL } +}; + +static const char * +ddpskt_string(register int skt) +{ + static char buf[8]; + + if (nflag) { + (void)snprintf(buf, sizeof(buf), "%d", skt); + return (buf); + } + return (tok2str(skt2str, "%d", skt)); +} diff --git a/print-atm.c b/print-atm.c new file mode 100644 index 0000000..135898b --- /dev/null +++ b/print-atm.c @@ -0,0 +1,449 @@ +/* + * Copyright (c) 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-atm.c,v 1.49 2007-10-22 19:37:51 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "atm.h" +#include "atmuni31.h" +#include "llc.h" + +#include "ether.h" + +#define OAM_CRC10_MASK 0x3ff +#define OAM_PAYLOAD_LEN 48 +#define OAM_FUNCTION_SPECIFIC_LEN 45 /* this excludes crc10 and cell-type/function-type */ +#define OAM_CELLTYPE_FUNCTYPE_LEN 1 + +struct tok oam_f_values[] = { + { VCI_OAMF4SC, "OAM F4 (segment)" }, + { VCI_OAMF4EC, "OAM F4 (end)" }, + { 0, NULL } +}; + +struct tok atm_pty_values[] = { + { 0x0, "user data, uncongested, SDU 0" }, + { 0x1, "user data, uncongested, SDU 1" }, + { 0x2, "user data, congested, SDU 0" }, + { 0x3, "user data, congested, SDU 1" }, + { 0x4, "VCC OAM F5 flow segment" }, + { 0x5, "VCC OAM F5 flow end-to-end" }, + { 0x6, "Traffic Control and resource Mgmt" }, + { 0, NULL } +}; + +#define OAM_CELLTYPE_FM 0x1 +#define OAM_CELLTYPE_PM 0x2 +#define OAM_CELLTYPE_AD 0x8 +#define OAM_CELLTYPE_SM 0xf + +struct tok oam_celltype_values[] = { + { OAM_CELLTYPE_FM, "Fault Management" }, + { OAM_CELLTYPE_PM, "Performance Management" }, + { OAM_CELLTYPE_AD, "activate/deactivate" }, + { OAM_CELLTYPE_SM, "System Management" }, + { 0, NULL } +}; + +#define OAM_FM_FUNCTYPE_AIS 0x0 +#define OAM_FM_FUNCTYPE_RDI 0x1 +#define OAM_FM_FUNCTYPE_CONTCHECK 0x4 +#define OAM_FM_FUNCTYPE_LOOPBACK 0x8 + +struct tok oam_fm_functype_values[] = { + { OAM_FM_FUNCTYPE_AIS, "AIS" }, + { OAM_FM_FUNCTYPE_RDI, "RDI" }, + { OAM_FM_FUNCTYPE_CONTCHECK, "Continuity Check" }, + { OAM_FM_FUNCTYPE_LOOPBACK, "Loopback" }, + { 0, NULL } +}; + +struct tok oam_pm_functype_values[] = { + { 0x0, "Forward Monitoring" }, + { 0x1, "Backward Reporting" }, + { 0x2, "Monitoring and Reporting" }, + { 0, NULL } +}; + +struct tok oam_ad_functype_values[] = { + { 0x0, "Performance Monitoring" }, + { 0x1, "Continuity Check" }, + { 0, NULL } +}; + +#define OAM_FM_LOOPBACK_INDICATOR_MASK 0x1 + +struct tok oam_fm_loopback_indicator_values[] = { + { 0x0, "Reply" }, + { 0x1, "Request" }, + { 0, NULL } +}; + +static const struct tok *oam_functype_values[16] = { + NULL, + oam_fm_functype_values, /* 1 */ + oam_pm_functype_values, /* 2 */ + NULL, + NULL, + NULL, + NULL, + NULL, + oam_ad_functype_values, /* 8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +/* + * Print an RFC 1483 LLC-encapsulated ATM frame. + */ +static void +atm_llc_print(const u_char *p, int length, int caplen) +{ + u_short extracted_ethertype; + + if (!llc_print(p, length, caplen, NULL, NULL, + &extracted_ethertype)) { + /* ether_type not known, print raw packet */ + if (extracted_ethertype) { + printf("(LLC %s) ", + etherproto_string(htons(extracted_ethertype))); + } + if (!suppress_default_print) + default_print(p, caplen); + } +} + +/* + * Given a SAP value, generate the LLC header value for a UI packet + * with that SAP as the source and destination SAP. + */ +#define LLC_UI_HDR(sap) ((sap)<<16 | (sap<<8) | 0x03) + +/* + * This is the top level routine of the printer. 'p' points + * to the LLC/SNAP header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +atm_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + u_int32_t llchdr; + u_int hdrlen = 0; + + if (caplen < 8) { + printf("[|atm]"); + return (caplen); + } + + /* Cisco Style NLPID ? */ + if (*p == LLC_UI) { + if (eflag) + printf("CNLPID "); + isoclns_print(p+1, length-1, caplen-1); + return hdrlen; + } + + /* + * Extract the presumed LLC header into a variable, for quick + * testing. + * Then check for a header that's neither a header for a SNAP + * packet nor an RFC 2684 routed NLPID-formatted PDU nor + * an 802.2-but-no-SNAP IP packet. + */ + llchdr = EXTRACT_24BITS(p); + if (llchdr != LLC_UI_HDR(LLCSAP_SNAP) && + llchdr != LLC_UI_HDR(LLCSAP_ISONS) && + llchdr != LLC_UI_HDR(LLCSAP_IP)) { + /* + * XXX - assume 802.6 MAC header from Fore driver. + * + * Unfortunately, the above list doesn't check for + * all known SAPs, doesn't check for headers where + * the source and destination SAP aren't the same, + * and doesn't check for non-UI frames. It also + * runs the risk of an 802.6 MAC header that happens + * to begin with one of those values being + * incorrectly treated as an 802.2 header. + * + * So is that Fore driver still around? And, if so, + * is it still putting 802.6 MAC headers on ATM + * packets? If so, could it be changed to use a + * new DLT_IEEE802_6 value if we added it? + */ + if (eflag) + printf("%08x%08x %08x%08x ", + EXTRACT_32BITS(p), + EXTRACT_32BITS(p+4), + EXTRACT_32BITS(p+8), + EXTRACT_32BITS(p+12)); + p += 20; + length -= 20; + caplen -= 20; + hdrlen += 20; + } + atm_llc_print(p, length, caplen); + return (hdrlen); +} + +/* + * ATM signalling. + */ +static struct tok msgtype2str[] = { + { CALL_PROCEED, "Call_proceeding" }, + { CONNECT, "Connect" }, + { CONNECT_ACK, "Connect_ack" }, + { SETUP, "Setup" }, + { RELEASE, "Release" }, + { RELEASE_DONE, "Release_complete" }, + { RESTART, "Restart" }, + { RESTART_ACK, "Restart_ack" }, + { STATUS, "Status" }, + { STATUS_ENQ, "Status_enquiry" }, + { ADD_PARTY, "Add_party" }, + { ADD_PARTY_ACK, "Add_party_ack" }, + { ADD_PARTY_REJ, "Add_party_reject" }, + { DROP_PARTY, "Drop_party" }, + { DROP_PARTY_ACK, "Drop_party_ack" }, + { 0, NULL } +}; + +static void +sig_print(const u_char *p, int caplen) +{ + bpf_u_int32 call_ref; + + if (caplen < PROTO_POS) { + printf("[|atm]"); + return; + } + if (p[PROTO_POS] == Q2931) { + /* + * protocol:Q.2931 for User to Network Interface + * (UNI 3.1) signalling + */ + printf("Q.2931"); + if (caplen < MSG_TYPE_POS) { + printf(" [|atm]"); + return; + } + printf(":%s ", + tok2str(msgtype2str, "msgtype#%d", p[MSG_TYPE_POS])); + + if (caplen < CALL_REF_POS+3) { + printf("[|atm]"); + return; + } + call_ref = EXTRACT_24BITS(&p[CALL_REF_POS]); + printf("CALL_REF:0x%06x", call_ref); + } else { + /* SCCOP with some unknown protocol atop it */ + printf("SSCOP, proto %d ", p[PROTO_POS]); + } +} + +/* + * Print an ATM PDU (such as an AAL5 PDU). + */ +void +atm_print(u_int vpi, u_int vci, u_int traftype, const u_char *p, u_int length, + u_int caplen) +{ + if (eflag) + printf("VPI:%u VCI:%u ", vpi, vci); + + if (vpi == 0) { + switch (vci) { + + case VCI_PPC: + sig_print(p, caplen); + return; + + case VCI_BCC: + printf("broadcast sig: "); + return; + + case VCI_OAMF4SC: /* fall through */ + case VCI_OAMF4EC: + oam_print(p, length, ATM_OAM_HEC); + return; + + case VCI_METAC: + printf("meta: "); + return; + + case VCI_ILMIC: + printf("ilmi: "); + snmp_print(p, length); + return; + } + } + + switch (traftype) { + + case ATM_LLC: + default: + /* + * Assumes traffic is LLC if unknown. + */ + atm_llc_print(p, length, caplen); + break; + + case ATM_LANE: + lane_print(p, length, caplen); + break; + } +} + +struct oam_fm_loopback_t { + u_int8_t loopback_indicator; + u_int8_t correlation_tag[4]; + u_int8_t loopback_id[12]; + u_int8_t source_id[12]; + u_int8_t unused[16]; +}; + +struct oam_fm_ais_rdi_t { + u_int8_t failure_type; + u_int8_t failure_location[16]; + u_int8_t unused[28]; +}; + +int +oam_print (const u_char *p, u_int length, u_int hec) { + + u_int32_t cell_header; + u_int16_t vpi, vci, cksum, cksum_shouldbe, idx; + u_int8_t cell_type, func_type, payload, clp; + + union { + const struct oam_fm_loopback_t *oam_fm_loopback; + const struct oam_fm_ais_rdi_t *oam_fm_ais_rdi; + } oam_ptr; + + + cell_header = EXTRACT_32BITS(p+hec); + cell_type = ((*(p+ATM_HDR_LEN_NOHEC+hec))>>4) & 0x0f; + func_type = (*(p+ATM_HDR_LEN_NOHEC+hec)) & 0x0f; + + vpi = (cell_header>>20)&0xff; + vci = (cell_header>>4)&0xffff; + payload = (cell_header>>1)&0x7; + clp = cell_header&0x1; + + printf("%s, vpi %u, vci %u, payload [ %s ], clp %u, length %u", + tok2str(oam_f_values, "OAM F5", vci), + vpi, vci, + tok2str(atm_pty_values, "Unknown", payload), + clp, length); + + if (!vflag) { + return 1; + } + + printf("\n\tcell-type %s (%u)", + tok2str(oam_celltype_values, "unknown", cell_type), + cell_type); + + if (oam_functype_values[cell_type] == NULL) + printf(", func-type unknown (%u)", func_type); + else + printf(", func-type %s (%u)", + tok2str(oam_functype_values[cell_type],"none",func_type), + func_type); + + p += ATM_HDR_LEN_NOHEC + hec; + + switch (cell_type << 4 | func_type) { + case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_LOOPBACK): + oam_ptr.oam_fm_loopback = (const struct oam_fm_loopback_t *)(p + OAM_CELLTYPE_FUNCTYPE_LEN); + printf("\n\tLoopback-Indicator %s, Correlation-Tag 0x%08x", + tok2str(oam_fm_loopback_indicator_values, + "Unknown", + oam_ptr.oam_fm_loopback->loopback_indicator & OAM_FM_LOOPBACK_INDICATOR_MASK), + EXTRACT_32BITS(&oam_ptr.oam_fm_loopback->correlation_tag)); + printf("\n\tLocation-ID "); + for (idx = 0; idx < sizeof(oam_ptr.oam_fm_loopback->loopback_id); idx++) { + if (idx % 2) { + printf("%04x ", EXTRACT_16BITS(&oam_ptr.oam_fm_loopback->loopback_id[idx])); + } + } + printf("\n\tSource-ID "); + for (idx = 0; idx < sizeof(oam_ptr.oam_fm_loopback->source_id); idx++) { + if (idx % 2) { + printf("%04x ", EXTRACT_16BITS(&oam_ptr.oam_fm_loopback->source_id[idx])); + } + } + break; + + case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_AIS): + case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_RDI): + oam_ptr.oam_fm_ais_rdi = (const struct oam_fm_ais_rdi_t *)(p + OAM_CELLTYPE_FUNCTYPE_LEN); + printf("\n\tFailure-type 0x%02x", oam_ptr.oam_fm_ais_rdi->failure_type); + printf("\n\tLocation-ID "); + for (idx = 0; idx < sizeof(oam_ptr.oam_fm_ais_rdi->failure_location); idx++) { + if (idx % 2) { + printf("%04x ", EXTRACT_16BITS(&oam_ptr.oam_fm_ais_rdi->failure_location[idx])); + } + } + break; + + case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_CONTCHECK): + /* FIXME */ + break; + + default: + break; + } + + /* crc10 checksum verification */ + cksum = EXTRACT_16BITS(p + OAM_CELLTYPE_FUNCTYPE_LEN + OAM_FUNCTION_SPECIFIC_LEN) + & OAM_CRC10_MASK; + cksum_shouldbe = verify_crc10_cksum(0, p, OAM_PAYLOAD_LEN); + + printf("\n\tcksum 0x%03x (%scorrect)", + cksum, + cksum_shouldbe == 0 ? "" : "in"); + + return 1; +} diff --git a/print-beep.c b/print-beep.c new file mode 100644 index 0000000..b476dbf --- /dev/null +++ b/print-beep.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2000, Richard Sharpe + * + * This software may be distributed either under the terms of the + * BSD-style licence that accompanies tcpdump or under the GNU GPL + * version 2 or later. + * + * print-beep.c + * + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-beep.c,v 1.6 2003-11-16 09:36:13 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifdef HAVE_MEMORY_H +#include +#endif +#include +#include +#include + +#include "interface.h" +#include "extract.h" + +/* Check for a string but not go beyond length + * Return TRUE on match, FALSE otherwise + * + * Looks at the first few chars up to tl1 ... + */ + +static int l_strnstart(const char *, u_int, const char *, u_int); + +static int +l_strnstart(const char *tstr1, u_int tl1, const char *str2, u_int l2) +{ + + if (tl1 > l2) + return 0; + + return (strncmp(tstr1, str2, tl1) == 0 ? 1 : 0); +} + +void +beep_print(const u_char *bp, u_int length) +{ + + if (l_strnstart("MSG", 4, (const char *)bp, length)) /* A REQuest */ + printf(" BEEP MSG"); + else if (l_strnstart("RPY ", 4, (const char *)bp, length)) + printf(" BEEP RPY"); + else if (l_strnstart("ERR ", 4, (const char *)bp, length)) + printf(" BEEP ERR"); + else if (l_strnstart("ANS ", 4, (const char *)bp, length)) + printf(" BEEP ANS"); + else if (l_strnstart("NUL ", 4, (const char *)bp, length)) + printf(" BEEP NUL"); + else if (l_strnstart("SEQ ", 4, (const char *)bp, length)) + printf(" BEEP SEQ"); + else if (l_strnstart("END", 4, (const char *)bp, length)) + printf(" BEEP END"); + else + printf(" BEEP (payload or undecoded)"); +} diff --git a/print-bfd.c b/print-bfd.c new file mode 100644 index 0000000..f157684 --- /dev/null +++ b/print-bfd.c @@ -0,0 +1,283 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-bfd.c,v 1.10 2006-02-02 06:35:52 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +#include "udp.h" + +/* + * Control packet, BFDv0, draft-katz-ward-bfd-01.txt + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Vers | Diag |H|D|P|F| Rsvd | Detect Mult | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | My Discriminator | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Your Discriminator | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Desired Min TX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Required Min RX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Required Min Echo RX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +/* + * Control packet, BFDv1, draft-ietf-bfd-base-02.txt + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Vers | Diag |Sta|P|F|C|A|D|R| Detect Mult | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | My Discriminator | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Your Discriminator | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Desired Min TX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Required Min RX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Required Min Echo RX Interval | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct bfd_header_t { + u_int8_t version_diag; + u_int8_t flags; + u_int8_t detect_time_multiplier; + u_int8_t length; + u_int8_t my_discriminator[4]; + u_int8_t your_discriminator[4]; + u_int8_t desired_min_tx_interval[4]; + u_int8_t required_min_rx_interval[4]; + u_int8_t required_min_echo_interval[4]; +}; + +/* + * An optional Authentication Header may be present + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Auth Type | Auth Len | Authentication Data... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct bfd_auth_header_t { + u_int8_t auth_type; + u_int8_t auth_len; + u_int8_t auth_data; +}; + +static const struct tok bfd_v1_authentication_values[] = { + { 0, "Reserved" }, + { 1, "Simple Password" }, + { 2, "Keyed MD5" }, + { 3, "Meticulous Keyed MD5" }, + { 4, "Keyed SHA1" }, + { 5, "Meticulous Keyed SHA1" }, + { 0, NULL } +}; + +#define BFD_EXTRACT_VERSION(x) (((x)&0xe0)>>5) +#define BFD_EXTRACT_DIAG(x) ((x)&0x1f) + +static const struct tok bfd_port_values[] = { + { BFD_CONTROL_PORT, "Control" }, + { BFD_ECHO_PORT, "Echo" }, + { 0, NULL } +}; + + +static const struct tok bfd_diag_values[] = { + { 0, "No Diagnostic" }, + { 1, "Control Detection Time Expired" }, + { 2, "Echo Function Failed" }, + { 3, "Neighbor Signaled Session Down" }, + { 4, "Forwarding Plane Reset" }, + { 5, "Path Down" }, + { 6, "Concatenated Path Down" }, + { 7, "Administratively Down" }, + { 8, "Reverse Concatenated Path Down" }, + { 0, NULL } +}; + +static const struct tok bfd_v0_flag_values[] = { + { 0x80, "I Hear You" }, + { 0x40, "Demand" }, + { 0x20, "Poll" }, + { 0x10, "Final" }, + { 0x08, "Reserved" }, + { 0x04, "Reserved" }, + { 0x02, "Reserved" }, + { 0x01, "Reserved" }, + { 0, NULL } +}; + +#define BFD_FLAG_AUTH 0x04 + +static const struct tok bfd_v1_flag_values[] = { + { 0x20, "Poll" }, + { 0x10, "Final" }, + { 0x08, "Control Plane Independent" }, + { BFD_FLAG_AUTH, "Authentication Present" }, + { 0x02, "Demand" }, + { 0x01, "Reserved" }, + { 0, NULL } +}; + +static const struct tok bfd_v1_state_values[] = { + { 0, "AdminDown" }, + { 1, "Down" }, + { 2, "Init" }, + { 3, "Up" }, + { 0, NULL } +}; + +void +bfd_print(register const u_char *pptr, register u_int len, register u_int port) +{ + const struct bfd_header_t *bfd_header; + const struct bfd_auth_header_t *bfd_auth_header; + u_int8_t version = 0; + + bfd_header = (const struct bfd_header_t *)pptr; + if (port == BFD_CONTROL_PORT) { + TCHECK(*bfd_header); + version = BFD_EXTRACT_VERSION(bfd_header->version_diag); + } else if (port == BFD_ECHO_PORT) { + /* Echo is BFD v1 only */ + version = 1; + } + switch ((port << 8) | version) { + + /* BFDv0 */ + case (BFD_CONTROL_PORT << 8): + if (vflag < 1 ) + { + printf("BFDv%u, %s, Flags: [%s], length: %u", + version, + tok2str(bfd_port_values, "unknown (%u)", port), + bittok2str(bfd_v0_flag_values, "none", bfd_header->flags), + len); + return; + } + + printf("BFDv%u, length: %u\n\t%s, Flags: [%s], Diagnostic: %s (0x%02x)", + version, + len, + tok2str(bfd_port_values, "unknown (%u)", port), + bittok2str(bfd_v0_flag_values, "none", bfd_header->flags), + tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(bfd_header->version_diag)), + BFD_EXTRACT_DIAG(bfd_header->version_diag)); + + printf("\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u", + bfd_header->detect_time_multiplier, + bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000, + bfd_header->length); + + + printf("\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator)); + printf(", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator)); + printf("\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000); + printf("\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000); + printf("\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000); + break; + + /* BFDv1 */ + case (BFD_CONTROL_PORT << 8 | 1): + if (vflag < 1 ) + { + printf("BFDv%u, %s, State %s, Flags: [%s], length: %u", + version, + tok2str(bfd_port_values, "unknown (%u)", port), + tok2str(bfd_v1_state_values, "unknown (%u)", (bfd_header->flags & 0xc0) >> 6), + bittok2str(bfd_v1_flag_values, "none", bfd_header->flags & 0x3f), + len); + return; + } + + printf("BFDv%u, length: %u\n\t%s, State %s, Flags: [%s], Diagnostic: %s (0x%02x)", + version, + len, + tok2str(bfd_port_values, "unknown (%u)", port), + tok2str(bfd_v1_state_values, "unknown (%u)", (bfd_header->flags & 0xc0) >> 6), + bittok2str(bfd_v1_flag_values, "none", bfd_header->flags & 0x3f), + tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(bfd_header->version_diag)), + BFD_EXTRACT_DIAG(bfd_header->version_diag)); + + printf("\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u", + bfd_header->detect_time_multiplier, + bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000, + bfd_header->length); + + + printf("\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator)); + printf(", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator)); + printf("\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000); + printf("\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000); + printf("\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000); + + if (bfd_header->flags & BFD_FLAG_AUTH) { + pptr += sizeof (const struct bfd_header_t); + bfd_auth_header = (const struct bfd_auth_header_t *)pptr; + TCHECK2(*bfd_auth_header, sizeof(const struct bfd_auth_header_t)); + printf("\n\t%s (%u) Authentication, length %u present", + tok2str(bfd_v1_authentication_values,"Unknown",bfd_auth_header->auth_type), + bfd_auth_header->auth_type, + bfd_auth_header->auth_len); + } + break; + + /* BFDv0 */ + case (BFD_ECHO_PORT << 8): /* not yet supported - fall through */ + /* BFDv1 */ + case (BFD_ECHO_PORT << 8 | 1): + + default: + printf("BFD, %s, length: %u", + tok2str(bfd_port_values, "unknown (%u)", port), + len); + if (vflag >= 1) { + if(!print_unknown_data(pptr,"\n\t",len)) + return; + } + break; + } + return; + +trunc: + printf("[|BFD]"); +} diff --git a/print-bgp.c b/print-bgp.c new file mode 100644 index 0000000..d77802d --- /dev/null +++ b/print-bgp.c @@ -0,0 +1,2602 @@ +/* + * Copyright (C) 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Extensively modified by Hannes Gredler (hannes@juniper.net) for more + * complete BGP support. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-bgp.c,v 1.118 2007-12-07 15:54:52 hannes Exp $"; +#endif + +#include + +#include +#include + +#include "interface.h" +#include "decode_prefix.h" +#include "addrtoname.h" +#include "extract.h" +#include "bgp.h" +#include "af.h" +#include "l2vpn.h" + +struct bgp { + u_int8_t bgp_marker[16]; + u_int16_t bgp_len; + u_int8_t bgp_type; +}; +#define BGP_SIZE 19 /* unaligned */ + +#define BGP_OPEN 1 +#define BGP_UPDATE 2 +#define BGP_NOTIFICATION 3 +#define BGP_KEEPALIVE 4 +#define BGP_ROUTE_REFRESH 5 + +static struct tok bgp_msg_values[] = { + { BGP_OPEN, "Open"}, + { BGP_UPDATE, "Update"}, + { BGP_NOTIFICATION, "Notification"}, + { BGP_KEEPALIVE, "Keepalive"}, + { BGP_ROUTE_REFRESH, "Route Refresh"}, + { 0, NULL} +}; + +struct bgp_open { + u_int8_t bgpo_marker[16]; + u_int16_t bgpo_len; + u_int8_t bgpo_type; + u_int8_t bgpo_version; + u_int16_t bgpo_myas; + u_int16_t bgpo_holdtime; + u_int32_t bgpo_id; + u_int8_t bgpo_optlen; + /* options should follow */ +}; +#define BGP_OPEN_SIZE 29 /* unaligned */ + +struct bgp_opt { + u_int8_t bgpopt_type; + u_int8_t bgpopt_len; + /* variable length */ +}; +#define BGP_OPT_SIZE 2 /* some compilers may pad to 4 bytes */ + +#define BGP_UPDATE_MINSIZE 23 + +struct bgp_notification { + u_int8_t bgpn_marker[16]; + u_int16_t bgpn_len; + u_int8_t bgpn_type; + u_int8_t bgpn_major; + u_int8_t bgpn_minor; +}; +#define BGP_NOTIFICATION_SIZE 21 /* unaligned */ + +struct bgp_route_refresh { + u_int8_t bgp_marker[16]; + u_int16_t len; + u_int8_t type; + u_int8_t afi[2]; /* the compiler messes this structure up */ + u_int8_t res; /* when doing misaligned sequences of int8 and int16 */ + u_int8_t safi; /* afi should be int16 - so we have to access it using */ +}; /* EXTRACT_16BITS(&bgp_route_refresh->afi) (sigh) */ +#define BGP_ROUTE_REFRESH_SIZE 23 + +struct bgp_attr { + u_int8_t bgpa_flags; + u_int8_t bgpa_type; + union { + u_int8_t len; + u_int16_t elen; + } bgpa_len; +#define bgp_attr_len(p) \ + (((p)->bgpa_flags & 0x10) ? \ + EXTRACT_16BITS(&(p)->bgpa_len.elen) : (p)->bgpa_len.len) +#define bgp_attr_off(p) \ + (((p)->bgpa_flags & 0x10) ? 4 : 3) +}; + +#define BGPTYPE_ORIGIN 1 +#define BGPTYPE_AS_PATH 2 +#define BGPTYPE_NEXT_HOP 3 +#define BGPTYPE_MULTI_EXIT_DISC 4 +#define BGPTYPE_LOCAL_PREF 5 +#define BGPTYPE_ATOMIC_AGGREGATE 6 +#define BGPTYPE_AGGREGATOR 7 +#define BGPTYPE_COMMUNITIES 8 /* RFC1997 */ +#define BGPTYPE_ORIGINATOR_ID 9 /* RFC1998 */ +#define BGPTYPE_CLUSTER_LIST 10 /* RFC1998 */ +#define BGPTYPE_DPA 11 /* draft-ietf-idr-bgp-dpa */ +#define BGPTYPE_ADVERTISERS 12 /* RFC1863 */ +#define BGPTYPE_RCID_PATH 13 /* RFC1863 */ +#define BGPTYPE_MP_REACH_NLRI 14 /* RFC2283 */ +#define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC2283 */ +#define BGPTYPE_EXTD_COMMUNITIES 16 /* draft-ietf-idr-bgp-ext-communities */ +#define BGPTYPE_AS4_PATH 17 /* RFC4893 */ +#define BGPTYPE_AGGREGATOR4 18 /* RFC4893 */ +#define BGPTYPE_PMSI_TUNNEL 22 /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */ +#define BGPTYPE_ATTR_SET 128 /* draft-marques-ppvpn-ibgp */ + +#define BGP_MP_NLRI_MINSIZE 3 /* End of RIB Marker detection */ + +static struct tok bgp_attr_values[] = { + { BGPTYPE_ORIGIN, "Origin"}, + { BGPTYPE_AS_PATH, "AS Path"}, + { BGPTYPE_AS4_PATH, "AS4 Path"}, + { BGPTYPE_NEXT_HOP, "Next Hop"}, + { BGPTYPE_MULTI_EXIT_DISC, "Multi Exit Discriminator"}, + { BGPTYPE_LOCAL_PREF, "Local Preference"}, + { BGPTYPE_ATOMIC_AGGREGATE, "Atomic Aggregate"}, + { BGPTYPE_AGGREGATOR, "Aggregator"}, + { BGPTYPE_AGGREGATOR4, "Aggregator4"}, + { BGPTYPE_COMMUNITIES, "Community"}, + { BGPTYPE_ORIGINATOR_ID, "Originator ID"}, + { BGPTYPE_CLUSTER_LIST, "Cluster List"}, + { BGPTYPE_DPA, "DPA"}, + { BGPTYPE_ADVERTISERS, "Advertisers"}, + { BGPTYPE_RCID_PATH, "RCID Path / Cluster ID"}, + { BGPTYPE_MP_REACH_NLRI, "Multi-Protocol Reach NLRI"}, + { BGPTYPE_MP_UNREACH_NLRI, "Multi-Protocol Unreach NLRI"}, + { BGPTYPE_EXTD_COMMUNITIES, "Extended Community"}, + { BGPTYPE_PMSI_TUNNEL, "PMSI Tunnel"}, + { BGPTYPE_ATTR_SET, "Attribute Set"}, + { 255, "Reserved for development"}, + { 0, NULL} +}; + +#define BGP_AS_SET 1 +#define BGP_AS_SEQUENCE 2 +#define BGP_CONFED_AS_SEQUENCE 3 /* draft-ietf-idr-rfc3065bis-01 */ +#define BGP_CONFED_AS_SET 4 /* draft-ietf-idr-rfc3065bis-01 */ + +#define BGP_AS_SEG_TYPE_MIN BGP_AS_SET +#define BGP_AS_SEG_TYPE_MAX BGP_CONFED_AS_SET + +static struct tok bgp_as_path_segment_open_values[] = { + { BGP_AS_SEQUENCE, ""}, + { BGP_AS_SET, "{ "}, + { BGP_CONFED_AS_SEQUENCE, "( "}, + { BGP_CONFED_AS_SET, "({ "}, + { 0, NULL} +}; + +static struct tok bgp_as_path_segment_close_values[] = { + { BGP_AS_SEQUENCE, ""}, + { BGP_AS_SET, "}"}, + { BGP_CONFED_AS_SEQUENCE, ")"}, + { BGP_CONFED_AS_SET, "})"}, + { 0, NULL} +}; + +#define BGP_OPT_AUTH 1 +#define BGP_OPT_CAP 2 + + +static struct tok bgp_opt_values[] = { + { BGP_OPT_AUTH, "Authentication Information"}, + { BGP_OPT_CAP, "Capabilities Advertisement"}, + { 0, NULL} +}; + +#define BGP_CAPCODE_MP 1 +#define BGP_CAPCODE_RR 2 +#define BGP_CAPCODE_ORF 3 /* XXX */ +#define BGP_CAPCODE_RESTART 64 /* draft-ietf-idr-restart-05 */ +#define BGP_CAPCODE_AS_NEW 65 /* XXX */ +#define BGP_CAPCODE_DYN_CAP 67 /* XXX */ +#define BGP_CAPCODE_RR_CISCO 128 + +static struct tok bgp_capcode_values[] = { + { BGP_CAPCODE_MP, "Multiprotocol Extensions"}, + { BGP_CAPCODE_RR, "Route Refresh"}, + { BGP_CAPCODE_ORF, "Cooperative Route Filtering"}, + { BGP_CAPCODE_RESTART, "Graceful Restart"}, + { BGP_CAPCODE_AS_NEW, "32-Bit AS Number"}, + { BGP_CAPCODE_DYN_CAP, "Dynamic Capability"}, + { BGP_CAPCODE_RR_CISCO, "Route Refresh (Cisco)"}, + { 0, NULL} +}; + +#define BGP_NOTIFY_MAJOR_MSG 1 +#define BGP_NOTIFY_MAJOR_OPEN 2 +#define BGP_NOTIFY_MAJOR_UPDATE 3 +#define BGP_NOTIFY_MAJOR_HOLDTIME 4 +#define BGP_NOTIFY_MAJOR_FSM 5 +#define BGP_NOTIFY_MAJOR_CEASE 6 +#define BGP_NOTIFY_MAJOR_CAP 7 + +static struct tok bgp_notify_major_values[] = { + { BGP_NOTIFY_MAJOR_MSG, "Message Header Error"}, + { BGP_NOTIFY_MAJOR_OPEN, "OPEN Message Error"}, + { BGP_NOTIFY_MAJOR_UPDATE, "UPDATE Message Error"}, + { BGP_NOTIFY_MAJOR_HOLDTIME,"Hold Timer Expired"}, + { BGP_NOTIFY_MAJOR_FSM, "Finite State Machine Error"}, + { BGP_NOTIFY_MAJOR_CEASE, "Cease"}, + { BGP_NOTIFY_MAJOR_CAP, "Capability Message Error"}, + { 0, NULL} +}; + +/* draft-ietf-idr-cease-subcode-02 */ +#define BGP_NOTIFY_MINOR_CEASE_MAXPRFX 1 +static struct tok bgp_notify_minor_cease_values[] = { + { BGP_NOTIFY_MINOR_CEASE_MAXPRFX, "Maximum Number of Prefixes Reached"}, + { 2, "Administratively Shutdown"}, + { 3, "Peer Unconfigured"}, + { 4, "Administratively Reset"}, + { 5, "Connection Rejected"}, + { 6, "Other Configuration Change"}, + { 7, "Connection Collision Resolution"}, + { 0, NULL} +}; + +static struct tok bgp_notify_minor_msg_values[] = { + { 1, "Connection Not Synchronized"}, + { 2, "Bad Message Length"}, + { 3, "Bad Message Type"}, + { 0, NULL} +}; + +static struct tok bgp_notify_minor_open_values[] = { + { 1, "Unsupported Version Number"}, + { 2, "Bad Peer AS"}, + { 3, "Bad BGP Identifier"}, + { 4, "Unsupported Optional Parameter"}, + { 5, "Authentication Failure"}, + { 6, "Unacceptable Hold Time"}, + { 7, "Capability Message Error"}, + { 0, NULL} +}; + +static struct tok bgp_notify_minor_update_values[] = { + { 1, "Malformed Attribute List"}, + { 2, "Unrecognized Well-known Attribute"}, + { 3, "Missing Well-known Attribute"}, + { 4, "Attribute Flags Error"}, + { 5, "Attribute Length Error"}, + { 6, "Invalid ORIGIN Attribute"}, + { 7, "AS Routing Loop"}, + { 8, "Invalid NEXT_HOP Attribute"}, + { 9, "Optional Attribute Error"}, + { 10, "Invalid Network Field"}, + { 11, "Malformed AS_PATH"}, + { 0, NULL} +}; + +static struct tok bgp_notify_minor_cap_values[] = { + { 1, "Invalid Action Value" }, + { 2, "Invalid Capability Length" }, + { 3, "Malformed Capability Value" }, + { 4, "Unsupported Capability Code" }, + { 0, NULL } +}; + +static struct tok bgp_origin_values[] = { + { 0, "IGP"}, + { 1, "EGP"}, + { 2, "Incomplete"}, + { 0, NULL} +}; + +#define BGP_PMSI_TUNNEL_RSVP_P2MP 1 +#define BGP_PMSI_TUNNEL_LDP_P2MP 2 +#define BGP_PMSI_TUNNEL_PIM_SSM 3 +#define BGP_PMSI_TUNNEL_PIM_SM 4 +#define BGP_PMSI_TUNNEL_PIM_BIDIR 5 +#define BGP_PMSI_TUNNEL_INGRESS 6 +#define BGP_PMSI_TUNNEL_LDP_MP2MP 7 + +static struct tok bgp_pmsi_tunnel_values[] = { + { BGP_PMSI_TUNNEL_RSVP_P2MP, "RSVP-TE P2MP LSP"}, + { BGP_PMSI_TUNNEL_LDP_P2MP, "LDP P2MP LSP"}, + { BGP_PMSI_TUNNEL_PIM_SSM, "PIM-SSM Tree"}, + { BGP_PMSI_TUNNEL_PIM_SM, "PIM-SM Tree"}, + { BGP_PMSI_TUNNEL_PIM_BIDIR, "PIM-Bidir Tree"}, + { BGP_PMSI_TUNNEL_INGRESS, "Ingress Replication"}, + { BGP_PMSI_TUNNEL_LDP_MP2MP, "LDP MP2MP LSP"}, + { 0, NULL} +}; + +static struct tok bgp_pmsi_flag_values[] = { + { 0x01, "Leaf Information required"}, + { 0, NULL} +}; + + +/* Subsequent address family identifier, RFC2283 section 7 */ +#define SAFNUM_RES 0 +#define SAFNUM_UNICAST 1 +#define SAFNUM_MULTICAST 2 +#define SAFNUM_UNIMULTICAST 3 +/* labeled BGP RFC3107 */ +#define SAFNUM_LABUNICAST 4 +/* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */ +#define SAFNUM_MULTICAST_VPN 5 +#define SAFNUM_TUNNEL 64 /* XXX */ +#define SAFNUM_VPLS 65 /* XXX */ +/* draft-nalawade-idr-mdt-safi-03 */ +#define SAFNUM_MDT 66 +/* Section 4.3.4 of draft-rosen-rfc2547bis-03.txt */ +#define SAFNUM_VPNUNICAST 128 +#define SAFNUM_VPNMULTICAST 129 +#define SAFNUM_VPNUNIMULTICAST 130 +/* draft-marques-ppvpn-rt-constrain-01.txt */ +#define SAFNUM_RT_ROUTING_INFO 132 + +#define BGP_VPN_RD_LEN 8 + +static struct tok bgp_safi_values[] = { + { SAFNUM_RES, "Reserved"}, + { SAFNUM_UNICAST, "Unicast"}, + { SAFNUM_MULTICAST, "Multicast"}, + { SAFNUM_UNIMULTICAST, "Unicast+Multicast"}, + { SAFNUM_LABUNICAST, "labeled Unicast"}, + { SAFNUM_TUNNEL, "Tunnel"}, + { SAFNUM_VPLS, "VPLS"}, + { SAFNUM_MDT, "MDT"}, + { SAFNUM_VPNUNICAST, "labeled VPN Unicast"}, + { SAFNUM_VPNMULTICAST, "labeled VPN Multicast"}, + { SAFNUM_VPNUNIMULTICAST, "labeled VPN Unicast+Multicast"}, + { SAFNUM_RT_ROUTING_INFO, "Route Target Routing Information"}, + { SAFNUM_MULTICAST_VPN, "Multicast VPN"}, + { 0, NULL } +}; + +/* well-known community */ +#define BGP_COMMUNITY_NO_EXPORT 0xffffff01 +#define BGP_COMMUNITY_NO_ADVERT 0xffffff02 +#define BGP_COMMUNITY_NO_EXPORT_SUBCONFED 0xffffff03 + +/* Extended community type - draft-ietf-idr-bgp-ext-communities-05 */ +#define BGP_EXT_COM_RT_0 0x0002 /* Route Target,Format AS(2bytes):AN(4bytes) */ +#define BGP_EXT_COM_RT_1 0x0102 /* Route Target,Format IP address:AN(2bytes) */ +#define BGP_EXT_COM_RT_2 0x0202 /* Route Target,Format AN(4bytes):local(2bytes) */ +#define BGP_EXT_COM_RO_0 0x0003 /* Route Origin,Format AS(2bytes):AN(4bytes) */ +#define BGP_EXT_COM_RO_1 0x0103 /* Route Origin,Format IP address:AN(2bytes) */ +#define BGP_EXT_COM_RO_2 0x0203 /* Route Origin,Format AN(4bytes):local(2bytes) */ +#define BGP_EXT_COM_LINKBAND 0x4004 /* Link Bandwidth,Format AS(2B):Bandwidth(4B) */ + /* rfc2547 bgp-mpls-vpns */ +#define BGP_EXT_COM_VPN_ORIGIN 0x0005 /* OSPF Domain ID / VPN of Origin - draft-rosen-vpns-ospf-bgp-mpls */ +#define BGP_EXT_COM_VPN_ORIGIN2 0x0105 /* duplicate - keep for backwards compatability */ +#define BGP_EXT_COM_VPN_ORIGIN3 0x0205 /* duplicate - keep for backwards compatability */ +#define BGP_EXT_COM_VPN_ORIGIN4 0x8005 /* duplicate - keep for backwards compatability */ + +#define BGP_EXT_COM_OSPF_RTYPE 0x0306 /* OSPF Route Type,Format Area(4B):RouteType(1B):Options(1B) */ +#define BGP_EXT_COM_OSPF_RTYPE2 0x8000 /* duplicate - keep for backwards compatability */ + +#define BGP_EXT_COM_OSPF_RID 0x0107 /* OSPF Router ID,Format RouterID(4B):Unused(2B) */ +#define BGP_EXT_COM_OSPF_RID2 0x8001 /* duplicate - keep for backwards compatability */ + +#define BGP_EXT_COM_L2INFO 0x800a /* draft-kompella-ppvpn-l2vpn */ + +#define BGP_EXT_COM_SOURCE_AS 0x0009 /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */ +#define BGP_EXT_COM_VRF_RT_IMP 0x010a /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */ + +/* http://www.cisco.com/en/US/tech/tk436/tk428/technologies_tech_note09186a00801eb09a.shtml */ +#define BGP_EXT_COM_EIGRP_GEN 0x8800 +#define BGP_EXT_COM_EIGRP_METRIC_AS_DELAY 0x8801 +#define BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW 0x8802 +#define BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU 0x8803 +#define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID 0x8804 +#define BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC 0x8805 + +static struct tok bgp_extd_comm_flag_values[] = { + { 0x8000, "vendor-specific"}, + { 0x4000, "non-transitive"}, + { 0, NULL}, +}; + +static struct tok bgp_extd_comm_subtype_values[] = { + { BGP_EXT_COM_RT_0, "target"}, + { BGP_EXT_COM_RT_1, "target"}, + { BGP_EXT_COM_RT_2, "target"}, + { BGP_EXT_COM_RO_0, "origin"}, + { BGP_EXT_COM_RO_1, "origin"}, + { BGP_EXT_COM_RO_2, "origin"}, + { BGP_EXT_COM_LINKBAND, "link-BW"}, + { BGP_EXT_COM_VPN_ORIGIN, "ospf-domain"}, + { BGP_EXT_COM_VPN_ORIGIN2, "ospf-domain"}, + { BGP_EXT_COM_VPN_ORIGIN3, "ospf-domain"}, + { BGP_EXT_COM_VPN_ORIGIN4, "ospf-domain"}, + { BGP_EXT_COM_OSPF_RTYPE, "ospf-route-type"}, + { BGP_EXT_COM_OSPF_RTYPE2, "ospf-route-type"}, + { BGP_EXT_COM_OSPF_RID, "ospf-router-id"}, + { BGP_EXT_COM_OSPF_RID2, "ospf-router-id"}, + { BGP_EXT_COM_L2INFO, "layer2-info"}, + { BGP_EXT_COM_EIGRP_GEN , "eigrp-general-route (flag, tag)" }, + { BGP_EXT_COM_EIGRP_METRIC_AS_DELAY , "eigrp-route-metric (AS, delay)" }, + { BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW , "eigrp-route-metric (reliability, nexthop, bandwidth)" }, + { BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU , "eigrp-route-metric (load, MTU)" }, + { BGP_EXT_COM_EIGRP_EXT_REMAS_REMID , "eigrp-external-route (remote-AS, remote-ID)" }, + { BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC , "eigrp-external-route (remote-proto, remote-metric)" }, + { BGP_EXT_COM_SOURCE_AS, "source-AS" }, + { BGP_EXT_COM_VRF_RT_IMP, "vrf-route-import"}, + { 0, NULL}, +}; + +/* OSPF codes for BGP_EXT_COM_OSPF_RTYPE draft-rosen-vpns-ospf-bgp-mpls */ +#define BGP_OSPF_RTYPE_RTR 1 /* OSPF Router LSA */ +#define BGP_OSPF_RTYPE_NET 2 /* OSPF Network LSA */ +#define BGP_OSPF_RTYPE_SUM 3 /* OSPF Summary LSA */ +#define BGP_OSPF_RTYPE_EXT 5 /* OSPF External LSA, note that ASBR doesn't apply to MPLS-VPN */ +#define BGP_OSPF_RTYPE_NSSA 7 /* OSPF NSSA External*/ +#define BGP_OSPF_RTYPE_SHAM 129 /* OSPF-MPLS-VPN Sham link */ +#define BGP_OSPF_RTYPE_METRIC_TYPE 0x1 /* LSB of RTYPE Options Field */ + +static struct tok bgp_extd_comm_ospf_rtype_values[] = { + { BGP_OSPF_RTYPE_RTR, "Router" }, + { BGP_OSPF_RTYPE_NET, "Network" }, + { BGP_OSPF_RTYPE_SUM, "Summary" }, + { BGP_OSPF_RTYPE_EXT, "External" }, + { BGP_OSPF_RTYPE_NSSA,"NSSA External" }, + { BGP_OSPF_RTYPE_SHAM,"MPLS-VPN Sham" }, + { 0, NULL }, +}; + +#define TOKBUFSIZE 128 +static char astostr[20]; + +/* + * as_printf + * + * Convert an AS number into a string and return string pointer. + * + * Bepending on bflag is set or not, AS number is converted into ASDOT notation + * or plain number notation. + * + */ +static char * +as_printf (char *str, int size, u_int asnum) +{ + if (!bflag || asnum <= 0xFFFF) { + snprintf(str, size, "%u", asnum); + } else { + snprintf(str, size, "%u.%u", asnum >> 16, asnum & 0xFFFF); + } + return str; +} + +int +decode_prefix4(const u_char *pptr, char *buf, u_int buflen) +{ + struct in_addr addr; + u_int plen; + + TCHECK(pptr[0]); + plen = pptr[0]; + if (32 < plen) + return -1; + + memset(&addr, 0, sizeof(addr)); + TCHECK2(pptr[1], (plen + 7) / 8); + memcpy(&addr, &pptr[1], (plen + 7) / 8); + if (plen % 8) { + ((u_char *)&addr)[(plen + 7) / 8 - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + snprintf(buf, buflen, "%s/%d", getname((u_char *)&addr), plen); + return 1 + (plen + 7) / 8; + +trunc: + return -2; +} + +static int +decode_labeled_prefix4(const u_char *pptr, char *buf, u_int buflen) +{ + struct in_addr addr; + u_int plen; + + TCHECK(pptr[0]); + plen = pptr[0]; /* get prefix length */ + + /* this is one of the weirdnesses of rfc3107 + the label length (actually the label + COS bits) + is added to the prefix length; + we also do only read out just one label - + there is no real application for advertisement of + stacked labels in a a single BGP message + */ + + if (24 > plen) + return -1; + + plen-=24; /* adjust prefixlen - labellength */ + + if (32 < plen) + return -1; + + memset(&addr, 0, sizeof(addr)); + TCHECK2(pptr[4], (plen + 7) / 8); + memcpy(&addr, &pptr[4], (plen + 7) / 8); + if (plen % 8) { + ((u_char *)&addr)[(plen + 7) / 8 - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + /* the label may get offsetted by 4 bits so lets shift it right */ + snprintf(buf, buflen, "%s/%d, label:%u %s", + getname((u_char *)&addr), + plen, + EXTRACT_24BITS(pptr+1)>>4, + ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + + return 4 + (plen + 7) / 8; + +trunc: + return -2; +} + +/* + * bgp_vpn_ip_print + * + * print an ipv4 or ipv6 address into a buffer dependend on address length. + */ +static char * +bgp_vpn_ip_print (const u_char *pptr, u_int addr_length) { + + /* worst case string is s fully formatted v6 address */ + static char addr[sizeof("1234:5678:89ab:cdef:1234:5678:89ab:cdef")]; + char *pos = addr; + + switch(addr_length) { + case (sizeof(struct in_addr) << 3): /* 32 */ + TCHECK2(pptr[0], sizeof(struct in_addr)); + snprintf(pos, sizeof(addr), "%s", ipaddr_string(pptr)); + break; +#ifdef INET6 + case (sizeof(struct in6_addr) << 3): /* 128 */ + TCHECK2(pptr[0], sizeof(struct in6_addr)); + snprintf(pos, sizeof(addr), "%s", ip6addr_string(pptr)); + break; +#endif + default: + snprintf(pos, sizeof(addr), "bogus address length %u", addr_length); + break; + } + pos += strlen(pos); + +trunc: + *(pos) = '\0'; + return (addr); +} + +/* + * bgp_vpn_sg_print + * + * print an multicast s,g entry into a buffer. + * the s,g entry is encoded like this. + * + * +-----------------------------------+ + * | Multicast Source Length (1 octet) | + * +-----------------------------------+ + * | Multicast Source (Variable) | + * +-----------------------------------+ + * | Multicast Group Length (1 octet) | + * +-----------------------------------+ + * | Multicast Group (Variable) | + * +-----------------------------------+ + * + * return the number of bytes read from the wire. + */ +static int +bgp_vpn_sg_print (const u_char *pptr, char *buf, u_int buflen) { + + u_int8_t addr_length; + u_int total_length, offset; + + total_length = 0; + + /* Source address length, encoded in bits */ + TCHECK2(pptr[0], 1); + addr_length = *pptr++; + + /* Source address */ + TCHECK2(pptr[0], (addr_length >> 3)); + total_length += (addr_length >> 3) + 1; + offset = strlen(buf); + if (addr_length) { + snprintf(buf + offset, buflen - offset, ", Source %s", + bgp_vpn_ip_print(pptr, addr_length)); + pptr += (addr_length >> 3); + } + + /* Group address length, encoded in bits */ + TCHECK2(pptr[0], 1); + addr_length = *pptr++; + + /* Group address */ + TCHECK2(pptr[0], (addr_length >> 3)); + total_length += (addr_length >> 3) + 1; + offset = strlen(buf); + if (addr_length) { + snprintf(buf + offset, buflen - offset, ", Group %s", + bgp_vpn_ip_print(pptr, addr_length)); + pptr += (addr_length >> 3); + } + +trunc: + return (total_length); +} + + +/* RDs and RTs share the same semantics + * we use bgp_vpn_rd_print for + * printing route targets inside a NLRI */ +char * +bgp_vpn_rd_print (const u_char *pptr) { + + /* allocate space for the largest possible string */ + static char rd[sizeof("xxxxxxxxxx:xxxxx (xxx.xxx.xxx.xxx:xxxxx)")]; + char *pos = rd; + + /* ok lets load the RD format */ + switch (EXTRACT_16BITS(pptr)) { + + /* 2-byte-AS:number fmt*/ + case 0: + snprintf(pos, sizeof(rd) - (pos - rd), "%u:%u (= %u.%u.%u.%u)", + EXTRACT_16BITS(pptr+2), + EXTRACT_32BITS(pptr+4), + *(pptr+4), *(pptr+5), *(pptr+6), *(pptr+7)); + break; + /* IP-address:AS fmt*/ + + case 1: + snprintf(pos, sizeof(rd) - (pos - rd), "%u.%u.%u.%u:%u", + *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5), EXTRACT_16BITS(pptr+6)); + break; + + /* 4-byte-AS:number fmt*/ + case 2: + snprintf(pos, sizeof(rd) - (pos - rd), "%s:%u (%u.%u.%u.%u:%u)", + as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(pptr+2)), + EXTRACT_16BITS(pptr+6), *(pptr+2), *(pptr+3), *(pptr+4), + *(pptr+5), EXTRACT_16BITS(pptr+6)); + break; + default: + snprintf(pos, sizeof(rd) - (pos - rd), "unknown RD format"); + break; + } + pos += strlen(pos); + *(pos) = '\0'; + return (rd); +} + +static int +decode_rt_routing_info(const u_char *pptr, char *buf, u_int buflen) +{ + u_int8_t route_target[8]; + u_int plen; + + TCHECK(pptr[0]); + plen = pptr[0]; /* get prefix length */ + + if (0 == plen) + return 1; /* default route target */ + + if (32 > plen) + return -1; + + plen-=32; /* adjust prefix length */ + + if (64 < plen) + return -1; + + memset(&route_target, 0, sizeof(route_target)); + TCHECK2(pptr[1], (plen + 7) / 8); + memcpy(&route_target, &pptr[1], (plen + 7) / 8); + if (plen % 8) { + ((u_char *)&route_target)[(plen + 7) / 8 - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + snprintf(buf, buflen, "origin AS: %s, route target %s", + as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(pptr+1)), + bgp_vpn_rd_print((u_char *)&route_target)); + + return 5 + (plen + 7) / 8; + +trunc: + return -2; +} + +static int +decode_labeled_vpn_prefix4(const u_char *pptr, char *buf, u_int buflen) +{ + struct in_addr addr; + u_int plen; + + TCHECK(pptr[0]); + plen = pptr[0]; /* get prefix length */ + + if ((24+64) > plen) + return -1; + + plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ + + if (32 < plen) + return -1; + + memset(&addr, 0, sizeof(addr)); + TCHECK2(pptr[12], (plen + 7) / 8); + memcpy(&addr, &pptr[12], (plen + 7) / 8); + if (plen % 8) { + ((u_char *)&addr)[(plen + 7) / 8 - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + /* the label may get offsetted by 4 bits so lets shift it right */ + snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", + bgp_vpn_rd_print(pptr+4), + getname((u_char *)&addr), + plen, + EXTRACT_24BITS(pptr+1)>>4, + ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + + return 12 + (plen + 7) / 8; + +trunc: + return -2; +} + +/* + * +-------------------------------+ + * | | + * | RD:IPv4-address (12 octets) | + * | | + * +-------------------------------+ + * | MDT Group-address (4 octets) | + * +-------------------------------+ + */ + +#define MDT_VPN_NLRI_LEN 16 + +static int +decode_mdt_vpn_nlri(const u_char *pptr, char *buf, u_int buflen) +{ + + const u_char *rd; + const u_char *vpn_ip; + + TCHECK(pptr[0]); + + /* if the NLRI is not predefined length, quit.*/ + if (*pptr != MDT_VPN_NLRI_LEN * NBBY) + return -1; + pptr++; + + /* RD */ + TCHECK2(pptr[0], 8); + rd = pptr; + pptr+=8; + + /* IPv4 address */ + TCHECK2(pptr[0], sizeof(struct in_addr)); + vpn_ip = pptr; + pptr+=sizeof(struct in_addr); + + /* MDT Group Address */ + TCHECK2(pptr[0], sizeof(struct in_addr)); + + snprintf(buf, buflen, "RD: %s, VPN IP Address: %s, MC Group Address: %s", + bgp_vpn_rd_print(rd), ipaddr_string(vpn_ip), ipaddr_string(pptr)); + + return MDT_VPN_NLRI_LEN + 1; + + trunc: + +return -2; +} + +#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI 1 +#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI 2 +#define BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI 3 +#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF 4 +#define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE 5 +#define BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN 6 +#define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN 7 + +static struct tok bgp_multicast_vpn_route_type_values[] = { + { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI, "Intra-AS I-PMSI"}, + { BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI, "Inter-AS I-PMSI"}, + { BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI, "S-PMSI"}, + { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF, "Intra-AS Segment-Leaf"}, + { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE, "Source-Active"}, + { BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN, "Shared Tree Join"}, + { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN, "Source Tree Join"}, +}; + +static int +decode_multicast_vpn(const u_char *pptr, char *buf, u_int buflen) +{ + u_int8_t route_type, route_length, addr_length, sg_length; + u_int offset; + + TCHECK2(pptr[0], 2); + route_type = *pptr++; + route_length = *pptr++; + + snprintf(buf, buflen, "Route-Type: %s (%u), length: %u", + tok2str(bgp_multicast_vpn_route_type_values, + "Unknown", route_type), + route_type, route_length); + + switch(route_type) { + case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI: + TCHECK2(pptr[0], BGP_VPN_RD_LEN); + offset = strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s, Originator %s", + bgp_vpn_rd_print(pptr), + bgp_vpn_ip_print(pptr + BGP_VPN_RD_LEN, + (route_length - BGP_VPN_RD_LEN) << 3)); + break; + case BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI: + TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4); + offset = strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s", + bgp_vpn_rd_print(pptr), + as_printf(astostr, sizeof(astostr), + EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN))); + break; + + case BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI: + TCHECK2(pptr[0], BGP_VPN_RD_LEN); + offset = strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s", + bgp_vpn_rd_print(pptr)); + pptr += BGP_VPN_RD_LEN; + + sg_length = bgp_vpn_sg_print(pptr, buf, buflen); + addr_length = route_length - sg_length; + + TCHECK2(pptr[0], addr_length); + offset = strlen(buf); + snprintf(buf + offset, buflen - offset, ", Originator %s", + bgp_vpn_ip_print(pptr, addr_length << 3)); + break; + + case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE: + TCHECK2(pptr[0], BGP_VPN_RD_LEN); + offset = strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s", + bgp_vpn_rd_print(pptr)); + pptr += BGP_VPN_RD_LEN; + + bgp_vpn_sg_print(pptr, buf, buflen); + break; + + case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */ + case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN: + TCHECK2(pptr[0], BGP_VPN_RD_LEN); + offset = strlen(buf); + snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s", + bgp_vpn_rd_print(pptr), + as_printf(astostr, sizeof(astostr), + EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN))); + pptr += BGP_VPN_RD_LEN; + + bgp_vpn_sg_print(pptr, buf, buflen); + break; + + /* + * no per route-type printing yet. + */ + case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF: + default: + break; + } + + return route_length + 2; + +trunc: + return -2; +} + +/* + * As I remember, some versions of systems have an snprintf() that + * returns -1 if the buffer would have overflowed. If the return + * value is negative, set buflen to 0, to indicate that we've filled + * the buffer up. + * + * If the return value is greater than buflen, that means that + * the buffer would have overflowed; again, set buflen to 0 in + * that case. + */ +#define UPDATE_BUF_BUFLEN(buf, buflen, strlen) \ + if (strlen<0) \ + buflen=0; \ + else if ((u_int)strlen>buflen) \ + buflen=0; \ + else { \ + buflen-=strlen; \ + buf+=strlen; \ + } + +static int +decode_labeled_vpn_l2(const u_char *pptr, char *buf, u_int buflen) +{ + int plen,tlen,strlen,tlv_type,tlv_len,ttlv_len; + + TCHECK2(pptr[0], 2); + plen=EXTRACT_16BITS(pptr); + tlen=plen; + pptr+=2; + TCHECK2(pptr[0],15); + buf[0]='\0'; + strlen=snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u", + bgp_vpn_rd_print(pptr), + EXTRACT_16BITS(pptr+8), + EXTRACT_16BITS(pptr+10), + EXTRACT_24BITS(pptr+12)>>4); /* the label is offsetted by 4 bits so lets shift it right */ + UPDATE_BUF_BUFLEN(buf, buflen, strlen); + pptr+=15; + tlen-=15; + + /* ok now the variable part - lets read out TLVs*/ + while (tlen>0) { + if (tlen < 3) + return -1; + TCHECK2(pptr[0], 3); + tlv_type=*pptr++; + tlv_len=EXTRACT_16BITS(pptr); + ttlv_len=tlv_len; + pptr+=2; + + switch(tlv_type) { + case 1: + if (buflen!=0) { + strlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x", + tlv_type, + tlv_len); + UPDATE_BUF_BUFLEN(buf, buflen, strlen); + } + ttlv_len=ttlv_len/8+1; /* how many bytes do we need to read ? */ + while (ttlv_len>0) { + TCHECK(pptr[0]); + if (buflen!=0) { + strlen=snprintf(buf,buflen, "%02x",*pptr++); + UPDATE_BUF_BUFLEN(buf, buflen, strlen); + } + ttlv_len--; + } + break; + default: + if (buflen!=0) { + strlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u", + tlv_type, + tlv_len); + UPDATE_BUF_BUFLEN(buf, buflen, strlen); + } + break; + } + tlen-=(tlv_len<<3); /* the tlv-length is expressed in bits so lets shift it right */ + } + return plen+2; + +trunc: + return -2; +} + +#ifdef INET6 +int +decode_prefix6(const u_char *pd, char *buf, u_int buflen) +{ + struct in6_addr addr; + u_int plen; + + TCHECK(pd[0]); + plen = pd[0]; + if (128 < plen) + return -1; + + memset(&addr, 0, sizeof(addr)); + TCHECK2(pd[1], (plen + 7) / 8); + memcpy(&addr, &pd[1], (plen + 7) / 8); + if (plen % 8) { + addr.s6_addr[(plen + 7) / 8 - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + snprintf(buf, buflen, "%s/%d", getname6((u_char *)&addr), plen); + return 1 + (plen + 7) / 8; + +trunc: + return -2; +} + +static int +decode_labeled_prefix6(const u_char *pptr, char *buf, u_int buflen) +{ + struct in6_addr addr; + u_int plen; + + TCHECK(pptr[0]); + plen = pptr[0]; /* get prefix length */ + + if (24 > plen) + return -1; + + plen-=24; /* adjust prefixlen - labellength */ + + if (128 < plen) + return -1; + + memset(&addr, 0, sizeof(addr)); + TCHECK2(pptr[4], (plen + 7) / 8); + memcpy(&addr, &pptr[4], (plen + 7) / 8); + if (plen % 8) { + addr.s6_addr[(plen + 7) / 8 - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + /* the label may get offsetted by 4 bits so lets shift it right */ + snprintf(buf, buflen, "%s/%d, label:%u %s", + getname6((u_char *)&addr), + plen, + EXTRACT_24BITS(pptr+1)>>4, + ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + + return 4 + (plen + 7) / 8; + +trunc: + return -2; +} + +static int +decode_labeled_vpn_prefix6(const u_char *pptr, char *buf, u_int buflen) +{ + struct in6_addr addr; + u_int plen; + + TCHECK(pptr[0]); + plen = pptr[0]; /* get prefix length */ + + if ((24+64) > plen) + return -1; + + plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ + + if (128 < plen) + return -1; + + memset(&addr, 0, sizeof(addr)); + TCHECK2(pptr[12], (plen + 7) / 8); + memcpy(&addr, &pptr[12], (plen + 7) / 8); + if (plen % 8) { + addr.s6_addr[(plen + 7) / 8 - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + /* the label may get offsetted by 4 bits so lets shift it right */ + snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", + bgp_vpn_rd_print(pptr+4), + getname6((u_char *)&addr), + plen, + EXTRACT_24BITS(pptr+1)>>4, + ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + + return 12 + (plen + 7) / 8; + +trunc: + return -2; +} +#endif + +static int +decode_clnp_prefix(const u_char *pptr, char *buf, u_int buflen) +{ + u_int8_t addr[19]; + u_int plen; + + TCHECK(pptr[0]); + plen = pptr[0]; /* get prefix length */ + + if (152 < plen) + return -1; + + memset(&addr, 0, sizeof(addr)); + TCHECK2(pptr[4], (plen + 7) / 8); + memcpy(&addr, &pptr[4], (plen + 7) / 8); + if (plen % 8) { + addr[(plen + 7) / 8 - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + snprintf(buf, buflen, "%s/%d", + isonsap_string(addr,(plen + 7) / 8), + plen); + + return 1 + (plen + 7) / 8; + +trunc: + return -2; +} + +static int +decode_labeled_vpn_clnp_prefix(const u_char *pptr, char *buf, u_int buflen) +{ + u_int8_t addr[19]; + u_int plen; + + TCHECK(pptr[0]); + plen = pptr[0]; /* get prefix length */ + + if ((24+64) > plen) + return -1; + + plen-=(24+64); /* adjust prefixlen - labellength - RD len*/ + + if (152 < plen) + return -1; + + memset(&addr, 0, sizeof(addr)); + TCHECK2(pptr[12], (plen + 7) / 8); + memcpy(&addr, &pptr[12], (plen + 7) / 8); + if (plen % 8) { + addr[(plen + 7) / 8 - 1] &= + ((0xff00 >> (plen % 8)) & 0xff); + } + /* the label may get offsetted by 4 bits so lets shift it right */ + snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s", + bgp_vpn_rd_print(pptr+4), + isonsap_string(addr,(plen + 7) / 8), + plen, + EXTRACT_24BITS(pptr+1)>>4, + ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" ); + + return 12 + (plen + 7) / 8; + +trunc: + return -2; +} + +/* + * bgp_attr_get_as_size + * + * Try to find the size of the ASs encoded in an as-path. It is not obvious, as + * both Old speakers that do not support 4 byte AS, and the new speakers that do + * support, exchange AS-Path with the same path-attribute type value 0x02. + */ +static int +bgp_attr_get_as_size (u_int8_t bgpa_type, const u_char *pptr, int len) +{ + const u_char *tptr = pptr; + + /* + * If the path attribute is the optional AS4 path type, then we already + * know, that ASs must be encoded in 4 byte format. + */ + if (bgpa_type == BGPTYPE_AS4_PATH) { + return 4; + } + + /* + * Let us assume that ASs are of 2 bytes in size, and check if the AS-Path + * TLV is good. If not, ask the caller to try with AS encoded as 4 bytes + * each. + */ + while (tptr < pptr + len) { + TCHECK(tptr[0]); + + /* + * If we do not find a valid segment type, our guess might be wrong. + */ + if (tptr[0] < BGP_AS_SEG_TYPE_MIN || tptr[0] > BGP_AS_SEG_TYPE_MAX) { + goto trunc; + } + TCHECK(tptr[1]); + tptr += 2 + tptr[1] * 2; + } + + /* + * If we correctly reached end of the AS path attribute data content, + * then most likely ASs were indeed encoded as 2 bytes. + */ + if (tptr == pptr + len) { + return 2; + } + +trunc: + + /* + * We can come here, either we did not have enough data, or if we + * try to decode 4 byte ASs in 2 byte format. Either way, return 4, + * so that calller can try to decode each AS as of 4 bytes. If indeed + * there was not enough data, it will crib and end the parse anyways. + */ + return 4; +} + +static int +bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len) +{ + int i; + u_int16_t af; + u_int8_t safi, snpa, nhlen; + union { /* copy buffer for bandwidth values */ + float f; + u_int32_t i; + } bw; + int advance; + int tlen; + const u_char *tptr; + char buf[MAXHOSTNAMELEN + 100]; + char tokbuf[TOKBUFSIZE]; + int as_size; + + tptr = pptr; + tlen=len; + + switch (attr->bgpa_type) { + case BGPTYPE_ORIGIN: + if (len != 1) + printf("invalid len"); + else { + TCHECK(*tptr); + printf("%s", tok2strbuf(bgp_origin_values, + "Unknown Origin Typecode", + tptr[0], + tokbuf, sizeof(tokbuf))); + } + break; + + + /* + * Process AS4 byte path and AS2 byte path attributes here. + */ + case BGPTYPE_AS4_PATH: + case BGPTYPE_AS_PATH: + if (len % 2) { + printf("invalid len"); + break; + } + if (!len) { + printf("empty"); + break; + } + + /* + * BGP updates exchanged between New speakers that support 4 + * byte AS, ASs are always encoded in 4 bytes. There is no + * definitive way to find this, just by the packet's + * contents. So, check for packet's TLV's sanity assuming + * 2 bytes first, and it does not pass, assume that ASs are + * encoded in 4 bytes format and move on. + */ + as_size = bgp_attr_get_as_size(attr->bgpa_type, pptr, len); + + while (tptr < pptr + len) { + TCHECK(tptr[0]); + printf("%s", tok2strbuf(bgp_as_path_segment_open_values, + "?", tptr[0], + tokbuf, sizeof(tokbuf))); + for (i = 0; i < tptr[1] * as_size; i += as_size) { + TCHECK2(tptr[2 + i], as_size); + printf("%s ", + as_printf(astostr, sizeof(astostr), + as_size == 2 ? + EXTRACT_16BITS(&tptr[2 + i]) : + EXTRACT_32BITS(&tptr[2 + i]))); + } + TCHECK(tptr[0]); + printf("%s", tok2strbuf(bgp_as_path_segment_close_values, + "?", tptr[0], + tokbuf, sizeof(tokbuf))); + TCHECK(tptr[1]); + tptr += 2 + tptr[1] * as_size; + } + break; + case BGPTYPE_NEXT_HOP: + if (len != 4) + printf("invalid len"); + else { + TCHECK2(tptr[0], 4); + printf("%s", getname(tptr)); + } + break; + case BGPTYPE_MULTI_EXIT_DISC: + case BGPTYPE_LOCAL_PREF: + if (len != 4) + printf("invalid len"); + else { + TCHECK2(tptr[0], 4); + printf("%u", EXTRACT_32BITS(tptr)); + } + break; + case BGPTYPE_ATOMIC_AGGREGATE: + if (len != 0) + printf("invalid len"); + break; + case BGPTYPE_AGGREGATOR: + + /* + * Depending on the AS encoded is of 2 bytes or of 4 bytes, + * the length of this PA can be either 6 bytes or 8 bytes. + */ + if (len != 6 && len != 8) { + printf("invalid len"); + break; + } + TCHECK2(tptr[0], len); + if (len == 6) { + printf(" AS #%s, origin %s", + as_printf(astostr, sizeof(astostr), EXTRACT_16BITS(tptr)), + getname(tptr + 2)); + } else { + printf(" AS #%s, origin %s", + as_printf(astostr, sizeof(astostr), + EXTRACT_32BITS(tptr)), getname(tptr + 4)); + } + break; + case BGPTYPE_AGGREGATOR4: + if (len != 8) { + printf("invalid len"); + break; + } + TCHECK2(tptr[0], 8); + printf(" AS #%s, origin %s", + as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr)), + getname(tptr + 4)); + break; + case BGPTYPE_COMMUNITIES: + if (len % 4) { + printf("invalid len"); + break; + } + while (tlen>0) { + u_int32_t comm; + TCHECK2(tptr[0], 4); + comm = EXTRACT_32BITS(tptr); + switch (comm) { + case BGP_COMMUNITY_NO_EXPORT: + printf(" NO_EXPORT"); + break; + case BGP_COMMUNITY_NO_ADVERT: + printf(" NO_ADVERTISE"); + break; + case BGP_COMMUNITY_NO_EXPORT_SUBCONFED: + printf(" NO_EXPORT_SUBCONFED"); + break; + default: + printf("%u:%u%s", + (comm >> 16) & 0xffff, + comm & 0xffff, + (tlen>4) ? ", " : ""); + break; + } + tlen -=4; + tptr +=4; + } + break; + case BGPTYPE_ORIGINATOR_ID: + if (len != 4) { + printf("invalid len"); + break; + } + TCHECK2(tptr[0], 4); + printf("%s",getname(tptr)); + break; + case BGPTYPE_CLUSTER_LIST: + if (len % 4) { + printf("invalid len"); + break; + } + while (tlen>0) { + TCHECK2(tptr[0], 4); + printf("%s%s", + getname(tptr), + (tlen>4) ? ", " : ""); + tlen -=4; + tptr +=4; + } + break; + case BGPTYPE_MP_REACH_NLRI: + TCHECK2(tptr[0], 3); + af = EXTRACT_16BITS(tptr); + safi = tptr[2]; + + printf("\n\t AFI: %s (%u), %sSAFI: %s (%u)", + tok2strbuf(af_values, "Unknown AFI", af, + tokbuf, sizeof(tokbuf)), + af, + (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ + tok2strbuf(bgp_safi_values, "Unknown SAFI", safi, + tokbuf, sizeof(tokbuf)), + safi); + + switch(af<<8 | safi) { + case (AFNUM_INET<<8 | SAFNUM_UNICAST): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): + case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): + case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): + case (AFNUM_INET<<8 | SAFNUM_MDT): +#ifdef INET6 + case (AFNUM_INET6<<8 | SAFNUM_UNICAST): + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): +#endif + case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): + case (AFNUM_VPLS<<8 | SAFNUM_VPLS): + break; + default: + TCHECK2(tptr[0], tlen); + printf("\n\t no AFI %u / SAFI %u decoder",af,safi); + if (vflag <= 1) + print_unknown_data(tptr,"\n\t ",tlen); + goto done; + break; + } + + tptr +=3; + + TCHECK(tptr[0]); + nhlen = tptr[0]; + tlen = nhlen; + tptr++; + + if (tlen) { + printf("\n\t nexthop: "); + while (tlen > 0) { + switch(af<<8 | safi) { + case (AFNUM_INET<<8 | SAFNUM_UNICAST): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): + case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): + case (AFNUM_INET<<8 | SAFNUM_MDT): + if (tlen < (int)sizeof(struct in_addr)) { + printf("invalid len"); + tlen = 0; + } else { + TCHECK2(tptr[0], sizeof(struct in_addr)); + printf("%s",getname(tptr)); + tlen -= sizeof(struct in_addr); + tptr += sizeof(struct in_addr); + } + break; + case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): + if (tlen < (int)(sizeof(struct in_addr)+BGP_VPN_RD_LEN)) { + printf("invalid len"); + tlen = 0; + } else { + TCHECK2(tptr[0], sizeof(struct in_addr)+BGP_VPN_RD_LEN); + printf("RD: %s, %s", + bgp_vpn_rd_print(tptr), + getname(tptr+BGP_VPN_RD_LEN)); + tlen -= (sizeof(struct in_addr)+BGP_VPN_RD_LEN); + tptr += (sizeof(struct in_addr)+BGP_VPN_RD_LEN); + } + break; +#ifdef INET6 + case (AFNUM_INET6<<8 | SAFNUM_UNICAST): + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): + if (tlen < (int)sizeof(struct in6_addr)) { + printf("invalid len"); + tlen = 0; + } else { + TCHECK2(tptr[0], sizeof(struct in6_addr)); + printf("%s", getname6(tptr)); + tlen -= sizeof(struct in6_addr); + tptr += sizeof(struct in6_addr); + } + break; + case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): + if (tlen < (int)(sizeof(struct in6_addr)+BGP_VPN_RD_LEN)) { + printf("invalid len"); + tlen = 0; + } else { + TCHECK2(tptr[0], sizeof(struct in6_addr)+BGP_VPN_RD_LEN); + printf("RD: %s, %s", + bgp_vpn_rd_print(tptr), + getname6(tptr+BGP_VPN_RD_LEN)); + tlen -= (sizeof(struct in6_addr)+BGP_VPN_RD_LEN); + tptr += (sizeof(struct in6_addr)+BGP_VPN_RD_LEN); + } + break; +#endif + case (AFNUM_VPLS<<8 | SAFNUM_VPLS): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): + if (tlen < (int)sizeof(struct in_addr)) { + printf("invalid len"); + tlen = 0; + } else { + TCHECK2(tptr[0], sizeof(struct in_addr)); + printf("%s", getname(tptr)); + tlen -= (sizeof(struct in_addr)); + tptr += (sizeof(struct in_addr)); + } + break; + case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): + TCHECK2(tptr[0], tlen); + printf("%s",isonsap_string(tptr,tlen)); + tptr += tlen; + tlen = 0; + break; + + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): + if (tlen < BGP_VPN_RD_LEN+1) { + printf("invalid len"); + tlen = 0; + } else { + TCHECK2(tptr[0], tlen); + printf("RD: %s, %s", + bgp_vpn_rd_print(tptr), + isonsap_string(tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN)); + /* rfc986 mapped IPv4 address ? */ + if (EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) == 0x47000601) + printf(" = %s", getname(tptr+BGP_VPN_RD_LEN+4)); +#ifdef INET6 + /* rfc1888 mapped IPv6 address ? */ + else if (EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) == 0x350000) + printf(" = %s", getname6(tptr+BGP_VPN_RD_LEN+3)); +#endif + tptr += tlen; + tlen = 0; + } + break; + default: + TCHECK2(tptr[0], tlen); + printf("no AFI %u/SAFI %u decoder",af,safi); + if (vflag <= 1) + print_unknown_data(tptr,"\n\t ",tlen); + tptr += tlen; + tlen = 0; + goto done; + break; + } + } + } + printf(", nh-length: %u", nhlen); + tptr += tlen; + + TCHECK(tptr[0]); + snpa = tptr[0]; + tptr++; + + if (snpa) { + printf("\n\t %u SNPA", snpa); + for (/*nothing*/; snpa > 0; snpa--) { + TCHECK(tptr[0]); + printf("\n\t %d bytes", tptr[0]); + tptr += tptr[0] + 1; + } + } else { + printf(", no SNPA"); + } + + while (len - (tptr - pptr) > 0) { + switch (af<<8 | safi) { + case (AFNUM_INET<<8 | SAFNUM_UNICAST): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): + advance = decode_prefix4(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): + advance = decode_labeled_prefix4(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_prefix4(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO): + advance = decode_rt_routing_info(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */ + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN): + advance = decode_multicast_vpn(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + + case (AFNUM_INET<<8 | SAFNUM_MDT): + advance = decode_mdt_vpn_nlri(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; +#ifdef INET6 + case (AFNUM_INET6<<8 | SAFNUM_UNICAST): + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): + advance = decode_prefix6(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): + advance = decode_labeled_prefix6(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_prefix6(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; +#endif + case (AFNUM_VPLS<<8 | SAFNUM_VPLS): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_l2(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): + advance = decode_clnp_prefix(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_clnp_prefix(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + default: + TCHECK2(*tptr,tlen); + printf("\n\t no AFI %u / SAFI %u decoder",af,safi); + if (vflag <= 1) + print_unknown_data(tptr,"\n\t ",tlen); + advance = 0; + tptr = pptr + len; + break; + } + if (advance < 0) + break; + tptr += advance; + } + done: + break; + + case BGPTYPE_MP_UNREACH_NLRI: + TCHECK2(tptr[0], BGP_MP_NLRI_MINSIZE); + af = EXTRACT_16BITS(tptr); + safi = tptr[2]; + + printf("\n\t AFI: %s (%u), %sSAFI: %s (%u)", + tok2strbuf(af_values, "Unknown AFI", af, + tokbuf, sizeof(tokbuf)), + af, + (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */ + tok2strbuf(bgp_safi_values, "Unknown SAFI", safi, + tokbuf, sizeof(tokbuf)), + safi); + + if (len == BGP_MP_NLRI_MINSIZE) + printf("\n\t End-of-Rib Marker (empty NLRI)"); + + tptr += 3; + + while (len - (tptr - pptr) > 0) { + switch (af<<8 | safi) { + case (AFNUM_INET<<8 | SAFNUM_UNICAST): + case (AFNUM_INET<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST): + advance = decode_prefix4(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET<<8 | SAFNUM_LABUNICAST): + advance = decode_labeled_prefix4(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_prefix4(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; +#ifdef INET6 + case (AFNUM_INET6<<8 | SAFNUM_UNICAST): + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST): + advance = decode_prefix6(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST): + advance = decode_labeled_prefix6(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_prefix6(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; +#endif + case (AFNUM_VPLS<<8 | SAFNUM_VPLS): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_l2(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_NSAP<<8 | SAFNUM_UNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST): + advance = decode_clnp_prefix(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST): + case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST): + advance = decode_labeled_vpn_clnp_prefix(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET<<8 | SAFNUM_MDT): + advance = decode_mdt_vpn_nlri(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */ + case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN): + advance = decode_multicast_vpn(tptr, buf, sizeof(buf)); + if (advance == -1) + printf("\n\t (illegal prefix length)"); + else if (advance == -2) + goto trunc; + else + printf("\n\t %s", buf); + break; + default: + TCHECK2(*(tptr-3),tlen); + printf("no AFI %u / SAFI %u decoder",af,safi); + if (vflag <= 1) + print_unknown_data(tptr-3,"\n\t ",tlen); + advance = 0; + tptr = pptr + len; + break; + } + if (advance < 0) + break; + tptr += advance; + } + break; + case BGPTYPE_EXTD_COMMUNITIES: + if (len % 8) { + printf("invalid len"); + break; + } + while (tlen>0) { + u_int16_t extd_comm; + + TCHECK2(tptr[0], 2); + extd_comm=EXTRACT_16BITS(tptr); + + printf("\n\t %s (0x%04x), Flags [%s]", + tok2strbuf(bgp_extd_comm_subtype_values, + "unknown extd community typecode", + extd_comm, tokbuf, sizeof(tokbuf)), + extd_comm, + bittok2str(bgp_extd_comm_flag_values, "none", extd_comm)); + + TCHECK2(*(tptr+2), 6); + switch(extd_comm) { + case BGP_EXT_COM_RT_0: + case BGP_EXT_COM_RO_0: + printf(": %u:%u (= %s)", + EXTRACT_16BITS(tptr+2), + EXTRACT_32BITS(tptr+4), + getname(tptr+4)); + break; + case BGP_EXT_COM_RT_1: + case BGP_EXT_COM_RO_1: + case BGP_EXT_COM_VRF_RT_IMP: + printf(": %s:%u", + getname(tptr+2), + EXTRACT_16BITS(tptr+6)); + break; + case BGP_EXT_COM_RT_2: + case BGP_EXT_COM_RO_2: + printf(": %s:%u", + as_printf(astostr, sizeof(astostr), + EXTRACT_32BITS(tptr+2)), EXTRACT_16BITS(tptr+6)); + break; + case BGP_EXT_COM_LINKBAND: + bw.i = EXTRACT_32BITS(tptr+2); + printf(": bandwidth: %.3f Mbps", + bw.f*8/1000000); + break; + case BGP_EXT_COM_VPN_ORIGIN: + case BGP_EXT_COM_VPN_ORIGIN2: + case BGP_EXT_COM_VPN_ORIGIN3: + case BGP_EXT_COM_VPN_ORIGIN4: + case BGP_EXT_COM_OSPF_RID: + case BGP_EXT_COM_OSPF_RID2: + printf("%s", getname(tptr+2)); + break; + case BGP_EXT_COM_OSPF_RTYPE: + case BGP_EXT_COM_OSPF_RTYPE2: + printf(": area:%s, router-type:%s, metric-type:%s%s", + getname(tptr+2), + tok2strbuf(bgp_extd_comm_ospf_rtype_values, + "unknown (0x%02x)", + *(tptr+6), + tokbuf, sizeof(tokbuf)), + (*(tptr+7) & BGP_OSPF_RTYPE_METRIC_TYPE) ? "E2" : "", + ((*(tptr+6) == BGP_OSPF_RTYPE_EXT) || (*(tptr+6) == BGP_OSPF_RTYPE_NSSA)) ? "E1" : ""); + break; + case BGP_EXT_COM_L2INFO: + printf(": %s Control Flags [0x%02x]:MTU %u", + tok2strbuf(l2vpn_encaps_values, + "unknown encaps", + *(tptr+2), + tokbuf, sizeof(tokbuf)), + *(tptr+3), + EXTRACT_16BITS(tptr+4)); + break; + case BGP_EXT_COM_SOURCE_AS: + printf(": AS %u", EXTRACT_16BITS(tptr+2)); + break; + default: + TCHECK2(*tptr,8); + print_unknown_data(tptr,"\n\t ",8); + break; + } + tlen -=8; + tptr +=8; + } + break; + + case BGPTYPE_PMSI_TUNNEL: + { + u_int8_t tunnel_type, flags; + + tunnel_type = *(tptr+1); + flags = *tptr; + tlen = len; + + TCHECK2(tptr[0], 5); + printf("\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u", + tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type), + tunnel_type, + bittok2str(bgp_pmsi_flag_values, "none", flags), + EXTRACT_24BITS(tptr+2)>>4); + + tptr +=5; + tlen -= 5; + + switch (tunnel_type) { + case BGP_PMSI_TUNNEL_PIM_SM: /* fall through */ + case BGP_PMSI_TUNNEL_PIM_BIDIR: + TCHECK2(tptr[0], 8); + printf("\n\t Sender %s, P-Group %s", + ipaddr_string(tptr), + ipaddr_string(tptr+4)); + break; + + case BGP_PMSI_TUNNEL_PIM_SSM: + TCHECK2(tptr[0], 8); + printf("\n\t Root-Node %s, P-Group %s", + ipaddr_string(tptr), + ipaddr_string(tptr+4)); + break; + case BGP_PMSI_TUNNEL_INGRESS: + TCHECK2(tptr[0], 4); + printf("\n\t Tunnel-Endpoint %s", + ipaddr_string(tptr)); + break; + case BGP_PMSI_TUNNEL_LDP_P2MP: /* fall through */ + case BGP_PMSI_TUNNEL_LDP_MP2MP: + TCHECK2(tptr[0], 8); + printf("\n\t Root-Node %s, LSP-ID 0x%08x", + ipaddr_string(tptr), + EXTRACT_32BITS(tptr+4)); + break; + case BGP_PMSI_TUNNEL_RSVP_P2MP: + TCHECK2(tptr[0], 8); + printf("\n\t Extended-Tunnel-ID %s, P2MP-ID 0x%08x", + ipaddr_string(tptr), + EXTRACT_32BITS(tptr+4)); + break; + default: + if (vflag <= 1) { + print_unknown_data(tptr,"\n\t ",tlen); + } + } + break; + } + case BGPTYPE_ATTR_SET: + TCHECK2(tptr[0], 4); + printf("\n\t Origin AS: %s", + as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr))); + tptr+=4; + len -=4; + + while (len >= 2 ) { + int alen; + struct bgp_attr bgpa; + + TCHECK2(tptr[0], sizeof(bgpa)); + memcpy(&bgpa, tptr, sizeof(bgpa)); + alen = bgp_attr_len(&bgpa); + tptr += bgp_attr_off(&bgpa); + len -= bgp_attr_off(&bgpa); + + printf("\n\t %s (%u), length: %u", + tok2strbuf(bgp_attr_values, + "Unknown Attribute", bgpa.bgpa_type, + tokbuf, sizeof(tokbuf)), + bgpa.bgpa_type, + alen); + + if (bgpa.bgpa_flags) { + printf(", Flags [%s%s%s%s", + bgpa.bgpa_flags & 0x80 ? "O" : "", + bgpa.bgpa_flags & 0x40 ? "T" : "", + bgpa.bgpa_flags & 0x20 ? "P" : "", + bgpa.bgpa_flags & 0x10 ? "E" : ""); + if (bgpa.bgpa_flags & 0xf) + printf("+%x", bgpa.bgpa_flags & 0xf); + printf("]: "); + } + /* FIXME check for recursion */ + if (!bgp_attr_print(&bgpa, tptr, alen)) + return 0; + tptr += alen; + len -= alen; + } + break; + + + default: + TCHECK2(*pptr,len); + printf("\n\t no Attribute %u decoder",attr->bgpa_type); /* we have no decoder for the attribute */ + if (vflag <= 1) + print_unknown_data(pptr,"\n\t ",len); + break; + } + if (vflag > 1 && len) { /* omit zero length attributes*/ + TCHECK2(*pptr,len); + print_unknown_data(pptr,"\n\t ",len); + } + return 1; + +trunc: + return 0; +} + +static void +bgp_open_print(const u_char *dat, int length) +{ + struct bgp_open bgpo; + struct bgp_opt bgpopt; + const u_char *opt; + int i,cap_type,cap_len,tcap_len,cap_offset; + char tokbuf[TOKBUFSIZE]; + char tokbuf2[TOKBUFSIZE]; + + TCHECK2(dat[0], BGP_OPEN_SIZE); + memcpy(&bgpo, dat, BGP_OPEN_SIZE); + + printf("\n\t Version %d, ", bgpo.bgpo_version); + printf("my AS %s, ", + as_printf(astostr, sizeof(astostr), ntohs(bgpo.bgpo_myas))); + printf("Holdtime %us, ", ntohs(bgpo.bgpo_holdtime)); + printf("ID %s", getname((u_char *)&bgpo.bgpo_id)); + printf("\n\t Optional parameters, length: %u", bgpo.bgpo_optlen); + + /* some little sanity checking */ + if (length < bgpo.bgpo_optlen+BGP_OPEN_SIZE) + return; + + /* ugly! */ + opt = &((const struct bgp_open *)dat)->bgpo_optlen; + opt++; + + i = 0; + while (i < bgpo.bgpo_optlen) { + TCHECK2(opt[i], BGP_OPT_SIZE); + memcpy(&bgpopt, &opt[i], BGP_OPT_SIZE); + if (i + 2 + bgpopt.bgpopt_len > bgpo.bgpo_optlen) { + printf("\n\t Option %d, length: %u", bgpopt.bgpopt_type, bgpopt.bgpopt_len); + break; + } + + printf("\n\t Option %s (%u), length: %u", + tok2strbuf(bgp_opt_values,"Unknown", + bgpopt.bgpopt_type, + tokbuf, sizeof(tokbuf)), + bgpopt.bgpopt_type, + bgpopt.bgpopt_len); + + /* now lets decode the options we know*/ + switch(bgpopt.bgpopt_type) { + case BGP_OPT_CAP: + cap_type=opt[i+BGP_OPT_SIZE]; + cap_len=opt[i+BGP_OPT_SIZE+1]; + tcap_len=cap_len; + printf("\n\t %s (%u), length: %u", + tok2strbuf(bgp_capcode_values, "Unknown", + cap_type, tokbuf, sizeof(tokbuf)), + cap_type, + cap_len); + switch(cap_type) { + case BGP_CAPCODE_MP: + printf("\n\t\tAFI %s (%u), SAFI %s (%u)", + tok2strbuf(af_values, "Unknown", + EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+2), + tokbuf, sizeof(tokbuf)), + EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+2), + tok2strbuf(bgp_safi_values, "Unknown", + opt[i+BGP_OPT_SIZE+5], + tokbuf, sizeof(tokbuf)), + opt[i+BGP_OPT_SIZE+5]); + break; + case BGP_CAPCODE_RESTART: + printf("\n\t\tRestart Flags: [%s], Restart Time %us", + ((opt[i+BGP_OPT_SIZE+2])&0x80) ? "R" : "none", + EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+2)&0xfff); + tcap_len-=2; + cap_offset=4; + while(tcap_len>=4) { + printf("\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s", + tok2strbuf(af_values,"Unknown", + EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+cap_offset), + tokbuf, sizeof(tokbuf)), + EXTRACT_16BITS(opt+i+BGP_OPT_SIZE+cap_offset), + tok2strbuf(bgp_safi_values,"Unknown", + opt[i+BGP_OPT_SIZE+cap_offset+2], + tokbuf2, sizeof(tokbuf2)), + opt[i+BGP_OPT_SIZE+cap_offset+2], + ((opt[i+BGP_OPT_SIZE+cap_offset+3])&0x80) ? "yes" : "no" ); + tcap_len-=4; + cap_offset+=4; + } + break; + case BGP_CAPCODE_RR: + case BGP_CAPCODE_RR_CISCO: + break; + case BGP_CAPCODE_AS_NEW: + + /* + * Extract the 4 byte AS number encoded. + */ + TCHECK2(opt[i + BGP_OPT_SIZE + 2], cap_len); + if (cap_len == 4) { + printf("\n\t\t 4 Byte AS %s", + as_printf(astostr, sizeof(astostr), + EXTRACT_32BITS(opt + i + BGP_OPT_SIZE + 2))); + } + break; + default: + TCHECK2(opt[i+BGP_OPT_SIZE+2],cap_len); + printf("\n\t\tno decoder for Capability %u", + cap_type); + if (vflag <= 1) + print_unknown_data(&opt[i+BGP_OPT_SIZE+2],"\n\t\t",cap_len); + break; + } + if (vflag > 1) { + TCHECK2(opt[i+BGP_OPT_SIZE+2],cap_len); + print_unknown_data(&opt[i+BGP_OPT_SIZE+2],"\n\t\t",cap_len); + } + break; + case BGP_OPT_AUTH: + default: + printf("\n\t no decoder for option %u", + bgpopt.bgpopt_type); + break; + } + + i += BGP_OPT_SIZE + bgpopt.bgpopt_len; + } + return; +trunc: + printf("[|BGP]"); +} + +static void +bgp_update_print(const u_char *dat, int length) +{ + struct bgp bgp; + struct bgp_attr bgpa; + const u_char *p; + int len; + int i; + char tokbuf[TOKBUFSIZE]; + + TCHECK2(dat[0], BGP_SIZE); + memcpy(&bgp, dat, BGP_SIZE); + p = dat + BGP_SIZE; /*XXX*/ + + /* Unfeasible routes */ + len = EXTRACT_16BITS(p); + if (len) { + /* + * Without keeping state from the original NLRI message, + * it's not possible to tell if this a v4 or v6 route, + * so only try to decode it if we're not v6 enabled. + */ +#ifdef INET6 + printf("\n\t Withdrawn routes: %d bytes", len); +#else + char buf[MAXHOSTNAMELEN + 100]; + int wpfx; + + TCHECK2(p[2], len); + i = 2; + + printf("\n\t Withdrawn routes:"); + + while(i < 2 + len) { + wpfx = decode_prefix4(&p[i], buf, sizeof(buf)); + if (wpfx == -1) { + printf("\n\t (illegal prefix length)"); + break; + } else if (wpfx == -2) + goto trunc; + else { + i += wpfx; + printf("\n\t %s", buf); + } + } +#endif + } + p += 2 + len; + + TCHECK2(p[0], 2); + len = EXTRACT_16BITS(p); + + if (len == 0 && length == BGP_UPDATE_MINSIZE) { + printf("\n\t End-of-Rib Marker (empty NLRI)"); + return; + } + + if (len) { + /* do something more useful!*/ + i = 2; + while (i < 2 + len) { + int alen, aoff; + + TCHECK2(p[i], sizeof(bgpa)); + memcpy(&bgpa, &p[i], sizeof(bgpa)); + alen = bgp_attr_len(&bgpa); + aoff = bgp_attr_off(&bgpa); + + printf("\n\t %s (%u), length: %u", + tok2strbuf(bgp_attr_values, "Unknown Attribute", + bgpa.bgpa_type, + tokbuf, sizeof(tokbuf)), + bgpa.bgpa_type, + alen); + + if (bgpa.bgpa_flags) { + printf(", Flags [%s%s%s%s", + bgpa.bgpa_flags & 0x80 ? "O" : "", + bgpa.bgpa_flags & 0x40 ? "T" : "", + bgpa.bgpa_flags & 0x20 ? "P" : "", + bgpa.bgpa_flags & 0x10 ? "E" : ""); + if (bgpa.bgpa_flags & 0xf) + printf("+%x", bgpa.bgpa_flags & 0xf); + printf("]: "); + } + if (!bgp_attr_print(&bgpa, &p[i + aoff], alen)) + goto trunc; + i += aoff + alen; + } + } + p += 2 + len; + + if (dat + length > p) { + printf("\n\t Updated routes:"); + while (dat + length > p) { + char buf[MAXHOSTNAMELEN + 100]; + i = decode_prefix4(p, buf, sizeof(buf)); + if (i == -1) { + printf("\n\t (illegal prefix length)"); + break; + } else if (i == -2) + goto trunc; + else { + printf("\n\t %s", buf); + p += i; + } + } + } + return; +trunc: + printf("[|BGP]"); +} + +static void +bgp_notification_print(const u_char *dat, int length) +{ + struct bgp_notification bgpn; + const u_char *tptr; + char tokbuf[TOKBUFSIZE]; + char tokbuf2[TOKBUFSIZE]; + + TCHECK2(dat[0], BGP_NOTIFICATION_SIZE); + memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE); + + /* some little sanity checking */ + if (length= BGP_NOTIFICATION_SIZE + 7) { + tptr = dat + BGP_NOTIFICATION_SIZE; + TCHECK2(*tptr, 7); + printf(", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u", + tok2strbuf(af_values, "Unknown", + EXTRACT_16BITS(tptr), tokbuf, sizeof(tokbuf)), + EXTRACT_16BITS(tptr), + tok2strbuf(bgp_safi_values, "Unknown", *(tptr+2), + tokbuf2, sizeof(tokbuf)), + *(tptr+2), + EXTRACT_32BITS(tptr+3)); + } + break; + default: + break; + } + + return; +trunc: + printf("[|BGP]"); +} + +static void +bgp_route_refresh_print(const u_char *pptr, int len) { + + const struct bgp_route_refresh *bgp_route_refresh_header; + char tokbuf[TOKBUFSIZE]; + char tokbuf2[TOKBUFSIZE]; + + TCHECK2(pptr[0], BGP_ROUTE_REFRESH_SIZE); + + /* some little sanity checking */ + if (lenafi), + tokbuf, sizeof(tokbuf)), + EXTRACT_16BITS(&bgp_route_refresh_header->afi), + tok2strbuf(bgp_safi_values,"Unknown", + bgp_route_refresh_header->safi, + tokbuf2, sizeof(tokbuf2)), + bgp_route_refresh_header->safi); + + if (vflag > 1) { + TCHECK2(*pptr, len); + print_unknown_data(pptr,"\n\t ", len); + } + + return; +trunc: + printf("[|BGP]"); +} + +static int +bgp_header_print(const u_char *dat, int length) +{ + struct bgp bgp; + char tokbuf[TOKBUFSIZE]; + + TCHECK2(dat[0], BGP_SIZE); + memcpy(&bgp, dat, BGP_SIZE); + printf("\n\t%s Message (%u), length: %u", + tok2strbuf(bgp_msg_values, "Unknown", bgp.bgp_type, + tokbuf, sizeof(tokbuf)), + bgp.bgp_type, + length); + + switch (bgp.bgp_type) { + case BGP_OPEN: + bgp_open_print(dat, length); + break; + case BGP_UPDATE: + bgp_update_print(dat, length); + break; + case BGP_NOTIFICATION: + bgp_notification_print(dat, length); + break; + case BGP_KEEPALIVE: + break; + case BGP_ROUTE_REFRESH: + bgp_route_refresh_print(dat, length); + break; + default: + /* we have no decoder for the BGP message */ + TCHECK2(*dat, length); + printf("\n\t no Message %u decoder",bgp.bgp_type); + print_unknown_data(dat,"\n\t ",length); + break; + } + return 1; +trunc: + printf("[|BGP]"); + return 0; +} + +void +bgp_print(const u_char *dat, int length) +{ + const u_char *p; + const u_char *ep; + const u_char *start; + const u_char marker[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + }; + struct bgp bgp; + u_int16_t hlen; + char tokbuf[TOKBUFSIZE]; + + ep = dat + length; + if (snapend < dat + length) + ep = snapend; + + printf(": BGP, length: %u",length); + + if (vflag < 1) /* lets be less chatty */ + return; + + p = dat; + start = p; + while (p < ep) { + if (!TTEST2(p[0], 1)) + break; + if (p[0] != 0xff) { + p++; + continue; + } + + if (!TTEST2(p[0], sizeof(marker))) + break; + if (memcmp(p, marker, sizeof(marker)) != 0) { + p++; + continue; + } + + /* found BGP header */ + TCHECK2(p[0], BGP_SIZE); /*XXX*/ + memcpy(&bgp, p, BGP_SIZE); + + if (start != p) + printf(" [|BGP]"); + + hlen = ntohs(bgp.bgp_len); + if (hlen < BGP_SIZE) { + printf("\n[|BGP Bogus header length %u < %u]", hlen, + BGP_SIZE); + break; + } + + if (TTEST2(p[0], hlen)) { + if (!bgp_header_print(p, hlen)) + return; + p += hlen; + start = p; + } else { + printf("\n[|BGP %s]", + tok2strbuf(bgp_msg_values, + "Unknown Message Type", + bgp.bgp_type, + tokbuf, sizeof(tokbuf))); + break; + } + } + + return; + +trunc: + printf(" [|BGP]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/print-bootp.c b/print-bootp.c new file mode 100644 index 0000000..c7538ff --- /dev/null +++ b/print-bootp.c @@ -0,0 +1,825 @@ +/* + * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Format and print bootp packets. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-bootp.c,v 1.89 2008-04-22 09:45:08 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "ether.h" +#include "bootp.h" + +static void rfc1048_print(const u_char *); +static void cmu_print(const u_char *); +static char *client_fqdn_flags(u_int flags); + +static char tstr[] = " [|bootp]"; + +static const struct tok bootp_flag_values[] = { + { 0x8000, "Broadcast" }, + { 0, NULL} +}; + +static const struct tok bootp_op_values[] = { + { BOOTPREQUEST, "Request" }, + { BOOTPREPLY, "Reply" }, + { 0, NULL} +}; + +/* + * Print bootp requests + */ +void +bootp_print(register const u_char *cp, u_int length) +{ + register const struct bootp *bp; + static const u_char vm_cmu[4] = VM_CMU; + static const u_char vm_rfc1048[4] = VM_RFC1048; + + bp = (const struct bootp *)cp; + TCHECK(bp->bp_op); + + printf("BOOTP/DHCP, %s", + tok2str(bootp_op_values, "unknown (0x%02x)", bp->bp_op)); + + if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) { + TCHECK2(bp->bp_chaddr[0], 6); + printf(" from %s", etheraddr_string(bp->bp_chaddr)); + } + + printf(", length %u", length); + + if (!vflag) + return; + + TCHECK(bp->bp_secs); + + /* The usual hardware address type is 1 (10Mb Ethernet) */ + if (bp->bp_htype != 1) + printf(", htype %d", bp->bp_htype); + + /* The usual length for 10Mb Ethernet address is 6 bytes */ + if (bp->bp_htype != 1 || bp->bp_hlen != 6) + printf(", hlen %d", bp->bp_hlen); + + /* Only print interesting fields */ + if (bp->bp_hops) + printf(", hops %d", bp->bp_hops); + if (bp->bp_xid) + printf(", xid 0x%x", EXTRACT_32BITS(&bp->bp_xid)); + if (bp->bp_secs) + printf(", secs %d", EXTRACT_16BITS(&bp->bp_secs)); + + printf(", Flags [%s]", + bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags))); + if (vflag > 1) + printf(" (0x%04x)", EXTRACT_16BITS(&bp->bp_flags)); + + /* Client's ip address */ + TCHECK(bp->bp_ciaddr); + if (bp->bp_ciaddr.s_addr) + printf("\n\t Client-IP %s", ipaddr_string(&bp->bp_ciaddr)); + + /* 'your' ip address (bootp client) */ + TCHECK(bp->bp_yiaddr); + if (bp->bp_yiaddr.s_addr) + printf("\n\t Your-IP %s", ipaddr_string(&bp->bp_yiaddr)); + + /* Server's ip address */ + TCHECK(bp->bp_siaddr); + if (bp->bp_siaddr.s_addr) + printf("\n\t Server-IP %s", ipaddr_string(&bp->bp_siaddr)); + + /* Gateway's ip address */ + TCHECK(bp->bp_giaddr); + if (bp->bp_giaddr.s_addr) + printf("\n\t Gateway-IP %s", ipaddr_string(&bp->bp_giaddr)); + + /* Client's Ethernet address */ + if (bp->bp_htype == 1 && bp->bp_hlen == 6) { + TCHECK2(bp->bp_chaddr[0], 6); + printf("\n\t Client-Ethernet-Address %s", etheraddr_string(bp->bp_chaddr)); + } + + TCHECK2(bp->bp_sname[0], 1); /* check first char only */ + if (*bp->bp_sname) { + printf("\n\t sname \""); + if (fn_print(bp->bp_sname, snapend)) { + putchar('"'); + fputs(tstr + 1, stdout); + return; + } + putchar('"'); + } + TCHECK2(bp->bp_file[0], 1); /* check first char only */ + if (*bp->bp_file) { + printf("\n\t file \""); + if (fn_print(bp->bp_file, snapend)) { + putchar('"'); + fputs(tstr + 1, stdout); + return; + } + putchar('"'); + } + + /* Decode the vendor buffer */ + TCHECK(bp->bp_vend[0]); + if (memcmp((const char *)bp->bp_vend, vm_rfc1048, + sizeof(u_int32_t)) == 0) + rfc1048_print(bp->bp_vend); + else if (memcmp((const char *)bp->bp_vend, vm_cmu, + sizeof(u_int32_t)) == 0) + cmu_print(bp->bp_vend); + else { + u_int32_t ul; + + ul = EXTRACT_32BITS(&bp->bp_vend); + if (ul != 0) + printf("\n\t Vendor-#0x%x", ul); + } + + return; +trunc: + fputs(tstr, stdout); +} + +/* + * The first character specifies the format to print: + * i - ip address (32 bits) + * p - ip address pairs (32 bits + 32 bits) + * l - long (32 bits) + * L - unsigned long (32 bits) + * s - short (16 bits) + * b - period-seperated decimal bytes (variable length) + * x - colon-seperated hex bytes (variable length) + * a - ascii string (variable length) + * B - on/off (8 bits) + * $ - special (explicit code to handle) + */ +static struct tok tag2str[] = { +/* RFC1048 tags */ + { TAG_PAD, " PAD" }, + { TAG_SUBNET_MASK, "iSubnet-Mask" }, /* subnet mask (RFC950) */ + { TAG_TIME_OFFSET, "LTime-Zone" }, /* seconds from UTC */ + { TAG_GATEWAY, "iDefault-Gateway" }, /* default gateway */ + { TAG_TIME_SERVER, "iTime-Server" }, /* time servers (RFC868) */ + { TAG_NAME_SERVER, "iIEN-Name-Server" }, /* IEN name servers (IEN116) */ + { TAG_DOMAIN_SERVER, "iDomain-Name-Server" }, /* domain name (RFC1035) */ + { TAG_LOG_SERVER, "iLOG" }, /* MIT log servers */ + { TAG_COOKIE_SERVER, "iCS" }, /* cookie servers (RFC865) */ + { TAG_LPR_SERVER, "iLPR-Server" }, /* lpr server (RFC1179) */ + { TAG_IMPRESS_SERVER, "iIM" }, /* impress servers (Imagen) */ + { TAG_RLP_SERVER, "iRL" }, /* resource location (RFC887) */ + { TAG_HOSTNAME, "aHostname" }, /* ascii hostname */ + { TAG_BOOTSIZE, "sBS" }, /* 512 byte blocks */ + { TAG_END, " END" }, +/* RFC1497 tags */ + { TAG_DUMPPATH, "aDP" }, + { TAG_DOMAINNAME, "aDomain-Name" }, + { TAG_SWAP_SERVER, "iSS" }, + { TAG_ROOTPATH, "aRP" }, + { TAG_EXTPATH, "aEP" }, +/* RFC2132 tags */ + { TAG_IP_FORWARD, "BIPF" }, + { TAG_NL_SRCRT, "BSRT" }, + { TAG_PFILTERS, "pPF" }, + { TAG_REASS_SIZE, "sRSZ" }, + { TAG_DEF_TTL, "bTTL" }, + { TAG_MTU_TIMEOUT, "lMTU-Timeout" }, + { TAG_MTU_TABLE, "sMTU-Table" }, + { TAG_INT_MTU, "sMTU" }, + { TAG_LOCAL_SUBNETS, "BLSN" }, + { TAG_BROAD_ADDR, "iBR" }, + { TAG_DO_MASK_DISC, "BMD" }, + { TAG_SUPPLY_MASK, "BMS" }, + { TAG_DO_RDISC, "BRouter-Discovery" }, + { TAG_RTR_SOL_ADDR, "iRSA" }, + { TAG_STATIC_ROUTE, "pStatic-Route" }, + { TAG_USE_TRAILERS, "BUT" }, + { TAG_ARP_TIMEOUT, "lAT" }, + { TAG_ETH_ENCAP, "BIE" }, + { TAG_TCP_TTL, "bTT" }, + { TAG_TCP_KEEPALIVE, "lKI" }, + { TAG_KEEPALIVE_GO, "BKG" }, + { TAG_NIS_DOMAIN, "aYD" }, + { TAG_NIS_SERVERS, "iYS" }, + { TAG_NTP_SERVERS, "iNTP" }, + { TAG_VENDOR_OPTS, "bVendor-Option" }, + { TAG_NETBIOS_NS, "iNetbios-Name-Server" }, + { TAG_NETBIOS_DDS, "iWDD" }, + { TAG_NETBIOS_NODE, "$Netbios-Node" }, + { TAG_NETBIOS_SCOPE, "aNetbios-Scope" }, + { TAG_XWIN_FS, "iXFS" }, + { TAG_XWIN_DM, "iXDM" }, + { TAG_NIS_P_DOMAIN, "sN+D" }, + { TAG_NIS_P_SERVERS, "iN+S" }, + { TAG_MOBILE_HOME, "iMH" }, + { TAG_SMPT_SERVER, "iSMTP" }, + { TAG_POP3_SERVER, "iPOP3" }, + { TAG_NNTP_SERVER, "iNNTP" }, + { TAG_WWW_SERVER, "iWWW" }, + { TAG_FINGER_SERVER, "iFG" }, + { TAG_IRC_SERVER, "iIRC" }, + { TAG_STREETTALK_SRVR, "iSTS" }, + { TAG_STREETTALK_STDA, "iSTDA" }, + { TAG_REQUESTED_IP, "iRequested-IP" }, + { TAG_IP_LEASE, "lLease-Time" }, + { TAG_OPT_OVERLOAD, "$OO" }, + { TAG_TFTP_SERVER, "aTFTP" }, + { TAG_BOOTFILENAME, "aBF" }, + { TAG_DHCP_MESSAGE, " DHCP-Message" }, + { TAG_SERVER_ID, "iServer-ID" }, + { TAG_PARM_REQUEST, "bParameter-Request" }, + { TAG_MESSAGE, "aMSG" }, + { TAG_MAX_MSG_SIZE, "sMSZ" }, + { TAG_RENEWAL_TIME, "lRN" }, + { TAG_REBIND_TIME, "lRB" }, + { TAG_VENDOR_CLASS, "aVendor-Class" }, + { TAG_CLIENT_ID, "$Client-ID" }, +/* RFC 2485 */ + { TAG_OPEN_GROUP_UAP, "aUAP" }, +/* RFC 2563 */ + { TAG_DISABLE_AUTOCONF, "BNOAUTO" }, +/* RFC 2610 */ + { TAG_SLP_DA, "bSLP-DA" }, /*"b" is a little wrong */ + { TAG_SLP_SCOPE, "bSLP-SCOPE" }, /*"b" is a little wrong */ +/* RFC 2937 */ + { TAG_NS_SEARCH, "sNSSEARCH" }, /* XXX 's' */ +/* RFC 3011 */ + { TAG_IP4_SUBNET_SELECT, "iSUBNET" }, +/* RFC 3442 */ + { TAG_CLASSLESS_STATIC_RT, "$Classless-Static-Route" }, + { TAG_CLASSLESS_STA_RT_MS, "$Classless-Static-Route-Microsoft" }, +/* http://www.iana.org/assignments/bootp-dhcp-extensions/index.htm */ + { TAG_USER_CLASS, "aCLASS" }, + { TAG_SLP_NAMING_AUTH, "aSLP-NA" }, + { TAG_CLIENT_FQDN, "$FQDN" }, + { TAG_AGENT_CIRCUIT, "$Agent-Information" }, + { TAG_AGENT_REMOTE, "bARMT" }, + { TAG_AGENT_MASK, "bAMSK" }, + { TAG_TZ_STRING, "aTZSTR" }, + { TAG_FQDN_OPTION, "bFQDNS" }, /* XXX 'b' */ + { TAG_AUTH, "bAUTH" }, /* XXX 'b' */ + { TAG_VINES_SERVERS, "iVINES" }, + { TAG_SERVER_RANK, "sRANK" }, + { TAG_CLIENT_ARCH, "sARCH" }, + { TAG_CLIENT_NDI, "bNDI" }, /* XXX 'b' */ + { TAG_CLIENT_GUID, "bGUID" }, /* XXX 'b' */ + { TAG_LDAP_URL, "aLDAP" }, + { TAG_6OVER4, "i6o4" }, + { TAG_PRINTER_NAME, "aPRTR" }, + { TAG_MDHCP_SERVER, "bMDHCP" }, /* XXX 'b' */ + { TAG_IPX_COMPAT, "bIPX" }, /* XXX 'b' */ + { TAG_NETINFO_PARENT, "iNI" }, + { TAG_NETINFO_PARENT_TAG, "aNITAG" }, + { TAG_URL, "aURL" }, + { TAG_FAILOVER, "bFAIL" }, /* XXX 'b' */ + { 0, NULL } +}; +/* 2-byte extended tags */ +static struct tok xtag2str[] = { + { 0, NULL } +}; + +/* DHCP "options overload" types */ +static struct tok oo2str[] = { + { 1, "file" }, + { 2, "sname" }, + { 3, "file+sname" }, + { 0, NULL } +}; + +/* NETBIOS over TCP/IP node type options */ +static struct tok nbo2str[] = { + { 0x1, "b-node" }, + { 0x2, "p-node" }, + { 0x4, "m-node" }, + { 0x8, "h-node" }, + { 0, NULL } +}; + +/* ARP Hardware types, for Client-ID option */ +static struct tok arp2str[] = { + { 0x1, "ether" }, + { 0x6, "ieee802" }, + { 0x7, "arcnet" }, + { 0xf, "frelay" }, + { 0x17, "strip" }, + { 0x18, "ieee1394" }, + { 0, NULL } +}; + +static struct tok dhcp_msg_values[] = { + { DHCPDISCOVER, "Discover" }, + { DHCPOFFER, "Offer" }, + { DHCPREQUEST, "Request" }, + { DHCPDECLINE, "Decline" }, + { DHCPACK, "ACK" }, + { DHCPNAK, "NACK" }, + { DHCPRELEASE, "Release" }, + { DHCPINFORM, "Inform" }, + { 0, NULL } +}; + +#define AGENT_SUBOPTION_CIRCUIT_ID 1 /* RFC 3046 */ +#define AGENT_SUBOPTION_REMOTE_ID 2 /* RFC 3046 */ +#define AGENT_SUBOPTION_SUBSCRIBER_ID 6 /* RFC 3993 */ +static struct tok agent_suboption_values[] = { + { AGENT_SUBOPTION_CIRCUIT_ID, "Circuit-ID" }, + { AGENT_SUBOPTION_REMOTE_ID, "Remote-ID" }, + { AGENT_SUBOPTION_SUBSCRIBER_ID, "Subscriber-ID" }, + { 0, NULL } +}; + + +static void +rfc1048_print(register const u_char *bp) +{ + register u_int16_t tag; + register u_int len; + register const char *cp; + register char c; + int first, idx; + u_int32_t ul; + u_int16_t us; + u_int8_t uc, subopt, suboptlen; + + printf("\n\t Vendor-rfc1048 Extensions"); + + /* Step over magic cookie */ + printf("\n\t Magic Cookie 0x%08x", EXTRACT_32BITS(bp)); + bp += sizeof(int32_t); + + /* Loop while we there is a tag left in the buffer */ + while (TTEST2(*bp, 1)) { + tag = *bp++; + if (tag == TAG_PAD && vflag < 3) + continue; + if (tag == TAG_END && vflag < 3) + return; + if (tag == TAG_EXTENDED_OPTION) { + TCHECK2(*(bp + 1), 2); + tag = EXTRACT_16BITS(bp + 1); + /* XXX we don't know yet if the IANA will + * preclude overlap of 1-byte and 2-byte spaces. + * If not, we need to offset tag after this step. + */ + cp = tok2str(xtag2str, "?xT%u", tag); + } else + cp = tok2str(tag2str, "?T%u", tag); + c = *cp++; + + if (tag == TAG_PAD || tag == TAG_END) + len = 0; + else { + /* Get the length; check for truncation */ + TCHECK2(*bp, 1); + len = *bp++; + } + + printf("\n\t %s Option %u, length %u%s", cp, tag, len, + len > 0 ? ": " : ""); + + if (tag == TAG_PAD && vflag > 2) { + u_int ntag = 1; + while (TTEST2(*bp, 1) && *bp == TAG_PAD) { + bp++; + ntag++; + } + if (ntag > 1) + printf(", occurs %u", ntag); + } + + if (!TTEST2(*bp, len)) { + printf("[|rfc1048 %u]", len); + return; + } + + if (tag == TAG_DHCP_MESSAGE && len == 1) { + uc = *bp++; + printf("%s", tok2str(dhcp_msg_values, "Unknown (%u)", uc)); + continue; + } + + if (tag == TAG_PARM_REQUEST) { + idx = 0; + while (len-- > 0) { + uc = *bp++; + cp = tok2str(tag2str, "?Option %u", uc); + if (idx % 4 == 0) + printf("\n\t "); + else + printf(", "); + printf("%s", cp + 1); + idx++; + } + continue; + } + + if (tag == TAG_EXTENDED_REQUEST) { + first = 1; + while (len > 1) { + len -= 2; + us = EXTRACT_16BITS(bp); + bp += 2; + cp = tok2str(xtag2str, "?xT%u", us); + if (!first) + putchar('+'); + printf("%s", cp + 1); + first = 0; + } + continue; + } + + /* Print data */ + if (c == '?') { + /* Base default formats for unknown tags on data size */ + if (len & 1) + c = 'b'; + else if (len & 2) + c = 's'; + else + c = 'l'; + } + first = 1; + switch (c) { + + case 'a': + /* ascii strings */ + putchar('"'); + if (fn_printn(bp, len, snapend)) { + putchar('"'); + goto trunc; + } + putchar('"'); + bp += len; + len = 0; + break; + + case 'i': + case 'l': + case 'L': + /* ip addresses/32-bit words */ + while (len >= sizeof(ul)) { + if (!first) + putchar(','); + ul = EXTRACT_32BITS(bp); + if (c == 'i') { + ul = htonl(ul); + printf("%s", ipaddr_string(&ul)); + } else if (c == 'L') + printf("%d", ul); + else + printf("%u", ul); + bp += sizeof(ul); + len -= sizeof(ul); + first = 0; + } + break; + + case 'p': + /* IP address pairs */ + while (len >= 2*sizeof(ul)) { + if (!first) + putchar(','); + memcpy((char *)&ul, (const char *)bp, sizeof(ul)); + printf("(%s:", ipaddr_string(&ul)); + bp += sizeof(ul); + memcpy((char *)&ul, (const char *)bp, sizeof(ul)); + printf("%s)", ipaddr_string(&ul)); + bp += sizeof(ul); + len -= 2*sizeof(ul); + first = 0; + } + break; + + case 's': + /* shorts */ + while (len >= sizeof(us)) { + if (!first) + putchar(','); + us = EXTRACT_16BITS(bp); + printf("%u", us); + bp += sizeof(us); + len -= sizeof(us); + first = 0; + } + break; + + case 'B': + /* boolean */ + while (len > 0) { + if (!first) + putchar(','); + switch (*bp) { + case 0: + putchar('N'); + break; + case 1: + putchar('Y'); + break; + default: + printf("%u?", *bp); + break; + } + ++bp; + --len; + first = 0; + } + break; + + case 'b': + case 'x': + default: + /* Bytes */ + while (len > 0) { + if (!first) + putchar(c == 'x' ? ':' : '.'); + if (c == 'x') + printf("%02x", *bp); + else + printf("%u", *bp); + ++bp; + --len; + first = 0; + } + break; + + case '$': + /* Guys we can't handle with one of the usual cases */ + switch (tag) { + + case TAG_NETBIOS_NODE: + /* this option should be at least 1 byte long */ + if (len < 1) { + printf("ERROR: option %u len %u < 1 bytes", + TAG_NETBIOS_NODE, len); + break; + } + tag = *bp++; + --len; + fputs(tok2str(nbo2str, NULL, tag), stdout); + break; + + case TAG_OPT_OVERLOAD: + /* this option should be at least 1 byte long */ + if (len < 1) { + printf("ERROR: option %u len %u < 1 bytes", + TAG_OPT_OVERLOAD, len); + break; + } + tag = *bp++; + --len; + fputs(tok2str(oo2str, NULL, tag), stdout); + break; + + case TAG_CLIENT_FQDN: + /* this option should be at least 3 bytes long */ + if (len < 3) { + printf("ERROR: option %u len %u < 3 bytes", + TAG_CLIENT_FQDN, len); + bp += len; + len = 0; + break; + } + if (*bp) + printf("[%s] ", client_fqdn_flags(*bp)); + bp++; + if (*bp || *(bp+1)) + printf("%u/%u ", *bp, *(bp+1)); + bp += 2; + putchar('"'); + if (fn_printn(bp, len - 3, snapend)) { + putchar('"'); + goto trunc; + } + putchar('"'); + bp += len - 3; + len = 0; + break; + + case TAG_CLIENT_ID: + { int type; + + /* this option should be at least 1 byte long */ + if (len < 1) { + printf("ERROR: option %u len %u < 1 bytes", + TAG_CLIENT_ID, len); + break; + } + type = *bp++; + len--; + if (type == 0) { + putchar('"'); + if (fn_printn(bp, len, snapend)) { + putchar('"'); + goto trunc; + } + putchar('"'); + bp += len; + len = 0; + break; + } else { + printf("%s ", tok2str(arp2str, "hardware-type %u,", type)); + while (len > 0) { + if (!first) + putchar(':'); + printf("%02x", *bp); + ++bp; + --len; + first = 0; + } + } + break; + } + + case TAG_AGENT_CIRCUIT: + while (len >= 2) { + subopt = *bp++; + suboptlen = *bp++; + len -= 2; + if (suboptlen > len) { + printf("\n\t %s SubOption %u, length %u: length goes past end of option", + tok2str(agent_suboption_values, "Unknown", subopt), + subopt, + suboptlen); + bp += len; + len = 0; + break; + } + printf("\n\t %s SubOption %u, length %u: ", + tok2str(agent_suboption_values, "Unknown", subopt), + subopt, + suboptlen); + switch (subopt) { + + case AGENT_SUBOPTION_CIRCUIT_ID: /* fall through */ + case AGENT_SUBOPTION_REMOTE_ID: + case AGENT_SUBOPTION_SUBSCRIBER_ID: + fn_printn(bp, suboptlen, NULL); + break; + + default: + print_unknown_data(bp, "\n\t\t", suboptlen); + } + + len -= suboptlen; + bp += suboptlen; + } + break; + + case TAG_CLASSLESS_STATIC_RT: + case TAG_CLASSLESS_STA_RT_MS: + { + u_int mask_width, significant_octets, i; + + /* this option should be at least 5 bytes long */ + if (len < 5) { + printf("ERROR: option %u len %u < 5 bytes", + TAG_CLASSLESS_STATIC_RT, len); + bp += len; + len = 0; + break; + } + while (len > 0) { + if (!first) + putchar(','); + mask_width = *bp++; + len--; + /* mask_width <= 32 */ + if (mask_width > 32) { + printf("[ERROR: Mask width (%d) > 32]", mask_width); + bp += len; + len = 0; + break; + } + significant_octets = (mask_width + 7) / 8; + /* significant octets + router(4) */ + if (len < significant_octets + 4) { + printf("[ERROR: Remaining length (%u) < %u bytes]", len, significant_octets + 4); + bp += len; + len = 0; + break; + } + putchar('('); + if (mask_width == 0) + printf("default"); + else { + for (i = 0; i < significant_octets ; i++) { + if (i > 0) + putchar('.'); + printf("%d", *bp++); + } + for (i = significant_octets ; i < 4 ; i++) + printf(".0"); + printf("/%d", mask_width); + } + memcpy((char *)&ul, (const char *)bp, sizeof(ul)); + printf(":%s)", ipaddr_string(&ul)); + bp += sizeof(ul); + len -= (significant_octets + 4); + first = 0; + } + } + break; + + default: + printf("[unknown special tag %u, size %u]", + tag, len); + bp += len; + len = 0; + break; + } + break; + } + /* Data left over? */ + if (len) { + printf("\n\t trailing data length %u", len); + bp += len; + } + } + return; +trunc: + printf("|[rfc1048]"); +} + +static void +cmu_print(register const u_char *bp) +{ + register const struct cmu_vend *cmu; + +#define PRINTCMUADDR(m, s) { TCHECK(cmu->m); \ + if (cmu->m.s_addr != 0) \ + printf(" %s:%s", s, ipaddr_string(&cmu->m.s_addr)); } + + printf(" vend-cmu"); + cmu = (const struct cmu_vend *)bp; + + /* Only print if there are unknown bits */ + TCHECK(cmu->v_flags); + if ((cmu->v_flags & ~(VF_SMASK)) != 0) + printf(" F:0x%x", cmu->v_flags); + PRINTCMUADDR(v_dgate, "DG"); + PRINTCMUADDR(v_smask, cmu->v_flags & VF_SMASK ? "SM" : "SM*"); + PRINTCMUADDR(v_dns1, "NS1"); + PRINTCMUADDR(v_dns2, "NS2"); + PRINTCMUADDR(v_ins1, "IEN1"); + PRINTCMUADDR(v_ins2, "IEN2"); + PRINTCMUADDR(v_ts1, "TS1"); + PRINTCMUADDR(v_ts2, "TS2"); + return; + +trunc: + fputs(tstr, stdout); +#undef PRINTCMUADDR +} + +static char * +client_fqdn_flags(u_int flags) +{ + static char buf[8+1]; + int i = 0; + + if (flags & CLIENT_FQDN_FLAGS_S) + buf[i++] = 'S'; + if (flags & CLIENT_FQDN_FLAGS_O) + buf[i++] = 'O'; + if (flags & CLIENT_FQDN_FLAGS_E) + buf[i++] = 'E'; + if (flags & CLIENT_FQDN_FLAGS_N) + buf[i++] = 'N'; + buf[i] = '\0'; + + return buf; +} diff --git a/print-bt.c b/print-bt.c new file mode 100644 index 0000000..259f3e5 --- /dev/null +++ b/print-bt.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2007 + * paolo.abeni@email.it All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by Paolo Abeni.'' + * The name of author may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-bt.c,v 1.2 2008-09-25 21:45:50 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +#if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H) +#include + +#define BT_HDRLEN sizeof(pcap_bluetooth_h4_header) +/* + * This is the top level routine of the printer. 'p' points + * to the bluetooth header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +bt_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int length = h->len; + u_int caplen = h->caplen; + const pcap_bluetooth_h4_header* hdr = (const pcap_bluetooth_h4_header*)p; + + if (caplen < BT_HDRLEN) { + printf("[|bt]"); + return (BT_HDRLEN); + } + caplen -= BT_HDRLEN; + length -= BT_HDRLEN; + p += BT_HDRLEN; + if (eflag) + (void)printf("hci length %d, direction %s, ", length, (EXTRACT_32BITS(&hdr->direction)&0x1)?"in":"out"); + + if (!suppress_default_print) + default_print(p, caplen); + + return (BT_HDRLEN); +} +#endif + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-cdp.c b/print-cdp.c new file mode 100644 index 0000000..bef7f5e --- /dev/null +++ b/print-cdp.c @@ -0,0 +1,379 @@ +/* + * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Code by Gert Doering, SpaceNet GmbH, gert@space.net + * + * Reference documentation: + * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-cdp.c,v 1.25 2004-10-07 14:53:11 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ +#include "nlpid.h" + +#define CDP_HEADER_LEN 4 + +static struct tok cdp_tlv_values[] = { + { 0x01, "Device-ID"}, + { 0x02, "Address"}, + { 0x03, "Port-ID"}, + { 0x04, "Capability"}, + { 0x05, "Version String"}, + { 0x06, "Platform"}, + { 0x07, "Prefixes"}, + { 0x08, "Protocol-Hello option"}, + { 0x09, "VTP Management Domain"}, + { 0x0a, "Native VLAN ID"}, + { 0x0b, "Duplex"}, + { 0x0e, "ATA-186 VoIP VLAN request"}, + { 0x0f, "ATA-186 VoIP VLAN assignment"}, + { 0x10, "power consumption"}, + { 0x11, "MTU"}, + { 0x12, "AVVID trust bitmap"}, + { 0x13, "AVVID untrusted ports CoS"}, + { 0x14, "System Name"}, + { 0x15, "System Object ID (not decoded)"}, + { 0x16, "Management Addresses"}, + { 0x17, "Physical Location"}, + { 0, NULL} +}; + +static struct tok cdp_capability_values[] = { + { 0x01, "Router" }, + { 0x02, "Transparent Bridge" }, + { 0x04, "Source Route Bridge" }, + { 0x08, "L2 Switch" }, + { 0x10, "L3 capable" }, + { 0x20, "IGMP snooping" }, + { 0x40, "L1 capable" }, + { 0, NULL } +}; + +static int cdp_print_addr(const u_char *, int); +static int cdp_print_prefixes(const u_char *, int); +static unsigned long cdp_get_number(const u_char *, int); + +void +cdp_print(const u_char *pptr, u_int length, u_int caplen) +{ + int type, len, i, j; + const u_char *tptr; + + if (caplen < CDP_HEADER_LEN) { + (void)printf("[|cdp]"); + return; + } + + tptr = pptr; /* temporary pointer */ + + if (!TTEST2(*tptr, CDP_HEADER_LEN)) + goto trunc; + printf("CDPv%u, ttl: %us", *tptr, *(tptr+1)); + if (vflag) + printf(", checksum: %u (unverified), length %u", EXTRACT_16BITS(tptr), length); + tptr += CDP_HEADER_LEN; + + while (tptr < (pptr+length)) { + + if (!TTEST2(*tptr, 4)) /* read out Type and Length */ + goto trunc; + type = EXTRACT_16BITS(tptr); + len = EXTRACT_16BITS(tptr+2); /* object length includes the 4 bytes header length */ + tptr += 4; + len -= 4; + + if (!TTEST2(*tptr, len)) + goto trunc; + + if (vflag || type == 1) { /* in non-verbose mode just print Device-ID */ + + if (vflag) + printf("\n\t%s (0x%02x), length: %u byte%s: ", + tok2str(cdp_tlv_values,"unknown field type", type), + type, + len, + len>1 ? "s" : ""); /* plural */ + + switch (type) { + + case 0x01: /* Device-ID */ + if (!vflag) + printf(", Device-ID "); + printf("'"); + fn_printn(tptr, len, NULL); + printf("'"); + break; + case 0x02: /* Address */ + if (cdp_print_addr(tptr, len) < 0) + goto trunc; + break; + case 0x03: /* Port-ID */ + printf("'"); + fn_printn(tptr, len, NULL); + printf("'"); + break; + case 0x04: /* Capabilities */ + printf("(0x%08x): %s", + EXTRACT_32BITS(tptr), + bittok2str(cdp_capability_values, "none",EXTRACT_32BITS(tptr))); + break; + case 0x05: /* Version */ + printf("\n\t "); + for (i=0;i 1) { + printf("/"); + fn_printn(tptr + 1, len - 1, NULL); + } + break; + default: + print_unknown_data(tptr,"\n\t ",len); + break; + } + } + /* avoid infinite loop */ + if (len == 0) + break; + tptr = tptr+len; + } + if (vflag < 1) + printf(", length %u",caplen); + + return; +trunc: + printf("[|cdp]"); +} + +/* + * Protocol type values. + * + * PT_NLPID means that the protocol type field contains an OSI NLPID. + * + * PT_IEEE_802_2 means that the protocol type field contains an IEEE 802.2 + * LLC header that specifies that the payload is for that protocol. + */ +#define PT_NLPID 1 /* OSI NLPID */ +#define PT_IEEE_802_2 2 /* IEEE 802.2 LLC header */ + +static int +cdp_print_addr(const u_char * p, int l) +{ + int pt, pl, al, num; + const u_char *endp = p + l; +#ifdef INET6 + static u_char prot_ipv6[] = { + 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x86, 0xdd + }; +#endif + + TCHECK2(*p, 2); + num = EXTRACT_32BITS(p); + p += 4; + + while (p < endp && num >= 0) { + TCHECK2(*p, 2); + if (p + 2 > endp) + goto trunc; + pt = p[0]; /* type of "protocol" field */ + pl = p[1]; /* length of "protocol" field */ + p += 2; + + TCHECK2(p[pl], 2); + if (p + pl + 2 > endp) + goto trunc; + al = EXTRACT_16BITS(&p[pl]); /* address length */ + + if (pt == PT_NLPID && pl == 1 && *p == NLPID_IP && al == 4) { + /* + * IPv4: protocol type = NLPID, protocol length = 1 + * (1-byte NLPID), protocol = 0xcc (NLPID for IPv4), + * address length = 4 + */ + p += 3; + + TCHECK2(*p, 4); + if (p + 4 > endp) + goto trunc; + printf("IPv4 (%u) %s", + num, + ipaddr_string(p)); + p += 4; + } +#ifdef INET6 + else if (pt == PT_IEEE_802_2 && pl == 8 && + memcmp(p, prot_ipv6, 8) == 0 && al == 16) { + /* + * IPv6: protocol type = IEEE 802.2 header, + * protocol length = 8 (size of LLC+SNAP header), + * protocol = LLC+SNAP header with the IPv6 + * Ethertype, address length = 16 + */ + p += 10; + TCHECK2(*p, al); + if (p + al > endp) + goto trunc; + + printf("IPv6 (%u) %s", + num, + ip6addr_string(p)); + p += al; + } +#endif + else { + /* + * Generic case: just print raw data + */ + TCHECK2(*p, pl); + if (p + pl > endp) + goto trunc; + printf("pt=0x%02x, pl=%d, pb=", *(p - 2), pl); + while (pl-- > 0) + printf(" %02x", *p++); + TCHECK2(*p, 2); + if (p + 2 > endp) + goto trunc; + al = (*p << 8) + *(p + 1); + printf(", al=%d, a=", al); + p += 2; + TCHECK2(*p, al); + if (p + al > endp) + goto trunc; + while (al-- > 0) + printf(" %02x", *p++); + } + num--; + if (num) + printf(" "); + } + + return 0; + +trunc: + return -1; +} + + +static int +cdp_print_prefixes(const u_char * p, int l) +{ + if (l % 5) + goto trunc; + + printf(" IPv4 Prefixes (%d):", l / 5); + + while (l > 0) { + printf(" %u.%u.%u.%u/%u", p[0], p[1], p[2], p[3], p[4]); + l -= 5; + p += 5; + } + + return 0; + +trunc: + return -1; +} + +/* read in a -byte number, MSB first + * (of course this can handle max sizeof(long)) + */ +static unsigned long cdp_get_number(const u_char * p, int l) +{ + unsigned long res=0; + while( l>0 ) + { + res = (res<<8) + *p; + p++; l--; + } + return res; +} diff --git a/print-cfm.c b/print-cfm.c new file mode 100644 index 0000000..fb0476f --- /dev/null +++ b/print-cfm.c @@ -0,0 +1,645 @@ +/* + * Copyright (c) 1998-2006 The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Support for the IEEE Connectivity Fault Management Protocols as per 802.1ag. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-cfm.c,v 1.5 2007-07-24 16:01:42 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "ether.h" +#include "addrtoname.h" +#include "oui.h" +#include "af.h" + +/* + * Prototypes + */ +const char * cfm_egress_id_string(register const u_char *); +int cfm_mgmt_addr_print(register const u_char *); + +struct cfm_common_header_t { + u_int8_t mdlevel_version; + u_int8_t opcode; + u_int8_t flags; + u_int8_t first_tlv_offset; +}; + +#define CFM_VERSION 0 +#define CFM_EXTRACT_VERSION(x) (((x)&0x1f)) +#define CFM_EXTRACT_MD_LEVEL(x) (((x)&0xe0)>>5) + +#define CFM_OPCODE_CCM 1 +#define CFM_OPCODE_LBR 2 +#define CFM_OPCODE_LBM 3 +#define CFM_OPCODE_LTR 4 +#define CFM_OPCODE_LTM 5 + +static const struct tok cfm_opcode_values[] = { + { CFM_OPCODE_CCM, "Continouity Check Message"}, + { CFM_OPCODE_LBR, "Loopback Reply"}, + { CFM_OPCODE_LBM, "Loopback Message"}, + { CFM_OPCODE_LTR, "Linktrace Reply"}, + { CFM_OPCODE_LTM, "Linktrace Message"}, + { 0, NULL} +}; + +/* + * Message Formats. + */ +struct cfm_ccm_t { + u_int8_t sequence[4]; + u_int8_t ma_epi[2]; + u_int8_t md_nameformat; + u_int8_t md_namelength; + u_int8_t md_name[46]; /* md name and short ma name */ + u_int8_t reserved_itu[16]; + u_int8_t reserved[6]; +}; + +/* + * Timer Bases for the CCM Interval field. + * Expressed in units of seconds. + */ +const float ccm_interval_base[8] = {0, 0.003333, 0.01, 0.1, 1, 10, 60, 600}; +#define CCM_INTERVAL_MIN_MULTIPLIER 3.25 +#define CCM_INTERVAL_MAX_MULTIPLIER 3.5 + +#define CFM_CCM_RDI_FLAG 0x80 +#define CFM_EXTRACT_CCM_INTERVAL(x) (((x)&0x07)) + +#define CFM_CCM_MD_FORMAT_8021 0 +#define CFM_CCM_MD_FORMAT_NONE 1 +#define CFM_CCM_MD_FORMAT_DNS 2 +#define CFM_CCM_MD_FORMAT_MAC 3 +#define CFM_CCM_MD_FORMAT_CHAR 4 + +static const struct tok cfm_md_nameformat_values[] = { + { CFM_CCM_MD_FORMAT_8021, "IEEE 802.1"}, + { CFM_CCM_MD_FORMAT_NONE, "No MD Name present"}, + { CFM_CCM_MD_FORMAT_DNS, "DNS string"}, + { CFM_CCM_MD_FORMAT_MAC, "MAC + 16Bit Integer"}, + { CFM_CCM_MD_FORMAT_CHAR, "Character string"}, + { 0, NULL} +}; + +#define CFM_CCM_MA_FORMAT_8021 0 +#define CFM_CCM_MA_FORMAT_VID 1 +#define CFM_CCM_MA_FORMAT_CHAR 2 +#define CFM_CCM_MA_FORMAT_INT 3 +#define CFM_CCM_MA_FORMAT_VPN 4 + +static const struct tok cfm_ma_nameformat_values[] = { + { CFM_CCM_MA_FORMAT_8021, "IEEE 802.1"}, + { CFM_CCM_MA_FORMAT_VID, "Primary VID"}, + { CFM_CCM_MA_FORMAT_CHAR, "Character string"}, + { CFM_CCM_MA_FORMAT_INT, "16Bit Integer"}, + { CFM_CCM_MA_FORMAT_VPN, "RFC2685 VPN-ID"}, + { 0, NULL} +}; + +struct cfm_lbm_t { + u_int8_t transaction_id[4]; + u_int8_t reserved[4]; +}; + +struct cfm_ltm_t { + u_int8_t transaction_id[4]; + u_int8_t egress_id[8]; + u_int8_t ttl; + u_int8_t original_mac[ETHER_ADDR_LEN]; + u_int8_t target_mac[ETHER_ADDR_LEN]; + u_int8_t reserved[3]; +}; + +static const struct tok cfm_ltm_flag_values[] = { + { 0x80, "Use Forwarding-DB only"}, + { 0, NULL} +}; + +struct cfm_ltr_t { + u_int8_t transaction_id[4]; + u_int8_t last_egress_id[8]; + u_int8_t next_egress_id[8]; + u_int8_t ttl; + u_int8_t replay_action; + u_int8_t reserved[6]; +}; + +static const struct tok cfm_ltr_flag_values[] = { + { 0x80, "Forwarded"}, + { 0x40, "Terminal MEP"}, + { 0, NULL} +}; + +static const struct tok cfm_ltr_replay_action_values[] = { + { 1, "Exact Match"}, + { 2, "Filtering DB"}, + { 3, "MIP CCM DB"}, + { 0, NULL} +}; + + +#define CFM_TLV_END 0 +#define CFM_TLV_SENDER_ID 1 +#define CFM_TLV_PORT_STATUS 2 +#define CFM_TLV_INTERFACE_STATUS 3 +#define CFM_TLV_DATA 4 +#define CFM_TLV_REPLY_INGRESS 5 +#define CFM_TLV_REPLY_EGRESS 6 +#define CFM_TLV_PRIVATE 31 + +static const struct tok cfm_tlv_values[] = { + { CFM_TLV_END, "End"}, + { CFM_TLV_SENDER_ID, "Sender ID"}, + { CFM_TLV_PORT_STATUS, "Port status"}, + { CFM_TLV_INTERFACE_STATUS, "Interface status"}, + { CFM_TLV_DATA, "Data"}, + { CFM_TLV_REPLY_INGRESS, "Reply Ingress"}, + { CFM_TLV_REPLY_EGRESS, "Reply Egress"}, + { CFM_TLV_PRIVATE, "Organization Specific"}, + { 0, NULL} +}; + +/* + * TLVs + */ + +struct cfm_tlv_header_t { + u_int8_t type; + u_int8_t length[2]; +}; + +/* FIXME define TLV formats */ + +static const struct tok cfm_tlv_port_status_values[] = { + { 1, "Blocked"}, + { 2, "Up"}, + { 0, NULL} +}; + +static const struct tok cfm_tlv_interface_status_values[] = { + { 1, "Up"}, + { 2, "Down"}, + { 3, "Testing"}, + { 5, "Dormant"}, + { 6, "not present"}, + { 7, "lower Layer down"}, + { 0, NULL} +}; + +#define CFM_CHASSIS_ID_CHASSIS_COMPONENT 1 +#define CFM_CHASSIS_ID_INTERFACE_ALIAS 2 +#define CFM_CHASSIS_ID_PORT_COMPONENT 3 +#define CFM_CHASSIS_ID_MAC_ADDRESS 4 +#define CFM_CHASSIS_ID_NETWORK_ADDRESS 5 +#define CFM_CHASSIS_ID_INTERFACE_NAME 6 +#define CFM_CHASSIS_ID_LOCAL 7 + +static const struct tok cfm_tlv_senderid_chassisid_values[] = { + { 0, "Reserved"}, + { CFM_CHASSIS_ID_CHASSIS_COMPONENT, "Chassis component"}, + { CFM_CHASSIS_ID_INTERFACE_ALIAS, "Interface alias"}, + { CFM_CHASSIS_ID_PORT_COMPONENT, "Port component"}, + { CFM_CHASSIS_ID_MAC_ADDRESS, "MAC address"}, + { CFM_CHASSIS_ID_NETWORK_ADDRESS, "Network address"}, + { CFM_CHASSIS_ID_INTERFACE_NAME, "Interface name"}, + { CFM_CHASSIS_ID_LOCAL, "Locally assigned"}, + { 0, NULL} +}; + + +int +cfm_mgmt_addr_print(register const u_char *tptr) { + + u_int mgmt_addr_type; + u_int hexdump = FALSE; + + /* + * Altough AFIs are tpically 2 octects wide, + * 802.1ab specifies that this field width + * is only once octet + */ + mgmt_addr_type = *tptr; + printf("\n\t Management Address Type %s (%u)", + tok2str(af_values, "Unknown", mgmt_addr_type), + mgmt_addr_type); + + /* + * Resolve the passed in Address. + */ + switch(mgmt_addr_type) { + case AFNUM_INET: + printf(", %s", ipaddr_string(tptr + 1)); + break; + +#ifdef INET6 + case AFNUM_INET6: + printf(", %s", ip6addr_string(tptr + 1)); + break; +#endif + + default: + hexdump = TRUE; + break; + } + + return hexdump; +} + +/* + * The egress-ID string is a 16-Bit string plus a MAC address. + */ +const char * +cfm_egress_id_string(register const u_char *tptr) { + static char egress_id_buffer[80]; + + snprintf(egress_id_buffer, sizeof(egress_id_buffer), + "MAC %0x4x-%s", + EXTRACT_16BITS(tptr), + etheraddr_string(tptr+2)); + + return egress_id_buffer; +} + +void +cfm_print(register const u_char *pptr, register u_int length) { + + const struct cfm_common_header_t *cfm_common_header; + const struct cfm_tlv_header_t *cfm_tlv_header; + const u_int8_t *tptr, *tlv_ptr, *ma_name, *ma_nameformat, *ma_namelength; + u_int hexdump, tlen, cfm_tlv_len, cfm_tlv_type, ccm_interval; + + + union { + const struct cfm_ccm_t *cfm_ccm; + const struct cfm_lbm_t *cfm_lbm; + const struct cfm_ltm_t *cfm_ltm; + const struct cfm_ltr_t *cfm_ltr; + } msg_ptr; + + tptr=pptr; + cfm_common_header = (const struct cfm_common_header_t *)pptr; + TCHECK(*cfm_common_header); + + /* + * Sanity checking of the header. + */ + if (CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version) != CFM_VERSION) { + printf("CFMv%u not supported, length %u", + CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version), length); + return; + } + + printf("CFMv%u %s, MD Level %u, length %u", + CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version), + tok2str(cfm_opcode_values, "unknown (%u)", cfm_common_header->opcode), + CFM_EXTRACT_MD_LEVEL(cfm_common_header->mdlevel_version), + length); + + /* + * In non-verbose mode just print the opcode and md-level. + */ + if (vflag < 1) { + return; + } + + printf("\n\tFirst TLV offset %u", cfm_common_header->first_tlv_offset); + + tptr += sizeof(const struct cfm_common_header_t); + tlen = length - sizeof(struct cfm_common_header_t); + + switch (cfm_common_header->opcode) { + case CFM_OPCODE_CCM: + msg_ptr.cfm_ccm = (const struct cfm_ccm_t *)tptr; + + ccm_interval = CFM_EXTRACT_CCM_INTERVAL(cfm_common_header->flags); + printf(", Flags [CCM Interval %u%s]", + ccm_interval, + cfm_common_header->flags & CFM_CCM_RDI_FLAG ? + ", RDI" : ""); + + /* + * Resolve the CCM interval field. + */ + if (ccm_interval) { + printf("\n\t CCM Interval %.3fs" + ", min CCM Lifetime %.3fs, max CCM Lifetime %.3fs", + ccm_interval_base[ccm_interval], + ccm_interval_base[ccm_interval] * CCM_INTERVAL_MIN_MULTIPLIER, + ccm_interval_base[ccm_interval] * CCM_INTERVAL_MAX_MULTIPLIER); + } + + printf("\n\t Sequence Number 0x%08x, MA-End-Point-ID 0x%04x", + EXTRACT_32BITS(msg_ptr.cfm_ccm->sequence), + EXTRACT_16BITS(msg_ptr.cfm_ccm->ma_epi)); + + + /* + * Resolve the MD fields. + */ + printf("\n\t MD Name Format %s (%u), MD Name length %u", + tok2str(cfm_md_nameformat_values, "Unknown", + msg_ptr.cfm_ccm->md_nameformat), + msg_ptr.cfm_ccm->md_nameformat, + msg_ptr.cfm_ccm->md_namelength); + + if (msg_ptr.cfm_ccm->md_nameformat != CFM_CCM_MD_FORMAT_NONE) { + printf("\n\t MD Name: "); + switch (msg_ptr.cfm_ccm->md_nameformat) { + case CFM_CCM_MD_FORMAT_DNS: + case CFM_CCM_MD_FORMAT_CHAR: + safeputs((const char *)msg_ptr.cfm_ccm->md_name, msg_ptr.cfm_ccm->md_namelength); + break; + + case CFM_CCM_MD_FORMAT_MAC: + printf("\n\t MAC %s", etheraddr_string( + msg_ptr.cfm_ccm->md_name)); + break; + + /* FIXME add printers for those MD formats - hexdump for now */ + case CFM_CCM_MA_FORMAT_8021: + default: + print_unknown_data(msg_ptr.cfm_ccm->md_name, "\n\t ", + msg_ptr.cfm_ccm->md_namelength); + } + } + + + /* + * Resolve the MA fields. + */ + ma_nameformat = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength; + ma_namelength = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength + 1; + ma_name = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength + 2; + + printf("\n\t MA Name-Format %s (%u), MA name length %u", + tok2str(cfm_ma_nameformat_values, "Unknown", + *ma_nameformat), + *ma_nameformat, + *ma_namelength); + + printf("\n\t MA Name: "); + switch (*ma_nameformat) { + case CFM_CCM_MA_FORMAT_CHAR: + safeputs((const char *)ma_name, *ma_namelength); + break; + + /* FIXME add printers for those MA formats - hexdump for now */ + case CFM_CCM_MA_FORMAT_8021: + case CFM_CCM_MA_FORMAT_VID: + case CFM_CCM_MA_FORMAT_INT: + case CFM_CCM_MA_FORMAT_VPN: + default: + print_unknown_data(ma_name, "\n\t ", *ma_namelength); + } + break; + + case CFM_OPCODE_LTM: + msg_ptr.cfm_ltm = (const struct cfm_ltm_t *)tptr; + + printf(", Flags [%s]", + bittok2str(cfm_ltm_flag_values, "none", cfm_common_header->flags)); + + printf("\n\t Transaction-ID 0x%08x, Egress-ID %s, ttl %u", + EXTRACT_32BITS(msg_ptr.cfm_ltm->transaction_id), + cfm_egress_id_string(msg_ptr.cfm_ltm->egress_id), + msg_ptr.cfm_ltm->ttl); + + printf("\n\t Original-MAC %s, Target-MAC %s", + etheraddr_string(msg_ptr.cfm_ltm->original_mac), + etheraddr_string(msg_ptr.cfm_ltm->target_mac)); + break; + + case CFM_OPCODE_LTR: + msg_ptr.cfm_ltr = (const struct cfm_ltr_t *)tptr; + + printf(", Flags [%s]", + bittok2str(cfm_ltr_flag_values, "none", cfm_common_header->flags)); + + printf("\n\t Transaction-ID 0x%08x, Last-Egress-ID %s", + EXTRACT_32BITS(msg_ptr.cfm_ltr->transaction_id), + cfm_egress_id_string(msg_ptr.cfm_ltr->last_egress_id)); + + printf("\n\t Next-Egress-ID %s, ttl %u", + cfm_egress_id_string(msg_ptr.cfm_ltr->next_egress_id), + msg_ptr.cfm_ltr->ttl); + + printf("\n\t Replay-Action %s (%u)", + tok2str(cfm_ltr_replay_action_values, + "Unknown", + msg_ptr.cfm_ltr->replay_action), + msg_ptr.cfm_ltr->replay_action); + break; + + /* + * No message decoder yet. + * Hexdump everything up until the start of the TLVs + */ + case CFM_OPCODE_LBR: + case CFM_OPCODE_LBM: + default: + if (tlen > cfm_common_header->first_tlv_offset) { + print_unknown_data(tptr, "\n\t ", + tlen - cfm_common_header->first_tlv_offset); + } + break; + } + + /* + * Sanity check for not walking off. + */ + if (tlen <= cfm_common_header->first_tlv_offset) { + return; + } + + tptr += cfm_common_header->first_tlv_offset; + tlen -= cfm_common_header->first_tlv_offset; + + while (tlen > 0) { + cfm_tlv_header = (const struct cfm_tlv_header_t *)tptr; + + /* Enough to read the tlv type ? */ + TCHECK2(*tptr, 1); + cfm_tlv_type=cfm_tlv_header->type; + + if (cfm_tlv_type != CFM_TLV_END) { + /* did we capture enough for fully decoding the object header ? */ + TCHECK2(*tptr, sizeof(struct cfm_tlv_header_t)); + cfm_tlv_len=EXTRACT_16BITS(&cfm_tlv_header->length); + } else { + cfm_tlv_len = 0; + } + + printf("\n\t%s TLV (0x%02x), length %u", + tok2str(cfm_tlv_values, "Unknown", cfm_tlv_type), + cfm_tlv_type, + cfm_tlv_len); + + /* sanity check for not walking off and infinite loop check. */ + if ((cfm_tlv_type != CFM_TLV_END) && + ((cfm_tlv_len + sizeof(struct cfm_tlv_header_t) > tlen) || + (!cfm_tlv_len))) { + print_unknown_data(tptr,"\n\t ",tlen); + return; + } + + tptr += sizeof(struct cfm_tlv_header_t); + tlen -= sizeof(struct cfm_tlv_header_t); + tlv_ptr = tptr; + + /* did we capture enough for fully decoding the object ? */ + if (cfm_tlv_type != CFM_TLV_END) { + TCHECK2(*tptr, cfm_tlv_len); + } + hexdump = FALSE; + + switch(cfm_tlv_type) { + case CFM_TLV_END: + /* we are done - bail out */ + return; + + case CFM_TLV_PORT_STATUS: + printf(", Status: %s (%u)", + tok2str(cfm_tlv_port_status_values, "Unknown", *tptr), + *tptr); + break; + + case CFM_TLV_INTERFACE_STATUS: + printf(", Status: %s (%u)", + tok2str(cfm_tlv_interface_status_values, "Unknown", *tptr), + *tptr); + break; + + case CFM_TLV_PRIVATE: + printf(", Vendor: %s (%u), Sub-Type %u", + tok2str(oui_values,"Unknown", EXTRACT_24BITS(tptr)), + EXTRACT_24BITS(tptr), + *(tptr+3)); + hexdump = TRUE; + break; + + case CFM_TLV_SENDER_ID: + { + u_int chassis_id_type, chassis_id_length; + u_int mgmt_addr_length; + + /* + * Check if there is a Chassis-ID. + */ + chassis_id_length = *tptr; + if (chassis_id_length > tlen) { + hexdump = TRUE; + break; + } + + tptr++; + tlen--; + + if (chassis_id_length) { + chassis_id_type = *tptr; + printf("\n\t Chassis-ID Type %s (%u), Chassis-ID length %u", + tok2str(cfm_tlv_senderid_chassisid_values, + "Unknown", + chassis_id_type), + chassis_id_type, + chassis_id_length); + + switch (chassis_id_type) { + case CFM_CHASSIS_ID_MAC_ADDRESS: + printf("\n\t MAC %s", etheraddr_string(tptr+1)); + break; + + case CFM_CHASSIS_ID_NETWORK_ADDRESS: + hexdump |= cfm_mgmt_addr_print(tptr); + break; + + case CFM_CHASSIS_ID_INTERFACE_NAME: /* fall through */ + case CFM_CHASSIS_ID_INTERFACE_ALIAS: + case CFM_CHASSIS_ID_LOCAL: + case CFM_CHASSIS_ID_CHASSIS_COMPONENT: + case CFM_CHASSIS_ID_PORT_COMPONENT: + safeputs((const char *)tptr+1, chassis_id_length); + break; + + default: + hexdump = TRUE; + break; + } + } + + tptr += chassis_id_length; + tlen -= chassis_id_length; + + /* + * Check if there is a Management Address. + */ + mgmt_addr_length = *tptr; + if (mgmt_addr_length > tlen) { + hexdump = TRUE; + break; + } + + tptr++; + tlen--; + + if (mgmt_addr_length) { + hexdump |= cfm_mgmt_addr_print(tptr); + } + + tptr += mgmt_addr_length; + tlen -= mgmt_addr_length; + + } + break; + + /* + * FIXME those are the defined TLVs that lack a decoder + * you are welcome to contribute code ;-) + */ + + case CFM_TLV_DATA: + case CFM_TLV_REPLY_INGRESS: + case CFM_TLV_REPLY_EGRESS: + default: + hexdump = TRUE; + break; + } + /* do we want to see an additional hexdump ? */ + if (hexdump || vflag > 1) + print_unknown_data(tlv_ptr, "\n\t ", cfm_tlv_len); + + tptr+=cfm_tlv_len; + tlen-=cfm_tlv_len; + } + return; +trunc: + printf("\n\t\t packet exceeded snapshot"); +} diff --git a/print-chdlc.c b/print-chdlc.c new file mode 100644 index 0000000..238e91a --- /dev/null +++ b/print-chdlc.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-chdlc.c,v 1.43 2005-11-29 08:56:19 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "extract.h" +#include "ppp.h" +#include "chdlc.h" + +static void chdlc_slarp_print(const u_char *, u_int); + +const struct tok chdlc_cast_values[] = { + { CHDLC_UNICAST, "unicast" }, + { CHDLC_BCAST, "bcast" }, + { 0, NULL} +}; + + +/* Standard CHDLC printer */ +u_int +chdlc_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + register u_int length = h->len; + register u_int caplen = h->caplen; + + if (caplen < CHDLC_HDRLEN) { + printf("[|chdlc]"); + return (caplen); + } + return (chdlc_print(p,length)); +} + +u_int +chdlc_print(register const u_char *p, u_int length) { + u_int proto; + + proto = EXTRACT_16BITS(&p[2]); + if (eflag) { + printf("%s, ethertype %s (0x%04x), length %u: ", + tok2str(chdlc_cast_values, "0x%02x", p[0]), + tok2str(ethertype_values, "Unknown", proto), + proto, + length); + } + + length -= CHDLC_HDRLEN; + p += CHDLC_HDRLEN; + + switch (proto) { + case ETHERTYPE_IP: + ip_print(gndo, p, length); + break; +#ifdef INET6 + case ETHERTYPE_IPV6: + ip6_print(p, length); + break; +#endif + case CHDLC_TYPE_SLARP: + chdlc_slarp_print(p, length); + break; +#if 0 + case CHDLC_TYPE_CDP: + chdlc_cdp_print(p, length); + break; +#endif + case ETHERTYPE_MPLS: + case ETHERTYPE_MPLS_MULTI: + mpls_print(p, length); + break; + case ETHERTYPE_ISO: + /* is the fudge byte set ? lets verify by spotting ISO headers */ + if (*(p+1) == 0x81 || + *(p+1) == 0x82 || + *(p+1) == 0x83) + isoclns_print(p+1, length-1, length-1); + else + isoclns_print(p, length, length); + break; + default: + if (!eflag) + printf("unknown CHDLC protocol (0x%04x)", proto); + break; + } + + return (CHDLC_HDRLEN); +} + +/* + * The fixed-length portion of a SLARP packet. + */ +struct cisco_slarp { + u_int8_t code[4]; +#define SLARP_REQUEST 0 +#define SLARP_REPLY 1 +#define SLARP_KEEPALIVE 2 + union { + struct { + u_int8_t addr[4]; + u_int8_t mask[4]; + } addr; + struct { + u_int8_t myseq[4]; + u_int8_t yourseq[4]; + u_int8_t rel[2]; + } keep; + } un; +}; + +#define SLARP_MIN_LEN 14 +#define SLARP_MAX_LEN 18 + +static void +chdlc_slarp_print(const u_char *cp, u_int length) +{ + const struct cisco_slarp *slarp; + u_int sec,min,hrs,days; + + printf("SLARP (length: %u), ",length); + if (length < SLARP_MIN_LEN) + goto trunc; + + slarp = (const struct cisco_slarp *)cp; + TCHECK2(*slarp, SLARP_MIN_LEN); + switch (EXTRACT_32BITS(&slarp->code)) { + case SLARP_REQUEST: + printf("request"); + /* + * At least according to William "Chops" Westfield's + * message in + * + * http://www.nethelp.no/net/cisco-hdlc.txt + * + * the address and mask aren't used in requests - + * they're just zero. + */ + break; + case SLARP_REPLY: + printf("reply %s/%s", + ipaddr_string(&slarp->un.addr.addr), + ipaddr_string(&slarp->un.addr.mask)); + break; + case SLARP_KEEPALIVE: + printf("keepalive: mineseen=0x%08x, yourseen=0x%08x, reliability=0x%04x", + EXTRACT_32BITS(&slarp->un.keep.myseq), + EXTRACT_32BITS(&slarp->un.keep.yourseq), + EXTRACT_16BITS(&slarp->un.keep.rel)); + + if (length >= SLARP_MAX_LEN) { /* uptime-stamp is optional */ + cp += SLARP_MIN_LEN; + if (!TTEST2(*cp, 4)) + goto trunc; + sec = EXTRACT_32BITS(cp) / 1000; + min = sec / 60; sec -= min * 60; + hrs = min / 60; min -= hrs * 60; + days = hrs / 24; hrs -= days * 24; + printf(", link uptime=%ud%uh%um%us",days,hrs,min,sec); + } + break; + default: + printf("0x%02x unknown", EXTRACT_32BITS(&slarp->code)); + if (vflag <= 1) + print_unknown_data(cp+4,"\n\t",length-4); + break; + } + + if (SLARP_MAX_LEN < length && vflag) + printf(", (trailing junk: %d bytes)", length - SLARP_MAX_LEN); + if (vflag > 1) + print_unknown_data(cp+4,"\n\t",length-4); + return; + +trunc: + printf("[|slarp]"); +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-cip.c b/print-cip.c new file mode 100644 index 0000000..e9d672f --- /dev/null +++ b/print-cip.c @@ -0,0 +1,116 @@ +/* + * Marko Kiiskila carnil@cs.tut.fi + * + * Tampere University of Technology - Telecommunications Laboratory + * + * Permission to use, copy, modify and distribute this + * software and its documentation is hereby granted, + * provided that both the copyright notice and this + * permission notice appear in all copies of the software, + * derivative works or modified versions, and any portions + * thereof, that both notices appear in supporting + * documentation, and that the use of this software is + * acknowledged in any publications resulting from using + * the software. + * + * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS + * SOFTWARE. + * + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-cip.c,v 1.26 2005-07-07 01:22:17 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "ether.h" + +#define RFC1483LLC_LEN 8 + +static unsigned char rfcllc[] = { + 0xaa, /* DSAP: non-ISO */ + 0xaa, /* SSAP: non-ISO */ + 0x03, /* Ctrl: Unnumbered Information Command PDU */ + 0x00, /* OUI: EtherType */ + 0x00, + 0x00 }; + +static inline void +cip_print(int length) +{ + /* + * There is no MAC-layer header, so just print the length. + */ + printf("%d: ", length); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the LLC/SNAP or raw header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +cip_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + u_short extracted_ethertype; + + if (memcmp(rfcllc, p, sizeof(rfcllc))==0 && caplen < RFC1483LLC_LEN) { + printf("[|cip]"); + return (0); + } + + if (eflag) + cip_print(length); + + if (memcmp(rfcllc, p, sizeof(rfcllc)) == 0) { + /* + * LLC header is present. Try to print it & higher layers. + */ + if (llc_print(p, length, caplen, NULL, NULL, + &extracted_ethertype) == 0) { + /* ether_type not known, print raw packet */ + if (!eflag) + cip_print(length); + if (extracted_ethertype) { + printf("(LLC %s) ", + etherproto_string(htons(extracted_ethertype))); + } + if (!suppress_default_print) + default_print(p, caplen); + } + } else { + /* + * LLC header is absent; treat it as just IP. + */ + ip_print(gndo, p, length); + } + + return (0); +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-cnfp.c b/print-cnfp.c new file mode 100644 index 0000000..86d7128 --- /dev/null +++ b/print-cnfp.c @@ -0,0 +1,190 @@ +/* $OpenBSD: print-cnfp.c,v 1.2 1998/06/25 20:26:59 mickey Exp $ */ + +/* + * Copyright (c) 1998 Michael Shalayeff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Michael Shalayeff. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Cisco NetFlow protocol */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-cnfp.c,v 1.17 2005-04-20 20:53:18 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "tcp.h" +#include "ipproto.h" + +struct nfhdr { + u_int32_t ver_cnt; /* version [15], and # of records */ + u_int32_t msys_uptime; + u_int32_t utc_sec; + u_int32_t utc_nsec; + u_int32_t sequence; /* v5 flow sequence number */ + u_int32_t reserved; /* v5 only */ +}; + +struct nfrec { + struct in_addr src_ina; + struct in_addr dst_ina; + struct in_addr nhop_ina; + u_int32_t ifaces; /* src,dst ifaces */ + u_int32_t packets; + u_int32_t octets; + u_int32_t start_time; /* sys_uptime value */ + u_int32_t last_time; /* sys_uptime value */ + u_int32_t ports; /* src,dst ports */ + u_int32_t proto_tos; /* proto, tos, pad, flags(v5) */ + u_int32_t asses; /* v1: flags; v5: src,dst AS */ + u_int32_t masks; /* src,dst addr prefix; v6: encaps */ + struct in_addr peer_nexthop; /* v6: IP address of the nexthop within the peer (FIB)*/ +}; + +void +cnfp_print(const u_char *cp, const u_char *bp _U_) +{ + register const struct nfhdr *nh; + register const struct nfrec *nr; + struct protoent *pent; + int nrecs, ver; +#if 0 + time_t t; +#endif + + nh = (const struct nfhdr *)cp; + + if ((const u_char *)(nh + 1) > snapend) + return; + + nrecs = EXTRACT_32BITS(&nh->ver_cnt) & 0xffff; + ver = (EXTRACT_32BITS(&nh->ver_cnt) & 0xffff0000) >> 16; +#if 0 + /* + * This is seconds since the UN*X epoch, and is followed by + * nanoseconds. XXX - format it, rather than just dumping the + * raw seconds-since-the-Epoch. + */ + t = EXTRACT_32BITS(&nh->utc_sec); +#endif + + printf("NetFlow v%x, %u.%03u uptime, %u.%09u, ", ver, + EXTRACT_32BITS(&nh->msys_uptime)/1000, + EXTRACT_32BITS(&nh->msys_uptime)%1000, + EXTRACT_32BITS(&nh->utc_sec), EXTRACT_32BITS(&nh->utc_nsec)); + + if (ver == 5 || ver == 6) { + printf("#%u, ", EXTRACT_32BITS(&nh->sequence)); + nr = (const struct nfrec *)&nh[1]; + snaplen -= 24; + } else { + nr = (const struct nfrec *)&nh->sequence; + snaplen -= 16; + } + + printf("%2u recs", nrecs); + + for (; nrecs-- && (const u_char *)(nr + 1) <= snapend; nr++) { + char buf[20]; + char asbuf[20]; + + printf("\n started %u.%03u, last %u.%03u", + EXTRACT_32BITS(&nr->start_time)/1000, + EXTRACT_32BITS(&nr->start_time)%1000, + EXTRACT_32BITS(&nr->last_time)/1000, + EXTRACT_32BITS(&nr->last_time)%1000); + + asbuf[0] = buf[0] = '\0'; + if (ver == 5 || ver == 6) { + snprintf(buf, sizeof(buf), "/%u", + (EXTRACT_32BITS(&nr->masks) >> 24) & 0xff); + snprintf(asbuf, sizeof(asbuf), ":%u", + (EXTRACT_32BITS(&nr->asses) >> 16) & 0xffff); + } + printf("\n %s%s%s:%u ", intoa(nr->src_ina.s_addr), buf, asbuf, + EXTRACT_32BITS(&nr->ports) >> 16); + + if (ver == 5 || ver ==6) { + snprintf(buf, sizeof(buf), "/%d", + (EXTRACT_32BITS(&nr->masks) >> 16) & 0xff); + snprintf(asbuf, sizeof(asbuf), ":%u", + EXTRACT_32BITS(&nr->asses) & 0xffff); + } + printf("> %s%s%s:%u ", intoa(nr->dst_ina.s_addr), buf, asbuf, + EXTRACT_32BITS(&nr->ports) & 0xffff); + + printf(">> %s\n ", intoa(nr->nhop_ina.s_addr)); + + pent = getprotobynumber((EXTRACT_32BITS(&nr->proto_tos) >> 8) & 0xff); + if (!pent || nflag) + printf("%u ", + (EXTRACT_32BITS(&nr->proto_tos) >> 8) & 0xff); + else + printf("%s ", pent->p_name); + + /* tcp flags for tcp only */ + if (pent && pent->p_proto == IPPROTO_TCP) { + int flags; + if (ver == 1) + flags = (EXTRACT_32BITS(&nr->asses) >> 24) & 0xff; + else + flags = (EXTRACT_32BITS(&nr->proto_tos) >> 16) & 0xff; + if (flags & TH_FIN) putchar('F'); + if (flags & TH_SYN) putchar('S'); + if (flags & TH_RST) putchar('R'); + if (flags & TH_PUSH) putchar('P'); + if (flags & TH_ACK) putchar('A'); + if (flags & TH_URG) putchar('U'); + if (flags) + putchar(' '); + } + + buf[0]='\0'; + if (ver == 6) { + snprintf(buf, sizeof(buf), "(%u<>%u encaps)", + (EXTRACT_32BITS(&nr->masks) >> 8) & 0xff, + (EXTRACT_32BITS(&nr->masks)) & 0xff); + } + printf("tos %u, %u (%u octets) %s", + EXTRACT_32BITS(&nr->proto_tos) & 0xff, + EXTRACT_32BITS(&nr->packets), + EXTRACT_32BITS(&nr->octets), buf); + } +} diff --git a/print-dccp.c b/print-dccp.c new file mode 100644 index 0000000..fee4a6e --- /dev/null +++ b/print-dccp.c @@ -0,0 +1,510 @@ +/* + * Copyright (C) Arnaldo Carvalho de Melo 2004 + * Copyright (C) Ian McDonald 2005 + * Copyright (C) Yoshifumi Nishida 2005 + * + * This software may be distributed either under the terms of the + * BSD-style license that accompanies tcpdump or the GNU GPL version 2 + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-dccp.c,v 1.8 2007-11-09 00:44:09 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "dccp.h" + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif +#include "ipproto.h" + +static const char *dccp_reset_codes[] = { + "unspecified", + "closed", + "aborted", + "no_connection", + "packet_error", + "option_error", + "mandatory_error", + "connection_refused", + "bad_service_code", + "too_busy", + "bad_init_cookie", + "aggression_penalty", +}; + +static const char *dccp_feature_nums[] = { + "reserved", + "ccid", + "allow_short_seqno", + "sequence_window", + "ecn_incapable", + "ack_ratio", + "send_ack_vector", + "send_ndp_count", + "minimum checksum coverage", + "check data checksum", +}; + +static inline int dccp_csum_coverage(const struct dccp_hdr* dh, u_int len) +{ + u_int cov; + + if (DCCPH_CSCOV(dh) == 0) + return len; + cov = (dh->dccph_doff + DCCPH_CSCOV(dh) - 1) * sizeof(u_int32_t); + return (cov > len)? len : cov; +} + +static int dccp_cksum(const struct ip *ip, + const struct dccp_hdr *dh, u_int len) +{ + int cov = dccp_csum_coverage(dh, len); + union phu { + struct phdr { + u_int32_t src; + u_int32_t dst; + u_char mbz; + u_char proto; + u_int16_t len; + } ph; + u_int16_t pa[6]; + } phu; + const u_int16_t *sp; + + /* pseudo-header.. */ + phu.ph.mbz = 0; + phu.ph.len = htons(len); + phu.ph.proto = IPPROTO_DCCP; + memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t)); + if (IP_HL(ip) == 5) + memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t)); + else + phu.ph.dst = ip_finddst(ip); + + sp = &phu.pa[0]; + return in_cksum((u_short *)dh, cov, sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]); +} + +#ifdef INET6 +static int dccp6_cksum(const struct ip6_hdr *ip6, const struct dccp_hdr *dh, u_int len) +{ + size_t i; + u_int32_t sum = 0; + int cov = dccp_csum_coverage(dh, len); + union { + struct { + struct in6_addr ph_src; + struct in6_addr ph_dst; + u_int32_t ph_len; + u_int8_t ph_zero[3]; + u_int8_t ph_nxt; + } ph; + u_int16_t pa[20]; + } phu; + + /* pseudo-header */ + memset(&phu, 0, sizeof(phu)); + phu.ph.ph_src = ip6->ip6_src; + phu.ph.ph_dst = ip6->ip6_dst; + phu.ph.ph_len = htonl(len); + phu.ph.ph_nxt = IPPROTO_DCCP; + + for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) + sum += phu.pa[i]; + + return in_cksum((u_short *)dh, cov, sum); +} +#endif + +static const char *dccp_reset_code(u_int8_t code) +{ + if (code >= __DCCP_RESET_CODE_LAST) + return "invalid"; + return dccp_reset_codes[code]; +} + +static u_int64_t dccp_seqno(const struct dccp_hdr *dh) +{ + u_int32_t seq_high = DCCPH_SEQ(dh); + u_int64_t seqno = EXTRACT_24BITS(&seq_high) & 0xFFFFFF; + + if (DCCPH_X(dh) != 0) { + const struct dccp_hdr_ext *dhx = (void *)(dh + 1); + u_int32_t seq_low = dhx->dccph_seq_low; + seqno &= 0x00FFFF; /* clear reserved field */ + seqno = (seqno << 32) + EXTRACT_32BITS(&seq_low); + } + + return seqno; +} + +static inline unsigned int dccp_basic_hdr_len(const struct dccp_hdr *dh) +{ + return sizeof(*dh) + (DCCPH_X(dh) ? sizeof(struct dccp_hdr_ext) : 0); +} + +static void dccp_print_ack_no(const u_char *bp) +{ + const struct dccp_hdr *dh = (const struct dccp_hdr *)bp; + const struct dccp_hdr_ack_bits *dh_ack = + (struct dccp_hdr_ack_bits *)(bp + dccp_basic_hdr_len(dh)); + u_int32_t ack_high; + u_int64_t ackno; + + TCHECK2(*dh_ack,4); + ack_high = DCCPH_ACK(dh_ack); + ackno = EXTRACT_24BITS(&ack_high) & 0xFFFFFF; + + if (DCCPH_X(dh) != 0) { + u_int32_t ack_low; + + TCHECK2(*dh_ack,8); + ack_low = dh_ack->dccph_ack_nr_low; + + ackno &= 0x00FFFF; /* clear reserved field */ + ackno = (ackno << 32) + EXTRACT_32BITS(&ack_low); + } + + (void)printf("(ack=%" PRIu64 ") ", ackno); +trunc: + return; +} + +static inline unsigned int dccp_packet_hdr_len(const u_int8_t type) +{ + if (type == DCCP_PKT_DATA) + return 0; + if (type == DCCP_PKT_DATAACK || + type == DCCP_PKT_ACK || + type == DCCP_PKT_SYNC || + type == DCCP_PKT_SYNCACK || + type == DCCP_PKT_CLOSE || + type == DCCP_PKT_CLOSEREQ) + return sizeof(struct dccp_hdr_ack_bits); + if (type == DCCP_PKT_REQUEST) + return sizeof(struct dccp_hdr_request); + if (type == DCCP_PKT_RESPONSE) + return sizeof(struct dccp_hdr_response); + return sizeof(struct dccp_hdr_reset); +} + +static int dccp_print_option(const u_char *option); + +/** + * dccp_print - show dccp packet + * @bp - beginning of dccp packet + * @data2 - beginning of enclosing + * @len - lenght of ip packet + */ +void dccp_print(const u_char *bp, const u_char *data2, u_int len) +{ + const struct dccp_hdr *dh; + const struct ip *ip; +#ifdef INET6 + const struct ip6_hdr *ip6; +#endif + const u_char *cp; + u_short sport, dport; + u_int hlen; + u_int extlen = 0; + + dh = (const struct dccp_hdr *)bp; + + ip = (struct ip *)data2; +#ifdef INET6 + if (IP_V(ip) == 6) + ip6 = (const struct ip6_hdr *)data2; + else + ip6 = NULL; +#endif /*INET6*/ + cp = (const u_char *)(dh + 1); + if (cp > snapend) { + printf("[Invalid packet|dccp]"); + return; + } + + if (len < sizeof(struct dccp_hdr)) { + printf("truncated-dccp - %ld bytes missing!", + (long)len - sizeof(struct dccp_hdr)); + return; + } + + sport = EXTRACT_16BITS(&dh->dccph_sport); + dport = EXTRACT_16BITS(&dh->dccph_dport); + hlen = dh->dccph_doff * 4; + +#ifdef INET6 + if (ip6) { + (void)printf("%s.%d > %s.%d: ", + ip6addr_string(&ip6->ip6_src), sport, + ip6addr_string(&ip6->ip6_dst), dport); + } else +#endif /*INET6*/ + { + (void)printf("%s.%d > %s.%d: ", + ipaddr_string(&ip->ip_src), sport, + ipaddr_string(&ip->ip_dst), dport); + } + fflush(stdout); + + if (qflag) { + (void)printf(" %d", len - hlen); + if (hlen > len) { + (void)printf("dccp [bad hdr length %u - too long, > %u]", + hlen, len); + } + return; + } + + /* other variables in generic header */ + if (vflag) { + (void)printf("CCVal %d, CsCov %d, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh)); + } + + /* checksum calculation */ + if (vflag && TTEST2(bp[0], len)) { + u_int16_t sum = 0, dccp_sum; + + dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum); + (void)printf("cksum 0x%04x ", dccp_sum); + if (IP_V(ip) == 4) + sum = dccp_cksum(ip, dh, len); +#ifdef INET6 + else if (IP_V(ip) == 6) + sum = dccp6_cksum(ip6, dh, len); +#endif + if (sum != 0) + (void)printf("(incorrect -> 0x%04x), ",in_cksum_shouldbe(dccp_sum, sum)); + else + (void)printf("(correct), "); + } + + switch (DCCPH_TYPE(dh)) { + case DCCP_PKT_REQUEST: { + struct dccp_hdr_request *dhr = + (struct dccp_hdr_request *)(bp + dccp_basic_hdr_len(dh)); + TCHECK(*dhr); + (void)printf("request (service=%d) ", + EXTRACT_32BITS(&dhr->dccph_req_service)); + extlen += 4; + break; + } + case DCCP_PKT_RESPONSE: { + struct dccp_hdr_response *dhr = + (struct dccp_hdr_response *)(bp + dccp_basic_hdr_len(dh)); + TCHECK(*dhr); + (void)printf("response (service=%d) ", + EXTRACT_32BITS(&dhr->dccph_resp_service)); + extlen += 12; + break; + } + case DCCP_PKT_DATA: + (void)printf("data "); + break; + case DCCP_PKT_ACK: { + (void)printf("ack "); + extlen += 8; + break; + } + case DCCP_PKT_DATAACK: { + (void)printf("dataack "); + extlen += 8; + break; + } + case DCCP_PKT_CLOSEREQ: + (void)printf("closereq "); + extlen += 8; + break; + case DCCP_PKT_CLOSE: + (void)printf("close "); + extlen += 8; + break; + case DCCP_PKT_RESET: { + struct dccp_hdr_reset *dhr = + (struct dccp_hdr_reset *)(bp + dccp_basic_hdr_len(dh)); + TCHECK(*dhr); + (void)printf("reset (code=%s) ", + dccp_reset_code(dhr->dccph_reset_code)); + extlen += 12; + break; + } + case DCCP_PKT_SYNC: + (void)printf("sync "); + extlen += 8; + break; + case DCCP_PKT_SYNCACK: + (void)printf("syncack "); + extlen += 8; + break; + default: + (void)printf("invalid "); + break; + } + + if ((DCCPH_TYPE(dh) != DCCP_PKT_DATA) && + (DCCPH_TYPE(dh) != DCCP_PKT_REQUEST)) + dccp_print_ack_no(bp); + + if (vflag < 2) + return; + + (void)printf("seq %" PRIu64, dccp_seqno(dh)); + + /* process options */ + if (hlen > dccp_basic_hdr_len(dh) + extlen){ + const u_char *cp; + u_int optlen; + cp = bp + dccp_basic_hdr_len(dh) + extlen; + printf(" <"); + + hlen -= dccp_basic_hdr_len(dh) + extlen; + while(1){ + TCHECK(*cp); + optlen = dccp_print_option(cp); + if (!optlen) goto trunc2; + if (hlen <= optlen) break; + hlen -= optlen; + cp += optlen; + printf(", "); + } + printf(">"); + } + return; +trunc: + printf("[|dccp]"); +trunc2: + return; +} + +static int dccp_print_option(const u_char *option) +{ + u_int8_t optlen, i; + + TCHECK(*option); + + if (*option >= 32) { + TCHECK(*(option+1)); + optlen = *(option +1); + if (optlen < 2) { + printf("Option %d optlen too short",*option); + return 1; + } + } else optlen = 1; + + TCHECK2(*option,optlen); + + switch (*option){ + case 0: + printf("nop"); + break; + case 1: + printf("mandatory"); + break; + case 2: + printf("slowreceiver"); + break; + case 32: + printf("change_l"); + if (*(option +2) < 10){ + printf(" %s", dccp_feature_nums[*(option +2)]); + for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i)); + } + break; + case 33: + printf("confirm_l"); + if (*(option +2) < 10){ + printf(" %s", dccp_feature_nums[*(option +2)]); + for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i)); + } + break; + case 34: + printf("change_r"); + if (*(option +2) < 10){ + printf(" %s", dccp_feature_nums[*(option +2)]); + for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i)); + } + break; + case 35: + printf("confirm_r"); + if (*(option +2) < 10){ + printf(" %s", dccp_feature_nums[*(option +2)]); + for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i)); + } + break; + case 36: + printf("initcookie 0x"); + for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i)); + break; + case 37: + printf("ndp_count"); + for (i = 0; i < optlen -2; i ++) printf(" %d", *(option +2 + i)); + break; + case 38: + printf("ack_vector0 0x"); + for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i)); + break; + case 39: + printf("ack_vector1 0x"); + for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i)); + break; + case 40: + printf("data_dropped 0x"); + for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i)); + break; + case 41: + printf("timestamp %u", EXTRACT_32BITS(option + 2)); + break; + case 42: + printf("timestamp_echo %u", EXTRACT_32BITS(option + 2)); + break; + case 43: + printf("elapsed_time "); + if (optlen == 6) + printf("%u", EXTRACT_32BITS(option + 2)); + else + printf("%u", EXTRACT_16BITS(option + 2)); + break; + case 44: + printf("data_checksum "); + for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i)); + break; + default : + if (*option >= 128) { + printf("CCID option %d",*option); + switch (optlen) { + case 4: + printf(" %u", EXTRACT_16BITS(option + 2)); + break; + case 6: + printf(" %u", EXTRACT_32BITS(option + 2)); + break; + default: + break; + } + break; + } + + printf("unknown_opt %d", *option); + break; + } + + return optlen; +trunc: + printf("[|dccp]"); + return 0; +} diff --git a/print-decnet.c b/print-decnet.c new file mode 100644 index 0000000..7fea582 --- /dev/null +++ b/print-decnet.c @@ -0,0 +1,895 @@ +/* + * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-decnet.c,v 1.39 2005-05-06 02:16:26 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +struct mbuf; +struct rtentry; + +#ifdef HAVE_NETDNET_DNETDB_H +#include +#endif + +#include +#include +#include + +#include "decnet.h" +#include "extract.h" +#include "interface.h" +#include "addrtoname.h" + +/* Forwards */ +static int print_decnet_ctlmsg(const union routehdr *, u_int, u_int); +static void print_t_info(int); +static int print_l1_routes(const char *, u_int); +static int print_l2_routes(const char *, u_int); +static void print_i_info(int); +static int print_elist(const char *, u_int); +static int print_nsp(const u_char *, u_int); +static void print_reason(int); +#ifdef PRINT_NSPDATA +static void pdata(u_char *, int); +#endif + +#ifndef HAVE_NETDNET_DNETDB_H_DNET_HTOA +extern char *dnet_htoa(struct dn_naddr *); +#endif + +void +decnet_print(register const u_char *ap, register u_int length, + register u_int caplen) +{ + register const union routehdr *rhp; + register int mflags; + int dst, src, hops; + u_int nsplen, pktlen; + const u_char *nspp; + + if (length < sizeof(struct shorthdr)) { + (void)printf("[|decnet]"); + return; + } + + TCHECK2(*ap, sizeof(short)); + pktlen = EXTRACT_LE_16BITS(ap); + if (pktlen < sizeof(struct shorthdr)) { + (void)printf("[|decnet]"); + return; + } + if (pktlen > length) { + (void)printf("[|decnet]"); + return; + } + length = pktlen; + + rhp = (const union routehdr *)&(ap[sizeof(short)]); + TCHECK(rhp->rh_short.sh_flags); + mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); + + if (mflags & RMF_PAD) { + /* pad bytes of some sort in front of message */ + u_int padlen = mflags & RMF_PADMASK; + if (vflag) + (void) printf("[pad:%d] ", padlen); + if (length < padlen + 2) { + (void)printf("[|decnet]"); + return; + } + TCHECK2(ap[sizeof(short)], padlen); + ap += padlen; + length -= padlen; + caplen -= padlen; + rhp = (const union routehdr *)&(ap[sizeof(short)]); + mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); + } + + if (mflags & RMF_FVER) { + (void) printf("future-version-decnet"); + default_print(ap, min(length, caplen)); + return; + } + + /* is it a control message? */ + if (mflags & RMF_CTLMSG) { + if (!print_decnet_ctlmsg(rhp, length, caplen)) + goto trunc; + return; + } + + switch (mflags & RMF_MASK) { + case RMF_LONG: + if (length < sizeof(struct longhdr)) { + (void)printf("[|decnet]"); + return; + } + TCHECK(rhp->rh_long); + dst = + EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr); + src = + EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr); + hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits); + nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]); + nsplen = length - sizeof(struct longhdr); + break; + case RMF_SHORT: + TCHECK(rhp->rh_short); + dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst); + src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src); + hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1; + nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]); + nsplen = length - sizeof(struct shorthdr); + break; + default: + (void) printf("unknown message flags under mask"); + default_print((u_char *)ap, min(length, caplen)); + return; + } + + (void)printf("%s > %s %d ", + dnaddr_string(src), dnaddr_string(dst), pktlen); + if (vflag) { + if (mflags & RMF_RQR) + (void)printf("RQR "); + if (mflags & RMF_RTS) + (void)printf("RTS "); + if (mflags & RMF_IE) + (void)printf("IE "); + (void)printf("%d hops ", hops); + } + + if (!print_nsp(nspp, nsplen)) + goto trunc; + return; + +trunc: + (void)printf("[|decnet]"); + return; +} + +static int +print_decnet_ctlmsg(register const union routehdr *rhp, u_int length, + u_int caplen) +{ + int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); + register union controlmsg *cmp = (union controlmsg *)rhp; + int src, dst, info, blksize, eco, ueco, hello, other, vers; + etheraddr srcea, rtea; + int priority; + char *rhpx = (char *)rhp; + int ret; + + switch (mflags & RMF_CTLMASK) { + case RMF_INIT: + (void)printf("init "); + if (length < sizeof(struct initmsg)) + goto trunc; + TCHECK(cmp->cm_init); + src = EXTRACT_LE_16BITS(cmp->cm_init.in_src); + info = EXTRACT_LE_8BITS(cmp->cm_init.in_info); + blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize); + vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers); + eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco); + ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco); + hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello); + print_t_info(info); + (void)printf( + "src %sblksize %d vers %d eco %d ueco %d hello %d", + dnaddr_string(src), blksize, vers, eco, ueco, + hello); + ret = 1; + break; + case RMF_VER: + (void)printf("verification "); + if (length < sizeof(struct verifmsg)) + goto trunc; + TCHECK(cmp->cm_ver); + src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src); + other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval); + (void)printf("src %s fcnval %o", dnaddr_string(src), other); + ret = 1; + break; + case RMF_TEST: + (void)printf("test "); + if (length < sizeof(struct testmsg)) + goto trunc; + TCHECK(cmp->cm_test); + src = EXTRACT_LE_16BITS(cmp->cm_test.te_src); + other = EXTRACT_LE_8BITS(cmp->cm_test.te_data); + (void)printf("src %s data %o", dnaddr_string(src), other); + ret = 1; + break; + case RMF_L1ROUT: + (void)printf("lev-1-routing "); + if (length < sizeof(struct l1rout)) + goto trunc; + TCHECK(cmp->cm_l1rou); + src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src); + (void)printf("src %s ", dnaddr_string(src)); + ret = print_l1_routes(&(rhpx[sizeof(struct l1rout)]), + length - sizeof(struct l1rout)); + break; + case RMF_L2ROUT: + (void)printf("lev-2-routing "); + if (length < sizeof(struct l2rout)) + goto trunc; + TCHECK(cmp->cm_l2rout); + src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src); + (void)printf("src %s ", dnaddr_string(src)); + ret = print_l2_routes(&(rhpx[sizeof(struct l2rout)]), + length - sizeof(struct l2rout)); + break; + case RMF_RHELLO: + (void)printf("router-hello "); + if (length < sizeof(struct rhellomsg)) + goto trunc; + TCHECK(cmp->cm_rhello); + vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers); + eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco); + ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco); + memcpy((char *)&srcea, (char *)&(cmp->cm_rhello.rh_src), + sizeof(srcea)); + src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); + info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info); + blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize); + priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority); + hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello); + print_i_info(info); + (void)printf( + "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d", + vers, eco, ueco, dnaddr_string(src), + blksize, priority, hello); + ret = print_elist(&(rhpx[sizeof(struct rhellomsg)]), + length - sizeof(struct rhellomsg)); + break; + case RMF_EHELLO: + (void)printf("endnode-hello "); + if (length < sizeof(struct ehellomsg)) + goto trunc; + TCHECK(cmp->cm_ehello); + vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers); + eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco); + ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco); + memcpy((char *)&srcea, (char *)&(cmp->cm_ehello.eh_src), + sizeof(srcea)); + src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); + info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info); + blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize); + /*seed*/ + memcpy((char *)&rtea, (char *)&(cmp->cm_ehello.eh_router), + sizeof(rtea)); + dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr); + hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello); + other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data); + print_i_info(info); + (void)printf( + "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o", + vers, eco, ueco, dnaddr_string(src), + blksize, dnaddr_string(dst), hello, other); + ret = 1; + break; + + default: + (void)printf("unknown control message"); + default_print((u_char *)rhp, min(length, caplen)); + ret = 1; + break; + } + return (ret); + +trunc: + return (0); +} + +static void +print_t_info(int info) +{ + int ntype = info & 3; + switch (ntype) { + case 0: (void)printf("reserved-ntype? "); break; + case TI_L2ROUT: (void)printf("l2rout "); break; + case TI_L1ROUT: (void)printf("l1rout "); break; + case TI_ENDNODE: (void)printf("endnode "); break; + } + if (info & TI_VERIF) + (void)printf("verif "); + if (info & TI_BLOCK) + (void)printf("blo "); +} + +static int +print_l1_routes(const char *rp, u_int len) +{ + int count; + int id; + int info; + + /* The last short is a checksum */ + while (len > (3 * sizeof(short))) { + TCHECK2(*rp, 3 * sizeof(short)); + count = EXTRACT_LE_16BITS(rp); + if (count > 1024) + return (1); /* seems to be bogus from here on */ + rp += sizeof(short); + len -= sizeof(short); + id = EXTRACT_LE_16BITS(rp); + rp += sizeof(short); + len -= sizeof(short); + info = EXTRACT_LE_16BITS(rp); + rp += sizeof(short); + len -= sizeof(short); + (void)printf("{ids %d-%d cost %d hops %d} ", id, id + count, + RI_COST(info), RI_HOPS(info)); + } + return (1); + +trunc: + return (0); +} + +static int +print_l2_routes(const char *rp, u_int len) +{ + int count; + int area; + int info; + + /* The last short is a checksum */ + while (len > (3 * sizeof(short))) { + TCHECK2(*rp, 3 * sizeof(short)); + count = EXTRACT_LE_16BITS(rp); + if (count > 1024) + return (1); /* seems to be bogus from here on */ + rp += sizeof(short); + len -= sizeof(short); + area = EXTRACT_LE_16BITS(rp); + rp += sizeof(short); + len -= sizeof(short); + info = EXTRACT_LE_16BITS(rp); + rp += sizeof(short); + len -= sizeof(short); + (void)printf("{areas %d-%d cost %d hops %d} ", area, area + count, + RI_COST(info), RI_HOPS(info)); + } + return (1); + +trunc: + return (0); +} + +static void +print_i_info(int info) +{ + int ntype = info & II_TYPEMASK; + switch (ntype) { + case 0: (void)printf("reserved-ntype? "); break; + case II_L2ROUT: (void)printf("l2rout "); break; + case II_L1ROUT: (void)printf("l1rout "); break; + case II_ENDNODE: (void)printf("endnode "); break; + } + if (info & II_VERIF) + (void)printf("verif "); + if (info & II_NOMCAST) + (void)printf("nomcast "); + if (info & II_BLOCK) + (void)printf("blo "); +} + +static int +print_elist(const char *elp _U_, u_int len _U_) +{ + /* Not enough examples available for me to debug this */ + return (1); +} + +static int +print_nsp(const u_char *nspp, u_int nsplen) +{ + const struct nsphdr *nsphp = (struct nsphdr *)nspp; + int dst, src, flags; + + if (nsplen < sizeof(struct nsphdr)) + goto trunc; + TCHECK(*nsphp); + flags = EXTRACT_LE_8BITS(nsphp->nh_flags); + dst = EXTRACT_LE_16BITS(nsphp->nh_dst); + src = EXTRACT_LE_16BITS(nsphp->nh_src); + + switch (flags & NSP_TYPEMASK) { + case MFT_DATA: + switch (flags & NSP_SUBMASK) { + case MFS_BOM: + case MFS_MOM: + case MFS_EOM: + case MFS_BOM+MFS_EOM: + printf("data %d>%d ", src, dst); + { + struct seghdr *shp = (struct seghdr *)nspp; + int ack; +#ifdef PRINT_NSPDATA + u_char *dp; +#endif + u_int data_off = sizeof(struct minseghdr); + + if (nsplen < data_off) + goto trunc; + TCHECK(shp->sh_seq[0]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); + if (ack & SGQ_ACK) { /* acknum field */ + if ((ack & SGQ_NAK) == SGQ_NAK) + (void)printf("nak %d ", ack & SGQ_MASK); + else + (void)printf("ack %d ", ack & SGQ_MASK); + data_off += sizeof(short); + if (nsplen < data_off) + goto trunc; + TCHECK(shp->sh_seq[1]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); + if (ack & SGQ_OACK) { /* ackoth field */ + if ((ack & SGQ_ONAK) == SGQ_ONAK) + (void)printf("onak %d ", ack & SGQ_MASK); + else + (void)printf("oack %d ", ack & SGQ_MASK); + data_off += sizeof(short); + if (nsplen < data_off) + goto trunc; + TCHECK(shp->sh_seq[2]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); + } + } + (void)printf("seg %d ", ack & SGQ_MASK); +#ifdef PRINT_NSPDATA + if (nsplen > data_off) { + dp = &(nspp[data_off]); + TCHECK2(*dp, nsplen - data_off); + pdata(dp, nsplen - data_off); + } +#endif + } + break; + case MFS_ILS+MFS_INT: + printf("intr "); + { + struct seghdr *shp = (struct seghdr *)nspp; + int ack; +#ifdef PRINT_NSPDATA + u_char *dp; +#endif + u_int data_off = sizeof(struct minseghdr); + + if (nsplen < data_off) + goto trunc; + TCHECK(shp->sh_seq[0]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); + if (ack & SGQ_ACK) { /* acknum field */ + if ((ack & SGQ_NAK) == SGQ_NAK) + (void)printf("nak %d ", ack & SGQ_MASK); + else + (void)printf("ack %d ", ack & SGQ_MASK); + data_off += sizeof(short); + if (nsplen < data_off) + goto trunc; + TCHECK(shp->sh_seq[1]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); + if (ack & SGQ_OACK) { /* ackdat field */ + if ((ack & SGQ_ONAK) == SGQ_ONAK) + (void)printf("nakdat %d ", ack & SGQ_MASK); + else + (void)printf("ackdat %d ", ack & SGQ_MASK); + data_off += sizeof(short); + if (nsplen < data_off) + goto trunc; + TCHECK(shp->sh_seq[2]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); + } + } + (void)printf("seg %d ", ack & SGQ_MASK); +#ifdef PRINT_NSPDATA + if (nsplen > data_off) { + dp = &(nspp[data_off]); + TCHECK2(*dp, nsplen - data_off); + pdata(dp, nsplen - data_off); + } +#endif + } + break; + case MFS_ILS: + (void)printf("link-service %d>%d ", src, dst); + { + struct seghdr *shp = (struct seghdr *)nspp; + struct lsmsg *lsmp = + (struct lsmsg *)&(nspp[sizeof(struct seghdr)]); + int ack; + int lsflags, fcval; + + if (nsplen < sizeof(struct seghdr) + sizeof(struct lsmsg)) + goto trunc; + TCHECK(shp->sh_seq[0]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); + if (ack & SGQ_ACK) { /* acknum field */ + if ((ack & SGQ_NAK) == SGQ_NAK) + (void)printf("nak %d ", ack & SGQ_MASK); + else + (void)printf("ack %d ", ack & SGQ_MASK); + TCHECK(shp->sh_seq[1]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); + if (ack & SGQ_OACK) { /* ackdat field */ + if ((ack & SGQ_ONAK) == SGQ_ONAK) + (void)printf("nakdat %d ", ack & SGQ_MASK); + else + (void)printf("ackdat %d ", ack & SGQ_MASK); + TCHECK(shp->sh_seq[2]); + ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); + } + } + (void)printf("seg %d ", ack & SGQ_MASK); + TCHECK(*lsmp); + lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags); + fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval); + switch (lsflags & LSI_MASK) { + case LSI_DATA: + (void)printf("dat seg count %d ", fcval); + switch (lsflags & LSM_MASK) { + case LSM_NOCHANGE: + break; + case LSM_DONOTSEND: + (void)printf("donotsend-data "); + break; + case LSM_SEND: + (void)printf("send-data "); + break; + default: + (void)printf("reserved-fcmod? %x", lsflags); + break; + } + break; + case LSI_INTR: + (void)printf("intr req count %d ", fcval); + break; + default: + (void)printf("reserved-fcval-int? %x", lsflags); + break; + } + } + break; + default: + (void)printf("reserved-subtype? %x %d > %d", flags, src, dst); + break; + } + break; + case MFT_ACK: + switch (flags & NSP_SUBMASK) { + case MFS_DACK: + (void)printf("data-ack %d>%d ", src, dst); + { + struct ackmsg *amp = (struct ackmsg *)nspp; + int ack; + + if (nsplen < sizeof(struct ackmsg)) + goto trunc; + TCHECK(*amp); + ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); + if (ack & SGQ_ACK) { /* acknum field */ + if ((ack & SGQ_NAK) == SGQ_NAK) + (void)printf("nak %d ", ack & SGQ_MASK); + else + (void)printf("ack %d ", ack & SGQ_MASK); + ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); + if (ack & SGQ_OACK) { /* ackoth field */ + if ((ack & SGQ_ONAK) == SGQ_ONAK) + (void)printf("onak %d ", ack & SGQ_MASK); + else + (void)printf("oack %d ", ack & SGQ_MASK); + } + } + } + break; + case MFS_IACK: + (void)printf("ils-ack %d>%d ", src, dst); + { + struct ackmsg *amp = (struct ackmsg *)nspp; + int ack; + + if (nsplen < sizeof(struct ackmsg)) + goto trunc; + TCHECK(*amp); + ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); + if (ack & SGQ_ACK) { /* acknum field */ + if ((ack & SGQ_NAK) == SGQ_NAK) + (void)printf("nak %d ", ack & SGQ_MASK); + else + (void)printf("ack %d ", ack & SGQ_MASK); + TCHECK(amp->ak_acknum[1]); + ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); + if (ack & SGQ_OACK) { /* ackdat field */ + if ((ack & SGQ_ONAK) == SGQ_ONAK) + (void)printf("nakdat %d ", ack & SGQ_MASK); + else + (void)printf("ackdat %d ", ack & SGQ_MASK); + } + } + } + break; + case MFS_CACK: + (void)printf("conn-ack %d", dst); + break; + default: + (void)printf("reserved-acktype? %x %d > %d", flags, src, dst); + break; + } + break; + case MFT_CTL: + switch (flags & NSP_SUBMASK) { + case MFS_CI: + case MFS_RCI: + if ((flags & NSP_SUBMASK) == MFS_CI) + (void)printf("conn-initiate "); + else + (void)printf("retrans-conn-initiate "); + (void)printf("%d>%d ", src, dst); + { + struct cimsg *cimp = (struct cimsg *)nspp; + int services, info, segsize; +#ifdef PRINT_NSPDATA + u_char *dp; +#endif + + if (nsplen < sizeof(struct cimsg)) + goto trunc; + TCHECK(*cimp); + services = EXTRACT_LE_8BITS(cimp->ci_services); + info = EXTRACT_LE_8BITS(cimp->ci_info); + segsize = EXTRACT_LE_16BITS(cimp->ci_segsize); + + switch (services & COS_MASK) { + case COS_NONE: + break; + case COS_SEGMENT: + (void)printf("seg "); + break; + case COS_MESSAGE: + (void)printf("msg "); + break; + case COS_CRYPTSER: + (void)printf("crypt "); + break; + } + switch (info & COI_MASK) { + case COI_32: + (void)printf("ver 3.2 "); + break; + case COI_31: + (void)printf("ver 3.1 "); + break; + case COI_40: + (void)printf("ver 4.0 "); + break; + case COI_41: + (void)printf("ver 4.1 "); + break; + } + (void)printf("segsize %d ", segsize); +#ifdef PRINT_NSPDATA + if (nsplen > sizeof(struct cimsg)) { + dp = &(nspp[sizeof(struct cimsg)]); + TCHECK2(*dp, nsplen - sizeof(struct cimsg)); + pdata(dp, nsplen - sizeof(struct cimsg)); + } +#endif + } + break; + case MFS_CC: + (void)printf("conn-confirm %d>%d ", src, dst); + { + struct ccmsg *ccmp = (struct ccmsg *)nspp; + int services, info; + u_int segsize, optlen; +#ifdef PRINT_NSPDATA + u_char *dp; +#endif + + if (nsplen < sizeof(struct ccmsg)) + goto trunc; + TCHECK(*ccmp); + services = EXTRACT_LE_8BITS(ccmp->cc_services); + info = EXTRACT_LE_8BITS(ccmp->cc_info); + segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize); + optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen); + + switch (services & COS_MASK) { + case COS_NONE: + break; + case COS_SEGMENT: + (void)printf("seg "); + break; + case COS_MESSAGE: + (void)printf("msg "); + break; + case COS_CRYPTSER: + (void)printf("crypt "); + break; + } + switch (info & COI_MASK) { + case COI_32: + (void)printf("ver 3.2 "); + break; + case COI_31: + (void)printf("ver 3.1 "); + break; + case COI_40: + (void)printf("ver 4.0 "); + break; + case COI_41: + (void)printf("ver 4.1 "); + break; + } + (void)printf("segsize %d ", segsize); + if (optlen) { + (void)printf("optlen %d ", optlen); +#ifdef PRINT_NSPDATA + if (optlen > nsplen - sizeof(struct ccmsg)) + goto trunc; + dp = &(nspp[sizeof(struct ccmsg)]); + TCHECK2(*dp, optlen); + pdata(dp, optlen); +#endif + } + } + break; + case MFS_DI: + (void)printf("disconn-initiate %d>%d ", src, dst); + { + struct dimsg *dimp = (struct dimsg *)nspp; + int reason; + u_int optlen; +#ifdef PRINT_NSPDATA + u_char *dp; +#endif + + if (nsplen < sizeof(struct dimsg)) + goto trunc; + TCHECK(*dimp); + reason = EXTRACT_LE_16BITS(dimp->di_reason); + optlen = EXTRACT_LE_8BITS(dimp->di_optlen); + + print_reason(reason); + if (optlen) { + (void)printf("optlen %d ", optlen); +#ifdef PRINT_NSPDATA + if (optlen > nsplen - sizeof(struct dimsg)) + goto trunc; + dp = &(nspp[sizeof(struct dimsg)]); + TCHECK2(*dp, optlen); + pdata(dp, optlen); +#endif + } + } + break; + case MFS_DC: + (void)printf("disconn-confirm %d>%d ", src, dst); + { + struct dcmsg *dcmp = (struct dcmsg *)nspp; + int reason; + + TCHECK(*dcmp); + reason = EXTRACT_LE_16BITS(dcmp->dc_reason); + + print_reason(reason); + } + break; + default: + (void)printf("reserved-ctltype? %x %d > %d", flags, src, dst); + break; + } + break; + default: + (void)printf("reserved-type? %x %d > %d", flags, src, dst); + break; + } + return (1); + +trunc: + return (0); +} + +static struct tok reason2str[] = { + { UC_OBJREJECT, "object rejected connect" }, + { UC_RESOURCES, "insufficient resources" }, + { UC_NOSUCHNODE, "unrecognized node name" }, + { DI_SHUT, "node is shutting down" }, + { UC_NOSUCHOBJ, "unrecognized object" }, + { UC_INVOBJFORMAT, "invalid object name format" }, + { UC_OBJTOOBUSY, "object too busy" }, + { DI_PROTOCOL, "protocol error discovered" }, + { DI_TPA, "third party abort" }, + { UC_USERABORT, "user abort" }, + { UC_INVNODEFORMAT, "invalid node name format" }, + { UC_LOCALSHUT, "local node shutting down" }, + { DI_LOCALRESRC, "insufficient local resources" }, + { DI_REMUSERRESRC, "insufficient remote user resources" }, + { UC_ACCESSREJECT, "invalid access control information" }, + { DI_BADACCNT, "bad ACCOUNT information" }, + { UC_NORESPONSE, "no response from object" }, + { UC_UNREACHABLE, "node unreachable" }, + { DC_NOLINK, "no link terminate" }, + { DC_COMPLETE, "disconnect complete" }, + { DI_BADIMAGE, "bad image data in connect" }, + { DI_SERVMISMATCH, "cryptographic service mismatch" }, + { 0, NULL } +}; + +static void +print_reason(register int reason) +{ + printf("%s ", tok2str(reason2str, "reason-%d", reason)); +} + +const char * +dnnum_string(u_short dnaddr) +{ + char *str; + size_t siz; + int area = (u_short)(dnaddr & AREAMASK) >> AREASHIFT; + int node = dnaddr & NODEMASK; + + str = (char *)malloc(siz = sizeof("00.0000")); + if (str == NULL) + error("dnnum_string: malloc"); + snprintf(str, siz, "%d.%d", area, node); + return(str); +} + +const char * +dnname_string(u_short dnaddr) +{ +#ifdef HAVE_DNET_HTOA + struct dn_naddr dna; + + dna.a_len = sizeof(short); + memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short)); + return (strdup(dnet_htoa(&dna))); +#else + return(dnnum_string(dnaddr)); /* punt */ +#endif +} + +#ifdef PRINT_NSPDATA +static void +pdata(u_char *dp, u_int maxlen) +{ + char c; + u_int x = maxlen; + + while (x-- > 0) { + c = *dp++; + safeputchar(c); + } +} +#endif diff --git a/print-dhcp6.c b/print-dhcp6.c new file mode 100644 index 0000000..26855cc --- /dev/null +++ b/print-dhcp6.c @@ -0,0 +1,840 @@ +/* + * Copyright (C) 1998 and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * RFC3315: DHCPv6 + * supported DHCPv6 options: + * RFC3319, + * RFC3633, + * RFC3646, + * RFC3898, + * RFC4075, + * RFC4242, + * RFC4280, + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.37 2008-02-06 10:26:09 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +/* lease duration */ +#define DHCP6_DURATITION_INFINITE 0xffffffff + +/* Error Values */ +#define DH6ERR_FAILURE 16 +#define DH6ERR_AUTHFAIL 17 +#define DH6ERR_POORLYFORMED 18 +#define DH6ERR_UNAVAIL 19 +#define DH6ERR_OPTUNAVAIL 20 + +/* Message type */ +#define DH6_SOLICIT 1 +#define DH6_ADVERTISE 2 +#define DH6_REQUEST 3 +#define DH6_CONFIRM 4 +#define DH6_RENEW 5 +#define DH6_REBIND 6 +#define DH6_REPLY 7 +#define DH6_RELEASE 8 +#define DH6_DECLINE 9 +#define DH6_RECONFIGURE 10 +#define DH6_INFORM_REQ 11 +#define DH6_RELAY_FORW 12 +#define DH6_RELAY_REPLY 13 +#define DH6_LEASEQUERY 14 +#define DH6_LQ_REPLY 15 + +/* DHCP6 base packet format */ +struct dhcp6 { + union { + u_int8_t m; + u_int32_t x; + } dh6_msgtypexid; + /* options follow */ +}; +#define dh6_msgtype dh6_msgtypexid.m +#define dh6_xid dh6_msgtypexid.x +#define DH6_XIDMASK 0x00ffffff + +/* DHCPv6 relay messages */ +struct dhcp6_relay { + u_int8_t dh6relay_msgtype; + u_int8_t dh6relay_hcnt; + u_int8_t dh6relay_linkaddr[16]; /* XXX: badly aligned */ + u_int8_t dh6relay_peeraddr[16]; + /* options follow */ +}; + +/* options */ +#define DH6OPT_CLIENTID 1 +#define DH6OPT_SERVERID 2 +#define DH6OPT_IA_NA 3 +#define DH6OPT_IA_TA 4 +#define DH6OPT_IA_ADDR 5 +#define DH6OPT_ORO 6 +#define DH6OPT_PREFERENCE 7 +# define DH6OPT_PREF_MAX 255 +#define DH6OPT_ELAPSED_TIME 8 +#define DH6OPT_RELAY_MSG 9 +/*#define DH6OPT_SERVER_MSG 10 deprecated */ +#define DH6OPT_AUTH 11 +# define DH6OPT_AUTHPROTO_DELAYED 2 +# define DH6OPT_AUTHPROTO_RECONFIG 3 +# define DH6OPT_AUTHALG_HMACMD5 1 +# define DH6OPT_AUTHRDM_MONOCOUNTER 0 +# define DH6OPT_AUTHRECONFIG_KEY 1 +# define DH6OPT_AUTHRECONFIG_HMACMD5 2 +#define DH6OPT_UNICAST 12 +#define DH6OPT_STATUS_CODE 13 +# define DH6OPT_STCODE_SUCCESS 0 +# define DH6OPT_STCODE_UNSPECFAIL 1 +# define DH6OPT_STCODE_NOADDRAVAIL 2 +# define DH6OPT_STCODE_NOBINDING 3 +# define DH6OPT_STCODE_NOTONLINK 4 +# define DH6OPT_STCODE_USEMULTICAST 5 +# define DH6OPT_STCODE_NOPREFIXAVAIL 6 +# define DH6OPT_STCODE_UNKNOWNQUERYTYPE 7 +# define DH6OPT_STCODE_MALFORMEDQUERY 8 +# define DH6OPT_STCODE_NOTCONFIGURED 9 +# define DH6OPT_STCODE_NOTALLOWED 10 +#define DH6OPT_RAPID_COMMIT 14 +#define DH6OPT_USER_CLASS 15 +#define DH6OPT_VENDOR_CLASS 16 +#define DH6OPT_VENDOR_OPTS 17 +#define DH6OPT_INTERFACE_ID 18 +#define DH6OPT_RECONF_MSG 19 +#define DH6OPT_RECONF_ACCEPT 20 +#define DH6OPT_SIP_SERVER_D 21 +#define DH6OPT_SIP_SERVER_A 22 +#define DH6OPT_DNS 23 +#define DH6OPT_DNSNAME 24 +#define DH6OPT_IA_PD 25 +#define DH6OPT_IA_PD_PREFIX 26 +#define DH6OPT_NIS_SERVERS 27 +#define DH6OPT_NISP_SERVERS 28 +#define DH6OPT_NIS_NAME 29 +#define DH6OPT_NISP_NAME 30 +#define DH6OPT_NTP_SERVERS 31 +#define DH6OPT_LIFETIME 32 +#define DH6OPT_BCMCS_SERVER_D 33 +#define DH6OPT_BCMCS_SERVER_A 34 +#define DH6OPT_GEOCONF_CIVIC 36 +#define DH6OPT_REMOTE_ID 37 +#define DH6OPT_SUBSCRIBER_ID 38 +#define DH6OPT_CLIENT_FQDN 39 +#define DH6OPT_PANA_AGENT 40 +#define DH6OPT_NEW_POSIX_TIMEZONE 41 +#define DH6OPT_NEW_TZDB_TIMEZONE 42 +#define DH6OPT_ERO 43 +#define DH6OPT_LQ_QUERY 44 +#define DH6OPT_CLIENT_DATA 45 +#define DH6OPT_CLT_TIME 46 +#define DH6OPT_LQ_RELAY_DATA 47 +#define DH6OPT_LQ_CLIENT_LINK 48 + +struct dhcp6opt { + u_int16_t dh6opt_type; + u_int16_t dh6opt_len; + /* type-dependent data follows */ +}; + +static const char * +dhcp6opt_name(int type) +{ + static char genstr[sizeof("opt_65535") + 1]; /* XXX thread unsafe */ + + if (type > 65535) + return "INVALID-option"; + + switch(type) { + case DH6OPT_CLIENTID: + return "client-ID"; + case DH6OPT_SERVERID: + return "server-ID"; + case DH6OPT_IA_NA: + return "IA_NA"; + case DH6OPT_IA_TA: + return "IA_TA"; + case DH6OPT_IA_ADDR: + return "IA_ADDR"; + case DH6OPT_ORO: + return "option-request"; + case DH6OPT_PREFERENCE: + return "preference"; + case DH6OPT_ELAPSED_TIME: + return "elapsed-time"; + case DH6OPT_RELAY_MSG: + return "relay-message"; + case DH6OPT_AUTH: + return "authentication"; + case DH6OPT_UNICAST: + return "server-unicast"; + case DH6OPT_STATUS_CODE: + return "status-code"; + case DH6OPT_RAPID_COMMIT: + return "rapid-commit"; + case DH6OPT_USER_CLASS: + return "user-class"; + case DH6OPT_VENDOR_CLASS: + return "vendor-class"; + case DH6OPT_VENDOR_OPTS: + return "vendor-specific-info"; + case DH6OPT_INTERFACE_ID: + return "interface-ID"; + case DH6OPT_RECONF_MSG: + return "reconfigure-message"; + case DH6OPT_RECONF_ACCEPT: + return "reconfigure-accept"; + case DH6OPT_SIP_SERVER_D: + return "SIP-servers-domain"; + case DH6OPT_SIP_SERVER_A: + return "SIP-servers-address"; + case DH6OPT_DNS: + return "DNS"; + case DH6OPT_DNSNAME: + return "DNS-name"; + case DH6OPT_IA_PD: + return "IA_PD"; + case DH6OPT_IA_PD_PREFIX: + return "IA_PD-prefix"; + case DH6OPT_NTP_SERVERS: + return "NTP-Server"; + case DH6OPT_LIFETIME: + return "lifetime"; + case DH6OPT_NIS_SERVERS: + return "NIS-server"; + case DH6OPT_NISP_SERVERS: + return "NIS+-server"; + case DH6OPT_NIS_NAME: + return "NIS-domain-name"; + case DH6OPT_NISP_NAME: + return "NIS+-domain-name"; + case DH6OPT_BCMCS_SERVER_D: + return "BCMCS-domain-name"; + case DH6OPT_BCMCS_SERVER_A: + return "BCMCS-server"; + case DH6OPT_GEOCONF_CIVIC: + return "Geoconf-Civic"; + case DH6OPT_REMOTE_ID: + return "Remote-ID"; + case DH6OPT_SUBSCRIBER_ID: + return "Subscriber-ID"; + case DH6OPT_CLIENT_FQDN: + return "Client-FQDN"; + case DH6OPT_PANA_AGENT: + return "PANA-agent"; + case DH6OPT_NEW_POSIX_TIMEZONE: + return "POSIX-timezone"; + case DH6OPT_NEW_TZDB_TIMEZONE: + return "POSIX-tz-database"; + case DH6OPT_ERO: + return "Echo-request-option"; + case DH6OPT_LQ_QUERY: + return "Lease-query"; + case DH6OPT_CLIENT_DATA: + return "LQ-client-data"; + case DH6OPT_CLT_TIME: + return "Clt-time"; + case DH6OPT_LQ_RELAY_DATA: + return "LQ-relay-data"; + case DH6OPT_LQ_CLIENT_LINK: + return "LQ-client-link"; + default: + snprintf(genstr, sizeof(genstr), "opt_%d", type); + return(genstr); + } +} + +static const char * +dhcp6stcode(int code) +{ + static char genstr[sizeof("code255") + 1]; /* XXX thread unsafe */ + + if (code > 255) + return "INVALID code"; + + switch(code) { + case DH6OPT_STCODE_SUCCESS: + return "success"; + case DH6OPT_STCODE_UNSPECFAIL: + return "unspec failure"; + case DH6OPT_STCODE_NOADDRAVAIL: + return "no addresses"; + case DH6OPT_STCODE_NOBINDING: + return "no binding"; + case DH6OPT_STCODE_NOTONLINK: + return "not on-link"; + case DH6OPT_STCODE_USEMULTICAST: + return "use multicast"; + case DH6OPT_STCODE_NOPREFIXAVAIL: + return "no prefixes"; + case DH6OPT_STCODE_UNKNOWNQUERYTYPE: + return "unknown query type"; + case DH6OPT_STCODE_MALFORMEDQUERY: + return "malformed query"; + case DH6OPT_STCODE_NOTCONFIGURED: + return "not configured"; + case DH6OPT_STCODE_NOTALLOWED: + return "not allowed"; + default: + snprintf(genstr, sizeof(genstr), "code%d", code); + return(genstr); + } +} + +static void +dhcp6opt_print(const u_char *cp, const u_char *ep) +{ + struct dhcp6opt *dh6o; + u_char *tp; + size_t i; + u_int16_t opttype; + size_t optlen; + u_int8_t auth_proto; + u_int authinfolen, authrealmlen; + + if (cp == ep) + return; + while (cp < ep) { + if (ep < cp + sizeof(*dh6o)) + goto trunc; + dh6o = (struct dhcp6opt *)cp; + optlen = EXTRACT_16BITS(&dh6o->dh6opt_len); + if (ep < cp + sizeof(*dh6o) + optlen) + goto trunc; + opttype = EXTRACT_16BITS(&dh6o->dh6opt_type); + printf(" (%s", dhcp6opt_name(opttype)); + switch (opttype) { + case DH6OPT_CLIENTID: + case DH6OPT_SERVERID: + if (optlen < 2) { + /*(*/ + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + switch (EXTRACT_16BITS(tp)) { + case 1: + if (optlen >= 2 + 6) { + printf(" hwaddr/time type %u time %u ", + EXTRACT_16BITS(&tp[2]), + EXTRACT_32BITS(&tp[4])); + for (i = 8; i < optlen; i++) + printf("%02x", tp[i]); + /*(*/ + printf(")"); + } else { + /*(*/ + printf(" ?)"); + } + break; + case 2: + if (optlen >= 2 + 8) { + printf(" vid "); + for (i = 2; i < 2 + 8; i++) + printf("%02x", tp[i]); + /*(*/ + printf(")"); + } else { + /*(*/ + printf(" ?)"); + } + break; + case 3: + if (optlen >= 2 + 2) { + printf(" hwaddr type %u ", + EXTRACT_16BITS(&tp[2])); + for (i = 4; i < optlen; i++) + printf("%02x", tp[i]); + /*(*/ + printf(")"); + } else { + /*(*/ + printf(" ?)"); + } + break; + default: + printf(" type %d)", EXTRACT_16BITS(tp)); + break; + } + break; + case DH6OPT_IA_ADDR: + if (optlen < 24) { + /*(*/ + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" %s", ip6addr_string(&tp[0])); + printf(" pltime:%u vltime:%u", + EXTRACT_32BITS(&tp[16]), + EXTRACT_32BITS(&tp[20])); + if (optlen > 24) { + /* there are sub-options */ + dhcp6opt_print(tp + 24, tp + 24 + optlen); + } + printf(")"); + break; + case DH6OPT_ORO: + case DH6OPT_ERO: + if (optlen % 2) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + for (i = 0; i < optlen; i += 2) { + printf(" %s", + dhcp6opt_name(EXTRACT_16BITS(&tp[i]))); + } + printf(")"); + break; + case DH6OPT_PREFERENCE: + if (optlen != 1) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" %d)", *tp); + break; + case DH6OPT_ELAPSED_TIME: + if (optlen != 2) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" %d)", EXTRACT_16BITS(tp)); + break; + case DH6OPT_RELAY_MSG: + printf(" ("); + tp = (u_char *)(dh6o + 1); + dhcp6_print(tp, optlen); + printf(")"); + break; + case DH6OPT_AUTH: + if (optlen < 11) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + auth_proto = *tp; + switch (auth_proto) { + case DH6OPT_AUTHPROTO_DELAYED: + printf(" proto: delayed"); + break; + case DH6OPT_AUTHPROTO_RECONFIG: + printf(" proto: reconfigure"); + break; + default: + printf(" proto: %d", auth_proto); + break; + } + tp++; + switch (*tp) { + case DH6OPT_AUTHALG_HMACMD5: + /* XXX: may depend on the protocol */ + printf(", alg: HMAC-MD5"); + break; + default: + printf(", alg: %d", *tp); + break; + } + tp++; + switch (*tp) { + case DH6OPT_AUTHRDM_MONOCOUNTER: + printf(", RDM: mono"); + break; + default: + printf(", RDM: %d", *tp); + break; + } + tp++; + printf(", RD:"); + for (i = 0; i < 4; i++, tp += 2) + printf(" %04x", EXTRACT_16BITS(tp)); + + /* protocol dependent part */ + authinfolen = optlen - 11; + switch (auth_proto) { + case DH6OPT_AUTHPROTO_DELAYED: + if (authinfolen == 0) + break; + if (authinfolen < 20) { + printf(" ??"); + break; + } + authrealmlen = authinfolen - 20; + if (authrealmlen > 0) { + printf(", realm: "); + } + for (i = 0; i < authrealmlen; i++, tp++) + printf("%02x", *tp); + printf(", key ID: %08x", EXTRACT_32BITS(tp)); + tp += 4; + printf(", HMAC-MD5:"); + for (i = 0; i < 4; i++, tp+= 4) + printf(" %08x", EXTRACT_32BITS(tp)); + break; + case DH6OPT_AUTHPROTO_RECONFIG: + if (authinfolen != 17) { + printf(" ??"); + break; + } + switch (*tp++) { + case DH6OPT_AUTHRECONFIG_KEY: + printf(" reconfig-key"); + break; + case DH6OPT_AUTHRECONFIG_HMACMD5: + printf(" type: HMAC-MD5"); + break; + default: + printf(" type: ??"); + break; + } + printf(" value:"); + for (i = 0; i < 4; i++, tp+= 4) + printf(" %08x", EXTRACT_32BITS(tp)); + break; + default: + printf(" ??"); + break; + } + + printf(")"); + break; + case DH6OPT_RAPID_COMMIT: /* nothing todo */ + printf(")"); + break; + case DH6OPT_INTERFACE_ID: + case DH6OPT_SUBSCRIBER_ID: + /* + * Since we cannot predict the encoding, print hex dump + * at most 10 characters. + */ + tp = (u_char *)(dh6o + 1); + printf(" "); + for (i = 0; i < optlen && i < 10; i++) + printf("%02x", tp[i]); + printf("...)"); + break; + case DH6OPT_RECONF_MSG: + tp = (u_char *)(dh6o + 1); + switch (*tp) { + case DH6_RENEW: + printf(" for renew)"); + break; + case DH6_INFORM_REQ: + printf(" for inf-req)"); + break; + default: + printf(" for ?\?\?(%02x))", *tp); + break; + } + break; + case DH6OPT_RECONF_ACCEPT: /* nothing todo */ + printf(")"); + break; + case DH6OPT_SIP_SERVER_A: + case DH6OPT_DNS: + case DH6OPT_NTP_SERVERS: + case DH6OPT_NIS_SERVERS: + case DH6OPT_NISP_SERVERS: + case DH6OPT_BCMCS_SERVER_A: + case DH6OPT_PANA_AGENT: + case DH6OPT_LQ_CLIENT_LINK: + if (optlen % 16) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + for (i = 0; i < optlen; i += 16) + printf(" %s", ip6addr_string(&tp[i])); + printf(")"); + break; + case DH6OPT_STATUS_CODE: + if (optlen < 2) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" %s)", dhcp6stcode(EXTRACT_16BITS(&tp[0]))); + break; + case DH6OPT_IA_NA: + case DH6OPT_IA_PD: + if (optlen < 12) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" IAID:%u T1:%u T2:%u", + EXTRACT_32BITS(&tp[0]), + EXTRACT_32BITS(&tp[4]), + EXTRACT_32BITS(&tp[8])); + if (optlen > 12) { + /* there are sub-options */ + dhcp6opt_print(tp + 12, tp + 12 + optlen); + } + printf(")"); + break; + case DH6OPT_IA_TA: + if (optlen < 4) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" IAID:%u", EXTRACT_32BITS(tp)); + if (optlen > 4) { + /* there are sub-options */ + dhcp6opt_print(tp + 4, tp + 4 + optlen); + } + printf(")"); + break; + case DH6OPT_IA_PD_PREFIX: + if (optlen < 25) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" %s/%d", ip6addr_string(&tp[9]), tp[8]); + printf(" pltime:%u vltime:%u", + EXTRACT_32BITS(&tp[0]), + EXTRACT_32BITS(&tp[4])); + if (optlen > 25) { + /* there are sub-options */ + dhcp6opt_print(tp + 25, tp + 25 + optlen); + } + printf(")"); + break; + case DH6OPT_LIFETIME: + case DH6OPT_CLT_TIME: + if (optlen != 4) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" %d)", EXTRACT_32BITS(tp)); + break; + case DH6OPT_REMOTE_ID: + if (optlen < 4) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" %d ", EXTRACT_32BITS(tp)); + /* + * Print hex dump first 10 characters. + */ + for (i = 4; i < optlen && i < 14; i++) + printf("%02x", tp[i]); + printf("...)"); + break; + case DH6OPT_LQ_QUERY: + if (optlen < 17) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + switch (*tp) { + case 1: + printf(" by-address"); + break; + case 2: + printf(" by-clientID"); + break; + default: + printf(" type_%d", (int)*tp); + break; + } + printf(" %s", ip6addr_string(&tp[1])); + if (optlen > 17) { + /* there are query-options */ + dhcp6opt_print(tp + 17, tp + optlen); + } + printf(")"); + break; + case DH6OPT_CLIENT_DATA: + tp = (u_char *)(dh6o + 1); + if (optlen > 0) { + /* there are encapsulated options */ + dhcp6opt_print(tp, tp + optlen); + } + printf(")"); + break; + case DH6OPT_LQ_RELAY_DATA: + if (optlen < 16) { + printf(" ?)"); + break; + } + tp = (u_char *)(dh6o + 1); + printf(" %s ", ip6addr_string(&tp[0])); + /* + * Print hex dump first 10 characters. + */ + for (i = 16; i < optlen && i < 26; i++) + printf("%02x", tp[i]); + printf("...)"); + break; + default: + printf(")"); + break; + } + + cp += sizeof(*dh6o) + optlen; + } + return; + +trunc: + printf("[|dhcp6ext]"); +} + +/* + * Print dhcp6 packets + */ +void +dhcp6_print(const u_char *cp, u_int length) +{ + struct dhcp6 *dh6; + struct dhcp6_relay *dh6relay; + const u_char *ep; + u_char *extp; + const char *name; + + printf("dhcp6"); + + ep = (u_char *)snapend; + if (cp + length < ep) + ep = cp + length; + + dh6 = (struct dhcp6 *)cp; + dh6relay = (struct dhcp6_relay *)cp; + TCHECK(dh6->dh6_xid); + switch (dh6->dh6_msgtype) { + case DH6_SOLICIT: + name = "solicit"; + break; + case DH6_ADVERTISE: + name = "advertise"; + break; + case DH6_REQUEST: + name = "request"; + break; + case DH6_CONFIRM: + name = "confirm"; + break; + case DH6_RENEW: + name = "renew"; + break; + case DH6_REBIND: + name = "rebind"; + break; + case DH6_REPLY: + name = "reply"; + break; + case DH6_RELEASE: + name = "release"; + break; + case DH6_DECLINE: + name = "decline"; + break; + case DH6_RECONFIGURE: + name = "reconfigure"; + break; + case DH6_INFORM_REQ: + name= "inf-req"; + break; + case DH6_RELAY_FORW: + name= "relay-fwd"; + break; + case DH6_RELAY_REPLY: + name= "relay-reply"; + break; + case DH6_LEASEQUERY: + name= "leasequery"; + break; + case DH6_LQ_REPLY: + name= "leasequery-reply"; + break; + default: + name = NULL; + break; + } + + if (!vflag) { + if (name) + printf(" %s", name); + else if (dh6->dh6_msgtype != DH6_RELAY_FORW && + dh6->dh6_msgtype != DH6_RELAY_REPLY) { + printf(" msgtype-%u", dh6->dh6_msgtype); + } + return; + } + + /* XXX relay agent messages have to be handled differently */ + + if (name) + printf(" %s (", name); /*)*/ + else + printf(" msgtype-%u (", dh6->dh6_msgtype); /*)*/ + if (dh6->dh6_msgtype != DH6_RELAY_FORW && + dh6->dh6_msgtype != DH6_RELAY_REPLY) { + printf("xid=%x", EXTRACT_32BITS(&dh6->dh6_xid) & DH6_XIDMASK); + extp = (u_char *)(dh6 + 1); + dhcp6opt_print(extp, ep); + } else { /* relay messages */ + struct in6_addr addr6; + + TCHECK(dh6relay->dh6relay_peeraddr); + + memcpy(&addr6, dh6relay->dh6relay_linkaddr, sizeof (addr6)); + printf("linkaddr=%s", ip6addr_string(&addr6)); + + memcpy(&addr6, dh6relay->dh6relay_peeraddr, sizeof (addr6)); + printf(" peeraddr=%s", ip6addr_string(&addr6)); + + dhcp6opt_print((u_char *)(dh6relay + 1), ep); + } + /*(*/ + printf(")"); + return; + +trunc: + printf("[|dhcp6]"); +} diff --git a/print-domain.c b/print-domain.c new file mode 100644 index 0000000..43e8f41 --- /dev/null +++ b/print-domain.c @@ -0,0 +1,751 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-domain.c,v 1.98 2007-12-09 01:40:32 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "nameser.h" + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +static const char *ns_ops[] = { + "", " inv_q", " stat", " op3", " notify", " update", " op6", " op7", + " op8", " updataA", " updateD", " updateDA", + " updateM", " updateMA", " zoneInit", " zoneRef", +}; + +static const char *ns_resp[] = { + "", " FormErr", " ServFail", " NXDomain", + " NotImp", " Refused", " YXDomain", " YXRRSet", + " NXRRSet", " NotAuth", " NotZone", " Resp11", + " Resp12", " Resp13", " Resp14", " NoChange", +}; + +/* skip over a domain name */ +static const u_char * +ns_nskip(register const u_char *cp) +{ + register u_char i; + + if (!TTEST2(*cp, 1)) + return (NULL); + i = *cp++; + while (i) { + if ((i & INDIR_MASK) == INDIR_MASK) + return (cp + 1); + if ((i & INDIR_MASK) == EDNS0_MASK) { + int bitlen, bytelen; + + if ((i & ~INDIR_MASK) != EDNS0_ELT_BITLABEL) + return(NULL); /* unknown ELT */ + if (!TTEST2(*cp, 1)) + return (NULL); + if ((bitlen = *cp++) == 0) + bitlen = 256; + bytelen = (bitlen + 7) / 8; + cp += bytelen; + } else + cp += i; + if (!TTEST2(*cp, 1)) + return (NULL); + i = *cp++; + } + return (cp); +} + +/* print a */ +static const u_char * +blabel_print(const u_char *cp) +{ + int bitlen, slen, b; + const u_char *bitp, *lim; + char tc; + + if (!TTEST2(*cp, 1)) + return(NULL); + if ((bitlen = *cp) == 0) + bitlen = 256; + slen = (bitlen + 3) / 4; + lim = cp + 1 + slen; + + /* print the bit string as a hex string */ + printf("\\[x"); + for (bitp = cp + 1, b = bitlen; bitp < lim && b > 7; b -= 8, bitp++) { + TCHECK(*bitp); + printf("%02x", *bitp); + } + if (b > 4) { + TCHECK(*bitp); + tc = *bitp++; + printf("%02x", tc & (0xff << (8 - b))); + } else if (b > 0) { + TCHECK(*bitp); + tc = *bitp++; + printf("%1x", ((tc >> 4) & 0x0f) & (0x0f << (4 - b))); + } + printf("/%d]", bitlen); + return lim; +trunc: + printf(".../%d]", bitlen); + return NULL; +} + +static int +labellen(const u_char *cp) +{ + register u_int i; + + if (!TTEST2(*cp, 1)) + return(-1); + i = *cp; + if ((i & INDIR_MASK) == EDNS0_MASK) { + int bitlen, elt; + if ((elt = (i & ~INDIR_MASK)) != EDNS0_ELT_BITLABEL) { + printf("", elt); + return(-1); + } + if (!TTEST2(*(cp + 1), 1)) + return(-1); + if ((bitlen = *(cp + 1)) == 0) + bitlen = 256; + return(((bitlen + 7) / 8) + 1); + } else + return(i); +} + +static const u_char * +ns_nprint(register const u_char *cp, register const u_char *bp) +{ + register u_int i, l; + register const u_char *rp = NULL; + register int compress = 0; + int chars_processed; + int elt; + int data_size = snapend - bp; + + if ((l = labellen(cp)) == (u_int)-1) + return(NULL); + if (!TTEST2(*cp, 1)) + return(NULL); + chars_processed = 1; + if (((i = *cp++) & INDIR_MASK) != INDIR_MASK) { + compress = 0; + rp = cp + l; + } + + if (i != 0) + while (i && cp < snapend) { + if ((i & INDIR_MASK) == INDIR_MASK) { + if (!compress) { + rp = cp + 1; + compress = 1; + } + if (!TTEST2(*cp, 1)) + return(NULL); + cp = bp + (((i << 8) | *cp) & 0x3fff); + if ((l = labellen(cp)) == (u_int)-1) + return(NULL); + if (!TTEST2(*cp, 1)) + return(NULL); + i = *cp++; + chars_processed++; + + /* + * If we've looked at every character in + * the message, this pointer will make + * us look at some character again, + * which means we're looping. + */ + if (chars_processed >= data_size) { + printf(""); + return (NULL); + } + continue; + } + if ((i & INDIR_MASK) == EDNS0_MASK) { + elt = (i & ~INDIR_MASK); + switch(elt) { + case EDNS0_ELT_BITLABEL: + if (blabel_print(cp) == NULL) + return (NULL); + break; + default: + /* unknown ELT */ + printf("", elt); + return(NULL); + } + } else { + if (fn_printn(cp, l, snapend)) + return(NULL); + } + + cp += l; + chars_processed += l; + putchar('.'); + if ((l = labellen(cp)) == (u_int)-1) + return(NULL); + if (!TTEST2(*cp, 1)) + return(NULL); + i = *cp++; + chars_processed++; + if (!compress) + rp += l + 1; + } + else + putchar('.'); + return (rp); +} + +/* print a */ +static const u_char * +ns_cprint(register const u_char *cp) +{ + register u_int i; + + if (!TTEST2(*cp, 1)) + return (NULL); + i = *cp++; + if (fn_printn(cp, i, snapend)) + return (NULL); + return (cp + i); +} + +/* http://www.iana.org/assignments/dns-parameters */ +struct tok ns_type2str[] = { + { T_A, "A" }, /* RFC 1035 */ + { T_NS, "NS" }, /* RFC 1035 */ + { T_MD, "MD" }, /* RFC 1035 */ + { T_MF, "MF" }, /* RFC 1035 */ + { T_CNAME, "CNAME" }, /* RFC 1035 */ + { T_SOA, "SOA" }, /* RFC 1035 */ + { T_MB, "MB" }, /* RFC 1035 */ + { T_MG, "MG" }, /* RFC 1035 */ + { T_MR, "MR" }, /* RFC 1035 */ + { T_NULL, "NULL" }, /* RFC 1035 */ + { T_WKS, "WKS" }, /* RFC 1035 */ + { T_PTR, "PTR" }, /* RFC 1035 */ + { T_HINFO, "HINFO" }, /* RFC 1035 */ + { T_MINFO, "MINFO" }, /* RFC 1035 */ + { T_MX, "MX" }, /* RFC 1035 */ + { T_TXT, "TXT" }, /* RFC 1035 */ + { T_RP, "RP" }, /* RFC 1183 */ + { T_AFSDB, "AFSDB" }, /* RFC 1183 */ + { T_X25, "X25" }, /* RFC 1183 */ + { T_ISDN, "ISDN" }, /* RFC 1183 */ + { T_RT, "RT" }, /* RFC 1183 */ + { T_NSAP, "NSAP" }, /* RFC 1706 */ + { T_NSAP_PTR, "NSAP_PTR" }, + { T_SIG, "SIG" }, /* RFC 2535 */ + { T_KEY, "KEY" }, /* RFC 2535 */ + { T_PX, "PX" }, /* RFC 2163 */ + { T_GPOS, "GPOS" }, /* RFC 1712 */ + { T_AAAA, "AAAA" }, /* RFC 1886 */ + { T_LOC, "LOC" }, /* RFC 1876 */ + { T_NXT, "NXT" }, /* RFC 2535 */ + { T_EID, "EID" }, /* Nimrod */ + { T_NIMLOC, "NIMLOC" }, /* Nimrod */ + { T_SRV, "SRV" }, /* RFC 2782 */ + { T_ATMA, "ATMA" }, /* ATM Forum */ + { T_NAPTR, "NAPTR" }, /* RFC 2168, RFC 2915 */ + { T_KX, "KX" }, /* RFC 2230 */ + { T_CERT, "CERT" }, /* RFC 2538 */ + { T_A6, "A6" }, /* RFC 2874 */ + { T_DNAME, "DNAME" }, /* RFC 2672 */ + { T_SINK, "SINK" }, + { T_OPT, "OPT" }, /* RFC 2671 */ + { T_APL, "APL" }, /* RFC 3123 */ + { T_DS, "DS" }, /* RFC 4034 */ + { T_SSHFP, "SSHFP" }, /* RFC 4255 */ + { T_IPSECKEY, "IPSECKEY" }, /* RFC 4025 */ + { T_RRSIG, "RRSIG" }, /* RFC 4034 */ + { T_NSEC, "NSEC" }, /* RFC 4034 */ + { T_DNSKEY, "DNSKEY" }, /* RFC 4034 */ + { T_SPF, "SPF" }, /* RFC-schlitt-spf-classic-02.txt */ + { T_UINFO, "UINFO" }, + { T_UID, "UID" }, + { T_GID, "GID" }, + { T_UNSPEC, "UNSPEC" }, + { T_UNSPECA, "UNSPECA" }, + { T_TKEY, "TKEY" }, /* RFC 2930 */ + { T_TSIG, "TSIG" }, /* RFC 2845 */ + { T_IXFR, "IXFR" }, /* RFC 1995 */ + { T_AXFR, "AXFR" }, /* RFC 1035 */ + { T_MAILB, "MAILB" }, /* RFC 1035 */ + { T_MAILA, "MAILA" }, /* RFC 1035 */ + { T_ANY, "ANY" }, + { 0, NULL } +}; + +struct tok ns_class2str[] = { + { C_IN, "IN" }, /* Not used */ + { C_CHAOS, "CHAOS" }, + { C_HS, "HS" }, + { C_ANY, "ANY" }, + { 0, NULL } +}; + +/* print a query */ +static const u_char * +ns_qprint(register const u_char *cp, register const u_char *bp, int is_mdns) +{ + register const u_char *np = cp; + register u_int i, class; + + cp = ns_nskip(cp); + + if (cp == NULL || !TTEST2(*cp, 4)) + return(NULL); + + /* print the qtype */ + i = EXTRACT_16BITS(cp); + cp += 2; + printf(" %s", tok2str(ns_type2str, "Type%d", i)); + /* print the qclass (if it's not IN) */ + i = EXTRACT_16BITS(cp); + cp += 2; + if (is_mdns) + class = (i & ~C_QU); + else + class = i; + if (class != C_IN) + printf(" %s", tok2str(ns_class2str, "(Class %d)", class)); + if (is_mdns) { + if (i & C_QU) + printf(" (QU)"); + else + printf(" (QM)"); + } + + fputs("? ", stdout); + cp = ns_nprint(np, bp); + return(cp ? cp + 4 : NULL); +} + +/* print a reply */ +static const u_char * +ns_rprint(register const u_char *cp, register const u_char *bp, int is_mdns) +{ + register u_int i, class, opt_flags = 0; + register u_short typ, len; + register const u_char *rp; + + if (vflag) { + putchar(' '); + if ((cp = ns_nprint(cp, bp)) == NULL) + return NULL; + } else + cp = ns_nskip(cp); + + if (cp == NULL || !TTEST2(*cp, 10)) + return (snapend); + + /* print the type/qtype */ + typ = EXTRACT_16BITS(cp); + cp += 2; + /* print the class (if it's not IN and the type isn't OPT) */ + i = EXTRACT_16BITS(cp); + cp += 2; + if (is_mdns) + class = (i & ~C_CACHE_FLUSH); + else + class = i; + if (class != C_IN && typ != T_OPT) + printf(" %s", tok2str(ns_class2str, "(Class %d)", class)); + if (is_mdns) { + if (i & C_CACHE_FLUSH) + printf(" (Cache flush)"); + } + + if (typ == T_OPT) { + /* get opt flags */ + cp += 2; + opt_flags = EXTRACT_16BITS(cp); + /* ignore rest of ttl field */ + cp += 2; + } else if (vflag > 2) { + /* print ttl */ + printf(" ["); + relts_print(EXTRACT_32BITS(cp)); + printf("]"); + cp += 4; + } else { + /* ignore ttl */ + cp += 4; + } + + len = EXTRACT_16BITS(cp); + cp += 2; + + rp = cp + len; + + printf(" %s", tok2str(ns_type2str, "Type%d", typ)); + if (rp > snapend) + return(NULL); + + switch (typ) { + case T_A: + if (!TTEST2(*cp, sizeof(struct in_addr))) + return(NULL); + printf(" %s", intoa(htonl(EXTRACT_32BITS(cp)))); + break; + + case T_NS: + case T_CNAME: + case T_PTR: +#ifdef T_DNAME + case T_DNAME: +#endif + putchar(' '); + if (ns_nprint(cp, bp) == NULL) + return(NULL); + break; + + case T_SOA: + if (!vflag) + break; + putchar(' '); + if ((cp = ns_nprint(cp, bp)) == NULL) + return(NULL); + putchar(' '); + if ((cp = ns_nprint(cp, bp)) == NULL) + return(NULL); + if (!TTEST2(*cp, 5 * 4)) + return(NULL); + printf(" %u", EXTRACT_32BITS(cp)); + cp += 4; + printf(" %u", EXTRACT_32BITS(cp)); + cp += 4; + printf(" %u", EXTRACT_32BITS(cp)); + cp += 4; + printf(" %u", EXTRACT_32BITS(cp)); + cp += 4; + printf(" %u", EXTRACT_32BITS(cp)); + cp += 4; + break; + case T_MX: + putchar(' '); + if (!TTEST2(*cp, 2)) + return(NULL); + if (ns_nprint(cp + 2, bp) == NULL) + return(NULL); + printf(" %d", EXTRACT_16BITS(cp)); + break; + + case T_TXT: + while (cp < rp) { + printf(" \""); + cp = ns_cprint(cp); + if (cp == NULL) + return(NULL); + putchar('"'); + } + break; + + case T_SRV: + putchar(' '); + if (!TTEST2(*cp, 6)) + return(NULL); + if (ns_nprint(cp + 6, bp) == NULL) + return(NULL); + printf(":%d %d %d", EXTRACT_16BITS(cp + 4), + EXTRACT_16BITS(cp), EXTRACT_16BITS(cp + 2)); + break; + +#ifdef INET6 + case T_AAAA: + { + struct in6_addr addr; + char ntop_buf[INET6_ADDRSTRLEN]; + + if (!TTEST2(*cp, sizeof(struct in6_addr))) + return(NULL); + memcpy(&addr, cp, sizeof(struct in6_addr)); + printf(" %s", + inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf))); + + break; + } + + case T_A6: + { + struct in6_addr a; + int pbit, pbyte; + char ntop_buf[INET6_ADDRSTRLEN]; + + if (!TTEST2(*cp, 1)) + return(NULL); + pbit = *cp; + pbyte = (pbit & ~7) / 8; + if (pbit > 128) { + printf(" %u(bad plen)", pbit); + break; + } else if (pbit < 128) { + if (!TTEST2(*(cp + 1), sizeof(a) - pbyte)) + return(NULL); + memset(&a, 0, sizeof(a)); + memcpy(&a.s6_addr[pbyte], cp + 1, sizeof(a) - pbyte); + printf(" %u %s", pbit, + inet_ntop(AF_INET6, &a, ntop_buf, sizeof(ntop_buf))); + } + if (pbit > 0) { + putchar(' '); + if (ns_nprint(cp + 1 + sizeof(a) - pbyte, bp) == NULL) + return(NULL); + } + break; + } +#endif /*INET6*/ + + case T_OPT: + printf(" UDPsize=%u", class); + if (opt_flags & 0x8000) + printf(" OK"); + break; + + case T_UNSPECA: /* One long string */ + if (!TTEST2(*cp, len)) + return(NULL); + if (fn_printn(cp, len, snapend)) + return(NULL); + break; + + case T_TSIG: + { + if (cp + len > snapend) + return(NULL); + if (!vflag) + break; + putchar(' '); + if ((cp = ns_nprint(cp, bp)) == NULL) + return(NULL); + cp += 6; + if (!TTEST2(*cp, 2)) + return(NULL); + printf(" fudge=%u", EXTRACT_16BITS(cp)); + cp += 2; + if (!TTEST2(*cp, 2)) + return(NULL); + printf(" maclen=%u", EXTRACT_16BITS(cp)); + cp += 2 + EXTRACT_16BITS(cp); + if (!TTEST2(*cp, 2)) + return(NULL); + printf(" origid=%u", EXTRACT_16BITS(cp)); + cp += 2; + if (!TTEST2(*cp, 2)) + return(NULL); + printf(" error=%u", EXTRACT_16BITS(cp)); + cp += 2; + if (!TTEST2(*cp, 2)) + return(NULL); + printf(" otherlen=%u", EXTRACT_16BITS(cp)); + cp += 2; + } + } + return (rp); /* XXX This isn't always right */ +} + +void +ns_print(register const u_char *bp, u_int length, int is_mdns) +{ + register const HEADER *np; + register int qdcount, ancount, nscount, arcount; + register const u_char *cp; + u_int16_t b2; + + np = (const HEADER *)bp; + TCHECK(*np); + /* get the byte-order right */ + qdcount = EXTRACT_16BITS(&np->qdcount); + ancount = EXTRACT_16BITS(&np->ancount); + nscount = EXTRACT_16BITS(&np->nscount); + arcount = EXTRACT_16BITS(&np->arcount); + + if (DNS_QR(np)) { + /* this is a response */ + printf("%d%s%s%s%s%s%s", + EXTRACT_16BITS(&np->id), + ns_ops[DNS_OPCODE(np)], + ns_resp[DNS_RCODE(np)], + DNS_AA(np)? "*" : "", + DNS_RA(np)? "" : "-", + DNS_TC(np)? "|" : "", + DNS_AD(np)? "$" : ""); + + if (qdcount != 1) + printf(" [%dq]", qdcount); + /* Print QUESTION section on -vv */ + cp = (const u_char *)(np + 1); + while (qdcount--) { + if (qdcount < EXTRACT_16BITS(&np->qdcount) - 1) + putchar(','); + if (vflag > 1) { + fputs(" q:", stdout); + if ((cp = ns_qprint(cp, bp, is_mdns)) == NULL) + goto trunc; + } else { + if ((cp = ns_nskip(cp)) == NULL) + goto trunc; + cp += 4; /* skip QTYPE and QCLASS */ + } + } + printf(" %d/%d/%d", ancount, nscount, arcount); + if (ancount--) { + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + while (cp < snapend && ancount--) { + putchar(','); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + } + } + if (ancount > 0) + goto trunc; + /* Print NS and AR sections on -vv */ + if (vflag > 1) { + if (cp < snapend && nscount--) { + fputs(" ns:", stdout); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + while (cp < snapend && nscount--) { + putchar(','); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + } + } + if (nscount > 0) + goto trunc; + if (cp < snapend && arcount--) { + fputs(" ar:", stdout); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + while (cp < snapend && arcount--) { + putchar(','); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + } + } + if (arcount > 0) + goto trunc; + } + } + else { + /* this is a request */ + printf("%d%s%s%s", EXTRACT_16BITS(&np->id), ns_ops[DNS_OPCODE(np)], + DNS_RD(np) ? "+" : "", + DNS_CD(np) ? "%" : ""); + + /* any weirdness? */ + b2 = EXTRACT_16BITS(((u_short *)np)+1); + if (b2 & 0x6cf) + printf(" [b2&3=0x%x]", b2); + + if (DNS_OPCODE(np) == IQUERY) { + if (qdcount) + printf(" [%dq]", qdcount); + if (ancount != 1) + printf(" [%da]", ancount); + } + else { + if (ancount) + printf(" [%da]", ancount); + if (qdcount != 1) + printf(" [%dq]", qdcount); + } + if (nscount) + printf(" [%dn]", nscount); + if (arcount) + printf(" [%dau]", arcount); + + cp = (const u_char *)(np + 1); + if (qdcount--) { + cp = ns_qprint(cp, (const u_char *)np, is_mdns); + if (!cp) + goto trunc; + while (cp < snapend && qdcount--) { + cp = ns_qprint((const u_char *)cp, + (const u_char *)np, + is_mdns); + if (!cp) + goto trunc; + } + } + if (qdcount > 0) + goto trunc; + + /* Print remaining sections on -vv */ + if (vflag > 1) { + if (ancount--) { + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + while (cp < snapend && ancount--) { + putchar(','); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + } + } + if (ancount > 0) + goto trunc; + if (cp < snapend && nscount--) { + fputs(" ns:", stdout); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + while (nscount-- && cp < snapend) { + putchar(','); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + } + } + if (nscount > 0) + goto trunc; + if (cp < snapend && arcount--) { + fputs(" ar:", stdout); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + while (cp < snapend && arcount--) { + putchar(','); + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) + goto trunc; + } + } + if (arcount > 0) + goto trunc; + } + } + printf(" (%d)", length); + return; + + trunc: + printf("[|domain]"); + return; +} diff --git a/print-dtp.c b/print-dtp.c new file mode 100644 index 0000000..c358a89 --- /dev/null +++ b/print-dtp.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 1998-2007 The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Dynamic Trunk Protocol (DTP) + * + * Original code by Carles Kishimoto + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "nlpid.h" + +#define DTP_HEADER_LEN 1 +#define DTP_DOMAIN_TLV 0x0001 +#define DTP_STATUS_TLV 0x0002 +#define DTP_DTP_TYPE_TLV 0x0003 +#define DTP_NEIGHBOR_TLV 0x0004 + +static struct tok dtp_tlv_values[] = { + { DTP_DOMAIN_TLV, "Domain TLV"}, + { DTP_STATUS_TLV, "Status TLV"}, + { DTP_DTP_TYPE_TLV, "DTP type TLV"}, + { DTP_NEIGHBOR_TLV, "Neighbor TLV"}, + { 0, NULL} +}; + +void +dtp_print (const u_char *pptr, u_int length) +{ + int type, len; + const u_char *tptr; + + if (length < DTP_HEADER_LEN) + goto trunc; + + tptr = pptr; + + if (!TTEST2(*tptr, DTP_HEADER_LEN)) + goto trunc; + + printf("DTPv%u, length %u", + (*tptr), + length); + + /* + * In non-verbose mode, just print version. + */ + if (vflag < 1) { + return; + } + + tptr += DTP_HEADER_LEN; + + while (tptr < (pptr+length)) { + + if (!TTEST2(*tptr, 4)) + goto trunc; + + type = EXTRACT_16BITS(tptr); + len = EXTRACT_16BITS(tptr+2); + + /* infinite loop check */ + if (type == 0 || len == 0) { + return; + } + + printf("\n\t%s (0x%04x) TLV, length %u", + tok2str(dtp_tlv_values, "Unknown", type), + type, len); + + switch (type) { + case DTP_DOMAIN_TLV: + printf(", %s", tptr+4); + break; + + case DTP_STATUS_TLV: + case DTP_DTP_TYPE_TLV: + printf(", 0x%x", *(tptr+4)); + break; + + case DTP_NEIGHBOR_TLV: + printf(", %s", etheraddr_string(tptr+4)); + break; + + default: + break; + } + tptr += len; + } + + return; + + trunc: + printf("[|dtp]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/print-dvmrp.c b/print-dvmrp.c new file mode 100644 index 0000000..437e716 --- /dev/null +++ b/print-dvmrp.c @@ -0,0 +1,369 @@ +/* + * Copyright (c) 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-dvmrp.c,v 1.27 2003-11-19 09:42:04 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * DVMRP message types and flag values shamelessly stolen from + * mrouted/dvmrp.h. + */ +#define DVMRP_PROBE 1 /* for finding neighbors */ +#define DVMRP_REPORT 2 /* for reporting some or all routes */ +#define DVMRP_ASK_NEIGHBORS 3 /* sent by mapper, asking for a list */ + /* of this router's neighbors */ +#define DVMRP_NEIGHBORS 4 /* response to such a request */ +#define DVMRP_ASK_NEIGHBORS2 5 /* as above, want new format reply */ +#define DVMRP_NEIGHBORS2 6 +#define DVMRP_PRUNE 7 /* prune message */ +#define DVMRP_GRAFT 8 /* graft message */ +#define DVMRP_GRAFT_ACK 9 /* graft acknowledgement */ + +/* + * 'flags' byte values in DVMRP_NEIGHBORS2 reply. + */ +#define DVMRP_NF_TUNNEL 0x01 /* neighbors reached via tunnel */ +#define DVMRP_NF_SRCRT 0x02 /* tunnel uses IP source routing */ +#define DVMRP_NF_DOWN 0x10 /* kernel state of interface */ +#define DVMRP_NF_DISABLED 0x20 /* administratively disabled */ +#define DVMRP_NF_QUERIER 0x40 /* I am the subnet's querier */ + +static int print_probe(const u_char *, const u_char *, u_int); +static int print_report(const u_char *, const u_char *, u_int); +static int print_neighbors(const u_char *, const u_char *, u_int); +static int print_neighbors2(const u_char *, const u_char *, u_int); +static int print_prune(const u_char *); +static int print_graft(const u_char *); +static int print_graft_ack(const u_char *); + +static u_int32_t target_level; + +void +dvmrp_print(register const u_char *bp, register u_int len) +{ + register const u_char *ep; + register u_char type; + + ep = (const u_char *)snapend; + if (bp >= ep) + return; + + TCHECK(bp[1]); + type = bp[1]; + + /* Skip IGMP header */ + bp += 8; + len -= 8; + + switch (type) { + + case DVMRP_PROBE: + printf(" Probe"); + if (vflag) { + if (print_probe(bp, ep, len) < 0) + goto trunc; + } + break; + + case DVMRP_REPORT: + printf(" Report"); + if (vflag > 1) { + if (print_report(bp, ep, len) < 0) + goto trunc; + } + break; + + case DVMRP_ASK_NEIGHBORS: + printf(" Ask-neighbors(old)"); + break; + + case DVMRP_NEIGHBORS: + printf(" Neighbors(old)"); + if (print_neighbors(bp, ep, len) < 0) + goto trunc; + break; + + case DVMRP_ASK_NEIGHBORS2: + printf(" Ask-neighbors2"); + break; + + case DVMRP_NEIGHBORS2: + printf(" Neighbors2"); + /* + * extract version and capabilities from IGMP group + * address field + */ + bp -= 4; + TCHECK2(bp[0], 4); + target_level = (bp[0] << 24) | (bp[1] << 16) | + (bp[2] << 8) | bp[3]; + bp += 4; + if (print_neighbors2(bp, ep, len) < 0) + goto trunc; + break; + + case DVMRP_PRUNE: + printf(" Prune"); + if (print_prune(bp) < 0) + goto trunc; + break; + + case DVMRP_GRAFT: + printf(" Graft"); + if (print_graft(bp) < 0) + goto trunc; + break; + + case DVMRP_GRAFT_ACK: + printf(" Graft-ACK"); + if (print_graft_ack(bp) < 0) + goto trunc; + break; + + default: + printf(" [type %d]", type); + break; + } + return; + +trunc: + printf("[|dvmrp]"); + return; +} + +static int +print_report(register const u_char *bp, register const u_char *ep, + register u_int len) +{ + register u_int32_t mask, origin; + register int metric, done; + register u_int i, width; + + while (len > 0) { + if (len < 3) { + printf(" [|]"); + return (0); + } + TCHECK2(bp[0], 3); + mask = (u_int32_t)0xff << 24 | bp[0] << 16 | bp[1] << 8 | bp[2]; + width = 1; + if (bp[0]) + width = 2; + if (bp[1]) + width = 3; + if (bp[2]) + width = 4; + + printf("\n\tMask %s", intoa(htonl(mask))); + bp += 3; + len -= 3; + do { + if (bp + width + 1 > ep) { + printf(" [|]"); + return (0); + } + if (len < width + 1) { + printf("\n\t [Truncated Report]"); + return (0); + } + origin = 0; + for (i = 0; i < width; ++i) { + TCHECK(*bp); + origin = origin << 8 | *bp++; + } + for ( ; i < 4; ++i) + origin <<= 8; + + TCHECK(*bp); + metric = *bp++; + done = metric & 0x80; + metric &= 0x7f; + printf("\n\t %s metric %d", intoa(htonl(origin)), + metric); + len -= width + 1; + } while (!done); + } + return (0); +trunc: + return (-1); +} + +static int +print_probe(register const u_char *bp, register const u_char *ep, + register u_int len) +{ + register u_int32_t genid; + + TCHECK2(bp[0], 4); + if ((len < 4) || ((bp + 4) > ep)) { + /* { (ctags) */ + printf(" [|}"); + return (0); + } + genid = (bp[0] << 24) | (bp[1] << 16) | (bp[2] << 8) | bp[3]; + bp += 4; + len -= 4; + if (vflag > 1) + printf("\n\t"); + else + printf(" "); + printf("genid %u", genid); + if (vflag < 2) + return (0); + + while ((len > 0) && (bp < ep)) { + TCHECK2(bp[0], 4); + printf("\n\tneighbor %s", ipaddr_string(bp)); + bp += 4; len -= 4; + } + return (0); +trunc: + return (-1); +} + +static int +print_neighbors(register const u_char *bp, register const u_char *ep, + register u_int len) +{ + const u_char *laddr; + register u_char metric; + register u_char thresh; + register int ncount; + + while (len > 0 && bp < ep) { + TCHECK2(bp[0], 7); + laddr = bp; + bp += 4; + metric = *bp++; + thresh = *bp++; + ncount = *bp++; + len -= 7; + while (--ncount >= 0) { + TCHECK2(bp[0], 4); + printf(" [%s ->", ipaddr_string(laddr)); + printf(" %s, (%d/%d)]", + ipaddr_string(bp), metric, thresh); + bp += 4; + len -= 4; + } + } + return (0); +trunc: + return (-1); +} + +static int +print_neighbors2(register const u_char *bp, register const u_char *ep, + register u_int len) +{ + const u_char *laddr; + register u_char metric, thresh, flags; + register int ncount; + + printf(" (v %d.%d):", + (int)target_level & 0xff, + (int)(target_level >> 8) & 0xff); + + while (len > 0 && bp < ep) { + TCHECK2(bp[0], 8); + laddr = bp; + bp += 4; + metric = *bp++; + thresh = *bp++; + flags = *bp++; + ncount = *bp++; + len -= 8; + while (--ncount >= 0 && (len >= 4) && (bp + 4) <= ep) { + printf(" [%s -> ", ipaddr_string(laddr)); + printf("%s (%d/%d", ipaddr_string(bp), + metric, thresh); + if (flags & DVMRP_NF_TUNNEL) + printf("/tunnel"); + if (flags & DVMRP_NF_SRCRT) + printf("/srcrt"); + if (flags & DVMRP_NF_QUERIER) + printf("/querier"); + if (flags & DVMRP_NF_DISABLED) + printf("/disabled"); + if (flags & DVMRP_NF_DOWN) + printf("/down"); + printf(")]"); + bp += 4; + len -= 4; + } + if (ncount != -1) { + printf(" [|]"); + return (0); + } + } + return (0); +trunc: + return (-1); +} + +static int +print_prune(register const u_char *bp) +{ + TCHECK2(bp[0], 12); + printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4)); + bp += 8; + (void)printf(" timer "); + relts_print(EXTRACT_32BITS(bp)); + return (0); +trunc: + return (-1); +} + +static int +print_graft(register const u_char *bp) +{ + TCHECK2(bp[0], 8); + printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4)); + return (0); +trunc: + return (-1); +} + +static int +print_graft_ack(register const u_char *bp) +{ + TCHECK2(bp[0], 8); + printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4)); + return (0); +trunc: + return (-1); +} diff --git a/print-eap.c b/print-eap.c new file mode 100644 index 0000000..9fb333a --- /dev/null +++ b/print-eap.c @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2004 - Michael Richardson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Format and print EAP packets. + * + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-eap.c,v 1.5 2007-10-04 16:41:33 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "netdissect.h" +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "ether.h" + +#define EAP_FRAME_TYPE_PACKET 0 +#define EAP_FRAME_TYPE_START 1 +#define EAP_FRAME_TYPE_LOGOFF 2 +#define EAP_FRAME_TYPE_KEY 3 +#define EAP_FRAME_TYPE_ENCAP_ASF_ALERT 4 + +struct eap_frame_t { + unsigned char version; + unsigned char type; + unsigned char length[2]; +}; + +static const struct tok eap_frame_type_values[] = { + { EAP_FRAME_TYPE_PACKET, "EAP packet" }, + { EAP_FRAME_TYPE_START, "EAPOL start" }, + { EAP_FRAME_TYPE_LOGOFF, "EAPOL logoff" }, + { EAP_FRAME_TYPE_KEY, "EAPOL key" }, + { EAP_FRAME_TYPE_ENCAP_ASF_ALERT, "Encapsulated ASF alert" }, + { 0, NULL} +}; + +/* RFC 3748 */ +struct eap_packet_t { + unsigned char code; + unsigned char id; + unsigned char length[2]; +}; + +#define EAP_REQUEST 1 +#define EAP_RESPONSE 2 +#define EAP_SUCCESS 3 +#define EAP_FAILURE 4 + +static const struct tok eap_code_values[] = { + { EAP_REQUEST, "Request" }, + { EAP_RESPONSE, "Response" }, + { EAP_SUCCESS, "Success" }, + { EAP_FAILURE, "Failure" }, + { 0, NULL} +}; + +#define EAP_TYPE_NO_PROPOSED 0 +#define EAP_TYPE_IDENTITY 1 +#define EAP_TYPE_NOTIFICATION 2 +#define EAP_TYPE_NAK 3 +#define EAP_TYPE_MD5_CHALLENGE 4 +#define EAP_TYPE_OTP 5 +#define EAP_TYPE_GTC 6 +#define EAP_TYPE_TLS 13 /* RFC 2716 */ +#define EAP_TYPE_SIM 18 /* RFC 4186 */ +#define EAP_TYPE_TTLS 21 /* draft-funk-eap-ttls-v0-01.txt */ +#define EAP_TYPE_AKA 23 /* RFC 4187 */ +#define EAP_TYPE_FAST 43 /* RFC 4851 */ +#define EAP_TYPE_EXPANDED_TYPES 254 +#define EAP_TYPE_EXPERIMENTAL 255 + +static const struct tok eap_type_values[] = { + { EAP_TYPE_NO_PROPOSED, "No proposed" }, + { EAP_TYPE_IDENTITY, "Identity" }, + { EAP_TYPE_NOTIFICATION, "Notification" }, + { EAP_TYPE_NAK, "Nak" }, + { EAP_TYPE_MD5_CHALLENGE, "MD5-challenge" }, + { EAP_TYPE_OTP, "OTP" }, + { EAP_TYPE_GTC, "GTC" }, + { EAP_TYPE_TLS, "TLS" }, + { EAP_TYPE_SIM, "SIM" }, + { EAP_TYPE_TTLS, "TTLS" }, + { EAP_TYPE_AKA, "AKA" }, + { EAP_TYPE_FAST, "FAST" }, + { EAP_TYPE_EXPANDED_TYPES, "Expanded types" }, + { EAP_TYPE_EXPERIMENTAL, "Experimental" }, + { 0, NULL} +}; + +#define EAP_TLS_EXTRACT_BIT_L(x) (((x)&0x80)>>7) + +/* RFC 2716 - EAP TLS bits */ +#define EAP_TLS_FLAGS_LEN_INCLUDED (1 << 7) +#define EAP_TLS_FLAGS_MORE_FRAGMENTS (1 << 6) +#define EAP_TLS_FLAGS_START (1 << 5) + +static const struct tok eap_tls_flags_values[] = { + { EAP_TLS_FLAGS_LEN_INCLUDED, "L bit" }, + { EAP_TLS_FLAGS_MORE_FRAGMENTS, "More fragments bit"}, + { EAP_TLS_FLAGS_START, "Start bit"}, + { 0, NULL} +}; + +#define EAP_TTLS_VERSION(x) ((x)&0x07) + +/* EAP-AKA and EAP-SIM - RFC 4187 */ +#define EAP_AKA_CHALLENGE 1 +#define EAP_AKA_AUTH_REJECT 2 +#define EAP_AKA_SYNC_FAILURE 4 +#define EAP_AKA_IDENTITY 5 +#define EAP_SIM_START 10 +#define EAP_SIM_CHALLENGE 11 +#define EAP_AKA_NOTIFICATION 12 +#define EAP_AKA_REAUTH 13 +#define EAP_AKA_CLIENT_ERROR 14 + +static const struct tok eap_aka_subtype_values[] = { + { EAP_AKA_CHALLENGE, "Challenge" }, + { EAP_AKA_AUTH_REJECT, "Auth reject" }, + { EAP_AKA_SYNC_FAILURE, "Sync failure" }, + { EAP_AKA_IDENTITY, "Identity" }, + { EAP_SIM_START, "Start" }, + { EAP_SIM_CHALLENGE, "Challenge" }, + { EAP_AKA_NOTIFICATION, "Notification" }, + { EAP_AKA_REAUTH, "Reauth" }, + { EAP_AKA_CLIENT_ERROR, "Client error" }, + { 0, NULL} +}; + +/* + * Print EAP requests / responses + */ +void +eap_print(netdissect_options *ndo _U_, + register const u_char *cp, + u_int length _U_) +{ + const struct eap_frame_t *eap; + const u_char *tptr; + u_int tlen, type, subtype; + int count=0, len; + + tptr = cp; + tlen = length; + eap = (const struct eap_frame_t *)cp; + TCHECK(*eap); + + /* in non-verbose mode just lets print the basic info */ + if (vflag < 1) { + printf("%s (%u) v%u, len %u", + tok2str(eap_frame_type_values, "unknown", eap->type), + eap->type, + eap->version, + EXTRACT_16BITS(eap->length)); + return; + } + + printf("%s (%u) v%u, len %u", + tok2str(eap_frame_type_values, "unknown", eap->type), + eap->type, + eap->version, + EXTRACT_16BITS(eap->length)); + + tptr += sizeof(const struct eap_frame_t); + tlen -= sizeof(const struct eap_frame_t); + + switch (eap->type) { + case EAP_FRAME_TYPE_PACKET: + type = *(tptr); + len = EXTRACT_16BITS(tptr+2); + printf(", %s (%u), id %u, len %u", + tok2str(eap_code_values, "unknown", type), + type, + *(tptr+1), + len); + + if (!TTEST2(*tptr, len)) + goto trunc; + + if (type <= 2) { /* For EAP_REQUEST and EAP_RESPONSE only */ + subtype = *(tptr+4); + printf("\n\t\t Type %s (%u)", + tok2str(eap_type_values, "unknown", *(tptr+4)), + *(tptr+4)); + + switch (subtype) { + case EAP_TYPE_IDENTITY: + if (len - 5 > 0) { + printf(", Identity: "); + safeputs((const char *)tptr+5, len-5); + } + break; + + case EAP_TYPE_NOTIFICATION: + if (len - 5 > 0) { + printf(", Notification: "); + safeputs((const char *)tptr+5, len-5); + } + break; + + case EAP_TYPE_NAK: + count = 5; + + /* + * one or more octets indicating + * the desired authentication + * type one octet per type + */ + while (count < len) { + printf(" %s (%u),", + tok2str(eap_type_values, "unknown", *(tptr+count)), + *(tptr+count)); + count++; + } + break; + + case EAP_TYPE_TTLS: + printf(" TTLSv%u", + EAP_TTLS_VERSION(*(tptr+5))); /* fall through */ + case EAP_TYPE_TLS: + printf(" flags [%s] 0x%02x,", + bittok2str(eap_tls_flags_values, "none", *(tptr+5)), + *(tptr+5)); + + if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) { + printf(" len %u", EXTRACT_32BITS(tptr+6)); + } + break; + + case EAP_TYPE_FAST: + printf(" FASTv%u", + EAP_TTLS_VERSION(*(tptr+5))); + printf(" flags [%s] 0x%02x,", + bittok2str(eap_tls_flags_values, "none", *(tptr+5)), + *(tptr+5)); + + if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) { + printf(" len %u", EXTRACT_32BITS(tptr+6)); + } + + /* FIXME - TLV attributes follow */ + break; + + case EAP_TYPE_AKA: + case EAP_TYPE_SIM: + printf(" subtype [%s] 0x%02x,", + tok2str(eap_aka_subtype_values, "unknown", *(tptr+5)), + *(tptr+5)); + + /* FIXME - TLV attributes follow */ + break; + + case EAP_TYPE_MD5_CHALLENGE: + case EAP_TYPE_OTP: + case EAP_TYPE_GTC: + case EAP_TYPE_EXPANDED_TYPES: + case EAP_TYPE_EXPERIMENTAL: + default: + break; + } + } + break; + + case EAP_FRAME_TYPE_LOGOFF: + case EAP_FRAME_TYPE_ENCAP_ASF_ALERT: + default: + break; + } + return; + + trunc: + printf("\n\t[|EAP]"); +} + +/* + * Local Variables: + * c-basic-offset: 4 + * End: + */ diff --git a/print-egp.c b/print-egp.c new file mode 100644 index 0000000..4a1d046 --- /dev/null +++ b/print-egp.c @@ -0,0 +1,362 @@ +/* + * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Lawrence Berkeley Laboratory, + * Berkeley, CA. The name of the University may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Initial contribution from Jeff Honig (jch@MITCHELL.CIT.CORNELL.EDU). + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-egp.c,v 1.38 2006-02-11 22:13:24 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "ip.h" + +struct egp_packet { + u_int8_t egp_version; +#define EGP_VERSION 2 + u_int8_t egp_type; +#define EGPT_ACQUIRE 3 +#define EGPT_REACH 5 +#define EGPT_POLL 2 +#define EGPT_UPDATE 1 +#define EGPT_ERROR 8 + u_int8_t egp_code; +#define EGPC_REQUEST 0 +#define EGPC_CONFIRM 1 +#define EGPC_REFUSE 2 +#define EGPC_CEASE 3 +#define EGPC_CEASEACK 4 +#define EGPC_HELLO 0 +#define EGPC_HEARDU 1 + u_int8_t egp_status; +#define EGPS_UNSPEC 0 +#define EGPS_ACTIVE 1 +#define EGPS_PASSIVE 2 +#define EGPS_NORES 3 +#define EGPS_ADMIN 4 +#define EGPS_GODOWN 5 +#define EGPS_PARAM 6 +#define EGPS_PROTO 7 +#define EGPS_INDET 0 +#define EGPS_UP 1 +#define EGPS_DOWN 2 +#define EGPS_UNSOL 0x80 + u_int16_t egp_checksum; + u_int16_t egp_as; + u_int16_t egp_sequence; + union { + u_int16_t egpu_hello; + u_int8_t egpu_gws[2]; + u_int16_t egpu_reason; +#define EGPR_UNSPEC 0 +#define EGPR_BADHEAD 1 +#define EGPR_BADDATA 2 +#define EGPR_NOREACH 3 +#define EGPR_XSPOLL 4 +#define EGPR_NORESP 5 +#define EGPR_UVERSION 6 + } egp_handg; +#define egp_hello egp_handg.egpu_hello +#define egp_intgw egp_handg.egpu_gws[0] +#define egp_extgw egp_handg.egpu_gws[1] +#define egp_reason egp_handg.egpu_reason + union { + u_int16_t egpu_poll; + u_int32_t egpu_sourcenet; + } egp_pands; +#define egp_poll egp_pands.egpu_poll +#define egp_sourcenet egp_pands.egpu_sourcenet +}; + +const char *egp_acquire_codes[] = { + "request", + "confirm", + "refuse", + "cease", + "cease_ack" +}; + +const char *egp_acquire_status[] = { + "unspecified", + "active_mode", + "passive_mode", + "insufficient_resources", + "administratively_prohibited", + "going_down", + "parameter_violation", + "protocol_violation" +}; + +const char *egp_reach_codes[] = { + "hello", + "i-h-u" +}; + +const char *egp_status_updown[] = { + "indeterminate", + "up", + "down" +}; + +const char *egp_reasons[] = { + "unspecified", + "bad_EGP_header_format", + "bad_EGP_data_field_format", + "reachability_info_unavailable", + "excessive_polling_rate", + "no_response", + "unsupported_version" +}; + +static void +egpnrprint(register const struct egp_packet *egp) +{ + register const u_int8_t *cp; + u_int32_t addr; + register u_int32_t net; + register u_int netlen; + int gateways, distances, networks; + int t_gateways; + const char *comma; + + addr = egp->egp_sourcenet; + if (IN_CLASSA(addr)) { + net = addr & IN_CLASSA_NET; + netlen = 1; + } else if (IN_CLASSB(addr)) { + net = addr & IN_CLASSB_NET; + netlen = 2; + } else if (IN_CLASSC(addr)) { + net = addr & IN_CLASSC_NET; + netlen = 3; + } else { + net = 0; + netlen = 0; + } + cp = (u_int8_t *)(egp + 1); + + t_gateways = egp->egp_intgw + egp->egp_extgw; + for (gateways = 0; gateways < t_gateways; ++gateways) { + /* Pickup host part of gateway address */ + addr = 0; + TCHECK2(cp[0], 4 - netlen); + switch (netlen) { + + case 1: + addr = *cp++; + /* fall through */ + case 2: + addr = (addr << 8) | *cp++; + /* fall through */ + case 3: + addr = (addr << 8) | *cp++; + } + addr |= net; + TCHECK2(cp[0], 1); + distances = *cp++; + printf(" %s %s ", + gateways < (int)egp->egp_intgw ? "int" : "ext", + ipaddr_string(&addr)); + + comma = ""; + putchar('('); + while (--distances >= 0) { + TCHECK2(cp[0], 2); + printf("%sd%d:", comma, (int)*cp++); + comma = ", "; + networks = *cp++; + while (--networks >= 0) { + /* Pickup network number */ + TCHECK2(cp[0], 1); + addr = (u_int32_t)*cp++ << 24; + if (IN_CLASSB(addr)) { + TCHECK2(cp[0], 1); + addr |= (u_int32_t)*cp++ << 16; + } else if (!IN_CLASSA(addr)) { + TCHECK2(cp[0], 2); + addr |= (u_int32_t)*cp++ << 16; + addr |= (u_int32_t)*cp++ << 8; + } + printf(" %s", ipaddr_string(&addr)); + } + } + putchar(')'); + } + return; +trunc: + fputs("[|]", stdout); +} + +void +egp_print(register const u_int8_t *bp, register u_int length) +{ + register const struct egp_packet *egp; + register int status; + register int code; + register int type; + + egp = (struct egp_packet *)bp; + if (!TTEST2(*egp, length)) { + printf("[|egp]"); + return; + } + + if (!vflag) { + printf("EGPv%u, AS %u, seq %u, length %u", + egp->egp_version, + EXTRACT_16BITS(&egp->egp_as), + EXTRACT_16BITS(&egp->egp_sequence), + length); + return; + } else + printf("EGPv%u, length %u", + egp->egp_version, + length); + + if (egp->egp_version != EGP_VERSION) { + printf("[version %d]", egp->egp_version); + return; + } + + type = egp->egp_type; + code = egp->egp_code; + status = egp->egp_status; + + switch (type) { + case EGPT_ACQUIRE: + printf(" acquire"); + switch (code) { + case EGPC_REQUEST: + case EGPC_CONFIRM: + printf(" %s", egp_acquire_codes[code]); + switch (status) { + case EGPS_UNSPEC: + case EGPS_ACTIVE: + case EGPS_PASSIVE: + printf(" %s", egp_acquire_status[status]); + break; + + default: + printf(" [status %d]", status); + break; + } + printf(" hello:%d poll:%d", + EXTRACT_16BITS(&egp->egp_hello), + EXTRACT_16BITS(&egp->egp_poll)); + break; + + case EGPC_REFUSE: + case EGPC_CEASE: + case EGPC_CEASEACK: + printf(" %s", egp_acquire_codes[code]); + switch (status ) { + case EGPS_UNSPEC: + case EGPS_NORES: + case EGPS_ADMIN: + case EGPS_GODOWN: + case EGPS_PARAM: + case EGPS_PROTO: + printf(" %s", egp_acquire_status[status]); + break; + + default: + printf("[status %d]", status); + break; + } + break; + + default: + printf("[code %d]", code); + break; + } + break; + + case EGPT_REACH: + switch (code) { + + case EGPC_HELLO: + case EGPC_HEARDU: + printf(" %s", egp_reach_codes[code]); + if (status <= EGPS_DOWN) + printf(" state:%s", egp_status_updown[status]); + else + printf(" [status %d]", status); + break; + + default: + printf("[reach code %d]", code); + break; + } + break; + + case EGPT_POLL: + printf(" poll"); + if (egp->egp_status <= EGPS_DOWN) + printf(" state:%s", egp_status_updown[status]); + else + printf(" [status %d]", status); + printf(" net:%s", ipaddr_string(&egp->egp_sourcenet)); + break; + + case EGPT_UPDATE: + printf(" update"); + if (status & EGPS_UNSOL) { + status &= ~EGPS_UNSOL; + printf(" unsolicited"); + } + if (status <= EGPS_DOWN) + printf(" state:%s", egp_status_updown[status]); + else + printf(" [status %d]", status); + printf(" %s int %d ext %d", + ipaddr_string(&egp->egp_sourcenet), + egp->egp_intgw, + egp->egp_extgw); + if (vflag) + egpnrprint(egp); + break; + + case EGPT_ERROR: + printf(" error"); + if (status <= EGPS_DOWN) + printf(" state:%s", egp_status_updown[status]); + else + printf(" [status %d]", status); + + if (EXTRACT_16BITS(&egp->egp_reason) <= EGPR_UVERSION) + printf(" %s", egp_reasons[EXTRACT_16BITS(&egp->egp_reason)]); + else + printf(" [reason %d]", EXTRACT_16BITS(&egp->egp_reason)); + break; + + default: + printf("[type %d]", type); + break; + } +} diff --git a/print-eigrp.c b/print-eigrp.c new file mode 100644 index 0000000..2787baf --- /dev/null +++ b/print-eigrp.c @@ -0,0 +1,480 @@ +/* + * Copyright (c) 1998-2004 Hannes Gredler + * The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-eigrp.c,v 1.7 2005-05-06 02:53:26 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * packet format documented at + * http://www.rhyshaden.com/eigrp.htm + */ + +struct eigrp_common_header { + u_int8_t version; + u_int8_t opcode; + u_int8_t checksum[2]; + u_int8_t flags[4]; + u_int8_t seq[4]; + u_int8_t ack[4]; + u_int8_t asn[4]; +}; + +#define EIGRP_VERSION 2 + +#define EIGRP_OPCODE_UPDATE 1 +#define EIGRP_OPCODE_QUERY 3 +#define EIGRP_OPCODE_REPLY 4 +#define EIGRP_OPCODE_HELLO 5 +#define EIGRP_OPCODE_IPXSAP 6 +#define EIGRP_OPCODE_PROBE 7 + +static const struct tok eigrp_opcode_values[] = { + { EIGRP_OPCODE_UPDATE, "Update" }, + { EIGRP_OPCODE_QUERY, "Query" }, + { EIGRP_OPCODE_REPLY, "Reply" }, + { EIGRP_OPCODE_HELLO, "Hello" }, + { EIGRP_OPCODE_IPXSAP, "IPX SAP" }, + { EIGRP_OPCODE_PROBE, "Probe" }, + { 0, NULL} +}; + +static const struct tok eigrp_common_header_flag_values[] = { + { 0x01, "Init" }, + { 0x02, "Conditionally Received" }, + { 0, NULL} +}; + +struct eigrp_tlv_header { + u_int8_t type[2]; + u_int8_t length[2]; +}; + +#define EIGRP_TLV_GENERAL_PARM 0x0001 +#define EIGRP_TLV_AUTH 0x0002 +#define EIGRP_TLV_SEQ 0x0003 +#define EIGRP_TLV_SW_VERSION 0x0004 +#define EIGRP_TLV_MCAST_SEQ 0x0005 +#define EIGRP_TLV_IP_INT 0x0102 +#define EIGRP_TLV_IP_EXT 0x0103 +#define EIGRP_TLV_AT_INT 0x0202 +#define EIGRP_TLV_AT_EXT 0x0203 +#define EIGRP_TLV_AT_CABLE_SETUP 0x0204 +#define EIGRP_TLV_IPX_INT 0x0302 +#define EIGRP_TLV_IPX_EXT 0x0303 + +static const struct tok eigrp_tlv_values[] = { + { EIGRP_TLV_GENERAL_PARM, "General Parameters"}, + { EIGRP_TLV_AUTH, "Authentication"}, + { EIGRP_TLV_SEQ, "Sequence"}, + { EIGRP_TLV_SW_VERSION, "Software Version"}, + { EIGRP_TLV_MCAST_SEQ, "Next Multicast Sequence"}, + { EIGRP_TLV_IP_INT, "IP Internal routes"}, + { EIGRP_TLV_IP_EXT, "IP External routes"}, + { EIGRP_TLV_AT_INT, "AppleTalk Internal routes"}, + { EIGRP_TLV_AT_EXT, "AppleTalk External routes"}, + { EIGRP_TLV_AT_CABLE_SETUP, "AppleTalk Cable setup"}, + { EIGRP_TLV_IPX_INT, "IPX Internal routes"}, + { EIGRP_TLV_IPX_EXT, "IPX External routes"}, + { 0, NULL} +}; + +struct eigrp_tlv_general_parm_t { + u_int8_t k1; + u_int8_t k2; + u_int8_t k3; + u_int8_t k4; + u_int8_t k5; + u_int8_t res; + u_int8_t holdtime[2]; +}; + +struct eigrp_tlv_sw_version_t { + u_int8_t ios_major; + u_int8_t ios_minor; + u_int8_t eigrp_major; + u_int8_t eigrp_minor; +}; + +struct eigrp_tlv_ip_int_t { + u_int8_t nexthop[4]; + u_int8_t delay[4]; + u_int8_t bandwidth[4]; + u_int8_t mtu[3]; + u_int8_t hopcount; + u_int8_t reliability; + u_int8_t load; + u_int8_t reserved[2]; + u_int8_t plen; + u_int8_t destination; /* variable length [1-4] bytes encoding */ +}; + +struct eigrp_tlv_ip_ext_t { + u_int8_t nexthop[4]; + u_int8_t origin_router[4]; + u_int8_t origin_as[4]; + u_int8_t tag[4]; + u_int8_t metric[4]; + u_int8_t reserved[2]; + u_int8_t proto_id; + u_int8_t flags; + u_int8_t delay[4]; + u_int8_t bandwidth[4]; + u_int8_t mtu[3]; + u_int8_t hopcount; + u_int8_t reliability; + u_int8_t load; + u_int8_t reserved2[2]; + u_int8_t plen; + u_int8_t destination; /* variable length [1-4] bytes encoding */ +}; + +struct eigrp_tlv_at_cable_setup_t { + u_int8_t cable_start[2]; + u_int8_t cable_end[2]; + u_int8_t router_id[4]; +}; + +struct eigrp_tlv_at_int_t { + u_int8_t nexthop[4]; + u_int8_t delay[4]; + u_int8_t bandwidth[4]; + u_int8_t mtu[3]; + u_int8_t hopcount; + u_int8_t reliability; + u_int8_t load; + u_int8_t reserved[2]; + u_int8_t cable_start[2]; + u_int8_t cable_end[2]; +}; + +struct eigrp_tlv_at_ext_t { + u_int8_t nexthop[4]; + u_int8_t origin_router[4]; + u_int8_t origin_as[4]; + u_int8_t tag[4]; + u_int8_t proto_id; + u_int8_t flags; + u_int8_t metric[2]; + u_int8_t delay[4]; + u_int8_t bandwidth[4]; + u_int8_t mtu[3]; + u_int8_t hopcount; + u_int8_t reliability; + u_int8_t load; + u_int8_t reserved2[2]; + u_int8_t cable_start[2]; + u_int8_t cable_end[2]; +}; + +static const struct tok eigrp_ext_proto_id_values[] = { + { 0x01, "IGRP" }, + { 0x02, "EIGRP" }, + { 0x03, "Static" }, + { 0x04, "RIP" }, + { 0x05, "Hello" }, + { 0x06, "OSPF" }, + { 0x07, "IS-IS" }, + { 0x08, "EGP" }, + { 0x09, "BGP" }, + { 0x0a, "IDRP" }, + { 0x0b, "Connected" }, + { 0, NULL} +}; + +void +eigrp_print(register const u_char *pptr, register u_int len) { + + const struct eigrp_common_header *eigrp_com_header; + const struct eigrp_tlv_header *eigrp_tlv_header; + const u_char *tptr,*tlv_tptr; + u_int tlen,eigrp_tlv_len,eigrp_tlv_type,tlv_tlen, byte_length, bit_length; + u_int8_t prefix[4]; + + union { + const struct eigrp_tlv_general_parm_t *eigrp_tlv_general_parm; + const struct eigrp_tlv_sw_version_t *eigrp_tlv_sw_version; + const struct eigrp_tlv_ip_int_t *eigrp_tlv_ip_int; + const struct eigrp_tlv_ip_ext_t *eigrp_tlv_ip_ext; + const struct eigrp_tlv_at_cable_setup_t *eigrp_tlv_at_cable_setup; + const struct eigrp_tlv_at_int_t *eigrp_tlv_at_int; + const struct eigrp_tlv_at_ext_t *eigrp_tlv_at_ext; + } tlv_ptr; + + tptr=pptr; + eigrp_com_header = (const struct eigrp_common_header *)pptr; + TCHECK(*eigrp_com_header); + + /* + * Sanity checking of the header. + */ + if (eigrp_com_header->version != EIGRP_VERSION) { + printf("EIGRP version %u packet not supported",eigrp_com_header->version); + return; + } + + /* in non-verbose mode just lets print the basic Message Type*/ + if (vflag < 1) { + printf("EIGRP %s, length: %u", + tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + + tlen=len-sizeof(struct eigrp_common_header); + + /* FIXME print other header info */ + printf("\n\tEIGRP v%u, opcode: %s (%u), chksum: 0x%04x, Flags: [%s]\n\tseq: 0x%08x, ack: 0x%08x, AS: %u, length: %u", + eigrp_com_header->version, + tok2str(eigrp_opcode_values, "unknown, type: %u",eigrp_com_header->opcode), + eigrp_com_header->opcode, + EXTRACT_16BITS(&eigrp_com_header->checksum), + tok2str(eigrp_common_header_flag_values, + "none", + EXTRACT_32BITS(&eigrp_com_header->flags)), + EXTRACT_32BITS(&eigrp_com_header->seq), + EXTRACT_32BITS(&eigrp_com_header->ack), + EXTRACT_32BITS(&eigrp_com_header->asn), + tlen); + + tptr+=sizeof(const struct eigrp_common_header); + + while(tlen>0) { + /* did we capture enough for fully decoding the object header ? */ + TCHECK2(*tptr, sizeof(struct eigrp_tlv_header)); + + eigrp_tlv_header = (const struct eigrp_tlv_header *)tptr; + eigrp_tlv_len=EXTRACT_16BITS(&eigrp_tlv_header->length); + eigrp_tlv_type=EXTRACT_16BITS(&eigrp_tlv_header->type); + + + if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header) || + eigrp_tlv_len > tlen) { + print_unknown_data(tptr+sizeof(sizeof(struct eigrp_tlv_header)),"\n\t ",tlen); + return; + } + + printf("\n\t %s TLV (0x%04x), length: %u", + tok2str(eigrp_tlv_values, + "Unknown", + eigrp_tlv_type), + eigrp_tlv_type, + eigrp_tlv_len); + + tlv_tptr=tptr+sizeof(struct eigrp_tlv_header); + tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header); + + /* did we capture enough for fully decoding the object ? */ + TCHECK2(*tptr, eigrp_tlv_len); + + switch(eigrp_tlv_type) { + + case EIGRP_TLV_GENERAL_PARM: + tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr; + + printf("\n\t holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u", + EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime), + tlv_ptr.eigrp_tlv_general_parm->k1, + tlv_ptr.eigrp_tlv_general_parm->k2, + tlv_ptr.eigrp_tlv_general_parm->k3, + tlv_ptr.eigrp_tlv_general_parm->k4, + tlv_ptr.eigrp_tlv_general_parm->k5); + break; + + case EIGRP_TLV_SW_VERSION: + tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr; + + printf("\n\t IOS version: %u.%u, EIGRP version %u.%u", + tlv_ptr.eigrp_tlv_sw_version->ios_major, + tlv_ptr.eigrp_tlv_sw_version->ios_minor, + tlv_ptr.eigrp_tlv_sw_version->eigrp_major, + tlv_ptr.eigrp_tlv_sw_version->eigrp_minor); + break; + + case EIGRP_TLV_IP_INT: + tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr; + + bit_length = tlv_ptr.eigrp_tlv_ip_int->plen; + if (bit_length > 32) { + printf("\n\t illegal prefix length %u",bit_length); + break; + } + byte_length = (bit_length + 7) / 8; /* variable length encoding */ + memset(prefix, 0, 4); + memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_int->destination,byte_length); + + printf("\n\t IPv4 prefix: %15s/%u, nexthop: ", + ipaddr_string(prefix), + bit_length); + if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->nexthop) == 0) + printf("self"); + else + printf("%s",ipaddr_string(&tlv_ptr.eigrp_tlv_ip_int->nexthop)); + + printf("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", + (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->delay)/100), + EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->bandwidth), + EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_int->mtu), + tlv_ptr.eigrp_tlv_ip_int->hopcount, + tlv_ptr.eigrp_tlv_ip_int->reliability, + tlv_ptr.eigrp_tlv_ip_int->load); + break; + + case EIGRP_TLV_IP_EXT: + tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr; + + bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen; + if (bit_length > 32) { + printf("\n\t illegal prefix length %u",bit_length); + break; + } + byte_length = (bit_length + 7) / 8; /* variable length encoding */ + memset(prefix, 0, 4); + memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_ext->destination,byte_length); + + printf("\n\t IPv4 prefix: %15s/%u, nexthop: ", + ipaddr_string(prefix), + bit_length); + if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->nexthop) == 0) + printf("self"); + else + printf("%s",ipaddr_string(&tlv_ptr.eigrp_tlv_ip_ext->nexthop)); + + printf("\n\t origin-router %s, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u", + ipaddr_string(tlv_ptr.eigrp_tlv_ip_ext->origin_router), + EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->origin_as), + tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_ip_ext->proto_id), + tlv_ptr.eigrp_tlv_ip_ext->flags, + EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->tag), + EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->metric)); + + printf("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", + (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->delay)/100), + EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->bandwidth), + EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_ext->mtu), + tlv_ptr.eigrp_tlv_ip_ext->hopcount, + tlv_ptr.eigrp_tlv_ip_ext->reliability, + tlv_ptr.eigrp_tlv_ip_ext->load); + break; + + case EIGRP_TLV_AT_CABLE_SETUP: + tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr; + + printf("\n\t Cable-range: %u-%u, Router-ID %u", + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start), + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_end), + EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->router_id)); + break; + + case EIGRP_TLV_AT_INT: + tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr; + + printf("\n\t Cable-Range: %u-%u, nexthop: ", + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start), + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_end)); + + if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop) == 0) + printf("self"); + else + printf("%u.%u", + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop), + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop[2])); + + printf("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", + (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->delay)/100), + EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->bandwidth), + EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_int->mtu), + tlv_ptr.eigrp_tlv_at_int->hopcount, + tlv_ptr.eigrp_tlv_at_int->reliability, + tlv_ptr.eigrp_tlv_at_int->load); + break; + + case EIGRP_TLV_AT_EXT: + tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr; + + printf("\n\t Cable-Range: %u-%u, nexthop: ", + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start), + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_end)); + + if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop) == 0) + printf("self"); + else + printf("%u.%u", + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop), + EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop[2])); + + printf("\n\t origin-router %u, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u", + EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_router), + EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_as), + tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_at_ext->proto_id), + tlv_ptr.eigrp_tlv_at_ext->flags, + EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->tag), + EXTRACT_16BITS(tlv_ptr.eigrp_tlv_at_ext->metric)); + + printf("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", + (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->delay)/100), + EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->bandwidth), + EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_ext->mtu), + tlv_ptr.eigrp_tlv_at_ext->hopcount, + tlv_ptr.eigrp_tlv_at_ext->reliability, + tlv_ptr.eigrp_tlv_at_ext->load); + break; + + /* + * FIXME those are the defined TLVs that lack a decoder + * you are welcome to contribute code ;-) + */ + + case EIGRP_TLV_AUTH: + case EIGRP_TLV_SEQ: + case EIGRP_TLV_MCAST_SEQ: + case EIGRP_TLV_IPX_INT: + case EIGRP_TLV_IPX_EXT: + + default: + if (vflag <= 1) + print_unknown_data(tlv_tptr,"\n\t ",tlv_tlen); + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag > 1) + print_unknown_data(tptr+sizeof(sizeof(struct eigrp_tlv_header)),"\n\t ", + eigrp_tlv_len-sizeof(struct eigrp_tlv_header)); + + tptr+=eigrp_tlv_len; + tlen-=eigrp_tlv_len; + } + return; +trunc: + printf("\n\t\t packet exceeded snapshot"); +} diff --git a/print-enc.c b/print-enc.c new file mode 100644 index 0000000..e98f7f7 --- /dev/null +++ b/print-enc.c @@ -0,0 +1,98 @@ +/* $OpenBSD: print-enc.c,v 1.7 2002/02/19 19:39:40 millert Exp $ */ + +/* + * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-enc.c,v 1.6 2008-11-18 07:35:32 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +#include "enc.h" + +#define ENC_PRINT_TYPE(wh, xf, nam) \ + if ((wh) & (xf)) { \ + printf("%s%s", nam, (wh) == (xf) ? "): " : ","); \ + (wh) &= ~(xf); \ + } + +u_int +enc_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + register u_int length = h->len; + register u_int caplen = h->caplen; + int flags; + const struct enchdr *hdr; + + if (caplen < ENC_HDRLEN) { + printf("[|enc]"); + goto out; + } + + hdr = (struct enchdr *)p; + flags = hdr->flags; + if (flags == 0) + printf("(unprotected): "); + else + printf("("); + ENC_PRINT_TYPE(flags, M_AUTH, "authentic"); + ENC_PRINT_TYPE(flags, M_CONF, "confidential"); + /* ENC_PRINT_TYPE(flags, M_TUNNEL, "tunnel"); */ + printf("SPI 0x%08x: ", EXTRACT_32BITS(&hdr->spi)); + + length -= ENC_HDRLEN; + caplen -= ENC_HDRLEN; + p += ENC_HDRLEN; + + switch (hdr->af) { + case AF_INET: + ip_print(gndo, p, length); + break; +#ifdef INET6 + case AF_INET6: + ip6_print(p, length); + break; +#endif /*INET6*/ + } + +out: + return (ENC_HDRLEN); +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-esp.c b/print-esp.c new file mode 100644 index 0000000..ade654a --- /dev/null +++ b/print-esp.c @@ -0,0 +1,694 @@ +/* $NetBSD: print-ah.c,v 1.4 1996/05/20 00:41:16 fvdl Exp $ */ + +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.58 2007-12-07 00:03:07 mcr Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include + +#ifdef HAVE_LIBCRYPTO +#ifdef HAVE_OPENSSL_EVP_H +#include +#endif +#endif + +#include + +#include "ip.h" +#include "esp.h" +#ifdef INET6 +#include "ip6.h" +#endif + +#include "netdissect.h" +#include "addrtoname.h" +#include "extract.h" + +#ifndef HAVE_SOCKADDR_STORAGE +#ifdef INET6 +struct sockaddr_storage { + union { + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + } un; +}; +#else +#define sockaddr_storage sockaddr +#endif +#endif /* HAVE_SOCKADDR_STORAGE */ + +#ifdef HAVE_LIBCRYPTO +struct sa_list { + struct sa_list *next; + struct sockaddr_storage daddr; + u_int32_t spi; /* if == 0, then IKEv2 */ + int initiator; + u_char spii[8]; /* for IKEv2 */ + u_char spir[8]; + const EVP_CIPHER *evp; + int ivlen; + int authlen; + u_char authsecret[256]; + int authsecret_len; + u_char secret[256]; /* is that big enough for all secrets? */ + int secretlen; +}; + +/* + * this will adjust ndo_packetp and ndo_snapend to new buffer! + */ +int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo, + int initiator, + u_char spii[8], u_char spir[8], + u_char *buf, u_char *end) +{ + struct sa_list *sa; + u_char *iv; + int len; + EVP_CIPHER_CTX ctx; + + /* initiator arg is any non-zero value */ + if(initiator) initiator=1; + + /* see if we can find the SA, and if so, decode it */ + for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) { + if (sa->spi == 0 + && initiator == sa->initiator + && memcmp(spii, sa->spii, 8) == 0 + && memcmp(spir, sa->spir, 8) == 0) + break; + } + + if(sa == NULL) return 0; + if(sa->evp == NULL) return 0; + + /* + * remove authenticator, and see if we still have something to + * work with + */ + end = end - sa->authlen; + iv = buf; + buf = buf + sa->ivlen; + len = end-buf; + + if(end <= buf) return 0; + + memset(&ctx, 0, sizeof(ctx)); + if (EVP_CipherInit(&ctx, sa->evp, sa->secret, NULL, 0) < 0) + (*ndo->ndo_warning)(ndo, "espkey init failed"); + EVP_CipherInit(&ctx, NULL, NULL, iv, 0); + EVP_Cipher(&ctx, buf, buf, len); + EVP_CIPHER_CTX_cleanup(&ctx); + + ndo->ndo_packetp = buf; + ndo->ndo_snapend = end; + + return 1; + +} + +static void esp_print_addsa(netdissect_options *ndo, + struct sa_list *sa, int sa_def) +{ + /* copy the "sa" */ + + struct sa_list *nsa; + + nsa = (struct sa_list *)malloc(sizeof(struct sa_list)); + if (nsa == NULL) + (*ndo->ndo_error)(ndo, "ran out of memory to allocate sa structure"); + + *nsa = *sa; + + if (sa_def) + ndo->ndo_sa_default = nsa; + + nsa->next = ndo->ndo_sa_list_head; + ndo->ndo_sa_list_head = nsa; +} + + +static u_int hexdigit(netdissect_options *ndo, char hex) +{ + if (hex >= '0' && hex <= '9') + return (hex - '0'); + else if (hex >= 'A' && hex <= 'F') + return (hex - 'A' + 10); + else if (hex >= 'a' && hex <= 'f') + return (hex - 'a' + 10); + else { + (*ndo->ndo_error)(ndo, "invalid hex digit %c in espsecret\n", hex); + return 0; + } +} + +static u_int hex2byte(netdissect_options *ndo, char *hexstring) +{ + u_int byte; + + byte = (hexdigit(ndo, hexstring[0]) << 4) + hexdigit(ndo, hexstring[1]); + return byte; +} + +/* + * returns size of binary, 0 on failure. + */ +static +int espprint_decode_hex(netdissect_options *ndo, + u_char *binbuf, unsigned int binbuf_len, + char *hex) +{ + unsigned int len; + int i; + + len = strlen(hex) / 2; + + if (len > binbuf_len) { + (*ndo->ndo_warning)(ndo, "secret is too big: %d\n", len); + return 0; + } + + i = 0; + while (hex[0] != '\0' && hex[1]!='\0') { + binbuf[i] = hex2byte(ndo, hex); + hex += 2; + i++; + } + + return i; +} + +/* + * decode the form: SPINUM@IP ALGONAME:0xsecret + */ + +static int +espprint_decode_encalgo(netdissect_options *ndo, + char *decode, struct sa_list *sa) +{ + int len; + size_t i; + const EVP_CIPHER *evp; + int authlen = 0; + char *colon, *p; + + colon = strchr(decode, ':'); + if (colon == NULL) { + (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode); + return 0; + } + *colon = '\0'; + + len = colon - decode; + if (strlen(decode) > strlen("-hmac96") && + !strcmp(decode + strlen(decode) - strlen("-hmac96"), + "-hmac96")) { + p = strstr(decode, "-hmac96"); + *p = '\0'; + authlen = 12; + } + if (strlen(decode) > strlen("-cbc") && + !strcmp(decode + strlen(decode) - strlen("-cbc"), "-cbc")) { + p = strstr(decode, "-cbc"); + *p = '\0'; + } + evp = EVP_get_cipherbyname(decode); + + if (!evp) { + (*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode); + sa->evp = NULL; + sa->authlen = 0; + sa->ivlen = 0; + return 0; + } + + sa->evp = evp; + sa->authlen = authlen; + sa->ivlen = EVP_CIPHER_iv_length(evp); + + colon++; + if (colon[0] == '0' && colon[1] == 'x') { + /* decode some hex! */ + + colon += 2; + sa->secretlen = espprint_decode_hex(ndo, sa->secret, sizeof(sa->secret), colon); + if(sa->secretlen == 0) return 0; + } else { + i = strlen(colon); + + if (i < sizeof(sa->secret)) { + memcpy(sa->secret, colon, i); + sa->secretlen = i; + } else { + memcpy(sa->secret, colon, sizeof(sa->secret)); + sa->secretlen = sizeof(sa->secret); + } + } + + return 1; +} + +/* + * for the moment, ignore the auth algorith, just hard code the authenticator + * length. Need to research how openssl looks up HMAC stuff. + */ +static int +espprint_decode_authalgo(netdissect_options *ndo, + char *decode, struct sa_list *sa) +{ + char *colon; + + colon = strchr(decode, ':'); + if (colon == NULL) { + (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode); + return 0; + } + *colon = '\0'; + + if(strcasecmp(colon,"sha1") == 0 || + strcasecmp(colon,"md5") == 0) { + sa->authlen = 12; + } + return 1; +} + +static void esp_print_decode_ikeline(netdissect_options *ndo, char *line, + const char *file, int lineno) +{ + /* it's an IKEv2 secret, store it instead */ + struct sa_list sa1; + + char *init; + char *icookie, *rcookie; + int ilen, rlen; + char *authkey; + char *enckey; + + init = strsep(&line, " \t"); + icookie = strsep(&line, " \t"); + rcookie = strsep(&line, " \t"); + authkey = strsep(&line, " \t"); + enckey = strsep(&line, " \t"); + + /* if any fields are missing */ + if(!init || !icookie || !rcookie || !authkey || !enckey) { + (*ndo->ndo_warning)(ndo, "print_esp: failed to find all fields for ikev2 at %s:%u", + file, lineno); + + return; + } + + ilen = strlen(icookie); + rlen = strlen(rcookie); + + if((init[0]!='I' && init[0]!='R') + || icookie[0]!='0' || icookie[1]!='x' + || rcookie[0]!='0' || rcookie[1]!='x' + || ilen!=18 + || rlen!=18) { + (*ndo->ndo_warning)(ndo, "print_esp: line %s:%u improperly formatted.", + file, lineno); + + (*ndo->ndo_warning)(ndo, "init=%s icookie=%s(%u) rcookie=%s(%u)", + init, icookie, ilen, rcookie, rlen); + + return; + } + + sa1.spi = 0; + sa1.initiator = (init[0] == 'I'); + if(espprint_decode_hex(ndo, sa1.spii, sizeof(sa1.spii), icookie+2)!=8) + return; + + if(espprint_decode_hex(ndo, sa1.spir, sizeof(sa1.spir), rcookie+2)!=8) + return; + + if(!espprint_decode_encalgo(ndo, enckey, &sa1)) return; + + if(!espprint_decode_authalgo(ndo, authkey, &sa1)) return; + + esp_print_addsa(ndo, &sa1, FALSE); +} + +/* + * + * special form: file /name + * causes us to go read from this file instead. + * + */ +static void esp_print_decode_onesecret(netdissect_options *ndo, char *line, + const char *file, int lineno) +{ + struct sa_list sa1; + int sa_def; + + char *spikey; + char *decode; + + spikey = strsep(&line, " \t"); + sa_def = 0; + memset(&sa1, 0, sizeof(struct sa_list)); + + /* if there is only one token, then it is an algo:key token */ + if (line == NULL) { + decode = spikey; + spikey = NULL; + /* memset(&sa1.daddr, 0, sizeof(sa1.daddr)); */ + /* sa1.spi = 0; */ + sa_def = 1; + } else + decode = line; + + if (spikey && strcasecmp(spikey, "file") == 0) { + /* open file and read it */ + FILE *secretfile; + char fileline[1024]; + int lineno=0; + char *nl; + char *filename = line; + + secretfile = fopen(filename, FOPEN_READ_TXT); + if (secretfile == NULL) { + perror(filename); + exit(3); + } + + while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) { + lineno++; + /* remove newline from the line */ + nl = strchr(fileline, '\n'); + if (nl) + *nl = '\0'; + if (fileline[0] == '#') continue; + if (fileline[0] == '\0') continue; + + esp_print_decode_onesecret(ndo, fileline, filename, lineno); + } + fclose(secretfile); + + return; + } + + if (spikey && strcasecmp(spikey, "ikev2") == 0) { + esp_print_decode_ikeline(ndo, line, file, lineno); + return; + } + + if (spikey) { + + char *spistr, *foo; + u_int32_t spino; + struct sockaddr_in *sin; +#ifdef INET6 + struct sockaddr_in6 *sin6; +#endif + + spistr = strsep(&spikey, "@"); + + spino = strtoul(spistr, &foo, 0); + if (spistr == foo || !spikey) { + (*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo); + return; + } + + sa1.spi = spino; + + sin = (struct sockaddr_in *)&sa1.daddr; +#ifdef INET6 + sin6 = (struct sockaddr_in6 *)&sa1.daddr; + if (inet_pton(AF_INET6, spikey, &sin6->sin6_addr) == 1) { +#ifdef HAVE_SOCKADDR_SA_LEN + sin6->sin6_len = sizeof(struct sockaddr_in6); +#endif + sin6->sin6_family = AF_INET6; + } else +#endif + if (inet_pton(AF_INET, spikey, &sin->sin_addr) == 1) { +#ifdef HAVE_SOCKADDR_SA_LEN + sin->sin_len = sizeof(struct sockaddr_in); +#endif + sin->sin_family = AF_INET; + } else { + (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey); + return; + } + } + + if (decode) { + /* skip any blank spaces */ + while (isspace((unsigned char)*decode)) + decode++; + + if(!espprint_decode_encalgo(ndo, decode, &sa1)) { + return; + } + } + + esp_print_addsa(ndo, &sa1, sa_def); +} + +static void esp_init(netdissect_options *ndo _U_) +{ + + OpenSSL_add_all_algorithms(); + EVP_add_cipher_alias(SN_des_ede3_cbc, "3des"); +} + +void esp_print_decodesecret(netdissect_options *ndo) +{ + char *line; + char *p; + static int initialized = 0; + + if (!initialized) { + esp_init(ndo); + initialized = 1; + } + + p = ndo->ndo_espsecret; + + while (p && p[0] != '\0') { + /* pick out the first line or first thing until a comma */ + if ((line = strsep(&p, "\n,")) == NULL) { + line = p; + p = NULL; + } + + esp_print_decode_onesecret(ndo, line, "cmdline", 0); + } + + ndo->ndo_espsecret = NULL; +} + +#endif + +int +esp_print(netdissect_options *ndo, + const u_char *bp, const int length, const u_char *bp2 +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + , + int *nhdr +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + , + int *padlen +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + ) +{ + register const struct newesp *esp; + register const u_char *ep; +#ifdef HAVE_LIBCRYPTO + struct ip *ip; + struct sa_list *sa = NULL; + int espsecret_keylen; +#ifdef INET6 + struct ip6_hdr *ip6 = NULL; +#endif + int advance; + int len; + u_char *secret; + int ivlen = 0; + u_char *ivoff; + u_char *p; + EVP_CIPHER_CTX ctx; + int blocksz; +#endif + + esp = (struct newesp *)bp; + +#ifdef HAVE_LIBCRYPTO + secret = NULL; + advance = 0; +#endif + +#if 0 + /* keep secret out of a register */ + p = (u_char *)&secret; +#endif + + /* 'ep' points to the end of available data. */ + ep = ndo->ndo_snapend; + + if ((u_char *)(esp + 1) >= ep) { + fputs("[|ESP]", stdout); + goto fail; + } + (*ndo->ndo_printf)(ndo, "ESP(spi=0x%08x", EXTRACT_32BITS(&esp->esp_spi)); + (*ndo->ndo_printf)(ndo, ",seq=0x%x)", EXTRACT_32BITS(&esp->esp_seq)); + (*ndo->ndo_printf)(ndo, ", length %u", length); + +#ifndef HAVE_LIBCRYPTO + goto fail; +#else + /* initiailize SAs */ + if (ndo->ndo_sa_list_head == NULL) { + if (!ndo->ndo_espsecret) + goto fail; + + esp_print_decodesecret(ndo); + } + + if (ndo->ndo_sa_list_head == NULL) + goto fail; + + ip = (struct ip *)bp2; + switch (IP_V(ip)) { +#ifdef INET6 + case 6: + ip6 = (struct ip6_hdr *)bp2; + /* we do not attempt to decrypt jumbograms */ + if (!EXTRACT_16BITS(&ip6->ip6_plen)) + goto fail; + /* if we can't get nexthdr, we do not need to decrypt it */ + len = sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen); + + /* see if we can find the SA, and if so, decode it */ + for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa->daddr; + if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) && + sin6->sin6_family == AF_INET6 && + memcmp(&sin6->sin6_addr, &ip6->ip6_dst, + sizeof(struct in6_addr)) == 0) { + break; + } + } + break; +#endif /*INET6*/ + case 4: + /* nexthdr & padding are in the last fragment */ + if (EXTRACT_16BITS(&ip->ip_off) & IP_MF) + goto fail; + len = EXTRACT_16BITS(&ip->ip_len); + + /* see if we can find the SA, and if so, decode it */ + for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) { + struct sockaddr_in *sin = (struct sockaddr_in *)&sa->daddr; + if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) && + sin->sin_family == AF_INET && + sin->sin_addr.s_addr == ip->ip_dst.s_addr) { + break; + } + } + break; + default: + goto fail; + } + + /* if we didn't find the specific one, then look for + * an unspecified one. + */ + if (sa == NULL) + sa = ndo->ndo_sa_default; + + /* if not found fail */ + if (sa == NULL) + goto fail; + + /* if we can't get nexthdr, we do not need to decrypt it */ + if (ep - bp2 < len) + goto fail; + if (ep - bp2 > len) { + /* FCS included at end of frame (NetBSD 1.6 or later) */ + ep = bp2 + len; + } + + ivoff = (u_char *)(esp + 1) + 0; + ivlen = sa->ivlen; + secret = sa->secret; + espsecret_keylen = sa->secretlen; + ep = ep - sa->authlen; + + if (sa->evp) { + memset(&ctx, 0, sizeof(ctx)); + if (EVP_CipherInit(&ctx, sa->evp, secret, NULL, 0) < 0) + (*ndo->ndo_warning)(ndo, "espkey init failed"); + + blocksz = EVP_CIPHER_CTX_block_size(&ctx); + + p = ivoff; + EVP_CipherInit(&ctx, NULL, NULL, p, 0); + EVP_Cipher(&ctx, p + ivlen, p + ivlen, ep - (p + ivlen)); + EVP_CIPHER_CTX_cleanup(&ctx); + advance = ivoff - (u_char *)esp + ivlen; + } else + advance = sizeof(struct newesp); + + /* sanity check for pad length */ + if (ep - bp < *(ep - 2)) + goto fail; + + if (padlen) + *padlen = *(ep - 2) + 2; + + if (nhdr) + *nhdr = *(ep - 1); + + (ndo->ndo_printf)(ndo, ": "); + return advance; +#endif + +fail: + return -1; +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-ether.c b/print-ether.c new file mode 100644 index 0000000..e086d16 --- /dev/null +++ b/print-ether.c @@ -0,0 +1,359 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.106 2008-02-06 10:47:53 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ethertype.h" + +#include "ether.h" + +const struct tok ethertype_values[] = { + { ETHERTYPE_IP, "IPv4" }, + { ETHERTYPE_MPLS, "MPLS unicast" }, + { ETHERTYPE_MPLS_MULTI, "MPLS multicast" }, + { ETHERTYPE_IPV6, "IPv6" }, + { ETHERTYPE_8021Q, "802.1Q" }, + { ETHERTYPE_VMAN, "VMAN" }, + { ETHERTYPE_PUP, "PUP" }, + { ETHERTYPE_ARP, "ARP"}, + { ETHERTYPE_REVARP, "Reverse ARP"}, + { ETHERTYPE_NS, "NS" }, + { ETHERTYPE_SPRITE, "Sprite" }, + { ETHERTYPE_TRAIL, "Trail" }, + { ETHERTYPE_MOPDL, "MOP DL" }, + { ETHERTYPE_MOPRC, "MOP RC" }, + { ETHERTYPE_DN, "DN" }, + { ETHERTYPE_LAT, "LAT" }, + { ETHERTYPE_SCA, "SCA" }, + { ETHERTYPE_TEB, "TEB" }, + { ETHERTYPE_LANBRIDGE, "Lanbridge" }, + { ETHERTYPE_DECDNS, "DEC DNS" }, + { ETHERTYPE_DECDTS, "DEC DTS" }, + { ETHERTYPE_VEXP, "VEXP" }, + { ETHERTYPE_VPROD, "VPROD" }, + { ETHERTYPE_ATALK, "Appletalk" }, + { ETHERTYPE_AARP, "Appletalk ARP" }, + { ETHERTYPE_IPX, "IPX" }, + { ETHERTYPE_PPP, "PPP" }, + { ETHERTYPE_MPCP, "MPCP" }, + { ETHERTYPE_SLOW, "Slow Protocols" }, + { ETHERTYPE_PPPOED, "PPPoE D" }, + { ETHERTYPE_PPPOES, "PPPoE S" }, + { ETHERTYPE_EAPOL, "EAPOL" }, + { ETHERTYPE_RRCP, "RRCP" }, + { ETHERTYPE_JUMBO, "Jumbo" }, + { ETHERTYPE_LOOPBACK, "Loopback" }, + { ETHERTYPE_ISO, "OSI" }, + { ETHERTYPE_GRE_ISO, "GRE-OSI" }, + { ETHERTYPE_CFM_OLD, "CFM (old)" }, + { ETHERTYPE_CFM, "CFM" }, + { ETHERTYPE_LLDP, "LLDP" }, + { 0, NULL} +}; + +static inline void +ether_hdr_print(register const u_char *bp, u_int length) +{ + register const struct ether_header *ep; + u_int16_t ether_type; + + ep = (const struct ether_header *)bp; + + (void)printf("%s > %s", + etheraddr_string(ESRC(ep)), + etheraddr_string(EDST(ep))); + + ether_type = EXTRACT_16BITS(&ep->ether_type); + if (!qflag) { + if (ether_type <= ETHERMTU) + (void)printf(", 802.3"); + else + (void)printf(", ethertype %s (0x%04x)", + tok2str(ethertype_values,"Unknown", ether_type), + ether_type); + } else { + if (ether_type <= ETHERMTU) + (void)printf(", 802.3"); + else + (void)printf(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ether_type)); + } + + (void)printf(", length %u: ", length); +} + +/* + * Print an Ethernet frame. + * This might be encapsulated within another frame; we might be passed + * a pointer to a function that can print header information for that + * frame's protocol, and an argument to pass to that function. + */ +void +ether_print(const u_char *p, u_int length, u_int caplen, + void (*print_encap_header)(const u_char *), const u_char *encap_header_arg) +{ + struct ether_header *ep; + u_int orig_length; + u_short ether_type; + u_short extracted_ether_type; + + if (caplen < ETHER_HDRLEN || length < ETHER_HDRLEN) { + printf("[|ether]"); + return; + } + + if (eflag) { + if (print_encap_header != NULL) + (*print_encap_header)(encap_header_arg); + ether_hdr_print(p, length); + } + orig_length = length; + + length -= ETHER_HDRLEN; + caplen -= ETHER_HDRLEN; + ep = (struct ether_header *)p; + p += ETHER_HDRLEN; + + ether_type = EXTRACT_16BITS(&ep->ether_type); + +recurse: + /* + * Is it (gag) an 802.3 encapsulation? + */ + if (ether_type <= ETHERMTU) { + /* Try to print the LLC-layer header & higher layers */ + if (llc_print(p, length, caplen, ESRC(ep), EDST(ep), + &extracted_ether_type) == 0) { + /* ether_type not known, print raw packet */ + if (!eflag) { + if (print_encap_header != NULL) + (*print_encap_header)(encap_header_arg); + ether_hdr_print((u_char *)ep, orig_length); + } + + if (!suppress_default_print) + default_print(p, caplen); + } + } else if (ether_type == ETHERTYPE_8021Q) { + /* + * Print VLAN information, and then go back and process + * the enclosed type field. + */ + if (caplen < 4 || length < 4) { + printf("[|vlan]"); + return; + } + if (eflag) { + u_int16_t tag = EXTRACT_16BITS(p); + + printf("vlan %u, p %u%s, ", + tag & 0xfff, + tag >> 13, + (tag & 0x1000) ? ", CFI" : ""); + } + + ether_type = EXTRACT_16BITS(p + 2); + if (eflag && ether_type > ETHERMTU) + printf("ethertype %s, ", tok2str(ethertype_values,"0x%04x", ether_type)); + p += 4; + length -= 4; + caplen -= 4; + goto recurse; + } else if (ether_type == ETHERTYPE_JUMBO) { + /* + * Alteon jumbo frames. + * See + * + * http://tools.ietf.org/html/draft-ietf-isis-ext-eth-01 + * + * which indicates that, following the type field, + * there's an LLC header and payload. + */ + /* Try to print the LLC-layer header & higher layers */ + if (llc_print(p, length, caplen, ESRC(ep), EDST(ep), + &extracted_ether_type) == 0) { + /* ether_type not known, print raw packet */ + if (!eflag) { + if (print_encap_header != NULL) + (*print_encap_header)(encap_header_arg); + ether_hdr_print((u_char *)ep, orig_length); + } + + if (!suppress_default_print) + default_print(p, caplen); + } + } else { + if (ethertype_print(ether_type, p, length, caplen) == 0) { + /* ether_type not known, print raw packet */ + if (!eflag) { + if (print_encap_header != NULL) + (*print_encap_header)(encap_header_arg); + ether_hdr_print((u_char *)ep, orig_length); + } + + if (!suppress_default_print) + default_print(p, caplen); + } + } +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +ether_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + ether_print(p, h->len, h->caplen, NULL, NULL); + + return (ETHER_HDRLEN); +} + +/* + * Prints the packet payload, given an Ethernet type code for the payload's + * protocol. + * + * Returns non-zero if it can do so, zero if the ethertype is unknown. + */ + +int +ethertype_print(u_short ether_type, const u_char *p, u_int length, u_int caplen) +{ + switch (ether_type) { + + case ETHERTYPE_IP: + ip_print(gndo, p, length); + return (1); + +#ifdef INET6 + case ETHERTYPE_IPV6: + ip6_print(p, length); + return (1); +#endif /*INET6*/ + + case ETHERTYPE_ARP: + case ETHERTYPE_REVARP: + arp_print(gndo, p, length, caplen); + return (1); + + case ETHERTYPE_DN: + decnet_print(p, length, caplen); + return (1); + + case ETHERTYPE_ATALK: + if (vflag) + fputs("et1 ", stdout); + atalk_print(p, length); + return (1); + + case ETHERTYPE_AARP: + aarp_print(p, length); + return (1); + + case ETHERTYPE_IPX: + printf("(NOV-ETHII) "); + ipx_print(p, length); + return (1); + + case ETHERTYPE_ISO: + isoclns_print(p+1, length-1, length-1); + return(1); + + case ETHERTYPE_PPPOED: + case ETHERTYPE_PPPOES: + case ETHERTYPE_PPPOED2: + case ETHERTYPE_PPPOES2: + pppoe_print(p, length); + return (1); + + case ETHERTYPE_EAPOL: + eap_print(gndo, p, length); + return (1); + + case ETHERTYPE_RRCP: + rrcp_print(gndo, p - 14 , length + 14); + return (1); + + case ETHERTYPE_PPP: + if (length) { + printf(": "); + ppp_print(p, length); + } + return (1); + + case ETHERTYPE_MPCP: + mpcp_print(p, length); + return (1); + + case ETHERTYPE_SLOW: + slow_print(p, length); + return (1); + + case ETHERTYPE_CFM: + case ETHERTYPE_CFM_OLD: + cfm_print(p, length); + return (1); + + case ETHERTYPE_LLDP: + lldp_print(p, length); + return (1); + + case ETHERTYPE_LOOPBACK: + return (1); + + case ETHERTYPE_MPLS: + case ETHERTYPE_MPLS_MULTI: + mpls_print(p, length); + return (1); + + case ETHERTYPE_LAT: + case ETHERTYPE_SCA: + case ETHERTYPE_MOPRC: + case ETHERTYPE_MOPDL: + /* default_print for now */ + default: + return (0); + } +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ + diff --git a/print-fddi.c b/print-fddi.c new file mode 100644 index 0000000..1e7d554 --- /dev/null +++ b/print-fddi.c @@ -0,0 +1,309 @@ +/* + * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-fddi.c,v 1.66 2005-11-13 12:12:41 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "ethertype.h" + +#include "ether.h" +#include "fddi.h" + +/* + * Some FDDI interfaces use bit-swapped addresses. + */ +#if defined(ultrix) || defined(__alpha) || defined(__bsdi) || defined(__NetBSD__) || defined(__linux__) +int fddi_bitswap = 0; +#else +int fddi_bitswap = 1; +#endif + +/* + * FDDI support for tcpdump, by Jeffrey Mogul [DECWRL], June 1992 + * + * Based in part on code by Van Jacobson, which bears this note: + * + * NOTE: This is a very preliminary hack for FDDI support. + * There are all sorts of wired in constants & nothing (yet) + * to print SMT packets as anything other than hex dumps. + * Most of the necessary changes are waiting on my redoing + * the "header" that a kernel fddi driver supplies to bpf: I + * want it to look like one byte of 'direction' (0 or 1 + * depending on whether the packet was inbound or outbound), + * two bytes of system/driver dependent data (anything an + * implementor thinks would be useful to filter on and/or + * save per-packet, then the real 21-byte FDDI header. + * Steve McCanne & I have also talked about adding the + * 'direction' byte to all bpf headers (e.g., in the two + * bytes of padding on an ethernet header). It's not clear + * we could do this in a backwards compatible way & we hate + * the idea of an incompatible bpf change. Discussions are + * proceeding. + * + * Also, to really support FDDI (and better support 802.2 + * over ethernet) we really need to re-think the rather simple + * minded assumptions about fixed length & fixed format link + * level headers made in gencode.c. One day... + * + * - vj + */ + +static u_char fddi_bit_swap[] = { + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, +}; + +/* + * Print FDDI frame-control bits + */ +static inline void +print_fddi_fc(u_char fc) +{ + switch (fc) { + + case FDDIFC_VOID: /* Void frame */ + printf("void "); + break; + + case FDDIFC_NRT: /* Nonrestricted token */ + printf("nrt "); + break; + + case FDDIFC_RT: /* Restricted token */ + printf("rt "); + break; + + case FDDIFC_SMT_INFO: /* SMT Info */ + printf("info "); + break; + + case FDDIFC_SMT_NSA: /* SMT Next station adrs */ + printf("nsa "); + break; + + case FDDIFC_MAC_BEACON: /* MAC Beacon frame */ + printf("beacon "); + break; + + case FDDIFC_MAC_CLAIM: /* MAC Claim frame */ + printf("claim "); + break; + + default: + switch (fc & FDDIFC_CLFF) { + + case FDDIFC_MAC: + printf("mac%1x ", fc & FDDIFC_ZZZZ); + break; + + case FDDIFC_SMT: + printf("smt%1x ", fc & FDDIFC_ZZZZ); + break; + + case FDDIFC_LLC_ASYNC: + printf("async%1x ", fc & FDDIFC_ZZZZ); + break; + + case FDDIFC_LLC_SYNC: + printf("sync%1x ", fc & FDDIFC_ZZZZ); + break; + + case FDDIFC_IMP_ASYNC: + printf("imp_async%1x ", fc & FDDIFC_ZZZZ); + break; + + case FDDIFC_IMP_SYNC: + printf("imp_sync%1x ", fc & FDDIFC_ZZZZ); + break; + + default: + printf("%02x ", fc); + break; + } + } +} + +/* Extract src, dst addresses */ +static inline void +extract_fddi_addrs(const struct fddi_header *fddip, char *fsrc, char *fdst) +{ + register int i; + + if (fddi_bitswap) { + /* + * bit-swap the fddi addresses (isn't the IEEE standards + * process wonderful!) then convert them to names. + */ + for (i = 0; i < 6; ++i) + fdst[i] = fddi_bit_swap[fddip->fddi_dhost[i]]; + for (i = 0; i < 6; ++i) + fsrc[i] = fddi_bit_swap[fddip->fddi_shost[i]]; + } + else { + memcpy(fdst, (const char *)fddip->fddi_dhost, 6); + memcpy(fsrc, (const char *)fddip->fddi_shost, 6); + } +} + +/* + * Print the FDDI MAC header + */ +static inline void +fddi_hdr_print(register const struct fddi_header *fddip, register u_int length, + register const u_char *fsrc, register const u_char *fdst) +{ + const char *srcname, *dstname; + + srcname = etheraddr_string(fsrc); + dstname = etheraddr_string(fdst); + + if (vflag) + (void) printf("%02x %s %s %d: ", + fddip->fddi_fc, + srcname, dstname, + length); + else if (qflag) + printf("%s %s %d: ", srcname, dstname, length); + else { + (void) print_fddi_fc(fddip->fddi_fc); + (void) printf("%s %s %d: ", srcname, dstname, length); + } +} + +static inline void +fddi_smt_print(const u_char *p _U_, u_int length _U_) +{ + printf(""); +} + +void +fddi_print(const u_char *p, u_int length, u_int caplen) +{ + const struct fddi_header *fddip = (const struct fddi_header *)p; + struct ether_header ehdr; + u_short extracted_ethertype; + + if (caplen < FDDI_HDRLEN) { + printf("[|fddi]"); + return; + } + + /* + * Get the FDDI addresses into a canonical form + */ + extract_fddi_addrs(fddip, (char *)ESRC(&ehdr), (char *)EDST(&ehdr)); + + if (eflag) + fddi_hdr_print(fddip, length, ESRC(&ehdr), EDST(&ehdr)); + + /* Skip over FDDI MAC header */ + length -= FDDI_HDRLEN; + p += FDDI_HDRLEN; + caplen -= FDDI_HDRLEN; + + /* Frame Control field determines interpretation of packet */ + if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) { + /* Try to print the LLC-layer header & higher layers */ + if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr), + &extracted_ethertype) == 0) { + /* + * Some kinds of LLC packet we cannot + * handle intelligently + */ + if (!eflag) + fddi_hdr_print(fddip, length + FDDI_HDRLEN, + ESRC(&ehdr), EDST(&ehdr)); + if (extracted_ethertype) { + printf("(LLC %s) ", + etherproto_string(htons(extracted_ethertype))); + } + if (!suppress_default_print) + default_print(p, caplen); + } + } else if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_SMT) + fddi_smt_print(p, caplen); + else { + /* Some kinds of FDDI packet we cannot handle intelligently */ + if (!eflag) + fddi_hdr_print(fddip, length + FDDI_HDRLEN, ESRC(&ehdr), + EDST(&ehdr)); + if (!suppress_default_print) + default_print(p, caplen); + } +} + +/* + * This is the top level routine of the printer. 'p' points + * to the FDDI header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +fddi_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + fddi_print(p, h->len, h->caplen); + + return (FDDI_HDRLEN); +} diff --git a/print-forces.c b/print-forces.c new file mode 100644 index 0000000..26e83d3 --- /dev/null +++ b/print-forces.c @@ -0,0 +1,1043 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Copyright (c) 2009 Mojatatu Networks, Inc + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "extract.h" + +#include "forces.h" + +#define RESLEN 4 + +int +prestlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + register const u_char *tdp = (u_char *) TLV_DATA(tlv); + struct res_val *r = (struct res_val *)tdp; + u_int dlen; + + /* + * pdatacnt_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen != RESLEN) { + printf("illegal RESULT-TLV: %d bytes!\n", dlen); + return -1; + } + + TCHECK(*r); + if (r->result >= 0x18 && r->result <= 0xFE) { + printf("illegal reserved result code: 0x%x!\n", r->result); + return -1; + } + + if (vflag >= 3) { + char *ib = indent_pr(indent, 0); + printf("%s Result: %s (code 0x%x)\n", ib, + tok2str(ForCES_errs, NULL, r->result), r->result); + } + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +fdatatlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + u_int rlen; + register const u_char *tdp = (u_char *) TLV_DATA(tlv); + u_int16_t type; + + /* + * pdatacnt_print() or pkeyitlv_print() has ensured that len + * (the TLV length) >= TLV_HDRL. + */ + rlen = len - TLV_HDRL; + TCHECK(*tlv); + type = EXTRACT_16BITS(&tlv->type); + if (type != F_TLV_FULD) { + printf("Error: expecting FULLDATA!\n"); + return -1; + } + + if (vflag >= 3) { + char *ib = indent_pr(indent + 2, 1); + printf("%s[", &ib[1]); + hex_print_with_offset(ib, tdp, rlen, 0); + printf("\n%s]\n", &ib[1]); + } + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +sdatailv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int rlen; + const struct forces_ilv *ilv = (struct forces_ilv *)pptr; + int invilv; + + if (len < ILV_HDRL) { + printf("Error: BAD SPARSEDATA-TLV!\n"); + return -1; + } + rlen = len - ILV_HDRL; + indent += 1; + while (rlen != 0) { + TCHECK(*ilv); + invilv = ilv_valid(ilv, rlen); + if (invilv) { + printf("Error: BAD ILV!\n"); + return -1; + } + if (vflag >= 3) { + register const u_char *tdp = (u_char *) ILV_DATA(ilv); + char *ib = indent_pr(indent, 1); + printf("\n%s SPARSEDATA: type %x length %d\n", &ib[1], + EXTRACT_32BITS(&ilv->type), + EXTRACT_32BITS(&ilv->length)); + printf("%s[", &ib[1]); + hex_print_with_offset(ib, tdp, rlen, 0); + printf("\n%s]\n", &ib[1]); + } + + ilv = GO_NXT_ILV(ilv, rlen); + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +sdatatlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + u_int rlen; + register const u_char *tdp = (u_char *) TLV_DATA(tlv); + u_int16_t type; + + /* + * pdatacnt_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + rlen = len - TLV_HDRL; + TCHECK(*tlv); + type = EXTRACT_16BITS(&tlv->type); + if (type != F_TLV_SPAD) { + printf("Error: expecting SPARSEDATA!\n"); + return -1; + } + + return sdatailv_print(tdp, rlen, op_msk, indent); + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +pkeyitlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + register const u_char *tdp = (u_char *) TLV_DATA(tlv); + register const u_char *dp = tdp + 4; + const struct forces_tlv *kdtlv = (struct forces_tlv *)dp; + u_int32_t id; + char *ib = indent_pr(indent, 0); + u_int16_t type, tll; + int invtlv; + + TCHECK(*tdp); + id = EXTRACT_32BITS(tdp); + printf("%sKeyinfo: Key 0x%x\n", ib, id); + TCHECK(*kdtlv); + type = EXTRACT_16BITS(&kdtlv->type); + invtlv = tlv_valid(kdtlv, len); + + if (invtlv) { + printf("%s TLV type 0x%x len %d\n", + tok2str(ForCES_TLV_err, NULL, invtlv), type, + EXTRACT_16BITS(&kdtlv->length)); + return -1; + } + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + tll = EXTRACT_16BITS(&kdtlv->length); + dp = (u_char *) TLV_DATA(kdtlv); + return fdatatlv_print(dp, tll, op_msk, indent); + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +pdatacnt_print(register const u_char * pptr, register u_int len, + u_int32_t IDcnt, u_int16_t op_msk, int indent) +{ + u_int i; + int rc; + u_int32_t id; + char *ib = indent_pr(indent, 0); + + for (i = 0; i < IDcnt; i++) { + TCHECK2(*pptr, 4); + if (len < 4) + goto trunc; + id = EXTRACT_32BITS(pptr); + if (vflag >= 3) + printf("%s ID#%02u: %d\n", ib, i + 1, id); + len -= 4; + pptr += 4; + } + if (len) { + const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; + u_int16_t type; + u_int16_t tll; + int pad = 0; + u_int aln; + int invtlv; + + TCHECK(*pdtlv); + type = EXTRACT_16BITS(&pdtlv->type); + invtlv = tlv_valid(pdtlv, len); + if (invtlv) { + printf + ("%s Outstanding bytes %d for TLV type 0x%x TLV len %d\n", + tok2str(ForCES_TLV_err, NULL, invtlv), len, type, + EXTRACT_16BITS(&pdtlv->length)); + goto pd_err; + } + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; + aln = F_ALN_LEN(EXTRACT_16BITS(&pdtlv->length)); + if (aln > EXTRACT_16BITS(&pdtlv->length)) { + if (aln > len) { + printf + ("Invalid padded pathdata TLV type 0x%x len %d missing %d pad bytes\n", + type, EXTRACT_16BITS(&pdtlv->length), aln - len); + } else { + pad = aln - EXTRACT_16BITS(&pdtlv->length); + } + } + if (pd_valid(type)) { + const struct pdata_ops *ops = get_forces_pd(type); + + if (vflag >= 3 && ops->v != F_TLV_PDAT) { + if (pad) + printf + ("%s %s (Length %d DataLen %d pad %d Bytes)\n", + ib, ops->s, EXTRACT_16BITS(&pdtlv->length), + tll, pad); + else + printf + ("%s %s (Length %d DataLen %d Bytes)\n", + ib, ops->s, EXTRACT_16BITS(&pdtlv->length), + tll); + } + + chk_op_type(type, op_msk, ops->op_msk); + + rc = ops->print((const u_char *)pdtlv, + tll + pad + TLV_HDRL, op_msk, + indent + 2); + } else { + printf("Invalid path data content type 0x%x len %d\n", + type, EXTRACT_16BITS(&pdtlv->length)); +pd_err: + if (EXTRACT_16BITS(&pdtlv->length)) { + hex_print_with_offset("Bad Data val\n\t [", + pptr, len, 0); + printf("]\n"); + + return -1; + } + } + } + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +pdata_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct pathdata_h *pdh = (struct pathdata_h *)pptr; + char *ib = indent_pr(indent, 0); + u_int minsize = 0; + + TCHECK(*pdh); + if (len < sizeof(struct pathdata_h)) + goto trunc; + if (vflag >= 3) { + printf("\n%sPathdata: Flags 0x%x ID count %d\n", + ib, EXTRACT_16BITS(&pdh->pflags), EXTRACT_16BITS(&pdh->pIDcnt)); + } + + if (EXTRACT_16BITS(&pdh->pflags) & F_SELKEY) { + op_msk |= B_KEYIN; + } + pptr += sizeof(struct pathdata_h); + len -= sizeof(struct pathdata_h); + minsize = EXTRACT_16BITS(&pdh->pIDcnt) * 4; + if (len < minsize) { + printf("\t\t\ttruncated IDs expected %uB got %uB\n", minsize, + len); + hex_print_with_offset("\t\t\tID Data[", pptr, len, 0); + printf("]\n"); + return -1; + } + return pdatacnt_print(pptr, len, EXTRACT_16BITS(&pdh->pIDcnt), op_msk, indent); + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +genoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; + u_int16_t type; + int tll; + int invtlv; + char *ib = indent_pr(indent, 0); + + TCHECK(*pdtlv); + type = EXTRACT_16BITS(&pdtlv->type); + tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; + invtlv = tlv_valid(pdtlv, len); + printf("genoptlvprint - %s TLV type 0x%x len %d\n", + tok2str(ForCES_TLV, NULL, type), type, EXTRACT_16BITS(&pdtlv->length)); + if (!invtlv) { + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + register const u_char *dp = (u_char *) TLV_DATA(pdtlv); + if (!ttlv_valid(type)) { + printf("%s TLV type 0x%x len %d\n", + tok2str(ForCES_TLV_err, NULL, invtlv), type, + EXTRACT_16BITS(&pdtlv->length)); + return -1; + } + if (vflag >= 3) + printf("%s%s, length %d (data length %d Bytes)", + ib, tok2str(ForCES_TLV, NULL, type), + EXTRACT_16BITS(&pdtlv->length), tll); + + return pdata_print(dp, tll, op_msk, indent + 1); + } else { + printf("\t\t\tInvalid ForCES TLV type=%x", type); + return -1; + } + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +recpdoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr; + int tll; + int rc = 0; + int invtlv; + u_int16_t type; + register const u_char *dp; + char *ib; + + while (len != 0) { + TCHECK(*pdtlv); + invtlv = tlv_valid(pdtlv, len); + if (invtlv) { + break; + } + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + ib = indent_pr(indent, 0); + type = EXTRACT_16BITS(&pdtlv->type); + dp = (u_char *) TLV_DATA(pdtlv); + tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL; + + if (vflag >= 3) + printf + ("%s%s, length %d (data encapsulated %d Bytes)", + ib, tok2str(ForCES_TLV, NULL, type), + EXTRACT_16BITS(&pdtlv->length), + EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL); + + rc = pdata_print(dp, tll, op_msk, indent + 1); + pdtlv = GO_NXT_TLV(pdtlv, len); + } + + if (len) { + printf + ("\n\t\tMessy PATHDATA TLV header, type (0x%x)\n\t\texcess of %d Bytes ", + EXTRACT_16BITS(&pdtlv->type), len - EXTRACT_16BITS(&pdtlv->length)); + return -1; + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +invoptlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + char *ib = indent_pr(indent, 1); + + if (vflag >= 3) { + printf("%sData[", &ib[1]); + hex_print_with_offset(ib, pptr, len, 0); + printf("%s]\n", ib); + } + return -1; +} + +int otlv_print(const struct forces_tlv *otlv, u_int16_t op_msk _U_, int indent) +{ + int rc = 0; + register const u_char *dp = (u_char *) TLV_DATA(otlv); + u_int16_t type; + int tll; + char *ib = indent_pr(indent, 0); + const struct optlv_h *ops; + + /* + * lfbselect_print() has ensured that EXTRACT_16BITS(&otlv->length) + * >= TLV_HDRL. + */ + TCHECK(*otlv); + type = EXTRACT_16BITS(&otlv->type); + tll = EXTRACT_16BITS(&otlv->length) - TLV_HDRL; + ops = get_forces_optlv_h(type); + if (vflag >= 3) { + printf("%sOper TLV %s(0x%x) length %d\n", ib, ops->s, type, + EXTRACT_16BITS(&otlv->length)); + } + /* empty TLVs like COMMIT and TRCOMMIT are empty, we stop here .. */ + if (!ops->flags & ZERO_TTLV) { + if (tll != 0) /* instead of "if (tll)" - for readability .. */ + printf("%s: Illegal - MUST be empty\n", ops->s); + return rc; + } + /* rest of ops must at least have 12B {pathinfo} */ + if (tll < OP_MIN_SIZ) { + printf("\t\tOper TLV %s(0x%x) length %d\n", ops->s, type, + EXTRACT_16BITS(&otlv->length)); + printf("\t\tTruncated data size %d minimum required %d\n", tll, + OP_MIN_SIZ); + return invoptlv_print(dp, tll, ops->op_msk, indent); + + } + + rc = ops->print(dp, tll, ops->op_msk, indent + 1); + return rc; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +#define ASTDLN 4 +#define ASTMCD 255 +int +asttlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int32_t rescode; + u_int dlen; + char *ib = indent_pr(indent, 0); + + /* + * forces_type_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen != ASTDLN) { + printf("illegal ASTresult-TLV: %d bytes!\n", dlen); + return -1; + } + TCHECK2(*pptr, 4); + rescode = EXTRACT_32BITS(pptr); + if (rescode > ASTMCD) { + printf("illegal ASTresult result code: %d!\n", rescode); + return -1; + } + + if (vflag >= 3) { + printf("Teardown reason:\n%s", ib); + switch (rescode) { + case 0: + printf("Normal Teardown"); + break; + case 1: + printf("Loss of Heartbeats"); + break; + case 2: + printf("Out of bandwidth"); + break; + case 3: + printf("Out of Memory"); + break; + case 4: + printf("Application Crash"); + break; + default: + printf("Unknown Teardown reason"); + break; + } + printf("(%x)\n%s", rescode, ib); + } + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +#define ASRDLN 4 +#define ASRMCD 3 +int +asrtlv_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int32_t rescode; + u_int dlen; + char *ib = indent_pr(indent, 0); + + /* + * forces_type_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen != ASRDLN) { /* id, instance, oper tlv */ + printf("illegal ASRresult-TLV: %d bytes!\n", dlen); + return -1; + } + TCHECK2(*pptr, 4); + rescode = EXTRACT_32BITS(pptr); + + if (rescode > ASRMCD) { + printf("illegal ASRresult result code: %d!\n", rescode); + return -1; + } + + if (vflag >= 3) { + printf("\n%s", ib); + switch (rescode) { + case 0: + printf("Success "); + break; + case 1: + printf("FE ID invalid "); + break; + case 2: + printf("permission denied "); + break; + default: + printf("Unknown "); + break; + } + printf("(%x)\n%s", rescode, ib); + } + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +/* + * XXX - not used. + */ +int +gentltlv_print(register const u_char * pptr _U_, register u_int len, + u_int16_t op_msk _U_, int indent _U_) +{ + u_int dlen = len - TLV_HDRL; + + if (dlen < 4) { /* at least 32 bits must exist */ + printf("truncated TLV: %d bytes missing! ", 4 - dlen); + return -1; + } + return 0; +} + +#define RD_MIN 8 +int +print_metailv(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int dlen; + u_int rlen; + char *ib = indent_pr(indent, 0); + /* XXX: check header length */ + const struct forces_ilv *ilv = (struct forces_ilv *)pptr; + + /* + * print_metatlv() has ensured that len (what remains in the + * ILV) >= ILV_HDRL. + */ + dlen = len - ILV_HDRL; + rlen = dlen; + TCHECK(*ilv); + printf("\n%sMetaID 0x%x length %d\n", ib, EXTRACT_32BITS(&ilv->type), + EXTRACT_32BITS(&ilv->length)); + hex_print_with_offset("\n\t\t\t\t[", ILV_DATA(ilv), rlen, 0); + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +print_metatlv(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + u_int dlen; + char *ib = indent_pr(indent, 0); + u_int rlen; + const struct forces_ilv *ilv = (struct forces_ilv *)pptr; + int invilv; + + /* + * redirect_print() has ensured that len (what remains in the + * TLV) >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + rlen = dlen; + printf("\n%s METADATA\n", ib); + while (rlen != 0) { + TCHECK(*ilv); + invilv = ilv_valid(ilv, rlen); + if (invilv) + break; + + /* + * At this point, ilv_valid() has ensured that the ILV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + print_metailv((u_char *) ilv, rlen, 0, indent + 1); + + ilv = GO_NXT_ILV(ilv, rlen); + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +/* +*/ +int +print_reddata(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent _U_) +{ + u_int dlen; + u_int rlen; + int invtlv; + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + + /* + * redirect_print() has ensured that len (what remains in the + * TLV) >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + printf("\n\t\t Redirect DATA\n"); + if (dlen <= RD_MIN) { + printf("\n\t\ttruncated Redirect data: %d bytes missing! ", + RD_MIN - dlen); + return -1; + } + + rlen = dlen; + TCHECK(*tlv); + invtlv = tlv_valid(tlv, rlen); + + if (invtlv) { + printf("Redir data type 0x%x len %d\n", EXTRACT_16BITS(&tlv->type), + EXTRACT_16BITS(&tlv->length)); + return -1; + } + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + rlen -= TLV_HDRL; + hex_print_with_offset("\n\t\t\t[", TLV_DATA(tlv), rlen, 0); + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +redirect_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk _U_, int indent) +{ + const struct forces_tlv *tlv = (struct forces_tlv *)pptr; + u_int dlen; + u_int rlen; + int invtlv; + + /* + * forces_type_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen <= RD_MIN) { + printf("\n\t\ttruncated Redirect TLV: %d bytes missing! ", + RD_MIN - dlen); + return -1; + } + + rlen = dlen; + indent += 1; + while (rlen != 0) { + TCHECK(*tlv); + invtlv = tlv_valid(tlv, rlen); + if (invtlv) + break; + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + if (EXTRACT_16BITS(&tlv->type) == F_TLV_METD) { + print_metatlv((u_char *) TLV_DATA(tlv), rlen, 0, indent); + } else if ((EXTRACT_16BITS(&tlv->type) == F_TLV_REDD)) { + print_reddata((u_char *) TLV_DATA(tlv), rlen, 0, indent); + } else { + printf("Unknown REDIRECT TLV 0x%x len %d\n", + EXTRACT_16BITS(&tlv->type), EXTRACT_16BITS(&tlv->length)); + } + + tlv = GO_NXT_TLV(tlv, rlen); + } + + if (rlen) { + printf + ("\n\t\tMessy Redirect TLV header, type (0x%x)\n\t\texcess of %d Bytes ", + EXTRACT_16BITS(&tlv->type), rlen - EXTRACT_16BITS(&tlv->length)); + return -1; + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +#define OP_OFF 8 +#define OP_MIN 12 + +int +lfbselect_print(register const u_char * pptr, register u_int len, + u_int16_t op_msk, int indent) +{ + const struct forces_lfbsh *lfbs; + const struct forces_tlv *otlv; + char *ib = indent_pr(indent, 0); + u_int dlen; + u_int rlen; + int invtlv; + + /* + * forces_type_print() has ensured that len (the TLV length) + * >= TLV_HDRL. + */ + dlen = len - TLV_HDRL; + if (dlen <= OP_MIN) { /* id, instance, oper tlv header .. */ + printf("\n\t\ttruncated lfb selector: %d bytes missing! ", + OP_MIN - dlen); + return -1; + } + + /* + * At this point, we know that dlen > OP_MIN; OP_OFF < OP_MIN, so + * we also know that it's > OP_OFF. + */ + rlen = dlen - OP_OFF; + + lfbs = (const struct forces_lfbsh *)pptr; + TCHECK(*lfbs); + if (vflag >= 3) { + printf("\n%s%s(Classid %x) instance %x\n", + ib, tok2str(ForCES_LFBs, NULL, EXTRACT_32BITS(&lfbs->class)), + EXTRACT_32BITS(&lfbs->class), + EXTRACT_32BITS(&lfbs->instance)); + } + + otlv = (struct forces_tlv *)(lfbs + 1); + + indent += 1; + while (rlen != 0) { + TCHECK(*otlv); + invtlv = tlv_valid(otlv, rlen); + if (invtlv) + break; + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the containing TLV). + */ + if (op_valid(EXTRACT_16BITS(&otlv->type), op_msk)) { + otlv_print(otlv, 0, indent); + } else { + if (vflag < 3) + printf("\n"); + printf + ("\t\tINValid oper-TLV type 0x%x length %d for this ForCES message\n", + EXTRACT_16BITS(&otlv->type), EXTRACT_16BITS(&otlv->length)); + invoptlv_print((u_char *)otlv, rlen, 0, indent); + } + otlv = GO_NXT_TLV(otlv, rlen); + } + + if (rlen) { + printf + ("\n\t\tMessy oper TLV header, type (0x%x)\n\t\texcess of %d Bytes ", + EXTRACT_16BITS(&otlv->type), rlen - EXTRACT_16BITS(&otlv->length)); + return -1; + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +int +forces_type_print(register const u_char * pptr, const struct forcesh *fhdr _U_, + register u_int mlen, const struct tom_h *tops) +{ + const struct forces_tlv *tltlv; + u_int rlen; + int invtlv; + int rc = 0; + int ttlv = 0; + + /* + * forces_print() has already checked that mlen >= ForCES_HDRL + * by calling ForCES_HLN_VALID(). + */ + rlen = mlen - ForCES_HDRL; + + if (rlen > TLV_HLN) { + if (tops->flags & ZERO_TTLV) { + printf("<0x%x>Illegal Top level TLV!\n", tops->flags); + return -1; + } + } else { + if (tops->flags & ZERO_MORE_TTLV) + return 0; + if (tops->flags & ONE_MORE_TTLV) { + printf("\tTop level TLV Data missing!\n"); + return -1; + } + } + + if (tops->flags & ZERO_TTLV) { + return 0; + } + + ttlv = tops->flags >> 4; + tltlv = GET_TOP_TLV(pptr); + + /*XXX: 15 top level tlvs will probably be fine + You are nuts if you send more ;-> */ + while (rlen != 0) { + TCHECK(*tltlv); + invtlv = tlv_valid(tltlv, rlen); + if (invtlv) + break; + + /* + * At this point, tlv_valid() has ensured that the TLV + * length is large enough but not too large (it doesn't + * go past the end of the packet). + */ + if (!ttlv_valid(EXTRACT_16BITS(&tltlv->type))) { + printf("\n\tInvalid ForCES Top TLV type=0x%x", + EXTRACT_16BITS(&tltlv->type)); + return -1; + } + + if (vflag >= 3) + printf("\t%s, length %d (data length %d Bytes)", + tok2str(ForCES_TLV, NULL, EXTRACT_16BITS(&tltlv->type)), + EXTRACT_16BITS(&tltlv->length), + EXTRACT_16BITS(&tltlv->length) - TLV_HDRL); + + rc = tops->print((u_char *) TLV_DATA(tltlv), + EXTRACT_16BITS(&tltlv->length), tops->op_msk, 9); + if (rc < 0) { + return -1; + } + tltlv = GO_NXT_TLV(tltlv, rlen); + ttlv--; + if (ttlv <= 0) + break; + } + /* + * XXX - if ttlv != 0, does that mean that the packet was too + * short, and didn't have *enough* TLVs in it? + */ + if (rlen) { + printf("\tMess TopTLV header: min %u, total %d advertised %d ", + TLV_HDRL, rlen, EXTRACT_16BITS(&tltlv->length)); + return -1; + } + + return 0; + +trunc: + fputs("[|forces]", stdout); + return -1; +} + +void forces_print(register const u_char * pptr, register u_int len) +{ + const struct forcesh *fhdr; + u_int mlen; + u_int32_t flg_raw; + const struct tom_h *tops; + int rc = 0; + + fhdr = (const struct forcesh *)pptr; + TCHECK(*fhdr); + if (!tom_valid(fhdr->fm_tom)) { + printf("Invalid ForCES message type %d\n", fhdr->fm_tom); + goto error; + } + + mlen = ForCES_BLN(fhdr); + + tops = get_forces_tom(fhdr->fm_tom); + if (tops->v == TOM_RSVD) { + printf("\n\tUnknown ForCES message type=0x%x", fhdr->fm_tom); + goto error; + } + + printf("\n\tForCES %s ", tops->s); + if (!ForCES_HLN_VALID(mlen, len)) { + printf + ("Illegal ForCES pkt len - min %u, total recvd %d, advertised %d ", + ForCES_HDRL, len, ForCES_BLN(fhdr)); + goto error; + } + + TCHECK2(*(pptr + 20), 4); + flg_raw = EXTRACT_32BITS(pptr + 20); + if (vflag >= 1) { + printf("\n\tForCES Version %d len %uB flags 0x%08x ", + ForCES_V(fhdr), mlen, flg_raw); + printf("\n\tSrcID 0x%x(%s) DstID 0x%x(%s) Correlator 0x%" PRIu64, + ForCES_SID(fhdr), ForCES_node(ForCES_SID(fhdr)), + ForCES_DID(fhdr), ForCES_node(ForCES_DID(fhdr)), + EXTRACT_64BITS(fhdr->fm_cor)); + + } + if (vflag >= 2) { + printf + ("\n\tForCES flags:\n\t %s(0x%x), prio=%d, %s(0x%x),\n\t %s(0x%x), %s(0x%x)\n", + ForCES_ACKp(ForCES_ACK(fhdr)), ForCES_ACK(fhdr), + ForCES_PRI(fhdr), + ForCES_EMp(ForCES_EM(fhdr)), ForCES_EM(fhdr), + ForCES_ATp(ForCES_AT(fhdr)), ForCES_AT(fhdr), + ForCES_TPp(ForCES_TP(fhdr)), ForCES_TP(fhdr)); + printf + ("\t Extra flags: rsv(b5-7) 0x%x rsv(b13-31) 0x%x\n", + ForCES_RS1(fhdr), ForCES_RS2(fhdr)); + } + rc = forces_type_print(pptr, fhdr, mlen, tops); + if (rc < 0) { +error: + hex_print_with_offset("\n\t[", pptr, len, 0); + printf("\n\t]"); + return; + } + + if (vflag >= 4) { + printf("\n\t Raw ForCES message\n\t ["); + hex_print_with_offset("\n\t ", pptr, len, 0); + printf("\n\t ]"); + } + printf("\n"); + return; + +trunc: + fputs("[|forces]", stdout); +} diff --git a/print-fr.c b/print-fr.c new file mode 100644 index 0000000..8f1409e --- /dev/null +++ b/print-fr.c @@ -0,0 +1,883 @@ +/* + * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#)$Header: /tcpdump/master/tcpdump/print-fr.c,v 1.51 2006-06-23 22:20:32 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "addrtoname.h" +#include "interface.h" +#include "ethertype.h" +#include "nlpid.h" +#include "extract.h" +#include "oui.h" + +static void frf15_print(const u_char *, u_int); + +/* + * the frame relay header has a variable length + * + * the EA bit determines if there is another byte + * in the header + * + * minimum header length is 2 bytes + * maximum header length is 4 bytes + * + * 7 6 5 4 3 2 1 0 + * +----+----+----+----+----+----+----+----+ + * | DLCI (6 bits) | CR | EA | + * +----+----+----+----+----+----+----+----+ + * | DLCI (4 bits) |FECN|BECN| DE | EA | + * +----+----+----+----+----+----+----+----+ + * | DLCI (7 bits) | EA | + * +----+----+----+----+----+----+----+----+ + * | DLCI (6 bits) |SDLC| EA | + * +----+----+----+----+----+----+----+----+ + */ + +#define FR_EA_BIT 0x01 + +#define FR_CR_BIT 0x02000000 +#define FR_DE_BIT 0x00020000 +#define FR_BECN_BIT 0x00040000 +#define FR_FECN_BIT 0x00080000 +#define FR_SDLC_BIT 0x00000002 + + +struct tok fr_header_flag_values[] = { + { FR_CR_BIT, "C!" }, + { FR_DE_BIT, "DE" }, + { FR_BECN_BIT, "BECN" }, + { FR_FECN_BIT, "FECN" }, + { FR_SDLC_BIT, "sdlcore" }, + { 0, NULL } +}; + +/* FRF.15 / FRF.16 */ +#define MFR_B_BIT 0x80 +#define MFR_E_BIT 0x40 +#define MFR_C_BIT 0x20 +#define MFR_BEC_MASK (MFR_B_BIT | MFR_E_BIT | MFR_C_BIT) +#define MFR_CTRL_FRAME (MFR_B_BIT | MFR_E_BIT | MFR_C_BIT) +#define MFR_FRAG_FRAME (MFR_B_BIT | MFR_E_BIT ) + +struct tok frf_flag_values[] = { + { MFR_B_BIT, "Begin" }, + { MFR_E_BIT, "End" }, + { MFR_C_BIT, "Control" }, + { 0, NULL } +}; + +/* Finds out Q.922 address length, DLCI and flags. Returns 0 on success + * save the flags dep. on address length + */ +static int parse_q922_addr(const u_char *p, u_int *dlci, + u_int *addr_len, u_int8_t *flags) +{ + if ((p[0] & FR_EA_BIT)) + return -1; + + *addr_len = 2; + *dlci = ((p[0] & 0xFC) << 2) | ((p[1] & 0xF0) >> 4); + + flags[0] = p[0] & 0x02; /* populate the first flag fields */ + flags[1] = p[1] & 0x0c; + flags[2] = 0; /* clear the rest of the flags */ + flags[3] = 0; + + if (p[1] & FR_EA_BIT) + return 0; /* 2-byte Q.922 address */ + + p += 2; + (*addr_len)++; /* 3- or 4-byte Q.922 address */ + if ((p[0] & FR_EA_BIT) == 0) { + *dlci = (*dlci << 7) | (p[0] >> 1); + (*addr_len)++; /* 4-byte Q.922 address */ + p++; + } + + if ((p[0] & FR_EA_BIT) == 0) + return -1; /* more than 4 bytes of Q.922 address? */ + + flags[3] = p[0] & 0x02; + + *dlci = (*dlci << 6) | (p[0] >> 2); + + return 0; +} + +char *q922_string(const u_char *p) { + + static u_int dlci, addr_len; + static u_int8_t flags[4]; + static char buffer[sizeof("DLCI xxxxxxxxxx")]; + memset(buffer, 0, sizeof(buffer)); + + if (parse_q922_addr(p, &dlci, &addr_len, flags) == 0){ + snprintf(buffer, sizeof(buffer), "DLCI %u", dlci); + } + + return buffer; +} + + +/* Frame Relay packet structure, with flags and CRC removed + + +---------------------------+ + | Q.922 Address* | + +-- --+ + | | + +---------------------------+ + | Control (UI = 0x03) | + +---------------------------+ + | Optional Pad (0x00) | + +---------------------------+ + | NLPID | + +---------------------------+ + | . | + | . | + | . | + | Data | + | . | + | . | + +---------------------------+ + + * Q.922 addresses, as presently defined, are two octets and + contain a 10-bit DLCI. In some networks Q.922 addresses + may optionally be increased to three or four octets. +*/ + +static u_int +fr_hdrlen(const u_char *p, u_int addr_len) +{ + if (!p[addr_len + 1] /* pad exist */) + return addr_len + 1 /* UI */ + 1 /* pad */ + 1 /* NLPID */; + else + return addr_len + 1 /* UI */ + 1 /* NLPID */; +} + +static void +fr_hdr_print(int length, u_int addr_len, u_int dlci, u_int8_t *flags, u_int16_t nlpid) +{ + if (qflag) { + (void)printf("Q.922, DLCI %u, length %u: ", + dlci, + length); + } else { + if (nlpid <= 0xff) /* if its smaller than 256 then its a NLPID */ + (void)printf("Q.922, hdr-len %u, DLCI %u, Flags [%s], NLPID %s (0x%02x), length %u: ", + addr_len, + dlci, + bittok2str(fr_header_flag_values, "none", EXTRACT_32BITS(flags)), + tok2str(nlpid_values,"unknown", nlpid), + nlpid, + length); + else /* must be an ethertype */ + (void)printf("Q.922, hdr-len %u, DLCI %u, Flags [%s], cisco-ethertype %s (0x%04x), length %u: ", + addr_len, + dlci, + bittok2str(fr_header_flag_values, "none", EXTRACT_32BITS(flags)), + tok2str(ethertype_values, "unknown", nlpid), + nlpid, + length); + } +} + +u_int +fr_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + register u_int length = h->len; + register u_int caplen = h->caplen; + + TCHECK2(*p, 4); /* minimum frame header length */ + + if ((length = fr_print(p, length)) == 0) + return (0); + else + return length; + trunc: + printf("[|fr]"); + return caplen; +} + +u_int +fr_print(register const u_char *p, u_int length) +{ + u_int16_t extracted_ethertype; + u_int dlci; + u_int addr_len; + u_int16_t nlpid; + u_int hdr_len; + u_int8_t flags[4]; + + if (parse_q922_addr(p, &dlci, &addr_len, flags)) { + printf("Q.922, invalid address"); + return 0; + } + + TCHECK2(*p,addr_len+1+1); + hdr_len = fr_hdrlen(p, addr_len); + TCHECK2(*p,hdr_len); + + if (p[addr_len] != 0x03 && dlci != 0) { + + /* lets figure out if we have cisco style encapsulation: */ + extracted_ethertype = EXTRACT_16BITS(p+addr_len); + + if (eflag) + fr_hdr_print(length, addr_len, dlci, flags, extracted_ethertype); + + if (ethertype_print(extracted_ethertype, + p+addr_len+ETHERTYPE_LEN, + length-addr_len-ETHERTYPE_LEN, + length-addr_len-ETHERTYPE_LEN) == 0) + /* ether_type not known, probably it wasn't one */ + printf("UI %02x! ", p[addr_len]); + else + return hdr_len; + } + + if (!p[addr_len + 1]) { /* pad byte should be used with 3-byte Q.922 */ + if (addr_len != 3) + printf("Pad! "); + } else if (addr_len == 3) + printf("No pad! "); + + nlpid = p[hdr_len - 1]; + + if (eflag) + fr_hdr_print(length, addr_len, dlci, flags, nlpid); + p += hdr_len; + length -= hdr_len; + + switch (nlpid) { + case NLPID_IP: + ip_print(gndo, p, length); + break; + +#ifdef INET6 + case NLPID_IP6: + ip6_print(p, length); + break; +#endif + case NLPID_CLNP: + case NLPID_ESIS: + case NLPID_ISIS: + isoclns_print(p-1, length+1, length+1); /* OSI printers need the NLPID field */ + break; + + case NLPID_SNAP: + if (snap_print(p, length, length, 0) == 0) { + /* ether_type not known, print raw packet */ + if (!eflag) + fr_hdr_print(length + hdr_len, hdr_len, + dlci, flags, nlpid); + if (!suppress_default_print) + default_print(p - hdr_len, length + hdr_len); + } + break; + + case NLPID_Q933: + q933_print(p, length); + break; + + case NLPID_MFR: + frf15_print(p, length); + break; + + case NLPID_PPP: + ppp_print(p, length); + break; + + default: + if (!eflag) + fr_hdr_print(length + hdr_len, addr_len, + dlci, flags, nlpid); + if (!xflag) + default_print(p, length); + } + + return hdr_len; + + trunc: + printf("[|fr]"); + return 0; + +} + +u_int +mfr_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + register u_int length = h->len; + register u_int caplen = h->caplen; + + TCHECK2(*p, 2); /* minimum frame header length */ + + if ((length = mfr_print(p, length)) == 0) + return (0); + else + return length; + trunc: + printf("[|mfr]"); + return caplen; +} + + +#define MFR_CTRL_MSG_ADD_LINK 1 +#define MFR_CTRL_MSG_ADD_LINK_ACK 2 +#define MFR_CTRL_MSG_ADD_LINK_REJ 3 +#define MFR_CTRL_MSG_HELLO 4 +#define MFR_CTRL_MSG_HELLO_ACK 5 +#define MFR_CTRL_MSG_REMOVE_LINK 6 +#define MFR_CTRL_MSG_REMOVE_LINK_ACK 7 + +struct tok mfr_ctrl_msg_values[] = { + { MFR_CTRL_MSG_ADD_LINK, "Add Link" }, + { MFR_CTRL_MSG_ADD_LINK_ACK, "Add Link ACK" }, + { MFR_CTRL_MSG_ADD_LINK_REJ, "Add Link Reject" }, + { MFR_CTRL_MSG_HELLO, "Hello" }, + { MFR_CTRL_MSG_HELLO_ACK, "Hello ACK" }, + { MFR_CTRL_MSG_REMOVE_LINK, "Remove Link" }, + { MFR_CTRL_MSG_REMOVE_LINK_ACK, "Remove Link ACK" }, + { 0, NULL } +}; + +#define MFR_CTRL_IE_BUNDLE_ID 1 +#define MFR_CTRL_IE_LINK_ID 2 +#define MFR_CTRL_IE_MAGIC_NUM 3 +#define MFR_CTRL_IE_TIMESTAMP 5 +#define MFR_CTRL_IE_VENDOR_EXT 6 +#define MFR_CTRL_IE_CAUSE 7 + +struct tok mfr_ctrl_ie_values[] = { + { MFR_CTRL_IE_BUNDLE_ID, "Bundle ID"}, + { MFR_CTRL_IE_LINK_ID, "Link ID"}, + { MFR_CTRL_IE_MAGIC_NUM, "Magic Number"}, + { MFR_CTRL_IE_TIMESTAMP, "Timestamp"}, + { MFR_CTRL_IE_VENDOR_EXT, "Vendor Extension"}, + { MFR_CTRL_IE_CAUSE, "Cause"}, + { 0, NULL } +}; + +#define MFR_ID_STRING_MAXLEN 50 + +struct ie_tlv_header_t { + u_int8_t ie_type; + u_int8_t ie_len; +}; + +u_int +mfr_print(register const u_char *p, u_int length) +{ + u_int tlen,idx,hdr_len = 0; + u_int16_t sequence_num; + u_int8_t ie_type,ie_len; + const u_int8_t *tptr; + + +/* + * FRF.16 Link Integrity Control Frame + * + * 7 6 5 4 3 2 1 0 + * +----+----+----+----+----+----+----+----+ + * | B | E | C=1| 0 0 0 0 | EA | + * +----+----+----+----+----+----+----+----+ + * | 0 0 0 0 0 0 0 0 | + * +----+----+----+----+----+----+----+----+ + * | message type | + * +----+----+----+----+----+----+----+----+ + */ + + TCHECK2(*p, 4); /* minimum frame header length */ + + if ((p[0] & MFR_BEC_MASK) == MFR_CTRL_FRAME && p[1] == 0) { + printf("FRF.16 Control, Flags [%s], %s, length %u", + bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)), + tok2str(mfr_ctrl_msg_values,"Unknown Message (0x%02x)",p[2]), + length); + tptr = p + 3; + tlen = length -3; + hdr_len = 3; + + if (!vflag) + return hdr_len; + + while (tlen>sizeof(struct ie_tlv_header_t)) { + TCHECK2(*tptr, sizeof(struct ie_tlv_header_t)); + ie_type=tptr[0]; + ie_len=tptr[1]; + + printf("\n\tIE %s (%u), length %u: ", + tok2str(mfr_ctrl_ie_values,"Unknown",ie_type), + ie_type, + ie_len); + + /* infinite loop check */ + if (ie_type == 0 || ie_len <= sizeof(struct ie_tlv_header_t)) + return hdr_len; + + TCHECK2(*tptr,ie_len); + tptr+=sizeof(struct ie_tlv_header_t); + /* tlv len includes header */ + ie_len-=sizeof(struct ie_tlv_header_t); + tlen-=sizeof(struct ie_tlv_header_t); + + switch (ie_type) { + + case MFR_CTRL_IE_MAGIC_NUM: + printf("0x%08x",EXTRACT_32BITS(tptr)); + break; + + case MFR_CTRL_IE_BUNDLE_ID: /* same message format */ + case MFR_CTRL_IE_LINK_ID: + for (idx = 0; idx < ie_len && idx < MFR_ID_STRING_MAXLEN; idx++) { + if (*(tptr+idx) != 0) /* don't print null termination */ + safeputchar(*(tptr+idx)); + else + break; + } + break; + + case MFR_CTRL_IE_TIMESTAMP: + if (ie_len == sizeof(struct timeval)) { + ts_print((const struct timeval *)tptr); + break; + } + /* fall through and hexdump if no unix timestamp */ + + /* + * FIXME those are the defined IEs that lack a decoder + * you are welcome to contribute code ;-) + */ + + case MFR_CTRL_IE_VENDOR_EXT: + case MFR_CTRL_IE_CAUSE: + + default: + if (vflag <= 1) + print_unknown_data(tptr,"\n\t ",ie_len); + break; + } + + /* do we want to see a hexdump of the IE ? */ + if (vflag > 1 ) + print_unknown_data(tptr,"\n\t ",ie_len); + + tlen-=ie_len; + tptr+=ie_len; + } + return hdr_len; + } +/* + * FRF.16 Fragmentation Frame + * + * 7 6 5 4 3 2 1 0 + * +----+----+----+----+----+----+----+----+ + * | B | E | C=0|seq. (high 4 bits) | EA | + * +----+----+----+----+----+----+----+----+ + * | sequence (low 8 bits) | + * +----+----+----+----+----+----+----+----+ + * | DLCI (6 bits) | CR | EA | + * +----+----+----+----+----+----+----+----+ + * | DLCI (4 bits) |FECN|BECN| DE | EA | + * +----+----+----+----+----+----+----+----+ + */ + + sequence_num = (p[0]&0x1e)<<7 | p[1]; + /* whole packet or first fragment ? */ + if ((p[0] & MFR_BEC_MASK) == MFR_FRAG_FRAME || + (p[0] & MFR_BEC_MASK) == MFR_B_BIT) { + printf("FRF.16 Frag, seq %u, Flags [%s], ", + sequence_num, + bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK))); + hdr_len = 2; + fr_print(p+hdr_len,length-hdr_len); + return hdr_len; + } + + /* must be a middle or the last fragment */ + printf("FRF.16 Frag, seq %u, Flags [%s]", + sequence_num, + bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK))); + print_unknown_data(p,"\n\t",length); + + return hdr_len; + + trunc: + printf("[|mfr]"); + return length; +} + +/* an NLPID of 0xb1 indicates a 2-byte + * FRF.15 header + * + * 7 6 5 4 3 2 1 0 + * +----+----+----+----+----+----+----+----+ + * ~ Q.922 header ~ + * +----+----+----+----+----+----+----+----+ + * | NLPID (8 bits) | NLPID=0xb1 + * +----+----+----+----+----+----+----+----+ + * | B | E | C |seq. (high 4 bits) | R | + * +----+----+----+----+----+----+----+----+ + * | sequence (low 8 bits) | + * +----+----+----+----+----+----+----+----+ + */ + +#define FR_FRF15_FRAGTYPE 0x01 + +static void +frf15_print (const u_char *p, u_int length) { + + u_int16_t sequence_num, flags; + + flags = p[0]&MFR_BEC_MASK; + sequence_num = (p[0]&0x1e)<<7 | p[1]; + + printf("FRF.15, seq 0x%03x, Flags [%s],%s Fragmentation, length %u", + sequence_num, + bittok2str(frf_flag_values,"none",flags), + p[0]&FR_FRF15_FRAGTYPE ? "Interface" : "End-to-End", + length); + +/* TODO: + * depending on all permutations of the B, E and C bit + * dig as deep as we can - e.g. on the first (B) fragment + * there is enough payload to print the IP header + * on non (B) fragments it depends if the fragmentation + * model is end-to-end or interface based wether we want to print + * another Q.922 header + */ + +} + +/* + * Q.933 decoding portion for framerelay specific. + */ + +/* Q.933 packet format + Format of Other Protocols + using Q.933 NLPID + +-------------------------------+ + | Q.922 Address | + +---------------+---------------+ + |Control 0x03 | NLPID 0x08 | + +---------------+---------------+ + | L2 Protocol ID | + | octet 1 | octet 2 | + +-------------------------------+ + | L3 Protocol ID | + | octet 2 | octet 2 | + +-------------------------------+ + | Protocol Data | + +-------------------------------+ + | FCS | + +-------------------------------+ + */ + +/* L2 (Octet 1)- Call Reference Usually is 0x0 */ + +/* + * L2 (Octet 2)- Message Types definition 1 byte long. + */ +/* Call Establish */ +#define MSG_TYPE_ESC_TO_NATIONAL 0x00 +#define MSG_TYPE_ALERT 0x01 +#define MSG_TYPE_CALL_PROCEEDING 0x02 +#define MSG_TYPE_CONNECT 0x07 +#define MSG_TYPE_CONNECT_ACK 0x0F +#define MSG_TYPE_PROGRESS 0x03 +#define MSG_TYPE_SETUP 0x05 +/* Call Clear */ +#define MSG_TYPE_DISCONNECT 0x45 +#define MSG_TYPE_RELEASE 0x4D +#define MSG_TYPE_RELEASE_COMPLETE 0x5A +#define MSG_TYPE_RESTART 0x46 +#define MSG_TYPE_RESTART_ACK 0x4E +/* Status */ +#define MSG_TYPE_STATUS 0x7D +#define MSG_TYPE_STATUS_ENQ 0x75 + +struct tok fr_q933_msg_values[] = { + { MSG_TYPE_ESC_TO_NATIONAL, "ESC to National" }, + { MSG_TYPE_ALERT, "Alert" }, + { MSG_TYPE_CALL_PROCEEDING, "Call proceeding" }, + { MSG_TYPE_CONNECT, "Connect" }, + { MSG_TYPE_CONNECT_ACK, "Connect ACK" }, + { MSG_TYPE_PROGRESS, "Progress" }, + { MSG_TYPE_SETUP, "Setup" }, + { MSG_TYPE_DISCONNECT, "Disconnect" }, + { MSG_TYPE_RELEASE, "Release" }, + { MSG_TYPE_RELEASE_COMPLETE, "Release Complete" }, + { MSG_TYPE_RESTART, "Restart" }, + { MSG_TYPE_RESTART_ACK, "Restart ACK" }, + { MSG_TYPE_STATUS, "Status Reply" }, + { MSG_TYPE_STATUS_ENQ, "Status Enquiry" }, + { 0, NULL } +}; + +#define MSG_ANSI_LOCKING_SHIFT 0x95 + +#define FR_LMI_ANSI_REPORT_TYPE_IE 0x01 +#define FR_LMI_ANSI_LINK_VERIFY_IE_91 0x19 /* details? */ +#define FR_LMI_ANSI_LINK_VERIFY_IE 0x03 +#define FR_LMI_ANSI_PVC_STATUS_IE 0x07 + +#define FR_LMI_CCITT_REPORT_TYPE_IE 0x51 +#define FR_LMI_CCITT_LINK_VERIFY_IE 0x53 +#define FR_LMI_CCITT_PVC_STATUS_IE 0x57 + +struct tok fr_q933_ie_values_codeset5[] = { + { FR_LMI_ANSI_REPORT_TYPE_IE, "ANSI Report Type" }, + { FR_LMI_ANSI_LINK_VERIFY_IE_91, "ANSI Link Verify" }, + { FR_LMI_ANSI_LINK_VERIFY_IE, "ANSI Link Verify" }, + { FR_LMI_ANSI_PVC_STATUS_IE, "ANSI PVC Status" }, + { FR_LMI_CCITT_REPORT_TYPE_IE, "CCITT Report Type" }, + { FR_LMI_CCITT_LINK_VERIFY_IE, "CCITT Link Verify" }, + { FR_LMI_CCITT_PVC_STATUS_IE, "CCITT PVC Status" }, + { 0, NULL } +}; + +#define FR_LMI_REPORT_TYPE_IE_FULL_STATUS 0 +#define FR_LMI_REPORT_TYPE_IE_LINK_VERIFY 1 +#define FR_LMI_REPORT_TYPE_IE_ASYNC_PVC 2 + +struct tok fr_lmi_report_type_ie_values[] = { + { FR_LMI_REPORT_TYPE_IE_FULL_STATUS, "Full Status" }, + { FR_LMI_REPORT_TYPE_IE_LINK_VERIFY, "Link verify" }, + { FR_LMI_REPORT_TYPE_IE_ASYNC_PVC, "Async PVC Status" }, + { 0, NULL } +}; + +/* array of 16 codepages - currently we only support codepage 1,5 */ +static struct tok *fr_q933_ie_codesets[] = { + NULL, + fr_q933_ie_values_codeset5, + NULL, + NULL, + NULL, + fr_q933_ie_values_codeset5, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +static int fr_q933_print_ie_codeset5(const struct ie_tlv_header_t *ie_p, + const u_char *p); + +typedef int (*codeset_pr_func_t)(const struct ie_tlv_header_t *ie_p, + const u_char *p); + +/* array of 16 codepages - currently we only support codepage 1,5 */ +static codeset_pr_func_t fr_q933_print_ie_codeset[] = { + NULL, + fr_q933_print_ie_codeset5, + NULL, + NULL, + NULL, + fr_q933_print_ie_codeset5, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +void +q933_print(const u_char *p, u_int length) +{ + const u_char *ptemp = p; + struct ie_tlv_header_t *ie_p; + int olen; + int is_ansi = 0; + u_int codeset; + u_int ie_is_known = 0; + + if (length < 9) { /* shortest: Q.933a LINK VERIFY */ + printf("[|q.933]"); + return; + } + + codeset = p[2]&0x0f; /* extract the codeset */ + + if (p[2] == MSG_ANSI_LOCKING_SHIFT) { + is_ansi = 1; + } + + printf("%s", eflag ? "" : "Q.933, "); + + /* printing out header part */ + printf("%s, codeset %u", is_ansi ? "ANSI" : "CCITT", codeset); + + if (p[0]) { + printf(", Call Ref: 0x%02x", p[0]); + } + if (vflag) { + printf(", %s (0x%02x), length %u", + tok2str(fr_q933_msg_values, + "unknown message", p[1]), + p[1], + length); + } else { + printf(", %s", + tok2str(fr_q933_msg_values, + "unknown message 0x%02x", p[1])); + } + + olen = length; /* preserve the original length for non verbose mode */ + + if (length < (u_int)(2 - is_ansi)) { + printf("[|q.933]"); + return; + } + length -= 2 + is_ansi; + ptemp += 2 + is_ansi; + + /* Loop through the rest of IE */ + while (length > sizeof(struct ie_tlv_header_t)) { + ie_p = (struct ie_tlv_header_t *)ptemp; + if (length < sizeof(struct ie_tlv_header_t) || + length < sizeof(struct ie_tlv_header_t) + ie_p->ie_len) { + if (vflag) { /* not bark if there is just a trailer */ + printf("\n[|q.933]"); + } else { + printf(", length %u",olen); + } + return; + } + + /* lets do the full IE parsing only in verbose mode + * however some IEs (DLCI Status, Link Verify) + * are also interestting in non-verbose mode */ + if (vflag) { + printf("\n\t%s IE (0x%02x), length %u: ", + tok2str(fr_q933_ie_codesets[codeset], + "unknown", ie_p->ie_type), + ie_p->ie_type, + ie_p->ie_len); + } + + /* sanity check */ + if (ie_p->ie_type == 0 || ie_p->ie_len == 0) { + return; + } + + if (fr_q933_print_ie_codeset[codeset] != NULL) { + ie_is_known = fr_q933_print_ie_codeset[codeset](ie_p, ptemp); + } + + if (vflag >= 1 && !ie_is_known) { + print_unknown_data(ptemp+2,"\n\t",ie_p->ie_len); + } + + /* do we want to see a hexdump of the IE ? */ + if (vflag> 1 && ie_is_known) { + print_unknown_data(ptemp+2,"\n\t ",ie_p->ie_len); + } + + length = length - ie_p->ie_len - 2; + ptemp = ptemp + ie_p->ie_len + 2; + } + if (!vflag) { + printf(", length %u",olen); + } +} + +static int +fr_q933_print_ie_codeset5(const struct ie_tlv_header_t *ie_p, const u_char *p) +{ + u_int dlci; + + switch (ie_p->ie_type) { + + case FR_LMI_ANSI_REPORT_TYPE_IE: /* fall through */ + case FR_LMI_CCITT_REPORT_TYPE_IE: + if (vflag) { + printf("%s (%u)", + tok2str(fr_lmi_report_type_ie_values,"unknown",p[2]), + p[2]); + } + return 1; + + case FR_LMI_ANSI_LINK_VERIFY_IE: /* fall through */ + case FR_LMI_CCITT_LINK_VERIFY_IE: + case FR_LMI_ANSI_LINK_VERIFY_IE_91: + if (!vflag) { + printf(", "); + } + printf("TX Seq: %3d, RX Seq: %3d", p[2], p[3]); + return 1; + + case FR_LMI_ANSI_PVC_STATUS_IE: /* fall through */ + case FR_LMI_CCITT_PVC_STATUS_IE: + if (!vflag) { + printf(", "); + } + /* now parse the DLCI information element. */ + if ((ie_p->ie_len < 3) || + (p[2] & 0x80) || + ((ie_p->ie_len == 3) && !(p[3] & 0x80)) || + ((ie_p->ie_len == 4) && ((p[3] & 0x80) || !(p[4] & 0x80))) || + ((ie_p->ie_len == 5) && ((p[3] & 0x80) || (p[4] & 0x80) || + !(p[5] & 0x80))) || + (ie_p->ie_len > 5) || + !(p[ie_p->ie_len + 1] & 0x80)) { + printf("Invalid DLCI IE"); + } + + dlci = ((p[2] & 0x3F) << 4) | ((p[3] & 0x78) >> 3); + if (ie_p->ie_len == 4) { + dlci = (dlci << 6) | ((p[4] & 0x7E) >> 1); + } + else if (ie_p->ie_len == 5) { + dlci = (dlci << 13) | (p[4] & 0x7F) | ((p[5] & 0x7E) >> 1); + } + + printf("DLCI %u: status %s%s", dlci, + p[ie_p->ie_len + 1] & 0x8 ? "New, " : "", + p[ie_p->ie_len + 1] & 0x2 ? "Active" : "Inactive"); + return 1; + } + + return 0; +} diff --git a/print-frag6.c b/print-frag6.c new file mode 100644 index 0000000..e125bd3 --- /dev/null +++ b/print-frag6.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-frag6.c,v 1.20 2005-04-20 22:33:06 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef INET6 + +#include + +#include + +#include "ip6.h" + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +int +frag6_print(register const u_char *bp, register const u_char *bp2) +{ + register const struct ip6_frag *dp; + register const struct ip6_hdr *ip6; + + dp = (const struct ip6_frag *)bp; + ip6 = (const struct ip6_hdr *)bp2; + + TCHECK(dp->ip6f_offlg); + + if (vflag) { + printf("frag (0x%08x:%d|%ld)", + EXTRACT_32BITS(&dp->ip6f_ident), + EXTRACT_16BITS(&dp->ip6f_offlg) & IP6F_OFF_MASK, + sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen) - + (long)(bp - bp2) - sizeof(struct ip6_frag)); + } else { + printf("frag (%d|%ld)", + EXTRACT_16BITS(&dp->ip6f_offlg) & IP6F_OFF_MASK, + sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen) - + (long)(bp - bp2) - sizeof(struct ip6_frag)); + } + +#if 1 + /* it is meaningless to decode non-first fragment */ + if ((EXTRACT_16BITS(&dp->ip6f_offlg) & IP6F_OFF_MASK) != 0) + return -1; + else +#endif + { + fputs(" ", stdout); + return sizeof(struct ip6_frag); + } +trunc: + fputs("[|frag]", stdout); + return -1; +#undef TCHECK +} +#endif /* INET6 */ diff --git a/print-gre.c b/print-gre.c new file mode 100644 index 0000000..106e6fd --- /dev/null +++ b/print-gre.c @@ -0,0 +1,403 @@ +/* $OpenBSD: print-gre.c,v 1.6 2002/10/30 03:04:04 fgsch Exp $ */ + +/* + * Copyright (c) 2002 Jason L. Wright (jason@thought.net) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Jason L. Wright + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * tcpdump filter for GRE - Generic Routing Encapsulation + * RFC1701 (GRE), RFC1702 (GRE IPv4), and RFC2637 (Enhanced GRE) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-gre.c,v 1.28 2005-04-06 21:32:39 mcr Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "ip.h" +#include "ethertype.h" + +#define GRE_CP 0x8000 /* checksum present */ +#define GRE_RP 0x4000 /* routing present */ +#define GRE_KP 0x2000 /* key present */ +#define GRE_SP 0x1000 /* sequence# present */ +#define GRE_sP 0x0800 /* source routing */ +#define GRE_RECRS 0x0700 /* recursion count */ +#define GRE_AP 0x0080 /* acknowledgment# present */ + +struct tok gre_flag_values[] = { + { GRE_CP, "checksum present"}, + { GRE_RP, "routing present"}, + { GRE_KP, "key present"}, + { GRE_SP, "sequence# present"}, + { GRE_sP, "source routing present"}, + { GRE_RECRS, "recursion count"}, + { GRE_AP, "ack present"}, + { 0, NULL } +}; + +#define GRE_VERS_MASK 0x0007 /* protocol version */ + +/* source route entry types */ +#define GRESRE_IP 0x0800 /* IP */ +#define GRESRE_ASN 0xfffe /* ASN */ + +void gre_print_0(const u_char *, u_int); +void gre_print_1(const u_char *, u_int); +void gre_sre_print(u_int16_t, u_int8_t, u_int8_t, const u_char *, u_int); +void gre_sre_ip_print(u_int8_t, u_int8_t, const u_char *, u_int); +void gre_sre_asn_print(u_int8_t, u_int8_t, const u_char *, u_int); + +void +gre_print(const u_char *bp, u_int length) +{ + u_int len = length, vers; + + if (len < 2) { + printf("[|gre]"); + return; + } + vers = EXTRACT_16BITS(bp) & GRE_VERS_MASK; + printf("GREv%u",vers); + + switch(vers) { + case 0: + gre_print_0(bp, len); + break; + case 1: + gre_print_1(bp, len); + break; + default: + printf(" ERROR: unknown-version"); + break; + } + return; + +} + +void +gre_print_0(const u_char *bp, u_int length) +{ + u_int len = length; + u_int16_t flags, prot; + + flags = EXTRACT_16BITS(bp); + if (vflag) + printf(", Flags [%s]", + bittok2str(gre_flag_values,"none",flags)); + + len -= 2; + bp += 2; + + if (len < 2) + goto trunc; + prot = EXTRACT_16BITS(bp); + len -= 2; + bp += 2; + + if ((flags & GRE_CP) | (flags & GRE_RP)) { + if (len < 2) + goto trunc; + if (vflag) + printf(", sum 0x%x", EXTRACT_16BITS(bp)); + bp += 2; + len -= 2; + + if (len < 2) + goto trunc; + printf(", off 0x%x", EXTRACT_16BITS(bp)); + bp += 2; + len -= 2; + } + + if (flags & GRE_KP) { + if (len < 4) + goto trunc; + printf(", key=0x%x", EXTRACT_32BITS(bp)); + bp += 4; + len -= 4; + } + + if (flags & GRE_SP) { + if (len < 4) + goto trunc; + printf(", seq %u", EXTRACT_32BITS(bp)); + bp += 4; + len -= 4; + } + + if (flags & GRE_RP) { + for (;;) { + u_int16_t af; + u_int8_t sreoff; + u_int8_t srelen; + + if (len < 4) + goto trunc; + af = EXTRACT_16BITS(bp); + sreoff = *(bp + 2); + srelen = *(bp + 3); + bp += 4; + len -= 4; + + if (af == 0 && srelen == 0) + break; + + gre_sre_print(af, sreoff, srelen, bp, len); + + if (len < srelen) + goto trunc; + bp += srelen; + len -= srelen; + } + } + + if (eflag) + printf(", proto %s (0x%04x)", + tok2str(ethertype_values,"unknown",prot), + prot); + + printf(", length %u",length); + + if (vflag < 1) + printf(": "); /* put in a colon as protocol demarc */ + else + printf("\n\t"); /* if verbose go multiline */ + + switch (prot) { + case ETHERTYPE_IP: + ip_print(gndo, bp, len); + break; +#ifdef INET6 + case ETHERTYPE_IPV6: + ip6_print(bp, len); + break; +#endif + case ETHERTYPE_MPLS: + mpls_print(bp, len); + break; + case ETHERTYPE_IPX: + ipx_print(bp, len); + break; + case ETHERTYPE_ATALK: + atalk_print(bp, len); + break; + case ETHERTYPE_GRE_ISO: + isoclns_print(bp, len, len); + break; + case ETHERTYPE_TEB: + ether_print(bp, len, len, NULL, NULL); + break; + default: + printf("gre-proto-0x%x", prot); + } + return; + +trunc: + printf("[|gre]"); +} + +void +gre_print_1(const u_char *bp, u_int length) +{ + u_int len = length; + u_int16_t flags, prot; + + flags = EXTRACT_16BITS(bp); + len -= 2; + bp += 2; + + if (vflag) + printf(", Flags [%s]", + bittok2str(gre_flag_values,"none",flags)); + + if (len < 2) + goto trunc; + prot = EXTRACT_16BITS(bp); + len -= 2; + bp += 2; + + + if (flags & GRE_KP) { + u_int32_t k; + + if (len < 4) + goto trunc; + k = EXTRACT_32BITS(bp); + printf(", call %d", k & 0xffff); + len -= 4; + bp += 4; + } + + if (flags & GRE_SP) { + if (len < 4) + goto trunc; + printf(", seq %u", EXTRACT_32BITS(bp)); + bp += 4; + len -= 4; + } + + if (flags & GRE_AP) { + if (len < 4) + goto trunc; + printf(", ack %u", EXTRACT_32BITS(bp)); + bp += 4; + len -= 4; + } + + if ((flags & GRE_SP) == 0) + printf(", no-payload"); + + if (eflag) + printf(", proto %s (0x%04x)", + tok2str(ethertype_values,"unknown",prot), + prot); + + printf(", length %u",length); + + if ((flags & GRE_SP) == 0) + return; + + if (vflag < 1) + printf(": "); /* put in a colon as protocol demarc */ + else + printf("\n\t"); /* if verbose go multiline */ + + switch (prot) { + case ETHERTYPE_PPP: + ppp_print(bp, len); + break; + default: + printf("gre-proto-0x%x", prot); + break; + } + return; + +trunc: + printf("[|gre]"); +} + +void +gre_sre_print(u_int16_t af, u_int8_t sreoff, u_int8_t srelen, + const u_char *bp, u_int len) +{ + switch (af) { + case GRESRE_IP: + printf(", (rtaf=ip"); + gre_sre_ip_print(sreoff, srelen, bp, len); + printf(") "); + break; + case GRESRE_ASN: + printf(", (rtaf=asn"); + gre_sre_asn_print(sreoff, srelen, bp, len); + printf(") "); + break; + default: + printf(", (rtaf=0x%x) ", af); + } +} +void +gre_sre_ip_print(u_int8_t sreoff, u_int8_t srelen, const u_char *bp, u_int len) +{ + struct in_addr a; + const u_char *up = bp; + + if (sreoff & 3) { + printf(", badoffset=%u", sreoff); + return; + } + if (srelen & 3) { + printf(", badlength=%u", srelen); + return; + } + if (sreoff >= srelen) { + printf(", badoff/len=%u/%u", sreoff, srelen); + return; + } + + for (;;) { + if (len < 4 || srelen == 0) + return; + + memcpy(&a, bp, sizeof(a)); + printf(" %s%s", + ((bp - up) == sreoff) ? "*" : "", + inet_ntoa(a)); + + bp += 4; + len -= 4; + srelen -= 4; + } +} + +void +gre_sre_asn_print(u_int8_t sreoff, u_int8_t srelen, const u_char *bp, u_int len) +{ + const u_char *up = bp; + + if (sreoff & 1) { + printf(", badoffset=%u", sreoff); + return; + } + if (srelen & 1) { + printf(", badlength=%u", srelen); + return; + } + if (sreoff >= srelen) { + printf(", badoff/len=%u/%u", sreoff, srelen); + return; + } + + for (;;) { + if (len < 2 || srelen == 0) + return; + + printf(" %s%x", + ((bp - up) == sreoff) ? "*" : "", + EXTRACT_16BITS(bp)); + + bp += 2; + len -= 2; + srelen -= 2; + } +} diff --git a/print-hsrp.c b/print-hsrp.c new file mode 100644 index 0000000..06304fd --- /dev/null +++ b/print-hsrp.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2001 Julian Cowley + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Cisco Hot Standby Router Protocol (HSRP). */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-hsrp.c,v 1.10 2005-05-06 07:56:52 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "interface.h" +#include "addrtoname.h" + +/* HSRP op code types. */ +static const char *op_code_str[] = { + "hello", + "coup", + "resign" +}; + +/* HSRP states and associated names. */ +static struct tok states[] = { + { 0, "initial" }, + { 1, "learn" }, + { 2, "listen" }, + { 4, "speak" }, + { 8, "standby" }, + { 16, "active" }, + { 0, NULL } +}; + +/* + * RFC 2281: + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Version | Op Code | State | Hellotime | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Holdtime | Priority | Group | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Authentication Data | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Authentication Data | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Virtual IP Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define HSRP_AUTH_SIZE 8 + +/* HSRP protocol header. */ +struct hsrp { + u_int8_t hsrp_version; + u_int8_t hsrp_op_code; + u_int8_t hsrp_state; + u_int8_t hsrp_hellotime; + u_int8_t hsrp_holdtime; + u_int8_t hsrp_priority; + u_int8_t hsrp_group; + u_int8_t hsrp_reserved; + u_int8_t hsrp_authdata[HSRP_AUTH_SIZE]; + struct in_addr hsrp_virtaddr; +}; + +void +hsrp_print(register const u_int8_t *bp, register u_int len) +{ + struct hsrp *hp = (struct hsrp *) bp; + + TCHECK(hp->hsrp_version); + printf("HSRPv%d", hp->hsrp_version); + if (hp->hsrp_version != 0) + return; + TCHECK(hp->hsrp_op_code); + printf("-"); + printf("%s ", tok2strary(op_code_str, "unknown (%d)", hp->hsrp_op_code)); + printf("%d: ", len); + TCHECK(hp->hsrp_state); + printf("state=%s ", tok2str(states, "Unknown (%d)", hp->hsrp_state)); + TCHECK(hp->hsrp_group); + printf("group=%d ", hp->hsrp_group); + TCHECK(hp->hsrp_reserved); + if (hp->hsrp_reserved != 0) { + printf("[reserved=%d!] ", hp->hsrp_reserved); + } + TCHECK(hp->hsrp_virtaddr); + printf("addr=%s", ipaddr_string(&hp->hsrp_virtaddr)); + if (vflag) { + printf(" hellotime="); + relts_print(hp->hsrp_hellotime); + printf(" holdtime="); + relts_print(hp->hsrp_holdtime); + printf(" priority=%d", hp->hsrp_priority); + printf(" auth=\""); + if (fn_printn(hp->hsrp_authdata, sizeof(hp->hsrp_authdata), + snapend)) { + printf("\""); + goto trunc; + } + printf("\""); + } + return; +trunc: + printf("[|hsrp]"); +} diff --git a/print-icmp.c b/print-icmp.c new file mode 100644 index 0000000..36bff6a --- /dev/null +++ b/print-icmp.c @@ -0,0 +1,688 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.87 2007-09-13 17:42:31 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +#include "ip.h" +#include "udp.h" +#include "ipproto.h" +#include "mpls.h" + +/* + * Interface Control Message Protocol Definitions. + * Per RFC 792, September 1981. + */ + +/* + * Structure of an icmp header. + */ +struct icmp { + u_int8_t icmp_type; /* type of message, see below */ + u_int8_t icmp_code; /* type sub code */ + u_int16_t icmp_cksum; /* ones complement cksum of struct */ + union { + u_int8_t ih_pptr; /* ICMP_PARAMPROB */ + struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ + struct ih_idseq { + u_int16_t icd_id; + u_int16_t icd_seq; + } ih_idseq; + u_int32_t ih_void; + } icmp_hun; +#define icmp_pptr icmp_hun.ih_pptr +#define icmp_gwaddr icmp_hun.ih_gwaddr +#define icmp_id icmp_hun.ih_idseq.icd_id +#define icmp_seq icmp_hun.ih_idseq.icd_seq +#define icmp_void icmp_hun.ih_void + union { + struct id_ts { + u_int32_t its_otime; + u_int32_t its_rtime; + u_int32_t its_ttime; + } id_ts; + struct id_ip { + struct ip idi_ip; + /* options and then 64 bits of data */ + } id_ip; + u_int32_t id_mask; + u_int8_t id_data[1]; + } icmp_dun; +#define icmp_otime icmp_dun.id_ts.its_otime +#define icmp_rtime icmp_dun.id_ts.its_rtime +#define icmp_ttime icmp_dun.id_ts.its_ttime +#define icmp_ip icmp_dun.id_ip.idi_ip +#define icmp_mask icmp_dun.id_mask +#define icmp_data icmp_dun.id_data +}; + +#define ICMP_MPLS_EXT_EXTRACT_VERSION(x) (((x)&0xf0)>>4) +#define ICMP_MPLS_EXT_VERSION 2 + +/* + * Lower bounds on packet lengths for various types. + * For the error advice packets must first insure that the + * packet is large enought to contain the returned ip header. + * Only then can we do the check to see if 64 bits of packet + * data have been returned, since we need to check the returned + * ip header length. + */ +#define ICMP_MINLEN 8 /* abs minimum */ +#define ICMP_EXTD_MINLEN (156 - sizeof (struct ip)) /* draft-bonica-internet-icmp-08 */ +#define ICMP_TSLEN (8 + 3 * sizeof (u_int32_t)) /* timestamp */ +#define ICMP_MASKLEN 12 /* address mask */ +#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */ +#define ICMP_ADVLEN(p) (8 + (IP_HL(&(p)->icmp_ip) << 2) + 8) + /* N.B.: must separately check that ip_hl >= 5 */ + +/* + * Definition of type and code field values. + */ +#define ICMP_ECHOREPLY 0 /* echo reply */ +#define ICMP_UNREACH 3 /* dest unreachable, codes: */ +#define ICMP_UNREACH_NET 0 /* bad net */ +#define ICMP_UNREACH_HOST 1 /* bad host */ +#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */ +#define ICMP_UNREACH_PORT 3 /* bad port */ +#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ +#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ +#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ +#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ +#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ +#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */ +#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ +#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ +#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ +#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */ +#define ICMP_REDIRECT 5 /* shorter route, codes: */ +#define ICMP_REDIRECT_NET 0 /* for network */ +#define ICMP_REDIRECT_HOST 1 /* for host */ +#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ +#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ +#define ICMP_ECHO 8 /* echo service */ +#define ICMP_ROUTERADVERT 9 /* router advertisement */ +#define ICMP_ROUTERSOLICIT 10 /* router solicitation */ +#define ICMP_TIMXCEED 11 /* time exceeded, code: */ +#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */ +#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */ +#define ICMP_PARAMPROB 12 /* ip header bad */ +#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ +#define ICMP_TSTAMP 13 /* timestamp request */ +#define ICMP_TSTAMPREPLY 14 /* timestamp reply */ +#define ICMP_IREQ 15 /* information request */ +#define ICMP_IREQREPLY 16 /* information reply */ +#define ICMP_MASKREQ 17 /* address mask request */ +#define ICMP_MASKREPLY 18 /* address mask reply */ + +#define ICMP_MAXTYPE 18 + +#define ICMP_INFOTYPE(type) \ + ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ + (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \ + (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ + (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ + (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) +#define ICMP_MPLS_EXT_TYPE(type) \ + ((type) == ICMP_UNREACH || \ + (type) == ICMP_TIMXCEED || \ + (type) == ICMP_PARAMPROB) +/* rfc1700 */ +#ifndef ICMP_UNREACH_NET_UNKNOWN +#define ICMP_UNREACH_NET_UNKNOWN 6 /* destination net unknown */ +#endif +#ifndef ICMP_UNREACH_HOST_UNKNOWN +#define ICMP_UNREACH_HOST_UNKNOWN 7 /* destination host unknown */ +#endif +#ifndef ICMP_UNREACH_ISOLATED +#define ICMP_UNREACH_ISOLATED 8 /* source host isolated */ +#endif +#ifndef ICMP_UNREACH_NET_PROHIB +#define ICMP_UNREACH_NET_PROHIB 9 /* admin prohibited net */ +#endif +#ifndef ICMP_UNREACH_HOST_PROHIB +#define ICMP_UNREACH_HOST_PROHIB 10 /* admin prohibited host */ +#endif +#ifndef ICMP_UNREACH_TOSNET +#define ICMP_UNREACH_TOSNET 11 /* tos prohibited net */ +#endif +#ifndef ICMP_UNREACH_TOSHOST +#define ICMP_UNREACH_TOSHOST 12 /* tos prohibited host */ +#endif + +/* rfc1716 */ +#ifndef ICMP_UNREACH_FILTER_PROHIB +#define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohibited filter */ +#endif +#ifndef ICMP_UNREACH_HOST_PRECEDENCE +#define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host precedence violation */ +#endif +#ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF +#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* precedence cutoff */ +#endif + +/* Most of the icmp types */ +static struct tok icmp2str[] = { + { ICMP_ECHOREPLY, "echo reply" }, + { ICMP_SOURCEQUENCH, "source quench" }, + { ICMP_ECHO, "echo request" }, + { ICMP_ROUTERSOLICIT, "router solicitation" }, + { ICMP_TSTAMP, "time stamp request" }, + { ICMP_TSTAMPREPLY, "time stamp reply" }, + { ICMP_IREQ, "information request" }, + { ICMP_IREQREPLY, "information reply" }, + { ICMP_MASKREQ, "address mask request" }, + { 0, NULL } +}; + +/* Formats for most of the ICMP_UNREACH codes */ +static struct tok unreach2str[] = { + { ICMP_UNREACH_NET, "net %s unreachable" }, + { ICMP_UNREACH_HOST, "host %s unreachable" }, + { ICMP_UNREACH_SRCFAIL, + "%s unreachable - source route failed" }, + { ICMP_UNREACH_NET_UNKNOWN, "net %s unreachable - unknown" }, + { ICMP_UNREACH_HOST_UNKNOWN, "host %s unreachable - unknown" }, + { ICMP_UNREACH_ISOLATED, + "%s unreachable - source host isolated" }, + { ICMP_UNREACH_NET_PROHIB, + "net %s unreachable - admin prohibited" }, + { ICMP_UNREACH_HOST_PROHIB, + "host %s unreachable - admin prohibited" }, + { ICMP_UNREACH_TOSNET, + "net %s unreachable - tos prohibited" }, + { ICMP_UNREACH_TOSHOST, + "host %s unreachable - tos prohibited" }, + { ICMP_UNREACH_FILTER_PROHIB, + "host %s unreachable - admin prohibited filter" }, + { ICMP_UNREACH_HOST_PRECEDENCE, + "host %s unreachable - host precedence violation" }, + { ICMP_UNREACH_PRECEDENCE_CUTOFF, + "host %s unreachable - precedence cutoff" }, + { 0, NULL } +}; + +/* Formats for the ICMP_REDIRECT codes */ +static struct tok type2str[] = { + { ICMP_REDIRECT_NET, "redirect %s to net %s" }, + { ICMP_REDIRECT_HOST, "redirect %s to host %s" }, + { ICMP_REDIRECT_TOSNET, "redirect-tos %s to net %s" }, + { ICMP_REDIRECT_TOSHOST, "redirect-tos %s to host %s" }, + { 0, NULL } +}; + +/* rfc1191 */ +struct mtu_discovery { + u_int16_t unused; + u_int16_t nexthopmtu; +}; + +/* rfc1256 */ +struct ih_rdiscovery { + u_int8_t ird_addrnum; + u_int8_t ird_addrsiz; + u_int16_t ird_lifetime; +}; + +struct id_rdiscovery { + u_int32_t ird_addr; + u_int32_t ird_pref; +}; + +/* + * draft-bonica-internet-icmp-08 + * + * The Destination Unreachable, Time Exceeded + * and Parameter Problem messages are slighly changed as per + * the above draft. A new Length field gets added to give + * the caller an idea about the length of the piggypacked + * IP packet before the MPLS extension header starts. + * + * The Length field represents length of the padded "original datagram" + * field measured in 32-bit words. + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Code | Checksum | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | unused | Length | unused | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Internet Header + leading octets of original datagram | + * | | + * | // | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct icmp_ext_t { + u_int8_t icmp_type; + u_int8_t icmp_code; + u_int8_t icmp_checksum[2]; + u_int8_t icmp_reserved; + u_int8_t icmp_length; + u_int8_t icmp_reserved2[2]; + u_int8_t icmp_ext_legacy_header[128]; /* extension header starts 128 bytes after ICMP header */ + u_int8_t icmp_ext_version_res[2]; + u_int8_t icmp_ext_checksum[2]; + u_int8_t icmp_ext_data[1]; +}; + +struct icmp_mpls_ext_object_header_t { + u_int8_t length[2]; + u_int8_t class_num; + u_int8_t ctype; +}; + +static const struct tok icmp_mpls_ext_obj_values[] = { + { 1, "MPLS Stack Entry" }, + { 2, "Extended Payload" }, + { 0, NULL} +}; + +/* prototypes */ +const char *icmp_tstamp_print(u_int); + +/* print the milliseconds since midnight UTC */ +const char * +icmp_tstamp_print(u_int tstamp) { + u_int msec,sec,min,hrs; + + static char buf[64]; + + msec = tstamp % 1000; + sec = tstamp / 1000; + min = sec / 60; sec -= min * 60; + hrs = min / 60; min -= hrs * 60; + snprintf(buf, sizeof(buf), "%02u:%02u:%02u.%03u",hrs,min,sec,msec); + return buf; +} + +void +icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) +{ + char *cp; + const struct icmp *dp; + const struct icmp_ext_t *ext_dp; + const struct ip *ip; + const char *str, *fmt; + const struct ip *oip; + const struct udphdr *ouh; + const u_int8_t *obj_tptr; + u_int32_t raw_label; + const u_char *snapend_save; + const struct icmp_mpls_ext_object_header_t *icmp_mpls_ext_object_header; + u_int hlen, dport, mtu, obj_tlen, obj_class_num, obj_ctype; + char buf[MAXHOSTNAMELEN + 100]; + + dp = (struct icmp *)bp; + ext_dp = (struct icmp_ext_t *)bp; + ip = (struct ip *)bp2; + str = buf; + + TCHECK(dp->icmp_code); + switch (dp->icmp_type) { + + case ICMP_ECHO: + case ICMP_ECHOREPLY: + TCHECK(dp->icmp_seq); + (void)snprintf(buf, sizeof(buf), "echo %s, id %u, seq %u", + dp->icmp_type == ICMP_ECHO ? + "request" : "reply", + EXTRACT_16BITS(&dp->icmp_id), + EXTRACT_16BITS(&dp->icmp_seq)); + break; + + case ICMP_UNREACH: + TCHECK(dp->icmp_ip.ip_dst); + switch (dp->icmp_code) { + + case ICMP_UNREACH_PROTOCOL: + TCHECK(dp->icmp_ip.ip_p); + (void)snprintf(buf, sizeof(buf), + "%s protocol %d unreachable", + ipaddr_string(&dp->icmp_ip.ip_dst), + dp->icmp_ip.ip_p); + break; + + case ICMP_UNREACH_PORT: + TCHECK(dp->icmp_ip.ip_p); + oip = &dp->icmp_ip; + hlen = IP_HL(oip) * 4; + ouh = (struct udphdr *)(((u_char *)oip) + hlen); + TCHECK(ouh->uh_dport); + dport = EXTRACT_16BITS(&ouh->uh_dport); + switch (oip->ip_p) { + + case IPPROTO_TCP: + (void)snprintf(buf, sizeof(buf), + "%s tcp port %s unreachable", + ipaddr_string(&oip->ip_dst), + tcpport_string(dport)); + break; + + case IPPROTO_UDP: + (void)snprintf(buf, sizeof(buf), + "%s udp port %s unreachable", + ipaddr_string(&oip->ip_dst), + udpport_string(dport)); + break; + + default: + (void)snprintf(buf, sizeof(buf), + "%s protocol %d port %d unreachable", + ipaddr_string(&oip->ip_dst), + oip->ip_p, dport); + break; + } + break; + + case ICMP_UNREACH_NEEDFRAG: + { + register const struct mtu_discovery *mp; + mp = (struct mtu_discovery *)(u_char *)&dp->icmp_void; + mtu = EXTRACT_16BITS(&mp->nexthopmtu); + if (mtu) { + (void)snprintf(buf, sizeof(buf), + "%s unreachable - need to frag (mtu %d)", + ipaddr_string(&dp->icmp_ip.ip_dst), mtu); + } else { + (void)snprintf(buf, sizeof(buf), + "%s unreachable - need to frag", + ipaddr_string(&dp->icmp_ip.ip_dst)); + } + } + break; + + default: + fmt = tok2str(unreach2str, "#%d %%s unreachable", + dp->icmp_code); + (void)snprintf(buf, sizeof(buf), fmt, + ipaddr_string(&dp->icmp_ip.ip_dst)); + break; + } + break; + + case ICMP_REDIRECT: + TCHECK(dp->icmp_ip.ip_dst); + fmt = tok2str(type2str, "redirect-#%d %%s to net %%s", + dp->icmp_code); + (void)snprintf(buf, sizeof(buf), fmt, + ipaddr_string(&dp->icmp_ip.ip_dst), + ipaddr_string(&dp->icmp_gwaddr)); + break; + + case ICMP_ROUTERADVERT: + { + register const struct ih_rdiscovery *ihp; + register const struct id_rdiscovery *idp; + u_int lifetime, num, size; + + (void)snprintf(buf, sizeof(buf), "router advertisement"); + cp = buf + strlen(buf); + + ihp = (struct ih_rdiscovery *)&dp->icmp_void; + TCHECK(*ihp); + (void)strncpy(cp, " lifetime ", sizeof(buf) - (cp - buf)); + cp = buf + strlen(buf); + lifetime = EXTRACT_16BITS(&ihp->ird_lifetime); + if (lifetime < 60) { + (void)snprintf(cp, sizeof(buf) - (cp - buf), "%u", + lifetime); + } else if (lifetime < 60 * 60) { + (void)snprintf(cp, sizeof(buf) - (cp - buf), "%u:%02u", + lifetime / 60, lifetime % 60); + } else { + (void)snprintf(cp, sizeof(buf) - (cp - buf), + "%u:%02u:%02u", + lifetime / 3600, + (lifetime % 3600) / 60, + lifetime % 60); + } + cp = buf + strlen(buf); + + num = ihp->ird_addrnum; + (void)snprintf(cp, sizeof(buf) - (cp - buf), " %d:", num); + cp = buf + strlen(buf); + + size = ihp->ird_addrsiz; + if (size != 2) { + (void)snprintf(cp, sizeof(buf) - (cp - buf), + " [size %d]", size); + break; + } + idp = (struct id_rdiscovery *)&dp->icmp_data; + while (num-- > 0) { + TCHECK(*idp); + (void)snprintf(cp, sizeof(buf) - (cp - buf), " {%s %u}", + ipaddr_string(&idp->ird_addr), + EXTRACT_32BITS(&idp->ird_pref)); + cp = buf + strlen(buf); + ++idp; + } + } + break; + + case ICMP_TIMXCEED: + TCHECK(dp->icmp_ip.ip_dst); + switch (dp->icmp_code) { + + case ICMP_TIMXCEED_INTRANS: + str = "time exceeded in-transit"; + break; + + case ICMP_TIMXCEED_REASS: + str = "ip reassembly time exceeded"; + break; + + default: + (void)snprintf(buf, sizeof(buf), "time exceeded-#%d", + dp->icmp_code); + break; + } + break; + + case ICMP_PARAMPROB: + if (dp->icmp_code) + (void)snprintf(buf, sizeof(buf), + "parameter problem - code %d", dp->icmp_code); + else { + TCHECK(dp->icmp_pptr); + (void)snprintf(buf, sizeof(buf), + "parameter problem - octet %d", dp->icmp_pptr); + } + break; + + case ICMP_MASKREPLY: + TCHECK(dp->icmp_mask); + (void)snprintf(buf, sizeof(buf), "address mask is 0x%08x", + EXTRACT_32BITS(&dp->icmp_mask)); + break; + + case ICMP_TSTAMP: + TCHECK(dp->icmp_seq); + (void)snprintf(buf, sizeof(buf), + "time stamp query id %u seq %u", + EXTRACT_16BITS(&dp->icmp_id), + EXTRACT_16BITS(&dp->icmp_seq)); + break; + + case ICMP_TSTAMPREPLY: + TCHECK(dp->icmp_ttime); + (void)snprintf(buf, sizeof(buf), + "time stamp reply id %u seq %u: org %s", + EXTRACT_16BITS(&dp->icmp_id), + EXTRACT_16BITS(&dp->icmp_seq), + icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_otime))); + + (void)snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),", recv %s", + icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_rtime))); + (void)snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),", xmit %s", + icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_ttime))); + break; + + default: + str = tok2str(icmp2str, "type-#%d", dp->icmp_type); + break; + } + (void)printf("ICMP %s, length %u", str, plen); + if (vflag && !fragmented) { /* don't attempt checksumming if this is a frag */ + u_int16_t sum, icmp_sum; + if (TTEST2(*bp, plen)) { + sum = in_cksum((u_short*)dp, plen, 0); + if (sum != 0) { + icmp_sum = EXTRACT_16BITS(&dp->icmp_cksum); + (void)printf(" (wrong icmp cksum %x (->%x)!)", + icmp_sum, + in_cksum_shouldbe(icmp_sum, sum)); + } + } + } + + /* + * print the remnants of the IP packet. + * save the snaplength as this may get overidden in the IP printer. + */ + if (vflag >= 1 && !ICMP_INFOTYPE(dp->icmp_type)) { + bp += 8; + (void)printf("\n\t"); + ip = (struct ip *)bp; + snaplen = snapend - bp; + snapend_save = snapend; + ip_print(gndo, bp, EXTRACT_16BITS(&ip->ip_len)); + snapend = snapend_save; + } + + /* + * Attempt to decode the MPLS extensions only for some ICMP types. + */ + if (vflag >= 1 && plen > ICMP_EXTD_MINLEN && ICMP_MPLS_EXT_TYPE(dp->icmp_type)) { + + TCHECK(*ext_dp); + + /* + * Check first if the mpls extension header shows a non-zero length. + * If the length field is not set then silently verify the checksum + * to check if an extension header is present. This is expedient, + * however not all implementations set the length field proper. + */ + if (!ext_dp->icmp_length && + in_cksum((const u_short *)&ext_dp->icmp_ext_version_res, + plen - ICMP_EXTD_MINLEN, 0)) { + return; + } + + printf("\n\tMPLS extension v%u", + ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res))); + + /* + * Sanity checking of the header. + */ + if (ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res)) != + ICMP_MPLS_EXT_VERSION) { + printf(" packet not supported"); + return; + } + + hlen = plen - ICMP_EXTD_MINLEN; + printf(", checksum 0x%04x (%scorrect), length %u", + EXTRACT_16BITS(ext_dp->icmp_ext_checksum), + in_cksum((const u_short *)&ext_dp->icmp_ext_version_res, + plen - ICMP_EXTD_MINLEN, 0) ? "in" : "", + hlen); + + hlen -= 4; /* subtract common header size */ + obj_tptr = (u_int8_t *)ext_dp->icmp_ext_data; + + while (hlen > sizeof(struct icmp_mpls_ext_object_header_t)) { + + icmp_mpls_ext_object_header = (struct icmp_mpls_ext_object_header_t *)obj_tptr; + TCHECK(*icmp_mpls_ext_object_header); + obj_tlen = EXTRACT_16BITS(icmp_mpls_ext_object_header->length); + obj_class_num = icmp_mpls_ext_object_header->class_num; + obj_ctype = icmp_mpls_ext_object_header->ctype; + obj_tptr += sizeof(struct icmp_mpls_ext_object_header_t); + + printf("\n\t %s Object (%u), Class-Type: %u, length %u", + tok2str(icmp_mpls_ext_obj_values,"unknown",obj_class_num), + obj_class_num, + obj_ctype, + obj_tlen); + + hlen-=sizeof(struct icmp_mpls_ext_object_header_t); /* length field includes tlv header */ + + /* infinite loop protection */ + if ((obj_class_num == 0) || + (obj_tlen < sizeof(struct icmp_mpls_ext_object_header_t))) { + return; + } + obj_tlen-=sizeof(struct icmp_mpls_ext_object_header_t); + + switch (obj_class_num) { + case 1: + switch(obj_ctype) { + case 1: + TCHECK2(*obj_tptr, 4); + raw_label = EXTRACT_32BITS(obj_tptr); + printf("\n\t label %u, exp %u", MPLS_LABEL(raw_label), MPLS_EXP(raw_label)); + if (MPLS_STACK(raw_label)) + printf(", [S]"); + printf(", ttl %u", MPLS_TTL(raw_label)); + break; + default: + print_unknown_data(obj_tptr, "\n\t ", obj_tlen); + } + break; + + /* + * FIXME those are the defined objects that lack a decoder + * you are welcome to contribute code ;-) + */ + case 2: + default: + print_unknown_data(obj_tptr, "\n\t ", obj_tlen); + break; + } + if (hlen < obj_tlen) + break; + hlen -= obj_tlen; + obj_tptr += obj_tlen; + } + } + + return; +trunc: + fputs("[|icmp]", stdout); +} diff --git a/print-icmp6.c b/print-icmp6.c new file mode 100644 index 0000000..cc48615 --- /dev/null +++ b/print-icmp6.c @@ -0,0 +1,1387 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-icmp6.c,v 1.86 2008-02-05 19:36:13 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef INET6 + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "ip6.h" +#include "icmp6.h" +#include "ipproto.h" + +#include "udp.h" +#include "ah.h" + +static const char *get_rtpref(u_int); +static const char *get_lifetime(u_int32_t); +static void print_lladdr(const u_char *, size_t); +static void icmp6_opt_print(const u_char *, int); +static void mld6_print(const u_char *); +static void mldv2_report_print(const u_char *, u_int); +static void mldv2_query_print(const u_char *, u_int); +static struct udphdr *get_upperlayer(u_char *, u_int *); +static void dnsname_print(const u_char *, const u_char *); +static void icmp6_nodeinfo_print(u_int, const u_char *, const u_char *); +static void icmp6_rrenum_print(const u_char *, const u_char *); + +#ifndef abs +#define abs(a) ((0 < (a)) ? (a) : -(a)) +#endif + +/* inline the various RPL definitions */ +#define ND_RPL_MESSAGE 0x9B + +static struct tok icmp6_type_values[] = { + { ICMP6_DST_UNREACH, "destination unreachable"}, + { ICMP6_PACKET_TOO_BIG, "packet too big"}, + { ICMP6_TIME_EXCEEDED, "time exceeded in-transit"}, + { ICMP6_PARAM_PROB, "parameter problem"}, + { ICMP6_ECHO_REQUEST, "echo request"}, + { ICMP6_ECHO_REPLY, "echo reply"}, + { MLD6_LISTENER_QUERY, "multicast listener query"}, + { MLD6_LISTENER_REPORT, "multicast listener report"}, + { MLD6_LISTENER_DONE, "multicast listener done"}, + { ND_ROUTER_SOLICIT, "router solicitation"}, + { ND_ROUTER_ADVERT, "router advertisement"}, + { ND_NEIGHBOR_SOLICIT, "neighbor solicitation"}, + { ND_NEIGHBOR_ADVERT, "neighbor advertisement"}, + { ND_REDIRECT, "redirect"}, + { ICMP6_ROUTER_RENUMBERING, "router renumbering"}, + { IND_SOLICIT, "inverse neighbor solicitation"}, + { IND_ADVERT, "inverse neighbor advertisement"}, + { MLDV2_LISTENER_REPORT, "multicast listener report v2"}, + { ICMP6_HADISCOV_REQUEST, "ha discovery request"}, + { ICMP6_HADISCOV_REPLY, "ha discovery reply"}, + { ICMP6_MOBILEPREFIX_SOLICIT, "mobile router solicitation"}, + { ICMP6_MOBILEPREFIX_ADVERT, "mobile router advertisement"}, + { ICMP6_WRUREQUEST, "who-are-you request"}, + { ICMP6_WRUREPLY, "who-are-you reply"}, + { ICMP6_NI_QUERY, "node information query"}, + { ICMP6_NI_REPLY, "node information reply"}, + { MLD6_MTRACE, "mtrace message"}, + { MLD6_MTRACE_RESP, "mtrace response"}, + { ND_RPL_MESSAGE, "RPL"}, + { 0, NULL } +}; + +static struct tok icmp6_dst_unreach_code_values[] = { + { ICMP6_DST_UNREACH_NOROUTE, "unreachable route" }, + { ICMP6_DST_UNREACH_ADMIN, " unreachable prohibited"}, + { ICMP6_DST_UNREACH_BEYONDSCOPE, "beyond scope"}, + { ICMP6_DST_UNREACH_ADDR, "unreachable address"}, + { ICMP6_DST_UNREACH_NOPORT, "unreachable port"}, + { 0, NULL } +}; + +static struct tok icmp6_opt_pi_flag_values[] = { + { ND_OPT_PI_FLAG_ONLINK, "onlink" }, + { ND_OPT_PI_FLAG_AUTO, "auto" }, + { ND_OPT_PI_FLAG_ROUTER, "router" }, + { 0, NULL } +}; + +static struct tok icmp6_opt_ra_flag_values[] = { + { ND_RA_FLAG_MANAGED, "managed" }, + { ND_RA_FLAG_OTHER, "other stateful"}, + { ND_RA_FLAG_HOME_AGENT, "home agent"}, + { 0, NULL } +}; + +static struct tok icmp6_nd_na_flag_values[] = { + { ND_NA_FLAG_ROUTER, "router" }, + { ND_NA_FLAG_SOLICITED, "solicited" }, + { ND_NA_FLAG_OVERRIDE, "override" }, + { 0, NULL } +}; + + +static struct tok icmp6_opt_values[] = { + { ND_OPT_SOURCE_LINKADDR, "source link-address"}, + { ND_OPT_TARGET_LINKADDR, "destination link-address"}, + { ND_OPT_PREFIX_INFORMATION, "prefix info"}, + { ND_OPT_REDIRECTED_HEADER, "redirected header"}, + { ND_OPT_MTU, "mtu"}, + { ND_OPT_RDNSS, "rdnss"}, + { ND_OPT_ADVINTERVAL, "advertisement interval"}, + { ND_OPT_HOMEAGENT_INFO, "homeagent information"}, + { ND_OPT_ROUTE_INFO, "route info"}, + { 0, NULL } +}; + +/* mldv2 report types */ +static struct tok mldv2report2str[] = { + { 1, "is_in" }, + { 2, "is_ex" }, + { 3, "to_in" }, + { 4, "to_ex" }, + { 5, "allow" }, + { 6, "block" }, + { 0, NULL } +}; + +static const char * +get_rtpref(u_int v) +{ + static const char *rtpref_str[] = { + "medium", /* 00 */ + "high", /* 01 */ + "rsv", /* 10 */ + "low" /* 11 */ + }; + + return rtpref_str[((v & ND_RA_FLAG_RTPREF_MASK) >> 3) & 0xff]; +} + +static const char * +get_lifetime(u_int32_t v) +{ + static char buf[20]; + + if (v == (u_int32_t)~0UL) + return "infinity"; + else { + snprintf(buf, sizeof(buf), "%u", v); + return buf; + } +} + +static void +print_lladdr(const u_int8_t *p, size_t l) +{ + const u_int8_t *ep, *q; + + q = p; + ep = p + l; + while (l > 0 && q < ep) { + if (q > p) + printf(":"); + printf("%02x", *q++); + l--; + } +} + +static int icmp6_cksum(const struct ip6_hdr *ip6, const struct icmp6_hdr *icp, + u_int len) +{ + size_t i; + register const u_int16_t *sp; + u_int32_t sum; + union { + struct { + struct in6_addr ph_src; + struct in6_addr ph_dst; + u_int32_t ph_len; + u_int8_t ph_zero[3]; + u_int8_t ph_nxt; + } ph; + u_int16_t pa[20]; + } phu; + + /* pseudo-header */ + memset(&phu, 0, sizeof(phu)); + phu.ph.ph_src = ip6->ip6_src; + phu.ph.ph_dst = ip6->ip6_dst; + phu.ph.ph_len = htonl(len); + phu.ph.ph_nxt = IPPROTO_ICMPV6; + + sum = 0; + for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) + sum += phu.pa[i]; + + sp = (const u_int16_t *)icp; + + for (i = 0; i < (len & ~1); i += 2) + sum += *sp++; + + if (len & 1) + sum += htons((*(const u_int8_t *)sp) << 8); + + while (sum > 0xffff) + sum = (sum & 0xffff) + (sum >> 16); + sum = ~sum & 0xffff; + + return (sum); +} + +enum ND_RPL_CODE { + ND_RPL_DAG_IS=0x01, + ND_RPL_DAG_IO=0x02, + ND_RPL_DAO =0x04 +}; + +enum ND_RPL_DIO_FLAGS { + ND_RPL_DIO_GROUNDED = 0x80, + ND_RPL_DIO_DATRIG = 0x40, + ND_RPL_DIO_DASUPPORT= 0x20, + ND_RPL_DIO_RES4 = 0x10, + ND_RPL_DIO_RES3 = 0x08, + ND_RPL_DIO_PRF_MASK = 0x07, /* 3-bit preference */ +}; + +struct nd_rpl_dio { + u_int8_t rpl_flags; + u_int8_t rpl_seq; + u_int8_t rpl_instanceid; + u_int8_t rpl_dagrank; + u_int8_t rpl_dagid[16]; +}; + +static void +rpl_print(netdissect_options *ndo, + const struct icmp6_hdr *hdr, + const u_char *bp, u_int length _U_) +{ + struct nd_rpl_dio *dio = (struct nd_rpl_dio *)bp; + + ND_TCHECK(dio->rpl_dagid); + + switch(hdr->icmp6_code) { + case ND_RPL_DAG_IS: + ND_PRINT((ndo, ", DAG Information Solicitation")); + if(ndo->ndo_vflag) { + } + break; + case ND_RPL_DAG_IO: + ND_PRINT((ndo, ", DAG Information Object")); + if(ndo->ndo_vflag) { + char dagid[65]; + char *d = dagid; + int i; + for(i=0;i<16;i++) { + if(isprint(dio->rpl_dagid[i])) { + *d++ = dio->rpl_dagid[i]; + } else { + int cnt=snprintf(d,4,"0x%02x", + dio->rpl_dagid[i]); + d += cnt; + } + } + *d++ = '\0'; + ND_PRINT((ndo, " [seq:%u,instance:%u,rank:%u,dagid:%s]", + dio->rpl_seq, + dio->rpl_instanceid, + dio->rpl_dagrank, + dagid)); + } + break; + case ND_RPL_DAO: + ND_PRINT((ndo, ", Destination Advertisement Object")); + if(ndo->ndo_vflag) { + } + break; + default: + ND_PRINT((ndo, ", RPL message, unknown code %u",hdr->icmp6_code)); + break; + } + return; +trunc: + ND_PRINT((ndo," [|truncated]")); + return; + +} + + +void +icmp6_print(netdissect_options *ndo, + const u_char *bp, u_int length, const u_char *bp2, int fragmented) +{ + const struct icmp6_hdr *dp; + const struct ip6_hdr *ip; + const struct ip6_hdr *oip; + const struct udphdr *ouh; + int dport; + const u_char *ep; + u_int prot; + + dp = (struct icmp6_hdr *)bp; + ip = (struct ip6_hdr *)bp2; + oip = (struct ip6_hdr *)(dp + 1); + /* 'ep' points to the end of available data. */ + ep = snapend; + + TCHECK(dp->icmp6_cksum); + + if (vflag && !fragmented) { + int sum = dp->icmp6_cksum; + + if (TTEST2(bp[0], length)) { + sum = icmp6_cksum(ip, dp, length); + if (sum != 0) + (void)printf("[bad icmp6 cksum %x!] ", sum); + else + (void)printf("[icmp6 sum ok] "); + } + } + + printf("ICMP6, %s", tok2str(icmp6_type_values,"unknown icmp6 type (%u)",dp->icmp6_type)); + + /* display cosmetics: print the packet length for printer that use the vflag now */ + if (vflag && (dp->icmp6_type == + ND_ROUTER_SOLICIT || + ND_ROUTER_ADVERT || + ND_NEIGHBOR_ADVERT || + ND_NEIGHBOR_SOLICIT || + ND_REDIRECT || + ICMP6_HADISCOV_REPLY || + ICMP6_MOBILEPREFIX_ADVERT )) + printf(", length %u", length); + + switch (dp->icmp6_type) { + case ICMP6_DST_UNREACH: + TCHECK(oip->ip6_dst); + printf(", %s", tok2str(icmp6_dst_unreach_code_values,"unknown unreach code (%u)",dp->icmp6_code)); + switch (dp->icmp6_code) { + + case ICMP6_DST_UNREACH_NOROUTE: /* fall through */ + case ICMP6_DST_UNREACH_ADMIN: + case ICMP6_DST_UNREACH_ADDR: + printf(" %s",ip6addr_string(&oip->ip6_dst)); + break; + case ICMP6_DST_UNREACH_BEYONDSCOPE: + printf(" %s, source address %s", + ip6addr_string(&oip->ip6_dst), + ip6addr_string(&oip->ip6_src)); + break; + case ICMP6_DST_UNREACH_NOPORT: + if ((ouh = get_upperlayer((u_char *)oip, &prot)) + == NULL) + goto trunc; + + dport = EXTRACT_16BITS(&ouh->uh_dport); + switch (prot) { + case IPPROTO_TCP: + printf(", %s tcp port %s", + ip6addr_string(&oip->ip6_dst), + tcpport_string(dport)); + break; + case IPPROTO_UDP: + printf(", %s udp port %s", + ip6addr_string(&oip->ip6_dst), + udpport_string(dport)); + break; + default: + printf(", %s protocol %d port %d unreachable", + ip6addr_string(&oip->ip6_dst), + oip->ip6_nxt, dport); + break; + } + break; + default: + if (vflag <= 1) { + print_unknown_data(bp,"\n\t",length); + return; + } + break; + } + break; + case ICMP6_PACKET_TOO_BIG: + TCHECK(dp->icmp6_mtu); + printf(", mtu %u", EXTRACT_32BITS(&dp->icmp6_mtu)); + break; + case ICMP6_TIME_EXCEEDED: + TCHECK(oip->ip6_dst); + switch (dp->icmp6_code) { + case ICMP6_TIME_EXCEED_TRANSIT: + printf(" for %s", + ip6addr_string(&oip->ip6_dst)); + break; + case ICMP6_TIME_EXCEED_REASSEMBLY: + printf(" (reassembly)"); + break; + default: + printf(", unknown code (%u)", dp->icmp6_code); + break; + } + break; + case ICMP6_PARAM_PROB: + TCHECK(oip->ip6_dst); + switch (dp->icmp6_code) { + case ICMP6_PARAMPROB_HEADER: + printf(", errorneous - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr)); + break; + case ICMP6_PARAMPROB_NEXTHEADER: + printf(", next header - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr)); + break; + case ICMP6_PARAMPROB_OPTION: + printf(", option - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr)); + break; + default: + printf(", code-#%d", + dp->icmp6_code); + break; + } + break; + case ICMP6_ECHO_REQUEST: + case ICMP6_ECHO_REPLY: + TCHECK(dp->icmp6_seq); + printf(", seq %u", EXTRACT_16BITS(&dp->icmp6_seq)); + break; + case ICMP6_MEMBERSHIP_QUERY: + if (length == MLD_MINLEN) { + mld6_print((const u_char *)dp); + } else if (length >= MLDV2_MINLEN) { + printf("v2 "); + mldv2_query_print((const u_char *)dp, length); + } else { + printf(" unknown-version (len %u) ", length); + } + break; + case ICMP6_MEMBERSHIP_REPORT: + mld6_print((const u_char *)dp); + break; + case ICMP6_MEMBERSHIP_REDUCTION: + mld6_print((const u_char *)dp); + break; + case ND_ROUTER_SOLICIT: +#define RTSOLLEN 8 + if (vflag) { + icmp6_opt_print((const u_char *)dp + RTSOLLEN, + length - RTSOLLEN); + } + break; + case ND_ROUTER_ADVERT: +#define RTADVLEN 16 + if (vflag) { + struct nd_router_advert *p; + + p = (struct nd_router_advert *)dp; + TCHECK(p->nd_ra_retransmit); + printf("\n\thop limit %u, Flags [%s]" \ + ", pref %s, router lifetime %us, reachable time %us, retrans time %us", + (u_int)p->nd_ra_curhoplimit, + bittok2str(icmp6_opt_ra_flag_values,"none",(p->nd_ra_flags_reserved)), + get_rtpref(p->nd_ra_flags_reserved), + EXTRACT_16BITS(&p->nd_ra_router_lifetime), + EXTRACT_32BITS(&p->nd_ra_reachable), + EXTRACT_32BITS(&p->nd_ra_retransmit)); + + icmp6_opt_print((const u_char *)dp + RTADVLEN, + length - RTADVLEN); + } + break; + case ND_NEIGHBOR_SOLICIT: + { + struct nd_neighbor_solicit *p; + p = (struct nd_neighbor_solicit *)dp; + TCHECK(p->nd_ns_target); + printf(", who has %s", ip6addr_string(&p->nd_ns_target)); + if (vflag) { +#define NDSOLLEN 24 + icmp6_opt_print((const u_char *)dp + NDSOLLEN, + length - NDSOLLEN); + } + } + break; + case ND_NEIGHBOR_ADVERT: + { + struct nd_neighbor_advert *p; + + p = (struct nd_neighbor_advert *)dp; + TCHECK(p->nd_na_target); + printf(", tgt is %s", + ip6addr_string(&p->nd_na_target)); + if (vflag) { + printf(", Flags [%s]", + bittok2str(icmp6_nd_na_flag_values, + "none", + EXTRACT_32BITS(&p->nd_na_flags_reserved))); +#define NDADVLEN 24 + icmp6_opt_print((const u_char *)dp + NDADVLEN, + length - NDADVLEN); +#undef NDADVLEN + } + } + break; + case ND_REDIRECT: +#define RDR(i) ((struct nd_redirect *)(i)) + TCHECK(RDR(dp)->nd_rd_dst); + printf(", %s", getname6((const u_char *)&RDR(dp)->nd_rd_dst)); + TCHECK(RDR(dp)->nd_rd_target); + printf(" to %s", + getname6((const u_char*)&RDR(dp)->nd_rd_target)); +#define REDIRECTLEN 40 + if (vflag) { + icmp6_opt_print((const u_char *)dp + REDIRECTLEN, + length - REDIRECTLEN); + } + break; +#undef REDIRECTLEN +#undef RDR + case ICMP6_ROUTER_RENUMBERING: + icmp6_rrenum_print(bp, ep); + break; + case ICMP6_NI_QUERY: + case ICMP6_NI_REPLY: + icmp6_nodeinfo_print(length, bp, ep); + break; + case IND_SOLICIT: + case IND_ADVERT: + break; + case ICMP6_V2_MEMBERSHIP_REPORT: + mldv2_report_print((const u_char *) dp, length); + break; + case ICMP6_MOBILEPREFIX_SOLICIT: /* fall through */ + case ICMP6_HADISCOV_REQUEST: + TCHECK(dp->icmp6_data16[0]); + printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0])); + break; + case ICMP6_HADISCOV_REPLY: + if (vflag) { + struct in6_addr *in6; + u_char *cp; + + TCHECK(dp->icmp6_data16[0]); + printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0])); + cp = (u_char *)dp + length; + in6 = (struct in6_addr *)(dp + 1); + for (; (u_char *)in6 < cp; in6++) { + TCHECK(*in6); + printf(", %s", ip6addr_string(in6)); + } + } + break; + case ICMP6_MOBILEPREFIX_ADVERT: + if (vflag) { + TCHECK(dp->icmp6_data16[0]); + printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0])); + if (dp->icmp6_data16[1] & 0xc0) + printf(" "); + if (dp->icmp6_data16[1] & 0x80) + printf("M"); + if (dp->icmp6_data16[1] & 0x40) + printf("O"); +#define MPADVLEN 8 + icmp6_opt_print((const u_char *)dp + MPADVLEN, + length - MPADVLEN); + } + break; + case ND_RPL_MESSAGE: + rpl_print(ndo, dp, &dp->icmp6_data8[0], length); + break; + default: + printf(", length %u", length); + if (vflag <= 1) + print_unknown_data(bp,"\n\t", length); + return; + } + if (!vflag) + printf(", length %u", length); + return; +trunc: + fputs("[|icmp6]", stdout); +} + +static struct udphdr * +get_upperlayer(u_char *bp, u_int *prot) +{ + const u_char *ep; + struct ip6_hdr *ip6 = (struct ip6_hdr *)bp; + struct udphdr *uh; + struct ip6_hbh *hbh; + struct ip6_frag *fragh; + struct ah *ah; + u_int nh; + int hlen; + + /* 'ep' points to the end of available data. */ + ep = snapend; + + if (!TTEST(ip6->ip6_nxt)) + return NULL; + + nh = ip6->ip6_nxt; + hlen = sizeof(struct ip6_hdr); + + while (bp < ep) { + bp += hlen; + + switch(nh) { + case IPPROTO_UDP: + case IPPROTO_TCP: + uh = (struct udphdr *)bp; + if (TTEST(uh->uh_dport)) { + *prot = nh; + return(uh); + } + else + return(NULL); + /* NOTREACHED */ + + case IPPROTO_HOPOPTS: + case IPPROTO_DSTOPTS: + case IPPROTO_ROUTING: + hbh = (struct ip6_hbh *)bp; + if (!TTEST(hbh->ip6h_len)) + return(NULL); + nh = hbh->ip6h_nxt; + hlen = (hbh->ip6h_len + 1) << 3; + break; + + case IPPROTO_FRAGMENT: /* this should be odd, but try anyway */ + fragh = (struct ip6_frag *)bp; + if (!TTEST(fragh->ip6f_offlg)) + return(NULL); + /* fragments with non-zero offset are meaningless */ + if ((EXTRACT_16BITS(&fragh->ip6f_offlg) & IP6F_OFF_MASK) != 0) + return(NULL); + nh = fragh->ip6f_nxt; + hlen = sizeof(struct ip6_frag); + break; + + case IPPROTO_AH: + ah = (struct ah *)bp; + if (!TTEST(ah->ah_len)) + return(NULL); + nh = ah->ah_nxt; + hlen = (ah->ah_len + 2) << 2; + break; + + default: /* unknown or undecodable header */ + *prot = nh; /* meaningless, but set here anyway */ + return(NULL); + } + } + + return(NULL); /* should be notreached, though */ +} + +static void +icmp6_opt_print(const u_char *bp, int resid) +{ + const struct nd_opt_hdr *op; + const struct nd_opt_hdr *opl; /* why there's no struct? */ + const struct nd_opt_prefix_info *opp; + const struct icmp6_opts_redirect *opr; + const struct nd_opt_mtu *opm; + const struct nd_opt_rdnss *oprd; + const struct nd_opt_advinterval *opa; + const struct nd_opt_homeagent_info *oph; + const struct nd_opt_route_info *opri; + const u_char *cp, *ep; + struct in6_addr in6, *in6p; + size_t l; + u_int i; + +#define ECHECK(var) if ((u_char *)&(var) > ep - sizeof(var)) return + + cp = bp; + /* 'ep' points to the end of available data. */ + ep = snapend; + + while (cp < ep) { + op = (struct nd_opt_hdr *)cp; + + ECHECK(op->nd_opt_len); + if (resid <= 0) + return; + if (op->nd_opt_len == 0) + goto trunc; + if (cp + (op->nd_opt_len << 3) > ep) + goto trunc; + + printf("\n\t %s option (%u), length %u (%u): ", + tok2str(icmp6_opt_values, "unknown", op->nd_opt_type), + op->nd_opt_type, + op->nd_opt_len << 3, + op->nd_opt_len); + + switch (op->nd_opt_type) { + case ND_OPT_SOURCE_LINKADDR: + opl = (struct nd_opt_hdr *)op; + l = (op->nd_opt_len << 3) - 2; + print_lladdr(cp + 2, l); + break; + case ND_OPT_TARGET_LINKADDR: + opl = (struct nd_opt_hdr *)op; + l = (op->nd_opt_len << 3) - 2; + print_lladdr(cp + 2, l); + break; + case ND_OPT_PREFIX_INFORMATION: + opp = (struct nd_opt_prefix_info *)op; + TCHECK(opp->nd_opt_pi_prefix); + printf("%s/%u%s, Flags [%s], valid time %ss", + ip6addr_string(&opp->nd_opt_pi_prefix), + opp->nd_opt_pi_prefix_len, + (op->nd_opt_len != 4) ? "badlen" : "", + bittok2str(icmp6_opt_pi_flag_values, "none", opp->nd_opt_pi_flags_reserved), + get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_valid_time))); + printf(", pref. time %ss", get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_preferred_time))); + break; + case ND_OPT_REDIRECTED_HEADER: + opr = (struct icmp6_opts_redirect *)op; + print_unknown_data(bp,"\n\t ",op->nd_opt_len<<3); + /* xxx */ + break; + case ND_OPT_MTU: + opm = (struct nd_opt_mtu *)op; + TCHECK(opm->nd_opt_mtu_mtu); + printf(" %u%s", + EXTRACT_32BITS(&opm->nd_opt_mtu_mtu), + (op->nd_opt_len != 1) ? "bad option length" : "" ); + break; + case ND_OPT_RDNSS: + oprd = (struct nd_opt_rdnss *)op; + l = (op->nd_opt_len - 1) / 2; + printf(" lifetime %us,", + EXTRACT_32BITS(&oprd->nd_opt_rdnss_lifetime)); + for (i = 0; i < l; i++) { + TCHECK(oprd->nd_opt_rdnss_addr[i]); + printf(" addr: %s", + ip6addr_string(&oprd->nd_opt_rdnss_addr[i])); + } + break; + case ND_OPT_ADVINTERVAL: + opa = (struct nd_opt_advinterval *)op; + TCHECK(opa->nd_opt_adv_interval); + printf(" %us", EXTRACT_32BITS(&opa->nd_opt_adv_interval)); + break; + case ND_OPT_HOMEAGENT_INFO: + oph = (struct nd_opt_homeagent_info *)op; + TCHECK(oph->nd_opt_hai_lifetime); + printf(" preference %u, lifetime %u", + EXTRACT_16BITS(&oph->nd_opt_hai_preference), + EXTRACT_16BITS(&oph->nd_opt_hai_lifetime)); + break; + case ND_OPT_ROUTE_INFO: + opri = (struct nd_opt_route_info *)op; + TCHECK(opri->nd_opt_rti_lifetime); + memset(&in6, 0, sizeof(in6)); + in6p = (struct in6_addr *)(opri + 1); + switch (op->nd_opt_len) { + case 1: + break; + case 2: + TCHECK2(*in6p, 8); + memcpy(&in6, opri + 1, 8); + break; + case 3: + TCHECK(*in6p); + memcpy(&in6, opri + 1, sizeof(in6)); + break; + default: + goto trunc; + } + printf(" %s/%u", ip6addr_string(&in6), + opri->nd_opt_rti_prefixlen); + printf(", pref=%s", get_rtpref(opri->nd_opt_rti_flags)); + printf(", lifetime=%s", + get_lifetime(EXTRACT_32BITS(&opri->nd_opt_rti_lifetime))); + break; + default: + if (vflag <= 1) { + print_unknown_data(cp+2,"\n\t ", (op->nd_opt_len << 3) - 2); /* skip option header */ + return; + } + break; + } + /* do we want to see an additional hexdump ? */ + if (vflag> 1) + print_unknown_data(cp+2,"\n\t ", (op->nd_opt_len << 3) - 2); /* skip option header */ + + cp += op->nd_opt_len << 3; + resid -= op->nd_opt_len << 3; + } + return; + + trunc: + fputs("[ndp opt]", stdout); + return; +#undef ECHECK +} + +static void +mld6_print(const u_char *bp) +{ + struct mld6_hdr *mp = (struct mld6_hdr *)bp; + const u_char *ep; + + /* 'ep' points to the end of available data. */ + ep = snapend; + + if ((u_char *)mp + sizeof(*mp) > ep) + return; + + printf("max resp delay: %d ", EXTRACT_16BITS(&mp->mld6_maxdelay)); + printf("addr: %s", ip6addr_string(&mp->mld6_addr)); +} + +static void +mldv2_report_print(const u_char *bp, u_int len) +{ + struct icmp6_hdr *icp = (struct icmp6_hdr *) bp; + u_int group, nsrcs, ngroups; + u_int i, j; + + /* Minimum len is 8 */ + if (len < 8) { + printf(" [invalid len %d]", len); + return; + } + + TCHECK(icp->icmp6_data16[1]); + ngroups = EXTRACT_16BITS(&icp->icmp6_data16[1]); + printf(", %d group record(s)", ngroups); + if (vflag > 0) { + /* Print the group records */ + group = 8; + for (i = 0; i < ngroups; i++) { + /* type(1) + auxlen(1) + numsrc(2) + grp(16) */ + if (len < group + 20) { + printf(" [invalid number of groups]"); + return; + } + TCHECK2(bp[group + 4], sizeof(struct in6_addr)); + printf(" [gaddr %s", ip6addr_string(&bp[group + 4])); + printf(" %s", tok2str(mldv2report2str, " [v2-report-#%d]", + bp[group])); + nsrcs = (bp[group + 2] << 8) + bp[group + 3]; + /* Check the number of sources and print them */ + if (len < group + 20 + (nsrcs * sizeof(struct in6_addr))) { + printf(" [invalid number of sources %d]", nsrcs); + return; + } + if (vflag == 1) + printf(", %d source(s)", nsrcs); + else { + /* Print the sources */ + (void)printf(" {"); + for (j = 0; j < nsrcs; j++) { + TCHECK2(bp[group + 20 + j * sizeof(struct in6_addr)], + sizeof(struct in6_addr)); + printf(" %s", ip6addr_string(&bp[group + 20 + j * sizeof(struct in6_addr)])); + } + (void)printf(" }"); + } + /* Next group record */ + group += 20 + nsrcs * sizeof(struct in6_addr); + printf("]"); + } + } + return; +trunc: + (void)printf("[|icmp6]"); + return; +} + +static void +mldv2_query_print(const u_char *bp, u_int len) +{ + struct icmp6_hdr *icp = (struct icmp6_hdr *) bp; + u_int mrc; + int mrt, qqi; + u_int nsrcs; + register u_int i; + + /* Minimum len is 28 */ + if (len < 28) { + printf(" [invalid len %d]", len); + return; + } + TCHECK(icp->icmp6_data16[0]); + mrc = EXTRACT_16BITS(&icp->icmp6_data16[0]); + if (mrc < 32768) { + mrt = mrc; + } else { + mrt = ((mrc & 0x0fff) | 0x1000) << (((mrc & 0x7000) >> 12) + 3); + } + if (vflag) { + (void)printf(" [max resp delay=%d]", mrt); + } + TCHECK2(bp[8], sizeof(struct in6_addr)); + printf(" [gaddr %s", ip6addr_string(&bp[8])); + + if (vflag) { + TCHECK(bp[25]); + if (bp[24] & 0x08) { + printf(" sflag"); + } + if (bp[24] & 0x07) { + printf(" robustness=%d", bp[24] & 0x07); + } + if (bp[25] < 128) { + qqi = bp[25]; + } else { + qqi = ((bp[25] & 0x0f) | 0x10) << (((bp[25] & 0x70) >> 4) + 3); + } + printf(" qqi=%d", qqi); + } + + TCHECK2(bp[26], 2); + nsrcs = EXTRACT_16BITS(&bp[26]); + if (nsrcs > 0) { + if (len < 28 + nsrcs * sizeof(struct in6_addr)) + printf(" [invalid number of sources]"); + else if (vflag > 1) { + printf(" {"); + for (i = 0; i < nsrcs; i++) { + TCHECK2(bp[28 + i * sizeof(struct in6_addr)], + sizeof(struct in6_addr)); + printf(" %s", ip6addr_string(&bp[28 + i * sizeof(struct in6_addr)])); + } + printf(" }"); + } else + printf(", %d source(s)", nsrcs); + } + printf("]"); + return; +trunc: + (void)printf("[|icmp6]"); + return; +} + +static void +dnsname_print(const u_char *cp, const u_char *ep) +{ + int i; + + /* DNS name decoding - no decompression */ + printf(", \""); + while (cp < ep) { + i = *cp++; + if (i) { + if (i > ep - cp) { + printf("???"); + break; + } + while (i-- && cp < ep) { + safeputchar(*cp); + cp++; + } + if (cp + 1 < ep && *cp) + printf("."); + } else { + if (cp == ep) { + /* FQDN */ + printf("."); + } else if (cp + 1 == ep && *cp == '\0') { + /* truncated */ + } else { + /* invalid */ + printf("???"); + } + break; + } + } + printf("\""); +} + +static void +icmp6_nodeinfo_print(u_int icmp6len, const u_char *bp, const u_char *ep) +{ + struct icmp6_nodeinfo *ni6; + struct icmp6_hdr *dp; + const u_char *cp; + size_t siz, i; + int needcomma; + + if (ep < bp) + return; + dp = (struct icmp6_hdr *)bp; + ni6 = (struct icmp6_nodeinfo *)bp; + siz = ep - bp; + + switch (ni6->ni_type) { + case ICMP6_NI_QUERY: + if (siz == sizeof(*dp) + 4) { + /* KAME who-are-you */ + printf(" who-are-you request"); + break; + } + printf(" node information query"); + + TCHECK2(*dp, sizeof(*ni6)); + ni6 = (struct icmp6_nodeinfo *)dp; + printf(" ("); /*)*/ + switch (EXTRACT_16BITS(&ni6->ni_qtype)) { + case NI_QTYPE_NOOP: + printf("noop"); + break; + case NI_QTYPE_SUPTYPES: + printf("supported qtypes"); + i = EXTRACT_16BITS(&ni6->ni_flags); + if (i) + printf(" [%s]", (i & 0x01) ? "C" : ""); + break; + break; + case NI_QTYPE_FQDN: + printf("DNS name"); + break; + case NI_QTYPE_NODEADDR: + printf("node addresses"); + i = ni6->ni_flags; + if (!i) + break; + /* NI_NODEADDR_FLAG_TRUNCATE undefined for query */ + printf(" [%s%s%s%s%s%s]", + (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "", + (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "", + (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "", + (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "", + (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "", + (i & NI_NODEADDR_FLAG_ALL) ? "A" : ""); + break; + default: + printf("unknown"); + break; + } + + if (ni6->ni_qtype == NI_QTYPE_NOOP || + ni6->ni_qtype == NI_QTYPE_SUPTYPES) { + if (siz != sizeof(*ni6)) + if (vflag) + printf(", invalid len"); + /*(*/ + printf(")"); + break; + } + + + /* XXX backward compat, icmp-name-lookup-03 */ + if (siz == sizeof(*ni6)) { + printf(", 03 draft"); + /*(*/ + printf(")"); + break; + } + + switch (ni6->ni_code) { + case ICMP6_NI_SUBJ_IPV6: + if (!TTEST2(*dp, + sizeof(*ni6) + sizeof(struct in6_addr))) + break; + if (siz != sizeof(*ni6) + sizeof(struct in6_addr)) { + if (vflag) + printf(", invalid subject len"); + break; + } + printf(", subject=%s", + getname6((const u_char *)(ni6 + 1))); + break; + case ICMP6_NI_SUBJ_FQDN: + printf(", subject=DNS name"); + cp = (const u_char *)(ni6 + 1); + if (cp[0] == ep - cp - 1) { + /* icmp-name-lookup-03, pascal string */ + if (vflag) + printf(", 03 draft"); + cp++; + printf(", \""); + while (cp < ep) { + safeputchar(*cp); + cp++; + } + printf("\""); + } else + dnsname_print(cp, ep); + break; + case ICMP6_NI_SUBJ_IPV4: + if (!TTEST2(*dp, sizeof(*ni6) + sizeof(struct in_addr))) + break; + if (siz != sizeof(*ni6) + sizeof(struct in_addr)) { + if (vflag) + printf(", invalid subject len"); + break; + } + printf(", subject=%s", + getname((const u_char *)(ni6 + 1))); + break; + default: + printf(", unknown subject"); + break; + } + + /*(*/ + printf(")"); + break; + + case ICMP6_NI_REPLY: + if (icmp6len > siz) { + printf("[|icmp6: node information reply]"); + break; + } + + needcomma = 0; + + ni6 = (struct icmp6_nodeinfo *)dp; + printf(" node information reply"); + printf(" ("); /*)*/ + switch (ni6->ni_code) { + case ICMP6_NI_SUCCESS: + if (vflag) { + printf("success"); + needcomma++; + } + break; + case ICMP6_NI_REFUSED: + printf("refused"); + needcomma++; + if (siz != sizeof(*ni6)) + if (vflag) + printf(", invalid length"); + break; + case ICMP6_NI_UNKNOWN: + printf("unknown"); + needcomma++; + if (siz != sizeof(*ni6)) + if (vflag) + printf(", invalid length"); + break; + } + + if (ni6->ni_code != ICMP6_NI_SUCCESS) { + /*(*/ + printf(")"); + break; + } + + switch (EXTRACT_16BITS(&ni6->ni_qtype)) { + case NI_QTYPE_NOOP: + if (needcomma) + printf(", "); + printf("noop"); + if (siz != sizeof(*ni6)) + if (vflag) + printf(", invalid length"); + break; + case NI_QTYPE_SUPTYPES: + if (needcomma) + printf(", "); + printf("supported qtypes"); + i = EXTRACT_16BITS(&ni6->ni_flags); + if (i) + printf(" [%s]", (i & 0x01) ? "C" : ""); + break; + case NI_QTYPE_FQDN: + if (needcomma) + printf(", "); + printf("DNS name"); + cp = (const u_char *)(ni6 + 1) + 4; + if (cp[0] == ep - cp - 1) { + /* icmp-name-lookup-03, pascal string */ + if (vflag) + printf(", 03 draft"); + cp++; + printf(", \""); + while (cp < ep) { + safeputchar(*cp); + cp++; + } + printf("\""); + } else + dnsname_print(cp, ep); + if ((EXTRACT_16BITS(&ni6->ni_flags) & 0x01) != 0) + printf(" [TTL=%u]", *(u_int32_t *)(ni6 + 1)); + break; + case NI_QTYPE_NODEADDR: + if (needcomma) + printf(", "); + printf("node addresses"); + i = sizeof(*ni6); + while (i < siz) { + if (i + sizeof(struct in6_addr) + sizeof(int32_t) > siz) + break; + printf(" %s", getname6(bp + i)); + i += sizeof(struct in6_addr); + printf("(%d)", (int32_t)EXTRACT_32BITS(bp + i)); + i += sizeof(int32_t); + } + i = ni6->ni_flags; + if (!i) + break; + printf(" [%s%s%s%s%s%s%s]", + (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "", + (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "", + (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "", + (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "", + (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "", + (i & NI_NODEADDR_FLAG_ALL) ? "A" : "", + (i & NI_NODEADDR_FLAG_TRUNCATE) ? "T" : ""); + break; + default: + if (needcomma) + printf(", "); + printf("unknown"); + break; + } + + /*(*/ + printf(")"); + break; + } + return; + +trunc: + fputs("[|icmp6]", stdout); +} + +static void +icmp6_rrenum_print(const u_char *bp, const u_char *ep) +{ + struct icmp6_router_renum *rr6; + const char *cp; + struct rr_pco_match *match; + struct rr_pco_use *use; + char hbuf[NI_MAXHOST]; + int n; + + if (ep < bp) + return; + rr6 = (struct icmp6_router_renum *)bp; + cp = (const char *)(rr6 + 1); + + TCHECK(rr6->rr_reserved); + switch (rr6->rr_code) { + case ICMP6_ROUTER_RENUMBERING_COMMAND: + printf("router renum: command"); + break; + case ICMP6_ROUTER_RENUMBERING_RESULT: + printf("router renum: result"); + break; + case ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET: + printf("router renum: sequence number reset"); + break; + default: + printf("router renum: code-#%d", rr6->rr_code); + break; + } + + printf(", seq=%u", EXTRACT_32BITS(&rr6->rr_seqnum)); + + if (vflag) { +#define F(x, y) ((rr6->rr_flags) & (x) ? (y) : "") + printf("["); /*]*/ + if (rr6->rr_flags) { + printf("%s%s%s%s%s,", F(ICMP6_RR_FLAGS_TEST, "T"), + F(ICMP6_RR_FLAGS_REQRESULT, "R"), + F(ICMP6_RR_FLAGS_FORCEAPPLY, "A"), + F(ICMP6_RR_FLAGS_SPECSITE, "S"), + F(ICMP6_RR_FLAGS_PREVDONE, "P")); + } + printf("seg=%u,", rr6->rr_segnum); + printf("maxdelay=%u", EXTRACT_16BITS(&rr6->rr_maxdelay)); + if (rr6->rr_reserved) + printf("rsvd=0x%x", EXTRACT_32BITS(&rr6->rr_reserved)); + /*[*/ + printf("]"); +#undef F + } + + if (rr6->rr_code == ICMP6_ROUTER_RENUMBERING_COMMAND) { + match = (struct rr_pco_match *)cp; + cp = (const char *)(match + 1); + + TCHECK(match->rpm_prefix); + + if (vflag > 1) + printf("\n\t"); + else + printf(" "); + printf("match("); /*)*/ + switch (match->rpm_code) { + case RPM_PCO_ADD: printf("add"); break; + case RPM_PCO_CHANGE: printf("change"); break; + case RPM_PCO_SETGLOBAL: printf("setglobal"); break; + default: printf("#%u", match->rpm_code); break; + } + + if (vflag) { + printf(",ord=%u", match->rpm_ordinal); + printf(",min=%u", match->rpm_minlen); + printf(",max=%u", match->rpm_maxlen); + } + if (inet_ntop(AF_INET6, &match->rpm_prefix, hbuf, sizeof(hbuf))) + printf(",%s/%u", hbuf, match->rpm_matchlen); + else + printf(",?/%u", match->rpm_matchlen); + /*(*/ + printf(")"); + + n = match->rpm_len - 3; + if (n % 4) + goto trunc; + n /= 4; + while (n-- > 0) { + use = (struct rr_pco_use *)cp; + cp = (const char *)(use + 1); + + TCHECK(use->rpu_prefix); + + if (vflag > 1) + printf("\n\t"); + else + printf(" "); + printf("use("); /*)*/ + if (use->rpu_flags) { +#define F(x, y) ((use->rpu_flags) & (x) ? (y) : "") + printf("%s%s,", + F(ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME, "V"), + F(ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME, "P")); +#undef F + } + if (vflag) { + printf("mask=0x%x,", use->rpu_ramask); + printf("raflags=0x%x,", use->rpu_raflags); + if (~use->rpu_vltime == 0) + printf("vltime=infty,"); + else + printf("vltime=%u,", + EXTRACT_32BITS(&use->rpu_vltime)); + if (~use->rpu_pltime == 0) + printf("pltime=infty,"); + else + printf("pltime=%u,", + EXTRACT_32BITS(&use->rpu_pltime)); + } + if (inet_ntop(AF_INET6, &use->rpu_prefix, hbuf, + sizeof(hbuf))) + printf("%s/%u/%u", hbuf, use->rpu_uselen, + use->rpu_keeplen); + else + printf("?/%u/%u", use->rpu_uselen, + use->rpu_keeplen); + /*(*/ + printf(")"); + } + } + + return; + +trunc: + fputs("[|icmp6]", stdout); +} + +#endif /* INET6 */ diff --git a/print-igmp.c b/print-igmp.c new file mode 100644 index 0000000..a848562 --- /dev/null +++ b/print-igmp.c @@ -0,0 +1,336 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-igmp.c,v 1.15 2004-03-24 00:59:16 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +#ifndef IN_CLASSD +#define IN_CLASSD(i) (((int32_t)(i) & 0xf0000000) == 0xe0000000) +#endif + +/* (following from ipmulti/mrouted/prune.h) */ + +/* + * The packet format for a traceroute request. + */ +struct tr_query { + u_int32_t tr_src; /* traceroute source */ + u_int32_t tr_dst; /* traceroute destination */ + u_int32_t tr_raddr; /* traceroute response address */ + u_int32_t tr_rttlqid; /* response ttl and qid */ +}; + +#define TR_GETTTL(x) (int)(((x) >> 24) & 0xff) +#define TR_GETQID(x) ((x) & 0x00ffffff) + +/* + * Traceroute response format. A traceroute response has a tr_query at the + * beginning, followed by one tr_resp for each hop taken. + */ +struct tr_resp { + u_int32_t tr_qarr; /* query arrival time */ + u_int32_t tr_inaddr; /* incoming interface address */ + u_int32_t tr_outaddr; /* outgoing interface address */ + u_int32_t tr_rmtaddr; /* parent address in source tree */ + u_int32_t tr_vifin; /* input packet count on interface */ + u_int32_t tr_vifout; /* output packet count on interface */ + u_int32_t tr_pktcnt; /* total incoming packets for src-grp */ + u_int8_t tr_rproto; /* routing proto deployed on router */ + u_int8_t tr_fttl; /* ttl required to forward on outvif */ + u_int8_t tr_smask; /* subnet mask for src addr */ + u_int8_t tr_rflags; /* forwarding error codes */ +}; + +/* defs within mtrace */ +#define TR_QUERY 1 +#define TR_RESP 2 + +/* fields for tr_rflags (forwarding error codes) */ +#define TR_NO_ERR 0 +#define TR_WRONG_IF 1 +#define TR_PRUNED 2 +#define TR_OPRUNED 3 +#define TR_SCOPED 4 +#define TR_NO_RTE 5 +#define TR_NO_FWD 7 +#define TR_NO_SPACE 0x81 +#define TR_OLD_ROUTER 0x82 + +/* fields for tr_rproto (routing protocol) */ +#define TR_PROTO_DVMRP 1 +#define TR_PROTO_MOSPF 2 +#define TR_PROTO_PIM 3 +#define TR_PROTO_CBT 4 + +/* igmpv3 report types */ +static struct tok igmpv3report2str[] = { + { 1, "is_in" }, + { 2, "is_ex" }, + { 3, "to_in" }, + { 4, "to_ex" }, + { 5, "allow" }, + { 6, "block" }, + { 0, NULL } +}; + +static void +print_mtrace(register const u_char *bp, register u_int len) +{ + register const struct tr_query *tr = (const struct tr_query *)(bp + 8); + + TCHECK(*tr); + if (len < 8 + sizeof (struct tr_query)) { + (void)printf(" [invalid len %d]", len); + return; + } + printf("mtrace %u: %s to %s reply-to %s", + TR_GETQID(EXTRACT_32BITS(&tr->tr_rttlqid)), + ipaddr_string(&tr->tr_src), ipaddr_string(&tr->tr_dst), + ipaddr_string(&tr->tr_raddr)); + if (IN_CLASSD(EXTRACT_32BITS(&tr->tr_raddr))) + printf(" with-ttl %d", TR_GETTTL(EXTRACT_32BITS(&tr->tr_rttlqid))); + return; +trunc: + (void)printf("[|igmp]"); + return; +} + +static void +print_mresp(register const u_char *bp, register u_int len) +{ + register const struct tr_query *tr = (const struct tr_query *)(bp + 8); + + TCHECK(*tr); + if (len < 8 + sizeof (struct tr_query)) { + (void)printf(" [invalid len %d]", len); + return; + } + printf("mresp %lu: %s to %s reply-to %s", + (u_long)TR_GETQID(EXTRACT_32BITS(&tr->tr_rttlqid)), + ipaddr_string(&tr->tr_src), ipaddr_string(&tr->tr_dst), + ipaddr_string(&tr->tr_raddr)); + if (IN_CLASSD(EXTRACT_32BITS(&tr->tr_raddr))) + printf(" with-ttl %d", TR_GETTTL(EXTRACT_32BITS(&tr->tr_rttlqid))); + return; +trunc: + (void)printf("[|igmp]"); + return; +} + +static void +print_igmpv3_report(register const u_char *bp, register u_int len) +{ + u_int group, nsrcs, ngroups; + register u_int i, j; + + /* Minimum len is 16, and should be a multiple of 4 */ + if (len < 16 || len & 0x03) { + (void)printf(" [invalid len %d]", len); + return; + } + TCHECK2(bp[6], 2); + ngroups = EXTRACT_16BITS(&bp[6]); + (void)printf(", %d group record(s)", ngroups); + if (vflag > 0) { + /* Print the group records */ + group = 8; + for (i=0; i> 4) + 3); + } + if (mrc != 100) { + (void)printf(" [max resp time "); + relts_print(mrt); + (void)printf("]"); + } + TCHECK2(bp[4], 4); + if (EXTRACT_32BITS(&bp[4]) == 0) + return; + (void)printf(" [gaddr %s", ipaddr_string(&bp[4])); + TCHECK2(bp[10], 2); + nsrcs = EXTRACT_16BITS(&bp[10]); + if (nsrcs > 0) { + if (len < 12 + (nsrcs << 2)) + (void)printf(" [invalid number of sources]"); + else if (vflag > 1) { + (void)printf(" {"); + for (i=0; i= 12) + print_igmpv3_query(bp, len); + else { + TCHECK(bp[1]); + if (bp[1]) { + (void)printf(" v2"); + if (bp[1] != 100) + (void)printf(" [max resp time %d]", bp[1]); + } else + (void)printf(" v1"); + TCHECK2(bp[4], 4); + if (EXTRACT_32BITS(&bp[4])) + (void)printf(" [gaddr %s]", ipaddr_string(&bp[4])); + if (len != 8) + (void)printf(" [len %d]", len); + } + break; + case 0x12: + TCHECK2(bp[4], 4); + (void)printf("igmp v1 report %s", ipaddr_string(&bp[4])); + if (len != 8) + (void)printf(" [len %d]", len); + break; + case 0x16: + TCHECK2(bp[4], 4); + (void)printf("igmp v2 report %s", ipaddr_string(&bp[4])); + break; + case 0x22: + (void)printf("igmp v3 report"); + print_igmpv3_report(bp, len); + break; + case 0x17: + TCHECK2(bp[4], 4); + (void)printf("igmp leave %s", ipaddr_string(&bp[4])); + break; + case 0x13: + (void)printf("igmp dvmrp"); + if (len < 8) + (void)printf(" [len %d]", len); + else + dvmrp_print(bp, len); + break; + case 0x14: + (void)printf("igmp pimv1"); + pimv1_print(bp, len); + break; + case 0x1e: + print_mresp(bp, len); + break; + case 0x1f: + print_mtrace(bp, len); + break; + default: + (void)printf("igmp-%d", bp[0]); + break; + } + + if (vflag && TTEST2(bp[0], len)) { + /* Check the IGMP checksum */ + if (in_cksum((const u_short*)bp, len, 0)) + printf(" bad igmp cksum %x!", EXTRACT_16BITS(&bp[2])); + } + return; +trunc: + fputs("[|igmp]", stdout); +} diff --git a/print-igrp.c b/print-igrp.c new file mode 100644 index 0000000..3cede7e --- /dev/null +++ b/print-igrp.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Initial contribution from Francis Dupont (francis.dupont@inria.fr) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-igrp.c,v 1.21 2005-04-20 21:01:56 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "interface.h" +#include "addrtoname.h" +#include "igrp.h" +#include "ip.h" +#include "extract.h" /* must come after interface.h */ + +static void +igrp_entry_print(register struct igrprte *igr, register int is_interior, + register int is_exterior) +{ + register u_int delay, bandwidth; + u_int metric, mtu; + + if (is_interior) + printf(" *.%d.%d.%d", igr->igr_net[0], + igr->igr_net[1], igr->igr_net[2]); + else if (is_exterior) + printf(" X%d.%d.%d.0", igr->igr_net[0], + igr->igr_net[1], igr->igr_net[2]); + else + printf(" %d.%d.%d.0", igr->igr_net[0], + igr->igr_net[1], igr->igr_net[2]); + + delay = EXTRACT_24BITS(igr->igr_dly); + bandwidth = EXTRACT_24BITS(igr->igr_bw); + metric = bandwidth + delay; + if (metric > 0xffffff) + metric = 0xffffff; + mtu = EXTRACT_16BITS(igr->igr_mtu); + + printf(" d=%d b=%d r=%d l=%d M=%d mtu=%d in %d hops", + 10 * delay, bandwidth == 0 ? 0 : 10000000 / bandwidth, + igr->igr_rel, igr->igr_ld, metric, + mtu, igr->igr_hct); +} + +static struct tok op2str[] = { + { IGRP_UPDATE, "update" }, + { IGRP_REQUEST, "request" }, + { 0, NULL } +}; + +void +igrp_print(register const u_char *bp, u_int length, const u_char *bp2 _U_) +{ + register struct igrphdr *hdr; + register u_char *cp; + u_int nint, nsys, next; + + hdr = (struct igrphdr *)bp; + cp = (u_char *)(hdr + 1); + (void)printf("igrp:"); + + /* Header */ + TCHECK(*hdr); + nint = EXTRACT_16BITS(&hdr->ig_ni); + nsys = EXTRACT_16BITS(&hdr->ig_ns); + next = EXTRACT_16BITS(&hdr->ig_nx); + + (void)printf(" %s V%d edit=%d AS=%d (%d/%d/%d)", + tok2str(op2str, "op-#%d", IGRP_OP(hdr->ig_vop)), + IGRP_V(hdr->ig_vop), + hdr->ig_ed, + EXTRACT_16BITS(&hdr->ig_as), + nint, + nsys, + next); + + length -= sizeof(*hdr); + while (length >= IGRP_RTE_SIZE) { + if (nint > 0) { + TCHECK2(*cp, IGRP_RTE_SIZE); + igrp_entry_print((struct igrprte *)cp, 1, 0); + --nint; + } else if (nsys > 0) { + TCHECK2(*cp, IGRP_RTE_SIZE); + igrp_entry_print((struct igrprte *)cp, 0, 0); + --nsys; + } else if (next > 0) { + TCHECK2(*cp, IGRP_RTE_SIZE); + igrp_entry_print((struct igrprte *)cp, 0, 1); + --next; + } else { + (void)printf(" [extra bytes %d]", length); + break; + } + cp += IGRP_RTE_SIZE; + length -= IGRP_RTE_SIZE; + } + if (nint == 0 && nsys == 0 && next == 0) + return; +trunc: + fputs(" [|igrp]", stdout); +} diff --git a/print-ip.c b/print-ip.c new file mode 100644 index 0000000..acf3bd8 --- /dev/null +++ b/print-ip.c @@ -0,0 +1,741 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.159 2007-09-14 01:29:28 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "addrtoname.h" +#include "interface.h" +#include "extract.h" /* must come after interface.h */ + +#include "ip.h" +#include "ipproto.h" + +struct tok ip_option_values[] = { + { IPOPT_EOL, "EOL" }, + { IPOPT_NOP, "NOP" }, + { IPOPT_TS, "timestamp" }, + { IPOPT_SECURITY, "security" }, + { IPOPT_RR, "RR" }, + { IPOPT_SSRR, "SSRR" }, + { IPOPT_LSRR, "LSRR" }, + { IPOPT_RA, "RA" }, + { IPOPT_RFC1393, "traceroute" }, + { 0, NULL } +}; + +/* + * print the recorded route in an IP RR, LSRR or SSRR option. + */ +static void +ip_printroute(register const u_char *cp, u_int length) +{ + register u_int ptr; + register u_int len; + + if (length < 3) { + printf(" [bad length %u]", length); + return; + } + if ((length + 1) & 3) + printf(" [bad length %u]", length); + ptr = cp[2] - 1; + if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1) + printf(" [bad ptr %u]", cp[2]); + + for (len = 3; len < length; len += 4) { + printf(" %s", ipaddr_string(&cp[len])); + if (ptr > len) + printf(","); + } +} + +/* + * If source-routing is present and valid, return the final destination. + * Otherwise, return IP destination. + * + * This is used for UDP and TCP pseudo-header in the checksum + * calculation. + */ +u_int32_t +ip_finddst(const struct ip *ip) +{ + int length; + int len; + const u_char *cp; + u_int32_t retval; + + cp = (const u_char *)(ip + 1); + length = (IP_HL(ip) << 2) - sizeof(struct ip); + + for (; length > 0; cp += len, length -= len) { + int tt; + + TCHECK(*cp); + tt = *cp; + if (tt == IPOPT_EOL) + break; + else if (tt == IPOPT_NOP) + len = 1; + else { + TCHECK(cp[1]); + len = cp[1]; + if (len < 2) + break; + } + TCHECK2(*cp, len); + switch (tt) { + + case IPOPT_SSRR: + case IPOPT_LSRR: + if (len < 7) + break; + memcpy(&retval, cp + len - 4, 4); + return retval; + } + } +trunc: + memcpy(&retval, &ip->ip_dst.s_addr, sizeof(u_int32_t)); + return retval; +} + +static void +ip_printts(register const u_char *cp, u_int length) +{ + register u_int ptr; + register u_int len; + int hoplen; + const char *type; + + if (length < 4) { + printf("[bad length %u]", length); + return; + } + printf(" TS{"); + hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4; + if ((length - 4) & (hoplen-1)) + printf("[bad length %u]", length); + ptr = cp[2] - 1; + len = 0; + if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1) + printf("[bad ptr %u]", cp[2]); + switch (cp[3]&0xF) { + case IPOPT_TS_TSONLY: + printf("TSONLY"); + break; + case IPOPT_TS_TSANDADDR: + printf("TS+ADDR"); + break; + /* + * prespecified should really be 3, but some ones might send 2 + * instead, and the IPOPT_TS_PRESPEC constant can apparently + * have both values, so we have to hard-code it here. + */ + + case 2: + printf("PRESPEC2.0"); + break; + case 3: /* IPOPT_TS_PRESPEC */ + printf("PRESPEC"); + break; + default: + printf("[bad ts type %d]", cp[3]&0xF); + goto done; + } + + type = " "; + for (len = 4; len < length; len += hoplen) { + if (ptr == len) + type = " ^ "; + printf("%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]), + hoplen!=8 ? "" : ipaddr_string(&cp[len])); + type = " "; + } + +done: + printf("%s", ptr == len ? " ^ " : ""); + + if (cp[3]>>4) + printf(" [%d hops not recorded]} ", cp[3]>>4); + else + printf("}"); +} + +/* + * print IP options. + */ +static void +ip_optprint(register const u_char *cp, u_int length) +{ + register u_int option_len; + const char *sep = ""; + + for (; length > 0; cp += option_len, length -= option_len) { + u_int option_code; + + printf("%s", sep); + sep = ","; + + TCHECK(*cp); + option_code = *cp; + + printf("%s", + tok2str(ip_option_values,"unknown %u",option_code)); + + if (option_code == IPOPT_NOP || + option_code == IPOPT_EOL) + option_len = 1; + + else { + TCHECK(cp[1]); + option_len = cp[1]; + if (option_len < 2) { + printf(" [bad length %u]", option_len); + return; + } + } + + if (option_len > length) { + printf(" [bad length %u]", option_len); + return; + } + + TCHECK2(*cp, option_len); + + switch (option_code) { + case IPOPT_EOL: + return; + + case IPOPT_TS: + ip_printts(cp, option_len); + break; + + case IPOPT_RR: /* fall through */ + case IPOPT_SSRR: + case IPOPT_LSRR: + ip_printroute(cp, option_len); + break; + + case IPOPT_RA: + if (option_len < 4) { + printf(" [bad length %u]", option_len); + break; + } + TCHECK(cp[3]); + if (EXTRACT_16BITS(&cp[2]) != 0) + printf(" value %u", EXTRACT_16BITS(&cp[2])); + break; + + case IPOPT_NOP: /* nothing to print - fall through */ + case IPOPT_SECURITY: + default: + break; + } + } + return; + +trunc: + printf("[|ip]"); +} + +/* + * compute an IP header checksum. + * don't modifiy the packet. + */ +u_short +in_cksum(const u_short *addr, register u_int len, int csum) +{ + int nleft = len; + const u_short *w = addr; + u_short answer; + int sum = csum; + + /* + * Our algorithm is simple, using a 32 bit accumulator (sum), + * we add sequential 16 bit words to it, and at the end, fold + * back all the carry bits from the top 16 bits into the lower + * 16 bits. + */ + while (nleft > 1) { + sum += *w++; + nleft -= 2; + } + if (nleft == 1) + sum += htons(*(u_char *)w<<8); + + /* + * add back carry outs from top 16 bits to low 16 bits + */ + sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ + sum += (sum >> 16); /* add carry */ + answer = ~sum; /* truncate to 16 bits */ + return (answer); +} + +/* + * Given the host-byte-order value of the checksum field in a packet + * header, and the network-byte-order computed checksum of the data + * that the checksum covers (including the checksum itself), compute + * what the checksum field *should* have been. + */ +u_int16_t +in_cksum_shouldbe(u_int16_t sum, u_int16_t computed_sum) +{ + u_int32_t shouldbe; + + /* + * The value that should have gone into the checksum field + * is the negative of the value gotten by summing up everything + * *but* the checksum field. + * + * We can compute that by subtracting the value of the checksum + * field from the sum of all the data in the packet, and then + * computing the negative of that value. + * + * "sum" is the value of the checksum field, and "computed_sum" + * is the negative of the sum of all the data in the packets, + * so that's -(-computed_sum - sum), or (sum + computed_sum). + * + * All the arithmetic in question is one's complement, so the + * addition must include an end-around carry; we do this by + * doing the arithmetic in 32 bits (with no sign-extension), + * and then adding the upper 16 bits of the sum, which contain + * the carry, to the lower 16 bits of the sum, and then do it + * again in case *that* sum produced a carry. + * + * As RFC 1071 notes, the checksum can be computed without + * byte-swapping the 16-bit words; summing 16-bit words + * on a big-endian machine gives a big-endian checksum, which + * can be directly stuffed into the big-endian checksum fields + * in protocol headers, and summing words on a little-endian + * machine gives a little-endian checksum, which must be + * byte-swapped before being stuffed into a big-endian checksum + * field. + * + * "computed_sum" is a network-byte-order value, so we must put + * it in host byte order before subtracting it from the + * host-byte-order value from the header; the adjusted checksum + * will be in host byte order, which is what we'll return. + */ + shouldbe = sum; + shouldbe += ntohs(computed_sum); + shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); + shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); + return shouldbe; +} + +#define IP_RES 0x8000 + +static struct tok ip_frag_values[] = { + { IP_MF, "+" }, + { IP_DF, "DF" }, + { IP_RES, "rsvd" }, /* The RFC3514 evil ;-) bit */ + { 0, NULL } +}; + +struct ip_print_demux_state { + const struct ip *ip; + const u_char *cp; + u_int len, off; + u_char nh; + int advance; +}; + +static void +ip_print_demux(netdissect_options *ndo, + struct ip_print_demux_state *ipds) +{ + struct protoent *proto; + +again: + switch (ipds->nh) { + + case IPPROTO_AH: + ipds->nh = *ipds->cp; + ipds->advance = ah_print(ipds->cp); + if (ipds->advance <= 0) + break; + ipds->cp += ipds->advance; + ipds->len -= ipds->advance; + goto again; + + case IPPROTO_ESP: + { + int enh, padlen; + ipds->advance = esp_print(ndo, ipds->cp, ipds->len, + (const u_char *)ipds->ip, + &enh, &padlen); + if (ipds->advance <= 0) + break; + ipds->cp += ipds->advance; + ipds->len -= ipds->advance + padlen; + ipds->nh = enh & 0xff; + goto again; + } + + case IPPROTO_IPCOMP: + { + int enh; + ipds->advance = ipcomp_print(ipds->cp, &enh); + if (ipds->advance <= 0) + break; + ipds->cp += ipds->advance; + ipds->len -= ipds->advance; + ipds->nh = enh & 0xff; + goto again; + } + + case IPPROTO_SCTP: + sctp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len); + break; + + case IPPROTO_DCCP: + dccp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len); + break; + + case IPPROTO_TCP: + /* pass on the MF bit plus the offset to detect fragments */ + tcp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip, + ipds->off & (IP_MF|IP_OFFMASK)); + break; + + case IPPROTO_UDP: + /* pass on the MF bit plus the offset to detect fragments */ + udp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip, + ipds->off & (IP_MF|IP_OFFMASK)); + break; + + case IPPROTO_ICMP: + /* pass on the MF bit plus the offset to detect fragments */ + icmp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip, + ipds->off & (IP_MF|IP_OFFMASK)); + break; + + case IPPROTO_PIGP: + /* + * XXX - the current IANA protocol number assignments + * page lists 9 as "any private interior gateway + * (used by Cisco for their IGRP)" and 88 as + * "EIGRP" from Cisco. + * + * Recent BSD headers define + * IP_PROTO_PIGP as 9 and IP_PROTO_IGRP as 88. + * We define IP_PROTO_PIGP as 9 and + * IP_PROTO_EIGRP as 88; those names better + * match was the current protocol number + * assignments say. + */ + igrp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip); + break; + + case IPPROTO_EIGRP: + eigrp_print(ipds->cp, ipds->len); + break; + + case IPPROTO_ND: + ND_PRINT((ndo, " nd %d", ipds->len)); + break; + + case IPPROTO_EGP: + egp_print(ipds->cp, ipds->len); + break; + + case IPPROTO_OSPF: + ospf_print(ipds->cp, ipds->len, (const u_char *)ipds->ip); + break; + + case IPPROTO_IGMP: + igmp_print(ipds->cp, ipds->len); + break; + + case IPPROTO_IPV4: + /* DVMRP multicast tunnel (ip-in-ip encapsulation) */ + ip_print(gndo, ipds->cp, ipds->len); + if (! vflag) { + ND_PRINT((ndo, " (ipip-proto-4)")); + return; + } + break; + +#ifdef INET6 + case IPPROTO_IPV6: + /* ip6-in-ip encapsulation */ + ip6_print(ipds->cp, ipds->len); + break; +#endif /*INET6*/ + + case IPPROTO_RSVP: + rsvp_print(ipds->cp, ipds->len); + break; + + case IPPROTO_GRE: + /* do it */ + gre_print(ipds->cp, ipds->len); + break; + + case IPPROTO_MOBILE: + mobile_print(ipds->cp, ipds->len); + break; + + case IPPROTO_PIM: + pim_print(ipds->cp, ipds->len, + in_cksum((const u_short*)ipds->cp, ipds->len, 0)); + break; + + case IPPROTO_VRRP: + vrrp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl); + break; + + case IPPROTO_PGM: + pgm_print(ipds->cp, ipds->len, (const u_char *)ipds->ip); + break; + + default: + if ((proto = getprotobynumber(ipds->nh)) != NULL) + ND_PRINT((ndo, " %s", proto->p_name)); + else + ND_PRINT((ndo, " ip-proto-%d", ipds->nh)); + ND_PRINT((ndo, " %d", ipds->len)); + break; + } +} + +void +ip_print_inner(netdissect_options *ndo, + const u_char *bp, + u_int length, u_int nh, + const u_char *bp2) +{ + struct ip_print_demux_state ipd; + + ipd.ip = (const struct ip *)bp2; + ipd.cp = bp; + ipd.len = length; + ipd.off = 0; + ipd.nh = nh; + ipd.advance = 0; + + ip_print_demux(ndo, &ipd); +} + + +/* + * print an IP datagram. + */ +void +ip_print(netdissect_options *ndo, + const u_char *bp, + u_int length) +{ + struct ip_print_demux_state ipd; + struct ip_print_demux_state *ipds=&ipd; + const u_char *ipend; + u_int hlen; + u_int16_t sum, ip_sum; + struct protoent *proto; + + ipds->ip = (const struct ip *)bp; + if (IP_V(ipds->ip) != 4) { /* print version if != 4 */ + printf("IP%u ", IP_V(ipds->ip)); + if (IP_V(ipds->ip) == 6) + printf(", wrong link-layer encapsulation"); + } + else if (!eflag) + printf("IP "); + + if ((u_char *)(ipds->ip + 1) > snapend) { + printf("[|ip]"); + return; + } + if (length < sizeof (struct ip)) { + (void)printf("truncated-ip %u", length); + return; + } + hlen = IP_HL(ipds->ip) * 4; + if (hlen < sizeof (struct ip)) { + (void)printf("bad-hlen %u", hlen); + return; + } + + ipds->len = EXTRACT_16BITS(&ipds->ip->ip_len); + if (length < ipds->len) + (void)printf("truncated-ip - %u bytes missing! ", + ipds->len - length); + if (ipds->len < hlen) { +#ifdef GUESS_TSO + if (ipds->len) { + (void)printf("bad-len %u", ipds->len); + return; + } + else { + /* we guess that it is a TSO send */ + ipds->len = length; + } +#else + (void)printf("bad-len %u", ipds->len); + return; +#endif /* GUESS_TSO */ + } + + /* + * Cut off the snapshot length to the end of the IP payload. + */ + ipend = bp + ipds->len; + if (ipend < snapend) + snapend = ipend; + + ipds->len -= hlen; + + ipds->off = EXTRACT_16BITS(&ipds->ip->ip_off); + + if (vflag) { + (void)printf("(tos 0x%x", (int)ipds->ip->ip_tos); + /* ECN bits */ + if (ipds->ip->ip_tos & 0x03) { + switch (ipds->ip->ip_tos & 0x03) { + case 1: + (void)printf(",ECT(1)"); + break; + case 2: + (void)printf(",ECT(0)"); + break; + case 3: + (void)printf(",CE"); + } + } + + if (ipds->ip->ip_ttl >= 1) + (void)printf(", ttl %u", ipds->ip->ip_ttl); + + /* + * for the firewall guys, print id, offset. + * On all but the last stick a "+" in the flags portion. + * For unfragmented datagrams, note the don't fragment flag. + */ + + (void)printf(", id %u, offset %u, flags [%s], proto %s (%u)", + EXTRACT_16BITS(&ipds->ip->ip_id), + (ipds->off & 0x1fff) * 8, + bittok2str(ip_frag_values, "none", ipds->off&0xe000), + tok2str(ipproto_values,"unknown",ipds->ip->ip_p), + ipds->ip->ip_p); + + (void)printf(", length %u", EXTRACT_16BITS(&ipds->ip->ip_len)); + + if ((hlen - sizeof(struct ip)) > 0) { + printf(", options ("); + ip_optprint((u_char *)(ipds->ip + 1), hlen - sizeof(struct ip)); + printf(")"); + } + + if (!Kflag && (u_char *)ipds->ip + hlen <= snapend) { + sum = in_cksum((const u_short *)ipds->ip, hlen, 0); + if (sum != 0) { + ip_sum = EXTRACT_16BITS(&ipds->ip->ip_sum); + (void)printf(", bad cksum %x (->%x)!", ip_sum, + in_cksum_shouldbe(ip_sum, sum)); + } + } + + printf(")\n "); + } + + /* + * If this is fragment zero, hand it to the next higher + * level protocol. + */ + if ((ipds->off & 0x1fff) == 0) { + ipds->cp = (const u_char *)ipds->ip + hlen; + ipds->nh = ipds->ip->ip_p; + + if (ipds->nh != IPPROTO_TCP && ipds->nh != IPPROTO_UDP && + ipds->nh != IPPROTO_SCTP && ipds->nh != IPPROTO_DCCP) { + (void)printf("%s > %s: ", + ipaddr_string(&ipds->ip->ip_src), + ipaddr_string(&ipds->ip->ip_dst)); + } + ip_print_demux(ndo, ipds); + } else { + /* Ultra quiet now means that all this stuff should be suppressed */ + if (qflag > 1) return; + + /* + * if this isn't the first frag, we're missing the + * next level protocol header. print the ip addr + * and the protocol. + */ + if (ipds->off & 0x1fff) { + (void)printf("%s > %s:", ipaddr_string(&ipds->ip->ip_src), + ipaddr_string(&ipds->ip->ip_dst)); + if ((proto = getprotobynumber(ipds->ip->ip_p)) != NULL) + (void)printf(" %s", proto->p_name); + else + (void)printf(" ip-proto-%d", ipds->ip->ip_p); + } + } +} + +void +ipN_print(register const u_char *bp, register u_int length) +{ + struct ip *ip, hdr; + + ip = (struct ip *)bp; + if (length < 4) { + (void)printf("truncated-ip %d", length); + return; + } + memcpy (&hdr, (char *)ip, 4); + switch (IP_V(&hdr)) { + case 4: + ip_print (gndo, bp, length); + return; +#ifdef INET6 + case 6: + ip6_print (bp, length); + return; +#endif + default: + (void)printf("unknown ip %d", IP_V(&hdr)); + return; + } +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ + + diff --git a/print-ip6.c b/print-ip6.c new file mode 100644 index 0000000..1599cf2 --- /dev/null +++ b/print-ip6.c @@ -0,0 +1,265 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.52 2007-09-21 07:05:33 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef INET6 + +#include + +#include +#include +#include + +#include "netdissect.h" +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "ip6.h" +#include "ipproto.h" + +/* + * Compute a V6-style checksum by building a pseudoheader. + */ +int +nextproto6_cksum(const struct ip6_hdr *ip6, const u_short *data, + u_int len, u_int next_proto) +{ + size_t i; + u_int32_t sum = 0; + union ip6_pseudo_hdr phu; + + /* pseudo-header */ + memset(&phu, 0, sizeof(phu)); + phu.ph.ph_src = ip6->ip6_src; + phu.ph.ph_dst = ip6->ip6_dst; + phu.ph.ph_len = htonl(len); + phu.ph.ph_nxt = next_proto; + + for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) { + sum += phu.pa[i]; + } + + return in_cksum(data, len, sum); +} + +/* + * print an IP6 datagram. + */ +void +ip6_print(register const u_char *bp, register u_int length) +{ + register const struct ip6_hdr *ip6; + register int advance; + u_int len; + const u_char *ipend; + register const u_char *cp; + register u_int payload_len; + int nh; + int fragmented = 0; + u_int flow; + + ip6 = (const struct ip6_hdr *)bp; + + TCHECK(*ip6); + if (length < sizeof (struct ip6_hdr)) { + (void)printf("truncated-ip6 %u", length); + return; + } + + if (!eflag) + printf("IP6 "); + + payload_len = EXTRACT_16BITS(&ip6->ip6_plen); + len = payload_len + sizeof(struct ip6_hdr); + if (length < len) + (void)printf("truncated-ip6 - %u bytes missing!", + len - length); + + if (vflag) { + flow = EXTRACT_32BITS(&ip6->ip6_flow); + printf("("); +#if 0 + /* rfc1883 */ + if (flow & 0x0f000000) + (void)printf("pri 0x%02x, ", (flow & 0x0f000000) >> 24); + if (flow & 0x00ffffff) + (void)printf("flowlabel 0x%06x, ", flow & 0x00ffffff); +#else + /* RFC 2460 */ + if (flow & 0x0ff00000) + (void)printf("class 0x%02x, ", (flow & 0x0ff00000) >> 20); + if (flow & 0x000fffff) + (void)printf("flowlabel 0x%05x, ", flow & 0x000fffff); +#endif + + (void)printf("hlim %u, next-header %s (%u) payload length: %u) ", + ip6->ip6_hlim, + tok2str(ipproto_values,"unknown",ip6->ip6_nxt), + ip6->ip6_nxt, + payload_len); + } + + /* + * Cut off the snapshot length to the end of the IP payload. + */ + ipend = bp + len; + if (ipend < snapend) + snapend = ipend; + + cp = (const u_char *)ip6; + advance = sizeof(struct ip6_hdr); + nh = ip6->ip6_nxt; + while (cp < snapend && advance > 0) { + cp += advance; + len -= advance; + + if (cp == (const u_char *)(ip6 + 1) && + nh != IPPROTO_TCP && nh != IPPROTO_UDP && + nh != IPPROTO_DCCP && nh != IPPROTO_SCTP) { + (void)printf("%s > %s: ", ip6addr_string(&ip6->ip6_src), + ip6addr_string(&ip6->ip6_dst)); + } + + switch (nh) { + case IPPROTO_HOPOPTS: + advance = hbhopt_print(cp); + nh = *cp; + break; + case IPPROTO_DSTOPTS: + advance = dstopt_print(cp); + nh = *cp; + break; + case IPPROTO_FRAGMENT: + advance = frag6_print(cp, (const u_char *)ip6); + if (snapend <= cp + advance) + return; + nh = *cp; + fragmented = 1; + break; + + case IPPROTO_MOBILITY_OLD: + case IPPROTO_MOBILITY: + /* + * XXX - we don't use "advance"; the current + * "Mobility Support in IPv6" draft + * (draft-ietf-mobileip-ipv6-24) says that + * the next header field in a mobility header + * should be IPPROTO_NONE, but speaks of + * the possiblity of a future extension in + * which payload can be piggybacked atop a + * mobility header. + */ + advance = mobility_print(cp, (const u_char *)ip6); + nh = *cp; + return; + case IPPROTO_ROUTING: + advance = rt6_print(cp, (const u_char *)ip6); + nh = *cp; + break; + case IPPROTO_SCTP: + sctp_print(cp, (const u_char *)ip6, len); + return; + case IPPROTO_DCCP: + dccp_print(cp, (const u_char *)ip6, len); + return; + case IPPROTO_TCP: + tcp_print(cp, len, (const u_char *)ip6, fragmented); + return; + case IPPROTO_UDP: + udp_print(cp, len, (const u_char *)ip6, fragmented); + return; + case IPPROTO_ICMPV6: + icmp6_print(gndo, cp, len, (const u_char *)ip6, fragmented); + return; + case IPPROTO_AH: + advance = ah_print(cp); + nh = *cp; + break; + case IPPROTO_ESP: + { + int enh, padlen; + advance = esp_print(gndo, cp, len, (const u_char *)ip6, &enh, &padlen); + nh = enh & 0xff; + len -= padlen; + break; + } + case IPPROTO_IPCOMP: + { + int enh; + advance = ipcomp_print(cp, &enh); + nh = enh & 0xff; + break; + } + + case IPPROTO_PIM: + pim_print(cp, len, nextproto6_cksum(ip6, (u_short *)cp, len, + IPPROTO_PIM)); + return; + + case IPPROTO_OSPF: + ospf6_print(cp, len); + return; + + case IPPROTO_IPV6: + ip6_print(cp, len); + return; + + case IPPROTO_IPV4: + ip_print(gndo, cp, len); + return; + + case IPPROTO_PGM: + pgm_print(cp, len, (const u_char *)ip6); + return; + + case IPPROTO_GRE: + gre_print(cp, len); + return; + + case IPPROTO_RSVP: + rsvp_print(cp, len); + return; + + case IPPROTO_NONE: + (void)printf("no next header"); + return; + + default: + (void)printf("ip-proto-%d %d", nh, len); + return; + } + } + + return; +trunc: + (void)printf("[|ip6]"); +} + +#endif /* INET6 */ diff --git a/print-ip6opts.c b/print-ip6opts.c new file mode 100644 index 0000000..7a4bf55 --- /dev/null +++ b/print-ip6opts.c @@ -0,0 +1,329 @@ +/* + * Copyright (C) 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ip6opts.c,v 1.18 2005-04-20 22:18:50 guy Exp $"; +#endif + +#ifdef INET6 +#include + +#include + +#include "ip6.h" + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +/* items outside of rfc2292bis */ +#ifndef IP6OPT_MINLEN +#define IP6OPT_MINLEN 2 +#endif +#ifndef IP6OPT_RTALERT_LEN +#define IP6OPT_RTALERT_LEN 4 +#endif +#ifndef IP6OPT_JUMBO_LEN +#define IP6OPT_JUMBO_LEN 6 +#endif +#define IP6OPT_HOMEADDR_MINLEN 18 +#define IP6OPT_BU_MINLEN 10 +#define IP6OPT_BA_MINLEN 13 +#define IP6OPT_BR_MINLEN 2 +#define IP6SOPT_UI 0x2 +#define IP6SOPT_UI_MINLEN 4 +#define IP6SOPT_ALTCOA 0x3 +#define IP6SOPT_ALTCOA_MINLEN 18 +#define IP6SOPT_AUTH 0x4 +#define IP6SOPT_AUTH_MINLEN 6 + +static void ip6_sopt_print(const u_char *, int); + +static void +ip6_sopt_print(const u_char *bp, int len) +{ + int i; + int optlen; + + for (i = 0; i < len; i += optlen) { + if (bp[i] == IP6OPT_PAD1) + optlen = 1; + else { + if (i + 1 < len) + optlen = bp[i + 1] + 2; + else + goto trunc; + } + if (i + optlen > len) + goto trunc; + + switch (bp[i]) { + case IP6OPT_PAD1: + printf(", pad1"); + break; + case IP6OPT_PADN: + if (len - i < IP6OPT_MINLEN) { + printf(", padn: trunc"); + goto trunc; + } + printf(", padn"); + break; + case IP6SOPT_UI: + if (len - i < IP6SOPT_UI_MINLEN) { + printf(", ui: trunc"); + goto trunc; + } + printf(", ui: 0x%04x ", EXTRACT_16BITS(&bp[i + 2])); + break; + case IP6SOPT_ALTCOA: + if (len - i < IP6SOPT_ALTCOA_MINLEN) { + printf(", altcoa: trunc"); + goto trunc; + } + printf(", alt-CoA: %s", ip6addr_string(&bp[i+2])); + break; + case IP6SOPT_AUTH: + if (len - i < IP6SOPT_AUTH_MINLEN) { + printf(", auth: trunc"); + goto trunc; + } + printf(", auth spi: 0x%08x", EXTRACT_32BITS(&bp[i + 2])); + break; + default: + if (len - i < IP6OPT_MINLEN) { + printf(", sopt_type %d: trunc)", bp[i]); + goto trunc; + } + printf(", sopt_type 0x%02x: len=%d", bp[i], bp[i + 1]); + break; + } + } + return; + +trunc: + printf("[trunc] "); +} + +void +ip6_opt_print(const u_char *bp, int len) +{ + int i; + int optlen = 0; + + for (i = 0; i < len; i += optlen) { + if (bp[i] == IP6OPT_PAD1) + optlen = 1; + else { + if (i + 1 < len) + optlen = bp[i + 1] + 2; + else + goto trunc; + } + if (i + optlen > len) + goto trunc; + + switch (bp[i]) { + case IP6OPT_PAD1: + printf("(pad1)"); + break; + case IP6OPT_PADN: + if (len - i < IP6OPT_MINLEN) { + printf("(padn: trunc)"); + goto trunc; + } + printf("(padn)"); + break; + case IP6OPT_ROUTER_ALERT: + if (len - i < IP6OPT_RTALERT_LEN) { + printf("(rtalert: trunc)"); + goto trunc; + } + if (bp[i + 1] != IP6OPT_RTALERT_LEN - 2) { + printf("(rtalert: invalid len %d)", bp[i + 1]); + goto trunc; + } + printf("(rtalert: 0x%04x) ", EXTRACT_16BITS(&bp[i + 2])); + break; + case IP6OPT_JUMBO: + if (len - i < IP6OPT_JUMBO_LEN) { + printf("(jumbo: trunc)"); + goto trunc; + } + if (bp[i + 1] != IP6OPT_JUMBO_LEN - 2) { + printf("(jumbo: invalid len %d)", bp[i + 1]); + goto trunc; + } + printf("(jumbo: %u) ", EXTRACT_32BITS(&bp[i + 2])); + break; + case IP6OPT_HOME_ADDRESS: + if (len - i < IP6OPT_HOMEADDR_MINLEN) { + printf("(homeaddr: trunc)"); + goto trunc; + } + if (bp[i + 1] < IP6OPT_HOMEADDR_MINLEN - 2) { + printf("(homeaddr: invalid len %d)", bp[i + 1]); + goto trunc; + } + printf("(homeaddr: %s", ip6addr_string(&bp[i + 2])); + if (bp[i + 1] > IP6OPT_HOMEADDR_MINLEN - 2) { + ip6_sopt_print(&bp[i + IP6OPT_HOMEADDR_MINLEN], + (optlen - IP6OPT_HOMEADDR_MINLEN)); + } + printf(")"); + break; + case IP6OPT_BINDING_UPDATE: + if (len - i < IP6OPT_BU_MINLEN) { + printf("(bu: trunc)"); + goto trunc; + } + if (bp[i + 1] < IP6OPT_BU_MINLEN - 2) { + printf("(bu: invalid len %d)", bp[i + 1]); + goto trunc; + } + printf("(bu: "); + if (bp[i + 2] & 0x80) + printf("A"); + if (bp[i + 2] & 0x40) + printf("H"); + if (bp[i + 2] & 0x20) + printf("S"); + if (bp[i + 2] & 0x10) + printf("D"); + if ((bp[i + 2] & 0x0f) || bp[i + 3] || bp[i + 4]) + printf("res"); + printf(", sequence: %u", bp[i + 5]); + printf(", lifetime: %u", EXTRACT_32BITS(&bp[i + 6])); + + if (bp[i + 1] > IP6OPT_BU_MINLEN - 2) { + ip6_sopt_print(&bp[i + IP6OPT_BU_MINLEN], + (optlen - IP6OPT_BU_MINLEN)); + } + printf(")"); + break; + case IP6OPT_BINDING_ACK: + if (len - i < IP6OPT_BA_MINLEN) { + printf("(ba: trunc)"); + goto trunc; + } + if (bp[i + 1] < IP6OPT_BA_MINLEN - 2) { + printf("(ba: invalid len %d)", bp[i + 1]); + goto trunc; + } + printf("(ba: "); + printf("status: %u", bp[i + 2]); + if (bp[i + 3]) + printf("res"); + printf(", sequence: %u", bp[i + 4]); + printf(", lifetime: %u", EXTRACT_32BITS(&bp[i + 5])); + printf(", refresh: %u", EXTRACT_32BITS(&bp[i + 9])); + + if (bp[i + 1] > IP6OPT_BA_MINLEN - 2) { + ip6_sopt_print(&bp[i + IP6OPT_BA_MINLEN], + (optlen - IP6OPT_BA_MINLEN)); + } + printf(")"); + break; + case IP6OPT_BINDING_REQ: + if (len - i < IP6OPT_BR_MINLEN) { + printf("(br: trunc)"); + goto trunc; + } + printf("(br"); + if (bp[i + 1] > IP6OPT_BR_MINLEN - 2) { + ip6_sopt_print(&bp[i + IP6OPT_BR_MINLEN], + (optlen - IP6OPT_BR_MINLEN)); + } + printf(")"); + break; + default: + if (len - i < IP6OPT_MINLEN) { + printf("(type %d: trunc)", bp[i]); + goto trunc; + } + printf("(opt_type 0x%02x: len=%d) ", bp[i], bp[i + 1]); + break; + } + } + +#if 0 +end: +#endif + return; + +trunc: + printf("[trunc] "); +} + +int +hbhopt_print(register const u_char *bp) +{ + const struct ip6_hbh *dp = (struct ip6_hbh *)bp; + int hbhlen = 0; + + TCHECK(dp->ip6h_len); + hbhlen = (int)((dp->ip6h_len + 1) << 3); + TCHECK2(*dp, hbhlen); + printf("HBH "); + if (vflag) + ip6_opt_print((const u_char *)dp + sizeof(*dp), hbhlen - sizeof(*dp)); + + return(hbhlen); + + trunc: + fputs("[|HBH]", stdout); + return(-1); +} + +int +dstopt_print(register const u_char *bp) +{ + const struct ip6_dest *dp = (struct ip6_dest *)bp; + int dstoptlen = 0; + + TCHECK(dp->ip6d_len); + dstoptlen = (int)((dp->ip6d_len + 1) << 3); + TCHECK2(*dp, dstoptlen); + printf("DSTOPT "); + if (vflag) { + ip6_opt_print((const u_char *)dp + sizeof(*dp), + dstoptlen - sizeof(*dp)); + } + + return(dstoptlen); + + trunc: + fputs("[|DSTOPT]", stdout); + return(-1); +} +#endif /* INET6 */ diff --git a/print-ipcomp.c b/print-ipcomp.c new file mode 100644 index 0000000..89130a3 --- /dev/null +++ b/print-ipcomp.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ipcomp.c,v 1.20 2003-11-19 00:36:08 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include + +struct ipcomp { + u_int8_t comp_nxt; /* Next Header */ + u_int8_t comp_flags; /* Length of data, in 32bit */ + u_int16_t comp_cpi; /* Compression parameter index */ +}; + +#if defined(HAVE_LIBZ) && defined(HAVE_ZLIB_H) +#include +#endif + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +int +ipcomp_print(register const u_char *bp, int *nhdr _U_) +{ + register const struct ipcomp *ipcomp; + register const u_char *ep; + u_int16_t cpi; +#if defined(HAVE_LIBZ) && defined(HAVE_ZLIB_H) + int advance; +#endif + + ipcomp = (struct ipcomp *)bp; + cpi = EXTRACT_16BITS(&ipcomp->comp_cpi); + + /* 'ep' points to the end of available data. */ + ep = snapend; + + if ((u_char *)(ipcomp + 1) >= ep - sizeof(struct ipcomp)) { + fputs("[|IPCOMP]", stdout); + goto fail; + } + printf("IPComp(cpi=0x%04x)", cpi); + +#if defined(HAVE_LIBZ) && defined(HAVE_ZLIB_H) + if (1) + goto fail; + + /* + * We may want to decompress the packet here. Packet buffer + * management is a headache (if we decompress, packet will become + * larger). + */ + if (nhdr) + *nhdr = ipcomp->comp_nxt; + advance = sizeof(struct ipcomp); + + printf(": "); + return advance; + +#endif +fail: + return -1; +} diff --git a/print-ipfc.c b/print-ipfc.c new file mode 100644 index 0000000..c980765 --- /dev/null +++ b/print-ipfc.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ipfc.c,v 1.9 2005-11-13 12:12:42 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "ethertype.h" + +#include "ether.h" +#include "ipfc.h" + +/* + * RFC 2625 IP-over-Fibre Channel. + */ + +/* Extract src, dst addresses */ +static inline void +extract_ipfc_addrs(const struct ipfc_header *ipfcp, char *ipfcsrc, + char *ipfcdst) +{ + /* + * We assume that, as per RFC 2625, the lower 48 bits of the + * source and destination addresses are MAC addresses. + */ + memcpy(ipfcdst, (const char *)&ipfcp->ipfc_dhost[2], 6); + memcpy(ipfcsrc, (const char *)&ipfcp->ipfc_shost[2], 6); +} + +/* + * Print the Network_Header + */ +static inline void +ipfc_hdr_print(register const struct ipfc_header *ipfcp _U_, + register u_int length, register const u_char *ipfcsrc, + register const u_char *ipfcdst) +{ + const char *srcname, *dstname; + + srcname = etheraddr_string(ipfcsrc); + dstname = etheraddr_string(ipfcdst); + + /* + * XXX - show the upper 16 bits? Do so only if "vflag" is set? + */ + (void) printf("%s %s %d: ", srcname, dstname, length); +} + +static void +ipfc_print(const u_char *p, u_int length, u_int caplen) +{ + const struct ipfc_header *ipfcp = (const struct ipfc_header *)p; + struct ether_header ehdr; + u_short extracted_ethertype; + + if (caplen < IPFC_HDRLEN) { + printf("[|ipfc]"); + return; + } + /* + * Get the network addresses into a canonical form + */ + extract_ipfc_addrs(ipfcp, (char *)ESRC(&ehdr), (char *)EDST(&ehdr)); + + if (eflag) + ipfc_hdr_print(ipfcp, length, ESRC(&ehdr), EDST(&ehdr)); + + /* Skip over Network_Header */ + length -= IPFC_HDRLEN; + p += IPFC_HDRLEN; + caplen -= IPFC_HDRLEN; + + /* Try to print the LLC-layer header & higher layers */ + if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr), + &extracted_ethertype) == 0) { + /* + * Some kinds of LLC packet we cannot + * handle intelligently + */ + if (!eflag) + ipfc_hdr_print(ipfcp, length + IPFC_HDRLEN, + ESRC(&ehdr), EDST(&ehdr)); + if (extracted_ethertype) { + printf("(LLC %s) ", + etherproto_string(htons(extracted_ethertype))); + } + if (!suppress_default_print) + default_print(p, caplen); + } +} + +/* + * This is the top level routine of the printer. 'p' points + * to the Network_Header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +ipfc_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + ipfc_print(p, h->len, h->caplen); + + return (IPFC_HDRLEN); +} diff --git a/print-ipnet.c b/print-ipnet.c new file mode 100644 index 0000000..957bd4f --- /dev/null +++ b/print-ipnet.c @@ -0,0 +1,109 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "netdissect.h" +#include "interface.h" +#include "addrtoname.h" +#include "ipnet.h" + +#ifdef DLT_IPNET + +const struct tok ipnet_values[] = { + { IPH_AF_INET, "IPv4" }, + { IPH_AF_INET6, "IPv6" }, + { 0, NULL } +}; + +static inline void +ipnet_hdr_print(struct netdissect_options *ndo, const u_char *bp, u_int length) +{ + const ipnet_hdr_t *hdr; + hdr = (const ipnet_hdr_t *)bp; + + ND_PRINT((ndo, "%d > %d", hdr->iph_zsrc, hdr->iph_zdst)); + + if (!ndo->ndo_qflag) { + ND_PRINT((ndo,", family %s (%d)", + tok2str(ipnet_values, "Unknown", + hdr->iph_family), + hdr->iph_family)); + } else { + ND_PRINT((ndo,", %s", + tok2str(ipnet_values, + "Unknown Ethertype (0x%04x)", + hdr->iph_family))); + } + + ND_PRINT((ndo, ", length %u: ", length)); +} + +static void +ipnet_print(struct netdissect_options *ndo, const u_char *p, u_int length, u_int caplen) +{ + ipnet_hdr_t *hdr; + + if (caplen < sizeof(ipnet_hdr_t)) { + ND_PRINT((ndo, "[|ipnet]")); + return; + } + + if (ndo->ndo_eflag) + ipnet_hdr_print(ndo, p, length); + + length -= sizeof(ipnet_hdr_t); + caplen -= sizeof(ipnet_hdr_t); + hdr = (ipnet_hdr_t *)p; + p += sizeof(ipnet_hdr_t); + + switch (hdr->iph_family) { + + case IPH_AF_INET: + ip_print(ndo, p, length); + break; + +#ifdef INET6 + case IPH_AF_INET6: + ip6_print(p, length); + break; +#endif /*INET6*/ + + default: + if (!ndo->ndo_eflag) + ipnet_hdr_print(ndo, (u_char *)hdr, + length + sizeof(ipnet_hdr_t)); + + if (!ndo->ndo_suppress_default_print) + ndo->ndo_default_print(ndo, p, caplen); + break; + } +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +ipnet_if_print(struct netdissect_options *ndo, + const struct pcap_pkthdr *h, const u_char *p) +{ + ipnet_print(ndo, p, h->len, h->caplen); + + return (sizeof(ipnet_hdr_t)); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ + +#endif /* DLT_IPNET */ diff --git a/print-ipx.c b/print-ipx.c new file mode 100644 index 0000000..604561c --- /dev/null +++ b/print-ipx.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Format and print Novell IPX packets. + * Contributed by Brad Parker (brad@fcr.com). + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ipx.c,v 1.42 2005-05-06 08:26:44 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "ipx.h" +#include "extract.h" + + +static const char *ipxaddr_string(u_int32_t, const u_char *); +void ipx_decode(const struct ipxHdr *, const u_char *, u_int); +void ipx_sap_print(const u_short *, u_int); +void ipx_rip_print(const u_short *, u_int); + +/* + * Print IPX datagram packets. + */ +void +ipx_print(const u_char *p, u_int length) +{ + const struct ipxHdr *ipx = (const struct ipxHdr *)p; + + if (!eflag) + printf("IPX "); + + TCHECK(ipx->srcSkt); + (void)printf("%s.%04x > ", + ipxaddr_string(EXTRACT_32BITS(ipx->srcNet), ipx->srcNode), + EXTRACT_16BITS(&ipx->srcSkt)); + + (void)printf("%s.%04x: ", + ipxaddr_string(EXTRACT_32BITS(ipx->dstNet), ipx->dstNode), + EXTRACT_16BITS(&ipx->dstSkt)); + + /* take length from ipx header */ + TCHECK(ipx->length); + length = EXTRACT_16BITS(&ipx->length); + + ipx_decode(ipx, (u_char *)ipx + ipxSize, length - ipxSize); + return; +trunc: + printf("[|ipx %d]", length); +} + +static const char * +ipxaddr_string(u_int32_t net, const u_char *node) +{ + static char line[256]; + + snprintf(line, sizeof(line), "%08x.%02x:%02x:%02x:%02x:%02x:%02x", + net, node[0], node[1], node[2], node[3], node[4], node[5]); + + return line; +} + +void +ipx_decode(const struct ipxHdr *ipx, const u_char *datap, u_int length) +{ + register u_short dstSkt; + + dstSkt = EXTRACT_16BITS(&ipx->dstSkt); + switch (dstSkt) { + case IPX_SKT_NCP: + (void)printf("ipx-ncp %d", length); + break; + case IPX_SKT_SAP: + ipx_sap_print((u_short *)datap, length); + break; + case IPX_SKT_RIP: + ipx_rip_print((u_short *)datap, length); + break; + case IPX_SKT_NETBIOS: + (void)printf("ipx-netbios %d", length); +#ifdef TCPDUMP_DO_SMB + ipx_netbios_print(datap, length); +#endif + break; + case IPX_SKT_DIAGNOSTICS: + (void)printf("ipx-diags %d", length); + break; + case IPX_SKT_NWLINK_DGM: + (void)printf("ipx-nwlink-dgm %d", length); +#ifdef TCPDUMP_DO_SMB + ipx_netbios_print(datap, length); +#endif + break; + case IPX_SKT_EIGRP: + eigrp_print(datap, length); + break; + default: + (void)printf("ipx-#%x %d", dstSkt, length); + break; + } +} + +void +ipx_sap_print(const u_short *ipx, u_int length) +{ + int command, i; + + TCHECK(ipx[0]); + command = EXTRACT_16BITS(ipx); + ipx++; + length -= 2; + + switch (command) { + case 1: + case 3: + if (command == 1) + (void)printf("ipx-sap-req"); + else + (void)printf("ipx-sap-nearest-req"); + + TCHECK(ipx[0]); + (void)printf(" %s", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0])))); + break; + + case 2: + case 4: + if (command == 2) + (void)printf("ipx-sap-resp"); + else + (void)printf("ipx-sap-nearest-resp"); + + for (i = 0; i < 8 && length > 0; i++) { + TCHECK(ipx[0]); + (void)printf(" %s '", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0])))); + if (fn_printzp((u_char *)&ipx[1], 48, snapend)) { + printf("'"); + goto trunc; + } + TCHECK2(ipx[25], 10); + printf("' addr %s", + ipxaddr_string(EXTRACT_32BITS(&ipx[25]), (u_char *)&ipx[27])); + ipx += 32; + length -= 64; + } + break; + default: + (void)printf("ipx-sap-?%x", command); + break; + } + return; +trunc: + printf("[|ipx %d]", length); +} + +void +ipx_rip_print(const u_short *ipx, u_int length) +{ + int command, i; + + TCHECK(ipx[0]); + command = EXTRACT_16BITS(ipx); + ipx++; + length -= 2; + + switch (command) { + case 1: + (void)printf("ipx-rip-req"); + if (length > 0) { + TCHECK(ipx[3]); + (void)printf(" %u/%d.%d", EXTRACT_32BITS(&ipx[0]), + EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3])); + } + break; + case 2: + (void)printf("ipx-rip-resp"); + for (i = 0; i < 50 && length > 0; i++) { + TCHECK(ipx[3]); + (void)printf(" %u/%d.%d", EXTRACT_32BITS(&ipx[0]), + EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3])); + + ipx += 4; + length -= 8; + } + break; + default: + (void)printf("ipx-rip-?%x", command); + break; + } + return; +trunc: + printf("[|ipx %d]", length); +} diff --git a/print-isakmp.c b/print-isakmp.c new file mode 100644 index 0000000..4f96afe --- /dev/null +++ b/print-isakmp.c @@ -0,0 +1,2570 @@ +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.61 2008-02-05 19:34:25 guy Exp $ (LBL)"; +#endif + +#define NETDISSECT_REWORKED +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include + +#include "isakmp.h" +#include "ipsec_doi.h" +#include "oakley.h" +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif + +#ifndef HAVE_SOCKADDR_STORAGE +#define sockaddr_storage sockaddr +#endif + +#define DECLARE_PRINTER(func) static const u_char *ike##func##_print( \ + netdissect_options *ndo, u_char tpay, \ + const struct isakmp_gen *ext, \ + u_int item_len, \ + const u_char *end_pointer, \ + u_int32_t phase,\ + u_int32_t doi0, \ + u_int32_t proto0, int depth) + +DECLARE_PRINTER(v1_sa); +DECLARE_PRINTER(v1_p); +DECLARE_PRINTER(v1_t); +DECLARE_PRINTER(v1_ke); +DECLARE_PRINTER(v1_id); +DECLARE_PRINTER(v1_cert); +DECLARE_PRINTER(v1_cr); +DECLARE_PRINTER(v1_sig); +DECLARE_PRINTER(v1_hash); +DECLARE_PRINTER(v1_nonce); +DECLARE_PRINTER(v1_n); +DECLARE_PRINTER(v1_d); +DECLARE_PRINTER(v1_vid); + +DECLARE_PRINTER(v2_sa); +DECLARE_PRINTER(v2_ke); +DECLARE_PRINTER(v2_ID); +DECLARE_PRINTER(v2_cert); +DECLARE_PRINTER(v2_cr); +DECLARE_PRINTER(v2_auth); +DECLARE_PRINTER(v2_nonce); +DECLARE_PRINTER(v2_n); +DECLARE_PRINTER(v2_d); +DECLARE_PRINTER(v2_vid); +DECLARE_PRINTER(v2_TS); +DECLARE_PRINTER(v2_cp); +DECLARE_PRINTER(v2_eap); + +static const u_char *ikev2_e_print(netdissect_options *ndo, + struct isakmp *base, + u_char tpay, + const struct isakmp_gen *ext, + u_int item_len, + const u_char *end_pointer, + u_int32_t phase, + u_int32_t doi0, + u_int32_t proto0, int depth); + + +static const u_char *ike_sub0_print(netdissect_options *ndo,u_char, const struct isakmp_gen *, + const u_char *, u_int32_t, u_int32_t, u_int32_t, int); +static const u_char *ikev1_sub_print(netdissect_options *ndo,u_char, const struct isakmp_gen *, + const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + +static const u_char *ikev2_sub_print(netdissect_options *ndo, + struct isakmp *base, + u_char np, const struct isakmp_gen *ext, + const u_char *ep, u_int32_t phase, + u_int32_t doi, u_int32_t proto, + int depth); + + +static char *numstr(int); +static void safememcpy(void *, const void *, size_t); + +static void +ikev1_print(netdissect_options *ndo, + const u_char *bp, u_int length, + const u_char *bp2, struct isakmp *base); + +#define MAXINITIATORS 20 +int ninitiator = 0; +struct { + cookie_t initiator; + struct sockaddr_storage iaddr; + struct sockaddr_storage raddr; +} cookiecache[MAXINITIATORS]; + +/* protocol id */ +static const char *protoidstr[] = { + NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp", +}; + +/* isakmp->np */ +static const char *npstr[] = { + "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash", /* 0 - 8 */ + "sig", "nonce", "n", "d", "vid", /* 9 - 13 */ + "pay14", "pay15", "pay16", "pay17", "pay18", /* 14- 18 */ + "pay19", "pay20", "pay21", "pay22", "pay23", /* 19- 23 */ + "pay24", "pay25", "pay26", "pay27", "pay28", /* 24- 28 */ + "pay29", "pay30", "pay31", "pay32", /* 29- 32 */ + "v2sa", "v2ke", "v2IDi", "v2IDr", "v2cert",/* 33- 37 */ + "v2cr", "v2auth","v2nonce", "v2n", "v2d", /* 38- 42 */ + "v2vid", "v2TSi", "v2TSr", "v2e", "v2cp", /* 43- 47 */ + "v2eap", /* 48 */ + +}; + +/* isakmp->np */ +static const u_char *(*npfunc[])(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len, + const u_char *end_pointer, + u_int32_t phase, + u_int32_t doi0, + u_int32_t proto0, int depth) = { + NULL, + ikev1_sa_print, + ikev1_p_print, + ikev1_t_print, + ikev1_ke_print, + ikev1_id_print, + ikev1_cert_print, + ikev1_cr_print, + ikev1_hash_print, + ikev1_sig_print, + ikev1_nonce_print, + ikev1_n_print, + ikev1_d_print, + ikev1_vid_print, /* 13 */ + NULL, NULL, NULL, NULL, NULL, /* 14- 18 */ + NULL, NULL, NULL, NULL, NULL, /* 19- 23 */ + NULL, NULL, NULL, NULL, NULL, /* 24- 28 */ + NULL, NULL, NULL, NULL, /* 29- 32 */ + ikev2_sa_print, /* 33 */ + ikev2_ke_print, /* 34 */ + ikev2_ID_print, /* 35 */ + ikev2_ID_print, /* 36 */ + ikev2_cert_print, /* 37 */ + ikev2_cr_print, /* 38 */ + ikev2_auth_print, /* 39 */ + ikev2_nonce_print, /* 40 */ + ikev2_n_print, /* 41 */ + ikev2_d_print, /* 42 */ + ikev2_vid_print, /* 43 */ + ikev2_TS_print, /* 44 */ + ikev2_TS_print, /* 45 */ + NULL, /* ikev2_e_print,*/ /* 46 - special */ + ikev2_cp_print, /* 47 */ + ikev2_eap_print, /* 48 */ +}; + +/* isakmp->etype */ +static const char *etypestr[] = { +/* IKEv1 exchange types */ + "none", "base", "ident", "auth", "agg", "inf", NULL, NULL, /* 0-7 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 8-15 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 16-23 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 24-31 */ + "oakley-quick", "oakley-newgroup", /* 32-33 */ +/* IKEv2 exchange types */ + "ikev2_init", "ikev2_auth", "child_sa", "inf2" /* 34-37 */ +}; + +#define STR_OR_ID(x, tab) \ + (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) +#define PROTOIDSTR(x) STR_OR_ID(x, protoidstr) +#define NPSTR(x) STR_OR_ID(x, npstr) +#define ETYPESTR(x) STR_OR_ID(x, etypestr) + +#define CHECKLEN(p, np) \ + if (ep < (u_char *)(p)) { \ + ND_PRINT((ndo," [|%s]", NPSTR(np))); \ + goto done; \ + } + + +#define NPFUNC(x) \ + (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \ + ? npfunc[(x)] : NULL) + +static int +iszero(u_char *p, size_t l) +{ + while (l--) { + if (*p++) + return 0; + } + return 1; +} + +/* find cookie from initiator cache */ +static int +cookie_find(cookie_t *in) +{ + int i; + + for (i = 0; i < MAXINITIATORS; i++) { + if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0) + return i; + } + + return -1; +} + +/* record initiator */ +static void +cookie_record(cookie_t *in, const u_char *bp2) +{ + int i; + struct ip *ip; + struct sockaddr_in *sin; +#ifdef INET6 + struct ip6_hdr *ip6; + struct sockaddr_in6 *sin6; +#endif + + i = cookie_find(in); + if (0 <= i) { + ninitiator = (i + 1) % MAXINITIATORS; + return; + } + + ip = (struct ip *)bp2; + switch (IP_V(ip)) { + case 4: + memset(&cookiecache[ninitiator].iaddr, 0, + sizeof(cookiecache[ninitiator].iaddr)); + memset(&cookiecache[ninitiator].raddr, 0, + sizeof(cookiecache[ninitiator].raddr)); + + sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr; +#ifdef HAVE_SOCKADDR_SA_LEN + sin->sin_len = sizeof(struct sockaddr_in); +#endif + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); + sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr; +#ifdef HAVE_SOCKADDR_SA_LEN + sin->sin_len = sizeof(struct sockaddr_in); +#endif + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)); + break; +#ifdef INET6 + case 6: + memset(&cookiecache[ninitiator].iaddr, 0, + sizeof(cookiecache[ninitiator].iaddr)); + memset(&cookiecache[ninitiator].raddr, 0, + sizeof(cookiecache[ninitiator].raddr)); + + ip6 = (struct ip6_hdr *)bp2; + sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr; +#ifdef HAVE_SOCKADDR_SA_LEN + sin6->sin6_len = sizeof(struct sockaddr_in6); +#endif + sin6->sin6_family = AF_INET6; + memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); + sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr; +#ifdef HAVE_SOCKADDR_SA_LEN + sin6->sin6_len = sizeof(struct sockaddr_in6); +#endif + sin6->sin6_family = AF_INET6; + memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); + break; +#endif + default: + return; + } + memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in)); + ninitiator = (ninitiator + 1) % MAXINITIATORS; +} + +#define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1) +#define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0) +static int +cookie_sidecheck(int i, const u_char *bp2, int initiator) +{ + struct sockaddr_storage ss; + struct sockaddr *sa; + struct ip *ip; + struct sockaddr_in *sin; +#ifdef INET6 + struct ip6_hdr *ip6; + struct sockaddr_in6 *sin6; +#endif + int salen; + + memset(&ss, 0, sizeof(ss)); + ip = (struct ip *)bp2; + switch (IP_V(ip)) { + case 4: + sin = (struct sockaddr_in *)&ss; +#ifdef HAVE_SOCKADDR_SA_LEN + sin->sin_len = sizeof(struct sockaddr_in); +#endif + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); + break; +#ifdef INET6 + case 6: + ip6 = (struct ip6_hdr *)bp2; + sin6 = (struct sockaddr_in6 *)&ss; +#ifdef HAVE_SOCKADDR_SA_LEN + sin6->sin6_len = sizeof(struct sockaddr_in6); +#endif + sin6->sin6_family = AF_INET6; + memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); + break; +#endif + default: + return 0; + } + + sa = (struct sockaddr *)&ss; + if (initiator) { + if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family) + return 0; +#ifdef HAVE_SOCKADDR_SA_LEN + salen = sa->sa_len; +#else +#ifdef INET6 + if (sa->sa_family == AF_INET6) + salen = sizeof(struct sockaddr_in6); + else + salen = sizeof(struct sockaddr); +#else + salen = sizeof(struct sockaddr); +#endif +#endif + if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0) + return 1; + } else { + if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family) + return 0; +#ifdef HAVE_SOCKADDR_SA_LEN + salen = sa->sa_len; +#else +#ifdef INET6 + if (sa->sa_family == AF_INET6) + salen = sizeof(struct sockaddr_in6); + else + salen = sizeof(struct sockaddr); +#else + salen = sizeof(struct sockaddr); +#endif +#endif + if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0) + return 1; + } + return 0; +} + +static void +hexprint(netdissect_options *ndo, caddr_t loc, size_t len) +{ + u_char *p; + size_t i; + + p = (u_char *)loc; + for (i = 0; i < len; i++) + ND_PRINT((ndo,"%02x", p[i] & 0xff)); +} + +static int +rawprint(netdissect_options *ndo, caddr_t loc, size_t len) +{ + ND_TCHECK2(*loc, len); + + hexprint(ndo, loc, len); + return 1; +trunc: + return 0; +} + + +/* + * returns false if we run out of data buffer + */ +static int ike_show_somedata(struct netdissect_options *ndo, + const u_char *cp, const u_char *ep) +{ + /* there is too much data, just show some of it */ + const u_char *end = ep - 20; + int elen = 20; + int len = ep - cp; + if(len > 10) { + len = 10; + } + + /* really shouldn't happen because of above */ + if(end < cp + len) { + end = cp+len; + elen = ep - end; + } + + ND_PRINT((ndo," data=(")); + if(!rawprint(ndo, (caddr_t)(cp), len)) goto trunc; + ND_PRINT((ndo, "...")); + if(elen) { + if(!rawprint(ndo, (caddr_t)(end), elen)) goto trunc; + } + ND_PRINT((ndo,")")); + return 1; + +trunc: + return 0; +} + +struct attrmap { + const char *type; + u_int nvalue; + const char *value[30]; /*XXX*/ +}; + +static const u_char * +ikev1_attrmap_print(netdissect_options *ndo, + const u_char *p, const u_char *ep, + const struct attrmap *map, size_t nmap) +{ + u_int16_t *q; + int totlen; + u_int32_t t, v; + + q = (u_int16_t *)p; + if (p[0] & 0x80) + totlen = 4; + else + totlen = 4 + EXTRACT_16BITS(&q[1]); + if (ep < p + totlen) { + ND_PRINT((ndo,"[|attr]")); + return ep + 1; + } + + ND_PRINT((ndo,"(")); + t = EXTRACT_16BITS(&q[0]) & 0x7fff; + if (map && t < nmap && map[t].type) + ND_PRINT((ndo,"type=%s ", map[t].type)); + else + ND_PRINT((ndo,"type=#%d ", t)); + if (p[0] & 0x80) { + ND_PRINT((ndo,"value=")); + v = EXTRACT_16BITS(&q[1]); + if (map && t < nmap && v < map[t].nvalue && map[t].value[v]) + ND_PRINT((ndo,"%s", map[t].value[v])); + else + rawprint(ndo, (caddr_t)&q[1], 2); + } else { + ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&q[1]))); + rawprint(ndo, (caddr_t)&p[4], EXTRACT_16BITS(&q[1])); + } + ND_PRINT((ndo,")")); + return p + totlen; +} + +static const u_char * +ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep) +{ + u_int16_t *q; + int totlen; + u_int32_t t; + + q = (u_int16_t *)p; + if (p[0] & 0x80) + totlen = 4; + else + totlen = 4 + EXTRACT_16BITS(&q[1]); + if (ep < p + totlen) { + ND_PRINT((ndo,"[|attr]")); + return ep + 1; + } + + ND_PRINT((ndo,"(")); + t = EXTRACT_16BITS(&q[0]) & 0x7fff; + ND_PRINT((ndo,"type=#%d ", t)); + if (p[0] & 0x80) { + ND_PRINT((ndo,"value=")); + t = q[1]; + rawprint(ndo, (caddr_t)&q[1], 2); + } else { + ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&q[1]))); + rawprint(ndo, (caddr_t)&p[2], EXTRACT_16BITS(&q[1])); + } + ND_PRINT((ndo,")")); + return p + totlen; +} + +static const u_char * +ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, + u_int item_len _U_, + const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_, + u_int32_t proto0, int depth) +{ + const struct ikev1_pl_sa *p; + struct ikev1_pl_sa sa; + const u_int32_t *q; + u_int32_t doi, sit, ident; + const u_char *cp, *np; + int t; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SA))); + + p = (struct ikev1_pl_sa *)ext; + ND_TCHECK(*p); + safememcpy(&sa, ext, sizeof(sa)); + doi = ntohl(sa.doi); + sit = ntohl(sa.sit); + if (doi != 1) { + ND_PRINT((ndo," doi=%d", doi)); + ND_PRINT((ndo," situation=%u", (u_int32_t)ntohl(sa.sit))); + return (u_char *)(p + 1); + } + + ND_PRINT((ndo," doi=ipsec")); + q = (u_int32_t *)&sa.sit; + ND_PRINT((ndo," situation=")); + t = 0; + if (sit & 0x01) { + ND_PRINT((ndo,"identity")); + t++; + } + if (sit & 0x02) { + ND_PRINT((ndo,"%ssecrecy", t ? "+" : "")); + t++; + } + if (sit & 0x04) + ND_PRINT((ndo,"%sintegrity", t ? "+" : "")); + + np = (u_char *)ext + sizeof(sa); + if (sit != 0x01) { + ND_TCHECK2(*(ext + 1), sizeof(ident)); + safememcpy(&ident, ext + 1, sizeof(ident)); + ND_PRINT((ndo," ident=%u", (u_int32_t)ntohl(ident))); + np += sizeof(ident); + } + + ext = (struct isakmp_gen *)np; + ND_TCHECK(*ext); + + cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0, + depth); + + return cp; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SA))); + return NULL; +} + +static const u_char * +ikev1_p_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep, u_int32_t phase, u_int32_t doi0, + u_int32_t proto0 _U_, int depth) +{ + const struct ikev1_pl_p *p; + struct ikev1_pl_p prop; + const u_char *cp; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_P))); + + p = (struct ikev1_pl_p *)ext; + ND_TCHECK(*p); + safememcpy(&prop, ext, sizeof(prop)); + ND_PRINT((ndo," #%d protoid=%s transform=%d", + prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t)); + if (prop.spi_size) { + ND_PRINT((ndo," spi=")); + if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size)) + goto trunc; + } + + ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); + ND_TCHECK(*ext); + + cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0, + prop.prot_id, depth); + + return cp; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P))); + return NULL; +} + +static const char *ikev1_p_map[] = { + NULL, "ike", +}; + +static const char *ikev2_t_type_map[]={ + NULL, "encr", "prf", "integ", "dh", "esn" +}; + +static const char *ah_p_map[] = { + NULL, "(reserved)", "md5", "sha", "1des", + "sha2-256", "sha2-384", "sha2-512", +}; + +static const char *prf_p_map[] = { + NULL, "hmac-md5", "hmac-sha", "hmac-tiger", + "aes128_xcbc" +}; + +static const char *integ_p_map[] = { + NULL, "hmac-md5", "hmac-sha", "dec-mac", + "kpdk-md5", "aes-xcbc" +}; + +static const char *esn_p_map[] = { + "no-esn", "esn" +}; + +static const char *dh_p_map[] = { + NULL, "modp768", + "modp1024", /* group 2 */ + "EC2N 2^155", /* group 3 */ + "EC2N 2^185", /* group 4 */ + "modp1536", /* group 5 */ + "iana-grp06", "iana-grp07", /* reserved */ + "iana-grp08", "iana-grp09", + "iana-grp10", "iana-grp11", + "iana-grp12", "iana-grp13", + "modp2048", /* group 14 */ + "modp3072", /* group 15 */ + "modp4096", /* group 16 */ + "modp6144", /* group 17 */ + "modp8192", /* group 18 */ +}; + +static const char *esp_p_map[] = { + NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast", + "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes" +}; + +static const char *ipcomp_p_map[] = { + NULL, "oui", "deflate", "lzs", +}; + +const struct attrmap ipsec_t_map[] = { + { NULL, 0, { NULL } }, + { "lifetype", 3, { NULL, "sec", "kb", }, }, + { "life", 0, { NULL } }, + { "group desc", 18, { NULL, "modp768", + "modp1024", /* group 2 */ + "EC2N 2^155", /* group 3 */ + "EC2N 2^185", /* group 4 */ + "modp1536", /* group 5 */ + "iana-grp06", "iana-grp07", /* reserved */ + "iana-grp08", "iana-grp09", + "iana-grp10", "iana-grp11", + "iana-grp12", "iana-grp13", + "modp2048", /* group 14 */ + "modp3072", /* group 15 */ + "modp4096", /* group 16 */ + "modp6144", /* group 17 */ + "modp8192", /* group 18 */ + }, }, + { "enc mode", 3, { NULL, "tunnel", "transport", }, }, + { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, }, + { "keylen", 0, { NULL } }, + { "rounds", 0, { NULL } }, + { "dictsize", 0, { NULL } }, + { "privalg", 0, { NULL } }, +}; + +const struct attrmap encr_t_map[] = { + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 0, 1 */ + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 2, 3 */ + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 4, 5 */ + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 6, 7 */ + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 8, 9 */ + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 10,11*/ + { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 12,13*/ + { "keylen", 14, { NULL }}, +}; + +const struct attrmap oakley_t_map[] = { + { NULL, 0, { NULL } }, + { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5", + "3des", "cast", "aes", }, }, + { "hash", 7, { NULL, "md5", "sha1", "tiger", + "sha2-256", "sha2-384", "sha2-512", }, }, + { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc", + "rsa enc revised", }, }, + { "group desc", 18, { NULL, "modp768", + "modp1024", /* group 2 */ + "EC2N 2^155", /* group 3 */ + "EC2N 2^185", /* group 4 */ + "modp1536", /* group 5 */ + "iana-grp06", "iana-grp07", /* reserved */ + "iana-grp08", "iana-grp09", + "iana-grp10", "iana-grp11", + "iana-grp12", "iana-grp13", + "modp2048", /* group 14 */ + "modp3072", /* group 15 */ + "modp4096", /* group 16 */ + "modp6144", /* group 17 */ + "modp8192", /* group 18 */ + }, }, + { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, }, + { "group prime", 0, { NULL } }, + { "group gen1", 0, { NULL } }, + { "group gen2", 0, { NULL } }, + { "group curve A", 0, { NULL } }, + { "group curve B", 0, { NULL } }, + { "lifetype", 3, { NULL, "sec", "kb", }, }, + { "lifeduration", 0, { NULL } }, + { "prf", 0, { NULL } }, + { "keylen", 0, { NULL } }, + { "field", 0, { NULL } }, + { "order", 0, { NULL } }, +}; + +static const u_char * +ikev1_t_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len, + const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto, int depth _U_) +{ + const struct ikev1_pl_t *p; + struct ikev1_pl_t t; + const u_char *cp; + const char *idstr; + const struct attrmap *map; + size_t nmap; + const u_char *ep2; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_T))); + + p = (struct ikev1_pl_t *)ext; + ND_TCHECK(*p); + safememcpy(&t, ext, sizeof(t)); + + switch (proto) { + case 1: + idstr = STR_OR_ID(t.t_id, ikev1_p_map); + map = oakley_t_map; + nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); + break; + case 2: + idstr = STR_OR_ID(t.t_id, ah_p_map); + map = ipsec_t_map; + nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); + break; + case 3: + idstr = STR_OR_ID(t.t_id, esp_p_map); + map = ipsec_t_map; + nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); + break; + case 4: + idstr = STR_OR_ID(t.t_id, ipcomp_p_map); + map = ipsec_t_map; + nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); + break; + default: + idstr = NULL; + map = NULL; + nmap = 0; + break; + } + + if (idstr) + ND_PRINT((ndo," #%d id=%s ", t.t_no, idstr)); + else + ND_PRINT((ndo," #%d id=%d ", t.t_no, t.t_id)); + cp = (u_char *)(p + 1); + ep2 = (u_char *)p + item_len; + while (cp < ep && cp < ep2) { + if (map && nmap) { + cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2, + map, nmap); + } else + cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2); + } + if (ep < ep2) + ND_PRINT((ndo,"...")); + return cp; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T))); + return NULL; +} + +static const u_char * +ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_KE))); + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4)); + if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_KE))); + return NULL; +} + +static const u_char * +ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ +#define USE_IPSECDOI_IN_PHASE1 1 + const struct ikev1_pl_id *p; + struct ikev1_pl_id id; + static const char *idtypestr[] = { + "IPv4", "IPv4net", "IPv6", "IPv6net", + }; + static const char *ipsecidtypestr[] = { + NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6", + "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN", + "keyid", + }; + int len; + const u_char *data; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_ID))); + + p = (struct ikev1_pl_id *)ext; + ND_TCHECK(*p); + safememcpy(&id, ext, sizeof(id)); + if (sizeof(*p) < item_len) { + data = (u_char *)(p + 1); + len = item_len - sizeof(*p); + } else { + data = NULL; + len = 0; + } + +#if 0 /*debug*/ + ND_PRINT((ndo," [phase=%d doi=%d proto=%d]", phase, doi, proto)); +#endif + switch (phase) { +#ifndef USE_IPSECDOI_IN_PHASE1 + case 1: +#endif + default: + ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.d.id_type, idtypestr))); + ND_PRINT((ndo," doi_data=%u", + (u_int32_t)(ntohl(id.d.doi_data) & 0xffffff))); + break; + +#ifdef USE_IPSECDOI_IN_PHASE1 + case 1: +#endif + case 2: + { + const struct ipsecdoi_id *p; + struct ipsecdoi_id id; + struct protoent *pe; + + p = (struct ipsecdoi_id *)ext; + ND_TCHECK(*p); + safememcpy(&id, ext, sizeof(id)); + ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.type, ipsecidtypestr))); + if (id.proto_id) { +#ifndef WIN32 + setprotoent(1); +#endif /* WIN32 */ + pe = getprotobynumber(id.proto_id); + if (pe) + ND_PRINT((ndo," protoid=%s", pe->p_name)); +#ifndef WIN32 + endprotoent(); +#endif /* WIN32 */ + } else { + /* it DOES NOT mean IPPROTO_IP! */ + ND_PRINT((ndo," protoid=%s", "0")); + } + ND_PRINT((ndo," port=%d", ntohs(id.port))); + if (!len) + break; + if (data == NULL) + goto trunc; + ND_TCHECK2(*data, len); + switch (id.type) { + case IPSECDOI_ID_IPV4_ADDR: + if (len < 4) + ND_PRINT((ndo," len=%d [bad: < 4]", len)); + else + ND_PRINT((ndo," len=%d %s", len, ipaddr_string(data))); + len = 0; + break; + case IPSECDOI_ID_FQDN: + case IPSECDOI_ID_USER_FQDN: + { + int i; + ND_PRINT((ndo," len=%d ", len)); + for (i = 0; i < len; i++) + safeputchar(data[i]); + len = 0; + break; + } + case IPSECDOI_ID_IPV4_ADDR_SUBNET: + { + const u_char *mask; + if (len < 8) + ND_PRINT((ndo," len=%d [bad: < 8]", len)); + else { + mask = data + sizeof(struct in_addr); + ND_PRINT((ndo," len=%d %s/%u.%u.%u.%u", len, + ipaddr_string(data), + mask[0], mask[1], mask[2], mask[3])); + } + len = 0; + break; + } +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR: + if (len < 16) + ND_PRINT((ndo," len=%d [bad: < 16]", len)); + else + ND_PRINT((ndo," len=%d %s", len, ip6addr_string(data))); + len = 0; + break; + case IPSECDOI_ID_IPV6_ADDR_SUBNET: + { + const u_int32_t *mask; + if (len < 20) + ND_PRINT((ndo," len=%d [bad: < 20]", len)); + else { + mask = (u_int32_t *)(data + sizeof(struct in6_addr)); + /*XXX*/ + ND_PRINT((ndo," len=%d %s/0x%08x%08x%08x%08x", len, + ip6addr_string(data), + mask[0], mask[1], mask[2], mask[3])); + } + len = 0; + break; + } +#endif /*INET6*/ + case IPSECDOI_ID_IPV4_ADDR_RANGE: + if (len < 8) + ND_PRINT((ndo," len=%d [bad: < 8]", len)); + else { + ND_PRINT((ndo," len=%d %s-%s", len, + ipaddr_string(data), + ipaddr_string(data + sizeof(struct in_addr)))); + } + len = 0; + break; +#ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR_RANGE: + if (len < 32) + ND_PRINT((ndo," len=%d [bad: < 32]", len)); + else { + ND_PRINT((ndo," len=%d %s-%s", len, + ip6addr_string(data), + ip6addr_string(data + sizeof(struct in6_addr)))); + } + len = 0; + break; +#endif /*INET6*/ + case IPSECDOI_ID_DER_ASN1_DN: + case IPSECDOI_ID_DER_ASN1_GN: + case IPSECDOI_ID_KEY_ID: + break; + } + break; + } + } + if (data && len) { + ND_PRINT((ndo," len=%d", len)); + if (2 < ndo->ndo_vflag) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)data, len)) + goto trunc; + } + } + return (u_char *)ext + item_len; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_ID))); + return NULL; +} + +static const u_char * +ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, + u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth _U_) +{ + const struct ikev1_pl_cert *p; + struct ikev1_pl_cert cert; + static const char *certstr[] = { + "none", "pkcs7", "pgp", "dns", + "x509sign", "x509ke", "kerberos", "crl", + "arl", "spki", "x509attr", + }; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CERT))); + + p = (struct ikev1_pl_cert *)ext; + ND_TCHECK(*p); + safememcpy(&cert, ext, sizeof(cert)); + ND_PRINT((ndo," len=%d", item_len - 4)); + ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr))); + if (2 < ndo->ndo_vflag && 4 < item_len) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4)) + goto trunc; + } + return (u_char *)ext + item_len; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CERT))); + return NULL; +} + +static const u_char * +ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth _U_) +{ + const struct ikev1_pl_cert *p; + struct ikev1_pl_cert cert; + static const char *certstr[] = { + "none", "pkcs7", "pgp", "dns", + "x509sign", "x509ke", "kerberos", "crl", + "arl", "spki", "x509attr", + }; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CR))); + + p = (struct ikev1_pl_cert *)ext; + ND_TCHECK(*p); + safememcpy(&cert, ext, sizeof(cert)); + ND_PRINT((ndo," len=%d", item_len - 4)); + ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr))); + if (2 < ndo->ndo_vflag && 4 < item_len) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4)) + goto trunc; + } + return (u_char *)ext + item_len; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CR))); + return NULL; +} + +static const u_char * +ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_HASH))); + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); + if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_HASH))); + return NULL; +} + +static const u_char * +ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SIG))); + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); + if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SIG))); + return NULL; +} + +static const u_char * +ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, + u_int item_len _U_, + const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_NONCE))); + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4)); + if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," ")); + if (!ike_show_somedata(ndo, (u_char *)(caddr_t)(ext + 1), ep)) + goto trunc; + } + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE))); + return NULL; +} + +static const u_char * +ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len, + const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth) +{ + struct ikev1_pl_n *p, n; + const u_char *cp; + u_char *ep2; + u_int32_t doi; + u_int32_t proto; + static const char *notify_error_str[] = { + NULL, "INVALID-PAYLOAD-TYPE", + "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED", + "INVALID-COOKIE", "INVALID-MAJOR-VERSION", + "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE", + "INVALID-FLAGS", "INVALID-MESSAGE-ID", + "INVALID-PROTOCOL-ID", "INVALID-SPI", + "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED", + "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX", + "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION", + "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING", + "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED", + "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION", + "AUTHENTICATION-FAILED", "INVALID-SIGNATURE", + "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME", + "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE", + "UNEQUAL-PAYLOAD-LENGTHS", + }; + static const char *ipsec_notify_error_str[] = { + "RESERVED", + }; + static const char *notify_status_str[] = { + "CONNECTED", + }; + static const char *ipsec_notify_status_str[] = { + "RESPONDER-LIFETIME", "REPLAY-STATUS", + "INITIAL-CONTACT", + }; +/* NOTE: these macro must be called with x in proper range */ + +/* 0 - 8191 */ +#define NOTIFY_ERROR_STR(x) \ + STR_OR_ID((x), notify_error_str) + +/* 8192 - 16383 */ +#define IPSEC_NOTIFY_ERROR_STR(x) \ + STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str) + +/* 16384 - 24575 */ +#define NOTIFY_STATUS_STR(x) \ + STR_OR_ID((u_int)((x) - 16384), notify_status_str) + +/* 24576 - 32767 */ +#define IPSEC_NOTIFY_STATUS_STR(x) \ + STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str) + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_N))); + + p = (struct ikev1_pl_n *)ext; + ND_TCHECK(*p); + safememcpy(&n, ext, sizeof(n)); + doi = ntohl(n.doi); + proto = n.prot_id; + if (doi != 1) { + ND_PRINT((ndo," doi=%d", doi)); + ND_PRINT((ndo," proto=%d", proto)); + if (ntohs(n.type) < 8192) + ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type)))); + else if (ntohs(n.type) < 16384) + ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); + else if (ntohs(n.type) < 24576) + ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type)))); + else + ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); + if (n.spi_size) { + ND_PRINT((ndo," spi=")); + if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) + goto trunc; + } + return (u_char *)(p + 1) + n.spi_size; + } + + ND_PRINT((ndo," doi=ipsec")); + ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto))); + if (ntohs(n.type) < 8192) + ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type)))); + else if (ntohs(n.type) < 16384) + ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type)))); + else if (ntohs(n.type) < 24576) + ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type)))); + else if (ntohs(n.type) < 32768) + ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type)))); + else + ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); + if (n.spi_size) { + ND_PRINT((ndo," spi=")); + if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) + goto trunc; + } + + cp = (u_char *)(p + 1) + n.spi_size; + ep2 = (u_char *)p + item_len; + + if (cp < ep) { + ND_PRINT((ndo," orig=(")); + switch (ntohs(n.type)) { + case IPSECDOI_NTYPE_RESPONDER_LIFETIME: + { + const struct attrmap *map = oakley_t_map; + size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); + while (cp < ep && cp < ep2) { + cp = ikev1_attrmap_print(ndo, cp, + (ep < ep2) ? ep : ep2, map, nmap); + } + break; + } + case IPSECDOI_NTYPE_REPLAY_STATUS: + ND_PRINT((ndo,"replay detection %sabled", + (*(u_int32_t *)cp) ? "en" : "dis")); + break; + case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN: + if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA, + (struct isakmp_gen *)cp, ep, phase, doi, proto, + depth) == NULL) + return NULL; + break; + default: + /* NULL is dummy */ + isakmp_print(ndo, cp, + item_len - sizeof(*p) - n.spi_size, + NULL); + } + ND_PRINT((ndo,")")); + } + return (u_char *)ext + item_len; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N))); + return NULL; +} + +static const u_char * +ikev1_d_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth _U_) +{ + const struct ikev1_pl_d *p; + struct ikev1_pl_d d; + const u_int8_t *q; + u_int32_t doi; + u_int32_t proto; + int i; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_D))); + + p = (struct ikev1_pl_d *)ext; + ND_TCHECK(*p); + safememcpy(&d, ext, sizeof(d)); + doi = ntohl(d.doi); + proto = d.prot_id; + if (doi != 1) { + ND_PRINT((ndo," doi=%u", doi)); + ND_PRINT((ndo," proto=%u", proto)); + } else { + ND_PRINT((ndo," doi=ipsec")); + ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto))); + } + ND_PRINT((ndo," spilen=%u", d.spi_size)); + ND_PRINT((ndo," nspi=%u", ntohs(d.num_spi))); + ND_PRINT((ndo," spi=")); + q = (u_int8_t *)(p + 1); + for (i = 0; i < ntohs(d.num_spi); i++) { + if (i != 0) + ND_PRINT((ndo,",")); + if (!rawprint(ndo, (caddr_t)q, d.spi_size)) + goto trunc; + q += d.spi_size; + } + return q; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_D))); + return NULL; +} + +static const u_char * +ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + + ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_VID))); + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); + if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_VID))); + return NULL; +} + +/************************************************************/ +/* */ +/* IKE v2 - rfc4306 - dissector */ +/* */ +/************************************************************/ + +static void +ikev2_pay_print(netdissect_options *ndo, const char *payname, int critical) +{ + ND_PRINT((ndo,"%s%s:", payname, critical&0x80 ? "[C]" : "")); +} + +static const u_char * +ikev2_gen_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext) +{ + struct isakmp_gen e; + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ikev2_pay_print(ndo, NPSTR(tpay), e.critical); + + ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); + if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +static const u_char * +ikev2_t_print(netdissect_options *ndo, u_char tpay _U_, int pcount, + const struct isakmp_gen *ext, u_int item_len, + const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + const struct ikev2_t *p; + struct ikev2_t t; + u_int16_t t_id; + const u_char *cp; + const char *idstr; + const struct attrmap *map; + size_t nmap; + const u_char *ep2; + + p = (struct ikev2_t *)ext; + ND_TCHECK(*p); + safememcpy(&t, ext, sizeof(t)); + ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_T), t.h.critical); + + t_id = ntohs(t.t_id); + + map = NULL; + nmap = 0; + + switch (t.t_type) { + case IV2_T_ENCR: + idstr = STR_OR_ID(t_id, esp_p_map); + map = encr_t_map; + nmap = sizeof(encr_t_map)/sizeof(encr_t_map[0]); + break; + + case IV2_T_PRF: + idstr = STR_OR_ID(t_id, prf_p_map); + break; + + case IV2_T_INTEG: + idstr = STR_OR_ID(t_id, integ_p_map); + break; + + case IV2_T_DH: + idstr = STR_OR_ID(t_id, dh_p_map); + break; + + case IV2_T_ESN: + idstr = STR_OR_ID(t_id, esn_p_map); + break; + + default: + idstr = NULL; + break; + } + + if (idstr) + ND_PRINT((ndo," #%u type=%s id=%s ", pcount, + STR_OR_ID(t.t_type, ikev2_t_type_map), + idstr)); + else + ND_PRINT((ndo," #%u type=%s id=%u ", pcount, + STR_OR_ID(t.t_type, ikev2_t_type_map), + t.t_id)); + cp = (u_char *)(p + 1); + ep2 = (u_char *)p + item_len; + while (cp < ep && cp < ep2) { + if (map && nmap) { + cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2, + map, nmap); + } else + cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2); + } + if (ep < ep2) + ND_PRINT((ndo,"...")); + return cp; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T))); + return NULL; +} + +static const u_char * +ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_, + const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep, u_int32_t phase, u_int32_t doi0, + u_int32_t proto0 _U_, int depth) +{ + const struct ikev2_p *p; + struct ikev2_p prop; + const u_char *cp; + + p = (struct ikev2_p *)ext; + ND_TCHECK(*p); + safememcpy(&prop, ext, sizeof(prop)); + ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), prop.h.critical); + + ND_PRINT((ndo," #%u protoid=%s transform=%d len=%u", + prop.p_no, PROTOIDSTR(prop.prot_id), + prop.num_t, ntohs(prop.h.len))); + if (prop.spi_size) { + ND_PRINT((ndo," spi=")); + if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size)) + goto trunc; + } + + ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); + ND_TCHECK(*ext); + + cp = ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_T, ext, ep, phase, doi0, + prop.prot_id, depth); + + return cp; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P))); + return NULL; +} + +static const u_char * +ikev2_sa_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext1, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + int osa_length, sa_length; + + ND_TCHECK(*ext1); + safememcpy(&e, ext1, sizeof(e)); + ikev2_pay_print(ndo, "sa", e.critical); + + osa_length= ntohs(e.len); + sa_length = osa_length - 4; + ND_PRINT((ndo," len=%d", sa_length)); + + ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_P, + ext1+1, ep, + 0, 0, 0, depth); + + return (u_char *)ext1 + osa_length; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +static const u_char * +ikev2_ke_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct ikev2_ke ke; + struct ikev2_ke *k; + + k = (struct ikev2_ke *)ext; + ND_TCHECK(*ext); + safememcpy(&ke, ext, sizeof(ke)); + ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical); + + ND_PRINT((ndo," len=%u group=%s", ntohs(ke.h.len) - 8, + STR_OR_ID(ntohs(ke.ke_group), dh_p_map))); + + if (2 < ndo->ndo_vflag && 8 < ntohs(ke.h.len)) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(k + 1), ntohs(ke.h.len) - 8)) + goto trunc; + } + return (u_char *)ext + ntohs(ke.h.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +static const u_char * +ikev2_ID_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct ikev2_id id; + int id_len, idtype_len, i; + unsigned int dumpascii, dumphex; + unsigned char *typedata; + + ND_TCHECK(*ext); + safememcpy(&id, ext, sizeof(id)); + ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical); + + id_len = ntohs(id.h.len); + + ND_PRINT((ndo," len=%d", id_len - 4)); + if (2 < ndo->ndo_vflag && 4 < id_len) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), id_len - 4)) + goto trunc; + } + + idtype_len =id_len - sizeof(struct ikev2_id); + dumpascii = 0; + dumphex = 0; + typedata = (unsigned char *)(ext)+sizeof(struct ikev2_id); + + switch(id.type) { + case ID_IPV4_ADDR: + ND_PRINT((ndo, " ipv4:")); + dumphex=1; + break; + case ID_FQDN: + ND_PRINT((ndo, " fqdn:")); + dumpascii=1; + break; + case ID_RFC822_ADDR: + ND_PRINT((ndo, " rfc822:")); + dumpascii=1; + break; + case ID_IPV6_ADDR: + ND_PRINT((ndo, " ipv6:")); + dumphex=1; + break; + case ID_DER_ASN1_DN: + ND_PRINT((ndo, " dn:")); + dumphex=1; + break; + case ID_DER_ASN1_GN: + ND_PRINT((ndo, " gn:")); + dumphex=1; + break; + case ID_KEY_ID: + ND_PRINT((ndo, " keyid:")); + dumphex=1; + break; + } + + if(dumpascii) { + ND_TCHECK2(*typedata, idtype_len); + for(i=0; indo_vflag && 4 < len) { + ND_PRINT((ndo," authdata=(")); + if (!rawprint(ndo, (caddr_t)authdata, len - sizeof(a))) + goto trunc; + ND_PRINT((ndo,") ")); + } else if(ndo->ndo_vflag && 4 < len) { + if(!ike_show_somedata(ndo, authdata, ep)) goto trunc; + } + + return (u_char *)ext + len; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +static const u_char * +ikev2_nonce_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ikev2_pay_print(ndo, "nonce", e.critical); + + ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); + if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) { + ND_PRINT((ndo," nonce=(")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + ND_PRINT((ndo,") ")); + } else if(ndo->ndo_vflag && 4 < ntohs(e.len)) { + if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc; + } + + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +/* notify payloads */ +static const u_char * +ikev2_n_print(netdissect_options *ndo, u_char tpay _U_, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct ikev2_n *p, n; + const u_char *cp; + u_char *ep2; + u_char showspi, showdata, showsomedata; + const char *notify_name; + u_int32_t type; + + p = (struct ikev2_n *)ext; + ND_TCHECK(*p); + safememcpy(&n, ext, sizeof(n)); + ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical); + + showspi = 1; + showdata = 0; + showsomedata=0; + notify_name=NULL; + + ND_PRINT((ndo," prot_id=%s", PROTOIDSTR(n.prot_id))); + + type = ntohs(n.type); + + /* notify space is annoying sparse */ + switch(type) { + case IV2_NOTIFY_UNSUPPORTED_CRITICAL_PAYLOAD: + notify_name = "unsupported_critical_payload"; + showspi = 0; + break; + + case IV2_NOTIFY_INVALID_IKE_SPI: + notify_name = "invalid_ike_spi"; + showspi = 1; + break; + + case IV2_NOTIFY_INVALID_MAJOR_VERSION: + notify_name = "invalid_major_version"; + showspi = 0; + break; + + case IV2_NOTIFY_INVALID_SYNTAX: + notify_name = "invalid_syntax"; + showspi = 1; + break; + + case IV2_NOTIFY_INVALID_MESSAGE_ID: + notify_name = "invalid_message_id"; + showspi = 1; + break; + + case IV2_NOTIFY_INVALID_SPI: + notify_name = "invalid_spi"; + showspi = 1; + break; + + case IV2_NOTIFY_NO_PROPOSAL_CHOSEN: + notify_name = "no_protocol_chosen"; + showspi = 1; + break; + + case IV2_NOTIFY_INVALID_KE_PAYLOAD: + notify_name = "invalid_ke_payload"; + showspi = 1; + break; + + case IV2_NOTIFY_AUTHENTICATION_FAILED: + notify_name = "authentication_failed"; + showspi = 1; + break; + + case IV2_NOTIFY_SINGLE_PAIR_REQUIRED: + notify_name = "single_pair_required"; + showspi = 1; + break; + + case IV2_NOTIFY_NO_ADDITIONAL_SAS: + notify_name = "no_additional_sas"; + showspi = 0; + break; + + case IV2_NOTIFY_INTERNAL_ADDRESS_FAILURE: + notify_name = "internal_address_failure"; + showspi = 0; + break; + + case IV2_NOTIFY_FAILED_CP_REQUIRED: + notify_name = "failed:cp_required"; + showspi = 0; + break; + + case IV2_NOTIFY_INVALID_SELECTORS: + notify_name = "invalid_selectors"; + showspi = 0; + break; + + case IV2_NOTIFY_INITIAL_CONTACT: + notify_name = "initial_contact"; + showspi = 0; + break; + + case IV2_NOTIFY_SET_WINDOW_SIZE: + notify_name = "set_window_size"; + showspi = 0; + break; + + case IV2_NOTIFY_ADDITIONAL_TS_POSSIBLE: + notify_name = "additional_ts_possible"; + showspi = 0; + break; + + case IV2_NOTIFY_IPCOMP_SUPPORTED: + notify_name = "ipcomp_supported"; + showspi = 0; + break; + + case IV2_NOTIFY_NAT_DETECTION_SOURCE_IP: + notify_name = "nat_detection_source_ip"; + showspi = 1; + break; + + case IV2_NOTIFY_NAT_DETECTION_DESTINATION_IP: + notify_name = "nat_detection_destination_ip"; + showspi = 1; + break; + + case IV2_NOTIFY_COOKIE: + notify_name = "cookie"; + showspi = 1; + showsomedata= 1; + showdata= 0; + break; + + case IV2_NOTIFY_USE_TRANSPORT_MODE: + notify_name = "use_transport_mode"; + showspi = 0; + break; + + case IV2_NOTIFY_HTTP_CERT_LOOKUP_SUPPORTED: + notify_name = "http_cert_lookup_supported"; + showspi = 0; + break; + + case IV2_NOTIFY_REKEY_SA: + notify_name = "rekey_sa"; + showspi = 1; + break; + + case IV2_NOTIFY_ESP_TFC_PADDING_NOT_SUPPORTED: + notify_name = "tfc_padding_not_supported"; + showspi = 0; + break; + + case IV2_NOTIFY_NON_FIRST_FRAGMENTS_ALSO: + notify_name = "non_first_fragment_also"; + showspi = 0; + break; + + default: + if (type < 8192) { + notify_name="error"; + } else if(type < 16384) { + notify_name="private-error"; + } else if(type < 40960) { + notify_name="status"; + } else { + notify_name="private-status"; + } + } + + if(notify_name) { + ND_PRINT((ndo," type=%u(%s)", type, notify_name)); + } + + + if (showspi && n.spi_size) { + ND_PRINT((ndo," spi=")); + if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) + goto trunc; + } + + cp = (u_char *)(p + 1) + n.spi_size; + ep2 = (u_char *)p + item_len; + + if(3 < ndo->ndo_vflag) { + showdata = 1; + } + + if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) { + ND_PRINT((ndo," data=(")); + if (!rawprint(ndo, (caddr_t)(cp), ep - cp)) + goto trunc; + + ND_PRINT((ndo,")")); + + } else if(showsomedata && cp < ep) { + if(!ike_show_somedata(ndo, cp, ep)) goto trunc; + } + + return (u_char *)ext + item_len; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N))); + return NULL; +} + +static const u_char * +ikev2_d_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + return ikev2_gen_print(ndo, tpay, ext); +} + +static const u_char * +ikev2_vid_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + struct isakmp_gen e; + const u_char *vid; + int i, len; + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ikev2_pay_print(ndo, NPSTR(tpay), e.critical); + ND_PRINT((ndo," len=%d vid=", ntohs(e.len) - 4)); + + vid = (const u_char *)(ext+1); + len = ntohs(e.len) - 4; + ND_TCHECK2(*vid, len); + for(i=0; indo_vflag && 4 < len) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; + } + return (u_char *)ext + ntohs(e.len); +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +static const u_char * +ikev2_TS_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + return ikev2_gen_print(ndo, tpay, ext); +} + +static const u_char * +ikev2_e_print(netdissect_options *ndo, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + struct isakmp *base, + u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + u_int32_t phase, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + u_int32_t doi, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + u_int32_t proto, +#ifndef HAVE_LIBCRYPTO + _U_ +#endif + int depth) +{ + struct isakmp_gen e; + u_char *dat; + volatile int dlen; + + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + ikev2_pay_print(ndo, NPSTR(tpay), e.critical); + + dlen = ntohs(e.len)-4; + + ND_PRINT((ndo," len=%d", dlen)); + if (2 < ndo->ndo_vflag && 4 < dlen) { + ND_PRINT((ndo," ")); + if (!rawprint(ndo, (caddr_t)(ext + 1), dlen)) + goto trunc; + } + + dat = (u_char *)(ext+1); + ND_TCHECK2(*dat, dlen); + +#ifdef HAVE_LIBCRYPTO + /* try to decypt it! */ + if(esp_print_decrypt_buffer_by_ikev2(ndo, + base->flags & ISAKMP_FLAG_I, + base->i_ck, base->r_ck, + dat, dat+dlen)) { + + ext = (const struct isakmp_gen *)ndo->ndo_packetp; + + /* got it decrypted, print stuff inside. */ + ikev2_sub_print(ndo, base, e.np, ext, ndo->ndo_snapend, + phase, doi, proto, depth+1); + } +#endif + + + /* always return NULL, because E must be at end, and NP refers + * to what was inside. + */ + return NULL; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(tpay))); + return NULL; +} + +static const u_char * +ikev2_cp_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + return ikev2_gen_print(ndo, tpay, ext); +} + +static const u_char * +ikev2_eap_print(netdissect_options *ndo, u_char tpay, + const struct isakmp_gen *ext, + u_int item_len _U_, const u_char *ep _U_, + u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) +{ + return ikev2_gen_print(ndo, tpay, ext); +} + +static const u_char * +ike_sub0_print(netdissect_options *ndo, + u_char np, const struct isakmp_gen *ext, const u_char *ep, + + u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) +{ + const u_char *cp; + struct isakmp_gen e; + u_int item_len; + + cp = (u_char *)ext; + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + + /* + * Since we can't have a payload length of less than 4 bytes, + * we need to bail out here if the generic header is nonsensical + * or truncated, otherwise we could loop forever processing + * zero-length items or otherwise misdissect the packet. + */ + item_len = ntohs(e.len); + if (item_len <= 4) + return NULL; + + if (NPFUNC(np)) { + /* + * XXX - what if item_len is too short, or too long, + * for this payload type? + */ + cp = (*npfunc[np])(ndo, np, ext, item_len, ep, phase, doi, proto, depth); + } else { + ND_PRINT((ndo,"%s", NPSTR(np))); + cp += item_len; + } + + return cp; +trunc: + ND_PRINT((ndo," [|isakmp]")); + return NULL; +} + +static const u_char * +ikev1_sub_print(netdissect_options *ndo, + u_char np, const struct isakmp_gen *ext, const u_char *ep, + u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) +{ + const u_char *cp; + int i; + struct isakmp_gen e; + + cp = (const u_char *)ext; + + while (np) { + ND_TCHECK(*ext); + + safememcpy(&e, ext, sizeof(e)); + + ND_TCHECK2(*ext, ntohs(e.len)); + + depth++; + ND_PRINT((ndo,"\n")); + for (i = 0; i < depth; i++) + ND_PRINT((ndo," ")); + ND_PRINT((ndo,"(")); + cp = ike_sub0_print(ndo, np, ext, ep, phase, doi, proto, depth); + ND_PRINT((ndo,")")); + depth--; + + if (cp == NULL) { + /* Zero-length subitem */ + return NULL; + } + + np = e.np; + ext = (struct isakmp_gen *)cp; + } + return cp; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(np))); + return NULL; +} + +static char * +numstr(int x) +{ + static char buf[20]; + snprintf(buf, sizeof(buf), "#%d", x); + return buf; +} + +/* + * some compiler tries to optimize memcpy(), using the alignment constraint + * on the argument pointer type. by using this function, we try to avoid the + * optimization. + */ +static void +safememcpy(void *p, const void *q, size_t l) +{ + memcpy(p, q, l); +} + +static void +ikev1_print(netdissect_options *ndo, + const u_char *bp, u_int length, + const u_char *bp2, struct isakmp *base) +{ + const struct isakmp *p; + const u_char *ep; + u_char np; + int i; + int phase; + + p = (const struct isakmp *)bp; + ep = ndo->ndo_snapend; + + phase = (*(u_int32_t *)base->msgid == 0) ? 1 : 2; + if (phase == 1) + ND_PRINT((ndo," phase %d", phase)); + else + ND_PRINT((ndo," phase %d/others", phase)); + + i = cookie_find(&base->i_ck); + if (i < 0) { + if (iszero((u_char *)&base->r_ck, sizeof(base->r_ck))) { + /* the first packet */ + ND_PRINT((ndo," I")); + if (bp2) + cookie_record(&base->i_ck, bp2); + } else + ND_PRINT((ndo," ?")); + } else { + if (bp2 && cookie_isinitiator(i, bp2)) + ND_PRINT((ndo," I")); + else if (bp2 && cookie_isresponder(i, bp2)) + ND_PRINT((ndo," R")); + else + ND_PRINT((ndo," ?")); + } + + ND_PRINT((ndo," %s", ETYPESTR(base->etype))); + if (base->flags) { + ND_PRINT((ndo,"[%s%s]", base->flags & ISAKMP_FLAG_E ? "E" : "", + base->flags & ISAKMP_FLAG_C ? "C" : "")); + } + + if (ndo->ndo_vflag) { + const struct isakmp_gen *ext; + int nparen; + + ND_PRINT((ndo,":")); + + /* regardless of phase... */ + if (base->flags & ISAKMP_FLAG_E) { + /* + * encrypted, nothing we can do right now. + * we hope to decrypt the packet in the future... + */ + ND_PRINT((ndo," [encrypted %s]", NPSTR(base->np))); + goto done; + } + + nparen = 0; + CHECKLEN(p + 1, base->np); + np = base->np; + ext = (struct isakmp_gen *)(p + 1); + ikev1_sub_print(ndo, np, ext, ep, phase, 0, 0, 0); + } + +done: + if (ndo->ndo_vflag) { + if (ntohl(base->len) != length) { + ND_PRINT((ndo," (len mismatch: isakmp %u/ip %u)", + (u_int32_t)ntohl(base->len), length)); + } + } +} + +static const u_char * +ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base, + u_char np, int pcount, + const struct isakmp_gen *ext, const u_char *ep, + u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) +{ + const u_char *cp; + struct isakmp_gen e; + u_int item_len; + + cp = (u_char *)ext; + ND_TCHECK(*ext); + safememcpy(&e, ext, sizeof(e)); + + /* + * Since we can't have a payload length of less than 4 bytes, + * we need to bail out here if the generic header is nonsensical + * or truncated, otherwise we could loop forever processing + * zero-length items or otherwise misdissect the packet. + */ + item_len = ntohs(e.len); + if (item_len <= 4) + return NULL; + + if(np == ISAKMP_NPTYPE_P) { + cp = ikev2_p_print(ndo, np, pcount, ext, item_len, + ep, phase, doi, proto, depth); + } else if(np == ISAKMP_NPTYPE_T) { + cp = ikev2_t_print(ndo, np, pcount, ext, item_len, + ep, phase, doi, proto, depth); + } else if(np == ISAKMP_NPTYPE_v2E) { + cp = ikev2_e_print(ndo, base, np, ext, item_len, + ep, phase, doi, proto, depth); + } else if (NPFUNC(np)) { + /* + * XXX - what if item_len is too short, or too long, + * for this payload type? + */ + cp = (*npfunc[np])(ndo, np, /*pcount,*/ ext, item_len, + ep, phase, doi, proto, depth); + } else { + ND_PRINT((ndo,"%s", NPSTR(np))); + cp += item_len; + } + + return cp; +trunc: + ND_PRINT((ndo," [|isakmp]")); + return NULL; +} + +static const u_char * +ikev2_sub_print(netdissect_options *ndo, + struct isakmp *base, + u_char np, const struct isakmp_gen *ext, const u_char *ep, + u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) +{ + const u_char *cp; + int i; + int pcount; + struct isakmp_gen e; + + cp = (const u_char *)ext; + pcount = 0; + while (np) { + pcount++; + ND_TCHECK(*ext); + + safememcpy(&e, ext, sizeof(e)); + + ND_TCHECK2(*ext, ntohs(e.len)); + + depth++; + ND_PRINT((ndo,"\n")); + for (i = 0; i < depth; i++) + ND_PRINT((ndo," ")); + ND_PRINT((ndo,"(")); + cp = ikev2_sub0_print(ndo, base, np, pcount, + ext, ep, phase, doi, proto, depth); + ND_PRINT((ndo,")")); + depth--; + + if (cp == NULL) { + /* Zero-length subitem */ + return NULL; + } + + np = e.np; + ext = (struct isakmp_gen *)cp; + } + return cp; +trunc: + ND_PRINT((ndo," [|%s]", NPSTR(np))); + return NULL; +} + +static void +ikev2_print(netdissect_options *ndo, + const u_char *bp, u_int length, + const u_char *bp2 _U_, struct isakmp *base) +{ + const struct isakmp *p; + const u_char *ep; + u_char np; + int phase; + + p = (const struct isakmp *)bp; + ep = ndo->ndo_snapend; + + phase = (*(u_int32_t *)base->msgid == 0) ? 1 : 2; + if (phase == 1) + ND_PRINT((ndo, " parent_sa")); + else + ND_PRINT((ndo, " child_sa ")); + + ND_PRINT((ndo, " %s", ETYPESTR(base->etype))); + if (base->flags) { + ND_PRINT((ndo, "[%s%s%s]", + base->flags & ISAKMP_FLAG_I ? "I" : "", + base->flags & ISAKMP_FLAG_V ? "V" : "", + base->flags & ISAKMP_FLAG_R ? "R" : "")); + } + + if (ndo->ndo_vflag) { + const struct isakmp_gen *ext; + int nparen; + + ND_PRINT((ndo, ":")); + + /* regardless of phase... */ + if (base->flags & ISAKMP_FLAG_E) { + /* + * encrypted, nothing we can do right now. + * we hope to decrypt the packet in the future... + */ + ND_PRINT((ndo, " [encrypted %s]", NPSTR(base->np))); + goto done; + } + + nparen = 0; + CHECKLEN(p + 1, base->np) + + np = base->np; + ext = (struct isakmp_gen *)(p + 1); + ikev2_sub_print(ndo, base, np, ext, ep, phase, 0, 0, 0); + } + +done: + if (ndo->ndo_vflag) { + if (ntohl(base->len) != length) { + ND_PRINT((ndo, " (len mismatch: isakmp %u/ip %u)", + (u_int32_t)ntohl(base->len), length)); + } + } +} + +void +isakmp_print(netdissect_options *ndo, + const u_char *bp, u_int length, + const u_char *bp2) +{ + const struct isakmp *p; + struct isakmp base; + const u_char *ep; + int major, minor; + +#ifdef HAVE_LIBCRYPTO + /* initialize SAs */ + if (ndo->ndo_sa_list_head == NULL) { + if (ndo->ndo_espsecret) + esp_print_decodesecret(ndo); + } +#endif + + p = (const struct isakmp *)bp; + ep = ndo->ndo_snapend; + + if ((struct isakmp *)ep < p + 1) { + ND_PRINT((ndo,"[|isakmp]")); + return; + } + + safememcpy(&base, p, sizeof(base)); + + ND_PRINT((ndo,"isakmp")); + major = (base.vers & ISAKMP_VERS_MAJOR) + >> ISAKMP_VERS_MAJOR_SHIFT; + minor = (base.vers & ISAKMP_VERS_MINOR) + >> ISAKMP_VERS_MINOR_SHIFT; + + if (ndo->ndo_vflag) { + ND_PRINT((ndo," %d.%d", major, minor)); + } + + if (ndo->ndo_vflag) { + ND_PRINT((ndo," msgid ")); + hexprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid)); + } + + if (1 < ndo->ndo_vflag) { + ND_PRINT((ndo," cookie ")); + hexprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck)); + ND_PRINT((ndo,"->")); + hexprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck)); + } + ND_PRINT((ndo,":")); + + switch(major) { + case IKEv1_MAJOR_VERSION: + ikev1_print(ndo, bp, length, bp2, &base); + break; + + case IKEv2_MAJOR_VERSION: + ikev2_print(ndo, bp, length, bp2, &base); + break; + } +} + +void +isakmp_rfc3948_print(netdissect_options *ndo, + const u_char *bp, u_int length, + const u_char *bp2) +{ + const u_char *ep; + ep = ndo->ndo_snapend; + + if(length == 1 && bp[0]==0xff) { + ND_PRINT((ndo, "isakmp-nat-keep-alive")); + return; + } + + if(length < 4) { + goto trunc; + } + + /* + * see if this is an IKE packet + */ + if(bp[0]==0 && bp[1]==0 && bp[2]==0 && bp[3]==0) { + ND_PRINT((ndo, "NONESP-encap: ")); + isakmp_print(ndo, bp+4, length-4, bp2); + return; + } + + /* must be an ESP packet */ + { + int nh, enh, padlen; + int advance; + + ND_PRINT((ndo, "UDP-encap: ")); + + advance = esp_print(ndo, bp, length, bp2, &enh, &padlen); + if(advance <= 0) + return; + + bp += advance; + length -= advance + padlen; + nh = enh & 0xff; + + ip_print_inner(ndo, bp, length, nh, bp2); + return; + } + +trunc: + ND_PRINT((ndo,"[|isakmp]")); + return; +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ + + + + diff --git a/print-isoclns.c b/print-isoclns.c new file mode 100644 index 0000000..ea58d8a --- /dev/null +++ b/print-isoclns.c @@ -0,0 +1,2753 @@ +/* + * Copyright (c) 1992, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Original code by Matt Thomas, Digital Equipment Corporation + * + * Extensively modified by Hannes Gredler (hannes@juniper.net) for more + * complete IS-IS & CLNP support. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.165 2008-08-16 13:38:15 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "ether.h" +#include "nlpid.h" +#include "extract.h" +#include "gmpls.h" +#include "oui.h" +#include "signature.h" + +/* + * IS-IS is defined in ISO 10589. Look there for protocol definitions. + */ + +#define SYSTEM_ID_LEN ETHER_ADDR_LEN +#define NODE_ID_LEN SYSTEM_ID_LEN+1 +#define LSP_ID_LEN SYSTEM_ID_LEN+2 + +#define ISIS_VERSION 1 +#define ESIS_VERSION 1 +#define CLNP_VERSION 1 + +#define ISIS_PDU_TYPE_MASK 0x1F +#define ESIS_PDU_TYPE_MASK 0x1F +#define CLNP_PDU_TYPE_MASK 0x1F +#define CLNP_FLAG_MASK 0xE0 +#define ISIS_LAN_PRIORITY_MASK 0x7F + +#define ISIS_PDU_L1_LAN_IIH 15 +#define ISIS_PDU_L2_LAN_IIH 16 +#define ISIS_PDU_PTP_IIH 17 +#define ISIS_PDU_L1_LSP 18 +#define ISIS_PDU_L2_LSP 20 +#define ISIS_PDU_L1_CSNP 24 +#define ISIS_PDU_L2_CSNP 25 +#define ISIS_PDU_L1_PSNP 26 +#define ISIS_PDU_L2_PSNP 27 + +static struct tok isis_pdu_values[] = { + { ISIS_PDU_L1_LAN_IIH, "L1 Lan IIH"}, + { ISIS_PDU_L2_LAN_IIH, "L2 Lan IIH"}, + { ISIS_PDU_PTP_IIH, "p2p IIH"}, + { ISIS_PDU_L1_LSP, "L1 LSP"}, + { ISIS_PDU_L2_LSP, "L2 LSP"}, + { ISIS_PDU_L1_CSNP, "L1 CSNP"}, + { ISIS_PDU_L2_CSNP, "L2 CSNP"}, + { ISIS_PDU_L1_PSNP, "L1 PSNP"}, + { ISIS_PDU_L2_PSNP, "L2 PSNP"}, + { 0, NULL} +}; + +/* + * A TLV is a tuple of a type, length and a value and is normally used for + * encoding information in all sorts of places. This is an enumeration of + * the well known types. + * + * list taken from rfc3359 plus some memory from veterans ;-) + */ + +#define ISIS_TLV_AREA_ADDR 1 /* iso10589 */ +#define ISIS_TLV_IS_REACH 2 /* iso10589 */ +#define ISIS_TLV_ESNEIGH 3 /* iso10589 */ +#define ISIS_TLV_PART_DIS 4 /* iso10589 */ +#define ISIS_TLV_PREFIX_NEIGH 5 /* iso10589 */ +#define ISIS_TLV_ISNEIGH 6 /* iso10589 */ +#define ISIS_TLV_ISNEIGH_VARLEN 7 /* iso10589 */ +#define ISIS_TLV_PADDING 8 /* iso10589 */ +#define ISIS_TLV_LSP 9 /* iso10589 */ +#define ISIS_TLV_AUTH 10 /* iso10589, rfc3567 */ +#define ISIS_TLV_CHECKSUM 12 /* rfc3358 */ +#define ISIS_TLV_CHECKSUM_MINLEN 2 +#define ISIS_TLV_LSP_BUFFERSIZE 14 /* iso10589 rev2 */ +#define ISIS_TLV_LSP_BUFFERSIZE_MINLEN 2 +#define ISIS_TLV_EXT_IS_REACH 22 /* draft-ietf-isis-traffic-05 */ +#define ISIS_TLV_IS_ALIAS_ID 24 /* draft-ietf-isis-ext-lsp-frags-02 */ +#define ISIS_TLV_DECNET_PHASE4 42 +#define ISIS_TLV_LUCENT_PRIVATE 66 +#define ISIS_TLV_INT_IP_REACH 128 /* rfc1195, rfc2966 */ +#define ISIS_TLV_PROTOCOLS 129 /* rfc1195 */ +#define ISIS_TLV_EXT_IP_REACH 130 /* rfc1195, rfc2966 */ +#define ISIS_TLV_IDRP_INFO 131 /* rfc1195 */ +#define ISIS_TLV_IDRP_INFO_MINLEN 1 +#define ISIS_TLV_IPADDR 132 /* rfc1195 */ +#define ISIS_TLV_IPAUTH 133 /* rfc1195 */ +#define ISIS_TLV_TE_ROUTER_ID 134 /* draft-ietf-isis-traffic-05 */ +#define ISIS_TLV_EXTD_IP_REACH 135 /* draft-ietf-isis-traffic-05 */ +#define ISIS_TLV_HOSTNAME 137 /* rfc2763 */ +#define ISIS_TLV_SHARED_RISK_GROUP 138 /* draft-ietf-isis-gmpls-extensions */ +#define ISIS_TLV_NORTEL_PRIVATE1 176 +#define ISIS_TLV_NORTEL_PRIVATE2 177 +#define ISIS_TLV_RESTART_SIGNALING 211 /* rfc3847 */ +#define ISIS_TLV_RESTART_SIGNALING_FLAGLEN 1 +#define ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN 2 +#define ISIS_TLV_MT_IS_REACH 222 /* draft-ietf-isis-wg-multi-topology-05 */ +#define ISIS_TLV_MT_SUPPORTED 229 /* draft-ietf-isis-wg-multi-topology-05 */ +#define ISIS_TLV_MT_SUPPORTED_MINLEN 2 +#define ISIS_TLV_IP6ADDR 232 /* draft-ietf-isis-ipv6-02 */ +#define ISIS_TLV_MT_IP_REACH 235 /* draft-ietf-isis-wg-multi-topology-05 */ +#define ISIS_TLV_IP6_REACH 236 /* draft-ietf-isis-ipv6-02 */ +#define ISIS_TLV_MT_IP6_REACH 237 /* draft-ietf-isis-wg-multi-topology-05 */ +#define ISIS_TLV_PTP_ADJ 240 /* rfc3373 */ +#define ISIS_TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */ +#define ISIS_TLV_IIH_SEQNR_MINLEN 4 +#define ISIS_TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-experimental-tlv-01 */ +#define ISIS_TLV_VENDOR_PRIVATE_MINLEN 3 + +static struct tok isis_tlv_values[] = { + { ISIS_TLV_AREA_ADDR, "Area address(es)"}, + { ISIS_TLV_IS_REACH, "IS Reachability"}, + { ISIS_TLV_ESNEIGH, "ES Neighbor(s)"}, + { ISIS_TLV_PART_DIS, "Partition DIS"}, + { ISIS_TLV_PREFIX_NEIGH, "Prefix Neighbors"}, + { ISIS_TLV_ISNEIGH, "IS Neighbor(s)"}, + { ISIS_TLV_ISNEIGH_VARLEN, "IS Neighbor(s) (variable length)"}, + { ISIS_TLV_PADDING, "Padding"}, + { ISIS_TLV_LSP, "LSP entries"}, + { ISIS_TLV_AUTH, "Authentication"}, + { ISIS_TLV_CHECKSUM, "Checksum"}, + { ISIS_TLV_LSP_BUFFERSIZE, "LSP Buffersize"}, + { ISIS_TLV_EXT_IS_REACH, "Extended IS Reachability"}, + { ISIS_TLV_IS_ALIAS_ID, "IS Alias ID"}, + { ISIS_TLV_DECNET_PHASE4, "DECnet Phase IV"}, + { ISIS_TLV_LUCENT_PRIVATE, "Lucent Proprietary"}, + { ISIS_TLV_INT_IP_REACH, "IPv4 Internal Reachability"}, + { ISIS_TLV_PROTOCOLS, "Protocols supported"}, + { ISIS_TLV_EXT_IP_REACH, "IPv4 External Reachability"}, + { ISIS_TLV_IDRP_INFO, "Inter-Domain Information Type"}, + { ISIS_TLV_IPADDR, "IPv4 Interface address(es)"}, + { ISIS_TLV_IPAUTH, "IPv4 authentication (deprecated)"}, + { ISIS_TLV_TE_ROUTER_ID, "Traffic Engineering Router ID"}, + { ISIS_TLV_EXTD_IP_REACH, "Extended IPv4 Reachability"}, + { ISIS_TLV_SHARED_RISK_GROUP, "Shared Risk Link Group"}, + { ISIS_TLV_NORTEL_PRIVATE1, "Nortel Proprietary"}, + { ISIS_TLV_NORTEL_PRIVATE2, "Nortel Proprietary"}, + { ISIS_TLV_HOSTNAME, "Hostname"}, + { ISIS_TLV_RESTART_SIGNALING, "Restart Signaling"}, + { ISIS_TLV_MT_IS_REACH, "Multi Topology IS Reachability"}, + { ISIS_TLV_MT_SUPPORTED, "Multi Topology"}, + { ISIS_TLV_IP6ADDR, "IPv6 Interface address(es)"}, + { ISIS_TLV_MT_IP_REACH, "Multi-Topology IPv4 Reachability"}, + { ISIS_TLV_IP6_REACH, "IPv6 reachability"}, + { ISIS_TLV_MT_IP6_REACH, "Multi-Topology IP6 Reachability"}, + { ISIS_TLV_PTP_ADJ, "Point-to-point Adjacency State"}, + { ISIS_TLV_IIH_SEQNR, "Hello PDU Sequence Number"}, + { ISIS_TLV_VENDOR_PRIVATE, "Vendor Private"}, + { 0, NULL } +}; + +#define ESIS_OPTION_PROTOCOLS 129 +#define ESIS_OPTION_QOS_MAINTENANCE 195 /* iso9542 */ +#define ESIS_OPTION_SECURITY 197 /* iso9542 */ +#define ESIS_OPTION_ES_CONF_TIME 198 /* iso9542 */ +#define ESIS_OPTION_PRIORITY 205 /* iso9542 */ +#define ESIS_OPTION_ADDRESS_MASK 225 /* iso9542 */ +#define ESIS_OPTION_SNPA_MASK 226 /* iso9542 */ + +static struct tok esis_option_values[] = { + { ESIS_OPTION_PROTOCOLS, "Protocols supported"}, + { ESIS_OPTION_QOS_MAINTENANCE, "QoS Maintenance" }, + { ESIS_OPTION_SECURITY, "Security" }, + { ESIS_OPTION_ES_CONF_TIME, "ES Configuration Time" }, + { ESIS_OPTION_PRIORITY, "Priority" }, + { ESIS_OPTION_ADDRESS_MASK, "Addressk Mask" }, + { ESIS_OPTION_SNPA_MASK, "SNPA Mask" }, + { 0, NULL } +}; + +#define CLNP_OPTION_DISCARD_REASON 193 +#define CLNP_OPTION_QOS_MAINTENANCE 195 /* iso8473 */ +#define CLNP_OPTION_SECURITY 197 /* iso8473 */ +#define CLNP_OPTION_SOURCE_ROUTING 200 /* iso8473 */ +#define CLNP_OPTION_ROUTE_RECORDING 203 /* iso8473 */ +#define CLNP_OPTION_PADDING 204 /* iso8473 */ +#define CLNP_OPTION_PRIORITY 205 /* iso8473 */ + +static struct tok clnp_option_values[] = { + { CLNP_OPTION_DISCARD_REASON, "Discard Reason"}, + { CLNP_OPTION_PRIORITY, "Priority"}, + { CLNP_OPTION_QOS_MAINTENANCE, "QoS Maintenance"}, + { CLNP_OPTION_SECURITY, "Security"}, + { CLNP_OPTION_SOURCE_ROUTING, "Source Routing"}, + { CLNP_OPTION_ROUTE_RECORDING, "Route Recording"}, + { CLNP_OPTION_PADDING, "Padding"}, + { 0, NULL } +}; + +static struct tok clnp_option_rfd_class_values[] = { + { 0x0, "General"}, + { 0x8, "Address"}, + { 0x9, "Source Routeing"}, + { 0xa, "Lifetime"}, + { 0xb, "PDU Discarded"}, + { 0xc, "Reassembly"}, + { 0, NULL } +}; + +static struct tok clnp_option_rfd_general_values[] = { + { 0x0, "Reason not specified"}, + { 0x1, "Protocol procedure error"}, + { 0x2, "Incorrect checksum"}, + { 0x3, "PDU discarded due to congestion"}, + { 0x4, "Header syntax error (cannot be parsed)"}, + { 0x5, "Segmentation needed but not permitted"}, + { 0x6, "Incomplete PDU received"}, + { 0x7, "Duplicate option"}, + { 0, NULL } +}; + +static struct tok clnp_option_rfd_address_values[] = { + { 0x0, "Destination address unreachable"}, + { 0x1, "Destination address unknown"}, + { 0, NULL } +}; + +static struct tok clnp_option_rfd_source_routeing_values[] = { + { 0x0, "Unspecified source routeing error"}, + { 0x1, "Syntax error in source routeing field"}, + { 0x2, "Unknown address in source routeing field"}, + { 0x3, "Path not acceptable"}, + { 0, NULL } +}; + +static struct tok clnp_option_rfd_lifetime_values[] = { + { 0x0, "Lifetime expired while data unit in transit"}, + { 0x1, "Lifetime expired during reassembly"}, + { 0, NULL } +}; + +static struct tok clnp_option_rfd_pdu_discard_values[] = { + { 0x0, "Unsupported option not specified"}, + { 0x1, "Unsupported protocol version"}, + { 0x2, "Unsupported security option"}, + { 0x3, "Unsupported source routeing option"}, + { 0x4, "Unsupported recording of route option"}, + { 0, NULL } +}; + +static struct tok clnp_option_rfd_reassembly_values[] = { + { 0x0, "Reassembly interference"}, + { 0, NULL } +}; + +/* array of 16 error-classes */ +static struct tok *clnp_option_rfd_error_class[] = { + clnp_option_rfd_general_values, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + clnp_option_rfd_address_values, + clnp_option_rfd_source_routeing_values, + clnp_option_rfd_lifetime_values, + clnp_option_rfd_pdu_discard_values, + clnp_option_rfd_reassembly_values, + NULL, + NULL, + NULL +}; + +#define CLNP_OPTION_OPTION_QOS_MASK 0x3f +#define CLNP_OPTION_SCOPE_MASK 0xc0 +#define CLNP_OPTION_SCOPE_SA_SPEC 0x40 +#define CLNP_OPTION_SCOPE_DA_SPEC 0x80 +#define CLNP_OPTION_SCOPE_GLOBAL 0xc0 + +static struct tok clnp_option_scope_values[] = { + { CLNP_OPTION_SCOPE_SA_SPEC, "Source Address Specific"}, + { CLNP_OPTION_SCOPE_DA_SPEC, "Destination Address Specific"}, + { CLNP_OPTION_SCOPE_GLOBAL, "Globally unique"}, + { 0, NULL } +}; + +static struct tok clnp_option_sr_rr_values[] = { + { 0x0, "partial"}, + { 0x1, "complete"}, + { 0, NULL } +}; + +static struct tok clnp_option_sr_rr_string_values[] = { + { CLNP_OPTION_SOURCE_ROUTING, "source routing"}, + { CLNP_OPTION_ROUTE_RECORDING, "recording of route in progress"}, + { 0, NULL } +}; + +static struct tok clnp_option_qos_global_values[] = { + { 0x20, "reserved"}, + { 0x10, "sequencing vs. delay"}, + { 0x08, "congested"}, + { 0x04, "delay vs. cost"}, + { 0x02, "error vs. delay"}, + { 0x01, "error vs. cost"}, + { 0, NULL } +}; + +#define ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID 4 /* rfc4205 */ +#define ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11 /* rfc4124 */ +#define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD 12 /* draft-ietf-tewg-diff-te-proto-06 */ +#define ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC 18 /* draft-ietf-isis-traffic-05 */ +#define ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE 19 /* draft-ietf-isis-link-attr-01 */ +#define ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20 /* rfc4205 */ +#define ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21 /* rfc4205 */ +#define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS 22 /* rfc4124 */ + +static struct tok isis_ext_is_reach_subtlv_values[] = { + { ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP, "Administrative groups" }, + { ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" }, + { ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID, "Link Remote Identifier" }, + { ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR, "IPv4 interface address" }, + { ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR, "IPv4 neighbor address" }, + { ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW, "Maximum link bandwidth" }, + { ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW, "Reservable link bandwidth" }, + { ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW, "Unreserved bandwidth" }, + { ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC, "Traffic Engineering Metric" }, + { ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE, "Link Attribute" }, + { ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE, "Link Protection Type" }, + { ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR, "Interface Switching Capability" }, + { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD, "Bandwidth Constraints (old)" }, + { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS, "Bandwidth Constraints" }, + { 250, "Reserved for cisco specific extensions" }, + { 251, "Reserved for cisco specific extensions" }, + { 252, "Reserved for cisco specific extensions" }, + { 253, "Reserved for cisco specific extensions" }, + { 254, "Reserved for cisco specific extensions" }, + { 255, "Reserved for future expansion" }, + { 0, NULL } +}; + +#define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32 1 /* draft-ietf-isis-admin-tags-01 */ +#define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64 2 /* draft-ietf-isis-admin-tags-01 */ +#define ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR 117 /* draft-ietf-isis-wg-multi-topology-05 */ + +static struct tok isis_ext_ip_reach_subtlv_values[] = { + { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32, "32-Bit Administrative tag" }, + { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64, "64-Bit Administrative tag" }, + { ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR, "Management Prefix Color" }, + { 0, NULL } +}; + +static struct tok isis_subtlv_link_attribute_values[] = { + { 0x01, "Local Protection Available" }, + { 0x02, "Link excluded from local protection path" }, + { 0x04, "Local maintenance required"}, + { 0, NULL } +}; + +#define ISIS_SUBTLV_AUTH_SIMPLE 1 +#define ISIS_SUBTLV_AUTH_MD5 54 +#define ISIS_SUBTLV_AUTH_MD5_LEN 16 +#define ISIS_SUBTLV_AUTH_PRIVATE 255 + +static struct tok isis_subtlv_auth_values[] = { + { ISIS_SUBTLV_AUTH_SIMPLE, "simple text password"}, + { ISIS_SUBTLV_AUTH_MD5, "HMAC-MD5 password"}, + { ISIS_SUBTLV_AUTH_PRIVATE, "Routing Domain private password"}, + { 0, NULL } +}; + +#define ISIS_SUBTLV_IDRP_RES 0 +#define ISIS_SUBTLV_IDRP_LOCAL 1 +#define ISIS_SUBTLV_IDRP_ASN 2 + +static struct tok isis_subtlv_idrp_values[] = { + { ISIS_SUBTLV_IDRP_RES, "Reserved"}, + { ISIS_SUBTLV_IDRP_LOCAL, "Routing-Domain Specific"}, + { ISIS_SUBTLV_IDRP_ASN, "AS Number Tag"}, + { 0, NULL} +}; + +#define CLNP_SEGMENT_PART 0x80 +#define CLNP_MORE_SEGMENTS 0x40 +#define CLNP_REQUEST_ER 0x20 + +static struct tok clnp_flag_values[] = { + { CLNP_SEGMENT_PART, "Segmentation permitted"}, + { CLNP_MORE_SEGMENTS, "more Segments"}, + { CLNP_REQUEST_ER, "request Error Report"}, + { 0, NULL} +}; + +#define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4) +#define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3) +#define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80) +#define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78) +#define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40) +#define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20) +#define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10) +#define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8) + +#define ISIS_MASK_MTID(x) ((x)&0x0fff) +#define ISIS_MASK_MTFLAGS(x) ((x)&0xf000) + +static struct tok isis_mt_flag_values[] = { + { 0x4000, "sub-TLVs present"}, + { 0x8000, "ATT bit set"}, + { 0, NULL} +}; + +#define ISIS_MASK_TLV_EXTD_IP_UPDOWN(x) ((x)&0x80) +#define ISIS_MASK_TLV_EXTD_IP_SUBTLV(x) ((x)&0x40) + +#define ISIS_MASK_TLV_EXTD_IP6_IE(x) ((x)&0x40) +#define ISIS_MASK_TLV_EXTD_IP6_SUBTLV(x) ((x)&0x20) + +#define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80) +#define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40) +#define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80) +#define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f) + +#define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1) + +static struct tok isis_mt_values[] = { + { 0, "IPv4 unicast"}, + { 1, "In-Band Management"}, + { 2, "IPv6 unicast"}, + { 3, "Multicast"}, + { 4095, "Development, Experimental or Proprietary"}, + { 0, NULL } +}; + +static struct tok isis_iih_circuit_type_values[] = { + { 1, "Level 1 only"}, + { 2, "Level 2 only"}, + { 3, "Level 1, Level 2"}, + { 0, NULL} +}; + +#define ISIS_LSP_TYPE_UNUSED0 0 +#define ISIS_LSP_TYPE_LEVEL_1 1 +#define ISIS_LSP_TYPE_UNUSED2 2 +#define ISIS_LSP_TYPE_LEVEL_2 3 + +static struct tok isis_lsp_istype_values[] = { + { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"}, + { ISIS_LSP_TYPE_LEVEL_1, "L1 IS"}, + { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"}, + { ISIS_LSP_TYPE_LEVEL_2, "L2 IS"}, + { 0, NULL } +}; + +/* + * Katz's point to point adjacency TLV uses codes to tell us the state of + * the remote adjacency. Enumerate them. + */ + +#define ISIS_PTP_ADJ_UP 0 +#define ISIS_PTP_ADJ_INIT 1 +#define ISIS_PTP_ADJ_DOWN 2 + +static struct tok isis_ptp_adjancey_values[] = { + { ISIS_PTP_ADJ_UP, "Up" }, + { ISIS_PTP_ADJ_INIT, "Initializing" }, + { ISIS_PTP_ADJ_DOWN, "Down" }, + { 0, NULL} +}; + +struct isis_tlv_ptp_adj { + u_int8_t adjacency_state; + u_int8_t extd_local_circuit_id[4]; + u_int8_t neighbor_sysid[SYSTEM_ID_LEN]; + u_int8_t neighbor_extd_local_circuit_id[4]; +}; + +static void osi_print_cksum(const u_int8_t *pptr, u_int16_t checksum, + u_int checksum_offset, u_int length); +static int clnp_print(const u_int8_t *, u_int); +static void esis_print(const u_int8_t *, u_int); +static int isis_print(const u_int8_t *, u_int); + +struct isis_metric_block { + u_int8_t metric_default; + u_int8_t metric_delay; + u_int8_t metric_expense; + u_int8_t metric_error; +}; + +struct isis_tlv_is_reach { + struct isis_metric_block isis_metric_block; + u_int8_t neighbor_nodeid[NODE_ID_LEN]; +}; + +struct isis_tlv_es_reach { + struct isis_metric_block isis_metric_block; + u_int8_t neighbor_sysid[SYSTEM_ID_LEN]; +}; + +struct isis_tlv_ip_reach { + struct isis_metric_block isis_metric_block; + u_int8_t prefix[4]; + u_int8_t mask[4]; +}; + +static struct tok isis_is_reach_virtual_values[] = { + { 0, "IsNotVirtual"}, + { 1, "IsVirtual"}, + { 0, NULL } +}; + +static struct tok isis_restart_flag_values[] = { + { 0x1, "Restart Request"}, + { 0x2, "Restart Acknowledgement"}, + { 0x4, "Suppress adjacency advertisement"}, + { 0, NULL } +}; + +struct isis_common_header { + u_int8_t nlpid; + u_int8_t fixed_len; + u_int8_t version; /* Protocol version */ + u_int8_t id_length; + u_int8_t pdu_type; /* 3 MSbits are reserved */ + u_int8_t pdu_version; /* Packet format version */ + u_int8_t reserved; + u_int8_t max_area; +}; + +struct isis_iih_lan_header { + u_int8_t circuit_type; + u_int8_t source_id[SYSTEM_ID_LEN]; + u_int8_t holding_time[2]; + u_int8_t pdu_len[2]; + u_int8_t priority; + u_int8_t lan_id[NODE_ID_LEN]; +}; + +struct isis_iih_ptp_header { + u_int8_t circuit_type; + u_int8_t source_id[SYSTEM_ID_LEN]; + u_int8_t holding_time[2]; + u_int8_t pdu_len[2]; + u_int8_t circuit_id; +}; + +struct isis_lsp_header { + u_int8_t pdu_len[2]; + u_int8_t remaining_lifetime[2]; + u_int8_t lsp_id[LSP_ID_LEN]; + u_int8_t sequence_number[4]; + u_int8_t checksum[2]; + u_int8_t typeblock; +}; + +struct isis_csnp_header { + u_int8_t pdu_len[2]; + u_int8_t source_id[NODE_ID_LEN]; + u_int8_t start_lsp_id[LSP_ID_LEN]; + u_int8_t end_lsp_id[LSP_ID_LEN]; +}; + +struct isis_psnp_header { + u_int8_t pdu_len[2]; + u_int8_t source_id[NODE_ID_LEN]; +}; + +struct isis_tlv_lsp { + u_int8_t remaining_lifetime[2]; + u_int8_t lsp_id[LSP_ID_LEN]; + u_int8_t sequence_number[4]; + u_int8_t checksum[2]; +}; + +#define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header)) +#define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header)) +#define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header)) +#define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header)) +#define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header)) +#define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header)) + +void isoclns_print(const u_int8_t *p, u_int length, u_int caplen) +{ + const struct isis_common_header *header; + + header = (const struct isis_common_header *)p; + + if (caplen <= 1) { /* enough bytes on the wire ? */ + printf("|OSI"); + return; + } + + if (eflag) + printf("OSI NLPID %s (0x%02x): ", + tok2str(nlpid_values,"Unknown",*p), + *p); + + switch (*p) { + + case NLPID_CLNP: + if (!clnp_print(p, length)) + print_unknown_data(p,"\n\t",caplen); + break; + + case NLPID_ESIS: + esis_print(p, length); + return; + + case NLPID_ISIS: + if (!isis_print(p, length)) + print_unknown_data(p,"\n\t",caplen); + break; + + case NLPID_NULLNS: + (void)printf("%slength: %u", + eflag ? "" : ", ", + length); + break; + + case NLPID_Q933: + q933_print(p+1, length-1); + break; + + case NLPID_IP: + ip_print(gndo, p+1, length-1); + break; + +#ifdef INET6 + case NLPID_IP6: + ip6_print(p+1, length-1); + break; +#endif + + case NLPID_PPP: + ppp_print(p+1, length-1); + break; + + default: + if (!eflag) + printf("OSI NLPID 0x%02x unknown",*p); + (void)printf("%slength: %u", + eflag ? "" : ", ", + length); + if (caplen > 1) + print_unknown_data(p,"\n\t",caplen); + break; + } +} + +#define CLNP_PDU_ER 1 +#define CLNP_PDU_DT 28 +#define CLNP_PDU_MD 29 +#define CLNP_PDU_ERQ 30 +#define CLNP_PDU_ERP 31 + +static struct tok clnp_pdu_values[] = { + { CLNP_PDU_ER, "Error Report"}, + { CLNP_PDU_MD, "MD"}, + { CLNP_PDU_DT, "Data"}, + { CLNP_PDU_ERQ, "Echo Request"}, + { CLNP_PDU_ERP, "Echo Response"}, + { 0, NULL } +}; + +struct clnp_header_t { + u_int8_t nlpid; + u_int8_t length_indicator; + u_int8_t version; + u_int8_t lifetime; /* units of 500ms */ + u_int8_t type; + u_int8_t segment_length[2]; + u_int8_t cksum[2]; +}; + +struct clnp_segment_header_t { + u_int8_t data_unit_id[2]; + u_int8_t segment_offset[2]; + u_int8_t total_length[2]; +}; + +/* + * clnp_print + * Decode CLNP packets. Return 0 on error. + */ + +static int clnp_print (const u_int8_t *pptr, u_int length) +{ + const u_int8_t *optr,*source_address,*dest_address; + u_int li,tlen,nsap_offset,source_address_length,dest_address_length, clnp_pdu_type, clnp_flags; + const struct clnp_header_t *clnp_header; + const struct clnp_segment_header_t *clnp_segment_header; + u_int8_t rfd_error_major,rfd_error_minor; + + clnp_header = (const struct clnp_header_t *) pptr; + TCHECK(*clnp_header); + + li = clnp_header->length_indicator; + optr = pptr; + + if (!eflag) + printf("CLNP"); + + /* + * Sanity checking of the header. + */ + + if (clnp_header->version != CLNP_VERSION) { + printf("version %d packet not supported", clnp_header->version); + return (0); + } + + /* FIXME further header sanity checking */ + + clnp_pdu_type = clnp_header->type & CLNP_PDU_TYPE_MASK; + clnp_flags = clnp_header->type & CLNP_FLAG_MASK; + + pptr += sizeof(struct clnp_header_t); + li -= sizeof(struct clnp_header_t); + dest_address_length = *pptr; + dest_address = pptr + 1; + + pptr += (1 + dest_address_length); + li -= (1 + dest_address_length); + source_address_length = *pptr; + source_address = pptr +1; + + pptr += (1 + source_address_length); + li -= (1 + source_address_length); + + if (vflag < 1) { + printf("%s%s > %s, %s, length %u", + eflag ? "" : ", ", + isonsap_string(source_address, source_address_length), + isonsap_string(dest_address, dest_address_length), + tok2str(clnp_pdu_values,"unknown (%u)",clnp_pdu_type), + length); + return (1); + } + printf("%slength %u",eflag ? "" : ", ",length); + + printf("\n\t%s PDU, hlen: %u, v: %u, lifetime: %u.%us, Segment PDU length: %u, checksum: 0x%04x", + tok2str(clnp_pdu_values, "unknown (%u)",clnp_pdu_type), + clnp_header->length_indicator, + clnp_header->version, + clnp_header->lifetime/2, + (clnp_header->lifetime%2)*5, + EXTRACT_16BITS(clnp_header->segment_length), + EXTRACT_16BITS(clnp_header->cksum)); + + osi_print_cksum(optr, EXTRACT_16BITS(clnp_header->cksum), 7, + clnp_header->length_indicator); + + printf("\n\tFlags [%s]", + bittok2str(clnp_flag_values,"none",clnp_flags)); + + printf("\n\tsource address (length %u): %s\n\tdest address (length %u): %s", + source_address_length, + isonsap_string(source_address, source_address_length), + dest_address_length, + isonsap_string(dest_address,dest_address_length)); + + if (clnp_flags & CLNP_SEGMENT_PART) { + clnp_segment_header = (const struct clnp_segment_header_t *) pptr; + TCHECK(*clnp_segment_header); + printf("\n\tData Unit ID: 0x%04x, Segment Offset: %u, Total PDU Length: %u", + EXTRACT_16BITS(clnp_segment_header->data_unit_id), + EXTRACT_16BITS(clnp_segment_header->segment_offset), + EXTRACT_16BITS(clnp_segment_header->total_length)); + pptr+=sizeof(const struct clnp_segment_header_t); + li-=sizeof(const struct clnp_segment_header_t); + } + + /* now walk the options */ + while (li >= 2) { + u_int op, opli; + const u_int8_t *tptr; + + TCHECK2(*pptr, 2); + if (li < 2) { + printf(", bad opts/li"); + return (0); + } + op = *pptr++; + opli = *pptr++; + li -= 2; + TCHECK2(*pptr, opli); + if (opli > li) { + printf(", opt (%d) too long", op); + return (0); + } + li -= opli; + tptr = pptr; + tlen = opli; + + printf("\n\t %s Option #%u, length %u, value: ", + tok2str(clnp_option_values,"Unknown",op), + op, + opli); + + switch (op) { + + + case CLNP_OPTION_ROUTE_RECORDING: /* those two options share the format */ + case CLNP_OPTION_SOURCE_ROUTING: + printf("%s %s", + tok2str(clnp_option_sr_rr_values,"Unknown",*tptr), + tok2str(clnp_option_sr_rr_string_values,"Unknown Option %u",op)); + nsap_offset=*(tptr+1); + if (nsap_offset == 0) { + printf(" Bad NSAP offset (0)"); + break; + } + nsap_offset-=1; /* offset to nsap list */ + if (nsap_offset > tlen) { + printf(" Bad NSAP offset (past end of option)"); + break; + } + tptr+=nsap_offset; + tlen-=nsap_offset; + while (tlen > 0) { + source_address_length=*tptr; + if (tlen < source_address_length+1) { + printf("\n\t NSAP address goes past end of option"); + break; + } + if (source_address_length > 0) { + source_address=(tptr+1); + TCHECK2(*source_address, source_address_length); + printf("\n\t NSAP address (length %u): %s", + source_address_length, + isonsap_string(source_address, source_address_length)); + } + tlen-=source_address_length+1; + } + break; + + case CLNP_OPTION_PRIORITY: + printf("0x%1x", *tptr&0x0f); + break; + + case CLNP_OPTION_QOS_MAINTENANCE: + printf("\n\t Format Code: %s", + tok2str(clnp_option_scope_values,"Reserved",*tptr&CLNP_OPTION_SCOPE_MASK)); + + if ((*tptr&CLNP_OPTION_SCOPE_MASK) == CLNP_OPTION_SCOPE_GLOBAL) + printf("\n\t QoS Flags [%s]", + bittok2str(clnp_option_qos_global_values, + "none", + *tptr&CLNP_OPTION_OPTION_QOS_MASK)); + break; + + case CLNP_OPTION_SECURITY: + printf("\n\t Format Code: %s, Security-Level %u", + tok2str(clnp_option_scope_values,"Reserved",*tptr&CLNP_OPTION_SCOPE_MASK), + *(tptr+1)); + break; + + case CLNP_OPTION_DISCARD_REASON: + rfd_error_major = (*tptr&0xf0) >> 4; + rfd_error_minor = *tptr&0x0f; + printf("\n\t Class: %s Error (0x%01x), %s (0x%01x)", + tok2str(clnp_option_rfd_class_values,"Unknown",rfd_error_major), + rfd_error_major, + tok2str(clnp_option_rfd_error_class[rfd_error_major],"Unknown",rfd_error_minor), + rfd_error_minor); + break; + + case CLNP_OPTION_PADDING: + printf("padding data"); + break; + + /* + * FIXME those are the defined Options that lack a decoder + * you are welcome to contribute code ;-) + */ + + default: + print_unknown_data(tptr,"\n\t ",opli); + break; + } + if (vflag > 1) + print_unknown_data(pptr,"\n\t ",opli); + pptr += opli; + } + + switch (clnp_pdu_type) { + + case CLNP_PDU_ER: /* fall through */ + case CLNP_PDU_ERP: + TCHECK(*pptr); + if (*(pptr) == NLPID_CLNP) { + printf("\n\t-----original packet-----\n\t"); + /* FIXME recursion protection */ + clnp_print(pptr, length-clnp_header->length_indicator); + break; + } + + case CLNP_PDU_DT: + case CLNP_PDU_MD: + case CLNP_PDU_ERQ: + + default: + /* dump the PDU specific data */ + if (length-(pptr-optr) > 0) { + printf("\n\t undecoded non-header data, length %u",length-clnp_header->length_indicator); + print_unknown_data(pptr,"\n\t ",length-(pptr-optr)); + } + } + + return (1); + + trunc: + fputs("[|clnp]", stdout); + return (1); + +} + + +#define ESIS_PDU_REDIRECT 6 +#define ESIS_PDU_ESH 2 +#define ESIS_PDU_ISH 4 + +static struct tok esis_pdu_values[] = { + { ESIS_PDU_REDIRECT, "redirect"}, + { ESIS_PDU_ESH, "ESH"}, + { ESIS_PDU_ISH, "ISH"}, + { 0, NULL } +}; + +struct esis_header_t { + u_int8_t nlpid; + u_int8_t length_indicator; + u_int8_t version; + u_int8_t reserved; + u_int8_t type; + u_int8_t holdtime[2]; + u_int8_t cksum[2]; +}; + +static void +esis_print(const u_int8_t *pptr, u_int length) +{ + const u_int8_t *optr; + u_int li,esis_pdu_type,source_address_length, source_address_number; + const struct esis_header_t *esis_header; + + if (!eflag) + printf("ES-IS"); + + if (length <= 2) { + if (qflag) + printf("bad pkt!"); + else + printf("no header at all!"); + return; + } + + esis_header = (const struct esis_header_t *) pptr; + TCHECK(*esis_header); + li = esis_header->length_indicator; + optr = pptr; + + /* + * Sanity checking of the header. + */ + + if (esis_header->nlpid != NLPID_ESIS) { + printf(" nlpid 0x%02x packet not supported", esis_header->nlpid); + return; + } + + if (esis_header->version != ESIS_VERSION) { + printf(" version %d packet not supported", esis_header->version); + return; + } + + if (li > length) { + printf(" length indicator(%d) > PDU size (%d)!", li, length); + return; + } + + if (li < sizeof(struct esis_header_t) + 2) { + printf(" length indicator < min PDU size %d:", li); + while (--length != 0) + printf("%02X", *pptr++); + return; + } + + esis_pdu_type = esis_header->type & ESIS_PDU_TYPE_MASK; + + if (vflag < 1) { + printf("%s%s, length %u", + eflag ? "" : ", ", + tok2str(esis_pdu_values,"unknown type (%u)",esis_pdu_type), + length); + return; + } else + printf("%slength %u\n\t%s (%u)", + eflag ? "" : ", ", + length, + tok2str(esis_pdu_values,"unknown type: %u", esis_pdu_type), + esis_pdu_type); + + printf(", v: %u%s", esis_header->version, esis_header->version == ESIS_VERSION ? "" : "unsupported" ); + printf(", checksum: 0x%04x", EXTRACT_16BITS(esis_header->cksum)); + + osi_print_cksum(pptr, EXTRACT_16BITS(esis_header->cksum), 7, li); + + printf(", holding time: %us, length indicator: %u",EXTRACT_16BITS(esis_header->holdtime),li); + + if (vflag > 1) + print_unknown_data(optr,"\n\t",sizeof(struct esis_header_t)); + + pptr += sizeof(struct esis_header_t); + li -= sizeof(struct esis_header_t); + + switch (esis_pdu_type) { + case ESIS_PDU_REDIRECT: { + const u_int8_t *dst, *snpa, *neta; + u_int dstl, snpal, netal; + + TCHECK(*pptr); + if (li < 1) { + printf(", bad redirect/li"); + return; + } + dstl = *pptr; + pptr++; + li--; + TCHECK2(*pptr, dstl); + if (li < dstl) { + printf(", bad redirect/li"); + return; + } + dst = pptr; + pptr += dstl; + li -= dstl; + printf("\n\t %s", isonsap_string(dst,dstl)); + + TCHECK(*pptr); + if (li < 1) { + printf(", bad redirect/li"); + return; + } + snpal = *pptr; + pptr++; + li--; + TCHECK2(*pptr, snpal); + if (li < snpal) { + printf(", bad redirect/li"); + return; + } + snpa = pptr; + pptr += snpal; + li -= snpal; + TCHECK(*pptr); + if (li < 1) { + printf(", bad redirect/li"); + return; + } + netal = *pptr; + pptr++; + TCHECK2(*pptr, netal); + if (li < netal) { + printf(", bad redirect/li"); + return; + } + neta = pptr; + pptr += netal; + li -= netal; + + if (netal == 0) + printf("\n\t %s", etheraddr_string(snpa)); + else + printf("\n\t %s", isonsap_string(neta,netal)); + break; + } + + case ESIS_PDU_ESH: + TCHECK(*pptr); + if (li < 1) { + printf(", bad esh/li"); + return; + } + source_address_number = *pptr; + pptr++; + li--; + + printf("\n\t Number of Source Addresses: %u", source_address_number); + + while (source_address_number > 0) { + TCHECK(*pptr); + if (li < 1) { + printf(", bad esh/li"); + return; + } + source_address_length = *pptr; + pptr++; + li--; + + TCHECK2(*pptr, source_address_length); + if (li < source_address_length) { + printf(", bad esh/li"); + return; + } + printf("\n\t NET (length: %u): %s", + source_address_length, + isonsap_string(pptr,source_address_length)); + pptr += source_address_length; + li -= source_address_length; + source_address_number--; + } + + break; + + case ESIS_PDU_ISH: { + TCHECK(*pptr); + if (li < 1) { + printf(", bad ish/li"); + return; + } + source_address_length = *pptr; + pptr++; + li--; + TCHECK2(*pptr, source_address_length); + if (li < source_address_length) { + printf(", bad ish/li"); + return; + } + printf("\n\t NET (length: %u): %s", source_address_length, isonsap_string(pptr, source_address_length)); + pptr += source_address_length; + li -= source_address_length; + break; + } + + default: + if (vflag <= 1) { + if (pptr < snapend) + print_unknown_data(pptr,"\n\t ",snapend-pptr); + } + return; + } + + /* now walk the options */ + while (li >= 2) { + u_int op, opli; + const u_int8_t *tptr; + + TCHECK2(*pptr, 2); + if (li < 2) { + printf(", bad opts/li"); + return; + } + op = *pptr++; + opli = *pptr++; + li -= 2; + if (opli > li) { + printf(", opt (%d) too long", op); + return; + } + li -= opli; + tptr = pptr; + + printf("\n\t %s Option #%u, length %u, value: ", + tok2str(esis_option_values,"Unknown",op), + op, + opli); + + switch (op) { + + case ESIS_OPTION_ES_CONF_TIME: + TCHECK2(*pptr, 2); + printf("%us", EXTRACT_16BITS(tptr)); + break; + + case ESIS_OPTION_PROTOCOLS: + while (opli>0) { + TCHECK(*pptr); + printf("%s (0x%02x)", + tok2str(nlpid_values, + "unknown", + *tptr), + *tptr); + if (opli>1) /* further NPLIDs ? - put comma */ + printf(", "); + tptr++; + opli--; + } + break; + + /* + * FIXME those are the defined Options that lack a decoder + * you are welcome to contribute code ;-) + */ + + case ESIS_OPTION_QOS_MAINTENANCE: + case ESIS_OPTION_SECURITY: + case ESIS_OPTION_PRIORITY: + case ESIS_OPTION_ADDRESS_MASK: + case ESIS_OPTION_SNPA_MASK: + + default: + print_unknown_data(tptr,"\n\t ",opli); + break; + } + if (vflag > 1) + print_unknown_data(pptr,"\n\t ",opli); + pptr += opli; + } +trunc: + return; +} + +/* shared routine for printing system, node and lsp-ids */ +static char * +isis_print_id(const u_int8_t *cp, int id_len) +{ + int i; + static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")]; + char *pos = id; + + for (i = 1; i <= SYSTEM_ID_LEN; i++) { + snprintf(pos, sizeof(id) - (pos - id), "%02x", *cp++); + pos += strlen(pos); + if (i == 2 || i == 4) + *pos++ = '.'; + } + if (id_len >= NODE_ID_LEN) { + snprintf(pos, sizeof(id) - (pos - id), ".%02x", *cp++); + pos += strlen(pos); + } + if (id_len == LSP_ID_LEN) + snprintf(pos, sizeof(id) - (pos - id), "-%02x", *cp); + return (id); +} + +/* print the 4-byte metric block which is common found in the old-style TLVs */ +static int +isis_print_metric_block (const struct isis_metric_block *isis_metric_block) +{ + printf(", Default Metric: %d, %s", + ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_default), + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_default) ? "External" : "Internal"); + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_delay)) + printf("\n\t\t Delay Metric: %d, %s", + ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_delay), + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_delay) ? "External" : "Internal"); + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_expense)) + printf("\n\t\t Expense Metric: %d, %s", + ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_expense), + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_expense) ? "External" : "Internal"); + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_error)) + printf("\n\t\t Error Metric: %d, %s", + ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_error), + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_error) ? "External" : "Internal"); + + return(1); /* everything is ok */ +} + +static int +isis_print_tlv_ip_reach (const u_int8_t *cp, const char *ident, int length) +{ + int prefix_len; + const struct isis_tlv_ip_reach *tlv_ip_reach; + + tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp; + + while (length > 0) { + if ((size_t)length < sizeof(*tlv_ip_reach)) { + printf("short IPv4 Reachability (%d vs %lu)", + length, + (unsigned long)sizeof(*tlv_ip_reach)); + return (0); + } + + if (!TTEST(*tlv_ip_reach)) + return (0); + + prefix_len = mask2plen(EXTRACT_32BITS(tlv_ip_reach->mask)); + + if (prefix_len == -1) + printf("%sIPv4 prefix: %s mask %s", + ident, + ipaddr_string((tlv_ip_reach->prefix)), + ipaddr_string((tlv_ip_reach->mask))); + else + printf("%sIPv4 prefix: %15s/%u", + ident, + ipaddr_string((tlv_ip_reach->prefix)), + prefix_len); + + printf(", Distribution: %s, Metric: %u, %s", + ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->isis_metric_block.metric_default) ? "down" : "up", + ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_default), + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_default) ? "External" : "Internal"); + + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_delay)) + printf("%s Delay Metric: %u, %s", + ident, + ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_delay), + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_delay) ? "External" : "Internal"); + + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_expense)) + printf("%s Expense Metric: %u, %s", + ident, + ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_expense), + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_expense) ? "External" : "Internal"); + + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_error)) + printf("%s Error Metric: %u, %s", + ident, + ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_error), + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_error) ? "External" : "Internal"); + + length -= sizeof(struct isis_tlv_ip_reach); + tlv_ip_reach++; + } + return (1); +} + +/* + * this is the common IP-REACH subTLV decoder it is called + * from various EXTD-IP REACH TLVs (135,235,236,237) + */ + +static int +isis_print_ip_reach_subtlv (const u_int8_t *tptr,int subt,int subl,const char *ident) { + + /* first lets see if we know the subTLVs name*/ + printf("%s%s subTLV #%u, length: %u", + ident, + tok2str(isis_ext_ip_reach_subtlv_values, + "unknown", + subt), + subt, + subl); + + if (!TTEST2(*tptr,subl)) + goto trunctlv; + + switch(subt) { + case ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR: /* fall through */ + case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32: + while (subl >= 4) { + printf(", 0x%08x (=%u)", + EXTRACT_32BITS(tptr), + EXTRACT_32BITS(tptr)); + tptr+=4; + subl-=4; + } + break; + case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64: + while (subl >= 8) { + printf(", 0x%08x%08x", + EXTRACT_32BITS(tptr), + EXTRACT_32BITS(tptr+4)); + tptr+=8; + subl-=8; + } + break; + default: + if(!print_unknown_data(tptr,"\n\t\t ", + subl)) + return(0); + break; + } + return(1); + +trunctlv: + printf("%spacket exceeded snapshot",ident); + return(0); +} + +/* + * this is the common IS-REACH subTLV decoder it is called + * from isis_print_ext_is_reach() + */ + +static int +isis_print_is_reach_subtlv (const u_int8_t *tptr,u_int subt,u_int subl,const char *ident) { + + u_int te_class,priority_level,gmpls_switch_cap; + union { /* int to float conversion buffer for several subTLVs */ + float f; + u_int32_t i; + } bw; + + /* first lets see if we know the subTLVs name*/ + printf("%s%s subTLV #%u, length: %u", + ident, + tok2str(isis_ext_is_reach_subtlv_values, + "unknown", + subt), + subt, + subl); + + if (!TTEST2(*tptr,subl)) + goto trunctlv; + + switch(subt) { + case ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP: + case ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID: + case ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID: + if (subl >= 4) { + printf(", 0x%08x", EXTRACT_32BITS(tptr)); + if (subl == 8) /* rfc4205 */ + printf(", 0x%08x", EXTRACT_32BITS(tptr+4)); + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR: + case ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR: + if (subl >= sizeof(struct in_addr)) + printf(", %s", ipaddr_string(tptr)); + break; + case ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW : + case ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW: + if (subl >= 4) { + bw.i = EXTRACT_32BITS(tptr); + printf(", %.3f Mbps", bw.f*8/1000000 ); + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW : + if (subl >= 32) { + for (te_class = 0; te_class < 8; te_class++) { + bw.i = EXTRACT_32BITS(tptr); + printf("%s TE-Class %u: %.3f Mbps", + ident, + te_class, + bw.f*8/1000000 ); + tptr+=4; + } + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS: /* fall through */ + case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD: + printf("%sBandwidth Constraints Model ID: %s (%u)", + ident, + tok2str(diffserv_te_bc_values, "unknown", *tptr), + *tptr); + tptr++; + /* decode BCs until the subTLV ends */ + for (te_class = 0; te_class < (subl-1)/4; te_class++) { + bw.i = EXTRACT_32BITS(tptr); + printf("%s Bandwidth constraint CT%u: %.3f Mbps", + ident, + te_class, + bw.f*8/1000000 ); + tptr+=4; + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC: + if (subl >= 3) + printf(", %u", EXTRACT_24BITS(tptr)); + break; + case ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE: + if (subl == 2) { + printf(", [ %s ] (0x%04x)", + bittok2str(isis_subtlv_link_attribute_values, + "Unknown", + EXTRACT_16BITS(tptr)), + EXTRACT_16BITS(tptr)); + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE: + if (subl >= 2) { + printf(", %s, Priority %u", + bittok2str(gmpls_link_prot_values, "none", *tptr), + *(tptr+1)); + } + break; + case ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR: + if (subl >= 36) { + gmpls_switch_cap = *tptr; + printf("%s Interface Switching Capability:%s", + ident, + tok2str(gmpls_switch_cap_values, "Unknown", gmpls_switch_cap)); + printf(", LSP Encoding: %s", + tok2str(gmpls_encoding_values, "Unknown", *(tptr+1))); + tptr+=4; + printf("%s Max LSP Bandwidth:",ident); + for (priority_level = 0; priority_level < 8; priority_level++) { + bw.i = EXTRACT_32BITS(tptr); + printf("%s priority level %d: %.3f Mbps", + ident, + priority_level, + bw.f*8/1000000 ); + tptr+=4; + } + subl-=36; + switch (gmpls_switch_cap) { + case GMPLS_PSC1: + case GMPLS_PSC2: + case GMPLS_PSC3: + case GMPLS_PSC4: + bw.i = EXTRACT_32BITS(tptr); + printf("%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f*8/1000000); + printf("%s Interface MTU: %u", ident, EXTRACT_16BITS(tptr+4)); + break; + case GMPLS_TSC: + bw.i = EXTRACT_32BITS(tptr); + printf("%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f*8/1000000); + printf("%s Indication %s", ident, + tok2str(gmpls_switch_cap_tsc_indication_values, "Unknown (%u)", *(tptr+4))); + break; + default: + /* there is some optional stuff left to decode but this is as of yet + not specified so just lets hexdump what is left */ + if(subl>0){ + if(!print_unknown_data(tptr,"\n\t\t ", + subl)) + return(0); + } + } + } + break; + default: + if(!print_unknown_data(tptr,"\n\t\t ", + subl)) + return(0); + break; + } + return(1); + +trunctlv: + printf("%spacket exceeded snapshot",ident); + return(0); +} + + +/* + * this is the common IS-REACH decoder it is called + * from various EXTD-IS REACH style TLVs (22,24,222) + */ + +static int +isis_print_ext_is_reach (const u_int8_t *tptr,const char *ident, int tlv_type) { + + char ident_buffer[20]; + int subtlv_type,subtlv_len,subtlv_sum_len; + int proc_bytes = 0; /* how many bytes did we process ? */ + + if (!TTEST2(*tptr, NODE_ID_LEN)) + return(0); + + printf("%sIS Neighbor: %s", ident, isis_print_id(tptr, NODE_ID_LEN)); + tptr+=(NODE_ID_LEN); + + if (tlv_type != ISIS_TLV_IS_ALIAS_ID) { /* the Alias TLV Metric field is implicit 0 */ + if (!TTEST2(*tptr, 3)) /* and is therefore skipped */ + return(0); + printf(", Metric: %d",EXTRACT_24BITS(tptr)); + tptr+=3; + } + + if (!TTEST2(*tptr, 1)) + return(0); + subtlv_sum_len=*(tptr++); /* read out subTLV length */ + proc_bytes=NODE_ID_LEN+3+1; + printf(", %ssub-TLVs present",subtlv_sum_len ? "" : "no "); + if (subtlv_sum_len) { + printf(" (%u)",subtlv_sum_len); + while (subtlv_sum_len>0) { + if (!TTEST2(*tptr,2)) + return(0); + subtlv_type=*(tptr++); + subtlv_len=*(tptr++); + /* prepend the ident string */ + snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); + if(!isis_print_is_reach_subtlv(tptr,subtlv_type,subtlv_len,ident_buffer)) + return(0); + tptr+=subtlv_len; + subtlv_sum_len-=(subtlv_len+2); + proc_bytes+=(subtlv_len+2); + } + } + return(proc_bytes); +} + +/* + * this is the common Multi Topology ID decoder + * it is called from various MT-TLVs (222,229,235,237) + */ + +static int +isis_print_mtid (const u_int8_t *tptr,const char *ident) { + + if (!TTEST2(*tptr, 2)) + return(0); + + printf("%s%s", + ident, + tok2str(isis_mt_values, + "Reserved for IETF Consensus", + ISIS_MASK_MTID(EXTRACT_16BITS(tptr)))); + + printf(" Topology (0x%03x), Flags: [%s]", + ISIS_MASK_MTID(EXTRACT_16BITS(tptr)), + bittok2str(isis_mt_flag_values, "none",ISIS_MASK_MTFLAGS(EXTRACT_16BITS(tptr)))); + + return(2); +} + +/* + * this is the common extended IP reach decoder + * it is called from TLVs (135,235,236,237) + * we process the TLV and optional subTLVs and return + * the amount of processed bytes + */ + +static int +isis_print_extd_ip_reach (const u_int8_t *tptr, const char *ident, u_int16_t afi) { + + char ident_buffer[20]; +#ifdef INET6 + u_int8_t prefix[sizeof(struct in6_addr)]; /* shared copy buffer for IPv4 and IPv6 prefixes */ +#else + u_int8_t prefix[sizeof(struct in_addr)]; /* shared copy buffer for IPv4 prefixes */ +#endif + u_int metric, status_byte, bit_length, byte_length, sublen, processed, subtlvtype, subtlvlen; + + if (!TTEST2(*tptr, 4)) + return (0); + metric = EXTRACT_32BITS(tptr); + processed=4; + tptr+=4; + + if (afi == AF_INET) { + if (!TTEST2(*tptr, 1)) /* fetch status byte */ + return (0); + status_byte=*(tptr++); + bit_length = status_byte&0x3f; + if (bit_length > 32) { + printf("%sIPv4 prefix: bad bit length %u", + ident, + bit_length); + return (0); + } + processed++; +#ifdef INET6 + } else if (afi == AF_INET6) { + if (!TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */ + return (0); + status_byte=*(tptr++); + bit_length=*(tptr++); + if (bit_length > 128) { + printf("%sIPv6 prefix: bad bit length %u", + ident, + bit_length); + return (0); + } + processed+=2; +#endif + } else + return (0); /* somebody is fooling us */ + + byte_length = (bit_length + 7) / 8; /* prefix has variable length encoding */ + + if (!TTEST2(*tptr, byte_length)) + return (0); + memset(prefix, 0, sizeof prefix); /* clear the copy buffer */ + memcpy(prefix,tptr,byte_length); /* copy as much as is stored in the TLV */ + tptr+=byte_length; + processed+=byte_length; + + if (afi == AF_INET) + printf("%sIPv4 prefix: %15s/%u", + ident, + ipaddr_string(prefix), + bit_length); +#ifdef INET6 + if (afi == AF_INET6) + printf("%sIPv6 prefix: %s/%u", + ident, + ip6addr_string(prefix), + bit_length); +#endif + + printf(", Distribution: %s, Metric: %u", + ISIS_MASK_TLV_EXTD_IP_UPDOWN(status_byte) ? "down" : "up", + metric); + + if (afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte)) + printf(", sub-TLVs present"); +#ifdef INET6 + if (afi == AF_INET6) + printf(", %s%s", + ISIS_MASK_TLV_EXTD_IP6_IE(status_byte) ? "External" : "Internal", + ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) ? ", sub-TLVs present" : ""); +#endif + + if ((afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte)) +#ifdef INET6 + || (afi == AF_INET6 && ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte)) +#endif + ) { + /* assume that one prefix can hold more + than one subTLV - therefore the first byte must reflect + the aggregate bytecount of the subTLVs for this prefix + */ + if (!TTEST2(*tptr, 1)) + return (0); + sublen=*(tptr++); + processed+=sublen+1; + printf(" (%u)",sublen); /* print out subTLV length */ + + while (sublen>0) { + if (!TTEST2(*tptr,2)) + return (0); + subtlvtype=*(tptr++); + subtlvlen=*(tptr++); + /* prepend the ident string */ + snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); + if(!isis_print_ip_reach_subtlv(tptr,subtlvtype,subtlvlen,ident_buffer)) + return(0); + tptr+=subtlvlen; + sublen-=(subtlvlen+2); + } + } + return (processed); +} + +/* + * isis_print + * Decode IS-IS packets. Return 0 on error. + */ + +static int isis_print (const u_int8_t *p, u_int length) +{ + const struct isis_common_header *isis_header; + + const struct isis_iih_lan_header *header_iih_lan; + const struct isis_iih_ptp_header *header_iih_ptp; + struct isis_lsp_header *header_lsp; + const struct isis_csnp_header *header_csnp; + const struct isis_psnp_header *header_psnp; + + const struct isis_tlv_lsp *tlv_lsp; + const struct isis_tlv_ptp_adj *tlv_ptp_adj; + const struct isis_tlv_is_reach *tlv_is_reach; + const struct isis_tlv_es_reach *tlv_es_reach; + + u_int8_t pdu_type, max_area, id_length, tlv_type, tlv_len, tmp, alen, lan_alen, prefix_len; + u_int8_t ext_is_len, ext_ip_len, mt_len; + const u_int8_t *optr, *pptr, *tptr; + u_short packet_len,pdu_len; + u_int i,vendor_id; + int sigcheck; + + packet_len=length; + optr = p; /* initialize the _o_riginal pointer to the packet start - + need it for parsing the checksum TLV and authentication + TLV verification */ + isis_header = (const struct isis_common_header *)p; + TCHECK(*isis_header); + pptr = p+(ISIS_COMMON_HEADER_SIZE); + header_iih_lan = (const struct isis_iih_lan_header *)pptr; + header_iih_ptp = (const struct isis_iih_ptp_header *)pptr; + header_lsp = (struct isis_lsp_header *)pptr; + header_csnp = (const struct isis_csnp_header *)pptr; + header_psnp = (const struct isis_psnp_header *)pptr; + + if (!eflag) + printf("IS-IS"); + + /* + * Sanity checking of the header. + */ + + if (isis_header->version != ISIS_VERSION) { + printf("version %d packet not supported", isis_header->version); + return (0); + } + + if ((isis_header->id_length != SYSTEM_ID_LEN) && (isis_header->id_length != 0)) { + printf("system ID length of %d is not supported", + isis_header->id_length); + return (0); + } + + if (isis_header->pdu_version != ISIS_VERSION) { + printf("version %d packet not supported", isis_header->pdu_version); + return (0); + } + + max_area = isis_header->max_area; + switch(max_area) { + case 0: + max_area = 3; /* silly shit */ + break; + case 255: + printf("bad packet -- 255 areas"); + return (0); + default: + break; + } + + id_length = isis_header->id_length; + switch(id_length) { + case 0: + id_length = 6; /* silly shit again */ + break; + case 1: /* 1-8 are valid sys-ID lenghts */ + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + break; + case 255: + id_length = 0; /* entirely useless */ + break; + default: + break; + } + + /* toss any non 6-byte sys-ID len PDUs */ + if (id_length != 6 ) { + printf("bad packet -- illegal sys-ID length (%u)", id_length); + return (0); + } + + pdu_type=isis_header->pdu_type; + + /* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/ + if (vflag < 1) { + printf("%s%s", + eflag ? "" : ", ", + tok2str(isis_pdu_values,"unknown PDU-Type %u",pdu_type)); + + switch (pdu_type) { + + case ISIS_PDU_L1_LAN_IIH: + case ISIS_PDU_L2_LAN_IIH: + printf(", src-id %s", + isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN)); + printf(", lan-id %s, prio %u", + isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN), + header_iih_lan->priority); + break; + case ISIS_PDU_PTP_IIH: + printf(", src-id %s", isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN)); + break; + case ISIS_PDU_L1_LSP: + case ISIS_PDU_L2_LSP: + printf(", lsp-id %s, seq 0x%08x, lifetime %5us", + isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), + EXTRACT_32BITS(header_lsp->sequence_number), + EXTRACT_16BITS(header_lsp->remaining_lifetime)); + break; + case ISIS_PDU_L1_CSNP: + case ISIS_PDU_L2_CSNP: + printf(", src-id %s", isis_print_id(header_csnp->source_id,NODE_ID_LEN)); + break; + case ISIS_PDU_L1_PSNP: + case ISIS_PDU_L2_PSNP: + printf(", src-id %s", isis_print_id(header_psnp->source_id,NODE_ID_LEN)); + break; + + } + printf(", length %u", length); + + return(1); + } + + /* ok they seem to want to know everything - lets fully decode it */ + printf("%slength %u", eflag ? "" : ", ",length); + + printf("\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)", + tok2str(isis_pdu_values, + "unknown, type %u", + pdu_type), + isis_header->fixed_len, + isis_header->version, + isis_header->pdu_version, + id_length, + isis_header->id_length, + max_area, + isis_header->max_area); + + if (vflag > 1) { + if(!print_unknown_data(optr,"\n\t",8)) /* provide the _o_riginal pointer */ + return(0); /* for optionally debugging the common header */ + } + + switch (pdu_type) { + + case ISIS_PDU_L1_LAN_IIH: + case ISIS_PDU_L2_LAN_IIH: + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) { + printf(", bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE); + return (0); + } + + pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len); + if (packet_len>pdu_len) { + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; + } + + TCHECK(*header_iih_lan); + printf("\n\t source-id: %s, holding time: %us, Flags: [%s]", + isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN), + EXTRACT_16BITS(header_iih_lan->holding_time), + tok2str(isis_iih_circuit_type_values, + "unknown circuit type 0x%02x", + header_iih_lan->circuit_type)); + + printf("\n\t lan-id: %s, Priority: %u, PDU length: %u", + isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN), + (header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK, + pdu_len); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_IIH_LAN_HEADER_SIZE)) + return(0); + } + + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); + break; + + case ISIS_PDU_PTP_IIH: + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) { + printf(", bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE); + return (0); + } + + pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len); + if (packet_len>pdu_len) { + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; + } + + TCHECK(*header_iih_ptp); + printf("\n\t source-id: %s, holding time: %us, Flags: [%s]", + isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN), + EXTRACT_16BITS(header_iih_ptp->holding_time), + tok2str(isis_iih_circuit_type_values, + "unknown circuit type 0x%02x", + header_iih_ptp->circuit_type)); + + printf("\n\t circuit-id: 0x%02x, PDU length: %u", + header_iih_ptp->circuit_id, + pdu_len); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_IIH_PTP_HEADER_SIZE)) + return(0); + } + + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); + break; + + case ISIS_PDU_L1_LSP: + case ISIS_PDU_L2_LSP: + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) { + printf(", bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE); + return (0); + } + + pdu_len=EXTRACT_16BITS(header_lsp->pdu_len); + if (packet_len>pdu_len) { + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; + } + + TCHECK(*header_lsp); + printf("\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x", + isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), + EXTRACT_32BITS(header_lsp->sequence_number), + EXTRACT_16BITS(header_lsp->remaining_lifetime), + EXTRACT_16BITS(header_lsp->checksum)); + + + osi_print_cksum((u_int8_t *)header_lsp->lsp_id, + EXTRACT_16BITS(header_lsp->checksum), 12, length-12); + + /* + * Clear checksum and lifetime prior to signature verification. + */ + header_lsp->checksum[0] = 0; + header_lsp->checksum[1] = 0; + header_lsp->remaining_lifetime[0] = 0; + header_lsp->remaining_lifetime[1] = 0; + + + printf(", PDU length: %u, Flags: [ %s", + pdu_len, + ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""); + + if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) { + printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""); + printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : ""); + printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : ""); + printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : ""); + printf("ATT bit set, "); + } + printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""); + printf("%s ]", tok2str(isis_lsp_istype_values,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_LSP_HEADER_SIZE)) + return(0); + } + + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); + break; + + case ISIS_PDU_L1_CSNP: + case ISIS_PDU_L2_CSNP: + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) { + printf(", bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE); + return (0); + } + + pdu_len=EXTRACT_16BITS(header_csnp->pdu_len); + if (packet_len>pdu_len) { + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; + } + + TCHECK(*header_csnp); + printf("\n\t source-id: %s, PDU length: %u", + isis_print_id(header_csnp->source_id, NODE_ID_LEN), + pdu_len); + printf("\n\t start lsp-id: %s", + isis_print_id(header_csnp->start_lsp_id, LSP_ID_LEN)); + printf("\n\t end lsp-id: %s", + isis_print_id(header_csnp->end_lsp_id, LSP_ID_LEN)); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_CSNP_HEADER_SIZE)) + return(0); + } + + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); + break; + + case ISIS_PDU_L1_PSNP: + case ISIS_PDU_L2_PSNP: + if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) { + printf("- bogus fixed header length %u should be %lu", + isis_header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE); + return (0); + } + + pdu_len=EXTRACT_16BITS(header_psnp->pdu_len); + if (packet_len>pdu_len) { + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; + } + + TCHECK(*header_psnp); + printf("\n\t source-id: %s, PDU length: %u", + isis_print_id(header_psnp->source_id, NODE_ID_LEN), + pdu_len); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_PSNP_HEADER_SIZE)) + return(0); + } + + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); + pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); + break; + + default: + if(!print_unknown_data(pptr,"\n\t ",length)) + return(0); + return (0); + } + + /* + * Now print the TLV's. + */ + + while (packet_len >= 2) { + if (pptr == snapend) { + return (1); + } + + if (!TTEST2(*pptr, 2)) { + printf("\n\t\t packet exceeded snapshot (%ld) bytes", + (long)(pptr-snapend)); + return (1); + } + tlv_type = *pptr++; + tlv_len = *pptr++; + tmp =tlv_len; /* copy temporary len & pointer to packet data */ + tptr = pptr; + packet_len -= 2; + if (tlv_len > packet_len) { + break; + } + + /* first lets see if we know the TLVs name*/ + printf("\n\t %s TLV #%u, length: %u", + tok2str(isis_tlv_values, + "unknown", + tlv_type), + tlv_type, + tlv_len); + + if (tlv_len == 0) /* something is malformed */ + continue; + + /* now check if we have a decoder otherwise do a hexdump at the end*/ + switch (tlv_type) { + case ISIS_TLV_AREA_ADDR: + if (!TTEST2(*tptr, 1)) + goto trunctlv; + alen = *tptr++; + while (tmp && alen < tmp) { + printf("\n\t Area address (length: %u): %s", + alen, + isonsap_string(tptr,alen)); + tptr += alen; + tmp -= alen + 1; + if (tmp==0) /* if this is the last area address do not attemt a boundary check */ + break; + if (!TTEST2(*tptr, 1)) + goto trunctlv; + alen = *tptr++; + } + break; + case ISIS_TLV_ISNEIGH: + while (tmp >= ETHER_ADDR_LEN) { + if (!TTEST2(*tptr, ETHER_ADDR_LEN)) + goto trunctlv; + printf("\n\t SNPA: %s",isis_print_id(tptr,ETHER_ADDR_LEN)); + tmp -= ETHER_ADDR_LEN; + tptr += ETHER_ADDR_LEN; + } + break; + + case ISIS_TLV_ISNEIGH_VARLEN: + if (!TTEST2(*tptr, 1) || tmp < 3) /* min. TLV length */ + goto trunctlv; + lan_alen = *tptr++; /* LAN address length */ + if (lan_alen == 0) { + printf("\n\t LAN address length 0 bytes (invalid)"); + break; + } + tmp --; + printf("\n\t LAN address length %u bytes ",lan_alen); + while (tmp >= lan_alen) { + if (!TTEST2(*tptr, lan_alen)) + goto trunctlv; + printf("\n\t\tIS Neighbor: %s",isis_print_id(tptr,lan_alen)); + tmp -= lan_alen; + tptr +=lan_alen; + } + break; + + case ISIS_TLV_PADDING: + break; + + case ISIS_TLV_MT_IS_REACH: + mt_len = isis_print_mtid(tptr, "\n\t "); + if (mt_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=mt_len; + tmp-=mt_len; + while (tmp >= 2+NODE_ID_LEN+3+1) { + ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); + if (ext_is_len == 0) /* did something go wrong ? */ + goto trunctlv; + + tmp-=ext_is_len; + tptr+=ext_is_len; + } + break; + + case ISIS_TLV_IS_ALIAS_ID: + while (tmp >= NODE_ID_LEN+1) { /* is it worth attempting a decode ? */ + ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); + if (ext_is_len == 0) /* did something go wrong ? */ + goto trunctlv; + tmp-=ext_is_len; + tptr+=ext_is_len; + } + break; + + case ISIS_TLV_EXT_IS_REACH: + while (tmp >= NODE_ID_LEN+3+1) { /* is it worth attempting a decode ? */ + ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); + if (ext_is_len == 0) /* did something go wrong ? */ + goto trunctlv; + tmp-=ext_is_len; + tptr+=ext_is_len; + } + break; + case ISIS_TLV_IS_REACH: + if (!TTEST2(*tptr,1)) /* check if there is one byte left to read out the virtual flag */ + goto trunctlv; + printf("\n\t %s", + tok2str(isis_is_reach_virtual_values, + "bogus virtual flag 0x%02x", + *tptr++)); + tlv_is_reach = (const struct isis_tlv_is_reach *)tptr; + while (tmp >= sizeof(struct isis_tlv_is_reach)) { + if (!TTEST(*tlv_is_reach)) + goto trunctlv; + printf("\n\t IS Neighbor: %s", + isis_print_id(tlv_is_reach->neighbor_nodeid, NODE_ID_LEN)); + isis_print_metric_block(&tlv_is_reach->isis_metric_block); + tmp -= sizeof(struct isis_tlv_is_reach); + tlv_is_reach++; + } + break; + + case ISIS_TLV_ESNEIGH: + tlv_es_reach = (const struct isis_tlv_es_reach *)tptr; + while (tmp >= sizeof(struct isis_tlv_es_reach)) { + if (!TTEST(*tlv_es_reach)) + goto trunctlv; + printf("\n\t ES Neighbor: %s", + isis_print_id(tlv_es_reach->neighbor_sysid,SYSTEM_ID_LEN)); + isis_print_metric_block(&tlv_es_reach->isis_metric_block); + tmp -= sizeof(struct isis_tlv_es_reach); + tlv_es_reach++; + } + break; + + /* those two TLVs share the same format */ + case ISIS_TLV_INT_IP_REACH: + case ISIS_TLV_EXT_IP_REACH: + if (!isis_print_tlv_ip_reach(pptr, "\n\t ", tlv_len)) + return (1); + break; + + case ISIS_TLV_EXTD_IP_REACH: + while (tmp>0) { + ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", AF_INET); + if (ext_ip_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=ext_ip_len; + tmp-=ext_ip_len; + } + break; + + case ISIS_TLV_MT_IP_REACH: + mt_len = isis_print_mtid(tptr, "\n\t "); + if (mt_len == 0) { /* did something go wrong ? */ + goto trunctlv; + } + tptr+=mt_len; + tmp-=mt_len; + + while (tmp>0) { + ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", AF_INET); + if (ext_ip_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=ext_ip_len; + tmp-=ext_ip_len; + } + break; + +#ifdef INET6 + case ISIS_TLV_IP6_REACH: + while (tmp>0) { + ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", AF_INET6); + if (ext_ip_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=ext_ip_len; + tmp-=ext_ip_len; + } + break; + + case ISIS_TLV_MT_IP6_REACH: + mt_len = isis_print_mtid(tptr, "\n\t "); + if (mt_len == 0) { /* did something go wrong ? */ + goto trunctlv; + } + tptr+=mt_len; + tmp-=mt_len; + + while (tmp>0) { + ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", AF_INET6); + if (ext_ip_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=ext_ip_len; + tmp-=ext_ip_len; + } + break; + + case ISIS_TLV_IP6ADDR: + while (tmp>=sizeof(struct in6_addr)) { + if (!TTEST2(*tptr, sizeof(struct in6_addr))) + goto trunctlv; + + printf("\n\t IPv6 interface address: %s", + ip6addr_string(tptr)); + + tptr += sizeof(struct in6_addr); + tmp -= sizeof(struct in6_addr); + } + break; +#endif + case ISIS_TLV_AUTH: + if (!TTEST2(*tptr, 1)) + goto trunctlv; + + printf("\n\t %s: ", + tok2str(isis_subtlv_auth_values, + "unknown Authentication type 0x%02x", + *tptr)); + + switch (*tptr) { + case ISIS_SUBTLV_AUTH_SIMPLE: + for(i=1;i=1) { + if (!TTEST2(*tptr, 1)) + goto trunctlv; + printf("\n\t Adjacency State: %s (%u)", + tok2str(isis_ptp_adjancey_values, "unknown", *tptr), + *tptr); + tmp--; + } + if(tmp>sizeof(tlv_ptp_adj->extd_local_circuit_id)) { + if (!TTEST2(tlv_ptp_adj->extd_local_circuit_id, + sizeof(tlv_ptp_adj->extd_local_circuit_id))) + goto trunctlv; + printf("\n\t Extended Local circuit-ID: 0x%08x", + EXTRACT_32BITS(tlv_ptp_adj->extd_local_circuit_id)); + tmp-=sizeof(tlv_ptp_adj->extd_local_circuit_id); + } + if(tmp>=SYSTEM_ID_LEN) { + if (!TTEST2(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN)) + goto trunctlv; + printf("\n\t Neighbor System-ID: %s", + isis_print_id(tlv_ptp_adj->neighbor_sysid,SYSTEM_ID_LEN)); + tmp-=SYSTEM_ID_LEN; + } + if(tmp>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) { + if (!TTEST2(tlv_ptp_adj->neighbor_extd_local_circuit_id, + sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id))) + goto trunctlv; + printf("\n\t Neighbor Extended Local circuit-ID: 0x%08x", + EXTRACT_32BITS(tlv_ptp_adj->neighbor_extd_local_circuit_id)); + } + break; + + case ISIS_TLV_PROTOCOLS: + printf("\n\t NLPID(s): "); + while (tmp>0) { + if (!TTEST2(*(tptr), 1)) + goto trunctlv; + printf("%s (0x%02x)", + tok2str(nlpid_values, + "unknown", + *tptr), + *tptr); + if (tmp>1) /* further NPLIDs ? - put comma */ + printf(", "); + tptr++; + tmp--; + } + break; + + case ISIS_TLV_TE_ROUTER_ID: + if (!TTEST2(*pptr, sizeof(struct in_addr))) + goto trunctlv; + printf("\n\t Traffic Engineering Router ID: %s", ipaddr_string(pptr)); + break; + + case ISIS_TLV_IPADDR: + while (tmp>=sizeof(struct in_addr)) { + if (!TTEST2(*tptr, sizeof(struct in_addr))) + goto trunctlv; + printf("\n\t IPv4 interface address: %s", ipaddr_string(tptr)); + tptr += sizeof(struct in_addr); + tmp -= sizeof(struct in_addr); + } + break; + + case ISIS_TLV_HOSTNAME: + printf("\n\t Hostname: "); + while (tmp>0) { + if (!TTEST2(*tptr, 1)) + goto trunctlv; + printf("%c",*tptr++); + tmp--; + } + break; + + case ISIS_TLV_SHARED_RISK_GROUP: + if (tmp < NODE_ID_LEN) + break; + if (!TTEST2(*tptr, NODE_ID_LEN)) + goto trunctlv; + printf("\n\t IS Neighbor: %s", isis_print_id(tptr, NODE_ID_LEN)); + tptr+=(NODE_ID_LEN); + tmp-=(NODE_ID_LEN); + + if (tmp < 1) + break; + if (!TTEST2(*tptr, 1)) + goto trunctlv; + printf(", Flags: [%s]", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr++) ? "numbered" : "unnumbered"); + tmp--; + + if (tmp < sizeof(struct in_addr)) + break; + if (!TTEST2(*tptr,sizeof(struct in_addr))) + goto trunctlv; + printf("\n\t IPv4 interface address: %s", ipaddr_string(tptr)); + tptr+=sizeof(struct in_addr); + tmp-=sizeof(struct in_addr); + + if (tmp < sizeof(struct in_addr)) + break; + if (!TTEST2(*tptr,sizeof(struct in_addr))) + goto trunctlv; + printf("\n\t IPv4 neighbor address: %s", ipaddr_string(tptr)); + tptr+=sizeof(struct in_addr); + tmp-=sizeof(struct in_addr); + + while (tmp>=4) { + if (!TTEST2(*tptr, 4)) + goto trunctlv; + printf("\n\t Link-ID: 0x%08x", EXTRACT_32BITS(tptr)); + tptr+=4; + tmp-=4; + } + break; + + case ISIS_TLV_LSP: + tlv_lsp = (const struct isis_tlv_lsp *)tptr; + while(tmp>=sizeof(struct isis_tlv_lsp)) { + if (!TTEST((tlv_lsp->lsp_id)[LSP_ID_LEN-1])) + goto trunctlv; + printf("\n\t lsp-id: %s", + isis_print_id(tlv_lsp->lsp_id, LSP_ID_LEN)); + if (!TTEST2(tlv_lsp->sequence_number, 4)) + goto trunctlv; + printf(", seq: 0x%08x",EXTRACT_32BITS(tlv_lsp->sequence_number)); + if (!TTEST2(tlv_lsp->remaining_lifetime, 2)) + goto trunctlv; + printf(", lifetime: %5ds",EXTRACT_16BITS(tlv_lsp->remaining_lifetime)); + if (!TTEST2(tlv_lsp->checksum, 2)) + goto trunctlv; + printf(", chksum: 0x%04x",EXTRACT_16BITS(tlv_lsp->checksum)); + tmp-=sizeof(struct isis_tlv_lsp); + tlv_lsp++; + } + break; + + case ISIS_TLV_CHECKSUM: + if (tmp < ISIS_TLV_CHECKSUM_MINLEN) + break; + if (!TTEST2(*tptr, ISIS_TLV_CHECKSUM_MINLEN)) + goto trunctlv; + printf("\n\t checksum: 0x%04x ", EXTRACT_16BITS(tptr)); + /* do not attempt to verify the checksum if it is zero + * most likely a HMAC-MD5 TLV is also present and + * to avoid conflicts the checksum TLV is zeroed. + * see rfc3358 for details + */ + osi_print_cksum(optr, EXTRACT_16BITS(tptr), tptr-optr, length); + break; + + case ISIS_TLV_MT_SUPPORTED: + if (tmp < ISIS_TLV_MT_SUPPORTED_MINLEN) + break; + while (tmp>1) { + /* length can only be a multiple of 2, otherwise there is + something broken -> so decode down until length is 1 */ + if (tmp!=1) { + mt_len = isis_print_mtid(tptr, "\n\t "); + if (mt_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=mt_len; + tmp-=mt_len; + } else { + printf("\n\t malformed MT-ID"); + break; + } + } + break; + + case ISIS_TLV_RESTART_SIGNALING: + /* first attempt to decode the flags */ + if (tmp < ISIS_TLV_RESTART_SIGNALING_FLAGLEN) + break; + if (!TTEST2(*tptr, ISIS_TLV_RESTART_SIGNALING_FLAGLEN)) + goto trunctlv; + printf("\n\t Flags [%s]", + bittok2str(isis_restart_flag_values, "none", *tptr)); + tptr+=ISIS_TLV_RESTART_SIGNALING_FLAGLEN; + tmp-=ISIS_TLV_RESTART_SIGNALING_FLAGLEN; + + /* is there anything other than the flags field? */ + if (tmp == 0) + break; + + if (tmp < ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN) + break; + if (!TTEST2(*tptr, ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN)) + goto trunctlv; + + printf(", Remaining holding time %us", EXTRACT_16BITS(tptr)); + tptr+=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN; + tmp-=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN; + + /* is there an additional sysid field present ?*/ + if (tmp == SYSTEM_ID_LEN) { + if (!TTEST2(*tptr, SYSTEM_ID_LEN)) + goto trunctlv; + printf(", for %s",isis_print_id(tptr,SYSTEM_ID_LEN)); + } + break; + + case ISIS_TLV_IDRP_INFO: + if (tmp < ISIS_TLV_IDRP_INFO_MINLEN) + break; + if (!TTEST2(*tptr, ISIS_TLV_IDRP_INFO_MINLEN)) + goto trunctlv; + printf("\n\t Inter-Domain Information Type: %s", + tok2str(isis_subtlv_idrp_values, + "Unknown (0x%02x)", + *tptr)); + switch (*tptr++) { + case ISIS_SUBTLV_IDRP_ASN: + if (!TTEST2(*tptr, 2)) /* fetch AS number */ + goto trunctlv; + printf("AS Number: %u",EXTRACT_16BITS(tptr)); + break; + case ISIS_SUBTLV_IDRP_LOCAL: + case ISIS_SUBTLV_IDRP_RES: + default: + if(!print_unknown_data(tptr,"\n\t ",tlv_len-1)) + return(0); + break; + } + break; + + case ISIS_TLV_LSP_BUFFERSIZE: + if (tmp < ISIS_TLV_LSP_BUFFERSIZE_MINLEN) + break; + if (!TTEST2(*tptr, ISIS_TLV_LSP_BUFFERSIZE_MINLEN)) + goto trunctlv; + printf("\n\t LSP Buffersize: %u",EXTRACT_16BITS(tptr)); + break; + + case ISIS_TLV_PART_DIS: + while (tmp >= SYSTEM_ID_LEN) { + if (!TTEST2(*tptr, SYSTEM_ID_LEN)) + goto trunctlv; + printf("\n\t %s",isis_print_id(tptr,SYSTEM_ID_LEN)); + tptr+=SYSTEM_ID_LEN; + tmp-=SYSTEM_ID_LEN; + } + break; + + case ISIS_TLV_PREFIX_NEIGH: + if (tmp < sizeof(struct isis_metric_block)) + break; + if (!TTEST2(*tptr, sizeof(struct isis_metric_block))) + goto trunctlv; + printf("\n\t Metric Block"); + isis_print_metric_block((const struct isis_metric_block *)tptr); + tptr+=sizeof(struct isis_metric_block); + tmp-=sizeof(struct isis_metric_block); + + while(tmp>0) { + if (!TTEST2(*tptr, 1)) + goto trunctlv; + prefix_len=*tptr++; /* read out prefix length in semioctets*/ + if (prefix_len < 2) { + printf("\n\t\tAddress: prefix length %u < 2", prefix_len); + break; + } + tmp--; + if (tmp < prefix_len/2) + break; + if (!TTEST2(*tptr, prefix_len/2)) + goto trunctlv; + printf("\n\t\tAddress: %s/%u", + isonsap_string(tptr,prefix_len/2), + prefix_len*4); + tptr+=prefix_len/2; + tmp-=prefix_len/2; + } + break; + + case ISIS_TLV_IIH_SEQNR: + if (tmp < ISIS_TLV_IIH_SEQNR_MINLEN) + break; + if (!TTEST2(*tptr, ISIS_TLV_IIH_SEQNR_MINLEN)) /* check if four bytes are on the wire */ + goto trunctlv; + printf("\n\t Sequence number: %u", EXTRACT_32BITS(tptr) ); + break; + + case ISIS_TLV_VENDOR_PRIVATE: + if (tmp < ISIS_TLV_VENDOR_PRIVATE_MINLEN) + break; + if (!TTEST2(*tptr, ISIS_TLV_VENDOR_PRIVATE_MINLEN)) /* check if enough byte for a full oui */ + goto trunctlv; + vendor_id = EXTRACT_24BITS(tptr); + printf("\n\t Vendor: %s (%u)", + tok2str(oui_values,"Unknown",vendor_id), + vendor_id); + tptr+=3; + tmp-=3; + if (tmp > 0) /* hexdump the rest */ + if(!print_unknown_data(tptr,"\n\t\t",tmp)) + return(0); + break; + /* + * FIXME those are the defined TLVs that lack a decoder + * you are welcome to contribute code ;-) + */ + + case ISIS_TLV_DECNET_PHASE4: + case ISIS_TLV_LUCENT_PRIVATE: + case ISIS_TLV_IPAUTH: + case ISIS_TLV_NORTEL_PRIVATE1: + case ISIS_TLV_NORTEL_PRIVATE2: + + default: + if (vflag <= 1) { + if(!print_unknown_data(pptr,"\n\t\t",tlv_len)) + return(0); + } + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag> 1) { + if(!print_unknown_data(pptr,"\n\t ",tlv_len)) + return(0); + } + + pptr += tlv_len; + packet_len -= tlv_len; + } + + if (packet_len != 0) { + printf("\n\t %u straggler bytes", packet_len); + } + return (1); + + trunc: + fputs("[|isis]", stdout); + return (1); + + trunctlv: + printf("\n\t\t packet exceeded snapshot"); + return(1); +} + +static void +osi_print_cksum (const u_int8_t *pptr, u_int16_t checksum, + u_int checksum_offset, u_int length) +{ + u_int16_t calculated_checksum; + + /* do not attempt to verify the checksum if it is zero */ + if (!checksum) { + printf("(unverified)"); + } else { + calculated_checksum = create_osi_cksum(pptr, checksum_offset, length); + if (checksum == calculated_checksum) { + printf(" (correct)"); + } else { + printf(" (incorrect should be 0x%04x)", calculated_checksum); + } + } +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-juniper.c b/print-juniper.c new file mode 100644 index 0000000..55ca1c9 --- /dev/null +++ b/print-juniper.c @@ -0,0 +1,1456 @@ +/* NetBSD: print-juniper.c,v 1.2 2007/07/24 11:53:45 drochner Exp */ + +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-juniper.c,v 1.34 2007-08-29 02:31:44 mcr Exp $ (LBL)"; +#else +__RCSID("NetBSD: print-juniper.c,v 1.3 2007/07/25 06:31:32 dogcow Exp "); +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "ppp.h" +#include "llc.h" +#include "nlpid.h" +#include "ethertype.h" +#include "atm.h" + +#define JUNIPER_BPF_OUT 0 /* Outgoing packet */ +#define JUNIPER_BPF_IN 1 /* Incoming packet */ +#define JUNIPER_BPF_PKT_IN 0x1 /* Incoming packet */ +#define JUNIPER_BPF_NO_L2 0x2 /* L2 header stripped */ +#define JUNIPER_BPF_IIF 0x4 /* IIF is valid */ +#define JUNIPER_BPF_FILTER 0x40 /* BPF filtering is supported */ +#define JUNIPER_BPF_EXT 0x80 /* extensions present */ +#define JUNIPER_MGC_NUMBER 0x4d4743 /* = "MGC" */ + +#define JUNIPER_LSQ_COOKIE_RE (1 << 3) +#define JUNIPER_LSQ_COOKIE_DIR (1 << 2) +#define JUNIPER_LSQ_L3_PROTO_SHIFT 4 +#define JUNIPER_LSQ_L3_PROTO_MASK (0x17 << JUNIPER_LSQ_L3_PROTO_SHIFT) +#define JUNIPER_LSQ_L3_PROTO_IPV4 (0 << JUNIPER_LSQ_L3_PROTO_SHIFT) +#define JUNIPER_LSQ_L3_PROTO_IPV6 (1 << JUNIPER_LSQ_L3_PROTO_SHIFT) +#define JUNIPER_LSQ_L3_PROTO_MPLS (2 << JUNIPER_LSQ_L3_PROTO_SHIFT) +#define JUNIPER_LSQ_L3_PROTO_ISO (3 << JUNIPER_LSQ_L3_PROTO_SHIFT) +#define AS_PIC_COOKIE_LEN 8 + +#define JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE 1 +#define JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE 2 +#define JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE 3 +#define JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE 4 +#define JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE 5 + +static struct tok juniper_ipsec_type_values[] = { + { JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE, "ESP ENCR-AUTH" }, + { JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE, "ESP ENCR-AH AUTH" }, + { JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE, "ESP AUTH" }, + { JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE, "AH AUTH" }, + { JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE, "ESP ENCR" }, + { 0, NULL} +}; + +static struct tok juniper_direction_values[] = { + { JUNIPER_BPF_IN, "In"}, + { JUNIPER_BPF_OUT, "Out"}, + { 0, NULL} +}; + +/* codepoints for encoding extensions to a .pcap file */ +enum { + JUNIPER_EXT_TLV_IFD_IDX = 1, + JUNIPER_EXT_TLV_IFD_NAME = 2, + JUNIPER_EXT_TLV_IFD_MEDIATYPE = 3, + JUNIPER_EXT_TLV_IFL_IDX = 4, + JUNIPER_EXT_TLV_IFL_UNIT = 5, + JUNIPER_EXT_TLV_IFL_ENCAPS = 6, + JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE = 7, + JUNIPER_EXT_TLV_TTP_IFL_ENCAPS = 8 +}; + +/* 1 byte type and 1-byte length */ +#define JUNIPER_EXT_TLV_OVERHEAD 2 + +struct tok jnx_ext_tlv_values[] = { + { JUNIPER_EXT_TLV_IFD_IDX, "Device Interface Index" }, + { JUNIPER_EXT_TLV_IFD_NAME,"Device Interface Name" }, + { JUNIPER_EXT_TLV_IFD_MEDIATYPE, "Device Media Type" }, + { JUNIPER_EXT_TLV_IFL_IDX, "Logical Interface Index" }, + { JUNIPER_EXT_TLV_IFL_UNIT,"Logical Unit Number" }, + { JUNIPER_EXT_TLV_IFL_ENCAPS, "Logical Interface Encapsulation" }, + { JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE, "TTP derived Device Media Type" }, + { JUNIPER_EXT_TLV_TTP_IFL_ENCAPS, "TTP derived Logical Interface Encapsulation" }, + { 0, NULL } +}; + +struct tok jnx_flag_values[] = { + { JUNIPER_BPF_EXT, "Ext" }, + { JUNIPER_BPF_FILTER, "Filter" }, + { JUNIPER_BPF_IIF, "IIF" }, + { JUNIPER_BPF_NO_L2, "no-L2" }, + { JUNIPER_BPF_PKT_IN, "In" }, + { 0, NULL } +}; + +#define JUNIPER_IFML_ETHER 1 +#define JUNIPER_IFML_FDDI 2 +#define JUNIPER_IFML_TOKENRING 3 +#define JUNIPER_IFML_PPP 4 +#define JUNIPER_IFML_FRAMERELAY 5 +#define JUNIPER_IFML_CISCOHDLC 6 +#define JUNIPER_IFML_SMDSDXI 7 +#define JUNIPER_IFML_ATMPVC 8 +#define JUNIPER_IFML_PPP_CCC 9 +#define JUNIPER_IFML_FRAMERELAY_CCC 10 +#define JUNIPER_IFML_IPIP 11 +#define JUNIPER_IFML_GRE 12 +#define JUNIPER_IFML_PIM 13 +#define JUNIPER_IFML_PIMD 14 +#define JUNIPER_IFML_CISCOHDLC_CCC 15 +#define JUNIPER_IFML_VLAN_CCC 16 +#define JUNIPER_IFML_MLPPP 17 +#define JUNIPER_IFML_MLFR 18 +#define JUNIPER_IFML_ML 19 +#define JUNIPER_IFML_LSI 20 +#define JUNIPER_IFML_DFE 21 +#define JUNIPER_IFML_ATM_CELLRELAY_CCC 22 +#define JUNIPER_IFML_CRYPTO 23 +#define JUNIPER_IFML_GGSN 24 +#define JUNIPER_IFML_LSI_PPP 25 +#define JUNIPER_IFML_LSI_CISCOHDLC 26 +#define JUNIPER_IFML_PPP_TCC 27 +#define JUNIPER_IFML_FRAMERELAY_TCC 28 +#define JUNIPER_IFML_CISCOHDLC_TCC 29 +#define JUNIPER_IFML_ETHERNET_CCC 30 +#define JUNIPER_IFML_VT 31 +#define JUNIPER_IFML_EXTENDED_VLAN_CCC 32 +#define JUNIPER_IFML_ETHER_OVER_ATM 33 +#define JUNIPER_IFML_MONITOR 34 +#define JUNIPER_IFML_ETHERNET_TCC 35 +#define JUNIPER_IFML_VLAN_TCC 36 +#define JUNIPER_IFML_EXTENDED_VLAN_TCC 37 +#define JUNIPER_IFML_CONTROLLER 38 +#define JUNIPER_IFML_MFR 39 +#define JUNIPER_IFML_LS 40 +#define JUNIPER_IFML_ETHERNET_VPLS 41 +#define JUNIPER_IFML_ETHERNET_VLAN_VPLS 42 +#define JUNIPER_IFML_ETHERNET_EXTENDED_VLAN_VPLS 43 +#define JUNIPER_IFML_LT 44 +#define JUNIPER_IFML_SERVICES 45 +#define JUNIPER_IFML_ETHER_VPLS_OVER_ATM 46 +#define JUNIPER_IFML_FR_PORT_CCC 47 +#define JUNIPER_IFML_FRAMERELAY_EXT_CCC 48 +#define JUNIPER_IFML_FRAMERELAY_EXT_TCC 49 +#define JUNIPER_IFML_FRAMERELAY_FLEX 50 +#define JUNIPER_IFML_GGSNI 51 +#define JUNIPER_IFML_ETHERNET_FLEX 52 +#define JUNIPER_IFML_COLLECTOR 53 +#define JUNIPER_IFML_AGGREGATOR 54 +#define JUNIPER_IFML_LAPD 55 +#define JUNIPER_IFML_PPPOE 56 +#define JUNIPER_IFML_PPP_SUBORDINATE 57 +#define JUNIPER_IFML_CISCOHDLC_SUBORDINATE 58 +#define JUNIPER_IFML_DFC 59 +#define JUNIPER_IFML_PICPEER 60 + +struct tok juniper_ifmt_values[] = { + { JUNIPER_IFML_ETHER, "Ethernet" }, + { JUNIPER_IFML_FDDI, "FDDI" }, + { JUNIPER_IFML_TOKENRING, "Token-Ring" }, + { JUNIPER_IFML_PPP, "PPP" }, + { JUNIPER_IFML_PPP_SUBORDINATE, "PPP-Subordinate" }, + { JUNIPER_IFML_FRAMERELAY, "Frame-Relay" }, + { JUNIPER_IFML_CISCOHDLC, "Cisco-HDLC" }, + { JUNIPER_IFML_SMDSDXI, "SMDS-DXI" }, + { JUNIPER_IFML_ATMPVC, "ATM-PVC" }, + { JUNIPER_IFML_PPP_CCC, "PPP-CCC" }, + { JUNIPER_IFML_FRAMERELAY_CCC, "Frame-Relay-CCC" }, + { JUNIPER_IFML_FRAMERELAY_EXT_CCC, "Extended FR-CCC" }, + { JUNIPER_IFML_IPIP, "IP-over-IP" }, + { JUNIPER_IFML_GRE, "GRE" }, + { JUNIPER_IFML_PIM, "PIM-Encapsulator" }, + { JUNIPER_IFML_PIMD, "PIM-Decapsulator" }, + { JUNIPER_IFML_CISCOHDLC_CCC, "Cisco-HDLC-CCC" }, + { JUNIPER_IFML_VLAN_CCC, "VLAN-CCC" }, + { JUNIPER_IFML_EXTENDED_VLAN_CCC, "Extended-VLAN-CCC" }, + { JUNIPER_IFML_MLPPP, "Multilink-PPP" }, + { JUNIPER_IFML_MLFR, "Multilink-FR" }, + { JUNIPER_IFML_MFR, "Multilink-FR-UNI-NNI" }, + { JUNIPER_IFML_ML, "Multilink" }, + { JUNIPER_IFML_LS, "LinkService" }, + { JUNIPER_IFML_LSI, "LSI" }, + { JUNIPER_IFML_ATM_CELLRELAY_CCC, "ATM-CCC-Cell-Relay" }, + { JUNIPER_IFML_CRYPTO, "IPSEC-over-IP" }, + { JUNIPER_IFML_GGSN, "GGSN" }, + { JUNIPER_IFML_PPP_TCC, "PPP-TCC" }, + { JUNIPER_IFML_FRAMERELAY_TCC, "Frame-Relay-TCC" }, + { JUNIPER_IFML_FRAMERELAY_EXT_TCC, "Extended FR-TCC" }, + { JUNIPER_IFML_CISCOHDLC_TCC, "Cisco-HDLC-TCC" }, + { JUNIPER_IFML_ETHERNET_CCC, "Ethernet-CCC" }, + { JUNIPER_IFML_VT, "VPN-Loopback-tunnel" }, + { JUNIPER_IFML_ETHER_OVER_ATM, "Ethernet-over-ATM" }, + { JUNIPER_IFML_ETHER_VPLS_OVER_ATM, "Ethernet-VPLS-over-ATM" }, + { JUNIPER_IFML_MONITOR, "Monitor" }, + { JUNIPER_IFML_ETHERNET_TCC, "Ethernet-TCC" }, + { JUNIPER_IFML_VLAN_TCC, "VLAN-TCC" }, + { JUNIPER_IFML_EXTENDED_VLAN_TCC, "Extended-VLAN-TCC" }, + { JUNIPER_IFML_CONTROLLER, "Controller" }, + { JUNIPER_IFML_ETHERNET_VPLS, "VPLS" }, + { JUNIPER_IFML_ETHERNET_VLAN_VPLS, "VLAN-VPLS" }, + { JUNIPER_IFML_ETHERNET_EXTENDED_VLAN_VPLS, "Extended-VLAN-VPLS" }, + { JUNIPER_IFML_LT, "Logical-tunnel" }, + { JUNIPER_IFML_SERVICES, "General-Services" }, + { JUNIPER_IFML_PPPOE, "PPPoE" }, + { JUNIPER_IFML_ETHERNET_FLEX, "Flexible-Ethernet-Services" }, + { JUNIPER_IFML_FRAMERELAY_FLEX, "Flexible-FrameRelay" }, + { JUNIPER_IFML_COLLECTOR, "Flow-collection" }, + { JUNIPER_IFML_PICPEER, "PIC Peer" }, + { JUNIPER_IFML_DFC, "Dynamic-Flow-Capture" }, + {0, NULL} +}; + +#define JUNIPER_IFLE_ATM_SNAP 2 +#define JUNIPER_IFLE_ATM_NLPID 3 +#define JUNIPER_IFLE_ATM_VCMUX 4 +#define JUNIPER_IFLE_ATM_LLC 5 +#define JUNIPER_IFLE_ATM_PPP_VCMUX 6 +#define JUNIPER_IFLE_ATM_PPP_LLC 7 +#define JUNIPER_IFLE_ATM_PPP_FUNI 8 +#define JUNIPER_IFLE_ATM_CCC 9 +#define JUNIPER_IFLE_FR_NLPID 10 +#define JUNIPER_IFLE_FR_SNAP 11 +#define JUNIPER_IFLE_FR_PPP 12 +#define JUNIPER_IFLE_FR_CCC 13 +#define JUNIPER_IFLE_ENET2 14 +#define JUNIPER_IFLE_IEEE8023_SNAP 15 +#define JUNIPER_IFLE_IEEE8023_LLC 16 +#define JUNIPER_IFLE_PPP 17 +#define JUNIPER_IFLE_CISCOHDLC 18 +#define JUNIPER_IFLE_PPP_CCC 19 +#define JUNIPER_IFLE_IPIP_NULL 20 +#define JUNIPER_IFLE_PIM_NULL 21 +#define JUNIPER_IFLE_GRE_NULL 22 +#define JUNIPER_IFLE_GRE_PPP 23 +#define JUNIPER_IFLE_PIMD_DECAPS 24 +#define JUNIPER_IFLE_CISCOHDLC_CCC 25 +#define JUNIPER_IFLE_ATM_CISCO_NLPID 26 +#define JUNIPER_IFLE_VLAN_CCC 27 +#define JUNIPER_IFLE_MLPPP 28 +#define JUNIPER_IFLE_MLFR 29 +#define JUNIPER_IFLE_LSI_NULL 30 +#define JUNIPER_IFLE_AGGREGATE_UNUSED 31 +#define JUNIPER_IFLE_ATM_CELLRELAY_CCC 32 +#define JUNIPER_IFLE_CRYPTO 33 +#define JUNIPER_IFLE_GGSN 34 +#define JUNIPER_IFLE_ATM_TCC 35 +#define JUNIPER_IFLE_FR_TCC 36 +#define JUNIPER_IFLE_PPP_TCC 37 +#define JUNIPER_IFLE_CISCOHDLC_TCC 38 +#define JUNIPER_IFLE_ETHERNET_CCC 39 +#define JUNIPER_IFLE_VT 40 +#define JUNIPER_IFLE_ATM_EOA_LLC 41 +#define JUNIPER_IFLE_EXTENDED_VLAN_CCC 42 +#define JUNIPER_IFLE_ATM_SNAP_TCC 43 +#define JUNIPER_IFLE_MONITOR 44 +#define JUNIPER_IFLE_ETHERNET_TCC 45 +#define JUNIPER_IFLE_VLAN_TCC 46 +#define JUNIPER_IFLE_EXTENDED_VLAN_TCC 47 +#define JUNIPER_IFLE_MFR 48 +#define JUNIPER_IFLE_ETHERNET_VPLS 49 +#define JUNIPER_IFLE_ETHERNET_VLAN_VPLS 50 +#define JUNIPER_IFLE_ETHERNET_EXTENDED_VLAN_VPLS 51 +#define JUNIPER_IFLE_SERVICES 52 +#define JUNIPER_IFLE_ATM_ETHER_VPLS_ATM_LLC 53 +#define JUNIPER_IFLE_FR_PORT_CCC 54 +#define JUNIPER_IFLE_ATM_MLPPP_LLC 55 +#define JUNIPER_IFLE_ATM_EOA_CCC 56 +#define JUNIPER_IFLE_LT_VLAN 57 +#define JUNIPER_IFLE_COLLECTOR 58 +#define JUNIPER_IFLE_AGGREGATOR 59 +#define JUNIPER_IFLE_LAPD 60 +#define JUNIPER_IFLE_ATM_PPPOE_LLC 61 +#define JUNIPER_IFLE_ETHERNET_PPPOE 62 +#define JUNIPER_IFLE_PPPOE 63 +#define JUNIPER_IFLE_PPP_SUBORDINATE 64 +#define JUNIPER_IFLE_CISCOHDLC_SUBORDINATE 65 +#define JUNIPER_IFLE_DFC 66 +#define JUNIPER_IFLE_PICPEER 67 + +struct tok juniper_ifle_values[] = { + { JUNIPER_IFLE_AGGREGATOR, "Aggregator" }, + { JUNIPER_IFLE_ATM_CCC, "CCC over ATM" }, + { JUNIPER_IFLE_ATM_CELLRELAY_CCC, "ATM CCC Cell Relay" }, + { JUNIPER_IFLE_ATM_CISCO_NLPID, "CISCO compatible NLPID" }, + { JUNIPER_IFLE_ATM_EOA_CCC, "Ethernet over ATM CCC" }, + { JUNIPER_IFLE_ATM_EOA_LLC, "Ethernet over ATM LLC" }, + { JUNIPER_IFLE_ATM_ETHER_VPLS_ATM_LLC, "Ethernet VPLS over ATM LLC" }, + { JUNIPER_IFLE_ATM_LLC, "ATM LLC" }, + { JUNIPER_IFLE_ATM_MLPPP_LLC, "MLPPP over ATM LLC" }, + { JUNIPER_IFLE_ATM_NLPID, "ATM NLPID" }, + { JUNIPER_IFLE_ATM_PPPOE_LLC, "PPPoE over ATM LLC" }, + { JUNIPER_IFLE_ATM_PPP_FUNI, "PPP over FUNI" }, + { JUNIPER_IFLE_ATM_PPP_LLC, "PPP over ATM LLC" }, + { JUNIPER_IFLE_ATM_PPP_VCMUX, "PPP over ATM VCMUX" }, + { JUNIPER_IFLE_ATM_SNAP, "ATM SNAP" }, + { JUNIPER_IFLE_ATM_SNAP_TCC, "ATM SNAP TCC" }, + { JUNIPER_IFLE_ATM_TCC, "ATM VCMUX TCC" }, + { JUNIPER_IFLE_ATM_VCMUX, "ATM VCMUX" }, + { JUNIPER_IFLE_CISCOHDLC, "C-HDLC" }, + { JUNIPER_IFLE_CISCOHDLC_CCC, "C-HDLC CCC" }, + { JUNIPER_IFLE_CISCOHDLC_SUBORDINATE, "C-HDLC via dialer" }, + { JUNIPER_IFLE_CISCOHDLC_TCC, "C-HDLC TCC" }, + { JUNIPER_IFLE_COLLECTOR, "Collector" }, + { JUNIPER_IFLE_CRYPTO, "Crypto" }, + { JUNIPER_IFLE_ENET2, "Ethernet" }, + { JUNIPER_IFLE_ETHERNET_CCC, "Ethernet CCC" }, + { JUNIPER_IFLE_ETHERNET_EXTENDED_VLAN_VPLS, "Extended VLAN VPLS" }, + { JUNIPER_IFLE_ETHERNET_PPPOE, "PPPoE over Ethernet" }, + { JUNIPER_IFLE_ETHERNET_TCC, "Ethernet TCC" }, + { JUNIPER_IFLE_ETHERNET_VLAN_VPLS, "VLAN VPLS" }, + { JUNIPER_IFLE_ETHERNET_VPLS, "VPLS" }, + { JUNIPER_IFLE_EXTENDED_VLAN_CCC, "Extended VLAN CCC" }, + { JUNIPER_IFLE_EXTENDED_VLAN_TCC, "Extended VLAN TCC" }, + { JUNIPER_IFLE_FR_CCC, "FR CCC" }, + { JUNIPER_IFLE_FR_NLPID, "FR NLPID" }, + { JUNIPER_IFLE_FR_PORT_CCC, "FR CCC" }, + { JUNIPER_IFLE_FR_PPP, "FR PPP" }, + { JUNIPER_IFLE_FR_SNAP, "FR SNAP" }, + { JUNIPER_IFLE_FR_TCC, "FR TCC" }, + { JUNIPER_IFLE_GGSN, "GGSN" }, + { JUNIPER_IFLE_GRE_NULL, "GRE NULL" }, + { JUNIPER_IFLE_GRE_PPP, "PPP over GRE" }, + { JUNIPER_IFLE_IPIP_NULL, "IPIP" }, + { JUNIPER_IFLE_LAPD, "LAPD" }, + { JUNIPER_IFLE_LSI_NULL, "LSI Null" }, + { JUNIPER_IFLE_LT_VLAN, "LT VLAN" }, + { JUNIPER_IFLE_MFR, "MFR" }, + { JUNIPER_IFLE_MLFR, "MLFR" }, + { JUNIPER_IFLE_MLPPP, "MLPPP" }, + { JUNIPER_IFLE_MONITOR, "Monitor" }, + { JUNIPER_IFLE_PIMD_DECAPS, "PIMd" }, + { JUNIPER_IFLE_PIM_NULL, "PIM Null" }, + { JUNIPER_IFLE_PPP, "PPP" }, + { JUNIPER_IFLE_PPPOE, "PPPoE" }, + { JUNIPER_IFLE_PPP_CCC, "PPP CCC" }, + { JUNIPER_IFLE_PPP_SUBORDINATE, "" }, + { JUNIPER_IFLE_PPP_TCC, "PPP TCC" }, + { JUNIPER_IFLE_SERVICES, "General Services" }, + { JUNIPER_IFLE_VLAN_CCC, "VLAN CCC" }, + { JUNIPER_IFLE_VLAN_TCC, "VLAN TCC" }, + { JUNIPER_IFLE_VT, "VT" }, + {0, NULL} +}; + +struct juniper_cookie_table_t { + u_int32_t pictype; /* pic type */ + u_int8_t cookie_len; /* cookie len */ + const char *s; /* pic name */ +}; + +static struct juniper_cookie_table_t juniper_cookie_table[] = { +#ifdef DLT_JUNIPER_ATM1 + { DLT_JUNIPER_ATM1, 4, "ATM1"}, +#endif +#ifdef DLT_JUNIPER_ATM2 + { DLT_JUNIPER_ATM2, 8, "ATM2"}, +#endif +#ifdef DLT_JUNIPER_MLPPP + { DLT_JUNIPER_MLPPP, 2, "MLPPP"}, +#endif +#ifdef DLT_JUNIPER_MLFR + { DLT_JUNIPER_MLFR, 2, "MLFR"}, +#endif +#ifdef DLT_JUNIPER_MFR + { DLT_JUNIPER_MFR, 4, "MFR"}, +#endif +#ifdef DLT_JUNIPER_PPPOE + { DLT_JUNIPER_PPPOE, 0, "PPPoE"}, +#endif +#ifdef DLT_JUNIPER_PPPOE_ATM + { DLT_JUNIPER_PPPOE_ATM, 0, "PPPoE ATM"}, +#endif +#ifdef DLT_JUNIPER_GGSN + { DLT_JUNIPER_GGSN, 8, "GGSN"}, +#endif +#ifdef DLT_JUNIPER_MONITOR + { DLT_JUNIPER_MONITOR, 8, "MONITOR"}, +#endif +#ifdef DLT_JUNIPER_SERVICES + { DLT_JUNIPER_SERVICES, 8, "AS"}, +#endif +#ifdef DLT_JUNIPER_ES + { DLT_JUNIPER_ES, 0, "ES"}, +#endif + { 0, 0, NULL } +}; + +struct juniper_l2info_t { + u_int32_t length; + u_int32_t caplen; + u_int32_t pictype; + u_int8_t direction; + u_int8_t header_len; + u_int8_t cookie_len; + u_int8_t cookie_type; + u_int8_t cookie[8]; + u_int8_t bundle; + u_int16_t proto; + u_int8_t flags; +}; + +#define LS_COOKIE_ID 0x54 +#define AS_COOKIE_ID 0x47 +#define LS_MLFR_COOKIE_LEN 4 +#define ML_MLFR_COOKIE_LEN 2 +#define LS_MFR_COOKIE_LEN 6 +#define ATM1_COOKIE_LEN 4 +#define ATM2_COOKIE_LEN 8 + +#define ATM2_PKT_TYPE_MASK 0x70 +#define ATM2_GAP_COUNT_MASK 0x3F + +#define JUNIPER_PROTO_NULL 1 +#define JUNIPER_PROTO_IPV4 2 +#define JUNIPER_PROTO_IPV6 6 + +#define MFR_BE_MASK 0xc0 + +static struct tok juniper_protocol_values[] = { + { JUNIPER_PROTO_NULL, "Null" }, + { JUNIPER_PROTO_IPV4, "IPv4" }, + { JUNIPER_PROTO_IPV6, "IPv6" }, + { 0, NULL} +}; + +int ip_heuristic_guess(register const u_char *, u_int); +int juniper_ppp_heuristic_guess(register const u_char *, u_int); +int juniper_read_tlv_value(const u_char *, u_int, u_int); +static int juniper_parse_header (const u_char *, const struct pcap_pkthdr *, struct juniper_l2info_t *); + +#ifdef DLT_JUNIPER_GGSN +u_int +juniper_ggsn_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + struct juniper_ggsn_header { + u_int8_t svc_id; + u_int8_t flags_len; + u_int8_t proto; + u_int8_t flags; + u_int8_t vlan_id[2]; + u_int8_t res[2]; + }; + const struct juniper_ggsn_header *gh; + + l2info.pictype = DLT_JUNIPER_GGSN; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + gh = (struct juniper_ggsn_header *)&l2info.cookie; + + if (eflag) { + printf("proto %s (%u), vlan %u: ", + tok2str(juniper_protocol_values,"Unknown",gh->proto), + gh->proto, + EXTRACT_16BITS(&gh->vlan_id[0])); + } + + switch (gh->proto) { + case JUNIPER_PROTO_IPV4: + ip_print(gndo, p, l2info.length); + break; +#ifdef INET6 + case JUNIPER_PROTO_IPV6: + ip6_print(p, l2info.length); + break; +#endif /* INET6 */ + default: + if (!eflag) + printf("unknown GGSN proto (%u)", gh->proto); + } + + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_ES +u_int +juniper_es_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + struct juniper_ipsec_header { + u_int8_t sa_index[2]; + u_int8_t ttl; + u_int8_t type; + u_int8_t spi[4]; + u_int8_t src_ip[4]; + u_int8_t dst_ip[4]; + }; + u_int rewrite_len,es_type_bundle; + const struct juniper_ipsec_header *ih; + + l2info.pictype = DLT_JUNIPER_ES; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + ih = (struct juniper_ipsec_header *)p; + + switch (ih->type) { + case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE: + case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE: + rewrite_len = 0; + es_type_bundle = 1; + break; + case JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE: + case JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE: + case JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE: + rewrite_len = 16; + es_type_bundle = 0; + default: + printf("ES Invalid type %u, length %u", + ih->type, + l2info.length); + return l2info.header_len; + } + + l2info.length-=rewrite_len; + p+=rewrite_len; + + if (eflag) { + if (!es_type_bundle) { + printf("ES SA, index %u, ttl %u type %s (%u), spi %u, Tunnel %s > %s, length %u\n", + EXTRACT_16BITS(&ih->sa_index), + ih->ttl, + tok2str(juniper_ipsec_type_values,"Unknown",ih->type), + ih->type, + EXTRACT_32BITS(&ih->spi), + ipaddr_string(&ih->src_ip), + ipaddr_string(&ih->dst_ip), + l2info.length); + } else { + printf("ES SA, index %u, ttl %u type %s (%u), length %u\n", + EXTRACT_16BITS(&ih->sa_index), + ih->ttl, + tok2str(juniper_ipsec_type_values,"Unknown",ih->type), + ih->type, + l2info.length); + } + } + + ip_print(gndo, p, l2info.length); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_MONITOR +u_int +juniper_monitor_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + struct juniper_monitor_header { + u_int8_t pkt_type; + u_int8_t padding; + u_int8_t iif[2]; + u_int8_t service_id[4]; + }; + const struct juniper_monitor_header *mh; + + l2info.pictype = DLT_JUNIPER_MONITOR; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + mh = (struct juniper_monitor_header *)p; + + if (eflag) + printf("service-id %u, iif %u, pkt-type %u: ", + EXTRACT_32BITS(&mh->service_id), + EXTRACT_16BITS(&mh->iif), + mh->pkt_type); + + /* no proto field - lets guess by first byte of IP header*/ + ip_heuristic_guess(p, l2info.length); + + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_SERVICES +u_int +juniper_services_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + struct juniper_services_header { + u_int8_t svc_id; + u_int8_t flags_len; + u_int8_t svc_set_id[2]; + u_int8_t dir_iif[4]; + }; + const struct juniper_services_header *sh; + + l2info.pictype = DLT_JUNIPER_SERVICES; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + sh = (struct juniper_services_header *)p; + + if (eflag) + printf("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ", + sh->svc_id, + sh->flags_len, + EXTRACT_16BITS(&sh->svc_set_id), + EXTRACT_24BITS(&sh->dir_iif[1])); + + /* no proto field - lets guess by first byte of IP header*/ + ip_heuristic_guess(p, l2info.length); + + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_PPPOE +u_int +juniper_pppoe_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_PPPOE; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + /* this DLT contains nothing but raw ethernet frames */ + ether_print(p, l2info.length, l2info.caplen, NULL, NULL); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_ETHER +u_int +juniper_ether_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_ETHER; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + /* this DLT contains nothing but raw Ethernet frames */ + ether_print(p, l2info.length, l2info.caplen, NULL, NULL); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_PPP +u_int +juniper_ppp_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_PPP; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + /* this DLT contains nothing but raw ppp frames */ + ppp_print(p, l2info.length); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_FRELAY +u_int +juniper_frelay_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_FRELAY; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + /* this DLT contains nothing but raw frame-relay frames */ + fr_print(p, l2info.length); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_CHDLC +u_int +juniper_chdlc_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_CHDLC; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + /* this DLT contains nothing but raw c-hdlc frames */ + chdlc_print(p, l2info.length); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_PPPOE_ATM +u_int +juniper_pppoe_atm_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + u_int16_t extracted_ethertype; + + l2info.pictype = DLT_JUNIPER_PPPOE_ATM; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + + extracted_ethertype = EXTRACT_16BITS(p); + /* this DLT contains nothing but raw PPPoE frames, + * prepended with a type field*/ + if (ethertype_print(extracted_ethertype, + p+ETHERTYPE_LEN, + l2info.length-ETHERTYPE_LEN, + l2info.caplen-ETHERTYPE_LEN) == 0) + /* ether_type not known, probably it wasn't one */ + printf("unknown ethertype 0x%04x", extracted_ethertype); + + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_MLPPP +u_int +juniper_mlppp_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_MLPPP; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + /* suppress Bundle-ID if frame was captured on a child-link + * best indicator if the cookie looks like a proto */ + if (eflag && + EXTRACT_16BITS(&l2info.cookie) != PPP_OSI && + EXTRACT_16BITS(&l2info.cookie) != (PPP_ADDRESS << 8 | PPP_CONTROL)) + printf("Bundle-ID %u: ",l2info.bundle); + + p+=l2info.header_len; + + /* first try the LSQ protos */ + switch(l2info.proto) { + case JUNIPER_LSQ_L3_PROTO_IPV4: + /* IP traffic going to the RE would not have a cookie + * -> this must be incoming IS-IS over PPP + */ + if (l2info.cookie[4] == (JUNIPER_LSQ_COOKIE_RE|JUNIPER_LSQ_COOKIE_DIR)) + ppp_print(p, l2info.length); + else + ip_print(gndo, p, l2info.length); + return l2info.header_len; +#ifdef INET6 + case JUNIPER_LSQ_L3_PROTO_IPV6: + ip6_print(p,l2info.length); + return l2info.header_len; +#endif + case JUNIPER_LSQ_L3_PROTO_MPLS: + mpls_print(p,l2info.length); + return l2info.header_len; + case JUNIPER_LSQ_L3_PROTO_ISO: + isoclns_print(p,l2info.length,l2info.caplen); + return l2info.header_len; + default: + break; + } + + /* zero length cookie ? */ + switch (EXTRACT_16BITS(&l2info.cookie)) { + case PPP_OSI: + ppp_print(p-2,l2info.length+2); + break; + case (PPP_ADDRESS << 8 | PPP_CONTROL): /* fall through */ + default: + ppp_print(p,l2info.length); + break; + } + + return l2info.header_len; +} +#endif + + +#ifdef DLT_JUNIPER_MFR +u_int +juniper_mfr_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_MFR; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + + /* child-link ? */ + if (l2info.cookie_len == 0) { + mfr_print(p,l2info.length); + return l2info.header_len; + } + + /* first try the LSQ protos */ + if (l2info.cookie_len == AS_PIC_COOKIE_LEN) { + switch(l2info.proto) { + case JUNIPER_LSQ_L3_PROTO_IPV4: + ip_print(gndo, p, l2info.length); + return l2info.header_len; +#ifdef INET6 + case JUNIPER_LSQ_L3_PROTO_IPV6: + ip6_print(p,l2info.length); + return l2info.header_len; +#endif + case JUNIPER_LSQ_L3_PROTO_MPLS: + mpls_print(p,l2info.length); + return l2info.header_len; + case JUNIPER_LSQ_L3_PROTO_ISO: + isoclns_print(p,l2info.length,l2info.caplen); + return l2info.header_len; + default: + break; + } + return l2info.header_len; + } + + /* suppress Bundle-ID if frame was captured on a child-link */ + if (eflag && EXTRACT_32BITS(l2info.cookie) != 1) printf("Bundle-ID %u, ",l2info.bundle); + switch (l2info.proto) { + case (LLCSAP_ISONS<<8 | LLCSAP_ISONS): + isoclns_print(p+1, l2info.length-1, l2info.caplen-1); + break; + case (LLC_UI<<8 | NLPID_Q933): + case (LLC_UI<<8 | NLPID_IP): + case (LLC_UI<<8 | NLPID_IP6): + /* pass IP{4,6} to the OSI layer for proper link-layer printing */ + isoclns_print(p-1, l2info.length+1, l2info.caplen+1); + break; + default: + printf("unknown protocol 0x%04x, length %u",l2info.proto, l2info.length); + } + + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_MLFR +u_int +juniper_mlfr_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_MLFR; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + + /* suppress Bundle-ID if frame was captured on a child-link */ + if (eflag && EXTRACT_32BITS(l2info.cookie) != 1) printf("Bundle-ID %u, ",l2info.bundle); + switch (l2info.proto) { + case (LLC_UI): + case (LLC_UI<<8): + isoclns_print(p, l2info.length, l2info.caplen); + break; + case (LLC_UI<<8 | NLPID_Q933): + case (LLC_UI<<8 | NLPID_IP): + case (LLC_UI<<8 | NLPID_IP6): + /* pass IP{4,6} to the OSI layer for proper link-layer printing */ + isoclns_print(p-1, l2info.length+1, l2info.caplen+1); + break; + default: + printf("unknown protocol 0x%04x, length %u",l2info.proto, l2info.length); + } + + return l2info.header_len; +} +#endif + +/* + * ATM1 PIC cookie format + * + * +-----+-------------------------+-------------------------------+ + * |fmtid| vc index | channel ID | + * +-----+-------------------------+-------------------------------+ + */ + +#ifdef DLT_JUNIPER_ATM1 +u_int +juniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + u_int16_t extracted_ethertype; + + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_ATM1; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + + if (l2info.cookie[0] == 0x80) { /* OAM cell ? */ + oam_print(p,l2info.length,ATM_OAM_NOHEC); + return l2info.header_len; + } + + if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ + EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ + + if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL, + &extracted_ethertype) != 0) + return l2info.header_len; + } + + if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */ + isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1); + /* FIXME check if frame was recognized */ + return l2info.header_len; + } + + if(ip_heuristic_guess(p, l2info.length) != 0) /* last try - vcmux encaps ? */ + return l2info.header_len; + + return l2info.header_len; +} +#endif + +/* + * ATM2 PIC cookie format + * + * +-------------------------------+---------+---+-----+-----------+ + * | channel ID | reserv |AAL| CCRQ| gap cnt | + * +-------------------------------+---------+---+-----+-----------+ + */ + +#ifdef DLT_JUNIPER_ATM2 +u_int +juniper_atm2_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + u_int16_t extracted_ethertype; + + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_ATM2; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + + if (l2info.cookie[7] & ATM2_PKT_TYPE_MASK) { /* OAM cell ? */ + oam_print(p,l2info.length,ATM_OAM_NOHEC); + return l2info.header_len; + } + + if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ + EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ + + if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL, + &extracted_ethertype) != 0) + return l2info.header_len; + } + + if (l2info.direction != JUNIPER_BPF_PKT_IN && /* ether-over-1483 encaps ? */ + (EXTRACT_32BITS(l2info.cookie) & ATM2_GAP_COUNT_MASK)) { + ether_print(p, l2info.length, l2info.caplen, NULL, NULL); + return l2info.header_len; + } + + if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */ + isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1); + /* FIXME check if frame was recognized */ + return l2info.header_len; + } + + if(juniper_ppp_heuristic_guess(p, l2info.length) != 0) /* PPPoA vcmux encaps ? */ + return l2info.header_len; + + if(ip_heuristic_guess(p, l2info.length) != 0) /* last try - vcmux encaps ? */ + return l2info.header_len; + + return l2info.header_len; +} +#endif + + +/* try to guess, based on all PPP protos that are supported in + * a juniper router if the payload data is encapsulated using PPP */ +int +juniper_ppp_heuristic_guess(register const u_char *p, u_int length) { + + switch(EXTRACT_16BITS(p)) { + case PPP_IP : + case PPP_OSI : + case PPP_MPLS_UCAST : + case PPP_MPLS_MCAST : + case PPP_IPCP : + case PPP_OSICP : + case PPP_MPLSCP : + case PPP_LCP : + case PPP_PAP : + case PPP_CHAP : + case PPP_ML : +#ifdef INET6 + case PPP_IPV6 : + case PPP_IPV6CP : +#endif + ppp_print(p, length); + break; + + default: + return 0; /* did not find a ppp header */ + break; + } + return 1; /* we printed a ppp packet */ +} + +int +ip_heuristic_guess(register const u_char *p, u_int length) { + + switch(p[0]) { + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + ip_print(gndo, p, length); + break; +#ifdef INET6 + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + ip6_print(p, length); + break; +#endif + default: + return 0; /* did not find a ip header */ + break; + } + return 1; /* we printed an v4/v6 packet */ +} + +int +juniper_read_tlv_value(const u_char *p, u_int tlv_type, u_int tlv_len) { + + int tlv_value; + + /* TLVs < 128 are little endian encoded */ + if (tlv_type < 128) { + switch (tlv_len) { + case 1: + tlv_value = *p; + break; + case 2: + tlv_value = EXTRACT_LE_16BITS(p); + break; + case 3: + tlv_value = EXTRACT_LE_24BITS(p); + break; + case 4: + tlv_value = EXTRACT_LE_32BITS(p); + break; + default: + tlv_value = -1; + break; + } + } else { + /* TLVs >= 128 are big endian encoded */ + switch (tlv_len) { + case 1: + tlv_value = *p; + break; + case 2: + tlv_value = EXTRACT_16BITS(p); + break; + case 3: + tlv_value = EXTRACT_24BITS(p); + break; + case 4: + tlv_value = EXTRACT_32BITS(p); + break; + default: + tlv_value = -1; + break; + } + } + return tlv_value; +} + +static int +juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info) { + + struct juniper_cookie_table_t *lp = juniper_cookie_table; + u_int idx, jnx_ext_len, jnx_header_len = 0; + u_int8_t tlv_type,tlv_len; + u_int32_t control_word; + int tlv_value; + const u_char *tptr; + + + l2info->header_len = 0; + l2info->cookie_len = 0; + l2info->proto = 0; + + + l2info->length = h->len; + l2info->caplen = h->caplen; + TCHECK2(p[0],4); + l2info->flags = p[3]; + l2info->direction = p[3]&JUNIPER_BPF_PKT_IN; + + if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */ + printf("no magic-number found!"); + return 0; + } + + if (eflag) /* print direction */ + printf("%3s ",tok2str(juniper_direction_values,"---",l2info->direction)); + + /* magic number + flags */ + jnx_header_len = 4; + + if (vflag>1) + printf("\n\tJuniper PCAP Flags [%s]", + bittok2str(jnx_flag_values, "none", l2info->flags)); + + /* extensions present ? - calculate how much bytes to skip */ + if ((l2info->flags & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) { + + tptr = p+jnx_header_len; + + /* ok to read extension length ? */ + TCHECK2(tptr[0], 2); + jnx_ext_len = EXTRACT_16BITS(tptr); + jnx_header_len += 2; + tptr +=2; + + /* nail up the total length - + * just in case something goes wrong + * with TLV parsing */ + jnx_header_len += jnx_ext_len; + + if (vflag>1) + printf(", PCAP Extension(s) total length %u", + jnx_ext_len); + + TCHECK2(tptr[0], jnx_ext_len); + while (jnx_ext_len > JUNIPER_EXT_TLV_OVERHEAD) { + tlv_type = *(tptr++); + tlv_len = *(tptr++); + tlv_value = 0; + + /* sanity check */ + if (tlv_type == 0 || tlv_len == 0) + break; + + if (vflag>1) + printf("\n\t %s Extension TLV #%u, length %u, value ", + tok2str(jnx_ext_tlv_values,"Unknown",tlv_type), + tlv_type, + tlv_len); + + tlv_value = juniper_read_tlv_value(tptr, tlv_type, tlv_len); + switch (tlv_type) { + case JUNIPER_EXT_TLV_IFD_NAME: + /* FIXME */ + break; + case JUNIPER_EXT_TLV_IFD_MEDIATYPE: + case JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE: + if (tlv_value != -1) { + if (vflag>1) + printf("%s (%u)", + tok2str(juniper_ifmt_values, "Unknown", tlv_value), + tlv_value); + } + break; + case JUNIPER_EXT_TLV_IFL_ENCAPS: + case JUNIPER_EXT_TLV_TTP_IFL_ENCAPS: + if (tlv_value != -1) { + if (vflag>1) + printf("%s (%u)", + tok2str(juniper_ifle_values, "Unknown", tlv_value), + tlv_value); + } + break; + case JUNIPER_EXT_TLV_IFL_IDX: /* fall through */ + case JUNIPER_EXT_TLV_IFL_UNIT: + case JUNIPER_EXT_TLV_IFD_IDX: + default: + if (tlv_value != -1) { + if (vflag>1) + printf("%u",tlv_value); + } + break; + } + + tptr+=tlv_len; + jnx_ext_len -= tlv_len+JUNIPER_EXT_TLV_OVERHEAD; + } + + if (vflag>1) + printf("\n\t-----original packet-----\n\t"); + } + + if ((l2info->flags & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) { + if (eflag) + printf("no-L2-hdr, "); + + /* there is no link-layer present - + * perform the v4/v6 heuristics + * to figure out what it is + */ + TCHECK2(p[jnx_header_len+4],1); + if(ip_heuristic_guess(p+jnx_header_len+4,l2info->length-(jnx_header_len+4)) == 0) + printf("no IP-hdr found!"); + + l2info->header_len=jnx_header_len+4; + return 0; /* stop parsing the output further */ + + } + l2info->header_len = jnx_header_len; + p+=l2info->header_len; + l2info->length -= l2info->header_len; + l2info->caplen -= l2info->header_len; + + /* search through the cookie table and copy values matching for our PIC type */ + while (lp->s != NULL) { + if (lp->pictype == l2info->pictype) { + + l2info->cookie_len += lp->cookie_len; + + switch (p[0]) { + case LS_COOKIE_ID: + l2info->cookie_type = LS_COOKIE_ID; + l2info->cookie_len += 2; + break; + case AS_COOKIE_ID: + l2info->cookie_type = AS_COOKIE_ID; + l2info->cookie_len = 8; + break; + + default: + l2info->bundle = l2info->cookie[0]; + break; + } + + +#ifdef DLT_JUNIPER_MFR + /* MFR child links don't carry cookies */ + if (l2info->pictype == DLT_JUNIPER_MFR && + (p[0] & MFR_BE_MASK) == MFR_BE_MASK) { + l2info->cookie_len = 0; + } +#endif + + l2info->header_len += l2info->cookie_len; + l2info->length -= l2info->cookie_len; + l2info->caplen -= l2info->cookie_len; + + if (eflag) + printf("%s-PIC, cookie-len %u", + lp->s, + l2info->cookie_len); + + if (l2info->cookie_len > 0) { + TCHECK2(p[0],l2info->cookie_len); + if (eflag) + printf(", cookie 0x"); + for (idx = 0; idx < l2info->cookie_len; idx++) { + l2info->cookie[idx] = p[idx]; /* copy cookie data */ + if (eflag) printf("%02x",p[idx]); + } + } + + if (eflag) printf(": "); /* print demarc b/w L2/L3*/ + + + l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len); + break; + } + ++lp; + } + p+=l2info->cookie_len; + + /* DLT_ specific parsing */ + switch(l2info->pictype) { +#ifdef DLT_JUNIPER_MLPPP + case DLT_JUNIPER_MLPPP: + switch (l2info->cookie_type) { + case LS_COOKIE_ID: + l2info->bundle = l2info->cookie[1]; + break; + case AS_COOKIE_ID: + l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; + l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; + break; + default: + l2info->bundle = l2info->cookie[0]; + break; + } + break; +#endif +#ifdef DLT_JUNIPER_MLFR + case DLT_JUNIPER_MLFR: + switch (l2info->cookie_type) { + case LS_COOKIE_ID: + l2info->bundle = l2info->cookie[1]; + l2info->proto = EXTRACT_16BITS(p); + l2info->header_len += 2; + l2info->length -= 2; + l2info->caplen -= 2; + break; + case AS_COOKIE_ID: + l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; + l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; + break; + default: + l2info->bundle = l2info->cookie[0]; + l2info->header_len += 2; + l2info->length -= 2; + l2info->caplen -= 2; + break; + } + break; +#endif +#ifdef DLT_JUNIPER_MFR + case DLT_JUNIPER_MFR: + switch (l2info->cookie_type) { + case LS_COOKIE_ID: + l2info->bundle = l2info->cookie[1]; + l2info->proto = EXTRACT_16BITS(p); + l2info->header_len += 2; + l2info->length -= 2; + l2info->caplen -= 2; + break; + case AS_COOKIE_ID: + l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; + l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; + break; + default: + l2info->bundle = l2info->cookie[0]; + break; + } + break; +#endif +#ifdef DLT_JUNIPER_ATM2 + case DLT_JUNIPER_ATM2: + TCHECK2(p[0],4); + /* ATM cell relay control word present ? */ + if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) { + control_word = EXTRACT_32BITS(p); + /* some control word heuristics */ + switch(control_word) { + case 0: /* zero control word */ + case 0x08000000: /* < JUNOS 7.4 control-word */ + case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/ + l2info->header_len += 4; + break; + default: + break; + } + + if (eflag) + printf("control-word 0x%08x ", control_word); + } + break; +#endif +#ifdef DLT_JUNIPER_GGSN + case DLT_JUNIPER_GGSN: + break; +#endif +#ifdef DLT_JUNIPER_ATM1 + case DLT_JUNIPER_ATM1: + break; +#endif +#ifdef DLT_JUNIPER_PPP + case DLT_JUNIPER_PPP: + break; +#endif +#ifdef DLT_JUNIPER_CHDLC + case DLT_JUNIPER_CHDLC: + break; +#endif +#ifdef DLT_JUNIPER_ETHER + case DLT_JUNIPER_ETHER: + break; +#endif +#ifdef DLT_JUNIPER_FRELAY + case DLT_JUNIPER_FRELAY: + break; +#endif + + default: + printf("Unknown Juniper DLT_ type %u: ", l2info->pictype); + break; + } + + if (eflag > 1) + printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto); + + return 1; /* everything went ok so far. continue parsing */ + trunc: + printf("[|juniper_hdr], length %u",h->len); + return 0; +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/print-krb.c b/print-krb.c new file mode 100644 index 0000000..213db64 --- /dev/null +++ b/print-krb.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Initial contribution from John Hawkinson (jhawk@mit.edu). + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-krb.c,v 1.23 2003-11-16 09:36:26 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +static const u_char *c_print(register const u_char *, register const u_char *); +static const u_char *krb4_print_hdr(const u_char *); +static void krb4_print(const u_char *); + +#define AUTH_MSG_KDC_REQUEST 1<<1 +#define AUTH_MSG_KDC_REPLY 2<<1 +#define AUTH_MSG_APPL_REQUEST 3<<1 +#define AUTH_MSG_APPL_REQUEST_MUTUAL 4<<1 +#define AUTH_MSG_ERR_REPLY 5<<1 +#define AUTH_MSG_PRIVATE 6<<1 +#define AUTH_MSG_SAFE 7<<1 +#define AUTH_MSG_APPL_ERR 8<<1 +#define AUTH_MSG_DIE 63<<1 + +#define KERB_ERR_OK 0 +#define KERB_ERR_NAME_EXP 1 +#define KERB_ERR_SERVICE_EXP 2 +#define KERB_ERR_AUTH_EXP 3 +#define KERB_ERR_PKT_VER 4 +#define KERB_ERR_NAME_MAST_KEY_VER 5 +#define KERB_ERR_SERV_MAST_KEY_VER 6 +#define KERB_ERR_BYTE_ORDER 7 +#define KERB_ERR_PRINCIPAL_UNKNOWN 8 +#define KERB_ERR_PRINCIPAL_NOT_UNIQUE 9 +#define KERB_ERR_NULL_KEY 10 + +struct krb { + u_int8_t pvno; /* Protocol Version */ + u_int8_t type; /* Type+B */ +}; + +static char tstr[] = " [|kerberos]"; + +static struct tok type2str[] = { + { AUTH_MSG_KDC_REQUEST, "KDC_REQUEST" }, + { AUTH_MSG_KDC_REPLY, "KDC_REPLY" }, + { AUTH_MSG_APPL_REQUEST, "APPL_REQUEST" }, + { AUTH_MSG_APPL_REQUEST_MUTUAL, "APPL_REQUEST_MUTUAL" }, + { AUTH_MSG_ERR_REPLY, "ERR_REPLY" }, + { AUTH_MSG_PRIVATE, "PRIVATE" }, + { AUTH_MSG_SAFE, "SAFE" }, + { AUTH_MSG_APPL_ERR, "APPL_ERR" }, + { AUTH_MSG_DIE, "DIE" }, + { 0, NULL } +}; + +static struct tok kerr2str[] = { + { KERB_ERR_OK, "OK" }, + { KERB_ERR_NAME_EXP, "NAME_EXP" }, + { KERB_ERR_SERVICE_EXP, "SERVICE_EXP" }, + { KERB_ERR_AUTH_EXP, "AUTH_EXP" }, + { KERB_ERR_PKT_VER, "PKT_VER" }, + { KERB_ERR_NAME_MAST_KEY_VER, "NAME_MAST_KEY_VER" }, + { KERB_ERR_SERV_MAST_KEY_VER, "SERV_MAST_KEY_VER" }, + { KERB_ERR_BYTE_ORDER, "BYTE_ORDER" }, + { KERB_ERR_PRINCIPAL_UNKNOWN, "PRINCIPAL_UNKNOWN" }, + { KERB_ERR_PRINCIPAL_NOT_UNIQUE,"PRINCIPAL_NOT_UNIQUE" }, + { KERB_ERR_NULL_KEY, "NULL_KEY"}, + { 0, NULL} +}; + +static const u_char * +c_print(register const u_char *s, register const u_char *ep) +{ + register u_char c; + register int flag; + + flag = 1; + while (s < ep) { + c = *s++; + if (c == '\0') { + flag = 0; + break; + } + if (!isascii(c)) { + c = toascii(c); + putchar('M'); + putchar('-'); + } + if (!isprint(c)) { + c ^= 0x40; /* DEL to ?, others to alpha */ + putchar('^'); + } + putchar(c); + } + if (flag) + return NULL; + return (s); +} + +static const u_char * +krb4_print_hdr(const u_char *cp) +{ + cp += 2; + +#define PRINT if ((cp = c_print(cp, snapend)) == NULL) goto trunc + + PRINT; + putchar('.'); + PRINT; + putchar('@'); + PRINT; + return (cp); + +trunc: + fputs(tstr, stdout); + return (NULL); + +#undef PRINT +} + +static void +krb4_print(const u_char *cp) +{ + register const struct krb *kp; + u_char type; + u_short len; + +#define PRINT if ((cp = c_print(cp, snapend)) == NULL) goto trunc +/* True if struct krb is little endian */ +#define IS_LENDIAN(kp) (((kp)->type & 0x01) != 0) +#define KTOHSP(kp, cp) (IS_LENDIAN(kp) ? EXTRACT_LE_16BITS(cp) : EXTRACT_16BITS(cp)) + + kp = (struct krb *)cp; + + if ((&kp->type) >= snapend) { + fputs(tstr, stdout); + return; + } + + type = kp->type & (0xFF << 1); + + printf(" %s %s: ", + IS_LENDIAN(kp) ? "le" : "be", tok2str(type2str, NULL, type)); + + switch (type) { + + case AUTH_MSG_KDC_REQUEST: + if ((cp = krb4_print_hdr(cp)) == NULL) + return; + cp += 4; /* ctime */ + TCHECK(*cp); + printf(" %dmin ", *cp++ * 5); + PRINT; + putchar('.'); + PRINT; + break; + + case AUTH_MSG_APPL_REQUEST: + cp += 2; + TCHECK(*cp); + printf("v%d ", *cp++); + PRINT; + TCHECK(*cp); + printf(" (%d)", *cp++); + TCHECK(*cp); + printf(" (%d)", *cp); + break; + + case AUTH_MSG_KDC_REPLY: + if ((cp = krb4_print_hdr(cp)) == NULL) + return; + cp += 10; /* timestamp + n + exp + kvno */ + TCHECK2(*cp, sizeof(short)); + len = KTOHSP(kp, cp); + printf(" (%d)", len); + break; + + case AUTH_MSG_ERR_REPLY: + if ((cp = krb4_print_hdr(cp)) == NULL) + return; + cp += 4; /* timestamp */ + TCHECK2(*cp, sizeof(short)); + printf(" %s ", tok2str(kerr2str, NULL, KTOHSP(kp, cp))); + cp += 4; + PRINT; + break; + + default: + fputs("(unknown)", stdout); + break; + } + + return; +trunc: + fputs(tstr, stdout); +} + +void +krb_print(const u_char *dat) +{ + register const struct krb *kp; + + kp = (struct krb *)dat; + + if (dat >= snapend) { + fputs(tstr, stdout); + return; + } + + switch (kp->pvno) { + + case 1: + case 2: + case 3: + printf(" v%d", kp->pvno); + break; + + case 4: + printf(" v%d", kp->pvno); + krb4_print((const u_char *)kp); + break; + + case 106: + case 107: + fputs(" v5", stdout); + /* Decode ASN.1 here "someday" */ + break; + } + return; +} diff --git a/print-l2tp.c b/print-l2tp.c new file mode 100644 index 0000000..2f72657 --- /dev/null +++ b/print-l2tp.c @@ -0,0 +1,719 @@ +/* + * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * L2TP support contributed by Motonori Shindo (mshindo@mshindo.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-l2tp.c,v 1.20 2006-06-23 02:03:09 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "l2tp.h" +#include "interface.h" +#include "extract.h" + +static char tstr[] = " [|l2tp]"; + +#define L2TP_MSGTYPE_SCCRQ 1 /* Start-Control-Connection-Request */ +#define L2TP_MSGTYPE_SCCRP 2 /* Start-Control-Connection-Reply */ +#define L2TP_MSGTYPE_SCCCN 3 /* Start-Control-Connection-Connected */ +#define L2TP_MSGTYPE_STOPCCN 4 /* Stop-Control-Connection-Notification */ +#define L2TP_MSGTYPE_HELLO 6 /* Hello */ +#define L2TP_MSGTYPE_OCRQ 7 /* Outgoing-Call-Request */ +#define L2TP_MSGTYPE_OCRP 8 /* Outgoing-Call-Reply */ +#define L2TP_MSGTYPE_OCCN 9 /* Outgoing-Call-Connected */ +#define L2TP_MSGTYPE_ICRQ 10 /* Incoming-Call-Request */ +#define L2TP_MSGTYPE_ICRP 11 /* Incoming-Call-Reply */ +#define L2TP_MSGTYPE_ICCN 12 /* Incoming-Call-Connected */ +#define L2TP_MSGTYPE_CDN 14 /* Call-Disconnect-Notify */ +#define L2TP_MSGTYPE_WEN 15 /* WAN-Error-Notify */ +#define L2TP_MSGTYPE_SLI 16 /* Set-Link-Info */ + +static struct tok l2tp_msgtype2str[] = { + { L2TP_MSGTYPE_SCCRQ, "SCCRQ" }, + { L2TP_MSGTYPE_SCCRP, "SCCRP" }, + { L2TP_MSGTYPE_SCCCN, "SCCCN" }, + { L2TP_MSGTYPE_STOPCCN, "StopCCN" }, + { L2TP_MSGTYPE_HELLO, "HELLO" }, + { L2TP_MSGTYPE_OCRQ, "OCRQ" }, + { L2TP_MSGTYPE_OCRP, "OCRP" }, + { L2TP_MSGTYPE_OCCN, "OCCN" }, + { L2TP_MSGTYPE_ICRQ, "ICRQ" }, + { L2TP_MSGTYPE_ICRP, "ICRP" }, + { L2TP_MSGTYPE_ICCN, "ICCN" }, + { L2TP_MSGTYPE_CDN, "CDN" }, + { L2TP_MSGTYPE_WEN, "WEN" }, + { L2TP_MSGTYPE_SLI, "SLI" }, + { 0, NULL } +}; + +#define L2TP_AVP_MSGTYPE 0 /* Message Type */ +#define L2TP_AVP_RESULT_CODE 1 /* Result Code */ +#define L2TP_AVP_PROTO_VER 2 /* Protocol Version */ +#define L2TP_AVP_FRAMING_CAP 3 /* Framing Capabilities */ +#define L2TP_AVP_BEARER_CAP 4 /* Bearer Capabilities */ +#define L2TP_AVP_TIE_BREAKER 5 /* Tie Breaker */ +#define L2TP_AVP_FIRM_VER 6 /* Firmware Revision */ +#define L2TP_AVP_HOST_NAME 7 /* Host Name */ +#define L2TP_AVP_VENDOR_NAME 8 /* Vendor Name */ +#define L2TP_AVP_ASSND_TUN_ID 9 /* Assigned Tunnel ID */ +#define L2TP_AVP_RECV_WIN_SIZE 10 /* Receive Window Size */ +#define L2TP_AVP_CHALLENGE 11 /* Challenge */ +#define L2TP_AVP_Q931_CC 12 /* Q.931 Cause Code */ +#define L2TP_AVP_CHALLENGE_RESP 13 /* Challenge Response */ +#define L2TP_AVP_ASSND_SESS_ID 14 /* Assigned Session ID */ +#define L2TP_AVP_CALL_SER_NUM 15 /* Call Serial Number */ +#define L2TP_AVP_MINIMUM_BPS 16 /* Minimum BPS */ +#define L2TP_AVP_MAXIMUM_BPS 17 /* Maximum BPS */ +#define L2TP_AVP_BEARER_TYPE 18 /* Bearer Type */ +#define L2TP_AVP_FRAMING_TYPE 19 /* Framing Type */ +#define L2TP_AVP_PACKET_PROC_DELAY 20 /* Packet Processing Delay (OBSOLETE) */ +#define L2TP_AVP_CALLED_NUMBER 21 /* Called Number */ +#define L2TP_AVP_CALLING_NUMBER 22 /* Calling Number */ +#define L2TP_AVP_SUB_ADDRESS 23 /* Sub-Address */ +#define L2TP_AVP_TX_CONN_SPEED 24 /* (Tx) Connect Speed */ +#define L2TP_AVP_PHY_CHANNEL_ID 25 /* Physical Channel ID */ +#define L2TP_AVP_INI_RECV_LCP 26 /* Initial Received LCP CONFREQ */ +#define L2TP_AVP_LAST_SENT_LCP 27 /* Last Sent LCP CONFREQ */ +#define L2TP_AVP_LAST_RECV_LCP 28 /* Last Received LCP CONFREQ */ +#define L2TP_AVP_PROXY_AUTH_TYPE 29 /* Proxy Authen Type */ +#define L2TP_AVP_PROXY_AUTH_NAME 30 /* Proxy Authen Name */ +#define L2TP_AVP_PROXY_AUTH_CHAL 31 /* Proxy Authen Challenge */ +#define L2TP_AVP_PROXY_AUTH_ID 32 /* Proxy Authen ID */ +#define L2TP_AVP_PROXY_AUTH_RESP 33 /* Proxy Authen Response */ +#define L2TP_AVP_CALL_ERRORS 34 /* Call Errors */ +#define L2TP_AVP_ACCM 35 /* ACCM */ +#define L2TP_AVP_RANDOM_VECTOR 36 /* Random Vector */ +#define L2TP_AVP_PRIVATE_GRP_ID 37 /* Private Group ID */ +#define L2TP_AVP_RX_CONN_SPEED 38 /* (Rx) Connect Speed */ +#define L2TP_AVP_SEQ_REQUIRED 39 /* Sequencing Required */ +#define L2TP_AVP_PPP_DISCON_CC 46 /* PPP Disconnect Cause Code */ + +static struct tok l2tp_avp2str[] = { + { L2TP_AVP_MSGTYPE, "MSGTYPE" }, + { L2TP_AVP_RESULT_CODE, "RESULT_CODE" }, + { L2TP_AVP_PROTO_VER, "PROTO_VER" }, + { L2TP_AVP_FRAMING_CAP, "FRAMING_CAP" }, + { L2TP_AVP_BEARER_CAP, "BEARER_CAP" }, + { L2TP_AVP_TIE_BREAKER, "TIE_BREAKER" }, + { L2TP_AVP_FIRM_VER, "FIRM_VER" }, + { L2TP_AVP_HOST_NAME, "HOST_NAME" }, + { L2TP_AVP_VENDOR_NAME, "VENDOR_NAME" }, + { L2TP_AVP_ASSND_TUN_ID, "ASSND_TUN_ID" }, + { L2TP_AVP_RECV_WIN_SIZE, "RECV_WIN_SIZE" }, + { L2TP_AVP_CHALLENGE, "CHALLENGE" }, + { L2TP_AVP_Q931_CC, "Q931_CC", }, + { L2TP_AVP_CHALLENGE_RESP, "CHALLENGE_RESP" }, + { L2TP_AVP_ASSND_SESS_ID, "ASSND_SESS_ID" }, + { L2TP_AVP_CALL_SER_NUM, "CALL_SER_NUM" }, + { L2TP_AVP_MINIMUM_BPS, "MINIMUM_BPS" }, + { L2TP_AVP_MAXIMUM_BPS, "MAXIMUM_BPS" }, + { L2TP_AVP_BEARER_TYPE, "BEARER_TYPE" }, + { L2TP_AVP_FRAMING_TYPE, "FRAMING_TYPE" }, + { L2TP_AVP_PACKET_PROC_DELAY, "PACKET_PROC_DELAY" }, + { L2TP_AVP_CALLED_NUMBER, "CALLED_NUMBER" }, + { L2TP_AVP_CALLING_NUMBER, "CALLING_NUMBER" }, + { L2TP_AVP_SUB_ADDRESS, "SUB_ADDRESS" }, + { L2TP_AVP_TX_CONN_SPEED, "TX_CONN_SPEED" }, + { L2TP_AVP_PHY_CHANNEL_ID, "PHY_CHANNEL_ID" }, + { L2TP_AVP_INI_RECV_LCP, "INI_RECV_LCP" }, + { L2TP_AVP_LAST_SENT_LCP, "LAST_SENT_LCP" }, + { L2TP_AVP_LAST_RECV_LCP, "LAST_RECV_LCP" }, + { L2TP_AVP_PROXY_AUTH_TYPE, "PROXY_AUTH_TYPE" }, + { L2TP_AVP_PROXY_AUTH_NAME, "PROXY_AUTH_NAME" }, + { L2TP_AVP_PROXY_AUTH_CHAL, "PROXY_AUTH_CHAL" }, + { L2TP_AVP_PROXY_AUTH_ID, "PROXY_AUTH_ID" }, + { L2TP_AVP_PROXY_AUTH_RESP, "PROXY_AUTH_RESP" }, + { L2TP_AVP_CALL_ERRORS, "CALL_ERRORS" }, + { L2TP_AVP_ACCM, "ACCM" }, + { L2TP_AVP_RANDOM_VECTOR, "RANDOM_VECTOR" }, + { L2TP_AVP_PRIVATE_GRP_ID, "PRIVATE_GRP_ID" }, + { L2TP_AVP_RX_CONN_SPEED, "RX_CONN_SPEED" }, + { L2TP_AVP_SEQ_REQUIRED, "SEQ_REQUIRED" }, + { L2TP_AVP_PPP_DISCON_CC, "PPP_DISCON_CC" }, + { 0, NULL } +}; + +static struct tok l2tp_authentype2str[] = { + { L2TP_AUTHEN_TYPE_RESERVED, "Reserved" }, + { L2TP_AUTHEN_TYPE_TEXTUAL, "Textual" }, + { L2TP_AUTHEN_TYPE_CHAP, "CHAP" }, + { L2TP_AUTHEN_TYPE_PAP, "PAP" }, + { L2TP_AUTHEN_TYPE_NO_AUTH, "No Auth" }, + { L2TP_AUTHEN_TYPE_MSCHAPv1, "MS-CHAPv1" }, + { 0, NULL } +}; + +#define L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL 0 +#define L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER 1 +#define L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL 2 + +static struct tok l2tp_cc_direction2str[] = { + { L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL, "global error" }, + { L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER, "at peer" }, + { L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL,"at local" }, + { 0, NULL } +}; + +#if 0 +static char *l2tp_result_code_StopCCN[] = { + "Reserved", + "General request to clear control connection", + "General error--Error Code indicates the problem", + "Control channel already exists", + "Requester is not authorized to establish a control channel", + "The protocol version of the requester is not supported", + "Requester is being shut down", + "Finite State Machine error" +#define L2TP_MAX_RESULT_CODE_STOPCC_INDEX 8 +}; +#endif + +#if 0 +static char *l2tp_result_code_CDN[] = { + "Reserved", + "Call disconnected due to loss of carrier", + "Call disconnected for the reason indicated in error code", + "Call disconnected for administrative reasons", + "Call failed due to lack of appropriate facilities being " \ + "available (temporary condition)", + "Call failed due to lack of appropriate facilities being " \ + "available (permanent condition)", + "Invalid destination", + "Call failed due to no carrier detected", + "Call failed due to detection of a busy signal", + "Call failed due to lack of a dial tone", + "Call was not established within time allotted by LAC", + "Call was connected but no appropriate framing was detected" +#define L2TP_MAX_RESULT_CODE_CDN_INDEX 12 +}; +#endif + +#if 0 +static char *l2tp_error_code_general[] = { + "No general error", + "No control connection exists yet for this LAC-LNS pair", + "Length is wrong", + "One of the field values was out of range or " \ + "reserved field was non-zero" + "Insufficient resources to handle this operation now", + "The Session ID is invalid in this context", + "A generic vendor-specific error occurred in the LAC", + "Try another" +#define L2TP_MAX_ERROR_CODE_GENERAL_INDEX 8 +}; +#endif + +/******************************/ +/* generic print out routines */ +/******************************/ +static void +print_string(const u_char *dat, u_int length) +{ + u_int i; + for (i=0; i 2) { /* Error Code (opt) */ + printf("/%u", EXTRACT_16BITS(ptr)); ptr++; + } + if (length > 4) { /* Error Message (opt) */ + printf(" "); + print_string((u_char *)ptr, length - 4); + } +} + +static void +l2tp_proto_ver_print(const u_int16_t *dat) +{ + printf("%u.%u", (EXTRACT_16BITS(dat) >> 8), + (EXTRACT_16BITS(dat) & 0xff)); +} + +static void +l2tp_framing_cap_print(const u_char *dat) +{ + u_int32_t *ptr = (u_int32_t *)dat; + + if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_ASYNC_MASK) { + printf("A"); + } + if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_SYNC_MASK) { + printf("S"); + } +} + +static void +l2tp_bearer_cap_print(const u_char *dat) +{ + u_int32_t *ptr = (u_int32_t *)dat; + + if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_ANALOG_MASK) { + printf("A"); + } + if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_DIGITAL_MASK) { + printf("D"); + } +} + +static void +l2tp_q931_cc_print(const u_char *dat, u_int length) +{ + print_16bits_val((u_int16_t *)dat); + printf(", %02x", dat[2]); + if (length > 3) { + printf(" "); + print_string(dat+3, length-3); + } +} + +static void +l2tp_bearer_type_print(const u_char *dat) +{ + u_int32_t *ptr = (u_int32_t *)dat; + + if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_ANALOG_MASK) { + printf("A"); + } + if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_DIGITAL_MASK) { + printf("D"); + } +} + +static void +l2tp_framing_type_print(const u_char *dat) +{ + u_int32_t *ptr = (u_int32_t *)dat; + + if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_ASYNC_MASK) { + printf("A"); + } + if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_SYNC_MASK) { + printf("S"); + } +} + +static void +l2tp_packet_proc_delay_print(void) +{ + printf("obsolete"); +} + +static void +l2tp_proxy_auth_type_print(const u_char *dat) +{ + u_int16_t *ptr = (u_int16_t *)dat; + + printf("%s", tok2str(l2tp_authentype2str, + "AuthType-#%u", EXTRACT_16BITS(ptr))); +} + +static void +l2tp_proxy_auth_id_print(const u_char *dat) +{ + u_int16_t *ptr = (u_int16_t *)dat; + + printf("%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK); +} + +static void +l2tp_call_errors_print(const u_char *dat) +{ + u_int16_t *ptr = (u_int16_t *)dat; + u_int16_t val_h, val_l; + + ptr++; /* skip "Reserved" */ + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("CRCErr=%u ", (val_h<<16) + val_l); + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("FrameErr=%u ", (val_h<<16) + val_l); + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("HardOver=%u ", (val_h<<16) + val_l); + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("BufOver=%u ", (val_h<<16) + val_l); + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("Timeout=%u ", (val_h<<16) + val_l); + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("AlignErr=%u ", (val_h<<16) + val_l); +} + +static void +l2tp_accm_print(const u_char *dat) +{ + u_int16_t *ptr = (u_int16_t *)dat; + u_int16_t val_h, val_l; + + ptr++; /* skip "Reserved" */ + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("send=%08x ", (val_h<<16) + val_l); + + val_h = EXTRACT_16BITS(ptr); ptr++; + val_l = EXTRACT_16BITS(ptr); ptr++; + printf("recv=%08x ", (val_h<<16) + val_l); +} + +static void +l2tp_ppp_discon_cc_print(const u_char *dat, u_int length) +{ + u_int16_t *ptr = (u_int16_t *)dat; + + printf("%04x, ", EXTRACT_16BITS(ptr)); ptr++; /* Disconnect Code */ + printf("%04x ", EXTRACT_16BITS(ptr)); ptr++; /* Control Protocol Number */ + printf("%s", tok2str(l2tp_cc_direction2str, + "Direction-#%u", *((u_char *)ptr++))); + + if (length > 5) { + printf(" "); + print_string((const u_char *)ptr, length-5); + } +} + +static void +l2tp_avp_print(const u_char *dat, int length) +{ + u_int len; + const u_int16_t *ptr = (u_int16_t *)dat; + u_int16_t attr_type; + int hidden = FALSE; + + if (length <= 0) { + return; + } + + printf(" "); + + TCHECK(*ptr); /* Flags & Length */ + len = EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_LEN_MASK; + + /* If it is not long enough to contain the header, we'll give up. */ + if (len < 6) + goto trunc; + + /* If it goes past the end of the remaining length of the packet, + we'll give up. */ + if (len > (u_int)length) + goto trunc; + + /* If it goes past the end of the remaining length of the captured + data, we'll give up. */ + TCHECK2(*ptr, len); + /* After this point, no need to worry about truncation */ + + if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) { + printf("*"); + } + if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) { + hidden = TRUE; + printf("?"); + } + ptr++; + + if (EXTRACT_16BITS(ptr)) { + /* Vendor Specific Attribute */ + printf("VENDOR%04x:", EXTRACT_16BITS(ptr)); ptr++; + printf("ATTR%04x", EXTRACT_16BITS(ptr)); ptr++; + printf("("); + print_octets((u_char *)ptr, len-6); + printf(")"); + } else { + /* IETF-defined Attributes */ + ptr++; + attr_type = EXTRACT_16BITS(ptr); ptr++; + printf("%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type)); + printf("("); + if (hidden) { + printf("???"); + } else { + switch (attr_type) { + case L2TP_AVP_MSGTYPE: + l2tp_msgtype_print((u_char *)ptr); + break; + case L2TP_AVP_RESULT_CODE: + l2tp_result_code_print((u_char *)ptr, len-6); + break; + case L2TP_AVP_PROTO_VER: + l2tp_proto_ver_print(ptr); + break; + case L2TP_AVP_FRAMING_CAP: + l2tp_framing_cap_print((u_char *)ptr); + break; + case L2TP_AVP_BEARER_CAP: + l2tp_bearer_cap_print((u_char *)ptr); + break; + case L2TP_AVP_TIE_BREAKER: + print_octets((u_char *)ptr, 8); + break; + case L2TP_AVP_FIRM_VER: + case L2TP_AVP_ASSND_TUN_ID: + case L2TP_AVP_RECV_WIN_SIZE: + case L2TP_AVP_ASSND_SESS_ID: + print_16bits_val(ptr); + break; + case L2TP_AVP_HOST_NAME: + case L2TP_AVP_VENDOR_NAME: + case L2TP_AVP_CALLING_NUMBER: + case L2TP_AVP_CALLED_NUMBER: + case L2TP_AVP_SUB_ADDRESS: + case L2TP_AVP_PROXY_AUTH_NAME: + case L2TP_AVP_PRIVATE_GRP_ID: + print_string((u_char *)ptr, len-6); + break; + case L2TP_AVP_CHALLENGE: + case L2TP_AVP_INI_RECV_LCP: + case L2TP_AVP_LAST_SENT_LCP: + case L2TP_AVP_LAST_RECV_LCP: + case L2TP_AVP_PROXY_AUTH_CHAL: + case L2TP_AVP_PROXY_AUTH_RESP: + case L2TP_AVP_RANDOM_VECTOR: + print_octets((u_char *)ptr, len-6); + break; + case L2TP_AVP_Q931_CC: + l2tp_q931_cc_print((u_char *)ptr, len-6); + break; + case L2TP_AVP_CHALLENGE_RESP: + print_octets((u_char *)ptr, 16); + break; + case L2TP_AVP_CALL_SER_NUM: + case L2TP_AVP_MINIMUM_BPS: + case L2TP_AVP_MAXIMUM_BPS: + case L2TP_AVP_TX_CONN_SPEED: + case L2TP_AVP_PHY_CHANNEL_ID: + case L2TP_AVP_RX_CONN_SPEED: + print_32bits_val((u_int32_t *)ptr); + break; + case L2TP_AVP_BEARER_TYPE: + l2tp_bearer_type_print((u_char *)ptr); + break; + case L2TP_AVP_FRAMING_TYPE: + l2tp_framing_type_print((u_char *)ptr); + break; + case L2TP_AVP_PACKET_PROC_DELAY: + l2tp_packet_proc_delay_print(); + break; + case L2TP_AVP_PROXY_AUTH_TYPE: + l2tp_proxy_auth_type_print((u_char *)ptr); + break; + case L2TP_AVP_PROXY_AUTH_ID: + l2tp_proxy_auth_id_print((u_char *)ptr); + break; + case L2TP_AVP_CALL_ERRORS: + l2tp_call_errors_print((u_char *)ptr); + break; + case L2TP_AVP_ACCM: + l2tp_accm_print((u_char *)ptr); + break; + case L2TP_AVP_SEQ_REQUIRED: + break; /* No Attribute Value */ + case L2TP_AVP_PPP_DISCON_CC: + l2tp_ppp_discon_cc_print((u_char *)ptr, len-6); + break; + default: + break; + } + } + printf(")"); + } + + l2tp_avp_print(dat+len, length-len); + return; + + trunc: + printf("|..."); +} + + +void +l2tp_print(const u_char *dat, u_int length) +{ + const u_char *ptr = dat; + u_int cnt = 0; /* total octets consumed */ + u_int16_t pad; + int flag_t, flag_l, flag_s, flag_o; + u_int16_t l2tp_len; + + flag_t = flag_l = flag_s = flag_o = FALSE; + + TCHECK2(*ptr, 2); /* Flags & Version */ + if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) { + printf(" l2tp:"); + } else if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) { + printf(" l2f:"); + return; /* nothing to do */ + } else { + printf(" Unknown Version, neither L2F(1) nor L2TP(2)"); + return; /* nothing we can do */ + } + + printf("["); + if (EXTRACT_16BITS(ptr) & L2TP_FLAG_TYPE) { + flag_t = TRUE; + printf("T"); + } + if (EXTRACT_16BITS(ptr) & L2TP_FLAG_LENGTH) { + flag_l = TRUE; + printf("L"); + } + if (EXTRACT_16BITS(ptr) & L2TP_FLAG_SEQUENCE) { + flag_s = TRUE; + printf("S"); + } + if (EXTRACT_16BITS(ptr) & L2TP_FLAG_OFFSET) { + flag_o = TRUE; + printf("O"); + } + if (EXTRACT_16BITS(ptr) & L2TP_FLAG_PRIORITY) + printf("P"); + printf("]"); + + ptr += 2; + cnt += 2; + + if (flag_l) { + TCHECK2(*ptr, 2); /* Length */ + l2tp_len = EXTRACT_16BITS(ptr); + ptr += 2; + cnt += 2; + } else { + l2tp_len = 0; + } + + TCHECK2(*ptr, 2); /* Tunnel ID */ + printf("(%u/", EXTRACT_16BITS(ptr)); + ptr += 2; + cnt += 2; + TCHECK2(*ptr, 2); /* Session ID */ + printf("%u)", EXTRACT_16BITS(ptr)); + ptr += 2; + cnt += 2; + + if (flag_s) { + TCHECK2(*ptr, 2); /* Ns */ + printf("Ns=%u,", EXTRACT_16BITS(ptr)); + ptr += 2; + cnt += 2; + TCHECK2(*ptr, 2); /* Nr */ + printf("Nr=%u", EXTRACT_16BITS(ptr)); + ptr += 2; + cnt += 2; + } + + if (flag_o) { + TCHECK2(*ptr, 2); /* Offset Size */ + pad = EXTRACT_16BITS(ptr); + ptr += (2 + pad); + cnt += (2 + pad); + } + + if (flag_l) { + if (length < l2tp_len) { + printf(" Length %u larger than packet", l2tp_len); + return; + } + length = l2tp_len; + } + if (length < cnt) { + printf(" Length %u smaller than header length", length); + return; + } + if (flag_t) { + if (!flag_l) { + printf(" No length"); + return; + } + if (length - cnt == 0) { + printf(" ZLB"); + } else { + l2tp_avp_print(ptr, length - cnt); + } + } else { + printf(" {"); + ppp_print(ptr, length - cnt); + printf("}"); + } + + return; + + trunc: + printf("%s", tstr); +} diff --git a/print-lane.c b/print-lane.c new file mode 100644 index 0000000..54c68c8 --- /dev/null +++ b/print-lane.c @@ -0,0 +1,118 @@ +/* + * Marko Kiiskila carnil@cs.tut.fi + * + * Tampere University of Technology - Telecommunications Laboratory + * + * Permission to use, copy, modify and distribute this + * software and its documentation is hereby granted, + * provided that both the copyright notice and this + * permission notice appear in all copies of the software, + * derivative works or modified versions, and any portions + * thereof, that both notices appear in supporting + * documentation, and that the use of this software is + * acknowledged in any publications resulting from using + * the software. + * + * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS + * SOFTWARE. + * + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-lane.c,v 1.25 2005-11-13 12:12:42 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "ether.h" +#include "lane.h" + +static const struct tok lecop2str[] = { + { 0x0001, "configure request" }, + { 0x0101, "configure response" }, + { 0x0002, "join request" }, + { 0x0102, "join response" }, + { 0x0003, "ready query" }, + { 0x0103, "ready indication" }, + { 0x0004, "register request" }, + { 0x0104, "register response" }, + { 0x0005, "unregister request" }, + { 0x0105, "unregister response" }, + { 0x0006, "ARP request" }, + { 0x0106, "ARP response" }, + { 0x0007, "flush request" }, + { 0x0107, "flush response" }, + { 0x0008, "NARP request" }, + { 0x0009, "topology request" }, + { 0, NULL } +}; + +static void +lane_hdr_print(const u_char *bp) +{ + (void)printf("lecid:%x ", EXTRACT_16BITS(bp)); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the LANE header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + * + * This assumes 802.3, not 802.5, LAN emulation. + */ +void +lane_print(const u_char *p, u_int length, u_int caplen) +{ + struct lane_controlhdr *lec; + + if (caplen < sizeof(struct lane_controlhdr)) { + printf("[|lane]"); + return; + } + + lec = (struct lane_controlhdr *)p; + if (EXTRACT_16BITS(&lec->lec_header) == 0xff00) { + /* + * LE Control. + */ + printf("lec: proto %x vers %x %s", + lec->lec_proto, lec->lec_vers, + tok2str(lecop2str, "opcode-#%u", EXTRACT_16BITS(&lec->lec_opcode))); + return; + } + + /* + * Go past the LE header. + */ + length -= 2; + caplen -= 2; + p += 2; + + /* + * Now print the encapsulated frame, under the assumption + * that it's an Ethernet frame. + */ + ether_print(p, length, caplen, lane_hdr_print, p - 2); +} + +u_int +lane_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + lane_print(p, h->len, h->caplen); + + return (sizeof(struct lecdatahdr_8023)); +} diff --git a/print-ldp.c b/print-ldp.c new file mode 100644 index 0000000..de3b34e --- /dev/null +++ b/print-ldp.c @@ -0,0 +1,623 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Original code by Hannes Gredler (hannes@juniper.net) + * and Steinar Haug (sthaug@nethelp.no) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ldp.c,v 1.20 2006-06-23 02:03:09 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "decode_prefix.h" +#include "extract.h" +#include "addrtoname.h" + +#include "l2vpn.h" +#include "af.h" + +/* + * ldp common header + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Version | PDU Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | LDP Identifier | + * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +struct ldp_common_header { + u_int8_t version[2]; + u_int8_t pdu_length[2]; + u_int8_t lsr_id[4]; + u_int8_t label_space[2]; +}; + +#define LDP_VERSION 1 + +/* + * ldp message header + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |U| Message Type | Message Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * + + + * | Mandatory Parameters | + * + + + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * + + + * | Optional Parameters | + * + + + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct ldp_msg_header { + u_int8_t type[2]; + u_int8_t length[2]; + u_int8_t id[4]; +}; + +#define LDP_MASK_MSG_TYPE(x) ((x)&0x7fff) +#define LDP_MASK_U_BIT(x) ((x)&0x8000) + +#define LDP_MSG_NOTIF 0x0001 +#define LDP_MSG_HELLO 0x0100 +#define LDP_MSG_INIT 0x0200 +#define LDP_MSG_KEEPALIVE 0x0201 +#define LDP_MSG_ADDRESS 0x0300 +#define LDP_MSG_ADDRESS_WITHDRAW 0x0301 +#define LDP_MSG_LABEL_MAPPING 0x0400 +#define LDP_MSG_LABEL_REQUEST 0x0401 +#define LDP_MSG_LABEL_WITHDRAW 0x0402 +#define LDP_MSG_LABEL_RELEASE 0x0403 +#define LDP_MSG_LABEL_ABORT_REQUEST 0x0404 + +#define LDP_VENDOR_PRIVATE_MIN 0x3e00 +#define LDP_VENDOR_PRIVATE_MAX 0x3eff +#define LDP_EXPERIMENTAL_MIN 0x3f00 +#define LDP_EXPERIMENTAL_MAX 0x3fff + +static const struct tok ldp_msg_values[] = { + { LDP_MSG_NOTIF, "Notification" }, + { LDP_MSG_HELLO, "Hello" }, + { LDP_MSG_INIT, "Initialization" }, + { LDP_MSG_KEEPALIVE, "Keepalive" }, + { LDP_MSG_ADDRESS, "Address" }, + { LDP_MSG_ADDRESS_WITHDRAW, "Address Withdraw" }, + { LDP_MSG_LABEL_MAPPING, "Label Mapping" }, + { LDP_MSG_LABEL_REQUEST, "Label Request" }, + { LDP_MSG_LABEL_WITHDRAW, "Label Withdraw" }, + { LDP_MSG_LABEL_RELEASE, "Label Release" }, + { LDP_MSG_LABEL_ABORT_REQUEST, "Label Abort Request" }, + { 0, NULL} +}; + +#define LDP_MASK_TLV_TYPE(x) ((x)&0x3fff) +#define LDP_MASK_F_BIT(x) ((x)&0x4000) + +#define LDP_TLV_FEC 0x0100 +#define LDP_TLV_ADDRESS_LIST 0x0101 +#define LDP_TLV_ADDRESS_LIST_AFNUM_LEN 2 +#define LDP_TLV_HOP_COUNT 0x0103 +#define LDP_TLV_PATH_VECTOR 0x0104 +#define LDP_TLV_GENERIC_LABEL 0x0200 +#define LDP_TLV_ATM_LABEL 0x0201 +#define LDP_TLV_FR_LABEL 0x0202 +#define LDP_TLV_STATUS 0x0300 +#define LDP_TLV_EXTD_STATUS 0x0301 +#define LDP_TLV_RETURNED_PDU 0x0302 +#define LDP_TLV_RETURNED_MSG 0x0303 +#define LDP_TLV_COMMON_HELLO 0x0400 +#define LDP_TLV_IPV4_TRANSPORT_ADDR 0x0401 +#define LDP_TLV_CONFIG_SEQ_NUMBER 0x0402 +#define LDP_TLV_IPV6_TRANSPORT_ADDR 0x0403 +#define LDP_TLV_COMMON_SESSION 0x0500 +#define LDP_TLV_ATM_SESSION_PARM 0x0501 +#define LDP_TLV_FR_SESSION_PARM 0x0502 +#define LDP_TLV_FT_SESSION 0x0503 +#define LDP_TLV_LABEL_REQUEST_MSG_ID 0x0600 +#define LDP_TLV_MTU 0x0601 /* rfc 3988 */ + +static const struct tok ldp_tlv_values[] = { + { LDP_TLV_FEC, "FEC" }, + { LDP_TLV_ADDRESS_LIST, "Address List" }, + { LDP_TLV_HOP_COUNT, "Hop Count" }, + { LDP_TLV_PATH_VECTOR, "Path Vector" }, + { LDP_TLV_GENERIC_LABEL, "Generic Label" }, + { LDP_TLV_ATM_LABEL, "ATM Label" }, + { LDP_TLV_FR_LABEL, "Frame-Relay Label" }, + { LDP_TLV_STATUS, "Status" }, + { LDP_TLV_EXTD_STATUS, "Extended Status" }, + { LDP_TLV_RETURNED_PDU, "Returned PDU" }, + { LDP_TLV_RETURNED_MSG, "Returned Message" }, + { LDP_TLV_COMMON_HELLO, "Common Hello Parameters" }, + { LDP_TLV_IPV4_TRANSPORT_ADDR, "IPv4 Transport Address" }, + { LDP_TLV_CONFIG_SEQ_NUMBER, "Configuration Sequence Number" }, + { LDP_TLV_IPV6_TRANSPORT_ADDR, "IPv6 Transport Address" }, + { LDP_TLV_COMMON_SESSION, "Common Session Parameters" }, + { LDP_TLV_ATM_SESSION_PARM, "ATM Session Parameters" }, + { LDP_TLV_FR_SESSION_PARM, "Frame-Relay Session Parameters" }, + { LDP_TLV_FT_SESSION, "Fault-Tolerant Session Parameters" }, + { LDP_TLV_LABEL_REQUEST_MSG_ID, "Label Request Message ID" }, + { LDP_TLV_MTU, "MTU" }, + { 0, NULL} +}; + +#define LDP_FEC_WILDCARD 0x01 +#define LDP_FEC_PREFIX 0x02 +#define LDP_FEC_HOSTADDRESS 0x03 +/* From draft-martini-l2circuit-trans-mpls-13.txt */ +#define LDP_FEC_MARTINI_VC 0x80 + +static const struct tok ldp_fec_values[] = { + { LDP_FEC_WILDCARD, "Wildcard" }, + { LDP_FEC_PREFIX, "Prefix" }, + { LDP_FEC_HOSTADDRESS, "Host address" }, + { LDP_FEC_MARTINI_VC, "Martini VC" }, + { 0, NULL} +}; + +#define LDP_FEC_MARTINI_IFPARM_MTU 0x01 +#define LDP_FEC_MARTINI_IFPARM_DESC 0x03 +#define LDP_FEC_MARTINI_IFPARM_VCCV 0x0c + +static const struct tok ldp_fec_martini_ifparm_values[] = { + { LDP_FEC_MARTINI_IFPARM_MTU, "MTU" }, + { LDP_FEC_MARTINI_IFPARM_DESC, "Description" }, + { LDP_FEC_MARTINI_IFPARM_VCCV, "VCCV" }, + { 0, NULL} +}; + +/* draft-ietf-pwe3-vccv-04.txt */ +static const struct tok ldp_fec_martini_ifparm_vccv_cc_values[] = { + { 0x01, "PWE3 control word" }, + { 0x02, "MPLS Router Alert Label" }, + { 0x04, "MPLS inner label TTL = 1" }, + { 0, NULL} +}; + +/* draft-ietf-pwe3-vccv-04.txt */ +static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = { + { 0x01, "ICMP Ping" }, + { 0x02, "LSP Ping" }, + { 0x04, "BFD" }, + { 0, NULL} +}; + +int ldp_msg_print(register const u_char *); +int ldp_tlv_print(register const u_char *); + +/* + * ldp tlv header + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |U|F| Type | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | Value | + * ~ ~ + * | | + * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +int +ldp_tlv_print(register const u_char *tptr) { + + struct ldp_tlv_header { + u_int8_t type[2]; + u_int8_t length[2]; + }; + + const struct ldp_tlv_header *ldp_tlv_header; + u_short tlv_type,tlv_len,tlv_tlen,af,ft_flags; + u_char fec_type; + u_int ui,vc_info_len, vc_info_tlv_type, vc_info_tlv_len,idx; + char buf[100]; + int i; + + ldp_tlv_header = (const struct ldp_tlv_header *)tptr; + tlv_len=EXTRACT_16BITS(ldp_tlv_header->length); + tlv_tlen=tlv_len; + tlv_type=LDP_MASK_TLV_TYPE(EXTRACT_16BITS(ldp_tlv_header->type)); + + /* FIXME vendor private / experimental check */ + printf("\n\t %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]", + tok2str(ldp_tlv_values, + "Unknown", + tlv_type), + tlv_type, + tlv_len, + LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "continue processing" : "ignore", + LDP_MASK_F_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "do" : "don't"); + + tptr+=sizeof(struct ldp_tlv_header); + + switch(tlv_type) { + + case LDP_TLV_COMMON_HELLO: + printf("\n\t Hold Time: %us, Flags: [%s Hello%s]", + EXTRACT_16BITS(tptr), + (EXTRACT_16BITS(tptr+2)&0x8000) ? "Targeted" : "Link", + (EXTRACT_16BITS(tptr+2)&0x4000) ? ", Request for targeted Hellos" : ""); + break; + + case LDP_TLV_IPV4_TRANSPORT_ADDR: + printf("\n\t IPv4 Transport Address: %s", ipaddr_string(tptr)); + break; +#ifdef INET6 + case LDP_TLV_IPV6_TRANSPORT_ADDR: + printf("\n\t IPv6 Transport Address: %s", ip6addr_string(tptr)); + break; +#endif + case LDP_TLV_CONFIG_SEQ_NUMBER: + printf("\n\t Sequence Number: %u", EXTRACT_32BITS(tptr)); + break; + + case LDP_TLV_ADDRESS_LIST: + af = EXTRACT_16BITS(tptr); + tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN; + tlv_tlen -= LDP_TLV_ADDRESS_LIST_AFNUM_LEN; + printf("\n\t Address Family: %s, addresses", + tok2str(af_values, "Unknown (%u)", af)); + switch (af) { + case AFNUM_INET: + while(tlv_tlen >= sizeof(struct in_addr)) { + printf(" %s",ipaddr_string(tptr)); + tlv_tlen-=sizeof(struct in_addr); + tptr+=sizeof(struct in_addr); + } + break; +#ifdef INET6 + case AFNUM_INET6: + while(tlv_tlen >= sizeof(struct in6_addr)) { + printf(" %s",ip6addr_string(tptr)); + tlv_tlen-=sizeof(struct in6_addr); + tptr+=sizeof(struct in6_addr); + } + break; +#endif + default: + /* unknown AF */ + break; + } + break; + + case LDP_TLV_COMMON_SESSION: + printf("\n\t Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]", + EXTRACT_16BITS(tptr), EXTRACT_16BITS(tptr+2), + (EXTRACT_16BITS(tptr+6)&0x8000) ? "On Demand" : "Unsolicited", + (EXTRACT_16BITS(tptr+6)&0x4000) ? "Enabled" : "Disabled" + ); + break; + + case LDP_TLV_FEC: + fec_type = *tptr; + printf("\n\t %s FEC (0x%02x)", + tok2str(ldp_fec_values, "Unknown", fec_type), + fec_type); + + tptr+=1; + switch(fec_type) { + + case LDP_FEC_WILDCARD: + break; + case LDP_FEC_PREFIX: + af = EXTRACT_16BITS(tptr); + tptr+=2; + if (af == AFNUM_INET) { + i=decode_prefix4(tptr,buf,sizeof(buf)); + printf(": IPv4 prefix %s",buf); + } +#ifdef INET6 + else if (af == AFNUM_INET6) { + i=decode_prefix6(tptr,buf,sizeof(buf)); + printf(": IPv6 prefix %s",buf); + } +#endif + break; + case LDP_FEC_HOSTADDRESS: + break; + case LDP_FEC_MARTINI_VC: + if (!TTEST2(*tptr, 11)) + goto trunc; + vc_info_len = *(tptr+2); + + printf(": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u", + tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff), + EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ", + EXTRACT_32BITS(tptr+3), + EXTRACT_32BITS(tptr+7), + vc_info_len); + + if (vc_info_len == 0) /* infinite loop protection */ + break; + + tptr+=11; + if (!TTEST2(*tptr, vc_info_len)) + goto trunc; + + while (vc_info_len > 2) { + vc_info_tlv_type = *tptr; + vc_info_tlv_len = *(tptr+1); + if (vc_info_tlv_len < 2) + break; + if (vc_info_len < vc_info_tlv_len) + break; + + printf("\n\t\tInterface Parameter: %s (0x%02x), len %u", + tok2str(ldp_fec_martini_ifparm_values,"Unknown",vc_info_tlv_type), + vc_info_tlv_type, + vc_info_tlv_len); + + switch(vc_info_tlv_type) { + case LDP_FEC_MARTINI_IFPARM_MTU: + printf(": %u",EXTRACT_16BITS(tptr+2)); + break; + + case LDP_FEC_MARTINI_IFPARM_DESC: + printf(": "); + for (idx = 2; idx < vc_info_tlv_len; idx++) + safeputchar(*(tptr+idx)); + break; + + case LDP_FEC_MARTINI_IFPARM_VCCV: + printf("\n\t\t Control Channels (0x%02x) = [%s]", + *(tptr+2), + bittok2str(ldp_fec_martini_ifparm_vccv_cc_values,"none",*(tptr+2))); + printf("\n\t\t CV Types (0x%02x) = [%s]", + *(tptr+3), + bittok2str(ldp_fec_martini_ifparm_vccv_cv_values,"none",*(tptr+3))); + break; + + default: + print_unknown_data(tptr+2,"\n\t\t ",vc_info_tlv_len-2); + break; + } + + vc_info_len -= vc_info_tlv_len; + tptr += vc_info_tlv_len; + } + break; + } + + break; + + case LDP_TLV_GENERIC_LABEL: + printf("\n\t Label: %u", EXTRACT_32BITS(tptr) & 0xfffff); + break; + + case LDP_TLV_STATUS: + ui = EXTRACT_32BITS(tptr); + tptr+=4; + printf("\n\t Status: 0x%02x, Flags: [%s and %s forward]", + ui&0x3fffffff, + ui&0x80000000 ? "Fatal error" : "Advisory Notification", + ui&0x40000000 ? "do" : "don't"); + ui = EXTRACT_32BITS(tptr); + tptr+=4; + if (ui) + printf(", causing Message ID: 0x%08x", ui); + break; + + case LDP_TLV_FT_SESSION: + ft_flags = EXTRACT_16BITS(tptr); + printf("\n\t Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]", + ft_flags&0x8000 ? "" : "No ", + ft_flags&0x8 ? "" : "Don't ", + ft_flags&0x4 ? "" : "No ", + ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels", + ft_flags&0x1 ? "" : "Don't "); + tptr+=4; + ui = EXTRACT_32BITS(tptr); + if (ui) + printf(", Reconnect Timeout: %ums", ui); + tptr+=4; + ui = EXTRACT_32BITS(tptr); + if (ui) + printf(", Recovery Time: %ums", ui); + break; + + case LDP_TLV_MTU: + printf("\n\t MTU: %u", EXTRACT_16BITS(tptr)); + break; + + + /* + * FIXME those are the defined TLVs that lack a decoder + * you are welcome to contribute code ;-) + */ + + case LDP_TLV_HOP_COUNT: + case LDP_TLV_PATH_VECTOR: + case LDP_TLV_ATM_LABEL: + case LDP_TLV_FR_LABEL: + case LDP_TLV_EXTD_STATUS: + case LDP_TLV_RETURNED_PDU: + case LDP_TLV_RETURNED_MSG: + case LDP_TLV_ATM_SESSION_PARM: + case LDP_TLV_FR_SESSION_PARM: + case LDP_TLV_LABEL_REQUEST_MSG_ID: + + default: + if (vflag <= 1) + print_unknown_data(tptr,"\n\t ",tlv_tlen); + break; + } + return(tlv_len+4); /* Type & Length fields not included */ + +trunc: + printf("\n\t\t packet exceeded snapshot"); + return 0; +} + +void +ldp_print(register const u_char *pptr, register u_int len) { + + int processed; + while (len > (sizeof(struct ldp_common_header) + sizeof(struct ldp_msg_header))) { + processed = ldp_msg_print(pptr); + if (processed == 0) + return; + len -= processed; + pptr += processed; + } +} + + +int +ldp_msg_print(register const u_char *pptr) { + + const struct ldp_common_header *ldp_com_header; + const struct ldp_msg_header *ldp_msg_header; + const u_char *tptr,*msg_tptr; + u_short tlen; + u_short pdu_len,msg_len,msg_type,msg_tlen; + int hexdump,processed; + + tptr=pptr; + ldp_com_header = (const struct ldp_common_header *)pptr; + TCHECK(*ldp_com_header); + + /* + * Sanity checking of the header. + */ + if (EXTRACT_16BITS(&ldp_com_header->version) != LDP_VERSION) { + printf("%sLDP version %u packet not supported", + (vflag < 1) ? "" : "\n\t", + EXTRACT_16BITS(&ldp_com_header->version)); + return 0; + } + + /* print the LSR-ID, label-space & length */ + pdu_len = EXTRACT_16BITS(&ldp_com_header->pdu_length); + printf("%sLDP, Label-Space-ID: %s:%u, pdu-length: %u", + (vflag < 1) ? "" : "\n\t", + ipaddr_string(&ldp_com_header->lsr_id), + EXTRACT_16BITS(&ldp_com_header->label_space), + pdu_len); + + /* bail out if non-verbose */ + if (vflag < 1) + return 0; + + /* ok they seem to want to know everything - lets fully decode it */ + tlen=pdu_len; + + tptr += sizeof(const struct ldp_common_header); + tlen -= sizeof(const struct ldp_common_header)-4; /* Type & Length fields not included */ + + while(tlen>0) { + /* did we capture enough for fully decoding the msg header ? */ + if (!TTEST2(*tptr, sizeof(struct ldp_msg_header))) + goto trunc; + + ldp_msg_header = (const struct ldp_msg_header *)tptr; + msg_len=EXTRACT_16BITS(ldp_msg_header->length); + msg_type=LDP_MASK_MSG_TYPE(EXTRACT_16BITS(ldp_msg_header->type)); + + /* FIXME vendor private / experimental check */ + printf("\n\t %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]", + tok2str(ldp_msg_values, + "Unknown", + msg_type), + msg_type, + msg_len, + EXTRACT_32BITS(&ldp_msg_header->id), + LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_msg_header->type)) ? "continue processing" : "ignore"); + + if (msg_len == 0) /* infinite loop protection */ + return 0; + + msg_tptr=tptr+sizeof(struct ldp_msg_header); + msg_tlen=msg_len-sizeof(struct ldp_msg_header)+4; /* Type & Length fields not included */ + + /* did we capture enough for fully decoding the message ? */ + if (!TTEST2(*tptr, msg_len)) + goto trunc; + hexdump=FALSE; + + switch(msg_type) { + + case LDP_MSG_NOTIF: + case LDP_MSG_HELLO: + case LDP_MSG_INIT: + case LDP_MSG_KEEPALIVE: + case LDP_MSG_ADDRESS: + case LDP_MSG_LABEL_MAPPING: + case LDP_MSG_ADDRESS_WITHDRAW: + case LDP_MSG_LABEL_WITHDRAW: + while(msg_tlen >= 4) { + processed = ldp_tlv_print(msg_tptr); + if (processed == 0) + break; + msg_tlen-=processed; + msg_tptr+=processed; + } + break; + + /* + * FIXME those are the defined messages that lack a decoder + * you are welcome to contribute code ;-) + */ + + case LDP_MSG_LABEL_REQUEST: + case LDP_MSG_LABEL_RELEASE: + case LDP_MSG_LABEL_ABORT_REQUEST: + + default: + if (vflag <= 1) + print_unknown_data(msg_tptr,"\n\t ",msg_tlen); + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag > 1 || hexdump==TRUE) + print_unknown_data(tptr+sizeof(sizeof(struct ldp_msg_header)),"\n\t ", + msg_len); + + tptr += msg_len+4; + tlen -= msg_len+4; + } + return pdu_len+4; +trunc: + printf("\n\t\t packet exceeded snapshot"); + return 0; +} + diff --git a/print-llc.c b/print-llc.c new file mode 100644 index 0000000..d20fbdf --- /dev/null +++ b/print-llc.c @@ -0,0 +1,545 @@ +/* + * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Code by Matt Thomas, Digital Equipment Corporation + * with an awful lot of hacking by Jeffrey Mogul, DECWRL + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-llc.c,v 1.75 2007-04-13 09:43:11 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +#include "llc.h" +#include "ethertype.h" +#include "oui.h" + +static struct tok llc_values[] = { + { LLCSAP_NULL, "Null" }, + { LLCSAP_GLOBAL, "Global" }, + { LLCSAP_8021B_I, "802.1B I" }, + { LLCSAP_8021B_G, "802.1B G" }, + { LLCSAP_IP, "IP" }, + { LLCSAP_SNA, "SNA" }, + { LLCSAP_PROWAYNM, "ProWay NM" }, + { LLCSAP_8021D, "STP" }, + { LLCSAP_RS511, "RS511" }, + { LLCSAP_ISO8208, "ISO8208" }, + { LLCSAP_PROWAY, "ProWay" }, + { LLCSAP_SNAP, "SNAP" }, + { LLCSAP_IPX, "IPX" }, + { LLCSAP_NETBEUI, "NetBeui" }, + { LLCSAP_ISONS, "OSI" }, + { 0, NULL }, +}; + +static struct tok llc_cmd_values[] = { + { LLC_UI, "ui" }, + { LLC_TEST, "test" }, + { LLC_XID, "xid" }, + { LLC_UA, "ua" }, + { LLC_DISC, "disc" }, + { LLC_DM, "dm" }, + { LLC_SABME, "sabme" }, + { LLC_FRMR, "frmr" }, + { 0, NULL } +}; + +static const struct tok llc_flag_values[] = { + { 0, "Command" }, + { LLC_GSAP, "Response" }, + { LLC_U_POLL, "Poll" }, + { LLC_GSAP|LLC_U_POLL, "Final" }, + { LLC_IS_POLL, "Poll" }, + { LLC_GSAP|LLC_IS_POLL, "Final" }, + { 0, NULL } +}; + + +static const struct tok llc_ig_flag_values[] = { + { 0, "Individual" }, + { LLC_IG, "Group" }, + { 0, NULL } +}; + + +static const struct tok llc_supervisory_values[] = { + { 0, "Receiver Ready" }, + { 1, "Receiver not Ready" }, + { 2, "Reject" }, + { 0, NULL } +}; + + +static const struct tok cisco_values[] = { + { PID_CISCO_CDP, "CDP" }, + { PID_CISCO_VTP, "VTP" }, + { PID_CISCO_DTP, "DTP" }, + { PID_CISCO_UDLD, "UDLD" }, + { PID_CISCO_PVST, "PVST" }, + { 0, NULL } +}; + +static const struct tok bridged_values[] = { + { PID_RFC2684_ETH_FCS, "Ethernet + FCS" }, + { PID_RFC2684_ETH_NOFCS, "Ethernet w/o FCS" }, + { PID_RFC2684_802_4_FCS, "802.4 + FCS" }, + { PID_RFC2684_802_4_NOFCS, "802.4 w/o FCS" }, + { PID_RFC2684_802_5_FCS, "Token Ring + FCS" }, + { PID_RFC2684_802_5_NOFCS, "Token Ring w/o FCS" }, + { PID_RFC2684_FDDI_FCS, "FDDI + FCS" }, + { PID_RFC2684_FDDI_NOFCS, "FDDI w/o FCS" }, + { PID_RFC2684_802_6_FCS, "802.6 + FCS" }, + { PID_RFC2684_802_6_NOFCS, "802.6 w/o FCS" }, + { PID_RFC2684_BPDU, "BPDU" }, + { 0, NULL }, +}; + +static const struct tok null_values[] = { + { 0, NULL } +}; + +struct oui_tok { + u_int32_t oui; + const struct tok *tok; +}; + +static const struct oui_tok oui_to_tok[] = { + { OUI_ENCAP_ETHER, ethertype_values }, + { OUI_CISCO_90, ethertype_values }, /* uses some Ethertype values */ + { OUI_APPLETALK, ethertype_values }, /* uses some Ethertype values */ + { OUI_CISCO, cisco_values }, + { OUI_RFC2684, bridged_values }, /* bridged, RFC 2427 FR or RFC 2864 ATM */ + { 0, NULL } +}; + +/* + * Returns non-zero IFF it succeeds in printing the header + */ +int +llc_print(const u_char *p, u_int length, u_int caplen, + const u_char *esrc, const u_char *edst, u_short *extracted_ethertype) +{ + u_int8_t dsap_field, dsap, ssap_field, ssap; + u_int16_t control; + int is_u; + register int ret; + + *extracted_ethertype = 0; + + if (caplen < 3) { + (void)printf("[|llc]"); + default_print((u_char *)p, caplen); + return(0); + } + + dsap_field = *p; + ssap_field = *(p + 1); + + /* + * OK, what type of LLC frame is this? The length + * of the control field depends on that - I frames + * have a two-byte control field, and U frames have + * a one-byte control field. + */ + control = *(p + 2); + if ((control & LLC_U_FMT) == LLC_U_FMT) { + /* + * U frame. + */ + is_u = 1; + } else { + /* + * The control field in I and S frames is + * 2 bytes... + */ + if (caplen < 4) { + (void)printf("[|llc]"); + default_print((u_char *)p, caplen); + return(0); + } + + /* + * ...and is little-endian. + */ + control = EXTRACT_LE_16BITS(p + 2); + is_u = 0; + } + + if (ssap_field == LLCSAP_GLOBAL && dsap_field == LLCSAP_GLOBAL) { + /* + * This is an Ethernet_802.3 IPX frame; it has an + * 802.3 header (i.e., an Ethernet header where the + * type/length field is <= ETHERMTU, i.e. it's a length + * field, not a type field), but has no 802.2 header - + * the IPX packet starts right after the Ethernet header, + * with a signature of two bytes of 0xFF (which is + * LLCSAP_GLOBAL). + * + * (It might also have been an Ethernet_802.3 IPX at + * one time, but got bridged onto another network, + * such as an 802.11 network; this has appeared in at + * least one capture file.) + */ + + if (eflag) + printf("IPX 802.3: "); + + ipx_print(p, length); + return (1); + } + + dsap = dsap_field & ~LLC_IG; + ssap = ssap_field & ~LLC_GSAP; + + if (eflag) { + printf("LLC, dsap %s (0x%02x) %s, ssap %s (0x%02x) %s", + tok2str(llc_values, "Unknown", dsap), + dsap, + tok2str(llc_ig_flag_values, "Unknown", dsap_field & LLC_IG), + tok2str(llc_values, "Unknown", ssap), + ssap, + tok2str(llc_flag_values, "Unknown", ssap_field & LLC_GSAP)); + + if (is_u) { + printf(", ctrl 0x%02x: ", control); + } else { + printf(", ctrl 0x%04x: ", control); + } + } + + if (ssap == LLCSAP_8021D && dsap == LLCSAP_8021D && + control == LLC_UI) { + stp_print(p+3, length-3); + return (1); + } + + if (ssap == LLCSAP_IP && dsap == LLCSAP_IP && + control == LLC_UI) { + ip_print(gndo, p+4, length-4); + return (1); + } + + if (ssap == LLCSAP_IPX && dsap == LLCSAP_IPX && + control == LLC_UI) { + /* + * This is an Ethernet_802.2 IPX frame, with an 802.3 + * header and an 802.2 LLC header with the source and + * destination SAPs being the IPX SAP. + * + * Skip DSAP, LSAP, and control field. + */ + if (eflag) + printf("IPX 802.2: "); + + ipx_print(p+3, length-3); + return (1); + } + +#ifdef TCPDUMP_DO_SMB + if (ssap == LLCSAP_NETBEUI && dsap == LLCSAP_NETBEUI + && (!(control & LLC_S_FMT) || control == LLC_U_FMT)) { + /* + * we don't actually have a full netbeui parser yet, but the + * smb parser can handle many smb-in-netbeui packets, which + * is very useful, so we call that + * + * We don't call it for S frames, however, just I frames + * (which are frames that don't have the low-order bit, + * LLC_S_FMT, set in the first byte of the control field) + * and UI frames (whose control field is just 3, LLC_U_FMT). + */ + + /* + * Skip the LLC header. + */ + if (is_u) { + p += 3; + length -= 3; + caplen -= 3; + } else { + p += 4; + length -= 4; + caplen -= 4; + } + netbeui_print(control, p, length); + return (1); + } +#endif + if (ssap == LLCSAP_ISONS && dsap == LLCSAP_ISONS + && control == LLC_UI) { + isoclns_print(p + 3, length - 3, caplen - 3); + return (1); + } + + if (ssap == LLCSAP_SNAP && dsap == LLCSAP_SNAP + && control == LLC_UI) { + /* + * XXX - what *is* the right bridge pad value here? + * Does anybody ever bridge one form of LAN traffic + * over a networking type that uses 802.2 LLC? + */ + ret = snap_print(p+3, length-3, caplen-3, 2); + if (ret) + return (ret); + } + + if (!eflag) { + if (ssap == dsap) { + if (esrc == NULL || edst == NULL) + (void)printf("%s ", tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)); + else + (void)printf("%s > %s %s ", + etheraddr_string(esrc), + etheraddr_string(edst), + tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)); + } else { + if (esrc == NULL || edst == NULL) + (void)printf("%s > %s ", + tok2str(llc_values, "Unknown SSAP 0x%02x", ssap), + tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)); + else + (void)printf("%s %s > %s %s ", + etheraddr_string(esrc), + tok2str(llc_values, "Unknown SSAP 0x%02x", ssap), + etheraddr_string(edst), + tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)); + } + } + + if (is_u) { + printf("Unnumbered, %s, Flags [%s], length %u", + tok2str(llc_cmd_values, "%02x", LLC_U_CMD(control)), + tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_U_POLL)), + length); + + p += 3; + length -= 3; + caplen -= 3; + + if ((control & ~LLC_U_POLL) == LLC_XID) { + if (*p == LLC_XID_FI) { + printf(": %02x %02x", p[1], p[2]); + p += 3; + length -= 3; + caplen -= 3; + } + } + } else { + if ((control & LLC_S_FMT) == LLC_S_FMT) { + (void)printf("Supervisory, %s, rcv seq %u, Flags [%s], length %u", + tok2str(llc_supervisory_values,"?",LLC_S_CMD(control)), + LLC_IS_NR(control), + tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_IS_POLL)), + length); + } else { + (void)printf("Information, send seq %u, rcv seq %u, Flags [%s], length %u", + LLC_I_NS(control), + LLC_IS_NR(control), + tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_IS_POLL)), + length); + } + p += 4; + length -= 4; + caplen -= 4; + } + return(1); +} + +int +snap_print(const u_char *p, u_int length, u_int caplen, u_int bridge_pad) +{ + u_int32_t orgcode; + register u_short et; + register int ret; + + TCHECK2(*p, 5); + orgcode = EXTRACT_24BITS(p); + et = EXTRACT_16BITS(p + 3); + + if (eflag) { + const struct tok *tok = null_values; + const struct oui_tok *otp; + + for (otp = &oui_to_tok[0]; otp->tok != NULL; otp++) { + if (otp->oui == orgcode) { + tok = otp->tok; + break; + } + } + (void)printf("oui %s (0x%06x), %s %s (0x%04x): ", + tok2str(oui_values, "Unknown", orgcode), + orgcode, + (orgcode == 0x000000 ? "ethertype" : "pid"), + tok2str(tok, "Unknown", et), + et); + } + p += 5; + length -= 5; + caplen -= 5; + + switch (orgcode) { + case OUI_ENCAP_ETHER: + case OUI_CISCO_90: + /* + * This is an encapsulated Ethernet packet, + * or a packet bridged by some piece of + * Cisco hardware; the protocol ID is + * an Ethernet protocol type. + */ + ret = ethertype_print(et, p, length, caplen); + if (ret) + return (ret); + break; + + case OUI_APPLETALK: + if (et == ETHERTYPE_ATALK) { + /* + * No, I have no idea why Apple used one + * of their own OUIs, rather than + * 0x000000, and an Ethernet packet + * type, for Appletalk data packets, + * but used 0x000000 and an Ethernet + * packet type for AARP packets. + */ + ret = ethertype_print(et, p, length, caplen); + if (ret) + return (ret); + } + break; + + case OUI_CISCO: + switch (et) { + case PID_CISCO_CDP: + cdp_print(p, length, caplen); + return (1); + case PID_CISCO_DTP: + dtp_print(p, length); + return (1); + case PID_CISCO_UDLD: + udld_print(p, length); + return (1); + case PID_CISCO_VTP: + vtp_print(p, length); + return (1); + case PID_CISCO_PVST: + stp_print(p, length); + return (1); + default: + break; + } + + case OUI_RFC2684: + switch (et) { + + case PID_RFC2684_ETH_FCS: + case PID_RFC2684_ETH_NOFCS: + /* + * XXX - remove the last two bytes for + * PID_RFC2684_ETH_FCS? + */ + /* + * Skip the padding. + */ + TCHECK2(*p, bridge_pad); + caplen -= bridge_pad; + length -= bridge_pad; + p += bridge_pad; + + /* + * What remains is an Ethernet packet. + */ + ether_print(p, length, caplen, NULL, NULL); + return (1); + + case PID_RFC2684_802_5_FCS: + case PID_RFC2684_802_5_NOFCS: + /* + * XXX - remove the last two bytes for + * PID_RFC2684_ETH_FCS? + */ + /* + * Skip the padding, but not the Access + * Control field. + */ + TCHECK2(*p, bridge_pad); + caplen -= bridge_pad; + length -= bridge_pad; + p += bridge_pad; + + /* + * What remains is an 802.5 Token Ring + * packet. + */ + token_print(p, length, caplen); + return (1); + + case PID_RFC2684_FDDI_FCS: + case PID_RFC2684_FDDI_NOFCS: + /* + * XXX - remove the last two bytes for + * PID_RFC2684_ETH_FCS? + */ + /* + * Skip the padding. + */ + TCHECK2(*p, bridge_pad + 1); + caplen -= bridge_pad + 1; + length -= bridge_pad + 1; + p += bridge_pad + 1; + + /* + * What remains is an FDDI packet. + */ + fddi_print(p, length, caplen); + return (1); + + case PID_RFC2684_BPDU: + stp_print(p, length); + return (1); + } + } + return (0); + +trunc: + (void)printf("[|snap]"); + return (1); +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-lldp.c b/print-lldp.c new file mode 100644 index 0000000..e8f67fd --- /dev/null +++ b/print-lldp.c @@ -0,0 +1,1107 @@ +/* + * Copyright (c) 1998-2007 The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * support for the IEEE Link Discovery Protocol as per 802.1ab + * + * Original code by Hannes Gredler (hannes@juniper.net) + * IEEE and TIA extensions by Carles Kishimoto + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-lldp.c,v 1.10 2008-03-20 09:30:56 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "af.h" +#include "oui.h" + +#define LLDP_EXTRACT_TYPE(x) (((x)&0xfe00)>>9) +#define LLDP_EXTRACT_LEN(x) ((x)&0x01ff) + +/* + * TLV type codes + */ +#define LLDP_END_TLV 0 +#define LLDP_CHASSIS_ID_TLV 1 +#define LLDP_PORT_ID_TLV 2 +#define LLDP_TTL_TLV 3 +#define LLDP_PORT_DESCR_TLV 4 +#define LLDP_SYSTEM_NAME_TLV 5 +#define LLDP_SYSTEM_DESCR_TLV 6 +#define LLDP_SYSTEM_CAP_TLV 7 +#define LLDP_MGMT_ADDR_TLV 8 +#define LLDP_PRIVATE_TLV 127 + +static const struct tok lldp_tlv_values[] = { + { LLDP_END_TLV, "End" }, + { LLDP_CHASSIS_ID_TLV, "Chassis ID" }, + { LLDP_PORT_ID_TLV, "Port ID" }, + { LLDP_TTL_TLV, "Time to Live" }, + { LLDP_PORT_DESCR_TLV, "Port Description" }, + { LLDP_SYSTEM_NAME_TLV, "System Name" }, + { LLDP_SYSTEM_DESCR_TLV, "System Description" }, + { LLDP_SYSTEM_CAP_TLV, "System Capabilities" }, + { LLDP_MGMT_ADDR_TLV, "Management Address" }, + { LLDP_PRIVATE_TLV, "Organization specific" }, + { 0, NULL} +}; + +/* + * Chassis ID subtypes + */ +#define LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE 1 +#define LLDP_CHASSIS_INTF_ALIAS_SUBTYPE 2 +#define LLDP_CHASSIS_PORT_COMP_SUBTYPE 3 +#define LLDP_CHASSIS_MAC_ADDR_SUBTYPE 4 +#define LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE 5 +#define LLDP_CHASSIS_INTF_NAME_SUBTYPE 6 +#define LLDP_CHASSIS_LOCAL_SUBTYPE 7 + +static const struct tok lldp_chassis_subtype_values[] = { + { LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE, "Chassis component"}, + { LLDP_CHASSIS_INTF_ALIAS_SUBTYPE, "Interface alias"}, + { LLDP_CHASSIS_PORT_COMP_SUBTYPE, "Port component"}, + { LLDP_CHASSIS_MAC_ADDR_SUBTYPE, "MAC address"}, + { LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE, "Network address"}, + { LLDP_CHASSIS_INTF_NAME_SUBTYPE, "Interface name"}, + { LLDP_CHASSIS_LOCAL_SUBTYPE, "Local"}, + { 0, NULL} +}; + +/* + * Port ID subtypes + */ +#define LLDP_PORT_INTF_ALIAS_SUBTYPE 1 +#define LLDP_PORT_PORT_COMP_SUBTYPE 2 +#define LLDP_PORT_MAC_ADDR_SUBTYPE 3 +#define LLDP_PORT_NETWORK_ADDR_SUBTYPE 4 +#define LLDP_PORT_INTF_NAME_SUBTYPE 5 +#define LLDP_PORT_AGENT_CIRC_ID_SUBTYPE 6 +#define LLDP_PORT_LOCAL_SUBTYPE 7 + +static const struct tok lldp_port_subtype_values[] = { + { LLDP_PORT_INTF_ALIAS_SUBTYPE, "Interface alias"}, + { LLDP_PORT_PORT_COMP_SUBTYPE, "Port component"}, + { LLDP_PORT_MAC_ADDR_SUBTYPE, "MAC address"}, + { LLDP_PORT_NETWORK_ADDR_SUBTYPE, "Network Address"}, + { LLDP_PORT_INTF_NAME_SUBTYPE, "Interface Name"}, + { LLDP_PORT_AGENT_CIRC_ID_SUBTYPE, "Agent circuit ID"}, + { LLDP_PORT_LOCAL_SUBTYPE, "Local"}, + { 0, NULL} +}; + +/* + * System Capabilities + */ +#define LLDP_CAP_OTHER (1 << 0) +#define LLDP_CAP_REPEATER (1 << 1) +#define LLDP_CAP_BRIDGE (1 << 2) +#define LLDP_CAP_WLAN_AP (1 << 3) +#define LLDP_CAP_ROUTER (1 << 4) +#define LLDP_CAP_PHONE (1 << 5) +#define LLDP_CAP_DOCSIS (1 << 6) +#define LLDP_CAP_STATION_ONLY (1 << 7) + +static const struct tok lldp_cap_values[] = { + { LLDP_CAP_OTHER, "Other"}, + { LLDP_CAP_REPEATER, "Repeater"}, + { LLDP_CAP_BRIDGE, "Bridge"}, + { LLDP_CAP_WLAN_AP, "WLAN AP"}, + { LLDP_CAP_ROUTER, "Router"}, + { LLDP_CAP_PHONE, "Telephone"}, + { LLDP_CAP_DOCSIS, "Docsis"}, + { LLDP_CAP_STATION_ONLY, "Station Only"}, + { 0, NULL} +}; + +#define LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID 1 +#define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID 2 +#define LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME 3 +#define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY 4 + +static const struct tok lldp_8021_subtype_values[] = { + { LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID, "Port VLAN Id"}, + { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID, "Port and Protocol VLAN ID"}, + { LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME, "VLAN name"}, + { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY, "Protocol Identity"}, + { 0, NULL} +}; + +#define LLDP_8021_PORT_PROTOCOL_VLAN_SUPPORT (1 << 1) +#define LLDP_8021_PORT_PROTOCOL_VLAN_STATUS (1 << 2) + +static const struct tok lldp_8021_port_protocol_id_values[] = { + { LLDP_8021_PORT_PROTOCOL_VLAN_SUPPORT, "supported"}, + { LLDP_8021_PORT_PROTOCOL_VLAN_STATUS, "enabled"}, + { 0, NULL} +}; + +#define LLDP_PRIVATE_8023_SUBTYPE_MACPHY 1 +#define LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER 2 +#define LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR 3 +#define LLDP_PRIVATE_8023_SUBTYPE_MTU 4 + +static const struct tok lldp_8023_subtype_values[] = { + { LLDP_PRIVATE_8023_SUBTYPE_MACPHY, "MAC/PHY configuration/status"}, + { LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER, "Power via MDI"}, + { LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR, "Link aggregation"}, + { LLDP_PRIVATE_8023_SUBTYPE_MTU, "Max frame size"}, + { 0, NULL} +}; + +#define LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES 1 +#define LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY 2 +#define LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID 3 +#define LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI 4 +#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV 5 +#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV 6 +#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV 7 +#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER 8 +#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME 9 +#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME 10 +#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID 11 + +static const struct tok lldp_tia_subtype_values[] = { + { LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES, "LLDP-MED Capabilities" }, + { LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY, "Network policy" }, + { LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID, "Location identification" }, + { LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI, "Extended power-via-MDI" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV, "Inventory - hardware revision" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV, "Inventory - firmware revision" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV, "Inventory - software revision" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER, "Inventory - serial number" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME, "Inventory - manufacturer name" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME, "Inventory - model name" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID, "Inventory - asset ID" }, + { 0, NULL} +}; + +#define LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_METERS 1 +#define LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_FLOORS 2 + +static const struct tok lldp_tia_location_altitude_type_values[] = { + { LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_METERS, "meters"}, + { LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_FLOORS, "floors"}, + { 0, NULL} +}; + +/* ANSI/TIA-1057 - Annex B */ +#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A1 1 +#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A2 2 +#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A3 3 +#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A4 4 +#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A5 5 +#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A6 6 + +static const struct tok lldp_tia_location_lci_catype_values[] = { + { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A1, "national subdivisions (state,canton,region,province,prefecture)"}, + { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A2, "county, parish, gun, district"}, + { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A3, "city, township, shi"}, + { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A4, "city division, borough, city district, ward chou"}, + { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A5, "neighborhood, block"}, + { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A6, "street"}, + { 0, NULL} +}; + +static const struct tok lldp_tia_location_lci_what_values[] = { + { 0, "location of DHCP server"}, + { 1, "location of the network element believed to be closest to the client"}, + { 2, "location of the client"}, + { 0, NULL} +}; + +/* + * From RFC 3636 - dot3MauType + */ +#define LLDP_MAU_TYPE_UNKNOWN 0 +#define LLDP_MAU_TYPE_AUI 1 +#define LLDP_MAU_TYPE_10BASE_5 2 +#define LLDP_MAU_TYPE_FOIRL 3 +#define LLDP_MAU_TYPE_10BASE_2 4 +#define LLDP_MAU_TYPE_10BASE_T 5 +#define LLDP_MAU_TYPE_10BASE_FP 6 +#define LLDP_MAU_TYPE_10BASE_FB 7 +#define LLDP_MAU_TYPE_10BASE_FL 8 +#define LLDP_MAU_TYPE_10BROAD36 9 +#define LLDP_MAU_TYPE_10BASE_T_HD 10 +#define LLDP_MAU_TYPE_10BASE_T_FD 11 +#define LLDP_MAU_TYPE_10BASE_FL_HD 12 +#define LLDP_MAU_TYPE_10BASE_FL_FD 13 +#define LLDP_MAU_TYPE_100BASE_T4 14 +#define LLDP_MAU_TYPE_100BASE_TX_HD 15 +#define LLDP_MAU_TYPE_100BASE_TX_FD 16 +#define LLDP_MAU_TYPE_100BASE_FX_HD 17 +#define LLDP_MAU_TYPE_100BASE_FX_FD 18 +#define LLDP_MAU_TYPE_100BASE_T2_HD 19 +#define LLDP_MAU_TYPE_100BASE_T2_FD 20 +#define LLDP_MAU_TYPE_1000BASE_X_HD 21 +#define LLDP_MAU_TYPE_1000BASE_X_FD 22 +#define LLDP_MAU_TYPE_1000BASE_LX_HD 23 +#define LLDP_MAU_TYPE_1000BASE_LX_FD 24 +#define LLDP_MAU_TYPE_1000BASE_SX_HD 25 +#define LLDP_MAU_TYPE_1000BASE_SX_FD 26 +#define LLDP_MAU_TYPE_1000BASE_CX_HD 27 +#define LLDP_MAU_TYPE_1000BASE_CX_FD 28 +#define LLDP_MAU_TYPE_1000BASE_T_HD 29 +#define LLDP_MAU_TYPE_1000BASE_T_FD 30 +#define LLDP_MAU_TYPE_10GBASE_X 31 +#define LLDP_MAU_TYPE_10GBASE_LX4 32 +#define LLDP_MAU_TYPE_10GBASE_R 33 +#define LLDP_MAU_TYPE_10GBASE_ER 34 +#define LLDP_MAU_TYPE_10GBASE_LR 35 +#define LLDP_MAU_TYPE_10GBASE_SR 36 +#define LLDP_MAU_TYPE_10GBASE_W 37 +#define LLDP_MAU_TYPE_10GBASE_EW 38 +#define LLDP_MAU_TYPE_10GBASE_LW 39 +#define LLDP_MAU_TYPE_10GBASE_SW 40 + +static const struct tok lldp_mau_types_values[] = { + { LLDP_MAU_TYPE_UNKNOWN, "Unknown"}, + { LLDP_MAU_TYPE_AUI, "AUI"}, + { LLDP_MAU_TYPE_10BASE_5, "10BASE_5"}, + { LLDP_MAU_TYPE_FOIRL, "FOIRL"}, + { LLDP_MAU_TYPE_10BASE_2, "10BASE2"}, + { LLDP_MAU_TYPE_10BASE_T, "10BASET duplex mode unknown"}, + { LLDP_MAU_TYPE_10BASE_FP, "10BASEFP"}, + { LLDP_MAU_TYPE_10BASE_FB, "10BASEFB"}, + { LLDP_MAU_TYPE_10BASE_FL, "10BASEFL duplex mode unknown"}, + { LLDP_MAU_TYPE_10BROAD36, "10BROAD36"}, + { LLDP_MAU_TYPE_10BASE_T_HD, "10BASET hdx"}, + { LLDP_MAU_TYPE_10BASE_T_FD, "10BASET fdx"}, + { LLDP_MAU_TYPE_10BASE_FL_HD, "10BASEFL hdx"}, + { LLDP_MAU_TYPE_10BASE_FL_FD, "10BASEFL fdx"}, + { LLDP_MAU_TYPE_100BASE_T4, "100BASET4"}, + { LLDP_MAU_TYPE_100BASE_TX_HD, "100BASETX hdx"}, + { LLDP_MAU_TYPE_100BASE_TX_FD, "100BASETX fdx"}, + { LLDP_MAU_TYPE_100BASE_FX_HD, "100BASEFX hdx"}, + { LLDP_MAU_TYPE_100BASE_FX_FD, "100BASEFX fdx"}, + { LLDP_MAU_TYPE_100BASE_T2_HD, "100BASET2 hdx"}, + { LLDP_MAU_TYPE_100BASE_T2_FD, "100BASET2 fdx"}, + { LLDP_MAU_TYPE_1000BASE_X_HD, "1000BASEX hdx"}, + { LLDP_MAU_TYPE_1000BASE_X_FD, "1000BASEX fdx"}, + { LLDP_MAU_TYPE_1000BASE_LX_HD, "1000BASELX hdx"}, + { LLDP_MAU_TYPE_1000BASE_LX_FD, "1000BASELX fdx"}, + { LLDP_MAU_TYPE_1000BASE_SX_HD, "1000BASESX hdx"}, + { LLDP_MAU_TYPE_1000BASE_SX_FD, "1000BASESX fdx"}, + { LLDP_MAU_TYPE_1000BASE_CX_HD, "1000BASECX hdx"}, + { LLDP_MAU_TYPE_1000BASE_CX_FD, "1000BASECX fdx"}, + { LLDP_MAU_TYPE_1000BASE_T_HD, "1000BASET hdx"}, + { LLDP_MAU_TYPE_1000BASE_T_FD, "1000BASET fdx"}, + { LLDP_MAU_TYPE_10GBASE_X, "10GBASEX"}, + { LLDP_MAU_TYPE_10GBASE_LX4, "10GBASELX4"}, + { LLDP_MAU_TYPE_10GBASE_R, "10GBASER"}, + { LLDP_MAU_TYPE_10GBASE_ER, "10GBASEER"}, + { LLDP_MAU_TYPE_10GBASE_LR, "10GBASELR"}, + { LLDP_MAU_TYPE_10GBASE_SR, "10GBASESR"}, + { LLDP_MAU_TYPE_10GBASE_W, "10GBASEW"}, + { LLDP_MAU_TYPE_10GBASE_EW, "10GBASEEW"}, + { LLDP_MAU_TYPE_10GBASE_LW, "10GBASELW"}, + { LLDP_MAU_TYPE_10GBASE_SW, "10GBASESW"}, + { 0, NULL} +}; + +#define LLDP_8023_AUTONEGOTIATION_SUPPORT (1 << 0) +#define LLDP_8023_AUTONEGOTIATION_STATUS (1 << 1) + +static const struct tok lldp_8023_autonegotiation_values[] = { + { LLDP_8023_AUTONEGOTIATION_SUPPORT, "supported"}, + { LLDP_8023_AUTONEGOTIATION_STATUS, "enabled"}, + { 0, NULL} +}; + +#define LLDP_TIA_CAPABILITY_MED (1 << 0) +#define LLDP_TIA_CAPABILITY_NETWORK_POLICY (1 << 1) +#define LLDP_TIA_CAPABILITY_LOCATION_IDENTIFICATION (1 << 2) +#define LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PSE (1 << 3) +#define LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PD (1 << 4) +#define LLDP_TIA_CAPABILITY_INVENTORY (1 << 5) + +static const struct tok lldp_tia_capabilities_values[] = { + { LLDP_TIA_CAPABILITY_MED, "LLDP-MED capabilities"}, + { LLDP_TIA_CAPABILITY_NETWORK_POLICY, "network policy"}, + { LLDP_TIA_CAPABILITY_LOCATION_IDENTIFICATION, "location identification"}, + { LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PSE, "extended power via MDI-PSE"}, + { LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PD, "extended power via MDI-PD"}, + { LLDP_TIA_CAPABILITY_INVENTORY, "Inventory"}, + { 0, NULL} +}; + +#define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_1 1 +#define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_2 2 +#define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_3 3 +#define LLDP_TIA_DEVICE_TYPE_NETWORK_CONNECTIVITY 4 + +static const struct tok lldp_tia_device_type_values[] = { + { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_1, "endpoint class 1"}, + { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_2, "endpoint class 2"}, + { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_3, "endpoint class 3"}, + { LLDP_TIA_DEVICE_TYPE_NETWORK_CONNECTIVITY, "network connectivity"}, + { 0, NULL} +}; + +#define LLDP_TIA_APPLICATION_TYPE_VOICE 1 +#define LLDP_TIA_APPLICATION_TYPE_VOICE_SIGNALING 2 +#define LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE 3 +#define LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE_SIGNALING 4 +#define LLDP_TIA_APPLICATION_TYPE_SOFTPHONE_VOICE 5 +#define LLDP_TIA_APPLICATION_TYPE_VIDEO_CONFERENCING 6 +#define LLDP_TIA_APPLICATION_TYPE_STREAMING_VIDEO 7 +#define LLDP_TIA_APPLICATION_TYPE_VIDEO_SIGNALING 8 + +static const struct tok lldp_tia_application_type_values[] = { + { LLDP_TIA_APPLICATION_TYPE_VOICE, "voice"}, + { LLDP_TIA_APPLICATION_TYPE_VOICE_SIGNALING, "voice signaling"}, + { LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE, "guest voice"}, + { LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE_SIGNALING, "guest voice signaling"}, + { LLDP_TIA_APPLICATION_TYPE_SOFTPHONE_VOICE, "softphone voice"}, + { LLDP_TIA_APPLICATION_TYPE_VIDEO_CONFERENCING, "video conferencing"}, + { LLDP_TIA_APPLICATION_TYPE_STREAMING_VIDEO, "streaming video"}, + { LLDP_TIA_APPLICATION_TYPE_VIDEO_SIGNALING, "video signaling"}, + { 0, NULL} +}; + +#define LLDP_TIA_NETWORK_POLICY_U_BIT (1 << 5) +#define LLDP_TIA_NETWORK_POLICY_T_BIT (1 << 6) +#define LLDP_TIA_NETWORK_POLICY_X_BIT (1 << 7) + +static const struct tok lldp_tia_network_policy_bits_values[] = { + { LLDP_TIA_NETWORK_POLICY_U_BIT, "Unknown"}, + { LLDP_TIA_NETWORK_POLICY_T_BIT, "Tagged"}, + { LLDP_TIA_NETWORK_POLICY_X_BIT, "reserved"}, + { 0, NULL} +}; + +#define LLDP_EXTRACT_NETWORK_POLICY_VLAN(x) (((x)&0x1ffe)>>1) +#define LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(x) (((x)&0x01ff)>>6) +#define LLDP_EXTRACT_NETWORK_POLICY_DSCP(x) ((x)&0x003f) + +#define LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED 1 +#define LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS 2 +#define LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN 3 + +static const struct tok lldp_tia_location_data_format_values[] = { + { LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED, "coordinate-based LCI"}, + { LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS, "civic address LCI"}, + { LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN, "ECS ELIN"}, + { 0, NULL} +}; + +#define LLDP_TIA_LOCATION_DATUM_WGS_84 1 +#define LLDP_TIA_LOCATION_DATUM_NAD_83_NAVD_88 2 +#define LLDP_TIA_LOCATION_DATUM_NAD_83_MLLW 3 + +static const struct tok lldp_tia_location_datum_type_values[] = { + { LLDP_TIA_LOCATION_DATUM_WGS_84, "World Geodesic System 1984"}, + { LLDP_TIA_LOCATION_DATUM_NAD_83_NAVD_88, "North American Datum 1983 (NAVD88)"}, + { LLDP_TIA_LOCATION_DATUM_NAD_83_MLLW, "North American Datum 1983 (MLLW)"}, + { 0, NULL} +}; + +#define LLDP_TIA_POWER_SOURCE_PSE 1 +#define LLDP_TIA_POWER_SOURCE_LOCAL 2 +#define LLDP_TIA_POWER_SOURCE_PSE_AND_LOCAL 3 + +static const struct tok lldp_tia_power_source_values[] = { + { LLDP_TIA_POWER_SOURCE_PSE, "PSE - primary power source"}, + { LLDP_TIA_POWER_SOURCE_LOCAL, "local - backup power source"}, + { LLDP_TIA_POWER_SOURCE_PSE_AND_LOCAL, "PSE+local - reserved"}, + { 0, NULL} +}; + +#define LLDP_TIA_POWER_PRIORITY_CRITICAL 1 +#define LLDP_TIA_POWER_PRIORITY_HIGH 2 +#define LLDP_TIA_POWER_PRIORITY_LOW 3 + +static const struct tok lldp_tia_power_priority_values[] = { + { LLDP_TIA_POWER_PRIORITY_CRITICAL, "critical"}, + { LLDP_TIA_POWER_PRIORITY_HIGH, "high"}, + { LLDP_TIA_POWER_PRIORITY_LOW, "low"}, + { 0, NULL} +}; + +#define LLDP_TIA_POWER_VAL_MAX 1024 + +static const struct tok lldp_tia_inventory_values[] = { + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV, "Hardware revision" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV, "Firmware revision" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV, "Software revision" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER, "Serial number" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME, "Manufacturer name" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME, "Model name" }, + { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID, "Asset ID" }, + { 0, NULL} +}; + +/* + * From RFC 3636 - ifMauAutoNegCapAdvertisedBits + */ +#define LLDP_MAU_PMD_OTHER (1 << 15) +#define LLDP_MAU_PMD_10BASE_T (1 << 14) +#define LLDP_MAU_PMD_10BASE_T_FD (1 << 13) +#define LLDP_MAU_PMD_100BASE_T4 (1 << 12) +#define LLDP_MAU_PMD_100BASE_TX (1 << 11) +#define LLDP_MAU_PMD_100BASE_TX_FD (1 << 10) +#define LLDP_MAU_PMD_100BASE_T2 (1 << 9) +#define LLDP_MAU_PMD_100BASE_T2_FD (1 << 8) +#define LLDP_MAU_PMD_FDXPAUSE (1 << 7) +#define LLDP_MAU_PMD_FDXAPAUSE (1 << 6) +#define LLDP_MAU_PMD_FDXSPAUSE (1 << 5) +#define LLDP_MAU_PMD_FDXBPAUSE (1 << 4) +#define LLDP_MAU_PMD_1000BASE_X (1 << 3) +#define LLDP_MAU_PMD_1000BASE_X_FD (1 << 2) +#define LLDP_MAU_PMD_1000BASE_T (1 << 1) +#define LLDP_MAU_PMD_1000BASE_T_FD (1 << 0) + +static const struct tok lldp_pmd_capability_values[] = { + { LLDP_MAU_PMD_10BASE_T, "10BASE-T hdx"}, + { LLDP_MAU_PMD_10BASE_T_FD, "10BASE-T fdx"}, + { LLDP_MAU_PMD_100BASE_T4, "100BASE-T4"}, + { LLDP_MAU_PMD_100BASE_TX, "100BASE-TX hdx"}, + { LLDP_MAU_PMD_100BASE_TX_FD, "100BASE-TX fdx"}, + { LLDP_MAU_PMD_100BASE_T2, "100BASE-T2 hdx"}, + { LLDP_MAU_PMD_100BASE_T2_FD, "100BASE-T2 fdx"}, + { LLDP_MAU_PMD_FDXPAUSE, "Pause for fdx links"}, + { LLDP_MAU_PMD_FDXAPAUSE, "Asym PAUSE for fdx"}, + { LLDP_MAU_PMD_FDXSPAUSE, "Sym PAUSE for fdx"}, + { LLDP_MAU_PMD_FDXBPAUSE, "Asym and Sym PAUSE for fdx"}, + { LLDP_MAU_PMD_1000BASE_X, "1000BASE-{X LX SX CX} hdx"}, + { LLDP_MAU_PMD_1000BASE_X_FD, "1000BASE-{X LX SX CX} fdx"}, + { LLDP_MAU_PMD_1000BASE_T, "1000BASE-T hdx"}, + { LLDP_MAU_PMD_1000BASE_T_FD, "1000BASE-T fdx"}, + { 0, NULL} +}; + +#define LLDP_MDI_PORT_CLASS (1 << 0) +#define LLDP_MDI_POWER_SUPPORT (1 << 1) +#define LLDP_MDI_POWER_STATE (1 << 2) +#define LLDP_MDI_PAIR_CONTROL_ABILITY (1 << 3) + +static const struct tok lldp_mdi_values[] = { + { LLDP_MDI_PORT_CLASS, "PSE"}, + { LLDP_MDI_POWER_SUPPORT, "supported"}, + { LLDP_MDI_POWER_STATE, "enabled"}, + { LLDP_MDI_PAIR_CONTROL_ABILITY, "can be controlled"}, + { 0, NULL} +}; + +#define LLDP_MDI_PSE_PORT_POWER_PAIRS_SIGNAL 1 +#define LLDP_MDI_PSE_PORT_POWER_PAIRS_SPARE 2 + +static const struct tok lldp_mdi_power_pairs_values[] = { + { LLDP_MDI_PSE_PORT_POWER_PAIRS_SIGNAL, "signal"}, + { LLDP_MDI_PSE_PORT_POWER_PAIRS_SPARE, "spare"}, + { 0, NULL} +}; + +#define LLDP_MDI_POWER_CLASS0 1 +#define LLDP_MDI_POWER_CLASS1 2 +#define LLDP_MDI_POWER_CLASS2 3 +#define LLDP_MDI_POWER_CLASS3 4 +#define LLDP_MDI_POWER_CLASS4 5 + +static const struct tok lldp_mdi_power_class_values[] = { + { LLDP_MDI_POWER_CLASS0, "class0"}, + { LLDP_MDI_POWER_CLASS1, "class1"}, + { LLDP_MDI_POWER_CLASS2, "class2"}, + { LLDP_MDI_POWER_CLASS3, "class3"}, + { LLDP_MDI_POWER_CLASS4, "class4"}, + { 0, NULL} +}; + +#define LLDP_AGGREGATION_CAPABILTIY (1 << 0) +#define LLDP_AGGREGATION_STATUS (1 << 1) + +static const struct tok lldp_aggregation_values[] = { + { LLDP_AGGREGATION_CAPABILTIY, "supported"}, + { LLDP_AGGREGATION_STATUS, "enabled"}, + { 0, NULL} +}; + +/* + * Interface numbering subtypes. + */ +#define LLDP_INTF_NUMB_IFX_SUBTYPE 2 +#define LLDP_INTF_NUMB_SYSPORT_SUBTYPE 3 + +static const struct tok lldp_intf_numb_subtype_values[] = { + { LLDP_INTF_NUMB_IFX_SUBTYPE, "Interface Index" }, + { LLDP_INTF_NUMB_SYSPORT_SUBTYPE, "System Port Number" }, + { 0, NULL} +}; + +#define LLDP_INTF_NUM_LEN 5 + +/* + * Print IEEE private extensions. (802.1 annex F) + */ +static int +lldp_private_8021_print(const u_char *tptr) +{ + int subtype, hexdump = FALSE; + + subtype = *(tptr+3); + + printf("\n\t %s Subtype (%u)", + tok2str(lldp_8021_subtype_values, "unknown", subtype), + subtype); + + switch (subtype) { + case LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID: + printf("\n\t port vlan id (PVID): %u", + EXTRACT_16BITS(tptr+4)); + break; + case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID: + printf("\n\t port and protocol vlan id (PPVID): %u, flags [%s] (0x%02x)", + EXTRACT_16BITS(tptr+5), + bittok2str(lldp_8021_port_protocol_id_values, "none", *(tptr+4)), + *(tptr+4)); + break; + case LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME: + printf("\n\t vlan id (VID): %u", + EXTRACT_16BITS(tptr+4)); + printf("\n\t vlan name: "); + safeputs((const char *)tptr+7, *(tptr+6)); + break; + case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY: + printf("\n\t protocol identity: "); + safeputs((const char *)tptr+5, *(tptr+4)); + break; + + default: + hexdump = TRUE; + break; + } + + return hexdump; +} + +/* + * Print IEEE private extensions. (802.3) + */ +static int +lldp_private_8023_print(const u_char *tptr) +{ + int subtype, hexdump = FALSE; + + subtype = *(tptr+3); + + printf("\n\t %s Subtype (%u)", + tok2str(lldp_8023_subtype_values, "unknown", subtype), + subtype); + + switch (subtype) { + case LLDP_PRIVATE_8023_SUBTYPE_MACPHY: + printf("\n\t autonegotiation [%s] (0x%02x)", + bittok2str(lldp_8023_autonegotiation_values, "none", *(tptr+4)), + *(tptr+4)); + printf("\n\t PMD autoneg capability [%s] (0x%04x)", + bittok2str(lldp_pmd_capability_values,"unknown", EXTRACT_16BITS(tptr+5)), + EXTRACT_16BITS(tptr+5)); + printf("\n\t MAU type %s (0x%04x)", + tok2str(lldp_mau_types_values, "unknown", EXTRACT_16BITS(tptr+7)), + EXTRACT_16BITS(tptr+7)); + break; + + case LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER: + printf("\n\t MDI power support [%s], power pair %s, power class %s", + bittok2str(lldp_mdi_values, "none", *(tptr+4)), + tok2str(lldp_mdi_power_pairs_values, "unknown", *(tptr+5)), + tok2str(lldp_mdi_power_class_values, "unknown", *(tptr+6))); + break; + + case LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR: + printf("\n\t aggregation status [%s], aggregation port ID %u", + bittok2str(lldp_aggregation_values, "none", *(tptr+4)), + EXTRACT_32BITS(tptr+5)); + break; + + case LLDP_PRIVATE_8023_SUBTYPE_MTU: + printf("\n\t MTU size %u", EXTRACT_16BITS(tptr+4)); + break; + + default: + hexdump = TRUE; + break; + } + + return hexdump; +} + +/* + * Extract 34bits of latitude/longitude coordinates. + */ +static u_int64_t +lldp_extract_latlon(const u_char *tptr) +{ + u_int64_t latlon; + + latlon = *tptr & 0x3; + latlon = (latlon << 32) | EXTRACT_32BITS(tptr+1); + + return latlon; +} + +/* + * Print private TIA extensions. + */ +static int +lldp_private_tia_print(const u_char *tptr, u_int tlv_len) +{ + int subtype, hexdump = FALSE; + u_int8_t location_format; + u_int16_t power_val; + u_int8_t lci_len, ca_type, ca_len; + + subtype = *(tptr+3); + + printf("\n\t %s Subtype (%u)", + tok2str(lldp_tia_subtype_values, "unknown", subtype), + subtype); + + switch (subtype) { + case LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES: + printf("\n\t Media capabilities [%s] (0x%04x)", + bittok2str(lldp_tia_capabilities_values, "none", + EXTRACT_16BITS(tptr+4)), EXTRACT_16BITS(tptr+4)); + printf("\n\t Device type [%s] (0x%02x)", + tok2str(lldp_tia_device_type_values, "unknown", *(tptr+6)), + *(tptr+6)); + break; + + case LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY: + printf("\n\t Application type [%s] (0x%02x)", + tok2str(lldp_tia_application_type_values, "none", *(tptr+4)), + *(tptr+4)); + printf(", Flags [%s]", bittok2str( + lldp_tia_network_policy_bits_values, "none", *(tptr+5))); + printf("\n\t Vlan id %u", + LLDP_EXTRACT_NETWORK_POLICY_VLAN(EXTRACT_16BITS(tptr+5))); + printf(", L2 priority %u", + LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(EXTRACT_16BITS(tptr+6))); + printf(", DSCP value %u", + LLDP_EXTRACT_NETWORK_POLICY_DSCP(EXTRACT_16BITS(tptr+6))); + break; + + case LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID: + location_format = *(tptr+4); + printf("\n\t Location data format %s (0x%02x)", + tok2str(lldp_tia_location_data_format_values, "unknown", location_format), + location_format); + + switch (location_format) { + case LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED: + printf("\n\t Latitude resolution %u, latitude value %" PRIu64, + (*(tptr+5)>>2), lldp_extract_latlon(tptr+5)); + printf("\n\t Longitude resolution %u, longitude value %" PRIu64, + (*(tptr+10)>>2), lldp_extract_latlon(tptr+10)); + printf("\n\t Altitude type %s (%u)", + tok2str(lldp_tia_location_altitude_type_values, "unknown",(*(tptr+15)>>4)), + (*(tptr+15)>>4)); + printf("\n\t Altitude resolution %u, altitude value 0x%x", + (EXTRACT_16BITS(tptr+15)>>6)&0x3f, + ((EXTRACT_32BITS(tptr+16)&0x3fffffff))); + printf("\n\t Datum %s (0x%02x)", + tok2str(lldp_tia_location_datum_type_values, "unknown", *(tptr+20)), + *(tptr+20)); + break; + + case LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS: + lci_len = *(tptr+5); + printf("\n\t LCI length %u, LCI what %s (0x%02x), Country-code ", + lci_len, + tok2str(lldp_tia_location_lci_what_values, "unknown", *(tptr+6)), + *(tptr+6)); + + /* Country code */ + safeputs((const char *)(tptr+7), 2); + + lci_len = lci_len-3; + tptr = tptr + 9; + + /* Decode each civic address element */ + while (lci_len > 0) { + ca_type = *(tptr); + ca_len = *(tptr+1); + + tptr += 2; + lci_len -= 2; + + printf("\n\t CA type \'%s\' (%u), length %u: ", + tok2str(lldp_tia_location_lci_catype_values, "unknown", ca_type), + ca_type, ca_len); + + /* basic sanity check */ + if ( ca_type == 0 || ca_len == 0) { + return hexdump; + } + + safeputs((const char *)tptr, ca_len); + tptr += ca_len; + lci_len -= ca_len; + } + break; + + case LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN: + printf("\n\t ECS ELIN id "); + safeputs((const char *)tptr+5, tlv_len-5); + break; + + default: + printf("\n\t Location ID "); + print_unknown_data(tptr+5, "\n\t ", tlv_len-5); + } + break; + + case LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI: + printf("\n\t Power type [%s]", + (*(tptr+4)&0xC0>>6) ? "PD device" : "PSE device"); + printf(", Power source [%s]", + tok2str(lldp_tia_power_source_values, "none", (*(tptr+4)&0x30)>>4)); + printf("\n\t Power priority [%s] (0x%02x)", + tok2str(lldp_tia_power_priority_values, "none", *(tptr+4)&0x0f), + *(tptr+4)&0x0f); + power_val = EXTRACT_16BITS(tptr+5); + if (power_val < LLDP_TIA_POWER_VAL_MAX) { + printf(", Power %.1f Watts", ((float)power_val)/10); + } else { + printf(", Power %u (Reserved)", power_val); + } + break; + + case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV: + case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV: + case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV: + case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER: + case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME: + case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME: + case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID: + printf("\n\t %s ", + tok2str(lldp_tia_inventory_values, "unknown", subtype)); + safeputs((const char *)tptr+4, tlv_len-4); + break; + + default: + hexdump = TRUE; + break; + } + + return hexdump; +} + +static char * +lldp_network_addr_print(const u_char *tptr) { + + u_int8_t af; + static char buf[BUFSIZE]; + const char * (*pfunc)(const u_char *); + + af = *tptr; + switch (af) { + case AFNUM_INET: + pfunc = getname; + break; +#ifdef INET6 + case AFNUM_INET6: + pfunc = getname6; + break; +#endif + case AFNUM_802: + pfunc = etheraddr_string; + break; + default: + pfunc = NULL; + break; + } + + if (!pfunc) { + snprintf(buf, sizeof(buf), "AFI %s (%u), no AF printer !", + tok2str(af_values, "Unknown", af), af); + } else { + snprintf(buf, sizeof(buf), "AFI %s (%u): %s", + tok2str(af_values, "Unknown", af), af, (*pfunc)(tptr+1)); + } + + return buf; +} + +static int +lldp_mgmt_addr_tlv_print(const u_char *pptr, u_int len) { + + u_int8_t mgmt_addr_len, intf_num_subtype, oid_len; + const u_char *tptr; + u_int tlen; + + tlen = len; + tptr = pptr; + + mgmt_addr_len = *tptr++; + tlen--; + + if (tlen < mgmt_addr_len) { + return 0; + } + + printf("\n\t Management Address length %u, %s", + mgmt_addr_len, + lldp_network_addr_print(tptr)); + tptr += mgmt_addr_len; + tlen -= mgmt_addr_len; + + if (tlen < LLDP_INTF_NUM_LEN) { + return 0; + } + + intf_num_subtype = *tptr; + printf("\n\t %s Interface Numbering (%u): %u", + tok2str(lldp_intf_numb_subtype_values, "Unknown", intf_num_subtype), + intf_num_subtype, + EXTRACT_32BITS(tptr+1)); + + tptr += LLDP_INTF_NUM_LEN; + tlen -= LLDP_INTF_NUM_LEN; + + /* + * The OID is optional. + */ + if (tlen) { + oid_len = *tptr; + + if (oid_len) { + printf("\n\t OID length %u", oid_len); + safeputs((const char *)tptr+1, oid_len); + } + } + + return 1; +} + +void +lldp_print(register const u_char *pptr, register u_int len) { + + u_int8_t subtype; + u_int16_t tlv, cap, ena_cap; + u_int oui, tlen, hexdump, tlv_type, tlv_len; + const u_char *tptr; + + tptr = pptr; + tlen = len; + + if (vflag) { + printf("LLDP, length %u", len); + } + + while (tlen >= sizeof(tlv)) { + + TCHECK2(*tptr, sizeof(tlv)); + + tlv = EXTRACT_16BITS(tptr); + + tlv_type = LLDP_EXTRACT_TYPE(tlv); + tlv_len = LLDP_EXTRACT_LEN(tlv); + hexdump = FALSE; + + tlen -= sizeof(tlv); + tptr += sizeof(tlv); + + if (vflag) { + printf("\n\t%s TLV (%u), length %u", + tok2str(lldp_tlv_values, "Unknown", tlv_type), + tlv_type, tlv_len); + } + + /* infinite loop check */ + if (!tlv_type || !tlv_len) { + break; + } + + TCHECK2(*tptr, tlv_len); + + switch (tlv_type) { + case LLDP_TTL_TLV: + if (vflag) { + printf(": TTL %us", EXTRACT_16BITS(tptr)); + } + break; + + case LLDP_SYSTEM_NAME_TLV: + + /* + * The system name is also print in non-verbose mode + * similar to the CDP printer. + */ + if (vflag) { + printf(": "); + safeputs((const char *)tptr, tlv_len); + } else { + printf("LLDP, name "); + safeputs((const char *)tptr, tlv_len); + printf(", length %u", len); + } + break; + + case LLDP_PORT_DESCR_TLV: + if (vflag) { + printf(": "); + safeputs((const char *)tptr, tlv_len); + } + break; + + case LLDP_SYSTEM_DESCR_TLV: + if (vflag) { + printf("\n\t "); + safeputs((const char *)tptr, tlv_len); + } + break; + + + case LLDP_CHASSIS_ID_TLV: + if (vflag) { + subtype = *tptr; + printf("\n\t Subtype %s (%u): ", + tok2str(lldp_chassis_subtype_values, "Unknown", subtype), + subtype); + + switch (subtype) { + case LLDP_CHASSIS_MAC_ADDR_SUBTYPE: + printf("%s", etheraddr_string(tptr+1)); + break; + + case LLDP_CHASSIS_INTF_NAME_SUBTYPE: /* fall through */ + case LLDP_CHASSIS_LOCAL_SUBTYPE: + case LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE: + case LLDP_CHASSIS_INTF_ALIAS_SUBTYPE: + case LLDP_CHASSIS_PORT_COMP_SUBTYPE: + safeputs((const char *)tptr+1, tlv_len-1); + break; + + case LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE: + printf("%s", lldp_network_addr_print(tptr+1)); + break; + + default: + hexdump = TRUE; + break; + } + } + break; + + case LLDP_PORT_ID_TLV: + if (vflag) { + subtype = *tptr; + printf("\n\t Subtype %s (%u): ", + tok2str(lldp_port_subtype_values, "Unknown", subtype), + subtype); + + switch (subtype) { + case LLDP_PORT_MAC_ADDR_SUBTYPE: + printf("%s", etheraddr_string(tptr+1)); + break; + + case LLDP_PORT_INTF_NAME_SUBTYPE: /* fall through */ + case LLDP_PORT_LOCAL_SUBTYPE: + case LLDP_PORT_AGENT_CIRC_ID_SUBTYPE: + case LLDP_PORT_INTF_ALIAS_SUBTYPE: + case LLDP_PORT_PORT_COMP_SUBTYPE: + safeputs((const char *)tptr+1, tlv_len-1); + break; + + case LLDP_PORT_NETWORK_ADDR_SUBTYPE: + printf("%s", lldp_network_addr_print(tptr+1)); + break; + + default: + hexdump = TRUE; + break; + } + } + break; + + case LLDP_PRIVATE_TLV: + if (vflag) { + oui = EXTRACT_24BITS(tptr); + printf(": OUI %s (0x%06x)", tok2str(oui_values, "Unknown", oui), oui); + + switch (oui) { + case OUI_IEEE_8021_PRIVATE: + hexdump = lldp_private_8021_print(tptr); + break; + case OUI_IEEE_8023_PRIVATE: + hexdump = lldp_private_8023_print(tptr); + break; + case OUI_TIA: + hexdump = lldp_private_tia_print(tptr, tlv_len); + break; + default: + hexdump = TRUE; + break; + } + } + break; + + case LLDP_SYSTEM_CAP_TLV: + if (vflag) { + cap = EXTRACT_16BITS(tptr); + ena_cap = EXTRACT_16BITS(tptr+2); + printf("\n\t System Capabilities [%s] (0x%04x)", + bittok2str(lldp_cap_values, "none", cap), cap); + printf("\n\t Enabled Capabilities [%s] (0x%04x)", + bittok2str(lldp_cap_values, "none", ena_cap), ena_cap); + } + break; + + case LLDP_MGMT_ADDR_TLV: + if (vflag) { + if (!lldp_mgmt_addr_tlv_print(tptr, tlen)) { + goto trunc; + } + } + break; + + default: + hexdump = TRUE; + break; + } + + /* do we also want to see a hex dump ? */ + if (vflag > 1 || (vflag && hexdump)) { + print_unknown_data(tptr,"\n\t ", tlv_len); + } + + tlen -= tlv_len; + tptr += tlv_len; + } + return; + trunc: + printf("\n\t[|LLDP]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/print-lmp.c b/print-lmp.c new file mode 100644 index 0000000..556db17 --- /dev/null +++ b/print-lmp.c @@ -0,0 +1,883 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Support for the Link Management Protocol as per rfc 4204. + * + * Original code by Hannes Gredler (hannes@juniper.net) + * Support for LMP service discovery extensions (defined by UNI 1.0) added + * by Manu Pathak (mapathak@cisco.com), May 2005 + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-lmp.c,v 1.11 2007-08-02 17:32:49 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "gmpls.h" + +/* + * LMP common header + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Vers | (Reserved) | Flags | Msg Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | LMP Length | (Reserved) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct lmp_common_header { + u_int8_t version_res[2]; + u_int8_t flags; + u_int8_t msg_type; + u_int8_t length[2]; + u_int8_t reserved[2]; +}; + +#define LMP_VERSION 1 +#define LMP_EXTRACT_VERSION(x) (((x)&0xf0)>>4) + +static const struct tok lmp_header_flag_values[] = { + { 0x01, "Control Channel Down"}, + { 0x02, "LMP restart"}, + { 0, NULL} +}; + +static const struct tok lmp_obj_te_link_flag_values[] = { + { 0x01, "Fault Management Supported"}, + { 0x02, "Link Verification Supported"}, + { 0, NULL} +}; + +static const struct tok lmp_obj_data_link_flag_values[] = { + { 0x01, "Data Link Port"}, + { 0x02, "Allocated for user traffic"}, + { 0x04, "Failed link"}, + { 0, NULL} +}; + +static const struct tok lmp_obj_channel_status_values[] = { + { 1, "Signal Okay"}, + { 2, "Signal Degraded"}, + { 3, "Signal Fail"}, + { 0, NULL} +}; + +static const struct tok lmp_obj_begin_verify_flag_values[] = { + { 0x0001, "Verify all links"}, + { 0x0002, "Data link type"}, + { 0, NULL} +}; + +static const struct tok lmp_obj_begin_verify_error_values[] = { + { 0x01, "Link Verification Procedure Not supported"}, + { 0x02, "Unwilling to verify"}, + { 0x04, "Unsupported verification transport mechanism"}, + { 0x08, "Link-Id configuration error"}, + { 0x10, "Unknown object c-type"}, + { 0, NULL} +}; + +static const struct tok lmp_obj_link_summary_error_values[] = { + { 0x01, "Unacceptable non-negotiable LINK-SUMMARY parameters"}, + { 0x02, "Renegotiate LINK-SUMMARY parameters"}, + { 0x04, "Invalid TE-LINK Object"}, + { 0x08, "Invalid DATA-LINK Object"}, + { 0x10, "Unknown TE-LINK Object c-type"}, + { 0x20, "Unknown DATA-LINK Object c-type"}, + { 0, NULL} +}; + +/* Service Config Supported Protocols Flags */ +static const struct tok lmp_obj_service_config_sp_flag_values[] = { + { 0x01, "RSVP Supported"}, + { 0x02, "LDP Supported"}, + { 0, NULL} +}; + +/* Service Config Client Port Service Attribute Transparency Flags */ +static const struct tok lmp_obj_service_config_cpsa_tp_flag_values[] = { + { 0x01, "Path/VC Overhead Transparency Supported"}, + { 0x02, "Line/MS Overhead Transparency Supported"}, + { 0x04, "Section/RS Overhead Transparency Supported"}, + { 0, NULL} +}; + +/* Service Config Client Port Service Attribute Contiguous Concatenation Types Flags */ +static const struct tok lmp_obj_service_config_cpsa_cct_flag_values[] = { + { 0x01, "Contiguous Concatenation Types Supported"}, + { 0, NULL} +}; + +/* Service Config Network Service Attributes Transparency Flags */ +static const struct tok lmp_obj_service_config_nsa_transparency_flag_values[] = { + { 0x01, "Standard SOH/RSOH Transparency Supported"}, + { 0x02, "Standard LOH/MSOH Transparency Supported"}, + { 0, NULL} +}; + +/* Service Config Network Service Attributes TCM Monitoring Flags */ +static const struct tok lmp_obj_service_config_nsa_tcm_flag_values[] = { + { 0x01, "Transparent Tandem Connection Monitoring Supported"}, + { 0, NULL} +}; + +/* Network Service Attributes Network Diversity Flags */ +static const struct tok lmp_obj_service_config_nsa_network_diversity_flag_values[] = { + { 0x01, "Node Diversity Supported"}, + { 0x02, "Link Diversity Supported"}, + { 0x04, "SRLG Diversity Supported"}, + { 0, NULL} +}; + +#define LMP_MSGTYPE_CONFIG 1 +#define LMP_MSGTYPE_CONFIG_ACK 2 +#define LMP_MSGTYPE_CONFIG_NACK 3 +#define LMP_MSGTYPE_HELLO 4 +#define LMP_MSGTYPE_VERIFY_BEGIN 5 +#define LMP_MSGTYPE_VERIFY_BEGIN_ACK 6 +#define LMP_MSGTYPE_VERIFY_BEGIN_NACK 7 +#define LMP_MSGTYPE_VERIFY_END 8 +#define LMP_MSGTYPE_VERIFY_END_ACK 9 +#define LMP_MSGTYPE_TEST 10 +#define LMP_MSGTYPE_TEST_STATUS_SUCCESS 11 +#define LMP_MSGTYPE_TEST_STATUS_FAILURE 12 +#define LMP_MSGTYPE_TEST_STATUS_ACK 13 +#define LMP_MSGTYPE_LINK_SUMMARY 14 +#define LMP_MSGTYPE_LINK_SUMMARY_ACK 15 +#define LMP_MSGTYPE_LINK_SUMMARY_NACK 16 +#define LMP_MSGTYPE_CHANNEL_STATUS 17 +#define LMP_MSGTYPE_CHANNEL_STATUS_ACK 18 +#define LMP_MSGTYPE_CHANNEL_STATUS_REQ 19 +#define LMP_MSGTYPE_CHANNEL_STATUS_RESP 20 +/* LMP Service Discovery message types defined by UNI 1.0 */ +#define LMP_MSGTYPE_SERVICE_CONFIG 50 +#define LMP_MSGTYPE_SERVICE_CONFIG_ACK 51 +#define LMP_MSGTYPE_SERVICE_CONFIG_NACK 52 + +static const struct tok lmp_msg_type_values[] = { + { LMP_MSGTYPE_CONFIG, "Config"}, + { LMP_MSGTYPE_CONFIG_ACK, "Config ACK"}, + { LMP_MSGTYPE_CONFIG_NACK, "Config NACK"}, + { LMP_MSGTYPE_HELLO, "Hello"}, + { LMP_MSGTYPE_VERIFY_BEGIN, "Begin Verify"}, + { LMP_MSGTYPE_VERIFY_BEGIN_ACK, "Begin Verify ACK"}, + { LMP_MSGTYPE_VERIFY_BEGIN_NACK, "Begin Verify NACK"}, + { LMP_MSGTYPE_VERIFY_END, "End Verify"}, + { LMP_MSGTYPE_VERIFY_END_ACK, "End Verify ACK"}, + { LMP_MSGTYPE_TEST, "Test"}, + { LMP_MSGTYPE_TEST_STATUS_SUCCESS, "Test Status Success"}, + { LMP_MSGTYPE_TEST_STATUS_FAILURE, "Test Status Failure"}, + { LMP_MSGTYPE_TEST_STATUS_ACK, "Test Status ACK"}, + { LMP_MSGTYPE_LINK_SUMMARY, "Link Summary"}, + { LMP_MSGTYPE_LINK_SUMMARY_ACK, "Link Summary ACK"}, + { LMP_MSGTYPE_LINK_SUMMARY_NACK, "Link Summary NACK"}, + { LMP_MSGTYPE_CHANNEL_STATUS, "Channel Status"}, + { LMP_MSGTYPE_CHANNEL_STATUS_ACK, "Channel Status ACK"}, + { LMP_MSGTYPE_CHANNEL_STATUS_REQ, "Channel Status Request"}, + { LMP_MSGTYPE_CHANNEL_STATUS_RESP, "Channel Status Response"}, + { LMP_MSGTYPE_SERVICE_CONFIG, "Service Config"}, + { LMP_MSGTYPE_SERVICE_CONFIG_ACK, "Service Config ACK"}, + { LMP_MSGTYPE_SERVICE_CONFIG_NACK, "Service Config NACK"}, + { 0, NULL} +}; + +/* + * LMP object header + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |N| C-Type | Class | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * // (object contents) // + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct lmp_object_header { + u_int8_t ctype; + u_int8_t class_num; + u_int8_t length[2]; +}; + +#define LMP_OBJ_CC_ID 1 +#define LMP_OBJ_NODE_ID 2 +#define LMP_OBJ_LINK_ID 3 +#define LMP_OBJ_INTERFACE_ID 4 +#define LMP_OBJ_MESSAGE_ID 5 +#define LMP_OBJ_CONFIG 6 +#define LMP_OBJ_HELLO 7 +#define LMP_OBJ_VERIFY_BEGIN 8 +#define LMP_OBJ_VERIFY_BEGIN_ACK 9 +#define LMP_OBJ_VERIFY_ID 10 +#define LMP_OBJ_TE_LINK 11 +#define LMP_OBJ_DATA_LINK 12 +#define LMP_OBJ_CHANNEL_STATUS 13 +#define LMP_OBJ_CHANNEL_STATUS_REQ 14 +#define LMP_OBJ_ERROR_CODE 20 + +#define LMP_OBJ_SERVICE_CONFIG 51 /* defined in UNI 1.0 */ + +static const struct tok lmp_obj_values[] = { + { LMP_OBJ_CC_ID, "Control Channel ID" }, + { LMP_OBJ_NODE_ID, "Node ID" }, + { LMP_OBJ_LINK_ID, "Link ID" }, + { LMP_OBJ_INTERFACE_ID, "Interface ID" }, + { LMP_OBJ_MESSAGE_ID, "Message ID" }, + { LMP_OBJ_CONFIG, "Configuration" }, + { LMP_OBJ_HELLO, "Hello" }, + { LMP_OBJ_VERIFY_BEGIN, "Verify Begin" }, + { LMP_OBJ_VERIFY_BEGIN_ACK, "Verify Begin ACK" }, + { LMP_OBJ_VERIFY_ID, "Verify ID" }, + { LMP_OBJ_TE_LINK, "TE Link" }, + { LMP_OBJ_DATA_LINK, "Data Link" }, + { LMP_OBJ_CHANNEL_STATUS, "Channel Status" }, + { LMP_OBJ_CHANNEL_STATUS_REQ, "Channel Status Request" }, + { LMP_OBJ_ERROR_CODE, "Error Code" }, + { LMP_OBJ_SERVICE_CONFIG, "Service Config" }, + + { 0, NULL} +}; + +#define INT_SWITCHING_TYPE_SUBOBJ 1 +#define WAVELENGTH_SUBOBJ 2 + +static const struct tok lmp_data_link_subobj[] = { + { INT_SWITCHING_TYPE_SUBOBJ, "Interface Switching Type" }, + { WAVELENGTH_SUBOBJ , "Wavelength" }, + { 0, NULL} +}; + +#define LMP_CTYPE_IPV4 1 +#define LMP_CTYPE_IPV6 2 + +#define LMP_CTYPE_LOC 1 +#define LMP_CTYPE_RMT 2 +#define LMP_CTYPE_UNMD 3 + +#define LMP_CTYPE_IPV4_LOC 1 +#define LMP_CTYPE_IPV4_RMT 2 +#define LMP_CTYPE_IPV6_LOC 3 +#define LMP_CTYPE_IPV6_RMT 4 +#define LMP_CTYPE_UNMD_LOC 5 +#define LMP_CTYPE_UNMD_RMT 6 + +#define LMP_CTYPE_1 1 +#define LMP_CTYPE_2 2 + +#define LMP_CTYPE_HELLO_CONFIG 1 +#define LMP_CTYPE_HELLO 1 + +#define LMP_CTYPE_BEGIN_VERIFY_ERROR 1 +#define LMP_CTYPE_LINK_SUMMARY_ERROR 2 + +/* C-Types for Service Config Object */ +#define LMP_CTYPE_SERVICE_CONFIG_SP 1 +#define LMP_CTYPE_SERVICE_CONFIG_CPSA 2 +#define LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM 3 +#define LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY 4 + +/* + * Different link types allowed in the Client Port Service Attributes + * subobject defined for LMP Service Discovery in the UNI 1.0 spec + */ +#define LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH 5 /* UNI 1.0 Sec 9.4.2 */ +#define LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET 6 /* UNI 1.0 Sec 9.4.2 */ + +/* + * the ctypes are not globally unique so for + * translating it to strings we build a table based + * on objects offsetted by the ctype + */ + +static const struct tok lmp_ctype_values[] = { + { 256*LMP_OBJ_CC_ID+LMP_CTYPE_LOC, "Local" }, + { 256*LMP_OBJ_CC_ID+LMP_CTYPE_RMT, "Remote" }, + { 256*LMP_OBJ_NODE_ID+LMP_CTYPE_LOC, "Local" }, + { 256*LMP_OBJ_NODE_ID+LMP_CTYPE_RMT, "Remote" }, + { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV4_LOC, "IPv4 Local" }, + { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV4_RMT, "IPv4 Remote" }, + { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV6_LOC, "IPv6 Local" }, + { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV6_RMT, "IPv6 Remote" }, + { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_UNMD_LOC, "Unnumbered Local" }, + { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_UNMD_RMT, "Unnumbered Remote" }, + { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV4_LOC, "IPv4 Local" }, + { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV4_RMT, "IPv4 Remote" }, + { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV6_LOC, "IPv6 Local" }, + { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV6_RMT, "IPv6 Remote" }, + { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_UNMD_LOC, "Unnumbered Local" }, + { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_UNMD_RMT, "Unnumbered Remote" }, + { 256*LMP_OBJ_MESSAGE_ID+LMP_CTYPE_1, "1" }, + { 256*LMP_OBJ_MESSAGE_ID+LMP_CTYPE_2, "2" }, + { 256*LMP_OBJ_CONFIG+LMP_CTYPE_1, "1" }, + { 256*LMP_OBJ_HELLO+LMP_CTYPE_1, "1" }, + { 256*LMP_OBJ_VERIFY_BEGIN+LMP_CTYPE_1, "1" }, + { 256*LMP_OBJ_VERIFY_BEGIN_ACK+LMP_CTYPE_1, "1" }, + { 256*LMP_OBJ_VERIFY_ID+LMP_CTYPE_1, "1" }, + { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_IPV4, "IPv4" }, + { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_IPV6, "IPv6" }, + { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_UNMD, "Unnumbered" }, + { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_IPV4, "IPv4" }, + { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_IPV6, "IPv6" }, + { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_UNMD, "Unnumbered" }, + { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_IPV4, "IPv4" }, + { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_IPV6, "IPv6" }, + { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_UNMD, "Unnumbered" }, + { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_IPV4, "IPv4" }, + { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_IPV6, "IPv6" }, + { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_UNMD, "Unnumbered" }, + { 256*LMP_OBJ_ERROR_CODE+LMP_CTYPE_1, "1" }, + { 256*LMP_OBJ_ERROR_CODE+LMP_CTYPE_2, "2" }, + { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_SP, "1" }, + { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_CPSA, "2" }, + { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM, "3" }, + { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY, "4" }, + { 0, NULL} +}; + +void +lmp_print(register const u_char *pptr, register u_int len) { + + const struct lmp_common_header *lmp_com_header; + const struct lmp_object_header *lmp_obj_header; + const u_char *tptr,*obj_tptr; + int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen; + int hexdump; + int offset,subobj_type,subobj_len,total_subobj_len; + int link_type; + + union { /* int to float conversion buffer */ + float f; + u_int32_t i; + } bw; + + tptr=pptr; + lmp_com_header = (const struct lmp_common_header *)pptr; + TCHECK(*lmp_com_header); + + /* + * Sanity checking of the header. + */ + if (LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]) != LMP_VERSION) { + printf("LMP version %u packet not supported", + LMP_EXTRACT_VERSION(lmp_com_header->version_res[0])); + return; + } + + /* in non-verbose mode just lets print the basic Message Type*/ + if (vflag < 1) { + printf("LMPv%u %s Message, length: %u", + LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]), + tok2str(lmp_msg_type_values, "unknown (%u)",lmp_com_header->msg_type), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + + tlen=EXTRACT_16BITS(lmp_com_header->length); + + printf("\n\tLMPv%u, msg-type: %s, Flags: [%s], length: %u", + LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]), + tok2str(lmp_msg_type_values, "unknown, type: %u",lmp_com_header->msg_type), + bittok2str(lmp_header_flag_values,"none",lmp_com_header->flags), + tlen); + + tptr+=sizeof(const struct lmp_common_header); + tlen-=sizeof(const struct lmp_common_header); + + while(tlen>0) { + /* did we capture enough for fully decoding the object header ? */ + if (!TTEST2(*tptr, sizeof(struct lmp_object_header))) + goto trunc; + + lmp_obj_header = (const struct lmp_object_header *)tptr; + lmp_obj_len=EXTRACT_16BITS(lmp_obj_header->length); + lmp_obj_ctype=(lmp_obj_header->ctype)&0x7f; + + if(lmp_obj_len % 4 || lmp_obj_len < 4) + return; + + printf("\n\t %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u", + tok2str(lmp_obj_values, + "Unknown", + lmp_obj_header->class_num), + lmp_obj_header->class_num, + tok2str(lmp_ctype_values, + "Unknown", + ((lmp_obj_header->class_num)<<8)+lmp_obj_ctype), + lmp_obj_ctype, + (lmp_obj_header->ctype)&0x80 ? "" : "non-", + lmp_obj_len); + + obj_tptr=tptr+sizeof(struct lmp_object_header); + obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header); + + /* did we capture enough for fully decoding the object ? */ + if (!TTEST2(*tptr, lmp_obj_len)) + goto trunc; + hexdump=FALSE; + + switch(lmp_obj_header->class_num) { + + case LMP_OBJ_CC_ID: + switch(lmp_obj_ctype) { + case LMP_CTYPE_LOC: + case LMP_CTYPE_RMT: + printf("\n\t Control Channel ID: %u (0x%08x)", + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + break; + + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_LINK_ID: + case LMP_OBJ_INTERFACE_ID: + switch(lmp_obj_ctype) { + case LMP_CTYPE_IPV4_LOC: + case LMP_CTYPE_IPV4_RMT: + printf("\n\t IPv4 Link ID: %s (0x%08x)", + ipaddr_string(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + break; +#ifdef INET6 + case LMP_CTYPE_IPV6_LOC: + case LMP_CTYPE_IPV6_RMT: + printf("\n\t IPv6 Link ID: %s (0x%08x)", + ip6addr_string(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + break; +#endif + case LMP_CTYPE_UNMD_LOC: + case LMP_CTYPE_UNMD_RMT: + printf("\n\t Link ID: %u (0x%08x)", + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + break; + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_MESSAGE_ID: + switch(lmp_obj_ctype) { + case LMP_CTYPE_1: + printf("\n\t Message ID: %u (0x%08x)", + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + break; + case LMP_CTYPE_2: + printf("\n\t Message ID Ack: %u (0x%08x)", + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + break; + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_NODE_ID: + switch(lmp_obj_ctype) { + case LMP_CTYPE_LOC: + case LMP_CTYPE_RMT: + printf("\n\t Node ID: %s (0x%08x)", + ipaddr_string(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + break; + + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_CONFIG: + switch(lmp_obj_ctype) { + case LMP_CTYPE_HELLO_CONFIG: + printf("\n\t Hello Interval: %u\n\t Hello Dead Interval: %u", + EXTRACT_16BITS(obj_tptr), + EXTRACT_16BITS(obj_tptr+2)); + break; + + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_HELLO: + switch(lmp_obj_ctype) { + case LMP_CTYPE_HELLO: + printf("\n\t Tx Seq: %u, Rx Seq: %u", + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr+4)); + break; + + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_TE_LINK: + printf("\n\t Flags: [%s]", + bittok2str(lmp_obj_te_link_flag_values, + "none", + EXTRACT_16BITS(obj_tptr)>>8)); + + switch(lmp_obj_ctype) { + case LMP_CTYPE_IPV4: + printf("\n\t Local Link-ID: %s (0x%08x) \ + \n\t Remote Link-ID: %s (0x%08x)", + ipaddr_string(obj_tptr+4), + EXTRACT_32BITS(obj_tptr+4), + ipaddr_string(obj_tptr+8), + EXTRACT_32BITS(obj_tptr+8)); + break; + +#ifdef INET6 + case LMP_CTYPE_IPV6: +#endif + case LMP_CTYPE_UNMD: + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_DATA_LINK: + printf("\n\t Flags: [%s]", + bittok2str(lmp_obj_data_link_flag_values, + "none", + EXTRACT_16BITS(obj_tptr)>>8)); + + switch(lmp_obj_ctype) { + case LMP_CTYPE_IPV4: + case LMP_CTYPE_UNMD: + printf("\n\t Local Interface ID: %s (0x%08x) \ + \n\t Remote Interface ID: %s (0x%08x)", + ipaddr_string(obj_tptr+4), + EXTRACT_32BITS(obj_tptr+4), + ipaddr_string(obj_tptr+8), + EXTRACT_32BITS(obj_tptr+8)); + + total_subobj_len = lmp_obj_len - 16; + offset = 12; + while (total_subobj_len > 0 && hexdump == FALSE ) { + subobj_type = EXTRACT_16BITS(obj_tptr+offset)>>8; + subobj_len = EXTRACT_16BITS(obj_tptr+offset)&0x00FF; + printf("\n\t Subobject, Type: %s (%u), Length: %u", + tok2str(lmp_data_link_subobj, + "Unknown", + subobj_type), + subobj_type, + subobj_len); + switch(subobj_type) { + case INT_SWITCHING_TYPE_SUBOBJ: + printf("\n\t Switching Type: %s (%u)", + tok2str(gmpls_switch_cap_values, + "Unknown", + EXTRACT_16BITS(obj_tptr+offset+2)>>8), + EXTRACT_16BITS(obj_tptr+offset+2)>>8); + printf("\n\t Encoding Type: %s (%u)", + tok2str(gmpls_encoding_values, + "Unknown", + EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF), + EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF); + bw.i = EXTRACT_32BITS(obj_tptr+offset+4); + printf("\n\t Min Reservable Bandwidth: %.3f Mbps", + bw.f*8/1000000); + bw.i = EXTRACT_32BITS(obj_tptr+offset+8); + printf("\n\t Max Reservable Bandwidth: %.3f Mbps", + bw.f*8/1000000); + break; + case WAVELENGTH_SUBOBJ: + printf("\n\t Wavelength: %u", + EXTRACT_32BITS(obj_tptr+offset+4)); + break; + default: + /* Any Unknown Subobject ==> Exit loop */ + hexdump=TRUE; + break; + } + total_subobj_len-=subobj_len; + offset+=subobj_len; + } + + break; +#ifdef INET6 + case LMP_CTYPE_IPV6: +#endif + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_VERIFY_BEGIN: + switch(lmp_obj_ctype) { + case LMP_CTYPE_1: + printf("\n\t Flags: %s", + bittok2str(lmp_obj_begin_verify_flag_values, + "none", + EXTRACT_16BITS(obj_tptr))); + printf("\n\t Verify Interval: %u", + EXTRACT_16BITS(obj_tptr+2)); + printf("\n\t Data links: %u", + EXTRACT_32BITS(obj_tptr+4)); + printf("\n\t Encoding type: %s", + tok2str(gmpls_encoding_values, "Unknown", *(obj_tptr+8))); + printf("\n\t Verify Tranport Mechanism: %u (0x%x) %s", + EXTRACT_16BITS(obj_tptr+10), + EXTRACT_16BITS(obj_tptr+10), + EXTRACT_16BITS(obj_tptr+10)&8000 ? "(Payload test messages capable)" : ""); + bw.i = EXTRACT_32BITS(obj_tptr+12); + printf("\n\t Transmission Rate: %.3f Mbps",bw.f*8/1000000); + printf("\n\t Wavelength: %u", + EXTRACT_32BITS(obj_tptr+16)); + break; + + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_VERIFY_BEGIN_ACK: + switch(lmp_obj_ctype) { + case LMP_CTYPE_1: + printf("\n\t Verify Dead Interval: %u \ + \n\t Verify Transport Response: %u", + EXTRACT_16BITS(obj_tptr), + EXTRACT_16BITS(obj_tptr+2)); + break; + + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_VERIFY_ID: + switch(lmp_obj_ctype) { + case LMP_CTYPE_1: + printf("\n\t Verify ID: %u", + EXTRACT_32BITS(obj_tptr)); + break; + + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_CHANNEL_STATUS: + switch(lmp_obj_ctype) { + case LMP_CTYPE_IPV4: + case LMP_CTYPE_UNMD: + offset = 0; + /* Decode pairs: */ + while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) { + printf("\n\t Interface ID: %s (0x%08x)", + ipaddr_string(obj_tptr+offset), + EXTRACT_32BITS(obj_tptr+offset)); + + printf("\n\t\t Active: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ? + "Allocated" : "Non-allocated", + (EXTRACT_32BITS(obj_tptr+offset+4)>>31)); + + printf("\n\t\t Direction: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ? + "Transmit" : "Receive", + (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1); + + printf("\n\t\t Channel Status: %s (%u)", + tok2str(lmp_obj_channel_status_values, + "Unknown", + EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF), + EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF); + offset+=8; + } + break; +#ifdef INET6 + case LMP_CTYPE_IPV6: +#endif + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_CHANNEL_STATUS_REQ: + switch(lmp_obj_ctype) { + case LMP_CTYPE_IPV4: + case LMP_CTYPE_UNMD: + offset = 0; + while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) { + printf("\n\t Interface ID: %s (0x%08x)", + ipaddr_string(obj_tptr+offset), + EXTRACT_32BITS(obj_tptr+offset)); + offset+=4; + } + break; +#ifdef INET6 + case LMP_CTYPE_IPV6: +#endif + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_ERROR_CODE: + switch(lmp_obj_ctype) { + case LMP_CTYPE_BEGIN_VERIFY_ERROR: + printf("\n\t Error Code: %s", + bittok2str(lmp_obj_begin_verify_error_values, + "none", + EXTRACT_32BITS(obj_tptr))); + break; + + case LMP_CTYPE_LINK_SUMMARY_ERROR: + printf("\n\t Error Code: %s", + bittok2str(lmp_obj_link_summary_error_values, + "none", + EXTRACT_32BITS(obj_tptr))); + break; + default: + hexdump=TRUE; + } + break; + + case LMP_OBJ_SERVICE_CONFIG: + switch (lmp_obj_ctype) { + case LMP_CTYPE_SERVICE_CONFIG_SP: + + printf("\n\t Flags: %s", + bittok2str(lmp_obj_service_config_sp_flag_values, + "none", + EXTRACT_16BITS(obj_tptr)>>8)); + + printf("\n\t UNI Version: %u", + EXTRACT_16BITS(obj_tptr) & 0x00FF); + + break; + + case LMP_CTYPE_SERVICE_CONFIG_CPSA: + + link_type = EXTRACT_16BITS(obj_tptr)>>8; + + printf("\n\t Link Type: %s (%u)", + tok2str(lmp_sd_service_config_cpsa_link_type_values, + "Unknown", link_type), + link_type); + + if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH) { + printf("\n\t Signal Type: %s (%u)", + tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values, + "Unknown", + EXTRACT_16BITS(obj_tptr) & 0x00FF), + EXTRACT_16BITS(obj_tptr) & 0x00FF); + } + + if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET) { + printf("\n\t Signal Type: %s (%u)", + tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values, + "Unknown", + EXTRACT_16BITS(obj_tptr) & 0x00FF), + EXTRACT_16BITS(obj_tptr) & 0x00FF); + } + + printf("\n\t Transparency: %s", + bittok2str(lmp_obj_service_config_cpsa_tp_flag_values, + "none", + EXTRACT_16BITS(obj_tptr+2)>>8)); + + printf("\n\t Contiguous Concatenation Types: %s", + bittok2str(lmp_obj_service_config_cpsa_cct_flag_values, + "none", + EXTRACT_16BITS(obj_tptr+2)>>8 & 0x00FF)); + + printf("\n\t Minimum NCC: %u", + EXTRACT_16BITS(obj_tptr+4)); + + printf("\n\t Maximum NCC: %u", + EXTRACT_16BITS(obj_tptr+6)); + + printf("\n\t Minimum NVC:%u", + EXTRACT_16BITS(obj_tptr+8)); + + printf("\n\t Maximum NVC:%u", + EXTRACT_16BITS(obj_tptr+10)); + + printf("\n\t Local Interface ID: %s (0x%08x)", + ipaddr_string(obj_tptr+12), + EXTRACT_32BITS(obj_tptr+12)); + + break; + + case LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM: + + printf("\n\t Transparency Flags: %s", + bittok2str( + lmp_obj_service_config_nsa_transparency_flag_values, + "none", + EXTRACT_32BITS(obj_tptr))); + + printf("\n\t TCM Monitoring Flags: %s", + bittok2str( + lmp_obj_service_config_nsa_tcm_flag_values, + "none", + EXTRACT_16BITS(obj_tptr+6) & 0x00FF)); + + break; + + case LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY: + + printf("\n\t Diversity: Flags: %s", + bittok2str( + lmp_obj_service_config_nsa_network_diversity_flag_values, + "none", + EXTRACT_16BITS(obj_tptr+2) & 0x00FF)); + break; + + default: + hexdump = TRUE; + }; + + break; + + default: + if (vflag <= 1) + print_unknown_data(obj_tptr,"\n\t ",obj_tlen); + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag > 1 || hexdump==TRUE) + print_unknown_data(tptr+sizeof(sizeof(struct lmp_object_header)),"\n\t ", + lmp_obj_len-sizeof(struct lmp_object_header)); + + tptr+=lmp_obj_len; + tlen-=lmp_obj_len; + } + return; +trunc: + printf("\n\t\t packet exceeded snapshot"); +} diff --git a/print-lspping.c b/print-lspping.c new file mode 100644 index 0000000..6958bda --- /dev/null +++ b/print-lspping.c @@ -0,0 +1,896 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-lspping.c,v 1.20 2008-01-28 14:20:43 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +#include "bgp.h" +#include "l2vpn.h" +#include "oui.h" + +/* + * LSPPING common header + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Version Number | Must Be Zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message Type | Reply mode | Return Code | Return Subcode| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sender's Handle | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sequence Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TimeStamp Sent (seconds) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TimeStamp Sent (microseconds) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TimeStamp Received (seconds) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TimeStamp Received (microseconds) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | TLVs ... | + * . . + * . . + * . . + */ + +struct lspping_common_header { + u_int8_t version[2]; + u_int8_t reserved[2]; + u_int8_t msg_type; + u_int8_t reply_mode; + u_int8_t return_code; + u_int8_t return_subcode; + u_int8_t sender_handle[4]; + u_int8_t seq_number[4]; + u_int8_t ts_sent_sec[4]; + u_int8_t ts_sent_usec[4]; + u_int8_t ts_rcvd_sec[4]; + u_int8_t ts_rcvd_usec[4]; +}; + +#define LSPPING_VERSION 1 + +static const struct tok lspping_msg_type_values[] = { + { 1, "MPLS Echo Request"}, + { 2, "MPLS Echo Reply"}, + { 0, NULL} +}; + +static const struct tok lspping_reply_mode_values[] = { + { 1, "Do not reply"}, + { 2, "Reply via an IPv4/IPv6 UDP packet"}, + { 3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"}, + { 4, "Reply via application level control channel"}, + { 0, NULL} +}; + +static const struct tok lspping_return_code_values[] = { + { 0, "No return code or return code contained in the Error Code TLV"}, + { 1, "Malformed echo request received"}, + { 2, "One or more of the TLVs was not understood"}, + { 3, "Replying router is an egress for the FEC at stack depth"}, + { 4, "Replying router has no mapping for the FEC at stack depth"}, + { 5, "Reserved"}, + { 6, "Reserved"}, + { 7, "Reserved"}, + { 8, "Label switched at stack-depth"}, + { 9, "Label switched but no MPLS forwarding at stack-depth"}, + { 10, "Mapping for this FEC is not the given label at stack depth"}, + { 11, "No label entry at stack-depth"}, + { 12, "Protocol not associated with interface at FEC stack depth"}, +}; + + +/* + * LSPPING TLV header + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Value | + * . . + * . . + * . . + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct lspping_tlv_header { + u_int8_t type[2]; + u_int8_t length[2]; +}; + +#define LSPPING_TLV_TARGET_FEC_STACK 1 +#define LSPPING_TLV_DOWNSTREAM_MAPPING 2 +#define LSPPING_TLV_PAD 3 +#define LSPPING_TLV_VENDOR_ENTERPRISE 5 +#define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4 +#define LSPPING_TLV_INTERFACE_LABEL_STACK 7 +#define LSPPING_TLV_ERROR_CODE 9 +#define LSPPING_TLV_REPLY_TOS_BYTE 10 +#define LSPPING_TLV_BFD_DISCRIMINATOR 15 /* draft-ietf-bfd-mpls-02 */ +#define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4 +#define LSPPING_TLV_VENDOR_PRIVATE 0xfc00 + +static const struct tok lspping_tlv_values[] = { + { LSPPING_TLV_TARGET_FEC_STACK, "Target FEC Stack" }, + { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" }, + { LSPPING_TLV_PAD, "Pad" }, + { LSPPING_TLV_ERROR_CODE, "Error Code" }, + { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" }, + { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" }, + { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" }, + { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" }, + { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" }, + { 0, NULL} +}; + +#define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4 1 +#define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6 2 +#define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4 3 +#define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6 4 +#define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4 6 +#define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6 7 +#define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT 8 +#define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD 9 +#define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID 10 +#define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4 11 +#define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6 12 + +static const struct tok lspping_tlvtargetfec_subtlv_values[] = { + { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4, "LDP IPv4 prefix"}, + { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6, "LDP IPv6 prefix"}, + { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4, "RSVP IPv4 Session Query"}, + { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6, "RSVP IPv6 Session Query"}, + { 5, "Reserved"}, + { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4, "VPN IPv4 prefix"}, + { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6, "VPN IPv6 prefix"}, + { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT, "L2 VPN endpoint"}, + { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD, "L2 circuit ID (old)"}, + { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID, "L2 circuit ID"}, + { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4, "BGP labeled IPv4 prefix"}, + { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6, "BGP labeled IPv6 prefix"}, + { 0, NULL} +}; + +/* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IPv4 prefix | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Prefix Length | Must Be Zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t { + u_int8_t prefix [4]; + u_int8_t prefix_len; +}; + +/* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IPv6 prefix | + * | (16 octets) | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Prefix Length | Must Be Zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t { + u_int8_t prefix [16]; + u_int8_t prefix_len; +}; + +/* + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sender identifier | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IPv4 prefix | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Prefix Length | Must Be Zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t { + u_int8_t sender_id [4]; + u_int8_t prefix [4]; + u_int8_t prefix_len; +}; + +/* + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sender identifier | + * | (16 octets) | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IPv6 prefix | + * | (16 octets) | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Prefix Length | Must Be Zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t { + u_int8_t sender_id [16]; + u_int8_t prefix [16]; + u_int8_t prefix_len; +}; + +/* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IPv4 tunnel end point address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Must Be Zero | Tunnel ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Extended Tunnel ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IPv4 tunnel sender address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Must Be Zero | LSP ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t { + u_int8_t tunnel_endpoint [4]; + u_int8_t res[2]; + u_int8_t tunnel_id[2]; + u_int8_t extended_tunnel_id[4]; + u_int8_t tunnel_sender [4]; + u_int8_t res2[2]; + u_int8_t lsp_id [2]; +}; + +/* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IPv6 tunnel end point address | + * | | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Must Be Zero | Tunnel ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Extended Tunnel ID | + * | | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IPv6 tunnel sender address | + * | | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Must Be Zero | LSP ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t { + u_int8_t tunnel_endpoint [16]; + u_int8_t res[2]; + u_int8_t tunnel_id[2]; + u_int8_t extended_tunnel_id[16]; + u_int8_t tunnel_sender [16]; + u_int8_t res2[2]; + u_int8_t lsp_id [2]; +}; + +/* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Route Distinguisher | + * | (8 octets) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IPv4 prefix | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Prefix Length | Must Be Zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t { + u_int8_t rd [8]; + u_int8_t prefix [4]; + u_int8_t prefix_len; +}; + +/* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Route Distinguisher | + * | (8 octets) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IPv6 prefix | + * | (16 octets) | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Prefix Length | Must Be Zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t { + u_int8_t rd [8]; + u_int8_t prefix [16]; + u_int8_t prefix_len; +}; + +/* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Route Distinguisher | + * | (8 octets) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sender's CE ID | Receiver's CE ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encapsulation Type | Must Be Zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * 0 1 2 3 + */ +struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t { + u_int8_t rd [8]; + u_int8_t sender_ce_id [2]; + u_int8_t receiver_ce_id [2]; + u_int8_t encapsulation[2]; +}; + +/* + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Remote PE Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | VC ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encapsulation Type | Must Be Zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t { + u_int8_t remote_pe_address [4]; + u_int8_t vc_id [4]; + u_int8_t encapsulation[2]; +}; + +/* + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sender's PE Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Remote PE Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | VC ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encapsulation Type | Must Be Zero | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t { + u_int8_t sender_pe_address [4]; + u_int8_t remote_pe_address [4]; + u_int8_t vc_id [4]; + u_int8_t encapsulation[2]; +}; + +/* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | MTU | Address Type | Resvd (SBZ) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Downstream IP Address (4 or 16 octets) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Downstream Interface Address (4 or 16 octets) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Hash Key Type | Depth Limit | Multipath Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * . . + * . (Multipath Information) . + * . . + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Downstream Label | Protocol | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * . . + * . . + * . . + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Downstream Label | Protocol | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lspping_tlv_downstream_map_ipv4_t { + u_int8_t mtu [2]; + u_int8_t address_type; + u_int8_t res; + u_int8_t downstream_ip[4]; + u_int8_t downstream_interface[4]; +}; + +struct lspping_tlv_downstream_map_ipv6_t { + u_int8_t mtu [2]; + u_int8_t address_type; + u_int8_t res; + u_int8_t downstream_ip[16]; + u_int8_t downstream_interface[16]; +}; + +struct lspping_tlv_downstream_map_info_t { + u_int8_t hash_key_type; + u_int8_t depth_limit; + u_int8_t multipath_length [2]; +}; + +#define LSPPING_AFI_IPV4 1 +#define LSPPING_AFI_UNMB 2 +#define LSPPING_AFI_IPV6 3 + +static const struct tok lspping_tlv_downstream_addr_values[] = { + { LSPPING_AFI_IPV4, "IPv4"}, + { LSPPING_AFI_IPV6, "IPv6"}, + { LSPPING_AFI_UNMB, "Unnumbered"}, + { 0, NULL} +}; + +void +lspping_print(register const u_char *pptr, register u_int len) { + + const struct lspping_common_header *lspping_com_header; + const struct lspping_tlv_header *lspping_tlv_header; + const struct lspping_tlv_header *lspping_subtlv_header; + const u_char *tptr,*tlv_tptr,*subtlv_tptr; + int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen; + int tlv_hexdump,subtlv_hexdump; + int lspping_subtlv_len,lspping_subtlv_type; + struct timeval timestamp; + + union { + const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4; + const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6; + const struct lspping_tlv_downstream_map_info_t *lspping_tlv_downstream_map_info; + } tlv_ptr; + + union { + const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *lspping_tlv_targetfec_subtlv_ldp_ipv4; + const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *lspping_tlv_targetfec_subtlv_ldp_ipv6; + const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *lspping_tlv_targetfec_subtlv_rsvp_ipv4; + const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *lspping_tlv_targetfec_subtlv_rsvp_ipv6; + const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv4; + const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv6; + const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *lspping_tlv_targetfec_subtlv_l2vpn_endpt; + const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old; + const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t *lspping_tlv_targetfec_subtlv_l2vpn_vcid; + const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *lspping_tlv_targetfec_subtlv_bgp_ipv4; + const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6; + } subtlv_ptr; + + tptr=pptr; + lspping_com_header = (const struct lspping_common_header *)pptr; + TCHECK(*lspping_com_header); + + /* + * Sanity checking of the header. + */ + if (EXTRACT_16BITS(&lspping_com_header->version[0]) != LSPPING_VERSION) { + printf("LSP-PING version %u packet not supported", + EXTRACT_16BITS(&lspping_com_header->version[0])); + return; + } + + /* in non-verbose mode just lets print the basic Message Type*/ + if (vflag < 1) { + printf("LSP-PINGv%u, %s, seq %u, length: %u", + EXTRACT_16BITS(&lspping_com_header->version[0]), + tok2str(lspping_msg_type_values, "unknown (%u)",lspping_com_header->msg_type), + EXTRACT_32BITS(lspping_com_header->seq_number), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + + tlen=len; + + printf("\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t reply-mode: %s (%u)", + EXTRACT_16BITS(&lspping_com_header->version[0]), + tok2str(lspping_msg_type_values, "unknown",lspping_com_header->msg_type), + lspping_com_header->msg_type, + len, + tok2str(lspping_reply_mode_values, "unknown",lspping_com_header->reply_mode), + lspping_com_header->reply_mode); + + /* + * the following return codes require that the subcode is attached + * at the end of the translated token output + */ + if (lspping_com_header->return_code == 3 || + lspping_com_header->return_code == 4 || + lspping_com_header->return_code == 8 || + lspping_com_header->return_code == 10 || + lspping_com_header->return_code == 11 || + lspping_com_header->return_code == 12 ) + printf("\n\t Return Code: %s %u (%u)\n\t Return Subcode: (%u)", + tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code), + lspping_com_header->return_subcode, + lspping_com_header->return_code, + lspping_com_header->return_subcode); + else + printf("\n\t Return Code: %s (%u)\n\t Return Subcode: (%u)", + tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code), + lspping_com_header->return_code, + lspping_com_header->return_subcode); + + printf("\n\t Sender Handle: 0x%08x, Sequence: %u", + EXTRACT_32BITS(lspping_com_header->sender_handle), + EXTRACT_32BITS(lspping_com_header->seq_number)); + + timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_sent_sec); + timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_sent_usec); + printf("\n\t Sender Timestamp: "); + ts_print(×tamp); + + timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_sec); + timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_usec); + printf("Receiver Timestamp: "); + if ((timestamp.tv_sec != 0) && (timestamp.tv_usec != 0)) + ts_print(×tamp); + else + printf("no timestamp"); + + tptr+=sizeof(const struct lspping_common_header); + tlen-=sizeof(const struct lspping_common_header); + + while(tlen>(int)sizeof(struct lspping_tlv_header)) { + + /* did we capture enough for fully decoding the tlv header ? */ + if (!TTEST2(*tptr, sizeof(struct lspping_tlv_header))) + goto trunc; + + lspping_tlv_header = (const struct lspping_tlv_header *)tptr; + lspping_tlv_type=EXTRACT_16BITS(lspping_tlv_header->type); + lspping_tlv_len=EXTRACT_16BITS(lspping_tlv_header->length); + + /* some little sanity checking */ + if (lspping_tlv_type == 0 || lspping_tlv_len == 0) + return; + + if(lspping_tlv_len < 4) { + printf("\n\t ERROR: TLV %u bogus size %u",lspping_tlv_type,lspping_tlv_len); + return; + } + + printf("\n\t %s TLV (%u), length: %u", + tok2str(lspping_tlv_values, + "Unknown", + lspping_tlv_type), + lspping_tlv_type, + lspping_tlv_len); + + tlv_tptr=tptr+sizeof(struct lspping_tlv_header); + tlv_tlen=lspping_tlv_len; /* header not included -> no adjustment */ + + /* did we capture enough for fully decoding the tlv ? */ + if (!TTEST2(*tptr, lspping_tlv_len)) + goto trunc; + tlv_hexdump=FALSE; + + switch(lspping_tlv_type) { + case LSPPING_TLV_TARGET_FEC_STACK: + while(tlv_tlen>(int)sizeof(struct lspping_tlv_header)) { + + /* did we capture enough for fully decoding the subtlv header ? */ + if (!TTEST2(*tptr, sizeof(struct lspping_tlv_header))) + goto trunc; + subtlv_hexdump=FALSE; + + lspping_subtlv_header = (const struct lspping_tlv_header *)tlv_tptr; + lspping_subtlv_type=EXTRACT_16BITS(lspping_subtlv_header->type); + lspping_subtlv_len=EXTRACT_16BITS(lspping_subtlv_header->length); + subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header); + + if (lspping_subtlv_len == 0) + break; + + printf("\n\t %s subTLV (%u), length: %u", + tok2str(lspping_tlvtargetfec_subtlv_values, + "Unknown", + lspping_subtlv_type), + lspping_subtlv_type, + lspping_subtlv_len); + + switch(lspping_subtlv_type) { + + case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4: + subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4 = \ + (const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *)subtlv_tptr; + printf("\n\t %s/%u", + ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix), + subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix_len); + break; + +#ifdef INET6 + case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6: + subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6 = \ + (const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *)subtlv_tptr; + printf("\n\t %s/%u", + ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix), + subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix_len); + break; +#endif + + case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4: + subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4 = \ + (const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *)subtlv_tptr; + printf("\n\t %s/%u, sender-id %s", + ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix), + subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len, + ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->sender_id)); + break; + +#ifdef INET6 + case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6: + subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6 = \ + (const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *)subtlv_tptr; + printf("\n\t %s/%u, sender-id %s", + ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix), + subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len, + ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->sender_id)); + break; +#endif + + case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4: + subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4 = \ + (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *)subtlv_tptr; + printf("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" \ + "\n\t tunnel-id 0x%04x, extended tunnel-id %s", + ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint), + ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender), + EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id), + EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id), + ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->extended_tunnel_id)); + break; + +#ifdef INET6 + case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6: + subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6 = \ + (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *)subtlv_tptr; + printf("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" \ + "\n\t tunnel-id 0x%04x, extended tunnel-id %s", + ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint), + ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender), + EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id), + EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id), + ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->extended_tunnel_id)); + break; +#endif + + case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4: + subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4 = \ + (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *)subtlv_tptr; + printf("\n\t RD: %s, %s/%u", + bgp_vpn_rd_print(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->rd), + ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix), + subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix_len); + break; + +#ifdef INET6 + case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6: + subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6 = \ + (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *)subtlv_tptr; + printf("\n\t RD: %s, %s/%u", + bgp_vpn_rd_print(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->rd), + ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix), + subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix_len); + break; +#endif + + case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT: + subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt = \ + (const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *)subtlv_tptr; + printf("\n\t RD: %s, Sender CE-ID: %u, Receiver CE-ID: %u" \ + "\n\t Encapsulation Type: %s (%u)", + bgp_vpn_rd_print(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->rd), + EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ce_id), + EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ce_id), + tok2str(l2vpn_encaps_values, + "unknown", + EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)), + EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)); + + break; + + /* the old L2VPN VCID subTLV does not have support for the sender field */ + case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD: + subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old = \ + (const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t *)subtlv_tptr; + printf("\n\t Remote PE: %s" \ + "\n\t VC-ID: 0x%08x, Encapsulation Type: %s (%u)", + ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address), + EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->vc_id), + tok2str(l2vpn_encaps_values, + "unknown", + EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation)), + EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation)); + + break; + + case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID: + subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid = \ + (const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t *)subtlv_tptr; + printf("\n\t Sender PE: %s, Remote PE: %s" \ + "\n\t VC-ID: 0x%08x, Encapsulation Type: %s (%u)", + ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address), + ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address), + EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->vc_id), + tok2str(l2vpn_encaps_values, + "unknown", + EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation)), + EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation)); + + break; + + default: + subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */ + break; + } + /* do we want to see an additionally subtlv hexdump ? */ + if (vflag > 1 || subtlv_hexdump==TRUE) + print_unknown_data(tlv_tptr+sizeof(struct lspping_tlv_header), \ + "\n\t ", + lspping_subtlv_len); + + tlv_tptr+=lspping_subtlv_len; + tlv_tlen-=lspping_subtlv_len+sizeof(struct lspping_tlv_header); + } + break; + + case LSPPING_TLV_DOWNSTREAM_MAPPING: + /* that strange thing with the downstream map TLV is that until now + * we do not know if its IPv4 or IPv6 , after we found the adress-type + * lets recast the tlv_tptr and move on */ + + tlv_ptr.lspping_tlv_downstream_map_ipv4= \ + (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr; + tlv_ptr.lspping_tlv_downstream_map_ipv6= \ + (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr; + printf("\n\t MTU: %u, Address-Type: %s (%u)", + EXTRACT_16BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->mtu), + tok2str(lspping_tlv_downstream_addr_values, + "unknown", + tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type), + tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type); + + switch(tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type) { + + case LSPPING_AFI_IPV4: + printf("\n\t Downstream IP: %s" \ + "\n\t Downstream Interface IP: %s", + ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip), + ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface)); + tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t); + tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t); + break; +#ifdef INET6 + case LSPPING_AFI_IPV6: + printf("\n\t Downstream IP: %s" \ + "\n\t Downstream Interface IP: %s", + ip6addr_string(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip), + ip6addr_string(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface)); + tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t); + tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t); + break; +#endif + case LSPPING_AFI_UNMB: + printf("\n\t Downstream IP: %s" \ + "\n\t Downstream Interface Index: 0x%08x", + ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip), + EXTRACT_32BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface)); + tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t); + tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t); + break; + + default: + /* should not happen ! - no error message - tok2str() has barked already */ + break; + } + + tlv_ptr.lspping_tlv_downstream_map_info= \ + (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr; + + /* FIXME add hash-key type, depth limit, multipath processing */ + + + tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_info_t); + tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_info_t); + + /* FIXME print downstream labels */ + + + tlv_hexdump=TRUE; /* dump the TLV until code complete */ + + break; + + case LSPPING_TLV_BFD_DISCRIMINATOR: + tptr += sizeof(struct lspping_tlv_header); + if (!TTEST2(*tptr, LSPPING_TLV_BFD_DISCRIMINATOR_LEN)) + goto trunc; + printf("\n\t BFD Discriminator 0x%08x", EXTRACT_32BITS(tptr)); + break; + + case LSPPING_TLV_VENDOR_ENTERPRISE: + { + u_int32_t vendor_id; + + if (!TTEST2(*tptr, LSPPING_TLV_VENDOR_ENTERPRISE_LEN)) + goto trunc; + vendor_id = EXTRACT_32BITS(tlv_tptr); + printf("\n\t Vendor: %s (0x%04x)", + tok2str(smi_values, "Unknown", vendor_id), + vendor_id); + } + break; + + /* + * FIXME those are the defined TLVs that lack a decoder + * you are welcome to contribute code ;-) + */ + case LSPPING_TLV_PAD: + case LSPPING_TLV_ERROR_CODE: + case LSPPING_TLV_VENDOR_PRIVATE: + + default: + if (vflag <= 1) + print_unknown_data(tlv_tptr,"\n\t ",tlv_tlen); + break; + } + /* do we want to see an additionally tlv hexdump ? */ + if (vflag > 1 || tlv_hexdump==TRUE) + print_unknown_data(tptr+sizeof(sizeof(struct lspping_tlv_header)),"\n\t ", + lspping_tlv_len); + + + /* All TLVs are aligned to four octet boundary */ + if (lspping_tlv_len % 4) { + lspping_tlv_len += (4 - lspping_tlv_len % 4); + } + + tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header); + tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header); + } + return; +trunc: + printf("\n\t\t packet exceeded snapshot"); +} diff --git a/print-lwapp.c b/print-lwapp.c new file mode 100644 index 0000000..984ebaa --- /dev/null +++ b/print-lwapp.c @@ -0,0 +1,360 @@ +/* + * Copyright (c) 1998-2007 The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Support for the Light Weight Access Point Protocol as per draft-ohara-capwap-lwapp-04 + * + * Original code by Carles Kishimoto + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-lwapp.c,v 1.1 2007-07-24 16:07:30 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * LWAPP transport (common) header + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |VER| RID |C|F|L| Frag ID | Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Status/WLANs | Payload... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +struct lwapp_transport_header { + u_int8_t version; + u_int8_t frag_id; + u_int8_t length[2]; + u_int16_t status; +}; + +/* + * LWAPP control header + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message Type | Seq Num | Msg Element Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Session ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Msg Element [0..N] | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct lwapp_control_header { + u_int8_t msg_type; + u_int8_t seq_num; + u_int8_t len[2]; + u_int8_t session_id[4]; +}; + +#define LWAPP_VERSION 0 +#define LWAPP_EXTRACT_VERSION(x) (((x)&0xC0)>>6) +#define LWAPP_EXTRACT_RID(x) (((x)&0x38)>>3) +#define LWAPP_EXTRACT_CONTROL_BIT(x) (((x)&0x04)>>2) + +static const struct tok lwapp_header_bits_values[] = { + { 0x01, "Last Fragment Bit"}, + { 0x02, "Fragment Bit"}, + { 0x04, "Control Bit"}, + { 0, NULL} +}; + +#define LWAPP_MSGTYPE_DISCOVERY_REQUEST 1 +#define LWAPP_MSGTYPE_DISCOVERY_RESPONSE 2 +#define LWAPP_MSGTYPE_JOIN_REQUEST 3 +#define LWAPP_MSGTYPE_JOIN_RESPONSE 4 +#define LWAPP_MSGTYPE_JOIN_ACK 5 +#define LWAPP_MSGTYPE_JOIN_CONFIRM 6 +#define LWAPP_MSGTYPE_CONFIGURE_REQUEST 10 +#define LWAPP_MSGTYPE_CONFIGURE_RESPONSE 11 +#define LWAPP_MSGTYPE_CONF_UPDATE_REQUEST 12 +#define LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE 13 +#define LWAPP_MSGTYPE_WTP_EVENT_REQUEST 14 +#define LWAPP_MSGTYPE_WTP_EVENT_RESPONSE 15 +#define LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST 16 +#define LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE 17 +#define LWAPP_MSGTYPE_ECHO_REQUEST 22 +#define LWAPP_MSGTYPE_ECHO_RESPONSE 23 +#define LWAPP_MSGTYPE_IMAGE_DATA_REQUEST 24 +#define LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE 25 +#define LWAPP_MSGTYPE_RESET_REQUEST 26 +#define LWAPP_MSGTYPE_RESET_RESPONSE 27 +#define LWAPP_MSGTYPE_KEY_UPDATE_REQUEST 30 +#define LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE 31 +#define LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST 32 +#define LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE 33 +#define LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST 34 +#define LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE 35 +#define LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION 36 +#define LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST 37 +#define LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE 38 +#define LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST 39 +#define LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE 40 + +static const struct tok lwapp_msg_type_values[] = { + { LWAPP_MSGTYPE_DISCOVERY_REQUEST, "Discovery req"}, + { LWAPP_MSGTYPE_DISCOVERY_RESPONSE, "Discovery resp"}, + { LWAPP_MSGTYPE_JOIN_REQUEST, "Join req"}, + { LWAPP_MSGTYPE_JOIN_RESPONSE, "Join resp"}, + { LWAPP_MSGTYPE_JOIN_ACK, "Join ack"}, + { LWAPP_MSGTYPE_JOIN_CONFIRM, "Join confirm"}, + { LWAPP_MSGTYPE_CONFIGURE_REQUEST, "Configure req"}, + { LWAPP_MSGTYPE_CONFIGURE_RESPONSE, "Configure resp"}, + { LWAPP_MSGTYPE_CONF_UPDATE_REQUEST, "Update req"}, + { LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE, "Update resp"}, + { LWAPP_MSGTYPE_WTP_EVENT_REQUEST, "WTP event req"}, + { LWAPP_MSGTYPE_WTP_EVENT_RESPONSE, "WTP event resp"}, + { LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST, "Change state event req"}, + { LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE, "Change state event resp"}, + { LWAPP_MSGTYPE_ECHO_REQUEST, "Echo req"}, + { LWAPP_MSGTYPE_ECHO_RESPONSE, "Echo resp"}, + { LWAPP_MSGTYPE_IMAGE_DATA_REQUEST, "Image data req"}, + { LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE, "Image data resp"}, + { LWAPP_MSGTYPE_RESET_REQUEST, "Channel status req"}, + { LWAPP_MSGTYPE_RESET_RESPONSE, "Channel status resp"}, + { LWAPP_MSGTYPE_KEY_UPDATE_REQUEST, "Key update req"}, + { LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE, "Key update resp"}, + { LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST, "Primary discovery req"}, + { LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE, "Primary discovery resp"}, + { LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST, "Data transfer req"}, + { LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE, "Data transfer resp"}, + { LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION, "Clear config ind"}, + { LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST, "Wlan config req"}, + { LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE, "Wlan config resp"}, + { LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST, "Mobile config req"}, + { LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE, "Mobile config resp"}, + { 0, NULL} +}; + +/* + * LWAPP message elements + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Length | Value ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +struct lwapp_message_header { + u_int8_t type; + u_int8_t length[2]; +}; + +void +lwapp_control_print(const u_char *pptr, u_int len, int has_ap_ident) { + + const struct lwapp_transport_header *lwapp_trans_header; + const struct lwapp_control_header *lwapp_control_header; + const u_char *tptr; + int hexdump,tlen; + int msg_tlen; + + tptr=pptr; + + if (has_ap_ident) { + /* check if enough bytes for AP identity */ + if (!TTEST2(*tptr, 6)) + goto trunc; + lwapp_trans_header = (const struct lwapp_transport_header *)(pptr+6); + } else { + lwapp_trans_header = (const struct lwapp_transport_header *)pptr; + } + TCHECK(*lwapp_trans_header); + + /* + * Sanity checking of the header. + */ + if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) { + printf("LWAPP version %u packet not supported", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version)); + return; + } + + /* non-verbose */ + if (vflag < 1) { + printf("LWAPPv%u, %s frame, Flags [%s], length %u", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), + LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", + bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + tlen=EXTRACT_16BITS(lwapp_trans_header->length); + + printf("LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), + LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", + LWAPP_EXTRACT_RID(lwapp_trans_header->version), + bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), + lwapp_trans_header->frag_id, + tlen); + + if (has_ap_ident) { + printf("\n\tAP identity: %s", + etheraddr_string(tptr)); + tptr+=sizeof(const struct lwapp_transport_header)+6; + } else { + tptr+=sizeof(const struct lwapp_transport_header); + } + + while(tlen>0) { + + /* did we capture enough for fully decoding the object header ? */ + if (!TTEST2(*tptr, sizeof(struct lwapp_control_header))) + goto trunc; + + lwapp_control_header = (const struct lwapp_control_header *)tptr; + msg_tlen = EXTRACT_16BITS(lwapp_control_header->len); + + /* print message header */ + printf("\n\t Msg type: %s (%u), Seqnum: %u, Msg len: %d, Session: 0x%08x", + tok2str(lwapp_msg_type_values,"Unknown",lwapp_control_header->msg_type), + lwapp_control_header->msg_type, + lwapp_control_header->seq_num, + msg_tlen, + EXTRACT_32BITS(lwapp_control_header->session_id)); + + /* did we capture enough for fully decoding the message */ + if (!TTEST2(*tptr, msg_tlen)) + goto trunc; + hexdump=FALSE; + + /* XXX - Decode sub messages for each message */ + switch(lwapp_control_header->msg_type) { + case LWAPP_MSGTYPE_DISCOVERY_REQUEST: + case LWAPP_MSGTYPE_DISCOVERY_RESPONSE: + case LWAPP_MSGTYPE_JOIN_REQUEST: + case LWAPP_MSGTYPE_JOIN_RESPONSE: + case LWAPP_MSGTYPE_JOIN_ACK: + case LWAPP_MSGTYPE_JOIN_CONFIRM: + case LWAPP_MSGTYPE_CONFIGURE_REQUEST: + case LWAPP_MSGTYPE_CONFIGURE_RESPONSE: + case LWAPP_MSGTYPE_CONF_UPDATE_REQUEST: + case LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE: + case LWAPP_MSGTYPE_WTP_EVENT_REQUEST: + case LWAPP_MSGTYPE_WTP_EVENT_RESPONSE: + case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST: + case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE: + case LWAPP_MSGTYPE_ECHO_REQUEST: + case LWAPP_MSGTYPE_ECHO_RESPONSE: + case LWAPP_MSGTYPE_IMAGE_DATA_REQUEST: + case LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE: + case LWAPP_MSGTYPE_RESET_REQUEST: + case LWAPP_MSGTYPE_RESET_RESPONSE: + case LWAPP_MSGTYPE_KEY_UPDATE_REQUEST: + case LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE: + case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST: + case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE: + case LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST: + case LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE: + case LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION: + case LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST: + case LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE: + case LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST: + case LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE: + default: + break; + } + + tptr += sizeof(struct lwapp_control_header) + msg_tlen; + tlen -= sizeof(struct lwapp_control_header) + msg_tlen; + } + return; + + trunc: + printf("\n\t\t packet exceeded snapshot"); +} + +void +lwapp_data_print(const u_char *pptr, u_int len) { + + const struct lwapp_transport_header *lwapp_trans_header; + const u_char *tptr; + int tlen; + + tptr=pptr; + + /* check if enough bytes for AP identity */ + if (!TTEST2(*tptr, 6)) + goto trunc; + lwapp_trans_header = (const struct lwapp_transport_header *)pptr; + TCHECK(*lwapp_trans_header); + + /* + * Sanity checking of the header. + */ + if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) { + printf("LWAPP version %u packet not supported", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version)); + return; + } + + /* non-verbose */ + if (vflag < 1) { + printf("LWAPPv%u, %s frame, Flags [%s], length %u", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), + LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", + bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + tlen=EXTRACT_16BITS(lwapp_trans_header->length); + + printf("LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u", + LWAPP_EXTRACT_VERSION(lwapp_trans_header->version), + LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data", + LWAPP_EXTRACT_RID(lwapp_trans_header->version), + bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07), + lwapp_trans_header->frag_id, + tlen); + + tptr+=sizeof(const struct lwapp_transport_header); + tlen-=sizeof(const struct lwapp_transport_header); + + /* FIX - An IEEE 802.11 frame follows - hexdump for now */ + print_unknown_data(tptr, "\n\t", tlen); + + return; + + trunc: + printf("\n\t\t packet exceeded snapshot"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-lwres.c b/print-lwres.c new file mode 100644 index 0000000..aad4eee --- /dev/null +++ b/print-lwres.c @@ -0,0 +1,601 @@ +/* + * Copyright (C) 2001 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-lwres.c,v 1.13 2004-03-24 01:54:29 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "nameser.h" + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +/* BIND9 lib/lwres/include/lwres */ +typedef u_int32_t lwres_uint32_t; +typedef u_int16_t lwres_uint16_t; +typedef u_int8_t lwres_uint8_t; + +struct lwres_lwpacket { + lwres_uint32_t length; + lwres_uint16_t version; + lwres_uint16_t pktflags; + lwres_uint32_t serial; + lwres_uint32_t opcode; + lwres_uint32_t result; + lwres_uint32_t recvlength; + lwres_uint16_t authtype; + lwres_uint16_t authlength; +}; + +#define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */ + +#define LWRES_LWPACKETVERSION_0 0 + +#define LWRES_FLAG_TRUSTNOTREQUIRED 0x00000001U +#define LWRES_FLAG_SECUREDATA 0x00000002U + +/* + * no-op + */ +#define LWRES_OPCODE_NOOP 0x00000000U + +typedef struct { + /* public */ + lwres_uint16_t datalength; + /* data follows */ +} lwres_nooprequest_t; + +typedef struct { + /* public */ + lwres_uint16_t datalength; + /* data follows */ +} lwres_noopresponse_t; + +/* + * get addresses by name + */ +#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U + +typedef struct lwres_addr lwres_addr_t; + +struct lwres_addr { + lwres_uint32_t family; + lwres_uint16_t length; + /* address folows */ +}; + +typedef struct { + /* public */ + lwres_uint32_t flags; + lwres_uint32_t addrtypes; + lwres_uint16_t namelen; + /* name follows */ +} lwres_gabnrequest_t; + +typedef struct { + /* public */ + lwres_uint32_t flags; + lwres_uint16_t naliases; + lwres_uint16_t naddrs; + lwres_uint16_t realnamelen; + /* aliases follows */ + /* addrs follows */ + /* realname follows */ +} lwres_gabnresponse_t; + +/* + * get name by address + */ +#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U +typedef struct { + /* public */ + lwres_uint32_t flags; + lwres_addr_t addr; + /* addr body follows */ +} lwres_gnbarequest_t; + +typedef struct { + /* public */ + lwres_uint32_t flags; + lwres_uint16_t naliases; + lwres_uint16_t realnamelen; + /* aliases follows */ + /* realname follows */ +} lwres_gnbaresponse_t; + +/* + * get rdata by name + */ +#define LWRES_OPCODE_GETRDATABYNAME 0x00010003U + +typedef struct { + /* public */ + lwres_uint32_t flags; + lwres_uint16_t rdclass; + lwres_uint16_t rdtype; + lwres_uint16_t namelen; + /* name follows */ +} lwres_grbnrequest_t; + +typedef struct { + /* public */ + lwres_uint32_t flags; + lwres_uint16_t rdclass; + lwres_uint16_t rdtype; + lwres_uint32_t ttl; + lwres_uint16_t nrdatas; + lwres_uint16_t nsigs; + /* realname here (len + name) */ + /* rdata here (len + name) */ + /* signatures here (len + name) */ +} lwres_grbnresponse_t; + +#define LWRDATA_VALIDATED 0x00000001 + +#define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */ +#define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */ + +#define LWRES_MAX_ALIASES 16 /* max # of aliases */ +#define LWRES_MAX_ADDRS 64 /* max # of addrs */ + +struct tok opcode[] = { + { LWRES_OPCODE_NOOP, "noop", }, + { LWRES_OPCODE_GETADDRSBYNAME, "getaddrsbyname", }, + { LWRES_OPCODE_GETNAMEBYADDR, "getnamebyaddr", }, + { LWRES_OPCODE_GETRDATABYNAME, "getrdatabyname", }, + { 0, NULL, }, +}; + +/* print-domain.c */ +extern struct tok ns_type2str[]; +extern struct tok ns_class2str[]; + +static int lwres_printname(size_t, const char *); +static int lwres_printnamelen(const char *); +static int lwres_printbinlen(const char *); +static int lwres_printaddr(lwres_addr_t *); + +static int +lwres_printname(size_t l, const char *p0) +{ + const char *p; + size_t i; + + p = p0; + /* + 1 for terminating \0 */ + if (p + l + 1 > (const char *)snapend) + goto trunc; + + printf(" "); + for (i = 0; i < l; i++) + safeputchar(*p++); + p++; /* skip terminating \0 */ + + return p - p0; + + trunc: + return -1; +} + +static int +lwres_printnamelen(const char *p) +{ + u_int16_t l; + int advance; + + if (p + 2 > (const char *)snapend) + goto trunc; + l = EXTRACT_16BITS(p); + advance = lwres_printname(l, p + 2); + if (advance < 0) + goto trunc; + return 2 + advance; + + trunc: + return -1; +} + +static int +lwres_printbinlen(const char *p0) +{ + const char *p; + u_int16_t l; + int i; + + p = p0; + if (p + 2 > (const char *)snapend) + goto trunc; + l = EXTRACT_16BITS(p); + if (p + 2 + l > (const char *)snapend) + goto trunc; + p += 2; + for (i = 0; i < l; i++) + printf("%02x", *p++); + return p - p0; + + trunc: + return -1; +} + +static int +lwres_printaddr(lwres_addr_t *ap) +{ + u_int16_t l; + const char *p; + int i; + + TCHECK(ap->length); + l = EXTRACT_16BITS(&ap->length); + /* XXX ap points to packed struct */ + p = (const char *)&ap->length + sizeof(ap->length); + TCHECK2(*p, l); + + switch (EXTRACT_32BITS(&ap->family)) { + case 1: /* IPv4 */ + if (l < 4) + return -1; + printf(" %s", ipaddr_string(p)); + p += sizeof(struct in_addr); + break; +#ifdef INET6 + case 2: /* IPv6 */ + if (l < 16) + return -1; + printf(" %s", ip6addr_string(p)); + p += sizeof(struct in6_addr); + break; +#endif + default: + printf(" %u/", EXTRACT_32BITS(&ap->family)); + for (i = 0; i < l; i++) + printf("%02x", *p++); + } + + return p - (const char *)ap; + + trunc: + return -1; +} + +void +lwres_print(register const u_char *bp, u_int length) +{ + const struct lwres_lwpacket *np; + u_int32_t v; + const char *s; + int response; + int advance; + int unsupported = 0; + + np = (const struct lwres_lwpacket *)bp; + TCHECK(np->authlength); + + printf(" lwres"); + v = EXTRACT_16BITS(&np->version); + if (vflag || v != LWRES_LWPACKETVERSION_0) + printf(" v%u", v); + if (v != LWRES_LWPACKETVERSION_0) { + s = (const char *)np + EXTRACT_32BITS(&np->length); + goto tail; + } + + response = EXTRACT_16BITS(&np->pktflags) & LWRES_LWPACKETFLAG_RESPONSE; + + /* opcode and pktflags */ + v = EXTRACT_32BITS(&np->opcode); + s = tok2str(opcode, "#0x%x", v); + printf(" %s%s", s, response ? "" : "?"); + + /* pktflags */ + v = EXTRACT_16BITS(&np->pktflags); + if (v & ~LWRES_LWPACKETFLAG_RESPONSE) + printf("[0x%x]", v); + + if (vflag > 1) { + printf(" ("); /*)*/ + printf("serial:0x%x", EXTRACT_32BITS(&np->serial)); + printf(" result:0x%x", EXTRACT_32BITS(&np->result)); + printf(" recvlen:%u", EXTRACT_32BITS(&np->recvlength)); + /* BIND910: not used */ + if (vflag > 2) { + printf(" authtype:0x%x", EXTRACT_16BITS(&np->authtype)); + printf(" authlen:%u", EXTRACT_16BITS(&np->authlength)); + } + /*(*/ + printf(")"); + } + + /* per-opcode content */ + if (!response) { + /* + * queries + */ + lwres_gabnrequest_t *gabn; + lwres_gnbarequest_t *gnba; + lwres_grbnrequest_t *grbn; + u_int32_t l; + + gabn = NULL; + gnba = NULL; + grbn = NULL; + + switch (EXTRACT_32BITS(&np->opcode)) { + case LWRES_OPCODE_NOOP: + break; + case LWRES_OPCODE_GETADDRSBYNAME: + gabn = (lwres_gabnrequest_t *)(np + 1); + TCHECK(gabn->namelen); + /* XXX gabn points to packed struct */ + s = (const char *)&gabn->namelen + + sizeof(gabn->namelen); + l = EXTRACT_16BITS(&gabn->namelen); + + /* BIND910: not used */ + if (vflag > 2) { + printf(" flags:0x%x", + EXTRACT_32BITS(&gabn->flags)); + } + + v = EXTRACT_32BITS(&gabn->addrtypes); + switch (v & (LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) { + case LWRES_ADDRTYPE_V4: + printf(" IPv4"); + break; + case LWRES_ADDRTYPE_V6: + printf(" IPv6"); + break; + case LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6: + printf(" IPv4/6"); + break; + } + if (v & ~(LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) + printf("[0x%x]", v); + + advance = lwres_printname(l, s); + if (advance < 0) + goto trunc; + s += advance; + break; + case LWRES_OPCODE_GETNAMEBYADDR: + gnba = (lwres_gnbarequest_t *)(np + 1); + TCHECK(gnba->addr); + + /* BIND910: not used */ + if (vflag > 2) { + printf(" flags:0x%x", + EXTRACT_32BITS(&gnba->flags)); + } + + s = (const char *)&gnba->addr; + + advance = lwres_printaddr(&gnba->addr); + if (advance < 0) + goto trunc; + s += advance; + break; + case LWRES_OPCODE_GETRDATABYNAME: + /* XXX no trace, not tested */ + grbn = (lwres_grbnrequest_t *)(np + 1); + TCHECK(grbn->namelen); + + /* BIND910: not used */ + if (vflag > 2) { + printf(" flags:0x%x", + EXTRACT_32BITS(&grbn->flags)); + } + + printf(" %s", tok2str(ns_type2str, "Type%d", + EXTRACT_16BITS(&grbn->rdtype))); + if (EXTRACT_16BITS(&grbn->rdclass) != C_IN) { + printf(" %s", tok2str(ns_class2str, "Class%d", + EXTRACT_16BITS(&grbn->rdclass))); + } + + /* XXX grbn points to packed struct */ + s = (const char *)&grbn->namelen + + sizeof(grbn->namelen); + l = EXTRACT_16BITS(&grbn->namelen); + + advance = lwres_printname(l, s); + if (advance < 0) + goto trunc; + s += advance; + break; + default: + unsupported++; + break; + } + } else { + /* + * responses + */ + lwres_gabnresponse_t *gabn; + lwres_gnbaresponse_t *gnba; + lwres_grbnresponse_t *grbn; + u_int32_t l, na; + u_int32_t i; + + gabn = NULL; + gnba = NULL; + grbn = NULL; + + switch (EXTRACT_32BITS(&np->opcode)) { + case LWRES_OPCODE_NOOP: + break; + case LWRES_OPCODE_GETADDRSBYNAME: + gabn = (lwres_gabnresponse_t *)(np + 1); + TCHECK(gabn->realnamelen); + /* XXX gabn points to packed struct */ + s = (const char *)&gabn->realnamelen + + sizeof(gabn->realnamelen); + l = EXTRACT_16BITS(&gabn->realnamelen); + + /* BIND910: not used */ + if (vflag > 2) { + printf(" flags:0x%x", + EXTRACT_32BITS(&gabn->flags)); + } + + printf(" %u/%u", EXTRACT_16BITS(&gabn->naliases), + EXTRACT_16BITS(&gabn->naddrs)); + + advance = lwres_printname(l, s); + if (advance < 0) + goto trunc; + s += advance; + + /* aliases */ + na = EXTRACT_16BITS(&gabn->naliases); + for (i = 0; i < na; i++) { + advance = lwres_printnamelen(s); + if (advance < 0) + goto trunc; + s += advance; + } + + /* addrs */ + na = EXTRACT_16BITS(&gabn->naddrs); + for (i = 0; i < na; i++) { + advance = lwres_printaddr((lwres_addr_t *)s); + if (advance < 0) + goto trunc; + s += advance; + } + break; + case LWRES_OPCODE_GETNAMEBYADDR: + gnba = (lwres_gnbaresponse_t *)(np + 1); + TCHECK(gnba->realnamelen); + /* XXX gnba points to packed struct */ + s = (const char *)&gnba->realnamelen + + sizeof(gnba->realnamelen); + l = EXTRACT_16BITS(&gnba->realnamelen); + + /* BIND910: not used */ + if (vflag > 2) { + printf(" flags:0x%x", + EXTRACT_32BITS(&gnba->flags)); + } + + printf(" %u", EXTRACT_16BITS(&gnba->naliases)); + + advance = lwres_printname(l, s); + if (advance < 0) + goto trunc; + s += advance; + + /* aliases */ + na = EXTRACT_16BITS(&gnba->naliases); + for (i = 0; i < na; i++) { + advance = lwres_printnamelen(s); + if (advance < 0) + goto trunc; + s += advance; + } + break; + case LWRES_OPCODE_GETRDATABYNAME: + /* XXX no trace, not tested */ + grbn = (lwres_grbnresponse_t *)(np + 1); + TCHECK(grbn->nsigs); + + /* BIND910: not used */ + if (vflag > 2) { + printf(" flags:0x%x", + EXTRACT_32BITS(&grbn->flags)); + } + + printf(" %s", tok2str(ns_type2str, "Type%d", + EXTRACT_16BITS(&grbn->rdtype))); + if (EXTRACT_16BITS(&grbn->rdclass) != C_IN) { + printf(" %s", tok2str(ns_class2str, "Class%d", + EXTRACT_16BITS(&grbn->rdclass))); + } + printf(" TTL "); + relts_print(EXTRACT_32BITS(&grbn->ttl)); + printf(" %u/%u", EXTRACT_16BITS(&grbn->nrdatas), + EXTRACT_16BITS(&grbn->nsigs)); + + /* XXX grbn points to packed struct */ + s = (const char *)&grbn->nsigs+ sizeof(grbn->nsigs); + + advance = lwres_printnamelen(s); + if (advance < 0) + goto trunc; + s += advance; + + /* rdatas */ + na = EXTRACT_16BITS(&grbn->nrdatas); + for (i = 0; i < na; i++) { + /* XXX should decode resource data */ + advance = lwres_printbinlen(s); + if (advance < 0) + goto trunc; + s += advance; + } + + /* sigs */ + na = EXTRACT_16BITS(&grbn->nsigs); + for (i = 0; i < na; i++) { + /* XXX how should we print it? */ + advance = lwres_printbinlen(s); + if (advance < 0) + goto trunc; + s += advance; + } + break; + default: + unsupported++; + break; + } + } + + tail: + /* length mismatch */ + if (EXTRACT_32BITS(&np->length) != length) { + printf(" [len: %u != %u]", EXTRACT_32BITS(&np->length), + length); + } + if (!unsupported && s < (const char *)np + EXTRACT_32BITS(&np->length)) + printf("[extra]"); + return; + + trunc: + printf("[|lwres]"); + return; +} diff --git a/print-mobile.c b/print-mobile.c new file mode 100644 index 0000000..816ffd6 --- /dev/null +++ b/print-mobile.c @@ -0,0 +1,109 @@ +/* $NetBSD: print-mobile.c,v 1.2 1998/09/30 08:57:01 hwr Exp $ */ + +/* + * (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Heiko W.Rupp + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-mobile.c,v 1.15 2004-03-24 01:58:14 guy Exp $"; +#endif + +#include + +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +#define MOBILE_SIZE (8) + +struct mobile_ip { + u_int16_t proto; + u_int16_t hcheck; + u_int32_t odst; + u_int32_t osrc; +}; + +#define OSRC_PRES 0x0080 /* old source is present */ + +/* + * Deencapsulate and print a mobile-tunneled IP datagram + */ +void +mobile_print(const u_char *bp, u_int length) +{ + const u_char *cp = bp +8 ; + const struct mobile_ip *mob; + u_short proto,crc; + u_char osp =0; /* old source address present */ + + mob = (const struct mobile_ip *)bp; + + if (length < MOBILE_SIZE || !TTEST(*mob)) { + fputs("[|mobile]", stdout); + return; + } + fputs("mobile: ", stdout); + + proto = EXTRACT_16BITS(&mob->proto); + crc = EXTRACT_16BITS(&mob->hcheck); + if (proto & OSRC_PRES) { + osp=1; + cp +=4 ; + } + + if (osp) { + fputs("[S] ",stdout); + if (vflag) + (void)printf("%s ",ipaddr_string(&mob->osrc)); + } else { + fputs("[] ",stdout); + } + if (vflag) { + (void)printf("> %s ",ipaddr_string(&mob->odst)); + (void)printf("(oproto=%d)",proto>>8); + } + if (in_cksum((u_short *)mob, osp ? 12 : 8, 0)!=0) { + (void)printf(" (bad checksum %d)",crc); + } + + return; +} diff --git a/print-mobility.c b/print-mobility.c new file mode 100644 index 0000000..1490b72 --- /dev/null +++ b/print-mobility.c @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2002 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-mobility.c,v 1.12 2005-04-20 22:21:00 guy Exp $"; +#endif + +#ifdef INET6 +#include + +#include + +#include "ip6.h" + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +/* Mobility header */ +struct ip6_mobility { + u_int8_t ip6m_pproto; /* following payload protocol (for PG) */ + u_int8_t ip6m_len; /* length in units of 8 octets */ + u_int8_t ip6m_type; /* message type */ + u_int8_t reserved; /* reserved */ + u_int16_t ip6m_cksum; /* sum of IPv6 pseudo-header and MH */ + union { + u_int16_t ip6m_un_data16[1]; /* type-specific field */ + u_int8_t ip6m_un_data8[2]; /* type-specific fiedl */ + } ip6m_dataun; +}; + +#define ip6m_data16 ip6m_dataun.ip6m_un_data16 +#define ip6m_data8 ip6m_dataun.ip6m_un_data8 + +#define IP6M_MINLEN 8 + +/* message type */ +#define IP6M_BINDING_REQUEST 0 /* Binding Refresh Request */ +#define IP6M_HOME_TEST_INIT 1 /* Home Test Init */ +#define IP6M_CAREOF_TEST_INIT 2 /* Care-of Test Init */ +#define IP6M_HOME_TEST 3 /* Home Test */ +#define IP6M_CAREOF_TEST 4 /* Care-of Test */ +#define IP6M_BINDING_UPDATE 5 /* Binding Update */ +#define IP6M_BINDING_ACK 6 /* Binding Acknowledgement */ +#define IP6M_BINDING_ERROR 7 /* Binding Error */ + +/* Mobility Header Options */ +#define IP6MOPT_MINLEN 2 +#define IP6MOPT_PAD1 0x0 /* Pad1 */ +#define IP6MOPT_PADN 0x1 /* PadN */ +#define IP6MOPT_REFRESH 0x2 /* Binding Refresh Advice */ +#define IP6MOPT_REFRESH_MINLEN 4 +#define IP6MOPT_ALTCOA 0x3 /* Alternate Care-of Address */ +#define IP6MOPT_ALTCOA_MINLEN 18 +#define IP6MOPT_NONCEID 0x4 /* Nonce Indices */ +#define IP6MOPT_NONCEID_MINLEN 6 +#define IP6MOPT_AUTH 0x5 /* Binding Authorization Data */ +#define IP6MOPT_AUTH_MINLEN 12 + +static void +mobility_opt_print(const u_char *bp, int len) +{ + int i; + int optlen; + + for (i = 0; i < len; i += optlen) { + if (bp[i] == IP6MOPT_PAD1) + optlen = 1; + else { + if (i + 1 < len) + optlen = bp[i + 1] + 2; + else + goto trunc; + } + if (i + optlen > len) + goto trunc; + + switch (bp[i]) { + case IP6MOPT_PAD1: + printf("(pad1)"); + break; + case IP6MOPT_PADN: + if (len - i < IP6MOPT_MINLEN) { + printf("(padn: trunc)"); + goto trunc; + } + printf("(padn)"); + break; + case IP6MOPT_REFRESH: + if (len - i < IP6MOPT_REFRESH_MINLEN) { + printf("(refresh: trunc)"); + goto trunc; + } + /* units of 4 secs */ + printf("(refresh: %d)", + EXTRACT_16BITS(&bp[i+2]) << 2); + break; + case IP6MOPT_ALTCOA: + if (len - i < IP6MOPT_ALTCOA_MINLEN) { + printf("(altcoa: trunc)"); + goto trunc; + } + printf("(alt-CoA: %s)", ip6addr_string(&bp[i+2])); + break; + case IP6MOPT_NONCEID: + if (len - i < IP6MOPT_NONCEID_MINLEN) { + printf("(ni: trunc)"); + goto trunc; + } + printf("(ni: ho=0x%04x co=0x%04x)", + EXTRACT_16BITS(&bp[i+2]), + EXTRACT_16BITS(&bp[i+4])); + break; + case IP6MOPT_AUTH: + if (len - i < IP6MOPT_AUTH_MINLEN) { + printf("(auth: trunc)"); + goto trunc; + } + printf("(auth)"); + break; + default: + if (len - i < IP6MOPT_MINLEN) { + printf("(sopt_type %d: trunc)", bp[i]); + goto trunc; + } + printf("(type-0x%02x: len=%d)", bp[i], bp[i + 1]); + break; + } + } + return; + +trunc: + printf("[trunc] "); +} + +/* + * Mobility Header + */ +int +mobility_print(const u_char *bp, const u_char *bp2 _U_) +{ + const struct ip6_mobility *mh; + const u_char *ep; + int mhlen, hlen, type; + + mh = (struct ip6_mobility *)bp; + + /* 'ep' points to the end of available data. */ + ep = snapend; + + if (!TTEST(mh->ip6m_len)) { + /* + * There's not enough captured data to include the + * mobility header length. + * + * Our caller expects us to return the length, however, + * so return a value that will run to the end of the + * captured data. + * + * XXX - "ip6_print()" doesn't do anything with the + * returned length, however, as it breaks out of the + * header-processing loop. + */ + mhlen = ep - bp; + goto trunc; + } + mhlen = (int)((mh->ip6m_len + 1) << 3); + + /* XXX ip6m_cksum */ + + TCHECK(mh->ip6m_type); + type = mh->ip6m_type; + switch (type) { + case IP6M_BINDING_REQUEST: + printf("mobility: BRR"); + hlen = IP6M_MINLEN; + break; + case IP6M_HOME_TEST_INIT: + case IP6M_CAREOF_TEST_INIT: + printf("mobility: %soTI", + type == IP6M_HOME_TEST_INIT ? "H" : "C"); + hlen = IP6M_MINLEN; + if (vflag) { + TCHECK2(*mh, hlen + 8); + printf(" %s Init Cookie=%08x:%08x", + type == IP6M_HOME_TEST_INIT ? "Home" : "Care-of", + EXTRACT_32BITS(&bp[hlen]), + EXTRACT_32BITS(&bp[hlen + 4])); + } + hlen += 8; + break; + case IP6M_HOME_TEST: + case IP6M_CAREOF_TEST: + printf("mobility: %soT", + type == IP6M_HOME_TEST ? "H" : "C"); + TCHECK(mh->ip6m_data16[0]); + printf(" nonce id=0x%x", EXTRACT_16BITS(&mh->ip6m_data16[0])); + hlen = IP6M_MINLEN; + if (vflag) { + TCHECK2(*mh, hlen + 8); + printf(" %s Init Cookie=%08x:%08x", + type == IP6M_HOME_TEST ? "Home" : "Care-of", + EXTRACT_32BITS(&bp[hlen]), + EXTRACT_32BITS(&bp[hlen + 4])); + } + hlen += 8; + if (vflag) { + TCHECK2(*mh, hlen + 8); + printf(" %s Keygen Token=%08x:%08x", + type == IP6M_HOME_TEST ? "Home" : "Care-of", + EXTRACT_32BITS(&bp[hlen]), + EXTRACT_32BITS(&bp[hlen + 4])); + } + hlen += 8; + break; + case IP6M_BINDING_UPDATE: + printf("mobility: BU"); + TCHECK(mh->ip6m_data16[0]); + printf(" seq#=%d", EXTRACT_16BITS(&mh->ip6m_data16[0])); + hlen = IP6M_MINLEN; + TCHECK2(*mh, hlen + 1); + if (bp[hlen] & 0xf0) + printf(" "); + if (bp[hlen] & 0x80) + printf("A"); + if (bp[hlen] & 0x40) + printf("H"); + if (bp[hlen] & 0x20) + printf("L"); + if (bp[hlen] & 0x10) + printf("K"); + /* Reserved (4bits) */ + hlen += 1; + /* Reserved (8bits) */ + hlen += 1; + TCHECK2(*mh, hlen + 2); + /* units of 4 secs */ + printf(" lifetime=%d", EXTRACT_16BITS(&bp[hlen]) << 2); + hlen += 2; + break; + case IP6M_BINDING_ACK: + printf("mobility: BA"); + TCHECK(mh->ip6m_data8[0]); + printf(" status=%d", mh->ip6m_data8[0]); + if (mh->ip6m_data8[1] & 0x80) + printf(" K"); + /* Reserved (7bits) */ + hlen = IP6M_MINLEN; + TCHECK2(*mh, hlen + 2); + printf(" seq#=%d", EXTRACT_16BITS(&bp[hlen])); + hlen += 2; + TCHECK2(*mh, hlen + 2); + /* units of 4 secs */ + printf(" lifetime=%d", EXTRACT_16BITS(&bp[hlen]) << 2); + hlen += 2; + break; + case IP6M_BINDING_ERROR: + printf("mobility: BE"); + TCHECK(mh->ip6m_data8[0]); + printf(" status=%d", mh->ip6m_data8[0]); + /* Reserved */ + hlen = IP6M_MINLEN; + TCHECK2(*mh, hlen + 16); + printf(" homeaddr %s", ip6addr_string(&bp[hlen])); + hlen += 16; + break; + default: + printf("mobility: type-#%d len=%d", type, mh->ip6m_len); + return(mhlen); + break; + } + if (vflag) + mobility_opt_print(&bp[hlen], mhlen - hlen); + + return(mhlen); + + trunc: + fputs("[|MOBILITY]", stdout); + return(mhlen); +} +#endif /* INET6 */ diff --git a/print-mpcp.c b/print-mpcp.c new file mode 100644 index 0000000..244f280 --- /dev/null +++ b/print-mpcp.c @@ -0,0 +1,274 @@ +/* + * Copyright (c) 1998-2006 The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * support for the IEEE MPCP protocol as per 802.3ah + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-mpcp.c,v 1.2 2006-02-10 17:24:55 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ether.h" + +#define MPCP_TIMESTAMP_LEN 4 +#define MPCP_TIMESTAMP_DURATION_LEN 2 + +struct mpcp_common_header_t { + u_int8_t opcode[2]; + u_int8_t timestamp[MPCP_TIMESTAMP_LEN]; +}; + +#define MPCP_OPCODE_PAUSE 0x0001 +#define MPCP_OPCODE_GATE 0x0002 +#define MPCP_OPCODE_REPORT 0x0003 +#define MPCP_OPCODE_REG_REQ 0x0004 +#define MPCP_OPCODE_REG 0x0005 +#define MPCP_OPCODE_REG_ACK 0x0006 + +static const struct tok mpcp_opcode_values[] = { + { MPCP_OPCODE_PAUSE, "Pause" }, + { MPCP_OPCODE_GATE, "Gate" }, + { MPCP_OPCODE_REPORT, "Report" }, + { MPCP_OPCODE_REG_REQ, "Register Request" }, + { MPCP_OPCODE_REG, "Register" }, + { MPCP_OPCODE_REG_ACK, "Register ACK" }, + { 0, NULL} +}; + +#define MPCP_GRANT_NUMBER_LEN 1 +#define MPCP_GRANT_NUMBER_MASK 0x7 +static const struct tok mpcp_grant_flag_values[] = { + { 0x08, "Discovery" }, + { 0x10, "Force Grant #1" }, + { 0x20, "Force Grant #2" }, + { 0x40, "Force Grant #3" }, + { 0x80, "Force Grant #4" }, + { 0, NULL} +}; + +struct mpcp_grant_t { + u_int8_t starttime[MPCP_TIMESTAMP_LEN]; + u_int8_t duration[MPCP_TIMESTAMP_DURATION_LEN]; +}; + +struct mpcp_reg_req_t { + u_int8_t flags; + u_int8_t pending_grants; +}; + + +static const struct tok mpcp_reg_req_flag_values[] = { + { 1, "Register" }, + { 3, "De-Register" }, + { 0, NULL} +}; + +struct mpcp_reg_t { + u_int8_t assigned_port[2]; + u_int8_t flags; + u_int8_t sync_time[MPCP_TIMESTAMP_DURATION_LEN]; + u_int8_t echoed_pending_grants; +}; + +static const struct tok mpcp_reg_flag_values[] = { + { 1, "Re-Register" }, + { 2, "De-Register" }, + { 3, "ACK" }, + { 4, "NACK" }, + { 0, NULL} +}; + +#define MPCP_REPORT_QUEUESETS_LEN 1 +#define MPCP_REPORT_REPORTBITMAP_LEN 1 +static const struct tok mpcp_report_bitmap_values[] = { + { 0x01, "Q0" }, + { 0x02, "Q1" }, + { 0x04, "Q2" }, + { 0x08, "Q3" }, + { 0x10, "Q4" }, + { 0x20, "Q5" }, + { 0x40, "Q6" }, + { 0x80, "Q7" }, + { 0, NULL} +}; + +struct mpcp_reg_ack_t { + u_int8_t flags; + u_int8_t echoed_assigned_port[2]; + u_int8_t echoed_sync_time[MPCP_TIMESTAMP_DURATION_LEN]; +}; + +static const struct tok mpcp_reg_ack_flag_values[] = { + { 0, "NACK" }, + { 1, "ACK" }, + { 0, NULL} +}; + +void +mpcp_print(register const u_char *pptr, register u_int length) { + + union { + const struct mpcp_common_header_t *common_header; + const struct mpcp_grant_t *grant; + const struct mpcp_reg_req_t *reg_req; + const struct mpcp_reg_t *reg; + const struct mpcp_reg_ack_t *reg_ack; + } mpcp; + + + const u_char *tptr; + u_int16_t opcode; + u_int8_t grant_numbers, grant; + u_int8_t queue_sets, queue_set, report_bitmap, report; + + tptr=pptr; + mpcp.common_header = (const struct mpcp_common_header_t *)pptr; + + if (!TTEST2(*tptr, sizeof(const struct mpcp_common_header_t))) + goto trunc; + opcode = EXTRACT_16BITS(mpcp.common_header->opcode); + printf("MPCP, Opcode %s", tok2str(mpcp_opcode_values, "Unknown (%u)", opcode)); + if (opcode != MPCP_OPCODE_PAUSE) { + printf(", Timestamp %u ticks", EXTRACT_32BITS(mpcp.common_header->timestamp)); + } + printf(", length %u", length); + + if (!vflag) + return; + + tptr += sizeof(const struct mpcp_common_header_t); + + switch (opcode) { + case MPCP_OPCODE_PAUSE: + break; + + case MPCP_OPCODE_GATE: + if (!TTEST2(*tptr, MPCP_GRANT_NUMBER_LEN)) + goto trunc; + grant_numbers = *tptr & MPCP_GRANT_NUMBER_MASK; + printf("\n\tGrant Numbers %u, Flags [ %s ]", + grant_numbers, + bittok2str(mpcp_grant_flag_values, + "?", + *tptr &~ MPCP_GRANT_NUMBER_MASK)); + tptr++; + + for (grant = 1; grant <= grant_numbers; grant++) { + if (!TTEST2(*tptr, sizeof(const struct mpcp_grant_t))) + goto trunc; + mpcp.grant = (const struct mpcp_grant_t *)tptr; + printf("\n\tGrant #%u, Start-Time %u ticks, duration %u ticks", + grant, + EXTRACT_32BITS(mpcp.grant->starttime), + EXTRACT_16BITS(mpcp.grant->duration)); + tptr += sizeof(const struct mpcp_grant_t); + } + + if (!TTEST2(*tptr, MPCP_TIMESTAMP_DURATION_LEN)) + goto trunc; + printf("\n\tSync-Time %u ticks", EXTRACT_16BITS(tptr)); + break; + + + case MPCP_OPCODE_REPORT: + if (!TTEST2(*tptr, MPCP_REPORT_QUEUESETS_LEN)) + goto trunc; + queue_sets = *tptr; + tptr+=MPCP_REPORT_QUEUESETS_LEN; + printf("\n\tTotal Queue-Sets %u", queue_sets); + + for (queue_set = 1; queue_set < queue_sets; queue_set++) { + if (!TTEST2(*tptr, MPCP_REPORT_REPORTBITMAP_LEN)) + goto trunc; + report_bitmap = *(tptr); + printf("\n\t Queue-Set #%u, Report-Bitmap [ %s ]", + queue_sets, + bittok2str(mpcp_report_bitmap_values, "Unknown", report_bitmap)); + tptr++; + + report=1; + while (report_bitmap != 0) { + if (report_bitmap & 1) { + if (!TTEST2(*tptr, MPCP_TIMESTAMP_DURATION_LEN)) + goto trunc; + printf("\n\t Q%u Report, Duration %u ticks", + report, + EXTRACT_16BITS(tptr)); + tptr+=MPCP_TIMESTAMP_DURATION_LEN; + } + report++; + report_bitmap = report_bitmap >> 1; + } + } + break; + + case MPCP_OPCODE_REG_REQ: + if (!TTEST2(*tptr, sizeof(const struct mpcp_reg_req_t))) + goto trunc; + mpcp.reg_req = (const struct mpcp_reg_req_t *)tptr; + printf("\n\tFlags [ %s ], Pending-Grants %u", + bittok2str(mpcp_reg_req_flag_values, "Reserved", mpcp.reg_req->flags), + mpcp.reg_req->pending_grants); + break; + + case MPCP_OPCODE_REG: + if (!TTEST2(*tptr, sizeof(const struct mpcp_reg_t))) + goto trunc; + mpcp.reg = (const struct mpcp_reg_t *)tptr; + printf("\n\tAssigned-Port %u, Flags [ %s ]" \ + "\n\tSync-Time %u ticks, Echoed-Pending-Grants %u", + EXTRACT_16BITS(mpcp.reg->assigned_port), + bittok2str(mpcp_reg_flag_values, "Reserved", mpcp.reg->flags), + EXTRACT_16BITS(mpcp.reg->sync_time), + mpcp.reg->echoed_pending_grants); + break; + + case MPCP_OPCODE_REG_ACK: + if (!TTEST2(*tptr, sizeof(const struct mpcp_reg_ack_t))) + goto trunc; + mpcp.reg_ack = (const struct mpcp_reg_ack_t *)tptr; + printf("\n\tEchoed-Assigned-Port %u, Flags [ %s ]" \ + "\n\tEchoed-Sync-Time %u ticks", + EXTRACT_16BITS(mpcp.reg_ack->echoed_assigned_port), + bittok2str(mpcp_reg_ack_flag_values, "Reserved", mpcp.reg_ack->flags), + EXTRACT_16BITS(mpcp.reg_ack->echoed_sync_time)); + break; + + default: + /* unknown opcode - hexdump for now */ + print_unknown_data(pptr, "\n\t", length); + break; + } + + return; + +trunc: + printf("\n\t[|MPCP]"); +} diff --git a/print-mpls.c b/print-mpls.c new file mode 100644 index 0000000..c6b0814 --- /dev/null +++ b/print-mpls.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2001 WIDE Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-mpls.c,v 1.14 2005-07-05 09:38:19 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "addrtoname.h" +#include "interface.h" +#include "extract.h" /* must come after interface.h */ +#include "mpls.h" + +static const char *mpls_labelname[] = { +/*0*/ "IPv4 explicit NULL", "router alert", "IPv6 explicit NULL", + "implicit NULL", "rsvd", +/*5*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd", +/*10*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd", +/*15*/ "rsvd", +}; + +/* + * RFC3032: MPLS label stack encoding + */ +void +mpls_print(const u_char *bp, u_int length) +{ + const u_char *p; + u_int32_t label_entry; + u_int16_t label_stack_depth = 0; + + p = bp; + printf("MPLS"); + do { + TCHECK2(*p, sizeof(label_entry)); + label_entry = EXTRACT_32BITS(p); + printf("%s(label %u", + label_stack_depth ? "\n\t" : " ", + MPLS_LABEL(label_entry)); + label_stack_depth++; + if (vflag && + MPLS_LABEL(label_entry) < sizeof(mpls_labelname) / sizeof(mpls_labelname[0])) + printf(" (%s)", mpls_labelname[MPLS_LABEL(label_entry)]); + printf(", exp %u", MPLS_EXP(label_entry)); + if (MPLS_STACK(label_entry)) + printf(", [S]"); + printf(", ttl %u)", MPLS_TTL(label_entry)); + + p += sizeof(label_entry); + } while (!MPLS_STACK(label_entry)); + + switch (MPLS_LABEL(label_entry)) { + case 0: /* IPv4 explicit NULL label */ + case 3: /* IPv4 implicit NULL label */ + if (vflag>0) { + printf("\n\t"); + ip_print(gndo, p, length - (p - bp)); + } + else printf(", IP, length: %u",length); + break; +#ifdef INET6 + case 2: /* IPv6 explicit NULL label */ + if (vflag>0) { + printf("\n\t"); + ip6_print(p, length - (p - bp)); + } + else printf(", IPv6, length: %u",length); + break; +#endif + default: + /* + * Generally there's no indication of protocol in MPLS label + * encoding, however draft-hsmit-isis-aal5mux-00.txt describes + * a technique that looks at the first payload byte if the BOS (bottom of stack) + * bit is set and tries to determine the network layer protocol + * 0x45-0x4f is IPv4 + * 0x60-0x6f is IPv6 + * 0x81-0x83 is OSI (CLNP,ES-IS,IS-IS) + * this technique is sometimes known as NULL encapsulation + * and decoding is particularly useful for control-plane traffic [BGP] + * which cisco by default sends MPLS encapsulated + */ + + if (MPLS_STACK(label_entry)) { /* only do this if the stack bit is set */ + switch(*p) { + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + if (vflag>0) { + printf("\n\t"); + ip_print(gndo, p, length - (p - bp)); + } + else printf(", IP, length: %u",length); + break; +#ifdef INET6 + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + if (vflag>0) { + printf("\n\t"); + ip6_print(p, length - (p - bp)); + } + else printf(", IPv6, length: %u",length); + break; +#endif + case 0x81: + case 0x82: + case 0x83: + if (vflag>0) { + printf("\n\t"); + isoclns_print(p, length - (p - bp), length - (p - bp)); + } + else printf(", OSI, length: %u",length); + break; + default: + /* ok bail out - we did not figure out what it is*/ + break; + } + } + return; + } + +trunc: + printf("[|MPLS]"); +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-msdp.c b/print-msdp.c new file mode 100644 index 0000000..a228ab7 --- /dev/null +++ b/print-msdp.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2001 William C. Fenner. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * The name of William C. Fenner may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-msdp.c,v 1.7 2005-04-06 21:32:41 mcr Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#define MSDP_TYPE_MAX 7 + +void +msdp_print(const unsigned char *sp, u_int length) +{ + unsigned int type, len; + + TCHECK2(*sp, 3); + /* See if we think we're at the beginning of a compound packet */ + type = *sp; + len = EXTRACT_16BITS(sp + 1); + if (len > 1500 || len < 3 || type == 0 || type > MSDP_TYPE_MAX) + goto trunc; /* not really truncated, but still not decodable */ + (void)printf(" msdp:"); + while (length > 0) { + TCHECK2(*sp, 3); + type = *sp; + len = EXTRACT_16BITS(sp + 1); + if (len > 1400 || vflag) + printf(" [len %u]", len); + if (len < 3) + goto trunc; + sp += 3; + length -= 3; + switch (type) { + case 1: /* IPv4 Source-Active */ + case 3: /* IPv4 Source-Active Response */ + if (type == 1) + (void)printf(" SA"); + else + (void)printf(" SA-Response"); + TCHECK(*sp); + (void)printf(" %u entries", *sp); + if ((u_int)((*sp * 12) + 8) < len) { + (void)printf(" [w/data]"); + if (vflag > 1) { + (void)printf(" "); + ip_print(gndo, sp + *sp * 12 + 8 - 3, + len - (*sp * 12 + 8)); + } + } + break; + case 2: + (void)printf(" SA-Request"); + TCHECK2(*sp, 5); + (void)printf(" for %s", ipaddr_string(sp + 1)); + break; + case 4: + (void)printf(" Keepalive"); + if (len != 3) + (void)printf("[len=%d] ", len); + break; + case 5: + (void)printf(" Notification"); + break; + default: + (void)printf(" [type=%d len=%d]", type, len); + break; + } + sp += (len - 3); + length -= (len - 3); + } + return; +trunc: + (void)printf(" [|msdp]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-netbios.c b/print-netbios.c new file mode 100644 index 0000000..c92eb9e --- /dev/null +++ b/print-netbios.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Format and print NETBIOS packets. + * Contributed by Brad Parker (brad@fcr.com). + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-netbios.c,v 1.20 2003-11-16 09:36:29 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "netbios.h" +#include "extract.h" + +/* + * Print NETBIOS packets. + */ +void +netbios_print(struct p8022Hdr *nb, u_int length) +{ + if (length < p8022Size) { + (void)printf(" truncated-netbios %d", length); + return; + } + + if (nb->flags == UI) { + (void)printf("802.1 UI "); + } else { + (void)printf("802.1 CONN "); + } + + if ((u_char *)(nb + 1) > snapend) { + printf(" [|netbios]"); + return; + } + +/* + netbios_decode(nb, (u_char *)nb + p8022Size, length - p8022Size); +*/ +} + +#ifdef never + (void)printf("%s.%d > ", + ipxaddr_string(EXTRACT_32BITS(ipx->srcNet), ipx->srcNode), + EXTRACT_16BITS(ipx->srcSkt)); + + (void)printf("%s.%d:", + ipxaddr_string(EXTRACT_32BITS(ipx->dstNet), ipx->dstNode), + EXTRACT_16BITS(ipx->dstSkt)); + + if ((u_char *)(ipx + 1) > snapend) { + printf(" [|ipx]"); + return; + } + + /* take length from ipx header */ + length = EXTRACT_16BITS(&ipx->length); + + ipx_decode(ipx, (u_char *)ipx + ipxSize, length - ipxSize); +#endif + diff --git a/print-nfs.c b/print-nfs.c new file mode 100644 index 0000000..4d17757 --- /dev/null +++ b/print-nfs.c @@ -0,0 +1,1851 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-nfs.c,v 1.111 2007-12-22 03:08:04 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "nfs.h" +#include "nfsfh.h" + +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif +#include "rpc_auth.h" +#include "rpc_msg.h" + +static void nfs_printfh(const u_int32_t *, const u_int); +static int xid_map_enter(const struct sunrpc_msg *, const u_char *); +static int32_t xid_map_find(const struct sunrpc_msg *, const u_char *, + u_int32_t *, u_int32_t *); +static void interp_reply(const struct sunrpc_msg *, u_int32_t, u_int32_t, int); +static const u_int32_t *parse_post_op_attr(const u_int32_t *, int); +static void print_sattr3(const struct nfsv3_sattr *sa3, int verbose); +static void print_nfsaddr(const u_char *, const char *, const char *); + +/* + * Mapping of old NFS Version 2 RPC numbers to generic numbers. + */ +u_int32_t nfsv3_procid[NFS_NPROCS] = { + NFSPROC_NULL, + NFSPROC_GETATTR, + NFSPROC_SETATTR, + NFSPROC_NOOP, + NFSPROC_LOOKUP, + NFSPROC_READLINK, + NFSPROC_READ, + NFSPROC_NOOP, + NFSPROC_WRITE, + NFSPROC_CREATE, + NFSPROC_REMOVE, + NFSPROC_RENAME, + NFSPROC_LINK, + NFSPROC_SYMLINK, + NFSPROC_MKDIR, + NFSPROC_RMDIR, + NFSPROC_READDIR, + NFSPROC_FSSTAT, + NFSPROC_NOOP, + NFSPROC_NOOP, + NFSPROC_NOOP, + NFSPROC_NOOP, + NFSPROC_NOOP, + NFSPROC_NOOP, + NFSPROC_NOOP, + NFSPROC_NOOP +}; + +/* + * NFS V2 and V3 status values. + * + * Some of these come from the RFCs for NFS V2 and V3, with the message + * strings taken from the FreeBSD C library "errlst.c". + * + * Others are errors that are not in the RFC but that I suspect some + * NFS servers could return; the values are FreeBSD errno values, as + * the first NFS server was the SunOS 2.0 one, and until 5.0 SunOS + * was primarily BSD-derived. + */ +static struct tok status2str[] = { + { 1, "Operation not permitted" }, /* EPERM */ + { 2, "No such file or directory" }, /* ENOENT */ + { 5, "Input/output error" }, /* EIO */ + { 6, "Device not configured" }, /* ENXIO */ + { 11, "Resource deadlock avoided" }, /* EDEADLK */ + { 12, "Cannot allocate memory" }, /* ENOMEM */ + { 13, "Permission denied" }, /* EACCES */ + { 17, "File exists" }, /* EEXIST */ + { 18, "Cross-device link" }, /* EXDEV */ + { 19, "Operation not supported by device" }, /* ENODEV */ + { 20, "Not a directory" }, /* ENOTDIR */ + { 21, "Is a directory" }, /* EISDIR */ + { 22, "Invalid argument" }, /* EINVAL */ + { 26, "Text file busy" }, /* ETXTBSY */ + { 27, "File too large" }, /* EFBIG */ + { 28, "No space left on device" }, /* ENOSPC */ + { 30, "Read-only file system" }, /* EROFS */ + { 31, "Too many links" }, /* EMLINK */ + { 45, "Operation not supported" }, /* EOPNOTSUPP */ + { 62, "Too many levels of symbolic links" }, /* ELOOP */ + { 63, "File name too long" }, /* ENAMETOOLONG */ + { 66, "Directory not empty" }, /* ENOTEMPTY */ + { 69, "Disc quota exceeded" }, /* EDQUOT */ + { 70, "Stale NFS file handle" }, /* ESTALE */ + { 71, "Too many levels of remote in path" }, /* EREMOTE */ + { 99, "Write cache flushed to disk" }, /* NFSERR_WFLUSH (not used) */ + { 10001, "Illegal NFS file handle" }, /* NFS3ERR_BADHANDLE */ + { 10002, "Update synchronization mismatch" }, /* NFS3ERR_NOT_SYNC */ + { 10003, "READDIR/READDIRPLUS cookie is stale" }, /* NFS3ERR_BAD_COOKIE */ + { 10004, "Operation not supported" }, /* NFS3ERR_NOTSUPP */ + { 10005, "Buffer or request is too small" }, /* NFS3ERR_TOOSMALL */ + { 10006, "Unspecified error on server" }, /* NFS3ERR_SERVERFAULT */ + { 10007, "Object of that type not supported" }, /* NFS3ERR_BADTYPE */ + { 10008, "Request couldn't be completed in time" }, /* NFS3ERR_JUKEBOX */ + { 0, NULL } +}; + +static struct tok nfsv3_writemodes[] = { + { 0, "unstable" }, + { 1, "datasync" }, + { 2, "filesync" }, + { 0, NULL } +}; + +static struct tok type2str[] = { + { NFNON, "NON" }, + { NFREG, "REG" }, + { NFDIR, "DIR" }, + { NFBLK, "BLK" }, + { NFCHR, "CHR" }, + { NFLNK, "LNK" }, + { NFFIFO, "FIFO" }, + { 0, NULL } +}; + +static void +print_nfsaddr(const u_char *bp, const char *s, const char *d) +{ + struct ip *ip; +#ifdef INET6 + struct ip6_hdr *ip6; + char srcaddr[INET6_ADDRSTRLEN], dstaddr[INET6_ADDRSTRLEN]; +#else +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif + char srcaddr[INET_ADDRSTRLEN], dstaddr[INET_ADDRSTRLEN]; +#endif + + srcaddr[0] = dstaddr[0] = '\0'; + switch (IP_V((struct ip *)bp)) { + case 4: + ip = (struct ip *)bp; + strlcpy(srcaddr, ipaddr_string(&ip->ip_src), sizeof(srcaddr)); + strlcpy(dstaddr, ipaddr_string(&ip->ip_dst), sizeof(dstaddr)); + break; +#ifdef INET6 + case 6: + ip6 = (struct ip6_hdr *)bp; + strlcpy(srcaddr, ip6addr_string(&ip6->ip6_src), + sizeof(srcaddr)); + strlcpy(dstaddr, ip6addr_string(&ip6->ip6_dst), + sizeof(dstaddr)); + break; +#endif + default: + strlcpy(srcaddr, "?", sizeof(srcaddr)); + strlcpy(dstaddr, "?", sizeof(dstaddr)); + break; + } + + (void)printf("%s.%s > %s.%s: ", srcaddr, s, dstaddr, d); +} + +static const u_int32_t * +parse_sattr3(const u_int32_t *dp, struct nfsv3_sattr *sa3) +{ + TCHECK(dp[0]); + sa3->sa_modeset = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_modeset) { + TCHECK(dp[0]); + sa3->sa_mode = EXTRACT_32BITS(dp); + dp++; + } + + TCHECK(dp[0]); + sa3->sa_uidset = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_uidset) { + TCHECK(dp[0]); + sa3->sa_uid = EXTRACT_32BITS(dp); + dp++; + } + + TCHECK(dp[0]); + sa3->sa_gidset = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_gidset) { + TCHECK(dp[0]); + sa3->sa_gid = EXTRACT_32BITS(dp); + dp++; + } + + TCHECK(dp[0]); + sa3->sa_sizeset = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_sizeset) { + TCHECK(dp[0]); + sa3->sa_size = EXTRACT_32BITS(dp); + dp++; + } + + TCHECK(dp[0]); + sa3->sa_atimetype = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT) { + TCHECK(dp[1]); + sa3->sa_atime.nfsv3_sec = EXTRACT_32BITS(dp); + dp++; + sa3->sa_atime.nfsv3_nsec = EXTRACT_32BITS(dp); + dp++; + } + + TCHECK(dp[0]); + sa3->sa_mtimetype = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT) { + TCHECK(dp[1]); + sa3->sa_mtime.nfsv3_sec = EXTRACT_32BITS(dp); + dp++; + sa3->sa_mtime.nfsv3_nsec = EXTRACT_32BITS(dp); + dp++; + } + + return dp; +trunc: + return NULL; +} + +static int nfserr; /* true if we error rather than trunc */ + +static void +print_sattr3(const struct nfsv3_sattr *sa3, int verbose) +{ + if (sa3->sa_modeset) + printf(" mode %o", sa3->sa_mode); + if (sa3->sa_uidset) + printf(" uid %u", sa3->sa_uid); + if (sa3->sa_gidset) + printf(" gid %u", sa3->sa_gid); + if (verbose > 1) { + if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT) + printf(" atime %u.%06u", sa3->sa_atime.nfsv3_sec, + sa3->sa_atime.nfsv3_nsec); + if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT) + printf(" mtime %u.%06u", sa3->sa_mtime.nfsv3_sec, + sa3->sa_mtime.nfsv3_nsec); + } +} + +void +nfsreply_print(register const u_char *bp, u_int length, + register const u_char *bp2) +{ + register const struct sunrpc_msg *rp; + u_int32_t proc, vers, reply_stat; + char srcid[20], dstid[20]; /*fits 32bit*/ + enum sunrpc_reject_stat rstat; + u_int32_t rlow; + u_int32_t rhigh; + enum sunrpc_auth_stat rwhy; + + nfserr = 0; /* assume no error */ + rp = (const struct sunrpc_msg *)bp; + + TCHECK(rp->rm_xid); + if (!nflag) { + strlcpy(srcid, "nfs", sizeof(srcid)); + snprintf(dstid, sizeof(dstid), "%u", + EXTRACT_32BITS(&rp->rm_xid)); + } else { + snprintf(srcid, sizeof(srcid), "%u", NFS_PORT); + snprintf(dstid, sizeof(dstid), "%u", + EXTRACT_32BITS(&rp->rm_xid)); + } + print_nfsaddr(bp2, srcid, dstid); + TCHECK(rp->rm_reply.rp_stat); + reply_stat = EXTRACT_32BITS(&rp->rm_reply.rp_stat); + switch (reply_stat) { + + case SUNRPC_MSG_ACCEPTED: + (void)printf("reply ok %u", length); + if (xid_map_find(rp, bp2, &proc, &vers) >= 0) + interp_reply(rp, proc, vers, length); + break; + + case SUNRPC_MSG_DENIED: + (void)printf("reply ERR %u: ", length); + TCHECK(rp->rm_reply.rp_reject.rj_stat); + rstat = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_stat); + switch (rstat) { + + case SUNRPC_RPC_MISMATCH: + TCHECK(rp->rm_reply.rp_reject.rj_vers.high); + rlow = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_vers.low); + rhigh = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_vers.high); + (void)printf("RPC Version mismatch (%u-%u)", + rlow, rhigh); + break; + + case SUNRPC_AUTH_ERROR: + TCHECK(rp->rm_reply.rp_reject.rj_why); + rwhy = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_why); + (void)printf("Auth "); + switch (rwhy) { + + case SUNRPC_AUTH_OK: + (void)printf("OK"); + break; + + case SUNRPC_AUTH_BADCRED: + (void)printf("Bogus Credentials (seal broken)"); + break; + + case SUNRPC_AUTH_REJECTEDCRED: + (void)printf("Rejected Credentials (client should begin new session)"); + break; + + case SUNRPC_AUTH_BADVERF: + (void)printf("Bogus Verifier (seal broken)"); + break; + + case SUNRPC_AUTH_REJECTEDVERF: + (void)printf("Verifier expired or was replayed"); + break; + + case SUNRPC_AUTH_TOOWEAK: + (void)printf("Credentials are too weak"); + break; + + case SUNRPC_AUTH_INVALIDRESP: + (void)printf("Bogus response verifier"); + break; + + case SUNRPC_AUTH_FAILED: + (void)printf("Unknown failure"); + break; + + default: + (void)printf("Invalid failure code %u", + (unsigned int)rwhy); + break; + } + break; + + default: + (void)printf("Unknown reason for rejecting rpc message %u", + (unsigned int)rstat); + break; + } + break; + + default: + (void)printf("reply Unknown rpc response code=%u %u", + reply_stat, length); + break; + } + return; + +trunc: + if (!nfserr) + fputs(" [|nfs]", stdout); +} + +/* + * Return a pointer to the first file handle in the packet. + * If the packet was truncated, return 0. + */ +static const u_int32_t * +parsereq(register const struct sunrpc_msg *rp, register u_int length) +{ + register const u_int32_t *dp; + register u_int len; + + /* + * find the start of the req data (if we captured it) + */ + dp = (u_int32_t *)&rp->rm_call.cb_cred; + TCHECK(dp[1]); + len = EXTRACT_32BITS(&dp[1]); + if (len < length) { + dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); + TCHECK(dp[1]); + len = EXTRACT_32BITS(&dp[1]); + if (len < length) { + dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); + TCHECK2(dp[0], 0); + return (dp); + } + } +trunc: + return (NULL); +} + +/* + * Print out an NFS file handle and return a pointer to following word. + * If packet was truncated, return 0. + */ +static const u_int32_t * +parsefh(register const u_int32_t *dp, int v3) +{ + u_int len; + + if (v3) { + TCHECK(dp[0]); + len = EXTRACT_32BITS(dp) / 4; + dp++; + } else + len = NFSX_V2FH / 4; + + if (TTEST2(*dp, len * sizeof(*dp))) { + nfs_printfh(dp, len); + return (dp + len); + } +trunc: + return (NULL); +} + +/* + * Print out a file name and return pointer to 32-bit word past it. + * If packet was truncated, return 0. + */ +static const u_int32_t * +parsefn(register const u_int32_t *dp) +{ + register u_int32_t len; + register const u_char *cp; + + /* Bail if we don't have the string length */ + TCHECK(*dp); + + /* Fetch string length; convert to host order */ + len = *dp++; + NTOHL(len); + + TCHECK2(*dp, ((len + 3) & ~3)); + + cp = (u_char *)dp; + /* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */ + dp += ((len + 3) & ~3) / sizeof(*dp); + putchar('"'); + if (fn_printn(cp, len, snapend)) { + putchar('"'); + goto trunc; + } + putchar('"'); + + return (dp); +trunc: + return NULL; +} + +/* + * Print out file handle and file name. + * Return pointer to 32-bit word past file name. + * If packet was truncated (or there was some other error), return 0. + */ +static const u_int32_t * +parsefhn(register const u_int32_t *dp, int v3) +{ + dp = parsefh(dp, v3); + if (dp == NULL) + return (NULL); + putchar(' '); + return (parsefn(dp)); +} + +void +nfsreq_print(register const u_char *bp, u_int length, + register const u_char *bp2) +{ + register const struct sunrpc_msg *rp; + register const u_int32_t *dp; + nfs_type type; + int v3; + u_int32_t proc; + u_int32_t access_flags; + struct nfsv3_sattr sa3; + char srcid[20], dstid[20]; /*fits 32bit*/ + + nfserr = 0; /* assume no error */ + rp = (const struct sunrpc_msg *)bp; + + TCHECK(rp->rm_xid); + if (!nflag) { + snprintf(srcid, sizeof(srcid), "%u", + EXTRACT_32BITS(&rp->rm_xid)); + strlcpy(dstid, "nfs", sizeof(dstid)); + } else { + snprintf(srcid, sizeof(srcid), "%u", + EXTRACT_32BITS(&rp->rm_xid)); + snprintf(dstid, sizeof(dstid), "%u", NFS_PORT); + } + print_nfsaddr(bp2, srcid, dstid); + (void)printf("%d", length); + + if (!xid_map_enter(rp, bp2)) /* record proc number for later on */ + goto trunc; + + v3 = (EXTRACT_32BITS(&rp->rm_call.cb_vers) == NFS_VER3); + proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); + + if (!v3 && proc < NFS_NPROCS) + proc = nfsv3_procid[proc]; + + switch (proc) { + case NFSPROC_NOOP: + printf(" nop"); + return; + case NFSPROC_NULL: + printf(" null"); + return; + + case NFSPROC_GETATTR: + printf(" getattr"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; + break; + + case NFSPROC_SETATTR: + printf(" setattr"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; + break; + + case NFSPROC_LOOKUP: + printf(" lookup"); + if ((dp = parsereq(rp, length)) != NULL && + parsefhn(dp, v3) != NULL) + return; + break; + + case NFSPROC_ACCESS: + printf(" access"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefh(dp, v3)) != NULL) { + TCHECK(dp[0]); + access_flags = EXTRACT_32BITS(&dp[0]); + if (access_flags & ~NFSV3ACCESS_FULL) { + /* NFSV3ACCESS definitions aren't up to date */ + printf(" %04x", access_flags); + } else if ((access_flags & NFSV3ACCESS_FULL) == NFSV3ACCESS_FULL) { + printf(" NFS_ACCESS_FULL"); + } else { + char separator = ' '; + if (access_flags & NFSV3ACCESS_READ) { + printf(" NFS_ACCESS_READ"); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_LOOKUP) { + printf("%cNFS_ACCESS_LOOKUP", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_MODIFY) { + printf("%cNFS_ACCESS_MODIFY", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_EXTEND) { + printf("%cNFS_ACCESS_EXTEND", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_DELETE) { + printf("%cNFS_ACCESS_DELETE", separator); + separator = '|'; + } + if (access_flags & NFSV3ACCESS_EXECUTE) + printf("%cNFS_ACCESS_EXECUTE", separator); + } + return; + } + break; + + case NFSPROC_READLINK: + printf(" readlink"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; + break; + + case NFSPROC_READ: + printf(" read"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefh(dp, v3)) != NULL) { + if (v3) { + TCHECK(dp[2]); + printf(" %u bytes @ %" PRIu64, + EXTRACT_32BITS(&dp[2]), + EXTRACT_64BITS(&dp[0])); + } else { + TCHECK(dp[1]); + printf(" %u bytes @ %u", + EXTRACT_32BITS(&dp[1]), + EXTRACT_32BITS(&dp[0])); + } + return; + } + break; + + case NFSPROC_WRITE: + printf(" write"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefh(dp, v3)) != NULL) { + if (v3) { + TCHECK(dp[2]); + printf(" %u (%u) bytes @ %" PRIu64, + EXTRACT_32BITS(&dp[4]), + EXTRACT_32BITS(&dp[2]), + EXTRACT_64BITS(&dp[0])); + if (vflag) { + dp += 3; + TCHECK(dp[0]); + printf(" <%s>", + tok2str(nfsv3_writemodes, + NULL, EXTRACT_32BITS(dp))); + } + } else { + TCHECK(dp[3]); + printf(" %u (%u) bytes @ %u (%u)", + EXTRACT_32BITS(&dp[3]), + EXTRACT_32BITS(&dp[2]), + EXTRACT_32BITS(&dp[1]), + EXTRACT_32BITS(&dp[0])); + } + return; + } + break; + + case NFSPROC_CREATE: + printf(" create"); + if ((dp = parsereq(rp, length)) != NULL && + parsefhn(dp, v3) != NULL) + return; + break; + + case NFSPROC_MKDIR: + printf(" mkdir"); + if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp, v3) != 0) + return; + break; + + case NFSPROC_SYMLINK: + printf(" symlink"); + if ((dp = parsereq(rp, length)) != 0 && + (dp = parsefhn(dp, v3)) != 0) { + fputs(" ->", stdout); + if (v3 && (dp = parse_sattr3(dp, &sa3)) == 0) + break; + if (parsefn(dp) == 0) + break; + if (v3 && vflag) + print_sattr3(&sa3, vflag); + return; + } + break; + + case NFSPROC_MKNOD: + printf(" mknod"); + if ((dp = parsereq(rp, length)) != 0 && + (dp = parsefhn(dp, v3)) != 0) { + TCHECK(*dp); + type = (nfs_type)EXTRACT_32BITS(dp); + dp++; + if ((dp = parse_sattr3(dp, &sa3)) == 0) + break; + printf(" %s", tok2str(type2str, "unk-ft %d", type)); + if (vflag && (type == NFCHR || type == NFBLK)) { + TCHECK(dp[1]); + printf(" %u/%u", + EXTRACT_32BITS(&dp[0]), + EXTRACT_32BITS(&dp[1])); + dp += 2; + } + if (vflag) + print_sattr3(&sa3, vflag); + return; + } + break; + + case NFSPROC_REMOVE: + printf(" remove"); + if ((dp = parsereq(rp, length)) != NULL && + parsefhn(dp, v3) != NULL) + return; + break; + + case NFSPROC_RMDIR: + printf(" rmdir"); + if ((dp = parsereq(rp, length)) != NULL && + parsefhn(dp, v3) != NULL) + return; + break; + + case NFSPROC_RENAME: + printf(" rename"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefhn(dp, v3)) != NULL) { + fputs(" ->", stdout); + if (parsefhn(dp, v3) != NULL) + return; + } + break; + + case NFSPROC_LINK: + printf(" link"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefh(dp, v3)) != NULL) { + fputs(" ->", stdout); + if (parsefhn(dp, v3) != NULL) + return; + } + break; + + case NFSPROC_READDIR: + printf(" readdir"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefh(dp, v3)) != NULL) { + if (v3) { + TCHECK(dp[4]); + /* + * We shouldn't really try to interpret the + * offset cookie here. + */ + printf(" %u bytes @ %" PRId64, + EXTRACT_32BITS(&dp[4]), + EXTRACT_64BITS(&dp[0])); + if (vflag) + printf(" verf %08x%08x", dp[2], + dp[3]); + } else { + TCHECK(dp[1]); + /* + * Print the offset as signed, since -1 is + * common, but offsets > 2^31 aren't. + */ + printf(" %u bytes @ %d", + EXTRACT_32BITS(&dp[1]), + EXTRACT_32BITS(&dp[0])); + } + return; + } + break; + + case NFSPROC_READDIRPLUS: + printf(" readdirplus"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefh(dp, v3)) != NULL) { + TCHECK(dp[4]); + /* + * We don't try to interpret the offset + * cookie here. + */ + printf(" %u bytes @ %" PRId64, + EXTRACT_32BITS(&dp[4]), + EXTRACT_64BITS(&dp[0])); + if (vflag) { + TCHECK(dp[5]); + printf(" max %u verf %08x%08x", + EXTRACT_32BITS(&dp[5]), dp[2], dp[3]); + } + return; + } + break; + + case NFSPROC_FSSTAT: + printf(" fsstat"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; + break; + + case NFSPROC_FSINFO: + printf(" fsinfo"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; + break; + + case NFSPROC_PATHCONF: + printf(" pathconf"); + if ((dp = parsereq(rp, length)) != NULL && + parsefh(dp, v3) != NULL) + return; + break; + + case NFSPROC_COMMIT: + printf(" commit"); + if ((dp = parsereq(rp, length)) != NULL && + (dp = parsefh(dp, v3)) != NULL) { + TCHECK(dp[2]); + printf(" %u bytes @ %" PRIu64, + EXTRACT_32BITS(&dp[2]), + EXTRACT_64BITS(&dp[0])); + return; + } + break; + + default: + printf(" proc-%u", EXTRACT_32BITS(&rp->rm_call.cb_proc)); + return; + } + +trunc: + if (!nfserr) + fputs(" [|nfs]", stdout); +} + +/* + * Print out an NFS file handle. + * We assume packet was not truncated before the end of the + * file handle pointed to by dp. + * + * Note: new version (using portable file-handle parser) doesn't produce + * generation number. It probably could be made to do that, with some + * additional hacking on the parser code. + */ +static void +nfs_printfh(register const u_int32_t *dp, const u_int len) +{ + my_fsid fsid; + ino_t ino; + const char *sfsname = NULL; + char *spacep; + + if (uflag) { + u_int i; + char const *sep = ""; + + printf(" fh["); + for (i=0; irm_call.cb_vers)) + return (0); + switch (IP_V((struct ip *)bp)) { + case 4: + ip = (struct ip *)bp; + break; +#ifdef INET6 + case 6: + ip6 = (struct ip6_hdr *)bp; + break; +#endif + default: + return (1); + } + + xmep = &xid_map[xid_map_next]; + + if (++xid_map_next >= XIDMAPSIZE) + xid_map_next = 0; + + xmep->xid = rp->rm_xid; + if (ip) { + xmep->ipver = 4; + memcpy(&xmep->client, &ip->ip_src, sizeof(ip->ip_src)); + memcpy(&xmep->server, &ip->ip_dst, sizeof(ip->ip_dst)); + } +#ifdef INET6 + else if (ip6) { + xmep->ipver = 6; + memcpy(&xmep->client, &ip6->ip6_src, sizeof(ip6->ip6_src)); + memcpy(&xmep->server, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); + } +#endif + xmep->proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); + xmep->vers = EXTRACT_32BITS(&rp->rm_call.cb_vers); + return (1); +} + +/* + * Returns 0 and puts NFSPROC_xxx in proc return and + * version in vers return, or returns -1 on failure + */ +static int +xid_map_find(const struct sunrpc_msg *rp, const u_char *bp, u_int32_t *proc, + u_int32_t *vers) +{ + int i; + struct xid_map_entry *xmep; + u_int32_t xid = rp->rm_xid; + struct ip *ip = (struct ip *)bp; +#ifdef INET6 + struct ip6_hdr *ip6 = (struct ip6_hdr *)bp; +#endif + int cmp; + + /* Start searching from where we last left off */ + i = xid_map_hint; + do { + xmep = &xid_map[i]; + cmp = 1; + if (xmep->ipver != IP_V(ip) || xmep->xid != xid) + goto nextitem; + switch (xmep->ipver) { + case 4: + if (memcmp(&ip->ip_src, &xmep->server, + sizeof(ip->ip_src)) != 0 || + memcmp(&ip->ip_dst, &xmep->client, + sizeof(ip->ip_dst)) != 0) { + cmp = 0; + } + break; +#ifdef INET6 + case 6: + if (memcmp(&ip6->ip6_src, &xmep->server, + sizeof(ip6->ip6_src)) != 0 || + memcmp(&ip6->ip6_dst, &xmep->client, + sizeof(ip6->ip6_dst)) != 0) { + cmp = 0; + } + break; +#endif + default: + cmp = 0; + break; + } + if (cmp) { + /* match */ + xid_map_hint = i; + *proc = xmep->proc; + *vers = xmep->vers; + return 0; + } + nextitem: + if (++i >= XIDMAPSIZE) + i = 0; + } while (i != xid_map_hint); + + /* search failed */ + return (-1); +} + +/* + * Routines for parsing reply packets + */ + +/* + * Return a pointer to the beginning of the actual results. + * If the packet was truncated, return 0. + */ +static const u_int32_t * +parserep(register const struct sunrpc_msg *rp, register u_int length) +{ + register const u_int32_t *dp; + u_int len; + enum sunrpc_accept_stat astat; + + /* + * Portability note: + * Here we find the address of the ar_verf credentials. + * Originally, this calculation was + * dp = (u_int32_t *)&rp->rm_reply.rp_acpt.ar_verf + * On the wire, the rp_acpt field starts immediately after + * the (32 bit) rp_stat field. However, rp_acpt (which is a + * "struct accepted_reply") contains a "struct opaque_auth", + * whose internal representation contains a pointer, so on a + * 64-bit machine the compiler inserts 32 bits of padding + * before rp->rm_reply.rp_acpt.ar_verf. So, we cannot use + * the internal representation to parse the on-the-wire + * representation. Instead, we skip past the rp_stat field, + * which is an "enum" and so occupies one 32-bit word. + */ + dp = ((const u_int32_t *)&rp->rm_reply) + 1; + TCHECK(dp[1]); + len = EXTRACT_32BITS(&dp[1]); + if (len >= length) + return (NULL); + /* + * skip past the ar_verf credentials. + */ + dp += (len + (2*sizeof(u_int32_t) + 3)) / sizeof(u_int32_t); + TCHECK2(dp[0], 0); + + /* + * now we can check the ar_stat field + */ + astat = (enum sunrpc_accept_stat) EXTRACT_32BITS(dp); + switch (astat) { + + case SUNRPC_SUCCESS: + break; + + case SUNRPC_PROG_UNAVAIL: + printf(" PROG_UNAVAIL"); + nfserr = 1; /* suppress trunc string */ + return (NULL); + + case SUNRPC_PROG_MISMATCH: + printf(" PROG_MISMATCH"); + nfserr = 1; /* suppress trunc string */ + return (NULL); + + case SUNRPC_PROC_UNAVAIL: + printf(" PROC_UNAVAIL"); + nfserr = 1; /* suppress trunc string */ + return (NULL); + + case SUNRPC_GARBAGE_ARGS: + printf(" GARBAGE_ARGS"); + nfserr = 1; /* suppress trunc string */ + return (NULL); + + case SUNRPC_SYSTEM_ERR: + printf(" SYSTEM_ERR"); + nfserr = 1; /* suppress trunc string */ + return (NULL); + + default: + printf(" ar_stat %d", astat); + nfserr = 1; /* suppress trunc string */ + return (NULL); + } + /* successful return */ + TCHECK2(*dp, sizeof(astat)); + return ((u_int32_t *) (sizeof(astat) + ((char *)dp))); +trunc: + return (0); +} + +static const u_int32_t * +parsestatus(const u_int32_t *dp, int *er) +{ + int errnum; + + TCHECK(dp[0]); + + errnum = EXTRACT_32BITS(&dp[0]); + if (er) + *er = errnum; + if (errnum != 0) { + if (!qflag) + printf(" ERROR: %s", + tok2str(status2str, "unk %d", errnum)); + nfserr = 1; + } + return (dp + 1); +trunc: + return NULL; +} + +static const u_int32_t * +parsefattr(const u_int32_t *dp, int verbose, int v3) +{ + const struct nfs_fattr *fap; + + fap = (const struct nfs_fattr *)dp; + TCHECK(fap->fa_gid); + if (verbose) { + printf(" %s %o ids %d/%d", + tok2str(type2str, "unk-ft %d ", + EXTRACT_32BITS(&fap->fa_type)), + EXTRACT_32BITS(&fap->fa_mode), + EXTRACT_32BITS(&fap->fa_uid), + EXTRACT_32BITS(&fap->fa_gid)); + if (v3) { + TCHECK(fap->fa3_size); + printf(" sz %" PRIu64, + EXTRACT_64BITS((u_int32_t *)&fap->fa3_size)); + } else { + TCHECK(fap->fa2_size); + printf(" sz %d", EXTRACT_32BITS(&fap->fa2_size)); + } + } + /* print lots more stuff */ + if (verbose > 1) { + if (v3) { + TCHECK(fap->fa3_ctime); + printf(" nlink %d rdev %d/%d", + EXTRACT_32BITS(&fap->fa_nlink), + EXTRACT_32BITS(&fap->fa3_rdev.specdata1), + EXTRACT_32BITS(&fap->fa3_rdev.specdata2)); + printf(" fsid %" PRIx64, + EXTRACT_64BITS((u_int32_t *)&fap->fa3_fsid)); + printf(" fileid %" PRIx64, + EXTRACT_64BITS((u_int32_t *)&fap->fa3_fileid)); + printf(" a/m/ctime %u.%06u", + EXTRACT_32BITS(&fap->fa3_atime.nfsv3_sec), + EXTRACT_32BITS(&fap->fa3_atime.nfsv3_nsec)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa3_mtime.nfsv3_sec), + EXTRACT_32BITS(&fap->fa3_mtime.nfsv3_nsec)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa3_ctime.nfsv3_sec), + EXTRACT_32BITS(&fap->fa3_ctime.nfsv3_nsec)); + } else { + TCHECK(fap->fa2_ctime); + printf(" nlink %d rdev %x fsid %x nodeid %x a/m/ctime", + EXTRACT_32BITS(&fap->fa_nlink), + EXTRACT_32BITS(&fap->fa2_rdev), + EXTRACT_32BITS(&fap->fa2_fsid), + EXTRACT_32BITS(&fap->fa2_fileid)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa2_atime.nfsv2_sec), + EXTRACT_32BITS(&fap->fa2_atime.nfsv2_usec)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa2_mtime.nfsv2_sec), + EXTRACT_32BITS(&fap->fa2_mtime.nfsv2_usec)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_sec), + EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_usec)); + } + } + return ((const u_int32_t *)((unsigned char *)dp + + (v3 ? NFSX_V3FATTR : NFSX_V2FATTR))); +trunc: + return (NULL); +} + +static int +parseattrstat(const u_int32_t *dp, int verbose, int v3) +{ + int er; + + dp = parsestatus(dp, &er); + if (dp == NULL) + return (0); + if (er) + return (1); + + return (parsefattr(dp, verbose, v3) != NULL); +} + +static int +parsediropres(const u_int32_t *dp) +{ + int er; + + if (!(dp = parsestatus(dp, &er))) + return (0); + if (er) + return (1); + + dp = parsefh(dp, 0); + if (dp == NULL) + return (0); + + return (parsefattr(dp, vflag, 0) != NULL); +} + +static int +parselinkres(const u_int32_t *dp, int v3) +{ + int er; + + dp = parsestatus(dp, &er); + if (dp == NULL) + return(0); + if (er) + return(1); + if (v3 && !(dp = parse_post_op_attr(dp, vflag))) + return (0); + putchar(' '); + return (parsefn(dp) != NULL); +} + +static int +parsestatfs(const u_int32_t *dp, int v3) +{ + const struct nfs_statfs *sfsp; + int er; + + dp = parsestatus(dp, &er); + if (dp == NULL) + return (0); + if (!v3 && er) + return (1); + + if (qflag) + return(1); + + if (v3) { + if (vflag) + printf(" POST:"); + if (!(dp = parse_post_op_attr(dp, vflag))) + return (0); + } + + TCHECK2(*dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS)); + + sfsp = (const struct nfs_statfs *)dp; + + if (v3) { + printf(" tbytes %" PRIu64 " fbytes %" PRIu64 " abytes %" PRIu64, + EXTRACT_64BITS((u_int32_t *)&sfsp->sf_tbytes), + EXTRACT_64BITS((u_int32_t *)&sfsp->sf_fbytes), + EXTRACT_64BITS((u_int32_t *)&sfsp->sf_abytes)); + if (vflag) { + printf(" tfiles %" PRIu64 " ffiles %" PRIu64 " afiles %" PRIu64 " invar %u", + EXTRACT_64BITS((u_int32_t *)&sfsp->sf_tfiles), + EXTRACT_64BITS((u_int32_t *)&sfsp->sf_ffiles), + EXTRACT_64BITS((u_int32_t *)&sfsp->sf_afiles), + EXTRACT_32BITS(&sfsp->sf_invarsec)); + } + } else { + printf(" tsize %d bsize %d blocks %d bfree %d bavail %d", + EXTRACT_32BITS(&sfsp->sf_tsize), + EXTRACT_32BITS(&sfsp->sf_bsize), + EXTRACT_32BITS(&sfsp->sf_blocks), + EXTRACT_32BITS(&sfsp->sf_bfree), + EXTRACT_32BITS(&sfsp->sf_bavail)); + } + + return (1); +trunc: + return (0); +} + +static int +parserddires(const u_int32_t *dp) +{ + int er; + + dp = parsestatus(dp, &er); + if (dp == NULL) + return (0); + if (er) + return (1); + if (qflag) + return (1); + + TCHECK(dp[2]); + printf(" offset %x size %d ", + EXTRACT_32BITS(&dp[0]), EXTRACT_32BITS(&dp[1])); + if (dp[2] != 0) + printf(" eof"); + + return (1); +trunc: + return (0); +} + +static const u_int32_t * +parse_wcc_attr(const u_int32_t *dp) +{ + printf(" sz %" PRIu64, EXTRACT_64BITS(&dp[0])); + printf(" mtime %u.%06u ctime %u.%06u", + EXTRACT_32BITS(&dp[2]), EXTRACT_32BITS(&dp[3]), + EXTRACT_32BITS(&dp[4]), EXTRACT_32BITS(&dp[5])); + return (dp + 6); +} + +/* + * Pre operation attributes. Print only if vflag > 1. + */ +static const u_int32_t * +parse_pre_op_attr(const u_int32_t *dp, int verbose) +{ + TCHECK(dp[0]); + if (!EXTRACT_32BITS(&dp[0])) + return (dp + 1); + dp++; + TCHECK2(*dp, 24); + if (verbose > 1) { + return parse_wcc_attr(dp); + } else { + /* If not verbose enough, just skip over wcc_attr */ + return (dp + 6); + } +trunc: + return (NULL); +} + +/* + * Post operation attributes are printed if vflag >= 1 + */ +static const u_int32_t * +parse_post_op_attr(const u_int32_t *dp, int verbose) +{ + TCHECK(dp[0]); + if (!EXTRACT_32BITS(&dp[0])) + return (dp + 1); + dp++; + if (verbose) { + return parsefattr(dp, verbose, 1); + } else + return (dp + (NFSX_V3FATTR / sizeof (u_int32_t))); +trunc: + return (NULL); +} + +static const u_int32_t * +parse_wcc_data(const u_int32_t *dp, int verbose) +{ + if (verbose > 1) + printf(" PRE:"); + if (!(dp = parse_pre_op_attr(dp, verbose))) + return (0); + + if (verbose) + printf(" POST:"); + return parse_post_op_attr(dp, verbose); +} + +static const u_int32_t * +parsecreateopres(const u_int32_t *dp, int verbose) +{ + int er; + + if (!(dp = parsestatus(dp, &er))) + return (0); + if (er) + dp = parse_wcc_data(dp, verbose); + else { + TCHECK(dp[0]); + if (!EXTRACT_32BITS(&dp[0])) + return (dp + 1); + dp++; + if (!(dp = parsefh(dp, 1))) + return (0); + if (verbose) { + if (!(dp = parse_post_op_attr(dp, verbose))) + return (0); + if (vflag > 1) { + printf(" dir attr:"); + dp = parse_wcc_data(dp, verbose); + } + } + } + return (dp); +trunc: + return (NULL); +} + +static int +parsewccres(const u_int32_t *dp, int verbose) +{ + int er; + + if (!(dp = parsestatus(dp, &er))) + return (0); + return parse_wcc_data(dp, verbose) != 0; +} + +static const u_int32_t * +parsev3rddirres(const u_int32_t *dp, int verbose) +{ + int er; + + if (!(dp = parsestatus(dp, &er))) + return (0); + if (vflag) + printf(" POST:"); + if (!(dp = parse_post_op_attr(dp, verbose))) + return (0); + if (er) + return dp; + if (vflag) { + TCHECK(dp[1]); + printf(" verf %08x%08x", dp[0], dp[1]); + dp += 2; + } + return dp; +trunc: + return (NULL); +} + +static int +parsefsinfo(const u_int32_t *dp) +{ + struct nfsv3_fsinfo *sfp; + int er; + + if (!(dp = parsestatus(dp, &er))) + return (0); + if (vflag) + printf(" POST:"); + if (!(dp = parse_post_op_attr(dp, vflag))) + return (0); + if (er) + return (1); + + sfp = (struct nfsv3_fsinfo *)dp; + TCHECK(*sfp); + printf(" rtmax %u rtpref %u wtmax %u wtpref %u dtpref %u", + EXTRACT_32BITS(&sfp->fs_rtmax), + EXTRACT_32BITS(&sfp->fs_rtpref), + EXTRACT_32BITS(&sfp->fs_wtmax), + EXTRACT_32BITS(&sfp->fs_wtpref), + EXTRACT_32BITS(&sfp->fs_dtpref)); + if (vflag) { + printf(" rtmult %u wtmult %u maxfsz %" PRIu64, + EXTRACT_32BITS(&sfp->fs_rtmult), + EXTRACT_32BITS(&sfp->fs_wtmult), + EXTRACT_64BITS((u_int32_t *)&sfp->fs_maxfilesize)); + printf(" delta %u.%06u ", + EXTRACT_32BITS(&sfp->fs_timedelta.nfsv3_sec), + EXTRACT_32BITS(&sfp->fs_timedelta.nfsv3_nsec)); + } + return (1); +trunc: + return (0); +} + +static int +parsepathconf(const u_int32_t *dp) +{ + int er; + struct nfsv3_pathconf *spp; + + if (!(dp = parsestatus(dp, &er))) + return (0); + if (vflag) + printf(" POST:"); + if (!(dp = parse_post_op_attr(dp, vflag))) + return (0); + if (er) + return (1); + + spp = (struct nfsv3_pathconf *)dp; + TCHECK(*spp); + + printf(" linkmax %u namemax %u %s %s %s %s", + EXTRACT_32BITS(&spp->pc_linkmax), + EXTRACT_32BITS(&spp->pc_namemax), + EXTRACT_32BITS(&spp->pc_notrunc) ? "notrunc" : "", + EXTRACT_32BITS(&spp->pc_chownrestricted) ? "chownres" : "", + EXTRACT_32BITS(&spp->pc_caseinsensitive) ? "igncase" : "", + EXTRACT_32BITS(&spp->pc_casepreserving) ? "keepcase" : ""); + return (1); +trunc: + return (0); +} + +static void +interp_reply(const struct sunrpc_msg *rp, u_int32_t proc, u_int32_t vers, int length) +{ + register const u_int32_t *dp; + register int v3; + int er; + + v3 = (vers == NFS_VER3); + + if (!v3 && proc < NFS_NPROCS) + proc = nfsv3_procid[proc]; + + switch (proc) { + + case NFSPROC_NOOP: + printf(" nop"); + return; + + case NFSPROC_NULL: + printf(" null"); + return; + + case NFSPROC_GETATTR: + printf(" getattr"); + dp = parserep(rp, length); + if (dp != NULL && parseattrstat(dp, !qflag, v3) != 0) + return; + break; + + case NFSPROC_SETATTR: + printf(" setattr"); + if (!(dp = parserep(rp, length))) + return; + if (v3) { + if (parsewccres(dp, vflag)) + return; + } else { + if (parseattrstat(dp, !qflag, 0) != 0) + return; + } + break; + + case NFSPROC_LOOKUP: + printf(" lookup"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (!(dp = parsestatus(dp, &er))) + break; + if (er) { + if (vflag > 1) { + printf(" post dattr:"); + dp = parse_post_op_attr(dp, vflag); + } + } else { + if (!(dp = parsefh(dp, v3))) + break; + if ((dp = parse_post_op_attr(dp, vflag)) && + vflag > 1) { + printf(" post dattr:"); + dp = parse_post_op_attr(dp, vflag); + } + } + if (dp) + return; + } else { + if (parsediropres(dp) != 0) + return; + } + break; + + case NFSPROC_ACCESS: + printf(" access"); + if (!(dp = parserep(rp, length))) + break; + if (!(dp = parsestatus(dp, &er))) + break; + if (vflag) + printf(" attr:"); + if (!(dp = parse_post_op_attr(dp, vflag))) + break; + if (!er) + printf(" c %04x", EXTRACT_32BITS(&dp[0])); + return; + + case NFSPROC_READLINK: + printf(" readlink"); + dp = parserep(rp, length); + if (dp != NULL && parselinkres(dp, v3) != 0) + return; + break; + + case NFSPROC_READ: + printf(" read"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (!(dp = parsestatus(dp, &er))) + break; + if (!(dp = parse_post_op_attr(dp, vflag))) + break; + if (er) + return; + if (vflag) { + TCHECK(dp[1]); + printf(" %u bytes", EXTRACT_32BITS(&dp[0])); + if (EXTRACT_32BITS(&dp[1])) + printf(" EOF"); + } + return; + } else { + if (parseattrstat(dp, vflag, 0) != 0) + return; + } + break; + + case NFSPROC_WRITE: + printf(" write"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (!(dp = parsestatus(dp, &er))) + break; + if (!(dp = parse_wcc_data(dp, vflag))) + break; + if (er) + return; + if (vflag) { + TCHECK(dp[0]); + printf(" %u bytes", EXTRACT_32BITS(&dp[0])); + if (vflag > 1) { + TCHECK(dp[1]); + printf(" <%s>", + tok2str(nfsv3_writemodes, + NULL, EXTRACT_32BITS(&dp[1]))); + } + return; + } + } else { + if (parseattrstat(dp, vflag, v3) != 0) + return; + } + break; + + case NFSPROC_CREATE: + printf(" create"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (parsecreateopres(dp, vflag) != 0) + return; + } else { + if (parsediropres(dp) != 0) + return; + } + break; + + case NFSPROC_MKDIR: + printf(" mkdir"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (parsecreateopres(dp, vflag) != 0) + return; + } else { + if (parsediropres(dp) != 0) + return; + } + break; + + case NFSPROC_SYMLINK: + printf(" symlink"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (parsecreateopres(dp, vflag) != 0) + return; + } else { + if (parsestatus(dp, &er) != 0) + return; + } + break; + + case NFSPROC_MKNOD: + printf(" mknod"); + if (!(dp = parserep(rp, length))) + break; + if (parsecreateopres(dp, vflag) != 0) + return; + break; + + case NFSPROC_REMOVE: + printf(" remove"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (parsewccres(dp, vflag)) + return; + } else { + if (parsestatus(dp, &er) != 0) + return; + } + break; + + case NFSPROC_RMDIR: + printf(" rmdir"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (parsewccres(dp, vflag)) + return; + } else { + if (parsestatus(dp, &er) != 0) + return; + } + break; + + case NFSPROC_RENAME: + printf(" rename"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (!(dp = parsestatus(dp, &er))) + break; + if (vflag) { + printf(" from:"); + if (!(dp = parse_wcc_data(dp, vflag))) + break; + printf(" to:"); + if (!(dp = parse_wcc_data(dp, vflag))) + break; + } + return; + } else { + if (parsestatus(dp, &er) != 0) + return; + } + break; + + case NFSPROC_LINK: + printf(" link"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (!(dp = parsestatus(dp, &er))) + break; + if (vflag) { + printf(" file POST:"); + if (!(dp = parse_post_op_attr(dp, vflag))) + break; + printf(" dir:"); + if (!(dp = parse_wcc_data(dp, vflag))) + break; + return; + } + } else { + if (parsestatus(dp, &er) != 0) + return; + } + break; + + case NFSPROC_READDIR: + printf(" readdir"); + if (!(dp = parserep(rp, length))) + break; + if (v3) { + if (parsev3rddirres(dp, vflag)) + return; + } else { + if (parserddires(dp) != 0) + return; + } + break; + + case NFSPROC_READDIRPLUS: + printf(" readdirplus"); + if (!(dp = parserep(rp, length))) + break; + if (parsev3rddirres(dp, vflag)) + return; + break; + + case NFSPROC_FSSTAT: + printf(" fsstat"); + dp = parserep(rp, length); + if (dp != NULL && parsestatfs(dp, v3) != 0) + return; + break; + + case NFSPROC_FSINFO: + printf(" fsinfo"); + dp = parserep(rp, length); + if (dp != NULL && parsefsinfo(dp) != 0) + return; + break; + + case NFSPROC_PATHCONF: + printf(" pathconf"); + dp = parserep(rp, length); + if (dp != NULL && parsepathconf(dp) != 0) + return; + break; + + case NFSPROC_COMMIT: + printf(" commit"); + dp = parserep(rp, length); + if (dp != NULL && parsewccres(dp, vflag) != 0) + return; + break; + + default: + printf(" proc-%u", proc); + return; + } +trunc: + if (!nfserr) + fputs(" [|nfs]", stdout); +} diff --git a/print-ntp.c b/print-ntp.c new file mode 100644 index 0000000..d56f02a --- /dev/null +++ b/print-ntp.c @@ -0,0 +1,308 @@ +/* + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Format and print ntp packets. + * By Jeffrey Mogul/DECWRL + * loosely based on print-bootp.c + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.43 2007-11-30 13:45:10 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#ifdef HAVE_STRFTIME +#include +#endif + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#ifdef MODEMASK +#undef MODEMASK /* Solaris sucks */ +#endif +#include "ntp.h" + +static void p_sfix(const struct s_fixedpt *); +static void p_ntp_time(const struct l_fixedpt *); +static void p_ntp_delta(const struct l_fixedpt *, const struct l_fixedpt *); + +static struct tok ntp_mode_values[] = { + { MODE_UNSPEC, "unspecified" }, + { MODE_SYM_ACT, "symmetric active" }, + { MODE_SYM_PAS, "symmetric passive" }, + { MODE_CLIENT, "Client" }, + { MODE_SERVER, "Server" }, + { MODE_BROADCAST, "Broadcast" }, + { MODE_RES1, "Reserved" }, + { MODE_RES2, "Reserved" }, + { 0, NULL } +}; + +static struct tok ntp_leapind_values[] = { + { NO_WARNING, "" }, + { PLUS_SEC, "+1s" }, + { MINUS_SEC, "-1s" }, + { ALARM, "clock unsynchronized" }, + { 0, NULL } +}; + +static struct tok ntp_stratum_values[] = { + { UNSPECIFIED, "unspecified" }, + { PRIM_REF, "primary reference" }, + { 0, NULL } +}; + +/* + * Print ntp requests + */ +void +ntp_print(register const u_char *cp, u_int length) +{ + register const struct ntpdata *bp; + int mode, version, leapind; + + bp = (struct ntpdata *)cp; + + TCHECK(bp->status); + + version = (int)(bp->status & VERSIONMASK) >> 3; + printf("NTPv%d", version); + + mode = bp->status & MODEMASK; + if (!vflag) { + printf (", %s, length %u", + tok2str(ntp_mode_values, "Unknown mode", mode), + length); + return; + } + + printf (", length %u\n\t%s", + length, + tok2str(ntp_mode_values, "Unknown mode", mode)); + + leapind = bp->status & LEAPMASK; + printf (", Leap indicator: %s (%u)", + tok2str(ntp_leapind_values, "Unknown", leapind), + leapind); + + TCHECK(bp->stratum); + printf(", Stratum %u (%s)", + bp->stratum, + tok2str(ntp_stratum_values, (bp->stratum >=2 && bp->stratum<=15) ? "secondary reference" : "reserved", bp->stratum)); + + TCHECK(bp->ppoll); + printf(", poll %us", bp->ppoll); + + /* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */ + TCHECK2(bp->root_delay, 0); + printf(", precision %d", bp->precision); + + TCHECK(bp->root_delay); + fputs("\n\tRoot Delay: ", stdout); + p_sfix(&bp->root_delay); + + TCHECK(bp->root_dispersion); + fputs(", Root dispersion: ", stdout); + p_sfix(&bp->root_dispersion); + + TCHECK(bp->refid); + fputs(", Reference-ID: ", stdout); + /* Interpretation depends on stratum */ + switch (bp->stratum) { + + case UNSPECIFIED: + printf("(unspec)"); + break; + + case PRIM_REF: + if (fn_printn((u_char *)&(bp->refid), 4, snapend)) + goto trunc; + break; + + case INFO_QUERY: + printf("%s INFO_QUERY", ipaddr_string(&(bp->refid))); + /* this doesn't have more content */ + return; + + case INFO_REPLY: + printf("%s INFO_REPLY", ipaddr_string(&(bp->refid))); + /* this is too complex to be worth printing */ + return; + + default: + printf("%s", ipaddr_string(&(bp->refid))); + break; + } + + TCHECK(bp->ref_timestamp); + fputs("\n\t Reference Timestamp: ", stdout); + p_ntp_time(&(bp->ref_timestamp)); + + TCHECK(bp->org_timestamp); + fputs("\n\t Originator Timestamp: ", stdout); + p_ntp_time(&(bp->org_timestamp)); + + TCHECK(bp->rec_timestamp); + fputs("\n\t Receive Timestamp: ", stdout); + p_ntp_time(&(bp->rec_timestamp)); + + TCHECK(bp->xmt_timestamp); + fputs("\n\t Transmit Timestamp: ", stdout); + p_ntp_time(&(bp->xmt_timestamp)); + + fputs("\n\t Originator - Receive Timestamp: ", stdout); + p_ntp_delta(&(bp->org_timestamp), &(bp->rec_timestamp)); + + fputs("\n\t Originator - Transmit Timestamp: ", stdout); + p_ntp_delta(&(bp->org_timestamp), &(bp->xmt_timestamp)); + + if ( (sizeof(struct ntpdata) - length) == 16) { /* Optional: key-id */ + TCHECK(bp->key_id); + printf("\n\tKey id: %u", bp->key_id); + } else if ( (sizeof(struct ntpdata) - length) == 0) { /* Optional: key-id + authentication */ + TCHECK(bp->key_id); + printf("\n\tKey id: %u", bp->key_id); + TCHECK2(bp->message_digest, sizeof (bp->message_digest)); + printf("\n\tAuthentication: %08x%08x%08x%08x", + EXTRACT_32BITS(bp->message_digest), + EXTRACT_32BITS(bp->message_digest + 4), + EXTRACT_32BITS(bp->message_digest + 8), + EXTRACT_32BITS(bp->message_digest + 12)); + } + return; + +trunc: + fputs(" [|ntp]", stdout); +} + +static void +p_sfix(register const struct s_fixedpt *sfp) +{ + register int i; + register int f; + register float ff; + + i = EXTRACT_16BITS(&sfp->int_part); + f = EXTRACT_16BITS(&sfp->fraction); + ff = f / 65536.0; /* shift radix point by 16 bits */ + f = ff * 1000000.0; /* Treat fraction as parts per million */ + printf("%d.%06d", i, f); +} + +#define FMAXINT (4294967296.0) /* floating point rep. of MAXINT */ + +static void +p_ntp_time(register const struct l_fixedpt *lfp) +{ + register int32_t i; + register u_int32_t uf; + register u_int32_t f; + register float ff; + + i = EXTRACT_32BITS(&lfp->int_part); + uf = EXTRACT_32BITS(&lfp->fraction); + ff = uf; + if (ff < 0.0) /* some compilers are buggy */ + ff += FMAXINT; + ff = ff / FMAXINT; /* shift radix point by 32 bits */ + f = ff * 1000000000.0; /* treat fraction as parts per billion */ + printf("%u.%09d", i, f); + +#ifdef HAVE_STRFTIME + /* + * print the time in human-readable format. + */ + if (i) { + time_t seconds = i - JAN_1970; + struct tm *tm; + char time_buf[128]; + + tm = localtime(&seconds); + strftime(time_buf, sizeof (time_buf), "%Y/%m/%d %H:%M:%S", tm); + printf (" (%s)", time_buf); + } +#endif +} + +/* Prints time difference between *lfp and *olfp */ +static void +p_ntp_delta(register const struct l_fixedpt *olfp, + register const struct l_fixedpt *lfp) +{ + register int32_t i; + register u_int32_t u, uf; + register u_int32_t ou, ouf; + register u_int32_t f; + register float ff; + int signbit; + + u = EXTRACT_32BITS(&lfp->int_part); + ou = EXTRACT_32BITS(&olfp->int_part); + uf = EXTRACT_32BITS(&lfp->fraction); + ouf = EXTRACT_32BITS(&olfp->fraction); + if (ou == 0 && ouf == 0) { + p_ntp_time(lfp); + return; + } + + i = u - ou; + + if (i > 0) { /* new is definitely greater than old */ + signbit = 0; + f = uf - ouf; + if (ouf > uf) /* must borrow from high-order bits */ + i -= 1; + } else if (i < 0) { /* new is definitely less than old */ + signbit = 1; + f = ouf - uf; + if (uf > ouf) /* must carry into the high-order bits */ + i += 1; + i = -i; + } else { /* int_part is zero */ + if (uf > ouf) { + signbit = 0; + f = uf - ouf; + } else { + signbit = 1; + f = ouf - uf; + } + } + + ff = f; + if (ff < 0.0) /* some compilers are buggy */ + ff += FMAXINT; + ff = ff / FMAXINT; /* shift radix point by 32 bits */ + f = ff * 1000000000.0; /* treat fraction as parts per billion */ + if (signbit) + putchar('-'); + else + putchar('+'); + printf("%d.%09d", i, f); +} + diff --git a/print-null.c b/print-null.c new file mode 100644 index 0000000..a69997d --- /dev/null +++ b/print-null.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-null.c,v 1.57 2006-03-23 14:58:44 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" + +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif +#include "af.h" + +/* + * The DLT_NULL packet header is 4 bytes long. It contains a host-byte-order + * 32-bit integer that specifies the family, e.g. AF_INET. + * + * Note here that "host" refers to the host on which the packets were + * captured; that isn't necessarily *this* host. + * + * The OpenBSD DLT_LOOP packet header is the same, except that the integer + * is in network byte order. + */ +#define NULL_HDRLEN 4 + +/* + * Byte-swap a 32-bit number. + * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on + * big-endian platforms.) + */ +#define SWAPLONG(y) \ +((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) + +static inline void +null_hdr_print(u_int family, u_int length) +{ + if (!qflag) { + (void)printf("AF %s (%u)", + tok2str(bsd_af_values,"Unknown",family),family); + } else { + (void)printf("%s", + tok2str(bsd_af_values,"Unknown AF %u",family)); + } + + (void)printf(", length %u: ", length); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +null_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int length = h->len; + u_int caplen = h->caplen; + u_int family; + + if (caplen < NULL_HDRLEN) { + printf("[|null]"); + return (NULL_HDRLEN); + } + + memcpy((char *)&family, (char *)p, sizeof(family)); + + /* + * This isn't necessarily in our host byte order; if this is + * a DLT_LOOP capture, it's in network byte order, and if + * this is a DLT_NULL capture from a machine with the opposite + * byte-order, it's in the opposite byte order from ours. + * + * If the upper 16 bits aren't all zero, assume it's byte-swapped. + */ + if ((family & 0xFFFF0000) != 0) + family = SWAPLONG(family); + + if (eflag) + null_hdr_print(family, length); + + length -= NULL_HDRLEN; + caplen -= NULL_HDRLEN; + p += NULL_HDRLEN; + + switch (family) { + + case BSD_AFNUM_INET: + ip_print(gndo, p, length); + break; + +#ifdef INET6 + case BSD_AFNUM_INET6_BSD: + case BSD_AFNUM_INET6_FREEBSD: + case BSD_AFNUM_INET6_DARWIN: + ip6_print(p, length); + break; +#endif + + case BSD_AFNUM_ISO: + isoclns_print(p, length, caplen); + break; + + case BSD_AFNUM_APPLETALK: + atalk_print(p, length); + break; + + case BSD_AFNUM_IPX: + ipx_print(p, length); + break; + + default: + /* unknown AF_ value */ + if (!eflag) + null_hdr_print(family, length + NULL_HDRLEN); + if (!suppress_default_print) + default_print(p, caplen); + } + + return (NULL_HDRLEN); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-olsr.c b/print-olsr.c new file mode 100644 index 0000000..ba0ed2b --- /dev/null +++ b/print-olsr.c @@ -0,0 +1,626 @@ +/* + * Copyright (c) 1998-2007 The TCPDUMP project + * Copyright (c) 2009 Florian Forster + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Optimized Link State Protocl (OLSR) as per rfc3626 + * + * Original code by Hannes Gredler + * IPv6 additions by Florian Forster + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "ip.h" + +/* + * RFC 3626 common header + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Packet Length | Packet Sequence Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message Type | Vtime | Message Size | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Originator Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Time To Live | Hop Count | Message Sequence Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * : MESSAGE : + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message Type | Vtime | Message Size | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Originator Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Time To Live | Hop Count | Message Sequence Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * : MESSAGE : + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * : : + */ + +struct olsr_common { + u_int8_t packet_len[2]; + u_int8_t packet_seq[2]; +}; + +#define OLSR_HELLO_MSG 1 /* rfc3626 */ +#define OLSR_TC_MSG 2 /* rfc3626 */ +#define OLSR_MID_MSG 3 /* rfc3626 */ +#define OLSR_HNA_MSG 4 /* rfc3626 */ +#define OLSR_POWERINFO_MSG 128 +#define OLSR_NAMESERVICE_MSG 130 +#define OLSR_HELLO_LQ_MSG 201 /* LQ extensions olsr.org */ +#define OLSR_TC_LQ_MSG 202 /* LQ extensions olsr.org */ + +static struct tok olsr_msg_values[] = { + { OLSR_HELLO_MSG, "Hello" }, + { OLSR_TC_MSG, "TC" }, + { OLSR_MID_MSG, "MID" }, + { OLSR_HNA_MSG, "HNA" }, + { OLSR_POWERINFO_MSG, "Powerinfo" }, + { OLSR_NAMESERVICE_MSG, "Nameservice" }, + { OLSR_HELLO_LQ_MSG, "Hello-LQ" }, + { OLSR_TC_LQ_MSG, "TC-LQ" }, + { 0, NULL} +}; + +struct olsr_msg4 { + u_int8_t msg_type; + u_int8_t vtime; + u_int8_t msg_len[2]; + u_int8_t originator[4]; + u_int8_t ttl; + u_int8_t hopcount; + u_int8_t msg_seq[2]; +}; + +struct olsr_msg6 { + u_int8_t msg_type; + u_int8_t vtime; + u_int8_t msg_len[2]; + u_int8_t originator[16]; + u_int8_t ttl; + u_int8_t hopcount; + u_int8_t msg_seq[2]; +}; + +struct olsr_hello { + u_int8_t res[2]; + u_int8_t htime; + u_int8_t will; +}; + +struct olsr_hello_link { + u_int8_t link_code; + u_int8_t res; + u_int8_t len[2]; +}; + +struct olsr_tc { + u_int8_t ans_seq[2]; + u_int8_t res[2]; +}; + +struct olsr_hna4 { + u_int8_t network[4]; + u_int8_t mask[4]; +}; + +struct olsr_hna6 { + u_int8_t network[16]; + u_int8_t mask[16]; +}; + + +#define OLSR_EXTRACT_LINK_TYPE(link_code) (link_code & 0x3) +#define OLSR_EXTRACT_NEIGHBOR_TYPE(link_code) (link_code >> 2) + +static struct tok olsr_link_type_values[] = { + { 0, "Unspecified" }, + { 1, "Asymmetric" }, + { 2, "Symmetric" }, + { 3, "Lost" }, + { 0, NULL} +}; + +static struct tok olsr_neighbor_type_values[] = { + { 0, "Not-Neighbor" }, + { 1, "Symmetric" }, + { 2, "Symmetric-MPR" }, + { 0, NULL} +}; + +struct olsr_lq_neighbor4 { + u_int8_t neighbor[4]; + u_int8_t link_quality; + u_int8_t neighbor_link_quality; + u_int8_t res[2]; +}; + +struct olsr_lq_neighbor6 { + u_int8_t neighbor[16]; + u_int8_t link_quality; + u_int8_t neighbor_link_quality; + u_int8_t res[2]; +}; + +/* + * macro to convert the 8-bit mantissa/exponent to a double float + * taken from olsr.org. + */ +#define VTIME_SCALE_FACTOR 0.0625 +#define ME_TO_DOUBLE(me) \ + (double)(VTIME_SCALE_FACTOR*(1+(double)(me>>4)/16)*(double)(1<<(me&0x0F))) + +/* + * print a neighbor list with LQ extensions. + */ +static void +olsr_print_lq_neighbor4 (const u_char *msg_data, u_int hello_len) +{ + struct olsr_lq_neighbor4 *lq_neighbor; + + while (hello_len >= sizeof(struct olsr_lq_neighbor4)) { + + lq_neighbor = (struct olsr_lq_neighbor4 *)msg_data; + + printf("\n\t neighbor %s, link-quality %.2lf%%" + ", neighbor-link-quality %.2lf%%", + ipaddr_string(lq_neighbor->neighbor), + ((double)lq_neighbor->link_quality/2.55), + ((double)lq_neighbor->neighbor_link_quality/2.55)); + + msg_data += sizeof(struct olsr_lq_neighbor4); + hello_len -= sizeof(struct olsr_lq_neighbor4); + } +} + +#if INET6 +static void +olsr_print_lq_neighbor6 (const u_char *msg_data, u_int hello_len) +{ + struct olsr_lq_neighbor6 *lq_neighbor; + + while (hello_len >= sizeof(struct olsr_lq_neighbor6)) { + + lq_neighbor = (struct olsr_lq_neighbor6 *)msg_data; + + printf("\n\t neighbor %s, link-quality %.2lf%%" + ", neighbor-link-quality %.2lf%%", + ip6addr_string(lq_neighbor->neighbor), + ((double)lq_neighbor->link_quality/2.55), + ((double)lq_neighbor->neighbor_link_quality/2.55)); + + msg_data += sizeof(struct olsr_lq_neighbor6); + hello_len -= sizeof(struct olsr_lq_neighbor6); + } +} +#endif /* INET6 */ + +/* + * print a neighbor list. + */ +static void +olsr_print_neighbor (const u_char *msg_data, u_int hello_len) +{ + int neighbor; + + printf("\n\t neighbor\n\t\t"); + neighbor = 1; + + while (hello_len >= sizeof(struct in_addr)) { + + /* print 4 neighbors per line */ + + printf("%s%s", ipaddr_string(msg_data), + neighbor % 4 == 0 ? "\n\t\t" : " "); + + msg_data += sizeof(struct in_addr); + hello_len -= sizeof(struct in_addr); + } +} + + +void +olsr_print (const u_char *pptr, u_int length, int is_ipv6) +{ + union { + const struct olsr_common *common; + const struct olsr_msg4 *msg4; + const struct olsr_msg6 *msg6; + const struct olsr_hello *hello; + const struct olsr_hello_link *hello_link; + const struct olsr_tc *tc; + const struct olsr_hna4 *hna; + } ptr; + + u_int msg_type, msg_len, msg_tlen, hello_len; + u_int16_t name_entry_type, name_entry_len; + u_int name_entry_padding; + u_int8_t link_type, neighbor_type; + const u_char *tptr, *msg_data; + + tptr = pptr; + + if (length < sizeof(struct olsr_common)) { + goto trunc; + } + + if (!TTEST2(*tptr, sizeof(struct olsr_common))) { + goto trunc; + } + + ptr.common = (struct olsr_common *)tptr; + length = MIN(length, EXTRACT_16BITS(ptr.common->packet_len)); + + printf("OLSRv%i, seq 0x%04x, length %u", + (is_ipv6 == 0) ? 4 : 6, + EXTRACT_16BITS(ptr.common->packet_seq), + length); + + tptr += sizeof(struct olsr_common); + + /* + * In non-verbose mode, just print version. + */ + if (vflag < 1) { + return; + } + + while (tptr < (pptr+length)) { + union + { + struct olsr_msg4 *v4; + struct olsr_msg6 *v6; + } msgptr; + int msg_len_valid = 0; + + if (!TTEST2(*tptr, sizeof(struct olsr_msg4))) + goto trunc; + +#if INET6 + if (is_ipv6) + { + msgptr.v6 = (struct olsr_msg6 *) tptr; + msg_type = msgptr.v6->msg_type; + msg_len = EXTRACT_16BITS(msgptr.v6->msg_len); + if ((msg_len >= sizeof (struct olsr_msg6)) + && (msg_len <= length)) + msg_len_valid = 1; + + /* infinite loop check */ + if (msg_type == 0 || msg_len == 0) { + return; + } + + printf("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" + "\n\t vtime %.3lfs, msg-seq 0x%04x, length %u%s", + tok2str(olsr_msg_values, "Unknown", msg_type), + msg_type, ip6addr_string(msgptr.v6->originator), + msgptr.v6->ttl, + msgptr.v6->hopcount, + ME_TO_DOUBLE(msgptr.v6->vtime), + EXTRACT_16BITS(msgptr.v6->msg_seq), + msg_len, (msg_len_valid == 0) ? " (invalid)" : ""); + + msg_tlen = msg_len - sizeof(struct olsr_msg6); + msg_data = tptr + sizeof(struct olsr_msg6); + } + else /* (!is_ipv6) */ +#endif /* INET6 */ + { + msgptr.v4 = (struct olsr_msg4 *) tptr; + msg_type = msgptr.v4->msg_type; + msg_len = EXTRACT_16BITS(msgptr.v4->msg_len); + if ((msg_len >= sizeof (struct olsr_msg4)) + && (msg_len <= length)) + msg_len_valid = 1; + + /* infinite loop check */ + if (msg_type == 0 || msg_len == 0) { + return; + } + + printf("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u" + "\n\t vtime %.3lfs, msg-seq 0x%04x, length %u%s", + tok2str(olsr_msg_values, "Unknown", msg_type), + msg_type, ipaddr_string(msgptr.v4->originator), + msgptr.v4->ttl, + msgptr.v4->hopcount, + ME_TO_DOUBLE(msgptr.v4->vtime), + EXTRACT_16BITS(msgptr.v4->msg_seq), + msg_len, (msg_len_valid == 0) ? " (invalid)" : ""); + + msg_tlen = msg_len - sizeof(struct olsr_msg4); + msg_data = tptr + sizeof(struct olsr_msg4); + } + + switch (msg_type) { + case OLSR_HELLO_MSG: + case OLSR_HELLO_LQ_MSG: + if (!TTEST2(*msg_data, sizeof(struct olsr_hello))) + goto trunc; + + ptr.hello = (struct olsr_hello *)msg_data; + printf("\n\t hello-time %.3lfs, MPR willingness %u", + ME_TO_DOUBLE(ptr.hello->htime), ptr.hello->will); + msg_data += sizeof(struct olsr_hello); + msg_tlen -= sizeof(struct olsr_hello); + + while (msg_tlen >= sizeof(struct olsr_hello_link)) { + int hello_len_valid = 0; + + /* + * link-type. + */ + if (!TTEST2(*msg_data, sizeof(struct olsr_hello_link))) + goto trunc; + + ptr.hello_link = (struct olsr_hello_link *)msg_data; + + hello_len = EXTRACT_16BITS(ptr.hello_link->len); + link_type = OLSR_EXTRACT_LINK_TYPE(ptr.hello_link->link_code); + neighbor_type = OLSR_EXTRACT_NEIGHBOR_TYPE(ptr.hello_link->link_code); + + if ((hello_len <= msg_tlen) + && (hello_len >= sizeof(struct olsr_hello_link))) + hello_len_valid = 1; + + printf("\n\t link-type %s, neighbor-type %s, len %u%s", + tok2str(olsr_link_type_values, "Unknown", link_type), + tok2str(olsr_neighbor_type_values, "Unknown", neighbor_type), + hello_len, + (hello_len_valid == 0) ? " (invalid)" : ""); + + if (hello_len_valid == 0) + break; + + msg_data += sizeof(struct olsr_hello_link); + msg_tlen -= sizeof(struct olsr_hello_link); + hello_len -= sizeof(struct olsr_hello_link); + + if (msg_type == OLSR_HELLO_MSG) { + olsr_print_neighbor(msg_data, hello_len); + } else { +#if INET6 + if (is_ipv6) + olsr_print_lq_neighbor6(msg_data, hello_len); + else +#endif + olsr_print_lq_neighbor4(msg_data, hello_len); + } + + msg_data += hello_len; + msg_tlen -= hello_len; + } + break; + + case OLSR_TC_MSG: + case OLSR_TC_LQ_MSG: + if (!TTEST2(*msg_data, sizeof(struct olsr_tc))) + goto trunc; + + ptr.tc = (struct olsr_tc *)msg_data; + printf("\n\t advertised neighbor seq 0x%04x", + EXTRACT_16BITS(ptr.tc->ans_seq)); + msg_data += sizeof(struct olsr_tc); + msg_tlen -= sizeof(struct olsr_tc); + + if (msg_type == OLSR_TC_MSG) { + olsr_print_neighbor(msg_data, msg_tlen); + } else { +#if INET6 + if (is_ipv6) + olsr_print_lq_neighbor6(msg_data, msg_tlen); + else +#endif + olsr_print_lq_neighbor4(msg_data, msg_tlen); + } + break; + + case OLSR_MID_MSG: + { + size_t addr_size = sizeof(struct in_addr); + +#if INET6 + if (is_ipv6) + addr_size = sizeof(struct in6_addr); +#endif + + while (msg_tlen >= addr_size) { + if (!TTEST2(*msg_data, addr_size)) + goto trunc; + + printf("\n\t interface address %s", +#if INET6 + is_ipv6 ? ip6addr_string(msg_data) : +#endif + ipaddr_string(msg_data)); + msg_data += addr_size; + msg_tlen -= addr_size; + } + break; + } + + case OLSR_HNA_MSG: + printf("\n\t Advertised networks (total %u)", + (unsigned int) (msg_tlen / sizeof(struct olsr_hna6))); +#if INET6 + if (is_ipv6) + { + int i = 0; + while (msg_tlen >= sizeof(struct olsr_hna6)) { + struct olsr_hna6 *hna6; + + if (!TTEST2(*msg_data, sizeof(struct olsr_hna6))) + goto trunc; + + hna6 = (struct olsr_hna6 *)msg_data; + + printf("\n\t #%i: %s/%u", + i, ip6addr_string(hna6->network), + mask62plen (hna6->mask)); + + msg_data += sizeof(struct olsr_hna6); + msg_tlen -= sizeof(struct olsr_hna6); + } + } + else +#endif + { + int col = 0; + while (msg_tlen >= sizeof(struct olsr_hna4)) { + if (!TTEST2(*msg_data, sizeof(struct olsr_hna4))) + goto trunc; + + ptr.hna = (struct olsr_hna4 *)msg_data; + + /* print 4 prefixes per line */ + if (col == 0) + printf ("\n\t "); + else + printf (", "); + + printf("%s/%u", + ipaddr_string(ptr.hna->network), + mask2plen(EXTRACT_32BITS(ptr.hna->mask))); + + msg_data += sizeof(struct olsr_hna4); + msg_tlen -= sizeof(struct olsr_hna4); + + col = (col + 1) % 4; + } + } + break; + + case OLSR_NAMESERVICE_MSG: + { + u_int name_entries = EXTRACT_16BITS(msg_data+2); + u_int addr_size = 4; + int name_entries_valid = 0; + u_int i; + + if (is_ipv6) + addr_size = 16; + + if ((name_entries > 0) + && ((name_entries * (4 + addr_size)) <= msg_tlen)) + name_entries_valid = 1; + + if (msg_tlen < 4) + goto trunc; + if (!TTEST2(*msg_data, 4)) + goto trunc; + + printf("\n\t Version %u, Entries %u%s", + EXTRACT_16BITS(msg_data), + name_entries, (name_entries_valid == 0) ? " (invalid)" : ""); + + if (name_entries_valid == 0) + break; + + msg_data += 4; + msg_tlen -= 4; + + for (i = 0; i < name_entries; i++) { + int name_entry_len_valid = 0; + + if (msg_tlen < 4) + break; + if (!TTEST2(*msg_data, 4)) + goto trunc; + + name_entry_type = EXTRACT_16BITS(msg_data); + name_entry_len = EXTRACT_16BITS(msg_data+2); + + msg_data += 4; + msg_tlen -= 4; + + if ((name_entry_len > 0) && ((addr_size + name_entry_len) <= msg_tlen)) + name_entry_len_valid = 1; + + printf("\n\t #%u: type %#06x, length %u%s", + (unsigned int) i, name_entry_type, + name_entry_len, (name_entry_len_valid == 0) ? " (invalid)" : ""); + + if (name_entry_len_valid == 0) + break; + + /* 32-bit alignment */ + name_entry_padding = 0; + if (name_entry_len%4 != 0) + name_entry_padding = 4-(name_entry_len%4); + + if (msg_tlen < addr_size + name_entry_len + name_entry_padding) + goto trunc; + + if (!TTEST2(*msg_data, addr_size + name_entry_len + name_entry_padding)) + goto trunc; + +#if INET6 + if (is_ipv6) + printf(", address %s, name \"", + ip6addr_string(msg_data)); + else +#endif + printf(", address %s, name \"", + ipaddr_string(msg_data)); + fn_printn(msg_data + addr_size, name_entry_len, NULL); + printf("\""); + + msg_data += addr_size + name_entry_len + name_entry_padding; + msg_tlen -= addr_size + name_entry_len + name_entry_padding; + } /* for (i = 0; i < name_entries; i++) */ + break; + } /* case OLSR_NAMESERVICE_MSG */ + + /* + * FIXME those are the defined messages that lack a decoder + * you are welcome to contribute code ;-) + */ + case OLSR_POWERINFO_MSG: + default: + print_unknown_data(msg_data, "\n\t ", msg_tlen); + break; + } /* switch (msg_type) */ + tptr += msg_len; + } /* while (tptr < (pptr+length)) */ + + return; + + trunc: + printf("[|olsr]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/print-ospf.c b/print-ospf.c new file mode 100644 index 0000000..983c14f --- /dev/null +++ b/print-ospf.c @@ -0,0 +1,1157 @@ +/* + * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ospf.c,v 1.66 2007-10-08 07:53:21 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "gmpls.h" + +#include "ospf.h" + +#include "ip.h" + +static struct tok ospf_option_values[] = { + { OSPF_OPTION_T, "MultiTopology" }, /* draft-ietf-ospf-mt-09 */ + { OSPF_OPTION_E, "External" }, + { OSPF_OPTION_MC, "Multicast" }, + { OSPF_OPTION_NP, "NSSA" }, + { OSPF_OPTION_L, "LLS" }, + { OSPF_OPTION_DC, "Demand Circuit" }, + { OSPF_OPTION_O, "Opaque" }, + { OSPF_OPTION_DN, "Up/Down" }, + { 0, NULL } +}; + +static struct tok ospf_authtype_values[] = { + { OSPF_AUTH_NONE, "none" }, + { OSPF_AUTH_SIMPLE, "simple" }, + { OSPF_AUTH_MD5, "MD5" }, + { 0, NULL } +}; + +static struct tok ospf_rla_flag_values[] = { + { RLA_FLAG_B, "ABR" }, + { RLA_FLAG_E, "ASBR" }, + { RLA_FLAG_W1, "Virtual" }, + { RLA_FLAG_W2, "W2" }, + { 0, NULL } +}; + +static struct tok type2str[] = { + { OSPF_TYPE_UMD, "UMD" }, + { OSPF_TYPE_HELLO, "Hello" }, + { OSPF_TYPE_DD, "Database Description" }, + { OSPF_TYPE_LS_REQ, "LS-Request" }, + { OSPF_TYPE_LS_UPDATE, "LS-Update" }, + { OSPF_TYPE_LS_ACK, "LS-Ack" }, + { 0, NULL } +}; + +static struct tok lsa_values[] = { + { LS_TYPE_ROUTER, "Router" }, + { LS_TYPE_NETWORK, "Network" }, + { LS_TYPE_SUM_IP, "Summary" }, + { LS_TYPE_SUM_ABR, "ASBR Summary" }, + { LS_TYPE_ASE, "External" }, + { LS_TYPE_GROUP, "Multicast Group" }, + { LS_TYPE_NSSA, "NSSA" }, + { LS_TYPE_OPAQUE_LL, "Link Local Opaque" }, + { LS_TYPE_OPAQUE_AL, "Area Local Opaque" }, + { LS_TYPE_OPAQUE_DW, "Domain Wide Opaque" }, + { 0, NULL } +}; + +static struct tok ospf_dd_flag_values[] = { + { OSPF_DB_INIT, "Init" }, + { OSPF_DB_MORE, "More" }, + { OSPF_DB_MASTER, "Master" }, + { OSPF_DB_RESYNC, "OOBResync" }, + { 0, NULL } +}; + +static struct tok lsa_opaque_values[] = { + { LS_OPAQUE_TYPE_TE, "Traffic Engineering" }, + { LS_OPAQUE_TYPE_GRACE, "Graceful restart" }, + { LS_OPAQUE_TYPE_RI, "Router Information" }, + { 0, NULL } +}; + +static struct tok lsa_opaque_te_tlv_values[] = { + { LS_OPAQUE_TE_TLV_ROUTER, "Router Address" }, + { LS_OPAQUE_TE_TLV_LINK, "Link" }, + { 0, NULL } +}; + +static struct tok lsa_opaque_te_link_tlv_subtlv_values[] = { + { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE, "Link Type" }, + { LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID, "Link ID" }, + { LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP, "Local Interface IP address" }, + { LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP, "Remote Interface IP address" }, + { LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC, "Traffic Engineering Metric" }, + { LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW, "Maximum Bandwidth" }, + { LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW, "Maximum Reservable Bandwidth" }, + { LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW, "Unreserved Bandwidth" }, + { LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP, "Administrative Group" }, + { LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" }, + { LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE, "Link Protection Type" }, + { LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR, "Interface Switching Capability" }, + { LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP, "Shared Risk Link Group" }, + { LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS, "Bandwidth Constraints" }, + { 0, NULL } +}; + +static struct tok lsa_opaque_grace_tlv_values[] = { + { LS_OPAQUE_GRACE_TLV_PERIOD, "Grace Period" }, + { LS_OPAQUE_GRACE_TLV_REASON, "Graceful restart Reason" }, + { LS_OPAQUE_GRACE_TLV_INT_ADDRESS, "IPv4 interface address" }, + { 0, NULL } +}; + +static struct tok lsa_opaque_grace_tlv_reason_values[] = { + { LS_OPAQUE_GRACE_TLV_REASON_UNKNOWN, "Unknown" }, + { LS_OPAQUE_GRACE_TLV_REASON_SW_RESTART, "Software Restart" }, + { LS_OPAQUE_GRACE_TLV_REASON_SW_UPGRADE, "Software Reload/Upgrade" }, + { LS_OPAQUE_GRACE_TLV_REASON_CP_SWITCH, "Control Processor Switch" }, + { 0, NULL } +}; + +static struct tok lsa_opaque_te_tlv_link_type_sub_tlv_values[] = { + { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_PTP, "Point-to-point" }, + { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_MA, "Multi-Access" }, + { 0, NULL } +}; + +static struct tok lsa_opaque_ri_tlv_values[] = { + { LS_OPAQUE_RI_TLV_CAP, "Router Capabilities" }, + { 0, NULL } +}; + +static struct tok lsa_opaque_ri_tlv_cap_values[] = { + { 1, "Reserved" }, + { 2, "Reserved" }, + { 4, "Reserved" }, + { 8, "Reserved" }, + { 16, "graceful restart capable" }, + { 32, "graceful restart helper" }, + { 64, "Stub router support" }, + { 128, "Traffic engineering" }, + { 256, "p2p over LAN" }, + { 512, "path computation server" }, + { 0, NULL } +}; + +static struct tok ospf_lls_tlv_values[] = { + { OSPF_LLS_EO, "Extended Options" }, + { OSPF_LLS_MD5, "MD5 Authentication" }, + { 0, NULL } +}; + +static struct tok ospf_lls_eo_options[] = { + { OSPF_LLS_EO_LR, "LSDB resync" }, + { OSPF_LLS_EO_RS, "Restart" }, + { 0, NULL } +}; + +static char tstr[] = " [|ospf2]"; + +#ifdef WIN32 +#define inline __inline +#endif /* WIN32 */ + +static int ospf_print_lshdr(const struct lsa_hdr *); +static const u_char *ospf_print_lsa(const struct lsa *); +static int ospf_decode_v2(const struct ospfhdr *, const u_char *); +static int ospf_decode_lls(const struct ospfhdr *, register u_int); + +int +ospf_print_grace_lsa (u_int8_t *tptr, u_int ls_length) { + + u_int tlv_type, tlv_length; + + + while (ls_length > 0) { + TCHECK2(*tptr, 4); + if (ls_length < 4) { + printf("\n\t Remaining LS length %u < 4", ls_length); + return -1; + } + tlv_type = EXTRACT_16BITS(tptr); + tlv_length = EXTRACT_16BITS(tptr+2); + tptr+=4; + ls_length-=4; + + printf("\n\t %s TLV (%u), length %u, value: ", + tok2str(lsa_opaque_grace_tlv_values,"unknown",tlv_type), + tlv_type, + tlv_length); + + if (tlv_length > ls_length) { + printf("\n\t Bogus length %u > %u", tlv_length, + ls_length); + return -1; + } + + /* Infinite loop protection. */ + if (tlv_type == 0 || tlv_length ==0) { + return -1; + } + + TCHECK2(*tptr, tlv_length); + switch(tlv_type) { + + case LS_OPAQUE_GRACE_TLV_PERIOD: + if (tlv_length != 4) { + printf("\n\t Bogus length %u != 4", tlv_length); + return -1; + } + printf("%us",EXTRACT_32BITS(tptr)); + break; + + case LS_OPAQUE_GRACE_TLV_REASON: + if (tlv_length != 1) { + printf("\n\t Bogus length %u != 1", tlv_length); + return -1; + } + printf("%s (%u)", + tok2str(lsa_opaque_grace_tlv_reason_values, "Unknown", *tptr), + *tptr); + break; + + case LS_OPAQUE_GRACE_TLV_INT_ADDRESS: + if (tlv_length != 4) { + printf("\n\t Bogus length %u != 4", tlv_length); + return -1; + } + printf("%s", ipaddr_string(tptr)); + break; + + default: + if (vflag <= 1) { + if(!print_unknown_data(tptr,"\n\t ",tlv_length)) + return -1; + } + break; + + } + /* in OSPF everything has to be 32-bit aligned, including TLVs */ + if (tlv_length%4 != 0) + tlv_length+=4-(tlv_length%4); + ls_length-=tlv_length; + tptr+=tlv_length; + } + + return 0; +trunc: + return -1; +} + +int +ospf_print_te_lsa (u_int8_t *tptr, u_int ls_length) { + + u_int tlv_type, tlv_length, subtlv_type, subtlv_length; + u_int priority_level, te_class, count_srlg; + union { /* int to float conversion buffer for several subTLVs */ + float f; + u_int32_t i; + } bw; + + while (ls_length != 0) { + TCHECK2(*tptr, 4); + if (ls_length < 4) { + printf("\n\t Remaining LS length %u < 4", ls_length); + return -1; + } + tlv_type = EXTRACT_16BITS(tptr); + tlv_length = EXTRACT_16BITS(tptr+2); + tptr+=4; + ls_length-=4; + + printf("\n\t %s TLV (%u), length: %u", + tok2str(lsa_opaque_te_tlv_values,"unknown",tlv_type), + tlv_type, + tlv_length); + + if (tlv_length > ls_length) { + printf("\n\t Bogus length %u > %u", tlv_length, + ls_length); + return -1; + } + + /* Infinite loop protection. */ + if (tlv_type == 0 || tlv_length ==0) { + return -1; + } + + switch(tlv_type) { + case LS_OPAQUE_TE_TLV_LINK: + while (tlv_length >= sizeof(subtlv_type) + sizeof(subtlv_length)) { + if (tlv_length < 4) { + printf("\n\t Remaining TLV length %u < 4", + tlv_length); + return -1; + } + TCHECK2(*tptr, 4); + subtlv_type = EXTRACT_16BITS(tptr); + subtlv_length = EXTRACT_16BITS(tptr+2); + tptr+=4; + tlv_length-=4; + + printf("\n\t %s subTLV (%u), length: %u", + tok2str(lsa_opaque_te_link_tlv_subtlv_values,"unknown",subtlv_type), + subtlv_type, + subtlv_length); + + TCHECK2(*tptr, subtlv_length); + switch(subtlv_type) { + case LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP: + printf(", 0x%08x", EXTRACT_32BITS(tptr)); + break; + case LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID: + case LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID: + printf(", %s (0x%08x)", + ipaddr_string(tptr), + EXTRACT_32BITS(tptr)); + if (subtlv_length == 8) /* rfc4203 */ + printf(", %s (0x%08x)", + ipaddr_string(tptr+4), + EXTRACT_32BITS(tptr+4)); + break; + case LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP: + case LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP: + printf(", %s", ipaddr_string(tptr)); + break; + case LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW: + case LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW: + bw.i = EXTRACT_32BITS(tptr); + printf(", %.3f Mbps", bw.f*8/1000000 ); + break; + case LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW: + for (te_class = 0; te_class < 8; te_class++) { + bw.i = EXTRACT_32BITS(tptr+te_class*4); + printf("\n\t\tTE-Class %u: %.3f Mbps", + te_class, + bw.f*8/1000000 ); + } + break; + case LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS: + printf("\n\t\tBandwidth Constraints Model ID: %s (%u)", + tok2str(diffserv_te_bc_values, "unknown", *tptr), + *tptr); + /* decode BCs until the subTLV ends */ + for (te_class = 0; te_class < (subtlv_length-4)/4; te_class++) { + bw.i = EXTRACT_32BITS(tptr+4+te_class*4); + printf("\n\t\t Bandwidth constraint CT%u: %.3f Mbps", + te_class, + bw.f*8/1000000 ); + } + break; + case LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC: + printf(", Metric %u", EXTRACT_32BITS(tptr)); + break; + case LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE: + printf(", %s, Priority %u", + bittok2str(gmpls_link_prot_values, "none", *tptr), + *(tptr+1)); + break; + case LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR: + printf("\n\t\tInterface Switching Capability: %s", + tok2str(gmpls_switch_cap_values, "Unknown", *(tptr))); + printf("\n\t\tLSP Encoding: %s\n\t\tMax LSP Bandwidth:", + tok2str(gmpls_encoding_values, "Unknown", *(tptr+1))); + for (priority_level = 0; priority_level < 8; priority_level++) { + bw.i = EXTRACT_32BITS(tptr+4+(priority_level*4)); + printf("\n\t\t priority level %d: %.3f Mbps", + priority_level, + bw.f*8/1000000 ); + } + break; + case LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE: + printf(", %s (%u)", + tok2str(lsa_opaque_te_tlv_link_type_sub_tlv_values,"unknown",*tptr), + *tptr); + break; + + case LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP: + count_srlg = subtlv_length / 4; + if (count_srlg != 0) + printf("\n\t\t Shared risk group: "); + while (count_srlg > 0) { + bw.i = EXTRACT_32BITS(tptr); + printf("%d",bw.i); + tptr+=4; + count_srlg--; + if (count_srlg > 0) + printf(", "); + } + break; + + default: + if (vflag <= 1) { + if(!print_unknown_data(tptr,"\n\t\t",subtlv_length)) + return -1; + } + break; + } + /* in OSPF everything has to be 32-bit aligned, including subTLVs */ + if (subtlv_length%4 != 0) + subtlv_length+=4-(subtlv_length%4); + + tlv_length-=subtlv_length; + tptr+=subtlv_length; + + } + break; + + case LS_OPAQUE_TE_TLV_ROUTER: + if (tlv_length < 4) { + printf("\n\t TLV length %u < 4", tlv_length); + return -1; + } + TCHECK2(*tptr, 4); + printf(", %s", ipaddr_string(tptr)); + break; + + default: + if (vflag <= 1) { + if(!print_unknown_data(tptr,"\n\t ",tlv_length)) + return -1; + } + break; + } + /* in OSPF everything has to be 32-bit aligned, including TLVs */ + if (tlv_length%4 != 0) + tlv_length+=4-(tlv_length%4); + ls_length-=tlv_length; + tptr+=tlv_length; + } + return 0; +trunc: + return -1; +} + + +static int +ospf_print_lshdr(register const struct lsa_hdr *lshp) +{ + u_int ls_length; + + TCHECK(lshp->ls_length); + ls_length = EXTRACT_16BITS(&lshp->ls_length); + if (ls_length < sizeof(struct lsa_hdr)) { + printf("\n\t Bogus length %u < header (%lu)", ls_length, + (unsigned long)sizeof(struct lsa_hdr)); + return(-1); + } + + TCHECK(lshp->ls_seq); /* XXX - ls_length check checked this */ + printf("\n\t Advertising Router %s, seq 0x%08x, age %us, length %u", + ipaddr_string(&lshp->ls_router), + EXTRACT_32BITS(&lshp->ls_seq), + EXTRACT_16BITS(&lshp->ls_age), + ls_length-(u_int)sizeof(struct lsa_hdr)); + + TCHECK(lshp->ls_type); /* XXX - ls_length check checked this */ + switch (lshp->ls_type) { + /* the LSA header for opaque LSAs was slightly changed */ + case LS_TYPE_OPAQUE_LL: + case LS_TYPE_OPAQUE_AL: + case LS_TYPE_OPAQUE_DW: + printf("\n\t %s LSA (%d), Opaque-Type %s LSA (%u), Opaque-ID %u", + tok2str(lsa_values,"unknown",lshp->ls_type), + lshp->ls_type, + + tok2str(lsa_opaque_values, + "unknown", + *(&lshp->un_lsa_id.opaque_field.opaque_type)), + *(&lshp->un_lsa_id.opaque_field.opaque_type), + EXTRACT_24BITS(&lshp->un_lsa_id.opaque_field.opaque_id) + + ); + break; + + /* all other LSA types use regular style LSA headers */ + default: + printf("\n\t %s LSA (%d), LSA-ID: %s", + tok2str(lsa_values,"unknown",lshp->ls_type), + lshp->ls_type, + ipaddr_string(&lshp->un_lsa_id.lsa_id)); + break; + } + + TCHECK(lshp->ls_options); /* XXX - ls_length check checked this */ + printf("\n\t Options: [%s]", bittok2str(ospf_option_values,"none",lshp->ls_options)); + + return (ls_length); +trunc: + return (-1); +} + +/* draft-ietf-ospf-mt-09 */ +static struct tok ospf_topology_values[] = { + { 0, "default " }, + { 1, "multicast " }, + { 2, "management " }, + { 0, NULL } +}; + +/* + * Print all the per-topology metrics. + */ +static void +ospf_print_tos_metrics(const union un_tos *tos) +{ + int metric_count; + int toscount; + + toscount = tos->link.link_tos_count+1; + metric_count = 0; + + /* + * All but the first metric contain a valid topology id. + */ + while (toscount) { + printf("\n\t\ttopology %s(%u), metric %u", + tok2str(ospf_topology_values, "", + metric_count ? tos->metrics.tos_type : 0), + metric_count ? tos->metrics.tos_type : 0, + EXTRACT_16BITS(&tos->metrics.tos_metric)); + metric_count++; + tos++; + toscount--; + } +} + +/* + * Print a single link state advertisement. If truncated or if LSA length + * field is less than the length of the LSA header, return NULl, else + * return pointer to data past end of LSA. + */ +static const u_int8_t * +ospf_print_lsa(register const struct lsa *lsap) +{ + register const u_int8_t *ls_end; + register const struct rlalink *rlp; + register const struct in_addr *ap; + register const struct aslametric *almp; + register const struct mcla *mcp; + register const u_int32_t *lp; + register int j, tlv_type, tlv_length, topology; + register int ls_length; + const u_int8_t *tptr; + + tptr = (u_int8_t *)lsap->lsa_un.un_unknown; /* squelch compiler warnings */ + ls_length = ospf_print_lshdr(&lsap->ls_hdr); + if (ls_length == -1) + return(NULL); + ls_end = (u_int8_t *)lsap + ls_length; + ls_length -= sizeof(struct lsa_hdr); + + switch (lsap->ls_hdr.ls_type) { + + case LS_TYPE_ROUTER: + TCHECK(lsap->lsa_un.un_rla.rla_flags); + printf("\n\t Router LSA Options: [%s]", bittok2str(ospf_rla_flag_values,"none",lsap->lsa_un.un_rla.rla_flags)); + + TCHECK(lsap->lsa_un.un_rla.rla_count); + j = EXTRACT_16BITS(&lsap->lsa_un.un_rla.rla_count); + TCHECK(lsap->lsa_un.un_rla.rla_link); + rlp = lsap->lsa_un.un_rla.rla_link; + while (j--) { + TCHECK(*rlp); + switch (rlp->un_tos.link.link_type) { + + case RLA_TYPE_VIRTUAL: + printf("\n\t Virtual Link: Neighbor Router-ID: %s, Interface Address: %s", + ipaddr_string(&rlp->link_id), + ipaddr_string(&rlp->link_data)); + break; + + case RLA_TYPE_ROUTER: + printf("\n\t Neighbor Router-ID: %s, Interface Address: %s", + ipaddr_string(&rlp->link_id), + ipaddr_string(&rlp->link_data)); + break; + + case RLA_TYPE_TRANSIT: + printf("\n\t Neighbor Network-ID: %s, Interface Address: %s", + ipaddr_string(&rlp->link_id), + ipaddr_string(&rlp->link_data)); + break; + + case RLA_TYPE_STUB: + printf("\n\t Stub Network: %s, Mask: %s", + ipaddr_string(&rlp->link_id), + ipaddr_string(&rlp->link_data)); + break; + + default: + printf("\n\t Unknown Router Link Type (%u)", + rlp->un_tos.link.link_type); + return (ls_end); + } + + ospf_print_tos_metrics(&rlp->un_tos); + + rlp = (struct rlalink *)((u_char *)(rlp + 1) + + ((rlp->un_tos.link.link_tos_count) * sizeof(union un_tos))); + } + break; + + case LS_TYPE_NETWORK: + TCHECK(lsap->lsa_un.un_nla.nla_mask); + printf("\n\t Mask %s\n\t Connected Routers:", + ipaddr_string(&lsap->lsa_un.un_nla.nla_mask)); + ap = lsap->lsa_un.un_nla.nla_router; + while ((u_char *)ap < ls_end) { + TCHECK(*ap); + printf("\n\t %s", ipaddr_string(ap)); + ++ap; + } + break; + + case LS_TYPE_SUM_IP: + TCHECK(lsap->lsa_un.un_nla.nla_mask); + printf("\n\t Mask %s", + ipaddr_string(&lsap->lsa_un.un_sla.sla_mask)); + TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); + lp = lsap->lsa_un.un_sla.sla_tosmetric; + while ((u_char *)lp < ls_end) { + register u_int32_t ul; + + TCHECK(*lp); + ul = EXTRACT_32BITS(lp); + topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS; + printf("\n\t\ttopology %s(%u) metric %d", + tok2str(ospf_topology_values, "", topology), + topology, + ul & SLA_MASK_METRIC); + ++lp; + } + break; + + case LS_TYPE_SUM_ABR: + TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); + lp = lsap->lsa_un.un_sla.sla_tosmetric; + while ((u_char *)lp < ls_end) { + register u_int32_t ul; + + TCHECK(*lp); + ul = EXTRACT_32BITS(lp); + topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS; + printf("\n\t\ttopology %s(%u) metric %d", + tok2str(ospf_topology_values, "", topology), + topology, + ul & SLA_MASK_METRIC); + ++lp; + } + break; + + case LS_TYPE_ASE: + case LS_TYPE_NSSA: /* fall through - those LSAs share the same format */ + TCHECK(lsap->lsa_un.un_nla.nla_mask); + printf("\n\t Mask %s", + ipaddr_string(&lsap->lsa_un.un_asla.asla_mask)); + + TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); + almp = lsap->lsa_un.un_asla.asla_metric; + while ((u_char *)almp < ls_end) { + register u_int32_t ul; + + TCHECK(almp->asla_tosmetric); + ul = EXTRACT_32BITS(&almp->asla_tosmetric); + topology = ((ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS); + printf("\n\t\ttopology %s(%u), type %d, metric", + tok2str(ospf_topology_values, "", topology), + topology, + (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1); + if ((ul & ASLA_MASK_METRIC)==0xffffff) + printf(" infinite"); + else + printf(" %d", (ul & ASLA_MASK_METRIC)); + + TCHECK(almp->asla_forward); + if (almp->asla_forward.s_addr) { + printf(", forward %s", + ipaddr_string(&almp->asla_forward)); + } + TCHECK(almp->asla_tag); + if (almp->asla_tag.s_addr) { + printf(", tag %s", + ipaddr_string(&almp->asla_tag)); + } + ++almp; + } + break; + + case LS_TYPE_GROUP: + /* Multicast extensions as of 23 July 1991 */ + mcp = lsap->lsa_un.un_mcla; + while ((u_char *)mcp < ls_end) { + TCHECK(mcp->mcla_vid); + switch (EXTRACT_32BITS(&mcp->mcla_vtype)) { + + case MCLA_VERTEX_ROUTER: + printf("\n\t Router Router-ID %s", + ipaddr_string(&mcp->mcla_vid)); + break; + + case MCLA_VERTEX_NETWORK: + printf("\n\t Network Designated Router %s", + ipaddr_string(&mcp->mcla_vid)); + break; + + default: + printf("\n\t unknown VertexType (%u)", + EXTRACT_32BITS(&mcp->mcla_vtype)); + break; + } + ++mcp; + } + break; + + case LS_TYPE_OPAQUE_LL: /* fall through */ + case LS_TYPE_OPAQUE_AL: + case LS_TYPE_OPAQUE_DW: + + switch (*(&lsap->ls_hdr.un_lsa_id.opaque_field.opaque_type)) { + case LS_OPAQUE_TYPE_RI: + tptr = (u_int8_t *)(&lsap->lsa_un.un_ri_tlv.type); + + while (ls_length != 0) { + TCHECK2(*tptr, 4); + if (ls_length < 4) { + printf("\n\t Remaining LS length %u < 4", ls_length); + return(ls_end); + } + tlv_type = EXTRACT_16BITS(tptr); + tlv_length = EXTRACT_16BITS(tptr+2); + tptr+=4; + ls_length-=4; + + printf("\n\t %s TLV (%u), length: %u, value: ", + tok2str(lsa_opaque_ri_tlv_values,"unknown",tlv_type), + tlv_type, + tlv_length); + + if (tlv_length > ls_length) { + printf("\n\t Bogus length %u > %u", tlv_length, + ls_length); + return(ls_end); + } + TCHECK2(*tptr, tlv_length); + switch(tlv_type) { + + case LS_OPAQUE_RI_TLV_CAP: + if (tlv_length != 4) { + printf("\n\t Bogus length %u != 4", tlv_length); + return(ls_end); + } + printf("Capabilities: %s", + bittok2str(lsa_opaque_ri_tlv_cap_values, "Unknown", EXTRACT_32BITS(tptr))); + break; + default: + if (vflag <= 1) { + if(!print_unknown_data(tptr,"\n\t ",tlv_length)) + return(ls_end); + } + break; + + } + tptr+=tlv_length; + ls_length-=tlv_length; + } + break; + + case LS_OPAQUE_TYPE_GRACE: + if (ospf_print_grace_lsa((u_int8_t *)(&lsap->lsa_un.un_grace_tlv.type), + ls_length) == -1) { + return(ls_end); + } + break; + + case LS_OPAQUE_TYPE_TE: + if (ospf_print_te_lsa((u_int8_t *)(&lsap->lsa_un.un_te_lsa_tlv.type), + ls_length) == -1) { + return(ls_end); + } + break; + + default: + if (vflag <= 1) { + if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown, + "\n\t ", ls_length)) + return(ls_end); + } + break; + } + } + + /* do we want to see an additionally hexdump ? */ + if (vflag> 1) + if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown, + "\n\t ", ls_length)) { + return(ls_end); + } + + return (ls_end); +trunc: + return (NULL); +} + +static int +ospf_decode_lls(register const struct ospfhdr *op, + register u_int length) +{ + register const u_char *dptr; + register const u_char *dataend; + register u_int length2; + register u_int16_t lls_type, lls_len; + register u_int32_t lls_flags; + + switch (op->ospf_type) { + + case OSPF_TYPE_HELLO: + if (!(op->ospf_hello.hello_options & OSPF_OPTION_L)) + return (0); + break; + + case OSPF_TYPE_DD: + if (!(op->ospf_db.db_options & OSPF_OPTION_L)) + return (0); + break; + + default: + return (0); + } + + /* dig deeper if LLS data is available; see RFC4813 */ + length2 = EXTRACT_16BITS(&op->ospf_len); + dptr = (u_char *)op + length2; + dataend = (u_char *)op + length; + + if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) { + dptr = dptr + op->ospf_authdata[3]; + length2 += op->ospf_authdata[3]; + } + if (length2 >= length) { + printf("\n\t[LLS truncated]"); + return (1); + } + TCHECK2(*dptr, 2); + printf("\n\t LLS: checksum: 0x%04x", (u_int)EXTRACT_16BITS(dptr)); + + dptr += 2; + TCHECK2(*dptr, 2); + length2 = EXTRACT_16BITS(dptr); + printf(", length: %u", length2); + + dptr += 2; + TCHECK(*dptr); + while (dptr < dataend) { + TCHECK2(*dptr, 2); + lls_type = EXTRACT_16BITS(dptr); + printf("\n\t %s (%u)", + tok2str(ospf_lls_tlv_values,"Unknown TLV",lls_type), + lls_type); + dptr += 2; + TCHECK2(*dptr, 2); + lls_len = EXTRACT_16BITS(dptr); + printf(", length: %u", lls_len); + dptr += 2; + switch (lls_type) { + + case OSPF_LLS_EO: + if (lls_len != 4) { + printf(" [should be 4]"); + lls_len = 4; + } + TCHECK2(*dptr, 4); + lls_flags = EXTRACT_32BITS(dptr); + printf("\n\t Options: 0x%08x [%s]", lls_flags, + bittok2str(ospf_lls_eo_options,"?",lls_flags)); + + break; + + case OSPF_LLS_MD5: + if (lls_len != 20) { + printf(" [should be 20]"); + lls_len = 20; + } + TCHECK2(*dptr, 4); + printf("\n\t Sequence number: 0x%08x", EXTRACT_32BITS(dptr)); + break; + } + + dptr += lls_len; + } + + return (0); +trunc: + return (1); +} + +static int +ospf_decode_v2(register const struct ospfhdr *op, + register const u_char *dataend) +{ + register const struct in_addr *ap; + register const struct lsr *lsrp; + register const struct lsa_hdr *lshp; + register const struct lsa *lsap; + register u_int32_t lsa_count,lsa_count_max; + + switch (op->ospf_type) { + + case OSPF_TYPE_UMD: + /* + * Rob Coltun's special monitoring packets; + * do nothing + */ + break; + + case OSPF_TYPE_HELLO: + printf("\n\tOptions [%s]", + bittok2str(ospf_option_values,"none",op->ospf_hello.hello_options)); + + TCHECK(op->ospf_hello.hello_deadint); + printf("\n\t Hello Timer %us, Dead Timer %us, Mask %s, Priority %u", + EXTRACT_16BITS(&op->ospf_hello.hello_helloint), + EXTRACT_32BITS(&op->ospf_hello.hello_deadint), + ipaddr_string(&op->ospf_hello.hello_mask), + op->ospf_hello.hello_priority); + + TCHECK(op->ospf_hello.hello_dr); + if (op->ospf_hello.hello_dr.s_addr != 0) + printf("\n\t Designated Router %s", + ipaddr_string(&op->ospf_hello.hello_dr)); + + TCHECK(op->ospf_hello.hello_bdr); + if (op->ospf_hello.hello_bdr.s_addr != 0) + printf(", Backup Designated Router %s", + ipaddr_string(&op->ospf_hello.hello_bdr)); + + ap = op->ospf_hello.hello_neighbor; + if ((u_char *)ap < dataend) + printf("\n\t Neighbor List:"); + while ((u_char *)ap < dataend) { + TCHECK(*ap); + printf("\n\t %s", ipaddr_string(ap)); + ++ap; + } + break; /* HELLO */ + + case OSPF_TYPE_DD: + TCHECK(op->ospf_db.db_options); + printf("\n\tOptions [%s]", + bittok2str(ospf_option_values,"none",op->ospf_db.db_options)); + TCHECK(op->ospf_db.db_flags); + printf(", DD Flags [%s]", + bittok2str(ospf_dd_flag_values,"none",op->ospf_db.db_flags)); + TCHECK(op->ospf_db.db_ifmtu); + if (op->ospf_db.db_ifmtu) { + printf(", MTU: %u", EXTRACT_16BITS(&op->ospf_db.db_ifmtu)); + } + TCHECK(op->ospf_db.db_seq); + printf(", Sequence: 0x%08x", EXTRACT_32BITS(&op->ospf_db.db_seq)); + + /* Print all the LS adv's */ + lshp = op->ospf_db.db_lshdr; + while (((u_char *)lshp < dataend) && ospf_print_lshdr(lshp) != -1) { + ++lshp; + } + break; + + case OSPF_TYPE_LS_REQ: + lsrp = op->ospf_lsr; + while ((u_char *)lsrp < dataend) { + TCHECK(*lsrp); + + printf("\n\t Advertising Router: %s, %s LSA (%u)", + ipaddr_string(&lsrp->ls_router), + tok2str(lsa_values,"unknown",EXTRACT_32BITS(lsrp->ls_type)), + EXTRACT_32BITS(&lsrp->ls_type)); + + switch (EXTRACT_32BITS(lsrp->ls_type)) { + /* the LSA header for opaque LSAs was slightly changed */ + case LS_TYPE_OPAQUE_LL: + case LS_TYPE_OPAQUE_AL: + case LS_TYPE_OPAQUE_DW: + printf(", Opaque-Type: %s LSA (%u), Opaque-ID: %u", + tok2str(lsa_opaque_values, "unknown",lsrp->un_ls_stateid.opaque_field.opaque_type), + lsrp->un_ls_stateid.opaque_field.opaque_type, + EXTRACT_24BITS(&lsrp->un_ls_stateid.opaque_field.opaque_id)); + break; + default: + printf(", LSA-ID: %s", + ipaddr_string(&lsrp->un_ls_stateid.ls_stateid)); + break; + } + + ++lsrp; + } + break; + + case OSPF_TYPE_LS_UPDATE: + lsap = op->ospf_lsu.lsu_lsa; + TCHECK(op->ospf_lsu.lsu_count); + lsa_count_max = EXTRACT_32BITS(&op->ospf_lsu.lsu_count); + printf(", %d LSA%s",lsa_count_max, lsa_count_max > 1 ? "s" : ""); + for (lsa_count=1;lsa_count <= lsa_count_max;lsa_count++) { + printf("\n\t LSA #%u",lsa_count); + lsap = (const struct lsa *)ospf_print_lsa(lsap); + if (lsap == NULL) + goto trunc; + } + break; + + case OSPF_TYPE_LS_ACK: + lshp = op->ospf_lsa.lsa_lshdr; + while (ospf_print_lshdr(lshp) != -1) { + ++lshp; + } + break; + + default: + break; + } + return (0); +trunc: + return (1); +} + +void +ospf_print(register const u_char *bp, register u_int length, + const u_char *bp2 _U_) +{ + register const struct ospfhdr *op; + register const u_char *dataend; + register const char *cp; + + op = (struct ospfhdr *)bp; + + /* XXX Before we do anything else, strip off the MD5 trailer */ + TCHECK(op->ospf_authtype); + if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) { + length -= OSPF_AUTH_MD5_LEN; + snapend -= OSPF_AUTH_MD5_LEN; + } + + /* If the type is valid translate it, or just print the type */ + /* value. If it's not valid, say so and return */ + TCHECK(op->ospf_type); + cp = tok2str(type2str, "unknown LS-type", op->ospf_type); + printf("OSPFv%u, %s, length %u", + op->ospf_version, + cp, + length); + if (*cp == 'u') + return; + + if(!vflag) { /* non verbose - so lets bail out here */ + return; + } + + TCHECK(op->ospf_len); + if (length != EXTRACT_16BITS(&op->ospf_len)) { + printf(" [len %d]", EXTRACT_16BITS(&op->ospf_len)); + } + + if (length > EXTRACT_16BITS(&op->ospf_len)) { + dataend = bp + EXTRACT_16BITS(&op->ospf_len); + } else { + dataend = bp + length; + } + + TCHECK(op->ospf_routerid); + printf("\n\tRouter-ID %s", ipaddr_string(&op->ospf_routerid)); + + TCHECK(op->ospf_areaid); + if (op->ospf_areaid.s_addr != 0) + printf(", Area %s", ipaddr_string(&op->ospf_areaid)); + else + printf(", Backbone Area"); + + if (vflag) { + /* Print authentication data (should we really do this?) */ + TCHECK2(op->ospf_authdata[0], sizeof(op->ospf_authdata)); + + printf(", Authentication Type: %s (%u)", + tok2str(ospf_authtype_values,"unknown",EXTRACT_16BITS(&op->ospf_authtype)), + EXTRACT_16BITS(&op->ospf_authtype)); + + switch (EXTRACT_16BITS(&op->ospf_authtype)) { + + case OSPF_AUTH_NONE: + break; + + case OSPF_AUTH_SIMPLE: + printf("\n\tSimple text password: "); + safeputs((const char *)op->ospf_authdata, OSPF_AUTH_SIMPLE_LEN); + break; + + case OSPF_AUTH_MD5: + printf("\n\tKey-ID: %u, Auth-Length: %u, Crypto Sequence Number: 0x%08x", + *((op->ospf_authdata)+2), + *((op->ospf_authdata)+3), + EXTRACT_32BITS((op->ospf_authdata)+4)); + break; + + default: + return; + } + } + /* Do rest according to version. */ + switch (op->ospf_version) { + + case 2: + /* ospf version 2 */ + if (ospf_decode_v2(op, dataend)) + goto trunc; + if (length > EXTRACT_16BITS(&op->ospf_len)) { + if (ospf_decode_lls(op, length)) + goto trunc; + } + break; + + default: + printf(" ospf [version %d]", op->ospf_version); + break; + } /* end switch on version */ + + return; +trunc: + fputs(tstr, stdout); +} diff --git a/print-ospf6.c b/print-ospf6.c new file mode 100644 index 0000000..1100485 --- /dev/null +++ b/print-ospf6.c @@ -0,0 +1,589 @@ +/* + * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ospf6.c,v 1.15 2006-09-13 06:31:11 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "ospf.h" +#include "ospf6.h" + +static const struct tok ospf6_option_values[] = { + { OSPF6_OPTION_V6, "V6" }, + { OSPF6_OPTION_E, "External" }, + { OSPF6_OPTION_MC, "Multicast" }, + { OSPF6_OPTION_N, "NSSA" }, + { OSPF6_OPTION_R, "Router" }, + { OSPF6_OPTION_DC, "Demand Circuit" }, + { 0, NULL } +}; + +static const struct tok ospf6_rla_flag_values[] = { + { RLA_FLAG_B, "ABR" }, + { RLA_FLAG_E, "External" }, + { RLA_FLAG_V, "Virtual-Link Endpoint" }, + { RLA_FLAG_W, "Wildcard Receiver" }, + { RLA_FLAG_N, "NSSA Translator" }, + { 0, NULL } +}; + +static const struct tok ospf6_asla_flag_values[] = { + { ASLA_FLAG_EXTERNAL, "External Type 2" }, + { ASLA_FLAG_FWDADDR, "Fforwarding" }, + { ASLA_FLAG_ROUTETAG, "Tag" }, + { 0, NULL } +}; + +static struct tok ospf6_type_values[] = { + { OSPF_TYPE_HELLO, "Hello" }, + { OSPF_TYPE_DD, "Database Description" }, + { OSPF_TYPE_LS_REQ, "LS-Request" }, + { OSPF_TYPE_LS_UPDATE, "LS-Update" }, + { OSPF_TYPE_LS_ACK, "LS-Ack" }, + { 0, NULL } +}; + +static struct tok ospf6_lsa_values[] = { + { LS_TYPE_ROUTER, "Router" }, + { LS_TYPE_NETWORK, "Network" }, + { LS_TYPE_INTER_AP, "Inter-Area Prefix" }, + { LS_TYPE_INTER_AR, "Inter-Area Router" }, + { LS_TYPE_ASE, "External" }, + { LS_TYPE_GROUP, "Multicast Group" }, + { LS_TYPE_NSSA, "NSSA" }, + { LS_TYPE_LINK, "Link" }, + { LS_TYPE_INTRA_AP, "Intra-Area Prefix" }, + { LS_TYPE_INTRA_ATE, "Intra-Area TE" }, + { LS_TYPE_GRACE, "Grace" }, + { 0, NULL } +}; + +static struct tok ospf6_ls_scope_values[] = { + { LS_SCOPE_LINKLOCAL, "Link Local" }, + { LS_SCOPE_AREA, "Area Local" }, + { LS_SCOPE_AS, "Domain Wide" }, + { 0, NULL } +}; + +static struct tok ospf6_dd_flag_values[] = { + { OSPF6_DB_INIT, "Init" }, + { OSPF6_DB_MORE, "More" }, + { OSPF6_DB_MASTER, "Master" }, + { 0, NULL } +}; + +static struct tok ospf6_lsa_prefix_option_values[] = { + { LSA_PREFIX_OPT_NU, "No Unicast" }, + { LSA_PREFIX_OPT_LA, "Local address" }, + { LSA_PREFIX_OPT_MC, "Multicast" }, + { LSA_PREFIX_OPT_P, "Propagate" }, + { LSA_PREFIX_OPT_DN, "Down" }, + { 0, NULL } +}; + +static char tstr[] = " [|ospf3]"; + +#ifdef WIN32 +#define inline __inline +#endif /* WIN32 */ + +/* Forwards */ +static void ospf6_print_ls_type(u_int, const rtrid_t *); +static int ospf6_print_lshdr(const struct lsa6_hdr *); +static int ospf6_print_lsa(const struct lsa6 *); +static int ospf6_decode_v3(const struct ospf6hdr *, const u_char *); + + +static void +ospf6_print_ls_type(register u_int ls_type, register const rtrid_t *ls_stateid) +{ + printf("\n\t %s LSA (%d), %s Scope%s, LSA-ID %s", + tok2str(ospf6_lsa_values, "Unknown", ls_type & LS_TYPE_MASK), + ls_type & LS_TYPE_MASK, + tok2str(ospf6_ls_scope_values, "Unknown", ls_type & LS_SCOPE_MASK), + ls_type &0x8000 ? ", transitive" : "", /* U-bit */ + ipaddr_string(ls_stateid)); +} + +static int +ospf6_print_lshdr(register const struct lsa6_hdr *lshp) +{ + + TCHECK(lshp->ls_type); + TCHECK(lshp->ls_seq); + + printf("\n\t Advertising Router %s, seq 0x%08x, age %us, length %u", + ipaddr_string(&lshp->ls_router), + EXTRACT_32BITS(&lshp->ls_seq), + EXTRACT_16BITS(&lshp->ls_age), + EXTRACT_16BITS(&lshp->ls_length)-(u_int)sizeof(struct lsa6_hdr)); + + ospf6_print_ls_type(EXTRACT_16BITS(&lshp->ls_type), &lshp->ls_stateid); + + return (0); +trunc: + return (1); +} + +static int +ospf6_print_lsaprefix(register const struct lsa6_prefix *lsapp) +{ + u_int wordlen; + struct in6_addr prefix; + + TCHECK(*lsapp); + wordlen = (lsapp->lsa_p_len + 31) / 32; + if (wordlen * 4 > sizeof(struct in6_addr)) { + printf(" bogus prefixlen /%d", lsapp->lsa_p_len); + goto trunc; + } + memset(&prefix, 0, sizeof(prefix)); + memcpy(&prefix, lsapp->lsa_p_prefix, wordlen * 4); + printf("\n\t\t%s/%d", ip6addr_string(&prefix), + lsapp->lsa_p_len); + if (lsapp->lsa_p_opt) { + printf(", Options [%s]", + bittok2str(ospf6_lsa_prefix_option_values, + "none", lsapp->lsa_p_opt)); + } + printf(", metric %u", EXTRACT_16BITS(&lsapp->lsa_p_metric)); + return sizeof(*lsapp) - 4 + wordlen * 4; + +trunc: + return -1; +} + + +/* + * Print a single link state advertisement. If truncated return 1, else 0. + */ +static int +ospf6_print_lsa(register const struct lsa6 *lsap) +{ + register const u_char *ls_end, *ls_opt; + register const struct rlalink6 *rlp; +#if 0 + register const struct tos_metric *tosp; +#endif + register const rtrid_t *ap; +#if 0 + register const struct aslametric *almp; + register const struct mcla *mcp; +#endif + register const struct llsa *llsap; + register const struct lsa6_prefix *lsapp; +#if 0 + register const u_int32_t *lp; +#endif + register u_int prefixes; + register int bytelen, length, lsa_length; + u_int32_t flags32; + u_int8_t *tptr; + + if (ospf6_print_lshdr(&lsap->ls_hdr)) + return (1); + TCHECK(lsap->ls_hdr.ls_length); + length = EXTRACT_16BITS(&lsap->ls_hdr.ls_length); + lsa_length = length - sizeof(struct lsa6_hdr); + ls_end = (u_char *)lsap + length; + tptr = (u_int8_t *)lsap+sizeof(struct lsa6_hdr); + + switch (EXTRACT_16BITS(&lsap->ls_hdr.ls_type)) { + case LS_TYPE_ROUTER | LS_SCOPE_AREA: + TCHECK(lsap->lsa_un.un_rla.rla_options); + printf("\n\t Options [%s]", + bittok2str(ospf6_option_values, "none", + EXTRACT_32BITS(&lsap->lsa_un.un_rla.rla_options))); + + TCHECK(lsap->lsa_un.un_rla.rla_flags); + printf(", RLA-Flags [%s]", + bittok2str(ospf6_rla_flag_values, "none", + lsap->lsa_un.un_rla.rla_flags)); + + + TCHECK(lsap->lsa_un.un_rla.rla_link); + rlp = lsap->lsa_un.un_rla.rla_link; + while (rlp + 1 <= (struct rlalink6 *)ls_end) { + TCHECK(*rlp); + switch (rlp->link_type) { + + case RLA_TYPE_VIRTUAL: + printf("\n\t Virtual Link: Neighbor Router-ID %s" + "\n\t Neighbor Interface-ID %s, Interface %s", + ipaddr_string(&rlp->link_nrtid), + ipaddr_string(&rlp->link_nifid), + ipaddr_string(&rlp->link_ifid)); + break; + + case RLA_TYPE_ROUTER: + printf("\n\t Neighbor Router-ID %s" + "\n\t Neighbor Interface-ID %s, Interface %s", + ipaddr_string(&rlp->link_nrtid), + ipaddr_string(&rlp->link_nifid), + ipaddr_string(&rlp->link_ifid)); + break; + + case RLA_TYPE_TRANSIT: + printf("\n\t Neighbor Network-ID %s" + "\n\t Neighbor Interface-ID %s, Interface %s", + ipaddr_string(&rlp->link_nrtid), + ipaddr_string(&rlp->link_nifid), + ipaddr_string(&rlp->link_ifid)); + break; + + default: + printf("\n\t Unknown Router Links Type 0x%02x", + rlp->link_type); + return (0); + } + printf(", metric %d", EXTRACT_16BITS(&rlp->link_metric)); + rlp++; + } + break; + + case LS_TYPE_NETWORK | LS_SCOPE_AREA: + TCHECK(lsap->lsa_un.un_nla.nla_options); + printf("\n\t Options [%s]", + bittok2str(ospf6_option_values, "none", + EXTRACT_32BITS(&lsap->lsa_un.un_nla.nla_options))); + printf("\n\t Connected Routers:"); + ap = lsap->lsa_un.un_nla.nla_router; + while ((u_char *)ap < ls_end) { + TCHECK(*ap); + printf("\n\t\t%s", ipaddr_string(ap)); + ++ap; + } + break; + + case LS_TYPE_INTER_AP | LS_SCOPE_AREA: + TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric); + printf(", metric %u", + EXTRACT_32BITS(&lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC); + lsapp = lsap->lsa_un.un_inter_ap.inter_ap_prefix; + while (lsapp + sizeof(lsapp) <= (struct lsa6_prefix *)ls_end) { + bytelen = ospf6_print_lsaprefix(lsapp); + if (bytelen) + goto trunc; + lsapp = (struct lsa6_prefix *)(((u_char *)lsapp) + bytelen); + } + break; + case LS_SCOPE_AS | LS_TYPE_ASE: + TCHECK(lsap->lsa_un.un_asla.asla_metric); + flags32 = EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric); + printf("\n\t Flags [%s]", + bittok2str(ospf6_asla_flag_values, "none", flags32)); + printf(" metric %u", + EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric) & + ASLA_MASK_METRIC); + lsapp = lsap->lsa_un.un_asla.asla_prefix; + bytelen = ospf6_print_lsaprefix(lsapp); + if (bytelen < 0) + goto trunc; + if ((ls_opt = (u_char *)(((u_char *)lsapp) + bytelen)) < ls_end) { + struct in6_addr *fwdaddr6; + + if ((flags32 & ASLA_FLAG_FWDADDR) != 0) { + fwdaddr6 = (struct in6_addr *)ls_opt; + TCHECK(*fwdaddr6); + printf(" forward %s", + ip6addr_string(fwdaddr6)); + + ls_opt += sizeof(struct in6_addr); + } + + if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) { + TCHECK(*(u_int32_t *)ls_opt); + printf(" tag %s", + ipaddr_string((u_int32_t *)ls_opt)); + + ls_opt += sizeof(u_int32_t); + } + + if (lsapp->lsa_p_metric) { + TCHECK(*(u_int32_t *)ls_opt); + printf(" RefLSID: %s", + ipaddr_string((u_int32_t *)ls_opt)); + + ls_opt += sizeof(u_int32_t); + } + } + break; + + case LS_TYPE_LINK: + /* Link LSA */ + llsap = &lsap->lsa_un.un_llsa; + TCHECK(llsap->llsa_options); + printf("\n\t Options [%s]", + bittok2str(ospf6_option_values, "none", + EXTRACT_32BITS(&llsap->llsa_options))); + TCHECK(llsap->llsa_nprefix); + prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix); + printf("\n\t Priority %d, Link-local address %s, Prefixes %d:", + llsap->llsa_priority, + ip6addr_string(&llsap->llsa_lladdr), + prefixes); + + tptr = (u_int8_t *)llsap->llsa_prefix; + while (prefixes > 0) { + lsapp = (struct lsa6_prefix *)tptr; + if ((bytelen = ospf6_print_lsaprefix(lsapp)) == -1) { + goto trunc; + } + prefixes--; + tptr += bytelen; + } + break; + + case LS_TYPE_INTRA_AP | LS_SCOPE_AREA: + /* Intra-Area-Prefix LSA */ + TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid); + ospf6_print_ls_type( + EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_lstype), + &lsap->lsa_un.un_intra_ap.intra_ap_lsid); + TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix); + prefixes = EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_nprefix); + printf("\n\t Prefixes %d:", prefixes); + + tptr = (u_int8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix; + + while (prefixes > 0) { + lsapp = (struct lsa6_prefix *)tptr; + if ((bytelen = ospf6_print_lsaprefix(lsapp)) == -1) { + goto trunc; + } + prefixes--; + tptr += bytelen; + } + break; + + case LS_TYPE_GRACE | LS_SCOPE_LINKLOCAL: + if (ospf_print_grace_lsa(tptr, lsa_length) == -1) { + return 1; + } + + break; + + case LS_TYPE_INTRA_ATE | LS_SCOPE_LINKLOCAL: + if (ospf_print_te_lsa(tptr, lsa_length) == -1) { + return 1; + } + break; + + default: + if(!print_unknown_data(tptr, + "\n\t ", + lsa_length)) { + return (1); + } + } + + return (0); +trunc: + return (1); +} + +static int +ospf6_decode_v3(register const struct ospf6hdr *op, + register const u_char *dataend) +{ + register const rtrid_t *ap; + register const struct lsr6 *lsrp; + register const struct lsa6_hdr *lshp; + register const struct lsa6 *lsap; + register int i; + + switch (op->ospf6_type) { + + case OSPF_TYPE_HELLO: + printf("\n\tOptions [%s]", + bittok2str(ospf6_option_values, "none", + EXTRACT_32BITS(&op->ospf6_hello.hello_options))); + + TCHECK(op->ospf6_hello.hello_deadint); + printf("\n\t Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u", + EXTRACT_16BITS(&op->ospf6_hello.hello_helloint), + EXTRACT_16BITS(&op->ospf6_hello.hello_deadint), + ipaddr_string(&op->ospf6_hello.hello_ifid), + op->ospf6_hello.hello_priority); + + TCHECK(op->ospf6_hello.hello_dr); + if (op->ospf6_hello.hello_dr != 0) + printf("\n\t Designated Router %s", + ipaddr_string(&op->ospf6_hello.hello_dr)); + TCHECK(op->ospf6_hello.hello_bdr); + if (op->ospf6_hello.hello_bdr != 0) + printf(", Backup Designated Router %s", + ipaddr_string(&op->ospf6_hello.hello_bdr)); + if (vflag) { + printf("\n\t Neighbor List:"); + ap = op->ospf6_hello.hello_neighbor; + while ((u_char *)ap < dataend) { + TCHECK(*ap); + printf("\n\t %s", ipaddr_string(ap)); + ++ap; + } + } + break; /* HELLO */ + + case OSPF_TYPE_DD: + TCHECK(op->ospf6_db.db_options); + printf("\n\tOptions [%s]", + bittok2str(ospf6_option_values, "none", + EXTRACT_32BITS(&op->ospf6_db.db_options))); + TCHECK(op->ospf6_db.db_flags); + printf(", DD Flags [%s]", + bittok2str(ospf6_dd_flag_values,"none",op->ospf6_db.db_flags)); + + TCHECK(op->ospf6_db.db_seq); + printf(", MTU %u, DD-Sequence 0x%08x", + EXTRACT_16BITS(&op->ospf6_db.db_mtu), + EXTRACT_32BITS(&op->ospf6_db.db_seq)); + + /* Print all the LS adv's */ + lshp = op->ospf6_db.db_lshdr; + while (!ospf6_print_lshdr(lshp)) { + ++lshp; + } + break; + + case OSPF_TYPE_LS_REQ: + if (vflag) { + lsrp = op->ospf6_lsr; + while ((u_char *)lsrp < dataend) { + TCHECK(*lsrp); + printf("\n\t Advertising Router %s", + ipaddr_string(&lsrp->ls_router)); + ospf6_print_ls_type(EXTRACT_16BITS(&lsrp->ls_type), + &lsrp->ls_stateid); + ++lsrp; + } + } + break; + + case OSPF_TYPE_LS_UPDATE: + if (vflag) { + lsap = op->ospf6_lsu.lsu_lsa; + TCHECK(op->ospf6_lsu.lsu_count); + i = EXTRACT_32BITS(&op->ospf6_lsu.lsu_count); + while (i--) { + if (ospf6_print_lsa(lsap)) + goto trunc; + lsap = (struct lsa6 *)((u_char *)lsap + + EXTRACT_16BITS(&lsap->ls_hdr.ls_length)); + } + } + break; + + + case OSPF_TYPE_LS_ACK: + if (vflag) { + lshp = op->ospf6_lsa.lsa_lshdr; + + while (!ospf6_print_lshdr(lshp)) { + ++lshp; + } + } + break; + + default: + break; + } + return (0); +trunc: + return (1); +} + +void +ospf6_print(register const u_char *bp, register u_int length) +{ + register const struct ospf6hdr *op; + register const u_char *dataend; + register const char *cp; + + op = (struct ospf6hdr *)bp; + + /* If the type is valid translate it, or just print the type */ + /* value. If it's not valid, say so and return */ + TCHECK(op->ospf6_type); + cp = tok2str(ospf6_type_values, "unknown LS-type", op->ospf6_type); + printf("OSPFv%u, %s, length %d", op->ospf6_version, cp, length); + if (*cp == 'u') { + return; + } + + if(!vflag) { /* non verbose - so lets bail out here */ + return; + } + + TCHECK(op->ospf6_len); + if (length != EXTRACT_16BITS(&op->ospf6_len)) { + printf(" [len %d]", EXTRACT_16BITS(&op->ospf6_len)); + return; + } + dataend = bp + length; + + /* Print the routerid if it is not the same as the source */ + TCHECK(op->ospf6_routerid); + printf("\n\tRouter-ID %s", ipaddr_string(&op->ospf6_routerid)); + + TCHECK(op->ospf6_areaid); + if (op->ospf6_areaid != 0) + printf(", Area %s", ipaddr_string(&op->ospf6_areaid)); + else + printf(", Backbone Area"); + TCHECK(op->ospf6_instanceid); + if (op->ospf6_instanceid) + printf(", Instance %u", op->ospf6_instanceid); + + /* Do rest according to version. */ + switch (op->ospf6_version) { + + case 3: + /* ospf version 3 */ + if (ospf6_decode_v3(op, dataend)) + goto trunc; + break; + + default: + printf(" ospf [version %d]", op->ospf6_version); + break; + } /* end switch on version */ + + return; +trunc: + fputs(tstr, stdout); +} diff --git a/print-pflog.c b/print-pflog.c new file mode 100644 index 0000000..0cacabf --- /dev/null +++ b/print-pflog.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-pflog.c,v 1.16 2007-09-12 19:36:18 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef HAVE_NET_PFVAR_H +#error "No pf headers available" +#endif +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "extract.h" +#include "interface.h" +#include "addrtoname.h" + +static struct tok pf_reasons[] = { + { 0, "0(match)" }, + { 1, "1(bad-offset)" }, + { 2, "2(fragment)" }, + { 3, "3(short)" }, + { 4, "4(normalize)" }, + { 5, "5(memory)" }, + { 6, "6(bad-timestamp)" }, + { 7, "7(congestion)" }, + { 8, "8(ip-option)" }, + { 9, "9(proto-cksum)" }, + { 10, "10(state-mismatch)" }, + { 11, "11(state-insert)" }, + { 12, "12(state-limit)" }, + { 13, "13(src-limit)" }, + { 14, "14(synproxy)" }, + { 0, NULL } +}; + +static struct tok pf_actions[] = { + { PF_PASS, "pass" }, + { PF_DROP, "block" }, + { PF_SCRUB, "scrub" }, + { PF_NAT, "nat" }, + { PF_NONAT, "nat" }, + { PF_BINAT, "binat" }, + { PF_NOBINAT, "binat" }, + { PF_RDR, "rdr" }, + { PF_NORDR, "rdr" }, + { PF_SYNPROXY_DROP, "synproxy-drop" }, + { 0, NULL } +}; + +static struct tok pf_directions[] = { + { PF_INOUT, "in/out" }, + { PF_IN, "in" }, + { PF_OUT, "out" }, + { 0, NULL } +}; + +/* For reading capture files on other systems */ +#define OPENBSD_AF_INET 2 +#define OPENBSD_AF_INET6 24 + +static void +pflog_print(const struct pfloghdr *hdr) +{ + u_int32_t rulenr, subrulenr; + + rulenr = EXTRACT_32BITS(&hdr->rulenr); + subrulenr = EXTRACT_32BITS(&hdr->subrulenr); + if (subrulenr == (u_int32_t)-1) + printf("rule %u/", rulenr); + else + printf("rule %u.%s.%u/", rulenr, hdr->ruleset, subrulenr); + + printf("%s: %s %s on %s: ", + tok2str(pf_reasons, "unkn(%u)", hdr->reason), + tok2str(pf_actions, "unkn(%u)", hdr->action), + tok2str(pf_directions, "unkn(%u)", hdr->dir), + hdr->ifname); +} + +u_int +pflog_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + u_int length = h->len; + u_int hdrlen; + u_int caplen = h->caplen; + const struct pfloghdr *hdr; + u_int8_t af; + + /* check length */ + if (caplen < sizeof(u_int8_t)) { + printf("[|pflog]"); + return (caplen); + } + +#define MIN_PFLOG_HDRLEN 45 + hdr = (struct pfloghdr *)p; + if (hdr->length < MIN_PFLOG_HDRLEN) { + printf("[pflog: invalid header length!]"); + return (hdr->length); /* XXX: not really */ + } + hdrlen = BPF_WORDALIGN(hdr->length); + + if (caplen < hdrlen) { + printf("[|pflog]"); + return (hdrlen); /* XXX: true? */ + } + + /* print what we know */ + hdr = (struct pfloghdr *)p; + TCHECK(*hdr); + if (eflag) + pflog_print(hdr); + + /* skip to the real packet */ + af = hdr->af; + length -= hdrlen; + caplen -= hdrlen; + p += hdrlen; + switch (af) { + + case AF_INET: +#if OPENBSD_AF_INET != AF_INET + case OPENBSD_AF_INET: /* XXX: read pcap files */ +#endif + ip_print(gndo, p, length); + break; + +#ifdef INET6 + case AF_INET6: +#if OPENBSD_AF_INET6 != AF_INET6 + case OPENBSD_AF_INET6: /* XXX: read pcap files */ +#endif + ip6_print(p, length); + break; +#endif + + default: + /* address family not handled, print raw packet */ + if (!eflag) + pflog_print(hdr); + if (!suppress_default_print) + default_print(p, caplen); + } + + return (hdrlen); +trunc: + printf("[|pflog]"); + return (hdrlen); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-pgm.c b/print-pgm.c new file mode 100644 index 0000000..73a4291 --- /dev/null +++ b/print-pgm.c @@ -0,0 +1,759 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Original code by Andy Heffernan (ahh@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-pgm.c,v 1.5 2005-06-07 22:05:58 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif +#include "ipproto.h" + +/* + * PGM header (RFC 3208) + */ +struct pgm_header { + u_int16_t pgm_sport; + u_int16_t pgm_dport; + u_int8_t pgm_type; + u_int8_t pgm_options; + u_int16_t pgm_sum; + u_int8_t pgm_gsid[6]; + u_int16_t pgm_length; +}; + +struct pgm_spm { + u_int32_t pgms_seq; + u_int32_t pgms_trailseq; + u_int32_t pgms_leadseq; + u_int16_t pgms_nla_afi; + u_int16_t pgms_reserved; + /* ... u_int8_t pgms_nla[0]; */ + /* ... options */ +}; + +struct pgm_nak { + u_int32_t pgmn_seq; + u_int16_t pgmn_source_afi; + u_int16_t pgmn_reserved; + /* ... u_int8_t pgmn_source[0]; */ + /* ... u_int16_t pgmn_group_afi */ + /* ... u_int16_t pgmn_reserved2; */ + /* ... u_int8_t pgmn_group[0]; */ + /* ... options */ +}; + +struct pgm_poll { + u_int32_t pgmp_seq; + u_int16_t pgmp_round; + u_int16_t pgmp_reserved; + /* ... options */ +}; + +struct pgm_polr { + u_int32_t pgmp_seq; + u_int16_t pgmp_round; + u_int16_t pgmp_subtype; + u_int16_t pgmp_nla_afi; + u_int16_t pgmp_reserved; + /* ... u_int8_t pgmp_nla[0]; */ + /* ... options */ +}; + +struct pgm_data { + u_int32_t pgmd_seq; + u_int32_t pgmd_trailseq; + /* ... options */ +}; + +typedef enum _pgm_type { + PGM_SPM = 0, /* source path message */ + PGM_POLL = 1, /* POLL Request */ + PGM_POLR = 2, /* POLL Response */ + PGM_ODATA = 4, /* original data */ + PGM_RDATA = 5, /* repair data */ + PGM_NAK = 8, /* NAK */ + PGM_NULLNAK = 9, /* Null NAK */ + PGM_NCF = 10, /* NAK Confirmation */ + PGM_ACK = 11, /* ACK for congestion control */ + PGM_SPMR = 12, /* SPM request */ + PGM_MAX = 255 +} pgm_type; + +#define PGM_OPT_BIT_PRESENT 0x01 +#define PGM_OPT_BIT_NETWORK 0x02 +#define PGM_OPT_BIT_VAR_PKTLEN 0x40 +#define PGM_OPT_BIT_PARITY 0x80 + +#define PGM_OPT_LENGTH 0x00 +#define PGM_OPT_FRAGMENT 0x01 +#define PGM_OPT_NAK_LIST 0x02 +#define PGM_OPT_JOIN 0x03 +#define PGM_OPT_NAK_BO_IVL 0x04 +#define PGM_OPT_NAK_BO_RNG 0x05 + +#define PGM_OPT_REDIRECT 0x07 +#define PGM_OPT_PARITY_PRM 0x08 +#define PGM_OPT_PARITY_GRP 0x09 +#define PGM_OPT_CURR_TGSIZE 0x0A +#define PGM_OPT_NBR_UNREACH 0x0B +#define PGM_OPT_PATH_NLA 0x0C + +#define PGM_OPT_SYN 0x0D +#define PGM_OPT_FIN 0x0E +#define PGM_OPT_RST 0x0F +#define PGM_OPT_CR 0x10 +#define PGM_OPT_CRQST 0x11 + +#define PGM_OPT_MASK 0x7f + +#define PGM_OPT_END 0x80 /* end of options marker */ + +#define PGM_MIN_OPT_LEN 4 + +#ifndef AFI_IP +#define AFI_IP 1 +#define AFI_IP6 2 +#endif + +void +pgm_print(register const u_char *bp, register u_int length, + register const u_char *bp2) +{ + register const struct pgm_header *pgm; + register const struct ip *ip; + register char ch; + u_int16_t sport, dport; + int addr_size; + const void *nla; + int nla_af; +#ifdef INET6 + char nla_buf[INET6_ADDRSTRLEN]; + register const struct ip6_hdr *ip6; +#else + char nla_buf[INET_ADDRSTRLEN]; +#endif + u_int8_t opt_type, opt_len, flags1, flags2; + u_int32_t seq, opts_len, len, offset; + + pgm = (struct pgm_header *)bp; + ip = (struct ip *)bp2; +#ifdef INET6 + if (IP_V(ip) == 6) + ip6 = (struct ip6_hdr *)bp2; + else + ip6 = NULL; +#else /* INET6 */ + if (IP_V(ip) == 6) { + (void)printf("Can't handle IPv6"); + return; + } +#endif /* INET6 */ + ch = '\0'; + if (!TTEST(pgm->pgm_dport)) { +#ifdef INET6 + if (ip6) { + (void)printf("%s > %s: [|pgm]", + ip6addr_string(&ip6->ip6_src), + ip6addr_string(&ip6->ip6_dst)); + return; + } else +#endif /* INET6 */ + { + (void)printf("%s > %s: [|pgm]", + ipaddr_string(&ip->ip_src), + ipaddr_string(&ip->ip_dst)); + return; + } + } + + sport = EXTRACT_16BITS(&pgm->pgm_sport); + dport = EXTRACT_16BITS(&pgm->pgm_dport); + +#ifdef INET6 + if (ip6) { + if (ip6->ip6_nxt == IPPROTO_PGM) { + (void)printf("%s.%s > %s.%s: ", + ip6addr_string(&ip6->ip6_src), + tcpport_string(sport), + ip6addr_string(&ip6->ip6_dst), + tcpport_string(dport)); + } else { + (void)printf("%s > %s: ", + tcpport_string(sport), tcpport_string(dport)); + } + } else +#endif /*INET6*/ + { + if (ip->ip_p == IPPROTO_PGM) { + (void)printf("%s.%s > %s.%s: ", + ipaddr_string(&ip->ip_src), + tcpport_string(sport), + ipaddr_string(&ip->ip_dst), + tcpport_string(dport)); + } else { + (void)printf("%s > %s: ", + tcpport_string(sport), tcpport_string(dport)); + } + } + + TCHECK(*pgm); + + (void)printf("PGM, length %u", pgm->pgm_length); + + if (!vflag) + return; + + if (length > pgm->pgm_length) + length = pgm->pgm_length; + + (void)printf(" 0x%02x%02x%02x%02x%02x%02x ", + pgm->pgm_gsid[0], + pgm->pgm_gsid[1], + pgm->pgm_gsid[2], + pgm->pgm_gsid[3], + pgm->pgm_gsid[4], + pgm->pgm_gsid[5]); + switch (pgm->pgm_type) { + case PGM_SPM: { + struct pgm_spm *spm; + + spm = (struct pgm_spm *)(pgm + 1); + TCHECK(*spm); + + switch (EXTRACT_16BITS(&spm->pgms_nla_afi)) { + case AFI_IP: + addr_size = sizeof(struct in_addr); + nla_af = AF_INET; + break; +#ifdef INET6 + case AFI_IP6: + addr_size = sizeof(struct in6_addr); + nla_af = AF_INET6; + break; +#endif + default: + goto trunc; + break; + } + bp = (u_char *) (spm + 1); + TCHECK2(*bp, addr_size); + nla = bp; + bp += addr_size; + + inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); + (void)printf("SPM seq %u trail %u lead %u nla %s", + EXTRACT_32BITS(&spm->pgms_seq), + EXTRACT_32BITS(&spm->pgms_trailseq), + EXTRACT_32BITS(&spm->pgms_leadseq), + nla_buf); + break; + } + + case PGM_POLL: { + struct pgm_poll *poll; + + poll = (struct pgm_poll *)(pgm + 1); + TCHECK(*poll); + (void)printf("POLL seq %u round %u", + EXTRACT_32BITS(&poll->pgmp_seq), + EXTRACT_16BITS(&poll->pgmp_round)); + bp = (u_char *) (poll + 1); + break; + } + case PGM_POLR: { + struct pgm_polr *polr; + u_int32_t ivl, rnd, mask; + + polr = (struct pgm_polr *)(pgm + 1); + TCHECK(*polr); + + switch (EXTRACT_16BITS(&polr->pgmp_nla_afi)) { + case AFI_IP: + addr_size = sizeof(struct in_addr); + nla_af = AF_INET; + break; +#ifdef INET6 + case AFI_IP6: + addr_size = sizeof(struct in6_addr); + nla_af = AF_INET6; + break; +#endif + default: + goto trunc; + break; + } + bp = (u_char *) (polr + 1); + TCHECK2(*bp, addr_size); + nla = bp; + bp += addr_size; + + inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); + + TCHECK2(*bp, sizeof(u_int32_t)); + ivl = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + + TCHECK2(*bp, sizeof(u_int32_t)); + rnd = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + + TCHECK2(*bp, sizeof(u_int32_t)); + mask = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + + (void)printf("POLR seq %u round %u nla %s ivl %u rnd 0x%08x " + "mask 0x%08x", EXTRACT_32BITS(&polr->pgmp_seq), + EXTRACT_16BITS(&polr->pgmp_round), nla_buf, ivl, rnd, mask); + break; + } + case PGM_ODATA: { + struct pgm_data *odata; + + odata = (struct pgm_data *)(pgm + 1); + TCHECK(*odata); + (void)printf("ODATA trail %u seq %u", + EXTRACT_32BITS(&odata->pgmd_trailseq), + EXTRACT_32BITS(&odata->pgmd_seq)); + bp = (u_char *) (odata + 1); + break; + } + + case PGM_RDATA: { + struct pgm_data *rdata; + + rdata = (struct pgm_data *)(pgm + 1); + TCHECK(*rdata); + (void)printf("RDATA trail %u seq %u", + EXTRACT_32BITS(&rdata->pgmd_trailseq), + EXTRACT_32BITS(&rdata->pgmd_seq)); + bp = (u_char *) (rdata + 1); + break; + } + + case PGM_NAK: + case PGM_NULLNAK: + case PGM_NCF: { + struct pgm_nak *nak; + const void *source, *group; + int source_af, group_af; +#ifdef INET6 + char source_buf[INET6_ADDRSTRLEN], group_buf[INET6_ADDRSTRLEN]; +#else + char source_buf[INET_ADDRSTRLEN], group_buf[INET_ADDRSTRLEN]; +#endif + + nak = (struct pgm_nak *)(pgm + 1); + TCHECK(*nak); + + /* + * Skip past the source, saving info along the way + * and stopping if we don't have enough. + */ + switch (EXTRACT_16BITS(&nak->pgmn_source_afi)) { + case AFI_IP: + addr_size = sizeof(struct in_addr); + source_af = AF_INET; + break; +#ifdef INET6 + case AFI_IP6: + addr_size = sizeof(struct in6_addr); + source_af = AF_INET6; + break; +#endif + default: + goto trunc; + break; + } + bp = (u_char *) (nak + 1); + TCHECK2(*bp, addr_size); + source = bp; + bp += addr_size; + + /* + * Skip past the group, saving info along the way + * and stopping if we don't have enough. + */ + switch (EXTRACT_16BITS(bp)) { + case AFI_IP: + addr_size = sizeof(struct in_addr); + group_af = AF_INET; + break; +#ifdef INET6 + case AFI_IP6: + addr_size = sizeof(struct in6_addr); + group_af = AF_INET6; + break; +#endif + default: + goto trunc; + break; + } + bp += (2 * sizeof(u_int16_t)); + TCHECK2(*bp, addr_size); + group = bp; + bp += addr_size; + + /* + * Options decoding can go here. + */ + inet_ntop(source_af, source, source_buf, sizeof(source_buf)); + inet_ntop(group_af, group, group_buf, sizeof(group_buf)); + switch (pgm->pgm_type) { + case PGM_NAK: + (void)printf("NAK "); + break; + case PGM_NULLNAK: + (void)printf("NNAK "); + break; + case PGM_NCF: + (void)printf("NCF "); + break; + default: + break; + } + (void)printf("(%s -> %s), seq %u", + source_buf, group_buf, EXTRACT_32BITS(&nak->pgmn_seq)); + break; + } + + case PGM_SPMR: + (void)printf("SPMR"); + break; + + default: + (void)printf("UNKNOWN type %0x02x", pgm->pgm_type); + break; + + } + if (pgm->pgm_options & PGM_OPT_BIT_PRESENT) { + + /* + * make sure there's enough for the first option header + */ + if (!TTEST2(*bp, PGM_MIN_OPT_LEN)) { + (void)printf("[|OPT]"); + return; + } + + /* + * That option header MUST be an OPT_LENGTH option + * (see the first paragraph of section 9.1 in RFC 3208). + */ + opt_type = *bp++; + if ((opt_type & PGM_OPT_MASK) != PGM_OPT_LENGTH) { + (void)printf("[First option bad, should be PGM_OPT_LENGTH, is %u]", opt_type & PGM_OPT_MASK); + return; + } + opt_len = *bp++; + if (opt_len != 4) { + (void)printf("[Bad OPT_LENGTH option, length %u != 4]", opt_len); + return; + } + opts_len = EXTRACT_16BITS(bp); + if (opts_len < 4) { + (void)printf("[Bad total option length %u < 4]", opts_len); + return; + } + bp += sizeof(u_int16_t); + (void)printf(" OPTS LEN %d", opts_len); + opts_len -= 4; + + while (opts_len) { + if (opts_len < PGM_MIN_OPT_LEN) { + (void)printf("[Total option length leaves no room for final option]"); + return; + } + opt_type = *bp++; + opt_len = *bp++; + if (opt_len < PGM_MIN_OPT_LEN) { + (void)printf("[Bad option, length %u < %u]", opt_len, + PGM_MIN_OPT_LEN); + break; + } + if (opts_len < opt_len) { + (void)printf("[Total option length leaves no room for final option]"); + return; + } + if (!TTEST2(*bp, opt_len - 2)) { + (void)printf(" [|OPT]"); + return; + } + + switch (opt_type & PGM_OPT_MASK) { + case PGM_OPT_LENGTH: + if (opt_len != 4) { + (void)printf("[Bad OPT_LENGTH option, length %u != 4]", opt_len); + return; + } + (void)printf(" OPTS LEN (extra?) %d", EXTRACT_16BITS(bp)); + bp += sizeof(u_int16_t); + opts_len -= 4; + break; + + case PGM_OPT_FRAGMENT: + if (opt_len != 16) { + (void)printf("[Bad OPT_FRAGMENT option, length %u != 16]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + seq = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + offset = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + len = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + (void)printf(" FRAG seq %u off %u len %u", seq, offset, len); + opts_len -= 16; + break; + + case PGM_OPT_NAK_LIST: + flags1 = *bp++; + flags2 = *bp++; + opt_len -= sizeof(u_int32_t); /* option header */ + (void)printf(" NAK LIST"); + while (opt_len) { + if (opt_len < sizeof(u_int32_t)) { + (void)printf("[Option length not a multiple of 4]"); + return; + } + TCHECK2(*bp, sizeof(u_int32_t)); + (void)printf(" %u", EXTRACT_32BITS(bp)); + bp += sizeof(u_int32_t); + opt_len -= sizeof(u_int32_t); + opts_len -= sizeof(u_int32_t); + } + break; + + case PGM_OPT_JOIN: + if (opt_len != 8) { + (void)printf("[Bad OPT_JOIN option, length %u != 8]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + seq = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + (void)printf(" JOIN %u", seq); + opts_len -= 8; + break; + + case PGM_OPT_NAK_BO_IVL: + if (opt_len != 12) { + (void)printf("[Bad OPT_NAK_BO_IVL option, length %u != 12]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + offset = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + seq = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + (void)printf(" BACKOFF ivl %u ivlseq %u", offset, seq); + opts_len -= 12; + break; + + case PGM_OPT_NAK_BO_RNG: + if (opt_len != 12) { + (void)printf("[Bad OPT_NAK_BO_RNG option, length %u != 12]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + offset = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + seq = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + (void)printf(" BACKOFF max %u min %u", offset, seq); + opts_len -= 12; + break; + + case PGM_OPT_REDIRECT: + flags1 = *bp++; + flags2 = *bp++; + switch (EXTRACT_16BITS(bp)) { + case AFI_IP: + addr_size = sizeof(struct in_addr); + nla_af = AF_INET; + break; +#ifdef INET6 + case AFI_IP6: + addr_size = sizeof(struct in6_addr); + nla_af = AF_INET6; + break; +#endif + default: + goto trunc; + break; + } + bp += (2 * sizeof(u_int16_t)); + if (opt_len != 4 + addr_size) { + (void)printf("[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len); + return; + } + TCHECK2(*bp, addr_size); + nla = bp; + bp += addr_size; + + inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); + (void)printf(" REDIRECT %s", (char *)nla); + opts_len -= 4 + addr_size; + break; + + case PGM_OPT_PARITY_PRM: + if (opt_len != 8) { + (void)printf("[Bad OPT_PARITY_PRM option, length %u != 8]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + len = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + (void)printf(" PARITY MAXTGS %u", len); + opts_len -= 8; + break; + + case PGM_OPT_PARITY_GRP: + if (opt_len != 8) { + (void)printf("[Bad OPT_PARITY_GRP option, length %u != 8]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + seq = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + (void)printf(" PARITY GROUP %u", seq); + opts_len -= 8; + break; + + case PGM_OPT_CURR_TGSIZE: + if (opt_len != 8) { + (void)printf("[Bad OPT_CURR_TGSIZE option, length %u != 8]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + len = EXTRACT_32BITS(bp); + bp += sizeof(u_int32_t); + (void)printf(" PARITY ATGS %u", len); + opts_len -= 8; + break; + + case PGM_OPT_NBR_UNREACH: + if (opt_len != 4) { + (void)printf("[Bad OPT_NBR_UNREACH option, length %u != 4]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + (void)printf(" NBR_UNREACH"); + opts_len -= 4; + break; + + case PGM_OPT_PATH_NLA: + (void)printf(" PATH_NLA [%d]", opt_len); + bp += opt_len; + opts_len -= opt_len; + break; + + case PGM_OPT_SYN: + if (opt_len != 4) { + (void)printf("[Bad OPT_SYN option, length %u != 4]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + (void)printf(" SYN"); + opts_len -= 4; + break; + + case PGM_OPT_FIN: + if (opt_len != 4) { + (void)printf("[Bad OPT_FIN option, length %u != 4]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + (void)printf(" FIN"); + opts_len -= 4; + break; + + case PGM_OPT_RST: + if (opt_len != 4) { + (void)printf("[Bad OPT_RST option, length %u != 4]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + (void)printf(" RST"); + opts_len -= 4; + break; + + case PGM_OPT_CR: + (void)printf(" CR"); + bp += opt_len; + opts_len -= opt_len; + break; + + case PGM_OPT_CRQST: + if (opt_len != 4) { + (void)printf("[Bad OPT_CRQST option, length %u != 4]", opt_len); + return; + } + flags1 = *bp++; + flags2 = *bp++; + (void)printf(" CRQST"); + opts_len -= 4; + break; + + default: + (void)printf(" OPT_%02X [%d] ", opt_type, opt_len); + bp += opt_len; + opts_len -= opt_len; + break; + } + + if (opt_type & PGM_OPT_END) + break; + } + } + + (void)printf(" [%u]", EXTRACT_16BITS(&pgm->pgm_length)); + + return; + +trunc: + fputs("[|pgm]", stdout); + if (ch != '\0') + putchar('>'); +} diff --git a/print-pim.c b/print-pim.c new file mode 100644 index 0000000..f9fd0c6 --- /dev/null +++ b/print-pim.c @@ -0,0 +1,1091 @@ +/* + * Copyright (c) 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-pim.c,v 1.49 2006-02-13 01:31:35 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "interface.h" + +#define PIMV2_TYPE_HELLO 0 +#define PIMV2_TYPE_REGISTER 1 +#define PIMV2_TYPE_REGISTER_STOP 2 +#define PIMV2_TYPE_JOIN_PRUNE 3 +#define PIMV2_TYPE_BOOTSTRAP 4 +#define PIMV2_TYPE_ASSERT 5 +#define PIMV2_TYPE_GRAFT 6 +#define PIMV2_TYPE_GRAFT_ACK 7 +#define PIMV2_TYPE_CANDIDATE_RP 8 +#define PIMV2_TYPE_PRUNE_REFRESH 9 + +static struct tok pimv2_type_values[] = { + { PIMV2_TYPE_HELLO, "Hello" }, + { PIMV2_TYPE_REGISTER, "Register" }, + { PIMV2_TYPE_REGISTER_STOP, "Register Stop" }, + { PIMV2_TYPE_JOIN_PRUNE, "Join / Prune" }, + { PIMV2_TYPE_BOOTSTRAP, "Bootstrap" }, + { PIMV2_TYPE_ASSERT, "Assert" }, + { PIMV2_TYPE_GRAFT, "Graft" }, + { PIMV2_TYPE_GRAFT_ACK, "Graft Acknowledgement" }, + { PIMV2_TYPE_CANDIDATE_RP, "Candidate RP Advertisement" }, + { PIMV2_TYPE_PRUNE_REFRESH, "Prune Refresh" }, + { 0, NULL} +}; + +#define PIMV2_HELLO_OPTION_HOLDTIME 1 +#define PIMV2_HELLO_OPTION_LANPRUNEDELAY 2 +#define PIMV2_HELLO_OPTION_DR_PRIORITY_OLD 18 +#define PIMV2_HELLO_OPTION_DR_PRIORITY 19 +#define PIMV2_HELLO_OPTION_GENID 20 +#define PIMV2_HELLO_OPTION_REFRESH_CAP 21 +#define PIMV2_HELLO_OPTION_BIDIR_CAP 22 +#define PIMV2_HELLO_OPTION_ADDRESS_LIST 24 +#define PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD 65001 + +static struct tok pimv2_hello_option_values[] = { + { PIMV2_HELLO_OPTION_HOLDTIME, "Hold Time" }, + { PIMV2_HELLO_OPTION_LANPRUNEDELAY, "LAN Prune Delay" }, + { PIMV2_HELLO_OPTION_DR_PRIORITY_OLD, "DR Priority (Old)" }, + { PIMV2_HELLO_OPTION_DR_PRIORITY, "DR Priority" }, + { PIMV2_HELLO_OPTION_GENID, "Generation ID" }, + { PIMV2_HELLO_OPTION_REFRESH_CAP, "State Refresh Capability" }, + { PIMV2_HELLO_OPTION_BIDIR_CAP, "Bi-Directional Capability" }, + { PIMV2_HELLO_OPTION_ADDRESS_LIST, "Address List" }, + { PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD, "Address List (Old)" }, + { 0, NULL} +}; + +#define PIMV2_REGISTER_FLAG_LEN 4 +#define PIMV2_REGISTER_FLAG_BORDER 0x80000000 +#define PIMV2_REGISTER_FLAG_NULL 0x40000000 + +static struct tok pimv2_register_flag_values[] = { + { PIMV2_REGISTER_FLAG_BORDER, "Border" }, + { PIMV2_REGISTER_FLAG_NULL, "Null" }, + { 0, NULL} +}; + +/* + * XXX: We consider a case where IPv6 is not ready yet for portability, + * but PIM dependent defintions should be independent of IPv6... + */ + +struct pim { + u_int8_t pim_typever; + /* upper 4bit: PIM version number; 2 for PIMv2 */ + /* lower 4bit: the PIM message type, currently they are: + * Hello, Register, Register-Stop, Join/Prune, + * Bootstrap, Assert, Graft (PIM-DM only), + * Graft-Ack (PIM-DM only), C-RP-Adv + */ +#define PIM_VER(x) (((x) & 0xf0) >> 4) +#define PIM_TYPE(x) ((x) & 0x0f) + u_char pim_rsv; /* Reserved */ + u_short pim_cksum; /* IP style check sum */ +}; + + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "ip.h" + +static void pimv2_print(register const u_char *bp, register u_int len, u_int cksum); + +static void +pimv1_join_prune_print(register const u_char *bp, register u_int len) +{ + int maddrlen, addrlen, ngroups, njoin, nprune; + int njp; + + /* If it's a single group and a single source, use 1-line output. */ + if (TTEST2(bp[0], 30) && bp[11] == 1 && + ((njoin = EXTRACT_16BITS(&bp[20])) + EXTRACT_16BITS(&bp[22])) == 1) { + int hold; + + (void)printf(" RPF %s ", ipaddr_string(bp)); + hold = EXTRACT_16BITS(&bp[6]); + if (hold != 180) { + (void)printf("Hold "); + relts_print(hold); + } + (void)printf("%s (%s/%d, %s", njoin ? "Join" : "Prune", + ipaddr_string(&bp[26]), bp[25] & 0x3f, + ipaddr_string(&bp[12])); + if (EXTRACT_32BITS(&bp[16]) != 0xffffffff) + (void)printf("/%s", ipaddr_string(&bp[16])); + (void)printf(") %s%s %s", + (bp[24] & 0x01) ? "Sparse" : "Dense", + (bp[25] & 0x80) ? " WC" : "", + (bp[25] & 0x40) ? "RP" : "SPT"); + return; + } + + TCHECK2(bp[0], sizeof(struct in_addr)); + if (vflag > 1) + (void)printf("\n"); + (void)printf(" Upstream Nbr: %s", ipaddr_string(bp)); + TCHECK2(bp[6], 2); + if (vflag > 1) + (void)printf("\n"); + (void)printf(" Hold time: "); + relts_print(EXTRACT_16BITS(&bp[6])); + if (vflag < 2) + return; + bp += 8; + len -= 8; + + TCHECK2(bp[0], 4); + maddrlen = bp[1]; + addrlen = bp[2]; + ngroups = bp[3]; + bp += 4; + len -= 4; + while (ngroups--) { + /* + * XXX - does the address have length "addrlen" and the + * mask length "maddrlen"? + */ + TCHECK2(bp[0], sizeof(struct in_addr)); + (void)printf("\n\tGroup: %s", ipaddr_string(bp)); + TCHECK2(bp[4], sizeof(struct in_addr)); + if (EXTRACT_32BITS(&bp[4]) != 0xffffffff) + (void)printf("/%s", ipaddr_string(&bp[4])); + TCHECK2(bp[8], 4); + njoin = EXTRACT_16BITS(&bp[8]); + nprune = EXTRACT_16BITS(&bp[10]); + (void)printf(" joined: %d pruned: %d", njoin, nprune); + bp += 12; + len -= 12; + for (njp = 0; njp < (njoin + nprune); njp++) { + const char *type; + + if (njp < njoin) + type = "Join "; + else + type = "Prune"; + TCHECK2(bp[0], 6); + (void)printf("\n\t%s %s%s%s%s/%d", type, + (bp[0] & 0x01) ? "Sparse " : "Dense ", + (bp[1] & 0x80) ? "WC " : "", + (bp[1] & 0x40) ? "RP " : "SPT ", + ipaddr_string(&bp[2]), bp[1] & 0x3f); + bp += 6; + len -= 6; + } + } + return; +trunc: + (void)printf("[|pim]"); + return; +} + +void +pimv1_print(register const u_char *bp, register u_int len) +{ + register const u_char *ep; + register u_char type; + + ep = (const u_char *)snapend; + if (bp >= ep) + return; + + TCHECK(bp[1]); + type = bp[1]; + + switch (type) { + case 0: + (void)printf(" Query"); + if (TTEST(bp[8])) { + switch (bp[8] >> 4) { + case 0: + (void)printf(" Dense-mode"); + break; + case 1: + (void)printf(" Sparse-mode"); + break; + case 2: + (void)printf(" Sparse-Dense-mode"); + break; + default: + (void)printf(" mode-%d", bp[8] >> 4); + break; + } + } + if (vflag) { + TCHECK2(bp[10],2); + (void)printf(" (Hold-time "); + relts_print(EXTRACT_16BITS(&bp[10])); + (void)printf(")"); + } + break; + + case 1: + (void)printf(" Register"); + TCHECK2(bp[8], 20); /* ip header */ + (void)printf(" for %s > %s", ipaddr_string(&bp[20]), + ipaddr_string(&bp[24])); + break; + case 2: + (void)printf(" Register-Stop"); + TCHECK2(bp[12], sizeof(struct in_addr)); + (void)printf(" for %s > %s", ipaddr_string(&bp[8]), + ipaddr_string(&bp[12])); + break; + case 3: + (void)printf(" Join/Prune"); + if (vflag) + pimv1_join_prune_print(&bp[8], len - 8); + break; + case 4: + (void)printf(" RP-reachable"); + if (vflag) { + TCHECK2(bp[22], 2); + (void)printf(" group %s", + ipaddr_string(&bp[8])); + if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) + (void)printf("/%s", ipaddr_string(&bp[12])); + (void)printf(" RP %s hold ", ipaddr_string(&bp[16])); + relts_print(EXTRACT_16BITS(&bp[22])); + } + break; + case 5: + (void)printf(" Assert"); + TCHECK2(bp[16], sizeof(struct in_addr)); + (void)printf(" for %s > %s", ipaddr_string(&bp[16]), + ipaddr_string(&bp[8])); + if (EXTRACT_32BITS(&bp[12]) != 0xffffffff) + (void)printf("/%s", ipaddr_string(&bp[12])); + TCHECK2(bp[24], 4); + (void)printf(" %s pref %d metric %d", + (bp[20] & 0x80) ? "RP-tree" : "SPT", + EXTRACT_32BITS(&bp[20]) & 0x7fffffff, + EXTRACT_32BITS(&bp[24])); + break; + case 6: + (void)printf(" Graft"); + if (vflag) + pimv1_join_prune_print(&bp[8], len - 8); + break; + case 7: + (void)printf(" Graft-ACK"); + if (vflag) + pimv1_join_prune_print(&bp[8], len - 8); + break; + case 8: + (void)printf(" Mode"); + break; + default: + (void)printf(" [type %d]", type); + break; + } + if ((bp[4] >> 4) != 1) + (void)printf(" [v%d]", bp[4] >> 4); + return; + +trunc: + (void)printf("[|pim]"); + return; +} + +/* + * auto-RP is a cisco protocol, documented at + * ftp://ftpeng.cisco.com/ipmulticast/specs/pim-autorp-spec01.txt + * + * This implements version 1+, dated Sept 9, 1998. + */ +void +cisco_autorp_print(register const u_char *bp, register u_int len) +{ + int type; + int numrps; + int hold; + + TCHECK(bp[0]); + (void)printf(" auto-rp "); + type = bp[0]; + switch (type) { + case 0x11: + (void)printf("candidate-advert"); + break; + case 0x12: + (void)printf("mapping"); + break; + default: + (void)printf("type-0x%02x", type); + break; + } + + TCHECK(bp[1]); + numrps = bp[1]; + + TCHECK2(bp[2], 2); + (void)printf(" Hold "); + hold = EXTRACT_16BITS(&bp[2]); + if (hold) + relts_print(EXTRACT_16BITS(&bp[2])); + else + printf("FOREVER"); + + /* Next 4 bytes are reserved. */ + + bp += 8; len -= 8; + + /*XXX skip unless -v? */ + + /* + * Rest of packet: + * numrps entries of the form: + * 32 bits: RP + * 6 bits: reserved + * 2 bits: PIM version supported, bit 0 is "supports v1", 1 is "v2". + * 8 bits: # of entries for this RP + * each entry: 7 bits: reserved, 1 bit: negative, + * 8 bits: mask 32 bits: source + * lather, rinse, repeat. + */ + while (numrps--) { + int nentries; + char s; + + TCHECK2(bp[0], 4); + (void)printf(" RP %s", ipaddr_string(bp)); + TCHECK(bp[4]); + switch (bp[4] & 0x3) { + case 0: printf(" PIMv?"); + break; + case 1: printf(" PIMv1"); + break; + case 2: printf(" PIMv2"); + break; + case 3: printf(" PIMv1+2"); + break; + } + if (bp[4] & 0xfc) + (void)printf(" [rsvd=0x%02x]", bp[4] & 0xfc); + TCHECK(bp[5]); + nentries = bp[5]; + bp += 6; len -= 6; + s = ' '; + for (; nentries; nentries--) { + TCHECK2(bp[0], 6); + (void)printf("%c%s%s/%d", s, bp[0] & 1 ? "!" : "", + ipaddr_string(&bp[2]), bp[1]); + if (bp[0] & 0xfe) + (void)printf("[rsvd=0x%02x]", bp[0] & 0xfe); + s = ','; + bp += 6; len -= 6; + } + } + return; + +trunc: + (void)printf("[|autorp]"); + return; +} + +void +pim_print(register const u_char *bp, register u_int len, u_int cksum) +{ + register const u_char *ep; + register struct pim *pim = (struct pim *)bp; + + ep = (const u_char *)snapend; + if (bp >= ep) + return; +#ifdef notyet /* currently we see only version and type */ + TCHECK(pim->pim_rsv); +#endif + + switch (PIM_VER(pim->pim_typever)) { + case 2: + if (!vflag) { + printf("PIMv%u, %s, length %u", + PIM_VER(pim->pim_typever), + tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever)), + len); + return; + } else { + printf("PIMv%u, length %u\n\t%s", + PIM_VER(pim->pim_typever), + len, + tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever))); + pimv2_print(bp, len, cksum); + } + break; + default: + printf("PIMv%u, length %u", + PIM_VER(pim->pim_typever), + len); + break; + } + return; +} + +/* + * PIMv2 uses encoded address representations. + * + * The last PIM-SM I-D before RFC2117 was published specified the + * following representation for unicast addresses. However, RFC2117 + * specified no encoding for unicast addresses with the unicast + * address length specified in the header. Therefore, we have to + * guess which encoding is being used (Cisco's PIMv2 implementation + * uses the non-RFC encoding). RFC2117 turns a previously "Reserved" + * field into a 'unicast-address-length-in-bytes' field. We guess + * that it's the draft encoding if this reserved field is zero. + * + * RFC2362 goes back to the encoded format, and calls the addr length + * field "reserved" again. + * + * The first byte is the address family, from: + * + * 0 Reserved + * 1 IP (IP version 4) + * 2 IP6 (IP version 6) + * 3 NSAP + * 4 HDLC (8-bit multidrop) + * 5 BBN 1822 + * 6 802 (includes all 802 media plus Ethernet "canonical format") + * 7 E.163 + * 8 E.164 (SMDS, Frame Relay, ATM) + * 9 F.69 (Telex) + * 10 X.121 (X.25, Frame Relay) + * 11 IPX + * 12 Appletalk + * 13 Decnet IV + * 14 Banyan Vines + * 15 E.164 with NSAP format subaddress + * + * In addition, the second byte is an "Encoding". 0 is the default + * encoding for the address family, and no other encodings are currently + * specified. + * + */ + +static int pimv2_addr_len; + +enum pimv2_addrtype { + pimv2_unicast, pimv2_group, pimv2_source +}; + +/* 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Addr Family | Encoding Type | Unicast Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+++++++ + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Addr Family | Encoding Type | Reserved | Mask Len | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Group multicast Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Addr Family | Encoding Type | Rsrvd |S|W|R| Mask Len | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Source Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +static int +pimv2_addr_print(const u_char *bp, enum pimv2_addrtype at, int silent) +{ + int af; + int len, hdrlen; + + TCHECK(bp[0]); + + if (pimv2_addr_len == 0) { + TCHECK(bp[1]); + switch (bp[0]) { + case 1: + af = AF_INET; + len = sizeof(struct in_addr); + break; +#ifdef INET6 + case 2: + af = AF_INET6; + len = sizeof(struct in6_addr); + break; +#endif + default: + return -1; + } + if (bp[1] != 0) + return -1; + hdrlen = 2; + } else { + switch (pimv2_addr_len) { + case sizeof(struct in_addr): + af = AF_INET; + break; +#ifdef INET6 + case sizeof(struct in6_addr): + af = AF_INET6; + break; +#endif + default: + return -1; + break; + } + len = pimv2_addr_len; + hdrlen = 0; + } + + bp += hdrlen; + switch (at) { + case pimv2_unicast: + TCHECK2(bp[0], len); + if (af == AF_INET) { + if (!silent) + (void)printf("%s", ipaddr_string(bp)); + } +#ifdef INET6 + else if (af == AF_INET6) { + if (!silent) + (void)printf("%s", ip6addr_string(bp)); + } +#endif + return hdrlen + len; + case pimv2_group: + case pimv2_source: + TCHECK2(bp[0], len + 2); + if (af == AF_INET) { + if (!silent) { + (void)printf("%s", ipaddr_string(bp + 2)); + if (bp[1] != 32) + (void)printf("/%u", bp[1]); + } + } +#ifdef INET6 + else if (af == AF_INET6) { + if (!silent) { + (void)printf("%s", ip6addr_string(bp + 2)); + if (bp[1] != 128) + (void)printf("/%u", bp[1]); + } + } +#endif + if (bp[0] && !silent) { + if (at == pimv2_group) { + (void)printf("(0x%02x)", bp[0]); + } else { + (void)printf("(%s%s%s", + bp[0] & 0x04 ? "S" : "", + bp[0] & 0x02 ? "W" : "", + bp[0] & 0x01 ? "R" : ""); + if (bp[0] & 0xf8) { + (void) printf("+0x%02x", bp[0] & 0xf8); + } + (void)printf(")"); + } + } + return hdrlen + 2 + len; + default: + return -1; + } +trunc: + return -1; +} + +static void +pimv2_print(register const u_char *bp, register u_int len, u_int cksum) +{ + register const u_char *ep; + register struct pim *pim = (struct pim *)bp; + int advance; + + ep = (const u_char *)snapend; + if (bp >= ep) + return; + if (ep > bp + len) + ep = bp + len; + TCHECK(pim->pim_rsv); + pimv2_addr_len = pim->pim_rsv; + if (pimv2_addr_len != 0) + (void)printf(", RFC2117-encoding"); + + printf(", cksum 0x%04x ", EXTRACT_16BITS(&pim->pim_cksum)); + if (EXTRACT_16BITS(&pim->pim_cksum) == 0) { + printf("(unverified)"); + } else { + printf("(%scorrect)", TTEST2(bp[0], len) && cksum ? "in" : "" ); + } + + switch (PIM_TYPE(pim->pim_typever)) { + case PIMV2_TYPE_HELLO: + { + u_int16_t otype, olen; + bp += 4; + while (bp < ep) { + TCHECK2(bp[0], 4); + otype = EXTRACT_16BITS(&bp[0]); + olen = EXTRACT_16BITS(&bp[2]); + TCHECK2(bp[0], 4 + olen); + + printf("\n\t %s Option (%u), length %u, Value: ", + tok2str( pimv2_hello_option_values,"Unknown",otype), + otype, + olen); + bp += 4; + + switch (otype) { + case PIMV2_HELLO_OPTION_HOLDTIME: + relts_print(EXTRACT_16BITS(bp)); + break; + + case PIMV2_HELLO_OPTION_LANPRUNEDELAY: + if (olen != 4) { + (void)printf("ERROR: Option Lenght != 4 Bytes (%u)", olen); + } else { + char t_bit; + u_int16_t lan_delay, override_interval; + lan_delay = EXTRACT_16BITS(bp); + override_interval = EXTRACT_16BITS(bp+2); + t_bit = (lan_delay & 0x8000)? 1 : 0; + lan_delay &= ~0x8000; + (void)printf("\n\t T-bit=%d, LAN delay %dms, Override interval %dms", + t_bit, lan_delay, override_interval); + } + break; + + case PIMV2_HELLO_OPTION_DR_PRIORITY_OLD: + case PIMV2_HELLO_OPTION_DR_PRIORITY: + switch (olen) { + case 0: + printf("Bi-Directional Capability (Old)"); + break; + case 4: + printf("%u", EXTRACT_32BITS(bp)); + break; + default: + printf("ERROR: Option Lenght != 4 Bytes (%u)", olen); + break; + } + break; + + case PIMV2_HELLO_OPTION_GENID: + (void)printf("0x%08x", EXTRACT_32BITS(bp)); + break; + + case PIMV2_HELLO_OPTION_REFRESH_CAP: + (void)printf("v%d", *bp); + if (*(bp+1) != 0) { + (void)printf(", interval "); + relts_print(*(bp+1)); + } + if (EXTRACT_16BITS(bp+2) != 0) { + (void)printf(" ?0x%04x?", EXTRACT_16BITS(bp+2)); + } + break; + + case PIMV2_HELLO_OPTION_BIDIR_CAP: + break; + + case PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD: + case PIMV2_HELLO_OPTION_ADDRESS_LIST: + if (vflag > 1) { + const u_char *ptr = bp; + while (ptr < (bp+olen)) { + int advance; + + printf("\n\t "); + advance = pimv2_addr_print(ptr, pimv2_unicast, 0); + if (advance < 0) { + printf("..."); + break; + } + ptr += advance; + } + } + break; + default: + if (vflag <= 1) + print_unknown_data(bp,"\n\t ",olen); + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag> 1) + print_unknown_data(bp,"\n\t ",olen); + bp += olen; + } + break; + } + + case PIMV2_TYPE_REGISTER: + { + struct ip *ip; + + if (!TTEST2(*(bp+4), PIMV2_REGISTER_FLAG_LEN)) + goto trunc; + + printf(", Flags [ %s ]\n\t", + tok2str(pimv2_register_flag_values, + "none", + EXTRACT_32BITS(bp+4))); + + bp += 8; len -= 8; + /* encapsulated multicast packet */ + ip = (struct ip *)bp; + switch (IP_V(ip)) { + case 0: /* Null header */ + (void)printf("IP-Null-header %s > %s", + ipaddr_string(&ip->ip_src), + ipaddr_string(&ip->ip_dst)); + break; + + case 4: /* IPv4 */ + ip_print(gndo, bp, len); + break; +#ifdef INET6 + case 6: /* IPv6 */ + ip6_print(bp, len); + break; +#endif + default: + (void)printf("IP ver %d", IP_V(ip)); + break; + } + break; + } + + case PIMV2_TYPE_REGISTER_STOP: + bp += 4; len -= 4; + if (bp >= ep) + break; + (void)printf(" group="); + if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; len -= advance; + if (bp >= ep) + break; + (void)printf(" source="); + if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; len -= advance; + break; + + case PIMV2_TYPE_JOIN_PRUNE: + case PIMV2_TYPE_GRAFT: + case PIMV2_TYPE_GRAFT_ACK: + + + /* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |PIM Ver| Type | Addr length | Checksum | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Unicast-Upstream Neighbor Address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | Num groups | Holdtime | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encoded-Multicast Group Address-1 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Number of Joined Sources | Number of Pruned Sources | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encoded-Joined Source Address-1 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | . | + * | . | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encoded-Joined Source Address-n | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encoded-Pruned Source Address-1 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | . | + * | . | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encoded-Pruned Source Address-n | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | . | + * | . | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Encoded-Multicast Group Address-n | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + { + u_int8_t ngroup; + u_int16_t holdtime; + u_int16_t njoin; + u_int16_t nprune; + int i, j; + + bp += 4; len -= 4; + if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ + if (bp >= ep) + break; + (void)printf(", upstream-neighbor: "); + if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; len -= advance; + } + if (bp + 4 > ep) + break; + ngroup = bp[1]; + holdtime = EXTRACT_16BITS(&bp[2]); + (void)printf("\n\t %u group(s)", ngroup); + if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/ + (void)printf(", holdtime: "); + if (holdtime == 0xffff) + (void)printf("infinite"); + else + relts_print(holdtime); + } + bp += 4; len -= 4; + for (i = 0; i < ngroup; i++) { + if (bp >= ep) + goto jp_done; + (void)printf("\n\t group #%u: ", i+1); + if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { + (void)printf("...)"); + goto jp_done; + } + bp += advance; len -= advance; + if (bp + 4 > ep) { + (void)printf("...)"); + goto jp_done; + } + njoin = EXTRACT_16BITS(&bp[0]); + nprune = EXTRACT_16BITS(&bp[2]); + (void)printf(", joined sources: %u, pruned sources: %u", njoin,nprune); + bp += 4; len -= 4; + for (j = 0; j < njoin; j++) { + (void)printf("\n\t joined source #%u: ",j+1); + if ((advance = pimv2_addr_print(bp, pimv2_source, 0)) < 0) { + (void)printf("...)"); + goto jp_done; + } + bp += advance; len -= advance; + } + for (j = 0; j < nprune; j++) { + (void)printf("\n\t pruned source #%u: ",j+1); + if ((advance = pimv2_addr_print(bp, pimv2_source, 0)) < 0) { + (void)printf("...)"); + goto jp_done; + } + bp += advance; len -= advance; + } + } + jp_done: + break; + } + + case PIMV2_TYPE_BOOTSTRAP: + { + int i, j, frpcnt; + bp += 4; + + /* Fragment Tag, Hash Mask len, and BSR-priority */ + if (bp + sizeof(u_int16_t) >= ep) break; + (void)printf(" tag=%x", EXTRACT_16BITS(bp)); + bp += sizeof(u_int16_t); + if (bp >= ep) break; + (void)printf(" hashmlen=%d", bp[0]); + if (bp + 1 >= ep) break; + (void)printf(" BSRprio=%d", bp[1]); + bp += 2; + + /* Encoded-Unicast-BSR-Address */ + if (bp >= ep) break; + (void)printf(" BSR="); + if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; + + for (i = 0; bp < ep; i++) { + /* Encoded-Group Address */ + (void)printf(" (group%d: ", i); + if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) + < 0) { + (void)printf("...)"); + goto bs_done; + } + bp += advance; + + /* RP-Count, Frag RP-Cnt, and rsvd */ + if (bp >= ep) { + (void)printf("...)"); + goto bs_done; + } + (void)printf(" RPcnt=%d", bp[0]); + if (bp + 1 >= ep) { + (void)printf("...)"); + goto bs_done; + } + (void)printf(" FRPcnt=%d", frpcnt = bp[1]); + bp += 4; + + for (j = 0; j < frpcnt && bp < ep; j++) { + /* each RP info */ + (void)printf(" RP%d=", j); + if ((advance = pimv2_addr_print(bp, + pimv2_unicast, + 0)) < 0) { + (void)printf("...)"); + goto bs_done; + } + bp += advance; + + if (bp + 1 >= ep) { + (void)printf("...)"); + goto bs_done; + } + (void)printf(",holdtime="); + relts_print(EXTRACT_16BITS(bp)); + if (bp + 2 >= ep) { + (void)printf("...)"); + goto bs_done; + } + (void)printf(",prio=%d", bp[2]); + bp += 4; + } + (void)printf(")"); + } + bs_done: + break; + } + case PIMV2_TYPE_ASSERT: + bp += 4; len -= 4; + if (bp >= ep) + break; + (void)printf(" group="); + if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; len -= advance; + if (bp >= ep) + break; + (void)printf(" src="); + if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; len -= advance; + if (bp + 8 > ep) + break; + if (bp[0] & 0x80) + (void)printf(" RPT"); + (void)printf(" pref=%u", EXTRACT_32BITS(&bp[0]) & 0x7fffffff); + (void)printf(" metric=%u", EXTRACT_32BITS(&bp[4])); + break; + + case PIMV2_TYPE_CANDIDATE_RP: + { + int i, pfxcnt; + bp += 4; + + /* Prefix-Cnt, Priority, and Holdtime */ + if (bp >= ep) break; + (void)printf(" prefix-cnt=%d", bp[0]); + pfxcnt = bp[0]; + if (bp + 1 >= ep) break; + (void)printf(" prio=%d", bp[1]); + if (bp + 3 >= ep) break; + (void)printf(" holdtime="); + relts_print(EXTRACT_16BITS(&bp[2])); + bp += 4; + + /* Encoded-Unicast-RP-Address */ + if (bp >= ep) break; + (void)printf(" RP="); + if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; + + /* Encoded-Group Addresses */ + for (i = 0; i < pfxcnt && bp < ep; i++) { + (void)printf(" Group%d=", i); + if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) + < 0) { + (void)printf("..."); + break; + } + bp += advance; + } + break; + } + + case PIMV2_TYPE_PRUNE_REFRESH: + (void)printf(" src="); + if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; + (void)printf(" grp="); + if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; + (void)printf(" forwarder="); + if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) { + (void)printf("..."); + break; + } + bp += advance; + TCHECK2(bp[0], 2); + (void)printf(" TUNR "); + relts_print(EXTRACT_16BITS(bp)); + break; + + + default: + (void)printf(" [type %d]", PIM_TYPE(pim->pim_typever)); + break; + } + + return; + +trunc: + (void)printf("[|pim]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-ppp.c b/print-ppp.c new file mode 100644 index 0000000..7f231ea --- /dev/null +++ b/print-ppp.c @@ -0,0 +1,1757 @@ +/* + * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Extensively modified by Motonori Shindo (mshindo@mshindo.net) for more + * complete PPP support. + */ + +/* + * TODO: + * o resolve XXX as much as possible + * o MP support + * o BAP support + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.114 2005-12-05 11:35:58 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifdef __bsdi__ +#include +#include +#endif + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ppp.h" +#include "chdlc.h" +#include "ethertype.h" +#include "oui.h" + +/* + * The following constatns are defined by IANA. Please refer to + * http://www.isi.edu/in-notes/iana/assignments/ppp-numbers + * for the up-to-date information. + */ + +/* Protocol Codes defined in ppp.h */ + +struct tok ppptype2str[] = { + { PPP_IP, "IP" }, + { PPP_OSI, "OSI" }, + { PPP_NS, "NS" }, + { PPP_DECNET, "DECNET" }, + { PPP_APPLE, "APPLE" }, + { PPP_IPX, "IPX" }, + { PPP_VJC, "VJC IP" }, + { PPP_VJNC, "VJNC IP" }, + { PPP_BRPDU, "BRPDU" }, + { PPP_STII, "STII" }, + { PPP_VINES, "VINES" }, + { PPP_MPLS_UCAST, "MPLS" }, + { PPP_MPLS_MCAST, "MPLS" }, + { PPP_COMP, "Compressed"}, + { PPP_ML, "MLPPP"}, + { PPP_IPV6, "IP6"}, + + { PPP_HELLO, "HELLO" }, + { PPP_LUXCOM, "LUXCOM" }, + { PPP_SNS, "SNS" }, + { PPP_IPCP, "IPCP" }, + { PPP_OSICP, "OSICP" }, + { PPP_NSCP, "NSCP" }, + { PPP_DECNETCP, "DECNETCP" }, + { PPP_APPLECP, "APPLECP" }, + { PPP_IPXCP, "IPXCP" }, + { PPP_STIICP, "STIICP" }, + { PPP_VINESCP, "VINESCP" }, + { PPP_IPV6CP, "IP6CP" }, + { PPP_MPLSCP, "MPLSCP" }, + + { PPP_LCP, "LCP" }, + { PPP_PAP, "PAP" }, + { PPP_LQM, "LQM" }, + { PPP_CHAP, "CHAP" }, + { PPP_EAP, "EAP" }, + { PPP_SPAP, "SPAP" }, + { PPP_SPAP_OLD, "Old-SPAP" }, + { PPP_BACP, "BACP" }, + { PPP_BAP, "BAP" }, + { PPP_MPCP, "MLPPP-CP" }, + { 0, NULL } +}; + +/* Control Protocols (LCP/IPCP/CCP etc.) Codes defined in RFC 1661 */ + +#define CPCODES_VEXT 0 /* Vendor-Specific (RFC2153) */ +#define CPCODES_CONF_REQ 1 /* Configure-Request */ +#define CPCODES_CONF_ACK 2 /* Configure-Ack */ +#define CPCODES_CONF_NAK 3 /* Configure-Nak */ +#define CPCODES_CONF_REJ 4 /* Configure-Reject */ +#define CPCODES_TERM_REQ 5 /* Terminate-Request */ +#define CPCODES_TERM_ACK 6 /* Terminate-Ack */ +#define CPCODES_CODE_REJ 7 /* Code-Reject */ +#define CPCODES_PROT_REJ 8 /* Protocol-Reject (LCP only) */ +#define CPCODES_ECHO_REQ 9 /* Echo-Request (LCP only) */ +#define CPCODES_ECHO_RPL 10 /* Echo-Reply (LCP only) */ +#define CPCODES_DISC_REQ 11 /* Discard-Request (LCP only) */ +#define CPCODES_ID 12 /* Identification (LCP only) RFC1570 */ +#define CPCODES_TIME_REM 13 /* Time-Remaining (LCP only) RFC1570 */ +#define CPCODES_RESET_REQ 14 /* Reset-Request (CCP only) RFC1962 */ +#define CPCODES_RESET_REP 15 /* Reset-Reply (CCP only) */ + +struct tok cpcodes[] = { + {CPCODES_VEXT, "Vendor-Extension"}, /* RFC2153 */ + {CPCODES_CONF_REQ, "Conf-Request"}, + {CPCODES_CONF_ACK, "Conf-Ack"}, + {CPCODES_CONF_NAK, "Conf-Nack"}, + {CPCODES_CONF_REJ, "Conf-Reject"}, + {CPCODES_TERM_REQ, "Term-Request"}, + {CPCODES_TERM_ACK, "Term-Ack"}, + {CPCODES_CODE_REJ, "Code-Reject"}, + {CPCODES_PROT_REJ, "Prot-Reject"}, + {CPCODES_ECHO_REQ, "Echo-Request"}, + {CPCODES_ECHO_RPL, "Echo-Reply"}, + {CPCODES_DISC_REQ, "Disc-Req"}, + {CPCODES_ID, "Ident"}, /* RFC1570 */ + {CPCODES_TIME_REM, "Time-Rem"}, /* RFC1570 */ + {CPCODES_RESET_REQ, "Reset-Req"}, /* RFC1962 */ + {CPCODES_RESET_REP, "Reset-Ack"}, /* RFC1962 */ + {0, NULL} +}; + +/* LCP Config Options */ + +#define LCPOPT_VEXT 0 +#define LCPOPT_MRU 1 +#define LCPOPT_ACCM 2 +#define LCPOPT_AP 3 +#define LCPOPT_QP 4 +#define LCPOPT_MN 5 +#define LCPOPT_DEP6 6 +#define LCPOPT_PFC 7 +#define LCPOPT_ACFC 8 +#define LCPOPT_FCSALT 9 +#define LCPOPT_SDP 10 +#define LCPOPT_NUMMODE 11 +#define LCPOPT_DEP12 12 +#define LCPOPT_CBACK 13 +#define LCPOPT_DEP14 14 +#define LCPOPT_DEP15 15 +#define LCPOPT_DEP16 16 +#define LCPOPT_MLMRRU 17 +#define LCPOPT_MLSSNHF 18 +#define LCPOPT_MLED 19 +#define LCPOPT_PROP 20 +#define LCPOPT_DCEID 21 +#define LCPOPT_MPP 22 +#define LCPOPT_LD 23 +#define LCPOPT_LCPAOPT 24 +#define LCPOPT_COBS 25 +#define LCPOPT_PE 26 +#define LCPOPT_MLHF 27 +#define LCPOPT_I18N 28 +#define LCPOPT_SDLOS 29 +#define LCPOPT_PPPMUX 30 + +#define LCPOPT_MIN LCPOPT_VEXT +#define LCPOPT_MAX LCPOPT_PPPMUX + +static const char *lcpconfopts[] = { + "Vend-Ext", /* (0) */ + "MRU", /* (1) */ + "ACCM", /* (2) */ + "Auth-Prot", /* (3) */ + "Qual-Prot", /* (4) */ + "Magic-Num", /* (5) */ + "deprecated(6)", /* used to be a Quality Protocol */ + "PFC", /* (7) */ + "ACFC", /* (8) */ + "FCS-Alt", /* (9) */ + "SDP", /* (10) */ + "Num-Mode", /* (11) */ + "deprecated(12)", /* used to be a Multi-Link-Procedure*/ + "Call-Back", /* (13) */ + "deprecated(14)", /* used to be a Connect-Time */ + "deprecated(15)", /* used to be a Compund-Frames */ + "deprecated(16)", /* used to be a Nominal-Data-Encap */ + "MRRU", /* (17) */ + "12-Bit seq #", /* (18) */ + "End-Disc", /* (19) */ + "Proprietary", /* (20) */ + "DCE-Id", /* (21) */ + "MP+", /* (22) */ + "Link-Disc", /* (23) */ + "LCP-Auth-Opt", /* (24) */ + "COBS", /* (25) */ + "Prefix-elision", /* (26) */ + "Multilink-header-Form",/* (27) */ + "I18N", /* (28) */ + "SDL-over-SONET/SDH", /* (29) */ + "PPP-Muxing", /* (30) */ +}; + +/* ECP - to be supported */ + +/* CCP Config Options */ + +#define CCPOPT_OUI 0 /* RFC1962 */ +#define CCPOPT_PRED1 1 /* RFC1962 */ +#define CCPOPT_PRED2 2 /* RFC1962 */ +#define CCPOPT_PJUMP 3 /* RFC1962 */ +/* 4-15 unassigned */ +#define CCPOPT_HPPPC 16 /* RFC1962 */ +#define CCPOPT_STACLZS 17 /* RFC1974 */ +#define CCPOPT_MPPC 18 /* RFC2118 */ +#define CCPOPT_GFZA 19 /* RFC1962 */ +#define CCPOPT_V42BIS 20 /* RFC1962 */ +#define CCPOPT_BSDCOMP 21 /* RFC1977 */ +/* 22 unassigned */ +#define CCPOPT_LZSDCP 23 /* RFC1967 */ +#define CCPOPT_MVRCA 24 /* RFC1975 */ +#define CCPOPT_DEC 25 /* RFC1976 */ +#define CCPOPT_DEFLATE 26 /* RFC1979 */ +/* 27-254 unassigned */ +#define CCPOPT_RESV 255 /* RFC1962 */ + +const struct tok ccpconfopts_values[] = { + { CCPOPT_OUI, "OUI" }, + { CCPOPT_PRED1, "Pred-1" }, + { CCPOPT_PRED2, "Pred-2" }, + { CCPOPT_PJUMP, "Puddle" }, + { CCPOPT_HPPPC, "HP-PPC" }, + { CCPOPT_STACLZS, "Stac-LZS" }, + { CCPOPT_MPPC, "MPPC" }, + { CCPOPT_GFZA, "Gand-FZA" }, + { CCPOPT_V42BIS, "V.42bis" }, + { CCPOPT_BSDCOMP, "BSD-Comp" }, + { CCPOPT_LZSDCP, "LZS-DCP" }, + { CCPOPT_MVRCA, "MVRCA" }, + { CCPOPT_DEC, "DEC" }, + { CCPOPT_DEFLATE, "Deflate" }, + { CCPOPT_RESV, "Reserved"}, + {0, NULL} +}; + +/* BACP Config Options */ + +#define BACPOPT_FPEER 1 /* RFC2125 */ + +const struct tok bacconfopts_values[] = { + { BACPOPT_FPEER, "Favored-Peer" }, + {0, NULL} +}; + + +/* SDCP - to be supported */ + +/* IPCP Config Options */ +#define IPCPOPT_2ADDR 1 /* RFC1172, RFC1332 (deprecated) */ +#define IPCPOPT_IPCOMP 2 /* RFC1332 */ +#define IPCPOPT_ADDR 3 /* RFC1332 */ +#define IPCPOPT_MOBILE4 4 /* RFC2290 */ +#define IPCPOPT_PRIDNS 129 /* RFC1877 */ +#define IPCPOPT_PRINBNS 130 /* RFC1877 */ +#define IPCPOPT_SECDNS 131 /* RFC1877 */ +#define IPCPOPT_SECNBNS 132 /* RFC1877 */ + +struct tok ipcpopt_values[] = { + { IPCPOPT_2ADDR, "IP-Addrs" }, + { IPCPOPT_IPCOMP, "IP-Comp" }, + { IPCPOPT_ADDR, "IP-Addr" }, + { IPCPOPT_MOBILE4, "Home-Addr" }, + { IPCPOPT_PRIDNS, "Pri-DNS" }, + { IPCPOPT_PRINBNS, "Pri-NBNS" }, + { IPCPOPT_SECDNS, "Sec-DNS" }, + { IPCPOPT_SECNBNS, "Sec-NBNS" }, + { 0, NULL } +}; + +#define IPCPOPT_IPCOMP_HDRCOMP 0x61 /* rfc3544 */ +#define IPCPOPT_IPCOMP_MINLEN 14 + +struct tok ipcpopt_compproto_values[] = { + { PPP_VJC, "VJ-Comp" }, + { IPCPOPT_IPCOMP_HDRCOMP, "IP Header Compression" }, + { 0, NULL } +}; + +struct tok ipcpopt_compproto_subopt_values[] = { + { 1, "RTP-Compression" }, + { 2, "Enhanced RTP-Compression" }, + { 0, NULL } +}; + +/* IP6CP Config Options */ +#define IP6CP_IFID 1 + +struct tok ip6cpopt_values[] = { + { IP6CP_IFID, "Interface-ID" }, + { 0, NULL } +}; + +/* ATCP - to be supported */ +/* OSINLCP - to be supported */ +/* BVCP - to be supported */ +/* BCP - to be supported */ +/* IPXCP - to be supported */ +/* MPLSCP - to be supported */ + +/* Auth Algorithms */ + +/* 0-4 Reserved (RFC1994) */ +#define AUTHALG_CHAPMD5 5 /* RFC1994 */ +#define AUTHALG_MSCHAP1 128 /* RFC2433 */ +#define AUTHALG_MSCHAP2 129 /* RFC2795 */ + +struct tok authalg_values[] = { + { AUTHALG_CHAPMD5, "MD5" }, + { AUTHALG_MSCHAP1, "MS-CHAPv1" }, + { AUTHALG_MSCHAP2, "MS-CHAPv2" }, + { 0, NULL } +}; + +/* FCS Alternatives - to be supported */ + +/* Multilink Endpoint Discriminator (RFC1717) */ +#define MEDCLASS_NULL 0 /* Null Class */ +#define MEDCLASS_LOCAL 1 /* Locally Assigned */ +#define MEDCLASS_IPV4 2 /* Internet Protocol (IPv4) */ +#define MEDCLASS_MAC 3 /* IEEE 802.1 global MAC address */ +#define MEDCLASS_MNB 4 /* PPP Magic Number Block */ +#define MEDCLASS_PSNDN 5 /* Public Switched Network Director Number */ + +/* PPP LCP Callback */ +#define CALLBACK_AUTH 0 /* Location determined by user auth */ +#define CALLBACK_DSTR 1 /* Dialing string */ +#define CALLBACK_LID 2 /* Location identifier */ +#define CALLBACK_E164 3 /* E.164 number */ +#define CALLBACK_X500 4 /* X.500 distinguished name */ +#define CALLBACK_CBCP 6 /* Location is determined during CBCP nego */ + +struct tok ppp_callback_values[] = { + { CALLBACK_AUTH, "UserAuth" }, + { CALLBACK_DSTR, "DialString" }, + { CALLBACK_LID, "LocalID" }, + { CALLBACK_E164, "E.164" }, + { CALLBACK_X500, "X.500" }, + { CALLBACK_CBCP, "CBCP" }, + { 0, NULL } +}; + +/* CHAP */ + +#define CHAP_CHAL 1 +#define CHAP_RESP 2 +#define CHAP_SUCC 3 +#define CHAP_FAIL 4 + +struct tok chapcode_values[] = { + { CHAP_CHAL, "Challenge" }, + { CHAP_RESP, "Response" }, + { CHAP_SUCC, "Success" }, + { CHAP_FAIL, "Fail" }, + { 0, NULL} +}; + +/* PAP */ + +#define PAP_AREQ 1 +#define PAP_AACK 2 +#define PAP_ANAK 3 + +struct tok papcode_values[] = { + { PAP_AREQ, "Auth-Req" }, + { PAP_AACK, "Auth-ACK" }, + { PAP_ANAK, "Auth-NACK" }, + { 0, NULL } +}; + +/* BAP */ +#define BAP_CALLREQ 1 +#define BAP_CALLRES 2 +#define BAP_CBREQ 3 +#define BAP_CBRES 4 +#define BAP_LDQREQ 5 +#define BAP_LDQRES 6 +#define BAP_CSIND 7 +#define BAP_CSRES 8 + +static void handle_ctrl_proto (u_int proto,const u_char *p, int length); +static void handle_chap (const u_char *p, int length); +static void handle_pap (const u_char *p, int length); +static void handle_bap (const u_char *p, int length); +static void handle_mlppp(const u_char *p, int length); +static int print_lcp_config_options (const u_char *p, int); +static int print_ipcp_config_options (const u_char *p, int); +static int print_ip6cp_config_options (const u_char *p, int); +static int print_ccp_config_options (const u_char *p, int); +static int print_bacp_config_options (const u_char *p, int); +static void handle_ppp (u_int proto, const u_char *p, int length); +static void ppp_hdlc(const u_char *p, int length); + +/* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */ +static void +handle_ctrl_proto(u_int proto, const u_char *pptr, int length) +{ + const char *typestr; + u_int code, len; + int (*pfunc)(const u_char *, int); + int x, j; + const u_char *tptr; + + tptr=pptr; + + typestr = tok2str(ppptype2str, "unknown ctrl-proto (0x%04x)", proto); + printf("%s, ",typestr); + + if (length < 4) /* FIXME weak boundary checking */ + goto trunc; + TCHECK2(*tptr, 2); + + code = *tptr++; + + printf("%s (0x%02x), id %u, length %u", + tok2str(cpcodes, "Unknown Opcode",code), + code, + *tptr++, /* ID */ + length+2); + + if (!vflag) + return; + + if (length <= 4) + return; /* there may be a NULL confreq etc. */ + + TCHECK2(*tptr, 2); + len = EXTRACT_16BITS(tptr); + tptr += 2; + + printf("\n\tencoded length %u (=Option(s) length %u)",len,len-4); + + if (vflag>1) + print_unknown_data(pptr-2,"\n\t",6); + + + switch (code) { + case CPCODES_VEXT: + if (length < 11) + break; + TCHECK2(*tptr, 4); + printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); + tptr += 4; + TCHECK2(*tptr, 3); + printf(" Vendor: %s (%u)", + tok2str(oui_values,"Unknown",EXTRACT_24BITS(tptr)), + EXTRACT_24BITS(tptr)); + /* XXX: need to decode Kind and Value(s)? */ + break; + case CPCODES_CONF_REQ: + case CPCODES_CONF_ACK: + case CPCODES_CONF_NAK: + case CPCODES_CONF_REJ: + x = len - 4; /* Code(1), Identifier(1) and Length(2) */ + do { + switch (proto) { + case PPP_LCP: + pfunc = print_lcp_config_options; + break; + case PPP_IPCP: + pfunc = print_ipcp_config_options; + break; + case PPP_IPV6CP: + pfunc = print_ip6cp_config_options; + break; + case PPP_CCP: + pfunc = print_ccp_config_options; + break; + case PPP_BACP: + pfunc = print_bacp_config_options; + break; + default: + /* + * No print routine for the options for + * this protocol. + */ + pfunc = NULL; + break; + } + + if (pfunc == NULL) /* catch the above null pointer if unknown CP */ + break; + + if ((j = (*pfunc)(tptr, len)) == 0) + break; + x -= j; + tptr += j; + } while (x > 0); + break; + + case CPCODES_TERM_REQ: + case CPCODES_TERM_ACK: + /* XXX: need to decode Data? */ + break; + case CPCODES_CODE_REJ: + /* XXX: need to decode Rejected-Packet? */ + break; + case CPCODES_PROT_REJ: + if (length < 6) + break; + TCHECK2(*tptr, 2); + printf("\n\t Rejected %s Protocol (0x%04x)", + tok2str(ppptype2str,"unknown", EXTRACT_16BITS(tptr)), + EXTRACT_16BITS(tptr)); + /* XXX: need to decode Rejected-Information? - hexdump for now */ + if (len > 6) { + printf("\n\t Rejected Packet"); + print_unknown_data(tptr+2,"\n\t ",len-2); + } + break; + case CPCODES_ECHO_REQ: + case CPCODES_ECHO_RPL: + case CPCODES_DISC_REQ: + if (length < 8) + break; + TCHECK2(*tptr, 4); + printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); + /* XXX: need to decode Data? - hexdump for now */ + if (len > 8) { + printf("\n\t -----trailing data-----"); + TCHECK2(tptr[4], len-8); + print_unknown_data(tptr+4,"\n\t ",len-8); + } + break; + case CPCODES_ID: + if (length < 8) + break; + TCHECK2(*tptr, 4); + printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); + /* RFC 1661 says this is intended to be human readable */ + if (len > 8) { + printf("\n\t Message\n\t "); + fn_printn(tptr+4,len-4,snapend); + } + break; + case CPCODES_TIME_REM: + if (length < 12) + break; + TCHECK2(*tptr, 4); + printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); + TCHECK2(*(tptr + 4), 4); + printf(", Seconds-Remaining %us", EXTRACT_32BITS(tptr + 4)); + /* XXX: need to decode Message? */ + break; + default: + /* XXX this is dirty but we do not get the + * original pointer passed to the begin + * the PPP packet */ + if (vflag <= 1) + print_unknown_data(pptr-2,"\n\t ",length+2); + break; + } + return; + +trunc: + printf("[|%s]", typestr); +} + +/* LCP config options */ +static int +print_lcp_config_options(const u_char *p, int length) +{ + int len, opt; + + if (length < 2) + return 0; + TCHECK2(*p, 2); + len = p[1]; + opt = p[0]; + if (length < len) + return 0; + if (len < 2) { + if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) + printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", lcpconfopts[opt],opt,len); + else + printf("\n\tunknown LCP option 0x%02x", opt); + return 0; + } + if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) + printf("\n\t %s Option (0x%02x), length %u: ", lcpconfopts[opt],opt,len); + else { + printf("\n\tunknown LCP option 0x%02x", opt); + return len; + } + + switch (opt) { + case LCPOPT_VEXT: + if (len >= 6) { + TCHECK2(*(p + 2), 3); + printf("Vendor: %s (%u)", + tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)), + EXTRACT_24BITS(p+2)); +#if 0 + TCHECK(p[5]); + printf(", kind: 0x%02x", p[5]); + printf(", Value: 0x") + for (i = 0; i < len - 6; i++) { + TCHECK(p[6 + i]); + printf("%02x", p[6 + i]); + } +#endif + } + break; + case LCPOPT_MRU: + if (len == 4) { + TCHECK2(*(p + 2), 2); + printf("%u", EXTRACT_16BITS(p + 2)); + } + break; + case LCPOPT_ACCM: + if (len == 6) { + TCHECK2(*(p + 2), 4); + printf("0x%08x", EXTRACT_32BITS(p + 2)); + } + break; + case LCPOPT_AP: + if (len >= 4) { + TCHECK2(*(p + 2), 2); + printf("%s", tok2str(ppptype2str,"Unknown Auth Proto (0x04x)",EXTRACT_16BITS(p+2))); + + switch (EXTRACT_16BITS(p+2)) { + case PPP_CHAP: + TCHECK(p[4]); + printf(", %s",tok2str(authalg_values,"Unknown Auth Alg %u",p[4])); + break; + case PPP_PAP: /* fall through */ + case PPP_EAP: + case PPP_SPAP: + case PPP_SPAP_OLD: + break; + default: + print_unknown_data(p,"\n\t",len); + } + } + break; + case LCPOPT_QP: + if (len >= 4) { + TCHECK2(*(p + 2), 2); + if (EXTRACT_16BITS(p+2) == PPP_LQM) + printf(" LQR"); + else + printf(" unknown"); + } + break; + case LCPOPT_MN: + if (len == 6) { + TCHECK2(*(p + 2), 4); + printf("0x%08x", EXTRACT_32BITS(p + 2)); + } + break; + case LCPOPT_PFC: + break; + case LCPOPT_ACFC: + break; + case LCPOPT_LD: + if (len == 4) { + TCHECK2(*(p + 2), 2); + printf("0x%04x", EXTRACT_16BITS(p + 2)); + } + break; + case LCPOPT_CBACK: + if (len < 3) + break; + TCHECK(p[2]); + printf("Callback Operation %s (%u)", + tok2str(ppp_callback_values,"Unknown",p[2]), + p[2]); + break; + case LCPOPT_MLMRRU: + if (len == 4) { + TCHECK2(*(p + 2), 2); + printf("%u", EXTRACT_16BITS(p + 2)); + } + break; + case LCPOPT_MLED: + if (len < 3) + break; + TCHECK(p[2]); + switch (p[2]) { /* class */ + case MEDCLASS_NULL: + printf("Null"); + break; + case MEDCLASS_LOCAL: + printf("Local"); /* XXX */ + break; + case MEDCLASS_IPV4: + if (len != 7) + break; + TCHECK2(*(p + 3), 4); + printf("IPv4 %s", ipaddr_string(p + 3)); + break; + case MEDCLASS_MAC: + if (len != 9) + break; + TCHECK(p[8]); + printf("MAC %02x:%02x:%02x:%02x:%02x:%02x", + p[3], p[4], p[5], p[6], p[7], p[8]); + break; + case MEDCLASS_MNB: + printf("Magic-Num-Block"); /* XXX */ + break; + case MEDCLASS_PSNDN: + printf("PSNDN"); /* XXX */ + break; + } + break; + +/* XXX: to be supported */ +#if 0 + case LCPOPT_DEP6: + case LCPOPT_FCSALT: + case LCPOPT_SDP: + case LCPOPT_NUMMODE: + case LCPOPT_DEP12: + case LCPOPT_DEP14: + case LCPOPT_DEP15: + case LCPOPT_DEP16: + case LCPOPT_MLSSNHF: + case LCPOPT_PROP: + case LCPOPT_DCEID: + case LCPOPT_MPP: + case LCPOPT_LCPAOPT: + case LCPOPT_COBS: + case LCPOPT_PE: + case LCPOPT_MLHF: + case LCPOPT_I18N: + case LCPOPT_SDLOS: + case LCPOPT_PPPMUX: + break; +#endif + default: + if(vflag<2) + print_unknown_data(&p[2],"\n\t ",len-2); + break; + } + + if (vflag>1) + print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ + + return len; + +trunc: + printf("[|lcp]"); + return 0; +} + +/* ML-PPP*/ +struct tok ppp_ml_flag_values[] = { + { 0x80, "begin" }, + { 0x40, "end" }, + { 0, NULL } +}; + +static void +handle_mlppp(const u_char *p, int length) { + + if (!eflag) + printf("MLPPP, "); + + printf("seq 0x%03x, Flags [%s], length %u", + (EXTRACT_16BITS(p))&0x0fff, /* only support 12-Bit sequence space for now */ + bittok2str(ppp_ml_flag_values, "none", *p & 0xc0), + length); + + return; +} + +/* CHAP */ +static void +handle_chap(const u_char *p, int length) +{ + u_int code, len; + int val_size, name_size, msg_size; + const u_char *p0; + int i; + + p0 = p; + if (length < 1) { + printf("[|chap]"); + return; + } else if (length < 4) { + TCHECK(*p); + printf("[|chap 0x%02x]", *p); + return; + } + + TCHECK(*p); + code = *p; + printf("CHAP, %s (0x%02x)", + tok2str(chapcode_values,"unknown",code), + code); + p++; + + TCHECK(*p); + printf(", id %u", *p); /* ID */ + p++; + + TCHECK2(*p, 2); + len = EXTRACT_16BITS(p); + p += 2; + + /* + * Note that this is a generic CHAP decoding routine. Since we + * don't know which flavor of CHAP (i.e. CHAP-MD5, MS-CHAPv1, + * MS-CHAPv2) is used at this point, we can't decode packet + * specifically to each algorithms. Instead, we simply decode + * the GCD (Gratest Common Denominator) for all algorithms. + */ + switch (code) { + case CHAP_CHAL: + case CHAP_RESP: + if (length - (p - p0) < 1) + return; + TCHECK(*p); + val_size = *p; /* value size */ + p++; + if (length - (p - p0) < val_size) + return; + printf(", Value "); + for (i = 0; i < val_size; i++) { + TCHECK(*p); + printf("%02x", *p++); + } + name_size = len - (p - p0); + printf(", Name "); + for (i = 0; i < name_size; i++) { + TCHECK(*p); + safeputchar(*p++); + } + break; + case CHAP_SUCC: + case CHAP_FAIL: + msg_size = len - (p - p0); + printf(", Msg "); + for (i = 0; i< msg_size; i++) { + TCHECK(*p); + safeputchar(*p++); + } + break; + } + return; + +trunc: + printf("[|chap]"); +} + +/* PAP (see RFC 1334) */ +static void +handle_pap(const u_char *p, int length) +{ + u_int code, len; + int peerid_len, passwd_len, msg_len; + const u_char *p0; + int i; + + p0 = p; + if (length < 1) { + printf("[|pap]"); + return; + } else if (length < 4) { + TCHECK(*p); + printf("[|pap 0x%02x]", *p); + return; + } + + TCHECK(*p); + code = *p; + printf("PAP, %s (0x%02x)", + tok2str(papcode_values,"unknown",code), + code); + p++; + + TCHECK(*p); + printf(", id %u", *p); /* ID */ + p++; + + TCHECK2(*p, 2); + len = EXTRACT_16BITS(p); + p += 2; + + if ((int)len > length) { + printf(", length %u > packet size", len); + return; + } + length = len; + if (length < (p - p0)) { + printf(", length %u < PAP header length", length); + return; + } + + switch (code) { + case PAP_AREQ: + if (length - (p - p0) < 1) + return; + TCHECK(*p); + peerid_len = *p; /* Peer-ID Length */ + p++; + if (length - (p - p0) < peerid_len) + return; + printf(", Peer "); + for (i = 0; i < peerid_len; i++) { + TCHECK(*p); + safeputchar(*p++); + } + + if (length - (p - p0) < 1) + return; + TCHECK(*p); + passwd_len = *p; /* Password Length */ + p++; + if (length - (p - p0) < passwd_len) + return; + printf(", Name "); + for (i = 0; i < passwd_len; i++) { + TCHECK(*p); + safeputchar(*p++); + } + break; + case PAP_AACK: + case PAP_ANAK: + if (length - (p - p0) < 1) + return; + TCHECK(*p); + msg_len = *p; /* Msg-Length */ + p++; + if (length - (p - p0) < msg_len) + return; + printf(", Msg "); + for (i = 0; i< msg_len; i++) { + TCHECK(*p); + safeputchar(*p++); + } + break; + } + return; + +trunc: + printf("[|pap]"); +} + +/* BAP */ +static void +handle_bap(const u_char *p _U_, int length _U_) +{ + /* XXX: to be supported!! */ +} + + +/* IPCP config options */ +static int +print_ipcp_config_options(const u_char *p, int length) +{ + int len, opt; + u_int compproto, ipcomp_subopttotallen, ipcomp_subopt, ipcomp_suboptlen; + + if (length < 2) + return 0; + TCHECK2(*p, 2); + len = p[1]; + opt = p[0]; + if (length < len) + return 0; + if (len < 2) { + printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", + tok2str(ipcpopt_values,"unknown",opt), + opt, + len); + return 0; + } + + printf("\n\t %s Option (0x%02x), length %u: ", + tok2str(ipcpopt_values,"unknown",opt), + opt, + len); + + switch (opt) { + case IPCPOPT_2ADDR: /* deprecated */ + if (len != 10) + goto invlen; + TCHECK2(*(p + 6), 4); + printf("src %s, dst %s", + ipaddr_string(p + 2), + ipaddr_string(p + 6)); + break; + case IPCPOPT_IPCOMP: + if (len < 4) + goto invlen; + TCHECK2(*(p + 2), 2); + compproto = EXTRACT_16BITS(p+2); + + printf("%s (0x%02x):", + tok2str(ipcpopt_compproto_values,"Unknown",compproto), + compproto); + + switch (compproto) { + case PPP_VJC: + /* XXX: VJ-Comp parameters should be decoded */ + break; + case IPCPOPT_IPCOMP_HDRCOMP: + if (len < IPCPOPT_IPCOMP_MINLEN) + goto invlen; + + TCHECK2(*(p + 2), IPCPOPT_IPCOMP_MINLEN); + printf("\n\t TCP Space %u, non-TCP Space %u" \ + ", maxPeriod %u, maxTime %u, maxHdr %u", + EXTRACT_16BITS(p+4), + EXTRACT_16BITS(p+6), + EXTRACT_16BITS(p+8), + EXTRACT_16BITS(p+10), + EXTRACT_16BITS(p+12)); + + /* suboptions present ? */ + if (len > IPCPOPT_IPCOMP_MINLEN) { + ipcomp_subopttotallen = len - IPCPOPT_IPCOMP_MINLEN; + p += IPCPOPT_IPCOMP_MINLEN; + + printf("\n\t Suboptions, length %u", ipcomp_subopttotallen); + + while (ipcomp_subopttotallen >= 2) { + TCHECK2(*p, 2); + ipcomp_subopt = *p; + ipcomp_suboptlen = *(p+1); + + /* sanity check */ + if (ipcomp_subopt == 0 || + ipcomp_suboptlen == 0 ) + break; + + /* XXX: just display the suboptions for now */ + printf("\n\t\t%s Suboption #%u, length %u", + tok2str(ipcpopt_compproto_subopt_values, + "Unknown", + ipcomp_subopt), + ipcomp_subopt, + ipcomp_suboptlen); + + ipcomp_subopttotallen -= ipcomp_suboptlen; + p += ipcomp_suboptlen; + } + } + break; + default: + break; + } + break; + + case IPCPOPT_ADDR: /* those options share the same format - fall through */ + case IPCPOPT_MOBILE4: + case IPCPOPT_PRIDNS: + case IPCPOPT_PRINBNS: + case IPCPOPT_SECDNS: + case IPCPOPT_SECNBNS: + if (len != 6) + goto invlen; + TCHECK2(*(p + 2), 4); + printf("%s", ipaddr_string(p + 2)); + break; + default: + if(vflag<2) + print_unknown_data(&p[2],"\n\t ",len-2); + break; + } + if (vflag>1) + print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ + return len; + +invlen: + printf(", invalid-length-%d", opt); + return 0; + +trunc: + printf("[|ipcp]"); + return 0; +} + +/* IP6CP config options */ +static int +print_ip6cp_config_options(const u_char *p, int length) +{ + int len, opt; + + if (length < 2) + return 0; + TCHECK2(*p, 2); + len = p[1]; + opt = p[0]; + if (length < len) + return 0; + if (len < 2) { + printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", + tok2str(ip6cpopt_values,"unknown",opt), + opt, + len); + return 0; + } + + printf("\n\t %s Option (0x%02x), length %u: ", + tok2str(ip6cpopt_values,"unknown",opt), + opt, + len); + + switch (opt) { + case IP6CP_IFID: + if (len != 10) + goto invlen; + TCHECK2(*(p + 2), 8); + printf("%04x:%04x:%04x:%04x", + EXTRACT_16BITS(p + 2), + EXTRACT_16BITS(p + 4), + EXTRACT_16BITS(p + 6), + EXTRACT_16BITS(p + 8)); + break; + default: + if(vflag<2) + print_unknown_data(&p[2],"\n\t ",len-2); + break; + } + if (vflag>1) + print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ + + return len; + +invlen: + printf(", invalid-length-%d", opt); + return 0; + +trunc: + printf("[|ip6cp]"); + return 0; +} + + +/* CCP config options */ +static int +print_ccp_config_options(const u_char *p, int length) +{ + int len, opt; + + if (length < 2) + return 0; + TCHECK2(*p, 2); + len = p[1]; + opt = p[0]; + if (length < len) + return 0; + if (len < 2) { + printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", + tok2str(ccpconfopts_values, "Unknown", opt), + opt, + len); + return 0; + } + + printf("\n\t %s Option (0x%02x), length %u:", + tok2str(ccpconfopts_values, "Unknown", opt), + opt, + len); + + switch (opt) { + /* fall through --> default: nothing supported yet */ + case CCPOPT_OUI: + case CCPOPT_PRED1: + case CCPOPT_PRED2: + case CCPOPT_PJUMP: + case CCPOPT_HPPPC: + case CCPOPT_STACLZS: + case CCPOPT_MPPC: + case CCPOPT_GFZA: + case CCPOPT_V42BIS: + case CCPOPT_BSDCOMP: + case CCPOPT_LZSDCP: + case CCPOPT_MVRCA: + case CCPOPT_DEC: + case CCPOPT_DEFLATE: + case CCPOPT_RESV: + default: + if(vflag<2) + print_unknown_data(&p[2],"\n\t ",len-2); + break; + } + if (vflag>1) + print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ + + return len; + +trunc: + printf("[|ccp]"); + return 0; +} + +/* BACP config options */ +static int +print_bacp_config_options(const u_char *p, int length) +{ + int len, opt; + + if (length < 2) + return 0; + TCHECK2(*p, 2); + len = p[1]; + opt = p[0]; + if (length < len) + return 0; + if (len < 2) { + printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", + tok2str(bacconfopts_values, "Unknown", opt), + opt, + len); + return 0; + } + + printf("\n\t %s Option (0x%02x), length %u:", + tok2str(bacconfopts_values, "Unknown", opt), + opt, + len); + + switch (opt) { + case BACPOPT_FPEER: + TCHECK2(*(p + 2), 4); + printf(", Magic-Num 0x%08x", EXTRACT_32BITS(p + 2)); + break; + default: + if(vflag<2) + print_unknown_data(&p[2],"\n\t ",len-2); + break; + } + if (vflag>1) + print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ + + return len; + +trunc: + printf("[|bacp]"); + return 0; +} + + +static void +ppp_hdlc(const u_char *p, int length) +{ + u_char *b, *s, *t, c; + int i, proto; + const void *se; + + b = (u_int8_t *)malloc(length); + if (b == NULL) + return; + + /* + * Unescape all the data into a temporary, private, buffer. + * Do this so that we dont overwrite the original packet + * contents. + */ + for (s = (u_char *)p, t = b, i = length; i > 0; i--) { + c = *s++; + if (c == 0x7d) { + if (i > 1) { + i--; + c = *s++ ^ 0x20; + } else + continue; + } + *t++ = c; + } + + se = snapend; + snapend = t; + + /* now lets guess about the payload codepoint format */ + proto = *b; /* start with a one-octet codepoint guess */ + + switch (proto) { + case PPP_IP: + ip_print(gndo, b+1, t - b - 1); + goto cleanup; +#ifdef INET6 + case PPP_IPV6: + ip6_print(b+1, t - b - 1); + goto cleanup; +#endif + default: /* no luck - try next guess */ + break; + } + + proto = EXTRACT_16BITS(b); /* next guess - load two octets */ + + switch (proto) { + case (PPP_ADDRESS << 8 | PPP_CONTROL): /* looks like a PPP frame */ + proto = EXTRACT_16BITS(b+2); /* load the PPP proto-id */ + handle_ppp(proto, b+4, t - b - 4); + break; + default: /* last guess - proto must be a PPP proto-id */ + handle_ppp(proto, b+2, t - b - 2); + break; + } + +cleanup: + snapend = se; + free(b); + return; +} + + +/* PPP */ +static void +handle_ppp(u_int proto, const u_char *p, int length) +{ + if ((proto & 0xff00) == 0x7e00) {/* is this an escape code ? */ + ppp_hdlc(p-1, length); + return; + } + + switch (proto) { + case PPP_LCP: /* fall through */ + case PPP_IPCP: + case PPP_OSICP: + case PPP_MPLSCP: + case PPP_IPV6CP: + case PPP_CCP: + case PPP_BACP: + handle_ctrl_proto(proto, p, length); + break; + case PPP_ML: + handle_mlppp(p, length); + break; + case PPP_CHAP: + handle_chap(p, length); + break; + case PPP_PAP: + handle_pap(p, length); + break; + case PPP_BAP: /* XXX: not yet completed */ + handle_bap(p, length); + break; + case ETHERTYPE_IP: /*XXX*/ + case PPP_VJNC: + case PPP_IP: + ip_print(gndo, p, length); + break; +#ifdef INET6 + case ETHERTYPE_IPV6: /*XXX*/ + case PPP_IPV6: + ip6_print(p, length); + break; +#endif + case ETHERTYPE_IPX: /*XXX*/ + case PPP_IPX: + ipx_print(p, length); + break; + case PPP_OSI: + isoclns_print(p, length, length); + break; + case PPP_MPLS_UCAST: + case PPP_MPLS_MCAST: + mpls_print(p, length); + break; + case PPP_COMP: + printf("compressed PPP data"); + break; + default: + printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto)); + print_unknown_data(p,"\n\t",length); + break; + } +} + +/* Standard PPP printer */ +u_int +ppp_print(register const u_char *p, u_int length) +{ + u_int proto,ppp_header; + u_int olen = length; /* _o_riginal length */ + u_int hdr_len = 0; + + /* + * Here, we assume that p points to the Address and Control + * field (if they present). + */ + if (length < 2) + goto trunc; + TCHECK2(*p, 2); + ppp_header = EXTRACT_16BITS(p); + + switch(ppp_header) { + case (PPP_WITHDIRECTION_IN << 8 | PPP_CONTROL): + if (eflag) printf("In "); + p += 2; + length -= 2; + hdr_len += 2; + break; + case (PPP_WITHDIRECTION_OUT << 8 | PPP_CONTROL): + if (eflag) printf("Out "); + p += 2; + length -= 2; + hdr_len += 2; + break; + case (PPP_ADDRESS << 8 | PPP_CONTROL): + p += 2; /* ACFC not used */ + length -= 2; + hdr_len += 2; + break; + + default: + break; + } + + if (length < 2) + goto trunc; + TCHECK(*p); + if (*p % 2) { + proto = *p; /* PFC is used */ + p++; + length--; + hdr_len++; + } else { + TCHECK2(*p, 2); + proto = EXTRACT_16BITS(p); + p += 2; + length -= 2; + hdr_len += 2; + } + + if (eflag) + printf("%s (0x%04x), length %u: ", + tok2str(ppptype2str, "unknown", proto), + proto, + olen); + + handle_ppp(proto, p, length); + return (hdr_len); +trunc: + printf("[|ppp]"); + return (0); +} + + +/* PPP I/F printer */ +u_int +ppp_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + register u_int length = h->len; + register u_int caplen = h->caplen; + + if (caplen < PPP_HDRLEN) { + printf("[|ppp]"); + return (caplen); + } + +#if 0 + /* + * XXX: seems to assume that there are 2 octets prepended to an + * actual PPP frame. The 1st octet looks like Input/Output flag + * while 2nd octet is unknown, at least to me + * (mshindo@mshindo.net). + * + * That was what the original tcpdump code did. + * + * FreeBSD's "if_ppp.c" *does* set the first octet to 1 for outbound + * packets and 0 for inbound packets - but only if the + * protocol field has the 0x8000 bit set (i.e., it's a network + * control protocol); it does so before running the packet through + * "bpf_filter" to see if it should be discarded, and to see + * if we should update the time we sent the most recent packet... + * + * ...but it puts the original address field back after doing + * so. + * + * NetBSD's "if_ppp.c" doesn't set the first octet in that fashion. + * + * I don't know if any PPP implementation handed up to a BPF + * device packets with the first octet being 1 for outbound and + * 0 for inbound packets, so I (guy@alum.mit.edu) don't know + * whether that ever needs to be checked or not. + * + * Note that NetBSD has a DLT_PPP_SERIAL, which it uses for PPP, + * and its tcpdump appears to assume that the frame always + * begins with an address field and a control field, and that + * the address field might be 0x0f or 0x8f, for Cisco + * point-to-point with HDLC framing as per section 4.3.1 of RFC + * 1547, as well as 0xff, for PPP in HDLC-like framing as per + * RFC 1662. + * + * (Is the Cisco framing in question what DLT_C_HDLC, in + * BSD/OS, is?) + */ + if (eflag) + printf("%c %4d %02x ", p[0] ? 'O' : 'I', length, p[1]); +#endif + + ppp_print(p, length); + + return (0); +} + +/* + * PPP I/F printer to use if we know that RFC 1662-style PPP in HDLC-like + * framing, or Cisco PPP with HDLC framing as per section 4.3.1 of RFC 1547, + * is being used (i.e., we don't check for PPP_ADDRESS and PPP_CONTROL, + * discard them *if* those are the first two octets, and parse the remaining + * packet as a PPP packet, as "ppp_print()" does). + * + * This handles, for example, DLT_PPP_SERIAL in NetBSD. + */ +u_int +ppp_hdlc_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + register u_int length = h->len; + register u_int caplen = h->caplen; + u_int proto; + u_int hdrlen = 0; + + if (caplen < 2) { + printf("[|ppp]"); + return (caplen); + } + + switch (p[0]) { + + case PPP_ADDRESS: + if (caplen < 4) { + printf("[|ppp]"); + return (caplen); + } + + if (eflag) + printf("%02x %02x %d ", p[0], p[1], length); + p += 2; + length -= 2; + hdrlen += 2; + + proto = EXTRACT_16BITS(p); + p += 2; + length -= 2; + hdrlen += 2; + printf("%s: ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto)); + + handle_ppp(proto, p, length); + break; + + case CHDLC_UNICAST: + case CHDLC_BCAST: + return (chdlc_if_print(h, p)); + + default: + if (eflag) + printf("%02x %02x %d ", p[0], p[1], length); + p += 2; + length -= 2; + hdrlen += 2; + + /* + * XXX - NetBSD's "ppp_netbsd_serial_if_print()" treats + * the next two octets as an Ethernet type; does that + * ever happen? + */ + printf("unknown addr %02x; ctrl %02x", p[0], p[1]); + break; + } + + return (hdrlen); +} + +#define PPP_BSDI_HDRLEN 24 + +/* BSD/OS specific PPP printer */ +u_int +ppp_bsdos_if_print(const struct pcap_pkthdr *h _U_, register const u_char *p _U_) +{ + register int hdrlength; +#ifdef __bsdi__ + register u_int length = h->len; + register u_int caplen = h->caplen; + u_int16_t ptype; + const u_char *q; + int i; + + if (caplen < PPP_BSDI_HDRLEN) { + printf("[|ppp]"); + return (caplen) + } + + hdrlength = 0; + +#if 0 + if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) { + if (eflag) + printf("%02x %02x ", p[0], p[1]); + p += 2; + hdrlength = 2; + } + + if (eflag) + printf("%d ", length); + /* Retrieve the protocol type */ + if (*p & 01) { + /* Compressed protocol field */ + ptype = *p; + if (eflag) + printf("%02x ", ptype); + p++; + hdrlength += 1; + } else { + /* Un-compressed protocol field */ + ptype = EXTRACT_16BITS(p); + if (eflag) + printf("%04x ", ptype); + p += 2; + hdrlength += 2; + } +#else + ptype = 0; /*XXX*/ + if (eflag) + printf("%c ", p[SLC_DIR] ? 'O' : 'I'); + if (p[SLC_LLHL]) { + /* link level header */ + struct ppp_header *ph; + + q = p + SLC_BPFHDRLEN; + ph = (struct ppp_header *)q; + if (ph->phdr_addr == PPP_ADDRESS + && ph->phdr_ctl == PPP_CONTROL) { + if (eflag) + printf("%02x %02x ", q[0], q[1]); + ptype = EXTRACT_16BITS(&ph->phdr_type); + if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) { + printf("%s ", tok2str(ppptype2str, + "proto-#%d", ptype)); + } + } else { + if (eflag) { + printf("LLH=["); + for (i = 0; i < p[SLC_LLHL]; i++) + printf("%02x", q[i]); + printf("] "); + } + } + } + if (eflag) + printf("%d ", length); + if (p[SLC_CHL]) { + q = p + SLC_BPFHDRLEN + p[SLC_LLHL]; + + switch (ptype) { + case PPP_VJC: + ptype = vjc_print(q, ptype); + hdrlength = PPP_BSDI_HDRLEN; + p += hdrlength; + switch (ptype) { + case PPP_IP: + ip_print(p, length); + break; +#ifdef INET6 + case PPP_IPV6: + ip6_print(p, length); + break; +#endif + case PPP_MPLS_UCAST: + case PPP_MPLS_MCAST: + mpls_print(p, length); + break; + } + goto printx; + case PPP_VJNC: + ptype = vjc_print(q, ptype); + hdrlength = PPP_BSDI_HDRLEN; + p += hdrlength; + switch (ptype) { + case PPP_IP: + ip_print(p, length); + break; +#ifdef INET6 + case PPP_IPV6: + ip6_print(p, length); + break; +#endif + case PPP_MPLS_UCAST: + case PPP_MPLS_MCAST: + mpls_print(p, length); + break; + } + goto printx; + default: + if (eflag) { + printf("CH=["); + for (i = 0; i < p[SLC_LLHL]; i++) + printf("%02x", q[i]); + printf("] "); + } + break; + } + } + + hdrlength = PPP_BSDI_HDRLEN; +#endif + + length -= hdrlength; + p += hdrlength; + + switch (ptype) { + case PPP_IP: + ip_print(p, length); + break; +#ifdef INET6 + case PPP_IPV6: + ip6_print(p, length); + break; +#endif + case PPP_MPLS_UCAST: + case PPP_MPLS_MCAST: + mpls_print(p, length); + break; + default: + printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", ptype)); + } + +printx: +#else /* __bsdi */ + hdrlength = 0; +#endif /* __bsdi__ */ + return (hdrlength); +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-pppoe.c b/print-pppoe.c new file mode 100644 index 0000000..7abc787 --- /dev/null +++ b/print-pppoe.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Original code by Greg Stark + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-pppoe.c,v 1.31 2005-04-26 19:48:38 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "ppp.h" +#include "ethertype.h" +#include "ether.h" +#include "extract.h" /* must come after interface.h */ + +/* Codes */ +enum { + PPPOE_PADI = 0x09, + PPPOE_PADO = 0x07, + PPPOE_PADR = 0x19, + PPPOE_PADS = 0x65, + PPPOE_PADT = 0xa7 +}; + +static struct tok pppoecode2str[] = { + { PPPOE_PADI, "PADI" }, + { PPPOE_PADO, "PADO" }, + { PPPOE_PADR, "PADR" }, + { PPPOE_PADS, "PADS" }, + { PPPOE_PADT, "PADT" }, + { 0, "" }, /* PPP Data */ + { 0, NULL } +}; + +/* Tags */ +enum { + PPPOE_EOL = 0, + PPPOE_SERVICE_NAME = 0x0101, + PPPOE_AC_NAME = 0x0102, + PPPOE_HOST_UNIQ = 0x0103, + PPPOE_AC_COOKIE = 0x0104, + PPPOE_VENDOR = 0x0105, + PPPOE_RELAY_SID = 0x0110, + PPPOE_SERVICE_NAME_ERROR = 0x0201, + PPPOE_AC_SYSTEM_ERROR = 0x0202, + PPPOE_GENERIC_ERROR = 0x0203 +}; + +static struct tok pppoetag2str[] = { + { PPPOE_EOL, "EOL" }, + { PPPOE_SERVICE_NAME, "Service-Name" }, + { PPPOE_AC_NAME, "AC-Name" }, + { PPPOE_HOST_UNIQ, "Host-Uniq" }, + { PPPOE_AC_COOKIE, "AC-Cookie" }, + { PPPOE_VENDOR, "Vendor-Specific" }, + { PPPOE_RELAY_SID, "Relay-Session-ID" }, + { PPPOE_SERVICE_NAME_ERROR, "Service-Name-Error" }, + { PPPOE_AC_SYSTEM_ERROR, "AC-System-Error" }, + { PPPOE_GENERIC_ERROR, "Generic-Error" }, + { 0, NULL } +}; + +#define PPPOE_HDRLEN 6 +#define MAXTAGPRINT 80 + +u_int +pppoe_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + return (pppoe_print(p, h->len)); +} + +u_int +pppoe_print(register const u_char *bp, u_int length) +{ + u_int16_t pppoe_ver, pppoe_type, pppoe_code, pppoe_sessionid; + u_int pppoe_length; + const u_char *pppoe_packet, *pppoe_payload; + + if (length < PPPOE_HDRLEN) { + (void)printf("truncated-pppoe %u", length); + return (length); + } + length -= PPPOE_HDRLEN; + pppoe_packet = bp; + TCHECK2(*pppoe_packet, PPPOE_HDRLEN); + pppoe_ver = (pppoe_packet[0] & 0xF0) >> 4; + pppoe_type = (pppoe_packet[0] & 0x0F); + pppoe_code = pppoe_packet[1]; + pppoe_sessionid = EXTRACT_16BITS(pppoe_packet + 2); + pppoe_length = EXTRACT_16BITS(pppoe_packet + 4); + pppoe_payload = pppoe_packet + PPPOE_HDRLEN; + + if (pppoe_ver != 1) { + printf(" [ver %d]",pppoe_ver); + } + if (pppoe_type != 1) { + printf(" [type %d]",pppoe_type); + } + + printf("PPPoE %s", tok2str(pppoecode2str, "PAD-%x", pppoe_code)); + if (pppoe_code == PPPOE_PADI && pppoe_length > 1484 - PPPOE_HDRLEN) { + printf(" [len %u!]",pppoe_length); + } + if (pppoe_length > length) { + printf(" [len %u > %u!]", pppoe_length, length); + pppoe_length = length; + } + if (pppoe_sessionid) { + printf(" [ses 0x%x]", pppoe_sessionid); + } + + if (pppoe_code) { + /* PPP session packets don't contain tags */ + u_short tag_type = 0xffff, tag_len; + const u_char *p = pppoe_payload; + + /* + * loop invariant: + * p points to current tag, + * tag_type is previous tag or 0xffff for first iteration + */ + while (tag_type && p < pppoe_payload + pppoe_length) { + TCHECK2(*p, 4); + tag_type = EXTRACT_16BITS(p); + tag_len = EXTRACT_16BITS(p + 2); + p += 4; + /* p points to tag_value */ + + if (tag_len) { + unsigned isascii = 0, isgarbage = 0; + const u_char *v = p; + char tag_str[MAXTAGPRINT]; + unsigned tag_str_len = 0; + + /* TODO print UTF-8 decoded text */ + TCHECK2(*p, tag_len); + for (v = p; v < p + tag_len && tag_str_len < MAXTAGPRINT-1; v++) + if (*v >= 32 && *v < 127) { + tag_str[tag_str_len++] = *v; + isascii++; + } else { + tag_str[tag_str_len++] = '.'; + isgarbage++; + } + tag_str[tag_str_len] = 0; + + if (isascii > isgarbage) { + printf(" [%s \"%*.*s\"]", + tok2str(pppoetag2str, "TAG-0x%x", tag_type), + (int)tag_str_len, + (int)tag_str_len, + tag_str); + } else { + /* Print hex, not fast to abuse printf but this doesn't get used much */ + printf(" [%s 0x", tok2str(pppoetag2str, "TAG-0x%x", tag_type)); + for (v=p; v + +#include + +#include "interface.h" +#include "extract.h" + +static char tstr[] = " [|pptp]"; + +#define PPTP_MSG_TYPE_CTRL 1 /* Control Message */ +#define PPTP_MSG_TYPE_MGMT 2 /* Management Message (currently not used */ +#define PPTP_MAGIC_COOKIE 0x1a2b3c4d /* for sanity check */ + +#define PPTP_CTRL_MSG_TYPE_SCCRQ 1 +#define PPTP_CTRL_MSG_TYPE_SCCRP 2 +#define PPTP_CTRL_MSG_TYPE_StopCCRQ 3 +#define PPTP_CTRL_MSG_TYPE_StopCCRP 4 +#define PPTP_CTRL_MSG_TYPE_ECHORQ 5 +#define PPTP_CTRL_MSG_TYPE_ECHORP 6 +#define PPTP_CTRL_MSG_TYPE_OCRQ 7 +#define PPTP_CTRL_MSG_TYPE_OCRP 8 +#define PPTP_CTRL_MSG_TYPE_ICRQ 9 +#define PPTP_CTRL_MSG_TYPE_ICRP 10 +#define PPTP_CTRL_MSG_TYPE_ICCN 11 +#define PPTP_CTRL_MSG_TYPE_CCRQ 12 +#define PPTP_CTRL_MSG_TYPE_CDN 13 +#define PPTP_CTRL_MSG_TYPE_WEN 14 +#define PPTP_CTRL_MSG_TYPE_SLI 15 + +#define PPTP_FRAMING_CAP_ASYNC_MASK 0x00000001 /* Aynchronous */ +#define PPTP_FRAMING_CAP_SYNC_MASK 0x00000002 /* Synchronous */ + +#define PPTP_BEARER_CAP_ANALOG_MASK 0x00000001 /* Analog */ +#define PPTP_BEARER_CAP_DIGITAL_MASK 0x00000002 /* Digital */ + +static const char *pptp_message_type_string[] = { + "NOT_DEFINED", /* 0 Not defined in the RFC2637 */ + "SCCRQ", /* 1 Start-Control-Connection-Request */ + "SCCRP", /* 2 Start-Control-Connection-Reply */ + "StopCCRQ", /* 3 Stop-Control-Connection-Request */ + "StopCCRP", /* 4 Stop-Control-Connection-Reply */ + "ECHORQ", /* 5 Echo Request */ + "ECHORP", /* 6 Echo Reply */ + + "OCRQ", /* 7 Outgoing-Call-Request */ + "OCRP", /* 8 Outgoing-Call-Reply */ + "ICRQ", /* 9 Incoming-Call-Request */ + "ICRP", /* 10 Incoming-Call-Reply */ + "ICCN", /* 11 Incoming-Call-Connected */ + "CCRQ", /* 12 Call-Clear-Request */ + "CDN", /* 13 Call-Disconnect-Notify */ + + "WEN", /* 14 WAN-Error-Notify */ + + "SLI" /* 15 Set-Link-Info */ +#define PPTP_MAX_MSGTYPE_INDEX 16 +}; + +/* common for all PPTP control messages */ +struct pptp_hdr { + u_int16_t length; + u_int16_t msg_type; + u_int32_t magic_cookie; + u_int16_t ctrl_msg_type; + u_int16_t reserved0; +}; + +struct pptp_msg_sccrq { + u_int16_t proto_ver; + u_int16_t reserved1; + u_int32_t framing_cap; + u_int32_t bearer_cap; + u_int16_t max_channel; + u_int16_t firm_rev; + u_char hostname[64]; + u_char vendor[64]; +}; + +struct pptp_msg_sccrp { + u_int16_t proto_ver; + u_int8_t result_code; + u_int8_t err_code; + u_int32_t framing_cap; + u_int32_t bearer_cap; + u_int16_t max_channel; + u_int16_t firm_rev; + u_char hostname[64]; + u_char vendor[64]; +}; + +struct pptp_msg_stopccrq { + u_int8_t reason; + u_int8_t reserved1; + u_int16_t reserved2; +}; + +struct pptp_msg_stopccrp { + u_int8_t result_code; + u_int8_t err_code; + u_int16_t reserved1; +}; + +struct pptp_msg_echorq { + u_int32_t id; +}; + +struct pptp_msg_echorp { + u_int32_t id; + u_int8_t result_code; + u_int8_t err_code; + u_int16_t reserved1; +}; + +struct pptp_msg_ocrq { + u_int16_t call_id; + u_int16_t call_ser; + u_int32_t min_bps; + u_int32_t max_bps; + u_int32_t bearer_type; + u_int32_t framing_type; + u_int16_t recv_winsiz; + u_int16_t pkt_proc_delay; + u_int16_t phone_no_len; + u_int16_t reserved1; + u_char phone_no[64]; + u_char subaddr[64]; +}; + +struct pptp_msg_ocrp { + u_int16_t call_id; + u_int16_t peer_call_id; + u_int8_t result_code; + u_int8_t err_code; + u_int16_t cause_code; + u_int32_t conn_speed; + u_int16_t recv_winsiz; + u_int16_t pkt_proc_delay; + u_int32_t phy_chan_id; +}; + +struct pptp_msg_icrq { + u_int16_t call_id; + u_int16_t call_ser; + u_int32_t bearer_type; + u_int32_t phy_chan_id; + u_int16_t dialed_no_len; + u_int16_t dialing_no_len; + u_char dialed_no[64]; /* DNIS */ + u_char dialing_no[64]; /* CLID */ + u_char subaddr[64]; +}; + +struct pptp_msg_icrp { + u_int16_t call_id; + u_int16_t peer_call_id; + u_int8_t result_code; + u_int8_t err_code; + u_int16_t recv_winsiz; + u_int16_t pkt_proc_delay; + u_int16_t reserved1; +}; + +struct pptp_msg_iccn { + u_int16_t peer_call_id; + u_int16_t reserved1; + u_int32_t conn_speed; + u_int16_t recv_winsiz; + u_int16_t pkt_proc_delay; + u_int32_t framing_type; +}; + +struct pptp_msg_ccrq { + u_int16_t call_id; + u_int16_t reserved1; +}; + +struct pptp_msg_cdn { + u_int16_t call_id; + u_int8_t result_code; + u_int8_t err_code; + u_int16_t cause_code; + u_int16_t reserved1; + u_char call_stats[128]; +}; + +struct pptp_msg_wen { + u_int16_t peer_call_id; + u_int16_t reserved1; + u_int32_t crc_err; + u_int32_t framing_err; + u_int32_t hardware_overrun; + u_int32_t buffer_overrun; + u_int32_t timeout_err; + u_int32_t align_err; +}; + +struct pptp_msg_sli { + u_int16_t peer_call_id; + u_int16_t reserved1; + u_int32_t send_accm; + u_int32_t recv_accm; +}; + +/* attributes that appear more than once in above messages: + + Number of + occurence attributes + -------------------------------------- + 2 u_int32_t bearer_cap; + 2 u_int32_t bearer_type; + 6 u_int16_t call_id; + 2 u_int16_t call_ser; + 2 u_int16_t cause_code; + 2 u_int32_t conn_speed; + 6 u_int8_t err_code; + 2 u_int16_t firm_rev; + 2 u_int32_t framing_cap; + 2 u_int32_t framing_type; + 2 u_char hostname[64]; + 2 u_int32_t id; + 2 u_int16_t max_channel; + 5 u_int16_t peer_call_id; + 2 u_int32_t phy_chan_id; + 4 u_int16_t pkt_proc_delay; + 2 u_int16_t proto_ver; + 4 u_int16_t recv_winsiz; + 2 u_int8_t reserved1; + 9 u_int16_t reserved1; + 6 u_int8_t result_code; + 2 u_char subaddr[64]; + 2 u_char vendor[64]; + + so I will prepare print out functions for these attributes (except for + reserved*). +*/ + +/******************************************/ +/* Attribute-specific print out functions */ +/******************************************/ + +/* In these attribute-specific print-out functions, it't not necessary + to do TCHECK because they are already checked in the caller of + these functions. */ + +static void +pptp_bearer_cap_print(const u_int32_t *bearer_cap) +{ + printf(" BEARER_CAP("); + if (EXTRACT_32BITS(bearer_cap) & PPTP_BEARER_CAP_DIGITAL_MASK) { + printf("D"); + } + if (EXTRACT_32BITS(bearer_cap) & PPTP_BEARER_CAP_ANALOG_MASK) { + printf("A"); + } + printf(")"); +} + +static void +pptp_bearer_type_print(const u_int32_t *bearer_type) +{ + printf(" BEARER_TYPE("); + switch (EXTRACT_32BITS(bearer_type)) { + case 1: + printf("A"); /* Analog */ + break; + case 2: + printf("D"); /* Digital */ + break; + case 3: + printf("Any"); + break; + default: + printf("?"); + break; + } + printf(")"); +} + +static void +pptp_call_id_print(const u_int16_t *call_id) +{ + printf(" CALL_ID(%u)", EXTRACT_16BITS(call_id)); +} + +static void +pptp_call_ser_print(const u_int16_t *call_ser) +{ + printf(" CALL_SER_NUM(%u)", EXTRACT_16BITS(call_ser)); +} + +static void +pptp_cause_code_print(const u_int16_t *cause_code) +{ + printf(" CAUSE_CODE(%u)", EXTRACT_16BITS(cause_code)); +} + +static void +pptp_conn_speed_print(const u_int32_t *conn_speed) +{ + printf(" CONN_SPEED(%u)", EXTRACT_32BITS(conn_speed)); +} + +static void +pptp_err_code_print(const u_int8_t *err_code) +{ + printf(" ERR_CODE(%u", *err_code); + if (vflag) { + switch (*err_code) { + case 0: + printf(":None"); + break; + case 1: + printf(":Not-Connected"); + break; + case 2: + printf(":Bad-Format"); + break; + case 3: + printf(":Bad-Valude"); + break; + case 4: + printf(":No-Resource"); + break; + case 5: + printf(":Bad-Call-ID"); + break; + case 6: + printf(":PAC-Error"); + break; + default: + printf(":?"); + break; + } + } + printf(")"); +} + +static void +pptp_firm_rev_print(const u_int16_t *firm_rev) +{ + printf(" FIRM_REV(%u)", EXTRACT_16BITS(firm_rev)); +} + +static void +pptp_framing_cap_print(const u_int32_t *framing_cap) +{ + printf(" FRAME_CAP("); + if (EXTRACT_32BITS(framing_cap) & PPTP_FRAMING_CAP_ASYNC_MASK) { + printf("A"); /* Async */ + } + if (EXTRACT_32BITS(framing_cap) & PPTP_FRAMING_CAP_SYNC_MASK) { + printf("S"); /* Sync */ + } + printf(")"); +} + +static void +pptp_framing_type_print(const u_int32_t *framing_type) +{ + printf(" FRAME_TYPE("); + switch (EXTRACT_32BITS(framing_type)) { + case 1: + printf("A"); /* Async */ + break; + case 2: + printf("S"); /* Sync */ + break; + case 3: + printf("E"); /* Either */ + break; + default: + printf("?"); + break; + } + printf(")"); +} + +static void +pptp_hostname_print(const u_char *hostname) +{ + printf(" HOSTNAME(%.64s)", hostname); +} + +static void +pptp_id_print(const u_int32_t *id) +{ + printf(" ID(%u)", EXTRACT_32BITS(id)); +} + +static void +pptp_max_channel_print(const u_int16_t *max_channel) +{ + printf(" MAX_CHAN(%u)", EXTRACT_16BITS(max_channel)); +} + +static void +pptp_peer_call_id_print(const u_int16_t *peer_call_id) +{ + printf(" PEER_CALL_ID(%u)", EXTRACT_16BITS(peer_call_id)); +} + +static void +pptp_phy_chan_id_print(const u_int32_t *phy_chan_id) +{ + printf(" PHY_CHAN_ID(%u)", EXTRACT_32BITS(phy_chan_id)); +} + +static void +pptp_pkt_proc_delay_print(const u_int16_t *pkt_proc_delay) +{ + printf(" PROC_DELAY(%u)", EXTRACT_16BITS(pkt_proc_delay)); +} + +static void +pptp_proto_ver_print(const u_int16_t *proto_ver) +{ + printf(" PROTO_VER(%u.%u)", /* Version.Revision */ + EXTRACT_16BITS(proto_ver) >> 8, + EXTRACT_16BITS(proto_ver) & 0xff); +} + +static void +pptp_recv_winsiz_print(const u_int16_t *recv_winsiz) +{ + printf(" RECV_WIN(%u)", EXTRACT_16BITS(recv_winsiz)); +} + +static void +pptp_result_code_print(const u_int8_t *result_code, int ctrl_msg_type) +{ + printf(" RESULT_CODE(%u", *result_code); + if (vflag) { + switch (ctrl_msg_type) { + case PPTP_CTRL_MSG_TYPE_SCCRP: + switch (*result_code) { + case 1: + printf(":Successful channel establishment"); + break; + case 2: + printf(":General error"); + break; + case 3: + printf(":Command channel already exists"); + break; + case 4: + printf(":Requester is not authorized to establish a command channel"); + break; + case 5: + printf(":The protocol version of the requester is not supported"); + break; + default: + printf(":?"); + break; + } + break; + case PPTP_CTRL_MSG_TYPE_StopCCRP: + case PPTP_CTRL_MSG_TYPE_ECHORP: + switch (*result_code) { + case 1: + printf(":OK"); + break; + case 2: + printf(":General Error"); + break; + default: + printf(":?"); + break; + } + break; + case PPTP_CTRL_MSG_TYPE_OCRP: + switch (*result_code) { + case 1: + printf(":Connected"); + break; + case 2: + printf(":General Error"); + break; + case 3: + printf(":No Carrier"); + break; + case 4: + printf(":Busy"); + break; + case 5: + printf(":No Dial Tone"); + break; + case 6: + printf(":Time-out"); + break; + case 7: + printf(":Do Not Accept"); + break; + default: + printf(":?"); + break; + } + break; + case PPTP_CTRL_MSG_TYPE_ICRP: + switch (*result_code) { + case 1: + printf(":Connect"); + break; + case 2: + printf(":General Error"); + break; + case 3: + printf(":Do Not Accept"); + break; + default: + printf(":?"); + break; + } + break; + case PPTP_CTRL_MSG_TYPE_CDN: + switch (*result_code) { + case 1: + printf(":Lost Carrier"); + break; + case 2: + printf(":General Error"); + break; + case 3: + printf(":Admin Shutdown"); + break; + case 4: + printf(":Request"); + default: + printf(":?"); + break; + break; + } + default: + /* assertion error */ + break; + } + } + printf(")"); +} + +static void +pptp_subaddr_print(const u_char *subaddr) +{ + printf(" SUB_ADDR(%.64s)", subaddr); +} + +static void +pptp_vendor_print(const u_char *vendor) +{ + printf(" VENDOR(%.64s)", vendor); +} + +/************************************/ +/* PPTP message print out functions */ +/************************************/ +static void +pptp_sccrq_print(const u_char *dat) +{ + struct pptp_msg_sccrq *ptr = (struct pptp_msg_sccrq *)dat; + + TCHECK(ptr->proto_ver); + pptp_proto_ver_print(&ptr->proto_ver); + TCHECK(ptr->reserved1); + TCHECK(ptr->framing_cap); + pptp_framing_cap_print(&ptr->framing_cap); + TCHECK(ptr->bearer_cap); + pptp_bearer_cap_print(&ptr->bearer_cap); + TCHECK(ptr->max_channel); + pptp_max_channel_print(&ptr->max_channel); + TCHECK(ptr->firm_rev); + pptp_firm_rev_print(&ptr->firm_rev); + TCHECK(ptr->hostname); + pptp_hostname_print(&ptr->hostname[0]); + TCHECK(ptr->vendor); + pptp_vendor_print(&ptr->vendor[0]); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_sccrp_print(const u_char *dat) +{ + struct pptp_msg_sccrp *ptr = (struct pptp_msg_sccrp *)dat; + + TCHECK(ptr->proto_ver); + pptp_proto_ver_print(&ptr->proto_ver); + TCHECK(ptr->result_code); + pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_SCCRP); + TCHECK(ptr->err_code); + pptp_err_code_print(&ptr->err_code); + TCHECK(ptr->framing_cap); + pptp_framing_cap_print(&ptr->framing_cap); + TCHECK(ptr->bearer_cap); + pptp_bearer_cap_print(&ptr->bearer_cap); + TCHECK(ptr->max_channel); + pptp_max_channel_print(&ptr->max_channel); + TCHECK(ptr->firm_rev); + pptp_firm_rev_print(&ptr->firm_rev); + TCHECK(ptr->hostname); + pptp_hostname_print(&ptr->hostname[0]); + TCHECK(ptr->vendor); + pptp_vendor_print(&ptr->vendor[0]); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_stopccrq_print(const u_char *dat) +{ + struct pptp_msg_stopccrq *ptr = (struct pptp_msg_stopccrq *)dat; + + TCHECK(ptr->reason); + printf(" REASON(%u", ptr->reason); + if (vflag) { + switch (ptr->reason) { + case 1: + printf(":None"); + break; + case 2: + printf(":Stop-Protocol"); + break; + case 3: + printf(":Stop-Local-Shutdown"); + break; + default: + printf(":?"); + break; + } + } + printf(")"); + TCHECK(ptr->reserved1); + TCHECK(ptr->reserved2); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_stopccrp_print(const u_char *dat) +{ + struct pptp_msg_stopccrp *ptr = (struct pptp_msg_stopccrp *)dat; + + TCHECK(ptr->result_code); + pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_StopCCRP); + TCHECK(ptr->err_code); + pptp_err_code_print(&ptr->err_code); + TCHECK(ptr->reserved1); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_echorq_print(const u_char *dat) +{ + struct pptp_msg_echorq *ptr = (struct pptp_msg_echorq *)dat; + + TCHECK(ptr->id); + pptp_id_print(&ptr->id); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_echorp_print(const u_char *dat) +{ + struct pptp_msg_echorp *ptr = (struct pptp_msg_echorp *)dat; + + TCHECK(ptr->id); + pptp_id_print(&ptr->id); + TCHECK(ptr->result_code); + pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_ECHORP); + TCHECK(ptr->err_code); + pptp_err_code_print(&ptr->err_code); + TCHECK(ptr->reserved1); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_ocrq_print(const u_char *dat) +{ + struct pptp_msg_ocrq *ptr = (struct pptp_msg_ocrq *)dat; + + TCHECK(ptr->call_id); + pptp_call_id_print(&ptr->call_id); + TCHECK(ptr->call_ser); + pptp_call_ser_print(&ptr->call_ser); + TCHECK(ptr->min_bps); + printf(" MIN_BPS(%u)", EXTRACT_32BITS(&ptr->min_bps)); + TCHECK(ptr->max_bps); + printf(" MAX_BPS(%u)", EXTRACT_32BITS(&ptr->max_bps)); + TCHECK(ptr->bearer_type); + pptp_bearer_type_print(&ptr->bearer_type); + TCHECK(ptr->framing_type); + pptp_framing_type_print(&ptr->framing_type); + TCHECK(ptr->recv_winsiz); + pptp_recv_winsiz_print(&ptr->recv_winsiz); + TCHECK(ptr->pkt_proc_delay); + pptp_pkt_proc_delay_print(&ptr->pkt_proc_delay); + TCHECK(ptr->phone_no_len); + printf(" PHONE_NO_LEN(%u)", EXTRACT_16BITS(&ptr->phone_no_len)); + TCHECK(ptr->reserved1); + TCHECK(ptr->phone_no); + printf(" PHONE_NO(%.64s)", ptr->phone_no); + TCHECK(ptr->subaddr); + pptp_subaddr_print(&ptr->subaddr[0]); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_ocrp_print(const u_char *dat) +{ + struct pptp_msg_ocrp *ptr = (struct pptp_msg_ocrp *)dat; + + TCHECK(ptr->call_id); + pptp_call_id_print(&ptr->call_id); + TCHECK(ptr->peer_call_id); + pptp_peer_call_id_print(&ptr->peer_call_id); + TCHECK(ptr->result_code); + pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_OCRP); + TCHECK(ptr->err_code); + pptp_err_code_print(&ptr->err_code); + TCHECK(ptr->cause_code); + pptp_cause_code_print(&ptr->cause_code); + TCHECK(ptr->conn_speed); + pptp_conn_speed_print(&ptr->conn_speed); + TCHECK(ptr->recv_winsiz); + pptp_recv_winsiz_print(&ptr->recv_winsiz); + TCHECK(ptr->pkt_proc_delay); + pptp_pkt_proc_delay_print(&ptr->pkt_proc_delay); + TCHECK(ptr->phy_chan_id); + pptp_phy_chan_id_print(&ptr->phy_chan_id); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_icrq_print(const u_char *dat) +{ + struct pptp_msg_icrq *ptr = (struct pptp_msg_icrq *)dat; + + TCHECK(ptr->call_id); + pptp_call_id_print(&ptr->call_id); + TCHECK(ptr->call_ser); + pptp_call_ser_print(&ptr->call_ser); + TCHECK(ptr->bearer_type); + pptp_bearer_type_print(&ptr->bearer_type); + TCHECK(ptr->phy_chan_id); + pptp_phy_chan_id_print(&ptr->phy_chan_id); + TCHECK(ptr->dialed_no_len); + printf(" DIALED_NO_LEN(%u)", EXTRACT_16BITS(&ptr->dialed_no_len)); + TCHECK(ptr->dialing_no_len); + printf(" DIALING_NO_LEN(%u)", EXTRACT_16BITS(&ptr->dialing_no_len)); + TCHECK(ptr->dialed_no); + printf(" DIALED_NO(%.64s)", ptr->dialed_no); + TCHECK(ptr->dialing_no); + printf(" DIALING_NO(%.64s)", ptr->dialing_no); + TCHECK(ptr->subaddr); + pptp_subaddr_print(&ptr->subaddr[0]); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_icrp_print(const u_char *dat) +{ + struct pptp_msg_icrp *ptr = (struct pptp_msg_icrp *)dat; + + TCHECK(ptr->call_id); + pptp_call_id_print(&ptr->call_id); + TCHECK(ptr->peer_call_id); + pptp_peer_call_id_print(&ptr->peer_call_id); + TCHECK(ptr->result_code); + pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_ICRP); + TCHECK(ptr->err_code); + pptp_err_code_print(&ptr->err_code); + TCHECK(ptr->recv_winsiz); + pptp_recv_winsiz_print(&ptr->recv_winsiz); + TCHECK(ptr->pkt_proc_delay); + pptp_pkt_proc_delay_print(&ptr->pkt_proc_delay); + TCHECK(ptr->reserved1); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_iccn_print(const u_char *dat) +{ + struct pptp_msg_iccn *ptr = (struct pptp_msg_iccn *)dat; + + TCHECK(ptr->peer_call_id); + pptp_peer_call_id_print(&ptr->peer_call_id); + TCHECK(ptr->reserved1); + TCHECK(ptr->conn_speed); + pptp_conn_speed_print(&ptr->conn_speed); + TCHECK(ptr->recv_winsiz); + pptp_recv_winsiz_print(&ptr->recv_winsiz); + TCHECK(ptr->pkt_proc_delay); + pptp_pkt_proc_delay_print(&ptr->pkt_proc_delay); + TCHECK(ptr->framing_type); + pptp_framing_type_print(&ptr->framing_type); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_ccrq_print(const u_char *dat) +{ + struct pptp_msg_ccrq *ptr = (struct pptp_msg_ccrq *)dat; + + TCHECK(ptr->call_id); + pptp_call_id_print(&ptr->call_id); + TCHECK(ptr->reserved1); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_cdn_print(const u_char *dat) +{ + struct pptp_msg_cdn *ptr = (struct pptp_msg_cdn *)dat; + + TCHECK(ptr->call_id); + pptp_call_id_print(&ptr->call_id); + TCHECK(ptr->result_code); + pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_CDN); + TCHECK(ptr->err_code); + pptp_err_code_print(&ptr->err_code); + TCHECK(ptr->cause_code); + pptp_cause_code_print(&ptr->cause_code); + TCHECK(ptr->reserved1); + TCHECK(ptr->call_stats); + printf(" CALL_STATS(%.128s)", ptr->call_stats); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_wen_print(const u_char *dat) +{ + struct pptp_msg_wen *ptr = (struct pptp_msg_wen *)dat; + + TCHECK(ptr->peer_call_id); + pptp_peer_call_id_print(&ptr->peer_call_id); + TCHECK(ptr->reserved1); + TCHECK(ptr->crc_err); + printf(" CRC_ERR(%u)", EXTRACT_32BITS(&ptr->crc_err)); + TCHECK(ptr->framing_err); + printf(" FRAMING_ERR(%u)", EXTRACT_32BITS(&ptr->framing_err)); + TCHECK(ptr->hardware_overrun); + printf(" HARDWARE_OVERRUN(%u)", EXTRACT_32BITS(&ptr->hardware_overrun)); + TCHECK(ptr->buffer_overrun); + printf(" BUFFER_OVERRUN(%u)", EXTRACT_32BITS(&ptr->buffer_overrun)); + TCHECK(ptr->timeout_err); + printf(" TIMEOUT_ERR(%u)", EXTRACT_32BITS(&ptr->timeout_err)); + TCHECK(ptr->align_err); + printf(" ALIGN_ERR(%u)", EXTRACT_32BITS(&ptr->align_err)); + + return; + +trunc: + printf("%s", tstr); +} + +static void +pptp_sli_print(const u_char *dat) +{ + struct pptp_msg_sli *ptr = (struct pptp_msg_sli *)dat; + + TCHECK(ptr->peer_call_id); + pptp_peer_call_id_print(&ptr->peer_call_id); + TCHECK(ptr->reserved1); + TCHECK(ptr->send_accm); + printf(" SEND_ACCM(0x%08x)", EXTRACT_32BITS(&ptr->send_accm)); + TCHECK(ptr->recv_accm); + printf(" RECV_ACCM(0x%08x)", EXTRACT_32BITS(&ptr->recv_accm)); + + return; + +trunc: + printf("%s", tstr); +} + +void +pptp_print(const u_char *dat) +{ + const struct pptp_hdr *hdr; + u_int32_t mc; + u_int16_t ctrl_msg_type; + + printf(": pptp"); + + hdr = (struct pptp_hdr *)dat; + + TCHECK(hdr->length); + if (vflag) { + printf(" Length=%u", EXTRACT_16BITS(&hdr->length)); + } + TCHECK(hdr->msg_type); + if (vflag) { + switch(EXTRACT_16BITS(&hdr->msg_type)) { + case PPTP_MSG_TYPE_CTRL: + printf(" CTRL-MSG"); + break; + case PPTP_MSG_TYPE_MGMT: + printf(" MGMT-MSG"); + break; + default: + printf(" UNKNOWN-MSG-TYPE"); + break; + } + } + + TCHECK(hdr->magic_cookie); + mc = EXTRACT_32BITS(&hdr->magic_cookie); + if (mc != PPTP_MAGIC_COOKIE) { + printf(" UNEXPECTED Magic-Cookie!!(%08x)", mc); + } + if (vflag || mc != PPTP_MAGIC_COOKIE) { + printf(" Magic-Cookie=%08x", mc); + } + TCHECK(hdr->ctrl_msg_type); + ctrl_msg_type = EXTRACT_16BITS(&hdr->ctrl_msg_type); + if (ctrl_msg_type < PPTP_MAX_MSGTYPE_INDEX) { + printf(" CTRL_MSGTYPE=%s", + pptp_message_type_string[ctrl_msg_type]); + } else { + printf(" UNKNOWN_CTRL_MSGTYPE(%u)", ctrl_msg_type); + } + TCHECK(hdr->reserved0); + + dat += 12; + + switch(ctrl_msg_type) { + case PPTP_CTRL_MSG_TYPE_SCCRQ: + pptp_sccrq_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_SCCRP: + pptp_sccrp_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_StopCCRQ: + pptp_stopccrq_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_StopCCRP: + pptp_stopccrp_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_ECHORQ: + pptp_echorq_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_ECHORP: + pptp_echorp_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_OCRQ: + pptp_ocrq_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_OCRP: + pptp_ocrp_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_ICRQ: + pptp_icrq_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_ICRP: + pptp_icrp_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_ICCN: + pptp_iccn_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_CCRQ: + pptp_ccrq_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_CDN: + pptp_cdn_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_WEN: + pptp_wen_print(dat); + break; + case PPTP_CTRL_MSG_TYPE_SLI: + pptp_sli_print(dat); + break; + default: + /* do nothing */ + break; + } + + return; + +trunc: + printf("%s", tstr); +} diff --git a/print-radius.c b/print-radius.c new file mode 100644 index 0000000..44f0c7f --- /dev/null +++ b/print-radius.c @@ -0,0 +1,937 @@ +/* + * Copyright (C) 2000 Alfredo Andres Omella. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +/* + * Radius printer routines as specified on: + * + * RFC 2865: + * "Remote Authentication Dial In User Service (RADIUS)" + * + * RFC 2866: + * "RADIUS Accounting" + * + * RFC 2867: + * "RADIUS Accounting Modifications for Tunnel Protocol Support" + * + * RFC 2868: + * "RADIUS Attributes for Tunnel Protocol Support" + * + * RFC 2869: + * "RADIUS Extensions" + * + * Alfredo Andres Omella (aandres@s21sec.com) v0.1 2000/09/15 + * + * TODO: Among other things to print ok MacIntosh and Vendor values + */ + +#ifndef lint +static const char rcsid[] _U_ = + "$Id: print-radius.c,v 1.28 2005-09-26 01:01:55 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "oui.h" + +#define TAM_SIZE(x) (sizeof(x)/sizeof(x[0]) ) + +#define PRINT_HEX(bytes_len, ptr_data) \ + while(bytes_len) \ + { \ + printf("%02X", *ptr_data ); \ + ptr_data++; \ + bytes_len--; \ + } + + +/* Radius packet codes */ +#define RADCMD_ACCESS_REQ 1 /* Access-Request */ +#define RADCMD_ACCESS_ACC 2 /* Access-Accept */ +#define RADCMD_ACCESS_REJ 3 /* Access-Reject */ +#define RADCMD_ACCOUN_REQ 4 /* Accounting-Request */ +#define RADCMD_ACCOUN_RES 5 /* Accounting-Response */ +#define RADCMD_ACCESS_CHA 11 /* Access-Challenge */ +#define RADCMD_STATUS_SER 12 /* Status-Server */ +#define RADCMD_STATUS_CLI 13 /* Status-Client */ +#define RADCMD_RESERVED 255 /* Reserved */ + +static struct tok radius_command_values[] = { + { RADCMD_ACCESS_REQ, "Access Request" }, + { RADCMD_ACCESS_ACC, "Access Accept" }, + { RADCMD_ACCESS_REJ, "Access Reject" }, + { RADCMD_ACCOUN_REQ, "Accounting Request" }, + { RADCMD_ACCOUN_RES, "Accounting Response" }, + { RADCMD_ACCESS_CHA, "Access Challenge" }, + { RADCMD_STATUS_SER, "Status Server" }, + { RADCMD_STATUS_CLI, "Status Client" }, + { RADCMD_RESERVED, "Reserved" }, + { 0, NULL} +}; + +/********************************/ +/* Begin Radius Attribute types */ +/********************************/ +#define SERV_TYPE 6 +#define FRM_IPADDR 8 +#define LOG_IPHOST 14 +#define LOG_SERVICE 15 +#define FRM_IPX 23 +#define SESSION_TIMEOUT 27 +#define IDLE_TIMEOUT 28 +#define FRM_ATALK_LINK 37 +#define FRM_ATALK_NETWORK 38 + +#define ACCT_DELAY 41 +#define ACCT_SESSION_TIME 46 + +#define TUNNEL_TYPE 64 +#define TUNNEL_MEDIUM 65 +#define TUNNEL_CLIENT_END 66 +#define TUNNEL_SERVER_END 67 +#define TUNNEL_PASS 69 + +#define ARAP_PASS 70 +#define ARAP_FEATURES 71 + +#define TUNNEL_PRIV_GROUP 81 +#define TUNNEL_ASSIGN_ID 82 +#define TUNNEL_PREFERENCE 83 + +#define ARAP_CHALLENGE_RESP 84 +#define ACCT_INT_INTERVAL 85 + +#define TUNNEL_CLIENT_AUTH 90 +#define TUNNEL_SERVER_AUTH 91 +/********************************/ +/* End Radius Attribute types */ +/********************************/ + + +static void print_attr_string(register u_char *, u_int, u_short ); +static void print_attr_num(register u_char *, u_int, u_short ); +static void print_vendor_attr(register u_char *, u_int, u_short ); +static void print_attr_address(register u_char *, u_int, u_short); +static void print_attr_time(register u_char *, u_int, u_short); +static void print_attr_strange(register u_char *, u_int, u_short); + + +struct radius_hdr { u_int8_t code; /* Radius packet code */ + u_int8_t id; /* Radius packet id */ + u_int16_t len; /* Radius total length */ + u_int8_t auth[16]; /* Authenticator */ + }; + +#define MIN_RADIUS_LEN 20 + +struct radius_attr { u_int8_t type; /* Attribute type */ + u_int8_t len; /* Attribute length */ + }; + + +/* Service-Type Attribute standard values */ +static const char *serv_type[]={ NULL, + "Login", + "Framed", + "Callback Login", + "Callback Framed", + "Outbound", + "Administrative", + "NAS Prompt", + "Authenticate Only", + "Callback NAS Prompt", + "Call Check", + "Callback Administrative", + }; + +/* Framed-Protocol Attribute standard values */ +static const char *frm_proto[]={ NULL, + "PPP", + "SLIP", + "ARAP", + "Gandalf proprietary", + "Xylogics IPX/SLIP", + "X.75 Synchronous", + }; + +/* Framed-Routing Attribute standard values */ +static const char *frm_routing[]={ "None", + "Send", + "Listen", + "Send&Listen", + }; + +/* Framed-Compression Attribute standard values */ +static const char *frm_comp[]={ "None", + "VJ TCP/IP", + "IPX", + "Stac-LZS", + }; + +/* Login-Service Attribute standard values */ +static const char *login_serv[]={ "Telnet", + "Rlogin", + "TCP Clear", + "PortMaster(proprietary)", + "LAT", + "X.25-PAD", + "X.25-T3POS", + "Unassigned", + "TCP Clear Quiet", + }; + + +/* Termination-Action Attribute standard values */ +static const char *term_action[]={ "Default", + "RADIUS-Request", + }; + +/* NAS-Port-Type Attribute standard values */ +static const char *nas_port_type[]={ "Async", + "Sync", + "ISDN Sync", + "ISDN Async V.120", + "ISDN Async V.110", + "Virtual", + "PIAFS", + "HDLC Clear Channel", + "X.25", + "X.75", + "G.3 Fax", + "SDSL", + "ADSL-CAP", + "ADSL-DMT", + "ISDN-DSL", + "Ethernet", + "xDSL", + "Cable", + "Wireless - Other", + "Wireless - IEEE 802.11", + }; + +/* Acct-Status-Type Accounting Attribute standard values */ +static const char *acct_status[]={ NULL, + "Start", + "Stop", + "Interim-Update", + "Unassigned", + "Unassigned", + "Unassigned", + "Accounting-On", + "Accounting-Off", + "Tunnel-Start", + "Tunnel-Stop", + "Tunnel-Reject", + "Tunnel-Link-Start", + "Tunnel-Link-Stop", + "Tunnel-Link-Reject", + "Failed", + }; + +/* Acct-Authentic Accounting Attribute standard values */ +static const char *acct_auth[]={ NULL, + "RADIUS", + "Local", + "Remote", + }; + +/* Acct-Terminate-Cause Accounting Attribute standard values */ +static const char *acct_term[]={ NULL, + "User Request", + "Lost Carrier", + "Lost Service", + "Idle Timeout", + "Session Timeout", + "Admin Reset", + "Admin Reboot", + "Port Error", + "NAS Error", + "NAS Request", + "NAS Reboot", + "Port Unneeded", + "Port Preempted", + "Port Suspended", + "Service Unavailable", + "Callback", + "User Error", + "Host Request", + }; + +/* Tunnel-Type Attribute standard values */ +static const char *tunnel_type[]={ NULL, + "PPTP", + "L2F", + "L2TP", + "ATMP", + "VTP", + "AH", + "IP-IP", + "MIN-IP-IP", + "ESP", + "GRE", + "DVS", + "IP-in-IP Tunneling", + }; + +/* Tunnel-Medium-Type Attribute standard values */ +static const char *tunnel_medium[]={ NULL, + "IPv4", + "IPv6", + "NSAP", + "HDLC", + "BBN 1822", + "802", + "E.163", + "E.164", + "F.69", + "X.121", + "IPX", + "Appletalk", + "Decnet IV", + "Banyan Vines", + "E.164 with NSAP subaddress", + }; + +/* ARAP-Zone-Access Attribute standard values */ +static const char *arap_zone[]={ NULL, + "Only access to dfl zone", + "Use zone filter inc.", + "Not used", + "Use zone filter exc.", + }; + +static const char *prompt[]={ "No Echo", + "Echo", + }; + + +struct attrtype { const char *name; /* Attribute name */ + const char **subtypes; /* Standard Values (if any) */ + u_char siz_subtypes; /* Size of total standard values */ + u_char first_subtype; /* First standard value is 0 or 1 */ + void (*print_func)(register u_char *, u_int, u_short ); + } attr_type[]= + { + { NULL, NULL, 0, 0, NULL }, + { "Username", NULL, 0, 0, print_attr_string }, + { "Password", NULL, 0, 0, NULL }, + { "CHAP Password", NULL, 0, 0, NULL }, + { "NAS IP Address", NULL, 0, 0, print_attr_address }, + { "NAS Port", NULL, 0, 0, print_attr_num }, + { "Service Type", serv_type, TAM_SIZE(serv_type)-1, 1, print_attr_num }, + { "Framed Protocol", frm_proto, TAM_SIZE(frm_proto)-1, 1, print_attr_num }, + { "Framed IP Address", NULL, 0, 0, print_attr_address }, + { "Framed IP Network", NULL, 0, 0, print_attr_address }, + { "Framed Routing", frm_routing, TAM_SIZE(frm_routing), 0, print_attr_num }, + { "Filter ID", NULL, 0, 0, print_attr_string }, + { "Framed MTU", NULL, 0, 0, print_attr_num }, + { "Framed Compression", frm_comp, TAM_SIZE(frm_comp), 0, print_attr_num }, + { "Login IP Host", NULL, 0, 0, print_attr_address }, + { "Login Service", login_serv, TAM_SIZE(login_serv), 0, print_attr_num }, + { "Login TCP Port", NULL, 0, 0, print_attr_num }, + { "Unassigned", NULL, 0, 0, NULL }, /*17*/ + { "Reply", NULL, 0, 0, print_attr_string }, + { "Callback-number", NULL, 0, 0, print_attr_string }, + { "Callback-ID", NULL, 0, 0, print_attr_string }, + { "Unassigned", NULL, 0, 0, NULL }, /*21*/ + { "Framed Route", NULL, 0, 0, print_attr_string }, + { "Framed IPX Network", NULL, 0, 0, print_attr_num }, + { "State", NULL, 0, 0, print_attr_string }, + { "Class", NULL, 0, 0, print_attr_string }, + { "Vendor Specific", NULL, 0, 0, print_vendor_attr }, + { "Session Timeout", NULL, 0, 0, print_attr_num }, + { "Idle Timeout", NULL, 0, 0, print_attr_num }, + { "Termination Action", term_action, TAM_SIZE(term_action), 0, print_attr_num }, + { "Called Station", NULL, 0, 0, print_attr_string }, + { "Calling Station", NULL, 0, 0, print_attr_string }, + { "NAS ID", NULL, 0, 0, print_attr_string }, + { "Proxy State", NULL, 0, 0, print_attr_string }, + { "Login LAT Service", NULL, 0, 0, print_attr_string }, + { "Login LAT Node", NULL, 0, 0, print_attr_string }, + { "Login LAT Group", NULL, 0, 0, print_attr_string }, + { "Framed Appletalk Link", NULL, 0, 0, print_attr_num }, + { "Framed Appltalk Net", NULL, 0, 0, print_attr_num }, + { "Framed Appletalk Zone", NULL, 0, 0, print_attr_string }, + { "Accounting Status", acct_status, TAM_SIZE(acct_status)-1, 1, print_attr_num }, + { "Accounting Delay", NULL, 0, 0, print_attr_num }, + { "Accounting Input Octets", NULL, 0, 0, print_attr_num }, + { "Accounting Output Octets", NULL, 0, 0, print_attr_num }, + { "Accounting Session ID", NULL, 0, 0, print_attr_string }, + { "Accounting Authentication", acct_auth, TAM_SIZE(acct_auth)-1, 1, print_attr_num }, + { "Accounting Session Time", NULL, 0, 0, print_attr_num }, + { "Accounting Input Packets", NULL, 0, 0, print_attr_num }, + { "Accounting Output Packets", NULL, 0, 0, print_attr_num }, + { "Accounting Termination Cause", acct_term, TAM_SIZE(acct_term)-1, 1, print_attr_num }, + { "Accounting Multilink Session ID", NULL, 0, 0, print_attr_string }, + { "Accounting Link Count", NULL, 0, 0, print_attr_num }, + { "Accounting Input Giga", NULL, 0, 0, print_attr_num }, + { "Accounting Output Giga", NULL, 0, 0, print_attr_num }, + { "Unassigned", NULL, 0, 0, NULL }, /*54*/ + { "Event Timestamp", NULL, 0, 0, print_attr_time }, + { "Unassigned", NULL, 0, 0, NULL }, /*56*/ + { "Unassigned", NULL, 0, 0, NULL }, /*57*/ + { "Unassigned", NULL, 0, 0, NULL }, /*58*/ + { "Unassigned", NULL, 0, 0, NULL }, /*59*/ + { "CHAP challenge", NULL, 0, 0, print_attr_string }, + { "NAS Port Type", nas_port_type, TAM_SIZE(nas_port_type), 0, print_attr_num }, + { "Port Limit", NULL, 0, 0, print_attr_num }, + { "Login LAT Port", NULL, 0, 0, print_attr_string }, /*63*/ + { "Tunnel Type", tunnel_type, TAM_SIZE(tunnel_type)-1, 1, print_attr_num }, + { "Tunnel Medium", tunnel_medium, TAM_SIZE(tunnel_medium)-1, 1, print_attr_num }, + { "Tunnel Client End", NULL, 0, 0, print_attr_string }, + { "Tunnel Server End", NULL, 0, 0, print_attr_string }, + { "Accounting Tunnel connect", NULL, 0, 0, print_attr_string }, + { "Tunnel Password", NULL, 0, 0, print_attr_string }, + { "ARAP Password", NULL, 0, 0, print_attr_strange }, + { "ARAP Feature", NULL, 0, 0, print_attr_strange }, + { "ARAP Zone Acces", arap_zone, TAM_SIZE(arap_zone)-1, 1, print_attr_num }, /*72*/ + { "ARAP Security", NULL, 0, 0, print_attr_string }, + { "ARAP Security Data", NULL, 0, 0, print_attr_string }, + { "Password Retry", NULL, 0, 0, print_attr_num }, + { "Prompt", prompt, TAM_SIZE(prompt), 0, print_attr_num }, + { "Connect Info", NULL, 0, 0, print_attr_string }, + { "Config Token", NULL, 0, 0, print_attr_string }, + { "EAP Message", NULL, 0, 0, print_attr_string }, + { "Message Authentication", NULL, 0, 0, print_attr_string }, /*80*/ + { "Tunnel Private Group", NULL, 0, 0, print_attr_string }, + { "Tunnel Assigned ID", NULL, 0, 0, print_attr_string }, + { "Tunnel Preference", NULL, 0, 0, print_attr_num }, + { "ARAP Challenge Response", NULL, 0, 0, print_attr_strange }, + { "Accounting Interim Interval", NULL, 0, 0, print_attr_num }, + { "Accounting Tunnel packets lost", NULL, 0, 0, print_attr_num }, /*86*/ + { "NAS Port ID", NULL, 0, 0, print_attr_string }, + { "Framed Pool", NULL, 0, 0, print_attr_string }, + { "Unassigned", NULL, 0, 0, NULL }, + { "Tunnel Client Authentication ID", NULL, 0, 0, print_attr_string }, + { "Tunnel Server Authentication ID", NULL, 0, 0, print_attr_string }, + { "Unassigned", NULL, 0, 0, NULL }, /*92*/ + { "Unassigned", NULL, 0, 0, NULL } /*93*/ + }; + + +/*****************************/ +/* Print an attribute string */ +/* value pointed by 'data' */ +/* and 'length' size. */ +/*****************************/ +/* Returns nothing. */ +/*****************************/ +static void +print_attr_string(register u_char *data, u_int length, u_short attr_code ) +{ + register u_int i; + + TCHECK2(data[0],length); + + switch(attr_code) + { + case TUNNEL_PASS: + if (length < 3) + { + printf(" [|radius]"); + return; + } + if (*data && (*data <=0x1F) ) + printf("Tag %u, ",*data); + data++; + length--; + printf("Salt %u ",EXTRACT_16BITS(data) ); + data+=2; + length-=2; + break; + case TUNNEL_CLIENT_END: + case TUNNEL_SERVER_END: + case TUNNEL_PRIV_GROUP: + case TUNNEL_ASSIGN_ID: + case TUNNEL_CLIENT_AUTH: + case TUNNEL_SERVER_AUTH: + if (*data <= 0x1F) + { + if (length < 1) + { + printf(" [|radius]"); + return; + } + printf("Tag %u",*data); + data++; + length--; + } + break; + } + + for (i=0; *data && i < length ; i++, data++) + printf("%c",(*data < 32 || *data > 128) ? '.' : *data ); + + return; + + trunc: + printf(" [|radius]"); +} + +/* + * print vendor specific attributes + */ + +static void +print_vendor_attr(register u_char *data, u_int length, u_short attr_code _U_) +{ + u_int idx; + u_int vendor_id; + u_int vendor_type; + u_int vendor_length; + + if (length < 4) + goto trunc; + TCHECK2(*data, 4); + vendor_id = EXTRACT_32BITS(data); + data+=4; + length-=4; + + printf("Vendor: %s (%u)", + tok2str(smi_values,"Unknown",vendor_id), + vendor_id); + + while (length >= 2) { + TCHECK2(*data, 2); + + vendor_type = *(data); + vendor_length = *(data+1); + + if (vendor_length < 2) + { + printf("\n\t Vendor Attribute: %u, Length: %u (bogus, must be >= 2)", + vendor_type, + vendor_length); + return; + } + if (vendor_length > length) + { + printf("\n\t Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)", + vendor_type, + vendor_length); + return; + } + data+=2; + vendor_length-=2; + length-=2; + TCHECK2(*data, vendor_length); + + printf("\n\t Vendor Attribute: %u, Length: %u, Value: ", + vendor_type, + vendor_length); + for (idx = 0; idx < vendor_length ; idx++, data++) + printf("%c",(*data < 32 || *data > 128) ? '.' : *data ); + length-=vendor_length; + } + return; + + trunc: + printf(" [|radius]"); +} + + + +/******************************/ +/* Print an attribute numeric */ +/* value pointed by 'data' */ +/* and 'length' size. */ +/******************************/ +/* Returns nothing. */ +/******************************/ +static void +print_attr_num(register u_char *data, u_int length, u_short attr_code ) +{ + u_int8_t tag; + u_int32_t timeout; + + if (length != 4) + { + printf("ERROR: length %u != 4", length); + return; + } + + TCHECK2(data[0],4); + /* This attribute has standard values */ + if (attr_type[attr_code].siz_subtypes) + { + static const char **table; + u_int32_t data_value; + table = attr_type[attr_code].subtypes; + + if ( (attr_code == TUNNEL_TYPE) || (attr_code == TUNNEL_MEDIUM) ) + { + if (!*data) + printf("Tag[Unused]"); + else + printf("Tag[%d]", *data); + data++; + data_value = EXTRACT_24BITS(data); + } + else + { + data_value = EXTRACT_32BITS(data); + } + if ( data_value <= (u_int32_t)(attr_type[attr_code].siz_subtypes - 1 + + attr_type[attr_code].first_subtype) && + data_value >= attr_type[attr_code].first_subtype ) + printf("%s",table[data_value]); + else + printf("#%u",data_value); + } + else + { + switch(attr_code) /* Be aware of special cases... */ + { + case FRM_IPX: + if (EXTRACT_32BITS( data) == 0xFFFFFFFE ) + printf("NAS Select"); + else + printf("%d",EXTRACT_32BITS( data) ); + break; + + case SESSION_TIMEOUT: + case IDLE_TIMEOUT: + case ACCT_DELAY: + case ACCT_SESSION_TIME: + case ACCT_INT_INTERVAL: + timeout = EXTRACT_32BITS( data); + if ( timeout < 60 ) + printf( "%02d secs", timeout); + else + { + if ( timeout < 3600 ) + printf( "%02d:%02d min", + timeout / 60, timeout % 60); + else + printf( "%02d:%02d:%02d hours", + timeout / 3600, (timeout % 3600) / 60, + timeout % 60); + } + break; + + case FRM_ATALK_LINK: + if (EXTRACT_32BITS(data) ) + printf("%d",EXTRACT_32BITS(data) ); + else + printf("Unnumbered" ); + break; + + case FRM_ATALK_NETWORK: + if (EXTRACT_32BITS(data) ) + printf("%d",EXTRACT_32BITS(data) ); + else + printf("NAS assigned" ); + break; + + case TUNNEL_PREFERENCE: + tag = *data; + data++; + if (tag == 0) + printf("Tag (Unused) %d",EXTRACT_24BITS(data) ); + else + printf("Tag (%d) %d", tag, EXTRACT_24BITS(data) ); + break; + + default: + printf("%d",EXTRACT_32BITS( data) ); + break; + + } /* switch */ + + } /* if-else */ + + return; + + trunc: + printf(" [|radius]"); +} + + +/*****************************/ +/* Print an attribute IPv4 */ +/* address value pointed by */ +/* 'data' and 'length' size. */ +/*****************************/ +/* Returns nothing. */ +/*****************************/ +static void +print_attr_address(register u_char *data, u_int length, u_short attr_code ) +{ + if (length != 4) + { + printf("ERROR: length %u != 4", length); + return; + } + + TCHECK2(data[0],4); + + switch(attr_code) + { + case FRM_IPADDR: + case LOG_IPHOST: + if (EXTRACT_32BITS(data) == 0xFFFFFFFF ) + printf("User Selected"); + else + if (EXTRACT_32BITS(data) == 0xFFFFFFFE ) + printf("NAS Select"); + else + printf("%s",ipaddr_string(data)); + break; + + default: + printf("%s",ipaddr_string(data) ); + break; + } + + return; + + trunc: + printf(" [|radius]"); +} + + +/*************************************/ +/* Print an attribute of 'secs since */ +/* January 1, 1970 00:00 UTC' value */ +/* pointed by 'data' and 'length' */ +/* size. */ +/*************************************/ +/* Returns nothing. */ +/*************************************/ +static void print_attr_time(register u_char *data, u_int length, u_short attr_code _U_) +{ + time_t attr_time; + char string[26]; + + if (length != 4) + { + printf("ERROR: length %u != 4", length); + return; + } + + TCHECK2(data[0],4); + + attr_time = EXTRACT_32BITS(data); + strlcpy(string, ctime(&attr_time), sizeof(string)); + /* Get rid of the newline */ + string[24] = '\0'; + printf("%.24s", string); + return; + + trunc: + printf(" [|radius]"); +} + + +/***********************************/ +/* Print an attribute of 'strange' */ +/* data format pointed by 'data' */ +/* and 'length' size. */ +/***********************************/ +/* Returns nothing. */ +/***********************************/ +static void print_attr_strange(register u_char *data, u_int length, u_short attr_code) +{ + u_short len_data; + + switch(attr_code) + { + case ARAP_PASS: + if (length != 16) + { + printf("ERROR: length %u != 16", length); + return; + } + printf("User_challenge ("); + TCHECK2(data[0],8); + len_data = 8; + PRINT_HEX(len_data, data); + printf(") User_resp("); + TCHECK2(data[0],8); + len_data = 8; + PRINT_HEX(len_data, data); + printf(")"); + break; + + case ARAP_FEATURES: + if (length != 14) + { + printf("ERROR: length %u != 14", length); + return; + } + TCHECK2(data[0],1); + if (*data) + printf("User can change password"); + else + printf("User cannot change password"); + data++; + TCHECK2(data[0],1); + printf(", Min password length: %d",*data); + data++; + printf(", created at: "); + TCHECK2(data[0],4); + len_data = 4; + PRINT_HEX(len_data, data); + printf(", expires in: "); + TCHECK2(data[0],4); + len_data = 4; + PRINT_HEX(len_data, data); + printf(", Current Time: "); + TCHECK2(data[0],4); + len_data = 4; + PRINT_HEX(len_data, data); + break; + + case ARAP_CHALLENGE_RESP: + if (length < 8) + { + printf("ERROR: length %u != 8", length); + return; + } + TCHECK2(data[0],8); + len_data = 8; + PRINT_HEX(len_data, data); + break; + } + return; + + trunc: + printf(" [|radius]"); +} + + + +static void +radius_attrs_print(register const u_char *attr, u_int length) +{ + register const struct radius_attr *rad_attr = (struct radius_attr *)attr; + const char *attr_string; + + while (length > 0) + { + if (length < 2) + goto trunc; + TCHECK(*rad_attr); + + if (rad_attr->type > 0 && rad_attr->type < TAM_SIZE(attr_type)) + attr_string = attr_type[rad_attr->type].name; + else + attr_string = "Unknown"; + if (rad_attr->len < 2) + { + printf("\n\t %s Attribute (%u), length: %u (bogus, must be >= 2)", + attr_string, + rad_attr->type, + rad_attr->len); + return; + } + if (rad_attr->len > length) + { + printf("\n\t %s Attribute (%u), length: %u (bogus, goes past end of packet)", + attr_string, + rad_attr->type, + rad_attr->len); + return; + } + printf("\n\t %s Attribute (%u), length: %u, Value: ", + attr_string, + rad_attr->type, + rad_attr->len); + + if (rad_attr->type < TAM_SIZE(attr_type)) + { + if (rad_attr->len > 2) + { + if ( attr_type[rad_attr->type].print_func ) + (*attr_type[rad_attr->type].print_func)( + ((u_char *)(rad_attr+1)), + rad_attr->len - 2, rad_attr->type); + } + } + /* do we also want to see a hex dump ? */ + if (vflag> 1) + print_unknown_data((u_char *)rad_attr+2,"\n\t ",(rad_attr->len)-2); + + length-=(rad_attr->len); + rad_attr = (struct radius_attr *)( ((char *)(rad_attr))+rad_attr->len); + } + return; + +trunc: + printf(" [|radius]"); +} + + +void +radius_print(const u_char *dat, u_int length) +{ + register const struct radius_hdr *rad; + u_int len, auth_idx; + + TCHECK2(*dat, MIN_RADIUS_LEN); + rad = (struct radius_hdr *)dat; + len = EXTRACT_16BITS(&rad->len); + + if (len < MIN_RADIUS_LEN) + { + printf(" [|radius]"); + return; + } + + if (len > length) + len = length; + + if (vflag < 1) { + printf("RADIUS, %s (%u), id: 0x%02x length: %u", + tok2str(radius_command_values,"Unknown Command",rad->code), + rad->code, + rad->id, + len); + return; + } + else { + printf("RADIUS, length: %u\n\t%s (%u), id: 0x%02x, Authenticator: ", + len, + tok2str(radius_command_values,"Unknown Command",rad->code), + rad->code, + rad->id); + + for(auth_idx=0; auth_idx < 16; auth_idx++) + printf("%02x", rad->auth[auth_idx] ); + } + + if (len > MIN_RADIUS_LEN) + radius_attrs_print( dat + MIN_RADIUS_LEN, len - MIN_RADIUS_LEN); + return; + +trunc: + printf(" [|radius]"); +} diff --git a/print-raw.c b/print-raw.c new file mode 100644 index 0000000..8e376ce --- /dev/null +++ b/print-raw.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-raw.c,v 1.41 2003-11-16 09:36:34 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "addrtoname.h" +#include "interface.h" + +/* + * The DLT_RAW packet has no header. It contains a raw IP packet. + */ + +u_int +raw_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + if (eflag) + printf("ip: "); + + ipN_print(p, h->len); + + return (0); +} diff --git a/print-rip.c b/print-rip.c new file mode 100644 index 0000000..27446a6 --- /dev/null +++ b/print-rip.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-rip.c,v 1.59 2006-03-23 14:58:44 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +#include "af.h" + +struct rip { + u_int8_t rip_cmd; /* request/response */ + u_int8_t rip_vers; /* protocol version # */ + u_int8_t unused[2]; /* unused */ +}; + +#define RIPCMD_REQUEST 1 /* want info */ +#define RIPCMD_RESPONSE 2 /* responding to request */ +#define RIPCMD_TRACEON 3 /* turn tracing on */ +#define RIPCMD_TRACEOFF 4 /* turn it off */ +#define RIPCMD_POLL 5 /* want info from everybody */ +#define RIPCMD_POLLENTRY 6 /* poll for entry */ + +static const struct tok rip_cmd_values[] = { + { RIPCMD_REQUEST, "Request" }, + { RIPCMD_RESPONSE, "Response" }, + { RIPCMD_TRACEON, "Trace on" }, + { RIPCMD_TRACEOFF, "Trace off" }, + { RIPCMD_POLL, "Poll" }, + { RIPCMD_POLLENTRY, "Poll Entry" }, + { 0, NULL} +}; + +#define RIP_AUTHLEN 16 +#define RIP_ROUTELEN 20 + +/* + * rfc 1723 + * + * 0 1 2 3 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Command (1) | Version (1) | unused | + * +---------------+---------------+-------------------------------+ + * | Address Family Identifier (2) | Route Tag (2) | + * +-------------------------------+-------------------------------+ + * | IP Address (4) | + * +---------------------------------------------------------------+ + * | Subnet Mask (4) | + * +---------------------------------------------------------------+ + * | Next Hop (4) | + * +---------------------------------------------------------------+ + * | Metric (4) | + * +---------------------------------------------------------------+ + * + */ + +struct rip_netinfo { + u_int16_t rip_family; + u_int16_t rip_tag; + u_int32_t rip_dest; + u_int32_t rip_dest_mask; + u_int32_t rip_router; + u_int32_t rip_metric; /* cost of route */ +}; + +static void +rip_entry_print_v1(register const struct rip_netinfo *ni) +{ + register u_short family; + + /* RFC 1058 */ + family = EXTRACT_16BITS(&ni->rip_family); + if (family != BSD_AFNUM_INET) { + printf("\n\t AFI %s, ", tok2str(bsd_af_values, "Unknown (%u)", family)); + print_unknown_data((u_int8_t *)&ni->rip_family,"\n\t ",RIP_ROUTELEN); + return; + } + if (EXTRACT_16BITS(&ni->rip_tag) || + EXTRACT_32BITS(&ni->rip_dest_mask) || + EXTRACT_32BITS(&ni->rip_router)) { + /* MBZ fields not zero */ + print_unknown_data((u_int8_t *)&ni->rip_family,"\n\t ",RIP_ROUTELEN); + return; + } /* BSD_AFNUM_INET */ + printf("\n\t %s, metric: %u", + ipaddr_string(&ni->rip_dest), + EXTRACT_32BITS(&ni->rip_metric)); +} + +static void +rip_entry_print_v2(register const struct rip_netinfo *ni) +{ + register u_char *p; + register u_short family; + u_char buf[RIP_AUTHLEN]; + + family = EXTRACT_16BITS(&ni->rip_family); + if (family == 0xFFFF) { /* 16 bytes authentication ? */ + if (EXTRACT_16BITS(&ni->rip_tag) == 2) { /* simple text authentication ? */ + memcpy(buf, &ni->rip_dest, sizeof(buf)); + buf[sizeof(buf)-1] = '\0'; + for (p = buf; *p; p++) { + if (!isprint(*p)) + break; + } + printf("\n\t Simple Text Authentication data: %s", buf); + } else { + printf("\n\t Unknown (%u) Authentication data:", + EXTRACT_16BITS(&ni->rip_tag)); + print_unknown_data((u_int8_t *)&ni->rip_dest,"\n\t ",RIP_AUTHLEN); + } + } else if (family != BSD_AFNUM_INET) { + printf("\n\t AFI %s", tok2str(bsd_af_values, "Unknown (%u)", family)); + print_unknown_data((u_int8_t *)&ni->rip_tag,"\n\t ",RIP_ROUTELEN-2); + return; + } else { /* BSD_AFNUM_INET */ + printf("\n\t AFI %s, %15s/%-2d, tag 0x%04x, metric: %u, next-hop: ", + tok2str(bsd_af_values, "Unknown (%u)", family), + ipaddr_string(&ni->rip_dest), + mask2plen(EXTRACT_32BITS(&ni->rip_dest_mask)), + EXTRACT_16BITS(&ni->rip_tag), + EXTRACT_32BITS(&ni->rip_metric)); + if (EXTRACT_32BITS(&ni->rip_router)) + printf("%s", ipaddr_string(&ni->rip_router)); + else + printf("self"); + } +} + +void +rip_print(const u_char *dat, u_int length) +{ + register const struct rip *rp; + register const struct rip_netinfo *ni; + register u_int i, j; + register int trunc; + + if (snapend < dat) { + printf(" [|rip]"); + return; + } + i = snapend - dat; + if (i > length) + i = length; + if (i < sizeof(*rp)) { + printf(" [|rip]"); + return; + } + i -= sizeof(*rp); + + rp = (struct rip *)dat; + + printf("%sRIPv%u", + (vflag >= 1) ? "\n\t" : "", + rp->rip_vers); + + switch (rp->rip_vers) { + case 0: + /* + * RFC 1058. + * + * XXX - RFC 1058 says + * + * 0 Datagrams whose version number is zero are to be ignored. + * These are from a previous version of the protocol, whose + * packet format was machine-specific. + * + * so perhaps we should just dump the packet, in hex. + */ + print_unknown_data((u_int8_t *)&rp->rip_cmd,"\n\t",length); + break; + default: + /* dump version and lets see if we know the commands name*/ + printf(", %s, length: %u", + tok2str(rip_cmd_values, + "unknown command (%u)", + rp->rip_cmd), + length); + + if (vflag < 1) + return; + + switch (rp->rip_cmd) { + case RIPCMD_RESPONSE: + j = length / sizeof(*ni); + printf(", routes: %u",j); + trunc = (i / sizeof(*ni)) != j; + ni = (struct rip_netinfo *)(rp + 1); + for (; i >= sizeof(*ni); ++ni) { + if (rp->rip_vers == 1) + rip_entry_print_v1(ni); + else if (rp->rip_vers == 2) + rip_entry_print_v2(ni); + else + break; + i -= sizeof(*ni); + } + if (trunc) + printf("[|rip]"); + break; + + case RIPCMD_REQUEST: + case RIPCMD_TRACEOFF: + case RIPCMD_POLL: + case RIPCMD_POLLENTRY: + break; + + case RIPCMD_TRACEON: + /* fall through */ + default: + if (vflag <= 1) { + if(!print_unknown_data((u_int8_t *)rp,"\n\t",length)) + return; + } + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag> 1) { + if(!print_unknown_data((u_int8_t *)rp,"\n\t",length)) + return; + } + } +} + + diff --git a/print-ripng.c b/print-ripng.c new file mode 100644 index 0000000..cef39da --- /dev/null +++ b/print-ripng.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 1989, 1990, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ripng.c,v 1.18 2005-01-04 00:15:54 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef INET6 + +#include +#include + +#include "route6d.h" +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#if !defined(IN6_IS_ADDR_UNSPECIFIED) && !defined(_MSC_VER) /* MSVC inline */ +static int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *addr) +{ + static const struct in6_addr in6addr_any; /* :: */ + return (memcmp(addr, &in6addr_any, sizeof(*addr)) == 0); +} +#endif + +static int +rip6_entry_print(register const struct netinfo6 *ni, int metric) +{ + int l; + l = printf("%s/%d", ip6addr_string(&ni->rip6_dest), ni->rip6_plen); + if (ni->rip6_tag) + l += printf(" [%d]", EXTRACT_16BITS(&ni->rip6_tag)); + if (metric) + l += printf(" (%d)", ni->rip6_metric); + return l; +} + +void +ripng_print(const u_char *dat, unsigned int length) +{ + register const struct rip6 *rp = (struct rip6 *)dat; + register const struct netinfo6 *ni; + register u_int amt; + register u_int i; + int j; + int trunc; + + if (snapend < dat) + return; + amt = snapend - dat; + i = min(length, amt); + if (i < (sizeof(struct rip6) - sizeof(struct netinfo6))) + return; + i -= (sizeof(struct rip6) - sizeof(struct netinfo6)); + + switch (rp->rip6_cmd) { + + case RIP6_REQUEST: + j = length / sizeof(*ni); + if (j == 1 + && rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6 + && IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) { + printf(" ripng-req dump"); + break; + } + if (j * sizeof(*ni) != length - 4) + printf(" ripng-req %d[%u]:", j, length); + else + printf(" ripng-req %d:", j); + trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i); + for (ni = rp->rip6_nets; i >= sizeof(*ni); + i -= sizeof(*ni), ++ni) { + if (vflag > 1) + printf("\n\t"); + else + printf(" "); + rip6_entry_print(ni, 0); + } + break; + case RIP6_RESPONSE: + j = length / sizeof(*ni); + if (j * sizeof(*ni) != length - 4) + printf(" ripng-resp %d[%u]:", j, length); + else + printf(" ripng-resp %d:", j); + trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i); + for (ni = rp->rip6_nets; i >= sizeof(*ni); + i -= sizeof(*ni), ++ni) { + if (vflag > 1) + printf("\n\t"); + else + printf(" "); + rip6_entry_print(ni, ni->rip6_metric); + } + if (trunc) + printf("[|ripng]"); + break; + default: + printf(" ripng-%d ?? %u", rp->rip6_cmd, length); + break; + } + if (rp->rip6_vers != RIP6_VERSION) + printf(" [vers %d]", rp->rip6_vers); +} +#endif /* INET6 */ diff --git a/print-rrcp.c b/print-rrcp.c new file mode 100644 index 0000000..961fb87 --- /dev/null +++ b/print-rrcp.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2007 - Andrey "nording" Chernyak + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Format and print Realtek Remote Control Protocol (RRCP) + * and Realtek Echo Protocol (RRCP-REP) packets. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-rrcp.c,v 1.2 2008-04-11 17:21:34 gianluca Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "netdissect.h" +#include "addrtoname.h" +#include "extract.h" +#include "ether.h" + +#ifndef ETH_ALEN +#define ETH_ALEN 6 +#endif + +#define RRCP_OPCODE_MASK 0x7F /* 0x00 = hello, 0x01 = get, 0x02 = set */ +#define RRCP_ISREPLY 0x80 /* 0 = request to switch, 0x80 = reply from switch */ + +#define RRCP_PROTO_OFFSET 0 /* proto - 1 byte, must be 1 */ +#define RRCP_OPCODE_ISREPLY_OFFSET 1 /* opcode and isreply flag - 1 byte */ +#define RRCP_AUTHKEY_OFFSET 2 /* authorization key - 2 bytes, 0x2379 by default */ + +/* most packets */ +#define RRCP_REG_ADDR_OFFSET 4 /* register address - 2 bytes */ +#define RRCP_REG_DATA_OFFSET 6 /* register data - 4 bytes */ +#define RRCP_COOKIE1_OFFSET 10 /* 4 bytes */ +#define RRCP_COOKIE2_OFFSET 14 /* 4 bytes */ + +/* hello reply packets */ +#define RRCP_DOWNLINK_PORT_OFFSET 4 /* 1 byte */ +#define RRCP_UPLINK_PORT_OFFSET 5 /* 1 byte */ +#define RRCP_UPLINK_MAC_OFFSET 6 /* 6 byte MAC address */ +#define RRCP_CHIP_ID_OFFSET 12 /* 2 bytes */ +#define RRCP_VENDOR_ID_OFFSET 14 /* 4 bytes */ + +static const struct tok proto_values[] = { + { 1, "RRCP" }, + { 2, "RRCP-REP" }, + { 0, NULL } +}; + +static const struct tok opcode_values[] = { + { 0, "hello" }, + { 1, "get" }, + { 2, "set" }, + { 0, NULL } +}; + +/* + * Print RRCP requests + */ +void +rrcp_print(netdissect_options *ndo, + register const u_char *cp, + u_int length _U_) +{ + const u_char *rrcp; + u_int8_t rrcp_proto; + u_int8_t rrcp_opcode; + register const struct ether_header *ep; + char proto_str[16]; + char opcode_str[32]; + + ep = (const struct ether_header *)cp; + rrcp = cp + ETHER_HDRLEN; + + ND_TCHECK(*(rrcp + RRCP_PROTO_OFFSET)); + rrcp_proto = *(rrcp + RRCP_PROTO_OFFSET); + ND_TCHECK(*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)); + rrcp_opcode = (*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK; + ND_PRINT((ndo, "%s > %s, %s %s", + etheraddr_string(ESRC(ep)), + etheraddr_string(EDST(ep)), + tok2strbuf(proto_values,"RRCP-0x%02d",rrcp_proto,proto_str,sizeof(proto_str)), + ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query")); + if (rrcp_proto==1){ + ND_PRINT((ndo, ": %s", + tok2strbuf(opcode_values,"unknown opcode (0x%02d)",rrcp_opcode,opcode_str,sizeof(opcode_str)))); + } + if (rrcp_opcode==1 || rrcp_opcode==2){ + ND_TCHECK2(*(rrcp + RRCP_REG_ADDR_OFFSET), 6); + ND_PRINT((ndo, " addr=0x%04x, data=0x%08x", + EXTRACT_16BITS(rrcp + RRCP_REG_ADDR_OFFSET), + EXTRACT_32BITS(rrcp + RRCP_REG_DATA_OFFSET))); + } + if (rrcp_proto==1){ + ND_TCHECK2(*(rrcp + RRCP_AUTHKEY_OFFSET), 2); + ND_PRINT((ndo, ", auth=0x%04x", + EXTRACT_16BITS(rrcp + RRCP_AUTHKEY_OFFSET))); + } + if (rrcp_proto==1 && rrcp_opcode==0 && + ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){ + ND_TCHECK2(*(rrcp + RRCP_VENDOR_ID_OFFSET), 4); + ND_PRINT((ndo, " downlink_port=%d, uplink_port=%d, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ", + *(rrcp + RRCP_DOWNLINK_PORT_OFFSET), + *(rrcp + RRCP_UPLINK_PORT_OFFSET), + etheraddr_string(rrcp + RRCP_UPLINK_MAC_OFFSET), + EXTRACT_32BITS(rrcp + RRCP_VENDOR_ID_OFFSET), + EXTRACT_16BITS(rrcp + RRCP_CHIP_ID_OFFSET))); + }else if (rrcp_opcode==1 || rrcp_opcode==2 || rrcp_proto==2){ + ND_TCHECK2(*(rrcp + RRCP_COOKIE2_OFFSET), 4); + ND_PRINT((ndo, ", cookie=0x%08x%08x ", + EXTRACT_32BITS(rrcp + RRCP_COOKIE2_OFFSET), + EXTRACT_32BITS(rrcp + RRCP_COOKIE1_OFFSET))); + } + if (!ndo->ndo_vflag) + return; + return; + +trunc: + ND_PRINT((ndo, "[|rrcp]")); +} diff --git a/print-rsvp.c b/print-rsvp.c new file mode 100644 index 0000000..6aa2f6d --- /dev/null +++ b/print-rsvp.c @@ -0,0 +1,1944 @@ +/* + * Copyright (c) 1998-2007 The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-rsvp.c,v 1.50 2008-08-16 11:36:20 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "gmpls.h" +#include "af.h" +#include "signature.h" + +/* + * RFC 2205 common header + * + * 0 1 2 3 + * +-------------+-------------+-------------+-------------+ + * | Vers | Flags| Msg Type | RSVP Checksum | + * +-------------+-------------+-------------+-------------+ + * | Send_TTL | (Reserved) | RSVP Length | + * +-------------+-------------+-------------+-------------+ + * + */ + +struct rsvp_common_header { + u_int8_t version_flags; + u_int8_t msg_type; + u_int8_t checksum[2]; + u_int8_t ttl; + u_int8_t reserved; + u_int8_t length[2]; +}; + +/* + * RFC2205 object header + * + * + * 0 1 2 3 + * +-------------+-------------+-------------+-------------+ + * | Length (bytes) | Class-Num | C-Type | + * +-------------+-------------+-------------+-------------+ + * | | + * // (Object contents) // + * | | + * +-------------+-------------+-------------+-------------+ + */ + +struct rsvp_object_header { + u_int8_t length[2]; + u_int8_t class_num; + u_int8_t ctype; +}; + +#define RSVP_VERSION 1 +#define RSVP_EXTRACT_VERSION(x) (((x)&0xf0)>>4) +#define RSVP_EXTRACT_FLAGS(x) ((x)&0x0f) + +#define RSVP_MSGTYPE_PATH 1 +#define RSVP_MSGTYPE_RESV 2 +#define RSVP_MSGTYPE_PATHERR 3 +#define RSVP_MSGTYPE_RESVERR 4 +#define RSVP_MSGTYPE_PATHTEAR 5 +#define RSVP_MSGTYPE_RESVTEAR 6 +#define RSVP_MSGTYPE_RESVCONF 7 +#define RSVP_MSGTYPE_AGGREGATE 12 +#define RSVP_MSGTYPE_ACK 13 +#define RSVP_MSGTYPE_HELLO_OLD 14 /* ancient Hellos */ +#define RSVP_MSGTYPE_SREFRESH 15 +#define RSVP_MSGTYPE_HELLO 20 + +static const struct tok rsvp_msg_type_values[] = { + { RSVP_MSGTYPE_PATH, "Path" }, + { RSVP_MSGTYPE_RESV, "Resv" }, + { RSVP_MSGTYPE_PATHERR, "PathErr" }, + { RSVP_MSGTYPE_RESVERR, "ResvErr" }, + { RSVP_MSGTYPE_PATHTEAR, "PathTear" }, + { RSVP_MSGTYPE_RESVTEAR, "ResvTear" }, + { RSVP_MSGTYPE_RESVCONF, "ResvConf" }, + { RSVP_MSGTYPE_AGGREGATE, "Aggregate" }, + { RSVP_MSGTYPE_ACK, "Acknowledgement" }, + { RSVP_MSGTYPE_HELLO_OLD, "Hello (Old)" }, + { RSVP_MSGTYPE_SREFRESH, "Refresh" }, + { RSVP_MSGTYPE_HELLO, "Hello" }, + { 0, NULL} +}; + +static const struct tok rsvp_header_flag_values[] = { + { 0x01, "Refresh reduction capable" }, /* rfc2961 */ + { 0, NULL} +}; + +#define RSVP_OBJ_SESSION 1 /* rfc2205 */ +#define RSVP_OBJ_RSVP_HOP 3 /* rfc2205, rfc3473 */ +#define RSVP_OBJ_INTEGRITY 4 /* rfc2747 */ +#define RSVP_OBJ_TIME_VALUES 5 /* rfc2205 */ +#define RSVP_OBJ_ERROR_SPEC 6 +#define RSVP_OBJ_SCOPE 7 +#define RSVP_OBJ_STYLE 8 /* rfc2205 */ +#define RSVP_OBJ_FLOWSPEC 9 /* rfc2215 */ +#define RSVP_OBJ_FILTERSPEC 10 /* rfc2215 */ +#define RSVP_OBJ_SENDER_TEMPLATE 11 +#define RSVP_OBJ_SENDER_TSPEC 12 /* rfc2215 */ +#define RSVP_OBJ_ADSPEC 13 /* rfc2215 */ +#define RSVP_OBJ_POLICY_DATA 14 +#define RSVP_OBJ_CONFIRM 15 /* rfc2205 */ +#define RSVP_OBJ_LABEL 16 /* rfc3209 */ +#define RSVP_OBJ_LABEL_REQ 19 /* rfc3209 */ +#define RSVP_OBJ_ERO 20 /* rfc3209 */ +#define RSVP_OBJ_RRO 21 /* rfc3209 */ +#define RSVP_OBJ_HELLO 22 /* rfc3209 */ +#define RSVP_OBJ_MESSAGE_ID 23 /* rfc2961 */ +#define RSVP_OBJ_MESSAGE_ID_ACK 24 /* rfc2961 */ +#define RSVP_OBJ_MESSAGE_ID_LIST 25 /* rfc2961 */ +#define RSVP_OBJ_RECOVERY_LABEL 34 /* rfc3473 */ +#define RSVP_OBJ_UPSTREAM_LABEL 35 /* rfc3473 */ +#define RSVP_OBJ_LABEL_SET 36 /* rfc3473 */ +#define RSVP_OBJ_PROTECTION 37 /* rfc3473 */ +#define RSVP_OBJ_S2L 50 /* rfc4875 */ +#define RSVP_OBJ_DETOUR 63 /* draft-ietf-mpls-rsvp-lsp-fastreroute-07 */ +#define RSVP_OBJ_CLASSTYPE 66 /* rfc4124 */ +#define RSVP_OBJ_CLASSTYPE_OLD 125 /* draft-ietf-tewg-diff-te-proto-07 */ +#define RSVP_OBJ_SUGGESTED_LABEL 129 /* rfc3473 */ +#define RSVP_OBJ_ACCEPT_LABEL_SET 130 /* rfc3473 */ +#define RSVP_OBJ_RESTART_CAPABILITY 131 /* rfc3473 */ +#define RSVP_OBJ_NOTIFY_REQ 195 /* rfc3473 */ +#define RSVP_OBJ_ADMIN_STATUS 196 /* rfc3473 */ +#define RSVP_OBJ_PROPERTIES 204 /* juniper proprietary */ +#define RSVP_OBJ_FASTREROUTE 205 /* draft-ietf-mpls-rsvp-lsp-fastreroute-07 */ +#define RSVP_OBJ_SESSION_ATTRIBUTE 207 /* rfc3209 */ +#define RSVP_OBJ_GENERALIZED_UNI 229 /* OIF RSVP extensions UNI 1.0 Signaling, Rel. 2 */ +#define RSVP_OBJ_CALL_ID 230 /* rfc3474 */ +#define RSVP_OBJ_CALL_OPS 236 /* rfc3474 */ + +static const struct tok rsvp_obj_values[] = { + { RSVP_OBJ_SESSION, "Session" }, + { RSVP_OBJ_RSVP_HOP, "RSVP Hop" }, + { RSVP_OBJ_INTEGRITY, "Integrity" }, + { RSVP_OBJ_TIME_VALUES, "Time Values" }, + { RSVP_OBJ_ERROR_SPEC, "Error Spec" }, + { RSVP_OBJ_SCOPE, "Scope" }, + { RSVP_OBJ_STYLE, "Style" }, + { RSVP_OBJ_FLOWSPEC, "Flowspec" }, + { RSVP_OBJ_FILTERSPEC, "FilterSpec" }, + { RSVP_OBJ_SENDER_TEMPLATE, "Sender Template" }, + { RSVP_OBJ_SENDER_TSPEC, "Sender TSpec" }, + { RSVP_OBJ_ADSPEC, "Adspec" }, + { RSVP_OBJ_POLICY_DATA, "Policy Data" }, + { RSVP_OBJ_CONFIRM, "Confirm" }, + { RSVP_OBJ_LABEL, "Label" }, + { RSVP_OBJ_LABEL_REQ, "Label Request" }, + { RSVP_OBJ_ERO, "ERO" }, + { RSVP_OBJ_RRO, "RRO" }, + { RSVP_OBJ_HELLO, "Hello" }, + { RSVP_OBJ_MESSAGE_ID, "Message ID" }, + { RSVP_OBJ_MESSAGE_ID_ACK, "Message ID Ack" }, + { RSVP_OBJ_MESSAGE_ID_LIST, "Message ID List" }, + { RSVP_OBJ_RECOVERY_LABEL, "Recovery Label" }, + { RSVP_OBJ_UPSTREAM_LABEL, "Upstream Label" }, + { RSVP_OBJ_LABEL_SET, "Label Set" }, + { RSVP_OBJ_ACCEPT_LABEL_SET, "Acceptable Label Set" }, + { RSVP_OBJ_DETOUR, "Detour" }, + { RSVP_OBJ_CLASSTYPE, "Class Type" }, + { RSVP_OBJ_CLASSTYPE_OLD, "Class Type (old)" }, + { RSVP_OBJ_SUGGESTED_LABEL, "Suggested Label" }, + { RSVP_OBJ_PROPERTIES, "Properties" }, + { RSVP_OBJ_FASTREROUTE, "Fast Re-Route" }, + { RSVP_OBJ_SESSION_ATTRIBUTE, "Session Attribute" }, + { RSVP_OBJ_GENERALIZED_UNI, "Generalized UNI" }, + { RSVP_OBJ_CALL_ID, "Call-ID" }, + { RSVP_OBJ_CALL_OPS, "Call Capability" }, + { RSVP_OBJ_RESTART_CAPABILITY, "Restart Capability" }, + { RSVP_OBJ_NOTIFY_REQ, "Notify Request" }, + { RSVP_OBJ_PROTECTION, "Protection" }, + { RSVP_OBJ_ADMIN_STATUS, "Administrative Status" }, + { RSVP_OBJ_S2L, "Sub-LSP to LSP" }, + { 0, NULL} +}; + +#define RSVP_CTYPE_IPV4 1 +#define RSVP_CTYPE_IPV6 2 +#define RSVP_CTYPE_TUNNEL_IPV4 7 +#define RSVP_CTYPE_TUNNEL_IPV6 8 +#define RSVP_CTYPE_UNI_IPV4 11 /* OIF RSVP extensions UNI 1.0 Signaling Rel. 2 */ +#define RSVP_CTYPE_1 1 +#define RSVP_CTYPE_2 2 +#define RSVP_CTYPE_3 3 +#define RSVP_CTYPE_4 4 +#define RSVP_CTYPE_12 12 +#define RSVP_CTYPE_13 13 +#define RSVP_CTYPE_14 14 + +/* + * the ctypes are not globally unique so for + * translating it to strings we build a table based + * on objects offsetted by the ctype + */ + +static const struct tok rsvp_ctype_values[] = { + { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_IPV6, "IPv6" }, + { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_3, "IPv4 plus opt. TLVs" }, + { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_4, "IPv6 plus opt. TLVs" }, + { 256*RSVP_OBJ_NOTIFY_REQ+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_NOTIFY_REQ+RSVP_CTYPE_IPV6, "IPv6" }, + { 256*RSVP_OBJ_CONFIRM+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_CONFIRM+RSVP_CTYPE_IPV6, "IPv6" }, + { 256*RSVP_OBJ_TIME_VALUES+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_FLOWSPEC+RSVP_CTYPE_1, "obsolete" }, + { 256*RSVP_OBJ_FLOWSPEC+RSVP_CTYPE_2, "IntServ" }, + { 256*RSVP_OBJ_SENDER_TSPEC+RSVP_CTYPE_2, "IntServ" }, + { 256*RSVP_OBJ_ADSPEC+RSVP_CTYPE_2, "IntServ" }, + { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_IPV6, "IPv6" }, + { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_3, "IPv6 Flow-label" }, + { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, + { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_12, "IPv4 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_13, "IPv6 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_IPV6, "IPv6" }, + { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, + { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_UNI_IPV4, "UNI IPv4" }, + { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_13, "IPv4 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_14, "IPv6 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_IPV6, "IPv6" }, + { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, + { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_12, "IPv4 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_13, "IPv6 P2MP LSP Tunnel" }, + { 256*RSVP_OBJ_MESSAGE_ID+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_MESSAGE_ID_ACK+RSVP_CTYPE_1, "Message id ack" }, + { 256*RSVP_OBJ_MESSAGE_ID_ACK+RSVP_CTYPE_2, "Message id nack" }, + { 256*RSVP_OBJ_MESSAGE_ID_LIST+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_STYLE+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_HELLO+RSVP_CTYPE_1, "Hello Request" }, + { 256*RSVP_OBJ_HELLO+RSVP_CTYPE_2, "Hello Ack" }, + { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_1, "without label range" }, + { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_2, "with ATM label range" }, + { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_3, "with FR label range" }, + { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_4, "Generalized Label" }, + { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_1, "Label" }, + { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_2, "Generalized Label" }, + { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_3, "Waveband Switching" }, + { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_1, "Label" }, + { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_2, "Generalized Label" }, + { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_3, "Waveband Switching" }, + { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_1, "Label" }, + { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_2, "Generalized Label" }, + { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_3, "Waveband Switching" }, + { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_1, "Label" }, + { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_2, "Generalized Label" }, + { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_3, "Waveband Switching" }, + { 256*RSVP_OBJ_ERO+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_RRO+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_IPV4, "IPv4" }, + { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_IPV6, "IPv6" }, + { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_3, "IPv4 plus opt. TLVs" }, + { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_4, "IPv6 plus opt. TLVs" }, + { 256*RSVP_OBJ_RESTART_CAPABILITY+RSVP_CTYPE_1, "IPv4" }, + { 256*RSVP_OBJ_SESSION_ATTRIBUTE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, + { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, /* old style*/ + { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_1, "1" }, /* new style */ + { 256*RSVP_OBJ_DETOUR+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, + { 256*RSVP_OBJ_PROPERTIES+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_ADMIN_STATUS+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_CLASSTYPE+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_CLASSTYPE_OLD+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_LABEL_SET+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_GENERALIZED_UNI+RSVP_CTYPE_1, "1" }, + { 256*RSVP_OBJ_S2L+RSVP_CTYPE_IPV4, "IPv4 sub-LSP" }, + { 256*RSVP_OBJ_S2L+RSVP_CTYPE_IPV6, "IPv6 sub-LSP" }, + { 0, NULL} +}; + +struct rsvp_obj_integrity_t { + u_int8_t flags; + u_int8_t res; + u_int8_t key_id[6]; + u_int8_t sequence[8]; + u_int8_t digest[16]; +}; + +static const struct tok rsvp_obj_integrity_flag_values[] = { + { 0x80, "Handshake" }, + { 0, NULL} +}; + +struct rsvp_obj_frr_t { + u_int8_t setup_prio; + u_int8_t hold_prio; + u_int8_t hop_limit; + u_int8_t flags; + u_int8_t bandwidth[4]; + u_int8_t include_any[4]; + u_int8_t exclude_any[4]; + u_int8_t include_all[4]; +}; + + +#define RSVP_OBJ_XRO_MASK_SUBOBJ(x) ((x)&0x7f) +#define RSVP_OBJ_XRO_MASK_LOOSE(x) ((x)&0x80) + +#define RSVP_OBJ_XRO_RES 0 +#define RSVP_OBJ_XRO_IPV4 1 +#define RSVP_OBJ_XRO_IPV6 2 +#define RSVP_OBJ_XRO_LABEL 3 +#define RSVP_OBJ_XRO_ASN 32 +#define RSVP_OBJ_XRO_MPLS 64 + +static const struct tok rsvp_obj_xro_values[] = { + { RSVP_OBJ_XRO_RES, "Reserved" }, + { RSVP_OBJ_XRO_IPV4, "IPv4 prefix" }, + { RSVP_OBJ_XRO_IPV6, "IPv6 prefix" }, + { RSVP_OBJ_XRO_LABEL, "Label" }, + { RSVP_OBJ_XRO_ASN, "Autonomous system number" }, + { RSVP_OBJ_XRO_MPLS, "MPLS label switched path termination" }, + { 0, NULL} +}; + +/* draft-ietf-mpls-rsvp-lsp-fastreroute-07.txt */ +static const struct tok rsvp_obj_rro_flag_values[] = { + { 0x01, "Local protection available" }, + { 0x02, "Local protection in use" }, + { 0x04, "Bandwidth protection" }, + { 0x08, "Node protection" }, + { 0, NULL} +}; + +/* RFC3209 */ +static const struct tok rsvp_obj_rro_label_flag_values[] = { + { 0x01, "Global" }, + { 0, NULL} +}; + +static const struct tok rsvp_resstyle_values[] = { + { 17, "Wildcard Filter" }, + { 10, "Fixed Filter" }, + { 18, "Shared Explicit" }, + { 0, NULL} +}; + +#define RSVP_OBJ_INTSERV_GUARANTEED_SERV 2 +#define RSVP_OBJ_INTSERV_CONTROLLED_LOAD 5 + +static const struct tok rsvp_intserv_service_type_values[] = { + { 1, "Default/Global Information" }, + { RSVP_OBJ_INTSERV_GUARANTEED_SERV, "Guaranteed Service" }, + { RSVP_OBJ_INTSERV_CONTROLLED_LOAD, "Controlled Load" }, + { 0, NULL} +}; + +static const struct tok rsvp_intserv_parameter_id_values[] = { + { 4, "IS hop cnt" }, + { 6, "Path b/w estimate" }, + { 8, "Minimum path latency" }, + { 10, "Composed MTU" }, + { 127, "Token Bucket TSpec" }, + { 130, "Guaranteed Service RSpec" }, + { 133, "End-to-end composed value for C" }, + { 134, "End-to-end composed value for D" }, + { 135, "Since-last-reshaping point composed C" }, + { 136, "Since-last-reshaping point composed D" }, + { 0, NULL} +}; + +static struct tok rsvp_session_attribute_flag_values[] = { + { 0x01, "Local Protection" }, + { 0x02, "Label Recording" }, + { 0x04, "SE Style" }, + { 0x08, "Bandwidth protection" }, /* RFC4090 */ + { 0x10, "Node protection" }, /* RFC4090 */ + { 0, NULL} +}; + +static struct tok rsvp_obj_prop_tlv_values[] = { + { 0x01, "Cos" }, + { 0x02, "Metric 1" }, + { 0x04, "Metric 2" }, + { 0x08, "CCC Status" }, + { 0x10, "Path Type" }, + { 0, NULL} +}; + +#define RSVP_OBJ_ERROR_SPEC_CODE_ROUTING 24 +#define RSVP_OBJ_ERROR_SPEC_CODE_NOTIFY 25 +#define RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE 28 +#define RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD 125 + +static struct tok rsvp_obj_error_code_values[] = { + { RSVP_OBJ_ERROR_SPEC_CODE_ROUTING, "Routing Problem" }, + { RSVP_OBJ_ERROR_SPEC_CODE_NOTIFY, "Notify Error" }, + { RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE, "Diffserv TE Error" }, + { RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD, "Diffserv TE Error (Old)" }, + { 0, NULL} +}; + +static struct tok rsvp_obj_error_code_routing_values[] = { + { 1, "Bad EXPLICIT_ROUTE object" }, + { 2, "Bad strict node" }, + { 3, "Bad loose node" }, + { 4, "Bad initial subobject" }, + { 5, "No route available toward destination" }, + { 6, "Unacceptable label value" }, + { 7, "RRO indicated routing loops" }, + { 8, "non-RSVP-capable router in the path" }, + { 9, "MPLS label allocation failure" }, + { 10, "Unsupported L3PID" }, + { 0, NULL} +}; + +static struct tok rsvp_obj_error_code_diffserv_te_values[] = { + { 1, "Unexpected CT object" }, + { 2, "Unsupported CT" }, + { 3, "Invalid CT value" }, + { 4, "CT/setup priority do not form a configured TE-Class" }, + { 5, "CT/holding priority do not form a configured TE-Class" }, + { 6, "CT/setup priority and CT/holding priority do not form a configured TE-Class" }, + { 7, "Inconsistency between signaled PSC and signaled CT" }, + { 8, "Inconsistency between signaled PHBs and signaled CT" }, + { 0, NULL} +}; + +/* rfc3473 / rfc 3471 */ +static const struct tok rsvp_obj_admin_status_flag_values[] = { + { 0x80000000, "Reflect" }, + { 0x00000004, "Testing" }, + { 0x00000002, "Admin-down" }, + { 0x00000001, "Delete-in-progress" }, + { 0, NULL} +}; + +/* label set actions - rfc3471 */ +#define LABEL_SET_INCLUSIVE_LIST 0 +#define LABEL_SET_EXCLUSIVE_LIST 1 +#define LABEL_SET_INCLUSIVE_RANGE 2 +#define LABEL_SET_EXCLUSIVE_RANGE 3 + +static const struct tok rsvp_obj_label_set_action_values[] = { + { LABEL_SET_INCLUSIVE_LIST, "Inclusive list" }, + { LABEL_SET_EXCLUSIVE_LIST, "Exclusive list" }, + { LABEL_SET_INCLUSIVE_RANGE, "Inclusive range" }, + { LABEL_SET_EXCLUSIVE_RANGE, "Exclusive range" }, + { 0, NULL} +}; + +/* OIF RSVP extensions UNI 1.0 Signaling, release 2 */ +#define RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS 1 +#define RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS 2 +#define RSVP_GEN_UNI_SUBOBJ_DIVERSITY 3 +#define RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL 4 +#define RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL 5 + +static const struct tok rsvp_obj_generalized_uni_values[] = { + { RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS, "Source TNA address" }, + { RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS, "Destination TNA address" }, + { RSVP_GEN_UNI_SUBOBJ_DIVERSITY, "Diversity" }, + { RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL, "Egress label" }, + { RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL, "Service level" }, + { 0, NULL} +}; + +static int rsvp_intserv_print(const u_char *, u_short); + +/* + * this is a dissector for all the intserv defined + * specs as defined per rfc2215 + * it is called from various rsvp objects; + * returns the amount of bytes being processed + */ +static int +rsvp_intserv_print(const u_char *tptr, u_short obj_tlen) { + + int parameter_id,parameter_length; + union { + float f; + u_int32_t i; + } bw; + + if (obj_tlen < 4) + return 0; + parameter_id = *(tptr); + parameter_length = EXTRACT_16BITS(tptr+2)<<2; /* convert wordcount to bytecount */ + + printf("\n\t Parameter ID: %s (%u), length: %u, Flags: [0x%02x]", + tok2str(rsvp_intserv_parameter_id_values,"unknown",parameter_id), + parameter_id, + parameter_length, + *(tptr+1)); + + if (obj_tlen < parameter_length+4) + return 0; + switch(parameter_id) { /* parameter_id */ + + case 4: + /* + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 4 (e) | (f) | 1 (g) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IS hop cnt (32-bit unsigned integer) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (parameter_length == 4) + printf("\n\t\tIS hop count: %u", EXTRACT_32BITS(tptr+4)); + break; + + case 6: + /* + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 6 (h) | (i) | 1 (j) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Path b/w estimate (32-bit IEEE floating point number) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (parameter_length == 4) { + bw.i = EXTRACT_32BITS(tptr+4); + printf("\n\t\tPath b/w estimate: %.10g Mbps", bw.f/125000); + } + break; + + case 8: + /* + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 8 (k) | (l) | 1 (m) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Minimum path latency (32-bit integer) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (parameter_length == 4) { + printf("\n\t\tMinimum path latency: "); + if (EXTRACT_32BITS(tptr+4) == 0xffffffff) + printf("don't care"); + else + printf("%u", EXTRACT_32BITS(tptr+4)); + } + break; + + case 10: + + /* + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 10 (n) | (o) | 1 (p) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Composed MTU (32-bit unsigned integer) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (parameter_length == 4) + printf("\n\t\tComposed MTU: %u bytes", EXTRACT_32BITS(tptr+4)); + break; + case 127: + /* + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 127 (e) | 0 (f) | 5 (g) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Token Bucket Rate [r] (32-bit IEEE floating point number) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Token Bucket Size [b] (32-bit IEEE floating point number) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Peak Data Rate [p] (32-bit IEEE floating point number) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Minimum Policed Unit [m] (32-bit integer) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Maximum Packet Size [M] (32-bit integer) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + if (parameter_length == 20) { + bw.i = EXTRACT_32BITS(tptr+4); + printf("\n\t\tToken Bucket Rate: %.10g Mbps", bw.f/125000); + bw.i = EXTRACT_32BITS(tptr+8); + printf("\n\t\tToken Bucket Size: %.10g bytes", bw.f); + bw.i = EXTRACT_32BITS(tptr+12); + printf("\n\t\tPeak Data Rate: %.10g Mbps", bw.f/125000); + printf("\n\t\tMinimum Policed Unit: %u bytes", EXTRACT_32BITS(tptr+16)); + printf("\n\t\tMaximum Packet Size: %u bytes", EXTRACT_32BITS(tptr+20)); + } + break; + + case 130: + /* + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 130 (h) | 0 (i) | 2 (j) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Rate [R] (32-bit IEEE floating point number) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Slack Term [S] (32-bit integer) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + if (parameter_length == 8) { + bw.i = EXTRACT_32BITS(tptr+4); + printf("\n\t\tRate: %.10g Mbps", bw.f/125000); + printf("\n\t\tSlack Term: %u", EXTRACT_32BITS(tptr+8)); + } + break; + + case 133: + case 134: + case 135: + case 136: + if (parameter_length == 4) + printf("\n\t\tValue: %u", EXTRACT_32BITS(tptr+4)); + break; + + default: + if (vflag <= 1) + print_unknown_data(tptr+4,"\n\t\t",parameter_length); + } + return (parameter_length+4); /* header length 4 bytes */ +} + +static int +rsvp_obj_print (const u_char *pptr +#ifndef HAVE_LIBCRYPTO +_U_ +#endif +, u_int plen +#ifndef HAVE_LIBCRYPTO +_U_ +#endif +, const u_char *tptr, + const char *ident, u_int tlen) { + + const struct rsvp_object_header *rsvp_obj_header; + const u_char *obj_tptr; + union { + const struct rsvp_obj_integrity_t *rsvp_obj_integrity; + const struct rsvp_obj_frr_t *rsvp_obj_frr; + } obj_ptr; + + u_short rsvp_obj_len,rsvp_obj_ctype,obj_tlen,intserv_serv_tlen; + int hexdump,processed,padbytes,error_code,error_value,i,sigcheck; + union { + float f; + u_int32_t i; + } bw; + u_int8_t namelen; + + u_int action, subchannel; + + while(tlen>=sizeof(struct rsvp_object_header)) { + /* did we capture enough for fully decoding the object header ? */ + if (!TTEST2(*tptr, sizeof(struct rsvp_object_header))) + goto trunc; + + rsvp_obj_header = (const struct rsvp_object_header *)tptr; + rsvp_obj_len=EXTRACT_16BITS(rsvp_obj_header->length); + rsvp_obj_ctype=rsvp_obj_header->ctype; + + if(rsvp_obj_len % 4) { + printf("%sERROR: object header size %u not a multiple of 4", ident, rsvp_obj_len); + return -1; + } + if(rsvp_obj_len < sizeof(struct rsvp_object_header)) { + printf("%sERROR: object header too short %u < %lu", ident, rsvp_obj_len, + (unsigned long)sizeof(const struct rsvp_object_header)); + return -1; + } + + printf("%s%s Object (%u) Flags: [%s", + ident, + tok2str(rsvp_obj_values, + "Unknown", + rsvp_obj_header->class_num), + rsvp_obj_header->class_num, + ((rsvp_obj_header->class_num)&0x80) ? "ignore" : "reject"); + + if (rsvp_obj_header->class_num > 128) + printf(" %s", + ((rsvp_obj_header->class_num)&0x40) ? "and forward" : "silently"); + + printf(" if unknown], Class-Type: %s (%u), length: %u", + tok2str(rsvp_ctype_values, + "Unknown", + ((rsvp_obj_header->class_num)<<8)+rsvp_obj_ctype), + rsvp_obj_ctype, + rsvp_obj_len); + + if(tlen < rsvp_obj_len) { + printf("%sERROR: object goes past end of objects TLV", ident); + return -1; + } + + obj_tptr=tptr+sizeof(struct rsvp_object_header); + obj_tlen=rsvp_obj_len-sizeof(struct rsvp_object_header); + + /* did we capture enough for fully decoding the object ? */ + if (!TTEST2(*tptr, rsvp_obj_len)) + return -1; + hexdump=FALSE; + + switch(rsvp_obj_header->class_num) { + case RSVP_OBJ_SESSION: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + if (obj_tlen < 8) + return -1; + printf("%s IPv4 DestAddress: %s, Protocol ID: 0x%02x", + ident, + ipaddr_string(obj_tptr), + *(obj_tptr+sizeof(struct in_addr))); + printf("%s Flags: [0x%02x], DestPort %u", + ident, + *(obj_tptr+5), + EXTRACT_16BITS(obj_tptr+6)); + obj_tlen-=8; + obj_tptr+=8; + break; +#ifdef INET6 + case RSVP_CTYPE_IPV6: + if (obj_tlen < 20) + return -1; + printf("%s IPv6 DestAddress: %s, Protocol ID: 0x%02x", + ident, + ip6addr_string(obj_tptr), + *(obj_tptr+sizeof(struct in6_addr))); + printf("%s Flags: [0x%02x], DestPort %u", + ident, + *(obj_tptr+sizeof(struct in6_addr)+1), + EXTRACT_16BITS(obj_tptr+sizeof(struct in6_addr)+2)); + obj_tlen-=20; + obj_tptr+=20; + break; + + case RSVP_CTYPE_TUNNEL_IPV6: + if (obj_tlen < 36) + return -1; + printf("%s IPv6 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", + ident, + ip6addr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+18), + ip6addr_string(obj_tptr+20)); + obj_tlen-=36; + obj_tptr+=36; + break; + + case RSVP_CTYPE_14: /* IPv6 p2mp LSP Tunnel */ + if (obj_tlen < 26) + return -1; + printf("%s IPv6 P2MP LSP ID: 0x%08x, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", + ident, + EXTRACT_32BITS(obj_tptr), + EXTRACT_16BITS(obj_tptr+6), + ip6addr_string(obj_tptr+8)); + obj_tlen-=26; + obj_tptr+=26; + break; +#endif + case RSVP_CTYPE_13: /* IPv4 p2mp LSP Tunnel */ + if (obj_tlen < 12) + return -1; + printf("%s IPv4 P2MP LSP ID: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6), + ipaddr_string(obj_tptr+8)); + obj_tlen-=12; + obj_tptr+=12; + break; + case RSVP_CTYPE_TUNNEL_IPV4: + case RSVP_CTYPE_UNI_IPV4: + if (obj_tlen < 12) + return -1; + printf("%s IPv4 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6), + ipaddr_string(obj_tptr+8)); + obj_tlen-=12; + obj_tptr+=12; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_CONFIRM: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + if (obj_tlen < sizeof(struct in_addr)) + return -1; + printf("%s IPv4 Receiver Address: %s", + ident, + ipaddr_string(obj_tptr)); + obj_tlen-=sizeof(struct in_addr); + obj_tptr+=sizeof(struct in_addr); + break; +#ifdef INET6 + case RSVP_CTYPE_IPV6: + if (obj_tlen < sizeof(struct in6_addr)) + return -1; + printf("%s IPv6 Receiver Address: %s", + ident, + ip6addr_string(obj_tptr)); + obj_tlen-=sizeof(struct in6_addr); + obj_tptr+=sizeof(struct in6_addr); + break; +#endif + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_NOTIFY_REQ: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + if (obj_tlen < sizeof(struct in_addr)) + return -1; + printf("%s IPv4 Notify Node Address: %s", + ident, + ipaddr_string(obj_tptr)); + obj_tlen-=sizeof(struct in_addr); + obj_tptr+=sizeof(struct in_addr); + break; +#ifdef INET6 + case RSVP_CTYPE_IPV6: + if (obj_tlen < sizeof(struct in6_addr)) + return-1; + printf("%s IPv6 Notify Node Address: %s", + ident, + ip6addr_string(obj_tptr)); + obj_tlen-=sizeof(struct in6_addr); + obj_tptr+=sizeof(struct in6_addr); + break; +#endif + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_SUGGESTED_LABEL: /* fall through */ + case RSVP_OBJ_UPSTREAM_LABEL: /* fall through */ + case RSVP_OBJ_RECOVERY_LABEL: /* fall through */ + case RSVP_OBJ_LABEL: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + while(obj_tlen >= 4 ) { + printf("%s Label: %u", ident, EXTRACT_32BITS(obj_tptr)); + obj_tlen-=4; + obj_tptr+=4; + } + break; + case RSVP_CTYPE_2: + if (obj_tlen < 4) + return-1; + printf("%s Generalized Label: %u", + ident, + EXTRACT_32BITS(obj_tptr)); + obj_tlen-=4; + obj_tptr+=4; + break; + case RSVP_CTYPE_3: + if (obj_tlen < 12) + return-1; + printf("%s Waveband ID: %u%s Start Label: %u, Stop Label: %u", + ident, + EXTRACT_32BITS(obj_tptr), + ident, + EXTRACT_32BITS(obj_tptr+4), + EXTRACT_32BITS(obj_tptr+8)); + obj_tlen-=12; + obj_tptr+=12; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_STYLE: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < 4) + return-1; + printf("%s Reservation Style: %s, Flags: [0x%02x]", + ident, + tok2str(rsvp_resstyle_values, + "Unknown", + EXTRACT_24BITS(obj_tptr+1)), + *(obj_tptr)); + obj_tlen-=4; + obj_tptr+=4; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_SENDER_TEMPLATE: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + if (obj_tlen < 8) + return-1; + printf("%s Source Address: %s, Source Port: %u", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6)); + obj_tlen-=8; + obj_tptr+=8; + break; +#ifdef INET6 + case RSVP_CTYPE_IPV6: + if (obj_tlen < 20) + return-1; + printf("%s Source Address: %s, Source Port: %u", + ident, + ip6addr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+18)); + obj_tlen-=20; + obj_tptr+=20; + break; + case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */ + if (obj_tlen < 40) + return-1; + printf("%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x" + "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", + ident, + ip6addr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+18), + ident, + ip6addr_string(obj_tptr+20), + EXTRACT_16BITS(obj_tptr+38)); + obj_tlen-=40; + obj_tptr+=40; + break; +#endif + case RSVP_CTYPE_TUNNEL_IPV4: + if (obj_tlen < 8) + return-1; + printf("%s IPv4 Tunnel Sender Address: %s, LSP-ID: 0x%04x", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6)); + obj_tlen-=8; + obj_tptr+=8; + break; + case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */ + if (obj_tlen < 16) + return-1; + printf("%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x" + "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6), + ident, + ipaddr_string(obj_tptr+8), + EXTRACT_16BITS(obj_tptr+12)); + obj_tlen-=16; + obj_tptr+=16; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_LABEL_REQ: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + while(obj_tlen >= 4 ) { + printf("%s L3 Protocol ID: %s", + ident, + tok2str(ethertype_values, + "Unknown Protocol (0x%04x)", + EXTRACT_16BITS(obj_tptr+2))); + obj_tlen-=4; + obj_tptr+=4; + } + break; + case RSVP_CTYPE_2: + if (obj_tlen < 12) + return-1; + printf("%s L3 Protocol ID: %s", + ident, + tok2str(ethertype_values, + "Unknown Protocol (0x%04x)", + EXTRACT_16BITS(obj_tptr+2))); + printf(",%s merge capability",((*(obj_tptr+4))&0x80) ? "no" : "" ); + printf("%s Minimum VPI/VCI: %u/%u", + ident, + (EXTRACT_16BITS(obj_tptr+4))&0xfff, + (EXTRACT_16BITS(obj_tptr+6))&0xfff); + printf("%s Maximum VPI/VCI: %u/%u", + ident, + (EXTRACT_16BITS(obj_tptr+8))&0xfff, + (EXTRACT_16BITS(obj_tptr+10))&0xfff); + obj_tlen-=12; + obj_tptr+=12; + break; + case RSVP_CTYPE_3: + if (obj_tlen < 12) + return-1; + printf("%s L3 Protocol ID: %s", + ident, + tok2str(ethertype_values, + "Unknown Protocol (0x%04x)", + EXTRACT_16BITS(obj_tptr+2))); + printf("%s Minimum/Maximum DLCI: %u/%u, %s%s bit DLCI", + ident, + (EXTRACT_32BITS(obj_tptr+4))&0x7fffff, + (EXTRACT_32BITS(obj_tptr+8))&0x7fffff, + (((EXTRACT_16BITS(obj_tptr+4)>>7)&3) == 0 ) ? "10" : "", + (((EXTRACT_16BITS(obj_tptr+4)>>7)&3) == 2 ) ? "23" : ""); + obj_tlen-=12; + obj_tptr+=12; + break; + case RSVP_CTYPE_4: + if (obj_tlen < 4) + return-1; + printf("%s LSP Encoding Type: %s (%u)", + ident, + tok2str(gmpls_encoding_values, + "Unknown", + *obj_tptr), + *obj_tptr); + printf("%s Switching Type: %s (%u), Payload ID: %s (0x%04x)", + ident, + tok2str(gmpls_switch_cap_values, + "Unknown", + *(obj_tptr+1)), + *(obj_tptr+1), + tok2str(gmpls_payload_values, + "Unknown", + EXTRACT_16BITS(obj_tptr+2)), + EXTRACT_16BITS(obj_tptr+2)); + obj_tlen-=4; + obj_tptr+=4; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_RRO: + case RSVP_OBJ_ERO: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + while(obj_tlen >= 4 ) { + printf("%s Subobject Type: %s, length %u", + ident, + tok2str(rsvp_obj_xro_values, + "Unknown %u", + RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)), + *(obj_tptr+1)); + + if (*(obj_tptr+1) == 0) { /* prevent infinite loops */ + printf("%s ERROR: zero length ERO subtype",ident); + break; + } + + switch(RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)) { + case RSVP_OBJ_XRO_IPV4: + printf(", %s, %s/%u, Flags: [%s]", + RSVP_OBJ_XRO_MASK_LOOSE(*obj_tptr) ? "Loose" : "Strict", + ipaddr_string(obj_tptr+2), + *(obj_tptr+6), + bittok2str(rsvp_obj_rro_flag_values, + "none", + *(obj_tptr+7))); /* rfc3209 says that this field is rsvd. */ + break; + case RSVP_OBJ_XRO_LABEL: + printf(", Flags: [%s] (%#x), Class-Type: %s (%u), %u", + bittok2str(rsvp_obj_rro_label_flag_values, + "none", + *(obj_tptr+2)), + *(obj_tptr+2), + tok2str(rsvp_ctype_values, + "Unknown", + *(obj_tptr+3) + 256*RSVP_OBJ_RRO), + *(obj_tptr+3), + EXTRACT_32BITS(obj_tptr+4)); + } + obj_tlen-=*(obj_tptr+1); + obj_tptr+=*(obj_tptr+1); + } + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_HELLO: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + case RSVP_CTYPE_2: + if (obj_tlen < 8) + return-1; + printf("%s Source Instance: 0x%08x, Destination Instance: 0x%08x", + ident, + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr+4)); + obj_tlen-=8; + obj_tptr+=8; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_RESTART_CAPABILITY: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < 8) + return-1; + printf("%s Restart Time: %ums, Recovery Time: %ums", + ident, + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr+4)); + obj_tlen-=8; + obj_tptr+=8; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_SESSION_ATTRIBUTE: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_TUNNEL_IPV4: + if (obj_tlen < 4) + return-1; + namelen = *(obj_tptr+3); + if (obj_tlen < 4+namelen) + return-1; + printf("%s Session Name: ", ident); + for (i = 0; i < namelen; i++) + safeputchar(*(obj_tptr+4+i)); + printf("%s Setup Priority: %u, Holding Priority: %u, Flags: [%s] (%#x)", + ident, + (int)*obj_tptr, + (int)*(obj_tptr+1), + bittok2str(rsvp_session_attribute_flag_values, + "none", + *(obj_tptr+2)), + *(obj_tptr+2)); + obj_tlen-=4+*(obj_tptr+3); + obj_tptr+=4+*(obj_tptr+3); + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_GENERALIZED_UNI: + switch(rsvp_obj_ctype) { + int subobj_type,af,subobj_len,total_subobj_len; + + case RSVP_CTYPE_1: + + if (obj_tlen < 4) + return-1; + + /* read variable length subobjects */ + total_subobj_len = obj_tlen; + while(total_subobj_len > 0) { + subobj_len = EXTRACT_16BITS(obj_tptr); + subobj_type = (EXTRACT_16BITS(obj_tptr+2))>>8; + af = (EXTRACT_16BITS(obj_tptr+2))&0x00FF; + + printf("%s Subobject Type: %s (%u), AF: %s (%u), length: %u", + ident, + tok2str(rsvp_obj_generalized_uni_values, "Unknown", subobj_type), + subobj_type, + tok2str(af_values, "Unknown", af), af, + subobj_len); + + switch(subobj_type) { + case RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS: + case RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS: + + switch(af) { + case AFNUM_INET: + if (subobj_len < 8) + return -1; + printf("%s UNI IPv4 TNA address: %s", + ident, ipaddr_string(obj_tptr+4)); + break; +#ifdef INET6 + case AFNUM_INET6: + if (subobj_len < 20) + return -1; + printf("%s UNI IPv6 TNA address: %s", + ident, ip6addr_string(obj_tptr+4)); + break; +#endif + case AFNUM_NSAP: + if (subobj_len) { + /* unless we have a TLV parser lets just hexdump */ + hexdump=TRUE; + } + break; + } + break; + + case RSVP_GEN_UNI_SUBOBJ_DIVERSITY: + if (subobj_len) { + /* unless we have a TLV parser lets just hexdump */ + hexdump=TRUE; + } + break; + + case RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL: + if (subobj_len < 16) { + return -1; + } + + printf("%s U-bit: %x, Label type: %u, Logical port id: %u, Label: %u", + ident, + ((EXTRACT_32BITS(obj_tptr+4))>>31), + ((EXTRACT_32BITS(obj_tptr+4))&0xFF), + EXTRACT_32BITS(obj_tptr+8), + EXTRACT_32BITS(obj_tptr+12)); + break; + + case RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL: + if (subobj_len < 8) { + return -1; + } + + printf("%s Service level: %u", + ident, (EXTRACT_32BITS(obj_tptr+4))>>24); + break; + + default: + hexdump=TRUE; + break; + } + total_subobj_len-=subobj_len; + obj_tptr+=subobj_len; + obj_tlen+=subobj_len; + } + + if (total_subobj_len) { + /* unless we have a TLV parser lets just hexdump */ + hexdump=TRUE; + } + break; + + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_RSVP_HOP: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */ + case RSVP_CTYPE_IPV4: + if (obj_tlen < 8) + return-1; + printf("%s Previous/Next Interface: %s, Logical Interface Handle: 0x%08x", + ident, + ipaddr_string(obj_tptr), + EXTRACT_32BITS(obj_tptr+4)); + obj_tlen-=8; + obj_tptr+=8; + if (obj_tlen) + hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */ + break; +#ifdef INET6 + case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */ + case RSVP_CTYPE_IPV6: + if (obj_tlen < 20) + return-1; + printf("%s Previous/Next Interface: %s, Logical Interface Handle: 0x%08x", + ident, + ip6addr_string(obj_tptr), + EXTRACT_32BITS(obj_tptr+16)); + obj_tlen-=20; + obj_tptr+=20; + hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */ + break; +#endif + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_TIME_VALUES: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < 4) + return-1; + printf("%s Refresh Period: %ums", + ident, + EXTRACT_32BITS(obj_tptr)); + obj_tlen-=4; + obj_tptr+=4; + break; + default: + hexdump=TRUE; + } + break; + + /* those three objects do share the same semantics */ + case RSVP_OBJ_SENDER_TSPEC: + case RSVP_OBJ_ADSPEC: + case RSVP_OBJ_FLOWSPEC: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_2: + if (obj_tlen < 4) + return-1; + printf("%s Msg-Version: %u, length: %u", + ident, + (*obj_tptr & 0xf0) >> 4, + EXTRACT_16BITS(obj_tptr+2)<<2); + obj_tptr+=4; /* get to the start of the service header */ + obj_tlen-=4; + + while (obj_tlen >= 4) { + intserv_serv_tlen=EXTRACT_16BITS(obj_tptr+2)<<2; + printf("%s Service Type: %s (%u), break bit %s set, Service length: %u", + ident, + tok2str(rsvp_intserv_service_type_values,"unknown",*(obj_tptr)), + *(obj_tptr), + (*(obj_tptr+1)&0x80) ? "" : "not", + intserv_serv_tlen); + + obj_tptr+=4; /* get to the start of the parameter list */ + obj_tlen-=4; + + while (intserv_serv_tlen>=4) { + processed = rsvp_intserv_print(obj_tptr, obj_tlen); + if (processed == 0) + break; + obj_tlen-=processed; + intserv_serv_tlen-=processed; + obj_tptr+=processed; + } + } + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_FILTERSPEC: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + if (obj_tlen < 8) + return-1; + printf("%s Source Address: %s, Source Port: %u", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6)); + obj_tlen-=8; + obj_tptr+=8; + break; +#ifdef INET6 + case RSVP_CTYPE_IPV6: + if (obj_tlen < 20) + return-1; + printf("%s Source Address: %s, Source Port: %u", + ident, + ip6addr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+18)); + obj_tlen-=20; + obj_tptr+=20; + break; + case RSVP_CTYPE_3: + if (obj_tlen < 20) + return-1; + printf("%s Source Address: %s, Flow Label: %u", + ident, + ip6addr_string(obj_tptr), + EXTRACT_24BITS(obj_tptr+17)); + obj_tlen-=20; + obj_tptr+=20; + break; + case RSVP_CTYPE_TUNNEL_IPV6: + if (obj_tlen < 20) + return-1; + printf("%s Source Address: %s, LSP-ID: 0x%04x", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+18)); + obj_tlen-=20; + obj_tptr+=20; + break; + case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */ + if (obj_tlen < 40) + return-1; + printf("%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x" + "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", + ident, + ip6addr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+18), + ident, + ip6addr_string(obj_tptr+20), + EXTRACT_16BITS(obj_tptr+38)); + obj_tlen-=40; + obj_tptr+=40; + break; +#endif + case RSVP_CTYPE_TUNNEL_IPV4: + if (obj_tlen < 8) + return-1; + printf("%s Source Address: %s, LSP-ID: 0x%04x", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6)); + obj_tlen-=8; + obj_tptr+=8; + break; + case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */ + if (obj_tlen < 16) + return-1; + printf("%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x" + "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x", + ident, + ipaddr_string(obj_tptr), + EXTRACT_16BITS(obj_tptr+6), + ident, + ipaddr_string(obj_tptr+8), + EXTRACT_16BITS(obj_tptr+12)); + obj_tlen-=16; + obj_tptr+=16; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_FASTREROUTE: + /* the differences between c-type 1 and 7 are minor */ + obj_ptr.rsvp_obj_frr = (const struct rsvp_obj_frr_t *)obj_tptr; + bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth); + + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: /* new style */ + if (obj_tlen < sizeof(struct rsvp_obj_frr_t)) + return-1; + printf("%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps", + ident, + (int)obj_ptr.rsvp_obj_frr->setup_prio, + (int)obj_ptr.rsvp_obj_frr->hold_prio, + (int)obj_ptr.rsvp_obj_frr->hop_limit, + bw.f*8/1000000); + printf("%s Include-any: 0x%08x, Exclude-any: 0x%08x, Include-all: 0x%08x", + ident, + EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any), + EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any), + EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_all)); + obj_tlen-=sizeof(struct rsvp_obj_frr_t); + obj_tptr+=sizeof(struct rsvp_obj_frr_t); + break; + + case RSVP_CTYPE_TUNNEL_IPV4: /* old style */ + if (obj_tlen < 16) + return-1; + printf("%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps", + ident, + (int)obj_ptr.rsvp_obj_frr->setup_prio, + (int)obj_ptr.rsvp_obj_frr->hold_prio, + (int)obj_ptr.rsvp_obj_frr->hop_limit, + bw.f*8/1000000); + printf("%s Include Colors: 0x%08x, Exclude Colors: 0x%08x", + ident, + EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any), + EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any)); + obj_tlen-=16; + obj_tptr+=16; + break; + + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_DETOUR: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_TUNNEL_IPV4: + while(obj_tlen >= 8) { + printf("%s PLR-ID: %s, Avoid-Node-ID: %s", + ident, + ipaddr_string(obj_tptr), + ipaddr_string(obj_tptr+4)); + obj_tlen-=8; + obj_tptr+=8; + } + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_CLASSTYPE: + case RSVP_OBJ_CLASSTYPE_OLD: /* fall through */ + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + printf("%s CT: %u", + ident, + EXTRACT_32BITS(obj_tptr)&0x7); + obj_tlen-=4; + obj_tptr+=4; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_ERROR_SPEC: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */ + case RSVP_CTYPE_IPV4: + if (obj_tlen < 8) + return-1; + error_code=*(obj_tptr+5); + error_value=EXTRACT_16BITS(obj_tptr+6); + printf("%s Error Node Address: %s, Flags: [0x%02x]%s Error Code: %s (%u)", + ident, + ipaddr_string(obj_tptr), + *(obj_tptr+4), + ident, + tok2str(rsvp_obj_error_code_values,"unknown",error_code), + error_code); + switch (error_code) { + case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING: + printf(", Error Value: %s (%u)", + tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value), + error_value); + break; + case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE: /* fall through */ + case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD: + printf(", Error Value: %s (%u)", + tok2str(rsvp_obj_error_code_diffserv_te_values,"unknown",error_value), + error_value); + break; + default: + printf(", Unknown Error Value (%u)", error_value); + break; + } + obj_tlen-=8; + obj_tptr+=8; + break; +#ifdef INET6 + case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */ + case RSVP_CTYPE_IPV6: + if (obj_tlen < 20) + return-1; + error_code=*(obj_tptr+17); + error_value=EXTRACT_16BITS(obj_tptr+18); + printf("%s Error Node Address: %s, Flags: [0x%02x]%s Error Code: %s (%u)", + ident, + ip6addr_string(obj_tptr), + *(obj_tptr+16), + ident, + tok2str(rsvp_obj_error_code_values,"unknown",error_code), + error_code); + + switch (error_code) { + case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING: + printf(", Error Value: %s (%u)", + tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value), + error_value); + break; + default: + break; + } + obj_tlen-=20; + obj_tptr+=20; + break; +#endif + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_PROPERTIES: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < 4) + return-1; + padbytes = EXTRACT_16BITS(obj_tptr+2); + printf("%s TLV count: %u, padding bytes: %u", + ident, + EXTRACT_16BITS(obj_tptr), + padbytes); + obj_tlen-=4; + obj_tptr+=4; + /* loop through as long there is anything longer than the TLV header (2) */ + while(obj_tlen >= 2 + padbytes) { + printf("%s %s TLV (0x%02x), length: %u", /* length includes header */ + ident, + tok2str(rsvp_obj_prop_tlv_values,"unknown",*obj_tptr), + *obj_tptr, + *(obj_tptr+1)); + if (obj_tlen < *(obj_tptr+1)) + return-1; + if (*(obj_tptr+1) < 2) + return -1; + print_unknown_data(obj_tptr+2,"\n\t\t",*(obj_tptr+1)-2); + obj_tlen-=*(obj_tptr+1); + obj_tptr+=*(obj_tptr+1); + } + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_MESSAGE_ID: /* fall through */ + case RSVP_OBJ_MESSAGE_ID_ACK: /* fall through */ + case RSVP_OBJ_MESSAGE_ID_LIST: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + case RSVP_CTYPE_2: + if (obj_tlen < 8) + return-1; + printf("%s Flags [0x%02x], epoch: %u", + ident, + *obj_tptr, + EXTRACT_24BITS(obj_tptr+1)); + obj_tlen-=4; + obj_tptr+=4; + /* loop through as long there are no messages left */ + while(obj_tlen >= 4) { + printf("%s Message-ID 0x%08x (%u)", + ident, + EXTRACT_32BITS(obj_tptr), + EXTRACT_32BITS(obj_tptr)); + obj_tlen-=4; + obj_tptr+=4; + } + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_INTEGRITY: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < sizeof(struct rsvp_obj_integrity_t)) + return-1; + obj_ptr.rsvp_obj_integrity = (const struct rsvp_obj_integrity_t *)obj_tptr; + printf("%s Key-ID 0x%04x%08x, Sequence 0x%08x%08x, Flags [%s]", + ident, + EXTRACT_16BITS(obj_ptr.rsvp_obj_integrity->key_id), + EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->key_id+2), + EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence), + EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence+4), + bittok2str(rsvp_obj_integrity_flag_values, + "none", + obj_ptr.rsvp_obj_integrity->flags)); + printf("%s MD5-sum 0x%08x%08x%08x%08x ", + ident, + EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest), + EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+4), + EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+8), + EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+12)); + +#ifdef HAVE_LIBCRYPTO + sigcheck = signature_verify(pptr, plen, (unsigned char *)obj_ptr.\ + rsvp_obj_integrity->digest); +#else + sigcheck = CANT_CHECK_SIGNATURE; +#endif + printf(" (%s)", tok2str(signature_check_values, "Unknown", sigcheck)); + + obj_tlen+=sizeof(struct rsvp_obj_integrity_t); + obj_tptr+=sizeof(struct rsvp_obj_integrity_t); + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_ADMIN_STATUS: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < 4) + return-1; + printf("%s Flags [%s]", ident, + bittok2str(rsvp_obj_admin_status_flag_values, "none", + EXTRACT_32BITS(obj_tptr))); + obj_tlen-=4; + obj_tptr+=4; + break; + default: + hexdump=TRUE; + } + break; + + case RSVP_OBJ_LABEL_SET: + switch(rsvp_obj_ctype) { + case RSVP_CTYPE_1: + if (obj_tlen < 4) + return-1; + action = (EXTRACT_16BITS(obj_tptr)>>8); + + printf("%s Action: %s (%u), Label type: %u", ident, + tok2str(rsvp_obj_label_set_action_values, "Unknown", action), + action, ((EXTRACT_32BITS(obj_tptr) & 0x7F))); + + switch (action) { + case LABEL_SET_INCLUSIVE_RANGE: + case LABEL_SET_EXCLUSIVE_RANGE: /* fall through */ + + /* only a couple of subchannels are expected */ + if (obj_tlen < 12) + return -1; + printf("%s Start range: %u, End range: %u", ident, + EXTRACT_32BITS(obj_tptr+4), + EXTRACT_32BITS(obj_tptr+8)); + obj_tlen-=12; + obj_tptr+=12; + break; + + default: + obj_tlen-=4; + obj_tptr+=4; + subchannel = 1; + while(obj_tlen >= 4 ) { + printf("%s Subchannel #%u: %u", ident, subchannel, + EXTRACT_32BITS(obj_tptr)); + obj_tptr+=4; + obj_tlen-=4; + subchannel++; + } + break; + } + break; + default: + hexdump=TRUE; + } + + case RSVP_OBJ_S2L: + switch (rsvp_obj_ctype) { + case RSVP_CTYPE_IPV4: + if (obj_tlen < 4) + return-1; + printf("%s Sub-LSP destination address: %s", + ident, ipaddr_string(obj_tptr)); + + obj_tlen-=4; + obj_tptr+=4; + break; +#ifdef INET6 + case RSVP_CTYPE_IPV6: + if (obj_tlen < 16) + return-1; + printf("%s Sub-LSP destination address: %s", + ident, ip6addr_string(obj_tptr)); + + obj_tlen-=16; + obj_tptr+=16; + break; +#endif + default: + hexdump=TRUE; + } + + /* + * FIXME those are the defined objects that lack a decoder + * you are welcome to contribute code ;-) + */ + + case RSVP_OBJ_SCOPE: + case RSVP_OBJ_POLICY_DATA: + case RSVP_OBJ_ACCEPT_LABEL_SET: + case RSVP_OBJ_PROTECTION: + default: + if (vflag <= 1) + print_unknown_data(obj_tptr,"\n\t ",obj_tlen); /* FIXME indentation */ + break; + } + /* do we also want to see a hex dump ? */ + if (vflag > 1 || hexdump==TRUE) + print_unknown_data(tptr+sizeof(sizeof(struct rsvp_object_header)),"\n\t ", /* FIXME indentation */ + rsvp_obj_len-sizeof(struct rsvp_object_header)); + + tptr+=rsvp_obj_len; + tlen-=rsvp_obj_len; + } + return 0; +trunc: + printf("\n\t\t packet exceeded snapshot"); + return -1; +} + + +void +rsvp_print(register const u_char *pptr, register u_int len) { + + struct rsvp_common_header *rsvp_com_header; + const u_char *tptr,*subtptr; + u_short plen, tlen, subtlen; + + tptr=pptr; + + rsvp_com_header = (struct rsvp_common_header *)pptr; + TCHECK(*rsvp_com_header); + + /* + * Sanity checking of the header. + */ + if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) { + printf("ERROR: RSVP version %u packet not supported", + RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags)); + return; + } + + /* in non-verbose mode just lets print the basic Message Type*/ + if (vflag < 1) { + printf("RSVPv%u %s Message, length: %u", + RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), + tok2str(rsvp_msg_type_values, "unknown (%u)",rsvp_com_header->msg_type), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + + plen = tlen = EXTRACT_16BITS(rsvp_com_header->length); + + printf("\n\tRSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x", + RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), + tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type), + rsvp_com_header->msg_type, + bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)), + tlen, + rsvp_com_header->ttl, + EXTRACT_16BITS(rsvp_com_header->checksum)); + + /* + * Clear checksum prior to signature verification. + */ + rsvp_com_header->checksum[0] = 0; + rsvp_com_header->checksum[1] = 0; + + if (tlen < sizeof(const struct rsvp_common_header)) { + printf("ERROR: common header too short %u < %lu", tlen, + (unsigned long)sizeof(const struct rsvp_common_header)); + return; + } + + tptr+=sizeof(const struct rsvp_common_header); + tlen-=sizeof(const struct rsvp_common_header); + + switch(rsvp_com_header->msg_type) { + + case RSVP_MSGTYPE_AGGREGATE: + while(tlen > 0) { + subtptr=tptr; + rsvp_com_header = (struct rsvp_common_header *)subtptr; + TCHECK(*rsvp_com_header); + + /* + * Sanity checking of the header. + */ + if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) { + printf("ERROR: RSVP version %u packet not supported", + RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags)); + return; + } + subtlen=EXTRACT_16BITS(rsvp_com_header->length); + + printf("\n\t RSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x", + RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags), + tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type), + rsvp_com_header->msg_type, + bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)), + subtlen, + rsvp_com_header->ttl, + EXTRACT_16BITS(rsvp_com_header->checksum)); + + /* + * Clear checksum prior to signature verification. + */ + rsvp_com_header->checksum[0] = 0; + rsvp_com_header->checksum[1] = 0; + + if (subtlen < sizeof(const struct rsvp_common_header)) { + printf("ERROR: common header too short %u < %lu", subtlen, + (unsigned long)sizeof(const struct rsvp_common_header)); + return; + } + + if (tlen < subtlen) { + printf("ERROR: common header too large %u > %u", subtlen, + tlen); + return; + } + + subtptr+=sizeof(const struct rsvp_common_header); + subtlen-=sizeof(const struct rsvp_common_header); + + if (rsvp_obj_print(pptr, plen, subtptr,"\n\t ", subtlen) == -1) + return; + + tptr+=subtlen+sizeof(const struct rsvp_common_header); + tlen-=subtlen+sizeof(const struct rsvp_common_header); + } + + break; + + case RSVP_MSGTYPE_PATH: + case RSVP_MSGTYPE_RESV: + case RSVP_MSGTYPE_PATHERR: + case RSVP_MSGTYPE_RESVERR: + case RSVP_MSGTYPE_PATHTEAR: + case RSVP_MSGTYPE_RESVTEAR: + case RSVP_MSGTYPE_RESVCONF: + case RSVP_MSGTYPE_HELLO_OLD: + case RSVP_MSGTYPE_HELLO: + case RSVP_MSGTYPE_ACK: + case RSVP_MSGTYPE_SREFRESH: + if (rsvp_obj_print(pptr, plen, tptr,"\n\t ", tlen) == -1) + return; + break; + + default: + print_unknown_data(tptr,"\n\t ",tlen); + break; + } + + return; +trunc: + printf("\n\t\t packet exceeded snapshot"); +} diff --git a/print-rt6.c b/print-rt6.c new file mode 100644 index 0000000..dc196b4 --- /dev/null +++ b/print-rt6.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-rt6.c,v 1.27 2005-04-20 22:34:57 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef INET6 + +#include + +#include + +#include "ip6.h" + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +int +rt6_print(register const u_char *bp, const u_char *bp2 _U_) +{ + register const struct ip6_rthdr *dp; + register const struct ip6_rthdr0 *dp0; + register const u_char *ep; + int i, len; + register const struct in6_addr *addr; + + dp = (struct ip6_rthdr *)bp; + len = dp->ip6r_len; + + /* 'ep' points to the end of available data. */ + ep = snapend; + + TCHECK(dp->ip6r_segleft); + + printf("srcrt (len=%d", dp->ip6r_len); /*)*/ + printf(", type=%d", dp->ip6r_type); + printf(", segleft=%d", dp->ip6r_segleft); + + switch (dp->ip6r_type) { +#ifndef IPV6_RTHDR_TYPE_0 +#define IPV6_RTHDR_TYPE_0 0 +#endif +#ifndef IPV6_RTHDR_TYPE_2 +#define IPV6_RTHDR_TYPE_2 2 +#endif + case IPV6_RTHDR_TYPE_0: + case IPV6_RTHDR_TYPE_2: /* Mobile IPv6 ID-20 */ + dp0 = (struct ip6_rthdr0 *)dp; + + TCHECK(dp0->ip6r0_reserved); + if (dp0->ip6r0_reserved || vflag) { + printf(", rsv=0x%0x", + EXTRACT_32BITS(&dp0->ip6r0_reserved)); + } + + if (len % 2 == 1) + goto trunc; + len >>= 1; + addr = &dp0->ip6r0_addr[0]; + for (i = 0; i < len; i++) { + if ((u_char *)(addr + 1) > ep) + goto trunc; + + printf(", [%d]%s", i, ip6addr_string(addr)); + addr++; + } + /*(*/ + printf(") "); + return((dp0->ip6r0_len + 1) << 3); + break; + default: + goto trunc; + break; + } + + trunc: + fputs("[|srcrt]", stdout); + return -1; +} +#endif /* INET6 */ diff --git a/print-rx.c b/print-rx.c new file mode 100644 index 0000000..70393ea --- /dev/null +++ b/print-rx.c @@ -0,0 +1,2798 @@ +/* + * Copyright: (c) 2000 United States Government as represented by the + * Secretary of the Navy. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +/* + * This code unmangles RX packets. RX is the mutant form of RPC that AFS + * uses to communicate between clients and servers. + * + * In this code, I mainly concern myself with decoding the AFS calls, not + * with the guts of RX, per se. + * + * Bah. If I never look at rx_packet.h again, it will be too soon. + * + * Ken Hornstein + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-rx.c,v 1.42 2008-07-01 07:44:50 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "rx.h" + +#include "ip.h" + +static struct tok rx_types[] = { + { RX_PACKET_TYPE_DATA, "data" }, + { RX_PACKET_TYPE_ACK, "ack" }, + { RX_PACKET_TYPE_BUSY, "busy" }, + { RX_PACKET_TYPE_ABORT, "abort" }, + { RX_PACKET_TYPE_ACKALL, "ackall" }, + { RX_PACKET_TYPE_CHALLENGE, "challenge" }, + { RX_PACKET_TYPE_RESPONSE, "response" }, + { RX_PACKET_TYPE_DEBUG, "debug" }, + { RX_PACKET_TYPE_PARAMS, "params" }, + { RX_PACKET_TYPE_VERSION, "version" }, + { 0, NULL }, +}; + +static struct double_tok { + int flag; /* Rx flag */ + int packetType; /* Packet type */ + const char *s; /* Flag string */ +} rx_flags[] = { + { RX_CLIENT_INITIATED, 0, "client-init" }, + { RX_REQUEST_ACK, 0, "req-ack" }, + { RX_LAST_PACKET, 0, "last-pckt" }, + { RX_MORE_PACKETS, 0, "more-pckts" }, + { RX_FREE_PACKET, 0, "free-pckt" }, + { RX_SLOW_START_OK, RX_PACKET_TYPE_ACK, "slow-start" }, + { RX_JUMBO_PACKET, RX_PACKET_TYPE_DATA, "jumbogram" } +}; + +static struct tok fs_req[] = { + { 130, "fetch-data" }, + { 131, "fetch-acl" }, + { 132, "fetch-status" }, + { 133, "store-data" }, + { 134, "store-acl" }, + { 135, "store-status" }, + { 136, "remove-file" }, + { 137, "create-file" }, + { 138, "rename" }, + { 139, "symlink" }, + { 140, "link" }, + { 141, "makedir" }, + { 142, "rmdir" }, + { 143, "oldsetlock" }, + { 144, "oldextlock" }, + { 145, "oldrellock" }, + { 146, "get-stats" }, + { 147, "give-cbs" }, + { 148, "get-vlinfo" }, + { 149, "get-vlstats" }, + { 150, "set-vlstats" }, + { 151, "get-rootvl" }, + { 152, "check-token" }, + { 153, "get-time" }, + { 154, "nget-vlinfo" }, + { 155, "bulk-stat" }, + { 156, "setlock" }, + { 157, "extlock" }, + { 158, "rellock" }, + { 159, "xstat-ver" }, + { 160, "get-xstat" }, + { 161, "dfs-lookup" }, + { 162, "dfs-flushcps" }, + { 163, "dfs-symlink" }, + { 220, "residency" }, + { 65536, "inline-bulk-status" }, + { 65537, "fetch-data-64" }, + { 65538, "store-data-64" }, + { 65539, "give-up-all-cbs" }, + { 65540, "get-caps" }, + { 65541, "cb-rx-conn-addr" }, + { 0, NULL }, +}; + +static struct tok cb_req[] = { + { 204, "callback" }, + { 205, "initcb" }, + { 206, "probe" }, + { 207, "getlock" }, + { 208, "getce" }, + { 209, "xstatver" }, + { 210, "getxstat" }, + { 211, "initcb2" }, + { 212, "whoareyou" }, + { 213, "initcb3" }, + { 214, "probeuuid" }, + { 215, "getsrvprefs" }, + { 216, "getcellservdb" }, + { 217, "getlocalcell" }, + { 218, "getcacheconf" }, + { 65536, "getce64" }, + { 65537, "getcellbynum" }, + { 65538, "tellmeaboutyourself" }, + { 0, NULL }, +}; + +static struct tok pt_req[] = { + { 500, "new-user" }, + { 501, "where-is-it" }, + { 502, "dump-entry" }, + { 503, "add-to-group" }, + { 504, "name-to-id" }, + { 505, "id-to-name" }, + { 506, "delete" }, + { 507, "remove-from-group" }, + { 508, "get-cps" }, + { 509, "new-entry" }, + { 510, "list-max" }, + { 511, "set-max" }, + { 512, "list-entry" }, + { 513, "change-entry" }, + { 514, "list-elements" }, + { 515, "same-mbr-of" }, + { 516, "set-fld-sentry" }, + { 517, "list-owned" }, + { 518, "get-cps2" }, + { 519, "get-host-cps" }, + { 520, "update-entry" }, + { 521, "list-entries" }, + { 530, "list-super-groups" }, + { 0, NULL }, +}; + +static struct tok vldb_req[] = { + { 501, "create-entry" }, + { 502, "delete-entry" }, + { 503, "get-entry-by-id" }, + { 504, "get-entry-by-name" }, + { 505, "get-new-volume-id" }, + { 506, "replace-entry" }, + { 507, "update-entry" }, + { 508, "setlock" }, + { 509, "releaselock" }, + { 510, "list-entry" }, + { 511, "list-attrib" }, + { 512, "linked-list" }, + { 513, "get-stats" }, + { 514, "probe" }, + { 515, "get-addrs" }, + { 516, "change-addr" }, + { 517, "create-entry-n" }, + { 518, "get-entry-by-id-n" }, + { 519, "get-entry-by-name-n" }, + { 520, "replace-entry-n" }, + { 521, "list-entry-n" }, + { 522, "list-attrib-n" }, + { 523, "linked-list-n" }, + { 524, "update-entry-by-name" }, + { 525, "create-entry-u" }, + { 526, "get-entry-by-id-u" }, + { 527, "get-entry-by-name-u" }, + { 528, "replace-entry-u" }, + { 529, "list-entry-u" }, + { 530, "list-attrib-u" }, + { 531, "linked-list-u" }, + { 532, "regaddr" }, + { 533, "get-addrs-u" }, + { 534, "list-attrib-n2" }, + { 0, NULL }, +}; + +static struct tok kauth_req[] = { + { 1, "auth-old" }, + { 21, "authenticate" }, + { 22, "authenticate-v2" }, + { 2, "change-pw" }, + { 3, "get-ticket-old" }, + { 23, "get-ticket" }, + { 4, "set-pw" }, + { 5, "set-fields" }, + { 6, "create-user" }, + { 7, "delete-user" }, + { 8, "get-entry" }, + { 9, "list-entry" }, + { 10, "get-stats" }, + { 11, "debug" }, + { 12, "get-pw" }, + { 13, "get-random-key" }, + { 14, "unlock" }, + { 15, "lock-status" }, + { 0, NULL }, +}; + +static struct tok vol_req[] = { + { 100, "create-volume" }, + { 101, "delete-volume" }, + { 102, "restore" }, + { 103, "forward" }, + { 104, "end-trans" }, + { 105, "clone" }, + { 106, "set-flags" }, + { 107, "get-flags" }, + { 108, "trans-create" }, + { 109, "dump" }, + { 110, "get-nth-volume" }, + { 111, "set-forwarding" }, + { 112, "get-name" }, + { 113, "get-status" }, + { 114, "sig-restore" }, + { 115, "list-partitions" }, + { 116, "list-volumes" }, + { 117, "set-id-types" }, + { 118, "monitor" }, + { 119, "partition-info" }, + { 120, "reclone" }, + { 121, "list-one-volume" }, + { 122, "nuke" }, + { 123, "set-date" }, + { 124, "x-list-volumes" }, + { 125, "x-list-one-volume" }, + { 126, "set-info" }, + { 127, "x-list-partitions" }, + { 128, "forward-multiple" }, + { 65536, "convert-ro" }, + { 65537, "get-size" }, + { 65538, "dump-v2" }, + { 0, NULL }, +}; + +static struct tok bos_req[] = { + { 80, "create-bnode" }, + { 81, "delete-bnode" }, + { 82, "set-status" }, + { 83, "get-status" }, + { 84, "enumerate-instance" }, + { 85, "get-instance-info" }, + { 86, "get-instance-parm" }, + { 87, "add-superuser" }, + { 88, "delete-superuser" }, + { 89, "list-superusers" }, + { 90, "list-keys" }, + { 91, "add-key" }, + { 92, "delete-key" }, + { 93, "set-cell-name" }, + { 94, "get-cell-name" }, + { 95, "get-cell-host" }, + { 96, "add-cell-host" }, + { 97, "delete-cell-host" }, + { 98, "set-t-status" }, + { 99, "shutdown-all" }, + { 100, "restart-all" }, + { 101, "startup-all" }, + { 102, "set-noauth-flag" }, + { 103, "re-bozo" }, + { 104, "restart" }, + { 105, "start-bozo-install" }, + { 106, "uninstall" }, + { 107, "get-dates" }, + { 108, "exec" }, + { 109, "prune" }, + { 110, "set-restart-time" }, + { 111, "get-restart-time" }, + { 112, "start-bozo-log" }, + { 113, "wait-all" }, + { 114, "get-instance-strings" }, + { 115, "get-restricted" }, + { 116, "set-restricted" }, + { 0, NULL }, +}; + +static struct tok ubik_req[] = { + { 10000, "vote-beacon" }, + { 10001, "vote-debug-old" }, + { 10002, "vote-sdebug-old" }, + { 10003, "vote-getsyncsite" }, + { 10004, "vote-debug" }, + { 10005, "vote-sdebug" }, + { 10006, "vote-xdebug" }, + { 10007, "vote-xsdebug" }, + { 20000, "disk-begin" }, + { 20001, "disk-commit" }, + { 20002, "disk-lock" }, + { 20003, "disk-write" }, + { 20004, "disk-getversion" }, + { 20005, "disk-getfile" }, + { 20006, "disk-sendfile" }, + { 20007, "disk-abort" }, + { 20008, "disk-releaselocks" }, + { 20009, "disk-truncate" }, + { 20010, "disk-probe" }, + { 20011, "disk-writev" }, + { 20012, "disk-interfaceaddr" }, + { 20013, "disk-setversion" }, + { 0, NULL }, +}; + +#define VOTE_LOW 10000 +#define VOTE_HIGH 10007 +#define DISK_LOW 20000 +#define DISK_HIGH 20013 + +static struct tok cb_types[] = { + { 1, "exclusive" }, + { 2, "shared" }, + { 3, "dropped" }, + { 0, NULL }, +}; + +static struct tok ubik_lock_types[] = { + { 1, "read" }, + { 2, "write" }, + { 3, "wait" }, + { 0, NULL }, +}; + +static const char *voltype[] = { "read-write", "read-only", "backup" }; + +static struct tok afs_fs_errors[] = { + { 101, "salvage volume" }, + { 102, "no such vnode" }, + { 103, "no such volume" }, + { 104, "volume exist" }, + { 105, "no service" }, + { 106, "volume offline" }, + { 107, "voline online" }, + { 108, "diskfull" }, + { 109, "diskquota exceeded" }, + { 110, "volume busy" }, + { 111, "volume moved" }, + { 112, "AFS IO error" }, + { -100, "restarting fileserver" }, + { 0, NULL } +}; + +/* + * Reasons for acknowledging a packet + */ + +static struct tok rx_ack_reasons[] = { + { 1, "ack requested" }, + { 2, "duplicate packet" }, + { 3, "out of sequence" }, + { 4, "exceeds window" }, + { 5, "no buffer space" }, + { 6, "ping" }, + { 7, "ping response" }, + { 8, "delay" }, + { 9, "idle" }, + { 0, NULL }, +}; + +/* + * Cache entries we keep around so we can figure out the RX opcode + * numbers for replies. This allows us to make sense of RX reply packets. + */ + +struct rx_cache_entry { + u_int32_t callnum; /* Call number (net order) */ + struct in_addr client; /* client IP address (net order) */ + struct in_addr server; /* server IP address (net order) */ + int dport; /* server port (host order) */ + u_short serviceId; /* Service identifier (net order) */ + u_int32_t opcode; /* RX opcode (host order) */ +}; + +#define RX_CACHE_SIZE 64 + +static struct rx_cache_entry rx_cache[RX_CACHE_SIZE]; + +static int rx_cache_next = 0; +static int rx_cache_hint = 0; +static void rx_cache_insert(const u_char *, const struct ip *, int); +static int rx_cache_find(const struct rx_header *, const struct ip *, + int, int32_t *); + +static void fs_print(const u_char *, int); +static void fs_reply_print(const u_char *, int, int32_t); +static void acl_print(u_char *, int, u_char *); +static void cb_print(const u_char *, int); +static void cb_reply_print(const u_char *, int, int32_t); +static void prot_print(const u_char *, int); +static void prot_reply_print(const u_char *, int, int32_t); +static void vldb_print(const u_char *, int); +static void vldb_reply_print(const u_char *, int, int32_t); +static void kauth_print(const u_char *, int); +static void kauth_reply_print(const u_char *, int, int32_t); +static void vol_print(const u_char *, int); +static void vol_reply_print(const u_char *, int, int32_t); +static void bos_print(const u_char *, int); +static void bos_reply_print(const u_char *, int, int32_t); +static void ubik_print(const u_char *); +static void ubik_reply_print(const u_char *, int, int32_t); + +static void rx_ack_print(const u_char *, int); + +static int is_ubik(u_int32_t); + +/* + * Handle the rx-level packet. See if we know what port it's going to so + * we can peek at the afs call inside + */ + +void +rx_print(register const u_char *bp, int length, int sport, int dport, + u_char *bp2) +{ + register struct rx_header *rxh; + int i; + int32_t opcode; + + if (snapend - bp < (int)sizeof (struct rx_header)) { + printf(" [|rx] (%d)", length); + return; + } + + rxh = (struct rx_header *) bp; + + printf(" rx %s", tok2str(rx_types, "type %d", rxh->type)); + + if (vflag) { + int firstflag = 0; + + if (vflag > 1) + printf(" cid %08x call# %d", + (int) EXTRACT_32BITS(&rxh->cid), + (int) EXTRACT_32BITS(&rxh->callNumber)); + + printf(" seq %d ser %d", + (int) EXTRACT_32BITS(&rxh->seq), + (int) EXTRACT_32BITS(&rxh->serial)); + + if (vflag > 2) + printf(" secindex %d serviceid %hu", + (int) rxh->securityIndex, + EXTRACT_16BITS(&rxh->serviceId)); + + if (vflag > 1) + for (i = 0; i < NUM_RX_FLAGS; i++) { + if (rxh->flags & rx_flags[i].flag && + (!rx_flags[i].packetType || + rxh->type == rx_flags[i].packetType)) { + if (!firstflag) { + firstflag = 1; + printf(" "); + } else { + printf(","); + } + printf("<%s>", rx_flags[i].s); + } + } + } + + /* + * Try to handle AFS calls that we know about. Check the destination + * port and make sure it's a data packet. Also, make sure the + * seq number is 1 (because otherwise it's a continuation packet, + * and we can't interpret that). Also, seems that reply packets + * do not have the client-init flag set, so we check for that + * as well. + */ + + if (rxh->type == RX_PACKET_TYPE_DATA && + EXTRACT_32BITS(&rxh->seq) == 1 && + rxh->flags & RX_CLIENT_INITIATED) { + + /* + * Insert this call into the call cache table, so we + * have a chance to print out replies + */ + + rx_cache_insert(bp, (const struct ip *) bp2, dport); + + switch (dport) { + case FS_RX_PORT: /* AFS file service */ + fs_print(bp, length); + break; + case CB_RX_PORT: /* AFS callback service */ + cb_print(bp, length); + break; + case PROT_RX_PORT: /* AFS protection service */ + prot_print(bp, length); + break; + case VLDB_RX_PORT: /* AFS VLDB service */ + vldb_print(bp, length); + break; + case KAUTH_RX_PORT: /* AFS Kerberos auth service */ + kauth_print(bp, length); + break; + case VOL_RX_PORT: /* AFS Volume service */ + vol_print(bp, length); + break; + case BOS_RX_PORT: /* AFS BOS service */ + bos_print(bp, length); + break; + default: + ; + } + + /* + * If it's a reply (client-init is _not_ set, but seq is one) + * then look it up in the cache. If we find it, call the reply + * printing functions Note that we handle abort packets here, + * because printing out the return code can be useful at times. + */ + + } else if (((rxh->type == RX_PACKET_TYPE_DATA && + EXTRACT_32BITS(&rxh->seq) == 1) || + rxh->type == RX_PACKET_TYPE_ABORT) && + (rxh->flags & RX_CLIENT_INITIATED) == 0 && + rx_cache_find(rxh, (const struct ip *) bp2, + sport, &opcode)) { + + switch (sport) { + case FS_RX_PORT: /* AFS file service */ + fs_reply_print(bp, length, opcode); + break; + case CB_RX_PORT: /* AFS callback service */ + cb_reply_print(bp, length, opcode); + break; + case PROT_RX_PORT: /* AFS PT service */ + prot_reply_print(bp, length, opcode); + break; + case VLDB_RX_PORT: /* AFS VLDB service */ + vldb_reply_print(bp, length, opcode); + break; + case KAUTH_RX_PORT: /* AFS Kerberos auth service */ + kauth_reply_print(bp, length, opcode); + break; + case VOL_RX_PORT: /* AFS Volume service */ + vol_reply_print(bp, length, opcode); + break; + case BOS_RX_PORT: /* AFS BOS service */ + bos_reply_print(bp, length, opcode); + break; + default: + ; + } + + /* + * If it's an RX ack packet, then use the appropriate ack decoding + * function (there isn't any service-specific information in the + * ack packet, so we can use one for all AFS services) + */ + + } else if (rxh->type == RX_PACKET_TYPE_ACK) + rx_ack_print(bp, length); + + + printf(" (%d)", length); +} + +/* + * Insert an entry into the cache. Taken from print-nfs.c + */ + +static void +rx_cache_insert(const u_char *bp, const struct ip *ip, int dport) +{ + struct rx_cache_entry *rxent; + const struct rx_header *rxh = (const struct rx_header *) bp; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) + return; + + rxent = &rx_cache[rx_cache_next]; + + if (++rx_cache_next >= RX_CACHE_SIZE) + rx_cache_next = 0; + + rxent->callnum = rxh->callNumber; + rxent->client = ip->ip_src; + rxent->server = ip->ip_dst; + rxent->dport = dport; + rxent->serviceId = rxh->serviceId; + rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header)); +} + +/* + * Lookup an entry in the cache. Also taken from print-nfs.c + * + * Note that because this is a reply, we're looking at the _source_ + * port. + */ + +static int +rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport, + int32_t *opcode) +{ + int i; + struct rx_cache_entry *rxent; + u_int32_t clip = ip->ip_dst.s_addr; + u_int32_t sip = ip->ip_src.s_addr; + + /* Start the search where we last left off */ + + i = rx_cache_hint; + do { + rxent = &rx_cache[i]; + if (rxent->callnum == rxh->callNumber && + rxent->client.s_addr == clip && + rxent->server.s_addr == sip && + rxent->serviceId == rxh->serviceId && + rxent->dport == sport) { + + /* We got a match! */ + + rx_cache_hint = i; + *opcode = rxent->opcode; + return(1); + } + if (++i > RX_CACHE_SIZE) + i = 0; + } while (i != rx_cache_hint); + + /* Our search failed */ + return(0); +} + +/* + * These extrememly grody macros handle the printing of various AFS stuff. + */ + +#define FIDOUT() { unsigned long n1, n2, n3; \ + TCHECK2(bp[0], sizeof(int32_t) * 3); \ + n1 = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + n2 = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + n3 = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + printf(" fid %d/%d/%d", (int) n1, (int) n2, (int) n3); \ + } + +#define STROUT(MAX) { unsigned int i; \ + TCHECK2(bp[0], sizeof(int32_t)); \ + i = EXTRACT_32BITS(bp); \ + if (i > (MAX)) \ + goto trunc; \ + bp += sizeof(int32_t); \ + printf(" \""); \ + if (fn_printn(bp, i, snapend)) \ + goto trunc; \ + printf("\""); \ + bp += ((i + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); \ + } + +#define INTOUT() { int i; \ + TCHECK2(bp[0], sizeof(int32_t)); \ + i = (int) EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + printf(" %d", i); \ + } + +#define UINTOUT() { unsigned long i; \ + TCHECK2(bp[0], sizeof(int32_t)); \ + i = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + printf(" %lu", i); \ + } + +#define UINT64OUT() { u_int64_t i; \ + TCHECK2(bp[0], sizeof(u_int64_t)); \ + i = EXTRACT_64BITS(bp); \ + bp += sizeof(u_int64_t); \ + printf(" %" PRIu64, i); \ + } + +#define DATEOUT() { time_t t; struct tm *tm; char str[256]; \ + TCHECK2(bp[0], sizeof(int32_t)); \ + t = (time_t) EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + tm = localtime(&t); \ + strftime(str, 256, "%Y/%m/%d %T", tm); \ + printf(" %s", str); \ + } + +#define STOREATTROUT() { unsigned long mask, i; \ + TCHECK2(bp[0], (sizeof(int32_t)*6)); \ + mask = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ + if (mask) printf (" StoreStatus"); \ + if (mask & 1) { printf(" date"); DATEOUT(); } \ + else bp += sizeof(int32_t); \ + i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ + if (mask & 2) printf(" owner %lu", i); \ + i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ + if (mask & 4) printf(" group %lu", i); \ + i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ + if (mask & 8) printf(" mode %lo", i & 07777); \ + i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \ + if (mask & 16) printf(" segsize %lu", i); \ + /* undocumented in 3.3 docu */ \ + if (mask & 1024) printf(" fsync"); \ + } + +#define UBIK_VERSIONOUT() {int32_t epoch; int32_t counter; \ + TCHECK2(bp[0], sizeof(int32_t) * 2); \ + epoch = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + counter = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + printf(" %d.%d", epoch, counter); \ + } + +#define AFSUUIDOUT() {u_int32_t temp; int i; \ + TCHECK2(bp[0], 11*sizeof(u_int32_t)); \ + temp = EXTRACT_32BITS(bp); \ + bp += sizeof(u_int32_t); \ + printf(" %08x", temp); \ + temp = EXTRACT_32BITS(bp); \ + bp += sizeof(u_int32_t); \ + printf("%04x", temp); \ + temp = EXTRACT_32BITS(bp); \ + bp += sizeof(u_int32_t); \ + printf("%04x", temp); \ + for (i = 0; i < 8; i++) { \ + temp = EXTRACT_32BITS(bp); \ + bp += sizeof(u_int32_t); \ + printf("%02x", (unsigned char) temp); \ + } \ + } + +/* + * This is the sickest one of all + */ + +#define VECOUT(MAX) { u_char *sp; \ + u_char s[AFSNAMEMAX]; \ + int k; \ + if ((MAX) + 1 > sizeof(s)) \ + goto trunc; \ + TCHECK2(bp[0], (MAX) * sizeof(int32_t)); \ + sp = s; \ + for (k = 0; k < (MAX); k++) { \ + *sp++ = (u_char) EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + } \ + s[(MAX)] = '\0'; \ + printf(" \""); \ + fn_print(s, NULL); \ + printf("\""); \ + } + +#define DESTSERVEROUT() { unsigned long n1, n2, n3; \ + TCHECK2(bp[0], sizeof(int32_t) * 3); \ + n1 = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + n2 = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + n3 = EXTRACT_32BITS(bp); \ + bp += sizeof(int32_t); \ + printf(" server %d:%d:%d", (int) n1, (int) n2, (int) n3); \ + } + +/* + * Handle calls to the AFS file service (fs) + */ + +static void +fs_print(register const u_char *bp, int length) +{ + int fs_op; + unsigned long i; + + if (length <= (int)sizeof(struct rx_header)) + return; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { + goto trunc; + } + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from fsint/afsint.xg + */ + + fs_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" fs call %s", tok2str(fs_req, "op#%d", fs_op)); + + /* + * Print out arguments to some of the AFS calls. This stuff is + * all from afsint.xg + */ + + bp += sizeof(struct rx_header) + 4; + + /* + * Sigh. This is gross. Ritchie forgive me. + */ + + switch (fs_op) { + case 130: /* Fetch data */ + FIDOUT(); + printf(" offset"); + UINTOUT(); + printf(" length"); + UINTOUT(); + break; + case 131: /* Fetch ACL */ + case 132: /* Fetch Status */ + case 143: /* Old set lock */ + case 144: /* Old extend lock */ + case 145: /* Old release lock */ + case 156: /* Set lock */ + case 157: /* Extend lock */ + case 158: /* Release lock */ + FIDOUT(); + break; + case 135: /* Store status */ + FIDOUT(); + STOREATTROUT(); + break; + case 133: /* Store data */ + FIDOUT(); + STOREATTROUT(); + printf(" offset"); + UINTOUT(); + printf(" length"); + UINTOUT(); + printf(" flen"); + UINTOUT(); + break; + case 134: /* Store ACL */ + { + char a[AFSOPAQUEMAX+1]; + FIDOUT(); + TCHECK2(bp[0], 4); + i = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + TCHECK2(bp[0], i); + i = min(AFSOPAQUEMAX, i); + strncpy(a, (char *) bp, i); + a[i] = '\0'; + acl_print((u_char *) a, sizeof(a), (u_char *) a + i); + break; + } + case 137: /* Create file */ + case 141: /* MakeDir */ + FIDOUT(); + STROUT(AFSNAMEMAX); + STOREATTROUT(); + break; + case 136: /* Remove file */ + case 142: /* Remove directory */ + FIDOUT(); + STROUT(AFSNAMEMAX); + break; + case 138: /* Rename file */ + printf(" old"); + FIDOUT(); + STROUT(AFSNAMEMAX); + printf(" new"); + FIDOUT(); + STROUT(AFSNAMEMAX); + break; + case 139: /* Symlink */ + FIDOUT(); + STROUT(AFSNAMEMAX); + printf(" link to"); + STROUT(AFSNAMEMAX); + break; + case 140: /* Link */ + FIDOUT(); + STROUT(AFSNAMEMAX); + printf(" link to"); + FIDOUT(); + break; + case 148: /* Get volume info */ + STROUT(AFSNAMEMAX); + break; + case 149: /* Get volume stats */ + case 150: /* Set volume stats */ + printf(" volid"); + UINTOUT(); + break; + case 154: /* New get volume info */ + printf(" volname"); + STROUT(AFSNAMEMAX); + break; + case 155: /* Bulk stat */ + case 65536: /* Inline bulk stat */ + { + unsigned long j; + TCHECK2(bp[0], 4); + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + + for (i = 0; i < j; i++) { + FIDOUT(); + if (i != j - 1) + printf(","); + } + if (j == 0) + printf(" "); + } + case 65537: /* Fetch data 64 */ + FIDOUT(); + printf(" offset"); + UINT64OUT(); + printf(" length"); + UINT64OUT(); + break; + case 65538: /* Store data 64 */ + FIDOUT(); + STOREATTROUT(); + printf(" offset"); + UINT64OUT(); + printf(" length"); + UINT64OUT(); + printf(" flen"); + UINT64OUT(); + break; + case 65541: /* CallBack rx conn address */ + printf(" addr"); + UINTOUT(); + default: + ; + } + + return; + +trunc: + printf(" [|fs]"); +} + +/* + * Handle replies to the AFS file service + */ + +static void +fs_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + unsigned long i; + struct rx_header *rxh; + + if (length <= (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from fsint/afsint.xg + */ + + printf(" fs reply %s", tok2str(fs_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, interpret the response + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) { + switch (opcode) { + case 131: /* Fetch ACL */ + { + char a[AFSOPAQUEMAX+1]; + TCHECK2(bp[0], 4); + i = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + TCHECK2(bp[0], i); + i = min(AFSOPAQUEMAX, i); + strncpy(a, (char *) bp, i); + a[i] = '\0'; + acl_print((u_char *) a, sizeof(a), (u_char *) a + i); + break; + } + case 137: /* Create file */ + case 141: /* MakeDir */ + printf(" new"); + FIDOUT(); + break; + case 151: /* Get root volume */ + printf(" root volume"); + STROUT(AFSNAMEMAX); + break; + case 153: /* Get time */ + DATEOUT(); + break; + default: + ; + } + } else if (rxh->type == RX_PACKET_TYPE_ABORT) { + int i; + + /* + * Otherwise, just print out the return code + */ + TCHECK2(bp[0], sizeof(int32_t)); + i = (int) EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + + printf(" error %s", tok2str(afs_fs_errors, "#%d", i)); + } else { + printf(" strange fs reply of type %d", rxh->type); + } + + return; + +trunc: + printf(" [|fs]"); +} + +/* + * Print out an AFS ACL string. An AFS ACL is a string that has the + * following format: + * + * + * + * .... + * + * "positive" and "negative" are integers which contain the number of + * positive and negative ACL's in the string. The uid/aclbits pair are + * ASCII strings containing the UID/PTS record and and a ascii number + * representing a logical OR of all the ACL permission bits + */ + +static void +acl_print(u_char *s, int maxsize, u_char *end) +{ + int pos, neg, acl; + int n, i; + char *user; + char fmt[1024]; + + if ((user = (char *)malloc(maxsize)) == NULL) + return; + + if (sscanf((char *) s, "%d %d\n%n", &pos, &neg, &n) != 2) + goto finish; + + s += n; + + if (s > end) + goto finish; + + /* + * This wacky order preserves the order used by the "fs" command + */ + +#define ACLOUT(acl) \ + if (acl & PRSFS_READ) \ + printf("r"); \ + if (acl & PRSFS_LOOKUP) \ + printf("l"); \ + if (acl & PRSFS_INSERT) \ + printf("i"); \ + if (acl & PRSFS_DELETE) \ + printf("d"); \ + if (acl & PRSFS_WRITE) \ + printf("w"); \ + if (acl & PRSFS_LOCK) \ + printf("k"); \ + if (acl & PRSFS_ADMINISTER) \ + printf("a"); + + for (i = 0; i < pos; i++) { + snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1); + if (sscanf((char *) s, fmt, user, &acl, &n) != 2) + goto finish; + s += n; + printf(" +{"); + fn_print((u_char *)user, NULL); + printf(" "); + ACLOUT(acl); + printf("}"); + if (s > end) + goto finish; + } + + for (i = 0; i < neg; i++) { + snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1); + if (sscanf((char *) s, fmt, user, &acl, &n) != 2) + goto finish; + s += n; + printf(" -{"); + fn_print((u_char *)user, NULL); + printf(" "); + ACLOUT(acl); + printf("}"); + if (s > end) + goto finish; + } + +finish: + free(user); + return; +} + +#undef ACLOUT + +/* + * Handle calls to the AFS callback service + */ + +static void +cb_print(register const u_char *bp, int length) +{ + int cb_op; + unsigned long i; + + if (length <= (int)sizeof(struct rx_header)) + return; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { + goto trunc; + } + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from fsint/afscbint.xg + */ + + cb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" cb call %s", tok2str(cb_req, "op#%d", cb_op)); + + bp += sizeof(struct rx_header) + 4; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from fsint/afscbint.xg + */ + + switch (cb_op) { + case 204: /* Callback */ + { + unsigned long j, t; + TCHECK2(bp[0], 4); + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + + for (i = 0; i < j; i++) { + FIDOUT(); + if (i != j - 1) + printf(","); + } + + if (j == 0) + printf(" "); + + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + + if (j != 0) + printf(";"); + + for (i = 0; i < j; i++) { + printf(" ver"); + INTOUT(); + printf(" expires"); + DATEOUT(); + TCHECK2(bp[0], 4); + t = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + tok2str(cb_types, "type %d", t); + } + } + case 214: { + printf(" afsuuid"); + AFSUUIDOUT(); + break; + } + default: + ; + } + + return; + +trunc: + printf(" [|cb]"); +} + +/* + * Handle replies to the AFS Callback Service + */ + +static void +cb_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + struct rx_header *rxh; + + if (length <= (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from fsint/afscbint.xg + */ + + printf(" cb reply %s", tok2str(cb_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, interpret the response. + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) + switch (opcode) { + case 213: /* InitCallBackState3 */ + AFSUUIDOUT(); + break; + default: + ; + } + else { + /* + * Otherwise, just print out the return code + */ + printf(" errcode"); + INTOUT(); + } + + return; + +trunc: + printf(" [|cb]"); +} + +/* + * Handle calls to the AFS protection database server + */ + +static void +prot_print(register const u_char *bp, int length) +{ + unsigned long i; + int pt_op; + + if (length <= (int)sizeof(struct rx_header)) + return; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { + goto trunc; + } + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from ptserver/ptint.xg + */ + + pt_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" pt"); + + if (is_ubik(pt_op)) { + ubik_print(bp); + return; + } + + printf(" call %s", tok2str(pt_req, "op#%d", pt_op)); + + /* + * Decode some of the arguments to the PT calls + */ + + bp += sizeof(struct rx_header) + 4; + + switch (pt_op) { + case 500: /* I New User */ + STROUT(PRNAMEMAX); + printf(" id"); + INTOUT(); + printf(" oldid"); + INTOUT(); + break; + case 501: /* Where is it */ + case 506: /* Delete */ + case 508: /* Get CPS */ + case 512: /* List entry */ + case 514: /* List elements */ + case 517: /* List owned */ + case 518: /* Get CPS2 */ + case 519: /* Get host CPS */ + case 530: /* List super groups */ + printf(" id"); + INTOUT(); + break; + case 502: /* Dump entry */ + printf(" pos"); + INTOUT(); + break; + case 503: /* Add to group */ + case 507: /* Remove from group */ + case 515: /* Is a member of? */ + printf(" uid"); + INTOUT(); + printf(" gid"); + INTOUT(); + break; + case 504: /* Name to ID */ + { + unsigned long j; + TCHECK2(bp[0], 4); + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + + /* + * Who designed this chicken-shit protocol? + * + * Each character is stored as a 32-bit + * integer! + */ + + for (i = 0; i < j; i++) { + VECOUT(PRNAMEMAX); + } + if (j == 0) + printf(" "); + } + break; + case 505: /* Id to name */ + { + unsigned long j; + printf(" ids:"); + TCHECK2(bp[0], 4); + i = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + for (j = 0; j < i; j++) + INTOUT(); + if (j == 0) + printf(" "); + } + break; + case 509: /* New entry */ + STROUT(PRNAMEMAX); + printf(" flag"); + INTOUT(); + printf(" oid"); + INTOUT(); + break; + case 511: /* Set max */ + printf(" id"); + INTOUT(); + printf(" gflag"); + INTOUT(); + break; + case 513: /* Change entry */ + printf(" id"); + INTOUT(); + STROUT(PRNAMEMAX); + printf(" oldid"); + INTOUT(); + printf(" newid"); + INTOUT(); + break; + case 520: /* Update entry */ + printf(" id"); + INTOUT(); + STROUT(PRNAMEMAX); + break; + default: + ; + } + + + return; + +trunc: + printf(" [|pt]"); +} + +/* + * Handle replies to the AFS protection service + */ + +static void +prot_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + struct rx_header *rxh; + unsigned long i; + + if (length < (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from ptserver/ptint.xg. Check to see if it's a + * Ubik call, however. + */ + + printf(" pt"); + + if (is_ubik(opcode)) { + ubik_reply_print(bp, length, opcode); + return; + } + + printf(" reply %s", tok2str(pt_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, interpret the response + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) + switch (opcode) { + case 504: /* Name to ID */ + { + unsigned long j; + printf(" ids:"); + TCHECK2(bp[0], 4); + i = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + for (j = 0; j < i; j++) + INTOUT(); + if (j == 0) + printf(" "); + } + break; + case 505: /* ID to name */ + { + unsigned long j; + TCHECK2(bp[0], 4); + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + + /* + * Who designed this chicken-shit protocol? + * + * Each character is stored as a 32-bit + * integer! + */ + + for (i = 0; i < j; i++) { + VECOUT(PRNAMEMAX); + } + if (j == 0) + printf(" "); + } + break; + case 508: /* Get CPS */ + case 514: /* List elements */ + case 517: /* List owned */ + case 518: /* Get CPS2 */ + case 519: /* Get host CPS */ + { + unsigned long j; + TCHECK2(bp[0], 4); + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + for (i = 0; i < j; i++) { + INTOUT(); + } + if (j == 0) + printf(" "); + } + break; + case 510: /* List max */ + printf(" maxuid"); + INTOUT(); + printf(" maxgid"); + INTOUT(); + break; + default: + ; + } + else { + /* + * Otherwise, just print out the return code + */ + printf(" errcode"); + INTOUT(); + } + + return; + +trunc: + printf(" [|pt]"); +} + +/* + * Handle calls to the AFS volume location database service + */ + +static void +vldb_print(register const u_char *bp, int length) +{ + int vldb_op; + unsigned long i; + + if (length <= (int)sizeof(struct rx_header)) + return; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { + goto trunc; + } + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from vlserver/vldbint.xg + */ + + vldb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" vldb"); + + if (is_ubik(vldb_op)) { + ubik_print(bp); + return; + } + printf(" call %s", tok2str(vldb_req, "op#%d", vldb_op)); + + /* + * Decode some of the arguments to the VLDB calls + */ + + bp += sizeof(struct rx_header) + 4; + + switch (vldb_op) { + case 501: /* Create new volume */ + case 517: /* Create entry N */ + VECOUT(VLNAMEMAX); + break; + case 502: /* Delete entry */ + case 503: /* Get entry by ID */ + case 507: /* Update entry */ + case 508: /* Set lock */ + case 509: /* Release lock */ + case 518: /* Get entry by ID N */ + printf(" volid"); + INTOUT(); + TCHECK2(bp[0], sizeof(int32_t)); + i = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + if (i <= 2) + printf(" type %s", voltype[i]); + break; + case 504: /* Get entry by name */ + case 519: /* Get entry by name N */ + case 524: /* Update entry by name */ + case 527: /* Get entry by name U */ + STROUT(VLNAMEMAX); + break; + case 505: /* Get new vol id */ + printf(" bump"); + INTOUT(); + break; + case 506: /* Replace entry */ + case 520: /* Replace entry N */ + printf(" volid"); + INTOUT(); + TCHECK2(bp[0], sizeof(int32_t)); + i = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + if (i <= 2) + printf(" type %s", voltype[i]); + VECOUT(VLNAMEMAX); + break; + case 510: /* List entry */ + case 521: /* List entry N */ + printf(" index"); + INTOUT(); + break; + default: + ; + } + + return; + +trunc: + printf(" [|vldb]"); +} + +/* + * Handle replies to the AFS volume location database service + */ + +static void +vldb_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + struct rx_header *rxh; + unsigned long i; + + if (length < (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from vlserver/vldbint.xg. Check to see if it's a + * Ubik call, however. + */ + + printf(" vldb"); + + if (is_ubik(opcode)) { + ubik_reply_print(bp, length, opcode); + return; + } + + printf(" reply %s", tok2str(vldb_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, interpret the response + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) + switch (opcode) { + case 510: /* List entry */ + printf(" count"); + INTOUT(); + printf(" nextindex"); + INTOUT(); + case 503: /* Get entry by id */ + case 504: /* Get entry by name */ + { unsigned long nservers, j; + VECOUT(VLNAMEMAX); + TCHECK2(bp[0], sizeof(int32_t)); + bp += sizeof(int32_t); + printf(" numservers"); + TCHECK2(bp[0], sizeof(int32_t)); + nservers = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + printf(" %lu", nservers); + printf(" servers"); + for (i = 0; i < 8; i++) { + TCHECK2(bp[0], sizeof(int32_t)); + if (i < nservers) + printf(" %s", + intoa(((struct in_addr *) bp)->s_addr)); + bp += sizeof(int32_t); + } + printf(" partitions"); + for (i = 0; i < 8; i++) { + TCHECK2(bp[0], sizeof(int32_t)); + j = EXTRACT_32BITS(bp); + if (i < nservers && j <= 26) + printf(" %c", 'a' + (int)j); + else if (i < nservers) + printf(" %lu", j); + bp += sizeof(int32_t); + } + TCHECK2(bp[0], 8 * sizeof(int32_t)); + bp += 8 * sizeof(int32_t); + printf(" rwvol"); + UINTOUT(); + printf(" rovol"); + UINTOUT(); + printf(" backup"); + UINTOUT(); + } + break; + case 505: /* Get new volume ID */ + printf(" newvol"); + UINTOUT(); + break; + case 521: /* List entry */ + case 529: /* List entry U */ + printf(" count"); + INTOUT(); + printf(" nextindex"); + INTOUT(); + case 518: /* Get entry by ID N */ + case 519: /* Get entry by name N */ + { unsigned long nservers, j; + VECOUT(VLNAMEMAX); + printf(" numservers"); + TCHECK2(bp[0], sizeof(int32_t)); + nservers = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + printf(" %lu", nservers); + printf(" servers"); + for (i = 0; i < 13; i++) { + TCHECK2(bp[0], sizeof(int32_t)); + if (i < nservers) + printf(" %s", + intoa(((struct in_addr *) bp)->s_addr)); + bp += sizeof(int32_t); + } + printf(" partitions"); + for (i = 0; i < 13; i++) { + TCHECK2(bp[0], sizeof(int32_t)); + j = EXTRACT_32BITS(bp); + if (i < nservers && j <= 26) + printf(" %c", 'a' + (int)j); + else if (i < nservers) + printf(" %lu", j); + bp += sizeof(int32_t); + } + TCHECK2(bp[0], 13 * sizeof(int32_t)); + bp += 13 * sizeof(int32_t); + printf(" rwvol"); + UINTOUT(); + printf(" rovol"); + UINTOUT(); + printf(" backup"); + UINTOUT(); + } + break; + case 526: /* Get entry by ID U */ + case 527: /* Get entry by name U */ + { unsigned long nservers, j; + VECOUT(VLNAMEMAX); + printf(" numservers"); + TCHECK2(bp[0], sizeof(int32_t)); + nservers = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + printf(" %lu", nservers); + printf(" servers"); + for (i = 0; i < 13; i++) { + if (i < nservers) { + printf(" afsuuid"); + AFSUUIDOUT(); + } else { + TCHECK2(bp[0], 44); + bp += 44; + } + } + TCHECK2(bp[0], 4 * 13); + bp += 4 * 13; + printf(" partitions"); + for (i = 0; i < 13; i++) { + TCHECK2(bp[0], sizeof(int32_t)); + j = EXTRACT_32BITS(bp); + if (i < nservers && j <= 26) + printf(" %c", 'a' + (int)j); + else if (i < nservers) + printf(" %lu", j); + bp += sizeof(int32_t); + } + TCHECK2(bp[0], 13 * sizeof(int32_t)); + bp += 13 * sizeof(int32_t); + printf(" rwvol"); + UINTOUT(); + printf(" rovol"); + UINTOUT(); + printf(" backup"); + UINTOUT(); + } + default: + ; + } + + else { + /* + * Otherwise, just print out the return code + */ + printf(" errcode"); + INTOUT(); + } + + return; + +trunc: + printf(" [|vldb]"); +} + +/* + * Handle calls to the AFS Kerberos Authentication service + */ + +static void +kauth_print(register const u_char *bp, int length) +{ + int kauth_op; + + if (length <= (int)sizeof(struct rx_header)) + return; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { + goto trunc; + } + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from kauth/kauth.rg + */ + + kauth_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" kauth"); + + if (is_ubik(kauth_op)) { + ubik_print(bp); + return; + } + + + printf(" call %s", tok2str(kauth_req, "op#%d", kauth_op)); + + /* + * Decode some of the arguments to the KA calls + */ + + bp += sizeof(struct rx_header) + 4; + + switch (kauth_op) { + case 1: /* Authenticate old */; + case 21: /* Authenticate */ + case 22: /* Authenticate-V2 */ + case 2: /* Change PW */ + case 5: /* Set fields */ + case 6: /* Create user */ + case 7: /* Delete user */ + case 8: /* Get entry */ + case 14: /* Unlock */ + case 15: /* Lock status */ + printf(" principal"); + STROUT(KANAMEMAX); + STROUT(KANAMEMAX); + break; + case 3: /* GetTicket-old */ + case 23: /* GetTicket */ + { + int i; + printf(" kvno"); + INTOUT(); + printf(" domain"); + STROUT(KANAMEMAX); + TCHECK2(bp[0], sizeof(int32_t)); + i = (int) EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + TCHECK2(bp[0], i); + bp += i; + printf(" principal"); + STROUT(KANAMEMAX); + STROUT(KANAMEMAX); + break; + } + case 4: /* Set Password */ + printf(" principal"); + STROUT(KANAMEMAX); + STROUT(KANAMEMAX); + printf(" kvno"); + INTOUT(); + break; + case 12: /* Get password */ + printf(" name"); + STROUT(KANAMEMAX); + break; + default: + ; + } + + return; + +trunc: + printf(" [|kauth]"); +} + +/* + * Handle replies to the AFS Kerberos Authentication Service + */ + +static void +kauth_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + struct rx_header *rxh; + + if (length <= (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from kauth/kauth.rg + */ + + printf(" kauth"); + + if (is_ubik(opcode)) { + ubik_reply_print(bp, length, opcode); + return; + } + + printf(" reply %s", tok2str(kauth_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, interpret the response. + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) + /* Well, no, not really. Leave this for later */ + ; + else { + /* + * Otherwise, just print out the return code + */ + printf(" errcode"); + INTOUT(); + } + + return; + +trunc: + printf(" [|kauth]"); +} + +/* + * Handle calls to the AFS Volume location service + */ + +static void +vol_print(register const u_char *bp, int length) +{ + int vol_op; + + if (length <= (int)sizeof(struct rx_header)) + return; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { + goto trunc; + } + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from volser/volint.xg + */ + + vol_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" vol call %s", tok2str(vol_req, "op#%d", vol_op)); + + bp += sizeof(struct rx_header) + 4; + + switch (vol_op) { + case 100: /* Create volume */ + printf(" partition"); + UINTOUT(); + printf(" name"); + STROUT(AFSNAMEMAX); + printf(" type"); + UINTOUT(); + printf(" parent"); + UINTOUT(); + break; + case 101: /* Delete volume */ + case 107: /* Get flags */ + printf(" trans"); + UINTOUT(); + break; + case 102: /* Restore */ + printf(" totrans"); + UINTOUT(); + printf(" flags"); + UINTOUT(); + break; + case 103: /* Forward */ + printf(" fromtrans"); + UINTOUT(); + printf(" fromdate"); + DATEOUT(); + DESTSERVEROUT(); + printf(" desttrans"); + INTOUT(); + break; + case 104: /* End trans */ + printf(" trans"); + UINTOUT(); + break; + case 105: /* Clone */ + printf(" trans"); + UINTOUT(); + printf(" purgevol"); + UINTOUT(); + printf(" newtype"); + UINTOUT(); + printf(" newname"); + STROUT(AFSNAMEMAX); + break; + case 106: /* Set flags */ + printf(" trans"); + UINTOUT(); + printf(" flags"); + UINTOUT(); + break; + case 108: /* Trans create */ + printf(" vol"); + UINTOUT(); + printf(" partition"); + UINTOUT(); + printf(" flags"); + UINTOUT(); + break; + case 109: /* Dump */ + case 655537: /* Get size */ + printf(" fromtrans"); + UINTOUT(); + printf(" fromdate"); + DATEOUT(); + break; + case 110: /* Get n-th volume */ + printf(" index"); + UINTOUT(); + break; + case 111: /* Set forwarding */ + printf(" tid"); + UINTOUT(); + printf(" newsite"); + UINTOUT(); + break; + case 112: /* Get name */ + case 113: /* Get status */ + printf(" tid"); + break; + case 114: /* Signal restore */ + printf(" name"); + STROUT(AFSNAMEMAX); + printf(" type"); + UINTOUT(); + printf(" pid"); + UINTOUT(); + printf(" cloneid"); + UINTOUT(); + break; + case 116: /* List volumes */ + printf(" partition"); + UINTOUT(); + printf(" flags"); + UINTOUT(); + break; + case 117: /* Set id types */ + printf(" tid"); + UINTOUT(); + printf(" name"); + STROUT(AFSNAMEMAX); + printf(" type"); + UINTOUT(); + printf(" pid"); + UINTOUT(); + printf(" clone"); + UINTOUT(); + printf(" backup"); + UINTOUT(); + break; + case 119: /* Partition info */ + printf(" name"); + STROUT(AFSNAMEMAX); + break; + case 120: /* Reclone */ + printf(" tid"); + UINTOUT(); + break; + case 121: /* List one volume */ + case 122: /* Nuke volume */ + case 124: /* Extended List volumes */ + case 125: /* Extended List one volume */ + case 65536: /* Convert RO to RW volume */ + printf(" partid"); + UINTOUT(); + printf(" volid"); + UINTOUT(); + break; + case 123: /* Set date */ + printf(" tid"); + UINTOUT(); + printf(" date"); + DATEOUT(); + break; + case 126: /* Set info */ + printf(" tid"); + UINTOUT(); + break; + case 128: /* Forward multiple */ + printf(" fromtrans"); + UINTOUT(); + printf(" fromdate"); + DATEOUT(); + { + unsigned long i, j; + TCHECK2(bp[0], 4); + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + for (i = 0; i < j; i++) { + DESTSERVEROUT(); + if (i != j - 1) + printf(","); + } + if (j == 0) + printf(" "); + } + break; + case 65538: /* Dump version 2 */ + printf(" fromtrans"); + UINTOUT(); + printf(" fromdate"); + DATEOUT(); + printf(" flags"); + UINTOUT(); + break; + default: + ; + } + return; + +trunc: + printf(" [|vol]"); +} + +/* + * Handle replies to the AFS Volume Service + */ + +static void +vol_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + struct rx_header *rxh; + + if (length <= (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from volser/volint.xg + */ + + printf(" vol reply %s", tok2str(vol_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, interpret the response. + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) { + switch (opcode) { + case 100: /* Create volume */ + printf(" volid"); + UINTOUT(); + printf(" trans"); + UINTOUT(); + break; + case 104: /* End transaction */ + UINTOUT(); + break; + case 105: /* Clone */ + printf(" newvol"); + UINTOUT(); + break; + case 107: /* Get flags */ + UINTOUT(); + break; + case 108: /* Transaction create */ + printf(" trans"); + UINTOUT(); + break; + case 110: /* Get n-th volume */ + printf(" volume"); + UINTOUT(); + printf(" partition"); + UINTOUT(); + break; + case 112: /* Get name */ + STROUT(AFSNAMEMAX); + break; + case 113: /* Get status */ + printf(" volid"); + UINTOUT(); + printf(" nextuniq"); + UINTOUT(); + printf(" type"); + UINTOUT(); + printf(" parentid"); + UINTOUT(); + printf(" clone"); + UINTOUT(); + printf(" backup"); + UINTOUT(); + printf(" restore"); + UINTOUT(); + printf(" maxquota"); + UINTOUT(); + printf(" minquota"); + UINTOUT(); + printf(" owner"); + UINTOUT(); + printf(" create"); + DATEOUT(); + printf(" access"); + DATEOUT(); + printf(" update"); + DATEOUT(); + printf(" expire"); + DATEOUT(); + printf(" backup"); + DATEOUT(); + printf(" copy"); + DATEOUT(); + break; + case 115: /* Old list partitions */ + break; + case 116: /* List volumes */ + case 121: /* List one volume */ + { + unsigned long i, j; + TCHECK2(bp[0], 4); + j = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + for (i = 0; i < j; i++) { + printf(" name"); + VECOUT(32); + printf(" volid"); + UINTOUT(); + printf(" type"); + bp += sizeof(int32_t) * 21; + if (i != j - 1) + printf(","); + } + if (j == 0) + printf(" "); + } + break; + + + default: + ; + } + } else { + /* + * Otherwise, just print out the return code + */ + printf(" errcode"); + INTOUT(); + } + + return; + +trunc: + printf(" [|vol]"); +} + +/* + * Handle calls to the AFS BOS service + */ + +static void +bos_print(register const u_char *bp, int length) +{ + int bos_op; + + if (length <= (int)sizeof(struct rx_header)) + return; + + if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) { + goto trunc; + } + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from bozo/bosint.xg + */ + + bos_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" bos call %s", tok2str(bos_req, "op#%d", bos_op)); + + /* + * Decode some of the arguments to the BOS calls + */ + + bp += sizeof(struct rx_header) + 4; + + switch (bos_op) { + case 80: /* Create B node */ + printf(" type"); + STROUT(BOSNAMEMAX); + printf(" instance"); + STROUT(BOSNAMEMAX); + break; + case 81: /* Delete B node */ + case 83: /* Get status */ + case 85: /* Get instance info */ + case 87: /* Add super user */ + case 88: /* Delete super user */ + case 93: /* Set cell name */ + case 96: /* Add cell host */ + case 97: /* Delete cell host */ + case 104: /* Restart */ + case 106: /* Uninstall */ + case 108: /* Exec */ + case 112: /* Getlog */ + case 114: /* Get instance strings */ + STROUT(BOSNAMEMAX); + break; + case 82: /* Set status */ + case 98: /* Set T status */ + STROUT(BOSNAMEMAX); + printf(" status"); + INTOUT(); + break; + case 86: /* Get instance parm */ + STROUT(BOSNAMEMAX); + printf(" num"); + INTOUT(); + break; + case 84: /* Enumerate instance */ + case 89: /* List super users */ + case 90: /* List keys */ + case 91: /* Add key */ + case 92: /* Delete key */ + case 95: /* Get cell host */ + INTOUT(); + break; + case 105: /* Install */ + STROUT(BOSNAMEMAX); + printf(" size"); + INTOUT(); + printf(" flags"); + INTOUT(); + printf(" date"); + INTOUT(); + break; + default: + ; + } + + return; + +trunc: + printf(" [|bos]"); +} + +/* + * Handle replies to the AFS BOS Service + */ + +static void +bos_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + struct rx_header *rxh; + + if (length <= (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from volser/volint.xg + */ + + printf(" bos reply %s", tok2str(bos_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, interpret the response. + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) + /* Well, no, not really. Leave this for later */ + ; + else { + /* + * Otherwise, just print out the return code + */ + printf(" errcode"); + INTOUT(); + } + + return; + +trunc: + printf(" [|bos]"); +} + +/* + * Check to see if this is a Ubik opcode. + */ + +static int +is_ubik(u_int32_t opcode) +{ + if ((opcode >= VOTE_LOW && opcode <= VOTE_HIGH) || + (opcode >= DISK_LOW && opcode <= DISK_HIGH)) + return(1); + else + return(0); +} + +/* + * Handle Ubik opcodes to any one of the replicated database services + */ + +static void +ubik_print(register const u_char *bp) +{ + int ubik_op; + int32_t temp; + + /* + * Print out the afs call we're invoking. The table used here was + * gleaned from ubik/ubik_int.xg + */ + + ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header)); + + printf(" ubik call %s", tok2str(ubik_req, "op#%d", ubik_op)); + + /* + * Decode some of the arguments to the Ubik calls + */ + + bp += sizeof(struct rx_header) + 4; + + switch (ubik_op) { + case 10000: /* Beacon */ + TCHECK2(bp[0], 4); + temp = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + printf(" syncsite %s", temp ? "yes" : "no"); + printf(" votestart"); + DATEOUT(); + printf(" dbversion"); + UBIK_VERSIONOUT(); + printf(" tid"); + UBIK_VERSIONOUT(); + break; + case 10003: /* Get sync site */ + printf(" site"); + UINTOUT(); + break; + case 20000: /* Begin */ + case 20001: /* Commit */ + case 20007: /* Abort */ + case 20008: /* Release locks */ + case 20010: /* Writev */ + printf(" tid"); + UBIK_VERSIONOUT(); + break; + case 20002: /* Lock */ + printf(" tid"); + UBIK_VERSIONOUT(); + printf(" file"); + INTOUT(); + printf(" pos"); + INTOUT(); + printf(" length"); + INTOUT(); + temp = EXTRACT_32BITS(bp); + bp += sizeof(int32_t); + tok2str(ubik_lock_types, "type %d", temp); + break; + case 20003: /* Write */ + printf(" tid"); + UBIK_VERSIONOUT(); + printf(" file"); + INTOUT(); + printf(" pos"); + INTOUT(); + break; + case 20005: /* Get file */ + printf(" file"); + INTOUT(); + break; + case 20006: /* Send file */ + printf(" file"); + INTOUT(); + printf(" length"); + INTOUT(); + printf(" dbversion"); + UBIK_VERSIONOUT(); + break; + case 20009: /* Truncate */ + printf(" tid"); + UBIK_VERSIONOUT(); + printf(" file"); + INTOUT(); + printf(" length"); + INTOUT(); + break; + case 20012: /* Set version */ + printf(" tid"); + UBIK_VERSIONOUT(); + printf(" oldversion"); + UBIK_VERSIONOUT(); + printf(" newversion"); + UBIK_VERSIONOUT(); + break; + default: + ; + } + + return; + +trunc: + printf(" [|ubik]"); +} + +/* + * Handle Ubik replies to any one of the replicated database services + */ + +static void +ubik_reply_print(register const u_char *bp, int length, int32_t opcode) +{ + struct rx_header *rxh; + + if (length < (int)sizeof(struct rx_header)) + return; + + rxh = (struct rx_header *) bp; + + /* + * Print out the ubik call we're invoking. This table was gleaned + * from ubik/ubik_int.xg + */ + + printf(" ubik reply %s", tok2str(ubik_req, "op#%d", opcode)); + + bp += sizeof(struct rx_header); + + /* + * If it was a data packet, print out the arguments to the Ubik calls + */ + + if (rxh->type == RX_PACKET_TYPE_DATA) + switch (opcode) { + case 10000: /* Beacon */ + printf(" vote no"); + break; + case 20004: /* Get version */ + printf(" dbversion"); + UBIK_VERSIONOUT(); + break; + default: + ; + } + + /* + * Otherwise, print out "yes" it it was a beacon packet (because + * that's how yes votes are returned, go figure), otherwise + * just print out the error code. + */ + + else + switch (opcode) { + case 10000: /* Beacon */ + printf(" vote yes until"); + DATEOUT(); + break; + default: + printf(" errcode"); + INTOUT(); + } + + return; + +trunc: + printf(" [|ubik]"); +} + +/* + * Handle RX ACK packets. + */ + +static void +rx_ack_print(register const u_char *bp, int length) +{ + struct rx_ackPacket *rxa; + int i, start, last; + u_int32_t firstPacket; + + if (length < (int)sizeof(struct rx_header)) + return; + + bp += sizeof(struct rx_header); + + /* + * This may seem a little odd .... the rx_ackPacket structure + * contains an array of individual packet acknowledgements + * (used for selective ack/nack), but since it's variable in size, + * we don't want to truncate based on the size of the whole + * rx_ackPacket structure. + */ + + TCHECK2(bp[0], sizeof(struct rx_ackPacket) - RX_MAXACKS); + + rxa = (struct rx_ackPacket *) bp; + bp += (sizeof(struct rx_ackPacket) - RX_MAXACKS); + + /* + * Print out a few useful things from the ack packet structure + */ + + if (vflag > 2) + printf(" bufspace %d maxskew %d", + (int) EXTRACT_16BITS(&rxa->bufferSpace), + (int) EXTRACT_16BITS(&rxa->maxSkew)); + + firstPacket = EXTRACT_32BITS(&rxa->firstPacket); + printf(" first %d serial %d reason %s", + firstPacket, EXTRACT_32BITS(&rxa->serial), + tok2str(rx_ack_reasons, "#%d", (int) rxa->reason)); + + /* + * Okay, now we print out the ack array. The way _this_ works + * is that we start at "first", and step through the ack array. + * If we have a contiguous range of acks/nacks, try to + * collapse them into a range. + * + * If you're really clever, you might have noticed that this + * doesn't seem quite correct. Specifically, due to structure + * padding, sizeof(struct rx_ackPacket) - RX_MAXACKS won't actually + * yield the start of the ack array (because RX_MAXACKS is 255 + * and the structure will likely get padded to a 2 or 4 byte + * boundary). However, this is the way it's implemented inside + * of AFS - the start of the extra fields are at + * sizeof(struct rx_ackPacket) - RX_MAXACKS + nAcks, which _isn't_ + * the exact start of the ack array. Sigh. That's why we aren't + * using bp, but instead use rxa->acks[]. But nAcks gets added + * to bp after this, so bp ends up at the right spot. Go figure. + */ + + if (rxa->nAcks != 0) { + + TCHECK2(bp[0], rxa->nAcks); + + /* + * Sigh, this is gross, but it seems to work to collapse + * ranges correctly. + */ + + for (i = 0, start = last = -2; i < rxa->nAcks; i++) + if (rxa->acks[i] == RX_ACK_TYPE_ACK) { + + /* + * I figured this deserved _some_ explanation. + * First, print "acked" and the packet seq + * number if this is the first time we've + * seen an acked packet. + */ + + if (last == -2) { + printf(" acked %d", + firstPacket + i); + start = i; + } + + /* + * Otherwise, if the there is a skip in + * the range (such as an nacked packet in + * the middle of some acked packets), + * then print the current packet number + * seperated from the last number by + * a comma. + */ + + else if (last != i - 1) { + printf(",%d", firstPacket + i); + start = i; + } + + /* + * We always set last to the value of + * the last ack we saw. Conversely, start + * is set to the value of the first ack + * we saw in a range. + */ + + last = i; + + /* + * Okay, this bit a code gets executed when + * we hit a nack ... in _this_ case we + * want to print out the range of packets + * that were acked, so we need to print + * the _previous_ packet number seperated + * from the first by a dash (-). Since we + * already printed the first packet above, + * just print the final packet. Don't + * do this if there will be a single-length + * range. + */ + } else if (last == i - 1 && start != last) + printf("-%d", firstPacket + i - 1); + + /* + * So, what's going on here? We ran off the end of the + * ack list, and if we got a range we need to finish it up. + * So we need to determine if the last packet in the list + * was an ack (if so, then last will be set to it) and + * we need to see if the last range didn't start with the + * last packet (because if it _did_, then that would mean + * that the packet number has already been printed and + * we don't need to print it again). + */ + + if (last == i - 1 && start != last) + printf("-%d", firstPacket + i - 1); + + /* + * Same as above, just without comments + */ + + for (i = 0, start = last = -2; i < rxa->nAcks; i++) + if (rxa->acks[i] == RX_ACK_TYPE_NACK) { + if (last == -2) { + printf(" nacked %d", + firstPacket + i); + start = i; + } else if (last != i - 1) { + printf(",%d", firstPacket + i); + start = i; + } + last = i; + } else if (last == i - 1 && start != last) + printf("-%d", firstPacket + i - 1); + + if (last == i - 1 && start != last) + printf("-%d", firstPacket + i - 1); + + bp += rxa->nAcks; + } + + + /* + * These are optional fields; depending on your version of AFS, + * you may or may not see them + */ + +#define TRUNCRET(n) if (snapend - bp + 1 <= n) return; + + if (vflag > 1) { + TRUNCRET(4); + printf(" ifmtu"); + INTOUT(); + + TRUNCRET(4); + printf(" maxmtu"); + INTOUT(); + + TRUNCRET(4); + printf(" rwind"); + INTOUT(); + + TRUNCRET(4); + printf(" maxpackets"); + INTOUT(); + } + + return; + +trunc: + printf(" [|ack]"); +} +#undef TRUNCRET diff --git a/print-sctp.c b/print-sctp.c new file mode 100644 index 0000000..0229396 --- /dev/null +++ b/print-sctp.c @@ -0,0 +1,407 @@ +/* Copyright (c) 2001 NETLAB, Temple University + * Copyright (c) 2001 Protocol Engineering Lab, University of Delaware + * + * Jerry Heinz + * John Fiore + * Armando L. Caro Jr. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-sctp.c,v 1.21 2007-09-13 18:03:49 guy Exp $ (NETLAB/PEL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "sctpHeader.h" +#include "sctpConstants.h" +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif + +#define CHAN_HP 6700 +#define CHAN_MP 6701 +#define CHAN_LP 6702 + +struct tok ForCES_channels[] = { + { CHAN_HP, "ForCES HP" }, + { CHAN_MP, "ForCES MP" }, + { CHAN_LP, "ForCES LP" }, + { 0, NULL } +}; + +static inline int isForCES_port(u_short Port) +{ + if (Port == CHAN_HP) + return 1; + if (Port == CHAN_MP) + return 1; + if (Port == CHAN_LP) + return 1; + + return 0; +} + +void sctp_print(const u_char *bp, /* beginning of sctp packet */ + const u_char *bp2, /* beginning of enclosing */ + u_int sctpPacketLength) /* ip packet */ +{ + const struct sctpHeader *sctpPktHdr; + const struct ip *ip; +#ifdef INET6 + const struct ip6_hdr *ip6; +#endif + const void *endPacketPtr; + u_short sourcePort, destPort; + int chunkCount; + const struct sctpChunkDesc *chunkDescPtr; + const void *nextChunk; + const char *sep; + int isforces = 0; + + + sctpPktHdr = (const struct sctpHeader*) bp; + endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength; + + if( (u_long) endPacketPtr > (u_long) snapend) + endPacketPtr = (const void *) snapend; + ip = (struct ip *)bp2; +#ifdef INET6 + if (IP_V(ip) == 6) + ip6 = (const struct ip6_hdr *)bp2; + else + ip6 = NULL; +#endif /*INET6*/ + TCHECK(*sctpPktHdr); + + if (sctpPacketLength < sizeof(struct sctpHeader)) + { + (void)printf("truncated-sctp - %ld bytes missing!", + (long)sctpPacketLength-sizeof(struct sctpHeader)); + return; + } + + /* sctpPacketLength -= sizeof(struct sctpHeader); packet length */ + /* is now only as long as the payload */ + + sourcePort = EXTRACT_16BITS(&sctpPktHdr->source); + destPort = EXTRACT_16BITS(&sctpPktHdr->destination); + +#ifdef INET6 + if (ip6) { + (void)printf("%s.%d > %s.%d: sctp", + ip6addr_string(&ip6->ip6_src), + sourcePort, + ip6addr_string(&ip6->ip6_dst), + destPort); + } else +#endif /*INET6*/ + { + (void)printf("%s.%d > %s.%d: sctp", + ipaddr_string(&ip->ip_src), + sourcePort, + ipaddr_string(&ip->ip_dst), + destPort); + } + fflush(stdout); + + if (isForCES_port(sourcePort)) { + printf("[%s]", tok2str(ForCES_channels, NULL, sourcePort)); + isforces = 1; + } + if (isForCES_port(destPort)) { + printf("[%s]", tok2str(ForCES_channels, NULL, destPort)); + isforces = 1; + } + + if (vflag >= 2) + sep = "\n\t"; + else + sep = " ("; + /* cycle through all chunks, printing information on each one */ + for (chunkCount = 0, + chunkDescPtr = (const struct sctpChunkDesc *) + ((const u_char*) sctpPktHdr + sizeof(struct sctpHeader)); + chunkDescPtr != NULL && + ( (const void *) + ((const u_char *) chunkDescPtr + sizeof(struct sctpChunkDesc)) + <= endPacketPtr); + + chunkDescPtr = (const struct sctpChunkDesc *) nextChunk, chunkCount++) + { + u_int16_t chunkLength; + const u_char *chunkEnd; + u_int16_t align; + + TCHECK(*chunkDescPtr); + chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength); + if (chunkLength < sizeof(*chunkDescPtr)) { + printf("%s%d) [Bad chunk length %u]", sep, chunkCount+1, chunkLength); + break; + } + + TCHECK2(*((u_int8_t *)chunkDescPtr), chunkLength); + chunkEnd = ((const u_char*)chunkDescPtr + chunkLength); + + align=chunkLength % 4; + if (align != 0) + align = 4 - align; + + nextChunk = (const void *) (chunkEnd + align); + + printf("%s%d) ", sep, chunkCount+1); + switch (chunkDescPtr->chunkID) + { + case SCTP_DATA : + { + const struct sctpDataPart *dataHdrPtr; + + printf("[DATA] "); + + if ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED) + == SCTP_DATA_UNORDERED) + printf("(U)"); + + if ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG) + == SCTP_DATA_FIRST_FRAG) + printf("(B)"); + + if ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG) + == SCTP_DATA_LAST_FRAG) + printf("(E)"); + + if( ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED) + == SCTP_DATA_UNORDERED) + || + ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG) + == SCTP_DATA_FIRST_FRAG) + || + ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG) + == SCTP_DATA_LAST_FRAG) ) + printf(" "); + + dataHdrPtr=(const struct sctpDataPart*)(chunkDescPtr+1); + + printf("[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN)); + printf("[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId)); + printf("[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence)); + printf("[PPID 0x%x] ", EXTRACT_32BITS(&dataHdrPtr->payloadtype)); + fflush(stdout); + if (isforces) { + const u_char *payloadPtr; + u_int chunksize = sizeof(struct sctpDataPart)+ + sizeof(struct sctpChunkDesc); + payloadPtr = (const u_char *) (dataHdrPtr + 1); + if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) < + sizeof(struct sctpDataPart)+ + sizeof(struct sctpChunkDesc)+1) { + /* Less than 1 byte of chunk payload */ + printf("bogus ForCES chunk length %u]", + EXTRACT_16BITS(&chunkDescPtr->chunkLength)); + return; + } + + forces_print(payloadPtr, EXTRACT_16BITS(&chunkDescPtr->chunkLength)- chunksize); + } else if (vflag >= 2) { /* if verbose output is specified */ + /* at the command line */ + const u_char *payloadPtr; + + printf("[Payload"); + + if (!suppress_default_print) { + payloadPtr = (const u_char *) (++dataHdrPtr); + printf(":"); + if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) < + sizeof(struct sctpDataPart)+ + sizeof(struct sctpChunkDesc)+1) { + /* Less than 1 byte of chunk payload */ + printf("bogus chunk length %u]", + EXTRACT_16BITS(&chunkDescPtr->chunkLength)); + return; + } + default_print(payloadPtr, + EXTRACT_16BITS(&chunkDescPtr->chunkLength) - + (sizeof(struct sctpDataPart)+ + sizeof(struct sctpChunkDesc))); + } else + printf("]"); + } + break; + } + case SCTP_INITIATION : + { + const struct sctpInitiation *init; + + printf("[INIT] "); + init=(const struct sctpInitiation*)(chunkDescPtr+1); + printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag)); + printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit)); + printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams)); + printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams)); + printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN)); + +#if(0) /* ALC you can add code for optional params here */ + if( (init+1) < chunkEnd ) + printf(" @@@@@ UNFINISHED @@@@@@%s\n", + "Optional params present, but not printed."); +#endif + break; + } + case SCTP_INITIATION_ACK : + { + const struct sctpInitiation *init; + + printf("[INIT ACK] "); + init=(const struct sctpInitiation*)(chunkDescPtr+1); + printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag)); + printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit)); + printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams)); + printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams)); + printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN)); + +#if(0) /* ALC you can add code for optional params here */ + if( (init+1) < chunkEnd ) + printf(" @@@@@ UNFINISHED @@@@@@%s\n", + "Optional params present, but not printed."); +#endif + break; + } + case SCTP_SELECTIVE_ACK: + { + const struct sctpSelectiveAck *sack; + const struct sctpSelectiveFrag *frag; + int fragNo, tsnNo; + const u_char *dupTSN; + + printf("[SACK] "); + sack=(const struct sctpSelectiveAck*)(chunkDescPtr+1); + printf("[cum ack %u] ", EXTRACT_32BITS(&sack->highestConseqTSN)); + printf("[a_rwnd %u] ", EXTRACT_32BITS(&sack->updatedRwnd)); + printf("[#gap acks %u] ", EXTRACT_16BITS(&sack->numberOfdesc)); + printf("[#dup tsns %u] ", EXTRACT_16BITS(&sack->numDupTsns)); + + + /* print gaps */ + for (frag = ( (const struct sctpSelectiveFrag *) + ((const struct sctpSelectiveAck *) sack+1)), + fragNo=0; + (const void *)frag < nextChunk && fragNo < EXTRACT_16BITS(&sack->numberOfdesc); + frag++, fragNo++) + printf("\n\t\t[gap ack block #%d: start = %u, end = %u] ", + fragNo+1, + EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart), + EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd)); + + + /* print duplicate TSNs */ + for (dupTSN = (const u_char *)frag, tsnNo=0; + (const void *) dupTSN < nextChunk && tsnNonumDupTsns); + dupTSN += 4, tsnNo++) + printf("\n\t\t[dup TSN #%u: %u] ", tsnNo+1, + EXTRACT_32BITS(dupTSN)); + + break; + } + case SCTP_HEARTBEAT_REQUEST : + { + const struct sctpHBsender *hb; + + hb=(const struct sctpHBsender*)chunkDescPtr; + + printf("[HB REQ] "); + + break; + } + case SCTP_HEARTBEAT_ACK : + printf("[HB ACK] "); + break; + case SCTP_ABORT_ASSOCIATION : + printf("[ABORT] "); + break; + case SCTP_SHUTDOWN : + printf("[SHUTDOWN] "); + break; + case SCTP_SHUTDOWN_ACK : + printf("[SHUTDOWN ACK] "); + break; + case SCTP_OPERATION_ERR : + printf("[OP ERR] "); + break; + case SCTP_COOKIE_ECHO : + printf("[COOKIE ECHO] "); + break; + case SCTP_COOKIE_ACK : + printf("[COOKIE ACK] "); + break; + case SCTP_ECN_ECHO : + printf("[ECN ECHO] "); + break; + case SCTP_ECN_CWR : + printf("[ECN CWR] "); + break; + case SCTP_SHUTDOWN_COMPLETE : + printf("[SHUTDOWN COMPLETE] "); + break; + case SCTP_FORWARD_CUM_TSN : + printf("[FOR CUM TSN] "); + break; + case SCTP_RELIABLE_CNTL : + printf("[REL CTRL] "); + break; + case SCTP_RELIABLE_CNTL_ACK : + printf("[REL CTRL ACK] "); + break; + default : + printf("[Unknown chunk type: 0x%x]", chunkDescPtr->chunkID); + return; + } + + if (vflag < 2) + sep = ", ("; + } + return; + +trunc: + printf("[|sctp]"); + return; +} diff --git a/print-sflow.c b/print-sflow.c new file mode 100644 index 0000000..baa5530 --- /dev/null +++ b/print-sflow.c @@ -0,0 +1,577 @@ +/* + * Copyright (c) 1998-2007 The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * The SFLOW protocol as per http://www.sflow.org/developers/specifications.php + * + * Original code by Carles Kishimoto + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-sflow.c,v 1.1 2007-08-08 17:20:58 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * sFlow datagram + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sflow version (2,4,5) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IP version (1 for IPv4 | 2 for IPv6) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IP Address AGENT (4 or 16 bytes) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sub agent ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Datagram sequence number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Switch uptime in ms | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | num samples in datagram | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +struct sflow_datagram_t { + u_int8_t version[4]; + u_int8_t ip_version[4]; + u_int8_t agent[4]; + u_int8_t agent_id[4]; + u_int8_t seqnum[4]; + u_int8_t uptime[4]; + u_int8_t samples[4]; +}; + +struct sflow_sample_header { + u_int8_t format[4]; + u_int8_t len[4]; +}; + +#define SFLOW_FLOW_SAMPLE 1 +#define SFLOW_COUNTER_SAMPLE 2 +#define SFLOW_EXPANDED_FLOW_SAMPLE 3 +#define SFLOW_EXPANDED_COUNTER_SAMPLE 4 + +static const struct tok sflow_format_values[] = { + { SFLOW_FLOW_SAMPLE, "flow sample" }, + { SFLOW_COUNTER_SAMPLE, "counter sample" }, + { SFLOW_EXPANDED_FLOW_SAMPLE, "expanded flow sample" }, + { SFLOW_EXPANDED_COUNTER_SAMPLE, "expanded counter sample" }, + { 0, NULL} +}; + +struct sflow_expanded_flow_sample_t { + u_int8_t seqnum[4]; + u_int8_t type[4]; + u_int8_t index[4]; + u_int8_t rate[4]; + u_int8_t pool[4]; + u_int8_t drops[4]; + u_int8_t in_interface_format[4]; + u_int8_t in_interface_value[4]; + u_int8_t out_interface_format[4]; + u_int8_t out_interface_value[4]; + u_int8_t records[4]; +}; + +#define SFLOW_FLOW_RAW_PACKET 1 +#define SFLOW_FLOW_ETHERNET_FRAME 2 +#define SFLOW_FLOW_IPV4_DATA 3 +#define SFLOW_FLOW_IPV6_DATA 4 +#define SFLOW_FLOW_EXTENDED_SWITCH_DATA 1001 +#define SFLOW_FLOW_EXTENDED_ROUTER_DATA 1002 +#define SFLOW_FLOW_EXTENDED_GATEWAY_DATA 1003 +#define SFLOW_FLOW_EXTENDED_USER_DATA 1004 +#define SFLOW_FLOW_EXTENDED_URL_DATA 1005 +#define SFLOW_FLOW_EXTENDED_MPLS_DATA 1006 +#define SFLOW_FLOW_EXTENDED_NAT_DATA 1007 +#define SFLOW_FLOW_EXTENDED_MPLS_TUNNEL 1008 +#define SFLOW_FLOW_EXTENDED_MPLS_VC 1009 +#define SFLOW_FLOW_EXTENDED_MPLS_FEC 1010 +#define SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC 1011 +#define SFLOW_FLOW_EXTENDED_VLAN_TUNNEL 1012 + +static const struct tok sflow_flow_type_values[] = { + { SFLOW_FLOW_RAW_PACKET, "Raw packet"}, + { SFLOW_FLOW_ETHERNET_FRAME, "Ethernet frame"}, + { SFLOW_FLOW_IPV4_DATA, "IPv4 Data"}, + { SFLOW_FLOW_IPV6_DATA, "IPv6 Data"}, + { SFLOW_FLOW_EXTENDED_SWITCH_DATA, "Extended Switch data"}, + { SFLOW_FLOW_EXTENDED_ROUTER_DATA, "Extended Router data"}, + { SFLOW_FLOW_EXTENDED_GATEWAY_DATA, "Extended Gateway data"}, + { SFLOW_FLOW_EXTENDED_USER_DATA, "Extended User data"}, + { SFLOW_FLOW_EXTENDED_URL_DATA, "Extended URL data"}, + { SFLOW_FLOW_EXTENDED_MPLS_DATA, "Extended MPLS data"}, + { SFLOW_FLOW_EXTENDED_NAT_DATA, "Extended NAT data"}, + { SFLOW_FLOW_EXTENDED_MPLS_TUNNEL, "Extended MPLS tunnel"}, + { SFLOW_FLOW_EXTENDED_MPLS_VC, "Extended MPLS VC"}, + { SFLOW_FLOW_EXTENDED_MPLS_FEC, "Extended MPLS FEC"}, + { SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC, "Extended MPLS LVP FEC"}, + { SFLOW_FLOW_EXTENDED_VLAN_TUNNEL, "Extended VLAN Tunnel"}, + { 0, NULL} +}; + +#define SFLOW_HEADER_PROTOCOL_ETHERNET 1 +#define SFLOW_HEADER_PROTOCOL_IPV4 11 +#define SFLOW_HEADER_PROTOCOL_IPV6 12 + +static const struct tok sflow_flow_raw_protocol_values[] = { + { SFLOW_HEADER_PROTOCOL_ETHERNET, "Ethernet"}, + { SFLOW_HEADER_PROTOCOL_IPV4, "IPv4"}, + { SFLOW_HEADER_PROTOCOL_IPV6, "IPv6"}, + { 0, NULL} +}; + +struct sflow_expanded_flow_raw_t { + u_int8_t protocol[4]; + u_int8_t length[4]; + u_int8_t stripped_bytes[4]; + u_int8_t header_size[4]; +}; + +struct sflow_expanded_counter_sample_t { + u_int8_t seqnum[4]; + u_int8_t type[4]; + u_int8_t index[4]; + u_int8_t records[4]; +}; + +#define SFLOW_COUNTER_GENERIC 1 +#define SFLOW_COUNTER_ETHERNET 2 +#define SFLOW_COUNTER_TOKEN_RING 3 +#define SFLOW_COUNTER_BASEVG 4 +#define SFLOW_COUNTER_VLAN 5 +#define SFLOW_COUNTER_PROCESSOR 1001 + +static const struct tok sflow_counter_type_values[] = { + { SFLOW_COUNTER_GENERIC, "Generic counter"}, + { SFLOW_COUNTER_ETHERNET, "Ethernet counter"}, + { SFLOW_COUNTER_TOKEN_RING, "Token ring counter"}, + { SFLOW_COUNTER_BASEVG, "100 BaseVG counter"}, + { SFLOW_COUNTER_VLAN, "Vlan counter"}, + { SFLOW_COUNTER_PROCESSOR, "Processor counter"}, + { 0, NULL} +}; + +#define SFLOW_IFACE_DIRECTION_UNKNOWN 0 +#define SFLOW_IFACE_DIRECTION_FULLDUPLEX 1 +#define SFLOW_IFACE_DIRECTION_HALFDUPLEX 2 +#define SFLOW_IFACE_DIRECTION_IN 3 +#define SFLOW_IFACE_DIRECTION_OUT 4 + +static const struct tok sflow_iface_direction_values[] = { + { SFLOW_IFACE_DIRECTION_UNKNOWN, "unknown"}, + { SFLOW_IFACE_DIRECTION_FULLDUPLEX, "full-duplex"}, + { SFLOW_IFACE_DIRECTION_HALFDUPLEX, "half-duplex"}, + { SFLOW_IFACE_DIRECTION_IN, "in"}, + { SFLOW_IFACE_DIRECTION_OUT, "out"}, + { 0, NULL} +}; + +struct sflow_generic_counter_t { + u_int8_t ifindex[4]; + u_int8_t iftype[4]; + u_int8_t ifspeed[8]; + u_int8_t ifdirection[4]; + u_int8_t ifstatus[4]; + u_int8_t ifinoctets[8]; + u_int8_t ifinunicastpkts[4]; + u_int8_t ifinmulticastpkts[4]; + u_int8_t ifinbroadcastpkts[4]; + u_int8_t ifindiscards[4]; + u_int8_t ifinerrors[4]; + u_int8_t ifinunkownprotos[4]; + u_int8_t ifoutoctets[8]; + u_int8_t ifoutunicastpkts[4]; + u_int8_t ifoutmulticastpkts[4]; + u_int8_t ifoutbroadcastpkts[4]; + u_int8_t ifoutdiscards[4]; + u_int8_t ifouterrors[4]; + u_int8_t ifpromiscmode[4]; +}; + +struct sflow_ethernet_counter_t { + u_int8_t alignerrors[4]; + u_int8_t fcserrors[4]; + u_int8_t single_collision_frames[4]; + u_int8_t multiple_collision_frames[4]; + u_int8_t test_errors[4]; + u_int8_t deferred_transmissions[4]; + u_int8_t late_collisions[4]; + u_int8_t excessive_collisions[4]; + u_int8_t mac_transmit_errors[4]; + u_int8_t carrier_sense_errors[4]; + u_int8_t frame_too_longs[4]; + u_int8_t mac_receive_errors[4]; + u_int8_t symbol_errors[4]; +}; + +struct sflow_100basevg_counter_t { + u_int8_t in_highpriority_frames[4]; + u_int8_t in_highpriority_octets[8]; + u_int8_t in_normpriority_frames[4]; + u_int8_t in_normpriority_octets[8]; + u_int8_t in_ipmerrors[4]; + u_int8_t in_oversized[4]; + u_int8_t in_data_errors[4]; + u_int8_t in_null_addressed_frames[4]; + u_int8_t out_highpriority_frames[4]; + u_int8_t out_highpriority_octets[8]; + u_int8_t transitioninto_frames[4]; + u_int8_t hc_in_highpriority_octets[8]; + u_int8_t hc_in_normpriority_octets[8]; + u_int8_t hc_out_highpriority_octets[8]; +}; + +struct sflow_vlan_counter_t { + u_int8_t vlan_id[4]; + u_int8_t octets[8]; + u_int8_t unicast_pkt[4]; + u_int8_t multicast_pkt[4]; + u_int8_t broadcast_pkt[4]; + u_int8_t discards[4]; +}; + +void +sflow_print(const u_char *pptr, u_int len) { + + const struct sflow_datagram_t *sflow_datagram; + const struct sflow_sample_header *sflow_sample; + const struct sflow_expanded_flow_sample_t *sflow_expanded_flow_sample; + const struct sflow_expanded_flow_raw_t *sflow_flow_raw; + const struct sflow_expanded_counter_sample_t *sflow_expanded_counter_sample; + const struct sflow_generic_counter_t *sflow_gen_counter; + const struct sflow_ethernet_counter_t *sflow_eth_counter; + const struct sflow_100basevg_counter_t *sflow_100basevg_counter; + const struct sflow_vlan_counter_t *sflow_vlan_counter; + const u_char *tptr; + int tlen; + u_int32_t sflow_sample_type, sflow_sample_len; + int nsamples, nrecords, counter_len, counter_type, flow_len, flow_type; + + tptr=pptr; + tlen = len; + sflow_datagram = (const struct sflow_datagram_t *)pptr; + TCHECK(*sflow_datagram); + + /* + * Sanity checking of the header. + */ + if (EXTRACT_32BITS(sflow_datagram->version) != 5) { + printf("sFlow version %u packet not supported", + EXTRACT_32BITS(sflow_datagram->version)); + return; + } + + if (vflag < 1) { + printf("sFlowv%u, %s agent %s, agent-id %u, length %u", + EXTRACT_32BITS(sflow_datagram->version), + EXTRACT_32BITS(sflow_datagram->ip_version) == 1 ? "IPv4" : "IPv6", + ipaddr_string(sflow_datagram->agent), + EXTRACT_32BITS(sflow_datagram->samples), + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + nsamples=EXTRACT_32BITS(sflow_datagram->samples); + printf("sFlowv%u, %s agent %s, agent-id %u, seqnum %u, uptime %u, samples %u, length %u", + EXTRACT_32BITS(sflow_datagram->version), + EXTRACT_32BITS(sflow_datagram->ip_version) == 1 ? "IPv4" : "IPv6", + ipaddr_string(sflow_datagram->agent), + EXTRACT_32BITS(sflow_datagram->agent_id), + EXTRACT_32BITS(sflow_datagram->seqnum), + EXTRACT_32BITS(sflow_datagram->uptime), + nsamples, + len); + + /* skip Common header */ + tptr+=sizeof(const struct sflow_datagram_t); + tlen-=sizeof(const struct sflow_datagram_t); + + while (nsamples > 0 && tlen > 0) { + sflow_sample = (const struct sflow_sample_header *)tptr; + sflow_sample_type = (EXTRACT_32BITS(sflow_sample->format)&0x0FFF); + sflow_sample_len = EXTRACT_32BITS(sflow_sample->len); + + tptr+=sizeof(struct sflow_sample_header); + tlen-=sizeof(struct sflow_sample_header); + + printf("\n\t%s (%u), length %u,", + tok2str(sflow_format_values, "Unknown", sflow_sample_type), + sflow_sample_type, + sflow_sample_len); + + /* basic sanity check */ + if (sflow_sample_type == 0 || sflow_sample_len ==0) { + return; + } + + /* did we capture enough for fully decoding the sample ? */ + if (!TTEST2(*tptr, sflow_sample_len)) + goto trunc; + + switch(sflow_sample_type) { + case SFLOW_FLOW_SAMPLE: /* XXX */ + break; + + case SFLOW_COUNTER_SAMPLE: /* XXX */ + break; + + case SFLOW_EXPANDED_FLOW_SAMPLE: + sflow_expanded_flow_sample = (const struct sflow_expanded_flow_sample_t *)tptr; + nrecords = EXTRACT_32BITS(sflow_expanded_flow_sample->records); + + printf(" seqnum %u, type %u, idx %u, rate %u, pool %u, drops %u, records %u", + EXTRACT_32BITS(sflow_expanded_flow_sample->seqnum), + EXTRACT_32BITS(sflow_expanded_flow_sample->type), + EXTRACT_32BITS(sflow_expanded_flow_sample->index), + EXTRACT_32BITS(sflow_expanded_flow_sample->rate), + EXTRACT_32BITS(sflow_expanded_flow_sample->pool), + EXTRACT_32BITS(sflow_expanded_flow_sample->drops), + EXTRACT_32BITS(sflow_expanded_flow_sample->records)); + + tptr+= sizeof(struct sflow_expanded_flow_sample_t); + tlen-= sizeof(struct sflow_expanded_flow_sample_t); + + while ( nrecords > 0 && tlen > 0) { + + /* decode Flow record - 2 bytes */ + flow_type = EXTRACT_32BITS(tptr)&0x0FFF; + flow_len = EXTRACT_32BITS(tptr+4); + printf("\n\t %s (%u) length %u", + tok2str(sflow_flow_type_values,"Unknown",flow_type), + flow_type, + flow_len); + + tptr += 8; + tlen -= 8; + + /* did we capture enough for fully decoding the flow ? */ + if (!TTEST2(*tptr, flow_len)) + goto trunc; + + switch(flow_type) { + case SFLOW_FLOW_RAW_PACKET: + sflow_flow_raw = (const struct sflow_expanded_flow_raw_t *)tptr; + printf("\n\t protocol %s (%u), length %u, stripped bytes %u, header_size %u", + tok2str(sflow_flow_raw_protocol_values,"Unknown",EXTRACT_32BITS(sflow_flow_raw->protocol)), + EXTRACT_32BITS(sflow_flow_raw->protocol), + EXTRACT_32BITS(sflow_flow_raw->length), + EXTRACT_32BITS(sflow_flow_raw->stripped_bytes), + EXTRACT_32BITS(sflow_flow_raw->header_size)); + break; + + /* + * FIXME those are the defined flow types that lack a decoder + */ + case SFLOW_FLOW_ETHERNET_FRAME: + case SFLOW_FLOW_IPV4_DATA: + case SFLOW_FLOW_IPV6_DATA: + case SFLOW_FLOW_EXTENDED_SWITCH_DATA: + case SFLOW_FLOW_EXTENDED_ROUTER_DATA: + case SFLOW_FLOW_EXTENDED_GATEWAY_DATA: + case SFLOW_FLOW_EXTENDED_USER_DATA: + case SFLOW_FLOW_EXTENDED_URL_DATA: + case SFLOW_FLOW_EXTENDED_MPLS_DATA: + case SFLOW_FLOW_EXTENDED_NAT_DATA: + case SFLOW_FLOW_EXTENDED_MPLS_TUNNEL: + case SFLOW_FLOW_EXTENDED_MPLS_VC: + case SFLOW_FLOW_EXTENDED_MPLS_FEC: + case SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC: + case SFLOW_FLOW_EXTENDED_VLAN_TUNNEL: + break; + default: + if (vflag <= 1) + print_unknown_data(tptr, "\n\t ", flow_len); + break; + + } + tptr += flow_len; + tlen -= flow_len; + nrecords--; + } + break; + + case SFLOW_EXPANDED_COUNTER_SAMPLE: + sflow_expanded_counter_sample = (const struct sflow_expanded_counter_sample_t *)tptr; + nrecords = EXTRACT_32BITS(sflow_expanded_counter_sample->records); + + printf(" seqnum %u, type %u, idx %u, records %u", + EXTRACT_32BITS(sflow_expanded_counter_sample->seqnum), + EXTRACT_32BITS(sflow_expanded_counter_sample->type), + EXTRACT_32BITS(sflow_expanded_counter_sample->index), + nrecords); + + tptr+= sizeof(struct sflow_expanded_counter_sample_t); + tlen-= sizeof(struct sflow_expanded_counter_sample_t); + + while ( nrecords > 0 && tlen > 0) { + + /* decode counter record - 2 bytes */ + counter_type = EXTRACT_32BITS(tptr)&0x0FFF; + counter_len = EXTRACT_32BITS(tptr+4); + printf("\n\t %s (%u) length %u", + tok2str(sflow_counter_type_values,"Unknown",counter_type), + counter_type, + counter_len); + + tptr += 8; + tlen -= 8; + + /* did we capture enough for fully decoding the counter ? */ + if (!TTEST2(*tptr, counter_len)) + goto trunc; + + switch(counter_type) { + case SFLOW_COUNTER_GENERIC: + sflow_gen_counter = (const struct sflow_generic_counter_t *)tptr; + printf("\n\t ifindex %u, iftype %u, ifspeed %u, ifdirection %u (%s)", + EXTRACT_32BITS(sflow_gen_counter->ifindex), + EXTRACT_32BITS(sflow_gen_counter->iftype), + EXTRACT_32BITS(sflow_gen_counter->ifspeed), + EXTRACT_32BITS(sflow_gen_counter->ifdirection), + tok2str(sflow_iface_direction_values, "Unknown", + EXTRACT_32BITS(sflow_gen_counter->ifdirection))); + printf("\n\t ifstatus %u, adminstatus: %s, operstatus: %s", + EXTRACT_32BITS(sflow_gen_counter->ifstatus), + EXTRACT_32BITS(sflow_gen_counter->ifstatus)&1 ? "up" : "down", + (EXTRACT_32BITS(sflow_gen_counter->ifstatus)>>1)&1 ? "up" : "down"); + printf("\n\t In octets %" PRIu64 + ", unicast pkts %u, multicast pkts %u, broadcast pkts %u, discards %u", + EXTRACT_64BITS(sflow_gen_counter->ifinoctets), + EXTRACT_32BITS(sflow_gen_counter->ifinunicastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifinmulticastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifinbroadcastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifindiscards)); + printf("\n\t In errors %u, unknown protos %u", + EXTRACT_32BITS(sflow_gen_counter->ifinerrors), + EXTRACT_32BITS(sflow_gen_counter->ifinunkownprotos)); + printf("\n\t Out octets %" PRIu64 + ", unicast pkts %u, multicast pkts %u, broadcast pkts %u, discards %u", + EXTRACT_64BITS(sflow_gen_counter->ifoutoctets), + EXTRACT_32BITS(sflow_gen_counter->ifoutunicastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifoutmulticastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifoutbroadcastpkts), + EXTRACT_32BITS(sflow_gen_counter->ifoutdiscards)); + printf("\n\t Out errors %u, promisc mode %u", + EXTRACT_32BITS(sflow_gen_counter->ifouterrors), + EXTRACT_32BITS(sflow_gen_counter->ifpromiscmode)); + break; + case SFLOW_COUNTER_ETHERNET: + sflow_eth_counter = (const struct sflow_ethernet_counter_t *)tptr; + printf("\n\t align errors %u, fcs errors %u, single collision %u, multiple collision %u, test error %u", + EXTRACT_32BITS(sflow_eth_counter->alignerrors), + EXTRACT_32BITS(sflow_eth_counter->fcserrors), + EXTRACT_32BITS(sflow_eth_counter->single_collision_frames), + EXTRACT_32BITS(sflow_eth_counter->multiple_collision_frames), + EXTRACT_32BITS(sflow_eth_counter->test_errors)); + printf("\n\t deferred %u, late collision %u, excessive collision %u, mac trans error %u", + EXTRACT_32BITS(sflow_eth_counter->deferred_transmissions), + EXTRACT_32BITS(sflow_eth_counter->late_collisions), + EXTRACT_32BITS(sflow_eth_counter->excessive_collisions), + EXTRACT_32BITS(sflow_eth_counter->mac_transmit_errors)); + printf("\n\t carrier error %u, frames too long %u, mac receive errors %u, symbol errors %u", + EXTRACT_32BITS(sflow_eth_counter->carrier_sense_errors), + EXTRACT_32BITS(sflow_eth_counter->frame_too_longs), + EXTRACT_32BITS(sflow_eth_counter->mac_receive_errors), + EXTRACT_32BITS(sflow_eth_counter->symbol_errors)); + break; + case SFLOW_COUNTER_TOKEN_RING: /* XXX */ + break; + case SFLOW_COUNTER_BASEVG: + sflow_100basevg_counter = (const struct sflow_100basevg_counter_t *)tptr; + printf("\n\t in high prio frames %u, in high prio octets %" PRIu64, + EXTRACT_32BITS(sflow_100basevg_counter->in_highpriority_frames), + EXTRACT_64BITS(sflow_100basevg_counter->in_highpriority_octets)); + printf("\n\t in norm prio frames %u, in norm prio octets %" PRIu64, + EXTRACT_32BITS(sflow_100basevg_counter->in_normpriority_frames), + EXTRACT_64BITS(sflow_100basevg_counter->in_normpriority_octets)); + printf("\n\t in ipm errors %u, oversized %u, in data errors %u, null addressed frames %u", + EXTRACT_32BITS(sflow_100basevg_counter->in_ipmerrors), + EXTRACT_32BITS(sflow_100basevg_counter->in_oversized), + EXTRACT_32BITS(sflow_100basevg_counter->in_data_errors), + EXTRACT_32BITS(sflow_100basevg_counter->in_null_addressed_frames)); + printf("\n\t out high prio frames %u, out high prio octets %" PRIu64 + ", trans into frames %u", + EXTRACT_32BITS(sflow_100basevg_counter->out_highpriority_frames), + EXTRACT_64BITS(sflow_100basevg_counter->out_highpriority_octets), + EXTRACT_32BITS(sflow_100basevg_counter->transitioninto_frames)); + printf("\n\t in hc high prio octets %" PRIu64 + ", in hc norm prio octets %" PRIu64 + ", out hc high prio octets %" PRIu64, + EXTRACT_64BITS(sflow_100basevg_counter->hc_in_highpriority_octets), + EXTRACT_64BITS(sflow_100basevg_counter->hc_in_normpriority_octets), + EXTRACT_64BITS(sflow_100basevg_counter->hc_out_highpriority_octets)); + break; + case SFLOW_COUNTER_VLAN: + sflow_vlan_counter = (const struct sflow_vlan_counter_t *)tptr; + printf("\n\t vlan_id %u, octets %" PRIu64 + ", unicast_pkt %u, multicast_pkt %u, broadcast_pkt %u, discards %u", + EXTRACT_32BITS(sflow_vlan_counter->vlan_id), + EXTRACT_64BITS(sflow_vlan_counter->octets), + EXTRACT_32BITS(sflow_vlan_counter->unicast_pkt), + EXTRACT_32BITS(sflow_vlan_counter->multicast_pkt), + EXTRACT_32BITS(sflow_vlan_counter->broadcast_pkt), + EXTRACT_32BITS(sflow_vlan_counter->discards)); + break; + case SFLOW_COUNTER_PROCESSOR: /* XXX */ + break; + default: + if (vflag <= 1) + print_unknown_data(tptr, "\n\t\t", counter_len); + break; + } + tptr += counter_len; + tlen -= counter_len; + nrecords--; + } + break; + default: + if (vflag <= 1) + print_unknown_data(tptr, "\n\t ", sflow_sample_len); + break; + } + tptr += sflow_sample_len; + tlen -= sflow_sample_len; + nsamples--; + } + return; + + trunc: + printf("[|SFLOW]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/print-sip.c b/print-sip.c new file mode 100644 index 0000000..c5bc853 --- /dev/null +++ b/print-sip.c @@ -0,0 +1,64 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-sip.c,v 1.1 2004-07-27 17:04:20 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "extract.h" + +#include "udp.h" + +void +sip_print(register const u_char *pptr, register u_int len) +{ + u_int idx; + + printf("SIP, length: %u%s", len, vflag ? "\n\t" : ""); + + /* in non-verbose mode just lets print the protocol and length */ + if (vflag < 1) + return; + + for (idx = 0; idx < len; idx++) { + TCHECK2(*(pptr+idx), 2); + if (EXTRACT_16BITS(pptr+idx) != 0x0d0a) { /* linefeed ? */ + safeputchar(*(pptr+idx)); + } else { + printf("\n\t"); + idx+=1; + } + } + + /* do we want to see an additionally hexdump ? */ + if (vflag> 1) + print_unknown_data(pptr,"\n\t",len); + + return; + +trunc: + printf("[|sip]"); +} diff --git a/print-sl.c b/print-sl.c new file mode 100644 index 0000000..f00d394 --- /dev/null +++ b/print-sl.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-sl.c,v 1.65 2005-04-06 21:32:42 mcr Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" /* must come after interface.h */ + +#include "ip.h" +#include "tcp.h" +#include "slip.h" +#include "slcompress.h" + +static u_int lastlen[2][256]; +static u_int lastconn = 255; + +static void sliplink_print(const u_char *, const struct ip *, u_int); +static void compressed_sl_print(const u_char *, const struct ip *, u_int, int); + +u_int +sl_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + register u_int caplen = h->caplen; + register u_int length = h->len; + register const struct ip *ip; + + if (caplen < SLIP_HDRLEN) { + printf("[|slip]"); + return (caplen); + } + + length -= SLIP_HDRLEN; + + ip = (struct ip *)(p + SLIP_HDRLEN); + + if (eflag) + sliplink_print(p, ip, length); + + switch (IP_V(ip)) { + case 4: + ip_print(gndo, (u_char *)ip, length); + break; +#ifdef INET6 + case 6: + ip6_print((u_char *)ip, length); + break; +#endif + default: + printf ("ip v%d", IP_V(ip)); + } + + return (SLIP_HDRLEN); +} + +u_int +sl_bsdos_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + register u_int caplen = h->caplen; + register u_int length = h->len; + register const struct ip *ip; + + if (caplen < SLIP_HDRLEN) { + printf("[|slip]"); + return (caplen); + } + + length -= SLIP_HDRLEN; + + ip = (struct ip *)(p + SLIP_HDRLEN); + +#ifdef notdef + if (eflag) + sliplink_print(p, ip, length); +#endif + + ip_print(gndo, (u_char *)ip, length); + + return (SLIP_HDRLEN); +} + +static void +sliplink_print(register const u_char *p, register const struct ip *ip, + register u_int length) +{ + int dir; + u_int hlen; + + dir = p[SLX_DIR]; + putchar(dir == SLIPDIR_IN ? 'I' : 'O'); + putchar(' '); + + if (nflag) { + /* XXX just dump the header */ + register int i; + + for (i = SLX_CHDR; i < SLX_CHDR + CHDR_LEN - 1; ++i) + printf("%02x.", p[i]); + printf("%02x: ", p[SLX_CHDR + CHDR_LEN - 1]); + return; + } + switch (p[SLX_CHDR] & 0xf0) { + + case TYPE_IP: + printf("ip %d: ", length + SLIP_HDRLEN); + break; + + case TYPE_UNCOMPRESSED_TCP: + /* + * The connection id is stored in the IP protocol field. + * Get it from the link layer since sl_uncompress_tcp() + * has restored the IP header copy to IPPROTO_TCP. + */ + lastconn = ((struct ip *)&p[SLX_CHDR])->ip_p; + hlen = IP_HL(ip); + hlen += TH_OFF((struct tcphdr *)&((int *)ip)[hlen]); + lastlen[dir][lastconn] = length - (hlen << 2); + printf("utcp %d: ", lastconn); + break; + + default: + if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) { + compressed_sl_print(&p[SLX_CHDR], ip, + length, dir); + printf(": "); + } else + printf("slip-%d!: ", p[SLX_CHDR]); + } +} + +static const u_char * +print_sl_change(const char *str, register const u_char *cp) +{ + register u_int i; + + if ((i = *cp++) == 0) { + i = EXTRACT_16BITS(cp); + cp += 2; + } + printf(" %s%d", str, i); + return (cp); +} + +static const u_char * +print_sl_winchange(register const u_char *cp) +{ + register short i; + + if ((i = *cp++) == 0) { + i = EXTRACT_16BITS(cp); + cp += 2; + } + if (i >= 0) + printf(" W+%d", i); + else + printf(" W%d", i); + return (cp); +} + +static void +compressed_sl_print(const u_char *chdr, const struct ip *ip, + u_int length, int dir) +{ + register const u_char *cp = chdr; + register u_int flags, hlen; + + flags = *cp++; + if (flags & NEW_C) { + lastconn = *cp++; + printf("ctcp %d", lastconn); + } else + printf("ctcp *"); + + /* skip tcp checksum */ + cp += 2; + + switch (flags & SPECIALS_MASK) { + case SPECIAL_I: + printf(" *SA+%d", lastlen[dir][lastconn]); + break; + + case SPECIAL_D: + printf(" *S+%d", lastlen[dir][lastconn]); + break; + + default: + if (flags & NEW_U) + cp = print_sl_change("U=", cp); + if (flags & NEW_W) + cp = print_sl_winchange(cp); + if (flags & NEW_A) + cp = print_sl_change("A+", cp); + if (flags & NEW_S) + cp = print_sl_change("S+", cp); + break; + } + if (flags & NEW_I) + cp = print_sl_change("I+", cp); + + /* + * 'hlen' is the length of the uncompressed TCP/IP header (in words). + * 'cp - chdr' is the length of the compressed header. + * 'length - hlen' is the amount of data in the packet. + */ + hlen = IP_HL(ip); + hlen += TH_OFF((struct tcphdr *)&((int32_t *)ip)[hlen]); + lastlen[dir][lastconn] = length - (hlen << 2); + printf(" %d (%ld)", lastlen[dir][lastconn], (long)(cp - chdr)); +} diff --git a/print-sll.c b/print-sll.c new file mode 100644 index 0000000..c954658 --- /dev/null +++ b/print-sll.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-sll.c,v 1.19 2005-11-13 12:12:43 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "ethertype.h" +#include "extract.h" + +#include "ether.h" +#include "sll.h" + +const struct tok sll_pkttype_values[] = { + { LINUX_SLL_HOST, "In" }, + { LINUX_SLL_BROADCAST, "B" }, + { LINUX_SLL_MULTICAST, "M" }, + { LINUX_SLL_OTHERHOST, "P" }, + { LINUX_SLL_OUTGOING, "Out" }, + { 0, NULL} +}; + +static inline void +sll_print(register const struct sll_header *sllp, u_int length) +{ + u_short ether_type; + + printf("%3s ",tok2str(sll_pkttype_values,"?",EXTRACT_16BITS(&sllp->sll_pkttype))); + + /* + * XXX - check the link-layer address type value? + * For now, we just assume 6 means Ethernet. + * XXX - print others as strings of hex? + */ + if (EXTRACT_16BITS(&sllp->sll_halen) == 6) + (void)printf("%s ", etheraddr_string(sllp->sll_addr)); + + if (!qflag) { + ether_type = EXTRACT_16BITS(&sllp->sll_protocol); + + if (ether_type <= ETHERMTU) { + /* + * Not an Ethernet type; what type is it? + */ + switch (ether_type) { + + case LINUX_SLL_P_802_3: + /* + * Ethernet_802.3 IPX frame. + */ + (void)printf("802.3"); + break; + + case LINUX_SLL_P_802_2: + /* + * 802.2. + */ + (void)printf("802.2"); + break; + + default: + /* + * What is it? + */ + (void)printf("ethertype Unknown (0x%04x)", + ether_type); + break; + } + } else { + (void)printf("ethertype %s (0x%04x)", + tok2str(ethertype_values, "Unknown", ether_type), + ether_type); + } + (void)printf(", length %u: ", length); + } +} + +/* + * This is the top level routine of the printer. 'p' points to the + * Linux "cooked capture" header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +sll_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + register const struct sll_header *sllp; + u_short ether_type; + u_short extracted_ethertype; + + if (caplen < SLL_HDR_LEN) { + /* + * XXX - this "can't happen" because "pcap-linux.c" always + * adds this many bytes of header to every packet in a + * cooked socket capture. + */ + printf("[|sll]"); + return (caplen); + } + + sllp = (const struct sll_header *)p; + + if (eflag) + sll_print(sllp, length); + + /* + * Go past the cooked-mode header. + */ + length -= SLL_HDR_LEN; + caplen -= SLL_HDR_LEN; + p += SLL_HDR_LEN; + + ether_type = EXTRACT_16BITS(&sllp->sll_protocol); + +recurse: + /* + * Is it (gag) an 802.3 encapsulation, or some non-Ethernet + * packet type? + */ + if (ether_type <= ETHERMTU) { + /* + * Yes - what type is it? + */ + switch (ether_type) { + + case LINUX_SLL_P_802_3: + /* + * Ethernet_802.3 IPX frame. + */ + ipx_print(p, length); + break; + + case LINUX_SLL_P_802_2: + /* + * 802.2. + * Try to print the LLC-layer header & higher layers. + */ + if (llc_print(p, length, caplen, NULL, NULL, + &extracted_ethertype) == 0) + goto unknown; /* unknown LLC type */ + break; + + default: + extracted_ethertype = 0; + /*FALLTHROUGH*/ + + unknown: + /* ether_type not known, print raw packet */ + if (!eflag) + sll_print(sllp, length + SLL_HDR_LEN); + if (extracted_ethertype) { + printf("(LLC %s) ", + etherproto_string(htons(extracted_ethertype))); + } + if (!suppress_default_print) + default_print(p, caplen); + break; + } + } else if (ether_type == ETHERTYPE_8021Q) { + /* + * Print VLAN information, and then go back and process + * the enclosed type field. + */ + if (caplen < 4 || length < 4) { + printf("[|vlan]"); + return (SLL_HDR_LEN); + } + if (eflag) { + u_int16_t tag = EXTRACT_16BITS(p); + + printf("vlan %u, p %u%s, ", + tag & 0xfff, + tag >> 13, + (tag & 0x1000) ? ", CFI" : ""); + } + + ether_type = EXTRACT_16BITS(p + 2); + if (ether_type <= ETHERMTU) + ether_type = LINUX_SLL_P_802_2; + if (!qflag) { + (void)printf("ethertype %s, ", + tok2str(ethertype_values, "Unknown", ether_type)); + } + p += 4; + length -= 4; + caplen -= 4; + goto recurse; + } else { + if (ethertype_print(ether_type, p, length, caplen) == 0) { + /* ether_type not known, print raw packet */ + if (!eflag) + sll_print(sllp, length + SLL_HDR_LEN); + if (!suppress_default_print) + default_print(p, caplen); + } + } + + return (SLL_HDR_LEN); +} diff --git a/print-slow.c b/print-slow.c new file mode 100644 index 0000000..eaf94ed --- /dev/null +++ b/print-slow.c @@ -0,0 +1,661 @@ +/* + * Copyright (c) 1998-2006 The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * support for the IEEE "slow protocols" LACP, MARKER as per 802.3ad + * OAM as per 802.3ah + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-slow.c,v 1.8 2006-10-12 05:44:33 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ether.h" +#include "oui.h" + +struct slow_common_header_t { + u_int8_t proto_subtype; + u_int8_t version; +}; + +#define SLOW_PROTO_LACP 1 +#define SLOW_PROTO_MARKER 2 +#define SLOW_PROTO_OAM 3 + +#define LACP_VERSION 1 +#define MARKER_VERSION 1 + +static const struct tok slow_proto_values[] = { + { SLOW_PROTO_LACP, "LACP" }, + { SLOW_PROTO_MARKER, "MARKER" }, + { SLOW_PROTO_OAM, "OAM" }, + { 0, NULL} +}; + +static const struct tok slow_oam_flag_values[] = { + { 0x0001, "Link Fault" }, + { 0x0002, "Dying Gasp" }, + { 0x0004, "Critical Event" }, + { 0x0008, "Local Evaluating" }, + { 0x0010, "Local Stable" }, + { 0x0020, "Remote Evaluating" }, + { 0x0040, "Remote Stable" }, + { 0, NULL} +}; + +#define SLOW_OAM_CODE_INFO 0x00 +#define SLOW_OAM_CODE_EVENT_NOTIF 0x01 +#define SLOW_OAM_CODE_VAR_REQUEST 0x02 +#define SLOW_OAM_CODE_VAR_RESPONSE 0x03 +#define SLOW_OAM_CODE_LOOPBACK_CTRL 0x04 +#define SLOW_OAM_CODE_PRIVATE 0xfe + +static const struct tok slow_oam_code_values[] = { + { SLOW_OAM_CODE_INFO, "Information" }, + { SLOW_OAM_CODE_EVENT_NOTIF, "Event Notification" }, + { SLOW_OAM_CODE_VAR_REQUEST, "Variable Request" }, + { SLOW_OAM_CODE_VAR_RESPONSE, "Variable Response" }, + { SLOW_OAM_CODE_LOOPBACK_CTRL, "Loopback Control" }, + { SLOW_OAM_CODE_PRIVATE, "Vendor Private" }, + { 0, NULL} +}; + +struct slow_oam_info_t { + u_int8_t info_type; + u_int8_t info_length; + u_int8_t oam_version; + u_int8_t revision[2]; + u_int8_t state; + u_int8_t oam_config; + u_int8_t oam_pdu_config[2]; + u_int8_t oui[3]; + u_int8_t vendor_private[4]; +}; + +#define SLOW_OAM_INFO_TYPE_END_OF_TLV 0x00 +#define SLOW_OAM_INFO_TYPE_LOCAL 0x01 +#define SLOW_OAM_INFO_TYPE_REMOTE 0x02 +#define SLOW_OAM_INFO_TYPE_ORG_SPECIFIC 0xfe + +static const struct tok slow_oam_info_type_values[] = { + { SLOW_OAM_INFO_TYPE_END_OF_TLV, "End of TLV marker" }, + { SLOW_OAM_INFO_TYPE_LOCAL, "Local" }, + { SLOW_OAM_INFO_TYPE_REMOTE, "Remote" }, + { SLOW_OAM_INFO_TYPE_ORG_SPECIFIC, "Organization specific" }, + { 0, NULL} +}; + +#define OAM_INFO_TYPE_PARSER_MASK 0x3 +static const struct tok slow_oam_info_type_state_parser_values[] = { + { 0x00, "forwarding" }, + { 0x01, "looping back" }, + { 0x02, "discarding" }, + { 0x03, "reserved" }, + { 0, NULL} +}; + +#define OAM_INFO_TYPE_MUX_MASK 0x4 +static const struct tok slow_oam_info_type_state_mux_values[] = { + { 0x00, "forwarding" }, + { 0x04, "discarding" }, + { 0, NULL} +}; + +static const struct tok slow_oam_info_type_oam_config_values[] = { + { 0x01, "Active" }, + { 0x02, "Unidirectional" }, + { 0x04, "Remote-Loopback" }, + { 0x08, "Link-Events" }, + { 0x10, "Variable-Retrieval" }, + { 0, NULL} +}; + +/* 11 Bits */ +#define OAM_INFO_TYPE_PDU_SIZE_MASK 0x7ff + +#define SLOW_OAM_LINK_EVENT_END_OF_TLV 0x00 +#define SLOW_OAM_LINK_EVENT_ERR_SYM_PER 0x01 +#define SLOW_OAM_LINK_EVENT_ERR_FRM 0x02 +#define SLOW_OAM_LINK_EVENT_ERR_FRM_PER 0x03 +#define SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM 0x04 +#define SLOW_OAM_LINK_EVENT_ORG_SPECIFIC 0xfe + +static const struct tok slow_oam_link_event_values[] = { + { SLOW_OAM_LINK_EVENT_END_OF_TLV, "End of TLV marker" }, + { SLOW_OAM_LINK_EVENT_ERR_SYM_PER, "Errored Symbol Period Event" }, + { SLOW_OAM_LINK_EVENT_ERR_FRM, "Errored Frame Event" }, + { SLOW_OAM_LINK_EVENT_ERR_FRM_PER, "Errored Frame Period Event" }, + { SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM, "Errored Frame Seconds Summary Event" }, + { SLOW_OAM_LINK_EVENT_ORG_SPECIFIC, "Organization specific" }, + { 0, NULL} +}; + +struct slow_oam_link_event_t { + u_int8_t event_type; + u_int8_t event_length; + u_int8_t time_stamp[2]; + u_int8_t window[8]; + u_int8_t threshold[8]; + u_int8_t errors[8]; + u_int8_t errors_running_total[8]; + u_int8_t event_running_total[4]; +}; + +struct slow_oam_variablerequest_t { + u_int8_t branch; + u_int8_t leaf[2]; +}; + +struct slow_oam_variableresponse_t { + u_int8_t branch; + u_int8_t leaf[2]; + u_int8_t length; +}; + +struct slow_oam_loopbackctrl_t { + u_int8_t command; +}; + +static const struct tok slow_oam_loopbackctrl_cmd_values[] = { + { 0x01, "Enable OAM Remote Loopback" }, + { 0x02, "Disable OAM Remote Loopback" }, + { 0, NULL} +}; + +struct tlv_header_t { + u_int8_t type; + u_int8_t length; +}; + +#define LACP_TLV_TERMINATOR 0x00 +#define LACP_TLV_ACTOR_INFO 0x01 +#define LACP_TLV_PARTNER_INFO 0x02 +#define LACP_TLV_COLLECTOR_INFO 0x03 + +#define MARKER_TLV_TERMINATOR 0x00 +#define MARKER_TLV_MARKER_INFO 0x01 + +static const struct tok slow_tlv_values[] = { + { (SLOW_PROTO_LACP << 8) + LACP_TLV_TERMINATOR, "Terminator"}, + { (SLOW_PROTO_LACP << 8) + LACP_TLV_ACTOR_INFO, "Actor Information"}, + { (SLOW_PROTO_LACP << 8) + LACP_TLV_PARTNER_INFO, "Partner Information"}, + { (SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO, "Collector Information"}, + + { (SLOW_PROTO_MARKER << 8) + MARKER_TLV_TERMINATOR, "Terminator"}, + { (SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO, "Marker Information"}, + { 0, NULL} +}; + +struct lacp_tlv_actor_partner_info_t { + u_int8_t sys_pri[2]; + u_int8_t sys[ETHER_ADDR_LEN]; + u_int8_t key[2]; + u_int8_t port_pri[2]; + u_int8_t port[2]; + u_int8_t state; + u_int8_t pad[3]; +}; + +static const struct tok lacp_tlv_actor_partner_info_state_values[] = { + { 0x01, "Activity"}, + { 0x02, "Timeout"}, + { 0x04, "Aggregation"}, + { 0x08, "Synchronization"}, + { 0x10, "Collecting"}, + { 0x20, "Distributing"}, + { 0x40, "Default"}, + { 0x80, "Expired"}, + { 0, NULL} +}; + +struct lacp_tlv_collector_info_t { + u_int8_t max_delay[2]; + u_int8_t pad[12]; +}; + +struct marker_tlv_marker_info_t { + u_int8_t req_port[2]; + u_int8_t req_sys[ETHER_ADDR_LEN]; + u_int8_t req_trans_id[4]; + u_int8_t pad[2]; +}; + +struct lacp_marker_tlv_terminator_t { + u_int8_t pad[50]; +}; + +void slow_marker_lacp_print(register const u_char *, register u_int); +void slow_oam_print(register const u_char *, register u_int); + +const struct slow_common_header_t *slow_com_header; + +void +slow_print(register const u_char *pptr, register u_int len) { + + int print_version; + + slow_com_header = (const struct slow_common_header_t *)pptr; + TCHECK(*slow_com_header); + + /* + * Sanity checking of the header. + */ + switch (slow_com_header->proto_subtype) { + case SLOW_PROTO_LACP: + if (slow_com_header->version != LACP_VERSION) { + printf("LACP version %u packet not supported",slow_com_header->version); + return; + } + print_version = 1; + break; + + case SLOW_PROTO_MARKER: + if (slow_com_header->version != MARKER_VERSION) { + printf("MARKER version %u packet not supported",slow_com_header->version); + return; + } + print_version = 1; + break; + + case SLOW_PROTO_OAM: /* fall through */ + print_version = 0; + break; + + default: + /* print basic information and exit */ + print_version = -1; + break; + } + + if (print_version) { + printf("%sv%u, length %u", + tok2str(slow_proto_values, "unknown (%u)",slow_com_header->proto_subtype), + slow_com_header->version, + len); + } else { + /* some slow protos don't have a version number in the header */ + printf("%s, length %u", + tok2str(slow_proto_values, "unknown (%u)",slow_com_header->proto_subtype), + len); + } + + /* unrecognized subtype */ + if (print_version == -1) { + print_unknown_data(pptr, "\n\t", len); + return; + } + + if (!vflag) + return; + + switch (slow_com_header->proto_subtype) { + default: /* should not happen */ + break; + + case SLOW_PROTO_OAM: + /* skip proto_subtype */ + slow_oam_print(pptr+1, len-1); + break; + + case SLOW_PROTO_LACP: /* LACP and MARKER share the same semantics */ + case SLOW_PROTO_MARKER: + /* skip slow_common_header */ + len -= sizeof(const struct slow_common_header_t); + pptr += sizeof(const struct slow_common_header_t); + slow_marker_lacp_print(pptr, len); + break; + } + return; + +trunc: + printf("\n\t\t packet exceeded snapshot"); +} + +void slow_marker_lacp_print(register const u_char *tptr, register u_int tlen) { + + const struct tlv_header_t *tlv_header; + const u_char *tlv_tptr; + u_int tlv_len, tlv_tlen; + + union { + const struct lacp_marker_tlv_terminator_t *lacp_marker_tlv_terminator; + const struct lacp_tlv_actor_partner_info_t *lacp_tlv_actor_partner_info; + const struct lacp_tlv_collector_info_t *lacp_tlv_collector_info; + const struct marker_tlv_marker_info_t *marker_tlv_marker_info; + } tlv_ptr; + + while(tlen>0) { + /* did we capture enough for fully decoding the tlv header ? */ + TCHECK2(*tptr, sizeof(struct tlv_header_t)); + tlv_header = (const struct tlv_header_t *)tptr; + tlv_len = tlv_header->length; + + printf("\n\t%s TLV (0x%02x), length %u", + tok2str(slow_tlv_values, + "Unknown", + (slow_com_header->proto_subtype << 8) + tlv_header->type), + tlv_header->type, + tlv_len); + + if ((tlv_len < sizeof(struct tlv_header_t) || + tlv_len > tlen) && + tlv_header->type != LACP_TLV_TERMINATOR && + tlv_header->type != MARKER_TLV_TERMINATOR) { + printf("\n\t-----trailing data-----"); + print_unknown_data(tptr+sizeof(sizeof(struct tlv_header_t)),"\n\t ",tlen); + return; + } + + tlv_tptr=tptr+sizeof(struct tlv_header_t); + tlv_tlen=tlv_len-sizeof(struct tlv_header_t); + + /* did we capture enough for fully decoding the tlv ? */ + TCHECK2(*tptr, tlv_len); + + switch((slow_com_header->proto_subtype << 8) + tlv_header->type) { + + /* those two TLVs have the same structure -> fall through */ + case ((SLOW_PROTO_LACP << 8) + LACP_TLV_ACTOR_INFO): + case ((SLOW_PROTO_LACP << 8) + LACP_TLV_PARTNER_INFO): + tlv_ptr.lacp_tlv_actor_partner_info = (const struct lacp_tlv_actor_partner_info_t *)tlv_tptr; + + printf("\n\t System %s, System Priority %u, Key %u" \ + ", Port %u, Port Priority %u\n\t State Flags [%s]", + etheraddr_string(tlv_ptr.lacp_tlv_actor_partner_info->sys), + EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->sys_pri), + EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->key), + EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->port), + EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->port_pri), + bittok2str(lacp_tlv_actor_partner_info_state_values, + "none", + tlv_ptr.lacp_tlv_actor_partner_info->state)); + + break; + + case ((SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO): + tlv_ptr.lacp_tlv_collector_info = (const struct lacp_tlv_collector_info_t *)tlv_tptr; + + printf("\n\t Max Delay %u", + EXTRACT_16BITS(tlv_ptr.lacp_tlv_collector_info->max_delay)); + + break; + + case ((SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO): + tlv_ptr.marker_tlv_marker_info = (const struct marker_tlv_marker_info_t *)tlv_tptr; + + printf("\n\t Request System %s, Request Port %u, Request Transaction ID 0x%08x", + etheraddr_string(tlv_ptr.marker_tlv_marker_info->req_sys), + EXTRACT_16BITS(tlv_ptr.marker_tlv_marker_info->req_port), + EXTRACT_32BITS(tlv_ptr.marker_tlv_marker_info->req_trans_id)); + + break; + + /* those two TLVs have the same structure -> fall through */ + case ((SLOW_PROTO_LACP << 8) + LACP_TLV_TERMINATOR): + case ((SLOW_PROTO_MARKER << 8) + LACP_TLV_TERMINATOR): + tlv_ptr.lacp_marker_tlv_terminator = (const struct lacp_marker_tlv_terminator_t *)tlv_tptr; + if (tlv_len == 0) { + tlv_len = sizeof(tlv_ptr.lacp_marker_tlv_terminator->pad) + + sizeof(struct tlv_header_t); + /* tell the user that we modified the length field */ + if (vflag>1) + printf(" (=%u)",tlv_len); + /* we have messed around with the length field - now we need to check + * again if there are enough bytes on the wire for the hexdump */ + TCHECK2(tlv_ptr.lacp_marker_tlv_terminator->pad[0], + sizeof(tlv_ptr.lacp_marker_tlv_terminator->pad)); + } + + break; + + default: + if (vflag <= 1) + print_unknown_data(tlv_tptr,"\n\t ",tlv_tlen); + break; + } + /* do we want to see an additional hexdump ? */ + if (vflag > 1) { + print_unknown_data(tptr+sizeof(sizeof(struct tlv_header_t)),"\n\t ", + tlv_len-sizeof(struct tlv_header_t)); + } + + tptr+=tlv_len; + tlen-=tlv_len; + } + return; +trunc: + printf("\n\t\t packet exceeded snapshot"); +} + +void slow_oam_print(register const u_char *tptr, register u_int tlen) { + + u_int hexdump; + + struct slow_oam_common_header_t { + u_int8_t flags[2]; + u_int8_t code; + }; + + struct slow_oam_tlv_header_t { + u_int8_t type; + u_int8_t length; + }; + + union { + const struct slow_oam_common_header_t *slow_oam_common_header; + const struct slow_oam_tlv_header_t *slow_oam_tlv_header; + } ptr; + + union { + const struct slow_oam_info_t *slow_oam_info; + const struct slow_oam_link_event_t *slow_oam_link_event; + const struct slow_oam_variablerequest_t *slow_oam_variablerequest; + const struct slow_oam_variableresponse_t *slow_oam_variableresponse; + const struct slow_oam_loopbackctrl_t *slow_oam_loopbackctrl; + } tlv; + + ptr.slow_oam_common_header = (struct slow_oam_common_header_t *)tptr; + tptr += sizeof(struct slow_oam_common_header_t); + tlen -= sizeof(struct slow_oam_common_header_t); + + printf("\n\tCode %s OAM PDU, Flags [%s]", + tok2str(slow_oam_code_values, "Unknown (%u)", ptr.slow_oam_common_header->code), + bittok2str(slow_oam_flag_values, + "none", + EXTRACT_16BITS(&ptr.slow_oam_common_header->flags))); + + switch (ptr.slow_oam_common_header->code) { + case SLOW_OAM_CODE_INFO: + while (tlen > 0) { + ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr; + printf("\n\t %s Information Type (%u), length %u", + tok2str(slow_oam_info_type_values, "Reserved", + ptr.slow_oam_tlv_header->type), + ptr.slow_oam_tlv_header->type, + ptr.slow_oam_tlv_header->length); + + hexdump = FALSE; + switch (ptr.slow_oam_tlv_header->type) { + case SLOW_OAM_INFO_TYPE_END_OF_TLV: + if (ptr.slow_oam_tlv_header->length != 0) { + printf("\n\t ERROR: illegal length - should be 0"); + } + return; + + case SLOW_OAM_INFO_TYPE_LOCAL: /* identical format - fall through */ + case SLOW_OAM_INFO_TYPE_REMOTE: + tlv.slow_oam_info = (const struct slow_oam_info_t *)tptr; + + if (tlv.slow_oam_info->info_length != + sizeof(struct slow_oam_info_t)) { + printf("\n\t ERROR: illegal length - should be %lu", + (unsigned long) sizeof(struct slow_oam_info_t)); + return; + } + + printf("\n\t OAM-Version %u, Revision %u", + tlv.slow_oam_info->oam_version, + EXTRACT_16BITS(&tlv.slow_oam_info->revision)); + + printf("\n\t State-Parser-Action %s, State-MUX-Action %s", + tok2str(slow_oam_info_type_state_parser_values, "Reserved", + tlv.slow_oam_info->state & OAM_INFO_TYPE_PARSER_MASK), + tok2str(slow_oam_info_type_state_mux_values, "Reserved", + tlv.slow_oam_info->state & OAM_INFO_TYPE_MUX_MASK)); + printf("\n\t OAM-Config Flags [%s], OAM-PDU-Config max-PDU size %u", + bittok2str(slow_oam_info_type_oam_config_values, "none", + tlv.slow_oam_info->oam_config), + EXTRACT_16BITS(&tlv.slow_oam_info->oam_pdu_config) & + OAM_INFO_TYPE_PDU_SIZE_MASK); + printf("\n\t OUI %s (0x%06x), Vendor-Private 0x%08x", + tok2str(oui_values, "Unknown", + EXTRACT_24BITS(&tlv.slow_oam_info->oui)), + EXTRACT_24BITS(&tlv.slow_oam_info->oui), + EXTRACT_32BITS(&tlv.slow_oam_info->vendor_private)); + break; + + case SLOW_OAM_INFO_TYPE_ORG_SPECIFIC: + hexdump = TRUE; + break; + + default: + hexdump = TRUE; + break; + } + + /* infinite loop check */ + if (!ptr.slow_oam_tlv_header->length) { + return; + } + + /* do we also want to see a hex dump ? */ + if (vflag > 1 || hexdump==TRUE) { + print_unknown_data(tptr,"\n\t ", + ptr.slow_oam_tlv_header->length); + } + + tlen -= ptr.slow_oam_tlv_header->length; + tptr += ptr.slow_oam_tlv_header->length; + } + break; + + case SLOW_OAM_CODE_EVENT_NOTIF: + while (tlen > 0) { + ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr; + printf("\n\t %s Link Event Type (%u), length %u", + tok2str(slow_oam_link_event_values, "Reserved", + ptr.slow_oam_tlv_header->type), + ptr.slow_oam_tlv_header->type, + ptr.slow_oam_tlv_header->length); + + hexdump = FALSE; + switch (ptr.slow_oam_tlv_header->type) { + case SLOW_OAM_LINK_EVENT_END_OF_TLV: + if (ptr.slow_oam_tlv_header->length != 0) { + printf("\n\t ERROR: illegal length - should be 0"); + } + return; + + case SLOW_OAM_LINK_EVENT_ERR_SYM_PER: /* identical format - fall through */ + case SLOW_OAM_LINK_EVENT_ERR_FRM: + case SLOW_OAM_LINK_EVENT_ERR_FRM_PER: + case SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM: + tlv.slow_oam_link_event = (const struct slow_oam_link_event_t *)tptr; + + if (tlv.slow_oam_link_event->event_length != + sizeof(struct slow_oam_link_event_t)) { + printf("\n\t ERROR: illegal length - should be %lu", + (unsigned long) sizeof(struct slow_oam_link_event_t)); + return; + } + + printf("\n\t Timestamp %u ms, Errored Window %" PRIu64 + "\n\t Errored Threshold %" PRIu64 + "\n\t Errors %" PRIu64 + "\n\t Error Running Total %" PRIu64 + "\n\t Event Running Total %u", + EXTRACT_16BITS(&tlv.slow_oam_link_event->time_stamp)*100, + EXTRACT_64BITS(&tlv.slow_oam_link_event->window), + EXTRACT_64BITS(&tlv.slow_oam_link_event->threshold), + EXTRACT_64BITS(&tlv.slow_oam_link_event->errors), + EXTRACT_64BITS(&tlv.slow_oam_link_event->errors_running_total), + EXTRACT_32BITS(&tlv.slow_oam_link_event->event_running_total)); + break; + + case SLOW_OAM_LINK_EVENT_ORG_SPECIFIC: + hexdump = TRUE; + break; + + default: + hexdump = TRUE; + break; + } + + /* infinite loop check */ + if (!ptr.slow_oam_tlv_header->length) { + return; + } + + /* do we also want to see a hex dump ? */ + if (vflag > 1 || hexdump==TRUE) { + print_unknown_data(tptr,"\n\t ", + ptr.slow_oam_tlv_header->length); + } + + tlen -= ptr.slow_oam_tlv_header->length; + tptr += ptr.slow_oam_tlv_header->length; + } + break; + + case SLOW_OAM_CODE_LOOPBACK_CTRL: + tlv.slow_oam_loopbackctrl = (const struct slow_oam_loopbackctrl_t *)tptr; + printf("\n\t Command %s (%u)", + tok2str(slow_oam_loopbackctrl_cmd_values, + "Unknown", + tlv.slow_oam_loopbackctrl->command), + tlv.slow_oam_loopbackctrl->command); + tptr ++; + tlen --; + break; + + /* + * FIXME those are the defined codes that lack a decoder + * you are welcome to contribute code ;-) + */ + case SLOW_OAM_CODE_VAR_REQUEST: + case SLOW_OAM_CODE_VAR_RESPONSE: + case SLOW_OAM_CODE_PRIVATE: + default: + if (vflag <= 1) { + print_unknown_data(tptr,"\n\t ", tlen); + } + break; + } + return; +} diff --git a/print-smb.c b/print-smb.c new file mode 100644 index 0000000..68c7365 --- /dev/null +++ b/print-smb.c @@ -0,0 +1,1510 @@ +/* + * Copyright (C) Andrew Tridgell 1995-1999 + * + * This software may be distributed either under the terms of the + * BSD-style license that accompanies tcpdump or the GNU GPL version 2 + * or later + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-smb.c,v 1.47 2007-12-09 00:30:47 guy Exp $"; +#endif + +#include + +#include +#include + +#include "interface.h" +#include "extract.h" +#include "smb.h" + +static int request = 0; +static int unicodestr = 0; + +const u_char *startbuf = NULL; + +struct smbdescript { + const char *req_f1; + const char *req_f2; + const char *rep_f1; + const char *rep_f2; + void (*fn)(const u_char *, const u_char *, const u_char *, const u_char *); +}; + +struct smbdescriptint { + const char *req_f1; + const char *req_f2; + const char *rep_f1; + const char *rep_f2; + void (*fn)(const u_char *, const u_char *, int, int); +}; + +struct smbfns +{ + int id; + const char *name; + int flags; + struct smbdescript descript; +}; + +struct smbfnsint +{ + int id; + const char *name; + int flags; + struct smbdescriptint descript; +}; + +#define DEFDESCRIPT { NULL, NULL, NULL, NULL, NULL } + +#define FLG_CHAIN (1 << 0) + +static struct smbfns * +smbfind(int id, struct smbfns *list) +{ + int sindex; + + for (sindex = 0; list[sindex].name; sindex++) + if (list[sindex].id == id) + return(&list[sindex]); + + return(&list[0]); +} + +static struct smbfnsint * +smbfindint(int id, struct smbfnsint *list) +{ + int sindex; + + for (sindex = 0; list[sindex].name; sindex++) + if (list[sindex].id == id) + return(&list[sindex]); + + return(&list[0]); +} + +static void +trans2_findfirst(const u_char *param, const u_char *data, int pcnt, int dcnt) +{ + const char *fmt; + + if (request) + fmt = "Attribute=[A]\nSearchCount=[d]\nFlags=[w]\nLevel=[dP4]\nFile=[S]\n"; + else + fmt = "Handle=[w]\nCount=[d]\nEOS=[w]\nEoffset=[d]\nLastNameOfs=[w]\n"; + + smb_fdata(param, fmt, param + pcnt, unicodestr); + if (dcnt) { + printf("data:\n"); + print_data(data, dcnt); + } +} + +static void +trans2_qfsinfo(const u_char *param, const u_char *data, int pcnt, int dcnt) +{ + static int level = 0; + const char *fmt=""; + + if (request) { + TCHECK2(*param, 2); + level = EXTRACT_LE_16BITS(param); + fmt = "InfoLevel=[d]\n"; + smb_fdata(param, fmt, param + pcnt, unicodestr); + } else { + switch (level) { + case 1: + fmt = "idFileSystem=[W]\nSectorUnit=[D]\nUnit=[D]\nAvail=[D]\nSectorSize=[d]\n"; + break; + case 2: + fmt = "CreationTime=[T2]VolNameLength=[lb]\nVolumeLabel=[c]\n"; + break; + case 0x105: + fmt = "Capabilities=[W]\nMaxFileLen=[D]\nVolNameLen=[lD]\nVolume=[C]\n"; + break; + default: + fmt = "UnknownLevel\n"; + break; + } + smb_fdata(data, fmt, data + dcnt, unicodestr); + } + if (dcnt) { + printf("data:\n"); + print_data(data, dcnt); + } + return; +trunc: + printf("[|SMB]"); + return; +} + +struct smbfnsint trans2_fns[] = { + { 0, "TRANSACT2_OPEN", 0, + { "Flags2=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]\nOFun=[w]\nSize=[D]\nRes=([w, w, w, w, w])\nPath=[S]", + NULL, + "Handle=[d]\nAttrib=[A]\nTime=[T2]\nSize=[D]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nInode=[W]\nOffErr=[d]\n|EALength=[d]\n", + NULL, NULL }}, + { 1, "TRANSACT2_FINDFIRST", 0, + { NULL, NULL, NULL, NULL, trans2_findfirst }}, + { 2, "TRANSACT2_FINDNEXT", 0, DEFDESCRIPT }, + { 3, "TRANSACT2_QFSINFO", 0, + { NULL, NULL, NULL, NULL, trans2_qfsinfo }}, + { 4, "TRANSACT2_SETFSINFO", 0, DEFDESCRIPT }, + { 5, "TRANSACT2_QPATHINFO", 0, DEFDESCRIPT }, + { 6, "TRANSACT2_SETPATHINFO", 0, DEFDESCRIPT }, + { 7, "TRANSACT2_QFILEINFO", 0, DEFDESCRIPT }, + { 8, "TRANSACT2_SETFILEINFO", 0, DEFDESCRIPT }, + { 9, "TRANSACT2_FSCTL", 0, DEFDESCRIPT }, + { 10, "TRANSACT2_IOCTL", 0, DEFDESCRIPT }, + { 11, "TRANSACT2_FINDNOTIFYFIRST", 0, DEFDESCRIPT }, + { 12, "TRANSACT2_FINDNOTIFYNEXT", 0, DEFDESCRIPT }, + { 13, "TRANSACT2_MKDIR", 0, DEFDESCRIPT }, + { -1, NULL, 0, DEFDESCRIPT } +}; + + +static void +print_trans2(const u_char *words, const u_char *dat, const u_char *buf, const u_char *maxbuf) +{ + u_int bcc; + static struct smbfnsint *fn = &trans2_fns[0]; + const u_char *data, *param; + const u_char *w = words + 1; + const char *f1 = NULL, *f2 = NULL; + int pcnt, dcnt; + + TCHECK(words[0]); + if (request) { + TCHECK2(w[14 * 2], 2); + pcnt = EXTRACT_LE_16BITS(w + 9 * 2); + param = buf + EXTRACT_LE_16BITS(w + 10 * 2); + dcnt = EXTRACT_LE_16BITS(w + 11 * 2); + data = buf + EXTRACT_LE_16BITS(w + 12 * 2); + fn = smbfindint(EXTRACT_LE_16BITS(w + 14 * 2), trans2_fns); + } else { + if (words[0] == 0) { + printf("%s\n", fn->name); + printf("Trans2Interim\n"); + return; + } + TCHECK2(w[7 * 2], 2); + pcnt = EXTRACT_LE_16BITS(w + 3 * 2); + param = buf + EXTRACT_LE_16BITS(w + 4 * 2); + dcnt = EXTRACT_LE_16BITS(w + 6 * 2); + data = buf + EXTRACT_LE_16BITS(w + 7 * 2); + } + + printf("%s param_length=%d data_length=%d\n", fn->name, pcnt, dcnt); + + if (request) { + if (words[0] == 8) { + smb_fdata(words + 1, + "Trans2Secondary\nTotParam=[d]\nTotData=[d]\nParamCnt=[d]\nParamOff=[d]\nParamDisp=[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nHandle=[d]\n", + maxbuf, unicodestr); + return; + } else { + smb_fdata(words + 1, + "TotParam=[d]\nTotData=[d]\nMaxParam=[d]\nMaxData=[d]\nMaxSetup=[b][P1]\nFlags=[w]\nTimeOut=[D]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nDataCnt=[d]\nDataOff=[d]\nSetupCnt=[b][P1]\n", + words + 1 + 14 * 2, unicodestr); + } + f1 = fn->descript.req_f1; + f2 = fn->descript.req_f2; + } else { + smb_fdata(words + 1, + "TotParam=[d]\nTotData=[d]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nParamDisp[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nSetupCnt=[b][P1]\n", + words + 1 + 10 * 2, unicodestr); + f1 = fn->descript.rep_f1; + f2 = fn->descript.rep_f2; + } + + TCHECK2(*dat, 2); + bcc = EXTRACT_LE_16BITS(dat); + printf("smb_bcc=%u\n", bcc); + if (fn->descript.fn) + (*fn->descript.fn)(param, data, pcnt, dcnt); + else { + smb_fdata(param, f1 ? f1 : "Parameters=\n", param + pcnt, unicodestr); + smb_fdata(data, f2 ? f2 : "Data=\n", data + dcnt, unicodestr); + } + return; +trunc: + printf("[|SMB]"); + return; +} + + +static void +print_browse(const u_char *param, int paramlen, const u_char *data, int datalen) +{ + const u_char *maxbuf = data + datalen; + int command; + + TCHECK(data[0]); + command = data[0]; + + smb_fdata(param, "BROWSE PACKET\n|Param ", param+paramlen, unicodestr); + + switch (command) { + case 0xF: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (LocalMasterAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n", + maxbuf, unicodestr); + break; + + case 0x1: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (HostAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n", + maxbuf, unicodestr); + break; + + case 0x2: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (AnnouncementRequest)\nFlags=[B]\nReplySystemName=[S]\n", + maxbuf, unicodestr); + break; + + case 0xc: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (WorkgroupAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nCommentPointer=[W]\nServerName=[S]\n", + maxbuf, unicodestr); + break; + + case 0x8: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (ElectionFrame)\nElectionVersion=[B]\nOSSummary=[W]\nUptime=[(W, W)]\nServerName=[S]\n", + maxbuf, unicodestr); + break; + + case 0xb: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (BecomeBackupBrowser)\nName=[S]\n", + maxbuf, unicodestr); + break; + + case 0x9: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (GetBackupList)\nListCount?=[B]\nToken=[W]\n", + maxbuf, unicodestr); + break; + + case 0xa: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (BackupListResponse)\nServerCount?=[B]\nToken=[W]\n*Name=[S]\n", + maxbuf, unicodestr); + break; + + case 0xd: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (MasterAnnouncement)\nMasterName=[S]\n", + maxbuf, unicodestr); + break; + + case 0xe: + data = smb_fdata(data, + "BROWSE PACKET:\nType=[B] (ResetBrowser)\nOptions=[B]\n", maxbuf, unicodestr); + break; + + default: + data = smb_fdata(data, "Unknown Browser Frame ", maxbuf, unicodestr); + break; + } + return; +trunc: + printf("[|SMB]"); + return; +} + + +static void +print_ipc(const u_char *param, int paramlen, const u_char *data, int datalen) +{ + if (paramlen) + smb_fdata(param, "Command=[w]\nStr1=[S]\nStr2=[S]\n", param + paramlen, + unicodestr); + if (datalen) + smb_fdata(data, "IPC ", data + datalen, unicodestr); +} + + +static void +print_trans(const u_char *words, const u_char *data1, const u_char *buf, const u_char *maxbuf) +{ + u_int bcc; + const char *f1, *f2, *f3, *f4; + const u_char *data, *param; + const u_char *w = words + 1; + int datalen, paramlen; + + if (request) { + TCHECK2(w[12 * 2], 2); + paramlen = EXTRACT_LE_16BITS(w + 9 * 2); + param = buf + EXTRACT_LE_16BITS(w + 10 * 2); + datalen = EXTRACT_LE_16BITS(w + 11 * 2); + data = buf + EXTRACT_LE_16BITS(w + 12 * 2); + f1 = "TotParamCnt=[d] \nTotDataCnt=[d] \nMaxParmCnt=[d] \nMaxDataCnt=[d]\nMaxSCnt=[d] \nTransFlags=[w] \nRes1=[w] \nRes2=[w] \nRes3=[w]\nParamCnt=[d] \nParamOff=[d] \nDataCnt=[d] \nDataOff=[d] \nSUCnt=[d]\n"; + f2 = "|Name=[S]\n"; + f3 = "|Param "; + f4 = "|Data "; + } else { + TCHECK2(w[7 * 2], 2); + paramlen = EXTRACT_LE_16BITS(w + 3 * 2); + param = buf + EXTRACT_LE_16BITS(w + 4 * 2); + datalen = EXTRACT_LE_16BITS(w + 6 * 2); + data = buf + EXTRACT_LE_16BITS(w + 7 * 2); + f1 = "TotParamCnt=[d] \nTotDataCnt=[d] \nRes1=[d]\nParamCnt=[d] \nParamOff=[d] \nRes2=[d] \nDataCnt=[d] \nDataOff=[d] \nRes3=[d]\nLsetup=[d]\n"; + f2 = "|Unknown "; + f3 = "|Param "; + f4 = "|Data "; + } + + smb_fdata(words + 1, f1, SMBMIN(words + 1 + 2 * words[0], maxbuf), + unicodestr); + + TCHECK2(*data1, 2); + bcc = EXTRACT_LE_16BITS(data1); + printf("smb_bcc=%u\n", bcc); + if (bcc > 0) { + smb_fdata(data1 + 2, f2, maxbuf - (paramlen + datalen), unicodestr); + + if (strcmp((const char *)(data1 + 2), "\\MAILSLOT\\BROWSE") == 0) { + print_browse(param, paramlen, data, datalen); + return; + } + + if (strcmp((const char *)(data1 + 2), "\\PIPE\\LANMAN") == 0) { + print_ipc(param, paramlen, data, datalen); + return; + } + + if (paramlen) + smb_fdata(param, f3, SMBMIN(param + paramlen, maxbuf), unicodestr); + if (datalen) + smb_fdata(data, f4, SMBMIN(data + datalen, maxbuf), unicodestr); + } + return; +trunc: + printf("[|SMB]"); + return; +} + + +static void +print_negprot(const u_char *words, const u_char *data, const u_char *buf _U_, const u_char *maxbuf) +{ + u_int wct, bcc; + const char *f1 = NULL, *f2 = NULL; + + TCHECK(words[0]); + wct = words[0]; + if (request) + f2 = "*|Dialect=[Y]\n"; + else { + if (wct == 1) + f1 = "Core Protocol\nDialectIndex=[d]"; + else if (wct == 17) + f1 = "NT1 Protocol\nDialectIndex=[d]\nSecMode=[B]\nMaxMux=[d]\nNumVcs=[d]\nMaxBuffer=[D]\nRawSize=[D]\nSessionKey=[W]\nCapabilities=[W]\nServerTime=[T3]TimeZone=[d]\nCryptKey="; + else if (wct == 13) + f1 = "Coreplus/Lanman1/Lanman2 Protocol\nDialectIndex=[d]\nSecMode=[w]\nMaxXMit=[d]\nMaxMux=[d]\nMaxVcs=[d]\nBlkMode=[w]\nSessionKey=[W]\nServerTime=[T1]TimeZone=[d]\nRes=[W]\nCryptKey="; + } + + if (f1) + smb_fdata(words + 1, f1, SMBMIN(words + 1 + wct * 2, maxbuf), + unicodestr); + else + print_data(words + 1, SMBMIN(wct * 2, PTR_DIFF(maxbuf, words + 1))); + + TCHECK2(*data, 2); + bcc = EXTRACT_LE_16BITS(data); + printf("smb_bcc=%u\n", bcc); + if (bcc > 0) { + if (f2) + smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data), + maxbuf), unicodestr); + else + print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); + } + return; +trunc: + printf("[|SMB]"); + return; +} + +static void +print_sesssetup(const u_char *words, const u_char *data, const u_char *buf _U_, const u_char *maxbuf) +{ + u_int wct, bcc; + const char *f1 = NULL, *f2 = NULL; + + TCHECK(words[0]); + wct = words[0]; + if (request) { + if (wct == 10) + f1 = "Com2=[w]\nOff2=[d]\nBufSize=[d]\nMpxMax=[d]\nVcNum=[d]\nSessionKey=[W]\nPassLen=[d]\nCryptLen=[d]\nCryptOff=[d]\nPass&Name=\n"; + else + f1 = "Com2=[B]\nRes1=[B]\nOff2=[d]\nMaxBuffer=[d]\nMaxMpx=[d]\nVcNumber=[d]\nSessionKey=[W]\nCaseInsensitivePasswordLength=[d]\nCaseSensitivePasswordLength=[d]\nRes=[W]\nCapabilities=[W]\nPass1&Pass2&Account&Domain&OS&LanMan=\n"; + } else { + if (wct == 3) { + f1 = "Com2=[w]\nOff2=[d]\nAction=[w]\n"; + } else if (wct == 13) { + f1 = "Com2=[B]\nRes=[B]\nOff2=[d]\nAction=[w]\n"; + f2 = "NativeOS=[S]\nNativeLanMan=[S]\nPrimaryDomain=[S]\n"; + } + } + + if (f1) + smb_fdata(words + 1, f1, SMBMIN(words + 1 + wct * 2, maxbuf), + unicodestr); + else + print_data(words + 1, SMBMIN(wct * 2, PTR_DIFF(maxbuf, words + 1))); + + TCHECK2(*data, 2); + bcc = EXTRACT_LE_16BITS(data); + printf("smb_bcc=%u\n", bcc); + if (bcc > 0) { + if (f2) + smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data), + maxbuf), unicodestr); + else + print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); + } + return; +trunc: + printf("[|SMB]"); + return; +} + +static void +print_lockingandx(const u_char *words, const u_char *data, const u_char *buf _U_, const u_char *maxbuf) +{ + u_int wct, bcc; + const u_char *maxwords; + const char *f1 = NULL, *f2 = NULL; + + TCHECK(words[0]); + wct = words[0]; + if (request) { + f1 = "Com2=[w]\nOff2=[d]\nHandle=[d]\nLockType=[w]\nTimeOut=[D]\nUnlockCount=[d]\nLockCount=[d]\n"; + TCHECK(words[7]); + if (words[7] & 0x10) + f2 = "*Process=[d]\n[P2]Offset=[M]\nLength=[M]\n"; + else + f2 = "*Process=[d]\nOffset=[D]\nLength=[D]\n"; + } else { + f1 = "Com2=[w]\nOff2=[d]\n"; + } + + maxwords = SMBMIN(words + 1 + wct * 2, maxbuf); + if (wct) + smb_fdata(words + 1, f1, maxwords, unicodestr); + + TCHECK2(*data, 2); + bcc = EXTRACT_LE_16BITS(data); + printf("smb_bcc=%u\n", bcc); + if (bcc > 0) { + if (f2) + smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data), + maxbuf), unicodestr); + else + print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2))); + } + return; +trunc: + printf("[|SMB]"); + return; +} + + +static struct smbfns smb_fns[] = { + { -1, "SMBunknown", 0, DEFDESCRIPT }, + + { SMBtcon, "SMBtcon", 0, + { NULL, "Path=[Z]\nPassword=[Z]\nDevice=[Z]\n", + "MaxXmit=[d]\nTreeId=[d]\n", NULL, + NULL } }, + + { SMBtdis, "SMBtdis", 0, DEFDESCRIPT }, + { SMBexit, "SMBexit", 0, DEFDESCRIPT }, + { SMBioctl, "SMBioctl", 0, DEFDESCRIPT }, + + { SMBecho, "SMBecho", 0, + { "ReverbCount=[d]\n", NULL, + "SequenceNum=[d]\n", NULL, + NULL } }, + + { SMBulogoffX, "SMBulogoffX", FLG_CHAIN, DEFDESCRIPT }, + + { SMBgetatr, "SMBgetatr", 0, + { NULL, "Path=[Z]\n", + "Attribute=[A]\nTime=[T2]Size=[D]\nRes=([w,w,w,w,w])\n", NULL, + NULL } }, + + { SMBsetatr, "SMBsetatr", 0, + { "Attribute=[A]\nTime=[T2]Res=([w,w,w,w,w])\n", "Path=[Z]\n", + NULL, NULL, NULL } }, + + { SMBchkpth, "SMBchkpth", 0, + { NULL, "Path=[Z]\n", NULL, NULL, NULL } }, + + { SMBsearch, "SMBsearch", 0, + { "Count=[d]\nAttrib=[A]\n", + "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\n", + "Count=[d]\n", + "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n", + NULL } }, + + { SMBopen, "SMBopen", 0, + { "Mode=[w]\nAttribute=[A]\n", "Path=[Z]\n", + "Handle=[d]\nOAttrib=[A]\nTime=[T2]Size=[D]\nAccess=[w]\n", + NULL, NULL } }, + + { SMBcreate, "SMBcreate", 0, + { "Attrib=[A]\nTime=[T2]", "Path=[Z]\n", "Handle=[d]\n", NULL, NULL } }, + + { SMBmknew, "SMBmknew", 0, + { "Attrib=[A]\nTime=[T2]", "Path=[Z]\n", "Handle=[d]\n", NULL, NULL } }, + + { SMBunlink, "SMBunlink", 0, + { "Attrib=[A]\n", "Path=[Z]\n", NULL, NULL, NULL } }, + + { SMBread, "SMBread", 0, + { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL, + "Count=[d]\nRes=([w,w,w,w])\n", NULL, NULL } }, + + { SMBwrite, "SMBwrite", 0, + { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL, + "Count=[d]\n", NULL, NULL } }, + + { SMBclose, "SMBclose", 0, + { "Handle=[d]\nTime=[T2]", NULL, NULL, NULL, NULL } }, + + { SMBmkdir, "SMBmkdir", 0, + { NULL, "Path=[Z]\n", NULL, NULL, NULL } }, + + { SMBrmdir, "SMBrmdir", 0, + { NULL, "Path=[Z]\n", NULL, NULL, NULL } }, + + { SMBdskattr, "SMBdskattr", 0, + { NULL, NULL, + "TotalUnits=[d]\nBlocksPerUnit=[d]\nBlockSize=[d]\nFreeUnits=[d]\nMedia=[w]\n", + NULL, NULL } }, + + { SMBmv, "SMBmv", 0, + { "Attrib=[A]\n", "OldPath=[Z]\nNewPath=[Z]\n", NULL, NULL, NULL } }, + + /* + * this is a Pathworks specific call, allowing the + * changing of the root path + */ + { pSETDIR, "SMBsetdir", 0, { NULL, "Path=[Z]\n", NULL, NULL, NULL } }, + + { SMBlseek, "SMBlseek", 0, + { "Handle=[d]\nMode=[w]\nOffset=[D]\n", "Offset=[D]\n", NULL, NULL, NULL } }, + + { SMBflush, "SMBflush", 0, { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + + { SMBsplopen, "SMBsplopen", 0, + { "SetupLen=[d]\nMode=[w]\n", "Ident=[Z]\n", "Handle=[d]\n", + NULL, NULL } }, + + { SMBsplclose, "SMBsplclose", 0, + { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + + { SMBsplretq, "SMBsplretq", 0, + { "MaxCount=[d]\nStartIndex=[d]\n", NULL, + "Count=[d]\nIndex=[d]\n", + "*Time=[T2]Status=[B]\nJobID=[d]\nSize=[D]\nRes=[B]Name=[s16]\n", + NULL } }, + + { SMBsplwr, "SMBsplwr", 0, + { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + + { SMBlock, "SMBlock", 0, + { "Handle=[d]\nCount=[D]\nOffset=[D]\n", NULL, NULL, NULL, NULL } }, + + { SMBunlock, "SMBunlock", 0, + { "Handle=[d]\nCount=[D]\nOffset=[D]\n", NULL, NULL, NULL, NULL } }, + + /* CORE+ PROTOCOL FOLLOWS */ + + { SMBreadbraw, "SMBreadbraw", 0, + { "Handle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nRes=[d]\n", + NULL, NULL, NULL, NULL } }, + + { SMBwritebraw, "SMBwritebraw", 0, + { "Handle=[d]\nTotalCount=[d]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\n|DataSize=[d]\nDataOff=[d]\n", + NULL, "WriteRawAck", NULL, NULL } }, + + { SMBwritec, "SMBwritec", 0, + { NULL, NULL, "Count=[d]\n", NULL, NULL } }, + + { SMBwriteclose, "SMBwriteclose", 0, + { "Handle=[d]\nCount=[d]\nOffset=[D]\nTime=[T2]Res=([w,w,w,w,w,w])", + NULL, "Count=[d]\n", NULL, NULL } }, + + { SMBlockread, "SMBlockread", 0, + { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL, + "Count=[d]\nRes=([w,w,w,w])\n", NULL, NULL } }, + + { SMBwriteunlock, "SMBwriteunlock", 0, + { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL, + "Count=[d]\n", NULL, NULL } }, + + { SMBreadBmpx, "SMBreadBmpx", 0, + { "Handle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nRes=[w]\n", + NULL, + "Offset=[D]\nTotCount=[d]\nRemaining=[d]\nRes=([w,w])\nDataSize=[d]\nDataOff=[d]\n", + NULL, NULL } }, + + { SMBwriteBmpx, "SMBwriteBmpx", 0, + { "Handle=[d]\nTotCount=[d]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\nDataSize=[d]\nDataOff=[d]\n", NULL, + "Remaining=[d]\n", NULL, NULL } }, + + { SMBwriteBs, "SMBwriteBs", 0, + { "Handle=[d]\nTotCount=[d]\nOffset=[D]\nRes=[W]\nDataSize=[d]\nDataOff=[d]\n", + NULL, "Count=[d]\n", NULL, NULL } }, + + { SMBsetattrE, "SMBsetattrE", 0, + { "Handle=[d]\nCreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]", NULL, + NULL, NULL, NULL } }, + + { SMBgetattrE, "SMBgetattrE", 0, + { "Handle=[d]\n", NULL, + "CreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]Size=[D]\nAllocSize=[D]\nAttribute=[A]\n", + NULL, NULL } }, + + { SMBtranss, "SMBtranss", 0, DEFDESCRIPT }, + { SMBioctls, "SMBioctls", 0, DEFDESCRIPT }, + + { SMBcopy, "SMBcopy", 0, + { "TreeID2=[d]\nOFun=[w]\nFlags=[w]\n", "Path=[S]\nNewPath=[S]\n", + "CopyCount=[d]\n", "|ErrStr=[S]\n", NULL } }, + + { SMBmove, "SMBmove", 0, + { "TreeID2=[d]\nOFun=[w]\nFlags=[w]\n", "Path=[S]\nNewPath=[S]\n", + "MoveCount=[d]\n", "|ErrStr=[S]\n", NULL } }, + + { SMBopenX, "SMBopenX", FLG_CHAIN, + { "Com2=[w]\nOff2=[d]\nFlags=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]OFun=[w]\nSize=[D]\nTimeOut=[D]\nRes=[W]\n", + "Path=[S]\n", + "Com2=[w]\nOff2=[d]\nHandle=[d]\nAttrib=[A]\nTime=[T2]Size=[D]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nFileID=[W]\nRes=[w]\n", + NULL, NULL } }, + + { SMBreadX, "SMBreadX", FLG_CHAIN, + { "Com2=[w]\nOff2=[d]\nHandle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nCountLeft=[d]\n", + NULL, + "Com2=[w]\nOff2=[d]\nRemaining=[d]\nRes=[W]\nDataSize=[d]\nDataOff=[d]\nRes=([w,w,w,w])\n", + NULL, NULL } }, + + { SMBwriteX, "SMBwriteX", FLG_CHAIN, + { "Com2=[w]\nOff2=[d]\nHandle=[d]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nCountLeft=[d]\nRes=[w]\nDataSize=[d]\nDataOff=[d]\n", + NULL, + "Com2=[w]\nOff2=[d]\nCount=[d]\nRemaining=[d]\nRes=[W]\n", + NULL, NULL } }, + + { SMBffirst, "SMBffirst", 0, + { "Count=[d]\nAttrib=[A]\n", + "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n", + "Count=[d]\n", + "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n", + NULL } }, + + { SMBfunique, "SMBfunique", 0, + { "Count=[d]\nAttrib=[A]\n", + "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n", + "Count=[d]\n", + "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n", + NULL } }, + + { SMBfclose, "SMBfclose", 0, + { "Count=[d]\nAttrib=[A]\n", + "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n", + "Count=[d]\n", + "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n", + NULL } }, + + { SMBfindnclose, "SMBfindnclose", 0, + { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + + { SMBfindclose, "SMBfindclose", 0, + { "Handle=[d]\n", NULL, NULL, NULL, NULL } }, + + { SMBsends, "SMBsends", 0, + { NULL, "Source=[Z]\nDest=[Z]\n", NULL, NULL, NULL } }, + + { SMBsendstrt, "SMBsendstrt", 0, + { NULL, "Source=[Z]\nDest=[Z]\n", "GroupID=[d]\n", NULL, NULL } }, + + { SMBsendend, "SMBsendend", 0, + { "GroupID=[d]\n", NULL, NULL, NULL, NULL } }, + + { SMBsendtxt, "SMBsendtxt", 0, + { "GroupID=[d]\n", NULL, NULL, NULL, NULL } }, + + { SMBsendb, "SMBsendb", 0, + { NULL, "Source=[Z]\nDest=[Z]\n", NULL, NULL, NULL } }, + + { SMBfwdname, "SMBfwdname", 0, DEFDESCRIPT }, + { SMBcancelf, "SMBcancelf", 0, DEFDESCRIPT }, + { SMBgetmac, "SMBgetmac", 0, DEFDESCRIPT }, + + { SMBnegprot, "SMBnegprot", 0, + { NULL, NULL, NULL, NULL, print_negprot } }, + + { SMBsesssetupX, "SMBsesssetupX", FLG_CHAIN, + { NULL, NULL, NULL, NULL, print_sesssetup } }, + + { SMBtconX, "SMBtconX", FLG_CHAIN, + { "Com2=[w]\nOff2=[d]\nFlags=[w]\nPassLen=[d]\nPasswd&Path&Device=\n", + NULL, "Com2=[w]\nOff2=[d]\n", "ServiceType=[R]\n", NULL } }, + + { SMBlockingX, "SMBlockingX", FLG_CHAIN, + { NULL, NULL, NULL, NULL, print_lockingandx } }, + + { SMBtrans2, "SMBtrans2", 0, { NULL, NULL, NULL, NULL, print_trans2 } }, + + { SMBtranss2, "SMBtranss2", 0, DEFDESCRIPT }, + { SMBctemp, "SMBctemp", 0, DEFDESCRIPT }, + { SMBreadBs, "SMBreadBs", 0, DEFDESCRIPT }, + { SMBtrans, "SMBtrans", 0, { NULL, NULL, NULL, NULL, print_trans } }, + + { SMBnttrans, "SMBnttrans", 0, DEFDESCRIPT }, + { SMBnttranss, "SMBnttranss", 0, DEFDESCRIPT }, + + { SMBntcreateX, "SMBntcreateX", FLG_CHAIN, + { "Com2=[w]\nOff2=[d]\nRes=[b]\nNameLen=[ld]\nFlags=[W]\nRootDirectoryFid=[D]\nAccessMask=[W]\nAllocationSize=[L]\nExtFileAttributes=[W]\nShareAccess=[W]\nCreateDisposition=[W]\nCreateOptions=[W]\nImpersonationLevel=[W]\nSecurityFlags=[b]\n", + "Path=[C]\n", + "Com2=[w]\nOff2=[d]\nOplockLevel=[b]\nFid=[d]\nCreateAction=[W]\nCreateTime=[T3]LastAccessTime=[T3]LastWriteTime=[T3]ChangeTime=[T3]ExtFileAttributes=[W]\nAllocationSize=[L]\nEndOfFile=[L]\nFileType=[w]\nDeviceState=[w]\nDirectory=[b]\n", + NULL, NULL } }, + + { SMBntcancel, "SMBntcancel", 0, DEFDESCRIPT }, + + { -1, NULL, 0, DEFDESCRIPT } +}; + + +/* + * print a SMB message + */ +static void +print_smb(const u_char *buf, const u_char *maxbuf) +{ + u_int16_t flags2; + int nterrcodes; + int command; + u_int32_t nterror; + const u_char *words, *maxwords, *data; + struct smbfns *fn; + const char *fmt_smbheader = + "[P4]SMB Command = [B]\nError class = [BP1]\nError code = [d]\nFlags1 = [B]\nFlags2 = [B][P13]\nTree ID = [d]\nProc ID = [d]\nUID = [d]\nMID = [d]\nWord Count = [b]\n"; + int smboffset; + + TCHECK(buf[9]); + request = (buf[9] & 0x80) ? 0 : 1; + flags2 = EXTRACT_LE_16BITS(&buf[10]); + unicodestr = flags2 & 0x8000; + nterrcodes = flags2 & 0x4000; + startbuf = buf; + + command = buf[4]; + + fn = smbfind(command, smb_fns); + + if (vflag > 1) + printf("\n"); + + printf("SMB PACKET: %s (%s)\n", fn->name, request ? "REQUEST" : "REPLY"); + + if (vflag < 2) + return; + + /* print out the header */ + smb_fdata(buf, fmt_smbheader, buf + 33, unicodestr); + + if (nterrcodes) { + nterror = EXTRACT_LE_32BITS(&buf[5]); + if (nterror) + printf("NTError = %s\n", nt_errstr(nterror)); + } else { + if (buf[5]) + printf("SMBError = %s\n", smb_errstr(buf[5], EXTRACT_LE_16BITS(&buf[7]))); + } + + smboffset = 32; + + for (;;) { + const char *f1, *f2; + int wct; + u_int bcc; + int newsmboffset; + + words = buf + smboffset; + TCHECK(words[0]); + wct = words[0]; + data = words + 1 + wct * 2; + maxwords = SMBMIN(data, maxbuf); + + if (request) { + f1 = fn->descript.req_f1; + f2 = fn->descript.req_f2; + } else { + f1 = fn->descript.rep_f1; + f2 = fn->descript.rep_f2; + } + + if (fn->descript.fn) + (*fn->descript.fn)(words, data, buf, maxbuf); + else { + if (wct) { + if (f1) + smb_fdata(words + 1, f1, words + 1 + wct * 2, unicodestr); + else { + int i; + int v; + + for (i = 0; &words[1 + 2 * i] < maxwords; i++) { + TCHECK2(words[1 + 2 * i], 2); + v = EXTRACT_LE_16BITS(words + 1 + 2 * i); + printf("smb_vwv[%d]=%d (0x%X)\n", i, v, v); + } + } + } + + TCHECK2(*data, 2); + bcc = EXTRACT_LE_16BITS(data); + printf("smb_bcc=%u\n", bcc); + if (f2) { + if (bcc > 0) + smb_fdata(data + 2, f2, data + 2 + bcc, unicodestr); + } else { + if (bcc > 0) { + printf("smb_buf[]=\n"); + print_data(data + 2, SMBMIN(bcc, PTR_DIFF(maxbuf, data + 2))); + } + } + } + + if ((fn->flags & FLG_CHAIN) == 0) + break; + if (wct == 0) + break; + TCHECK(words[1]); + command = words[1]; + if (command == 0xFF) + break; + TCHECK2(words[3], 2); + newsmboffset = EXTRACT_LE_16BITS(words + 3); + + fn = smbfind(command, smb_fns); + + printf("\nSMB PACKET: %s (%s) (CHAINED)\n", + fn->name, request ? "REQUEST" : "REPLY"); + if (newsmboffset <= smboffset) { + printf("Bad andX offset: %u <= %u\n", newsmboffset, smboffset); + break; + } + smboffset = newsmboffset; + } + + printf("\n"); + return; +trunc: + printf("[|SMB]"); + return; +} + + +/* + * print a NBT packet received across tcp on port 139 + */ +void +nbt_tcp_print(const u_char *data, int length) +{ + int caplen; + int type; + u_int nbt_len; + const u_char *maxbuf; + + if (length < 4) + goto trunc; + if (snapend < data) + goto trunc; + caplen = snapend - data; + if (caplen < 4) + goto trunc; + maxbuf = data + caplen; + type = data[0]; + nbt_len = EXTRACT_16BITS(data + 2); + length -= 4; + caplen -= 4; + + startbuf = data; + + if (vflag < 2) { + printf(" NBT Session Packet: "); + switch (type) { + case 0x00: + printf("Session Message"); + break; + + case 0x81: + printf("Session Request"); + break; + + case 0x82: + printf("Session Granted"); + break; + + case 0x83: + { + int ecode; + + if (nbt_len < 4) + goto trunc; + if (length < 4) + goto trunc; + if (caplen < 4) + goto trunc; + ecode = data[4]; + + printf("Session Reject, "); + switch (ecode) { + case 0x80: + printf("Not listening on called name"); + break; + case 0x81: + printf("Not listening for calling name"); + break; + case 0x82: + printf("Called name not present"); + break; + case 0x83: + printf("Called name present, but insufficient resources"); + break; + default: + printf("Unspecified error 0x%X", ecode); + break; + } + } + break; + + case 0x85: + printf("Session Keepalive"); + break; + + default: + data = smb_fdata(data, "Unknown packet type [rB]", maxbuf, 0); + break; + } + } else { + printf ("\n>>> NBT Session Packet\n"); + switch (type) { + case 0x00: + data = smb_fdata(data, "[P1]NBT Session Message\nFlags=[B]\nLength=[rd]\n", + data + 4, 0); + if (data == NULL) + break; + if (nbt_len >= 4 && caplen >= 4 && memcmp(data,"\377SMB",4) == 0) { + if ((int)nbt_len > caplen) { + if ((int)nbt_len > length) + printf("WARNING: Packet is continued in later TCP segments\n"); + else + printf("WARNING: Short packet. Try increasing the snap length by %d\n", + nbt_len - caplen); + } + print_smb(data, maxbuf > data + nbt_len ? data + nbt_len : maxbuf); + } else + printf("Session packet:(raw data or continuation?)\n"); + break; + + case 0x81: + data = smb_fdata(data, + "[P1]NBT Session Request\nFlags=[B]\nLength=[rd]\nDestination=[n1]\nSource=[n1]\n", + maxbuf, 0); + break; + + case 0x82: + data = smb_fdata(data, "[P1]NBT Session Granted\nFlags=[B]\nLength=[rd]\n", maxbuf, 0); + break; + + case 0x83: + { + const u_char *origdata; + int ecode; + + origdata = data; + data = smb_fdata(data, "[P1]NBT SessionReject\nFlags=[B]\nLength=[rd]\nReason=[B]\n", + maxbuf, 0); + if (data == NULL) + break; + if (nbt_len >= 1 && caplen >= 1) { + ecode = origdata[4]; + switch (ecode) { + case 0x80: + printf("Not listening on called name\n"); + break; + case 0x81: + printf("Not listening for calling name\n"); + break; + case 0x82: + printf("Called name not present\n"); + break; + case 0x83: + printf("Called name present, but insufficient resources\n"); + break; + default: + printf("Unspecified error 0x%X\n", ecode); + break; + } + } + } + break; + + case 0x85: + data = smb_fdata(data, "[P1]NBT Session Keepalive\nFlags=[B]\nLength=[rd]\n", maxbuf, 0); + break; + + default: + data = smb_fdata(data, "NBT - Unknown packet type\nType=[B]\n", maxbuf, 0); + break; + } + printf("\n"); + fflush(stdout); + } + return; +trunc: + printf("[|SMB]"); + return; +} + + +/* + * print a NBT packet received across udp on port 137 + */ +void +nbt_udp137_print(const u_char *data, int length) +{ + const u_char *maxbuf = data + length; + int name_trn_id, response, opcode, nm_flags, rcode; + int qdcount, ancount, nscount, arcount; + const char *opcodestr; + const u_char *p; + int total, i; + + TCHECK2(data[10], 2); + name_trn_id = EXTRACT_16BITS(data); + response = (data[2] >> 7); + opcode = (data[2] >> 3) & 0xF; + nm_flags = ((data[2] & 0x7) << 4) + (data[3] >> 4); + rcode = data[3] & 0xF; + qdcount = EXTRACT_16BITS(data + 4); + ancount = EXTRACT_16BITS(data + 6); + nscount = EXTRACT_16BITS(data + 8); + arcount = EXTRACT_16BITS(data + 10); + startbuf = data; + + if (maxbuf <= data) + return; + + if (vflag > 1) + printf("\n>>> "); + + printf("NBT UDP PACKET(137): "); + + switch (opcode) { + case 0: opcodestr = "QUERY"; break; + case 5: opcodestr = "REGISTRATION"; break; + case 6: opcodestr = "RELEASE"; break; + case 7: opcodestr = "WACK"; break; + case 8: opcodestr = "REFRESH(8)"; break; + case 9: opcodestr = "REFRESH"; break; + case 15: opcodestr = "MULTIHOMED REGISTRATION"; break; + default: opcodestr = "OPUNKNOWN"; break; + } + printf("%s", opcodestr); + if (response) { + if (rcode) + printf("; NEGATIVE"); + else + printf("; POSITIVE"); + } + + if (response) + printf("; RESPONSE"); + else + printf("; REQUEST"); + + if (nm_flags & 1) + printf("; BROADCAST"); + else + printf("; UNICAST"); + + if (vflag < 2) + return; + + printf("\nTrnID=0x%X\nOpCode=%d\nNmFlags=0x%X\nRcode=%d\nQueryCount=%d\nAnswerCount=%d\nAuthorityCount=%d\nAddressRecCount=%d\n", + name_trn_id, opcode, nm_flags, rcode, qdcount, ancount, nscount, + arcount); + + p = data + 12; + + total = ancount + nscount + arcount; + + if (qdcount > 100 || total > 100) { + printf("Corrupt packet??\n"); + return; + } + + if (qdcount) { + printf("QuestionRecords:\n"); + for (i = 0; i < qdcount; i++) { + p = smb_fdata(p, + "|Name=[n1]\nQuestionType=[rw]\nQuestionClass=[rw]\n#", + maxbuf, 0); + if (p == NULL) + goto out; + } + } + + if (total) { + printf("\nResourceRecords:\n"); + for (i = 0; i < total; i++) { + int rdlen; + int restype; + + p = smb_fdata(p, "Name=[n1]\n#", maxbuf, 0); + if (p == NULL) + goto out; + restype = EXTRACT_16BITS(p); + p = smb_fdata(p, "ResType=[rw]\nResClass=[rw]\nTTL=[rD]\n", p + 8, 0); + if (p == NULL) + goto out; + rdlen = EXTRACT_16BITS(p); + printf("ResourceLength=%d\nResourceData=\n", rdlen); + p += 2; + if (rdlen == 6) { + p = smb_fdata(p, "AddrType=[rw]\nAddress=[b.b.b.b]\n", p + rdlen, 0); + if (p == NULL) + goto out; + } else { + if (restype == 0x21) { + int numnames; + + TCHECK(*p); + numnames = p[0]; + p = smb_fdata(p, "NumNames=[B]\n", p + 1, 0); + if (p == NULL) + goto out; + while (numnames--) { + p = smb_fdata(p, "Name=[n2]\t#", maxbuf, 0); + if (p == NULL) + goto out; + TCHECK(*p); + if (p[0] & 0x80) + printf(" "); + switch (p[0] & 0x60) { + case 0x00: printf("B "); break; + case 0x20: printf("P "); break; + case 0x40: printf("M "); break; + case 0x60: printf("_ "); break; + } + if (p[0] & 0x10) + printf(" "); + if (p[0] & 0x08) + printf(" "); + if (p[0] & 0x04) + printf(" "); + if (p[0] & 0x02) + printf(" "); + printf("\n"); + p += 2; + } + } else { + print_data(p, min(rdlen, length - (p - data))); + p += rdlen; + } + } + } + } + + if (p < maxbuf) + smb_fdata(p, "AdditionalData:\n", maxbuf, 0); + +out: + printf("\n"); + fflush(stdout); + return; +trunc: + printf("[|SMB]"); + return; +} + +/* + * Print an SMB-over-TCP packet received across tcp on port 445 + */ +void +smb_tcp_print (const u_char * data, int length) +{ + int caplen; + u_int smb_len; + const u_char *maxbuf; + + if (length < 4) + goto trunc; + if (snapend < data) + goto trunc; + caplen = snapend - data; + if (caplen < 4) + goto trunc; + maxbuf = data + caplen; + smb_len = EXTRACT_24BITS(data + 1); + length -= 4; + caplen -= 4; + + startbuf = data; + data += 4; + + if (smb_len >= 4 && caplen >= 4 && memcmp(data,"\377SMB",4) == 0) { + if ((int)smb_len > caplen) { + if ((int)smb_len > length) + printf("WARNING: Packet is continued in later TCP segments\n"); + else + printf("WARNING: Short packet. Try increasing the snap length by %d\n", + smb_len - caplen); + } + print_smb(data, maxbuf > data + smb_len ? data + smb_len : maxbuf); + } else + printf("SMB-over-TCP packet:(raw data or continuation?)\n"); + return; +trunc: + printf("[|SMB]"); + return; +} + +/* + * print a NBT packet received across udp on port 138 + */ +void +nbt_udp138_print(const u_char *data, int length) +{ + const u_char *maxbuf = data + length; + + if (maxbuf > snapend) + maxbuf = snapend; + if (maxbuf <= data) + return; + startbuf = data; + + if (vflag < 2) { + printf("NBT UDP PACKET(138)"); + return; + } + + data = smb_fdata(data, + "\n>>> NBT UDP PACKET(138) Res=[rw] ID=[rw] IP=[b.b.b.b] Port=[rd] Length=[rd] Res2=[rw]\nSourceName=[n1]\nDestName=[n1]\n#", + maxbuf, 0); + + if (data != NULL) { + /* If there isn't enough data for "\377SMB", don't check for it. */ + if (&data[3] >= maxbuf) + goto out; + + if (memcmp(data, "\377SMB",4) == 0) + print_smb(data, maxbuf); + } +out: + printf("\n"); + fflush(stdout); +} + + +/* + print netbeui frames +*/ +struct nbf_strings { + const char *name; + const char *nonverbose; + const char *verbose; +} nbf_strings[0x20] = { + { "Add Group Name Query", ", [P23]Name to add=[n2]#", + "[P5]ResponseCorrelator=[w]\n[P16]Name to add=[n2]\n" }, + { "Add Name Query", ", [P23]Name to add=[n2]#", + "[P5]ResponseCorrelator=[w]\n[P16]Name to add=[n2]\n" }, + { "Name In Conflict", NULL, NULL }, + { "Status Query", NULL, NULL }, + { NULL, NULL, NULL }, /* not used */ + { NULL, NULL, NULL }, /* not used */ + { NULL, NULL, NULL }, /* not used */ + { "Terminate Trace", NULL, NULL }, + { "Datagram", NULL, + "[P7]Destination=[n2]\nSource=[n2]\n" }, + { "Broadcast Datagram", NULL, + "[P7]Destination=[n2]\nSource=[n2]\n" }, + { "Name Query", ", [P7]Name=[n2]#", + "[P1]SessionNumber=[B]\nNameType=[B][P2]\nResponseCorrelator=[w]\nName=[n2]\nName of sender=[n2]\n" }, + { NULL, NULL, NULL }, /* not used */ + { NULL, NULL, NULL }, /* not used */ + { "Add Name Response", ", [P1]GroupName=[w] [P4]Destination=[n2] Source=[n2]#", + "AddNameInProcess=[B]\nGroupName=[w]\nTransmitCorrelator=[w][P2]\nDestination=[n2]\nSource=[n2]\n" }, + { "Name Recognized", NULL, + "[P1]Data2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nDestination=[n2]\nSource=[n2]\n" }, + { "Status Response", NULL, NULL }, + { NULL, NULL, NULL }, /* not used */ + { NULL, NULL, NULL }, /* not used */ + { NULL, NULL, NULL }, /* not used */ + { "Terminate Trace", NULL, NULL }, + { "Data Ack", NULL, + "[P3]TransmitCorrelator=[w][P2]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "Data First/Middle", NULL, + "Flags=[{RECEIVE_CONTINUE|NO_ACK||PIGGYBACK_ACK_INCLUDED|}]\nResyncIndicator=[w][P2]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "Data Only/Last", NULL, + "Flags=[{|NO_ACK|PIGGYBACK_ACK_ALLOWED|PIGGYBACK_ACK_INCLUDED|}]\nResyncIndicator=[w][P2]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "Session Confirm", NULL, + "Data1=[B]\nData2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "Session End", NULL, + "[P1]Data2=[w][P4]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "Session Initialize", NULL, + "Data1=[B]\nData2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "No Receive", NULL, + "Flags=[{|SEND_NO_ACK}]\nDataBytesAccepted=[b][P4]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "Receive Outstanding", NULL, + "[P1]DataBytesAccepted=[b][P4]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { "Receive Continue", NULL, + "[P2]TransmitCorrelator=[w]\n[P2]RemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" }, + { NULL, NULL, NULL }, /* not used */ + { NULL, NULL, NULL }, /* not used */ + { "Session Alive", NULL, NULL } +}; + +void +netbeui_print(u_short control, const u_char *data, int length) +{ + const u_char *maxbuf = data + length; + int len; + int command; + const u_char *data2; + int is_truncated = 0; + + if (maxbuf > snapend) + maxbuf = snapend; + TCHECK(data[4]); + len = EXTRACT_LE_16BITS(data); + command = data[4]; + data2 = data + len; + if (data2 >= maxbuf) { + data2 = maxbuf; + is_truncated = 1; + } + + startbuf = data; + + if (vflag < 2) { + printf("NBF Packet: "); + data = smb_fdata(data, "[P5]#", maxbuf, 0); + } else { + printf("\n>>> NBF Packet\nType=0x%X ", control); + data = smb_fdata(data, "Length=[d] Signature=[w] Command=[B]\n#", maxbuf, 0); + } + if (data == NULL) + goto out; + + if (command > 0x1f || nbf_strings[command].name == NULL) { + if (vflag < 2) + data = smb_fdata(data, "Unknown NBF Command#", data2, 0); + else + data = smb_fdata(data, "Unknown NBF Command\n", data2, 0); + } else { + if (vflag < 2) { + printf("%s", nbf_strings[command].name); + if (nbf_strings[command].nonverbose != NULL) + data = smb_fdata(data, nbf_strings[command].nonverbose, data2, 0); + } else { + printf("%s:\n", nbf_strings[command].name); + if (nbf_strings[command].verbose != NULL) + data = smb_fdata(data, nbf_strings[command].verbose, data2, 0); + else + printf("\n"); + } + } + + if (vflag < 2) + return; + + if (data == NULL) + goto out; + + if (is_truncated) { + /* data2 was past the end of the buffer */ + goto out; + } + + /* If this isn't a command that would contain an SMB message, quit. */ + if (command != 0x08 && command != 0x09 && command != 0x15 && + command != 0x16) + goto out; + + /* If there isn't enough data for "\377SMB", don't look for it. */ + if (&data2[3] >= maxbuf) + goto out; + + if (memcmp(data2, "\377SMB",4) == 0) + print_smb(data2, maxbuf); + else { + int i; + for (i = 0; i < 128; i++) { + if (&data2[i + 3] >= maxbuf) + break; + if (memcmp(&data2[i], "\377SMB", 4) == 0) { + printf("found SMB packet at %d\n", i); + print_smb(&data2[i], maxbuf); + break; + } + } + } + +out: + printf("\n"); + return; +trunc: + printf("[|SMB]"); + return; +} + + +/* + * print IPX-Netbios frames + */ +void +ipx_netbios_print(const u_char *data, u_int length) +{ + /* + * this is a hack till I work out how to parse the rest of the + * NetBIOS-over-IPX stuff + */ + int i; + const u_char *maxbuf; + + maxbuf = data + length; + /* Don't go past the end of the captured data in the packet. */ + if (maxbuf > snapend) + maxbuf = snapend; + startbuf = data; + for (i = 0; i < 128; i++) { + if (&data[i + 4] > maxbuf) + break; + if (memcmp(&data[i], "\377SMB", 4) == 0) { + smb_fdata(data, "\n>>> IPX transport ", &data[i], 0); + print_smb(&data[i], maxbuf); + printf("\n"); + fflush(stdout); + break; + } + } + if (i == 128) + smb_fdata(data, "\n>>> Unknown IPX ", maxbuf, 0); +} diff --git a/print-snmp.c b/print-snmp.c new file mode 100644 index 0000000..728da6b --- /dev/null +++ b/print-snmp.c @@ -0,0 +1,1904 @@ +/* + * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 + * John Robert LoVerso. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * This implementation has been influenced by the CMU SNMP release, + * by Steve Waldbusser. However, this shares no code with that system. + * Additional ASN.1 insight gained from Marshall T. Rose's _The_Open_Book_. + * Earlier forms of this implementation were derived and/or inspired by an + * awk script originally written by C. Philip Wood of LANL (but later + * heavily modified by John Robert LoVerso). The copyright notice for + * that work is preserved below, even though it may not rightly apply + * to this file. + * + * Support for SNMPv2c/SNMPv3 and the ability to link the module against + * the libsmi was added by J. Schoenwaelder, Copyright (c) 1999. + * + * This started out as a very simple program, but the incremental decoding + * (into the BE structure) complicated things. + * + # Los Alamos National Laboratory + # + # Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 + # This software was produced under a U.S. Government contract + # (W-7405-ENG-36) by Los Alamos National Laboratory, which is + # operated by the University of California for the U.S. Department + # of Energy. The U.S. Government is licensed to use, reproduce, + # and distribute this software. Permission is granted to the + # public to copy and use this software without charge, provided + # that this Notice and any statement of authorship are reproduced + # on all copies. Neither the Government nor the University makes + # any warranty, express or implied, or assumes any liability or + # responsibility for the use of this software. + # @(#)snmp.awk.x 1.1 (LANL) 1/15/90 + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-snmp.c,v 1.64 2005-05-06 07:56:53 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#ifdef HAVE_SMI_H +#include +#endif + +#include "interface.h" +#include "addrtoname.h" + +#undef OPAQUE /* defined in */ + +/* + * Universal ASN.1 types + * (we only care about the tag values for those allowed in the Internet SMI) + */ +const char *Universal[] = { + "U-0", + "Boolean", + "Integer", +#define INTEGER 2 + "Bitstring", + "String", +#define STRING 4 + "Null", +#define ASN_NULL 5 + "ObjID", +#define OBJECTID 6 + "ObjectDes", + "U-8","U-9","U-10","U-11", /* 8-11 */ + "U-12","U-13","U-14","U-15", /* 12-15 */ + "Sequence", +#define SEQUENCE 16 + "Set" +}; + +/* + * Application-wide ASN.1 types from the Internet SMI and their tags + */ +const char *Application[] = { + "IpAddress", +#define IPADDR 0 + "Counter", +#define COUNTER 1 + "Gauge", +#define GAUGE 2 + "TimeTicks", +#define TIMETICKS 3 + "Opaque", +#define OPAQUE 4 + "C-5", + "Counter64" +#define COUNTER64 6 +}; + +/* + * Context-specific ASN.1 types for the SNMP PDUs and their tags + */ +const char *Context[] = { + "GetRequest", +#define GETREQ 0 + "GetNextRequest", +#define GETNEXTREQ 1 + "GetResponse", +#define GETRESP 2 + "SetRequest", +#define SETREQ 3 + "Trap", +#define TRAP 4 + "GetBulk", +#define GETBULKREQ 5 + "Inform", +#define INFORMREQ 6 + "V2Trap", +#define V2TRAP 7 + "Report" +#define REPORT 8 +}; + +#define NOTIFY_CLASS(x) (x == TRAP || x == V2TRAP || x == INFORMREQ) +#define READ_CLASS(x) (x == GETREQ || x == GETNEXTREQ || x == GETBULKREQ) +#define WRITE_CLASS(x) (x == SETREQ) +#define RESPONSE_CLASS(x) (x == GETRESP) +#define INTERNAL_CLASS(x) (x == REPORT) + +/* + * Context-specific ASN.1 types for the SNMP Exceptions and their tags + */ +const char *Exceptions[] = { + "noSuchObject", +#define NOSUCHOBJECT 0 + "noSuchInstance", +#define NOSUCHINSTANCE 1 + "endOfMibView", +#define ENDOFMIBVIEW 2 +}; + +/* + * Private ASN.1 types + * The Internet SMI does not specify any + */ +const char *Private[] = { + "P-0" +}; + +/* + * error-status values for any SNMP PDU + */ +const char *ErrorStatus[] = { + "noError", + "tooBig", + "noSuchName", + "badValue", + "readOnly", + "genErr", + "noAccess", + "wrongType", + "wrongLength", + "wrongEncoding", + "wrongValue", + "noCreation", + "inconsistentValue", + "resourceUnavailable", + "commitFailed", + "undoFailed", + "authorizationError", + "notWritable", + "inconsistentName" +}; +#define DECODE_ErrorStatus(e) \ + ( e >= 0 && (size_t)e < sizeof(ErrorStatus)/sizeof(ErrorStatus[0]) \ + ? ErrorStatus[e] \ + : (snprintf(errbuf, sizeof(errbuf), "err=%u", e), errbuf)) + +/* + * generic-trap values in the SNMP Trap-PDU + */ +const char *GenericTrap[] = { + "coldStart", + "warmStart", + "linkDown", + "linkUp", + "authenticationFailure", + "egpNeighborLoss", + "enterpriseSpecific" +#define GT_ENTERPRISE 6 +}; +#define DECODE_GenericTrap(t) \ + ( t >= 0 && (size_t)t < sizeof(GenericTrap)/sizeof(GenericTrap[0]) \ + ? GenericTrap[t] \ + : (snprintf(buf, sizeof(buf), "gt=%d", t), buf)) + +/* + * ASN.1 type class table + * Ties together the preceding Universal, Application, Context, and Private + * type definitions. + */ +#define defineCLASS(x) { "x", x, sizeof(x)/sizeof(x[0]) } /* not ANSI-C */ +struct { + const char *name; + const char **Id; + int numIDs; + } Class[] = { + defineCLASS(Universal), +#define UNIVERSAL 0 + defineCLASS(Application), +#define APPLICATION 1 + defineCLASS(Context), +#define CONTEXT 2 + defineCLASS(Private), +#define PRIVATE 3 + defineCLASS(Exceptions), +#define EXCEPTIONS 4 +}; + +/* + * defined forms for ASN.1 types + */ +const char *Form[] = { + "Primitive", +#define PRIMITIVE 0 + "Constructed", +#define CONSTRUCTED 1 +}; + +/* + * A structure for the OID tree for the compiled-in MIB. + * This is stored as a general-order tree. + */ +struct obj { + const char *desc; /* name of object */ + u_char oid; /* sub-id following parent */ + u_char type; /* object type (unused) */ + struct obj *child, *next; /* child and next sibling pointers */ +} *objp = NULL; + +/* + * Include the compiled in SNMP MIB. "mib.h" is produced by feeding + * RFC-1156 format files into "makemib". "mib.h" MUST define at least + * a value for `mibroot'. + * + * In particular, this is gross, as this is including initialized structures, + * and by right shouldn't be an "include" file. + */ +#include "mib.h" + +/* + * This defines a list of OIDs which will be abbreviated on output. + * Currently, this includes the prefixes for the Internet MIB, the + * private enterprises tree, and the experimental tree. + */ +struct obj_abrev { + const char *prefix; /* prefix for this abrev */ + struct obj *node; /* pointer into object table */ + const char *oid; /* ASN.1 encoded OID */ +} obj_abrev_list[] = { +#ifndef NO_ABREV_MIB + /* .iso.org.dod.internet.mgmt.mib */ + { "", &_mib_obj, "\53\6\1\2\1" }, +#endif +#ifndef NO_ABREV_ENTER + /* .iso.org.dod.internet.private.enterprises */ + { "E:", &_enterprises_obj, "\53\6\1\4\1" }, +#endif +#ifndef NO_ABREV_EXPERI + /* .iso.org.dod.internet.experimental */ + { "X:", &_experimental_obj, "\53\6\1\3" }, +#endif +#ifndef NO_ABBREV_SNMPMODS + /* .iso.org.dod.internet.snmpV2.snmpModules */ + { "S:", &_snmpModules_obj, "\53\6\1\6\3" }, +#endif + { 0,0,0 } +}; + +/* + * This is used in the OID print routine to walk down the object tree + * rooted at `mibroot'. + */ +#define OBJ_PRINT(o, suppressdot) \ +{ \ + if (objp) { \ + do { \ + if ((o) == objp->oid) \ + break; \ + } while ((objp = objp->next) != NULL); \ + } \ + if (objp) { \ + printf(suppressdot?"%s":".%s", objp->desc); \ + objp = objp->child; \ + } else \ + printf(suppressdot?"%u":".%u", (o)); \ +} + +/* + * This is the definition for the Any-Data-Type storage used purely for + * temporary internal representation while decoding an ASN.1 data stream. + */ +struct be { + u_int32_t asnlen; + union { + caddr_t raw; + int32_t integer; + u_int32_t uns; + const u_char *str; + struct { + u_int32_t high; + u_int32_t low; + } uns64; + } data; + u_short id; + u_char form, class; /* tag info */ + u_char type; +#define BE_ANY 255 +#define BE_NONE 0 +#define BE_NULL 1 +#define BE_OCTET 2 +#define BE_OID 3 +#define BE_INT 4 +#define BE_UNS 5 +#define BE_STR 6 +#define BE_SEQ 7 +#define BE_INETADDR 8 +#define BE_PDU 9 +#define BE_UNS64 10 +#define BE_NOSUCHOBJECT 128 +#define BE_NOSUCHINST 129 +#define BE_ENDOFMIBVIEW 130 +}; + +/* + * SNMP versions recognized by this module + */ +const char *SnmpVersion[] = { + "SNMPv1", +#define SNMP_VERSION_1 0 + "SNMPv2c", +#define SNMP_VERSION_2 1 + "SNMPv2u", +#define SNMP_VERSION_2U 2 + "SNMPv3" +#define SNMP_VERSION_3 3 +}; + +/* + * Defaults for SNMP PDU components + */ +#define DEF_COMMUNITY "public" + +/* + * constants for ASN.1 decoding + */ +#define OIDMUX 40 +#define ASNLEN_INETADDR 4 +#define ASN_SHIFT7 7 +#define ASN_SHIFT8 8 +#define ASN_BIT8 0x80 +#define ASN_LONGLEN 0x80 + +#define ASN_ID_BITS 0x1f +#define ASN_FORM_BITS 0x20 +#define ASN_FORM_SHIFT 5 +#define ASN_CLASS_BITS 0xc0 +#define ASN_CLASS_SHIFT 6 + +#define ASN_ID_EXT 0x1f /* extension ID in tag field */ + +/* + * This decodes the next ASN.1 object in the stream pointed to by "p" + * (and of real-length "len") and stores the intermediate data in the + * provided BE object. + * + * This returns -l if it fails (i.e., the ASN.1 stream is not valid). + * O/w, this returns the number of bytes parsed from "p". + */ +static int +asn1_parse(register const u_char *p, u_int len, struct be *elem) +{ + u_char form, class, id; + int i, hdr; + + elem->asnlen = 0; + elem->type = BE_ANY; + if (len < 1) { + fputs("[nothing to parse]", stdout); + return -1; + } + TCHECK(*p); + + /* + * it would be nice to use a bit field, but you can't depend on them. + * +---+---+---+---+---+---+---+---+ + * + class |frm| id | + * +---+---+---+---+---+---+---+---+ + * 7 6 5 4 3 2 1 0 + */ + id = *p & ASN_ID_BITS; /* lower 5 bits, range 00-1f */ +#ifdef notdef + form = (*p & 0xe0) >> 5; /* move upper 3 bits to lower 3 */ + class = form >> 1; /* bits 7&6 -> bits 1&0, range 0-3 */ + form &= 0x1; /* bit 5 -> bit 0, range 0-1 */ +#else + form = (u_char)(*p & ASN_FORM_BITS) >> ASN_FORM_SHIFT; + class = (u_char)(*p & ASN_CLASS_BITS) >> ASN_CLASS_SHIFT; +#endif + elem->form = form; + elem->class = class; + elem->id = id; + p++; len--; hdr = 1; + /* extended tag field */ + if (id == ASN_ID_EXT) { + /* + * The ID follows, as a sequence of octets with the + * 8th bit set and the remaining 7 bits being + * the next 7 bits of the value, terminated with + * an octet with the 8th bit not set. + * + * First, assemble all the octets with the 8th + * bit set. XXX - this doesn't handle a value + * that won't fit in 32 bits. + */ + for (id = 0; *p & ASN_BIT8; len--, hdr++, p++) { + if (len < 1) { + fputs("[Xtagfield?]", stdout); + return -1; + } + TCHECK(*p); + id = (id << 7) | (*p & ~ASN_BIT8); + } + if (len < 1) { + fputs("[Xtagfield?]", stdout); + return -1; + } + TCHECK(*p); + elem->id = id = (id << 7) | *p; + --len; + ++hdr; + ++p; + } + if (len < 1) { + fputs("[no asnlen]", stdout); + return -1; + } + TCHECK(*p); + elem->asnlen = *p; + p++; len--; hdr++; + if (elem->asnlen & ASN_BIT8) { + u_int32_t noct = elem->asnlen % ASN_BIT8; + elem->asnlen = 0; + if (len < noct) { + printf("[asnlen? %d<%d]", len, noct); + return -1; + } + TCHECK2(*p, noct); + for (; noct-- > 0; len--, hdr++) + elem->asnlen = (elem->asnlen << ASN_SHIFT8) | *p++; + } + if (len < elem->asnlen) { + printf("[len%dasnlen); + return -1; + } + if (form >= sizeof(Form)/sizeof(Form[0])) { + printf("[form?%d]", form); + return -1; + } + if (class >= sizeof(Class)/sizeof(Class[0])) { + printf("[class?%c/%d]", *Form[form], class); + return -1; + } + if ((int)id >= Class[class].numIDs) { + printf("[id?%c/%s/%d]", *Form[form], Class[class].name, id); + return -1; + } + + switch (form) { + case PRIMITIVE: + switch (class) { + case UNIVERSAL: + switch (id) { + case STRING: + elem->type = BE_STR; + elem->data.str = p; + break; + + case INTEGER: { + register int32_t data; + elem->type = BE_INT; + data = 0; + + TCHECK2(*p, elem->asnlen); + if (*p & ASN_BIT8) /* negative */ + data = -1; + for (i = elem->asnlen; i-- > 0; p++) + data = (data << ASN_SHIFT8) | *p; + elem->data.integer = data; + break; + } + + case OBJECTID: + elem->type = BE_OID; + elem->data.raw = (caddr_t)p; + break; + + case ASN_NULL: + elem->type = BE_NULL; + elem->data.raw = NULL; + break; + + default: + elem->type = BE_OCTET; + elem->data.raw = (caddr_t)p; + printf("[P/U/%s]", + Class[class].Id[id]); + break; + } + break; + + case APPLICATION: + switch (id) { + case IPADDR: + elem->type = BE_INETADDR; + elem->data.raw = (caddr_t)p; + break; + + case COUNTER: + case GAUGE: + case TIMETICKS: { + register u_int32_t data; + TCHECK2(*p, elem->asnlen); + elem->type = BE_UNS; + data = 0; + for (i = elem->asnlen; i-- > 0; p++) + data = (data << 8) + *p; + elem->data.uns = data; + break; + } + + case COUNTER64: { + register u_int32_t high, low; + TCHECK2(*p, elem->asnlen); + elem->type = BE_UNS64; + high = 0, low = 0; + for (i = elem->asnlen; i-- > 0; p++) { + high = (high << 8) | + ((low & 0xFF000000) >> 24); + low = (low << 8) | *p; + } + elem->data.uns64.high = high; + elem->data.uns64.low = low; + break; + } + + default: + elem->type = BE_OCTET; + elem->data.raw = (caddr_t)p; + printf("[P/A/%s]", + Class[class].Id[id]); + break; + } + break; + + case CONTEXT: + switch (id) { + case NOSUCHOBJECT: + elem->type = BE_NOSUCHOBJECT; + elem->data.raw = NULL; + break; + + case NOSUCHINSTANCE: + elem->type = BE_NOSUCHINST; + elem->data.raw = NULL; + break; + + case ENDOFMIBVIEW: + elem->type = BE_ENDOFMIBVIEW; + elem->data.raw = NULL; + break; + } + break; + + default: + printf("[P/%s/%s]", + Class[class].name, Class[class].Id[id]); + TCHECK2(*p, elem->asnlen); + elem->type = BE_OCTET; + elem->data.raw = (caddr_t)p; + break; + } + break; + + case CONSTRUCTED: + switch (class) { + case UNIVERSAL: + switch (id) { + case SEQUENCE: + elem->type = BE_SEQ; + elem->data.raw = (caddr_t)p; + break; + + default: + elem->type = BE_OCTET; + elem->data.raw = (caddr_t)p; + printf("C/U/%s", Class[class].Id[id]); + break; + } + break; + + case CONTEXT: + elem->type = BE_PDU; + elem->data.raw = (caddr_t)p; + break; + + default: + elem->type = BE_OCTET; + elem->data.raw = (caddr_t)p; + printf("C/%s/%s", + Class[class].name, Class[class].Id[id]); + break; + } + break; + } + p += elem->asnlen; + len -= elem->asnlen; + return elem->asnlen + hdr; + +trunc: + fputs("[|snmp]", stdout); + return -1; +} + +/* + * Display the ASN.1 object represented by the BE object. + * This used to be an integral part of asn1_parse() before the intermediate + * BE form was added. + */ +static int +asn1_print(struct be *elem) +{ + u_char *p = (u_char *)elem->data.raw; + u_int32_t asnlen = elem->asnlen; + u_int32_t i; + + switch (elem->type) { + + case BE_OCTET: + TCHECK2(*p, asnlen); + for (i = asnlen; i-- > 0; p++) + printf("_%.2x", *p); + break; + + case BE_NULL: + break; + + case BE_OID: { + int o = 0, first = -1, i = asnlen; + + if (!sflag && !nflag && asnlen > 2) { + struct obj_abrev *a = &obj_abrev_list[0]; + size_t a_len = strlen(a->oid); + for (; a->node; a++) { + TCHECK2(*p, a_len); + if (memcmp(a->oid, (char *)p, a_len) == 0) { + objp = a->node->child; + i -= strlen(a->oid); + p += strlen(a->oid); + fputs(a->prefix, stdout); + first = 1; + break; + } + } + } + + for (; !sflag && i-- > 0; p++) { + TCHECK(*p); + o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8); + if (*p & ASN_LONGLEN) + continue; + + /* + * first subitem encodes two items with 1st*OIDMUX+2nd + * (see X.690:1997 clause 8.19 for the details) + */ + if (first < 0) { + int s; + if (!nflag) + objp = mibroot; + first = 0; + s = o / OIDMUX; + if (s > 2) s = 2; + OBJ_PRINT(s, first); + o -= s * OIDMUX; + } + OBJ_PRINT(o, first); + if (--first < 0) + first = 0; + o = 0; + } + break; + } + + case BE_INT: + printf("%d", elem->data.integer); + break; + + case BE_UNS: + printf("%u", elem->data.uns); + break; + + case BE_UNS64: { /* idea borrowed from by Marshall Rose */ + double d; + int j, carry; + char *cpf, *cpl, last[6], first[30]; + if (elem->data.uns64.high == 0) { + printf("%u", elem->data.uns64.low); + break; + } + d = elem->data.uns64.high * 4294967296.0; /* 2^32 */ + if (elem->data.uns64.high <= 0x1fffff) { + d += elem->data.uns64.low; +#if 0 /*is looks illegal, but what is the intention?*/ + printf("%.f", d); +#else + printf("%f", d); +#endif + break; + } + d += (elem->data.uns64.low & 0xfffff000); +#if 0 /*is looks illegal, but what is the intention?*/ + snprintf(first, sizeof(first), "%.f", d); +#else + snprintf(first, sizeof(first), "%f", d); +#endif + snprintf(last, sizeof(last), "%5.5d", + elem->data.uns64.low & 0xfff); + for (carry = 0, cpf = first+strlen(first)-1, cpl = last+4; + cpl >= last; + cpf--, cpl--) { + j = carry + (*cpf - '0') + (*cpl - '0'); + if (j > 9) { + j -= 10; + carry = 1; + } else { + carry = 0; + } + *cpf = j + '0'; + } + fputs(first, stdout); + break; + } + + case BE_STR: { + register int printable = 1, first = 1; + const u_char *p = elem->data.str; + TCHECK2(*p, asnlen); + for (i = asnlen; printable && i-- > 0; p++) + printable = isprint(*p) || isspace(*p); + p = elem->data.str; + if (printable) { + putchar('"'); + if (fn_printn(p, asnlen, snapend)) { + putchar('"'); + goto trunc; + } + putchar('"'); + } else + for (i = asnlen; i-- > 0; p++) { + printf(first ? "%.2x" : "_%.2x", *p); + first = 0; + } + break; + } + + case BE_SEQ: + printf("Seq(%u)", elem->asnlen); + break; + + case BE_INETADDR: + if (asnlen != ASNLEN_INETADDR) + printf("[inetaddr len!=%d]", ASNLEN_INETADDR); + TCHECK2(*p, asnlen); + for (i = asnlen; i-- != 0; p++) { + printf((i == asnlen-1) ? "%u" : ".%u", *p); + } + break; + + case BE_NOSUCHOBJECT: + case BE_NOSUCHINST: + case BE_ENDOFMIBVIEW: + printf("[%s]", Class[EXCEPTIONS].Id[elem->id]); + break; + + case BE_PDU: + printf("%s(%u)", + Class[CONTEXT].Id[elem->id], elem->asnlen); + break; + + case BE_ANY: + fputs("[BE_ANY!?]", stdout); + break; + + default: + fputs("[be!?]", stdout); + break; + } + return 0; + +trunc: + fputs("[|snmp]", stdout); + return -1; +} + +#ifdef notdef +/* + * This is a brute force ASN.1 printer: recurses to dump an entire structure. + * This will work for any ASN.1 stream, not just an SNMP PDU. + * + * By adding newlines and spaces at the correct places, this would print in + * Rose-Normal-Form. + * + * This is not currently used. + */ +static void +asn1_decode(u_char *p, u_int length) +{ + struct be elem; + int i = 0; + + while (i >= 0 && length > 0) { + i = asn1_parse(p, length, &elem); + if (i >= 0) { + fputs(" ", stdout); + if (asn1_print(&elem) < 0) + return; + if (elem.type == BE_SEQ || elem.type == BE_PDU) { + fputs(" {", stdout); + asn1_decode(elem.data.raw, elem.asnlen); + fputs(" }", stdout); + } + length -= i; + p += i; + } + } +} +#endif + +#ifdef LIBSMI + +struct smi2be { + SmiBasetype basetype; + int be; +}; + +static struct smi2be smi2betab[] = { + { SMI_BASETYPE_INTEGER32, BE_INT }, + { SMI_BASETYPE_OCTETSTRING, BE_STR }, + { SMI_BASETYPE_OCTETSTRING, BE_INETADDR }, + { SMI_BASETYPE_OBJECTIDENTIFIER, BE_OID }, + { SMI_BASETYPE_UNSIGNED32, BE_UNS }, + { SMI_BASETYPE_INTEGER64, BE_NONE }, + { SMI_BASETYPE_UNSIGNED64, BE_UNS64 }, + { SMI_BASETYPE_FLOAT32, BE_NONE }, + { SMI_BASETYPE_FLOAT64, BE_NONE }, + { SMI_BASETYPE_FLOAT128, BE_NONE }, + { SMI_BASETYPE_ENUM, BE_INT }, + { SMI_BASETYPE_BITS, BE_STR }, + { SMI_BASETYPE_UNKNOWN, BE_NONE } +}; + +static int +smi_decode_oid(struct be *elem, unsigned int *oid, + unsigned int oidsize, unsigned int *oidlen) +{ + u_char *p = (u_char *)elem->data.raw; + u_int32_t asnlen = elem->asnlen; + int o = 0, first = -1, i = asnlen; + + for (*oidlen = 0; sflag && i-- > 0; p++) { + TCHECK(*p); + o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8); + if (*p & ASN_LONGLEN) + continue; + + /* + * first subitem encodes two items with 1st*OIDMUX+2nd + * (see X.690:1997 clause 8.19 for the details) + */ + if (first < 0) { + first = 0; + if (*oidlen < oidsize) { + oid[*oidlen] = o / OIDMUX; + if (oid[*oidlen] > 2) oid[*oidlen] = 2; + } + o -= oid[*oidlen] * OIDMUX; + if (*oidlen < oidsize) (*oidlen)++; + } + if (*oidlen < oidsize) { + oid[(*oidlen)++] = o; + } + o = 0; + } + return 0; + +trunc: + fputs("[|snmp]", stdout); + return -1; +} + +static int smi_check_type(SmiBasetype basetype, int be) +{ + int i; + + for (i = 0; smi2betab[i].basetype != SMI_BASETYPE_UNKNOWN; i++) { + if (smi2betab[i].basetype == basetype && smi2betab[i].be == be) { + return 1; + } + } + + return 0; +} + +static int smi_check_a_range(SmiType *smiType, SmiRange *smiRange, + struct be *elem) +{ + int ok = 1; + + switch (smiType->basetype) { + case SMI_BASETYPE_OBJECTIDENTIFIER: + case SMI_BASETYPE_OCTETSTRING: + if (smiRange->minValue.value.unsigned32 + == smiRange->maxValue.value.unsigned32) { + ok = (elem->asnlen == smiRange->minValue.value.unsigned32); + } else { + ok = (elem->asnlen >= smiRange->minValue.value.unsigned32 + && elem->asnlen <= smiRange->maxValue.value.unsigned32); + } + break; + + case SMI_BASETYPE_INTEGER32: + ok = (elem->data.integer >= smiRange->minValue.value.integer32 + && elem->data.integer <= smiRange->maxValue.value.integer32); + break; + + case SMI_BASETYPE_UNSIGNED32: + ok = (elem->data.uns >= smiRange->minValue.value.unsigned32 + && elem->data.uns <= smiRange->maxValue.value.unsigned32); + break; + + case SMI_BASETYPE_UNSIGNED64: + /* XXX */ + break; + + /* case SMI_BASETYPE_INTEGER64: SMIng */ + /* case SMI_BASETYPE_FLOAT32: SMIng */ + /* case SMI_BASETYPE_FLOAT64: SMIng */ + /* case SMI_BASETYPE_FLOAT128: SMIng */ + + case SMI_BASETYPE_ENUM: + case SMI_BASETYPE_BITS: + case SMI_BASETYPE_UNKNOWN: + ok = 1; + break; + + default: + ok = 0; + break; + } + + return ok; +} + +static int smi_check_range(SmiType *smiType, struct be *elem) +{ + SmiRange *smiRange; + int ok = 1; + + for (smiRange = smiGetFirstRange(smiType); + smiRange; + smiRange = smiGetNextRange(smiRange)) { + + ok = smi_check_a_range(smiType, smiRange, elem); + + if (ok) { + break; + } + } + + if (ok) { + SmiType *parentType; + parentType = smiGetParentType(smiType); + if (parentType) { + ok = smi_check_range(parentType, elem); + } + } + + return ok; +} + +static SmiNode *smi_print_variable(struct be *elem, int *status) +{ + unsigned int oid[128], oidlen; + SmiNode *smiNode = NULL; + unsigned int i; + + *status = smi_decode_oid(elem, oid, sizeof(oid)/sizeof(unsigned int), + &oidlen); + if (*status < 0) + return NULL; + smiNode = smiGetNodeByOID(oidlen, oid); + if (! smiNode) { + *status = asn1_print(elem); + return NULL; + } + if (vflag) { + fputs(smiGetNodeModule(smiNode)->name, stdout); + fputs("::", stdout); + } + fputs(smiNode->name, stdout); + if (smiNode->oidlen < oidlen) { + for (i = smiNode->oidlen; i < oidlen; i++) { + printf(".%u", oid[i]); + } + } + *status = 0; + return smiNode; +} + +static int +smi_print_value(SmiNode *smiNode, u_char pduid, struct be *elem) +{ + unsigned int i, oid[128], oidlen; + SmiType *smiType; + SmiNamedNumber *nn; + int done = 0; + + if (! smiNode || ! (smiNode->nodekind + & (SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN))) { + return asn1_print(elem); + } + + if (elem->type == BE_NOSUCHOBJECT + || elem->type == BE_NOSUCHINST + || elem->type == BE_ENDOFMIBVIEW) { + return asn1_print(elem); + } + + if (NOTIFY_CLASS(pduid) && smiNode->access < SMI_ACCESS_NOTIFY) { + fputs("[notNotifyable]", stdout); + } + + if (READ_CLASS(pduid) && smiNode->access < SMI_ACCESS_READ_ONLY) { + fputs("[notReadable]", stdout); + } + + if (WRITE_CLASS(pduid) && smiNode->access < SMI_ACCESS_READ_WRITE) { + fputs("[notWritable]", stdout); + } + + if (RESPONSE_CLASS(pduid) + && smiNode->access == SMI_ACCESS_NOT_ACCESSIBLE) { + fputs("[noAccess]", stdout); + } + + smiType = smiGetNodeType(smiNode); + if (! smiType) { + return asn1_print(elem); + } + + if (! smi_check_type(smiType->basetype, elem->type)) { + fputs("[wrongType]", stdout); + } + + if (! smi_check_range(smiType, elem)) { + fputs("[outOfRange]", stdout); + } + + /* resolve bits to named bits */ + + /* check whether instance identifier is valid */ + + /* apply display hints (integer, octetstring) */ + + /* convert instance identifier to index type values */ + + switch (elem->type) { + case BE_OID: + if (smiType->basetype == SMI_BASETYPE_BITS) { + /* print bit labels */ + } else { + smi_decode_oid(elem, oid, + sizeof(oid)/sizeof(unsigned int), + &oidlen); + smiNode = smiGetNodeByOID(oidlen, oid); + if (smiNode) { + if (vflag) { + fputs(smiGetNodeModule(smiNode)->name, stdout); + fputs("::", stdout); + } + fputs(smiNode->name, stdout); + if (smiNode->oidlen < oidlen) { + for (i = smiNode->oidlen; + i < oidlen; i++) { + printf(".%u", oid[i]); + } + } + done++; + } + } + break; + + case BE_INT: + if (smiType->basetype == SMI_BASETYPE_ENUM) { + for (nn = smiGetFirstNamedNumber(smiType); + nn; + nn = smiGetNextNamedNumber(nn)) { + if (nn->value.value.integer32 + == elem->data.integer) { + fputs(nn->name, stdout); + printf("(%d)", elem->data.integer); + done++; + break; + } + } + } + break; + } + + if (! done) { + return asn1_print(elem); + } + return 0; +} +#endif + +/* + * General SNMP header + * SEQUENCE { + * version INTEGER {version-1(0)}, + * community OCTET STRING, + * data ANY -- PDUs + * } + * PDUs for all but Trap: (see rfc1157 from page 15 on) + * SEQUENCE { + * request-id INTEGER, + * error-status INTEGER, + * error-index INTEGER, + * varbindlist SEQUENCE OF + * SEQUENCE { + * name ObjectName, + * value ObjectValue + * } + * } + * PDU for Trap: + * SEQUENCE { + * enterprise OBJECT IDENTIFIER, + * agent-addr NetworkAddress, + * generic-trap INTEGER, + * specific-trap INTEGER, + * time-stamp TimeTicks, + * varbindlist SEQUENCE OF + * SEQUENCE { + * name ObjectName, + * value ObjectValue + * } + * } + */ + +/* + * Decode SNMP varBind + */ +static void +varbind_print(u_char pduid, const u_char *np, u_int length) +{ + struct be elem; + int count = 0, ind; +#ifdef LIBSMI + SmiNode *smiNode = NULL; +#endif + int status; + + /* Sequence of varBind */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_SEQ) { + fputs("[!SEQ of varbind]", stdout); + asn1_print(&elem); + return; + } + if ((u_int)count < length) + printf("[%d extra after SEQ of varbind]", length - count); + /* descend */ + length = elem.asnlen; + np = (u_char *)elem.data.raw; + + for (ind = 1; length > 0; ind++) { + const u_char *vbend; + u_int vblength; + + fputs(" ", stdout); + + /* Sequence */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_SEQ) { + fputs("[!varbind]", stdout); + asn1_print(&elem); + return; + } + vbend = np + count; + vblength = length - count; + /* descend */ + length = elem.asnlen; + np = (u_char *)elem.data.raw; + + /* objName (OID) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_OID) { + fputs("[objName!=OID]", stdout); + asn1_print(&elem); + return; + } +#ifdef LIBSMI + smiNode = smi_print_variable(&elem, &status); +#else + status = asn1_print(&elem); +#endif + if (status < 0) + return; + length -= count; + np += count; + + if (pduid != GETREQ && pduid != GETNEXTREQ + && pduid != GETBULKREQ) + fputs("=", stdout); + + /* objVal (ANY) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (pduid == GETREQ || pduid == GETNEXTREQ + || pduid == GETBULKREQ) { + if (elem.type != BE_NULL) { + fputs("[objVal!=NULL]", stdout); + if (asn1_print(&elem) < 0) + return; + } + } else { + if (elem.type != BE_NULL) { +#ifdef LIBSMI + status = smi_print_value(smiNode, pduid, &elem); +#else + status = asn1_print(&elem); +#endif + } + if (status < 0) + return; + } + length = vblength; + np = vbend; + } +} + +/* + * Decode SNMP PDUs: GetRequest, GetNextRequest, GetResponse, SetRequest, + * GetBulk, Inform, V2Trap, and Report + */ +static void +snmppdu_print(u_short pduid, const u_char *np, u_int length) +{ + struct be elem; + int count = 0, error; + + /* reqId (Integer) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[reqId!=INT]", stdout); + asn1_print(&elem); + return; + } + if (vflag) + printf("R=%d ", elem.data.integer); + length -= count; + np += count; + + /* errorStatus (Integer) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[errorStatus!=INT]", stdout); + asn1_print(&elem); + return; + } + error = 0; + if ((pduid == GETREQ || pduid == GETNEXTREQ || pduid == SETREQ + || pduid == INFORMREQ || pduid == V2TRAP || pduid == REPORT) + && elem.data.integer != 0) { + char errbuf[20]; + printf("[errorStatus(%s)!=0]", + DECODE_ErrorStatus(elem.data.integer)); + } else if (pduid == GETBULKREQ) { + printf(" N=%d", elem.data.integer); + } else if (elem.data.integer != 0) { + char errbuf[20]; + printf(" %s", DECODE_ErrorStatus(elem.data.integer)); + error = elem.data.integer; + } + length -= count; + np += count; + + /* errorIndex (Integer) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[errorIndex!=INT]", stdout); + asn1_print(&elem); + return; + } + if ((pduid == GETREQ || pduid == GETNEXTREQ || pduid == SETREQ + || pduid == INFORMREQ || pduid == V2TRAP || pduid == REPORT) + && elem.data.integer != 0) + printf("[errorIndex(%d)!=0]", elem.data.integer); + else if (pduid == GETBULKREQ) + printf(" M=%d", elem.data.integer); + else if (elem.data.integer != 0) { + if (!error) + printf("[errorIndex(%d) w/o errorStatus]", + elem.data.integer); + else { + printf("@%d", elem.data.integer); + error = elem.data.integer; + } + } else if (error) { + fputs("[errorIndex==0]", stdout); + error = 0; + } + length -= count; + np += count; + + varbind_print(pduid, np, length); + return; +} + +/* + * Decode SNMP Trap PDU + */ +static void +trappdu_print(const u_char *np, u_int length) +{ + struct be elem; + int count = 0, generic; + + putchar(' '); + + /* enterprise (oid) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_OID) { + fputs("[enterprise!=OID]", stdout); + asn1_print(&elem); + return; + } + if (asn1_print(&elem) < 0) + return; + length -= count; + np += count; + + putchar(' '); + + /* agent-addr (inetaddr) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INETADDR) { + fputs("[agent-addr!=INETADDR]", stdout); + asn1_print(&elem); + return; + } + if (asn1_print(&elem) < 0) + return; + length -= count; + np += count; + + /* generic-trap (Integer) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[generic-trap!=INT]", stdout); + asn1_print(&elem); + return; + } + generic = elem.data.integer; + { + char buf[20]; + printf(" %s", DECODE_GenericTrap(generic)); + } + length -= count; + np += count; + + /* specific-trap (Integer) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[specific-trap!=INT]", stdout); + asn1_print(&elem); + return; + } + if (generic != GT_ENTERPRISE) { + if (elem.data.integer != 0) + printf("[specific-trap(%d)!=0]", elem.data.integer); + } else + printf(" s=%d", elem.data.integer); + length -= count; + np += count; + + putchar(' '); + + /* time-stamp (TimeTicks) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_UNS) { /* XXX */ + fputs("[time-stamp!=TIMETICKS]", stdout); + asn1_print(&elem); + return; + } + if (asn1_print(&elem) < 0) + return; + length -= count; + np += count; + + varbind_print (TRAP, np, length); + return; +} + +/* + * Decode arbitrary SNMP PDUs. + */ +static void +pdu_print(const u_char *np, u_int length, int version) +{ + struct be pdu; + int count = 0; + + /* PDU (Context) */ + if ((count = asn1_parse(np, length, &pdu)) < 0) + return; + if (pdu.type != BE_PDU) { + fputs("[no PDU]", stdout); + return; + } + if ((u_int)count < length) + printf("[%d extra after PDU]", length - count); + if (vflag) { + fputs("{ ", stdout); + } + if (asn1_print(&pdu) < 0) + return; + fputs(" ", stdout); + /* descend into PDU */ + length = pdu.asnlen; + np = (u_char *)pdu.data.raw; + + if (version == SNMP_VERSION_1 && + (pdu.id == GETBULKREQ || pdu.id == INFORMREQ || + pdu.id == V2TRAP || pdu.id == REPORT)) { + printf("[v2 PDU in v1 message]"); + return; + } + + if (version == SNMP_VERSION_2 && pdu.id == TRAP) { + printf("[v1 PDU in v2 message]"); + return; + } + + switch (pdu.id) { + case TRAP: + trappdu_print(np, length); + break; + case GETREQ: + case GETNEXTREQ: + case GETRESP: + case SETREQ: + case GETBULKREQ: + case INFORMREQ: + case V2TRAP: + case REPORT: + snmppdu_print(pdu.id, np, length); + break; + } + + if (vflag) { + fputs(" } ", stdout); + } +} + +/* + * Decode a scoped SNMP PDU. + */ +static void +scopedpdu_print(const u_char *np, u_int length, int version) +{ + struct be elem; + int i, count = 0; + + /* Sequence */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_SEQ) { + fputs("[!scoped PDU]", stdout); + asn1_print(&elem); + return; + } + length = elem.asnlen; + np = (u_char *)elem.data.raw; + + /* contextEngineID (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[contextEngineID!=STR]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + fputs("E= ", stdout); + for (i = 0; i < (int)elem.asnlen; i++) { + printf("0x%02X", elem.data.str[i]); + } + fputs(" ", stdout); + + /* contextName (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[contextName!=STR]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + printf("C=%.*s ", (int)elem.asnlen, elem.data.str); + + pdu_print(np, length, version); +} + +/* + * Decode SNMP Community Header (SNMPv1 and SNMPv2c) + */ +static void +community_print(const u_char *np, u_int length, int version) +{ + struct be elem; + int count = 0; + + /* Community (String) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[comm!=STR]", stdout); + asn1_print(&elem); + return; + } + /* default community */ + if (!(elem.asnlen == sizeof(DEF_COMMUNITY) - 1 && + strncmp((char *)elem.data.str, DEF_COMMUNITY, + sizeof(DEF_COMMUNITY) - 1) == 0)) + /* ! "public" */ + printf("C=%.*s ", (int)elem.asnlen, elem.data.str); + length -= count; + np += count; + + pdu_print(np, length, version); +} + +/* + * Decode SNMPv3 User-based Security Message Header (SNMPv3) + */ +static void +usm_print(const u_char *np, u_int length) +{ + struct be elem; + int count = 0; + + /* Sequence */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_SEQ) { + fputs("[!usm]", stdout); + asn1_print(&elem); + return; + } + length = elem.asnlen; + np = (u_char *)elem.data.raw; + + /* msgAuthoritativeEngineID (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[msgAuthoritativeEngineID!=STR]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + /* msgAuthoritativeEngineBoots (INTEGER) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[msgAuthoritativeEngineBoots!=INT]", stdout); + asn1_print(&elem); + return; + } + if (vflag) + printf("B=%d ", elem.data.integer); + length -= count; + np += count; + + /* msgAuthoritativeEngineTime (INTEGER) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[msgAuthoritativeEngineTime!=INT]", stdout); + asn1_print(&elem); + return; + } + if (vflag) + printf("T=%d ", elem.data.integer); + length -= count; + np += count; + + /* msgUserName (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[msgUserName!=STR]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + printf("U=%.*s ", (int)elem.asnlen, elem.data.str); + + /* msgAuthenticationParameters (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[msgAuthenticationParameters!=STR]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + /* msgPrivacyParameters (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[msgPrivacyParameters!=STR]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + if ((u_int)count < length) + printf("[%d extra after usm SEQ]", length - count); +} + +/* + * Decode SNMPv3 Message Header (SNMPv3) + */ +static void +v3msg_print(const u_char *np, u_int length) +{ + struct be elem; + int count = 0; + u_char flags; + int model; + const u_char *xnp = np; + int xlength = length; + + /* Sequence */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_SEQ) { + fputs("[!message]", stdout); + asn1_print(&elem); + return; + } + length = elem.asnlen; + np = (u_char *)elem.data.raw; + + if (vflag) { + fputs("{ ", stdout); + } + + /* msgID (INTEGER) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[msgID!=INT]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + /* msgMaxSize (INTEGER) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[msgMaxSize!=INT]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + /* msgFlags (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[msgFlags!=STR]", stdout); + asn1_print(&elem); + return; + } + if (elem.asnlen != 1) { + printf("[msgFlags size %d]", elem.asnlen); + return; + } + flags = elem.data.str[0]; + if (flags != 0x00 && flags != 0x01 && flags != 0x03 + && flags != 0x04 && flags != 0x05 && flags != 0x07) { + printf("[msgFlags=0x%02X]", flags); + return; + } + length -= count; + np += count; + + fputs("F=", stdout); + if (flags & 0x01) fputs("a", stdout); + if (flags & 0x02) fputs("p", stdout); + if (flags & 0x04) fputs("r", stdout); + fputs(" ", stdout); + + /* msgSecurityModel (INTEGER) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[msgSecurityModel!=INT]", stdout); + asn1_print(&elem); + return; + } + model = elem.data.integer; + length -= count; + np += count; + + if ((u_int)count < length) + printf("[%d extra after message SEQ]", length - count); + + if (vflag) { + fputs("} ", stdout); + } + + if (model == 3) { + if (vflag) { + fputs("{ USM ", stdout); + } + } else { + printf("[security model %d]", model); + return; + } + + np = xnp + (np - xnp); + length = xlength - (np - xnp); + + /* msgSecurityParameters (OCTET STRING) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_STR) { + fputs("[msgSecurityParameters!=STR]", stdout); + asn1_print(&elem); + return; + } + length -= count; + np += count; + + if (model == 3) { + usm_print(elem.data.str, elem.asnlen); + if (vflag) { + fputs("} ", stdout); + } + } + + if (vflag) { + fputs("{ ScopedPDU ", stdout); + } + + scopedpdu_print(np, length, 3); + + if (vflag) { + fputs("} ", stdout); + } +} + +/* + * Decode SNMP header and pass on to PDU printing routines + */ +void +snmp_print(const u_char *np, u_int length) +{ + struct be elem; + int count = 0; + int version = 0; + + putchar(' '); + + /* initial Sequence */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_SEQ) { + fputs("[!init SEQ]", stdout); + asn1_print(&elem); + return; + } + if ((u_int)count < length) + printf("[%d extra after iSEQ]", length - count); + /* descend */ + length = elem.asnlen; + np = (u_char *)elem.data.raw; + + /* Version (INTEGER) */ + if ((count = asn1_parse(np, length, &elem)) < 0) + return; + if (elem.type != BE_INT) { + fputs("[version!=INT]", stdout); + asn1_print(&elem); + return; + } + + switch (elem.data.integer) { + case SNMP_VERSION_1: + case SNMP_VERSION_2: + case SNMP_VERSION_3: + if (vflag) + printf("{ %s ", SnmpVersion[elem.data.integer]); + break; + default: + printf("[version = %d]", elem.data.integer); + return; + } + version = elem.data.integer; + length -= count; + np += count; + + switch (version) { + case SNMP_VERSION_1: + case SNMP_VERSION_2: + community_print(np, length, version); + break; + case SNMP_VERSION_3: + v3msg_print(np, length); + break; + default: + printf("[version = %d]", elem.data.integer); + break; + } + + if (vflag) { + fputs("} ", stdout); + } +} diff --git a/print-stp.c b/print-stp.c new file mode 100644 index 0000000..8822c30 --- /dev/null +++ b/print-stp.c @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2000 Lennert Buytenhek + * + * This software may be distributed either under the terms of the + * BSD-style license that accompanies tcpdump or the GNU General + * Public License + * + * Format and print IEEE 802.1d spanning tree protocol packets. + * Contributed by Lennert Buytenhek + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-stp.c,v 1.20 2007-03-18 17:11:46 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#define RSTP_EXTRACT_PORT_ROLE(x) (((x)&0x0C)>>2) +/* STP timers are expressed in multiples of 1/256th second */ +#define STP_TIME_BASE 256 +#define STP_BPDU_MSTP_MIN_LEN 102 + +struct stp_bpdu_ { + u_int8_t protocol_id[2]; + u_int8_t protocol_version; + u_int8_t bpdu_type; + u_int8_t flags; + u_int8_t root_id[8]; + u_int8_t root_path_cost[4]; + u_int8_t bridge_id[8]; + u_int8_t port_id[2]; + u_int8_t message_age[2]; + u_int8_t max_age[2]; + u_int8_t hello_time[2]; + u_int8_t forward_delay[2]; + u_int8_t v1_length; +}; + +#define STP_PROTO_REGULAR 0x00 +#define STP_PROTO_RAPID 0x02 +#define STP_PROTO_MSTP 0x03 + +struct tok stp_proto_values[] = { + { STP_PROTO_REGULAR, "802.1d" }, + { STP_PROTO_RAPID, "802.1w" }, + { STP_PROTO_MSTP, "802.1s" }, + { 0, NULL} +}; + +#define STP_BPDU_TYPE_CONFIG 0x00 +#define STP_BPDU_TYPE_RSTP 0x02 +#define STP_BPDU_TYPE_TOPO_CHANGE 0x80 + +struct tok stp_bpdu_flag_values[] = { + { 0x01, "Topology change" }, + { 0x02, "Proposal" }, + { 0x10, "Learn" }, + { 0x20, "Forward" }, + { 0x40, "Agreement" }, + { 0x80, "Topology change ACK" }, + { 0, NULL} +}; + +struct tok stp_bpdu_type_values[] = { + { STP_BPDU_TYPE_CONFIG, "Config" }, + { STP_BPDU_TYPE_RSTP, "Rapid STP" }, + { STP_BPDU_TYPE_TOPO_CHANGE, "Topology Change" }, + { 0, NULL} +}; + +struct tok rstp_obj_port_role_values[] = { + { 0x00, "Unknown" }, + { 0x01, "Alternate" }, + { 0x02, "Root" }, + { 0x03, "Designated" }, + { 0, NULL} +}; + +static char * +stp_print_bridge_id(const u_char *p) +{ + static char bridge_id_str[sizeof("pppp.aa:bb:cc:dd:ee:ff")]; + + snprintf(bridge_id_str, sizeof(bridge_id_str), + "%.2x%.2x.%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + + return bridge_id_str; +} + +static void +stp_print_config_bpdu(const struct stp_bpdu_ *stp_bpdu, u_int length) +{ + printf(", Flags [%s]", + bittok2str(stp_bpdu_flag_values, "none", stp_bpdu->flags)); + + printf(", bridge-id %s.%04x, length %u", + stp_print_bridge_id((const u_char *)&stp_bpdu->bridge_id), + EXTRACT_16BITS(&stp_bpdu->port_id), length); + + /* in non-verbose mode just print the bridge-id */ + if (!vflag) { + return; + } + + printf("\n\tmessage-age %.2fs, max-age %.2fs" + ", hello-time %.2fs, forwarding-delay %.2fs", + (float)EXTRACT_16BITS(&stp_bpdu->message_age) / STP_TIME_BASE, + (float)EXTRACT_16BITS(&stp_bpdu->max_age) / STP_TIME_BASE, + (float)EXTRACT_16BITS(&stp_bpdu->hello_time) / STP_TIME_BASE, + (float)EXTRACT_16BITS(&stp_bpdu->forward_delay) / STP_TIME_BASE); + + printf("\n\troot-id %s, root-pathcost %u", + stp_print_bridge_id((const u_char *)&stp_bpdu->root_id), + EXTRACT_32BITS(&stp_bpdu->root_path_cost)); + + /* Port role is only valid for 802.1w */ + if (stp_bpdu->protocol_version == STP_PROTO_RAPID) { + printf(", port-role %s", + tok2str(rstp_obj_port_role_values, "Unknown", + RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags))); + } +} + +/* + * MSTP packet format + * Ref. IEEE 802.1Q 2003 Ed. Section 14 + * + * MSTP BPDU + * + * 2 - bytes Protocol Id + * 1 - byte Protocol Ver. + * 1 - byte BPDU tye + * 1 - byte Flags + * 8 - bytes CIST Root Identifier + * 4 - bytes CIST External Path Cost + * 8 - bytes CIST Regional Root Identifier + * 2 - bytes CIST Port Identifier + * 2 - bytes Message Age + * 2 - bytes Max age + * 2 - bytes Hello Time + * 2 - bytes Forward delay + * 1 - byte Version 1 length. Must be 0 + * 2 - bytes Version 3 length + * 1 - byte Config Identifier + * 32 - bytes Config Name + * 2 - bytes Revision level + * 16 - bytes Config Digest [MD5] + * 4 - bytes CIST Internal Root Path Cost + * 8 - bytes CIST Bridge Identifier + * 1 - byte CIST Remaining Hops + * 16 - bytes MSTI information [Max 64 MSTI, each 16 bytes] + * + * MSTI Payload + * + * 1 - byte MSTI flag + * 8 - bytes MSTI Regional Root Identifier + * 4 - bytes MSTI Regional Path Cost + * 1 - byte MSTI Bridge Priority + * 1 - byte MSTI Port Priority + * 1 - byte MSTI Remaining Hops + */ + +#define MST_BPDU_MSTI_LENGTH 16 +#define MST_BPDU_CONFIG_INFO_LENGTH 64 + +/* Offsets of fields from the begginning for the packet */ +#define MST_BPDU_VER3_LEN_OFFSET 36 +#define MST_BPDU_CONFIG_NAME_OFFSET 39 +#define MST_BPDU_CONFIG_DIGEST_OFFSET 73 +#define MST_BPDU_CIST_INT_PATH_COST_OFFSET 89 +#define MST_BPDU_CIST_BRIDGE_ID_OFFSET 93 +#define MST_BPDU_CIST_REMAIN_HOPS_OFFSET 101 +#define MST_BPDU_MSTI_OFFSET 102 +/* Offsets within an MSTI */ +#define MST_BPDU_MSTI_ROOT_PRIO_OFFSET 1 +#define MST_BPDU_MSTI_ROOT_PATH_COST_OFFSET 9 +#define MST_BPDU_MSTI_BRIDGE_PRIO_OFFSET 13 +#define MST_BPDU_MSTI_PORT_PRIO_OFFSET 14 +#define MST_BPDU_MSTI_REMAIN_HOPS_OFFSET 15 + +static void +stp_print_mstp_bpdu(const struct stp_bpdu_ *stp_bpdu, u_int length) +{ + const u_char *ptr; + u_int16_t v3len; + u_int16_t len; + u_int16_t msti; + u_int16_t offset; + + ptr = (const u_char *)stp_bpdu; + printf(", CIST Flags [%s]", + bittok2str(stp_bpdu_flag_values, "none", stp_bpdu->flags)); + + /* + * in non-verbose mode just print the flags. We dont read that much + * of the packet (DEFAULT_SNAPLEN) to print out cist bridge-id + */ + if (!vflag) { + return; + } + + printf(", CIST bridge-id %s.%04x, length %u", + stp_print_bridge_id(ptr + MST_BPDU_CIST_BRIDGE_ID_OFFSET), + EXTRACT_16BITS(&stp_bpdu->port_id), length); + + + printf("\n\tmessage-age %.2fs, max-age %.2fs" + ", hello-time %.2fs, forwarding-delay %.2fs", + (float)EXTRACT_16BITS(&stp_bpdu->message_age) / STP_TIME_BASE, + (float)EXTRACT_16BITS(&stp_bpdu->max_age) / STP_TIME_BASE, + (float)EXTRACT_16BITS(&stp_bpdu->hello_time) / STP_TIME_BASE, + (float)EXTRACT_16BITS(&stp_bpdu->forward_delay) / STP_TIME_BASE); + + printf("\n\tCIST root-id %s, ext-pathcost %u int-pathcost %u", + stp_print_bridge_id((const u_char *)&stp_bpdu->root_id), + EXTRACT_32BITS(&stp_bpdu->root_path_cost), + EXTRACT_32BITS(ptr + MST_BPDU_CIST_INT_PATH_COST_OFFSET)); + + printf(", port-role %s", + tok2str(rstp_obj_port_role_values, "Unknown", + RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags))); + + printf("\n\tCIST regional-root-id %s", + stp_print_bridge_id((const u_char *)&stp_bpdu->bridge_id)); + + printf("\n\tMSTP Configuration Name %s, revision %u, digest %08x%08x%08x%08x", + ptr + MST_BPDU_CONFIG_NAME_OFFSET, + EXTRACT_16BITS(ptr + MST_BPDU_CONFIG_NAME_OFFSET + 32), + EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET), + EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 4), + EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 8), + EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 12)); + + printf("\n\tCIST remaining-hops %d", ptr[MST_BPDU_CIST_REMAIN_HOPS_OFFSET]); + + /* Dump all MSTI's */ + v3len = EXTRACT_16BITS(ptr + MST_BPDU_VER3_LEN_OFFSET); + if (v3len > MST_BPDU_CONFIG_INFO_LENGTH) { + len = v3len - MST_BPDU_CONFIG_INFO_LENGTH; + offset = MST_BPDU_MSTI_OFFSET; + while (len >= MST_BPDU_MSTI_LENGTH) { + msti = EXTRACT_16BITS(ptr + offset + + MST_BPDU_MSTI_ROOT_PRIO_OFFSET); + msti = msti & 0x0FFF; + + printf("\n\tMSTI %d, Flags [%s], port-role %s", + msti, bittok2str(stp_bpdu_flag_values, "none", ptr[offset]), + tok2str(rstp_obj_port_role_values, "Unknown", + RSTP_EXTRACT_PORT_ROLE(ptr[offset]))); + printf("\n\t\tMSTI regional-root-id %s, pathcost %u", + stp_print_bridge_id(ptr + offset + + MST_BPDU_MSTI_ROOT_PRIO_OFFSET), + EXTRACT_32BITS(ptr + offset + + MST_BPDU_MSTI_ROOT_PATH_COST_OFFSET)); + printf("\n\t\tMSTI bridge-prio %d, port-prio %d, hops %d", + ptr[offset + MST_BPDU_MSTI_BRIDGE_PRIO_OFFSET] >> 4, + ptr[offset + MST_BPDU_MSTI_PORT_PRIO_OFFSET] >> 4, + ptr[offset + MST_BPDU_MSTI_REMAIN_HOPS_OFFSET]); + + len -= MST_BPDU_MSTI_LENGTH; + offset += MST_BPDU_MSTI_LENGTH; + } + } +} + +/* + * Print 802.1d / 802.1w / 802.1q (mstp) packets. + */ +void +stp_print(const u_char *p, u_int length) +{ + const struct stp_bpdu_ *stp_bpdu; + u_int16_t mstp_len; + + stp_bpdu = (struct stp_bpdu_*)p; + + /* Minimum STP Frame size. */ + if (length < 4) + goto trunc; + + if (EXTRACT_16BITS(&stp_bpdu->protocol_id)) { + printf("unknown STP version, length %u", length); + return; + } + + printf("STP %s", tok2str(stp_proto_values, "Unknown STP protocol (0x%02x)", + stp_bpdu->protocol_version)); + + switch (stp_bpdu->protocol_version) { + case STP_PROTO_REGULAR: + case STP_PROTO_RAPID: + case STP_PROTO_MSTP: + break; + default: + return; + } + + printf(", %s", tok2str(stp_bpdu_type_values, "Unknown BPDU Type (0x%02x)", + stp_bpdu->bpdu_type)); + + switch (stp_bpdu->bpdu_type) { + case STP_BPDU_TYPE_CONFIG: + if (length < sizeof(struct stp_bpdu_) - 1) { + goto trunc; + } + stp_print_config_bpdu(stp_bpdu, length); + break; + + case STP_BPDU_TYPE_RSTP: + if (stp_bpdu->protocol_version == STP_PROTO_RAPID) { + if (length < sizeof(struct stp_bpdu_)) { + goto trunc; + } + stp_print_config_bpdu(stp_bpdu, length); + } else if (stp_bpdu->protocol_version == STP_PROTO_MSTP) { + if (length < STP_BPDU_MSTP_MIN_LEN) { + goto trunc; + } + if (stp_bpdu->v1_length != 0) { + /* FIX ME: Emit a message here ? */ + goto trunc; + } + /* Validate v3 length */ + mstp_len = EXTRACT_16BITS(p + MST_BPDU_VER3_LEN_OFFSET); + mstp_len += 2; /* length encoding itself is 2 bytes */ + if (length < (sizeof(struct stp_bpdu_) + mstp_len)) { + goto trunc; + } + stp_print_mstp_bpdu(stp_bpdu, length); + } + break; + + case STP_BPDU_TYPE_TOPO_CHANGE: + /* always empty message - just break out */ + break; + + default: + break; + } + + return; + trunc: + printf("[|stp %d]", length); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/print-sunatm.c b/print-sunatm.c new file mode 100644 index 0000000..e6f19e8 --- /dev/null +++ b/print-sunatm.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 1997 Yen Yen Lim and North Dakota State University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Yen Yen Lim and + North Dakota State University + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-sunatm.c,v 1.8 2004-03-17 23:24:38 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +struct mbuf; +struct rtentry; + +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +#include "atm.h" +#include "atmuni31.h" + +/* SunATM header for ATM packet */ +#define DIR_POS 0 /* Direction (0x80 = transmit, 0x00 = receive) */ +#define VPI_POS 1 /* VPI */ +#define VCI_POS 2 /* VCI */ +#define PKT_BEGIN_POS 4 /* Start of the ATM packet */ + +/* Protocol type values in the bottom for bits of the byte at SUNATM_DIR_POS. */ +#define PT_LANE 0x01 /* LANE */ +#define PT_LLC 0x02 /* LLC encapsulation */ + +/* + * This is the top level routine of the printer. 'p' points + * to the SunATM pseudo-header for the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +sunatm_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + u_short vci; + u_char vpi; + u_int traftype; + + if (caplen < PKT_BEGIN_POS) { + printf("[|atm]"); + return (caplen); + } + + if (eflag) { + if (p[DIR_POS] & 0x80) + printf("Tx: "); + else + printf("Rx: "); + } + + switch (p[DIR_POS] & 0x0f) { + + case PT_LANE: + traftype = ATM_LANE; + break; + + case PT_LLC: + traftype = ATM_LLC; + break; + + default: + traftype = ATM_UNKNOWN; + break; + } + + vci = EXTRACT_16BITS(&p[VCI_POS]); + vpi = p[VPI_POS]; + + p += PKT_BEGIN_POS; + caplen -= PKT_BEGIN_POS; + length -= PKT_BEGIN_POS; + atm_print(vpi, vci, traftype, p, length, caplen); + + return (PKT_BEGIN_POS); +} diff --git a/print-sunrpc.c b/print-sunrpc.c new file mode 100644 index 0000000..e33b762 --- /dev/null +++ b/print-sunrpc.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 1992, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-sunrpc.c,v 1.47 2005-04-27 21:43:48 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* + * At least on HP-UX: + * + * 1) getrpcbynumber() is declared in , not any of the RPC + * header files + * + * and + * + * 2) if _XOPEN_SOURCE_EXTENDED is defined, doesn't declare + * it + * + * so we undefine it. + */ +#undef _XOPEN_SOURCE_EXTENDED + +#include + +#ifdef HAVE_GETRPCBYNUMBER +#include +#ifdef HAVE_RPC_RPCENT_H +#include +#endif /* HAVE_RPC_RPCENT_H */ +#endif /* HAVE_GETRPCBYNUMBER */ + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif + +#include "rpc_auth.h" +#include "rpc_msg.h" +#include "pmap_prot.h" + +static struct tok proc2str[] = { + { SUNRPC_PMAPPROC_NULL, "null" }, + { SUNRPC_PMAPPROC_SET, "set" }, + { SUNRPC_PMAPPROC_UNSET, "unset" }, + { SUNRPC_PMAPPROC_GETPORT, "getport" }, + { SUNRPC_PMAPPROC_DUMP, "dump" }, + { SUNRPC_PMAPPROC_CALLIT, "call" }, + { 0, NULL } +}; + +/* Forwards */ +static char *progstr(u_int32_t); + +void +sunrpcrequest_print(register const u_char *bp, register u_int length, + register const u_char *bp2) +{ + register const struct sunrpc_msg *rp; + register const struct ip *ip; +#ifdef INET6 + register const struct ip6_hdr *ip6; +#endif + u_int32_t x; + char srcid[20], dstid[20]; /*fits 32bit*/ + + rp = (struct sunrpc_msg *)bp; + + if (!nflag) { + snprintf(srcid, sizeof(srcid), "0x%x", + EXTRACT_32BITS(&rp->rm_xid)); + strlcpy(dstid, "sunrpc", sizeof(dstid)); + } else { + snprintf(srcid, sizeof(srcid), "0x%x", + EXTRACT_32BITS(&rp->rm_xid)); + snprintf(dstid, sizeof(dstid), "0x%x", SUNRPC_PMAPPORT); + } + + switch (IP_V((struct ip *)bp2)) { + case 4: + ip = (struct ip *)bp2; + printf("%s.%s > %s.%s: %d", + ipaddr_string(&ip->ip_src), srcid, + ipaddr_string(&ip->ip_dst), dstid, length); + break; +#ifdef INET6 + case 6: + ip6 = (struct ip6_hdr *)bp2; + printf("%s.%s > %s.%s: %d", + ip6addr_string(&ip6->ip6_src), srcid, + ip6addr_string(&ip6->ip6_dst), dstid, length); + break; +#endif + default: + printf("%s.%s > %s.%s: %d", "?", srcid, "?", dstid, length); + break; + } + + printf(" %s", tok2str(proc2str, " proc #%u", + EXTRACT_32BITS(&rp->rm_call.cb_proc))); + x = EXTRACT_32BITS(&rp->rm_call.cb_rpcvers); + if (x != 2) + printf(" [rpcver %u]", x); + + switch (EXTRACT_32BITS(&rp->rm_call.cb_proc)) { + + case SUNRPC_PMAPPROC_SET: + case SUNRPC_PMAPPROC_UNSET: + case SUNRPC_PMAPPROC_GETPORT: + case SUNRPC_PMAPPROC_CALLIT: + x = EXTRACT_32BITS(&rp->rm_call.cb_prog); + if (!nflag) + printf(" %s", progstr(x)); + else + printf(" %u", x); + printf(".%u", EXTRACT_32BITS(&rp->rm_call.cb_vers)); + break; + } +} + +static char * +progstr(prog) + u_int32_t prog; +{ +#ifdef HAVE_GETRPCBYNUMBER + register struct rpcent *rp; +#endif + static char buf[32]; + static u_int32_t lastprog = 0; + + if (lastprog != 0 && prog == lastprog) + return (buf); +#ifdef HAVE_GETRPCBYNUMBER + rp = getrpcbynumber(prog); + if (rp == NULL) +#endif + (void) snprintf(buf, sizeof(buf), "#%u", prog); +#ifdef HAVE_GETRPCBYNUMBER + else + strlcpy(buf, rp->r_name, sizeof(buf)); +#endif + return (buf); +} diff --git a/print-symantec.c b/print-symantec.c new file mode 100644 index 0000000..0fba8e5 --- /dev/null +++ b/print-symantec.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-symantec.c,v 1.5 2005-07-07 01:22:21 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ethertype.h" + +#include "ether.h" + +struct symantec_header { + u_int8_t stuff1[6]; + u_int16_t ether_type; + u_int8_t stuff2[36]; +}; + +static inline void +symantec_hdr_print(register const u_char *bp, u_int length) +{ + register const struct symantec_header *sp; + u_int16_t etype; + + sp = (const struct symantec_header *)bp; + + etype = EXTRACT_16BITS(&sp->ether_type); + if (!qflag) { + if (etype <= ETHERMTU) + (void)printf("invalid ethertype %u", etype); + else + (void)printf("ethertype %s (0x%04x)", + tok2str(ethertype_values,"Unknown", etype), + etype); + } else { + if (etype <= ETHERMTU) + (void)printf("invalid ethertype %u", etype); + else + (void)printf("%s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", etype)); + } + + (void)printf(", length %u: ", length); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +symantec_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int length = h->len; + u_int caplen = h->caplen; + struct symantec_header *sp; + u_short ether_type; + + if (caplen < sizeof (struct symantec_header)) { + printf("[|symantec]"); + return caplen; + } + + if (eflag) + symantec_hdr_print(p, length); + + length -= sizeof (struct symantec_header); + caplen -= sizeof (struct symantec_header); + sp = (struct symantec_header *)p; + p += sizeof (struct symantec_header); + + ether_type = EXTRACT_16BITS(&sp->ether_type); + + if (ether_type <= ETHERMTU) { + /* ether_type not known, print raw packet */ + if (!eflag) + symantec_hdr_print((u_char *)sp, length + sizeof (struct symantec_header)); + + if (!suppress_default_print) + default_print(p, caplen); + } else if (ethertype_print(ether_type, p, length, caplen) == 0) { + /* ether_type not known, print raw packet */ + if (!eflag) + symantec_hdr_print((u_char *)sp, length + sizeof (struct symantec_header)); + + if (!suppress_default_print) + default_print(p, caplen); + } + + return (sizeof (struct symantec_header)); +} diff --git a/print-syslog.c b/print-syslog.c new file mode 100755 index 0000000..3685d62 --- /dev/null +++ b/print-syslog.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 1998-2004 Hannes Gredler + * The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-syslog.c,v 1.1 2004-10-29 11:42:53 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * tokenlists and #defines taken from Ethereal - Network traffic analyzer + * by Gerald Combs + */ + +#define SYSLOG_SEVERITY_MASK 0x0007 /* 0000 0000 0000 0111 */ +#define SYSLOG_FACILITY_MASK 0x03f8 /* 0000 0011 1111 1000 */ +#define SYSLOG_MAX_DIGITS 3 /* The maximum number if priority digits to read in. */ + +static const struct tok syslog_severity_values[] = { + { 0, "emergency" }, + { 1, "alert" }, + { 2, "critical" }, + { 3, "error" }, + { 4, "warning" }, + { 5, "notice" }, + { 6, "info" }, + { 7, "debug" }, + { 0, NULL }, +}; + +static const struct tok syslog_facility_values[] = { + { 0, "kernel" }, + { 1, "user" }, + { 2, "mail" }, + { 3, "daemon" }, + { 4, "auth" }, + { 5, "syslog" }, + { 6, "lpr" }, + { 7, "news" }, + { 8, "uucp" }, + { 9, "cron" }, + { 10, "authpriv" }, + { 11, "ftp" }, + { 12, "ntp" }, + { 13, "security" }, + { 14, "console" }, + { 15, "cron" }, + { 16, "local0" }, + { 17, "local1" }, + { 18, "local2" }, + { 19, "local3" }, + { 20, "local4" }, + { 21, "local5" }, + { 22, "local6" }, + { 23, "local7" }, + { 0, NULL }, +}; + +void +syslog_print(register const u_char *pptr, register u_int len) +{ + u_int16_t msg_off = 0; + u_int16_t pri = 0; + u_int16_t facility,severity; + + /* extract decimal figures that are + * encapsulated within < > tags + * based on this decimal figure extract the + * severity and facility values + */ + + if (!TTEST2(*pptr, 1)) + goto trunc; + + if (*(pptr+msg_off) == '<') { + msg_off++; + + if (!TTEST2(*(pptr+msg_off), 1)) + goto trunc; + + while ( *(pptr+msg_off) >= '0' && + *(pptr+msg_off) <= '9' && + msg_off <= SYSLOG_MAX_DIGITS) { + + if (!TTEST2(*(pptr+msg_off), 1)) + goto trunc; + + pri = pri * 10 + (*(pptr+msg_off) - '0'); + msg_off++; + + if (!TTEST2(*(pptr+msg_off), 1)) + goto trunc; + + if (*(pptr+msg_off) == '>') + msg_off++; + } + } else { + printf("[|syslog]"); + return; + } + + facility = (pri & SYSLOG_FACILITY_MASK) >> 3; + severity = pri & SYSLOG_SEVERITY_MASK; + + + if (vflag < 1 ) + { + printf("SYSLOG %s.%s, length: %u", + tok2str(syslog_facility_values, "unknown (%u)", facility), + tok2str(syslog_severity_values, "unknown (%u)", severity), + len); + return; + } + + printf("SYSLOG, length: %u\n\tFacility %s (%u), Severity %s (%u)\n\tMsg: ", + len, + tok2str(syslog_facility_values, "unknown (%u)", facility), + facility, + tok2str(syslog_severity_values, "unknown (%u)", severity), + severity); + + /* print the syslog text in verbose mode */ + for (; msg_off < len; msg_off++) { + if (!TTEST2(*(pptr+msg_off), 1)) + goto trunc; + safeputchar(*(pptr+msg_off)); + } + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t",len)) + return; + } + + return; + +trunc: + printf("[|syslog]"); +} diff --git a/print-tcp.c b/print-tcp.c new file mode 100644 index 0000000..e2559ec --- /dev/null +++ b/print-tcp.c @@ -0,0 +1,811 @@ +/* $NetBSD: print-tcp.c,v 1.9 2007/07/26 18:15:12 plunky Exp $ */ + +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Copyright (c) 1999-2004 The tcpdump.org project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = +"@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.135 2008-11-09 23:35:03 mcr Exp $ (LBL)"; +#else +__RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $"); +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +#include "tcp.h" + +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif +#include "ipproto.h" +#include "rpc_auth.h" +#include "rpc_msg.h" + +#include "nameser.h" + +#ifdef HAVE_LIBCRYPTO +#include +#include + +static int tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp, + const u_char *data, int length, const u_char *rcvsig); +#endif + +static void print_tcp_rst_data(register const u_char *sp, u_int length); + +#define MAX_RST_DATA_LEN 30 + + +struct tha { +#ifndef INET6 + struct in_addr src; + struct in_addr dst; +#else + struct in6_addr src; + struct in6_addr dst; +#endif /*INET6*/ + u_int port; +}; + +struct tcp_seq_hash { + struct tcp_seq_hash *nxt; + struct tha addr; + tcp_seq seq; + tcp_seq ack; +}; + +#define TSEQ_HASHSIZE 919 + +/* These tcp optinos do not have the size octet */ +#define ZEROLENOPT(o) ((o) == TCPOPT_EOL || (o) == TCPOPT_NOP) + +static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE]; + +struct tok tcp_flag_values[] = { + { TH_FIN, "F" }, + { TH_SYN, "S" }, + { TH_RST, "R" }, + { TH_PUSH, "P" }, + { TH_ACK, "." }, + { TH_URG, "U" }, + { TH_ECNECHO, "E" }, + { TH_CWR, "W" }, + { 0, NULL } +}; + +struct tok tcp_option_values[] = { + { TCPOPT_EOL, "eol" }, + { TCPOPT_NOP, "nop" }, + { TCPOPT_MAXSEG, "mss" }, + { TCPOPT_WSCALE, "wscale" }, + { TCPOPT_SACKOK, "sackOK" }, + { TCPOPT_SACK, "sack" }, + { TCPOPT_ECHO, "echo" }, + { TCPOPT_ECHOREPLY, "echoreply" }, + { TCPOPT_TIMESTAMP, "TS" }, + { TCPOPT_CC, "cc" }, + { TCPOPT_CCNEW, "ccnew" }, + { TCPOPT_CCECHO, "" }, + { TCPOPT_SIGNATURE, "md5" }, + { TCPOPT_AUTH, "enhanced auth" }, + { TCPOPT_UTO, "uto" }, + { 0, NULL } +}; + +static int tcp_cksum(register const struct ip *ip, + register const struct tcphdr *tp, + register u_int len) +{ + union phu { + struct phdr { + u_int32_t src; + u_int32_t dst; + u_char mbz; + u_char proto; + u_int16_t len; + } ph; + u_int16_t pa[6]; + } phu; + const u_int16_t *sp; + + /* pseudo-header.. */ + phu.ph.len = htons((u_int16_t)len); + phu.ph.mbz = 0; + phu.ph.proto = IPPROTO_TCP; + memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t)); + if (IP_HL(ip) == 5) + memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t)); + else + phu.ph.dst = ip_finddst(ip); + + sp = &phu.pa[0]; + return in_cksum((u_short *)tp, len, + sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]); +} + +void +tcp_print(register const u_char *bp, register u_int length, + register const u_char *bp2, int fragmented) +{ + register const struct tcphdr *tp; + register const struct ip *ip; + register u_char flags; + register u_int hlen; + register char ch; + u_int16_t sport, dport, win, urp; + u_int32_t seq, ack, thseq, thack; + u_int utoval; + int threv; +#ifdef INET6 + register const struct ip6_hdr *ip6; +#endif + + tp = (struct tcphdr *)bp; + ip = (struct ip *)bp2; +#ifdef INET6 + if (IP_V(ip) == 6) + ip6 = (struct ip6_hdr *)bp2; + else + ip6 = NULL; +#endif /*INET6*/ + ch = '\0'; + if (!TTEST(tp->th_dport)) { + (void)printf("%s > %s: [|tcp]", + ipaddr_string(&ip->ip_src), + ipaddr_string(&ip->ip_dst)); + return; + } + + sport = EXTRACT_16BITS(&tp->th_sport); + dport = EXTRACT_16BITS(&tp->th_dport); + + hlen = TH_OFF(tp) * 4; + + /* + * If data present, header length valid, and NFS port used, + * assume NFS. + * Pass offset of data plus 4 bytes for RPC TCP msg length + * to NFS print routines. + */ + if (!qflag && hlen >= sizeof(*tp) && hlen <= length && + (length - hlen) >= 4) { + u_char *fraglenp; + u_int32_t fraglen; + register struct sunrpc_msg *rp; + enum sunrpc_msg_type direction; + + fraglenp = (u_char *)tp + hlen; + if (TTEST2(*fraglenp, 4)) { + fraglen = EXTRACT_32BITS(fraglenp) & 0x7FFFFFFF; + if (fraglen > (length - hlen) - 4) + fraglen = (length - hlen) - 4; + rp = (struct sunrpc_msg *)(fraglenp + 4); + if (TTEST(rp->rm_direction)) { + direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction); + if (dport == NFS_PORT && + direction == SUNRPC_CALL) { + nfsreq_print((u_char *)rp, fraglen, + (u_char *)ip); + return; + } + if (sport == NFS_PORT && + direction == SUNRPC_REPLY) { + nfsreply_print((u_char *)rp, fraglen, + (u_char *)ip); + return; + } + } + } + } +#ifdef INET6 + if (ip6) { + if (ip6->ip6_nxt == IPPROTO_TCP) { + (void)printf("%s.%s > %s.%s: ", + ip6addr_string(&ip6->ip6_src), + tcpport_string(sport), + ip6addr_string(&ip6->ip6_dst), + tcpport_string(dport)); + } else { + (void)printf("%s > %s: ", + tcpport_string(sport), tcpport_string(dport)); + } + } else +#endif /*INET6*/ + { + if (ip->ip_p == IPPROTO_TCP) { + (void)printf("%s.%s > %s.%s: ", + ipaddr_string(&ip->ip_src), + tcpport_string(sport), + ipaddr_string(&ip->ip_dst), + tcpport_string(dport)); + } else { + (void)printf("%s > %s: ", + tcpport_string(sport), tcpport_string(dport)); + } + } + + if (hlen < sizeof(*tp)) { + (void)printf(" tcp %d [bad hdr length %u - too short, < %lu]", + length - hlen, hlen, (unsigned long)sizeof(*tp)); + return; + } + + TCHECK(*tp); + + seq = EXTRACT_32BITS(&tp->th_seq); + ack = EXTRACT_32BITS(&tp->th_ack); + win = EXTRACT_16BITS(&tp->th_win); + urp = EXTRACT_16BITS(&tp->th_urp); + + if (qflag) { + (void)printf("tcp %d", length - hlen); + if (hlen > length) { + (void)printf(" [bad hdr length %u - too long, > %u]", + hlen, length); + } + return; + } + + flags = tp->th_flags; + printf("Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags)); + + if (!Sflag && (flags & TH_ACK)) { + register struct tcp_seq_hash *th; + const void *src, *dst; + register int rev; + struct tha tha; + /* + * Find (or record) the initial sequence numbers for + * this conversation. (we pick an arbitrary + * collating order so there's only one entry for + * both directions). + */ +#ifdef INET6 + memset(&tha, 0, sizeof(tha)); + rev = 0; + if (ip6) { + src = &ip6->ip6_src; + dst = &ip6->ip6_dst; + if (sport > dport) + rev = 1; + else if (sport == dport) { + if (memcmp(src, dst, sizeof ip6->ip6_dst) > 0) + rev = 1; + } + if (rev) { + memcpy(&tha.src, dst, sizeof ip6->ip6_dst); + memcpy(&tha.dst, src, sizeof ip6->ip6_src); + tha.port = dport << 16 | sport; + } else { + memcpy(&tha.dst, dst, sizeof ip6->ip6_dst); + memcpy(&tha.src, src, sizeof ip6->ip6_src); + tha.port = sport << 16 | dport; + } + } else { + src = &ip->ip_src; + dst = &ip->ip_dst; + if (sport > dport) + rev = 1; + else if (sport == dport) { + if (memcmp(src, dst, sizeof ip->ip_dst) > 0) + rev = 1; + } + if (rev) { + memcpy(&tha.src, dst, sizeof ip->ip_dst); + memcpy(&tha.dst, src, sizeof ip->ip_src); + tha.port = dport << 16 | sport; + } else { + memcpy(&tha.dst, dst, sizeof ip->ip_dst); + memcpy(&tha.src, src, sizeof ip->ip_src); + tha.port = sport << 16 | dport; + } + } +#else + rev = 0; + src = &ip->ip_src; + dst = &ip->ip_dst; + if (sport > dport) + rev = 1; + else if (sport == dport) { + if (memcmp(src, dst, sizeof ip->ip_dst) > 0) + rev = 1; + } + if (rev) { + memcpy(&tha.src, dst, sizeof ip->ip_dst); + memcpy(&tha.dst, src, sizeof ip->ip_src); + tha.port = dport << 16 | sport; + } else { + memcpy(&tha.dst, dst, sizeof ip->ip_dst); + memcpy(&tha.src, src, sizeof ip->ip_src); + tha.port = sport << 16 | dport; + } +#endif + + threv = rev; + for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE]; + th->nxt; th = th->nxt) + if (memcmp((char *)&tha, (char *)&th->addr, + sizeof(th->addr)) == 0) + break; + + if (!th->nxt || (flags & TH_SYN)) { + /* didn't find it or new conversation */ + if (th->nxt == NULL) { + th->nxt = (struct tcp_seq_hash *) + calloc(1, sizeof(*th)); + if (th->nxt == NULL) + error("tcp_print: calloc"); + } + th->addr = tha; + if (rev) + th->ack = seq, th->seq = ack - 1; + else + th->seq = seq, th->ack = ack - 1; + } else { + if (rev) + seq -= th->ack, ack -= th->seq; + else + seq -= th->seq, ack -= th->ack; + } + + thseq = th->seq; + thack = th->ack; + } else { + /*fool gcc*/ + thseq = thack = threv = 0; + } + if (hlen > length) { + (void)printf(" [bad hdr length %u - too long, > %u]", + hlen, length); + return; + } + + if (IP_V(ip) == 4 && vflag && !Kflag && !fragmented) { + u_int16_t sum, tcp_sum; + if (TTEST2(tp->th_sport, length)) { + sum = tcp_cksum(ip, tp, length); + + (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum)); + if (sum != 0) { + tcp_sum = EXTRACT_16BITS(&tp->th_sum); + (void)printf(" (incorrect -> 0x%04x)",in_cksum_shouldbe(tcp_sum, sum)); + } else + (void)printf(" (correct)"); + } + } +#ifdef INET6 + if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !Kflag && !fragmented) { + u_int16_t sum,tcp_sum; + if (TTEST2(tp->th_sport, length)) { + sum = nextproto6_cksum(ip6, (u_short *)tp, length, IPPROTO_TCP); + (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum)); + if (sum != 0) { + tcp_sum = EXTRACT_16BITS(&tp->th_sum); + (void)printf(" (incorrect -> 0x%04x)",in_cksum_shouldbe(tcp_sum, sum)); + } else + (void)printf(" (correct)"); + + } + } +#endif + + length -= hlen; + if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) { + (void)printf(", seq %u", seq); + + if (length > 0) { + (void)printf(":%u", seq + length); + } + } + + if (flags & TH_ACK) { + (void)printf(", ack %u", ack); + } + + (void)printf(", win %d", win); + + if (flags & TH_URG) + (void)printf(", urg %d", urp); + /* + * Handle any options. + */ + if (hlen > sizeof(*tp)) { + register const u_char *cp; + register u_int i, opt, datalen; + register u_int len; + + hlen -= sizeof(*tp); + cp = (const u_char *)tp + sizeof(*tp); + printf(", options ["); + while (hlen > 0) { + if (ch != '\0') + putchar(ch); + TCHECK(*cp); + opt = *cp++; + if (ZEROLENOPT(opt)) + len = 1; + else { + TCHECK(*cp); + len = *cp++; /* total including type, len */ + if (len < 2 || len > hlen) + goto bad; + --hlen; /* account for length byte */ + } + --hlen; /* account for type byte */ + datalen = 0; + +/* Bail if "l" bytes of data are not left or were not captured */ +#define LENCHECK(l) { if ((l) > hlen) goto bad; TCHECK2(*cp, l); } + + + printf("%s", tok2str(tcp_option_values, "Unknown Option %u", opt)); + + switch (opt) { + + case TCPOPT_MAXSEG: + datalen = 2; + LENCHECK(datalen); + (void)printf(" %u", EXTRACT_16BITS(cp)); + break; + + case TCPOPT_WSCALE: + datalen = 1; + LENCHECK(datalen); + (void)printf(" %u", *cp); + break; + + case TCPOPT_SACK: + datalen = len - 2; + if (datalen % 8 != 0) { + (void)printf("malformed sack"); + } else { + u_int32_t s, e; + + (void)printf(" %d ", datalen / 8); + for (i = 0; i < datalen; i += 8) { + LENCHECK(i + 4); + s = EXTRACT_32BITS(cp + i); + LENCHECK(i + 8); + e = EXTRACT_32BITS(cp + i + 4); + if (threv) { + s -= thseq; + e -= thseq; + } else { + s -= thack; + e -= thack; + } + (void)printf("{%u:%u}", s, e); + } + } + break; + + case TCPOPT_CC: + case TCPOPT_CCNEW: + case TCPOPT_CCECHO: + case TCPOPT_ECHO: + case TCPOPT_ECHOREPLY: + + /* + * those options share their semantics. + * fall through + */ + datalen = 4; + LENCHECK(datalen); + (void)printf(" %u", EXTRACT_32BITS(cp)); + break; + + case TCPOPT_TIMESTAMP: + datalen = 8; + LENCHECK(datalen); + (void)printf(" val %u ecr %u", + EXTRACT_32BITS(cp), + EXTRACT_32BITS(cp + 4)); + break; + + case TCPOPT_SIGNATURE: + datalen = TCP_SIGLEN; + LENCHECK(datalen); +#ifdef HAVE_LIBCRYPTO + switch (tcp_verify_signature(ip, tp, + bp + TH_OFF(tp) * 4, length, cp)) { + + case SIGNATURE_VALID: + (void)printf("valid"); + break; + + case SIGNATURE_INVALID: + (void)printf("invalid"); + break; + + case CANT_CHECK_SIGNATURE: + (void)printf("can't check - "); + for (i = 0; i < TCP_SIGLEN; ++i) + (void)printf("%02x", cp[i]); + break; + } +#else + for (i = 0; i < TCP_SIGLEN; ++i) + (void)printf("%02x", cp[i]); +#endif + break; + + case TCPOPT_AUTH: + (void)printf("keyid %d", *cp++); + datalen = len - 3; + for (i = 0; i < datalen; ++i) { + LENCHECK(i); + (void)printf("%02x", cp[i]); + } + break; + + + case TCPOPT_EOL: + case TCPOPT_NOP: + case TCPOPT_SACKOK: + /* + * Nothing interesting. + * fall through + */ + break; + + case TCPOPT_UTO: + datalen = 2; + LENCHECK(datalen); + utoval = EXTRACT_16BITS(cp); + (void)printf("0x%x", utoval); + if (utoval & 0x0001) + utoval = (utoval >> 1) * 60; + else + utoval >>= 1; + (void)printf(" %u", utoval); + break; + + default: + datalen = len - 2; + for (i = 0; i < datalen; ++i) { + LENCHECK(i); + (void)printf("%02x", cp[i]); + } + break; + } + + /* Account for data printed */ + cp += datalen; + hlen -= datalen; + + /* Check specification against observed length */ + ++datalen; /* option octet */ + if (!ZEROLENOPT(opt)) + ++datalen; /* size octet */ + if (datalen != len) + (void)printf("[len %d]", len); + ch = ','; + if (opt == TCPOPT_EOL) + break; + } + putchar(']'); + } + + /* + * Print length field before crawling down the stack. + */ + printf(", length %u", length); + + if (length <= 0) + return; + + /* + * Decode payload if necessary. + */ + bp += TH_OFF(tp) * 4; + if ((flags & TH_RST) && vflag) { + print_tcp_rst_data(bp, length); + return; + } + + if (sport == TELNET_PORT || dport == TELNET_PORT) { + if (!qflag && vflag) + telnet_print(bp, length); + } else if (sport == BGP_PORT || dport == BGP_PORT) + bgp_print(bp, length); + else if (sport == PPTP_PORT || dport == PPTP_PORT) + pptp_print(bp); +#ifdef TCPDUMP_DO_SMB + else if (sport == NETBIOS_SSN_PORT || dport == NETBIOS_SSN_PORT) + nbt_tcp_print(bp, length); + else if (sport == SMB_PORT || dport == SMB_PORT) + smb_tcp_print(bp, length); +#endif + else if (sport == BEEP_PORT || dport == BEEP_PORT) + beep_print(bp, length); + else if (length > 2 && + (sport == NAMESERVER_PORT || dport == NAMESERVER_PORT || + sport == MULTICASTDNS_PORT || dport == MULTICASTDNS_PORT)) { + /* + * TCP DNS query has 2byte length at the head. + * XXX packet could be unaligned, it can go strange + */ + ns_print(bp + 2, length - 2, 0); + } else if (sport == MSDP_PORT || dport == MSDP_PORT) { + msdp_print(bp, length); + } + else if (length > 0 && (sport == LDP_PORT || dport == LDP_PORT)) { + ldp_print(bp, length); + } + + return; + bad: + fputs("[bad opt]", stdout); + if (ch != '\0') + putchar('>'); + return; + trunc: + fputs("[|tcp]", stdout); + if (ch != '\0') + putchar('>'); +} + +/* + * RFC1122 says the following on data in RST segments: + * + * 4.2.2.12 RST Segment: RFC-793 Section 3.4 + * + * A TCP SHOULD allow a received RST segment to include data. + * + * DISCUSSION + * It has been suggested that a RST segment could contain + * ASCII text that encoded and explained the cause of the + * RST. No standard has yet been established for such + * data. + * + */ + +static void +print_tcp_rst_data(register const u_char *sp, u_int length) +{ + int c; + + if (TTEST2(*sp, length)) + printf(" [RST"); + else + printf(" [!RST"); + if (length > MAX_RST_DATA_LEN) { + length = MAX_RST_DATA_LEN; /* can use -X for longer */ + putchar('+'); /* indicate we truncate */ + } + putchar(' '); + while (length-- && sp <= snapend) { + c = *sp++; + safeputchar(c); + } + putchar(']'); +} + +#ifdef HAVE_LIBCRYPTO +static int +tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp, + const u_char *data, int length, const u_char *rcvsig) +{ + struct tcphdr tp1; + u_char sig[TCP_SIGLEN]; + char zero_proto = 0; + MD5_CTX ctx; + u_int16_t savecsum, tlen; +#ifdef INET6 + struct ip6_hdr *ip6; + u_int32_t len32; + u_int8_t nxt; +#endif + + if (data + length > snapend) { + printf("snaplen too short, "); + return (CANT_CHECK_SIGNATURE); + } + + tp1 = *tp; + + if (sigsecret == NULL) { + printf("shared secret not supplied with -M, "); + return (CANT_CHECK_SIGNATURE); + } + + MD5_Init(&ctx); + /* + * Step 1: Update MD5 hash with IP pseudo-header. + */ + if (IP_V(ip) == 4) { + MD5_Update(&ctx, (char *)&ip->ip_src, sizeof(ip->ip_src)); + MD5_Update(&ctx, (char *)&ip->ip_dst, sizeof(ip->ip_dst)); + MD5_Update(&ctx, (char *)&zero_proto, sizeof(zero_proto)); + MD5_Update(&ctx, (char *)&ip->ip_p, sizeof(ip->ip_p)); + tlen = EXTRACT_16BITS(&ip->ip_len) - IP_HL(ip) * 4; + tlen = htons(tlen); + MD5_Update(&ctx, (char *)&tlen, sizeof(tlen)); +#ifdef INET6 + } else if (IP_V(ip) == 6) { + ip6 = (struct ip6_hdr *)ip; + MD5_Update(&ctx, (char *)&ip6->ip6_src, sizeof(ip6->ip6_src)); + MD5_Update(&ctx, (char *)&ip6->ip6_dst, sizeof(ip6->ip6_dst)); + len32 = htonl(EXTRACT_16BITS(&ip6->ip6_plen)); + MD5_Update(&ctx, (char *)&len32, sizeof(len32)); + nxt = 0; + MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); + MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); + MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); + nxt = IPPROTO_TCP; + MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); +#endif + } else { +#ifdef INET6 + printf("IP version not 4 or 6, "); +#else + printf("IP version not 4, "); +#endif + return (CANT_CHECK_SIGNATURE); + } + + /* + * Step 2: Update MD5 hash with TCP header, excluding options. + * The TCP checksum must be set to zero. + */ + savecsum = tp1.th_sum; + tp1.th_sum = 0; + MD5_Update(&ctx, (char *)&tp1, sizeof(struct tcphdr)); + tp1.th_sum = savecsum; + /* + * Step 3: Update MD5 hash with TCP segment data, if present. + */ + if (length > 0) + MD5_Update(&ctx, data, length); + /* + * Step 4: Update MD5 hash with shared secret. + */ + MD5_Update(&ctx, sigsecret, strlen(sigsecret)); + MD5_Final(sig, &ctx); + + if (memcmp(rcvsig, sig, TCP_SIGLEN) == 0) + return (SIGNATURE_VALID); + else + return (SIGNATURE_INVALID); +} +#endif /* HAVE_LIBCRYPTO */ + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-telnet.c b/print-telnet.c new file mode 100644 index 0000000..4911e5c --- /dev/null +++ b/print-telnet.c @@ -0,0 +1,267 @@ +/* $NetBSD: print-telnet.c,v 1.2 1999/10/11 12:40:12 sjg Exp $ */ + +/*- + * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Simon J. Gerraty. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/* + * @(#)Copyright (c) 1994, Simon J. Gerraty. + * + * This is free software. It comes with NO WARRANTY. + * Permission to use, modify and distribute this source code + * is granted subject to the following conditions. + * 1/ that the above copyright notice and this notice + * are preserved in all copies. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-telnet.c,v 1.24 2003-12-29 11:05:10 hannes Exp $"; +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "addrtoname.h" + +#define TELCMDS +#define TELOPTS +#include "telnet.h" + +/* normal */ +static const char *cmds[] = { + "IS", "SEND", "INFO", +}; + +/* 37: Authentication */ +static const char *authcmd[] = { + "IS", "SEND", "REPLY", "NAME", +}; +static const char *authtype[] = { + "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", + "SRP", "RSA", "SSL", NULL, NULL, + "LOKI", "SSA", "KEA_SJ", "KEA_SJ_INTEG", "DSS", + "NTLM", +}; + +/* 38: Encryption */ +static const char *enccmd[] = { + "IS", "SUPPORT", "REPLY", "START", "END", + "REQUEST-START", "REQUEST-END", "END_KEYID", "DEC_KEYID", +}; +static const char *enctype[] = { + "NULL", "DES_CFB64", "DES_OFB64", "DES3_CFB64", "DES3_OFB64", + NULL, "CAST5_40_CFB64", "CAST5_40_OFB64", "CAST128_CFB64", "CAST128_OFB64", +}; + +#define STR_OR_ID(x, tab) \ + (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) + +static char * +numstr(int x) +{ + static char buf[20]; + + snprintf(buf, sizeof(buf), "%#x", x); + return buf; +} + +/* sp points to IAC byte */ +static int +telnet_parse(const u_char *sp, u_int length, int print) +{ + int i, x; + u_int c; + const u_char *osp, *p; +#define FETCH(c, sp, length) \ + do { \ + if (length < 1) \ + goto pktend; \ + TCHECK(*sp); \ + c = *sp++; \ + length--; \ + } while (0) + + osp = sp; + + FETCH(c, sp, length); + if (c != IAC) + goto pktend; + FETCH(c, sp, length); + if (c == IAC) { /* ! */ + if (print) + printf("IAC IAC"); + goto done; + } + + i = c - TELCMD_FIRST; + if (i < 0 || i > IAC - TELCMD_FIRST) + goto pktend; + + switch (c) { + case DONT: + case DO: + case WONT: + case WILL: + case SB: + /* DONT/DO/WONT/WILL x */ + FETCH(x, sp, length); + if (x >= 0 && x < NTELOPTS) { + if (print) + (void)printf("%s %s", telcmds[i], telopts[x]); + } else { + if (print) + (void)printf("%s %#x", telcmds[i], x); + } + if (c != SB) + break; + /* IAC SB .... IAC SE */ + p = sp; + while (length > (u_int)(p + 1 - sp)) { + if (p[0] == IAC && p[1] == SE) + break; + p++; + } + if (*p != IAC) + goto pktend; + + switch (x) { + case TELOPT_AUTHENTICATION: + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, authcmd)); + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, authtype)); + break; + case TELOPT_ENCRYPT: + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, enccmd)); + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, enctype)); + break; + default: + if (p <= sp) + break; + FETCH(c, sp, length); + if (print) + (void)printf(" %s", STR_OR_ID(c, cmds)); + break; + } + while (p > sp) { + FETCH(x, sp, length); + if (print) + (void)printf(" %#x", x); + } + /* terminating IAC SE */ + if (print) + (void)printf(" SE"); + sp += 2; + length -= 2; + break; + default: + if (print) + (void)printf("%s", telcmds[i]); + goto done; + } + +done: + return sp - osp; + +trunc: + (void)printf("[|telnet]"); +pktend: + return -1; +#undef FETCH +} + +void +telnet_print(const u_char *sp, u_int length) +{ + int first = 1; + const u_char *osp; + int l; + + osp = sp; + + while (length > 0 && *sp == IAC) { + l = telnet_parse(sp, length, 0); + if (l < 0) + break; + + /* + * now print it + */ + if (Xflag && 2 < vflag) { + if (first) + printf("\nTelnet:"); + hex_print_with_offset("\n", sp, l, sp - osp); + if (l > 8) + printf("\n\t\t\t\t"); + else + printf("%*s\t", (8 - l) * 3, ""); + } else + printf("%s", (first) ? " [telnet " : ", "); + + (void)telnet_parse(sp, length, 1); + first = 0; + + sp += l; + length -= l; + } + if (!first) { + if (Xflag && 2 < vflag) + printf("\n"); + else + printf("]"); + } +} diff --git a/print-tftp.c b/print-tftp.c new file mode 100644 index 0000000..0caff42 --- /dev/null +++ b/print-tftp.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Format and print trivial file transfer protocol packets. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.39 2008-04-11 16:47:38 gianluca Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifdef SEGSIZE +#undef SEGSIZE /* SINIX sucks */ +#endif + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "tftp.h" + +/* op code to string mapping */ +static struct tok op2str[] = { + { RRQ, "RRQ" }, /* read request */ + { WRQ, "WRQ" }, /* write request */ + { DATA, "DATA" }, /* data packet */ + { ACK, "ACK" }, /* acknowledgement */ + { TFTP_ERROR, "ERROR" }, /* error code */ + { OACK, "OACK" }, /* option acknowledgement */ + { 0, NULL } +}; + +/* error code to string mapping */ +static struct tok err2str[] = { + { EUNDEF, "EUNDEF" }, /* not defined */ + { ENOTFOUND, "ENOTFOUND" }, /* file not found */ + { EACCESS, "EACCESS" }, /* access violation */ + { ENOSPACE, "ENOSPACE" }, /* disk full or allocation exceeded */ + { EBADOP, "EBADOP" }, /* illegal TFTP operation */ + { EBADID, "EBADID" }, /* unknown transfer ID */ + { EEXISTS, "EEXISTS" }, /* file already exists */ + { ENOUSER, "ENOUSER" }, /* no such user */ + { 0, NULL } +}; + +/* + * Print trivial file transfer program requests + */ +void +tftp_print(register const u_char *bp, u_int length) +{ + register const struct tftphdr *tp; + register const char *cp; + register const u_char *p; + register int opcode, i; + static char tstr[] = " [|tftp]"; + + tp = (const struct tftphdr *)bp; + + /* Print length */ + printf(" %d", length); + + /* Print tftp request type */ + TCHECK(tp->th_opcode); + opcode = EXTRACT_16BITS(&tp->th_opcode); + cp = tok2str(op2str, "tftp-#%d", opcode); + printf(" %s", cp); + /* Bail if bogus opcode */ + if (*cp == 't') + return; + + switch (opcode) { + + case RRQ: + case WRQ: + case OACK: + /* + * XXX Not all arpa/tftp.h's specify th_stuff as any + * array; use address of th_block instead + */ +#ifdef notdef + p = (u_char *)tp->th_stuff; +#else + p = (u_char *)&tp->th_block; +#endif + putchar(' '); + /* Print filename or first option */ + if (opcode != OACK) + putchar('"'); + i = fn_print(p, snapend); + if (opcode != OACK) + putchar('"'); + + /* Print the mode (RRQ and WRQ only) and any options */ + while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) { + if (length <= (u_int)(p - (const u_char *)&tp->th_block)) + break; + p++; + if (*p != '\0') { + putchar(' '); + fn_print(p, snapend); + } + } + + if (i) + goto trunc; + break; + + case ACK: + case DATA: + TCHECK(tp->th_block); + printf(" block %d", EXTRACT_16BITS(&tp->th_block)); + break; + + case TFTP_ERROR: + /* Print error code string */ + TCHECK(tp->th_code); + printf(" %s \"", tok2str(err2str, "tftp-err-#%d \"", + EXTRACT_16BITS(&tp->th_code))); + /* Print error message string */ + i = fn_print((const u_char *)tp->th_data, snapend); + putchar('"'); + if (i) + goto trunc; + break; + + default: + /* We shouldn't get here */ + printf("(unknown #%d)", opcode); + break; + } + return; +trunc: + fputs(tstr, stdout); + return; +} diff --git a/print-timed.c b/print-timed.c new file mode 100644 index 0000000..55fbb39 --- /dev/null +++ b/print-timed.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2000 Ben Smithurst + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-timed.c,v 1.9 2003-11-16 09:36:40 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "timed.h" +#include "interface.h" +#include "extract.h" + +static const char *tsptype[TSPTYPENUMBER] = + { "ANY", "ADJTIME", "ACK", "MASTERREQ", "MASTERACK", "SETTIME", "MASTERUP", + "SLAVEUP", "ELECTION", "ACCEPT", "REFUSE", "CONFLICT", "RESOLVE", "QUIT", + "DATE", "DATEREQ", "DATEACK", "TRACEON", "TRACEOFF", "MSITE", "MSITEREQ", + "TEST", "SETDATE", "SETDATEREQ", "LOOP" }; + +void +timed_print(register const u_char *bp) +{ +#define endof(x) ((u_char *)&(x) + sizeof (x)) + struct tsp *tsp = (struct tsp *)bp; + long sec, usec; + const u_char *end; + + if (endof(tsp->tsp_type) > snapend) { + fputs("[|timed]", stdout); + return; + } + if (tsp->tsp_type < TSPTYPENUMBER) + printf("TSP_%s", tsptype[tsp->tsp_type]); + else + printf("(tsp_type %#x)", tsp->tsp_type); + + if (endof(tsp->tsp_vers) > snapend) { + fputs(" [|timed]", stdout); + return; + } + printf(" vers %d", tsp->tsp_vers); + + if (endof(tsp->tsp_seq) > snapend) { + fputs(" [|timed]", stdout); + return; + } + printf(" seq %d", tsp->tsp_seq); + + if (tsp->tsp_type == TSP_LOOP) { + if (endof(tsp->tsp_hopcnt) > snapend) { + fputs(" [|timed]", stdout); + return; + } + printf(" hopcnt %d", tsp->tsp_hopcnt); + } else if (tsp->tsp_type == TSP_SETTIME || + tsp->tsp_type == TSP_ADJTIME || + tsp->tsp_type == TSP_SETDATE || + tsp->tsp_type == TSP_SETDATEREQ) { + if (endof(tsp->tsp_time) > snapend) { + fputs(" [|timed]", stdout); + return; + } + sec = EXTRACT_32BITS(&tsp->tsp_time.tv_sec); + usec = EXTRACT_32BITS(&tsp->tsp_time.tv_usec); + if (usec < 0) + /* corrupt, skip the rest of the packet */ + return; + fputs(" time ", stdout); + if (sec < 0 && usec != 0) { + sec++; + if (sec == 0) + fputc('-', stdout); + usec = 1000000 - usec; + } + printf("%ld.%06ld", sec, usec); + } + + end = memchr(tsp->tsp_name, '\0', snapend - (u_char *)tsp->tsp_name); + if (end == NULL) + fputs(" [|timed]", stdout); + else { + fputs(" name ", stdout); + fwrite(tsp->tsp_name, end - (u_char *)tsp->tsp_name, 1, stdout); + } +} diff --git a/print-token.c b/print-token.c new file mode 100644 index 0000000..4f8422b --- /dev/null +++ b/print-token.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Hacked version of print-ether.c Larry Lile + * + * Further tweaked to more closely resemble print-fddi.c + * Guy Harris + */ +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-token.c,v 1.27 2005-11-13 12:12:43 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ethertype.h" + +#include "ether.h" +#include "token.h" + +/* Extract src, dst addresses */ +static inline void +extract_token_addrs(const struct token_header *trp, char *fsrc, char *fdst) +{ + memcpy(fdst, (const char *)trp->token_dhost, 6); + memcpy(fsrc, (const char *)trp->token_shost, 6); +} + +/* + * Print the TR MAC header + */ +static inline void +token_hdr_print(register const struct token_header *trp, register u_int length, + register const u_char *fsrc, register const u_char *fdst) +{ + const char *srcname, *dstname; + + srcname = etheraddr_string(fsrc); + dstname = etheraddr_string(fdst); + + if (vflag) + (void) printf("%02x %02x %s %s %d: ", + trp->token_ac, + trp->token_fc, + srcname, dstname, + length); + else + printf("%s %s %d: ", srcname, dstname, length); +} + +static const char *broadcast_indicator[] = { + "Non-Broadcast", "Non-Broadcast", + "Non-Broadcast", "Non-Broadcast", + "All-routes", "All-routes", + "Single-route", "Single-route" +}; + +static const char *direction[] = { + "Forward", "Backward" +}; + +static const char *largest_frame[] = { + "516", + "1500", + "2052", + "4472", + "8144", + "11407", + "17800", + "??" +}; + +u_int +token_print(const u_char *p, u_int length, u_int caplen) +{ + const struct token_header *trp; + u_short extracted_ethertype; + struct ether_header ehdr; + u_int route_len = 0, hdr_len = TOKEN_HDRLEN; + int seg; + + trp = (const struct token_header *)p; + + if (caplen < TOKEN_HDRLEN) { + printf("[|token-ring]"); + return hdr_len; + } + + /* + * Get the TR addresses into a canonical form + */ + extract_token_addrs(trp, (char*)ESRC(&ehdr), (char*)EDST(&ehdr)); + + /* Adjust for source routing information in the MAC header */ + if (IS_SOURCE_ROUTED(trp)) { + /* Clear source-routed bit */ + *ESRC(&ehdr) &= 0x7f; + + if (eflag) + token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); + + if (caplen < TOKEN_HDRLEN + 2) { + printf("[|token-ring]"); + return hdr_len; + } + route_len = RIF_LENGTH(trp); + hdr_len += route_len; + if (caplen < hdr_len) { + printf("[|token-ring]"); + return hdr_len; + } + if (vflag) { + printf("%s ", broadcast_indicator[BROADCAST(trp)]); + printf("%s", direction[DIRECTION(trp)]); + + for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) + printf(" [%d:%d]", RING_NUMBER(trp, seg), + BRIDGE_NUMBER(trp, seg)); + } else { + printf("rt = %x", EXTRACT_16BITS(&trp->token_rcf)); + + for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) + printf(":%x", EXTRACT_16BITS(&trp->token_rseg[seg])); + } + printf(" (%s) ", largest_frame[LARGEST_FRAME(trp)]); + } else { + if (eflag) + token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); + } + + /* Skip over token ring MAC header and routing information */ + length -= hdr_len; + p += hdr_len; + caplen -= hdr_len; + + /* Frame Control field determines interpretation of packet */ + if (FRAME_TYPE(trp) == TOKEN_FC_LLC) { + /* Try to print the LLC-layer header & higher layers */ + if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr), + &extracted_ethertype) == 0) { + /* ether_type not known, print raw packet */ + if (!eflag) + token_hdr_print(trp, + length + TOKEN_HDRLEN + route_len, + ESRC(&ehdr), EDST(&ehdr)); + if (extracted_ethertype) { + printf("(LLC %s) ", + etherproto_string(htons(extracted_ethertype))); + } + if (!suppress_default_print) + default_print(p, caplen); + } + } else { + /* Some kinds of TR packet we cannot handle intelligently */ + /* XXX - dissect MAC packets if frame type is 0 */ + if (!eflag) + token_hdr_print(trp, length + TOKEN_HDRLEN + route_len, + ESRC(&ehdr), EDST(&ehdr)); + if (!suppress_default_print) + default_print(p, caplen); + } + return (hdr_len); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the TR header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +token_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + return (token_print(p, h->len, h->caplen)); +} diff --git a/print-udld.c b/print-udld.c new file mode 100644 index 0000000..a5488dd --- /dev/null +++ b/print-udld.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 1998-2007 The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * UNIDIRECTIONAL LINK DETECTION (UDLD) as per + * http://www.ietf.org/internet-drafts/draft-foschiano-udld-02.txt + * + * Original code by Carles Kishimoto + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "nlpid.h" + +#define UDLD_HEADER_LEN 4 +#define UDLD_DEVICE_ID_TLV 0x0001 +#define UDLD_PORT_ID_TLV 0x0002 +#define UDLD_ECHO_TLV 0x0003 +#define UDLD_MESSAGE_INTERVAL_TLV 0x0004 +#define UDLD_TIMEOUT_INTERVAL_TLV 0x0005 +#define UDLD_DEVICE_NAME_TLV 0x0006 +#define UDLD_SEQ_NUMBER_TLV 0x0007 + +static struct tok udld_tlv_values[] = { + { UDLD_DEVICE_ID_TLV, "Device-ID TLV"}, + { UDLD_PORT_ID_TLV, "Port-ID TLV"}, + { UDLD_ECHO_TLV, "Echo TLV"}, + { UDLD_MESSAGE_INTERVAL_TLV, "Message Interval TLV"}, + { UDLD_TIMEOUT_INTERVAL_TLV, "Timeout Interval TLV"}, + { UDLD_DEVICE_NAME_TLV, "Device Name TLV"}, + { UDLD_SEQ_NUMBER_TLV,"Sequence Number TLV"}, + { 0, NULL} +}; + +static struct tok udld_code_values[] = { + { 0x00, "Reserved"}, + { 0x01, "Probe message"}, + { 0x02, "Echo message"}, + { 0x03, "Flush message"}, + { 0, NULL} +}; + +static struct tok udld_flags_values[] = { + { 0x00, "RT"}, + { 0x01, "RSY"}, + { 0, NULL} +}; + +/* + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Ver | Opcode | Flags | Checksum | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | List of TLVs (variable length list) | + * | ... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +#define UDLD_EXTRACT_VERSION(x) (((x)&0xe0)>>5) +#define UDLD_EXTRACT_OPCODE(x) ((x)&0x1f) + +void +udld_print (const u_char *pptr, u_int length) +{ + int code, type, len; + const u_char *tptr; + + if (length < UDLD_HEADER_LEN) + goto trunc; + + tptr = pptr; + + if (!TTEST2(*tptr, UDLD_HEADER_LEN)) + goto trunc; + + code = UDLD_EXTRACT_OPCODE(*tptr); + + printf("UDLDv%u, Code %s (%x), Flags [%s] (0x%02x), length %u", + UDLD_EXTRACT_VERSION(*tptr), + tok2str(udld_code_values, "Reserved", code), + code, + bittok2str(udld_flags_values, "none", *(tptr+1)), + *(tptr+1), + length); + + /* + * In non-verbose mode, just print version and opcode type + */ + if (vflag < 1) { + return; + } + + printf("\n\tChecksum 0x%04x (unverified)", EXTRACT_16BITS(tptr+2)); + + tptr += UDLD_HEADER_LEN; + + while (tptr < (pptr+length)) { + + if (!TTEST2(*tptr, 4)) + goto trunc; + + type = EXTRACT_16BITS(tptr); + len = EXTRACT_16BITS(tptr+2); + len -= 4; + tptr += 4; + + /* infinite loop check */ + if (type == 0 || len == 0) { + return; + } + + printf("\n\t%s (0x%04x) TLV, length %u", + tok2str(udld_tlv_values, "Unknown", type), + type, len); + + switch (type) { + case UDLD_DEVICE_ID_TLV: + case UDLD_PORT_ID_TLV: + case UDLD_ECHO_TLV: + case UDLD_DEVICE_NAME_TLV: + printf(", %s", tptr); + break; + + case UDLD_MESSAGE_INTERVAL_TLV: + case UDLD_TIMEOUT_INTERVAL_TLV: + printf(", %us", (*tptr)); + break; + + case UDLD_SEQ_NUMBER_TLV: + printf(", %u", EXTRACT_32BITS(tptr)); + break; + + default: + break; + } + tptr += len; + } + + return; + + trunc: + printf("[|udld]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/print-udp.c b/print-udp.c new file mode 100644 index 0000000..0f1528e --- /dev/null +++ b/print-udp.c @@ -0,0 +1,720 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.142 2007-08-08 17:20:58 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifdef SEGSIZE +#undef SEGSIZE +#endif +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "appletalk.h" + +#include "udp.h" + +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif +#include "ipproto.h" +#include "rpc_auth.h" +#include "rpc_msg.h" + +#include "nameser.h" +#include "nfs.h" +#include "bootp.h" + +struct rtcphdr { + u_int16_t rh_flags; /* T:2 P:1 CNT:5 PT:8 */ + u_int16_t rh_len; /* length of message (in words) */ + u_int32_t rh_ssrc; /* synchronization src id */ +}; + +typedef struct { + u_int32_t upper; /* more significant 32 bits */ + u_int32_t lower; /* less significant 32 bits */ +} ntp64; + +/* + * Sender report. + */ +struct rtcp_sr { + ntp64 sr_ntp; /* 64-bit ntp timestamp */ + u_int32_t sr_ts; /* reference media timestamp */ + u_int32_t sr_np; /* no. packets sent */ + u_int32_t sr_nb; /* no. bytes sent */ +}; + +/* + * Receiver report. + * Time stamps are middle 32-bits of ntp timestamp. + */ +struct rtcp_rr { + u_int32_t rr_srcid; /* sender being reported */ + u_int32_t rr_nl; /* no. packets lost */ + u_int32_t rr_ls; /* extended last seq number received */ + u_int32_t rr_dv; /* jitter (delay variance) */ + u_int32_t rr_lsr; /* orig. ts from last rr from this src */ + u_int32_t rr_dlsr; /* time from recpt of last rr to xmit time */ +}; + +/*XXX*/ +#define RTCP_PT_SR 200 +#define RTCP_PT_RR 201 +#define RTCP_PT_SDES 202 +#define RTCP_SDES_CNAME 1 +#define RTCP_SDES_NAME 2 +#define RTCP_SDES_EMAIL 3 +#define RTCP_SDES_PHONE 4 +#define RTCP_SDES_LOC 5 +#define RTCP_SDES_TOOL 6 +#define RTCP_SDES_NOTE 7 +#define RTCP_SDES_PRIV 8 +#define RTCP_PT_BYE 203 +#define RTCP_PT_APP 204 + +static void +vat_print(const void *hdr, register const struct udphdr *up) +{ + /* vat/vt audio */ + u_int ts = *(u_int16_t *)hdr; + if ((ts & 0xf060) != 0) { + /* probably vt */ + (void)printf("udp/vt %u %d / %d", + (u_int32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up)), + ts & 0x3ff, ts >> 10); + } else { + /* probably vat */ + u_int32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]); + u_int32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]); + printf("udp/vat %u c%d %u%s", + (u_int32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8), + i0 & 0xffff, + i1, i0 & 0x800000? "*" : ""); + /* audio format */ + if (i0 & 0x1f0000) + printf(" f%d", (i0 >> 16) & 0x1f); + if (i0 & 0x3f000000) + printf(" s%d", (i0 >> 24) & 0x3f); + } +} + +static void +rtp_print(const void *hdr, u_int len, register const struct udphdr *up) +{ + /* rtp v1 or v2 */ + u_int *ip = (u_int *)hdr; + u_int hasopt, hasext, contype, hasmarker; + u_int32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]); + u_int32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]); + u_int dlen = EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8; + const char * ptype; + + ip += 2; + len >>= 2; + len -= 2; + hasopt = 0; + hasext = 0; + if ((i0 >> 30) == 1) { + /* rtp v1 */ + hasopt = i0 & 0x800000; + contype = (i0 >> 16) & 0x3f; + hasmarker = i0 & 0x400000; + ptype = "rtpv1"; + } else { + /* rtp v2 */ + hasext = i0 & 0x10000000; + contype = (i0 >> 16) & 0x7f; + hasmarker = i0 & 0x800000; + dlen -= 4; + ptype = "rtp"; + ip += 1; + len -= 1; + } + printf("udp/%s %d c%d %s%s %d %u", + ptype, + dlen, + contype, + (hasopt || hasext)? "+" : "", + hasmarker? "*" : "", + i0 & 0xffff, + i1); + if (vflag) { + printf(" %u", EXTRACT_32BITS(&((u_int *)hdr)[2])); + if (hasopt) { + u_int i2, optlen; + do { + i2 = ip[0]; + optlen = (i2 >> 16) & 0xff; + if (optlen == 0 || optlen > len) { + printf(" !opt"); + return; + } + ip += optlen; + len -= optlen; + } while ((int)i2 >= 0); + } + if (hasext) { + u_int i2, extlen; + i2 = ip[0]; + extlen = (i2 & 0xffff) + 1; + if (extlen > len) { + printf(" !ext"); + return; + } + ip += extlen; + } + if (contype == 0x1f) /*XXX H.261 */ + printf(" 0x%04x", ip[0] >> 16); + } +} + +static const u_char * +rtcp_print(const u_char *hdr, const u_char *ep) +{ + /* rtp v2 control (rtcp) */ + struct rtcp_rr *rr = 0; + struct rtcp_sr *sr; + struct rtcphdr *rh = (struct rtcphdr *)hdr; + u_int len; + u_int16_t flags; + int cnt; + double ts, dts; + if ((u_char *)(rh + 1) > ep) { + printf(" [|rtcp]"); + return (ep); + } + len = (EXTRACT_16BITS(&rh->rh_len) + 1) * 4; + flags = EXTRACT_16BITS(&rh->rh_flags); + cnt = (flags >> 8) & 0x1f; + switch (flags & 0xff) { + case RTCP_PT_SR: + sr = (struct rtcp_sr *)(rh + 1); + printf(" sr"); + if (len != cnt * sizeof(*rr) + sizeof(*sr) + sizeof(*rh)) + printf(" [%d]", len); + if (vflag) + printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc)); + if ((u_char *)(sr + 1) > ep) { + printf(" [|rtcp]"); + return (ep); + } + ts = (double)(EXTRACT_32BITS(&sr->sr_ntp.upper)) + + ((double)(EXTRACT_32BITS(&sr->sr_ntp.lower)) / + 4294967296.0); + printf(" @%.2f %u %up %ub", ts, EXTRACT_32BITS(&sr->sr_ts), + EXTRACT_32BITS(&sr->sr_np), EXTRACT_32BITS(&sr->sr_nb)); + rr = (struct rtcp_rr *)(sr + 1); + break; + case RTCP_PT_RR: + printf(" rr"); + if (len != cnt * sizeof(*rr) + sizeof(*rh)) + printf(" [%d]", len); + rr = (struct rtcp_rr *)(rh + 1); + if (vflag) + printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc)); + break; + case RTCP_PT_SDES: + printf(" sdes %d", len); + if (vflag) + printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc)); + cnt = 0; + break; + case RTCP_PT_BYE: + printf(" bye %d", len); + if (vflag) + printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc)); + cnt = 0; + break; + default: + printf(" type-0x%x %d", flags & 0xff, len); + cnt = 0; + break; + } + if (cnt > 1) + printf(" c%d", cnt); + while (--cnt >= 0) { + if ((u_char *)(rr + 1) > ep) { + printf(" [|rtcp]"); + return (ep); + } + if (vflag) + printf(" %u", EXTRACT_32BITS(&rr->rr_srcid)); + ts = (double)(EXTRACT_32BITS(&rr->rr_lsr)) / 65536.; + dts = (double)(EXTRACT_32BITS(&rr->rr_dlsr)) / 65536.; + printf(" %ul %us %uj @%.2f+%.2f", + EXTRACT_32BITS(&rr->rr_nl) & 0x00ffffff, + EXTRACT_32BITS(&rr->rr_ls), + EXTRACT_32BITS(&rr->rr_dv), ts, dts); + } + return (hdr + len); +} + +static int udp_cksum(register const struct ip *ip, + register const struct udphdr *up, + register u_int len) +{ + union phu { + struct phdr { + u_int32_t src; + u_int32_t dst; + u_char mbz; + u_char proto; + u_int16_t len; + } ph; + u_int16_t pa[6]; + } phu; + register const u_int16_t *sp; + + /* pseudo-header.. */ + phu.ph.len = htons((u_int16_t)len); + phu.ph.mbz = 0; + phu.ph.proto = IPPROTO_UDP; + memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t)); + if (IP_HL(ip) == 5) + memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t)); + else + phu.ph.dst = ip_finddst(ip); + + sp = &phu.pa[0]; + return in_cksum((u_short *)up, len, + sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]); +} + +#ifdef INET6 +static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up, + u_int len) +{ + size_t i; + register const u_int16_t *sp; + u_int32_t sum; + union { + struct { + struct in6_addr ph_src; + struct in6_addr ph_dst; + u_int32_t ph_len; + u_int8_t ph_zero[3]; + u_int8_t ph_nxt; + } ph; + u_int16_t pa[20]; + } phu; + + /* pseudo-header */ + memset(&phu, 0, sizeof(phu)); + phu.ph.ph_src = ip6->ip6_src; + phu.ph.ph_dst = ip6->ip6_dst; + phu.ph.ph_len = htonl(len); + phu.ph.ph_nxt = IPPROTO_UDP; + + sum = 0; + for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) + sum += phu.pa[i]; + + sp = (const u_int16_t *)up; + + for (i = 0; i < (len & ~1); i += 2) + sum += *sp++; + + if (len & 1) + sum += htons((*(const u_int8_t *)sp) << 8); + + while (sum > 0xffff) + sum = (sum & 0xffff) + (sum >> 16); + sum = ~sum & 0xffff; + + return (sum); +} +#endif + +static void +udpipaddr_print(const struct ip *ip, int sport, int dport) +{ +#ifdef INET6 + const struct ip6_hdr *ip6; + + if (IP_V(ip) == 6) + ip6 = (const struct ip6_hdr *)ip; + else + ip6 = NULL; + + if (ip6) { + if (ip6->ip6_nxt == IPPROTO_UDP) { + if (sport == -1) { + (void)printf("%s > %s: ", + ip6addr_string(&ip6->ip6_src), + ip6addr_string(&ip6->ip6_dst)); + } else { + (void)printf("%s.%s > %s.%s: ", + ip6addr_string(&ip6->ip6_src), + udpport_string(sport), + ip6addr_string(&ip6->ip6_dst), + udpport_string(dport)); + } + } else { + if (sport != -1) { + (void)printf("%s > %s: ", + udpport_string(sport), + udpport_string(dport)); + } + } + } else +#endif /*INET6*/ + { + if (ip->ip_p == IPPROTO_UDP) { + if (sport == -1) { + (void)printf("%s > %s: ", + ipaddr_string(&ip->ip_src), + ipaddr_string(&ip->ip_dst)); + } else { + (void)printf("%s.%s > %s.%s: ", + ipaddr_string(&ip->ip_src), + udpport_string(sport), + ipaddr_string(&ip->ip_dst), + udpport_string(dport)); + } + } else { + if (sport != -1) { + (void)printf("%s > %s: ", + udpport_string(sport), + udpport_string(dport)); + } + } + } +} + +void +udp_print(register const u_char *bp, u_int length, + register const u_char *bp2, int fragmented) +{ + register const struct udphdr *up; + register const struct ip *ip; + register const u_char *cp; + register const u_char *ep = bp + length; + u_int16_t sport, dport, ulen; +#ifdef INET6 + register const struct ip6_hdr *ip6; +#endif + + if (ep > snapend) + ep = snapend; + up = (struct udphdr *)bp; + ip = (struct ip *)bp2; +#ifdef INET6 + if (IP_V(ip) == 6) + ip6 = (struct ip6_hdr *)bp2; + else + ip6 = NULL; +#endif /*INET6*/ + cp = (u_char *)(up + 1); + if (!TTEST(up->uh_dport)) { + udpipaddr_print(ip, -1, -1); + (void)printf("[|udp]"); + return; + } + + sport = EXTRACT_16BITS(&up->uh_sport); + dport = EXTRACT_16BITS(&up->uh_dport); + + if (length < sizeof(struct udphdr)) { + udpipaddr_print(ip, sport, dport); + (void)printf("truncated-udp %d", length); + return; + } + length -= sizeof(struct udphdr); + + if (cp > snapend) { + udpipaddr_print(ip, sport, dport); + (void)printf("[|udp]"); + return; + } + + ulen = EXTRACT_16BITS(&up->uh_ulen); + if (ulen < 8) { + udpipaddr_print(ip, sport, dport); + (void)printf("truncated-udplength %d", ulen); + return; + } + if (packettype) { + register struct sunrpc_msg *rp; + enum sunrpc_msg_type direction; + + switch (packettype) { + + case PT_VAT: + udpipaddr_print(ip, sport, dport); + vat_print((void *)(up + 1), up); + break; + + case PT_WB: + udpipaddr_print(ip, sport, dport); + wb_print((void *)(up + 1), length); + break; + + case PT_RPC: + rp = (struct sunrpc_msg *)(up + 1); + direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction); + if (direction == SUNRPC_CALL) + sunrpcrequest_print((u_char *)rp, length, + (u_char *)ip); + else + nfsreply_print((u_char *)rp, length, + (u_char *)ip); /*XXX*/ + break; + + case PT_RTP: + udpipaddr_print(ip, sport, dport); + rtp_print((void *)(up + 1), length, up); + break; + + case PT_RTCP: + udpipaddr_print(ip, sport, dport); + while (cp < ep) + cp = rtcp_print(cp, ep); + break; + + case PT_SNMP: + udpipaddr_print(ip, sport, dport); + snmp_print((const u_char *)(up + 1), length); + break; + + case PT_CNFP: + udpipaddr_print(ip, sport, dport); + cnfp_print(cp, (const u_char *)ip); + break; + + case PT_TFTP: + udpipaddr_print(ip, sport, dport); + tftp_print(cp, length); + break; + + case PT_AODV: + udpipaddr_print(ip, sport, dport); + aodv_print((const u_char *)(up + 1), length, +#ifdef INET6 + ip6 != NULL); +#else + 0); +#endif + break; + } + return; + } + + if (!qflag) { + register struct sunrpc_msg *rp; + enum sunrpc_msg_type direction; + + rp = (struct sunrpc_msg *)(up + 1); + if (TTEST(rp->rm_direction)) { + direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction); + if (dport == NFS_PORT && direction == SUNRPC_CALL) { + nfsreq_print((u_char *)rp, length, + (u_char *)ip); + return; + } + if (sport == NFS_PORT && direction == SUNRPC_REPLY) { + nfsreply_print((u_char *)rp, length, + (u_char *)ip); + return; + } +#ifdef notdef + if (dport == SUNRPC_PORT && direction == SUNRPC_CALL) { + sunrpcrequest_print((u_char *)rp, length, (u_char *)ip); + return; + } +#endif + } + if (TTEST(((struct LAP *)cp)->type) && + ((struct LAP *)cp)->type == lapDDP && + (atalk_port(sport) || atalk_port(dport))) { + if (vflag) + fputs("kip ", stdout); + llap_print(cp, length); + return; + } + } + udpipaddr_print(ip, sport, dport); + + if (IP_V(ip) == 4 && (vflag > 1) && !Kflag && !fragmented) { + int sum = up->uh_sum; + if (sum == 0) { + (void)printf("[no cksum] "); + } else if (TTEST2(cp[0], length)) { + sum = udp_cksum(ip, up, length + sizeof(struct udphdr)); + if (sum != 0) + (void)printf("[bad udp cksum %x!] ", sum); + else + (void)printf("[udp sum ok] "); + } + } +#ifdef INET6 + if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !Kflag && !fragmented) { + int sum = up->uh_sum; + /* for IPv6, UDP checksum is mandatory */ + if (TTEST2(cp[0], length)) { + sum = udp6_cksum(ip6, up, length + sizeof(struct udphdr)); + if (sum != 0) + (void)printf("[bad udp cksum %x!] ", sum); + else + (void)printf("[udp sum ok] "); + } + } +#endif + + if (!qflag) { +#define ISPORT(p) (dport == (p) || sport == (p)) + if (ISPORT(NAMESERVER_PORT)) + ns_print((const u_char *)(up + 1), length, 0); + else if (ISPORT(MULTICASTDNS_PORT)) + ns_print((const u_char *)(up + 1), length, 1); + else if (ISPORT(TIMED_PORT)) + timed_print((const u_char *)(up + 1)); + else if (ISPORT(TFTP_PORT)) + tftp_print((const u_char *)(up + 1), length); + else if (ISPORT(IPPORT_BOOTPC) || ISPORT(IPPORT_BOOTPS)) + bootp_print((const u_char *)(up + 1), length); + else if (ISPORT(RIP_PORT)) + rip_print((const u_char *)(up + 1), length); + else if (ISPORT(AODV_PORT)) + aodv_print((const u_char *)(up + 1), length, +#ifdef INET6 + ip6 != NULL); +#else + 0); +#endif + else if (ISPORT(ISAKMP_PORT)) + isakmp_print(gndo, (const u_char *)(up + 1), length, bp2); + else if (ISPORT(ISAKMP_PORT_NATT)) + isakmp_rfc3948_print(gndo, (const u_char *)(up + 1), length, bp2); +#if 1 /*???*/ + else if (ISPORT(ISAKMP_PORT_USER1) || ISPORT(ISAKMP_PORT_USER2)) + isakmp_print(gndo, (const u_char *)(up + 1), length, bp2); +#endif + else if (ISPORT(SNMP_PORT) || ISPORT(SNMPTRAP_PORT)) + snmp_print((const u_char *)(up + 1), length); + else if (ISPORT(NTP_PORT)) + ntp_print((const u_char *)(up + 1), length); + else if (ISPORT(KERBEROS_PORT) || ISPORT(KERBEROS_SEC_PORT)) + krb_print((const void *)(up + 1)); + else if (ISPORT(L2TP_PORT)) + l2tp_print((const u_char *)(up + 1), length); +#ifdef TCPDUMP_DO_SMB + else if (ISPORT(NETBIOS_NS_PORT)) + nbt_udp137_print((const u_char *)(up + 1), length); + else if (ISPORT(NETBIOS_DGRAM_PORT)) + nbt_udp138_print((const u_char *)(up + 1), length); +#endif + else if (dport == 3456) + vat_print((const void *)(up + 1), up); + else if (ISPORT(ZEPHYR_SRV_PORT) || ISPORT(ZEPHYR_CLT_PORT)) + zephyr_print((const void *)(up + 1), length); + /* + * Since there are 10 possible ports to check, I think + * a <> test would be more efficient + */ + else if ((sport >= RX_PORT_LOW && sport <= RX_PORT_HIGH) || + (dport >= RX_PORT_LOW && dport <= RX_PORT_HIGH)) + rx_print((const void *)(up + 1), length, sport, dport, + (u_char *) ip); +#ifdef INET6 + else if (ISPORT(RIPNG_PORT)) + ripng_print((const u_char *)(up + 1), length); + else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT)) { + dhcp6_print((const u_char *)(up + 1), length); + } +#endif /*INET6*/ + /* + * Kludge in test for whiteboard packets. + */ + else if (dport == 4567) + wb_print((const void *)(up + 1), length); + else if (ISPORT(CISCO_AUTORP_PORT)) + cisco_autorp_print((const void *)(up + 1), length); + else if (ISPORT(RADIUS_PORT) || + ISPORT(RADIUS_NEW_PORT) || + ISPORT(RADIUS_ACCOUNTING_PORT) || + ISPORT(RADIUS_NEW_ACCOUNTING_PORT) ) + radius_print((const u_char *)(up+1), length); + else if (dport == HSRP_PORT) + hsrp_print((const u_char *)(up + 1), length); + else if (ISPORT(LWRES_PORT)) + lwres_print((const u_char *)(up + 1), length); + else if (ISPORT(LDP_PORT)) + ldp_print((const u_char *)(up + 1), length); + else if (ISPORT(OLSR_PORT)) + olsr_print((const u_char *)(up + 1), length, +#if INET6 + (IP_V(ip) == 6) ? 1 : 0); +#else + 0); +#endif + else if (ISPORT(MPLS_LSP_PING_PORT)) + lspping_print((const u_char *)(up + 1), length); + else if (dport == BFD_CONTROL_PORT || + dport == BFD_ECHO_PORT ) + bfd_print((const u_char *)(up+1), length, dport); + else if (ISPORT(LMP_PORT)) + lmp_print((const u_char *)(up + 1), length); + else if (ISPORT(VQP_PORT)) + vqp_print((const u_char *)(up + 1), length); + else if (ISPORT(SFLOW_PORT)) + sflow_print((const u_char *)(up + 1), length); + else if (dport == LWAPP_CONTROL_PORT) + lwapp_control_print((const u_char *)(up + 1), length, 1); + else if (sport == LWAPP_CONTROL_PORT) + lwapp_control_print((const u_char *)(up + 1), length, 0); + else if (ISPORT(LWAPP_DATA_PORT)) + lwapp_data_print((const u_char *)(up + 1), length); + else if (ISPORT(SIP_PORT)) + sip_print((const u_char *)(up + 1), length); + else if (ISPORT(SYSLOG_PORT)) + syslog_print((const u_char *)(up + 1), length); + else + (void)printf("UDP, length %u", + (u_int32_t)(ulen - sizeof(*up))); +#undef ISPORT + } else + (void)printf("UDP, length %u", (u_int32_t)(ulen - sizeof(*up))); +} + + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ + diff --git a/print-usb.c b/print-usb.c new file mode 100644 index 0000000..8e15e7b --- /dev/null +++ b/print-usb.c @@ -0,0 +1,174 @@ +/* + * Copyright 2009 Bert Vermeulen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by Paolo Abeni.'' + * The name of author may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Support for USB packets + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" + + +#if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) +#include + +/* returns direction: 1=inbound 2=outbound -1=invalid */ +static int +get_direction(int transfer_type, int event_type) +{ + int direction; + + direction = -1; + switch(transfer_type){ + case URB_BULK: + case URB_CONTROL: + case URB_ISOCHRONOUS: + switch(event_type) + { + case URB_SUBMIT: + direction = 2; + break; + case URB_COMPLETE: + case URB_ERROR: + direction = 1; + break; + default: + direction = -1; + } + break; + case URB_INTERRUPT: + switch(event_type) + { + case URB_SUBMIT: + direction = 1; + break; + case URB_COMPLETE: + case URB_ERROR: + direction = 2; + break; + default: + direction = -1; + } + break; + default: + direction = -1; + } + + return direction; +} + +static void +usb_header_print(const pcap_usb_header *uh) +{ + int direction; + + switch(uh->transfer_type) + { + case URB_ISOCHRONOUS: + printf("ISOCHRONOUS"); + break; + case URB_INTERRUPT: + printf("INTERRUPT"); + break; + case URB_CONTROL: + printf("CONTROL"); + break; + case URB_BULK: + printf("BULK"); + break; + default: + printf(" ?"); + } + + switch(uh->event_type) + { + case URB_SUBMIT: + printf(" SUBMIT"); + break; + case URB_COMPLETE: + printf(" COMPLETE"); + break; + case URB_ERROR: + printf(" ERROR"); + break; + default: + printf(" ?"); + } + + direction = get_direction(uh->transfer_type, uh->event_type); + if(direction == 1) + printf(" from"); + else if(direction == 2) + printf(" to"); + printf(" %d:%d:%d", uh->bus_id, uh->device_address, uh->endpoint_number & 0x7f); +} + +/* + * This is the top level routine of the printer for captures with a + * 48-byte header. + * + * 'p' points to the header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +usb_linux_48_byte_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + if (h->caplen < sizeof(pcap_usb_header)) { + printf("[|usb]"); + return(sizeof(pcap_usb_header)); + } + + usb_header_print((const pcap_usb_header *) p); + + return(sizeof(pcap_usb_header)); +} + +#ifdef DLT_USB_LINUX_MMAPPED +/* + * This is the top level routine of the printer for captures with a + * 64-byte header. + * + * 'p' points to the header of the packet, 'h->ts' is the timestamp, + * 'h->len' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +usb_linux_64_byte_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + if (h->caplen < sizeof(pcap_usb_header_mmapped)) { + printf("[|usb]"); + return(sizeof(pcap_usb_header_mmapped)); + } + + usb_header_print((const pcap_usb_header *) p); + + return(sizeof(pcap_usb_header_mmapped)); +} +#endif /* DLT_USB_LINUX_MMAPPED */ + +#endif /* defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) */ + diff --git a/print-vjc.c b/print-vjc.c new file mode 100644 index 0000000..2dc89aa --- /dev/null +++ b/print-vjc.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-vjc.c,v 1.15 2004-03-25 03:31:17 mcr Exp $ (LBL)"; +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" + +#include "slcompress.h" +#include "ppp.h" + +/* + * XXX - for BSD/OS PPP, what packets get supplied with a PPP header type + * of PPP_VJC and what packets get supplied with a PPP header type of + * PPP_VJNC? PPP_VJNC is for "UNCOMPRESSED_TCP" packets, and PPP_VJC + * is for COMPRESSED_TCP packets (PPP_IP is used for TYPE_IP packets). + * + * RFC 1144 implies that, on the wire, the packet type is *not* needed + * for PPP, as different PPP protocol types can be used; it only needs + * to be put on the wire for SLIP. + * + * It also indicates that, for compressed SLIP: + * + * If the COMPRESSED_TCP bit is set in the first byte, it's + * a COMPRESSED_TCP packet; that byte is the change byte, and + * the COMPRESSED_TCP bit, 0x80, isn't used in the change byte. + * + * If the upper 4 bits of the first byte are 7, it's an + * UNCOMPRESSED_TCP packet; that byte is the first byte of + * the UNCOMPRESSED_TCP modified IP header, with a connection + * number in the protocol field, and with the version field + * being 7, not 4. + * + * Otherwise, the packet is an IPv4 packet (where the upper 4 bits + * of the packet are 4). + * + * So this routine looks as if it's sort-of intended to handle + * compressed SLIP, although it doesn't handle UNCOMPRESSED_TCP + * correctly for that (it doesn't fix the version number and doesn't + * do anything to the protocol field), and doesn't check for COMPRESSED_TCP + * packets correctly for that (you only check the first bit - see + * B.1 in RFC 1144). + * + * But it's called for BSD/OS PPP, not SLIP - perhaps BSD/OS does weird + * things with the headers? + * + * Without a BSD/OS VJC-compressed PPP trace, or knowledge of what the + * BSD/OS VJC code does, we can't say what's the case. + * + * We therefore leave "proto" - which is the PPP protocol type - in place, + * *not* marked as unused, for now, so that GCC warnings about the + * unused argument remind us that we should fix this some day. + */ +int +vjc_print(register const char *bp, u_short proto _U_) +{ + int i; + + switch (bp[0] & 0xf0) { + case TYPE_IP: + if (eflag) + printf("(vjc type=IP) "); + return PPP_IP; + case TYPE_UNCOMPRESSED_TCP: + if (eflag) + printf("(vjc type=raw TCP) "); + return PPP_IP; + case TYPE_COMPRESSED_TCP: + if (eflag) + printf("(vjc type=compressed TCP) "); + for (i = 0; i < 8; i++) { + if (bp[1] & (0x80 >> i)) + printf("%c", "?CI?SAWU"[i]); + } + if (bp[1]) + printf(" "); + printf("C=0x%02x ", bp[2]); + printf("sum=0x%04x ", *(u_short *)&bp[3]); + return -1; + case TYPE_ERROR: + if (eflag) + printf("(vjc type=error) "); + return -1; + default: + if (eflag) + printf("(vjc type=0x%02x) ", bp[0] & 0xf0); + return -1; + } +} diff --git a/print-vqp.c b/print-vqp.c new file mode 100644 index 0000000..2d9e8e1 --- /dev/null +++ b/print-vqp.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 1998-2006 The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * support for the Cisco prop. VQP Protocol + * + * Original code by Carles Kishimoto + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-vqp.c,v 1.3 2006-08-19 06:51:13 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +#define VQP_VERSION 1 +#define VQP_EXTRACT_VERSION(x) ((x)&0xFF) + +/* + * VQP common header + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Constant | Packet type | Error Code | nitems | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Packet Sequence Number (4 bytes) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct vqp_common_header_t { + u_int8_t version; + u_int8_t msg_type; + u_int8_t error_code; + u_int8_t nitems; + u_int8_t sequence[4]; +}; + +struct vqp_obj_tlv_t { + u_int8_t obj_type[4]; + u_int8_t obj_length[2]; +}; + +#define VQP_OBJ_REQ_JOIN_PORT 0x01 +#define VQP_OBJ_RESP_VLAN 0x02 +#define VQP_OBJ_REQ_RECONFIRM 0x03 +#define VQP_OBJ_RESP_RECONFIRM 0x04 + +static const struct tok vqp_msg_type_values[] = { + { VQP_OBJ_REQ_JOIN_PORT, "Request, Join Port"}, + { VQP_OBJ_RESP_VLAN, "Response, VLAN"}, + { VQP_OBJ_REQ_RECONFIRM, "Request, Reconfirm"}, + { VQP_OBJ_RESP_RECONFIRM, "Response, Reconfirm"}, + { 0, NULL} +}; + +static const struct tok vqp_error_code_values[] = { + { 0x00, "No error"}, + { 0x03, "Access denied"}, + { 0x04, "Shutdown port"}, + { 0x05, "Wrong VTP domain"}, + { 0, NULL} +}; + +/* FIXME the heading 0x0c looks ugly - those must be flags etc. */ +#define VQP_OBJ_IP_ADDRESS 0x0c01 +#define VQP_OBJ_PORT_NAME 0x0c02 +#define VQP_OBJ_VLAN_NAME 0x0c03 +#define VQP_OBJ_VTP_DOMAIN 0x0c04 +#define VQP_OBJ_ETHERNET_PKT 0x0c05 +#define VQP_OBJ_MAC_NULL 0x0c06 +#define VQP_OBJ_MAC_ADDRESS 0x0c08 + +static const struct tok vqp_obj_values[] = { + { VQP_OBJ_IP_ADDRESS, "Client IP Address" }, + { VQP_OBJ_PORT_NAME, "Port Name" }, + { VQP_OBJ_VLAN_NAME, "VLAN Name" }, + { VQP_OBJ_VTP_DOMAIN, "VTP Domain" }, + { VQP_OBJ_ETHERNET_PKT, "Ethernet Packet" }, + { VQP_OBJ_MAC_NULL, "MAC Null" }, + { VQP_OBJ_MAC_ADDRESS, "MAC Address" }, + { 0, NULL} +}; + +void +vqp_print(register const u_char *pptr, register u_int len) +{ + const struct vqp_common_header_t *vqp_common_header; + const struct vqp_obj_tlv_t *vqp_obj_tlv; + + const u_char *tptr; + u_int16_t vqp_obj_len; + u_int32_t vqp_obj_type; + int tlen; + u_int8_t nitems; + + tptr=pptr; + tlen = len; + vqp_common_header = (const struct vqp_common_header_t *)pptr; + TCHECK(*vqp_common_header); + + /* + * Sanity checking of the header. + */ + if (VQP_EXTRACT_VERSION(vqp_common_header->version) != VQP_VERSION) { + printf("VQP version %u packet not supported", + VQP_EXTRACT_VERSION(vqp_common_header->version)); + return; + } + + /* in non-verbose mode just lets print the basic Message Type */ + if (vflag < 1) { + printf("VQPv%u %s Message, error-code %s (%u), length %u", + VQP_EXTRACT_VERSION(vqp_common_header->version), + tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type), + tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code), + vqp_common_header->error_code, + len); + return; + } + + /* ok they seem to want to know everything - lets fully decode it */ + nitems = vqp_common_header->nitems; + printf("\n\tVQPv%u, %s Message, error-code %s (%u), seq 0x%08x, items %u, length %u", + VQP_EXTRACT_VERSION(vqp_common_header->version), + tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type), + tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code), + vqp_common_header->error_code, + EXTRACT_32BITS(&vqp_common_header->sequence), + nitems, + len); + + /* skip VQP Common header */ + tptr+=sizeof(const struct vqp_common_header_t); + tlen-=sizeof(const struct vqp_common_header_t); + + while (nitems > 0 && tlen > 0) { + + vqp_obj_tlv = (const struct vqp_obj_tlv_t *)tptr; + vqp_obj_type = EXTRACT_32BITS(vqp_obj_tlv->obj_type); + vqp_obj_len = EXTRACT_16BITS(vqp_obj_tlv->obj_length); + tptr+=sizeof(struct vqp_obj_tlv_t); + tlen-=sizeof(struct vqp_obj_tlv_t); + + printf("\n\t %s Object (0x%08x), length %u, value: ", + tok2str(vqp_obj_values, "Unknown", vqp_obj_type), + vqp_obj_type, vqp_obj_len); + + /* basic sanity check */ + if (vqp_obj_type == 0 || vqp_obj_len ==0) { + return; + } + + /* did we capture enough for fully decoding the object ? */ + if (!TTEST2(*tptr, vqp_obj_len)) + goto trunc; + + switch(vqp_obj_type) { + case VQP_OBJ_IP_ADDRESS: + printf("%s (0x%08x)", ipaddr_string(tptr), EXTRACT_32BITS(tptr)); + break; + /* those objects have similar semantics - fall through */ + case VQP_OBJ_PORT_NAME: + case VQP_OBJ_VLAN_NAME: + case VQP_OBJ_VTP_DOMAIN: + case VQP_OBJ_ETHERNET_PKT: + safeputs((const char *)tptr, vqp_obj_len); + break; + /* those objects have similar semantics - fall through */ + case VQP_OBJ_MAC_ADDRESS: + case VQP_OBJ_MAC_NULL: + printf("%s", etheraddr_string(tptr)); + break; + default: + if (vflag <= 1) + print_unknown_data(tptr, "\n\t ", vqp_obj_len); + break; + } + tptr += vqp_obj_len; + tlen -= vqp_obj_len; + nitems--; + } + return; +trunc: + printf("\n\t[|VQP]"); +} diff --git a/print-vrrp.c b/print-vrrp.c new file mode 100644 index 0000000..899542d --- /dev/null +++ b/print-vrrp.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2000 William C. Fenner. + * All rights reserved. + * + * Kevin Steves July 2000 + * Modified to: + * - print version, type string and packet length + * - print IP address count if > 1 (-v) + * - verify checksum (-v) + * - print authentication string (-v) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * The name of William C. Fenner may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-vrrp.c,v 1.10 2005-05-06 07:56:54 guy Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" + +/* + * RFC 2338: + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Version| Type | Virtual Rtr ID| Priority | Count IP Addrs| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Auth Type | Adver Int | Checksum | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IP Address (1) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | . | + * | . | + * | . | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | IP Address (n) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Authentication Data (1) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Authentication Data (2) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +/* Type */ +#define VRRP_TYPE_ADVERTISEMENT 1 + +static const struct tok type2str[] = { + { VRRP_TYPE_ADVERTISEMENT, "Advertisement" }, + { 0, NULL } +}; + +/* Auth Type */ +#define VRRP_AUTH_NONE 0 +#define VRRP_AUTH_SIMPLE 1 +#define VRRP_AUTH_AH 2 + +static const struct tok auth2str[] = { + { VRRP_AUTH_NONE, "none" }, + { VRRP_AUTH_SIMPLE, "simple" }, + { VRRP_AUTH_AH, "ah" }, + { 0, NULL } +}; + +void +vrrp_print(register const u_char *bp, register u_int len, int ttl) +{ + int version, type, auth_type; + const char *type_s; + + TCHECK(bp[0]); + version = (bp[0] & 0xf0) >> 4; + type = bp[0] & 0x0f; + type_s = tok2str(type2str, "unknown type (%u)", type); + printf("VRRPv%u, %s", version, type_s); + if (ttl != 255) + printf(", (ttl %u)", ttl); + if (version != 2 || type != VRRP_TYPE_ADVERTISEMENT) + return; + TCHECK(bp[2]); + printf(", vrid %u, prio %u", bp[1], bp[2]); + TCHECK(bp[5]); + auth_type = bp[4]; + printf(", authtype %s", tok2str(auth2str, NULL, auth_type)); + printf(", intvl %us, length %u", bp[5],len); + if (vflag) { + int naddrs = bp[3]; + int i; + char c; + + if (TTEST2(bp[0], len) && in_cksum((const u_short*)bp, len, 0)) + printf(", (bad vrrp cksum %x)", + EXTRACT_16BITS(&bp[6])); + printf(", addrs"); + if (naddrs > 1) + printf("(%d)", naddrs); + printf(":"); + c = ' '; + bp += 8; + for (i = 0; i < naddrs; i++) { + TCHECK(bp[3]); + printf("%c%s", c, ipaddr_string(bp)); + c = ','; + bp += 4; + } + if (auth_type == VRRP_AUTH_SIMPLE) { /* simple text password */ + TCHECK(bp[7]); + printf(" auth \""); + if (fn_printn(bp, 8, snapend)) { + printf("\""); + goto trunc; + } + printf("\""); + } + } + return; +trunc: + printf("[|vrrp]"); +} diff --git a/print-vtp.c b/print-vtp.c new file mode 100644 index 0000000..7631c6f --- /dev/null +++ b/print-vtp.c @@ -0,0 +1,378 @@ +/* + * Copyright (c) 1998-2007 The TCPDUMP project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * VLAN TRUNKING PROTOCOL (VTP) + * + * Reference documentation: + * http://www.cisco.com/en/US/tech/tk389/tk689/technologies_tech_note09186a0080094c52.shtml + * http://www.cisco.com/warp/public/473/21.html + * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm + * + * Original code ode by Carles Kishimoto + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" +#include "nlpid.h" + +#define VTP_HEADER_LEN 36 +#define VTP_DOMAIN_NAME_LEN 32 +#define VTP_MD5_DIGEST_LEN 16 +#define VTP_UPDATE_TIMESTAMP_LEN 12 +#define VTP_VLAN_INFO_OFFSET 12 + +#define VTP_SUMMARY_ADV 0x01 +#define VTP_SUBSET_ADV 0x02 +#define VTP_ADV_REQUEST 0x03 +#define VTP_JOIN_MESSAGE 0x04 + +struct vtp_vlan_ { + u_int8_t len; + u_int8_t status; + u_int8_t type; + u_int8_t name_len; + u_int16_t vlanid; + u_int16_t mtu; + u_int32_t index; +}; + +static struct tok vtp_message_type_values[] = { + { VTP_SUMMARY_ADV, "Summary advertisement"}, + { VTP_SUBSET_ADV, "Subset advertisement"}, + { VTP_ADV_REQUEST, "Advertisement request"}, + { VTP_JOIN_MESSAGE, "Join message"}, + { 0, NULL } +}; + +static struct tok vtp_header_values[] = { + { 0x01, "Followers"}, /* On Summary advertisement, 3rd byte is Followers */ + { 0x02, "Seq number"}, /* On Subset advertisement, 3rd byte is Sequence number */ + { 0x03, "Rsvd"}, /* On Adver. requests 3rd byte is Rsvd */ + { 0x04, "Rsvd"}, /* On Adver. requests 3rd byte is Rsvd */ + { 0, NULL } +}; + +static struct tok vtp_vlan_type_values[] = { + { 0x01, "Ethernet"}, + { 0x02, "FDDI"}, + { 0x03, "TrCRF"}, + { 0x04, "FDDI-net"}, + { 0x05, "TrBRF"}, + { 0, NULL } +}; + +static struct tok vtp_vlan_status[] = { + { 0x00, "Operational"}, + { 0x01, "Suspended"}, + { 0, NULL } +}; + +#define VTP_VLAN_SOURCE_ROUTING_RING_NUMBER 0x01 +#define VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER 0x02 +#define VTP_VLAN_STP_TYPE 0x03 +#define VTP_VLAN_PARENT_VLAN 0x04 +#define VTP_VLAN_TRANS_BRIDGED_VLAN 0x05 +#define VTP_VLAN_PRUNING 0x06 +#define VTP_VLAN_BRIDGE_TYPE 0x07 +#define VTP_VLAN_ARP_HOP_COUNT 0x08 +#define VTP_VLAN_STE_HOP_COUNT 0x09 +#define VTP_VLAN_BACKUP_CRF_MODE 0x0A + +static struct tok vtp_vlan_tlv_values[] = { + { VTP_VLAN_SOURCE_ROUTING_RING_NUMBER, "Source-Routing Ring Number TLV"}, + { VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER, "Source-Routing Bridge Number TLV"}, + { VTP_VLAN_STP_TYPE, "STP type TLV"}, + { VTP_VLAN_PARENT_VLAN, "Parent VLAN TLV"}, + { VTP_VLAN_TRANS_BRIDGED_VLAN, "Translationally bridged VLANs TLV"}, + { VTP_VLAN_PRUNING, "Pruning TLV"}, + { VTP_VLAN_BRIDGE_TYPE, "Bridge Type TLV"}, + { VTP_VLAN_ARP_HOP_COUNT, "Max ARP Hop Count TLV"}, + { VTP_VLAN_STE_HOP_COUNT, "Max STE Hop Count TLV"}, + { VTP_VLAN_BACKUP_CRF_MODE, "Backup CRF Mode TLV"}, + { 0, NULL } +}; + +static struct tok vtp_stp_type_values[] = { + { 1, "SRT"}, + { 2, "SRB"}, + { 3, "Auto"}, + { 0, NULL } +}; + +void +vtp_print (const u_char *pptr, u_int length) +{ + int type, len, tlv_len, tlv_value; + const u_char *tptr; + const struct vtp_vlan_ *vtp_vlan; + + if (length < VTP_HEADER_LEN) + goto trunc; + + tptr = pptr; + + if (!TTEST2(*tptr, VTP_HEADER_LEN)) + goto trunc; + + type = *(tptr+1); + printf("VTPv%u, Message %s (0x%02x), length %u", + *tptr, + tok2str(vtp_message_type_values,"Unknown message type", type), + *(tptr+1), + length); + + /* In non-verbose mode, just print version and message type */ + if (vflag < 1) { + return; + } + + /* verbose mode print all fields */ + printf("\n\tDomain name: %s, %s: %u", + (tptr+4), + tok2str(vtp_header_values,"Unknown",*(tptr+1)), + *(tptr+2)); + + tptr += VTP_HEADER_LEN; + + switch (type) { + + case VTP_SUMMARY_ADV: + + /* + * SUMMARY ADVERTISEMENT + * + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Version | Code | Followers | MmgtD Len | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Management Domain Name | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Configuration revision number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Updater Identity IP address | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Update Timestamp (12 bytes) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | MD5 digest (16 bytes) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + + printf("\n\t Config Rev %x, Updater %s", + EXTRACT_32BITS(tptr), + ipaddr_string(tptr+4)); + tptr += 8; + printf(", Timestamp 0x%08x 0x%08x 0x%08x", + EXTRACT_32BITS(tptr), + EXTRACT_32BITS(tptr + 4), + EXTRACT_32BITS(tptr + 8)); + tptr += VTP_UPDATE_TIMESTAMP_LEN; + printf(", MD5 digest: %08x%08x%08x%08x", + EXTRACT_32BITS(tptr), + EXTRACT_32BITS(tptr + 4), + EXTRACT_32BITS(tptr + 8), + EXTRACT_32BITS(tptr + 12)); + tptr += VTP_MD5_DIGEST_LEN; + break; + + case VTP_SUBSET_ADV: + + /* + * SUBSET ADVERTISEMENT + * + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Version | Code | Seq number | MmgtD Len | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Management Domain Name | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Configuration revision number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | VLAN info field 1 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ................ | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | VLAN info field N | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + + printf(", Config Rev %x", EXTRACT_32BITS(tptr)); + + /* + * VLAN INFORMATION + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | V info len | Status | VLAN type | VLAN name len | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | ISL vlan id | MTU size | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 802.10 index (SAID) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | VLAN name | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + + tptr += 4; + while (tptr < (pptr+length)) { + + len = *tptr; + if (len == 0) + break; + + if (!TTEST2(*tptr, len)) + goto trunc; + + vtp_vlan = (struct vtp_vlan_*)tptr; + printf("\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name %s", + tok2str(vtp_vlan_status,"Unknown",vtp_vlan->status), + tok2str(vtp_vlan_type_values,"Unknown",vtp_vlan->type), + EXTRACT_16BITS(&vtp_vlan->vlanid), + EXTRACT_16BITS(&vtp_vlan->mtu), + EXTRACT_32BITS(&vtp_vlan->index), + (tptr + VTP_VLAN_INFO_OFFSET)); + + /* + * Vlan names are aligned to 32-bit boundaries. + */ + len -= VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4); + tptr += VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4); + + /* TLV information follows */ + + while (len > 0) { + + /* + * Cisco specs says 2 bytes for type + 2 bytes for length, take only 1 + * See: http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm + */ + type = *tptr; + tlv_len = *(tptr+1); + + printf("\n\t\t%s (0x%04x) TLV", + tok2str(vtp_vlan_tlv_values, "Unknown", type), + type); + + /* + * infinite loop check + */ + if (type == 0 || tlv_len == 0) { + return; + } + + if (!TTEST2(*tptr, tlv_len*2 +2)) + goto trunc; + + tlv_value = EXTRACT_16BITS(tptr+2); + + switch (type) { + case VTP_VLAN_STE_HOP_COUNT: + printf(", %u", tlv_value); + break; + + case VTP_VLAN_PRUNING: + printf(", %s (%u)", + tlv_value == 1 ? "Enabled" : "Disabled", + tlv_value); + break; + + case VTP_VLAN_STP_TYPE: + printf(", %s (%u)", + tok2str(vtp_stp_type_values, "Unknown", tlv_value), + tlv_value); + break; + + case VTP_VLAN_BRIDGE_TYPE: + printf(", %s (%u)", + tlv_value == 1 ? "SRB" : "SRT", + tlv_value); + break; + + case VTP_VLAN_BACKUP_CRF_MODE: + printf(", %s (%u)", + tlv_value == 1 ? "Backup" : "Not backup", + tlv_value); + break; + + /* + * FIXME those are the defined TLVs that lack a decoder + * you are welcome to contribute code ;-) + */ + + case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER: + case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER: + case VTP_VLAN_PARENT_VLAN: + case VTP_VLAN_TRANS_BRIDGED_VLAN: + case VTP_VLAN_ARP_HOP_COUNT: + default: + print_unknown_data(tptr, "\n\t\t ", 2 + tlv_len*2); + break; + } + len -= 2 + tlv_len*2; + tptr += 2 + tlv_len*2; + } + } + break; + + case VTP_ADV_REQUEST: + + /* + * ADVERTISEMENT REQUEST + * + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Version | Code | Reserved | MmgtD Len | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Management Domain Name | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Start value | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + + printf("\n\tStart value: %u", EXTRACT_32BITS(tptr)); + break; + + case VTP_JOIN_MESSAGE: + + /* FIXME - Could not find message format */ + break; + + default: + break; + } + + return; + + trunc: + printf("[|vtp]"); +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/print-wb.c b/print-wb.c new file mode 100644 index 0000000..3ae604f --- /dev/null +++ b/print-wb.c @@ -0,0 +1,444 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-wb.c,v 1.33 2004-03-24 04:06:28 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "interface.h" +#include "addrtoname.h" +#include "extract.h" + +/* XXX need to add byte-swapping macros! */ +/* XXX - you mean like the ones in "extract.h"? */ + +/* + * Largest packet size. Everything should fit within this space. + * For instance, multiline objects are sent piecewise. + */ +#define MAXFRAMESIZE 1024 + +/* + * Multiple drawing ops can be sent in one packet. Each one starts on a + * an even multiple of DOP_ALIGN bytes, which must be a power of two. + */ +#define DOP_ALIGN 4 +#define DOP_ROUNDUP(x) ((((int)(x)) + (DOP_ALIGN - 1)) & ~(DOP_ALIGN - 1)) +#define DOP_NEXT(d)\ + ((struct dophdr *)((u_char *)(d) + \ + DOP_ROUNDUP(EXTRACT_16BITS(&(d)->dh_len) + sizeof(*(d))))) + +/* + * Format of the whiteboard packet header. + * The transport level header. + */ +struct pkt_hdr { + u_int32_t ph_src; /* site id of source */ + u_int32_t ph_ts; /* time stamp (for skew computation) */ + u_int16_t ph_version; /* version number */ + u_char ph_type; /* message type */ + u_char ph_flags; /* message flags */ +}; + +/* Packet types */ +#define PT_DRAWOP 0 /* drawing operation */ +#define PT_ID 1 /* announcement packet */ +#define PT_RREQ 2 /* repair request */ +#define PT_RREP 3 /* repair reply */ +#define PT_KILL 4 /* terminate participation */ +#define PT_PREQ 5 /* page vector request */ +#define PT_PREP 7 /* page vector reply */ + +#ifdef PF_USER +#undef PF_USER /* {Digital,Tru64} UNIX define this, alas */ +#endif + +/* flags */ +#define PF_USER 0x01 /* hint that packet has interactive data */ +#define PF_VIS 0x02 /* only visible ops wanted */ + +struct PageID { + u_int32_t p_sid; /* session id of initiator */ + u_int32_t p_uid; /* page number */ +}; + +struct dophdr { + u_int32_t dh_ts; /* sender's timestamp */ + u_int16_t dh_len; /* body length */ + u_char dh_flags; + u_char dh_type; /* body type */ + /* body follows */ +}; +/* + * Drawing op sub-types. + */ +#define DT_RECT 2 +#define DT_LINE 3 +#define DT_ML 4 +#define DT_DEL 5 +#define DT_XFORM 6 +#define DT_ELL 7 +#define DT_CHAR 8 +#define DT_STR 9 +#define DT_NOP 10 +#define DT_PSCODE 11 +#define DT_PSCOMP 12 +#define DT_REF 13 +#define DT_SKIP 14 +#define DT_HOLE 15 +#define DT_MAXTYPE 15 + +/* + * A drawing operation. + */ +struct pkt_dop { + struct PageID pd_page; /* page that operations apply to */ + u_int32_t pd_sseq; /* start sequence number */ + u_int32_t pd_eseq; /* end sequence number */ + /* drawing ops follow */ +}; + +/* + * A repair request. + */ +struct pkt_rreq { + u_int32_t pr_id; /* source id of drawops to be repaired */ + struct PageID pr_page; /* page of drawops */ + u_int32_t pr_sseq; /* start seqno */ + u_int32_t pr_eseq; /* end seqno */ +}; + +/* + * A repair reply. + */ +struct pkt_rrep { + u_int32_t pr_id; /* original site id of ops */ + struct pkt_dop pr_dop; + /* drawing ops follow */ +}; + +struct id_off { + u_int32_t id; + u_int32_t off; +}; + +struct pgstate { + u_int32_t slot; + struct PageID page; + u_int16_t nid; + u_int16_t rsvd; + /* seqptr's */ +}; + +/* + * An announcement packet. + */ +struct pkt_id { + u_int32_t pi_mslot; + struct PageID pi_mpage; /* current page */ + struct pgstate pi_ps; + /* seqptr's */ + /* null-terminated site name */ +}; + +struct pkt_preq { + struct PageID pp_page; + u_int32_t pp_low; + u_int32_t pp_high; +}; + +struct pkt_prep { + u_int32_t pp_n; /* size of pageid array */ + /* pgstate's follow */ +}; + +static int +wb_id(const struct pkt_id *id, u_int len) +{ + int i; + const char *cp; + const struct id_off *io; + char c; + int nid; + + printf(" wb-id:"); + if (len < sizeof(*id) || (u_char *)(id + 1) > snapend) + return (-1); + len -= sizeof(*id); + + printf(" %u/%s:%u (max %u/%s:%u) ", + EXTRACT_32BITS(&id->pi_ps.slot), + ipaddr_string(&id->pi_ps.page.p_sid), + EXTRACT_32BITS(&id->pi_ps.page.p_uid), + EXTRACT_32BITS(&id->pi_mslot), + ipaddr_string(&id->pi_mpage.p_sid), + EXTRACT_32BITS(&id->pi_mpage.p_uid)); + + nid = EXTRACT_16BITS(&id->pi_ps.nid); + len -= sizeof(*io) * nid; + io = (struct id_off *)(id + 1); + cp = (char *)(io + nid); + if ((u_char *)cp + len <= snapend) { + putchar('"'); + (void)fn_print((u_char *)cp, (u_char *)cp + len); + putchar('"'); + } + + c = '<'; + for (i = 0; i < nid && (u_char *)(io + 1) <= snapend; ++io, ++i) { + printf("%c%s:%u", + c, ipaddr_string(&io->id), EXTRACT_32BITS(&io->off)); + c = ','; + } + if (i >= nid) { + printf(">"); + return (0); + } + return (-1); +} + +static int +wb_rreq(const struct pkt_rreq *rreq, u_int len) +{ + printf(" wb-rreq:"); + if (len < sizeof(*rreq) || (u_char *)(rreq + 1) > snapend) + return (-1); + + printf(" please repair %s %s:%u<%u:%u>", + ipaddr_string(&rreq->pr_id), + ipaddr_string(&rreq->pr_page.p_sid), + EXTRACT_32BITS(&rreq->pr_page.p_uid), + EXTRACT_32BITS(&rreq->pr_sseq), + EXTRACT_32BITS(&rreq->pr_eseq)); + return (0); +} + +static int +wb_preq(const struct pkt_preq *preq, u_int len) +{ + printf(" wb-preq:"); + if (len < sizeof(*preq) || (u_char *)(preq + 1) > snapend) + return (-1); + + printf(" need %u/%s:%u", + EXTRACT_32BITS(&preq->pp_low), + ipaddr_string(&preq->pp_page.p_sid), + EXTRACT_32BITS(&preq->pp_page.p_uid)); + return (0); +} + +static int +wb_prep(const struct pkt_prep *prep, u_int len) +{ + int n; + const struct pgstate *ps; + const u_char *ep = snapend; + + printf(" wb-prep:"); + if (len < sizeof(*prep)) { + return (-1); + } + n = EXTRACT_32BITS(&prep->pp_n); + ps = (const struct pgstate *)(prep + 1); + while (--n >= 0 && (u_char *)(ps + 1) <= ep) { + const struct id_off *io, *ie; + char c = '<'; + + printf(" %u/%s:%u", + EXTRACT_32BITS(&ps->slot), + ipaddr_string(&ps->page.p_sid), + EXTRACT_32BITS(&ps->page.p_uid)); + io = (struct id_off *)(ps + 1); + for (ie = io + ps->nid; io < ie && (u_char *)(io + 1) <= ep; ++io) { + printf("%c%s:%u", c, ipaddr_string(&io->id), + EXTRACT_32BITS(&io->off)); + c = ','; + } + printf(">"); + ps = (struct pgstate *)io; + } + return ((u_char *)ps <= ep? 0 : -1); +} + + +const char *dopstr[] = { + "dop-0!", + "dop-1!", + "RECT", + "LINE", + "ML", + "DEL", + "XFORM", + "ELL", + "CHAR", + "STR", + "NOP", + "PSCODE", + "PSCOMP", + "REF", + "SKIP", + "HOLE", +}; + +static int +wb_dops(const struct dophdr *dh, u_int32_t ss, u_int32_t es) +{ + printf(" <"); + for ( ; ss <= es; ++ss) { + register int t = dh->dh_type; + + if (t > DT_MAXTYPE) + printf(" dop-%d!", t); + else { + printf(" %s", dopstr[t]); + if (t == DT_SKIP || t == DT_HOLE) { + u_int32_t ts = EXTRACT_32BITS(&dh->dh_ts); + printf("%d", ts - ss + 1); + if (ss > ts || ts > es) { + printf("[|]"); + if (ts < ss) + return (0); + } + ss = ts; + } + } + dh = DOP_NEXT(dh); + if ((u_char *)dh > snapend) { + printf("[|wb]"); + break; + } + } + printf(" >"); + return (0); +} + +static int +wb_rrep(const struct pkt_rrep *rrep, u_int len) +{ + const struct pkt_dop *dop = &rrep->pr_dop; + + printf(" wb-rrep:"); + if (len < sizeof(*rrep) || (u_char *)(rrep + 1) > snapend) + return (-1); + len -= sizeof(*rrep); + + printf(" for %s %s:%u<%u:%u>", + ipaddr_string(&rrep->pr_id), + ipaddr_string(&dop->pd_page.p_sid), + EXTRACT_32BITS(&dop->pd_page.p_uid), + EXTRACT_32BITS(&dop->pd_sseq), + EXTRACT_32BITS(&dop->pd_eseq)); + + if (vflag) + return (wb_dops((const struct dophdr *)(dop + 1), + EXTRACT_32BITS(&dop->pd_sseq), + EXTRACT_32BITS(&dop->pd_eseq))); + return (0); +} + +static int +wb_drawop(const struct pkt_dop *dop, u_int len) +{ + printf(" wb-dop:"); + if (len < sizeof(*dop) || (u_char *)(dop + 1) > snapend) + return (-1); + len -= sizeof(*dop); + + printf(" %s:%u<%u:%u>", + ipaddr_string(&dop->pd_page.p_sid), + EXTRACT_32BITS(&dop->pd_page.p_uid), + EXTRACT_32BITS(&dop->pd_sseq), + EXTRACT_32BITS(&dop->pd_eseq)); + + if (vflag) + return (wb_dops((const struct dophdr *)(dop + 1), + EXTRACT_32BITS(&dop->pd_sseq), + EXTRACT_32BITS(&dop->pd_eseq))); + return (0); +} + +/* + * Print whiteboard multicast packets. + */ +void +wb_print(register const void *hdr, register u_int len) +{ + register const struct pkt_hdr *ph; + + ph = (const struct pkt_hdr *)hdr; + if (len < sizeof(*ph) || (u_char *)(ph + 1) > snapend) { + printf("[|wb]"); + return; + } + len -= sizeof(*ph); + + if (ph->ph_flags) + printf("*"); + switch (ph->ph_type) { + + case PT_KILL: + printf(" wb-kill"); + return; + + case PT_ID: + if (wb_id((struct pkt_id *)(ph + 1), len) >= 0) + return; + break; + + case PT_RREQ: + if (wb_rreq((struct pkt_rreq *)(ph + 1), len) >= 0) + return; + break; + + case PT_RREP: + if (wb_rrep((struct pkt_rrep *)(ph + 1), len) >= 0) + return; + break; + + case PT_DRAWOP: + if (wb_drawop((struct pkt_dop *)(ph + 1), len) >= 0) + return; + break; + + case PT_PREQ: + if (wb_preq((struct pkt_preq *)(ph + 1), len) >= 0) + return; + break; + + case PT_PREP: + if (wb_prep((struct pkt_prep *)(ph + 1), len) >= 0) + return; + break; + + default: + printf(" wb-%d!", ph->ph_type); + return; + } +} diff --git a/print-zephyr.c b/print-zephyr.c new file mode 100644 index 0000000..7c52e65 --- /dev/null +++ b/print-zephyr.c @@ -0,0 +1,322 @@ +/* + * Decode and print Zephyr packets. + * + * http://web.mit.edu/zephyr/doc/protocol + * + * Copyright (c) 2001 Nickolai Zeldovich + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * The name of the author(s) may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-zephyr.c,v 1.10 2007-08-09 18:47:27 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" + +struct z_packet { + char *version; + int numfields; + int kind; + char *uid; + int port; + int auth; + int authlen; + char *authdata; + char *class; + char *inst; + char *opcode; + char *sender; + const char *recipient; + char *format; + int cksum; + int multi; + char *multi_uid; + /* Other fields follow here.. */ +}; + +enum z_packet_type { + Z_PACKET_UNSAFE = 0, + Z_PACKET_UNACKED, + Z_PACKET_ACKED, + Z_PACKET_HMACK, + Z_PACKET_HMCTL, + Z_PACKET_SERVACK, + Z_PACKET_SERVNAK, + Z_PACKET_CLIENTACK, + Z_PACKET_STAT +}; + +static struct tok z_types[] = { + { Z_PACKET_UNSAFE, "unsafe" }, + { Z_PACKET_UNACKED, "unacked" }, + { Z_PACKET_ACKED, "acked" }, + { Z_PACKET_HMACK, "hm-ack" }, + { Z_PACKET_HMCTL, "hm-ctl" }, + { Z_PACKET_SERVACK, "serv-ack" }, + { Z_PACKET_SERVNAK, "serv-nak" }, + { Z_PACKET_CLIENTACK, "client-ack" }, + { Z_PACKET_STAT, "stat" } +}; + +char z_buf[256]; + +static char * +parse_field(char **pptr, int *len) +{ + char *s; + + if (*len <= 0 || !pptr || !*pptr) + return NULL; + if (*pptr > (char *) snapend) + return NULL; + + s = *pptr; + while (*pptr <= (char *) snapend && *len >= 0 && **pptr) { + (*pptr)++; + (*len)--; + } + (*pptr)++; + (*len)--; + if (*len < 0 || *pptr > (char *) snapend) + return NULL; + return s; +} + +static const char * +z_triple(char *class, char *inst, const char *recipient) +{ + if (!*recipient) + recipient = "*"; + snprintf(z_buf, sizeof(z_buf), "<%s,%s,%s>", class, inst, recipient); + z_buf[sizeof(z_buf)-1] = '\0'; + return z_buf; +} + +static const char * +str_to_lower(char *string) +{ + strncpy(z_buf, string, sizeof(z_buf)); + z_buf[sizeof(z_buf)-1] = '\0'; + + string = z_buf; + while (*string) { + *string = tolower((unsigned char)(*string)); + string++; + } + + return z_buf; +} + +void +zephyr_print(const u_char *cp, int length) +{ + struct z_packet z; + char *parse = (char *) cp; + int parselen = length; + char *s; + int lose = 0; + + /* squelch compiler warnings */ + + z.kind = 0; + z.class = 0; + z.inst = 0; + z.opcode = 0; + z.sender = 0; + z.recipient = 0; + +#define PARSE_STRING \ + s = parse_field(&parse, &parselen); \ + if (!s) lose = 1; + +#define PARSE_FIELD_INT(field) \ + PARSE_STRING \ + if (!lose) field = strtol(s, 0, 16); + +#define PARSE_FIELD_STR(field) \ + PARSE_STRING \ + if (!lose) field = s; + + PARSE_FIELD_STR(z.version); + if (lose) return; + if (strncmp(z.version, "ZEPH", 4)) + return; + + PARSE_FIELD_INT(z.numfields); + PARSE_FIELD_INT(z.kind); + PARSE_FIELD_STR(z.uid); + PARSE_FIELD_INT(z.port); + PARSE_FIELD_INT(z.auth); + PARSE_FIELD_INT(z.authlen); + PARSE_FIELD_STR(z.authdata); + PARSE_FIELD_STR(z.class); + PARSE_FIELD_STR(z.inst); + PARSE_FIELD_STR(z.opcode); + PARSE_FIELD_STR(z.sender); + PARSE_FIELD_STR(z.recipient); + PARSE_FIELD_STR(z.format); + PARSE_FIELD_INT(z.cksum); + PARSE_FIELD_INT(z.multi); + PARSE_FIELD_STR(z.multi_uid); + + if (lose) { + printf(" [|zephyr] (%d)", length); + return; + } + + printf(" zephyr"); + if (strncmp(z.version+4, "0.2", 3)) { + printf(" v%s", z.version+4); + return; + } + + printf(" %s", tok2str(z_types, "type %d", z.kind)); + if (z.kind == Z_PACKET_SERVACK) { + /* Initialization to silence warnings */ + char *ackdata = NULL; + PARSE_FIELD_STR(ackdata); + if (!lose && strcmp(ackdata, "SENT")) + printf("/%s", str_to_lower(ackdata)); + } + if (*z.sender) printf(" %s", z.sender); + + if (!strcmp(z.class, "USER_LOCATE")) { + if (!strcmp(z.opcode, "USER_HIDE")) + printf(" hide"); + else if (!strcmp(z.opcode, "USER_UNHIDE")) + printf(" unhide"); + else + printf(" locate %s", z.inst); + return; + } + + if (!strcmp(z.class, "ZEPHYR_ADMIN")) { + printf(" zephyr-admin %s", str_to_lower(z.opcode)); + return; + } + + if (!strcmp(z.class, "ZEPHYR_CTL")) { + if (!strcmp(z.inst, "CLIENT")) { + if (!strcmp(z.opcode, "SUBSCRIBE") || + !strcmp(z.opcode, "SUBSCRIBE_NODEFS") || + !strcmp(z.opcode, "UNSUBSCRIBE")) { + + printf(" %ssub%s", strcmp(z.opcode, "SUBSCRIBE") ? "un" : "", + strcmp(z.opcode, "SUBSCRIBE_NODEFS") ? "" : + "-nodefs"); + if (z.kind != Z_PACKET_SERVACK) { + /* Initialization to silence warnings */ + char *c = NULL, *i = NULL, *r = NULL; + PARSE_FIELD_STR(c); + PARSE_FIELD_STR(i); + PARSE_FIELD_STR(r); + if (!lose) printf(" %s", z_triple(c, i, r)); + } + return; + } + + if (!strcmp(z.opcode, "GIMME")) { + printf(" ret"); + return; + } + + if (!strcmp(z.opcode, "GIMMEDEFS")) { + printf(" gimme-defs"); + return; + } + + if (!strcmp(z.opcode, "CLEARSUB")) { + printf(" clear-subs"); + return; + } + + printf(" %s", str_to_lower(z.opcode)); + return; + } + + if (!strcmp(z.inst, "HM")) { + printf(" %s", str_to_lower(z.opcode)); + return; + } + + if (!strcmp(z.inst, "REALM")) { + if (!strcmp(z.opcode, "ADD_SUBSCRIBE")) + printf(" realm add-subs"); + if (!strcmp(z.opcode, "REQ_SUBSCRIBE")) + printf(" realm req-subs"); + if (!strcmp(z.opcode, "RLM_SUBSCRIBE")) + printf(" realm rlm-sub"); + if (!strcmp(z.opcode, "RLM_UNSUBSCRIBE")) + printf(" realm rlm-unsub"); + return; + } + } + + if (!strcmp(z.class, "HM_CTL")) { + printf(" hm_ctl %s", str_to_lower(z.inst)); + printf(" %s", str_to_lower(z.opcode)); + return; + } + + if (!strcmp(z.class, "HM_STAT")) { + if (!strcmp(z.inst, "HMST_CLIENT") && !strcmp(z.opcode, "GIMMESTATS")) { + printf(" get-client-stats"); + return; + } + } + + if (!strcmp(z.class, "WG_CTL")) { + printf(" wg_ctl %s", str_to_lower(z.inst)); + printf(" %s", str_to_lower(z.opcode)); + return; + } + + if (!strcmp(z.class, "LOGIN")) { + if (!strcmp(z.opcode, "USER_FLUSH")) { + printf(" flush_locs"); + return; + } + + if (!strcmp(z.opcode, "NONE") || + !strcmp(z.opcode, "OPSTAFF") || + !strcmp(z.opcode, "REALM-VISIBLE") || + !strcmp(z.opcode, "REALM-ANNOUNCED") || + !strcmp(z.opcode, "NET-VISIBLE") || + !strcmp(z.opcode, "NET-ANNOUNCED")) { + printf(" set-exposure %s", str_to_lower(z.opcode)); + return; + } + } + + if (!*z.recipient) + z.recipient = "*"; + + printf(" to %s", z_triple(z.class, z.inst, z.recipient)); + if (*z.opcode) + printf(" op %s", z.opcode); + return; +} diff --git a/route6d.h b/route6d.h new file mode 100644 index 0000000..53953fd --- /dev/null +++ b/route6d.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 1995, 1996, 1997 and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * $Header: /tcpdump/master/tcpdump/route6d.h,v 1.5 2002-12-11 07:14:10 guy Exp $ + */ + +#define RIP6_VERSION 1 + +#define RIP6_REQUEST 1 +#define RIP6_RESPONSE 2 + +struct netinfo6 { + struct in6_addr rip6_dest; + u_int16_t rip6_tag; + u_int8_t rip6_plen; + u_int8_t rip6_metric; +}; + +struct rip6 { + u_int8_t rip6_cmd; + u_int8_t rip6_vers; + u_int8_t rip6_res1[2]; + union { + struct netinfo6 ru6_nets[1]; + char ru6_tracefile[1]; + } rip6un; +#define rip6_nets rip6un.ru6_nets +#define rip6_tracefile rip6un.ru6_tracefile +}; + +#define HOPCNT_INFINITY6 16 +#define MAXRTE 24 +#define NEXTHOP_METRIC 0xff + +#ifndef DEBUG +#define SUPPLY_INTERVAL6 30 +#define RIP_LIFETIME 180 +#define RIP_HOLDDOWN 120 +#define RIP_TRIG_INTERVAL6 5 +#define RIP_TRIG_INTERVAL6_MIN 1 +#else +/* only for debugging; can not wait for 30sec to appear a bug */ +#define SUPPLY_INTERVAL6 10 +#define RIP_LIFETIME 60 +#define RIP_HOLDDOWN 40 +#define RIP_TRIG_INTERVAL6 5 +#define RIP_TRIG_INTERVAL6_MIN 1 +#endif + +#define RIP6_PORT 521 +#define RIP6_DEST "ff02::9" diff --git a/rpc_auth.h b/rpc_auth.h new file mode 100644 index 0000000..fe9a40b --- /dev/null +++ b/rpc_auth.h @@ -0,0 +1,79 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/rpc_auth.h,v 1.2 2005-04-27 21:43:48 guy Exp $ (LBL) */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)auth.h 1.17 88/02/08 SMI + * from: @(#)auth.h 2.3 88/08/07 4.0 RPCSRC + * $FreeBSD: src/include/rpc/auth.h,v 1.14.2.1 1999/08/29 14:39:02 peter Exp $ + */ + +/* + * auth.h, Authentication interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The data structures are completely opaque to the client. The client + * is required to pass a AUTH * to routines that create rpc + * "sessions". + */ + +/* + * Status returned from authentication check + */ +enum sunrpc_auth_stat { + SUNRPC_AUTH_OK=0, + /* + * failed at remote end + */ + SUNRPC_AUTH_BADCRED=1, /* bogus credentials (seal broken) */ + SUNRPC_AUTH_REJECTEDCRED=2, /* client should begin new session */ + SUNRPC_AUTH_BADVERF=3, /* bogus verifier (seal broken) */ + SUNRPC_AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */ + SUNRPC_AUTH_TOOWEAK=5, /* rejected due to security reasons */ + /* + * failed locally + */ + SUNRPC_AUTH_INVALIDRESP=6, /* bogus response verifier */ + SUNRPC_AUTH_FAILED=7 /* some unknown reason */ +}; + +/* + * Authentication info. Opaque to client. + */ +struct sunrpc_opaque_auth { + u_int32_t oa_flavor; /* flavor of auth */ + u_int32_t oa_len; /* length of opaque body */ + /* zero or more bytes of body */ +}; + +#define SUNRPC_AUTH_NONE 0 /* no authentication */ +#define SUNRPC_AUTH_NULL 0 /* backward compatibility */ +#define SUNRPC_AUTH_UNIX 1 /* unix style (uid, gids) */ +#define SUNRPC_AUTH_SYS 1 /* forward compatibility */ +#define SUNRPC_AUTH_SHORT 2 /* short hand unix style */ +#define SUNRPC_AUTH_DES 3 /* des style (encrypted timestamps) */ diff --git a/rpc_msg.h b/rpc_msg.h new file mode 100644 index 0000000..3e79ac7 --- /dev/null +++ b/rpc_msg.h @@ -0,0 +1,128 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/rpc_msg.h,v 1.2 2005-04-27 21:43:48 guy Exp $ (LBL) */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)rpc_msg.h 1.7 86/07/16 SMI + * from: @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD: src/include/rpc/rpc_msg.h,v 1.11.2.1 1999/08/29 14:39:07 peter Exp $ + */ + +/* + * rpc_msg.h + * rpc message definition + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#define SUNRPC_MSG_VERSION ((u_int32_t) 2) + +/* + * Bottom up definition of an rpc message. + * NOTE: call and reply use the same overall stuct but + * different parts of unions within it. + */ + +enum sunrpc_msg_type { + SUNRPC_CALL=0, + SUNRPC_REPLY=1 +}; + +enum sunrpc_reply_stat { + SUNRPC_MSG_ACCEPTED=0, + SUNRPC_MSG_DENIED=1 +}; + +enum sunrpc_accept_stat { + SUNRPC_SUCCESS=0, + SUNRPC_PROG_UNAVAIL=1, + SUNRPC_PROG_MISMATCH=2, + SUNRPC_PROC_UNAVAIL=3, + SUNRPC_GARBAGE_ARGS=4, + SUNRPC_SYSTEM_ERR=5 +}; + +enum sunrpc_reject_stat { + SUNRPC_RPC_MISMATCH=0, + SUNRPC_AUTH_ERROR=1 +}; + +/* + * Reply part of an rpc exchange + */ + +/* + * Reply to an rpc request that was rejected by the server. + */ +struct sunrpc_rejected_reply { + u_int32_t rj_stat; /* enum reject_stat */ + union { + struct { + u_int32_t low; + u_int32_t high; + } RJ_versions; + u_int32_t RJ_why; /* enum auth_stat - why authentication did not work */ + } ru; +#define rj_vers ru.RJ_versions +#define rj_why ru.RJ_why +}; + +/* + * Body of a reply to an rpc request. + */ +struct sunrpc_reply_body { + u_int32_t rp_stat; /* enum reply_stat */ + struct sunrpc_rejected_reply rp_reject; /* if rejected */ +}; + +/* + * Body of an rpc request call. + */ +struct sunrpc_call_body { + u_int32_t cb_rpcvers; /* must be equal to two */ + u_int32_t cb_prog; + u_int32_t cb_vers; + u_int32_t cb_proc; + struct sunrpc_opaque_auth cb_cred; + /* followed by opaque verifier */ +}; + +/* + * The rpc message + */ +struct sunrpc_msg { + u_int32_t rm_xid; + u_int32_t rm_direction; /* enum msg_type */ + union { + struct sunrpc_call_body RM_cmb; + struct sunrpc_reply_body RM_rmb; + } ru; +#define rm_call ru.RM_cmb +#define rm_reply ru.RM_rmb +}; +#define acpted_rply ru.RM_rmb.ru.RP_ar +#define rjcted_rply ru.RM_rmb.ru.RP_dr diff --git a/rx.h b/rx.h new file mode 100644 index 0000000..b79dd30 --- /dev/null +++ b/rx.h @@ -0,0 +1,113 @@ +/* + * Copyright: (c) 2000 United States Government as represented by the + * Secretary of the Navy. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +/* + * Rx protocol format + * + * $Id: rx.h,v 1.8 2002-12-11 07:14:11 guy Exp $ + */ + +#define FS_RX_PORT 7000 +#define CB_RX_PORT 7001 +#define PROT_RX_PORT 7002 +#define VLDB_RX_PORT 7003 +#define KAUTH_RX_PORT 7004 +#define VOL_RX_PORT 7005 +#define ERROR_RX_PORT 7006 /* Doesn't seem to be used */ +#define BOS_RX_PORT 7007 + +#ifndef AFSNAMEMAX +#define AFSNAMEMAX 256 +#endif + +#ifndef AFSOPAQUEMAX +#define AFSOPAQUEMAX 1024 +#endif + +#define PRNAMEMAX 64 +#define VLNAMEMAX 65 +#define KANAMEMAX 64 +#define BOSNAMEMAX 256 + +#define PRSFS_READ 1 /* Read files */ +#define PRSFS_WRITE 2 /* Write files */ +#define PRSFS_INSERT 4 /* Insert files into a directory */ +#define PRSFS_LOOKUP 8 /* Lookup files into a directory */ +#define PRSFS_DELETE 16 /* Delete files */ +#define PRSFS_LOCK 32 /* Lock files */ +#define PRSFS_ADMINISTER 64 /* Change ACL's */ + +struct rx_header { + u_int32_t epoch; + u_int32_t cid; + u_int32_t callNumber; + u_int32_t seq; + u_int32_t serial; + u_int8_t type; +#define RX_PACKET_TYPE_DATA 1 +#define RX_PACKET_TYPE_ACK 2 +#define RX_PACKET_TYPE_BUSY 3 +#define RX_PACKET_TYPE_ABORT 4 +#define RX_PACKET_TYPE_ACKALL 5 +#define RX_PACKET_TYPE_CHALLENGE 6 +#define RX_PACKET_TYPE_RESPONSE 7 +#define RX_PACKET_TYPE_DEBUG 8 +#define RX_PACKET_TYPE_PARAMS 9 +#define RX_PACKET_TYPE_VERSION 13 + u_int8_t flags; +#define RX_CLIENT_INITIATED 1 +#define RX_REQUEST_ACK 2 +#define RX_LAST_PACKET 4 +#define RX_MORE_PACKETS 8 +#define RX_FREE_PACKET 16 +#define RX_SLOW_START_OK 32 +#define RX_JUMBO_PACKET 32 + u_int8_t userStatus; + u_int8_t securityIndex; + u_int16_t spare; /* How clever: even though the AFS */ + u_int16_t serviceId; /* header files indicate that the */ +}; /* serviceId is first, it's really */ + /* encoded _after_ the spare field */ + /* I wasted a day figuring that out! */ + +#define NUM_RX_FLAGS 7 + +#define RX_MAXACKS 255 + +struct rx_ackPacket { + u_int16_t bufferSpace; /* Number of packet buffers available */ + u_int16_t maxSkew; /* Max diff between ack'd packet and */ + /* highest packet received */ + u_int32_t firstPacket; /* The first packet in ack list */ + u_int32_t previousPacket; /* Previous packet recv'd (obsolete) */ + u_int32_t serial; /* # of packet that prompted the ack */ + u_int8_t reason; /* Reason for acknowledgement */ + u_int8_t nAcks; /* Number of acknowledgements */ + u_int8_t acks[RX_MAXACKS]; /* Up to RX_MAXACKS acknowledgements */ +}; + +/* + * Values for the acks array + */ + +#define RX_ACK_TYPE_NACK 0 /* Don't have this packet */ +#define RX_ACK_TYPE_ACK 1 /* I have this packet */ diff --git a/sctpConstants.h b/sctpConstants.h new file mode 100644 index 0000000..ac28a15 --- /dev/null +++ b/sctpConstants.h @@ -0,0 +1,571 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/sctpConstants.h,v 1.4 2003-06-03 23:49:23 guy Exp $ (LBL) */ + +/* SCTP reference Implementation Copyright (C) 1999 Cisco And Motorola + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of Cisco nor of Motorola may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the SCTP reference Implementation + * + * + * Please send any bug reports or fixes you make to one of the following email + * addresses: + * + * rstewar1@email.mot.com + * kmorneau@cisco.com + * qxie1@email.mot.com + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorperated into the next SCTP release. + */ + + +#ifndef __sctpConstants_h__ +#define __sctpConstants_h__ + + + /* If you wish to use MD5 instead of SLA uncomment the line + * below. Why you would like to do this: + * a) There may be IPR on SHA-1, or so the FIP-180-1 page says, + * b) MD5 is 3 times faster (has coded here). + * + * The disadvantage is, it is thought that MD5 has been + * cracked... see RFC2104. + */ +/*#define USE_MD5 1*/ + +/* the SCTP protocol signature + * this includes the version number + * encoded in the last 4 bits of the + * signature. + */ +#define PROTO_SIGNATURE_A 0x30000000 + +#define SCTP_VERSION_NUMBER 0x3 + +#define MAX_TSN 0xffffffff +#define MAX_SEQ 0xffff + +/* option: + * If you comment out the following you will + * receive the old behavior of obeying cwnd for + * the fast retransmit algorithm. With this defined + * a FR happens right away with-out waiting for the + * flightsize to drop below the cwnd value (which + * is reduced by the FR to 1/2 the inflight packets). + */ +#define SCTP_IGNORE_CWND_ON_FR 1 +/* default max I can burst out after a fast retransmit */ +#define SCTP_DEF_MAX_BURST 4 + +/* Packet transmit states in the sent + * field in the SCTP_transmitOnQueue struct + */ +#define SCTP_DATAGRAM_UNSENT 0 +#define SCTP_DATAGRAM_SENT 1 +#define SCTP_DATAGRAM_RESEND1 2 /* not used */ +#define SCTP_DATAGRAM_RESEND2 3 /* not used */ +#define SCTP_DATAGRAM_RESEND3 4 /* not used */ +#define SCTP_DATAGRAM_RESEND 5 +#define SCTP_DATAGRAM_ACKED 10010 +#define SCTP_DATAGRAM_INBOUND 10011 +#define SCTP_READY_TO_TRANSMIT 10012 +#define SCTP_DATAGRAM_MARKED 20010 + +#define MAX_FSID 64 /* debug 5 ints used for cc dynamic tracking */ + +/* The valid defines for all message + * types know to SCTP. 0 is reserved + */ +#define SCTP_MSGTYPE_MASK 0xff + +#define SCTP_DATA 0x00 +#define SCTP_INITIATION 0x01 +#define SCTP_INITIATION_ACK 0x02 +#define SCTP_SELECTIVE_ACK 0x03 +#define SCTP_HEARTBEAT_REQUEST 0x04 +#define SCTP_HEARTBEAT_ACK 0x05 +#define SCTP_ABORT_ASSOCIATION 0x06 +#define SCTP_SHUTDOWN 0x07 +#define SCTP_SHUTDOWN_ACK 0x08 +#define SCTP_OPERATION_ERR 0x09 +#define SCTP_COOKIE_ECHO 0x0a +#define SCTP_COOKIE_ACK 0x0b +#define SCTP_ECN_ECHO 0x0c +#define SCTP_ECN_CWR 0x0d +#define SCTP_SHUTDOWN_COMPLETE 0x0e +#define SCTP_FORWARD_CUM_TSN 0xc0 +#define SCTP_RELIABLE_CNTL 0xc1 +#define SCTP_RELIABLE_CNTL_ACK 0xc2 + +/* ABORT and SHUTDOWN COMPLETE FLAG */ +#define SCTP_HAD_NO_TCB 0x01 + +/* Data Chuck Specific Flags */ +#define SCTP_DATA_FRAG_MASK 0x03 +#define SCTP_DATA_MIDDLE_FRAG 0x00 +#define SCTP_DATA_LAST_FRAG 0x01 +#define SCTP_DATA_FIRST_FRAG 0x02 +#define SCTP_DATA_NOT_FRAG 0x03 +#define SCTP_DATA_UNORDERED 0x04 + +#define SCTP_CRC_ENABLE_BIT 0x01 /* lower bit of reserved */ + +#define isSCTPControl(a) (a->chunkID != SCTP_DATA) +#define isSCTPData(a) (a->chunkID == SCTP_DATA) + +/* sctp parameter types for init/init-ack */ + +#define SCTP_IPV4_PARAM_TYPE 0x0005 +#define SCTP_IPV6_PARAM_TYPE 0x0006 +#define SCTP_RESPONDER_COOKIE 0x0007 +#define SCTP_UNRECOG_PARAM 0x0008 +#define SCTP_COOKIE_PRESERVE 0x0009 +#define SCTP_HOSTNAME_VIA_DNS 0x000b +#define SCTP_RESTRICT_ADDR_TO 0x000c + +#define SCTP_ECN_I_CAN_DO_ECN 0x8000 +#define SCTP_OPERATION_SUCCEED 0x4001 +#define SCTP_ERROR_NOT_EXECUTED 0x4002 + +#define SCTP_UNRELIABLE_STRM 0xc000 +#define SCTP_ADD_IP_ADDRESS 0xc001 +#define SCTP_DEL_IP_ADDRESS 0xc002 +#define SCTP_STRM_FLOW_LIMIT 0xc003 +#define SCTP_PARTIAL_CSUM 0xc004 +#define SCTP_ERROR_CAUSE_TLV 0xc005 +#define SCTP_MIT_STACK_NAME 0xc006 +#define SCTP_SETADDRESS_PRIMARY 0xc007 + +/* bits for TOS field */ +#define SCTP_ECT_BIT 0x02 +#define SCTP_CE_BIT 0x01 + +/* error codes */ +#define SCTP_OP_ERROR_NO_ERROR 0x0000 +#define SCTP_OP_ERROR_INV_STRM 0x0001 +#define SCTP_OP_ERROR_MISS_PARAM 0x0002 +#define SCTP_OP_ERROR_STALE_COOKIE 0x0003 +#define SCTP_OP_ERROR_NO_RESOURCE 0x0004 +#define SCTP_OP_ERROR_DNS_FAILED 0x0005 +#define SCTP_OP_ERROR_UNK_CHUNK 0x0006 +#define SCTP_OP_ERROR_INV_PARAM 0x0007 +#define SCTP_OP_ERROR_UNK_PARAM 0x0008 +#define SCTP_OP_ERROR_NO_USERD 0x0009 +#define SCTP_OP_ERROR_COOKIE_SHUT 0x000a +#define SCTP_OP_ERROR_DELETE_LAST 0x000b +#define SCTP_OP_ERROR_RESOURCE_SHORT 0x000c + +#define SCTP_MAX_ERROR_CAUSE 12 + +/* empty error causes i.e. nothing but the cause + * are SCTP_OP_ERROR_NO_RESOURCE, SCTP_OP_ERROR_INV_PARAM, + * SCTP_OP_ERROR_COOKIE_SHUT. + */ + +/* parameter for Heart Beat */ +#define HEART_BEAT_PARAM 0x0001 + + + +/* send options for SCTP + */ +#define SCTP_ORDERED_DELIVERY 0x01 +#define SCTP_NON_ORDERED_DELIVERY 0x02 +#define SCTP_DO_CRC16 0x08 +#define SCTP_MY_ADDRESS_ONLY 0x10 + +/* below turns off above */ +#define SCTP_FLEXIBLE_ADDRESS 0x20 +#define SCTP_NO_HEARTBEAT 0x40 + +/* mask to get sticky */ +#define SCTP_STICKY_OPTIONS_MASK 0x0c + +/* MTU discovery flags */ +#define SCTP_DONT_FRAGMENT 0x0100 +#define SCTP_FRAGMENT_OK 0x0200 + + +/* SCTP state defines for internal state machine */ +#define SCTP_STATE_EMPTY 0x0000 +#define SCTP_STATE_INUSE 0x0001 +#define SCTP_STATE_COOKIE_WAIT 0x0002 +#define SCTP_STATE_COOKIE_SENT 0x0004 +#define SCTP_STATE_OPEN 0x0008 +#define SCTP_STATE_SHUTDOWN 0x0010 +#define SCTP_STATE_SHUTDOWN_RECV 0x0020 +#define SCTP_STATE_SHUTDOWN_ACK_SENT 0x0040 +#define SCTP_STATE_SHUTDOWN_PEND 0x0080 +#define SCTP_STATE_MASK 0x007f +/* SCTP reachability state for each address */ +#define SCTP_ADDR_NOT_REACHABLE 1 +#define SCTP_ADDR_REACHABLE 2 +#define SCTP_ADDR_NOHB 4 +#define SCTP_ADDR_BEING_DELETED 8 + +/* How long a cookie lives */ +#define SCTP_DEFAULT_COOKIE_LIFE 60 /* seconds */ + +/* resource limit of streams */ +#define MAX_SCTP_STREAMS 2048 + + +/* guess at how big to make the TSN mapping array */ +#define SCTP_STARTING_MAPARRAY 10000 + +/* Here we define the timer types used + * by the implementation has + * arguments in the set/get timer type calls. + */ +#define SCTP_TIMER_INIT 0 +#define SCTP_TIMER_RECV 1 +#define SCTP_TIMER_SEND 2 +#define SCTP_TIMER_SHUTDOWN 3 +#define SCTP_TIMER_HEARTBEAT 4 +#define SCTP_TIMER_PMTU 5 +/* number of timer types in the base SCTP + * structure used in the set/get and has + * the base default. + */ +#define SCTP_NUM_TMRS 6 + + + +#define SCTP_IPV4_ADDRESS 2 +#define SCTP_IPV6_ADDRESS 4 + +/* timer types */ +#define SctpTimerTypeNone 0 +#define SctpTimerTypeSend 1 +#define SctpTimerTypeInit 2 +#define SctpTimerTypeRecv 3 +#define SctpTimerTypeShutdown 4 +#define SctpTimerTypeHeartbeat 5 +#define SctpTimerTypeCookie 6 +#define SctpTimerTypeNewCookie 7 +#define SctpTimerTypePathMtuRaise 8 +#define SctpTimerTypeShutdownAck 9 +#define SctpTimerTypeRelReq 10 + +/* Here are the timer directives given to the + * user provided function + */ +#define SCTP_TIMER_START 1 +#define SCTP_TIMER_STOP 2 + +/* running flag states in timer structure */ +#define SCTP_TIMER_IDLE 0x0 +#define SCTP_TIMER_EXPIRED 0x1 +#define SCTP_TIMER_RUNNING 0x2 + + +/* number of simultaneous timers running */ +#define SCTP_MAX_NET_TIMERS 6 /* base of where net timers start */ +#define SCTP_NUMBER_TIMERS 12 /* allows up to 6 destinations */ + + +/* Of course we really don't collect stale cookies, being + * folks of decerning taste. However we do count them, if + * we get to many before the association comes up.. we + * give up. Below is the constant that dictates when + * we give it up...this is a implemenation dependant + * treatment. In ours we do not ask for a extension of + * time, but just retry this many times... + */ +#define SCTP_MAX_STALE_COOKIES_I_COLLECT 10 + +/* max number of TSN's dup'd that I will hold */ +#define SCTP_MAX_DUP_TSNS 20 + +/* Here we define the types used when + * setting the retry ammounts. + */ +/* constants for type of set */ +#define SCTP_MAXATTEMPT_INIT 2 +#define SCTP_MAXATTEMPT_SEND 3 + +/* Here we define the default timers and the + * default number of attemts we make for + * each respective side (send/init). + */ + +/* init timer def = 3sec */ +#define SCTP_INIT_SEC 3 +#define SCTP_INIT_NSEC 0 + +/* send timer def = 3 seconds */ +#define SCTP_SEND_SEC 1 +#define SCTP_SEND_NSEC 0 + +/* recv timer def = 200ms (in nsec) */ +#define SCTP_RECV_SEC 0 +#define SCTP_RECV_NSEC 200000000 + +/* 30 seconds + RTO */ +#define SCTP_HB_SEC 30 +#define SCTP_HB_NSEC 0 + + +/* 300 ms */ +#define SCTP_SHUTDOWN_SEC 0 +#define SCTP_SHUTDOWN_NSEC 300000000 + +#define SCTP_RTO_UPPER_BOUND 60000000 /* 60 sec in micro-second's */ +#define SCTP_RTO_UPPER_BOUND_SEC 60 /* for the init timer */ +#define SCTP_RTO_LOWER_BOUND 1000000 /* 1 sec in micro-sec's */ + +#define SCTP_DEF_MAX_INIT 8 +#define SCTP_DEF_MAX_SEND 10 + +#define SCTP_DEF_PMTU_RAISE 600 /* 10 Minutes between raise attempts */ +#define SCTP_DEF_PMTU_MIN 600 + +#define SCTP_MSEC_IN_A_SEC 1000 +#define SCTP_USEC_IN_A_SEC 1000000 +#define SCTP_NSEC_IN_A_SEC 1000000000 + + +/* Events that SCTP will look for, these + * are or'd together to declare what SCTP + * wants. Each select mask/poll list should be + * set for the fd, if the bit is on. + */ +#define SCTP_EVENT_READ 0x000001 +#define SCTP_EVENT_WRITE 0x000002 +#define SCTP_EVENT_EXCEPT 0x000004 + +/* The following constant is a value for this + * particular implemenation. It is quite arbitrary and + * is used to limit how much data will be queued up to + * a sender, waiting for cwnd to be larger than flightSize. + * All implementations will need this protection is some + * way due to buffer size constraints. + */ + +#define SCTP_MAX_OUTSTANDING_DG 10000 + + + +/* This constant (SCTP_MAX_READBUFFER) define + * how big the read/write buffer is + * when we enter the fd event notification + * the buffer is put on the stack, so the bigger + * it is the more stack you chew up, however it + * has got to be big enough to handle the bigest + * message this O/S will send you. In solaris + * with sockets (not TLI) we end up at a value + * of 64k. In TLI we could do partial reads to + * get it all in with less hassel.. but we + * write to sockets for generality. + */ +#define SCTP_MAX_READBUFFER 65536 +#define SCTP_ADDRMAX 60 + +/* amount peer is obligated to have in rwnd or + * I will abort + */ +#define SCTP_MIN_RWND 1500 + +#define SCTP_WINDOW_MIN 1500 /* smallest rwnd can be */ +#define SCTP_WINDOW_MAX 1048576 /* biggest I can grow rwnd to + * My playing around suggests a + * value greater than 64k does not + * do much, I guess via the kernel + * limitations on the stream/socket. + */ + +#define SCTP_MAX_BUNDLE_UP 256 /* max number of chunks I can bundle */ + +/* I can handle a 1meg re-assembly */ +#define SCTP_DEFAULT_MAXMSGREASM 1048576 + + +#define SCTP_DEFAULT_MAXWINDOW 32768 /* default rwnd size */ +#define SCTP_DEFAULT_MAXSEGMENT 1500 /* MTU size, this is the default + * to which we set the smallestMTU + * size to. This governs what is the + * largest size we will use, of course + * PMTU will raise this up to + * the largest interface MTU or the + * ceiling below if there is no + * SIOCGIFMTU. + */ +#ifdef LYNX +#define DEFAULT_MTU_CEILING 1500 /* Since Lynx O/S is brain dead + * in the way it handles the + * raw IP socket, insisting + * on makeing its own IP + * header, we limit the growth + * to that of the e-net size + */ +#else +#define DEFAULT_MTU_CEILING 2048 /* If no SIOCGIFMTU, highest value + * to raise the PMTU to, i.e. + * don't try to raise above this + * value. Tune this per your + * largest MTU interface if your + * system does not support the + * SIOCGIFMTU ioctl. + */ +#endif +#define SCTP_DEFAULT_MINSEGMENT 512 /* MTU size ... if no mtu disc */ +#define SCTP_HOW_MANY_SECRETS 2 /* how many secrets I keep */ +/* This is how long a secret lives, NOT how long a cookie lives */ +#define SCTP_HOW_LONG_COOKIE_LIVE 3600 /* how many seconds the current secret will live */ + +#define SCTP_NUMBER_OF_SECRETS 8 /* or 8 * 4 = 32 octets */ +#define SCTP_SECRET_SIZE 32 /* number of octets in a 256 bits */ + +#ifdef USE_MD5 +#define SCTP_SIGNATURE_SIZE 16 /* size of a MD5 signature */ +#else +#define SCTP_SIGNATURE_SIZE 20 /* size of a SLA-1 signature */ +#endif +/* Here are the notification constants + * that the code and upper layer will get + */ + +/* association is up */ +#define SCTP_NOTIFY_ASSOC_UP 1 + +/* association is down */ +#define SCTP_NOTIFY_ASSOC_DOWN 2 + +/* interface on a association is down + * and out of consideration for selection. + */ +#define SCTP_NOTIFY_INTF_DOWN 3 + +/* interface on a association is up + * and now back in consideration for selection. + */ +#define SCTP_NOTIFY_INTF_UP 4 + +/* The given datagram cannot be delivered + * to the peer, this will probably be followed + * by a SCTP_NOTFIY_ASSOC_DOWN. + */ +#define SCTP_NOTIFY_DG_FAIL 5 + +/* Sent dg on non-open stream extreme code error! + */ +#define SCTP_NOTIFY_STRDATA_ERR 6 + +#define SCTP_NOTIFY_ASSOC_ABORTED 7 + +/* The stream ones are not used yet, but could + * be when a association opens. + */ +#define SCTP_NOTIFY_PEER_OPENED_STR 8 +#define SCTP_NOTIFY_STREAM_OPENED_OK 9 + +/* association sees a restart event */ +#define SCTP_NOTIFY_ASSOC_RESTART 10 + +/* a user requested HB returned */ +#define SCTP_NOTIFY_HB_RESP 11 + +/* a result from a REL-REQ */ +#define SCTP_NOTIFY_RELREQ_RESULT_OK 12 +#define SCTP_NOTIFY_RELREQ_RESULT_FAILED 13 + +/* clock variance is 10ms or 10,000 us's */ +#define SCTP_CLOCK_GRAINULARITY 10000 + +#define IP_HDR_SIZE 40 /* we use the size of a IP6 header here + * this detracts a small amount for ipv4 + * but it simplifies the ipv6 addition + */ + +#define SCTP_NUM_FDS 3 + +/* raw IP filedescriptor */ +#define SCTP_FD_IP 0 +/* raw ICMP filedescriptor */ +#define SCTP_FD_ICMP 1 +/* processes contact me for requests here */ +#define SCTP_REQUEST 2 + + +#define SCTP_DEAMON_PORT 9899 + +/* Deamon registration message types/responses */ +#define DEAMON_REGISTER 0x01 +#define DEAMON_REGISTER_ACK 0x02 +#define DEAMON_DEREGISTER 0x03 +#define DEAMON_DEREGISTER_ACK 0x04 +#define DEAMON_CHECKADDR_LIST 0x05 + +#define DEAMON_MAGIC_VER_LEN 0xff + +/* max times I will attempt to send a message to deamon */ +#define SCTP_MAX_ATTEMPTS_AT_DEAMON 5 +#define SCTP_TIMEOUT_IN_POLL_FOR_DEAMON 1500 /* 1.5 seconds */ + +/* modular comparison */ +/* True if a > b (mod = M) */ +#define compare_with_wrap(a, b, M) ((a > b) && ((a - b) < (M >> 1))) || \ + ((b > a) && ((b - a) > (M >> 1))) + +#ifndef TIMEVAL_TO_TIMESPEC +#define TIMEVAL_TO_TIMESPEC(tv, ts) \ +{ \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000; \ +} +#endif + +/* pegs */ +#define SCTP_NUMBER_OF_PEGS 21 +/* peg index's */ +#define SCTP_PEG_SACKS_SEEN 0 +#define SCTP_PEG_SACKS_SENT 1 +#define SCTP_PEG_TSNS_SENT 2 +#define SCTP_PEG_TSNS_RCVD 3 +#define SCTP_DATAGRAMS_SENT 4 +#define SCTP_DATAGRAMS_RCVD 5 +#define SCTP_RETRANTSN_SENT 6 +#define SCTP_DUPTSN_RECVD 7 +#define SCTP_HBR_RECV 8 +#define SCTP_HBA_RECV 9 +#define SCTP_HB_SENT 10 +#define SCTP_DATA_DG_SENT 11 +#define SCTP_DATA_DG_RECV 12 +#define SCTP_TMIT_TIMER 13 +#define SCTP_RECV_TIMER 14 +#define SCTP_HB_TIMER 15 +#define SCTP_FAST_RETRAN 16 +#define SCTP_PEG_TSNS_READ 17 +#define SCTP_NONE_LFT_TO 18 +#define SCTP_NONE_LFT_RWND 19 +#define SCTP_NONE_LFT_CWND 20 + + + +#endif + diff --git a/sctpHeader.h b/sctpHeader.h new file mode 100644 index 0000000..63f30b5 --- /dev/null +++ b/sctpHeader.h @@ -0,0 +1,323 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/sctpHeader.h,v 1.6 2002-12-11 07:14:11 guy Exp $ (LBL) */ + +/* SCTP reference Implementation Copyright (C) 1999 Cisco And Motorola + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 4. Neither the name of Cisco nor of Motorola may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the SCTP reference Implementation + * + * + * Please send any bug reports or fixes you make to one of the following email + * addresses: + * + * rstewar1@email.mot.com + * kmorneau@cisco.com + * qxie1@email.mot.com + * + * Any bugs reported given to us we will try to fix... any fixes shared will + * be incorperated into the next SCTP release. + */ + + +#ifndef __sctpHeader_h__ +#define __sctpHeader_h__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* the sctp common header */ + +#ifdef TRU64 + #define _64BITS 1 +#endif + +struct sctpHeader{ + u_int16_t source; + u_int16_t destination; + u_int32_t verificationTag; + u_int32_t adler32; +}; + +/* various descriptor parsers */ + +struct sctpChunkDesc{ + u_int8_t chunkID; + u_int8_t chunkFlg; + u_int16_t chunkLength; +}; + +struct sctpParamDesc{ + u_int16_t paramType; + u_int16_t paramLength; +}; + + +struct sctpRelChunkDesc{ + struct sctpChunkDesc chk; + u_int32_t serialNumber; +}; + +struct sctpVendorSpecificParam { + struct sctpParamDesc p; /* type must be 0xfffe */ + u_int32_t vendorId; /* vendor ID from RFC 1700 */ + u_int16_t vendorSpecificType; + u_int16_t vendorSpecificLen; +}; + + +/* Structures for the control parts */ + + + +/* Sctp association init request/ack */ + +/* this is used for init ack, too */ +struct sctpInitiation{ + u_int32_t initTag; /* tag of mine */ + u_int32_t rcvWindowCredit; /* rwnd */ + u_int16_t NumPreopenStreams; /* OS */ + u_int16_t MaxInboundStreams; /* MIS */ + u_int32_t initialTSN; + /* optional param's follow in sctpParamDesc form */ +}; + +struct sctpV4IpAddress{ + struct sctpParamDesc p; /* type is set to SCTP_IPV4_PARAM_TYPE, len=10 */ + u_int32_t ipAddress; +}; + + +struct sctpV6IpAddress{ + struct sctpParamDesc p; /* type is set to SCTP_IPV6_PARAM_TYPE, len=22 */ + u_int8_t ipAddress[16]; +}; + +struct sctpDNSName{ + struct sctpParamDesc param; + u_int8_t name[1]; +}; + + +struct sctpCookiePreserve{ + struct sctpParamDesc p; /* type is set to SCTP_COOKIE_PRESERVE, len=8 */ + u_int32_t extraTime; +}; + + +struct sctpTimeStamp{ + u_int32_t ts_sec; + u_int32_t ts_usec; +}; + +/* wire structure of my cookie */ +struct cookieMessage{ + u_int32_t TieTag_curTag; /* copied from assoc if present */ + u_int32_t TieTag_hisTag; /* copied from assoc if present */ + int32_t cookieLife; /* life I will award this cookie */ + struct sctpTimeStamp timeEnteringState; /* the time I built cookie */ + struct sctpInitiation initAckISent; /* the INIT-ACK that I sent to my peer */ + u_int32_t addressWhereISent[4]; /* I make this 4 ints so I get 128bits for future */ + int32_t addrtype; /* address type */ + u_int16_t locScope; /* V6 local scope flag */ + u_int16_t siteScope; /* V6 site scope flag */ + /* at the end is tacked on the INIT chunk sent in + * its entirety and of course our + * signature. + */ +}; + + +/* this guy is for use when + * I have a initiate message gloming the + * things together. + + */ +struct sctpUnifiedInit{ + struct sctpChunkDesc uh; + struct sctpInitiation initm; +}; + +struct sctpSendableInit{ + struct sctpHeader mh; + struct sctpUnifiedInit msg; +}; + + +/* Selective Acknowledgement + * has the following structure with + * a optional ammount of trailing int's + * on the last part (based on the numberOfDesc + * field). + */ + +struct sctpSelectiveAck{ + u_int32_t highestConseqTSN; + u_int32_t updatedRwnd; + u_int16_t numberOfdesc; + u_int16_t numDupTsns; +}; + +struct sctpSelectiveFrag{ + u_int16_t fragmentStart; + u_int16_t fragmentEnd; +}; + + +struct sctpUnifiedSack{ + struct sctpChunkDesc uh; + struct sctpSelectiveAck sack; +}; + +/* for both RTT request/response the + * following is sent + */ + +struct sctpHBrequest { + u_int32_t time_value_1; + u_int32_t time_value_2; +}; + +/* here is what I read and respond with to. */ +struct sctpHBunified{ + struct sctpChunkDesc hdr; + struct sctpParamDesc hb; +}; + + +/* here is what I send */ +struct sctpHBsender{ + struct sctpChunkDesc hdr; + struct sctpParamDesc hb; + struct sctpHBrequest rtt; + int8_t addrFmt[SCTP_ADDRMAX]; + u_int16_t userreq; +}; + + + +/* for the abort and shutdown ACK + * we must carry the init tag in the common header. Just the + * common header is all that is needed with a chunk descriptor. + */ +struct sctpUnifiedAbort{ + struct sctpChunkDesc uh; +}; + +struct sctpUnifiedAbortLight{ + struct sctpHeader mh; + struct sctpChunkDesc uh; +}; + +struct sctpUnifiedAbortHeavy{ + struct sctpHeader mh; + struct sctpChunkDesc uh; + u_int16_t causeCode; + u_int16_t causeLen; +}; + +/* For the graceful shutdown we must carry + * the tag (in common header) and the highest consequitive acking value + */ +struct sctpShutdown { + u_int32_t TSN_Seen; +}; + +struct sctpUnifiedShutdown{ + struct sctpChunkDesc uh; + struct sctpShutdown shut; +}; + +/* in the unified message we add the trailing + * stream id since it is the only message + * that is defined as a operation error. + */ +struct sctpOpErrorCause{ + u_int16_t cause; + u_int16_t causeLen; +}; + +struct sctpUnifiedOpError{ + struct sctpChunkDesc uh; + struct sctpOpErrorCause c; +}; + +struct sctpUnifiedStreamError{ + struct sctpHeader mh; + struct sctpChunkDesc uh; + struct sctpOpErrorCause c; + u_int16_t strmNum; + u_int16_t reserved; +}; + +struct staleCookieMsg{ + struct sctpHeader mh; + struct sctpChunkDesc uh; + struct sctpOpErrorCause c; + u_int32_t moretime; +}; + +/* the following is used in all sends + * where nothing is needed except the + * chunk/type i.e. shutdownAck Abort */ + +struct sctpUnifiedSingleMsg{ + struct sctpHeader mh; + struct sctpChunkDesc uh; +}; + +struct sctpDataPart{ + u_int32_t TSN; + u_int16_t streamId; + u_int16_t sequence; + u_int32_t payloadtype; +}; + +struct sctpUnifiedDatagram{ + struct sctpChunkDesc uh; + struct sctpDataPart dp; +}; + +struct sctpECN_echo{ + struct sctpChunkDesc uh; + u_int32_t Lowest_TSN; +}; + + +struct sctpCWR{ + struct sctpChunkDesc uh; + u_int32_t TSN_reduced_at; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/send-ack.awk b/send-ack.awk new file mode 100644 index 0000000..f55b7c2 --- /dev/null +++ b/send-ack.awk @@ -0,0 +1,68 @@ +BEGIN { + # we need the number of bytes in a packet to do the output + # in packet numbers rather than byte numbers. + if (packetsize <= 0) + packetsize = 512 + expectNext = 1 + lastwin = -1 + } + { + # convert tcp trace to send/ack form. + n = split ($1,t,":") + tim = t[1]*3600 + t[2]*60 + t[3] + if (NR <= 1) { + tzero = tim + ltim = tim + OFS = "\t" + } + if ($6 != "ack") { + # we have a data packet record: + # ignore guys with syn, fin or reset 'cause we + # can't handle their sequence numbers. Try to + # detect and add a flag character for 'anomalies': + # * -> re-sent packet + # - -> packet after hole (missing packet(s)) + # # -> odd size packet + if ($5 !~ /[SFR]/) { + i = index($6,":") + j = index($6,"(") + strtSeq = substr($6,1,i-1) + endSeq = substr($6,i+1,j-i-1) + len = endSeq - strtSeq + id = endSeq + if (! timeOf[id]) + timeOf[id] = tim + if (endSeq - expectNext < 0) + flag = "*" + else { + if (strtSeq - expectNext > 0) + flag = "-" + else if (len != packetsize) + flag = "#" + else + flag = " " + expectNext = endSeq + } + printf "%7.2f\t%7.2f\t%s send %s %d", tim-tzero, tim-ltim,\ + flag, $5, strtSeq + if (++timesSent[id] > 1) + printf " (%.2f) [%d]", tim - timeOf[id], timesSent[id] + if (len != packetsize) + printf " <%d>", len + } + } else { + id = $7 + + printf "%7.2f\t%7.2f\t%s ack %s %d", tim-tzero, tim-ltim,\ + flag, $5, id + if ($9 != lastwin) { + printf " win %d", $9 + lastwin = $9 + } + printf " (%.2f)", tim - timeOf[id] + if (++timesAcked[id] > 1) + printf " [%d]", timesAcked[id] + } + printf "\n" + ltim = tim + } diff --git a/setsignal.c b/setsignal.c new file mode 100644 index 0000000..a4b59ce --- /dev/null +++ b/setsignal.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/setsignal.c,v 1.11 2003-11-16 09:36:42 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#ifdef HAVE_SIGACTION +#include +#endif + +#ifdef HAVE_OS_PROTO_H +#include "os-proto.h" +#endif + +#include "setsignal.h" + +/* + * An OS-independent signal() with, whenever possible, partial BSD + * semantics, i.e. the signal handler is restored following service + * of the signal, but system calls are *not* restarted, so that if + * "pcap_breakloop()" is called in a signal handler in a live capture, + * the read/recvfrom/whatever in the live capture doesn't get restarted, + * it returns -1 and sets "errno" to EINTR, so we can break out of the + * live capture loop. + * + * We use "sigaction()" if available. We don't specify that the signal + * should restart system calls, so that should always do what we want. + * + * Otherwise, if "sigset()" is available, it probably has BSD semantics + * while "signal()" has traditional semantics, so we use "sigset()"; it + * might cause system calls to be restarted for the signal, however. + * I don't know whether, in any systems where it did cause system calls to + * be restarted, there was a way to ask it not to do so; there may no + * longer be any interesting systems without "sigaction()", however, + * and, if there are, they might have "sigvec()" with SV_INTERRUPT + * (which I think first appeared in 4.3BSD). + * + * Otherwise, we use "signal()" - which means we might get traditional + * semantics, wherein system calls don't get restarted *but* the + * signal handler is reset to SIG_DFL and the signal is not blocked, + * so that a subsequent signal would kill the process immediately. + * + * Did I mention that signals suck? At least in POSIX-compliant systems + * they suck far less, as those systems have "sigaction()". + */ +RETSIGTYPE +(*setsignal (int sig, RETSIGTYPE (*func)(int)))(int) +{ +#ifdef HAVE_SIGACTION + struct sigaction old, new; + + memset(&new, 0, sizeof(new)); + new.sa_handler = func; + if (sigaction(sig, &new, &old) < 0) + return (SIG_ERR); + return (old.sa_handler); + +#else +#ifdef HAVE_SIGSET + return (sigset(sig, func)); +#else + return (signal(sig, func)); +#endif +#endif +} + diff --git a/setsignal.h b/setsignal.h new file mode 100644 index 0000000..984c340 --- /dev/null +++ b/setsignal.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#) $Header: /tcpdump/master/tcpdump/setsignal.h,v 1.2 1999-10-07 23:47:13 mcr Exp $ (LBL) + */ +#ifndef setsignal_h +#define setsignal_h + +RETSIGTYPE (*setsignal(int, RETSIGTYPE (*)(int)))(int); +#endif diff --git a/signature.c b/signature.c new file mode 100644 index 0000000..c55645f --- /dev/null +++ b/signature.c @@ -0,0 +1,159 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Functions for signature and digest verification. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/signature.c,v 1.2 2008-09-22 20:22:10 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "interface.h" +#include "signature.h" + +#ifdef HAVE_LIBCRYPTO +#include +#endif + +const struct tok signature_check_values[] = { + { SIGNATURE_VALID, "valid"}, + { SIGNATURE_INVALID, "invalid"}, + { CANT_CHECK_SIGNATURE, "unchecked"}, + { 0, NULL } +}; + + +#ifdef HAVE_LIBCRYPTO +/* + * Compute a HMAC MD5 sum. + * Taken from rfc2104, Appendix. + */ +static void +signature_compute_hmac_md5(const u_int8_t *text, int text_len, unsigned char *key, + unsigned int key_len, u_int8_t *digest) +{ + MD5_CTX context; + unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */ + unsigned char k_opad[65]; /* outer padding - key XORd with opad */ + unsigned char tk[16]; + int i; + + /* if key is longer than 64 bytes reset it to key=MD5(key) */ + if (key_len > 64) { + + MD5_CTX tctx; + + MD5_Init(&tctx); + MD5_Update(&tctx, key, key_len); + MD5_Final(tk, &tctx); + + key = tk; + key_len = 16; + } + + /* + * the HMAC_MD5 transform looks like: + * + * MD5(K XOR opad, MD5(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected + */ + + /* start out by storing key in pads */ + memset(k_ipad, 0, sizeof k_ipad); + memset(k_opad, 0, sizeof k_opad); + memcpy(k_ipad, key, key_len); + memcpy(k_opad, key, key_len); + + /* XOR key with ipad and opad values */ + for (i=0; i<64; i++) { + k_ipad[i] ^= 0x36; + k_opad[i] ^= 0x5c; + } + + /* + * perform inner MD5 + */ + MD5_Init(&context); /* init context for 1st pass */ + MD5_Update(&context, k_ipad, 64); /* start with inner pad */ + MD5_Update(&context, text, text_len); /* then text of datagram */ + MD5_Final(digest, &context); /* finish up 1st pass */ + + /* + * perform outer MD5 + */ + MD5_Init(&context); /* init context for 2nd pass */ + MD5_Update(&context, k_opad, 64); /* start with outer pad */ + MD5_Update(&context, digest, 16); /* then results of 1st hash */ + MD5_Final(digest, &context); /* finish up 2nd pass */ +} +#endif + +#ifdef HAVE_LIBCRYPTO +/* + * Verify a cryptographic signature of the packet. + * Currently only MD5 is supported. + */ +int +signature_verify (const u_char *pptr, u_int plen, u_char *sig_ptr) +{ + u_int8_t rcvsig[16]; + u_int8_t sig[16]; + unsigned int i; + + /* + * Save the signature before clearing it. + */ + memcpy(rcvsig, sig_ptr, sizeof(rcvsig)); + memset(sig_ptr, 0, sizeof(rcvsig)); + + if (!sigsecret) { + return (CANT_CHECK_SIGNATURE); + } + + signature_compute_hmac_md5(pptr, plen, (unsigned char *)sigsecret, + strlen(sigsecret), sig); + + if (memcmp(rcvsig, sig, sizeof(sig)) == 0) { + return (SIGNATURE_VALID); + + } else { + + for (i = 0; i < sizeof(sig); ++i) { + (void)printf("%02x", sig[i]); + } + + return (SIGNATURE_INVALID); + } +} +#endif + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 4 + * End: + */ diff --git a/signature.h b/signature.h new file mode 100644 index 0000000..e48b722 --- /dev/null +++ b/signature.h @@ -0,0 +1,26 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Functions for signature and digest verification. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +/* @(#) $Header: /tcpdump/master/tcpdump/signature.h,v 1.1 2008-08-16 11:36:20 hannes Exp $ (LBL) */ + +/* signature checking result codes */ +#define SIGNATURE_VALID 0 +#define SIGNATURE_INVALID 1 +#define CANT_CHECK_SIGNATURE 2 + +extern const struct tok signature_check_values[]; +extern int signature_verify (const u_char *, u_int, u_char *); diff --git a/slcompress.h b/slcompress.h new file mode 100644 index 0000000..d10243a --- /dev/null +++ b/slcompress.h @@ -0,0 +1,87 @@ +/* + * Definitions for tcp compression routines. + * + * @(#) $Header: /tcpdump/master/tcpdump/slcompress.h,v 1.2 2000-10-09 02:03:44 guy Exp $ (LBL) + * + * Copyright (c) 1989, 1990, 1992, 1993 Regents of the University of + * California. All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van@ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. + */ + +/* + * Compressed packet format: + * + * The first octet contains the packet type (top 3 bits), TCP + * 'push' bit, and flags that indicate which of the 4 TCP sequence + * numbers have changed (bottom 5 bits). The next octet is a + * conversation number that associates a saved IP/TCP header with + * the compressed packet. The next two octets are the TCP checksum + * from the original datagram. The next 0 to 15 octets are + * sequence number changes, one change per bit set in the header + * (there may be no changes and there are two special cases where + * the receiver implicitly knows what changed -- see below). + * + * There are 5 numbers which can change (they are always inserted + * in the following order): TCP urgent pointer, window, + * acknowlegement, sequence number and IP ID. (The urgent pointer + * is different from the others in that its value is sent, not the + * change in value.) Since typical use of SLIP links is biased + * toward small packets (see comments on MTU/MSS below), changes + * use a variable length coding with one octet for numbers in the + * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the + * range 256 - 65535 or 0. (If the change in sequence number or + * ack is more than 65535, an uncompressed packet is sent.) + */ + +/* + * Packet types (must not conflict with IP protocol version) + * + * The top nibble of the first octet is the packet type. There are + * three possible types: IP (not proto TCP or tcp with one of the + * control flags set); uncompressed TCP (a normal IP/TCP packet but + * with the 8-bit protocol field replaced by an 8-bit connection id -- + * this type of packet syncs the sender & receiver); and compressed + * TCP (described above). + * + * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and + * is logically part of the 4-bit "changes" field that follows. Top + * three bits are actual packet type. For backward compatibility + * and in the interest of conserving bits, numbers are chosen so the + * IP protocol version number (4) which normally appears in this nibble + * means "IP packet". + */ + +/* packet types */ +#define TYPE_IP 0x40 +#define TYPE_UNCOMPRESSED_TCP 0x70 +#define TYPE_COMPRESSED_TCP 0x80 +#define TYPE_ERROR 0x00 + +/* Bits in first octet of compressed packet */ +#define NEW_C 0x40 /* flag bits for what changed in a packet */ +#define NEW_I 0x20 +#define NEW_S 0x08 +#define NEW_A 0x04 +#define NEW_W 0x02 +#define NEW_U 0x01 + +/* reserved, special-case values of above */ +#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ +#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ +#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) + +#define TCP_PUSH_BIT 0x10 diff --git a/slip.h b/slip.h new file mode 100644 index 0000000..aa6402c --- /dev/null +++ b/slip.h @@ -0,0 +1,34 @@ +/* + * Definitions that user level programs might need to know to interact + * with serial line IP (slip) lines. + * + * @(#) $Header: /tcpdump/master/tcpdump/slip.h,v 1.1 2000-10-09 01:53:21 guy Exp $ + * + * Copyright (c) 1990 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + * definitions of the pseudo- link-level header attached to slip + * packets grabbed by the packet filter (bpf) traffic monitor. + */ +#define SLIP_HDRLEN 16 + +#define SLX_DIR 0 +#define SLX_CHDR 1 +#define CHDR_LEN 15 + +#define SLIPDIR_IN 0 +#define SLIPDIR_OUT 1 diff --git a/sll.h b/sll.h new file mode 100644 index 0000000..0a34963 --- /dev/null +++ b/sll.h @@ -0,0 +1,127 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#) $Header: /tcpdump/master/tcpdump/sll.h,v 1.8 2008-05-30 01:37:41 guy Exp $ (LBL) + */ + +/* + * For captures on Linux cooked sockets, we construct a fake header + * that includes: + * + * a 2-byte "packet type" which is one of: + * + * LINUX_SLL_HOST packet was sent to us + * LINUX_SLL_BROADCAST packet was broadcast + * LINUX_SLL_MULTICAST packet was multicast + * LINUX_SLL_OTHERHOST packet was sent to somebody else + * LINUX_SLL_OUTGOING packet was sent *by* us; + * + * a 2-byte Ethernet protocol field; + * + * a 2-byte link-layer type; + * + * a 2-byte link-layer address length; + * + * an 8-byte source link-layer address, whose actual length is + * specified by the previous value. + * + * All fields except for the link-layer address are in network byte order. + * + * DO NOT change the layout of this structure, or change any of the + * LINUX_SLL_ values below. If you must change the link-layer header + * for a "cooked" Linux capture, introduce a new DLT_ type (ask + * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it + * a value that collides with a value already being used), and use the + * new header in captures of that type, so that programs that can + * handle DLT_LINUX_SLL captures will continue to handle them correctly + * without any change, and so that capture files with different headers + * can be told apart and programs that read them can dissect the + * packets in them. + * + * This structure, and the #defines below, must be the same in the + * libpcap and tcpdump versions of "sll.h". + */ + +/* + * A DLT_LINUX_SLL fake link-layer header. + */ +#define SLL_HDR_LEN 16 /* total header length */ +#define SLL_ADDRLEN 8 /* length of address field */ + +struct sll_header { + u_int16_t sll_pkttype; /* packet type */ + u_int16_t sll_hatype; /* link-layer address type */ + u_int16_t sll_halen; /* link-layer address length */ + u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ + u_int16_t sll_protocol; /* protocol */ +}; + +/* + * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the + * PACKET_ values on Linux, but are defined here so that they're + * available even on systems other than Linux, and so that they + * don't change even if the PACKET_ values change. + */ +#define LINUX_SLL_HOST 0 +#define LINUX_SLL_BROADCAST 1 +#define LINUX_SLL_MULTICAST 2 +#define LINUX_SLL_OTHERHOST 3 +#define LINUX_SLL_OUTGOING 4 + +/* + * The LINUX_SLL_ values for "sll_protocol"; these correspond to the + * ETH_P_ values on Linux, but are defined here so that they're + * available even on systems other than Linux. We assume, for now, + * that the ETH_P_ values won't change in Linux; if they do, then: + * + * if we don't translate them in "pcap-linux.c", capture files + * won't necessarily be readable if captured on a system that + * defines ETH_P_ values that don't match these values; + * + * if we do translate them in "pcap-linux.c", that makes life + * unpleasant for the BPF code generator, as the values you test + * for in the kernel aren't the values that you test for when + * reading a capture file, so the fixup code run on BPF programs + * handed to the kernel ends up having to do more work. + * + * Add other values here as necessary, for handling packet types that + * might show up on non-Ethernet, non-802.x networks. (Not all the ones + * in the Linux "if_ether.h" will, I suspect, actually show up in + * captures.) + */ +#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ +#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ diff --git a/smb.h b/smb.h new file mode 100644 index 0000000..8eeb303 --- /dev/null +++ b/smb.h @@ -0,0 +1,122 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/smb.h,v 1.9 2004-12-28 22:29:44 guy Exp $ (LBL) */ +/* + * Copyright (C) Andrew Tridgell 1995-1999 + * + * This software may be distributed either under the terms of the + * BSD-style license that accompanies tcpdump or the GNU GPL version 2 + * or later + */ + +#define SMBMIN(a,b) ((a)<(b)?(a):(b)) + +/* the complete */ +#define SMBmkdir 0x00 /* create directory */ +#define SMBrmdir 0x01 /* delete directory */ +#define SMBopen 0x02 /* open file */ +#define SMBcreate 0x03 /* create file */ +#define SMBclose 0x04 /* close file */ +#define SMBflush 0x05 /* flush file */ +#define SMBunlink 0x06 /* delete file */ +#define SMBmv 0x07 /* rename file */ +#define SMBgetatr 0x08 /* get file attributes */ +#define SMBsetatr 0x09 /* set file attributes */ +#define SMBread 0x0A /* read from file */ +#define SMBwrite 0x0B /* write to file */ +#define SMBlock 0x0C /* lock byte range */ +#define SMBunlock 0x0D /* unlock byte range */ +#define SMBctemp 0x0E /* create temporary file */ +#define SMBmknew 0x0F /* make new file */ +#define SMBchkpth 0x10 /* check directory path */ +#define SMBexit 0x11 /* process exit */ +#define SMBlseek 0x12 /* seek */ +#define SMBtcon 0x70 /* tree connect */ +#define SMBtconX 0x75 /* tree connect and X*/ +#define SMBtdis 0x71 /* tree disconnect */ +#define SMBnegprot 0x72 /* negotiate protocol */ +#define SMBdskattr 0x80 /* get disk attributes */ +#define SMBsearch 0x81 /* search directory */ +#define SMBsplopen 0xC0 /* open print spool file */ +#define SMBsplwr 0xC1 /* write to print spool file */ +#define SMBsplclose 0xC2 /* close print spool file */ +#define SMBsplretq 0xC3 /* return print queue */ +#define SMBsends 0xD0 /* send single block message */ +#define SMBsendb 0xD1 /* send broadcast message */ +#define SMBfwdname 0xD2 /* forward user name */ +#define SMBcancelf 0xD3 /* cancel forward */ +#define SMBgetmac 0xD4 /* get machine name */ +#define SMBsendstrt 0xD5 /* send start of multi-block message */ +#define SMBsendend 0xD6 /* send end of multi-block message */ +#define SMBsendtxt 0xD7 /* send text of multi-block message */ + +/* Core+ protocol */ +#define SMBlockread 0x13 /* Lock a range and read */ +#define SMBwriteunlock 0x14 /* Unlock a range then write */ +#define SMBreadbraw 0x1a /* read a block of data with no smb header */ +#define SMBwritebraw 0x1d /* write a block of data with no smb header */ +#define SMBwritec 0x20 /* secondary write request */ +#define SMBwriteclose 0x2c /* write a file then close it */ + +/* dos extended protocol */ +#define SMBreadBraw 0x1A /* read block raw */ +#define SMBreadBmpx 0x1B /* read block multiplexed */ +#define SMBreadBs 0x1C /* read block (secondary response) */ +#define SMBwriteBraw 0x1D /* write block raw */ +#define SMBwriteBmpx 0x1E /* write block multiplexed */ +#define SMBwriteBs 0x1F /* write block (secondary request) */ +#define SMBwriteC 0x20 /* write complete response */ +#define SMBsetattrE 0x22 /* set file attributes expanded */ +#define SMBgetattrE 0x23 /* get file attributes expanded */ +#define SMBlockingX 0x24 /* lock/unlock byte ranges and X */ +#define SMBtrans 0x25 /* transaction - name, bytes in/out */ +#define SMBtranss 0x26 /* transaction (secondary request/response) */ +#define SMBioctl 0x27 /* IOCTL */ +#define SMBioctls 0x28 /* IOCTL (secondary request/response) */ +#define SMBcopy 0x29 /* copy */ +#define SMBmove 0x2A /* move */ +#define SMBecho 0x2B /* echo */ +#define SMBopenX 0x2D /* open and X */ +#define SMBreadX 0x2E /* read and X */ +#define SMBwriteX 0x2F /* write and X */ +#define SMBsesssetupX 0x73 /* Session Set Up & X (including User Logon) */ +#define SMBffirst 0x82 /* find first */ +#define SMBfunique 0x83 /* find unique */ +#define SMBfclose 0x84 /* find close */ +#define SMBinvalid 0xFE /* invalid command */ + +/* Extended 2.0 protocol */ +#define SMBtrans2 0x32 /* TRANS2 protocol set */ +#define SMBtranss2 0x33 /* TRANS2 protocol set, secondary command */ +#define SMBfindclose 0x34 /* Terminate a TRANSACT2_FINDFIRST */ +#define SMBfindnclose 0x35 /* Terminate a TRANSACT2_FINDNOTIFYFIRST */ +#define SMBulogoffX 0x74 /* user logoff */ + +/* NT SMB extensions. */ +#define SMBnttrans 0xA0 /* NT transact */ +#define SMBnttranss 0xA1 /* NT transact secondary */ +#define SMBntcreateX 0xA2 /* NT create and X */ +#define SMBntcancel 0xA4 /* NT cancel */ + +/* pathworks special */ +#define pSETDIR '\377' + + +/* these are the TRANS2 sub commands */ +#define TRANSACT2_OPEN 0 +#define TRANSACT2_FINDFIRST 1 +#define TRANSACT2_FINDNEXT 2 +#define TRANSACT2_QFSINFO 3 +#define TRANSACT2_SETFSINFO 4 +#define TRANSACT2_QPATHINFO 5 +#define TRANSACT2_SETPATHINFO 6 +#define TRANSACT2_QFILEINFO 7 +#define TRANSACT2_SETFILEINFO 8 +#define TRANSACT2_FSCTL 9 +#define TRANSACT2_IOCTL 10 +#define TRANSACT2_FINDNOTIFYFIRST 11 +#define TRANSACT2_FINDNOTIFYNEXT 12 +#define TRANSACT2_MKDIR 13 + +#define PTR_DIFF(p1, p2) ((size_t)(((char *)(p1)) - (char *)(p2))) + +/* some protos */ +const u_char *smb_fdata(const u_char *, const char *, const u_char *, int); diff --git a/smbutil.c b/smbutil.c new file mode 100644 index 0000000..5eadb4f --- /dev/null +++ b/smbutil.c @@ -0,0 +1,1889 @@ +/* + * Copyright (C) Andrew Tridgell 1995-1999 + * + * This software may be distributed either under the terms of the + * BSD-style license that accompanies tcpdump or the GNU GPL version 2 + * or later + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.39 2007-07-15 19:07:39 guy Exp $"; +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "smb.h" + +static u_int32_t stringlen; +extern const u_char *startbuf; + +/* + * interpret a 32 bit dos packed date/time to some parameters + */ +static void +interpret_dos_date(u_int32_t date, struct tm *tp) +{ + u_int32_t p0, p1, p2, p3; + + p0 = date & 0xFF; + p1 = ((date & 0xFF00) >> 8) & 0xFF; + p2 = ((date & 0xFF0000) >> 16) & 0xFF; + p3 = ((date & 0xFF000000) >> 24) & 0xFF; + + tp->tm_sec = 2 * (p0 & 0x1F); + tp->tm_min = ((p0 >> 5) & 0xFF) + ((p1 & 0x7) << 3); + tp->tm_hour = (p1 >> 3) & 0xFF; + tp->tm_mday = (p2 & 0x1F); + tp->tm_mon = ((p2 >> 5) & 0xFF) + ((p3 & 0x1) << 3) - 1; + tp->tm_year = ((p3 >> 1) & 0xFF) + 80; +} + +/* + * common portion: + * create a unix date from a dos date + */ +static time_t +int_unix_date(u_int32_t dos_date) +{ + struct tm t; + + if (dos_date == 0) + return(0); + + interpret_dos_date(dos_date, &t); + t.tm_wday = 1; + t.tm_yday = 1; + t.tm_isdst = 0; + + return (mktime(&t)); +} + +/* + * create a unix date from a dos date + * in network byte order + */ +static time_t +make_unix_date(const u_char *date_ptr) +{ + u_int32_t dos_date = 0; + + dos_date = EXTRACT_LE_32BITS(date_ptr); + + return int_unix_date(dos_date); +} + +/* + * create a unix date from a dos date + * in halfword-swapped network byte order! + */ +static time_t +make_unix_date2(const u_char *date_ptr) +{ + u_int32_t x, x2; + + x = EXTRACT_LE_32BITS(date_ptr); + x2 = ((x & 0xFFFF) << 16) | ((x & 0xFFFF0000) >> 16); + return int_unix_date(x2); +} + +/* + * interpret an 8 byte "filetime" structure to a time_t + * It's originally in "100ns units since jan 1st 1601" + */ +static time_t +interpret_long_date(const u_char *p) +{ + double d; + time_t ret; + + /* this gives us seconds since jan 1st 1601 (approx) */ + d = (EXTRACT_LE_32BITS(p + 4) * 256.0 + p[3]) * (1.0e-7 * (1 << 24)); + + /* now adjust by 369 years to make the secs since 1970 */ + d -= 369.0 * 365.25 * 24 * 60 * 60; + + /* and a fudge factor as we got it wrong by a few days */ + d += (3 * 24 * 60 * 60 + 6 * 60 * 60 + 2); + + if (d < 0) + return(0); + + ret = (time_t)d; + + return(ret); +} + +/* + * interpret the weird netbios "name". Return the name type, or -1 if + * we run past the end of the buffer + */ +static int +name_interpret(const u_char *in, const u_char *maxbuf, char *out) +{ + int ret; + int len; + + if (in >= maxbuf) + return(-1); /* name goes past the end of the buffer */ + TCHECK2(*in, 1); + len = (*in++) / 2; + + *out=0; + + if (len > 30 || len < 1) + return(0); + + while (len--) { + TCHECK2(*in, 2); + if (in + 1 >= maxbuf) + return(-1); /* name goes past the end of the buffer */ + if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { + *out = 0; + return(0); + } + *out = ((in[0] - 'A') << 4) + (in[1] - 'A'); + in += 2; + out++; + } + *out = 0; + ret = out[-1]; + + return(ret); + +trunc: + return(-1); +} + +/* + * find a pointer to a netbios name + */ +static const u_char * +name_ptr(const u_char *buf, int ofs, const u_char *maxbuf) +{ + const u_char *p; + u_char c; + + p = buf + ofs; + if (p >= maxbuf) + return(NULL); /* name goes past the end of the buffer */ + TCHECK2(*p, 1); + + c = *p; + + /* XXX - this should use the same code that the DNS dissector does */ + if ((c & 0xC0) == 0xC0) { + u_int16_t l; + + TCHECK2(*p, 2); + if ((p + 1) >= maxbuf) + return(NULL); /* name goes past the end of the buffer */ + l = EXTRACT_16BITS(p) & 0x3FFF; + if (l == 0) { + /* We have a pointer that points to itself. */ + return(NULL); + } + p = buf + l; + if (p >= maxbuf) + return(NULL); /* name goes past the end of the buffer */ + TCHECK2(*p, 1); + } + return(p); + +trunc: + return(NULL); /* name goes past the end of the buffer */ +} + +/* + * extract a netbios name from a buf + */ +static int +name_extract(const u_char *buf, int ofs, const u_char *maxbuf, char *name) +{ + const u_char *p = name_ptr(buf, ofs, maxbuf); + if (p == NULL) + return(-1); /* error (probably name going past end of buffer) */ + name[0] = '\0'; + return(name_interpret(p, maxbuf, name)); +} + + +/* + * return the total storage length of a mangled name + */ +static int +name_len(const unsigned char *s, const unsigned char *maxbuf) +{ + const unsigned char *s0 = s; + unsigned char c; + + if (s >= maxbuf) + return(-1); /* name goes past the end of the buffer */ + TCHECK2(*s, 1); + c = *s; + if ((c & 0xC0) == 0xC0) + return(2); + while (*s) { + if (s >= maxbuf) + return(-1); /* name goes past the end of the buffer */ + TCHECK2(*s, 1); + s += (*s) + 1; + } + return(PTR_DIFF(s, s0) + 1); + +trunc: + return(-1); /* name goes past the end of the buffer */ +} + +static void +print_asc(const unsigned char *buf, int len) +{ + int i; + for (i = 0; i < len; i++) + safeputchar(buf[i]); +} + +static const char * +name_type_str(int name_type) +{ + const char *f = NULL; + + switch (name_type) { + case 0: f = "Workstation"; break; + case 0x03: f = "Client?"; break; + case 0x20: f = "Server"; break; + case 0x1d: f = "Master Browser"; break; + case 0x1b: f = "Domain Controller"; break; + case 0x1e: f = "Browser Server"; break; + default: f = "Unknown"; break; + } + return(f); +} + +void +print_data(const unsigned char *buf, int len) +{ + int i = 0; + + if (len <= 0) + return; + printf("[%03X] ", i); + for (i = 0; i < len; /*nothing*/) { + TCHECK(buf[i]); + printf("%02X ", buf[i] & 0xff); + i++; + if (i%8 == 0) + printf(" "); + if (i % 16 == 0) { + print_asc(&buf[i - 16], 8); + printf(" "); + print_asc(&buf[i - 8], 8); + printf("\n"); + if (i < len) + printf("[%03X] ", i); + } + } + if (i % 16) { + int n; + + n = 16 - (i % 16); + printf(" "); + if (n>8) + printf(" "); + while (n--) + printf(" "); + + n = SMBMIN(8, i % 16); + print_asc(&buf[i - (i % 16)], n); + printf(" "); + n = (i % 16) - n; + if (n > 0) + print_asc(&buf[i - n], n); + printf("\n"); + } + return; + +trunc: + printf("\n"); + printf("WARNING: Short packet. Try increasing the snap length\n"); +} + + +static void +write_bits(unsigned int val, const char *fmt) +{ + const char *p = fmt; + int i = 0; + + while ((p = strchr(fmt, '|'))) { + size_t l = PTR_DIFF(p, fmt); + if (l && (val & (1 << i))) + printf("%.*s ", (int)l, fmt); + fmt = p + 1; + i++; + } +} + +/* convert a UCS2 string into iso-8859-1 string */ +#define MAX_UNISTR_SIZE 1000 +static const char * +unistr(const u_char *s, u_int32_t *len, int use_unicode) +{ + static char buf[MAX_UNISTR_SIZE+1]; + size_t l = 0; + u_int32_t strsize; + const u_char *sp; + + if (use_unicode) { + /* + * Skip padding that puts the string on an even boundary. + */ + if (((s - startbuf) % 2) != 0) { + TCHECK(s[0]); + s++; + } + } + if (*len == 0) { + /* + * Null-terminated string. + */ + strsize = 0; + sp = s; + if (!use_unicode) { + for (;;) { + TCHECK(sp[0]); + *len += 1; + if (sp[0] == 0) + break; + sp++; + } + strsize = *len - 1; + } else { + for (;;) { + TCHECK2(sp[0], 2); + *len += 2; + if (sp[0] == 0 && sp[1] == 0) + break; + sp += 2; + } + strsize = *len - 2; + } + } else { + /* + * Counted string. + */ + strsize = *len; + } + if (!use_unicode) { + while (strsize != 0) { + TCHECK(s[0]); + if (l >= MAX_UNISTR_SIZE) + break; + if (isprint(s[0])) + buf[l] = s[0]; + else { + if (s[0] == 0) + break; + buf[l] = '.'; + } + l++; + s++; + strsize--; + } + } else { + while (strsize != 0) { + TCHECK2(s[0], 2); + if (l >= MAX_UNISTR_SIZE) + break; + if (s[1] == 0 && isprint(s[0])) { + /* It's a printable ASCII character */ + buf[l] = s[0]; + } else { + /* It's a non-ASCII character or a non-printable ASCII character */ + if (s[0] == 0 && s[1] == 0) + break; + buf[l] = '.'; + } + l++; + s += 2; + if (strsize == 1) + break; + strsize -= 2; + } + } + buf[l] = 0; + return buf; + +trunc: + return NULL; +} + +static const u_char * +smb_fdata1(const u_char *buf, const char *fmt, const u_char *maxbuf, + int unicodestr) +{ + int reverse = 0; + const char *attrib_fmt = "READONLY|HIDDEN|SYSTEM|VOLUME|DIR|ARCHIVE|"; + + while (*fmt && buf sizeof(bitfmt) - 1) + l = sizeof(bitfmt)-1; + + strncpy(bitfmt, fmt, l); + bitfmt[l] = '\0'; + fmt = p + 1; + TCHECK(buf[0]); + write_bits(buf[0], bitfmt); + buf++; + break; + } + + case 'P': + { + int l = atoi(fmt + 1); + TCHECK2(buf[0], l); + buf += l; + fmt++; + while (isdigit((unsigned char)*fmt)) + fmt++; + break; + } + case 'r': + reverse = !reverse; + fmt++; + break; + case 'b': + { + unsigned int x; + TCHECK(buf[0]); + x = buf[0]; + printf("%u (0x%x)", x, x); + buf += 1; + fmt++; + break; + } + case 'd': + { + unsigned int x; + TCHECK2(buf[0], 2); + x = reverse ? EXTRACT_16BITS(buf) : + EXTRACT_LE_16BITS(buf); + printf("%d (0x%x)", x, x); + buf += 2; + fmt++; + break; + } + case 'D': + { + unsigned int x; + TCHECK2(buf[0], 4); + x = reverse ? EXTRACT_32BITS(buf) : + EXTRACT_LE_32BITS(buf); + printf("%d (0x%x)", x, x); + buf += 4; + fmt++; + break; + } + case 'L': + { + u_int64_t x; + TCHECK2(buf[0], 8); + x = reverse ? EXTRACT_64BITS(buf) : + EXTRACT_LE_64BITS(buf); + printf("%" PRIu64 " (0x%" PRIx64 ")", x, x); + buf += 8; + fmt++; + break; + } + case 'M': + { + /* Weird mixed-endian length values in 64-bit locks */ + u_int32_t x1, x2; + u_int64_t x; + TCHECK2(buf[0], 8); + x1 = reverse ? EXTRACT_32BITS(buf) : + EXTRACT_LE_32BITS(buf); + x2 = reverse ? EXTRACT_32BITS(buf + 4) : + EXTRACT_LE_32BITS(buf + 4); + x = (((u_int64_t)x1) << 32) | x2; + printf("%" PRIu64 " (0x%" PRIx64 ")", x, x); + buf += 8; + fmt++; + break; + } + case 'B': + { + unsigned int x; + TCHECK(buf[0]); + x = buf[0]; + printf("0x%X", x); + buf += 1; + fmt++; + break; + } + case 'w': + { + unsigned int x; + TCHECK2(buf[0], 2); + x = reverse ? EXTRACT_16BITS(buf) : + EXTRACT_LE_16BITS(buf); + printf("0x%X", x); + buf += 2; + fmt++; + break; + } + case 'W': + { + unsigned int x; + TCHECK2(buf[0], 4); + x = reverse ? EXTRACT_32BITS(buf) : + EXTRACT_LE_32BITS(buf); + printf("0x%X", x); + buf += 4; + fmt++; + break; + } + case 'l': + { + fmt++; + switch (*fmt) { + + case 'b': + TCHECK(buf[0]); + stringlen = buf[0]; + printf("%u", stringlen); + buf += 1; + break; + + case 'd': + TCHECK2(buf[0], 2); + stringlen = reverse ? EXTRACT_16BITS(buf) : + EXTRACT_LE_16BITS(buf); + printf("%u", stringlen); + buf += 2; + break; + + case 'D': + TCHECK2(buf[0], 4); + stringlen = reverse ? EXTRACT_32BITS(buf) : + EXTRACT_LE_32BITS(buf); + printf("%u", stringlen); + buf += 4; + break; + } + fmt++; + break; + } + case 'S': + case 'R': /* like 'S', but always ASCII */ + { + /*XXX unistr() */ + const char *s; + u_int32_t len; + + len = 0; + s = unistr(buf, &len, (*fmt == 'R') ? 0 : unicodestr); + if (s == NULL) + goto trunc; + printf("%s", s); + buf += len; + fmt++; + break; + } + case 'Z': + case 'Y': /* like 'Z', but always ASCII */ + { + const char *s; + u_int32_t len; + + TCHECK(*buf); + if (*buf != 4 && *buf != 2) { + printf("Error! ASCIIZ buffer of type %u", *buf); + return maxbuf; /* give up */ + } + len = 0; + s = unistr(buf + 1, &len, (*fmt == 'Y') ? 0 : unicodestr); + if (s == NULL) + goto trunc; + printf("%s", s); + buf += len + 1; + fmt++; + break; + } + case 's': + { + int l = atoi(fmt + 1); + TCHECK2(*buf, l); + printf("%-*.*s", l, l, buf); + buf += l; + fmt++; + while (isdigit((unsigned char)*fmt)) + fmt++; + break; + } + case 'c': + { + TCHECK2(*buf, stringlen); + printf("%-*.*s", (int)stringlen, (int)stringlen, buf); + buf += stringlen; + fmt++; + while (isdigit((unsigned char)*fmt)) + fmt++; + break; + } + case 'C': + { + const char *s; + s = unistr(buf, &stringlen, unicodestr); + if (s == NULL) + goto trunc; + printf("%s", s); + buf += stringlen; + fmt++; + break; + } + case 'h': + { + int l = atoi(fmt + 1); + TCHECK2(*buf, l); + while (l--) + printf("%02x", *buf++); + fmt++; + while (isdigit((unsigned char)*fmt)) + fmt++; + break; + } + case 'n': + { + int t = atoi(fmt+1); + char nbuf[255]; + int name_type; + int len; + + switch (t) { + case 1: + name_type = name_extract(startbuf, PTR_DIFF(buf, startbuf), + maxbuf, nbuf); + if (name_type < 0) + goto trunc; + len = name_len(buf, maxbuf); + if (len < 0) + goto trunc; + buf += len; + printf("%-15.15s NameType=0x%02X (%s)", nbuf, name_type, + name_type_str(name_type)); + break; + case 2: + TCHECK(buf[15]); + name_type = buf[15]; + printf("%-15.15s NameType=0x%02X (%s)", buf, name_type, + name_type_str(name_type)); + buf += 16; + break; + } + fmt++; + while (isdigit((unsigned char)*fmt)) + fmt++; + break; + } + case 'T': + { + time_t t; + struct tm *lt; + const char *tstring; + u_int32_t x; + + switch (atoi(fmt + 1)) { + case 1: + TCHECK2(buf[0], 4); + x = EXTRACT_LE_32BITS(buf); + if (x == 0 || x == 0xFFFFFFFF) + t = 0; + else + t = make_unix_date(buf); + buf += 4; + break; + case 2: + TCHECK2(buf[0], 4); + x = EXTRACT_LE_32BITS(buf); + if (x == 0 || x == 0xFFFFFFFF) + t = 0; + else + t = make_unix_date2(buf); + buf += 4; + break; + case 3: + TCHECK2(buf[0], 8); + t = interpret_long_date(buf); + buf += 8; + break; + default: + t = 0; + break; + } + if (t != 0) { + lt = localtime(&t); + if (lt != NULL) + tstring = asctime(lt); + else + tstring = "(Can't convert time)\n"; + } else + tstring = "NULL\n"; + printf("%s", tstring); + fmt++; + while (isdigit((unsigned char)*fmt)) + fmt++; + break; + } + default: + putchar(*fmt); + fmt++; + break; + } + } + + if (buf >= maxbuf && *fmt) + printf("END OF BUFFER\n"); + + return(buf); + +trunc: + printf("\n"); + printf("WARNING: Short packet. Try increasing the snap length\n"); + return(NULL); +} + +const u_char * +smb_fdata(const u_char *buf, const char *fmt, const u_char *maxbuf, + int unicodestr) +{ + static int depth = 0; + char s[128]; + char *p; + + while (*fmt) { + switch (*fmt) { + case '*': + fmt++; + while (buf < maxbuf) { + const u_char *buf2; + depth++; + buf2 = smb_fdata(buf, fmt, maxbuf, unicodestr); + depth--; + if (buf2 == NULL) + return(NULL); + if (buf2 == buf) + return(buf); + buf = buf2; + } + return(buf); + + case '|': + fmt++; + if (buf >= maxbuf) + return(buf); + break; + + case '%': + fmt++; + buf = maxbuf; + break; + + case '#': + fmt++; + return(buf); + break; + + case '[': + fmt++; + if (buf >= maxbuf) + return(buf); + memset(s, 0, sizeof(s)); + p = strchr(fmt, ']'); + if ((size_t)(p - fmt + 1) > sizeof(s)) { + /* overrun */ + return(buf); + } + strncpy(s, fmt, p - fmt); + s[p - fmt] = '\0'; + fmt = p + 1; + buf = smb_fdata1(buf, s, maxbuf, unicodestr); + if (buf == NULL) + return(NULL); + break; + + default: + putchar(*fmt); + fmt++; + fflush(stdout); + break; + } + } + if (!depth && buf < maxbuf) { + size_t len = PTR_DIFF(maxbuf, buf); + printf("Data: (%lu bytes)\n", (unsigned long)len); + print_data(buf, len); + return(buf + len); + } + return(buf); +} + +typedef struct { + const char *name; + int code; + const char *message; +} err_code_struct; + +/* DOS Error Messages */ +static const err_code_struct dos_msgs[] = { + { "ERRbadfunc", 1, "Invalid function." }, + { "ERRbadfile", 2, "File not found." }, + { "ERRbadpath", 3, "Directory invalid." }, + { "ERRnofids", 4, "No file descriptors available" }, + { "ERRnoaccess", 5, "Access denied." }, + { "ERRbadfid", 6, "Invalid file handle." }, + { "ERRbadmcb", 7, "Memory control blocks destroyed." }, + { "ERRnomem", 8, "Insufficient server memory to perform the requested function." }, + { "ERRbadmem", 9, "Invalid memory block address." }, + { "ERRbadenv", 10, "Invalid environment." }, + { "ERRbadformat", 11, "Invalid format." }, + { "ERRbadaccess", 12, "Invalid open mode." }, + { "ERRbaddata", 13, "Invalid data." }, + { "ERR", 14, "reserved." }, + { "ERRbaddrive", 15, "Invalid drive specified." }, + { "ERRremcd", 16, "A Delete Directory request attempted to remove the server's current directory." }, + { "ERRdiffdevice", 17, "Not same device." }, + { "ERRnofiles", 18, "A File Search command can find no more files matching the specified criteria." }, + { "ERRbadshare", 32, "The sharing mode specified for an Open conflicts with existing FIDs on the file." }, + { "ERRlock", 33, "A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process." }, + { "ERRfilexists", 80, "The file named in a Create Directory, Make New File or Link request already exists." }, + { "ERRbadpipe", 230, "Pipe invalid." }, + { "ERRpipebusy", 231, "All instances of the requested pipe are busy." }, + { "ERRpipeclosing", 232, "Pipe close in progress." }, + { "ERRnotconnected", 233, "No process on other end of pipe." }, + { "ERRmoredata", 234, "There is more data to be returned." }, + { NULL, -1, NULL } + }; + +/* Server Error Messages */ +static const err_code_struct server_msgs[] = { + { "ERRerror", 1, "Non-specific error code." }, + { "ERRbadpw", 2, "Bad password - name/password pair in a Tree Connect or Session Setup are invalid." }, + { "ERRbadtype", 3, "reserved." }, + { "ERRaccess", 4, "The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID." }, + { "ERRinvnid", 5, "The tree ID (TID) specified in a command was invalid." }, + { "ERRinvnetname", 6, "Invalid network name in tree connect." }, + { "ERRinvdevice", 7, "Invalid device - printer request made to non-printer connection or non-printer request made to printer connection." }, + { "ERRqfull", 49, "Print queue full (files) -- returned by open print file." }, + { "ERRqtoobig", 50, "Print queue full -- no space." }, + { "ERRqeof", 51, "EOF on print queue dump." }, + { "ERRinvpfid", 52, "Invalid print file FID." }, + { "ERRsmbcmd", 64, "The server did not recognize the command received." }, + { "ERRsrverror", 65, "The server encountered an internal error, e.g., system file unavailable." }, + { "ERRfilespecs", 67, "The file handle (FID) and pathname parameters contained an invalid combination of values." }, + { "ERRreserved", 68, "reserved." }, + { "ERRbadpermits", 69, "The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute." }, + { "ERRreserved", 70, "reserved." }, + { "ERRsetattrmode", 71, "The attribute mode in the Set File Attribute request is invalid." }, + { "ERRpaused", 81, "Server is paused." }, + { "ERRmsgoff", 82, "Not receiving messages." }, + { "ERRnoroom", 83, "No room to buffer message." }, + { "ERRrmuns", 87, "Too many remote user names." }, + { "ERRtimeout", 88, "Operation timed out." }, + { "ERRnoresource", 89, "No resources currently available for request." }, + { "ERRtoomanyuids", 90, "Too many UIDs active on this session." }, + { "ERRbaduid", 91, "The UID is not known as a valid ID on this session." }, + { "ERRusempx", 250, "Temp unable to support Raw, use MPX mode." }, + { "ERRusestd", 251, "Temp unable to support Raw, use standard read/write." }, + { "ERRcontmpx", 252, "Continue in MPX mode." }, + { "ERRreserved", 253, "reserved." }, + { "ERRreserved", 254, "reserved." }, + { "ERRnosupport", 0xFFFF, "Function not supported." }, + { NULL, -1, NULL } +}; + +/* Hard Error Messages */ +static const err_code_struct hard_msgs[] = { + { "ERRnowrite", 19, "Attempt to write on write-protected diskette." }, + { "ERRbadunit", 20, "Unknown unit." }, + { "ERRnotready", 21, "Drive not ready." }, + { "ERRbadcmd", 22, "Unknown command." }, + { "ERRdata", 23, "Data error (CRC)." }, + { "ERRbadreq", 24, "Bad request structure length." }, + { "ERRseek", 25 , "Seek error." }, + { "ERRbadmedia", 26, "Unknown media type." }, + { "ERRbadsector", 27, "Sector not found." }, + { "ERRnopaper", 28, "Printer out of paper." }, + { "ERRwrite", 29, "Write fault." }, + { "ERRread", 30, "Read fault." }, + { "ERRgeneral", 31, "General failure." }, + { "ERRbadshare", 32, "A open conflicts with an existing open." }, + { "ERRlock", 33, "A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process." }, + { "ERRwrongdisk", 34, "The wrong disk was found in a drive." }, + { "ERRFCBUnavail", 35, "No FCBs are available to process request." }, + { "ERRsharebufexc", 36, "A sharing buffer has been exceeded." }, + { NULL, -1, NULL } +}; + +static const struct { + int code; + const char *class; + const err_code_struct *err_msgs; +} err_classes[] = { + { 0, "SUCCESS", NULL }, + { 0x01, "ERRDOS", dos_msgs }, + { 0x02, "ERRSRV", server_msgs }, + { 0x03, "ERRHRD", hard_msgs }, + { 0x04, "ERRXOS", NULL }, + { 0xE1, "ERRRMX1", NULL }, + { 0xE2, "ERRRMX2", NULL }, + { 0xE3, "ERRRMX3", NULL }, + { 0xFF, "ERRCMD", NULL }, + { -1, NULL, NULL } +}; + +/* + * return a SMB error string from a SMB buffer + */ +char * +smb_errstr(int class, int num) +{ + static char ret[128]; + int i, j; + + ret[0] = 0; + + for (i = 0; err_classes[i].class; i++) + if (err_classes[i].code == class) { + if (err_classes[i].err_msgs) { + const err_code_struct *err = err_classes[i].err_msgs; + for (j = 0; err[j].name; j++) + if (num == err[j].code) { + snprintf(ret, sizeof(ret), "%s - %s (%s)", + err_classes[i].class, err[j].name, err[j].message); + return ret; + } + } + + snprintf(ret, sizeof(ret), "%s - %d", err_classes[i].class, num); + return ret; + } + + snprintf(ret, sizeof(ret), "ERROR: Unknown error (%d,%d)", class, num); + return(ret); +} + +typedef struct { + u_int32_t code; + const char *name; +} nt_err_code_struct; + +/* + * NT Error codes + */ +static const nt_err_code_struct nt_errors[] = { + { 0x00000000, "STATUS_SUCCESS" }, + { 0x00000000, "STATUS_WAIT_0" }, + { 0x00000001, "STATUS_WAIT_1" }, + { 0x00000002, "STATUS_WAIT_2" }, + { 0x00000003, "STATUS_WAIT_3" }, + { 0x0000003F, "STATUS_WAIT_63" }, + { 0x00000080, "STATUS_ABANDONED" }, + { 0x00000080, "STATUS_ABANDONED_WAIT_0" }, + { 0x000000BF, "STATUS_ABANDONED_WAIT_63" }, + { 0x000000C0, "STATUS_USER_APC" }, + { 0x00000100, "STATUS_KERNEL_APC" }, + { 0x00000101, "STATUS_ALERTED" }, + { 0x00000102, "STATUS_TIMEOUT" }, + { 0x00000103, "STATUS_PENDING" }, + { 0x00000104, "STATUS_REPARSE" }, + { 0x00000105, "STATUS_MORE_ENTRIES" }, + { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" }, + { 0x00000107, "STATUS_SOME_NOT_MAPPED" }, + { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" }, + { 0x00000109, "STATUS_VOLUME_MOUNTED" }, + { 0x0000010A, "STATUS_RXACT_COMMITTED" }, + { 0x0000010B, "STATUS_NOTIFY_CLEANUP" }, + { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" }, + { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" }, + { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" }, + { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" }, + { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" }, + { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" }, + { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" }, + { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" }, + { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" }, + { 0x00000116, "STATUS_CRASH_DUMP" }, + { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" }, + { 0x00000118, "STATUS_REPARSE_OBJECT" }, + { 0x0000045C, "STATUS_NO_SHUTDOWN_IN_PROGRESS" }, + { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" }, + { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" }, + { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" }, + { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" }, + { 0x40000004, "STATUS_RXACT_STATE_CREATED" }, + { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" }, + { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" }, + { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" }, + { 0x40000008, "STATUS_SERIAL_MORE_WRITES" }, + { 0x40000009, "STATUS_REGISTRY_RECOVERED" }, + { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" }, + { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" }, + { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" }, + { 0x4000000D, "STATUS_NULL_LM_PASSWORD" }, + { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" }, + { 0x4000000F, "STATUS_RECEIVE_PARTIAL" }, + { 0x40000010, "STATUS_RECEIVE_EXPEDITED" }, + { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" }, + { 0x40000012, "STATUS_EVENT_DONE" }, + { 0x40000013, "STATUS_EVENT_PENDING" }, + { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" }, + { 0x40000015, "STATUS_FATAL_APP_EXIT" }, + { 0x40000016, "STATUS_PREDEFINED_HANDLE" }, + { 0x40000017, "STATUS_WAS_UNLOCKED" }, + { 0x40000018, "STATUS_SERVICE_NOTIFICATION" }, + { 0x40000019, "STATUS_WAS_LOCKED" }, + { 0x4000001A, "STATUS_LOG_HARD_ERROR" }, + { 0x4000001B, "STATUS_ALREADY_WIN32" }, + { 0x4000001C, "STATUS_WX86_UNSIMULATE" }, + { 0x4000001D, "STATUS_WX86_CONTINUE" }, + { 0x4000001E, "STATUS_WX86_SINGLE_STEP" }, + { 0x4000001F, "STATUS_WX86_BREAKPOINT" }, + { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" }, + { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" }, + { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" }, + { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" }, + { 0x40000024, "STATUS_NO_YIELD_PERFORMED" }, + { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" }, + { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" }, + { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" }, + { 0x80000003, "STATUS_BREAKPOINT" }, + { 0x80000004, "STATUS_SINGLE_STEP" }, + { 0x80000005, "STATUS_BUFFER_OVERFLOW" }, + { 0x80000006, "STATUS_NO_MORE_FILES" }, + { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" }, + { 0x8000000A, "STATUS_HANDLES_CLOSED" }, + { 0x8000000B, "STATUS_NO_INHERITANCE" }, + { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" }, + { 0x8000000D, "STATUS_PARTIAL_COPY" }, + { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" }, + { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" }, + { 0x80000010, "STATUS_DEVICE_OFF_LINE" }, + { 0x80000011, "STATUS_DEVICE_BUSY" }, + { 0x80000012, "STATUS_NO_MORE_EAS" }, + { 0x80000013, "STATUS_INVALID_EA_NAME" }, + { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" }, + { 0x80000015, "STATUS_INVALID_EA_FLAG" }, + { 0x80000016, "STATUS_VERIFY_REQUIRED" }, + { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" }, + { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" }, + { 0x8000001A, "STATUS_NO_MORE_ENTRIES" }, + { 0x8000001B, "STATUS_FILEMARK_DETECTED" }, + { 0x8000001C, "STATUS_MEDIA_CHANGED" }, + { 0x8000001D, "STATUS_BUS_RESET" }, + { 0x8000001E, "STATUS_END_OF_MEDIA" }, + { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" }, + { 0x80000020, "STATUS_MEDIA_CHECK" }, + { 0x80000021, "STATUS_SETMARK_DETECTED" }, + { 0x80000022, "STATUS_NO_DATA_DETECTED" }, + { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" }, + { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" }, + { 0x80000025, "STATUS_ALREADY_DISCONNECTED" }, + { 0x80000026, "STATUS_LONGJUMP" }, + { 0x80040111, "MAPI_E_LOGON_FAILED" }, + { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" }, + { 0x80090301, "SEC_E_INVALID_HANDLE" }, + { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" }, + { 0x8009030B, "SEC_E_NO_IMPERSONATION" }, + { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" }, + { 0x8009030E, "SEC_E_NO_CREDENTIALS" }, + { 0x8009030F, "SEC_E_MESSAGE_ALTERED" }, + { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" }, + { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" }, + { 0xC0000001, "STATUS_UNSUCCESSFUL" }, + { 0xC0000002, "STATUS_NOT_IMPLEMENTED" }, + { 0xC0000003, "STATUS_INVALID_INFO_CLASS" }, + { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" }, + { 0xC0000005, "STATUS_ACCESS_VIOLATION" }, + { 0xC0000006, "STATUS_IN_PAGE_ERROR" }, + { 0xC0000007, "STATUS_PAGEFILE_QUOTA" }, + { 0xC0000008, "STATUS_INVALID_HANDLE" }, + { 0xC0000009, "STATUS_BAD_INITIAL_STACK" }, + { 0xC000000A, "STATUS_BAD_INITIAL_PC" }, + { 0xC000000B, "STATUS_INVALID_CID" }, + { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" }, + { 0xC000000D, "STATUS_INVALID_PARAMETER" }, + { 0xC000000E, "STATUS_NO_SUCH_DEVICE" }, + { 0xC000000F, "STATUS_NO_SUCH_FILE" }, + { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" }, + { 0xC0000011, "STATUS_END_OF_FILE" }, + { 0xC0000012, "STATUS_WRONG_VOLUME" }, + { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" }, + { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" }, + { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" }, + { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" }, + { 0xC0000017, "STATUS_NO_MEMORY" }, + { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" }, + { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" }, + { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" }, + { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" }, + { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" }, + { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" }, + { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" }, + { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" }, + { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" }, + { 0xC0000021, "STATUS_ALREADY_COMMITTED" }, + { 0xC0000022, "STATUS_ACCESS_DENIED" }, + { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" }, + { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" }, + { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" }, + { 0xC0000026, "STATUS_INVALID_DISPOSITION" }, + { 0xC0000027, "STATUS_UNWIND" }, + { 0xC0000028, "STATUS_BAD_STACK" }, + { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" }, + { 0xC000002A, "STATUS_NOT_LOCKED" }, + { 0xC000002B, "STATUS_PARITY_ERROR" }, + { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" }, + { 0xC000002D, "STATUS_NOT_COMMITTED" }, + { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" }, + { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" }, + { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" }, + { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" }, + { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" }, + { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" }, + { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" }, + { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" }, + { 0xC0000037, "STATUS_PORT_DISCONNECTED" }, + { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" }, + { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" }, + { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" }, + { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" }, + { 0xC000003C, "STATUS_DATA_OVERRUN" }, + { 0xC000003D, "STATUS_DATA_LATE_ERROR" }, + { 0xC000003E, "STATUS_DATA_ERROR" }, + { 0xC000003F, "STATUS_CRC_ERROR" }, + { 0xC0000040, "STATUS_SECTION_TOO_BIG" }, + { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" }, + { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" }, + { 0xC0000043, "STATUS_SHARING_VIOLATION" }, + { 0xC0000044, "STATUS_QUOTA_EXCEEDED" }, + { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" }, + { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" }, + { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" }, + { 0xC0000048, "STATUS_PORT_ALREADY_SET" }, + { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" }, + { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" }, + { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" }, + { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" }, + { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" }, + { 0xC000004E, "STATUS_SECTION_PROTECTION" }, + { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" }, + { 0xC0000050, "STATUS_EA_TOO_LARGE" }, + { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" }, + { 0xC0000052, "STATUS_NO_EAS_ON_FILE" }, + { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" }, + { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" }, + { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" }, + { 0xC0000056, "STATUS_DELETE_PENDING" }, + { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" }, + { 0xC0000058, "STATUS_UNKNOWN_REVISION" }, + { 0xC0000059, "STATUS_REVISION_MISMATCH" }, + { 0xC000005A, "STATUS_INVALID_OWNER" }, + { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" }, + { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" }, + { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" }, + { 0xC000005E, "STATUS_NO_LOGON_SERVERS" }, + { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" }, + { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" }, + { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" }, + { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" }, + { 0xC0000063, "STATUS_USER_EXISTS" }, + { 0xC0000064, "STATUS_NO_SUCH_USER" }, + { 0xC0000065, "STATUS_GROUP_EXISTS" }, + { 0xC0000066, "STATUS_NO_SUCH_GROUP" }, + { 0xC0000067, "STATUS_MEMBER_IN_GROUP" }, + { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" }, + { 0xC0000069, "STATUS_LAST_ADMIN" }, + { 0xC000006A, "STATUS_WRONG_PASSWORD" }, + { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" }, + { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" }, + { 0xC000006D, "STATUS_LOGON_FAILURE" }, + { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" }, + { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" }, + { 0xC0000070, "STATUS_INVALID_WORKSTATION" }, + { 0xC0000071, "STATUS_PASSWORD_EXPIRED" }, + { 0xC0000072, "STATUS_ACCOUNT_DISABLED" }, + { 0xC0000073, "STATUS_NONE_MAPPED" }, + { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" }, + { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" }, + { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" }, + { 0xC0000077, "STATUS_INVALID_ACL" }, + { 0xC0000078, "STATUS_INVALID_SID" }, + { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" }, + { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" }, + { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" }, + { 0xC000007C, "STATUS_NO_TOKEN" }, + { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" }, + { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" }, + { 0xC000007F, "STATUS_DISK_FULL" }, + { 0xC0000080, "STATUS_SERVER_DISABLED" }, + { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" }, + { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" }, + { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" }, + { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" }, + { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" }, + { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" }, + { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" }, + { 0xC0000088, "STATUS_NOT_MAPPED_DATA" }, + { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" }, + { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" }, + { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" }, + { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" }, + { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" }, + { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" }, + { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" }, + { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" }, + { 0xC0000091, "STATUS_FLOAT_OVERFLOW" }, + { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" }, + { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" }, + { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" }, + { 0xC0000095, "STATUS_INTEGER_OVERFLOW" }, + { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" }, + { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" }, + { 0xC0000098, "STATUS_FILE_INVALID" }, + { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" }, + { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" }, + { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" }, + { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" }, + { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" }, + { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" }, + { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" }, + { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" }, + { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" }, + { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" }, + { 0xC00000A3, "STATUS_DEVICE_NOT_READY" }, + { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" }, + { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" }, + { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" }, + { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" }, + { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" }, + { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" }, + { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" }, + { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" }, + { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" }, + { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" }, + { 0xC00000AE, "STATUS_PIPE_BUSY" }, + { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" }, + { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" }, + { 0xC00000B1, "STATUS_PIPE_CLOSING" }, + { 0xC00000B2, "STATUS_PIPE_CONNECTED" }, + { 0xC00000B3, "STATUS_PIPE_LISTENING" }, + { 0xC00000B4, "STATUS_INVALID_READ_MODE" }, + { 0xC00000B5, "STATUS_IO_TIMEOUT" }, + { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" }, + { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" }, + { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" }, + { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" }, + { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" }, + { 0xC00000BB, "STATUS_NOT_SUPPORTED" }, + { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" }, + { 0xC00000BD, "STATUS_DUPLICATE_NAME" }, + { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" }, + { 0xC00000BF, "STATUS_NETWORK_BUSY" }, + { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" }, + { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" }, + { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" }, + { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" }, + { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" }, + { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" }, + { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" }, + { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" }, + { 0xC00000C8, "STATUS_PRINT_CANCELLED" }, + { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" }, + { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" }, + { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" }, + { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" }, + { 0xC00000CD, "STATUS_TOO_MANY_NAMES" }, + { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" }, + { 0xC00000CF, "STATUS_SHARING_PAUSED" }, + { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" }, + { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" }, + { 0xC00000D2, "STATUS_NET_WRITE_FAULT" }, + { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" }, + { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" }, + { 0xC00000D5, "STATUS_FILE_RENAMED" }, + { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" }, + { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" }, + { 0xC00000D8, "STATUS_CANT_WAIT" }, + { 0xC00000D9, "STATUS_PIPE_EMPTY" }, + { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" }, + { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" }, + { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" }, + { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" }, + { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" }, + { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" }, + { 0xC00000E0, "STATUS_DOMAIN_EXISTS" }, + { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" }, + { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" }, + { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" }, + { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" }, + { 0xC00000E5, "STATUS_INTERNAL_ERROR" }, + { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" }, + { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" }, + { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" }, + { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" }, + { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" }, + { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" }, + { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" }, + { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" }, + { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" }, + { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" }, + { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" }, + { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" }, + { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" }, + { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" }, + { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" }, + { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" }, + { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" }, + { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" }, + { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" }, + { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" }, + { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" }, + { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" }, + { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" }, + { 0xC00000FD, "STATUS_STACK_OVERFLOW" }, + { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" }, + { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" }, + { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" }, + { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" }, + { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" }, + { 0xC0000103, "STATUS_NOT_A_DIRECTORY" }, + { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" }, + { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" }, + { 0xC0000106, "STATUS_NAME_TOO_LONG" }, + { 0xC0000107, "STATUS_FILES_OPEN" }, + { 0xC0000108, "STATUS_CONNECTION_IN_USE" }, + { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" }, + { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" }, + { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" }, + { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" }, + { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" }, + { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" }, + { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" }, + { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" }, + { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" }, + { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" }, + { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" }, + { 0xC0000114, "STATUS_ABIOS_INVALID_LID" }, + { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" }, + { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" }, + { 0xC0000117, "STATUS_NO_LDT" }, + { 0xC0000118, "STATUS_INVALID_LDT_SIZE" }, + { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" }, + { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" }, + { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" }, + { 0xC000011C, "STATUS_RXACT_INVALID_STATE" }, + { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" }, + { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" }, + { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" }, + { 0xC0000120, "STATUS_CANCELLED" }, + { 0xC0000121, "STATUS_CANNOT_DELETE" }, + { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" }, + { 0xC0000123, "STATUS_FILE_DELETED" }, + { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" }, + { 0xC0000125, "STATUS_SPECIAL_GROUP" }, + { 0xC0000126, "STATUS_SPECIAL_USER" }, + { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" }, + { 0xC0000128, "STATUS_FILE_CLOSED" }, + { 0xC0000129, "STATUS_TOO_MANY_THREADS" }, + { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" }, + { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" }, + { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" }, + { 0xC000012D, "STATUS_COMMITMENT_LIMIT" }, + { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" }, + { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" }, + { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" }, + { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" }, + { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" }, + { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" }, + { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" }, + { 0xC0000135, "STATUS_DLL_NOT_FOUND" }, + { 0xC0000136, "STATUS_OPEN_FAILED" }, + { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" }, + { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" }, + { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" }, + { 0xC000013A, "STATUS_CONTROL_C_EXIT" }, + { 0xC000013B, "STATUS_LOCAL_DISCONNECT" }, + { 0xC000013C, "STATUS_REMOTE_DISCONNECT" }, + { 0xC000013D, "STATUS_REMOTE_RESOURCES" }, + { 0xC000013E, "STATUS_LINK_FAILED" }, + { 0xC000013F, "STATUS_LINK_TIMEOUT" }, + { 0xC0000140, "STATUS_INVALID_CONNECTION" }, + { 0xC0000141, "STATUS_INVALID_ADDRESS" }, + { 0xC0000142, "STATUS_DLL_INIT_FAILED" }, + { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" }, + { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" }, + { 0xC0000145, "STATUS_APP_INIT_FAILURE" }, + { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" }, + { 0xC0000147, "STATUS_NO_PAGEFILE" }, + { 0xC0000148, "STATUS_INVALID_LEVEL" }, + { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" }, + { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" }, + { 0xC000014B, "STATUS_PIPE_BROKEN" }, + { 0xC000014C, "STATUS_REGISTRY_CORRUPT" }, + { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" }, + { 0xC000014E, "STATUS_NO_EVENT_PAIR" }, + { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" }, + { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" }, + { 0xC0000151, "STATUS_NO_SUCH_ALIAS" }, + { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" }, + { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" }, + { 0xC0000154, "STATUS_ALIAS_EXISTS" }, + { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" }, + { 0xC0000156, "STATUS_TOO_MANY_SECRETS" }, + { 0xC0000157, "STATUS_SECRET_TOO_LONG" }, + { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" }, + { 0xC0000159, "STATUS_FULLSCREEN_MODE" }, + { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" }, + { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" }, + { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" }, + { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" }, + { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" }, + { 0xC000015F, "STATUS_FT_MISSING_MEMBER" }, + { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" }, + { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" }, + { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" }, + { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" }, + { 0xC0000164, "STATUS_FLOPPY_VOLUME" }, + { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" }, + { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" }, + { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" }, + { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" }, + { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" }, + { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" }, + { 0xC000016B, "STATUS_DISK_RESET_FAILED" }, + { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" }, + { 0xC000016D, "STATUS_FT_ORPHANING" }, + { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" }, + { 0xC0000172, "STATUS_PARTITION_FAILURE" }, + { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" }, + { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" }, + { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" }, + { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" }, + { 0xC0000177, "STATUS_EOM_OVERFLOW" }, + { 0xC0000178, "STATUS_NO_MEDIA" }, + { 0xC000017A, "STATUS_NO_SUCH_MEMBER" }, + { 0xC000017B, "STATUS_INVALID_MEMBER" }, + { 0xC000017C, "STATUS_KEY_DELETED" }, + { 0xC000017D, "STATUS_NO_LOG_SPACE" }, + { 0xC000017E, "STATUS_TOO_MANY_SIDS" }, + { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" }, + { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" }, + { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" }, + { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" }, + { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" }, + { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" }, + { 0xC0000185, "STATUS_IO_DEVICE_ERROR" }, + { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" }, + { 0xC0000187, "STATUS_BACKUP_CONTROLLER" }, + { 0xC0000188, "STATUS_LOG_FILE_FULL" }, + { 0xC0000189, "STATUS_TOO_LATE" }, + { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" }, + { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" }, + { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" }, + { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" }, + { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" }, + { 0xC000018F, "STATUS_EVENTLOG_CANT_START" }, + { 0xC0000190, "STATUS_TRUST_FAILURE" }, + { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" }, + { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" }, + { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" }, + { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" }, + { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" }, + { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" }, + { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" }, + { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" }, + { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" }, + { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" }, + { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" }, + { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" }, + { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" }, + { 0xC0000203, "STATUS_USER_SESSION_DELETED" }, + { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" }, + { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" }, + { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" }, + { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" }, + { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" }, + { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" }, + { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" }, + { 0xC000020B, "STATUS_ADDRESS_CLOSED" }, + { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" }, + { 0xC000020D, "STATUS_CONNECTION_RESET" }, + { 0xC000020E, "STATUS_TOO_MANY_NODES" }, + { 0xC000020F, "STATUS_TRANSACTION_ABORTED" }, + { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" }, + { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" }, + { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" }, + { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" }, + { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" }, + { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" }, + { 0xC0000216, "STATUS_NOT_SERVER_SESSION" }, + { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" }, + { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" }, + { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" }, + { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" }, + { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" }, + { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" }, + { 0xC000021D, "STATUS_VDM_HARD_ERROR" }, + { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" }, + { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" }, + { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" }, + { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" }, + { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" }, + { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" }, + { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" }, + { 0xC0000225, "STATUS_NOT_FOUND" }, + { 0xC0000226, "STATUS_NOT_TINY_STREAM" }, + { 0xC0000227, "STATUS_RECOVERY_FAILURE" }, + { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" }, + { 0xC0000229, "STATUS_FAIL_CHECK" }, + { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" }, + { 0xC000022B, "STATUS_OBJECTID_EXISTS" }, + { 0xC000022C, "STATUS_CONVERT_TO_LARGE" }, + { 0xC000022D, "STATUS_RETRY" }, + { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" }, + { 0xC000022F, "STATUS_ALLOCATE_BUCKET" }, + { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" }, + { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" }, + { 0xC0000232, "STATUS_INVALID_VARIANT" }, + { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" }, + { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" }, + { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" }, + { 0xC0000236, "STATUS_CONNECTION_REFUSED" }, + { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" }, + { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" }, + { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" }, + { 0xC000023A, "STATUS_CONNECTION_INVALID" }, + { 0xC000023B, "STATUS_CONNECTION_ACTIVE" }, + { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" }, + { 0xC000023D, "STATUS_HOST_UNREACHABLE" }, + { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" }, + { 0xC000023F, "STATUS_PORT_UNREACHABLE" }, + { 0xC0000240, "STATUS_REQUEST_ABORTED" }, + { 0xC0000241, "STATUS_CONNECTION_ABORTED" }, + { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" }, + { 0xC0000243, "STATUS_USER_MAPPED_FILE" }, + { 0xC0000244, "STATUS_AUDIT_FAILED" }, + { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" }, + { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" }, + { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" }, + { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" }, + { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" }, + { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" }, + { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" }, + { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" }, + { 0xC0000253, "STATUS_LPC_REPLY_LOST" }, + { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" }, + { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" }, + { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" }, + { 0xC0000257, "STATUS_PATH_NOT_COVERED" }, + { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" }, + { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" }, + { 0xC000025A, "STATUS_PWD_TOO_SHORT" }, + { 0xC000025B, "STATUS_PWD_TOO_RECENT" }, + { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" }, + { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" }, + { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" }, + { 0xC0000260, "STATUS_INVALID_HW_PROFILE" }, + { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" }, + { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" }, + { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" }, + { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" }, + { 0xC0000265, "STATUS_TOO_MANY_LINKS" }, + { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" }, + { 0xC0000267, "STATUS_FILE_IS_OFFLINE" }, + { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" }, + { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" }, + { 0xC000026A, "STATUS_LICENSE_VIOLATION" }, + { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" }, + { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" }, + { 0xC000026D, "STATUS_DFS_UNAVAILABLE" }, + { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" }, + { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" }, + { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" }, + { 0xC0000271, "STATUS_VALIDATE_CONTINUE" }, + { 0xC0000272, "STATUS_NO_MATCH" }, + { 0xC0000273, "STATUS_NO_MORE_MATCHES" }, + { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" }, + { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" }, + { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" }, + { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" }, + { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" }, + { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" }, + { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" }, + { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" }, + { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" }, + { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" }, + { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" }, + { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" }, + { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" }, + { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" }, + { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" }, + { 0xC000028A, "STATUS_ENCRYPTION_FAILED" }, + { 0xC000028B, "STATUS_DECRYPTION_FAILED" }, + { 0xC000028C, "STATUS_RANGE_NOT_FOUND" }, + { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" }, + { 0xC000028E, "STATUS_NO_EFS" }, + { 0xC000028F, "STATUS_WRONG_EFS" }, + { 0xC0000290, "STATUS_NO_USER_KEYS" }, + { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" }, + { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" }, + { 0xC0000293, "STATUS_FILE_ENCRYPTED" }, + { 0x40000294, "STATUS_WAKE_SYSTEM" }, + { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" }, + { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" }, + { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" }, + { 0xC0000298, "STATUS_WMI_TRY_AGAIN" }, + { 0xC0000299, "STATUS_SHARED_POLICY" }, + { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" }, + { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" }, + { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" }, + { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" }, + { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" }, + { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" }, + { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" }, + { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" }, + { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" }, + { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" }, + { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" }, + { 0xC00002A5, "STATUS_DS_BUSY" }, + { 0xC00002A6, "STATUS_DS_UNAVAILABLE" }, + { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" }, + { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" }, + { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" }, + { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" }, + { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" }, + { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" }, + { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" }, + { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" }, + { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" }, + { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" }, + { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" }, + { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" }, + { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" }, + { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" }, + { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" }, + { 0xC00002B6, "STATUS_DEVICE_REMOVED" }, + { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" }, + { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" }, + { 0xC00002B9, "STATUS_NOINTERFACE" }, + { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" }, + { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" }, + { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" }, + { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" }, + { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" }, + { 0xC00002C6, "STATUS_WMI_READ_ONLY" }, + { 0xC00002C7, "STATUS_WMI_SET_FAILURE" }, + { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" }, + { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" }, + { 0xC00002CA, "STATUS_TRANSPORT_FULL" }, + { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" }, + { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" }, + { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" }, + { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" }, + { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" }, + { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" }, + { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" }, + { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" }, + { 0xC00002D3, "STATUS_POWER_STATE_INVALID" }, + { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" }, + { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" }, + { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" }, + { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" }, + { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" }, + { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" }, + { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" }, + { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" }, + { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" }, + { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" }, + { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" }, + { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" }, + { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" }, + { 0xC00002E1, "STATUS_DS_CANT_START" }, + { 0xC00002E2, "STATUS_DS_INIT_FAILURE" }, + { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" }, + { 0xC00002E4, "STATUS_DS_GC_REQUIRED" }, + { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" }, + { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" }, + { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" }, + { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" }, + { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" }, + { 0xC0009898, "STATUS_WOW_ASSERTION" }, + { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" }, + { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" }, + { 0xC0020003, "RPC_NT_INVALID_BINDING" }, + { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" }, + { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" }, + { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" }, + { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" }, + { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" }, + { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" }, + { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" }, + { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" }, + { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" }, + { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" }, + { 0xC002000E, "RPC_NT_ALREADY_LISTENING" }, + { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" }, + { 0xC0020010, "RPC_NT_NOT_LISTENING" }, + { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" }, + { 0xC0020012, "RPC_NT_UNKNOWN_IF" }, + { 0xC0020013, "RPC_NT_NO_BINDINGS" }, + { 0xC0020014, "RPC_NT_NO_PROTSEQS" }, + { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" }, + { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" }, + { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" }, + { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" }, + { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" }, + { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" }, + { 0xC002001B, "RPC_NT_CALL_FAILED" }, + { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" }, + { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" }, + { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" }, + { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" }, + { 0xC0020022, "RPC_NT_INVALID_TAG" }, + { 0xC0020023, "RPC_NT_INVALID_BOUND" }, + { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" }, + { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" }, + { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" }, + { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" }, + { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" }, + { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" }, + { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" }, + { 0xC002002C, "RPC_NT_STRING_TOO_LONG" }, + { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" }, + { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" }, + { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" }, + { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" }, + { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" }, + { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" }, + { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" }, + { 0xC0020034, "EPT_NT_INVALID_ENTRY" }, + { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" }, + { 0xC0020036, "EPT_NT_NOT_REGISTERED" }, + { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" }, + { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" }, + { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" }, + { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" }, + { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" }, + { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" }, + { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" }, + { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" }, + { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" }, + { 0xC0020040, "RPC_NT_INVALID_NAF_ID" }, + { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" }, + { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" }, + { 0xC0020043, "RPC_NT_INTERNAL_ERROR" }, + { 0xC0020044, "RPC_NT_ZERO_DIVIDE" }, + { 0xC0020045, "RPC_NT_ADDRESS_ERROR" }, + { 0xC0020046, "RPC_NT_FP_DIV_ZERO" }, + { 0xC0020047, "RPC_NT_FP_UNDERFLOW" }, + { 0xC0020048, "RPC_NT_FP_OVERFLOW" }, + { 0xC0021007, "RPC_P_RECEIVE_ALERTED" }, + { 0xC0021008, "RPC_P_CONNECTION_CLOSED" }, + { 0xC0021009, "RPC_P_RECEIVE_FAILED" }, + { 0xC002100A, "RPC_P_SEND_FAILED" }, + { 0xC002100B, "RPC_P_TIMEOUT" }, + { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" }, + { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" }, + { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" }, + { 0xC0021015, "RPC_P_THREAD_LISTENING" }, + { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" }, + { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" }, + { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" }, + { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" }, + { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" }, + { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" }, + { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" }, + { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" }, + { 0xC0030009, "RPC_NT_NULL_REF_POINTER" }, + { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" }, + { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" }, + { 0xC003000C, "RPC_NT_BAD_STUB_DATA" }, + { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" }, + { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" }, + { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" }, + { 0xC002004C, "EPT_NT_CANT_CREATE" }, + { 0xC002004D, "RPC_NT_INVALID_OBJECT" }, + { 0xC002004F, "RPC_NT_NO_INTERFACES" }, + { 0xC0020050, "RPC_NT_CALL_CANCELLED" }, + { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" }, + { 0xC0020052, "RPC_NT_COMM_FAILURE" }, + { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" }, + { 0xC0020054, "RPC_NT_NO_PRINC_NAME" }, + { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" }, + { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" }, + { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" }, + { 0xC0020058, "RPC_NT_NOT_CANCELLED" }, + { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" }, + { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" }, + { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" }, + { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" }, + { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" }, + { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" }, + { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" }, + { 0, NULL } +}; + +/* + * return an NT error string from a SMB buffer + */ +const char * +nt_errstr(u_int32_t err) +{ + static char ret[128]; + int i; + + ret[0] = 0; + + for (i = 0; nt_errors[i].name; i++) { + if (err == nt_errors[i].code) + return nt_errors[i].name; + } + + snprintf(ret, sizeof(ret), "0x%08x", err); + return ret; +} diff --git a/stime.awk b/stime.awk new file mode 100644 index 0000000..61891f2 --- /dev/null +++ b/stime.awk @@ -0,0 +1,19 @@ +$6 !~ /^ack/ && $5 !~ /[SFR]/ { + # given a tcpdump ftp trace, output one line for each send + # in the form + # + # where is the time packet was sent (in seconds with + # zero at time of first packet) and is the tcp sequence + # number of the packet divided by 1024 (i.e., Kbytes sent). + # + # convert time to seconds + n = split ($1,t,":") + tim = t[1]*3600 + t[2]*60 + t[3] + if (! tzero) { + tzero = tim + OFS = "\t" + } + # get packet sequence number + i = index($6,":") + printf "%7.2f\t%g\n", tim-tzero, substr($6,1,i-1)/1024 + } diff --git a/strcasecmp.c b/strcasecmp.c new file mode 100644 index 0000000..5504e0a --- /dev/null +++ b/strcasecmp.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1987 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of California at Berkeley. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific written prior permission. This software + * is provided ``as is'' without express or implied warranty. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/strcasecmp.c,v 1.6 2003-11-16 09:36:43 guy Exp $"; +#endif + +#include + +#include "interface.h" + +/* + * This array is designed for mapping upper and lower case letter + * together for a case independent comparison. The mappings are + * based upon ascii character sequences. + */ +static const u_char charmap[] = { + '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', + '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', + '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', + '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', + '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', + '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', + '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', + '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', + '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', + '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', + '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', + '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', + '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', + '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', + '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', + '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', + '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', + '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', + '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', + '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', + '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', + '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', + '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', + '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', + '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347', + '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', + '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', + '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337', + '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', + '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', + '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', + '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377', +}; + +int +strcasecmp(s1, s2) + const char *s1, *s2; +{ + register const u_char *cm = charmap, + *us1 = (u_char *)s1, + *us2 = (u_char *)s2; + + while (cm[*us1] == cm[*us2++]) + if (*us1++ == '\0') + return(0); + return(cm[*us1] - cm[*--us2]); +} + +int +strncasecmp(s1, s2, n) + const char *s1, *s2; + register int n; +{ + register const u_char *cm = charmap, + *us1 = (u_char *)s1, + *us2 = (u_char *)s2; + + while (--n >= 0 && cm[*us1] == cm[*us2++]) + if (*us1++ == '\0') + return(0); + return(n < 0 ? 0 : cm[*us1] - cm[*--us2]); +} diff --git a/tcp.h b/tcp.h new file mode 100644 index 0000000..ac83714 --- /dev/null +++ b/tcp.h @@ -0,0 +1,111 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/tcp.h,v 1.14 2007-12-09 00:30:47 guy Exp $ (LBL) */ +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)tcp.h 8.1 (Berkeley) 6/10/93 + */ + +typedef u_int32_t tcp_seq; +/* + * TCP header. + * Per RFC 793, September, 1981. + */ +struct tcphdr { + u_int16_t th_sport; /* source port */ + u_int16_t th_dport; /* destination port */ + tcp_seq th_seq; /* sequence number */ + tcp_seq th_ack; /* acknowledgement number */ + u_int8_t th_offx2; /* data offset, rsvd */ + u_int8_t th_flags; + u_int16_t th_win; /* window */ + u_int16_t th_sum; /* checksum */ + u_int16_t th_urp; /* urgent pointer */ +}; + +#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) + +/* TCP flags */ +#define TH_FIN 0x01 +#define TH_SYN 0x02 +#define TH_RST 0x04 +#define TH_PUSH 0x08 +#define TH_ACK 0x10 +#define TH_URG 0x20 +#define TH_ECNECHO 0x40 /* ECN Echo */ +#define TH_CWR 0x80 /* ECN Cwnd Reduced */ + + +#define TCPOPT_EOL 0 +#define TCPOPT_NOP 1 +#define TCPOPT_MAXSEG 2 +#define TCPOLEN_MAXSEG 4 +#define TCPOPT_WSCALE 3 /* window scale factor (rfc1323) */ +#define TCPOPT_SACKOK 4 /* selective ack ok (rfc2018) */ +#define TCPOPT_SACK 5 /* selective ack (rfc2018) */ +#define TCPOPT_ECHO 6 /* echo (rfc1072) */ +#define TCPOPT_ECHOREPLY 7 /* echo (rfc1072) */ +#define TCPOPT_TIMESTAMP 8 /* timestamp (rfc1323) */ +#define TCPOLEN_TIMESTAMP 10 +#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ +#define TCPOPT_CC 11 /* T/TCP CC options (rfc1644) */ +#define TCPOPT_CCNEW 12 /* T/TCP CC options (rfc1644) */ +#define TCPOPT_CCECHO 13 /* T/TCP CC options (rfc1644) */ +#define TCPOPT_SIGNATURE 19 /* Keyed MD5 (rfc2385) */ +#define TCPOLEN_SIGNATURE 18 +#define TCP_SIGLEN 16 /* length of an option 19 digest */ +#define TCPOPT_AUTH 20 /* Enhanced AUTH option */ +#define TCPOPT_UTO 28 /* tcp user timeout (rfc5482) */ +#define TCPOLEN_UTO 4 + + +#define TCPOPT_TSTAMP_HDR \ + (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) + +#ifndef TELNET_PORT +#define TELNET_PORT 23 +#endif +#ifndef BGP_PORT +#define BGP_PORT 179 +#endif +#define NETBIOS_SSN_PORT 139 +#ifndef PPTP_PORT +#define PPTP_PORT 1723 +#endif +#define BEEP_PORT 10288 +#ifndef NFS_PORT +#define NFS_PORT 2049 +#endif +#define MSDP_PORT 639 +#define LDP_PORT 646 +#ifndef SMB_PORT +#define SMB_PORT 445 +#endif diff --git a/tcpdump-stdinc.h b/tcpdump-stdinc.h new file mode 100644 index 0000000..c437cc1 --- /dev/null +++ b/tcpdump-stdinc.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * @(#) $Header: /tcpdump/master/tcpdump/tcpdump-stdinc.h,v 1.18 2007-11-24 18:13:33 mcr Exp $ (LBL) + */ + +/* + * Include the appropriate OS header files on Windows and various flavors + * of UNIX, and also define some additional items and include various + * non-OS header files on Windows, and; this isolates most of the platform + * differences to this one file. + */ + +#ifndef tcpdump_stdinc_h +#define tcpdump_stdinc_h + +#ifdef WIN32 + +#include +#include +#include +#include "bittypes.h" +#include +#include +#include +#include +#include +#include /* in wpcap's Win32/include */ + +#ifndef NBBY +#define NBBY 8 +#endif + +#if !defined(__MINGW32__) && !defined(__WATCOMC__) +#undef toascii +#define isascii __isascii +#define toascii __toascii +#define stat _stat +#define open _open +#define fstat _fstat +#define read _read +#define close _close +#define O_RDONLY _O_RDONLY + +typedef short ino_t; +#endif /* __MINGW32__ */ + +#ifdef __MINGW32__ +#include +#endif + +/* Protos for missing/x.c functions (ideally + * should be used, but it clashes with ). + */ +extern const char *inet_ntop (int, const void *, char *, size_t); +extern int inet_pton (int, const char *, void *); +extern int inet_aton (const char *cp, struct in_addr *addr); + +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN 46 +#endif + +#ifndef toascii +#define toascii(c) ((c) & 0x7f) +#endif + +#ifndef caddr_t +typedef char* caddr_t; +#endif /* caddr_t */ + +#define MAXHOSTNAMELEN 64 +#define NI_MAXHOST 1025 +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#define RETSIGTYPE void + +#else /* WIN32 */ + +#include +#include +#include +#if HAVE_INTTYPES_H +#include +#else +#if HAVE_STDINT_H +#include +#endif +#endif +#ifdef HAVE_SYS_BITYPES_H +#include +#endif +#include +#include /* concession to AIX */ +#include +#include +#include + +#ifdef TIME_WITH_SYS_TIME +#include +#endif + +#include + +#endif /* WIN32 */ + +#ifdef INET6 +#include "ip6.h" +#endif + +#if defined(WIN32) || defined(MSDOS) + #define FOPEN_READ_TXT "rt" + #define FOPEN_READ_BIN "rb" + #define FOPEN_WRITE_TXT "wt" + #define FOPEN_WRITE_BIN "wb" +#else + #define FOPEN_READ_TXT "r" + #define FOPEN_READ_BIN FOPEN_READ_TXT + #define FOPEN_WRITE_TXT "w" + #define FOPEN_WRITE_BIN FOPEN_WRITE_TXT +#endif + +#if defined(__GNUC__) && defined(__i386__) && !defined(__ntohl) + #undef ntohl + #undef ntohs + #undef htonl + #undef htons + + static __inline__ unsigned long __ntohl (unsigned long x); + static __inline__ unsigned short __ntohs (unsigned short x); + + #define ntohl(x) __ntohl(x) + #define ntohs(x) __ntohs(x) + #define htonl(x) __ntohl(x) + #define htons(x) __ntohs(x) + + static __inline__ unsigned long __ntohl (unsigned long x) + { + __asm__ ("xchgb %b0, %h0\n\t" /* swap lower bytes */ + "rorl $16, %0\n\t" /* swap words */ + "xchgb %b0, %h0" /* swap higher bytes */ + : "=q" (x) : "0" (x)); + return (x); + } + + static __inline__ unsigned short __ntohs (unsigned short x) + { + __asm__ ("xchgb %b0, %h0" /* swap bytes */ + : "=q" (x) : "0" (x)); + return (x); + } +#endif + +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#endif /* tcpdump_stdinc_h */ diff --git a/tcpdump.1.in b/tcpdump.1.in new file mode 100644 index 0000000..5e1a00f --- /dev/null +++ b/tcpdump.1.in @@ -0,0 +1,1721 @@ +.\" @(#) $Header: /tcpdump/master/tcpdump/tcpdump.1.in,v 1.2 2008-11-09 23:35:03 mcr Exp $ (LBL) +.\" +.\" $NetBSD: tcpdump.8,v 1.9 2003/03/31 00:18:17 perry Exp $ +.\" +.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997 +.\" The Regents of the University of California. All rights reserved. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that: (1) source code distributions +.\" retain the above copyright notice and this paragraph in its entirety, (2) +.\" distributions including binary code include the above copyright notice and +.\" this paragraph in its entirety in the documentation or other materials +.\" provided with the distribution, and (3) all advertising materials mentioning +.\" features or use of this software display the following acknowledgement: +.\" ``This product includes software developed by the University of California, +.\" Lawrence Berkeley Laboratory and its contributors.'' Neither the name of +.\" the University nor the names of its contributors may be used to endorse +.\" or promote products derived from this software without specific prior +.\" written permission. +.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +.\" +.TH TCPDUMP 1 "05 March 2009" +.SH NAME +tcpdump \- dump traffic on a network +.SH SYNOPSIS +.na +.B tcpdump +[ +.B \-AbdDefIKlLnNOpqRStuUvxX +] [ +.B \-B +.I buffer_size +] [ +.B \-c +.I count +] +.br +.ti +8 +[ +.B \-C +.I file_size +] [ +.B \-G +.I rotate_seconds +] [ +.B \-F +.I file +] +.br +.ti +8 +[ +.B \-i +.I interface +] +[ +.B \-m +.I module +] +[ +.B \-M +.I secret +] +.br +.ti +8 +[ +.B \-r +.I file +] +[ +.B \-s +.I snaplen +] +[ +.B \-T +.I type +] +[ +.B \-w +.I file +] +.br +.ti +8 +[ +.B \-W +.I filecount +] +.br +.ti +8 +[ +.B \-E +.I spi@ipaddr algo:secret,... +] +.br +.ti +8 +[ +.B \-y +.I datalinktype +] +[ +.B \-z +.I postrotate-command +] +[ +.B \-Z +.I user +] +.ti +8 +[ +.I expression +] +.br +.ad +.SH DESCRIPTION +.LP +\fITcpdump\fP prints out a description of the contents of packets on a +network interface that match the boolean \fIexpression\fP. It can also +be run with the +.B \-w +flag, which causes it to save the packet data to a file for later +analysis, and/or with the +.B \-r +flag, which causes it to read from a saved packet file rather than to +read packets from a network interface. In all cases, only packets that +match +.I expression +will be processed by +.IR tcpdump . +.LP +.I Tcpdump +will, if not run with the +.B \-c +flag, continue capturing packets until it is interrupted by a SIGINT +signal (generated, for example, by typing your interrupt character, +typically control-C) or a SIGTERM signal (typically generated with the +.BR kill (1) +command); if run with the +.B \-c +flag, it will capture packets until it is interrupted by a SIGINT or +SIGTERM signal or the specified number of packets have been processed. +.LP +When +.I tcpdump +finishes capturing packets, it will report counts of: +.IP +packets ``captured'' (this is the number of packets that +.I tcpdump +has received and processed); +.IP +packets ``received by filter'' (the meaning of this depends on the OS on +which you're running +.IR tcpdump , +and possibly on the way the OS was configured - if a filter was +specified on the command line, on some OSes it counts packets regardless +of whether they were matched by the filter expression and, even if they +were matched by the filter expression, regardless of whether +.I tcpdump +has read and processed them yet, on other OSes it counts only packets that were +matched by the filter expression regardless of whether +.I tcpdump +has read and processed them yet, and on other OSes it counts only +packets that were matched by the filter expression and were processed by +.IR tcpdump ); +.IP +packets ``dropped by kernel'' (this is the number of packets that were +dropped, due to a lack of buffer space, by the packet capture mechanism +in the OS on which +.I tcpdump +is running, if the OS reports that information to applications; if not, +it will be reported as 0). +.LP +On platforms that support the SIGINFO signal, such as most BSDs +(including Mac OS X) and Digital/Tru64 UNIX, it will report those counts +when it receives a SIGINFO signal (generated, for example, by typing +your ``status'' character, typically control-T, although on some +platforms, such as Mac OS X, the ``status'' character is not set by +default, so you must set it with +.BR stty (1) +in order to use it) and will continue capturing packets. +.LP +Reading packets from a network interface may require that you have +special privileges; see the +.B pcap (3PCAP) +man page for details. Reading a saved packet file doesn't require +special privileges. +.SH OPTIONS +.TP +.B \-A +Print each packet (minus its link level header) in ASCII. Handy for +capturing web pages. +.TP +.B \-b +Print the AS number in BGP packets in ASDOT notation rather than ASPLAIN +notation. +.TP +.B \-B +Set the operating system capture buffer size to \fIbuffer_size\fP. +.TP +.B \-c +Exit after receiving \fIcount\fP packets. +.TP +.B \-C +Before writing a raw packet to a savefile, check whether the file is +currently larger than \fIfile_size\fP and, if so, close the current +savefile and open a new one. Savefiles after the first savefile will +have the name specified with the +.B \-w +flag, with a number after it, starting at 1 and continuing upward. +The units of \fIfile_size\fP are millions of bytes (1,000,000 bytes, +not 1,048,576 bytes). +.TP +.B \-d +Dump the compiled packet-matching code in a human readable form to +standard output and stop. +.TP +.B \-dd +Dump packet-matching code as a +.B C +program fragment. +.TP +.B \-ddd +Dump packet-matching code as decimal numbers (preceded with a count). +.TP +.B \-D +Print the list of the network interfaces available on the system and on +which +.I tcpdump +can capture packets. For each network interface, a number and an +interface name, possibly followed by a text description of the +interface, is printed. The interface name or the number can be supplied +to the +.B \-i +flag to specify an interface on which to capture. +.IP +This can be useful on systems that don't have a command to list them +(e.g., Windows systems, or UNIX systems lacking +.BR "ifconfig \-a" ); +the number can be useful on Windows 2000 and later systems, where the +interface name is a somewhat complex string. +.IP +The +.B \-D +flag will not be supported if +.I tcpdump +was built with an older version of +.I libpcap +that lacks the +.B pcap_findalldevs() +function. +.TP +.B \-e +Print the link-level header on each dump line. +.TP +.B \-E +Use \fIspi@ipaddr algo:secret\fP for decrypting IPsec ESP packets that +are addressed to \fIaddr\fP and contain Security Parameter Index value +\fIspi\fP. This combination may be repeated with comma or newline seperation. +.IP +Note that setting the secret for IPv4 ESP packets is supported at this time. +.IP +Algorithms may be +\fBdes-cbc\fP, +\fB3des-cbc\fP, +\fBblowfish-cbc\fP, +\fBrc3-cbc\fP, +\fBcast128-cbc\fP, or +\fBnone\fP. +The default is \fBdes-cbc\fP. +The ability to decrypt packets is only present if \fItcpdump\fP was compiled +with cryptography enabled. +.IP +\fIsecret\fP is the ASCII text for ESP secret key. +If preceeded by 0x, then a hex value will be read. +.IP +The option assumes RFC2406 ESP, not RFC1827 ESP. +The option is only for debugging purposes, and +the use of this option with a true `secret' key is discouraged. +By presenting IPsec secret key onto command line +you make it visible to others, via +.IR ps (1) +and other occasions. +.IP +In addition to the above syntax, the syntax \fIfile name\fP may be used +to have tcpdump read the provided file in. The file is opened upon +receiving the first ESP packet, so any special permissions that tcpdump +may have been given should already have been given up. +.TP +.B \-f +Print `foreign' IPv4 addresses numerically rather than symbolically +(this option is intended to get around serious brain damage in +Sun's NIS server \(em usually it hangs forever translating non-local +internet numbers). +.IP +The test for `foreign' IPv4 addresses is done using the IPv4 address and +netmask of the interface on which capture is being done. If that +address or netmask are not available, available, either because the +interface on which capture is being done has no address or netmask or +because the capture is being done on the Linux "any" interface, which +can capture on more than one interface, this option will not work +correctly. +.TP +.B \-F +Use \fIfile\fP as input for the filter expression. +An additional expression given on the command line is ignored. +.TP +.B \-G +If specified, rotates the dump file specified with the +.B \-w +option every \fIrotate_seconds\fP seconds. +Savefiles will have the name specified by +.B \-w +which should include a time format as defined by +.BR strftime (3). +If no time format is specified, each new file will overwrite the previous. +.IP +If used in conjunction with the +.B \-C +option, filenames will take the form of `\fIfile\fP'. +.TP +.B \-i +Listen on \fIinterface\fP. +If unspecified, \fItcpdump\fP searches the system interface list for the +lowest numbered, configured up interface (excluding loopback). +Ties are broken by choosing the earliest match. +.IP +On Linux systems with 2.2 or later kernels, an +.I interface +argument of ``any'' can be used to capture packets from all interfaces. +Note that captures on the ``any'' device will not be done in promiscuous +mode. +.IP +If the +.B \-D +flag is supported, an interface number as printed by that flag can be +used as the +.I interface +argument. +.TP +.B \-I +Put the interface in "monitor mode"; this is supported only on IEEE +802.11 Wi-Fi interfaces, and supported only on some operating systems. +.IP +Note that in monitor mode the adapter might disassociate from the +network with which it's associated, so that you will not be able to use +any wireless networks with that adapter. This could prevent accessing +files on a network server, or resolving host names or network addresses, +if you are capturing in monitor mode and are not connected to another +network with another adapter. +.IP +This flag will affect the output of the +.B \-L +flag. If +.B \-I +isn't specified, only those link-layer types available when not in +monitor mode will be shown; if +.B \-I +is specified, only those link-layer types available when in monitor mode +will be shown. +.TP +.B \-K +Don't attempt to verify IP, TCP, or UDP checksums. This is useful for +interfaces that perform some or all of those checksum calculation in +hardware; otherwise, all outgoing TCP checksums will be flagged as bad. +.TP +.B \-l +Make stdout line buffered. +Useful if you want to see the data +while capturing it. +E.g., +.br +``tcpdump\ \ \-l\ \ |\ \ tee dat'' or +``tcpdump\ \ \-l \ \ > dat\ \ &\ \ tail\ \ \-f\ \ dat''. +.TP +.B \-L +List the known data link types for the interface, in the specified mode, +and exit. The list of known data link types may be dependent on the +specified mode; for example, on some platforms, a Wi-Fi interface might +support one set of data link types when not in monitor mode (for +example, it might support only fake Ethernet headers, or might support +802.11 headers but not support 802.11 headers with radio information) +and another set of data link types when in monitor mode (for example, it +might support 802.11 headers, or 802.11 headers with radio information, +only in monitor mode). +.TP +.B \-m +Load SMI MIB module definitions from file \fImodule\fR. +This option +can be used several times to load several MIB modules into \fItcpdump\fP. +.TP +.B \-M +Use \fIsecret\fP as a shared secret for validating the digests found in +TCP segments with the TCP-MD5 option (RFC 2385), if present. +.TP +.B \-n +Don't convert addresses (i.e., host addresses, port numbers, etc.) to names. +.TP +.B \-N +Don't print domain name qualification of host names. +E.g., +if you give this flag then \fItcpdump\fP will print ``nic'' +instead of ``nic.ddn.mil''. +.TP +.B \-O +Do not run the packet-matching code optimizer. +This is useful only +if you suspect a bug in the optimizer. +.TP +.B \-p +\fIDon't\fP put the interface +into promiscuous mode. +Note that the interface might be in promiscuous +mode for some other reason; hence, `-p' cannot be used as an abbreviation for +`ether host {local-hw-addr} or ether broadcast'. +.TP +.B \-q +Quick (quiet?) output. +Print less protocol information so output +lines are shorter. +.TP +.B \-R +Assume ESP/AH packets to be based on old specification (RFC1825 to RFC1829). +If specified, \fItcpdump\fP will not print replay prevention field. +Since there is no protocol version field in ESP/AH specification, +\fItcpdump\fP cannot deduce the version of ESP/AH protocol. +.TP +.B \-r +Read packets from \fIfile\fR (which was created with the +.B \-w +option). +Standard input is used if \fIfile\fR is ``-''. +.TP +.B \-S +Print absolute, rather than relative, TCP sequence numbers. +.TP +.B \-s +Snarf \fIsnaplen\fP bytes of data from each packet rather than the +default of 65535 bytes. +Packets truncated because of a limited snapshot +are indicated in the output with ``[|\fIproto\fP]'', where \fIproto\fP +is the name of the protocol level at which the truncation has occurred. +Note that taking larger snapshots both increases +the amount of time it takes to process packets and, effectively, +decreases the amount of packet buffering. +This may cause packets to be +lost. +You should limit \fIsnaplen\fP to the smallest number that will +capture the protocol information you're interested in. +Setting +\fIsnaplen\fP to 0 sets it to the default of 65535, +for backwards compatibility with recent older versions of +.IR tcpdump . +.TP +.B \-T +Force packets selected by "\fIexpression\fP" to be interpreted the +specified \fItype\fR. +Currently known types are +\fBaodv\fR (Ad-hoc On-demand Distance Vector protocol), +\fBcnfp\fR (Cisco NetFlow protocol), +\fBrpc\fR (Remote Procedure Call), +\fBrtp\fR (Real-Time Applications protocol), +\fBrtcp\fR (Real-Time Applications control protocol), +\fBsnmp\fR (Simple Network Management Protocol), +\fBtftp\fR (Trivial File Transfer Protocol), +\fBvat\fR (Visual Audio Tool), +and +\fBwb\fR (distributed White Board). +.TP +.B \-t +\fIDon't\fP print a timestamp on each dump line. +.TP +.B \-tt +Print an unformatted timestamp on each dump line. +.TP +.B \-ttt +Print a delta (micro-second resolution) between current and previous line +on each dump line. +.TP +.B \-tttt +Print a timestamp in default format proceeded by date on each dump line. +.TP +.B \-ttttt +Print a delta (micro-second resolution) between current and first line +on each dump line. +.TP +.B \-u +Print undecoded NFS handles. +.TP +.B \-U +Make output saved via the +.B \-w +option ``packet-buffered''; i.e., as each packet is saved, it will be +written to the output file, rather than being written only when the +output buffer fills. +.IP +The +.B \-U +flag will not be supported if +.I tcpdump +was built with an older version of +.I libpcap +that lacks the +.B pcap_dump_flush() +function. +.TP +.B \-v +When parsing and printing, produce (slightly more) verbose output. +For example, the time to live, +identification, total length and options in an IP packet are printed. +Also enables additional packet integrity checks such as verifying the +IP and ICMP header checksum. +.IP +When writing to a file with the +.B \-w +option, report, every 10 seconds, the number of packets captured. +.TP +.B \-vv +Even more verbose output. +For example, additional fields are +printed from NFS reply packets, and SMB packets are fully decoded. +.TP +.B \-vvv +Even more verbose output. +For example, +telnet \fBSB\fP ... \fBSE\fP options +are printed in full. +With +.B \-X +Telnet options are printed in hex as well. +.TP +.B \-w +Write the raw packets to \fIfile\fR rather than parsing and printing +them out. +They can later be printed with the \-r option. +Standard output is used if \fIfile\fR is ``-''. +See +.BR pcap-savefile (@MAN_FILE_FORMATS@) +for a description of the file format. +.TP +.B \-W +Used in conjunction with the +.B \-C +option, this will limit the number +of files created to the specified number, and begin overwriting files +from the beginning, thus creating a 'rotating' buffer. +In addition, it will name +the files with enough leading 0s to support the maximum number of +files, allowing them to sort correctly. +.IP +Used in conjunction with the +.B \-G +option, this will limit the number of rotated dump files that get +created, exiting with status 0 when reaching the limit. If used with +.B \-C +as well, the behavior will result in cyclical files per timeslice. +.TP +.B \-x +When parsing and printing, +in addition to printing the headers of each packet, print the data of +each packet (minus its link level header) in hex. +The smaller of the entire packet or +.I snaplen +bytes will be printed. Note that this is the entire link-layer +packet, so for link layers that pad (e.g. Ethernet), the padding bytes +will also be printed when the higher layer packet is shorter than the +required padding. +.TP +.B \-xx +When parsing and printing, +in addition to printing the headers of each packet, print the data of +each packet, +.I including +its link level header, in hex. +.TP +.B \-X +When parsing and printing, +in addition to printing the headers of each packet, print the data of +each packet (minus its link level header) in hex and ASCII. +This is very handy for analysing new protocols. +.TP +.B \-XX +When parsing and printing, +in addition to printing the headers of each packet, print the data of +each packet, +.I including +its link level header, in hex and ASCII. +.TP +.B \-y +Set the data link type to use while capturing packets to \fIdatalinktype\fP. +.TP +.B \-z +Used in conjunction with the +.B -C +or +.B -G +options, this will make +.I tcpdump +run " +.I command file +" where +.I file +is the savefile being closed after each rotation. For example, specifying +.B \-z gzip +or +.B \-z bzip2 +will compress each savefile using gzip or bzip2. +.IP +Note that tcpdump will run the command in parallel to the capture, using +the lowest priority so that this doesn't disturb the capture process. +.IP +And in case you would like to use a command that itself takes flags or +different arguments, you can always write a shell script that will take the +savefile name as the only argument, make the flags & arguments arrangements +and execute the command that you want. +.TP +.B \-Z +Drops privileges (if root) and changes user ID to +.I user +and the group ID to the primary group of +.IR user . +.IP +This behavior can also be enabled by default at compile time. +.IP "\fI expression\fP" +.RS +selects which packets will be dumped. +If no \fIexpression\fP +is given, all packets on the net will be dumped. +Otherwise, +only packets for which \fIexpression\fP is `true' will be dumped. +.LP +For the \fIexpression\fP syntax, see +.BR pcap-filter (@MAN_MISC_INFO@). +.LP +Expression arguments can be passed to \fItcpdump\fP as either a single +argument or as multiple arguments, whichever is more convenient. +Generally, if the expression contains Shell metacharacters, it is +easier to pass it as a single, quoted argument. +Multiple arguments are concatenated with spaces before being parsed. +.SH EXAMPLES +.LP +To print all packets arriving at or departing from \fIsundown\fP: +.RS +.nf +\fBtcpdump host sundown\fP +.fi +.RE +.LP +To print traffic between \fIhelios\fR and either \fIhot\fR or \fIace\fR: +.RS +.nf +\fBtcpdump host helios and \\( hot or ace \\)\fP +.fi +.RE +.LP +To print all IP packets between \fIace\fR and any host except \fIhelios\fR: +.RS +.nf +\fBtcpdump ip host ace and not helios\fP +.fi +.RE +.LP +To print all traffic between local hosts and hosts at Berkeley: +.RS +.nf +.B +tcpdump net ucb-ether +.fi +.RE +.LP +To print all ftp traffic through internet gateway \fIsnup\fP: +(note that the expression is quoted to prevent the shell from +(mis-)interpreting the parentheses): +.RS +.nf +.B +tcpdump 'gateway snup and (port ftp or ftp-data)' +.fi +.RE +.LP +To print traffic neither sourced from nor destined for local hosts +(if you gateway to one other net, this stuff should never make it +onto your local net). +.RS +.nf +.B +tcpdump ip and not net \fIlocalnet\fP +.fi +.RE +.LP +To print the start and end packets (the SYN and FIN packets) of each +TCP conversation that involves a non-local host. +.RS +.nf +.B +tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net \fIlocalnet\fP' +.fi +.RE +.LP +To print all IPv4 HTTP packets to and from port 80, i.e. print only +packets that contain data, not, for example, SYN and FIN packets and +ACK-only packets. (IPv6 is left as an exercise for the reader.) +.RS +.nf +.B +tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' +.fi +.RE +.LP +To print IP packets longer than 576 bytes sent through gateway \fIsnup\fP: +.RS +.nf +.B +tcpdump 'gateway snup and ip[2:2] > 576' +.fi +.RE +.LP +To print IP broadcast or multicast packets that were +.I not +sent via Ethernet broadcast or multicast: +.RS +.nf +.B +tcpdump 'ether[0] & 1 = 0 and ip[16] >= 224' +.fi +.RE +.LP +To print all ICMP packets that are not echo requests/replies (i.e., not +ping packets): +.RS +.nf +.B +tcpdump 'icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply' +.fi +.RE +.SH OUTPUT FORMAT +.LP +The output of \fItcpdump\fP is protocol dependent. +The following +gives a brief description and examples of most of the formats. +.de HD +.sp 1.5 +.B +.. +.HD +Link Level Headers +.LP +If the '-e' option is given, the link level header is printed out. +On Ethernets, the source and destination addresses, protocol, +and packet length are printed. +.LP +On FDDI networks, the '-e' option causes \fItcpdump\fP to print +the `frame control' field, the source and destination addresses, +and the packet length. +(The `frame control' field governs the +interpretation of the rest of the packet. +Normal packets (such +as those containing IP datagrams) are `async' packets, with a priority +value between 0 and 7; for example, `\fBasync4\fR'. +Such packets +are assumed to contain an 802.2 Logical Link Control (LLC) packet; +the LLC header is printed if it is \fInot\fR an ISO datagram or a +so-called SNAP packet. +.LP +On Token Ring networks, the '-e' option causes \fItcpdump\fP to print +the `access control' and `frame control' fields, the source and +destination addresses, and the packet length. +As on FDDI networks, +packets are assumed to contain an LLC packet. +Regardless of whether +the '-e' option is specified or not, the source routing information is +printed for source-routed packets. +.LP +On 802.11 networks, the '-e' option causes \fItcpdump\fP to print +the `frame control' fields, all of the addresses in the 802.11 header, +and the packet length. +As on FDDI networks, +packets are assumed to contain an LLC packet. +.LP +\fI(N.B.: The following description assumes familiarity with +the SLIP compression algorithm described in RFC-1144.)\fP +.LP +On SLIP links, a direction indicator (``I'' for inbound, ``O'' for outbound), +packet type, and compression information are printed out. +The packet type is printed first. +The three types are \fIip\fP, \fIutcp\fP, and \fIctcp\fP. +No further link information is printed for \fIip\fR packets. +For TCP packets, the connection identifier is printed following the type. +If the packet is compressed, its encoded header is printed out. +The special cases are printed out as +\fB*S+\fIn\fR and \fB*SA+\fIn\fR, where \fIn\fR is the amount by which +the sequence number (or sequence number and ack) has changed. +If it is not a special case, +zero or more changes are printed. +A change is indicated by U (urgent pointer), W (window), A (ack), +S (sequence number), and I (packet ID), followed by a delta (+n or -n), +or a new value (=n). +Finally, the amount of data in the packet and compressed header length +are printed. +.LP +For example, the following line shows an outbound compressed TCP packet, +with an implicit connection identifier; the ack has changed by 6, +the sequence number by 49, and the packet ID by 6; there are 3 bytes of +data and 6 bytes of compressed header: +.RS +.nf +\fBO ctcp * A+6 S+49 I+6 3 (6)\fP +.fi +.RE +.HD +ARP/RARP Packets +.LP +Arp/rarp output shows the type of request and its arguments. +The +format is intended to be self explanatory. +Here is a short sample taken from the start of an `rlogin' from +host \fIrtsg\fP to host \fIcsam\fP: +.RS +.nf +.sp .5 +\f(CWarp who-has csam tell rtsg +arp reply csam is-at CSAM\fR +.sp .5 +.fi +.RE +The first line says that rtsg sent an arp packet asking +for the Ethernet address of internet host csam. +Csam +replies with its Ethernet address (in this example, Ethernet addresses +are in caps and internet addresses in lower case). +.LP +This would look less redundant if we had done \fItcpdump \-n\fP: +.RS +.nf +.sp .5 +\f(CWarp who-has 128.3.254.6 tell 128.3.254.68 +arp reply 128.3.254.6 is-at 02:07:01:00:01:c4\fP +.fi +.RE +.LP +If we had done \fItcpdump \-e\fP, the fact that the first packet is +broadcast and the second is point-to-point would be visible: +.RS +.nf +.sp .5 +\f(CWRTSG Broadcast 0806 64: arp who-has csam tell rtsg +CSAM RTSG 0806 64: arp reply csam is-at CSAM\fR +.sp .5 +.fi +.RE +For the first packet this says the Ethernet source address is RTSG, the +destination is the Ethernet broadcast address, the type field +contained hex 0806 (type ETHER_ARP) and the total length was 64 bytes. +.HD +TCP Packets +.LP +\fI(N.B.:The following description assumes familiarity with +the TCP protocol described in RFC-793. +If you are not familiar +with the protocol, neither this description nor \fItcpdump\fP will +be of much use to you.)\fP +.LP +The general format of a tcp protocol line is: +.RS +.nf +.sp .5 +\fIsrc > dst: flags data-seqno ack window urgent options\fP +.sp .5 +.fi +.RE +\fISrc\fP and \fIdst\fP are the source and destination IP +addresses and ports. +\fIFlags\fP are some combination of S (SYN), +F (FIN), P (PUSH), R (RST), W (ECN CWR) or E (ECN-Echo), or a single +`.' (no flags). +\fIData-seqno\fP describes the portion of sequence space covered +by the data in this packet (see example below). +\fIAck\fP is sequence number of the next data expected the other +direction on this connection. +\fIWindow\fP is the number of bytes of receive buffer space available +the other direction on this connection. +\fIUrg\fP indicates there is `urgent' data in the packet. +\fIOptions\fP are tcp options enclosed in angle brackets (e.g., ). +.LP +\fISrc, dst\fP and \fIflags\fP are always present. +The other fields +depend on the contents of the packet's tcp protocol header and +are output only if appropriate. +.LP +Here is the opening portion of an rlogin from host \fIrtsg\fP to +host \fIcsam\fP. +.RS +.nf +.sp .5 +\s-2\f(CWrtsg.1023 > csam.login: S 768512:768512(0) win 4096 +csam.login > rtsg.1023: S 947648:947648(0) ack 768513 win 4096 +rtsg.1023 > csam.login: . ack 1 win 4096 +rtsg.1023 > csam.login: P 1:2(1) ack 1 win 4096 +csam.login > rtsg.1023: . ack 2 win 4096 +rtsg.1023 > csam.login: P 2:21(19) ack 1 win 4096 +csam.login > rtsg.1023: P 1:2(1) ack 21 win 4077 +csam.login > rtsg.1023: P 2:3(1) ack 21 win 4077 urg 1 +csam.login > rtsg.1023: P 3:4(1) ack 21 win 4077 urg 1\fR\s+2 +.sp .5 +.fi +.RE +The first line says that tcp port 1023 on rtsg sent a packet +to port \fIlogin\fP +on csam. +The \fBS\fP indicates that the \fISYN\fP flag was set. +The packet sequence number was 768512 and it contained no data. +(The notation is `first:last(nbytes)' which means `sequence +numbers \fIfirst\fP +up to but not including \fIlast\fP which is \fInbytes\fP bytes of user data'.) +There was no piggy-backed ack, the available receive window was 4096 +bytes and there was a max-segment-size option requesting an mss of +1024 bytes. +.LP +Csam replies with a similar packet except it includes a piggy-backed +ack for rtsg's SYN. +Rtsg then acks csam's SYN. +The `.' means no +flags were set. +The packet contained no data so there is no data sequence number. +Note that the ack sequence +number is a small integer (1). +The first time \fItcpdump\fP sees a +tcp `conversation', it prints the sequence number from the packet. +On subsequent packets of the conversation, the difference between +the current packet's sequence number and this initial sequence number +is printed. +This means that sequence numbers after the +first can be interpreted +as relative byte positions in the conversation's data stream (with the +first data byte each direction being `1'). +`-S' will override this +feature, causing the original sequence numbers to be output. +.LP +On the 6th line, rtsg sends csam 19 bytes of data (bytes 2 through 20 +in the rtsg \(-> csam side of the conversation). +The PUSH flag is set in the packet. +On the 7th line, csam says it's received data sent by rtsg up to +but not including byte 21. +Most of this data is apparently sitting in the +socket buffer since csam's receive window has gotten 19 bytes smaller. +Csam also sends one byte of data to rtsg in this packet. +On the 8th and 9th lines, +csam sends two bytes of urgent, pushed data to rtsg. +.LP +If the snapshot was small enough that \fItcpdump\fP didn't capture +the full TCP header, it interprets as much of the header as it can +and then reports ``[|\fItcp\fP]'' to indicate the remainder could not +be interpreted. +If the header contains a bogus option (one with a length +that's either too small or beyond the end of the header), \fItcpdump\fP +reports it as ``[\fIbad opt\fP]'' and does not interpret any further +options (since it's impossible to tell where they start). +If the header +length indicates options are present but the IP datagram length is not +long enough for the options to actually be there, \fItcpdump\fP reports +it as ``[\fIbad hdr length\fP]''. +.HD +.B Capturing TCP packets with particular flag combinations (SYN-ACK, URG-ACK, etc.) +.PP +There are 8 bits in the control bits section of the TCP header: +.IP +.I CWR | ECE | URG | ACK | PSH | RST | SYN | FIN +.PP +Let's assume that we want to watch packets used in establishing +a TCP connection. +Recall that TCP uses a 3-way handshake protocol +when it initializes a new connection; the connection sequence with +regard to the TCP control bits is +.PP +.RS +1) Caller sends SYN +.RE +.RS +2) Recipient responds with SYN, ACK +.RE +.RS +3) Caller sends ACK +.RE +.PP +Now we're interested in capturing packets that have only the +SYN bit set (Step 1). +Note that we don't want packets from step 2 +(SYN-ACK), just a plain initial SYN. +What we need is a correct filter +expression for \fItcpdump\fP. +.PP +Recall the structure of a TCP header without options: +.PP +.nf + 0 15 31 +----------------------------------------------------------------- +| source port | destination port | +----------------------------------------------------------------- +| sequence number | +----------------------------------------------------------------- +| acknowledgment number | +----------------------------------------------------------------- +| HL | rsvd |C|E|U|A|P|R|S|F| window size | +----------------------------------------------------------------- +| TCP checksum | urgent pointer | +----------------------------------------------------------------- +.fi +.PP +A TCP header usually holds 20 octets of data, unless options are +present. +The first line of the graph contains octets 0 - 3, the +second line shows octets 4 - 7 etc. +.PP +Starting to count with 0, the relevant TCP control bits are contained +in octet 13: +.PP +.nf + 0 7| 15| 23| 31 +----------------|---------------|---------------|---------------- +| HL | rsvd |C|E|U|A|P|R|S|F| window size | +----------------|---------------|---------------|---------------- +| | 13th octet | | | +.fi +.PP +Let's have a closer look at octet no. 13: +.PP +.nf + | | + |---------------| + |C|E|U|A|P|R|S|F| + |---------------| + |7 5 3 0| +.fi +.PP +These are the TCP control bits we are interested +in. +We have numbered the bits in this octet from 0 to 7, right to +left, so the PSH bit is bit number 3, while the URG bit is number 5. +.PP +Recall that we want to capture packets with only SYN set. +Let's see what happens to octet 13 if a TCP datagram arrives +with the SYN bit set in its header: +.PP +.nf + |C|E|U|A|P|R|S|F| + |---------------| + |0 0 0 0 0 0 1 0| + |---------------| + |7 6 5 4 3 2 1 0| +.fi +.PP +Looking at the +control bits section we see that only bit number 1 (SYN) is set. +.PP +Assuming that octet number 13 is an 8-bit unsigned integer in +network byte order, the binary value of this octet is +.IP +00000010 +.PP +and its decimal representation is +.PP +.nf + 7 6 5 4 3 2 1 0 +0*2 + 0*2 + 0*2 + 0*2 + 0*2 + 0*2 + 1*2 + 0*2 = 2 +.fi +.PP +We're almost done, because now we know that if only SYN is set, +the value of the 13th octet in the TCP header, when interpreted +as a 8-bit unsigned integer in network byte order, must be exactly 2. +.PP +This relationship can be expressed as +.RS +.B +tcp[13] == 2 +.RE +.PP +We can use this expression as the filter for \fItcpdump\fP in order +to watch packets which have only SYN set: +.RS +.B +tcpdump -i xl0 tcp[13] == 2 +.RE +.PP +The expression says "let the 13th octet of a TCP datagram have +the decimal value 2", which is exactly what we want. +.PP +Now, let's assume that we need to capture SYN packets, but we +don't care if ACK or any other TCP control bit is set at the +same time. +Let's see what happens to octet 13 when a TCP datagram +with SYN-ACK set arrives: +.PP +.nf + |C|E|U|A|P|R|S|F| + |---------------| + |0 0 0 1 0 0 1 0| + |---------------| + |7 6 5 4 3 2 1 0| +.fi +.PP +Now bits 1 and 4 are set in the 13th octet. +The binary value of +octet 13 is +.IP + 00010010 +.PP +which translates to decimal +.PP +.nf + 7 6 5 4 3 2 1 0 +0*2 + 0*2 + 0*2 + 1*2 + 0*2 + 0*2 + 1*2 + 0*2 = 18 +.fi +.PP +Now we can't just use 'tcp[13] == 18' in the \fItcpdump\fP filter +expression, because that would select only those packets that have +SYN-ACK set, but not those with only SYN set. +Remember that we don't care +if ACK or any other control bit is set as long as SYN is set. +.PP +In order to achieve our goal, we need to logically AND the +binary value of octet 13 with some other value to preserve +the SYN bit. +We know that we want SYN to be set in any case, +so we'll logically AND the value in the 13th octet with +the binary value of a SYN: +.PP +.nf + + 00010010 SYN-ACK 00000010 SYN + AND 00000010 (we want SYN) AND 00000010 (we want SYN) + -------- -------- + = 00000010 = 00000010 +.fi +.PP +We see that this AND operation delivers the same result +regardless whether ACK or another TCP control bit is set. +The decimal representation of the AND value as well as +the result of this operation is 2 (binary 00000010), +so we know that for packets with SYN set the following +relation must hold true: +.IP +( ( value of octet 13 ) AND ( 2 ) ) == ( 2 ) +.PP +This points us to the \fItcpdump\fP filter expression +.RS +.B + tcpdump -i xl0 'tcp[13] & 2 == 2' +.RE +.PP +Some offsets and field values may be expressed as names +rather than as numeric values. For example tcp[13] may +be replaced with tcp[tcpflags]. The following TCP flag +field values are also available: tcp-fin, tcp-syn, tcp-rst, +tcp-push, tcp-act, tcp-urg. +.PP +This can be demonstrated as: +.RS +.B + tcpdump -i xl0 'tcp[tcpflags] & tcp-push != 0' +.RE +.PP +Note that you should use single quotes or a backslash +in the expression to hide the AND ('&') special character +from the shell. +.HD +.B +UDP Packets +.LP +UDP format is illustrated by this rwho packet: +.RS +.nf +.sp .5 +\f(CWactinide.who > broadcast.who: udp 84\fP +.sp .5 +.fi +.RE +This says that port \fIwho\fP on host \fIactinide\fP sent a udp +datagram to port \fIwho\fP on host \fIbroadcast\fP, the Internet +broadcast address. +The packet contained 84 bytes of user data. +.LP +Some UDP services are recognized (from the source or destination +port number) and the higher level protocol information printed. +In particular, Domain Name service requests (RFC-1034/1035) and Sun +RPC calls (RFC-1050) to NFS. +.HD +UDP Name Server Requests +.LP +\fI(N.B.:The following description assumes familiarity with +the Domain Service protocol described in RFC-1035. +If you are not familiar +with the protocol, the following description will appear to be written +in greek.)\fP +.LP +Name server requests are formatted as +.RS +.nf +.sp .5 +\fIsrc > dst: id op? flags qtype qclass name (len)\fP +.sp .5 +\f(CWh2opolo.1538 > helios.domain: 3+ A? ucbvax.berkeley.edu. (37)\fR +.sp .5 +.fi +.RE +Host \fIh2opolo\fP asked the domain server on \fIhelios\fP for an +address record (qtype=A) associated with the name \fIucbvax.berkeley.edu.\fP +The query id was `3'. +The `+' indicates the \fIrecursion desired\fP flag +was set. +The query length was 37 bytes, not including the UDP and +IP protocol headers. +The query operation was the normal one, \fIQuery\fP, +so the op field was omitted. +If the op had been anything else, it would +have been printed between the `3' and the `+'. +Similarly, the qclass was the normal one, +\fIC_IN\fP, and omitted. +Any other qclass would have been printed +immediately after the `A'. +.LP +A few anomalies are checked and may result in extra fields enclosed in +square brackets: If a query contains an answer, authority records or +additional records section, +.IR ancount , +.IR nscount , +or +.I arcount +are printed as `[\fIn\fPa]', `[\fIn\fPn]' or `[\fIn\fPau]' where \fIn\fP +is the appropriate count. +If any of the response bits are set (AA, RA or rcode) or any of the +`must be zero' bits are set in bytes two and three, `[b2&3=\fIx\fP]' +is printed, where \fIx\fP is the hex value of header bytes two and three. +.HD +UDP Name Server Responses +.LP +Name server responses are formatted as +.RS +.nf +.sp .5 +\fIsrc > dst: id op rcode flags a/n/au type class data (len)\fP +.sp .5 +\f(CWhelios.domain > h2opolo.1538: 3 3/3/7 A 128.32.137.3 (273) +helios.domain > h2opolo.1537: 2 NXDomain* 0/1/0 (97)\fR +.sp .5 +.fi +.RE +In the first example, \fIhelios\fP responds to query id 3 from \fIh2opolo\fP +with 3 answer records, 3 name server records and 7 additional records. +The first answer record is type A (address) and its data is internet +address 128.32.137.3. +The total size of the response was 273 bytes, +excluding UDP and IP headers. +The op (Query) and response code +(NoError) were omitted, as was the class (C_IN) of the A record. +.LP +In the second example, \fIhelios\fP responds to query 2 with a +response code of non-existent domain (NXDomain) with no answers, +one name server and no authority records. +The `*' indicates that +the \fIauthoritative answer\fP bit was set. +Since there were no +answers, no type, class or data were printed. +.LP +Other flag characters that might appear are `\-' (recursion available, +RA, \fInot\fP set) and `|' (truncated message, TC, set). +If the +`question' section doesn't contain exactly one entry, `[\fIn\fPq]' +is printed. + +.HD +SMB/CIFS decoding +.LP +\fItcpdump\fP now includes fairly extensive SMB/CIFS/NBT decoding for data +on UDP/137, UDP/138 and TCP/139. +Some primitive decoding of IPX and +NetBEUI SMB data is also done. + +By default a fairly minimal decode is done, with a much more detailed +decode done if -v is used. +Be warned that with -v a single SMB packet +may take up a page or more, so only use -v if you really want all the +gory details. + +For information on SMB packet formats and what all te fields mean see +www.cifs.org or the pub/samba/specs/ directory on your favorite +samba.org mirror site. +The SMB patches were written by Andrew Tridgell +(tridge@samba.org). + +.HD +NFS Requests and Replies +.LP +Sun NFS (Network File System) requests and replies are printed as: +.RS +.nf +.sp .5 +\fIsrc.xid > dst.nfs: len op args\fP +\fIsrc.nfs > dst.xid: reply stat len op results\fP +.sp .5 +\f(CW +sushi.6709 > wrl.nfs: 112 readlink fh 21,24/10.73165 +wrl.nfs > sushi.6709: reply ok 40 readlink "../var" +sushi.201b > wrl.nfs: + 144 lookup fh 9,74/4096.6878 "xcolors" +wrl.nfs > sushi.201b: + reply ok 128 lookup fh 9,74/4134.3150 +\fR +.sp .5 +.fi +.RE +In the first line, host \fIsushi\fP sends a transaction with id \fI6709\fP +to \fIwrl\fP (note that the number following the src host is a +transaction id, \fInot\fP the source port). +The request was 112 bytes, +excluding the UDP and IP headers. +The operation was a \fIreadlink\fP +(read symbolic link) on file handle (\fIfh\fP) 21,24/10.731657119. +(If one is lucky, as in this case, the file handle can be interpreted +as a major,minor device number pair, followed by the inode number and +generation number.) +\fIWrl\fP replies `ok' with the contents of the link. +.LP +In the third line, \fIsushi\fP asks \fIwrl\fP to lookup the name +`\fIxcolors\fP' in directory file 9,74/4096.6878. +Note that the data printed +depends on the operation type. +The format is intended to be self +explanatory if read in conjunction with +an NFS protocol spec. +.LP +If the \-v (verbose) flag is given, additional information is printed. +For example: +.RS +.nf +.sp .5 +\f(CW +sushi.1372a > wrl.nfs: + 148 read fh 21,11/12.195 8192 bytes @ 24576 +wrl.nfs > sushi.1372a: + reply ok 1472 read REG 100664 ids 417/0 sz 29388 +\fP +.sp .5 +.fi +.RE +(\-v also prints the IP header TTL, ID, length, and fragmentation fields, +which have been omitted from this example.) In the first line, +\fIsushi\fP asks \fIwrl\fP to read 8192 bytes from file 21,11/12.195, +at byte offset 24576. +\fIWrl\fP replies `ok'; the packet shown on the +second line is the first fragment of the reply, and hence is only 1472 +bytes long (the other bytes will follow in subsequent fragments, but +these fragments do not have NFS or even UDP headers and so might not be +printed, depending on the filter expression used). +Because the \-v flag +is given, some of the file attributes (which are returned in addition +to the file data) are printed: the file type (``REG'', for regular file), +the file mode (in octal), the uid and gid, and the file size. +.LP +If the \-v flag is given more than once, even more details are printed. +.LP +Note that NFS requests are very large and much of the detail won't be printed +unless \fIsnaplen\fP is increased. +Try using `\fB\-s 192\fP' to watch +NFS traffic. +.LP +NFS reply packets do not explicitly identify the RPC operation. +Instead, +\fItcpdump\fP keeps track of ``recent'' requests, and matches them to the +replies using the transaction ID. +If a reply does not closely follow the +corresponding request, it might not be parsable. +.HD +AFS Requests and Replies +.LP +Transarc AFS (Andrew File System) requests and replies are printed +as: +.HD +.RS +.nf +.sp .5 +\fIsrc.sport > dst.dport: rx packet-type\fP +\fIsrc.sport > dst.dport: rx packet-type service call call-name args\fP +\fIsrc.sport > dst.dport: rx packet-type service reply call-name args\fP +.sp .5 +\f(CW +elvis.7001 > pike.afsfs: + rx data fs call rename old fid 536876964/1/1 ".newsrc.new" + new fid 536876964/1/1 ".newsrc" +pike.afsfs > elvis.7001: rx data fs reply rename +\fR +.sp .5 +.fi +.RE +In the first line, host elvis sends a RX packet to pike. +This was +a RX data packet to the fs (fileserver) service, and is the start of +an RPC call. +The RPC call was a rename, with the old directory file id +of 536876964/1/1 and an old filename of `.newsrc.new', and a new directory +file id of 536876964/1/1 and a new filename of `.newsrc'. +The host pike +responds with a RPC reply to the rename call (which was successful, because +it was a data packet and not an abort packet). +.LP +In general, all AFS RPCs are decoded at least by RPC call name. +Most +AFS RPCs have at least some of the arguments decoded (generally only +the `interesting' arguments, for some definition of interesting). +.LP +The format is intended to be self-describing, but it will probably +not be useful to people who are not familiar with the workings of +AFS and RX. +.LP +If the -v (verbose) flag is given twice, acknowledgement packets and +additional header information is printed, such as the the RX call ID, +call number, sequence number, serial number, and the RX packet flags. +.LP +If the -v flag is given twice, additional information is printed, +such as the the RX call ID, serial number, and the RX packet flags. +The MTU negotiation information is also printed from RX ack packets. +.LP +If the -v flag is given three times, the security index and service id +are printed. +.LP +Error codes are printed for abort packets, with the exception of Ubik +beacon packets (because abort packets are used to signify a yes vote +for the Ubik protocol). +.LP +Note that AFS requests are very large and many of the arguments won't +be printed unless \fIsnaplen\fP is increased. +Try using `\fB-s 256\fP' +to watch AFS traffic. +.LP +AFS reply packets do not explicitly identify the RPC operation. +Instead, +\fItcpdump\fP keeps track of ``recent'' requests, and matches them to the +replies using the call number and service ID. +If a reply does not closely +follow the +corresponding request, it might not be parsable. + +.HD +KIP AppleTalk (DDP in UDP) +.LP +AppleTalk DDP packets encapsulated in UDP datagrams are de-encapsulated +and dumped as DDP packets (i.e., all the UDP header information is +discarded). +The file +.I /etc/atalk.names +is used to translate AppleTalk net and node numbers to names. +Lines in this file have the form +.RS +.nf +.sp .5 +\fInumber name\fP + +\f(CW1.254 ether +16.1 icsd-net +1.254.110 ace\fR +.sp .5 +.fi +.RE +The first two lines give the names of AppleTalk networks. +The third +line gives the name of a particular host (a host is distinguished +from a net by the 3rd octet in the number \- +a net number \fImust\fP have two octets and a host number \fImust\fP +have three octets.) The number and name should be separated by +whitespace (blanks or tabs). +The +.I /etc/atalk.names +file may contain blank lines or comment lines (lines starting with +a `#'). +.LP +AppleTalk addresses are printed in the form +.RS +.nf +.sp .5 +\fInet.host.port\fP + +\f(CW144.1.209.2 > icsd-net.112.220 +office.2 > icsd-net.112.220 +jssmag.149.235 > icsd-net.2\fR +.sp .5 +.fi +.RE +(If the +.I /etc/atalk.names +doesn't exist or doesn't contain an entry for some AppleTalk +host/net number, addresses are printed in numeric form.) +In the first example, NBP (DDP port 2) on net 144.1 node 209 +is sending to whatever is listening on port 220 of net icsd node 112. +The second line is the same except the full name of the source node +is known (`office'). +The third line is a send from port 235 on +net jssmag node 149 to broadcast on the icsd-net NBP port (note that +the broadcast address (255) is indicated by a net name with no host +number \- for this reason it's a good idea to keep node names and +net names distinct in /etc/atalk.names). +.LP +NBP (name binding protocol) and ATP (AppleTalk transaction protocol) +packets have their contents interpreted. +Other protocols just dump +the protocol name (or number if no name is registered for the +protocol) and packet size. + +\fBNBP packets\fP are formatted like the following examples: +.RS +.nf +.sp .5 +\s-2\f(CWicsd-net.112.220 > jssmag.2: nbp-lkup 190: "=:LaserWriter@*" +jssmag.209.2 > icsd-net.112.220: nbp-reply 190: "RM1140:LaserWriter@*" 250 +techpit.2 > icsd-net.112.220: nbp-reply 190: "techpit:LaserWriter@*" 186\fR\s+2 +.sp .5 +.fi +.RE +The first line is a name lookup request for laserwriters sent by net icsd host +112 and broadcast on net jssmag. +The nbp id for the lookup is 190. +The second line shows a reply for this request (note that it has the +same id) from host jssmag.209 saying that it has a laserwriter +resource named "RM1140" registered on port 250. +The third line is +another reply to the same request saying host techpit has laserwriter +"techpit" registered on port 186. + +\fBATP packet\fP formatting is demonstrated by the following example: +.RS +.nf +.sp .5 +\s-2\f(CWjssmag.209.165 > helios.132: atp-req 12266<0-7> 0xae030001 +helios.132 > jssmag.209.165: atp-resp 12266:0 (512) 0xae040000 +helios.132 > jssmag.209.165: atp-resp 12266:1 (512) 0xae040000 +helios.132 > jssmag.209.165: atp-resp 12266:2 (512) 0xae040000 +helios.132 > jssmag.209.165: atp-resp 12266:3 (512) 0xae040000 +helios.132 > jssmag.209.165: atp-resp 12266:4 (512) 0xae040000 +helios.132 > jssmag.209.165: atp-resp 12266:5 (512) 0xae040000 +helios.132 > jssmag.209.165: atp-resp 12266:6 (512) 0xae040000 +helios.132 > jssmag.209.165: atp-resp*12266:7 (512) 0xae040000 +jssmag.209.165 > helios.132: atp-req 12266<3,5> 0xae030001 +helios.132 > jssmag.209.165: atp-resp 12266:3 (512) 0xae040000 +helios.132 > jssmag.209.165: atp-resp 12266:5 (512) 0xae040000 +jssmag.209.165 > helios.132: atp-rel 12266<0-7> 0xae030001 +jssmag.209.133 > helios.132: atp-req* 12267<0-7> 0xae030002\fR\s+2 +.sp .5 +.fi +.RE +Jssmag.209 initiates transaction id 12266 with host helios by requesting +up to 8 packets (the `<0-7>'). +The hex number at the end of the line +is the value of the `userdata' field in the request. +.LP +Helios responds with 8 512-byte packets. +The `:digit' following the +transaction id gives the packet sequence number in the transaction +and the number in parens is the amount of data in the packet, +excluding the atp header. +The `*' on packet 7 indicates that the +EOM bit was set. +.LP +Jssmag.209 then requests that packets 3 & 5 be retransmitted. +Helios +resends them then jssmag.209 releases the transaction. +Finally, +jssmag.209 initiates the next request. +The `*' on the request +indicates that XO (`exactly once') was \fInot\fP set. + +.HD +IP Fragmentation +.LP +Fragmented Internet datagrams are printed as +.RS +.nf +.sp .5 +\fB(frag \fIid\fB:\fIsize\fB@\fIoffset\fB+)\fR +\fB(frag \fIid\fB:\fIsize\fB@\fIoffset\fB)\fR +.sp .5 +.fi +.RE +(The first form indicates there are more fragments. +The second +indicates this is the last fragment.) +.LP +\fIId\fP is the fragment id. +\fISize\fP is the fragment +size (in bytes) excluding the IP header. +\fIOffset\fP is this +fragment's offset (in bytes) in the original datagram. +.LP +The fragment information is output for each fragment. +The first +fragment contains the higher level protocol header and the frag +info is printed after the protocol info. +Fragments +after the first contain no higher level protocol header and the +frag info is printed after the source and destination addresses. +For example, here is part of an ftp from arizona.edu to lbl-rtsg.arpa +over a CSNET connection that doesn't appear to handle 576 byte datagrams: +.RS +.nf +.sp .5 +\s-2\f(CWarizona.ftp-data > rtsg.1170: . 1024:1332(308) ack 1 win 4096 (frag 595a:328@0+) +arizona > rtsg: (frag 595a:204@328) +rtsg.1170 > arizona.ftp-data: . ack 1536 win 2560\fP\s+2 +.sp .5 +.fi +.RE +There are a couple of things to note here: First, addresses in the +2nd line don't include port numbers. +This is because the TCP +protocol information is all in the first fragment and we have no idea +what the port or sequence numbers are when we print the later fragments. +Second, the tcp sequence information in the first line is printed as if there +were 308 bytes of user data when, in fact, there are 512 bytes (308 in +the first frag and 204 in the second). +If you are looking for holes +in the sequence space or trying to match up acks +with packets, this can fool you. +.LP +A packet with the IP \fIdon't fragment\fP flag is marked with a +trailing \fB(DF)\fP. +.HD +Timestamps +.LP +By default, all output lines are preceded by a timestamp. +The timestamp +is the current clock time in the form +.RS +.nf +\fIhh:mm:ss.frac\fP +.fi +.RE +and is as accurate as the kernel's clock. +The timestamp reflects the time the kernel first saw the packet. +No attempt +is made to account for the time lag between when the +Ethernet interface removed the packet from the wire and when the kernel +serviced the `new packet' interrupt. +.SH "SEE ALSO" +stty(1), pcap(3PCAP), bpf(4), nit(4P), pcap-savefile(@MAN_FILE_FORMATS@), +pcap-filter(@MAN_MISC_INFO@) +.SH AUTHORS +The original authors are: +.LP +Van Jacobson, +Craig Leres and +Steven McCanne, all of the +Lawrence Berkeley National Laboratory, University of California, Berkeley, CA. +.LP +It is currently being maintained by tcpdump.org. +.LP +The current version is available via http: +.LP +.RS +.I http://www.tcpdump.org/ +.RE +.LP +The original distribution is available via anonymous ftp: +.LP +.RS +.I ftp://ftp.ee.lbl.gov/tcpdump.tar.Z +.RE +.LP +IPv6/IPsec support is added by WIDE/KAME project. +This program uses Eric Young's SSLeay library, under specific configurations. +.SH BUGS +Please send problems, bugs, questions, desirable enhancements, patches +etc. to: +.LP +.RS +tcpdump-workers@lists.tcpdump.org +.RE +.LP +NIT doesn't let you watch your own outbound traffic, BPF will. +We recommend that you use the latter. +.LP +On Linux systems with 2.0[.x] kernels: +.IP +packets on the loopback device will be seen twice; +.IP +packet filtering cannot be done in the kernel, so that all packets must +be copied from the kernel in order to be filtered in user mode; +.IP +all of a packet, not just the part that's within the snapshot length, +will be copied from the kernel (the 2.0[.x] packet capture mechanism, if +asked to copy only part of a packet to userland, will not report the +true length of the packet; this would cause most IP packets to get an +error from +.BR tcpdump ); +.IP +capturing on some PPP devices won't work correctly. +.LP +We recommend that you upgrade to a 2.2 or later kernel. +.LP +Some attempt should be made to reassemble IP fragments or, at least +to compute the right length for the higher level protocol. +.LP +Name server inverse queries are not dumped correctly: the (empty) +question section is printed rather than real query in the answer +section. +Some believe that inverse queries are themselves a bug and +prefer to fix the program generating them rather than \fItcpdump\fP. +.LP +A packet trace that crosses a daylight savings time change will give +skewed time stamps (the time change is ignored). +.LP +Filter expressions on fields other than those in Token Ring headers will +not correctly handle source-routed Token Ring packets. +.LP +Filter expressions on fields other than those in 802.11 headers will not +correctly handle 802.11 data packets with both To DS and From DS set. +.LP +.BR "ip6 proto" +should chase header chain, but at this moment it does not. +.BR "ip6 protochain" +is supplied for this behavior. +.LP +Arithmetic expression against transport layer headers, like \fBtcp[0]\fP, +does not work against IPv6 packets. +It only looks at IPv4 packets. diff --git a/tcpdump.c b/tcpdump.c new file mode 100644 index 0000000..06683af --- /dev/null +++ b/tcpdump.c @@ -0,0 +1,1833 @@ +/* + * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Support for splitting captures into multiple files with a maximum + * file size: + * + * Copyright (c) 2001 + * Seth Webster + */ + +#ifndef lint +static const char copyright[] _U_ = + "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\ +The Regents of the University of California. All rights reserved.\n"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.283 2008-09-25 21:45:50 guy Exp $ (LBL)"; +#endif + +/* + * tcpdump - monitor tcp/ip traffic on an ethernet. + * + * First written in 1987 by Van Jacobson, Lawrence Berkeley Laboratory. + * Mercilessly hacked and occasionally improved since then via the + * combined efforts of Van, Steve McCanne and Craig Leres of LBL. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifdef WIN32 +#include "getopt.h" +#include "w32_fzs.h" +extern int strcasecmp (const char *__s1, const char *__s2); +extern int SIZE_BUF; +#define off_t long +#define uint UINT +#endif /* WIN32 */ + +#ifdef HAVE_SMI_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#ifndef WIN32 +#include +#include +#include +#include +#include +#endif /* WIN32 */ + + +#include "netdissect.h" +#include "interface.h" +#include "addrtoname.h" +#include "machdep.h" +#include "setsignal.h" +#include "gmt2local.h" +#include "pcap-missing.h" + +#ifndef NAME_MAX +#define NAME_MAX 255 +#endif + +netdissect_options Gndo; +netdissect_options *gndo = &Gndo; + +static int dflag; /* print filter code */ +static int Lflag; /* list available data link types and exit */ +static char *zflag = NULL; /* compress each savefile using a specified command (like gzip or bzip2) */ + +static int infodelay; +static int infoprint; + +char *program_name; + +int32_t thiszone; /* seconds offset from gmt to local time */ + +/* Forwards */ +static RETSIGTYPE cleanup(int); +static RETSIGTYPE child_cleanup(int); +static void usage(void) __attribute__((noreturn)); +static void show_dlts_and_exit(const char *device, pcap_t *pd) __attribute__((noreturn)); + +static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *); +static void ndo_default_print(netdissect_options *, const u_char *, u_int); +static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *); +static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *); +static void droproot(const char *, const char *); +static void ndo_error(netdissect_options *ndo, const char *fmt, ...); +static void ndo_warning(netdissect_options *ndo, const char *fmt, ...); + +#ifdef SIGINFO +RETSIGTYPE requestinfo(int); +#endif + +#if defined(USE_WIN32_MM_TIMER) + #include + static UINT timer_id; + static void CALLBACK verbose_stats_dump(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR); +#elif defined(HAVE_ALARM) + static void verbose_stats_dump(int sig); +#endif + +static void info(int); +static u_int packets_captured; + +typedef u_int (*if_printer)(const struct pcap_pkthdr *, const u_char *); +typedef u_int (*if_ndo_printer)(struct netdissect_options *ndo, + const struct pcap_pkthdr *, const u_char *); + +struct printer { + if_printer f; + int type; +}; + + +struct ndo_printer { + if_ndo_printer f; + int type; +}; + + +static struct printer printers[] = { + { arcnet_if_print, DLT_ARCNET }, +#ifdef DLT_ARCNET_LINUX + { arcnet_linux_if_print, DLT_ARCNET_LINUX }, +#endif + { ether_if_print, DLT_EN10MB }, + { token_if_print, DLT_IEEE802 }, +#ifdef DLT_LANE8023 + { lane_if_print, DLT_LANE8023 }, +#endif +#ifdef DLT_CIP + { cip_if_print, DLT_CIP }, +#endif +#ifdef DLT_ATM_CLIP + { cip_if_print, DLT_ATM_CLIP }, +#endif + { sl_if_print, DLT_SLIP }, +#ifdef DLT_SLIP_BSDOS + { sl_bsdos_if_print, DLT_SLIP_BSDOS }, +#endif + { ppp_if_print, DLT_PPP }, +#ifdef DLT_PPP_WITHDIRECTION + { ppp_if_print, DLT_PPP_WITHDIRECTION }, +#endif +#ifdef DLT_PPP_BSDOS + { ppp_bsdos_if_print, DLT_PPP_BSDOS }, +#endif + { fddi_if_print, DLT_FDDI }, + { null_if_print, DLT_NULL }, +#ifdef DLT_LOOP + { null_if_print, DLT_LOOP }, +#endif + { raw_if_print, DLT_RAW }, + { atm_if_print, DLT_ATM_RFC1483 }, +#ifdef DLT_C_HDLC + { chdlc_if_print, DLT_C_HDLC }, +#endif +#ifdef DLT_HDLC + { chdlc_if_print, DLT_HDLC }, +#endif +#ifdef DLT_PPP_SERIAL + { ppp_hdlc_if_print, DLT_PPP_SERIAL }, +#endif +#ifdef DLT_PPP_ETHER + { pppoe_if_print, DLT_PPP_ETHER }, +#endif +#ifdef DLT_LINUX_SLL + { sll_if_print, DLT_LINUX_SLL }, +#endif +#ifdef DLT_IEEE802_11 + { ieee802_11_if_print, DLT_IEEE802_11}, +#endif +#ifdef DLT_LTALK + { ltalk_if_print, DLT_LTALK }, +#endif +#if defined(DLT_PFLOG) && defined(HAVE_NET_PFVAR_H) + { pflog_if_print, DLT_PFLOG }, +#endif +#ifdef DLT_FR + { fr_if_print, DLT_FR }, +#endif +#ifdef DLT_FRELAY + { fr_if_print, DLT_FRELAY }, +#endif +#ifdef DLT_SUNATM + { sunatm_if_print, DLT_SUNATM }, +#endif +#ifdef DLT_IP_OVER_FC + { ipfc_if_print, DLT_IP_OVER_FC }, +#endif +#ifdef DLT_PRISM_HEADER + { prism_if_print, DLT_PRISM_HEADER }, +#endif +#ifdef DLT_IEEE802_11_RADIO + { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO }, +#endif +#ifdef DLT_ENC + { enc_if_print, DLT_ENC }, +#endif +#ifdef DLT_SYMANTEC_FIREWALL + { symantec_if_print, DLT_SYMANTEC_FIREWALL }, +#endif +#ifdef DLT_APPLE_IP_OVER_IEEE1394 + { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 }, +#endif +#ifdef DLT_IEEE802_11_RADIO_AVS + { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS }, +#endif +#ifdef DLT_JUNIPER_ATM1 + { juniper_atm1_print, DLT_JUNIPER_ATM1 }, +#endif +#ifdef DLT_JUNIPER_ATM2 + { juniper_atm2_print, DLT_JUNIPER_ATM2 }, +#endif +#ifdef DLT_JUNIPER_MFR + { juniper_mfr_print, DLT_JUNIPER_MFR }, +#endif +#ifdef DLT_JUNIPER_MLFR + { juniper_mlfr_print, DLT_JUNIPER_MLFR }, +#endif +#ifdef DLT_JUNIPER_MLPPP + { juniper_mlppp_print, DLT_JUNIPER_MLPPP }, +#endif +#ifdef DLT_JUNIPER_PPPOE + { juniper_pppoe_print, DLT_JUNIPER_PPPOE }, +#endif +#ifdef DLT_JUNIPER_PPPOE_ATM + { juniper_pppoe_atm_print, DLT_JUNIPER_PPPOE_ATM }, +#endif +#ifdef DLT_JUNIPER_GGSN + { juniper_ggsn_print, DLT_JUNIPER_GGSN }, +#endif +#ifdef DLT_JUNIPER_ES + { juniper_es_print, DLT_JUNIPER_ES }, +#endif +#ifdef DLT_JUNIPER_MONITOR + { juniper_monitor_print, DLT_JUNIPER_MONITOR }, +#endif +#ifdef DLT_JUNIPER_SERVICES + { juniper_services_print, DLT_JUNIPER_SERVICES }, +#endif +#ifdef DLT_JUNIPER_ETHER + { juniper_ether_print, DLT_JUNIPER_ETHER }, +#endif +#ifdef DLT_JUNIPER_PPP + { juniper_ppp_print, DLT_JUNIPER_PPP }, +#endif +#ifdef DLT_JUNIPER_FRELAY + { juniper_frelay_print, DLT_JUNIPER_FRELAY }, +#endif +#ifdef DLT_JUNIPER_CHDLC + { juniper_chdlc_print, DLT_JUNIPER_CHDLC }, +#endif +#ifdef DLT_MFR + { mfr_if_print, DLT_MFR }, +#endif +#if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H) + { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR}, +#endif +#ifdef HAVE_PCAP_USB_H +#ifdef DLT_USB_LINUX + { usb_linux_48_byte_print, DLT_USB_LINUX}, +#endif /* DLT_USB_LINUX */ +#ifdef DLT_USB_LINUX_MMAPPED + { usb_linux_64_byte_print, DLT_USB_LINUX_MMAPPED}, +#endif /* DLT_USB_LINUX_MMAPPED */ +#endif /* HAVE_PCAP_USB_H */ +#ifdef DLT_IPV4 + { raw_if_print, DLT_IPV4 }, +#endif +#ifdef DLT_IPV6 + { raw_if_print, DLT_IPV6 }, +#endif + { NULL, 0 }, +}; + +static struct ndo_printer ndo_printers[] = { +#ifdef DLT_IPNET + { ipnet_if_print, DLT_IPNET }, +#endif + { NULL, 0 }, +}; + +static if_printer +lookup_printer(int type) +{ + struct printer *p; + + for (p = printers; p->f; ++p) + if (type == p->type) + return p->f; + + return NULL; + /* NOTREACHED */ +} + +static if_ndo_printer +lookup_ndo_printer(int type) +{ + struct ndo_printer *p; + + for (p = ndo_printers; p->f; ++p) + if (type == p->type) + return p->f; + + return NULL; + /* NOTREACHED */ +} + +static pcap_t *pd; + +static int supports_monitor_mode; + +extern int optind; +extern int opterr; +extern char *optarg; + +struct print_info { + netdissect_options *ndo; + union { + if_printer printer; + if_ndo_printer ndo_printer; + } p; + int ndo_type; +}; + +struct dump_info { + char *WFileName; + char *CurrentFileName; + pcap_t *pd; + pcap_dumper_t *p; +}; + +static void +show_dlts_and_exit(const char *device, pcap_t *pd) +{ + int n_dlts; + int *dlts = 0; + const char *dlt_name; + + n_dlts = pcap_list_datalinks(pd, &dlts); + if (n_dlts < 0) + error("%s", pcap_geterr(pd)); + else if (n_dlts == 0 || !dlts) + error("No data link types."); + + /* + * If the interface is known to support monitor mode, indicate + * whether these are the data link types available when not in + * monitor mode, if -I wasn't specified, or when in monitor mode, + * when -I was specified (the link-layer types available in + * monitor mode might be different from the ones available when + * not in monitor mode). + */ + if (supports_monitor_mode) + (void) fprintf(stderr, "Data link types for %s %s (use option -y to set):\n", + device, + Iflag ? "when in monitor mode" : "when not in monitor mode"); + else + (void) fprintf(stderr, "Data link types for %s (use option -y to set):\n", + device); + + while (--n_dlts >= 0) { + dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]); + if (dlt_name != NULL) { + (void) fprintf(stderr, " %s (%s)", dlt_name, + pcap_datalink_val_to_description(dlts[n_dlts])); + + /* + * OK, does tcpdump handle that type? + */ + if (lookup_printer(dlts[n_dlts]) == NULL + && lookup_ndo_printer(dlts[n_dlts]) == NULL) + (void) fprintf(stderr, " (printing not supported)"); + putchar('\n'); + } else { + (void) fprintf(stderr, " DLT %d (printing not supported)\n", + dlts[n_dlts]); + } + } + free(dlts); + exit(0); +} + +/* + * Set up flags that might or might not be supported depending on the + * version of libpcap we're using. + */ +#if defined(HAVE_PCAP_CREATE) || defined(WIN32) +#define B_FLAG "B:" +#define B_FLAG_USAGE " [ -B size ]" +#else /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ +#define B_FLAG +#define B_FLAG_USAGE +#endif /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ + +#ifdef HAVE_PCAP_CREATE +#define I_FLAG "I" +#else /* HAVE_PCAP_CREATE */ +#define I_FLAG +#endif /* HAVE_PCAP_CREATE */ + +#ifdef HAVE_PCAP_FINDALLDEVS +#ifndef HAVE_PCAP_IF_T +#undef HAVE_PCAP_FINDALLDEVS +#endif +#endif + +#ifdef HAVE_PCAP_FINDALLDEVS +#define D_FLAG "D" +#else +#define D_FLAG +#endif + +#ifdef HAVE_PCAP_DUMP_FLUSH +#define U_FLAG "U" +#else +#define U_FLAG +#endif + +#ifndef WIN32 +/* Drop root privileges and chroot if necessary */ +static void +droproot(const char *username, const char *chroot_dir) +{ + struct passwd *pw = NULL; + + if (chroot_dir && !username) { + fprintf(stderr, "tcpdump: Chroot without dropping root is insecure\n"); + exit(1); + } + + pw = getpwnam(username); + if (pw) { + if (chroot_dir) { + if (chroot(chroot_dir) != 0 || chdir ("/") != 0) { + fprintf(stderr, "tcpdump: Couldn't chroot/chdir to '%.64s': %s\n", + chroot_dir, pcap_strerror(errno)); + exit(1); + } + } + if (initgroups(pw->pw_name, pw->pw_gid) != 0 || + setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) { + fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n", + username, + (unsigned long)pw->pw_uid, + (unsigned long)pw->pw_gid, + pcap_strerror(errno)); + exit(1); + } + } + else { + fprintf(stderr, "tcpdump: Couldn't find user '%.32s'\n", + username); + exit(1); + } +} +#endif /* WIN32 */ + +static int +getWflagChars(int x) +{ + int c = 0; + + x -= 1; + while (x > 0) { + c += 1; + x /= 10; + } + + return c; +} + + +static void +MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars) +{ + char *filename = malloc(NAME_MAX + 1); + + /* Process with strftime if Gflag is set. */ + if (Gflag != 0) { + struct tm *local_tm; + + /* Convert Gflag_time to a usable format */ + if ((local_tm = localtime(&Gflag_time)) == NULL) { + error("MakeTimedFilename: localtime"); + } + + /* There's no good way to detect an error in strftime since a return + * value of 0 isn't necessarily failure. + */ + strftime(filename, NAME_MAX, orig_name, local_tm); + } else { + strncpy(filename, orig_name, NAME_MAX); + } + + if (cnt == 0 && max_chars == 0) + strncpy(buffer, filename, NAME_MAX + 1); + else + if (snprintf(buffer, NAME_MAX + 1, "%s%0*d", filename, max_chars, cnt) > NAME_MAX) + /* Report an error if the filename is too large */ + error("too many output files or filename is too long (> %d)", NAME_MAX); + free(filename); +} + +static int tcpdump_printf(netdissect_options *ndo _U_, + const char *fmt, ...) +{ + + va_list args; + int ret; + + va_start(args, fmt); + ret=vfprintf(stdout, fmt, args); + va_end(args); + + return ret; +} + +int +main(int argc, char **argv) +{ + register int cnt, op, i; + bpf_u_int32 localnet, netmask; + register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName; + pcap_handler callback; + int type; + struct bpf_program fcode; +#ifndef WIN32 + RETSIGTYPE (*oldhandler)(int); +#endif + struct print_info printinfo; + struct dump_info dumpinfo; + u_char *pcap_userdata; + char ebuf[PCAP_ERRBUF_SIZE]; + char *username = NULL; + char *chroot_dir = NULL; +#ifdef HAVE_PCAP_FINDALLDEVS + pcap_if_t *devpointer; + int devnum; +#endif + int status; +#ifdef WIN32 + if(wsockinit() != 0) return 1; +#endif /* WIN32 */ + + gndo->ndo_Oflag=1; + gndo->ndo_Rflag=1; + gndo->ndo_dlt=-1; + gndo->ndo_default_print=ndo_default_print; + gndo->ndo_printf=tcpdump_printf; + gndo->ndo_error=ndo_error; + gndo->ndo_warning=ndo_warning; + gndo->ndo_snaplen = DEFAULT_SNAPLEN; + + cnt = -1; + device = NULL; + infile = NULL; + RFileName = NULL; + WFileName = NULL; + if ((cp = strrchr(argv[0], '/')) != NULL) + program_name = cp + 1; + else + program_name = argv[0]; + + if (abort_on_misalignment(ebuf, sizeof(ebuf)) < 0) + error("%s", ebuf); + +#ifdef LIBSMI + smiInit("tcpdump"); +#endif + + opterr = 0; + while ( + (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:i:" I_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:")) != -1) + switch (op) { + + case 'a': + /* compatibility for old -a */ + break; + + case 'A': + ++Aflag; + break; + + case 'b': + ++bflag; + break; + +#if defined(HAVE_PCAP_CREATE) || defined(WIN32) + case 'B': + Bflag = atoi(optarg)*1024; + if (Bflag <= 0) + error("invalid packet buffer size %s", optarg); + break; +#endif /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ + + case 'c': + cnt = atoi(optarg); + if (cnt <= 0) + error("invalid packet count %s", optarg); + break; + + case 'C': + Cflag = atoi(optarg) * 1000000; + if (Cflag < 0) + error("invalid file size %s", optarg); + break; + + case 'd': + ++dflag; + break; + +#ifdef HAVE_PCAP_FINDALLDEVS + case 'D': + if (pcap_findalldevs(&devpointer, ebuf) < 0) + error("%s", ebuf); + else { + for (i = 0; devpointer != 0; i++) { + printf("%d.%s", i+1, devpointer->name); + if (devpointer->description != NULL) + printf(" (%s)", devpointer->description); + printf("\n"); + devpointer = devpointer->next; + } + } + return 0; +#endif /* HAVE_PCAP_FINDALLDEVS */ + + case 'L': + Lflag++; + break; + + case 'e': + ++eflag; + break; + + case 'E': +#ifndef HAVE_LIBCRYPTO + warning("crypto code not compiled in"); +#endif + gndo->ndo_espsecret = optarg; + break; + + case 'f': + ++fflag; + break; + + case 'F': + infile = optarg; + break; + + case 'G': + Gflag = atoi(optarg); + if (Gflag < 0) + error("invalid number of seconds %s", optarg); + + /* We will create one file initially. */ + Gflag_count = 0; + + /* Grab the current time for rotation use. */ + if ((Gflag_time = time(NULL)) == (time_t)-1) { + error("main: can't get current time: %s", + pcap_strerror(errno)); + } + break; + + case 'i': + if (optarg[0] == '0' && optarg[1] == 0) + error("Invalid adapter index"); + +#ifdef HAVE_PCAP_FINDALLDEVS + /* + * If the argument is a number, treat it as + * an index into the list of adapters, as + * printed by "tcpdump -D". + * + * This should be OK on UNIX systems, as interfaces + * shouldn't have names that begin with digits. + * It can be useful on Windows, where more than + * one interface can have the same name. + */ + if ((devnum = atoi(optarg)) != 0) { + if (devnum < 0) + error("Invalid adapter index"); + + if (pcap_findalldevs(&devpointer, ebuf) < 0) + error("%s", ebuf); + else { + /* + * Look for the devnum-th entry + * in the list of devices + * (1-based). + */ + for (i = 0; + i < devnum-1 && devpointer != NULL; + i++, devpointer = devpointer->next) + ; + if (devpointer == NULL) + error("Invalid adapter index"); + } + device = devpointer->name; + break; + } +#endif /* HAVE_PCAP_FINDALLDEVS */ + device = optarg; + break; + +#ifdef HAVE_PCAP_CREATE + case 'I': + ++Iflag; + break; +#endif /* HAVE_PCAP_CREATE */ + + case 'l': +#ifdef WIN32 + /* + * _IOLBF is the same as _IOFBF in Microsoft's C + * libraries; the only alternative they offer + * is _IONBF. + * + * XXX - this should really be checking for MSVC++, + * not WIN32, if, for example, MinGW has its own + * C library that is more UNIX-compatible. + */ + setvbuf(stdout, NULL, _IONBF, 0); +#else /* WIN32 */ +#ifdef HAVE_SETLINEBUF + setlinebuf(stdout); +#else + setvbuf(stdout, NULL, _IOLBF, 0); +#endif +#endif /* WIN32 */ + break; + + case 'K': + ++Kflag; + break; + + case 'm': +#ifdef LIBSMI + if (smiLoadModule(optarg) == 0) { + error("could not load MIB module %s", optarg); + } + sflag = 1; +#else + (void)fprintf(stderr, "%s: ignoring option `-m %s' ", + program_name, optarg); + (void)fprintf(stderr, "(no libsmi support)\n"); +#endif + break; + + case 'M': + /* TCP-MD5 shared secret */ +#ifndef HAVE_LIBCRYPTO + warning("crypto code not compiled in"); +#endif + sigsecret = optarg; + break; + + case 'n': + ++nflag; + break; + + case 'N': + ++Nflag; + break; + + case 'O': + Oflag = 0; + break; + + case 'p': + ++pflag; + break; + + case 'q': + ++qflag; + ++suppress_default_print; + break; + + case 'r': + RFileName = optarg; + break; + + case 'R': + Rflag = 0; + break; + + case 's': { + char *end; + + snaplen = strtol(optarg, &end, 0); + if (optarg == end || *end != '\0' + || snaplen < 0 || snaplen > MAXIMUM_SNAPLEN) + error("invalid snaplen %s", optarg); + else if (snaplen == 0) + snaplen = MAXIMUM_SNAPLEN; + break; + } + + case 'S': + ++Sflag; + break; + + case 't': + ++tflag; + break; + + case 'T': + if (strcasecmp(optarg, "vat") == 0) + packettype = PT_VAT; + else if (strcasecmp(optarg, "wb") == 0) + packettype = PT_WB; + else if (strcasecmp(optarg, "rpc") == 0) + packettype = PT_RPC; + else if (strcasecmp(optarg, "rtp") == 0) + packettype = PT_RTP; + else if (strcasecmp(optarg, "rtcp") == 0) + packettype = PT_RTCP; + else if (strcasecmp(optarg, "snmp") == 0) + packettype = PT_SNMP; + else if (strcasecmp(optarg, "cnfp") == 0) + packettype = PT_CNFP; + else if (strcasecmp(optarg, "tftp") == 0) + packettype = PT_TFTP; + else if (strcasecmp(optarg, "aodv") == 0) + packettype = PT_AODV; + else + error("unknown packet type `%s'", optarg); + break; + + case 'u': + ++uflag; + break; + +#ifdef HAVE_PCAP_DUMP_FLUSH + case 'U': + ++Uflag; + break; +#endif + + case 'v': + ++vflag; + break; + + case 'w': + WFileName = optarg; + break; + + case 'W': + Wflag = atoi(optarg); + if (Wflag < 0) + error("invalid number of output files %s", optarg); + WflagChars = getWflagChars(Wflag); + break; + + case 'x': + ++xflag; + ++suppress_default_print; + break; + + case 'X': + ++Xflag; + ++suppress_default_print; + break; + + case 'y': + gndo->ndo_dltname = optarg; + gndo->ndo_dlt = + pcap_datalink_name_to_val(gndo->ndo_dltname); + if (gndo->ndo_dlt < 0) + error("invalid data link type %s", gndo->ndo_dltname); + break; + +#if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG) + case 'Y': + { + /* Undocumented flag */ +#ifdef HAVE_PCAP_DEBUG + extern int pcap_debug; + pcap_debug = 1; +#else + extern int yydebug; + yydebug = 1; +#endif + } + break; +#endif + case 'z': + if (optarg) { + zflag = strdup(optarg); + } else { + usage(); + /* NOTREACHED */ + } + break; + + case 'Z': + if (optarg) { + username = strdup(optarg); + } + else { + usage(); + /* NOTREACHED */ + } + break; + + default: + usage(); + /* NOTREACHED */ + } + + switch (tflag) { + + case 0: /* Default */ + case 4: /* Default + Date*/ + thiszone = gmt2local(0); + break; + + case 1: /* No time stamp */ + case 2: /* Unix timeval style */ + case 3: /* Microseconds since previous packet */ + case 5: /* Microseconds since first packet */ + break; + + default: /* Not supported */ + error("only -t, -tt, -ttt, -tttt and -ttttt are supported"); + break; + } + +#ifdef WITH_CHROOT + /* if run as root, prepare for chrooting */ + if (getuid() == 0 || geteuid() == 0) { + /* future extensibility for cmd-line arguments */ + if (!chroot_dir) + chroot_dir = WITH_CHROOT; + } +#endif + +#ifdef WITH_USER + /* if run as root, prepare for dropping root privileges */ + if (getuid() == 0 || geteuid() == 0) { + /* Run with '-Z root' to restore old behaviour */ + if (!username) + username = WITH_USER; + } +#endif + + if (RFileName != NULL) { + int dlt; + const char *dlt_name; + +#ifndef WIN32 + /* + * We don't need network access, so relinquish any set-UID + * or set-GID privileges we have (if any). + * + * We do *not* want set-UID privileges when opening a + * trace file, as that might let the user read other + * people's trace files (especially if we're set-UID + * root). + */ + if (setgid(getgid()) != 0 || setuid(getuid()) != 0 ) + fprintf(stderr, "Warning: setgid/setuid failed !\n"); +#endif /* WIN32 */ + pd = pcap_open_offline(RFileName, ebuf); + if (pd == NULL) + error("%s", ebuf); + dlt = pcap_datalink(pd); + dlt_name = pcap_datalink_val_to_name(dlt); + if (dlt_name == NULL) { + fprintf(stderr, "reading from file %s, link-type %u\n", + RFileName, dlt); + } else { + fprintf(stderr, + "reading from file %s, link-type %s (%s)\n", + RFileName, dlt_name, + pcap_datalink_val_to_description(dlt)); + } + localnet = 0; + netmask = 0; + if (fflag != 0) + error("-f and -r options are incompatible"); + } else { + if (device == NULL) { + device = pcap_lookupdev(ebuf); + if (device == NULL) + error("%s", ebuf); + } +#ifdef WIN32 + if(strlen(device) == 1) //we assume that an ASCII string is always longer than 1 char + { //a Unicode string has a \0 as second byte (so strlen() is 1) + fprintf(stderr, "%s: listening on %ws\n", program_name, device); + } + else + { + fprintf(stderr, "%s: listening on %s\n", program_name, device); + } + + fflush(stderr); +#endif /* WIN32 */ +#ifdef HAVE_PCAP_CREATE + pd = pcap_create(device, ebuf); + if (pd == NULL) + error("%s", ebuf); + /* + * Is this an interface that supports monitor mode? + */ + if (pcap_can_set_rfmon(pd) == 1) + supports_monitor_mode = 1; + else + supports_monitor_mode = 0; + status = pcap_set_snaplen(pd, snaplen); + if (status != 0) + error("%s: pcap_set_snaplen failed: %s", + device, pcap_statustostr(status)); + status = pcap_set_promisc(pd, !pflag); + if (status != 0) + error("%s: pcap_set_promisc failed: %s", + device, pcap_statustostr(status)); + if (Iflag) { + status = pcap_set_rfmon(pd, 1); + if (status != 0) + error("%s: pcap_set_rfmon failed: %s", + device, pcap_statustostr(status)); + } + status = pcap_set_timeout(pd, 1000); + if (status != 0) + error("%s: pcap_set_timeout failed: %s", + device, pcap_statustostr(status)); + if (Bflag != 0) { + status = pcap_set_buffer_size(pd, Bflag); + if (status != 0) + error("%s: pcap_set_buffer_size failed: %s", + device, pcap_statustostr(status)); + } + status = pcap_activate(pd); + if (status < 0) { + /* + * pcap_activate() failed. + */ + cp = pcap_geterr(pd); + if (status == PCAP_ERROR) + error("%s", cp); + else if ((status == PCAP_ERROR_NO_SUCH_DEVICE || + status == PCAP_ERROR_PERM_DENIED) && + *cp != '\0') + error("%s: %s\n(%s)", device, + pcap_statustostr(status), cp); + else + error("%s: %s", device, + pcap_statustostr(status)); + } else if (status > 0) { + /* + * pcap_activate() succeeded, but it's warning us + * of a problem it had. + */ + cp = pcap_geterr(pd); + if (status == PCAP_WARNING) + warning("%s", cp); + else if (status == PCAP_WARNING_PROMISC_NOTSUP && + *cp != '\0') + warning("%s: %s\n(%s)", device, + pcap_statustostr(status), cp); + else + warning("%s: %s", device, + pcap_statustostr(status)); + } +#else + *ebuf = '\0'; + pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf); + if (pd == NULL) + error("%s", ebuf); + else if (*ebuf) + warning("%s", ebuf); +#endif /* HAVE_PCAP_CREATE */ + /* + * Let user own process after socket has been opened. + */ +#ifndef WIN32 + if (setgid(getgid()) != 0 || setuid(getuid()) != 0) + fprintf(stderr, "Warning: setgid/setuid failed !\n"); +#endif /* WIN32 */ +#if !defined(HAVE_PCAP_CREATE) && defined(WIN32) + if(Bflag != 0) + if(pcap_setbuff(pd, Bflag)==-1){ + error("%s", pcap_geterr(pd)); + } +#endif /* !defined(HAVE_PCAP_CREATE) && defined(WIN32) */ + if (Lflag) + show_dlts_and_exit(device, pd); + if (gndo->ndo_dlt >= 0) { +#ifdef HAVE_PCAP_SET_DATALINK + if (pcap_set_datalink(pd, gndo->ndo_dlt) < 0) + error("%s", pcap_geterr(pd)); +#else + /* + * We don't actually support changing the + * data link type, so we only let them + * set it to what it already is. + */ + if (gndo->ndo_dlt != pcap_datalink(pd)) { + error("%s is not one of the DLTs supported by this device\n", + gndo->ndo_dltname); + } +#endif + (void)fprintf(stderr, "%s: data link type %s\n", + program_name, gndo->ndo_dltname); + (void)fflush(stderr); + } + i = pcap_snapshot(pd); + if (snaplen < i) { + warning("snaplen raised from %d to %d", snaplen, i); + snaplen = i; + } + if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) { + localnet = 0; + netmask = 0; + warning("%s", ebuf); + } + } + if (infile) + cmdbuf = read_infile(infile); + else + cmdbuf = copy_argv(&argv[optind]); + + if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) + error("%s", pcap_geterr(pd)); + free(cmdbuf); + if (dflag) { + bpf_dump(&fcode, dflag); + pcap_close(pd); + exit(0); + } + init_addrtoname(localnet, netmask); + init_checksum(); + +#ifndef WIN32 + (void)setsignal(SIGPIPE, cleanup); + (void)setsignal(SIGTERM, cleanup); + (void)setsignal(SIGINT, cleanup); + (void)setsignal(SIGCHLD, child_cleanup); +#endif /* WIN32 */ + /* Cooperate with nohup(1) */ +#ifndef WIN32 + if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL) + (void)setsignal(SIGHUP, oldhandler); +#endif /* WIN32 */ + + if (pcap_setfilter(pd, &fcode) < 0) + error("%s", pcap_geterr(pd)); + if (WFileName) { + pcap_dumper_t *p; + /* Do not exceed the default NAME_MAX for files. */ + dumpinfo.CurrentFileName = (char *)malloc(NAME_MAX + 1); + + if (dumpinfo.CurrentFileName == NULL) + error("malloc of dumpinfo.CurrentFileName"); + + /* We do not need numbering for dumpfiles if Cflag isn't set. */ + if (Cflag != 0) + MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, WflagChars); + else + MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0); + + p = pcap_dump_open(pd, dumpinfo.CurrentFileName); + if (p == NULL) + error("%s", pcap_geterr(pd)); + if (Cflag != 0 || Gflag != 0) { + callback = dump_packet_and_trunc; + dumpinfo.WFileName = WFileName; + dumpinfo.pd = pd; + dumpinfo.p = p; + pcap_userdata = (u_char *)&dumpinfo; + } else { + callback = dump_packet; + pcap_userdata = (u_char *)p; + } + } else { + type = pcap_datalink(pd); + printinfo.ndo_type = 1; + printinfo.ndo = gndo; + printinfo.p.ndo_printer = lookup_ndo_printer(type); + if (printinfo.p.ndo_printer == NULL) { + printinfo.p.printer = lookup_printer(type); + printinfo.ndo_type = 0; + if (printinfo.p.printer == NULL) { + gndo->ndo_dltname = pcap_datalink_val_to_name(type); + if (gndo->ndo_dltname != NULL) + error("packet printing is not supported for link type %s: use -w", + gndo->ndo_dltname); + else + error("packet printing is not supported for link type %d: use -w", type); + } + } + callback = print_packet; + pcap_userdata = (u_char *)&printinfo; + } +#ifndef WIN32 + /* + * We cannot do this earlier, because we want to be able to open + * the file (if done) for writing before giving up permissions. + */ + if (getuid() == 0 || geteuid() == 0) { + if (username || chroot_dir) + droproot(username, chroot_dir); + } +#endif /* WIN32 */ +#ifdef SIGINFO + /* + * We can't get statistics when reading from a file rather + * than capturing from a device. + */ + if (RFileName == NULL) + (void)setsignal(SIGINFO, requestinfo); +#endif + + if (vflag > 0 && WFileName) { + /* + * When capturing to a file, "-v" means tcpdump should, + * every 10 secodns, "v"erbosely report the number of + * packets captured. + */ +#ifdef USE_WIN32_MM_TIMER + /* call verbose_stats_dump() each 1000 +/-100msec */ + timer_id = timeSetEvent(1000, 100, verbose_stats_dump, 0, TIME_PERIODIC); + setvbuf(stderr, NULL, _IONBF, 0); +#elif defined(HAVE_ALARM) + (void)setsignal(SIGALRM, verbose_stats_dump); + alarm(1); +#endif + } + +#ifndef WIN32 + if (RFileName == NULL) { + int dlt; + const char *dlt_name; + + if (!vflag && !WFileName) { + (void)fprintf(stderr, + "%s: verbose output suppressed, use -v or -vv for full protocol decode\n", + program_name); + } else + (void)fprintf(stderr, "%s: ", program_name); + dlt = pcap_datalink(pd); + dlt_name = pcap_datalink_val_to_name(dlt); + if (dlt_name == NULL) { + (void)fprintf(stderr, "listening on %s, link-type %u, capture size %u bytes\n", + device, dlt, snaplen); + } else { + (void)fprintf(stderr, "listening on %s, link-type %s (%s), capture size %u bytes\n", + device, dlt_name, + pcap_datalink_val_to_description(dlt), snaplen); + } + (void)fflush(stderr); + } +#endif /* WIN32 */ + status = pcap_loop(pd, cnt, callback, pcap_userdata); + if (WFileName == NULL) { + /* + * We're printing packets. Flush the printed output, + * so it doesn't get intermingled with error output. + */ + if (status == -2) { + /* + * We got interrupted, so perhaps we didn't + * manage to finish a line we were printing. + * Print an extra newline, just in case. + */ + putchar('\n'); + } + (void)fflush(stdout); + } + if (status == -1) { + /* + * Error. Report it. + */ + (void)fprintf(stderr, "%s: pcap_loop: %s\n", + program_name, pcap_geterr(pd)); + } + if (RFileName == NULL) { + /* + * We're doing a live capture. Report the capture + * statistics. + */ + info(1); + } + pcap_close(pd); + exit(status == -1 ? 1 : 0); +} + +/* make a clean exit on interrupts */ +static RETSIGTYPE +cleanup(int signo _U_) +{ +#ifdef USE_WIN32_MM_TIMER + if (timer_id) + timeKillEvent(timer_id); + timer_id = 0; +#elif defined(HAVE_ALARM) + alarm(0); +#endif + +#ifdef HAVE_PCAP_BREAKLOOP + /* + * We have "pcap_breakloop()"; use it, so that we do as little + * as possible in the signal handler (it's probably not safe + * to do anything with standard I/O streams in a signal handler - + * the ANSI C standard doesn't say it is). + */ + pcap_breakloop(pd); +#else + /* + * We don't have "pcap_breakloop()"; this isn't safe, but + * it's the best we can do. Print the summary if we're + * not reading from a savefile - i.e., if we're doing a + * live capture - and exit. + */ + if (pd != NULL && pcap_file(pd) == NULL) { + /* + * We got interrupted, so perhaps we didn't + * manage to finish a line we were printing. + * Print an extra newline, just in case. + */ + putchar('\n'); + (void)fflush(stdout); + info(1); + } + exit(0); +#endif +} + +/* + On windows, we do not use a fork, so we do not care less about + waiting a child processes to die + */ +#ifndef WIN32 +static RETSIGTYPE +child_cleanup(int signo _U_) +{ + wait(NULL); +} +#endif /* WIN32 */ + +static void +info(register int verbose) +{ + struct pcap_stat stat; + + /* + * Older versions of libpcap didn't set ps_ifdrop on some + * platforms; initialize it to 0 to handle that. + */ + stat.ps_ifdrop = 0; + if (pcap_stats(pd, &stat) < 0) { + (void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pd)); + infoprint = 0; + return; + } + + if (!verbose) + fprintf(stderr, "%s: ", program_name); + + (void)fprintf(stderr, "%u packets captured", packets_captured); + if (!verbose) + fputs(", ", stderr); + else + putc('\n', stderr); + (void)fprintf(stderr, "%u packets received by filter", stat.ps_recv); + if (!verbose) + fputs(", ", stderr); + else + putc('\n', stderr); + (void)fprintf(stderr, "%u packets dropped by kernel", stat.ps_drop); + if (stat.ps_ifdrop != 0) { + if (!verbose) + fputs(", ", stderr); + else + putc('\n', stderr); + (void)fprintf(stderr, "%u packets dropped by interface\n", + stat.ps_ifdrop); + } else + putc('\n', stderr); + infoprint = 0; +} + +#ifndef WIN32 +static void +compress_savefile(const char *filename) +{ + if (fork()) + return; + /* + * Set to lowest priority so that this doesn't disturb the capture + */ +#ifdef NZERO + setpriority(PRIO_PROCESS, 0, NZERO - 1); +#else + setpriority(PRIO_PROCESS, 0, 19); +#endif + if (execlp(zflag, zflag, filename, (char *)NULL) == -1) + fprintf(stderr, + "compress_savefile:execlp(%s, %s): %s\n", + zflag, + filename, + strerror(errno)); +} +#else /* WIN32 */ +static void +compress_savefile(const char *filename) +{ + fprintf(stderr, + "compress_savefile failed. Functionality not implemented under windows\n"); +} +#endif /* WIN32 */ + +static void +dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) +{ + struct dump_info *dump_info; + + ++packets_captured; + + ++infodelay; + + dump_info = (struct dump_info *)user; + + /* + * XXX - this won't force the file to rotate on the specified time + * boundary, but it will rotate on the first packet received after the + * specified Gflag number of seconds. Note: if a Gflag time boundary + * and a Cflag size boundary coincide, the time rotation will occur + * first thereby cancelling the Cflag boundary (since the file should + * be 0). + */ + if (Gflag != 0) { + /* Check if it is time to rotate */ + time_t t; + + /* Get the current time */ + if ((t = time(NULL)) == (time_t)-1) { + error("dump_and_trunc_packet: can't get current_time: %s", + pcap_strerror(errno)); + } + + + /* If the time is greater than the specified window, rotate */ + if (t - Gflag_time >= Gflag) { + /* Update the Gflag_time */ + Gflag_time = t; + /* Update Gflag_count */ + Gflag_count++; + /* + * Close the current file and open a new one. + */ + pcap_dump_close(dump_info->p); + + /* + * Compress the file we just closed, if the user asked for it + */ + if (zflag != NULL) + compress_savefile(dump_info->CurrentFileName); + + /* + * Check to see if we've exceeded the Wflag (when + * not using Cflag). + */ + if (Cflag == 0 && Wflag > 0 && Gflag_count >= Wflag) { + (void)fprintf(stderr, "Maximum file limit reached: %d\n", + Wflag); + exit(0); + /* NOTREACHED */ + } + if (dump_info->CurrentFileName != NULL) + free(dump_info->CurrentFileName); + /* Allocate space for max filename + \0. */ + dump_info->CurrentFileName = (char *)malloc(NAME_MAX + 1); + if (dump_info->CurrentFileName == NULL) + error("dump_packet_and_trunc: malloc"); + /* + * This is always the first file in the Cflag + * rotation: e.g. 0 + * We also don't need numbering if Cflag is not set. + */ + if (Cflag != 0) + MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, 0, + WflagChars); + else + MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, 0, 0); + + dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); + if (dump_info->p == NULL) + error("%s", pcap_geterr(pd)); + } + } + + /* + * XXX - this won't prevent capture files from getting + * larger than Cflag - the last packet written to the + * file could put it over Cflag. + */ + if (Cflag != 0 && pcap_dump_ftell(dump_info->p) > Cflag) { + /* + * Close the current file and open a new one. + */ + pcap_dump_close(dump_info->p); + + /* + * Compress the file we just closed, if the user asked for it + */ + if (zflag != NULL) + compress_savefile(dump_info->CurrentFileName); + + Cflag_count++; + if (Wflag > 0) { + if (Cflag_count >= Wflag) + Cflag_count = 0; + } + if (dump_info->CurrentFileName != NULL) + free(dump_info->CurrentFileName); + dump_info->CurrentFileName = (char *)malloc(NAME_MAX + 1); + if (dump_info->CurrentFileName == NULL) + error("dump_packet_and_trunc: malloc"); + MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, Cflag_count, WflagChars); + dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); + if (dump_info->p == NULL) + error("%s", pcap_geterr(pd)); + } + + pcap_dump((u_char *)dump_info->p, h, sp); +#ifdef HAVE_PCAP_DUMP_FLUSH + if (Uflag) + pcap_dump_flush(dump_info->p); +#endif + + --infodelay; + if (infoprint) + info(0); +} + +static void +dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) +{ + ++packets_captured; + + ++infodelay; + + pcap_dump(user, h, sp); +#ifdef HAVE_PCAP_DUMP_FLUSH + if (Uflag) + pcap_dump_flush((pcap_dumper_t *)user); +#endif + + --infodelay; + if (infoprint) + info(0); +} + +static void +print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) +{ + struct print_info *print_info; + u_int hdrlen; + + ++packets_captured; + + ++infodelay; + ts_print(&h->ts); + + print_info = (struct print_info *)user; + + /* + * Some printers want to check that they're not walking off the + * end of the packet. + * Rather than pass it all the way down, we set this global. + */ + snapend = sp + h->caplen; + + if(print_info->ndo_type) { + hdrlen = (*print_info->p.ndo_printer)(print_info->ndo, h, sp); + } else { + hdrlen = (*print_info->p.printer)(h, sp); + } + + if (Xflag) { + /* + * Print the raw packet data in hex and ASCII. + */ + if (Xflag > 1) { + /* + * Include the link-layer header. + */ + hex_and_ascii_print("\n\t", sp, h->caplen); + } else { + /* + * Don't include the link-layer header - and if + * we have nothing past the link-layer header, + * print nothing. + */ + if (h->caplen > hdrlen) + hex_and_ascii_print("\n\t", sp + hdrlen, + h->caplen - hdrlen); + } + } else if (xflag) { + /* + * Print the raw packet data in hex. + */ + if (xflag > 1) { + /* + * Include the link-layer header. + */ + hex_print("\n\t", sp, h->caplen); + } else { + /* + * Don't include the link-layer header - and if + * we have nothing past the link-layer header, + * print nothing. + */ + if (h->caplen > hdrlen) + hex_print("\n\t", sp + hdrlen, + h->caplen - hdrlen); + } + } else if (Aflag) { + /* + * Print the raw packet data in ASCII. + */ + if (Aflag > 1) { + /* + * Include the link-layer header. + */ + ascii_print(sp, h->caplen); + } else { + /* + * Don't include the link-layer header - and if + * we have nothing past the link-layer header, + * print nothing. + */ + if (h->caplen > hdrlen) + ascii_print(sp + hdrlen, h->caplen - hdrlen); + } + } + + putchar('\n'); + + --infodelay; + if (infoprint) + info(0); +} + +#ifdef WIN32 + /* + * XXX - there should really be libpcap calls to get the version + * number as a string (the string would be generated from #defines + * at run time, so that it's not generated from string constants + * in the library, as, on many UNIX systems, those constants would + * be statically linked into the application executable image, and + * would thus reflect the version of libpcap on the system on + * which the application was *linked*, not the system on which it's + * *running*. + * + * That routine should be documented, unlike the "version[]" + * string, so that UNIX vendors providing their own libpcaps + * don't omit it (as a couple of vendors have...). + * + * Packet.dll should perhaps also export a routine to return the + * version number of the Packet.dll code, to supply the + * "Wpcap_version" information on Windows. + */ + char WDversion[]="current-cvs.tcpdump.org"; +#if !defined(HAVE_GENERATED_VERSION) + char version[]="current-cvs.tcpdump.org"; +#endif + char pcap_version[]="current-cvs.tcpdump.org"; + char Wpcap_version[]="3.1"; +#endif + +/* + * By default, print the specified data out in hex and ASCII. + */ +static void +ndo_default_print(netdissect_options *ndo _U_, const u_char *bp, u_int length) +{ + hex_and_ascii_print("\n\t", bp, length); /* pass on lf and identation string */ +} + +void +default_print(const u_char *bp, u_int length) +{ + ndo_default_print(gndo, bp, length); +} + +#ifdef SIGINFO +RETSIGTYPE requestinfo(int signo _U_) +{ + if (infodelay) + ++infoprint; + else + info(0); +} +#endif + +/* + * Called once each second in verbose mode while dumping to file + */ +#ifdef USE_WIN32_MM_TIMER +void CALLBACK verbose_stats_dump (UINT timer_id _U_, UINT msg _U_, DWORD_PTR arg _U_, + DWORD_PTR dw1 _U_, DWORD_PTR dw2 _U_) +{ + struct pcap_stat stat; + + if (infodelay == 0 && pcap_stats(pd, &stat) >= 0) + fprintf(stderr, "Got %u\r", packets_captured); +} +#elif defined(HAVE_ALARM) +static void verbose_stats_dump(int sig _U_) +{ + struct pcap_stat stat; + + if (infodelay == 0 && pcap_stats(pd, &stat) >= 0) + fprintf(stderr, "Got %u\r", packets_captured); + alarm(1); +} +#endif + +static void +usage(void) +{ + extern char version[]; +#ifndef HAVE_PCAP_LIB_VERSION +#if defined(WIN32) || defined(HAVE_PCAP_VERSION) + extern char pcap_version[]; +#else /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */ + static char pcap_version[] = "unknown"; +#endif /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */ +#endif /* HAVE_PCAP_LIB_VERSION */ + +#ifdef HAVE_PCAP_LIB_VERSION +#ifdef WIN32 + (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version); +#else /* WIN32 */ + (void)fprintf(stderr, "%s version %s\n", program_name, version); +#endif /* WIN32 */ + (void)fprintf(stderr, "%s\n",pcap_lib_version()); +#else /* HAVE_PCAP_LIB_VERSION */ +#ifdef WIN32 + (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version); + (void)fprintf(stderr, "WinPcap version %s, based on libpcap version %s\n",Wpcap_version, pcap_version); +#else /* WIN32 */ + (void)fprintf(stderr, "%s version %s\n", program_name, version); + (void)fprintf(stderr, "libpcap version %s\n", pcap_version); +#endif /* WIN32 */ +#endif /* HAVE_PCAP_LIB_VERSION */ + (void)fprintf(stderr, +"Usage: %s [-aAbd" D_FLAG "ef" I_FLAG "KlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [ -c count ]\n", program_name); + (void)fprintf(stderr, +"\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n"); + (void)fprintf(stderr, +"\t\t[ -i interface ] [ -M secret ] [ -r file ]\n"); + (void)fprintf(stderr, +"\t\t[ -s snaplen ] [ -T type ] [ -w file ] [ -W filecount ]\n"); + (void)fprintf(stderr, +"\t\t[ -y datalinktype ] [ -z command ] [ -Z user ]\n"); + (void)fprintf(stderr, +"\t\t[ expression ]\n"); + exit(1); +} + + + +/* VARARGS */ +static void +ndo_error(netdissect_options *ndo _U_, const char *fmt, ...) +{ + va_list ap; + + (void)fprintf(stderr, "%s: ", program_name); + va_start(ap, fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + if (*fmt) { + fmt += strlen(fmt); + if (fmt[-1] != '\n') + (void)fputc('\n', stderr); + } + exit(1); + /* NOTREACHED */ +} + +/* VARARGS */ +static void +ndo_warning(netdissect_options *ndo _U_, const char *fmt, ...) +{ + va_list ap; + + (void)fprintf(stderr, "%s: WARNING: ", program_name); + va_start(ap, fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + if (*fmt) { + fmt += strlen(fmt); + if (fmt[-1] != '\n') + (void)fputc('\n', stderr); + } +} diff --git a/telnet.h b/telnet.h new file mode 100644 index 0000000..33a07be --- /dev/null +++ b/telnet.h @@ -0,0 +1,348 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/telnet.h,v 1.5 2007-08-29 02:31:44 mcr Exp $ (LBL) */ + +/* NetBSD: telnet.h,v 1.9 2001/06/11 01:50:50 wiz Exp */ + +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)telnet.h 8.2 (Berkeley) 12/15/93 + */ + +#ifndef _ARPA_TELNET_H_ +#define _ARPA_TELNET_H_ + +/* + * Definitions for the TELNET protocol. + */ +#define IAC 255 /* interpret as command: */ +#define DONT 254 /* you are not to use option */ +#define DO 253 /* please, you use option */ +#define WONT 252 /* I won't use option */ +#define WILL 251 /* I will use option */ +#define SB 250 /* interpret as subnegotiation */ +#define GA 249 /* you may reverse the line */ +#define EL 248 /* erase the current line */ +#define EC 247 /* erase the current character */ +#define AYT 246 /* are you there */ +#define AO 245 /* abort output--but let prog finish */ +#define IP 244 /* interrupt process--permanently */ +#define BREAK 243 /* break */ +#define DM 242 /* data mark--for connect. cleaning */ +#define NOP 241 /* nop */ +#define SE 240 /* end sub negotiation */ +#define EOR 239 /* end of record (transparent mode) */ +#define ABORT 238 /* Abort process */ +#define SUSP 237 /* Suspend process */ +#define xEOF 236 /* End of file: EOF is already used... */ + +#define SYNCH 242 /* for telfunc calls */ + +#ifdef TELCMDS +const char *telcmds[] = { + "EOF", "SUSP", "ABORT", "EOR", + "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC", + "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0, +}; +#else +extern char *telcmds[]; +#endif + +#define TELCMD_FIRST xEOF +#define TELCMD_LAST IAC +#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \ + (unsigned int)(x) >= TELCMD_FIRST) +#define TELCMD(x) telcmds[(x)-TELCMD_FIRST] + +/* telnet options */ +#define TELOPT_BINARY 0 /* 8-bit data path */ +#define TELOPT_ECHO 1 /* echo */ +#define TELOPT_RCP 2 /* prepare to reconnect */ +#define TELOPT_SGA 3 /* suppress go ahead */ +#define TELOPT_NAMS 4 /* approximate message size */ +#define TELOPT_STATUS 5 /* give status */ +#define TELOPT_TM 6 /* timing mark */ +#define TELOPT_RCTE 7 /* remote controlled transmission and echo */ +#define TELOPT_NAOL 8 /* negotiate about output line width */ +#define TELOPT_NAOP 9 /* negotiate about output page size */ +#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */ +#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */ +#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */ +#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */ +#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */ +#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */ +#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */ +#define TELOPT_XASCII 17 /* extended ascic character set */ +#define TELOPT_LOGOUT 18 /* force logout */ +#define TELOPT_BM 19 /* byte macro */ +#define TELOPT_DET 20 /* data entry terminal */ +#define TELOPT_SUPDUP 21 /* supdup protocol */ +#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */ +#define TELOPT_SNDLOC 23 /* send location */ +#define TELOPT_TTYPE 24 /* terminal type */ +#define TELOPT_EOR 25 /* end or record */ +#define TELOPT_TUID 26 /* TACACS user identification */ +#define TELOPT_OUTMRK 27 /* output marking */ +#define TELOPT_TTYLOC 28 /* terminal location number */ +#define TELOPT_3270REGIME 29 /* 3270 regime */ +#define TELOPT_X3PAD 30 /* X.3 PAD */ +#define TELOPT_NAWS 31 /* window size */ +#define TELOPT_TSPEED 32 /* terminal speed */ +#define TELOPT_LFLOW 33 /* remote flow control */ +#define TELOPT_LINEMODE 34 /* Linemode option */ +#define TELOPT_XDISPLOC 35 /* X Display Location */ +#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */ +#define TELOPT_AUTHENTICATION 37/* Authenticate */ +#define TELOPT_ENCRYPT 38 /* Encryption option */ +#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */ +#define TELOPT_EXOPL 255 /* extended-options-list */ + + +#define NTELOPTS (1+TELOPT_NEW_ENVIRON) +#ifdef TELOPTS +const char *telopts[NTELOPTS+1] = { + "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME", + "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP", + "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS", + "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO", + "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT", + "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD", + "TACACS UID", "OUTPUT MARKING", "TTYLOC", + "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW", + "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION", + "ENCRYPT", "NEW-ENVIRON", + 0, +}; +#define TELOPT_FIRST TELOPT_BINARY +#define TELOPT_LAST TELOPT_NEW_ENVIRON +#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST) +#define TELOPT(x) telopts[(x)-TELOPT_FIRST] +#endif + +/* sub-option qualifiers */ +#define TELQUAL_IS 0 /* option is... */ +#define TELQUAL_SEND 1 /* send option */ +#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */ +#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */ +#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */ + +#define LFLOW_OFF 0 /* Disable remote flow control */ +#define LFLOW_ON 1 /* Enable remote flow control */ +#define LFLOW_RESTART_ANY 2 /* Restart output on any char */ +#define LFLOW_RESTART_XON 3 /* Restart output only on XON */ + +/* + * LINEMODE suboptions + */ + +#define LM_MODE 1 +#define LM_FORWARDMASK 2 +#define LM_SLC 3 + +#define MODE_EDIT 0x01 +#define MODE_TRAPSIG 0x02 +#define MODE_ACK 0x04 +#define MODE_SOFT_TAB 0x08 +#define MODE_LIT_ECHO 0x10 + +#define MODE_MASK 0x1f + +/* Not part of protocol, but needed to simplify things... */ +#define MODE_FLOW 0x0100 +#define MODE_ECHO 0x0200 +#define MODE_INBIN 0x0400 +#define MODE_OUTBIN 0x0800 +#define MODE_FORCE 0x1000 + +#define SLC_SYNCH 1 +#define SLC_BRK 2 +#define SLC_IP 3 +#define SLC_AO 4 +#define SLC_AYT 5 +#define SLC_EOR 6 +#define SLC_ABORT 7 +#define SLC_EOF 8 +#define SLC_SUSP 9 +#define SLC_EC 10 +#define SLC_EL 11 +#define SLC_EW 12 +#define SLC_RP 13 +#define SLC_LNEXT 14 +#define SLC_XON 15 +#define SLC_XOFF 16 +#define SLC_FORW1 17 +#define SLC_FORW2 18 +#define SLC_MCL 19 +#define SLC_MCR 20 +#define SLC_MCWL 21 +#define SLC_MCWR 22 +#define SLC_MCBOL 23 +#define SLC_MCEOL 24 +#define SLC_INSRT 25 +#define SLC_OVER 26 +#define SLC_ECR 27 +#define SLC_EWR 28 +#define SLC_EBOL 29 +#define SLC_EEOL 30 + +#define NSLC 30 + +/* + * For backwards compatibility, we define SLC_NAMES to be the + * list of names if SLC_NAMES is not defined. + */ +#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \ + "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \ + "LNEXT", "XON", "XOFF", "FORW1", "FORW2", \ + "MCL", "MCR", "MCWL", "MCWR", "MCBOL", \ + "MCEOL", "INSRT", "OVER", "ECR", "EWR", \ + "EBOL", "EEOL", \ + 0, + +#ifdef SLC_NAMES +const char *slc_names[] = { + SLC_NAMELIST +}; +#else +extern char *slc_names[]; +#define SLC_NAMES SLC_NAMELIST +#endif + +#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC) +#define SLC_NAME(x) slc_names[x] + +#define SLC_NOSUPPORT 0 +#define SLC_CANTCHANGE 1 +#define SLC_VARIABLE 2 +#define SLC_DEFAULT 3 +#define SLC_LEVELBITS 0x03 + +#define SLC_FUNC 0 +#define SLC_FLAGS 1 +#define SLC_VALUE 2 + +#define SLC_ACK 0x80 +#define SLC_FLUSHIN 0x40 +#define SLC_FLUSHOUT 0x20 + +#define OLD_ENV_VAR 1 +#define OLD_ENV_VALUE 0 +#define NEW_ENV_VAR 0 +#define NEW_ENV_VALUE 1 +#define ENV_ESC 2 +#define ENV_USERVAR 3 + +/* + * AUTHENTICATION suboptions + */ + +/* + * Who is authenticating who ... + */ +#define AUTH_WHO_CLIENT 0 /* Client authenticating server */ +#define AUTH_WHO_SERVER 1 /* Server authenticating client */ +#define AUTH_WHO_MASK 1 + +/* + * amount of authentication done + */ +#define AUTH_HOW_ONE_WAY 0 +#define AUTH_HOW_MUTUAL 2 +#define AUTH_HOW_MASK 2 + +/* + * should we be encrypting? (not yet formally standardized) + */ +#define AUTH_ENCRYPT_OFF 0 +#define AUTH_ENCRYPT_ON 4 +#define AUTH_ENCRYPT_MASK 4 + +#define AUTHTYPE_NULL 0 +#define AUTHTYPE_KERBEROS_V4 1 +#define AUTHTYPE_KERBEROS_V5 2 +#define AUTHTYPE_SPX 3 +#define AUTHTYPE_MINK 4 +#define AUTHTYPE_CNT 5 + +#define AUTHTYPE_TEST 99 + +#ifdef AUTH_NAMES +const char *authtype_names[] = { + "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0, +}; +#else +extern char *authtype_names[]; +#endif + +#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT) +#define AUTHTYPE_NAME(x) authtype_names[x] + +/* + * ENCRYPTion suboptions + */ +#define ENCRYPT_IS 0 /* I pick encryption type ... */ +#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */ +#define ENCRYPT_REPLY 2 /* Initial setup response */ +#define ENCRYPT_START 3 /* Am starting to send encrypted */ +#define ENCRYPT_END 4 /* Am ending encrypted */ +#define ENCRYPT_REQSTART 5 /* Request you start encrypting */ +#define ENCRYPT_REQEND 6 /* Request you send encrypting */ +#define ENCRYPT_ENC_KEYID 7 +#define ENCRYPT_DEC_KEYID 8 +#define ENCRYPT_CNT 9 + +#define ENCTYPE_ANY 0 +#define ENCTYPE_DES_CFB64 1 +#define ENCTYPE_DES_OFB64 2 +#define ENCTYPE_CNT 3 + +#ifdef ENCRYPT_NAMES +const char *encrypt_names[] = { + "IS", "SUPPORT", "REPLY", "START", "END", + "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID", + 0, +}; +const char *enctype_names[] = { + "ANY", "DES_CFB64", "DES_OFB64", 0, +}; +#else +extern char *encrypt_names[]; +extern char *enctype_names[]; +#endif + + +#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT) +#define ENCRYPT_NAME(x) encrypt_names[x] + +#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT) +#define ENCTYPE_NAME(x) enctype_names[x] + +#endif /* _ARPA_TELNET_H_ */ diff --git a/tests/02-sunrise-sunset-esp.puu b/tests/02-sunrise-sunset-esp.puu new file mode 100644 index 0000000..0ceffc1 --- /dev/null +++ b/tests/02-sunrise-sunset-esp.puu @@ -0,0 +1,34 @@ +begin 644 02-sunrise-sunset-esp.pcap +MU,.RH0(`!``````````````&```!``````````````"6````E@```!```&1D +M11```&1D(P@`10``B/]G``!`,O:5P`$"%\`!`BT2-%9X`````4P@12\\L)(1 +MTZ=(S>7($>.<3N@\_I:AY"K/TKAZJP719"NCKYP;PT(0+$"M%=]-X"`*8V.' +M-'$1A]02"3N#OZI#&1R]A*1;`G8S@YFQ]`````(:<$'CW)%VZ',2KQMB@CN?'"^GJ<=: +MD-0`+.V^J'2AK).'XQ_B"B8:[%A_+K[6KS2'XR[UN`,R"BJP?^].ZM#/[$)# +M17^!D"8_[BZ>GU4Z*$7I"N$U*>J47?C-4;I>#`%6+#0%]D75YC']*Z\````` +M`````)8```"6````$```9&1%$```9&0C"`!%``"(_VD``$`R]I/``0(7P`$" +M+1(T5G@````#7?C-4;I>#`%@W%89?QJ#$TJ,4G\FO&HO=F+,,%1E(]);XI]T +MV7W.RY$2=JZ1%!QCNX[;^.JD4W91;7)NJWV2MF4?7`=&_3OWW%V&6RIXKB75 +M#;2TWNL"A:MF!I@_5R^]L6;Z`L?E@1:T&71G``````````"6````E@```!`` +M`&1D11```&1D(P@`10``B/]J``!`,O:2P`$"%\`!`BT2-%9X````!*MF!I@_ +M5R^]%';9*Q:S_B]]O_8FV:2K1A!]/SQHI7>OS815*I?4%/:.=BBJUEGJ(X8\ +MP1E/@&P\9MR)DP3[UCWI@,MR%A$\CR]=G(("[CFB7AUN$AENZOO&\:7% +M2KLW<'NP,L(I=!;8=0``````````E@```)8````0``!D9$40``!D9",(`$4` +M`(C_:P``0#+VD<`!`A?``0(M$C16>`````5NZOO&\:7%2J12,9;LOK"-S,=$ +MO0]X+J(OJQED#PLBRY[\^352UZK&576,Z<:%73AWV3:;Y/:=@(` +M`````````)8```"6````$```9&1%$```9&0C"`!%``"(_VP``$`R]I#``0(7 +MP`$"+1(T5G@````&M,^T?7>6,Z=>N_YZQFV[H1^6\!/I*IMAOHZE\E0M.Z!X +M#[0EG3#>%]7`]*2F?@S4X2''TK09J@NG/.HEXCE./..K^'-@":X[\?0L+B`S +MQA\HTK\'J]:S]N6O`]\)NQD)9;H2P\K`^NX37`R5``````````"6````E@`` +M`!```&1D11```&1D(P@`10``B/]M``!`,O:/P`$"%\`!`BT2-%9X````!^6O +M`]\)NQD)>BYZ>`/DA=N;A2...3-7FZOK?:5KGXBN`/E?$\[-11-$G#E;(>N" +M+<$/YP'SM$>16LU18&Q]9)$]0)/M]:2Z#A6]-,SM*>FI/`X*K-*-:KS3IW<" +MO(>(P(K=:X::SJ;O[J>0K```````````E@```)8````0``!D9$40``!D9",( +M`$4``(C_;@``0#+VCL`!`A?``0(M$C16>`````C3IW<"O(>(P'-43;C[`MCD +M`BMZAX]F!?'Z$8Q"5HYMVDC9"8I^O(Z4!/)`/IVD-(ZK)_52-H2XK+,(-LR) +MM)K#XLF">KY0>C?\[MA%3F%$?ORJ@:>O]5H>?-$OQH)J:['.C0J(%P +MVF'>(TU6&*"9A,`,/KS\:>DH>O_L(51)_[YY"L9?8'?J4V:_.]B+6UR\T>39D+=NA;$``````````*8```"F````$``` +M9&1%$```9&0C"`!%``"8_.L``$`R^0'``0(7P`$"+=$C16<````";K2P<-=Q +MYE]@=^I39K\[V$1HDU9'L,6BVK.^B4]E6QY&:?3?T)G?"RSU;X!J]]7S)<`, +M*L!SYO^RUWR?!EIJMWU=5B406YL-I`]LK`^;-3%(NEY#R`ST=W40=:*[M$*8 +M#`GLTK(5ZCS"BC@``````````I@```*8````0 +M``!D9$40``!D9",(`$4``)C\[```0#+Y`,`!`A?``0(MT2-%9P````,-RO@E +M%F`X`Y3]7F3YK9N>=6-;U&'6">_4H80DMY^Z9E3ZL3[ONN*L<"Z@7(VO]XT^ +M/2JP<(/^8NTO-4\/B5AJEC4N;,\"7-&(;9AM_2G5A1C.[LBK3')P?AE;$I[) +M!8N&RC?OTD77ELURFXRD/JD(:@RER``````````"F````I@`` +M`!```&1D11```&1D(P@`10``F/SM``!`,OC_P`$"%\`!`BW1(T5G````!(;* +M-^_21=S8F&G50PJ5Y>5K%@R;)A(E<5YD'@86@GT"-&&MHP*.A=?%=:FDZH=4 +M*9":>]'G'CB4%2?PJ"2^H*51\8P!9T`X3#;F+H$[4Z$7ZL0<\S=S\%`:BW9U2'@U^@D,,:.P``````````*8```"F +M````$```9&1%$```9&0C"`!%``"8_.X``$`R^/[``0(7P`$"+=$C16<````% +M,2>GIY3H1?JQ!SS-W/P4!BW&*&A[$!XGK<^M^>_X193"G"1QTWG>Q"CO25$" +MPM+1+8[6&(17\EE\P:6-WVPT=911?@'-Z,,/UVZ2!QV(X4513U9]P62CJMS> +M^ODBGHU=%T.H2&Z<4,8(!4,2[&A4^H="L:+`=4G?*(7,2@``````````I@`` +M`*8````0``!D9$40``!D9",(`$4``)C\[P``0#+X_<`!`A?``0(MT2-%9P`` +M``870ZA(;IQ0Q@@%0Q+L:%3Z@*HQPZA]3STWDY#CYJGOJH)K>I' +MEHMF"X!^G,H@,YWT7^=60.3/$7?AYH)G9GBD%%#,D]!EDA]B*?UE>U96+"5\ +MK=""/.LO'__^;$NI`L#D]@&G?Z7B2O#GI?NDK +MF[7JPN,8V\H>%G+)'+%+FL*&\8+H2^KFWF5YQ:$4V!,1?G;=OYD;!,3YD'V( +MW[Y!I(U=X9[\:L)(5GBJ,B!-5N$.CGV$VLD^R?Z,KL[AMI(ZC-P````````` +M`*8```"F````$```9&1%$```9&0C"`!%``"8_/$``$`R^/O``0(7P`$"+=$C +M16<````(PDA6>*HR($U6X0Z.?83:R;Y0&'2065/"*M'ELXD?1%3\L3TC.UK +HKWB(C5O@78>9LQ^<0Z6]F=:<;@[>L^;/\-6WB81[GX)LGD@`` +` +end diff --git a/tests/08-sunrise-sunset-esp2.puu b/tests/08-sunrise-sunset-esp2.puu new file mode 100644 index 0000000..4785f2b --- /dev/null +++ b/tests/08-sunrise-sunset-esp2.puu @@ -0,0 +1,43 @@ +begin 644 08-sunrise-sunset-esp2.pcap +MU,.RH0(`!``````````````&```!``````````````#.````S@```!```&1D +M11```&1D(P@`10``P"E-``!`,LQXP`$"%\`!`BT2-%9X`````4=!+\5+F8`+ +M[[NOU-#98*AO5\780X[VDXF@2W8<10:J!'!Z!-[7N4CFNRKIH;PUA1SL"Y9\ +M-?_3N_,W/@*T+C/"]=S[`;D!/;`SR5,3+><9K.^\9N><18TY9Z\!I\S./L8R +MFE53,S6Y5X_Z\(T)ZIUS?X$8>&(_MT1"!SV:VPP!\XU$[3S-5L)4-O"&>]`Z +M1:./61=%C6`6U1/65"A&KUE902]*``````````#.````S@```!```&1D11`` +M`&1D(P@`10``P"E/``!`,LQVP`$"%\`!`BT2-%9X`````CIU^SX%;G^!GUSP +MSA +ML7P6FM81),N>T/1Z'"P7H5;```````````#.````S@```!```&1D11```&1D +M(P@`10``P"E1``!`,LQTP`$"%\`!`BT2-%9X`````R4)-P&F>HPK/?_$MTFC +M^TOO=/L#W_APTK6MIH_BC*I7\L<,9(?/0M"HK3[T3F;(Y2V70$P5?D'7GFIB +MJZ/C",S/BD!9N8GV"\.;GVME[P!@!B1"DT=1W0_75FMI23H!T2^C);4GY>`I +M-2T^O_0_WU&$)&+/P)%[TQUQ-T7G%\RXYJT0HO[$=< +M`@@TL1#(Y980]E*/!^2@G`*&S9O^QMS1S?/`TL=5F9B(12?(145>Y2I+;+T? +MKWUD@&.7U36]K-$[.%9CB*FK^E8>N:K/)4#$]ZO/:=#;MRH-)_139\,W6M4T +M7SQ?BBX>,+A3#BB5^O=>+GKIC-4]5VBP)D-S7-)\W&;<@_J@,*!``````````#.````S@```!```&1D11```&1D(P@`10`` +MP"E5``!`,LQPP`$"%\`!`BT2-%9X````!0OIFA;,@2C4HF3>5!-C(0>5LR0" +M='1\OQ.!-?@D(U0!453"``````````#.````S@```!```&1D11```&1D(P@`10``P"E7 +M``!`,LQNP`$"%\`!`BT2-%9X````!I0M"-THEF=+!L=>A3N,\1+"'Z7(J?O0 +M.B?)(#X=/5F-.">%3.X'(=JKK:WZMN +M=B+^Q3"(KE\1299]=5E,'.&U(`H9N)+>9FS/`CA*>D^>AV.-C(S\)BM&)*XM +M^BF__^<_``````````#.````S@```!```&1D11```&1D(P@`10``P"E9``!` +M,LQLP`$"%\`!`BT2-%9X````!R"SQ'[6%(;Q>>O+]CS6D*+AD3IMC\^MMK8[ +M:T3)KM06!G^.H\>%UAT@)X6JL9\3V.HR"+_Q^_T-O$Y_S":_TP;V,LIV1O]H +M-G@DOL'V-5)O@%<%!#O$2V,AS@W7(&$IX.YKK]\K#>FITU)<>O42T2GKFW+^ +M\/[,>E4P[Q"+7O,Y1(R22LND[H+469(%3,SN&3:U:/I`'&R@<`HKGOV,^#L9,QF%)W^9!VFM +MXG'XY]CWI5VF33?7,*P?6:.PS'&[\N$7W<*==+;P*$./4*OH&=O,6G!JIN>I +M'ZDP*D&4K>SK-\/!7\Z&<&5J4%NU?NRM&25'*_"'UE3VH&?U]/V@932UYZT\ +` +end diff --git a/tests/TESTLIST b/tests/TESTLIST new file mode 100644 index 0000000..bbc19b6 --- /dev/null +++ b/tests/TESTLIST @@ -0,0 +1,51 @@ +# BGP test +bgp_vpn_attrset bgp_vpn_attrset.pcap bgp_vpn_attrset.out -t -v + +# EAP tests +eapon1 eapon1.pcap eapon1.out -t + +# ESP tests +esp0 02-sunrise-sunset-esp.pcap esp0.out -t +esp1 02-sunrise-sunset-esp.pcap esp1.out -t -E "0x12345678@192.1.2.45 3des-cbc-hmac96:0x4043434545464649494a4a4c4c4f4f515152525454575758" +esp2 08-sunrise-sunset-esp2.pcap esp2.out -t -E "0x12345678@192.1.2.45 3des-cbc-hmac96:0x43434545464649494a4a4c4c4f4f51515252545457575840,0xabcdabcd@192.0.1.1 3des-cbc-hmac96:0x434545464649494a4a4c4c4f4f5151525254545757584043" +esp3 02-sunrise-sunset-esp.pcap esp1.out -t -E "3des-cbc-hmac96:0x4043434545464649494a4a4c4c4f4f515152525454575758" +esp4 08-sunrise-sunset-esp2.pcap esp2.out -t -E "file esp-secrets.txt" +esp5 08-sunrise-sunset-aes.pcap esp5.out -t -E "file esp-secrets.txt" +espudp1 espudp1.pcap espudp1.out -t -E "file esp-secrets.txt" + +# ISAKMP tests +isakmp1 isakmp-delete-segfault.pcap isakmp1.out -t +isakmp2 isakmp-pointer-loop.pcap isakmp2.out -t +isakmp3 isakmp-identification-segfault.pcap isakmp3.out -t -v +isakmp4 isakmp4500.pcap isakmp4.out -t -E "file esp-secrets.txt" + +# LMP tests (what is it?) +# fails right now. +#lmp lmp.pcap lmp.out -t -v -v + +# MPLS tests +mpls-ldp-hello mpls-ldp-hello.pcap mpls-ldp-hello.out -t -v + +# OSPF tests +ospf-gmpls ospf-gmpls.pcap ospf-gmpls.out -t -v + +# IKEv2 tests +ikev2four ikev2four.pcap ikev2four.out -t -v +ikev2fourv ikev2four.pcap ikev2fourv.out -t -v -v -v +ikev2fourv4 ikev2four.pcap ikev2fourv4.out -t -v -v -v -v +ikev2pI2 ikev2pI2.pcap ikev2pI2.out -t -E "file ikev2pI2-secrets.txt" -v -v -v -v + +# IETF ROLL RPL packets +dio01 dio.pcap dio.out -t -v + +# IPNET encapsulated site +e1000g e1000g.pcap e1000g.out -t + +# IETF FORCES WG packets and printer +forces01 forces1.pcap forces1.out -t +forces02 forces2.pcap forces2.out -t +forces02v forces2.pcap forces2v.out -t -v +forces02vv forces2.pcap forces2vv.out -t -v -v +forces01vvv forces1.pcap forces1vvv.out -t -v -v -v +forces01vvvv forces1.pcap forces1vvvv.out -t -v -v -v -v + diff --git a/tests/TESTonce b/tests/TESTonce new file mode 100755 index 0000000..40d544b --- /dev/null +++ b/tests/TESTonce @@ -0,0 +1,46 @@ +#!/usr/bin/perl + +system("mkdir -p NEW DIFF"); + +if(@ARGV == 1) { + open(TESTLIST, "TESTLIST") || die "can not open TESTLIST: $!\n"; + $wanted = $ARGV[0]; + #print "Searching for test case $wanted\n"; + while() { + #print "Processing $_\n"; + next unless (/^$wanted/); + + chop; + ($name,$input,$output,$options)=split(/\s+/,$_, 4); + last; + } + close(TESTLIST); + + die "Can not find test $wanted\n" unless defined($input); + +} elsif(@ARGV == 4) { + $name=$ARGV[0]; + $input=$ARGV[1]; + $output=$ARGV[2]; + $options=$ARGV[3]; +} else { + print "Usage: TESTonce name [input output options]\n"; + exit 20; +} + +print "Running $name. \n"; +print " Input: $input, OUTPUT: $output, OPTIONS: $options\n"; + +if (! -f $input) { + ($puu = $input) =~ s/\.pcap/\.puu/; + if( -f $puu) { + print "Uudecoding $puu to make $input\n"; + system("uudecode $puu"); + } +} + +print " "; +exec("../tcpdump -n -r $input $options | tee NEW/$output | diff -w - $output >DIFF/$output.diff"); +@cores = glob("core*"); +exit 10 if (@cores > 0); +exit 0; diff --git a/tests/TESTrun.sh b/tests/TESTrun.sh new file mode 100755 index 0000000..656974d --- /dev/null +++ b/tests/TESTrun.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +mkdir -p NEW +mkdir -p DIFF +passed=0 +failed=0 + +# first run any specific tests. +for i in *.sh +do + case $i in TEST*.sh) continue;; esac + + if sh ./$i >DIFF/$i.result + then + echo $i: passed. + rm -f DIFF/$i.result + passed=$(($passed + 1)) + else + echo $i: failed. + failed=$(($failed + 1)) + fi +done + +echo $passed >.passed +echo $failed >.failed + +# now run typical tests +cat TESTLIST | while read name input output options +do + case $name in + \#*) continue;; + '') continue;; + esac + + if ./TESTonce $name $input $output "$options" + then + echo $name: passed. + rm -f DIFF/$output.diff + passed=$(($passed + 1)) + echo $passed >.passed + else + echo $name: failed. + failed=$(($failed + 1)) + echo $failed >.failed + fi +done + +# I hate shells with their stupid, useless subshells. +passed=`cat .passed` +failed=`cat .failed` + +# exit with number of failing tests. +echo +echo +printf "%4u tests failed\n" $failed +printf "%4u tests passed\n" $passed +echo +echo +exit $failed + + + + diff --git a/tests/bgp-infinite-loop.pcap b/tests/bgp-infinite-loop.pcap new file mode 100644 index 0000000000000000000000000000000000000000..9f07d41228266c2a34be727de5fba4a79d118a35 GIT binary patch literal 554 zcmca|c+)~A1{MYwNB}YlfjH%AzLQ%d4?`4?4Z;j8OhDqC7Kq8fz`@|kz~IHY+kv5h z&F<_GYXipvD;OEg+ZZ-awqBymIY~MturZlJRu2WQ~g(l%}z5H e6+ASHi~!lRC5#w9r2<3Gcq=51aK#gKYytqiNWOsp literal 0 HcmV?d00001 diff --git a/tests/bgp_vpn_attrset.out b/tests/bgp_vpn_attrset.out new file mode 100644 index 0000000..a0a9f1c --- /dev/null +++ b/tests/bgp_vpn_attrset.out @@ -0,0 +1,19 @@ +IP (tos 0xc0, ttl 62, id 58628, offset 0, flags [none], proto TCP (6), length 173) + 12.4.4.4.2051 > 12.1.1.1.179: Flags [P.], cksum 0xcf18 (correct), seq 3293077573:3293077694, ack 3348108582, win 16384, options [nop,nop,TS val 383131 ecr 890299], length 121: BGP, length: 121 + Update Message (2), length: 121 + Origin (1), length: 1, Flags [T]: IGP + AS Path (2), length: 0, Flags [T]: empty + Local Preference (5), length: 4, Flags [T]: 100 + Extended Community (16), length: 8, Flags [OT]: + target (0x0002), Flags [none]: 300:300 (= 0.0.1.44) + Attribute Set (128), length: 36, Flags [OT]: + Origin AS: 65001 + Origin (1), length: 1, Flags [T]: IGP + AS Path (2), length: 4, Flags [T]: 5555 + Local Preference (5), length: 4, Flags [T]: 44 + Originator ID (9), length: 4, Flags [O]: 22.5.5.5 + Cluster List (10), length: 4, Flags [O]: 22.5.5.5 + Multi-Protocol Reach NLRI (14), length: 30, Flags [OE]: + AFI: IPv4 (1), SAFI: labeled VPN Unicast (128) + nexthop: RD: 0:0 (= 0.0.0.0), 12.4.4.4, nh-length: 12, no SNPA + RD: 500:500 (= 0.0.1.244), 133.0.0.0/8, label:100208 (bottom) diff --git a/tests/bgp_vpn_attrset.pcap b/tests/bgp_vpn_attrset.pcap new file mode 100644 index 0000000000000000000000000000000000000000..e60aff5c838bf9cd06213d916d83c94b91b111af GIT binary patch literal 217 zcmca|c+)~A1{MYw*ul-fzzO6yS-r5|@|uldBajWk|Ct#ST@NsX9tI&G8-)8A8ccx{69X@oVYow_8q0qGOI`}U literal 0 HcmV?d00001 diff --git a/tests/chdlc-slarp.pcap b/tests/chdlc-slarp.pcap new file mode 100644 index 0000000000000000000000000000000000000000..1521443a8f15788b24c59940549735f0f58418c9 GIT binary patch literal 62 zcmca|c+)~A1{MYwNB}Z2fVk;&ghS>X9tJTW8-)8A8ccx{69X@oVYow_8q5FxQZG3H DeP0aH literal 0 HcmV?d00001 diff --git a/tests/dio.out b/tests/dio.out new file mode 100644 index 0000000..fd0846a --- /dev/null +++ b/tests/dio.out @@ -0,0 +1 @@ +IP6 (hlim 255, next-header ICMPv6 (58) payload length: 24) fe80::1000:ff:fe64:6423 > ff02::1: [icmp6 sum ok] ICMP6, RPL, length 24, DAG Information Object [seq:10,instance:42,rank:1,dagid:thisismynicedag1] diff --git a/tests/dio.pcap b/tests/dio.pcap new file mode 100644 index 0000000000000000000000000000000000000000..81706352a563b86d77b2c651cf61751e220cde67 GIT binary patch literal 120 zcmca|c+)~A1{MYw`2U}Qp%BP99`xU9*=a_G03aKL8JHLt8Q6pv7*bM{85r8`CV<2w ytp5LN05KRC1Q;0p{{zbXXM*sdB;#zR@=OLUEyj|J%;L=A+{(Pn 10.5.233.117: ICMP echo request, id 6901, seq 0, length 64 +IP 10.5.233.117 > 129.146.106.55: ICMP echo reply, id 6901, seq 0, length 64 +IP 129.146.106.55 > 10.5.233.117: ICMP echo request, id 6901, seq 1, length 64 +IP 10.5.233.117 > 129.146.106.55: ICMP echo reply, id 6901, seq 1, length 64 +IP 129.146.106.55 > 10.5.233.117: ICMP echo request, id 6901, seq 2, length 64 +IP 10.5.233.117 > 129.146.106.55: ICMP echo reply, id 6901, seq 2, length 64 +IP 129.146.106.55 > 10.5.233.117: ICMP echo request, id 6901, seq 3, length 64 +IP 10.5.233.117 > 129.146.106.55: ICMP echo reply, id 6901, seq 3, length 64 +IP 129.146.106.55 > 10.5.233.117: ICMP echo request, id 6901, seq 4, length 64 +IP 10.5.233.117 > 129.146.106.55: ICMP echo reply, id 6901, seq 4, length 64 +IP 129.146.106.55 > 10.5.233.117: ICMP echo request, id 6901, seq 5, length 64 +IP 10.5.233.117 > 129.146.106.55: ICMP echo reply, id 6901, seq 5, length 64 +IP 129.146.106.55 > 10.5.233.117: ICMP echo request, id 6901, seq 6, length 64 +IP 10.5.233.117 > 129.146.106.55: ICMP echo reply, id 6901, seq 6, length 64 +IP 129.146.106.55 > 10.5.233.117: ICMP echo request, id 6901, seq 7, length 64 +IP 10.5.233.117 > 129.146.106.55: ICMP echo reply, id 6901, seq 7, length 64 +IP 129.146.106.55 > 10.5.233.117: ICMP echo request, id 6901, seq 8, length 64 +IP 10.5.233.117 > 129.146.106.55: ICMP echo reply, id 6901, seq 8, length 64 +IP 129.146.106.55 > 10.5.233.117: ICMP echo request, id 6901, seq 9, length 64 +IP 10.5.233.117 > 129.146.106.55: ICMP echo reply, id 6901, seq 9, length 64 diff --git a/tests/e1000g.pcap b/tests/e1000g.pcap new file mode 100644 index 0000000000000000000000000000000000000000..11b0174504a3b24eb545c47aa55eaef39a77c29b GIT binary patch literal 2504 zcmbu=OGp)A6u|K_bDv%vUsvx=o4-E^422tAQF^N zm@ADI2CYPBky`m^83++Atb7HMdOPPVJbasv>wE(<%nSp6eskurG&A+w1}_{eet=ax z*uU>YdftYh1NUjQY`!9jTi%P~LT9c6M8Ed}>{z?Yk7DgLA>YpjL8w~I-v(HF=tQRP zB||VNl$_$Erln_OhO@Gdv1-9sSi+V)Q)3&IF_KhkKIe+p75aC`i1VgYlnAJdsJy_ z+_%`BCGIyyZD?~M4N9BtvfOiJ-u>)e6!&Wz-S%&nZff69+8Xz5c8A41Wz@E?{ca$^ zc@MDri@2Xz==S_Ucf`fKsr_DQYut_O&J_1cqqdFhHl?kZcZ}Vi#XSz__O7G*stY%@ zJC(M^-Nfz;aZehxJ=h*o+8Xy0c7GE0!allv8|codKm7Ym?N>@$%;|E5bfweKozjk}rMY2scnYWuJ~+n?b3J;?5Paev!IcVG+MJ{R+* z_6Mb{aksELRop*}+J0)7`3~Vw#MDcZb#e`M(qH$3zW9z jIUi>CM{$q*LwC|&bT_#8u2H*KX=~hf*qtKo7e?*>H-htv literal 0 HcmV?d00001 diff --git a/tests/eapon1.gdbinit b/tests/eapon1.gdbinit new file mode 100644 index 0000000..37ad0bc --- /dev/null +++ b/tests/eapon1.gdbinit @@ -0,0 +1 @@ +set args -r eapon1.pcap diff --git a/tests/eapon1.out b/tests/eapon1.out new file mode 100644 index 0000000..69f7537 --- /dev/null +++ b/tests/eapon1.out @@ -0,0 +1,114 @@ +IP 192.168.1.249.138 > 192.168.1.255.138: NBT UDP PACKET(138) +IP 192.168.1.249.138 > 192.168.1.255.138: NBT UDP PACKET(138) +IP 192.168.1.249.138 > 192.168.1.255.138: NBT UDP PACKET(138) +IP 192.168.1.249.137 > 192.168.1.255.137: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST +IP 192.168.1.249.137 > 192.168.1.255.137: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST +IP 192.168.1.249.137 > 192.168.1.255.137: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST +IP 192.168.1.249.138 > 192.168.1.255.138: NBT UDP PACKET(138) +IP 192.168.1.249.137 > 192.168.1.255.137: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST +IP 192.168.1.249.137 > 192.168.1.255.137: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST +IP 192.168.1.249.137 > 192.168.1.255.137: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST +ARP, Request who-has 192.168.1.1 tell 192.168.1.249, length 28 +ARP, Reply 192.168.1.1 is-at 00:0d:88:4f:25:91, length 46 +IP 192.168.1.249.68 > 192.168.1.1.67: BOOTP/DHCP, Request from 00:04:23:57:a5:7a, length 300 +EAP packet (0) v1, len 5 +IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:04:23:57:a5:7a, length 300 +IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:04:23:57:a5:7a, length 300 +EAPOL start (1) v1, len 0 +EAP packet (0) v1, len 5 +EAP packet (0) v1, len 45 +EAP packet (0) v1, len 20 +EAP packet (0) v1, len 76 +EAP packet (0) v1, len 80 +EAP packet (0) v1, len 28 +EAP packet (0) v1, len 4 +EAPOL key (3) v1, len 57 +EAPOL key (3) v1, len 44 +IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:04:23:57:a5:7a, length 300 +IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:04:23:57:a5:7a, length 300 +IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:04:23:57:a5:7a, length 300 +EAPOL start (1) v1, len 0 +EAP packet (0) v1, len 5 +EAP packet (0) v1, len 45 +EAP packet (0) v1, len 20 +EAP packet (0) v1, len 76 +EAP packet (0) v1, len 80 +EAP packet (0) v1, len 28 +EAP packet (0) v1, len 4 +EAPOL key (3) v1, len 57 +EAPOL key (3) v1, len 44 +ARP, Request who-has 169.254.67.194 tell 169.254.67.194, length 28 +ARP, Request who-has 169.254.67.194 tell 169.254.67.194, length 28 +ARP, Request who-has 169.254.67.194 tell 169.254.67.194, length 28 +IP 169.254.67.194.4299 > 239.255.255.250.1900: UDP, length 133 +IP 169.254.67.194 > 224.0.0.22: igmp v3 report, 1 group record(s) +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194 > 224.0.0.22: igmp v3 report, 1 group record(s) +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:04:23:57:a5:7a, length 300 +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.4299 > 239.255.255.250.1900: UDP, length 133 +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +EAPOL start (1) v1, len 0 +EAP packet (0) v1, len 5 +EAP packet (0) v1, len 45 +EAP packet (0) v1, len 20 +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +EAP packet (0) v1, len 76 +EAP packet (0) v1, len 80 +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +EAP packet (0) v1, len 28 +EAP packet (0) v1, len 4 +EAPOL key (3) v1, len 57 +EAPOL key (3) v1, len 44 +IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:04:23:57:a5:7a, length 300 +IP 169.254.67.194.4299 > 239.255.255.250.1900: UDP, length 133 +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.138 > 169.254.255.255.138: NBT UDP PACKET(138) +IP 169.254.67.194.138 > 169.254.255.255.138: NBT UDP PACKET(138) +IP 169.254.67.194.138 > 169.254.255.255.138: NBT UDP PACKET(138) +IP 169.254.67.194.138 > 169.254.255.255.138: NBT UDP PACKET(138) +IP 169.254.67.194.138 > 169.254.255.255.138: NBT UDP PACKET(138) +IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:04:23:57:a5:7a, length 300 +IP 169.254.67.194.138 > 169.254.255.255.138: NBT UDP PACKET(138) +IP 169.254.67.194.138 > 169.254.255.255.138: NBT UDP PACKET(138) +IP 169.254.67.194.138 > 169.254.255.255.138: NBT UDP PACKET(138) +IP 169.254.67.194.138 > 169.254.255.255.138: NBT UDP PACKET(138) +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST +IP 169.254.67.194.138 > 169.254.255.255.138: NBT UDP PACKET(138) +IP 169.254.67.194.138 > 169.254.255.255.138: NBT UDP PACKET(138) +IP 169.254.67.194.138 > 169.254.255.255.138: NBT UDP PACKET(138) +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST +IP 169.254.67.194.137 > 169.254.255.255.137: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST +IP 0.0.0.0.68 > 255.255.255.255.67: BOOTP/DHCP, Request from 00:04:23:57:a5:7a, length 300 +EAPOL start (1) v1, len 0 +EAP packet (0) v1, len 5 +EAP packet (0) v1, len 45 +EAP packet (0) v1, len 20 +IP 169.254.67.194.138 > 169.254.255.255.138: NBT UDP PACKET(138) +EAP packet (0) v1, len 76 +EAP packet (0) v1, len 80 +EAP packet (0) v1, len 28 +EAP packet (0) v1, len 4 +EAPOL key (3) v1, len 57 +EAPOL key (3) v1, len 44 diff --git a/tests/eapon1.puu b/tests/eapon1.puu new file mode 100644 index 0000000..25c1436 --- /dev/null +++ b/tests/eapon1.puu @@ -0,0 +1,368 @@ +begin 644 eapon1.pcap +MU,.RH0(`!````````````/__```!````"%5@0)*@#@#=````W0```/______ +M_P`$(U>E>@@`10``SSB'``"`$7Q.P*@!^<"H`?\`B@"*`+M3[!$.B1W`J`'Y +M`(H`I0``($5%14M&041*1$9&1$1!14M#04-!0T%#04-!0T%#04%!`"!%0D9# +M14-%1D5*1D5&1$5(1D-&1D9!1D%%1D-!0T%!00#_4TU")0`````````````` +M`````````````````````!$```L```````````#H`P``````````"P!6``,` +M`0`!``(`'`!<34%)3%-,3U1<0E)/5U-%``(`1$I0.353,$H`"%5@0/2@#@#= +M````W0```/_______P`$(U>E>@@`10``SSB(``"`$7Q-P*@!^<"H`?\`B@"* +M`+L,\A$.B1[`J`'Y`(H`I0``($5%14M&041*1$9&1$1!14M#04-!0T%#04-! +M0T%#04%!`"!!0D%#1E!&4$5.1D1%0T9#15!&2$9$149&4$9004-!0@#_4TU" +M)0```````````````````````````````````!$```L```````````#H`P`` +M````````"P!6``,``0`!``(`'`!<34%)3%-,3U1<0E)/5U-%``(`1$I0.353 +M,$H`"%5@0("C#@#[````^P```/_______P`$(U>E>@@`10``[3B)``"`$7PN +MP*@!^<"H`?\`B@"*`-E#WA$.B1_`J`'Y`(H`PP``($5%14M&041*1$9&1$1! +M14M#04-!0T%#04-!0T%#04%!`"!!0D%#1E!&4$5.1D1%0T9#15!&2$9$149& +M4$9004-!0@#_4TU")0```````````````````````````````````!$``"D` +M``````````#H`P``````````*0!6``,``0`!``(`.@!<34%)3%-,3U1<0E)/ +M5U-%``P`8.H``$%20D5)5%-'4E504$4``0`#"@`0`(!,_@0#1$I0.353,$H` +M"%5@0/JI#@!<````7````/_______P`$(U>E>@@`10``3CB*``"`$7S,P*@! +M^<"H`?\`B0")`#J"=XDA`1```0```````"!%0D9#14-%1D5*1D5&1$5(1D-& +M1D9!1D%%1D-!0T%"3```(``!"55@0//8"@!<````7````/_______P`$(U>E +M>@@`10``3CB-``"`$7S)P*@!^<"H`?\`B0")`#J"=XDA`1```0```````"!% +M0D9#14-%1D5*1D5&1$5(1D-&1D9!1D%%1D-!0T%"3```(``!"E5@0+,)!P!< +M````7````/_______P`$(U>E>@@`10``3CB.``"`$7S(P*@!^<"H`?\`B0") +M`#J"=XDA`1```0```````"!%0D9#14-%1D5*1D5&1$5(1D-&1D9!1D%%1D-! +M0T%"3```(``!"E5@0,@N#`#S````\P```/_______P`$(U>E>@@`10``Y3B/ +M``"`$7PPP*@!^<"H`?\`B@"*`-'GIA$.B2+`J`'Y`(H`NP``($5%14M&041* +M1$9&1$1!14M#04-!0T%#04-!0T%#04-!`"!%0D9#14-%1D5*1D5&1$5(1D-& +M1D9!1D%%1D-!0T%"3P#_4TU")0`````````````````````````````````` +M`!$``"$```````````#H`P``````````(0!6``,``0````(`,@!<34%)3%-, +M3U1<0E)/5U-%``\`@/P*`$1*4#DU4S!*``!R`&\`10,`7````%P```#_______\`!"-7I7H( +M`$4``$XXE0``@!%\P<"H`?G`J`'_`(D`B0`Z@G")*`$0``$````````@14)& +M0T5#149%2D9%1D1%2$9#1D9&049!149#04-!0DP``"```0Y58$!0N`X`7``` +M`%P```#_______\`!"-7I7H(`$4``$XXE@``@!%\P,"H`?G`J`'_`(D`B0`Z +M@G")*`$0``$````````@14)&0T5#149%2D9%1D1%2$9#1D9&049!149#04-! +M0DP``"```0]58$#*.`<`*@```"H```#_______\`!"-7I7H(!@`!"``&!``! +M``0C5Z5ZP*@!^0```````,"H`0$/56!`%UD'`#P````\``````0C5Z5Z``V( +M3R61"`8``0@`!@0``@`-B$\ED<"H`0$`!"-7I7K`J`'Y```````````````` +M````````#U5@0"E9!P!6`0``5@$````-B$\ED0`$(U>E>@@`10`!2#B7``"` +M$7S#P*@!^<"H`0$`1`!#`31YVP$!!@#(+24]CP&``,"H`?D````````````` +M````!"-7I7H````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````8X)38S4!!S8$P*@!`3T' +M`0`$(U>E>O\````````````````````````````````````````````````` +M``````]58$`6@0D`/````#P`````!"-7I7H`#,Z(,9J(C@$```4!`0`%`0`` +M```````````````````````````````````````````````/56!`"BL*`%8! +M``!6`0``________``0C5Z5Z"`!%``%(.)\``(`1`0<`````_____P!$`$,! +M-,&K`0$&`)@7ASP````````````````````````````$(U>E>@`````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````!C@E-C-0$!=`$!/0E>@@`10`!2#BA``"`$0$%`````/____\`1`!#`32. +MS0$!!@#5`WTN````````````````````````````!"-7I7H````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````8X)38S4!`70!`3T'`0`$(U>E>C($P*@!^0P(1$I0.353 +M,$H\"$U31E0@-2XP-PL!#P,&+"XO'R'Y*_\``````!!58$"$8P(`$P```!,` +M````#,Z(,9H`!"-7I7J(C@$!````$%5@0.IK`@`\````/``````$(U>E>@`, +MSH@QFHB.`0``!0$"``4!```````````````````````````````````````` +M`````````!%58$!>L`L`/P```#\`````#,Z(,9H`!"-7I7J(C@$``"T"`@`M +M`3$R.34P,C,X,C`P,#4S.3%`;6YC,#(S+FUC8S(Y-2YO=VQA;BYO````7@`````, +MSH@QF@`$(U>E>HB.`0``3`(0`$P2"@``#@L`*#$R.34P,C,X,C`P,#4S.3%` +M;6YC,#(S+FUC8S(Y-2YO=VQA;BYOL.*X:RH)3A8\F +M`ET1,5U'QWV%1Z`@V,N=24.:\=%3TKIE>@`,SH@QFHB.`0,`+`$`#0``0&!5$0"=&X[D=]]>4;W^,JD$U5@0*@!#0!6`0``5@$``/_______P`$(U>E +M>@@`10`!2#BG``"`$0#_`````/____\`1`!#`30ES`$!!@#5`WTN:0$````` +M````````````````````!"-7I7H````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````````````8X)3 +M8S4!`70!`3T'`0`$(U>E>C($P*@!^0P(1$I0.353,$H\"$U31E0@-2XP-PL! +M#P,&+"XO'R'Y*_\``````!I58$#O`@T`5@$``%8!``#_______\`!"-7I7H( +M`$4``4@XKP``@!$`]P````#_____`$0`0P$T)E>@`````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````````!C@E-C-0$! +M=`$!/0E>HB.`0$` +M```P56!`^J$*`#P````\``````0C5Z5Z``S.B#&:B(X!```%`0,`!0$````` +M````````````````````````````````````````````,%5@0)SA"@`_```` +M/P`````,SH@QF@`$(U>E>HB.`0``+0(#`"T!,3(Y-3`R,S@R,#`P-3,Y,4!M +M;F,P,C,N;6-C,CDU+F]W;&%N+F]R9S!58$#0!`P`/````#P`````!"-7I7H` +M#,Z(,9J(C@$``!0!+P`4$@H```\"``(``0``$0$!```````````````````` +M```````````R56!`-$(%`%X```!>``````S.B#&:``0C5Z5ZB(X!``!,`B\` +M3!(*```."P`H,3(Y-3`R,S@R,#`P-3,Y,4!M;F,P,C,N;6-C,CDU+F]W;&%N +M+F]R9P<%``#7H!![\\SE,P[&']$W6C<%$`$``3)58$#,.`<`8@```&(````` +M!"-7I7H`#,Z(,9J(C@$``%`!,`!0$@L```$-```P```````````````````` +M,0```````````````````#(````````````````````+!0``0WL?0G!%;49D +M0(DL@MD'#C-58$!S4P(`+@```"X`````#,Z(,9H`!"-7I7J(C@$``!P",``< +M$@L```L%``!%[_\P8H+&6U!$B#@$)T-",U5@0"'6`P`\````/``````$(U>E +M>@`,SH@QFHB.`0``!`,```0````````````````````````````````````` +M`````````````#-58$!=V@,`2P```$L`````!"-7I7H`#,Z(,9J(C@$#`#D! +M``T``$!@53$`G7]!<++?0.3Y>#A83O[YHHT"0T@&N\)FL/6P9NHATX%BIRI%B`S56!`F-T#`#X````^``````0C5Z5Z``S.B#&:B(X!`P`L +M`0`-``!`8%4Q`)[N$`!R;$K*.XLG`JO9N"A#@XK>5*[_:U"C]E[O?""IR!5+ +M56!`]Q(-`"H````J````________``0C5Z5Z"`8``0@`!@0``0`$(U>E>JG^ +M0\(```````"I_D/"2U5@0'&!#0`J````*@```/_______P`$(U>E>@@&``$( +M``8$``$`!"-7I7JI_D/"````````J?Y#PDQ58$`X@@T`*@```"H```#_____ +M__\`!"-7I7H(!@`!"``&!``!``0C5Z5ZJ?Y#P@```````*G^0\)-56!`*=H- +M`*\```"O`````0!>?__Z``0C5Z5Z"`!%``"A.+X```$1HM.I_D/"[___^A#+ +M!VP`C6+X32U314%20T@@*B!(5%10+S$N,0T*2&]S=#HR,SDN,C4U+C(U-2XR +M-3`Z,3DP,`T*4U0Z=7)N.G-C:&5M87,M=7!N<"UO41E=FEC93HQ#0I-86XZ(G-S9'`Z9&ES8V]V97(B#0I-6#HS +M#0H-"DU58$"\Y`T`-@```#8````!`%X``!8`!"-7I7H(`$8``"@XP````0(> +M.:G^0\+@```6E`0``"(`Z@,````!!````.____I-56!`OK4.`&X```!N```` +M________``0C5Z5Z"`!%``!@.,(``(`1:@RI_D/"J?[__P")`(D`3+4(B2XI +M$``!```````!($5%14M&041*1$9&1$1!14M#04-!0T%#04-!0T%#04%!```@ +M``'`#``@``$`!)/@``9@`*G^0\).56!`!H\*`#8````V`````0!>```6``0C +M5Z5Z"`!&```H.,0```$"'C6I_D/"X```%I0$```B`.H#`````00```#O___Z +M3E5@0!3E"@!N````;@```/_______P`$(U>E>@@`10``8#C%``"`$6H)J?Y# +MPJG^__\`B0")`$RU"(DN*1```0```````2!%145+1D%$2D1&1D1$045+0T%# +M04-!0T%#04-!0T%!00``(``!P`P`(``!``23X``&8`"I_D/"3U5@0#,6!P!N +M````;@```/_______P`$(U>E>@@`10``8#C&``"`$6H(J?Y#PJG^__\`B0") +M`$RU"(DN*1```0```````2!%145+1D%$2D1&1D1$045+0T%#04-!0T%#04-! +M0T%!00``(``!P`P`(``!``23X``&8`"I_D/"3U5@0*^U#0!6`0``5@$``/__ +M_____P`$(U>E>@@`10`!2#C'``"`$0#?`````/____\`1`!#`325:P$!!@"2 +M13E.``"`````````````````````````!"-7I7H````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````8X)38S4!`70!`3T'`0`$(U>E>C($P*@!^0P(1$I0.353,$H\"$U3 +M1E0@-2XP-PL!#P,&+"XO'R'Y*_\``````%!58$`T1P,`;@```&X```#_____ +M__\`!"-7I7H(`$4``&`XR```@!%J!JG^0\*I_O__`(D`B0!,M@B)+B@0``$` +M``````$@145%2T9!1$I$1D9$1$%%2T-!0T%#04-!0T%#04-!04$``"```<`, +M`"```0`$D^``!F``J?Y#PE!58$",WPT`KP```*\````!`%Y___H`!"-7I7H( +M`$4``*$XR@```1&BQZG^0\+O___Z$,L';`"-8OA-+5-%05)#2"`J($A45%`O +M,2XQ#0I(;W-T.C(S.2XR-34N,C4U+C(U,#HQ.3`P#0I35#IUE>@@`10``8#C,``"`$6H"J?Y#PJG^__\`B0")`$PP]8DO*1`` +M`0```````2!%0D9#14-%1D5*1D5&1$5(1D-&1D9!1D%%1D-!0T%!00``(``! +MP`P`(``!``23X``&X`"I_D/"455@0#/A`P`3````$P`````,SH@QF@`$(U>E +M>HB.`0$```!156!`8>D#`#P````\``````0C5Z5Z``S.B#&:B(X!```%`00` +M!0$`````````````````````````````````````````````````455@0+TU +M!``_````/P`````,SH@QF@`$(U>E>HB.`0``+0($`"T!,3(Y-3`R,S@R,#`P +M-3,Y,4!M;F,P,C,N;6-C,CDU+F]W;&%N+F]R9U%58$#Y[@4`/````#P````` +M!"-7I7H`#,Z(,9J(C@$``!0!4``4$@H```\"``(``0``$0$!```````````` +M``````````````````!156!`9.L*`&X```!N````________``0C5Z5Z"`!% +M``!@.,T``(`1:@&I_D/"J?[__P")`(D`3##UB2\I$``!```````!($5"1D-% +M0T5&14I&149$14A&0T9&1D%&045&0T%#04%!```@``'`#``@``$`!)/@``;@ +M`*G^0\)256!`71P'`&X```!N````________``0C5Z5Z"`!%``!@.,X``(`1 +M:@"I_D/"J?[__P")`(D`3##UB2\I$``!```````!($5"1D-%0T5&14I&149$ +M14A&0T9&1D%&045&0T%#04%!```@``'`#``@``$`!)/@``;@`*G^0\)256!` +M9[(.`%X```!>``````S.B#&:``0C5Z5ZB(X!``!,`E``3!(*```."P`H,3(Y +M-3`R,S@R,#`P-3,Y,4!M;F,P,C,N;6-C,CDU+F]W;&%N+F]R9P<%```Z)]TL +M?V'JYOR&8?J))U]%$`$``5)58$`"$P\`8@```&(`````!"-7I7H`#,Z(,9J( +MC@$``%`!40!0$@L```$-```P````````````````````,0`````````````` +M`````#(````````````````````+!0``*IFHOZ$\8[TX!>!F]%P6:%-58$!8 +M30,`;@```&X```#_______\`!"-7I7H(`$4``&`XSP``@!%I_ZG^0\*I_O__ +M`(D`B0!,,?6)+R@0``$```````$@14)&0T5#149%2D9%1D1%2$9#1D9&049! +M149#04-!04$``"```<`,`"```0`$D^``!N``J?Y#PE-58$#M3`H`+@```"X` +M````#,Z(,9H`!"-7I7J(C@$``!P"40`<$@L```L%``#BE(K>$<9]M,I(_@G, +MC).Y4U5@0`*="@`\````/``````$(U>E>@`,SH@QFHB.`0``!`,```0````` +M`````````````````````````````````````````````%-58$#CH`H`2P`` +M`$L`````!"-7I7H`#,Z(,9J(C@$#`#D!``T``$!@55(`GZN0MGOEA8[@4WO* +M&_11@$@"&2ZIH`.YHY==8)$_%6#R:U/Z"F'14BLDK,Z)I:%356!`&*0*`#X` +M```^``````0C5Z5Z``S.B#&:B(X!`P`L`0`-``!`8%52`*!&UK1?KE>@`````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``!C@E-C-0$!=`$!/0E>@@`10``H3C2```!$:*_J?Y#PN____H0RP=L`(UB^$TM4T5!4D-(("H@ +M2%144"\Q+C$-"DAOE>@@`10``SSCF``"` +M$6EYJ?Y#PJG^__\`B@"*`+L)/1$.B3:I_D/"`(H`I0``($5%14M&041*1$9& +M1$1!14M#04-!0T%#04-!0T%#04%!`"!%0D9#14-%1D5*1D5&1$5(1D-&1D9! +M1D%%1D-!0T%"3@#_4TU")0```````````````````````````````````!$` +M``L```````````#H`P``````````"P!6``,``0`!``(`'`!<34%)3%-,3U1< +M0E)/5U-%``(`1$I0.353,$H`655@0.K0#@#=````W0```/_______P`$(U>E +M>@@`10``SSCG``"`$6EXJ?Y#PJG^__\`B@"*`+L)/!$.B3>I_D/"`(H`I0`` +M($5%14M&041*1$9&1$1!14M#04-!0T%#04-!0T%#04%!`"!%0D9#14-%1D5* +M1D5&1$5(1D-&1D9!1D%%1D-!0T%"3@#_4TU")0`````````````````````` +M`````````````!$```L```````````#H`P``````````"P!6``,``0`!``(` +M'`!<34%)3%-,3U1<0E)/5U-%``(`1$I0.353,$H`6U5@0-@R!P#=````W0`` +M`/_______P`$(U>E>@@`10``SSCH``"`$6EWJ?Y#PJG^__\`B@"*`+L).Q$. +MB3BI_D/"`(H`I0``($5%14M&041*1$9&1$1!14M#04-!0T%#04-!0T%#04%! +M`"!%0D9#14-%1D5*1D5&1$5(1D-&1D9!1D%%1D-!0T%"3@#_4TU")0`````` +M`````````````````````````````!$```L```````````#H`P`````````` +M"P!6``,``0`!``(`'`!<34%)3%-,3U1<0E)/5U-%``(`1$I0.353,$H`7%5@ +M0"2]#0!6`0``5@$``/_______P`$(U>E>@@`10`!2#CI``"`$0"]`````/__ +M__\`1`!#`31L:@$!!@"213E.*0&`````````````````````````!"-7I7H` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````````````````8X)38S4!`70!`3T'`0`$(U>E>C($P*@! +M^0P(1$I0.353,$H\"$U31E0@-2XP-PL!#P,&+"XO'R'Y*_\``````%Q58$`# +MUPX`Z0```.D```#_______\`!"-7I7H(`$4``-LXZ@``@!%I::G^0\*I_O__ +M`(H`B@#';@L1#HDYJ?Y#P@"*`+$``"!%145+1D%$2D1&1D1$045+0T%#04-! +M0T%#04-!0T%!00`@14)&0T5#149%2D9%1D1%2$9#1D9&049!149#04-!0D\` +M_U--0B4````````````````````````````````````1```7```````````` +MZ`,``````````!<`5@`#``$``0`"`"@`7$U!24Q33$]47$)23U=310`(`2`/ +M`1!9L1D5`````$1*4#DU4S!*`%U58$#/UPX`Z0```.D```#_______\`!"-7 +MI7H(`$4``-LXZP``@!%I:*G^0\*I_O__`(H`B@#';@H1#HDZJ?Y#P@"*`+$` +M`"!%145+1D%$2D1&1D1$045+0T%#04-!0T%#04-!0T%!00`@14)&0T5#149% +M2D9%1D1%2$9#1D9&049!149#04-!0D\`_U--0B4````````````````````` +M```````````````1```7````````````Z`,``````````!<`5@`#``$``0`" +M`"@`7$U!24Q33$]47$)23U=310`(`2`/`1!9L1D5`````$1*4#DU4S!*`%Y5 +M8$"+V`X`Z0```.D```#_______\`!"-7I7H(`$4``-LX[```@!%I9ZG^0\*I +M_O__`(H`B@#';@D1#HD[J?Y#P@"*`+$``"!%145+1D%$2D1&1D1$045+0T%# +M04-!0T%#04-!0T%!00`@14)&0T5#149%2D9%1D1%2$9#1D9&049!149#04-! +M0D\`_U--0B4````````````````````````````````````1```7```````` +M````Z`,``````````!<`5@`#``$``0`"`"@`7$U!24Q33$]47$)23U=310`( +M`2`/`1!9L1D5`````$1*4#DU4S!*`%]58$!)V0X`Z0```.D```#_______\` +M!"-7I7H(`$4``-LX[0``@!%I9JG^0\*I_O__`(H`B@#';@@1#HD\J?Y#P@"* +M`+$``"!%145+1D%$2D1&1D1$045+0T%#04-!0T%#04-!0T%!00`@14)&0T5# +M149%2D9%1D1%2$9#1D9&049!149#04-!0D\`_U--0B4````````````````` +M```````````````````1```7````````````Z`,``````````!<`5@`#``$` +M`0`"`"@`7$U!24Q33$]47$)23U=310`(`2`/`1!9L1D5`````$1*4#DU4S!* +M`&!58$"CV@X`;@```&X```#_______\`!"-7I7H(`$4``&`X[@``@!%IX*G^ +M0\*I_O__`(D`B0!,H^:)/2D0``$```````$@14)&0T5#149%2D9%1D1%2$9# +M1D9&049!149#04-!0DX``"```<`,`"```0`$D^``!F``J?Y#PF%58$#F"@L` +M;@```&X```#_______\`!"-7I7H(`$4``&`X[P``@!%IWZG^0\*I_O__`(D` +MB0!,H^:)/2D0``$```````$@14)&0T5#149%2D9%1D1%2$9#1D9&049!149# +M04-!0DX``"```<`,`"```0`$D^``!F``J?Y#PF)58$#?.P<`;@```&X```#_ +M______\`!"-7I7H(`$4``&`X\```@!%IWJG^0\*I_O__`(D`B0!,H^:)/2D0 +M``$```````$@14)&0T5#149%2D9%1D1%2$9#1D9&049!149#04-!0DX``"`` +M`<`,`"```0`$D^``!F``J?Y#PF-58$#9;`,`;@```&X```#_______\`!"-7 +MI7H(`$4``&`X\P``@!%IVZG^0\*I_O__`(D`B0!,I.:)/2@0``$```````$@ +M14)&0T5#149%2D9%1D1%2$9#1D9&049!149#04-!0DX``"```<`,`"```0`$ +MD^``!F``J?Y#PF-58$"'X`X`;@```&X```#_______\`!"-7I7H(`$4``&`X +M]```@!%IVJG^0\*I_O__`(D`B0!,Z>R)/BD0``$```````$@04)!0T901E!% +M3D9$14-&0T501DA&1$5&1E!&4$%#04(``"```<`,`"```0`$D^``!N``J?Y# +MPF158$`/$0L`;@```&X```#_______\`!"-7I7H(`$4``&`X]0``@!%IV:G^ +M0\*I_O__`(D`B0!,Z>R)/BD0``$```````$@04)!0T901E!%3D9$14-&0T50 +M1DA&1$5&1E!&4$%#04(``"```<`,`"```0`$D^``!N``J?Y#PF558$`&0@<` +M;@```&X```#_______\`!"-7I7H(`$4``&`X]@``@!%IV*G^0\*I_O__`(D` +MB0!,Z>R)/BD0``$```````$@04)!0T901E!%3D9$14-&0T501DA&1$5&1E!& +M4$%#04(``"```<`,`"```0`$D^``!N``J?Y#PF958$#^<@,`;@```&X```#_ +M______\`!"-7I7H(`$4``&`X]P``@!%IUZG^0\*I_O__`(D`B0!,ZNR)/B@0 +M``$```````$@04)!0T901E!%3D9$14-&0T501DA&1$5&1E!&4$%#04(``"`` +M`<`,`"```0`$D^``!N``J?Y#PF958$!_Y@X`W0```-T```#_______\`!"-7 +MI7H(`$4``,\X^```@!%I9ZG^0\*I_O__`(H`B@"[%C41#HD_J?Y#P@"*`*4` +M`"!%145+1D%$2D1&1D1$045+0T%#04-!0T%#04-!0T%!00`@14)&0T5#149% +M2D9%1D1%2$9#1D9&049!149#04-!04$`_U--0B4````````````````````` +M```````````````1```+````````````Z`,```````````L`5@`#``$``0`" +M`!P`7$U!24Q33$]47$)23U=310`"`$1*4#DU4S!*`&958$!AYPX`W0```-T` +M``#_______\`!"-7I7H(`$4``,\X^0``@!%I9JG^0\*I_O__`(H`B@"[SSH1 +M#HE`J?Y#P@"*`*4``"!%145+1D%$2D1&1D1$045+0T%#04-!0T%#04-!0T%! +M00`@04)!0T901E!%3D9$14-&0T501DA&1$5&1E!&4$%#04(`_U--0B4````` +M```````````````````````````````1```+````````````Z`,````````` +M``L`5@`#``$``0`"`!P`7$U!24Q33$]47$)23U=310`"`$1*4#DU4S!*`&95 +M8$!PZ@X`^P```/L```#_______\`!"-7I7H(`$4``.TX^@``@!%I1ZG^0\*I +M_O__`(H`B@#9)2,1#HE!J?Y#P@"*`,,``"!%145+1D%$2D1&1D1$045+0T%# +M04-!0T%#04-!0T%!00`@04)!0T901E!%3D9$14-&0T501DA&1$5&1E!&4$%# +M04(`_U--0B4````````````````````````````````````1```I```````` +M````Z`,``````````"D`5@`#``$``0`"`#H`7$U!24Q33$]47$)23U=310`, +M`&#J``!!4D)%25131U)54%!%``$``PH`$`"`;/[%!D1*4#DU4S!*`&958$"4 +M\`X`7````%P```#_______\`!"-7I7H(`$4``$XX^P``@!%IY:G^0\*I_O__ +M`(D`B0`Z;]^)0P$0``$````````@14)&0T5#149%2D9%1D1%2$9#1D9&049! +M149#04-!0DP``"```6=58$`('PL`7````%P```#_______\`!"-7I7H(`$4` +M`$XX_```@!%IY*G^0\*I_O__`(D`B0`Z;]^)0P$0``$````````@14)&0T5# +M149%2D9%1D1%2$9#1D9&049!149#04-!0DP``"```6A58$`&4`<`7````%P` +M``#_______\`!"-7I7H(`$4``$XX_0``@!%IXZG^0\*I_O__`(D`B0`Z;]^) +M0P$0``$````````@14)&0T5#149%2D9%1D1%2$9#1D9&049!149#04-!0DP` +M`"```6M58$"J6P<`7````%P```#_______\`!"-7I7H(`$4``$XY`0``@!%I +MWZG^0\*I_O__`(D`B0`Z;]N)1P$0``$````````@14)&0T5#149%2D9%1D1% +M2$9#1D9&049!149#04-!0DP``"```6Q58$`-BP,`7````%P```#_______\` +M!"-7I7H(`$4``$XY`@``@!%IWJG^0\*I_O__`(D`B0`Z;]N)1P$0``$````` +M```@14)&0T5#149%2D9%1D1%2$9#1D9&049!149#04-!0DP``"```6Q58$!% +M_@X`7````%P```#_______\`!"-7I7H(`$4``$XY!```@!%IW*G^0\*I_O__ +M`(D`B0`Z;]N)1P$0``$````````@14)&0T5#149%2D9%1D1%2$9#1D9&049! +M149#04-!0DP``"```6U58$`7O@T`5@$``%8!``#_______\`!"-7I7H(`$4` +M`4@Y!@``@!$`H`````#_____`$0`0P$T;&H!`08`DD4Y3BD!@``````````` +M``````````````0C5Z5Z```````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````````&."4V,U`0%T +M`0$]!P$`!"-7I7HR!,"H`?D,"$1*4#DU4S!*/`A-4T94(#4N,#<+`0\#!BPN +M+Q\A^2O_``````!Q56!`]:$*`!,````3``````S.B#&:``0C5Z5ZB(X!`0`` +M`'%58$!%P`H`/````#P`````!"-7I7H`#,Z(,9J(C@$```4!!0`%`0`````` +M``````````````````````````````````````````!Q56!`C?4*`#\````_ +M``````S.B#&:``0C5Z5ZB(X!```M`@4`+0$Q,CDU,#(S.#(P,#`U,SDQ0&UN +M8S`R,RYM8V,R.34N;W=L86XN;W)G<55@0/XV"P`\````/``````$(U>E>@`, +MSH@QFHB.`0``%`%P`!02"@``#P(``@`!```1`0$````````````````````` +M`````````')58$#=.0P`\P```/,```#_______\`!"-7I7H(`$4``.4Y#``` +M@!%I/:G^0\*I_O__`(H`B@#1\^D1#HE*J?Y#P@"*`+L``"!%145+1D%$2D1& +M1D1$045+0T%#04-!0T%#04-!0T%#00`@14)&0T5#149%2D9%1D1%2$9#1D9& +M049!149#04-!0D\`_U--0B4````````````````````````````````````1 +M```A````````````Z`,``````````"$`5@`#``$````"`#(`7$U!24Q33$]4 +M7$)23U=310`/`(#\"@!$2E`Y-5,P2@``60!<`%4`!0$#$`4`#P%5J@!S56!` +MJ'L$`%X```!>``````S.B#&:``0C5Z5ZB(X!``!,`G``3!(*```."P`H,3(Y +M-3`R,S@R,#`P-3,Y,4!M;F,P,C,N;6-C,CDU+F]W;&%N+F]R9P<%```)[DNV +M]E>@`,SH@QFHB.`0`` +M!`,```0``````````````````````````````````````````````````'15 +M8$`G6P``2P```$L`````!"-7I7H`#,Z(,9J(C@$#`#D!``T``$!@57(`H7=G +MF]`L&:EKBMN@`6*6Y2?^.:F>V`$/C@ +M9C@```$!"`H974FMBM15+Q!58$!QG`8`8````.L`````"]N0_0(`X$]@<4 +M5(X`:)P-"Q0`8$$!L&:EKA4C@<4`/I,<`$5`/+M5G/\`0<0G:=Q]S4< +MM*"$``/81;I[5@?]ZP9J6N%2.!Q0`RHLB`18`PB*WG4W^01LM]B4XN&`' +M6E(!*C$R.34P,C,X,C`P,#4S.3%`;6YC,#(S+FUC8S(Y-2YO$55@0!P&!0!@ +M````!@$`````#`>LA0`+VY#]`@@`10``^``"0`!`$0RDP9J6N-6!_WH'%%2. +M`.2>DP(6`-P04TN>&O"\WL%@,.`1V142"`;____^#`8```)`!@8````"&CH` +M``$W$32`+U<1;LS62B]58$!:H@8`8````.L`````"]N0_0(`X$]@M>A=G +MB0$J,3(Y-3`R,S@R,#`P-3,Y,4!M;F,P,C,N;6-C,CDU+F\O56!`G*<&`&`` +M``"*```````,!ZR%``O;D/T""`!%``!\``-``$`1#1_!FI:XU8'_>@<45(X` +M:#L&:EKA4C@<4`/H2$P$9`/)6HP7H8R0(O +M*"8``/81;IG5@?]ZP9J6N%2.!Q0`R@WC`1H`PCS/?&QHIT8SX.[2#=[S68H! +M*C$R.34P,C,X,C`P,#4S.3%`;6YC,#(S+FUC8S(Y-2YO,55@0#VS#0!@```` +M!@$`````#`>LA0`+VY#]`@@`10``^``%0`!`$0RAP9J6N-6!_WH'%%2.`.3B +MMP(:`-S*Z(?9H34)&AB0":D9@<45(X`:#0% +M"QL`8(N:^N5L(EK&#H6-':U$XV((!O____X,!@```D`&!@````)/%@%0`!02 +M"@``#P(``@`!455@0*VL"0!@````'`$````+VY#]`@#@3UR$8`@`10`!#B@I +M``#V$6YFU8'_>L&:EKA4C@<4`/KDFP$<`/+H$R8P9(B"W[^G<4!"HKQ+`2HQ +M,CDU,#(S.#(P,#`U,SDQ0&UN8S`R,RYM8V,R.34N;U%58$"ZL@D`8````,8` +M``````P'K(4`"]N0_0((`$4``+@`!T``0!$,W\&:EKC5@?]Z!Q14C@"DI=@+ +M'`";*!>&FY;C?2/)T74`@&_____@P&```"0`8&`````D]2`5$`4!(+ +M```!#0``,`!256!`@SL%`&````#L``````O;D/T"`.!/7(1@"`!%``#>*"H` +M`/81;I75@?]ZP9J6N%2.!Q0`RI"T`1T`PE:^P6JH@]U$D*!C#8CO0UP!*C$R +M.34P,C,X,C`P,#4S.3%`;6YC,#(S+FUC8S(Y-2YO4E5@0'M`!0!@````!@$` +M````#`>LA0`+VY#]`@@`10``^``(0`!`$0R>P9J6N-6!_WH'%%2.`.2<&@(= +M`-P&]WGHNB++Z0K&A"^B<2S/"`;____^#`8```)`!@8````"&CH```$W$32F +M=DT@&\D[/G!58$!OW04`8````.L`````"]N0_0(`X$]AS"W^P0$J,3(Y +M-3`R,S@R,#`P-3,Y,4!M;F,P,C,N;6-C,CDU+F]P56!`L>(%`&````"*```` +M```,!ZR%``O;D/T""`!%``!\``E``$`1#1G!FI:XU8'_>@<45(X`:`.V"QX` +M8+P/!*Y!RZ>(/:C.%/A62\((!O____X,!@```D`&!@````)/%@%P`!02"@`` +M#P(``@`!<55@0)*H#@!@````'`$````+VY#]`@#@3UR$8`@`10`!#B@L``#V +M$6YCU8'_>L&:EKA4C@<4`/JLH@$?`/*.M".D<>M4,KL=.(:"[-F;`2HQ,CDU +M,#(S.#(P,#`U,SDQ0&UN8S`R,RYM8V,R.34N;W%58$#$K@X`8````,8````` +M``P'K(4`"]N0_0((`$4``+@`"D``0!$,W,&:EKC5@?]Z!Q14C@"DK7D+'P"< +MMWVPJO:XC`JEY#15<5U0Z@@&_____@P&```"0`8&`````D]2`7$`4!(+```! +M#0``,`!R56!`S#4*`&````#L``````O;D/T"`.!/7(1@"`!%``#>*"T``/81 +M;I+5@?]ZP9J6N%2.!Q0`RE>1`2``PK+"]?UCV]G1I<-+X16?0+L!*C$R.34P +M,C,X,C`P,#4S.3%`;6YC,#(S+FUC8S(Y-2YOLA0`+VY#]`@@`10``^``+0`!`$0R;P9J6N-6!_WH'%%2.`.1M%P(@`-PJ +M=?H'6<1=UD&:FRVA,V+S"`;____^#`8```)`!@8````"&CH```$W$32RVRE= +$I%P\00`` +` +end diff --git a/tests/esp-secrets.txt b/tests/esp-secrets.txt new file mode 100644 index 0000000..81847a0 --- /dev/null +++ b/tests/esp-secrets.txt @@ -0,0 +1,5 @@ +# a comment + +0x12345678@192.1.2.45 3des-cbc-hmac96:0x43434545464649494a4a4c4c4f4f51515252545457575840 +0xabcdabcd@192.0.1.1 3des-cbc-hmac96:0x434545464649494a4a4c4c4f4f5151525254545757584043 +0xd1234567@192.1.2.45 aes256-cbc-hmac96:0xaaaabbbbccccdddd4043434545464649494a4a4c4c4f4f515152525454575758 diff --git a/tests/esp0.out b/tests/esp0.out new file mode 100644 index 0000000..a0ddf1b --- /dev/null +++ b/tests/esp0.out @@ -0,0 +1,8 @@ +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x1), length 116 +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x2), length 116 +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x3), length 116 +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x4), length 116 +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x5), length 116 +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x6), length 116 +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x7), length 116 +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x8), length 116 diff --git a/tests/esp1.gdbinit b/tests/esp1.gdbinit new file mode 100644 index 0000000..6c8ae89 --- /dev/null +++ b/tests/esp1.gdbinit @@ -0,0 +1 @@ +set args -t -n -E "0x12345678@192.1.2.45 3des-cbc-hmac96:0x4043434545464649494a4a4c4c4f4f515152525454575758" -r 02-sunrise-sunset-esp.pcap diff --git a/tests/esp1.out b/tests/esp1.out new file mode 100644 index 0000000..61b2967 --- /dev/null +++ b/tests/esp1.out @@ -0,0 +1,8 @@ +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x1), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 1280, length 64 (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x2), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 1536, length 64 (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x3), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 1792, length 64 (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x4), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 2048, length 64 (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x5), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 2304, length 64 (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x6), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 2560, length 64 (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x7), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 2816, length 64 (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x8), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 3072, length 64 (ipip-proto-4) diff --git a/tests/esp2.gdbinit b/tests/esp2.gdbinit new file mode 100644 index 0000000..7c18407 --- /dev/null +++ b/tests/esp2.gdbinit @@ -0,0 +1 @@ +set args -t -n -E "0x12345678@192.1.2.45 3des-cbc-hmac96:0x43434545464649494a4a4c4c4f4f51515252545457575840,0xabcdabcd@192.0.1.1 3des-cbc-hmac96:0x434545464649494a4a4c4c4f4f5151525254545757584043" -r 08-sunrise-sunset-esp2.pcap diff --git a/tests/esp2.out b/tests/esp2.out new file mode 100644 index 0000000..a829c8e --- /dev/null +++ b/tests/esp2.out @@ -0,0 +1,8 @@ +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x1), length 172: IP 192.1.2.23 > 192.0.1.1: ESP(spi=0xabcdabcd,seq=0x1), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 1280, length 64 (ipip-proto-4) (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x2), length 172: IP 192.1.2.23 > 192.0.1.1: ESP(spi=0xabcdabcd,seq=0x2), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 1536, length 64 (ipip-proto-4) (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x3), length 172: IP 192.1.2.23 > 192.0.1.1: ESP(spi=0xabcdabcd,seq=0x3), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 1792, length 64 (ipip-proto-4) (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x4), length 172: IP 192.1.2.23 > 192.0.1.1: ESP(spi=0xabcdabcd,seq=0x4), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 2048, length 64 (ipip-proto-4) (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x5), length 172: IP 192.1.2.23 > 192.0.1.1: ESP(spi=0xabcdabcd,seq=0x5), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 2304, length 64 (ipip-proto-4) (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x6), length 172: IP 192.1.2.23 > 192.0.1.1: ESP(spi=0xabcdabcd,seq=0x6), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 2560, length 64 (ipip-proto-4) (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x7), length 172: IP 192.1.2.23 > 192.0.1.1: ESP(spi=0xabcdabcd,seq=0x7), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 2816, length 64 (ipip-proto-4) (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0x12345678,seq=0x8), length 172: IP 192.1.2.23 > 192.0.1.1: ESP(spi=0xabcdabcd,seq=0x8), length 116: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 3072, length 64 (ipip-proto-4) (ipip-proto-4) diff --git a/tests/esp3.gdbinit b/tests/esp3.gdbinit new file mode 100644 index 0000000..7150118 --- /dev/null +++ b/tests/esp3.gdbinit @@ -0,0 +1 @@ +set args -t -n -E "3des-cbc-hmac96:0x43434545464649494a4a4c4c4f4f51515252545457575840" -r 08-sunrise-sunset-esp2.pcap diff --git a/tests/esp4.gdbinit b/tests/esp4.gdbinit new file mode 100644 index 0000000..8007444 --- /dev/null +++ b/tests/esp4.gdbinit @@ -0,0 +1,2 @@ +set args -t -n -E "file esp-secrets.txt" -r 08-sunrise-sunset-esp2.pcap + diff --git a/tests/esp5.gdbinit b/tests/esp5.gdbinit new file mode 100644 index 0000000..2f578e3 --- /dev/null +++ b/tests/esp5.gdbinit @@ -0,0 +1,3 @@ +set args -t -n -E "file esp-secrets.txt" -r 08-sunrise-sunset-aes.pcap + + diff --git a/tests/esp5.out b/tests/esp5.out new file mode 100644 index 0000000..73f35e0 --- /dev/null +++ b/tests/esp5.out @@ -0,0 +1,8 @@ +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0xd1234567,seq=0x1), length 132: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 1280, length 64 (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0xd1234567,seq=0x2), length 132: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 1536, length 64 (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0xd1234567,seq=0x3), length 132: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 1792, length 64 (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0xd1234567,seq=0x4), length 132: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 2048, length 64 (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0xd1234567,seq=0x5), length 132: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 2304, length 64 (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0xd1234567,seq=0x6), length 132: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 2560, length 64 (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0xd1234567,seq=0x7), length 132: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 2816, length 64 (ipip-proto-4) +IP 192.1.2.23 > 192.1.2.45: ESP(spi=0xd1234567,seq=0x8), length 132: IP 192.0.2.1 > 192.0.1.1: ICMP echo request, id 28416, seq 3072, length 64 (ipip-proto-4) diff --git a/tests/espudp1.out b/tests/espudp1.out new file mode 100644 index 0000000..db8eafb --- /dev/null +++ b/tests/espudp1.out @@ -0,0 +1,8 @@ +IP 192.1.2.23.4500 > 192.1.2.45.4500: UDP-encap: ESP(spi=0x12345678,seq=0x1), length 116 +IP 192.1.2.23.4500 > 192.1.2.45.4500: UDP-encap: ESP(spi=0x12345678,seq=0x2), length 116: ip-proto-227 49 +IP 192.1.2.23.4500 > 192.1.2.45.4500: UDP-encap: ESP(spi=0x12345678,seq=0x3), length 116: PIMv13, length 10 +IP 192.1.2.23.4500 > 192.1.2.45.4500: UDP-encap: ESP(spi=0x12345678,seq=0x4), length 116 +IP 192.1.2.23.4500 > 192.1.2.45.4500: UDP-encap: ESP(spi=0x12345678,seq=0x5), length 116 +IP 192.1.2.23.4500 > 192.1.2.45.4500: UDP-encap: ESP(spi=0x12345678,seq=0x6), length 116: ip-proto-183 28 +IP 192.1.2.23.4500 > 192.1.2.45.4500: UDP-encap: ESP(spi=0x12345678,seq=0x7), length 116: ip-proto-72 34 +IP 192.1.2.23.4500 > 192.1.2.45.4500: UDP-encap: ESP(spi=0x12345678,seq=0x8), length 116: ip-proto-224 59 diff --git a/tests/espudp1.puu b/tests/espudp1.puu new file mode 100644 index 0000000..353c1c9 --- /dev/null +++ b/tests/espudp1.puu @@ -0,0 +1,35 @@ +begin 644 espudp1.pcap +MU,.RH0(`!``````````````&```!``````````````">````G@```!```&1D +M11```&1D(P@`10``D*8.``!`$5`(P`$"%\`!`BT1E!&4`'P``!(T5G@````! +MIQI1WARY*2.,3*N>\E4-MV0"Q0&B9RG\CH]Z?F.J2U2J6?9"%WHI),PCC4.T +MPHU1D2,KT6".3TG`1R:V$E7'FE[]PG%1#\!'O=1;9"P[#Q*U;DU12<9BO$:/ +M(AI2S*,BK5H_YVKC,]K'@[Y^``````````">````G@```!```&1D11```&1D +M(P@`10``D*8/``!`$5`'P`$"%\`!`BT1E!&4`'P``!(T5G@````"*3$H)*^K +MG65!9?U^[O>)/*D1"&WNUN@=BGJZV$;E12<$J$SGOAFJ!<5)O%=NY:HY\B$3 +M!*Q.N--U/:_F^;L-H0>[$9AU0\QP"`F5JD8GY307\SDD5=Y\G@%('76R5O`G +MA/2`=,$VWF]0[L\*``````````">````G@```!```&1D11```&1D(P@`10`` +MD*80``!`$5`&P`$"%\`!`BT1E!&4`'P``!(T5G@````#C]!\R;K$H/YX7>T6 +MZT6>/2I[+Q4&*]7A`VLB)[%A_/MKQMX-:R"-)DA.[G>)\5]KF#Z5:3L+JCMC +MXDHKBE%/Q%D1VV#=?\3JEZ?8)&[3[(4F"4*0W"B)."[.?0U(7!!Z2_69:0DV +M98H$8R%=``````````">````G@```!```&1D11```&1D(P@`10``D*81``!` +M$5`%P`$"%\`!`BT1E!&4`'P``!(T5G@````$FV8=\*GR(@_[&TF2&3'AZ9)Q +M*?@[(M!I:IE"@-?4W5TEZ-5@(F\613%V19L#%[XCJFJY^G4BVW"O\/*X\!A6 +M@1<[4J(5+60M8]9R>$=\TU>XX7AB7\T'1W1HAPX[(KPTVN"*NEC)E/7@5D_1 +M``````````">````G@```!```&1D11```&1D(P@`10``D*82``!`$5`$P`$" +M%\`!`BT1E!&4`'P``!(T5G@````%=@CRA49O0D;A1@T5[WR$Q5?Y(\M[>D@C +MRFK+$5I%Y8:85K`)&LZ.Q@G&N)8-RG@2;GNYJ\2OC9ZV?,IT7HJU7K&DM/1_ +M:K+-8KXY4?22*8=.1@O<,#R&;^R2P`>PAR9E7*>!>3*D24OK4*C1```````` +M``">````G@```!```&1D11```&1D(P@`10``D*83``!`$5`#P`$"%\`!`BT1 +ME!&4`'P``!(T5G@````&OTF+$=SM[Y.=U8E>9V&69R:M\.1&LA]$#9Q^:+E7 +MQE#E^)1R]--?O]SW!%7]KB<7\MLR56^WX)#?)/IJR<_@C91NG`(S^S``````````">```` +MG@```!```&1D11```&1D(P@`10``D*84``!`$5`"P`$"%\`!`BT1E!&4`'P` +M`!(T5G@````'!12933DTC1RSTN*./4ZCE%A8GGVL:;@`.%'8MEA.C7/6]D[S +MO1C([D/N6]%[?NISR>1W1EE,)=\I9&.PF-'Q*LXZQU71100.[\,-HK41G3/R +MG9DY$,].(M58U1\0XT\4R[<=RCCXM;_%AVM)``````````">````G@```!`` +M`&1D11```&1D(P@`10``D*85``!`$5`!P`$"%\`!`BT1E!&4`'P``!(T5G@` +M```(*_3L6&DE`65QQPA"@BAQ5FY@=%,+]@C9K+O)@],/GCI4%,MKI282(0M9 +M*<@/=L.DB"**EM":*2KJK`^H=0YM,$^[`=L%(RO,O_<4`MNKJ*:^9W8@1BP$ +59LK`-:)VQ/=2B;1'4FV3B?L]2;O! +` +end diff --git a/tests/forces1.out b/tests/forces1.out new file mode 100644 index 0000000..7e013d7 --- /dev/null +++ b/tests/forces1.out @@ -0,0 +1,8 @@ +IP 192.168.1.7.6700 > 192.168.1.7.34917: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3442086958] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query + +IP 192.168.1.7.34917 > 192.168.1.7.6700: sctp[ForCES HP] (1) [SACK] [cum ack 3442086958] [a_rwnd 56288] [#gap acks 0] [#dup tsns 0] +IP 192.168.1.7.34917 > 192.168.1.7.6700: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 2574629157] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query Response + +IP 192.168.1.7.6700 > 192.168.1.7.34917: sctp[ForCES HP] (1) [SACK] [cum ack 2574629157] [a_rwnd 56296] [#gap acks 0] [#dup tsns 0] diff --git a/tests/forces1.pcap b/tests/forces1.pcap new file mode 100644 index 0000000000000000000000000000000000000000..49c8f6453b685a5809de99f2a543fcc3512a2bc8 GIT binary patch literal 476 zcmca|c+)~A1{MYw*uu)dzzF0ldm8Aq@-rtx9gq#e$bf^vm5HH%fx&^np=I0311lKW zL0C$sBX#x08xdfY%nSi%wM6uQY>;6L0xS#y4iGjwhz|rzKY)Y)1A_*T0;yqSU}unF z6kw2m@|l2a9vBP5Jm=I*BCIcgI)6o=9-RFDV=RKr9mK-%s`7EuDSgH z#9t0HE%gL5Ll=+@!pHz@S`7mS*tDtGOamGhGqZH3Do_{1Zz2rBKsL~R2p`C1vH%i5 zznK6jh~GFFG=Tn5f$~9qL-`x|;9LQxWFR|hCCnVHg!d!+N>L7nYTz2~f&@=`B Dp?65B literal 0 HcmV?d00001 diff --git a/tests/forces1vvv.out b/tests/forces1vvv.out new file mode 100644 index 0000000..886e429 --- /dev/null +++ b/tests/forces1vvv.out @@ -0,0 +1,52 @@ +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 112) + 192.168.1.7.6700 > 192.168.1.7.34917: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 3442086958] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query + ForCES Version 1 len 64B flags 0xf8000000 + SrcID 0x40000001(CE) DstID 0x7(FE) Correlator 0x2 + ForCES flags: + AlwaysACK(0x3), prio=7, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + LFBselect TLV, length 40 (data length 36 Bytes) + FEObj LFB(Classid 1) instance 1 + Oper TLV Get(0x7) length 28 + PATH-DATA TLV, length 24 (data encapsulated 20 Bytes) + Pathdata: Flags 0x0 ID count 1 + ID#01: 2 + PATH-DATA TLV, length 12 (data encapsulated 8 Bytes) + Pathdata: Flags 0x0 ID count 1 + ID#01: 2 + + +IP (tos 0x2,ECT(0), ttl 64, id 7, offset 0, flags [DF], proto SCTP (132), length 48) + 192.168.1.7.34917 > 192.168.1.7.6700: sctp[ForCES HP] + 1) [SACK] [cum ack 3442086958] [a_rwnd 56288] [#gap acks 0] [#dup tsns 0] +IP (tos 0x2,ECT(0), ttl 64, id 8, offset 0, flags [DF], proto SCTP (132), length 124) + 192.168.1.7.34917 > 192.168.1.7.6700: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 2574629157] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query Response + ForCES Version 1 len 76B flags 0x38000000 + SrcID 0x7(FE) DstID 0x40000001(CE) Correlator 0x2 + ForCES flags: + NoACK(0x0), prio=7, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + LFBselect TLV, length 52 (data length 48 Bytes) + FEObj LFB(Classid 1) instance 1 + Oper TLV GetResp(0x9) length 40 + PATH-DATA TLV, length 36 (data encapsulated 32 Bytes) + Pathdata: Flags 0x0 ID count 1 + ID#01: 2 + PATH-DATA TLV, length 24 (data encapsulated 20 Bytes) + Pathdata: Flags 0x0 ID count 1 + ID#01: 2 + FULLDATA TLV (Length 12 DataLen 8 Bytes) + [ + 0x0000: 0000 0002 0000 0001 + ] + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 48) + 192.168.1.7.6700 > 192.168.1.7.34917: sctp[ForCES HP] + 1) [SACK] [cum ack 2574629157] [a_rwnd 56296] [#gap acks 0] [#dup tsns 0] diff --git a/tests/forces1vvvv.out b/tests/forces1vvvv.out new file mode 100644 index 0000000..4274ca3 --- /dev/null +++ b/tests/forces1vvvv.out @@ -0,0 +1,67 @@ +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 112) + 192.168.1.7.6700 > 192.168.1.7.34917: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 3442086958] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query + ForCES Version 1 len 64B flags 0xf8000000 + SrcID 0x40000001(CE) DstID 0x7(FE) Correlator 0x2 + ForCES flags: + AlwaysACK(0x3), prio=7, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + LFBselect TLV, length 40 (data length 36 Bytes) + FEObj LFB(Classid 1) instance 1 + Oper TLV Get(0x7) length 28 + PATH-DATA TLV, length 24 (data encapsulated 20 Bytes) + Pathdata: Flags 0x0 ID count 1 + ID#01: 2 + PATH-DATA TLV, length 12 (data encapsulated 8 Bytes) + Pathdata: Flags 0x0 ID count 1 + ID#01: 2 + + Raw ForCES message + [ + 0x0000: 1004 0010 4000 0001 0000 0007 0000 0000 + 0x0010: 0000 0002 f800 0000 1000 0028 0000 0001 + 0x0020: 0000 0001 0007 001c 0110 0018 0000 0001 + 0x0030: 0000 0002 0110 000c 0000 0001 0000 0002 + ] + +IP (tos 0x2,ECT(0), ttl 64, id 7, offset 0, flags [DF], proto SCTP (132), length 48) + 192.168.1.7.34917 > 192.168.1.7.6700: sctp[ForCES HP] + 1) [SACK] [cum ack 3442086958] [a_rwnd 56288] [#gap acks 0] [#dup tsns 0] +IP (tos 0x2,ECT(0), ttl 64, id 8, offset 0, flags [DF], proto SCTP (132), length 124) + 192.168.1.7.34917 > 192.168.1.7.6700: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 2574629157] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query Response + ForCES Version 1 len 76B flags 0x38000000 + SrcID 0x7(FE) DstID 0x40000001(CE) Correlator 0x2 + ForCES flags: + NoACK(0x0), prio=7, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + LFBselect TLV, length 52 (data length 48 Bytes) + FEObj LFB(Classid 1) instance 1 + Oper TLV GetResp(0x9) length 40 + PATH-DATA TLV, length 36 (data encapsulated 32 Bytes) + Pathdata: Flags 0x0 ID count 1 + ID#01: 2 + PATH-DATA TLV, length 24 (data encapsulated 20 Bytes) + Pathdata: Flags 0x0 ID count 1 + ID#01: 2 + FULLDATA TLV (Length 12 DataLen 8 Bytes) + [ + 0x0000: 0000 0002 0000 0001 + ] + + Raw ForCES message + [ + 0x0000: 1014 0013 0000 0007 4000 0001 0000 0000 + 0x0010: 0000 0002 3800 0000 1000 0034 0000 0001 + 0x0020: 0000 0001 0009 0028 0110 0024 0000 0001 + 0x0030: 0000 0002 0110 0018 0000 0001 0000 0002 + 0x0040: 0112 000c 0000 0002 0000 0001 + ] + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 48) + 192.168.1.7.6700 > 192.168.1.7.34917: sctp[ForCES HP] + 1) [SACK] [cum ack 2574629157] [a_rwnd 56296] [#gap acks 0] [#dup tsns 0] diff --git a/tests/forces2.out b/tests/forces2.out new file mode 100644 index 0000000..a997b59 --- /dev/null +++ b/tests/forces2.out @@ -0,0 +1,491 @@ +IP 122.234.155.8.32820 > 150.140.188.145.6700: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 996458213] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Setup + +IP 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3761691905] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Response + +IP 150.140.188.146.32780 > 150.140.188.145.6700: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 2256581227] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Setup + +IP 150.140.188.145.6700 > 150.140.188.146.32780: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3596535672] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Response + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632869] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244257] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.50001 > 150.140.188.145.6700: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3118638120] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Setup + +IP 150.140.188.145.6700 > 150.140.188.175.50001: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3264258942] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Response + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073935] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825012] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632870] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632870] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019513] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437131] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073936] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825013] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632871] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244258] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019514] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437132] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073937] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825014] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632872] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244260] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019515] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437133] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073938] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825015] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632873] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244261] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019516] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437134] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073939] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825016] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3761691906] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query + +IP 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3761691906] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query + +IP 122.234.155.8.32820 > 150.140.188.145.6700: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 996458214] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query Response + +IP 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3761691906] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019517] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437135] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073940] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825017] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632874] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244262] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019518] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437136] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073941] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825018] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632875] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244263] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019519] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437137] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073942] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825019] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632876] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632876] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019520] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437138] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073943] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825020] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632877] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244264] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019521] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437139] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073944] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825021] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632878] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244266] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019522] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437140] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073945] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825022] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632879] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244267] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019523] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437141] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073946] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825023] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632880] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632880] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019524] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437142] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073947] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3761691907] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES Config + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825024] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32820 > 150.140.188.145.6700: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 996458215] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES Config Response + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019525] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437143] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073948] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632881] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825025] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632881] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019526] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437144] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073949] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632882] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825026] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244269] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019527] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437145] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073950] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825027] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632883] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244271] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019528] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437146] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073951] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825028] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632884] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244272] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019529] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437147] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073952] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825029] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632885] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244273] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3761691908] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES Config + +IP 122.234.155.8.32820 > 150.140.188.145.6700: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 996458216] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES Config Response + +IP 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3761691908] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES Config + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019530] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437148] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073953] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825030] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632886] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019531] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437149] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073954] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825031] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632887] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019532] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437150] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244274] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat +, (2) [DATA] (B)(E) [TSN: 1662244278] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073955] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825032] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632888] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019533] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437151] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073956] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825033] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632889] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244279] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019534] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437152] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244283] [SID: 0] [SSEQ 26] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073957] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825034] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632890] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244284] [SID: 0] [SSEQ 27] [PPID 0x0] + ForCES HeartBeat + +IP 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244285] [SID: 0] [SSEQ 28] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019535] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437153] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073958] [SID: 0] [SSEQ 23] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825035] [SID: 0] [SSEQ 23] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019536] [SID: 0] [SSEQ 23] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437154] [SID: 0] [SSEQ 23] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073959] [SID: 0] [SSEQ 24] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825036] [SID: 0] [SSEQ 24] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019537] [SID: 0] [SSEQ 24] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437155] [SID: 0] [SSEQ 24] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073960] [SID: 0] [SSEQ 25] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825037] [SID: 0] [SSEQ 25] [PPID 0x0] + ForCES HeartBeat + +IP 150.140.188.145.6700 > 150.140.188.146.32780: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3596535673] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Association TearDown + +IP 150.140.188.145.6700 > 150.140.188.175.50001: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3264258943] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Association TearDown + diff --git a/tests/forces2.pcap b/tests/forces2.pcap new file mode 100644 index 0000000000000000000000000000000000000000..6970b348782af0997f9b1bb03a7f70e8f7095184 GIT binary patch literal 17566 zcmdU%3z$vi8pqe3*>hvAW|%Qi$t81!kz9*T3sH<*N;!_(l!SC~qM{thwTo0#x~PMa zA`wSYgr=e+g^Wv)kx+CaPUvXP|Nri_)_(U|`EtWHrcVwh&LLxx#_)w{6)6RfRTtF@g{ddEpQ4y zNeMQsVhli^uTcCD3zRschhdn8IcaMy2_)q=8sGfb(f-RiPW^l#C>NEt+{@FImYHQF zo1t!e=!X$#orzwik<9(tptZU@-knqYm2V{P6Pn~?PMUcfv>B39YJQ_BCytaXJG|sE z<}_vevf)-_JEuf5G+;a|Igv8xP<%KiiSNy6=1~$zLQbg#uXa0-d-k?w%xTAf4Wk`O zC@1E~5oC+VsV->!$5aXDBnm0oRn`ceN1BXa(fAhU-9Gx2(w*OrWlpotqz(=R#z18l z%!kbx!F3qHdZ2uDX1t0J3(8BsSZlFG-e0^?0m=e-QJ3Ef^Xy!3c zLe5UlFG@XLaJFpj?n9)!`qv+tYYO@i&gQ?h0wv>>SiCl9Yxl;az-u=nkc?Cmuf;K! z)}Xvoo*vG{x1;|P%4MK@l#vvsxLsiDvcqvf(VRQu{&n@Mt4gLeVJsdT?=?2Q)A5z2Wd+S+})U$kdJzMz5164>tJ(~xL z<7D)az0-u=6O^15N`2oRt9f(1aiqXwmm;P^u?Vt{#+pUWvkm`omLjS zND4gmiKeh`knYK&QM%Y36J1E@_oycq?XgfUKe|0O zbmO*-q`+e>H3fa`F>%2_P+ApL4Xf|F!mJva*NYT*Y$zg2G?k0(u^>HG0?Ob2R_Qep zcPqGqs_FLFktrKqBLyCNSyR|Iv9Vf^KL>-d<|Z{_zC9L9nHC@g9&3X@?)hSSOmrco z=TJrQdJOXgbN@59$NKJiU_UAF*k(;ZUwbT`9=i>c?LWujv8GRd@G>dz*fogk*2VUi z=t9ca50b;`hjP&#gD%L0_h%8;$_5QOZ6*aCYo#gZYmbR8BSE>~-dH?Vcj?hHq`+gt z5Lu!{@mK;qHVTyX<&}D@ig+y7?XeL9nkSJ0kImN<=4E1IwFLeg14_f`N`2oR>ofeu zy`;cnZ4t<=i|sMdg_IdjD2mr(DWc0}x5tW0hV&o>9{W^N(AORd(qj*RGT=gWrzE`nM$252}9LM4WZ%3;&O2J-KCyF#+Si zSI9Bp^>AR60e2Qo`sRCQrdjLZ+Ar)FWW)!0VLg1v8aE>|$KbUv-o(agiLFf;>vHUe z#yZ8=j&a*!?Z*YG86PwcGXj(0qf@j0-+c5a=j={Z<$TxD(&bN#WMx1ty$t!g z>kr3}P3jLROTSPQZ!N8Avi@vx*V3(TKlwW;sHLAFnnOWf*U|*TG>oS}DSRxJTH0yG z?3SdUmiFQ~;}z|mFp<|dQWBe~E2;N-ohrE;cGuEPPiIUf1+|nbHHU(Jq8V}>x}oPP zPlIwMPdyv*eNWhAcb}Q0;Cg)vqB#^0*f{stl9&rACo|RRCX|b?tfy+}a=p%Ws)+R* zWo)Y{x08bFHA}riK|kKa#%f9YITw_*t<)WkZ;uUHaq$JDz+-aA0z8M}d(Pbehcl3?LW5s)pts(^; z8?GrJu-P6F1msgcx(Zp>RhzPSbdEZpnNh~sqfok)2LA)wyVoCDCJRKv`Z*J=ySm zPxwW*74|baJ|q{Fqj*eoA?5D5X_c)zpbI>9!0oZ#T^dYhF7OyvY7T{Y;q>jwFS@)3 z%JcJL@!0SCMxP`F9=lajKwz^ymO@?Df>JeK%}U?Z@;{+`%v?TH>ihOsNoilH{P38G zb9Y9JJ7~^`F&9z_K2{X3$FfA158WQC$lho_quYk44uu308>=PLV_QKv-7gl8t$nO^ zbLxUR)*BH;Qp`fol#=Asg8z}h| zv3RU>{qbp}z+<;*ipj8Hk5!>AWuP=Fu5@i%L+V&ncO7dr`7QYb3U%yNMAf?JIwra7 z1*O%mN`2oRONjeLa)HO%f#Qsqi5)cCW1QrtVH^ad#h6$;w(;-+88LY5PlzZZ6UAeq%OOw}ZVr7as6H9g9?Owj_PIT_ zuXp`-EsyaI)}f%UJ;v3CLCQ4+>RFKQ3ezTUYuwjo?rN>Cwe!S9aWv+Ov zirZty+pl?;6nJbQqUv0<$GCbjj)5|@sd^gV+hg;CJ?!Tv?KQ<@*s#Y$7gDOXP!zAn zs*5h`-5$FqebX%F0*`G+RGo|VSQUEgG$>EK8jHuu9?TG3;ITfSh{{nsCc2yfr99}F z``Tle`?yx_b$e{~?G+;|kMR!Hp`folCc2O^YHTbX`?SXD_Lj%)&=eCpX!f--l^!Fd zcOTFCMc?z+6ptmlJ(kq<&cUR>V~Y?~=b}B9N@T)OTr2x4^?iHn?ct~7Duz1NK~qeI z4SP&-N|!Hw^lgxxiy(h^lkZ9;-@^rIGSQEFSytqVH;v0+0O} z6j3>f$3&NOQ2wOv#=Y0dJjvxtx5u`PAAT1pxK{EG)}f%UJtn%4a@X!yJXY_$qoO{p zl_NC8#15M6u{3%t1C(ce{clrhg3{w@rM_>E9ZacVf1Y&(&fOU?lbM7)Cc2RF<+F<7 z^%&+0JhsN|v3qwk1Z{*AKg!V}TCxa)npCgxuC$#U3{iru6qws{5O2_e+Gvf_pF3nay{S*$s z09|pE?+M^PK84MZKAzv;X_>6AaSU(68?Z08CIKT)z0Z33cIh)0;EbowP)_pB3Opso z=8(u}m*&=c7H zl>2;p{Qj*6w=jRy(T)i0{I1*M<$=3@B?WbKC!#qN z5=?BYmIhlHEkOBta4a5Q*8ELbal+&M5K%OX;_-CW9#YOU$q27&ec!2d*-AeeKJ1B1t*g_P?D= zJ5V-Uq3$|;du-p%P7g2_c&wAo#pKC{Jtn%4@>Wkp@p`PbjMyr-$7T)tB#RVyY!{;H z5z`(^r^h;jvTJ!P9$V74<}p&>vHqaQ_($=WsNV&YhdQe@hi{MN1s@zu3OshF&IPB= zW_v7?9wQ|!pmOng>|7Z!e*Y}uli}u@=l(znJk}mjom|k@9?KxID=0kZ zb{!L4NV#~nqIf-ao{ZQ^x5pk%yh)yC!(+P<)uE7JVq>)odaOSviz<{ZzOU71A9~0B z%ys}G%E(0Vn5a+6god6qx?XdHa@p=yzjfykat96dJ7@~}T79|B3;?CzUZuWoCnpR) zUp}#ilSd-5Gh!xo&}=7X(aEH=@1RD^>#=&`v9oTE&3x{nV#{Mo5Y?fOU}9snEdCq@ zO74E8zHg6R8SEwZQ1IAQ2;|nq_L%5G%HBlJ`bk*Uw?gZP$5yyKwrl%_r>22}?rV>Qa^d#@BPvY0cBd{O z1s=OXQ_$BQ6J72ErSBWDcT`_1jKIzM!j zRT}EpQcXc$d#oDvjlY62Ay29A+hdK#zw$G4fyZ#=@aSTDOmrb-N4}zX>sVd!*mAeW zmi1_{lN5ODOHDyvdn}6{n+(eE$7Au>fM(stkOGgDAhM_&#bcriDH*fWtPJI%Jr>Gk zi`!#svkLZ*0*~^cln^V)aycyvm_T#Oj2M;D~-%mtGJK?OriW*jNM+^Q(v>QP^+$D8izF>u<8 zREX7M4+1(A63h^R+iI*H&w`R$9!vG;(C=^}DX1PdNHlDsR1cYPq!fSZ$wgO>P%iwx zBOlLgZ1?t~}KyF=Z^=mMfRiIpb zTB`Wg^ehXdC8 z-a@ZBcdgm0-xt3Q$JgU*hMtVYiyyZ=UXv7faS#HD8=`noW-lqr+gAEn_8(+q`Te2@ zFV1aHv6d8gk*f=bg1+{mbzt@|QsBkWi0tTRVh7FkVlKV78I+DA z)%S~hd$ISmOJ64iUc4Gnom@;Z!d{dSBW3m7isJQRp^Vrfw-+}~tosNl@Zvs1btoj5 z*jTMPy;ugyxFPEP(sw1QSKdb)5A|K2;_{I$*^Jd^QitlP|o`# z5Pm`$%0)l%xmafJPwv@USp2seNx|%0iKueUQD$Xu9sY4YC^sxq>ihQCuh(UtB?TVq zhCt4Unb<+I>z(LA%9$04;`LZ#(d9L_#{z5Wy+aB-R*t9+g#;5DtJR>#4uLXpgu2)9 zj#x7pu^-(dwx`$2pIamLE+XbLYLpR6T!-V|fpQWb6J3u!UxsfdU-H;7@fe&u7{BM} zVlqnD$ujqkfb#QDkNVolsNJ}x^7};*POjDc#1qT~PUbzRLm|No>ynFo<7ZHQ3aAnD zUB|jV_~UX?;N*J|$k7D^HoK11q?1Xhx7<^cwUe8REb+6-lz8tyq-3g>%zH~<* zM;8-2X!d*&^+{Rby`vJA_4KNVsK3BHUutce_8}>lFZ&VIp^#u=W3^n)m$RUB?HY@d z-)=jih!i;aW<(S(al{am&92E($9@MTYfh!#%D6~!;kTF~oLssvsV6CLGViAy3JGR- z#PYCjqsV9CWxiXN7j8&<)6(T@ zM0F@6nAlh?kGf=ma`T*6blH1$*M*iYLl99$CW!r=OX3d3*y zMCh{OaG89b1YLNi>rl|wy2z}o4NBoZ)rk3?FSRbY;xu!?eCeqvCU($lT_hJ$-Z-r& zUR_Z6k;_YNT~5uJ|F)&e0YufgXkBVjm-?XO_ET3e-<5yiQ#Y=+bQubYj7$_=@>wk# zfHF0`($6eWEs+bqEfb+j@yg&$q(B$m^*I#uwJvgXYYfW1PU>%HxO2f=5DNc)M*ckm z=kHA%9C$A8#`*Uq#vrojkQrwro7h3K=e{9-Lj!+@f(J?4TdZhq7uYnfR_vj6}9 literal 0 HcmV?d00001 diff --git a/tests/forces2v.out b/tests/forces2v.out new file mode 100644 index 0000000..dff4df5 --- /dev/null +++ b/tests/forces2v.out @@ -0,0 +1,982 @@ +IP (tos 0x0, ttl 43, id 1, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32820 > 150.140.188.145.6700: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 996458213] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Setup + ForCES Version 1 len 24B flags 0xf8000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x1 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 80) + 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3761691905] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Response + ForCES Version 1 len 32B flags 0x38100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x1 + +IP (tos 0x2,ECT(0), ttl 64, id 1, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32780 > 150.140.188.145.6700: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 2256581227] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Setup + ForCES Version 1 len 24B flags 0xf8000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x1 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 80) + 150.140.188.145.6700 > 150.140.188.146.32780: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3596535672] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Response + ForCES Version 1 len 32B flags 0x38100000 + SrcID 0x40000001(CE) DstID 0x6(FE) Correlator 0x1 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632869] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x1 + +IP (tos 0x0, ttl 43, id 2, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244257] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x1 + +IP (tos 0x2,ECT(0), ttl 64, id 1, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.50001 > 150.140.188.145.6700: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3118638120] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Setup + ForCES Version 1 len 24B flags 0xf8000000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x1 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 80) + 150.140.188.145.6700 > 150.140.188.175.50001: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3264258942] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Response + ForCES Version 1 len 32B flags 0x38100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x1 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073935] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x1 + +IP (tos 0x2,ECT(0), ttl 64, id 2, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825012] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x1 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632870] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x2 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632870] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x2 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019513] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x1 + +IP (tos 0x2,ECT(0), ttl 64, id 4, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437131] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x1 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073936] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x2 + +IP (tos 0x2,ECT(0), ttl 64, id 3, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825013] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x2 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632871] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x3 + +IP (tos 0x0, ttl 43, id 7, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244258] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x2 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019514] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x2 + +IP (tos 0x2,ECT(0), ttl 64, id 5, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437132] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x2 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073937] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x3 + +IP (tos 0x2,ECT(0), ttl 64, id 5, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825014] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x3 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632872] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x4 + +IP (tos 0x0, ttl 43, id 8, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244260] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x4 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019515] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x3 + +IP (tos 0x2,ECT(0), ttl 64, id 7, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437133] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x3 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073938] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x4 + +IP (tos 0x2,ECT(0), ttl 64, id 8, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825015] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x4 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632873] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x5 + +IP (tos 0x0, ttl 43, id 10, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244261] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x5 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019516] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x4 + +IP (tos 0x2,ECT(0), ttl 64, id 9, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437134] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x4 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073939] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x5 + +IP (tos 0x2,ECT(0), ttl 64, id 10, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825016] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x5 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 152) + 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3761691906] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query + ForCES Version 1 len 104B flags 0xf8400000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x6 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 152) + 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3761691906] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query + ForCES Version 1 len 104B flags 0xf8400000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x6 + +IP (tos 0x0, ttl 43, id 9, offset 0, flags [DF], proto SCTP (132), length 372) + 122.234.155.8.32820 > 150.140.188.145.6700: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 996458214] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query Response + ForCES Version 1 len 324B flags 0x38400000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x6 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 152) + 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3761691906] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query + ForCES Version 1 len 104B flags 0xf8400000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x6 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019517] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x5 + +IP (tos 0x2,ECT(0), ttl 64, id 11, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437135] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x5 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073940] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x6 + +IP (tos 0x2,ECT(0), ttl 64, id 12, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825017] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x6 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632874] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x7 + +IP (tos 0x0, ttl 43, id 14, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244262] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x7 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019518] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x6 + +IP (tos 0x2,ECT(0), ttl 64, id 13, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437136] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x6 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073941] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x7 + +IP (tos 0x2,ECT(0), ttl 64, id 14, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825018] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x7 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632875] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x8 + +IP (tos 0x0, ttl 43, id 16, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244263] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x8 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019519] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x7 + +IP (tos 0x2,ECT(0), ttl 64, id 15, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437137] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x7 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073942] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x8 + +IP (tos 0x2,ECT(0), ttl 64, id 16, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825019] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x8 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632876] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x9 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632876] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x9 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019520] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x8 + +IP (tos 0x2,ECT(0), ttl 64, id 17, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437138] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x8 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073943] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x9 + +IP (tos 0x2,ECT(0), ttl 64, id 18, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825020] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x9 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632877] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x10 + +IP (tos 0x0, ttl 43, id 22, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244264] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x9 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019521] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x9 + +IP (tos 0x2,ECT(0), ttl 64, id 19, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437139] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x9 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073944] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x10 + +IP (tos 0x2,ECT(0), ttl 64, id 20, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825021] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x10 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632878] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x11 + +IP (tos 0x0, ttl 43, id 23, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244266] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x11 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019522] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x10 + +IP (tos 0x2,ECT(0), ttl 64, id 21, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437140] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x10 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073945] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x11 + +IP (tos 0x2,ECT(0), ttl 64, id 22, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825022] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x11 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632879] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x12 + +IP (tos 0x0, ttl 43, id 25, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244267] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x12 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019523] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x11 + +IP (tos 0x2,ECT(0), ttl 64, id 23, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437141] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x11 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073946] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x12 + +IP (tos 0x2,ECT(0), ttl 64, id 24, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825023] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x12 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632880] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x13 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632880] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x13 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019524] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x12 + +IP (tos 0x2,ECT(0), ttl 64, id 25, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437142] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x12 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073947] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x13 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 148) + 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3761691907] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES Config + ForCES Version 1 len 100B flags 0xf8400000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x14 + +IP (tos 0x2,ECT(0), ttl 64, id 26, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825024] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x13 + +IP (tos 0x0, ttl 43, id 21, offset 0, flags [DF], proto SCTP (132), length 124) + 122.234.155.8.32820 > 150.140.188.145.6700: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 996458215] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES Config Response + ForCES Version 1 len 76B flags 0x38400000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x14 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019525] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x13 + +IP (tos 0x2,ECT(0), ttl 64, id 27, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437143] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x13 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073948] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x14 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632881] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x15 + +IP (tos 0x2,ECT(0), ttl 64, id 28, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825025] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x14 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632881] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x15 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019526] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x14 + +IP (tos 0x2,ECT(0), ttl 64, id 29, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437144] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x14 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073949] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x15 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632882] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x16 + +IP (tos 0x2,ECT(0), ttl 64, id 30, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825026] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x15 + +IP (tos 0x0, ttl 43, id 35, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244269] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x15 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019527] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x15 + +IP (tos 0x2,ECT(0), ttl 64, id 31, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437145] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x15 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073950] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x16 + +IP (tos 0x2,ECT(0), ttl 64, id 31, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825027] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x16 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632883] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x17 + +IP (tos 0x0, ttl 43, id 36, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244271] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x17 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019528] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x16 + +IP (tos 0x2,ECT(0), ttl 64, id 33, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437146] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x16 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073951] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x17 + +IP (tos 0x2,ECT(0), ttl 64, id 33, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825028] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x17 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632884] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x18 + +IP (tos 0x0, ttl 43, id 38, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244272] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x18 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019529] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x17 + +IP (tos 0x2,ECT(0), ttl 64, id 35, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437147] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x17 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073952] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x18 + +IP (tos 0x2,ECT(0), ttl 64, id 35, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825029] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x18 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632885] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x19 + +IP (tos 0x0, ttl 43, id 40, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244273] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x19 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 128) + 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3761691908] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES Config + ForCES Version 1 len 80B flags 0xf8400000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x20 + +IP (tos 0x0, ttl 43, id 29, offset 0, flags [DF], proto SCTP (132), length 128) + 122.234.155.8.32820 > 150.140.188.145.6700: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 996458216] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES Config Response + ForCES Version 1 len 80B flags 0x38400000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x20 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 128) + 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3761691908] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES Config + ForCES Version 1 len 80B flags 0xf8400000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x20 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019530] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x18 + +IP (tos 0x2,ECT(0), ttl 64, id 37, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437148] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x18 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073953] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x19 + +IP (tos 0x2,ECT(0), ttl 64, id 37, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825030] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x19 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632886] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x21 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019531] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x19 + +IP (tos 0x2,ECT(0), ttl 64, id 39, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437149] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x19 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073954] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x20 + +IP (tos 0x2,ECT(0), ttl 64, id 40, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825031] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x20 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632887] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x22 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019532] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x20 + +IP (tos 0x2,ECT(0), ttl 64, id 41, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437150] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x20 + +IP (tos 0x0, ttl 43, id 46, offset 0, flags [DF], proto SCTP (132), length 112) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244274] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x1 +, (2) [DATA] (B)(E) [TSN: 1662244278] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x3 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073955] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x21 + +IP (tos 0x2,ECT(0), ttl 64, id 42, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825032] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x21 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632888] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x23 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019533] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x21 + +IP (tos 0x2,ECT(0), ttl 64, id 43, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437151] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x21 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073956] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x22 + +IP (tos 0x2,ECT(0), ttl 64, id 44, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825033] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x22 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632889] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x24 + +IP (tos 0x0, ttl 43, id 50, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244279] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x4 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019534] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x22 + +IP (tos 0x2,ECT(0), ttl 64, id 45, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437152] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x22 + +IP (tos 0x0, ttl 43, id 51, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244283] [SID: 0] [SSEQ 26] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x6 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073957] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x23 + +IP (tos 0x2,ECT(0), ttl 64, id 46, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825034] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x23 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2633632890] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x25 + +IP (tos 0x0, ttl 43, id 52, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244284] [SID: 0] [SSEQ 27] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x25 + +IP (tos 0x0, ttl 43, id 54, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1662244285] [SID: 0] [SSEQ 28] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x7 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019535] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x23 + +IP (tos 0x2,ECT(0), ttl 64, id 47, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437153] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x23 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073958] [SID: 0] [SSEQ 23] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x24 + +IP (tos 0x2,ECT(0), ttl 64, id 48, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825035] [SID: 0] [SSEQ 23] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x24 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019536] [SID: 0] [SSEQ 23] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x24 + +IP (tos 0x2,ECT(0), ttl 64, id 49, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437154] [SID: 0] [SSEQ 23] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x24 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073959] [SID: 0] [SSEQ 24] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x25 + +IP (tos 0x2,ECT(0), ttl 64, id 50, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825036] [SID: 0] [SSEQ 24] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x25 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 1724019537] [SID: 0] [SSEQ 24] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x25 + +IP (tos 0x2,ECT(0), ttl 64, id 51, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3749437155] [SID: 0] [SSEQ 24] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x25 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 3406073960] [SID: 0] [SSEQ 25] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x26 + +IP (tos 0x2,ECT(0), ttl 64, id 52, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] (1) [DATA] (B)(E) [TSN: 2826825037] [SID: 0] [SSEQ 25] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x26 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 80) + 150.140.188.145.6700 > 150.140.188.146.32780: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3596535673] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Association TearDown + ForCES Version 1 len 32B flags 0x38100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x0 + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 80) + 150.140.188.145.6700 > 150.140.188.175.50001: sctp[ForCES HP] (1) [DATA] (B)(E) [TSN: 3264258943] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Association TearDown + ForCES Version 1 len 32B flags 0x38100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x0 + diff --git a/tests/forces2vv.out b/tests/forces2vv.out new file mode 100644 index 0000000..d43de74 --- /dev/null +++ b/tests/forces2vv.out @@ -0,0 +1,1966 @@ +IP (tos 0x0, ttl 43, id 1, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32820 > 150.140.188.145.6700: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 996458213] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Setup + ForCES Version 1 len 24B flags 0xf8000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x1 + ForCES flags: + AlwaysACK(0x3), prio=7, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 80) + 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 3761691905] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Response + ForCES Version 1 len 32B flags 0x38100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x1 + ForCES flags: + NoACK(0x0), prio=7, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 1, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32780 > 150.140.188.145.6700: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 2256581227] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Setup + ForCES Version 1 len 24B flags 0xf8000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x1 + ForCES flags: + AlwaysACK(0x3), prio=7, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 80) + 150.140.188.145.6700 > 150.140.188.146.32780: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 3596535672] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Response + ForCES Version 1 len 32B flags 0x38100000 + SrcID 0x40000001(CE) DstID 0x6(FE) Correlator 0x1 + ForCES flags: + NoACK(0x0), prio=7, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632869] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x1 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 2, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244257] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x1 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 1, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.50001 > 150.140.188.145.6700: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 3118638120] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Setup + ForCES Version 1 len 24B flags 0xf8000000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x1 + ForCES flags: + AlwaysACK(0x3), prio=7, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 80) + 150.140.188.145.6700 > 150.140.188.175.50001: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 3264258942] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES Association Response + ForCES Version 1 len 32B flags 0x38100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x1 + ForCES flags: + NoACK(0x0), prio=7, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073935] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x1 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 2, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825012] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x1 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632870] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x2 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632870] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x2 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019513] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x1 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 4, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437131] [SID: 0] [SSEQ 0] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x1 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073936] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x2 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 3, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825013] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x2 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632871] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x3 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 7, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244258] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x2 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019514] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x2 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 5, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437132] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x2 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073937] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x3 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 5, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825014] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x3 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632872] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x4 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 8, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244260] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x4 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019515] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x3 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 7, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437133] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x3 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073938] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x4 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 8, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825015] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x4 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632873] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x5 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 10, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244261] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x5 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019516] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x4 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 9, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437134] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x4 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073939] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x5 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 10, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825016] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x5 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 152) + 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 3761691906] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query + ForCES Version 1 len 104B flags 0xf8400000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x6 + ForCES flags: + AlwaysACK(0x3), prio=7, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 152) + 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 3761691906] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query + ForCES Version 1 len 104B flags 0xf8400000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x6 + ForCES flags: + AlwaysACK(0x3), prio=7, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 9, offset 0, flags [DF], proto SCTP (132), length 372) + 122.234.155.8.32820 > 150.140.188.145.6700: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 996458214] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query Response + ForCES Version 1 len 324B flags 0x38400000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x6 + ForCES flags: + NoACK(0x0), prio=7, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 152) + 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 3761691906] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Query + ForCES Version 1 len 104B flags 0xf8400000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x6 + ForCES flags: + AlwaysACK(0x3), prio=7, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019517] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x5 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 11, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437135] [SID: 0] [SSEQ 4] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x5 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073940] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x6 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 12, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825017] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x6 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632874] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x7 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 14, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244262] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x7 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019518] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x6 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 13, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437136] [SID: 0] [SSEQ 5] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x6 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073941] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x7 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 14, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825018] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x7 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632875] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x8 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 16, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244263] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x8 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019519] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x7 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 15, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437137] [SID: 0] [SSEQ 6] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x7 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073942] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x8 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 16, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825019] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x8 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632876] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x9 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632876] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x9 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019520] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x8 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 17, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437138] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x8 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073943] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x9 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 18, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825020] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x9 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632877] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x10 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 22, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244264] [SID: 0] [SSEQ 7] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x9 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019521] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x9 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 19, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437139] [SID: 0] [SSEQ 8] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x9 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073944] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x10 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 20, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825021] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x10 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632878] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x11 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 23, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244266] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x11 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019522] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x10 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 21, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437140] [SID: 0] [SSEQ 9] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x10 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073945] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x11 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 22, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825022] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x11 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632879] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x12 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 25, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244267] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x12 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019523] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x11 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 23, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437141] [SID: 0] [SSEQ 10] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x11 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073946] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x12 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 24, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825023] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x12 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632880] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x13 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632880] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x13 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019524] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x12 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 25, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437142] [SID: 0] [SSEQ 11] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x12 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073947] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x13 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 148) + 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 3761691907] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES Config + ForCES Version 1 len 100B flags 0xf8400000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x14 + ForCES flags: + AlwaysACK(0x3), prio=7, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 26, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825024] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x13 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 21, offset 0, flags [DF], proto SCTP (132), length 124) + 122.234.155.8.32820 > 150.140.188.145.6700: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 996458215] [SID: 0] [SSEQ 2] [PPID 0x0] + ForCES Config Response + ForCES Version 1 len 76B flags 0x38400000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x14 + ForCES flags: + NoACK(0x0), prio=7, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019525] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x13 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 27, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437143] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x13 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073948] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x14 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632881] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x15 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 28, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825025] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x14 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632881] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x15 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019526] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x14 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 29, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437144] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x14 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073949] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x15 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632882] [SID: 0] [SSEQ 13] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x16 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 30, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825026] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x15 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 35, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244269] [SID: 0] [SSEQ 12] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x15 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019527] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x15 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 31, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437145] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x15 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073950] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x16 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 31, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825027] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x16 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632883] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x17 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 36, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244271] [SID: 0] [SSEQ 14] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x17 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019528] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x16 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 33, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437146] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x16 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073951] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x17 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 33, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825028] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x17 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632884] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x18 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 38, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244272] [SID: 0] [SSEQ 15] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x18 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019529] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x17 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 35, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437147] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x17 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073952] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x18 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 35, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825029] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x18 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632885] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x19 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 40, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244273] [SID: 0] [SSEQ 16] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x19 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 128) + 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 3761691908] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES Config + ForCES Version 1 len 80B flags 0xf8400000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x20 + ForCES flags: + AlwaysACK(0x3), prio=7, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 29, offset 0, flags [DF], proto SCTP (132), length 128) + 122.234.155.8.32820 > 150.140.188.145.6700: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 996458216] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES Config Response + ForCES Version 1 len 80B flags 0x38400000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x20 + ForCES flags: + NoACK(0x0), prio=7, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 128) + 150.140.188.145.6700 > 122.234.155.8.32820: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 3761691908] [SID: 0] [SSEQ 3] [PPID 0x0] + ForCES Config + ForCES Version 1 len 80B flags 0xf8400000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x20 + ForCES flags: + AlwaysACK(0x3), prio=7, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019530] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x18 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 37, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437148] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x18 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073953] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x19 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 37, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825030] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x19 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632886] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x21 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019531] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x19 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 39, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437149] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x19 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073954] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x20 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 40, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825031] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x20 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632887] [SID: 0] [SSEQ 18] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x22 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019532] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x20 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 41, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437150] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x20 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 46, offset 0, flags [DF], proto SCTP (132), length 112) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244274] [SID: 0] [SSEQ 17] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x1 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + + 2) [DATA] (B)(E) [TSN: 1662244278] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x3 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073955] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x21 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 42, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825032] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x21 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632888] [SID: 0] [SSEQ 19] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x23 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019533] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x21 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 43, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437151] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x21 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073956] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x22 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 44, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825033] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x22 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632889] [SID: 0] [SSEQ 20] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x24 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 50, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244279] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x4 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019534] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x22 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 45, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437152] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x22 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 51, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244283] [SID: 0] [SSEQ 26] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x6 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073957] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x23 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 46, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825034] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x23 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 122.234.155.8.32821: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2633632890] [SID: 0] [SSEQ 21] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x3(FE) Correlator 0x25 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 52, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244284] [SID: 0] [SSEQ 27] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x25 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x0, ttl 43, id 54, offset 0, flags [DF], proto SCTP (132), length 72) + 122.234.155.8.32821 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1662244285] [SID: 0] [SSEQ 28] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0000000 + SrcID 0x3(FE) DstID 0x40000000(CE) Correlator 0x7 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019535] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x23 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 47, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437153] [SID: 0] [SSEQ 22] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x23 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073958] [SID: 0] [SSEQ 23] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x24 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 48, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825035] [SID: 0] [SSEQ 23] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x24 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019536] [SID: 0] [SSEQ 23] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x24 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 49, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437154] [SID: 0] [SSEQ 23] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x24 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073959] [SID: 0] [SSEQ 24] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x25 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 50, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825036] [SID: 0] [SSEQ 24] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x25 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.175.41074: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 1724019537] [SID: 0] [SSEQ 24] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x25 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 51, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.175.41074 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3749437155] [SID: 0] [SSEQ 24] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00400000 + SrcID 0x1(FE) DstID 0x40000000(CE) Correlator 0x25 + ForCES flags: + NoACK(0x0), prio=0, execute-all-or-none(0x1), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.145.6702 > 150.140.188.146.32782: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 3406073960] [SID: 0] [SSEQ 25] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0xc0100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x26 + ForCES flags: + AlwaysACK(0x3), prio=0, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 52, offset 0, flags [DF], proto SCTP (132), length 72) + 150.140.188.146.32782 > 150.140.188.145.6702: sctp[ForCES LP] + 1) [DATA] (B)(E) [TSN: 2826825037] [SID: 0] [SSEQ 25] [PPID 0x0] + ForCES HeartBeat + ForCES Version 1 len 24B flags 0x00000000 + SrcID 0x6(FE) DstID 0x40000001(CE) Correlator 0x26 + ForCES flags: + NoACK(0x0), prio=0, EMReserved(0x0), + Standalone(0x0), StartofTransaction(0x0) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 80) + 150.140.188.145.6700 > 150.140.188.146.32780: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 3596535673] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Association TearDown + ForCES Version 1 len 32B flags 0x38100000 + SrcID 0x40000000(CE) DstID 0x6(FE) Correlator 0x0 + ForCES flags: + NoACK(0x0), prio=7, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + +IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto SCTP (132), length 80) + 150.140.188.145.6700 > 150.140.188.175.50001: sctp[ForCES HP] + 1) [DATA] (B)(E) [TSN: 3264258943] [SID: 0] [SSEQ 1] [PPID 0x0] + ForCES Association TearDown + ForCES Version 1 len 32B flags 0x38100000 + SrcID 0x40000000(CE) DstID 0x1(FE) Correlator 0x0 + ForCES flags: + NoACK(0x0), prio=7, EMReserved(0x0), + Standalone(0x0), EndofTransaction(0x2) + Extra flags: rsv(b5-7) 0x0 rsv(b13-31) 0x0 + + diff --git a/tests/ikev2.puu b/tests/ikev2.puu new file mode 100644 index 0000000..85b773f --- /dev/null +++ b/tests/ikev2.puu @@ -0,0 +1,22231 @@ +begin 644 ikev2.pcap +MU,.RH0(`!````````````-P%````````1!*W1JWG!0"8`0``F`$```(```!% +M``&43<0``$`1``#`J`$!P*@!`@'T`?0!@`=EJ(AUJ!F)DJ8``````````"$@ +M(@@````````!>"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``M41;U@SLYOW-/):E++M[M":HQZ#U:IPXT;'$\,.FZ.?;I<'[_$%BT02 +MMT9`]@4`7````%P````"````10``6$W%``!`$0``P*@!`<"H`0(!]`'T`$0& +M*:B(=:@9B9*F```````````I("(@`````````#P````@``!`!@````'"(AY0 +MP6X2/RL,<:[\\,L[>8>"QD02MT8;!08`N`$``+@!```"````10`!M$W&``!` +M$0``P*@!`<"H`0(!]`'T`:`'A:B(=:@9B9*F```````````I("((```````` +M`9@A```@``!`!@````'"(AY0P6X2/RL,<:[\\,L[>8>"QB(``'@```!T`0$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``M41;U@SLYOW-/):E++M[M":H +MQZ#U:IPXT;'$\,.FZ.?;I<'[_$%BT02MT9-*`8`4`$``%`!```"````10`! +M3$W'``!`$0``P*@!`<"H`0(!]`'T`3@'':B(=:@9B9*F<;Z#6.^N=F,A("(@ +M`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@# +M```"````"`0```(H``"(``(``%I6<4TZOV3CH_0!ZMGU,C_PMW^J7QZ9&9L3 +MK((?"@Q/A4>&R@FWIVJE"+SN$?%C::%M7Z!!RBV:C?J"*,8?)(+2%UQ<&I21 +M_"(;['H?II]E;4R8NDFNG7(=[?2@+7[-_"`=QX6A/M=.3SF"=BHG(/_?PV7N +M3C'MO`@:%/L/9\_X%R'? +M[L'Y*0``'```0`3^*_M\+('M"V'W5K5_K'BG7.V*]@```!P``$`%D%E4IX.^ +M+#?BS,3]TG"E,MOF]"A$$K=&E%0&``P!```,`0```@```$4``0A-R```0!$` +M`,"H`0'`J`$"`?0!]`#T!]FHB'6H&8F2IG&^@UCOKG9C+B`C"`````$```#L +M(P``T/8&$UK3<^<(-OVI&V/*3&".&M6"&$B,)D?_'HJ1*5BJ=^^\,&BBKFJW +MP]#+'F^X9-^9QB\LP$5P@(1P@52CD\+TR^^M'VA(4EU)VU8^$S1:3FXOT&;` +M3BSBD?1Q2Z[&OS*#5L1&)'RK@UO:/HX:KEEG)(\!ZSH<`J5!M-H)LR=K0`U0 +MH&=4*F>$:,7T'E0!?`"63Q`#^,B(EJ;Q(A6E\:!@<3S(.`+*XZON&$%\##7< +M;UB@&MN6[1P`G&CC!IKG#TL0K[=S;!$:WDV";D02MT;S:P8`O````+P````" +M````10``N$W)``!`$0``P*@!`<"H`0(!]`'T`*0&B:B(=:@9B9*F<;Z#6.^N +M=F,N(",@`````0```)PD``"`:OZ5O%%'L*U^3,N10<%@I$]\;MW&LIU!2M7B +MN()43]QL/N:8.N%`BU=DL6230X=D5-&_35%:KP/!7J_G&^:TSU&K8&,,1;SP +MXJ+;CNYP"5I.`0_;-"K;;0/:Y=[YU)!\W\C,UO/:FW27Q8Z$J5+9@[K[E!JQ +MWAL+N?^M.T02MT8RB@8`'`$``!P!```"````10`!&$W*``!`$0``P*@!`<"H +M`0(!]`'T`00'Z:B(=:@9B9*F<;Z#6.^N=F,N("0(`````@```/PA``#@4\QL +M"T'Q3D_`5\?VHU)*W>A2'R;V?`6$,*D"VQI2[1;3(F,-+K45-RW!+9?5'S?YI]JIQ:;H)UK6QHAP#+?TO-;[@"7I +M.[;=7U@?KKR^RWF,AV%Z3L&P:Z*0K%_!UN3"GQ +M?;]$A\:2//`+<$#5.;R4?'!7D.3IFX-*>N*HUY]6(.$6%>"G8HB:JX(>#0,3 +M+?N,QK-QA8)!&\V8PD*HL0IF)TVN'.!5^S"DT^9,EIOFX(MB:5CT1&QN2@R- +M>B12*5G&%2YCI77`:3#""74YO[W_",<%,T*,]K12X+BP)9PBDI)=+M8NB5:\ +M?CJ1&F%0F^&LCWM\U&-A=N4D]-#Q=7/RKMW.(E'];5V7NO>T +M'G@T(KQ-J_70.K)"#2=].R\HT?`#VIC11!*W1A"[!@!L````;`````(```!% +M``!H36&N!*].1Z=P)@UAXIT8^Q/."3I'EP!H +MVLLT+WF9S#T-6?=ZE$02MT9=U`8`/`$``#P!```"````10`!.$W.``!`$0`` +MP*@!`<"H`0(!]`'T`20'":B(=:@9B9*F<;Z#6.^N=F,N("0(````!````1PA +M``$`Q_+QS$F7LPIA8C(BU+^U-;JC`AF<38P?W/IT6PLIM>=AC_`U:$A$324! +M#EK4('8(D.W@9L@X)ILBV>,-3^P:`2YS&B$,)#^`.V89<-,NF8Z1GU<\5T+2 +M*(E)!2Q:1J#-?$H:*5[>*6Q/V8.;9-Q)1.$:-?0JC.&+1'(`_0/;U8IQ6#LZ +M)\.`%(R`'.%$4O?75K'U6Q"X2EC/J5)@`?_W%7%49%`BY$5@A5%\[MF+>>(. +MTS*7SUK8`H?G@G**C&N'TK0BY^[:''*S/KQ1I;=M[YI9_]&T^7WLB,(J3U1( +MIQKNWR#(?:Y;1,TN>E&=<9I0GX/SLOKV]<8'VF"?1!*W1A7@!@`<`0``'`$` +M``(```!%``$83<\``$`1``#`J`$!P*@!`@'T`?0!!`?IJ(AUJ!F)DJ9QOH-8 +M[ZYV8RX@)`@````%````_"$``.#:YA-*G/\:3CS%FGG@&:D_A&G=3B^JJM'# +MK[HB[-$H_;'HE4QU/X]BKK:JR7,O04L&7L.5::9POFF`R!ZSY$O)/L8^FG5- +M!%;&<#S7&#<>WN]G22@8#YT4PYY2SZ2E%S:.?;+Z"_VT'/5MEP!B,Q`_(F4/ +MW-7_JX08Y`D#Y'2>$FT&Z=PJ&,_5O]H`$^/IZU/GF[XPZM\/3=SONK#`CH<+ +M*=.;)`''6VC\1J!F>"A7RDC51^00K!7*NV'.F8.+G4T1(H=&14-QL,QN +MP&?A3AY<5E*$#/VN#JA,?PIN>9_W^Q,=%78_[O1>@/)'%LWD?2-2?VC@5:?# +MK<L$[MO$`F''>J9)_!&0RS0&P0C0@30%8.Z\Z1!*W +M1G4.!P#L````[`````(```!%``#H3=$``$`1``#`J`$!P*@!`@'T`?0`U`:Y +MJ(AUJ!F)DJ9QOH-8[ZYV8RX@)"`````%````S"$``+#V_($3\TN2ZWU96@2/ +M5]1EDT0:V:89&>61GGWD14^C6(*3?3MTR#JY6?T%/&H2I1L$H.DN`6@W@F6+ +MN:\KO,>DO5X>[RV\W'<5RL;J[/O,!1I&\B8]&X.'O:U^:,;DNAOI>4X6/DA' +M:)E:GTH8[!UNV[=Z-I +MJ$1-Q'I-P)7KTZP['<,W5PO$+)/-;>A.EC.%\9;&%Z& +MWO@]9O3$W<0SYFNOE0I9G$U>E$YL+8^OS+F4M\).+K>I:E@[A=8X`^J9# +MOMA?>M[BXN=;KNR>#?B(5Z9\I?*B])&="R1ZW7^RA175J#,KC9`[I +MC!9HG?411#(HA&TL6X@PZFT4G!J^T1K0HHRC.9,#;I&674BH*HF!1:VIE*]5 +MEX:62`JVRVE^$^9Y:*=TC#,X>&[[=R4.5!&SI^K(3-(A,DO7N1"=FFE$$K=& +M=S8'`!P!```<`0```@```$4``1A-TP``0!$``,"H`0'`J`$"`?0!]`$$!^FH +MB'6H&8F2IG&^@UCOKG9C+B`D"`````<```#\(0``X`+'`_2]V#)&K<9^'*!] +M?GS^(;:]Z48W:`HS*!.XI,I'-!J].IPW)CB6P()2O['J;'ZD1X.Y*L4JRT^_ +M[%/P-50H'&-W90P)((\]=XL1YWM?O9@[X>EFF2,CDN\QI0']ISQA4/S"Z`NK +M'@U)A%O5U1'WR2A>P(-2:'HJR-<-#>PT=DD<0+E\N=I`5@;\7HU&N^&9YMD: +MZ9.W^J!8/L0I:H"!+[?@KHC3O53$HPY>VR=XR6#SX,M;$VGIF?A-Y-QRM=`& +M@%[[?BTNU`,^$?^5>`$M(I0N-YG)."4&H"%$$K=&#D8'`.P```#L`````@`` +M`$4``.A-U```0!$``,"H`0'`J`$"`?0!]`#4!KFHB'6H&8F2IG&^@UCOKG9C +M+B`D(`````8```#,(0``L'XN9B/&;A8=Z60:Q^&VW]SSI?1;OM$COHCS=4T2 +M440$K\!4L\?WB>M2I#*D.#6=WC$5+!&XT@D@/6)WG*!D@CUP4VQ`^$;4/6:4 +MHO$J,7;U<`>C4&R"__KSV[<3N]NU]4"WLYKN/)<45G%00U8)7WJPQ:A#1\`F +MB\XEG*4;2BW76GXZ?N>?.__%C2_`K#9H8BGR,)M=F-'A_G=P3C&>2^J!TOBZ\M#^#]$ +M0DEGD!CL;QN>3:LF*0RI27"0&WI0+,X +MR12SK:&MNW"_%P=&0^WY?F.MY>T']T9T\FQ(TM:I!$1W +M[I\@,(3";H5`68?LBY:3WJZB#.>,*D4;].@TU[S#Q4P3(K7RBZ,'\LXQH`52 +MN7N/P0.BG^XN`$#,W?H0OSJST2">9#PBC>Q74D#'O74,]-;0;)6/9KV*>8,= +M^''V^]D^`EL6O0/>-?_-NKK&57#2-GYB39^.A6#:F\.B%"MU`(M\ZXZ#G;]" +M7:=,2^%\:QO9<(W4$+<^6@M]T)9N,1#?7[HWQG^INP=6]210)S')V +MUP[@NI%RM!=_O.?Z*!<:(VRHXN#!2>8"R<:@H_]?!4*']4M\,4L'S?;21B0= +MTV3'09S`9'0BT(]5$;$^>URW&6%D9N'&EF]UB-:[/][SY(/,+P%8P'!QUM^N]SW,MLW/>E=8Y!=XVLZW'/9S +M/A<6B^_V[R`5UG#`ME=/QRZ7U"@I"99O.4J?G@_.V.)IN_8.D_#R"`](W-3@ +M+_$2FY3VBR:-W9S_0V\XYX^GF&V'YB+1\]H[/">55PZ\)]/#U1\I[P__`:Z) +MO7'2X0JX^NY]>[2UOHJ>X.J;7C1[NO/KWZ\9S_N +M98A1*)EIQ5[<;587&*#'8;";#V?);F'0"G^BDI`CM:W/W3-#;V.D>!0=4;4C +M,T02MT9GY@<`?````'P````"````10``>$W8``!`$0``P*@!`<"H`0(!]`'T +M`&0&21V;Z44=3Y>H9**DM=#A>VHN("4(`````````%PJ``!`:1M(@IML76W9 +M/ZCC/#C=3`#U0TW"*T)1P(=O"]M=NZ/=!B@Y!U6:)R\'['<)N=66HDS8_FFX +M*A]EV_;R1!*W1D#Q!P!L````;`````(```!%``!H3=D``$`1``#`J`$!P*@! +M`@'T`?0`5`8Y'9OI11U/EZADHJ2UT.%[:BX@)2``````````3````#!$I23@ +M.FG-L;@E0<#<"6$G*L'FZ!5B*`<&K[X0A'OE[=$OXA21Q%4.N!P0%$02MT8` +M``@`;````&P````"````10``:$W:``!`$0``P*@!`<"H`0(!]`'T`%0&.1V; +MZ44=3Y>H9**DM=#A>VHN("4(`````0```$PJ```P7O[NGM9!0O6XN$"%'SGM +M-D%;L+=VOMOW[S/1@3S,S$*700"N58X0#&Z[%&Q$$K=&.`T(`&P```!L```` +M`@```$4``&A-W```0!$``,"H`0'`J`$"`?0!]`!4!CD=F^E%'4^7J&2BI+70 +MX7MJ+B`E(`````$```!,````,)G:-DSX^QV`@LUWBM[!_-IW'1\9B?1C-A'! +M!*Z>I!&/0A4ML"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``WGS[ +MUOV]XT6R7?T[,2)59]+;!_91&!H;O5J=X*+8\Z"B2?EST``I^16[;6?7M0&)!4R+^V[15)%+4?<$I```DKE'6[G)I +M49S&T'5ZDI[0X0Q?IZL?`58S+$LT^$A"SP6E$S&L*V0BZ7B<>!"].TND02MT8T&`D` +M7````%P````"````10``6$W>``!`$0``P*@!`<"H`0(!]`'T`$0&*51S&P,7 +MST[@```````````I("(@`````````#P````@``!`!@````%G7*!?)CY_R?:^ +MA,\_A([]_?EO?T02MT86*`D`N`$``+@!```"````10`!M$W?``!`$0``P*@! +M`<"H`0(!]`'T`:`'A51S&P,7ST[@```````````I("((`````````9@A```@ +M``!`!@````%G7*!?)CY_R?:^A,\_A([]_?EO?R(``'@```!T`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``WGS[UOV]XT6R7?T[,2)59]+;!_91&!H; +MO5J=X*+8\Z"B2?EST``I^16[;6?7M +M0&)!4R+^V[15)%+4?<$I```DKE'6[G)I49S&T'5ZDI[0X0Q?IZL?`58S+$LT +M^$A"SP +M6E$S&L*V0BZ7B<>!"].TND02MT;Y2PD`4`$``%`!```"````10`!3$W@``!` +M$0``P*@!`<"H`0(!]`'T`3@''51S&P,7ST[@5%`A&I@X#9(A("(@```````` +M`3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"```` +M"`0```(H``"(``(``"E;6V_=X0;85F#![,3)M;_-F1+6+X&\*8>)'7G;`W>2 +M.M04%]Y0J:Z-GK07`HG^4`OL_LDQ/F1;K4$;J!E_A)"+BT8EK7B]6!,4#<*0`` +M'```0`2F9)@!3*OGYW3C]-Z'D%/P^++J]P```!P``$`%42U]_T^!C.UD'U;P +M3A$V#J5'F'9$$K=&PGD)``P!```,`0```@```$4``0A-X0``0!$``,"H`0'` +MJ`$"`?0!]`#T!]E4-+`H>V(\'"Y--#UO')+$LBSD--8+L55@43[3#AMN +M1F4#L^9M1?B7Y'45D) +M.%)C(I2VLNQ621ZQ1`=O;AU%@8@8_;HAVE<8SE/Q[EP/?2:2^?1Z'M'#R&R83V?[@TJ,%LB%).5:+:?2/W*-T('@^K=O&\6P\O +M=97@25W,VDE59][1[%NIGVO+T??>HM5RR2/ +M?7]O"IVMKVI.O6M]_=U^$1:,H81)*2LGW\=7.,VF,:HPHVADHB;?]-:D@=4C +M27D]L%D.O+$_Z2&5I@I[B]+0&`:&P/_9_Q,$S?TY7;"]?8M7`Z0`/!N0C/0I +ML\O%?WL7A![*._PSP578>;P%N2MC,:1!*W1O7B"0!L````;`````(```!%``!H3>8` +M`$`1``#`J`$!P*@!`@'T`?0`5`8Y5',;`Q?/3N!44"$:F#@-DBX@)"`````# +M````3"D``#`[3T^$2DIWV1"%CR8=X\()?NL',9#DES0`MMA9FOUG;S:2:P0! +M4S"ISEG8T402MT;:_@D`/`$``#P!```"````10`!.$WG``!`$0``P*@!`<"H +M`0(!]`'T`20'"51S&P,7ST[@5%`A&I@X#9(N("0(````!````1PA``$`T*H^ +MYK#!9#QV,`N6#?]=`*ML`F'"R%3B\H+Q67&)YR]5]_MDQ-#?7#&\/*IX#G*M +M'C!7YQ)&%@,5NF:,*[B,(#.G/):/G>M$AGHH\%U^8?#1A!<6)25O3_6U/"<3==#Y;#,4[)0JZT)<@SHIF2;A/[F +M$C'THQI$;TY:5[^;'4?,:EB0IV1%QN$1JP`AV[0S6KL_0'][LM1WQ5(#8L_P +M,!'T[D%-$60`IFII=Y#7CJ&O28RD,CG_FSBO39;L)I<),*:\Y7SC,\0ZPC(S +M)NTS=?$*=FFVZKET>6F1%1!*W1O4*"@`<`0``'`$```(```!% +M``$83>@``$`1``#`J`$!P*@!`@'T`?0!!`?I5',;`Q?/3N!44"$:F#@-DBX@ +M)`@````%````_"$``.`^[E<9U09(\JR]9`ON?;OOJ-C[0Y"+O#P['JN0U/S; +M0'QA!8IX>UT\>UDT%S]V/B5%-A#SG"F9L&Q\I+%N\,+"#$(3UP,6L59)EEIX +MRA_8HWC9Y$(NB,JX0(_E-:-3I>[;J+!YRFZYX;_X\+V&CG\,I+1O]P&,L5>?D5_0VYE)C;,1TBR3 +M,KR8L^I]G)!!VOR!(N_HO524T&+^RN$7(P65_WD,Q71?'.N*=J;*QBAA$[86 +M%CPAD``$`1``#`J`$! +MP*@!`@'T`?0`U`:Y5',;`Q?/3N!44"$:F#@-DBX@)"`````$````S"$``+#8 +MQ'W*^WAK+7.KLP!6.3YD1J,L[83^.@E^]5![^87XX@)F$P]]TRIW'9**NZQ] +M?F#\%/#]!R5IRT'L!20-3]$%=3+_/2ZQ'B6%B/S8!SW0,[$JM@4SF_70\X3` +MOQMV`JN(^,.JE[L\\>1'$3*N:3.O0<)Z3(WRM?5X+@IW2U`!87@T4JC;&?)U +M2/U/0+)VV?\P^WW'Y;1A$."+?]DA?Z3H1HK1@E`=);;ON$131!*W1HX\"@#L +M````[`````(```!%``#H3>H``$`1``#`J`$!P*@!`@'T`?0`U`:Y5',;`Q?/ +M3N!44"$:F#@-DBX@)"`````%````S"$``+!-_%.(@QZYU*VX^/J7%+MY.#3_ +M'X8:%]*C;F)63*C4C)R])=KF +M]\-!4:L^KF'/3+[3D\Y*5]=%S1!`#H.*Q/&T[5E,L\K6FL"6NT;J$9N+?ZCF +MG[D#,JYX\L$7@=R=M%1A?);]"CE\*1]@P+<:!7%16RV[;YF* +M<2_I$&GA*MI']U"5U/L+;@&(1!*W1HQ9"@`\`0``/`$```(```!%``$X3>L` +M`$`1``#`J`$!P*@!`@'T`?0!)`<)5',;`Q?/3N!44"$:F#@-DBX@)`@````& +M```!'"$``0!6EYI/.$-B0B"7*Q-SD$CG`2IY5VG$V^YLU]J&T85X=\`]AB_< +MX?[.@8:80\$NU'/WU>]+B,BB(+\L!;KWUX6@^Y+]KL4!ZP,^Q*.D/=]J&W]6 +M:MJNTR(H-C-"2`WRSW"1IG2N':`N$;Q6^Z8N*H"C@0#$/APZR84<:Z\#A[*Z +M`P\=I"_G]0UGV39>(NXWY\6JFV+,[JZ(3'A4T#`4+A8C8#/Q>-PW&W,+@AO>B_FB4S/J5-WEK>'WI3-DHEJ:1U$$K=&360*`!P! +M```<`0```@```$4``1A-[```0!$``,"H`0'`J`$"`?0!]`$$!^E4DE2=LWVYRD-Q`#B'?TZG[ +MY_2&S1]?<`,BM-^/VP@%;+;S^Z'!ROB=B+;[X];:&"+4_ +MV/HH&@=LT98.(_1XG3^E3+,\_B?U6BE+,]4%:?>^Z<`1[;+1+CI,;EQH/IY5'I6K8[-FQ12F78VR)V#+B +MBW&Y^_A#/)Z:F"`<#N+0AP5";_"%=C-K/^E'N(!:L*^7AQEN;;TZ+/>P_KU& +M0$)"?F'-(G)5N7/9*_6#UX:2T^T)$S.5+1\;NH]KQ:M3:V,G)6JYO)MH/%U] +MXL%$$K=&N)<*`.P```#L`````@```$4``.A-[@``0!$``,"H`0'`J`$"`?0! +M]`#4!KE4TL_PIC(/%62(6:@N#$D!! +M)S-I:-'^XP[9$AL:_8,))7)`@63O]08^8,YXZ!.@L/.04+6VF">/"??^ +MU+2Q`^6:9RHL@34[N/#LJC7\[(W$R8CSBM;=>`S"M..A8)CZPZZ_Y&T!!?^P +ME@BUD;7(%)[IUW@GQW^:16Z*IBG#Z(EHG=/GYS%$$K=&FKT*`(P!``",`0`` +M`@```$4``8A-[P``0!$``,"H`0'`J`$"`?0!]`%T!UE4-H&TI31^/?R@03UT%?C4N_<";VNF)#[6R/&NSAPR4>Q`4WHWQB@F<)ON%2 +MC4&#"DGG?)L]>[&Z`PIY;WT5(3&4R65$`5=DY>GA$T!T?N_!P7]M\S#";D?T +M]]H)H'Z\5#2SSMVLAQCB?Y08!E5_;36[])&7Y&^*]]O;[ +MA-&5'@N'4$U)HP?[P;A%G)T&?FE/5VQCASDM(?NKTT,I.7I3YY$S6/)ODWYS +MJ&R<_F&04`!E0&`$^,^AP_Z1+JKP(I&WQ_BD3PSL8B4;YP#?,8K$3[D=L8"M +MOT"9(Y3NNC`@MDQ>DTYI4%7;A[Q9ZUFG\,#B"$LRGQ5&AY/^1!*W1KSQ"@!< +M`0``7`$```(```!%``%83?```$`1``#`J`$!P*@!`@'T`?0!1`RI%8N]N"]A1>MWH0 +MG7CR#'UD!W`U7ZC^"W3G+5$8%VT/ZNNFXB4XTL477'Z#O0O(,IR4W!\M_&BD +M]^0DSV>Q""(H]2M/L^B=#J8-_V2%I6>E;U*RDI;KQPP78PM5P7CRZ6S-07_# +M3-$$HWI49?'!+Q,OUPJ)<5M`RN5@UD?R]\\^.4<0<`@.9+/A/5Z6WVF=H0$N +M=8HK>7FGE8.]JAXG3#-/PU!S.F?8KD_6:2I0_[1MA*3'&NI,8Y5Y9#+;BRV/ +MT\825A,570UMQJ4LLX(&7W0JU/"<(ZS],=,U>N\:FEW^WCB2KC"*I>UDL:B% +M.&E!)9;$WQ``!`$0``P*@!`<"H`0(!]`'T`&0&28SF +M^@RVP`F[")#FM3GJSZ@N("4(`````````%PJ``!`JRS02/].&S51X.16;.H* +MVS"/_(W+7(3\C'[WCT:(M2D9)D-_F](;K0NV325/E)^KZ +M1!*W1IHC"P!L````;`````(```!%``!H3?(``$`1``#`J`$!P*@!`@'T`?0` +M5`8YC.;Z#+;`";L(D.:U.>K/J"X@)2``````````3````#`G=OGODK/:$:HJ +MT"(PTL/*%FKN*Z['9TGQ`#3B;Z+?G\>4FA0>I,$@]P&?VT02MT97,@L`;``` +M`&P````"````10``:$WS``!`$0``P*@!`<"H`0(!]`'T`%0&.8SF^@RVP`F[ +M")#FM3GJSZ@N("4(`````0```$PJ```P0L!]*:R/W5& +M`/^R\6%9`^'%A^$?=`U;/OWCO9B2@8M$$K=&GS\+`&P```!L`````@```$4` +M`&A-]```0!$``,"H`0'`J`$"`?0!]`!4!CF,YOH,ML`)NPB0YK4YZL^H+B`E +M(`````$```!,````,.`[,[F48`GKB^F5D-I#G=A3PW_F-:4R8^6)L9?7R:=0 +MJ%*.4>3BLM4,>?NU1!*W1L4\#`"8`0``F`$```(```!%``&43?4``$`1``#` +MJ`$!P*@!`@'T`?0!@`=ETB+:][SD:'L``````````"$@(@@````````!>"(` +M`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``T69"RFEU,96- +ML3`*__;4)I3K.U6V0/28.KZ=%`:^QB=-VMFZ,KEO/^2V6?-EH4FSDT.#;VW' +M.$7]4X"9,35"-S;)QG@O5J!8>[HJ_F?_,;'YJN>)F<^6UPJ&Z)PP%C3YG:4I +MS3TI?:.,UY[O@6@52[L4@=W>*WT@,#EMA5)@UH$I```D-&6+%NN%Y;P4=?[O +M'>9W4L74T:.@YM_6$"$:YDQ(!%0I```<``!`!%N*FVF3#B9#"X39^$ZU'7%M +MB,1+````'```0`53?.5._2UKES6-G[[B*QS-"L\Y&A[```` +M```````I("(@`````````#P````@``!`!@````$+TQG"/`^M=<;U;B3CKOP# +MR]@#^D02MT9+6PP`N`$``+@!```"````10`!M$WW``!`$0``P*@!`<"H`0(! +M]`'T`:`'A=(BVO>\Y&A[```````````I("((`````````9@A```@``!`!@`` +M``$+TQG"/`^M=<;U;B3CKOP#R]@#^B(``'@```!T`0$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``T69"RFEU,96-L3`*__;4)I3K.U6V0/28.KZ=%`:^ +MQB=-VMFZ,KEO/^2V6?-EH4FSDT.#;VW'.$7]4X"9,35"-S;)QG@O5J!8>[HJ +M_F?_,;'YJN>)F<^6UPJ&Z)PP%C3YG:4IS3TI?:.,UY[O@6@52[L4@=W>*WT@ +M,#EMA5)@UH$I```D-&6+%NN%Y;P4=?[O'>9W4L74T:.@YM_6$"$:YDQ(!%0I +M```<``!`!%N*FVF3#B9#"X39^$ZU'7%MB,1+````'```0`53?.5._2UKES6- +MG[[B*QS-"L\Y&A[TPO3Q7FH/@4A("(@`````````3`B```P +M````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H +M``"(``(``!O?XWIU;BO)/QXF*E3XG4=3=GN11W'`W]*D>ABZMA2`_'?\F>WJ8YGL&Z#9*0``'```0`2' +M^Z=!4`![6ECMO>D8&H99`I;8YP```!P``$`%S0',#!PC0A#LWZ3D_^0+$K.% +M"45$$K=&=JT,``P!```,`0```@```$4``0A-^0``0!$``,"H`0'`J`$"`?0! +M]`#T!]G2(MKWO.1H>],+T\5YJ#X%+B`C"`````$```#L(P``T&I]7E!!+9+Y +M]7B(@A'[$UL"'("P_RU5Y%44'J4+LS14[6_T4)LSM]$&XS%\1$"@'38<3_L6%:5Y] +M`G`9T=\^#E"V*[#<70'H5T02MT;XQ0P`O````+P````"````10``N$WZ``!` +M$0``P*@!`<"H`0(!]`'T`*0&B=(BVO>\Y&A[TPO3Q7FH/@4N(",@`````0`` +M`)PD``"`')C-QK,$J]O]XWSYF"=S.D\OLNA>O/%3\BA5*"!)3E&"TGZS6H)1F@7(U6@J&1.;%6W2T]'#V?[>@YL5KL(`IT5KN3B +MA&]$'"BQQ93U%L:3K9?,''I,D&`V)08`@8/AWHU?E9OKF0>8,5VN(T02MT:W +MY0P`'`$``!P!```"````10`!&$W[``!`$0``P*@!`<"H`0(!]`'T`00'Z=(B +MVO>\Y&A[TPO3Q7FH/@4N("0(`````@```/PA``#@4!G?1)Y34`<<"+"^G<$G +MO:GNHVEC81^?X%]OU%-KGA]N9ZFZV](9[7_HI7>2^S>8ABQ&/F?SBO<,G+T1 +MJQ*G!V>8%WX.J`8@A9^A-?*@-R"4Q9CJP!&Y('1II3<3%V57TL0>$ +M\Y&A[TPO3Q7FH/@4N +M("0(`````P```-PA``#`TI)_57M:Z'7341JB&^@(*N.0F$(\*V0M"6;MG8VIR]=R6D7E%^PK$_.<,M`'%'9ZM2:CM98RX2_JJTNI.6C"ELAR3K +MDA"W;J,M.)_MV9JSR"ME!0F=XH]#+':#HLCM_II4"]TJ(+,",KAYHSC!8!2= +MZ1NE59T,$.T0M]9VZAY)L)]_.%;%E:G6"Q8:DX;)RJV'P';"ZKF1/V.8\H@? +M2LIPNWTC'O.#0UKS+%"CH*3$5J(_(N1$$K=&=/P,`&P```!L`````@```$4` +M`&A-_0``0!$``,"H`0'`J`$"`?0!]`!4!CG2(MKWO.1H>],+T\5YJ#X%+B`D +M(`````(```!,*0``,/]LMG:P)\`MJ9H[JF\/N8O(@/(MXN%2""CU@IZ\?WM: +M?E6!^B.#HWS:?7/?1!*W1O$7#0!L````;`````(```!%``!H3?X``$`1``#` +MJ`$!P*@!`@'T`?0`5`8YTB+:][SD:'O3"]/%>:@^!2X@)"`````#````3"D` +M`#!04+PYGI488Z?O'M^3+YSD8GN(*BO5?&PMOB)*E8FLSB(/$JX`'37B(\B9 +MWD02MT8>,PT`/`$``#P!```"````10`!.$W_``!`$0``P*@!`<"H`0(!]`'T +M`20'"=(BVO>\Y&A[TPO3Q7FH/@4N("0(````!````1PA``$`9""'&R;"P>&O +MDM(_(M:3LMO'3T`#*)P"\OYUF:"$,.UI[R1CH[H>]0E&0^4ANW/Q8'QZKO`< +M#`4QPL&=,IH4YS72J#2EL@=$WL$\MDA[ZJ*S=/(XV09D3#,I#]S94,"U"!-7 +M;0`S8$]^H*X2=GTDV_7FZ(-_%A`H"@66G4J_$3SM#7,>@WMN9%B"U"IB45M# +M!):+3=!X,E&M_:K)WD+BQ2BT.O&,C*KDP\?-F!$%@-"W8';M:_JOMH)%:I3? +M:L'6"#C$ASUT[M'IT2*R';4$7)(KE$;T4>M4K@N;+IVCJ/5S`F&NJ__N\-,"&1!*W1H(^#0`<`0``'`$```(```!%``$83@`` +M`$`1``#`J`$!P*@!`@'T`?0!!`?ITB+:][SD:'O3"]/%>:@^!2X@)`@````% +M````_"$``.#^MYBRM90'ZJU%P06;4[8FSMB?O_TE'7@X>LEPT!Z$3B2*Q;NC-M +M9T.IKJ^G(+8H@]!*A@`VN).@#L99@HG![C=Z5ZL#9Y-#7/ +M'IXY1!*W1KE.#0#L````[`````(```!%``#H3@$``$`1``#`J`$!P*@!`@'T +M`?0`U`:YTB+:][SD:'O3"]/%>:@^!2X@)"`````$````S"$``+#%7G86BE&= +M!?CR4-40K[B@B$D/>Y#.N1B3/_%* +M'L!75J$NCOC4^`2-MUF"C]2Y@MK^>%JY[$&D4KJ9LH926#`4(N#<`C^2@FU +MC`ZR$SA])CF!\BC_:@^!2X@)"`````%````S"$``+`)9N3CW9>/[*Y!=RP#0^-<]6K+(A.?J_P! +MC$D[APK7M>3Z!]6(.^`@?`0)O1VPFGS=JP +MF35?U)-W-MCW=1!*W1G^/#0`\`0``/`$```(```!%``$X3@,``$`1``#` +MJ`$!P*@!`@'T`?0!)`<)TB+:][SD:'O3"]/%>:@^!2X@)`@````&```!'"$` +M`0"QJ29TI>7174%`&UIAL`N*T%[E4@T`E&U5DRQ]-?'W]=E)K"91SP2*&3$(H%O4 +M1\0%1`/41"1$+D@8"F6R;#"*,14W`,F"^3[C[SR9V(&7+H.5JRX*LBE/O$C5 +M-<-D'SQ_%ZGXK+KOK)D-7Y-@8R]2K6JPJ0KM+RA$$K=&!IL-`!P!```<`0`` +M`@```$4``1A.!```0!$``,"H`0'`J`$"`?0!]`$$!^G2(MKWO.1H>],+T\5Y +MJ#X%+B`D"`````<```#\(0``X#\Y?`H34K#MDF[)^^MI4KZ=Z-/HJ80HM%04 +MJYB=KP")FP"C![&'2A>EE"GI7!7KT5>JEX@+18OA036EYRWC=4/JPG*9=`>V +M":DY-(-UN)*4`(Y\*3^2D5R=#@?F=^,SOZI*A`X;7JN!@R#66+7^" +M#]>*&&GFY'MH??P*737A1;E&YYB`>E#=(V,4R"0 +M,D)SFS#C&2_._!YDON&D39)Z],+T\5YJ#X%+B`D(`````8```#, +M(0``L-!2!)R"/>!GT1JPIC'Q[PE1Q+Q!T!+,E?RO5`;4Y84['B.,$?Q%,HG&9\89=P-? +MYYK->3+S4$G"(N$C8R=0>E.-2>0+J:D5.606[JC\!@YGY>!J(\4`%^BZCW7G +M6'IZ8Y3XORTD59I=;%#!_N#<;\EID!XB9A44_$**9X:UW<.VC7DHF0Q$$K=& +ME\X-`.P```#L`````@```$4``.A."```0!$``,"H`0'`J`$"`?0!]`#4!KG2 +M(MKWO.1H>],+T\5YJ#X%+B`D(`````<```#,(0``L++N/U(18>@<`Q/&Q4#W +M6)NIS>1AN]Z6P5)+',J+A^2D1X`&.=U.ZFS\V!!1,^A&L7_^*X +MFPU()Q,J'D)[,)VOK#!,,^/QYQ1=KY=%=!'Y$$K=&GO0-`(P!``",`0```@```$4` +M`8A."0``0!$``,"H`0'`J`$"`?0!]`%T!UG2(MKWO.1H>],+T\5YJ#X%+B`D +M"`````@```%L(0`!4`PYR,>_*Z5VFMBEONYP7IXX=^%"$S@!]A3Q!5#N>R'[ +M:KUL`HSWR9@7^>>D;AV+]?^PK/SV<,^:.R["VMSH"?T*'IRI9HS1_"!+0W-* +MA)OG_/Y)CW[CD3>%''KN<.A`/9=4`"442C@_SU;-,]`R5,12/1A;6!T +M6[*)O.%-1.[#*12%?&"LAZTK'+;DR7)P;QHYBMH$-O2HVI;>$AF;U%X9E;5[3@M)4Z[^PB]BON%7/R"]% +M0JEO9EJ39DV`GNOVD%CY!V*>BQMJGRI9_. +M8#7UPK@3%\-0J&_&)7S/.\UG9$[_]\A@-J.]Y\D)1!*W1CPJ#@!<`0``7`$` +M``(```!%``%83@H``$`1``#`J`$!P*@!`@'T`?0!1`:@^!2X@)"`````(```!/"$``2"W_,`NY'"2-U`_I!?S!'IWMK\7PZP!C%'QM!I\ +M?_IWDP:3VT[Q'O_-W,&_Z!X4D?,V7L34FAID>Z4(X1=<[402MT8T4@X`?``` +M`'P````"````10``>$X+``!`$0``P*@!`<"H`0(!]`'T`&0&2?76W9IJ;HV= +MBA'-Q:0U.*$N("4(`````````%PJ``!`3IRAK3*4M%PZ[%7AW81CXA%;B%[W +M"5+$"N+A(J_:Z*XD1DXWJ8A3E`&Z&@':@S02JTD-J"LR"J3EB8&11!*W1J9= +M#@!L````;`````(```!%``!H3@P``$`1``#`J`$!P*@!`@'T`?0`5`8Y]=;= +MFFINC9V*$W +M^%H!39>]7QUK0WR0-IR$UG)RK+YLQJ-L;HZ.WD02MT9>;`X`;````&P````" +M````10``:$X-``!`$0``P*@!`<"H`0(!]`'T`%0&.?76W9IJ;HV=BA'-Q:0U +M.*$N("4(`````0```$PJ```P4VK?Y%Y"DFV_;%.S\[-_XGPFS&LN"4:0M1&QZ911*W1IPT``"8`0``F`$```(```!%``&43@\``$`1``#`J`$!P*@! +M`@'T`?0!@`=E43]1BISDM%X``````````"$@(@@````````!>"(``'@```!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``U-=BQ2%E7U'S5N4RH(B^ +M+=0-3+_M&I;:5:K;@CU@WJQ')"AN6Q2-@AST`AL$FSMT*84):F^`&NLU.CA^ +M`H@QG3(%B/R:N0+BY.QTZ1YXG/M"I*:]7*?!$&_DB,,@=XD!-7;@!1@(^KXP +M!#CXAQ@5R^$`I```DDKP/J2O''F><.[)*CI05YR+L +MY#3),VBI]VE#TJ&=7JDI```<``!`!!O5GA2Y```` +M'```0`65*0KIH3'WIOWFPY_>:7/YFHXH$$42MT9L0P``7````%P````"```` +M10``6$X0``!`$0``P*@!`<"H`0(!]`'T`$0&*5$_48J```````````I +M("(@`````````#P````@``!`!@````$:F2,_?E>C1)LM]TY96X"U4A;%+442 +MMT9"5```N`$``+@!```"````10`!M$X1``!`$0``P*@!`<"H`0(!]`'T`:`' +MA5$_48J```````````I("((`````````9@A```@``!`!@````$:F2,_ +M?E>C1)LM]TY96X"U4A;%+2(``'@```!T`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``U-=BQ2%E7U'S5N4RH(B^+=0-3+_M&I;:5:K;@CU@WJQ')"AN +M6Q2-@AST`AL$FSMT*84):F^`&NLU.CA^`H@QG3(%B/R:N0+BY.QTZ1YXG/M" +MI*:]7*?!$&_DB,,@=XD!-7;@!1@(^KXP!#CXAQ@5R +M^$`I```DDKP/J2O''F><.[)*CI05YR+LY#3),VBI]VE#TJ&=7JDI```<``!` +M!!O5GA2Y````'```0`65*0KIH3'WIOWFPY_>:7/Y +MFHXH$$42MT;5=P``4`$``%`!```"````10`!3$X2``!`$0``P*@!`<"H`0(! +M]`'T`3@''5$_48J^M[MF1:N?_`A("(@`````````3`B```P````+`$! +M``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(` +M`#I1MF=>2J!2%3$W$0HV!0B?P+!5EWW2`%W$D%W+BH(U341R`0S:-O`(<6+A +M]95:27TD^#`MGW'+K[ORU\_2RVZ)W+@9>OEUF#7%R44?_"1?<8A*>1P%ED"' +M?R0.4DX[F',:X/4:N<^6*5*9OS?R90%$/D":]&!W3)6U!9T)P!4\*0``),_V +M3KK2N#AS_D">S#$]M[$-0[*\3;=M.)(-E["?$3[1*0``'```0`2,@4%_KIS6 +M">=-(+(6H=^NT:/]00```!P``$`%C5-'[^61SCXURH]OC84!"_2\/FQ%$K=& +MV:0```P!```,`0```@```$4``0A.$P``0!$``,"H`0'`J`$"`?0!]`#T!]E1 +M/U&*G.2T7OK>[9D6KG_P+B`C"`````$```#L(P``T!FOZ+1:!GXHH^]5=B[# +M).EJTY*O.O=T\.D=I0ST1[&]Q&B\)TRF'//%"Y>7JRQNRY/O7)^;D^I&Q!)Q +M/XKI3$]NI"V0"(]WUDBIUP`.6_-=W'*%V!H(U%T(USB:>%=PS>@BYT8`"X%MBP!ET.X7BCX*#DJ35.9>H\ON&PI4Z(/+&U^M[MF1:N?_`N(",@`````0```)PD``"` +MIV+FM=:B&]RQ)JV(QEZ...>M_`K"GO=GZ60I&P:L]"K'%YROUBS&*F,+R%8I +M1#N_R^0Y*$SJS#X'F$UG@A(FU$42MT;?W0``'`$` +M`!P!```"````10`!&$X5``!`$0``P*@!`<"H`0(!]`'T`00'Z5$_48J +M^M[MF1:N?_`N("0(`````@```/PA``#@UT^M[MF1:N?_`N("0(```` +M`P```-PA``#`R\S&AU.FH+/B7^4A&$H^(E8TA'K,6N<8;=70I]5++Z'!C*P$@P]A +M]JLM!GH9"( +M,J92[9D6KG_P+B`D(`````(` +M``!,*0``,-7JN&-'[XT)3)D5#DZS^WTI!?KTRQ%0\&(`9Z)C5`4C1X&B'[XQ +M'6+2X7BK11*W1G$/`0!L````;`````(```!%``!H3A@``$`1``#`J`$!P*@! +M`@'T`?0`5`8Y43]1BISDM%[ZWNV9%JY_\"X@)"`````#````3"D``#"G\I-0 +M>>/F&A_RZGC'-5PH!R%!%HO.3IR'^3MFI71P5AND?_$A[:,(<=%@?$42MT:- +M*P$`/`$``#P!```"````10`!.$X9``!`$0``P*@!`<"H`0(!]`'T`20'"5$_ +M48J^M[MF1:N?_`N("0(````!````1PA``$`<:M_*/>F+65R%EV^,+__ +M4"X&1]]:T(8^4A=OF3_<`N'>=4MFS)`OO,*V>6%8_D!;,+S/NY +MB_KZ8E^2\H7KAS!U\*8_V;\L!HL$<:@\3H(_CQ5\2JC&B^[QT)"Y^_5UC!3@ +M(J:RV;S'0"/NOT17FC8EP3&RS71Z=._Q4<,H94W[..B,`-(N9XF(3?,*R1BY +M)(+JRPIOBZ.B"Z"5IX=:.`Q;PU[6EI'"+J3:H^%6P"#RS/-8U`JR3)(^=&+# +MS';>'/7->O=J`!DEFFY>-#HG'F=^`NU>.VP3.P2MR7E=VMD:8?E]T(1N&F]?!< +M!M)M%EAZ+U'7YX&%8]83UA'7>5&NJ)T6#O+1B]`9V(\2+(G$ +ML!(J/^7U:UQC`^1H:;,O%0/\+BIU"@/$R)\:DR)(<%?,7<(WWO+6&-3M+H,- +ME(#Z:<,(NO?;X86LI>?JI8:\7!BE]CG:^!`M@V-BI4B.2;PX=54=<^IY-"S7 +M#H^MVAE,)/]"%49I@]N41*3PP2PXI*HQV*F+F>76;317[;Z.F@P`KP2+11*W +M1N9&`0#L````[`````(```!%``#H3AL``$`1``#`J`$!P*@!`@'T`?0`U`:Y +M43]1BISDM%[ZWNV9%JY_\"X@)"`````$````S"$``+!@NJ+>U&7'/C+N:6CA +MF:"+[R:;'MG9#ZUC>AF0+%YE6DH/.:.QL7.ZZJD>&`&,!--":Y4W&7:2UOVB-21!;11*W1H1J`0#L````[`````(```!% +M``#H3AT``$`1``#`J`$!P*@!`@'T`?0`U`:Y43]1BISDM%[ZWNV9%JY_\"X@ +M)"`````%````S"$``+"TE%&8QR%FGW9/DI;,!J'^9,%57W>B4D:D_'J.;LI6 +M@H:JP!W?)\2XR:L/DG.(E0OG@E.@UWW.PN'O]A3I7#/-4%%2O+^HU[VD*F?L +MMM"_'ROP55N,_#[`"IXNSQI![SU6(1?;;M#/<86,AOFI(U9T0`D:=J7/C#&# +MUBM+%B1-74?6599.$+$5TALRR+R!Q\>9P1YEPT,+X:QXJ1']ZVI +M61^>"3]^/;PM46&"&M`>KM1O=;N045J"D(%C&Y;4,K_B&[0.J*C#R5=OKD#$ +M[,,!=R8C$OL":,K(0?Q]7S-)`:Y"^T$)N#/G/GR.-S/Y(]O,B3#!G+)-D&8R +M?O%VBG&JC8,V`#/Z:2]3%#I%=.[^D+1USS8G3K2E'@DQR!#?*?LD!9?\M[S> +M9)C\D:,D?JI+3YJYK7KJDON)&[HR.75%$K=&DK,!`.P```#L`````@```$4` +M`.A.10``0!$``,"H`0'`J`$"`?0!]`#4!KE1/U&*G.2T7OK>[9D6KG_P+B`D +M(`````8```#,(0``L"\X$;6$Z]DG:46E$0$Y2M6[RK$,N6(O98ERV!=,==83 +MU@2@N'LGD9&;EFRYZ@K/6>_GJX!_S`P-P3V=5BEP%;415SN:UE#(!B9_M]?OE^ +M;3$OV5FNU?"!4MD*T]A+U@A1\_6^4^Z!SH+SXWATR'W6K<.GAUD]QG5O)X+> +M;^HRD_=%$K=&N;0!`!P!```<`0```@```$4``1A.1@``0!$``,"H`0'`J`$" +M`?0!]`$$!^E1/U&*G.2T7OK>[9D6KG_P+B`D"`````<```#\(0``X&XWBH.` +MC.'PR5S`W^[-ZS=G!R*TICN/([-6%QR?)KUC.[(E'I>R-_!!F +MZ!LP:Q*6PLMOI&+J:]2ASH3QY"X5+M(6OIF^XG'ON(3!K,%4$XRMI`R^D;N=%$K=&8]@!`.P` +M``#L`````@```$4``.A.2```0!$``,"H`0'`J`$"`?0!]`#4!KE1/U&*G.2T +M7OK>[9D6KG_P+B`D(`````<```#,(0``L#X;T!OT-UIAI2'P'7;5YW%+1ON@ +M!9YAJFN1YA/E#[?YBU[7,'-D?\$0LADH<#SC6L74^((#T-@/YS\VT;9PW;4% +M9=%@$>'3.D+;PES9`7HD.')\\:PL/M"[0[$O[)TBX.ZTW

9R[C[/],7A)= +M\%/.C/K0#+R'27@L8CLNMV['GFGY6GW!HZJ>0GVR:E-33F`^G#X$/9W^EFMC +MR3^V[Z8!\4-9?_CTCS?8Q[9D6KG_P+B`D"`````@` +M``%L(0`!4+!-/JT4I6U,5\TG]W])`[[LD"BKIH3LN:SO8H^'^*3MKDSY3E&: +M)JX208V\7B=-#*]9WO]*:^R%6%+)_Z&4,]+0EG/$>W2N2S(CL*?#98\\*<:: +M,FL9;W^8!4;0>ACPKT"*-$]8@CTBT52<`8&&_QH%)%KC9YS!LBV3S2V.^DD@ +M/2BFM,HB:Z>2".$V-;_]?[E.4N>#6'6_N/3_JZ&;RS(<]J>N;2Y:#(52"#3U +MX@XGI76XZ!ZIP]FW58M.!&WS\/O>%Q?LO[C-J[(<1 +MT@7!LKA.*9.2^']V;]=A@Z]AV4=;PV61*<)UL;$Q=@1 +M[G#YGS4=*]1LGEGCWM/0RH`#CW\5C?X0@;+UW?9U;GDSW8/VEQY/+82K+B0= +MVJN'MF(I)>PT]HQH$)[V/;U,B28)4,..11*W1@HT`@!<`0``7`$```(```!% +M``%83DH``$`1``#`J`$!P*@!`@'T`?0!1`%%.;(K,2X'VYC71^8J<@0]N/3GP`#(C0L.1;$7`X+&AZ+@]L\C4[Q+_"Y6UBRU2E2V_FSNR0?>TY"!V(O^X^15?#PT_4U=MLNSYY +M#/T7H>PQ['@$6;Y4&7];MVD7QOR/V%[]PKD.7D42MT;V6@(`?````'P````" +M````10``>$Y+``!`$0``P*@!`<"H`0(!]`'T`&0&20UG.Q.A`'F97S5NN6UA +MZ@@N("4(`````````%PJ``!`"MJFT4U2:(!4M[<$R(QN"DLI)$[%JMNBW?U* +MG+)@G76/D`%L&O-)B77_75O<@1+H.29[;9XJN09:V)3-11*W1KUG`@!L```` +M;`````(```!%``!H3DP``$`1``#`J`$!P*@!`@'T`?0`5`8Y#6<[$Z$`>9E? +M-6ZY;6'J""X@)2``````````3````#`QH+P?D0B2&E8:B^XM`%'SY_);^'2/ +M;/.$0<8Z:-70\`D,X,?T!`F(+90+0T42MT9-=P(`;````&P````"````10`` +M:$Y-``!`$0``P*@!`<"H`0(!]`'T`%0&.0UG.Q.A`'F97S5NN6UAZ@@N("4( +M`````0```$PJ```PLIS-UG>G8#?7DY2+&?]S'TG1K%=N]=:GQKMY2+K#!@-0 +MXU+5_PWQ%:[^A/E%$K=&$H4"`&P```!L`````@```$4``&A.3@``0!$``,"H +M`0'`J`$"`?0!]`!4!CD-9SL3H0!YF5\U;KEM8>H(+B`E(`````$```!,```` +M,)T[AOVVWJ\#0YJB_[F3"%16"H=;P*S:M552K2ZA5:ZO!,/\1DBO0^&.$(\? +M11*W1ON!`P"8`0``F`$```(```!%``&43E,``$`1``#`J`$!P*@!`@'T`?0! +M@`=E6KM!)(B+I8D``````````"$@(@@````````!>"(``'@```!T`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``$UCG_D6)H4E`>+-6'M;O[^C0%(*6 +MIY^,MNX=1/5-Q1L_4_MK.[Q&`8ML=HJ]PNHM.^$WL5/565;>\E7JC`SO=8+F +MW>$=L?:M[!?`37T)IU_X7*4,-,X@8:IQBS$L?FG- +MB9#JO3^X.94[:*_X@!UZ2:0I```DOQQMXM+J`O)2]@0:#'ZAL.'2C$.9Z6O= +MMC\V"4_ZBCLI```<``!`!')?P[&X8FRFFKM7ULO9\I"/6:+D````'```0`48 +ML5%Q<3=":%]!8GKHGW5["&N"GD42MT9HD`,`7````%P````"````10``6$Y4 +M``!`$0``P*@!`<"H`0(!]`'T`$0&*5J[022(BZ6)```````````I("(@```` +M`````#P````@``!`!@````',.1A0KH+-6'M;O[^C0%(*6IY^,MNX=1/5-Q1L_4_MK.[Q&`8ML +M=HJ]PNHM.^$WL5/565;>\E7JC`SO=8+FW>$=L?:M[!?`37T)IU_X7*4,-,X@8:IQBS$L?FG-B9#JO3^X.94[:*_X@!UZ2:0I```D +MOQQMXM+J`O)2]@0:#'ZAL.'2C$.9Z6O=MC\V"4_ZBCLI```<``!`!')?P[&X +M8FRFFKM7ULO9\I"/6:+D````'```0`48L5%Q<3=":%]!8GKHGW5["&N"GD42 +MMT;=Q`,`4`$``%`!```"````10`!3$Y6``!`$0``P*@!`<"H`0(!]`'T`3@' +M'5J[022(BZ6)I1_B\W;9E.PA("(@`````````3`B```P````+`$!``0#```, +M`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``%'S%/>< +MBW5T2#Y)PE!U#/P,E(R^3A$>']&JP`(%,YL.5\$U(BW+H_#]RCQ:TV,^)JG$ +M:M6G7ZE1,PIN^GD]:"A:G:T91M3Y^'NT9'DD(:=IN$R6JBE9)WX*"N5^;+&+ +MV>V[I]]O.-9?J?A-+N)'P%@>!KL,=MJA[*%/]Q6W`W9S*0``)!P:OF=O(L)-KH5E@;X87+]RD2SG1&I.9-4,!L*0``'```0`02[*&9HV1:0?A)X,OY +M9)U_U),_60```!P``$`%C`5%R1(.;;=KTS$PJ0IN1'7>O=%%$K=&J_$#``P! +M```,`0```@```$4``0A.5P``0!$``,"H`0'`J`$"`?0!]`#T!]E:NT$DB(NE +MB:4?XO-VV93L+B`C"`````$```#L(P``T*_2#%Y2_ZYGAIO7H&F&=.OL0V8G +MY+:-W8F +M^+35DD42MT;^"@0`O````+P````"````10``N$Y8``!`$0``P*@!`<"H`0(! +M]`'T`*0&B5J[022(BZ6)I1_B\W;9E.PN(",@`````0```)PD``"`(P=:\.IY +M89^HT,:C%S?X,&E?&^)6@!>\NOT8$&1XI]"C97'"E0G@/?)P^:*=J=K>6)@_ +M=+>+3,4*&2I]&2UZ[J0[$A69O_@F]71H`UQ#(1M8P%[T5>`_M(5ZJ=^0AD%#:S=.3BURT42MT;&*@0`'`$``!P!```" +M````10`!&$Y9``!`$0``P*@!`<"H`0(!]`'T`00'Z5J[022(BZ6)I1_B\W;9 +ME.PN("0(`````@```/PA``#@9_(X`#Q<9A5GA*F?"&6C;/)9U^.=0AU?'_/T +MN,((RB%$IM^F\WWP@8JB[.M'(R9XATH&D+30(T4^@MRJH4Y +MR]5U$CVP3Z(?>'=>8`EO2*[VR/C"0GIF)O`*9RN6>PL1_!U`4M4\PNF442MT8!-@0`_````/P````"````10``^$Y:``!`$0`` +MP*@!`<"H`0(!]`'T`.0&R5J[022(BZ6)I1_B\W;9E.PN("0(`````P```-PA +M``#`KJ-U2&!"NGU[!F/&%:H[J0+KL$3[Y+`1C]Z@3W0G'D%@,RH!G=1(I'A:9/VK!MWC09_] +M^YKWH"W6(=;@9U.3K53CYS&P4()HV$$F7>`^D9V19JLN,*A2[]>QJ;A_NKZ; +MHIE?IUNP@S!"S9,[>M-%Z[+RW&$CP::899)K%'N"!UN^5A&IOP=>HUTD)Z<$ +MUFKV#G8E)SA"R$9%$K=&ST`$`&P```!L`````@```$4``&A.6P``0!$``,"H +M`0'`J`$"`?0!]`!4!CE:NT$DB(NEB:4?XO-VV93L+B`D(`````(```!,*0`` +M,'+AN:5P+;H07>UJ#' +M11*W1DE8!`!L````;`````(```!%``!H3EP``$`1``#`J`$!P*@!`@'T`?0` +M5`8Y6KM!)(B+I8FE'^+S=MF4["X@)"`````#````3"D``#`)%MX#43TP*P4; +MP$OG`^]*Q]*;.@`W@T7%/CW9140Y>\N'L\=."CK)N:9B4^ +MRBXD'8.,BHYU)D3_GV@O0$YTY%%NS$PDJ([U'JO1RR+-R5"TO_<+LL:H'!&. +MV&KCV+TG8^R![85.,U@<(BXP`2>(9^&GI)P_`[O@SF1Q;67-"HR$58:43^&7 +MV5E9GP)3@8^973L0N)*8\>[J&,2>P_XG1W8!-B@%C>WTM^(,O?D8A(``Z>QL +M:Y>A9S>3^+W)+X/]FYTVJ@WE<[Q(9S&E6$R^C@UZ^N2H4G#+ +MZ(?_ACPO7W::!(O.;C+UE^/37(AP%D.,WT6;-@(0(4.,+P-+CYSDI)=_=!PP +MU5*3(:BV11*W1NR"!``<`0``'`$```(```!%``$83EX``$`1``#`J`$!P*@! +M`@'T`?0!!`?I6KM!)(B+I8FE'^+S=MF4["X@)`@````%````_"$``.#5:]NQ +MV"\8G=V(-ESXB3G7=)=$FN^3&G6I(7F?+-EYE,H"$ABI2V,Z"5-(Z_"`O>+' +M&BQ'W6\-9Q%@=J]8R+K)30=^24SP"0..M'"+8J`+(:I,)- +M-FND2%"_#3@]O2!)/-$2>AY#5L0TTP6XNRB=Z$K9'K9B.>#G`D\,=,$)7^OH +M1566R'!EM2WQ@\-%^JJ81VU<(3I^GDDO9\CW\[':8>Z27SA5]"-CZU(Y$\!8 +M\:W+%V)]II6D']K'[^9DT*C$GGM+V2J +M5G]2VUI>$R*BNPS;[DFSFE(Q=_6L=%A3/6<$DZ/:&>B2FJUR(X%LBVP/MF/J +MQ$#@3>>2'\W<`%W2I4$PD(,F,C2*X+G@QS.G\_9R#/"Q+V5;GV#?5DO +M?*LQ?]@5_C7#&@3Q8)'-_4U>11*W1D:U!`#L````[`````(```!%``#H3F`` +M`$`1``#`J`$!P*@!`@'T`?0`U`:Y6KM!)(B+I8FE'^+S=MF4["X@)"`````% +M````S"$``+!N,>@.;&O5J\W+TUU]3P])-=?DN/@=B&E;X1KFMMT_#/PVB +M^E1'`NW#A%217=0U,S8\%XH!,G]S6H+M:ISE3XI1ZMUQ[4PT-2!I@^G-`1S) +MBUZ!][(\+,D;@^#%B"5GWG!#V8NV&]"89'K*\2!-,DY,+;)=0ELBI>8+/-]B +M=/K!X2,G6'4WP??[DCL`42B:&KSQPJ!_AL-V"=DBYNU#$@S9(Q(5@ZN@;AMG>AR!Y\_N%J7F-ND^!3 +M#$00?$R+#'PQ +MV?;Z1>L*D+`4,:JA:WN*?H%%$K=&$]\$`!P!```<`0```@```$4``1A.8@`` +M0!$``,"H`0'`J`$"`?0!]`$$!^E:NT$DB(NEB:4?XO-VV93L+B`D"`````<` +M``#\(0``X.ZARNS"6*YJVM[&&H>[S:C`Z68E^$>3*<\[6.?$\T#1!Z5E.#VE)2HHW]:TXQH!SI)"V,_FESOGWY +MDMEUNO6<4]T>8551+14P\"?AN]3^+NHV[3)&U0U!;'8[OSSW9'XW'(*@*=Y[ +MVVUD)%Z..41UP:OE#(UPOK#=F9I7GE$Y5C:1_N]WM9<&G1=ENA07OOVDFN59 +MD!)%$K=&2NX$`.P```#L`````@```$4``.A.8P``0!$``,"H`0'`J`$"`?0! +M]`#4!KE:NT$DB(NEB:4?XO-VV93L+B`D(`````8```#,(0``L,G&'-J>21X= +M=ID8*9P'&]/NH(RK-&*%[XK)D,%JZ!.[(P@(M;5EBR/QL?R8]#JP'=(; +M%)[`/66"5V\5^1C%,\LJ:"(B><:U<9B)H4_< +M^NZO>2VR1.YAP):7$E0)=K#W\QKF`O4=H4$6!U6S,P&IW0'\:-L3L[@T- +MY%@I,R1XQBQ/39%%$K=&+#T%`(P!``",`0```@```$4``8A.9P``0!$``,"H +M`0'`J`$"`?0!]`%T!UE:NT$DB(NEB:4?XO-VV93L+B`D"`````@```%L(0`! +M4'M[T>9(2#F4V8!3E-UA5T(,F0W/G0AB(CNT`/4A9E.^?ZOOS"R=W"K;A6\; +M\.PK+@G["J/`'=H"$9VL(#=^_,'Y(MUEH[;G:VV'JF; +M7MLQ"TWBR@`$HSZC=#=+!:@1O*]N;.R*2,_!5V11),12JDV:;#UI\R@*-C6% +M)]H(QSJOJJ%TTWU'9M-5\P%%S!OJI'20D5<-5QR_A%Y;=9E1^KJOM.B"A$]H]O-55_3AYYW[G]X+W`5M5&W^`ZU10,;KQGZ,D^$OB[R'Z2@,GY?NGG1[@<])B-_Z%Y +M3\%(Z[YY15A94>>*T].<[@[311*W1E9R!0!<`0``7`$```(```!%``%83F@` +M`$`1``#`J`$!P*@!`@'T`?0!1`@<5('4UGPZJB=1J)W)A&2%3 +M5[=C>X&E*/N!C\67VD.A44=IPHOMNW!9 +MC]0X3VN-D(K`BJ<-\*+@F-^WR[M-%9])N<8UFI%FW+(%Q1@H5IUNC!9D83FX +MK%PQF4$3YU.9]3F@"`0=T>4ZVM'#'TQTUKW0WIE!$3OMR<[DC57+7N*LD&2O +MBT7H0F]WA[_CGVY7$YI``!`$0``P*@!`<"H`0(!]`'T`&0&2?0VTAS6.P1XNLYK\LA)O?@N("4( +M`````````%PJ``!`A]B%?`W`8KCZNPPR_:C5,8$FHS-+K.:_+(2;WX+B`E(`````$```!,````,-=MWMU4 +M`--'_*R7<6[N::AC7[D!**86ZRL#,>U_,`_3IF5+@2^I)C)@*_<=11*W1I;Z +M!@"8`0``F`$```(```!%``&43FX``$`1``#`J`$!P*@!`@'T`?0!@`=E@5*K +MN#D7COX``````````"$@(@@````````!>"(``'@```!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``.--'%60%A]+_ZM-K>O8BR"79(B*3"$O9=,^: +MU?5_1,W5+#Q1O!U]IG+^]'7I0/[917(4B[2=:N*%K,^(&OY*#;#H8$L7/-(4 +ME)B.EP,YI+YZIJ1]I?\CM6:BJ#F+*HKC^'`.:Z)'K4^M7IM)%2J@$U6-EP@! +M>4S'>@'(.);$J7O8BR"79(B*3"$O9=,^:U?5_1,W5+#Q1O!U]IG+^]'7I0/[9 +M17(4B[2=:N*%K,^(&OY*#;#H8$L7/-(4E)B.EP,YI+YZIJ1]I?\CM6:BJ#F+ +M*HKC^'`.:Z)'K4^M7IM)%2J@$U6-EP@!>4S'>@'(.);$J7K$[>&?4)+9 +M>?QI6/G#6A@X$]GI-H++>JRUGXW"\U"/`53Q(U`: +MJFSZ*%).0_B&R_]$8H'?HWT^;_D3&-Q)!Y?OV$B?;%OAJ91PVW-;0:XA*=!AMS,)^%;49YLLQ*0``)'X^B'@F&/3W1F]M+@Q+@'L_$K$-9%D._F:3'2@U +MV>]<+B`C"`````$```#L(P``T"K]O*L'-?/J0?WH&_M)+6;BNY$2]/Q=AXD_ +M=E28$FF!N6&"Y=T,?H[5^RAL6FLJ`;&N5>IR_FONL&UZ+9MC.4E9)Q1[+2#8 +MC5VWX,#`_<[L<_PZ;#XM +MC[:/?](S]37WLO^L\U;J4=`:IO#OYA8D&HA<'8;VY#E_TOOL%,PVG&@SOW-I!3XS +M4\.5T8IH#/!`1OQ?FK*RI*G +MX$@YH2[!/;(HW8@P]T1]K[2JZ`D)LI3QO>?/9*8('&MP?%_DHCJ+;IHB\G!/ +M^9#FD4E/WWW>#Y9'QS1>Y*`M/?OOXY!7=O#I +M_RFG9GSVE442MT8+RP<`_````/P````"````10``^$YU``!`$0``P*@!`<"H +M`0(!]`'T`.0&R8%2J[@Y%X[^9I,=*#79[UPN("0(`````P```-PA``#`Y?_E +MW:[P@MSF>*@`_X#!X3]9%;2)D]_#JJW#@QG,;3_*49'-5 +M[S+7T;U<%=0&Y.Y\BY--DZ5'DQ'AQDSI2&`>BGZBN'OTY]/-VBFT['6(C&LI +MO;A9.,>KWN3D\&MZ$)6Y=_):8S#W'[:6*21]338JC53OWD6$,+=!$"C-CNM^ +M1N$,JLMNGBE``(?S.WE$:<1>7__S=2%_U(NNZ5MSY=6+CAFQ9#$57YJO^)M/ +M+>D;\(9%$K=&`.0'`&P```!L`````@```$4``&A.=@``0!$``,"H`0'`J`$" +M`?0!]`!4!CF!4JNX.1>._F:3'2@UV>]<+B`D(`````(```!,*0``,-//R=CP +ME^&>T-=U/(*.A@2V^>:K!!Z5P3<,$#B)DB>6)+]1^@XX861-3X5511*W1F8` +M"`!L````;`````(```!%``!H3G<``$`1``#`J`$!P*@!`@'T`?0`5`8Y@5*K +MN#D7COYFDQTH-=GO7"X@)"`````#````3"D``#!>@='MEN\+VXN_T?.46C$K +M_]>&8MN+\Q3U\4,4PRJ`@:D0W1FN29C)9[9*\442MT9P&P@`/`$``#P!```" +M````10`!.$YX``!`$0``P*@!`<"H`0(!]`'T`20'"8%2J[@Y%X[^9I,=*#79 +M[UPN("0(````!````1PA``$`Q5J#-%$NB(#/$IQ>OY!PROW?K.VP2&KE)Z7D +MY"F;3GC'*5!Y:I$`'P+QY(QC2)2J9AO1,#E1O:X1ME]7'SOVJZ1^AQDZ-&VB +M?RS^)]6G6NSF_(%GS!&*/)SD*\-=@?P!)8MH="V$'1E!V96EK/SD!(!TRPAP +MCY*1`=I+X2]#"#\;AO583=X>8O@QH<1EV/)%OE2D7Z_QI*(.>=YC`)] +MF*,13]#VTW+6O;2F*=K5[3@N +M11*W1KA%8*GY>1H':3 +M$-WC!4[!+K&,8)Q,U,OD;M\#%I$>@9IS=X5O +M_M0TOIK,]C(`N2I]?%@R"NCU[*R@:\WAI20QKIM>.8=VGTZ,*W?0_?4X#2!S +M4=7P*#;1T=+-OS3IN+;+@:WVRV"-24,GYK,E"MO=11*W1A4W"`#L````[``` +M``(```!%``#H3GP``$`1``#`J`$!P*@!`@'T`?0`U`:Y@5*KN#D7COYFDQTH +M-=GO7"X@)"`````$````S"$``+!NA82+`9>.^N16M,B)JF*0%JOF/GWS,B$B +MM%$SF6#/"[HM<.V]00T478/6D-MLR-&_,Y5(SF9&(*%'1$VMWFO-L]H#@,/? +M-PPGK52_"MIF3Y@IXED47(9`KTN+Y3'$JS?"'<((*+.TA*3WT_B35+SI2V-Z +M'9ST\I(MD,&*&F@4[!X?E3^=[$LE?8`^`2H=H76)7>Q^DE,^;B>P_-_N31IC +MX09YPRR/_K=&)L&]11*W1G)9"`#L````[`````(```!%``#H3GT``$`1``#` +MJ`$!P*@!`@'T`?0`U`:Y@5*KN#D7COYFDQTH-=GO7"X@)"`````%````S"$` +M`+##<1K0KCD&[A#T:2:__4#]E+Z%.C\LKOZ]<<]\)NB2CMC@369(U;K`A4J8 +MS13)%VH6P]/;G"-2*5>UEVDFB**/-'(A]WMPN`NPO%!A0K95F=T>,-Z/-(L. +MNQM9JQY(^Z36S0'?3=23@#:$UBYPW[7JFG"A1=U+QK.A"&:P*1-=K=[0T[]:*511*W1G:% +M"``\`0``/`$```(```!%``$X3GX``$`1``#`J`$!P*@!`@'T`?0!)`<)@5*K +MN#D7COYFDQTH-=GO7"X@)`@````&```!'"$``0!C)-YR_3&-36^AS\Y#ZZ&A +MZ<,-U[%@$D"Z)P!<"#]+7.G'DMR@92,LVF1%K#MB#PY^-@4*TMGK-I*LM\*, +M5\-H-'F5!K%:RSD(>NTN"CVU*/O3X#=N$,2P9!20+92LXUB,J#7""P9>$JD! +M1#)_#B3NX]7=.H;>8-GE7>BWI//QC7G#`"!>_32K8XEPAB2NV.D"1F[.5(.* +MG#>:+*3Q"NZTR,=V.0XB^=:5]V..UI0G>>@+R]HUC&\G-%B@H'!B/5]*#7#$ +MB;+<%$V]2(Q*&Y3OC8S3I%$K=&+9D(`!P!```<`0```@```$4``1A.?P``0!$``,"H +M`0'`J`$"`?0!]`$$!^F!4JNX.1>._F:3'2@UV>]<+B`D"`````<```#\(0`` +MX+Z6TU>V4-$PEB4N#P^X/UPB,UYK*S_YI=S.QQ +M,Z*@3>O`XMEUKY"N%Y&J>\HK;P4/#-2`/491R;VBC=$\F%.]]A-?77/ +MCK>`Y"[-CJY$U=K8HH.9A:Q&5($^",R/PJ#\=T]HAAJRH`IY'DD$ZP$?9([- +MKCIXKQZ&Z[V`KD/TT(\&DJI;-VT]:@_V!#'%>\Z0M96.3Y3^_DCC<#),C]7& +M$7I8KJ6F*)_@)D8-TO]#7*3$M_&;4ZY80L9[-RS#17J82W^9G;$_;Z=%$K=& +MO:`(`.P```#L`````@```$4``.A.@```0!$``,"H`0'`J`$"`?0!]`#4!KF! +M4JNX.1>._F:3'2@UV>]<+B`D(`````8```#,(0``L-NP0]M"01XPB+5F/1WE +M84NF*O")*"Z-TZUTYF?\B7C^:,Q3S#3[Y@`\A;:"/ZL>F$13.V%8`)_3`YBG +M[G#H':+X(9H1K>U3O+9OR1CIW^@BWA1'>&T.1?P5GY215?43S1)_._F:3'2@UV>]<+B`D +M(`````<```#,(0``L!87U4CA:ZFB4B3>8UW9[>^C;B4<]'6.T1.Z^0XJY3_@ +MW%!$TJ3#=RIYSZ6*1).V2Y@#8 +M[P3F3]GBB$O<+!^]-.4YT/WN2Q<2YDP$-02"S'[0_0KR(.Q7:5YQ01HNJE[ +M^(*M8QY%$K=&MO@(`(P!``",`0```@```$4``8A.@@``0!$``,"H`0'`J`$" +M`?0!]`%T!UF!4JNX.1>._F:3'2@UV>]<+B`D"`````@```%L(0`!4*4[39>S +M+@@%3`W!.`7=E0,..PT6V*KYX3^7Q>ZSS7 +M:Y3BKY[3`N;HPUN9^1)QC6*O_V_@)3?#\X5#\*YL9=;C9I/_@[[& +M7DOF)<FW2BO7>\C:_-YX?+Q`!5EQM&,\LO\UWX26$SQNN//XX+9T+W +M&D&6E]RQRG-#@+XR,>;(E&'8/>$NS +MU)O*\8EO'"U]`6JF11*W1B(T"0!<`0``7`$```(```!%``%83H,``$`1``#` +MJ`$!P*@!`@'T`?0!1`>_.7EZ><;GRH!C,ZZKP/PHQJEN>W2K`_X$B(EJ +M9:3\%-?05=GJF'TSL`09P@N*$K/$XH-,&]VXJK'[#&8B^]N^E4==-J_\NNKJ +M>#^="ION9.:\R@C0/VM*08F2V,%K%(XKQ75_)96Y*['9VJ06Y(6@!U*@K6'Y +M@O^8(T";/CVC^@[#TM,/[442MT856PD`?````'P````"````10``>$Z$``!` +M$0``P*@!`<"H`0(!]`'T`&0&24U"XYH9:EB3/I"VJ6B%%=DN("4(```````` +M`%PJ``!`;'N[N#<(_./&A&C\*28;RT*MMUK1`7W.X,_#>8T'001V;(A:L>GG +MRWPYP:?&=VZ;14*"O50]*DX97EG$11*W1DYF"0!L````;`````(```!%``!H +M3H4``$`1``#`J`$!P*@!`@'T`?0`5`8Y34+CFAEJ6),^D+:I:(45V2X@)2`` +M````````3````#`I^!L2R(QK&60Z,OMK_J\:[O$D*Q%NM5C;C'%'%;R!J,+L +MJTC@_CS;M(DSD442MT9M>0D`;````&P````"````10``:$Z&``!`$0``P*@! +M`<"H`0(!]`'T`%0&.4U"XYH9:EB3/I"VJ6B%%=DN("4(`````0```$PJ```P +M-!5P)F9#[4S39@OFL)Z"(MJK!VE_80(5%A<8$M/<'GQW&4!_4TCFNZ1/MR9% +M$K=&/XD)`&P```!L`````@```$4``&A.AP``0!$``,"H`0'`J`$"`?0!]`!4 +M!CE-0N.:&6I8DSZ0MJEHA179+B`E(`````$```!,````,'YP6E#;"8WM[.W6 +M*X"(``'@```!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``_1J1L$VT&2QKY1T]]_VJP2 +M!QN6/+PGLB?5'Q3>(9HWC)DWMDV!2N@RE%,>IP8/8]E,MU@0K[9FS8RQ7$9S +M0QVI%M3IPK)XK_WG21P&XA%%QR=A+`EX]1I#FIB0[59&\T]MR"Y\>E4@2^F8 +MIW%+<$@I```D+)JJN/SJFFP4EX+RPO;\,K&B";F&LO5*NG/)(]#'SC$I```< +M``!`!!Z,E3(/BU=-3F-<+A%%/S%1&>@[````'```0`7TN+ZX>`I[IU*K]Q4G +MS(SRU9,1HD42MT89NPH`7````%P````"````10``6$Z)``!`$0``P*@!`<"H +M`0(!]`'T`$0&*6'"H(MC:S(-```````````I("(@`````````#P````@``!` +M!@````''_T_E")201M">3Y'^K.KM@ZBS`D42MT:OR@H`N`$``+@!```"```` +M10`!M$Z*``!`$0``P*@!`<"H`0(!]`'T`:`'A6'"H(MC:S(-```````````I +M("((`````````9@A```@``!`!@````''_T_E")201M">3Y'^K.KM@ZBS`B(` +M`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``_1J1L$VT&2QK +MY1T]]_VJP2!QN6/+PGLB?5'Q3>(9HWC)DWMDV! +M2N@RE%,>IP8/8]E,MU@0K[9FS8RQ7$9S0QVI%M3IPK)XK_WG21P&XA%%QR=A +M+`EX]1I#FIB0[59&\T]MR"Y\>E4@2^F8IW%+<$@I```D+)JJN/SJFFP4EX+R +MPO;\,K&B";F&LO5*NG/)(]#'SC$I```<``!`!!Z,E3(/BU=-3F-<+A%%/S%1 +M&>@[````'```0`7TN+ZX>`I[IU*K]Q4GS(SRU9,1HD42MT9F[@H`4`$``%`! +M```"````10`!3$Z+``!`$0``P*@!`<"H`0(!]`'T`3@''6'"H(MC:S(-Q465 +MMOQ/)*\X9V.(TO2V.4WR +M8Q[B$*U':8*8WE?>*0``'```0`0*573"H'=K"G#Y6QA<@#:XZ<=N,0```!P` +M`$`%?P`;-N3$$)L_8WQU+CEK;\0?ET'$O +M:WH/,T[B>=@@<4XR@G=AD)G:Q\;47SL*2ZH1NV-]#AMWL<+>A3TO7P1!M\TU +M$4'HY^7[\@2R`J(%;*HE=>O12-<6F +M5#3:F2SS^"7DIR"-F4O&2D42MT:880L`'`$``!P!```"````10`!&$Z.``!` +M$0``P*@!`<"H`0(!]`'T`00'Z6'"H(MC:S(-Q465MOQ/)*DL<-?8<:J<3E8&U][!Y5EBMIS#J%!P!P% +M14Z`+UTR0USZ7E8RW0QC*_Y1?X[+K5Z$!Y,#SP,:FM15/:TM0X;!:[;._@$V +M10IA2HO\:$FP4<&)1UURN/BHSEENJJEQ$A+P\0A1O+I3Z5,G?Z4GID_:Q3!R +M-DV;^OL/)\4%=!Q;EW@J4^PSQ$KH22MWE+6R=+A]SE3-E7 +M1T42MT98;0L`_````/P````"````10``^$Z/``!`$0``P*@!`<"H`0(!]`'T +M`.0&R6'"H(MC:S(-Q465MOQ/)*3W<1''!"Q; +M^LY]@]A`M789MG'K<$;C@Z*AH8?0-4R59?*[$42MT:,O`L`/`$``#P!```"````10`! +M.$Z2``!`$0``P*@!`<"H`0(!]`'T`20'"6'"H(MC:S(-Q465MOQ/)*2IC_XSUN%`RV1UW+8T\: +M4]JPF`!*O1AMH'X51@W60)Z1J\,R+=#*$BNQW`D?$">YLSW$M+_:-VN7?_[Y +M:79R:XXMM&_^Z"I3VOH<>XT7?=`N88P'D0D"DXY^9HHR` +M6HPW??&%O7",LZZ7W_$!X_E:SVLBWZVXX;P^U&<]MW1<>-['6&&YXA8WPSC- +M>(V9=4Z[UMC?0NN=W;EC6Y_'.QJ#VBMZ2M?OJ_6S-ZQUL!E7M[5^ES",?>6L +M`)GY,JO)(5BW#E2MNZN56T1-)OC`+]9`6=\FI-(#_T/=9>4?QM.J11*W1F[( +M"P`<`0``'`$```(```!%``$83I,``$`1``#`J`$!P*@!`@'T`?0!!`?I8<*@ +MBV-K,@W%196V_$\DIRX@)`@````%````_"$``.`:Z'HRIZ5?0Z*W]U^Y7*O5 +MI1_7Z*"9)_4KV.;L?'QR\R8+$NO%ADU0 +M?8P0&!H.L/WT +M-[RDF/B7C9+[^MH\[6L9^)Z!4F8A^:+PSNI^7#O_Y2_?4I(E?SJ'LM7-;/8^ +MLXM;BF`[K=Z#CUKTHL8E78WK%__N5?>/11*W1JKF"P#L````[`````(```!% +M``#H3I0``$`1``#`J`$!P*@!`@'T`?0`U`:Y8<*@BV-K,@W%196V_$\DIRX@ +M)"`````$````S"$``+#>U1!(5+NG5D]5T6:2Z#1.^])U%4&W@@=E#<,+CJ!9 +M>_")MC2(01C1[/-WPO9H&#.5XZQ:_VKH4#/4%OM:R91E=S?E6Q=X?%SBUF!9 +M:RX)2X?\YY!/K_Y;3D>]F16+[?G/<0/+(,]H^Q3R@MRHMC9XQ0=]JP`?ZW +MR@/OHF)?CXT=W7\T7BMH9>L0.*T9N+(6)>O'?59P\/DU`BB +M3ZH+0Y;N6MFDXF_1ZKP7P5\O-DY$`%-QHO.[8[J`AJ2_N$C&,US2;X#HE+;B +MT>?+"&Y7TN_N%+5)2CC9LF:O<8SZ^[=-OW&DX_SP[8J\)#3>^SUXVQ^(6VG% +M1C5)HML(5=&-SZ$H2SX/YN=JY@UZA#_6Z/.RYG>A?O\511*W1JTQ#``\`0`` +M/`$```(```!%``$X3I8``$`1``#`J`$!P*@!`@'T`?0!)`<)8<*@BV-K,@W% +M196V_$\DIRX@)`@````&```!'"$``0!.^Y@"7?`9[Y6V$!;Z7?O_C,XD`Q"T +M,HD81,C"9W&7=9BI1;W(->'B+?=5XQC%\!4?Y$N7,4&^ +M-,&8VQQN:XPD!!0*B:@MZH`I4P7&V^[86V5D[A(M#\)A:2!W085_W.84*\BJ +MG0=Q/MR$R@E#S>\!B,>!5DU7'>*W9UVW!317^.$^?`N%>+\DYMX0:Y#ZYN-Y +MS#)0^>5OOHGCN]V+_\4)/A3%]RY$^DIY^`8`4JC>VSZ/Q3/%I47:^4D@=$;W +M-6]Z!6\*V81]62VI"#JQG^HFYCL]ZMI(][4%#/)9=3]HG^7'()?F$5U=6\$) +MUA$:@SQ%$K=&]4P,`!P!```<`0```@```$4``1A.EP``0!$``,"H`0'`J`$" +M`?0!]`$$!^EAPJ"+8VLR#<5%E;;\3R2G+B`D"`````<```#\(0``X$LI&QLK +MX<*J\W\FX`7O3QA$7>5,^T=YE#?>;R%^(W:MB1 +MW5CZUU94`Y56IIE=Q!)N"[52%-Y(`-N2J$4S?&#)(G?&M=VK_.Q2J"*MW.[JS>_L?#J(+/,FOV/ +MU`'?_S+VD]Y2/)JH7*!YEE;0:1L')">QS']\XW!YI1Y6KL$PY0_GM0T\V8QP\FXH?7QU&;FAJK><850:.H,P!\H9`X\I0NJX +M90SCWZ[!"I9+&IM:I*(D@<1D!B%_OIJ\5%! +MZ)0)R/>Z0F5&QSHWKOF!K6?T:&[JL*&.!R]R4/9JP.]HMDF".AZW[[ZH,4_P +MW&>,^2^+OU;Y:,)EB;LN?>Q-'L\S<'"=+R8U8V^#PNDS<2Y1Y.;%2K1%Q2PN +M59-6H?P/`EL3).'^!JPFD_D/VN6MACFVANO/>4LY%RX.M30;L#&Y% +M$K=&,+T,`(P!``",`0```@```$4``8A.F@``0!$``,"H`0'`J`$"`?0!]`%T +M!UEAPJ"+8VLR#<5%E;;\3R2G+B`D"`````@```%L(0`!4!#.(%7\D#F=57@D +M`>#N5%_I*'E%O+6/J&99G,-E34L&ZD;6:`?0O?N(A+"1=9+=^QMQI5BHYIOC,3/S%_<QN?^[!GT&!@^*OM)XJ\4\W)&$+"-T::L48H" +M#EO3TO*EY<`TAA?_?6=R0!`VZ,]B@1^/S:J^R5DVY*(/ZTC')%DP8<@'?G +M99=>\GM]11*W1O3P#`!<`0``7`$```(```!%``%83IL``$`1``#`J`$!P*@! +M`@'T`?0!1`)-.$>Q'*GNND$(\T<:3T8\=,NYTP"UV([XN4P[Y +MKV$^BYZ-P@7%/,?L[&A,.O;D%.B!L_QQ4W+?16MW.`WKH*D(4U2S9+B3*V0R +M/6TRFDNUTA`RSLY8`/[##>&["L`Q`16'(\7[%93A,JJZ)ZJ#&]^+_&J>:-^_^;#_L=K*M_#$J[4#6*]G#'T($5RKW +M.,-!#F.$C2JEZU[!8?9UR97JA?4.+IY0.BA4QI<&1^KD,VCAJ$^[#\\$:=)> +M02R]==``U&WQ^#1KZO;\L>X')CS3BDXKYEMRIJ-_A\-W,\\'6XF_F/O$`ZP- +MD?*4@?<;M+O-9$42MT:M%PT`?````'P````"````10``>$Z<``!`$0``P*@! +M`<"H`0(!]`'T`&0&2=BG@+1^#%^>O3$/2=TE**8N("4(`````````%PJ``!` +M._KCVBZ;/>!^WT2%07K$//FC;G].98-V6K*48')FL0,)SR-BK9;$0;*H:OQ+ +MJ);Y"LOBWTQC;0#A8QU+11*W1F,Q#0!L````;`````(```!%``!H3IT``$`1 +M``#`J`$!P*@!`@'T`?0`5`8YV*>`M'X,7YZ],0])W24HIBX@)2`````````` +M3````#"_@FC^)HJD'1++;(QD-/JOY=24.FY3^6CLK^]F9``!`$0``P*@!`<"H`0(! +M]`'T`%0&.=BG@+1^#%^>O3$/2=TE**8N("4(`````0```$PJ```P9W$;2(\0 +MV-X]/GM_2X:WO+_Z9!&M@$L=!`I%R?O!Y%BS=5E/240"T"LD%GY%$K=&3TT- +M`&P```!L`````@```$4``&A.GP``0!$``,"H`0'`J`$"`?0!]`!4!CG8IX"T +M?@Q?GKTQ#TG=)2BF+B`E(`````$```!,````,&AK$8^I3.7B4ML`[XW)A2AH +MM)FI\P]\%PS,$TJL+YT"YWN[7C9)R6\>V!I^11*W1MR.#@"8`0``F`$```(` +M``!%``&43J```$`1``#`J`$!P*@!`@'T`?0!@`=EE/ET7-YG?&,````````` +M`"$@(@@````````!>"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``AWQ#U%>8,DJM2+@.!Y?."!YKO%MH\\@S5JK)\&O*7<,8$9Q>87LE +M;:GB+IF&99KC)&Q1<"8,E4^P_`I```<``!`!`JN +MMQ#F?6A7>?1(SZ:VQY%==X9U````'```0`6FU9@-[%O#./]=`"N5C*_\X-4@ +M<$42MT;AG0X`7````%P````"````10``6$ZA``!`$0``P*@!`<"H`0(!]`'T +M`$0&*93Y=%S>9WQC```````````I("(@`````````#P````@``!`!@````%C +M=5/?NC\5>*^K+?;8Z^'#PO@'W$42MT;[MPX`N`$``+@!```"````10`!M$ZB +M``!`$0``P*@!`<"H`0(!]`'T`:`'A93Y=%S>9WQC```````````I("((```` +M`````9@A```@``!`!@````%C=5/?NC\5>*^K+?;8Z^'#PO@'W"(``'@```!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``AWQ#U%>8,DJM2+@.!Y?. +M"!YKO%MH\\@S5JK)\&O*7<,8$9Q>87LE;:GB+IF +M&99KC)&Q1<"8,E4^P_`I```<``!`!`JNMQ#F?6A7>?1(SZ:VQY%==X9U```` +M'```0`6FU9@-[%O#./]=`"N5C*_\X-4@<$42MT8]XPX`4`$``%`!```"```` +M10`!3$ZC``!`$0``P*@!`<"H`0(!]`'T`3@''93Y=%S>9WQC?=$%6LG^0R`A +M("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,` +M``@#```"````"`0```(H``"(``(``!]2$KS$I\I=!N_(W"/)@?&G@W4G1;;W +MWL()("^VSZ;F,#Y-NQ>K3KEUGU&^Q7?1/P"`'_Q!O94?6:D@#8[TYRRC@ML% +M^Q3N+YZ8WK1^IY(L@?QV7(F3+=%K3;!3R-1A`+;>>&IS6CAN?H@,]`P>>3+\ +M;'LTK]LIS-S,I^^$UY^U*0``)`H"],E;$/590HQ?T1&GO).S05_IX4K=)\=? +MK_VZ$KCE*0``'```0`2HYO+>TYJ3Z-ZR%@2$IP`0FS0W@````!P``$`%H8;< +MQLZ*DIB#M%\!S8H>89Y)P+M%$K=&(1`/``P!```,`0```@```$4``0A.I``` +M0!$``,"H`0'`J`$"`?0!]`#T!]F4^71M7X)V"TR5(3OCV_JTW#@O69NG,AJR-NO57Q)7DIV&D5ZZ0(^`._& +M_N1%*7#!UB6)ZCM&P1.R2FQ5V/7(3_6>&\LZ[C2D4%#/!UH]PR+^ZPE54$EX +M=TA_]J^^.P`7E[+_7LJ>I7W&YE$/*.V,^-0P:#Y4:ZL.2CNR^90/EX,Z#6_Z +M+FS2L<.TB?(RBWB:O3+!3Z'Q\81IIB@GP/?WSMT43442MT;W*`\`O````+P` +M```"````10``N$ZE``!`$0``P*@!`<"H`0(!]`'T`*0&B93Y=%S>9WQC?=$% +M6LG^0R`N(",@`````0```)PD``"`RB^B4/K>3N;;7= +MZ`DB8(SUH/MF;R2R+(O0A!PA5HFV"5!4')>:+NVVF'FC>Z@2O]0E&B0U[HW: +M;C#HB"=7_I*/XO;>=(@B5X7V&2=KQA0SA]MZXN=S&;OJ"^0\H-OSL(YV:$SX +M'9WQC?=$%6LG^0R`N("0(`````@```/PA``#@ +M5NDJ"[*[RFU_]*_<3;4:=`,H>Y6D9^*#C3T#GPE)=Z2?7&M/-/T64Z98\;W% +M2B4N3C&.H]O=M._8DR4KL!L7.]V;/TK56#"TY5`8'N#D@3Q:0R.HGK?WBIE` +MI@'>NGFPJ1!82,X,SUA4:^"WBN@7WF3S?M:O$K@S.^(=Z7;EV`0VPPWR'=JG +MR@LX))/U)HL><;T_CP=B`"NV6X?(;V2_%#,^I;X9.)6$4IP#B4K54073^%`` +MCC."XNI'#!A:/LTJ2*>_E4&UZ%ZX&SMU<$\M@9WQC?=$%6LG^0R`N("0(`````P```-PA``#`,I.*.D7`:?J-*%4WY8.# +M$2]F"@[)TG==(:)7-L(Z<%'/N)G +M>U4ADGE,D-9SCSQ7^F[;]]&5^-`C'`N[1)GQ2F;'0P!Q]NJIE,J_I:SP!NF) +M:'&$[":-^1,\.\G)$E&&:[!XR%,,NPC0>4R_U+KVT*''=S2B$$*>1MQD_1CJ +M^=>OD-0];#_`ZH$?_]V*4JPB_Q29:`;'>A!_@)+^FUJ:@[.$SBE&$K=&\QP` +M`&P```!L`````@```$4``&A.J```0!$``,"H`0'`J`$"`?0!]`!4!CF4^71< +MWF=\8WW1!5K)_D,@+B`D(`````(```!,*0``,(N<"G].U(9X'H*1B?&AH_@E +M\\-SFY9X5=W8E5`$Z^NP2/\Y815N[)UK,.9T1A*W1E!4``!L````;`````(` +M``!%``!H3JD``$`1``#`J`$!P*@!`@'T`?0`5`8YE/ET7-YG?&-]T05:R?Y# +M("X@)"`````#````3"D``##UN`RUYX;R(7D,6%9PRSK=>\PZI0/^'.(S[A0[ +MQ8C/3.@=ZJIDM/]5I#7(MT82MT9B;P``/`$``#P!```"````10`!.$ZJ``!` +M$0``P*@!`<"H`0(!]`'T`20'"93Y=%S>9WQC?=$%6LG^0R`N("0(````!``` +M`1PA``$`>C#!PHW/@(Z2FEX,T"$9B#L&2CH]5^N+^#;MC3,J,LIC9;9MGV&_ +M^X)L*N492&AQ>]KQ;<&G:,N+OF([3(:Q<'/(Z6JAX,-'.VWT3[@T8!194C0L +MM+>,,H#$C:A;=(!1IFLLZLVZY37V$B1X&ULT:[\/PK.4_P0X&U`Y#1\O5494-\+3:+;1JU^DF"C-[2`9'33M).2A@MQ$U.*(D +M$>6&!^]0 +M:6;<^D[I><.^P_*C(V\.&6>6.%R_,)AO<\;N?G`D%W+61A*W1@-[```<`0`` +M'`$```(```!%``$83JL``$`1``#`J`$!P*@!`@'T`?0!!`?IE/ET7-YG?&-] +MT05:R?Y#("X@)`@````%````_"$``.!`0,JE)3@/)-PA9(D[W6)`%"TK`K9@ +M(BP5>/%*FG4,Z5*_')"GI5DH-US\;?<1_..KGJ$>;Q;N&KY8Y'/GW3?^9RH` +M@0WW[([)OJ2CR\89!@.TE1N"4*)E)1W0\]>/^3<*@*H=N:CX=JM*ME](+5XP +MNW@$+;)O\E4:W-=4\T7K)"P1JM#+/LV8-J3SNFRB>GHSEMMO5_?E8G+)HI#` +M@D_"XN8WR/K-^I60?B7N7LS=T#">Q/"'I-FT1SHKL,`<@VF6S'[NK`5]GM1EJQUOUFY1A*W1A*9``#L````[`````(```!%``#H3JP` +M`$`1``#`J`$!P*@!`@'T`?0`U`:YE/ET7-YG?&-]T05:R?Y#("X@)"`````$ +M````S"$``+"5+16<(;M"X^L)PR;4A/BR,\65ZR3(5II.]1C^U@TF+W4"UO2$ +ME#_K,KN+:T>_E469@D3Z8^_0EI"<+L8B<,F)"KY7>H%9)'WWUB/]/12_V%_[ +M+QYZ>0:I).>+IX[JJNZ%+W:!.RZ+2/A)^H[R8N8Z]&NX`G3A("G9PS<9<:N0 +M`@(7M.[[A1/*@TX(+!J,8K?"Q3!R=JO1X'T^&9&F!V'IHP&A>NS-N61KU3PT +M1A*W1F*[``#L````[`````(```!%``#H3JT``$`1``#`J`$!P*@!`@'T`?0` +MU`:YE/ET7-YG?&-]T05:R?Y#("X@)"`````%````S"$``+"1T^VQ^);*#M%, +M50K6?AC!\9JT2E:S<,`KA89%K)U4OG@8M!Y3'^UO].\M:;@]UA**/K*`4./.36M8'-K)6;^%KWBP$-OO/I-%?#`CAU +M1\@?A<)#V=(1GXBV_V"M,64D*L@["@F3J@D+1A*W1G[8```\`0``/`$```(` +M``!%``$X3JX``$`1``#`J`$!P*@!`@'T`?0!)`<)E/ET7-YG?&-]T05:R?Y# +M("X@)`@````&```!'"$``0#$M^(]GA9VI+?%3&04QD#7S$0\@>Q5O406BN0= +MA8@9*@(%"/*VVLJ*R![?U!G,VA+I170%7]_\51RN'MO%U0A,-*]@\XQF?F7\ +MD=AR!$"E"+_7'(;86VP"&!LPZ\&^J:6O2X'.`8O*1_&KW$]E5?S:(RC68'D\ +M(HR8[CZV&S15HMGXUA1?QC:7`YM$8XS_656!;!30/P2T>SL(RJOK/PVGO:U> +MD(JH%BIL6;CFWOQ*W7SQ$`AD.?OL6#R-P6R.;6=77WH]RG2?%OVJ&%;:OWNC +M3,TV@.6N!57_OM$>YXW]B0:SMDKIB`^D*D&8>XV +M`$U80$D9^&$R#A&&@,3R%47]1:8UUDJ(W?L@0R^%>57=/J%F_H:*=B.R`<[^ +MF(RJ@8WE(C3E!*\)"I2>#5HJ/'?_TV94$O8EV9/%^!>.9:B#&TBH[7R&H69\ +M&T+M;UO[`J^G^SAW&"B31V$$R$5\KI2*RP^7(H9&$K=&S?,``.P```#L```` +M`@```$4``.A.L```0!$``,"H`0'`J`$"`?0!]`#4!KF4^71TUS-:%3R31*7B,GK\D>*MN<^%E:S$1 +M+Q<)%XEXV;DY9$\T7W,+_0K/Q]W,HHGBDRH/&QI<+]@U=8R?2?4[L'+)=3:W +MTN)#M2T2%TKE6,4K^R+HQLZOXN3WI`[X\&/<>V\R1#6Q*(7_8%"T?WI3A1)S +MRSMSJK0YW-'R>#U&$K=&="0!`.P```#L`````@```$4``.A.L0``0!$``,"H +M`0'`J`$"`?0!]`#4!KF4^71NOA=B.U9B%H,?29KEKAYCS3W$G'U09$\D97_*M.S +M0TE[1EJF<`<#<=`EX)N5#(M+OW%:(@C&2/@'472&<!+_]HAT#"F=#[-/:9TIE1(U&$K=&XE0! +M`(P!``",`0```@```$4``8A.L@``0!$``,"H`0'`J`$"`?0!]`%T!UF4^71< +MWF=\8WW1!5K)_D,@+B`D"`````@```%L(0`!4+LIA`8X6C#Y#];+Z[.2/US# +MA@T"H4#M-:Z+T9\%'O[F4?\/R&=(M.WP\/QAY9C*#SJ0F=6I1,_"M+6F/661T#C;A%';"*+4LN +M*>4\"KX%HF2)@I_8;HFM7<<&SN1RC/?A=?]ZXSD@VZO-HH*A[`A86KJR''I4 +M1A*W1CV)`0!<`0``7`$```(```!%``%83K,``$`1``#`J`$!P*@!`@'T`?0! +M1`0$A.AWLH0 +M@I5$._#I7GRNON(4XA#A,=AR^X*]7^"!U/#Y+*5'DTE9X!<`ZCO[3;75E.&9 +M6?D@I,92V+09-I=:D[W$!'(I-`Z4\]).]0'^Z&X@SMS">H\,S7KK]BZ_WUNN +MF6(X7W[;XW%!3X%R/A2D40">`R98S.I)W.'GWI%,>JZ)(:-SJ@(@AZG%?O+\ +MB`;)DC[&QW/:FM)$DP>[^WMC21@OGU6K?2%T4F*]5:PI\WA.&+33D,$DU.[, +M?;L/-W(,>8,1L16B.8D-V)$,X@9OQ]-CP.\ZM^H%'#Q.\\Y6Q_V3Y4OMX1-W +MA'4O6)$<(F54,C69F*[F#_Z$!)F!#]273BPP9Z2[<&;_-44?2""/4]'D" +M7;N![$82MT9FO@$`?````'P````"````10``>$ZT``!`$0``P*@!`<"H`0(! +M]`'T`&0&2;@`:4^AT"/!JHOP@>W(IQ(N("4(`````````%PJ``!`O"0::_U; +MVSF=B4#1"4$'S:.[])I6@X#J_6Q1%'=FJ#7.%>=(T3"&%XE"ZXQ1FL2K_BQP\%1A*W1C+*`0!L````;`````(```!%``!H3K4``$`1``#`J`$! +MP*@!`@'T`?0`5`8YN`!I3Z'0(\&JB_"![BI)-482 +MMT;%V`$`;````&P````"````10``:$ZV``!`$0``P*@!`<"H`0(!]`'T`%0& +M.;@`:4^AT"/!JHOP@>W(IQ(N("4(`````0```$PJ```P9'V_'"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M!B0D05M*N']&2IT4;,H`C-_8F$J;[N'U/5C#;N2C3@T6M>^0$\(ZR0OV8E," +MG945<*CAT!=9%MM%K).[0DM-C@VS!1BG7H[/C"^C.K*2ZY]P5Z[4LX=SY4^;Q(`VUL;DE;=<=F71[RWTU,R@4-%]!,F(/%`I```D-Y]C +M=Y$"]81!4LH&?Z0<%/<:/H%*WGXRP*$PEZ+]R^0$\(ZR0OV8E,"G945<*CAT!=9%MM%K).[0DM-C@VS +M!1BG7H[/C"^C.K*2ZY]P5Z[4LX=SY4^;Q(`VUL;DE;=< +M=F71[RWTU,R@4-%]!,F(/%`I```D-Y]C=Y$"]81!4LH&?Z0<%/<:/H%*WGXR +MP*$PEZ+]RI689_M]NXQO)/C6;P50TEI +M3V`G]!.#06=.MYNNF8H]'-*G;W+\YZ9'D/-*T;E$?>FU5^WR'^QB&,PIZ?7C +MT:X+`"'\%@`"E0\N6-/?5$+@7]>7=.;Z3I1$INX;8`("?R%6NNVUCYB8'JW:-9/OO):%LF#*\30 +MQS%_9&IX:(CK.4'DKHB-K&TQ+H+EQ0\-X+K%4I(L>SWRPXAG#;FEK',N?587 +MO?/Q-=ID@YWP,]J`1):(J!A?N4S['1&84ED#./`I;G_]=,0K/XX9;A6,`XOAFST#9(<1H2SP;>$J&*Y1*F?81T<*:*]@0Q,]"]9C#UL'`+<\4Q7&,"XR(E0N@QRAV+XZ[0]N?MV/X1[_`+H!QX[< +MEU$A.R:ES$`-:FN+7`6O3/*(#R$6\!S@`#1[I6IF=H7[2--W\!`_`$-W +M_TR0#[+SOZ]V"T),OW3>G(\$[?1UA70Z\27X^M.\-DQ7.2EQ_>8D7/53(W.C +MY*;@_#A:@LT(6.M9>`?Q3ST2E/F?[S\D,E7N6BJG4 +MR*\]QY`N446K.21GLS%A,9M#,YOSR_T!J#6)TO\^-.`8,R4^2LOBJQH575_Q +M7%;MQC57Y55JA/0PX)JIZF93'`<_Y'\L%-687^(-)]"EY=V`BQ,LGM><5'E' +MK+UT.*TR2FA2&FH4+&=`TLY'!+/_";*/K2],J_4X72I&$K=&!:$#`&P```!L +M`````@```$4``&A.P```0!$``,"H`0'`J`$"`?0!]`!4!CD+LMM-A)FMJ#$, +MAY\XAZ-Y+B`D(`````(```!,*0``,'?8A>V)IM:;J69-B/-3#0QVOJRT4X*2 +M`Q"$K<$)T-_(N#2YC>&=TU)S`H$Y1A*W1D/``P!L````;`````(```!%``!H +M3L8``$`1``#`J`$!P*@!`@'T`?0`5`8Y"[+;3829K:@Q#(>?.(>C>2X@)"`` +M```#````3"D``#";,5QPE8Z%C37NJ!F,-=I`]H=;E%3389.K1!_9>)[>"V%* +M6GP[,Z!@P.J[Y$82MT:LY`,`/`$``#P!```"````10`!.$[H``!`$0``P*@! +M`<"H`0(!]`'T`20'"0NRVTV$F:VH,0R'GSB'HWDN("0(````!````1PA``$` +M28+@3L9G%/JYE%$OWB9AGV51^IVAS]VT=::4>2)9$OB0SH7+I,@BX[$B1K-F +MGT]4WX7>K_KIJ!T65S,=YKN50JZ9D3ZWG'>6RW0,B^XGM%3I+KG:GMBS\J5* +MPJ0D(IG4N.J61E65:E[_#T"10ZCNNP#AL'4EQ"`6B@#8)=ZF5E55R=7 +MD4<>^P0A69E`+Q%TEH"B''85=QJ&QB4%7DFH]1ORVIVR_`F1">-Z@Q:VFHBD +MK^,]`M-4W*KLG/VS93:5;WR04S934[B7C)DR#OLV&%W!ZWGB3](W*Z?Q&BG0 +MBA;VA05_GW=DM8$[@9`M*(6GH],YX2WWD,'61A*W1L+R`P`<`0``'`$```(` +M``!%``$83ND``$`1``#`J`$!P*@!`@'T`?0!!`?I"[+;3829K:@Q#(>?.(>C +M>2X@)`@````%````_"$``.!5NM$IR9=+?HB=@>'3V1>L>`KWUQ1TM0R#SNM_ +M3>H<2&GA/7PJ\XI!8P0_L^XM?$T,C"VO18`96\SC6M9[_>]]A$GG8NE)TOC] +M<`7G3JPT>_\='H272S'0<+MB7QX:\SSWZV-?>G^P+IIF9>W%E=02$HNQKE/\ +M(6@'>"Q.R:F':^Z'Z+2'P`D.Y*%?5OPN>\6'P$_O6[=NVBE8/+?F9:,+6/S+ +M_92NE#)'2?'Q2\;7JXQUPRS=.SP`B:(KS7T31H%#6)T7YR&*A*Y$U)TDVCBG +M9VW0CFY@K'S)3&]+1A*W1I;_`P#L````[`````(```!%``#H3NH``$`1``#` +MJ`$!P*@!`@'T`?0`U`:Y"[+;3829K:@Q#(>?.(>C>2X@)"`````$````S"$` +M`+`>MB*I_/+W^4"2]A8#`9N,":'\9B4FDK$UA1$[`"(&X)?;+%5J<@NJ7XC? +MU;LK\]_4.@4_QS,M**>#K$%]&SJ'D<2MFU%WX,#>"^]$KS2`N1OBYA97BR*H +M;>.WLGTI\#Y2H&7>JN);70:UH_.Y=1` +MX,2W@^SZ8K&I??&V'8L?"WSHM.\@G_EC2?(5_ZX;R"!)VNB-:X4Y1A*W1@\C +M!`#L````[`````(```!%``#H3NL``$`1``#`J`$!P*@!`@'T`?0`U`:Y"[+; +M3829K:@Q#(>?.(>C>2X@)"`````%````S"$``+"@J]W8821X2\<'*,0BKA)@ +M"LN"E`@JHM>Q`UY6N,T33%C[LL<,$*2&9AI[SA\ +M'PWK77NH^]B_QUD^T87J3R$1D=@[PO007PL]^;QJ/[@ZMT&C!;+1X!*%1=2W +M8=GT3R]FZ-_K;55SM9#_K=0V_R\X1A*W1@%`!``\`0``/`$```(```!%``$X +M3NP``$`1``#`J`$!P*@!`@'T`?0!)`<)"[+;3829K:@Q#(>?.(>C>2X@)`@` +M```&```!'"$``0!T1PG[ALPI*=K.2D5:\7[&B=,HZW^&6+[H,:O]"=>BKSFHNVN0ZDRH2L-3"7 +MR)4$QA3-GHU1^[4U5JYAJC9R^ELZ?C."Z1AY00P8>1=Z)--V207$@-I(`)'H +M/@C:Y?TT9G9T-MB=]EG7"=\"=@]Y&CU2#B\W\D\*?`E15&$K=&5$P$ +M`!P!```<`0```@```$4``1A.[0``0!$``,"H`0'`J`$"`?0!]`$$!^D+LMM- +MA)FMJ#$,AY\XAZ-Y+B`D"`````<```#\(0``X&FR(G&!DC=Z];F4:?WP.RL% +M0XZS*UD2#]6"KIWR['E6PDVQ-?.C#.19'H):BWM56]H2>6W7FX"M8'CEX\08 +MM`[$-JUZ#?*8^D'PL/5Z">?L9L$YYH13EJ^CQ/R4Y9"PFT;[,PHG.OI@C;3ZWMF*(+*=2N$6)R8)CSK-_ +MZBK]1A5N,A7SW^TS:O":MMB7;M!_[ZKU(;)8LTR)6Y!PQ(--FB?S$,:)F6 +MO7XU_T/=Y!\&W#>+J1-:(VQ1W#MN%C!!5`@))=B*($7YLEM22D7C=+;I1*PC +M#W0YU$8SF>7XC1V'2%//*C^LC-W]/P-G%)\V_.&8,8G;G'IP:!+R@\N"V?YA +M"2NKS)IWLY;J;YA$IY?M)&$K=&U'T$`.P```#L`````@```$4``.A.[P``0!$``,"H`0'`J`$" +M`?0!]`#4!KD+LMM-A)FMJ#$,AY\XAZ-Y+B`D(`````<```#,(0``L!"YYD.^ +M[,=/0.A^-JH)B6FB$".A)0S`<1NUP+97..F7+A^DHI<&/ZJ)]XWK'LQM'-9! +M&L2;:[Y9P@/O%T[=/#YO"%O@(C5#L;:8>@PBF$SEL(YS"SW?8&*E?*@NGUX] +M;YQ[VL;L0ZSYUH9I?W3,$;>#W/'W*.4[MW4P/NM- +MS%,FGG,Q[;X/TQ%X'E[S2S$U(RR+*'4+XHMW-9?S^>M&$K=&>:8$`(P!``", +M`0```@```$4``8A.\@``0!$``,"H`0'`J`$"`?0!]`%T!UD+LMM-A)FMJ#$, +MAY\XAZ-Y+B`D"`````@```%L(0`!4$B`9*;LTBAK$A%0PE:WBN)/^PNZ!]6Q.9+.-M0!DJ[ZVBK$ +MOE?S:\I!V$TIP],_7UQ'@2DQERV)-)5Q2>9G='-E>]?L"5I!F*5/VLP0CM+P\]J<,0#M +M]D/QX9UM1]5RJ5/*#L=R2N`;KV5N9=O8(?*7@)!`I;)),P(5$MXU.?MX:UN5 +M5DFRK]MFL`L72!B@^IW#6;U_`;SKRSJVE9'<0&J6AZ8\)-(H$5&'I1<&95]T +M&-3?+RP\RY/LW8W@`@[(K'S&I7I1A*W1K/< +M!`!<`0``7`$```(```!%``%83O,``$`1``#`J`$!P*@!`@'T`?0!1`?.(>C>2X@)"`````(```!/"$``2!'V:Z*OJ!6\`*8N%\&2(1B +MK^,[V:7)0;81T3R\.`R,_/1>4J422RM^EV199,C,PSDDM?%+;66=X0_=Y8CP9+T3R +MJG]\1_GAV$5HA0--2.5VCDPWR%%,=3D>_RKYS`RF,15V*/\!",Y0-%N8"UD7 +M\\7Q6PW-PU&/^!X51)!(5_*VS)KTQAA#M(R1PD6&(IWH3"!FSHJTMVK1,T82 +MMT84!04`?````'P````"````10``>$[U``!`$0``P*@!`<"H`0(!]`'T`&0& +M26/OX!N]8^LT8CUJJ)7@.9*UR79,R7HDUU['$R:3\H781:9^@ZQA_>,&; +M7.M#1A*W1F40!0!L````;`````(```!%``!H3O8``$`1``#`J`$!P*@!`@'T +M`?0`5`8Y8^_AR%:0@UK@%<%?WX#<-2X@)2``````````3````##"_JE?8W95 +MW0RU]?UZ96#PU44>D4\G@N2$NF++'.+6KCK:4XKGGX%RT$N%"T82MT9J'P4` +M;````&P````"````10``:$[W``!`$0``P*@!`<"H`0(!]`'T`%0&.6/OX3'9OZ+F_7ZN-AE="(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``RQ\2'%CG +M0B1RXX0/^W1@&:G'X+=:[3LP5$JB@8D#`16"Q8$`-EP_, +M7X^U3;B3'+=VZ&8?^<+!(N651^BOKK@F$1'H?*"[R@^C<`#T^VO\V?(("[@`+1"'Y_CY#4I```DP]',[WG`:WSK +MCD%5`7'`$CL"?_HTO!BA75!RN.-=70\I```<``!`!*10;G]MK7OC9PJO2.OX +MYW-?$$V[````'```0`7$T?'`P"0D4?DLQG5M@]K9I'B]ET82MT;K/@8`7``` +M`%P````"````10``6$\!``!`$0``P*@!`<"H`0(!]`'T`$0&*66+RY=%*C'( +M```````````I("(@`````````#P````@``!`!@````$L/;>%\COHLF6V=:PB +M!4KY:*'7M482MT;83@8`N`$``+@!```"````10`!M$\"``!`$0``P*@!`<"H +M`0(!]`'T`:`'A66+RY=%*C'(```````````I("((`````````9@A```@``!` +M!@````$L/;>%\COHLF6V=:PB!4KY:*'7M2(``'@```!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``RQ\2'%CG0B1RXX0/^W1@&:G'X+=:[3LP5$J< +MI\A;4Z[1,,N61>B@8D#`16"Q8$`-EP_,7X^U3;B3'+=VZ&8?^<+!(N651^BO +MKK@F$1'H?*"[R@^C<`#T^VO\V?( +M("[@`+1"'Y_CY#4I```DP]',[WG`:WSKCD%5`7'`$CL"?_HTO!BA75!RN.-= +M70\I```<``!`!*10;G]MK7OC9PJO2.OXYW-?$$V[````'```0`7$T?'`P"0D +M4?DLQG5M@]K9I'B]ET82MT9D"YS8X+]Y-E%A +MP*ZNRY$R-LPYKQTZ`.^.N;)/!E0:,^B#)&ATFD;/](V)$)RSOE^5G/&[G'#Q +MI9,<*0``))1L80EU2A4H8EGUNR/3R5=_,0@*?>+3_4IY\HQ2_XXU*0``'``` +M0`0C9[7]7:"1;4JQ[IM!^D.<.41>;P```!P``$`%:+4G>P6C)".9>=5[.K5@ +MHPX6_$A&$K=&!Z(&``P!```,`0```@```$4``0A/!@``0!$``,"H`0'`J`$" +M`?0!]`#T!]EEB\N712HQR$M\93K#6:!O+B`C"`````$```#L(P``T'1KQE3U +MAH1O$V^U0>NT&C\O>M-"(,9=SFV#F/DUJ,1N_9;\U[U.D33X>I8L?(9;AGMVO +M$`N/V%S<1:R;S25H+=^1S]H*[S-DJ3MC#/G!`\^GY>_1S2I)E?UTW=;[M!.3 +M3'C46A_A],DDJ2O3NS5$Q#[D11]\VMP"'H]4BDKJ+3@(P,Y8-=V`V";_,K)P +M3E?3=X9"&'Q(J1_O2]"1BFBJF482MT:^NP8`O````+P````"````10``N$\' +M``!`$0``P*@!`<"H`0(!]`'T`*0&B66+RY=%*C'(2WQE.L-9H&\N(",@```` +M`0```)PD``"`?C:F>IQNW"Y4;3UUSS+(F-0O?E+5S-5$P`CX+Z9*O@5:>R+; +M0P2W$&Q7CU+[8<)[)/%T!26*SXYN$PX#BS'OAO!*7N4H_H41XM%V(T]#O2`E +M<))U17R"(@KQ0G?=9@P&109STD\(]3YHVZ3VP_^$E.:EL-\3)SL8*/Y[W482 +MMT88W`8`'`$``!P!```"````10`!&$\(``!`$0``P*@!`<"H`0(!]`'T`00' +MZ66+RY=%*C'(2WQE.L-9H&\N("0(`````@```/PA``#@91E^TKIWO$U@7$[G +M%G9[LORJR5,N0017X.(!ZD1NQ`B<0P:E1?$H1.)1S4A8(ARN>"OUS_?2/XD^ +ME!+<^!!Q3*U*\C'4S.LVM0@W+A_I/LKU%YF_K`@0KT\1NDYX*]0),ZZX(!.5BEV<4Y3+$GY",QVDFI)K< +M.I4;4#>OEZ8^LC:!)+8]^R@*/.G$MD$OH`=R$$82MT9[YP8`_````/P````" +M````10``^$\)``!`$0``P*@!`<"H`0(!]`'T`.0&R66+RY=%*C'(2WQE.L-9 +MH&\N("0(`````P```-PA``#`GCNGN4XHDZ@IZZWES=1I? +M]\>)S$(%&^UA%%9-'5*&Y@=C>_Y0;A('"B/<^2_:MU>UKI+6%)$!6%@[Z7JH +M!Y:Z%D][8[_SC'B47\M_G-:K#/^B3+W%;^V-9G%L!;6"%XWH[684WD_90_33 +M%ROG:9`9NE?P(R*9UDCI]5N[BX"><(EDZ?\^[#[$M85PQ5HVR9FSM +M?3*B^J-0V@:%'OZIG?H@F0PM*PBE][T@O2A&$K=&+?(&`&P```!L`````@`` +M`$4``&A/"@``0!$``,"H`0'`J`$"`?0!]`!4!CEEB\N712HQR$M\93K#6:!O +M+B`D(`````(```!,*0``,$2T/V?Z.U#K+U31,?,_A*.+NHM%KEGS7=&G3:LB +M-,4YC;&L(2K+K!;U=[+%)Q`_)T#WC8N@-=5%XQPZ??5%(%-[*M%=@6-F=^ +M=>A`*$82MT:>*P<`/`$``#P!```"````10`!.$\,``!`$0``P*@!`<"H`0(! +M]`'T`20'"66+RY=%*C'(2WQE.L-9H&\N("0(````!````1PA``$`_5][=CL; +M<@,FO03$!<2HJ`'5&;[F7PB].XC'=*[(,/0Y4]C,NF6I.K<< +MH9]OAK(+[RXUCL0IMX, +MQ:`\=XV>#DG;KKFQ[#MQ>(C![D967<::Z7^&>VG#:O]:*>CG*0O=W04YHOS1 +MK\@A)9XE&OE2TVL,KI!U#375F5@.;Q"`VF->B[O).E**JI(]LH%M"& +M$Y>S(.KSQ%92>L)=.=2W"FOR`1>):N'Y%;FMOMIK[7(QS^LRQ;>3P"J%3[KZ +MXVB\J:#2H]56+H1;(_R>CN0O4F;GQ(?3@]R9A9:\4=';%Y&6X1;:\O3$C*MSE8WTN+[W@H6N]DW_"6W +MTXJJ=-IK]B#C%0?]_5V!SUNLZB'4@C_1A*W1G5I!P#L```` +M[`````(```!%``#H3P\``$`1``#`J`$!P*@!`@'T`?0`U`:Y98O+ET4J,R`,6F%#7!HB +M#QS0.4SQ-=U?7\;U`C>H?:9$)$UA5Y-2P%4DD8(>PI\[^_)3D4FT5S]74]XA +MQUV(E8Y;P?#+VJ8\Y*H\111B0K1]5X%$<,\;I.Y_7FQTI9?RP^BZ:$SGCBI! +M31IOG*/$T_9\P=5!`:CD6XO&[Y%FY[<^X(?`A@E4^-]<)^$E-C`WB1V +M\T>Z/TJW''X1KINJ;'#]1A*W1N2'!P`\`0``/`$```(```!%``$X3Q```$`1 +M``#`J`$!P*@!`@'T`?0!)`<)98O+ET4J,H0NI2KS(+V?V&#WI5&W-*?O?_:X +MS`3\DV#@(!>E@L=)%,#S]9>?ZU>#@%.+G4=@-T1&K&@B_[4'N8[)'U/$:'0J +M=7`$44]*ER"[1P3$-@G-F(),^RG21DMNX@_YJSM5-"KLDLIX$<2W3*(#ZZR) +MAG%N&]/8]W7O!8"F1/]?6*)TRB+335%X+\*#`CCPQT[$=*V_C*_9@>G8N;_@ +M2Y"FP`?3IR)+$7>EIJ0+G\#L5+4F)!'CUGWH8XIJ?*5&$K=&,Y,'`!P!```< +M`0```@```$4``1A/$0``0!$``,"H`0'`J`$"`?0!]`$$!^EEB\N712HQR$M\ +M93K#6:!O+B`D"`````<```#\(0``X/EKQ-ATQ#M'*-C\C#M7M33_B]*D?5^F +MNF7'8`2+34&`<0(/D$W?7[D6-E!GUQB[S%CUN_:GU\<5QG(TD(A.QNG5^B/Q +M#Z1"`L.O9!]G@[<>_<-&QW@`$%Q3XW(_^.^8G3*7/#VTI%_ +MA*9K7-R(9>86`G#$3^[-8K!&$K=&HZ('`.P```#L`````@```$4``.A/$@`` +M0!$``,"H`0'`J`$"`?0!]`#4!KEEB\N712HQR$M\93K#6:!O+B`D(`````8` +M``#,(0``L(5;"3*$#]*K3L5_'L.2T!\8J7K]UTIWL&M:*`S0(^&46_\=N&-6 +MT=MB>LXW,01&,IS>1^`T(V^;8HV@!Y>W!1KCH?N.8EX*.^HS31!+"#Y`?:+($8S>ZMQF`37SH +MI\;;%''),A/6+F5L&-]T_D>-"3I`15GV2C<^^PXMABO.&<19&V])O%Q:RZI& +M$K=&8,4'`.P```#L`````@```$4``.A/$P``0!$``,"H`0'`J`$"`?0!]`#4 +M!KEEB\N712HQR$M\93K#6:!O+B`D(`````<```#,(0``L$57M.FIA`#P1LFM +MC*<6SKBN$2(;*>MG@B86(&@.H,@7NZ>=:B6.+Z_?6QN]+Z4RC`_]E0*6&,[] +MSJM/==\E,BPS:?H-\SC''N%[CAKR7ML^,'Z.FC**<4]29,V"EU1L!5Z4)_R? +M\)%P9$]2;"-C44P;,?@I,IFI&$K=&4.L'`(P!``",`0```@`` +M`$4``8A/%```0!$``,"H`0'`J`$"`?0!]`%T!UEEB\N712HQR$M\93K#6:!O +M+B`D"`````@```%L(0`!4)1E]-AQ9@QA-12QU4_2'M0P("4',1MAA%"'397( +M5"[M"\LS>OJGAQLH3FUE1&+6FJHNE&@2C +MYG@2.C3HZ=V09QB^0'W"SP2-GC!U?Y2HI*)5:J[1!GP)O($:P+__W7QM +MJ_)(S=SR9%H)8AO/JEY0U5$=38_.0_P(1672&?%UH7J>5VH)AN&%J5H9R1+B +M=V;IBH?=*%TO0P`4@>=@B(E'.SPC]](K^R:`J`]%66.H*7=L9$_4&U#)S7F, +MOH`45V4Q";!\/S]4N6[.HJ="(*0;[K0(OFVP19T&`]Z2HU^QIQ&3-RD<(J1A*W1K,?"`!<`0`` +M7`$```(```!%``%83Q4``$`1``#`J`$!P*@!`@'T`?0!1`?]-(CYM;`6O +M#W1I/XRC*;TD]G<1*;Y2IT`%@X>W/78$K*L0U72BF,;;$O.2'AU;R0R]7(&^ +MZ-0&H,P:#U'L4YV'\==O.NV^*M5JPEL(UE[,[C'L-42,49_P+1R+.,!=I)I4 +MX*\_?KHG\?#^-5N-^U:$4FD3+&[_^\"$PAM/#A,I/)K)$XQY6-)B>J60W1^) +MO1($::4NJ[QZ_/$YM8D7['Q4OF>JX/6\KXG!I]=W*)X7PCS<#6EI"<^4$]D@ +M7/S.ORS3QSMK3LY7`&JO"^3##R+248:V<@ZQ,!4$S>,\%M&1EG:FO^G+;(D# +M]$S=RMJ([ZJPEKI?Q!,ZNWB8(P$\6``!`$0``P*@!`<"H`0(!]`'T`&0&24.$/3

[M]M`2^O-\<+?S3&Z+!I!G$A:04DX:LI^XVO+UNT82MT:/8@@`;````&P` +M```"````10``:$\8``!`$0``P*@!`<"H`0(!]`'T`%0&.4.$/3"(``'@` +M``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``7T/529F6!768S.W^ +MF#7-=O7.M*-&-E;CDR*MV3=JCGSQ_N#=+=M$6O0_MMA]MHO<`D`7````%P````" +M````10``6$\>``!`$0``P*@!`<"H`0(!]`'T`$0&*8J_#%0SK`9\```````` +M```I("(@`````````#P````@``!`!@````&0._P7A^.810S.$RA"D$1%DBRW +M<$82MT;;APD`N`$``+@!```"````10`!M$\?``!`$0``P*@!`<"H`0(!]`'T +M`:`'A8J_#%0SK`9\```````````I("((`````````9@A```@``!`!@````&0 +M._P7A^.810S.$RA"D$1%DBRW<"(``'@```!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``7T/529F6!768S.W^F#7-=O7.M*-&-E;CDR*MV3=JCGSQ +M_N#=+=M$6O0_MMA]MHO<S,M=9=3S(.'B[4AN;QG)K"P#Q;!L'.);A"D$0S +M/3`9',J<.\\'Q'$S:,B/&;1<_;`P:D\V13,/PELZ$=#T*/3!$A._)T3+?[[O +MQ'+B6#5$U[0]^.)D(?K72I`&9:@>WG;5-!W.EP6;LG^MR?_RE+M0$$"_*0`` +M)(C%/7T_FUE..V+J7A4!L+[&OD8'X%CYJ&1\L#"ADDJI*0``'```0`08;T*D +MI66!`&:O3&1TM\#G[J+2$P```!P``$`%W>MP#(4GLZ!%FU9ILG(_+_"K>NI& +M$K=&X=D)``P!```,`0```@```$4``0A/(@``0!$``,"H`0'`J`$"`?0!]`#T +M!]F*OPQ4,ZP&?(\*BPX@PR_6+B`C"`````$```#L(P``T!)8DVNU6(1+HVU% +M:BW\/,7?.52L>\\H])QPH-.]=/=P5>\0:X#NO=+/0B<*SP?8R.)%]!P_5T4R +M7Y3@U[;O^'1E=?H$Y)8MVU!=[C[:T612SR)4N_ZF.E[.3!V_F8^$Y`/&%KZ> +M6`E^A:206JV%M30Y35H*2+23E`:3135*I!V347'-PW(HEL+")B_I7F\+,AJ/ +MJ_'OQ`6)4NK-IVU"./R^D!+WO=Y7]>VT-75-,EMX[:P>^0E@0!Y5O-*`+#B3 +M_M;PSDMDX+DM0H?@X$82MT:D\@D`O````+P````"````10``N$\D``!`$0`` +MP*@!`<"H`0(!]`'T`*0&B8J_#%0SK`9\CPJ+#B##+]8N(",@`````0```)PD +M``"`PG270Z0Z/;0UV,&L?H83>]TRJ4+N\SQS__FY +M(NYQ0EXP-X]B5BAH&-@1YB%EBHF[BU94_VGH;&#+L33K=Z$V?%QK5!9^XP;, +M7(L9BF?;!JK,*DJ)>6@79]1!OO%6KJ0+:C`QX20PKJ).C7Z^,D82MT8^$0H` +M'`$``!P!```"````10`!&$\E``!`$0``P*@!`<"H`0(!]`'T`00'Z8J_#%0S +MK`9\CPJ+#B##+]8N("0(`````@```/PA``#@GL>1Q1_L\$)3;UI:+PG%Z[YW +M1_SHA+0322!A>I&%\V?X7#_"G&3F_;)!9AIYGPA[6T-('-OC^EOZD]]6G3P9 +M8&L2^%.-&/BA6W%D7X`4((L4+KGIHOK!6K8+!GZ;[?#6NPM=I<6 +M=-9H_@O9*58;]`EG,N9]ISN`'$3++@H7YQ*7F(D`YUF7W&"PL?Y/U'#`#ES- +M%0;.2+X(703!LJ(M?;K1\<2S$`:7V)G(!\NI6\4`+V1VJ(>:\C"7Q@%C3=UF +M*MX*VRD]=Z"(/Y5]MUJIAA!)!Z+L#$82MT9B'0H`_````/P````"````10`` +M^$\F``!`$0``P*@!`<"H`0(!]`'T`.0&R8J_#%0SK`9\CPJ+#B##+]8N("0( +M`````P```-PA``#`YLLT"OVPO%W%V-[<51&[-@497'/`)+0P'"D<`/^?*O/U +ME_J[,6YFG>YB1[Y,18I+BLTPKS'Z*-O03II3GVG47C)K$&Y-U +MBUM%4S4=-U""N6V&.([ +M*I"@3-:,PFS;FG!P*0M,#N,M1\[7`3A#4VCHY@/*-V_@.^*G$0F1F<6<8/1A*W1C-K"@`<`0``'`$```(```!%``$83RH``$`1 +M``#`J`$!P*@!`@'T`?0!!`?IBK\,5#.L!GR/"HL.(,,OUBX@)`@````%```` +M_"$``."U4AP4JFJ%<'EX>3,#"'=9K%HL::QB_4]'-*_<8SG,X]*:[:E.7WFB +MJ/SI>&JPA9:&[.[$+,O8%(?N>XNYIIZE58_BM#MD6V](M!2(#/V_S'[6@D'\ +MF-=PM=Q_\N?<*B+!23`):T,R2P,3HB"O9D;5-+K'*K%L<\S0M[A6ONM4=[QT +M?`.BA)$M'L==K`$FY?8*K]<5`K1I4+#I[KC8UBIVF\,RE/6"96/P35Z(TRP" +M;HVP:^69YLMIDTL6LBZJ0XA^*98MH[GF]?WVEM9/7@O1WM-K0-#08V^YNK8: +M1A*W1J=Z"@#L````[`````(```!%``#H3RL``$`1``#`J`$!P*@!`@'T`?0` +MU`:YBK\,5#.L!GR/"HL.(,,OUBX@)"`````$````S"$``+!]#.Z6(!1.?-X? +MD6.^W=4V?CUZPTP=@A/I2BRY0^=]KP4K=A.1_HT$ +MFTB:I%/;LM;.].MNBEA7D/=Z)H4V1[[6ZVR5?+GR<#F*8`PR_WYUN.%/M,G@ +M:^/X_TH.$EE4Y*VK^416I&VKK@GKAZUQ)&,_1A*W1AV="@#L````[`````(` +M``!%``#H3RP``$`1``#`J`$!P*@!`@'T`?0`U`:YBK\,5#.L!GR/"HL.(,,O +MUBX@)"`````%````S"$``+`EB[1RDK-Y3T0.6S>;E55&![V0!\;ENP.^K!`J +MRV;SD,UK)YMU#_#J9*L$8>H12YULHBI>?8")#6TC#7<]YZ8R5Q^OAM#\B7*= +MROQO!FJ#U`-0A>"?H%:5!*.LNV@4:T:[ZTNK-*AK2ER':7(DS_X%\?-(BW>/ +M^89JK3R`T0D0KB1M&P4"6ON\3(BN[K3]E6'@A^M\@(+*3#B';.]NNN;Y<(>@ +MX^[`9I[FI33$1A*W1MZY"@`\`0``/`$```(```!%``$X3RT``$`1``#`J`$! +MP*@!`@'T`?0!)`<)BK\,5#.L!GR/"HL.(,,OUBX@)`@````&```!'"$``0`1 +MTC&!MI"F6:[D4+4 +MZDYE?L#7_Q4"LIE)O1^PQ3Q#^EE^Q2N7.QW6%I$8<8VOT\[/(UY,C7H#6=H9 +M]<@B=D/[B&$4R^%+@^OUZ)LJ`*B!F[,1`G87S3\4ZJ966*TL1">Z?SI2[A;' +ML7($K#P:D,%RE7OF?ZLCI&$K=&;,4*`!P!```<`0```@`` +M`$4``1A/+@``0!$``,"H`0'`J`$"`?0!]`$$!^F*OPQ4,ZP&?(\*BPX@PR_6 +M+B`D"`````<```#\(0``X+%IC)'8H#Z.!'=KVEJSV4LPXZ=MK0PE8_#A$<A +MZSYT)KEX:I&$#R9L') +M8>XKQ^):]^/&HWODGVHG0"\Q4=71;7IR$YX`+/YD-B;C7/8!,-G/ +M$5^:E`'6T%KW,UM&$K=&GM4*`.P```#L`````@```$4``.A/+P``0!$``,"H +M`0'`J`$"`?0!]`#4!KF*OPQ4,ZP&?(\*BPX@PR_6+B`D(`````8```#,(0`` +ML#(-15"G3$U,!\C^9B&7\ZVM7WHSY/E:T#W+3BO5A;A<%X,;<]J:]N8:J=Y: +MR]2`MSH>PEA\L=#5CS\)Q#8G(;O8>_,J5QYA]_VZU7_>O<*WS +M;#2VHAR6JB],J>IW0+EC3K`B:+ABVFKX8BH#S*?WOUWO'D0C-R-&$K=&O`0+ +M`.P```#L`````@```$4``.A/1P``0!$``,"H`0'`J`$"`?0!]`#4!KF*OPQ4 +M,ZP&?(\*BPX@PR_6+B`D(`````<```#,(0``L%S>.VA>A&IU:SS<]V +MJ?X7-V&GJJAGA.8/O2WO%^B&2>FP9G[F]4:^+E%UN5[)8&9HX4VX@&?Q$+!N +M9,0T'#I6=N2`-MN];9,=]SXI2/=`DSMHW7T'WAJ'Z/7;34I7,?%!=@EJEV)= +MF]GI+'7/R6P[/6/VXT&=*U::US(-BO81U!'78%OQ5U2^XXVOG%\=X6HA +MY!;2=\3*^(69373IY:'Z\8@)''WF(`$,03C.D7G3FL#CTM*V3-W?$3)7\#0RP!M@125^>X2W3CUL,2_;P\8LJ9+`6GH/T8/OW"R\[!D!#??DMLS>'LQEY&0HX3S:% +M7%)=N@$]*``!`$0``P*@!`<"H`0(!]`'T`&0&20O&Z)-)-WMBVDR< +ML8VOM(Y7_D;@2Y1A*W1K62"P!L +M````;`````(```!%``!H3TT``$`1``#`J`$!P*@!`@'T`?0`5`8Y"\;HDTDW +M>V+:3)RQC:^TARX@)2``````````3````#`AFSRJ)JM*X(D$XV;E+]FM/H62 +M+Z0PR@J,H_Z/KM*'S\PM+M2H$#\(,K(PW482MT8$H@L`;````&P````"```` +M10``:$]/``!`$0``P*@!`<"H`0(!]`'T`%0&.0O&Z)-)-WMBVDR- +MSIGM1A*W1DBK#`"8`0``F`$```(```!%``&43U$``$`1``#`J`$!P*@!`@'T +M`?0!@`=E>,:-I*PNC;X``````````"$@(@@````````!>"(``'@```!T`0$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``HF87@F;YC$AP/A0:L>F9[J7+R'N,-:,%%P'Z+A`&+(WUJ3AN<>8D4#IY4Y*PT^Z<]/'TABHF= +MW(?CGXVA$K]%7H(!JL3HL:8$`D&K=C%)>8]ZXQ7?8LSF;UJ0S(5P7Z@`,(F@Y0S(5 +MP7Z@`,(F@YF9[J7+R'N,-:,%%P'Z+A`&+ +M(WUJ3AN<>8D4#IY4Y*PT^Z<]/'TABHF=W(?CGXVA$K]%7H(!JL3HL:8$`D&K +M=C%)>8]ZXQ7?8LSF;UJEF'$ +M^VF3&AG'X2:SU&F3S:ZO"C.B86\2]+G>LBY6Y68-;7G="D;KZ=[@QN3D;&0X +M.G9Q:\:NR=?()]D29ZU=9P4ZZF2%09?O9\<\)H?[!WE +M"M9@TCA[SNIB71H/NKE4<#[%\#-TOG9CPC97<(V[1:G'#JB'1),F()R$AP3] +MB&5O0H^[8D[XM1G(KD9EUX4'>(P*:NX2E-[^!=%:!@.9L;9RFYGA>ZFRR7G, +M4G'=QV61G_NYXLC>\?98TTMCWXC>T$2DNX(CE)\QGTOE68?O +MURO$9J&G*?06>/Z-Q@X_88>LY#H[,5QLF<*CG_3.)WNW=LDO%WJLY:_)HP*` +M+IS%^FX.GT82MT8!-`T`O````+P````"````10``N$]6``!`$0``P*@!`<"H +M`0(!]`'T`*0&B7C&C:2L+HV^`)3`IJ<&D%EO6I3"P`J&F3()5J26-^QW!A`%5C,= +M;V%2%&8?)#;PE\O)ACB85=:[G$P`T;/+@?*:,BW?CT82MT974PT`'`$``!P! +M```"````10`!&$]8``!`$0``P*@!`<"H`0(!]`'T`00'Z7C&C:2L+HV^`)3` +MIJF!&E]/%1O=VT30])%(VKEB +M`VNT68[X!^F-Q3%,-$0>?"?9D)FMJ(Y2;L%;8&PI?^W+WJW-O,65N94>M;S= +M!/C<:\J=FKA,JJFJ?:7-I\LYT'VZEQY\,A4D4'R0)EUKBXZ+_^]&#^;!(&,0 +MWDCKN;2,TQ:XS[A&JB`X*)G/1A/J27Z^D64_-&S!E?V#TX_]K!<_UN&^748Y +M9*>#"?T>C^T#\=Y[\U@;CT7EFG)L)W6Y2']116FA?`VT#(S)!CK?U]^A+`+@ +M2:/FWO5+C^_]1E30T*\)9482MT;>7@T`_````/P````"````10``^$]9``!` +M$0``P*@!`<"H`0(!]`'T`.0&R7C&C:2L+HV^`)3`IJR#\9]MN6ED`R_@I"J]H3^?C-#[(B=0]X +M?=PS=!M.@Y@=F3L>C,)3?A-&%"F.T(0D+DJ0)G,\6,^YU'\=5<9$NBCVFC,S +M:&NLT"R&26MQ5):G-__:YGQ,SJ,OX?-QJ] +M.++_/Y4`ICW9/9@5P\!&$K=&;FD-`&P```!L`````@```$4``&A/6@``0!$` +M`,"H`0'`J`$"`?0!]`!4!CEXQHVDK"Z-O@"4P*:G*4;_+B`D(`````(```!, +M*0``,$FOU-^5G>6$S,2><72CY98:]JF\R\KM%>6V-(E'Z4#C"/.[GE&?GA`A +MP=>-1A*W1E^%#0!L````;`````(```!%``!H3UL``$`1``#`J`$!P*@!`@'T +M`?0`5`8Y>,:-I*PNC;X`E,"FIRE&_RX@)"`````#````3"D``#!2%Y-2FG?5 +M;N/>8B_ZM3-&G4&&H(W,=J2WMK;"J6A#`!3-W[.3^9NK8B5+-8/]GHC9(VM/]HYUF:AE8,:>;JG/GKW>Q'$ZS#;Y_+H +M6&+O6"Q_/?ES=^`YIJ/LB+*KX\[2I/-`8"W9CXLGWV:V`((H[CTX]?@=UIN):QOO+AFG.M +MZ:8#:E&\QT5?=\(G`B!@GY-,1').>B$(5_X_QW;#7NZ(F!@;D&G]& +M%6%*VU=K%A`"2'Z3!G-,/HEJXK;8;'(":K+TI,:-I*PNC;X`E,"FIRE&_RX@)`@````%````_"$``.#[ +M[NEZ;&-GV^@R*F^;+%'"4@<&]O==-+-H$4T$NN8MB.RISV!_RI5XC]#[#GJ_ +M`DWVUZ'HE["6\.-GIH#%&2K7V6@O.RQ#IZZM-9Z(`?,+4=LO/###M1N]L^9, +MH"$+5VH6XIP[^?V$F=CY.T\*RT.Z%]]&R3F>IM'7?4:&8/!'&Y7[I6K15^XP +MNBNV.HCL)WR-:0RW../T,^D+BV<[6N3O_H//*J5A0N,?Y=^_E2,\6!`\=C[# +M:E3GYZ9&60/E\+L]Q,H1I+^N_^K,:- +MI*PNC;X`E,"FIRE&_RX@)"`````$````S"$``+#$TAZF#8O#Z`H@"24&J8I] +MPV/IAF(#2B`*?9Z!2Q7G`$BG#@S,#?;S+0`EW$M"XBW&,W\T[1/7[`OPF*W9 +MR9\1*2^U##P)^6.R#GC^N[%-4*&Q[+&*.U2Y*8:@5E`-$@1!]_HNL"(NF)\Z +M3,:-I*PNC;X`E,"FIRE&_RX@)"`` +M```%````S"$``+`CSZDG];+:P@X'.>,;C,R&>HUQK3=I$/V1N/`@FF0A(+:+ +MY'$'B5G8ROUW356X>,QN=[8@,:-I*PNC;X`E,"FIRE&_RX@)`@````&```!'"$``0`?(]GJ:_C` +M5A$U(3#3$<&2T:5BQ*!>.LDZO;.FC5E`3XL^=)1E;3'1V"6S'7P#W^(_'E7D +M(4B?Z9>J`L%2B6O[1W;5M'E$#Y"+X2DVOSQ5%PQ%,5QQP'9NA8/.*,NMG8J) +MC,@XC$Z):O8-I*B(8O(VU&`_`1!9).B">TL,03[6)STWOS$6S`OO$]L:DAC-M +MN+=19F5QOF9<;.VY7U"!>(($*3JH3.R!C6"X3D=.W$Y)<.?5C&/#J'JU&$K=&.@<.`!P!```<`0```@```$4``1A/ +M80``0!$``,"H`0'`J`$"`?0!]`$$!^EXQHVDK"Z-O@"4P*:G*4;_+B`D"``` +M``<```#\(0``X+KK>T-N?*E8''!-[WNE"5K`\K=`TR9;M1=/26!F,J(=R)2G +M.5JOY7P_7:&6)]>2G=_@MQH:K2!/Z!(7_-G!=(S84G!'#09A;Y"@K7?=?>-$ +M,OVL%#7#IZY88DX%"I!IQ+)M$-:`%PMJ8E_B +MO1%KECYK%N9O*@:DLI=SI?4NQ0"\MDS*S?,6'^I:25X&"HII`<' +M?OCT\!5&$K=&SA8.`.P```#L`````@```$4``.A/8@``0!$``,"H`0'`J`$" +M`?0!]`#4!KEXQHVDK"Z-O@"4P*:G*4;_+B`D(`````8```#,(0``L(!UG7.5 +MXX(594R5ZO/8W;T$D9`"BJ%#A +MD\#V'!B=(L!3#3Q?@0,=B(,I;KG_B7+[C7QEA#+7W117Q +M[VS\4NX1W?04>L?:O!0;\\MWQ7BK[91=#BS3R:TZY=CWS971QDC`!_D1*=(0 +MM^*H^_A7`>(E$11$:@=R57D<`E1" +M&=!2,VU?+AY17RB'Z9E&$K=&UF$.`(P!``",`0```@```$4``8A/90``0!$` +M`,"H`0'`J`$"`?0!]`%T!UEXQHVDK"Z-O@"4P*:G*4;_+B`D"`````@```%L +M(0`!4'"\X,$T1])7UK;4V][7\2&+R@B(SAJ=MET!*9BV7L:[=H074^@98PC\ +M3=^'KU9B1%SUA)2BLZN%%$B[LT2R<@"YE$UQQ=ZVDO;DQ*O;V%0`F#<*.?R_ +MSAIN/BERTRE6)&H1<89)!E)AR*$^1U-YF+@?\,^\:;X\Q5=W6=NM:-HTFN[W +MWO,F9&8Z?C)6FGE^RH@+SM&AB:@GXZ#YZLVWJDZA.><"''L@G\P(TBB/IY(G +M6>J(L9\)6?%^ECIC]-3(\U/%*FGW7=64@(I,'9(%B^A)5&E^#%%_8$/!AKN$VS$HE\B3X"14Q:T$V=BC_/LX&EBHC1X,W<>R:.,!Y85 +M][)04M.#L@0*`J:0R;G)3[%VBL!+G>BDC\/2#+G^AJ9S8]K\Z>VJFNE*+(BS +M!QA`PWZ_\>QI3'TIV.[`_'2V1:L'1A*W1DR7#@!<`0``7`$```(```!%``%8 +M3V<``$`1``#`J`$!P*@!`@'T`?0!1`,:-I*PNC;X`E,"FIRE&_RX@)"`` +M```(```!/"$``2!H57TP$,!XDJ``@0XE469)#(&R&'T0&I=A._U1=\BPOKX5 +M*#)#MGQ7,B_95J@2:3L>2W[I^Q^@'B+3CX8N/SX;2&=`JI4W"C\C*D$2"B9UB'5D#K-=8[Q7YIBH +M&/F"8IJ?8(+Y?OE%-QI?8(\_%R!V5*)O0K=-_D:A0[+*CIYFG*7/2R1]DMT( +M18=87EW!?>RC_"_Q]E'KI#F4X(AF"<63;U70.X!A68BQ*+X&K0X)\F5&(SIB +M,J\79^E'6E=#;_G5+;%^*`_3YB7IZM=']D82MT;7OPX`?````'P````"```` +M10``>$]I``!`$0``P*@!`<"H`0(!]`'T`&0&260VPPCZH+CB19L.!]G*5V0N +M("4(`````````%PJ``!`JWPS>ZIPH$GC/@OGY*:[]<4O$("DUN790KHF@NTT +M3L4>GII-BOXZNK0"K!G2)WCW\#YHF;G@K6;I)<2C1A*W1@;,#@!L````;``` +M``(```!%``!H3VH``$`1``#`J`$!P*@!`@'T`?0`5`8Y9#;#"/J@N.)%FPX' +MV!0!-'&@AOPG[?.%=G>OG +M"AEP")@(RB$HQ8':OLK@*H6V<482MT93V@X`;````&P````"````10``:$]K +M``!`$0``P*@!`<"H`0(!]`'T`%0&.60VPPCZH+CB19L.!]G*5V0N("4(```` +M`0```$PJ```P.EP*\\B=@VT7[ZR@(,_)&6*\;EC]56@H7DW%;==IX)T.D^#1 +MYGS,9.)'"'E&$K=&K><.`&P```!L`````@```$4``&A/;```0!$``,"H`0'` +MJ`$"`?0!]`!4!CED-L,(^J"XXD6;#@?9RE=D+B`E(`````$```!,````,'S? +MH\K2FZIV\4_.5W\>P,ES&/`$N`#8T8Y8;C"R;1EDVMRE*QC`]%E2Y+)51Q*W +M1NN@``"8`0``F`$```(```!%``&43W```$`1``#`J`$!P*@!`@'T`?0!@`=E +MP^0IA8IR2E8``````````"$@(@@````````!>"(``'@```!T`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``E1>!%RQ\3A(9'822&-[[3Y#?@`^TU#.6 +MU[3`VVW0RH]!6C*^B2%1WKKBCV+RW7U"B`87XN,=KP]SH"C"TA]<.&3NYN_@ +MA6J`B#.'SWK<185#:PD%L/*374T5SE%%E>.S*20)?+*FWJ +MP#N!'QXR?Z3EATW+&2PI```D@?/77#:$ +MY.T8A`@I```<``!`!`)M'[I"YS`<_G95W7.?O!A!3U0T````'```0`7@[]'I +M[\T@^5+;`[!E!%RQ\3A(9'822&-[[3Y#?@`^TU#.6U[3`VVW0RH]!6C*^B2%1WKKBCV+R +MW7U"B`87XN,=KP]SH"C"TA]<.&3NYN_@A6J`B#.'SWK<185#:PD%L/*374T5 +MSE%%E>.S*20)?+*FWJP#N!'QXR?Z3EATW+&2PI```D@?/7 +M7#:$Y.T8A`@I```<``!`!`)M'[I"YS`< +M_G95W7.?O!A!3U0T````'```0`7@[]'I[\T@^5+;`[!E!#?-CI[Y]*!)]QB`0B'%X7=!U``>D$*VORBL,7733T2(XCQ7,F&MS3:G +M$B"ZKS6A2E-1S5P6M\E\JI3UA.K2??4)>*)9I6H?:!NBFKZ2-HS2:,EWI'$K=&71(!``P!```, +M`0```@```$4``0A/=```0!$``,"H`0'`J`$"`?0!]`#T!]G#Y"F%BG)*5GXB +M"S?K:"P7+B`C"`````$```#L(P``T(2%+V?W8.\7O+RCHTL9,D_[KV_I/[;T-E<>5Z(/'<"*_RSR^0E'*\[\& +MV6X,:,'?,!5@@X=T:P6#WZS]%5P@M$^"8SQRI?F#QMR,?(W)SZOX\7C92,@=K=!H[ +MF_GU6U+XLDB%1]$=WMZ;7I-*`4=38>K\-_Y#]8.-0RE$<2MT8\2@$`'`$``!P!```"```` +M10`!&$]W``!`$0``P*@!`<"H`0(!]`'T`00'ZL?@]7)R,.YA&K3*&'/7HIK!V'"' +M&E1E2-WQ(93ND?O2^GA^9^&WZN;6@2MBR:NP"N^$-SZPOR2?:)I0\F'`#299CG26+\3]5R<#1!AL,(KZ +M""&S$@1`Z%\7AU.%'$K=&O&`!`&P```!L`````@```$4``&A/>0``0!$``,"H`0'` +MJ`$"`?0!]`!4!CG#Y"F%BG)*5GXB"S?K:"P7+B`D(`````(```!,*0``,`_] +M<=7?X65BJ+O5+4>8!WU.,"*;5\]Q=QK'CD\<_:$AL?,)^%9/-@!U +M:"WV.GZT'L,(6TM=1X'$(GSSF`%%GZMP/)[[7;L**T<2MT:_EP$`/`$``#P! +M```"````10`!.$]]``!`$0``P*@!`<"H`0(!]`'T`20'"G]G5Z>`CNMT)^MA>7H"5ERT;+S'# +MX(_X!MC,OZJQZ<75SUSC'6)PG:#8:E1:Q3\Z.%7K)0EW,^;?>G.%2C:HQ +M$X<<#BD76Q4XGP?DZT.62>,L7@?,B#P?.GF2FE7=ZY8:!-0X#P;5OYY@)VH*Q_S^_Z4%>.#-OG\->,`Y(AX[58J +M1OYS)MW]'XFK_;TA,)>P')V![U;;IHMX!E9UK#N=,+(`BB)I0Z>:@`FBR]`2 +MDWZ?PU\2KM2BA"CF%Q,_<1XX9T$B\T]N0JR!6CR:8H\Y:Y,)+V^.!;]&;WX. +M\2$_ZSA.J-^-(PE0ZU@/-]-0#1Q*W1F&T`0#L```` +M[`````(```!%``#H3W\``$`1``#`J`$!P*@!`@'T`?0`U`:YP^0IA8IR2E9^ +M(@LWZV@L%RX@)"`````$````S"$``+#K.7V7]KZRBA@>GNP[Y.H'N[P-]0I) +MFK$4@:`@%4S@51_W3+%7ER5TTZF=95CK8#(Q7@H6%N@C$P5(A^J2L:'QJ>UW +M=Y7AH+7@^L7.=E7[ +MF&IARWE7/AH>S?47'25I1Q*W1HS7`0#L````[`````(```!%``#H3X```$`1 +M``#`J`$!P*@!`@'T`?0`U`:YP^0IA8IR2E9^(@LWZV@L%RX@)"`````%```` +MS"$``+#DH@F8YL*EF(0?VQM'#\5FBG,#>_.O6>WWA062,1,.X4X)IOOSZ\EM!Q-MPADR^TCD?(SLD+,S-C8 +M&[/+(GS_O&F8H]Z^44^^^%N`$=/KFI;U5AB4]"HQ`6[)7>`U@9( +M1A'D&UYQ-YDE-(SJW5+D7"="^D"F!X)ERFM7.CFPYG/9$W#*V>,"VBX;2/.V +M<%["4#66C=*VI]"DS"`J(!QK'#8>@Y_.@C)Y;[&M4;.`%4_;CD +M0VOU3E,G8S`8!?;."Z9-U:,A8@__"F+BK63%UU$38]PLM)P:YYG^.D3!T0@Q +M^]LE@=/QM[ZUS9%/[7IG)@-JK4;SUN,^PVG9TV4>*'CPX[MUA?U;R?3%0*;0 +MV*-.^-E.S,#8#5"6W4M'$K=&N@,"`!P!```<`0```@```$4``1A/A0``0!$` +M`,"H`0'`J`$"`?0!]`$$!^G#Y"F%BG)*5GXB"S?K:"P7+B`D"`````<```#\ +M(0``X`H$V$[A[&0G772]ZEP.1TW^4`L#79EE"W7*#I]&?)HY+S/GG%(Q*EM` +MM8FCA,TSZ*NTE"1;WK7.F6K[&+$Q%LV-*X+:8K/E/G'\Y/403-R+$@Q5&PB- +M4/TC9@*?.26Y/D=G,5!8UG=(?P+DC-(')&-M@':X4(AVRAO#M)UR=6`N%S:P +M"GA7DBY#M:$RYQJF^#H2J!1=0K)O@4N,'O[3'":WXC$;!A'<=]L5,KZ-0[=] +M>65:O[?HG3BX+_BIL'4);5Q9S410"`.P```#L`````@```$4``.A/A@``0!$``,"H`0'`J`$"`?0!]`#4 +M!KG#Y"F%BG)*5GXB"S?K:"P7+B`D(`````8```#,(0``L,%OIT+U@TF9`.D] +MYF[T;DU]8L,X_Q6KX+;#K#7*#TM\PW[N[5V-RH%\H0M\0ZJ(JS:(S^<)SH$: +MST%$^1-R\[YC31O(@K4,*@0REYS@*`ZC[-L,G-63$N">CL\1*E3YL^E/1.XN +MXP141^0M$T->)K;KE[QL`SUFQ3-EF;C1[H38+?@B=NH2/KIH2N<%)88!/?YM +MC1EO#=CE?6[KC19T7#UO4XF,>5WZG%4)*V)'$K=&MBL"`.P```#L`````@`` +M`$4``.A/AP``0!$``,"H`0'`J`$"`?0!]`#4!KG#Y"F%BG)*5GXB"S?K:"P7 +M+B`D(`````<```#,(0``L..9D,0,^>FR@CWJ&,+)X]WB5SG%VB"4FXLW'`N; +MPC#4)+.OSUB#&7#'$Z,`!LJ]`.U$!)7I?*A.`%SK+3S1+[[Y2NS[OQM!?948 +M5;!8]5W&K<@3R/,+Q$R3N'AFB1^N.IU)6%"L]&BGY%[+U:RWA[)6@K/8OT=% +M%'\[U=0W/%4?K7USF759Z`+^B$:W9X_.L9X[S40N?U@(]+%/YA:Z#1KW1G"E +M*Z=IE:"*>I<^/(^ +MC3E]S+C:D5]@BPBPE5'9*%$<,1RAWN\JL_`(U@)0?TIVLSCL*FCX"R\ICH4* +MLJ[WO(\V!5Q#;R%-``V;*:)9:ZV,12:7:S(S.P.$2`@!<`0``7`$```(```!%``%83XD``$`1 +M``#`J`$!P*@!`@'T`?0!1`:(.0%7;;=13Z7.5BYQHCP +MK9-E02']@FG@1=F!1TY,N`RQKTLZ'/6UW"(E/$9)>7L,H]0P]"O:S++OO[I>N!!AO+6F@@SEMO%V0.3*-M+B,( +M]CRJ=M^I%EI\N7$%`XB)4,OO6T$,'!%O0%RQ$IWGR!'B'&/6##.H.E=/?\!' +M'_!,DGDFHND<;$$?#_1#.`3OJT<2MT8-N0(`?````'P````"````10``>$^* +M``!`$0``P*@!`<"H`0(!]`'T`&0&2=)'@'LU[SF',7:!*F?#VR4N("4(```` +M`````%PJ``!`1\"T%B?IR2+$1K\-!0AA9%AOLSQM5F^(U!I.XI[<((;21V]5 +MZ`,)^<7^*AR`27?M\G/D4O4D3RGH=E241Q*W1E+$`@!L````;`````(```!% +M``!H3XL``$`1``#`J`$!P*@!`@'T`?0`5`8YTD>`>S7O.81X[&3;R+#K5MF\YAS%V@2IGP]LE+B`E(`````$```!,````,-E\.A2HEDP7 +MP4CVJR]2!X;R$F>Y/._Z[GT/&Y>R48`&XC5#/"(``'@```!T`0$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``WAS*PR,8`>1)$0WTG#:TH"AB:;3=?L6$X)JLT2?5 +M$C)6Y*(.<+`&>Y,7)T$M.MUQ&9&2';<.J!?;^HH +MO8)0,/EO.0,I```D)Q=6#>XAG8N7==#:*`9M,&LP$,7Q:S&(R60I +M```<``!`!#N6^]*3AM[\O=#$$T9"=VW;:V%6````'```0`5Y#K0&E5XKWT-Q +MGD@]\I)U#ZE#R4<2MT;IZ0,`7````%P````"````10``6$^/``!`$0``P*@! +M`<"H`0(!]`'T`$0&*?_Q@%W'?56^```````````I("(@`````````#P````@ +M``!`!@````%?P/IS3F)H-^X0+CT,YKW'=&P2J4<2MT9R^0,`N`$``+@!```" +M````10`!M$^0``!`$0``P*@!`<"H`0(!]`'T`:`'A?_Q@%W'?56^```````` +M```I("((`````````9@A```@``!`!@````%?P/IS3F)H-^X0+CT,YKW'=&P2 +MJ2(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``WAS*PR,8 +M`>1)$0WTG#:TH"AB:;3=?L6$X)JLT2?5$C)6Y*( +M.<+`&>Y,7)T$M.MUQ&9&2';<.J!?;^HHO8)0,/EO.0,I```D)Q=6#>XAG8N7 +M==#:*`9M,&LP$,7Q:S&(R60I```<``!`!#N6^]*3AM[\O=#$$T9" +M=VW;:V%6````'```0`5Y#K0&E5XKWT-QGD@]\I)U#ZE#R4<2MT:M'@0`4`$` +M`%`!```"````10`!3$^1``!`$0``P*@!`<"H`0(!]`'T`3@''?_Q@%W'?56^ +M#VSW76'>Y.`U.3.O +MDD&E^>0C',=>]#RT5*N6$ECZ.%)K'X)'Q$K_"'\W=;S[M`#4/8"\VUH-DO=4 +M8F+O&,%&MZ(I\77X.HUVZ +MP=-#0WM*27E +M4BCK4]*CV)+2J#?N2O"L]:,%@"9DC$Q9IV7&;_2$+7EG8&(T9BC[V"?4X^P( +MKY\?WBJP09E1/_.QZ$12SMJ@":5[.%ZV:EH;5[_0-,?]J=>^@4IR>5&DB>'9 +M6$<3$KYDR<3T@':K'*Q237F"5;(\Z6(;(7/;(D-1Y.Y.PF.)FV%1-0W"V&=_Z),>MD5[E_#`<-0ZOE,O7X2>Q)&JWT+C4/Q`&D:R +M9/W;./J&5[[5?/!B%S8$O`AMQ^$L0+/XLQ[=63F%SAQ>/&1T5?+K&Q> +M&K8*.A)TJI`++=T31\L$<$VY?Y.F)M.U_H^>B$.RI18+!A*U`45H%,1?XI&;6(-_.YWU;+KV@\!A^3V'K +MBCK.YZQN(3,U!F;OM+KO8\6:P)I/N,9^'^:N14"H\C,@(!==:'3'6/V^8]DS +MB@JX53,VRH!IY^:*SORKODO0V(M#MRFM,3W)97K),=DH]E1XM<>E0S +MP1JE$L*B1#&5<\6ZXC;OB@_QODP-21+`L*1]]V(58+L-0/QNW>,K55U^)X]! +M:AE'$K=&K)D$`&P```!L`````@```$4``&A/E@``0!$``,"H`0'`J`$"`?0! +M]`!4!CG_\8!=QWU5O@]L]UUAWN3G+B`D(`````(```!,*0``,+OOH.SOARIR +MN#Y8$!TH;U[T^P%Q('[DWOJ;B3?)V<.-@K">D)M@[0&7GP\C1Q*W1DBU!`!L +M````;`````(```!%``!H3Y<``$`1``#`J`$!P*@!`@'T`?0`5`8Y__&`7<=] +M5;X/;/==8=[DYRX@)"`````#````3"D``#!^UH,\557,"X9U>#8[U:.8=XU@ +MVY.-;&([%_[Q)P=J)IQO^\/'41XTH"8) +MWWT^R'%;>2SL*`HCNW@GC;J!3,[>,Y=Q*6>;3@M8P'^[$0*7\N!.]S7"*[GP +M0-+RLW8;LK!_QT23^#]X4%&F#2CPMO/\P>'D8 +M9P0=-W.H7`3RVM#OY:"VE2SDNFIY@NPLE>T_H<,@]N>_$UB/RLH]]GG6&6!R +M+V,9!,V\8C_.R)X"0-`S"M_:HCGTC;<'&'HA9_I[[AG1O'-RUVW3Z +M9V*"P3NA>]A83'/E``&I2&"PH9-=)9WQNE,2!;\BMF"NIRKJ]V+AZ=>RFZP7 +M$-@+NY#<#^I%WN2PQ;B?(HT"L.\Y^G2_#KA03S:`CD=NN.Y,#&RQ`<&\=K]T"8(GT@1/._XDBU +MN!/:&$T>%I<>&#E+:?(19,-YE#3^0&`<93>FEY* +MXB#GN!TWYA0Y0-!TJ_OX:=M'P<$CS)4#LJC3$<)E%"7=@]C-A#IW1III<-'> +MW!:-#ZWU1,W"N5H6>N6&H5ANBFYCDG4#0"BMDLN!.U/02H++%`(4D^BKSP8= +MV9:C^:P#N:EN+L&0LBB.[(+FH<)?(/I`8`G?=\T5FQ\#'Z#@:B\GR[:!F?+I`K>Y)WWR_\N +M\$C/>\3*WCED[0&!M.RN"E`-'&[&!$[]C$UKP>J8Y;DC_+:!HQ4"8/:2KIU^ +M^XMCD9R&3Z$!V/UW)?Y?IRB/2]>@/&#IBCL!_;Q>':`N%(^]F1"SW5Q`#,T_ +M985J(4"QRTZG^1CC1QSH.EGZ]#7]N'M\OE/X^Q9[,5\"+)>#1Q*W1G8M!0`\ +M`0``/`$```(```!%``$X3YX``$`1``#`J`$!P*@!`@'T`?0!)`<)__&`7<=] +M5;X/;/==8=[DYRX@)`@````&```!'"$``0`:J#/\JI9JLO?%KV'ZUPW%Z8`2 +MLAQ<_^$!>3^QGLO4$@"E"B`OSH`B+HPA4K--_Q_V[\8\LP9(I4?LZ[N8V +MGI$'E.$1W^Q!%@*),@/N`T)HOO3:I\(6/;VN2YZ\=]>0M^8V<=^K(E#M`^(/,G94:?4D8@VB&)+X0%#`6&3G3T6?GL0G@=;F)%I,<' +MZA.B0L6&D"7W6Y*Y+P)S0,"@199;+VO5_1>MPOXJOHQT!A-A8:O/._)F.I*E$0> +MY]H?T[$I6?>4+;R+:8#=XSW6+V[SE9$E`4```#-V\%_`8G)6$.]'$K=&QT@% +M`.P```#L`````@```$4``.A/H```0!$``,"H`0'`J`$"`?0!]`#4!KG_\8!= +MQWU5O@]L]UUAWN3G+B`D(`````8```#,(0``L#KIS_*FTPJ:^P="!85X8,Y$ +MXK)'"9"5](.2S +MBTY66&]YN;WRSFI](+T\G%\:@EV>HFIDK`FCT2O3#%QS81%^Y//O\$%>Q)+# +M7X$#EO,S(EDIDA0(9ZB@GV=*T9PJI%',!A!V_O[>J?SVS-9I6%'W-6.Z;IQ6 +MX7YA/>CE51?@]8O78JJD>X]4R:Y'$K=&S6H%`.P```#L`````@```$4``.A/ +MH0``0!$``,"H`0'`J`$"`?0!]`#4!KG_\8!=QWU5O@]L]UUAWN3G+B`D(``` +M``<```#,(0``L(L(-5$9@+!U$RX9XJS9#1UNPV:A6P*HKB&`=#KX$[C@8I1C +MB^R`*Z3[K-M0P?)Q8:S-+JV?^-;RKBKC)FX2!64UIZ5=&7L0/%K>10K0>)KN +MH'!P7@V5Y)RJJ/_??6P!.)E:/HI/Y\6YZ\L?'[VMH]Y]TP3)O3APD`4W'B*7 +M%)R,5-`*6RYAH3P.31*V[;TC<83;'B-RD2I7?[YNPE4]_TDA,@+>T4SM],#G +M]K-'$K=&U)$%`(P!``",`0```@```$4``8A/HP``0!$``,"H`0'`J`$"`?0! +M]`%T!UG_\8!=QWU5O@]L]UUAWN3G+B`D"`````@```%L(0`!4$OAM6^Z,3EP +MWW>0"USF&T"N!@9K[Y(R4`VZ,#+?-_`>;S)Q\81B1A``/'A.Y-U"VDK36X@GGQV#*:[/?OGUFJJER_(\P5>5YBR7-! +M/5MWK*K0BW]>7$8:/L6GX'"9H]P']`/6Z`"+6$;O;F,UX/WP7>G7F4W=#TK; +M3SNSET3AJ;CJUB8(H7OA<."Q>'%N)4_/MQK8TBHZ+%I<$2A$<.F%BDVANVPIUWQN&30(?@HD8;KN@,@S^^ +M[?!XOU6E%BG$5ZNU@*H[5,+QPN40JNA65QV>_^8=HX6YG]7._S!D4ZK +M=4'/[AF`WESBBKHIZ2`G0>Y3+(@AI'X49^[['.F,P_%LV>ED>$G./N#_QABU +MZ(_&8?B2P]4'(0('X)K]+Q\%,HOACZB3(Z-A=>IDUK"YD7`SMT,.S`P_J006 +MJ5JV3I9+GZOLD,N/W6`/>8ETIE^0[>G3L!>Q=37"_UTEV9F?RZ=Q\9@=GZ<1\N"8,P?XR-#>`Z'+I#\T"=0P&8@5,B!Y8S;;-$,T9[7 +M:X"=QCG7S=U%3G]TVD<2MT9Q[@4`?````'P````"````10``>$^E``!`$0`` +MP*@!`<"H`0(!]`'T`&0&2581Y&":[.VBX8;6B0-ADG,N("4(`````````%PJ +M``!`"'+I4KXO7;X"L$[8L%LX?\O[FZ`_@CA="LN#<"^B@^,7JC:K!B$Z>910 +M*]^7)KL,#D\<3DXE^6`8:Z55'I+[D<2MT:%"`8`;````&P````"````10``:$^G``!`$0``P*@!`<"H +M`0(!]`'T`%0&.581Y&":[.VBX8;6B0-ADG,N("4(`````0```$PJ```PRW`- +M[0[`S<]WT`'';^QHGTX@2-N_;%,TQR5,*F)VY8GD)607U*1\];":75!'$K=& +M?Q4&`&P```!L`````@```$4``&A/J```0!$``,"H`0'`J`$"`?0!]`!4!CE6 +M$>1@FNSMHN&&UHD#89)S+B`E(`````$```!,````,"I=LXG4W;![QAI@HYSI +M=8XZNHKGB^_J'EMKT].+X4W:H]@N=TBQ"1Q*W1C<0!P"8`0``F`$` +M``(```!%``&43ZD``$`1``#`J`$!P*@!`@'T`?0!@`=ETM01!]CK5K(````` +M`````"$@(@@````````!>"(``'@```!T`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``-T'Z$_YD>>>@ZY$,""4YI^9[GPD07HPZ:R1Z6W.8VB +M++;&9]UL@(TA%H^I9_( +M3&),QU<.O`?FB'-,G:QF/OFXP_/7+9(>^_?@YI4"NSJ_':^K<"N>8)VM:8]> +M1N4I```D+NW')+67E+8NGG)0Q6>S-IS(X@8E9)T7U&\V=]"2K3PI```<``!` +M!+I8,L6&"TLM@)^2B6/90:AA9_]7````'```0`5.]&2)66AF9Y/O*"\I)!Y^ +MKF]2@4<2MT;-'@<`7````%P````"````10``6$^J``!`$0``P*@!`<"H`0(! +M]`'T`$0&*=+4$0?8ZU:R```````````I("(@`````````#P````@``!`!@`` +M``$4>>@ZY$,""4YI^9[GPD07HPZ:R1Z6W.8VB++;&9]UL@(TA%H^I9_(3&),QU<.O`?FB'-,G:QF/OFXP_/7 +M+9(>^_?@YI4"NSJ_':^K<"N>8)VM:8]>1N4I```D+NW')+67E+8NGG)0Q6>S +M-IS(X@8E9)T7U&\V=]"2K3PI```<``!`!+I8,L6&"TLM@)^2B6/90:AA9_]7 +M````'```0`5.]&2)66AF9Y/O*"\I)!Y^KF]2@4<2MT8J5`<`4`$``%`!```" +M````10`!3$^L``!`$0``P*@!`<"H`0(!]`'T`3@''=+4$0?8ZU:RXH)/_FD7 +M#FTA("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@`` +M`@,```@#```"````"`0```(H``"(``(``#3*W($W0*LT1TB]E"HKCK\K4Y;8 +M7W,SKV+S:Y:A"8>C1>J^#`U4B#V.)P'9^ER)+[D&O)FBXP%\>V6?<9OSQ?;" +M^0]VGZ*9X+%V.OD$'K77()H;,8VC.1BG\/^?7>)WU*LYUS<"3NLV*0``)*<%OZW\\IP5AG=*^GFS_?+F^/Y4O%!4 +M1LFR+SU%KANO*0``'```0`1:4;5&*7G$.)%YXZ+'W@._B>*/[````!P``$`% +M\]LD(%0P%`I;V3(6I%UQ9@V'G,A'$K=&P(`'``P!```,`0```@```$4``0A/ +MK0``0!$``,"H`0'`J`$"`?0!]`#T!]G2U!$'V.M6LN*"3_YI%PYM+B`C"``` +M``$```#L(P``T(U5>YCD-I7``"K#Y+A%G._8F)U(4C5;V,3/?'B;@'U1PJ/# +M*(4JEW9Y.-E)$6MD$(N\67#F##`LCHOCZ0-F<^591:[7Y1?M'OG$PP3IB+;X +M5'&=E"S2LE/S#J;M\'55(A4;1P-^"BE=D6,<((M;WU3B3H\Y>]L/?B3`77'U +M=B$^Z,]IVX.ZAVB'`T[&-<\4MESR?6"874'=Z,E0L5%LAF5K!/CM<'=X<:44 +M)H340T/^(=+$]SB^69QG!&0V]15J?!B`O%9J*>)R$\D0Y4<2MT8UF@<`O``` +M`+P````"````10``N$^N``!`$0``P*@!`<"H`0(!]`'T`*0&B=+4$0?8ZU:R +MXH)/_FD7#FTN(",@`````0```)PD``"`Z\,)F.8VUC?,LBR]7S*`-+&1AE1) +M=6@E8G,JWIA!Q1(<@C_DC#:)P?(OX1@[A*Y2'U8>!J;AYV\V!OEN+`-XKT]0 +M\9%]([?['ZVZB.I#5^+JZ$*%UC?J033?4]9=LN(`T='/M`SZIOO?=H;.'X[U +MFMV\@B$"M0OCLZ%F^T<2MT9VN`<`'`$``!P!```"````10`!&$^O``!`$0`` +MP*@!`<"H`0(!]`'T`00'Z=+4$0?8ZU:RXH)/_FD7#FTN("0(`````@```/PA +M``#@>3.,!,L+`$N-I,F'<9CS]CFXF=%GX=5?KXLA6$*!M`)^,"Q"3QFFN7T?03 +M#KWX%DY>>=`DYV/5VX%W6)K<;$=%D*3$]N(K"K_.CW(GAJI8`H'QP_K=A2,C +M+8[C4*+86Z]HU]D*)^F09OY'3GI1VWL,Z)5.U`RUR=FBQXH,6ZR(A&D4*])` +M,]?%(&,1'%#E,)@;MOQO,-"7,&KO#WM%^.(;G(;EC26@)+?5VI!VVW/42T<2 +MMT9QPP<`_````/P````"````10``^$^P``!`$0``P*@!`<"H`0(!]`'T`.0& +MR=+4$0?8ZU:RXH)/_FD7#FTN("0(`````P```-PA``#`9`X!6W4NBT"W8+E] +M,=D@@'$[SU"LE_>W(P/ +M"&IQ(XG!+4[GL[73!N"04K=?RW'-B@:GZ`/:?QP[[9/:,>J6AA,0=)AQ.^W) +MI](N2H'3\RK9H-H^USEZ"U!K"72J<]=46N!9@\_SY?4XNC(_RO_76N[2UZ[J($0PZO11]"1:GF#N1Q*W1D?J!P!L````;``` +M``(```!%``!H3[(``$`1``#`J`$!P*@!`@'T`?0`5`8YTM01!]CK5K+B@D_^ +M:1<.;2X@)"`````#````3"D``#!^"#=-[%FKLT1UA&*V#@B[C9Y(&422P+(; +M<6S)C&_34O5N^8)J1O^$^W989T<2MT:\!`@`/`$``#P!```"````10`!.$^S +M``!`$0``P*@!`<"H`0(!]`'T`20'"=+4$0?8ZU:RXH)/_FD7#FTN("0(```` +M!````1PA``$`%C%]A9%N_)=M+=%:!.`ZI>)F%6T`?>9Y+X8V8L$K6QH`5$$( +MU;-RHA6%^&#K...4M;.JLXI_]<:O"LWCQJR)LGH+[!VV?):MOE;R8#F3NYM8 +M/]"11G[G[C3#R4U"PP:O\Y.N`VH:PT[J#%3"H9--*F?JH=AD:^8.?-?-./_] +M_A`V'O'0?(4#H,60"T1BR!^3C@EUL*B-B6LW49WM4'TCU6>0KD_ZE783#85U +MB92H%"%+QB171T[])WDOGMJ*PJ<;1CEC'G$AL]([ECL4V34HK1Q*W1L@0"``< +M`0``'`$```(```!%``$83[4``$`1``#`J`$!P*@!`@'T`?0!!`?ITM01!]CK +M5K+B@D_^:1<.;2X@)`@````%````_"$``.""A7\9TWID*6EL#OXL-^$RX\1X +M'/&*HZO^7\&ZF8$S6\8!?#(#G]6:9K\1G#R?%);@'/EJ-806'?0G%-Y(XOI]1U&0D[IX3N,#]5D%".!DS1BWZ3JU+!L& +M`Q:DWF=!/LWTER%CJ@@YX#FJ.Q30'<@@N!;H'\E4UIX`.VY6TV(^>E_RA?F! +M0G,>`^C6X/>12&E0D+'O%J99KL?S[;&-(4`IB4L'3.TWQI-+S0*8EZ2T0LSB +MM^IV0A0W2KPW]6YCR^AX=2)&P&TA1Q*W1DD@"`#L````[`````(```!%``#H +M3[8``$`1``#`J`$!P*@!`@'T`?0`U`:YTM01!]CK5K+B@D_^:1<.;2X@)"`` +M```$````S"$``+`!U+0D9]QM@,NU-1=)]!&V:,]K,[A:O%E>,]:SX<0,73Z_ +M;R.@7FA$-@TP^?<89I8R$"AK><8:R-+52L_D55T-\66!X$EDLX/#Y\L8W[,Q +MA^Q'M3*RE"*<>*50,)[P22.6BCI#>D6=G2IX,RS54/5J\K]JR]/W4=P[N-;R +MXU9M)51U?]1I1./+[:%1`+M+W]=H^#+1:0H<(LL9_U^;WBL60^!X3&)XG[.B8!E<.L8+I,WB5FHI&;VPH'[="8D973*!H-=?^X(:>__LB]%D +MIRFU,Q-_D(@RYM%]<<.\QMF^VI5:)'#R23#WF5:3U>I0\&F;V=C(G!'_#?H# +M,=-G*'SO[JP9I,B/.?`_;A^9W."I6UXF$[UC9E^_LI\K_51S(!K)XP19T#F. +M*9']B6-JZMCUXR?B?!--T0HY)::KK-0X9I:"!BV11Q*W1OE?"``\`0``/`$` +M``(```!%``$X3[@``$`1``#`J`$!P*@!`@'T`?0!)`<)TM01!]CK5K+B@D_^ +M:1<.;2X@)`@````&```!'"$``0#.:NO8I^(E+HI+JGI$/@C:QY8_=6$'`R=+ +M-3+2:V+\'O?4O/G[FED\:T-9F+$'8[3U"Y$:_;DB).[BX?YR=TX>^J.,;5/8 +M^A4$5&OB\MQ_^?"EIZG?!.O +MBABQHMF`J,6`P!+H((N'EC>Z1O/F8%7]7=B_F+_\71HK`(L>)7^EC.E-5:IPK\$+,D+'7^T')?)-*20`DM4RM5[`KNAYZ42!?0FU7OH_&A_?'[T!S!WUDK$8 +M%@\E[^,I8V&3>AO*H";=^`H"I&Y&.9:X$<8#Y<,UT\`YQ[7BL/Q\ +M!V@F!I&1GE11!]'2P>I'$K=&_)P(`.P```#L`````@```$4``.A/NP``0!$` +M`,"H`0'`J`$"`?0!]`#4!KG2U!$'V.M6LN*"3_YI%PYM+B`D(`````<```#, +M(0``L%@QM1KV8?\GY["E:KIKF0/Z(KO/#Q`_IE@#X-[1LVS^RU:N-=$%V,'' +MZ_P1;>"EKG'\VI'UJ)_!79-XDAQ>2=[Q(;N^;B==[_1?5``]<*DD(/"]K +M2^S]O/Z!XCR,O"4JZ\?B7%SE`1GVBCF9?NK,D3SX\XI9D@BV4)M];[7DY4OW\-`:IN<50..V[=$IPF]D98/7G'\A^8``HQJG0ZP#LDG6T%W:F@>]X/UH; +MV)SB?YD5D$<2MT:P'0D`?````'P````"````10``>$^^``!`$0``P*@!`<"H +M`0(!]`'T`&0&263UABRJ7JNC!?O2T$WMYSDN("4(`````````%PJ``!`P5[O +MU63JZ,%^]+03>WG.2X@)2``````````3``` +M`#`1.=2MVBI^QD\P5)81!TAUGOZ_['0EG*[M>Z7Y7H_M?XH'^&0%+6:AA46R +MRD<2MT:[.0D`;````&P````"````10``:$_```!`$0``P*@!`<"H`0(!]`'T +M`%0&.63UABRJ7JNC!?O2T$WMYSDN("4(`````0```$PJ```P2,Z-OT*`=1'^ +M.1[*=+'/(T,*K&Z_8B!L6::S_/GA,8IOIZ\)E%'SJAODPR5'$K=&"T<)`&P` +M``!L`````@```$4``&A/P0``0!$``,"H`0'`J`$"`?0!]`!4!CED]88LJEZK +MHP7[TM!-[>"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``Q[4Z3Q@MW\-SNQ49,L?K8DIE:6'C>E4EJ+X!$KM08EO+L!V=XQ?C,:WETWR)O6V46[8/2$&RUD=Y/VD0RHI```D +MIG!N'"2FO2,Z?P3-\!C<\GJ"HO-'\XA1&G)V;6,'S9\I```<``!`!-DF"-JA +M>H&;S[)98"N)D;K;N4,&````'```0`489ZO*U74WX?Z`!P;8)U=K]Q[%4<2MT;"8`H`N`$``+@!```"````10`!M$_$``!` +M$0``P*@!`<"H`0(!]`'T`:`'A33E1[*A]'U)```````````I("((```````` +M`9@A```@``!`!@````%E;\H`<[DF>X?Z`!P;8)U=K]Q[%2(``'@```!T`0$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``Q[4Z3Q@MW\-SNQ49,L?K8DIE +M:6'C>E4EJ+X!$KM08EO+L!V=XQ?C,:W +METWR)O6V46[8/2$&RUD=Y/VD0RHI```DIG!N'"2FO2,Z?P3-\!C<\GJ"HO-' +M\XA1&G)V;6,'S9\I```<``!`!-DF"-JA>H&;S[)98"N)D;K;N4,&````'``` +M0`489ZO*U74WNR%CH!VQ$A("(@ +M`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@# +M```"````"`0```(H``"(``(``(G7&MN,QI+"'FIGLC?YN\W[_K,CJS2P9K'F +MF%F.2<#'B+0M\A%2*4GA$(3@8_&C#>?Z/-NEXB!*"^OERX%6I"8NTE!Y$28E +M#?3$S?!];3@M_(%/;MUB?3`-T':E`QTYB%:&G\FXBJ[;70Y5V\:/82J`T&>B +M!I!N&67J=R-F1T\F*0``)/EQ'I4>LQ0T?_IDF]H4ASFOVAM7OR0S#Q[VXJ97 +M,8@Q*0``'```0`21>4)C>>M*@U?TZ>(:MB.`DN?LI````!P``$`%R:RH?1]2:'KLA8Z`=L1+B`C"`````$```#L +M(P``T!YM1V8,8OY0W,CL7*T'5[R5!(1ZKV*TQ]=1073&=E(P\^$]'A-DQV#/ +MV(6MJ3J*&P$D:8$8%O:KM_RW9:8ACM+?%TO@DC@)E?37MPY\G7R +M4A8'&:.5GM\32BIF9CS^%]5DT<2MT;8S0H`O````+P````" +M````10``N$_'``!`$0``P*@!`<"H`0(!]`'T`*0&B33E1[*A]'U)H>NR%CH! +MVQ$N(",@`````0```)PD``"`;S!$FUUL+O5M@A3Z_5=5$^L+UF2C/,5)9&;Q +M&>13.*S,U(Z(L@_I(^7`4KGXLFW)4-4<8(FI,RNUIAO<+9G2D0N=9GH>0^PK +MM/8K<4ACW76E1J=R.>K),*^/_7+^O;TB5MKIH&7>\[*'*%-[C!PS90D`.2'& +MD\/M4RVNH$<2MT84[`H`'`$``!P!```"````10`!&$_(``!`$0``P*@!`<"H +M`0(!]`'T`00'Z33E1[*A]'U)H>NR%CH!VQ$N("0(`````@```/PA``#@5@C[ +M/RHW09+T'VW^J=U-.BTBY3B!>,U&WO"M%1/(9ZQOSZ96?R6N3UB7$J]`NZK6 +M'RPG&/>\BXR87.KUFBJ\$6EJD?LV[;F`8AVBX_X"AO6HW(Q"];S#JP,GR64\ +MV8-EN616\-K9KS)&N5M.L.V(C.3ED/> +MNT%P%`[J`W?-#"/Z:X-=`0P0/J5K#B#JG.62**5.'&:EUK0 +M%6]JCJSF#"?)W+-7+!O2+;$'>I:<^'D<]5@);AALW4)""%JS4$<2MT8B]PH` +M_````/P````"````10``^$_)``!`$0``P*@!`<"H`0(!]`'T`.0&R33E1[*A +M]'U)H>NR%CH!VQ$N("0(`````P```-PA``#`40YKDT(:O%FY/@5/C^$4D]EM +MIY?.^`GTP*>EXCNU>(H>WK"M6MA$Q71RZ"9<\QWF#\6\2WOC(?L*>>H5Q9IO +ME#ZU6,I_(;0+G;^9$ZU1?./AU'"K'[2_7$WR3MO<]_?B;0.4[(:;C]?YRH?1] +M2:'KLA8Z`=L1+B`D(`````(```!,*0``,-^<#OI/NR%CH!VQ$N("0(````!````1PA +M``$`@H;=ZLQ(S$?M'U@<_&&LH8L$EO^9DK'+FY\6T108;@>,`U-AGK616;<) +M(Z>7>#,EB;%;P8I*KEED;-R"'0$EKR0S_[O[NO[(KE/+WF,2&RH]VOY+>;*X +M5$I#\0QS^YG97[\#%N41^.(\_<4@@2W-'.:)>F'[2^XV$%\Q_;C`%\`>P5QM +M9IM\8W=M'9L]9M=?^Y5LFG\L#U;S@J('1C4P7I-&K;>+,B37]"LSK@]W(DE) +ME<$A^2,.%*UQ]K:+V]MT#O):_B!F1.1'CEX&@/&GLU"PV]F(MCIAK=T7NI)L +MU*,G.*X]R"%?5D+Q&^\V4_BF**^<&;SVAOO4)HC91Q*W1D]$"P`<`0``'`$` +M``(```!%``$83\X``$`1``#`J`$!P*@!`@'T`?0!!`?I-.5'LJ'T?4FAZ[(6 +M.@';$2X@)`@````%````_"$``.#$D&IQD@!?^6,W`!\$(P5X1?:\@;8DC?:7 +M5,IMWQ0:RV$$529GKF^3+CKM5EUMVFUGH$$V3$D$E?[J/H!IN%1_Q\/N$G#X1T`HOU=* +MQP&)@\WVO71FX2%A]I6$1Q*W1@Y4"P#L````[`````(```!%``#H3\\``$`1 +M``#`J`$!P*@!`@'T`?0`U`:Y-.5'LJ'T?4FAZ[(6.@';$2X@)"`````$```` +MS"$``+"'5DX=>/!F[2>`)]UW0>W.:VU\H& +MT[5(VP;9%RH$LK-TL6Y-Q=P4MNA:()(Y^2%/B)"H&@[?J@L'=!+ZGQQ'(?;?&;$R/B +MC#'_1("(`V)BHPBDC,RZ^[L^+D!7;:@*]':<:J#>H0Z):!`63`=[0(651Q*W +M1E1V"P#L````[`````(```!%``#H3]```$`1``#`J`$!P*@!`@'T`?0`U`:Y +M-.5'LJ'T?4FAZ[(6.@';$2X@)"`````%````S"$``+!F;S9':>L(-C2K#`E$ +M/QAXQ:6M6QR6G7^13'6R[M@2HK,8M?[)'KCH!:DY+0)RA`CQJD#O#XC)MPST#%]RC;$_0O+JW*@!DQZO2ULR%%U%`83 +MH%4&8T,>;B`$\1U<8F4\YB/:<7NBLW/7_1P6%J>,J"P*:K[6$$=LF\M49$XE +M:A*M(3)E`HZ.HW]3FD>3(Z3O)`14(!L=1Q*W1A&3"P`\`0``/`$```(```!% +M``$X3]$``$`1``#`J`$!P*@!`@'T`?0!)`<)-.5'LJ'T?4FAZ[(6.@';$2X@ +M)`@````&```!'"$``0`)^@?(C#7GVK+%`>;AXN')@8M,S/$/G7EJ)7FPDY\O +M7:_6R],QGL;;+SK`B6=G.6E\#;.N[G`\<9*,6S%2Z*6L1882J45]][EF.TBE +MH+6S^Z7,.'HX!OA4,_FG+UJS2<^5L@5O4E*8+"BLR`QOY(NZ17!VO+TQ4Y[C-N[?..A=?M]+* +M--JI4I4JH]!QQRT"ELXRVY+5Y3?/TR#8PMI3V[+C!RS8_0&;?G6X(,-&RVI=LSS-X)+701L=E'$K=& +M,Y\+`!P!```<`0```@```$4``1A/T@``0!$``,"H`0'`J`$"`?0!]`$$!^DT +MY4>RH?1]2:'KLA8Z`=L1+B`D"`````<```#\(0``X)24F2H$6;JSD276`H2N +M@A"*-K%?6?EZA9*`S53U=*R\@V[9)&X8%2_+SB6C)C*,2!O`FK5(9EG$8\L( +MRI;[)`,4>P^$PH12Z#H\AHIR^:1P4GNT0NA&OMERMYM*.KB5PE]C5=3>$K[? +M-81A":_;^;R"WH>U/\\&Y""9+R\(8V^5*5V_=$Q&T?^2 +MHFIT]N8%AO"RH?1]2:'KLA8Z`=L1 +M+B`D(`````8```#,(0``L/B&5\PI;W"ZTBY3@`F(W6UE1W"A>C*1CM?X:'KZ +MR/[J/WZJ?I==@N=D#\`HX]@PDC<&@+/HW,W?SQ+^Y!YE,>HG"F=;M]FIZX=1@:'*;V^=V`SQZY&!7UFP20I#\[EN! +M^CPPI'QY?X='$K=&!](+`.P```#L`````@```$4``.A/U```0!$``,"H`0'` +MJ`$"`?0!]`#4!KDTY4>RH?1]2:'KLA8Z`=L1+B`D(`````<```#,(0``L`73 +M:262%6E8,\BA^O*@LTU*(`D"Y&EW>=@1%#<\$GND":C.P"O#(4*3C%4E`9/^ +MVS_;@/45N$;6O:<,Y`"$21^F!L%=WP +M,23$L>/3$ +MG*T)Y+4/!L1J!OB/B7LD'XBY4.M'!01W`,A9I/?)[/@ICLI'$K=&;O@+`(P! +M``",`0```@```$4``8A/U0``0!$``,"H`0'`J`$"`?0!]`%T!UDTY4>RH?1] +M2:'KLA8Z`=L1+B`D"`````@```%L(0`!4)48%K;J(,[\\(IPUBAGE,F/""^% +MR%()\U#3@#J"*@+D<=_F$AK+65+0Y#D0TA`#Q61*V:GU%U: +M75TF'M*5#^;:BE^[W09:>/S&)].BSS`5B1ENQ\#IG;_2MVLI1J_5%)=KUL#^ +MBRF9^/2_0&"T^^0%5I3:6`+*Z#8AFV)T:S"]'U&7]=]?V +M4;'SB.*=Q(<%'DGRJ[;%2-<(LY=ON,V'J`*2-V[^$1W6>]R7;ZAWU)J61"TQ +M,*\4`IR*\/^MMXUB+CO@)H0WS7J"U7Z<:8M*>CM%%PWG7/B<4`*EG8L`JDR)-2HSYC5K@:'APAR_>@(A\)6QULS+;AP6JU(Y_? +MZG/EO3C]5W-0C0'&UWZ_/9_PM=".5;WPQ>J+\*=#EH)AR#KQ>RJI#C$F[[; +M]LLB/>+5R# +M[$L@<`07P9Y*D:=Y<.7DG*\?F%X-&+[AY)Z3+P;;7=:YXU$H[3/I!\A"5V1[ +MD[Q%4CL=CI\>_]91%C1F?-X[) +M\Z&01$_7``!`$0``P*@!`<"H`0(!]`'T +M`&0&28YXYH'.NYVF37-N@5AH3@DN("4(`````````%PJ``!`R()!V[=R^TD4 +M#TZ-,>+VO.AKCKX1IVD`-DAWL5VVJ@F,S^GY$C=>PQ'+C48!BRA.X3N0.JJ@ +M#I6I,VF*1Q*W1D]>#`!L````;`````(```!%``!H3]@``$`1``#`J`$!P*@! +M`@'T`?0`5`8YCGCF@PM'4,DEC*)R4X6ZFY,@3G+5M6'>_L-Y/6_S>!@6"]P),6.*'KD<2MT;; +M;`P`;````&P````"````10``:$_9``!`$0``P*@!`<"H`0(!]`'T`%0&.8YX +MYH'.NYVF37-N@5AH3@DN("4(`````0```$PJ```P):FB:BHPIY[*%!64(3A. +ME*;>D2_ZFOGEA%C@8"4.WX.39R7&"Y-A0XX+VO9'$K=&(WL,`&P```!L```` +M`@```$4``&A/V@``0!$``,"H`0'`J`$"`?0!]`!4!CF.>.:!SKN=IDUS;H%8 +M:$X)+B`E(`````$```!,````,([$P79Q7#`"+HL\4V)]H`!3DR"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``L6O= +MXD_NO<:C>RRQOW!9"NCM&SN&>QZ&U*X7[%< +M9FO(T/%W&1NNE-U;T.O!,[P')#=EE5?T.%PA'3/%QN>AKCTI```D3@7&I)#H +M;)FQB$`DXNX&ENO[1?S$9,,OSS_/"#>0&;LI```<``!`!!QOV4Y/Y_N!,R0_ +M^?.R(!S3Y5XY````'```0`6[^DR'3::;'M^'.E68MKG)?*#D-$<2MT;?A`T` +M7````%P````"````10``6$_<``!`$0``P*@!`<"H`0(!]`'T`$0&*2>4CSQ! +M.,QT```````````I("(@`````````#P````@``!`!@````'#K\T[7@?0W#3I +M)=02=--MHB\(]T<2MT:LE`T`N`$``+@!```"````10`!M$_=``!`$0``P*@! +M`<"H`0(!]`'T`:`'A2>4CSQ!.,QT```````````I("((`````````9@A```@ +M``!`!@````'#K\T[7@?0W#3I)=02=--MHB\(]R(``'@```!T`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``L6O=XD_NO<:C>RRQOW!9"NCM&SN&>QZ&U*X7[%<9FO(T/%W&1NNE-U;T.O!,[P')#=E +ME5?T.%PA'3/%QN>AKCTI```D3@7&I)#H;)FQB$`DXNX&ENO[1?S$9,,OSS_/ +M"#>0&;LI```<``!`!!QOV4Y/Y_N!,R0_^?.R(!S3Y5XY````'```0`6[^DR' +M3::;'M^'.E68MKG)?*#D-$<2MT8.N0T`4`$``%`!```"````10`!3$_>``!` +M$0``P*@!`<"H`0(!]`'T`3@''2>4CSQ!.,QTQ_[\SY-)>XDA("(@```````` +M`3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"```` +M"`0```(H``"(``(``"">_96?2VQ.^H6O+<)"-^.5L6)5-YF8*)871I0:2P"2 +MZG1S:O6\6G(:9CFU?B4Q&Z>:C6D:.%+$6=#<*F/;8/(O(3"#K5>WXX8645H4 +M;8#.:WWN-3,!L)$)LB!O437Z\M)=L<<@;[99D_A+C>SZ)\Z(W]$%E +MN&6OVUU[*0``)*/E![/H&IN`.!8LB4BD+C6FH3)(U)A4>B;K..RG:4DL*0`` +M'```0`1""OQ#/@V!T@X7Y35?MVT5H.P<]@L!\:9Z1`>FZCFQ\M;"?P3=[9(NPT +M[O$G=3)MVLFUOUX.(I+.5"UG%7G;JE6Y=5,+O1OZP(\I`_C(K%:=K4(`;>`% +MRHF?"G'L;B=?=:B8,&I+R?MK\=AJ$/^1C#:9/+-!:CY-;\;*>QE.6@N<$ +M8(DFAAB[K96`VAT<5S3XQ,S8VC5=YTL!:0YI^YT$4]1)(5E$2%^/K=!#)][> +MS>DON7*?QV=4#9'?:?^,"$H*<$VN;D<2MT;$_@T`O````+P````"````10`` +MN$_@``!`$0``P*@!`<"H`0(!]`'T`*0&B2>4CSQ!.,QTQ_[\SY-)>XDN(",@ +M`````0```)PD``"`^]5>5JU0&'Z*,@<$K2TS7(6H-,`4B6D&T5%W@69M1+67&A\K?JI>)'0G +MXE)^:J#V_YWB$*L5-%04CSQ!.,QTQ_[\SY-)>XDN("0(`````@```/PA``#@;"YFADP#%)PR +M@Q]:D?:?JV[F])BI`PL[6/82NV?]3Z':5_S-(%WV^VJY5W!5\4Z/8!MQ@257 +M3J,]BN(FD",TF_R>?@@];NBQCFQO)#R$RMF!1X=.M>?&%[8K2+NK91??9'A4 +M=^V%"VQ;JN1-N8MG%QNW;\5'%U+>^`!MR#O:!=\D/)NS1^;QEGQIMOX!6"ZP +MCH>[P$29"018XZ8'D)F_$O.Y'=>G<7*Y-^D'^U:-=+`_3_2]B0_[2.:O3.@* +MK%7%X$\M3N"EZ4!2?84,4CSQ!.,QTQ_[\ +MSY-)>XDN("0(`````P```-PA``#`Z?R:'V+2F-;W32`/'X5/3DLT9Q::V4&X +MHLDCMAEO.D2"./5@@JOMBAGF)!ZI&9NV)-J-@PLPUFPSFX!VGG/>:;5!`P!T9O5;#CT@C(I1R=%#CXR9Y1XI".'B?:@ +M/^49W/^-[T18AL2XF>OZH1N3$:I1Q*W1AA1#@!L````;`````(```!%``!H3^8` +M`$`1``#`J`$!P*@!`@'T`?0`5`8Y)Y2//$$XS'3'_OS/DTE[B2X@)"`````# +M````3"D``#"WU5E\]\*I4CSQ!.,QTQ_[\SY-)>XDN("0(````!````1PA``$`G;D0 +MR">-T`.F5X"YH1+UE/]X3O&7233[7_Q0[-R?F#S +MO62641O4D*SZ@Z2"R.,?:-H5H)K322)R]Q40R(&4'A-SS#]">KY&$JR5&QHBZ=[N8J +MR`WT7=E$,&1A1)16)$(XALJV49X.`-M!1Q*W1IQW#@`<`0``'`$```(```!% +M``$83^@``$`1``#`J`$!P*@!`@'T`?0!!`?I)Y2//$$XS'3'_OS/DTE[B2X@ +M)`@````%````_"$``.#L]*]YEDQMR`LYG'[T]&N?:&68['=P4?03RI928VKE +M@569>T!WW^TCZ:5_0!?+*NG3"F;L'T(*K6Y/"F7>BH?E\P!#(4G*-MH\F*ZC +M>AROY87?WLW#)@)'F4GQ.Y1$OJ#@;\X?7?G&<`&]"GWHP2#\^E532Z4K;LN0 +M,JZCU,]/+-&.DOW1KGZO@CS+,R7$"!?4&%$*G9V$*#1 +MT6-#953G:/(D1Q*W1D6'#@#L````[`````(```!%``#H3^D``$`1``#`J`$! +MP*@!`@'T`?0`U`:Y)Y2//$$XS'3'_OS/DTE[B2X@)"`````$````S"$``+`< +M;+\JT.9D&[G$5)538M'XE2U]8L=F#25@])*,)@[-W\L4:.)]^5*"6\)\B8LH#XS@+[9Q(X88-LUUHE76S`^&#=H^20&+4']LR,(2)@/\<9`SW@[>+!WV4 +M>\B0-;2,4T0X5=7V('8V\?S9)Q(9(B'C7BE'W7CK5K16OS3!BEO`, +M2VWKWD;&\);-A-8X9^26ODOK1Q*W1A;'#@`\`0``/`$```(```!%``$X3^L` +M`$`1``#`J`$!P*@!`@'T`?0!)`<))Y2//$$XS'3'_OS/DTE[B2X@)`@````& +M```!'"$``0#M"SRG"-8#B4LD-8$1ZQ`:C'8-QFE9J9*8P22>Z02!^5NS/0=; +M(OL_JE6YFE';)._0?H4E6[6\Y,+\1:R-MU3GQG6!1RYNJ+9:6&8Z)IJW<_ZU +MS`_%-AVXG#+KLLD84;X"O%$5R==@J_=_3+DI"B$H9M)&%TZ0^WL7Z.%U'4W3 +MMA'&I#N-S3WUV8X`$@7[M'$K=&5=(.`!P! +M```<`0```@```$4``1A/[```0!$``,"H`0'`J`$"`?0!]`$$!^DGE(\\03C, +M=,?^_,^327N)+B`D"`````<```#\(0``X#SQ/%D/G!JFXJRR2R[W`-GHR""2 +M@R;ADH-_`9@WIKXSS]7O='B"]Y`5!1;I[80WHEEDL;>LLV&,\R4GO0T72P`L +MF``ZP]8:(*RU$?XH>SK!B,_N;;D";(81+MY;0FEW>16;*RKT(L-G- +M*YX..(&4_[T+!;:L7/C5L^?NQ+6(*[P_18KJYB'[_QR-;2IK^V!2(:IW%REF +MGFMR&D8_(W2<$KFB\9B\9OB>.4T"Q;KU!.\VL+E\\@AM&G\V*RH((M=T";JQ +M!UX^;?9@_<[CR"!,P=A(3M'\@*='$K=&K>(.`.P```#L`````@```$4``.A/ +M[0``0!$``,"H`0'`J`$"`?0!]`#4!KDGE(\\03C,=,?^_,^327N)+B`D(``` +M``8```#,(0``L(H$O'H:KF$YL\^2,9C;8WV7UK';1DV9X!YQ;V9D>O_)]'/] +MQGCNO'![\T%+P'.(1OUW!I+N;*>-W-;Y`@AI:[8L8%!:'7]2?KS'G3\.>K5@ +M?X^%%EV)>ZAWT-IGM^!^8$7P?X@E`JEOE<%E`#RC7K!`QH%._47<[=[#'H/1 +M\*GVPDARL$V=K=OQ_%6L\]3PP5(G-]S@2[#?E"6M7^N&A4+^-ZMZ)MF@[Y`: +ML*)'$K=&N`4/`.P```#L`````@```$4``.A/[@``0!$``,"H`0'`J`$"`?0! +M]`#4!KDGE(\\03C,=,?^_,^327N)+B`D(`````<```#,(0``L"&"$8YX8(W( +MP/L?#:DWAKV[@$"H'^VI=E?V3DQ?)I%!>EJ=+2,Q+Q')>TL>P\`7`M^]17-1 +M:C!.EBHX62D3@!7U_%14*X2\[_YL[@@F^78^(H,P-?.ZRE9R8MBPI],E>Y]8 +MU99AQ7>)`)YC9XH[W.2ZAUJS;R<\2!J/W)26L+O0&_X4WQ]K:N`5,H=KEHQT +M_#A9A>#EFEGCQ%%57U.=F$P7PK]1+*( +MCUD@VG/P;38<%&J5:?:X7W`^/DR.A)X(C@XNB48TYEG)1^3@H+7HQ:)+R&'( +MFN`:-X@T/%L'!3C*S]Z3XIZ*\P?-;1`??&58M*@]Z-AP=1[FB(O+J^R*02H# +M="-)M=XB]0]A>R>Q4Z4H$IU.65N5>5OQUP"TBBK1@N#)X?*:=2F+%DB>QC#@ +MU0!0V9#X=H:T`CO)-*4WTO.L4+1(^>!'903*2^=]\8__!G/GPR.TQ`HZ5Y!'"_;@@("]_(6R0X>6:YW-4?2!*W1F\>``!< +M`0``7`$```(```!%``%83_```$`1``#`J`$!P*@!`@'T`?0!1`X6A'2@ +MOT*_*LW.N&?!P8RXBY5?X90]3R"^J6R@J-U_S2K!WROH?>H,'7>U$<=]##1% +M&H34*?BR'3'F2C'@;#GM'_)F@U- +M^A[JI10`V1\S_I"&(&+!LCD7\H( +M0+YO1G4`:RI=[+_C3::UV1S,:AE7-J"`4GYJ<=$_Q``!`$0``P*@!`<"H`0(!]`'T`&0&250N +M,*%FSMQ8.WAY[)_JAT,N("4(`````````%PJ``!`[@\Y%P[-;W/;K[G%<=QH +MSL`K2BI/'C&S^5N"(%S&0&;3!QUSP>>D&"O)%I+VTR;2%2.6@5Y).TJG7[4T +M2!*W1IA1``!L````;`````(```!%``!H3_(``$`1``#`J`$!P*@!`@'T`?0` +M5`8Y5"XPH6;.W%@[>'GLG^J'0RX@)2``````````3````#"AG@4'R.1C8(J- +M)JCPV)J+^NU.9SO,];>$0M])]&:6^Z5]?!?4@2MT;G7P``;``` +M`&P````"````10``:$_S``!`$0``P*@!`<"H`0(!]`'T`%0&.50N,*%FSMQ8 +M.WAY[)_JAT,N("4(`````0```$PJ```PPW&15JAA1.J9J=01>^C*;/8SD'?B +MEWJY#*[E($K=&0VT``&P```!L`````@```$4` +M`&A/]```0!$``,"H`0'`J`$"`?0!]`!4!CE4+C"A9L[<6#MX>>R?ZH=#+B`E +M(`````$```!,````,(=J'KF*G?$LK21,E,0P]8GF<)H?UVAT!IRHX%#=JX\9 +MV,6@(VK.[,!8R=?O2!*W1K]H`0"8`0``F`$```(```!%``&43_8``$`1``#` +MJ`$!P*@!`@'T`?0!@`=ETG50%C;\9?H``````````"$@(@@````````!>"(` +M`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``]J=066IGW6-P +M#?K53-:BW=,AHHC!OXRTM'[NH9#6-W!SSBRD*Z3@@/M6+2NNQP=[Z\RFBSO0 +M,]QXI&FBIOJ?>J!\6ZSIMM"*H@WF;,4:]0#-6+V70V7KDO*T\>WLXZ02WS`) +MX,%,]3.QAAQV;&65UC:2P"Q@$K\39CNO/_+._S\I```DYC7WG!SO+4[LW0EF +MF!V1LXR_8,I_/.Q8W>EKW6GQ!/(I```<``!`!!8\_4G412__#L.AQVBJ%;I; +M+<[P````'```0`4,K;)=I;M/O\;Q;R[&F3!WQ';[-4@2MT:C>`$`7````%P` +M```"````10``6$_W``!`$0``P*@!`<"H`0(!]`'T`$0&*=)U4!8V_&7Z```` +M```````I("(@`````````#P````@``!`!@````'1+D-?5CP7]`K\2^V,'NII +MSN=:]$@2MT8?B0$`N`$``+@!```"````10`!M$_X``!`$0``P*@!`<"H`0(! +M]`'T`:`'A=)U4!8V_&7Z```````````I("((`````````9@A```@``!`!@`` +M``'1+D-?5CP7]`K\2^V,'NIISN=:]"(``'@```!T`0$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``]J=066IGW6-P#?K53-:BW=,AHHC!OXRTM'[NH9#6 +M-W!SSBRD*Z3@@/M6+2NNQP=[Z\RFBSO0,]QXI&FBIOJ?>J!\6ZSIMM"*H@WF +M;,4:]0#-6+V70V7KDO*T\>WLXZ02WS`)X,%,]3.QAAQV;&65UC:2P"Q@$K\3 +M9CNO/_+._S\I```DYC7WG!SO+4[LW0EFF!V1LXR_8,I_/.Q8W>EKW6GQ!/(I +M```<``!`!!8\_4G412__#L.AQVBJ%;I;+<[P````'```0`4,K;)=I;M/O\;Q +M;R[&F3!WQ';[-4@2MT9TK0$`4`$``%`!```"````10`!3$_Y``!`$0``P*@! +M`<"H`0(!]`'T`3@''=)U4!8V_&7Z5/;-:$@&3YDA("(@`````````3`B```P +M````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H +M``"(``(``%\I`4!M[>FW!;(S^H5(47'"-1Q;-@'DCH:F-Q5#QTYSO2A+*V40 +M>W5[\E=J3=DL8\3*]@]!+>^!5AZ"U!]BSUH"6;V:%D9VC-UYL:=[+/;/II?(I]_,$C`ECBXLYV;RJAS\K*JMNR(SN\VE3LZ +M*0``)#1QL/KR=!V9+H:VWT1!9C[YH91'O"_I````!P``$`%$Z]_,HLL4%D5$EH3L.CZ9PTJ +M9^I($K=&L]P!``P!```,`0```@```$4``0A/^@``0!$``,"H`0'`J`$"`?0! +M]`#T!]G2=5`6-OQE^E3VS6A(!D^9+B`C"`````$```#L(P``T)=;W]IR6S-V +MO@BFH(2QZ`T!8^]U#:.M5%@L;X;Q8/M&V08:?@?,H>N7IW_1NW[GL5=%1&G( +M7`GC11`1^@Q3[>)4J7P/900(HRW@OH"$P,5%`FX6G!T90X)^)6#.B4YT_UZ(.,UJR]%LP6M'B +M)%^7H5-,:EJ`^AXKS_7D94]*#9"ADZ>D;>):^Q8X^&@ +M,QZNII@R-+1$`"O*M\Q?74@2MT:E]0$`O````+P````"````10``N$_[``!` +M$0``P*@!`<"H`0(!]`'T`*0&B=)U4!8V_&7Z5/;-:$@&3YDN(",@`````0`` +M`)PD``"`9G+!>Z5BT8712#OJ+P1:/[BC(]'5JE7E5*E:&R&0#1($T5,.[P?] +M/N#TX?31D!;J4WZ]8E+KOD1O8NXJ.,1/%H.&#FSH)W\LF04BWV]=AJ#;:+[$4@2MT;R +M$P(`'`$``!P!```"````10`!&$_\``!`$0``P*@!`<"H`0(!]`'T`00'Z=)U +M4!8V_&7Z5/;-:$@&3YDN("0(`````@```/PA``#@V3I^VWB9:@^F@*;?JOX` +M64D'F&M$P)+3&^(>(KC;AZ]J*VJ.`G5"L.?'OC9@:,$V6OM^$G0]A0[H6JE_ +M!>GB:TCVI<&:T"R2MZD2B2,HQD\[(.QYN2G@Z5_2>BHHW"9F*#C.]/[2TXD' +M'J34PG-904&A!]&G^X]9>O3^1?"C(:;?N`0(@P);$@2MT:V&0(`_````/P````"```` +M10``^$_]``!`$0``P*@!`<"H`0(!]`'T`.0&R=)U4!8V_&7Z5/;-:$@&3YDN +M("0(`````P```-PA``#`$HRAJN3"VX$_P/AB(O[UAO8]'SJ:'L^^)`V(YE_Q.RXLLHSPUG`DZ?RMHTA!6W*6XT6QXKB0[L>L6&XP,[EVA +M>O<&]>C%FAY)SQ=Y/]8Q%0LX").UQ4]($K=&,BH"`&P```!L`````@```$4` +M`&A/_@``0!$``,"H`0'`J`$"`?0!]`!4!CG2=5`6-OQE^E3VS6A(!D^9+B`D +M(`````(```!,*0``,`QN!)_)O!:D8IX],_**ZP)0%SAKQ9\3B.%'Z^#FEFH/ +MR$2J^:B-[!HI55"-CS>D2ARLCI;M<1D#JPKJN!=*0V(`F1`HFW,+7)',K +M+^6.,)J'X"YPC(!T`:=9V-Y.W#%R\'I;LNN6&H@5J+]:\WHN_$;@)S"RK +M-3_N/AS!31)[6':P(*M#29)$FJ7M9TZD>B0SOA-W73K>6Y347PQ5C3 +M/AQ=8#O%1U`N+W/*H,Q'LX>_1AYSOH/J!VM622FRU^*T.`YA[%J.#Q,5%V16 +M:=?RY(*E&@G@G(#W8K)-5GH[!_WM!Z%.7T8PQ2`TKXY?@'72%=D_2>5[.5'G +MR!8GSHD'!(;1E@%W00QH,Z-Q5%-$.Q&CU)ZZ$O'+H05]_QW:"ADZD1XR/:!+ +M8'FUD"=]N_2!8/\83,*F7S#V2!*W1L-M`@`<`0``'`$```(```!%``$84`$` +M`$`1``#`J`$!P*@!`@'T`?0!!`?ITG50%C;\9?I4]LUH2`9/F2X@)`@````% +M````_"$``.`R5-;-5`*-+BL!`*:_"Y-"FP*..&E?K68)5'9,IL(LCX0Q")L$ +MW32VL0WS9S#SOGE3L(:/2A(KG'ED>#`.6`/<5/3L)KW>I"1=K3)NI1W-FTRC +MW/(;.TCETF/RSKY3QE\.,,[Z!B1PQ2!=)OCRBT,?AG>S%P,$N?/1`Z2J$C'5 +M[\)>GV6=E5.3.-&A,:0^-4@>UVYUZ#,J#_=<6JS)9,DZ4#E8;<6RN4:FYOZY +MU+1?VXT/1D=G)`AM]#M;N1+Y$2!6&(IOI.N.>XE:ZO3TZI*:+8:P.XM3>B:K +MTZAT2!*W1C]]`@#L````[`````(```!%``#H4`(``$`1``#`J`$!P*@!`@'T +M`?0`U`:YTG50%C;\9?I4]LUH2`9/F2X@)"`````$````S"$``+#<23\'%LYQ +M*]ZL@W&OC'3"T1UY6MJ] +MC=2K@1(C$EQS$65_#&E]1\I;ME20>57/[VR_"P\K2!*W1M"?`@#L````[``` +M``(```!%``#H4`,``$`1``#`J`$!P*@!`@'T`?0`U`:YTG50%C;\9?I4]LUH +M2`9/F2X@)"`````%````S"$``+!.0!;Q.A;A$FOLO.SR3G:T;S/0:_0WY5[; +M:).[7P"O^^VD]E9K@;9IP+S"G5D1:ZUV=YGSZV#]`H1'I^6A;[M)$IBT=!7S +M**VL^-?3=;>E7%4T-3]D;@4>^0L,>]&"5([OZF8$'B\X\,ZT08_S.343D(Y%UC%LM** +MI@7XB2!*W1D*\`@`\`0``/`$```(```!%``$X4`0``$`1``#` +MJ`$!P*@!`@'T`?0!)`<)TG50%C;\9?I4]LUH2`9/F2X@)`@````&```!'"$` +M`0`-.T.V'-Q3>6@?3502OJY)#J+O/%U+' +M9W7(EDOKM1/LQ?2L<11Z^&RHNJ[\K1=KC'"4/9X67`T8EG5'G)HR!@5KC@UK +M*YJ`-^*H0J]DOS;7FDG`R.,5-ETWB05K?.7;RA_%U +M[_G6ONI25%"8=[T=*7X,BT_9)Y_;KC[7'^5]Y1$\K."RD>2I%PK\IFLJI>[*YD]>PFDR-!$ +MDDI7Q3O=I55S`YP/N:*];#:!ZB3\(HWMGYI=CO6P.(U=/M:EV=KOP?'VI0TD +M'SBX/I3H^K-;GN^\J+*.=19$_<2K]:#CN7N@4;%KL(OEYZXGC;-XK4CEW!/3 +MILDN'EOES^=;*^4BT:(NX2C=:6QQMX6D`-YQ@TV>K<`A`,"^["@N`9M:`&B* +M*WN+^L2'*S/$ONTS;99*<'_6P)7]!S4T9W'<)K/Z6H7;(Y$YT@5I'#=S%D?= +M-$`NU>I +M)@*2G*HM./0-WI$_$X6K184<^QMZB]0!Q,TX8'&;#0Q@%4'-^ZVT+T;01($K=& +MF?L"`.P```#L`````@```$4``.A0!P``0!$``,"H`0'`J`$"`?0!]`#4!KG2 +M=5`6-OQE^E3VS6A(!D^9+B`D(`````<```#,(0``L-S=DM/RH/*;F59EI +M6F.AC)L:,?%HM')2CU>="B2&(=`!SG3\?SWK6(?&Z;T=,D"S?>NG$ +M.IV';86E8ZZ&(]]`ZT7>>Q@G&X``9A!($K=&=B(#`(P!``",`0```@```$4` +M`8A0"```0!$``,"H`0'`J`$"`?0!]`%T!UG2=5`6-OQE^E3VS6A(!D^9+B`D +M"`````@```%L(0`!4,G>1O(8!/8)\0-V_9J15>C]5`/A*HM%1EL=$;!JJ,$8 +M-A#[J)`GLLYD@XEZ>8>HE!/!$^9LMZ+>"1PV3@JUS#NXO%7^X\VG)L?$@#J, +M#!_BJ]4')RKW'FVD6B4T;?%7(QMF*3))I:6/=9#,,IX!9XHBZLJ[^2UI#SV& +M`;(RBQ.W@G;%RZ9C92ZAP8U)&L;/+C\C0'_`2A)GY!8X,7O/?\(:Z^\!.[FV +M.^_39"A\YM'WWE^5ZW8H,[_Y&A+FCGZMB\V;8:^`!!7N%BF'YYWO$=8FUX%Q +MFEOT4N_4GTFJ/0/T7RMY,_^`L>^+&I[7B![P(RN`-:W.6UW;G77%8U'HZ7QO +M"@8%9O(/`MO1'Q,GJ.>T?=8M;NT##1:W)DU!RI!9QV8'Y8`15+.05B0ZJGX< +MR/^0PX%=Z1,!18($<2-;6K*/Z#S+`E*SWBP%\F6Q2!*W1B-7`P!<`0``7`$` +M``(```!%``%84`D``$`1``#`J`$!P*@!`@'T`?0!1`Y`J*IN]#W2-\-0B5!&246<]-<5%[T +MT%ZXUH])]D0-%0;98B]V-MA2-;\,!:L:.6QYH4&<,CR"P-[0&L'H8_-40.-P>FY*JW3)7 +M"A5)$K[XM*D/YJ04+T>?@.MQ;D(+9VZ\U4R;])]G:S2Y(N_Q;RJ&,;4`V;"M +M*U%XA"!,S!Z^>R;-8(G!T5&2F=WS(6WAA[%5?\7D0(._4Y.M^TKEST@2MT;&?0,`?``` +M`'P````"````10``>%`,``!`$0``P*@!`<"H`0(!]`'T`&0&28%M,IKY+,24 +M5ZV:.@'96,4N("4(`````````%PJ``!`0[$;LEGW'%&<,RI33BS]4#WF=F(N +M5GW.6K.?<"5>;LG&%$@.#VBIE57;01ROU0`R([9/,98I/(/)I\@F2!*W1E6) +M`P!L````;`````(```!%``!H4`T``$`1``#`J`$!P*@!`@'T`?0`5`8Y@6TR +MFODLQ)17K9HZ`=E8Q2X@)2``````````3````#"DB/I]\8NF%0SM="AA^%H< +M*$M42$8CE&+RX+SPQ`(2K%TN/V;IEU/1:0C&K$@2MT;?EP,`;````&P````" +M````10``:%`.``!`$0``P*@!`<"H`0(!]`'T`%0&.8%M,IKY+,245ZV:.@'9 +M6,4N("4(`````0```$PJ```PI$)XH-@QT,.3DJ@8U\W:A?Q`RB<[[T,KF+$X +MP!P7UF93PUF,X$!L_!UH6%I($K=&"J4#`&P```!L`````@```$4``&A0#P`` +M0!$``,"H`0'`J`$"`?0!]`!4!CF!;3*:^2S$E%>MFCH!V5C%+B`E(`````$` +M``!,````,+CPI3$;0:C@Y!M!$TJOKB::F.L1%'$LI['!Z!1H?U68[L@>/*3/ +M"(``'@```!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``U3!=;G[E*RGX>28#PCAE +MB=?#[B4&H@UZ/;UE:NY3UWCEP98R<6`M.\./\ACTHGCXMUF(L/9@;[(9'VJF +MH,-PO?7%/F]5AO5(+NF3J*N=%*`POX2MRPK@0`7````%P````"```` +M10``6%`2``!`$0``P*@!`<"H`0(!]`'T`$0&*3(E(OL9=K&A```````````I +M("(@`````````#P````@``!`!@````%TW4'7'`H4@2 +MMT;&O@0`N`$``+@!```"````10`!M%`3``!`$0``P*@!`<"H`0(!]`'T`:`' +MA3(E(OL9=K&A```````````I("((`````````9@A```@``!`!@````%TW

4'7'`H2(``'@```!T`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``U3!=;G[E*RGX>28#PCAEB=?#[B4&H@UZ/;UE:NY3UWCEP98R +M<6`M.\./\ACTHGCXMUF(L/9@;[(9'VJFH,-PO?7%/F]5AO5(+NF3J*N=%*`P +MOX2MRP*MPA("(@`````````3`B```P````+`$! +M``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(` +M`"G6-#)J%E3MA&\3`?[+<".X=3,8JZ*0)8V9]OQ)+$#NN*0``)&ZC +MUH$L>58C\60XV$^ +M%(VCKIO1(NO.@8R.BP```!P``$`%_8&4`3/^:=)GI04\2#38[)%O^-9($K=& +M!A$%``P!```,`0```@```$4``0A0%0``0!$``,"H`0'`J`$"`?0!]`#T!]DR +M)2+[&7:QH7$J+%YUGBK<+B`C"`````$```#L(P``T*]VWTWZ(Q3C793?HBV:J/4)3[3K2XO/VVF[P:I_FBGN.C)9NKWMITB%X-D@8 +M:^;7I+&U`)0!2TEF(2?$F@)#)5!"@8Z4?X1G$<5N>WU,^UCPH4P$"XJ)(U_T?LN!AF[: +M.X[JN$@2MT;:*04`O````+P````"````10``N%`6``!`$0``P*@! +M`<"H`0(!]`'T`*0&B3(E(OL9=K&A<2HL7G6>*MPN(",@`````0```)PD``"` +MB=9[H=L]JF?`%@W]@\G7P+_E37("?@XH;J?$([1=/YH#A6CIT#7P^ZK:KJ6G +M]4ZBYK0=/!C`*W_6M$""P#3LHV4@U+>-19W>S@5JN?P>FM:UE)=3@GZ4MPZI]=N>1\%#*>*:3*K=POU7D@2MT8I204`'`$` +M`!P!```"````10`!&%`7``!`$0``P*@!`<"H`0(!]`'T`00'Z3(E(OL9=K&A +M<2HL7G6>*MPN("0(`````@```/PA``#@^0O@RCA.+?)K##,]"4OK;T=<3]P[ +MYWU/I]3D/AA/)8]M*3&+G9EZM7E0=\1'5)#@FQ,?3GB%A<(_8F:SF3QF8+N1 +M*:;J6:E/!\.!P.DIMR3Q,5RX]MC33UB((X6UHVG$"878@)8`QHWE_!.M$MFV +M/4STE+4YCZZ2%#B;2Z`)DGC31M+&0.#]44BLF#3$AHXX9-F+;#5-]Z1F,_F4 +M)WIBO0=(SK2PJG#_D'57&K=A*T'D_8,=#*-LU2B$JU=$F8WO^]/E).*<\%Q9 +MOD)>KW-:(J!#7)=WT.E4EWBJ,$@2MT9T5`4`_````/P````"````10``^%`8 +M``!`$0``P*@!`<"H`0(!]`'T`.0&R3(E(OL9=K&A<2HL7G6>*MPN("0(```` +M`P```-PA``#`E1GYW1@&;AH,Q3NU*OW[=30)J/NW\1\Q8RTP@(BDP\\]J0'2 +MR0)M\L.Z5(6X1%L&`%&S@:$.7(!XNB)AD-(1Z?!-_6NIW&C`FU@\Q9W%K/LW +MB%R5J1_KL!6U@>"\K$#Y9XE($K=&'E\%`&P```!L`````@```$4``&A0&0`` +M0!$``,"H`0'`J`$"`?0!]`!4!CDR)2+[&7:QH7$J+%YUGBK<+B`D(`````(` +M``!,*0``,,!"V=SA)CJ+DUL>?J&U`^,BI$#EL<%VT2*T478!$EK,<"Q,-:I+ +MYLLYY,?R2!*W1IUZ!0!L````;`````(```!%``!H4!H``$`1``#`J`$!P*@! +M`@'T`?0`5`8Y,B4B^QEVL:%Q*BQ>=9XJW"X@)"`````#````3"D``#!\G6'A +MK@@LR/UO3,&P(6G_!?_I=UP\IP75S4FCQ@N^VE(?6;OA3Y9:>]<8\D@2MT;E +ME`4`/`$``#P!```"````10`!.%`;``!`$0``P*@!`<"H`0(!]`'T`20'"3(E +M(OL9=K&A<2HL7G6>*MPN("0(````!````1PA``$`%ENM7#I'YX@@54_&Q=0X +M)LZ14K*6P.R\SLWUZ]=,A%PUY"MJA1`9A]79`3* +M<7-02O[F#-P#\E'W4S)0JE\^+\TP>''#YX3+/]07A>T"Q/L?6MQ"H!;N*RV, +M3CT=]PN-H;"D6UTQ,;AIH-G@SDQ3JQ^5'_,HW]Y4/EZ)I_NK%/?.DY3O@5FS +M_9IN@%$2C1;YI>AUWV)B83-DM#2>E4#:.MBI__*9Y1F=9XJW"X@)`@````%````_"$` +M`.#@&IY;DDFIM\(A^1?BG]E]2]'J4A#,2;&8L3KBI##%K=]O(OE2&!E(!/)O +M2*51CG%,8$S]K63FW6):B+=X,:M+#+5+$_&U%7_Y6G8G@MN3'&#`:>N\_!9< +MN7D)`+_>.I(M%/C+D;\.QV_44PWU-+1;A^>8*(A9R`>Z/ZTX\$9IDZT?3^-+ +M`_K)K67+&(LN9@^SYA]MK%3^0YD:ZZZ*1Q:(PJE6C\0YM(B-SX4]KOLRMODB +M7$+X_I<'L?)VXO_*SLNP.#`]RCV+C*G$/`C-*G;D"+2J&XJW5Q?U25Y"2!*W +M1OJP!0#L````[`````(```!%``#H4!T``$`1``#`J`$!P*@!`@'T`?0`U`:Y +M,B4B^QEVL:%Q*BQ>=9XJW"X@)"`````$````S"$``+`UV8T'(DCF$\YP+0*+ +M\PK'MH*EPW/`4O%'JE2@W0I:%G`V;/I";+Z#D5EHH3<%.R?1OG$A%LM2?-"6 +MIM&E6HCGQ4F599X1R6"U:+I`.HK0=_/5O'$F(JNKI$^IX@$4AS3S6-ARF.&[ +M.US'&U(_KIB2M3=U6;=AGT1LD6>]N3ZA<*'CRUF?B]?,AO$^OGT:F5[?W>8, +M^[1F3HY&-#$12E*N5YW_W7)+DE-YSH.,2!*W1I?3!0#L````[`````(```!% +M``#H4!X``$`1``#`J`$!P*@!`@'T`?0`U`:Y,B4B^QEVL:%Q*BQ>=9XJW"X@ +M)"`````%````S"$``+!AXLHH.KOXIK'VY31GH38-!?:A&/5'-$IA[ZLTZLY: +MF`>YK)D/_:T-=9@EEH!B_\.B+/W;P=9XJW"X@)`@````&```!'"$``0!TW5,] +M:TOH9JI01&BJZBZ<8WY*#&.';Y5A)%Y@@J03*TJWJ].A4*40YON@"+)3.!IM +MSSZRW$PGZ&.##H0.&(3;/`<>Y^L?G[O=A04A5:W!&^1<)F"IA]J'0,_C^#2] +M:3`!;#^@.6+<8ZI2"AS11P@#`$+LJ_3O/&/:+]CVUHY:X&ER0ES^./^R1=*\ +MN!G,?:9>#@C^A#QGC#?GI:K#RTZR/LCN\(V5+$PYL`]BYF$84PN$-^,`J`7X +M"D(Y23YOF@531(]Y)^5M;5M+V=(&=[:.=/]\D'#^U.H^@3X1=I9(FIDYVNG5 +M`E(5.K17_\M'%4T`.0RA%J"*(>#,3]1($K=&$OT%`!P!```<`0```@```$4` +M`1A0(```0!$``,"H`0'`J`$"`?0!]`$$!^DR)2+[&7:QH7$J+%YUGBK<+B`D +M"`````<```#\(0``X$P$2HP;XP&MBI-IEZL0\,;H.74=4CI%>4N9)R0H9W3@ +MK:+M!&&R'>?,N*!-J@XRHZT`%P`MQ+9X&P&+VF7;!1Z`CRPV$Y49,B3&F6Q- +MT_J+I[8S`J8S!.+)K(P2/.UF8RU^#80_X.'"3+'X\^0WRELPY+'?!7GMH?G` +MY01#\=Q&+O$<%=EX/`3D1K5&2W+EV.#\*`P>'# +M]).K:?:-4.(`L*[NDACW>*%A]_*B'21`M--A>-8MU*=V=,K4;J^@P\UV!@CK +M#/KV(E32=15($K=&J0P&`.P```#L`````@```$4``.A0(0``0!$``,"H`0'` +MJ`$"`?0!]`#4!KDR)2+[&7:QH7$J+%YUGBK<+B`D(`````8```#,(0``L(@Z +M]"D^@&U@U%D'HU<[7AIO$/`2:_)`6RI)U_49D;Z`($Q"G\=X(.Z?'9,:DDV] +M]H[TW-F#SUNL@K(J/3! +M=$CVC)&YT>B96Z#2+P3KS;F]Q +MU70D0ZEV[T$#%3-08A=LI/#N7']I*^$%I4T[22L>X\+2M6^C?3TB)76ZLH6T +MI_\O9+"LW8/!&J=:_$9OM-O2?VZ\%/A#MXN0`V\K7@N-[NS7FN1<2%1N)]F$ +MA(#@.4"^[$R2XR2;'D#3YG(-'+P#V/]*())ZP/Q7_\,+EUX!/O(QWAIR_W*@ +MR>G0PY54.+0!>,J54[\Y0D +MW*8EF;A?]A)-(\5RZ4:4$UW#A9]0"O)H,TFX1>LQ&,HJ;1<_89;O?9!ED!K] +MCNW>&?KPKN-3Z=&W-_=A5.!/&>M\P6`P`-KJG%U:!]::IV]IE8P13%586XM7 +M?>\1_-JG.GCBZ5]JFP(]:79=.)Q&3^E>`>Y5&. +MW.DWPPIKS:J%D7:*30'/-U'(TCXX8G][74=ECNJ:*(G=N@__EQ%`7/AJ"J#U +MAF/^26X1)='TO7GHPO#_OX'PK@)1;3NOR^$>!@K,0QUKR*RU3)&)'^;RJ(]A +MQ7=%Q]C2K;&&C7#Q5"EP._H$F!$P!4%A2!*W1H>*!@!<`0``7`$```(```!% +M``%84"0``$`1``#`J`$!P*@!`@'T`?0!1`=9XJW"X@ +M)"`````(```!/"$``2!+.2UC#V(G[PA%DQHEM"O5CVB59NBS(K.>HB?W +M>WOVI7%;<=G]M1Y-:`1C.` +M/)U;B6/+ZW-)M?*Y_//@9D16G]]:IPZ<3%,!C]+B.Z.;GW8L)@AG8U"F1*TK +MG(?JYI8[7A<;8-<8?V!ZMK6V\.!KE=EPCAJ,>U"?E#X&KAK5QL2,.@2*\+$& +MMJEI(3_H6C1T:Y\0?@K+TZ-TLV^U'VP#$[Q0A=YA2/Y]^`FSLX;#S6LL!;*+ +M)TBHB[1#YGJ%^9D]K'IMD9:*-=Y-L),!\XD5U*BIMO#U5;RO[Z +MAZG9(ZD>K]]E-\/7$TH:-/909@TL-"_^1.TPB$@2MT;*L08`?````'P````" +M````10``>%`E``!`$0``P*@!`<"H`0(!]`'T`&0&230[^,YIR]4A1WJOP#SG +MH7$N("4(`````````%PJ``!`S#`W80"4#NOVQ5^WKP@ST@NG)H*A,M=M;=K& +MA;,,\2@%`259Q-/JU179!TB>HN_4]?KLDF(37Z]&"6R]2!*W1G>]!@!L```` +M;`````(```!%``!H4"8``$`1``#`J`$!P*@!`@'T`?0`5`8Y-#OXSFG+U2%' +M>J_`/.>A<2X@)2``````````3````#"`D%L5J!;:=%G=LVJ&#//Z+])II@N$ +M5LRI;<0]?EJ+ZP%O09']15<+1)[D:$@2MT;NRP8`;````&P````"````10`` +M:%`G``!`$0``P*@!`<"H`0(!]`'T`%0&.30[^,YIR]4A1WJOP#SGH7$N("4( +M`````0```$PJ```P92A!MK:YZU?8FI\TDFAMX,KCUT5VI0X'D5M'=\__A<+K +M0.7V?N6$$-^4N[Q($K=&7=D&`&P```!L`````@```$4``&A0*```0!$``,"H +M`0'`J`$"`?0!]`!4!CDT._C.:"(``'@```!T`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``XGY6OL>DA`.I`:&1:>J^/XC&\^Y7 +MF^*"OP`]-%2KD=/-J`,F\9F=+$*WU1MGW(N%?_C=/@3)"Z3#];FW]7S:LTHI +M4PA%F`#U[`?^JHTR(+9Q<9)N,`#KB5;BE4<(EDNGFW"L*C7(+H?AD.1YGQX8 +MRK`=3[*[<+8YB!92WQU771\I```D-:U@($7_UB8JW[DCH*\F,Y1(-11XZ9LV +MRO,&KDA`.I`:&1:>J^/XC&\^Y7F^*"OP`]-%2KD=/-J`,F\9F=+$*W +MU1MGW(N%?_C=/@3)"Z3#];FW]7S:LTHI4PA%F`#U[`?^JHTR(+9Q<9)N,`#K +MB5;BE4<(EDNGFW"L*C7(+H?AD.1YGQX8RK`=3[*[<+8YB!92WQU771\I```D +M-:U@($7_UB8JW[DCH*\F,Y1(-11XZ9LVRO,&K,EN`H^0-%"^+1/.*.F+`+KL +MR@(EGG?TXV5`DR@TH@/&T)":Z$N7]MG%U:18,HMSS +M9_-\AHJD7!F`? +M;L$J4X]->>A2$"<1`\X!TL +M]O8Z,8&SKJV?V1J`Y!Q*_,&J[H?JG*=1ISL%I4@2MT:=>@@`'`$``!P!```" +M````10`!&%`Q``!`$0``P*@!`<"H`0(!]`'T`00'Z22-G8#R4R]NS@XTHJW? +M1+$N("0(`````@```/PA``#@&^.4C?3TJK6)L>8*)1]GM?JUDJI3B=G2-_V)N9?`W5/M3ZO23$!+`!18B5%RP!Y'<9%0[4 +MM]=K.NXVAK6<>T&)W7(=U*UE`8JC7>3CIB#O9Y@R:5`\Y)UQ*3.EOCPW6'K! +M8*UNY.QQE5V0+-2.?G&RF]L3_EB'6O^7U19[NX5C^=FY,ZP>>>UM"'G;*KU9 +M\#"QT:+C5!%U2H;\(`_L&DR:F/0?A\)KGB38U`>6*T*[H*NS71CYFEQWV$DN +MV_@8#24B0A`Q[US$MD@2MT9-A@@`_````/P````"````10``^%`R``!`$0`` +MP*@!`<"H`0(!]`'T`.0&R22-G8#R4R]NS@XTHJW?1+$N("0(`````P```-PA +M``#`(:='=4WF_=%:OQ:"$N72Z`^7VX?W0$5U-DQEVP`$@D>8E_:&\JB*"3H$ +M$%LA'1[4+M#&<0!G$7V:6:@ +M:D&%ZA8J'G27Y<2E6JY*PI'YEG]\\*1._CKB"7D)9A_0]1[27SO=&,5SW]"% +M3_:"B==$-T+:MEAF&*9+MRC[-[T(BB#X\0*M?UM1S^!+[`)CS*T>O4/ROT +M2!*W1H2K"`!L````;`````(```!%``!H4#0``$`1``#`J`$!P*@!`@'T`?0` +M5`8Y)(V=@/)3+V[.#C2BK=]$L2X@)"`````#````3"D``##^0UL>F_!+7[54 +M@YI&P.>69)V"XI%L$2314Y=I!DH*W2Z]Z&`E%15BZ,=M4D@2MT:MQ@@`/`$` +M`#P!```"````10`!.%`U``!`$0``P*@!`<"H`0(!]`'T`20'"22-G8#R4R]N +MS@XTHJW?1+$N("0(````!````1PA``$`Q.5!-8#>S#`UAGNLO4Z"30M2B4\? +M,G84&"89SIQQL$OKX)B1XZ@A5LME&A^_+U8/![CE2I>SNFMMSE@VG[*!E=B;CG[>E +M(2I+57"(_+D,OZ0Q?0CEEI"B(9$Z[&\DJWT?%F#1]#RD2I=>Z[;3MUF'/`3, +MTDA'30"/M;@$*J>ED'D=!G)UO5C"W52@)"%OVG2!*W1N'2"``<`0``'`$```(```!%``$84#8``$`1``#`J`$!P*@! +M`@'T`?0!!`?I)(V=@/)3+V[.#C2BK=]$L2X@)`@````%````_"$``.!#,[N: +M2/H!%!VKI"*-^M_@/W*B[FDLALR*)3V"`]ZL^&-EF[8YCL*.RCI +M/=C4)HB9%8P$YBC(%^NV<5=M7-6U#P!9Z_-Q"#`(?+=\/V8')B$38%\9[.2] +MSE/H!B[2`0"JCXVB]P^>`&YDX:YESQ[>R@MJR)N(][()Y@"2GWTJ+A9@. +M9>WS&^NGBZ9=K(C5-W$PB]D,9245/2]TP=,UDM*YI@IE!D]C2!*W1NGA"`#L +M````[`````(```!%``#H4#<``$`1``#`J`$!P*@!`@'T`?0`U`:Y)(V=@/)3 +M+V[.#C2BK=]$L2X@)"`````$````S"$``+#UF;Z[*NG%,6\WKB'G2XQASSH4 +M5")_`/]!+,S=$!*FKS(,/%C$/-R3.H,WF>H[3C(6GM!9DQCP!-Y(WTHK4,^[ +M(U%!/A?DG*K586B+;T$0+RP7JOEN#]`>QS@Z%0'N*<#D/TYH- +MJ:&!SE%4?\YTO;( +M+ME$E]E"`5@K`;>)6;15NO8.4/4B_R.^W;^`O7S@P>LP*CTBH[U_K"27*KL! +M*QPRE?UL[C4.`M'1?V?2I]Y-PYEN[,SJW'U=U)RRT/MN(.?/*?\=I<#,X<9& +M.1%6G#RE%O2"Z/[[:HR"F'*5<"='182,J7TN^+"2)/-'I"86C=;/U'?C>-OV +M2!*W1A8A"0`\`0``/`$```(```!%``$X4#D``$`1``#`J`$!P*@!`@'T`?0! +M)`<))(V=@/)3+V[.#C2BK=]$L2X@)`@````&```!'"$``0#-T3UPH9)_QH&T +M;(S&JCUSJRU1,X&\9NYUOXF@H+I.5/)^12&P6KK,1+IGH)/6^(W.382<#6D3 +M?W!29!Z/]A!A"*6`T+D,V1TAO1ZD;5G`;)9CZ'/358X\8?;&\0$WKIZ2."Y? +M,V%<>J&.[W*_'J"&$LJ0E^>19.#(FDVBQT\Y;\_\Z40F28CI'+NG,-4!I573 +M.X`Z8U/?,,+6+3V"")@"4A>Z!M$`:.#GV49!?2'=71B!^!;UEH5$C1G!G#F= +M"9;FTL1$TCO3%&__Z<9FY[PH.^3C[S$T%"!E1 +M0M+.#/"[I#K1"L^^HS$%VH1($K=&\"P)`!P!```<`0```@```$4``1A0.@`` +M0!$``,"H`0'`J`$"`?0!]`$$!^DDC9V`\E,O;LX.-**MWT2Q+B`D"`````<` +M``#\(0``X+%*1YKF((31L3<3+"="+N/@%J5_0)MQZ.,9L69^W^HW1]L$H3!/ +M,>$454NZNK_YYD#7U/MTN\ZT9.6/C_A/RHA&XJ(,+SA?5['H)",D'$LFG;/F +M6!X#C*P=Q:Z^!W67D5%$.G9)V7FG1`XR,8K,^S!_P$O%$Z\9;:F^-E@!GL4R +MPFW5W\6(-%Z[5CTOOG`_4`_HF$NOZ2$#*Y>D;\]$+B%11OVLO2A-WI4TTMP> +MW][VPB4]L,;]DWV/2_BCIT5E*S51@-U=C21LKR3_WX5\FDV>EU/WF'^I^W%7 +MR+E($K=&$#P)`.P```#L`````@```$4``.A0.P``0!$``,"H`0'`J`$"`?0! +M]`#4!KDDC9V`\E,O;LX.-**MWT2Q+B`D(`````8```#,(0``L.G!?O3Y%/], +MW]&J*5+?4I-W]0[C#VT+?./'JN]+`3Y5(#;A/D)?F/5?LU*7RDQ +MMN$TB]QZN'VE[MMIE3ORPF-U'*6+E9/E/A4(WG[:<85""!1"+?YLMT/C3_A& +MYLT5!81JR;!==_DZ3Q(LO,_)CS7^T'BP7D3A,:(;,%41M/9Z!\)B/LZ/O7&# +MI_IO27]VGKD%_91A>:__/\_2>4V2X=;Y*5:TSN#<<-!WW,#BF!Z0"\@U8YO`-79 +M^==IPDLLCT6@=J/"M`\OC50![V+:O`&IO.G2@`''D0",V/-EQ.LIR!68"0"< +MA++=?P97',^!>QA($K=&.H4)`(P!``",`0```@```$4``8A0/0``0!$``,"H +M`0'`J`$"`?0!]`%T!UDDC9V`\E,O;LX.-**MWT2Q+B`D"`````@```%L(0`! +M4%E"V$!)2ET8?DU"9!:/]M[9R!SO6U?UG?A?$?9+\P'67AYR`>Z8]MYG8S6@ +MWX4$">%!F>6]V7<_7?&;^I)ZN$N>VJ&?$5\GPE-!@V2&!)KS_*%]I^;[5F9U +MC7(8@1S0VGI[Y-V&8&[%AJ9 +MJ9@OWA;F6\3@YKV[S2+,@+J?AU!T2-'^=$34WRFTVTJ19O1N9H")4P5O0*S` +MD2>G<6'*!`>BZ:.OJBGN,QX<(O"4N[E.RV:;.4")D\,&G_ZM +MZ],49?L=PK$:R"O4/.?^F#AB;WUL5K`OV8P4M;:4?2!*W1@&Z"0!<`0``7`$```(```!%``%84#X` +M`$`1``#`J`$!P*@!`@'T`?0!1`D62V`$X6@&`[=X]1PF,[-@:=C&6T#GY[I +M4IM%.1$-515$*$3['#YP_D0X9\1'Q="8SD=%T#S#P^\^N.5JB\;]02-/!7F3 +MMC`?DG3X'0_7F.#_#DQK9HG_LSD%`7KD:VT`WEVT?AC2$M[(HDX;JG.=65FY +M<8BS&M3VQ'H6^WC&K>H +M3=74DU3WN6I/R(1496PNP:=Z^O5O%`_``!`$0``P*@!`<"H`0(!]`'T`&0&2>E>MJ;[T+W(O+N:K,-IMT`N("4( +M`````````%PJ``!`DSY"6ABS!S\*;?I9[Y=ZC$,$84??2#"YW/&)VO7^AR\/ +MD%6?:^M]=C1":..`WTH!)L&'!N&;7GEUSMH@2!*W1@/L"0!L````;`````(` +M``!%``!H4$```$`1``#`J`$!P*@!`@'T`?0`5`8YZ5ZVIOO0O$ +MK,NRC3V([IV../PY<-6Y&$@2MT:1^@D`;````&P````"````10``:%!!``!` +M$0``P*@!`<"H`0(!]`'T`%0&.>E>MJ;[T+W(O+N:K,-IMT`N("4(`````0`` +M`$PJ```P]5[+_,RSLZ-@/,%9MGA&#W>DO/%O>J$KM3S3IKUH6]L'Q,;:ZZW,FDF16P:5+(>2])5!`$AJ>6097&2P[PR5V':]=*6O_2!*W1A8$ +M"P"8`0``F`$```(```!%``&44$,``$`1``#`J`$!P*@!`@'T`?0!@`=EJ_": +M#2C@5O@``````````"$@(@@````````!>"(``'@```!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``?(-)7"*+:PE&B1ZH_$G!76ZNMNEL!/SB`*Z, +MI__XS,H_&-?AP-,MC,.H4:T`"&&3Z?>LKE5/X?'51)H`=#L<^B7`:Q3GC&NG +M4\-&'G%UI3!3&S6_S"H=3YU@RFI^N!G.97ZPF*A^M!8QKAGG6L]M3T7F*@MQ +M=GF<;]Z)0YE[T@LI```D[79M104W\AF"^P/7TKI(DP\6#AB%"9#A#WO//YI) +MQH]_->(++7!2*P9UB$@2MT;@$@L`7````%P````"````10``6%!$``!`$0`` +MP*@!`<"H`0(!]`'T`$0&*:OPF@THX%;X```````````I("(@`````````#P` +M```@``!`!@````&*.=&A=PQV)_P^$N)?O:5]W$YN"$@2MT9:(@L`N`$``+@! +M```"````10`!M%!%``!`$0``P*@!`<"H`0(!]`'T`:`'A:OPF@THX%;X```` +M```````I("((`````````9@A```@``!`!@````&*.=&A=PQV)_P^$N)?O:5] +MW$YN""(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``?(-) +M7"*+:PE&B1ZH_$G!76ZNMNEL!/SB`*Z,I__XS,H_&-?AP-,MC,.H4:T`"&&3 +MZ?>LKE5/X?'51)H`=#L<^B7`:Q3GC&NG4\-&'G%UI3!3&S6_S"H=3YU@RFI^ +MN!G.97ZPF*A^M!8QKAGG6L]M3T7F*@MQ=GF<;]Z)0YE[T@LI```D[79M104W +M\AF"^P/7TKI(DP\6#AB%"9#A#WO//YI)QH]_->(++7!2*P9UB$@2MT;T10L` +M4`$``%`!```"````10`!3%!&``!`$0``P*@!`<"H`0(!]`'T`3@'':OPF@TH +MX%;X7:A_^&F5IGHA("(@`````````3`B```P````+`$!``0#```,`0``#(`. +M`(`#```(`@```@,```@#```"````"`0```(H``"(``(``$:I@2^1"W0/S)C9 +M*ZK0XHD\(VO('[Q+WYO1P@#X!_57L2M8B91*+L2@6*>D +MC=&D4@]CNWQ_*C&+>*E7SHC1@^_"#\@:!4(7DJ&(.??3_95@26-ZNJ+E+L+: +MS2Z,MR(:9\69":&&?$X"T6(\TK(^@A0C\!:%*0``)##@QT>0R;DTD+G*R_.6 +M\!WQPK=H`S>&N=]!TU*3>-HD*0``'```0`2,+PM[P\.LU:4DKX!L."O#RIU\5NFX$PA7"9C_;DQ@8=S'X[ORW<]U`L@[S6BSO'?@D[<2+B`O3'$ +MWA$_FA>6_]]VP4`C7(]U.BKN1$";A0L]HYT&O67/A[B!L/)V#G-^VDSA*?>A +MP#1<<),S^@:-*];0R.2DCY6&F>+DL)B[X?C*"2./=8]YL*S:/Z +MSSS]:Z]@);<],>F6HV$4Z\2D#P"$@2MT9CJPL`'`$``!P!```"````10`! +M&%!)``!`$0``P*@!`<"H`0(!]`'T`00'Z:OPF@THX%;X7:A_^&F5IGHN("0( +M`````@```/PA``#@&[E=#^$*PBGOJ\R+,IF*;'7/LS%N2RA(@7BK0$0HHT"P +M;.'O7@*Y$$UY2[]Z_,'0&[(*>82E?,]I.K83Z3US"NNZRC9K=QG,=W1G%LP5$=3_4A4QJ`Q`8/+;@K#1 +MM*>BC)K7_$@2MT:3M@L`_````/P````"````10``^%!*``!`$0``P*@!`<"H +M`0(!]`'T`.0&R:OPF@THX%;X7:A_^&F5IGHN("0(`````P```-PA``#`"&SU +MYAX^/7]8Y8V9#Q<'TNN,Z0_$LD'9*^?JDY&RS9]LOV76PWBO%8P61"8+9_3. +M-9;FY1+P_T7W(M9,9TCTA)$XGMT4ABL.]66IZY5W`+]]Q3Q$ +M'C;KJL9][5UI>8`9Q(YB_4:@*+?KGBP/WH2*)#]770YOD#:`U31CA%CLK"QH +M(9"T('Y($K=&5L$+`&P```!L`````@```$4``&A02P``0!$``,"H`0'`J`$" +M`?0!]`!4!CFK\)H-*.!6^%VH?_AIE:9Z+B`D(`````(```!,*0``,+YP8-[, +MOY1A1P0L:I?\^]J0.Y<^YE]%2G]91>;.9*6?-I?5?K9)YBX@)"`````#````3"D``#`2M.ROR992YMO-K+O>R7:U +M_!>_&%NSBLLB6JEVK>]HZ61&;;BI%3V3:Y1R5D@2MT9?]@L`/`$``#P!```" +M````10`!.%!-``!`$0``P*@!`<"H`0(!]`'T`20'":OPF@THX%;X7:A_^&F5 +MIGHN("0(````!````1PA``$`@Q6AQST$"Z?!.*DT:2AZ,US0`?JHA?L+@>J_ +MIMPXOJ6LY+&N=93>P'V($GJ`EKX1)&4;R,_FQB.'/'4P9H$8.)/RNK<.KU.( +MJ]?F-&I0I:6S5Q%&W0L$^7UF=:?T3?YGC!"O]:]]G9U]`F$1QN4J*W>I'WKF +MN9P')S+C6)T.&"MO9K9CCQ+^R,G^R%5='S7>T<'S?A%FG['I4D=H]QD7+W,QP^\V5+%N.614>SS_7#X,Y/ +MU53S_)PE#MX5O\;R6WB*NPXMAK9<%^BJ3YGXA5C!RLD;JC^HB+(17,!48$LV +M2!*W1G0-#``<`0``'`$```(```!%``$84$X``$`1``#`J`$!P*@!`@'T`?0! +M!`?IJ_":#2C@5OA=J'_X:96F>BX@)`@````%````_"$``.`R0(UP\A@Q*@-R +MQ.O3QFY"[%3.W9][66]7\48M@J;)E&L'(K#&S9G;,T*X0509T^I;?@A^WM[O +MAZ,5<27LU$PPJ&V9OVI]O\GA(?SJ..4!`5K"P.P[J=MLDGKA9+5(0Z1Y)\OV +M1,7FKFD,=_AB]],I$3D]+)7078^,<'A`KVZA:KEX1J$1L;5<)@6.P%\@<`M6 +M-!W5;MMN1[MO0\?1PK/MBF=7([&]/(Z^8]FA<"KOKZ5<:%*DW6'U9F<=_$D! +M[N-_$]$<:4HT+]0/E.Q4^2)AJ\+G>15LS.S55/?C2!*W1N40#`#L````[``` +M``(```!%``#H4$\``$`1``#`J`$!P*@!`@'T`?0`U`:YJ_":#2C@5OA=J'_X +M:96F>BX@)"`````$````S"$``+!\%9.&"]2]'"LR%HWV4.'UM9L:U@5U!0HA +M*WEOOSK6#=VI:#4`T.B^O.>;;I&2G`\U-[2H6D<3T&LM6%-$`DC972SH+ZRU +M"]29G'_VZ&TYM/,4EF/EM,"07VL*(Y;I@L0L/DCL#OXHCNXYD`TALR\84$4& +M1W;VL)<2\7)'?7C!TIG5R6!/`D&![P'-R6EPFT3:-[MH']$I77%1JM4!-!S` +MQ8/^FZVIB';U_^M^2!*W1A0T#`#L````[`````(```!%``#H4%```$`1``#` +MJ`$!P*@!`@'T`?0`U`:YJ_":#2C@5OA=J'_X:96F>BX@)"`````%````S"$` +M`+`"OLE9(WT?U6ZR43MLM%+=!88)F;N:B.+Y(NC.!&AU1@Q4T1YO24HO3H*_ +M>*8[BH(RGD5)N9#"^2GB1D0.HI#BM-M3@AA6M!AAX692\.YM7UM3IE`A[VC# +MQMQ*E5_P$/>;EXG`/+:L2IF'M(D?AMFS3XMIZ3.];+G6.S6C:73TAC?B\0?^ +M%,_\JR-5"`1RLEVM*_JJH'AK*#P_1CXN#3`ZJ;F-7/+5'PI*UGC^2!*W1L91 +M#``\`0``/`$```(```!%``$X4%$``$`1``#`J`$!P*@!`@'T`?0!)`<)J_": +M#2C@5OA=J'_X:96F>BX@)`@````&```!'"$``0"'H3,%YM;%P'"A9MTZD>4R +MIN]M7/2XP&6%;;4G8XK:@Z_RGW(I65.,^LA*>WT)I2$Q+<4U-)^Q1N5\0SP] +M'K['_T".#];I@T[O^6.3$X=[[Q!1GDX@I]KQ"LM2?RD!?JAIU>R`?\>!JS37[IUO(V7D[#1.."D)@W,G@I,>S9!<)CU6#WXJR%7E +MLD>7#Q0?!;O<#KY($K=&?UT,`!P!```<`0```@```$4``1A04@``0!$``,"H +M`0'`J`$"`?0!]`$$!^FK\)H-*.!6^%VH?_AIE:9Z+B`D"`````<```#\(0`` +MX!K1ZLUTQBC`>BF92$4'0K0P!I:KVAW4P45!(>$`#0>DR=Q;59E=LO.W''`;*VI@ +M]9R_#FF5=,-<5/+D7!OW4M$/P9!73X$-\]&?N-U?,^5QR,4S@DF??GG&>*7] +MQA"`!(VCU+@.OOW02,"#N1Z98H%E^]HU;C38J\F(#L]++S.:_I$2*)W/T>H-[P7FC+G5.X9.A)-&G9FLCK7:`_\7J+MYMZ=4:9O=!($K=& +M[6P,`.P```#L`````@```$4``.A04P``0!$``,"H`0'`J`$"`?0!]`#4!KFK +M\)H-*.!6^%VH?_AIE:9Z+B`D(`````8```#,(0``L)+=%V5$G*ZC3U*-Y?T"T%HY8\CK,;*1$ +M5\>YC-`@VDKMZ^:D2LG;RY5-Q,%\_G%C;29O-Z2FAS&;>7[HSRWCP4S/I!L, +M!6`*+J".K4$8GN(8G1&0ZU`?(T*?(R9($K=&/8\,`.P```#L`````@```$4` +M`.A05```0!$``,"H`0'`J`$"`?0!]`#4!KFK\)H-*.!6^%VH?_AIE:9Z+B`D +M(`````<```#,(0``L&<%4)UW/;E/7_*J!Q'Q9;TG&7H@0M.+^LQH*:"Y9&/E +M9;+)QI..1)B..#Z[LY<-ZSNS"]+YE^XL?FD-W)IH?D;BD`],*<6SES3EA +MX;F.<.%3:[BK'66#N]+8Q*41C/-AGI1)FHR0U+/Z87MMF.+6:%.@?77N@8/+ +M?U4;%*A:CR$,%;N3>*S!$OVVA2F#/!OWPIB/1" +MC$%H2II($K=&Q+0,`(P!``",`0```@```$4``8A050``0!$``,"H`0'`J`$" +M`?0!]`%T!UFK\)H-*.!6^%VH?_AIE:9Z+B`D"`````@```%L(0`!4-'9*#,> +M5P<[OVH42H,T.0UZS9:WIBUW>P#!BR53?=PBWQG-[:(PI"8"-J*OCINEH+H7 +MEZC2\_#;;Y"@G`J#V/Q6SC.-I1[)MK8CF?6^V:GXJ;_B8RSVRC9)6K..>X6D +M`__M^[KZ8@$V.Q6N_9"8(D%W&OLS/4--"$@J]'+L;BN(2JB#0?E#@ +MCAY7,EC+*LO-35L29+^.5PGMIX8O35Q>M?6;P@`SKC>6\'B">2X +M:S`+Y3JM;.")/I[12U?`H+^48E:+B"\_8;!%+5:@/&]MZ.;.'I,-W@RO$O%Y +ME96PLY$HH\E2A7@RW^0V%)AK)RD7'])A:4Y7QE4Z1?IUEW7)!$*FEP!![BU* +MM)$?A!:=@2!*W1ECI#`!<`0``7`$```(```!%``%84%8``$`1``#` +MJ`$!P*@!`@'T`?0!1`BX@)"`````(```!/"$` +M`2`"L9&7OVK6'VWD'.+!06JSNH=93USO-<+K#(\1KB82==]"N2X&.'B@X=&="6=>Y8,#!_'"DF52@K<=SABYYP'3>]?D>CTDZX'%\ +MZJ7!@5?']8;Z^&Z-T%AN6U%MA##'\P-F`)V_[Z_"Q.#^9Q8+*$67%YB.VI1Q +MTX.Z74R`W:@D:H\CUWNLZ9<(_ZCG[%7V`Y:?YCQ365@0?FK#AO+2L%;#'M%M +M.,VBI(;JX0O$[(Q5+^.BKS3*6A/7.U(?%7H%^?QR!#Z[FX/M"FN)2S&I&!Z@ +MS@N";&`!"NMADK.KZ`;U3:+3@-?>.E5M=Q[(E]6_R!]A(SLF`2.N;RN8]0@_ +MQ\"85]8D>A3H/XH\;(2@(4@2MT9E$`T`?````'P````"````10``>%!7``!` +M$0``P*@!`<"H`0(!]`'T`&0&29T,%+?'_93P!V7XNIU:L.8N("4(```````` +M`%PJ``!`)`IILZ[(C+6G'5J2^$M4QTT.AX1S<>'-82>DS1B@T"R`!P@E_#UY#1?_)S\$%2!*W1H@S#@"8`0`` +MF`$```(```!%``&44%L``$`1``#`J`$!P*@!`@'T`?0!@`=E1S7>%+UIUG(` +M`````````"$@(@@````````!>"(``'@```!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``K@>LB2!JQW@G7X:DQFE)B<0W=Q*P4^0ID*[96X4_M6O[ +M:(*MB)@/K@YU'X%(VWFJRHSN$6Y4B.;F)%LXR5HE=0(<$CO_E(/?D\.V#-2U +M&I6S,&P:M8[O-,;D)OY.@X/#+B\'YLYB!<8-MYP"$%#G(X'ZP6==_L=@\S=P +M51('F*@I```DF1,[:O?[F^$HA-Y[V15T.'1?<8`AL`D"W:-9[@1%BG`I```< +M``!`!.GD!K2:>:TD,A2'3C/J'CN>]Q7M````'```0`6",D_=$N!4W'\9*#"S +MX[(5`?M]84@2MT8G0@X`7````%P````"````10``6%!<``!`$0``P*@!`<"H +M`0(!]`'T`$0&*4LB2!JQW@G +M7X:DQFE)B<0W=Q*P4^0ID*[96X4_M6O[:(*MB)@/K@YU'X%(VWFJRHSN$6Y4 +MB.;F)%LXR5HE=0(<$CO_E(/?D\.V#-2U&I6S,&P:M8[O-,;D)OY.@X/#+B\' +MYLYB!<8-MYP"$%#G(X'ZP6==_L=@\S=P51('F*@I```DF1,[:O?[F^$HA-Y[ +MV15T.'1?<8`AL`D"W:-9[@1%BG`I```<``!`!.GD!K2:>:TD,A2'3C/J'CN> +M]Q7M````'```0`6",D_=$N!4W'\9*#"SX[(5`?M]84@2MT:0=@X`4`$``%`! +M```"````10`!3%!>``!`$0``P*@!`<"H`0(!]`'T`3@''4&C0UA8FC8'H-V]0N:`&09EZ5 +MBD\#])$`JN9C!U`8X-F3"&64GC6%U:[.M5_4!Y8/-_(P#(K]/6&^86R;%=2W +MTWM7]%Z*Q$R8E@^@M&+3](PI!<-W*0``)"E6R;4D!::0"DUBJ2!"[.3$40FO +M$HX21^0H4IK$C4I[*0``'```0`1N:5:LL==?Q_Z]9>NBJMRQ$(E9&P```!P` +M`$`%D_E4NZ6X&3)<8W\:)=BCLX9]Y?I($K=&]Z(.``P!```,`0```@```$4` +M`0A07P``0!$``,"H`0'`J`$"`?0!]`#T!]E'-=X4O6G6G'G4@"43K,)T*03TC/"PILI +MM6,UEL0@]4E8Y$]AB\1^=5<@$)C&16`:H:$[;R52""UY]2DN&(MW60I.> +MRT4O=_88C/[GC9],@D:/B=H5(**6F!RZL6W_'"X()!,[A]_'\N[R-RKU(/]HNW2^>5NM,S\:EA04`M,/\0][?0&BJZQQ_Z<_7Y_CD3F!^M'5W>6\>NEU4>LZ2 +MVO+O206Z^/;LO&2O8!Z/\/*+,Q7B>#*" +MI0"K34VN-'["_B;]!Z/2.S1'%L7IX`/T7Q@8O]E\1T%[P\>6!EA( +M$K=&,_$.`&P```!L`````@```$4``&A08P``0!$``,"H`0'`J`$"`?0!]`!4 +M!CE'-=X4O6G6U_6@VR&;8HX%8XFPY%CE*K%^2!*W1CL,#P!L```` +M;`````(```!%``!H4&0``$`1``#`J`$!P*@!`@'T`?0`5`8Y1S7>%+UIUG)F +ME"A!U2^CXBX@)"`````#````3"D``#!^GZ)KSB'8A[%"KAC576//9!=#;DI6 +M%KA\=/.Z^B]Z,4I94J9ANK4J755_64@2MT;A)P\`/`$``#P!```"````10`! +M.%!E``!`$0``P*@!`<"H`0(!]`'T`20'"45\4W\D]":VR`O4.LFR0'T&/Y' +M`]\^2;>%9_HVRJB;TB@Q'*NVC]^%_FV$I\7`_'S(@!5&[8_6F^.\$IB;BVL, +MBU1B/9MV+W.&%1;ZBJ0,(K*1#*X'#J:ZIU_]PA+KP7[KL'9O]Q0'"&K="E-F +M_*5:MR\'GE%".OYR^FV:W5SL=N:.<3P')%E\&VO2!*W1I(S +M#P`<`0``'`$```(```!%``$84&8``$`1``#`J`$!P*@!`@'T`?0!!`?I1S7> +M%+UIUG)FE"A!U2^CXBX@)`@````%````_"$``.#W!AN&VW!;N`KS]87P*'1^ +MDW('A>/MYV9;MVJ''V*1F@1I@'MJ)PPE+]+S5#I#62^5_)LPUWSX._J[#\D=MK[:6PK)-XG$9$@$7`EH=ID56?#%;HMM4 +M.`!5ES.FYP!W=>UZ?'/^ZY),T9:)($V)21*W1C,"``#L````[`````(```!% +M``#H4&<``$`1``#`J`$!P*@!`@'T`?0`U`:Y1S7>%+UIUG)FE"A!U2^CXBX@ +M)"`````$````S"$``+"D^HD4-O-0%URDXD/PZJ^LWUL;",KM'L[/<9/9L?PN +MW-\XH;.B,[U5$/*A,SWT\U_%Z5E;E*'VDS +MSRY\L8*,39VQ*YQ_ZZDG>PTGWJN5H3*E-X&JE9TZ($U$0B+XF+^V/OG\3:'^%)Y%0+=(W%I3-9`()7OC.F\J95VT?^*Q<`2)/ +M../;7%_,21*W1B\D``#L````[`````(```!%``#H4&@``$`1``#`J`$!P*@! +M`@'T`?0`U`:Y1S7>%+UIUG)FE"A!U2^CXBX@)"`````%````S"$``+#4KI]1 +MQ\(I/M:OTH@7WMWP5"GDC+G)-UNT?")!R)8M'L"B6W%/93>SW6).8B:K5^_4 +M]80!/UITQ$$]&&J,5@"3__J\[@TML(.E=/#A=%+UIUG)F +ME"A!U2^CXBX@)`@````&```!'"$``0!7M;S*TYBRO5$N0,,`6TDR.G'4(HE* +M(*@(BS(QM5#A#;ZWF1FB$B3W""1",QRWN +M:]^Z%FM.KN\-X=`6L`VPAE<):HZT;J_XB]`$P/*5'F$";I"B+;C\)`^D5!B= +MA/@-:%TD!Z5]@I@L,+&P2T?-,9:WFW39&X3N:'5WZ&??7!@Y,*BX<:ZF/$.? +M*9[T@3*N\MS66?X4W@H"TX$>CDL"M!#V\+2K?&Z`]U<@.]@'X<2.?X.;Y'-> +MILB?%:`B2LST('7SVZJM6P1]`A[;G1Q;L:,K+IH4<25R,U\,R1A\W +M$23KL8FW^];-NAI%U*U;/$\(QGY)]2\]BZ;I26(:='TV[D6+VNO8B[DH%6#B +M'7VQ%W(K".DHU\?43#JD]ZCZ_ +MF=NG%:0@!Y+MMK3WMUZ^S&/L-PDJ:O[ZB3] +M$_L7AIA]8C"B@S.'2@4%E>MOK)5K^-SRY"ZP9GG)Z/&,86A)$K=&65P``.P` +M``#L`````@```$4``.A0:P``0!$``,"H`0'`J`$"`?0!]`#4!KE'-=X4O6G6 +MB>V[?V2(U$@>1?C=DW +M>0\BM>D?&TN9'U@27>'5TN.PIXBRE4J3$!QB%`DA_@2U2-KXFZ#[A\?\#>[YR`U!'>9D&BBV0=X9:A:V]>;C2O[$`0MIW8.!L4B!13V +MF!`!.+0LWNM6FU5NG^K(4;@3;7-2,!>UI0.9[UY-.E"L2R,E'E,+*]3B$EC, +MU]_Q7#Q]*T??SM&<9#8[J)=)$K=&6G\``.P```#L`````@```$4``.A0;``` +M0!$``,"H`0'`J`$"`?0!]`#4!KE'-=X4O6G6`W/]HC^[#%T_6I$97\GVRF\I`IH"!"= +MJ>!#(>?-T@C;8$/0E3B.>U"=Q-`L5$8+#.!?J`I;BQ";QL5VM!?RQWX26&3>OQ#\T&8&PP@+U9N76'@*HL*](LI*UVO*A&A(,)8PZ`]\5T5U@VOY +M^H8GF,?5M#XTROH!DT)C6QAQ(FMD%SHV?-`7"(:3X5CW;16"97`Y163M/"O\ +M3<&&JS4]%":W5*X.@;2Z25%T#)#?T&]Y[XTB$D72+DE@BG$@$5JV_HOP!>B] +M0N\=C0>:=RA`>8_AN'4C7";??HXY.(SN>-+\O),J@^AQM!QJ@/OX4RSL6A*F0B-2B"N==?6ZPIGB$1[8JK>;G%S\G"TW`KUJ^^RJ%5 +M"3/`B-T>X`4^'.G`&YJAWZ#P30M,70?W+-*OXOBT=F99&+CDOPB;1_]%GV`' +MT[>>#$OA3X^-IX@%+UIUG)FE"A!U2^CXBX@)"`````(```!/"$``2!I^YO= +MDYS7?#R^_3X<$,:V$!"=43ZVCYSG&P^#7``;GS/,W*IW8?`5<;0VP/:..H>S +M%%)T'\!C#7/6@0K+K>!<:7W>0@H[3N=[U,68^1W:D=W>5YD*^A^FK&E`M0]6 +M,K`Z!0C:-J1XPF-@ +M*)O#LZ\N[Z>,VDD2MT:C_P``?````'P````"````10``>%!O``!`$0``P*@! +M`<"H`0(!]`'T`&0&2?1AM#3L=3KZ.9E%7;QC/!+@(?A21*W1A<+`0!L````;`````(```!%``!H4'```$`1 +M``#`J`$!P*@!`@'T`?0`5`8Y]&&T-.QU.OHYF45=O&,]RRX@)2`````````` +M3````#`A,E.*,]Q&L)\#RG(QQCKGEA??-#KPJCJ-FA3M'.A9U!^R7GJ;7>\E +MS7HN`DD2MT9I&0$`;````&P````"````10``:%!Q``!`$0``P*@!`<"H`0(! +M]`'T`%0&.?1AM#3L=3KZ.9E%7;QC/^F4KXBBK3MZ963JL5CYT@5)$K=&728! +M`&P```!L`````@```$4``&A0<@``0!$``,"H`0'`J`$"`?0!]`!4!CGT8;0T +M['4Z^CF915V\8SW++B`E(`````$```!,````,'UAY94$YF*M.)MQ&!\2@8=Y +MPJ,$!5,UY8ZD6U9+#;[24=J"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``]YF>//X9E,[\UU67P^K@*M<&_G%U02V?)*\1%L018%4M^W[0-JUD +MD*=`(D))N^0]AQD'`P?S:5`R&8)1)5[[W#J(T]D3= +M$B0OAW.G1<=U)XWB&S/-RSE;,BD*`HDJJC>"5;5+^^SVEK_O](B;#K:8).0I +M```D%_W\#+5(<-L9Z[(.N[TM?6J^ZN#X?3:PEYUQ6?G0J)HI```<``!`!)SR +M?T$?83%":7`]NDD2MT:@00(`N`$``+@!```"````10`!M%!U +M``!`$0``P*@!`<"H`0(!]`'T`:`'A;+!U-"9%%K1```````````I("((```` +M`````9@A```@``!`!@````%L\G8I"V(T6G7>?T$?83%":7`]NB(``'@```!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``]YF>//X9E,[\UU67P^K@ +M*M<&_G%U02V?)*\1%L018%4M^W[0-JUDD*=`(D))N +M^0]AQD'`P?S:5`R&8)1)5[[W#J(T]D3=$B0OAW.G1<=U)XWB&S/-RSE;,BD* +M`HDJJC>"5;5+^^SVEK_O](B;#K:8).0I```D%_W\#+5(<-L9Z[(.N[TM?6J^ +MZN#X?3:PEYUQ6?G0J)HI```<``!`!)SR+R.A +M-PVA!V\NQNK6JGTBHNHJ`8MZ9Q[^B1D#J2;E\2TW"C37S;%5.P)!)$K=&"I("``P!```,`0```@```$4``0A0=P`` +M0!$``,"H`0'`J`$"`?0!]`#T!]FRP=30F11:T65_?-LJ9PS'+B`C"`````$` +M``#L(P``T,T_8`0@)L,>C9'Q/_F#_N:/M`$D(60,C#<2O&*]5]:X@*>,3^EZ +M)21/V$C"SLV)AH@K=KI#<$0Y76UCS._.$%?)6H#8O:I(JV?'8U("]8<1HH3DGSIXOY3!^E5GU9+7\E^-K35@](4[C-HY08_'%E<+U6AS#!1F9/[E9MTPP/\> +M^Y9Q+A^;!-$"]+9RD[Z%.),>Q%Y[UK8D#_W:3#TG5$D2MT:5J@(`O````+P` +M```"````10``N%!X``!`$0``P*@!`<"H`0(!]`'T`*0&B;+!U-"9%%K197]\ +MVRIG#,%J"@Z +M9VQB+B1R0BL'V[$'T,XU?.G5R/8VRE;6P^'=]5TYXYLS`/-PQ.W<*"03SC'9 +M]E`;7#&P_TD6:TD2MT:_R0(`'`$``!P!```"````10`!&%!Y``!`$0``P*@! +M`<"H`0(!]`'T`00'Z;+!U-"9%%K197]\VRIG#,2Y]LF!L1C7Q<)X>CZA[;B1(9*"!,Y/V[AA#= +MBM:5"-1J<5:AE/([HG+,HY*Q6YE/E]>HTM>^41@R,9Y)O(WV7*O>'-W@.R'Y +MU(R2GEL+!E]''_5E.KQ +M&H37%QF8UD7A:CD]IF`OVD%5#=X?PG@E+=.F5>T`"X9E2'U1[J=)$K=&E=\" +M`&P```!L`````@```$4``&A0>P``0!$``,"H`0'`J`$"`?0!]`!4!CFRP=30 +MF11:T65_?-LJ9PS'+B`D(`````(```!,*0``,(8CNO?2K'?M-<6J.BTU;B7Y +M=$".I_LI5K6)D*+!0&\9S@6+9F7I<*0)XXC`21*W1I+[`@!L````;`````(` +M``!%``!H4'P``$`1``#`J`$!P*@!`@'T`?0`5`8YLL'4T)D46M%E?WS;*F<, +MQRX@)"`````#````3"D``#`94/^Q&P56<-,M.C9G.EQU!DC`<`?"[L3H.`97 +MVGS]-NK0/?I(HZ<=DD2MT9:%@,`/`$``#P!```"````10`!.%!]``!` +M$0``P*@!`<"H`0(!]`'T`20'";+!U-"9%%K197]\VRIG#,Y#(R*A(2H?^_87-7Y_OLA?[R7`OMWIQZ\@/)[34O\@<; +MKJ#/6E1OTE.9@NW7Z/-C+9!PZR?I$3PL6EWBBI(P@-R-BKFY[`B99[D%F3DP +M9929UZI)`M26UZ>D3ZY7AT%.#J`TL<]=AW+#K,1(^_:(K'GR^V/($'/Z3:@9 +MK'M90E<6#"GR$Y4TG"U51++U;3$N,")F4AQ#K21*W1BLB`P`<`0`` +M'`$```(```!%``$84'X``$`1``#`J`$!P*@!`@'T`?0!!`?ILL'4T)D46M%E +M?WS;*F<,QRX@)`@````%````_"$``.`?HX$1:9Y_I6]+L^:<4>17#'L/MD(] +MM%0(U3J`1,H6'(__(N9VD-.G+J]<<%,XM_5-.YPVZ>8N:)%+5(($'AIC56^5 +MR)MY:CRA"#.E5^@TVZB>Z[!8XDPV#ZLL-7QG7/E,F$&27T4(Y0X7S+VJP4UG +M]E^1=F=,M7E"/@\J#_^-66[2ZQ>+]JI<6LH4.$P:PR[O^$2]S/;O3'!OM7HJ +MPX^^FRD^>>M"[&^?@E?794<,>LU9OQPD+MV6A;)J"L.6D&8&'0&K5WN`A($:^I_XO@IJ#]>S%N!U;,>CA# +MC[U/3:.C>,RW,A][.)$&*4E#,4E;RMB!YY87$&6D3LLJN.RVNB_]3GA,&'_# +M%?[W](_);UYO9;SLW_*N%[;^-'?44$)SAX(>6G_0GL-G[8)HM)MIY\/1BTV0 +M91_)>(`&8W]@15`'X0N6R6,`.@'/*LM5DBT<;$]MK&=L#<&Y]*7R[M)O%GSL +M21*W1A15`P#L````[`````(```!%``#H4(```$`1``#`J`$!P*@!`@'T`?0` +MU`:YLL'4T)D46M%E?WS;*F<,QRX@)"`````%````S"$``+#KVT$+MO5<4&E\ +MH64Y(#S>K%06TN9KM]]#554>!E$@@HB1TVL0FIW@0RI@+;Z.\# +MB;H3&0G-NR'Z@#=K!N;>8JU+\3^`^*M4;AR*)E%:NAB?O6J=808!NA?IL:,X +M)>@X_Q%W`;=82`+M"<#"9==3FF1YCR.KAD.#655U$8E*V!3^?C*DGVY1`!,= +M`S$0( +M7BZC121'"FMTK+@ND#D45DZ2"([;RRY]L#:90IAZTE5%7NKT`T&1U?8%YU$T +M(`#3UP6Y)\1+SD;`<;)ZR,+!)@^!]!_YP_()5!_S@;?I`AFG2:2VOY"PQ.,J +M6Q:;B6M39.CGZR4A3I^H,I(X6MNF5!1X6^I'98%===/E,%;D9 +M*R.W;2:F/J;1LZ%R%XI(@];B]_9H=F&"/_SB[V4!:_;IE;>DI(IBDW?2I==& +ME^*IYPYJ@H*Z5SC3LND6@`K;O/TO;>Y];HG^K04(N;Q,>'0T5RQ+ +M[GQ.+`_.BC%SQY\K=Z)USCS])Q&H^'0%!,<8.P3:TI=[?ML6K";2="-*2=L7 +M]&AQ^J^)3YES9$%EEL;(&K;9H8U&PK8*_XMZE(/4;'$0M[Y9>^,)JEW+O<_H +MCM!+Z["8FCVD/>Z(-4:0`^_+84YT:^P[<`N)IRQ)$K=&N(P#`.P```#L```` +M`@```$4``.A0@P``0!$``,"H`0'`J`$"`?0!]`#4!KFRP=30F11:T65_?-LJ +M9PS'+B`D(`````8```#,(0``L(M.:_>!\KE(=4)Y%<0E*,E#!!)\5PRHT.NA +M,:?'AV0EQT2K2A9V,0Z89@1->]T(2DQL2C?[&PY&6(..XO`Q!SS+_Q_@_+UZ +MSO$>ABQ+JNT&@;*#L[,6``S6.^O7/UL#$7Z`ILK4<]F\(CU7/DW[GS9'_1G0 +M=++HI`T>6M`E!A7HK1(Y/P$R\XIVA:@:S9)XK-XT"A3V#/9:T:`U^D-QIU,! +M^U0P!(\KU&;_AZ9)$K=&[ZP#`.P```#L`````@```$4``.A0A```0!$``,"H +M`0'`J`$"`?0!]`#4!KFRP=30F11:T65_?-LJ9PS'+B`D(`````<```#,(0`` +ML`'B749OI1L*:1;)B"T$ZP9_U*V=F_LZ\3IV%Q@`<<.4B]2P*1E5??6R`FH+ +M_F20&9=/:">U,5.1J&42SA8W*,CGS#!]@:LYH5/VV\EBVI+56ZZS/4Z20^+- +M15.O/*T&Q$>)$^+!G!2,USWX-W@S&'DWD/*"CS\"M4I"-SN;.RS=:@(*=WJ*(`E)$K=&FM0# +M`(P!``",`0```@```$4``8A0A0``0!$``,"H`0'`J`$"`?0!]`%T!UFRP=30 +MF11:T65_?-LJ9PS'+B`D"`````@```%L(0`!4%(*U(&<\I-J?8=N +MR%M:PW1T^(CF(1L*?G?.+D6(KRWF9Y;J=UUL[9\FGUR!@MVER%>^8?JX+PD+ +MX63\3CPC2HG,9K07O#-]2R]!^5.(\*?_P@\K&!*,]3]8<,_%1A%//*4<(GIJ +MTW:,RP(U#0NI1!Y7,1-NCKAFU.,&".$$7B)]%WJ>0/.:;^TK'1_,%$'Z3_?* +M").RU`-X0PSF/'%*7FC+;PZCB-&M2A<>#/ +M.&((;V^Y%\^K3F<7W#A&)OHA$\2DW$OABYTLS$RI^)[^757VY+_VEOH4B\'T +MXK90V2E/,28(^!/L!`#,IG-]LT]07#4S:-*2!U)DIQWV2)'S?+"'<^'43E?O +M.'#):/,M)_\4]$ME1NRNN6>W0#_$L#.G-4X`31EJF&7\]^9+SF8]QN""TXBT +M21*W1F0)!`!<`0``7`$```(```!%``%84(8``$`1``#`J`$!P*@!`@'T`?0! +M1`; +MOD2359X\,RLZUF":B+MK`QQIO/Q]PCE8F:%3B-J_C>UYO9,X6AK(C@R8%D$B +MRSZEI>HZ6R\:3PQ$^ISV9"TV4P5H@O)!U&?)_8]'._5'V+6=3XOJ%,U;H6]_ +M;^TVF/]*A*D@(@A1'C8C*RKHQ31/B1//)'@L#&=*YT1P#*@8H5FW[]UM6)2R +M5=6#!M_)'0<3%'O>+%"'``!`$0``P*@!`<"H`0(! +M]`'T`&0&27MM*[UF`8A9!U]+"]N40[,N("4(`````````%PJ``!`H$QZDMKM +M`BK4()]JSM0!!-07Y]_^\5S3*K3=ZBE=`D*`-JKS,+%V8BUIEAKW*/7:U;`4 +MGO?\V]29E%(V21*W1HL[!`!L````;`````(```!%``!H4(@``$`1``#`J`$! +MP*@!`@'T`?0`5`8Y>VTKO68!B%D'7TL+VY1#LRX@)2``````````3````##Y +MD,_9M%0.@3K_4V)$H_A[V*W=_?NEHHI<%.(3CS,DONV*W)4D2 +MMT8:2@0`;````&P````"````10``:%")``!`$0``P*@!`<"H`0(!]`'T`%0& +M.7MM*[UF`8A9!U]+"]N40[,N("4(`````0```$PJ```P[LH0)(5@JQ/Y;%4K +M665>82]W5,0K41:F(6[^71R^;`U2ASH24CO;?O1S*9%)$K=&>E<$`&P```!L +M`````@```$4``&A0B@``0!$``,"H`0'`J`$"`?0!]`!4!CE[;2N]9@&(60=? +M2PO;E$.S+B`E(`````$```!,````,&-MWF9JZGIK=*LNJA`%G6\8^VT"9"3@ +M.+?B85/(4):W$!`:@7HW0ZV67)2$21*W1HU1!0"8`0``F`$```(```!%``&4 +M4(L``$`1``#`J`$!P*@!`@'T`?0!@`=E$'CI=<8>^AP``````````"$@(@@` +M```````!>"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MPQ0J!KA:;JN7%\?^,Y?EHE;1()BD2EII\$SF]X6^7JQ9&$T92FQX;Q/-+5L3 +M*2*VFJ0;*AY@"/X^!L-GVEQ/F^9*5D>;5\">)6FZIKHM\-\S>C@`JY?J[?XG +M_YT-\+2X7O,;0TL[7HM.T]*S&:"B<`4`N`$``+@!```"````10`!M%"-``!`$0`` +MP*@!`<"H`0(!]`'T`:`'A1!XZ77&'OH<```````````I("((`````````9@A +M```@``!`!@````&R^+;5\">)6FZIKHM\-\S>C@`JY?J[?XG_YT-\+2X7O,;0TL[7HM.T]*S&:"B +MB[!C]=OC*0``)`6P:K>*B&8CJOAD2AX=:,"PUZY._^?9##LSZ$>CS<[S +M*0``'```0`3'=(C^K31S"@;W\J!UN3E-C*3@/P```!P``$`%9*EMGMS`$H@U +M"G70C&&.EUQA[Z'!OOK$_-*.$L+B`C"`````$```#L(P`` +MT!)E,?HVE4E$/K>X9UV:6W8.^H-2')JMSZEU9^D87(X(G&I)J`"YV3(G#>@+ +M;YJ_JIS,[,F'.46XL?;+W@Y1;U`EQG-/H@KI<11$\#`6F`UC^MRRCQQ%`Q%" +M?@HB?RS?`R!0X==TK8F_>R$Q=.>+ECA"*=]`ARTB"17"I-M^&#`L%EE5P@O2 +MY7&:0,L6P"T5(">QZ[U=)^.K[G6S@1P>8VN?"9MDUM4D2MT:CVP4`O````+P````"```` +M10``N%"0``!`$0``P*@!`<"H`0(!]`'T`*0&B1!XZ77&'OH<&^^L3\THX2PN +M(",@`````0```)PD``"`5(Q7T#R4WN#OVX4*2W^%[W-L4`3OA'+,RH>'@R&# +M;(GMRPL(=X&L9RH&^U4AY=)&$?$FY[&A4>:EUZR? +M=JL41CS-'<%,'\06WLVN0RX63;=/EQ&]/:6C%"]4<:YY9:?1./@8;6*U&AL1!;<3!K0DQ2`VB6FP^FTP%1?N6&%#G%JUP +M=EU;OJY>`+PD_5,P`*:3A?S689`]7K%9R(+QP +MT=#Z"0A`DV,:ENV%Z+\EE#.@_F*?(;>F=8J;-$=F5>EZ8TD2MT9:!08`_``` +M`/P````"````10``^%"2``!`$0``P*@!`<"H`0(!]`'T`.0&R1!XZ77&'OH< +M&^^L3\THX2PN("0(`````P```-PA``#`=OJS"X9!_P)4E:])NA4R:]>'P@91 +M,(*QS]1D-SE>8%J-W9EJZ*,9A;/M?48W3ZNE6,Z>>K#4ZBD8R<1CJC'U&H2' +MA$CLP]/2C8\!W$4S\]R-O6^:;0K0O^GK:3MULD)7BK@EWBLSO8K=W38_O'Z. +M-6UPGTH=CR]IY(9'T"@X`5O66UK'<6L)S"P6B[0DR%=5J4@ +M_!NB&`!4\UXX[6^:W"=^]EL9^GH%I]5W$LBMPUB[:/E)$K=&'A`&`&P```!L +M`````@```$4``&A0DP``0!$``,"H`0'`J`$"`?0!]`!4!CD0>.EUQA[Z'!OO +MK$_-*.$L+B`D(`````(```!,*0``,**'LC>TCRQZF_:8N+X)D#69^VYR:4M6 +MEBN;?;>@:JQ<_#T^AP;[ZQ/S2CA+"X@)"`` +M```#````3"D``##\QQ(9*6AH42FS?RR^]\4C>HL<\$>#HL%OME.RPV7P\C&; +M:K8A%N5C$C0FQ[N6SJ06J$[1=`)-59G<'J=U3R\+EMK0#5%1_$5P\Y!.K +M61^;JG@&7%@)MZ)HX*_%'"Y"L4AS(C,Y8(6D\9/PNQA<1HMEP5 +M7^2&T?^AP;[ZQ/S2CA +M+"X@)`@````%````_"$``."\%S<#9"C1@CI[@"G=;VFCNH3:)BX%.D@6HGAS +M_\YF92^.&G8AP'K0/A;P,AF8CAU=7C5=&)A=PB5Z']!O7^)X5U,N"'SK,7X2VTYX6D/8(GK%N^8,NT0B3R68QV`PV@0,)NDC3T`#>3 +MXX;@LZ]M"$O;B7%"21*W1AYB!@#L````[`````(```!%``#H4)<``$`1``#` +MJ`$!P*@!`@'T`?0`U`:Y$'CI=<8>^AP;[ZQ/S2CA+"X@)"`````$````S"$` +M`+#N!\M=H9A>SDU,A`23\I->YT?[L4@&)RW_?=K]_F8-/K(DH?&/)RPWA*'8 +M@E)/'W7N,+]QI,5?_/MA2\G]"1YPU!Q@7B0YK)@^AP;[ZQ/S2CA+"X@)"`````%````S"$``+"G-A3FPF.&[@%"(7FEAD"K +MYHQB&XF+I\7.=>D1*XPOC[MV%/`GP`(FNR%4^X0X)E,OZ81G%>4&[^MB+6MC +MC'[O_4KKF*0:/C&(^/,_T._*YLM^AP;[ZQ/S2CA+"X@)`@` +M```&```!'"$``0`0C[YQZ8`1A/D8)4^*+7"7\Y\4%@WZ;TV(NE8G8*"+,\)( +M"N;CVLC;*P/,OCUP'PN0C@)+QI+\?`]6EO[<37>F'YS(>7RG`^93THV061 +M?/\\R,\(#=[4'AB#P&OG1$GS914\!DOMX30'RV2D.]X3'GGW,_4/-8%57;V! +M+T:BZ%@IVHM:[52$XAE74?LL@UX$TE"&UZ4MVD`'>(\20@FX+`M)$K=&)ZX& +M`!P!```<`0```@```$4``1A0F@``0!$``,"H`0'`J`$"`?0!]`$$!^D0>.EU +MQA[Z'!OOK$_-*.$L+B`D"`````<```#\(0``X-]5AFJ3EMM.$)&@.;(P#0>< +MO6ADYQYH%20E1E:Y%Y0T>*^F$CN.4T,K'Z)H__6C2Y"?`P^%ATVFH@G(Y:C[ +MD(EC3$419'`L>)/7!5OO,U?BEY3M1#"+:2)7G!6J6,KN\3+K4&Q7QQ^_E;1: +MQ@OBI?\XT<*53OJC,\!$<$K!2'.)501%\1_D9:9W)012`@,`8&U#O^W-$#5X +M0[K-T]@P*J*5OA%Y=3K36-2,M*G#=9MFZM`,.EUQA[Z'!OOK$_-*.$L+B`D +M(`````8```#,(0``L/D0;Y"/$)ZCG5M[$AX2;>:SXDE>'<8ERNM/\RI*J/`$ +MX&^@%MV-B8Y#TE@`G4U7C*LVF+GV=^JE)7=R^!LYB_T[.)V`YIJ +ME[A&"`ZQ.YG(V"(J^C"^>@YR%9XTP5!)X6RBNW3!'D3YU*N$Q[QC@:O?M3-0 +M+X?M%]2<56Z,"B+;/K]L!!)\5(*A'S?C4Q[A"-=;4*TQ66>$)$3A5*1J^0&0 +M&7KLFH=)$K=&5>`&`.P```#L`````@```$4``.A0G```0!$``,"H`0'`J`$" +M`?0!]`#4!KD0>.EUQA[Z'!OOK$_-*.$L+B`D(`````<```#,(0``L!;]F'HA +MY$!4\UQL$8OGS572:.@&A=W,">]R$.Z?F_*'P@R@=/I*3?B;!T;^%21H'"*= +M@Z9XA"HW:>HPE](RO.3^F9)ZMI*XQ\AGZ??`QG+):F9=SL(4*9XMNW&,MMN\ +M^C1)D?U).'C5`#3W](;/*J7Q/"&.P#EF6\.R*2B7AII8XFCYHINDYG43SNJ@ +M0.EUQA[Z'!OO +MK$_-*.$L+B`D"`````@```%L(0`!4$PMQ?CP432O7KC#*//$`V#/341BR1%> +MVGMNC<2NS8_)Q;VUBM34?[(]?:&U."_;3BX(9R:/\5"66"KV>VUT:30:4$%/ +M%:CZU<(CGS'K:CQ-WEC.C++:$X&(#GVED)[U&A=8A7]#$*6T^F#M-@N];=LV +MN_*1\+Y75\5_(H-6;@0S-G=$SR]LOSTD0_5;(0^\I^JM!E7S#C@]%LV&?ZS^ +MQR6`B!&2XM8HFR9#<2SVS)&S`O*&95N9O)MQFR&_*!"'8B>8(,RXVJPV>G%^ +M[:2TQ3W[FT#9Q4'7B;18).'JMI("5C;1[\3DD6YXC)#K`#)H'`37ATAP&QTZ +MN^N7W/6.!/0G3&XD!U*;EER0H04KFCBTO)V:@;Q]GC?2SSSP1-!JV-RK`N0> +M.`'!_/R>DZD(RPNQ*I"`\%:^+C9$H\F\T*)"P@A38T$[IFK4K5)>21*W1B,] +M!P!<`0``7`$```(```!%``%84)X``$`1``#`J`$!P*@!`@'T`?0!1`^AP;[ZQ/S2CA+"X@)"`````(```!/"$``2`/&OK?W&ZS47XD`AUDGCSQ +MD["Y7KG"+X4!$EM +M?6$_V4;#[SY@HFWE@(OC_G7[/F#23K[?5RY(ZI<$VWJO144JF^5N9+L#.QHG +MTEK]6!*DF^=MQ/ELVQ5\_1::RHF%^"=6.(0G6^$*UU75OS8%GL"9)KFD%C)K +MK$7N#UL#D0&?^G%-!T7'2SM8,7')<)TT9**H64)J+@LBOA@/7MQ$*J#7-*B! +MB!"'"^*7L>,`,+_-B'7A)$IN,9"^M="#%"?``!`$0``P*@!`<"H`0(!]`'T`&0& +M29:?,6(K,#?5F-O$-#AM!E=$D2MT99?@<` +M;````&P````"````10``:%"A``!`$0``P*@!`<"H`0(!]`'T`%0&.9:?,6(K +M,#?5"(!`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``XJ(K$XS9 +M4S!'T?8[A\FP'0JAT^7^YJT(PTLHO[%##C`(4,3&)^$X+%-=>CJ\%<0#H?>+ +MU+$O@C.G1AK(-[UMUY/OHOH7WY-Q[NK/*PK@%$3-Z!>J_/]0%"D;6Y4=`JV4 +MR6L.7)P<"WHR,90/'P\L%84I```<``!`!*-(6IE&@S:5X.\GZZN8 +M%]1-I8^\````'```0`4GLJK.W*C]W(BSM]I58Q'-X2M]+DD2MT:0E0@`7``` +M`%P````"````10``6%"D``!`$0``P*@!`<"H`0(!]`'T`$0&*6+'!E&KTC34 +M```````````I("(@`````````#P````@``!`!@````&GK6T+J"V;H::589Z` +M+>3Q`TE/UDD2MT9WI0@`N`$``+@!```"````10`!M%"E``!`$0``P*@!`<"H +M`0(!]`'T`:`'A6+'!E&KTC34```````````I("((`````````9@A```@``!` +M!@````&GK6T+J"V;H::589Z`+>3Q`TE/UB(``'@```!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``XJ(K$XS94S!'T?8[A\FP'0JAT^7^YJT(PTLH +MO[%##C`(4,3&)^$X+%-=>CJ\%<0#H?>+U+$O@C.G1AK(-[UMUY/OHOH7WY-Q +M[NK/*PK@%$3-Z!>J_/]0%"D;6Y4=`JV4R6L.7)P<"WHR,90/'P\L +M%84I```<``!`!*-(6IE&@S:5X.\GZZN8%]1-I8^\````'```0`4GLJK.W*C] +MW(BSM]I58Q'-X2M]+DD2MT9BR@@`4`$``%`!```"````10`!3%"F``!`$0`` +MP*@!`<"H`0(!]`'T`3@''6+'!E&KTC346XPK<5>P.K\A("(@`````````3`B +M```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0` +M``(H``"(``(``-3+PL=[KL&.,7*BF4.,FYKH!\VCQ'C+!_!8>W,5.AQ +MU*F\`@@&GS7YDQ>_1A6XK=^_0Z&WQ%H&71MA\MA*%IC$E_S`P(R7$0&3/1IA +M\Y-2*0``)#V-I6U"OL-,"+L`K8O6M6I6R)A%PD558"]H2\UP!;`^*0``'``` +M0`0S%MK0TYI5K%>90$3<8U\8J8]M#0```!P``$`%G_\2U9$^I^2Y>,.DLGMT-:S8:0D1H?TTN/%82O@I?(3F?B._Z_2A=^8@3H:P9.=?Q9E.^//I6#ALG'G&HOAZC4?XLT +MX&\=?>9B\.B/P.K\N(",@```` +M`0```)PD``"`KO,7C>Q-V*9#9@QC%C^@7H:\GD)+T9$>Z>HVG>@>BAA8,FAI +MRQZ<)^/$1[LYO1D`3J(SP'B]*NI@KHJ&:W=E]7X*@F)*>`#$.P,-0.,*]NU` +MTE*;M38DA*;"WO`L9F,PL*R&;$OM^RU@BP)LQD-4P.K\N("0(`````@```/PA``#@X0VBQ#$SO9_E`B7Y +MQX%ZBZ&,7S&@`XB#,[Y%!-=-#=[+&[E*'2"9?N16+&+)GLR\7VO.B7O=;AE! +MP]9F=-U$>:TJ=#6DB'LQ'-B>)=A*W=[RJTJ)#U=D]#.8D#=Z1"W+>M->81*U +M;Q\,5EY6'URM")E>[<3?4`2__*RYJFB#DU>-U;A7WV=%>G5S(^I6/GMV0%0MH"EU_(^FJ6I$QLWJK3 +M.6*J$F$K+XB\^9U(L6D6@OJ;[C97)SG_QB3BDDD2MT:H.@D`_````/P````" +M````10``^%"J``!`$0``P*@!`<"H`0(!]`'T`.0&R6+'!E&KTC346XPK<5>P +M.K\N("0(`````P```-PA``#`8)(/C%62-`2)P4G,//]6HX[Z_;),\)O+G(MB +MPQ>#V=;F'\^S]HK\)2EJBZ(!V=E9B(]Z?"JK7P21(NIU9D+/3X`HAO6>U+V9T8\=S\4P&L4UY37?T&:2>B'JT@3H=+_]9: +MV\ESP9@!S\EN?U(@Y25U>+YA7\XU@LD;J+Q*5B"QP/9\IK>S(+H@ZNH%A*L' +M]%%YHCEYBB1CO'F$F^#3Z`7#.`088XOV3AA)$K=&M$4)`&P```!L`````@`` +M`$4``&A0JP``0!$``,"H`0'`J`$"`?0!]`!4!CEBQP91J](TU%N,*W%7L#J_ +M+B`D(`````(```!,*0``,$)6@&<4U/JPSZOR*+S3E>&*U5J/!@.V_4WA\6., +MQD,\]M;S]GHPJ,'@;(-K21*W1I1A"0!L````;`````(```!%``!H4*P``$`1 +M``#`J`$!P*@!`@'T`?0`5`8Y8L<&4:O2--1;C"MQ5[`ZORX@)"`````#```` +M3"D``#!@:M^3%@\(2Y&CP:;LE1W1$C!/(;89\1+@I0((NW'1>;1-<0",N!@* +M,18LE$D2MT98?`D`/`$``#P!```"````10`!.%"M``!`$0``P*@!`<"H`0(! +M]`'T`20'"6+'!E&KTC346XPK<5>P.K\N("0(````!````1PA``$`Z;Q*RE&I +M)9!]:R")Z/"3V5%<*.HMJ(,9924_XV-:4Y08,B@G,^S?88_=7DPN/?0JZR7^.6A/T5M*,N0AA/ZL9:?P82@7 +M9?[F:OCKC5?SBV;5SZXL6 +M?<6Z%VKP\N.M]).:RG(>B^D(-%C#_602GK0;`V*/&09_UY_+.K +M+;Y1<(!79;'; +MG+K-D+`T?A@0PEA"@8A@"5O?WX6821*W1K^("0`<`0``'`$```(```!%``$8 +M4*X``$`1``#`J`$!P*@!`@'T`?0!!`?I8L<&4:O2--1;C"MQ5[`ZORX@)`@` +M```%````_"$``."O=%$RJ!V4?\($W/*8WW,,6BA)Q,9]Q9Q.2NY4Q`<%M'P^ +MJGVA\LLUPM%^[?KMD7S,U,9*DY4,#BIVA570^;SAO80Y5:]3K:R^/ZM.MD(; +MSIR2XLGX11G@%B/**6$H_"2[M7OE^%?IJR<'0KO26L&;LJD\BNGG.J#J0V6S +M`U"*@]BQ0F9D*PK-;WM^$OU6J*0?,6N`$.8!/%!S=S(MYSQ7#Z_;8@+FW>== +M\Z4^<[@,Q23G\6^IR,MYTKR#A7/OM(&GA>W"WAB\-=-C18E>3?\Z#@U>CA2. +M\N-H[`VFJFU[K/42TM*//,1$OA\:LW?(E)Y-_41A>[9]*)0V>!^UE:IT'DJA +M4Q78(FFONVGR_:M+'%C$-J)*N6LQ=@*`NH55C^?X8)`CPF&`:)8=IQ'M9K#B09"2NT%TZOX$O[T!PK#40N?U++=]9385A7WZ#]5=J'>'/`26$^$5K +M?X`(XC.N0J"(SNE=Y%QKPKSD44Y16ZG(O9)(IHU:6?C=ZS-6S!Y372ON);Y- +MU!ZGSITW-'[RP\@,D$K`21*W1CC8"0`\`0``/`$```(```!%``$X4+$``$`1 +M``#`J`$!P*@!`@'T`?0!)`<)8L<&4:O2--1;C"MQ5[`ZORX@)`@````&```! +M'"$``0`2V8W;A4["Q%\HGH=L?-NF)+TOL5;*MI!H/GDY(K/T\5>1U>0^GEL- +M#PL+IMW;T::V`?#6LXFQXGJN'I0/^OV#/15[K\0X9N0A?73,F7+2W4&YECI9 +M!W"*O+L(_WA][0ZL(3PV1"-A7VGE*1#JL.`D]4K9',^%7#;3=44_%E&PYVV( +M=G>^3Z'@DU.75]01GDCCNB>H>!?+=ACPP_<^V_T6*^4IU<4]KN&$G72$=]-O +M)N.T`MA=`?-%;TP;ZAY]\4)>IK-[SC`!V2$&\!,>\&\9VQ[6+9=NX8('6_=Z +M"7I0`I34YA7FJ0+)OQVY\,JJO*;S?UL.]TA/*-SH54Y)$K=&U.,)`!P!```< +M`0```@```$4``1A0L@``0!$``,"H`0'`J`$"`?0!]`$$!^EBQP91J](TU%N, +M*W%7L#J_+B`D"`````<```#\(0``X.A+#-21(8T_,R)8!_6UKNDE=$!G-WBM +M)^UWB_SF_!"<%MU._'_W)3QT!%'(^;`U?L@ER#YC&B<_4,W6;*(E'W[T_:#G +M$Q(&%>VV4$J&E/)"F-A&!@A,A26Q\.DU.3#VH9F&@KDYI_4529$&4G7L7?2W +MXVD+T%@D;2W:#>%-Z,89Z.3Q:>E'VR.C!7@^,>0:B@`))7FG02!GX5[YXD!P56?X +M?_A3,_?>EG/+,M6T9Z.R.XXSS^^A+!@\O% +M2UD0)GV!&I1$90R`$Y(F-"=&6.0I3ERKDD3A[OV:"`2>U-F]8(WONF;/*^#R@?L<00;)"RD=Z"^MW+5DCY(&C9) +M$K=*`.P```#L`````@```$4``.A0M```0!$``,"H`0'`J`$"`?0!]`#4 +M!KEBQP91J](TU%N,*W%7L#J_+B`D(`````<```#,(0``L`Y92SJRPJ`X8:R7@20AJQ6@@ +MTAT7N:$33[!N6WL.I%'Y7IF_8IUFLPU9LD3Z'L"^CO,W<)S:[\3":P=1'<0" +MS7>?T?G`DN'HJO+U1H>Y90@.YW3T#(#;!Z9)$K=&##P*`(P!``",`0```@`` +M`$4``8A0M0``0!$``,"H`0'`J`$"`?0!]`%T!UEBQP91J](TU%N,*W%7L#J_ +M+B`D"`````@```%L(0`!4`G20@T9&A+[6U4[ZD9/=B'@8,H1LYH(G2U$YME_ +M)1;8JYE@.?.A=%6H%LEK6763,L*Y,6&`'DT@V(KB`O=^$@7_2U,2C&L%&SH8 +M*TNKP3U_%E1B(5B=R&7+=P=J>#^(X'%8D.0#A"#KB1ZQ<=*]F9_$COXR=3,N +MR.&JJKT3@5#CU:)Z6_]`)/;[P1_B]Z-1"WC$T"#J,MI*L?WK/AIZ5_%[CV6B +MMV3V#FO!8LMHZ*4KJ"?&X3P1E;;$$$KM<1G$O.P8*'('D&M%3AA8(2;JYJLP +M?&;=S!UNM#"#"OG^2<[5ATO0U2M)6+@!./[YXZQ^U9W6AV!`CC1N+S0WO!V: +M5SMI)\JS,+>P+=3>IT\PQ]8LE\4.!!-0&`@!*8052M/,O$]P83L3]\G$^T-5 +M7?W")?L(][L-EI)A[.>[\'?X/(;;65^!_!_L=>C)A&QM*Q]<0RN%MI[4.Z,@7?QAO(M!2TQL\I.725"6/739^6F#")= +M`OYJ\?PVY>3<`W^Z-I":A$J+5H=MVV['#[@PT+3(\D!" +M/!'FNA#&O&<*C#^5BEJ:6W]$V61Q=I(7!C_FO&ET]#S$M>U=;D!L_E9G!N(# +MOP"FZP#-D0W'&.1]*&QG^;UW;"H2-&Y`LXT,$.)::W;IDG-'ONF&0G/^`3-2 +ML,#/MGVXUC/:`9)O2-W,$H<9]-S89XN_W5E5CN%"W``!`$0``P*@!`<"H`0(!]`'T`&0&2=W"7R/I +M'7BN):.5JF63PK`N("4(`````````%PJ``!`L^-SH?[1A!*XEHY6J99/"L"X@)2``````````3````#"VXB!/#8!REPKPX'_, +M\%;)_0-N-1$:%?1&]#4F7OT2HHU()#"[<==;C/`[\DD2MT8LLPH`;````&P` +M```"````10``:%"Y``!`$0``P*@!`<"H`0(!]`'T`%0&.=W"7R/I'7BN):.5 +MJF63PK`N("4(`````0```$PJ```PQ_J0_(@_\LM6K4G706DA7JDA)M&%?G.M +M!R"=S_7U[[,X9WZ,14Y@0Q6N]*-)$K=&9<`*`&P```!L`````@```$4``&A0 +MN@``0!$``,"H`0'`J`$"`?0!]`!4!CG=PE\CZ1UXKB6CE:IED\*P+B`E(``` +M``$```!,````,,M]-S]_5?4\PVJPC=O[YQ+T)ZD\-9G!9>*K^1W'Z"(!`'@` +M``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``4#WVR:!^`;1.)%:4 +MF=`O.LA>5AIJ'L)678D.]S<@Z.-]<@KA7?%$RS7I2]&+C3O",$C735LM>\`E +M]AN%AQ]JV@A2TT0+3\#O\2M@920;338+9]@I?V:H(,$.*-R1W_A/U8->L9\Z +MV'$1?ZG]90>R^_P>%>P!%;Z&#&?;,._,.28I```DHEI,`'7%MNTU>J_,V9`W +MW^/P;$.=,P-^"A\@M^BS*-PI```<``!`!-YOVH.?CMB>-V;/`L+E3;Z#,Y#2 +M````'```0`5))Y;[+K)5AIJ'L)678D.]S<@Z.-] +M<@KA7?%$RS7I2]&+C3O",$C735LM>\`E]AN%AQ]JV@A2TT0+3\#O\2M@920; +M338+9]@I?V:H(,$.*-R1W_A/U8->L9\ZV'$1?ZG]90>R^_P>%>P!%;Z&#&?; +M,._,.28I```DHEI,`'7%MNTU>J_,V9`WW^/P;$.=,P-^"A\@M^BS*-PI```< +M``!`!-YOVH.?CMB>-V;/`L+E3;Z#,Y#2````'```0`5))Y;[+K).LE"LA("(@`````````3`B```P```` +M+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"( +M``(``'?#,,&806=XR]6,+;+IMH@T8@+M*G@"0,"P/J&=0'BFXSLU-1$I_ +MN&7%!]]O\*.3--[>;ZO,!U?"N<-LZ2`?[@N`WA;W-29`IQ\HGMMFDB4[2+;6 +MV.W^G0_N0`)M<8%H9`UTE/LT.M`$!=Q_BY>WF83O,J)\H:*9S3<\%5M]*0`` +M).L24Q17>9$#WZ,"`/4[+D6B&:VU#="+;[?>1CM0C2[S*0``'```0`1A!`KU +M;9"X1JXH1=<-]1-7QW\6S0```!P``$`%'W\X5T7JNJ,=;C\[R[#FNEM7CYU) +M$K=&IRL,``P!```,`0```@```$4``0A0OP``0!$``,"H`0'`J`$"`?0!]`#T +M!]DS?;_:R!8^!Y;/QQRD= +M$PUGV4694_/Z[M/+[V$Y@M6&Z9+AP\- +M;B8M473N/6:%`*&I'Q68P_U-J*=$9_/ZD-7WW'W0T6?,ZRTJ&7&.LE"LN(",@`````0```)PD +M``"`DP4VC&;;WO;A5:RJ2LG]UM;,%SKA0+VL;RGRC.4&B/Q*:]4>'"_SO..C +ME+O?RO+]0P?)1I1MWP(%_SZLV5N".W^E0'44/J&4(/1O3BX(#0<3GGRZD>D_ +M0#GV8,0.G:S/W.LE"LN("0(`````@```/PA``#@K%(M!K+4<$@,SM74CHG`LU`Z +MS=L0F$7Z,X@+OWG]71A*V1^L.=T"=L]1D#-7E0?HA$%3D_J=5T($PR-35'9` +M3<2WF(+/'?"?OI$^5*E?W`CY?;)WUC[/`!;[KAN(PF?C^,(?G>01*D? +M+GT3I,!R&T=#PTI'!L4[IBG[!XTPK?G>#H\QG%9;4-CX7W0U\8G]%%W^/]'4 +M7]!O[Q\V9>;S2F5PN;Y1$Q)@)GS%V;/F$RV25G53B8W&"%?H-?];HLPD.LC>^-X18-SEDMK=D"YLTD2MT9L;PP`_````/P````"````10`` +M^%#"``!`$0``P*@!`<"H`0(!]`'T`.0&R3-]O]K(%CX'ERP:!>.LE"LN("0( +M`````P```-PA``#`G>YD/3''&A/P)-7CTV>9*XJ"/,@?:+?AJ56MI-K`NCD_ +M4E^=TQJI$LL5WZ[9#:*-]'LN;:25308T'CCX4O^)`[C*ZIO4K6NY"LF(0O.[ +MC_6@8BX_^4ILBR%M%"TQU3JQ(V&T)D]$1(!=K4N-&J*#U?DT?:IPF5P:MLO* +M/"KI!>A,1/XTH`!+<`&TJ';ZU6/IR_6^Z-OB#R0-^P21"8A&\&M)V6^53C`- +MI7Y\,QBP[&ELA&[GA>"Q]R,;R5#`!L````;`````(```!%``!H4,0``$`1``#`J`$! +MP*@!`@'T`?0`5`8Y,WV_VL@6/@>7+!H%XZR4*RX@)"`````#````3"D``#!T +M)MX$O;"<@]LN(O79YA&\!*#^]WSEY_TGM/$#8I1.-W3SCK&`ZBU[_"=K9DD2 +MMT9BL`P`/`$``#P!```"````10`!.%#%``!`$0``P*@!`<"H`0(!]`'T`20' +M"3-]O]K(%CX'ERP:!>.LE"LN("0(````!````1PA``$`70H[,PR?$9QXL?<= +MBG01\-?WXR0F%ZD;,8.&-'9`^07>)YWF1^&D;=PD;;;\7JT&F6R/M)0Y#"'W +M#%JEIU0)SU?C5,,0?[%M^%R-P[UQXH3MNWP[LIA`-7&2>&E?TBU@*/??;QXB +MEK+B3GY@ZX'34M(H!AYHVZE)[`$934>=>$Q71'DJT\/@32)S$Y$7-&357*5V +MK=F?TAZU^,8@;'U.GBR/T%ZNP[]D0[/:.[_P.22RN'''S0!MZ<.6C;0=GTZL +M>H>?5NUAW;6:Q?F';/Y:S)::A?F/$9PKGAQ!=YMG>[[Z\;$T&GNZ9)L+#A@C +MSF!T4!E&27`GHI"%U"YX21*W1M:[#``<`0``'`$```(```!%``$84,8``$`1 +M``#`J`$!P*@!`@'T`?0!!`?I,WV_VL@6/@>7+!H%XZR4*RX@)`@````%```` +M_"$``.#2BE"A"Z:,N?.W8K!6,\6-:+4GE(ZFBNY9'+^L#AH=JPS`$_C`_E`] +M[W&%\4\)Z!8Q6^J"VU7M'R[;X62.X@>:@EU.:*%R>=4$ZB4!'!RQANA"LJ?0 +M_%B7SFI7KCU)KA4>IS'*6\D05Q[@9F)G[=<1G#QQ.+5!;&].WF;=8$".%(1`"W#`+N%N;L7?OO96'?(F*&NC_W"Q.'H^=NP +M(1/7CB#![R3Y(QR7N+DL:WQ2ZSIGLXD7$FA,1KM6"3)N`FUYH-K,1+7%0O]8 +M21*W1A/+#`#L````[`````(```!%``#H4,<``$`1``#`J`$!P*@!`@'T`?0` +MU`:Y,WV_VL@6/@>7+!H%XZR4*RX@)"`````$````S"$``+!`7%IFO3`SFB22 +M\("`/=IE-R^_T0*I?:KK@"!ORXPP@19EWC=@7Q`S#8ABM0JH$N&=+DT_JM/L +M`H"NEU1M5-OYO,+'XPP5)I``6ZV"433&`V?\;$N5L2\@T]*Q*7YD70K2+&^L +MO+H0=4.9.V>F&7+!H%XZR4 +M*RX@)"`````%````S"$``+#'T-T\JN%)5(&]OPDO4)Y>1=!X'/:L!5_H<$M\ +M]!U9BTT*<$V&\XQ0P7Q(YB\?OTW.6GRO2$[B94MM[?J4:\RC&1<`EW;&Y85S +M2G&J8Z#.KF\SUUZ:E@V!MOBHXN7AL]1DQM"\W6<')SNB'D./0A[@!C.WLBV$ +MXM7+!H%XZR4*RX@)`@````&```!'"$``0#P +MM<+*\C@TW[%81[F`BYEK$P%X6RX6G;_>81R1?TK1J@:!")KJ@8(,/AGS6EZZ +MF4Z,2W]Z-/&=\\%#_')I"8?_+;]I8VR[,DX`EK7"?_ET$'ZFN:C[J1L!U'R6 +M>PBOY<7="`B!G;4H@QW4'O^$?[&\H'.RWZ1/BNF`44R0\L(T_'\H&52.9EVE +M(NF.RQ'H\VG/NWDT+H1FQM@51KQL(`VY5QCLY'[N$<4M1U$"PW\"U?QI6HF_9$ZQW:.A$",#>]^A,LLP#K*U\<%6V^A,CM`T&& +ME_RF2I*G3*C46D^4XQ!)$K=&RA<-`!P!```<`0```@`` +M`$4``1A0R@``0!$``,"H`0'`J`$"`?0!]`$$!^DS?;_:R!8^!YH'NV1SY33[#G9YV[3,QO+&'&GJH*XS;6 +MUO"<]`:/[9TH52D/DRN+6V-SZ`2R[OJ+S#!HU6R7HFHWYU69$:Z9=GX6;1[[ +M,YE+ZB[EGSQU;75QT3G*G,\E"JSZ[*,'WCPP:'#"(EZNTF+%R*GH!.:UOS-= +M*G@R=@3$GK$J;M8NM'D,^ZE5Z="F(IY?UKP1D40>8;Q7ZH*]XT34L]%-_VST +MTFK4!BK?*K)?8+8!3$I%]J_6IWJT+PIL':<)D8.3,'0>:8M=A +ME/B6T'#&8O$*,NTYC[9B]:ZK+0&Z:4G%,7-?C#K/!< +MWNUG#\/6Z$;CZ+6(U!/82PN2.;K!U]N;-@""O7ANDO6+YO/RVS])$K=&G$D- +M`.P```#L`````@```$4``.A0S```0!$``,"H`0'`J`$"`?0!]`#4!KDS?;_: +MR!8^!Y4JE +MYNW/;=1E+W'$W:*5WY3)4#$)XO$W9>@0"1<3G3K0:?YMCHH!/ +M%N#6UKF8`HKL?PDXHN^SX0ER]NUOO^QF\-`(P!``",`0```@```$4``8A0 +MS0``0!$``,"H`0'`J`$"`?0!]`%T!UDS?;_:R!8^!YRA(,.WS.Q#O83+$Y,HN7B<&I/JA9>TS%]>62W +M$;6HH#Q$1@JR0>=/5CKQ$5*^S*CHW'-%G*VW%_]M3"[;B*YC.KOTZ9( +M:YX/+_N3+LLW9^#7:9%H7G$K>0?Y7+!H%XZR4 +M*RX@)"`````(```!/"$``2#]#RAR[V8&R($>5(XK$7,@:@Y.Z`S"^%@DQ@T* +M-YEEO/9OW*=L:8V-,`],A9>F&#\YO)%+%O/%+*:?9> +MZT<>3R5>57MN*^Z4CL9^49E2E=[#\X>OG@+0>;=QW:X;D;N!B,J?UD&G1^=N +M4T/B+-HMH.T[GG6+.;D:+&.^%SKD/HX_J>1=M\TK3%)N)Q1'^J/IT;\$;BR* +M/9D$JOIRK;31DT1II8Y#P_)?'>7%^ID'G3P]1T_F<:)AM=A6>ZD'>6D0)H6< +M<(_JI>@J+E"AM3U:X2*)B^//>GSS'FO8TK?&7L_ZF-._)PJ!+U[6/\1D(L@- +M9P-N*_+7>']MX2R]GB)L1]9&-YHTL_P)Q;4'Y]G%.DD2MT8?R@T`?````'P` +M```"````10``>%#/``!`$0``P*@!`<"H`0(!]`'T`&0&2<@29T@>AC)_(13- +M;6?1U98N("4(`````````%PJ``!`(%0EH>:'!-VO`>MC]9433A$>"K#B/;E( +M1H>T!=O%R3GT3G@/BBYX7$:6.ML9OW-JV?'N)./.3#$F/,P<21*W1L/6#0!L +M````;`````(```!%``!H4-```$`1``#`J`$!P*@!`@'T`?0`5`8YR!)G2!Z& +M,G\A%,UM9]'5EBX@)2``````````3````#"<9698K#W!FF[$(_U_&)P2G]5@ +M8*)43A%/I%+:(1WVX\0BIG`]*L1=^TD2MT9[Y@T`;````&P````"```` +M10``:%#1``!`$0``P*@!`<"H`0(!]`'T`%0&.<@29T@>AC)_(13-;6?1U98N +M("4(`````0```$PJ```P,(C6=RX6/T9!-I:VG71NF&#@VB"("`'@```!T`0$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``AONM?&\&1"`OI+Z:-!>54VL" +M/:/8K13\YJ^;!W=_AXZ87Z31[`[GK$PO("2N__0CTV-BR>HC6C7$?]@SNQ0LB.B*5?ET%H`H)Y +MF`RO/X=V_Y3SWQ4:O"+"_[$.Y>4I```D#3]XAOAZ6LA&A@98OH>)/J)RF2B4 +M4=M<-FR"`'ZS%N8I```<``!`!!H+AQ#3F>_#A]8U.N=7L1ZJ['2V````'``` +M0`49@G\&C>YHV6`T/5UFH=E(>03A]4D2MT9L_0X`7````%P````"````10`` +M6%#4``!`$0``P*@!`<"H`0(!]`'T`$0&*9HJ%I3W+1E0```````````I("(@ +M`````````#P````@``!`!@````$E^RJ!Y7\\WU8K1%;6Q'WRPO\[K$D2MT8/ +M#0\`N`$``+@!```"````10`!M%#5``!`$0``P*@!`<"H`0(!]`'T`:`'A9HJ +M%I3W+1E0```````````I("((`````````9@A```@``!`!@````$E^RJ!Y7\\ +MWU8K1%;6Q'WRPO\[K"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``AONM?&\&1"`OI+Z:-!>54VL"/:/8K13\YJ^;!W=_AXZ87Z31[`[GK$PO("2N__0CTV +M-BR>HC6C7$?]@SNQ0LB.B*5?ET%H`H)YF`RO/X=V_Y3SWQ4:O"+"_[$.Y>4I +M```D#3]XAOAZ6LA&A@98OH>)/J)RF2B44=M<-FR"`'ZS%N8I```<``!`!!H+ +MAQ#3F>_#A]8U.N=7L1ZJ['2V````'```0`49@G\&C>YHV6`T/5UFH=E(>03A +M]4D2MT:&,0\`4`$``%`!```"````10`!3%#6``!`$0``P*@!`<"H`0(!]`'T +M`3@''9HJ%I3W+1E0+9^$52]QUWPA("(@`````````3`B```P````+`$!``0# +M```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``&IE +M9SJA1)P3\G_Z?>-]ZIGFQEV:LH47W9/T%P(826=QM1A3BK*^3G-IJ'&N=0UE +MLLQ6]LH;U=KSA3:>N/EK>:H)#11M!#AN,Y:UJ#U_+59*91SIJ[`?V(3D#1;!3AL!2HDJB0*0``'```0`0PZ7?NVEB*V.?[ +M_5!(:LCV3.P6>0```!P``$`%^`(0=I'E3W@`*8=F)%K/KSG#>I]*$K=&_1T` +M``P!```,`0```@```$4``0A0UP``0!$``,"H`0'`J`$"`?0!]`#T!]F:*A:4 +M]RT94"V?A%4O<==\+B`C"`````$```#L(P``T*^<8?!]6'_X`YV>A.R_I-;9 +M%T`M`-."*AHNTIK*`]9(@ZT.,W9*]P[JG34WN@'$)#7 +M`T5%Z&.&2CEF_@=MBH9TR`MC2A@@=*1Z=Z*8Z"W8XMYOK-UU!14&V*+N$BMN=\;L5, +M0J9&_/:"5DH2MT;6-P``O````+P````"````10``N%#8``!`$0``P*@!`<"H +M`0(!]`'T`*0&B9HJ%I3W+1E0+9^$52]QUWPN(",@`````0```)PD``"`$9VN +MC'_-'DJ>YDW)ZN)^`_%N/`0L.$>&>YJ2!JWM51V7X)[TX+6`X%*U&C*!U#L0 +M(F/K,'^;`SMO;A^EA3;^6K;X3SI,Z5Y;Q.5P$TV^K\S>>*5K1*$OIUH## +MW;;O:0'RQ%&703W?I(.US^DUX7>4]L +M<2GE?/<(/=V<4@MAF=5@9\0HC4(QERBK\9)34=G/;+5U!G\R/1_+\D&6>/LH +M-P.@QK_3MW%*9#&%S2>%Q<7@\O#&4HR;TI/^,W"U`7'K.03L,Q2KBT%P\AF% +M^=:C5`D(XT)_OV@G;-*.IVS:YKNN[C,A>3O%-%ZMG*@=]W+,GZ!LRP&7]*1, +M#A&3!8G[L9[\&/9<[C>VLE/AVM_KK3A"85C4UJPZSL8$H14\Q2_(:C-MF'50 +M]UZ[]&>4_N4F&MIY_T,Z&4H2MT:T8@``_````/P````"````10``^%#:``!` +M$0``P*@!`<"H`0(!]`'T`.0&R9HJ%I3W+1E0+9^$52]QUWPN("0(`````P`` +M`-PA``#`:!)B=-8U_F +M06]G.MSU58/1]D:,9]EW6(^Z?' +MIR)-2A*W1C^)``!L````;`````(```!%``!H4-P``$`1``#`J`$!P*@!`@'T +M`?0`5`8YFBH6E/`NB +M&/S<=%=G\D)(=DI=8?Z.*@K8U9ETO6:ZI"78,&!R\^+AZO6>^PLH3Y/R04.< +MEK'JJTX'\3L`YN[KO!>V +MU6[1-Z_/GR994A(2]AIIN1XC7`6S"(9.VB9#)40$:X>>_5!3XMLW6$S)34.X +M.0TVI&RRI,0A"4<\<).)$O*7N@=5$LP\3,+@_\';O?%U']?=D1NHDBO6;:[3 +M3PL63I%'&!!%(@X),MIIG)AF]R`^1PRD3*G1J8$">P<9AI[D4-*'1K',*<&9 +M&Q^?G?"[%K@72A*W1K.P```<`0``'`$```(```!%``$84-X``$`1``#`J`$! +MP*@!`@'T`?0!!`?IFBH6E/:`6*3]IE&JF]F$1WZP[UZ9HMRB8"Q*5ML@\;>ZMD;WT=2_[U96B;A&FG\'[.E6=@8 +MI6[M/B@4B9]FJ#T=^7Z67?B,?3=_XEJ^?Z[E$H8H"_1=N4X-2=')JRL[5F$% +M]]8:MV:G\>1/9ES*Q39%[TZ6,SHV+HI.36* +MB/`:;#;6[`0#,:,$R=B1^IW/ML4X/CB1?.&A]H'COY')W,'SQS`A2A*W1J?` +M``#L````[`````(```!%``#H4-\``$`1``#`J`$!P*@!`@'T`?0`U`:YFBH6 +ME/S+>,NM`\VDZ6T'$)[X512D^]0MN;8];IGLD#7V^>B\3G0O?96$".\G +MWV)8]C;.-X*K9?2!>!2250?;*F.-]7F_^[:<8U>%3?T=\^_:(:.!T'K)T?-D +MF(9N4O,BXHIFO6)"(]\H)U2A*W1BOC``#L````[`````(```!%``#H +M4.```$`1``#`J`$!P*@!`@'T`?0`U`:YFBH6E/BP*S` +MU@UY?F?YC9JW]('AZFV>L(>J>C27ND4A]UIE!8A#LI%V2]EC44*ZRF&3B-=# +M<0``,@"K1,[(HUVSP[N,J[?N-[@:-<87+?B`UB.G4\)2R-]O!&7E\;\ZKJNO +MZ13)N*Z$*PM2J!TC,51),(D>$L!XS%U$SZ(#@>7&LQ\_W.D.[W\0-[PK9HRG +M^RO:2A*W1@L``0`\`0``/`$```(```!%``$X4.$``$`1``#`J`$!P*@!`@'T +M`?0!)`<)FBH6E/FKC=FS:4K5W!T_E.$&3]@K$EC)#8\L(2A\F +M?I@>+T^U@. +MN0F^,L(O-N-Y4?]%\6K9!J#]%Q!F&YM1)6B[20*[+)>>U_> +MZ>P.UQ#PSV+E(#1E/=J0E;O=B?CRE@L.4HM*5B/'D2UW.EV^_%KJP!\^&JE) +MU)/,/S7*2$?.9S9Y*$K=&^3X!`.P```#L +M`````@```$4``.A0Y```0!$``,"H`0'`J`$"`?0!]`#4!KF:*A:4]RT94"V? +MA%4O<==\+B`D(`````<```#,(0``L!PX?(D0U4CK+)VA"1_#]0/Z<,A*`CY^ +M(Q5)I[.P>E7@Z\:[Q^H560=*<4Z'[<^H<2)<7-$&H-*U6VALOARP_/J;J_32GFV +M6-[!28&J=.#B^`=[97J1Y +M'T2T-T.\;GUC<]DML(/:-YJ#KI'>0:U&K1G-V)ET5 +MS8UP];D%).5VNCWLV/[2+">K"J0=3=UX\59:ZA213TQEGM +M9B*H6FRB^Z`KR"C?7F&U&*Y`F,AVYVH7S^@`-W.'^RUWP\ZO9>5*C/9B$D7* +MQ.YAXW8<>#=OZ[96'=&Q'?431ILXS>C]]W8)DRQDE<;IV-55(7\V6&#!*#L] +MGR@2YJ`]C\6?85?)9D0?KSIO/O/A2A*W1J.9`0!<`0``7`$```(```!%``%8 +M4.8``$`1``#`J`$!P*@!`@'T`?0!1`A@4(P,WG\CGS4&X1*R`<^"IZ1LCP7YFJJ#?(/<29E(B=I=(9]C52W^7AP_H' +M3D'O2Q^U-[B-\YS/H4<78I`$>"?29OJL?4H2MT;9P`$`?````'P````"```` +M10``>%#G``!`$0``P*@!`<"H`0(!]`'T`&0&24)6056SEN8$R/N^Y).4A'XN +M("4(`````````%PJ``!`!/4$:R%8+'G)<`A_S>DV%&S5@?XN-#L5=_4U1M1( +MDY-)>GIO/<.#7\P!>!7A^Z!*'3=49+FS8[1*3?]P.EB, +MGC[>/FP<\(!;OIB\846ZMKZU[4H2MT;FV@$`;````&P````"````10``:%#I +M``!`$0``P*@!`<"H`0(!]`'T`%0&.4)6056SEN8$R/N^Y).4A'XN("4(```` +M`0```$PJ```PH5QW!#;&`78S[D'SS9L&L?T):86]4;/9!9$1#!B@S'SZR8A3 +MHBY?OCF%C$I*$K=&TN@!`&P```!L`````@```$4``&A0Z@``0!$``,"H`0'` +MJ`$"`?0!]`!4!CE"5D%5LY;F!,C[ON23E(1^+B`E(`````$```!,````,*)< +MYUUON?^+NYWA?/\8>-PO*><'@MZ#1/)OZ"N$3-E?2=6!%M;\-8+A!=462A*W +M1GWF`@"8`0``F`$```(```!%``&44.L``$`1``#`J`$!P*@!`@'T`?0!@`=E +M8RT0C"(#`'@```!T`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``UP7*D!WA<.F*3%$U1(QQQ_)S)<;K_G"9 +M:F$&W?2@_=-BP%P>ZJ(?Q@\70KTKI.?E;CSDVO!9QW.`?1)"6W42D.LRYFW. +ME*/ROBX!!DJR]31':PY,;M$A$X"MD=9N/?G]\0?R)"N790!0AETS"KWG2+O* +M'2,1A4YF-%P!-X;ID/LI```DW!]MW1YY*&D7SP2<"Z`9$'3$HW#L]:1XL2L] +MQ;7+\T8I```<``!`!%(U6RF#8E3WC^NZET0*_"HO<"0?````'```0`6]U93K +M?;4#0WNE\W\NB&@!*T.GZTH2MT;O]`(`7````%P````"````10``6%#L``!` +M$0``P*@!`<"H`0(!]`'T`$0&*6,M$(W.&TR@```````````I("(@```````` +M`#P````@``!`!@````$>6E)("Y]A`W,1L)&1;R>MO4).3$H2MT:?!`,`N`$` +M`+@!```"````10`!M%#M``!`$0``P*@!`<"H`0(!]`'T`:`'A6,M$(W.&TR@ +M```````````I("((`````````9@A```@``!`!@````$>6E)("Y]A`W,1L)&1 +M;R>MO4).3"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MUP7*D!WA<.F*3%$U1(QQQ_)S)<;K_G"9:F$&W?2@_=-BP%P>ZJ(?Q@\70KTK +MI.?E;CSDVO!9QW.`?1)"6W42D.LRYFW.E*/ROBX!!DJR]31':PY,;M$A$X"M +MD=9N/?G]\0?R)"N790!0AETS"KWG2+O*'2,1A4YF-%P!-X;ID/LI```DW!]M +MW1YY*&D7SP2<"Z`9$'3$HW#L]:1XL2L]Q;7+\T8I```<``!`!%(U6RF#8E3W +MC^NZET0*_"HO<"0?````'```0`6]U93K?;4#0WNE\W\NB&@!*T.GZTH2MT:[ +M*`,`4`$``%`!```"````10`!3%#N``!`$0``P*@!`<"H`0(!]`'T`3@''6,M +M$(W.&TR@;9-$#V0,[W0A("(@`````````3`B```P````+`$!``0#```,`0`` +M#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``!B&Z!X^AN'Y +MC2QQX-2;A$+I\IS!7W3!9O^BL-YI9U1WW:GC[M-!7*9,=8!AE@/==^ZW]YQ#7'2,7MT#?6&FR\I`F +M2.DP<33F/4`+WVB_SW)J+N3 +M;RHY/7CUWUI$TO34>-;^GFMY`:^4*0``'```0`2LW"5#R1>GCRQM=!Z"/2OA2A5UD"KPO$DHI50(9 +MM1-N`XCHTO1VC9&:P@8W0#IT:`HQH>,>EXI6B]!^AR8!P.S!PGG!!_?\:IRG +M'Z8MDB)=*&:)AZ?"OM<=^3BPVX?W=MJ(*EIV_R3JTO>,5Q!>W(9P[+[NYXJ+ +MMDH2MT:F;@,`O````+P````"````10``N%#P``!`$0``P*@!`<"H`0(!]`'T +M`*0&B6,M$(W.&TR@;9-$#V0,[W0N(",@`````0```)PD``"`&T\0%+\!#HT< +M%WH?H+06%?N_WD&X%:.W-[X`S!'&Y]IGSI]F*ZT;HRO)[J+7OYZVP;+M__23 +M*46!/4-+P-C#@E'@$C'5LADQ^SPS]9X?-1LCZ/=M;`I]%J/%32KW#6F(J#8Z +MRF<&*2[6>;QS;XY-\`A[&P?O=7+8&IRW[DH2MT87C@,`'`$``!P!```"```` +M10`!&%#Q``!`$0``P*@!`<"H`0(!]`'T`00'Z6,M$(W.&TR@;9-$#V0,[W0N +M("0(`````@```/PA``#@TTB4NL(87XS+:#1\9GQ2/_-YB$?ZC(%L$FC6D&(/ +M`83.?"87+<4];]J=P'#KMX2-[U"*E/X*!\E?Q\S)'>"WI"$J+-X,!4IT"`,! +M;]:$,8SR0$A=`&'/F]@)KCG#YFHN1;].S,QL7[8`(SSIG,X%<9IZXP0;[E7Z +M+P0A[B:>TVG"=M.RPGN#PIBU%.KW`EMGEK3H3EEEW!P^>;34C^-I*ULU&9W@ +M`R&UI*SX`=3!``20Y>[A>IJ%=S#V#,R$-7*!`*+6IDV2/+'BT$3^)(B#)//- +M4=-LA;+')!(CZTH2MT9:F0,`_````/P````"````10``^%#R``!`$0``P*@! +M`<"H`0(!]`'T`.0&R6,M$(W.&TR@;9-$#V0,[W0N("0(`````P```-PA``#` +M09)%`YGEAI=@V?I-WJ3`+9ED7PF+N`F +M&9Z3/R)2HT8<;[N&F[8:72S[?Y1;*F$6[<,H=AAPN`FD:C0$PF +M5X)R&1D/Z'!*$K=&JZ0#`&P```!L`````@```$4``&A0\P``0!$``,"H`0'` +MJ`$"`?0!]`!4!CEC+1"-SAM,H&V31`]D#.]T+B`D(`````(```!,*0``,$SZ +MA8E\UJ;?HS0SA95\#\O&Y&JD2A*W +M1B_``P!L````;`````(```!%``!H4/0``$`1``#`J`$!P*@!`@'T`?0`5`8Y +M8RT0CA4!6+ZX![Q634H2MT;KV@,`/`$``#P! +M```"````10`!.%#U``!`$0``P*@!`<"H`0(!]`'T`20'"6,M$(W.&TR@;9-$ +M#V0,[W0N("0(````!````1PA``$`4T8''P@/,W#]1(_&,Q]Q6#TCYX0B*!MN +MO>8_J%36\(>)+;X`3\8]^:7OC=;M:P'Y*Z +M`O!6&K]T[)SK"^IKX4R+G5L:CW-218[#/^4+$V!BV/=7,28P0]S@KWM+RQN6 +MFKVA7S`@@MBE`G\]HUG/K&69A(1(T +MH!;72A*W1OKF`P`<`0``'`$```(```!%``$84/8``$`1``#`J`$!P*@!`@'T +M`?0!!`?I8RT0C3FOX2A*W1C7V`P#L```` +M[`````(```!%``#H4/<``$`1``#`J`$!P*@!`@'T`?0`U`:Y8RT0C\N::,,#_A!# +M383)A$31$K&5BWWAKA!B.SR!-6Z'_%\0I_<^B&:6E"*9(\D:-SI0BQ4FYIS. +M[>^9+S`%+,H2EZ&/,:A[!"_+^P5/+XU#2(H&$W.8+23F?QLB_L` +M,T:,"&]?9G`IN?B#";\H2A*W1FT8!`#L````[`````(```!%``#H4/@``$`1 +M``#`J`$!P*@!`@'T`?0`U`:Y8RT0CX%%IU$3+?`^+5-C5[9' +ML"DJ*A6Q,\]F+>@]%4:5+N3P[V#TL.!*,-D@ZFOYZH=`]/>]K\ +MN<3/Z5*WQKS,`(RQ1L;@=*`.#B2A)NCW]-]9KF3NLANQ:;]FP/?%R5LM>EQZ +MAR9TW"*_$LB!V9VV>Q:CC`24X8OT53'\>HPPBU]^NW/S^6&#R+#_:;?\2A*W +M1BPV!``\`0``/`$```(```!%``$X4/D``$`1``#`J`$!P*@!`@'T`?0!)`<) +M8RT0CC:*%;1&K%MT_A*\'-9>_>B +M0.>2HV2BP$I'=(F?$*:ZXGM=`00*=%"))Y$"CJ:VTN6D3J+ZX")2DAXHD&X) +M9'-.1J@EZWX9VO071U(VX$7ZX&7VFFC7CX_8L%`:*NP4:@7M69(U7=_^`^TZ8LLSTMY$M&M:@WY9/8*Y"-=^.M[-) +MNYG75I&OUGPT0HIV&K=*$K=&LC_!PC`XUCS4M5$_:0_$!\D7I!(8^-HMXP/GW6K2DA;,EJI)2 +MZI&:(!?7K15@,_T_:WXJ0J98TDONGY`EE&38&".#MY:1O9]YMQ"H4!FRD:"` +MG9$>TO`E:UT.8@.F>=IY6V9_>G:TBHS>,J/LK>3+X$FBS3[SO7?3`*WI9>$L +MY&/R5Y45D%,W#%5C4MBSN5N@"MTK)E&4/WM%%KTX^L_?>\YSF@=._V3+]P[H +ML\);,&2O\9]\@$7'* +MV/!85@9UP:E1G#>H(/`@X@T>UL&89T&.";U<98JSZ>DA+!/D#H8QNR=)F2WZ +M(KL5"9?J6@44>6#HW29;\,?;$AS))>N4`5P;*[+>_W`/;RN +MWQ?[$``;CG),NW]SOPUNC>`;0!P:+8A7 +M$G=*9X7@FG-*$K=&I9H$`(P!``",`0```@```$4``8A0_0``0!$``,"H`0'` +MJ`$"`?0!]`%T!UEC+1"-SAM,H&V31`]D#.]T+B`D"`````@```%L(0`!4,`4 +M\V?TA+A9/J4$5E&TLT$F4V6M(M2+G3X7B#6)`7R+0:W`',)FV8BZ86@-@TUL +M71U\Y&VS;)K(3,+[A%7!%^=.>!,/T&E1[3_"J-GBF=\C#[]<:O+MA6DV?!(? +M@]U2PMCWB&#/"J8JR43,##SX+HKKG7X5M+'P*XM%@![COPQ,>S3@(V_R,1JK +MWIYA7S]]X$,A&1"?ICEW`WU?[J>_DL`X!4N\JKNMHC1%+X;M5;*/AF"UBU$CUAJQ0#4'#*VK3%;=?M9PN;CT%ZC^T8;,F^;('6OI_S-EE$))Q7:E; +M0SM>1HQ3UL=Q_+<+9$A_P.^F7UP1$'I)]$B`$@)H^JCF/Z&JN0XE[(]R'B0H +MX2!KX?V[L;IY@VAKG!UPWXW=MA)V*7(!@]4-]XOIC-9)*)9QEFL\2\%I1!%= +M!A&6Y08U("658_NC>^`)2A*W1G3.!`!<`0``7`$```(```!%``%84/X``$`1 +M``#`J`$!P*@!`@'T`?0!1`V=^=<)U%W\3TQ+66(=B?^U[8`QBBO%%R+%&W1RQ&%4Y^E*+(,?*]]F; +M0U%ZC8EF,44;E%"99OL\'/!7/N8E?4T;HE&/JY(V;2,7J,\ND=-S>@G3WZZN +MRK+;[_IQ":#+U@+4V_2>CAEJ>1C>/D6A?C_X>J?(D$^,0-*@]PTSF6[5+5WL +M@FQE3N+R:DP4H<%LG9=5/EM0[5`Q(+'80"_J$X!MV\)Y;O1()14J),5[S9$? +MUV28#>G:._,_;44=G\R&BTWNW4H2MT:6]00`?````'P````"````10``>%#_ +M``!`$0``P*@!`<"H`0(!]`'T`&0&230'OX^5@P,IX[TAF`QOQ]F(8^#=<"3LLBL`@"5W0I``3CH.,;'* +MHMS7OI#S4+1-Y7]%>Z86B$+(S4,K4*/#2A*W1@`!!0!L````;`````(```!% +M``!H40```$`1``#`J`$!P*@!`@'T`?0`5`8Y-`>_CY6#`RGCO2&8#&_'URX@ +M)2``````````3````#"61I0L.]GV6"(]=ML?++,7-:N)4;!\F:`I2T;SJ/+1 +MO^B"6_RB$SD&^I#M3_3]/S9E0%".0D=@TZ6M?0O*?1-_"7QE)7 +MR&=*$K=&!!T%`&P```!L`````@```$4``&A1`@``0!$``,"H`0'`J`$"`?0! +M]`!4!CDT![^/E8,#*>.](9@,;\?7+B`E(`````$```!,````,)ET<:ZAKKF% +M$>\R7XB!S3=5S]7"TKC#/'.UN+TP#X`;3%RQ93NGM<,Q3-Y:2A*W1N48!@"8 +M`0``F`$```(```!%``&440,``$`1``#`J`$!P*@!`@'T`?0!@`=E/9&Y5CV( +M6OP``````````"$@(@@````````!>"($`'@```!T`0$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``H>'CK])-KQ,YFYT?)-$&6-#\K:[#1'*.9(1MB9H<`1#;J\I%;RRY<:^D%)H=^(?M#+=*5P^ +M=>Y5;V2&$AHI```D/I@D;FA0KNKFXW>0XN*A#0-SIX#^U=HR1HI +M```<``!`!!>TT>HGCCCZSQ`P1#E9P7HM2;N@````'```0`4[C+CS#I97'CK])- +MKQ,YFYT?)-$&6-#\K:[#1'*.9( +M1MB9H +M<`1#;J\I%;RRY<:^D%)H=^(?M#+=*5P^=>Y5;V2&$AHI```D/I@D;FA0KNKF +MXW>0XN*A#0-SIX#^U=HR1HI```<``!`!!>TT>HGCCCZSQ`P1#E9 +MP7HM2;N@````'```0`4[C+CS#I97_P"JN3)5IU8NP`` +M`!P``$`%LVU9Z:Z-MK@%9A6-[=9&]1!E +MT;Y*^<7Q2H<%)<0@<2_%Q2/_IGMM4;S9O%G%X5!];BKVJ+]]6"JG!LH/P^$- +M@<+/'UN)>Y*W#SM\CV5G-6RT@D[AVLL3/NO+,$UU"UJ\`1-+/E`!T4E6AU-T +ME(9C`<9"]-.U"R,^LG]F>`G#HQ\VBJ-D<4!89F!W>Z-7T?A:$MNB[4RVDMU@ +M/5Y9%I%3WS^R"%D?DXAL^PN*404TBZD>/PFIR8.?OUC![DX9*3Z` +M)]]%%TR1'^^YP5_?0^$WX#O]%=SY;/1K)_'D03_]Y*SJ.+14`Y+>]G8I)=Z..Q`E]?,;.X.H +M''O=[JRICM+A&5I0,/U<0$V#4\; +M==,$F_,T6D92ZG/2-&(&)&-.E!NS[,;-7M5&4Q2/HD_T;J>J\AA'S?!.M7ZI +M]4R%;=73O=B'"QMV)E&!.%_F@D"*D:B*9SA?":4BO2M,9HF)T]MUP%X +MQU!4^DH2MT8=U@8`_````/P````"````10``^%$*``!`$0``P*@!`<"H`0(! +M]`'T`.0&R3V1N58]B%K\(,R&Z01]O,0N("0(`````P```-PA``#`6[=F:!@D +MY/')$LIQAG?T?FAUU5?_E0G$QV1PX1`H%K_=B-T$*NQ)(^4AH0FP-K=3^Y+M +M#>L0T1F$0=JC4$@B2;[QK*F-1.J<8%*TCH8/L^3%U-0[6Z`ORB,K#T'[O>G$ +M8P*:NX;I?;NF?JU#6.=<:=!WEC$E+NK)2,1T(KW\^?@_BGY38+U9;0*F@)XB*2A*W1A;S!@!L +M````;`````(```!%``!H40P``$`1``#`J`$!P*@!`@'T`?0`5`8Y/9&Y5CV( +M6OP@S(;I!'V\Q"X@)"`````#````3"D``#`&V5%`@)ANNP83A@OM&,DSYGB@ +MD8(``CU;8@W=HGQO@#&J0:E,V]#'(K>^S#A8@1J\_ +M@Q%XA4BG/$5$(-CFIJ$ZX_+_QG.[CS2")D@&BTVNJ%-FHT6N(^6O>UV9+XRY +MCQ%6F54-YV9@7^X>2QP*F?.'C>1$DF*!@(H7._8MXHEQ%):1R@OJ_)V$EI>Z^ZUL6DYN9T,9R+B.02 +MT)=13?QC@G7`&*JGP0 +MKPERB4^L036ZL)GJMR,A0][Z)13`"L2PS(Z*(`;<9&XOC@^(01R;[!!&9DTC +MN!94?7%WIU4!:"2!%:CH\"/,)6>2,!DD8FTKH9GAJ(V3+I@Z8?*RN +M>,ZZ"(GK7\!TBP0L;17JO1757K^.P-(^V!M`1FN3R;:8IGSY]M' +MB-]$YI`]O.0H,])9#JMO$5P)^.Q6,QPXD*[I/]Y7XHW3GEUH@92O<+,^E#^J +M9]6A<1$!#KN"`R'!4!1Z7&N-4:?;+/T^0&,N[_"=<*>,1#"`H9A1>Q4EN'JU07SES6 +M5]9@$"&&.]ZT(]DY"C89(G[65,;#L4]]"A)8X$'U"!0\]G_<4E%]5)]<6>1Z +MNKTLC*7CWRMW336_3.!I.$(]=JASG[F%F3K\_8=D-4$TO.I]G]0KVW[0,JK+ +M&I`".LJW2A%*$K=&:G0'`!P!```<`0```@```$4``1A1$@``0!$``,"H`0'` +MJ`$"`?0!]`$$!^D]D;E6/8A:_"#,AND$?;S$+B`D"`````<```#\(0``X%5E +M]B&Y]L-G.-%M5G(TBS"";&K]SP/VY(D?R*WZ.D$$]FQ#D2\H4>&K42]7F +MVQ=?*\U6X[*"\!4D94*/AR(\;7$GN-;:+HG:EO9=#\`.WC33^6B=EY"%3FM+ +M9!E$]08%+%Z@T[YP;>T3"5J<_>C-"1,X48@X:NCG$UMW,V,A5=O4FLRT@%'T +MPVXRM^+^;2,)Y@D@Z94/:?9>Q(.VFM6M&C-<`QD.JHQT5JA_=SA7_IQ;9R(X +M#\DJW\S!O_J2YNN1%5-?DW-B5X4_A/T2,.F`PDTNCP@0L-[!9\]*$K=&OX,' +M`.P```#L`````@```$4``.A1$P``0!$``,"H`0'`J`$"`?0!]`#4!KD]D;E6 +M/8A:_"#,AND$?;S$+B`D(`````8```#,(0``L&LD5SO,(%M`*X +MEKWI1+C;[_EH2GJ6/YFOVE70@6$_G'F5!,U:7D%_20',45Q`T#'D5H#V8GLL +M=KT@%3&C9_(Z3GI2%2 +MNKHV0-AH(K0+>UKO;:9-$?4$LKID+0$Q?PT!908EI'E`D=FQEZAJ`>]E?!NI +M!?R[]T?5:H"D\T!X]^$V&,C6$$M*$K=&\J<'`.P```#L`````@```$4``.A1 +M%```0!$``,"H`0'`J`$"`?0!]`#4!KD]D;E6/8A:_"#,AND$?;S$+B`D(``` +M``<```#,(0``L+=`M7`O:E4-V[FK)K/>,`FI-JL3"(IB"7EK8XI:6AP^!ZT! +MQP^F6=#Y2S]2O8!O;+6AM?GR7LIJ<*3EBN.UX2LBD.UC+I#1BS!KS;>`A:S- +M,Q9*@6J05R`P@)Z#^&N/*NUGXX'$;5+O^,9W>P4"-""G^*8.<(@#4[!7.N3B +M*1C21RUVJ-2\,@M)9;@7T&,G)XAE.V:(EM041A4L(0[$E5X+CSL`_G*-L.<8Y*Q!9+$^"1>\H^R;J;=/[ +MIUD2K)OF`",W@"KNL(#[N_/S;Q+J]Z]WZ%6WN!+;:%D7QA"/[WLHCYO]WY1X +M"FC!KYTML2C&+U&PW)^M@!C^`.^"CH!Y%E-'['XMW9J;R#L"[,C,A,W=6WTC +MC?$Z&9<1F%&3Q:!QPYU]'=XZJ>6H>6IC5B*[9QX=OHP=H&.:Y+Y38$:3.2UOR[?)T[$;=R\A_E$!=L]+;P)6>[X/& +M92GR/!+^>G>S4GPY&LP#M+8DOYPDY$^]#^PT>$6+TK!/*LBMI+8K" +MJ!HB@-F[$G$P(]""F;[K:[LS*(O%$7``!`$0`` +MP*@!`<"H`0(!]`'T`&0&26RT.(!S]A0^:JY7H;`BK\DN("4(`````````%PJ +M``!`)S*^->+)L0<3;:"@VU&U-W/J-28/*S3'I*2.+AL"*OR2X@)2`````` +M````3````#"54#WXZJ<\MT>CY5UP]FS'C$KH)Z(JBX0JV$JA'X(KX?^&]FN` +M+EB675GK"4H2MT930P@`;````&P````"````10``:%$9``!`$0``P*@!`<"H +M`0(!]`'T`%0&.6RT.(!S]A0^:JY7H;`BK\DN("4(`````0```$PJ```PQL!Q +MO'X4+0J]4SU_@>%!XB'_KG2N#R0`Y)*%E'$R?R'[Z;L1!&C%+&F["('`'@```!T`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``N)CW;IGT/#(IQH;PW9'"_M4^VZ;FS-Y`AFS$/M!,34"\LSQJ +MQSL76M\HGT@DTWI-I.[_\*P071NR"H);&+(,I(-X`?3CO&0SX_Y2X-T?T'$, +MPQJYH^/1]0$':58@/3KEGG:OOVMU4LYXQ745T>C3B]"[D/`^[V]"[OT8[[;A +M_7\I```D8)@1$8TP*D@>>1@)DIWNI<5YT0X#C3B]"[D/`^[V]"[OT8[[;A_7\I```D8)@1$8TP*D@>>1@)DIWN +MI<5YT0X#``!`$0``P*@!`<"H`0(!]`'T`3@'':_B,A#MK0HB;9G7(:&' +M^&,A("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@`` +M`@,```@#```"````"`0```(H``"(``(``);R,C^U%4GQ2_SE%:,,Y"N.JWLT*:%JZ7'.@V*0``)!!/1P%>-WT1*_K7@PW".[[4_J1/]W*) +M`8Q:HS+U>R^[*0``'```0`2AF9[DL$O6:NJN;RMR?R(AMG(7(@```!P``$`% +MHAK3`')X.WFU@JS_UC].,3(Q@'E*$K=&=[L)``P!```,`0```@```$4``0A1 +M'P``0!$``,"H`0'`J`$"`?0!]`#T!]FOXC(0[:T*(FV9UR&AA_AC+B`C"``` +M``$```#L(P``T"Z\,Y=<>^,/H;G5]]G.#J;/Z+'($=`8XBHF>)WB^[9^KV*> +MW3BO=HE53+S@'G0_^UW5]Z$+5QX%E./L:]?Z*L/A(MJWNQ/L,"I;JQW`!Y1/ +M3/8EMHCEHW\=1Q;Y^RI?*:H>*>=-+K%8.>XM?OTR'HL%)D7%F3#Y?].;:%J0 +M]IIO#&TC%!K0O0)@%7&2?Q[7JJV+O@+=_4O?\!-D[:I$47;>/H=+6\H69=/A +MJLB?1P'N\TS8CFZ]S:7[UVXP1Z_U@;H.^.07I&J*#KJI-DH2MT;RTPD`O``` +M`+P````"````10``N%$@``!`$0``P*@!`<"H`0(!]`'T`*0&B:_B,A#MK0HB +M;9G7(:&'^&,N(",@`````0```)PD``"`=D*ZU>_>;'T;04X'2\/NU9F3_M:) +MB"Q@KG1\D5HGC<]GF5?BGU6[TFN=\;4E0A$VTTH2MT8A\PD`'`$``!P!```"````10`!&%$A``!`$0`` +MP*@!`<"H`0(!]`'T`00'Z:_B,A#MK0HB;9G7(:&'^&,N("0(`````@```/PA +M``#@I6,V/B]7G/SV!U[:DD89M-`VS@$B_P*UB=D1Z^K?R"=F]=4%)52SCKP+ +MD1.$$"BVB/6KACMGI8FET"CG3QK+]%:^GTQ5W;H])]$G@8]U]O$L"[&^RHA; +M-N7#.0:03Q5CZ)1;C^L[8Z]Z#)CJ9V=FX*6-F(L*JE`]<`=BD4`%*1=PL>P) +M3E\#%\;"PT#@6Z!K_CJ]?1'"O?6X^WDH2 +MMT9:_@D`_````/P````"````10``^%$B``!`$0``P*@!`<"H`0(!]`'T`.0& +MR:_B,A#MK0HB;9G7(:&'^&,N("0(`````P```-PA``#`(D]3$/A#YS+;C1[; +M!W;X[7),2ZL[52`_SEZY)+H8!Q(:,@J;/$U_!+6TR-WULO!J4E"XSTH(VQ1" +M:/\NGNDD79+JHGOW:>B=L/,$"54\0&0>I7`'V9\(PV161NSZ[NEM@Z*$$UJ>/HO9-*$K=& +MYP@*`&P```!L`````@```$4``&A1(P``0!$``,"H`0'`J`$"`?0!]`!4!CFO +MXC(0[:T*(FV9UR&AA_AC+B`D(`````(```!,*0``,+B:RKNMD;$^GI4_4)U/ +M7_1]4Z);=1\->,,/4;[-TIT;(E='OPF_!-/2O3/N2A*W1M,C"@!L````;``` +M``(```!%``!H420``$`1``#`J`$!P*@!`@'T`?0`5`8YK^(R$.VM"B)MF=
@\"25PR:Z863_&%_Y%85Z*C,V: +M6F+M:@66,J?'Z0`>4#55\LX=K$H2MT9N/@H`/`$``#P!```"````10`!.%$E +M``!`$0``P*@!`<"H`0(!]`'T`20'":_B,A#MK0HB;9G7(:&'^&,N("0(```` +M!````1PA``$`:(VU^(N]'D3B\]!63@=807D5EFV7.-`G=?[O"NZ=+L^(8[79 +M203N4E4U^W@;,%,W#LSI2[F%CQXMWP8=R_"Z(=L+G/F/'\VG!JZ2P"4_ASPD@,I>(] +M?M%CDB40N*RE09OY/#+"FF5KY^"IW[M.4@>=EONT3LD%F93E>)]GV7,YPU_TDN'/?&LO8!)U(/:_<1'VYF +MKI]#[NB,NU5;[6PAWC&E"L;Z(]?.5$"Z#F\Y?/OGKM&FH#Y-4D+-G[K`C<1^ +MC_%2?><1LOCW$4/;1,"LBZS)EL32`:3=IZ#/'-&AAD295ES/7:>U3,#WDL] +MG:BUXUQ$74W_YCAEF%=4=I)_2S6"*7*AZ(X$A0Y.MZJ\6+VI? +M5XBNK:T.^?:0EDO0F'H9=3,ZIX`9;3?A!(J7L0.*I.'$HZTTA=E_!3`G+"3Y +M_<5H(^^(RC'`FO$-#0R1F&5;"_'N5H*YAYR&HA;%A(_2VUN;N]B!KL1&G-Y_ +MR!G\"AI&A4/\QAV.F30+YQ27,:;2GW^S_=-!7Y)(_+H5L#S_X-AJZD^Z9^/L +M\WQCRZ;?AR,3G+KF-X@2F-3D*?!O]R&4B!L&*7&,2A*W1AB<"@`\`0``/`$` +M``(```!%``$X42L``$`1``#`J`$!P*@!`@'T`?0!)`<)K^(R$.VM"B)MF=F_W%].=/@[N[RU$"*+.$&^K.E +M#@7P#P5]_3#'O@Z5U7=5)^;'AF&.9FR0=BW_&(31I.$#X*[EI,X4E5&5M)KD +MQJ,/PK=]#B*^-J\%38NR4W6D$8"L0H1DFDO.KE)2IP+M"[SPRI/UP:V]63YA +MA\E*$K=&TZ<*`!P!```<`0```@```$4``1A1+```0!$``,"H`0'`J`$"`?0! +M]`$$!^FOXC(0[:T*(FV9UR&AA_AC+B`D"`````<```#\(0``X`.S;529BX:Y +MPJG&P3?$7D`7[G#5[3Y-V]A=#"":C#YG-UT:6+SEY]7B#T>^[[&Q>?=[3(AM +MYASE;E6Q)`ZW]QLKV&GJ^,/]1=5/;XE1/E0UV[EB8I]J!-:ROUCG1L&(;A(& +M)W11R9&0FNH:$)3_6K,=#ZMPP4-FAXZNS*%-C.N=O,''GSWO5$^6`\/Y"2F^ +MNM:^5T;\2!O(W6[FW?'T%!*$K=&9;<*`.P```#L +M`````@```$4``.A1+0``0!$``,"H`0'`J`$"`?0!]`#4!KFOXC(0[:T*(FV9 +MUR&AA_AC+B`D(`````8```#,(0``L/:NWST@J.H0N2Z>94W@1.W?!\-@/>X4 +M#36ZY+KV7'\H2M]*$C28'.^349%-@,2GA9H6JJFBAV_^=6H*&I'1E1@6D601 +M2&>**T;F'5"ZCE],0N)[8J5Q)KI;'C!7(D1;V:KH7U-#@$%+00-UMJE187`W*,970@:*SI+/E-FL85>O]MOS`W3T/RPWNEGEVBF"7F?;D]IZI-UW +M93?4U"]$EY^29HW4UP**@L2DCP8G2/@CW:R@#(++*9$Y0L;'@CLRU(81FW_O +M0J@,Z_A9D&]0Y(=TT')L9;$B`$%])192VEUA'Q!"]5L8ZGML5)991K5*$K=& +MJ``+`(P!``",`0```@```$4``8A1,```0!$``,"H`0'`J`$"`?0!]`%T!UFO +MXC(0[:T*(FV9UR&AA_AC+B`D"`````@```%L(0`!4.\2`@)^1,M&%K(Y7Q)J +M?E&^SBZ:]2#6D?[XV?V%@$))J^#*PAT40/Y#*P%($@W/!L'")%;(M",Z";6: +M(\"E4/2RJ?07 +M.!@D<#H'Y&;@),65\UUJPU6$SJ)42F1IR4Q-(DZL7PT=E(;-LUR$0-VB^P]H +MK305,E>AYU=LZY +MW)29[M9'#]Z%.CR3@'P>,9(U.EC:E9\V`YOV.4;0A0>C*8%A@FOX7-UFE:#R +MK&0%-L%&]/DL5;>;B[GKZ)V\/VPC:F$GN-QG$=A!OG#=QS^H,MJ^T)?ZL1]6 +MX)O*I=&NB>X]AX5G2YO]/S!7E?C"6NS``'DA0#Y]&8`L5U]0E!%Z;OG0U[WO +M]1L`2A*W1A@V"P!<`0``7`$```(```!%``%843$``$`1``#`J`$!P*@!`@'T +M`?0!1`YD?>1NBZV2()^:$Q.,^EI[S]Q45?2@U@RZ$HLSIEC_$!]BY"7Z +M$>TY[*8U>?+]0?!W`2R=:*;-YL'6N^N("[1C^ZF.B*6R!D/LH8`>:$X`%V%3 +M04CNT0.[>9++<)Z=OR+_Y"HQ7&]-I!M6)ZI*GF;68]&609?!+3%[;D-,XTO.5R10 +MUY+MB>.?1DH2MT;X70L`?````'P````"````10``>%$R``!`$0``P*@!`<"H +M`0(!]`'T`&0&243TBIF4P0^?D?4?P5T(@!(N("4(`````````%PJ``!`O^'` +ME>$5]!`L.\U0!:>&TC7;,LL-]CW+!6I7RH(87X)S-(0;JNKU$X3`)F(%CL,- +M597RQ($OD>A1\ORM2A*W1IAI"P!L````;`````(```!%``!H43,``$`1``#` +MJ`$!P*@!`@'T`?0`5`8Y1/2*F93!#Y^1]1_!70B`$BX@)2``````````3``` +M`#"*N]B,X!9S5UT3HK:\"&SJ!]8)/@=+7\$7"-$[5>/F7EWOYARE;7H+P8EV +M0TH2MT9M>`L`;````&P````"````10``:%$T``!`$0``P*@!`<"H`0(!]`'T +M`%0&.43TBIF4P0^?D?4?P5T(@!(N("4(`````0```$PJ```P\(;:BQ.'SO:; +M!:^?W*T'')J[Y0,:W5#>D4G,>-=T'ST/%&D]#-X<`4^\)7=*$K=&R84+`&P` +M``!L`````@```$4``&A1-0``0!$``,"H`0'`J`$"`?0!]`!4!CE$](J9E,$/ +MGY'U'\%="(`2+B`E(`````$```!,````,$3#-KU:\D9M+)?<@7:<=ZI8QL;: +MB!OF)?]7B?7+>:+,&^;+]YGH)JW';\*>2A*W1H:!#`"8`0``F`$```(```!% +M``&4438``$`1``#`J`$!P*@!`@'T`?0!@`=E<7$!&0\.=ET``````````"$@ +M(@@````````!>"((`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``&+I*MDBO5HA,E"$)--^_[!^!#G&:TK:K"3F;Z@@(/-]AT>*QL_:Q<%P, +M&HN)A,1K`#HCGM4WZ.M&JRDJ@3[W-A8NM3FWY[=B&8H;UHVW*A5V1']+FDW1W@O+2KWP$I```D +M9%!E?UB$R:FYA$C5@K-A!+Z62I8:6I!A;,<$3R<[AX,I```<``!`!*[QT97^ +M@V!65=<6HI`33SI60TBI````'```0`6Q4)P0!J97"1W*QL_:Q<%P,&HN)A,1K`#HCGM4WZ.M&JRDJ@3[W +M-A8NM3FWY[=B&8H;UHVW*A5V1']+FDW1W@O+2KWP$I```D9%!E?UB$R:FYA$C5@K-A!+Z62I8: +M6I!A;,<$3R<[AX,I```<``!`!*[QT97^@V!65=<6HI`33SI60TBI````'``` +M0`6Q4)P0!J97"1W,N(I&8A("(@ +M`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@# +M```"````"`0```(H``"(``(```6/ODOZ_/)[\>FVL8UZ8FSICMZ$TVN@DF"M +M^C!M26;)B$OR2%#7[.^XRH.Z#*3LI?2E%D3OL2\!E\H94-IVAQP7+%Z@;*UOH6:7[:=>0%+D-[.V:(: +MJ?@>Y6J=%9ZL'`64*0``)`A=UIG'1Y8\Q4&HH4=JL%<(?XJ:-0M,9$4A^@/]*$K=&0_@,``P!```,`0```@```$4``0A1.@``0!$` +M`,"H`0'`J`$"`?0!]`#T!]EQ<0$9#PYV7:]]EGC+B*1F+B`C"`````$```#L +M(P``T.D9!=Y:1*!K"P5HE4%<@JX/L=173%AH0`KBR)R;76X@I&BF51A*K8"T +M:`XU^,@KS*34E)$F`985::6]93LKKYF])QN?MEB&,!4-)7F`H%%E;MHMB=&:3(AE\R*MB:;-QKD0,%(&2/J!V;+V;&1X4-X; +M4"3,`UHCKTN_9,.HK8B(Q@2V",5'=X=)O"/SEL#I&@_JPC,FD=G^BGBH9O@0 +M+#5BM?$^4?OX"N^$G`A+XS6%W+A>_$0,OKFE-TH2MT8Y$@T`O````+P````" +M````10``N%$[``!`$0``P*@!`<"H`0(!]`'T`*0&B7%Q`1D/#G9=KWV6>,N( +MI&8N(",@`````0```)PD``"`?DNK8,0ND;3!PSXVB8BQ;G/IU5E[$@P6G]%M +M:SD#SM_+V]KDJ?F_&X881"A6SW)LSF$_(0*L0C%H1G,LO0*"`[J7CZ&)\'[[ +M\0)(J-Q=7H?146/)J/=^*%09KEA^[5=8S,BE2^(!$+\*#C!F+B-X[%9V**M' +M;H_7/[R_>$H2MT;`,`T`'`$``!P!```"````10`!&%$\``!`$0``P*@!`<"H +M`0(!]`'T`00'Z7%Q`1D/#G9=KWV6>,N(I&8N("0(`````@```/PA``#@Q@7, +M^W@%.PP-2@Y?&?['Z@VTJ"`0$*V]1G"(8&A@095-RD>O48)6>O&0>.DURXL5 +ME&T6MHE*4R6T9(MCQ_J[WW,XW_:2/.8SR\49*XF>P&"'KB]^]DT +M\%N7.RT9F(IJ)C/&(%G;#*G`%U^Y\3W#!J+7(.S*?I^E#P4MA)LZ6/EEG0#C +M#"&SVV32STR<,]$LQQ)_\T4@4,S%*'XC`)_Q3$]ZW5`K]&+VV2#&ZOUBRV*: +M"D&2*H0>B?-E.GP*&LO*!1T#.)I3I"",Q)$WXX&."LPJLNX9J4H2MT99/`T` +M_````/P````"````10``^%$]``!`$0``P*@!`<"H`0(!]`'T`.0&R7%Q`1D/ +M#G9=KWV6>,N(I&8N("0(`````P```-PA``#`EX;T,7+K)PQWRUV]AN*) +M5%372:A`[>[;!"7N17S:<&?N'47=PUT#'1KMYPO0SB^!N__0VK^>5#%34*[I +M?A"*5P8F(J+[(JET"[L*5I3?56C(S9^D-9>GP'(,\89-8GXH:/]J>]?/7E?X +MF^26],/AS1'5$F^&JOPG!1"6>9&]>7L8II6FS7A?U!E;%&-%@5[",N(I&8N("0(````!````1PA +M``$`CG73XMG`\T@;8.UKHNJ3^@/[V1W>=^L"0GDBJ)58`S5'N&-M*]R^Z!2/ +M:"M%"":WU(T;2G4)XP?#@%280'IF^)@Q4/W_]+9'80.%R;Y(G9BYH8=_B7;; +M&;V1P=CNE0H^UU5]N(:OV\`1P)@)',L>BA79Y&E)B'9^QVO5N6-3H$257N[8 +M`JN3,&8P=E06EK7S2`,2-OI[@6)85??%HY.D[V!L!?CP_W0L29A!3:A11^J; +M9!2+S;@FU!`EUTYK^:BA;+B`?%'WH?+F9'""X,,*+#"ED!%97GR4-XG$FY3 +MYA-&8(:4Z^?(\1$%,QH0%-T8B-,]O/BE"KK.@9".#!H/S:YH3+&'R;_O6J]= +MH#$PX]_#>Y0/;N@AUX'[;G?(5LC^K^@(V&CN%^'[%],Z+7`>Z^LYXQ"9%I(! +M330U2_FK<1<^PVHIP5S6>!=P*?:`'TZH7V<#3,Q_[]P#`DHQ*TH$R +MN>J;LA@16O='@'@-0PHN2A*W1E&;#0#L````[`````(```!%``#H440``$`1 +M``#`J`$!P*@!`@'T`?0`U`:Y<7$!&0\.=EVO?99XRXBD9BX@)"`````$```` +MS"$``+!OK]]`5!CE;/1?B@ZS]$8HS>T1&:B,V.WRS+Q#*F-U+N6Z5\'`Y""" +M!*,@1?/*1BT>LA758,^JM*66RK!",A96+$BVZGMI,A$$H<]5.:[A\S^H-6^3^=0P(+?NA_O[2);'8(::]=9N332/5YL)?N +MM+'>09)Y[29T+/SS$F1@YA#N;X5+`NYG[$5A@-A[:ZNC:29]],SYXF5&2A*W +M1@B_#0#L````[`````(```!%``#H444``$`1``#`J`$!P*@!`@'T`?0`U`:Y +M<7$!&0\.=EVO?99XRXBD9BX@)"`````%````S"$``+#XH10%:/S["X0R^I3#N[0)@"2AC%P+0)B?&A[U@ +M&(M2#L)^(@J'[T$!1"+CVAP+[G?>=XWF",9=D=WLCV2;CR+6`:OWT;'3W?$M +MK+6)?>P<:SW8G/XKS\!WDGR4BDJP_#H2`,3N)H9?;6":?.\Z(8D-8`61E@QH +M]/F14UC:OU&D-Q-(:P+:SQ^'HJ6"P4/7"T%E=V3'QQ.;SN+/N7-V#DZ3\4TN +M*=-*]WG\#VP"T/O51<`]U6-9<#H.>P +MH)JHR>,\<\T3THUFZVR%Y9*$K=& +M`>D-`!P!```<`0```@```$4``1A12```0!$``,"H`0'`J`$"`?0!]`$$!^EQ +M<0$9#PYV7:]]EGC+B*1F+B`D"`````<```#\(0``X+XTI+:[=3D0\41#?6]" +M\.P]\`C]OQZ6YT3DK=7C%[]+AC.DR4/0XQ%"L<`:.+72WGWP%J0+-.CS/P-2 +M;6=1(1W8M6PYPS=@D7"V+8F>V?.3T,Q6%B,L"JD,$8B2Z0W->%V6)\P\@2-N +MAE/WQHUZ_E[X^U"/;X36AFW2>Y6;X2B!I_PF$9)%$X*29413D_5OLQE +MP2W<,J-35MO^U1)@N.>Z-LE[<,N/?^=Z@#L]&'IUOR",7W&MA*VD^#RYVB.E +MUD(NXO;&V.(LI0&*9A"?`4%!)#!J&H#>LS9*$K=&S_@-`.P```#L`````@`` +M`$4``.A120``0!$``,"H`0'`J`$"`?0!]`#4!KEQ<0$9#PYV7:]]EGC+B*1F +M+B`D(`````8```#,(0``L%:4&4TJ+"B&58`>!<#DXIG"HHEB4K?<\M+^!ZK^ +M!>4>D<2^U,DJ1;L.5!4EOU%6L+_WT)@]3@;BZEX2HR$G$3TFF/N'*_-@AR^W +M@P^8IO6E'.1^+QB01:,W&&2]7929+][G8$MCVI=BIS=TU773:"R%^O-%IE&D +MJWK)%W=6O!*NP)\O`(7]$ILT.KI_,>XD*99PL?C]%<]=O<Z@2\498*8DI;Z0U;"?)P)N-ZY+5B@EQSOGI3ES2A%F].IE*$K=&#D(.`(P! +M``",`0```@```$4``8A12P``0!$``,"H`0'`J`$"`?0!]`%T!UEQ<0$9#PYV +M7:]]EGC+B*1F+B`D"`````@```%L(0`!4$V]1B]4"H>^F&!V6%>Y1%IW$)\` +MA8KD#+QS=^L<=2\EL$@UP+YRDIOMW.SMJ*88DQ"6_\/^.7KJ,L^8LTQ8VA>P +MIV23!U/%DZTVZ?YW\RWDWEB)*PIVUA-L0T_/%FPQOAN0#8*!.8;*?V>N:OW? +M\A$AQ=O59`!`GK4'3\?,A_N%:1L.4[NM;PG0__8(]>+F5M0?&<2@[WKR87[) +M\LC"$ZV3M`Q`E>M'M9N/QB;44(ZGW/W8$([Q*+N"7TD;,;P$SUB0KK0ES\/&VGXIL$R[HNH9DV=7/N`.C8RZR +M%OQY!12UC[.6D?%C6-?OG>7Q#IUUE]96#F46S^Q):_)+BK`]@`,23*>P/D%@ +M&;5)!W/X+B[K1D%M$M]QZV!V<7*_F\\5'K5!,^#0@#7;G->1:1J4IIL92A*W +M1H=V#@!<`0``7`$```(```!%``%844P``$`1``#`J`$!P*@!`@'T`?0!1`2.2:P2/BRPY8X$)]!;EN0K4Z43:Z#G +M60O!:O!RZ+/Q:>[TNK5Y!)("[JC2 +MF04W8:_5XZAA=MHY>:ZD/6J')PLWC1Y:.[?P>&3NMCRMZTVG*(+N3CIQQ91VPC.?KQ;0Q6&>4< +MZ$H2MT9"G0X`?````'P````"````10``>%%-``!`$0``P*@!`<"H`0(!]`'T +M`&0&29]:9>_.<]:LL0138`>".\LN("4(`````````%PJ``!`TZWM8QKG*3ZX +M*;\[+/]?B?VWJTO#JCO!.<(X)@9F`4R>:>B-H98450`]M!N#NT?HFND74H2MT9P +MN`X`;````&P````"````10``:%%/``!`$0``P*@!`<"H`0(!]`'T`%0&.9]: +M9>_.<]:LL0138`>".\LN("4(`````0```$PJ```P>.N9^'UE7!4Z%G?GE(SG +MAZD,J^SX5]^BTH#21S!#`NSO5L/-*$K=&M<4.`&P```!L```` +M`@```$4``&A14```0!$``,"H`0'`J`$"`?0!]`!4!CF?6F7OSG/6K+$$4V`' +M@CO++B`E(`````$```!,````,)3.8X\\S1T)QIE2[5\R5',\Z,XM*\M.9]A) +M'5URRK:D+`BXZP'M>X")O7]_2Q*W1NI_``"8`0``F`$```(```!%``&445$` +M`$`1``#`J`$!P*@!`@'T`?0!@`=E9?7)!26@";D``````````"$@(@@````` +M```!>"()`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``:QZW +M)>H,@F+ZX%@;"/5JBWUH]G4.I0\<;%^$FKVDE_VGLF1WZ-&Y*#JYJ?9*7/24 +M\ZT\2K7J>5\TC`YA7TXZD!J1YK\* +MK*PXGD.!XA;"\W2B\1*-WW=Z4>/332\R$`/"/W2'9^1R<$,I```DBE6\MN&T +M:+&XMBD1F\$"-!````'```0`4_F;_>J[+*-"R`#VQ/`5RA&7I=TDL2MT:/C@`` +M7````%P````"````10``6%%2``!`$0``P*@!`<"H`0(!]`'T`$0&*67UR04E +MH`FY```````````I("(@`````````#P````@``!`!@````$FP6_%4_<]Q6(Z +MHICL6DD$.6/?Y4L2MT9=G@``N`$``+@!```"````10`!M%%3``!`$0``P*@! +M`<"H`0(!]`'T`:`'A67UR04EH`FY```````````I("((`````````9@A```@ +M``!`!@````$FP6_%4_<]Q6(ZHICL6DD$.6/?Y2(``'@```!T`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``:QZW)>H,@F+ZX%@;"/5JBWUH]G4.I0\< +M;%^$FKVDE_VGLF1WZ-&Y*#JYJ?9*7/24\ZT\2K7J>5\TC`YA7TXZD!J1YK\*K*PXGD.!XA;"\W2B\1*-WW=Z4>/3 +M32\R$`/"/W2'9^1R<$,I```DBE6\MN&T:+&XMBD1F\$"-!````'```0`4_F;_> +MJ[+*-"R`#VQ/`5RA&7I=TDL2MT:&P@``4`$``%`!```"````10`!3%%4``!` +M$0``P*@!`<"H`0(!]`'T`3@''67UR04EH`FY_);F8_SJ%IH4MD=-^53"`AAO'O>I&8H +M:>_I1$CU]L4>5E.2?\F1TA:QQ?C_M0/9>=(L7/."$7K1G7Z.-_A;[;G*?5:A +M-F+=:A":%F'/IA+=K?>;Y97=PE[L32;!8H+S.> +M#^M4&90(*0``)([0:#E_[/R*+XL&U)&M=<*?FE$AAI;:H.9!7"9[%C$S*0`` +M'```0`0?YPB!!'FF2^D(3@H@YX"[D5^>2P```!P``$`%JJ+IRTL`FJ+;B#LS +MS!\_X<$J`XM+$K=&6>\```P!```,`0```@```$4``0A150``0!$``,"H`0'` +MJ`$"`?0!]`#T!]EE]!)"[$"V4BSQ3U&D.]OCMMESP]ZZD>$69?5@`?'YS#S_ZO"5DAG,KH@-U5NY^\58B]>XIV:SH0QTO]>3<#- +MISME>!WDW?\T%/(?N,NW?[]R&F\0_=HWRT+D-W.IYJ4V['F8BH[ +MI:IHGI]\CWMTWL4^E=Z.O$,ASLUI'4I&4H/=$`! +M%OF_+FXO,!EXK=]4")[K%,&*V;QDA.8LQAFY8DQT!@EP&T+E$ZG/R55H;E8W +MSDL2MT:(*`$`'`$``!P!```"````10`!&%%7``!`$0``P*@!`<"H`0(!]`'T +M`00'Z67UR04EH`FY_);F8_SJ%I(ID9`J?C91MC,75[.V\ZJ1:A07I5!Z/2-1"_7D`A3YC&I:%!BI2[L +M*EY+%XBLYK-".9753YB*O[&'5VI.X*IYE87/"I'E>(VRM#)+E*!X=7V'W52% +M'T$?.HT'1E^1/$ +M;(DH2:4=96,R_H$G\AM\3;YU/4#@AGXUYP=8##&VN'I:<^.R)@!@!PPEH'9K +M(48P5]/L9_=@6JB.#/'S'(SA"-CZ9[ZK'>@?C"6,Q4L2MT9H,P$`_````/P` +M```"````10``^%%8``!`$0``P*@!`<"H`0(!]`'T`.0&R67UR04EH`FY_);F +M8_SJ%I]RR!6N&4K!H4#Z$SBH!=]G#.19^[2`GWOM0.\FAPO,W\+C +M==:<$7=$];FE$9+IW_QF2?CCN4=38?35/<+=L45TZ\33L=6&8,NGU3*\9;(% +M^54L*+PU5=9K&33T2E,1,1<17;;]?SK/[0CJ;6-VVEBX?3`;.)*MR\!6)'*: +MQ@?-8%]AF'=_**YD:I5T8+L,/M4"^.C-K*X67CQ+$K=&,3X!`&P```!L```` +M`@```$4``&A160``0!$``,"H`0'`J`$"`?0!]`!4!CEE]5$*``%/GL>AI= +MO+6NSZT[SDL2MT9"=`$`/`$``#P!```"````10`!.%%;``!`$0``P*@!`<"H +M`0(!]`'T`20'"67UR04EH`FY_);F8_SJ%IU%]LYR=/]IK.JZ`1@4B)*+_=$LYO +M#L!2F9K`!K_DM-G4&R>5\;"6!H(+?Z)A5A9A-95^7^J@'+*DJ&XW[\L&O)>Z +M_VJB-TX,B2L,YP=+S^Q7LXZ+BJ+,R@D3A"B>4]Q4HW?S1$*MW\D7O$3HP/8`&N'N6[Y]=1.4W-A^BWXSDMR=.! +M6=RQU=/%>VYX9^:V1SRUT_^YQ2J!46HG/PYL6]RV#<,;LG&@X:<$/.MJZ^%J +M4U:$I>:4D1),2Q*W1HV/`0#L````[`````(```!%``#H45\``$`1``#`J`$! +MP*@!`@'T`?0`U`:Y9?7)!26@";G\EN9C_.H6ERX@)"`````$````S"$``+`^ +M-)31A,ZZIBR=6S1S6R1M#X0HYFROEQ\[6=?N-F1?;UGVP]-;LQ8=-NK4]3*C +MK8>!S\]U&ZK+R^(VJ[@&JP9+.(6ZKX5(N/'W%V99?])*5Z9??(B[$(X5:N$O +ML#K@_W>1A57??)JX\K)?Y).J6:*4%7_)*3OH8SQ;]^"W(T5J8LW/*E:P&F#] +MJUL)F;HH1LE_R)ZUBSI"6")_+&]=BX%3WG,+$'8%?T`OXHYR2Q*W1DVR`0#L +M````[`````(```!%``#H46```$`1``#`J`$!P*@!`@'T`?0`U`:Y9?7)!26@ +M";G\EN9C_.H6ERX@)"`````%````S"$``+#R+J1CN`[[?-R*@9H7TIO>3,\J +M<)%SE2T4!F'P+O70@T2ZS)C8BA\!@$=9A?)*U=&K`?A6@\_U#'1JG29:0^HP +M:!Z:.D05(87:0X7@6+/-GI3`4$MI&HR]\+P,2PK08-Q7$8&\K$FOQ<-2#3)Q +M"CBN'H(0OD6@#"Q,0'%+Z[SA^C'GGST]L$M__OUX_!BI7 +M6_6_R)F+UNX][2(\E3S=%L"U2Q*W1A'/`0`\`0``/`$```(```!%``$X46$` +M`$`1``#`J`$!P*@!`@'T`?0!)`<)9?7)!26@";G\EN9C_.H6ERX@)`@````& +M```!'"$``0!ERS_G'KNIY2AA+L('L%J+6\!`T6]2E=1BB5U]:)4<.C\8M5?0G+AZ`GH$N!H7R!P521)'S +MKV-0Y*&\RY0"+(\I]P%TKO1TW=L)MX_(EU>H/$$X2_^,5IZ*R_/$S'[2L=%G +M&.Y*(\,+1Q#XX0;_<8QPR80T9EE*7P]N1$="D^[QA5G`5%P)5B&NP%;VGM'A +M2JW7KB%)?0M!N?.3R8MI4='1ZZQ7X$5ST1Z>8(OY/,*-#B)+$K=&(-P!`!P! +M```<`0```@```$4``1A18@``0!$``,"H`0'`J`$"`?0!]`$$!^EE]]!!-$B5_B\;M?5>#,B.\&,3 +M28X9A7T@\9/^!]-`F1=:[O7(8F_CY6?9XDHOFCUW"IP?+S[F,O`BN7U7((ZR +MV.ZF+HKY3:G6K:>XR5+H**MTK/T6"F.]O"S>#GAND;P^Q0PQYNB*D_7;>!UF +M'E!EN>_%:(F=V>7MP`-\.%Z#X=?W$$]I.=`*(=5!/J4'^(69$EC@Y,>0S(0% +M:Z[<]OC'&;?14`(!&^Y8$Z4!W12WLAY#:J!AT7I@N(XR +MPU()7YSA,*&]O>AQ!-M$&"MO3.)+$K=&G^L!`.P```#L`````@```$4``.A1 +M8P``0!$``,"H`0'`J`$"`?0!]`#4!KEE]\H`Q/+0[G\/ZU9&FT$ +M35CU^"0"3'EQHU]KVT4EA@2XA/U+0H$+;.NF2D%^*ZV:$B7>>SBR9\`42;,E +M68C8UX."'@QV\1-JEP['<8NN0.?,(.Q6[Z01*8Q$K-.\L_G>I`U9\5#U^D6R +M351+$K=&C@X"`.P```#L`````@```$4``.A19```0!$``,"H`0'`J`$"`?0! +M]`#4!KEE]M. +MY$D%'*L9S5++YJC6Q^?7$D,Z9K+C$-(&PH3[?E%A>WY14/)ZG\\8?0)\$7\[ +M[O>?U+V>(U?(12;3"R0J&H])"2;<"T2A7OCX=5HG`;2\=GQ$-N6302%4RK_H +M,(VBJ4P5/(,L&XC[?B^Z7F(7Z%5)9Y^79VX:KGT1/`H]JBG3>(`U$0;AOV;^ +MQXY%-/'[I\/<<$T[-Z3XKVJK9.?;\9.H[\V2H:!+$K=&+S0"`(P!``",`0`` +M`@```$4``8A190``0!$``,"H`0'`J`$"`?0!]`%T!UEE]68\I+Y::U[/M!HAMOT>",B4A[OF^2YU\EXJ<=AG1FXN<@KDV`E/ +M/C;CE,#-<6<^*YAZ%@*V6'JC&&L;R]TH"\&I7'J]7;5J@+JT2;P +M2]3!#M(SYL-Q1$0G?K@"\&"BYV4#!5TME1`NM>L=5L?:I'#29&,57A%K>KKL?U3HZ0T#L:IR?E+@P, +M3`MD`]1O(GGKC3?PZA=07?L+#6!.!V8JD[U59/[-Z`J/I$%@A`YAO5^[?YE1 +M]4+XK59V83&H?88-?X#:#Y_#?AD.EAO,WE^D\?H(`K"4R\9Y2Q*W1NIG`@!< +M`0``7`$```(```!%``%8468``$`1``#`J`$!P*@!`@'T`?0!1`,E`JM\DD>9O+P!&'RH47>L@N881-PW16^ID?M)0/"Q=EH)?M$_NB"0USUY'=5LS +M(P(P=?#XE#HC,G#4G!E51@:^NV#\9P!N4R_]6/2Z$%[1\L6F9V\\SPZ:2H@H +MZJW($!LISNN$?KU5VC#$]G_;MQ_&'[93`(YQQX&&C;*1C-8)BIT/\QM6T"C[ +MIAD8ZHW*?S10I]<;P73F3E18C['$L*1Z[T=88[%HGOC$;-/V>%%G``!`$0``P*@!`<"H`0(!]`'T`&0&2;6: +M@..>N22ZM!43%V[$OA0N("4(`````````%PJ``!`YJ"FWN]#RZ[D7,@LQKXR +MQ[/S)ZY3]RTLQ0NU/T?JOH"JN`<(2YV&%(>Z4G*6=:7HA0^SV"F8+P\F9$&* +M2Q*W1NB:`@!L````;`````(```!%``!H46@``$`1``#`J`$!P*@!`@'T`?0` +M5`8YM9J`XYZY)+JT%1,7;L2^%"X@)2``````````3````#!3'B>;C_N&7G@K +M\ZUMN22Z +MM!43%V[$OA0N("4(`````0```$PJ```P@P]`:MO5C(%:1['XX9ALFB3(X%%] +M]5NXI16"\/XIY1[/QB0RAFVJSN:@@WA+$K=&#+@"`&P```!L`````@```$4` +M`&A1:@``0!$``,"H`0'`J`$"`?0!]`!4!CFUFH#CGKDDNK05$Q=NQ+X4+B`E +M(`````$```!,````,!\"[L..>#4ZC/&-#\_()&JGN9B!$'"Z58;&QST3QAS@ +M[&OP0'[$&EO&ZH'B2Q*W1I>R`P"8`0``F`$```(```!%``&446L``$`1``#` +MJ`$!P*@!`@'T`?0!@`=E<"5$X$FRT8,``````````"$@(@@````````!>"+W +M`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``;H'L^8*#52O=D2+=``9@#+J$*4W.;G$'%D`G)(/+)HAH?LM1( +M.7]X,ONU8UCL4F"UYNT0P\O7-FV-UV824%9?=$^5*2C*L(?4-[S#`PP(\UQ+GU&8:%N2UCC_%&-72F(I```DP?E#G%Z_:$X,0Z\V +M.3^OY`K>5O1B.W>S8N*G)!I1T +M-;86````'```0`5BJ)-K)UUI(/M%!`9=[J/_0CLC8$L2MT9-P0,`7````%P` +M```"````10``6%%L``!`$0``P*@!`<"H`0(!]`'T`$0&*7`E1.!)LM&#```` +M```````I("(@`````````#P````@``!`!@````%1MMCX]ED32)3R,/8I_3?9 +M(XL4?$L2MT;#T0,`N`$``+@!```"````10`!M%%M``!`$0``P*@!`<"H`0(! +M]`'T`:`'A7`E1.!)LM&#```````````I("((`````````9@A```@``!`!@`` +M``%1MMCX]ED32)3R,/8I_3?9(XL4?"(``'@```!T`0$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``;H'L^8*#52O=D2+=` +M`9@#+J$*4W.;G$'%D`G)(/+)HAH?LM1(.7]X,ONU8UCL4F"UYNT0P\O7-FV- +MUV824%9?=$^5*2C*L(?4-[S#`PP(\UQ+GU&8:%N2 +MUCC_%&-72F(I```DP?E#G%Z_:$X,0Z\V.3^OY`K>5O1B.W>S8N*G)!I1T-;86````'```0`5BJ)-K)UUI(/M% +M!`9=[J/_0CLC8$L2MT8S]0,`4`$``%`!```"````10`!3%%N``!`$0``P*@! +M`<"H`0(!]`'T`3@''7`E1.!)LM&#T;B[X%.]4[TA("(@`````````3`B```P +M````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H +M``"(``(``#Q/"PS9P+]7/_-\"4\)13CE5XLN,PV:L8IA_(ZU)C-Z3*CVQ0A1=(;%!8EDQ"1FX[<%>=>\'HB@```!P``$`%=\HX7C'@GKN=["NMWC!8OA3/ +M^QY+$K=&9"$$``P!```,`0```@```$4``0A1;P``0!$``,"H`0'`J`$"`?0! +M]`#T!]EP)43@2;+1@]&XN^!3O5.]+B`C"`````$```#L(P``T(XB(&P;VQ+> +MB3XZ>A80!GG!@34MJ9'2G[I-^_K;L*IF"44" +M>L>5YWSKYFDQ`P`4?M%;AS6Q"J(EOY[6.SN"M0U34/D +M!EHA?8%-0VPKMEVE2%4'WX>\OCH29,6)Y$9^J7"6@.%T%6LAAXH7UDL2MT:V +M6`0`'`$``!P!```"````10`!&%%Q``!`$0``P*@!`<"H`0(!]`'T`00'Z7`E +M1.!)LM&#T;B[X%.]4[TN("0(`````@```/PA``#@:7P^2H)F_:"0XFEH3MUS +M2B]'&Q$](+<('F%:Q'<$Y4?4<)W10H_D6QI]7F7*YDUDH/K07.M$X/W`/@EW +M[+U'?0`+W-*W6OM@;?4\#CQ-FM==>7.K3:;`:4ONP_" +MB\$,5'68O#=>0N.PR8&FR@/X][W3YFJYTE^M[L0B8Q*05$G^=C9200(ETOMA +MU`<[/72&4@"PZ="^IK(-&L.B<(Y7L]U?A$L2MT;Y8P0`_````/P````"```` +M10``^%%R``!`$0``P*@!`<"H`0(!]`'T`.0&R7`E1.!)LM&#T;B[X%.]4[TN +M("0(`````P```-PA``#`D[O<>OQS5Z'FJYK2%]3]FG^+D&P^2)T5X^L+CYSK +M^CA+`YDDWQN>R3H9Q"&R`>^S4Z)_+Y?"<=O@F&TOPO693B2GU!0O+"X)@7)$ +M2&>9S[SR;003F(R4A'9B'.:$1:ZT&^:G"$&!)21_4.F,MLE^_(J0]SQN#S4[ +M'VEA`7+NX2F\Z5O+X':(0*2'RHO6_2?FN';[^:^742Q*W1O",!`!L````;`````(```!%``!H470``$`1``#` +MJ`$!P*@!`@'T`?0`5`8Y<"5$X$FRT8/1N+O@4[U3O2X@)"`````#````3"D` +M`#`7%V)-!`N94Z4"Q"&A8#HO?(2_&F@>+WF9Z3+#:DS*O'5PDQ".@K(`PRWC +M_4L2MT:(IP0`/`$``#P!```"````10`!.%%U``!`$0``P*@!`<"H`0(!]`'T +M`20'"7`E1.!)LM&#T;B[X%.]4[TN("0(````!````1PA``$`48P7UAUTFCPX +M#/D[B"K/LHF+Y6S:22>N8&2I&5FUKIN>P96)"/Z$HN"-6WX6(K1M90BX+)JQ59F7*S1;-IG[P>#P2XY<9CY58*5H7& +MTVB.MOKCXV'^JLHO:B +MD;7!$7M8<#+--3KD(HIG.Z]5&5SFCT]KCCZ"=OHVYQ98&;5064?/B<1N`[M# +MX:UX2Q*W1K#"!`#L````[`````(```!%``#H47<``$`1``#`J`$!P*@!`@'T +M`?0`U`:Y<"5$X$FRT8/1N+O@4[U3O2X@)"`````$````S"$``+!_=:L;6F:G(D>RO[ +M.@?L<#+E#4-S5^8V!'FG;P-:BB>2N08`'G-XD,?@_!:F/[PA,I@(C0W!S"K/ +M;CBKMQ.@LL]:S]OL?+"DR)/JO2$\/2<+($$SBA!92(H/5I0+`9YO.`12WE/5 +M'QENTX',SGY')>\2QGZ@A9$E$/`8Z-B&+U3EC`\%2Q*W1A#E!`#L````[``` +M``(```!%``#H47@``$`1``#`J`$!P*@!`@'T`?0`U`:Y<"5$X$FRT8/1N+O@ +M4[U3O2X@)"`````%````S"$``+"54*,23TLR]CPBW#*.8^\C/R9L0?FSM9I> +M:3=F)EX`&@5X1[#,]YEZ;Z;\?4&E99[&>D"F$"=YP>=.P=52'__-$4M!$^:- +M]C>$O.Z,0W_L@<&V]H0$HT&(Q::FT/=)W3%*_5_Q->#(.U0>DJBF1,$$K.Y> +M@.O%'3J:V@.CPYBZ!DZ@U"M],-HC.A87-K!>^>LY$SPUU\)# +M:[N+Q$.JN*3:%U+C0#!YL +MQC7-_`>W<^V3?:[GWFO25;RJ"ZB$.-VJ9$I\G%-[FNG/?7!'!80G +M[^G\Z*`$>0N`TNI#A!G']-D1R*LMW&9Z*8K>ZNU+$K=&*`\%`!P!```<`0`` +M`@```$4``1A1>@``0!$``,"H`0'`J`$"`?0!]`$$!^EP)43@2;+1@]&XN^!3 +MO5.]+B`D"`````<```#\(0``X+[T9DCP6CVW(MQ_N!P#/&.4T#/^^;0(_MUD +M`YA`.T("!$8K8F-G098X@,[[H>"+7^0^:-"]J9/VLOHH>_IB7G#E\NN94OG- +MPXAI11JXU=<]1K[$S_M]S@:,!`*!XB!IP&)VH8"K9QJJJBN>0/2JWVUH_`Q# +MH*?;(;%A7ARB.0>H0-$:&$9V.NO_9*.;ICY(XMGBDD)M"8M^^<2Z3[T\[]`* +M'5KR4R=QALAVR;7S#1^VLS7%/D"VV8S<5*_[ES$EK$LWORHF>Z?O;3OW?9F6 +M5[MN]H-$LV?3T/UT,A=+$K=&YA\%`.P```#L`````@```$4``.A1>P``0!$` +M`,"H`0'`J`$"`?0!]`#4!KEP)43@2;+1@]&XN^!3O5.]+B`D(`````8```#, +M(0``L/?+"'C<<*S&$K1HTUE<4AMJA_)7UH_W\[F.123)M)*=?\*F&<)Q>^S9 +M>%+\9#QD0T1-U;=_?N5.0PP],&_^MZ3;-LCCB4X&QPTB(`W6(E.E_0']56YX>=1KA)?F#VZ&M+`A/CO$,H15*B=9\"MPUZ>HZ??:WPS@9C +M(DX4R?K900^C@:Z^EKX4Z$Z0E8_56!(7GKHX`F"0X%@>?X\W83FM@O@I(AKB +MJ.,/D:M)\$^[$WV\O,33H$E&+6,[)6Y:<=@^`S[-CFG!%70S?,`P%=22Q*W1NN>!0!<`0``7`$` +M``(```!%``%848```$`1``#`J`$!P*@!`@'T`?0!1`XK'C-/['V@9@= +M'MKA]J&,[Z.[X2XA*Y(%4JZ<1TL`C],'FA$OM*(^$G*LH7C06JYTZG^53&Q8 +MO,/&Q;Y$HO'1[QV0^>O2<6/J3SZ4]9T2,MR1JGVUM&;3'./4%ZT]OU-.1O)Z +MARKW6UCQX_5`&,O/::%TABG#85$.*,IY+GXZYI2Y0XR`9+_6OK6ZN_*`@?);43EGBDYKH0$4K%<_PCTXWZ +M#].02=R&&8"J@*97:DB:PF5V_*<(R@Z,TW-7I3%E1L.?7<6*/\M-?NB1#Z>? +M7.KW;H3FK\J7.!GJV(HQRB4H]R%&"``!`$0``P*@!`<"H`0(!]`'T`&0&2<*OQUC2N7!V +MMV6UW%7SO^TN("4(`````````%PJ``!`Z,2)=*'":SJFL6.%7G#,#?XNQC+D +MQA^+/DQ>LZ&=%0VD^5Y:]9.ALRO!/KK"G/@<>>+CG,,.LRJ2,.NW2Q*W1G#3 +M!0!L````;`````(```!%``!H48,``$`1``#`J`$!P*@!`@'T`?0`5`8YPJ_' +M6-*Y<':W9;7<5?._[2X@)2``````````3````#"P8\L-!MA!\\$Z#0782K`" +M0&T328)_"*5KC\.]PQ_K#I34XPQ6ZGIGN+R1+$L2MT96XP4`;````&P````" +M````10``:%&$``!`$0``P*@!`<"H`0(!]`'T`%0&.<*OQUC2N7!VMV6UW%7S +MO^TN("4(`````0```$PJ```PQ& +MWHY"]GCWO-"BO-21$75%!^A+$K=&I_`%`&P```!L`````@```$4``&A1A0`` +M0!$``,"H`0'`J`$"`?0!]`!4!CG"K\=8TKEP=K=EM=Q5\[_M+B`E(`````$` +M``!,````,"0T/+OW=>)^H,M'/"\81>O$DH2.1,L8OCP4AK,8AEW +MA#:@XE;D``````````"$@(@@````````!>"+X`'@```!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``^E4&IB\ST:%^S\VH)*,I +M+/#L*YXYHD[='?GXKZW1IE!CZ/HRX_2D;7OGEP[UUX;]`P%M2>N,3C+R-!Z\ +MKY486X:-)5BQSP0($SS+*I-(S9IVC[92H;;3Q4:7L1[$/F(/"6 +M'*(^*_LF*7P;$"4-*XX#=>=U7Z"KZ#(I```D20369XF&@-I>H+NP;Y+G'>F+-R"6```` +M'```0`5[JZ]`K#1>AGX,+,F],1=U7Z"K +MZ#(I```D20369XF&@-I>H+NP;Y+G'>F+-R"6````'```0`5[JZ]`K#1>AGX,+,F],1+0<`4`$``%`!```"````10`!3%&)``!`$0``P*@!`<"H`0(! +M]`'T`3@''`U@G@"X9%`>P6]2/U69U!@^MLE_B7/HPL;BVJ;\^*0``)/Y` +MCTC<_WD2VR&`MG#;3R`$5QY;Q(2P9!%!)M#NU)4_2LFC!OAP%Y[/I79)GI\+0=%:7>FTW_=`Y +MIIDJX,)GKRYES)MGHP!A0AW]*[G'U"2PO0[NA$@#W-63S=QIJ8E<*CT7"7,2 +M,W9%*OOE?K00\`2BA5<#![E<_[*`=2(:J7WZ<,KZ@#[2RFF80(:;CS[&S2*R +MLP4I>!Z6;AS;%4L2MT:P>`<`O````+P````"````10``N%&+``!`$0``P*@! +M`<"H`0(!]`'T`*0&B3IY_Z0";,?<(1[RQUN=Y5EF#M>`_@:"]L\%$B+<:H*D.`W;"W](PU +M\HZ(?C,K#*FZZ3^]PN)PT\GHU=,VRG!C&?4!X)Y1)M;V*^KETBX1A;D[) +M@I@IY.=M@.&>X@^]S^";GNQT;ABV@\HUG3ZC4@JK8I/\@N>-*\BN +M^Y$K#S!`I9#U2/5BQ,I"S?&+,N[&2Y[7@&;3@P0L/R#Q_XM-=1,K)(`BX3SZ,L^65/V>QD2:APZLWMML?-#HV%KQ?!KL60>?U9D +MTA^?[5>1/0!.9G0*.)@&-H;4X/M/-?)+@[!PYWS8;D-+NG3$01K#@S@O\X"* +MT/;WKR_H5E%SQYIHBGC6IEM47\["DDPK-,>(NUT::]MD,,%O6XH7M(5%\"`N +M&\]Q%!:9\AXHR)IQH*X77R_TT4L2MT9.HP<`_````/P````"````10``^%&- +M``!`$0``P*@!`<"H`0(!]`'T`.0&R:7YHM=F3(Z%%B,MDBY%W202$[X@L.-FU'OY +MZYO&]IQES)%F*OIOQNFL;LVJ6<@C70!GV,Z-2YVA+LOZ]HM"ID$: +M`?^%HOW6=V"HX4+[,P$RKR1+$K=&"JX'`&P```!L`````@```$4``&A1C@`` +M0!$``,"H`0'`J`$"`?0!]`!4!CG)MZ$-J#B5N:`^RV8K%UZR+B`D(`````(` +M``!,*0``,.J.CS.*4^<*5R+5)5`:K4]<8U@"-_)/L-B"/7JG=CUUA#:@XE;F@/LMF*Q=>LBX@)"`````#````3"D``#"=VW=X +M-BWEF+<&,#XZB_7L=M"`TH9*6"WX.8/<)I>=T;-4)/YGE]]BD6Z_1DL2MT9H +MY0<`/`$``#P!```"````10`!.%&0``!`$0``P*@!`<"H`0(!]`'T`20'"$^]H3&AU%W8PJL4%)7: +M04N7Z8+M+*!+Z3JXM@'*WR@J+&S"!YXY[HJ)ZF='?VQ-`'MF+!SNE_+_C\XY +M_<_`V:]9?@P+#<4$N0>LK>[1;]57`L%0EF%O1WK7]XWV?,J^U"=X_@4==E0K +M/^`(XTJ[`KWW:I&Z +M(BA$-S/@=#"MBL/3@^X_W-W[#*-IT6LEWJP9'3T=K38A+J]Y-M2ZJW^Z`OSE +MB,+M--QW68%JNZ+W2Q*W1N+Q!P`<`0``'`$```(```!%``$849$``$`1``#` +MJ`$!P*@!`@'T`?0!!`?IR;>A#:@XE;F@/LMF*Q=>LBX@)`@````%````_"$` +M`."]HO)A413@G84GA5/-N%#F,6//32USW=\)=1D*SXN>5^0_)*@+X=!P +M;PQ^A("IC1/1ULWZG35IEM)\*08/3]JKU15:BG]^'S5!Z#;GC8#K9(15,(NF +M=M6[V@F4P&YJ+TM0/[*B3SR]R:R76C20F$6^`@S!Z&JHT7K(7@*JUG#YC]K# +MRNHU^X\GFG0:+9MPCJ3.3MN@WW?#SW-;BEV0@!MX_"DCB*KX.,;H,#36$GGG +M!2Q*W +M1L`!"`#L````[`````(```!%``#H49(``$`1``#`J`$!P*@!`@'T`?0`U`:Y +MR;>A#:@XE;F@/LMF*Q=>LBX@)"`````$````S"$``+!*SOWV=B7)-UC9'`C4 +MQBJKNMO\W:,#&(3I41-H8%X=E-4FS\=?SZLA/[G>-;'=+`LF9:1,;[2!O6G/ +M$I*MK*;%,\+,N1PX#/[*[S.U[:*;G!QTM&,QTTG0.,%S#J4YE;>8EJUZO<`! +MASV@_M2Q^)%D';:0FD2HJIW1WA5J]6G0#6NUB^20264$-KXS0PF8"A.Z@RBQ +MC`B:;`6R"[DIK]8&>/0K+TE%Z.LH;N*E2Q*W1K4E"`#L````[`````(```!% +M``#H494``$`1``#`J`$!P*@!`@'T`?0`U`:YR;>A#:@XE;F@/LMF*Q=>LBX@ +M)"`````%````S"$``+!@YT(.'?Y)?N[9LTI:7/]0<0\J:[$^>@'$_":7$&OK +MI5&/A#>UM3'9Y5TOF'>[_0%>!M9F,>YM_@;T_5IE$$5&]^QQX7FP.@07>(^9:CX71"O$/8$<#8(`O)%8 +MWYIGW`1L;1+$L/;W'04/.W\Y`>,=SV6PS,83>A+X-,E0=L- +M3.:^GJ*$2Q*W1MI""``\`0``/`$```(```!%``$X498``$`1``#`J`$!P*@! +M`@'T`?0!)`<)R;>A#:@XE;F@/LMF*Q=>LBX@)`@````&```!'"$``0!R>8SM +M)JY!E(&(G218#7FRF@X4IB?>0QX\UK%)Y$C+'4C%B=,G(R+^ZWWFF.EXZ$<6 +M:W52ZT+1%[HS1+5RUE$DVSXA^ENP8(E91MBY8>E?-NU>6O[2IF)A-LAZ[M(I +M%TZ4[B8I?=['1=)*SAM!ZK,)0!7,@(XR;%F@8K?V25)>E.I?<7=]7&"L?2;2 +M%X6B'YN%>7-*6SYVUAM!31#X%7RFMS:+U-Y_>T%3*)3_)Z"3GPV,IJJ&]>1( +M'VK&<+7A7P(3-+\_]UL)+$K=&;$X(`!P!```<`0```@```$4` +M`1A1EP``0!$``,"H`0'`J`$"`?0!]`$$!^G)MZ$-J#B5N:`^RV8K%UZR+B`D +M"`````<```#\(0``X'/&-.#S*B/RHMDD9*,0(%,2E*Q53B9E6>I-BY+9]SZD +M$Y)B`4@X(@5;CI#RX_Y^5RO9<_U#MT'J^M1=%[D<;?5L1FYG$"!M#"1)RT0& +M@'=RDT@9\O0^_W[W2!:9AXPRPDWU[C=@)TYQ60+?!K__%["?FS]$%8QI +M8^+>.2'([C&$1F4(B.\3B]I9"3YT73-S\I2:GP<(7.X-'$_'3%%8+'I:S>;> +M&:U39W\)OZ3V]E2CYS`>-!#!BSO6SYUH2*#/-A8NG?'0H5;8+TBHK/]LD_P[%Z>Q?HX-V +M]MGE\YBHY'/`Y$2ETXMJ&)]![EV3,E)$R1+RO`)&&MB/5VV7_$IT.'']Z6PC +M(%LKL^@260QRJD7E]^P=OX74#RI=&>&&\T<'CI\6;>[C0/AG`G,;S28`;PW2 +M=BRG6:F.EAV<6"*WK/P1!,E+$K=&XJD(`(P!``",`0```@```$4``8A1FP`` +M0!$``,"H`0'`J`$"`?0!]`%T!UG)MZ$-J#B5N:`^RV8K%UZR+B`D"`````@` +M``%L(0`!4"V5W,DB6TD1AOS^M^ZX;RDHH$LD/1)ILPAM%Y99`=27=9:5(HF?:(K$L0OYJ"@LD0SM.59*,ZS\)`9IO +M>MU4ZH;B5=%),=SM_,T;K3I:^C;! +M4.KEB8I>:)+`%QTM)YUZ#F`8N^=-82]`687J&N7,D");;,&$FYM!$(`NT]S@H%.(G1Z`[Z[0Y%B'DQZ3W3;Q- +M3Y^>.!$ND:OYKE5L!`@0NG`-,V&7B(-6>E"42)'5@950&V=(A]C2W3LY?]:& +MC&KL<7+*[TRF3$,Q"9$V1S5ZG`!E9/&$2Q*W1DK>"`!<`0``7`$```(```!% +M``%849P``$`1``#`J`$!P*@!`@'T`?0!1`A#:@XE;F@/LMF*Q=>LBX@ +M)"`````(```!/"$``2!3)<_5?Z,IMJ=#ZPFR\<2G:9.21Q60@Y#;J.VA^HUY +M7?ROKV>18/^9P?1[8_;T(J:6,&$6&:H8_5MOS>8FL4[[D@T%]Q +M==[YB[9,W=2-=Q3:C66'R)JOV*VB$Y22AA`>J$-8?>+S'_EVL2X4U2'@8YS9 +M[/LZ^X0ZTMKD%#:J)QE2]CBQ%XQZX(+$RAQ355,JR0Q'AH[GW'N,^$U)PY,> +MN^I?8[\.3'1UJ@!$#7/F(1,.BWJ#R9O;+2>W@6KNT865MB0(.).X/,L_S5U5 +M.^2?L90)H)>VI8L6N9G-=#AQ@X]!H47_Q43X^P3]$PG'`L(L!9VC@926I(,, +MA\,F)>OY9?+_DE%*,P@Z.\-SS]:TP.F"I.*3*4L2MT91!0D`?````'P````" +M````10``>%&=``!`$0``P*@!`<"H`0(!]`'T`&0&2;@?&VKXV+=E_HH8WX42 +MSW,N("4(`````````%PJ``!`H6X14$\\I%:^\J_5IU6=A6TRCY%%Q,`7PHIF +MI4`*\!Q-F>`0CP%@K`"0BU^8G2_,H0?9"3$2Q*W1O`0"0!L```` +M;`````(```!%``!H49X``$`1``#`J`$!P*@!`@'T`?0`5`8YN!\;:OC8MV7^ +MBAC?A1+/"+Y`'@```!T`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``V%7J_:,2Z>ZM';7ANHQ9R:XA%Q]3 +M:!%T=?XU-(1\5*Q4H)N7>HY,[JYJ*,;O2,[$A3-357@)S/H/]*A%$D; +MB6OGZA<5&A=IN)S#6;?F,ODHKV%DQU!7Y,">KS1GK!KK,7)JH\6"7.CF(X?M +M0J_(U3NVM#=>N1D-($U6OSX6S>M3NHJ>U>&P21_G4HN=!^ +M-79\GC%J=J$I```<``!`!`&T`6N5,KNU@LO<*-#XA5]'3G9U````'```0`7F +MMR3$J3JI0G.TX]75R60+'%R/!DL2MT8G.@H`7````%P````"````10``6%&D +M``!`$0``P*@!`<"H`0(!]`'T`$0&*<2B[`N64"PJ```````````I("(@```` +M`````#P````@``!`!@````&..MVKAKQ-2##=)0&SEZM';7ANHQ9R:XA%Q]3:!%T=?XU-(1\5*Q4H)N7>HY +M,[JYJ*,;O2,[$A3-357@)S/H/]*A%$D;B6OGZA<5&A=IN)S#6;?F,ODHKV%D +MQU!7Y,">KS1GK!KK,7)JH\6"7.CF(X?M0J_(U3NVM#=>N1D-($U6OSX6S>M3NHJ>U>&P21_G4HN=!^-79\GC%J=J$I```<``!`!`&T`6N5 +M,KNU@LO<*-#XA5]'3G9U````'```0`7FMR3$J3JI0G.TX]75R60+'%R/!DL2 +MMT;;;PH`4`$``%`!```"````10`!3%&G``!`$0``P*@!`<"H`0(!]`'T`3@' +M'<2B[`N64"PJ^2+_)"5(03XA("(@`````````3`B```P````+`$!``0#```, +M`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``%Z6*[+X +M)"?3I5TD<&(0BT0;G[O@_%()9Y)=0LZ-@]U&GWI"U)LG4IXA'@.K5-LD"UUU +M%Z"1^0O?=%CQ<03,OOHS/#PP1/S4''>*5J>\]O&0RE=?\ROK*J(B8ER/CY\] +MVMG:3AE@5KR8HBKY5%[Q!^5(#-1=#!Y@6L/@N2TM2)OK*0``),W^F7"M`+J) +M8#8S7F/A`>LT(YU5!5+FP2789K\F5GD7*0``'```0`3-&#^?2GIR0ZQ@3I"%S.(_S*.\ +M@<\TION-X_`WPH__&OPY`7?C,37Q!I<-RZV*%+B?237[$::BFW^C#9I1&22E +M>*_8HBB`^?M?D&%5&7]!-=UEV'OUZL0VL:@)+H25734&TI'B_30@C^D5$BKA +MYM.KHM_!\YCAV/`H@&(>X"'G(BD,@BJ`>6/UAJ;!`6,:+1^R2<+'QR.XKV&I +M#A(A8O`&M$5T?'*K]6C.Y\RD=2B)4]__0U[D$,I% +M\[J->9@9>V_A`5`GNJ_!9'E>V8>/Z^#*(CD,)<.CZC.*L?O(F^/-:1LX:F:& +M&::S<5:#:TC+!'.9R=3@@MEV/DHA4V.>PKIY`7GJ$Z +M,.9/KN=]7`_W.AZSJ+DK;.%7JDU$Z"+QG*;`+\/5;$L2MT89X`H`_````/P````"````10``^%&K``!`$0`` +MP*@!`<"H`0(!]`'T`.0&R<2B[`N64"PJ^2+_)"5(03XN("0(`````P```-PA +M``#`0#4WQE:`*$:#;Q#!L(67X?R[J:-+F^NOAE10P`6O*!8J+KX?!5I^%M1" +MBEU9ATWI#;6V#CA')C'^LLR#)R%SQ_8$+CK\S6.60B*;3>FOQ(/+F-QSD$GZ +M-$BD>AWZZE173Z;K$8)^P^/,DJ$D0,+TC7K:KM`(SM@[QH$09&700/L6:S^U +M1Q$SY(VH]1C>Q.E7$YCRI$.9LSXM;0]T9^8$@J>IF>VX^9%^97OY)V:?PXTA +M'GR4_6L!N@=E@Y)+$K=&LNH*`&P```!L`````@```$4``&A1K```0!$``,"H +M`0'`J`$"`?0!]`!4!CG$HNP+EE`L*ODB_R0E2$$^+B`D(`````(```!,*0`` +M,.'R0$-X?/B:@^(T)E.X^GI_9M2XXZ-UC#NDFLUD1*Z>/M._>GMI_%>!-TBD +M2Q*W1F4'"P!L````;`````(```!%``!H4:T``$`1``#`J`$!P*@!`@'T`?0` +M5`8YQ*+L"Y90+"KY(O\D)4A!/BX@)"`````#````3"D``#"YZ!2Y]\P!0J$C +M;Y$YI4:3ZN\\DM?8ZD[C\)^BSPC3)J+:8[J7)KP=F"&)-TL2MT;2(@L`/`$` +M`#P!```"````10`!.%&N``!`$0``P*@!`<"H`0(!]`'T`20'"<2B[`N64"PJ +M^2+_)"5(03XN("0(````!````1PA``$`3F4@`_X,WP9'^J1WP?9[;G5V47EGVBPR:LJ5(2($&J8SN`7U'+0) +M=CU.A4EK0!M>!_8ZX2EDS<$\8:5L3Z+"^<4;N1-$9IA936+D!!!_'3#Q.^75 +MRID;4L%%@$2-&"+G^C[EAZG7,2UC9'\8-77_!F$:(M&P^:US?%1\UO==#VL[ +MH#-IJVP6,)-L."L6V2#9Z/5VZ++,,X'OZ8^#G$CM]]\/O2@!8'QGOC\_H@.U8U*?R<9:+K_N.`1%&+ED+D!',M,CP_R$]3&QG$T["3M'LG%\T,:#94A-'O:CQW2#_(GDM276M`>'9<_ +MYZCQNU2`29NA',+8Y7BB'-TFOM[/91#1^--]"814KB2A6(Q?N37@_N]2"D@3 +M=VC5K'QT0QTW7]![+.\H<9.=^"@X;NAWS1P@^)3]^+W3\L2*2Q*W1AP_"P#L +M````[`````(```!%``#H4;```$`1``#`J`$!P*@!`@'T`?0`U`:YQ*+L"Y90 +M+"KY(O\D)4A!/BX@)"`````$````S"$``+!=3REOAH0&!L3%\[QKQT0?5%1C +M62.8W[]=9,+%=>-L1=6(V)<_^QHHP:IMVRL/ETF?UR$TZ>3$>##FAXB=7_K8.QWU> +M/3*88! +MZ`B$SVRC`!G52Q*W1DUA"P#L````[`````(```!%``#H4;$` +M`$`1``#`J`$!P*@!`@'T`?0`U`:YQ*+L"Y90+"KY(O\D)4A!/BX@)"`````% +M````S"$``+!6R:'22M.(LN`"UMG#8/@D=!J,;4T00-+.8EGBUS3$@7>6S6^^ +M>L[LYJ(VW=8KN+?3;?DIX9.\*&)..?,)"B#$&?%[-90?SJX&=]+A2+.Z).(1 +M%A'O8B)3M)B4(S,UAMVAD)WU"XJ9NG.`G-?IK<"L"#TD7\5 +M($Q(8:HYU&_PCTF5S=_,^QD?7=$-@7(SQM2VL#"_G/(FKU@N +M2Q*W1FE_"P`\`0``/`$```(```!%``$X4;(``$`1``#`J`$!P*@!`@'T`?0! +M)`<)Q*+L"Y90+"KY(O\D)4A!/BX@)`@````&```!'"$``0#&N7>1_1>LL\+C +M:$I@B4GH-APPT,AC`I0IJ>7J@E/T$<,?D0+A:&CT?'!,3&>)M*R/JIW*\7!& +MC5&,L4%O2(*&L?\W52(UL!V=4&<%4F,W@"D&!H>!-JZ$\#B;D;)9LF)%@I90 +MN*G6\>]D]ZS"*673M%O862]UGMTFWLYA1`%5WB-E\?Z^+)G1 +MJDE39NHIG1#%$G0I[_JOX']N8@EAP77N;GS#6&QM$^8@>HE%?M6*L'MA@;`F +MKMU5)"Z\#)Z!GA_/MR9Q_=%+$K=&HHL+`!P!```<`0```@```$4``1A1LP`` +M0!$``,"H`0'`J`$"`?0!]`$$!^G$HNP+EE`L*ODB_R0E2$$^+B`D"`````<` +M``#\(0``X$JDH`OK6AAMF1F8['=.H,ZV,;:7EE"!"6JR +MFP?TL=3(]NW+7TO$"6F4U7N.4$/"XVQ#T/BJ%T[AZF`(*[8$8[Y?U+VB;QNA +M;4>+LH+[E5YL&JK.R+'F%R;U*>O;'PL5R?75#WA]V13!P;-CATG]8M+U$(^U +MTR>``V*X#YT7ESD(&0H&JC7GF%:J1V!OK]$DOLVFM?))ILA]^K)YG*NFR#"" +MG%#F$4U7PIGO/5#/-1&OM67-()C@JD2S0ID#7G-!:VBTLJL@Y)$HNF0D^K\X +M>^-+$K=&O)H+`.P```#L`````@```$4``.A1M```0!$``,"H`0'`J`$"`?0! +M]`#4!KG$HNP+EE`L*ODB_R0E2$$^+B`D(`````8```#,(0``L(-,DXZ^M@S3UDEYVF +MS___*P59B:@,GP*Z-6;0BE=Q`*LW]UGJQK`_>[H:[Z[WVBE1\AX.*FYG*\#*52#!;7@'CC3UV?EG`'$$?P4YLNMB+.A"X<( +MG^@C_`@F`,B\I/#H)".9[=1!.0#'N,=8SKV(Y"E+$K=&';T+`.P```#L```` +M`@```$4``.A1M0``0!$``,"H`0'`J`$"`?0!]`#4!KG$HNP+EE`L*ODB_R0E +M2$$^+B`D(`````<```#,(0``L'_&H`03?2:584W2,(NQ.YDZC7V1_(50-UB("W].G$/1?\^YZ"V%XP>!KA,N-L +MU*Y!;R)B*QD40^)+$K=&_^(+`(P!``",`0```@```$4``8A1M@``0!$``,"H +M`0'`J`$"`?0!]`%T!UG$HNP+EE`L*ODB_R0E2$$^+B`D"`````@```%L(0`! +M4*1I\_<+H:4\3<^R2+ND\NNJ*NA"*.L\"GB<(-7O08(\V\]V_MGC3-L1AKA% +MU8,I!&GV>P;(X*O+0<[)O3SQ@?2G:V$5NJ]Y,-.52BE10VESA3@$'/`3,)&I +M^I28?6J1[4A07A+D?]7_8/,L)681"),"%$E'`M\NC;^V,WR,+=IBZGJTK5GV +M/'ER]!);:-`HXIH*W/X29I=X=U7@/[,D.7(HAB.I#2C6Z\X>(=>C@=Z;@T_Z +MU"`YN=;F?2X)EQ5VG%3F?):9#FG[L[F_-8U7 +M1)9E\%,H1']VT*7\DR(&7Y6WDQ[.MV78"V@-ZCL&D9Y!2J2_!RAV8;..<0&4 +MXA6$Z!ZJ`J=BTW;0`@*9M-/D2Q*W1A`8#`!<`0``7`$```(```!%``%84;<` +M`$`1``#`J`$!P*@!`@'T`?0!1`;\(BNEC+S+8M87)4>1YPLJW`:P1]W5(Q-/*.6FOW8)8D$0>Y +M%M#BU^G!I6Q->T3%VZ^S">(.1%>4[M]C8N*HA\.L"_UO:^B[!$(-DX12Y-F- +MU!3.3A_/KWU?.$',#LVCBA\DC:=WXDL2MT8!/PP`?````'P````"````10`` +M>%&X``!`$0``P*@!`<"H`0(!]`'T`&0&2>973-W"."`-UYI, +MYHAR%D20=SC9I?VVUS@5M$L2MT;E60P`;````&P````"````10``:%&Z``!` +M$0``P*@!`<"H`0(!]`'T`%0&.>973-:TH5GF,&4,3`GR93P95QM1J&?\D3_I57XQ;5)%#\S]A?5EP4 +M<23"T9M+$K=&(F<,`&P```!L`````@```$4``&A1NP``0!$``,"H`0'`J`$" +M`?0!]`!4!CGF5TS7*%`DJ(3OPJHJ[1K0B3GA3A7$1[J4*/@M0^18*Y29/12Q*W1EUA +M#0"8`0``F`$```(```!%``&44;T``$`1``#`J`$!P*@!`@'T`?0!@`=EX<)Q +M*,Y0B;X``````````"$@(@@````````!>"+\`'@```!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``Z_-Z8A0Z8_GG +M=>808WSPI9709FJ#%#%%?$D'[`M7':`7W%DFG8I<23%'Z)$BTY +M?!8T%=S3ZH&:A>HI```D9K8\?!#FBCQH51B!U!6*1]?$,CM-(*K7=OU/]P?A +MR*TI```<``!`!%?#>8-P'V/-G^M`=UEUT)@1[7W@````'```0`66)31VLMOK +MU5@$JN7#=\2.=&]IRDL2MT;X;PT`7````%P````"````10``6%&_``!`$0`` +MP*@!`<"H`0(!]`'T`$0&*>'"<2C.4(F^```````````I("(@`````````#P` +M```@``!`!@````&;&=90H@6[7Z)W+;/+?J2IP0H'$$L2MT:N?PT`N`$``+@! +M```"````10`!M%'```!`$0``P*@!`<"H`0(!]`'T`:`'A>'"<2C.4(F^```` +M```````I("((`````````9@A```@``!`!@````&;&=90H@6[7Z)W+;/+?J2I +MP0H'$"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``Z_-Z +M8A0Z8_GG=>808WSPI9709FJ#%#%%?$D'[`M7 +M':`7W%DFG8I<23%'Z)$BTY?!8T%=S3ZH&:A>HI```D9K8\?!#F +MBCQH51B!U!6*1]?$,CM-(*K7=OU/]P?AR*TI```<``!`!%?#>8-P'V/-G^M` +M=UEUT)@1[7W@````'```0`66)31VLMOKU5@$JN7#=\2.=&]IRDL2MT:WI`T` +M4`$``%`!```"````10`!3%'!``!`$0``P*@!`<"H`0(!]`'T`3@''>'"<2C. +M4(F^?<4JD[$?AYTA("(@`````````3`B```P````+`$!``0#```,`0``#(`. +M`(`#```(`@```@,```@#```"````"`0```(H``"(``(``(ANGZ&+QW]%4]-& +M,AP](CH_O/U67[#3J+XL.*^14*U&M:FD8-I]7@)>H\>\[FBRJF>*GHI4H8'M +M[@DE,AR!1(Y]*81I?.)$CF$6Y[Q&3/&9&\W,D,TF=*0``)+$_%VHQ?_Z.DSD"RWW\ +M'!HQ2N_]-%[-UE!^;#X$V0G<*0``'```0`0/MH#PLBLXW!=+B`C"`````$```#L(P``T$BU$8D2V/%PT"N,"PNU*?E^N).T2\$73;0Y +MKB99LXI.A>U7`Y"CJ92AFO*$RME1F;96POM(WU4!:/##8$`O)W01Z]BR'(9? +MKTO=@WKH!CN@=X/9OFC)K$C:NR7^&IN,Z%M[I_GF5'SJ'JO#T\E-/P=CO3XS +M^A])ZFU(ZSE;?"+*VWGG(.T#90>UUA+B>)\M6\.$%X2T-[\V1_=%_\]TI\QS +MB#K3HVL[BIZ/Q#+G4E[\*5^TGF#;^Z4TQFZK!]L#=[ZPT`O````+P````"````10``N%'#``!`$0``P*@!`<"H`0(!]`'T`*0& +MB>'"<2C.4(F^?<4JD[$?AYTN(",@`````0```)PD``"`OUH<_8M:*(W*?99E +M@$X_TE'80@C`W5=6'@_91:/*/\Q*:UBYL#.WUWQZ_> +M-!`PY'QW:'[M[5$[F)HX-%3.)ICA^(ZIC*E5@RZ:*+!K:4/L/.R%*[:Z%]:` +MEKZ/N:Y^,D^0FP#U^:'6;)$SEN)^YDL2MT;;"0X`'`$``!P!```"````10`! +M&%'$``!`$0``P*@!`<"H`0(!]`'T`00'Z>'"<2C.4(F^?<4JD[$?AYTN("0( +M`````@```/PA``#@]*3UK-ITAT3Y,[-MQU86X.83A/N +MI/IK$6P#%/1BTLF$HK$]#`'RA +M]7%UO:I_DCI*:N'T[0P0O1&M`EAM<6FBV,,!,=SG(H)'(%I&TC*_PLDQD/C%2Q2 +M-&!#^.0R!TL2MT8A%0X`_````/P````"````10``^%'%``!`$0``P*@!`<"H +M`0(!]`'T`.0&R>'"<2C.4(F^?<4JD[$?AYTN("0(`````P```-PA``#`51VA +MVUC"*)YD%(1G2S&1T&ED1#?C)#&3]^)E52!*6=GZ34HW0F.;_R!7]%860Z?> +M-4#XX3(#TS+=^@G;?Y2AUBH8:@Q/GWIU +M`+LZ]^AEG_ON2!HDF216_%OS55P5>8C_RA32)?(NTE^P9]_SK8)YYS_+_+1# +M0),$(N5+$K=&\!\.`&P```!L`````@```$4``&A1Q@``0!$``,"H`0'`J`$" +M`?0!]`!4!CGAPG$HSE")OGW%*I.Q'X>=+B`D(`````(```!,*0``,/A14TQ9 +M!!/W;>(&WS!W4EBS61T!8B(>]I9&"8+Q$=N>Q3>NC+GGQ?#N#)\B2Q*W1LTZ +M#@!L````;`````(```!%``!H4<<``$`1``#`J`$!P*@!`@'T`?0`5`8YX<)Q +M*,Y0B;Y]Q2J3L1^'G2X@)"`````#````3"D``##Y1LXCHJQ/NCA".C*'VGN\ +M^GA3`+XK(1[+=M-[HV6G$X+)I]2!#&+O)ITK5$L2MT9P5@X`/`$``#P!```" +M````10`!.%'(``!`$0``P*@!`<"H`0(!]`'T`20'">'"<2C.4(F^?<4JD[$? +MAYTN("0(````!````1PA``$`VJ*KJ<:^6I,\]FME.RHSM<*ZH:=`EBEYR46R +M@('3@[?;#T-08TWB5X1W]XE9/G512G%A.VXXS#Q6J8;0AH:GMOWOMSD@*.DU)6HI"L[N40RBZC(^[ +MC6Y/C(E,66'"RJ2B259N_>8#K`1W_"=3 +M2Q*W1FAB#@`<`0``'`$```(```!%``$84!I*)B8DAK +MSS8=1-YOX1(51T@,]P6*Y,IP$8<6R)8(Z4)P6)CB!,GR2W.PY^[48>"*4X/E +MB&K09TW#>Z&K6$Y>(U)<:2@#3.6UD\$#J/F`P\R-BP?%[1%=_%EY%6=)J(1$ +M8="[_75MB2>I9=:7XK6V&=R#U!2")VMVQ4,+*)`C1_Q^TD(U/P9K5#!$D[&!O\L2Q*W1H=R#@#L````[``` +M``(```!%``#H4%D@>@UKFJ"?7SWE5_]WQ%YJ +MC0H5\9SEZ/"N/G?ZC-S +M@^,#L*6^/O;9=2'82Q*W1G:5#@#L````[`````(```!%``#H4LJYXOR0B3.+&A@=K&7P1@W]7?*0Z:^(N2+PM`-%'%-`%)1J_R:!N? +MPX4S&JMWO_<"3@,V]]H1CD3AJPH)DCO-$[02Q*W1E.R +M#@`\`0``/`$```(```!%``$X4`$6ELBVVH=H#?IP=$SQO2G*J+$!FVF89[8AD+/G)=,.6NR-_-EM`\X*K?R]#Z[^_CN/; +M^JXS$DY.)J3$I1=LW+Q!0O=*?J/2PWPD4O`)%/$YV:3?OX#6Q4WR1)I+GY8[# +MB_=,1&2@_;,40[]+$K=&++X.`!P!```<`0```@```$4``1A1S0``0!$``,"H +M`0'`J`$"`?0!]`$$!^GAPG$HSE")OGW%*I.Q'X>=+B`D"`````<```#\(0`` +MX)"0TQ#Y1AXC3,TOZXC]VGEI$9E(J__Z-G+=T*4ZRBE@/GL6^EN\I_AYJEOXZMZ)@^QPD\ +MD00GH*3%<)Z)974=1OU="*>^K6E8B<=745`=56EL$$+5O.8R6^0QCDM+$K=& +MA=+B`D(`````8```#,(0``L-=H*$ES,NI1Y"U-0OQ4 +M\C+3<`TUW-/F1HXS1CYUOUG>P=`?I*+7OA]D"`A)-)%,K;D4SCA%HW]&&6S$ +MN'NZ?M`JZEYYS[YCZ([[XM9H6G?&'ZWQAO(H(A?L][]5VR(:L?O&U]H=0:MD +M&9CVY")9RTXHW.K(P]//./@M1&OL>,O^9.Q#FK*2)Q]A1*T5G]+MHH5JKSL[ +M$:?Y?F=+B`D +M(`````<```#,(0``L.4#I'**''BZAVUL5!9TVY!W);Z0ME]+$K=&,Q=+B`D"`````@```%L(0`!4`7_OHN] +M]Y^2GC(Z$BV`[;QPT:^`]ZSZ![8T\ +MT5E%3]^WP4E.)`J;((G=[P@^(3+DPF?NBG;1W(]%7+LCJ#SVEDT@[!HT4I:+ +M.:CW^)K:^*93=$G3Q`1EHM>5IWE'+K9D*W/;&')+`!P"%\$4E(.G),+>Z'ZK +MF!D^3U%=<\$'1%`OO&1!SCEY8SYQB/]H2EQ+[8ZQD$!?7CU.;YPL+JLT.D#G +MK2ST6LI2^QL[];S`_24?^A/!+],"=83"MI$E41T[E8A.SM>"1:=A9)`J?"H# +MZ9`H[;!(`(M04()-BG5Y_I*:^*&X`/`,RR+1J`\2:Z+3IVK!*[\/`(D2M&)F +MFT&'-_\QZ`0_1+3':>S>2]U,KO5X[R&+.Z1*)*8'N;\/D[:W#U$:"WF?D5X. +M8@JEL@S92NFE879I[.3:R1WX[[^(MIV_=U1HC1,G]F?;A-(5=HV"0T'2C4ZZ72 +MLS73'$H+_LCQJ.ZTV>0!]`,F7X8)2G-,BI;J%:]/7.D32Q:@I<"6I58"<1VS +MD*A"F&U<9(;=#G,Z!V?4GKD)190"="?I'ZH +M&B)J0+SSE;\$**EJT:MBULUU[`6\Z0<*EH=[[PR_6->KGE6FFO>"%3Z6F.X: +M--GU;(QT[HV&#W8?9-W.'?-0;6/9.=UB36O_7Y1$=FQ>OG#IT2A/KFM,O6(6 +M8O+!M'FM51FY)&;94I-,UDP2MT;_,0``?````'P````"````10``>%'2``!` +M$0``P*@!`<"H`0(!]`'T`&0&26GNEE[.JQ$4W.#>''CP28$N("4(```````` +M`%PJ``!`EMM`/YL?8?Y_/EIP34`4KEE@>"Q--J9_YBG`FWR%M/^?_E; +M.DK#OBPOW2C@+RRM'HF@M""?0:$'3!*W1H`]``!L````;`````(```!%``!H +M4=,``$`1``#`J`$!P*@!`@'T`?0`5`8Y:>Z67LZK$13/!)@2X@)2`` +M````````3````#`W["/:J-9V*+_(1Y'3@:*\&RZ9#L>)?9<7;6Q`.1V\K1ED +M_1;00<'Q,9XK"TP2MT8\3```;````&P````"````10``:%'4``!`$0``P*@! +M`<"H`0(!]`'T`%0&.6GNEE[.JQ$4W.#>''CP28$N("4(`````0```$PJ```P +MZ,2Q)@4/U#1-M5";EY[R;)?R3IB,IZF/%)=$%S+9JX1"*>I_=''!+^9?AT!, +M$K=&G%D``&P```!L`````@```$4``&A1U0``0!$``,"H`0'`J`$"`?0!]`!4 +M!CEI[I9>SJL1%-S@WAQX\$F!+B`E(`````$```!,````,)HD-M6R!O=@"+]`'@```!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``=.;S3ZDO8[?SP+YEAK$W<Q0+.5!O8AC[@:%H:\'-<]O- +M+]\)*TJI8=GA&`PCZ?)`]C1L$C63&&DFC,Z\P)]/]YOTT?*A69SAI_]:UH46 +MPU?DO2C"IY-[7```````````I("(@`````````#P````@``!` +M!@````&U#3Y[0=O6S@K0`JJ]([6V:7WY\TP2MT:/<@$`N`$``+@!```"```` +M10`!M%'8``!`$0``P*@!`<"H`0(!]`'T`:`'A4E>2C"IY-[7```````````I +M("((`````````9@A```@``!`!@````&U#3Y[0=O6S@K0`JJ]([6V:7WY\R(` +M`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``=.;S3ZDO8[?S +MP+YEAK$W<Q0+.5!O8AC[@:%H:\'-<]O-+]\)*TJI8=GA&`PCZ?)`]C1L$C63 +M&&DFC,Z\P)]/]YOTT?*A69SAI_]:UH46PU?DO2C"IY-[7K+DK +M_KE\1W,A("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```( +M`@```@,```@#```"````"`0```(H``"(``(``'B].KZ4K8BH*2S!*&&6:NNWFR@H)NT*(LOYVJ;5GS[6M +M\XOB2MS/X**=D1Z9JFKB..'LFEY9[I-3=,0I'=279+0`#S#HNFK1WK,F?^?X +M/"SR`&2WIJ?R84;SUH.6#FYMF)R?*0``)`@:Q2.6%'J89KG`$\SF"J%G_%HE +METM`J&\LP,F*B?-G*0``'```0`1=(B-E/TTDT%:[12M\P'SM0@&B=0```!P` +M`$`%WI].*H5/A#5*B968"3<6S"%0U1U,$K=&LL,!``P!```,`0```@```$4` +M`0A1V@``0!$``,"H`0'`J`$"`?0!]`#T!]E)7DHPJ>3>UZRY*_ZY?$=S+B`C +M"`````$```#L(P``T%MWNAU=$CXV_@`0P`_64?W93E!*VJI'86*%K.([A\&M +MUMIU6*/51X&?4S!IBOOL0EZM?^#'W)40`FI0@<"=3/@K68L0XQ^^4G^3J06X +M]9XU"<-'0 +MY9F=D"NSB=UE%6HXR#06!LK?Q'5)YI@/]0(,$3*C/UEG;44TIC$!XZ45R=WT +M*DU,$TKZ&TB#+M\SQ8E.RS(T=(!N+73F]R\[>GCP`*UZ4R1HX4P2MT8]W0$` +MO````+P````"````10``N%';``!`$0``P*@!`<"H`0(!]`'T`*0&B4E>2C"I +MY-[7K+DK_KE\1W,N(",@`````0```)PD``"`3<*::0*3#ZR,KF,WM155S1_A +M[)_9^**E<&?9FU6"VTET,@9B8'3D[FAA,J'Z#S4OH<"C?&5ORZ'H[*N7C9NM +M2'UBJ=W9P>EGY+]*\(VFL_A9//;C7S(_%9]L#G#0+7<'R#@RT3!Z4T"N6P\G +M?!;P*I'&1LTXAT-3'4__`DP2MT:A_`$`'`$``!P!```"````10`!&%'<``!` +M$0``P*@!`<"H`0(!]`'T`00'Z4E>2C"IY-[7K+DK_KE\1W,N("0(`````@`` +M`/PA``#@RT8%9]%4X3XGNSLCU-4\3O5PDT1^G_#Q4M`TW&73):=@1A/G=<0< +MLQ(6$76'Z3)(D`],(QQ.)!ST&%>+JNY=,6Z"?,;SET>\%U?[)FFB;C'W]BMT +ML/YCS4"?M("HGC.('*,YE9HG",&Z4#1))/1U==R",#U>2@ +MJ38=_\]PYWW(<@"*&A,*/-`FH!R;#Z>+M=+@7#]?5T,;7OBRATH_/V^6%1O" +M#C&WN"RI9TG39P("WM3:(,=3B[`O(E#IBL.<(O0)"2JZ(2N?$ISA95W@/'EU +M:DP2MT8)"`(`_````/P````"````10``^%'=``!`$0``P*@!`<"H`0(!]`'T +M`.0&R4E>2C"IY-[7K+DK_KE\1W,N("0(`````P```-PA``#`JAM$Q;;%WI^# +MW8V2LF$JI,'UDS8/TXT%^+C+K"C2IF6%4!6F?P4H<`K`3JYH2<2%[T9HCBESS1B9&8_V[A4 +M_#6=JA]G-!+N)\!,8@WMID^*)^WSR4TTZ;"Q?OU5!F!G1H3UCZKJ+0[?2;], +M$K=&QQ("`&P```!L`````@```$4``&A1W@``0!$``,"H`0'`J`$"`?0!]`!4 +M!CE)7DHPJ>3>UZRY*_ZY?$=S+B`D(`````(```!,*0``,`VE%S(%,L:HLDC; +ME=8X6C-1)R58)S#/'IT=0V:83+)K4SD*-^C3MP*X.5H`3!*W1GTN`@!L```` +M;`````(```!%``!H4=\``$`1``#`J`$!P*@!`@'T`?0`5`8Y25Y*,*GDWM>L +MN2O^N7Q'2C"IY-[7K+DK_KE\1W,N("0( +M````!````1PA``$`!@^VR8^^KM\'*=.`EY1#,^_%D`_.91+KWY+#?F&-7T-V +M]1`Y3+A2\<99=I>@,H)%+<,Q*'C*';\@^)@>#0TX0>4N9SG5.LIU`.MG +MQGVA&R#N<$-$ZY-0^*_E!A.973<)-&&7$)<\!@/SQ,M]^UAYZY2;KG\?&TK8 +M6BX]YS`,3_GV3U*U63#N,'$=XH)O*#[$6TN=)]'VT(HG-V'W`WG0FDD6NF[E +M]-X_W*]O-"G#9%FOO?!'K";G,CK(X0;#&BT?#$A@.#*$``$`1``#`J`$!P*@!`@'T`?0!!`?I25Y* +M,*GDWM>LN2O^N7Q'W)K(R1JG6?OY5<%71 +M!5MZ05W1A[VE'!1$%`RFW75TUL-S1E +MF7/HL-L3XN?2IPX!>Z#`4%SP5;YUP!<32[/UZ63L39=@<''LC(PNMEH5LQ@" +M2F*+8JZQ9&[XNL9_J;E4IHH/LQQ`FSL[NO:XP)SJK^>M8FQO)[W`IT(I];H& +MQ2EVO"H%`43O(J\Z]3.ER"*5%<>^+XN]LG9Z;J1KA3:-?0#URUG-]HLL%O[4 +M&-@0`I(S5(``$`1``#`J`$!P*@!`@'T`?0`U`:Y25Y*,*GDWM>LN2O^N7Q'OH^QSN`V%J,'!VW#,<.I&7ZU)RZK=\(WF=1)52SXGM"1PGVK +MO=Z]EM#*-<;M^F)O'&0_X&EE1U?Z&/*NZV,,``$`1``#`J`$!P*@! +M`@'T`?0`U`:Y25Y*,*GDWM>LN2O^N7Q'S_\E/37(\)_>[IM6R`L0X33,$?*R!#:7"F#Y)M>[ZPU3!*W1FNF`@`\`0`` +M/`$```(```!%``$X4>0``$`1``#`J`$!P*@!`@'T`?0!)`<)25Y*,*GDWM>L +MN2O^N7Q',O^WQB@ICF'G#&2:F7YVF'!;M>YU +MU0?-N;)JO3F)MIEO=P(&$=U56JVYS;*^<,3>UZRY*_ZY?$=S+B`D"`````<```#\(0``X-^1L`"R +MNU_X]>["SIED!-Q0C4QSZ=I) +MF54EFK:_E3Z5E`0YIA';0+*&^Q7,(A=NVQ]GN,P.D&/FC?_*GF<8;M4G;P&W +M*6FI96[FVVN]"F5C9.$UWG1QA;N%-PT;9)4VX?'S+ +M\#.I$9BDJ0W4:5FL-09]D&H"GNKP:,@XY>57\\C:0PRD$YWCU^/%7C>!_,Q) +M:#$Q7TT(6)@6888V)"$,JE7?UF(0@&G'PD:KI@_;#N.,[E5,$K=&Y\$"`.P` +M``#L`````@```$4``.A1Y@``0!$``,"H`0'`J`$"`?0!]`#4!KE)7DHPJ>3> +MUZRY*_ZY?$=S+B`D(`````8```#,(0``L+VK("\]">UY+PV36HD7$R9;@P)# +M'T$B5D%G,=S&\T0C1-J062:LM<:^=+/NF(6?0,BKU216=*?M;*1]JEO8%=9: +MA;U429#.T,HWG'8RUJ?/1(T78<[V^W4E(A\PQ>$ +MH<^3>UZRY*_ZY?$=S+B`D(`````<` +M``#,(0``L#*LQ%*"#$@D$1GEFU]7GKJ:S!,SNSRSRH0J1RL)-7?\QB5XUW*2 +MU^WC(U8CE/]H^X>J+>L?*&FZF'8$KU@(VCC9YKAJ^,"X(_%@_U.6L?7YO2X9 +M^JWJP')]T8'X9<8F$^/9#I[>3LYA"&N5MSDS`O%.!'\,Z?C@]K63I6=1*XNZ +MDS<6K[V-?!04_US-4/'+RH&AWXL2"J^8BP.O"00F:KW^U_D(O\!, +M$K=&VPH#`(P!``",`0```@```$4``8A1Z```0!$``,"H`0'`J`$"`?0!]`%T +M!UE)7DHPJ>3>UZRY*_ZY?$=S+B`D"`````@```%L(0`!4"N,8$.ED/?TMX.8 +MS!S"0NO%$N4J"T,$';;`.'/.IVSF'DJ3JA\2[C48M)"H=W?#W".SP=[:QI&N/1E.0P=LL78#^]`YG)W$A.M77$9%R'.T!T"0K,*#5ZGA3<[I\1ZP>)1A6LB'B.0X_DOS*`YO6T0-_U;S+< +MW;]2.2-ES]=CVV]P"=?N215,0VU<`-#R;L*;]Q*@,/!YL$NY)NI#C%.$#D``$`1``#`J`$!P*@! +M`@'T`?0!1`LN2O^N7Q'-MP\`$@I!JNL(9NMLQ4X-P88H)87 +MKGV_WYT9'N.JTX_$6!L*ZZP'(`(]S[VMM4D +MC]J5?Q+3)9[XP4P2MT;L9P,`?````'P````"````10``>%'J``!`$0``P*@! +M`<"H`0(!]`'T`&0&27$)7&*_[T$0H^JBM.]@/9LN("4(`````````%PJ``!` +M:G?X*#5-(9?J2DT_3;N>6JL55708+!AP*CU8(;FG*>$JZ@AMWG'E%\BJG@W, +M:1$L#UWC?[I-Z/:Q)1X^3!*W1O-S`P!L````;`````(```!%``!H4>L``$`1 +M``#`J`$!P*@!`@'T`?0`5`8Y<0E<8K_O01"CZJ*T[V`]FRX@)2`````````` +M3````##S3D17#F40.,@B?IB3*6#V!Z<27.C+;K/[N"+`&<\O:K[9'-CR\0ZR +M"1SF#$P2MT:8@P,`;````&P````"````10``:%'L``!`$0``P*@!`<"H`0(! +M]`'T`%0&.7$)7&*_[T$0H^JBM.]@/9LN("4(`````0```$PJ```P:7[>Y7`) +M3^VFA>&U:?[$1A[ZL=^+PL&D2=83^GV@5\HLHT.=&G'Z$S75^#Y,$K=&G)`# +M`&P```!L`````@```$4``&A1[0``0!$``,"H`0'`J`$"`?0!]`!4!CEQ"5QB +MO^]!$*/JHK3O8#V;+B`E(`````$```!,````,"?437%'^;[B.+[A/N(T_Q;W +M^IXYFV>ULNQ63!*W1A*-!`"8`0``F`$```(` +M``!%``&44>X``$`1``#`J`$!P*@!`@'T`?0!@`=E(0^#5WH_AJ\````````` +M`"$@(@@````````!>"+^`'@```!T`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``%PUIB`.3C(7(UZA10L?F:C.RM8%R.H0@S#")+[!)?ZUYL1%CJ)K! +MZV"+6U\(V*7NZ#`F?4X/RL1I[G7"/`NB_YK;^!\I29PM+H+E1]YS1'3T6.HQ +MSA4HRJ4`1I)?X=3L4%0QZ8H2;"T5B:\,4L3N*]Y6PGNI4N/[K]E\]Q.S'=HI +M```D=;LB]ZF846!BTYKM/J#D/5F"Y+L?[D7'HJ6:B8XN>Z,OWDRQ>)7WPW<4`B&96YD\7)9<*S:4=(^:LWSFYAQYIZ2' +M-K:6!#=,O_8OR",O8>S`;/(^H@8]A3)(Z[[-O3DCV..90LMEXU5M;*G'=\%Y +M5<3\!=*2D2LS+?I?O>FY*0``)$6DV0Z;G!ELW=@Y966`(@```!P``$`%!@C^&K]Q(M.XB[PZ,+B`C"`````$` +M``#L(P``T!Z]'&&442T)C\EHP)+':YK66^K!>)`_$K7ZW$Q)37MI*&.?[-!0_>GEWQ[?,5=A):;:*O9X"/3D>0W +M8*"M-5)R<[']^:4_EC%!B=>>RK#OK\9\\0Q:.J4O74"`+]PWRJDU#]D!MO +M;&0UAS^=+4Z8N4P2MT:_-@4`'`$``!P!```"````10`!&%'T``!`$0``P*@! +M`<"H`0(!]`'T`00'Z2$/@U=Z/X:OW$BT[B+O#HPN("0(`````@```/PA``#@ +MNB4ED-/*X*1)0,2:8U\6[XF@6LIRZ0I\FZT-"\Z?0%34"QZ6G*_35& +MQFKA0/YA0N^`5=HI^='^(U(?8^`T9G((PPG'>#I1(4W@K[BHGJ`MDD*FC]E`?P8P +M>$7Z?3AN`"C3+YU1G-G.75>9FX7-M\(*4DS#0I]8$Y. +M.PG(O"L[W`&'6C^;]R@5VV!G9@)&CF+FI6^)Z,@%WTR[$C!N6 +MJV8>B@GW*X"Z?OI?#Z`LJ/V'8U&A:#3RWO#?2#B;I6[BW1B.!AA4+IX>P_"G +MY>5.1WKP5C7'P$KMD0?VN:&7,C^&K]Q(M.XB[PZ,+B`D(`````(```!,*0``,`OL8QLB8G4QY)!U-_QM@Y\3!*W1I5J!0!L````;`````(` +M``!%``!H4?<``$`1``#`J`$!P*@!`@'T`?0`5`8Y(0^#5WH_AJ_<2+3N(N\. +MC"X@)"`````#````3"D``#"Z:K0F4O'B2FZR0D/6B!1ZK+-KRY3$7.\PV?,8 +M(+L?;&$V-;[DCVE1B9H0BTP2MT:-A@4`/`$``#P!```"````10`!.%'X``!` +M$0``P*@!`<"H`0(!]`'T`20'"2$/@U=Z/X:OW$BT[B+O#HPN("0(````!``` +M`1PA``$`54Z:1O!);;.S4"B`V;,);%XF$[BZK/?+6V#V!"/SG"^K(K-QH%D$ +M`5_C=[)>>QG[A](?"6P@F6AM<04OO8 +M*C0S$I`[R#22V3>&9I]6HIRU-KZ?9"QI,=0(!,Y)^B-]&>;FQ$ME4B[.%^<, +M$FL/35"P$$="CYI%!:'JS^CO/0U_9'^8E&,:NM\O1)?_#Q/X^>61SQ-O15:/ +MEMH_H5,/44\&V*_B8G_4P47\K9_L. +MW#?+]79!BU#^KB]E#]4>SW*8L6&N\H/#2$X3GL4P-O`:%A>Y]=;:&9(N&\YD +M1\!CB8B$8C2P>'PZ#KA?8=)Q&]A_HN%W7PJBQITJK:+8/PDT>2O`G$0ZS1WH +M1'5&K>Y&Z;;5%U:Q])AMRO+V'YU52RW,;F,?@#>6^F +MI\#O$6B_R4M-@BD=DS9Y]\',3!*W1FVB!0#L````[`````(```!%``#H4?H` +M`$`1``#`J`$!P*@!`@'T`?0`U`:Y(0^#5WH_AJ_<2+3N(N\.C"X@)"`````$ +M````S"$``+`[4(:,"'3\S0YG>OIU'AUYK43INFQ)6\]+/6IY@'O:W$G>HG6!ZPNF,?L'C$D?NA +M3!*W1K'%!0#L````[`````(```!%``#H4?L``$`1``#`J`$!P*@!`@'T`?0` +MU`:Y(0^#5WH_AJ_<2+3N(N\.C"X@)"`````%````S"$``+"!F*[:%,8XY6,U +MJK("4@!Y9M\#K*)7D9Y]%-;(&@M#E(6#N`EBF75;)^4[WJA=O3@:$88:R*S\ +MXA/U_,^E`.2G5)=>]VKR"CFCD5:.P16 +M`GB,E#DPQRENVBP9M]T8K2'O!92),%3H]5Y>J76F)PBH6OF0_Z&>^%/D&+'> +M5?>C]=R]CN-W7N/^-V$=YVLH?,,@'N`/^LVB'ZHM$\YW!?&YUB&7GT7>B5E, +M$K=&2/0%`!P!```<`0```@```$4``1A1_0``0!$``,"H`0'`J`$"`?0!]`$$ +M!^DA#X-7>C^&K]Q(M.XB[PZ,+B`D"`````<```#\(0``X'_-58"V?USAM4XK_66T4GZN0NL<[`OE\G +MC`$Q5#W\M%@6N.[JQ&OR0UVC +M21P7-=H191@L'`JZ?U2O?*,>T,2\3,V&K#3/C`%,$K=&(_\%`.P```#L```` +M`@```$4``.A1_@``0!$``,"H`0'`J`$"`?0!]`#4!KDA#X-7>C^&K]Q(M.XB +M[PZ,+B`D(`````8```#,(0``L/3V6#$EI>;6T6T][Y"O*(COT2X3U7X6QK`! +M!79$3'9O""*9KP!#LG.$*4Y-GCL>"_^&G\3$""K`:,ZW_OO^+(Z?_)*'9T1O +M&!CFF0K_4@0X4S0,V_MD!-.-!INIF:/>`*AET@7*2`F;SBG\U +M$KJ7^DM%W08>FBQ,$K=&/2,&`.P```#L`````@```$4``.A1_P``0!$``,"H +M`0'`J`$"`?0!]`#4!KDA#X-7>C^&K]Q(M.XB[PZ,+B`D(`````<```#,(0`` +ML/I/>VAGB(C9POX2:]\"X<]@`5JMLG4)K:0'+90H>.>);)FK6U,N->!:&HG' +M&G!W\X*TZ3`?KM2S`.S;E/B5AJU??Z)7QLV+ONW!GP')S@W[#%B^,B944?'S +M,ZM[2-Q="59GOOG5)G$#"Q[9.26I>2]AN@].\3,&NKJ&IYWFE[6>8!_M^ +M?[5"&TK@)=^S/VNEBW;L^EER&SD@'FYIN$H@-K0P]"\PP;'`3*Q,$K=&W4D& +M`(P!``",`0```@```$4``8A2````0!$``,"H`0'`J`$"`?0!]`%T!UDA#X-7 +M>C^&K]Q(M.XB[PZ,+B`D"`````@```%L(0`!4"^(C\F=F==H;)EHHVA10,E? +M$JU`(J\34@\P7$FC=3JD;ZYI1Y>U03`T7!BXB^J$Q%PI\?W:&+`)Q +MJK"`%*FA[^FH?L7((%?GTHPSB4X>7CE#RZJEG +MU*!(IIYFJ#$CY6T__C_WTK9;`9QB`-%M:U#*^;'KW_O4@H-,=[;1A; +ML*SJ^F$+:B&F1$A!#(V*>.>EEP&*GYF_4W$U2U*:1N#*[?##@CGWB=&<,^=G]P568U8N!D(@UO88,F +M?ID72W`'=]`Y:5K^^EJ0IA"4;W)O/SK4*+J_/[UTYG<2!`954S38Y7 +M3!*W1G5^!@!<`0``7`$```(```!%``%84@$``$`1``#`J`$!P*@!`@'T`?0! +M1`R?HA\%0L9H;T(HQM0DA(A,=7]J_ +M>7N\+79QB;+4FDJY_`&-6_V(I8!71OG`873&`R3['A)UXZF&0`F'V05!9.A+ +M8Q[J04P2MT;KI08`?````'P````"````10``>%("``!`$0``P*@!`<"H`0(! +M]`'T`&0&20&4T27/1=QBT5"@4([=0J^],DP#69FS3HU@ +MJW_B(\4TN1/@3!*W1GJQ!@!L````;`````(```!%``!H4@,``$`1``#`J`$! +MP*@!`@'T`?0`5`8Y`931)<]%W&+14*!0CMUR42X@)2``````````3````#"\ +M7D5\(XZ2&6,.*`)+@[-'59B'.W^35,M31L9%K&==F+(EV'Z<55=#KJH?"DP2 +MMT97P`8`;````&P````"````10``:%($``!`$0``P*@!`<"H`0(!]`'T`%0& +M.0&4T27/1=QBT5"@4([=H,J/^G#BRFE;L +MRTXPL>-@E?R@2@J+Y`LEQCB20D[@3!*W1CC+!P"8`0``F`$```(```!%``&4 +M4@8``$`1``#`J`$!P*@!`@'T`?0!@`=E[AGL/8J0(7X``````````"$@(@@` +M```````!>"+_`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M"+6XF3/&R2(T7C>Z;`L(OE\K+BE8D5;EBB'.\?-04`:.W*3:I!WY;R3R?,J7 +MG0*J3T0,;P57WSYUCZI_`[9D8"2\B6IKFUR +M:(7HMXUAS0B=DIQJJN_C1V\*%W+D_)PCK.O@@=)9MV+CE%AOCS4I```DLLWP +M+D-7$2B\#O+LB%YOH`DY&SW"(`>J?L[;=GY066LI```<``!`!!QSGS;NDVO3 +MZ-UP%14K_U)9]=TG````'```0`5FJ&G^RB9:1S^1J,AGM^EB.7817TP2MT;I +MV@<`7````%P````"````10``6%('``!`$0``P*@!`<"H`0(!]`'T`$0&*>X9 +M[#V*D"%^```````````I("(@`````````#P````@``!`!@````'"%2BX8-83 +MI?M?"VD0BKE_"W3W!4P2MT;PZ@<`N`$``+@!```"````10`!M%((``!`$0`` +MP*@!`<"H`0(!]`'T`:`'A>X9[#V*D"%^```````````I("((`````````9@A +M```@``!`!@````'"%2BX8-83I?M?"VD0BKE_"W3W!2(``'@```!T`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``"+6XF3/&R2(T7C>Z;`L(OE\K+BE8 +MD5;EBB'.\?-04`:.W*3:I!WY;R3R?,J7G0*J3T0,;P57WSYUCZI_`[9D8"2\B6IKFUR:(7HMXUAS0B=DIQJJN_C1V\*%W+D +M_)PCK.O@@=)9MV+CE%AOCS4I```DLLWP+D-7$2B\#O+LB%YOH`DY&SW"(`>J +M?L[;=GY066LI```<``!`!!QSGS;NDVO3Z-UP%14K_U)9]=TG````'```0`5F +MJ&G^RB9:1S^1J,AGM^EB.7817TP2MT;+#P@`4`$``%`!```"````10`!3%(+ +M``!`$0``P*@!`<"H`0(!]`'T`3@''>X9[#V*D"%^#G^G=Z"D4=4A("(@```` +M`````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```" +M````"`0```(H``"(``(``$R@6NY,M@>(P6=$G,=O*ZA]/\#HUV?&H$C"\\82 +M?-:4CKS/U/$F^=3DEPH+<#-0PTX3%:M,@2GB;%/7';4T6AK/Z;Q1ZR]FS8!2 +M(H@T]/@TKF,-:-&<]/R(-,\!$W%Y)0MM"[1Z-^Q-,838]UF0UT];\=R$_/?) +MR7!?'1XD8GO9*0``)!87/=SQXPK6^)DAHRQR5G_'W!A0CE)9SZ#;4H/W4\BQ +M*0``'```0`24J^>JBE?1224&=*AO=Y;Q+:<)+@```!P``$`%/"L_'=SAJY$5 +M9(*/`,9U6'0=P>),$K=&Z3P(``P!```,`0```@```$4``0A2#```0!$``,"H +M`0'`J`$"`?0!]`#T!]GN&>P]BI`A?@Y_IW>@I%'5+B`C"`````$```#L(P`` +MT(MK1=0FNEMI790)@,X-_1D5<[=)MOA>>=)G<28DI@^35AQFJU0^DNO5DN*/ +MWW[\X2^43=[KV/2I&H)UV@"PG&WH8-_UP^*P7&)`7QHV.(QA"&YE&K4QV0\R +MT!!.<03S<\YK[8%*S"T!.P?_0V+/*N:JWL>*#9V$[HE!(IN>FZ/%1J6J;_2O +MWZ'W%(@'Y7"+"AZ\?:I&47=VX+XE:R6,:>.AI#<%RI/$"=Y9=!R2,G<=^`HR +MUHV\HUP,95D=Q--1:E-$\/3%5K<>[9`@P4P2MT:950@`O````+P````"```` +M10``N%(-``!`$0``P*@!`<"H`0(!]`'T`*0&B>X9[#V*D"%^#G^G=Z"D4=4N +M(",@`````0```)PD``"`V\?KPQ(*/@2'>>V?U7QC4G#U2& +MVW)#A@0#8CT=_.%)V8Q=Q2X)XY0EX-@29QM"$F`TAQ,6$)35`5>I_R=8HY3^ +ML+FSHOJU1K\)6"T:A+;CCYMG&;@1>Q`*Q+JDBDL#$=^-?V(VDT-Q$.8DO$L- +MPL&7X4P2MT;^=0@`'`$``!P!```"````10`!&%(.``!`$0``P*@!`<"H`0(! +M]`'T`00'Z>X9[#V*D"%^#G^G=Z"D4=4N("0(`````@```/PA``#@G*S&90$. +MR*96T^:\6M]_L1ZIOUV,7&!H0TUR_0V[8;'H-G;P?7EC@-F#:2[$\G*J9"(S^#PH)6@'\S#Z*1@%]'CX/3Y!QLEW +MWQVA!)TCOR3=&QE5,L7`NAC7_JPAOL&FP5',(X.^UU[*'E +M@4=;":IAGBJ71S3Z3L%%?C;)N`%RC]1)/RQ#?R;S]8!Q3TP2MT86@@@`_``` +M`/P````"````10``^%(0``!`$0``P*@!`<"H`0(!]`'T`.0&R>X9[#V*D"%^ +M#G^G=Z"D4=4N("0(`````P```-PA``#`6;4YTO')ESVPK*`DK]JJ]/M?%8V] +MHB+DE#E=0?*IWK^N33O)ALQWU9&,.WG_+MB-DLT4WH%*PMJA[D0`DDT-*Q8=V)I6ARJMKB\VUW:>/C +M&+#Q6_()\Z)69UCRYEXWE&@+KD61IQ-=)?8HU@&HYW\UU;KY#$N& +M]&`V"E0>+-P]BI`A?@Y_ +MIW>@I%'5+B`D(`````(```!,*0``,.3DWHZ+A7*QBO?1%MD(!5O-0`542`*L +MASX2YT=1I1V3,I%M/`$O7#\03CK<3!*W1L>I"`!L````;`````(```!%``!H +M4A(``$`1``#`J`$!P*@!`@'T`?0`5`8Y[AGL/8J0(7X.?Z=WH*11U2X@)"`` +M```#````3"D``##U=XX9[#V*D"%^#G^G=Z"D4=4N("0(````!````1PA``$` +M];&G(O%@^]0G>S!I7U3_/2.*-$^A+M%IM:$".OXPU?Y>>`IV=QQ1B$AVT58X +MR#T2SQ6WH;G-C&BA/SKAE&?C0@7O^6NGQFJ-C),)SM&W_$%I(5.%.NBX2[0T +M.8@,RI>#A[U8Q;*OM9`9S-VL1AI%NZ>N*ZN-+O,(&E#C(4@%[;BV$WKC4I^S#WSN)->0!06(QS&MG!4/"Y3!*W1AS1"``<`0``'`$```(` +M``!%``$84A0``$`1``#`J`$!P*@!`@'T`?0!!`?I[AGL/8J0(7X.?Z=WH*11 +MU2X@)`@````%````_"$``.`>HDK.D&!YG@"2@CL;%QRE:>"W^6[JW+AC8J![ +M*8'HF8+=:A\I2<6GA/):S/>%35V1-&-,$U1OV>;FIX^!D)VX`NAOZ`\NL?62G@%/!SGR&*,V*2(Z__0H61 +M0FVQR6;:-NIPND@83!*W1BG@"`#L````[`````(```!%``#H4A4``$`1``#` +MJ`$!P*@!`@'T`?0`U`:Y[AGL/8J0(7X.?Z=WH*11U2X@)"`````$````S"$` +M`+#KYTY58/4^%KII;MGS+U7G=Z'1W>DDQ>DE%Z<0,L@)J.VN-C +M^F?VGRNT]Y-'BIX;3YI20IA/9E5E/^4E!:"7I3TYB^8MB_:Y[#L!2BWCT?_% +MXT\K<'I&B7+J]LV1=Z@\##:ZY![O?)I?^I":A`[.%_FX`#`;$6DV3!*W1BH# +M"0#L````[`````(```!%``#H4A8``$`1``#`J`$!P*@!`@'T`?0`U`:Y[AGL +M/8J0(7X.?Z=WH*11U2X@)"`````%````S"$``+#V1^/5^QN/LVU^EQ404)R< +M@$$V*5]BY7'`[CLT*0B`S@,K'[-VN2MR+G;&!"3YP[(YE"LD3\W_B%EJ\7R& +MPG-.6K_%4TEA%G3`@C8==J.Z^+LDI_1\>%CR^7G'*MB^7>L[ +M/N>%!Z@V&0-7P.LAJS:8W*$9.B5P3!*W1H,A"0`\`0``/`$```(```!%``$X +M4A<``$`1``#`J`$!P*@!`@'T`?0!)`<)[AGL/8J0(7X.?Z=WH*11U2X@)`@` +M```&```!'"$``0`=LTM>K*\.IUU$R3M8&QKO9$5LRU39,MJK8756`*6?G>G7 +MNQC9$XW$J@S6&M);)*4<2:1:#K(]C,,_,XD]?VKPG+YLAM!BN]"&Y:7$I1J\ +M$R1S4`70D\_A^LW/NUIECM1,!K=*'OM`'K$LL@A.2BL\O!?YP)1)-Q9R_'># +MRX_*O358&3TS<X]'YSJ0:PX`Y"=Z'OH2E1N`;:E +MF]+!%(*V;70^2YTYW]TO^31T_.Y,W`MZQH`$]=G-0!OU*AG)0+IMW#U73,H? +M0UH"NJ*WT!Z"+,%R,$$`;VF=W3DY7@'27WT(\=+TS;.6DU^8,UE,$K=&H"T) +M`!P!```<`0```@```$4``1A2&```0!$``,"H`0'`J`$"`?0!]`$$!^GN&>P] +MBI`A?@Y_IW>@I%'5+B`D"`````<```#\(0``X$@(^K1['HS"?,IWJ@J7@43A +MLI6T>#,B>%O93\U`6W,G;PUG2Z_!%E"%KS>;Y3_LF7M%#,)O+.0P,ZLI5EX% +MN0?;DGO%7KT4T!<&W[YZSGD'U8]M>,]Q^X'=1L.5*[X8J^39)RJ:H!@)190A +MY9R[H]5TM\@[.&7U"$IRKL+04&;9]1F^YVM097`[@C#"IO;Z0L6SX/A/'9AZ +M75FB_4L/5NF&].IO1)+(*P=#V*EDS3*IP]BI`A?@Y_IW>@I%'5+B`D +M(`````8```#,(0``L!CU>-GT*7!E&`MBAJ]I=Z]&R1;LS9W][)S`ZZJ`R%UB +M-A.,^#ZA`H#["ER$LTR@V#Y6=MG?HF@O_#KHG9,T?F>0Y8`5=4ZI&?UZ%(.! +MQM9TD;_DL/:[3TBZ457?>^.?1T,A0`=V\O5T_2U2D,T,_*])^V\=;8A]B)!" +MN5"@H*3_!!ZL-^]#@D>7E&LC-DB5`!T4CG>ON:=M]2[YU@)B^*@\#?"!)/V^ +M68%L27Q,$K=&5F`)`.P```#L`````@```$4``.A2&@``0!$``,"H`0'`J`$" +M`?0!]`#4!KGN&>P]BI`A?@Y_IW>@I%'5+B`D(`````<```#,(0``L)@&3^CU +M"63O&`-C)SKT354'*6SV\9@.QXZ>VL#IB5P*'C&[P53JV>X\!\?I5DLUW+*'I(#1E(B'@KN.O$JT1JC8P5OEZFLLFE#Z*2X="]TNE[9D?` +M<"AW$^.5A7__$=C.;B[@T,_TOINE$[&_5]-B1(1VN>@ +MN3YTLBO9Y_Z!+EI(18X\";>#,MZ3=`70I%*56'X&SLI,$K=&K88)`(P!``", +M`0```@```$4``8A2&P``0!$``,"H`0'`J`$"`?0!]`%T!UGN&>P]BI`A?@Y_ +MIW>@I%'5+B`D"`````@```%L(0`!4+"03O876W&6A/V=.IF>!C/^@+$!&SH` +M!+%HZ:N(G:UMP\G(?5$"*Q87O+!9J!I[II+AI.6E4YH5Q#E04KV&I%F=Y`!^ +M)-X^D#2A-?V@?7(N8068T(V`EYPJ,DX:^=^=_X%%J'VRN;"K7_--811!L+T/O5[9CJ#&SHHR^4@'*C(FJ+RI['7 +MYJ8YSU7:M-BXY@TQP083OBQDD]]ZLS/)@Q%\Y@#OK/;AQXZVLX370,C>*I8< +M[V_`*LP?ONB723N,T;A72N=*\&>9[B``6&K]'JJFGU(?"+M8=F^M3!*W1KJZ +M"0!<`0``7`$```(```!%``%84AP``$`1``#`J`$!P*@!`@'T`?0!1`4UM^<(5'U9%(1\G +M^J3;-5SDC\/@V'SC>]:_O>K4`NFBV_(Q!8BD-&_#(&/L^^/'=,_K?I\=BK5[ +MJV0^.]P&^VTGA2J3S7!A,7?,";AD^ZJ]31$1D(Q'?TF/V!)D!]KWM=A9OI&I +MJ=]YF2F.PMT72]6IB:%/[63X`@,:MSBH_@RK)/HJ+[>I:5V$_X%OQ6&#\"1I +MJ`B7U01#R@U'WW/6"AN8:.='Y;0&DL,!+O+=%_%BW#*B^]R3>_5?W0OWL6'T +MZ9F1SR>P2!;2+OH(*^PM3GXO`L;SJCT9D`DY#:'/2UDPN0N:J4HQC__J* +M<(@^'=8Z5L"3?`<4PK4*(M#4)/[A#YA%?-J";*@9RJU"#%0M,IQ#[[`J%TP2 +MMT;=X@D`?````'P````"````10``>%(=``!`$0``P*@!`<"H`0(!]`'T`&0& +M2:3R8NQ8.L6JU3M=$'3A+@@N("4(`````````%PJ``!`283J/FH7$T`2/?>; +MDRF&>HRS5YG:NB9"5^9P\5LY>;GC7=/6Y_1,$K=&7PH*`&P```!L`````@`` +M`$4``&A2(```0!$``,"H`0'`J`$"`?0!]`!4!CFD\F+L6#K%JM4[71!TX2X( +M+B`E(`````$```!,````,!Q%=:Z$X?-5ROQ8HWOO\T47_2"(!`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``PH4:(LCK +M/;2/1)L1M2/J1S$-K]"\-,BO4!5U$VO`@UB2<'@ +MC6@,?O:YE7$8H`G#'E&W6FZ,FM%'Q8=O4FRM@66O/J$I```D5]&)^SJ)S4L:U2 +M```````````I("(@`````````#P````@``!`!@````'U")2S/\&4+[<=W2M' +MY+818Z$YD$P2MT;U)@L`N`$``+@!```"````10`!M%(F``!`$0``P*@!`<"H +M`0(!]`'T`:`'A72:X0>4L:U2```````````I("((`````````9@A```@``!` +M!@````'U")2S/\&4+[<=W2M'Y+818Z$YD"(``'@```!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``PH4:(LCK/;2/1)L1M2/J1S$-K]"\-,BO4!5U$VO`@UB2<'@C6@,?O:YE7$8H`G#'E&W6FZ,FM%' +MQ8=O4FRM@66O/J$I```D5]&)^SJ)S4L:U2:.-U;(D[SF(A("(@`````````3`B +M```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0` +M``(H``"(``(``#RE:;R)8":$+6^F5/Y^;ON88LSZ30>1G0/LT6%]SH.\F!$. +M\5H:/S[!WL46<$'6^K<8!EUN]O63?T3(LJR8*H@`D?`C#ZZ4GFGGE!B-C@`9 +MCR$2>^^)@)>1W]'P'/U#L6LP9>Z5;;CU08Y!L^=I*4Z]6V(@1 +MA>/Q*0``)%L'R4\4]S55:^IV(KN40";T>N*=44[>E":'/+DJ]$)=*0``'``` +M0`0&&\_*E$S(4:Y8/14;FY4]&G&Y/@```!P``$`%W;W)"UV+EYRN(LW"4:EU +M1)MVSI),$K=&V'D+``P!```,`0```@```$4``0A2*```0!$``,"H`0'`J`$" +M`?0!]`#T!]ETFN$'E+&M4FCC=6R).\YB+B`C"`````$```#L(P``T#<9ZKAA +MK*6G[T5E'V!!5&IGP=WD2*BE,FKNY6=,4#<""<"6B:$IN(I3W:@2XT&'%.0] +MF:AP%20Z(M4L:U2:.-U;(D[SF(N(",@```` +M`0```)PD``"`-_`$@'%@]G5QVWIG-7FIA,SOKN[`FC4IIQ)X:S:WOD(UL1)K +MQN(0`6'%Y@O#"Q)(;?NDO]YO,0OC[M!6B;D)C`+4%CH3>[I7%*M2OETD?HV% +MDM'B4L:U2:.-U;(D[SF(N("0(`````@```/PA``#@%-T@5@`P` +M15Z0<97^6M-JQ'P7YIE+6_U%9IR\]$E,X\L(8<,91\S:2+OVI//'FEN#LLV[ +MKB15[&$]+%#`_GK-'MU1YS,A8#@JX3.M)N(^VJ6"F2( +MK/]*$(M#?/"."S4L:U2:.-U;(D[ +MSF(N("0(`````P```-PA``#`GHHRD9"NQ5\E;T:`.8Y8%T$"#KN&GXQBBFGW +M"]"0[MD)LC(=.MTZ@B'M1JEZX)`<*32V*:JA2Y&]5B(Q4W`RPMC]J*6DO^]@ +MM$7[`CTR\S8U+`6Q.)8>:N\61/G9$^&/LC*(3)$-I&8 +M'YF*NG1@D`BIKGFC?RO+3X:XCBKZ%,DSA1;"WCD5PT<[X&+Y?MQS7BW9B_7] +MJ49.BM"8NZ[A@D]WG9NVCR'D,`>>SR64#]Y,$K=&JL<+`&P```!L`````@`` +M`$4``&A2+```0!$``,"H`0'`J`$"`?0!]`!4!CETFN$'E+&M4FCC=6R).\YB +M+B`D(`````(```!,*0``,%S+@^7%6^J5LB/['@$8334>K>D>8$DGP&7[JH]; +MC9_-Q@Y?3LXZH.@>@7XT3!*W1A+C"P!L````;`````(```!%``!H4BT``$`1 +M``#`J`$!P*@!`@'T`?0`5`8Y=)KA!Y2QK5)HXW5LB3O.8BX@)"`````#```` +M3"D``##7#7"7P*8.<^J@JDB'V)TT'M2:Y9I0Y!?7*,C52*'JG.Z4//T4@``/ +M;OS=$TP2MT80_PL`/`$``#P!```"````10`!.%(N``!`$0``P*@!`<"H`0(! +M]`'T`20'"72:X0>4L:U2:.-U;(D[SF(N("0(````!````1PA``$`K`&UH`T0 +ML/E;GCK[]6='^,@0/.&%-Z=\#H,V#R`.3Q\,PFX84)U=G_RBINZH07A8[@?T +MH4`"9CGY+J+5WR+*9I&U+H3]UODE4$)%A(OV;B$90)^8GF6#8W]L7#BM1'S["ON@.@+8F;+ +M7!=A[G64784*OH;-T-GC\*[DB_SKYW`=P2!V!"7VR3!*W1M,+#``<`0``'`$```(```!%``$8 +M4B\``$`1``#`J`$!P*@!`@'T`?0!!`?I=)KA!Y2QK5)HXW5LB3O.8BX@)`@` +M```%````_"$``.!ZFVE]PI:]S9OAMI(.F:)[?_`6O5=E.P>N1AZ<(OI!<21' +M0Q0A4']E[&7Y+TR8FQ7PQ+MV.6B:/+=*^RW4>_RK(5:`RFF*4'-@ZP_U$2;O +M'O&#X*85^CM:2W?5NV$CSUV@8VB(IGX2R!.?=-0T;"H8AJIXQJ=9_JCBY/6] +M_T@4*M?66%Z?5EJ@HKZC?M4CLM9J,+YK&3;$9:+M]0`A#XI<9AV$VJ'I>@'K +MD'7`>*;Q1VE3T^O5T)OF,R2@\#Q"OJ%JG[#EO8\FI@Z$I$P,,=;^,\HE>A:! +M'`X.F]=P3!*W1@<;#`#L````[`````(```!%``#H4C```$`1``#`J`$!P*@! +M`@'T`?0`U`:Y=)KA!Y2QK5)HXW5LB3O.8BX@)"`````$````S"$``+#@)/'; +M4",TVN=H6)^'D^ +M83*1AH#[VQ*]T=.X)J]K&$U>>P>83!*W1IX]#`#L```` +M[`````(```!%``#H4C$``$`1``#`J`$!P*@!`@'T`?0`U`:Y=)KA!Y2QK5)H +MXW5LB3O.8BX@)"`````%````S"$``+#;F_++A1XD<6#8:^-HNS8!N1JKP`OK*>__+BJ9CM*N>1C:XH +MI$:^#\_K$T?Y,\J>T':8X5I(]8+%;S:!_&PBC@K&1>1A^FWAEPQ/DW%X$Y.L +M?.0^74KR>!B,&*.`8H>MI2C^6A:=ZPI@4^D72I$Y:_NY@^G4\PP2^SI>)DCX +ML.GV52KU7T1^9L".SX6D3!*W1LA;#``\`0``/`$```(```!%``$X4C(``$`1 +M``#`J`$!P*@!`@'T`?0!)`<)=)KA!Y2QK5)HXW5LB3O.8BX@)`@````&```! +M'"$``0`_]5.-#P8/HX#\#C&Z;?OPW(E'M-2KL%.5GMVNW86A0:M.2MZ+R#^. +M.YY[%)3YU$X8ORMI5G]T;F-SZI8=P"9)G8VRH5U;`N]"9P^W@WATTN=6R2VJ2*O\S +M]M=="(M3*T7>`KR1[F@VFU:"12`2Q_UG_(T?!4G0[86*M:RQ;J0$W)>%DFY[ +M"N`CHG#B"<.":BM&K9H9YV@)J[DIL["&]<77R3?..I;Y7(L70^4E'H(;!J3+ +M+TY0#AC$YSX,1("BB[E5:JG6BMA^5W(>/)2ZE,CX3ZE,$K=&SV<,`!P!```< +M`0```@```$4``1A2,P``0!$``,"H`0'`J`$"`?0!]`$$!^ETFN$'E+&M4FCC +M=6R).\YB+B`D"`````<```#\(0``X(;O_!PP63A69;09!I1:"FVV$YJ7][$Y +M`0G)DHK(=Y,W))UQ1]9!'I/D7,`QKA/<-R!;#K`]J\Y\Y.<-E:OLFIJH5T>C +M63^0_"D@(PRX7HI?X$[0DYRB.HQ?AIML7<%[K35>[6#[A7EZ!35EE#DBDS3T +M+-/G`CY7Q#1RC\#L>J4@K>D3!0@FDZ24!H1^U,:TO@3H/]FIZX\T/]QD8A5I +M%"1X4(42%.E9K!3']C=IHK)GCC>)]U"07IE93)$JFY]WL0D'=__9ZL6PS7:5 +M:G;HENILS5ZINJ_Y[0\0`EY,$K=&27<,`.P```#L`````@```$4``.A2-``` +M0!$``,"H`0'`J`$"`?0!]`#4!KETFN$'E+&M4FCC=6R).\YB+B`D(`````8` +M``#,(0``L`?>I5!ENL5F$C_[6$]7R,"<*O),DUO31\*?NTR +MWW?4-L,QEW*H+]@T/RKUW13SV-MRY&K@.\LTJ=\&$\0IM/W=."=BD#-[?JR* +MG\U]YFR7.WP#\KTDGLKL5BNCDZRD"]'`.7M^!*5V_#X5.I,DU!'Y;M@&_;], +M$K=&*9L,`.P```#L`````@```$4``.A2-0``0!$``,"H`0'`J`$"`?0!]`#4 +M!KETFN$'E+&M4FCC=6R).\YB+B`D(`````<```#,(0``L%(HDCC?=445[.JD +ML7G'T>ZYC=-CQA[BS:A^-MFS:)\`#$$C)&UU2;)J&@H4YK,OU9/$\8'L.+_W +ME5ZW%T9^P7;(?0J&,L8R8Q/JLQA)%QM5K?P14*R]($I_#$A,)'8X0WA#W&FU +MQUL:F&=46OKHV\#!*%Y9>@8YSW;[65\W=M;IA>O,]UE'A>X#W.WNG-\SW=XB +M`,?\@(EY$5T:.VQ%6Z)$1!O&:#=@R!2C(Q!,$K=&_\,,`(P!``",`0```@`` +M`$4``8A2.```0!$``,"H`0'`J`$"`?0!]`%T!UETFN$'E+&M4FCC=6R).\YB +M+B`D"`````@```%L(0`!4)J2@SI,6.Q^,L/BA;#U2K2YNT6ULX_#V"FJU.D3G'76BI5!?@LK,_;ZH6\BKJ[MA/H^0)JWHTSZUWZP%&U;))Y;8URP2)K+1HYD*>&M`T1W +M<]A-O?A!'>XW$6J+5AD_XLG@PY!NIJ5-^^J9HX-_.NO'&N8\88.JXNU5?W\0 +M%99I>;>/AJ?Z$/O_GL?^*5==T.TA&B(,K0Q1"4?#^N6R3!*W1BCX#`!<`0`` +M7`$```(```!%``%84CD``$`1``#`J`$!P*@!`@'T`?0!1``*!SQ1-E:*7;!)3?\?7K&#V`9H +M&T&/E4X03Q1`.]?,H2)Z\"#/>=01V?N[J +MH/G"[JEF?.KQ5M__)H4,"AQWM_N]S"H_)KM9Q.$45X=B!_R2C?]`*#D1L9(5'H]^; +MHNW99*%2!_,+FMBV)ER!A^-4^ZP,1/W][^11Y,*'G\0N@#[&H/S7-:-%S1SJ +MV_*A7P'+4RBMTZGQQVV'A-J7V9E\APO5:"2AVG0Z&T>Q_SS"OTP2MT8_(`T` +M?````'P````"````10``>%(Z``!`$0``P*@!`<"H`0(!]`'T`&0&204=V.3\ +M4I"PKZ88QZ]U!+0N("4(`````````%PJ``!``F(`\R:3'AJ$J`5J`.BZZY'; +M[J^-?\Q!HW%Z%,HX_=QEL8*'/2$P2MT8_/`T`;````&P` +M```"````10``:%(]``!`$0``P*@!`<"H`0(!]`'T`%0&.04=V.3\4I"PKZ88 +MQZ]U!+0N("4(`````0```$PJ```P#VZ8<<./(O2OO=02T+B`E(``` +M``$```!,````,`D5O^RMFTW7GOH^B'?QTY7P-\!)Q`D@IIH`F7/I7!C&T38- +M$0.A<#D-*66&3!*W1FA'#@"8`0``F`$```(```!%``&44C\``$`1``#`J`$! +MP*@!`@'T`?0!@`=EM3U8;BIC=]\``````````"$@(@@````````!>"("`'@` +M``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``R36]K.U%1U&J[LR4 +MXASC$&99,1(EQRS\YG)V\?;]07M=KIFN38M33M1>)27TTV3VRP=0&BZ=M](X +M+/"6*8'`&_'FTUEZ7Y3%:4OX[FJ1178P>3+4`-R!`"Y;O0GU6GK4=]L/VDO#4_ +MG*&2:V(I.7V=EM8\I'EX*>`I```<``!`!$74X0G;$2F$-Q$$'FR'RP3W$09^ +M````'```0`7N+KV=L.H-V;N#N+GQRYB]D=%_6$P2MT9M5@X`7````%P````" +M````10``6%)```!`$0``P*@!`<"H`0(!]`'T`$0&*;4]6&XJ8W??```````` +M```I("(@`````````#P````@``!`!@````&,,&F_N="[R4)/G/'9ZMM_+?R\ +M]TP2MT;79@X`N`$``+@!```"````10`!M%)!``!`$0``P*@!`<"H`0(!]`'T +M`:`'A;4]6&XJ8W??```````````I("((`````````9@A```@``!`!@````&, +M,&F_N="[R4)/G/'9ZMM_+?R\]R(``'@```!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``R36]K.U%1U&J[LR4XASC$&99,1(EQRS\YG)V\?;]07M= +MKIFN38M33M1>)27TTV3VRP=0&BZ=M](X+/"6*8'`&_'FTUEZ7Y3%:4OX[FJ1 +M178P>3+4`-R!`"Y;O0GU6GK4=]L/VDO#4_G*&2:V(I.7V=EM8\I'EX*>`I```< +M``!`!$74X0G;$2F$-Q$$'FR'RP3W$09^````'```0`7N+KV=L.H-V;N#N+GQ +MRYB]D=%_6$P2MT:(BPX`4`$``%`!```"````10`!3%)"``!`$0``P*@!`<"H +M`0(!]`'T`3@'';4]6&XJ8W??6W&-\QFR04\A("(@`````````3`B```P```` +M+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"( +M``(``+XOOGUZQ4+BNZ5,<(9+*3EOJ/MWK^GK"HE&-ZC?T:V:+MJQG3SB*BG1AG0DM/I/B,-"3LVFQ7LO538.=?V: +M6_;M8ZBK.CXR*'UN+AXVB;TW,("XE(86))@DC1VNB'D]98F93^59@/I3*0`` +M))?OTJJP%+\XB=U[\DF_.4(^@1DV<5HS1!]!_WUYAG9I*0``'```0`3#\<3+ +M+T<>F-WM\4+<,5Z:":UW2P```!P``$`%EP6RHOL#[@)2F6B7(:IM`Z39FC], +M$K=&4;D.``P!```,`0```@```$4``0A20P``0!$``,"H`0'`J`$"`?0!]`#T +M!]FU/5AN*F-WWUMQC?,9LD%/+B`C"`````$```#L(P``T&#(H=2:_SV)FD,E +MQH3=]ID#AV&SV:L,/:B%K6N@^7Q>EM8879?`6E8*%O'$!*6:FIR/02D:_Z-) +M:\^L%Z(BXR]BHCAO+VL623W9YLEP.TS%A;"!HY6^CR_DS]]O!SJP!1,59/+Y +M^O!NPP$1C$8#5[Z$UEDB(V%]YV*`9&N+UI3J!&EYVIB^\!.-3+>I=[GA0/'+ +M%Y`&EX^\MJR+_LL$I#1N63KS-<%6P+X2M=03VUK^V#@M2"WFJ?@EP5-<4.GS +ML=;,"!,L8EY*;;BS8$P2MT8,T@X`O````+P````"````10``N%)$``!`$0`` +MP*@!`<"H`0(!]`'T`*0&B;4]6&XJ8W??6W&-\QFR04\N(",@`````0```)PD +M``"`WV;2Z)>V^DPFF5<\/;>CR]XN>S&,HM=/Q#YC`H!I9N +M.35%^C+6EYG8>J[IM)R7P!I`B@&_0UP#G:K&WWK#6!ZT=8\ZG[JYI+DI?]Y` +M/W)9>CV+22S"-D_%G7ZXNU/!02>A]'V)T&&]WX<2G^H5]?.4CTP2MT:(\@X` +M'`$``!P!```"````10`!&%)%``!`$0``P*@!`<"H`0(!]`'T`00'Z;4]6&XJ +M8W??6W&-\QFR04\N("0(`````@```/PA``#@]LUL4#2#X5WU.J:ONQ&248,M +M3I$Z$QGB4$8^F/[ZFB53!YOAH_?E;.ON*BNG/0CX[IO9'X0Y7U@F?NL56 +M"R6ZQD95.0QK/[`^'R@1Z:N3<^/OX;EEC3$=L7@^)`<5K"_IQ4^WRMLT00;= +MO0#]_D!!FURXU(TJ9"MSA9?3<*H_09HU8)@U:5<@OQ2D\Q:CH^Q]MN`W"M%;51[)!;1: +M9Q)=62GRN?K+J(JN*Z?2_5HE'&$OH.O,-4[LB/75QA5UUKEGV]Q&F?SW%6/*P4&"//8G +M_>TX:VF&Z&'XGJ$SJ7X$6SLS;+J)G2OUWE:D9`PHQ;S<:LQ.23I6$L_GCZC> +MYX0*<[#R(O?;`56K.YJ^`]GWP`ON5JB\]]4O$$YPX<_RN[@REX&S,"P6^HKR +M'`!HK9;I/PI8TPCAAAAKET"?5CJ:F +MKY%*\%S_BEQ&3!*W1A(G#P!L````;`````(```!%``!H4DH``$`1``#`J`$! +MP*@!`@'T`?0`5`8YM3U8;BIC=]];<8WS&;)!3RX@)"`````#````3"D``#`& +M!/92$7;H$88M$?*B>Y^N[`2PULB[IV`#R06USHWT0%/C=/W#C/T%V_"^WTT2 +MMT9]`0``/`$``#P!```"````10`!.%)+``!`$0``P*@!`<"H`0(!]`'T`20' +M";4]6&XJ8W??6W&-\QFR04\N("0(````!````1PA``$`S5U5VP)VU:^P"?3] +M2L]@&?`>9PBAPD%U&X49$'Z4*GH.ITBA%.*F$EJ0=%N&*(MGJ[+_PHQIDL,Y +M*ZANJPVS!$JSWUP%(I.''?]!A7.C['&(9ZB>O(.=&'[)-!O)3S:M-M.L,W=J +M61.C_FA![2Y]?;#*?CNEH6\%&I.9N>H_X>L@.9([DS=I`G,QW(G0:4R_[%<= +MATUUK_8]/5>J:V>=+2R2R_4<:-D`!:PZ#!/)>YBLRQU:V`98)XD6!*FA>;QQM>6T%-C28-13 +M_S0&M\;^-(ME.YAH.`,.[^E%)!2>)*0=Z*^N+PUN_]E^SE9)#2[&:7+=E:VN +M7.K5(FXV<61US5;/PX)2(HL.9M@AF9B6I.[!RM*=^.R0"2QO6F=Z%K)Y[-:Y +M".I]D6#F*7L%Y-O>/ST,L7:E_!WJ9[H^SL>-MXR&UP"."/VTBBU//ZG531*W +M1@(>```<`0``'`$```(```!%``$84DT``$`1``#`J`$!P*@!`@'T`?0!!`?I +MM3U8;BIC=]];<8WS&;)!3RX@)`@````%````_"$``.!8SP3O*;(-36/J_26X +M,X4+."":F^SI?MN15.W\R?,1!,S`[(/,<1LXS"N'[&%9XB270;H:\$4LOVMP +M^B1[EN)!%M<[*)6&&'E^:^,7>5`Q?Z'=[59Y:R=NG#"'4I)ZDQEA`BA5*O%' +M>+5?I3%'9>8YI9$8$:7\H +M:JE`NHD1%&[%.UQ<7V3!$#)<"/G!PQNT]2MW8OI@\&!.C[I/1>1^FX\+ +M&8W0OPJ"31*W1D]"``#L````[`````(` +M``!%``#H4DX``$`1``#`J`$!P*@!`@'T`?0`U`:YM3U8;BIC=]];<8WS&;)! +M3RX@)"`````%````S"$``+`&CLT>@\C9=%RG4U8.L1[PPSGLSK+)G'$*I#./ +M`28:/>[ID'W]\1$P#)*>G2HOIWVP\'W&>P`?T`^%:Y&6]=MW:V8;=*JV77^O& +M@)ZGL?U4&<_631*W1E)A```\`0``/`$```(```!%``$X4E```$`1``#`J`$! +MP*@!`@'T`?0!)`<)M3U8;BIC=]];<8WS&;)!3RX@)`@````&```!'"$``0!$ +M&0G$4OAA]*F7VSA8+INMB#@Z+,^F8@]14!@K>\9^42V-.>`X(6JM`M=3P[]_ +M\ZNST:>E(9+,?SBFM:1F+8]S"VQ5*_`]P$55\TA]BYN,S[U`5#4JEN8+1),W +M:U?=GO>HSU>L9A^2X;,Y%FKV+N4.]0\BO(X;>>=,0U&OC,_JHC%DOC\W+#4@ +MYP*%X;\Q9B)*,DYQ:9ZY+N,7\K(%=\GQ0OD.GO>+9=G^3)'6BP;*B/(K/!W' +MCPLNKN1/QY(X]U:RW=Z=:!-$K=&K&T``!P!```<`0```@`` +M`$4``1A240``0!$``,"H`0'`J`$"`?0!]`$$!^FU/5AN*F-WWUMQC?,9LD%/ +M+B`D"`````<```#\(0``X-'HW'\O=E\\C#4NA4"RG?!A-4Q::<`%P05`@R]X +MAZ/8YDI;X[YJX4E#BS01Z*-1-V8MQ6:+6Z-&%9GUU;"#M9$7[MJ_OE*@"Q]C +M%,C3>)6JPI=-\5E\QT]M^[;XC'NF.M).3M0^:7!`PE[*OQT5/6_V`>&>[TEE +MOR$D#T-W!_2J>;R9^PER#FCHN(45Q"_W!QR:U*<.7+_,W')'J@E9/D4RJP<^ +MB\Z(ZC+G([`:?LR+&'W-=>"NFD^Q8"\A9*`__'>O!^AV?*\>$)9@S*LR7MO( +M:"@\/9`]4!\^H^--$K=&"'T``.P```#L`````@```$4``.A24@``0!$``,"H +M`0'`J`$"`?0!]`#4!KFU/5AN*F-WWUMQC?,9LD%/+B`D(`````8```#,(0`` +ML`]Z"P5`@S.?\^1+3'D8+>2/EK;255FVVV1]+)TW,6RC97ONE81S[,8V8/.B\1*%&+ +MQQ05U;65%/TC$G`S36WE%HM)/'@DK2X5_6>0\4[9>Y+4W0MWIG1?VL2O.`K) +M\N&!P0TE5PJ5"5/*:.M@H&7^F*(#E!>]324:+_ZA-$K=&`*`` +M`.P```#L`````@```$4``.A24P``0!$``,"H`0'`J`$"`?0!]`#4!KFU/5AN +M*F-WWUMQC?,9LD%/+B`D(`````<```#,(0``L-Y&2:"W1KOJ=XC4WSS^9TCL +ML+JD7Q)H`+L87]RFJH#)K.W]@IPE^KUR3][G4RKX8V)1H)P%&BEJD//DO7 +M]$/#,)5N;R0LT-V7NSS[1YG9J%=.]W6>AX^4M%\C)EOCOO8Q?5-$K=&Z<<``(P!``",`0```@```$4``8A2 +M5```0!$``,"H`0'`J`$"`?0!]`%T!UFU/5AN*F-WWUMQC?,9LD%/+B`D"``` +M``@```%L(0`!4+I)DMIF(L@S\]$8QDZJR.FP4#)S/I6EVUUA;<,SZXCQOYV, +M1I75U%,+7P,!R"'%#3HW'!M'#C[UD4C6/V:#CN^_!B>)H:XMW\`I1%,>S_OA +M7P/(&R`4J"UK7S9/IAK`/"5F8R)67^R)+NIKU$1=??&?QRTBMJ=WC8]_([>7 +MX9>$<0XX?^*G=U@0F[.&V@1>D?;!?PHSH8=.CT$^0F6UMW"K0[EN"?H)-X$. +M3DMFJ"4Y6T>H+_4,36KN,T@X_"^DH,?;MWJY2[(ATM>QS4)+3)_.AIQ*PAR\ +M"*58().Q]Z[:EW/PNN]DRZMG2?C?`JK8875MWGMJ,I0CRCUC/UZ6CERMK0L& +M*8!-X3=MO`U&'J72S[7D9^X\'AHA_4NJ&-+WL)!I.GS(=)`')5"@S5Z]=Y(L +M5?H0$S_C@^"I8+7+>&)_D!U\^L=.6<+W)\DY31*W1I[]``!<`0``7`$```(` +M``!%``%84E4``$`1``#`J`$!P*@!`@'T`?0!1`(C#D%H/2:Z?0&B7N$YJC)$TCWGRVPWK-#? +MT$F(A51LZ_6[Z>O,)S52ZX[Q_BEDTBPE*+H)J1L1S^(J$3\):42J.46'-K3$ +M!Z,4L+T3:0$UB-WJI58'4TM`!)#J[/ZF(.PXHP]`T.L5G3'(S<>UM%SXW4T! +M#Z.-":9G9@]NPLT/4M@3!M8W)))-(N +MZ"(>%EC%)6``!`$0``P*@!`<"H`0(!]`'T`&0&24-7N-=2M4[IHZ@6 +M`@`P?#4N("4(`````````%PJ``!`,QV,YPTGZ,35(*T<%`;1;>W[9Q8\TRU< +MH&2R<]`0LQ^*280_!1[6AWJ`5(_Z#3^TKU<`X]ZG`%F`TPGZ31*W1J8R`0!L +M````;`````(```!%``!H4E<``$`1``#`J`$!P*@!`@'T`?0`5`8Y0U>XUU*U +M3NFCJ!8"`#!\-2X@)2``````````3````##!A6U)77&6S77RL\..SU$BVPZ) +MV-Z?/7@J+;@E+SHM':@8[0B)W`_P$8?54$T2MT:900$`;````&P````"```` +M10``:%)8``!`$0``P*@!`<"H`0(!]`'T`%0&.4-7N-=2M4[IHZ@6`@`P?#4N +M("4(`````0```$PJ```P0RQ,=G)J$&N/"X8)L/Z0C1PMTG:U)B03EPP!AD,S +MB]`=,/*H$!5,WT:$:@9-$K=&:TX!`&P```!L`````@```$4``&A260``0!$` +M`,"H`0'`J`$"`?0!]`!4!CE#5[C74K5.Z:.H%@(`,'PU+B`E(`````$```!, +M````,&-U@*_"`37$[VAWL`[:\51?'1?K!(>(:+,5GQ-'G;H&O)%K`Z+&\.!Y +M[O"B31*W1IU+`@"8`0``F`$```(```!%``&44EH``$`1``#`J`$!P*@!`@'T +M`?0!@`=E#>I>T#XBO.X``````````"$@(@@````````!>"(#`'@```!T`0$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``&ILD]&V_,:'QD%?VT!CX`J6& +MA30T6N11L"K>50J57U!DQR(2DLRN&Q0'0,Q-192EFS9^RX\82QY4%Q_QY0IS +M=Z6:(.O'VSYH*TJMY"KY`K +MN*,%IR;OSZ..C-G:R$G2[A2W=B +M9`N8=V*)V#V1`U(I```<``!`!#&4^QOIR<(R`",-1!3.7=0HR50J57U!DQR(2DLRN +M&Q0'0,Q-192EFS9^RX\82QY4%Q_QY0IS=Z6:(.O'VSYH*TJMY"KY`KN*,%IR;OSZ..C-G:R$G2[A2W=B9`N8=V*)V#V1`U(I```<``!`!#&4 +M^QOIR<(R`",-1!3.7=0HRC2AOF"M! +M!/K4@->O?GNF,:"\6CL=QSA(`]BV*RRG:EIUD--`V2D-:K!Y5Z/VXCO<*BLQ +MW18-G,`=&`3`J4-D3E@HAA3UC#T;DD@3Q>L<%C3&VVK$JK;S*0``)/1":?U* +M-N>`7!WB6VD8Z6#6@K+&G'`.J&"%=R(JU@7`*0``'```0`1N:.BR.P1*IGU: +M[5!!#&^+H\5N10```!P``$`%SG."O/DLD8$S>4;/O_L7U@_#!9U-$K=&KKX" +M``P!```,`0```@```$4``0A28```0!$``,"H`0'`J`$"`?0!]`#T!]D-ZE[0 +M/B*\[M"DR*6-2/,(+B`C"`````$```#L(P``T(R3NG/X%8?(AD^'3US-SK_< +MU>3A6^59JT?IQ8"C(<&%N[]LYWWYE81RH=*?@[AV.*",`S-OMO<5C!BBK"SI +MXDJ\B1$0HRB-"&Q8W+<__5:V^8582<>4C88GQ!","D4D#[T<\L@-LC!-&'ZZ +M)0^#[):K5$"9+P=]2U7H/9ZV"!OR +M'2@*=E"63^/,Q@>LOD6/=)E$#\O%ZF*-?-"U'\2096`4I&,^?_ +MPO)0D7"'YJRWC1("Y_<',$T2MT9V!`,`_````/P````"````10``^%)C``!` +M$0``P*@!`<"H`0(!]`'T`.0&R0WJ7M`^(KSNT*3(I8U(\P@N("0(`````P`` +M`-PA``#`80FF8'G;JI)C^K"^6GH`IF6,3PH9+XN1C#GU?U-FYVB+J2)_1X+^ +M(<*K5>:WOP9!XVR4=BBUEA)'6.:%+R?M +M2#VJ&=)=E +M&0JZ!#4FL\Q]SY`1D4-+5&M3PDI>T#XBO.[0I,BEC4CS""X@)"`````#````3"D``#"H/T16J1)M +M4V0,@`./OWA!K4.#GYP\Y1'5L0D%!U;A!V+%Y/25#N,\]U.D]DT2MT:?1P,` +M/`$``#P!```"````10`!.%)F``!`$0``P*@!`<"H`0(!]`'T`20'"0WJ7M`^ +M(KSNT*3(I8U(\P@N("0(````!````1PA``$`MK[#N5_`LL%3<9>BIN453QWB +MTF="L_!WKY0ITR^SK50(G&G\V8I?"=+8PIBG5,:7A8Q""NHZ<82`V2XP%+<: +MK.`>X1+.3HZ3U4J^J9O#-*QCJ1$\<4AVY]SAV:'YI6N`V(D6$LMGPETYT/TH +M<^'S9,/#D0"6CT(2NG(5R]Y<.%5NR+'FN9BZQ+!"0VX\D->.BNKGMX7B]4C[ +MI,5[L/I@/8HE,J"\=E;A-9@N`@96N]:9EOQ+XWHC;G&` +MEAPRLGKFE_)[B?@.XUAS>8`!8H!C;\D340JY_'[_A/&_C&!V%S`J)3<.A*`V +M6M7GKXZB,U]=31*W1H)4`P`<`0``'`$```(```!%``$84F<``$`1``#`J`$! +MP*@!`@'T`?0!!`?I#>I>T#XBO.[0I,BEC4CS""X@)`@````%````_"$``.", +MI%,W<5D!3AVO-KMDI%X8=AYLL\\5Q,/N\J+2A=8*ZV^Z"%?B$_5ZO[0QO:`#U-8$FV$B-?AP31*W1N]C +M`P#L````[`````(```!%``#H4F@``$`1``#`J`$!P*@!`@'T`?0`U`:Y#>I> +MT#XBO.[0I,BEC4CS""X@)"`````$````S"$``+"DPO=YKJ\DIOV>0><;K-P( +M*J?'#/I\;FK\3O>419^[\(-5X6P_792Y6)3[9?LBSSP-.X7(/CT6>G&#BW`3 +M!C.$534-:5P*6]L:`^7@5$O%B%NHX#@H2SZD9"DAZJO4ZFC;2IYPQCLRP?S* +MOFRXZ[Q+)7)T8_]="VH"X33\4HG';^#BGHBWE&9]4[)TG-?)UCJL5# +M\0#'"LAK^^7H%M1H]RV<2CFOA=W.31*W1@:*`P#L````[`````(```!%``#H +M4FL``$`1``#`J`$!P*@!`@'T`?0`U`:Y#>I>T#XBO.[0I,BEC4CS""X@)"`` +M```%````S"$``+#VMCY6>)L#,B?$KMIWRO1=U<6=>E7"K6L@E<8&,H4&'U'+ +M,>E?=L/BPE<$&L@2 +M1XJ)31*W1O^G`P`\`0``/`$```(```!%``$X4FP``$`1``#`J`$!P*@!`@'T +M`?0!)`<)#>I>T#XBO.[0I,BEC4CS""X@)`@````&```!'"$``0!5C*2-0*<&;PY$_2V;9?LI`53Q[3U$0T_`#S)Z* +M8W6,;W^LKK+G5L#V3O.!--C`F,D`0BQ-^Z7X"1^`H.[>R"A=T_>MO:(*`0Z! +M6&$B5-WZ1&KI]=>-J[[H&YD`O!K8:=OV]TP+%'3V"#H+-7<9E>!5B<9@AUBG(DSXJ@GH^X3> +M$ICOS8(1C+O[@Q&*\S)6!5/A1#DZ0IDW9Y09_F)/E.8!OF^V9FME'B3R)VC$ +M"="YN]`M!OI%8SI9#S-184TVK3!V'SC\R+L"VAA("(F1=M,*>6SOP3I3TBXD +MY0I3F>"'\OG99NUU.R,J+;TDZK(_Y6";\,H790*\THC(#B2C+-;T<(U.Y##)SZRM[MTSID'`,HZ7P5 +M[=E.!J*=NUYT>"_#[4@8C%JRE8A>`811W?_;60`^.^Y-$K=&->@#`.P```#L +M`````@```$4``.A2;P``0!$``,"H`0'`J`$"`?0!]`#4!KD-ZE[0/B*\[M"D +MR*6-2/,(+B`D(`````<```#,(0``L'G/V(AV<:@B?_FZ,$(U7EP"F9>$(+EH +MUBW``<6O(/'J20];AF"NH?HRU_I8?"I(5*#[QR?FCX3WL%]_6K7W-QK75$Q" +MT=VP3=2]UN3V2>8V2=`UW_T)968)A3;NTZ;J\*U\;]'*W&<.?_58E^S/5\8\ +M:<,:OR7OVU]._B.71I!)DH`\+1R5'9%UM"R/$-E243/@S[Y(#+I_K2Q,?%W+ +M^='PK8=0*2X+_CE?I,]-$K=&=`\$`(P!``",`0```@```$4``8A2<```0!$` +M`,"H`0'`J`$"`?0!]`%T!UD-ZE[0/B*\[M"DR*6-2/,(+B`D"`````@```%L +M(0`!4,I.Z+8*I\[&J*14$X%;)Q>Q3QSVD4:?Y65/2FB)]\"`PV[3H(8'-@>M +ME=2R)K+B0H@\X)4EG9=,D%)!2_1SQ8$=Y^7?B"M+-GUUP-M0;4$H#ALK#/ZH +MPD7V5'GMX>_*1;;!;?8[3LW;"#R&1A*\`!/8;7#X6XI2+;@W*]4]@:'$_AP"L<^=.:7MC<"0RM970TE]YGY42`<44980$)DJVN +MCQOAPI*<6A6)07006"WS6Z^\@:83[&A'+]23R2=7['Q@H^57?Y%LNFGNP6P; +M-T#EC'568QJ_Z#?GC6U*(G;U"`5,[DS(3N).@ER1ULZ=-[+6X#?=#MMKB";` +M:A!$]PME[A!*W#RA0#%@,)JU&CN631*W1I=#!`!<`0``7`$```(```!%``%8 +M4G$``$`1``#`J`$!P*@!`@'T`?0!1`I>T#XBO.[0I,BEC4CS""X@)"`` +M```(```!/"$``2#KR;SN\KR0*)9,;:J$'71):^JY/;)&_\W?@D;UPI8KAJY" +M*H1@RE&8";P$LC9:]#G:`1Q7E_]E+16[#=!H<-+D(FU+-?,)2)5Y0LD*J!PW +M]3G1!EC:%4Y:HYR5UH3M6&OMO`*)C)G2U]BUAW5=)%%*CY3IF)(^M\YDHHUT +M1V:X'Z9F.;_ZL,,+_+50$/BRP3_!#;J%GOW4(J"5@*U6U[S0NE!@ +M!<^PT\9D!YB]64V7N#)0=MU3,9YYQ#76M4CLP%ZD;*?@AOWL3;[<"UD,])O\ +M1[CUXQ5TYL6[5/"MH5#D^0>UA00;>6X')1_'JL79W[T$,)_\$47A=0J3.SDN3=M)C)@=$RY14T2MT8";`0`?````'P````"```` +M10``>%)R``!`$0``P*@!`<"H`0(!]`'T`&0&2:F>6>DN+"0+H'9:BWYFZ@HN +M("4(`````````%PJ``!`43RP@+?@]_CFIP&S(,R="TH>J$20,6M8KS6_K6BD +MP]U=V%4(6!XO^Q[V:CQ:ET\^KN8%]WGSK&RQMY9*31*W1N!X!`!L````;``` +M``(```!%``!H4G,``$`1``#`J`$!P*@!`@'T`?0`5`8YJ9Y9Z2XL)`N@=EJ+ +M?F;J"BX@)2``````````3````###D\)-JY$2]^#$?<)L[,P'$.]Y,:MK! +MSMGW\J*2SN"S1Z#C1:C2N#&8(TT2MT8[B00`;````&P````"````10``:%)T +M``!`$0``P*@!`<"H`0(!]`'T`%0&.:F>6>DN+"0+H'9:BWYFZ@HN("4(```` +M`0```$PJ```P=1@S[TA.+M2]MBL(L1A>B"!QXM2/=R"=?P;2V0ROUMW/B$1? +MY3H])'O!M/%-$K=&TI8$`&P```!L`````@```$4``&A2=0``0!$``,"H`0'` +MJ`$"`?0!]`!4!CFIGEGI+BPD"Z!V6HM^9NH*+B`E(`````$```!,````,*0? +MLGOTFMHIM8XA)3'A2%I5OGLQ"($`'@```!T`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``+XG$'[9>W9S*B>H8R&,0GL:Z8(>;V7VD +M,CE5"Z`2_3/ZC_H-0V\W]7L\*2_*![07TYH9B)&=93%`HI;CR;OH^VO6RT=H +M0"P\M>84^W#4!)8&XN,\=6Z0R/K*%K$`I```<``!`!)U.O>I94\J)KOT%PO[(DU*2J%&W````'```0`5=[49` +MC`N9WJ^;;_8(GW='`0RW+4T2MT:`H@4`7````%P````"````10``6%)W``!` +M$0``P*@!`<"H`0(!]`'T`$0&*6^?NDB\G:91```````````I("(@```````` +M`#P````@``!`!@````%G\)D]'V/_P["TH08)#9KL5!#JGTT2MT;0L@4`N`$` +M`+@!```"````10`!M%)X``!`$0``P*@!`<"H`0(!]`'T`:`'A6^?NDB\G:91 +M```````````I("((`````````9@A```@``!`!@````%G\)D]'V/_P["TH08) +M#9KL5!#JGR(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M+XG$'[9>W9S*B>H8R&,0GL:Z8(>;V7VD,CE5"Z`2_3/ZC_H-0V\W]7L\*2_* +M![07TYH9B)&=93%`HI;CR;OH^VO6RT=H0"P\M>84^W#4!)8&XN,\=6Z0R/K* +M%K$`I```<``!`!)U.O>I94\J) +MKOT%PO[(DU*2J%&W````'```0`5=[49`C`N9WJ^;;_8(GW='`0RW+4T2MT9V +MUP4`4`$``%`!```"````10`!3%)Y``!`$0``P*@!`<"H`0(!]`'T`3@''6^? +MNDB\G:914[O-'%Z?&S$A("(@`````````3`B```P````+`$!``0#```,`0`` +M#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``,A2R9EVS[5A +MZ9R/YW\S;5T7&%/$(ML +M(TW%#/!>YOCI7*0``'```0`3Z>[>R'WS6+2?<=F^$!?@O +M\^144@```!P``$`%EA53%@T]F-XR;JEW&48;;##JL%5-$K=&<@0&``P!```, +M`0```@```$4``0A2>@``0!$``,"H`0'`J`$"`?0!]`#T!]EOG[I(O)VF45.[ +MS1Q>GQLQ+B`C"`````$```#L(P``T*E0)S+(B!45N[!#F!I/]<*>V7I\&(P$ +M9*W/E8/\\F'A0H0^*<$/L@)I^^&P\@%[.QVBH0E=/>I!8:G0ICZ,P;*;<`J7 +M^.Z8!Q-Y]:"D4`1'CERL&:>G5\:8O2 +M613D+C/ZF`M#>C3-U._IA=:7T-9M&Z3<6>1'$PS57IG3!#!WX*;XCB!T^I!J +M@J3E4;;7WX8\QW0@WXE^L3M!B&@C*H)MM28E1Z"CJW3+C>KQ(%[FGSE;F5D" +MSDT2MT;;'@8`O````+P````"````10``N%)\``!`$0``P*@!`<"H`0(!]`'T +M`*0&B6^?NDB\G:914[O-'%Z?&S$N(",@`````0```)PD``"`_/::U@K8&I)K +M=Y-VXL>^L,OWMJ5RG0'NB6F\Z!YBZ"(?.Q7SSC,K0:H95W^[@NKCQ),VF*FX +M5,*02$,"--D38PW_?5R3%142]$13E&E_UX**X;W7`XJDT2MT;=/P8`'`$``!P!```"```` +M10`!&%)]``!`$0``P*@!`<"H`0(!]`'T`00'Z6^?NDB\G:914[O-'%Z?&S$N +M("0(`````@```/PA``#@`@T+/;$?SS219E]BF&K'Y`:4MDZZTO>N+:IW]@P@ +M;27N_R\\E#>-A3)8^P/P>7R=E#/5.CAU-F=QD%HEX$TNHPQ!P4S59+2#,#;Z +MR4M/$5>7R\?6A$%]7[Q.48<$>FW3S<8"-;9G90>=I9Z5"?#_WVH6$RCO@CRR +M,NHJQO(N1H:UFOREA86A#B<^663HM1#&QT0`!DW5=:DX7W],X.T#('H'763N +M];5D5@TN=SV",*=Q3>G[.;AI^V'@YZ?(8+OIQLT^:%SG\T_A0=?B`S:D6K5: +M?]*`C!T=D-O-PTT2MT9T2P8`_````/P````"````10``^%)^``!`$0``P*@! +M`<"H`0(!]`'T`.0&R6^?NDB\G:914[O-'%Z?&S$N("0(`````P```-PA``#` +ME$YE59@"VT$TQ\WYX?O2F=O]Q(>-]N'7115FGB4/^E/HL%CP26]`SM7V_E"G +M@_/MPB"U54R+J5VKR!N""85F]G8=-[4R_:U[$ZK +M4?4&C,K>X8-YT&@3G3C1--MI8#_9G@S3CC_U9",ZS8W7/ET7*PQ98R2MHT=. +M6.J?46U%63G0?6FL8[K%W)<;LT#_W`F=@#"AUA1>B@X4+3[HHYM`:.2>'=)J +MGD+M!@MGY-=-$K=&'%8&`&P```!L`````@```$4``&A2?P``0!$``,"H`0'` +MJ`$"`?0!]`!4!CEOG[I(O)VF45.[S1Q>GQLQ+B`D(`````(```!,*0``,+VC +M-0FBPTO)!O7DF9`(K2(5;A@J_S.:[-?+KS$PSS0^[ZEPK+/'RD*C>:Q031*W +M1B5R!@!L````;`````(```!%``!H4H```$`1``#`J`$!P*@!`@'T`?0`5`8Y +M;Y^Z2+R=IE%3N\T<7I\;,2X@)"`````#````3"D``#`QN'`6@[P04/H=R`.> +M=)DRL,_,XIFF\XHD(UN$!'K!(E%)"C6[%<_\K_(,*4T2MT;MC@8`/`$``#P! +M```"````10`!.%*"``!`$0``P*@!`<"H`0(!]`'T`20'"6^?NDB\G:914[O- +M'%Z?&S$N("0(````!````1PA``$`JP>=@YX39/;O09"HIJ2X3T>YC'.-S<4+&X*TFS;B;%BS3&PA3N]L&@G33R`["8^,@7'@Q&,68@1 +M@(!ZRYK?$$4;F[N?2+0(?EYN3^R.H0&A%MD27%GLM&+8%@2CT>5/S7$\!`H= +M"5F'+SJ`:TWL7P_IW95:Q_=^YPM8^#P67-1 +M#YE;5*PE(M^JL$Z421%0'59'#-\GLJWBW%MM7QB0!&9,`8YN-;3^#T>8,SS< +MRV29-P"^CX82E2+:O`4;JN\]3]X+7+ROI[N#F%N42-+]:W8J?]BA<`\A[0EQ +M>A3J31*W1E6?!@`<`0``'`$```(```!%``$84H,``$`1``#`J`$!P*@!`@'T +M`?0!!`?I;Y^Z2+R=IE%3N\T<7I\;,2X@)`@````%````_"$``.!/$`\O'S(9 +M^9OW[=C)O[^?9B`:@`F;?\\BO@1CO/`=IM]IZ7*[X^3IC3(Y!AG.?UU$:LO) +MR\4EJ[XU16]@X=DJ*$)X9`(OA1YWKJY/5A\G$<;B6Q5PU)F+P' +MFL61U#>@[WRW5[`+HP_E'"80=#+*JA^TCQ$`>@+"+?M;^`LE(KC>2(9\SK@V +MQC;#U79MW]W;\`9_5N3/J*CTK+[0G"2MFE>0?Y,*MN(*45H>/3H\R)W,S?Q+ +M_?"MTU#[XR'N:XQFLI&`BK*DIG/J\Y[Y5W\9Z:P9(SI831*W1B*J!@#L```` +M[`````(```!%``#H4H0``$`1``#`J`$!P*@!`@'T`?0`U`:Y;Y^Z2+R=IE%3 +MN\T<7I\;,2X@)"`````$````S"$``+"4Y:&RO(*-\]PF<;%@-O[P%$R?OD'( +MLU/Z3?%B*RRSL&6-`\'!"FTK,./?['D=RB=$W->$%0'^_#V8Q'"(9I2:,J@T +MGF@@"A(]J3QD(J!U+='43"%SK8LE.EB^A&`A"#:H6/"'708'+.[K-?6[=)KU5VRM?_!%G61C9TOX'GX +M1#PH@.Q!%(IB)BNKY[2731*W1A7.!@#L````[`````(```!%``#H4H4``$`1 +M``#`J`$!P*@!`@'T`?0`U`:Y;Y^Z2+R=IE%3N\T<7I\;,2X@)"`````%```` +MS"$``+"*""&7H!XL@PDLYMCV'8&D2%^_S;U470KW@O<;X%DZ&0B;%-^+",02 +MCSQ++<%FL.:)OV"/+A_-)Q:"OG6E<@%RM,L;@['@0>IJ29G5MP)2WV_D^2P1 +M(O:SL^Y+4ZA#<]3&D#A7C>+6%M$(V,6C%";G&@&WE3LNX::?;P$H.\4!&VL` +M,#$)^YR=E=^03']ED*/[Q5MMIOL$A>"!6_;(HX9#=7TP-V^YJY5.IKW9T?(LL6^\0$6* +M,%J6Z[YXK1!3%,=K!,BBJRJ$X\0[M8)12H(Y%]CO`FIEO[%\A16P_-SPX5O8 +M8X@H#KI`@%;XETCTN0F:92DS#__Z@"HRF[$L"&.BJQE;7FB8PE-:_EBBICCM]M1&]B-AH`4I'M\ZP7N;P/D6,30HC;;`B$ +MYZ5NI0U5`_%>@0B1I0U^6->V(LIG_N6Y&[$?GIUE,8)(D6K^D"\X3:&IXETV +M`4;DCC=Q36&ZOQ)&<^--$K=&N/D&`!P!```<`0```@```$4``1A2AP``0!$` +M`,"H`0'`J`$"`?0!]`$$!^EOG[I(O)VF45.[S1Q>GQLQ+B`D"`````<```#\ +M(0``X)-Y2#"<(Y^0I/'@#O>D`Q\]P[R]&(K:(HW3.YUG%"GE]CBX.S$T=J]I +MS^N;*K"7^4&MC7,2R +MJOC-%:MUSQ7)NFE1GQLQ+B`D(`````8```#,(0``L*ZX8(PJ/UW*"6*/ +MGOWTX^4@JM&ISSL7A\E#5GG,O&6_C"3H!TI&-J>$(KR!Q`R1F2!C90S]W6XM +M>_)^E\N3^W`\2=$R#%LVKYO;84=.8Q/9&:`TP0%6I1W/OYWP@IQVI9JH/6W\ +MG^9:,2P!)U8BOS#/20VS(L9'O*U!A&'P1NE=C8D3\H-]V0Q_:;X2.%/H+BNS +M=@R"X3L`$9FE61U?*N7TXRLR@:((CT!-$(Y-$K=&V2T'`.P```#L`````@`` +M`$4``.A2B0``0!$``,"H`0'`J`$"`?0!]`#4!KEOG[I(O)VF45.[S1Q>GQLQ +M+B`D(`````<```#,(0``L&#W=E[<.1;?0W*%7+6:RMAZ%N.8%>]BQI1UH%@" +M(.<6`#]2AW0?SEW';-S!S_9C;CPDA,J$B31:[S>:SU$CU>LH-!73W/9E`;A_'?\DL +M6-N0,L:L`^Q-$K=&@54'`(P!``",`0```@```$4``8A2B@``0!$``,"H`0'` +MJ`$"`?0!]`%T!UEOG[I(O)VF45.[S1Q>GQLQ+B`D"`````@```%L(0`!4/]] +M^S&#BT!@!*SA!^3ZDK7O$O&"64/)2WF?G7C-EP[ +M.[_9MRLN`^3%6K5GUH'$JZNF?87_HS[)Q"R]3`GWIO%DQP%';U.#OO.F35@C +MC>->!31*W1@Z+!P!<`0``7`$```(```!%``%84HL``$`1 +M``#`J`$!P*@!`@'T`?0!1`[UIEK5CN6M\!ZT&$YA83QQU1BN]:HBU2E+>;8XE +MN.U7-5CM&'%"!/K$+7HQ'[8%X+T=WLI1R$S5U?D[M^DGNTC=YN"@9G5T] +M2C!N7B[-4*[)3XL15X>?:MV',5]>)4V*HFI=&7357W&M0E+L=]D*U&M-!71' +MD(9DYUR5#72M.F-_>[YUNP/MV]*[>/[#AD)F9'=KADK5\PD#_65JNV`('`O5 +M:,*,5@K"2'RM47NSQNTK["`ET\PXIWD7X:M^+Z-4FQH"37&E:YM^`$E-V-@Q +MLNV:4CV,L#=E."5%\=T87K\*=>VQ/>^SL.Y27P]H-\_`NX(^S8:\<[BFP7+V +M?+?[]M\ZD+K[=_0.I/HNF>C^FTT2MT9:LP<`?````'P````"````10``>%*, +M``!`$0``P*@!`<"H`0(!]`'T`&0&2;"C$:MW7D+*H\`#SK:*^9@N("4(```` +M`````%PJ``!`Z=K![I'L`W31=%=76_DRT:UT\,',+0AQGDI,8C74($DOW,5P +M-=^5@S3A"F/R$A&1F1`>F#$!4FISG@C131*W1MF^!P!L````;`````(```!% +M``!H4HT``$`1``#`J`$!P*@!`@'T`?0`5`8YL*,1JW=>0LJCP`/.MHKYF"X@ +M)2``````````3````#"2"`5MRN"5*L8]A\RC4D@3FRS=F@/?;UI*EE7R'3,D +MBUK0=/AS.B,9L`$L4$T2MT8-S@<`;````&P````"````10``:%*.``!`$0`` +MP*@!`<"H`0(!]`'T`%0&.;"C$:MW7D+*H\`#SK:*^9@N("4(`````0```$PJ +M```P51AA&QW@89:5VZ'PJES^AG5ZN?0N%#--'%:(<@TG1R/K@=XF,)330:J> +MP^5-$K=&1-P'`&P```!L`````@```$4``&A2CP``0!$``,"H`0'`J`$"`?0! +M]`!4!CFPHQ&K=UY"RJ/``\ZVBOF8+B`E(`````$```!,````,(`'3FD63;/: +MJ#HA?(Z[;UVD)"('`'@```!T`0$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``KDG"CB"P8PE``1/76\1/JL(%+X1$`I +M```<``!`!+'GZ"/Y7',2F4DWQ>WZQ>+T&@(%+X1$`I```<``!`!+'GZ"/Y7',2F4DWQ>WZ +MQ>+T&@IG-`U`9O?]<2`39=!;><3D2=.7#X_.LCBE>;YRB):0PN`4$,2ES2Z. +MG,A>"R*E^@C7Z*LT`:*CXBS:#+Z\0'D+!$TF'VT*H&J0CI:M9?Q`F=^L\^&N +M#Q.V?H8--C'6+/U:)J8TJC$Y5P^"\O88*0``)*B8MJ_9T$%LH?"R7.<+L:P, +MP=)I_2O[Y$(]`)/3%!3V*0``'```0`0"8I+(7#ZH^2;0_6%S#31YHTU!T@`` +M`!P``$`%4RT?Q,1`I5'RYF]*RB$7-9G`76U-$K=&HTH)``P!```,`0```@`` +M`$4``0A2E```0!$``,"H`0'`J`$"`?0!]`#T!]D&8E3T9T\!,L]&S!MZWY#@ +M+B`C"`````$```#L(P``T,;>ZT,0HADGK'PK92M(9,;97TVAGY0S_#6J86"Z +M^_O_".WA.SXE@K&`D,=:U_EN"2XE=`V;.:@_+X@&I=LIEAG8WTFN:XFJ[:GQ +M-I+8J!NIIEKH"@<"].MX6!;_B'46&Z'MHP&7]';`(IT'F'9?ZJ,/L'-+J5=2 +M\8M5P-TMX!&L65MIQ:4@;PI;0]2UI,459LE'ZI-P[H[C5G,%EDJD<\9JC9N@ +M//!A@.8@='1R@(`^WS3<^EWBH3^BU64-N.5;[-N$]U_RH`=>],Q<=/W7#**F +M,`21,S4SA]*D97HT9E7W^ERKA+G?>*Y1IC7&ZH5=(7FR)_I!:\'3UH);Y1U_ +MM3UY8H:\G+=@AT_&>;>GAR`%B0OE>,D!+'^FQM6&\SK>8-#4NB&'QFSO)6!R +M(#?!##/NX[<$%$DI98JX[7KB>8><\`0^>4BS8Y9#-IA#N' +M8OR7V>WSU)&"^Z6@.>@X,6F?#-/M?R)0"#L:UNPQK] +MTWQ#^KJO#9^.@G=%UPG=OK`2.ZE/*DM^0X"X@)"`````#````3"D``##>*J^-/K+&.7$GD`4K#N7`F>%J +MUQ,^9I6Q+4VU0F=_\G4=3<=$(=#B[IG^5DT2MT;LT@D`/`$``#P!```"```` +M10`!.%*<``!`$0``P*@!`<"H`0(!]`'T`20'"09B5/1G3P$RST;,&WK?D.`N +M("0(````!````1PA``$`*"O+J81>#K[IZ*JB.?:YM4/;GQW/JY8L]"Y^>Q=" +MMV6U8JI#=T^KF:24IZY&1P^L+J2,M"X7_^0@770V1_A03SN?#`EN`@(9+'D; +M[1GP-8!HD8''VYS=E]("/U+&VJ\VXDYGFU8LK."-2KR;O!`.[M^0X"X@)`@````%````_"$``.#>B[ATQ0[RA`,O1[N% +M^!Q'-:N3(%02]#")3SE(\C2=Y!PJ&+#Y'D5Q,''MTT02-&3Y'61"&ZJN*=ZW]I[5O4 +MVZM?U5HVW<4YP+X/;8SG;(-@F'!]7JN80W0,31*W1JSN"0#L````[`````(` +M``!%``#H4IX``$`1``#`J`$!P*@!`@'T`?0`U`:Y!F)4]&=/`3+/1LP;>M^0 +MX"X@)"`````$````S"$``+!#=ZWV:F?Y;:9YB_MI"#\MOFM2T[V/('M5@"U^ +M"L\^7YMVV#0F;-DJ14:W`X$/(V,&Q-%"-2,'^,`KR:MOUNCL!..V+GW2-0L+ +M^NL"#XT?'S!%PU)[H7@]5%M^0X"X@)"`````%````S"$``+"P +M<%_30.P0_6"A]UJ1Q_0B37\A%*?S&-N]?>F8JA"OG6MS.L8V7%\XLUFH4:-] +M"72A$`-%N#MK*/2';R8$J..V.'WHSJ%QN::QMZ^8/W.)`R,G?UI&3^Z?LN8]@L8&_.,<5E9Y-8#G1[SN(DK!U%KK31*W1F,P"@`\ +M`0``/`$```(```!%``$X4J```$`1``#`J`$!P*@!`@'T`?0!)`<)!F)4]&=/ +M`3+/1LP;>M^0X"X@)`@````&```!'"$``0`(,\'?GUNU'QZ"XD2B17B19MIQ +MK1:!"'G4KTG@,:0ZSE.TT@9G%.D_^D$M&&"B>[RTW2$*OQN[!$AV?&E1H#9Z +MSJ84*,?:#DI+CZXXYDJ2D;E@T(F?=:JJ'2%RFVRODZLLNU"6%J1G9]S'6UU+ +MXYA!I8IOFW5,SJ2ELTQZ0S$F:9&]R'IX^+<<_IU-D2SVU/A@.D_[YA:;VAV+ +M^"'[DE&@MZTL*Y8+TIK[)6,-80JSA+L"DLTFZ[F47@9NDQM<$0+67C%>%L;` +M7U]WGR/KR.\YG\-QW="6*:T^D45%$:UAO;L_XB]3._O],;1Q1O`*KX&9-V3] +MD)88_(VP7[A-$K=&8#P*`!P!```<`0```@```$4``1A2H0``0!$``,"H`0'` +MJ`$"`?0!]`$$!^D&8E3T9T\!,L]&S!MZWY#@+B`D"`````<```#\(0``X$&Z +MT[11UXM/A]*$W;O+@KMP:8D>CV,Y\M%#EF\2N1`]/`3@!+@PA3FYSPZC&PC9 +M5U8A.#K/JOM-EMJ#.BP.KA?;%U_*UX>C._A%3:*2;9.BRW*_AJB,;L3PKWS1 +M_]\1D;)GH.!;QR&4+_3M^41#-F,D\]'(I81^6/(34*]@GN\!8&5P5P++FOA+ +M/7-Q.3+7(I[QC'`(J,_T9-P!;G6=T&*)6=Z9>,?@7.AIP/"8'I5GY1BC9S;6 +MC4NDT(Y3QGVF0WPKL.GST?F1@8L([X%-O1M+"U`OC)KCPL\+1"E-$K=&CTP* +M`.P```#L`````@```$4``.A2H@``0!$``,"H`0'`J`$"`?0!]`#4!KD&8E3T +M9T\!,L]&S!MZWY#@+B`D(`````8```#,(0``L`A%:)()"Z]`6O1SGQ4<3TD, +M`*'MZ>JYQ*1=W`]?LA34/L=?;WC:3HP6^`E:4\6((P`R.ZX[/M5FS'XILU*7OP">M@XYBHG:02[;\ +MZ"ME9(?,="J\C]Q>ZAOY.P4X9._J:_%MD%"#>9$B$A +M.[MV6NZ$Z>!]WKFO'G5U3:=PQRD`J6P[1LY[C]A.TU-$R)&W\7*`DY$ORX;] +M"J:V*4J-1O)IOU*M#Y`9U?E^+DWO!_F,KZ,72ZF`$,2B%!A:)DLQ_(0M<]7+ +ME4F7PC>SVNG8Z'P.<8^R+:]7VX>AN75_#KXSJ4C(!73ES9:GWL#`T?VL;W%MIG[>B*W?Z. +MF+,[ED*>#B^!0T*J&ZC`CF36#2Q6V6%E'GQV>&X$>AJC#V!J9-MY5V3RO3'L +M79+C,P=7?BI431*W1H;*"@!<`0``7`$```(```!%``%84J4``$`1``#`J`$! +MP*@!`@'T`?0!1`M^0X"X@)"`````(```!/"$``2#$ +M`RP0,%PQ;'W:[Q'(+P?HJZ6#R@[N,AH.N)M4RHWFF2+O.^X)%U%BJ(67_WK*;/0C_M2W#^]M]\\LU-G4$`SA]X-GYAD=D'\WX +MW5I6F!_/L"A_F08_HJU++-K:5%TH0HN@6"+[(^.FR?`'O@'$.$A'8=;;6:$O +M#&JL\)'Z\>M^]UXQS4T2MT8*\@H`?````'P````"````10``>%*F``!`$0`` +MP*@!`<"H`0(!]`'T`&0&21`?"3IJ(9;]J(K4GC=F@B8N("4(`````````%PJ +M``!`8`2%>.[('1GB+%%CS[*9SJ;)!A?Q0>@>XRD6K5MYJF`H5:N`*I39)7HI +M/RNF;.H(+H^)5+$XKGPB2PO831*W1GO]"@!L````;`````(```!%``!H4J<` +M`$`1``#`J`$!P*@!`@'T`?0`5`8Y$!\).FHAEOVHBM2>-V:")BX@)2`````` +M````3````#".9_JE8/QQ^60%6+[1J75B$*CUF)E29[G>S\T*4081^&7M"9]? +MY2S@`.4>K4T2MT;6#0L`;````&P````"````10``:%*H``!`$0``P*@!`<"H +M`0(!]`'T`%0&.1`?"3IJ(9;]J(K4GC=F@B8N("4(`````0```$PJ```P9F6T +M\,O"^S#`(P30C+M/$K]$#1M`@Z=8EL879*@(S%#O+D\I-!\NOWOB34]-$K=& +M;QL+`&P```!L`````@```$4``&A2J0``0!$``,"H`0'`J`$"`?0!]`!4!CD0 +M'PDZ:B&6_:B*U)XW9H(F+B`E(`````$```!,````,#W.ZA^<:@4TBE1^UUD) +MO!6#R-"Y8&SK2V"DG8[K-<16J3,,LU\]M,]M-?[O31*W1H46#`"8`0``F`$` +M``(```!%``&44JH``$`1``#`J`$!P*@!`@'T`?0!@`=E9ZG8I]&S"^4````` +M`````"$@(@@````````!>"((`'@```!T`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``E$LTHT1FOA(';0(6+`%A[$^,/V%#H!NUC3DH)NA_J<69G0:E +M"LEJ[AP;@<5W!$^U-+;XX9A^`SG8V:)M]57)^_$"9WCD/BHMNEW!9UQ`$8?M +M<$50"Q5-GOB%L!AT*,OZ4LI*GC=BT3]A`H)CKB\`6C@YH#+'P8MUS78@?#V$ +M;N4I```D0MP5-'[UU;49CC<2\??>4;4&N[;M\7D'7*_W4-'5S.PI```<``!` +M!%%9ED>`^=RJ#$AYD`RF]3.=[N*E````'```0`5L--/0`W@:(4H/\,;`2*Y] +M,&IP:$T2MT97)@P`7````%P````"````10``6%*K``!`$0``P*@!`<"H`0(! +M]`'T`$0&*6>IV*?1LPOE```````````I("(@`````````#P````@``!`!@`` +M``%N?J7&'(V_#-67B,PO$]!U%JF-EDT2MT:S-@P`N`$``+@!```"````10`! +MM%*L``!`$0``P*@!`<"H`0(!]`'T`:`'A6>IV*?1LPOE```````````I("(( +M`````````9@A```@``!`!@````%N?J7&'(V_#-67B,PO$]!U%JF-EB(``'@` +M``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``E$LTHT1FOA(';0(6 +M+`%A[$^,/V%#H!NUC3DH)NA_J<69G0:E"LEJ[AP;@<5W!$^U-+;XX9A^`SG8 +MV:)M]57)^_$"9WCD/BHMNEW!9UQ`$8?M<$50"Q5-GOB%L!AT*,OZ4LI*GC=B +MT3]A`H)CKB\`6C@YH#+'P8MUS78@?#V$;N4I```D0MP5-'[UU;49CC<2\??> +M4;4&N[;M\7D'7*_W4-'5S.PI```<``!`!%%9ED>`^=RJ#$AYD`RF]3.=[N*E +M````'```0`5L--/0`W@:(4H/\,;`2*Y],&IP:$T2MT:Z6@P`4`$``%`!```" +M````10`!3%*M``!`$0``P*@!`<"H`0(!]`'T`3@''6>IV*?1LPOE+:8JH($T +M#=HA("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@`` +M`@,```@#```"````"`0```(H``"(``(``!WC8X<+5V(\-J6"&LAH2-;"A.MX +M%S%;!AGNJ"2@T%1\QU_J3XH:*5'(U-GC(.@@PKWQ[YC;^-9Y76'65$YC`XLL +M16\.`-N);@`7\DT(9J:'WC]>!\K9(S68`WH[.@DLC"KJ*."B^`7QB:UP"Q@^ +MJH3KK#(Y5<^M@8F=;AO=0D$"*0``)#Y3!QV4KGG+F*)DB%1@:X4N-"D:SX-( +M[CLA@RX,:M[/*0``'```0`2/^I9=YS:''30K47&7[/W!LY^%-$K=&18D,``P!```,`0```@```$4``0A2 +MK@``0!$``,"H`0'`J`$"`?0!]`#T!]EGJ=BGT;,+Y2VF*J"!-`W:+B`C"``` +M``$```#L(P``T(7$HFXICM,:EE;X-9O?FY*U\.!IS1_,$X+A9\G/$#1-( +MY[ZY6QYDLK!,T(4RLF%@@D]-62TFV/WR/,1,B9%L$NUHS6N]9(:(XGE*OLG3 +M`"AH[^XO06>8&=LE=?'M\!`/$[%PHO^*'IC!=O`]PF29G6!^UUU._BKW42XL($T2MT;FH0P`O``` +M`+P````"````10``N%*O``!`$0``P*@!`<"H`0(!]`'T`*0&B6>IV*?1LPOE +M+:8JH($T#=HN(",@`````0```)PD``"`LBZ#SA[92Z(]ZY^7:LP)LN?QC#!( +M-&OS#I8%<*I@TF9,!74PN8'B!6@&Y5Z631QI03TI6!AKQWJQ`"NNYU" +MCM!RS?BOE+%G`KF`2$^>//J[6@M!DT2MT;9P`P`'`$``!P!```"````10`!&%*P``!`$0`` +MP*@!`<"H`0(!]`'T`00'Z6>IV*?1LPOE+:8JH($T#=HN("0(`````@```/PA +M``#@ED@,.4(W0&HLS`Y=7B7*UP^-RV1 +MZIE;,O"`],\&X`':UJV]SLJ\6P_RY=^T[Y)GI\.,BW6$ZK#4M']21`K-STT2 +MMT;-R0P`_````/P````"````10``^%*Q``!`$0``P*@!`<"H`0(!]`'T`.0& +MR6>IV*?1LPOE+:8JH($T#=HN("0(`````P```-PA``#`(?A/QCEW`+<0$2;H +MIF->56`=1'.NH*6-8X.BGZ:Q#PY4.($P>N$3.5T_"R"I\#^:)TG!O3#UI*1( +MTF-&,QC;%MOQ`2[_2EIN[-7WMP=D5X7MR*)Q#C205<4H;VK->'V*VL&T4/7O +MA!8Q9?N8N?1(I[V4V(J]+B1BZG2DWCU+1=#,T+H8%"K15R$V>1Y,E;!1/>W2 +MID>SO*T,QK[;>ZIV*?1LPOE+:8JH($T#=HN("0(```` +M!````1PA``$`GY?O7;Q7Y$HZ^S'XG>`BR>>E;ZEKDFB_I;[(]D,MU0['5^GG +M0T/*:)EI:302XC5$SW?E#;2JD@V%_K9@7K@79W_'!?BI&B2-,A[NUSM])((] +M][I%N&%U@_57#+0K!KINX1R)L9`3UYR<65B]'E\3LE!4>`E/!W*1,93[)O +M^_9^S$N4<&KN(?CV'32$K'FK2V1C)DT.YDL$0+U3'QH%7 +M`8T@/L%2XKB]V5+3L@(4EUH.=,`O/DORW?[Z9=$0OM#?\\E2HD32,(SA>Q(# +M-6[#QOE)V]<0`7GI\^AK_39`IV7Q31*W1GPL#0#L````[`````(```!%``#H +M4K8``$`1``#`J`$!P*@!`@'T`?0`U`:Y9ZG8I]&S"^4MIBJ@@30-VBX@)"`` +M```$````S"$``+!#?@[3%&N<7KHE4T@0C&T./[;R3[Z[1B3?JI`7E]$]=WKR +M6["(W +M,\Y18'Q06.WT-UR@E`O6T$62ZU'])[HR(C`U[:'G/Q:L>AF9+31E)A[6*:1& +MGJ2Y#7;K#O\B"-NXL!'F-:!!N_:`C+4(%+(WV&D,-4YK"JD"638"T3L1\7); +MRF#F31*W1C=/#0#L````[`````(```!%``#H4K<``$`1``#`J`$!P*@!`@'T +M`?0`U`:Y9ZG8I]&S"^4MIBJ@@30-VBX@)"`````%````S"$``+"K730T%6_< +M4EW,%[>?/)[`4K[P-^D"^;UOK)[]*S;K>"1!RFQ7Q/ +M#S)@E9Z"';P'L."J\"D;)+DIG]3:0.BB5XC(WT$YTHSOQ*<2_8(D,C\O@P[6 +MGJK):5E_CZ_)'UQLLP.HRXU43D?1H*<4GOT,!DLY31*W1G!L#0`\`0``/`$` +M``(```!%``$X4K@``$`1``#`J`$!P*@!`@'T`?0!)`<)9ZG8I]&S"^4MIBJ@ +M@30-VBX@)`@````&```!'"$``0#YZ^IR>Z7??]GX&&PAH=K,H8+NO8)NBE^B +M:F:TX<'D'##R_5`%1!TBK%55:V=]("PO1[9`@%^F(<="S5[2YOA5\76PBS1Q +M"!5)2+4P(-/F1GK$Z;3H(Z;B'?I-L+K_N+=JPK)BJI8)_?F(DFWMK>*[GFPG +M'X)JVL@\S7E[L#BM-,1"PO8("8)O8C^5JU!0)&+]4K\3UNP@WM&WR"\FQXQJQA8/T1&)&KI(Z:Y9\( +M/Q.O"GA:`8]+BA*Y.7HRP>_84@8;N'/@G/@&:R7TLC+H2D0@<*A'\$=DN`&%N#9$F@5 +MX87_H4J(47-CZKW9!PS2?"E:LLZI$_PI$&IZ3TYJ9?^?>$/.!DA+T5TKO][- +MIB5WWO"/0]LW4,2[H_PDQ/8A%\BMK]F"7"Z`KX?<>@W+"EA%RN?$XA0N^+P5 +M$*PB^M5W)""W#Y?.VM5??%[KC+@[RVE`=H_X:EXU*9M-$K=&FH<-`.P```#L +M`````@```$4``.A2N@``0!$``,"H`0'`J`$"`?0!]`#4!KEGJ=BGT;,+Y2VF +M*J"!-`W:+B`D(`````8```#,(0``L`Y/95LU4^*9#[=[D-T.2H>39@,:,X@] +MVNV"<+T[H]_=_&.?PPTR9#AI@5`&EZF$LOR%V>?JK6ZP\%L7^"16O7DR\>=N-JK:$"JUZKHH:-0DRS+Y*ZPR1CNK3AMX7QX) +MX7*O.8J#)VN2P;:I!3%-$K=&G*L-`.P```#L`````@```$4``.A2NP``0!$` +M`,"H`0'`J`$"`?0!]`#4!KEGJ=BGT;,+Y2VF*J"!-`W:+B`D(`````<```#, +M(0``L!DBMDFG3#T$"I!R)VR?[D40[$8\2(Y5LOQ>NLX2(WH3\/I6QGX6NQ8=F+>+*QA>V +MK-#>5A@IIRZ)A0_<]!3)'\*#;"*&O/:S<8=[@'GDQV(GG%[D8)]HOZ](JA9S +M.(E\4Z"43[5G/*Y-$K=& +MGM(-`(P!``",`0```@```$4``8A2O```0!$``,"H`0'`J`$"`?0!]`%T!UEG +MJ=BGT;,+Y2VF*J"!-`W:+B`D"`````@```%L(0`!4(D$R4+*.W0DPE.]^4#\ +M%.W[=R[>MCWXD6O!`^_,B;UB7,&1IQU#!CC+][O% +M>0V8T_,)*2E3C\T!(D`OD3/K=+-BW?>2).`]2,+YDS\,1R14)N-;2\V`5I3; +MU"^!(%)&MMUIT>`]J?;S<2%\=">;4XR-4OADF&775BD*:D[4O1A9,Q;<@O +M@D%PX"@*!M(R'UK*[:TI[*:*J5W+):YR96G +MG^D0:\LVR$R@$IP!#^NCW<+EZ>OUGIR8W`-5"`%1A;*,W5A%3N +MMO0831*W1D\'#@!<`0``7`$```(```!%``%84KT``$`1``#`J`$!P*@!`@'T +M`?0!1`3]I<``N+X!VBI]O1(9,+[E9%'3S.?@UG8 +M`QS"_3IWE>*C<1E(,-OL'`,X&RBRLI8-BI==#0%+7Z\YD'B6DLQJXL"IZ=*[ +M5E"^@AX;)YXVDC5[P=3X>GJPW8IK!$'83!EX#B\OO2:O38C5R[O]DK)-M]Y? +M659++"&R7OW'ZBFK50%=9M=@G#"G(,ZH,A$EH$*,^*TKB1M`>)\](`FI`F:7 +M;.`'2LB&:S!I)83L9<*[$[^AX[%H)B7(B7-FL=-^L_VG!$`_KG%6(GYM`+FV +M1*Y(S\QWS&P0??!?U;/Y.W!MG@VD=Y3I`\#%9 +MR<&L;::=&DT2MT86+PX`?````'P````"````10``>%*^``!`$0``P*@!`<"H +M`0(!]`'T`&0&264*_2PBK]-*DU3A+.YB3B4N("4(`````````%PJ``!`#+`) +M-V)8DY&(?2&.OY&!A64?AP;QQB\O?&5^K%V>SJ*!,B)Y`;1^P"$QGBQX]XMR +MAUBLNCCN>A$%"ZZQ31*W1M$Z#@!L````;`````(```!%``!H4K\``$`1``#` +MJ`$!P*@!`@'T`?0`5`8Y90K]+"*OTTJ35.$L[F).)2X@)2``````````3``` +M`#":]>JZL-3Y-I;D=;KX*+:$DE'N'K5:E'.JQ>&EDGH^,!!EA0LID6^`'/1VG8%-$K=&XU8.`&P` +M``!L`````@```$4``&A2P0``0!$``,"H`0'`J`$"`?0!]`!4!CEE"OTL(J_3 +M2I-4X2SN8DXE+B`E(`````$```!,````,"WR4V)$;.D*D$9:9&\.G:'&4[V> +M$R"()`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``_?'>:;6P2)$S]9,?792$7`XMBOIV+H`8XV&5UT-HQ/J/ZTT$%8SJYJRI +M44?JN6J!_&R!FGT&AZ@67QPV^.&`]ELG-!*FNQ<>0ITYD?(07S(_CW&F57"+ +M\SV`XJ/P7(@#[8[=)W%J/\H]Z.5DUWT@#SDT7S3)M_D&I>[^)V:**WDI```D +M6]$LS#M^F"=5)'KVD6@_A>^AN*WE_1KF%[=HHN>W]Y(I```<``!`!(>/+=0J +M&T1]$LM[-4]=1^DZN]4X2 +MMT9H(0``7````%P````"````10``6%+#``!`$0``P*@!`<"H`0(!]`'T`$0& +M*=&12K2FN,\\7#.NRT&`QX)PW+CY4X2MT9A,0``N`$``+@!```"````10`!M%+$``!` +M$0``P*@!`<"H`0(!]`'T`:`'A=&12K2FN,\\7#.NRT&`QX)PW+CY2(``'@```!T`0$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``_?'>:;6P2)$S]9,?792$7`XM +MBOIV+H`8XV&5UT-HQ/J/ZTT$%8SJYJRI44?JN6J!_&R!FGT&AZ@67QPV^.&` +M]ELG-!*FNQ<>0ITYD?(07S(_CW&F57"+\SV`XJ/P7(@#[8[=)W%J/\H]Z.5D +MUWT@#SDT7S3)M_D&I>[^)V:**WDI```D6]$LS#M^F"=5)'KVD6@_A>^AN*WE +M_1KF%[=HHN>W]Y(I```<``!`!(>/+=0J&T1]$LM[-4]=1^DZN]4X2MT;T5@``4`$``%`!```"````10`! +M3%+%``!`$0``P*@!`<"H`0(!]`'T`3@''=&12K2FNG;:J4FP4=($,5::P=XS#T)58A>VF")@I)P'"5MW8C%3&>ICPR?>TY0>'B96C/X9=(&T)2S4+".WJ^%.$K=&7(0```P!```,`0```@```$4``0A2Q@``0!$` +M`,"H`0'`J`$"`?0!]`#T!]G1D4JTIKG-%!DL4;8,EE,"+B`C"`````$```#L +M(P``T`@:$VI)5+0*@G/MQNJJIYF^W?#7+\NURIKI)NP&S\HW<:O'P\4*J6G*2^[H1/1W:ORO[K +M$&%!\[`ZSX/#B\7`\S'R8R1JDK+_C/XDS!O8Y*K36X/P)[?4NK#)V5W+#3BB +MKD@FIS1"Z)D0MVH/)_E!V00HN.8_,;+POLN4LV+(^WT-`]<`%40=;DDN.IF? +M=7.C0=V-QQS5PE1=B1;-M.J9;SGN.1^4VO+-34X2MT:[G0``O````+P````" +M````10``N%+'``!`$0``P*@!`<"H`0(!]`'T`*0&B=&12K2FND8UJ] +MM=I^I]_R),:Z=&50QBQ@=S=12T2(I#;EY!L!RHW9#J60>/Z,>[MUF]@C'VF^ +MT4J/$]:'2>1$FJ9:=W^LV5&8C`8_)@A=F;,[=54OZ7VX^XA*6XJEY#SB2F8` +ML@.@7M^PX?>)-501M[#]TW=6_AXV:Q2?J0W:FJ/`2M,I9:SOI!/8!\>^(CK/ +M,5H0LUS%-WO76%^7#;P?[.?2IA?G`$U,-DG.R])L2P.$5K@>G$X2MT:3R0`` +M_````/P````"````10``^%+)``!`$0``P*@!`<"H`0(!]`'T`.0&R=&12K2F +MN`,FGKHXD%,42AX*6C6G(ZGRMM1#0PJ-%1VN9#+U2D +M9BI/XCHI7*^X"&0`M.6"YS8"`L7M,_P*GQI\S%P?:J&^@&2>CT@DJ(D?7/N` +M\T`,+AHP$_(H3THW'5QBY\BR*&?C)%'E(JRND%+K&'HBK><0EWJ1)(YS-1WH +MY+DG6&!QPVA^O9W-QD&H5CIV7LSTIIZJM"4Q&+L0Y1;(_HQ.$K=&]-,``&P` +M``!L`````@```$4``&A2R@``0!$``,"H`0'`J`$"`?0!]`!4!CG1D4JTIKG- +M%!DL4;8,EE,"+B`D(`````(```!,*0``,%PJ^K.HON@V+F=M*[]M+18!S)6> +ML,CQOE\9-G*](]5BQ*^CHEN4T4#IE?3Y3A*W1EGO``!L````;`````(```!% +M``!H4LL``$`1``#`J`$!P*@!`@'T`?0`5`8YT9%*M*:YS109+%&V#)93`BX@ +M)"`````#````3"D``#`1_UT1%#^1&SC8V(!SN+;?=2`\I#I=S/=,90/9;;&T +MJ;Y;BHJSCT7Y7&,"VDX2MT:6"@$`/`$``#P!```"````10`!.%+,``!`$0`` +MP*@!`<"H`0(!]`'T`20'"=&12K2FN5X$=A:CL@"Y7]6\"CV$*Y;=QK=$ +MB;\G*XNG6R]+MX'4=P>!0SHD(=QN_>/E.Q/]Q#_-]3-%BA<-)8L#JIDBG?^9 +MA0L0[;@^/70Z#-M.L"S>,H>P*]KHKLEN@&X]^;\#5"=-'/`I)&B*-7+K-P%N +MU`"28HN:L,+QI9J$Y1RF7J3""S:(@2,)6LA]5TBMP0WY`!E1&U,49KH1XU3F +MEI_/VW?/Z(]105U`KT@XE&1&F82*P[*OG8%31&M$3A*W1GP6`0`<`0``'`$` +M``(```!%``$84LT``$`1``#`J`$!P*@!`@'T`?0!!`?IT9%*M*:YS109+%&V +M#)93`BX@)`@````%````_"$``.#B+%KU.4?MO%H+HI?ALMK8;3QER^Y&XN5! +MJG3`[GR)L[6;8;EN2&+(/.SJVW0/:>M+*!B`QW3$ROQP%/[,\&OU::O0"*@E +MG)8M$1Z8=&?'=CNZNE>88A8*YW8JG\=BC<%8Y+\O8*D'0$/MD9-=U$'%,3+E\O-7'.H(=/WN'#>I_H\AV"3D(_'1"WUA:,LP_KJS4]?EE[:?3A*W1LDF`0#L````[`````(```!%``#H4LX``$`1 +M``#`J`$!P*@!`@'T`?0`U`:YT9%*M*:YS109+%&V#)93`BX@)"`````$```` +MS"$``+!:`?8_>/]KYJTHP(VO>!F0W$/=(L@!,MBR>/-%\^.K$ +M6QMOF;[\H?\O$.W?W_VFTLW[8I]W=$GI.L"P9.MKEB*PD@J$F83+T,Q(]?R>0%YY091)/D!P8GG;Y=+5(1N@)6<^UB[LXI(S$P\<H& +M/1!6?WG.'!L!T<4;15P4U[D.J[@T1H4M[`J$L?+X@Q'!_0KCWYR^KD@8 +M;K*HPY=`(A%Z5I,-OQ@H5LP=+X##JQ-SV7$09:@(>4BN1)GL5W7\*NL]9(!, +MZO#>48VU6\,RLGSYM!Y?HJ`RZBLWQ'$J.#_8T(\:3!E6&M_5J`3US>3U[:.+ +MF?A_=/U-R='K0SW.%JD7X_Z&X>KN57!#UH4]?UG#1AMDFS7!.$K=& +M"70!`!P!```<`0```@```$4``1A2T0``0!$``,"H`0'`J`$"`?0!]`$$!^G1 +MD4JTIKG-%!DL4;8,EE,"+B`D"`````<```#\(0``X'GE#GY7UZU("%%AW&1+ +M2Z+QO/+Z_'F87L)*0!!!T,+8X2J#GWL/@]<0.(ZON]`^$H=7!,#A(I57BYG. +M-[M2.C93^!3'6@PVK(/*49V@=H&$FH0:\?D0!#]XVYM?A-)[WN:(WR[E3C8L +MZM'5`!26M78L+])VIV[%S]EF08V-QWAFQ7DO!!9<.$VO`#;Z]7:&LX13=X(_ +MU]7R6Y6IM(Q%T12S;B7GF$B9Y^7%AXIL@NP?Q,B4]^7R4"30O+%)-2>W[RR`B\&:)"+Y4GT`0:[I!PV!1((U0S;Y@0.E?(/'T>'(>^(6%%% +M,]-QBX]L*B!^14NX$ZO#?!MI=65TC2S\]>6J2DBV;M71D58#0GE6W/[\!"FO +M6AN`_%Z";5:3%;=$^T].O@#F7(?EZ_DA\*$\>CN:XC,-M'JCVYNE6XK +MP0(L5./A=+!$_]H<6=I<5?DFJ,Z`&O<])-!'<=Z'XBI9I0K``0[["R11J0<$ +M_M1+T['38G0@Z7GOA>&8&O(1$Z`+';YT\\CF7-17_$T_27%:#RO_CFYF#G.( +MN7C6\V!3H92F/-?TPH7T<\3H721)P +M#/H"%@^3T]).Y79:*XF)P%$"J"CA.'L[4_G,1@929%=V[)D]+T]DL+TT>^&^ +M/L.:==C*#/]P_6$%D[XOF?.A\X5/8(*@@S#R>5QP4"DOI;(T6A;^HM,;GGPY +M&:DPSDAC'INECW*_;\'"YQS,CCGR`&52!NKT.WDP#*+R%YN]&-D%-LA4J7`? +MKA]**;*+,.&$"8;L+XM+L:L^FOH":I76GJM(I@+#E7[#S`#Y,0H1C6Z#DJU' +M(;)MF&`Z`+@7C&MY],R(V'C)CJ!.['3K(UD);MQ!"O\5I`[\%,$^2:%`.'+$ +M'*!BE5KHWP1;^<)\*?[>&?19/K1Z=_TGSKH;]RESA'<>8M:%#I#_$P;H8E:[DL3BH"3A*W +M1@4!`@!<`0``7`$```(```!%``%84M4``$`1``#`J`$!P*@!`@'T`?0!1`@DI7T:Y%N1M2"!W'O.^O$NI!#-VNQ6:2C;BC:H'C]"]:S;VJ +M!TX2MT98*0(`?````'P````"````10``>%+6``!`$0``P*@!`<"H`0(!]`'T +M`&0&20(+W\]\E\181:\9QS.;"KDN("4(`````````%PJ``!`W`1MB4.*.CVA +M`TP0N$;C=DH6,:15M*@^:]NXYZV-]G,0,E)KOY#(HLGB#<[)D\TX2MT:Q +M0P(`;````&P````"````10``:%+8``!`$0``P*@!`<"H`0(!]`'T`%0&.0(+ +MW\]\E\181:\9QS.;"KDN("4(`````0```$PJ```P*QD00_*QH8(#V0_'L%.# +MMLLO/`]&5CCXKSF_=W9(PFAMG90/:6;?B3K/Z)-.$K=&!%$"`&P```!L```` +M`@```$4``&A2V0``0!$``,"H`0'`J`$"`?0!]`!4!CD""]_/?)?$6$6O&<Z'F!0``````````"$@(@@````` +M```!>"+_`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``08)# +M@W,<(:9Z@1+S.;^&!H?'8;^,,0,Z["/VO)4BWVJJ+'L<%9$BIL:C/OV@C9M\ +M2_U:IS80!UJX("_59^JF'=A/AZAN,+?!K0K;X@28"A/^VJ":2?105THVS5<> +MF/&SC`F00I6]Z:8:G.>2'#[&_+)H^N_8"!*:J:L5`V:<0F,I```D4(-WDDUC +M1,R504V:)7#5%+K283O-.D9S]?I<..7OFW@I```<``!`!"6+LC:L[B:#!X<& +MF=RL3P4+^Y,:````'```0`65`/2DH1)4,W[J(1$7I25#EIT)\TX2MT:K60,` +M7````%P````"````10``6%+;``!`$0``P*@!`<"H`0(!]`'T`$0&*2]TRWWN +MAY@4```````````I("(@`````````#P````@``!`!@````'9-#MEL-"-+#_! +M,Q?C7-&H@+6A24X2MT:W:0,`N`$``+@!```"````10`!M%+<``!`$0``P*@! +M`<"H`0(!]`'T`:`'A2]TRWWNAY@4```````````I("((`````````9@A```@ +M``!`!@````'9-#MEL-"-+#_!,Q?C7-&H@+6A22(``'@```!T`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``08)#@W,<(:9Z@1+S.;^&!H?'8;^,,0,Z +M["/VO)4BWVJJ+'L<%9$BIL:C/OV@C9M\2_U:IS80!UJX("_59^JF'=A/AZAN +M,+?!K0K;X@28"A/^VJ":2?105THVS5<>F/&SC`F00I6]Z:8:G.>2'#[&_+)H +M^N_8"!*:J:L5`V:<0F,I```D4(-WDDUC1,R504V:)7#5%+K283O-.D9S]?I< +M..7OFW@I```<``!`!"6+LC:L[B:#!X<&F=RL3P4+^Y,:````'```0`65`/2D +MH1)4,W[J(1$7I25#EIT)\TX2MT9XC0,`4`$``%`!```"````10`!3%+=``!` +M$0``P*@!`<"H`0(!]`'T`3@''2]TRWWNAY@4-U;5GL8>7$8A("(@```````` +M`3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"```` +M"`0```(H``"(``(``'-06H673!]M5S?/VH*UN=.=TM[;FE8ZN$O'`VM1<4'H +M]KZ3OFTO&$\19"9+EU@2.N1!F_+VVJ17M,:I.YJ)G[=;(PW7'[K7GL?5D%%U +M>!"'2U&;C'6';U!PA4$J +M8UV7Q4Q=('C+2G%DY4IYQ*0`` +M'```0`0%D+-0%8M=1GR:0V5I(0U/;WC*80```!P``$`%X9X^Z3>:!;!M/0KA`_V;Y.$K=&H[P#``P!```,`0```@```$4``0A2W@``0!$``,"H`0'` +MJ`$"`?0!]`#T!]DO=,M][H>8%#=6U9[&'EQ&+B`C"`````$```#L(P``T'@Q +MOB_ZC+-8+.^V;Z?-47X3FT@[Q(C%4R(V;":OZBG`9[$POU]`O`_F#9.K"87-F./9)O!0F) +M1.+MQO;.UVO,_Y(AH4EJ:!+&#%,8=D$@HE]Z]-EXR(H3?GP89^S`U1A43`GU +M_=E3\_!TP.ET^/"MM;,GUQ.DZ`\KLDX2MT9WU0,`O````+P````"````10`` +MN%+?``!`$0``P*@!`<"H`0(!]`'T`*0&B2]TRWWNAY@4-U;5GL8>7$8N(",@ +M`````0```)PD``"`6&Y!ME*>GC&CGH)XOUG@:_(@`G15BC%ONL"%AV;-:O=% +M9D?8YHACNHI0;:;_!G1(G\"]).VG>8=6N'V(6<1]V`!3DG?O$K+@9UYZ6)`% +MTG?/6D^MZ!2T9/S"_I9OV^C)-H<(JIX1A?GA=T*<1`\.8CM?4&"0+&:J%H?X +M)DX2MT9J]`,`'`$``!P!```"````10`!&%+@``!`$0``P*@!`<"H`0(!]`'T +M`00'Z2]TRWWNAY@4-U;5GL8>7$8N("0(`````@```/PA``#@C-3#<7OOK@.L +MVPA#[G.CCI=Y'*I=KK#<_QPT+T4R;T[OS:$:J(=I=;IEWM*35K\.$&@E'-&) +MXO)OL;[R"2GK,:=PPP*I@KE?M%K_%,P8Z/K7_18[C+(-.+2UJ[-'-&A/Y`X[ +MY9-(IFSP)%=;1V?A36].B94NZ5X/5D)!PH4RPVYHIKF^C:HKI`AO2G)71,V3 +MM;QA?(A-@8\_%%U/VW@,LAX51#^>F6?<-^+T)[\#44FQ>/+D6F4A\[+*Q-FM +M^#VLWL'.PEB1\L*5%MSBKL=ZGZ7$8N("0(`````P```-PA``#`5W^4])D40YFD)E:L'9*.R@IHQFOWF +M(D3XQ@[3[$HGY"2/`X>.NL+L^38=/CFKT7+BC:U*=Z9[2%FM,ML@;"1U=4S\ +M@WLW<"8AH,O[TZE=[`R^4SE?O08S>*/X4"A1]TUNZF'XP%'\.0QIGT'H!K9E +MGBC5ZJVF,?ZU)9_L*_A%3<)/"Y.^"A9;6O]9T`CS0]:(5P_GK$2'7V"Z')88 +M"F!L7XG2"Z%4,21[7.I)]#N'5L;I?ZEO56B$8;-.$K=&60H$`&P```!L```` +M`@```$4``&A2X@``0!$``,"H`0'`J`$"`?0!]`!4!CDO=,M][H>8%#=6U9[& +M'EQ&+B`D(`````(```!,*0``,!!2W!A&XI\Z'F!0W5M6>QAY<1BX@)"`````# +M````3"D``#!#J&[7$8N("0(````!````1PA``$`KR>2 +M_M)="[VNZG_N!7O:QZU;@Y*!6QA[6L)3"HJ^"(LWNJ+AX+5(BC3+YBK8&4!\ +MY[7*V$%OW8`R!52M=%($2SBA+C_D(H.DD3RWFT(RMP2B.^,1@F!K53@+NUKJ>+7<34Q3>D+S`/53C2QRG)UY]-!+8'.]4^PUH'7=OW",MGG\'POF>WTSN,:!WL$YIT3B)V\J1L_M +M<@]:,?,=$=.L*S6M0I`!V(P&`>)!(G0D3A*W1BI-!``<`0``'`$```(```!% +M``$84N4``$`1``#`J`$!P*@!`@'T`?0!!`?I+W3+?>Z'F!0W5M6>QAY<1BX@ +M)`@````%````_"$``.#R5I7;I,A7G>;/L#+UE"*+./A*CGCU*D4FH%O+NL/T +M@)L)N(S-/;#G1?V%"TQX>>+T!OP.LFYQ#)[RC;,<&(F<^ +MR_H3[.M;4OR!97R)E+\>,V\-N;8X%&$S7'C6K!.8FE$=;)I,STFTT"&6=F*, +MD(WW6U_W_J@M3A*W1EUZ'F!0W5M6>QAY<1BX@)"`````$````S"$``+"M +MB#&:RKH3=\Y[VCVGM*??X*%@FN1[`G:@@!75`IX@W&WL+==X4%=92`69<[J2 +MV\V+/`YW+8"O1IHSN.J&#'9E97ZK6*;++H^/`P?R)PKI]Q:_.+)TS26;4-@W +M?8#RKE2*NWT>;:ANCX/7O"I4`0&F#A.(@_F;`AHG_[74MM%:\>EG54\H9IG0 +MR;XN@7Y^N/1B][F*!PK)#940^DZKZSJ6XH2`$-;2'SDAWGG&3A*W1BU_!`#L +M````[`````(```!%``#H4N<``$`1``#`J`$!P*@!`@'T`?0`U`:Y+W3+?>Z' +MF!0W5M6>QAY<1BX@)"`````%````S"$``+!CES,#OD+7P[1E6`IU>DM/Z7

'I(&7VY_[&SS_V]>53F$1&)TZWBSO_B&[?J4TW)(A%QR1+ +MI60FEO9$">9E2$D`-!D"8FM$3A*W1K2Z'F!0W5M6>QAY<1BX@)`@````& +M```!'"$``0#QZB[>WJ,J`2G-5MN_[X\3,?720208(!.&CIR"VP<`U69F_V!4 +M"_)<&9Y>5J1"#U/\RG>:T71R/,2&,Z4\Z?D+IR[I(=WO[7TIT3FE/CNB$?'L +M-'&*K!$FN&$MF*4^`K%T!NN>U:F-TV^(TI><9H1>E+G]@6AH2RACEA:'2GYU +M:Y++[6RE44=!$YU:[DISODO<-?%'+Q.]&K\O@U1B_;- +M60%(!$/*J==FJ!-B/.P,T)B0P)%H!S73-`EZ3H]L:NMY=:=6^6^&@%2#O):+ +M#AJZ`7M.(R#-T*!RUD,63\O##S"!3CGQK&!6J1ZY-3(OQQQ.$K=&X:@$`!P! +M```<`0```@```$4``1A2Z0``0!$``,"H`0'`J`$"`?0!]`$$!^DO=,M][H>8 +M%#=6U9[&'EQ&+B`D"`````<```#\(0``X(/CQ[IQFPOA*JWZL0F<>%=:@`%< +M8(F1:5IJR6R"6$F=!=K@YO+/]]*R98DYI"II]LB]4FU^)@_\`UK'^SH&70CDKGFIL8+64! +M9%6P%J46;2P`\'S*]/Q[A@7QO8=2H0#1#TX-+'7;=SC)XY>%9?]["'%*ZQS0 +M^5`-)`.T58.H;!M63N)A@H7ZK1V<^I%(FRF,5CEH7@KRD&Q8%#=6U9[&'EQ&+B`D(``` +M``8```#,(0``L-;$NTVUC;;>P2!0!@)+VC#?;S*3OSM9Z5BJ2X[)&>ZB5)?7 +MKE3$35OJ!ZX+R'ZDDC]L6AD!P>SAY?Y8F8>(U6J:P^*=E'[-4!F_HP#W(YAQ +M]85'+P`&(7!`+-!$/0V#,@MH[DRB@VC*(6JY;@)&GMGYMB"4`'NW/,+-VMU_ +M'<,^M`\VLC$48OS=LF?M'02KD`GRQ94*S*+FH)>(ED;@I(/F?^3&I+I;1;ML +M!X).$K=&I-H$`.P```#L`````@```$4``.A2ZP``0!$``,"H`0'`J`$"`?0! +M]`#4!KDO=,M][H>8%#=6U9[&'EQ&+B`D(`````<```#,(0``L#TEHY529W!1 +M][]\HS.$:@$&7`OJ]0#IL4YNG<;WUI+/\9%[)S(@\*Q-%XM]6)A\\W1F:W`. +M%S\L#.OYY;O7>MIR71C#05.$K=&K0$%`(P!``",`0`` +M`@```$4``8A2[```0!$``,"H`0'`J`$"`?0!]`%T!UDO=,M][H>8%#=6U9[& +M'EQ&+B`D"`````@```%L(0`!4%X-\?O1!Z/X=+^V.3DLU!);>W[:;B=V[FIM +M07R6()K;'VW-:[2`+A(?@3Y\3B94N#F\&.\LB1G$))OJQ*1T):0:MGE1_=RZ +M:VR]-V2C!E2`!X-SK]R?[9<2BRE4LY>$).!K:U>`Q/N_UA'?:!I.ZO5+N2=H +MG&;2_JPFF.E8%*5'RDB:_/1@';:578(""FTUOHF%I-C1L;`WSFY^/_UUOQ +MWQ@Y9K)V-(AF9DIZ!T&I_6.VDJ\P#G"I"Z=K?XN2WH_^L7T/3A*W1I@V!0!< +M`0``7`$```(```!%``%84NT``$`1``#`J`$!P*@!`@'T`?0!1`Z' +MF!0W5M6>QAY<1BX@)"`````(```!/"$``2"]8#P](!B9L='E>)TK:W+L!6.5 +MP#0$D&KY*1S.]C(Y"XCN2BT9L-:XW`WCJ@BWE!9V-5OHB$W/?6FSF?)C3C.` +M'NDBM)\Q!R.M#V]4)'; +M2_:.N-T0^PJK[()<+VH_=:>^@;=Z.`4/<,$J=,*URC-"FQ%S^O@DJ)=PS%;1 +M4^T&6RB_&]/!.R(=..C92[9S(A,4U^UM@:NK0Q&H'XU7W#YA'Y@/=L6YHJ.% +MW:&,5U_^QOR%+N``!`$0``P*@!`<"H`0(!]`'T`&0&2=(1 +M-^!C<@R0F[IM1/=5.=,N("4(`````````%PJ``!`WF1L/FT"P9RSO)&N)(Q: +M33*>3GG2+R1>CTWV:F[E_R:1,=5*J#JT=,:]0+-?Z@A--9/G5)>HHF!CV-RE +M3A*W1OYH!0!L````;`````(```!%``!H4N\``$`1``#`J`$!P*@!`@'T`?0` +M5`8YTA$WX&-R#)";NFU$]U4YTRX@)2``````````3````#"8+)J[HD?MXP;O +MQ(M]JQW+ICCD\AM+^9YNYIW6_H<>W1PQE&4QL-9=+--_HDX2MT;O=P4`;``` +M`&P````"````10``:%+P``!`$0``P*@!`<"H`0(!]`'T`%0&.=(1-^!C<@R0 +MF[IM1/=5.=,N("4(`````0```$PJ```P5CM,$.V8N_@D;^$<4=(Z12MA\`-4 +M1/TKHU?_6!95EZ!ZFIP-#-V`0DQ,EZ].$K=&3(4%`&P```!L`````@```$4` +M`&A2\0``0!$``,"H`0'`J`$"`?0!]`!4!CG2$3?@8W(,D)NZ;43W53G3+B`E +M(`````$```!,````,$#L$Z#)Y3OCB+GE+A)2"$01Y#^2G<81ZV".L>T.DTS2 +M3A-*'0W1NSC>)1"*` +M`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``4<-@VXT+;$,% +M3Q,3//MD+:.:B&>2W*GOFTE6AI9GQ4^$5PY?P6,3\Y9,`($61"A,\QU*0!LV +M&KV_KRZ1RW*QWP[SO0="P(B!G`>:8VR,`6#&L?N-!]Y`\$?AP(%32;\T@SO* +MI]2W7JT&F5<NN%L=F2I12T:E2[ +MAH9MP$X2MT8GG@8`N`$``+@!```"````10`!M%+T``!`$0``P*@!`<"H`0(! +M]`'T`:`'A:+X/*=8;AX4```````````I("((`````````9@A```@``!`!@`` +M``&W^F,C>NN%L=F2I12T:E2[AH9MP"(``'@```!T`0$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``4<-@VXT+;$,%3Q,3//MD+:.:B&>2W*GOFTE6AI9G +MQ4^$5PY?P6,3\Y9,`($61"A,\QU*0!LV&KV_KRZ1RW*QWP[SO0="P(B!G`>: +M8VR,`6#&L?N-!]Y`\$?AP(%32;\T@SO*I]2W7JT&F5<4K'#[G@NA +MY3Z"_+TH>'(AFX#EW`2L%C$[T:;7]1*=BSU]2S^2/"1D20@\4LJ7*0``'```0`3L +M9'[-ZP8YQ7K[0```!P``$`%V3JU(8,&6@I<8D=-PI&_^BN7 +MRE].$K=&M>T&``P!```,`0```@```$4``0A2]@``0!$``,"H`0'`J`$"`?0! +M]`#T!]FB^#RG6&X>%#ZYL6JZWR(J+B`C"`````$```#L(P``T.::EJP9H"CE +M<%R+ON,O>@Y1#[E:4#>V!!_9ZIMN"5N=2D=E=**;J[SVUI<)N/!1]0KWTCL/ +M6:H/B&U2^-[;XF):;L0TGKN!D-OTT<_K:J.&+DC2.21`P4F6%XZ&C[9(&.PS +M)ZWP\*T4<^!D8<"JHGRIZ@@NF#G'L(N9E``/ZE,@'&VLK(7>`S/?VNORUX(G +M[XTITDL`"I_M_QDC6[,XO<;&C+N&?6_/L](;%[`V4],A)?,M/,3;E9?)HH-V +M-`6J5*7`N?APP*V;)4NU*TX2MT8#!P<`O````+P````"````10``N%+W``!` +M$0``P*@!`<"H`0(!]`'T`*0&B:+X/*=8;AX4/KFQ:KK?(BHN(",@`````0`` +M`)PD``"`,-5YXEYM\:!:S+*\X]UIA,T%6_M=+'1 +MU<9*VS-P)LHRV,<@.R6/VS(F\"U(7,=VGSB1`W<&#N&6'BVVZ"]TRDX2MT;L +M)P<`'`$``!P!```"````10`!&%+X``!`$0``P*@!`<"H`0(!]`'T`00'Z:+X +M/*=8;AX4/KFQ:KK?(BHN("0(`````@```/PA``#@/T576HWE\GZN).9I$"_# +M_(U],,)A6VF3[\T8\:4@ZV`Q*R'VHQ;M`+)GR0^+;7+3*VG=[9H@3P/W#0E. +M^%'-C[K4%$9DF5UBG+E:"-%;I/?_EB=P,^/OFAH0WT&VIP<6\M2YUH^9;F#2 +M(I^.;-[6%BV8@%=XF2&PTF[S)5;9['?GR*/+5=*_@%RO/J4U(6GM>(M.F8]< +MG,LA]HPA0V2,WD&5^&NZ0)J2;/=1]Q>#>:#"B0%):Y:KL4L*YA"E9$X2MT:),P<`_````/P````"```` +M10``^%+Y``!`$0``P*@!`<"H`0(!]`'T`.0&R:+X/*=8;AX4/KFQ:KK?(BHN +M("0(`````P```-PA``#`[D].Q#JM1%S'\<>HR/UV`[_J-?0Y`O%QJ=G:;:Q12-H/$>"0WGDX(7=)I-FE+EN&S$EB><$Q$FO2U)"&EYM3.,-_F[5EBT!V<1/7Q?VA[?O-1Q +M-8K`XLDIU-Q7-P-3NZ$5:>:_97"X"GN;@:XGZ1.2D`J-JY6@%.[\RA:,'BR5 +MN]S)^4[T_Z:EM+N!MGC[H1RO!1CR?`9.$K=&(SX'`&P```!L`````@```$4` +M`&A2^@``0!$``,"H`0'`J`$"`?0!]`!4!CFB^#RG6&X>%#ZYL6JZWR(J+B`D +M(`````(```!,*0``,(K>(GP=^\;9^P=R%Z"L3.,DN)O>*:^8*NZOG2Q0:?NU +MY4M3A*W1LY:!P!L````;`````(```!%``!H4OL``$`1``#` +MJ`$!P*@!`@'T`?0`5`8YHO@\IUAN'A0^N;%JNM\B*BX@)"`````#````3"D` +M`##]!AN5RFM:?MK@F%/D!V*DPQF#-MUP3UJ:Q[KTB2\<\*:$LZN.=QET(M]A +M_$X2MT8G=@<`/`$``#P!```"````10`!.%+\``!`$0``P*@!`<"H`0(!]`'T +M`20'":+X/*=8;AX4/KFQ:KK?(BHN("0(````!````1PA``$`)F6LDAWLNN>U +M^5YETYB2<>5D%BD/P(@L@&1X[`\3Q!9E>`5'B1-)!&2B/9]*ZWTG\EI$,LJ, +M,AUY82"ARVV2:;QP#:QUV&[OLYS^I/]12D=[++FV:1L].ZHN`*> +M1`1&FJ-B'A9]2`R?`(,Y[RTK([!@N:"?9(XR-6IP]:T8@V'6-8U^S_!@HO"1 +M"S55FYN`<,%+"@CZGJDZ+$ZR(@HA'O0YW?1%[^`.*;"."6&RN1FH=2L&?=YY +M;;O-FEK'ZZEURRM)6IZ8'///3A*W1K2!!P`<`0``'`$```(```!%``$84OT` +M`$`1``#`J`$!P*@!`@'T`?0!!`?IHO@\IUAN'A0^N;%JNM\B*BX@)`@````% +M````_"$``.#ZIDU\/?XB?#)B2FAW4(CKATAI='&+=KK);\H:!/[M(UDKQH*( +M+*+:<6/@7H+5'&D:#EF%5)R4"4Y03;3?/WBV=V@09]+FR[5#VJM%,DJZT`9U +MH!$0TGQU:I5L+K-&;L=SD>Z! +M-R7C9!?OZ9.J&4(=@AO9)%K,L&QXZR*D]/U\B$W&'V2)ZW/JLGZYFJ*1;!5V +M(TA\3A*W1B21!P#L````[`````(```!%``#H4OX``$`1``#`J`$!P*@!`@'T +M`?0`U`:YHO@\IUAN'A0^N;%JNM\B*BX@)"`````$````S"$``+"&&;F)\@D1 +M4+0G0A02'3#?W3\%^"LV4'XB[@3J.3_0@P?#/9N48F'LPR*']D)4K]I?3T0& +MS2K#A2"><6^=T2,^MC:PN^ZX_94;F!?:A,1;U4!)3PVAQ^>ZJ-:4%X[KU`N; +MV8%UL0Z8`JTE`E8I2NP%8N^PL,U;J5@?P0"SHH>=4OV+/-;]J]<.NJNEJMXG +M%)'.(#]M-,>D/;5?JR?A8E=D22CV194,9 +M6<(3/]1+#ER-A_U4.'6M8X%W$534`(NFZ +M@=+&GVL#8X-@FD=]J*W1AK^'$P@T!/Y.DA)MEZ%T]5[.D;E5UYM9",IOBCO7 +M!J<38>YJU_>P+@2CG!A#.%H-T`.PP\%3AB&,K-QE:LN[<&A3E$OH-F$R5$FW2'\3Y:ZPQYG(K,`&!.$K=&?-T'`!P!```<`0`` +M`@```$4``1A3`0``0!$``,"H`0'`J`$"`?0!]`$$!^FB^#RG6&X>%#ZYL6JZ +MWR(J+B`D"`````<```#\(0``X+ZK\R<@D93.UK6$27"1!)U-#Q!$QQIU4U"A +M1]BFAP8(.S7P3/'S%[_9]HW#CDD8`-?6PH8F*4J)+P[R\[Y+_>:U@_GH]O>$ +MDL$R1^V)GR'\W@%\%!NP7SL51NL2]LR9$8*XNI6'!&?QBT1SK3KPX>Z@N3##G0Z(:!]91,[$>;&Y-$YM1#\V#F<0!AC+QY9$W3`=&- +M=(?SOH.!QF$!JN2\K"#)_$X2PE9EGP5/3&26J-E9W7[K("FCFRS+F3@F!@ZF +MJ2X2%?]2!L6+;:-/^D-.$K=&YNP'`.P```#L`````@```$4``.A3`@``0!$` +M`,"H`0'`J`$"`?0!]`#4!KFB^#RG6&X>%#ZYL6JZWR(J+B`D(`````8```#, +M(0``L,*OM_J\I"S],["&U@SDVB=@]784=AH,7B.V@_?Z/;,AOQVML:K.FFQK +M%CAS;Q-_(A'SR-XJQ0XICO_F83];OM*=]ZS%DX\\CAI2AB85%Q:$"1Y>M]WB +M,;3K$N&!0)NLR/=4L"MX1^!W\^'.P3JOY#^_S4^OZ%"ZU.[8V>R'R$KDR6#% +MCRV5"2/AV'H,8GQ)L/>Y\UG.QVNZ>"'A.^@P!/`?:]B-!0\-*`H>,8).$K=& +MY@X(`.P```#L`````@```$4``.A3`P``0!$``,"H`0'`J`$"`?0!]`#4!KFB +M^#RG6&X>%#ZYL6JZWR(J+B`D(`````<```#,(0``L%K4:@]!_18+%AIK/V9Q +MZRDKW>]!1I\7$:,,L:*,4-\FC7>PT47O7)#PNK'#_*IA6LM<@W2AFZJ9F`'EM:2C62SOE3C3L@IT)>0]*-[4%I>"DHWG@:H +MIY!UUB<>M@"Q%!:6B:6==QA)6#09.6EF*/6QCA&V$C0G:2 +M']-A^,G=CAZC,2?V7:YC>\C'M=_\%#ZYL6JZWR(J+B`D +M"`````@```%L(0`!4`S?'%?9S8>=\GZ33*/11SE;C"6HX1T\Y]NU>&NE6AN:PA!6R(&"J)%"9WLYVU? +M*.C^V$$G,FFZ%\0TM@;=,(*M!:]ZM/ZW6R./EIJ,<(-`I#6E5Q&P;E27>I1@ +MD77@J_"&(HD1.(1P-P"+*8&FOM*P&].PY2`2C<.O.4#+*:!2( +M2,]3^=!;1+UYEJ"26>T(96%\0$,>D`ZD_/U%2.$+UM$].V5=_D]?S_P +M_=,54K8-2/?3VQ-U^E\XQU;U3'Z'20K#Y6MLW(T%V,7-QFNS:3?7NV;^DOR; +M>O`H><(:8(FCNP_9-B#Q;LT[0M5R=6W+,D>^V@1UVY+X*8`?W?T*9#_S)5H? +M,WM,N@0[Z23/TED8&T_!W'8J30?&/H)5`5OD[X\R3A*W1N1H"`!<`0``7`$` +M``(```!%``%84P4``$`1``#`J`$!P*@!`@'T`?0!1`C@;G4,+DB9P1N%VQ2,O5E"PC[;F_\M\HTN$ +M34@FADW+>.\\2ADAZET91!?ZT+T![6P>4X[%1ZQ*VZ&H=0AR@ +MFP+5,VQ<5+>@]`0KK?'`U1D#:L38PII$'*3XTR.?TBV9H6ZWO**M!E=QI)[T +M0N4NFUE\3']UO7*D\<_FWD-,&Y0N^6F7CM@UEG"K6M\N=4X2MT;8D`@`?``` +M`'P````"````10``>%,&``!`$0``P*@!`<"H`0(!]`'T`&0&29KM=,[=6>9M +MK(\$M][`-9,N("4(`````````%PJ``!`[.@Z*8U59&E2NI(.\BYWRZ/WU/.3 +M>HB)9H28V.SU3Y_("D*5EUTX=0N`:=)YPN7:RC>DUBLYV8Y`:]K-3A*W1AR< +M"`!L````;`````(```!%``!H4P<``$`1``#`J`$!P*@!`@'T`?0`5`8YFNUT +MSMU9YFVLCP2WWL`UDRX@)2``````````3````##J#Y9MK(\$M][` +M-9,N("4(`````0```$PJ```PYZE-E^PFUF-F;`#OZ,*8:\=/E,-_=]XRP4"? +MXB(?GQ\'+$,`6JBF'4IM)^-.$K=&_[@(`&P```!L`````@```$4``&A3"0`` +M0!$``,"H`0'`J`$"`?0!]`!4!CF:[73.W5GF;:R/!+?>P#63+B`E(`````$` +M``!,````,%,+_HB2<<&1#>)CO+X[99I\["TMT2FU997!60TB]A^>+!XHRW!( +MDO%_7)Y>3A*W1NJU"0"8`0``F`$```(```!%``&44PH``$`1``#`J`$!P*@! +M`@'T`?0!@`=EZM%.%+/C+V(``````````"$@(@@````````!>"(``'@```!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``Y!;=ZX-ZWO'2ZE48F+R[ +M2V\6$X%0;TB>`GB72N_R58E7N45-,4Z!QF@6LKNQ)"8F6-5%+^UZ7@R-H`*( +M/>BV$'2A40G,W$5XKW$U>Z\V&X=^CG)MBP>R?V6V0FWX088)(!@>\@+)T>K0 +MH#-*5\2,2HT@CZG\*$,A>TC3?`_UDU\I```D0L$6?#1TV_BNHM`D2QI$#:'] +MN[`F>@,YIB_QY.JE=_,I```<``!`!'=\1L/NI30!H6*_3_:X'I-V+:5O```` +M'```0`7ES%,0N'B.^>V\#1$ED_WH+T76$TX2MT:ZQ`D`7````%P````"```` +M10``6%,+``!`$0``P*@!`<"H`0(!]`'T`$0&*>K13A2SXR]B```````````I +M("(@`````````#P````@``!`!@````%'W?:X.PKT&[53[_(.OKUK8RX.ODX2 +MMT8&U`D`N`$``+@!```"````10`!M%,,``!`$0``P*@!`<"H`0(!]`'T`:`' +MA>K13A2SXR]B```````````I("((`````````9@A```@``!`!@````%'W?:X +M.PKT&[53[_(.OKUK8RX.OB(``'@```!T`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``Y!;=ZX-ZWO'2ZE48F+R[2V\6$X%0;TB>`GB72N_R58E7N45- +M,4Z!QF@6LKNQ)"8F6-5%+^UZ7@R-H`*(/>BV$'2A40G,W$5XKW$U>Z\V&X=^ +MCG)MBP>R?V6V0FWX088)(!@>\@+)T>K0H#-*5\2,2HT@CZG\*$,A>TC3?`_U +MDU\I```D0L$6?#1TV_BNHM`D2QI$#:']N[`F>@,YIB_QY.JE=_,I```<``!` +M!'=\1L/NI30!H6*_3_:X'I-V+:5O````'```0`7ES%,0N'B.^>V\#1$ED_WH +M+T76$TX2MT87^`D`4`$``%`!```"````10`!3%,-``!`$0``P*@!`<"H`0(! +M]`'T`3@''>K13A2SXR]B)H?`#],Y20(A("(@`````````3`B```P````+`$! +M``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(` +M`)N@G=]FONC&>\B52Q"XAZ9?!I)]*QN&W+D7<<_J/\41S:+Y,;6.7:!&]7?*Q7LZ%AW?V''/VQ;J5:BX[%Z,18C83EWZ.LA?PEJY.$K=& +M-B8*``P!```,`0```@```$4``0A3#@``0!$``,"H`0'`J`$"`?0!]`#T!]GJ +MT4X4L^,O8B:'P`_3.4D"+B`C"`````$```#L(P``T&%N&NN*H,VO'W6I?,>N +M_S!]7$X>(/YQEC,LH]3*>HN\W(9HXT#'SGYL`52]5-#8\+U0$GBN8C +M\#:=!G3G@<=88T1^$`LRL0KTZ7(88TSB%SAP7?'5:@>*I7K=MM8V+>/>W=4V +M%PRJ1U!P:WR&G=,.-^.'H6DMI$%\XX#/1,$+1*J)U#6$P)QI!J.9+V1Y+\P) +MR(0LT8]OQMX\'TX2MT89/PH`O````+P````"````10``N%,/``!`$0``P*@! +M`<"H`0(!]`'T`*0&B>K13A2SXR]B)H?`#],Y20(N(",@`````0```)PD``"` +MZP"G[K1+F,3Z'7V;A@`N:871ZDK13A2SXR]B +M)H?`#],Y20(N("0(`````@```/PA``#@R2_!NA?>F6+J3]Y-+\1&C_1G1??P +M2\KA9+GFUA#P(79.PG[E=[GR)-_%6\$_LE8,=2A]H_`?O4UNM-5L0PJ*+UN> +MSB361([QH2L6'FE[C"9-1/29!>F3)YH3/K.7?I<3X6+ORT1WZP$;NXSMOLD7 +ME(BE)1TQF*OM`*G:&CGT2VFTT]'1?7QE?UO1N[6P3U':9_1VVAD5L<]=QA3\ +MH9Z<$ZB^.[M!*VW)GF:GP@8F5N`S:O]>]:[D\B8A>5.Y1W3MDX2MT;3:`H`_````/P````"````10``^%,1 +M``!`$0``P*@!`<"H`0(!]`'T`.0&R>K13A2SXR]B)H?`#],Y20(N("0(```` +M`P```-PA``#`);AG*Z[5&R]YN"Z-N&XZVIALUOUHY6OG^@HR&K:#%]]AYR7F +MJ#ZG9::P8X,>DE8>JO>N),=>T9]\%0'8-WC*OA;#*-^?G&J])P,,3!52?9^^ +MHEQC9F%DRVJ[9OW/12"=!61U#;9,"HX,`)TN38(/*1BP^NP@MI_BN=]M+6,B +MD1*!O$;?8U>WO6*/U;\,#-&_#/F]&I@A"L1&`W,74TN,WJQ;(XQG7;!3:V() +MA#XL[E]+*E_L-BTEY4K4R[Y.$K=&PW,*`&P```!L`````@```$4``&A3$@`` +M0!$``,"H`0'`J`$"`?0!]`!4!CGJT4X4L^,O8B:'P`_3.4D"+B`D(`````(` +M``!,*0``,!E[0C#3$%:9*EG\ORPG9N0#U4%6)ZJ;(>=;-Z6;O!Q;]I)\F9=L +MM=M"ZHR)3A*W1AV/"@!L````;`````(```!%``!H4Q,``$`1``#`J`$!P*@! +M`@'T`?0`5`8YZM%.%+/C+V(FA\`/TSE)`BX@)"`````#````3"D``#"?5]EY +M2)[;@_1,DA9S+@=SDSJM='(GJE+27ZSP8<%EB@H?5!<.Q2T652E,`TX2MT:4 +MJ@H`/`$``#P!```"````10`!.%,4``!`$0``P*@!`<"H`0(!]`'T`20'">K1 +M3A2SXR]B)H?`#],Y20(N("0(````!````1PA``$`O&35U4\V6[M&4?.B&50/ +M>BRB_*>Q03DE/VNH_C:=CH#>I`5ML1TY05RU00.9K]KT)!_F'-RV +MO!TN'2W@R$0_YS^ED9!%Z;?(>YTK)("-YCT"?^.]'N'-DNM:TPP)6C:Y<#O_ +M_=O##1D9_=GWXN))N%B)4++Q,)G!O! +MWP!$PG#(AY.%N"[7GAOP$]2?+#\9Q@ZF+/$(4]]]K4ZGX''M)8EW)]#H#J,- +M>+2EE-ZYD%V\"GTXQW)9#3A*W1IRV"@`<`0``'`$```(```!%``$84Q4``$`1``#` +MJ`$!P*@!`@'T`?0!!`?IZM%.%+/C+V(FA\`/TSE)`BX@)`@````%````_"$` +M`."H>7>P"MG\`H25,;&F7MUY3?>D!/$8Z9+!^+]74,"KT_%`EH +MH:##WZAEK(K35(UEH[N.GK?-/.+:6)%7)&*#4V^X,C&4*V2F!_P,0TI:FQXJ +M^&?3,7!%`WE^.M*3PQ'W,76)^X!FX8Y++2:T9US8A[ZS\7*SR7_PD`RY"B9O +M@C?H%K:3Q5=@!:?I=+3IS`4!R5-%9]E0PR#@^'T[&X17V!.HBQVOFQ7(N2THB2URD>/D@T>2O-Q!]EL +MG,S_'`CKN>C&L^5/6F]"PBF/,:Z_C3',97F18)\R4M[I*Y^<1,Q'_EK)RM:/ +MFL[JBC>.6>6..P#6HS$UW-4D$!PH1:^^+1*/]:$68X'M17/9)_Y=D0`3X3BG?-PG&W"Y-_%S(^" +M_WFAM5QGC%UD^(N,)S)XP1017N698V +M,G`RRH^U%03Z"NTT*9A[GGR+X_5V?,_E.H4Z,N^)BC`)G`#>`>,BX04@7]4? +M?!_75W_Q3A*W1EX%"P`\`0``/`$```(```!%``$X4Q@``$`1``#`J`$!P*@! +M`@'T`?0!)`<)ZM%.%+/C+V(FA\`/TSE)`BX@)`@````&```!'"$``0``LLV: +M9Y"F^2(1?W]/3]#3%2#[1\@%TVJ,ZC)6R^XN1*QJB['/YO!)(-;MH`U/$DR* +M)ZY#NL8.N+QHG\5TP)&UX.('5YN=9@Z\OD,SM]J*F=10;M,48L'!I +MGUU?7[6,:^^7:XDU.ER"(9[T>+B(6Z-.$K=&*A$+`!P!```<`0```@```$4` +M`1A3&0``0!$``,"H`0'`J`$"`?0!]`$$!^GJT4X4L^,O8B:'P`_3.4D"+B`D +M"`````<```#\(0``X+%BQC7#U8%>+C)NTQP@4C0#^F_0_UQ\*DPVK61S!N$^ +M]\R1]['(_?GK%_.A,EUD$&_>#'8!&_JA">S\:-[&6+I?E%!S/K]W"'(/SVD1#$)+28B-W0-` +M1+<,M;^RZ/!4V,3\N'T)*7J$1H7:MUD+3BF!RZ3?1&[II;@C!GD$B[7DLI!I +M[-#L@1`E:*I.$K=&B"$+`.P```#L`````@```$4``.A3&@``0!$``,"H`0'` +MJ`$"`?0!]`#4!KGJT4X4L^,O8B:'P`_3.4D"+B`D(`````8```#,(0``L#^O +MX[MQ=$^5C.0G1*NO\G!4H/B9,#ON0(U-W^:!>EPR,/,=)+>PF`$UN)6WO^(\ +M0^>1=Y&G@=]"],4^-*/([Y$D\\OL%`Q69Q>E!2YHGF+?%[9;R_H)VF-V[930 +MW"0_(KIY!J;FW6B9^_>;[1YSY36C"YP6PH2SXUC;IG;C9_0J%2;O&-2!8^#F +ML7J(S_M-+NQCZXA8SJY:@I68_I5LG&CT68ZOH9G;^;I[H]_YCGG7"OL$)IK;H6^KZB:#2/@_D):BK`-/D\E/`. +M(BO<5'?#1JBDAE,1WEG:U\Y.$K=&(&H+`(P!``",`0```@```$4``8A3'``` +M0!$``,"H`0'`J`$"`?0!]`%T!UGJT4X4L^,O8B:'P`_3.4D"+B`D"`````@` +M``%L(0`!4-[!$>%6)R=P(`^([1=)V]^]`F!,!/M^PS/=LHUXN?$!)]4#/ +M$GHXQZNCY>&YI&3YY)9V:X4SVDYX2>#V*O:H[U-ZAV`9VB5[C%W&#%,:?9PO +MPZB6`FMPG>$ZX.R1/#"BCNRH`Q>K=J%`&()T8W`)01W5,U=(@D*<]D!X0)Y* +M.]73C5H8%)2_SN%9',K=O9?L_]X!V-F0Y4CODO9K]=%IG#QH[0( +M*Y6Y[^.U%)@D1M%B>G)P848PF!B;WF]#.H"FI2[F'=`4^.EBH;HIAXY!K$J] +MQ[SIA[7M(_2"AU6;OC+$Z;&PJ?W"P!<`0``7`$```(```!% +M``%84QT``$`1``#`J`$!P*@!`@'T`?0!1`7$?@S29. +M$@G'QYP8ZUKL+>9BU.J?18W:EW-ATMN@2EY"FWXH[WH3/1'"A1D=RC.,66*[ +M^:$TVY[?$B/^4?SJMX`UQ,18$W"`?/^FS).GJGXU3Y3/ +M`L'X&&3K3'`-[UV9;U)W#Z!M4G`AC!F:8$EH"R7@=*U@9I[W_2BXC;V1#=AI +MXK%]$]7CAT)5Q%,>``!`$0``P*@!`<"H`0(!]`'T`&0&2X24\7P*S;/6@8V(3 +M(JDN("4(`````````%PJ``!`;DS%>,8P9EC$CN&A]:9K]"#<\O6)U&K#>F8M +ML@H1$Q]WQ'`A&3%!^RKZQQ.K!`X24\7P*S;/6@8V(3(JDN("4( +M`````0```$PJ```PY4HIB%8\FA'U9`WKY!?["%AUTPT>U?8ENP:-BO0 +M3A*W1H_F#`"8`0``F`$```(```!%``&44R(``$`1``#`J`$!P*@!`@'T`?0! +M@`=EY(9(ON%:1"(``'@```!T`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``,$]1:Y\\Z7SV%L.*0\A@Y^(ZO*#T +M'3YEXBA2@-`VLA,1P/)G$8?9J@9B2.Q;N1;'E`YC,\!/>D&-*(A"/*:[9"]1 +M)X<+*M@@PE'OJ9A%TU?)(S>R*"DBZ4$S)-Y9'9'1L0Z`-M(^XXB8L\(A +M;^S+X5]#N2$I```<``!`!-H(JC_T-*CFL+GCZ>ES^LWQM?,M````'```0`6; +M2O$K_-3N19.J2V7@M+C@AERU:4X2MT8E]@P`7````%P````"````10``6%,C +M``!`$0``P*@!`<"H`0(!]`'T`$0&*>2&2+[A6D7)```````````I("(@```` +M`````#P````@``!`!@````'[D44*5S&\.X#PE(;`;#GXTBIZ14X2MT:]!0T` +MN`$``+@!```"````10`!M%,D``!`$0``P*@!`<"H`0(!]`'T`:`'A>2&2+[A +M6D7)```````````I("((`````````9@A```@``!`!@````'[D44*5S&\.X#P +ME(;`;#GXTBIZ12(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``,$]1:Y\\Z7SV%L.*0\A@Y^(ZO*#T'3YEXBA2@-`VLA,1P/)G$8?9J@9B +M2.Q;N1;'E`YC,\!/>D&-*(A"/*:[9"]1)X<+*M@@PE'OJ9A%TU?)(S>R*"DB +MZ4$S)-Y9'9'1L0Z`-M(^XXB8L\(A;^S+X5]#N2$I```<``!`!-H(JC_T +M-*CFL+GCZ>ES^LWQM?,M````'```0`6;2O$K_-3N19.J2V7@M+C@AERU:4X2 +MMT9;,0T`4`$``%`!```"````10`!3%,E``!`$0``P*@!`<"H`0(!]`'T`3@' +M'>2&2+[A6D7)AQ\)OMQHUZ\'"!ROH+B[VCG2;.NG4]5L&@"P4=S +M[UX'.5);X."A@QYPS":V!L4DG59&0O\-O89XV')+2))`*0``)+&%O2'&D@%@ +MQ#'%U&>-PUHN:P?F;3_N>)6A>[%9+G0^*0``'```0`2^MA)`E.&X<%!#0:[] +MF-XP1TQWSP```!P``$`%WL^AT)F0P=CXGGU-",HR3HWW(NU.$K=&Y%T-``P! +M```,`0```@```$4``0A3)@``0!$``,"H`0'`J`$"`?0!]`#T!]GDADB^X5I% +MR8G+B`C"`````$```#L(P``T&3L_M.B9Q_H7PMI87ZI%!.Q(&&! +MHM\$`#WM"&Q\1^]^X8W.'<2JT=^WR6^052L?*XT>"G2RMKPGJE5'O^%<(8`9 +M$?AG83RPY3JJ>J1ED=78OCY<]5ID+=2RE!$-\;G<&&68M[R?Z*T?I0-^!)9; +ML$@/KQO\2^=27C;I<6C=>GG!8M!G7S8UP^K/61>R!>I/NYQ$0*,K31U$,F6& +M=TSX2];3%%DZ9IHX^6:J,Z^':XE;BDG#8=]#J4 +MV-B9YTX2MT:C=@T`O````+P````"````10``N%,G``!`$0``P*@!`<"H`0(! +M]`'T`*0&B>2&2+[A6D7)AQ\)OMQHUZT_.^C,^K2/++Q6!,3"YWZ?H(I<^=?`Q).U(E!7Y^I^(2F?K@^`;ADO5BK +MM!YP]0T>P&[<&0_FP]L*Y<5=RTJV-/;E:%,T_;FK69WP!T5-B.]'ACC4FD3U +MY=M=>6P<_2&2+[A6D7)AQ\)OMQH +MUZ+_D4NI;=1S;>[KJY5[,%FZ\921*?]*; +M])F?^_*!RH:\!R/6Q`X9V0ZR66V@Z@F^(BHA'BQ.@W;Y2^(B+Y$QJ1SC?P!3 +M@M5&.X)^#/QIA.#-?#XRP8;N\+%!06./;]1-^N7:V$E`B4'$47)JUH2Z4%U0F6HUEPYJ* +ME^IN/C0MZ@Z2-M7@ZN!;U&MOW8PD+>NUTMU0+V';:)P<6TN7O,=`F\&7R]$: +M^9U`_P.FH]5C7EJFUTX2MT8\I0T`;````&P````"````10``:%,I``!`$0`` +MP*@!`<"H`0(!]`'T`%0&.>2&2+[A6D7)AQ\)OMQHUZ;4&E;V`7-5HQ\7K](@B-IJDF?AT3*8%E +M4=I.$K=&8*L-`/P```#\`````@```$4``/A3*@``0!$``,"H`0'`J`$"`?0! +M]`#D!LGDADB^X5I%R8G+B`D"`````,```#<(0``P##I0=!-;EME +M.#IW_+,3QW4,.4X^:)22:X%6Z6ZPSSQJ4!7MX#M/XRZX7JV$7C4=F];*BDB3 +M%W7O\L\#CGZPBBLF>OU?0>O5>4,T(4YX/JVI."!3!@4XN@Q"*ERS:[2)UC%. +M&&='!LKM'X3QKBLU<=@@T?>?:OC2:7+[5KO_3:V^`<@9;Y\ZI6/:NBF\UX\= +MGA.,96K\LBP'JWQPO&!I_#:@>N.:5OXI(E2&2+[A6D7) +MAQ\)OMQHUZ"6] +M^:B&(&/[?%D7%4\7BC<1,(],1$<32SAA!B"[MWION5]=?K2?M)[84LSKH&=8 +M`EO_T9^KNP-O!>H[Y6UQ6#_QID@%F*EC`)7FEEOBV.WPI/0S2/CW\`UJZ/@! +M*^CE:Z5>:.L;H?6JP3T5`@-9"90QGR"/A(!:8<=9_T233[H&GY0S:-AR)JA:I)IE\[]ABM)F +M_V":+HR<:F@Y9+WRL0R5GYT1@>!@J\"-[;F.FJ2$#T>:!0W>O][I'#E;T>@] +MF/S(+&'R3A*W1H7M#0`<`0``'`$```(```!%``$84RT``$`1``#`J`$!P*@! +M`@'T`?0!!`?IY(9(ON%:1*AL=7J>#-K:VK?4^Y)Z&=HW_$ +MP8^4$_4;:[U/$V!Z32P/'BQ#`3^.<418NQR)U^T.DB-2",FIHX5Q95J8D([\ +MY@8W3"P6QG+1$T\AW'+>@:NT&-=3!$.VIJJ!Q4Z).C8'X>6)M^)P60<]SH(, +M!R7T<6JFQNZ[0I@5Y/"K,M.U,YD3=7$,$X^F#]4:IE<&E%2XU!4->(IK)J^X +M:H^_TRHOL1Z`OG..T>)+W4?&>-\\00UK>PE%W0FH1:C.VP!+3A*W1O+\#0#L +M````[`````(```!%``#H4RX``$`1``#`J`$!P*@!`@'T`?0`U`:YY(9(ON%: +M1^M,1B<2&@ +MKT/%)L@/$9S_T(E;XI/V=K>]OWT3R4Q_0V'C)V;*PD##"T3@!#,M3TQ_IO]K +ML&&95`?.L:W`O@);V]96R]IPH)&=LTRS+E$-.L20" +MT7X#DJMX]RTO1UXQS(1XV+=N3A*W1O@?#@#L````[`````(```!%``#H4R\` +M`$`1``#`J`$!P*@!`@'T`?0`U`:YY(9(ON%:1*6V'BLN5G2Z&??)P[]__,[9:??! +ME=M(NJ7$4$7P4T:C`$`5B0_AR'XPR3"4ZVHG"JQ!4B9TGTK(%#$:OI1A&(E( +M+Y#AV&0@;.X/!2JRGKQ;+P@"&MVNC,(*#_)TG[=66'7$/!B^UV1FGR]%L4-- +M3A*W1H4\#@`\`0``/`$```(```!%``$X4S```$`1``#`J`$!P*@!`@'T`?0! +M)`<)Y(9(ON%:1KHRY@!O95 +M2@\X>BD29UL>B5!6USUNQ%E49#6J4;EUI9T5`35IADNI-8<4DHS(L2\.CBHV +MMNT']$8N(='UI7`O-?S[F-<[=D`:FW:IW,5>04`#RSM?WU**NU>'BT%9EP6T +M%*@B][N,>D_$6.=S\-&9R&N8.7W/";_GQ +M$29RB0XJN=B')D$W6^E[)5UJP6QF6KFP&B`(B"G&P621A>6U%H3*.J3OI2.` +M;PW8/L*^E0+<[=9P]4^=5C'QU\K>DG-L=?\7%JZQG*#*"7R^D:P0(OG[*8&Y +M!XJ1#(YSLR(6JX*6`Y?(9AQ.$K=&AD(.`!P!```<`0```@```$4``1A3,0`` +M0!$``,"H`0'`J`$"`?0!]`$$!^GDADB^X5I%R8G+B`D"`````<` +M``#\(0``X%-<#`,N'N4VTMQG@?@^)Q*>LJVF_0#TAC+YY<\&ZGJ^A?LEXEYA +M%A61J8MG?Z0K9P;&QUS_.8H4RW3O/?WS($K!SX_3^DO;$G<':K:I/3&::'WG +M_"3$!=/W,^4:0E2C/^!5>Q.J#GVCO+/6#L"";DK,6$' +M%X%.$K=&'U@.`.P```#L`````@```$4``.A3,@``0!$``,"H`0'`J`$"`?0! +M]`#4!KGDADB^X5I%R8G+B`D(`````8```#,(0``L#U)BB0/C)*# +MK>.^Q2W\+I[$^?4TUPR^"B2ML?JSX$/#2XEG'-7EQAY%75T26Z`L@H;JRI]' +M:WA>1U/2$!U#:3/[)8'UM4VH8!'EK>QAN$3]DR61_0T2YVE1'0VX\W9)M.\* +M;?4-79BEM[21J$PTC9LY'Q]AE4A`A[56T'UE%FX2E/>0Y^+CUS@U\*(O`(VX +M_\?`P:S*OR;R`*Z=6ORPM@:QVSO>72EZ##W?G+B`D(`````<```#,(0``L.C(,W",/H)L05_KC'*$DT,HUNL?HE"'9WFK +M[2'%AN?!Y[:MFQR@*5?"0D*-XHX)3%+;R.5[VF\9XAF;IZ"`.S%1"C`M0&BY +MB#2=3SNDS7LT?]<7N0\9JH-C<.+29,4=?*`1@DM]_VG'"AR0GK3,T$#Y*^"D +MK![DH*FFW=`I#?H3NK7_XVL7&NMV<5),B:7H1;\RK[8O'XX;VZ?AVQO*;S1' +M(]0AA,"Z=A$3:<9.$K=&U*`.`(P!``",`0```@```$4``8A3-0``0!$``,"H +M`0'`J`$"`?0!]`%T!UGDADB^X5I%R8G+B`D"`````@```%L(0`! +M4'>?0?VFPO%+:O2.B[DEUF(N8;AS.3AMPD:TC4RC31#=@@&,O=&"-?">:[X0 +MQ3&GM(J<:M,]5:/+A=T@ORJ8=*'6^P],2[:DJ6B9OY,Z?G9*0>]OSX"$=@-[ +MDQ0$82CEFM2THXV($D\_.\!BY$]I(0W/N4)MZM5JR?\N7[-!#=801#[8JL2R +M)-I-XNR8..C!1][ +MZJ2F]&:]`2KZ0:WK9>[-W0?.\ZCH!QM(M2`LRHL2R89/FM]OGO%,5;BF:\L6,3Y,"):!9ZG2@!>;++N6<2\#^[.5!:OT*>1?@\&;!KP#9_.M4Z6, +ML$V,3J6QZS/4+:[S[L,;#ZI]3A*W1H74#@!<`0``7`$```(```!%``%84S8` +M`$`1``#`J`$!P*@!`@'T`?0!1`=EJX>Z5)=3G-&Z($%O_3EMK*NSP(WJ*KS!G;M +M4#-EBE12+UXS7TJMZ*O!:R7CS.EZ(4%++)4JD&W8*BF4EACP5?V`F:^L>EX, +MN+O"`-VJP[UUMO'D4C+GS,5`9)P+20$'NBR3%QA$'RSWP=@\PV+*=6^2&+?;?BVA^-LR5\HC7BL:F==P7*B_Z9!D0AWLFXJ[[ +MWG**Z$X4>&\LS-(G0IGI)IV$\#$8[-CFL'>S7C4:U@"W<+R!>,T]+XJ>M&N2 +MKIK:*PN4Q>@.M5DIY7BM0U7`'B&[;Y.X+F=EDN2"B@[6[D]JLSRIK=(/:5\" +MO!.E83<9_*((W6V__.[H!!W*OP'NCTX2MT;J^PX`?````'P````"````10`` +M>%,W``!`$0``P*@!`<"H`0(!]`'T`&0&26<]FG:VX%,AH!I&O2;H6>XN("4( +M`````````%PJ``!`]"U/'R+/:>\+XXU1,-&-`$7Q9*"M"&;@WAQ>)E<[Q=J' +MH%'%_JGI^[(GC%V8Q*8;U;3>/+!34#&4=EW/3A*W1F('#P!L````;`````(` +M``!%``!H4S@``$`1``#`J`$!P*@!`@'T`?0`5`8Y9SV:=K;@4R&@&D:])NA9 +M[BX@)2``````````3````##/\E##K$(1&?11R]<460**OWO*%#KAX*>5:!9L +MKEF*D*6#>];U%_NDVC.>;4X2MT;(%0\`;````&P````"````10``:%,Y``!` +M$0``P*@!`<"H`0(!]`'T`%0&.6<]FG:VX%,AH!I&O2;H6>XN("4(`````0`` +M`$PJ```P2&.'#U8W;,DV'2NK>)8V>K[O&[X`VW`>#/.%A[RN+5E%E0@P)S`8 +M'`]=4S5.$K=&!2,/`&P```!L`````@```$4``&A3.@``0!$``,"H`0'`J`$" +M`?0!]`!4!CEG/9IVMN!3(:`:1KTFZ%GN+B`E(`````$```!,````,/5S(0*@ +M$>I=5@#=]4Z\,+@WGD%PF7YF6\:OG`&0K55&=!&D9D$_?2@PYLJ53Q*W1F3; +M``"8`0``F`$```(```!%``&44SL``$`1``#`J`$!P*@!`@'T`?0!@`=EHGE% +M9*FT2IL``````````"$@(@@````````!>"(``'@```!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``%V#W!XSS]#/K)=*9Q9"ID*[@D7 +M)WZJHP+3'EVS:R;E&E:FMHF6F]3)(QASL#'+%^@*E;Z+6'`D=NCV+3*3"\?9 +MC":+<=PUETIJ<6(^^)Z#[.F!6JWP!NZ_-Q>N_;5M`VDKU +MI<8I```<``!`!.'GG,$W$YKYD>'LT,P@55OQ@8OF````'```0`63CF0SS1%. +M"&;F22YQ#P/C'\#DHD\2MT8)Z@``7````%P````"````10``6%,\``!`$0`` +MP*@!`<"H`0(!]`'T`$0&*:)Y162IM$J;```````````I("(@`````````#P` +M```@``!`!@````&X[.P:[H)KS>!^9QGC`G07C?6\\T\2MT8O^@``N`$``+@! +M```"````10`!M%,]``!`$0``P*@!`<"H`0(!]`'T`:`'A:)Y162IM$J;```` +M```````I("((`````````9@A```@``!`!@````&X[.P:[H)KS>!^9QGC`G07 +MC?6\\R(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``%V#W +M!XSS]#/K)=*9Q9"ID*[@D7)WZJHP+3'EVS:R;E&E:FMHF6F]3) +M(QASL#'+%^@*E;Z+6'`D=NCV+3*3"\?9C":+<=PUETIJ<6(^^)Z#[.F!6JWP!NZ_-Q>N_;5M`VDKUI<8I```<``!`!.'GG,$W$YKYD>'L +MT,P@55OQ@8OF````'```0`63CF0SS1%."&;F22YQ#P/C'\#DHD\2MT98'P$` +M4`$``%`!```"````10`!3%,^``!`$0``P*@!`<"H`0(!]`'T`3@'':)Y162I +MM$J;AZ[)AZ<'TM<$DN8W.<9U(#>\M6+<>T,E;ED@=Q7RZA +MXLTV\^MRU;)-ZWIFU::GDB-+OGWY8?GV)]&;Y.'@$ +MJ!00[P"HIC;J.=Y6L6GF>VL1)3+CXR(X:U$E*0``)%^>Z%DZ-&ITYJ[]-";R +MNXT6_[NO40&&Q62CS +M@````!P``$`%L>=DD>KF;QL'N%)QM?@85UJV45DJ;1*FX>NR87+ +MI._E+B`C"`````$```#L(P``T!,BIXO?0%3+4`9G.O''S](H\/^UR/19/WDC +MI]B-<`TC>"*&94T*/'@HS!T?R4;]HKMG58]T2!64-/P7$1)A_PY#2#YQ4CG; +M"2Q,TOTZ?K\48!+W7*8T$S::I\@^;=-3N&8SNG:;(2?S#J"@*':>L[)">N=T1-(,@` +M@.SF1,7QL\_O5WE&Q;50NK0 +MC-&VY5I3$BZ3K2V3Q-,D=;(.)\$LF*YV/3R'D(="/&V>AC\(.K%]2K.X?O(T +MG#[@H^V!J4UA1(ST +MB_+,V3(GIDW6['L=CM,.YKE4$'BUY4=*N1NXG#_@U0\"Z?\KJZ.QPVEW%'`, +M:WI`T00=/4\2MT:WI`$`_````/P````"````10``^%-"``!`$0``P*@!`<"H +M`0(!]`'T`.0&R:)Y162IM$J;AZ[)A'12-:K3[E],$<):R>!B>[]N.V"^K6HLYI +MAT-4IWX!J5JK1,XFCQ,-5N>WM.:%1I445DJ;1*FX>NR87+I._E+B`D(`````(```!,*0``,/\T`>RP +M?[_"&N8'':5TH9S\3'OU2'13Q*W1L7* +M`0!L````;`````(```!%``!H4T0``$`1``#`J`$!P*@!`@'T`?0`5`8YHGE% +M9*FT2IN'KLF%RZ3OY2X@)"`````#````3"D``#`MY+K"G^=Q%A&^:&'](0'/ +MT0*_*,BC2_*H;:0Q1B;&22GE#S?HWF\YXXQ^C2F8I@46O1+:L_!UH)`[Q7 +M..B.H"X]R@O]&`^,$`M4\,ULRV%(M7X;SBTU7MWFWPW1OTM<>(@F"FT*>8!HBE +MX$C+2VX3"'].X-'ET(P`&0=30"9D:072$!UI+>PR),RK(JB'-^`4"`C>#-^0 +M3Q*W1C3U`0`<`0``'`$```(```!%``$84T8``$`1``#`J`$!P*@!`@'T`?0! +M!`?IHGE%9*FT2IN'KLF%RZ3OY2X@)`@````%````_"$``.#FO@XKF429OP]` +M5;$N9FL6[&O\8&V9\2E!QM,&7OW,SX@Z&+G2YZ&U>?(:.9/TP\9V1#ZM@CD@ +M1;7/;[;>>,U4Q\FW5G'X:;2TC&`4-5EVF5:R#E$^)41O[C$%V$ZV9=%9&J!G +M5'-+E63?1-I!'NGCY,X1I<7A^\AG2E/RI6RU?2(F@5?<8RR@$6:SS3I:4;^$7N3_9HY7)3^'2`5SWST4)*`V +M=?>P0=S^)`?(WV,3RZWLQ^XZ?.3*5U?-3.:.C^'`8LRR%U"#JA/#T=+^YD8+ +M@LEV>E=\6;>L*M9/;44RLX'&4Y<7M-1((TO\0FC<;+$-7[P>GB2/Q^#+QBV/ +MYC69"/?N;7#^TX\J.J38B!/[VF[J)H,*CCP&';W_LZE&#K+\-[L\3Q*W1BE! +M`@`\`0``/`$```(```!%``$X4TL``$`1``#`J`$!P*@!`@'T`?0!)`<)HGE% +M9*FT2IN'KLF%RZ3OY2X@)`@````&```!'"$``0`*B.`^__H:Y8/EM@M^CV;I +M7,+O3U&!*^?L!\L;'(DD-JH'VC4NHL'L<'4OA>T._ZR<86V+P:,^/\-./;8L +MO)Q1]2+[1:)-LC^]P\S_I/:^\L=IE4N)^5GMP=B;30$+;T6V==/X8/QX`QMA%[NE3:Z@*)IO5,5%&;PJ`9 +MM++&>7B<_)\=!O2H-3O*^+_S^ZZET`-IH,<`$/#9=7*.WL/+I>15G6:14)+( +MP+OS02W*YR,YM>9JB:4S0"D1;E_A8BU$KM!!/OMIS(!F!4=\Y"N]Y$JT[%B9 +M!SN[^$:(XH;;F3Y/$K=&%TX"`!P!```<`0```@```$4``1A33```0!$``,"H +M`0'`J`$"`?0!]`$$!^FB>45DJ;1*FX>NR87+I._E+B`D"`````<```#\(0`` +MX'VI7:S>FBF4.;[A?-*#67-Z\E#(&.X+NP5B>:;@%Q*7L6;99CX(1-OK90G7F7H=+[^=Y/__N<82UK_34L3G.21*1G57MTB@ +MNW>U:O_?G]8O;"#7;-GF@)92DK2"1BJ;O?%4V4G.#VQ>1BV*F/6^R%B>9R5< +M\J7LP)47[T8J#Q8!AGTJ_N4:^4PF$-='=SO[UY!5M4.^\?_<5[2INMQ/$K=& +M9%T"`.P```#L`````@```$4``.A330``0!$``,"H`0'`J`$"`?0!]`#4!KFB +M>45DJ;1*FX>NR87+I._E+B`D(`````8```#,(0``L)P##@6UU@S8DL1 +MB@QX-UR(!8%I(LR#7*IP^Z/H+I&VJV32?PL(9.,9$[*EB1Z8 +M2%0#E\R^PT#3J +MTN<<=1^.JXJ!)Q(LT/\KR(*OPW.%\SD?$[Z#3:C2J`X;.!N2(1"0M^YE![1@ +MG;WOYCO^DW8+^_UP9GIDS7EH7[EDW:E/$K=&Y'X"`.P```#L`````@```$4` +M`.A33@``0!$``,"H`0'`J`$"`?0!]`#4!KFB>45DJ;1*FX>NR87+I._E+B`D +M(`````<```#,(0``L.`L:[*CH,7._+L&DB\A?NTET+,G..D3W3BG4:CN@>.V +M=V?.,J+KZ$&M8%24;OEBGGMO\BZ[:W^$+U^*?#N.Y9W1V@VVOZ\LEU60`_[_ +MT,UR::L\8CK>E;6$D.\=CEI&H&U`F1T>`>A)VIQ.`L'C3+QR0C*SS^&;\#.` +M],QF,+25.K1F0,(BR/5VUVXG0._EC+7\D*Z6KL26LB4TUM-4`BN*`<0VAQ=[ +MFG9[*VQ/$K=&?Z0"`(P!``",`0```@```$4``8A33P``0!$``,"H`0'`J`$" +M`?0!]`%T!UFB>45DJ;1*FX>NR87+I._E+B`D"`````@```%L(0`!4%P!+.TD +M[PEB!M6T/!V6.3]OU4='$FS@(C7U=+[G]$PX17<(4_[2W"*!Q'>?Q,%;X35# +MS0#%0;6N(F`(O]B5G2>J+QRP)WLZYJ':!;.?GP].2\0V(+)=R%7<[Q*WYOI; +M'[@-(RWL9-20RFL;/9$<78?N$(J^Z(H'YA?S)$C=&+Z^%;KZK%\&5]'H8TAB +M@B..>.\80`<>2-.I'T9KY2P[DMDC]OQR`';D&3N;-DB[HFVZ:"&O=_B!3"HN +MA>HT`:01U>$O^0-T8U)DC2&S5U`>S^,-XQU#LO+$462C*_"C +M]^4A>>]%Q0I6CSS@[)`2MFI$_JOLH"C;3WFA[SN4?'T3S%V]0RS3AM5(]77\ +MK+JSID._82*%.Z+'\[)M[8JR3>P`Y+AM+R$K>#X'+7FB;O'P,3-&VV9N(#W% +M%7`%!8)BJ@/4__HV3Q*W1C+9`@!<`0``7`$```(```!%``%84U```$`1``#` +MJ`$!P*@!`@'T`?0!1`G>I@:9J== +MLJ91FX8^])X>`^M]"_M7*/6J)"PD4C/;7R1-V_\>DD+"&LU>]W?WKF4>)D9? +M@=98'(%=K+A:EQ"8DSRB_N#'9P..`^.UCD^Y'E&EE>QG@UT\8\5K0U'EP#QP +M'I904.@YSXNZ,KSDTDB"C8^,@\X4C\.\G``;F1P*JO:;[%O$G7ES'\-T<_)8 +M<.0-)65\RSZ6E'$,3[RB\$\2MT;\_P(`?````'P````"````10``>%-1``!` +M$0``P*@!`<"H`0(!]`'T`&0&225U']IC]1Q%#U(+4J7!ZS`N("4(```````` +M`%PJ``!`D%E/_%I(O_S3'R)9U-Y*9REV06UE1E4)W$8T5J6O!]0UI&!2R^+, +MC44LZJ>1?#\&"T8\B!VTL^\R!G>T3Q*W1M`+`P!L````;`````(```!%``!H +M4U(``$`1``#`J`$!P*@!`@'T`?0`5`8Y)74?VF/U'$4/4@M2I<'K,"X@)2`` +M````````3````#`?PC'@/J8%G%)9H1XO-::LQ^+4N@%1Y*T<0/ON!:/@(V+AVQ/ +M$K=&AR@#`&P```!L`````@```$4``&A35```0!$``,"H`0'`J`$"`?0!]`!4 +M!CDE=1_:8_4<10]2"U*EP>LP+B`E(`````$```!,````,)MGXQ$P\[^>X?69 +M`B?;;#&ORO+[%+8,(RMAWE*O>2WO69='C;O^FXLU/;6F3Q*W1OP@!`"8`0`` +MF`$```(```!%``&44U4``$`1``#`J`$!P*@!`@'T`?0!@`=ET(ZUJ"QUH4$` +M`````````"$@(@@````````!>"(``'@```!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``B9E'1?Y']:&%:']6Y4XHED&.^APW6!3=W5TV1E81GB79 +M;/5Z*.1FHA,0JA#&+S8L`__@$83I@%T)2JWM0:`&[OF*.RLP.W)+!KK:]$G? +M`;%0LN&@>PXD<5+OD%/,Q43K6]A;Q/QV.U/.#(#[89P^!\%4,(L +M^BA7>.4I```DBQ6A(&2[%7V@?9BR-IXV?J5"33\_-7@I'#J9C+8=*3XI```< +M``!`!,&RN5-1Y[V2&I\E$%M4X'HH/Q`;````'```0`4'161DGOWB]V)6@=TC +MPXD<5+OD%/,Q43K6]A;Q/QV.U/.#(#[89P^!\%4,(L^BA7>.4I```DBQ6A(&2[%7V@?9BR +M-IXV?J5"33\_-7@I'#J9C+8=*3XI```<``!`!,&RN5-1Y[V2&I\E$%M4X'HH +M/Q`;````'```0`4'161DGOWB]V)6@=TC+8]E1_3Y5X'+>4P%5.JD_()*0``)&Z17>7J='JFMX:N,&BP>NKL(U71 +M=;A#G[H*ZW9V6"4B*0``'```0`0ZP4OX6;;F"(&J5Z;;*`^L)W#Q8@```!P` +M`$`%H!:M=\29Y'\^T3B<=R;B(CGN/N-/$K=&7Y`$``P!```,`0```@```$4` +M`0A360``0!$``,"H`0'`J`$"`?0!]`#T!]G0CK6H+'6A0?"!!-%.RY%T+B`C +M"`````$```#L(P``T.@%9)D^V50[.IXM>S647F3GT,N%K5PL]C8M=0KYPWC& +MWA:$6/PL<>DA"X:".K@KRA,W2;)!Q#@BT'D50>CR#9,)CP),@#(%_Q:RFE;C +M!L,UM/?=(4(*L38_IM[LDORKK1.+E4=FP,F`+%_B?T=:61K@&,9I6+*2S!<< +MG4%N$*!J%OJXLM*;50!%C'96@L%2@E!,P')K_XOK`;@&7/D--W_'+"L:FBRF +MDV-A8+&6G+[Q4-N;#&]&=)8D#M9U;Y2JOR5]D-Q4V?VRA_`<#D\2MT9BJ00` +MO````+P````"````10``N%-:``!`$0``P*@!`<"H`0(!]`'T`*0&B=".M:@L +M=:%!\($$T4[+D70N(",@`````0```)PD``"`;?EU`R9K8._!^@9?G>C)P=(U +MGRWV@O^-00M/HLDPN%<]S]+,PZ8^DAH:8=/)(/+MT@F^??P9G9)YT7TK4X/5 +MD>N_>/"`Y,>P9/ZZCZ&0SP+%@N3BX5$$'AED+SJ!LWX= +M'K3$/#GN)AQ$X3"%AM>X3D\2MT;?R00`'`$``!P!```"````10`!&%-=``!` +M$0``P*@!`<"H`0(!]`'T`00'Z=".M:@L=:%!\($$T4[+D70N("0(`````@`` +M`/PA``#@Z&@7K`S?1W`UV,5`346,HX[_4)6)\7!5["Y?`:!4UXM/<4C)V0/X3P(_J?J^)[$JO0(W +MX3N_1_/D*&T%.`$\;SGX+EB6ZS0\F8QIMP1^I*F\-XI1N'*L#@\"$Q\A(?>= +MR[CI\=``!`$0``P*@!`<"H`0(!]`'T +M`.0&R=".M:@L=:%!\($$T4[+D70N("0(`````P```-PA``#`%P6J$2;6ZPN? +MW8^0P9/Y;5&F9%0,V;#V=&9)EV:(J+6N)U +MS)Y2WP>Q!5B^C0$U-=$C=J_X\SB&K&^V4?NIV'/2![^7L>;V;;L;UE#89?&) +M&9Q"S"`,--1%U@!%"?^MDJ5[7X(PE.(,N8DE7OWH;Y_5P69?Q'2PO]P+538[ +M+X*^3V`#$X^>9[#5Q%F(Q^O@NELR8NT#=R^GGY;1;+8*P8.T8-3RY0Z9$!!/ +M$K=&Y]\$`&P```!L`````@```$4``&A37P``0!$``,"H`0'`J`$"`?0!]`!4 +M!CG0CK6H+'6A0?"!!-%.RY%T+B`D(`````(```!,*0``,."%W`%5-5[::90!(U +M$@T'+?\V[_DC,\XTEP5II$*\O_`G#RO,3Q@K%<@$\)8?[[;)(=PCD3C +M*^X]U(L5>E@.V]LHU3?V/8@8FR29*8M`D11O^V+D_+MN.40J\T/$)KCJ6,:? +MZ;T14-S[>KPUV2=<_21/(V3A85J4E7TY#,R9D=VQDFZFU<.T9(YCX?]OG'7R +M6W'30&*"BG9^>0OO3BS\O$\B[(;!3QA1#:*4F-Z2[*84("7\*.54&!7*L`%^ +M46<9O'EQ<9*NC.E'KU'8;(=):-!.10()"V/P2*0A]@X2\78SK]=9?@P[BB`R0K"FL!:MM_53W:#!(B3Q*W1HH< +M!0`<`0``'`$```(```!%``$84V(``$`1``#`J`$!P*@!`@'T`?0!!`?IT(ZU +MJ"QUH4'P@0313LN1="X@)`@````%````_"$``.!5`MHP1;Y7JZ>ZK +M%BA\23M,-"*UZXGP`@(!H`>*`R8L\"D'Q=4UWX,RCT!0.-:9A-;Y8%CT;K&T +MEE_L"3`#G]6]B(%WP.L-H'!T(27C])1B\PF?MDKTL"DH?K%Z.C)YA]U-[V-. +M)TXQ)HE$00FFP`2]9VB;B:(/RM+7B@D_]9_2@HVO"MO;(?&ROL*V4BNZ\$[Z +M!5XP(B-Y'6?+]X?[[CX&QM7QV";&-3Y.>@C/ +MH%<*FPIV7[AS;ACK+R1ZWD[OD+>.M^H)3Q*W1I`S!0#L````[`````(```!% +M``#H4V0``$`1``#`J`$!P*@!`@'T`?0`U`:YT(ZUJ"QUH4'P@0313LN1="X@ +M)"`````$````S"$``+![Y"+>M[MZ7T'G;=AC5G[J@=H?1A\7)KQ,C2@&*/.# +M0`\*/PA[VW#?*5%XO7_1TYO/S_TL'5E:$L*ET^ZP7RU\2M=\*%`,;)I(]0C, +M6?76+/`^_E+JWMZNR-Q?4KV5S3OC,XA.917X/.L!:-U5(DLP'@S)R/24`3>6 +M][-L71!3.L="!Z?8XM_.P)/:$P,2J]H"&;(]8<0)FIB^E895C1JDN-SW0X_+ +MJ>:[*T/C3Q*W1J96!0#L````[`````(```!%``#H4V4``$`1``#`J`$!P*@! +M`@'T`?0`U`:YT(ZUJ"QUH4'P@0313LN1="X@)"`````%````S"$``+"X,^]@ +M1U2C&&J[NO.9V6^'EG9M?Q&-H99+<;/T@KP0Z+9Z;L0?H4L+#\OW31V7A4ZI +M@X8G9]XG#;Y`P<"5+P%CU:#+)C#@>-BR?UF9?I$-O>,LNFY#X+RJ]]("J-]P +M+APM;>(R8I;&:0HT)^`=LNQC2V8)L8QPTO4>'@(_YW_QR/JS-= +M!THJSX[(+"6>E)'&`1*IY]HE)OS7_L9:=DH]72G%`12M0[&H0,*+#1Z/>W>T +M5-'\[G*&J%IJORWJ8C[;&?8\;W'UE#LV]KD"^([F974S%.D:IL&AZ*MU6Y)& +MO\AV9`N?Q+J1H!`#"^N`2_$]T4$Z(95$;O1_BOSFI=#/.6<&1XNFV5LOOCZ8 +M=GI8._)/$K=&[G\%`!P!```<`0```@```$4``1A39P``0!$``,"H`0'`J`$" +M`?0!]`$$!^G0CK6H+'6A0?"!!-%.RY%T+B`D"`````<```#\(0``X,PYS4E/ +MUCJXN!(@2QET&KK$;1\`I'!^TA=,VO>Q-G;?#;+BV!/X`%E@9@(6&?H7'(!U +M9U]4<'WIY!B9WV.;^^*BQ#K07(WF"(8[ +M:S@1'((_J]2EI\HH\RCN`H1=6G,G+_TLC-P]'F[SD'_@`+"4%F!P5@MQ#?6@ +M`@3CN036:8($^)C@@)GSBWV*@,PI&1A,9@L\&V4,\R+=;3J0[)"Q7\Z\?51" +MVO$XS<8`TO+.$X`ZK)%BE-M'T7>$2Q-?%/58DO]4NCO+G)-_%VJ< +M^S]6^UVG<4,KO-ZX<#"MA9S;Q%O9G)G[>>"S]U`JNO8!)^KM6@'Y%(6\P'Y; +MW&C9Q,K>?(PWU@BOQ-'O]ZH/J6U*0>!""914GH0?)R_^&Q_>V+VV`XGE@F&2 +M'7*34'('=P]G"&HQ])BE/%;4G!<7V(V]&_E,OI]<\!DN)S&S6=D71X'R`QQ/ +M$K=&O=T%`(P!``",`0```@```$4``8A3:@``0!$``,"H`0'`J`$"`?0!]`%T +M!UG0CK6H+'6A0?"!!-%.RY%T+B`D"`````@```%L(0`!4+1]WU.(C3HO4?C( +MB3Q4..\6,GEPA[BYT?J60VB>VOW51:.W94:#2<&`R;<@I"9^<;>LBEU!TV.$ +M&PJ!#1\7V:M5A*4**RVARG%^/V@'YI,I#,#72`%(5ZCH1U:M>.F)5?.Y)$6J +M[CWAPG<6=2>(M,P^)SOV#UQ>E=W:`+5GU,T"S$SK?*QE,E`@G@@;4^\4>GJ" +MEZ-]?F=RT%U`SVB#`1/4%[(&I0,3/ +M@FRMP;:]"]FE\#R.D5>Q'M=4(+'AQ3H2ECU>(G3RB:*> +MDH)64@STA&.$1Z,":3!>/7'!SRQL_%I1^_L7BUU+UCQ9@$K*T=[`#'2!.3]3 +M*Q3H]@W>3Q*W1@@2!@!<`0``7`$```(```!%``%84VL``$`1``#`J`$!P*@! +M`@'T`?0!1`8R(I:8\8S +M'^OYNQD%_#%_!O^<)?`:"3R5:XDS?ZJ\AH#`*T-U>=D<'+[N5 +M@OQ)2V9BH$MEX/V`-V;147*IO1IHO,4GD.(O^B-.P/J"9<\&_=EDKI45_41Y +M4X$]^E"Z083N--#QJ*#R]`6%T`,<]R_!$MQB8DX'V#WO#3V#_)>.8&5-C'8L +M>-/U_8-@BR#=/,!(G88R!U0RM/[\A(34%7=@GN*YX2)%]KS7_P-E\=_%-L``!`$0``P*@! +M`<"H`0(!]`'T`&0&26@Y)B7W?V7T\C7X9IPBR_DN("4(`````````%PJ``!` +MXJ?->+Q:C$;*QO7VE;*8YF.$F'UGBS*/6'I3'09=R.`XM$20"O=74:"2(G^; +MY<".,E`TE6(E#+HS(VFM3Q*W1DU$!@!L````;`````(```!%``!H4VT``$`1 +M``#`J`$!P*@!`@'T`?0`5`8Y:#DF)?=_9?3R-?AFG"++^2X@)2`````````` +M3````##H3M=G`5X0^KM;2VN(&=3-0BU7>.UP109<\A=[Q&XHEH#+D"P2ER)( +MVN^$=D\2MT;A4@8`;````&P````"````10``:%-N``!`$0``P*@!`<"H`0(! +M]`'T`%0&.6@Y)B7W?V7T\C7X9IPBR_DN("4(`````0```$PJ```P,,H-/"H! +M5)WLK.[C"[3E*I7YK5.Q$ENY>@6!57P82@Z#N`!>P?%RS.0SX0Q/$K=&(6`& +M`&P```!L`````@```$4``&A3;P``0!$``,"H`0'`J`$"`?0!]`!4!CEH.28E +M]W]E]/(U^&:<(LOY+B`E(`````$```!,````,$_N<4SBDFQ[:3IZ#%%9Z/IR +M=2P,<(XIN11T'IQ"(X?=,I\JO!D[2$9<\_@43Q*W1M9"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``VGORFA<#-`SCNT\]A$&MZL%]'*0_@\0%>67*(33U*Z=FPQ!TR$RW +MW/,;P'XP7X8NR'X0VR/6B01M4F$UL[/D2[N>.G"OO]S_2AJG7HJ#9RF--5D^ +MG)/?&3-ZRB'.)M5P1<_K-2P=IPU?/['/RJ;0AK.7*EYATVK\5\8@O3=\12XI +M```DDJ%>Y'!1TL%/JHDE/U"4>1-DC#&Z?Z/ED7(.??HL:L(I```<``!`!$JF +MD['*(8Y.=7TLFZ83(SR%;);L````'```0`5_AKCSF-%+NN!UOZ"Y)DWE31JE +M`4\2MT:^:P<`7````%P````"````10``6%-S``!`$0``P*@!`<"H`0(!]`'T +M`$0&*7$>@-/1)."S```````````I("(@`````````#P````@``!`!@````&\ +M'Q7.MRI633P-=!B)Z>&TS1_ZHD\2MT8E?`<`N`$``+@!```"````10`!M%-T +M``!`$0``P*@!`<"H`0(!]`'T`:`'A7$>@-/1)."S```````````I("((```` +M`````9@A```@``!`!@````&\'Q7.MRI633P-=!B)Z>&TS1_ZHB(``'@```!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``VGORFA<#-`SCNT\]A$&M +MZL%]'*0_@\0%>67*(33U*Z=FPQ!TR$RWW/,;P'XP7X8NR'X0VR/6B01M4F$U +ML[/D2[N>.G"OO]S_2AJG7HJ#9RF--5D^G)/?&3-ZRB'.)M5P1<_K-2P=IPU? +M/['/RJ;0AK.7*EYATVK\5\8@O3=\12XI```DDJ%>Y'!1TL%/JHDE/U"4>1-D +MC#&Z?Z/ED7(.??HL:L(I```<``!`!$JFD['*(8Y.=7TLFZ83(SR%;);L```` +M'```0`5_AKCSF-%+NN!UOZ"Y)DWE31JE`4\2MT8@-/1)."SI'TCFFL(S\$A +M("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,` +M``@#```"````"`0```(H``"(``(``-<-?LB^]*034@$4(;I3V-QPS;:=<;:V +M39P`A-'5N-7A+L^.3Z0!O>K%X&3G?CRQ?BHAX'H4D0$*]K*!.Y>&M+7H,."'+ +M7NOIM_BE7M:=_2SK7/"_/G?#1(,AJVD?:.(Y*#MJL-^#!.:?X%0A7B[)OG%Q/]^=4G$L,;KXN +M(KW"I&>XB(*`U[93K;-S0Y#.+=L)N>FNS!\A@A$&M:SYGDK5&^<"MSOPM2I+ +M['#$3<"F>=*4L>GB/7>MH##=:_W,D1P<2DQ=]\9KGT\2MT:;YP<`O````+P` +M```"````10``N%-X``!`$0``P*@!`<"H`0(!]`'T`*0&B7$>@-/1)."SI'TC +MFFL(S\$N(",@`````0```)PD``"`S>J!'F%1'D0`]DM&YHV'1G*\*HK08;FM +MFXSAW[8UJ%!)@-^)&,];+:J9R_B1CJ+XV;0%D-!!ODX[/MYWH%!"92PUBI1% +M47&[W.WFCT"E',HRJG0WWK,AVHEB9<;3WG9HUX";V/I:HVYX?+=WM@KX\BMC +M/ARHC.UW=)G3+4\2MT;:!0@`'`$``!P!```"````10`!&%-Y``!`$0``P*@! +M`<"H`0(!]`'T`00'Z7$>@-/1)."SI'TCFFL(S\$N("0(`````@```/PA``#@ +M.E+7ZD&!^_\MZ^?;GG"Q:G3GE#'8VV1F^VQJR3\4S3-XQGYR+X'9V=_?%EDV +M9/S;_F:V#"CM)/UDE;1Q0N'DG8`':,3OH"%QH\O?K"H@=/RMTC:'+,==X/3# +M*@@P9X-FKRW<832][(4B&M5Y`:)O]T;3MU*E,2G,\/:!K/Y5(H.?^*[HV-V0 +MX#5["47$_)[W=MI,P]"G\YO9F@.ITZ6/1PU&9.>2ASA;#)'5KPPN4(R%M7#O +M3:&Y+\A@[RKY*9*^=F;P!:0BJ(G#]AT62YWVGX"9K(/L[*]@ACN6^D\2MT:A +M$0@`_````/P````"````10``^%-Z``!`$0``P*@!`<"H`0(!]`'T`.0&R7$> +M@-/1)."SI'TCFFL(S\$N("0(`````P```-PA``#`BT\T<+:GB*/<.FXNQV

7*VXZJ$/L51B +MI`#4)R4VH&3RKQPW7".FM_3ZE4I1?I>"#^];*8LP8V-%V>D!ZD8W(5@3Z@E> +M,[[NB1?7YXMFD$EK'40&%>Y@%[PT5"\]DY/\4P``0!$``,"H`0'`J`$"`?0!]`!4!CEQ'H#3 +MT23@LZ1](YIK",_!+B`D(`````(```!,*0``,.A29%LQ,$WF)9\OZ:`C/FUD +M1T2SKM!\9X*H%4F!^76[Q[^.E5UB[$5:7/W8ZWHU@.2N7O,Y#!(! +M3%V%>M1@1^4S1TO&TGX6TT\2MT824P@`/`$``#P!```"````10`!.%-]``!` +M$0``P*@!`<"H`0(!]`'T`20'"7$>@-/1)."SI'TCFFL(S\$N("0(````!``` +M`1PA``$`[1=="0Y<,T\5Y/`/[&_U:_H:_K@CR;1LQ(+ +MKKP3O]-[^2()E?U6;'S"<#W^0HZ/*ALH`_SI_@QW;T#PFA$#BW4@Y3;6>J$% +MNN$@YZ^-9_&,$>@S(\2I6FUJ*G;#04QY73^KDBOMO93I;&J7=H<'A& +M=E<\N^AO!K^&3;3FX1JGRCD%%9%Y^$[\(KV_S\-0O_KI3Q*W1L=>"``<`0`` +M'`$```(```!%``$84WX``$`1``#`J`$!P*@!`@'T`?0!!`?I<1Z`T]$DX+.D +M?2.::PC/P2X@)`@````%````_"$``.!;C6M#3C%TIFCMR@5]OC;M:BM=2FYY +MGJQ)EA4MJV#>Y9E)4*\"4Z:1B+L=_TY3TDS?K;P?*0W7];L?2[/()*>GTA]W +MW8$4O5+XJ?7$:"W)6SE&O',PQJ(<%(C +MGJ=JH*AN_E(FL?VU!"A*7(\F3EC4KM28/=X65?C27,K!*KE'_S8\:B0J>,E2 +MD73\%".RQOVOH6WK!,UQDC2`3Q*W1BEN"`#L````[`````(```!%``#H4W\` +M`$`1``#`J`$!P*@!`@'T`?0`U`:Y<1Z`T]$DX+.D?2.::PC/P2X@)"`````$ +M````S"$``+"[BD*'*"14.I0^Z;F^HA[<;GK\Q"W7F%^=$6M.5+5I$*,5_QKM +M]_2^P'X5B&-5JEWQ9[^<`\2)F@+^*[88[R^_H[`XI?(6^?ZC<[/8SF^%6^4O +MG/=GH6WVIT:H;ZY4&@T/@RLX9TI@`BK!S?3M58,()\!GL49D4HP\TX) +M3Q*W1@Z1"`#L````[`````(```!%``#H4X```$`1``#`J`$!P*@!`@'T`?0` +MU`:Y<1Z`T]$DX+.D?2.::PC/P2X@)"`````%````S"$``+""&]$W*E"F#2,C +MX+")("V]^R02/XCR:)"G$>1>0FYL@E=6VO'9)'.=IPBCDH(TKBJSO"US.3&#'?8"K;%;)FYR"UY*/ZQT:,T7YIB/=*^+NN]Q34#C5(0R14J&%:?=(7FBO3Q*W1ERN"``\`0``/`$```(` +M``!%``$X4X$``$`1``#`J`$!P*@!`@'T`?0!)`<)<1Z`T]$DX+.D?2.::PC/ +MP2X@)`@````&```!'"$``0"\$U<[J!ZW8;EG^-:EC_PE_;.J>VRY?R(3:,;# +MYVM/ER[,^7S1\M?9$#4:=S!)LJ/K]*O$#80Y2]?HJ2CC6-*C!P'"V$B,@+B_ +M5,X=N\E(Z-EO3K0VN`!,Q*V +M)(7G[MF?PU@P'^W=#CP%*^_%FA8S=U;D7;WJ!/OTGY_"=?!V4BL;>Q01\#N/_;&VK;0['R[UZX"7Y +MM4,UW!!K)'F5@3S754=1;?Q050O;309I=X_Z.19,D/9':=$-'EP#2&+QP(UKZM6H8 +MH^EHMS3=:W4:J)].5YQ33(L#XI)$-G'F?[P@X;3_NW%;G)%@UUXE4 +MQW7%N7!6)NA'G=9F/`J"=`\:]#J0CH1-/$K=&[\D(`.P```#L```` +M`@```$4``.A3@P``0!$``,"H`0'`J`$"`?0!]`#4!KEQ'H#3T23@LZ1](YIK +M",_!+B`D(`````8```#,(0``L!,G^2RRAFQ\/UOB2.2#JZ+W0?W<^%2"WJOW +MK?KV`5CHF3*)0%>!0:L^Z<)5\3T-S[KLO(M7?\Z(0%JT\PRC1C:X8ZC3@=_0 +MZR_`+2QGH\H.)UB\PY6,]&L`$\[[3P%5&/BQ,5#,9GXLA":;L!!,:M;U0@0? +MDKEX8EN80UX%1`@-D,*&<]T(39URC7$)8)S.1G^KHDUL``2WH*PE,K'WU>WQ +M\.R@D9RBC@O%4EE/$K=&U.P(`.P```#L`````@```$4``.A3A```0!$``,"H +M`0'`J`$"`?0!]`#4!KEQ'H#3T23@LZ1](YIK",_!+B`D(`````<```#,(0`` +ML#$W@0BB[38C3F*%-/Z>H8)`-A](G`2=O)2B]-E(8H(@TF<6Q>5C6H69B/G\ +M_3]3NM>7H[[&`O/^5XKDNW?RU@CCSH&81NDR"&60.!`2#M+U9CX_6-=3W5&H +M%BXZ?7&60;^#=V0LU_9QM+GF3)X\.`5<].'*`:BK(Q/GQA)*R2BW')'QFA44 +M2YI'>TJY=R:WBKW=-$X*1*'?HA06>%M;7OUB&_BU2HJEO"1 +MU2%)<_[YE0%T+>R85MX=`W[^F_G"4T08YRWA1`*7UP(PDPL>N!5_;EZ17A5V +MF:/%O>&GI_N]"P.%#(RRW_RTU\GFNFKI=.HF5)Z +M$206_!CF=4);T< +M3Q*W1FI&"0!<`0``7`$```(```!%``%84X8``$`1``#`J`$!P*@!`@'T`?0! +M1`B +M\)T);S)@3_Y&?4?.&`.TR$!W;`1IZ#6'1:DOYV(W;;']&:F+[\X@F=>$TSRO +MJ0^S%@#*JS5$].FR9_1^)9NC9"2D,/K9C=W7*GZW0DZ32=A%S%7VEY/<+)VC +M39S.K2G_8[O@YS11:LV&J@%B[JG[$&1E)%I:\RR9<86%C0MUCAOS+>X(X'M: +M0,L0>\*_(O&F'E(9[?R>+SXM9QK`_`"--?\#3AG*-,\DYB[P>YAG*OD36*GA +M"H;WO_[*VWV>TK+BXVZLR?E1EH+TAD#GZ"A0<]KR<,*B8A11QWC!X?@8TCHL +MH9$"QC-:9.QRQ?_ZK>Z_*4_A)H0$2F10*+AQ2)*L'R368T]I"S/>.-?J91>8 +M&\$)\$\2MT;Z;`D`?````'P````"````10``>%.'``!`$0``P*@!`<"H`0(! +M]`'T`&0&2;T^R.???CWIAP[K26465=']%D;FXAD,5?@HS@*^`D7/GQZ4GS"_^&F +M)[1V,1*L1F'#NM)9195URX@)2``````````3````##9 +MVY^1;M0),2AF"N2D;X=,7J_G//4K*J<40B[:Q&0FKB#B`!H%#1K$ZDZN<$\2 +MMT9VB`D`;````&P````"````10``:%.)``!`$0``P*@!`<"H`0(!]`'T`%0& +M.;T^R.???CWIAP[K26465=JTZ-"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M5,.DH^QQT^'T<%T8O/#NXHH2#V8RC`OUSS_,7FI\#!S*K5&5[IG+"!O7D`5. +M)D,*-X&>[`O8D^*%%\F)*/.']38./*PI+OG; +M*%0^9C[BMU0\&<'O````'```0`6S;+I::7 +M5$54/I-P```````````I("(@`````````#P````@``!`!@````%>'@52##WM +M=\ZU*S.M2QRZ%,3*\$\2MT:,L`H`N`$``+@!```"````10`!M%.0``!`$0`` +MP*@!`<"H`0(!]`'T`:`'A>:75$54/I-P```````````I("((`````````9@A +M```@``!`!@````%>'@52##WM=\ZU*S.M2QRZ%,3*\"(``'@```!T`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``5,.DH^QQT^'T<%T8O/#NXHH2#V8R +MC`OUSS_,7FI\#!S*K5&5[IG+"!O7D`5.)D,*-X&>[`O8D^*%%\F)*/.']38. +M/*PI+OG;*%0^9C[BMU0\&<'O````'```0`6S +M;+I::75$54/I-PVRS@/U-7JZTA("(@```` +M`````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```" +M````"`0```(H``"(``(``$84=(H>9"X#/0'SK6_G7$$Y'R#%\(I%84+R%Y>P3N`4&RVT(9"S>8&&8.=,[U4@/&M>R,_]S'I# +MUI4P<>+A+QUZ,G.[;"J"LKF;?-!O[I0@81Z67M06C.L$G+V>7<(6T;+Q< +M*0``'```0`3@4".[57FN:U\-MZ\9]0# +M)KX5GW#\[>7;^E;#>N/"01/C3MKGH061,H:_&2KA)/[@@SO0H4$3H!5@V#K/ +MNH@-`BJ(L_'6R[1Z0=]L?K/U%Q2.<5R#9`SD`?S1F,+8=$SR"JL"[FN`')]? +M-K5L#R&%KJEF4N>(\%AJTH4<]$'H?X`IX5/ECO,!W]9(F5T"LR<&X30(\P*V +M/R_GWM#E0#G+YW\?V,'O:4NNZ%Z(5**2%4\2MT8/'`L`O````+P````"```` +M10``N%.3``!`$0``P*@!`<"H`0(!]`'T`*0&B>:75$54/I-PVRS@/U-7JZTN +M(",@`````0```)PD``"`.K^KXP6AZKP8>D6@^?9.H;I:P1)9Q-""/\'0R$F9 +M>^FC%K[1$2L"@W^`67&S```!ZJ&%<^F_X/GJ9R<\!$0E;&Q6AP>LKQ&]V%%1 +MY`7#B+H?BDJ92QJ\HL4-N\'8$"WR2>'02I$:](1(-\#Z\X)".F%X:J2JJFF_ +MJ$[/?T\2MT99.@L`'`$``!P!```"````10`!&%.4``!`$0``P*@!`<"H`0(! +M]`'T`00'Z>:75$54/I-PVRS@/U-7JZTN("0(`````@```/PA``#@0/.H'<`? +MCY1G,)V*(H($B3HR)X\01:=&B)`/F,JNQG,PKAZ8L>MP3",O/SPWT2J<0:O$ +MDO=\"N?M4IB\/47)AWH$='8A#UBG#F(C,&Y`:75$54/I-P +MVRS@/U-7JZTN("0@`````@```$PI```P7H;N\BF>(9>N1<=?IERD>@G11G`W +M/#%:BZ_SI4^R?LH;4"EG@Z9FH_4CC^U/$K=&VE`+`/P```#\`````@```$4` +M`/A3E@``0!$``,"H`0'`J`$"`?0!]`#D!LGFEU1%5#Z3<-LLX#]35ZNM+B`D +M"`````,```#<(0``P.6*QE@(M1*Z=D)V(:*/8A$1C]CK<9C3GE?I?H9;ZQZ& +MUJ_/B'F)"=D'*]7MR/]IA3)?PB]'-GY56UCF6ZD26\*;^/8L0T69Y]BX31#F +MD;2N+:AVEJ?:@AM1GW@R!ZXNQ/;^C@'SB?\RZ,M;F8W+]Q"T=\)[),#D!Z&Z +MPS]E2T2?,27!WG&/Q5F6V*UF(-9/BL+M73D9O;?4\R70<[%8&\L,\\-KB,5P +M,C,2A,*TX^)^$+3##ZA7(@J'"[PI3Q*W1H9L"P!L````;`````(```!%``!H +M4Y<``$`1``#`J`$!P*@!`@'T`?0`5`8YYI=4150^DW#;+.`_4U>KK2X@)"`` +M```#````3"D``##_ZX6,6T,!NQYEN@C+*;_WTL'7J%1(EX9AYCZ&:P\(JMBL +MUF)O_&Z`#R)R9$\2MT;GA@L`/`$``#P!```"````10`!.%.8``!`$0``P*@! +M`<"H`0(!]`'T`20'">:75$54/I-PVRS@/U-7JZTN("0(````!````1PA``$` +M6V(![]C+3;,L!57M8Q`R8R<>!]@'*+8!C_<-VX,ZW&-__X^F;,B!\Q080^DF +M8551<'?^?,6KJ? +M$XV1ZJ>33G`"+A*R\+)$H&&U>^?X50"8X(`LBW;\>S:*IDB6\:N'(+3>#.?( +M!X$!U3K]G(^@>*ONM?K]Q^=KESA +M<>$_"?->(T',G`$KE^^#F!2^")$[E,)+D^T.:I(HP"GLW/0:MAZ%$S20#B(8 +M5PM=IE'<3FJ>3^4<63LT2LZ]%NUQ"_E<521I3Q*W1I^3"P`<`0``'`$```(` +M``!%``$84YD``$`1``#`J`$!P*@!`@'T`?0!!`?IYI=4150^DW#;+.`_4U>K +MK2X@)`@````%````_"$``.#?N_Z2$4(B/XQN](XK%8`FR6NP]]:3/IWHJ+.( +MDW?WB1E"E+`*?[L"K8''\$7W\`U#3`,"EIV#J:U=Y[F56\B[^XI["`ER71)Z +MR,P(^*%OV0FEZFU8H8HE$GVO$*2C3XE5=,N8?YFRS?+XK&S989Z6O#DR7M7"?@-#,V_&D4LA!]^%/G@7- +MC41Y^K\^;3IF@[1K+I:D#"$P/T,3Z?=@7-5A^ELA60@O@=)4SHU$\AU(PUEU +M34+;+029>M;"GMLL3Q*W1B^C"P#L````[`````(```!%``#H4YH``$`1``#` +MJ`$!P*@!`@'T`?0`U`:YYI=4150^DW#;+.`_4U>KK2X@)"`````$````S"$` +M`+`U&Y,BFPCE^RAR'^'-"HF5]-:A>D-V6__U$7TRM::<'>VJF-^PFF0'-`[_ +MRL&MA*\BJ$^26NO*X*_0"6T44H7X6KCR8KY\DDR+MRI732U`;6KK3W2V!D#K +MZTY,W@`<,`>8+&9UE=)G/Z\/]9'/PLB?X^&X_7?$.EOA_-LKK2X@)"`````%````S"$``+!X$R+M(\D;T:#,D\2YX8)L +MI)'I4"R:C)XEB.YS]37"1[#6A9HE>^`"H]FQY\)YPS;\*J?J9F#E*#_J3T\783ON +M??,[Q)AM2487OE6\>RYF;*H.NK;;P+>.A7);*)SM=HVC[34:Z(XP`GW +MZ/4N4<:@?1,")D!,;/B7+WO2+F+@3Q*W1N+A"P`\`0``/`$```(```!%``$X +M4YP``$`1``#`J`$!P*@!`@'T`?0!)`<)YI=4150^DW#;+.`_4U>KK2X@)`@` +M```&```!'"$``0`WF$'Z:@%P5RPZ/4K)8ASJD6FSEZT3R^$B#X9KMHL+Q!.` +M]KS^N#K4D-X>A,/7-]JU)JH#'!WX9$'[+O#A?U\N&0CK@4(4%!+)9HLR"^-? +M#D2^_9D!68-3GFZ>J2>B\7I&_:[?*Y+-4EBRC>@DTY;0XYUF%"\*B7J/)OH@ +M3!++;/X8?QKL8L7HS>GN8(!_+P#I)B2(CG+BF[DED;W(I&*UC>2M4%'4D!@N +MU==5N_;[E'OKHW"2%W.)^L9-2.+\[B"P&)3SZU72[$9,/\O5SNAQ&S.T#9%R +MP8.V'L)JYV&9I+3ZWJX2YM[8Y#@O2]D?9%R>FW>2&8`QNV\Q\L1/$K=&Z^<+ +M`!P!```<`0```@```$4``1A3G0``0!$``,"H`0'`J`$"`?0!]`$$!^GFEU1% +M5#Z3<-LLX#]35ZNM+B`D"`````<```#\(0``X-'[Y=4>6WS-9072DF6!/"QY +M! +M^4?(!U,2RCJ=25?@R/S?KMF9*[`.B@P.@&XX\RY874)^S[E_?7#;:D"/(NSO +M2PW$%=D#OF.9VM7'#Z?'#D@IW?""P%5/$K=&=/X+`.P```#L`````@```$4` +M`.A3G@``0!$``,"H`0'`J`$"`?0!]`#4!KGFEU1%5#Z3<-LLX#]35ZNM+B`D +M(`````8```#,(0``L+-=:-<0*MF6PI-H,C-C`")F.&^U7/8!A\"1Z/4$3Z.P +MX;(>C/UDG4&B@TAQ:EF(C%3+&UY"\+]\-&NU)T9*3'!6MVTL+A8OM,%S[+<> +MS)JBOR7%*G4-%W1?85)9>((@WC/1I!N3K1K_BQC_@MKZE7=E[:=^E[JO;*7: +M^MXN.?,B'*GX83J8L_\]A0U/5DG_CXCK67QG4O!J(X+QZ'.`+(Y(XUC* +MH2Q6XH]/$K=&/"`,`.P```#L`````@```$4``.A3H0``0!$``,"H`0'`J`$" +M`?0!]`#4!KGFEU1%5#Z3<-LLX#]35ZNM+B`D(`````<```#,(0``L,='?WY9 +MBQK*Y*C>-.6$G/M;9%A_%EH2 +M;>K^W^I5TL>89'(]X^@%-050RW<_^)W]XJ,-<6[[.2*-]1J +MTLRM-79E!ABYO=$(_BG>\^/5HI_*LKJ(%XU7J(X?#!^OQ8@,@X3J1.TIU=>< +MU>^^`9$?.3%M8A`&(%B3,2T"L>:GAXIAXAN!"O6B4K,0#BE_*/A\_JT_ +M26=*?ZEI=4S-,782L"`-LD4&1@$"[BJ;"5A1'*T:$>2%QX^ +MT@\N#O*PK)$,:!H"C:Z)U3^M7$)KXO^%!8\_`^`0ZJK=?W.D?0X0E29VJF83/!IEU04W8MJB41?T3.RHO6=/0S7GY]-U^U%:095O[,I8 +M`O"@'.(H8KCA/`)6.KK2X@)"`````(```!/"$``2#IOY+,2E\=U9Z-BW]6OWYY +MF6/`?PU=S;5(82R^),-:)(!6_`7[_)>8)SG3@]^O]"NDE6>&KBL6WXTZ>_*> +M-=.)EIV@[74"!JS;HSGR*Z[_C!+O?CHR:-!+ZA)P,#AW!(RIY9>,Z?8*-4VH +MPQEC:\VKV7)LR0:IGZ?*SX`A8;4;G+VP]*\=IEM2[]'5%O2,[4\2 +MMT;[H@P`?````'P````"````10``>%.E``!`$0``P*@!`<"H`0(!]`'T`&0& +M24I/(Q;6AST44=U!Y4FZ]G@N("4(`````````%PJ``!`YPS%X8PFF*].=XCX +M58H#4XTRPH;PJW'$J(SPP<7;_NWF`<>/VJH-"'==$?WLBW[SG7S8[A8DL_<$ +MMYKC3Q*W1I&N#`!L````;`````(```!%``!H4Z8``$`1``#`J`$!P*@!`@'T +M`?0`5`8Y2D\C%M:'/111W4'E2;KV>"X@)2``````````3````###(@U,4/G_ +M6:C6@4_#;@L=%WB17T_SL$@X5)NO9X +M+B`E(`````$```!,````,$M`-0LBXVTR2Z>O6^66@E^D(Y6/Z82"@9I@Q>`A +M;3F\'$VDJ"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``Y.K8H_VY +MNY088BM+EPW;HBU$7`U&"+#F%*$*<&^CEGU,"U2MMOOG#6+]1%%@$7I.`(9S?F`W@^Y<*GL]QQ<9B3[FRT?1OSJ^4:-.46NW(K<# +M-4;40%KRT0J==SE"MY+(O)=+>GQJMZ^'=B=*_':AL@XI```D'$,[S)=63F`? +M?R'-@$*.M>"\VBAV6WYEGE,6B'R0>O`I```<``!`!#]SE*Z<<64(\EIU%@$7I.`(9S?F`W@^Y< +M*GL]QQ<9B3[FRT?1OSJ^4:-.46NW(K<#-4;40%KRT0J==SE"MY+(O)=+>GQJ +MMZ^'=B=*_':AL@XI```D'$,[S)=63F`??R'-@$*.M>"\VBAV6WYEGE,6B'R0 +M>O`I```<``!`!#]SE*Z<<64(\EIUJM_BB7>VH!`'E +M:\D.MIZ=50]GO\DG!;(XSD%0+;',&%LF(,3"%!Z*%+;]7^!JBKI[5\#8A&5Y +M.:]B*0``))8'$**#@B`S^*KH_TE=^/$\CP?):^J_Y3(V54Z1=C%B*0``'``` +M0`283#B%\PW.5F&::6,AYS%MS0OW8````!P``$`%\]89%;=K2H,=#)SH_#H8 +M:"4L4^M/$K=&OC<.``P!```,`0```@```$4``0A3K0``0!$``,"H`0'`J`$" +M`?0!]`#T!]F5)`I@IF?@OZO8KB$<_[':+B`C"`````$```#L(P``T*56Q(L6 +M/E[ZFAF5)3R*R@;^EM3OJ2I`LOGV^!!(&:BOOH#9.S4+)G`=:%?0Z\\R_7_; +ML0+Y7B-C52]@3.:RTC<0J&2(0',"]*#M%>GO@\D33(5^T!'E=O#5K^_@*T%N +M$*L7HA'T23%;/'4?#]?*&P)?&$NY\@K%'O/#P8P1B`>"A%DNF +MIMH<"NT"YH/IZ;X\L(7>TT_?3D\2MT:L4`X`O````+P````"````10``N%.N +M``!`$0``P*@!`<"H`0(!]`'T`*0&B94D"F"F9^"_J]BN(1S_L=HN(",@```` +M`0```)PD``"`D0%`RR=5&-P9JP%@9;F[_Q*2HG=X%=('Y`9)DN$8"\O3_\GQ +M+4\]5`7#@ZI.(P,%!W.8LH];02;_Q6!*%7/LI +M;>.L^V`\\/&H[(LKG:ACI$4EH;:WY2F/!O70/D+_/VVMVEB&=)'OD)WZ05G% +M5*$5B\9\"^[F`Q9YBN<"/KF2>;KZI*%XC=C=A\?4\[]W59GED!$W%$20`(DY +MH7G6:_#OHP&3\5DPET0HH\D[QFDM.PO0&OUU^\F(M:D8RJC[>:*5M_4VXX;L +M'3HACL^OS"H!8OD13C]369IJ^'A#9:4Q +MA!R7;L*7WTA'K$$@A2KJ%OV@K6N'A'5+!/._E4\2MT;$@@X`;````&P````" +M````10``:%.P``!`$0``P*@!`<"H`0(!]`'T`%0&.94D"F"F9^"_J]BN(1S_ +ML=HN("0@`````@```$PI```P2*!;S\W":*7U(3UWTP9&AJE;71C`$_=DZOIA +MSP?:=Q]3K$@5BL5&>;?&JTU/$K=&(88.`/P```#\`````@```$4``/A3L0`` +M0!$``,"H`0'`J`$"`?0!]`#D!LF5)`I@IF?@OZO8KB$<_[':+B`D"`````,` +M``#<(0``P$$S3!XE'>*V(@:7.`<521TCW673M#Z`MOTS$OH>*W!X^$SI[4(6 +M?;8E3QG&1O(SKA3;:LM,<"Z]NE^!2&OPE-R1)!XHR(/OW`$H,7"@=C-GM/?. +ME[CV]U;SRH"(-L,,X+874!>#F`"D5+J_E(:6HG0T&OTCR=28O&Z-(#5(*;ZT +MQ6<4WF*9;#]/G!QE?79^5W-JIL*H6N:*3)51*R[%CS,* +M[(&41_=ZM[L>Y-DP?U$[3Q*W1O>@#@!L````;`````(```!%``!H4[(``$`1 +M``#`J`$!P*@!`@'T`?0`5`8YE20*8*9GX+^KV*XA'/^QVBX@)"`````#```` +M3"D``#`J40=PAZ`_5B($7'XMF']'(VZ3P@G_FU1K< +M!:E4KD\2MT:^OPX`/`$``#P!```"````10`!.%.S``!`$0``P*@!`<"H`0(! +M]`'T`20'"94D"F"F9^"_J]BN(1S_L=HN("0(````!````1PA``$`V&'6?[;L +MNB,;07:O`,7CEAH*D'`/X%N +M(TM.+$BXOF7+RV$A\L*N0=[\NBZ%;$>4D<*7&]*Z?DXND]>4PIGD9^67I!IC +MZ3./1.]#P-&&HB.;3:?](*I-F+\^VC`0'5FZQUMF$BO2GL8?G'CVN9?%?"ZIDU +M%,=P.\.C8#9HJ%.ODTIVU;LMFB\E3Q*W1M++#@`<`0``'`$```(```!%``$8 +M4[0``$`1``#`J`$!P*@!`@'T`?0!!`?IE20*8*9GX+^KV*XA'/^QVBX@)`@` +M```%````_"$``."CV>5Z8Z?YT035W-MWG;'IFGG""\;LVLW;H\5_'-EX\[,^ +MB7&:46O'T>8"]T7+*X2,33F6%O-'@EQC+LU#_]<%\"\DZ/:NE'+M;R(:VP"9 +M1D(:GO9^KE]DZ6+>2ZUSG,\#U>-/W+9Z&OA?R$D6<7>Z4N3U:79LU[+*@*_RSF1L\%U>:4:1IG<<. +M4'I7^)K+3Q*W1@G;#@#L````[`````(```!%``#H4[4``$`1``#`J`$!P*@! +M`@'T`?0`U`:YE20*8*9GX+^KV*XA'/^QVBX@)"`````$````S"$``+!%'V%R +M,X;^E_MO@J+CJZ!QBR`\LN*"PC3JG<$U@2X,8?OPXW01J\3B]^=X($(O(4&X +M`:U33A0);Y1'1KN*1@H)ZRJ.B072G_O&N_:(H@"R!DE.I#7LH"7]2N<(PU7T +MW1&/HZGNJSQ[RPU!!I*3E20H&$_FD&!K55%AM&B=NE^#O;/12'R_?DI?9]*? +M#UDXPUEG\2PP0HE`DME\ECI5H-@.*%@GD?7#D6-@G0SE3Q*W1M7\#@#L```` +M[`````(```!%``#H4[8``$`1``#`J`$!P*@!`@'T`?0`U`:YE20*8*9GX+^K +MV*XA'/^QVBX@)"`````%````S"$``+!(+32U:YCQ@OO/+W3IE542`_Q,G2:< +MN&G@IRR49TMWFH0_+0032?=@(]?V3;T6MI@S)+GV?ZL28]/0L=4%&B1(3^J\ +M)M^`*@2>@9]-B3#1%,[3:H'>^/L-I%"KCF,-:,,(\NF%Z7Y(/%#L)YHY\]`> +M+SJ,SMAQX",ZQ)L^_H!C*+"NE<.?IY:*56])D%FV"!\)7LNVU]S3=MEVO\O8 +M^\Q6=_T%A&L/);[J>^K13Q*W1CP:#P`\`0``/`$```(```!%``$X4[<``$`1 +M``#`J`$!P*@!`@'T`?0!)`<)E20*8*9GX+^KV*XA'/^QVBX@)`@````&```! +M'"$``0"\QH;2[H">_[=+5NA0R%./IG):(U[ZZ1A*2EPMA@^48R#PI-=+>K.> +MU'"^(U_ZP8'J_*D"V&R!`N=7?72,(Q*?I.I?F3@%^Y(P%JXI77]RHRYPH3DC +M^KC)6DFXZ>3UM>3WOA>2,/(HUS\0D.Z@1#D:7)6H>"E1?5^7>A=>Q!EI"%-( +M'N?,\2N0'O"N*6^*&A;PLM3HOV[QMCFG56?UB+ZV`[RBA_/2!K00S@G+-$7D +M#@E98NZ,.V.#>UX?-GX:?O18^U/2E9=%?UD/0T*[3KGJ/'MVY1[_SCA%(E^' +M7[2HL3B8%C2+TGB5,08,-HXRR,2?2E]M`&I%<.5>U;]/$K=&328/`!P!```< +M`0```@```$4``1A3N```0!$``,"H`0'`J`$"`?0!]`$$!^F5)`I@IF?@OZO8 +MKB$<_[':+B`D"`````<```#\(0``X"=TRNR:@ALO1B2\>V(V:H.;:'90EH'\ +M+G?&/:*P!&5G@WS6]F?8%U#Q:J4HB^G@IC +M;EMM.'`-'O/CSI&8U3'A2BT/3Z?KMN#"$(J)-LC`V`+;[6^7_?+"=![@MB9P +M^S`(E\"6G4:"SCSZU`3;`.$=G3QE4%\_C!/I=P["*B5O@)+*7Y6?PQR6HSA&),$ +M#53J3(,79GD6;DBRL+3;^\1\B9JR[[+([.0M"#-OC@(\AHZ\%E"33V!CJZK< +M8T@P4;(4^`R?6:#@#&1BX@U4:!!!PT>$Q7)TJ=7T9EE2+;SK0W?JQZ`2*/90 +M$K=&E1<``.P```#L`````@```$4``.A3N@``0!$``,"H`0'`J`$"`?0!]`#4 +M!KF5)`I@IF?@OZO8KB$<_[':+B`D(`````<```#,(0``L&K71#6/=$,VP3"R +MNL"D.UM60"XSR.G93U(J+`%D^:TVJU'*PLR2Z6W=-]D.@[#8)`QL`W\-VD00 +M]Y)N=`6F49#/KN^(\Z%U565-GFVV,9T@K6:16H?7=2;7@V[#6V$/0$[R@"-6 +M(5D&A""T_0XKBH$A;]=CGMT +M"\"LO^MWSC.4$6BC(K[1,VWB2JV'A?P>,(G0[BRPI]?ZSSW*!M'N1US%)]=) +M^VHCT+28TD-%O_&?] +MDDQ8O47.U5VH/7`+&!LH@V^CL#4>FS$J`_!>!%@5H(_2!)[O85)F-!J9*LUY,=7OQ%#X +ML)6:#A7$SH=VJ53[-P9@J5(&VM@Y4,?P"C-$.C7`"D>24A0,R!UM)\6B**!* +MY]3O0-?QHY6=U9U1=_N(E7N-UJR%&!R,&9U]RV\RQ0$6T'\@=G?<(07%(K+# +MX_PCV48?-[8H-I*=F,B8!`B.:X-#G]/X"1['"V""QCB!4!*W1J5Q``!<`0`` +M7`$```(```!%``%84[X``$`1``#`J`$!P*@!`@'T`?0!1`T#S[S6G&.Z7>5;-_S:D?,1EA^*S^9/'& +MU0U)2TPP8`,!/SA0S/09X>+-T8`D/MG]&NO32K$U`2MT;,F``` +M?````'P````"````10``>%._``!`$0``P*@!`<"H`0(!]`'T`&0&2:YWDJI( +MS$J<6*,:0S=N1`8N("4(`````````%PJ``!`2JDC,2IQ8HQI#-VY$!BX@)2``````````3````#!?OZ,QLX-BS=$K`@"P^N;\C +M<^]1&E9*<36MU,ORVX[9A+&,8-%0$K=&3,```&P```!L`````@```$4``&A3 +MP@``0!$``,"H`0'`J`$"`?0!]`!4!CFN=Y*J2,Q*G%BC&D,W;D0&+B`E(``` +M``$```!,````,,'674R:#S0+T5>O+)5._ARF!&6EN8,2\/.3,N%P>T<53%PN +M`E)+C5K\=REQ4!*W1LN[`0"8`0``F`$```(```!%``&44\,``$`1``#`J`$! +MP*@!`@'T`?0!@`=E8@`KP'BG%P<``````````"$@(@@````````!>"(``'@` +M``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``A13.HJSO_E+@LX,XQ."HMG.>RA->50;R1F2\"BBL;8[Y$W7;TM33*>%NV$).E5]5$M@ +M?Z-9,JJ\ARD*CYDM!U8;J_QM2,I```D%)]9358-;)"S:K+((#D^ +MP5VHD]]&6H!I&&JW +M````'```0`4_-JG7,.:G.#6#^>%13%`2MT:LRP$`7````%P````" +M````10``6%/$``!`$0``P*@!`<"H`0(!]`'T`$0&*6(`*\!XIQ<'```````` +M```I("(@`````````#P````@``!`!@````%"#O'+\.TK"KX0KBT9P5[9LO`" +MSE`2MT8ZVP$`N`$``+@!```"````10`!M%/%``!`$0``P*@!`<"H`0(!]`'T +M`:`'A6(`*\!XIQ<'```````````I("((`````````9@A```@``!`!@````%" +M#O'+\.TK"KX0KBT9P5[9LO`"SB(``'@```!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``A13.HJSO_E+@LX,XQ."HMG.>RA->50;R1F2\"BBL;8[Y$W7;TM33*>%NV$).E5]5$M@?Z-9,JJ\ARD*CYDM!U8 +M;J_QM2,I```D%)]9358-;)"S:K+((#D^P5VHD]]&6H!I&&JW````'```0`4_-JG7,.:G.#6#^>%13%`2MT:4_P$`4`$``%`!```"````10`!3%/&``!`$0``P*@!`<"H +M`0(!]`'T`3@''6(`*\!XIQ<';>&Y?P*E"J`A("(@`````````3`B```P```` +M+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"( +M``(``)H5<^UR+8B_$UF"2;S+6D^A`/0OC7I7JJW99.8DO.#;>QHN9R.*<%&2 +ME)Z-I..H4I(20YY7,J(PJDRB[^ZG`Q\LRA_K19H"X[Z5;1%=L4\(A#]3#Z1G +M`NZ'Y8VUT,W#FV`0IQ;,[_P*]G;,DH-X,`KD*<7!VWAN7\"I0J@+B`C"`````$```#L(P``T*;F!S3^L.$&2X&/ +MI0Y5S3<3)O/BI2!"`:\8)$8V9QT4N<`?`#LI`L]KG/0TH=/"\];8KL@2*-R8 +MY!55)LQURU=!?$G+&4YU0MXJ9[`C&'-NJYO,.T@N*^!YE*,)DX$&4+7GA#=)@FS$UH'7`]\'?<$^ +M`A`<'9`*O69,U4FB!8OI8Y3>Q]E&;JO%6Z&Y?P*E"J`N(",@`````0```)PD +M``"`239[_;-(&DA\FKPN6SF9E^T_L>?E?ALX0-D%R:1H'N*>O@)+'-(M'?V; +MW(7'B8)N"F=PT@>%^'@O]UC.)@SYPE]WI=;*A4;^S<0Q5+NW"\[<4:=?"_?% +M`L8I;8]+2F0A.&5Y"#561_`8<`!C;W\[9_9.WC)]SWI!;)7@Y5`2MT;%8P(` +M'`$``!P!```"````10`!&%/)``!`$0``P*@!`<"H`0(!]`'T`00'Z6(`*\!X +MIQ<';>&Y?P*E"J`N("0(`````@```/PA``#@HX,`>/Y&<,`XQ\WJOH3[^E-3 +MU,)T*G1QNCWJE\*Q=(=C(I*W`8>;?E"J-!YP@_IPA:[$OA()C6BV:'&DU[], +MD8J8VPH^[0>-@?L?3@X_IH^93!9&U7!WM8F=V96YV7;I%"-B41^Y_.5N)Y)M +MZDWBD+`QA8O/W9!:AQE7X4&JJ0KP_I#[?O3VC#\Q8BN^E9//@CD,L,N8+^3/ +MLL@)DWBN.]IH+_9Y,H0$>G@-`-[]VO1I43-A=$DD-%IU8=*"+*F/M(*(0T31 +MOXM$%1^H.6?#$P@:H"D3ZX2P9]<@B%`2MT;W;@(`_````/P````"````10`` +M^%/*``!`$0``P*@!`<"H`0(!]`'T`.0&R6(`*\!XIQ<';>&Y?P*E"J`N("0( +M`````P```-PA``#`)N/EF_O(";E.X[K2/7<+L/`>'C`-/OD0U)J@Y=M^Q^';YU-YKK9!`[VZ?H-]5VD:U1=&>;"I*A"9-&S#NV;Z@._T([T>F3CQ0(8-W0;67^SEB8J?, +MH/I!EWLSOMN8EQ6@>2SX,8?+]J;:J&;UR/`WC>J4,Q_=AE,9A@*OG]1^HVM_ +M<'0N83CS%DSGC8IY28L42"#;6%Q0$K=&S'D"`&P```!L`````@```$4``&A3 +MRP``0!$``,"H`0'`J`$"`?0!]`!4!CEB`"O`>*<7!VWAN7\"I0J@+B`D(``` +M``(```!,*0``,"([%@]']X9R-B-*CO0_HZ._&*[9Q1"U:3<8!$>C.>35='P_ +MP#197T0C5?XT4!*W1@^6`@!L````;`````(```!%``!H4\P``$`1``#`J`$! +MP*@!`@'T`?0`5`8Y8@`KP'BG%P=MX;E_`J4*H"X@)"`````#````3"D``#!C +M$BJF.,]>"W2J)0R=!:SHFUYD2::$@O]BPUKBW-3)+U`2 +MMT8JL0(`/`$``#P!```"````10`!.%/-``!`$0``P*@!`<"H`0(!]`'T`20' +M"6(`*\!XIQ<';>&Y?P*E"J`N("0(````!````1PA``$`>Y',-OY#*7<%:YER +MHI35= +M8)Y4+GMGP5%4,T;3413P7)D)M"E_7W8H\+>"J-PVF3"5Y0C%7U),#PT +M!9AN(0_Y"7UXTIA=%YM5E]8*`O.>$D8Y:NJG1E30]S-Q%N)Z!AZK,<$)PXZ_ +MI^=(8Y%S@X/SP.XHX@SBFM-O'04T65H(=(RC;B<^)Y\P=$>F=L6W@KE*&IA" +MO:\P-0S2W7'CE6>JC6K\8@>YERD>IX(V>)XF"K6W$WPENBE`(?X+ +ME]VX-!M7:9E5^L0'T"QQN`%?U+DSD<%D-AJ3P]+_'??SF8X+2\-Y84F[3)A0 +MQAB=I@=].=@#2RWCW*,`P +M`)O$K7WN%R]9#]@A-]@IP$W)"7E-0*'XX +MR'VSK1HI41/TOJ$IQFY^C5M;]9>!H)G>LP?/R3<"?&OOK$7)L',3VV%(;%XE +M4!*W1HW,`@#L````[`````(```!%``#H4\\``$`1``#`J`$!P*@!`@'T`?0` +MU`:Y8@`KP'BG%P=MX;E_`J4*H"X@)"`````$````S"$``+#15=8&E\3X&T_B +M`3"],T^P;BW=QK!86+!)DQ:?Z&2MOO6+A:EUWX1N0J1SBTO;Y(^B-R""65QO +M,,G!4$*Q9; +MV:Y0,D?THT2>*5+TZU29S2I2E[F#N,SZR<;P*'S_E^W[,4?D+IZ[(&IJ`/?7 +M/S/=;@ZRY>4A6>._.P92.2QTQWU3'",T=8P?87AI5WZ\?3WUU7K_=[VCPK#C +MT\ML4=(S'WN>4!*W1OD+`P`\`0``/`$```(```!%``$X4]$``$`1``#`J`$! +MP*@!`@'T`?0!)`<)8@`KP'BG%P=MX;E_`J4*H"X@)`@````&```!'"$``0"* +M_D2JD]#%1@>.!\X"6/@X#C)(>>HZ]C5O?C2#$;]E)2--N]KHL>,(VG0\B]K0 +MRIP__T+N@:1$8L1[8!3S/J.H$6CA2-ZT$$JN'##<5]U%RVC<+HDISA7M"4HN +M^Q`FQ^U_4*-6+.YS;5-,:C +M0(QK_9S]A[+O&!QG5.:3L4]]G.AAN]B3]+<4HH*[,`R6#I0SNU3=8LRCO2#ED +MOZIN>361[=^H79TI+8BFQNB?`ZJNU&,I,?U0$K=&#A@#`!P!```<`0```@`` +M`$4``1A3T@``0!$``,"H`0'`J`$"`?0!]`$$!^EB`"O`>*<7!VWAN7\"I0J@ +M+B`D"`````<```#\(0``X.')IBU_4F9&4J0K>[(AX+GBOS9O!T)$'\80#F1_ +M8>Y>(H#=@G\R1?XAA9<&U%VS*\2LHMI'AY44NU%>F`>RN4 +MKY*`25.668C>GQ]HG8R*=BM*3MW=JVU>?>U@K/^)*$(`NR[X9I-6@@\5:V5_ +MUXON7[!,>[U>@\ST>=`^BH9-UGK\(31G,('BNBF8;)_A^-)V(49K3M-.93\* +M).A[(&V6^0ZVX5$8I+*,M/BND_-:9M&2JFO--DC%*[E$QU?D21]$-V%C7_#. +MZ4:=!2P.2DFF?VA0$K=&*<7!VWAN7\"I0J@+B`D(`````8```#,(0`` +ML)/IT$F+.J?&;+G<5:%M,K1_"P@M\,3\/M$K8X>.RIP:G18=H!*<>.N)42`R +MFA,I]:#Z^H3K./]L;I_:\+395W'F%&^7FT2&ST!-2Q>\HBX_IB?4D)@H$LW3 +M*E<$EC^2+>@OLH:-R#<;+Z)@++QY6,H)V22:;JGP/V'!L[@?SH%.XK42SIEC +MA0*<7!VWAN7\"I0J@+B`D(`````<```#,(0``L#6R\[#:HS\YC,1]^>+#+36` +MY"K#;G'5)5WZ(,XE1T1<@T*C4S92%\TE%/=\48GF?=H-5\DL*8$BGYQKI@5[ +M)M@=HY*//O1MZD5LY(7#B;,448JC]3(--%1`$>+R>9F[`>T#OC8O))HHLNW( +M`6[XOI%!]^%OMI[Y%ZEP^Y;VIRN"%QL[OD=0$K=&&G`#`(P!``",`0```@```$4``8A3 +MU0``0!$``,"H`0'`J`$"`?0!]`%T!UEB`"O`>*<7!VWAN7\"I0J@+B`D"``` +M``@```%L(0`!4(H:T-\W-C8^,/)!6!.?_Z4%Z%P*W88I7GHQ"J!AZ$F*LXG] +MKO,WEOYK^?;UR\,9&+/1?6V24.'$WQYFV"['!_N8V;D"TY=4-P>!0`UY6C,2 +MVA]#LD@%8[P%R6JXXR,^=/H\NS.3#LA(`J]H*11U +MXC(4%W!X;MH98K[4Y2E?$202WDN@F<4]8'3(0D?3_T?SE+E4,>!.L1PA(0K9 +M,A&?X@5#WN<,$A`'A4/BJ5Y)3?.=1/M;>,1=.I')Y289@&]%_0V7:DQG0F@Z +M4K(CWXKWLW.T"'/BBP"_U,90+H:.4:6C*8$/UZX_Q^=:AAJHYFBFMIWS[YM' +M4\Y_`.\U'F\&X>0[E>9U.NVS?$M#"(@.$%M6Q-[9O6Z[G;AV,,7FEM:5XKQ? +M79[N/I2D<$N-5$ADL."ADQ&0`4!9$'_!F8PQ4!*W1C2D`P!<`0``7`$```(` +M``!%``%84]8``$`1``#`J`$!P*@!`@'T`?0!1`YA?KWQM>CZU4TWX67N`YG7E=5 +M;@"ZLY1,XQ&1W15`2MT8#RP,`?````'P` +M```"````10``>%/7``!`$0``P*@!`<"H`0(!]`'T`&0&26/"@BU\FIO'\6,% +M66];MI0N("4(`````````%PJ``!`I#A#40P9S[\"[`?>=0MI7\9B1"N-@=Q% +M;6=",I9'HQ/JU,UX:9#I[^H8[\O&E9!]O-?]OE2+>RW8XZ'O4!*W1G#6`P!L +M````;`````(```!%``!H4]@``$`1``#`J`$!P*@!`@'T`?0`5`8Y8\*"+7R: +MF\?Q8P59;UNVE"X@)2``````````3````#`:&=]9 +MNO`%$3$1.5'-,25,@EG![^2PW<=^?TB>J%`2MT8LY@,`;````&P````"```` +M10``:%/;``!`$0``P*@!`<"H`0(!]`'T`%0&.6/"@BU\FIO'\6,%66];MI0N +M("4(`````0```$PJ```P>7"$30I%WE=E#HC#"F%.=%B;#&&@HA$/!AW2"SIK +M!7'EJXJXP.K@S)J?D"M0$K=&1_,#`&P```!L`````@```$4``&A3W```0!$` +M`,"H`0'`J`$"`?0!]`!4!CECPH(M?)J;Q_%C!5EO6[:4+B`E(`````$```!, +M````,.6'.7W=X2`@,PALYKT[(FU<_I?IQ(LF`[FH'X0\XC$ANMGV*$^>0X"? +M/?U$4!*W1IKO!`"8`0``F`$```(```!%``&44]X``$`1``#`J`$!P*@!`@'T +M`?0!@`=E8KMZF;L4_/,``````````"$@(@@````````!>"(``'@```!T`0$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``D6H^(?'2G0$%YK_3TC\?M$);E'-S]*_RR'GQ*I3FJ7F +M>F0>D:R^.L>`U/`D%!*ILT* +M0&OSCBDEWEZ>/N7,A+83ZQ%,Q_(I```DL8YY",80]RX)3I2*=X)2!Q=G",FP +M9I$K]-0XNH"4*3,I```<``!`!/YIF[%/SS```````````I("(@ +M`````````#P````@``!`!@````&BT/3$2.$Y,T5=4S<*ONB#SC<^\U`2MT9# +M#@4`N`$``+@!```"````10`!M%/@``!`$0``P*@!`<"H`0(!]`'T`:`'A6*[ +M>IF[%/SS```````````I("((`````````9@A```@``!`!@````&BT/3$2.$Y +M,T5=4S<*ONB#SC<^\R(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``D6H^(?'2G0$ +M%YK_3TC\?M$);E'-S]*_RR'GQ*I3FJ7F>F0>D:R^.L>`U/`D%!*ILT*0&OSCBDEWEZ>/N7,A+83ZQ%,Q_(I +M```DL8YY",80]RX)3I2*=X)2!Q=G",FP9I$K]-0XNH"4*3,I```<``!`!/Y< +MM[_F+46'4TP_B`Y\U%KSZ$*9````'```0`49R55[(K4A\XH?DI(\!?.!;^*N +MH%`2MT8\,P4`4`$``%`!```"````10`!3%/A``!`$0``P*@!`<"H`0(!]`'T +M`3@''6*[>IF[%/SSW$O,Q`FAGYPA("(@`````````3`B```P````+`$!``0# +M```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``+'? +M2JO@#;V(KB;7()AFHOL/%2'8FEH[@@3USR=F_E5_P(8)C0$RFC)YFTQSXMY) +MD4`,H_)=_E,]ZP)%HUNU>.@4#JQO([43YD]032+]P/W!D49].L7CH/=Y_FYH +MUZ[G8O1)UK2C'6V[B"%J.X-X-E8AUV3R=GA8[X4G!RI68$'=*0``)#KG*]E. +M+\@CJ-MX7Y>)F24KE<"%;HM[AB`"V5).GH!^*0``'```0`36>W7OE'72C!K4 +M+E$26T1NE552&````!P``$`%3<>[Q2Y',N*>C%*CY8Q+V2\W=[!0$K=&`V(% +M``P!```,`0```@```$4``0A3X@``0!$``,"H`0'`J`$"`?0!]`#T!]EBNWJ9 +MNQ3\\]Q+S,0)H9^<+B`C"`````$```#L(P``T(.+G5#TH$[MPIQGLW,MU7S/ +M5\@>1+=9CD/5>8R35T7K'>^&B'YC&W.!W\7@@`&PGK\/71H'(%%*2@`_F<6W +M'1#\HG^_V3RZBXC5Y9=N;>$:)3$P!QF[?S]O36D[< +MC6UG'A5E(CWFM#0'FO2%'E,34R<9(M_CQD^\5>-(IL$LT,"5DS*I>57Z5D3E +M(KQ/ZU9T0&%RV2RO\(GAZ.V.+M>TCAE[+5TU856MO2[P?I'E10I`??DV#*F_ +M3E@EI(0BW%`2MT;(>@4`O````+P````"````10``N%/C``!`$0``P*@!`<"H +M`0(!]`'T`*0&B6*[>IF[%/SSW$O,Q`FAGYPN(",@`````0```)PD``"`J22* +M.V=%#`5=L_XFXZ@C=8_N@0W65CZY]_)HVM,'5-I_LI;C&Z+Q'I4MXM%!X0_? +M.M!(D$D;X$KQFR/T]=H9QY/Q$I:EP(:A%#L([\0IS&+_U2U!CM"O%'0:O._] +MG9VO&_PI!H'@./G\!LW1]#91[5NI%56-,'>?5C0/&U`2MT:=F04`'`$``!P! +M```"````10`!&%/D``!`$0``P*@!`<"H`0(!]`'T`00'Z6*[>IF[%/SSW$O, +MQ`FAGYPN("0(`````@```/PA``#@X:#-N:0GR(DV<]:"7ISFM$@EZ(YIR7>G +MU6%PK"!3,96GS?VL<&4X]IP.3*-HIZ#NL^IY\?(BZZP"0"9NL8]GQZ.T*LUC +M89.B!57.HE[/(0=6'_ZSRE->;3N%6M!=E@W#,=UCW*"JQ"I?%H7<$C*ELVWX +M3)OH]D.3%?[LESX<4(,K[FO]Z%=V90"2$#EQ +M">QHW>.T-NT.',8'SX;RJE`2MT;+I`4`_````/P````"````10``^%/E``!` +M$0``P*@!`<"H`0(!]`'T`.0&R6*[>IF[%/SSW$O,Q`FAGYPN("0(`````P`` +M`-PA``#`LU@86LO#XK6_-]#ZEZ/E<8E8?..ENOZCW#]5#HN-%`P`SX\W*R8T%Y8O76-&<@RL029U1.QW2T&=J;(P$G9VQ]8FM#)U-FT-#2ZVR+='@89)1\@ +M!\CV??K"4C+P;10P"Q%0$K=&>Z\%`&P```!L`````@```$4``&A3Y@``0!$` +M`,"H`0'`J`$"`?0!]`!4!CEBNWJ9NQ3\\]Q+S,0)H9^<+B`D(`````(```!, +M*0``,+#L"PO837R+.O=/4,4XSL['_<[4V8#78U-LR"`A;HU"^"R6=/\`CV+" +M=Q,U4!*W1O_)!0!L````;`````(```!%``!H4^<``$`1``#`J`$!P*@!`@'T +M`?0`5`8Y8KMZF;L4_//<2\S$":&?G"X@)"`````#````3"D``#`"Y+G]"157 +M_?$7[=5%_D[FZ`H`[V_;T4&UD1+&A^VZ72I?)5QK1>];22R$A5`2MT9#Y`4` +M/`$``#P!```"````10`!.%/H``!`$0``P*@!`<"H`0(!]`'T`20'"6*[>IF[ +M%/SSW$O,Q`FAGYPN("0(````!````1PA``$`1B=G\P1RB:DA[GH""$_ZSZ@\ +MT<;''(A"O\H[T/5\71N(EB]$G+3C\-KO*P!!1$I![%_?6?$C<;1XVQJLU>6$ +M0P'TL^@-0\UF[=#'7BB8`UL4F&+)BC`X]N\.)RY]32&=H9=P:.5S9B%UUZ>S +M:LW-,JW?7ZINCT/.=]J[<8=5V5;7@LS!S'#@UL[X84P)KYU(P+9ZK0SI3#=/ +M7ULMTCW@JLEFO'B_KZV4T9!@J8U5;#UWQF)`[-B![(;S& +M$Y0HS\D;0F3_4!*W1M;O!0`<`0``'`$```(```!%``$84^D``$`1``#`J`$! +MP*@!`@'T`?0!!`?I8KMZF;L4_//<2\S$":&?G"X@)`@````%````_"$``.!1 +M]*Q"LF45O`L>:Q7",9'GM<80ODEWW*I63%S`__G5B\-[H$:&XCMD_O\8S6OL-@#L%`W>Y1 +ML*\%WDB6#88<)5JNCK#3!;`!'3BR5*\_AX\ROK)08`;AV^&EOP!HBM"*95>8 +MPP52'K1+%75>':U=^)<&V0X#+'G#(8^+?$H5N=K^$GQ4\.&'L-"74!*W1G<` +M!@#L````[`````(```!%``#H4^H``$`1``#`J`$!P*@!`@'T`?0`U`:Y8KMZ +MF;L4_//<2\S$":&?G"X@)"`````$````S"$``+#D;[JY3>8(*H!68Y$)6P:1 +ME);[YS'=>FB)L,_1MO9R%`3N8ZG;FD,5Q0!\6EV33@0G&=V+X%1Y[@,^;6^J +M@QR8[;.!W?K+-*,R[#3GBI4A,I4C/&(3ZPA"]?Q]J#Q95F$N%/>O?I(`LEGD+LL!!@TP +M/GR@R+]HX4W250F0")N;5L#OTFYV4!*W1ETC!@#L````[`````(```!%``#H +M4^L``$`1``#`J`$!P*@!`@'T`?0`U`:Y8KMZF;L4_//<2\S$":&?G"X@)"`` +M```%````S"$``+"?%`#6T?54&OT%GS,M9GDM*??%:/U2+V"B%JY!)DRF.=_X +M/O'ZA<[,1[K'U?9--I/P:JMZ4/N*ABM"_C"F5-0%#WOM`;/*4-F9#`3_4`T] +MF$MR,1JW?H-9&HW"/K>T`RDPR,[)G+[FX*N_1H#;.KPHM$PB$P)XM-CIEOM6 +M1;WAW3P)OB9CQ=?Z?;_S:^VI:&BI''\[=7I1E5]Z6 +M!NC#4!*W1KE`!@`\`0``/`$```(```!%``$X4^P``$`1``#`J`$!P*@!`@'T +M`?0!)`<)8KMZF;L4_//<2\S$":&?G"X@)`@````&```!'"$``0!M^D`<6`3O +MP-_;*JW">YV`4W\??E0Y,IZ@[6VJ7CP9+#=`79IP\!T0\OH-\HZS$'[6X<]; +M.%5K6[VXUW4='\14E9=TFSJ!8.2L5XFA1G"D$%&)5ID1EJ9J\MXIA"\(V!EV +MVW`%P"$Y[I6N^G#Q-5&(.+TGV&PH".AP#!^9_2 +M3'A&+V^H'*1HG\M'0`=M4#.6KA):A:&V#JO?@(@;N9<2HZ3UHI>>JD/C;AG- +MFLV)8WY16WS56!R^QX9?]MX&P450$K=&3TP&`!P!```<`0```@```$4``1A3 +M[0``0!$``,"H`0'`J`$"`?0!]`$$!^EBNWJ9NQ3\\]Q+S,0)H9^<+B`D"``` +M``<```#\(0``X#I%ZE_>E!Y1:*-_/2,!5$[VY;=@)'@F3#$=-W9O.<36F5HO +MI^(\RB5*?/SUN=XK'L=[MACG"X9;[FWQ'2S$P4E2%7?K5HIJ`2;;4NV^2-+Y +M"&E"7+QBACNDPZH/<"6>]_TWZQ(T(=#=I7',*F).!6?-:#%J_MJ&Q(RW'*^@ +MZWF1(R+1J4QPSX\AB)"IF2^'BI!WA@@QXI32$XC*?P_RB&;;M5$2"LK3MBHE +M13==HE'Z#XU5<'PG)$\AA@@%+@_5F<(1+&^A(P1!H,^Q^.=8)ZDVZ?C?V:4M +M068"!>=0$K=&ZUL&`.P```#L`````@```$4``.A3[@``0!$``,"H`0'`J`$" +M`?0!]`#4!KEBNWJ9NQ3\\]Q+S,0)H9^<+B`D(`````8```#,(0``L,&-'Y[T +M9$5D$1?^DBL1'%N@Z/CA)\)-Q8N00A?`*^,?P*I#;]0WJ[/0@53_S+0KQ1856@OW>A*=YNF?_FYS%5=5G7B_F>*&2]#Z4^$/ +MM_KZ:V`+&`_`Z<=+[?KXI241VAMM@03JWSS*C4WHI&!0$K=&Q7\&`.P```#L +M`````@```$4``.A3\0``0!$``,"H`0'`J`$"`?0!]`#4!KEBNWJ9NQ3\\]Q+ +MS,0)H9^<+B`D(`````<```#,(0``L)GEG0!,4.K1G?6:'7Z&VZ141%U3C:WF +M`SR>;Y_FSM&XRLR'J91E2*2^']\^+2^0=\N4(X(K,0-E5OMOV(1!AT(80/:) +M[E5+4W&$-J5V)Q9;:O_S*(%!76G(YKI'UR?N1@=RK<-`Q6/3#!?$0$E,XO%.-4 +MI!+NBAA&!F,32Q)P>XX0;AX0)4K%==#['?50:HR@D?(?N2P1U^\B`?O76QZ(Q-MII->/:1S.9^E3\RTX!,F'1/Y +MV`H85BO_4)+Y,*M,L#&R%UG$Y(L[A;`E!6Y$[Y3`#G8+!V\AH"^^W"S*U+WI +MBHPJ(J!&5VP^N_8GH\.H%N7L;*1S>OL$_?*,[R6$;8'Y=!9+/X/6CMOAF"O: +M4K3:9D2TB?[&C[BWF\80]8!3URR*-GFB?-N[//;8$@7(XGQR2"!T5HXODH9R +ML8JJ#F5%[:0I@@_NP)@;L"TUYBY.4!*W1O/:!@!<`0``7`$```(```!%``%8 +M4_,``$`1``#`J`$!P*@!`@'T`?0!1`\5'#7Z:)/4B5C%":P51GF( +M]2]GBS2&1]`$;0&2Z3E0;V!2T(_0FA>WEQ^[A`"G&'MC$-]I??SB`Y+7PF+%\"# +MD98=IJMR7G/0B;UZ2-)`;:3"QA+5E;NB*0-'2.L7S)CY@:UE]9+&.CZF9@&? +M]2Y=,?UX8H&(/$CCUH9*`LK\ST1-K)R0/P##&UIY0J.?NJ^E@<>8G"`JKA"E +M(QS[BT$?6P))4C9PI*36%+PZKQ_+D,I+\E`2MT8)`@<`?````'P````"```` +M10``>%/T``!`$0``P*@!`<"H`0(!]`'T`&0&28L^TP5&DB4R/M$5RW5.0#(N +M("4(`````````%PJ``!`<0Q8QR?>TP=B/IFP1EU8GI)I$!#5\(&5=IT%9+=1 +M2&[22M2WXP\Q/TP>*-#ZVWK8"[^.0GL>P+X)RTQ<4!*W1I`-!P!L````;``` +M``(```!%``!H4_4``$`1``#`J`$!P*@!`@'T`?0`5`8YBS[3!4:2)3(^T17+ +M=4Y`,BX@)2``````````3````#`==H^TUIIR:BVKTNTG!%.YFZ +MD+=K3]=M\IR'TL85VZQ5'H:*.E`2MT8P'`<`;````&P````"````10``:%/V +M``!`$0``P*@!`<"H`0(!]`'T`%0&.8L^TP5&DB4R/M$5RW5.0#(N("4(```` +M`0```$PJ```P70?/F!E3-ZR"PCAD9+NI`%[ZIT_2>F$5&:8)MH`H0R8Q/!O- +MFZK!@U*`G*Q0$K=&ERH'`&P```!L`````@```$4``&A3]P``0!$``,"H`0'` +MJ`$"`?0!]`!4!CF+/M,%1I(E,C[1%H`B`AX#&1>EMK&AQ<\/KBJ"7>QXK2*4!*W +M1@PJ"`"8`0``F`$```(```!%``&44_@``$`1``#`J`$!P*@!`@'T`?0!@`=E +M$&-H5E1L&S<``````````"$@(@@````````!>"(``'@```!T`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``O90,"6HELEMK_HVL9_GX)F;IH^>/8B98 +MN6&3*1\W&0Q9>?U6B]%G=8/"#>"X>I5Y&OG0D7`ILDV@\)7_I-L.R9)1Y9`+ +M*AJ'S8@93DIO`2H6#O']S&U&G&5T>\(?H6<@T$26NV(5V>TE8DF7I7C/K2%+ +MY47P?3S/"9@VA3E,(H(I```D&F+*.XS/=WR"3@F:/50;KGBRDJ&/3Z]"7V7J +MC,_PI)XI```<``!`!&1!?X8RLNXE,S-G8K].MM4,,4_<````'```0`4-UAK2 +MUVBH@7%DB\?7FRUVN/<%K5`2MT;H.`@`7````%P````"````10``6%/Y``!` +M$0``P*@!`<"H`0(!]`'T`$0&*1!C:%94;!LW```````````I("(@```````` +M`#P````@``!`!@````$+D$@ZLS?7:P68*?SWR?]_%O,^5%`2MT9)2`@`N`$` +M`+@!```"````10`!M%/Z``!`$0``P*@!`<"H`0(!]`'T`:`'A1!C:%94;!LW +M```````````I("((`````````9@A```@``!`!@````$+D$@ZLS?7:P68*?SW +MR?]_%O,^5"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MO90,"6HELEMK_HVL9_GX)F;IH^>/8B98N6&3*1\W&0Q9>?U6B]%G=8/"#>"X +M>I5Y&OG0D7`ILDV@\)7_I-L.R9)1Y9`+*AJ'S8@93DIO`2H6#O']S&U&G&5T +M>\(?H6<@T$26NV(5V>TE8DF7I7C/K2%+Y47P?3S/"9@VA3E,(H(I```D&F+* +M.XS/=WR"3@F:/50;KGBRDJ&/3Z]"7V7JC,_PI)XI```<``!`!&1!?X8RLNXE +M,S-G8K].MM4,,4_<````'```0`4-UAK2UVBH@7%DB\?7FRUVN/<%K5`2MT9Z +M;`@`4`$``%`!```"````10`!3%/[``!`$0``P*@!`<"H`0(!]`'T`3@''1!C +M:%94;!LW!U583"=(Q:@(#)Z"])W<%!DIO"^.$KXAV +M:Y60ZU!,[&_CD@XZ\PQ]_7=\&;6FX\1!PS-E;W*4"Y/ZFM?N,LP1E6+JF(ZC +M@VI%I:PJ'"I)%RG1XV:$YR6V1+S']@SPV8DD3-[%*0``),83U=KY'1[A5-F' +M73!J"-96K3RR$E7O]I7,_NY/7,$_*0``'```0`0V/EPR%+^+?DWL*UGFE0AL +MTLI#TP```!P``$`%2)\[VO=.$P+P_C4+V.TN,,"&LKU0$K=&P)D(``P!```, +M`0```@```$4``0A3_```0!$``,"H`0'`J`$"`?0!]`#T!]D08VA65&P;-P7, +MTQ,=,LT"+B`C"`````$```#L(P``T`X,9NUOY85[;Z/"\/O="Y\/[NNFDH6(-P,_YT*1-G0@NN185#,\"-CESW_BU:=O$#%ZZ%IKM;] +M@E=HX-9"(]3::Z';$[YM/#*U>?*=;=`AOE`2MT9=T@@`'`$``!P!```"```` +M10`!&%/^``!`$0``P*@!`<"H`0(!]`'T`00'Z1!C:%94;!LW!_$@ +M<5O%F7F$D<5VIKEKOT5N;#6-_@?WD%V$UQ<^^?X;C6RY;#_ST<6T_"82#4A_ +M*RLU&+M2$Y>)BIK.E;0P(I+>0`+(TN?.L#DB#1Y&IB:_4GL%:,3.E!L$S"E- +MV\SI*&57'%SH5;F<@'L()5Y+%P0? +M7\%Y+?S!&]N!7V[>QM+HOAH@44PR"6'D#W<%-%SQ2N;"0H)EAUVA'9ZJ]37V +MA*[V(?B_,%((;E`2MT8YV`@`_````/P````"````10``^%/_``!`$0``P*@! +M`<"H`0(!]`'T`.0&R1!C:%94;!LW!NZY"U1__"0AZ7Q+FFN4?[$MQF!\"3YNE\M:NRIEKB/PH^=\,+K=N +MR)@C<0^>'$)0$K=&9N@(`&P```!L`````@```$4``&A4````0!$``,"H`0'` +MJ`$"`?0!]`!4!CD08VA65&P;-P7,TQ,=,LT"+B`D(`````(```!,*0``,*-O +M[_/^IXKXPDF+"+M$W@?JON51B]W`M%F7?G"D@@0OKW*4V_:QPM#>``VZ4!*W +M1M($"0!L````;`````(```!%``!H5`$``$`1``#`J`$!P*@!`@'T`?0`5`8Y +M$&-H5E1L&S<%S-,3'3+-`BX@)"`````#````3"D``##F88*XR>K-F33^"LFY +M^QD(#"0#P*T"<'_'VC-J5Z\;T-2=3U.0C1:><=`JR_V_NV=OWKKE2QG&(DCZ<\2B3SRJW:H3D"P +M&1B=F%?LQ_MR'PV?>2Y&!W^KA0:[8.J`_TK&:0N7UR?V--9_)>5+H[G\_16B +MMM[[7#=P0-R/5;3R<_J6;(P41NK9H9CG +M$6I@+\!8Z7^RHX(E]FN` +M^%"1A9YY3]3CED'-NN#F68K=^5:3V'-X#'@B@2KGXP*JW)*ZFZ4RKBVRE$Y/ +M2?[!4!*W1G\L"0`<`0``'`$```(```!%``$85`,``$`1``#`J`$!P*@!`@'T +M`?0!!`?I$&-H5E1L&S<%S-,3'3+-`BX@)`@````%````_"$``."VHP944<(8 +M%VI08$=]AZ+ZA1^,,>QC/X9&SF8_X%WO,I?;6]-M0@)3U<$A="`N787/8.@V +M`$ZC$*Y>X;94C+48%03^=X7-NX]$69[<[Y(!X[7+\4DD09`?B*JJ_ELQZD2L.L#[QA:419N5 +M\J1HA7EUMCHZA3IF\1/!4!*W1@1@"0#L````[`````(```!%``#H5`4``$`1 +M``#`J`$!P*@!`@'T`?0`U`:Y$&-H5E1L&S<%S-,3'3+-`BX@)"`````%```` +MS"$``+#>/JH.^0&]5:BW3O_U),^-AQU0/BH:%(E/^[9!KRJ6D9I9-=F(PC'. +M]%P*M5J,)A5/I$83B4^V[8F-_<3DOP-I^"$@.H4GN"T$?=E?=.>I +MWCH?H[VIYDA7:!QITLDNUF[/ABEY%LD1H[HY%%QNR+5)@2GUR36E.'D[$>BF +M(K3%F[N-A_J'E3'VN]KL(^*"RC$YA9!JE'AS]2!Z[1YA^K9K[9C/FS\>R`16 +M%KN;%/07=+1$M4R),8W:A"?B@(;4W396K+["V#X7=DVSS;[Q`` +M.$$<>9EV=X9B/EGJHZ"1?*G3BQ3D;M_Q;,K\2I(@4J,_-.DF8.FSLST&7#3HL%IF8!N5K63_9F[1H\:8,2 +MDI-V5*1WHA]8\V:5TD"G9==TFG[(9S.>D*5$$2N>7XI@LXR'NVK;1E=,10TZ +M#EE$9R0D;>)H)`.P```#L`````@```$4``.A4"@``0!$``,"H`0'`J`$"`?0!]`#4 +M!KD08VA65&P;-P7,TQ,=,LT"+B`D(`````8```#,(0``L'"=GF^QV*T@L#H\ +MRLSZ3H6QSCOT8;>:LH?ZP.H( +M:]QZ781/ZII#WWQ^E3#T5M2D>\WR_BPUC',Y@3 +M$^\7NI]:A$9#A2\`E\LL&D]2#4S$0N^RH(-0$K=&N+T)`.P```#L`````@`` +M`$4``.A4"P``0!$``,"H`0'`J`$"`?0!]`#4!KD08VA65&P;-P7,TQ,=,LT" +M+B`D(`````<```#,(0``L,R-#XKN,7A9OE3`I.0-%MOH07"7@PL&"?P3&^/` +M\%+J@67\:KYFY6;V"L#3EV,A:J*-,=3FCJFO9CQT'*,P;"$;IHO?5]^E9,.C +MOMQV=L3T!9JCRJ\(7LS-8SIC +MH_!H-4[6:TDJ)5PA6BXZZF=UZ>/OBV5GDQD72W"[34A^2G"4N20[K0IB+#&!*^N(@&>=A\;;S?O'15=L3S'RC5AR+'1[' +MC?=97NU%!JEY[[(4[L%\\D'E+GAA96(D!#]M0`NM;UM^9<A6KZ!TMG6^V^J@[5>AFW0:-ETU*DL/.#PB]?[N92`=!,GA_#0Y29>/" +MMT"NIJ#&$AC7U^=!>;1J%7QH9N@V:@Q=\-L.;KX<3_GEYDAD^VS79=A:PEPK +M[4O86-J9F*A#IG-SNY?/NB<0SF>_=N6@(#V(1=UIL$$\9A+!5P#0PTG6X3A; +M_M6,YD[ +M$=N"+?+B@S=,61++>AT("]4E;:+F\"73TE)9,4BQBW$:HSC05]2$=#<0,Y<3 +M,$D&)H;2KHH>E(7^0^7N4!*W1I48"@!<`0``7`$```(```!%``%85`X``$`1 +M``#`J`$!P*@!`@'T`?0!1`"+T'EGV-RC(0F)S.=LX4PDS/SSRG67)OE:,#P%]Q4Y<8I*[9TLL +MU=:7,\=>;G6V0+NZ]CI:](C6=X@;"HT&V5X)F+[0=S(,,PR.Z96<1F__VC$= +M)<]65)G#,B;`[VJ(]B^Y)-1@UV/-,J^;(=$0ZE;Z0;$*`)Z]-43Y+]3-9C7` +MZ][]N&&9[K7F;CY8D+&A@B]ZE@-O? +M_+[$(K#1\&[(/7K1X]X^2/DF'-W(:LX1N][_XET<`I)LBV-==G^&W4),,G\5 +M%ZDO:YB-@P16(FKWB[W;@_V2T%`2MT9*/PH`?````'P````"````10``>%0/ +M``!`$0``P*@!`<"H`0(!]`'T`&0&2;H%WZ#\P:LD&S!+J)5!*;\N("4(```` +M`````%PJ``!`1&_Q5,F6#\4,05(PQ@Q/8,0+3=AT["5QIM^S#KMA7R!/N%[A +MK3X]ZSFZBSU:Y:D:S;N[W.Q&N(B9K$J(4!*W1H=*"@!L````;`````(```!% +M``!H5!```$`1``#`J`$!P*@!`@'T`?0`5`8YN@7?H/S!JR0;,$NHE4$IORX@ +M)2``````````3````##::O#YZA:YZ-Y*9=>(Z<_2'9$*UHZ518KF#F2SP#(% +M9U@7"2[>;4OKF_BKKE`2MT9]60H`;````&P````"````10``:%01``!`$0`` +MP*@!`<"H`0(!]`'T`%0&.;H%WZ#\P:LD&S!+J)5!*;\N("4(`````0```$PJ +M```P7A/%F"@G,!8JC +MO*I0$K=&!F@*`&P```!L`````@```$4``&A4$P``0!$``,"H`0'`J`$"`?0! +M]`!4!CFZ!=^@_,&K)!LP2ZB502F_+B`E(`````$```!,````,"QT9_&8`,3^ +MNG^[2EZNT#.#/MANL_@-J;:W$>MHY/C&;L3WA]ZM=DK-IKCS4!*W1@=F"P"8 +M`0``F`$```(```!%``&45!<``$`1``#`J`$!P*@!`@'T`?0!@`=EA@9Y2+,X +M+D0``````````"$@(@@````````!>"(``'@```!T`0$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``OR'&J+SZ]XT#@J=>S^9$.>%R!G_PM,R42!1=_*,' +MI9=JR&\CO9BWYPOQP`HG\17ZL46T30S:?7\KP6/H@:KST2$#(D&*"`-8PJ3_ +M;'",21*LYX9%W`6G<4#/^,[NO`32"H_LW5H"Z0*$3C\>"U!#T.A![4 +MJ;V[WRF@P#TI```D]!JKFV,C+`BAU,TKV=1=9+DR6AC6C;$\"-@*"X&K@GXI +M```<``!`!!7?H()W01BQTE]+'[ILY@4/!!@F````'```0`6K'Q`I]40=F"CG +M4171`-"3([^N5E`2MT8U=0L`7````%P````"````10``6%08``!`$0``P*@! +M`<"H`0(!]`'T`$0&*88&>4BS."Y$```````````I("(@`````````#P````@ +M``!`!@````$?>([)S0,7[2`'EH&LU@O4BS."Y$```````` +M```I("((`````````9@A```@``!`!@````$?>([)S0,7[2`'EH&LU@OS^9$.>%R!G_PM,R42!1=_*,'I9=JR&\CO9BWYPOQP`HG\17ZL46T +M30S:?7\KP6/H@:KST2$#(D&*"`-8PJ3_;'",21*LYX9%W`6G<4#/^, +M[NO`32"H_LW5H"Z0*$3C\>"U!#T.A![4J;V[WRF@P#TI```D]!JKFV,C+`BA +MU,TKV=1=9+DR6AC6C;$\"-@*"X&K@GXI```<``!`!!7?H()W01BQTE]+'[IL +MY@4/!!@F````'```0`6K'Q`I]40=F"CG4171`-"3([^N5E`2MT8_J0L`4`$` +M`%`!```"````10`!3%0:``!`$0``P*@!`<"H`0(!]`'T`3@''88&>4BS."Y$ +M`L:;L#G:8:PA("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`# +M```(`@```@,```@#```"````"`0```(H``"(``(``#*C=$AR#^ZZFDQJFUY: +MEU>U4E.'HJ0>C@I>$I+C[YEV/&\B0K_X6HJH4]/C$^0N(4 +MW!H6S"*?7#E+UO86X.B=PKS<\R:*N$P5*0``)-X^-XUA>/\J9<:J$1#-E@ZP +MP@:,KZQLN2O%E/P%,ZG?*0``'```0`2Q-E]N3>]-#&2*T4O]2RI0$K=&)]8+``P!```,`0```@`` +M`$4``0A4&P``0!$``,"H`0'`J`$"`?0!]`#T!]F&!GE(LS@N1`+&F[`YVF&L +M+B`C"`````$```#L(P``T/_R9R+3?435`HA(UIA=_R1\V@8'%47!"DID)9Y*5ZZ0( +M4!:#738)!BEQL<5H\K>([36B05T$1YPU935DVI7PGR/%MY%!OV'B165`2MT;2 +M[PL`O````+P````"````10``N%0<``!`$0``P*@!`<"H`0(!]`'T`*0&B88& +M>4BS."Y$`L:;L#G:8:PN(",@`````0```)PD``"`M4*E;P(00@=AL@7W)S]X&K[!0?&TB'K;A1UES&88:%GP[_5,TC7_W%E];/ +M_>Y98*'77:XM1-,.)E@;K//#V]-I"F>LY::K@4?$44BS."Y$`L:;L#G:8:PN("0(```` +M`@```/PA``#@EA%I^\:!`?&1JFAL/@"<3`I`U700!SYK*H457&0H*%%4@:CQYQ"V@/H(SUMG?C<,Z'P;Q@1\GXE_-6#,I&$YDN +M?+:(,"1.N]"'IV$N-%25-`>JTC3$\V^Q_1AJ.]ZXTEL0^_"60-O='"!$7IY" +MGT:;+V5H2)3`J>8K#"1S"'Q)0QP=U9)B;^)*.BS/B'=-Y5#1L:H.K92QYOUR +M8[)SZR,(CD``!`$0``P*@!`<"H`0(! +M]`'T`.0&R88&>4BS."Y$`L:;L#G:8:PN("0(`````P```-PA``#`\"V<12S@ +M`E`F(!0+G+@7;62%*OUNAP3- +M'S[HAL.\L^^Z(A":[!F?1"UX>>V&NQP>X\YRQO(26XU=[W-#\IPWRV^KKW%C +MDSE02J,3K.OU)3EA+?W2-'<,EOD]4L63S=.#&JXA.RXH85!02UCPP7S9)P8] +M(,E(MN4JXK#<[_L/5J`(Z[-H]."!HUA:C1O3XR$X#3*03?]>H>LZQKQ!A==@ +M\G=0$K=&9B4,`&P```!L`````@```$4``&A4'P``0!$``,"H`0'`J`$"`?0! +M]`!4!CF&!GE(LS@N1`+&F[`YVF&L+B`D(`````(```!,*0``,&<^ +M%C9[A6F*($-GP']^H0,E;,!JH;;/A2%F3E`2MT9X6PP`/`$``#P!```"```` +M10`!.%0A``!`$0``P*@!`<"H`0(!]`'T`20'"88&>4BS."Y$`L:;L#G:8:PN +M("0(````!````1PA``$``6&MP1'V]817B3>`"&M"'-E(!*"V.8&!W(O8F_R> +M"6KJOTB42X!I$')Z6_P!07(`1X?]1)`Z:/6`8\`8MW(:K:_3RW1,O +M$2P+E^40:<5]UGVX/]IYZ#HZ+:)$Y(CHRXW@B9"S.2]@)Z'+,AN/OWJB\"M+ +MBKL*LZO#U=XMUK%T*>5K%PIO%J0#AO5Y$# +M("-"MI2_&SI<^L2'M-5-/K"0!3,)\E@&PM(.7N6M*6GH[$,DTDE8[ZTFYV&) +M/@!>_Y@6;8&&%SMQJW%$[I,*IS4_<_ZD,+\EJNM1V&`LK!P&[;Q$VS\D4!*W +M1J=G#``<`0``'`$```(```!%``$85"(``$`1``#`J`$!P*@!`@'T`?0!!`?I +MA@9Y2+,X+D0"QINP.=IAK"X@)`@````%````_"$``.`^LT`?8($;_Z^\+82[O`$,$1T3^8A;H/TH`\Z,PLJJ#%5[D+1$VMP^NZJQWH.R0O9PAQB^^ +M<""KQG-,=J`8&U)-V-@J76X'"_Y/ +M.9=H+S*@Q!8L.0'&`8ZC)2\FW/+,CDQ`Q]P&4!*W1CEW#`#L````[`````(` +M``!%``#H5",``$`1``#`J`$!P*@!`@'T`?0`U`:YA@9Y2+,X+D0"QINP.=IA +MK"X@)"`````$````S"$``+"TK\I<^^&H+A1K@$`++W//>RU]ZIR9]NO[IZWR +M1/1>QISG@20C70BMRWV\2>.V1/^!>JUYG"3IF\&S>_2(,^94?R&'?-*$M`SS +MQ<*`VCH-T;\=+$#U-XKS:#':H.:T%*6<&;`9&M[M30N"II](3YBU"6KFP(JW +M<\6*M]8+F+/(=)AHLC`=GA-T!,]3W@8,U\W=[=NR,8X"5015\Z80RUME4?\3 +M:R4$/3#I?-X_4!*W1L6:#`#L````[`````(```!%``#H5"0``$`1``#`J`$! +MP*@!`@'T`?0`U`:YA@9Y2+,X+D0"QINP.=IAK"X@)"`````%````S"$``+"# +ME*"B\DM94O$DHOZ)&24B(68X)ZDK8;UQ(WR,B*+EH>1QC/:3MAS)N_N*%]=T +M4JU---FKAZO_DY:^ER*,ULJ>+8X.YB-#`YE$=!3_%:U4,'-6L[JTTP*C(JXN +M&)_2L`GKONG/.X[]C/_G6/"<2JTMZS7 +M^SEE*?O@_4502T>&%V'@+#Y[.@AT:@*YL+UK]6FK<#7ZXT>^C,_IYL(+K03Q +MTSR/?V1H?W*Y&2<6+J[OY']6N+2\273B,L'!JGSYT0>+Y$@^2?7V+?3E3`"L +MFGM*JB#HM)!W-@W&G\0H/88_["$G)=VK+O#<>P:%A9I^5]\] +M?X\3:I.QQFAZB6R/7I6DA-QM%9QA7YJ82(<`LG+\]2E2;3X,1O>C(QKC4DQ* +M.B:-XT+P7\*A+LH&]Y.I75O&(JB^>W6`I&=%8IK&J#I$L<-O/W6J.]U:X&S; +M:EF*DKV)O0M0$K=&4,,,`!P!```<`0```@```$4``1A4)@``0!$``,"H`0'` +MJ`$"`?0!]`$$!^F&!GE(LS@N1`+&F[`YVF&L+B`D"`````<```#\(0``X!/M +M`%/BI]YR3D,2TNW6Y(>W`EYO(./&2"?S4!!L`%Z,=,_&0.1,4WQ';[UU%A+V +M$V>^8EQTP_9RZ/4I_<N6_P/?F`LKO2JI +M)'=U1>L6V3O%!3VZ8%(# +M!UU;<GVX4^V=',0@SB/A^;`0@UU^=7=($GO*+ +M]:+QWWYE!QYT"#NS_5IH'O/]3B[<4-'0ZB,O@5YM"@YP,-B-7790$K=&'M,, +M`.P```#L`````@```$4``.A4)P``0!$``,"H`0'`J`$"`?0!]`#4!KF&!GE( +MLS@N1`+&F[`YVF&L+B`D(`````8```#,(0``L!N&$20Z6[_M04DRR8@]#=/"JH#'!JM%L)Y9[B=TK2%9-J +M`JH?:W0+"\Q9W#GR=W;WX?HW%J5*%QD]B9+SFYBOVY30"D=#B:AM4+%\74\W +M.$,.,"D4[D`@)E5CV*.?+H*,<6G:)P`U;EX!@&GO%K3^2,;HO33/(/SOVC:Q +MC%N&W8F#7SD`:I_/2L-]D/98ND90$K=&I/4,`.P```#L`````@```$4``.A4 +M*```0!$``,"H`0'`J`$"`?0!]`#4!KF&!GE(LS@N1`+&F[`YVF&L+B`D(``` +M``<```#,(0``L(*^#/D6=ART:[(TZTW764!(OY)%?^S/T4ZL!TB(9H3K5HZX +M&ETN8.'Y9]/<&Y3[$V?-:E""=,O#/-QSN31!GHSDZ_6920F//])C;3@AEJX, +M]!IW9#M;LN@]Y=CT,RM*^=N`?KQ8!)-2N\,E\>M@R1AYKKGZ`"?%4RAT`M_M\[L3#RPK%XAIPD#;GM\(/RA'Z'^P*.ZS_LUJKE +MZ3E0$K=&CAL-`(P!``",`0```@```$4``8A4*0``0!$``,"H`0'`J`$"`?0! +M]`%T!UF&!GE(LS@N1`+&F[`YVF&L+B`D"`````@```%L(0`!4+_`)B_+SGW9 +MV^!ZG%M5<;&#U@@>:@?E9D''*AU':,HQ!G,D-##$/=,57[`[^KO2WJ'/]/_/ +M.02"RF'QT-(4?+64T$[B+`WM(+.W9]$G^7S]BWT-*?]`E[P%<'IM.IH$7A!" +M!@(!ZVA.H3$M7`0$-$Y\KP"11STX:8V]V7\VPW&ABZ#E2532;=_B__"ZK(]? +MH]TI&J!Z>X39KX:"G+6U8=N1@)SKS'*0IR_,BP#0S"FV'58U?\#_:YN0/-?# +M$XAD+]&0*.E+^+=#3ONC/-O@L^W6W9D*KU&5%0>H%9_SB`E_9YJP&71\-\2> +M[E`M#0SNV$-ZQ855<29[ +MH!TVRJHX`1@Y4!*W1BE0#0!<`0``7`$```(```!%``%85"H``$`1``#`J`$! +MP*@!`@'T`?0!1`TUEKHF^MLHK[IK7OU]=JTWOMR1J]7]%I-7, +MR>XL--B:T=C!@IS?2:2T'XP=AN!2CJN-GYE,)75AV?SKC_Z-SU]S8!@R$]:_ +M:X!)T4)G7PHR#8J.72$E,O!D&B*(;YO!Y'Q6+\+8"F!50?T7>;7#RBKW=*FW0?WN^D83F;6HHYQRDY2`V%2[RQ>ZVG +M(HT\NLI2NL4RRC%,?D2*(35)A@I=7DC^,'ES>`T`?````'P````"````10``>%0K``!`$0`` +MP*@!`<"H`0(!]`'T`&0&2>V7H`\JPLZC(B13I*PNOQ4N("4(`````````%PJ +M``!`U)Q;!P]F&SO+LS>].[S@X2I_J1I3?4?Z]C>T'M=M6[C&+84FVG1XMY@U +MA14.8B)D(_:2]YSL7_V_[`3L4!*W1G^##0!L````;`````(```!%``!H5"P` +M`$`1``#`J`$!P*@!`@'T`?0`5`8Y[9>@#RK"SJ,B)%.DK"Z_%2X@)2`````` +M````3````#`&,$UP[G)T*4/AY=)MQ4+:J)"H^%V7H`\JPLZC(B13I*PNOQ4N("4(`````0```$PJ```P$-%S +M>+-77(M)$O51DS)P\O%0$K=& +M\)\-`&P```!L`````@```$4``&A4+@``0!$``,"H`0'`J`$"`?0!]`!4!CGM +MEZ`/*L+.HR(D4Z2L+K\5+B`E(`````$```!,````,,E!;A:'WN&9O+,/+T?D +ME<2YB8K>Z$)]B3ID=U9,`>=-`N-K^D;L(94!*W1IZ?#@"8`0``F`$` +M``(```!%``&45#4``$`1``#`J`$!P*@!`@'T`?0!@`=E&[#;@&5GW7,````` +M`````"$@(@@````````!>"(``'@```!T`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``0`4VBPKZ8Q=HW%?VQ:7]H:5C1&K9-B18'-LE5ZMU-;?W\=@U +M!I(YIXT5W3"XO8$F+.Y"#0T3+;2\GQ,_:?=6H]@[(_UW>+KV7S3*_."^GXX< +M02IL1&GUWJ`TA'QENY,N?G:*_I1FHG#B)$!739\XBPQI^@.4QA6`3=D`90[; +M*Q`I```D2J`]R(:2PU8=6P]:KL[L24K7.?2U,=;WP"KT>R)[N5LI```<``!` +M!,+.D@39#1BN7RX*]8R1:EU972Q5````'```0`6'@/*^7T%M3RYS;%':K7#' +MB-Q2B%`2MT:)K@X`7````%P````"````10``6%0V``!`$0``P*@!`<"H`0(! +M]`'T`$0&*1NPVX!E9]US```````````I("(@`````````#P````@``!`!@`` +M``%\Q;:]&@A"!P)$]LSI0*O6'`U+^5`2MT;-O@X`N`$``+@!```"````10`! +MM%0W``!`$0``P*@!`<"H`0(!]`'T`:`'A1NPVX!E9]US```````````I("(( +M`````````9@A```@``!`!@````%\Q;:]&@A"!P)$]LSI0*O6'`U+^2(``'@` +M``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``0`4VBPKZ8Q=HW%?V +MQ:7]H:5C1&K9-B18'-LE5ZMU-;?W\=@U!I(YIXT5W3"XO8$F+.Y"#0T3+;2\ +MGQ,_:?=6H]@[(_UW>+KV7S3*_."^GXX<02IL1&GUWJ`TA'QENY,N?G:*_I1F +MHG#B)$!739\XBPQI^@.4QA6`3=D`90[;*Q`I```D2J`]R(:2PU8=6P]:KL[L +M24K7.?2U,=;WP"KT>R)[N5LI```<``!`!,+.D@39#1BN7RX*]8R1:EU972Q5 +M````'```0`6'@/*^7T%M3RYS;%':K7#'B-Q2B%`2MT:1X@X`4`$``%`!```" +M````10`!3%0X``!`$0``P*@!`<"H`0(!]`'T`3@''1NPVX!E9]USJNU^+ON) +MZI8A("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@`` +M`@,```@#```"````"`0```(H``"(``(``.;'^B!U+0P3?,@A/P2KJC:WB\7%!50=C3Y!K,XW<)6M'J5]X>$-3M"MM9M +M;4\^*#0A"&^AU">KV$2S:TL:*0``),MQA/8U/+JVQ[3']<>J.<=Y@6\3A\0[ +M"WF?$C7/](C5_@```!P``$`% +MQZ;>,?V$[0LW)XJV+Q+\EBC9:V10$K=&'Q$/``P!```,`0```@```$4``0A4 +M.0``0!$``,"H`0'`J`$"`?0!]`#T!]D;L-N`96?=J6+B`C"``` +M``$```#L(P``T`9:'6$47W$?;P1^7$T2?*=BA6''^5X"$1[GD\?S8;C_7^;[ +M+FI>E3OP0Y162;>WJPGY(U8@Y=MT.!D@?RPO6$DD)(P(V]<#OY5MK0SU#HN`\?(H4!S7T +M?9I?7X)(92U=HQ4K^G&WJI^LO0D$V&L+`(1(,@0DK)XY>E`2MT;[*0\`O``` +M`+P````"````10``N%0Z``!`$0``P*@!`<"H`0(!]`'T`*0&B1NPVX!E9]US +MJNU^+ON)ZI8N(",@`````0```)PD``"`W95@:]$!.090(#OLU/LNC?,WMK`_ +M<7;WX+I![ +M*C\73YKN:]VG.(IE^LV,L23%7MUB/F#&%:9Q@>1CBR8GCS_TIB"H%XG%ZY[B +M$YCNCFSL$.2K1^YS!E$2MT97!P``'`$``!P!```"````10`!&%0[``!`$0`` +MP*@!`<"H`0(!]`'T`00'Z1NPVX!E9]USJNU^+ON)ZI8N("0(`````@```/PA +M``#@MZ`[';)R?J=<*/R+KCX5P*V7?1S.JG9>5(L&G@C6H'EE6[=GU'"N'&CC +MP&FT1\ZZ77>0,[6%!`:95W:/39FTLY;;DPO6.S8:_H*+;S/7)]&E#8&I">N$ +M\9/-]N7N+PDK$\[$0=(,7F@@\[(7#^W7D=QK7$V'PRW4'E%*7I\J1(DX@W-_ +MQPERL()[/[D)Z0''8#:AR=F1@@C0^CM$W+Y,G"3JC9G`^JX2*Z!%%]Q8EEX9 +M#>MEU"I]KD2]@?09I7_CT'/_N&W*OY0W7=@\$`1Q^41`<;O;DP8J)Z9+,E$2 +MMT:2$@``_````/P````"````10``^%0\``!`$0``P*@!`<"H`0(!]`'T`.0& +MR1NPVX!E9]USJNU^+ON)ZI8N("0(`````P```-PA``#`K/$FG%)!K^0+(7NJ +MV4[W]W=&W`8>(D+0_'.]IL!V21B1P^25U1*QHR==D3HY=6E!0Q*OCF?'#H:&3<81,WB;$!K?323*F+ZPU**&0Y^EY0D`>C&7;`6*CIK0PIS +MU01%[L%;U'9?_3;^(^F_NQMIIR2^?UO4X'Y6Z"UBO)V+U#=0V((&`<^&J45U +M1E`C(J/S"UQ\"RA3QT+0!\76\["W=+#ACG0#4CHY$$+=['G.[#9.9K]1$K=& +M41X``&P```!L`````@```$4``&A4/0``0!$``,"H`0'`J`$"`?0!]`!4!CD; +ML-N`96?=J6+B`D(`````(```!,*0``,,MIC7S4G5V8XM3!SIAW +MBH=K1X:D!Z*WE4D4Q.,<1DTPV7PY?Q9M>NO\[:NV41*W1I+TU,ZFDL +M=^!G0H<;SHD6UB@T_G511U*\JE$2MT8;50``/`$``#P!```"````10`!.%0_ +M``!`$0``P*@!`<"H`0(!]`'T`20'"1NPVX!E9]USJNU^+ON)ZI8N("0(```` +M!````1PA``$`"M*Y`!TM$L1!NU"IFX'!SHUYFHY[>74W>$1(:VY`)Y1726 +M^EJ,D^+HP(7+[L^LJU+2&GKOIC`7NMA1?E>UR[T=:$=(W.$_ET5+$/N]5Z;M +M>0TX-I@*"?[[X)/B1JK0F''N],ER^LR7P;TIM%[^OS:5&906%XM#J8"-0>5> +M]^MI'W:A)1]:VFWDUDRK<>(MI'QOO\QT$#+&V"=RUSL7CD>O41*W1K!@```< +M`0``'`$```(```!%``$85$```$`1``#`J`$!P*@!`@'T`?0!!`?I&[#;@&5G +MW7.J[7XN^XGJEBX@)`@````%````_"$``.!LG`*90+6NXA]+GM@(_BDGU,81 +M+V,"H2=6J5)*T*3H#.)NK*!23#:70MA/^V.E18KA#)?DN'M#EG"+4C!(@Q,- +MP9#,"9]48'"/3`::7*BBTEES +MC')WI1=.J'6;4*UP,U9:61VD$YT,+7QI("D5\"\S;-@X?EY.F%U&O9XOC+[! +M&4YH;EO7;JPQ@WT`YJ3Z`0`%G(<2R%(/8_[_YKYT<0Y"2K_< +M0O(D,CY>B^<<"3Q1V'N5]]P)]+7S41*W1GMP``#L````[`````(```!%``#H +M5$$``$`1``#`J`$!P*@!`@'T`?0`U`:Y&[#;@&5GW7.J[7XN^XGJEBX@)"`` +M```$````S"$``+#HGX?O9`8FY,5(0\&0:J9!J;F/Q@_ +M3``#L````[`````(```!%``#H5$(``$`1``#`J`$!P*@!`@'T +M`?0`U`:Y&[#;@&5GW7.J[7XN^XGJEBX@)"`````%````S"$``+"U!:;E\JQ" +MQJ6PPPM6D+R!XR]1?>$VG/V*6/*-)`EP%Z1#)>1(DK<0NACQ'3ZW/<6%EM$"U +M40DN-8!O6.,4(7O]\G6M*_84YL55-"V=)3/>X"V;41*W1N&O```\`0``/`$` +M``(```!%``$X5$,``$`1``#`J`$!P*@!`@'T`?0!)`<)&[#;@&5GW7.J[7XN +M^XGJEBX@)`@````&```!'"$``0#N>"8U`_B=PP[?U['S?X:?,06-!DOOA-R" +M>$=9UPM$9L_$K>&^P<=;P[MV#=+1@S"Z]L]C@J-P1U&##DUL4M)KZ/O['I&D +MYTR])8:[(*Z5R8F;AL@&@A$KGP6ZR*K&Q21500T@P/8^2]+Z@IDQ`H6(#6DA +MQ3"U&[?HASN3WLE<%X%U;/Z(AZ7=K@A#5IT?G^"^\5L^J)*K_3'!'A&%J&RX +M)#Z,9L@&K*S4?R=TJPW/I+JJ5O\SB<"TY3&\160X"I;>;5?]X_MI"BP9R]LK +MN%[76>FUU''QK7&&4!8]<:>_??P447`:CY.Y[A@OE]Z"1=79YF] +MB/Y1$K=&3;P``!P!```<`0```@```$4``1A41```0!$``,"H`0'`J`$"`?0! +M]`$$!^D;L-N`96?=J6+B`D"`````<```#\(0``X,[DMY^?4+$D +M-_]3)7PND]8I12Y0F'``Z4L]RC)]9=K%'[''3*KX^LEG\7-4]8&3YQ1^U+]7 +M=QM#;TBTE?GVV*MZ,$K"&Z\IU4)KBLO"$>Q+CW$1P&O=3F&;WQ-XY4!(^N(8 +M!IZ^*2%DPI3(*A37>]+;99-_)GK^32OK$P`/<==;<"^L]X,CK9(27AH:N/$*C\R4.$3[8L8LM'L43]BZRJ\XW#U@GF20LD8 +M_TKE3]Z35=C6:-"N-X%QR8C;NM*#1#H1'Z:VAL4OJ6+B`D(`````8```#,(0``L'\U5AN&J[N%G;0@YKH0('[N2SM78P=51]4 +M]087!O+#.XUC:P(-R&F(!3'W/[:WUIC7-SA%W(\7[(3T;Y%^1P,3B^DL5:LW +M-.HDZL`^)"@HRV&S;Z=1$K=&/>X``.P```#L`````@```$4``.A41@``0!$` +M`,"H`0'`J`$"`?0!]`#4!KD;L-N`96?=J6+B`D(`````<```#, +M(0``L$@\33.#M=$]%>_H8F-4E_@JIJN"%VM"R1E'EUYI3UM(M&MLAXL.WU=U +MBI$@JZ[[LVA59IH]8F*%S;42;0EX,!:W;GKZGV0QP)R-N']Z'34,,UN/UB;A +M=R$UC!G(W3F2-Y1\GT6UHC_R.F6`ZAQEBV@29,Z&)$=&,Z3@$4ZEYHK<&!U[ +M#,@SU:[-^`RP/K7.2@[46FXR0IC6_>Z5A4>D:@O^>5L`L_]D%31%A%E1$K=& +M^Q@!`(P!``",`0```@```$4``8A41P``0!$``,"H`0'`J`$"`?0!]`%T!UD; +ML-N`96?=J6+B`D"`````@```%L(0`!4#"Z`<1<5Y]C)"N5R5MS +M71(M]DW<"?F%']K]B?1F%A,F2ICY`[K&.^L;140:H.`9PV[YWV1!YMP"Q.^, +M#SA=F@)[$JZ[;R#P2*!#0L+<`R44[O.>EW$*SLC@90S?-9*`D' +MCN*%&&39^=;_B_([JZZ+W>C6[A$`/=547:0'6F%:.`,4DFX +M+'@`41*W1L)-`0!<`0``7`$```(```!%``%85$@``$`1``#`J`$!P*@!`@'T +M`?0!1`5CNWI\0Y'N>([MKUNLI6I*/'DD;7)F%M5W#6G^ZPI +M"VRD&.S()8M!E/"`*1,Z7QM@1DGSE4(:%1)``!`$0``P*@!`<"H +M`0(!]`'T`&0&216GBU<-DJDN!J*I26BI*MDN("4(`````````%PJ``!`1G:' +MIE=81P_KD[JP&*,7`DIBF>RQ)Z)WB>&#M!P:5T%,V1\'I[I(F\<-H<''FV1> +MTC=-(L[#N":XO\I-41*W1D6``0!L````;`````(```!%``!H5$H``$`1``#` +MJ`$!P*@!`@'T`?0`5`8Y%:>+5PV2J2X&HJE):*DJV2X@)2``````````3``` +M`#`T`W^L[XUE6/:#DWH+QKV`(&"D!'Z!W13Q:=U-]6O_L$/YW4(&DD(7BI%Y +M/E$2MT;8C@$`;````&P````"````10``:%1+``!`$0``P*@!`<"H`0(!]`'T +M`%0&.16GBU<-DJDN!J*I26BI*MDN("4(`````0```$PJ```P#%1EN7^GO!(P +MWFJI^P+?I2$F[N\T_$7`'`Z]Y;"D.]P>24&$H`UC +MA!*6;`:\6SH5U2R2H>D4&C-GNBU?1Y=K41*W1J&9`@"8`0``F`$```(```!% +M``&45%```$`1``#`J`$!P*@!`@'T`?0!@`=EQLJ^>&O""8(``````````"$@ +M(@@````````!>"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``,X3^AA+(*DP_K7Q(:W]+^'AN@8/)LYE3%)C5B3%=R/X\[=J13!(A3#[2 +ML#2/"-3QZS[.+@5(KHGC('_2HIW+G:/]&Q)OU,M4J=N,@Y_[KQTWRQ/7ASRD +M#\:3CBRS5'S-HKJ\@K0%0\#KT0N7-MLFT&1T&-WY28L1]QRN1)DQ5[,I```D +M^L33F!D]/L2T.L8`B197R!4/&;_IZRQS/4\T_1F+4\,I```<``!`!'6?[R2Z +MC!Z.[@*L=85!ZO494$NH````'```0`5`I"*:3R+=@.E6YLPPUZZ@+"57IE$2 +MMT8MJ0(`7````%P````"````10``6%11``!`$0``P*@!`<"H`0(!]`'T`$0& +M*<;*OGAKP@F"```````````I("(@`````````#P````@``!`!@````%;DMQ@ +MJ?XT@##\*:9*XQ)=VD*,@PA("(@ +M`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@# +M```"````"`0```(H``"(``(``$`]F`R:4!NJ/>)'.->FNW;7)ZQCXWKEW:S_ +M0FSY?[!E%0ZX7,]>C6\_77#MI]L9,8"44Z?`ON!7&L;LO^YJ!;X@S+:)*1'Y +M#"?E.]YR8]957\#J+]-$MPV3$@(/:G4T^,9I&!@\E-HHWQ97_>*%BLW$JF.$ +M20.#,S$4_7LPOSA$*0``)`V!F!WY]Y9K@.&3=JNY"?0=Q^8Y8^MQZ-8PU*VX +M]TVJ*0``'```0`2"L(+):VUE\?==23;%!Y,NNAL71P```!P``$`%.,475:Y/]HD[U#(:<53;T%H?-,6]D."023IM? +M5N>OC7P]->7Y36"T5X',_D&S2L,E)D&;HRB1N\DA;KQRHRFNH;>Y__`GH1Z.V$:9SIXX^Q^0Z]Z<&?L^A"/3)?:]G"NVN:(2=8?]K=]A_V]OX'=/X_3`4@6I^+/"1)Z[Q+*89->/HB-M$*"L +M.VD\/;Q)=VD* +M,@PN(",@`````0```)PD``"`E$<545SW])16F6L]U$RQW4$1^07\87ZV@\(, +M_(H5FPQ?N_#N(Y-A,E7_OY\[O8`Y(IOHWCP^N5^UJ0$X;,7F'2+Q3)@.Q\OD +M&"\HV(R[R+#M35$2MT;E0@,`'`$``!P!```"````10`!&%16``!`$0``P*@!`<"H +M`0(!]`'T`00'Z<;*OGAKP@F"_>Q)=VD*,@PN("0(`````@```/PA``#@,D>? +M#JBI6K0X[)*,N[PR=:JK=6BK#42L(/UL$%\BDG1HJF@:YQ*-;FOD;[3Z(FPT +MY?LZ_UT=SU*9YG2I&A&/W=BK#ZH!I,[`Q=DRH`(,1T4D-:111F5W238G( +M9B.E)B1HN1NH)HA3.H'SOOMR@$/;87"U$=.7+*8D@M_L+/* +MC.OMW="OV&5R-ZB?/("\P:E?@OUI)'KD`6V"(JP!AHVOJK6,AE$2MT;L30,` +M_````/P````"````10``^%17``!`$0``P*@!`<"H`0(!]`'T`.0&R<;*OGAK +MP@F"_>Q)=VD*,@PN("0(`````P```-PA``#`"4N0"_Q&R7W+E2P#?^[!=2RI +M%.$@9>#GG>_JJ1J'.1]1-''ZG13V6&2:O?!>XFS6]>-X;3J.5G#HL";/6[VOU05 +MZI`6<_>X5Z()EZ].%R4C;3YX%V(YZR2XF._X.(9;?Q=J#9`?N5N218.R5>C+ +M`0#2.OON6AZ;O_WUZPT.0.H[C7(=(&R0I'D)]/YP(EFKT8U1$K=&XE@#`&P` +M``!L`````@```$4``&A46```0!$``,"H`0'`J`$"`?0!]`!4!CG&RKYX:\() +M@OWL27=I"C(,+B`D(`````(```!,*0``,$?'V$;!7;EJ.ZQ5M)Y+*7/E1;XU +MEW?HZ)K0JCU.JKJA:JX"=LJ)*35_P]B&41*W1@AU`P!L````;`````(```!% +M``!H5%D``$`1``#`J`$!P*@!`@'T`?0`5`8YQLJ^>&O""8+][$EW:0HR#"X@ +M)"`````#````3"D``#!RKPT%G.*O@`49DD?6"`MFNZ^],V7Y>)_NT1H:DL=+ +MT""!IA7D8D3R@'FN$5$2MT;;CP,`/`$``#P!```"````10`!.%1:``!`$0`` +MP*@!`<"H`0(!]`'T`20'"<;*OGAKP@F"_>Q)=VD*,@PN("0(````!````1PA +M``$`_B)Q6^-=1/,Y7ZPG+>F>0TK0)N;W(`\G:#$@D)_&#$9`88$\=2IAA^/8 +M@;-\,]5R8/0V=Z%+2U)K;LJ($5ORW*H5@CWP$#4\=I!HFY/S%RP"S$B+UC/! +M+9YV&0Q&<#V9EJ[6!BH*,68K)RF$0=YW7V4HT'Z]S.`@$:J%`F +M!:)%#JU3@-)+Z1N;T@_5:2@_A8JB*H!LF0`K#T/1N +MK6O';&O""8+][$EW +M:0HR#"X@)`@````%````_"$``.`%TQP*I,*N62'5)G[Z;/*U,&8;GV;;'@& +M_*%^3.OHRW1X+<1?IPA+6YK:Q.4I"(T6D>/;OC>?#5L`J\8N_JM2.$#/)L*' +M=5OE<#B\Z"-$22ITR3],41*W1O"J`P#L````[`````(```!%``#H5%P``$`1 +M``#`J`$!P*@!`@'T`?0`U`:YQLJ^>&O""8+][$EW:0HR#"X@)"`````$```` +MS"$``+"&[E@'V%V-Z4Q'Q\>,&H9OT%9A;SS*WL2U#\,^@Y5`)DZYVE!#'36= +M9IS`#EZXRRV7=B<6>@S;#DRD"FY0UN00ZV6J$+[<46#D>H&'G"?OPQ8QJ(Y- +M-KI>;Q0Y-97(LV@!\4M-YULLH!;XLO^I:.>3I[<$B[=@;U(!JQJ)Q+1PY6P. +M-H@[WN)%P!D%.#"ZQO(7>6?O>9@;73G*RT4)K8AY_I%Q9.U$W,A'X/,O41*W +M1OC.`P#L````[`````(```!%``#H5&```$`1``#`J`$!P*@!`@'T`?0`U`:Y +MQLJ^>&O""8+][$EW:0HR#"X@)"`````%````S"$``+#[3[P4TFW3P3^;.;)E +MYP6(G5!3/6P"_$*`/">)>.#'F!\W-U6SBF>UZ1_V:-1JGP3L*S"GXG0(RN"E +M(-B5.Q0&E["M6E&O\29SH=+QR(PA*&S!$EXJ9UH0B]#56AY+T<'\MGIA/>SY +MZF?>29M.'5'_:B&NCPP[WR[@/QO4N+]N`7II"/(2/':F_SSN3LN'&O""8+][$EW:0HR#"X@ +M)`@````&```!'"$``0#K6B/ISAPY3F?EF.'W#K=*D2XECCB2Z&472R'L`M9YB`X-?.6"OWB_`R#E$6Q+K.#: +M^-)2I*;IR7/SEGA[+KRW\6`^0!#+M`-$MOF?[V^%0]8 +M>W^5^)0`&EA-P^1L,E&ZOMVP\/7:N*K^@TN"&4U4;*[T.#'<]?0,5:H/6Z]? +M,"J-`@FG/`QPZLSNDR(J4I*PG6L1$)/`N%T6R=7_,8=S'#,!"]R(N\!1$K=& +M?O@#`!P!```<`0```@```$4``1A48@``0!$``,"H`0'`J`$"`?0!]`$$!^G& +MRKYX:\()@OWL27=I"C(,+B`D"`````<```#\(0``X!H1&D9*S8:$X#N[TL*2Q6C19H&BK4U7CQU4@(5 +M,:TB8T4"CS]'[`IS?.BA#+FI=$H=G"!@P!UO[%8YHCDK]`(LG?@='*$WFHZ@ +M"]D(D((R?W2(!X9=*S/V=AHS:UD4Q_0[)85BU"1 +M*P!::@.^9:L3790UNBRLQ_+5EN:D].X2ME"0;(O/ +M.N1WV8HL<4;CG=%\I]RJ:(<=6&SLF8..FZ^/OY^S`#6FKL83B6&\N)'3@F!Z +MQOE\M(R;ZX#:7#*.A!(&$+I'$K+W_,^+?7!\?"!!HAZ![HJ1[MS"-ZH^4J@F;C=V@(7#MQO[`XT/] +M/7K\(@D_*M-1$K=&*"L$`.P```#L`````@```$4``.A49```0!$``,"H`0'` +MJ`$"`?0!]`#4!KG&RKYX:\()@OWL27=I"C(,+B`D(`````<```#,(0``L/M8 +M^EEWBC5D\+K&[4$GAR=U$TYL0R]PNJ74,EL^3:SJ9"\]]X0V3A*DYEGG:GAG +M<\N55G;8DG]CF^$$9_L-P)B]D6'0*V-6O;$U"H<,$.`.X;2Z/AM*YC%+/[I# +M#GU%#Q+'L,[3>+`Y]+X$S6O"2Z5LDDU)#JN3VPI!_5S"9S>BA8MM +M.;A#+'8R=$]C_6K=>8X&V?C=#Q]?J*![U'B!*06])-("[OQ1$K=&AE,$`(P! +M``",`0```@```$4``8A4:```0!$``,"H`0'`J`$"`?0!]`%T!UG&RKYX:\() +M@OWL27=I"C(,+B`D"`````@```%L(0`!4,2\>^?.8BZ_D"WA_L<_Q0YIFP+S +M*Q#Y%T\'1Q"..@I/57PS/WH7,6=AVW3SM56MZ[XTL&H?"*7*EAC-:)M.HX$= +MN/&TXZMT\@$AX^T4Y*1;YO],(!R)+I+]$>\)6`.MX77D@O(Q?HBHZ;>,)(X, +M[0#G=C>)DC;7VA`1``2[\I">[2S/T2J2:_1!X"`=7HW@OG1M$"`0E(]_=-D? +MV*:JDUL7B"FT$9HW-J]:?_(8,[O)HNNEG^JUA76)!9,JW0L=_B!;)W#2B2T` +MM6PL2>0"_>Z]FOO1H8".Y]`?X2-])H@$%7T3]>0RK"=LSA$DM>8PW#I,'BE; +MTXI!B@]=M32WO/4=.PB'$6=G\^,!$P]2E:@0;5'S>AR6'2SJA'N$J3B*AFR+ +MN<=,,34=O_"DU9A`:^6$P5[`23.4ZF>6[=.X)M+R,AV+3C:(09P%[Q>+41*W +M1L>'!`!<`0``7`$```(```!%``%85&D``$`1``#`J`$!P*@!`@'T`?0!1`&O""8+][$EW:0HR#"X@)"`````(```!/"$``2`108JRBF$W&/.1?IM- +MP`Y9^A;VJ7MAZ^/)0DT&H6L<`'BE#DJF1-UJ2B1^YP=!$A`)APXB]:CEVIJ\`>S?D_R +M'-1&2(E@G3$>C%1%UQ>SYQ_38L@RJX?V!*'H?H#3E5@.KZAKWQAIEK!!N]S2 +M@$Q@FR+P&^CA.&!59,&MTO*16T%P5MF]B.'#U4YAL>'2W11%5 +M,:SD9'F4S,D;!O.(:J:4)$5).A,P%QF1&X$LSZ*56V6B)!&4O_75HZ[]1%$G +M=+$,[#(22]8NU_ZFB9M$<*1Q$G*DW67UWP!7QW"LX)9D3E*A7@QK +M_%$2MT9.K@0`?````'P````"````10``>%1J``!`$0``P*@!`<"H`0(!]`'T +M`&0&27UPCC>):,.;R%A2W?7Z+W,N("4(`````````%PJ``!`&:;IH2\\?_-B +MPX]:VG.,%#S23]'-Z%B-ERIMTYA)]P*1L_074:PG0T\/:9SE*;K&N8U%E$2MT;9 +MR`0`;````&P````"````10``:%1L``!`$0``P*@!`<"H`0(!]`'T`%0&.7UP +MCC>):,.;R%A2W?7Z+W,N("4(`````0```$PJ```PY45Y;'5*-[[NDI*KR]HS +ME[L\"-P;D\-92SS+9:])MVN2V;NJ#7TF#ED4+'!1$K=&[M4$`&P```!L```` +M`@```$4``&A4;0``0!$``,"H`0'`J`$"`?0!]`!4!CE]<(XWB6C#F\A84MWU +M^B]S+B`E(`````$```!,````,#-8@G#9N-W!OF/S$'-EQ3_Y>IXN8'20@(UV +M'^R3XJG41*W1L;4!0"8`0``F`$```(```!%``&45&X` +M`$`1``#`J`$!P*@!`@'T`?0!@`=EH7]B)B"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``V]", +M0X9Q34G$-B>>VY3"9UNA9C:>WI7T5YZ)45+5D)\7TI\[J$G%I$PE90@Y/,!& +M'K>R\?HYE,2--&L\BXA:%=DQ#A(;8:,BG$W9?OL! +MP#IFCL/\W0H,SKKRSIF1F17D=P7D.-DS)S.8=AD3,I?UO8PI```D\32:!!F6 +M#9G(D!S[F/CH@[VHCY^L/D=MX^;;)`01!Z@I```<``!`!%!/VXR@:I4.O+>VY3"9UNA9C:>WI7T +M5YZ)45+5D)\7TI\[J$G%I$PE90@Y/,!&'K>R\?HYE,2--&L\BXA:%=DQ#A(;8:,BG$W9?OL!P#IFCL/\W0H,SKKRSIF1F17D=P7D +M.-DS)S.8=AD3,I?UO8PI```D\32:!!F6#9G(D!S[F/CH@[VHCY^L/D=MX^;; +M)`01!Z@I```<``!`!%!/VXR@:I4.O+]8R!GH=TWY,9O)SBH]I"^8MR8'>$*!4'7-N#B@F*=,8RP_!9M[.67Y[^\ +M;TESW?OI*0``)!0P\ZK-M`DT.KPAN$@Z(B72+'&1K]JK:P8-@```!P``$`%1&G-/EZ/'@^L]EG* +M>Q?G0I:JO-I1$K=&T4<&``P!```,`0```@```$4``0A4=0``0!$``,"H`0'` +MJ`$"`?0!]`#T!]FA?V(F)S$MMLD3T:"Y.YH>+B`C"`````$```#L(P``T('I +MC:DVAO%\VZGT`]1"EAK(GBH;92\]*#6)+0@>$1`%I\-@GRP*R\YD`QC-)WGA +MCC^1XQ="GMV2XW7@S@IB'H"!?V0R7,.X-/[)1D8Q6!2MQT!4T>%LI].RE5O; +MW(1=@7X_`MK>=U[2(2/%L;VQ50:IGZ?X'V"9!$6EG_ +MY0UMP:*?79D/:V6N=TU^2SXP^"XA*+MHS0+!`URZ@8C71J>[@J'8MLE&EFO5 +M(\LN\8J-[@U\T(A!31#`D@;Y +M0V=L/.P<5V$=R./N$CQU+"Y& +MAC9)(+HSR9)RWU8&N"`B!8XL!!A(MP1QY_$&&W2.>Z:$);Z;07;+4RNM'\B@ +MWE$2MT9]?P8`'`$``!P!```"````10`!&%1W``!`$0``P*@!`<"H`0(!]`'T +M`00'Z:%_8B8G,2VVR1/1H+D[FAXN("0(`````@```/PA``#@8TN+S#@$@(PC +M)D3OCU83N.;KREB385"4K"=>319%A9F&>O&$,1KI5M._7B=^ACF&#Y?N;B': +M_*2:30&17C1Y;8D=9G6CY?'H_9VP238 +MCLQ2@=!"S.NW#$M%)O%H@WQ1K9:0D_U\R"7NS;R.<)+_NLDF, +M0-5V#RZQ:2[N;C^X,V>/SU$U]0[K8]9N&41?74;0X;'M$WY;3P$,*JRY1/@< +MD=T'=;1]_%"Y`1:7P2$3`B23;/LU'@N[AF^Z4M;U6U$2MT;DB@8`_````/P` +M```"````10``^%1X``!`$0``P*@!`<"H`0(!]`'T`.0&R:%_8B8G,2VVR1/1 +MH+D[FAXN("0(`````P```-PA``#`]T&&Y>O[KL;]ZS>9OOHHG>;E>?\RC7#73^,I/-O<9(,HYXG+7070CO19`O2B=N=0V/G"(7 +M8`Y].-)@9=4JE^&*@US8K,UKSS\#TPILP,F_",!1$K=&T)4&`&P```!L```` +M`@```$4``&A4>0``0!$``,"H`0'`J`$"`?0!]`!4!CFA?V(F)S$MMLD3T:"Y +M.YH>+B`D(`````(```!,*0``,,R&*2I('28PL8*.B907>>7)U6%2HG*,Y`:3 +MV,?9#!!,ZQE%14>8*]QC!UL'L0=?C$S+\!#%OI>@L(C!H5/MIA`L.WC.-\FA`(0E^, +MY1NIM[O+;%$2MT:LS`8`/`$``#P!```"````10`!.%1[``!`$0``P*@!`<"H +M`0(!]`'T`20'":%_8B8G,2VVR1/1H+D[FAXN("0(````!````1PA``$`UE7` +MD<`B*5;E=Z*$=4.1SQ7A:#B%\*D/P$!UCH&/V"G%['%'0@)6H'@3]Q@[RM@( +MLV%SN-/9^ZOY=EXO[J/9@\>^!8/UDU4AY$/NNNLG@:QN:6@RG-G&)G0:+?/G! +M_2I]BF'.TSA_A2$VP5M`M,C]2MD.PL(B]$!+0;$<(0,']=9[D-O.'*4`*[.B +M_R>B\(3=\W.)LFMG"=G$GU\YA%%^4U%VK$M$6:$3/=DWN/`21E[,M8H/:C,I +MGH.>^80?GE'>^SJ:DK1D1^/D?>8IY)&P41*W1AO9!@`<`0``'`$```(```!% +M``$85'P``$`1``#`J`$!P*@!`@'T`?0!!`?IH7]B)BG$G[HWS`+8V(U^[_L_[JY&Y97=L?_&02N[B28HU +M7^&7>!#EV@Z06R^VP*%Y,>T;?<49.%0@X$.>V/.`8^E`%U!!"J_UXP<%F2EB +M',R$I6XD1/JE1\A/QGZ3JB*!($@WCR$BJ(T%&(,HR:8K[_Y[35GV2Z-7SP!\ +MMP_ZAK029M-^J?E*P_"\F/@8+]SJLB0^A\0_WM>JX)M&E9^?+6ZOP7BL1I6F +M$@G((+YGE#MV41*W1O#H!@#L````[`````(```!%``#H5'T``$`1``#`J`$! +MP*@!`@'T`?0`U`:YH7]B)BX4\HI^9^9P%ZKO,U@/;ICC/B=9(/O@8WSM)H3@$W[D6P-MMT41*W1O<,!P#L +M````[`````(```!%``#H5($``$`1``#`J`$!P*@!`@'T`?0`U`:YH7]B)BX!=SIU1!PES#9*#!<8K]_G5<6!`:7C:[!S/=NO[ +M%JT&AM7K=&#HP=/Q0),!5%T[O4/J?TBNJ@_2X/EFGDOGK9-<3`-YPZ[*.]N$ +MT2F(.^DLT7RC?GC/XFI='V;$41*W1A,L!P`\`0``/`$```(```!%``$X5((` +M`$`1``#`J`$!P*@!`@'T`?0!)`<)H7]B)B39%B"-&\V$&&OJW0!10+I,&%%LHT'3?QT!` +M?\6[6YC[[@#\9?\KT;E_KX9`GLQRACUKN/'XE+6=7!C(([8K707TX26'XPQJ +MVV7JRC2K5Y%I'(TM\@5141A]?$I9_LE%#E623+$]&"8*Q`IZ5=DQ>X7VT2#< +M-2>0,Z&^*K0RARK1'&=SY7;Y\V=9AW95H);?^DU0L$=^BXE1$K=&*#@'`!P! +M```<`0```@```$4``1A4@P``0!$``,"H`0'`J`$"`?0!]`$$!^FA?V(F)S$M +MMLD3T:"Y.YH>+B`D"`````<```#\(0``X!RRI]Z!8>CWW93F[/ZYWFL-]7#( +M).3!_ZY38@>72AKK&"GH`EZ9AZA!MD;^@-K/?-NRPZV-^Z.8I,'8*3=G] +MKJ`-$*?;OJ/X,)G[_P;[/#+%2B"V[KS51K*-(3MLZ1^S]R8N,DU)1$K=&)D@'`.P```#L`````@```$4``.A4 +MA```0!$``,"H`0'`J`$"`?0!]`#4!KFA?V(F)S$MMLD3T:"Y.YH>+B`D(``` +M``8```#,(0``L!P1E4F';12+5''4?"U@`&8D#AO'#YQF$`Q.1DF(#?XJ1W$? +MLD$._C,")>:Y`K"W]`T`TR86%LCO%16/:C>T&W3_6^P"JU"_T;Y.NZ@./L2$ +M%%PPKNIU*7IEUE(.G9Z3B"`QOJKRH,FMC9^,*%:N"IDA3TJ:V%?H64H^/CU,T<(YY;7'`JR,5Y"N\M74 +M)`A1$K=&WFH'`.P```#L`````@```$4``.A4A0``0!$``,"H`0'`J`$"`?0! +M]`#4!KFA?V(F)S$MMLD3T:"Y.YH>+B`D(`````<```#,(0``L&RC@[B9`,3= +M&PB]-F.9)CQ5O87AS,:45C,&_`_&LAM&51\G.JM`]C.PS^![;Z\1.JM:78Q,-:8*PI/[>U([N*,+*^V`XN9;,IJI#-%: +MO8Z`I3K=NTY]?Z<"Y-BO",N$GKGWID@N`"-7Y8M1$K=&/I`'`(P!``",`0`` +M`@```$4``8A4A@``0!$``,"H`0'`J`$"`?0!]`%T!UFA?V(F)S$MMLD3T:"Y +M.YH>+B`D"`````@```%L(0`!4(Y;JMC+G6JP2!&9/S-R?U\+0;/A-GM(VV<@ +MVY/1[&OQ/DQ1M;\/N>*3FA!?*$?]M3K=C0\8VUH\=()L_`(L[6:G%?4I$-Q9 +M%HO=80T7)96%@Y-V>%TWP+7/^E$G$FZ@0SV!9EPET51V%),#8F^3B]D:"I[V +M,"2\[""MM')HOXI7+PV:S&L)Y<\9Q%WXW+A\HT@I[UZ+&Q/B='!H?B2+I%$5 +M!4.Q?R'W(V+86.D@)[:XTF>K6*"*`-9Q;"(KC*2*0V/=3"BQ60=KFRMO`%L2"[ +M;$$B_`/DXRAYE(;!&P039NG9:4IW4"WXN]L&D$[YD"N@#MGHDFBE0\#\QQF/(K+I'GV=K^HS(Y$PI&L?O5G"]#:HWHPP9L) +MKN8!T=_T&_?K8IRMFT_9YMKSQ_H[8;"2]_83@`W)L%(5)/Y&H\,-.8]GI[T. +MNB]>E<3X8",]Q#Y5L,`Y<,IV_IA;WQ&Z#9NN(W.)REWJ[2!9DQ*H:3GR2&=# +M`=VQY.#O<,3`Z +M#HYR'P89HG+\1I.@S@7)$+1PS,P/:/5:U6GG@I\(LI$L%]+Q$!+&;;T<@U'4 +MH5F"A4Q0*8]I85+91E`:V1[5#8&=Y-?F%]M@.\ZYO1+LQ+>H<^&%2+``!`$0``P*@!`<"H`0(!]`'T`&0&27^G +MBN'B442@G&%0YFP\G@DN("4(`````````%PJ``!`/@V;Y/ZEX)OMX1-U+81J +MN>3L'+P?HX.`BF45<4C'!'4'[#IIYQ/'S_FS@)XY.9F+"5]_F +M41*W1C_Z!P!L````;`````(```!%``!H5(P``$`1``#`J`$!P*@!`@'T`?0` +M5`8Y?Z>*X>)11*"<85#F;#R>"2X@)2``````````3````#`PE((3NK#/F*SY +M-K[^+-"_A`'Z^PRW!)[5XF,].6A:]F@[69S'E%G5IKA#W5$2MT9V"0@`;``` +M`&P````"````10``:%2-``!`$0``P*@!`<"H`0(!]`'T`%0&.7^GBN'B442@ +MG&%0YFP\G@DN("4(`````0```$PJ```P_P'O&M#^79"&IC]T,X^L3O`_D;F` +M_`_O+CO!!-P&78&R#9GGGA@;UR#17H51$K=&41<(`&P```!L`````@```$4` +M`&A4C@``0!$``,"H`0'`J`$"`?0!]`!4!CE_IXKAXE%$H)QA4.9L/)X)+B`E +M(`````$```!,````,&+72ZB52?8Q@2BS-YS"D$5C1>""O"*B"=H-9S7E2I87 +M_^'4+U`,3A*&N,7)41*W1A03"0"8`0``F`$```(```!%``&45(\``$`1``#` +MJ`$!P*@!`@'T`?0!@`=EZUR"OJ@K*@```````````"$@(@@````````!>"(` +M`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``CG&L8G#,+L*; +MJZ4,,''$2#9Q=5E(UK/WV9_664/9J-RKOSB=2WGX$D^L!>J-9L4_ +MR>V_````'```0`5"ICC(!R%($77LB,=P06VSR3;[!E$2MT;I(0D`7````%P` +M```"````10``6%20``!`$0``P*@!`<"H`0(!]`'T`$0&*>M<@KZH*RH````` +M```````I("(@`````````#P````@``!`!@````%,"OZ&36$=Y^F<[J2&K4K) +MF2OD'5$2MT:X,0D`N`$``+@!```"````10`!M%21``!`$0``P*@!`<"H`0(! +M]`'T`:`'A>M<@KZH*RH````````````I("((`````````9@A```@``!`!@`` +M``%,"OZ&36$=Y^F<[J2&K4K)F2OD'2(``'@```!T`0$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``CG&L8G#,+L*;JZ4,,''$2#9Q=5E(UK/WV9_664/9 +MJ-RKOSB=2WGX$D^L!>J-9L4_R>V_````'```0`5"ICC(!R%($77L +MB,=P06VSR3;[!E$2MT9+5@D`4`$``%`!```"````10`!3%22``!`$0``P*@! +M`<"H`0(!]`'T`3@''>M<@KZH*RH`D-AJ#!2,2_RY`-7E"L-<7UJHVM5-$W@DX& +M/PB%/CHK77/L&2!I6U)L:QAO,$:K=["*"[*/]&A-OM[/)K$I#W%JN_XQ(]A^ +MW[+'`'P`&.V6$&V;`N[7B+?W<_)U8N?3+CM)>L_UP@9NZC>8^]@T;W]N,(^Z +M*0``)"82=']<)T!DK%F)52(TVQ^?1,NI&:P:^#[MH(-`<\;"*0``'```0`33 +M\U=/>PUSANR>2LX/GQ*R-Z6;UP```!P``$`%[D#I35[J=N-6L&K+XZ`=(YNW +MN#Y1$K=&I84)``P!```,`0```@```$4``0A4E@``0!$``,"H`0'`J`$"`?0! +M]`#T!]GK7(*^J"LJ`)#8:@P4C$OW+B`C"`````$```#L(P``T#J^\5E\'4D@ +MS0DJ(WQ@::O^43-(B'T+NO<=R&XF4W4,SI*98NJ\@V](W1;!Y88L4BD2L(,F08S2 +M*NK&Q\\.27L3N)I:-9E+H#J%KX7#/DSH-CIE,75I?YJ['Z`(Z6&&9MI:DSAC +MNO0482;M"'_]0B#67B/+2O:4#CR0UF(,U)R5A4)>A.$;S8.+.+IBC2PJWRI< +M7W/7<.#4<3>TGG]^**'F=U$2MT:#G@D`O````+P````"````10``N%27``!` +M$0``P*@!`<"H`0(!]`'T`*0&B>M<@KZH*RH`D-AJ#!2,2_,W];AYE=\+31T&TS\YCO%X]6[JF=>#'.SB3F?F<4^;#P_;C!U* +M'HJ'`0#-2A4D2XYU!B`I*5N_'7$R]!4OM3=%4V/B&"V*-;%QMJZ_7Q+9=!>3 +ML7$T>Y\2!MK+Q5&.%TT,(]EB$WWO#7*?IMW-(!QIUUM;F.A8%W0.#E$2MT;9 +MO`D`'`$``!P!```"````10`!&%28``!`$0``P*@!`<"H`0(!]`'T`00'Z>M< +M@KZH*RH`D-AJ#!2,2_?!"%LIL:!P1?UA\B4I8A"V\I;3"0JB\7PS3'U3>^]_DZP&W>GGN18 +MRT,(:.!LW1>X-KS`"V/P?Q>)R%UP:FX]>E$2MT;=QPD`_````/P````"```` +M10``^%29``!`$0``P*@!`<"H`0(!]`'T`.0&R>M<@KZH*RH`D-AJ#!2,2_>DD.EW)35=M,^2!U82V5C?,^8C!A-C6D%N% +M]EHXKL@7;+&^M+589U91-G^BEB(#25AIKRZH]EPIDDD[&I>+9HA0Y72Z2/J<+=5-Y-[3FQ?ZSCCS]A&UPI`)H7 +MS1.S5&@MO-SA9TI)LTNS +M#:][1'R"6^8-"4D_]RYK[F:"%ST2+`M1$K=&L=()`&P```!L`````@```$4` +M`&A4F@``0!$``,"H`0'`J`$"`?0!]`!4!CGK7(*^J"LJ`)#8:@P4C$OW+B`D +M(`````(```!,*0``,&56RD8+C"E)_T'W$>A)!:Y<=U^FSXVT+^QWO.!WP$@H +MG&R\/\BOT),LL$++41*W1JGM"0!L````;`````(```!%``!H5)L``$`1``#` +MJ`$!P*@!`@'T`?0`5`8YZUR"OJ@K*@"0V&H,%(Q+]RX@)"`````#````3"D` +M`##BPMZ.[KC!Z<&,T,"`59<^P!:Z%JM18>W_*Z1NP%QKH#^LW_84=#'\E5E* +M-U$2MT8B"`H`/`$``#P!```"````10`!.%2<``!`$0``P*@!`<"H`0(!]`'T +M`20'">M<@KZH*RH`D-AJ#!2,2_:G@^52P.O$54C.BMS#BC[TKBPG-F0=FCFXZ@:N%^[F57)YS0*9!7Z* +M@QQ#7EJ-[P@ZD8T=2Y<5P+_@KVMV"KF0.)<%G]G1]SJ#UH6^I<#T0DMJ&?V% +M:$P!#H"B$2%TD*?NQ,\0YU+Z>[%E[%VS/0@8#5CS&+=X64F)+9^,/Y4BTINX2 +M?=[2'(42,*OJ3$BNRW=1XQ#.>^F#XSSE'][ZUOWI\96T0[([MX^Q%7FF?ZI7 +MM_^);ZMJS6F2D#!4]![:/1%'#&^1/$;W/FC1_\;MA\?#:^WWE)9\:N]+G#O0 +MN6[0.0B5E$1CJJ6L=+V4D`,B9-RER]?W!0\S#=!/7IR8E:UG]QF_ML6;>[%W +M3"?741*W1C$J"@#L````[`````(```!%``#H5)X``$`1``#`J`$!P*@!`@'T +M`?0`U`:YZUR"OJ@K*@"0V&H,%(Q+]RX@)"`````$````S"$``+#I[LUBP$X. +MD&]*'\LV1O"0[7^%7I3I!9U.L,IVC/RX>_C>=YEEN+"`I]!$U$+ZE7YI_M!Y%'$=B$I-E_OO8!?!-B^G`Z[B+4IA]P4C"B_LVXI +M%_]R_#DKU@.@':!".SN;*GB8`9_R%8FFL)T%+87?U:8D9F$YU7W.[34L!V,H +MBQA/#R\_81&!T?W<>3K3S0A:(74QH!`/>P$'TF3841*W1B1."@#L````[``` +M``(```!%``#H5*(``$`1``#`J`$!P*@!`@'T`?0`U`:YZUR"OJ@K*@"0V&H, +M%(Q+]RX@)"`````%````S"$``+"BWF2ULHL6D45,^`"Q070!4N@2"KR%F,^N +MUK@TFFQS45.8?LTDH=/`I]',Y3]%!4E\'>8#L,+:GFB'X8CNNRH"8QL375LR +MHVB%'IZE7C([-D9$?T1\=Q>F\CY9-PTXY,.7[_5JAR&R(.Y?WWP"8/+$0HO- +M22%#]:6XXBA&#\K#;,]>CJ@Q;GY4"?881*UAMMV41*W1LMJ"@`\`0``/`$```(```!%``$X5*,``$`1``#` +MJ`$!P*@!`@'T`?0!)`<)ZUR"OJ@K*@"0V&H,%(Q+]RX@)`@````&```!'"$` +M`0`"L>$PQ+),.,(X'NY$'O<;TV2SECWI3M0O'0H[P-([9>-07(XO>+&Q(D@A +MK+STZQS];J"I;]@80U!>.T$=>$T"^3RWH`R[+,[)6%ORBG/Q%;+3*B)Q%T_# +MUA+=+$7-=)/7UO^@16WU?Y-Q3>PD8H?\YEBJB:I8,CJB7%`IJ*;EQHHB^9YI +MRS_$O*[D>+2_LN=;ZTIX4:1&E9T0>".$#)PE/)!9I/-/#JG:T:"N&\Z%I[]4 +MH26-!7I_A0RN0`$>37[B?^UWA8B8&LF^??&%=$QA%0JU^PI"#OPW`V06]+"KO$YL>)[E1$K=&U7`*`!P!```<`0`` +M`@```$4``1A4I```0!$``,"H`0'`J`$"`?0!]`$$!^GK7(*^J"LJ`)#8:@P4 +MC$OW+B`D"`````<```#\(0``X*!SKOF7=EIS#3ZG^:&\A%XR'I$1K`]]83E= +M9IM"($4K5'+F"1,FDT,22?697^&8K&N;TL"!_K\"_Y6;;[!SE+ER]*?-JVB_ +M*<;2BY"=#'!RG<"2[RH_2=]#3OG,^V^S[;6KLD6)T`5OS:27-$B67FX*3J7\ +MD6SMNT2EA&K2*!#L4KIQ!&1:.%T_EO7T_Y\%[V!`K&#*K_KOX,#&C&=1$K=&*X8*`.P```#L`````@```$4``.A4I0``0!$` +M`,"H`0'`J`$"`?0!]`#4!KGK7(*^J"LJ`)#8:@P4C$OW+B`D(`````8```#, +M(0``L)7N=!6$1B&KP'G6(0WL@%4:W'.$`YP*EM(+*4/"CXC5K<>DE-1N\0UB +M('!*`(]1E[U:':!*R#-6$U6O2!NDE3MS_9,"9Q.%)WV5CM--?SPZH@"+\,"- +MZ?JPM[75Z=V]R*?)4Q?>$P607N`5@#9LRN&.US4M3XQ4+EY[:)AO<8F9"Q0#:WCEWAJG:=/SJ%S;W&S_/=[DK +MA`9S@ZA/>PYI:0=27R4?A%Y%SZ9R2@"%TN`4QY7+'G;LO<^/WQC'5I)":/7F +MTZEC:%31-0&^B[E[4E +MQT;J@X>9[W:K8[D)JXYCF)NE_GE5+5QZAIH!@%E\94Y[Z]#QZ9_ZZDJK.0TR +MYG2B38B,)$8.=SS+594>T$;V-Z:BT9TI4O)H4[UCF?A+S\F8Y[&%ZT4CV#*) +MEJ^82.23^A?:=&U!J&2,SFJ00N)>;VG7I.#E61`E^T#GW16X:"+-+*PYH`V>\A--!JJ:/>AW@YX&.!'>TR;,1MDHWG=(M>,941*W1FD$"P!<`0``7`$` +M``(```!%``%85*@``$`1``#`J`$!P*@!`@'T`?0!1``4%?]ZZMWDSBS7I80X4.]Y`[.K+=2P +M0F%(X"Q?>M9*[E;#0P?CXM+%GIZ3AU`P[.[V/:HD.K8%8TX1VL_+>]WK/:W^_W +M](A27RWQYH.%2I``!`$0``P*@!`<"H`0(!]`'T`&0&26\":1;X0FW' +MX$%GJB`Q=O0N("4(`````````%PJ``!`\_2*GPLS`AW^DDV!MW1M3ZH*L//J +M9#P0-/=^8*ANW<.K@$C\`%BJ(#%V]"X@)2``````````3````##U`/>GR"#301U=NQ(@B010L`;````&P````" +M````10``:%2K``!`$0``P*@!`<"H`0(!]`'T`%0&.6\":1;X0FW'X$%GJB`Q +M=O0N("4(`````0```$PJ```P.;B(O056IMP+*!.9?CPNT,M>.7B4,/DHM=F]G29X6_FDR#H8 +M#1C'AAB"41*W1E5.#`"8`0``F`$```(```!%``&45*T``$`1``#`J`$!P*@! +M`@'T`?0!@`=E'6+<8?"WKJ(``````````"$@(@@````````!>"(``'@```!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``F'+"+H.B\O\45D +M;,`\,S[IU.NTV`N)??JA/X13J@("LVJC92]Q]5F^G;#/=_],M,9"'NEJ]RJMQ;/GP@$64:!3%G!5-SZ&_!(<;U0W)HX0F +M66J\L7"E8+8DKH/0[VD':0XQ5/<[SZ0I```DI[N&KX>6X.&S2W"15BW^':32 +MH.PECYE\(!MFT'2%?RPI```<``!`!'BCM%8.@B>6<5F[`'%ZB.9UM:,V```` +M'```0`7).UL/H?5O4^U@:RT,+8N4YB2X=E$2MT9I70P`7````%P````"```` +M10``6%2N``!`$0``P*@!`<"H`0(!]`'T`$0&*1UBW&'PMZZB```````````I +M("(@`````````#P````@``!`!@````$163D8L;P@[#\WC.C)=&_@27JT@U$2 +MMT8(;0P`N`$``+@!```"````10`!M%2O``!`$0``P*@!`<"H`0(!]`'T`:`' +MA1UBW&'PMZZB```````````I("((`````````9@A```@``!`!@````$163D8 +ML;P@[#\WC.C)=&_@27JT@R(``'@```!T`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``F'+"+H.B\O\45D;,`\,S[IU.NTV`N)??JA/X13J@(" +MLVJC92]Q]5F^G;#/=_],M,9"'NEJ]RJMQ +M;/GP@$64:!3%G!5-SZ&_!(<;U0W)HX0F66J\L7"E8+8DKH/0[VD':0XQ5/<[ +MSZ0I```DI[N&KX>6X.&S2W"15BW^':32H.PECYE\(!MFT'2%?RPI```<``!` +M!'BCM%8.@B>6<5F[`'%ZB.9UM:,V````'```0`7).UL/H?5O4^U@:RT,+8N4 +MYB2X=E$2MT9-D0P`4`$``%`!```"````10`!3%2P``!`$0``P*@!`<"H`0(! +M]`'T`3@''1UBW&'PMZZBH5%O`JLEU1HA("(@`````````3`B```P````+`$! +M``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(` +M`,;V0@06RNL1:H8R&D+_9U\Z-[-'6PXTKFE\;,,T)AU_TG.#-"YM(NQIP73[ +MVFPFU:E]\;Z@O[XW?SQ1!`%1>_YXZ0;7X(P*\<:S*OAO)=H$!*0'*LC&_RE" +M?6GVDNZ<:R3MVPV.=LWU5_TL][\0"0N\WRRV):F-G`N?)_5(5!5?*>AV*0``'```0`2(K2XDR/(" +MF$+`UW5#&"XY\@```!P``$`%Z#3R05*A>!J>[)2.7NG$3+GK^4I1$K=& +M)[X,``P!```,`0```@```$4``0A4L0``0!$``,"H`0'`J`$"`?0!]`#T!]D= +M8MQA\+>NHJ%1;P*K)=4:+B`C"`````$```#L(P``T%.MLL'U09PR^I,2?-*> +MES\"K:]ED6EK>C=:.X*BV'\P28:RH>Q@08>KSYFI+_5/>([]4P1%^H%0+2PQ/F@<$R1A0C^%LD!]W7Z +M5GSOG6`T[\B0(?_M,Q3FEPOMY*I_Q9Q`=^RZQW/,U_P5K@P(6FVXQ%#`#G@` +M#VWX"EHH#/Q&%6',_JR70D)&KF\S`D^#F+A&I9Z>52")(Q[ +M^],VWTH^^G;^$XP6))-(U`=S07?.G,6%_.F`D8;C(^GCV__8A6?L6!.X+7AL +M<9[#<\E@_-DC%WX&BZZZ.LCO(\!M@D&]&24GCQ7OQ&R`#5$2MT80]@P`'`$` +M`!P!```"````10`!&%2S``!`$0``P*@!`<"H`0(!]`'T`00'Z1UBW&'PMZZB +MH5%O`JLEU1HN("0(`````@```/PA``#@=),)4J,ZG4@3S^94O<8=FJE$SLH^ +MU)G+J(V)7L1SHJ6L.<;NX'D4Z/?V@^]2B.*C"8!+@5M)-*8H$[J#'LEV\Y*T +MV2'RV?@L0I=#4.>JBF=?BL%7#B]G4P0ZVS4`%DECTRU#!"1W)=#NXX$1U3L_ +M!$CRP.T55GGKT909@"6%O3NM;< +M;41]XUR(:QS;^UMS:K0/FL9R2E$2MT9V`@T`_````/P````"````10``^%2T +M``!`$0``P*@!`<"H`0(!]`'T`.0&R1UBW&'PMZZBH5%O`JLEU1HN("0(```` +M`P```-PA``#`_FV\'@?1D5.;-6QD1:\BM=@Q2GBTWP*@:_0*EN[HIHXL;2;* +M!-+L_;%']4O<^U`OW0 +M8"*D9?->&"SI&^UDUKA[?LO&V>YH\5!9)^L.^FBA97\4`R./EUI0CE@`FA_( +MG00"%F9;'6414UJ3*;`.*H,EC=AD%&.>WP*8D,-`8\2KZL5?L%('!M+#&`7H +M]&M'VK64R%^4PI$!,+_!'TA1$K=&20T-`&P```!L`````@```$4``&A4M0`` +M0!$``,"H`0'`J`$"`?0!]`!4!CD=8MQA\+>NHJ%1;P*K)=4:+B`D(`````(` +M``!,*0``,`#(%HGT[3F@JA$$.U6X)Y0>\7`Z/'>#\O`!OWZ26O,'H)!WF4GC +M/E>KWX[Q41*W1NPH#0!L````;`````(```!%``!H5+8``$`1``#`J`$!P*@! +M`@'T`?0`5`8Y'6+<8?"WKJ*A46\"JR75&BX@)"`````#````3"D``#"KB0Z/ +MR\$ERV_>9X0Z:C7[HL(FZ$5KT;2N8IR%>=-4G&VC06Y%H%AW;""IQE$2MT9] +M1`T`/`$``#P!```"````10`!.%2Y``!`$0``P*@!`<"H`0(!]`'T`20'"1UB +MW&'PMZZBH5%O`JLEU1HN("0(````!````1PA``$`GCV9\/2K-09+EKR=7,?; +M+8=K_]-1RI`DCG43#)W/CG%)YJ%%A>CJ +M[=>'@&F&A9,7>G2<+J9NS5&@N)WY8V]\M0=R(V-E(TX??$\B*_>/B%![QAVC +M;$?Z+]^C>JAFSEQ!.00:M>!)*$BW@8;0'="BM!B7KV@@E9\QD6N!]%+\4V;P +MU'N0K2B+3NL!\[:VUQUB8SR*L(Q[*8;BJ92K`<7FI)KPV(AP!V)F7,.]09D;L(FD.T5_TV'+A8 +MCS*[2EX00Q[[\22$41*W1F!0#0`<`0``'`$```(```!%``$85+H``$`1``#` +MJ`$!P*@!`@'T`?0!!`?I'6+<8?"WKJ*A46\"JR75&BX@)`@````%````_"$` +M`.`$L)3ARW:^MIM[](4!?98^[2&I(7XJBP9RD)@,6R(;\M^_\FDL@A<7Y$5C +M9=B"^*[QC0"$#]WLOS[QQAZ6,O@K21003O2<"$%&\%&Z=1$SP>H3U_5@E8"* +M'P%^RYEKH'9,[`/,:\+*K08M^+8'\&#JUP;RP/3=J5)1A!=!W%<)K$ZW&R2A +MR4"5?V?8].)6]N;/>)=G<:4[X%OS80-&9WWMTDC;H%W"6D9;5!-+5)>98H4? +MHXX6C$\19).5WF.A6ERZ/8-';#R3?CLRY_K]-AR*@YY68C4L`BR@CR7F41*W +M1NI?#0#L````[`````(```!%``#H5+L``$`1``#`J`$!P*@!`@'T`?0`U`:Y +M'6+<8?"WKJ*A46\"JR75&BX@)"`````$````S"$``+#&ZP>R94A`3_6RSCS^("WUJ6X#D"3_^`^(U]2<6,84"5U[(G!Z`V/IUON4#<*& +M4,<[&7AYY*=S3;XXW`Z.*TDI;Y>U`&;?\]AM&#SHAL%6\!0,]LJ4:$)9G[)* +ML`_S\1(#+P+*Z>P8=!0)=)K=3H*_745K41*W1C:##0#L````[`````(```!% +M``#H5+P``$`1``#`J`$!P*@!`@'T`?0`U`:Y'6+<8?"WKJ*A46\"JR75&BX@ +M)"`````%````S"$``+"TN@H0Y,8%JX[ +MIM;56`+Y&'H]A-_A5C+#?M%;11Z,$/8E6+J@*N!5N*Z(?7` +M+9"&/S>6.7_^1L.[_6:^.!;W6?$""C>5N<4\&:N64KB\98\:OP9<7`B;`=4R*K^L8Z/O<'ZS_K)1L.A>]J".G:0]D4*OA +M(K)3S'`I$B>$Y*5GPEH!8H;"E=3848'R%*TG4..YHU64"+[-:&833=$V9/4[N4O;ZF/&2Z6UW&>^(9`<2 +M=TN\\0*N!4W'OBZC-K>7\,99>G3;Q@%1Z"K0-',@LXVOK85,YQX#.:,<&QOX +M@/]&HJC5D\[>\$73;^G(V?EE\E9UP/M1$K=&GZP-`!P!```<`0```@```$4` +M`1A4O@``0!$``,"H`0'`J`$"`?0!]`$$!^D=8MQA\+>NHJ%1;P*K)=4:+B`D +M"`````<```#\(0``X.@D&=#67J"-ZM`K4VT]>8AR8-GUHLJ7V:RSIWBK\C2-)WUOU4;J^GD'2CSH&J*"C +MQT]\N.2^X!3:NWU7]*KG9[4"'$@H_717RBF>PUS`[?*'2>PQCI/CD`0Y[/#RN&;F6$*<9_C@-JKG=1FA2 +M(1RQ,"KM7S1G7.@I!!`TLXK@.O$;=.$Z:LW8:U,"LNLO*+,@2X'3=+1AA.=R +M/H8XN),"X=!1$K=&'[X-`.P```#L`````@```$4``.A4P@``0!$``,"H`0'` +MJ`$"`?0!]`#4!KD=8MQA\+>NHJ%1;P*K)=4:+B`D(`````8```#,(0``L(NJ +MH/F";8\V[$,'",\Y]==14[45C4[*6T^WPY7T=7WC:0Q'79#YEIB3D82RBR6M +M!>$EWI3XOQY=,-)NU[OY:-2C!3@SDJ9:8HXB)AD6%AO6C-)X-IQ"!A`_!`UI +MAX1UGL0`2V2%4AW*S_O6:&;[$@8\]TBB2[LB^X7="BI,G[&1?BTM=7\K/5K# +M\E#T*WAT\KM*O)DO?]8E,S)\^E!XE_<8PQ4&>"NC4FOJ(G11$K=&@.$-`.P` +M``#L`````@```$4``.A4PP``0!$``,"H`0'`J`$"`?0!]`#4!KD=8MQA\+>N +MHJ%1;P*K)=4:+B`D(`````<```#,(0``L&]TD')@;_F)+(F_KJZ%0E_,/YS@ +MY>SDJ,,U>U<6=-:$ND!6V%\GX_K/9A_X,8S/'8-//@K5G9%T\_X0S4D"MC^G +MLT1+Q,-,I*7@CV4DT?=Q=>N,4(LBC>_C&.<,H4!ICC*%V%5N+CW(A/6;GOZ!]!TW,K-B +M[*!;RL^$(H'5&-'N:\(X0K91$K=&^P8.`(P!``",`0```@```$4``8A4Q``` +M0!$``,"H`0'`J`$"`?0!]`%T!UD=8MQA\+>NHJ%1;P*K)=4:+B`D"`````@` +M``%L(0`!4/%1KJ5!:)2^P_X4\1/VDH]SHL$_B[^Y!+>:I1-5%45CZ&,SSIN> +MS\BCIC=2X08NX";H:C466\N"\++GC4G0;T/C60PFZRY[.J-(0>@_ +MJ]?-FT*>OQVE_R"'9%JZ\W`9"K_F +M,R"G@_;,LI]LHT)3M-+-6M([^=T>!BR:^:)J$--1CK04DS)+4V)2\USLZ'PK +M*4=A#WOH`^^QP`D)(`$:O?G]`@("X6O@&J&6HS.M_;A9%0OMGC^/F25AAFYD +MX6\B3F3;C:]R![+/IMH1.;A`*`X]AE/P`Q]>S=H@RMB0W_N_020'>)2B`3D- +MPLK057"&\3=+CK]A)-!W%Y(//URYW5,81)19"-6]^!PP-U<3P"6/_L9N3S&I +M:_%)TT*!OL)?1\"$_'2T9$N/O.7:V6G6HC3,J[$K\7X&&.L7[,CU-%?3&4I4 +M^>RK9("RVH*K-$<5V&OZ9/>DYL;V@U'\'V/B_5$2MT:,8@X`?````'P````" +M````10``>%3&``!`$0``P*@!`<"H`0(!]`'T`&0&24#25E%JNL2TH58#`,U+ +M7T8N("4(`````````%PJ``!``E9W5`\XR64PHHRQFDYRPLOV[?TUNX(4/W2> +M3C\406N%6BKF(18NF'6O\S*RVIS\?!_:XO-Q.R6?&CQO41*W1N=N#@!L```` +M;`````(```!%``!H5,<``$`1``#`J`$!P*@!`@'T`?0`5`8Y0-)646JZQ+2A +M5@,`S4M?1BX@)2``````````3````#!524`,Y4DSN',YG09+3+#N-HV?86M2UV_W-W +MO'GCY!W=G&/)Y=A1$K=&:XH.`&P```!L`````@```$4``&A4R0``0!$``,"H +M`0'`J`$"`?0!]`!4!CE`TE91:KK$M*%6`P#-2U]&+B`E(`````$```!,```` +M,..H\`-8-\0C8OE3L4W/G*U(A_T6.?$E'Y0UJ%E+PH984OHP\A8<)4:4'/$E +M4A*W1KI'``"8`0``F`$```(```!%``&45,T``$`1``#`J`$!P*@!`@'T`?0! +M@`=E9=+>Z5P$3!<``````````"$@(@@````````!>"(``'@```!T`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``J+X*0K*NAS2>ZTO[^@%_88"";E" +M1ZYMWCP3,I#[J$F8$$VZ:HP@U%,ISB*[LF!;/'3&Z&5/D/TZF-R.U$->PMI3 +M_-C2TW%1)+O;I6_-5(2MT:(5@``7````%P````"````10``6%3. +M``!`$0``P*@!`<"H`0(!]`'T`$0&*672WNEAS2>ZTO[^@%_88"";E"1ZYMWCP3,I#[J$F8$$VZ:HP@U%,I +MSB*[LF!;/'3&Z&5/D/TZF-R.U$->PMI3_-C2TW%1)+O;I6_-5(2 +MMT8&T0XP3*<'R?@` +M<<]E`<0X>[FRHWLG/ZWP8)\I&!YWP'"6P&WX%UU]2\!^*0``)-\HO3;Z3C"B +MP5,H9&LX,L02@)P3J--+BQ33U%JO_&O8*0``'```0`2ZR71",5EPT/U6-YK< +MVB,8H+IL+P```!P``$`%F!.LL3[40U*#%;R#78<=)5OG6(A2$K=&V+H```P! +M```,`0```@```$4``0A4T0``0!$``,"H`0'`J`$"`?0!]`#T!]EETM[I7`1, +M%]0?33O#H6HE+B`C"`````$```#L(P``T*WQ]:"**O-VL&PS>0+R-DFG3YV^ +M\#5?$I:;5\YK)IK*=Y=C)@*T\$*`2<=%T-J#EWBIRE57Y(8QN(-KJ[AU\IY5Q$T.H4=^!^OADZ:Y)R\2 +MH`&5+P:&B/8F-!V1_7GBQIGN& +MD7S(A%29KWP!*(GE5W<*`&]?_(T2\*/)<+E`]W!-C9@]DGY084_5`OA.&;T" +M>K)0P=TXW7O%V]MJ=_6J,7)C(+9\<;I]TK+0OW,G(2-Y77(&:_/URAQ_TRW6 +M]54_1]=0,?%S(31'>])EV2+Z+4(0:3(@`@/ +M!9]%8GXJIL](P<',N%(2MT8U_@``_````/P````"````10``^%34``!`$0`` +MP*@!`<"H`0(!]`'T`.0&R672WNE+Q7_O^R!],+3WS#K7U!,/XA*P* +ML`*LQ+AXTI,$&?6S,AL7'1.(S^U.'2^UK;8>T6O\.BP9EJRL<(9U"'8[7Q59 +M>9Q#I/U7!+&6EQ$\"1"Y$C]K#^1OY'VF/*0N-5K7N\>TVN'H1Z+,3B+'D%OL +MO:48:J9B!G_?32F&&/=K35*8?ZC+7$QNQ2%:"\VUJK^(#M*8%7,A&=:I3:*A +M6A7%8F(P-MBA6`!2$K=&UPH!`&P```!L`````@```$4``&A4U@``0!$``,"H +M`0'`J`$"`?0!]`!4!CEETM[I7`1,%]0?33O#H6HE+B`D(`````(```!,*0`` +M,#$[/UE.I9J4KXQ,P!&>IL!:*NDDKZ6#4Y)L`-0*54$5PM?\.8,A"/BX^`3A +M4A*W1C`H`0!L````;`````(```!%``!H5-D``$`1``#`J`$!P*@!`@'T`?0` +M5`8Y9=+>Z5P$3!?4'TT[PZ%J)2X@)"`````#````3"D``#"\JSKM=J&1L12Y%$\RWP:6&'YV7;*96UQGK7QDI/ +M,O9)B')+_H$F6D`)XS>#&^B0+WRC^[=<8['7/)MC7NM5HQ=0;4!(S&(;YRK$ +M54H]==O5?XKUG49+[FS12M'3X]7.<_F;[-D>YO1ZCQ:')@'RTI%[9_F+2%J4 +M`:?H_:FLF]&(MO.GFGM53PA6E.=Z5P$3!?4'TT[PZ%J)2X@)`@````%````_"$``.`CD,/) +MW`R-2XB??HNBQ-FSD+<45E,P)AS-)EQF`/A,'G:&"R68.V[W^4=8PSN%BU<9 +M-:#6U"\[G(=)91GD^H-]1>B)0M0#=Y8#!!OIXVHW7C#B&:(*Z76\+0.\;4V-3U^[O%$+5H*X\7`^+5"!$"GM-3+@"%HO^(KS)CB%Y))<>EFB6>C%=& +MVC#GBS#/"ZK-]]@"-:X9!;)*,@26A*'#=&UUFJ6`7,;G'6^YEM<#8FI,@#P+ +ML`QX2^G>SXRQWN)92/_NZ\;4M^V!W\OF4_J55[]2#+WEH]^H4A*W1H9?`0#L +M````[`````(```!%``#H5-P``$`1``#`J`$!P*@!`@'T`?0`U`:Y9=+>Z5P$ +M3!?4'TT[PZ%J)2X@)"`````$````S"$``+!`KJX,)=$(3O"VT#@*@M<=DR;1 +MSF6<9L8^/K\T^0U2"+]U(@5[!>0HN^'M5.J3C![@>C9I$A6_0V.DA/3(L^B& +M`UHFQ0&,%]MV)3?E4T:6=E38NIXRR(=#A[)2+HJJ;&FVDTQ>B6;R@\WW+BC5 +M)H=:=WMA:.ZH9)_?%MP*1R"W_;5>]52?AH0`+]0>`Z.);/&!"LF[02_QZ5P$3!?4'TT[PZ%J)2X@)"`````% +M````S"$``+#4HDUJW/'Y6(I)=`6\[_ZRX!/U&Z&KB)$"F5DP6;`[)DP<\V6E +M;Q7Z+6%JPAL43\#[$H5VDN3FS+8I6NQIO%/)[K/!+F`-'Y&0&R=VC@KV;_X9 +MN;FB!M4ZIB5^2Y6RGL(LE(%6-V/3D^O:^:JI[ZY@]WRLW?1;7XR1Z/T=R^T. +MC"H4O=9V+`&;8H:5%LSF`QDZ3ZG)0>`0`\`0``/`$```(```!%``$X5-X``$`1``#`J`$!P*@!`@'T`?0! +M)`<)9=+>Z5P$3!?4'TT[PZ%J)2X@)`@````&```!'"$``0`^OU20SEM7?'5C +MG%\YO?T%Y!S3G[EFX>=,":-@"V#+5.)<8R(?R<[)Y<2;4^YUE^?RM)09'^UD +M_W5>2#@@S]08)/Z,%%9+1'(0L,8/*"GV^P,RH()-D$ICKRSN%C;>]%.Q+=3Y +M>!IR5615[7CR_BF&L2^-`D)1/.K#+BXJ$.JN$!Y=@_2BJVGOG'XR6?DCYLTW +MP0+)/&8R^M3'/,*JW[IL(NB*YH9T(0)^V5AMR[QU[KJ*X&@KG*2DB#D?!-%% +M.!2I4.:'?`+W"`H-`OJE['YX/&`C/<#R5T[><*Y^PD-PD)9^'6,]+8"+CKQY +M`Z98!UO[/._G9:91A>"R5IX>]+"I4ZK@1UZY[%)TK![(N@MWT'O[81Y,-9*E +M5]8"/F,;(AB3.\`*\,G:LM8ZN?\AUDA+I/G[T6>[XQQQ1C[O[-DH5D*W^F=3 +MO'S>:#I76=8H`%.P9>1!^<4;TT$SD(5X)*/B^.658FU0-B#ADVWIHA*[4K'B +M#NF0=XS@=!C1:#[N201`-_9;B2"RY.FI9DT*8NKC)($2(/;&L;)]I*^;GF?A +MVE]2$K=&6;L!`.P```#L`````@```$4``.A4X```0!$``,"H`0'`J`$"`?0! +M]`#4!KEETM[I7`1,%]0?33O#H6HE+B`D(`````8```#,(0``L+\4Q6,N4W%< +M'B^%KGAF:D9PUK!)ZQMV>180Y'I,;@E5U@(Y^P^7D=R^I7@#%Y>CF?KM\_%J +M`CW[37N_YY4"[8G/,(5FY1;1WL5H#[WW&!DEJ>&;8"ZEH+J`@,JR"")3B.:( +M#?*+*?$08Z/>R;;6'.5]N4Z5K[<`] +M&\KMQ2<1'1EQP*>Q62>JA'VV!?O9E_3M;CFI1*-*BB^J_C=O`S-,\E4M1@*] +M%65OW?GQHD@$LJU2$K=&&@4"`(P!``",`0```@```$4``8A4XP``0!$``,"H +M`0'`J`$"`?0!]`%T!UEETM[I7`1,%]0?33O#H6HE+B`D"`````@```%L(0`! +M4.FZ1!^?;_;5\I#M6*ZN:\L,A!W[RT+G`P_3P32:C$@U^E+3,C\*FZ)Z\/RF +M:ZAE!\^BUYZ93DO;FV9?\M>XFEZ*AV?09SOG<9VO\0R[J]+?:+%UDFM0MXOY +M;D^AJ$?C98-8;D;F4GG:M=T*''UY,`I<<,1C_,D@T)=2M1K#J]#Z`D;N^YL2 +M,IC4`XT(8*)X*L8,TO,AJJG,AB2X7*U"Z;5?6N#CG%.;14&1B)&'/KLV6TC& +MO;(D+U64J[&$&[!?-2.*B)[[1 +MU[QQ'ADHE7VW/N6@/7XXF]J!_J7AU1$ILX.R +M\#OGJ'=T;N]H>[D`DC*&JV2+AE\O8WA(8<1)/3.HV_Z(&4E*/H1((RCQ.-]V +MQX&L2KIUW$6V7U=MWLEQ6LY-4A*W1H\Z`@!<`0``7`$```(```!%``%85.0` +M`$`1``#`J`$!P*@!`@'T`?0!1`Z5P$3!?4'TT[PZ%J)2X@)"`````( +M```!/"$``2!5X0\HGSQXBS#+Z\:=`N;V(4GUC_1(#4TDU)$(OYE>-;"O)L`F#<99;-SA? +M\[.M^^*5"CAMH[E=,7'6%]'UFW:%$'I3P@2?+8AL'0EDN1Z_3N +M]!Y80A/]Q8N@-"HDSG029WY%3G``!`$0``P*@!`<"H`0(!]`'T`&0&2:;149(-,9?X]5@HLN("4( +M`````````%PJ``!`0CV!-UA':8YQLY4,:_(Y@_,DO0P(A]TV;YOW^<_*+IOW +MO92%V[*0I"#3F@P#1@L9LVGB*?_]+V?TA6>"4A*W1FUN`@!L````;`````(` +M``!%``!H5.@``$`1``#`J`$!P*@!`@'T`?0`5`8YIM%1D@TQS.(Z=YE_CU6" +MBRX@)2``````````3````#`CHYV7%;CX71.M&5ISR7`I@UUM@$+V-(E0]"4" +M="R,L=GK]6J98M&'OD,R$U(2MT84?0(`;````&P````"````10``:%3I``!` +M$0``P*@!`<"H`0(!]`'T`%0&.:;149(-,9?X]5@HLN("4(`````0`` +M`$PJ```P!:"FO9(6]OK=F#8JDS.O[OSW/:4.5^Y\L>J2'80)IG-)`9F2#.[[ +M'SC_7P]2$K=&(XL"`&P```!L`````@```$4``&A4Z@``0!$``,"H`0'`J`$" +M`?0!]`!4!CFFT5&2#3',XCIWF7^/58*++B`E(`````$```!,````,),5=Y*- +M.P^RD#4FW$`'92N&&R$3_&.&;O5837.'_?1/;2)@RAWGA-D;!J^Q4A*W1EV% +M`P"8`0``F`$```(```!%``&45.P``$`1``#`J`$!P*@!`@'T`?0!@`=ED<%A +MK+F*0XL``````````"$@(@@````````!>"(``'@```!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``_2:JZF3ZZ^WS@2"T[Y%^Y(66RA`CX!L4>L1S +M'#H;89">!1!N:J$HF]0<'XYBW`$N=N?*-GV<=I"BO`4K+,/>?"X?`IA;@-0] +M""#?CMPX6^6A)NU4+>\-"^T%[.FA5U[L((SZQ144L:5Z$N;#Z7^1AZAO3PO; +MWZT/KW-G381H'T`I```DR6T]V[WP"54WK8\593@^3UZ\]7MI3/-4B:(R.+SP +MG'\I```<``!`!+5\H6UG958.(N62JBFAPPO;V%*:````'```0`4'&XV>R6RR +MQOF46PL0L1S'#H;89">!1!N:J$HF]0<'XYBW`$N +M=N?*-GV<=I"BO`4K+,/>?"X?`IA;@-0]""#?CMPX6^6A)NU4+>\-"^T%[.FA +M5U[L((SZQ144L:5Z$N;#Z7^1AZAO3PO;WZT/KW-G381H'T`I```DR6T]V[WP +M"54WK8\593@^3UZ\]7MI3/-4B:(R.+SPG'\I```<``!`!+5\H6UG958.(N62 +MJBFAPPO;V%*:````'```0`4'&XV>R6RRQOF46PL0*YQ5"MF^T,:: +M51'\O:>HO29%/66R1LHG'Z%_%.KULA[MOKH`'F?"1&:PHSW+<,X;%?5+>8D->'O,6OJMRKTVU*U*1>L@!F\0EH*0``)%,P`HP4L1M5Z8H8/:'? +MP)@V/IDS)<(JZ#:LS#3RQ4"1@(FF^]_H$I>85(N6/QOU9ON` +M]&H!X0R^X[VW6O)9$,_`4H<8J6K=I\`18K_(=R>Z"Z&I)2!YNRBX$Y]2R0@& +MP,O(/JK>TP]Z'_NQB9X>LX:1>3F7P6[,%)NYS2R9T#GM?/G,!, +MY`1*/=#Z7QP`2;WKEN(`NQ;43HL"?ZMJ8 +M$XE.+`'>11$WOK4U'L7@C-?!RD4,7BK>%G8R>]%\6Q +M+I4R8K#O*@>'RP4E?Q,R`9E](]<5]Z0)LPM7 +MY\:CIRE7=:*@B=X!2^(5_"GUDINC93>C`;E,"7>G_CZ0BO_VIC1`(+_?+VK- +M7HC08[VAIED4M/GCPC87D#J1]&;PISU=SN,>F1E`#SE9Z3)=45P*!]^,@YL^ +M(+\"/L0]9*@8$0'+M2._1>`%P23ZD``EI,=;&W)DG!`N\H][RX5'+K`LJY6M +M:TBH*FI[(%(2MT:6/`0`_````/P````"````10``^%3S``!`$0``P*@!`<"H +M`0(!]`'T`.0&R9'!8:RYBD.+95]24XL0A%;O(@F;:QU%7#8M7Y32E:=%TN!-558AWZQ./;X1`;\-BK.=GPQ*[,9, +MBV_W.+D28F9:BH@7L-AE)+A2?B#OWZQZ3RB\EV]@XF>VR/D+4!51,H:"LEAK +MB+>?=YJ?G\AF[[M@?^$S;<(0CR7%/MLMM442`?KK](%6N)P)+P9'UYS;ES&< +MQ-!_W`K+(U1UF:"O1>062><,03``R)$J0VFUR4%-;5@["`=08CW\'+2$0\RQ +M_T%BWZE2$K=&)$@$`&P```!L`````@```$4``&A4]```0!$``,"H`0'`J`$" +M`?0!]`!4!CF1P6&LN8I#BV5?4E.+$(17+B`D(`````(```!,*0``,$=QGJ#B +M8\^$\UNBHPN82KO"\9P`7,4]W^*(3^M8<&:4-.OM+G#5HC<^F4A*W1H5C +M!`!L````;`````(```!%``!H5/4``$`1``#`J`$!P*@!`@'T`?0`5`8YD<%A +MK+F*0XME7U)3BQ"$5RX@)"`````#````3"D``#"_#H3L*Q+Z,8Z1D-MD_^.2 +M'OT/RS:R=&^->[$$NS#/BA=^UH8Z7@/YR%^KEU(2MT;=?00`/`$``#P!```" +M````10`!.%3V``!`$0``P*@!`<"H`0(!]`'T`20'"9'!8:RYBD.+95]24XL0 +MA%"Z(S]UUCX5\2O<.[5J4TE.LJ1I<4"R0T'?!_$BB@!+^=_9&CCML];7(V4GV +MNTY/$Y&C?]R\Z75".,!<$Q9%EM\K[!&KDP:37P=1X7#/2>FNO2N*`;[6O6S@ +M];'''U@F,A\HP$QG]76B&&C&0S[F,]U9IW\GZ&>?I'IUB +MOQ8NYQCB4$>Q=U/Q_J:,X>`H<2B+M09LF'?]4ZQFIP=LV05%VDE=J3-ZW?9F +M7N-CNY^!9Q!@7>);/(6!L==-&SP\\=,6;/VYI`.D8E7\#-&&YC^+J7=!LF9H6G^:(7GJQW8+7V#3X`!.]93A#5 +M/OIJY6>'W`4H!"XY4A*W1I*Z!`#L````[`````(```!%``#H5/D``$`1``#` +MJ`$!P*@!`@'T`?0`U`:YD<%AK+F*0XME7U)3BQ"$5RX@)"`````%````S"$` +M`+`4QZC5C/?N/>?,<(C6KYIJA+ +M.9G!AK"UA3\PDSMPY!<."JMLUW\5/[#5;QZ*_*<<5=?I@!OJRF"$K^6X?94A*W1LG7 +M!``\`0``/`$```(```!%``$X5/H``$`1``#`J`$!P*@!`@'T`?0!)`<)D<%A +MK+F*0XME7U)3BQ"$5RX@)`@````&```!'"$``0",J7=QZ8(D*U9(92H2.5." +M74QPR491H4Q+DP!21UE%83PJ,=`VI2NE_Q%7B\0@U37]1$'K+@EL$!8[XM5P +MB#V%/`)(O!::KSU>:.(F6C&W(P>7'L0?0U1I&4.!/08HVM@%`4__C'HC@DP2JE!>Q*)KN( +M\).%ZO\WW2SG^=C8@M0@%;,'%;^$KUQ4P?.AA3ML%[>Y]LT12KU\ZZ/4R9B$ +MKZA*8"M:CE-3\A@ +M!F1`0!7%2XJNG&XO,5B8;R4_TQ"TK7K*8LF>-:TS+'M(VL]:8^16$]\-P>JC +M-#I9N^:CC]\:`S*S0M.@6ZU?SK2.V(T4LBG4\AES_ +M34JM_)$.&2EL]'O',T.\FZ,JB0+*^U_8ST'/]TD+++W%^<3)@I<@SWYXWTTP +ML$Z'GWN7D<=OO%*;*"%UDSN-.@#9^$/%=MGGV6BS$D**^1"*@27&7'C&:]YP +M'2ANW9*4'.M3B642IO^(F!AT^2-'-I-`9@5K-7E5'3[!?^*.TIT:6#0*_DBF +M"2W/EW:&0">5Y#N7+;@E@&S6L2PBMLE2$K=&'A8%`.P```#L`````@```$4` +M`.A4_0``0!$``,"H`0'`J`$"`?0!]`#4!KF1P6&LN8I#BV5?4E.+$(17+B`D +M(`````<```#,(0``L#;][YZ623I1$/&V%O(H]FVS-$N^/U6^/=LJ.?O]S@X/ +M:5/N3>:`4>U6&*%VZ5IUG?VN)3<;BV92_L^"AW>O%)T3MB>$K4KV+2&ID')8 +M3L36E[/Z(&YD3$_#'F\'8]E#+OW2$LHXGFMA>M]]+12!?PE2CW<>+YK@0,(@ +M>05,#FG\2;\U2J8X<'0O57F,U\'LLRY=/12$K=&%SP%`(P!``",`0```@```$4``8A4_@``0!$``,"H`0'`J`$" +M`?0!]`%T!UF1P6&LN8I#BV5?4E.+$(17+B`D"`````@```%L(0`!4'P=(<=M +M&HT#CZH.0<-:C!=? +MVE,XN`:7@")4M'G0U:UQ#,6#;.BXZK0[`)4:1<0@JJ/6@+G8F0O\+-`>>8`HPOPH.*A[N()-[GT(^>FWE8DJTP()%$`979;GGR.71(>Z69 +MRJP&J(K/6-FIH#!=_:R;_^A>]*_5X;'!)-],:HU_)?A!==O9?C&?D2_HA(O, +MU'19SS-OI[8+OV$I"]OKQJ629LA3D##G([6NG)$R*L^US="DG7< +M6=*7[>5(?P_[8GWK4A*W1D!P!0!<`0``7`$```(```!%``%85/\``$`1``#` +MJ`$!P*@!`@'T`?0!1`L +MSVD6Q#GI"[+H`K/.22IXIM=@W9]U27$9PK"S%W>W:6Z'3 +MQ0],OH@-BP9)L[0=*4ULZB"^/N&NJ7=R?^2G]NCE#MH6$[7H$-UT5M.EVRR* +M;&S*CLDZ-,AGCSRC*H%\U?I?/J8RP,(I]*#*A*\+>"_JBX+$GDQRJL6B3N5' +MGM9V"NBX)&IIV/;##AID_;QRB&-%5#F=/TZ/!475BT_2 +MQK=8,PG[\462T^:(9"F^C6C3]H%35U]^*($,"G@'?-C?-YE3*9)JB14VCQ>E +MPDR8&@GB>:#1F**$[2X$M5(2MT;>EP4`?````'P````"````10``>%4```!` +M$0``P*@!`<"H`0(!]`'T`&0&26=N$)U(-KG1#->*2GY75WTN("4(```````` +M`%PJ``!`C:V$AE&H(F(JSI0ACF`.C^`#+8XA+LF4JX^ +M4Z91WV^F;(NO1E%8`Y?E>@&ND%4C4A*W1E*C!0!L````;`````(```!%``!H +M50$``$`1``#`J`$!P*@!`@'T`?0`5`8Y9VX0G4@VN=$,UXI*?E=7?2X@)2`` +M````````3````#`(^9PH%Z77#>RM4]65V#"R3*2GY75WTN("4(`````0```$PJ```P +M+WH7F]-<),0YN0HB";8_/^LGIEOG^J8+8&-,J8Y3JZQZ;A-M:PA!]8` +M`````````"$@(@@````````!>"(``'@```!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``F?5$9Z>)`@K1]%W#*DX?X0@31L +M,.9J#/#B-U;$IE,1G@^LU.SZ1H*6@?8-D/YM#]?G>G]6#F*UQ#=0G\*E;@!. +MX;2[[YT/$O#!?-3X'27_3-U%Q3 +MLT2-S/(I```DR?X]Y9P;`?*!$W]+*P````'```0`6^5(W<;^"VH8YO\JU9 +MKA,%-6NEA%(2MT8'S@8`7````%P````"````10``6%4(``!`$0``P*@!`<"H +M`0(!]`'T`$0&*10>'K6L(0?6```````````I("(@`````````#P````@``!` +M!@````%]L>YG2ZS9C55OFU]"Z83,5,1`"U(2MT9'K6L(0?6```````````I +M("((`````````9@A```@``!`!@````%]L>YG2ZS9C55OFU]"Z83,5,1`"R(` +M`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``F?5$9Z>)`@K1 +M]%W#*DX?X0@31L,.9J#/#B-U;$IE,1G@^LU.SZ1H*6 +M@?8-D/YM#]?G>G]6#F*UQ#=0G\*E;@!.X;2[[YT/$O#!?-3X'27_3-U%Q3LT2-S/(I```DR?X]Y9P;`?*!$W +M]+*P````'```0`6^5(W<;^"VH8YO\JU9KA,%-6NEA%(2MT9P`@<`4`$``%`! +M```"````10`!3%4*``!`$0``P*@!`<"H`0(!]`'T`3@''10>'K6L(0?6:49S +M<7^2OC`A("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```( +M`@```@,```@#```"````"`0```(H``"(``(``-B85T)WHDW$._]ZA-R="Z)Q5R).QS0\3C]H@7J&IG9NCWCJRD[(M,HE +MY_*HOW38BUG=9.EN)7YXTV!_*0``)'RN5ZV#X>+/-.3(91:]VE=:4SB( +MO//S,6]TRI$()VTC*0``'```0`3K0WDL54@EGB\_VC842/(YD6;,J````!P` +M`$`%W\<[',DB`_-*I*G?*"!+$Z"QW@12$K=&5C$'``P!```,`0```@```$4` +M`0A5"P``0!$``,"H`0'`J`$"`?0!]`#T!]D4'AZUK"$'UFE&5P313` +MZ4RY9S)7S]^JR.;R9&&>S/I/O^TS+W#E'!?=2PF5CL79^_N.5C`*=FVX\-$= +MWJ2CR)"ZW!UX+3+[/GF?;TZB9X\'HP("XV8/P02A#*3C[!@JN`82O\3>,B2> +MS,G$E.@$);&ZX$RA[N]FMZZD[J]:FQLD4"+E=>N,GU_?>\`LA5(2MT8A2@<` +MO````+P````"````10``N%4,``!`$0``P*@!`<"H`0(!]`'T`*0&B10>'K6L +M(0?6:49S<7^2OC`N(",@`````0```)PD``"`YM?'G3UR9$,%BKT-1?E[0`.( +MPO=G4@*(L-ERF_H>H982Y7WE@[RQH=E" +M_F_>TR"]<]'__+-1W[O7\U(2MT;9:`<`'`$``!P!```"````10`!&%4-``!` +M$0``P*@!`<"H`0(!]`'T`00'Z10>'K6L(0?6:49S<7^2OC`N("0(`````@`` +M`/PA``#@7AH2>4PQY%`41B%5V=!,N!9\,01_!8#^Z2RD>LX<"?FZ@1LU'3.P +M"WP_K40S9OR^^](M="BJ84JPF>2>]W^NUBG".10_8^%]$YP\A&4L`=$47X!* +MPNG&#*R@!TK[3O5.()/X'IL!_;M73N)/24JM%8 +MTPO)KO:I%S>_(HH:K:_H-69]E*8OTF?5.T+6EOI'>K%QC+SM;+?.]UU:_"NU&'-252IM=2EP2L6@J( +M0E(2MT9==`<`_````/P````"````10``^%4.``!`$0``P*@!`<"H`0(!]`'T +M`.0&R10>'K6L(0?6:49S<7^2OC`N("0(`````P```-PA``#`IOI=Q#9()Z`2 +ME*EKX.=_MF(H3+'A_R.2SMY%A8FO8#&=R? +M_"\;0J+C0AI\I=GW=FFLR#.D.0;AGZ8`L7S'2`J"=$Y!NL"A:SVIGUMF)LV5 +M,5K#`7-V(LDLM0,L",3C*QQ!:JM.SCYI=X\ +M_L`+TG$5U^94I6/9LA%%LT=C:C@XGHUB8R_@`^J3,JY_6$L]2B:)N`:JY$!2 +M$K=&#G\'`&P```!L`````@```$4``&A5#P``0!$``,"H`0'`J`$"`?0!]`!4 +M!CD4'AZUK"$'UFE&*KY#BTU\1RJTV3"#I;X4]R2>4A*W1N2:!P!L```` +M;`````(```!%``!H51```$`1``#`J`$!P*@!`@'T`?0`5`8Y%!X>M:PA!]9I +M1G-Q?Y*^,"X@)"`````#````3"D``#"B&:[Y3VD#-DA'4V$A!HXYAO&R@`@L +MVD(K"Z;]5D0A!R'K6L(0?6:49S<7^2OC`N("0( +M````!````1PA``$`ZBTB;2;W-UMR<87&^CZ#??H$_3KWCGUH28VARS,HU;NW +MC8'&VI=**=1%>%$;UQ#!7T@YM(H$$&"3S:1Y5&6K<:KBD92QC:O$CT"@(N.3 +M]1A87X-\5[Y'8)%*J><-Q@F%'AS;H&P8M!AC6O!8`QS +M[DC[_KI"N1NI=CTQ`T^+)!'7Z%^HV5U/V3M"@`2R3+AWR``TT903US]2%+OZ +M95O1@'%'M(MM="D32C4D(",3/&\1F0]2^U.D*7Z%>3$)XFKS$`_\#4A*W1DC" +M!P`<`0``'`$```(```!%``$851(``$`1``#`J`$!P*@!`@'T`?0!!`?I%!X> +MM:PA!]9I1G-Q?Y*^,"X@)`@````%````_"$``.#4W:@7?0'&$WT3'#>SU:>E +ME$GLEDBO=]V)#$H+-ZGH"CVLWKH^9QW9I\BN?O^")Z055:)Q +MX0%_J)!"Q_X03I].8.UE#:JG=E:O;6E<+\HM7QLM:PA!]9I1G-Q?Y*^,"X@ +M)"`````$````S"$``+#^L,8,OK099>L4TQ;![0E\UCFR'N1ST8=8K[,O0KSJ +M[KM%.+TX@QD81+UD>3UNC_(P@^8HA2D_>D@79 +MF0]P-=-2-[X&D>?N%5KI3]SDB`9*AAH*QRO'51.OQ0,2,AJ_^Y@G?=2)^?=% +MFHYZJ*6@,'#)?!JF[:\+SH8%P<*MZA?#&/\P,24A*W1F[T!P#L````[`````(```!%``#H510``$`1``#`J`$!P*@! +M`@'T`?0`U`:Y%!X>M:PA!]9I1G-Q?Y*^,"X@)"`````%````S"$``+#<;,A7 +M]"\JU:<-6`'3OJUAT]X'/%`I'Q$=.*KS/9L8<10)5-Y:V'GZM06[D@U8O]^@ +MSW%#Q7I>>3-/[C][EC$VEO_-'^G +M#2'$/Z!\MA^!"'E_?@;XM,JN)=VP&SN8K9Y&9" +M]8/])RID&4%66A_-_)FZ;1>IF-\WS$ANVSJ)4\$#JUA(4A*W1I<1"``\`0`` +M/`$```(```!%``$X514``$`1``#`J`$!P*@!`@'T`?0!)`<)%!X>M:PA!]9I +M1G-Q?Y*^,"X@)`@````&```!'"$``0"VK;5]_8DPNH9@1)8"?((Q3CFZ-*9I +MZ-R2PM[?W?F^]CP.JS8&NYT'8YIZH@K;?V3E4?:2*@<#8^AB;O#EO3J:@?YB +MN`7N^LZ383D#`Y-DG7C9?EP9L[?WFS\08^)GNYC=<65,/M*K,.@\/S)9W\.K +M(P/]Z4B@0J7=[@V*U)U7K`V:(HO25I\/BR8_K?/5^T3 +MO-Q+;IN##O87QAE'%$P.5JPKGU<,?UX9ZJ,(EPZ;[\X_]/A>7=]XFCW?OU#^ +MU8RT$99/"S/S'AG<%5E])N3?-.1X^B05$E@W:1!W-(/SS()S(?&ES1)KMJXF +M#=.[\8%2$K=&7QT(`!P!```<`0```@```$4``1A5%@``0!$``,"H`0'`J`$" +M`?0!]`$$!^D4'AZUK"$'UFE&F`\Q2+KS_>9>Q$:RA(\\GO!_VD%HSG^BTC/3P&-93P>0!)RJZ2R?7DS +MU'R'S)`7X7%#^8%897[%=HJ6'3W(&L]EO8F4""#^63*2)UB]CAB,P9I*_.8@ +MZH-V=*O-K#DXJ$LQ*7H#L8Z)]*+3+.\,QV9=36_(5MC*NKB)-(:\>X],CM`\D&>9X/Q_38:; +MH]AL]S1CVBHD93(-ZIK/P^#&GG,(G2B;DH-M$\YD_R^O,9^C0+NU$OA\%6ZG +M"97X3=GP`GLUPR_"29X?%+?$7O#;+O0*83KD;'2#U$#/65:N"01`FX-#B.WB +MY,<`;W.7.Z%+1:%5BW.>03<#9O)OD[P+L>/)8+RN%RC0]=A(KB%[::+2+Z1Z +M6LKL,7K7LG@CF#=93PLU\`]2$K=&S4\(`.P```#L`````@```$4``.A5&``` +M0!$``,"H`0'`J`$"`?0!]`#4!KD4'AZUK"$'UFE&VC)I5T>`)%9HZQ>-%S`.8U%F%LF!RNE,XVS0B+6CI +M2?];-51\?^"J)2[$"GZF^EK$8%2&,1QE!C)1.J)#?YV;&9U2 +M$K=&H7<(`(P!``",`0```@```$4``8A5&P``0!$``,"H`0'`J`$"`?0!]`%T +M!UD4'AZUK"$'UFE&=462R:1 +M4R&__;\-0`[]Y34[]?O(XO8Y$(N$$R?A;:XZ3?0&DRS3)=E,X/_-1XV[J4#J +M-%C)],P97R9;B@>+H/C,14B>=8;V(DP.I@ZPVH)0-?7@#$OO9@*']1]$-(UR +M"J=J#]G,YSL+PF8#UCK?S=!H(89=NRZPDGF@$7H0:A:VO-[U)5\"6\U2,V\6 +MK*CYRENK+-EP,QT$N9<0E54[)6*U(VN0)8@OC$*?3S6.Z5N3+TX/HR%CSJ;Z +MY(,Q&(RU/GK>66C/6['"@H5S.5H4'%R)3E\?DY07U=]"5%7H2$]OOC*/YLVI +MW7(0J:^66V5OV=WLH\_M6,`?<(.<15G]>RX%Y5'4A*W1B2L"`!<`0``7`$```(```!%``%851P``$`1``#`J`$!P*@! +M`@'T`?0!1`M:PA!]9I1G-Q?Y*^,"X@)"`````(```!/"$``2"8@+&9 +MUJ0O\CS]I1_;-P[IM[Z_-5@-GR'?D:=,W-D"JR1:IW&]2$)D00:B).6=Z^I/B=IP5 +M*\L3\0`F:H-YX"E%JOR#3#&DPC8!FR`/K!RH+&,1>>4IA;D<@/>H9$;<1DN> +M[V+,XK18S92"%*7^XF-<7[MR62&'M:EUS-8Q`>;.`/_Q;7]HA$(K@`J%RQ8= +MYJ:81?U@P'.M.1-E`$*ZNWH5LLE');NQ2>*>%QB)6,C@:4[(;?-1G6T0(_U8 +M`5+7'":H/FS@CNM6TZ/<91_\Z!'SH9?T'.U6\,5,> +M-Z%4=``!`$0``P*@! +M`<"H`0(!]`'T`&0&219RO'(VM!&!?^.6AJM-$+@N("4(`````````%PJ``!` +M\6-$/8:CWHZ#=^6PLKX4_>VA0:-`+UM!>%.P7@OLD]C(#84+%BQ%RY4^8+49 +M,;7G%SU[WV("//YGH#A%4A*W1CK?"`!L````;`````(```!%``!H51\``$`1 +M``#`J`$!P*@!`@'T`?0`5`8Y%G*\@'DL#-,E;HU*L(FM=`BO&S)Y9QV/R( +ML:=X25(2MT85[@@`;````&P````"````10``:%4@``!`$0``P*@!`<"H`0(! +M]`'T`%0&.19RO'(VM!&!?^.6AJM-$+@N("4(`````0```$PJ```P=X8SB\>9 +M>1>=N]9=8Q-[9OL( +M`&P```!L`````@```$4``&A5(0``0!$``,"H`0'`J`$"`?0!]`!4!CD6_<5&U_VT*04AA>I5ZV!B +MECS_$=C(3!V]4UUT=R1Y.-TL#(R2H2])@OIW4A*W1DSZ"0"8`0``F`$```(` +M``!%``&452<``$`1``#`J`$!P*@!`@'T`?0!@`=EE$NB@)'*VP\````````` +M`"$@(@@````````!>"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``HU$]Z>>JU#U0F<343HGB+%&:,%>#_U7Z3F[8\T5P"7)-BYO%_I^& +M1->:;M@1>D[`UK:/8GY&2D/U5RUD.LS/R)+/"R\NS)*1,KP-Y^FZ>ZZ0Y2'0XSJP8;URI9*N6ZZ2V2%E+^0X;I0>:Z6LA[DI +M```DO32/P%G<6Q0*;Q%SXHIAUJ5$#W:8FHI]-=/`'[IT*:@I```<``!`!%QP +MA<%ZZ#F'1U5OUE;.DG'/&@SP````'```0`7D%RTQ&@Q/%7+?-)M[QY2H;93X +M"%(2MT9Q"0H`7````%P````"````10``6%4H``!`$0``P*@!`<"H`0(!]`'T +M`$0&*91+HH"1RML/```````````I("(@`````````#P````@``!`!@````$5 +M<+0@I13=[T&*3WS.^FO1NV[T-%(2MT;J&`H`N`$``+@!```"````10`!M%4I +M``!`$0``P*@!`<"H`0(!]`'T`:`'A91+HH"1RML/```````````I("((```` +M`````9@A```@``!`!@````$5<+0@I13=[T&*3WS.^FO1NV[T-"(``'@```!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``HU$]Z>>JU#U0F<343HGB +M+%&:,%>#_U7Z3F[8\T5P"7)-BYO%_I^&1->:;M@1>D[`UK:/8GY&2D/U5RUD +M.LS/R)+/"R\NS)*1,KP-Y^FZ>ZZ0Y2'0XSJP +M8;URI9*N6ZZ2V2%E+^0X;I0>:Z6LA[DI```DO32/P%G<6Q0*;Q%SXHIAUJ5$ +M#W:8FHI]-=/`'[IT*:@I```<``!`!%QPA<%ZZ#F'1U5OUE;.DG'/&@SP```` +M'```0`7D%RTQ&@Q/%7+?-)M[QY2H;93X"%(2MT:O/0H`4`$``%`!```"```` +M10`!3%4J``!`$0``P*@!`<"H`0(!]`'T`3@''91+HH"1RML/-#"3Z-_7JE#Z^L6< +M)9_K!N):Q&Y""0@?\.M-&E2FK^IJS&LY9R;44C6$<*#?H1Z'2B.QZZ,M&5R" +MJGC-LRH#',=2^,]4=&1P)#F/,&=:05XL<3B3IDQT\1RZ#F/^0'+!VQ,`K>QK +M;4!,^,/]=JR6(S"L-/CU*0``)$A[A\*803%RCH"^L"-AG`Z?$=-TRME_HC^% +MF-PK!/;$*0``'```0`3DF[D8X890#31S%(5"3CA9F*AHF````!P``$`%#XS" +MY>9Q2BDDA]^LR=PT#BQ]9MI2$K=&4&P*``P!```,`0```@```$4``0A5+``` +M0!$``,"H`0'`J`$"`?0!]`#T!]F42Z*`DNP1G`VL,E[%_(-9,^K6BH.D)F8,P2-L3!7_'J+R[%X!-!!ZPQY/9/.H]IAL7=)RS9.B]K +M,8PZ:XW.T36H7'$_G/Z-L2X<2J#PH1&I(QYE/G`0?E(2MT94A0H`O````+P` +M```"````10``N%4M``!`$0``P*@!`<"H`0(!]`'T`*0&B91+HH"1RML/-#"< +MLK/A#[$N(",@`````0```)PD``"`X4&=;#1SX0IM;+S[5C<5S8C:Z6YD1;H5 +M9160FD+&CX.>)>\?"O$PF +M^5!<\$Q&D9&CTKV#=3SQ&B%9U*$A+8;VR>I[>)G@>,4516K?TAJ!!BF[E($G +M]H$O9)'OW_857U(2MT9ZI`H`'`$``!P!```"````10`!&%4N``!`$0``P*@! +M`<"H`0(!]`'T`00'Z91+HH"1RML/-#"S$I.*&4B1[G+[A_,5F +M#+F-M_2[B[[T[$+&;3$N$3)+:Q@B1X!`7S`C,S@^HV@2N/X/IPPB1-3!F#_E>-ZD-*5W9\!//>27QHY`EAP/WF_2'C"^_W>>RHD1D*ELI\2_C4'F+_-!NU +M6"P9HCTL7_C:].=B!H.O:S&5<#!IL)0]^^D8?;IC8Z^0Z0UEI,*O.;.OF[U> +M3#%WIMW8B!)G5U([SFB1]5:!T\(]PO2WE\));T^VCJ,,:T<0D$P.!(+Q]0%: +MB-7^CZ6H:75D/CBK('>=R> +M=OYZ:&.;DYVU-S=_"I;!05(2MT9Y\0H`/`$``#P!```"````10`!.%4R``!` +M$0``P*@!`<"H`0(!]`'T`20'"91+HH"1RML/-#"Z+U6^;TWV&O+'.1ZI#9'OS4B +MB9,LJNC/%4+$'FC<1"&>0%(;N$?.S+!F1Z[4T>O:C/%0^;>(<\P87(!X-#7W +MYB4,)`3>379@EHPGQS) +MOAEV`T[-!&^>;F/JN!QK!5!6]Y]U>&Q11B:HI\O<:4`#A)XVB>V9_?SF)$]59^4A*W1GC]"@`<`0`` +M'`$```(```!%``$853,``$`1``#`J`$!P*@!`@'T`?0!!`?IE$NB@)'*VP\T +M,)RRL^$/L2X@)`@````%````_"$``.!1/O`@=5^EV+A9_>"B*57]XS6)&?SI +M6R6X311I&>':15V21`1X@WDT,J(IOX]DL]%\H1!B\ZYVI']XB;.=310"H84? +M&CAP5#T(=M&9L8T_OWBT4V+K7'W;,0BZPP_OGS$/W0Y"!<.:]]R92`_`YZ\T +M&!52O^.@!Q>;[)8.B82_92'^4P/0@1<:6TZ_U\$3H&QR)]WU;5:;@_HT6'0D +MJW'JNZI-IN`C\GKP`1)B)0<[D\^QCF7/^6D=0*X,'2`<(-ZR@AED]RF$;)#/ +M3RV"^K<".8CB4)`N#$+J*XC4<^F4` +MZU2PV"?J]Z]\$EH7GX/=.J?_3;%DM?+OS&8\G[*;#%`ZU&`SX)8Z@?>DO-TY +MG6U3U=@2V([O2\EBP;N\/9&=.#Y@9-O*5;^_#5=?Z>LC71@*PE1WA'-O;HU3 +M4A*W1J8P"P#L````[`````(```!%``#H534``$`1``#`J`$!P*@!`@'T`?0` +MU`:YE$NB@)'*VP\T,)RRL^$/L2X@)"`````%````S"$``+"A7;?E[3#L8(4A+8_=+*;:A.::D+ML71UR,%J.>KX**@`6L033IF! +M%W2X6XGLG/!I2BY[FPD-T1*=-B@F<=96*:JPS.[$1851GG&KAER%:H'^,HK- +MBN9>?[8A>R"!&C9]JN<;]SK.A*RI*C+>3D#D>?D*SRNX#AMJ7*M#F-?GC:.Q +MN-\K^N:61D$\S7,<`PWJR[[$!#%@/>O-N]F>4A*W1D9."P`\`0``/`$```(` +M``!%``$X538``$`1``#`J`$!P*@!`@'T`?0!)`<)E$NB@)'*VP\T,)RRL^$/ +ML2X@)`@````&```!'"$``0`_UP'$_WAHI%&*N>.YX;OK1])B_N9EIS">+"W] +MO]S!M:#!3CL<)2VA/,`.E;@G)'^LV4ND/M85=S@NO.E;7'MP9+R?!4M0(%BF +M02J%*5QP^B>4"=:KDX;_ERT3EXI`-*)?>IBYHAF,P,I==V71'%#KF#>$-'3Y +MJL?^>>GH%MT':)1D10!.A#]5(!9DHR125U7<^66Y>!.# +M8.=X11!FW]Z@ALK=6N8?%L[78WN:J^BGL]]_5^L*@KW3QCZ*B2:HTDBXZ3`Z?12 +M$K=&,%H+`!P!```<`0```@```$4``1A5-P``0!$``,"H`0'`J`$"`?0!]`$$ +M!^F42Z*`DJVI`20F,6P89V\E:+8/"H;:G5X>]M`]H)^_$ +M/FZMY!*%H^A4#_<2J[[U_/!V5JK*B5="*XLV.,7;>;*7T8O)%Q,AXP7%\W\S +M5$W=@][M#1:X'M22#[M(GDT!,4DE7%D!'*!BAU9=,!'\(_2J])K*X*7^!%HG +MT5O4Z//B@M\B33YKYH.:TW1Z0]:_<64,-#L?OCJV?V&"%Q%35'CCZ@+;=*>I +MLTWZ(#=-QWH*,4TDKB6]S>LC64OQ@&3-H9[5!UI2$K=&N6D+`.P```#L```` +M`@```$4``.A5.```0!$``,"H`0'`J`$"`?0!]`#4!KF42Z*`DR6<\*W+2X>BVGYF&1Z+CD%(SUC.F]L%P9(*_36`BEF>T' +M3A4HF-X9?%/Q+4T*"FFH(:9_TJ2BVY4T0&9?!3VY][=6H7OY#.E9"I0F"?LH^`KP>G3"*?ZU,ZK^:YS3^) +M4J`$@&T]/!-*N=M2$K=&XY`+`.P```#L`````@```$4``.A5.0``0!$``,"H +M`0'`J`$"`?0!]`#4!KF42Z*`D.<;`)#8IPO3O5M<24W[J5:]/L`#,&H4CF4 +M:_,)=BMG*R-1ZSF`LZ]RJ9[L0:E!5@=H8?$0S36#%_([L$LHO9*ZIE=\AQ,T +M)L&2%-7FZ?D5D1!VS!-=:G^L`QIZ!@H6\Y\HF=&XZ?5$=+#/Z5]2$K=&++<+ +M`(P!``",`0```@```$4``8A5.@``0!$``,"H`0'`J`$"`?0!]`%T!UF42Z*` +MD/`[9R99<>]9EH[5 +M;RS@>]5"Z+PX\<8]0H_0!O,'RRTD>CQ!I`OG#`LHS]5.E5O^DD."*7;5W)OH +M*!6S0@(I&XL\!3)G&"BFPDHV84IBFB#^UY(OMR +M2L%7%KCU]R9'PF!U[CRE`-K6&I?-(/P=B8^G<_]+)9RISK1ZD$L#4QX-2#R9 +MPS).1)#ES0'/J.M%@'4)(:M0;AW9P- +M8M5'B*>"0"YR$H[B*E`H9MV9)\$)B54JJ*IPRPA^8NLCP=%O56]6^KMH)M4K]099P(V`4(G4^8\&8B[0#&3DX\$G +MY0!-K:@Q/&QM.!$S=)(=Z$!9-788\EP(9\/3-4`/>A`]X"VZ15H\';F[>>_@ +M,.-P'XOBO2PP9"??AP>UNN,TLD!5DJO3'?EEP-XJ/I1L0\T:-ZFY1+Z-C;SQ +M3NR795(2MT:@%`P`?````'P````"````10``>%4\``!`$0``P*@!`<"H`0(! +M]`'T`&0&24TF9!V-E;!^&?9^@!6FA%"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MY9D1BTRN-JO`3(O%RAT(N@ZHWJV;0W+&$>P:HWCGH+;LJ.DH%1B5 +MJ01LGBYI?U"`6T4=2?:_O2M2I9HN9RK\G/Y[_S#.O:.8;G$EW#P&XY?:A8+5HI```DX5X) +M7A:CU3G'L70##SD"[KZ^66PFR%N`I```<``!`!+0?Z:6*L&=` +M=^B;S3C[X20S!!CT````'```0`6FKK9P\#4]NTVD"D"P:HWCGH+;LJ.DH%1B5J01LGBYI?U"`6T4=2?:_O2M2I9HN +M9RK\G/Y[_S#.O:.8;G$EW#P&XY?:A8+5HI```DX5X)7A:CU3G'L70##SD"[ +MKZ^66PFR%N`I```<``!`!+0?Z:6*L&=`=^B;S3C[X20S!!CT````'```0`6F +MKK9P\#4]NTV3N_@U@2$AI;BR/,TSA@+=/QCI"8) +MRR/N39/./`?9C(GXN1$DG?5#Y(BS>ZZ!8RBERC["Z;>?\/O]+XK7UEYI@E2Y +M@+S:$[Q?.1 +MC1)V0B?L3AM>]\M2$K=&AJP-``P!```,`0```@```$4``0A51P``0!$``,"H +M`0'`J`$"`?0!]`#T!]G2-3&2OG&2$02'?V`B9;(7+B`C"`````$```#L(P`` +MT..==8G.@RM(\LC4]^(SY?&:)UD[F%_$UR[KL$M,.(3$],]N&45H*?O0[M-5 +MDL-,B5!.:USBB39`X%J9X`>8.``(OY>:?Y+-?$ZR2;[W+[-Q&YM>&.M +M_FLD!D&BW!F(=XH*V^PB`T=Z_:9CU:3TB.\_)9;ZJG"Z?>%\`=570*[/BW;N +M(`-U!N%-#9*IE)UU!YM9[''*;F?T34>59!!&]RL7@B=_4P713"B#4%Y3#/?! +M']H#`>-SC(:/J=E=N(V1[IG^'(H7G\R(?%(2MT;WQ0T`O````+P````"```` +M10``N%5(``!`$0``P*@!`<"H`0(!]`'T`*0&B=(U,9*^<9(1!(=_8")ELA/BO5^F!EV)QNU6 +M?0`[$2L2,E;H0.-9@J=3(2*Y^B&N(P0%,3+)NZFNG"A:'N-S,W=`'89:G=%0 +MBVY$X<]'W$%7,@SWPH^38MJ^QF7B-_I]OM;-");"%-J(^!HC4(TV<1SV=]2/ +MJ^*58%(2MT9[Y`T`'`$``!P!```"````10`!&%5)``!`$0``P*@!`<"H`0(! +M]`'T`00'Z=(U,9*^<9(1!(=_8")ELAO9CP%%>"KWN13_OG.?*9V8V)"U`N#9WM-DGX+&`F0+;=PPF\1]UWY69#7=?>E;3^D^&K$Y +M'X+K7Q;;9:&>]\:)]M[[CH5#JE*ZD?_=M]8_[*T^`]S4!E5@GID]!/4I5E`" +ME[+*SDQ13ED'W\^"IP)CW/A/W7F2J-9,C#\/*B.+-=@B9U(2MT;C[PT`_``` +M`/P````"````10``^%5*``!`$0``P*@!`<"H`0(!]`'T`.0&R=(U,9*^<9(1 +M!(=_8")ELA:V,FP,J,A`3W#:BY`13!!!2%3Q+#1B=%$7?0`YR[04MAU2$K=&R/H-`&P```!L +M`````@```$4``&A52P``0!$``,"H`0'`J`$"`?0!]`!4!CG2-3&2OG&2$02' +M?V`B9;(7+B`D(`````(```!,*0``,'W?)7"QQ'J24H%0I;T*_OG1)NDR[-"ENA$W2%R[V$)ZAM=L$%W.2&V$)S%=< +MU;>EVT^$>V)4GR2)\7W=9]559VF*6NB?(8JLO!>93M"60IHM3[1Y>`V0IT>Z]4 +MVDC08O,(@'EK2E2.?;;/3L%2@L)SO`D:+J&,IP0%KP?V,X1)ZG%JX)FJ[>C< +M@6/K:((CG77RK;%Q1C/K5LV_UT;]%\@DJ?4_M%0!-T!A4AS=Q\=BU1`+9!^D +MY(5_-KBV)6TW0F]ZC]MH15%O^XRGTAK-'>-B4A*W1FL]#@`<`0``'`$```(` +M``!%``$854X``$`1``#`J`$!P*@!`@'T`?0!!`?ITC4QDKYQDA$$AW]@(F6R +M%RX@)`@````%````_"$``."@0,Y@VR9#CXR8E3_TWA:Y0J9)[!TV=-!BW85B +MYI,XL,C!PSZ2&R;'(IG'X/-D6F2>O.,#?(VK@7^P?WS+=_A%7X%J!W#(;7$R +M2^3.F=:RZP8_0''?5QKF%_2K*B%">8F?_?NM_=H<;8^):#?`@%X3=RH4N.A/ +MN$.:EM5I]71E@%>VO9CD1N)MQA4C3M3O2%9J\7H=*`P+%@BH;I$FC0&-B.CC +MS/A`13YY=@WG[.[I;"*#Q5<YTM1Q$`C_;1-E`E'[5SY?Y?I:J4TF@J +MIU4;O3$:CMY1?!\QCZ<,:(/F. +MD>D]2BV0GWXA>)ZQ8,[4V)!XZF/O9L`P$5K_!]:;$BU">P&`,@!#4A*W1JIO +M#@#L````[`````(```!%``#H55```$`1``#`J`$!P*@!`@'T`?0`U`:YTC4Q +MDKYQDA$$AW]@(F6R%RX@)"`````%````S"$``+"G<"_-U!3F]1K`5K2&MJ@Q +MMWN0GN7DS!#P5MZ,06F"[,AW']S;6;KN\2F&P)EY*BXV +M)&V6;0W:M5KTQ+GP,@N5@MS9/I%7.*ADRA+65A,"C@OR7:FZA6/JKP2<(J_, +M*C7M&;F?RUU%`YCF;R,9=^E8[>W!NMJD-P>`XO +M_)Y\[^./:@IQZ?IX&08#W(K+#FS?)*/QQS5!1(6+K_1:KK'KS1\^/ZEM5FW1 +MG>K"YU#3?WF`(_J`E:FA=*V_[,2>%MG&ONU/C1?=CCIUI"MP.&((S&Z&VZC8(4:;UP:O*P=@@GAX'=Y +MTG:X?;K>'L&)3V?SX.PN:LR-)F%2$K=&@*D.`.P```#L`````@```$4` +M`.A550``0!$``,"H`0'`J`$"`?0!]`#4!KG2-3&2OG&2$02'?V`B9;(7+B`D +M(`````8```#,(0``L*OUH>DWVW[H^)`G2@3X;H!8P<);YQ/OD +M`FY00*FOA<@$PB3:L.*1<4QKE5L*B')YGZ4/:I%T,QS6">8X/V7/(>(E5>"&@B,SQRH@\&V+&W]E=Q%7$C*U)U0-UPMU;G'^'-"=> +M&A9=8A6`]1>^!0H'.[-1OVB3O"7N/UZ=BX(3F?*\F:I2$K=&(?(.`(P!``", +M`0```@```$4``8A55P``0!$``,"H`0'`J`$"`?0!]`%T!UG2-3&2OG&2$02' +M?V`B9;(7+B`D"`````@```%L(0`!4,>@R&0(?G+&U#@S-@+_[+RP2U-`GF$O +M3\-5\]07-[$6K_,1;GGKU9-E[ZQ_#LTX5OU73T%F?>(A>LG*%07M!N.V^?`. +MTBFCK'N*FV@5W887@8OPOUN8.$*`\CY,OJM*(T7Q^'F/!2.2M`@D68;F0Z&5 +MMA='3/!LX*"K7QH&$$,!)W3DU4FQ:S>YJ?-4Q1U"UA'6E$Y3C&E'<@#CZHB! +M6_:MQK-S2+F(^HFYCNI,V&+M=N_IDV8$DU%58"W=#! +M=]&(BI4KBS"UL80:;-$Q$$QZ%)2T0^UR2\\@Q+8>QSC\A+[61E8/FQ"XNL`ZA4'T^J4A*W1N(F +M#P!<`0``7`$```(```!%``%855D``$`1``#`J`$!P*@!`@'T`?0!1`#. +M.F`U>KO$5RO@BTE@]62HM-=2*Z^,(($:#RUISF>/$4;Q +M>U!<1M+7[*S>NSAO"NL#T0:\?ADI*:LC:M5O&^]EXK(CB4,&Q&\;/A/T7-M^ +MMT[8'1'%F%\R^]4,5%0/:2M.Q=?`@CE62O-V\JW]8LZ@F%,9+-/F#>!!+5,2 +MMT8R#0``?````'P````"````10``>%5:``!`$0``P*@!`<"H`0(!]`'T`&0& +M2>AUH,P(N;"@N:Z'+G[8*YDN("4(`````````%PJ``!`YQ=L-QA\8],N$K3A +MUP1QL&XVSXKY+HA(:0)M;GKD;$0F8#>9-%2;4V>9(TY%;9Z)S]_(YX$/4HY_ +MRED24Q*W1ID9``!L````;`````(```!%``!H55L``$`1``#`J`$!P*@!`@'T +M`?0`5`8YZ'6@S`BYL*"YKHXU]5@4YT6'9Y.PM*^LESU,2MT:)*``` +M;````&P````"````10``:%5<``!`$0``P*@!`<"H`0(!]`'T`%0&.>AUH,P( +MN;"@N:Z'+G[8*YDN("4(`````0```$PJ```P#PZ1D'?6Z1>0I,0BMU!&@(IC +MVB8JC,"N#GM[@ZR^A8^LZU3?NY/P_WS/$+13$K=&``&P```!L`````@`` +M`$4``&A570``0!$``,"H`0'`J`$"`?0!]`!4!CGH=:#,"+FPH+FNARY^V"N9 +M+B`E(`````$```!,````,&;L`T[.B9?6\AH!POESPTP0$2D@J,K<>29*_3Q& +M"R.,;129`GTW@_$)-[:Y4Q*W1CLQ`0"8`0``F`$```(```!%``&455X``$`1 +M``#`J`$!P*@!`@'T`?0!@`=EQM;L-[C*9+T``````````"$@(@@````````! +M>"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``20'A@?+< +M_(,.?,'SG0=TVMK.7QI"5,3)87KI,;7"8W,`D$-, +M$G,WR;ITL^=L#?+:$;/%)Y>;AS&4E+/$4B\)C*?>F](I```D"ZYN>@I```<``!`!.87&BF:NAZ"O4?+">H_ +MTW]"XRF2] +M```````````I("(@`````````#P````@``!`!@````'"0,)^T!;BXH"=+@1, +M\O>?C29VD%,2MT:Y3P$`N`$``+@!```"````10`!M%5@``!`$0``P*@!`<"H +M`0(!]`'T`:`'A<;6[#>XRF2]```````````I("((`````````9@A```@``!` +M!@````'"0,)^T!;BXH"=+@1,\O>?C29VD"(``'@```!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``20'A@?+<_(,.?,'SG0=TVMK.7QI"5,3)87KI +M,;7"8W,`D$-,$G,WR;ITL^=L#?+:$;/%)Y>;AS&4 +ME+/$4B\)C*?>F](I```D"ZY +MN>@I```<``!`!.87&BF:NAZ"O4?+">H_TW]"XRF2];"D!O]B7^,LA("(@`````````3`B +M```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0` +M``(H``"(``(```?%)V-!:MT0RC,K'S*TMMZIN7%_C^C*S!/)Y^KDZQ`_Z3QVG5U4IM?T-<4R4A5K*0&.&6?F;S*0``'``` +M0`2#PH+:EVH31EXU&+$]`M]^ZO+`K5*J=GEM%Z1(9=1':>P4WN5DS4+;<13/8R.NRD9N`\6M2M.6M1@#C%^[W"J3T<)V*CIA5/XGG*7)@HB`="2C;--B-Q'4Y +MH(K*8@]&N9HMI&-#JVP(B8]#`5,2MT;HO`$`O````+P````"````10``N%5E +M``!`$0``P*@!`<"H`0(!]`'T`*0&B<;6[#>XRF2];"D!O]B7^,LN(",@```` +M`0```)PD``"`CA_/9X:<*4>(*+75),ZKKDJ*/WMPCCV9T9I1SH2X**J)$'YB5"(0562*'_00NJWWQZUX?&/,+#Y'K3KF6L]UIF>@9Y7>P-+X +MQ0G\XM7D"WO6U6N"]>NX=>?'6-0:M-OA]1=(`,.$"G=BGM-1WUS"B,MS*%,2 +MMT80W`$`'`$``!P!```"````10`!&%5F``!`$0``P*@!`<"H`0(!]`'T`00' +MZ<;6[#>XRF2];"D!O]B7^,LN("0(`````@```/PA``#@FJ3F$_,/)/$M`BIA +M@0N;I*6>?;&_EOYN;*#=Q.-[^^WBQVG6T!JJ-EHBM[K.)3L?>F8U\-,5'SI: +M$(G#3;,LNDFF7N!N7`#TN>R9U(8?DDY:887LP7E?JG]/"?1&-Y5+LR]+D\K< +M)T<%J,GN9'0[`Y?;WL0L'`]S;5X7O6'U[V"&N=8EPLNF1:A+C2SU]`N!9^L; +MWY[4N,B/$PD(R9[L[%HK,N#C.)R+E"'VB2E9E_(/GZ-@8T)D:,LK4()D-TZ$ +ML,9L^UO,_>ZOIXB,7XRF2];"D!O]B7 +M^,LN("0(`````P```-PA``#`6=9\PG9C,T/S!`31LY#5G5![FVGS5O!E0'4! +M=$: +MSCUNSU^/0>9@9Q5P=3BV=+\4C]AQ_'ZR`H[BZOL;E_?L,8TJ-P+-@O5);UK#5@].2P%<-.D=IW3+ +M*V,[62,@M(8%KTHW5ORS+'FH(<)S=/*-2IE3$K=&5?(!`&P```!L`````@`` +M`$4``&A5:```0!$``,"H`0'`J`$"`?0!]`!4!CG&UNPWN,IDO6PI`;_8E_C+ +M+B`D(`````(```!,*0``,+J$WA=W4Y>+N2/J1%S$J<9J\U)>R>[MN$O]*RV: +M!]Y3`'UM11VAH,SXH]*Q4Q*W1G`-`@!L````;`````(```!%``!H56D``$`1 +M``#`J`$!P*@!`@'T`?0`5`8YQM;L-[C*9+UL*0&_V)?XRRX@)"`````#```` +M3"D``##^2-&J0N^\5]Y!AOIWNK7Z_GF*=0"_0Z5BH?NJP@8/[99S+"XRF2];"D!O]B7^,LN("0(````!````1PA``$`Z./WFU&N +MT6DVSYW0'Y`-^CPF8"2^YHXO&M$F0BK^M^1-7BV4BS=!D=<;YL'L(J[G18FS +M&RG#4#CTCTZZC^T4V/*NI#6'T''CUBZ4"=`*O:XX)J\V:A9)-&1,VSO;=WV] +M^5&WA^1MEWDK;I?"38BX\C,AEK%C<#E/*0&C6>V4`G5[9^.*:Z*]H.]'\,*E +MD]VZ:2)I)MC4LC?6?;W9B-5KZ1"`RXTLV$0W/0H5+!L0*P' +M33QGQ^&`3:U;V*/++"#_/`NYOQ)14Q*W1H0U`@`<`0``'`$```(```!%``$8 +M56P``$`1``#`J`$!P*@!`@'T`?0!!`?IQM;L-[C*9+UL*0&_V)?XRRX@)`@` +M```%````_"$``.!5N;PDSSB68&X!40AM8I$CNKT^,C-]3H6D^L;ZO!4C\*X1 +MHUM:#."]:60J,5P43`>'30#NRY'],P +M`G*>FV1@J^SR^6:!E(WM*"(K+(FEU%*0[>F5)HF(+SM9#.Y*T3E=;:$5[7!O(LCM!ECK3J:0NMSEQ +M'E;YW4Q*W1F!%`@#L````[`````(```!%``#H56T``$`1``#`J`$!P*@! +M`@'T`?0`U`:YQM;L-[C*9+UL*0&_V)?XRRX@)"`````$````S"$``+#3!+Q[ +M%&.O#_A2-2+5=$A37.5R27;<$9L=Q#D3K]U"ZSI$ET.A#"G7(H]YERIQSTVY +MO7/K2R9`.\=&JB!L9NNZGF$CO@G0O5%UF6\/#XZ+)Z40(^RUKB!XYUVYD,.< +M%-AQ@GQ[NU,U;XX@:!J_D5':](!5RC2'2EE2.5[4/DJ'V9@EMX:02_ZG_Z1Q +M\[3'-B<)'#U=6`Z/WRPYP1@5_,?4-JY/&@X^%HX"1A#A4Q*W1D%I`@#L```` +M[`````(```!%``#H56X``$`1``#`J`$!P*@!`@'T`?0`U`:YQM;L-[C*9+UL +M*0&_V)?XRRX@)"`````%````S"$``+!(+U#"9B`S3H>D>B1&U9\I/+KD/*6* +M[#B-]6O,Q6%ZF(KB'3#+'@%&>J$>H?T_ZKZO@R9(MC8@F_1#XFT"*G8K<$Y= +M75V?^Q&WEIK!TQK>3'(@*Y*A/J<3][ROII7):W9S7H\'9G0;9G2M@\"YLJP5 +M[_"ZU?&E3ZF8V=#PY2#TK$T)V:M5$J'$V4R;)6DN<2W_[#A.KA&!L2@,ME]:*""AJ4Q*W1FB&`@`\`0``/`$```(```!%``$X56\``$`1 +M``#`J`$!P*@!`@'T`?0!)`<)QM;L-[C*9+UL*0&_V)?XRRX@)`@````&```! +M'"$``0#O)]TQ)LY;DBF1M[9N8\E?UY0MATI_>@`:S=*O/*E-^4'5/Z,F_JX= +M_TQ7GD1ST\:VT!5>*?(U!]#K/<8OJXI3@LF75& +M^ITLWMRYILK\LO;5<.,'K>M0;CR"O+1WY]Q?H>&ZS#1(>];6'N([\[N007GG +M&*2U@&W,$-RC,A#.LA/&8BH+)-R3U?4(JDUV?WM2E#_F>WYCK@7-QHG`EY;$_7HP,Z9X6KJ9[P1)4E5T+>67 +MLWO6-8`\`KY%#I12,C[A7ME#%WQ=56(@N_O@#C=S2)E3$K=&PY,"`!P!```< +M`0```@```$4``1A5<```0!$``,"H`0'`J`$"`?0!]`$$!^G&UNPWN,IDO6PI +M`;_8E_C++B`D"`````<```#\(0``X.I@-TB5%D;$W49)()),H1[4MS3!X3^@ +MIA8@XU=HH$P9.N.;;N9%46)+3VEL\)IDW]JZ0C +M74HGP:\';ZR2=>*NH1AK$*[O3GI'J-DE('GQXK-'5'?:4L;PD>Q]-!2-!LRS +MJ_Q7R_^=U*916+M$(>*&L@RZ":=NQ]W1BZ.]?8;8K\*T^"0,=WJR +M1RNYVQ@!DO*7B5S4^]?TS']3$K=&+Z,"`.P```#L`````@```$4``.A5<0`` +M0!$``,"H`0'`J`$"`?0!]`#4!KG&UNPWN,IDO6PI`;_8E_C++B`D(`````8` +M``#,(0``L.(?Z*I)81&;_.2_)!L_1]=5<"=:C4,!?,-V._`C+R&!$"HUKXRE +M:6TG+YE"6H,DE9$>3`6S?M0Y-=;`<.#Q@^P;SG97'/A8C&8<@NCN;]C4+'Q] +MHT\-@VB9J`JZPO]].__)'[)1*##IA4.:`RSN^_L5^TUCXI8F&P@;<+P@5;`" +MKJ3KQJ/IZOUG(V:*^7O_/#:G$S;#QGA""^>?3?X%9IIV5_7."@HCMQ$E'-)3 +M$K=&>,8"`.P```#L`````@```$4``.A5=```0!$``,"H`0'`J`$"`?0!]`#4 +M!KG&UNPWN,IDO6PI`;_8E_C++B`D(`````<```#,(0``L+O3Y\!)F*=2*CC" +MCW7#7UM'G81P.#[^$F4)Q%:B=>=>'Y]X5BPY^TFGFS[N&J>/91AMBF0QWE1_ +M'^:K<9,JX[B(U%/G1!0PQ[`OZ+8T(?Y@7"I$HB'COFFD;0\33B-K,Y?2_6:_ +M?ND:,[%UFBUD"[G0$2G785)I.EV,Z?"J$M&VS7V*AB`'0C0;EFH$W;O>DOWS3F[T\+2F;A3 +M30TV-8]R3G.S9PK@S@(1"*Z89N#'K6U660[[QR1E46LB-UH-;&4_.-+R_^=T +M-9QL<&;Z0TF*VG1]2[ +M)S=RD.I<>7)\:+HPEH@6(V+(H*9K]H&2,SC:\&YWO?Q44Q*W1N,C`P!<`0`` +M7`$```(```!%``%857@``$`1``#`J`$!P*@!`@'T`?0!1`'3HCHL7Y +M^<[BUUD,.^-"#A`*@GA\F5.%!M`%RB'^HPMXK]ZV+R^722*`]ZY*)VEAJ)U4 +M'&2"U1JBC&3;"820D]-AKQUF!QPE81J7L]%]2\F6+[+"9W(=J +MD69Y4-9_X0J#&)]46/XU#/FT(SWU'6PQ<8UGHFHI,I%HG82H+#JF5S,X5EXM +M/=["@U(EG'\KMD`([9!7Y)K/T=JC;O7[$=*YDW$9&*MX]Z=&)LH&#Z97HB*D +MG3+*[WM":W4_S.8)F[_UU8)L_MU,2MT9&3`,` +M?````'P````"````10``>%5[``!`$0``P*@!`<"H`0(!]`'T`&0&29)U:=#= +MT2\5J'/<:'-)C$`N("4(`````````%PJ``!`M/^`$:R1A%:MV`H&8Z!T:QXE +MA">+1T-MKQLG?1"".V;GE/J7\$BJ&#DERQ6+6$^7]/;3ET[$BRV`K/R +M^IQ@1'TE]&^D4Q*W1IMQ!`"8`0``F`$```(```!%``&457\``$`1``#`J`$! +MP*@!`@'T`?0!@`=E]XB.:W:UPF@``````````"$@(@@````````!>"(``'@` +M``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``KY+A`3[KH>UZQ*:J +M0$7+U?6PYAV<9AX9)?`:VN*][<'BYAF%%(0PRL^HNY:%8P>@\CS00V88^L92 +M\OW(LW$9SBC7&GI7A^-K-=G&:/=&J[8*"@>)7NOWPI<"7Z-XJB=82C="Q\+X +M^3+K6BBWM$F13R%IG:3)XN\-V6U`6Y,$0&`I```DF_#9E*-)B6`U"3AE?GU! +M@K2!TX\;!U]@?O3[X/2;E]`I```<``!`!`+WN^@IN>F7;8M),8?0M"0+(`U2 +M````'```0`5PK$?J1*88D6)MU0(CFMVM<)H```````` +M```I("(@`````````#P````@``!`!@````'I2!BB`VF\2H[AMSJYE+DG2=+B +M45,2MT:HD`0`N`$``+@!```"````10`!M%6!``!`$0``P*@!`<"H`0(!]`'T +M`:`'A?>(CFMVM<)H```````````I("((`````````9@A```@``!`!@````'I +M2!BB`VF\2H[AMSJYE+DG2=+B42(``'@```!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``KY+A`3[KH>UZQ*:J0$7+U?6PYAV<9AX9)?`:VN*][<'B +MYAF%%(0PRL^HNY:%8P>@\CS00V88^L92\OW(LW$9SBC7&GI7A^-K-=G&:/=& +MJ[8*"@>)7NOWPI<"7Z-XJB=82C="Q\+X^3+K6BBWM$F13R%IG:3)XN\-V6U` +M6Y,$0&`I```DF_#9E*-)B6`U"3AE?GU!@K2!TX\;!U]@?O3[X/2;E]`I```< +M``!`!`+WN^@IN>F7;8M),8?0M"0+(`U2````'```0`5PK$?J1*88D6)MU0(CFMVM<)H.M/%29[57\$A("(@`````````3`B```P```` +M+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"( +M``(``(MS+_5^`?70L*C?2/X3S@["2L3'6(SB +MG_U)]P!8WJEJ64-TVRSU7AB.Z['0TDA.O/P4S^+,4;VZW>'>]J?EJPHE*0`` +M),0&QQ_$.*/?^[%B?/V@BSV"R9HM_'!Q-1-NGLJA.AI(*0``'```0`3S+DW0 +M=NB;\@3UUNAQ7$5IICBB'````!P``$`%058^]=F(.7,*Z-PE,4TN)R&=9-M3 +M$K=&8^$$``P!```,`0```@```$4``0A5@P``0!$``,"H`0'`J`$"`?0!]`#T +M!]GWB(YK=K7":#K3Q4F>U5_!+B`C"`````$```#L(P``T&OTWXD0CH>IVSXK +MDL/;F!G!I_NMC51[T$RLTH.+]!AQUC^D_-FKI8R2NEL<85O1KI8R9$9]:_'! +MM^`9]8YC[W/8$Y680JH*.$`TUOHYI,#AV2)J>P('>-HGFS^`..W6$JWMR59G +M:.^SJ36@RE''X3&([T;,E@IQ#F(%*$L;0$4[V0AH&);M!SPWP/`7>=@IFN7@ +M$*7$PVLOIV:85X*J+;A4OF0CK\=MZ/[#Z[8W\RP]\HFY<++$2]+^@X:8O3II +MHI6S187Y:;Q(CFMVM<)H.M/%29[57\$N(",@`````0```)PD +M``"`>'7/A71E->'^.5\Y(P@2[Q][-^#Z:ENUF&C":#27O/0J\TJ$)-G3)9H8^A@3]$]6ED;96?%'/*20#BPZQK/D7V'^.D"H,+ +M0$*Q2[7-HN"1WS]"3=OX>AH:_3/ZP*$6:DX#ZF^YI!5,OPH[\5,2MT9?&`4` +M'`$``!P!```"````10`!&%6%``!`$0``P*@!`<"H`0(!]`'T`00'Z?>(CFMV +MM<)H.M/%29[57\$N("0(`````@```/PA``#@//A\->)(N8:1Z]N<=#?.X@:#T9ZBDS%@.\3V&X(NJ%[)H!*Q95>H%RE+.+,GB.BSRS&!^UQ$P=S<+-5&0-QZA62N81PPJ(< +ME26J5,_H&&^Q3L>8RH=D@OCTT^5JA5,2MT8;'@4`_````/P````"````10`` +M^%6&``!`$0``P*@!`<"H`0(!]`'T`.0&R?>(CFMVM<)H.M/%29[57\$N("0( +M`````P```-PA``#`>M-S`PK'SH>2),GGP3?HQM!R=-21D\=.AVGMA*Y3'C=W +M<`L[!Y+,>XYOS$YO;)B]AR[.B;6=GK=%@[>ILI5,B`GZX42?.\QG:?T*[6B8 +MD,G>>@!L;ILU^7.LC&>8^NC@*`;GXK(WJ^"]P^,L:Y[T3N"OB"AU4K[$1255 +M[_*J`U5_!+B`D(``` +M``(```!,*0``,-G&VR3>P"97_,"V2D.8]8W51&?((:[N0ME%^DZGHLL["QE" +MDK/$%Y5B#ESA4Q*W1I-0!0!L````;`````(```!%``!H58@``$`1``#`J`$! +MP*@!`@'T`?0`5`8Y]XB.:W:UPF@ZT\5)GM5?P2X@)"`````#````3"D``##B +MB_II&&-:Z&$@)?34]42=!RI\/3]2W(V^Z#@Z\U#A?H7&>9;GI4UMB-O\<%,2 +MMT;U:@4`/`$``#P!```"````10`!.%6)``!`$0``P*@!`<"H`0(!]`'T`20' +M"?>(CFMVM<)H.M/%29[57\$N("0(````!````1PA``$`$6N5SSN<;^U>F@)Y +MS'P-;]A,IYVX>^7W'Q6#P_0CS<[RHW,Q!)P%@J=7[_+@( +MN10B/R%7*IX+(*J4VZU-0`D92#2]^:[.#D@;YZT`GXR(8(]_Q"&/6O[\`+Y$ +MX3$+>1],A+MWD*V0ZSS#E,*FAF[RBI%%@)L +M62^`.`R:SY`XDW&,)[;8B)O9W<^GP?-IZX$"6LOT<'"4KT9R@+LP>(K$_?<3 +MO9KDCCQO*W*A5GTC&W*TUL#$(K\K!-8#"]D5LEZ1:B#A[;P%>>%UOLBB6;,= +MZ_S8DL[$\@A?*3!=2NRRVMD]_S?B96/9Z1NHIA;0]C +M#D'#FXYLZ`!YBF24%[ZA@YZ2E_1\[H=-BG;9'8I2YJY7R]V'\\YQ0^J"EP9@ +M]V7'T;Q-7O-GQB5?$T24%5KBEJ/S=BK4%;^3^==]=D^.S\'%SII^,XJC6*]- +MAQ!0?!<7^YX=II9.Y93:>/1E`>2OEJ2AT$FRQ5O:!YL:]BR!SU^ZFWD@\Y2H0[L#3F2>I2=&]U!9%Q7D25M*=\3PC`WF#MT[ +M4QM)RS55MLZ]G>7SBC,$N@Q2SC3^24R.H8J$J*/0B6YA/GXSD@R-%=)E1 +M"U3T+.\ES!;J!K%$/:RTZYQ<-P^&FA\(98\:T6Q_KS_DTKZF-UW$T(:AKN"O +M)N>F$U9<-V(979$TNIR0*6UM0@'3!Y9:K9AVL`-#P'QR+,+U4@2=5K%X-7-? +M9ZH#.?4M+?GTX2$L/19`C_J'[?ND[^9KXV\RZ-*T'/6"MHYIPOMR*YXF+('8 +ME[9\#1*2J6BZ4Q*W1F'%!0`\`0``/`$```(```!%``$X58T``$`1``#`J`$! +MP*@!`@'T`?0!)`<)]XB.:W:UPF@ZT\5)GM5?P2X@)`@````&```!'"$``0"Y +M`[!AZ)'KAHSDEE][J-<'@0D>GPT]8[OS-E5_+AVMGV?+4:E*]Y" +M6#P%@C.9$,.=W0=Z`+]U@)*X/,2@:%;[H3HLOCE#)HVSW!*F1Y[GRM\+U54/ +M_M,$"6QN&JK/3+Y=$'9@^`:!-&3ID"_4!+]^_K]*`Y,T?0T[\*CP&/^^(LX! +MG%LLS@PO3B;L_:_^0M_G?OH7-R$+,0:6Q=#IMLE,?T7/;LRL9ODZE(=3$K=&4=$%`!P!```<`0```@`` +M`$4``1A5C@``0!$``,"H`0'`J`$"`?0!]`$$!^GWB(YK=K7":#K3Q4F>U5_! +M+B`D"`````<```#\(0``X.0*6?C&5](+P6+?0[ZCJZ15#0;A#/)'53\Q=)JU +MQL;9)`'=_P=5H5/*5&])+0K+ZZ +M*:+7>[4QI;,%7NUB@&!<^+7*&W,`-3KUR!BWYK4MD?J7],SZ[LLTJ]RU126- +M^=:!^H^ZW.":[NV$3;DRU4):KH").`O>=YG[QRI1-E@>IJ4#I:VNH:LMTS[#@XT?3R_SK&",OL@]@:+`"? +MVLVXJ>B05Z/2GU5_!+B`D(`````8```#,(0`` +ML*,.7$D4_"=.<$52(T6/B#7^)%N-`)V\Z58\_'WGP56;9T5-+Q3$K=&*`,& +M`.P```#L`````@```$4``.A5D```0!$``,"H`0'`J`$"`?0!]`#4!KGWB(YK +M=K7":#K3Q4F>U5_!+B`D(`````<```#,(0``L(J0!F:U[WU5_!+B`D"``` +M``@```%L(0`!4.D*J'I%()1A%M^>LA+W)M%']<5J.(7V2<$%X`[S*DAW7.XC +M\"WT!ZOB,MQ=Z476QP_X!;Z!M<9"TD2Q89&J4@W"UP%CZ7N@*S4%;9?NASE\=`T4.([5>:W2`+W>SBU^\7\;D5_ +MN$>M3R.AGC*^V.[,/KY/-.6ZX'%(10NX#?+^`V/6+.M.Y#K';8MQ?MNV,VD# +MIFK@::<84[K]7'ZH/_(U/JD'GB)@Y8+[AAM74Q*W1I5G6$$LI-)YQCUF)'5UH1W\8_X#-':S9R1PV +MMW"1+4\^DP06@/RK:5BNA+J)X7`7RV.[A#GQQV*-Z//Z?:K"(][(0^G#0C#^ +M$'FSC9K*XY,9LWW0WL.K:E.;&5369)O%!Z%]8_R2]PZ(`;5, +MS/(I$CE]&&2>&.8G4Z8YPH-5F'7%BX"4-`R[RICAF\8PMS'KQFKQX^XRL+61 +MCCW*C+7K%65``!`$0``P*@!`<"H`0(!]`'T`&0&2=6-KTN("4(`````````%PJ``!`MM(&H5>P:MK;=R[=`FJ%I0U@'Q]ZZ59W +MHE.AFA!E@<<-S$VV-JB,%)EU'=KO*SK3P6#GBC_L7^X=\P:[4Q*W1E^.!@!L +M````;`````(```!%``!H598``$`1``#`J`$!P*@!`@'T`?0`5`8YUR7(:)&W +M2AD8)8LZYY8VO2X@)2``````````3````#`&EL]PO,X\8[PSX=MMH@A0)Y0G +M3A/RYD8NK]1/`6%:)W=>NCD@V\$OF^4:@%,2MT:EG08`;````&P````"```` +M10``:%67``!`$0``P*@!`<"H`0(!]`'T`%0&.=6-KTN +M("4(`````0```$PJ```PEQ]'28!_6G!#S(7DS_ZA^4-;]HKNQ(4F'9H].0]6 +MWK,2J8Q,EH\K\F?-M8" +MR>-S4Q*W1@ZG!P"8`0``F`$```(```!%``&459H``$`1``#`J`$!P*@!`@'T +M`?0!@`=E>+Q&\MFYTP$``````````"$@(@@````````!>"(``'@```!T`0$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``X:0$Y0H\7BH+^_/#3D[HL4)W +M>D7L5_7HV@7Q=.MZ4-&;55!'6J^+6!*\'!U:U6*\WI_];38EQT`T<" +M:44U7_MR$029@.:_W3S!"`%;`7B<8'HO;;I`-I=*&I@/B((,HT9'=JC0R_W% +M3E.;X1!3,!\LYS<7OL:I%*)7==HI```DM,&Z#,]-04CV)6O*9Y<1L//&*T^; +M?+-K*2+U1/4UU;$I```<``!`!%]>%V@BN8"9K5A/"FAWR!U>I(EJ````'``` +M0`6#V+6N8M`E3"C;RQ>(E"3))]S[@%,2MT;XM@<`7````%P````"````10`` +M6%6;``!`$0``P*@!`<"H`0(!]`'T`$0&*7B\1O+9N=,!```````````I("(@ +M`````````#P````@``!`!@````$777:P2K&F>.SHX":'FF=#:O'2`5,2MT:J +MQ@<`N`$``+@!```"````10`!M%6<``!`$0``P*@!`<"H`0(!]`'T`:`'A7B\ +M1O+9N=,!```````````I("((`````````9@A```@``!`!@````$777:P2K&F +M>.SHX":'FF=#:O'2`2(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``X:0$Y0H\7BH+^_/#3D[HL4)W>D7L5_7HV@7Q=.MZ4-&;55!'6J^+6!*\'!U:U6*\WI_];38EQT`T<":44U7_MR$029@.:_W3S!"`%;`7B< +M8'HO;;I`-I=*&I@/B((,HT9'=JC0R_W%3E.;X1!3,!\LYS<7OL:I%*)7==HI +M```DM,&Z#,]-04CV)6O*9Y<1L//&*T^;?+-K*2+U1/4UU;$I```<``!`!%]> +M%V@BN8"9K5A/"FAWR!U>I(EJ````'```0`6#V+6N8M`E3"C;RQ>(E"3))]S[ +M@%,2MT9FZ@<`4`$``%`!```"````10`!3%6=``!`$0``P*@!`<"H`0(!]`'T +M`3@''7B\1O+9N=,!2N_$VD8G&DLA("(@`````````3`B```P````+`$!``0# +M```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``"<; +MH7ZMM1R4'#/&V2YK-G2')?M$&9/UWLB$XRJF< +M9LU!JJ:3ZJ@;K<$Y"-CY>*=*WFY2O*)@;L7G4+DD$K(+%U=.E9C&OC,.CP8. +MK7Y,B!KO;-T*K'J4PP(R]>06@>`,:=$FED+A"3FY0!@,ZM,4*0``)([]B@`. +MV*K84M.IZT90@S[3BD.$4[F"UM(>I^:KVZKC*0``'```0`2:?APXG3GO]4&G +MH`;TK]=#+C?])P```!P``$`%'/Y9P,],8VY\_?<3%W\9.WC^SYA3$K=&M1@( +M``P!```,`0```@```$4``0A5G@``0!$``,"H`0'`J`$"`?0!]`#T!]EXO$;R +MV;G3`4KOQ-I&)QI++B`C"`````$```#L(P``T)52R[:II9DG"HH/)2RA@-/U +MISE!P^P19W/PR5"1W+^R-QBRK+(QBB=(5U:$L:&WJ90CB.L;$"LK$% +MX@\ME:NF#KQ\?H"H1'*;AL36MM6P%XI9JBN`$>\M9HH:LA`ESL;-?S9QXX@- +MD3C\AC?=%,=`U;G&]E"4Z*)_`<`R9)F-L'-H4#1F,#"GJB1YU0&I+*QU@Q8` +MF"IK'H'K0&EM%J7:!P3O44D,T'O+\'\Q* +M6]6F.5#23U,2MT;#,0@`O````+P````"````10``N%6?``!`$0``P*@!`<"H +M`0(!]`'T`*0&B7B\1O+9N=,!2N_$VD8G&DLN(",@`````0```)PD``"`ZHW7 +MP0/$&T\;T_Z[??)@JE2.*22;!^\2=&2'^$5O,9'P5N]U@O//\V>W-RA'&-8# +MX"1K(R_E +M:/SB,(<43,`7MVA6B>#$YWL(Z_S,.-P=BCIQF@/VD5,2MT:Y4`@`'`$``!P! +M```"````10`!&%6@``!`$0``P*@!`<"H`0(!]`'T`00'Z7B\1O+9N=,!2N_$ +MVD8G&DLN("0(`````@```/PA``#@(?!JP$V0^KI?'W9.M'W@ZF0@D7$Z\%9` +M9VPY4LZPDB4JI=WD:3)RRE;F>\..54&<+?W3O=EG<-7H!J*=[=L$>Y^&+G*9 +M:#0STV20RNL@S3T5/H*<:*"?G,1;&/J$O$6Z34$#MS+A%Z)V7L^H:9^M&=K(V\^G*U06VI"M +M4NF1-21+%W=IDK<`I>Y+S%,2MT;26P@`_````/P````"````10``^%6A``!` +M$0``P*@!`<"H`0(!]`'T`.0&R7B\1O+9N=,!2N_$VD8G&DLN("0(`````P`` +M`-PA``#`%DD!$",=@1Y&.**3'YX_>#"$":9$NM<*JS10"KC_S-[_%S+CI8%D +MVS<&U>#5,SG4P0%SO7NV4PK(ZLBFGBR_Z@>@8N$)#%W$2MY-J6OW?[/XC!;..,7_&D>.\9`-_.5D& +M.&JFP;TXCZ7WU1"G$F1BF'9DRUWE]8Y,$'X&(*5/8][B<8*?8_D3.>++A8XG +MZY0?>@-NQ9EY'\1M;D)3$K=&AF8(`&P```!L`````@```$4``&A5H@``0!$` +M`,"H`0'`J`$"`?0!]`!4!CEXO$;RV;G3`4KOQ-I&)QI++B`D(`````(```!, +M*0``,`0VS,2UR`GZ$Z-;SB=NGT+%AW+7%(FX03:-V7^%.EVHT!T:^FQHH=$I +MR&'Z4Q*W1H>""`!L````;`````(```!%``!H5:,``$`1``#`J`$!P*@!`@'T +M`?0`5`8Y>+Q&\MFYTP%*[\3:1B<:2RX@)"`````#````3"D``#!I#]L_RR@( +M5J"'M\G""L`5;^Z6#C2=E]Z>G4!G$PUL2J^SO>U\PVL(Q+(2C5;Z\"4;BE6R0)!DX3:T +M:!3,4H(C'?:Q4Q*W1F"I"``<`0``'`$```(```!%``$85:4``$`1``#`J`$! +MP*@!`@'T`?0!!`?I>+Q&\MFYTP%*[\3:1B<:2RX@)`@````%````_"$``.#J +MB.,CN9]S8X7@D0^5S#,^=H_H]SM9\_:/:\M@[2$+)Y`/D*2K..!_(A(8.H^L +MC4W2(44\9K,A]&)N112N]:Y/N]B3:VW%>:JM-IU.[NRYOF2X$T5#:);@TN8P4Q*W1N6X +M"`#L````[`````(```!%``#H5:8``$`1``#`J`$!P*@!`@'T`?0`U`:Y>+Q& +M\MFYTP%*[\3:1B<:2RX@)"`````$````S"$``+`#-)!2^H9DI?=\%<&&?,-[5!*B:]MU`P?(^9VEDA"?<.0Q2S)HI6.8C!&J'4B@ +M)/)4F%G6<:Q8/B:-,[Q@:P3@A)R`U1`3Q1OWE0;8X8#3*X<4G7^QVRH4H0:D +M:]NYFR=T_]HHV]":8#:^#)V95OD$1WBMY+0+U2?,I..<:ZHNVK#I3B$ZTOR; +M81$<9TUB5SXWDHL&&^D"X+(C_B3^4Q*W1A;;"`#L````[`````(```!%``#H +M5:<``$`1``#`J`$!P*@!`@'T`?0`U`:Y>+Q&\MFYTP%*[\3:1B<:2RX@)"`` +M```%````S"$``+`'EK'S5M'0-9QAY&X26]0!:Z70L4ZE$',#+]9*J8GF'%4/ +M@\R^,9!*4$8_^6=F5O;JJ:_L'/K\A,$#6='D.MM>57J2N'F[\1_/234\,H>' +M?F^8R?@94WX.O66Z8="7+&IO]:F39=QZY*+;@$0[V*.RJ3W5L&F$< +MNO50O=W,A@UTU+$KT/K6!5)#F1.4Z868+4-D@6+_Q`3)S-\\;@R^#7YT08%] +MD*.;4Q*W1LGW"``\`0``/`$```(```!%``$X5:@``$`1``#`J`$!P*@!`@'T +M`?0!)`<)>+Q&\MFYTP%*[\3:1B<:2RX@)`@````&```!'"$``0#NC2,>)D!8 +MBN$Z$ETLZO+HH\W"/*&YHJ5+Y7'.*QLL+R]#]\END%;A+#N=`186L_?:YS_DT(ZJBA8CTHX"'T +MN5;48E3IBB>L)P'R';]]8D=4SE.PJ6`$<7.RP/^)*E2'YH?_:;BQ4_52LGJP +ME,77->[T\S4^DH#)#UV/3JT#\/U[/[H1*^R1SD\+F+NT![5#_"R/)C$810Z3 +MQ`$CDWTFT59US[LRX\EUZJ\E0!04T4*20A]J:)>>`LO0%?J9@YQ_$D +M.LW&2OW7M!:9OM39+(W++>`!!P]3$K=&;0,)`!P!```<`0```@```$4``1A5 +MJ0``0!$``,"H`0'`J`$"`?0!]`$$!^EXO$;RV;G3`4KOQ-I&)QI++B`D"``` +M``<```#\(0``X!49V'AP:RK9/+4NA[`[L&WC:JFI7Z^9,/0^BDK'>P_/NDW3 +MJ+RUCO&8"WK?HZ,K;M@1>Q38FO[&C=.SOV60R.P3AC<1EY5R$=%-A_T69RV$ +MPJUMN.WJH3;K5%J3R-SBVM?^B]&O%/1$&UQ>('LTTD"6C/L7>.556L+7?S_X +MQ2#+]UP9L8FQ@:\/PS7[=N/?@*Y4B=,<9NH.592?'0O67HN?9YU5W6YQ82B] +M4A'^-6CCVLAD#G1;=-&H)ZF"-G,*D\6T&S_P- +M*#U+TNU3$K=&ZA()`.P```#L`````@```$4``.A5J@``0!$``,"H`0'`J`$" +M`?0!]`#4!KEXO$;RV;G3`4KOQ-I&)QI++B`D(`````8```#,(0``L$;\/M1W +MA_`BA4TYU8\?-TZ/T'PP-FSI$32@PX)'IH%6)WQ0O/!.5QRK]H=/\>[HE@^3 +M^]1L-CI5G@[E\>*+-C#.7-\RL=59<[N)T9K#51&AJ0D]>2!JZYH4=:H.=6>7C5EW`+T[*UGGQ=BU_UWPTO<$;3;#)<2B_[C@(Z/4-3C)%=H$>L +M5OB*(2:RO>.!D?G@=TR.@]*8<<5<6_!QX!F\958"B`:#,%4*FHX_96/- +M&?5#1G#1KH/A-/75ILVX$#TKP'). +MSBL,Z,0ID"'$79#RZEZ[R,&6!C>#)IBWOZ*4)2_[FED@!9X2GZC=]4$-T64$_UK[;R6V`O==BMH?O#@M0[(Z6'C-LR38[O +M,;]N:>-=@4L9XNQL=J13$K=&W5L)`(P!``",`0```@```$4``8A5K0``0!$` +M`,"H`0'`J`$"`?0!]`%T!UEXO$;RV;G3`4KOQ-I&)QI++B`D"`````@```%L +M(0`!4&D?")V9OY[R4]G)8Q"%%Q4JLE563R2Q&NNK4=,)6:>?421Y]*Q&Y/?. +M)E!))=[UA#`9VM35D1E82I3$U)45V;3I\]0&1$'V+K&F4ZA',QIDG;_YJ>"/ +MC(14I$@&ZG<&)XA$5*$Y91IN.M49\[`X*^H$MIQHV$PLK&W7L"CF6?$_"Y

VT8#1E%AI_D1?9C-5UC"C`#PO'ZRLT>K%#-;U/;]Z$3?Y"J&< +M$>`&H<7*H__0'K8WF205AI10)727&YZI4$84V0)(;R1:)S2`00`O&U%OF@;B +M0>,II;$3.V77O-ZBM01CP]M7^^*!<_62RV%\:1K,1%Q&\4+B#C/=5&,\GD&RVN2N3!37U-V.".%6O=YQ1NEI[6Q<*;3QP>C%`:+A +MJUZ2.R;LU".I(#(/@7[ZCU"[H`[;4Q*W1BZ0"0!<`0``7`$```(```!%``%8 +M5:X``$`1``#`J`$!P*@!`@'T`?0!1`+Q&\MFYTP%*[\3:1B<:2RX@)"`` +M```(```!/"$``2!?9OM;Z4:%9*J/\$LO%W)Z?!F +M<*TX1BN:D<#E^K_P*G>BX*B6P/C?3H8)NK$$S%N>V*`]NP63GCTF#NN-Z_6N +MEE(PER;&$/RB=20%R;?S5);8S#".V@]UU^U&O,YUS/`I3LC61A>2AHTNB`.N +M/:3*AZMF`@#IL8@KS%/UM-O5DKT\65&$AG04%IBYJG!"H9S.7T$Y;?=' +M;M1A*$V#"PJ@8=WTHMSI%[L4M#[!G4_8@:A$*@5V@,I4JCWX?FP!XL)5\IL; +MR;4886.%6O``!`$0``P*@!`<"H`0(!]`'T`&0&25[3?=#I72X>/J@R6%]&F%Y43=N*= +M-B/^]8:YDKP\\8)8VF@4Z7\[0B,#-@.#U_G?PMYK4Q*W1CG""0!L````;``` +M``(```!%``!H5;```$`1``#`J`$!P*@!`@'T`?0`5`8Y7M-]T.E=+AX^J#)8 +M7T:85RX@)2``````````3````#!K^/9I^B=%'>&]FM6I`$MIB^WWZTWU;%:' +M/J@R6%]&F%TWW0Z5TN'CZH,EA?1IA7+B`E(`````$```!,````,.%3 +M)(^9B6RGPVX\!=KZ,;N%8_,EW2U9BH*R?3I9/5':5TG1GJ,C`YPN6_(44Q*W +M1AC<"@"8`0``F`$```(```!%``&45;,``$`1``#`J`$!P*@!`@'T`?0!@`=E +M+)%1F[&JB&P``````````"$@(@@````````!>"(``'@!``!T`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``XQ?;4?`0P*!KDHLOO9)I_$,U3TJ9*XSL +M9(B5,,_7)[MS@KF0XW(#39N@Z4^@KSW5F/VV=I,;9\Y()T-,I]=W5B37Q.21 +MRAU4?KF3>MSK_H>+MEK%KC_F^8*B@M3X#E(1+T,^*._T3OJMC# +MVQE>P+'Z*>_SJ"0Y[)8I```DP&BT^3K>S?^_3EH`W[Q->(:#IIZ7`QG49A]9 +M&(")%'@I```<``!`!&&=F>%1`547X6IY>]'$J=;6E?A7````'```0`4YV4PZ +ML.='L!JC*KDX47H5O9V4XE,2MT8W_@T`F`$``)@!```"````10`!E%6T``!` +M$0``P*@!`<"H`0(!]`'T`8`'92R149NQJHAL```````````A("((```````` +M`7@B``!X`0``=`$!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0`` +M#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```" +M`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``.,7VU'P +M$,"@:Y*++[V2:?Q#-4]*F2N,[&2(E3#/UR>[R6*0``),!HM/DZWLW_ +MOTY:`-^\37B&@Z:>EP,9U&8?61B`B11X*0``'```0`1AG9GA40%5%^%J>7O1 +MQ*G6UI7X5P```!P``$`%.=E,.K#G1[`:HRJY.%%Z%;V=E.)4$K=&M/T$`)@! +M``"8`0```@```$4``915O@``0!$``,"H`0'`J`$"`?0!]`&`!V4LD5&;L:J( +M;```````````(2`B"`````````%X(@``>`$``'0!`0`,`P``#`$```R`#@"` +M`P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@" +M```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@`` +M``@$```.*```B``"``#C%]M1\!#`H&N2BR^]DFG\0S5/2IDKC.QDB)4PS]1U[@.4A$O0SXH[_1.^JV,/;&5[`L?HI +M[_.H)#GLEBD``"3`:+3Y.M[-_[].6@#?O$UXAH.FGI<#&=1F'UD8@(D4>"D` +M`!P``$`$89V9X5$!51?A:GE[T<2IUM:5^%<````<``!`!3G93#JPYT>P&J,J +MN3A1>A6]G93B51*W1@`-`P"8`0``F`$```(```!%``&45=T``$`1``#`J`$! +MP*@!`@'T`?0!@`=E*,$P]NS/%S,``````````"$@(@@````````!>"(``'@! +M``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``DL>HR!Y7IBP,*-@E +MD$$1/GM`)#VQN+F[T^F21N>:'W>C5JLN<^6RJI51,#POEL[+E!*M[2S*$#\; +M3"#T)1R>"V&1'1"Z+.U;WA^)0O\^.IS3O?*#`F7PZV^3+KWWA0[\T_:6O6P? +M&^I`B;FVJCWQ:^%ALFIL@K6T%B5)LCD],R,I```DQ4AV,6@B@TU=\+W9CN9* +M.E)XUVT[Q$3QT@ZH1!*]?S4I```<``!`!'VY,!_24)D1^,U[Q;?XQ+NK1695 +M````'```0`7,ZP(4(VWF*-_0DC.2^-B'^6TFVE42MT8)-@8`F`$``)@!```" +M````10`!E%7A``!`$0``P*@!`<"H`0(!]`'T`8`'92C!,/;LSQ5Z8L#"C8)9!!$3Y[0"0]L;BYN]/IDD;GFA]WHU:K+G/E +MLJJ543`\+Y;.RY02K>TLRA`_&TP@]"4-=M.\1$\=(.J$02O7\U*0``'```0`1] +MN3`?TE"9$?C->\6W^,2[JT5F50```!P``$`%S.L"%"-MYBC?T)(SDOC8A_EM +M)MI5$K=&E7<,`)@!``"8`0```@```$4``9168@``0!$``,"H`0'`J`$"`?0! +M]`&`!V4HP3#V[,\7,P``````````(2`B"`````````%X(@``>`$``'0!`0`, +M`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,# +M```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,` +M``4#```(!````@````@$```.*```B``"``"2QZC('E>F+`PHV"6001$^>T`D +M/;&XN;O3Z9)&YYH?=Z-6JRYSY;*JE5$P/"^6SLN4$JWM+,H0/QM,(/0E')X+ +M89$=$+HL[5O>'XE"_SXZG-.]\H,"9?#K;Y,NO?>%#OS3]I:];!\;ZD")N;:J +M/?%KX6&R:FR"M;06)4FR.3TS(RD``"3%2'8Q:"*#35WPO=F.YDHZ4GC7;3O$ +M1/'2#JA$$KU_-2D``!P``$`$?;DP'])0F1'XS7O%M_C$NZM%9E4````<``!` +M!8HW]"2,Y+XV(?Y;2;:5A*W1E.%"@"8`0``F`$```(```!%``&4 +M5J(``$`1``#`J`$!P*@!`@'T`?0!@`=E?6!^U()9U;4``````````"$@(@@` +M```````!>"(``'@"``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MDJ#1:713(^`,5-K40>[29;JFPDO03M2#C;<"U$5H6TFNUQP5$SI.IW6#J<85 +M/.KU%#JE;E@&V3RSEK,C2K8:`O)2A6R-:7@A0"3Y7QPG6?!%)IN0YC,VQXK_ +MS%`#:/U,JG=],I>`OKK>[&VZU9*N4X$DTSAH*R.=YQ!8G$68$X\I```D9#0A +MW!1M\,&1WV!V6K&16TPK]#R'2;J9YO7;,@Y?7!PI```<``!`!"1#Y@A+%-M: +M7,A;@+W'B]FFW8#7B5@U82MT94 +ME`H`7````%P````"````10``6%:C``!`$0``P*@!`<"H`0(!]`'T`$0&*7U@ +M?M2"6=6U```````````I("(@`````````#P````@``!`!@````(@6O$4[TU; +MRF+SUHQ(MI_%P,582MT9BI`H`N`$``+@!```"````10`!M%:D``!`$0`` +MP*@!`<"H`0(!]`'T`:`'A7U@?M2"6=6U```````````I("((`````````9@A +M```@``!`!@````(@6O$4[TU;RF+SUHQ(MI_%P,2(``'@```!T`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``DJ#1:713(^`,5-K40>[29;JFPDO0 +M3M2#C;<"U$5H6TFNUQP5$SI.IW6#J<85/.KU%#JE;E@&V3RSEK,C2K8:`O)2 +MA6R-:7@A0"3Y7QPG6?!%)IN0YC,VQXK_S%`#:/U,JG=],I>`OKK>[&VZU9*N +M4X$DTSAH*R.=YQ!8G$68$X\I```D9#0AW!1M\,&1WV!V6K&16TPK]#R'2;J9 +MYO7;,@Y?7!PI```<``!`!"1#Y@A+%-M:7,A;@+W'B]FFW8#7B5@U82MT9>R`H`4`$``%`!```"````10`!3%:E +M``!`$0``P*@!`<"H`0(!]`'T`3@''7U@?M2"6=6U*ALTU^%CPR2W[F.R!:W?'!EV0*S>[J:=>W$SY^)?_XA&$5I4_$ZL<8$R57 +M.L=.*]O:0,O4NJK4%[TM4""R6Y+E')`"3>'>W2`NM%5,.Z0^Z4*>D_G^+0Y8 +M`W$]S5;G9/$/*0``)#,0:W/^$W*XWM*QG!2,5/SB?3Y^;-%[<*<*4>4L]VLP,`,U:9@6**@SVQY>.8*X +M'EV&S;Y)=P=(\^%'I*(-.F5*F%8>_&P;\`O?=C+>,.*,'6TW!2S20]Q]\;.% +M#Y@,*[]_Z8\.A3%_2?,ZP5BYZ_JO='ONJ"O&^FW-Q<)JL"Y@<'R$]J@6/'RY +M`%&@"PO*%@9NIHX>2$*&W;#(@MQ,*I_8)3)"P5734;N9AB+X`!6.30) +M+9';#-]XT=Y>H`VMVY:7=.B/&2>MA-P+=^,L'2S)]*N@V!KLR(_X;9W*>L\^ +MO^Z>,DJ6H1[CV7*;%TF(W`@2P?`$-4[7Q2?$C?)`U]7X?0("XX +M.2%.6582MT:?,`L`'`$``!P!```"````10`!&%:I``!`$0``P*@!`<"H`0(! +M]`'T`00'Z7U@?M2"6=6U\5"W#< +M*SD'TL:([`R"J1B*6;6#X`7/:.G#6SJ^ZIH)"6HQ#!\XC#K*1?=C.E2`,$8P +M+?Q5=JNLA@\E]RFI8!F.6X&>*7O3:UA!W<=XY)^>GV^($?>>P/A'L4Z]EB.L +ME)U6)^'[>VQW@F/\[84#?$?K1-86JU$HTE;.F%1^[;;DD=`GE*D7_PNQ3#16 +MTR1?/=">OV*"O-D>.#+QDK#3]2EEJ^[2HJ+/A&WDO/TII"K/'`_59G)'ZR5' +M%'06FF]SGC/.MK'*,J(?AXAO=@;,%K>L!$4?2BMKL+<(E582MT:..PL`_``` +M`/P````"````10``^%:J``!`$0``P*@!`<"H`0(!]`'T`.0&R7U@?M2"6=6U +M0LPT19,'(EKNAN0H"<8I3C,(B3(G2>SM_WUOPC.( +M0>AL%\)F)2);%)W&':OR942M1K#+-$$'E[XR%9^\(>/.5MWD`MVHU#=):)_? +M^S(3GB+P8+;2--#K+Z\]_!.DX"8K]W+AV>UUEBN!)-Q6$K=&.$8+`&P```!L +M`````@```$4``&A6JP``0!$``,"H`0'`J`$"`?0!]`!4!CE]8'[4@EG5M7,Z +M_-?BS(I0+B`D(`````(```!,*0``,*Q-PU5PG$:'J=,)S)K?5KUKV1&QX'9< +MR\5/%[0[ON[H^"W5_4FZN-.DU-(+5A*W1B-C"P!L````;`````(```!%``!H +M5JX``$`1``#`J`$!P*@!`@'T`?0`5`8Y?6!^U()9U;5S.OS7XLR*4"X@)"`` +M```#````3"D``##4JX&=3IWB]/_U*\)0,$3;RAWH<( +MLI!C!CV;0#*.;E82MT;&?@L`/`$``#P!```"````10`!.%:O``!`$0``P*@! +M`<"H`0(!]`'T`20'"7U@?M2"6=6UMRP_#]Z&R0ULR1C\VF,A#TA,N]Q]^`$C[\_`C&$T8:.K5/X?TABDAM[NR^ +MKD'W@1`.%8P6KCH#1;:&[?E4[Q._W5O,EX=P371$N0J(.Z,5P;9W8;Z!98"Y +M/)H,HQ+`T<^UHEBFQG_@>XFS*I:7^71]KV>\A'(")48IJOBFH)GC,!$_WQM3 +MQ2,+?DFJ%P0S,T3Q7=JLSDQK[+IA7]^)$`"RCO,'6IU$S#8V;U'=4#X3_&%< +MY?ID!HL^A+P_5.]=&"$P6H&3>R2\`D!OJ&'CPR`GP%WYE2RFLLX6(3XDD?(/ +M!/H487@G53\9XA![IEL9K79H[:[_T +M9F'4!7L<*A"S*AWY%V7*W/C)GMM`T[Q.[,P?T,%[$`YLF<&?,?I1-?FF0B<8%#1``3$Z!?]$NP\^RT%XK`PK!BRAI +M'S7"^-9;!Q_Q0!A;(A,UBP*EQ=3VB$]&RY?OQ166DPA*B%[>#44[DR]3SSCU +M"OP4H'1P$F^]E([L!N3A=A64#"MR@;]K!G^K@40E?R5A_"?)S1ER+S@S.[Q^ +M.4;`@B^$'9NGW0(I5A*W1B::"P#L````[`````(```!%``#H5K$``$`1``#` +MJ`$!P*@!`@'T`?0`U`:Y?6!^U()9U;5S.OS7XLR*4"X@)"`````$````S"$` +M`+"&+1MM])JHU$U%9T5[:0EI](-*$2)KKDD4F_K"=JT[KJW`,@N +MS5\8"]/0[G"H!2,M70SA':"$?_K`2HMSB@BL+.UEC8R`+) +M2L>#@W.$D7369;Z_`?MU2(;F;-N,N@\M9"A)AF95Z$Z.#B(]"JUB5\!V**[+ +M*MY:7O50OR;TK*0%)^$\YGG;8QJFO3JX/*@\35D-"60U`TJ'=E.B*%R'[,JIXD>._*DO75?BWRN) +M5I[.P)AS%JQM-%C1:N1^V`".MLE"4_-K!93?R3D;5>`Z2,HP'>)BC4OS51D3 +MKLWI#84XU66Z\N4_:SJ"/E+&?6Y5680CFNK+^!11` +MFD6[JGFIVPB\D?_WB3;Q-4P)X[*:5A*W1I?;"P`\`0``/`$```(```!%``$X +M5K0``$`1``#`J`$!P*@!`@'T`?0!)`<)?6!^U()9U;5S.OS7XLR*4"X@)`@` +M```&```!'"$``0`S!PQ^M?B#S37HXP/=9E%-FV-ZMK$1>4;[+W_9'!3V62`8 +M"1PU9;Y/=GM.G`=Y#\NU\WVUPR!2.`YYY-9HI(*WW?U!= +MI-IY9*B_>'GDZ!*.P`HBL39*_)'SG.XJ4/ZI;W#":"B<4.KQ,^Y6$K=&4><+ +M`!P!```<`0```@```$4``1A6M0``0!$``,"H`0'`J`$"`?0!]`$$!^E]8'[4 +M@EG5M7,Z_-?BS(I0+B`D"`````<```#\(0``X-`+9=P_Y0F7`.$O0Z\95S+G +M%Y7X?A:G;@'&)=MN&$?WPFVCGFP]!JL9R8Q"W\82VL'5$IO*`,52(95Z@LQ" +ML>3PLG=F`>EK=WR3]`CD`+(6>('YRQDC7I\WLOC0=ASMR5N"F*`1KV>I(^QG +MZS-PG'9=S%9J)D993Y^%_Y?U,503!BK4+@(.@A]41!FJ_V224MJ+KU6+JMMO +MF_"3J9B?PC')L:H21T7[O&4V0I:=9"3GI'0AW?PR,$\%=BS"-/;BUAL]_D$? +MP.O'*D)/FU,D_X(_F6N3)L3ON6@J#!A6$K=&@O<+`.P```#L`````@```$4` +M`.A6M@``0!$``,"H`0'`J`$"`?0!]`#4!KE]8'[4@EG5M7,Z_-?BS(I0+B`D +M(`````8```#,(0``L)-MCFD9GIZ0XB[Q*`>3P3(!$C&DIS<`P(5//W;,5X!X +MY*U4[%YN+8!^,"]!O4W_;%BL!/7@-_5;_S.$1"!\.U,DCBW>=,:?6-S3L7.H +M(N`VK"N8+Q;?X4WNPKT8V>:POW/!)DT1J\6E\[1K)L;8Z+-^@6@O:8#(C/N? +M*OAY&'U\IZ'DE#]0J`YC@-EKCR/I=[>*N+T_#J<0,_J-LG.:6+>PW35_$KZ9 +M*9"2=`I6$K=&)QH,`.P```#L`````@```$4``.A6MP``0!$``,"H`0'`J`$" +M`?0!]`#4!KE]8'[4@EG5M7,Z_-?BS(I0+B`D(`````<```#,(0``L*X>9!RT +M5^4F!6*;_A2VL0HBFF4]C"=_:/G!;+Z.$'[T`>CC3N3)[CK-@V5@SLOH71&C +M?M?PD*UQ7+/1E1R'=TXYJ6:^C');8*?7V1J-8$$<;$8$X-ZO>H,E:G?NI#S9 +M>2%^!^8V=P5AYOY8"3^M#12VP/Q^CQ9*9-U50Y#;[SO=#O]\J"/SR'`@"_O*TWZ'@A7Z +M2?<3IHVCF]Z8$F7R,JY#_XS6\<3,X9D<^&*9$1\N<8% +M[>C)%-%$*72:U&EU(DA38,1L&9*0896+:>?)AU.N($`0&&P&+-.I(2KZ*:3U +M0`-6=^.`6-H.PTEU/+QY!Y^WGU9#Y685C*P,*H1!ZSU=3]EDL+#F=<'C);QR'OV,3LZ;+*9B6X',<\6]=JZ;DAP3,\09JJC@-9X63C8\ +MUZ.MGW7K.&+:O._A'P7S!62=E(Y-&`Z6+2;@D`]9[(-)TS`O.OL&#A6]C^CQ +M%KST3``!K*2Z%I/4'UZ:RHQA[RBD=A(M=RB +M=X^D8L&M/6O7=BN%K.'5`:[=\CXE;@_]%&MW'"@K&2(%:Z``!`$0``P*@!`<"H`0(!]`'T`&0& +M26EAWC0"RW4LII*]/I]H;A@N("4(`````````%PJ``!`J09)'+@P0R?6`N"S +M/$+&E5V>KP`MG!,/UE]<]=S=,MH>J40;1>."DPL>[B[#1!)!6&CPZ\_@YLIX +ME($,5A*W1FJP#`!L````;`````(```!%``!H5KL``$`1``#`J`$!P*@!`@'T +M`?0`5`8Y:6'>-`++=2RFDKT^GVAN&"X@)2``````````3````#`1>SWX#\H\ +M5B66DCO^;A!_O!#J2<+7C#B;4#&H6ZQ7@^SHYPT!X%PODV5JI582MT8YOPP` +M;````&P````"````10``:%:\``!`$0``P*@!`<"H`0(!]`'T`%0&.6EAWC0" +MRW4LII*]/I]H;A@N("4(`````0```$PJ```PAROHV_3YU=\1X)$.;0M>R_DY +MN!'-;Q)@L%!+YW/+]LC\V]_$#NGK"9#_=4=6$K=&U,P,`&P```!L`````@`` +M`$4``&A6O0``0!$``,"H`0'`J`$"`?0!]`!4!CEI8=XT`LMU+*:2O3Z?:&X8 +M+B`E(`````$```!,````,"%,H&*`C,&A;\^6XC4"(``'@#``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``%T'N'DL5 +MFOE"4(&/OV3X]513_#/:B,48;?1AK$#:-3W24];BD"V@GIR$']/Y]=/1K#%^[A\S,60**>E.S>'M98%PI```<``!`!.3REOSWX!WO,X:6[8@X +MC7REQIR:````'```0`7>T?;1'^^AB%:O(=SN"^!18\1H"%<2MT8LH@$`F`$` +M`)@!```"````10`!E%;'``!`$0``P*@!`<"H`0(!]`'T`8`'92_460$#H?$0 +M```````````A("((`````````7@B``!X`P``=`$!``P#```,`0``#(`.`(`# +M```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(` +M``$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"```` +M"`0```XH``"(``(``!=![AY+%9KY0E"!C[]D^/544_PSVHC%&&WT8:Q`VC4] +MTE/6XI`MH)Z4?L&RU<>-2O2+U:EFYZZPK= +MM!$@]9T&C:7ZDCIB6VREH5#.V*X=B+'XBD7R2(U)*TTK\][G/V)W5R@V:KY7 +M+:(8&(@\*0``)!A>7Y5,'`)@!``"8`0```@```$4``916S0``0!$``,"H`0'` +MJ`$"`?0!]`&`!V4OU%D!`Z'Q$```````````(2`B"`````````%X(@``>`,` +M`'0!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P`` +M"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```! +M`P``"`,```4#```(!````@````@$```.*```B``"```70>X>2Q6:^4)0@8^_ +M9/CU5%/\,]J(Q1AM]&&L0-HU/=)3UN*0+:">G(0?T_GUSKJ%:[.F_U4@K7E' +M[!LM7'C4KTB]7-K7FI9N>NL*W;01(/6=!HVE^I(Z8EMLI:%0SMBN'8BQ^(I% +M\DB-22M-*_/>YS]B=UUE@7"D``!P``$`$Y/*6_/?@'>\SAI;MB#B-?*7&G)H` +M```<``!`!=[1]M$?[Z&(5J\AW.X+X%%CQ&@(6!*W1BWQ!0"8`0``F`$```(` +M``!%``&45N$``$`1``#`J`$!P*@!`@'T`?0!@`=E1;`.U'S)V3D````````` +M`"$@(@@````````!>"(``'@$``!T`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``FOFCDRG%RS_]A:_I''8-.=P6N2\HJA]):LC=6 +M#JVI/%7G.+M_9W<=_NQAIB'HB=]Z:&3:L:82KW\@;#Y%\118+P.N".2\7M\% +M"3B`(1AKZHX7R;\-5(!\@@`2SW]RS3)HQ5"VH[MP'`!'45M?J:ATO8=@Y(8I +M```D_2]SM(UE*'Z=[>8^JLSP>$,$&\2`#)CC*U"0I```<``!`!+C1 +MT=[3`(V=B74VS/SU\07ZM&\4````'```0`5A$BB_IFADVK&F +M$J]_(&P^1?$46"\#K@CDO%[?!0DX@"$8:^J.%\F_#52`?((`$L]_WF/JK,\'A#! +M!O$@`R8XRM0D*0``'```0`2XT='>TP"-G8EU-LS\]?$%^K1O%````!P``$`% +M81(HOZ7(P)T;W)M9CAQ@67>0BK]9$K=&?1L``)@!``"8`0```@```$4``916 +M]@``0!$``,"H`0'`J`$"`?0!]`&`!V5%L`[4?,G9.0``````````(2`B"``` +M``````%X(@``>`0``'0!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P`` +M#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```( +M`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``": +M^:.3*<7+/_V%K^D<=@TYW!:Y+RBJ'URS<[ET3HSQK?;YXEJR-U8.K:D\5>B)WWIH9-JQIA*O?R!L/D7Q%%@O`ZX(Y+Q>WP4).(`A&&OJ +MCA?)OPU4@'R"`!+/?W+-,FC%4+:CNW`<`$=16U^IJ'2]AV#DABD``"3]+W.T +MC64H?IS>,#J1YWMYCZJS/!X0P0;Q(`,F.,K4)"D``!P``$`$N-'1WM,`C9V) +M=3;,_/7Q!?JT;Q0````<``!`!6$2*+^ER,"=&]R;68X<8%EWD(J_61*W1NYF +M#0"8`0``F`$```(```!%``&45Q@``$`1``#`J`$!P*@!`@'T`?0!@`=E&W@L +M#DI!)S@``````````"$@(@@````````!>"(``'@'``!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``$4/J@.WN;TE4B$D`#V:_?]BH^$6"APE8*]CO +M;/9#I\LJ'D*L`O!ZZX-0.T7J"[E%F$PY&$',A)#HS?Z\U"5IOQS>QEIB]B.6 +M2[C2]?UN$&AT_V>8T+-[6=--@*4OI&='#.?HE8Z8P-FB+X!Q-H17>Q80%'7;.2CO:=VT````'```0`5*8(>"+70` +MV]^\L=!W@@8WSO`EP%H2MT;T4P$`F`$``)@!```"````10`!E%<<``!`$0`` +MP*@!`<"H`0(!]`'T`8`'91MX+`Y*02NN#4#M%Z@NY19A,.1A! +MS(20Z,W^O-0E:;\UG338"E+Z1G1PSG +MZ)6.F,#9G.+S31N;^K:TF#N!;Q=!#6B5RG,"*X'V*0``)#;%&A9)P\W7"&R+ +M1#[;!>PK,M]2QY=3VZ*0``'```0`1WHB^`<3:$5WL6$!1UVSDH +M[VG=M````!P``$`%2F"'@BUT`-O?O+'0=X(&-\[P)"P.2D$G.``` +M````````(2`B"`````````%X(@``>`<``'0!`0`,`P``#`$```R`#@"``P`` +M#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```! +M`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$ +M```.*```B``"```10^J`[>YO252(20`/9K]_V*CX18*'"5@KV.]L]D.GRRH> +M0JP"\'KK@U`[1>H+N4683#D8074]NBD``!P` +M`$`$=Z(O@'$VA%=[%A`4==LY*.]IW;0````<``!`!4I@AX(M=`#;W[RQT'>" +M!C?.\"7`6Q*W1CRB!0"8`0``F`$```(```!%``&45SD``$`1``#`J`$!P*@! +M`@'T`?0!@`=E_!/(*-AX-7(``````````"$@(@@````````!>"(``'@(``!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``,S2A&EML7.)E[/;^^ +MQX5%'9@3G_U57=5X@C$K;S'[7[_58\SGO.S]2X%SWHL^J.V\B)_ +M_&F/_JX3\!Q;5QV,Q[(@R*A]:+@H!W]*ZY`H88DI```<``!`!,5#H05($E<4)DJR)5^4QNH=(N-O```` +M'```0`7;:18A1DF+F-*_'"C1S"=@1.[5(UL2MT8%S@@`F`$``)@!```"```` +M10`!E%=```!`$0``P*@!`<"H`0(!]`'T`8`'9?P3R"C8>#5R```````````A +M("((`````````7@B``!X"```=`$!``P#```,`0``#(`.`(`#```,`0``#(`. +M`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@`` +M!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"( +M``(``#,TH1I;;%W'Z=_3S$[*D0!;8P[*=`-.+;#?Q-X\Q[5B`?C#Z_G!^PXD +MN5"6K!QSOJ^>C*EQ7CB9>SV_OL>%11V7.L9((Q*V\Q^U^ +M_U6/,Y[SL_4N!<]Z+/JCMO(B?_QIC_ZN$_`<6U<=C,>R(,G,I1^BOB`V*0`` +M)'55Y`8D6HS'^!B2P-CI=!J9\WBH?6BX*`=_2NN0*&&)*0``'```0`3%0Z$% +M2!)7%"9*LB5?E,;J'2+C;P```!P``$`%VVD6(49)BYC2OQPHT`@``'0!`0`,`P`` +M#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```( +M`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4# +M```(!````@````@$```.*```B``"```S-*$:6VQ=Q^G?T\Q.RI$`6V,.RG0# +M3BVPW\3>/,>U8@'XP^OYP?L.)+E0EJP<<[ZOGHRI<5XXF7L]O[['A44=ESK& +M7*C$UZ!.?_55=U7B",2MO,?M?O]5CS.>\[/U+@7/>BSZH[;R(G_\:8_^KA/P +M'%M7'8S'LB#)S*4?HKX@-BD``"1U5>0&)%J,Q_@8DL#8Z70:F?-XJ'UHN"@' +M?TKKD"AAB2D``!P``$`$Q4.A!4@25Q0F2K(E7Y3&ZATBXV\````<``!`!=MI +M%B%&28N8TK\<*-',)V!$[M4C7!*W1N@=#0"8`0``F`$```(```!%``&45V\` +M`$`1``#`J`$!P*@!`@'T`?0!@`=E\PI"*U/]B.P``````````"$@(@@````` +M```!>"(``'@)``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``9?+2 +M22A&RE4@,KU7BK]4\K%]CR>^5N+`P$.7KD:<[-P3V>W6NG9\)#0W$%!A84)K +MQ31X/0`*DTC5!````'```0`6)CF[_H0HNRZPY=)NV848)"O!Z*5T2MT:Y!0$` +MF`$``)@!```"````10`!E%=W``!`$0``P*@!`<"H`0(!]`'T`8`'9?,*0BM3 +M_8CL```````````A("((`````````7@B``!X"0``=`$!``P#```,`0``#(`. +M`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P`` +M"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```" +M````"`0```XH``"(``(``&7RTDDH1LI5(#*]5XJ_5/*Q?8\GOE;BP,!#EZY& +MG.S<$]GMUKIV?"0T-Q!086%":\4T>#T`"I'+(%T`!?YXI,#J&H#;M+VLJFNR +M]5BH,ZS\94,J^59!$*[.%JL,I/PWT+'`'%<(!\.D5VNC]"CRX>%I@&ZYV-C$ +MW1TY>XF7W;(4*0``)*@C0.3H@1C;V2"7`"#T#WO#Y= +M*0``'```0`3`]8'_4H7*4<8R;6IA@8Z2'M(U00```!P``$`%B8YN_Z$*+LNL +M.72;MF%&"0KP>BE=$K=&7T<'`)@!``"8`0```@```$4``917?@``0!$``,"H +M`0'`J`$"`?0!]`&`!V7S"D(K4_V([```````````(2`B"`````````%X(@`` +M>`D``'0!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#` +M`P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@# +M```!`P``"`,```4#```(!````@````@$```.*```B``"``!E\M))*$;*52`R +MO5>*OU3RL7V/)[Y6XL#`0Y>N1ISLW!/9[=:Z=GPD-#<04&%A0FO%-'@]``J1 +MRR!=``7^>*3`ZAJ`V[2]K*IKLO58J#.L_&5#*OE601"NSA:K#*3\-]"QP!Q7 +M"`?#I%=KH_0H\N'A:8!NN=C8Q-T=.7N)E]VR%"D``"2H(T#DZ($8V]D@EP`@ +M]`][PW,W)K>KNS(M*C*`=47N72D``!P``$`$P/6!_U*%RE'&,FUJ88&.DA[2 +M-4$````<``!`!8F.;O^A"B[+K#ETF[9A1@D*\'HI7A*W1NI4!0"8`0``F`$` +M``(```!%``&45Z```$`1``#`J`$!P*@!`@'T`?0!@`=EI0:O#^ZBU20````` +M`````"$@(@@````````!>"(``'CW``!T`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``+8RU$A8C5RN?P)@4:)L^XFW*$_8VT;V9`;MJ*MGSY@.@WJDZ +M;WQP\MVG#I@,?<>;^$0J2N`UDRXIC_'<98<)_$4N9ZA8_-W]D8B[IH0B?Z-\ +MJ1M]@=DW*>?E/(9K-@*WMW-9#6&0\0]E*/#/-*3]+Q>/W>G4$$>%8:"`;UW^ +MV?`I```DW([#P)*^[_MVQ4@\YVSO'-"U>%42CB0'`M^55B9;S#LI```<``!` +M!'9;UA_^[%&POS!_IT!VS@OQPSE5````'```0`4/Z53$;W;#'.!/$P23#RZJ +M@@)ZF5X2MT;#?P@`F`$``)@!```"````10`!E%>D``!`$0``P*@!`<"H`0(! +M]`'T`8`'9:4&KP_NHM4D```````````A("((`````````7@B``!X]P``=`$! +M``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0`` +M`P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```( +M`P``!0,```@$```"````"`0```XH``"(``(``"V,M1(6(UH6/S=_9&(NZ:$(G^C?*D;?8'9-RGGY3R&:S8"M[=S60UAD/$/92CP +MSS2D_2\7C]WIU!!'A6&@@&]=_MGP*0``)-R.P\"2ON_[=L5(/.=L[QS0M7A5 +M$HXD!P+?E58F6\P[*0``'```0`1V6]8?_NQ1L+\P?Z=`=LX+\<,Y50```!P` +M`$`%#^E4Q&]VPQS@3Q,$DP\NJH(">IE>$K=&/\$.`)@!``"8`0```@```$4` +M`917LP``0!$``,"H`0'`J`$"`?0!]`&`!V6E!J\/[J+5)```````````(2`B +M"`````````%X(@``>/<``'0!`0`,`P``#`$```R`#@"``P``#`$```R`#@$` +M`P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0# +M```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``" +M```MC+42%B-7*Y_`F!1HFS[B;J3IO?'#RW:<. +MF`Q]QYOX1"I*X#63+BF/\=QEAPG\12YGJ%C\W?V1B+NFA")_HWRI&WV!V3W"(``'CX``!T`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``4N^_SVHGC*OO&ALTD&YSO@`1<_@R+DRH +M2_PWG(Q+9I%?YX#X'M:UKRL^PS*F(B)=K?_6]([QNPJKQD+3]JNX.=RN=-F +M93:UI\:2&&[,X2^GY'<#>A4=-X.N"P#L)Y +M]%E:.&4I```<``!`!)O7#/7XX1G=\H]*+_>#5T)RMA(N````'```0`7DQ5;9 +MKLH8%7`$`"%JZ5)E9\I]F&`2MT:(MP``F`$``)@!```"````10`!E%@E``!` +M$0``P*@!`<"H`0(!]`'T`8`'9;BNZP&%`)3S```````````A("((```````` +M`7@B``!X^```=`$!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0`` +M#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```" +M`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``%+OO\]J +M)XRK[QH;-)!N<[X`$7/X,BY,J$O\-YR,2V:17^>`^![6M:\K/L,RIB(B7:W_ +MUO2.\;L*J\9"T_:KN'.KTSI'VSCL741*H0!52)+*@^1_;N\AG!TP$E3#*?L) +M/!/QU'!0!:/C$1@\F'CG#K@L`[">?196CAE*0``'```0`2;UPSU^.$9W?*/2B_W +M@U="/@``'0!`0`,`P``#`$```R`#@"` +M`P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@" +M```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@`` +M``@$```.*```B``"``!2[[_/:B>,J^\:&S20;G.^`!%S^#(N3*A+_#>UK6O*S[#,J8B(EVM_];TCO&["JO&0M/VJ[ASJ],Z1]LX[%U$2J$` +M54B2RH/D?V[O(9P=,!)4PRG["3P3\=1P4`6CXQ$8/)AXYW*YTV9E-K6GQIS` +M=QO:C^^;42D``"090*W=A;]Y(8;LSA+Z?D=P-Z%1TW@ZX+`.PGGT65HX92D` +M`!P``$`$F]<,]?CA&=WRCTHO]X-70G*V$BX````<``!`!>3%5MFNRA@5<`0` +M(6KI4F5GRGV881*W1C$%!0"8`0``F`$```(```!%``&46*$``$`1``#`J`$! +MP*@!`@'T`?0!@`=ES$9T>B$M_B8``````````"$@(@@````````!>"(``'CY +M``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``71DE8+_9@V9\W7]) +M`#*@MJ9+V5ZG6U9PWQS:?1==1B7NN;M7[IXI```D!`/L?Y0'(Z]]O-G$G_/M +MW7/)T^PYEZO\9IN7.;+*:V\I```<``!`!`W0;171?.OZJF9[[-T$F$[*D@BK +M````'```0`7DG3]AYR?URZ"LP':B'BXP4WA96V$2MT:',0@`F`$``)@!```" +M````10`!E%BF``!`$0``P*@!`<"H`0(!]`'T`8`'9IUM6<-\0CH.JF,&U\AITH^!YZ4:;"U,]VV@[HG-%![7&LEM.NU=`#@*KW"S +MI39;LY6O@_,]M-S$#@&!L8@6E*%[F*NMU3F$W!+W5F%-^ZLGG48E[KF[5^Z> +M*0``)`0#['^4!R.O?;S9Q)_S[=USR=/L.9>K_&:;ESFRRFMO*0``'```0`0- +MT&T5T7SK^JIF>^S=!)A.RI((JP```!P``$`%Y)T_8>/D``'0!`0`, +M`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,# +M```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,` +M``4#```(!````@````@$```.*```B``"``!=&25@O]F#9GS=?TD`,J"VIDO9 +M7J=;5G#?'-I]%US<'!,(`UDM&O]CW>=EGD(Z#JIC!M?(:=*/@>>E&FPM3/=M +MH.Z)S10>UQK);3KM70`X"J]PLZ4V6[.5KX/S/;3YBKK=4Y +MA-P2]U9A3?NK)YU&)>ZYNU?NGBD``"0$`^Q_E`2=/V'G)_7+H*S`=J(>+C!3>%E;8A*W1FY^#`"8`0``F`$```(```!%``&4 +M6,L``$`1``#`J`$!P*@!`@'T`?0!@`=E:DZL=(&"8X,``````````"$@(@@` +M```````!>"(``'C\``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MZOK,]EYLGV93N?YY'H

[-^E=0$3&-K@[)7QKHGTVYO,@)F6"Z8Q6F4:8!C +M<_"P4`X\-=,#WLX7Q%4,O;/_Q$$T5>I5PU^LG%&FEE]!6LMG/;-6.'"';R92 +MF[[&UE@.JIJ$@@O:<5^CRIF_YO +MJ<+!M5P93UM=H82:-$$$`KP*>=(V,37%Q+I+1E@I```<``!`!.082$9[/MN] +M/U5N,,%\L)59````'```0`5F57S]P;,F@#I6JH>A*G#:]Q?**6,2MT8K +M:0``F`$``)@!```"````10`!E%C0``!`$0``P*@!`<"H`0(!]`'T`8`'96I. +MK'2!@F.#```````````A("((`````````7@B``!X_```=`$!``P#```,`0`` +M#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```" +M`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$ +M```"````"`0```XH``"(``(``.KZS/9>;)]F4[G^>1Z','NS?I74!$QC:X.R +M5\:Z)]-N;S("9E@NF,5IE&F`8W/PL%`./#73`][.%\15#+VS_\1!-%7J5<-? +MK)Q1II9?05K+9SVS5CAPAV\F4IN^QM98#JJ:A((+VG%?H\J9OW+>$TFS%-S[;O3]5;C#!?+"7`17E60```!P``$`%9E5\_<&S +M)H`Z5JJ'H2IPVO<7RBEC$K=&S:H&`)@!``"8`0```@```$4``918W```0!$` +M`,"H`0'`J`$"`?0!]`&`!V5J3JQT@8)C@P``````````(2`B"`````````%X +M(@``>/P``'0!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R` +M#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,` +M``@#```!`P``"`,```4#```(!````@````@$```.*```B``"``#J^LSV7FR? +M9E.Y_GD>AS![LWZ5U`1,8VN#LE?&NB?3;F\R`F98+IC%:91I@&-S\+!0#CPU +MTP/>SA?$50R]L__$0315ZE7#7ZR<4::67T%:RV<]LU8X<(=O)E*;OL;66`ZJ +MFH2""]IQ7Z/*F;]RWA-)LQ37,=\PX!OAL]D%SLKRRBD``"0][F^IPL&U7!E/ +M6UVAA)HT000"O`IYTC8Q-<7$NDM&6"D``!P``$`$Y!A(1GL^V[T_56XPP7RP +MEP$5Y5D````<``!`!695?/W!LR:`.E:JAZ$J<-KW%\HI9!*W1C&W!`"8`0`` +MF`$```(```!%``&46/8``$`1``#`J`$!P*@!`@'T`?0!@`=EXY/3M[_L`<$` +M`````````"$@(@@````````!>"(``'C]``!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``?\A:T^&%^5M(']R?*1S!KW48_.SG96]Q>7JS;P,F^&AG +MDF?_R'*.P^@--7?M0CX88`_74_8&#Y$8M"!PV+!2@Q&'+G_N!FA1FXBR\ONQ#\E9>4F2`)%:-@(3$E.LFG^ROKC!0N!8VU;J.B6!?:4?5HRE&GEV8*-ZM*&@S,'YI5GU)O%/$XTX4MN@\*WLI```< +M``!`!(:-7<>ZW;8L@W4+I?=*L`E&Z@?W````'```0`4V@H,-.HCUF02MT90XP<`F`$``)@!```"````10`!E%C[``!`$0``P*@!`<"H +M`0(!]`'T`8`'9>.3T[>_[`'!```````````A("((`````````7@B``!X_0`` +M=`$!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```( +M`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$# +M```(`P``!0,```@$```"````"`0```XH``"(``(``'_(6M/AA?E;2!__MJ;T3,<$I,=,*0``)%XKJWLI1IY=F"C>K2AH,S!^ +M:59]2;Q3Q.-.%+;H/"M[*0``'```0`2&C5W'NMVV+(-U"Z7W2K`)1NH']P`` +M`!P``$`%-H'(4ZC0_!USCS8:CO'J##3J(]9D$K=&M"0.`)@!``"8`0```@`` +M`$4``919!P``0!$``,"H`0'`J`$"`?0!]`&`!V7CD].WO^P!P0`````````` +M(2`B"`````````%X(@``>/T``'0!`0`,`P``#`$```R`#@"``P``#`$```R` +M#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(` +M``0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*``` +MB``"``!_R%K3X87Y6T@?W)\I',&O=1C\[.=E;W%Y>K-O`R;X:&>29__(*ZM[*4:>79@HWJTH:#,P?FE6?4F\4\3C3A2VZ#PK>RD``!P``$`$AHU= +MQ[K=MBR#=0NE]TJP"4;J!_<````<``!`!3:!R%.HT/P="(``'C^``!T`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``LEXO&OS)`X%\Z""_P_LWSE8-=/;LT#,D-E0LWN$0FVSEK?[981'OHE +M1/?*0L'B2GKJO3.^?PXJX]$I```DJ3TP-N0T#+X[Q2(=LLU-_S$GZ>E4N0?] +M1#K9\>\#@^@I```<``!`!`"7EYG]7#5)\#=SE5:6I]*-#!;Y````'```0`40 +M";SBI#*ICGG0X>L2C]WT44D[\F82MT;O&@``F`$``)@!```"````10`!E%D6 +M``!`$0``P*@!`<"H`0(!]`'T`8`'98>RQ/I*%1]Y```````````A("((```` +M`````7@B``!X_@``=`$!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```, +M`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@# +M```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``+)> +M+QK\R0.!?.@@O\/['(:-Q)!XZ_-`$/"5(0%N-X7M\Y6#73V[- +M`S)#94+-[A$)MLY:W^V6$1[Z)43WRD+!XDIZZKTSOG\.*N/1*0``)*D],#;D +M-`R^.\4B';+-3?\Q)^GI5+D'_40ZV?'O`X/H*0``'```0`0`EY>9_5PU2?`W +M0``````````(2`B"`````````%X(@``>/X``'0!`0`,`P``#`$```R` +M#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,` +M``@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!``` +M`@````@$```.*```B``"``"R7B\:_,D#@7SH(+_#^QR&C<20>.OS0!#PE2$! +M7)-H+TJ5NH;(S)UC!V.T,&X_O>]H54"L(!=<>UDDV(]$`<-F,[,3/SH`M:,M +M'*!"U^7THYWKC>%[?.5@UT]NS0,R0V5"S>X1";;.6M_MEA$>^B5$]\I"P>)* +M>NJ],[Y_#BKCT2D``"2I/3`VY#0,OCO%(AVRS4W_,2?IZ52Y!_U$.MGQ[P.# +MZ"D``!P``$`$`)>7F?U<-4GP-W.55I:GTHT,%OD````<``!`!1`)O.*D,JF. +M>=#AZQ*/W?1123OR9Q*W1M%I!`"8`0``F`$```(```!%``&46;<``$`1``#` +MJ`$!P*@!`@'T`?0!@`=EA<2J%"169+L``````````"$@(@@````````!>"(` +M`'C_``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``O;?7/_R?;YFH +M/N\D60\TE&SY9>@](8YZ"K-\C;3IC(1NXN13J[]I=:M54$";-I#W:WB!DNEU +M0$C))74D'T]KNI>>FEI>[FB])(C[FT^MA#+DK<@WA^5\<*E+8Q-73FEOJ!R- +MQ6!7XET=N[2Q+9P(4`>29WB.WMF8S-LC'LX&<2MT:)E0<`F`$``)@! +M```"````10`!E%F]``!`$0``P*@!`<"H`0(!]`'T`8`'987$JA0D5F2[```` +M```````A("((`````````7@B``!X_P``=`$!``P#```,`0``#(`.`(`#```, +M`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$# +M```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0` +M``XH``"(``(``+VWUS_\GV^9J#[O)%D/-)1L^67H/2&.>@JS?(VTZ8R$;N+D +M4ZN_:76K55!`FS:0]VMX@9+I=4!(R25U)!]/:[J7GII:7NYHO22(^YM/K80R +MY*W(-X?E?'"I2V,35TYI;Z@GP"`NY( +M!%]8*0``),L_^U_1Y\EF5D/>7$`8@/(6\1:F!;9JI$9EV9T"1VF.*0``'``` +M0`1!R_0V5?Z42P/`$X@6#J]O:.J\`````!P``$`%O'L2V<"%`'DF=XCM[9F, +MS;(Q[.!G$K=&GM8-`)@!``"8`0```@```$4``919RP``0!$``,"H`0'`J`$" +M`?0!]`&`!V6%Q*H4)%9DNP``````````(2`B"`````````%X(@``>/\``'0! +M`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$` +M``,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P`` +M"`,```4#```(!````@````@$```.*```B``"``"]M]<__)]OF:@^[R19#S24 +M;/EEZ#TACGH*LWR-M.F,A&[BY%.KOVEUJU500)LVD/=K>(&2Z75`2,DE=20? +M3VNZEYZ:6E[N:+TDB/N;3ZV$,N2MR#>'Y7QPJ4MC$U=.:6^H'(W%8%?B71V[ +MM)R:PJV/W6=M;K%I'WI\`@+N2`1?6"D``"3+/_M?T>?)9E9#WEQ`&(#R%O$6 +MI@6V:J1&9=F=`D=ICBD``!P``$`$0([>V9C,VR,>S@:!*W1N3C"P"8`0``F`$```(```!% +M``&46?```$`1``#`J`$!P*@!`@'T`?0!@`=E4),)Y]#YMV0``````````"$@ +M(@@````````!>"(``'@!``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``P,%-,ZRJ"5(<$U)\+G?,DOE3!SN?2QC&"B?(DG'XK6W7@%B1'V5?A^,=^>!+MWLPI```D +MW!1>=;N'XW.>LZK4UJJ)T/SK6)4R+C>%YK2;EEE$K;PI```<``!`!+@#9]GJ +MC#ZC?PX6MC/_"EG*\$\C````'```0`5_DSH$.]WW(E+PPU,KZCTR;,L7`F@2 +MMT8*#P\`F`$``)@!```"````10`!E%GW``!`$0``P*@!`<"H`0(!]`'T`8`' +M95"3">?0^;=D```````````A("((`````````7@B``!X`0``=`$!``P#```, +M`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@" +M```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,` +M``@$```"````"`0```XH``"(``(``,#!33.LJ@E2'!-2?"YWS)+W*$B^.^F/ +MOO.)L!64JMYR#BI];L^YX'X]:T +MFY991*V\*0``'```0`2X`V?9ZHP^HW\.%K8S_PI9RO!/(P```!P``$`%?Y,Z +M!#O=]R)2\,-3*^H],FS+%P)I$K=&8@X&`)@!``"8`0```@```$4``91:```` +M0!$``,"H`0'`J`$"`?0!]`&`!V50DPGGT/FW9```````````(2`B"``````` +M``%X(@``>`$``'0!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$` +M``R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P`` +M`@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``#`P4TS +MK*H)4AP34GPN=\R2]RA(OCOIC[[SB;`5E*K><@XJ?6[/N>!^/7.1/C8-3JKE!6)R*=#&F.L%^+V=]'R +M8X]Z5,'.Y]+&,8*)\B2`6)$?95^'XQWYX$NW>S"D``"3<%%YUNX?C +MJ,/J-_#A:V +M,_\*6"(``'@"``!T`0$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``?PSC'%7R3D#099@0#DG%B0U;:\XG2*17TG@4\5"_ +M4C48/[YS18UT"Q/4MP/S\,Z$NN#@H0`$Z`$U3GR>;$HR!T3>&ARG#WK4D:$T +M+AK!B-2)'B1&#`DD4T1A0NWR9G`%W1J]#!69)I>GG#FHQ;S`0T,NKP +M6H!^/@RP:S`I```D'RG`WA,KV(@0/KE^0;;'7&2M\[?@#K7,C&538EW?E_`I +M```<``!`!"X*>GA(9D+&N#%IF"WRE]96H2MT98*00`7````%P````"````10``6%H;``!`$0``P*@! +M`<"H`0(!]`'T`$0&*8@*M+`)K;MX```````````I("(@`````````#P````@ +M``!`!@````3KN^T\Q:SHS7Y_V0748*Q3[<"G/&H2MT;1.`0`N`$``+@!```" +M````10`!M%H<``!`$0``P*@!`<"H`0(!]`'T`:`'A8@*M+`)K;MX```````` +M```I("((`````````9@A```@``!`!@````3KN^T\Q:SHS7Y_V0748*Q3[<"G +M/"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``?PSC'%7R +M3D#099@0#DG%B0U;:\XG2*17TG@4\5"_4C48/[YS18UT"Q/4MP/S\,Z$NN#@ +MH0`$Z`$U3GR>;$HR!T3>&ARG#WK4D:$T+AK!B-2)'B1&#`DD4T1A0NWR9G`%W1J]#!69)I>GG#FHQ;S`0T,NKP6H!^/@RP:S`I```D'RG`WA,KV(@0 +M/KE^0;;'7&2M\[?@#K7,C&538EW?E_`I```<``!`!"X*>GA(9D+&N#%IF"WRE]96H2MT::7`0`4`$` +M`%`!```"````10`!3%H=``!`$0``P*@!`<"H`0(!]`'T`3@''8@*M+`)K;MX +ML$42Z410>("!L5`-*7POAV$`J$?R.V2##/2\S,^S@YH,:;Q^623%G26 +M6$FP/E>`[:>*4BHV5A1D9H!MU%`?I!>4:[Q%3HH+!%$NE'.*T2 +M+B`C"`````$```#L(P``T#"+[;RGF=LM7>B/07MQ8#N2NL<3T3I=[9SHR324 +MOT`/Q:,.OORRZ\;XJZ5[M(N303TI("YF0M<$F=$Y^7"]7DCXKF=K5$\;EO*^ +M(=3Z#F)T$_MM:*A9)O#3@26]>@[&ER@[1!:#KROV6(DN$\4/#6+NN.B8BS2% +M*SO*^1_*8Q^60BRQR^0NKB86=U0*UHXPD^"ON^J&3KZ?BFX8$M"!Q\5T1W-S +M`*)7#R!>LQDVX1")>Y(G!P/B@DLIN1K=4&Q)T93,Y:Z7Q1J9D@!$B< +MP)2?]I,=+N^B+!$'*V2DO4[_%]S('9MMCZGTJ52)N7=-&ZN)=N5S)N +MZ9S\:ORVO7Z#?6=XL=BK;IT6N3AD]8*ZWP4IFN"O1ZCK5QAJ;,6@N\CG^TOX +M(36/X^21E<5:&>Q?FS,B33R\"@#"C"@H8FOQ@M@SRLW0F'MO,(R8O"_D]=Y= +MK`ZZP6$/>(2P(X6!ZD6L@'JE>V*G[O4N-#F>^A3T`+5?=82.[CV'K)N3,J7T +M)@A",9EL0@QR&P!D#K.^]-YLTEFU1B(-]F$NHJU/6H\VNTE/]KO8^TEK+4(I +MX0I<*&H2MT;5S`0`_````/P````"````10``^%HA``!`$0``P*@!`<"H`0(! +M]`'T`.0&R8@*M+`)K;MXL$42Z4*E&XR$4)7W(D4VK;D\TNE3JA9H5<\X=OC5 +M1CP&V6+D4'&21R*5'A4A$/CAR-,3;>(O2?+O[C*,*@E3XWQJO&T1[?O?&_;3 +MFT9J$K=&D]<$`&P```!L`````@```$4``&A:(@``0!$``,"H`0'`J`$"`?0! +M]`!4!CF("K2P":V[>+!%$NE'.*T2+B`D(`````(```!,*0``,.7<'(*"E9LG +MQT8"5'Q=IU,3R0*_QTP/D42XAOZ`5X@F^=,[,UFT=U30YJOR:A*W1H_R!`!L +M````;`````(```!%``!H6B,``$`1``#`J`$!P*@!`@'T`?0`5`8YB`JTL`FM +MNWBP11+I1SBM$BX@)"`````#````3"D``#"4W9(6,5GZ2/<HV]'L[9BD9;024:P]_6H2MT;$#04`/`$``#P!```"```` +M10`!.%HD``!`$0``P*@!`<"H`0(!]`'T`20'"8@*M+`)K;MXL$42Z4.[W_F3RY3AM(AO)U)6Q*"E1UMTA,"JL +M;N4[05*8%#_L`[*[HIDOF/,M[X?:A3 +M6/*@&IRM"FB24]KMGL`4^:G/(1KE_H2W<=`*\NP!?,KJ(.A=-H4O`G8[,WON +M=>O$]P>2`-(QF)`=P_:&@%!>JRJKN84?2O>Y$D^0T-6Y%&F"K1C64("$:A*W +M1DL9!0`<`0``'`$```(```!%``$86B4``$`1``#`J`$!P*@!`@'T`?0!!`?I +MB`JTL`FMNWBP11+I1SBM$BX@)`@````%````_"$``.`U?+2=*XM8A^#O`K*Y +M7%+<&UOHF=D$(1&V>N0EQ$1\7^\`:MBI]/\HIY[`UR%V7V@=A^"10*YHF"K-VQ4YUR. +M2H8)5\0P-1`&-/1[.-_WV/YC'?*18M]Z\!_B:A*W1O`H!0#L````[`````(` +M``!%``#H6B8``$`1``#`J`$!P*@!`@'T`?0`U`:YB`JTL`FMNWBP11+I1SBM +M$BX@)"`````$````S"$``+!`8]7<4_?;G("#P]($*A^IU-(8V,7;WQ\`EW/J +M/6-;A2"S!B?O+0T5R(T-]I=^7HT@4^3:PXR7F%.EJ]J$K8UYWM&^FI)H#/<< +M+3U\+JA0:^Y%3685G;T`2?H6O0`JJESF6L@Z2?!6XA'5A?"PFXE^_'<5IOCA +MHXR9$N-^Q:A*W1I1+!0#L````[`````(```!%``#H6B@``$`1``#`J`$! +MP*@!`@'T`?0`U`:YB`JTL`FMNWBP11+I1SBM$BX@)"`````%````S"$``+`% +M0SH,?:'T+F+`S'$$891#!/<@FK\+[L[4=0`XIK15P7M(E5+#>7G]SRI1YSD* +MZZ`,\,(>&72BK5_Y0)P0';YAQJ[+3.^"\Y+^L9G%/;NUOP=$]EN1#253H"@E +M"45.^GT-U7R94[**%X=B0"AUVH.M1JM9BSDD_+#"T7C8E9>R8TEVA,?Z^>G] +M>==93!#8OXL@4;I.KI$J'I:ZZ(;45VY!'(4X6WL^K +M\\>."V4W/">G2OU+733S`^%0QW",MZ\9]^4$NQ]!TDZB+8CX]W@^H`.#-_XK +M,L'1C_6M?CP6EXJYDD7>X0Q)2[MFSM('YR!PV$ +M5@WW<:OJD'H3VBK4-HC*')Y>J-23LGL<,.!0,P[XD=PRK%F89);'9F">SK.:="HE,[$ZRI?KL15M(MKVT/\$_&: +MUL>X(C86F6;"OML:G"R,[]E(KDJ*X7+.U[I._,;9ZI8H3(LH/B-_ND/?79(Y +MYUBVG-L$=/AJ$K=&EG,%`!P!```<`0```@```$4``1A:*@``0!$``,"H`0'` +MJ`$"`?0!]`$$!^F("K2P":V[>+!%$NE'.*T2+B`D"`````<```#\(0``X-[5 +MG(,T<=@*7>'#589U;Y/VWQP1MLH+AYR00,1B=S-4IMH4@$1&.%ZMI^)GL^.[ +M_@`J3"^;QA*[OR2DZ.&U>H24X`:CO)XG4*$)J$K=&Q8(% +M`.P```#L`````@```$4``.A:*P``0!$``,"H`0'`J`$"`?0!]`#4!KF("K2P +M":V[>+!%$NE'.*T2+B`D(`````8```#,(0``L+85<@2Q]?SR@@!$+IMP7K0M +M8L(!S1TV9\@^((L10+!Y^"QS0ZNS[=;.GB[W8Q<1X4[C_N>ZA79V4+:.(V?< +MP*-PJDE^5CY)Z??%`TO_+:]+/OP?],KRM+44%[323__TRB"@ +M'@\/UJ$K=&$J4%`.P```#L`````@```$4``.A: +M+```0!$``,"H`0'`J`$"`?0!]`#4!KF("K2P":V[>+!%$NE'.*T2+B`D(``` +M``<```#,(0``L*T%`Z5(7)N$*VU*E;7O&8W!"/$0$)%!XXA9IWZDZ*(L`K>C$[FU%AM^HSRT7^@5M3 +M*A\[VX2308V)@%U@*X<$0\W3H-IS:MY(LO]Q-`IM1LHE'"S +M';"(41K,X^LF$P>>HKWL5[$!Y*2J2)H(4,#Q/G^##DX"WH)U1RU\KSV8)TSE +M(RAJ$K=&8\L%`(P!``",`0```@```$4``8A:+0``0!$``,"H`0'`J`$"`?0! +M]`%T!UF("K2P":V[>+!%$NE'.*T2+B`D"`````@```%L(0`!4"M8JV0GH2,* +M-7O:<0*QI+,,DAV9%Q>DY[>'\OECJ#26;I,QM0JYE]%"YX*UG@8_41KXKT0. +MY_=MRP67,K-SK9"E"V@JIN[GNH(T/))HO@P@]$6'=U$FJL3MDAN[X3M272FDZWQ_<8S@ +M3FRL.4FRYHUR$U'8=^+PJY`JSTH:>IPSL3Z4ULU"A%X8$`3;/J3BGVR4!4J] +M+;59#D8:&9?';J_)5)A^"0";MHLE@CL`.JD&`,5*,D5WRJ-Y(9Z$=P?^1;/M +M6M+U6*0"MHZ"AD/19'X&(&`-3Z[>F+MM:09&5((`:)C3:O;6^GHH'VLXS*U> +M]?F#S!:=)Y.+:A*W1O__!0!<`0``7`$```(```!%``%86BX``$`1``#`J`$! +MP*@!`@'T`?0!1`+:])8Q_ +MO\&>,0T_L.T1&!<]27J90,>5R0]7U)!;&-M! +MA\D>9=^-I/@THVS6+)ZO\!O?W;CMK(.!#K3][0DD+6,+Y0US-X#L&H.+=T@YZ$`GGGWY_!&WT6Q +MR`P%ZP!VONPUGV9B%#G5>O&`B#,[!$%HO``!`$0`` +MP*@!`<"H`0(!]`'T`&0&25\WSRZW"&8K5O`+VI`QSA']XP1?='B6E0?*.:Q&WS>SN?S_7+*6?(N< +M0'NJ@6>A!;!4:ER>S)Z'4VP`:A*W1JLY!@!L````;`````(```!%``!H6C`` +M`$`1``#`J`$!P*@!`@'T`?0`5`8Y7S?/+K<(9BM6\`O:D#'.%RX@)2`````` +M````3````#"NN*9[MX3//SC$J%$>-%-"4#Z.G:3/ES:2Y;3A_=^^ACFFYZ;[ +MC.HV1`?8@6H2MT8(2`8`;````&P````"````10``:%HQ``!`$0``P*@!`<"H +M`0(!]`'T`%0&.5\WSRZW"&8K5O`+VI`QSA)XW[Y*:!CHGNJF^W2R'X6/6=^[EMJ$K=& +MD54&`&P```!L`````@```$4``&A:,@``0!$``,"H`0'`J`$"`?0!]`!4!CE? +M-\\NMPAF*U;P"]J0,&+>P'#VDGUEDD#.\>Y]I?]E@PX(`L!JKU4BQ2_<:A*W1JI0!P"8`0``F`$` +M``(```!%``&46C,``$`1``#`J`$!P*@!`@'T`?0!@`=E;^^I=3";/9P````` +M`````"$@(@@````````!>"(``'@#``!T`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``Y?AW^%B65_JG66HXCS)]G&Y7[*7OI-UPOJ@.K9*15N#BCB0] +MQ0+L>K)84Z!V)H27N''JO2,]-)XLK3DURQZZ!)YU=9J':)Q1BG1<( +M7X^4&@'57ZM'6BQ!K3)A""$K\(>NP!XI1XLB&M0:'AE00KW"1:1J%H^8QSR% +MQ8PH`F`$``)@!```"````10`!E%HT``!`$0``P*@!`<"H`0(! +M]`'T`8`'96_OJ74PFSV<```````````A("((`````````7@B``!X`P``=`$! +M``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0`` +M`P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```( +M`P``!0,```@$```"````"`0```XH``"(``(``.7X=_A8EE?ZIUEJ.(\R?9QN +M5^RE[Z3=<+ZH#JV2D5;@XHXD/<4"['JR6%.@=B:$EW-"BZP7KAQZKTC/32>+ +M*TY-N@2>=76:AVB<48IT7"%^/E!H!U5^K1UHL0:TR80@A*_"'KL`>*4>+ +M(AK4&AX94$*]PD6D:A:/F,<\A<6'*0``)&2&^5*\='\I)D?^`L#>407XK8SP +M"CSX>EDY`"^B?Q?**0``'```0`0$P,RCA!)>RRH4SLTX1D!,RA!76@```!P` +M`$`%;UJT]QC,!+[J@A#[JQ==3$0/VXUK$K=&A'H!`)@!``"8`0```@```$4` +M`91:-0``0!$``,"H`0'`J`$"`?0!]`&`!V5O[ZEU,)L]G```````````(2`B +M"`````````%X(@``>`,``'0!`0`,`P``#`$```R`#@"``P``#`$```R`#@$` +M`P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0# +M```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``" +M``#E^'?X6)97^J=9:CB/,GV<;E?LI>^DW7"^J`ZMDI%6X.*.)#W%`NQZLEA3 +MH'8FA)=S0HNL%ZX<>J](STTGBRM.37+'KH$GG5UFH=HG%&*=%PA?CY0:`=5? +MJT=:+$&M,F$((2OPAZ[`'BE'BR(:U!H>&5!"O<)%I&H6CYC'/(7%ARD``"1D +MAOE2O'1_*29'_@+`WE$%^*V,\`H\^'I9.0`OHG\7RBD``!P``$`$!,#,HX02 +M7LLJ%,[-.$9`3,H05UH````<``!`!6]:M/<8S`2^ZH(0^ZL774Q$#]N-:Q*W +M1MK-#@"8`0``F`$```(```!%``&46D@``$`1``#`J`$!P*@!`@'T`?0!@`=E +M\\,H(+K\:X(``````````"$@(@@````````!>"(``'@$``!T`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``=Z!MC6D$.*;]]\\.30B%\M;%3UKE][HYF'7BF*ZKP!PD*Y259#\,7I3QPT^&7W-Y$ +M_?@>U#X2H,[(Y<%K\Q(I```D$=2F&=SG1BDOOG0*>LFXM:*@172,F4$@;8UI +M!#BFW,L=W?R[)E/<_/MBV!=',TZ)L`G!2C"VR\`/G_PJQ\<6>%L#47):C*8> +MRC7YV:Y):AR'"^(I\-RV3'4'(+4#Z.9AUXIBNJ +M\`<)"N4E60_#%Z4\<-/AE]S>1/WX'M0^$J#.R.7!:_,2*0``)!'4IAG^5P??I353,2#<0* +M(BL3:>`)$0```!P``$`%J`V-D5\PY5(,Q`0``'0!`0`,`P``#`$```R`#@"` +M`P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@" +M```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@`` +M``@$```.*```B``"``!WH&V-:00XIMS+'=W\NR93W/S[8M@71S-.B;`)P4HP +MMLO`#Y_\*L?'%GA;`U%R6HRF'LHU^=FN26H*8KJO`'"0KE)5D/PQ>E/'#3X9?"(``'@' +M``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``L^YY(ZAS-B]%L(`Z +MWEX;=!:]&TNS9=VQ)K*7B.A#%]Y9T`5YUR^=EE_AA7Z5R5>04G@"V=R>C/(G +MB0"HF/P'0A[QN&,1(S?:W(X37M]"&CCPO1*G$[B#%AWY0#+UT#X#L1H7'T1\ +M">G8J!ON98@@G\ZO(7_*^X1ZD780&*AU%K35%4H"&@\@I```<``!`!&I&V,6GLHG%9XA66L<%L%,H*)1" +M````'```0`6G#'UG6I+56=5_B;2$E?6/X6$```````` +M```A("((`````````7@B``!X!P``=`$!``P#```,`0``#(`.`(`#```,`0`` +M#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```( +M`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH +M``"(``(``+/N>2.H&W06O1M+LV7=L2:REXCH0Q?>6=`%>=\;AC$2,WVMR.$U[?0AHX\+T2 +MIQ.X@Q8=^4`R]=`^`[$:%Q]$?`GIV*@;[F6(()_.KR%_RON$>G+S$PB%@F@A +M*0``)#&>WP>F2^\Z?&.FB/04'I%V$!BH=1:TU15*`AH/(*0``'```0`1J +M1MC%I[*)Q6>(5EK'!;!3*"B40@```!P``$`%IPQ]9UJ2U5G5?XFTA)7UG(8, +MO)MN$K=&>2P!`)@!``"8`0```@```$4``91:@0``0!$``,"H`0'`J`$"`?0! +M]`&`!V6O(&()'C^%A```````````(2`B"`````````%X(@``>`<``'0!`0`, +M`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,# +M```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,` +M``4#```(!````@````@$```.*```B``"``"S[GDCJ',V+T6P@#K>7AMT%KT; +M2[-EW;$FLI>(Z$,7WEG0!7G7+YV67^&%?I7)5Y!2>`+9W)Z,\B>)`*B8_`=" +M'O&X8Q$C-]KWT(:./"]$J<3N(,6'?E`,O70/@.Q&ARB<5GB%9:QP6P4R@HE$(````<``!` +M!:<,?6=:DM59U7^)M(25]9R&#+R;;A*W1HM]#@"8`0``F`$```(```!%``&4 +M6ID``$`1``#`J`$!P*@!`@'T`?0!@`=E0QJ#-MEAF*,``````````"$@(@@` +M```````!>"(``'@(``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M(0TO=%L(']HZ-&SXM!U>HI```<``!`!$LI^R9^>.S* +M!CM:A>#W_:O$M-Q@````'```0`5T00T>'E#NM?N%X^>C):C`X(Z)Y&\2MT:8 +M9`(`F`$``)@!```"````10`!E%J=``!`$0``P*@!`<"H`0(!]`'T`8`'94,: +M@S;989BC```````````A("((`````````7@B``!X"```=`$!``P#```,`0`` +M#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```" +M`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$ +M```"````"`0```XH``"(``(``"$-+W1;"!_:.C1L^+7(D%\J`(-9$K9F=I>M +M#ZHD<+16W>AK+?SS0TTVW[9B<)3ZN=R`J<:>`+,/S?&6 +MB<8>A@*6"6)]HC1\*0``))I]XR05+0<$O!M-!M4[%@\3K`/GHR6HP.".B>1O$K=&+Z8(`)@!``"8`0```@```$4``91:JP``0!$` +M`,"H`0'`J`$"`?0!]`&`!V5#&H,VV6&8HP``````````(2`B"`````````%X +M(@``>`@``'0!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R` +M#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,` +M``@#```!`P``"`,```4#```(!````@````@$```.*```B``"```A#2]T6P@? +MVCHT;/BUR)!?*@"#61*V9G:7K0^J)'"T5MWH:RW\\T---M^V7.`5`5=>FT;E +M"VNKX/>S;TB8?K;@U..>0,L''9`GP-NEP/E*3!/YSX(XM*1NJG-D6]A_A(66 +MHU=7HG"4^KG<@*G&G@"S#\WQEHG&'H8"E@EB?:(T?"D``"2:?>,D%2T'!+P; +M30;5.Q8/$ZP'-;W#$&ML=W[BUX'5ZBD``!P``$`$2RG[)GYX[,H&.UJ%X/?] +MJ\2TW&`````<``!`!71!#1X>4.ZU^X7CYZ,EJ,#@CHGD"(``'@)``!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``6L,:&K5$UY?W4@#(G'5(VSX3!V$^<96*=BG+8-G;0.4( +M60?W*3SXB[<5'AS`N/J4%U="Y$("9CQP,#W@O#ZA#S9U=LYV:4_K&GMM$9&^ +M9.QEH,UR<:_KP!__%O%E)%_D`N!R`+````'```0`7)XP+DOOJ,@)&"P#B\ +M0U;O?G+ZHG`2MT;+W@D`F`$``)@!```"````10`!E%K+``!`$0``P*@!`<"H +M`0(!]`'T`8`'93G*=QX622_=```````````A("((`````````7@B``!X"0`` +M=`$!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```( +M`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$# +M```(`P``!0,```@$```"````"`0```XH``"(``(``%K#&AJU1->7]U(`R)QU +M2-L^$P=A/G&5BG8IRV#9VT#E"%D']RD\^(NW%1X$&!(5K#Z6ZW2-DA52I +MH%.(#!68UG9$1N[\)5QR*0``'```0`30WU*DT,"_Y'OQ;Q921?Y`+@<@"P`` +M`!P``$`%R>,"Y+[ZC("1@L`XO$-6[WYR^J)Q$K=&[=T``)@!``"8`0```@`` +M`$4``91:U@``0!$``,"H`0'`J`$"`?0!]`&`!V4YRG<>%DDOW0`````````` +M(2`B"`````````%X(@``>`D``'0!`0`,`P``#`$```R`#@"``P``#`$```R` +M#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(` +M``0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*``` +MB``"``!:PQH:M437E_=2`,B<=4C;/A,'83YQE8IV*',"X^I075T+D0@)F/'`P/>"\/J$/-G5VSG9I3^L:>VT1D;YD[&6@S7)Q +MK^O`']SD"[*K"0JNH0W%'.$@UW=49$3,&<+LX@YN[\:!N1#M`,C%.T9U+2D` +M`"3@Z`WA!@2%:P^ENMTC9(54J:!3B`P5F-9V1$;N_"5<"(``'C_``!T`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``C^>")B8O,RM>FUM@M`0BWA*I,?VM +MVNW;EN[OQ_3W*Q\E6#<%733M'3DRGU>WC#((K0T:KG'0MB>WE>&@`"/VI'NT@OR-H8````'```0`5C +M.-J#V+C5<_EE$ZI8ZW?U=F&(Q'(2MT9K%@(`F`$``)@!```"````10`!E%N1 +M``!`$0``P*@!`<"H`0(!]`'T`8`'9>Q),LHA%_^!```````````A("((```` +M`````7@B``!X_P``=`$!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```, +M`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@# +M```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``(_G +M@B8F+S,K7IM;8+0$(MX2J3']K=KMVY;N[\?T]RL?)5@W!5TT[1TY,I]7MXPR +M"*T-&JYQW`>I3^@FCD=_D&]YRI6RS2!9#MYYMTHZV[$0+R(ZT%CL?.?*BTXI +M6>'3VQ'D+8G(G51/G&`DUOMI>)R#FY7XHG6;I-<:N$0!`,*]*0``)*]:,(N_ +MQ/AYLZM\)E&Y).-K@Y)_0",B%`@`%W.`;>W**0``'```0`1/.O22WGMY7AH` +M`C]J1[M(+\C:&````!P``$`%8SC:@]BXU7/Y91.J6.MW]79AB,1R$K=&-%@( +M`)@!``"8`0```@```$4``91;NP``0!$``,"H`0'`J`$"`?0!]`&`!V7L23+* +M(1?_@0``````````(2`B"`````````%X(@``>/\``'0!`0`,`P``#`$```R` +M#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,` +M``@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!``` +M`@````@$```.*```B``"``"/YX(F)B\S*UZ;6V"T!"+>$JDQ_:W:[=N6[N_' +M]/,,@BM#1JN<=P'J4_H)HY'?Y!O> +M>;=*.MNQ$"\B.M!8['SGRHM.*5GAT]L1Y"V)R)U43YQ@)-;[:7B<@YN5^*)U +MFZ37&KA$`0#"O2D``"2O6C"+O\3X>;.K?"91N23C:X.2?T`C(A0(`!=S@&WM +MRBD``!P``$`$3SKTDMY[>5X:``(_:D>[2"_(VA@````<``!`!6,XVH/8N-5S +M^643JECK=_5V88C$"(` +M`'B```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``[LRVD@WN79F! +MC]QDM^&,PC2%-^OAX-4G[-D,*#'E!*Y]]"YZ50;R8MDKC7*=?$=ICXZOP)A6 +MV5JAM.W=X"S\1PA2I:5JD@U[BI$A$=$R:;-/U4*3"+.BD5LV.<8BCK1O:%O8 +MR:LO+]FP/\DG.ZQPD+*)]%AEWR8'>.?W,2MT:8D`D`F`$``)@! +M```"````10`!E%O<``!`$0``P*@!`<"H`0(!]`'T`8`'93(;!H973EX=```` +M```````A("((`````````7@B``!X@```=`$!``P#```,`0``#(`.`(`#```, +M`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$# +M```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0` +M``XH``"(``(``.[,MI(-[EV9@8_<9+?AC,(TA3?KX>#5)^S9#"@QY02N??0N +M>E4&\F+9*XURG7Q':8^.K\"85ME:H;3MW>`L_$<(4J6E:I(->XJ1(1'1,FFS +M3]5"DPBSHI%;-CG&(HZT;VA;V,FK+R_9L#_))SNL<)"RB?17+TJLWQ-)C2Z< +MG282*0``)'5\Z[#)AU?A)K$HP#\MLYSY7"+8T@@N54/0Y0O:[L'!*0``'``` +M0`1DX/$U!5'0``````````(2`B"`````````%X(@``>(```'0! +M`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$` +M``,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P`` +M"`,```4#```(!````@````@$```.*```B``"``#NS+:2#>Y=F8&/W&2WX8S" +M-(4WZ^'@U2?LV0PH,>4$KGWT+GI5!O)BV2N-'-=%Q1$@O0_8WT````< +M``!`!::P"(5:CBZUW\ZL1!Z&7?)@=XY_=!*W1E3?#0"8`0``F`$```(```!% +M``&46_,``$`1``#`J`$!P*@!`@'T`?0!@`=E.?O="O^XAI$``````````"$@ +M(@@````````!>"(``'@``0!T`0$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``9UN@C2Q'%]FZ)MV=8(!%V42FS._`JS@UU0&X6:+BB-T6C;:)FXH?M)/O8U`SZ5X#( +MO=-7^HI$-WR'LL>*M44<>$63WF#"]051IMAHEQ'LI>=SVU,BB^B1$^`I```D +M5J@C$%V7DHB;:(N&#Q)]:#.G0:;TB!YX`G1AHNZQCQHI```<``!`!-L:>A51 +MR>\U6\2,4G$%JUHLX@=C````'```0`4FM"OP[[,U+Q"QH(&[+D#Z-;EO/'02 +MMT9<[@T`7````%P````"````10``6%OT``!`$0``P*@!`<"H`0(!]`'T`$0& +M*3G[W0K_N(:1```````````I("(@`````````#P````@``!`!@````;;H!"2 +M9;?<$.#HUVU)[$!K[/#YX'02MT:P_0T`N`$``+@!```"````10`!M%OU``!` +M$0``P*@!`<"H`0(!]`'T`:`'A3G[W0K_N(:1```````````I("((```````` +M`9@A```@``!`!@````;;H!"29;?<$.#HUVU)[$!K[/#YX"(``'@```!T`0$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``9UN@C2Q'%]FZ)MV=8(!%V42F +MS._`JS@UU0&X6:+BB-T6C;:)FXH?M)/O8U`SZ5X#(O=-7^HI$-WR'LL>*M44<>$63WF#" +M]051IMAHEQ'LI>=SVU,BB^B1$^`I```D5J@C$%V7DHB;:(N&#Q)]:#.G0:;T +MB!YX`G1AHNZQCQHI```<``!`!-L:>A51R>\U6\2,4G$%JUHLX@=C````'``` +M0`4FM"OP[[,U+Q"QH(&[+D#Z-;EO/'02MT:\(0X`4`$``%`!```"````10`! +M3%OV``!`$0``P*@!`<"H`0(!]`'T`3@''3G[W0K_N(:1M03>L5SM#>DA("(@ +M`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@# +M```"````"`0```(H``"(``(``-(-%+X$:,?2E9.^R%J58'0.*?%.P?R*"MQ2 +MBFW*@&L.R\.T$(!X\3;8;F*N75V(7X;:.*YKM%%VT?H3XP-K`-\^?!ZPU>%1 +MA=P#(?^%^8/KB64(5U,F0,^Z6H5$2,?*U&^P\````!P``$`%2EQ:0^H` +ME@`,*9*!/%F>?M.X5D)T$K=&]TX.``P!```,`0```@```$4``0A;]P``0!$` +M`,"H`0'`J`$"`?0!]`#T!]DY^]T*_[B&D;4$WK%<[0WI+B`C"`````$```#L +M(P``T)G)]TVND)AT^RG;N7JZQ!R7!H1^J8/BF) +M:^M&*TV6MOMR5BCG)I&S]./TP#WFYF#%E"IV]:2(SKJ_R>'C'KL[)J+B#[6> +M##U`EY#S?L5SM +M#>DN(",@`````0```)PD``"`R/).+3>;O(M,@QDV&0N80!O8[#MI@K?%0/`+ +MI8_W6=?":_*MMG>_33BD!$NX^V(:1J;(V$PF.&PC<_,A5+"1R?%2Y.(^;FX/ +MM%Q?MO^!VLH\:&B('&1R9FS86^4,[\G02MT8XA@X`'`$``!P!```"````10`!&%OY``!`$0``P*@!`<"H +M`0(!]`'T`00'Z3G[W0K_N(:1M03>L5SM#>DN("0(`````@```/PA``#@R3P, +M=R)[M$C6K\7V+^R:KWD-'`UD^+3L(U6C(2R[)+93#_WP.`P1@6Y_GP-VK+`R +MCQ+WAS(LPC!DQ"$)@PL*%;Q2^;3Z^@F"8>&&&J"H%,X#12BH`6+\[O;ZA;#> +M>1_.^VF-"B:+/3Z&S0@`;TQE70`6Q@9"6;7V0+25;$7$ZPUJ%,W["\YJCJ'/ +M.PSR^I5+=W<^-!6]Q^YJJYQ;0K9$C9PUT_NTBH'X)]>\Q5\.,LCD(DK>%9\? +M0JHLI1^2%&Z(P8EUX;V_SKG%/$R`N.>DV+,OGGJU](6I!V>+!702MT:.D0X` +M_````/P````"````10``^%OZ``!`$0``P*@!`<"H`0(!]`'T`.0&R3G[W0K_ +MN(:1M03>L5SM#>DN("0(`````P```-PA``#`;?0HD,/H[+D_"OH3N=$TN#&: +M"\A.&[>;4&5_V1#W-<.+HT*U)PGU,@(:65B;.9#Z8&^:74;GON8&6(SPV1*K +M-2)/C/NF4A#BLL\;#I)`[@"#::F.L8"/%GK]/M*`T$[86<8#0D>F5O(_"0?5 +MF4CDHB_54YGB(%;%G3_&@,2F:.)S509S]SX$\%;%2/#&=%#'J@`H@,WW(I1+ +M-X=\(#J?=.^@$EC`RGBQS'J(HQ.^>P_&_CK$@MT$K=&])P.`&P` +M``!L`````@```$4``&A;^P``0!$``,"H`0'`J`$"`?0!]`!4!CDY^]T*_[B& +MD;4$WK%<[0WI+B`D(`````(```!,*0``,`32OW=M&.)[S&SDJZS4T<7ZX6@> +M?0W9>BX2\_D5);Q/6#G7M0KYO<"3&31\=!*W1C^X#@!L````;`````(```!% +M``!H6_P``$`1``#`J`$!P*@!`@'T`?0`5`8Y.?O="O^XAI&U!-ZQ7.T-Z2X@ +M)"`````#````3"D``#"LT&PW0+(@A@^I<,@3$Q)TI91\V;WA?LA:DCN,]05W +M5?<27.,MJLIYBJTNE702MT:,T@X`/`$``#P!```"````10`!.%O]``!`$0`` +MP*@!`<"H`0(!]`'T`20'"3G[W0K_N(:1M03>L5SM#>DN("0(````!````1PA +M``$`E:99YWUA:SVW.P_D.B/F$SFAK#G%R0DS4QGR]D?*K?#FGY!2IR051"O< +ME=UT(Y-H7M](TG&ZF7HX8V=)HA^()RX<`BOSM6=TN[':XSQIX.W+`R_K`J`8 +M;RR/2N?Y,2OW*POKW56B=FO0Z+82>$<'`OX1*IVC(Y!_4E4399/U'=\;E>NX +MA:#WTMR7D,)D21^=JXRJ\WOUC>\>TL_I9B4;(&(_::J["##_)N-==#"C<;`= +ME8M5[:?FW]FYOS) +M&_,NA*G(,4>,LFFXYR[6+O&!.N5;W'\&A+]!0I:H&HGK`K;M'#S*H1J-67G; +MI5@NOF0&92XUP3_N$PXHI?$+6;3++NM)`]\'_&%EXN*B(F_MUF!D1$-(>8NI +M_2E96J,5[*GN6D=F'ZTJZ5((-4N9KJGS@^@LSSEL*\6X];<9'/MRC-!"CR;] +M;:L\%^`'&5BWZW%<";N:R89=$LEM:5.):$N&?_CP=X@NP^^>@PL^RWB,7*?Q +M^G3[Q6)S=ZX"3)@OV%#I=!*W1OWN#@#L````[`````(```!%``#H6_\``$`1 +M``#`J`$!P*@!`@'T`?0`U`:Y.?O="O^XAI&U!-ZQ7.T-Z2X@)"`````$```` +MS"$``+`+"C?X"#0,6&%H-CK&JON^:GW06.SU_J80\@'LR??S!-S$2T@(GZ-F +M5XN$N4C^Q]A?BU(<%A:9)O3,N:X6 +MN=VGJU%OS"U!9O6P$!GSU/6?YZ,9,!U6XJY<(\!`-F+]=W\/`1+;.U$>9X7Y]U=!*W +M1E$1#P#L````[`````(```!%``#H7````$`1``#`J`$!P*@!`@'T`?0`U`:Y +M.?O="O^XAI&U!-ZQ7.T-Z2X@)"`````%````S"$``+#TN0YS,926)REHKJB8 +M1=.?3S3+[U^FMZZTXD,-LRK9M,!&5WS%Z&1>56!EVT%8EAD>77&`AZ0;\I`F-<;>U/^VL:AVQ3WPZ +M8OX<]T&$W'Q1C!1`P0$>[\6>EBO543X*`:J*%X`)MQ(I+0R?YT)O&GJ2@TM] +M-@]HB*>4Q4SIB>AVYW9\U!C(LQNA5`Z39$$#J^ZHK1AQM8^06GPAB@)Y=3=O +M?/Y1L7)_ +MNB,ZP4$HX?DET@]NOK]8C)H_MIP:LE[KEC<9M&":RQCZ<3E-`=AS+8LOEULKL\`L*EL4S.W?NB\TA6NW.CJ +M9"F&+M"U7F(Y1TP/@IDK?*!LWQ[\;^MZ[D#G2DL]_#E9OJH]K>+S$L'>[AC* +M+/9$\5R2ONA6RWWG%UBK2!:(>1!EO%:H`;<9YW;[+3:7%ZH10MI%9[5K9#C?JJQ8PESY\R; +M5_G\:F6[4A+R5,8FKE777F]"AV,JI-@HF7]U$K=&:@<``.P```#L`````@`` +M`$4``.A<`P``0!$``,"H`0'`J`$"`?0!]`#4!KDY^]T*_[B&D;4$WK%<[0WI +M+B`D(`````8```#,(0``L)T)[$4NJ_E4>YT_0Z&L/S:[V46O>MYRQ>31X'?_ +MF_Z3E#$1,3_7$'?3BJ/@;\GO'APA8(BE)2&7`)F"S*4,>-WI%=F-SVI"FVQE +M`*JX%0)D/Y*,SH+E*5G=XL-MQ0WO.MBM!'U]>LNLR'B^,N>=1X2!@))SC2$4N*-3PT>ZE +MB.4#0)(W`N9:0`&"1UFC@7\!,$[_PRV4\@:3N2N$^19\^\L%8CPZZUFE0W11 +M=HYN_.WL;Z)F=?Y>BT2:"MCK/$X)OO1TBQ\<',79BP6Y*E8W+:6W3<$"ZDCW:_>4?5%EB.*,TU)D[WX98#P$UU$K=&[T\``(P! +M``",`0```@```$4``8AEC;TU5Q#"KGG]]!9B&1 +MH2P?P]E:K5Y`1]75](]K'MXV:PK_%XQ+X^&SC3L3_7W;ELZTX9EYYXZ*7M*H +M;%>_.70Q2:]A"8PAE4-@X/%GRJB%P15PVSLITQOZD,:A[>6\8$#D:#9O*)NTC5B:PPW65'UD0Y(E+9ER"+P\6A?_;6&6\0+):VHFVC07ET;D=L=<']VJRX# +MV#.GX%,=8#`GQC0%YN]'*[MFD3Z9AF5[/,GYP_![[2;[A./6HG0Z#,#%ZJAX +M[IFBW]CX:LS1G?V`'OU1V,G2?PA@#:VVA7!(',Z"(:P%*A^Q[G,?NY_].[OI +M)742MT9)JP``?````'P````"````10``>%P'``!`$0``P*@!`<"H`0(!]`'T +M`&0&275O]QB#F/053.$%I7!STF4N("4(`````````%PJ``!`0V:-WD!%;-@\ +M.,/_MQN8A<;/$!(/_8P*((SV;U-%*K_+'75#R4=2G?5@+'AF(NDYLA:B?WY] +MOT;&F=/4=1*W1MNV``!L````;`````(```!%``!H7`@``$`1``#`J`$!P*@! +M`@'T`?0`5`8Y=6_W&(.8]!5,X06E<'/292X@)2``````````3````#!=)FM5 +M'@$3T9M,-$1I)/HXX07B0<2T>8)2D*RWTBB`8S67U5"(``'@``0!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``K;KV +MN.75LI%Z@_O7BGP@#G?XA<%&)2[AK=:$MQ67WCO2WY:)V!4,1Y5U.)D7I1`^ +MB1!]EVSRZPNMKY!&989U+C0[13KGT;HIA8!"RI'7UVD&]B16;?8<>S;[&,]1 +M7+/%R604U1OVZ1>T_EI&@#16D@U*.*;AO8B9=S+?YGX@:8?&"I=Q.C$I```<``!`!(S6JI7O1Y;7^_J; +M?0Y')^,_ +MN\0W```````````I("(@`````````#P````@``!`!@````9RN=UJLOECS"`^ +M=%`L(:%#W@_N\0W```````````I("((`````````9@A```@ +M``!`!@````9RN=UJLOECS"`^=%`L(:%#W@S;[&,]17+/%R604U1OVZ1>T_EI&@#16D@U* +M.*;AO8B9=S+?YGX@:8?& +M"I=Q.C$I```<``!`!(S6JI7O1Y;7^_J;?0Y')^,_N\0W77(1RHORL"HA("(@```````` +M`3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"```` +M"`0```(H``"(``(``$#;(])3TGD%K5IJO9>1CU850QS5BL\ +M;-9\-#"^GN%#!(\P4XW\^IP3G])O>5>_.\.B:X'!%>M*,/2A\WJ +M66KC+]M,?=P"()FT.TWRE:%Z[WAHCW42MT9*60(`O````+P````"````10`` +MN%P0``!`$0``P*@!`<"H`0(!]`'T`*0&B3SJ[]>_N\0W77(1RHORL"HN(",@ +M`````0```)PD``"`G"H]>P)Q-K`9/07FUW@:8N[&[X26R9_N\0W77(1RHORL"HN("0(`````@```/PA``#@K[5.#)R_\:TS +M]<^CQ,7U%UN4C8^`ME.8AR2\0JWJJP`9I2$LH<#0N4FB]5J(E5#FTBTH_[+I +M\,F:O>(.O(N?L,:+TL:@F?"A`4\<_R_D_)(0_Q4[,3Z(R%,,6SGJ8.X +M?+JOK8=;185AFRG:><0-0(A:,AK7)LLV;'&-PR8SA\82HOX!<6FYOT@32%N= +MQ4=V^7\"(14H;IO9N@GB)*>M9/AUQ0VXG(U_N\0W77(1 +MRHORL"HN("0(`````P```-PA``#`SR<#Q63XT(16(N&Q8OI;(VJ+K9>2OSA< +M[NL?9]HY:.-@1*1+N3L-I$;(B?0-(15)^>&Q_#=!*0@GPC'/;R,W,8BN$_.A7C0)]#B&)F( +M$>NV6QK]/W42MT98Q0(`/`$``#P!```"````10`!.%P5``!`$0``P*@!`<"H +M`0(!]`'T`20'"3SJ[]>_N\0W77(1RHORL"HN("0(````!````1PA``$`ZGV] +M(CH[L)UNV175GG'9[!&1??%H)X,Q+I$HO2#HJ=*$>^-1#7+`4;[]#!N;BNK? +MK;)F+_NIZR6U+5BU57E$F^FK3B4R$GG5Z[X"AT(KSC2)YF3+L^.-15!1M\1+ +MPA6#J9";C#]@7$PTI:>^U=(\@H^!2*/N(8`\N=Y-G*9S/+@1KA'ERY\&6JWD +M'YIA2;@="PTL$*9%]F[3JK:MZ4%K'TXM4C#0O@_7C>?)I2LKUU5=<9^52JN8 +M3CKSA!ZR0]V^)1YSC",U.J*(CJVS>^J3*T?ER'V.A;V7O,YU?341V`'(\=]= +M>?/J@K+D9!13O-#&"NLIC^J^S?B.`H3N=1*W1@/1`@`<`0``'`$```(```!% +M``$87!8``$`1``#`J`$!P*@!`@'T`?0!!`?I/.KOU[^[Q#==F0HX&^ODIB'*O(IAPNIP%=84'BGXWC7Z0U"JTXU/L`&OPJ1KK] +M7)6=2IQ.2Q+8-S=\H:X\U>79P&!_%880G@$+,]-=71R\;[9_J;."U,89>W^O +M]Y#_$YV@DTDX&2F\*U"AV=LPLGD8F?O5I2U-[>R)$Z;*P%4F]1GQP/2OZ1'L +M^&/_85QJ`\G!=1*W1IW@`@#L````[`````(```!%``#H7!<``$`1``#`J`$! +MP*@!`@'T`?0`U`:Y/.KOU[^[Q#===5H_<^LCI-28/2YPEW`M/]H[-*8=\9L3*>QL=*X1O1N#7VDF&* +ML9,6470IF@]=4%(0NEMK_9E[2"K-8<##?%,\V:O?Q+UB?)S1R;26-?_H5BPY&]3-NI +M4@>7P>I!$I#]JF(89G[(C+>0"2AWWC`YW:+\9A^CZ>)T"DGG)(&P^2-:]^:$82EO$"2S,X9P%1YZ?,TM0:E905`OKAT;*R3OYMS?W4 +M7FMIY"0+>TFRIC07@F>Z8&2EX??%568:ME)8:'/SP'+9D$6[>O$!`7HI;:6C +M\WH.MEJD:*A9/FO=E5&!D#AXGN]%V,6:8_$#-JOR`PGD:@\L*7U/ZTI.C&0X%,@L\PEAWN7X.*+QU$K=&E2L#`!P! +M```<`0```@```$4``1A<&@``0!$``,"H`0'`J`$"`?0!]`$$!^D\ZN_7O[O$ +M-UUR$6GMRIB#/'8<5G;<8^B;!F1W +M8[(1I14IUB92;AO11?5'KWT-=6A^/F>I(2KW6,@(0.<\=QO72#U(ZQE[4&:# +MI%M6HU_]#SYRHMG%,[0:L6:0?X!U$K=&&3L#`.P```#L`````@```$4``.A< +M&P``0!$``,"H`0'`J`$"`?0!]`#4!KD\ZN_7O[O$-UUR$0E;%XAFZ(&+,9;:P,56H^YC9\[Y>NK4QZ%I +M8.?RB6&J8B=O@ZOZJ,+Y'4.&,C&Y?PT@M=#M9LD+'"';?8ZD)L^?):N0FBA= +MBOH5:R2M*5J\CRV?*#XY\\5X?R1,#@N17/\\AN>T1G-$7\;PO>G]];JW)9X7.6:8A46EQS +M6)J(3`5BO['HK!^04:OO614T:J"HO2= +MWKRJM$TS5F.&;OD.:M3BC'_H81MSZ'[R`JGG[ZVU5!5(MY[EO^CPBD@;YQG> +M@>/WHR-9EX!]_N:F4Q[B/*ORV#*_4;TXI!@DD))U$K=&<(,#`(P!``",`0`` +M`@```$4``8A<'0``0!$``,"H`0'`J`$"`?0!]`%T!UD\ZN_7O[O$-UUR$(I1AX=6E9D!?1384[=,U*<&/A*[ +M(G4"$$49OUJF".1_#//\6B55?Q&NF_%:_%Q]EP1^@**JRZ71P[U82%4L]OB" +M48FJ]_2/N44.0='(\`KM:KVYB3N1POO>%&2FB+SZ'5"QH1TH]K"72 +MQIV(Y8`1?DQA.7X]<2H079KT0\6!V+28XJ&RP%^)5\\D>!?T]U;<3FQ&44/? +ML0"9%Z#.K/&-:!U/M1+%X8R9WRBEGR1A\624Q0=ER9.J(>!D=1*W1EVX`P!< +M`0``7`$```(```!%``%87!X``$`1``#`J`$!P*@!`@'T`?0!1`'V:[N!L\O'N@93)T#"V:*4TC"Y(/`IC3 +MP"$8I/LRYGMXX`2QRNK9T4Q4;6IU%U#JV*&I.F+5'"RNOC$#!!.;YAM"W__$EP]@]/+3*(I +M35V*Y292N$Q\10<,\+E[2BTA1;P*QE3;^',K$"D'3.:ABW\_58AFL<]^9)N$ +M0Q-KV"T.1;:1$%P?``!`$0``P*@!`<"H`0(!]`'T`&0&23=G +MJ`.Y*JUDC(1J4,N("4(`````````%PJ``!`F9WJ.QCQ.*JRU^0K%,)- +MOPK$HJ\:3-_1;%QL?%O3-14S=];13#7Q>MH3^,!U1NI_0X@?YAI1"\CI5B/# +M=1*W1@CQ`P!L````;`````(```!%``!H7"```$`1``#`J`$!P*@!`@'T`?0` +M5`8Y-V>H`[ERG6EXJK62,A&I0RX@)2``````````3````#!";)@[_872BH%_ +M*<6%X9BTA$[L-2R-,]RP?:HK.,J-;,4K02IW7HR"?\;17'42MT:+_P,`;``` +M`&P````"````10``:%PA``!`$0``P*@!`<"H`0(!]`'T`%0&.3=GJ`.Y*JUDC(1J4,N("4(`````0```$PJ```P?81=5&AD8;2)`"[#E14WCH;Z"SVETNR8@"(` +M`'@``@!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``\3K4+MZHHCGD*SLLX#VMZHHCGD*SLLX#VWCL^(F7;N"AX0^U%QNU\M5O`AEE0H&X$! +MF`P@01G<\B>'E:=0$1U,0[Z79\&_H9!UN*W#Y"GITVKXZR+P)^(!%\AJ<*0``'```0`2@ +M)YBG?H,3D"XYGDC`'UX+*G[420```!P``$`%1ZZ-;0$_WVA"^&H"LC4=UKE(="+B`C"`````$```#L(P``T'"+XWC;_7E) +M7B2@/$Z7U<.Y0$54Z05D25B:-:`\)KG*T"T&'"%FU7'YYK[6*8,9O,?FP3[^ +M:KY)MVV0N!F6&WL,S+!QF"ED[)#U2:ZP0C\"5%UR;@,(_R"AV)3#`*L-('6+ +MM$\]#3)"!<&IUVK]WKYY-LD'+Z>NXA-G<+OY$"M!2H/M:_5%$T#B5S +MC9[<)%_C$.0\[VB_SDHPK7+/03HY$CK%&H*@4:I8W`_6--NTL]'^U<>>'YE9 +MW5M9O^]R^6[_DEYY#H3"8OO2$.BZU\=9)8YK]R;;WRB]7O?[91-(;W42MT8Z +MK@4`'`$``!P!```"````10`!&%PI``!`$0``P*@!`<"H`0(!]`'T`00'Z595 +M[?:$+X:@*R-1W6N4AT(N("0(`````@```/PA``#@X%C&X^[WSH5<4FIK7)5W +MLW\\T&!XG.`'T&D\Q_M7(L-;EJ3.#S1V0,:WV9=RHR$X/^ +MI$>;T5Y(Z(>%#>92D4PST4R]Z"6@I^QCB;WOA85.B5_UOV#.'SJ37`ODYQX; +M0R`1B?0+,O(Z]+0K;=V%Y+;8/]H<3S%U+^/EC?8[=E1QP]S[\&NU2,E84RZ0 +M](\+(@/OX[J-=!?&^N-/_UWP,CDRBLDZ##Y>>?/OW+CIC_\"0?7`%E%A#/P4 +M41?Q)?8FF>V&!3C\IT7',S]2J+5VQI4@X742MT9[N04`_````/P````"```` +M10``^%PJ``!`$0``P*@!`<"H`0(!]`'T`.0&R595[?:$+X:@*R-1W6N4AT(N +M("0(`````P```-PA``#`?CDIY^^)"&.,2WY(X$%=R)L>DZO%K($3./=GB4/J +M3X;SDMBFO)3.(!L^I^9*_ST70/RS0%'/C'TT]P0G/NM]V-Q0Q[L:!&3%N\_] +MGL+V/H8MZ6?Z>E%G,\\F(JLD,T`:VX5'6,"E(MG=NQPZQZ/_M\EE2>/>T9S+ +M6B`ZCKQ`EQELZ%$UJ[CY(7>7R37.*)FI0XOWL0EY:0^M.ZL_^+[0Y3V=)B0C +M!G0"9,2PC;Q6[[>KO??(XGXP@D&]25IU$K=&.L0%`&P```!L`````@```$4` +M`&A<*P``0!$``,"H`0'`J`$"`?0!]`!4!CE65>WVA"^&H"LC4=UKE(="+B`D +M(`````(```!,*0``,!$H\?:^`YIG\+$7=(V\>,,-G0$L"+D#W5=6@Y9"H;)E +M7+-/.-+(@^(-PES:=1*W1B/5!0!L````;`````(```!%``!H7"P``$`1``#` +MJ`$!P*@!`@'T`?0`5`8Y5E7M]H0OAJ`K(U'=:Y2'0BX@)"`````#````3"D` +M`##CP>"DCW,,0LWET%@%!\>2)/3 +MFG42MT:/^P4`/`$``#P!```"````10`!.%PM``!`$0``P*@!`<"H`0(!]`'T +M`20'"595[?:$+X:@*R-1W6N4AT(N("0(````!````1PA``$`;^Y8%(!K@.NLQE2^6, +MADL=PNUZ^E;>@9DH(KKSVDW#*IZ4U/)I8"):NC@F.V$\+G;603I8C'5L%*3[ +M`(:P3=[!693DR=1Y[DW)Z3AG$ +M2;1??UR!-%`DN8=7B%%Q!*A#O7>L(U[GC`=H%*L',Z8$5M$C'^ +M0'*VPC"X1CYNKVF&7('9.MF@"4+P-M,>-HJV<=O83`9H(5812H%2AY=))@4= +M^CIW'UOST9&W'4]G/&1-'M_B=1*W1G,+!@`<`0``'`$```(```!%``$87"X` +M`$`1``#`J`$!P*@!`@'T`?0!!`?I5E7M]H0OAJ`K(U'=:Y2'0BX@)`@````% +M````_"$``."E$QGM;=G-\N-R7ROYE%)6;>7:K8=1Z5SCH=I4L'&\A[`R,K&? +M"\Y'ZO%;XFJ%<@42R9&^^NF!;H=C*(?O69)F1%>^F<[^!0O=+C17/BJ%RFB. +MD_,_/AA;$*<1`8!'YW*K$9'Z3=J1\+,2FC:;1$CLOO:^1`>3U@-Y!14N".%A +M/T68X*"H[6^*UR7Z()O7'P4L-Z+?@*KT0`4M_GS"=#/=!`$\"+"V[-O5P^Q( +MAQ3KI&WE^?[SBI3\65$X:T2J$UO5TZ.UAMMC8SVF&E`P(W.^6;+N-V/\P$4] +M`I`)=1*W1NX6!@#L````[`````(```!%``#H7"\``$`1``#`J`$!P*@!`@'T +M`?0`U`:Y5E7M]H0OAJ`K(U'=:Y2'0BX@)"`````$````S"$``+!Y,"Z]/9HV +M@#]"I0(!)'6@@^;?V-5*(M58@5'B"\SQ5BH"2?ZMC.])Y%W6JKWI;-D[?_0YZII[HW@(0>@AV +MW9)9#4+_.LU?0X.:[K`:MA.-\M95)%W6-1X^,2B@&\>._DD3UR_Z!?-%EL+& +MRYA?S./_C%@_H$!%=1*W1JE5!@`\`0``/`$```(```!%``$X7#$``$`1``#` +MJ`$!P*@!`@'T`?0!)`<)5E7M]H0OAJ`K(U'=:Y2'0BX@)`@````&```!'"$` +M`0#T::$EAQ`+=-8IC]>.X+3T(>5)WDU\JK22PUY[LGFXQ`M1`3!=?]:=':-B +ML^5<_@+LY:Q%-@VGYINC#!D#'*-N"E*`87^43,,ZY!?BV:J!1C7*OZ5`7F0< +MRK!0C1DT4+!J`M9VH-:?#AS/W4DD:+6+WT/_._*>=7=CI;]+1.WXFV=FJ'N3 +M'+%PFM*JP+MG!D']TM*G)+@2&Q_7F-43B<04'ZCMF'?;.=SI>,(,&%G%[M"M +M5L6GMON)P8=#$!/$U6:6\7GU3(>HO9U$K=&8F(&`!P!```<`0`` +M`@```$4``1A<,@``0!$``,"H`0'`J`$"`?0!]`$$!^E65>WVA"^&H"LC4=UK +ME(="+B`D"`````<```#\(0``X"Y9N@!HV__<\5\SP3I)HA@A,#6K&@]SJDN# +M1()_U5PIR_;T,D#X.>Y,VUP*S"5T1R\YE.)`W34*VGDAN"^$?>TPEIP]*QAV +M)UNVJ=*,J@VCO(3C_YPL6!5!GK,6E[D6*!M$`4^1_7[^?M-A'8V&M=U41JZZH7R>DA8XVDJ!L,N>&]SF` +MW-KI@8[S=4H=Z",HPWK^LN^<^390,F!HA]EF$!(O0SV4?ANPX9,M@BXF+ERI +MD0IV"(\WRL"P!?U!@IAU$K=&EW$&`.P```#L`````@```$4``.A<,P``0!$` +M`,"H`0'`J`$"`?0!]`#4!KE65>WVA"^&H"LC4=UKE(="+B`D(`````8```#, +M(0``L!R37A_B,_A76YC&,50C26'BY^R20`GA:^H^L#P'+%"Q'_?'YB\>XI&D +MT_]H\`2P2SVKBB$A^`3;;\#)1@T_I7@LWWQ]H5TK`'"_+^W'2$4VJWYH#?,Y +M3N);^:1R#[H_%#RCLM^O^OO=0/W#R&-A2*WHY6#&[?BVD7*$,XRFQFB<7]=D +M>4M#,(8,+\72K\X4I6DQX!O$TM=9MIU09\!\489R0SC)$H:3>S3,)[9U$K=& +M490&`.P```#L`````@```$4``.A<-```0!$``,"H`0'`J`$"`?0!]`#4!KE6 +M5>WVA"^&H"LC4=UKE(="+B`D(`````<```#,(0``L&3X!V#O*"BT]'SY3W8] +MWT*-D'KU-8+W_N$4_-ENWD%Q"K"O5>)"71RU8UDMAO0Y_X7$WVA"^&H"LC4=UKE(="+B`D +M"`````@```%L(0`!4)F,=?9@$G0P8R0%/1DD^]>LBW.S3Q?BH'KDY +M;R?U8#<]97I-D/[QGRVS.-;2H@3RH^(TR'@$LV.HJ$ +MD;B#`#I&M#SH:_A&J[?H#^=GP/I&QQ>$3P%=O_L&^=^=7]^'^ME[HP2[.@UH +M&E-3'B+Q=R5<7Q)152EHJY)<'S\V/$!!_44M_ARG1HV(?]U)8+W?_FH&IG*O=1*W1@;Q!@!<`0``7`$` +M``(```!%``%87#8``$`1``#`J`$!P*@!`@'T`?0!1`(\4F_V-D(4K(7I)QVTVI3?`C:TC,0:).[:R +M@FZ4^;O#0PEGUMI2(MWA +MFI3J(H(Y0!Q6]&1800T)&919\]`D+(";8R].@)VTEOAIF*CE=#VTKV!==W$D +M4+/A^48I4V=+VRF6[_3%-J!Q$LD9(9K-TMJ8IEI81/@L[XM$O;ZIB#%=>WB:FRK +M*<5/JL[L&XBK*"ZFDO):FV%?5",8!>KY,VJJ(_5-M)TUTW42MT8&&`<`?``` +M`'P````"````10``>%PW``!`$0``P*@!`<"H`0(!]`'T`&0&26LSUH@PW+T! +MA/BD?"_$:NXN("4(`````````%PJ``!`\CNQ`))2(QH*IT)'>5@!+LVO>M9" +M"T`^#1*NR:YPBBPE'ZUDS)0XOGV6&DD2)0O6K8Z$25`,A^[!3BV\=1*W1K@D +M!P!L````;`````(```!%``!H7#@``$`1``#`J`$!P*@!`@'T`?0`5`8Y:S/6 +MB##1*B<`=LU78C%%P7D^;V2HE,:E]9K8Y\9'42MT8_,P<`;````&P````" +M````10``:%PY``!`$0``P*@!`<"H`0(!]`'T`%0&.6LSUH@PW+T!A/BD?"_$ +M:NXN("4(`````0```$PJ```P&EA>$$"F,+C2J^44TK)07;V`0%DJS2K$7L(9 +MWZ?_UU%73@MKK&OJJQ/Q@WQU$K=&_T`'`&P```!L`````@```$4``&A<.@`` +M0!$``,"H`0'`J`$"`?0!]`!4!CEK,]:(,-R]`83XI'POQ&KN+B`E(`````$` +M``!,````,-X!U<"9:ZO^B+R/&3*G\8GQIB`^:0T"(``'@``P!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``\_+?PSXK/;/(+;;1]+`^ +M)%T)LMS[V?(,'?`9RF@"(=+@&@Z^R6$'R;!U55K-&C\'V?Z#8 +M<5:VL"9=Q[R9`8.*J_$I```<``!`!,!9M=`1"P$'17V[/0@!D$.!N9$5```` +M'```0`4HY*K#;N3HJ!WCJ5:XPMPB"8VQ^742MT9G3`@`7````%P````"```` +M10``6%P\``!`$0``P*@!`<"H`0(!]`'T`$0&*?@#%5K^H7RS```````````I +M("(@`````````#P````@``!`!@````:PE5EC@B$AJ+WPN";]WB;?^+*7;'42 +MMT8H7`@`N`$``+@!```"````10`!M%P]``!`$0``P*@!`<"H`0(!]`'T`:`' +MA?@#%5K^H7RS```````````I("((`````````9@A```@``!`!@````:PE5EC +M@B$AJ+WPN";]WB;?^+*7;"(``'@```!T`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``\_+?PSXK/;/(+;;1]+`^)%T)LMS[V?(,'?`9RF@"(=+@&@Z^ +MR6$'R;!U55K-&C\'V?Z#8<5:VL"9=Q[R9`8.*J_$I```<``!` +M!,!9M=`1"P$'17V[/0@!D$.!N9$5````'```0`4HY*K#;N3HJ!WCJ5:XPMPB +M"8VQ^742MT;X@`@`4`$``%`!```"````10`!3%P^``!`$0``P*@!`<"H`0(! +M]`'T`3@''?@#%5K^H7RS^?P>9ON(-#LA("(@`````````3`B```P````+`$! +M``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(` +M`,72W=.'XC8^,)(XQ*MFDLE?&[E-1`7C>1R!4<^Q@9G"`VL4F:'<(VG@%QW. +MP'O\%A>;.%/78KBHW#^3-&A@B676_`QOVF@=MXPSD[#BD>@0XC"Q_9RLM8*8 +MRL3>PITE+R\"QLLBX_%M][,D)O,:?%P<,'AY_=VL5S2DZ)Y/[T""*0``)-=^ +M]D2TA45B5)P3H[;P)4:].*0``'```0`31.BRD>.VD +M#V$HO?#<\V&"A"UKA=W2N3H](;N*2_H??'>-WU%"X215H-+J)TWJV4/];O7 +MO--`0XEAMDSFVH(]OPQSIW-[RSD\E"U<,;`<;;'^7V[(DXF=RY:NEH]6'EU3 +MT6_8N:+05_*;S!93B[&Z;]R`"I:04RD\L*ZP#R=.E45^(G3:V'0?`T:0"1:$ +M!-;$B+Z;]3403742MT;;Q@@`O````+P````"````10``N%Q```!`$0``P*@! +M`<"H`0(!]`'T`*0&B?@#%5K^H7RS^?P>9ON(-#LN(",@`````0```)PD``"` +M?5BXP<2Z<(TY/_HW$:5=M0FN+Z^#P+[1@@:;%KHF-2S#W0[=&_UN0$)%N +M<52*Q"W$+\':;SAPM!V0N-H9NU]B-C16O_DKZ#56JC#7EW42MT9,Y@@`'`$` +M`!P!```"````10`!&%Q!``!`$0``P*@!`<"H`0(!]`'T`00'Z?@#%5K^H7RS +M^?P>9ON(-#LN("0(`````@```/PA``#@9KS%8GSDJ&QBNYO(YATU_JDY82,'M52,O+)"`12GYDKL[-RK7,@&`R!=KS53R&UV6;31>> +M46*QZ&VHJ2\V*^;,'PYRG@<<`OQ%`N82N$\(:1`")1K6)-9UB^&S1(7+Q,5SUC:---,C/E7F/E`=/6NZ[;5"2<-]TE#38^0,(, +M565%]5A`P#G@.`;%JV!K*B-I5$!&92H7S%@?SL20V\RN-0N)ONK(DQ5<*^B% +M+<>GT4N#X3).*1B^IA-%T9ON(-#LN("0(```` +M`P```-PA``#`<"A4ZFC456FN)8]8OYGC;U<7<8 +M,"B"%XEGIJ^@'[>\8L'2I+CSI&EX$^Q!GBTZS*X"J?9G_>]VC/U[6+ENB0D8 +M3/3M_<2]L,-EC)T?HB!_/MYU$K=&)/P(`&P```!L`````@```$4``&A<0P`` +M0!$``,"H`0'`J`$"`?0!]`!4!CGX`Q5:_J%\L_G\'F;[B#0[+B`D(`````(` +M``!,*0``,!-E40'[R$Z29\.L2&'80!M6>44A$LL.@S$V\M9-5R+XC7;ZQ?O! +MA1LQ+QV-=1*W1F,7"0!L````;`````(```!%``!H7$0``$`1``#`J`$!P*@! +M`@'T`?0`5`8Y^`,56OZA?+/Y_!YF^X@T.RX@)"`````#````3"D``##2`'[< +M:^!=67<;AX^=#I'U7_A9&N5+B(8//VF2@&.LL-+F=_W@K/VH:$^-*W42MT81 +M,@D`/`$``#P!```"````10`!.%Q%``!`$0``P*@!`<"H`0(!]`'T`20'"?@# +M%5K^H7RS^?P>9ON(-#LN("0(````!````1PA``$`)KUYI3G1L*XP?E9>V^7\\W(`V#=+8*&D3J9FRE].%2$$OG8`C#!PI)*7D/K? +M(H:HP"$PZY0_*]0"90#S-<>2#\>`2K&1K$;0&N\W]ZE[350@=ZLOYAX$C16# +M^"KMDW1P1!J;<.+/';H`]\\->8;$J);%YO0W2R-]I=?-F3N!>1`%E6FJP?VA +M.EE[;!E\X#2:@HHVRD8'].5,?X7D,H-!(@WQO#UINNCSE%/BG7>'SNDZ)- +MH_^@N,`F+IUY\I"30=63K]&+&)1/&_(L/:ZUJ0[V#D7G^[V'6U5210P#[\E= +M0PFQ2ESC[/$ZP13UP1:QT3%8MMO:K:#J?7>-<^Y +MI1>>R8/R"/UG%(W7'R@"4C;9]]]H)W<'JU-;`965T!7&0^A8`:`*@/&[L[TT +MN!?*_Z]_>Q,P_W8[M4.;U^+DPOL6$S=9BDOK&;Z'B38U4YK7_.3M:&Y7=1*W +M1EI."0#L````[`````(```!%``#H7$<``$`1``#`J`$!P*@!`@'T`?0`U`:Y +M^`,56OZA?+/Y_!YF^X@T.RX@)"`````$````S"$``+`E'0KG%5B3P"]0YLHP +ME[1.Z4.`CF)3/N-^E,83YG0O4.8IOMWJ+-%M4^^5`9AK4(-N48(9_/>KT]E:[IUE]"+.G,AZ/7@8V/J,Y8WT +MY*U,<663R*"\_]\J]BGL-.`J,/M19I_+?FK])"M(:2AOQ3V+ZQ(Z>#`CS +M+<(6>)`<4A.''M?I$4CD3#^(B(,^2;Y%/I1BWXRX7>_XZ6#,)!OK)-]*=^YV +M%Q63V?_*:LF:F>G&DD&=,*A.K"AKP0@TR.7E9;]5<7P)=AT+2_F/9'.#DGN, +MGQQT%W(]^ZCYWO?"1&S5HPIP1"ZW<#$H5F68FU?C^5O%W1(J%*1@W5FR;:3 +M:62Z^R3T+\NH!'7X6>YH3O:2SQ9%2^W.RZ4FS/!I=MXTM^0_N92LV,MV/WC1 +M/11DH\[JF9E$680'Q43K&/73?P$?97^?'E\ONQ\#%C^0LA;O]H`\F3QL*X?Y +M53_BD3:]#5Q\-_2%@GT41PS[X%.AKU!?'RIUH3A3^)+A):, +M&[U2HF)+^(F)N#`^-\SEZD"L2QKV_E*8(7+5VS@H^>L.>8Q0$(J@\`8):'H6 +MG.BEEWXP%M3MD"O=[=>F%9U&.."A.;QU$K=&6YH)`!P!```<`0```@```$4` +M`1A<2@``0!$``,"H`0'`J`$"`?0!]`$$!^GX`Q5:_J%\L_G\'F;[B#0[+B`D +M"`````<```#\(0``X/@(UM2`RU=+$Z(!WU^$9U1)-5@G3=F+7_1,GI,@S/-F +M[N1#DFVF#.@9HWMBE'V+/W,G8>)I+5AHHT0B!A9]O45W#V@A>FG?3C!X*(K` +M?L_W/E(G\Z2X]SY1)/[]%SV1;6L%P%AYBIWW[]W1%EHY.]Q2F154+;\0AUZ' +M=N"?V)@<8+ZFNE,&G\F#P0&*X,@@U4,TXA0:&R[LF)V:DR:"K\\CKB%JU#5< +MWER$.:Y@4O!-="Z1'HE,"YL'H$W9NWH,4KM"B,*_\ITB:U2(AJ.4?=P=>K;O +M#@41&<,:@B=U$K=&+ZH)`.P```#L`````@```$4``.A<2P``0!$``,"H`0'` +MJ`$"`?0!]`#4!KGX`Q5:_J%\L_G\'F;[B#0[+B`D(`````8```#,(0``L*\A +MHOL_Z7N+RY(/LU"\WI.30,R63=;\*Z.B7UH@6-<&PYHXWTV!Y'>O%X8T.(SJ +MX70Y_UFLGH(#[@KT=931BR%T)P\$`4ZOF=/[H0U;$^AO%'*VJNO8.[,(7-N2 +M9_<<]]&I2KJF\#GU37[(2XYQ^M(W*7DPM-1D:A9'].OMQ"HY2;X$L,Q[&J2K +M;B[IMO%C\VH_<)#K>'LWAE?+$U[BI8_5+*)Q0LP)`.P` +M``#L`````@```$4``.A<3```0!$``,"H`0'`J`$"`?0!]`#4!KGX`Q5:_J%\ +ML_G\'F;[B#0[+B`D(`````<```#,(0``L'EKF17GF"!ZE3%)V^_'SDI:WC*N +M](G,@9)ZNHW3'IA;A6(I4$O+ZN)7$%?!R;6B-SRR\%60%3L?E)YGZ9RB,Y(3%,*YR\A_>T"B'$2M^6*80$6/XRV-9NX=&Z^+EYXD[B%?9&[L:NH^X\K^7P`W-;4KMK(Z/9NDR[] +M.UV'LV-7PJYFA[M8N&R=9);QX9['*&)G?:&^.^IJ,8)7A^O0Q/AG]LAGR=P$ +MKVLVSN0X/->9;?53QJ%?TS/_:ZM"$>&]]6T@0`W[Z;G=_J\6=I@L=3]-H`%K +MV;R54?)*!"L3RY!XC'0_8ZX5\X_!L)<#;-!#(IJ\R=3U%SGW!TIMSC:FVN>( +M:>ZF]QN]((%I5'UW&?X\<HM.=AU2KNN\:-3C-V@3ZKG_N1T'*O?:G3%D? +MJS8D"UL0ETQA3@NL8[;E2E#>S06Z*K[%(4LX2>9*F;/U^_LR'JFIS&NGL]QF +M#]=PFR(`Y9:T0"'GH`-RK'[=96_IXK,7=1*W1HTH"@!<`0``7`$```(```!% +M``%87$\``$`1``#`J`$!P*@!`@'T`?0!1`$TE"H\\=3T5R/L'-LH>#=<+Z`74$Q3W1',D+`$UT&F*O_00 +M8Z#)$ZXQ`;H]HO\,XS7WI?.AG3,)$=U)PIT<0K,S_JU2D4[.$4^0P!=JR*'HE4DSQPU*\D+'1%Q0``!`$0``P*@!`<"H`0(!]`'T`&0&298T]90"`@)E8D:.!2>C,G>#'.+5<0+67+B;-@ +MHY@HU\#;1BD156*@5_9X>YI>/>JR'T`?JQV[4;!$V[AH=1*W1O];"@!L```` +M;`````(```!%``!H7%$``$`1``#`J`$!P*@!`@'T`?0`5`8YEC3UE`("`F5A +MRC3K:OQ#ORX@)2``````````3````##UU/\2)K5JKLS4H93>&B]!T_P+YSV: +MZ9-&;NTQTL#+8-)!S/T1>`&$+1;D]'42MT;/:@H`;````&P````"````10`` +M:%Q2``!`$0``P*@!`<"H`0(!]`'T`%0&.98T]90"`@)E8=+L&\B<=K91N`,L`S@\JI+K/)9UI98( +M&P)X_&](OSQ>UY)U$K=&3G@*`&P```!L`````@```$4``&A<4P``0!$``,"H +M`0'`J`$"`?0!]`!4!CF6-/64`@("96'*-.MJ_$._+B`E(`````$```!,```` +M,%V0$,FD=X:K,9F+*Z=H0``````````"$@(@@````````!>"(``'@`!`!T`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``\>W%FHU%*&'TYWTK0=3LF.89--$H +M_J=%722MG;<-[4^$J,@6,;(,&80M-O_:TD4T(H45K@&_0WOSH,I*]]_B"?H( +M,]CTZ]AO$+'08!JY-S(WBI,B!Y`D!%P;/QX8/AU8D@MAC1:SC+9R/PM^\1L, +MDD-"GN?]CLQ^H/(TS/^_30`I```D"G8E_O%-G-F6T2Z\?F>)2F&J%$:_L^YD +M44T$"%5.\H0\=+11-````'```0`5J +M*>.W7!RUP=W)YQZP98^3`2,^[742MT9$@PL`7````%P````"````10``6%Q5 +M``!`$0``P*@!`<"H`0(!]`'T`$0&*5[<7IBRNG:$```````````I("(@```` +M`````#P````@``!`!@````:RV_ZO,/"@06'X(IC_*9I!K=U3-W42MT8?DPL` +MN`$``+@!```"````10`!M%Q6``!`$0``P*@!`<"H`0(!]`'T`:`'A5[<7IBR +MNG:$```````````I("((`````````9@A```@``!`!@````:RV_ZO,/"@06'X +M(IC_*9I!K=U3-R(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``\>W%FHU%*&'TYWTK0=3LF.89--$H_J=%722MG;<-[4^$J,@6,;(,&80M +M-O_:TD4T(H45K@&_0WOSH,I*]]_B"?H(,]CTZ]AO$+'08!JY-S(WBI,B!Y`D +M!%P;/QX8/AU8D@MAC1:SC+9R/PM^\1L,DD-"GN?]CLQ^H/(TS/^_30`I```D +M"G8E_O%-G-F6T2Z\?F>)2F&J%$:_L^YD44T$"%5.\H0\=+11-````'```0`5J*>.W7!RUP=W)YQZP98^3`2,^[742 +MMT9"MPL`4`$``%`!```"````10`!3%Q7``!`$0``P*@!`<"H`0(!]`'T`3@' +M'5[<7IBRNG:$#+()7TY,8VTA("(@`````````3`B```P````+`$!``0#```, +M`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``&A&YBN! +M2<1T`VN^`A=<$)H,*LXF<14W6:7\X0SSC(0?H";Z9\:RJ[YQ$/\+!8N9_U'Y +M"GAY%'CS>6OUE=?[889YO%&*S1^/8S#@U7+1R:H:X5D.5N46-Z0DVK4PN2`+@INS,\Z1*JEZ;,T8`FC+!#RV5X1.,^296#W1(@9HT*0``)%,!(^=EFLA* +MO+HKFGUV7\P_:Y`.7\>8F8J\%7]KIN`U*0``'```0`3Y?Q\?#=XW>DVT#WX1 +MR+H:$R*<]0```!P``$`%D\=&3%:50=?&JY-(R\%^&`VSW%Z8LKIV +MA`RR"5].3&-M+B`C"`````$```#L(P``T+A1,.\K'3PLZ.4H2_L4[H<^VH@I +M^9W?@IEM!F(K_"I3;H4D<:7Z0RNA6_[U(V].EL@&9X5R4M)TU7/K1N>0);4( +M8OAV)LV;%.?;?^)5-=ALF(>F!@!E1F?14IP4\VD+"<.'XJ,ALB-=(:-_I6L5 +ML%(^'FB-M(4W)4VEQZ#[[744$&S_A5D>XQ2LEHA5ZC-2Q:>=]6>N7Z04.`R] +MA%E-.]P=5=X/L8@0W^#V,F9*%&/AAQ=V6;$:DV2'R9;@QG`+U=WY$@PC&+SQ +M9?J3SG42MT9^_@L`O````+P````"````10``N%Q9``!`$0``P*@!`<"H`0(! +M]`'T`*0&B5[<7IBRNG:$#+()7TY,8VTN(",@`````0```)PD``"`/#:#F:R" +M4=4'5\RY:XM[-P*7*B*K4K&_SGXR5L;TI$ABX$HBY@),P$D)`(]^LH&X^Z:E +M'B%KK*=I#O'D;+;.CE?))#E+'W!@,H5,Y0$>ME%R1+?9U#W._WF4(%IAC77[ +M^#.WNK:1TCE]12WC&>KD`LV'DP)[YIK^5\.W6'42MT9#'0P`'`$``!P!```" +M````10`!&%Q:``!`$0``P*@!`<"H`0(!]`'T`00'Z5[<7IBRNG:$#+()7TY, +M8VTN("0(`````@```/PA``#@'Q,:>')^;J?W.IH8IT9>$Q`LN.3O0)5R[/J0 +MU^/4I]??Y.9#8%&]KW85IQ2#&(GQ+,Y>L9W&1E378#C"6*NT@P$K6`ZN-@`S +MXN(="4)3N/$-)V->+\$*#4'$KOS_Q:)U9)=DOSJ,63$U$9Z5 +ME66>Q-V'$A$_@1-#\0NH"1L\M-ZE`]Q05ODTG]-B]$HQHIYU>KCL,#?*%H47 +MV@;F=#SV(DV0ZQB=B7S/ML^)W_[W%K9,)[A5];/3]'/4_NS4([Q;6JU+OL+) +M@-[U7,K":P@3G\:L@'42MT;,*`P`_````/P````"````10``^%Q;``!`$0`` +MP*@!`<"H`0(!]`'T`.0&R5[<7IBRNG:$#+()7TY,8VTN("0(`````P```-PA +M``#`)ZK]-EW"V7>4LU?_A+SCF?U;D^(\'A25YB=\KNX`36.R[A?M@:,_^)P, +M\5F[V"A@YO=*PKM)G[W;<7EVC"J[[*.4!R!PE_:1V$UYY4JE9$DP6Y?96*.J +MT3\HG&P'W%Z8LKIVA`RR"5].3&-M+B`D(`````(```!,*0`` +M,,0GFN#4"!V/C%?@8$/TO\PI,AFQ6_5?P4'6H6;3X5,+M-^HL;N8+"-8 +M=1*W1O!.#`!L````;`````(```!%``!H7%T``$`1``#`J`$!P*@!`@'T`?0` +M5`8Y7MQ>F+*Z=H0,L@E?3DQC;2X@)"`````#````3"D``#!RR%)_&YTH8H+I +M<9]<*SWH$E+.W5YZ8,V'\\UY@@=/):3)`]:H^#)SO[HEN742MT9@:@P`/`$` +M`#P!```"````10`!.%Q>``!`$0``P*@!`<"H`0(!]`'T`20'"5[<7IBRNG:$ +M#+()7TY,8VTN("0(````!````1PA``$`/^%VJUBRYS-)A8G/S9*#Q,9QIB5H +MPAX/+@$*/$4.-$D$IPU0/ZQ1F,D[#0^D<[+\UK<'EF\\Q@*LOI]=7@N23[H@ +MFS^I/M"L(L!7+75W\LDHSIMPD2JV0*GZ1(* +M9_-7$5_I8SYXX]V&?P"I+M%\_7Y3^JU;XR<^2,. +ML27^UZ0DCO8X=_1A''0607RCN75T\,IS@GV;PJ#1@[=1ST%*+H2EV"Q.0@96 +MWKW5GU3(=1*W1C5V#``<`0``'`$```(```!%``$87%\``$`1``#`J`$!P*@! +M`@'T`?0!!`?I7MQ>F+*Z=H0,L@E?3DQC;2X@)`@````%````_"$``.#/R'LH +MF>JO)U,E;C6^,3$V#+"SG,V&L/<38GPMOO&IO['`-U"Y[)-]C@>F+*Z +M=H0,L@E?3DQC;2X@)"`````$````S"$``+!1.?@6T1BX6[IBDE#W5_A"07)I +MQ2HRXO:%V`_!+#9]*X`K-I$)2[.>LM31SQ`,#(7RAA.3PAS6XL20B/T4*LXI +MD'^TQVP`=R6AXA*%&221V1N"TY\V?!U-AX_VB8A`YO9KD]'^Z#>EI)H$#EDD +M*0!`59/LI@(E*5?;$MV62!9YG=^;/4*F=_WO$NI)YV"LGCP[!Y+I^CN^_D3` +M*OMQK-C!*\REP?]DHT,,QS9F=1*W1L&H#`#L````[`````(```!%``#H7&$` +M`$`1``#`J`$!P*@!`@'T`?0`U`:Y7MQ>F+*Z=H0,L@E?3DQC;2X@)"`````% +M````S"$``+#U!HGU<>EB^O5*E7*A2>HMTOU!9]%#I"*VD"-^&I#:`HVKCY^: +MIIX5]*$RHQZ\[$I0.B?NXE,SSS_'_YNB[V@KVF<&;T#A8,3W>\88I'@W&W[CE& +M=1*W1L_%#``\`0``/`$```(```!%``$X7&(``$`1``#`J`$!P*@!`@'T`?0! +M)`<)7MQ>F+*Z=H0,L@E?3DQC;2X@)`@````&```!'"$``0`06?JW/[*IPW#] +MHPYKSQ$O;\J!8>?Y*'@JSRN/5$C(]ZI\HM\NI<3]]V)W5>'PV@99-01<%;`, +M@.E2?QWH+VQ0FEWUM0FK14;W9'V)*_U@H+82R-;I7?S`0W9[BC3<[<\#> +MR'([<(JP)^W!YH>*W9;2,J0P:E^"L?$#PJ.;6VL;7GM&BQT]$#Q+1S&P#K(X +M:]1?=&?UNZW*M:1+V&-\/#5'_D4QK%J`V'T0HH1?;^10^,8M5I#"W"X'FYI@ +MHY59HD6C.N-YQA$Z;!KJ*4X1^LY.45V5*Q(VZ^?-'0.VYCIW%Z8LKIVA`RR"5].3&-M+B`D"`````<` +M``#\(0``X!-ZG&U&C08D6\GD/2L@DL\(KWD_2H\M5>EGEAO926^3AW3+$6V) +M7BV3?G!:D/DN43\B@49)M&ALXAV:#AB1F9Y:P8A*%3!P9Q8T%K0->?(KO-P$?$F>\3NPV"O="6M>L%>>:7*YH,BL_ +MMU+`P/8V]\PM\$3WK9T"!6Y"VF6C?TNYRS*3CF5L?C:?P`>^$'P\2Z[V8#9" +MUF``BKRR_KEDF$?'BV)`MC1PSYB;Y\01*_)2MGC*ZY8%GQ:`3TE4_\7_>;SR +MHF1U$K=&&^<,`.P```#L`````@```$4``.A<9```0!$``,"H`0'`J`$"`?0! +M]`#4!KE>W%Z8LKIVA`RR"5].3&-M+B`D(`````8```#,(0``L*ETY9M^M[EJ +MOYUO^"2P-O.+ZL:7-Z_)UBT%7&G53N^EL2$O\(MXPKG +MCA\7C68DO<$`7+#"NHJ\,H"-RN,Z,Q;T990X49?/$5_LWV'4J8K"IQ27*#FI +MR8=%5\]P?WY[:1RW@?102\4%NXLI`*??C,CM;=/Q0OUQ@3!?G*$"")7,'&=H +MZBM9_%9^KA_->ZE1NP3S(7%NQIB:[0Q#S6'P4Z!U$K=&F@@-`.P```#L```` +M`@```$4``.A<9P``0!$``,"H`0'`J`$"`?0!]`#4!KE>W%Z8LKIVA`RR"5]. +M3&-M+B`D(`````<```#,(0``L(>L3_]$]RHFU+LW+Y<0N?02>5H#+ID&A4$, +MH1]YJS2[5AO1)@[;@;/=P7Z+I0>9L%?#AV^%RD>/WC6X&W@X$G2F?KU*4W)P +M.@8D#YD?`D#]TEM*1!&A*"KP^&Y0%+C]DH&*:U3R^*R&D].PZ8"_XW_ +M5FXG]\1_.-8`@A]U$K=&$C`-`(P!``",`0```@```$4``8A<:```0!$``,"H +M`0'`J`$"`?0!]`%T!UE>W%Z8LKIVA`RR"5].3&-M+B`D"`````@```%L(0`! +M4*O::$R-9+6Y%/=D9%#M.;TF]3^F)G.EB8O`K&?NJ1K3/F?_\;V-N&B*("8DTN=?(PK:P?+Q$?'KFI27:7K"=@FF4R^%2MA*6T$W9+4 +M?FTFU`=]E\66V?_VF'A1KV"BQZ"1E?LB)T-R=`9$;_",D'I@T-/>(#+YPWR% +MA;N*U3S!PB7;C#Q^UT<;0(F`;%.@7NUDYPC?7ST2';M$KICN+.93+<"`U;9# +MRQTK?S0.3?]RDLC1I>QO>YYZF;&\MYT!+`:.TC,C0Y535VQ8.`(XW71D:4GD +M+\%+,N#.]91K;*RK7=Z?BF+*Z=H0,L@E?3DQC;2X@)"`````( +M```!/"$``2!ZE_L(!87L(T#NG?02XB7N0XCNX62E`=AXQ/IZPIY5G%"RKMI6 +M)>OQ?CL<"VOL#;80.EYX:\24X>T5"`UHK+S#]!(,P]6=[XDCD2%-KHC\)D+4 +MV+'_L1.#X>,HDY`8%;FZZ?%;;@XIMZF?XR9QD&T\X0>L?#_1O(*!87MN;0*S +M/5;-6:P>!P%W=;5TU34KJ58-#1%V-L_-E.M<@5HILZ7@.7?&6O-V/W:9"!*. +M7W"YW;-']-$-[&V&>5[4M<]0H&S-,9BL?=7._0`,165T3?A9,G6%2]L=8'@" +M5`8!M"1\JL:?I@8`>2D^#<(T:_'=-SV)I^)VJ2(^Q8`&&+>&(:R5$9=\Y%QL``!`$0``P*@!`<"H`0(!]`'T`&0&2:H)3YSKCEX,[_/>R!JD1>PN("4( +M`````````%PJ``!`7@@&-KQE>)*ETP$V_./)36HL'-NG1T>:-%J"8I'1+=1*W1F^9#0!L````;`````(` +M``!%``!H7&T``$`1``#`J`$!P*@!`@'T`?0`5`8YJ@E/G.N.7@SO\][(&J1% +M["X@)2``````````3````#"T0&HS"A#6#C:B0`EIVAX#30\"W9^R7;P+H6W42MT93J`T`;````&P````"````10``:%QN``!` +M$0``P*@!`<"H`0(!]`'T`%0&.:H)3YSKCEX,[_/>R!JD1>PN("4(`````0`` +M`$PJ```PD.VFYE4;>OO/'M>'*":A=48JJMD7]XCK*;]R*.):I'&2^N)`;+Y= +M2(`'CW!U$K=&A+8-`&P```!L`````@```$4``&A<<```0!$``,"H`0'`J`$" +M`?0!]`!4!CFJ"4^#._SWL@:I$7L+B`E(`````$```!,````,&(EJ[9] +M#\(RNT8G5-R7T>$'.]>KBM.D;V)0@G154D,,;17"(``'@`!P!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``6%XGDQ3>!U*R_NT4F`>HCGFY.PN,);TQ.'"W +MJQS4]'?J4=TK4@4^:.-XL*Z*C]H;&0WWBS;S]+\?S`2CYD5I+M?K`YR=1VF9 +MMCKC:;UWL\W001E3F]`!$KG$`-9G(AY/5L)UJ_?(RS&*?J04<1WU%>1/A*9Y +M!KZS2_6ALI]X>PTI```D]LU^O/(TRVD7+O7W2#>-M"P.%TE@CRTH0(/*.#DT +M=4HI```<``!`!)8UIR!I4````'```0`7P"8:@<.W% +MV0+#D&(!U*R_NT4F`>HCGFY.PN,);TQ.'"WJQS4]'?J4=TK4@4^:.-XL*Z*C]H; +M&0WWBS;S]+\?S`2CYD5I+M?K`YR=1VF9MCKC:;UWL\W001E3F]`!$KG$`-9G +M(AY/5L)UJ_?(RS&*?J04<1WU%>1/A*9Y!KZS2_6ALI]X>PTI```D]LU^O/(T +MRVD7+O7W2#>-M"P.%TE@CRTH0(/*.#DT=4HI```<``!`!)8UIR!I4````'```0`7P"8:@<.W%V0+#D&(05?JZAK1E?'>_MI_&I-UTGH^L'=E:9E1/WVAU"W6%!>R#Y6(@" +M.RC+5=Z7(?`."W$K,X-4QWXKI4JXBJ@6DCAFL#A]3:H9)L,M-]JUJ.Y*BVTT +M^),,Y-E5B5CP-GRTT)>E2RM006[ZO2WW^N!"*0``)'U=)T8)C9)Q`HI_]:YW +MF7(?T'@8B/JU^*88//(0P!)/*0``'```0`1CHFW0K`5(P+`X?;Z:(QWUT,S@ +M6@```!P``$`%-%O[)NPX=D?R"2QN;HW#7S80+TEU$K=&\24/``P!```,`0`` +M`@```$4``0A<=P``0!$``,"H`0'`J`$"`?0!]`#T!]D0&IR!%&&[>;^I5"QR +M`&3F+B`C"`````$```#L(P``T'TF5KZARC?EJVU0@YV9(_%O1?Z37[J;$-Z9 +MK-QR/1NNS+[#/ZPW:GOED<>LVJL/_4G/@DK?6NK>C/GI2$3-"[RQP!N,W"'( +MV(8$GDD#-('X=W)Z='$4&(H)>Z],7,ALNM-9FF&)!`(^A@B-6+Z"^+IW4PC` +MVGQY+"D3C>HN'`)MJS6"\MS@NENSO3)@WF,5[F3;M&*[P#K(J=R*5G996#`T +M3(=A0%]/^3?(L9[0R^-SMAGHKA%OKTJ\AVE>`Z2QA9BV`46<=B/.9Z-D#W42 +MMT8"0`\`O````+P````"````10``N%QX``!`$0``P*@!`<"H`0(!]`'T`*0& +MB1`:G($48;MYOZE4+'(`9.8N(",@`````0```)PD``"`\ZLKRI_]?6,`W6DI +M570OF(G3[X++[>OEH>2@O[@(0!L!\))!0*8.][GBMX2#O>_C$AC-6YI_LW24 +MWM8@:='R']$AT=CH0R\%ZM/PF<<%HN6XT+,@[L,)=1QF=H69.F>'!7"0.C?' +M>#E?%]2RDU(Z\^:@HX)9P,9=PI1BCG82MT8['0``'`$``!P!```"````10`! +M&%QY``!`$0``P*@!`<"H`0(!]`'T`00'Z1`:G($48;MYOZE4+'(`9.8N("0( +M`````@```/PA``#@C"SR=6GQ&1L@?-T&J\1N2DTH&``H\13X-]OZZL%D+]9^ +MF`@0'#^)]^/?0*8@^J2]YU3PW3D8.DYKQ8.<4[P`FD5P,%R\:N +M8T[1U?QD'$UZ3#&(RY1_%,:)#-L6&>U1$2FYH@-D&?:+WV9@))>/WTB@ZO9? +M_/]T]/P``0!$``,"H`0'`J`$" +M`?0!]`!4!CD0&IR!%&&[>;^I5"QR`&3F+B`D(`````(```!,*0``,+*[.YT3 +MF(I(K4S2\K4G?>!Y/PP94RH&]Y98`\SW)9=757B&Z7NJYVTK:"])=A*W1EA0 +M``!L````;`````(```!%``!H7'X``$`1``#`J`$!P*@!`@'T`?0`5`8Y$!J< +M@11ANWF_J50L<@!DYBX@)"`````#````3"D``#`R^EDIPY$>TJ;FX0&NY_4Q +M!(-W6#]V8M8*IZ6%-$.@Z?K5SD<(CMW +M*TZI:9L#`+E9VVWM^[9IWF,`P`F+917K3[6S+L0F(`*VUSRTN8N&?MW';57W +MLRBU$.-8!SNK337RHPGPD_MMQ1&UUU':7^%H+P=654*2MND0R4P(^C5;0N.G +ME'O,X(7AV<84*6;(:U:/D;BF2`:1D?XGJ4,X'9Z7NG_N<*>R5P9I:6WE +M]/$LK#C"WW-J#U(\-7'N7]DE>.Q%)UBAN8,ECE/F@HLO;FG[98 +MCD]WUE_Z3ASC\B,*K2%`"WHL&^0WTQC%Q5MG*1!WA;,J-MMR83_V&^1L/?.S +M=A*W1FAW```<`0``'`$```(```!%``$87(```$`1``#`J`$!P*@!`@'T`?0! +M!`?I$!J<@11ANWF_J50L<@!DYBX@)`@````%````_"$``.!J\HL462I`[&5R +M4F.F7DR,:CJ[=LEWS?V'Z[/*RKSPT=7I%]7?I"UO&Z#HUIA)OL]5]9`(!7"X +M*V*TZ&[5$\&%M&2]J+U6[V]@*JCW$&RR6C,`4B<*ZNWV_",4/XC1T+WMU2A2 +M#V7]`K.R>1UJTP1JQVU6K^)>"]M.JO,#\W!YVWXW\L&M"2?]^'-T0Q=]4#\$ +MV,R!KD.,`J`W^7WQDYBKSJ1R74HX--A->3O^I,*9\3'U_4_5.=87L[Y^KL_^**Q]V-ZT"*#-XXK*68L%QKP: +MNV)O.W.1;5LB'H::ZX"\J#:GSU^U+_YW:=%HYB$,IQ20,*8B-^#"U5[N"(MY +MZGG-/L/5UG>]%KVO5[ICJ!-2OG(YD.(HP;O6)W:;NPE+>O&$IRH1_]XR*2]3 +MP2.E(S"F]_7E0HLU=A*W1GBG``#L````[`````(```!%``#H7((``$`1``#` +MJ`$!P*@!`@'T`?0`U`:Y$!J<@11ANWF_J50L<@!DYBX@)"`````%````S"$` +M`+#(J"K!3L_YMW1+QE"(6B&.T) +M>NUQ@ZK17NOF#3:=IU%]ZGY5$/S13^!$[26]H3G@!K=Y$X\K]&8]K:NUQO.R +MNL*93D1;(7J9I1?MB8[=$@CK#5K)I0&^_BG^W45)&O(L&..X?>I#5L?UY=;0 +M%3]7=J4614>EU?VA(NA2(^=Z=C3?']N&1],4I0AQAN)`.$A/SK/0=A*W1C?& +M```\`0``/`$```(```!%``$X7(,``$`1``#`J`$!P*@!`@'T`?0!)`<)$!J< +M@11ANWF_J50L<@!DYBX@)`@````&```!'"$``0#5498>\14V$CP>2T"1^#52 +M#(!C[L(!?"F8TK\WMNM3G8`1`)=M-YZRJ)Z"*I->\L1V&M'=FCUR3+_N" +MN:VN>?\^2#5+AJ$+S?S&^PY"_T].0J`*QY<`/EJ-WJ18BB9F$N.KV]A@_0Y) +MF]1IQ8-Z6]U98HH!3>_$?)/SC.*##REZI8*D,D['B!A(= +M!>`?M7$B9;A3:-Y4WDKC&^P_LL=4-%[)UGGJ9]03ZQ_*T2I'L]D'DLCXQEZ> +M&E4.N]#W.I;_G8_R>5;$"JD[S/9N+S#)GX'?^7'L:)4RZAW7A9\W/5D_55UX +MH9C+#BXT8`).:]UV$K=&+-(``!P!```<`0```@```$4``1A;^I5"QR`&3F+B`D"`````<```#\(0`` +MX*B5FD[T&AKD(#ZK3HC:F-12(Q?)WS/?E2"Y`@W6_`.A'F,>3FE7Z[NLP`_R +M;^I5"QR`&3F+B`D(`````8```#,(0``L%J13BQ9]5W&DAWU[7Z/ +MOSA'B.V7@];%*6EU+UC`FVQRPVSOQ9!0A1$WF\U877!!P@0+P2]^=010"?I" +M4#DN1`N+_%2("HKL^;QI#*+<3T_-A_=0,CDC_;`Y*G.2.UO!W[+%_=B4S(#5 +M-';%4KW/]AEPI>/=^?Q7>G]3R5(!\W`!05?;0DF<(3`>&*_;9:^-*KA**-U. +MARH[:F^/9X@#,9=?W/M_)G9QE0ER:*5V$K=&Q@4!`.P```#L`````@```$4` +M`.A;^I5"QR`&3F+B`D +M(`````<```#,(0``L'LU)Z'4*XU&/4PS>OL>6?47ZIT=*8SKP[D#4Y!O@BD& +M:J@^OQ*LV%JURD&_ZCMD/.L`N.[:R8>*8$2?*ML'7$F +MO$;W;7]V$K=&P2L!`(P!``",`0```@```$4``8A;^I5"QR`&3F+B`D"`````@```%L(0`!4(*BITU[ +M"V>+/NRZ<7.^)&GRYOM2&4*ZA046X.)7]]Y#/V-S"LQMV;D +M:7W'^_?]9M/TZ[STH6&_E@!HEG(YO`5S +M!6^8TX;N=&X!=_FN+]'I#LB`NO4QY)*O)M*G,EZV]:.@1\8 +M(12Q-W`*#FC]2C3DO#X3?5_/.>A^&9W>;`H$F,1S^L)-,4`1A;[`]YPE.9R= +MH2%:=R6"\>[=PUW\REHP@_>#K[!C]]&04%.`XC<$,7GXR@HMG3,YEIEUH318 +M=V6SG,\?2FD=XY@?=2(O!W%R6UYKZ^D"[Y/,CUUKK.LH1&*^'9M +MN`8Q-.L6Y7ZV-P*=[NL&9M`;4;2Z)006[.[`BV1<.;([(]4?)U=YF2]^HM*MPZZCV-%*;R^SF&AL`[VVIF3>JU2NK&'QLSYR::X- +MPYE8,L)I=!4OKPHK76JE*!MBIS.Q7^,*]D`PQE%,'"$R>87_^<((O%MP277+ +M_;1[EGT4];2\)=)+Q68GP782MT8*B`$`?````'P````"````10``>%R)``!` +M$0``P*@!`<"H`0(!]`'T`&0&26"#@(ZR`?BP6@JDR0*3E,0N("4(```````` +M`%PJ``!`[=ERN@+SP/N"F.B=8=CR1](BIU/74!C''J?_=A*W1H*3`0!L````;`````(```!%``!H +M7(H``$`1``#`J`$!P*@!`@'T`?0`5`8Y8(.`CK(!^+!:"J3)`I.4Q"X@)2`` +M````````3````#!;T6@:S$:I<'YRAW!3?]"7<@-QCBX3`UEV;=%E5P']:_)3 +MN$QC%6M5"+?(['82MT9:H@$`;````&P````"````10``:%R+``!`$0``P*@! +M`<"H`0(!]`'T`%0&.6"#@(ZR`?BP6@JDR0*3E,0N("4(`````0```$PJ```P +MW@)/:>O`-M1_U0)U&H9)`HP*R9KZV1A>A%3/P`]@^KZEM5A4$!)=#35?.$EV +M$K=&*;`!`&P```!L`````@```$4``&A"(``'@`"`!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``847NT/L"<9^U8K]R180PDU.)U;D"6+"C6^#'WK:,<;Q)QX@I```< +M``!`!$Q0CWB.XHQ@<\P\SDUV:O^:R]6T````'```0`4;4L)"+B[0U,^M\/_, +M0$[M,@1(,782MT;3N0(`7````%P````"````10``6%R.``!`$0``P*@!`<"H +M`0(!]`'T`$0&*4S:#AK@\MN!```````````I("(@`````````#P````@``!` +M!@````>;U*P1E8W\J*V-P0JFXW5_ER@N;U*P1E8W\J*V-P0JFXW5_ER@NC6^#'WK:,<;Q)QX@I```<``!`!$Q0CWB.XHQ@<\P\SDUV:O^: +MR]6T````'```0`4;4L)"+B[0U,^M\/_,0$[M,@1(,782MT;J[@(`4`$``%`! +M```"````10`!3%R1``!`$0``P*@!`<"H`0(!]`'T`3@''4S:#AK@\MN!M'^! +M(A"AJ]@A("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```( +M`@```@,```@#```"````"`0```(H``"(``(```VI)%C*$;J>**5E48%;:^EK +M/&+%7BK@^Y1:N<7V!V38/U:@L8PJ\L]M0SGI8;EWN1]]Z*F;0/I0SLX!]8O0>;9T2&+.;:<4X#=TQ1#(@\:I0&C24(-V8['&2`R8;KC4O19, +M#;",_.2H0)+S.*E;R)\H3]D\:-Z(^6ENQ@```!P` +M`$`%5@?>R&X>^4/;D5U@`KF^UVYL2Q)V$K=&Y!L#``P!```,`0```@```$4` +M`0AM^NVO[ZQ,O?+'82MT;T-`,` +MO````+P````"````10``N%R3``!`$0``P*@!`<"H`0(!]`'T`*0&B4S:#AK@ +M\MN!M'^!(A"AJ]@N(",@`````0```)PD``"`GB0(9_7.!JP?)=Z-KIV&$R#V +MQIWB:$0D,&!2[\23]ZN?!0C>-!+'YV(`\1[D\.?5K*!D,(GJ&#;AS9F([[*/WUHG2C782MT9B4P,`'`$``!P!```"````10`!&%R4``!` +M$0``P*@!`<"H`0(!]`'T`00'Z4S:#AK@\MN!M'^!(A"AJ]@N("0(`````@`` +M`/PA``#@`3DHS2VEV[VO5S\UE?&8V1@->R)\7`RA%+MO(#`Z/#DTO$B,U&YD+! +ME(;6-QUU6+L/%$_%0?Y5I=(9J<>#0G6.B*>+>]94WZ*IM>FA5%&O..39F9!9 +M;YGTF6`RCD<)D#>O/..`E2OK'L.+/\5=]5V`;Z2V0/\WHG%9G0YT^L\,$47< +M-"PPZ'F*OD:'F#G&@'$98T4B2A`NG+@)?_54@WL63C9A6ZTK5:Y7&+MY0_;F +MX'82MT;>7@,`_````/P````"````10``^%R5``!`$0``P*@!`<"H`0(!]`'T +M`.0&R4S:#AK@\MN!M'^!(A"AJ]@N("0(`````P```-PA``#`,K/3&G(1D%CI +M6XCW91JX$:9`AM:FE#'U0I1B7"RF\L=5/+MCTP[CO`.,J(>CK\_A=0[0TUCG +M6RS.[,N80RI\\7:C.S'S;EBOKQ!\[1I8W)](`P#,B'D"Q&[+[:;`TW,22;DH +M!G_D[&N,6KK>/BXX6JOS!$N!%5;P[@N'6HO)*S03,9`[3=IA=Z#R57)YGJJ" +M^<$LE1:R,2!6K)$W3,G;+CK)782MT;1H@,`/`$``#P!```"````10`! +M.%R9``!`$0``P*@!`<"H`0(!]`'T`20'"4S:#AK@\MN!M'^!(A"AJ]@N("0( +M````!````1PA``$`?0_KE,!F0VD.'W49BY+*E3H5CX@K+J__V%>(>U")IN^Z +M*TR\+!0[!*5(WQ=AZ51G]H=+V%LMZHT.?_$J-*C^G8U$H_`TK@3RUPX136Z%CE@@3@;5- +MVF=J?-<@@D-HEFERS>DD__CFX*8+WJ;X#'V6>D1C:',? +MFXX=WZ#8G2/FWSXAXZI.%")2#86W1$?0WE3R<9:/;,9YU1/EOQ$,", +M=WCR?50CP>$BP(`B?567!]S'SEL52%LFC!M4*1)PC!^:UFUW6E170Y^#O@/I +M!9,F=H>@__Z][>J+X,VJ^)";5Q@AH+"L=9K?F2R;>1;2E;X=CZ6`KG&_[K4Q +M-7IEQP;PB>%W(BZ?WH;FG%!R0O(O@EQS9:=-?IG"R$(`_L.Z!_+-;QHO29C% +MA=M.+;G1ZI%GI*GS:[WNZ]AP;ZF/)0*&=A*W1F*^`P#L````[`````(```!% +M``#H7)L``$`1``#`J`$!P*@!`@'T`?0`U`:Y3-H.&N#RVX&T?X$B$*&KV"X@ +M)"`````$````S"$``+!(%?+_2U<^[V%$@T*39;L82DM!/T*Y^\D8S$S!GC?` +M:O6@]9Z8G89S:F&K1*=&$*N437F8"*<46A5(1*5>9/K,^2HCD@53WJ#0"_K@ +M-&&N-8(W-8W13]BS*%I\E=FHU<@)+OC*>,;9E*F\PA7`_J(H(NGXXP&C56RV +MQ)HC=2;%S26EKHKO*QD*Q2+BL<%NGN[8(#9Y0HJA;"RRE(.#85%LC(XB?=M. +M#528?X`I=A*W1K+B`P#L````[`````(```!%``#H7)X``$`1``#`J`$!P*@! +M`@'T`?0`U`:Y3-H.&N#RVX&T?X$B$*&KV"X@)"`````%````S"$``+#;?13> +MKD6^W2+GF)!*2@4#1*\-'1R,",&8S!R*=DYI`LPRK=Q]5Q4:CJ!);ME45Q6S&+-+)DVWQP``UNVY +M*@)XO80+[PJGH4`#[B%SH@G!DV^ +MW(1=@T6)_B72JF6X0T=@"6[*9JH6.0GA%Q##PB8N$]Z]9MRTW;H^JUU#\Y!_ +M/QUB>L.1#Q*LD4$7["+.TV7$A5#Y;FM-A[+)F>V=W& +MEHG%D"",H4\E#AYE='%GCM3*O0;M/W_M8Z5]66I>:J-N((@5?`84Q5369WR` +M#,U*J`^I+J7FSJ#K;`'>QXMS8A9JP^$A1TP0%CF0NRBZ]5M_@/BCOW,$4Q>A +M`F)I>22R+U5_8`MUIK8]D]'=`KT?5#D>>1_63R[PJGPN2!(*KJ+?]K61C+W[ +M/*#Z1)UV$K=&TPL$`!P!```<`0```@```$4``1A"-SBED=UD\GMMYQ0=]`TWH^"IJPV,_P(0%KU7-BQ33,5"`QMA6>D1*)]WN +MQ#(L9U?*C5TCB^^!W@Z\+P3C?NM1X9432O.5W!<.4_.O_3*.Z`?P1F'0A7[> +M*$<)J!X5R$%;MV^[\AJ&1%T^9:OA[3=`%(E/M@'\'7X7D=P;-SL$]'ZT]EN8 +M\@6HGP41GY.VVO?4TQ%JES09JO&DO>\&E]XUZ*S-_AD_Z-5%-]%(J!4/G,<2E-HDTD6%-C;7_W=_Y& +M3"^L:V(,]=2;;"K^)E@D>4\=H&A+7>IJ&'WE@4TS*6H-,J+A3&/:QR3_5WQ1 +M!O_F,B.C[[6.>*RCV>PI@:C;D)](U0=6ZJ([V7PU@5&GWW'K@77775!7\!<, +M9%:X,GQNA7QQ5@&9+C]@\$IV$K=&64`$`.P```#L`````@```$4``.A:7?A[AX(;6.2KN2_W54E;1(A.,>0WJ507T1,E"&@9\70OD+V]T1I&>T +MS3VL6[QF9=_GOA#ED!`U3`&9SVTMT[P7\VDGK+W`(O79U-UE<#)`J;EQ4?T@ +M5^92YZZ^Q.F^XE'>%;V($XF+])S)9'T\!26C.G?^6Q+C5HT2<1LAC*J16*9V +M$K=&1&8$`(P!``",`0```@```$4``8A`=9HR%<1,"`Z:/T5&7"]YK,6"?_$6$76S.A< +M;$Y"A8J@,'E".JY&XU+8R^1AU,>6M&,PL]Q*A1./WJ7@A]BLI&1X!N.QM_#A +MURM5`Q@^F9A*.=R2EDJCL#-+&;LB`IYZ9``3(M(?U>>''F\D`+G[W<>G-.3' +M.$\S;QF\VY7@&?'])#"J]P].K*0)-$(\[)Z=F8XH&Z._V@9X"IY2SM')^R[* +M._QW@ +MMIHEU9C:CG<.*2(USA)@P\3_Z6K\E#+^7?!7)30O!HK5*%$O-7^Z&.YBDFJZ +MH3O.JDDST])3@4\Q_A[4#,U<6IK=,F,N.<''TN)8REK[GNKXL'EJ'?6H)=#Z +MPD/C[F<:QQ<[88`?8-L$_!^-SH<7,5!5_0^7IPW0`91+O`9)Y8>I?RR:PMC! +M)7EAWR612'0\&IHW\!>G`^D$7_N6&"NO$6U/LEQ5$-+K8&$P#DE)T7%LQC4_ +M%RV0TG5SD0Q@]2VJH/`"]L;-&<(\')Y='[KWOK5JKE,GVTD6*T%"M_;RID", +M+(.[+/XK^_P%*G82MT;4P@0`?````'P````"````10``>%RE``!`$0``P*@! +M`<"H`0(!]`'T`&0&262M,P$C#T,G\4YH?./)(,$N("4(`````````%PJ``!` +MJ-F-04]6>*T2C=@-RYL2'-$@]HSBAF78R2<7831E*`]97 +M$Z6X(W82MT;IW`0`;````&P````"````10``:%RG``!`$0``P*@!`<"H`0(! +M]`'T`%0&.62M,P$C#T,G\4YH?./)(,$N("4(`````0```$PJ```PJA+[)M@` +M_PZB,:F']\R[AB$1A'*KN.-:T$BD$'-E@;EOL?#N9_#,1)`KE0%V$K=&3>H$ +M`&P```!L`````@```$4``&A7PL^X;029SCHX^6C_Y2&F^\/!VQY6=A*W1H_G!0"8`0``F`$```(` +M``!%``&47*D``$`1``#`J`$!P*@!`@'T`?0!@`=EZ\;@\9-]I[8````````` +M`"$@(@@````````!>"(``'@`"0!T`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``Y0>NPNK@OQP1`^RQ,`PDBXT9CH(R?I!UE+!M^D!1(H+^\2FQJ2:, +M92<8WJ_3><5(`JQ%52L`]JW1D++,^4DZ["@\-Z+."$F1N2.+FH5>L1F +M\Z)#-IT#"@#):ZZ,^P5PB^^X5K+J6H"L`37M!.W(/*ZQXOV\OV:!D0H,_J(I +M```DNRMI^ +M1G82MT8%]P4`7````%P````"````10``6%RJ``!`$0``P*@!`<"H`0(!]`'T +M`$0&*>O&X/&3?:>V```````````I("(@`````````#P````@``!`!@````?, +M[.15P1ANF7A/U;M9N#W82MT;&!@8`N`$``+@!```"````10`!M%RK +M``!`$0``P*@!`<"H`0(!]`'T`:`'A>O&X/&3?:>V```````````I("((```` +M`````9@A```@``!`!@````?,[.15P1ANF7A/U;M9N#R(``'@```!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``Y0>NPNK@OQP1`^RQ,`PD +MBXT9CH(R?I!UE+!M^D!1(H+^\2FQJ2:,92<8WJ_3><5(`JQ%52L`]JW1D++, +M^4DZ["@\-Z+."$F1N2.+FH5>L1F\Z)#-IT#"@#):ZZ,^P5PB^^X5K+J +M6H"L`37M!.W(/*ZQXOV\OV:!D0H,_J(I```DNRMI^1G82MT;J*@8`4`$``%`!```"```` +M10`!3%RL``!`$0``P*@!`<"H`0(!]`'T`3@''>O&X/&3?:>VM,2C<`7HBE0A +M("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,` +M``@#```"````"`0```(H``"(``(``$S-IW;:G`J6WTF0WG/=IZ74@FJM)F;D +M&DG\_]SOJ>0^%*HLR4REZLT\>/_+TV;)=KS\-(0/:>L5?O1"'.63XY/3'*<5:=DYV$K=&VU@&``P!```,`0```@```$4``0A2C_7B%$$YFJT+U%A"$R-A566S`LSL&L6>0+RIUZRFEGYUOG@'LP"PMIKS +MM+@M]+:>SG^Z5G53$=Q5GIZUX!G;ZQH!-;BBU];J.15*U;.\U>24Q;J@C.G82MT9M<08`O````+P` +M```"````10``N%RN``!`$0``P*@!`<"H`0(!]`'T`*0&B>O&X/&3?:>VM,2C +M<`7HBE0N(",@`````0```)PD``"`^X,]=MD5U(X41(+`4M%A6<%GZY"KML7< +M4!@98PMVPLE2(WB"OU[##!N;W*=9W6X`)\EC!]\(`D7N"_\X::HMA5.^I`+, +MZ0:O[^8^@<\"9:Q<@AP";D-7<(,W>:/##UP[R#O'4W82MT9'E08`'`$``!P!```"````10`!&%RO``!`$0``P*@! +M`<"H`0(!]`'T`00'Z>O&X/&3?:>VM,2C<`7HBE0N("0(`````@```/PA``#@ +M-@^A<)(^RESGL?W1,6?A4FZ`P20)6T'\!6RBU]A3+8),!MR4\KV$565/1#XM4B/-FB?W\(]NKS"T(&17*HO($Q^\_SQA: +MY%]63:VG,$A96.(@C>V?*4%4KZQ&@8567\7\3:,NK*K*0$M3SUSK)(`\'H6P +M7Q4AC`B"&*>PL,`$L&M.?.1B]*WS0;%#H4Z9\$5H4;/;#VQ+AKZ\6 +MMG&P7^"SL4@1RFZK[,H>4/;G_X&FF'!DV[5OE92C;]M',A(M`Y3F>W82MT9X +MH`8`_````/P````"````10``^%RP``!`$0``P*@!`<"H`0(!]`'T`.0&R>O& +MX/&3?:>VM,2C<`7HBE0N("0(`````P```-PA``#`PO2\0Q9PKX,"IQ#N=;W:T.E_X.RU6-66&"F$P:HX6*6R770/\)" +M>B\QSO-F["+4Y&G5Y1.&@3Y=VE^&!+D/>7RAEV$K=&9JL& +M`&P```!L`````@```$4``&AN>J]"M^NG9$J* +M6F[6!&:V!P?+LL+J(TL0#F#NK#[,QQK%[&X0=A*W1D?'!@!L````;`````(` +M``!%``!H7+(``$`1``#`J`$!P*@!`@'T`?0`5`8YZ\;@\9-]I[:TQ*-P!>B* +M5"X@)"`````#````3"D``#"$'S)ELN9!;GFA\']YL9)B^?<+VH/X0T3^(^U* +MCW9Y*H&#F[]9+4_YK0P%W782MT8[X@8`/`$``#P!```"````10`!.%RT``!` +M$0``P*@!`<"H`0(!]`'T`20'">O&X/&3?:>VM,2C<`7HBE0N("0(````!``` +M`1PA``$`DZLB3R@@"KD=\^'*!5MI4$BN#[0?4'!UB\SB>\*-0L3<]`XG3#-C +M]E_B7KTV0A<%B_>C[!)(L_Q*AJ5U+[0KC"+'8?JG[!OU]>6Z]^['0$R!D2SC +M]4`)J.W;FZ2+#^1AK2>/J[<:!"K7N?';2P8.B^P&?1.$,T96+>QCP!2_.U$? +MB,3C*3L"OX]X.:#F&`Z^!VIV.D?['.:/1HKZH2*6@24DOI"9[E4R@7_-ON3K +M?SE^?K9<5]6EA5B=SV!\*"P!*B#G8"A9>/+F)N^)$%B9SQ#7&9"!MQ1FQD46 +M,9:)$S0+$4D(G89'7IPS)_0<1$_M@`PCB*5"X@)`@````%````_"$``.!VLQ.>_DY)\3XL=[2H'FI6P"*RFF*O +M=P2>+9''B^AU_=K_]`=%>9(=QIU;^D!8Q-]LC/2@]L +MC/&@HU2[U=!>;+TG%0I?@$^I!T2C>KL?G*U1YH"1OZ +M;^%D*;*+._23FF61&45B*5"X@)"`````$ +M````S"$``+`64;/K/]\^_@J>HJL775Y/(9W:$0W&K;10D)\X("H1P>NQ7.FB +M1D2IFBPZP_5BA2--KG72G=4N&W0:^7!6??AE&><+^9.+ +M5MJ'VTR5'*4.[0*F]6WF[V&6@7IW6@E=&^@Z&=R5@O%? +M=A*W1GB*5"X@)"`````%````S"$``+#,!Y*)^HX9*X)D +M[Q9@4H1FN1:I!V[X+]X2?3)PBGM5*0SE!AP^TF^G>IR6IWX++9:/)@[+CC/- +MFX&QL\^H]SIEEC4C#OA2PN7JO<QB4#O]40(\KCE]]X'GG?%N&F/=_ +M67F*W%!"6'#`;=M0&N3XS+A4_3[(<.DGR2D/C<4OD-?'7136S^*SN4>R$A25 +M&4B* +M5"X@)`@````&```!'"$``0`4\QM"?=_=5">6]&:\8KJ4H=I>L7`1L8O=WVYE +MCN:!&P:>HGK3QJ,$#SD3*.70W&J34XPERCN^G$E5"7&.I6]=:@OU[ZH]<^1? +M,W^J77NNF%>-V@0L\N,DCR072A)#8"G4EST"?$)2R;-C7?*CDNC:FGWYK8(- +M:%5E9AG;>_1\7%MZ>[M74@%1X/N=F:M=-3;#HC\>1RKY@75IW"#:.$4`5D8I +MTN;"TE19]]7^A4]QUF4XA/&6UW%KS!YS]2$GF6!_/P)XNK,6OZTZ`)':OP6& +M^EO712L?SF`]E-]#2:W554/$K;$\`E,[QAV +M$K=&T%H'`.P```#L`````@```$4``.ACQ(91^7N:L_O,L?PAEF(-[YRH8? +MJJT7)OD?=>ENM(>:'G>.^,+/(F&^+$NZQU-#2!*#,T1CEO>1LVM@DO +M`:C>CU=L=+433=8CR0/-50#)%T(-$[C.%81V$K=&*5L'`!P!```<`0```@`` +M`$4``1AM8WA)\V.#KL$OCU%$6_(H8_1E1O]J@NM.I,A +M4I&"IFYNNWP`;(T^X51!PU>8@/>F\M[W;VZ>RB&@-Z'3X&WO=V$K=&@GX'`.P```#L`````@```$4``.ATDIQV)"L4N1"N9^I^?DIGJ65X"?:LZ4TD\^?+.D7](O7F2V +M]#7'<[H\@JZ_16$R&>-9F,8,,B4H6M[8THI':M'G_-VW:(F;:1+F(9M9%'%/":EHE+.(;)J@\/'W<07,!:JM(OQD\/,LA>.[R3LE,N,\Q8P8^+( +M-NR[2B7@^#V[+SV4SH@XGAA?J*B@W/)[&1?Z_L_<"!UC^(73DTSIU0O?+4EV +M$8$@=-Q*^8M/0$M?ZX5_$JK1CZ3KL9*C(E(;`O&Q-\7<[)!'PNHS8CE +M98S>:XU)!9X*[L"(B4U%JN164@4;9E!TZ.[#)DI83/` +M19D^PVJ0>?O3FG%?OA*@H`*/UXM?G6W^:]-1.;^>==)G1TO8%+5!1.X$[4G> +MIH;U&GU',M3Y7P:P84_\%CJ*%N;TN)A`,=?%ZA/.&E6];HA.'L-@TE`_%[>-._@9!"9A,(\ZR +M=A*W1M_9!P!<`0``7`$```(```!%``%87+X``$`1``#`J`$!P*@!`@'T`?0! +M1`B*5"X@)"`````(```!/"$``2!SZZV-G5/``CX& +M9%\["^U-X]_BVZ'D;XJ5[9E)N%KD(S+V7]>4[I]U99$P&*F.*EN1DJYDYNE" +M]UCW`'6X<5K=*5+CQCXN/N\M*?W?PE3V^W=V2P6SI'?O44U\M_$3@\?QA^]* +M@WM%5BBW.?/*_V#QI73Y-VBZCUNCLT(4"'\,S%4:YQ?V0N/K^A5 +M<3%6^_P"%&>W$2J-)]LX]!<7RTX@_%??-KP,HG8Q+5%T6;LU;A$_<#P=;L\K'E6A+D5T6>PFEU/*3/O>'!D)H-] +M828:'@L*@R75*104SS17.^!"#SHS6@Y`7[L%?BR2)LD\@#W66="NX4/WH`R7 +MWE08K'82MT;1``@`?````'P````"````10``>%R_``!`$0``P*@!`<"H`0(! +M]`'T`&0&27GPSTTP":S`P]4L`]=]R70N("4(`````````%PJ``!`Y"(+TM?Q +MB-Q8/:[\TSGTK48C++@9Y-45WE:'7N5\BGT"YTG*B$WG:GX&N?X'17MN?B'# +M*6]<_8?[98:H=A*W1G\,"`!L````;`````(```!%``!H7,```$`1``#`J`$! +MP*@!`@'T`?0`5`8Y>?#/33`)K,##U2P#UWW)="X@)2``````````3````#!` +M^2?=NDIQA(S#H"5:R1%ZVX>:V/@E=G3>89/#'<*M;K@V*>6"R`?*R\Q_XW82 +MMT90&P@`;````&P````"````10``:%S!``!`$0``P*@!`<"H`0(!]`'T`%0& +M.7GPSTTP":S`P]4L`]=]R70N("4(`````0```$PJ```PBUMAW9;M^/S:@?1) +MAY?*3!MD823R>HU@ZR2'5V$K=&CR@(`&P```!L +M`````@```$4``&A"(``'@`]P!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MOJ5_T4?/R%'2E.!)E'EI.P#G@/K<7#\7`JF87@QCY(".ED`D1.%'H#ROVJIR +M]3)@Q>,8[-*0;Q+XL&AR%$9?>SF;=)_R*\;Y?0G64%GULY]NI7E(/'./-3/R +M[]@0Y8DJ[PI@_^JO<1]@J-^ZJ_?N;D:"[1L`(PHBDGZSC1<-MD,I```D^L;' +M*\_TLP)"$X0C?@+I.9]'9(>?S1\5S%G17/JK$VTI```<``!`!*=W?WS%J/S/ +M/.TZ8H3X\W5]<$_8````'```0`5#/`Q[M>*J(.U&.+%)1QPL`G1.OW82MT8W +M,PD`7````%P````"````10``6%S&``!`$0``P*@!`<"H`0(!]`'T`$0&*86Y +MF*KQB^TO```````````I("(@`````````#P````@``!`!@````?8B'82MT;S0PD`N`$``+@!```"````10`!M%S'``!`$0`` +MP*@!`<"H`0(!]`'T`:`'A86YF*KQB^TO```````````I("((`````````9@A +M```@``!`!@````?8B"(``'@```!T`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``OJ5_T4?/R%'2E.!)E'EI.P#G@/K< +M7#\7`JF87@QCY(".ED`D1.%'H#ROVJIR]3)@Q>,8[-*0;Q+XL&AR%$9?>SF; +M=)_R*\;Y?0G64%GULY]NI7E(/'./-3/R[]@0Y8DJ[PI@_^JO<1]@J-^ZJ_?N +M;D:"[1L`(PHBDGZSC1<-MD,I```D^L;'*\_TLP)"$X0C?@+I.9]'9(>?S1\5 +MS%G17/JK$VTI```<``!`!*=W?WS%J/S//.TZ8H3X\W5]<$_8````'```0`5# +M/`Q[M>*J(.U&.+%)1QPL`G1.OW82MT:#:@D`4`$``%`!```"````10`!3%S) +M``!`$0``P*@!`<"H`0(!]`'T`3@''86YF*KQB^TO>-U1\H]?K\TA("(@```` +M`````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```" +M````"`0```(H``"(``(``-T(CJ5P'\CYXZ#\:)*U*"NEQ3XTKFT,/D#+68&]2_^DG +MA]\N5R"#?>T@4)^:=K`22ZH;2$_V;'LH)?GZ3@BA#LWWS=T +M23Q@2L[:ZJW,*0``)%!@-QLTJUHXDMP+IV+Y*Q9:)$418[YM$I;,!.FI*:$Z +M*0``'```0`2F%,MH9X@%NV[WT(QDO`J6"F``0````!P``$`%<1F%K_S&W@W/ +MW'U@U\4)0R1(W(/^J:"T=\.*>'Y75)(><5WK]-:5."4$M]9TN2?W +M9HJ]G\T]_YPEK01GO8H=4X8_/;@"<';Y,X'"E=S1"=$UIE$0C2P;Y,@3Y$*V +M(;N/XRW242N?;^HF$%ZFXN/4[Y5X#]<+2=H<=L;P0(SZC`/`P_Z,O3`4/OG? +M^L[LC,>29BRQ+V,F=&?!J2'@JA?W]>`+;G82MT8+L0D`O````+P````"```` +M10``N%S+``!`$0``P*@!`<"H`0(!]`'T`*0&B86YF*KQB^TO>-U1\H]?K\TN +M(",@`````0```)PD``"`*;XB`%"&RKKU1,3_$3:R;K2!?/DU-62K%1HH2S+1 +MLI9)1:6_;+/MEX[SV)9MF"]_&8O0G+C@T7A%8-U1\H]?K\TN("0(`````@```/PA``#@S]>ZI"GT +M?ZAO!3Q?`DZ8[)+UAMK)'5E-WI5_`Q'DIKX:"_E(KD^>HB5.YI67@AI[2301 +M0?9&H>5/ZQ1F4&O0K(,;=>)I&$C&,'S#(3[K$S2?#H782MT8$WPD`_``` +M`/P````"````10``^%S-``!`$0``P*@!`<"H`0(!]`'T`.0&R86YF*KQB^TO +M>-U1\H]?K\TN("0(`````P```-PA``#`$RH^@@/Y0+U5>]/Y`^=BW0C)DUIQ +MW(J*K'6:9I2(E4P>.XKSW!K?%@(&YJ\Z^Y1983],\%N +M!AJ)YNV'V)TGVOQ\J??R\R;J(@VX+R'L6I2G<4>H?,]>RFHM;`-?MOQ[WBGW +M2E8V68D64?QO%X>][^B7COG-T>7Z4)`&P```!L +M`````@```$4``&A8*(H=3023_TOJ2=+OF`I#-=A*W1@$""@!L````;`````(```!%``!H +M7,\``$`1``#`J`$!P*@!`@'T`?0`5`8YA;F8JO&+[2]XW5'RCU^OS2X@)"`` +M```#````3"D``#!U9DJTB[0F]8N'L0./_OQKIZ'"@*F8`6`C')F$*DRJ6?=] +M\4T^)&BN=G*W,G82MT8Y'0H`/`$``#P!```"````10`!.%S0``!`$0``P*@! +M`<"H`0(!]`'T`20'"86YF*KQB^TO>-U1\H]?K\TN("0(````!````1PA``$` +MR:6&+?X8'+K/HCHZOX*R=52TS^,0VAQHK=);[)4DG5?VOU+NOI-7&<*)CH-- +MLRS)9LZ:%'1KB_0`@/9U>M/.]U#*G26G2%4QRA8D-RP(<4).\*K`[Y7&[G]$ +MO<&J)&H0Q"@CK)=^@]VLZCI7_1@+>[[\?GN^#CU:A6G^G&#,BVG>)"1FZ]XV"[*F.O-)LM+64^21UNX7@H\M#=I +MB+Y`:,J5?'!U^YT_%.YE0Y24PE"R_.$TQLF7*JST_:483@40R#O2:7*`B#0* +M'(41AZ$GQ"FN8/Y'SENU785M%TKKHS\\?]-P=A*W1OTH"@`<`0``'`$```(` +M``!%``$87-$``$`1``#`J`$!P*@!`@'T`?0!!`?IA;F8JO&+[2]XW5'RCU^O +MS2X@)`@````%````_"$``.!BXO1L1:U8_RMC-W'\O^`8O0C`\]V`0.H69ZL6 +M8$\5;$[\%R8RUC\-IX`@([0_5VWSO!Q_&B-E/J\I:[ +MR?W]K^$5S#DV(E3C[H%D8WV;OQ)*VN)H<+O3QG#L`+/,C<+.RP.6X+#XGFZK +M/?<(0TY^MYQ?;_6M[M`3N+0H%6R\1,II2Q/VI.02,&QXN'/2#7O.M492L-/2 +M4B(C18*OKKE8=A*W1F$Y"@#L````[`````(```!%``#H7-(``$`1``#` +MJ`$!P*@!`@'T`?0`U`:YA;F8JO&+[2]XW5'RCU^OS2X@)"`````$````S"$` +M`+#J].>EN0$54@5P?*M,,P&,VD%#ZB`YV#][S/=;5(;?$)M)PC;-D9L*1)B! +M%].X"M6EIB&(Q.L%[Y`U@-G2X/)R%N]GS?$U\C69@"?OF#<:M7+K +M4\7R4,)CS/L]-.FDZF9%9RIE^&+941>``N%=B!8O.J'^@`,L/'9_=A*W1G)= +M"@#L````[`````(```!%``#H7-4``$`1``#`J`$!P*@!`@'T`?0`U`:YA;F8 +MJO&+[2]XW5'RCU^OS2X@)"`````%````S"$``+`%JWWS=-&QMJ?B)_69%1'$5[V)7<)@2M +M.U>7]"+%RC=MWPPL9H(B7<0$`8$JB*C\^H*+D*J"T%AC3_?`KH#D;7:.` +MG!ZY1L8`=T9NW"MO\UNKI24?&&ML=A*W1H1["@`\`0``/`$```(```!%``$X +M7-8``$`1``#`J`$!P*@!`@'T`?0!)`<)A;F8JO&+[2]XW5'RCU^OS2X@)`@` +M```&```!'"$``0!L+QXQ'$0LE05AK*L(77`8*F/=*5U[6_16ZV'!^?BH%-"8N8_0 +MX_I3[I._MW/PD;6]>WEZA8#+O2ZS8QKO;CIE0B9/Z[,NO5(3Y!KG[:0G+M'X +MT=8GM"AB6NO!0QN1;5>7#!S?* +M5[KN_FTB\E3_UE5!067.C_OQJC("+JN/JY.O&[&QGO4E;7^5H!AV$K=&KH<* +M`!P!```<`0```@```$4``1A_WU6H6(MG\,=81KL+3D-" +M=;GWZ9S@K#2.@N/%,U*I+*D55%H'!P_+GVB:1DJOG=)P90UP_:/]V#R$UWFS +MSA-]?U$D*I>)E^QK$!0CE0O=*>-+.8LHB!X +M;4&0IY8[<]2&&JSG9%XN\AU%Y]BHN]R4W=WT.] +M6:-T#,L:G7D8+DJ$FZ>.BH>'RHH:#?-Z]\;9]&;&5N95;+M/")!3)[BR)9>A +M36EXW`K),1$8/8MT[VB7:_RE?QCK6*^?4+R;1[,U3;W>V#'09):CCJ>CZ'5* +M2%W5A3_EL!SV9A0FEGU+K9X/1IBK)S2#A0%K3%F[:'AD:I31/X]'LHCU.KFE +MUQ$.#4)V$K=&[;D*`.P```#L`````@```$4``.AD44=42W;57]C>49W99R+Z[%Y;7*S`-0O\7I^D>NT!V$K=&Y>`*`(P!``", +M`0```@```$4``8A2[O(E;P0`U*VQ?-,_>@0)@9ITG%[(.F_ +MR9O&T==VG))R(5?,J#I"S(;S"Z&D[OV[8*=TE67B,2..G9'(?U\SHL(!^6`4 +M3H.XK.;)RHHRJUS?XM>9"&V+UX(:(AWF.(P4"81>F7U=CZL!L_/VUGVC&D=: +MT5-42/F>$'W:)4?@&?VH?8O6DN;F[::(AJAZL`*=-^06E#8!<,9)0I/9P!). +MX<10H,FC;L5R8.%,.&X*SC3L(]R]__7>I\H^7V"FO,PN?H1>).5[;%HY<,>D +M$ZU1N476G7JQ1L\SMJ'16]J]-]63RP2AUB_D]N0^*^Q4]3U9'J_I.-Z@A_?7 +MXIVH/R-!J[NJ"S/:!K<-%"M]K64],/AN\J=4*RK]SA1JJ022@B"?=A*W1G`6 +M"P!<`0``7`$```(```!%``%87-P``$`1``#`J`$!P*@!`@'T`?0!1`Z44.[30;,$\WE*,K(#&ZB9Y?$?[R4-Z/'RL::6KQ,X]Q:=U'\U +M)YH2'$Z+_;!\YI/VVB.%=8S9!_Z9LW`++#[Q?^,1VRT1%/TYDP2IIYQM7%EU +M[*,D%:I@J]G'/J_*!%`B'.PWUS1:1,O*HD4ZZ-6DI>>#TJ[&OHRT +MO;+.-(K*\03N@CLC6SVPDMLS?"OG`42DJ"R!5+&.=:1RN;S64*/F?USR$CG\ +M)Y0ZRZ1&!>03'D3"`Z]V[-,82`!=J^L7D@PH7#)F>-Q&Q`AH"7JU[[L*G8W7 +MW[*O[B#OL0UXEHCR0C"[EH$#L222-$N>;U$RNU%)E@Q^$K"XW>[.PO]D)782 +MMT8V/@L`?````'P````"````10``>%S=``!`$0``P*@!`<"H`0(!]`'T`&0& +M26G;1+=L]E@A#)'VVF2M9K@N("4(`````````%PJ``!`G*:%*V*9/641/34Q +MN#-R^X$CCP#Y<3[OM3J/$FH%2TB/+?!FIY^@(.8JI1@\`').8)@P:^4"9>^S +M)E.[=A*W1M))"P!L````;`````(```!%``!H7-X``$`1``#`J`$!P*@!`@'T +M`?0`5`8Y:=M$MVSV6"$,D?;:9*UFN"X@)2``````````3````#"6@+EW+,28 +MF,;ET;^E_MOU>,F,N-%.[(26>8'0I8X$\T)OEQ@>A/E?66*-V'82MT8^60L` +M;````&P````"````10``:%S?``!`$0``P*@!`<"H`0(!]`'T`%0&.6G;1+=L +M]E@A#)'VVF2M9K@N("4(`````0```$PJ```PQL`'>[N&21114.'F6(E)P6X+ +M<,JA`DS^%[D[8I#YNDH1.+KJW:X8]-'H/&1V$K=&EV8+`&P```!L`````@`` +M`$4``&A.$=A*W1A%C#`"8`0``F`$```(```!%``&47.,``$`1 +M``#`J`$!P*@!`@'T`?0!@`=E\BUZ=L4A;B4``````````"$@(@@````````! +M>"(``'@`^`!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``G3ZS5?P[ +M'MV\P_@^<\L.GHDVQ^`8$>R;GAQSKOI7,5@F-ZN^DT>".+',4Q?)6(AT5 +MOJOQ[(UF>9?YI?/>T4W]#'3:,VP1:)/M!NL1DP6'==0I```D7Q=3A^I#N#52 +MKA'C=M9'G'".;5618H0*BLJ>;3@V1I0I```<``!`!$LE24;!&T%#````'```0`7VTOGF!5>C[6TH*X/M:H[HK6(-S'82MT8(<@P`7``` +M`%P````"````10``6%SD``!`$0``P*@!`<"H`0(!]`'T`$0&*?(M>G;%(6XE +M```````````I("(@`````````#P````@``!`!@````>L=_@0,JL]E\,4(]++ +MZVMLX7XDX'82MT8B@@P`N`$``+@!```"````10`!M%SE``!`$0``P*@!`<"H +M`0(!]`'T`:`'A?(M>G;%(6XE```````````I("((`````````9@A```@``!` +M!@````>L=_@0,JL]E\,4(]++ZVMLX7XDX"(``'@```!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``G3ZS5?P['MV\P_@^<\L.GHDVQ^`8$>R;G +MAQSKOI7,5@F-ZN^DT>".+',4Q?)6(AT5OJOQ[(UF>9?YI?/>T4W]#'3:,VP1 +M:)/M!NL1DP6'==0I```D7Q=3A^I#N#52KA'C=M9'G'".;5618H0*BLJ>;3@V +M1I0I```<``!`!$LE24;!&T%#````'```0`7VTOGF!5>C +M[6TH*X/M:H[HK6(-S'82MT9"I@P`4`$``%`!```"````10`!3%SF``!`$0`` +MP*@!`<"H`0(!]`'T`3@''?(M>G;%(6XE4YKR#=O,4R8A("(@`````````3`B +M```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0` +M``(H``"(``(``%=K'D83[2/.JA#7D<%J5^8+&X_.9F2MFCTRJA!IH;A%;++3 +M`8A%-@&?YK%32Q#>2AEHL3?0]'6@WA%9T@1$3`'MF%(-%OT.)5MS.P95U&18 +MOXP\`B,DJ[;`'364SMBS17I8/5;GL[+Q;[#`RE.68Q:4+ZGKA>^6L?'^IJ8Y +M.G-C*0``)(>87B[RT2=:#%GAU#@X/F]K)]]DHPD"I7$<@8Y<4O +M]M4&CYO0M!2$6B!$)KN.P6*J<6GGHV7.NKA">+E7YTY;^%CZV;'_Y\2X1W*] +MF*$C(`%L;/5L!7*=Y;XI;@3\(N+4>(O5CQV\@IN9?$31SN+FJ!:VF!X4%T3T +M])W9HG6/KVQ5`S(:C\U?DW2B+YJS"T5$P\$M5JJ_P2F&/&A;[5T$2B&+9 +M5!Z.USJO2$&VGR9$)_T,<<:K^782MT87[PP`O````+P````"````10``N%SI +M``!`$0``P*@!`<"H`0(!]`'T`*0&B?(M>G;%(6XE4YKR#=O,4R8N(",@```` +M`0```)PD``"`A4GOZ/F#41ULVBQ\%'!<\HUVT);/VVG'BH]`FHNRT8"JY[6H +MF_\Z6^D_'7[$8$`7GRUM*5:@\;2JY<.%O*>4>22\73D7\L7E15*OR#C1&+_E*(?EFA#]-!']E782 +MMT9L#@T`'`$``!P!```"````10`!&%SJ``!`$0``P*@!`<"H`0(!]`'T`00' +MZ?(M>G;%(6XE4YKR#=O,4R8N("0(`````@```/PA``#@R^U;SHZL*T;T;+AI^B-FN""TFFK:!XR]Y_T4@UM^&(K +M('9V1?`Y[E$IGG@(0Z426/KUOQ7F,OZ-33S#`#`I8JD$*7*=4!+Y/W%*G=@6 +ML-"F)5=$6CY[^]=:%P]:809_REG;%(6XE4YKR#=O, +M4R8N("0(`````P```-PA``#`6Y6[&O^2$"F:[70LE'LICBK+@<68W/SMWTFP +M?DZJ,'\)LST6`8)W3J=;^0#E)Z3R$%CSBZ/%W:FJ'.'@:BPE3GD=36)%K^2I +M"`5QN90ZGRDHI-"&!X@[(22#1NU#VON1=Z]V)-6<(M,?0T"+1\G^N]O4IK#- +MV17@/K7Y<^"'9/_3=D%'D00CS;,YXJ(^;620P(U3XF +M=KZ:#'^AZLDLH966`/7Y=A*W1E=`#0!L````;`````(```!%``!H7.T``$`1 +M``#`J`$!P*@!`@'T`?0`5`8Y\BUZ=L4A;B53FO(-V\Q3)BX@)"`````#```` +M3"D``#"[?<]M>[>?)]]:=9+MF'K,;E[IW9JV_[2\OXYNJ5[HJ'I<3"$P)G#: +MX[D25'82MT846PT`/`$``#P!```"````10`!.%SN``!`$0``P*@!`<"H`0(! +M]`'T`20'"?(M>G;%(6XE4YKR#=O,4R8N("0(````!````1PA``$`1=+GQ&,= +MLI)DFL6?#&QPR9N1TUS3_[L2O0X=E2:\KRR,W9HVN7 +M(^]//CBBI'T<-1@:?+'@:7A3>8;P^_/.X;[\0` +MV(NO#%C*5Z;%AE60PYX30I6[7D8>YE`R\Z/94:7R@GAM1Y'@IL2C)?F-!'@F +M&UV`I%^=H2_F0K +M;=4_?P0]F]2+LA?@@$,'O-E>+I.D"_.>S%6?::>>%3FB!@.Y?4H7^KZ"3.JI +MJDB0_1C7['MA$?+,XV"`%#3X+H\:F,ZM&HYV/HM)2%@4%_&:;F3F6Y3@QB*D +MA[_4R=+,GDTB+JRR\>C0A$&8(%XR5+8R9.'WZKI4O2OZ80D630J@8V&'-9Z4 +MA+Q9`56%V$GQ_M"E"NR^7)\ZF!'HF@!N-_XS3^*%BG[DH]48 +M0TZ0-3!",F*ZYM3@/I>CM0SG^J[[TJ"*G^BE#M2L==>HF4M88RVEI/=J%-J5 +MESE$T,51`5D9D2/U?&EM[/,J,Q)#&'C7-3KOQ6!0;63P=A*W1@N:#0#L```` +M[`````(```!%``#H7/$``$`1``#`J`$!P*@!`@'T`?0`U`:Y\BUZ=L4A;B53 +MFO(-V\Q3)BX@)"`````%````S"$``+`^S/7W"91='=#^&9/;0B[8F0Z&*EO@ +MS,:#*/BM\7T$X#^<603,=,_,$=8]%+XU!2[*:X.Y@[3-0A![\WZ59/@I,^@" +M7*\>W);!;9\2TYZ/&*NGVQ.6*W1GSKCY=?0TUGJ'CZ00I5$G(R+C.TFN5A9E +M5=B#GB?=FFWO+H9SJ75,K-Q%\ANEJ=HK>V"^X?G@0/8>ERF@6L/_$5;UD_F%54+2=\N8P/`CK)H>CV$^>FN)SEI:HHEUJJQ2/S^[VNT,BF +MD:,`YX_*(2GLJ`0?"=3Y*=_->C&Y/8429U$:GVCKDF(*O!;8!*D$N3\W59`' +M?52!?UE35NI,0QC?(WY20/.?1K\71TQB`3'7&MT,D:()/FYP7=)ZN*5>*^.X +M``O%4U\'":H&1>RE?7@@B"ZWGY:PT12)(!)A*H'3EPO'4$_?K:<;[;H#"@#J +M=,N06?Y(L?"$\.4:;_9CL8GE/R8HW('R-+.$1>TJ4'UR/(9L^V%](<-,#U@% +ML8@)[V+`C#>J7+$?++:5)S('()E79"6$F%84M;6P95-V$K=&>\,-`!P!```< +M`0```@```$4``1A<\P``0!$``,"H`0'`J`$"`?0!]`$$!^GR+7IVQ2%N)5.: +M\@W;S%,F+B`D"`````<```#\(0``X%J"(D>R_WFI?YIRYVCA/&/KJ'$_KO>& +MW)`$(%FY>(3QX]_,)<9$W+^@64A0.UQ$SNK=5;+8#LM(D4DC+8>#XC8[Y+@S +M:H7*#.5'JA^9QZO6N@0YAP[P[F0B,I)I0.*D1[561&7"=*$`"0/+L[38`@H' +MD8#N#J2QP*QP'6BX>5!NW0![*Z9V""DRHS'%<,_WW]H$J(6V?BJ)S_C-7N?: +M;BYN-850IR:T(Q!_E!"O,M0)6I3;\",[?XWM-JC@-FG'F$3E[\];7G?8V/>/ +M@:18?:YPD'R*6(R]D[IEAWYV$K=&WM(-`.P```#L`````@```$4``.A<]``` +M0!$``,"H`0'`J`$"`?0!]`#4!KGR+7IVQ2%N)5.:\@W;S%,F+B`D(`````8` +M``#,(0``L`#[_`VYXXDH%*#..2;+*Z]7K\U=2UNSC//^-HNJ;?5QL$3;8C8M +M"T%-AU<^4G5D_N5#<=$=71CU@J)X0`P(6RMGUY^1NG?#F]6VS^$=])A.A\_= +MWX-1Z?ES1E3S:Y-!L2T'FU(QU![6U[>7X!4"2.F+7G5!$PMD[4+O#.!]_?RK +MY!W"N'O9:+#1V\QJ!P&MUV +M$K=&Z/0-`.P```#L`````@```$4``.A<]0``0!$``,"H`0'`J`$"`?0!]`#4 +M!KGR+7IVQ2%N)5.:\@W;S%,F+B`D(`````<```#,(0``L-8>&OUTD01,YDEP +M<:_)';^OYADY6Q>@CZD=5EO^"A5I]*PWT7NM.FO`G'9U+-_L)FON>C(AZ^VG +M7;)UP&6^5621V8OGG()Z=/GI`37==%J/VNOW(6/N!,,73<"):3'0OOLA^4,\;Z;>0(J3>5;+O"W +MJMO.!>3J)OQF>I\Y5JKAV$K=&IQL.`(P!``",`0```@`` +M`$4``8A<]@``0!$``,"H`0'`J`$"`?0!]`%T!UGR+7IVQ2%N)5.:\@W;S%,F +M+B`D"`````@```%L(0`!4.A1-W13(5GTV[O3'Z1^@;9*#BZB[7Z4-_+`2@8C +MNVS\+R^Z@R"$,FT_T/EGFFQ""@BER5&JP@,N7W=AUMZ^+UL2`$2HBP4K/T!SMG'2K&;>*N`E54=PTY0N994*(ZQ.; +M.)*M$/#JY4>AD1H#.M//M\8??M`&#=$B_Z&14J'W]'$[CW2GK$BL0\'"%/'& +M?.+JFQ.0A0=0.?7QP3J2M_Y7WO@EH/9X[+VDII]R:Z=!)]/HU9HXL30RM&[, +M&J$`H>_ET5(,*[;]I5P(52OXD1U?8[BQ=OFP`N:5C,C%<6%ET/8'@6>?\0N< +M;:S#GL:`=.M9-.,V\R^N$'0IIU@Q\W0GPS]Q*MDA$!K\QH9L\VDM5%JF]H7: +MT82CTI"@V$&S-T0"A1"@%*_1+!//*ELRZG)YL(7EHTW,=A*W1DM1#@!<`0`` +M7`$```(```!%``%87/<``$`1``#`J`$!P*@!`@'T`?0!1`X"X]8V +MVBBH1G-HF@\X&04R]M,2G$V.;/LH;>5M85>#<4MR[]VKE+[-W,)*8%=//_K[J]R&W4Y;6YQRN]ERNU8PP2GCYSI_/2GXJ +M:.4'G4R@V%31=]HJH,L[JWGBF2/-7+1^5G*9U6A&$TTDM^K+BU)1?N;BM;_C +MA^A<;O)L>XJME*AER%%SX``!`$0``P*@!`<"H`0(!]`'T`&0&2?F%'BB6 +MA?-H%M=N2"$&C(\N("4(`````````%PJ``!`EE*3A#V(<:J+]>R"5;KXK4DZ +MIQ_2'^T,Y!.KI>@"7\&QKRH,6)\-1X1-)QK$DUT-K>SP!"M!FSM?8HR>=A*W +M1LJ)#@!L````;`````(```!%``!H7/D``$`1``#`J`$!P*@!`@'T`?0`5`8Y +M^84>*):%\V@6UVY((0:,CRX@)2``````````3````#"'^ZT*K)VS$:GL:V1` +MCBIN7<&H-=W^F\J300,/ZB5>L-L.+C]@3<+US2?R_G82MT:-F`X`;````&P` +M```"````10``:%SZ``!`$0``P*@!`<"H`0(!]`'T`%0&.?F%'BB6A?-H%M=N +M2"$&C(\N("4(`````0```$PJ```PO*QG=&/R*HD][=SFTE7I`##/^>,78XJ^ +M.._EK(;OT6'^-G;?U_QKN%3`WZEV$K=&-Z8.`&P```!L`````@```$4``&A< +M^P``0!$``,"H`0'`J`$"`?0!]`!4!CGYA1XHEH7S:!;7;D@A!HR/+B`E(``` +M``$```!,````,(B@[OSW#2R\9&J7'@>"(``'@` +M^0!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``*9+[T>>[X[YN]@C/ +M)1/)\S"K%!0K!^+*]*;# +M3BTW!"5W]A\_WWM>)K2`"G3ZIESW>XN>O@A])$C[XIN37]T@-^^Y\:84CQXT +M;'963R)V.D9HY.A4`HD?1>I(=#NB\GC\$<@I```D67FEVB6.]R)&#+'=_7+9 +MA%77MA4$`2]*Y[$$M..-1TLI```<``!`!/_=NL`(3NE=14\\&T*ZQ.6GT\.Z +M````'```0`5[&3'WG''G<2MT9-;P``7````%P````" +M````10``6%S]``!`$0``P*@!`<"H`0(!]`'T`$0&*01Y"_49@LE[```````` +M```I("(@`````````#P````@``!`!@````<#,.(A_,29A':AUQ6>F&F"+-_R +M;'<2MT;7?@``N`$``+@!```"````10`!M%S^``!`$0``P*@!`<"H`0(!]`'T +M`:`'A01Y"_49@LE[```````````I("((`````````9@A```@``!`!@````<# +M,.(A_,29A':AUQ6>F&F"+-_R;"(``'@```!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``*9+[T>>[X[YN]@C/)1/)\S"K%!0K!^+*]*;#3BTW!"5W]A\_WWM>)K2`"G3ZIESW +M>XN>O@A])$C[XIN37]T@-^^Y\:84CQXT;'963R)V.D9HY.A4`HD?1>I(=#NB +M\GC\$<@I```D67FEVB6.]R)&#+'=_7+9A%77MA4$`2]*Y[$$M..-1TLI```< +M``!`!/_=NL`(3NE=14\\&T*ZQ.6GT\.Z````'```0`5[&3'WG''G<2MT;$HP``4`$``%`!```"````10`!3%T!``!`$0``P*@!`<"H +M`0(!]`'T`3@''01Y"_49@LE[+/KZ3]37H!@A("(@`````````3`B```P```` +M+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"( +M``(``&[L8YA[7:+GC^OPB"@00*(R\+W\?V?(A3OEB%!!/5KACO +M01#Y.Y854"9%,VC/LF=?CT-A@6+0#-A,$>;9"T;%T/_E*0`` +M)(>^K/:C0$VT9IY"\S9L32?CTS"D2(M/^K=W?WF!Z'%:*0``'```0`3;LR9^ +ME>-\+I@BAJ,DF&S[-_E4[@```!P``$`%WX!9Y.$X/GHH1/!M93(-R3N*3KMW +M$K=&:=$```P!```,`0```@```$4``0A=`@``0!$``,"H`0'`J`$"`?0!]`#T +M!]D$>0OU&8+)>RSZ^D_4UZ`8+B`C"`````$```#L(P``T)W8SS@\(2#ZH^D0 +MQ@6B[\G=S+!W88*MP5%W!W)OUP2HL5'Y?MTD^#84G3ZN%H#E5`%F+5/G%\A% +M2%[)T'L61AKG#"R%V5N1$V&Y)B)%P\@YIQ5=.MMVA8./C`;D"53DC1ECG22E +M,Q<]P2\?TLS'>:R)GZ^MIJ-.MT((HA8ET@/C,F5"KC1"#''/L(T31F?3935I +MBXI_"V4L-(-TX]O(JNWW]US4?@$76/W>;.A+-9`M7GZX<8F"SE^0)67GWMMY$'^=Q-37AXV-30-BHX_I.!TR&0$E(;-@ +M':)K$['G@S)G4LNK'JRW:EQS1M8@D*:#6PT/+C(KYGE^!I%4Z/2F!^D3Z0`^ +MLY:-/<*]^L`=>G#DJQCAU5D6$$(B^R&'.O(-5@'#I?NHW.N4G'<2MT90"@$` +M'`$``!P!```"````10`!&%T$``!`$0``P*@!`<"H`0(!]`'T`00'Z01Y"_49 +M@LE[+/KZ3]37H!@N("0(`````@```/PA``#@?0$O]LVF\>$$B5&\'\<]^SPK +M@@5;=%N=/NK9"+B9NTA]:4OUN50'>3YR[<)_L7NF)_E_CS36CG:OX;Q!SP\N +MU<''VM%O`#38C*KYP.H)B=1H0":&$23G_PG7"*4?2H9]T`")])VE#N!X-[_( +M(SF=@5)&_F'1>^TDG<$`#Z?^KU^>]SN, +M?>XJP&CXXX2QGA[YQA)]-3FGB17YY7<2MT84%@$`_````/P````"````10`` +M^%T%``!`$0``P*@!`<"H`0(!]`'T`.0&R01Y"_49@LE[+/KZ3]37H!@N("0( +M`````P```-PA``#`U=S!J^FPK>2"KZ`NBK^&[.E1^='+@QKCA5<@W@>H6CY. +MB55OTB-%WF=H8_8"XDJ-T1_9OH&'9(/:Y53$JF311M+`CQYS&T`&@#C_6GEX +M-"LM=+>,,-00WAGEP1\T\>10YF]A&F<1+\MMM)&;CV)4G4QJL)K>N,TF>0X/ +MKA$):V(X)$L:%(@>-_@;Z_F%$+:8=A%D=;-?;,40MCG\Q'A(^E6-6B!4CX5K +MM0,C+SW=(/-\6HI:G.@5LQ4%KO]W$K=&/2$!`&P```!L`````@```$4``&A= +M!@``0!$``,"H`0'`J`$"`?0!]`!4!CD$>0OU&8+)>RSZ^D_4UZ`8+B`D(``` +M``(```!,*0``,/H-CQ7$4JR+(5UP2B_M1[X6I1)+I78")VJ;:A`)1KDT>@KL +MC!"MQJ#F]^QH=Q*W1IX\`0!L````;`````(```!%``!H70<``$`1``#`J`$! +MP*@!`@'T`?0`5`8Y!'D+]1F"R7LL^OI/U->@&"X@)"`````#````3"D``#"L +MM-!X5ZFJ>]1!TZ5M1A@S?=SG'%_6(IE*8+=F9SJG:@.^YMMM`_UW'<@V-W<2 +MMT915P$`/`$``#P!```"````10`!.%T(``!`$0``P*@!`<"H`0(!]`'T`20' +M"01Y"_49@LE[+/KZ3]37H!@N("0(````!````1PA``$`+(X4,E?!XJ+N)4GK +MG"FFW_!Z'K'`G^Y1%C2L+/&"=4A)QLP)\/'8S9\#-M\C'6JGV&H00>FR261V +MMZ*L5I?^V;;4;38879BZ6G,X"O[^(@P#8_9R+>>NIO1[Q5L3LTUKJ]V#ASO6 +M+FHO.S-84RWJGE3`1>'X=,E`OAJ4"LTWV[OC)LXZNK1]-3'$UP,%@?<%D


+(MA/N)4^UM&3?XUGTD;N6\1M2=*Y'_:H1V>KE2WM\#W?/FQB +M.-LAR%@&"X@)`@````%```` +M_"$``.!TZSWDC<"DONOSNJF&+3:MQ1X$#[$=?!;0*:Y-QE-#!6+*LR_XW@R3 +M)5(5]JE:G[_3-?2`J<(I7^B=>:WCKV`O/!A,H0GNM(0H+5,P9_T4/!4O,CTL +M5Y(L-8@OY(4Y<@=FK(0]_T881I"^+HCC-[66.76KT^7(Z.;RH)UO)?/*%FI> +M04N@&"X@)"`````$````S"$``+!J2X,7ZNNC3J2G +M/-?L]U8+M/>8,`9O-*2G2$=4JH%2!V3F6WAW@C-QEH/E>>[GMZ^I14\(_:I) +MO:C7H;%SJ)36F5`02_N9<^U[%>3PK79QV(;VC"P=-8D^J\(5`0#L````[`````(` +M``!%``#H70L``$`1``#`J`$!P*@!`@'T`?0`U`:Y!'D+]1F"R7LL^OI/U->@ +M&"X@)"`````%````S"$``+#^:1C!^68T["SW*\E+WRA8O*?Q!4TQ1D +M+3\/]%9.Y.WI'"ZDM.%P'E,[-OT>0,.^0KK>?S,MXS2+G?*("XP\I!V(K/)_ +M6N.M.[-E]$+,X3>G(GR#[X=(&<)8?`518[^`4`.&Z +ME'J^:"7]R!Q,+HGBK?2%+U"CSQ@3=V!<];875NDDJ8D>$T!$4GNXJ^ +M,8RZ=]1[L$\F=Q*W1C&S`0`\`0``/`$```(```!%``$X70P``$`1``#`J`$! +MP*@!`@'T`?0!)`<)!'D+]1F"R7LL^OI/U->@&"X@)`@````&```!'"$``0!1 +MRLL-+%=(`D_LQH(@1MT^@>[*$<5+7L_QPV8URN]7W-X27!R@UW$K=&Q+X!`!P!```<`0```@`` +M`$4``1A=#0``0!$``,"H`0'`J`$"`?0!]`$$!^D$>0OU&8+)>RSZ^D_4UZ`8 +M+B`D"`````<```#\(0``X`2D01`'TPIKGD+H9L2:F83_QOQ#A-'QH!YC)W_D +M/Z%P*.-F+,(6>%^?_BG27`0OU&8+)>RSZ^D_4UZ`8+B`D(`````8```#,(0`` +ML!!IUWI-6G,9#&#(M5!OL+G6XY*EL^\1/[K7V2URV%]O_][,&!!JC2KO>G&` +MF&/#)G\N-[.VR&.L-&E;LXRY']W%8FA[D6@\0'L=G^[/D-(HOL9=X^LIRG>K +M,GEE`RVA0.NV^5Z\GN)HS1HI3Y@(_$;ETU%8,:YE,IL\P5U"I)\BC_&&4H&" +M:PVQRLX:.7:AYE1#'+>N1%5QB>[X_EP4L6T!%I$]_K#=E'+V!69W$K=&%O$! +M`.P```#L`````@```$4``.A=#P``0!$``,"H`0'`J`$"`?0!]`#4!KD$>0OU +M&8+)>RSZ^D_4UZ`8+B`D(`````<```#,(0``L!D$:KM;#_T@<83'!(]']FIQ +MM[<]7JV#9?3M^<5^C:2QA^ +M#$OGI*?/ZH^(?L(7P<;;07[6,EW$K=&(!<"`(P!``",`0```@```$4``8A= +M$```0!$``,"H`0'`J`$"`?0!]`%T!UD$>0OU&8+)>RSZ^D_4UZ`8+B`D"``` +M``@```%L(0`!4`]^'RT)D\G)/ST$GW:/8?9:*6ENK[HC-L!]H,4K:GUV*X1G +M2FE7D#N)=K6)$N$/=P,;."%)EOJVK0;;(>*8H_+96L5$PXW*6Z.2861L;=6P9O"(>]N4\>"K$)[`=E-6:D6+I78W>0'AV$1`\21AEQSP'0KN$]F#_ +M5BDGUZH"3WINFEXZ)%&/5N7/9^1J\MNHF^6YB*F)`>C.A4%S_(W?WJ`-1R78 +MG7=S.7J^!2^`AO+%U[:FQ8542^W/A$,82O\%QQM-`P]C6O%+T;95HBM/6+)W +M,O0U9'N#;5KF`^5_=.A45N."8W)U.Z;YWW^H\K828>?>SI9MOSF3I*N('ZV` +M.<6%\K@ +M&"X@)"`````(```!/"$``2!`I1L=2./DXV3!1%G/GK8 +M"$!381/QFHQ\,0;5L!S)%GLNT2_OLM4MZAP:WIW3`%Y#-WN_,&/]AC:.:]/? +MV+W:O02^YMML),2-+Q^._/>+AEFBFKN-\BOI8IY=GH(F"I#>&IP\E4+'$V5L +M$2",Z%QG::,W>]\R^2#9)"8GX][KR%JQE&5JB_3+]G2"N1*2G7V`.G+3L8S_ +M:G$.0TND7[JR!4)%A%`//ENHO4M$H\%"441A4:1E&J2V<.1Z/D?0>+."17/0 +M+U/(_UJHU.E<&_^4&E_`_$6-:L+"B\.#FX[@2_V/J#<,X#Z(TW^V*:[T'Y1' +M;H?T.<;T,I/-*(P^N@WP9.S18(:"UF`5+K*UDVN9''<2MT9+<@(`?````'P` +M```"````10``>%T2``!`$0``P*@!`<"H`0(!]`'T`&0&2:/:)98@#8RI]29U +M'!(%VZ4N("4(`````````%PJ``!`]HT!GDLJP!OV=OK,*5LT#P"91G$O_I!F8G9=Q*W1J1]`@!L +M````;`````(```!%``!H71,``$`1``#`J`$!P*@!`@'T`?0`5`8YH]HEEB`- +MC*GU)G4<$@7;I2X@)2``````````3````##6\_NB`";P+BYZWAT,=_X!UHM7 +MHN;I(B?P5#D-F*HXMVDFHBP:.*FQ24#O4'<2MT9&C0(`;````&P````"```` +M10``:%T4``!`$0``P*@!`<"H`0(!]`'T`%0&.:/:)98@#8RI]29U'!(%VZ4N +M("4(`````0```$PJ```PA+*_@``JA<&(I7 +M1LXIRF-+A.&2],;BOFAW$K=&8)L"`&P```!L`````@```$4``&A=%0``0!$` +M`,"H`0'`J`$"`?0!]`!4!CFCVB66(`V,J?4F=1P2!=NE+B`E(`````$```!, +M````,+%A_BBL-(W7!MQA)B7LNQ1B1%$:-C3_/^U*D=[0R+H^HP.%.B-^^A6T +MS0R2=Q*W1G^5`P"8`0``F`$```(```!%``&4718``$`1``#`J`$!P*@!`@'T +M`?0!@`=E.IE7L0C7^U,``````````"$@(@@````````!>"(``'@`_`!T`0$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``X&H:#Y"Q0'UT7$%<:N9_Z\2E +MWQ58-(=,)87RAJ,HY'D[.UI<'ZK0%,&16W'#2$<2&WQW#<_1RNA"K\M*%Z%A +M/!3,-]5),V_N"F'PSSS.X[J+-,8%O!"A*KYK_:[5B6B7VJ+*:E@FMF1@CMM? +MU^^$WA_`V3J0FST.63/L7_J9U/DI```DJ$SC1:]:4*I(Z74W1=SXQGUS.$Y>>'!K':2VZ<7FAR````'``` +M0`7V3Q9]T_;BE7%76!2LY'<2MT9F +MM`,`N`$``+@!```"````10`!M%T8``!`$0``P*@!`<"H`0(!]`'T`:`'A3J9 +M5[$(U_M3```````````I("((`````````9@A```@``!`!@````9]T_;BE7%76!2LY"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``X&H:#Y"Q0'UT7$%<:N9_Z\2EWQ58-(=,)87RAJ,HY'D[.UI<'ZK0 +M%,&16W'#2$<2&WQW#<_1RNA"K\M*%Z%A/!3,-]5),V_N"F'PSSS.X[J+-,8% +MO!"A*KYK_:[5B6B7VJ+*:E@FMF1@CMM?U^^$WA_`V3J0FST.63/L7_J9U/DI +M```DJ$SC1:]:4*I(Z74W1=SXQGUS.$Y>>'!K':2VZ<7FAR````'```0`7V3QV0,`4`$``%`!```"````10`!3%T9``!`$0``P*@!`<"H`0(!]`'T +M`3@''3J95[$(U_M332IKB'"KJ]PA("(@`````````3`B```P````+`$!``0# +M```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``*-- +MSJ+?1>#J\`@(V/4`(XO22[0$W]GC9@")X"D"KIN66UMXQ7?6*!?4U"_$!SA= +M7C:*6,./C.^>H:F:\H.XOYP,U+1(3>.ED,D5W60X?%Z3J3Y64J0%8//0/Z)@&?\]`#FUW$K=&XP8$ +M``P!```,`0```@```$4``0A=&@``0!$``,"H`0'`J`$"`?0!]`#T!]DZF5>Q +M"-?[4TTJ:XAPJZO<+B`C"`````$```#L(P``T&V[M4IW\5MZE&IKB<4CN4N? +M6=!K(%F@!"O[3MWZEJ_JZ`)+Q%@;B4D`%KNZT5@Y1^1LPIN9U'0SXJAZ9'Y? +MS&14%O#\?ZN/G,`;YW;+AS16,STKP#JK65D_KX8^I!T0>H39M-P1Q:O0C@RM +M8(_Q#C&-*JG-2[TXH?'7"Y\Y'L7BA#8*&NU8,2GI98F09/^1G`RZG;IF\!G2 +M]`;C!D:ZKA1E=W:R^9=<_NTQIJZW5MR09C--@F_3BHZW$NFM%=6W"J$D;L^1 +M:RU!XD[.^7<2MT;5'P0`O````+P````"````10``N%T;``!`$0``P*@!`<"H +M`0(!]`'T`*0&B3J95[$(U_M332IKB'"KJ]PN(",@`````0```)PD``"`#^Y: +M35#J[YR=7W<"7?%1TA.]VQNO0'.=[WDLH.CC.COE3`X?[;B:& +MB=$BTL1W5[*Q__N@].[R0&P/WSE?D7Q!+WO#J#!/N^;_D):WZ,;1E3M>'M_) +MC/MK1@[BI:?JXIJJ&-&[K2[>ME78/E1\$=Y`E$8PHG<2MT:*/@0`'`$``!P! +M```"````10`!&%T<``!`$0``P*@!`<"H`0(!]`'T`00'Z3J95[$(U_M332IK +MB'"KJ]PN("0(`````@```/PA``#@T4E`AA&\9I;]OD0\23'=#1S+K4BJ:Y`= +M)BU@BGCC23$*"(7SZ'NG]6@JBQC11.!#;#D.RY]L&"M[#\&!YJ4VL*J-H'.'T-VHV:G>Y`;D_1?"URZJ"\ +M^)`Q(OPZ:72=;RR=H[50.!: +M*06'M"HJILK9WK$C!`*3A`2DL#2V&\4!L^,;UI\PO"LW6:014X3+3CH2M'=8 +MH/^^QLTRZ8B[>$?&_@SMLC?!<-*5*N-_,X&*B=K06 +MDSBI2NQIB48RS\?W3+KA_O/_FO2 +MRT-#9541Y)7D_P:4[TMW$K=&8E4$`&P```!L`````@```$4``&A='@``0!$` +M`,"H`0'`J`$"`?0!]`!4!CDZF5>Q"-?[4TTJ:XAPJZO<+B`D(`````(```!, +M*0``,,9_-:?SH8?2CH@@D3I@)B!%A,--]S$=<6'K!]#DB*=4E4`3_\=&7&#K +MVIT-=Q*W1B%Q!`!L````;`````(```!%``!H71\``$`1``#`J`$!P*@!`@'T +M`?0`5`8Y.IE7L0C7^U--*FN(<*NKW"X@)"`````#````3"D``#`+*(S90KZG +MS,TXR"UD0G1H$V`(Q_3T:4:_N%`!_6G*E?H/O(`HV>INWY`.[27YO8G'JSEVW+.(]JGUP/B?O/`X4VLQ^6=!IWO)']PD[%.>S`WA[!@,_W! +M0U9:\&/+2E[>302M`,7^6/MN%:A8`^=FTI=1*U'F2:5N)ZZ-$I9:"4,MS-O3 +ME=I"6TDQY(_.=Q*W1M67!``<`0``'`$```(```!%``$872$``$`1``#`J`$! +MP*@!`@'T`?0!!`?I.IE7L0C7^U--*FN(<*NKW"X@)`@````%````_"$``.`K +MM!$.1#;G"ZA*]P[KSJN>2>8=0]5&VI?IYMS25Z@:ZJA@0$XSHX6%K^%&N@V\>_^X$)#+Q.+IL+L&TBQM]\J*().``'* +M6/P=SYN'-$<,^:KJ86?QRWN?C:%X77)];80H1N5=;KU]/LD_?FTL=Q*W1HRG +M!`#L````[`````(```!%``#H72(``$`1``#`J`$!P*@!`@'T`?0`U`:Y.IE7 +ML0C7^U--*FN(<*NKW"X@)"`````$````S"$``+#X(V(Z.#]Z:G.U0Q3S^)`' +M3`>^\..*'_I?0R,?+&^DB4@,IP(AS-8FFW;%SANMPXZR*@*&N^NJS4%[+>T9 +M3`,O9\]OJW)0WNNNYAJ/LXJJB&P;D9F4<:8'NII;!-S +MG"AE8Y]9GBT^0`%]XJ20H,UPM!G/V@;JX:IQEG+\4"X5S/=J^[[8#271J#M\ +ML.MW6E6.DHM5I)JC<4>W8#PA@QX-=Q*W1I/*!`#L````[`````(```!%``#H +M72,``$`1``#`J`$!P*@!`@'T`?0`U`:Y.IE7L0C7^U--*FN(<*NKW"X@)"`` +M```%````S"$``+!Y[P+<812()+0&`TN$2/(&)=``."+;NE-P$C*/-DNRFUMT +MCK*7`*;7G&]LUAX]+&@FNBCZK*X`(W9QBM9K@),X^9ZNSL0G5*`7;VTE3"8V +M'V4`CPR3'#NZY@(4P#_;F&N&*N.E4^F[+*/@C'E[_Q#GV>JT"F$STVE=7#^U +M-38;Z:%%0*'G!M*=E$PS4GDZN)+WD](<&DN>A#VU4;_DM +MG]X+=Q*W1H#G!``\`0``/`$```(```!%``$X720``$`1``#`J`$!P*@!`@'T +M`?0!)`<).IE7L0C7^U--*FN(<*NKW"X@)`@````&```!'"$``0!8OLR2S/PG +M+FW%=#Z-;WV&.)<^!5_%^);@$-EA=$F,\=Q,M*.;=GM#[U-\;5XY!P_NCNQ; +MM_^$&82`S^7#UL<'"Z+_6*,J<:7.L`C8-_CNN!U96]$C,8AELY/S'2D<<'5; +M&.JK&&0F;UW"G_/'*@(>Z^X?/M#3D3OQ4S(>98N$.0E/HUK1QCW0F7\!17O_ +M%U']DG^&]YW6A3[#CO[B)->S'G?4]!@+#?B!=M2$JR]P!Z&?44Q.[?UQ\0,] +M70'K5QPTBEC`;X<,U_S&[T*O>>2^_!8$;:`NIP)AU?#A9/0GL&VT\.&ZM1#\ +M-5(GF/X-`6HA`A_57/!;S%P-DM=W$K=&WO($`!P!```<`0```@```$4``1A= +M)0``0!$``,"H`0'`J`$"`?0!]`$$!^DZF5>Q"-?[4TTJ:XAPJZO<+B`D"``` +M``<```#\(0``X,T>E,,A]CT8T%3Z0\H$(F>U4FRZRHL&,4V20<5V\8;,'`]) +MFZ_EV(J42_(2<;@5O4[YJ=O>RH`E*:8EQDK]5K./+!:KW>$HKT'/<":ALEF\?A'0TOR.-V?N';$&:R;6)TCW)/J,'MTA +M;XG4+_/YT\NT-P])3+)50S['*U1?70MIZ4<*KC4.B!1<9D^9&^KZ9SPIA5", +MAELL?KK43LH3Q(-R*\6$"A#O\/`9/BTNWAVX$C<*8ZJ_U4?Q\@F3V;.7]]0D +MX2XC]6)W$K=&K@,%`.P```#L`````@```$4``.A=)@``0!$``,"H`0'`J`$" +M`?0!]`#4!KDZF5>Q"-?[4TTJ:XAPJZO<+B`D(`````8```#,(0``L/_IZE[= +M"_,^V.CKVSH/ZNQ"-?[4TTJ +M:XAPJZO<+B`D(`````<```#,(0``L$`DNSA`O$UGFUMORQ9.GNSO +M8-,P?]3>EWG`&@CCQMM6FC;E;(`'S>2-$/E[^Z8?("5)9(<1;VOHW.TNRR\' +MU1L-^&A?6ZE%CV<\+"F_PZ!2E=H+8Q%9.9H7Z1\&^$.U];%)I+[S)`Y%U(3A +M0<>7M$)>?BS'QFC6,8IW$K=&&$T%`(P!``",`0```@```$4``8A=*```0!$` +M`,"H`0'`J`$"`?0!]`%T!UDZF5>Q"-?[4TTJ:XAPJZO<+B`D"`````@```%L +M(0`!4&KXG5NHRS1562Z/]:8DD+'Y= +MV)URD54N?Q#)"CS:O"F[S7\(P=0+9%A5AP?K@UD43J<6B-!I*V$NZ.-$F3TH +MD[!"BYR9@'5[T$RO6:_%A#CAC0I5^'$4'&>HG,_ML"=%SNOQX[("F)#6"1:/ +MJ58G<"Z0:T1P^I.+_#/-7%( +MR!RL9%W43N._L"EQG3GCN>PO]+0GS99K!<_]M1*&%RF,C;("Q^EK2G`DJR03 +MO9Z\WGSNK&IF/"6:A=Q*W1A6!!0!<`0``7`$```(```!%``%8 +M72D``$`1``#`J`$!P*@!`@'T`?0!1`^D/O27E0066?-%"W_\,)E6F'Q/YC@O7MOODL +MI4)=Z-8L=TQ$P$PG6[/?`Y1%$><5ML9!9^SA+1`>K%01TAF9E!'8I].U_XF& +M9T%#V2A"_71L4[H&;()F^A;5&'-57[0_QKI2-89'KL:BEAQ"$:."45,DW@_4 +MV!4,(/.3XN9H9HCG!/!&>K-24)#EAK0"D2>R)C$^)]@'&#!Y^4C\2#+R0D9K +ME\Z)M[O<8\EK,*)ZWP>OP7?Z7/W0?G3'?*?-@1<.`1-+<'[38OEJWU/5CD8` +MA)'SN@A:/)?71`6E*#BO)4X'<2MT;.IP4`?````'P````"```` +M10``>%TJ``!`$0``P*@!`<"H`0(!]`'T`&0&22P@A_#,J%V4\X>2G,&RX@)2``````````3````##QONAM2(;PY/N*()7VC[:?J-5Y[`^8$*YY +MX._=V&0?(2G,&H +M@)V\G(:V(\IW$K=&]LX%`&P```!L`````@```$4``&A=+0``0!$``,"H`0'` +MJ`$"`?0!]`!4!CDL((?PS*A=E/.'DIS!G*E[+B`E(`````$```!,````,-M@ +M)@%<7!((VT`X7['"54-/\ZZP=:5N2&69<`J7"(``'@`_0!T`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``I"(J3Y;`,G-?B=--3 +M7Z9.)9E]+#7=;Y/2('G!SVO,%7LL=5,2C6+$QD/'I`-CN;6A<0Q!I01/VMWQ +M)5H%>MDE/K*:\[TG(SPI```D_+*:F+6[7KOEO7>7/&@?R-I'_6J:#3)`8_HS9RZJ3G<2MT8X[P8`N`$` +M`+@!```"````10`!M%TU``!`$0``P*@!`<"H`0(!]`'T`:`'A8,AU6P+BI=3 +M```````````I("((`````````9@A```@``!`!@````>7/&@?R-I'_6J:#3)` +M8_HS9RZJ3B(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MI"(J3Y;`,G-?B=--37Z9.)9E]+#7=;Y/2('G!SVO,%7LL +M=5,2C6+$QD/'I`-CN;6A<0Q!I01/VMWQ)5H%>MDE/K*:\[TG(SPI```D_+*: +MF+6[7KOEO7>'K;; +M&JJ5O)82S!>Q5^RT"OV"GDJ5RL+JEK0!==VU_F\K0?3F(Y8.S+<2W,^Y;@SS +M"IWALI/.IE\?^:J\!A7S88;6OFY(.K1;O.Z]6&M[I#SKS0+6_<+-M'F24M9!W?+L=S@E01A9 +MB*2A!!&..(H0N"/30LJX;VD921O@(^!<\2O=NT016,;G<2MT8`>0<`'`$``!P!```"```` +M10`!&%TY``!`$0``P*@!`<"H`0(!]`'T`00'Z8,AU6P+BI=3$L$TB[F@QL0N +M("0(`````@```/PA``#@UM)YQUH^*4]S[+]Y@/PDIDMQR+@%[PI\T<`RGPDI +MAU_G-![M6[DT,N=\F1+\`2G.]=[T3^WF8\>5)_LNF!?SE?7FY^GAC,;B%O"V;[F,OZ10=E`+F?ZVHA1>9W1<=^`PPDF8(VM@1%3@ +M24Q#.,D`2U6S5W<2MT8-A@<`_````/P````"````10``^%TZ``!`$0``P*@! +M`<"H`0(!]`'T`.0&R8,AU6P+BI=3$L$TB[F@QL0N("0(`````P```-PA``#` +MM#N)RW1"=W,I>PA8;<@+F@!BE63PA,G&J>-L_$C>(\(PN[^/^,HLDK+:]&._ +M5#;70J+&=X3,8][-X$@MC:.OM6=V3TN@)X.+Y3P%"#`/!!C5T+B%OGOGLIR\ +M0K[PKM:LWNCN]*T^FC!]2LJIR]QK(%&?>F@IXKF +MK]SLC1BG\;9W$K=&Y8\'`&P```!L`````@```$4``&A=.P``0!$``,"H`0'` +MJ`$"`?0!]`!4!CF#(=5L"XJ74Q+!-(NYH,;$+B`D(`````(```!,*0``,'&$ +M(+CO=:.\:`)EB"Q#`A^@+NP&GS]R<:JD`D>@S<0LX\G=8X.M)HD1HC]X=Q*W +M1NJK!P!L````;`````(```!%``!H73P``$`1``#`J`$!P*@!`@'T`?0`5`8Y +M@R'5;`N*EU,2P32+N:#&Q"X@)"`````#````3"D``#!0#,6[[U\E6IQ&FOP- +M$]O[6Q1_/BV45O(Y6N^Q7^&2G@'U;/2?&4RI<;7[@G<2MT9\R`<`/`$``#P! +M```"````10`!.%T_``!`$0``P*@!`<"H`0(!]`'T`20'"8,AU6P+BI=3$L$T +MB[F@QL0N("0(````!````1PA``$`AMT[,%;ZUA^/V0%N4W_,,ZNO'7]-LP7W +MZ(,LX\*`=Z>'\L2+!4:7GSX'2HITJ`TXA]CW6GQ0L,WLS!(_ABM(TLQ.-<*"@J,OS),AQ6QW*#+G52NH!38N$:20I58QTHA54>$E\ +M_OJAD8X!\8PD$!:[,\M7K5.G&RDT%=VE<6.P/&P@8HA.K:0&^$MHHI3(F&75 +MGLHWMG.@/-4Z+Y#R!F%-)_F):].$+4?;B32O7+^!+6/>?R8+,*L\JUAEX_N% +M5X2RA`CGN>$Q)SH8=AD3$G#I=)HT_6V9R0BNRP(7&GP-7C_'`^1SD,(C',V1 +M">1@=Q*W1D[4!P`<`0``'`$```(```!%``$874```$`1``#`J`$!P*@!`@'T +M`?0!!`?I@R'5;`N*EU,2P32+N:#&Q"X@)`@````%````_"$``.#7SR=VB\3[ +MY%U_!J7Y@%GP6#Q7KBQ+B]"B\^L^^[<3XRY7O:;54:71Q_9,770XA5_(4B\M`3X6%_-5'UHA[.T@P;%)^D\`B>DT#$O +M^O=0"H)QD[G.;,@?(-%"W0>,LQLG6Y7N[(VN-;LI?ABYRVLZW(6H:L'!S<41 +M*TI-2X:LCE63F4]R`9$\!?$>*+V=FR.]VW'`'99.G`^Z,1N(MCJ]++*H?9>'Y,RH"<6,*#_Z*2+,ZJ4,WMC(E39AC +M#O4424FJ>P"M5SK_AQ&#Z*A'*6D`/%#SA*>^S_2]YV%@X#2_$9BZ7'P=H)6? +MN.@2%-G/65<&7<;Z+&C.E4HC1D./=Q*W1I@+"`#L````[`````(```!%``#H74(``$`1 +M``#`J`$!P*@!`@'T`?0`U`:Y@R'5;`N*EU,2P32+N:#&Q"X@)"`````%```` +MS"$``+")?,>".#LHTGV#"Z=\&(')/)'FB>*]3G-NHAHF7T]>G@6WEJW3QQF@ +MH1W8"V=L9>2ZO`K +MC[D*FCL!BCO%UKF$?8?*@U@*E;]K&G?9LM=4'?\4ZOUK"QIAX7@Q?D96=Q*W +M1@$I"``\`0``/`$```(```!%``$X74,``$`1``#`J`$!P*@!`@'T`?0!)`<) +M@R'5;`N*EU,2P32+N:#&Q"X@)`@````&```!'"$``0`Y7*)]APN!QCN/TB3] +M+J>(X.JDSC1)PL4W[!-+?+D8?QB:$+2]07^[3Z;X&G([;A0F-L)OEA>A&28V +M?#=6^1EY>C*2^2+N#>AYHZ:.S,S+!UP9]:/VAO?;8SH?)/E%(/ +MCJTS>XTZ"O@@CA^#RB'LG%$D[W +M=BQI%ZDK6\=$XH&P>4[5/=T#-7AU$/8P^#-#=0IG86.2-D0#SWJ>[Z[L^/;N.!)J +MHI9"73."Z'YX\WQ,"F)W$K=&(C,(`!P!```<`0```@```$4``1A=1```0!$` +M`,"H`0'`J`$"`?0!]`$$!^F#(=5L"XJ74Q+!-(NYH,;$+B`D"`````<```#\ +M(0``X$ML>/0+"*I.R6%[K5M67VEAH6_I^_U#RSYIB)M-Y3$3S-AZ*Z%^%?_5 +MQB2GKO-9\M4EQZK#+(TW`Y+W"G>)MKP&_:=B*B_1J?/Y?B3H6`5^'8],[";) +M/%(+-RR`;'_JX?/%X?,\48WBP&&639J4H754L\G>0L45OR<#T>90>B"O&U;N +MV-+0I/XT_M91DS$H[$\%4>'4S_U2`W)`E]F75'(+3!Z=X?@NLXIDY2L$7Q^6 +M[;&W8$?R%<>R?O;V1L,A;;6IH`!CH)#K,WPB2Y3IJ@KT4#OA."SH[6-MD$!W +M$K=&,40(`.P```#L`````@```$4``.A=10``0!$``,"H`0'`J`$"`?0!]`#4 +M!KF#(=5L"XJ74Q+!-(NYH,;$+B`D(`````8```#,(0``L+@%GN"IP$+/5@AP +M6FWMBWM-YZ(2,9P(0(,PS5TA42&<>(1FY4D6@J2QO_-(ML*&-Z^"J08J4*I%=TR)9!^B*/6X'^ +M%@B>^0*5E@7H4-5*='60.U>>WYCG4R"&Y7:F +MV'P9GIM[+*!W$K=&Y8P(`(P!``",`0```@```$4``8A=1P``0!$``,"H`0'` +MJ`$"`?0!]`%T!UF#(=5L"XJ74Q+!-(NYH,;$+B`D"`````@```%L(0`!4%C( +MZ7>%-X3\V\EEKR)-Z:6ARPQQ^W2_XQ7+GU-C'4$I%7MTNN5W]&OPU^O;0=;& +MO@1%;O2;4V$L6&LOPQ[7P--YG6X0!R?[[,_?B\"[G+?#I@MH/P@_.::5AJ\B +M>CNP,_\I!L8$FI+)&3&7=95JWDT]HQ#&"Y1?6)D=#;]J[`41,7@,^$`FY)C* +M1+&KS@\-3BTWE6%-DQ>XZISMCHU=&J+:UT.G_79.$[_2`/M*:+LB6C45+0Q= +MT`5'*MYQZX\6BLZ%.W#?2)UZN%"%DYL?731#U>*YM7D7R*AC'^?/OJI0;@:C +MR38E<7X-NYC1E^$:NT5(="VYC`]YWOSY4C"S?8H?BNQNIN#]/]SKU2_:D>@U +M6>W2M.ZR&V@G`"G3]!3OO@6&WPNV$;G^@@NI]2*04+;(\81Y(BBU&G(M;8;] +M#44[-I2QJ67MDNPDYQ!<=Q*W1@[!"`!<`0``7`$```(```!%``%874@``$`1 +M``#`J`$!P*@!`@'T`?0!1`711(0%SH-PLP`*B\@7.+9I@F26*/I$9\ +MI@G71#DW8Q>`)"1BL/ICN"JWF'<284"?+V_<3^HCF>WN\0LK(U>";:V?;JW3 +M<`"%U) +M``!`$0``P*@!`<"H`0(!]`'T`&0&29:U$1D/QPD2PQ?,*99]%%,N("4(```` +M`````%PJ``!`[ET^>0B\4+BCIZ?X!OOBN(LB'K*5Z:"5*U&)WP]^,'G,I3_* +M:')>W[5L7=9+;YVR5%%L*ZDSLH'D_8J1=Q*W1FOT"`!L````;`````(```!% +M``!H74H``$`1``#`J`$!P*@!`@'T`?0`5`8YEK41&0_'"1+#%\PIEGT44RX@ +M)2``````````3````##8E39[$S62B%OTJW2W+C3YDAVQG:^IEH<]^?Z(9[88 +M^Z3K=;\1U^05M[]Z87<2MT9!`PD`;````&P````"````10``:%U+``!`$0`` +MP*@!`<"H`0(!]`'T`%0&.9:U$1D/QPD2PQ?,*99]%%,N("4(`````0```$PJ +M```PZ)8.36G(IDOT^:$TQB4/7@"_[6,]-7I4.SW*Q'9FH,I35-[N47"ZIB6& +MA*AW$K=&=!`)`&P```!L`````@```$4``&A=3```0!$``,"H`0'`J`$"`?0! +M]`!4!CF6M1$9#\<)$L,7S"F6?113+B`E(`````$```!,````,*MD;0I&HN'8 +M*J^D"3#]-3^X2N +M39(``````````"$@(@@````````!>"(``'@`_@!T`0$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``FFDE^C413*Y^R6[%J)+<@Q*/BD+ML.0E&E/[ENX+ +MCFR!?0$\5`*M6+^F(L(:;&N.&YQ:&3G.@!JY>W18'U$X&W&>?22KLBFX +M47CM?6)C:%J!_(&.\(!PG;'\S^B->/Q?2JI).NUUJH?G4E-UU7:-5(#V7V#^ +MW%#BWP%5X((I```D"G-LS7V?S1\_-DS6N9D((519;[4Q?MH03+OQ_ZUI_@@I +M```<``!`!#!?$3R+494;IYB"Z:,IO[(5Y(YR````'```0`4)1PE0U]"GV3+P +MY\P4#2,X_]*9J7<2MT;D&0H`7````%P````"````10``6%U.``!`$0``P*@! +M`<"H`0(!]`'T`$0&*5@'D_N$KDV2```````````I("(@`````````#P````@ +M``!`!@````+^F(L(:;&N. +M&YQ:&3G.@!JY>W18'U$X&W&>?22KLBFX47CM?6)C:%J!_(&.\(!PG;'\S^B- +M>/Q?2JI).NUUJH?G4E-UU7:-5(#V7V#^W%#BWP%5X((I```D"G-LS7V?S1\_ +M-DS6N9D((519;[4Q?MH03+OQ_ZUI_@@I```<``!`!#!?$3R+494;IYB"Z:,I +MO[(5Y(YR````'```0`4)1PE0U]"GV3+PY\P4#2,X_]*9J7<2MT8M3@H`4`$` +M`%`!```"````10`!3%U1``!`$0``P*@!`<"H`0(!]`'T`3@''5@'D_N$KDV2 +M(WWM2&>[D]PA("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`# +M```(`@```@,```@#```"````"`0```(H``"(``(``+J6Y%M.53D17EP=/:X( +M\,Z,IR+;=5@AD\LVYNOP-A?==+B`?9&CG0EE:JT<2"FVA#RO&<4IW>Z:<84-@@C#D``D6YW$K=&,'P*``P!```,`0```@`` +M`$4``0A=4@``0!$``,"H`0'`J`$"`?0!]`#T!]E8!Y/[A*Y-DB-][4AGNY/< +M+B`C"`````$```#L(P``T"I4(JP)LWD"M[4)L!CX-L;*U6&#>O*;ZZ39W=S9.%O7#OZ]05V(=UEQAPT3J7/NK'8H6-!>[\$H(IY*"] +MTN:(+W;[5I"D%TQ6`/YG>*5Z;K$(`Z'KZKU'58F)!IV$"W%/-2BJ$?5=K)4U +M[D]PN(",@`````0```)PD``"`NG])(HP5YG#_K=[MK*9S +M'(4T'&U"*3S,]B="S(Q#5A]A[@BK5VH@= +MOZ&'5`)@$CX-1Y1HT6BC2CVBL@X2G?S#,$%:`=,\YMD@#!4MW_5P#(?.W3>K +ML^_!].:RZZQ=$O?VQI79D-_,UG<2MT;5LPH`'`$``!P!```"````10`!&%U4 +M``!`$0``P*@!`<"H`0(!]`'T`00'Z5@'D_N$KDV2(WWM2&>[D]PN("0(```` +M`@```/PA``#@QJJ0*4#W8W_:\Y&QEU?''CZKU@!L\(C0`+_-0[YKZ`UE!S&6 +M^\(Z+``NW)PR/SW)=@$JOU2@\.F +MF.@]$LUI__[C'SQ!'QR;+WN`"=]'.E6**`W"V4Q*-9-$\7,AM^_`T@/U^C2' +M/6MV8^ZF^-O[(\XDD%:"%]5NMBT.B=%\>FM0S7!UC_9MQ6(=>4N)U0\7O`5K +MQ"K`\S%ZCRQJ/5?L[_F0)VJU_^9CSU*#6.3=$`G*]+_2&,BY+[('N;W_K3,? +MW)CB`W<2MT:/O@H`_````/P````"````10``^%U5``!`$0``P*@!`<"H`0(! +M]`'T`.0&R5@'D_N$KDV2(WWM2&>[D]PN("0(`````P```-PA``#`C-:&<1)E +M[XHO7HP6STW7'\A@-/,\BMAF7I:$W* +MBOAV7R=UBBTE+.^,R.,1WDAW6G3`<_]/H2,W4*RZ+"A^P@^F@W'<7-7#QS)Z +M[.7'/UC%V*:46G8/0K!=`WU,Z@J1$*P#>LZP@T;X4D7Q**7YPP%5=;]=58G6 +M=BEW$K=&.,D*`&P```!L`````@```$4``&A=5@``0!$``,"H`0'`J`$"`?0! +M]`!4!CE8!Y/[A*Y-DB-][4AGNY/<+B`D(`````(```!,*0``,+S=')*/9[<* +MZ)Z^B=&Z2`-1\7PM9XQ3^X2N +M39(C?>U(9[N3W"X@)"`````#````3"D``##A/CK#N^5N0JL@J6#"9S<3*A9B +MY="E\5)F0`?9]#)M$TZ/?)`\[]<'NTZ@+G<2MT:"`0L`/`$``#P!```"```` +M10`!.%U9``!`$0``P*@!`<"H`0(!]`'T`20'"5@'D_N$KDV2(WWM2&>[D]PN +M("0(````!````1PA``$`/X,%/5;79?ZRLZ=@OF@>[>L#-AR\Y"/6^[8FGWX,2'-W7>HB$>A4>])?V=#9G1Z(1#CS;&"4$M.#6H\6-GJB_08VC_ +MLHF.:MQ3H:/I^4WH4\HG7%K(9!NQW\G2NO4\M![ME#M[=?G6.BR2THOH=Q*W +M1E$-"P`<`0``'`$```(```!%``$875H``$`1``#`J`$!P*@!`@'T`?0!!`?I +M6`>3^X2N39(C?>U(9[N3W"X@)`@````%````_"$``.".,=\_I'+KIH,;]=3+ +M>".:L1M>OI)5H.-=A)C99!\=&0-UP*I*>TO84UO]"R@QO5;`5<1O-$% +MA3?:I(D<>'ADP(LBUGOV_3YI*+AKFEF2JZQ:,XCQ!ROXXD'>Z#?!'5\5:V0* +MU*'XTP5/H\ +MX?AF-/_2RI82K%R(1GWSGUQFXQ*&1D>IX8+#=Q*W1N(="P#L````[`````(` +M``!%``#H75L``$`1``#`J`$!P*@!`@'T`?0`U`:Y6`>3^X2N39(C?>U(9[N3 +MW"X@)"`````$````S"$``+#H;81&[5VO]!%K,*#V0Y*3OY3)^>A(WT&]DXBT +M1?6.#FFX%V.MT*7ABM^%S)P332JN]]B9DSV=>=/:HTO;JU2SAT#%T7!>LSFR +M;^-24+<#-I+?6?QKU%KYHCH1Y\L.5O%:M*9,+>U&]+/3^X2N39(C?>U(9[N3W"X@)"`````%````S"$``+#E +M##\!;7W-;PJWR2'`!6P6NOUC?,,=$YPA-7R3EAT:OV5B"0$?2*$[3*[>/U2JV7:SGS1)M%3]J/=Q*W1@I>"P`\ +M`0``/`$```(```!%``$X75T``$`1``#`J`$!P*@!`@'T`?0!)`<)6`>3^X2N +M39(C?>U(9[N3W"X@)`@````&```!'"$``0#F#/K[7UPOZ,5K)[`EQT/E*>5W +M3Y+8\A^_R=@!AR'N&J5(O:C&E4K!T6+6%I$X&^^UDCQ",HT<$G/1]%7T7"D` +M>^J^6`)74S"21E^DXA8J;7HU![X?`,8ZBV1P]?:M^+AV/5$/Q1S6E.>=^BCL +M-C@2N(.C$4,GTAU@@Y+\F!JLQCL`^B8TMPL4T!2R[^52D(CM=R??W+`R.^F( +MHP#A9VMV5Y,`&849=!XRX#0QV?3,^DIPE[*."ZU&A6/VW$`KN#L_$BG**'R6 +MXVV8+\RX5<*`R.`094>'IIY;%:'Y8CE1X3MU;K9GFOGZ?F2ZJ<,\S_H-5U*V +MQ#BR&V\N8P%W$K=&UVD+`!P!```<`0```@```$4``1A=7@``0!$``,"H`0'` +MJ`$"`?0!]`$$!^E8!Y/[A*Y-DB-][4AGNY/<+B`D"`````<```#\(0``X#-( +MSV5-^E,.1F,N(LSC@3CL32NNBP)FGS#?S(>8"/A;@BLA(6J2!S+/TIF4ZL'% +MFA34<*Z'P<$$@O;>1`/G(]QRLB='`V#0?G.*BT\981B;\J.3/F*A39]33&=# +M'7\W*@$Q9:H.>0B;=S,!%56C4S81GE-U/6EKLE"E[]`@IKF-1#GY,5"A&WP= +M.3AU-6*F1K3H`W$.,%9,TQQMNJ")VU+LT4/=R]QU$9N-ZYNEI4A(0<%K)E%F +M[4X<1V^]>!["LH/L@&',I2AB3NV_ER-MOU%7GCO?[?OQR+'"'3]W$K=&('D+ +M`.P```#L`````@```$4``.A=7P``0!$``,"H`0'`J`$"`?0!]`#4!KE8!Y/[ +MA*Y-DB-][4AGNY/<+B`D(`````8```#,(0``L-U.,[A;*Q/=527;*\AAM4YN +M-\"#UBBIQKGZI+6]5?L^SS;(D]2`@@447;%HQW$K=&2IP+`.P```#L`````@```$4``.A= +M8```0!$``,"H`0'`J`$"`?0!]`#4!KE8!Y/[A*Y-DB-][4AGNY/<+B`D(``` +M``<```#,(0``L!^W6NN)%ZRCNBQ(8A[_CM>'FV/VG6V[_79L-@A@PQH!<(== +M!T&B4A3T'MJV`N;N9J/B?.(W._!*9\CD49;:1QY*B<9L_39KXPHMGJW?AZ3< +M0HF:>7/,7(,$E_Q:'M?$5O$+M34@Q4-C8O<>NXGHQZ,=_(>+#K\).O=7+JN^ +M.8B8`PNB=5@N!F.1T%00$FY7+68A4PYL@U-#V6S-&D7GZ>KURO>"YS'@Z):@ +M?,5W$K=&@<(+`(P!``",`0```@```$4``8A=80``0!$``,"H`0'`J`$"`?0! +M]`%T!UE8!Y/[A*Y-DB-][4AGNY/<+B`D"`````@```%L(0`!4#UY0AR6>IEO +M[TZ]_J3G2:QXKRQ7BDS"GU0X">TW9`W:=%N$US3N;>=GP`1P1:Y#\9S]D51+ +M96]ETN=Q^,!E_Y0)VIE2)W%J\;D++VEZH(M?D9+CBX3T3I^C3M+?SIGQ6+T] +MOO/)U]T.NSNFFS&8/A%)6:@!W\"4[EQ+)('@VTS\PX-[PM2@GFEOK5'UWTY2 +M5V-"\+KN,_"\Z-UA5%CQ,FW1!>5+=['J)7]5`V@D=4DH4WR\$,'8J'U-JE]H +MP;BJ.F6Y`J&8';+GX?1CA6Y70/$F +MG`(!QJ^3^X2N39(C?>U(9[N3W"X@)"`````(```!/"$``2"' +M=/8L"9B?KA%`X*DY'"Y+F;6+:O#H[G1YF/*H2,+LS\5V+JA)CRYFJP.+%Q97 +M*RINY[%^>[D7=V5K8`PUK@`^9`B?$]DNWZVA7^0F&K<;HW4A]1R^7BO6*KTC +M[)V*6D8QTH;OW&,1L`<1Q[T=PDXBH=`%I^GJCI(>'Q]38^2@S0K4Y=/;&R9G +M-5XC>E1'Z]J1$%7E"4;%`++9VSD<9)D0];PIVHS8:2\;]Z$1 +M.+?IYST,'4+8JTN-9IES/=O\IBY[TK^$Y$%PN,-)8G&QOG_BB<)"MR-.KN@_ +M/WIJ@]46<@@CFX$E?W<2MT9W'@P`?````'P````"````10``>%UE``!`$0`` +MP*@!`<"H`0(!]`'T`&0&21MD"/E9>T'F=3LN("4(`````````%PJ +M``!`M9L,-HX)RFA\?PRAY+=,1<&+#]B2\DK"Q50#DGOH0=--2,E\*WKVH&:7 +MRSMDU5:WD$@N>'4XJR`\*4&E=Q*W1@XJ#`!L````;`````(```!%``!H768` +M`$`1``#`J`$!P*@!`@'T`?0`5`8Y&V0(^5E[1S:;=N.=X>9U.RX@)2`````` +M````3````#"YI&>BG[N<"J!-]C);FZ)LP;8<2!=H38^M9 +M+"USPXR/A7<2MT;4.`P`;````&P````"````10``:%UG``!`$0``P*@!`<"H +M`0(!]`'T`%0&.1MD"/E9>T'F=3LN("4(`````0```$PJ```PQ6=. +M>=U"4"U?"(U5+Q^4RRA7'.@:&LYOKQI>#^M47F.2_(/1!/B&,]IH^.9W$K=& +M0$8,`&P```!L`````@```$4``&A=:```0!$``,"H`0'`J`$"`?0!]`!4!CD; +M9`CY67M'-IMVXYWAYG4[+B`E(`````$```!,````,.`/F$BB).2Z-Q$[L\BR +M@UN+]C=E"PL*)K4A3<.^EKJ7V6>AZGO-O=O4NOD?=Q*W1F9"#0"8`0``F`$` +M``(```!%``&476D``$`1``#`J`$!P*@!`@'T`?0!@`=E%*H^'`2.)5D````` +M`````"$@(@@````````!>"(``'@`_P!T`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``K?JX#8GS6QS^9F#P%\$%)7?QMAP.*/O?_Z!FK7.3N4!FN$YA +M_!GW_5-4Q4Z<996L`(LOL<9/K4V9T_P-,E3X&#G,LDZK]2F>&0/SX$,AN"B7 +M7I$OE7_JT$9YYQ<]&Q2XWH,DT4;.?"X2/)6QZKV0QT(%]GH\PA&-_RSR`+EZ +MUE9?T%CZ9-I?`O\LB;/]$&&6RX/%23O[]4/GE#4,`6YPO'68MD7<2MT8%80T`N`$``+@!```"````10`! +MM%UK``!`$0``P*@!`<"H`0(!]`'T`:`'A12J/AP$CB59```````````I("(( +M`````````9@A```@``!`!@````>RX/%23O[]4/GE#4,`6YPO'68MD2(``'@` +M``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``K?JX#8GS6QS^9F#P +M%\$%)7?QMAP.*/O?_Z!FK7.3N4!FN$YA_!GW_5-4Q4Z<996L`(LOL<9/K4V9 +MT_P-,E3X&#G,LDZK]2F>&0/SX$,AN"B77I$OE7_JT$9YYQ<]&Q2XWH,DT4;. +M?"X2/)6QZKV0QT(%]GH\PA&-_RSR`+EZUE9?T%CZ9-I? +M`O\LB;/]$&&6)R*C0-J!9G\YM6PO1?&N4S$4(--N2H_,2?\[`&KX=_ +M"*QE_.DN_O!]78UPZ3Q260.HMV34:R':K/A8C*(IPY0C`.$XWW]%W+[[6K#< +M8_;Y].Y](DUV]/A[HNF%&T']*0``)'Y=AE+F_8H)Q,:):2:DO7"!KHS?*L]- +MR"XE2VU8&(S&*0``'```0`2!I[-"*B^>V#U@*(NW2BPVI@6C@@```!P``$`% +M=7Y$AC;8/E5_;*YVYAZ6]5&=MH9W$K=&5+,-``P!```,`0```@```$4``0A= +M;0``0!$``,"H`0'`J`$"`?0!]`#T!]D4JCXF-^0AYH>T_S[#>F5.; +MWUX[VK+$6Q@JPD"U*Y:V@$$HRP*FUB,$0HUCYX`]KLK14%[][/]'`G"MKW\!3#YOLEL:>F;M3=EGFI)DV1L*:;X8M2G>R+PPCFI[>3%<>=L=8FKH>>; +M&4W7#DZ'=8WR$!@MEW<2MT9OZPT`'`$``!P!```"````10`!&%UO``!`$0`` +MP*@!`<"H`0(!]`'T`00'Z12J/AP$CB59GC-'&P0JG\DN("0(`````@```/PA +M``#@7P"&O.8[/]J;V8BU3KE"`OJK&DE%\%Q=[T$'= +M)9?4`%P(&ZS*7'$-]E4#^)0P$CBEIQ:<&Q,.+.OTZ5;RWPM"L'NR8G^F`F20 +M93)>6%&O=-=+29^#,%35M%4O.=1*_>:`W+GT-MU6?Z^QR0N%V#O&:.MKH'<2 +MMT:H]@T`_````/P````"````10``^%UP``!`$0``P*@!`<"H`0(!]`'T`.0& +MR12J/AP$CB59GC-'&P0JG\DN("0(`````P```-PA``#`DVJ9N;LH_+&W;M-C +MI#9E@'6>._[#ZPZ8!]%NS#?K&-&1B*?5V!<5NUT`!M#K=^1@%_G^P89WH(8H-'GJ440IM4LQ&WX8&5 +M9&3=6?L>WT8ORPYJ'39(A*N-'ISA!SSEYK<7=2MN;"9C3<;9YQ19M_L",T<; +M!"J?R2X@)"`````#````3"D``#`B0_G*`'9WDJEC;":\M@&L77XA5X_RJTBO +MJDT]?Z6,0_0XK0BZBTM7>2$R%7<2MT92.`X`/`$``#P!```"````10`!.%US +M``!`$0``P*@!`<"H`0(!]`'T`20'"12J/AP$CB59GC-'&P0JG\DN("0(```` +M!````1PA``$`(J!L6`;<<"T-CR4^MF[UV;T0%FQ7*MU8SV^%Z.MK0$^TE!`- +MJUK4P$A>Q^:>YA-=A^$(O2\YVC=;G-6*U=YEO52X+XD_,Z.G#V8*9&N,$7X! +MKS\P1/YCL55V*^R+,8(A^>:A6,^MHDI;`VK4A'RZX%/`F?H:'+$M\:)-"9DI +M;]'>YJ;K!CV4MGA8HOKP$4+7S6"$%&GY-\&=`1=^E5D_\CEW_5;:E'OR*X4' +M\<'SK]QD`/C2D3B;D8>*1>X1'V+AI6G&-<:-4)<&V"+E7>77,T<;!"J?R2X@)`@````%````_"$``.!_)KVVZ,(2X-SJ^L[FV'*=K[K% +MXZW%6*OHU&1B9)L!C;6)WBZ`@`[K83HO(1M2E%&E>R,KO@L,%F.]#(%6D#O] +M&==W\TYN8)%7-=CS4L!Q/^C1[3>KKC\:%T=Y^2R"[.?LXQYU9=6:%?#`X,-[ +MZJSDOJ%Y][KP(UFN0!$()[C*.(U,BHT41UCY:6=XG-(5^/1H1X_[YP-_K.775A\.W'E`=71"$,E2"RXAOZ"4QB=Q*W1H%4#@#L````[`````(```!%``#H +M774``$`1``#`J`$!P*@!`@'T`?0`U`:Y%*H^'`2.)5F>,T<;!"J?R2X@)"`` +M```$````S"$``+`)$0/9N+)H/OT>G7T7<,,A]*"5'.B<<4XI[5P_J6;Q9M$N(;+*^OHP+_O=-4D0O[;0 +M-C!4XOYWSD+7E.)YE\'CL89/-&Y+32G2QS!1A*P@XP/QR255 +M>CO:=Q*W1FAW#@#L````[`````(```!%``#H778``$`1``#`J`$!P*@!`@'T +M`?0`U`:Y%*H^'`2.)5F>,T<;!"J?R2X@)"`````%````S"$``+`1F&.:]DVB +ML)7:A#F=2;FQO'^*B$"`@`;>839Y`[J1MNY&5ZL?/WL0MSC,]^&VSP]8;YB< +MSM'MFCWC"<"T`"D*#9G9,@+C+#HRZGX][B]Y7JCX:)._#VKIRX24V3"62&WR +MMDUA()M(XEH+:@:ZP<356Y7:<@IZR?,[N'ETJ$G;BW,T<; +M!"J?R2X@)`@````&```!'"$``0!SJ(YY7KAJ@B#EF#;V*EY,RG36:Z8C"0:8 +MUZ4@YU?]=?53.E5!PR!ZH?;.H6KQV64;<"25@VC^%W]0[\3<3T4.MA7G'Q`[ +M[JY%;]GOYY/%#".6^5Q75VNW%/<9SPY2QM6,B/,YD]8\-$U13/#W:'`TSS^7]+#(N=*>[E5UL*33 +M=X@?=M6GF*\V+)G.Z+Q**%@5HA'/LVM3\-/"5DE"662P1."*1V]IR8]30X'* +MF"-W$K=&LJ`.`!P!```<`0```@```$4``1A=>```0!$``,"H`0'`J`$"`?0! +M]`$$!^D4JCXYM`YZ2"9D=&J=0&R6EY'XV64@`LI8C@;IW==C$!W?OYS?`E +M-D@KR_Z8[[U%B>&A@C;+BH*'OWA/H(/1#;51OZ,.0Z9]<`"2R*+H:I#E]%UD +M^FZC_/K?(/&_C6O.[YJR[O\:LJ>.$P^R8.?W8FJBD[7?%C&6\NOW,S=-\+B<(6>S,HPB@-_$7IPGI2$S +MZMT#\8C(2#FLA3S^XG6@BY0S8&Y-/8LV"L.0MW$K=&F[$.`.P```#L +M`````@```$4``.A=>@``0!$``,"H`0'`J`$"`?0!]`#4!KD4JCX3]3`R]6A)V +MYW-35P^#I"=M'?OKJV0+6&%P`3 +MD[Y\+)AO4JYTF(V97O5W$K=&&-4.`.P```#L`````@```$4``.A=>P``0!$` +M`,"H`0'`J`$"`?0!]`#4!KD4JCX(H[:4N)T==F/"F;]\._4Q?(&E,?T,U\AM*Y[ +M0"B(KP+Y@3<%JDHG9!).SPSMD/@MX6=DY>AS=I4.:NU'J["1#JJQA)R^$7+A +M`@3CX3D3.S6%EJ:'&IYA.9$IM1C2PUW3E>UJIG#6Q$-S0/V7N2[@Q^KAP:T* +MEO%7W1[!/QC(AJ-K`_@M*1#J7LD&M];"[/&(6QQDFVG9&`\.LDZWL<5W$K=& +M"?L.`(P!``",`0```@```$4``8A=?```0!$``,"H`0'`J`$"`?0!]`%T!UD4 +MJCXECCT("^<*A2=T^7'%?MJP62A871K^&DET])_#=A-8[02`V>]?^)-8'K>3V=L-PVX`1HH\[Y4X&M=H,C +M3L,ELZ*B6''2C6J_<,!U!(XR5>?]>T +M.O%`P:<$&"KLT\GG]Q*\]Y>;6A[W.4DZZ-Z3;Z26M2J7`41%++6)3E0S..P\ +M9F#)ZW;:&S02+;7KXNVC7/T2H(HMN#>`@3OFY!7302R6)4*2=M)A>L$JL)3G +M-8_A1.G;9=X"*;[ON\27_D($@N8HX)-40H]U*\,&(7QI=:6,Z41Y$G0C;74I +M?LLH@#]+WPO66`=T.[^W[]\MW'2ZWQ7XYMJG<*FJT2E%C#9)$=[!ZA*%R^%6 +M5VDW=Q*W1F4P#P!<`0``7`$```(```!%``%877T``$`1``#`J`$!P*@!`@'T +M`?0!1`,T<;!"J?R2X@)"`````(```!/"$``2`;]$3^.&*% +M#E\4Q5R0TYN3MP&XUG7@Y&!8?&N""Z8A>[#0=?/OU''W^&#L"/-P0M]J*(3> +MB"ZC1,0NV[@T>^F=&>93*7?P^FS57#T-,`3'2)9I1(G#GKR_%45BR;*.("A) +M$?RWNUY\4GB4.N0U\:_(MW>$G/&1*PO?!$XF=D0_1617"]6F3#*GK7HS*`H0 +ML\V7I.<@6[?Z3*;7-88WH%&@E=G-R`(HY+-;,E/,TO@Y5\*C=<5#KFZG37?] +M1,;&W.*/E07QIK[%=40,`S@0C$^-LU9$$2=%%B>1?;YC,Z*C_T/VZ1@=Q:48 +MY1C6EGP)C.K./YE[[SS+R?/0RYG+?]CZ.2@!3\[U'8>94*0*R?W][)VOQ!`X +M+@]+L?]V?G@2MT;7%@``?````'P````"````10``>%U^``!`$0``P*@!`<"H +M`0(!]`'T`&0&28%<>U;`+Z(H:6Z"J\;!'>PN("4(`````````%PJ``!`5B[X +M5%LB5??!H4!*,`4.5,/!:AGRG`DEO]MWJKHL4]SYOS<<31$2#B1WQ$GMPX$E +M0YPWXIZA_B2,F6>:>!*W1G,B``!L````;`````(```!%``!H77\``$`1``#` +MJ`$!P*@!`@'T`?0`5`8Y@5Q[5L`OHBAI;H*KQL$=["X@)2``````````3``` +M`#!AYJD>6+?K253_0]*AZ2OO!,3F%V7WV1A`N/N?Z':=Y-U4920)IPG9$SLK +MCW@2MT94,0``;````&P````"````10``:%V```!`$0``P*@!`<"H`0(!]`'T +M`%0&.8%<>U;`+Z(H:6Z"J\;!'>PN("4(`````0```$PJ```PB>:F]XKR*EO' +M@529/W^6M'(^7Z'D#6'@Y4_(^3TNX-4C8@'##$KF?^F#SX=X$K=&M#X``&P` +M``!L`````@```$4``&A=@0``0!$``,"H`0'`J`$"`?0!]`!4!CF!7'M6P"^B +M*&EN@JO&P1WL+B`E(`````$```!,````,!M)SNHE<%"ZKL0./(E@LH,-553U +M%-G"@AK/S1%_Q[-U`W;MG`U^9K(#L:!*W1FXX`0"8`0``F`$```(```!% +M``&478(``$`1``#`J`$!P*@!`@'T`?0!@`=EI,=_S@QR+IP``````````"$@ +M(@@````````!>"(``'@``0!T`0$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``G]TED7@,P7#RX`1,^GZY!J`!YO?W=^:AW5G(@OT-)!/IG]L`D(Z[98BFJ'+_XI```<``!`!#)%$4RL +M,`A:3Q,MY\+HO&_Z8*4`````'```0`6UL.XHUL%BON$@6%(.J7@2MT9H7`$`N`$``+@!```"````10`!M%V$``!` +M$0``P*@!`<"H`0(!]`'T`:`'A:3'?\X,BON$@6%(.J2(``'@```!T`0$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``G]TED7@,P7#RX`1,^GZY!J`! +MYO?W=^:AW5G(@OT-)!/IG] +ML`D(Z[98BFJ'+_XI```<``!`!#)%$4RL,`A:3Q,MY\+HO&_Z8*4`````'``` +M0`6UL.XHUL%.6FQ)8`,=F]()=8(UD=#:_C:RC08\3 +M#+,P):5H0*/[8[^`[V;W?_T@&XBEE-"BJQ%RV-])(-O%C/!C!R'N`]%&J9=A +MO3C>V-<;!^=,UZ$*W6YRU!71(P+:";TS1"-*&E#T+-#K;^I;8N!>"F#D4,X3 +M^SRC5#WHGZB6>B3R*0``)!HB8V>B+^;EO-$Y[B4A8JHK*N#QVQC4J"1P@(LD +M>H/W*0``'```0`2UK0,4A':_=THP&$V;7KM[AT/H#P```!P``$`%I9S(%:[' +M!G]G+/K[!:D&0(W#U?!X$K=&TJT!``P!```,`0```@```$4``0A=A@``0!$` +M`,"H`0'`J`$"`?0!]`#T!]FDQW_.#'(NG#]W"4?Z"E>^*Z,DF.Q&R^?"Z6;4O[EUSU6P5/0^4[2$Y%ATDP:TSB\-95\KZAPJ08=9_HCH1 +M/VHX4=,W-0`,?QO_)*#>C(B4>+>L6(%,VSX`'D8NE6&%-Q(L;LV;\Y!]YM&B +MQE]7MVR;1A>"'GH+/=*3\""`\YK9?^GBJE&T/@?=?B56'7ES6<'8X1P(&-*] +MJ=R3!@X>]F@W85W(075SC"C.;,C7QAS5.;W@$7@2MT89QP$`O````+P````" +M````10``N%V'``!`$0``P*@!`<"H`0(!]`'T`*0&B:3'?\X,)C"UL=MDL'K)YW0]\":U +M%^/]$B*Q5>,9I&"%4B8W#*$^KA,'.;&Z/B%D<<7OB<9VT[U0J"-%%M$O'9"M +MJB6R<2E"H8$]CSNMPWGH:)_%[4CL[]E1YRDK]-0X>')0+O74X['- +M%[[8H\1RH9`IW'1,G)93Q3#>>NQ>64>;Q/VU:]W.R&]QUP3JK`41E8[RYHBM +MQ(Y7*P?%3;SUZ4>!F>U$BPKR'/UYVOT;]_9*Y3*YF;EON+2YNQN<_6\[.58RU7 +M@!&5%7P7:$$2*HDO.!288C/S1?@4T(N/IC#XA"VG5KA86I!35JC`*(HM!"&PI +M(U;/3RD*8VJ(D*3%Y6(0U)":"RS,:C'&O8QZ;&2L-M5%7T-X$K=&]?L!`&P` +M``!L`````@```$4``&A=B@``0!$``,"H`0'`J`$"`?0!]`!4!CFDQW_.#'(N +MG#]W"4?ZS*M+_D',].`+H68K%Y>!*W1G%R`@!L````;`````(```!% +M``!H78\``$`1``#`J`$!P*@!`@'T`?0`5`8YI,=_S@QR+IP_=PE'^G-_TRX@ +M)"`````#````3"D``#"GKXC13.%I"_/?M"MS'8-`I/4!'F6M:35!U'W95E)4 +M@IE+;_YG:776/O&4VW@2MT9:C@(`/`$``#P!```"````10`!.%V0``!`$0`` +MP*@!`<"H`0(!]`'T`20'":3'?\X,8.6PA-Y628),:_\)["RW(\W..R +MH4UG3^_JZ0!%:0P!K1ZI*!MU_J11K*A8!G'E6A:R+IWOQF'FE3&I[!D+R`K\ +M[_N)G2RU3Q-L(7:#2D,5,V;8P;8MY*?U:F65>6;\Y8DE-T:_@-9\]I*8!7N6 +MWC;PCLC*G:N?YA;DHVF2J\DZMW'[2"6(\5=_HI:W*'Q10AL&ZZ')/&YATY?' +MAHJ^&_1:K`>!QR4E*G3@V-=8-P`=Q!*W1M29`@`<`0``'`$` +M``(```!%``$879$``$`1``#`J`$!P*@!`@'T`?0!!`?II,=_S@QR+IP_=PE' +M^G-_TRX@)`@````%````_"$``.!JE'QE%6]W82M)NGBT"J(S)AT+;$Y"`U_\ +M`$_\Z[@Z$N("[G-4R0R0\.2>66V_8/SY`%B%>+4!?XPZ*![>Z3D2A- +M&P^0YTY-[>VPHOC&WXVDGPF^I)-OLKR.T&PS`>!]?;DC^7+["H('0<]T.2X% +M*WJ,ELVA4*LO`%R'_#HU3<#J4R##<=K%O:N.K='S[@)%V#.&N%D.&<@E*4#R +M7,]?`E\.#2G2TX,L>;H)4(.EH>^2/X6S5'>-20+"&$`W?&"^)8^N)=ZUG$EP +M2K3`[Q/86)V'RLN.TH&;>!*W1DZI`@#L````[`````(```!%``#H79(``$`1 +M``#`J`$!P*@!`@'T`?0`U`:YI,=_S@QR+IP_=PE'^G-_TRX@)"`````$```` +MS"$``+#")YE9UO9F+:L'&8*;I^\)Q"ZM5:3+V12P<'EUJL0*)$WG%JW376D] +MDY,.5H^"M>W]%AX.KOJ]9E>L=N8XF:#"4.<)PPEV`$7PN>./:5)O&)#\Y^:& +M_U`09:]^>N.]2RUAH<$2%5\>?X$2'3/!/MJR:C&U&(U_\0*OR=#ZX\YE)#@E +M&(U*.WHE''AW)I3,+U%'\FM2`')V-2KSFHP;O7;9U)Y:!5/D3_1.)SLI>!*W +M1ES,`@#L````[`````(```!%``#H79,``$`1``#`J`$!P*@!`@'T`?0`U`:Y +MI,=_S@QR+IP_=PE'^G-_TRX@)"`````%````S"$``+`F55NR_$4?T&W_&9N] +M^VOIJ`PYANIVM*FQ(\5O2A"9U$+H\R^_&-$O3'KSSQUQZBCL49\"=$]X8^^G +M.6#YR7*`[ZB-SJ[LKO+IK]2_Y<2PIKQ5YE2)S_+SOM(_@TY;`]N78B^M_WAF +M0N-*YD/TS"1C\9#)P]N[[_U3+_4Z\-#(JOF2FIA/_4(SM(J`H;-^Y;YYQUDY +M(N1R/5^25EF:5IN@':?)F9G@N$%PWN-(>!*W1I?J`@`\`0``/`$```(```!% +M``$X794``$`1``#`J`$!P*@!`@'T`?0!)`<)I,=_S@QR+IP_=PE'^G-_TRX@ +M)`@````&```!'"$``0"Q.AZ(ND4406KU3F#N=5SZ5JK+NA)/'*3'7T+!CR%) +M!E-,E>)[6*+&E.R]W$Z:CXJ[@LN`<:D2OV7=8O\2ZR:I(,IO6\ZF+NR$?AS+ +M:6%WQ]C4@5/R`6\)P#A`)U["FKK9B/KV'!U22=@$K/S+`TY+P)6!?K +MJ244:H>C>)`LVZB+"S4UNS[5KG. +M\V<*6_J*JWM!V9M`+]_GH,),<^\4PU^,"/@1)MQI/(19$`1(LYYQM=]Q!GDX +M?;FSG^5AM"7*J;#8D_\,X"*YZ9M_M@Z1!2OKZ$$!F-5@]8CPCHN32B$1SK'4 +MG\V>")_4%<$S$'/`%0ZD+(S&_'SQ7DMXS7V*PQ_EBY1&L3\*G1+2CVA7?;8$ +MKM&+72ZB9Q!6)%7QS\8!B@=]?CV\Q)MN32&S:3#9\H(OL*S6&+>4IQI)32*2 +MWHD0YSJP:#9)5S/M&HZO15Z(AM;"BYDOR15X$K=&,P8#`.P```#L`````@`` +M`$4``.A=EP``0!$``,"H`0'`J`$"`?0!]`#4!KFDQW_.#'(NG#]W"4?ZK,WB\WN5/LAQ+QJ: +M!#J$1>B_/PL1V1XFJ]=O+5Y_RO>^"QXCU2442CM$]TN*=#6LPV)."!+&EK42Y_LW"]&0*@<.1DE61(OJ!LRJ +MFN3Q58.`7)(B9,ATPSAI%^:TF8A0MWN0%^9;-E3)=`.O'LL2=3AZ,\_.>!B_ +M#NZU>/\_ZR]X$K=&]BD#`.P```#L`````@```$4``.A=F```0!$``,"H`0'` +MJ`$"`?0!]`#4!KFDQW_.#'(NG#]W"4?Z0"I8PGP4\*6Z2"3WU/)&[CJ3W=7)J/&M=`I-.;AX$K=&ST\#`(P! +M``",`0```@```$4``8A=F0``0!$``,"H`0'`J`$"`?0!]`%T!UFDQW_.#'(N +MG#]W"4?Z1*>3E["VKR78M< +M8C_BH:TGIBOM1'SN9=TQY3FN<4[\]?2&Q=,>Y]2D`9W'7:!]4Z/AP4VO[L`8 +MUN!X'6-QE(DK50!P?8E&1`#WJ*E<&<#.=`%2C]1;3*FX1@/G`]*7H:=>]N.S_52#UC1T$9V.BH00_%Q\[!E[W/W]Q$\ +M#DN38#./0S!0[V^UO9!*1*1;XWJ_4!X!P!H'M##O,']R$?U<97BG3PB/L\_$ +M-D^7ML-U7939'PXS>;3*JPK9G5--C-@`X&:+@Q&&==RM$=>M]8BBA3J:O"[Q +M`<_--GQC=PR,BMX:OW5323Y(-BG1^%(&0@/DBR#N+89"B?HY80U+$9D3>!*W +M1CJ$`P!<`0``7`$```(```!%``%879H``$`1``#`J`$!P*@!`@'T`?0!1`[VA8`N7VZ)D&=.?;+I\"@]J4-Q +MGG)J[R0VAG'+R=!>V!V;40#NVO'?E.,?4>9N@'X0+OTZ>^$(J)V[7%!X3K7& +MT*8_M.KMY"3?%@6'F"3YR1E$!'K#F*G28\MJ[6H65%*U,S[W]NYW,FNXPXT) +M4*0,NMP-__9`(F"6M-!3YH4HKDFQ0_>!N>3\I4AJ!$G82;5P3E!,"TVWJ\8/ +M4/[M75NW]+&AC_""'DD=2IM64PWW?_RRF3.8_B:<$]DZ%V;``!`$0``P*@!`<"H`0(!]`'T +M`&0&2=F%8)Q&9+'/;<'E.@IF"64N("4(`````````%PJ``!`@*:XD\`R^+-4 +M<@??Q!<)NS+!*W1@6W`P!L````;`````(```!%``!H79P``$`1``#`J`$!P*@! +M`@'T`?0`5`8YV85@G$9DL<]MP>4Z"F8)92X@)2``````````3````#`M6NFW +M:PR3GV[^=%G,;X:3S8"^"HRF=2SW4=:E[^*BM6P9>4(D,(S&N2QPE'@2MT;? +MQ0,`;````&P````"````10``:%V=``!`$0``P*@!`<"H`0(!]`'T`%0&.=F% +M8)Q&9+'/;<'E.@IF"64N("4(`````0```$PJ```PQJCR:/3*5B@)><9L;:;G +M_K`ALZL&%D]>)X$K=&^-(#`&P```!L```` +M`@```$4``&A=G@``0!$``,"H`0'`J`$"`?0!]`!4!CG9A6"<1F2QSVW!Y3H* +M9@EE+B`E(`````$```!,````,`"ZD=,ECCBD`-GA,\$H4X``7I]9,Z/[@7GJ +MWT??/"/:S:\$#>%GHF%$E#_S>!*W1G/2!`"8`0``F`$```(```!%``&47:$` +M`$`1``#`J`$!P*@!`@'T`?0!@`=E/K[]*.1V-(P``````````"$@(@@````` +M```!>"(``'@``@!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``C0X( +M>C.P>9CKRKG`95?JQ<5%F@LT[\,P9(T"; +M";;(2=,\YEL<:5EJ1OIT"<1*O&=&B\I5SE:;"(/_]M03J"KR/AN2T5TZ%&@E +M(>$L@O\R@'/64F6M6HM2.[K4[VI#>YW@VO>M"'Z[`:9&KLXI```D/T%2HE*\ +MEB6_&#O$2'X`XOT8%Q??I.?;_)6C@DK5"D4I```<``!`!/J4-$'%M2?30/'G +MC?3PD@\4\6`+````'```0`6U';.1NY,)0CQXO>O/,G>T0!/?+G@2MT:-X00` +M7````%P````"````10``6%VB``!`$0``P*@!`<"H`0(!]`'T`$0&*3Z^_2CD +M=C2,```````````I("(@`````````#P````@``!`!@````<@UI-A?Y9%\HHQ +M%3F<6HO/Y#C.P>9CKRKG`95?JQ<5%F@LT[\,P +M9(T";";;(2=,\YEL<:5EJ1OIT"<1*O&=& +MB\I5SE:;"(/_]M03J"KR/AN2T5TZ%&@E(>$L@O\R@'/64F6M6HM2.[K4[VI# +M>YW@VO>M"'Z[`:9&KLXI```D/T%2HE*\EB6_&#O$2'X`XOT8%Q??I.?;_)6C +M@DK5"D4I```<``!`!/J4-$'%M2?30/'GC?3PD@\4\6`+````'```0`6U';.1 +MNY,)0CQXO>O/,G>T0!/?+G@2MT;N%04`4`$``%`!```"````10`!3%VD``!` +M$0``P*@!`<"H`0(!]`'T`3@''3Z^_2CD=C2,UU7.AER7#PXA("(@```````` +M`3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"```` +M"`0```(H``"(``(``*4N/,1IQQKAN"&%)0$2]E4@&;[3O,('A)''YJZ"FZXM +MOBU#FW>_G7U^TG`C"\[892E!F@%Y$CL;$A>MS:6(27ND(T++NB28]),"V)/* +M89S3VKF[$KO-%$A2)VFG9NA'U."T7-_5M*2.>`DC0^8N5%_SXT,)]7HOW[30 +M$G.&83#A*0``)"BT\@0+(J4VSSU-D\>7962/)('AN\1&UNG+`CWFRX7%*0`` +M'```0`0TZ9`%:4ABO5I^EVLOU'UDY#5J90```!P``$`%;,A!91^L^X:Y+483 +M=PXK*^6+!WYX$K=&0$H%``P!```,`0```@```$4``0A=I@``0!$``,"H`0'` +MJ`$"`?0!]`#T!]D^OOTHY'8TC-=5SH9MFW@/*=,)Q^A_9JBM)^JSOH<3!CGKZ1^OW[\#`AO+NN)*I^%2H-S?,QHXK+ +MMCL(9$OTK9"BE*+7U92F4#:U:!2:E"GHQ]B&/"UK'HQQ`627(J]4(?TM+$^! +MQ\4=-ZR7TQ53D<%JGOX57=#9PL"=^X370^I\'J83AG@.0M#NJ[Q\*`PZZM_J +M%\Q*MIDRB[?\7-?:X;VU1RYOS4>6C%#`Z:5QZ/4+BINX7C)NN`!$H2999WD7 +M>6/N`@XN&8:9+]@'2&1'P;_QS^FB4G@2MT;N8@4`O````+P````"````10`` +MN%VG``!`$0``P*@!`<"H`0(!]`'T`*0&B3Z^_2CD=C2,UU7.AER7#PXN(",@ +M`````0```)PD``"`MOC>*C-,F+ESV%N!CK(HH>WJ[0H0/G@S6]%UDFO]EQ]W +MZHHP.$0VS>3*JJT\&NSIX)XQIE<'6G"B]NDWQ65 +MVG@2MT90@@4`'`$``!P!```"````10`!&%VH``!`$0``P*@!`<"H`0(!]`'T +M`00'Z3Z^_2CD=C2,UU7.AER7#PXN("0(`````@```/PA``#@".NF)-9[G,$V +M_950_ADT^2XMD2MGW7W&<$X4V24IV*\M$6"8VH=!*RXC"A80).V])Z!7"SGEJ321E*VNBS`LBP-0[YL3.]-:90VZ7O\RC0ZE0S8 +MA822>)O'1T&R<%0Q[+_V"Q"@ARB9998A4^1X9<13VN/#FMBFN*':&2@> +MEU>/?UQ#8MA8N!<(1O!&I77).8;,0!5]^Z:0OK*TD)J+<'OC<7RC[`(*"?NY +M]#W,RM_R(P,K&=4NI5"8U(@:AE2'5%C7R%2/*6^VL'@2MT8JC@4`_````/P` +M```"````10``^%VI``!`$0``P*@!`<"H`0(!]`'T`.0&R3Z^_2CD=C2,UU7. +MAER7#PXN("0(`````P```-PA``#`I')"HX+^3>4E?#.]>B;=:A^;.N^9,Y2> +M[1BJK&ZJK::`M2DSFITE=EZ(:O<1I*5>-(\?/0)GF"?%&N$)*'YIK?/ROL49 +M/D+MH\&HKZ#)N5#,H!&D8$!C:8?;H%YP'X6Z"2*:0_"X%L'7ZB@YJ)+:V7O1 +M\*JQ/VO4)5ZKP13X\NQMD3_6D0W)_"00OJA"T8UT[*QVWC.)/(2B4$SVGI!" +M&,5R1OG1=D]A$-6@L3TD\@+DI#]L",-W+E/SQC!X$K=&.9D%`&P```!L```` +M`@```$4``&A=J@``0!$``,"H`0'`J`$"`?0!]`!4!CD^OOTHY'8TC-=5SH9< +MEP\.+B`D(`````(```!,*0``,.0!,VEL*D-.39\%BP'.:=R2-X$O;;[@!X`Y +M!NV!#H9U.(F3I"^06EHY[_GD>!*W1E^T!0!L````;`````(```!%``!H7:L` +M`$`1``#`J`$!P*@!`@'T`?0`5`8Y/K[]*.1V-(S75/U(QN4<571$@UR88Y!BS0=/^[`]=:^]5LJ5+X6 +MZO^I7MS_>C<%48.9H_]$)'F\+5QB9%CQ.:TI%[UB9P(W`O7;K"5-SD0KB\>];S2/DIGF8[ +M;GKIPS8BR0L"$LZM11_\3:X6P4YT.R!P>!*W1E;=!0`<`0``'`$```(```!% +M``$87:X``$`1``#`J`$!P*@!`@'T`?0!!`?I/K[]*.1V-(S751I^=?0TQD*8I//^4Z.7/,3G$N?/C\PD.,%_>&6#U8#YE?O626.^.4 +MB?%XU/'H9Q'J34:49B'7B6:&$'WF,"#X4+440JJWA?F(4_%[ELOWL(-[;#^P +M^WRDM_BM5F^!>!*W1HSL!0#L````[`````(```!%``#H7:\``$`1``#`J`$! +MP*@!`@'T`?0`U`:Y/K[]*.1V-(S75;]=6Y8B**&H+(D^<-6L951 +MA+LX:B<0C="O,,I(#W%74G8SBV-?&G3@7+4;SDQA(N94B8\UMHF9VEI.K&TT +MV3I>,L>L8KX'A-J6H0A73FV4N%2A8N6P.)?#F]IZ)%,U+*Q+>!*W1E\/!@#L +M````[`````(```!%``#H7;```$`1``#`J`$!P*@!`@'T`?0`U`:Y/K[]*.1V +M-(S75\H7_P`:WR]CA#[UWW9#M#`LL]ZU +MPC;96SV'AC-[]J;D)H93,NIJ;1EJ?%D&[N"&G>,<47+5/$;112/6*&6H?RS, +M@(KO(20-SY90^+\Y\?'BC4@`4D1Q +M\L,2:]^LWR7Y``DZ`,);)>/&>!*W1D`SRQ*U;`;`WDE2(BS=Z&YRS0@[O2I&*\!/;?. +M/9&U6[H.Y$8SE/CZR);$L6<$FTTB#(_,4:N6E`48N>=U:R^B*2X;0MD>( +M4E];9L42#H\)T-)GK?1=^Y`%"ML;WL\):O]"5*-K%;M/=FKLQX@UHA=?D5"J +M+ET<5Z95"5SM[A?8!>DTG"83#E_0Y*M$`EM>OT2[:9'5GD\S^/]D+JS//MY3)1IV=G? +M.@(W\_`+PT1]_S(FI5#^J/>FE*>V%5SK_82$D^%X$K=&ISD&`!P! +M```<`0```@```$4``1A=L@``0!$``,"H`0'`J`$"`?0!]`$$!^D^OOTHY'8T +MC-=5SH9_)31R+O +M4P7,S:98UTZ8ZYC3@T";MMQJR"SLL:'+LS42F;$7SPN^6,X.^K1@48HXUZ#8 +M:N4\KC#DPB7--$V9#0SXN3==1'2(.3C4"M;/`X39$Y66,EMUC)F8Y#F2?E$! +MJ='.K:<812ZW1%[R1.0YC2.)43S<;*X:%.Z?YCKBE2^;(XV:Q71[4:=9*E?_ +MW>G9-\-=/U0`#^Y!)]4O;EX +M>4JIEF)@C!3N1SEX$K=&_TD&`.P```#L`````@```$4``.A= +MLP``0!$``,"H`0'`J`$"`?0!]`#4!KD^OOTHY'8TC-=5SH9I[(9KC4^Z:.OL[7T"6\HR2BJG%4,X`"[K1$#^\JS` +M+&.H-A`L!T!=RVK&%'[(>0/BABE5D1=VQF/<@BS!7QZ_(?2%R5;H0S*.S@]W +M+F9"FY`:*8:*#I'-MF:.%X++?$Z:@UF%N2FN9DU\_;L?T_1C;)7&'0XP:(.I +M&*D]`*!<#+G`C173UOF=&Z/JRC[A3_=0<=#VHS%WW8GYO=?XGR'Y$"!.(B0% +M%"QX$K=&66P&`.P```#L`````@```$4``.A=M```0!$``,"H`0'`J`$"`?0! +M]`#4!KD^OOTHY'8TC-=5SH9P3R4IO)D7*@J`)PWPG@CL; +M;2LPE5'L5]Q*(JE`-P^`>\JTOX>W*P'(TD?*#X0_@,S^P9+9U?L(+=-``@HW +M&(TWAAD8W7KVTQL8PD&WC9/;##R"3+7W@M%F%LY!;!RY'Q4%P3%-^N[U.0M&,O@S."+'=G!X$K=&*Y,&`(P!``",`0`` +M`@```$4``8A=M@``0!$``,"H`0'`J`$"`?0!]`%T!UD^OOTHY'8TC-=5SH9< +MEP\.+B`D"`````@```%L(0`!4!RI6%]27OB&`V"XD!UW[-;Y/=0Z=CE1S8Z: +M252%4W](\Z]%D@)/9;#`?M!ULWWSC#8AM^+XI:(J_?N4$T+Y.L&%W,*AT!7? +M5D8.?<9E]&^[]?E\=!+]HAL1#'G;)>4&1$+)'^2!ZT3EX=$FPZW>;WVPC21) +M'RK7K*>4\:L%>SH%K'"\%S!ZP(S)R]3/8&>U<^0SP,,C94(9;1P,565#GR&4?P#$91&$T*N>_0S3 +ME9M:HR00_>B>;Z"K]1\A]!)38R?IBFVV^Z=`_=E&1\K$\+4!R>DWTG;3H.@= +MT36GO#==77G/#!V0$1.DO=3XFT!U!8BWSH18YO//N/`I+943>!*W1K;'!@!< +M`0``7`$```(```!%``%87;<``$`1``#`J`$!P*@!`@'T`?0!1`H3,<.)LK*PN.U\<\B_E%.D95MKWKX*KZ*9C?TY=_8- +M34M"9P7V!X``$&8'\S!/^9-/Q-RAN'O5ZSP*?V:>K$V4.,_(V!>U1_PF'?$R +MIVQVEDT5I\>6A4T@_'B5,6U&7V=I87W>N8A0=IR(E\67NIG]&NSVO'#)!OKE +M5!7JB`M^/TB@.32$DVK"]&#>*?3Q(IY2-;3@M?3,F.]LE#_DZ6M,2.7(;$A^ +MZ1Z<\P7X>GW/_/Q^S+OD$5`)!D)01*M@_82JS/XKEAG@UX6N)#C%F^\V<.@3 +M,U0!(-M`EQH'R=%P'VH&5NX.-/K(2)4_^J(+3_=Z7!`*59G83B=UF'@2MT9Z +M\`8`?````'P````"````10``>%VX``!`$0``P*@!`<"H`0(!]`'T`&0&2:)( +MJTO?1T#?S)59&,Q8W%0N("4(`````````%PJ``!`39^XZ9)H7W\J1M>&N)[' +MEPP(4^%UX)7GJZ^I.,-.=ZYT)Y94+*J8@*#:I2C3]7`^`=E'40C/%,?'LI+O +M>!*W1CW\!@!L````;`````(```!%``!H7;D``$`1``#`J`$!P*@!`@'T`?0` +M5`8YHDBK2]]'0-_,E5D8S%C<5"X@)2``````````3````#!0-L^[G`[OOQ"7,EAUR=MQE[G@2MT;@"@<`;``` +M`&P````"````10``:%VZ``!`$0``P*@!`<"H`0(!]`'T`%0&.:)(JTO?1T#? +MS)59&,Q8W%0N("4(`````0```$PJ```PEDCI)(54FG2P:7'8ZRD0WV6.?/F$ +MN5HB?'("3#>UY)KPHK'5]>!*W1F\6"`"8`0``F`$```(```!%``&47;X``$`1``#` +MJ`$!P*@!`@'T`?0!@`=E1RI'M*A58)(``````````"$@(@@````````!>"(` +M`'@``P!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``K&X.N2AHH,41/3M:46T' +M,4K,;V:69"O!:'*2L*E[66XN<*@QZX9NO_(`*8$I```D<0_*S^0-C"O]?_]* +M#[OZD]HR^A9*]FG29JG%.(I```<``!`!%.P4FHP_W,G_6J\OD\^2.O$W9U +MB#6GZG@2MT:M2`@`N`$``+@!```"````10`!M%W,``!`$0``P*@!`<"H`0(! +M]`'T`:`'A4HP_W,G_6J\OD\^2.O$W9UB#6GZB(``'@```!T`0$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``K&X.N2AHH,41/3M:46T',4K,;V:69"O!:'*2L*E[66XN<*@Q +MZX9NO_(`*8$I```D<0_*S^0-C"O]?_]*#[OZD]HR^A9*]FG29JG%.(I +M```<``!`!%.P4F&O>;JA\Z,\.D%0QN@```!P``$`%!B`12-YJ:F:01]M9;>@_LCR8 +ML)MX$K=&T)D(``P!```,`0```@```$4``0A=S@``0!$``,"H`0'`J`$"`?0! +M]`#T!]E'*D>TJ%5@DKBIW>PD(O/-+B`C"`````$```#L(P``T$VS(`*90>`5 +M9Q1>/%V[ZUME4;EIGC-#8B$O_,P3QH\)@JG+[V`$6""/XH_B(Q>=^>;HDZ4@ +M#P@\"1SL[R&::8545X51P)-OAK]8Y`[F1PPD!^=U;ZDNHK2@4%CTGX65O!!7 +MK@,<`@'@&>_?7M3`E<18I&":2-@V7$(B9H8OG]>\A4ITJ-8*`'(9#2(8,7&K +M@4/I-]XT(($C&S]4W2DYJM[4]H.#=&"0F10-(3E`$X?_-F[)MB.XW^0Y-K+Q +M;!SEGNJ**8'2?XKD3@YQ&\5ZDCP+8Z[E4A!^7%N?J2%OX\9)@\C+/'9P1J&H +MW9O]MW)F74)?8#?=#S3!*1'&5J_OF%,!TA1DN]W"A/0KP!A/1IY'FG+T\F"/B'1*^Z+E%GW;PS +M1Y'GRQ%8GJ%%@SA[M*J-G?AV\RCSV0,_&,C>2_@]<1\=K#@F;;NHNH"S6OWA +MCIL]IM;43-J6*F0)FJIIVKG:::I_F)(WFL5%!`%'.G!E/8,DP@=KX_Q!CL4% +MWC0#7PNHLW5(H/M`N*,^"/!L`#(GEC"M_6W@-7A@NPK>7^<^I\96-5-96=T@ +MV?/P+B5&I$D`#NMOIAC&:"V`@IM8M(=G?'@2MT:*UP@`_````/P````"```` +M10``^%W1``!`$0``P*@!`<"H`0(!]`'T`.0&R4"-P\XUU+'N.`?X'OG^1(6('UCIQ>;XH +M$")#T-PZK(O)8YY[8'ULH;RP8L&'R5?Z^;5Q-96GG'(@UA,O*B`6LOP3KQXA +MLZN`^UC,BI-!6-6`DB(.J*/0U+1RJ"U2H=ZP-SK2MGF2WS/&K(FYVOPNP0Q( +M-?J9F7M9JCY:YSR_B&.TLTLW`T@6_YYX$K=&L.<(`&P```!L`````@```$4` +M`&A=T@``0!$``,"H`0'`J`$"`?0!]`!4!CE'*D>TJ%5@DKBIW>PD(O/-+B`D +M(`````(```!,*0``,->3*0[3!.HOJ-?ZAB8@?`_MJ:#4"!6;"4D\S"-P8-`F +M5.+M28U31E@M+Q^(>!*W1C$%"0!L````;`````(```!%``!H7=,``$`1``#` +MJ`$!P*@!`@'T`?0`5`8Y1RI'M*A58)*XJ=WL)"+SS2X@)"`````#````3"D` +M`#!*OG>]A`C$0[L@-KP&U>6+.7C$"EE9,,-B11/7=#@Y]44R,\"WP3&N>(_, +MC7@2MT;='PD`/`$``#P!```"````10`!.%W4``!`$0``P*@!`<"H`0(!]`'T +M`20'"4NE5\_T?[.1S(RDCAT[M%86$K,^UBUN@QIC +MJ(&=<;P>$F`XM^@SS\XZ%IMZ&:AMZUWL()6'&YF/9Y&-C676$Z]A)%N3U0&6 +M;W0':\V>6-70-;C=39[N@5H8LBEZB>\"K3NE!W_KZ'8)NI%!HT.H[V+XAI@; +M?+HW[D]<$\LK0C^94K\(^DSQFXO!VMJ(Z3&.JE`UKB/\8MQ>0@HL2)KT%/'/ +MLI!'J6D4HUT)+]+NYZ.VF'6!$9.:I:%X5XW'-&E760?A/&NCF;?P3ICB@^1D +M=(#F/8S3:NIF`%/#B!67+O27>!*W1NXK"0`<`0``'`$```(```!%``$87=4` +M`$`1``#`J`$!P*@!`@'T`?0!!`?I1RI'M*A58)*XJ=WL)"+SS2X@)`@````% +M````_"$``.!\UEFA;3S^ED5Y1(<.2_;VRC5@SGQ^%"=8UK[$8^<6>R>6^6*: +M9Q5"R4I:]I*,A0Y"]&Q/?T"U]A5;>H-IPRUY8WDM*C:U=/L +MZ5]=>F'T,[S;?T3AK6BB"!(6-`$;N^Y\Z_5D76C,7*"$Z2`SSWVS8'GX%V:1 +M-COC(-L@89&&;(N]['ETC`W@:1?)9>N1RK&*H+BDH"W_E@I`FC3!:7TI`FK,>,+V]U<(,X'&1F_TNF2*G3L(D$;0/;_3G[##/BF(@C<.-CT3B +M`,N7>!*W1F8^"0#L````[`````(```!%``#H7=@``$`1``#`J`$!P*@!`@'T +M`?0`U`:Y1RI'M*A58)*XJ=WL)"+SS2X@)"`````$````S"$``+`CPW%_H!TW +M]'*$[7$W]V`O,G/.#',UJ%;^$&EM-E/.#0#WO`))+;HUZJ3&;A'S`P9GL#.;`2X3"L%6'"&0"JKMS>38`TNY&Q +M^;#/.$68GH>WM=H#5!*W1E1@"0#L````[``` +M``(```!%``#H7=D``$`1``#`J`$!P*@!`@'T`?0`U`:Y1RI'M*A58)*XJ=WL +M)"+SS2X@)"`````%````S"$``+`)Q0$+S]@B,*X6HTIG(J*6E%?_P@-8<9Q; +M7@!"X=UK+Q[+YQ`+HQYB:KNE.U!'"9HP,)[B_7DB1)]9Y!SGK*G/(W8(%8A:'U<@GY]6MV4A8SS>3F^T]+_:7HEB;) +MH+I9-U*KM%MQ&9ZN7'5@_SOG+9+YWX!H*EX202M[=U-M&#F;U+IT#V*=C8"J>!*W1D1]"0`\`0``/`$```(```!%``$X7=H``$`1``#` +MJ`$!P*@!`@'T`?0!)`<)1RI'M*A58)*XJ=WL)"+SS2X@)`@````&```!'"$` +M`0!QO0K->X6WW%GKX`T#1L-;PR#2W4<$6$I:(4@OI!DM<_66/YC=!G`,>)0N +MI$6<"8E(S<2F&T]!7;6'6,O\0A-:5JU62>.]9D-/S"U"$R$T/N$X(Z)5:STY +MJ!&-E[:`8_<^J2PH7G.P04H..S?>E]F(=C*QX3T)XHI@O/)Y@]]-$_ZL-K-0 +M.1`#*\?U&>0O'_N8170W[LE9#\A$`V_T&["9_$910L2:IO,:E,BYK]@\N];O +M5?'8:;+_P;'_5)F,N>=Y9ZZCH4)8FUXM'HF +M'-QCIC.B;,_5HB/@/IWO*7V>\L&DIR_+^O&Z7UMX$K=&8HH)`!P!```<`0`` +M`@```$4``1A=VP``0!$``,"H`0'`J`$"`?0!]`$$!^E'*D>TJ%5@DKBIW>PD +M(O/-+B`D"`````<```#\(0``X,V[(#2[+UU=M9UN#CY.B)Z$5!Y%PIG2@^29 +MRJ,<`%ZBG:N=9X%E]A:FKM[[4]'*+ +M0D9>PMD9D@R38P-J$O),5:R+#U>2Y.+=9G2KO\C!_H4VH9XFI6:4%!=ML&57NRH_H$O'*A_R8VJ!5+T2+E#,J! +MW'(-UO^*Q`2/?=CQ!IMX$K=&KIH)`.P```#L`````@```$4``.A=W```0!$` +M`,"H`0'`J`$"`?0!]`#4!KE'*D>TJ%5@DKBIW>PD(O/-+B`D(`````8```#, +M(0``L.4%FM7@E7IQ)#4I"YT\=[&HR!&J5HE9*9G`D)GST:(N*WH$$!D"')'\ +MUP$Q4\H25HI-P=C?3<7:JY]#I]II-WJ[K+Z?F)\&MWT,3S`.T(ZZH>\K#+\M +MX+Z;3K^E@D)71V=C3+!I[NPQ_<,B7Z7OQ@'@4WK&/&NM6]I"_,1:GN^>'00R +MV,A6WS$TJ%5@DKBIW>PD(O/-+B`D(`````<```#,(0``L-[\TH]VD0/>C#=`$3DT +MLO,31_Q&NE'D7.O%K>B8E[7&FV5_.8K#T%H+#!7;&OX[XX8KG- +M-M1>C7HBI"8)>2_'!RA'52:4<_RI7?&1&>@PY*+F^*6-VM'K(3,LD%#):+$> +M?I'F6P1?6HNKP7FJ35/E\VGO30:)&"*41'7?YN0#E_[>9D_VF/)UVGO?`I64 +M=^Z_-QC=:!D/EGWO26D-,/W=6EMWBRQX$K=&#.D)`(P!``",`0```@```$4` +M`8A=WP``0!$``,"H`0'`J`$"`?0!]`%T!UE'*D>TJ%5@DKBIW>PD(O/-+B`D +M"`````@```%L(0`!4(@RE-<5PD`Z=%^OJNC&EKG*];AFP^B?WBD=WO^UH;8; +MJX#/!L]#=5!0XJ]>]PN7R@SLI]K/>@\M<%.GX!`0(4PSB6*Q"HMSE,'D+F9`S&'A3U'2-LW8[>Q97%\@155QEQ"Z+]C2 +M7QR!=Q:1=>9.E;%1B>W-P5N[!L>C^J<)'.`P+#Z).M;Q`]`-\JV,OEOUJHM^ +M7]^V>MBA3F/%[T0P>25VI`;FN$RP:G7N:\-`KR0(8JS(35Z1%XFG'TJ50J]H +MH@A7]^S9"P_PW^QY$NX6`&*S]\4]A^9KK>\0)YB9<>K/N\BBO6Y$S';V,JDU +MC_+U5%SUTDP*M9V0`DBWH?'W+8=M5^8]6!WP\4U2UEL*&;(=!Q!=TDJ14R,' +M>RUQ[AY9=.PA5_G8Z:?:Q8??"I*;982D2?3`IPND>!*W1D$="@!<`0``7`$` +M``(```!%``%87>```$`1``#`J`$!P*@!`@'T`?0!1`3T2R.<:BF@I/\6X0WZJ.M#^ZN.3&H( +M=L#Y.'PCA?X:[GX?;/V54(LIXG<+CQX,-W!/- +MOHSB(2DD;X<8_5/.T64MQVQ`"NYU.$KXD]%(WY=Y,;^"`1YSV<6^-F#P*:[/ +M0T=G-[8:A9X/*IM4E35[#ZIL)&T<`P=4(6P=L&#-_:LNP4S$1897;5UW8AQ= +MR/Y\RCFDX4CUI7Z,&!/:3$6B`]K&Q'/&^866[(PS49ZB2?LN`4)5AOOQQ%)% +M_L4VNZ4>BEUFG:FEG\'*X1>QFK=)M2P0FOY?VVV4U-&O"W@2MT;01`H`?``` +M`'P````"````10``>%WA``!`$0``P*@!`<"H`0(!]`'T`&0&22Y!W*`WK)<) +M=X0V_E3I[-(N("4(`````````%PJ``!`C4Q2:\GX#R[M'9:1Y]RCODIMWNE] +M2N^A49H\&1^J9;^"'!*W1D!0 +M"@!L````;`````(```!%``!H7>(``$`1``#`J`$!P*@!`@'T`?0`5`8Y+D'< +MH#>LEPEWA#;^5.GLTBX@)2``````````3````#!TK*V91M`,>C=DB%KE>OH4 +MO,N"+)R#??;_D%"H4&C=L,PF?<)B?2EM&':>''@2MT:S7PH`;````&P````" +M````10``:%WC``!`$0``P*@!`<"H`0(!]`'T`%0&.2Y!W*`WK)<)=X0V_E3I +M[-(N("4(`````0```$PJ```PM"1[(N/]$'L2[CI'"%M(H['8=5IK2L=U9JF< +M]*8"@I*YHJ/T[T4K6M8W>[]X$K=&/VT*`&P```!L`````@```$4``&A=Y``` +M0!$``,"H`0'`J`$"`?0!]`!4!CDN0=R@-ZR7"7>$-OY4Z>S2+B`E(`````$` +M``!,````,+Y)1957/@GSHL!H8B-MMA8E[&98D.9>U!*W1O9K"P"8`0``F`$```(```!%``&47>D``$`1``#`J`$!P*@! +M`@'T`?0!@`=E%;2;T=?2(",``````````"$@(@@````````!>"(``'@`!`!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``2D%F$:=7-LR9X!XE9A`C +M><(UCMZ4L6^P(;:,]A=T6XYX,==F&"1WC@`(.::NR#!"]N7E,Q86/T_'WT/0 +M!<8O\)F,$&D-[KMK72A>&WT2K=%Y><6E:UT:';-]8X\POSUK*?(<9QI*$VDO +M;7O9@MEB-J#!6M'-\\I=10UM5K,?-:PI```D23YMHJ]08O,8]>_W97$,I#E_ +M5T__7D;-2WAL(^0P+-`I```<``!`!!_)]NK9Y25!C%='D<\_0IR$U`W1```` +M'```0`5/U73JK`PL`7````%P````"```` +M10``6%WJ``!`$0``P*@!`<"H`0(!]`'T`$0&*16TF]'7TB`C```````````I +M("(@`````````#P````@``!`!@````=U=(%XJQ7CAG#MG(AL?&"[6[%?$G@2 +MMT9HBPL`N`$``+@!```"````10`!M%WK``!`$0``P*@!`<"H`0(!]`'T`:`' +MA16TF]'7TB`C```````````I("((`````````9@A```@``!`!@````=U=(%X +MJQ7CAG#MG(AL?&"[6[%?$B(``'@```!T`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``2D%F$:=7-LR9X!XE9A`C><(UCMZ4L6^P(;:,]A=T6XYX,==F +M&"1WC@`(.::NR#!"]N7E,Q86/T_'WT/0!<8O\)F,$&D-[KMK72A>&WT2K=%Y +M><6E:UT:';-]8X\POSUK*?(<9QI*$VDO;7O9@MEB-J#!6M'-\\I=10UM5K,? +M-:PI```D23YMHJ]08O,8]>_W97$,I#E_5T__7D;-2WAL(^0P+-`I```<``!` +M!!_)]NK9Y25!C%='D<\_0IR$U`W1````'```0`5/U73JK`1N3IN‹?,5UY^,W4_#I[<1!,8>M(3Q3'#U +M.H,+VP>>:X''Q3*?8ILK*=@B+9D4:<^70L\Q_607[-,9*$"-E +MSO-$Q_<7Q']6!2E`AJ@'OH\N?K50Y+)H%MF9:7#O/5M?ZDNVSL"'*0``).8J +MTFG-V++=PPTV!DB'&R/7+@C=ZO-V_V9_PJ]Y"Z42*0``'```0`2Q3F324#&# +MIZN6'\+`Q3<=`"ZC90```!P``$`%%]H7^((F_YMFW]/-[XWSV!5/C2%X$K=& +M&-P+``P!```,`0```@```$4``0A=[0``0!$``,"H`0'`J`$"`?0!]`#T!]D5 +MM)O1U](@(\JG13KV4U=Z+B`C"`````$```#L(P``T-J2DL&Z%6_N185Q5#^& +M8A!U_T&L/\[PTLG'7#XRO(6"7`I&,0T2)F`(XL%H@8Y2W;7,N,PC +MZ])GV[/1>&ZA(=(I9T=%*AOIJ+EEMW-UPRU(#J]3N@)5,0%YFK&P_^85I@Q+ +M"VMPCG[4STCBJ#L\4.W)H.>7H4J:OC0:FAE%0&83ZZ`?:=N0CC*,@'%[(,., +M@W+FU>.R4TQ9WW@2MT:@]`L`O````+P````"````10``N%WN``!`$0``P*@! +M`<"H`0(!]`'T`*0&B16TF]'7TB`CRJ=%.O935WHN(",@`````0```)PD``"` +MEU?E.;6Q]EC#S]2%WF!4DR3@)7*_6_A>7'/81S_T#>J]71Y=J7W>GNDS'ZYC +M.!O8S-N^40:MK0%:J'BFI\['_NV3.]2H>*J+](Y+T$6R5#O"AR+_M4Y)6?"Y +M&4+Z.M4Z$EQNSX+\UN`S#:!(&'8G21!EX^ROS<>.C,T`67@2MT;6$PP`'`$` +M`!P!```"````10`!&%WO``!`$0``P*@!`<"H`0(!]`'T`00'Z16TF]'7TB`C +MRJ=%.O935WHN("0(`````@```/PA``#@!='Z7<$ES\B?L(2.&#M&1&SB%`[7 +M.Y,X4]L>CO#\!@J<071>V/JU*CKAD#+RDM4S*QJ-Z/5BY>HA>3TWP)8G?"@" +M=`3:$@VW*\@+DT8B"DH.[T8Z,U0,;K#B^Q%W=Y]_VVZ)Q;"EV9;H14_BPAGC +MFAXQ&^X[]D2!1VM>D%\`K#O6@HC-X@.\$@"V5-7>NHTV21P6/1RX>'B"'!4G +M4;2A#Q/":*IPQ8Q-/ZSF7KK]D).@N1APPR]!1W@2MT8]'PP`_````/P````"````10``^%WP +M``!`$0``P*@!`<"H`0(!]`'T`.0&R16TF]'7TB`CRJ=%.O935WHN("0(```` +M`P```-PA``#`AY>!H(+NO^/4D2=A]H21'V.S%EZ9YBP%2%_OH^-PWJ:1HO(O'H:L?E%(OM +MXP5-VO+C6TIS8D+HZ?4=(XEX$K=&*BT,`&P```!L`````@```$4``&A=\P`` +M0!$``,"H`0'`J`$"`?0!]`!4!CD5M)O1U](@(\JG13KV4U=Z+B`D(`````(` +M``!,*0``,)L<:^K"*!B(5=6=P@:RQ\=1$@5X,X#\']">`R(O(_:BTZ4TTF'\ +MT.K("/88>!*W1N-(#`!L````;`````(```!%``!H7?0``$`1``#`J`$!P*@! +M`@'T`?0`5`8Y%;2;T=?2("/*IT4Z]E-7>BX@)"`````#````3"D``##;T_I6 +MNJ26$I1A?B<0_EADWKC-9*SJ/3(UO-M/KL!U99!=2LB?0JYQ-.SV)GGTIPLQVO(RB +MUR5[Q%@-;48^G[E;PE':1*;0&VO( +MO;C92MQ5<$:1V^T@Q)0WJG^W9NS0??RHK8J_:^4IA)+:7@'@ZU/.&-&/%4K3 +MH8T7\!6,1&[,'0\6YV%@]<->#A]:L4!MI'>P9B.B^9]!!@;"=`/6EA6CI;.J +M23#CA0W-UDE7V@)0,99ML>71=^G]ZI$-H[6T)L8CZF*M_)O(+[2P7`D@%R:F +MV0/3BYU(OK9TQ>27@NRI+4-'@^`+[*)W#/:D6#Q<#$)+4*!#:HA] +MNJ8>1@$)P.L-+[_D>!*W1N9O#``<`0``'`$```(```!%``$87?8``$`1``#` +MJ`$!P*@!`@'T`?0!!`?I%;2;T=?2("/*IT4Z]E-7>BX@)`@````%````_"$` +M`.!@K;G>(L(\5C+'D5QDN/&>5X@(!6T%7$YXBA@2[;DV:W!@-:@_<.WS)_-% +MUF4[]5N@Q5^GYN*DOX@394L6,K1 +M\;M7UEYKU#UIE_\`@\DR/PK1+S7S"@BE.2NW1+12B=2BB$'H0,^>]UO=4_DN +MAAO'N;:MRLCRY`4KVPH8B?V%'J^8*G@N;D.2_+ZX,/-+KW'_&TPY5EL`$_$E +M[JZO-'6+S3CW^N15JF`&/P`U*N8\C!EZ3;H>*)8O:-8397^%EB8=AP,B>!*W +M1F=_#`#L````[`````(```!%``#H7?<``$`1``#`J`$!P*@!`@'T`?0`U`:Y +M%;2;T=?2("/*IT4Z]E-7>BX@)"`````$````S"$``+#+$-`HJ\%,?:JAW3@2=D5["8G,+[,`HQ83-])9,E'<%R@VIIF=E_#3D0PI(6S. +M\Y\\)#Q(+OLIC`I#M-$!*W1DJC#`#L````[`````(```!% +M``#H7?@``$`1``#`J`$!P*@!`@'T`?0`U`:Y%;2;T=?2("/*IT4Z]E-7>BX@ +M)"`````%````S"$``+#<5Z/=V$;:8T?$XPQR4L204KHU&B(WQ]^?^4C^I3QU +M^NI#8B$>TL)YB=PA8[QH]@OQMF#>6VU61^"H.0?&?Z"$XG@H?YK67&R:0ILW +M.*C8+KLUX,@G01?-AK;H1.1)CA%\>Q0"65%? +M]4P6,*"N0,JCIH$JFHY60A[>`_9V3#%^O-T'55\NCOX1*.A%H643H?+!$D4S +M?1G*`*%S>!*W1AO`#``\`0``/`$```(```!%``$X7?D``$`1``#`J`$!P*@! +M`@'T`?0!)`<)%;2;T=?2("/*IT4Z]E-7>BX@)`@````&```!'"$``0"EW@QJ +MT(&?8N.)@(*L3+]X(Q$#\+:1/_?9<5@E,`UK@Y-Y8G3_Q`(KCS/<2%PSQ]6_ +M?0(E.%`XZVU6L#TQKJ* +MM1<.=] +M5".+K7KB"SMMNB^FN6T&2]D$^<.;`QM\T +M,?M,0AWE<)VGN3\LQR7,&_F2W/XGO(XO?*_O,`,!Z"Y$(BG^Z)ES4RMO-JQG +M`-T4CX07*/X(.-UR.)%R&*-A0"0`9Y+B9/C.ET;F`D.CYRLK4(8>:S#(0IY$ +M*<*&?M1OX`_NL;C.]I=G!87E6N;3]\+%0:C/H4AI/OY'\.\?L0HLPNW.NPZB +MY,WOLHDMZ3-X$K=&#G#21#>;'1#PN;?<_W;H<P=2XGB-`#2'XM*162H1#CLNTICB^79C'+[>M.B".FN`Q-T#AT'=;) +MQ7'L+7D[%J6->OPJDRJ'D@]WG:`6&!+G[2(\GEFYYLBW[9KB;Y%08J>C**J! +MI3@=$D'D1#'8*L<=E),%1U/WRI+;;4CV1HH4`I!1G3S)/4+5M.Z"?;%%#TKN +M*/CLJYSC=Q3Z,1N%*&QXVYMX$K=&*"4-`(P!``",`0```@```$4``8A=_0`` +M0!$``,"H`0'`J`$"`?0!]`%T!UD5M)O1U](@(\JG13KV4U=Z+B`D"`````@` +M``%L(0`!4+H'6XS7$9Q!I*5-3IY3#BAW^H0?7WC+RT3%!\# +M!0)F)6M]V(6[+NZN(H?T-D'+0CLU'I>A;F/0)+:4N]^@[5>D +M\\"26R%,4@%)86F)<44T?2NN8.TPMSFA@NKL'NYIWBU`-]>QM'O@T>7>B:T- +M>+"[4:_SC8J160ZP!7SUA)S-!$8-G*[DC0D>W1Y+8M*>%9PI5@EVU_?CL+CV +M0WW8&:'0!3^+Q*TR^)[\_F$PIAUK?J^>4&N2G?XE4@#DVUR:0[9NA=U@_YS$ +ML,,=^L=\"6ZC2"LC<-5PI.@).R&3OT3D0S4E3RU@*&L640^"ZC_1_TV,O?S` +M:K;PXE&(^J77/\IJE8W6L.B<-L>!*W1LI8#0!<`0``7`$```(```!% +M``%87?X``$`1``#`J`$!P*@!`@'T`?0!1`BX@ +M)"`````(```!/"$``2#'^-K5DQUQ9QXMACO>(KC&[+CN@9GF,U+\R776G[T#SMOWN:B>L21$G,X,Y%0],[SJ,:0C^4E#BS_E*5V_8=Z8XP#+@X([I +MX^6+C^&&.)O%17_D$4#7<0(B+2JUEO!;*":%W_``!`$0``P*@!`<"H`0(!]`'T`&0&2?N[X[M)L10BT:T,JZKT +M=CHN("4(`````````%PJ``!`$@TU$^UY!?<>VH7\-CV6@V$W64O<@_J`>Z#Z +MC[+:;0Q@'ZZ7R2%"5ZE<_?(LI4MXN^M?*\BQ;UKPF4HY>!*W1O**#0!L```` +M;`````(```!%``!H7@```$`1``#`J`$!P*@!`@'T`?0`5`8Y^[OCNTFQ%"+1 +MK0RKJO1V.BX@)2``````````3````#"M3"$$"/.__BI1DSAF/AM[&K,0$8K$ +M]BIL/GA/]^\75?BVHOX9#97`?-5,TG@2MT9UF0T`;````&P````"````10`` +M:%X!``!`$0``P*@!`<"H`0(!]`'T`%0&.?N[X[M)L10BT:T,JZKT=CHN("4( +M`````0```$PJ```P<64-`2GL":?<7>KC!6:X5"[6I0HXGG:,`@``0!$``,"H +M`0'`J`$"`?0!]`!4!CG[N^.[2;$4(M&M#*NJ]'8Z+B`E(`````$```!,```` +M,'UAZ4"P*M!Q!0XSMD2T&=2*TD,LEB>?&(4`R_TI?`J2D"KW0PV)5VFI)2-( +M>!*W1MRA#@"8`0``F`$```(```!%``&47@,``$`1``#`J`$!P*@!`@'T`?0! +M@`=EU5[OT#IT/!T``````````"$@(@@````````!>"(``'@`!P!T`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``)`^7$RT5.T+"`_V5CHVK)[GYJKZC`-,`C\H?/1 +M'8>`8T.IX]![?J8DD::(L#LI```D?YSF+K-T:!T3MMWZ26C\X$Z3J;F@K5CU +M^*B_C]!T$?TI```<``!`!%9#!'B7E(9H^]PN_I[*1\X48HY-````'```0`5] +M-C#H7?-:D/&1"/>#LR%GIKY(N7@2MT85L0X`7````%P````"````10``6%X$ +M``!`$0``P*@!`<"H`0(!]`'T`$0&*=5>[]`Z=#P=```````````I("(@```` +M`````#P````@``!`!@````>F>'8(3T*06O+XZ(8E(:(7:;D?=W@2MT:ZP`X` +MN`$``+@!```"````10`!M%X%``!`$0``P*@!`<"H`0(!]`'T`:`'A=5>[]`Z +M=#P=```````````I("((`````````9@A```@``!`!@````>F>'8(3T*06O+X +MZ(8E(:(7:;D?=R(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``)`^7$RT5.T+"`_V5CHVK)[GYJKZC`-,`C\H?/1'8>`8T.IX]![?J8DD::(L#LI```D +M?YSF+K-T:!T3MMWZ26C\X$Z3J;F@K5CU^*B_C]!T$?TI```<``!`!%9#!'B7 +ME(9H^]PN_I[*1\X48HY-````'```0`5]-C#H7?-:D/&1"/>#LR%GIKY(N7@2 +MMT:LY0X`4`$``%`!```"````10`!3%X&``!`$0``P*@!`<"H`0(!]`'T`3@' +M'=5>[]`Z=#P=R4H)=>54V;0A("(@`````````3`B```P````+`$!``0#```, +M`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``!-N_!F` +ML+I[(V,%4`+_MS_K2IVB8[J(]E8)SW7N$":?$O>\[G\U5TI4:LV_2>A,(UNM +MH)3;4C$_5-990S*0``)+B#UGYI+;@] +MFD@0]#AH8=M[X_O+:?!EP%)@V/H;YF#S*0``'```0`07(X&'Q5/?F2,,U)LB +MKXE4[`800````!P``$`%VADI>M+033[K#5M,OKF[I'8BXXMX$K=&21,/``P! +M```,`0```@```$4``0A>!P``0!$``,"H`0'`J`$"`?0!]`#T!]G57N_0.G0\ +M'E::BZA(G.Z+_C#\4_QCF)W0S12FHE4I+*<_P^ +MC)646+P[8+W\B@ZCIR#W.A4W9V+2$:;@E<3>G+I=7_B!V,2\IQS#>$H0F,#* +MP479-'@2MT;C*P\`O````+P````"````10``N%X(``!`$0``P*@!`<"H`0(! +M]`'T`*0&B=5>[]`Z=#P=R4H)=>54V;0N(",@`````0```)PD``"`B%@%O).% +M\C/OI7>_U_D[,KH>&(-)A1+CZ7I*9,;#":`[L:8-W*C+/-/O"?O8YW@ATUAZ +MIFO6"=^1Q.`AA-)*%K4SEMP37:?SMF`X/2E4O=QKBB/6]\(["'$QF/^!M8>6 +M)?Z<3K\(=2_WTWC+ZD!1.*+XWV^9&7BQ/)PZTGD2MT:V"0``'`$``!P!```" +M````10`!&%X+``!`$0``P*@!`<"H`0(!]`'T`00'Z=5>[]`Z=#P=R4H)=>54 +MV;0N("0(`````@```/PA``#@DA<'_V4+`-E`1@-C5N!,0`<#TJ&[MP,&[W3. +MNH$;`\WDS*=D3EYA#<%`??XOX2A5G^YAHRM@[P`F\N=]PV+TVL3S9LCZOJY" +M5M_-U&=4QA@,!Q]!P9ZZSC_:!8.PXVB@/II"8M8WMK^20J$;C]=2( +M)N&C^Q$Q'L.8/X26G?2SJ>IDV?E]MO5,B)TG82#RE5:6O`B5N[B4GZPT3MFQ +M&_Y#H9GC.[U,*1[,%7D2MT8A%0``_````/P````"````10``^%X,``!`$0`` +MP*@!`<"H`0(!]`'T`.0&R=5>[]`Z=#P=R4H)=>54V;0N("0(`````P```-PA +M``#`09J,\?<1`A4EM_NUN*?'8=>U7Z+&8>&N-YPBZ*ZSL']TGTV)"OM0,XC/ +MVCYW]&/K^8XL=%^(JH!>?Q@A%1L8I.)F?)(WE)>F6E^"(A=L`QLOW.S=(0:9H)"OV>S2)'&W;#B\@)9@R.&R^ +M,T@^BKZXZ0N%@,03KSED;647O;@#`P>K>:_JW@`4O45$X.;\!,$=;R1DV86- +MF9[S<:/C5^%[*K-Y$K=&2"```&P```!L`````@```$4``&A>#@``0!$``,"H +M`0'`J`$"`?0!]`!4!CG57N_0.G0\'1*W1E4\``!L````;`````(```!%``!H7@\``$`1``#`J`$!P*@!`@'T`?0` +M5`8YU5[OT#IT/!W)2@EUY539M"X@)"`````#````3"D``#"^T#6CWQ?2M#IW +MRV`35156Y%SME#N6(G2HKU:H@]A^142=.CAKKBWN]KW/GGD2MT:[5@``/`$` +M`#P!```"````10`!.%X0``!`$0``P*@!`<"H`0(!]`'T`20'"=5>[]`Z=#P= +MR4H)=>54V;0N("0(````!````1PA``$`/_`*S^8\12B79H_M1N6U<-'BMGZ&_.&)+JU!MWX`$8U$Z +M&>+ME><6\6K1*W1K%B```<`0``'`$```(```!%``$87A$``$`1``#`J`$!P*@! +M`@'T`?0!!`?IU5[OT#IT/!W)2@EUY539M"X@)`@````%````_"$``.!2(%U^ +M]<`\V=?4!%;'F<%0'O/BPR8GF4?6!K9?GBK>;T1E3?3Y&)I&Y`=-$R6O%(K+ +MZ=`U+/8]2O+9ZT'+6A]OY;D<6#^D';E-CYC\. +M5$W`[A^='G4`1(L^87D2UM\2NL-K.PR.'GG&/4(^UUCU>K3S\^'^,LY7Q/EB +M/3N>0A*QW\$Q#9OHH.C5R[I7UQ6CUBET0JGYI[-X]&;>1*W1O!R``#L +M````[`````(```!%``#H7A(``$`1``#`J`$!P*@!`@'T`?0`U`:YU5[OT#IT +M/!W)2@EUY539M"X@)"`````$````S"$``+`F,RW>G6EJQ +MN,2:-D6F3=%D/:\]`$JP6Q!:BUFQ+_TO?>! +M.LQQ%C,9Y*1[OE$+@1&FD3[]>1*W1D65``#L````[`````(```!%``#H7A,` +M`$`1``#`J`$!P*@!`@'T`?0`U`:YU5[OT#IT/!W)2@EUY539M"X@)"`````% +M````S"$``+"]6_R&U_45=P:8TE&XV\Q%F6.1^0T9I;D^.C),F3ZTEQJQZ$A[SS*>3]V1J"M +M,G:9!"G^$W'>F2O38U"^),XN9_OOSV(`'.81;L_A)^GSTM+W`HD%(^+4@U-' +M$*LIS&6?]4B&2\>YR6O`:N4$L&L3''X6Z@][EM0*D/%LKDB?:BJE6(WR2_HG +M>1*W1@.S```\`0``/`$```(```!%``$X7A0``$`1``#`J`$!P*@!`@'T`?0! +M)`<)U5[OT#IT/!W)2@EUY539M"X@)`@````&```!'"$``0#:'N.68G]Q'LLC +M9[9BN#K>LQ^69RN^MM`>-,7)V@EI(KATT.U#40-_H?B9)N<'_P.@%W +MB6TV"GJ#3F`WIL,'"1Z39"ORSN?P-:,-[X@XF&J6C=1!7LDJPK%!4W_5<6^= +M,I52,_K,B/$/&L\^/#((:1$1OB>/ +MCH,N@ZDI[>);Y.`XQ&%$87#@M0'6Z01L%8#9#U@O78QI"ZS'3R^FD$=^S;$^ +M"Y0T)86.;!422Q'@"D2?1R5Y$K=&#[\``!P!```<`0```@```$4``1A>%0`` +M0!$``,"H`0'`J`$"`?0!]`$$!^G57N_0.G0\'>24(R:$SIL?\&/)7?25/+R +M:<;:8YPCHL&*[#Q1JWB5A83'Q6GA4,3V]3,/Q7O,M`)/_IUS!%6;6HQ[LP!4 +M?NE-5H#LLV$$)*+]9+G%J:3">=$HXLELQ%]LH\U?`SLB.H*V';LUIE2QY2FN +MTR@AKXA>]A,@Y\1>DTARA4=3.^[2QW"A(5VR4*&`3 +MS4+;DK/V[[+?T4DLAX+`?YXYS&+_O3`$6J51Y!%@``0!$``,"H`0'`J`$"`?0! +M]`#4!KG57N_0.G0\'<76DA8?MDX(6,YRQ%1I#F'66`(,A'73),MBJ@'(9`+R\FI_)AAD +MU"^:;*]M!%>S]8UU!9;8^[NL'M.VKP464.R>E2ZHNV307X5H(CAM-I3U%1QA +M^C0`1D1%`J2WI^"V)7$A--2HD$AG2E4A_%Z!@)Y'$)_YZ^1)@W#BF1?EZV:! +MYAQ0%KPJW$0?X=D47,0(C?M'^S"F'KJ0\;`!DOMY$K=&$?```.P```#L```` +M`@```$4``.A>%P``0!$``,"H`0'`J`$"`?0!]`#4!KG57N_0.G0\'M&"^^M2"MQXZ-9102"63KP;N^AZSHN7O*RT;9RO0$<&```0!$``,"H +M`0'`J`$"`?0!]`%T!UG57N_0.G0\'FS_CH/' +M*L4W8LSVU6,GSJ2^D]^71+3!.Z#0+&7TY=8P=(B7EM,MV])VL%K\0RO/2\R[ +MV,.311-<\M$OVP1.+IF)<^S^1$`2R6I!6OEO)61)>KKKX!,D@+LJ4KH3$WY# +M5TI-]_8KLRZ=/D@"1^&J3>O]O[IOT%S%T(0(-6XJ2M--DSC2KMF,%@B757`>73"L&\ +M+ZZW?BM7AB6\1)WGRCM2![=T90288M!94PL:O65@+)H?>4'\WA3KX`_W0ZTF +M1*W1II+`0!<`0``7`$```(```!%``%87AD` +M`$`1``#`J`$!P*@!`@'T`?0!1`OQL?E:K\>W#\Q?OGXG%%$S)I +M3\CO?9(CTQM+`>!4ND_D,11>=7.H5_R[ +M\.B!,J]K5#VK>K#/[63/J`*B.$?;8O!$\#XN$N%%.:E,$<+P,C>[";SRT')K +MP_QSN>TOGR2%B.0.[TX:W'KX/:&Q%X:``!`$0``P*@!`<"H`0(!]`'T`&0&25&0$Y<82>![ZT20J5XHWI8N("4( +M`````````%PJ``!`!O:X@D%TU* +M^K_J9215O=X&D@TH=PITK$E7B8=)Z%&\A;H5>1*W1I%^`0!L````;`````(` +M``!%``!H7AL``$`1``#`J`$!P*@!`@'T`?0`5`8Y49`3EQA)X'OK1)"I7BC> +MEBX@)2``````````3````#`,U@$.=/%^!A3:>3R4]G.-TH>^4NIM9`![ZT20J5XHWI8N("4(`````0`` +M`$PJ```PT5@G(S1_F!UA`T#`-_)1'?&\_.8/X!("[GB8$.K;L,9[<2NK?+F: +M9"*60MUY$K=&(9L!`&P```!L`````@```$4``&A>'0``0!$``,"H`0'`J`$" +M`?0!]`!4!CE1D!.7&$G@>^M$D*E>*-Z6+B`E(`````$```!,````,-RSZ.#8 +M5H)8*`H$,;L91*W1BN7 +M`@"8`0``F`$```(```!%``&47AX``$`1``#`J`$!P*@!`@'T`?0!@`=E:H2` +M:9M5_F@``````````"$@(@@````````!>"(``'@`"`!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``__QB=]I0>T;D:Z@NJ'&J/8(PE4.PI(:S@EPY +M],%3IP5U"1K)ZW+__C)]><;<%@508&K51*U0J<1RFP*#R9QRT:O,)^[:16=$:]"EEU;D>M-GYG'P"GE(````'```0`49=0&G$`7E +M@;8,Q.)V?=\1LU\39GD2MT8,I@(`7````%P````"````10``6%X?``!`$0`` +MP*@!`<"H`0(!]`'T`$0&*6J$@&F;5?YH```````````I("(@`````````#P` +M```@``!`!@````<=2/I?1)T_1`.V#Q"I96G\N/N.&7D2MT8KM@(`N`$``+@! +M```"````10`!M%X@``!`$0``P*@!`<"H`0(!]`'T`:`'A6J$@&F;5?YH```` +M```````I("((`````````9@A```@``!`!@````<=2/I?1)T_1`.V#Q"I96G\ +MN/N.&2(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``__QB +M=]I0>T;D:Z@NJ'&J/8(PE4.PI(:S@EPY],%3IP5U"1K)ZW+__C)]><;<%@50 +M8&K51*U0J<1RFP*#R9QRT:O,)^[:16=$:]"EEU;D +M>M-GYG'P"GE(````'```0`49=0&G$`7E@;8,Q.)V?=\1LU\39GD2MT;WV0(` +M4`$``%`!```"````10`!3%XA``!`$0``P*@!`<"H`0(!]`'T`3@''6J$@&F; +M5?YHX%ER6T\$.T`A("(@`````````3`B```P````+`$!``0#```,`0``#(`. +M`(`#```(`@```@,```@#```"````"`0```(H``"(``(``!\ET-UP82,TZ0D@ +M??&X%8,_L6HB3V/'_:442.4B/4`U/KNP+)I.)B+-ZW[KI@/>KA]/+*0``)-B/$))```0!$``,"H`0'`J`$"`?0!]`#T!]EJA(!IFU7^:.!9_ +M1*O6]'8.H6^=G4^5M#EV4^]U#]7(!%S86Q#ZPP<#RS-88/@ +M=E&QWBJ)O42G48(29+@"+<;:CUZ3CAEAZY +M8.HV[Q"=\9C3UQLZ.%B(^>/#2E\!=['^R-L3';1D9_.RYI\32#HO9$;6;^^; +M*-<86(T:3"'SWZ_UYW"L.CJ( +MM84(ES@,Y1(]H7;,+7B/6DQ<-0P55'D2MT9"1`,`'`$``!P!```"````10`! +M&%XF``!`$0``P*@!`<"H`0(!]`'T`00'Z6J$@&F;5?YHX%ER6T\$.T`N("0( +M`````@```/PA``#@L=]>=7L"[W4KQ;01*73;4EL\G@LQ>F:8J&@M^NSD.`&5 +MKO/0:\"L^"),8<0`#&S=#.Y2?>>HGC456D(OEF8$DERTMY<$RC\B3/:($N3V +M8Z0A^NJ9BC&*/0L/,@XX8#::B(A,C-[7/F]^;'(GI*H7SL;QFJ-C&@72FA]J\37.(\;G:0CK] +M00FE9*J7X7D2MT;>5`,`_````/P````"````10``^%XG``!`$0``P*@!`<"H +M`0(!]`'T`.0&R6J$@&F;5?YHX%ER6T\$.T`N("0(`````P```-PA``#`>L#8 +MK20W;$GJ=^JTEB7M;:%6U[F\\5$[(K>_!#FJ(W='I3\^@25(GB^:\39W +M;>0+2'_HR5`FI^G\:Q##^_=(@A%5K$$7G75@9%#C$?U(4O-0L,,3!+H6R!?P +M:UJ$V;NGTC>1AY`-E3_@/,R.\0E=H1F6HVIW"I:+)Q<*!18#\'(:I%I9/]@P +MA13(`BAY$K=&8U\#`&P```!L`````@```$4``&A>*```0!$``,"H`0'`J`$" +M`?0!]`!4!CEJA(!IFU7^:.!9"?8(1*W1A%[ +M`P!L````;`````(```!%``!H7BD``$`1``#`J`$!P*@!`@'T`?0`5`8Y:H2` +M:9M5_FC@67);3P0[0"X@)"`````#````3"D``#!E3C0L&0[ST>\DEJ5)#B;@ +M&D,)YC+[*]8,'.6^X5*?!(%"N_6OT[X+O9# +MI3RM0@Q(Q-5_NVR>U<&[8;1X(.Y7I\^E+EWE-/F8MN=Z^2EO:-B2Y5I$LD!- +MP?;'0*N<+U+!"?"&]/7N:@9E[`,55N+U%&H&)[)W[8-J1I!&!0;H;+\T@N0( +MT=,N0HL&/B"ESJ>-,1\H^/#_O6TJ8;>?5QRE#5DGA)QFU62+?S@=QF5W3HU` +MZD'*N+EKYO*\\6UP:R[S\B2MO1I.I2__M*='J0<1[6.S0V7J&8&E"`OD%,8B +M>1*W1J*B`P`<`0``'`$```(```!%``$87BL``$`1``#`J`$!P*@!`@'T`?0! +M!`?I:H2`:9M5_FC@67);3P0[0"X@)`@````%````_"$``.#0X*N7Y@4W+3": +MY(OO%L(H8T>@'@PL7A!EWG@>?W>@D-_[(="@A??:"=4!,"6&GO\GIT21<7AQW(9[BF^*.O2<@-K-L,Z*`#ZYB\JH[>Z6?ZY,I# +M`V.DW*$1]F@W(*D5-]W8Y+L80?<[7;]$>B>\D!>QC[,-1[0S_M4L*_#P>]'+ +M\?/0@=-"`QP[MTF)W>.8ZT_BC%7\"Z(V/GHZ.;1`>1*W1HVR`P#L````[``` +M``(```!%``#H7BP``$`1``#`J`$!P*@!`@'T`?0`U`:Y:H2`:9M5_FC@67); +M3P0[0"X@)"`````$````S"$``+#\9XAX6_@1&N$*QYHKPSGHHMQJE4!%J%2& +M#H^VO\K>2_ZX:,2P-\A0;!YNGKRTR&MRN1:3/?!PM@3KVA``/%*P4HCQS)KV +M49`4;,!J?(P_Y[F.PJ,Q.BC3;HQ?<83#PE[P.]%?YW<`8]IC+?"`7ET)D&IE +M):3I<9B6*.$)+K0&34E7+(\L+F=N<&`??@U]1F)7EKX'<[/"123\<.AV3*_/ +M(?8TI]QJ:6(KGAZX>1*W1NK5`P#L````[`````(```!%``#H7BT``$`1``#` +MJ`$!P*@!`@'T`?0`U`:Y:H2`:9M5_FC@67);3P0[0"X@)"`````%````S"$` +M`+!4F5)'FQ@DP0@A!(I5,\FX3RAD:U/4'M-9Q!RX0KK^YI!G,C": +M'B/#T8=5M[>O;1M2YN$^;W%*KD0W)06HHR2&NC5^1P,-R@]T?]#W4F;GF\XP +M@FDJN\&]>]6ZCR]>F5K%TYO=0-0F@Y#.:V/D@9&D2[DXL!8E+K:>V>"^['?E +MW8[VT*WLZ.-BTZG#%2E[<:'79H$T\*:&/N4$[TF@FF[X0:2PA_'U>1*W1C7S +M`P`\`0``/`$```(```!%``$X7B\``$`1``#`J`$!P*@!`@'T`?0!)`<):H2` +M:9M5_FC@67);3P0[0"X@)`@````&```!'"$``0!<=0L:B$RS2`A@W+@O?YOL +MA%+E6;T-GDUC*5@H_^GX$L&QV(/,+7^\XP1."@>.1Q[+V_TLGE]T30"`+N)E +M<*]>OT`X:'STD#+[R[(T#.@HQ@N$^>5%"P-/^N +M!$N9,LM9JGCKD`(%6NB/^7DFXV,```0!$``,"H +M`0'`J`$"`?0!]`$$!^EJA(!IFU7^:.!9,S"8$WQ=>=+9 +MO3B2:FMF7_X-8`P<*9\=XK>G1'JBQ5!11K?;2CCD+$=`F5=3:1?4O)]]CU?( +M)=##W4GH0?MDYH"XFI:G[VMS'.R?.S%2$;NFRIU1*UQ\6E&U0XK8K.>]EC/- +M)G.86-94\J@D)H_)'_+&I_:KK%*\NO_3O(FTQK9#.8VB]ATM51FL@WUY$K=& +M8PX$`.P```#L`````@```$4``.A>,0``0!$``,"H`0'`J`$"`?0!]`#4!KEJ +MA(!IFU7^:.!9[?*'M?G+@(DRF#K3YZP](2?CW+OU<17@'MNR/KEN)U%/)Y$K=&J#`$`.P```#L`````@```$4` +M`.A>,@``0!$``,"H`0'`J`$"`?0!]`#4!KEJA(!IFU7^:.!9Y@]S&\ZWQ`LFDLFX'BD8A%] +MZ:Y<9ZJ1]C5UM/$6?3P;YR%)RBQ]W4*-_"+^K,@5F-!.3[1DU#GDKTD.>N%# +MHL@TROEY$K=&.5<$`(P!``",`0```@```$4``8A>,P``0!$``,"H`0'`J`$" +M`?0!]`%T!UEJA(!IFU7^:.!9&T2IH-,9*$G&B'5OTK)S'&AL/Y&M0>(_:8RY!IK;`[F'A=WX +M"R/]P\+26H5GF\%JTOB/>T;VIF!_HS,26XAGD2$[VU3WT[*ST-!7@+@K7Z[; +MC#-K[\M)&0,]>Y(EE.+3?+D\XW@QA6G+#`\_A!ZHA&@K]#0P\"9LY,P[(!!, +MXXQ.VY&?B9I#X^_1C>@=V5[Q^F&K?3P`@UG6;&VQEV$J"8H3'RN%F4+8RA.I +MP:PTCZ;1!;L?FQP9KI=)(Y7(SV9_"9)\MZ1!GO=;7%'[$]I9.J7B8!Q.2E`I +MA"OW=AT+>7\?2Z/P^-P74$ZJK7_7W%Z\2[SQ<&I5G3`05+#:EY"8Q.#YT0F$ +MS\I3UVD@_#_?H5.O22:PI!5@SV55`2-5MZ?'5BQ.FY16#^TW6I"27_!4SHG! +M8<=(B5\QP6*BK8*^>1*W1G>+!`!<`0``7`$```(```!%``%87C0``$`1``#` +MJ`$!P*@!`@'T`?0!1`C#.L/Y(D>(OPX48J]6U"&_[-N7T]9T@1&O/M/>HGE8J_QXJ,&=@D=0DD'EM(E]#2VBC=[)'; +M="3^H_(OW08D+A=OLO+#&LE!I#G^9?\3+FM;.6"=95:A_'\BQ,U1Q5"!5K`Y +M_(87Y'%TCH,I76O5I%#[G(7M=^W!YL4:)T%XU``!` +M$0``P*@!`<"H`0(!]`'T`&0&21)LQ6GA@HA^3:SG;!$#N'XN("4(```````` +M`%PJ``!`+NGHY``A701HG4[]\3F[B;>T2;!<=J.I`VYSL-YI$Z:.6$EAY*9L>1*W1B*_!`!L````;`````(```!%``!H +M7C8``$`1``#`J`$!P*@!`@'T`?0`5`8Y$FS%:>&"B'Y-K.=L$0.X?BX@)2`` +M````````3````#"Z5\INT\8T:Z2,A?J,B3QF:B3?G!NX7Q^M;7VRB:)]30^< +M98QW(C-<59]>[WD2MT;&S00`;````&P````"````10``:%XW``!`$0``P*@! +M`<"H`0(!]`'T`%0&.1)LQ6GA@HA^3:SG;!$#N'XN("4(`````0```$PJ```P +M=%.N2QBA'RWC0(G%%]:*ZL]!`'[FD0SN<1;"MK7?AWZW=S%`@ZSP`#P[T2-Y +M$K=&,]L$`&P```!L`````@```$4``&A>.```0!$``,"H`0'`J`$"`?0!]`!4 +M!CD2;,5IX8*(?DVLYVP1`[A^+B`E(`````$```!,````,,80PU4>RB@QSAK, +MK#:"7;&,]G+8FE!UR%O@`.F^T%V*";JD[&9[Y]I05*GA>1*W1N77!0"8`0`` +MF`$```(```!%``&47CD``$`1``#`J`$!P*@!`@'T`?0!@`=EK3);\PSONUD` +M`````````"$@(@@````````!>"(``'@`"0!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``XS2^2J%]A_PQ+^IG?B4P#[0M^QM5EG&B?I6^4^8@L/2C +M57BQLPU3ALJ"OP&*/=2.7QQ)IY`N&D`=! +M698I```D_%V-]JN:Z6!R7R?4_`Y_E+G>=N0Z>YBZ'Y(:1QA=9O> +MM..#:O5S?7D2MT9QY@4`7````%P````"````10``6%XZ``!`$0``P*@!`<"H +M`0(!]`'T`$0&*:TR6_,,[[M9```````````I("(@`````````#P````@``!` +M!@````?^5FA%FLI3EM#E(+_P@"6-L_IO8WD2MT9J]@4`N`$``+@!```"```` +M10`!M%X[``!`$0``P*@!`<"H`0(!]`'T`:`'A:TR6_,,[[M9```````````I +M("((`````````9@A```@``!`!@````?^5FA%FLI3EM#E(+_P@"6-L_IO8R(` +M`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``XS2^2J%]A_PQ +M+^IG?B4P#[0M^QM5EG&B?I6^4^8@L/2C57BQLPU3ALJ"OP&*/=2.7QQ)IY`N&D`=!698I```D_%V-]JN:Z6!R7R?4 +M_`Y_E+G>=N0Z>YBZ'Y(:1QA=9O>M..#:O5S?7D2MT9X&@8`4`$``%`! +M```"````10`!3%X]``!`$0``P*@!`<"H`0(!]`'T`3@'':TR6_,,[[M9)IRP +M81)@O8(A("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```( +M`@```@,```@#```"````"`0```(H``"(``(``.C>0Q1\#)\B*K<;15B0_5I` +M8,IT.!8+R=X.6!,IXRS[F2]F\L=^1J'K256@H3![@14#7O#O8;PA94I,'W^8 +MO/#0&0Z^W@!;B.QD?-C2`4$HV*():KN+28S4=$<.)M#-J;X/@``0!$``,"H`0'`J`$"`?0!]`#T!]FM,EOS#.^[62:?7!;#'W`#&(G;8\C%]1C]$2J,YQC=JJI0I--U#^/9 +M6-_?750"Q/%^5(5@))C47M'+:4^H43K,*:/,\\JI9E70%>JJ>K;@BS>F:E&V]&+&=ND_2`+S=WD2MT81@`8`'`$``!P!```"````10`!&%Y```!` +M$0``P*@!`<"H`0(!]`'T`00'Z:TR6_,,[[M9)IRP81)@O8(N("0(`````@`` +M`/PA``#@J1@<[%2OL(N7VB#,UW->+0J(_4R3RV\AL?B6JB&>#NMA(FDMM6B$ +MJ:BON48E5]\3&7E$,XR?]'DY(!F"@/CEC`M&I5B +M1-'%;W1CG<]?R?;)RWK>[;P^I2[B06=H,=#.')Z,^E"'LBEBB*S +MEGD2MT8QBP8`_````/P````"````10``^%Y!``!`$0``P*@!`<"H`0(!]`'T +M`.0&R:TR6_,,[[M9)IRP81)@O8(N("0(`````P```-PA``#`"NLM$P;5./MRWZ%VUV +M[);,6F3P7KY[%N3$$76#WE:4:;WX@0?0G7*-[7Y#!:L^9*7DC,?AICTWG1,2 +MD[]H=VZS0F2P6ZB8&1`:K2U_YZ0K-^9YWK +M>->CRGNOS%$W;OH*OG(9Q*"*)Z#3Y-^6O-Y\D2@"SA._UGS])M$>U,66_A-Y +M$K=&/I8&`&P```!L`````@```$4``&A>0@``0!$``,"H`0'`J`$"`?0!]`!4 +M!CFM,EOS#.^[62:1*W1JRQ!@!L```` +M;`````(```!%``!H7D,``$`1``#`J`$!P*@!`@'T`?0`5`8YK3);\PSONUDF +MG+!A$F"]@BX@)"`````#````3"D``#"UQ:(74\9'TX6N^0GI!Z.D%]8PQ!W^ +MTPXZEI4*("JW.`(9IYZ#F\7@"LQG07D2MT9WS`8`/`$``#P!```"````10`! +M.%Y$``!`$0``P*@!`<"H`0(!]`'T`20'":TR6_,,[[M9)IRP81)@O8(N("0( +M````!````1PA``$`*AR7+'J@<3EBF)R#IHQ5@03=K(5FGL\D:_M5(KVX7#G= +M(U`/\6F??.4JW+KWNHBH"'8,2((B_";7HFNN^#6DE)BIIE\@NTH!_DD1U<$6 +MKAJJE"T("UW4X_496C@&.QSPDR,U(_:")EWO-V!S1XM*\C5])$+4<"$501@+ +MB3S0.=_Q,3-2L>"X`S_?_IW\^"VOG8=Z=XNC;MO7^OS@.E(6CJXW_0!6CGDI +M6M^KCB)UTIFRH@&&>)8$ROV$A<==!0V$_*W60T$+IS9BL)B(AK1*W1F;8 +M!@`<`0``'`$```(```!%``$87D4``$`1``#`J`$!P*@!`@'T`?0!!`?IK3); +M\PSONUDFG+!A$F"]@BX@)`@````%````_"$``.#Q%L70]=ZB59`A +MAO-/]%4Z;;<#T'ZQ3GC:_7'(Z%,[E\HC:=[:B.'(&\R0QP!:RD7K;ZX^ +MIP1/7N+=>\YT%Z5(*?K-)SN5%8&)PJ,)/3*0$\&&Y5W9$_9*1IS5D]\QT[:US+-XCS&\=,V\B@6/_E)2WD(]7M>1*W1BOH!@#L````[`````(```!% +M``#H7D8``$`1``#`J`$!P*@!`@'T`?0`U`:YK3);\PSONUDFG+!A$F"]@BX@ +M)"`````$````S"$``+`,.9KT&!B\ZU">)D0>)V4'W`1CEA6?<^X-H(MRN8*, +M&3+#@6K`N^O)IR+N)+F>SY`/4!AG<5?#$?QM-FES3<15<@G9FQ*YD9[#_`QP +M-BP`GWW['^L6:?"6=N]);Z.'.X:>Z-!`F$SF\'Q_&Q^Z8]+W*VW-[W*,=_;# +MVHL6;;MNWU?-[ZAI7:6EMZ`N>OD5W^Z=I+E9@%#KRK3N+O?>7NI39L6W4V/^ +MWE!!HZL&>1*W1LT*!P#L````[`````(```!%``#H7D<``$`1``#`J`$!P*@! +M`@'T`?0`U`:YK3);\PSONUDFG+!A$F"]@BX@)"`````%````S"$``+"Y06Q( +M'\./QBSZ@0OV"U2%%O0`8O0&&YA5-@D!&U:A2OJ-)/5)]:*TGFT5<3W,?I'M +MWKY&1]:_$SB^%3KYP4X5?%;?C"`T=L=]SB@R(W\G9E]?9RO'+;+[LE$O"#W9 +M;(58T6N.6_[LT-L"NDTFY&0EMFX,R\XB-)7LBB5",UK>`08W'T^XG0>Y@I>U +MV<#O6^:RR=/@?H.5K[`?UM1*W1IXI!P`\`0`` +M/`$```(```!%``$X7D@``$`1``#`J`$!P*@!`@'T`?0!)`<)K3);\PSONUDF +MG+!A$F"]@BX@)`@````&```!'"$``0"JC2TYD%-?BPO>^RP/!.'>PMA3!?JP +M>#GAOJBV)QBQ$0(6,MDUOIL*W)>2B3V.Z^W]HA:- +MP`3AH'@.4"[Z)7')^OTS"8P0*EUTR=V6@9QB\H.!+MD:T>PAS5&_I5E,!,L= +MD\-3/N`N']XB4S1,>*L5SA&C*FK@:"B+G!$D]?]C3P@DQ9&C&)T\.$-S5B=4\S*V`:](E( +MS3$=>P5`/NAX@F>;-B[%]CZF>ZL+:58^HFR*_C7YL-QK+9W&HO$9UM,@1_DA +MIPW4!O!Y$K=&:38'`!P!```<`0```@```$4``1A>20``0!$``,"H`0'`J`$" +M`?0!]`$$!^FM,EOS#.^[62:X#D[(9-F4;B!BDQ^1:`N_+EX]6,;ZDOV+P&.ETXY_@5V/?&[U&O+ +MVGK%"BKVPI$>WG[]1";/O:7'4VN[B"7+3ARY7I:Y\$%LF[-9N?DN3Q5,=W-F +M(U>L/],$L4\3XK33-E)EZJ(/@I%B<@ZEWMHID\IBP@4MA%1JF,5B4\*$H`/= +ME)@F.2]7EPI2XLAYZI+^$H*#77_?"B'SL-75S0;4N=@P@:.M2(U7G@Z/(O4H +M\SJN%\.^BU:P%"YEP4M5(&+::1W9"?QR06O`C!$R1.`A-OIY$K=&ZT4'`.P` +M``#L`````@```$4``.A>2@``0!$``,"H`0'`J`$"`?0!]`#4!KFM,EOS#.^[ +M62:"&7GG<45[RJ.1]0, +M3:W(,1WQ(I#.':H*_KZ"F:H#6ZQ-49Y36A3(L3--7U1QW=V/5_Z`7]9^PT1V +M+4Y4TBK&(&FL)F?2GHHM(XTJ%['9)RTRAIM%LS8Q7)F_&_A@7[$9QLR+YGY+ +M<8N6N91YW-7J"JTGM@D!+2@LB._.\B_(DEE?(\V5;"RL3AM)M]K^NI>$:Z-> +M8;RUCIZ5R#P%::W-'U]*EI9Y$K=&7&@'`.P```#L`````@```$4``.A>2P`` +M0!$``,"H`0'`J`$"`?0!]`#4!KFM,EOS#.^[62:/&W:_ +M3=4`M?3XRX'MAW)-Z[.$K-2KP")$_S/OTM0E5SRKP',/1K:OG^7P['!\_+OK +MF-QP<^&1>X-X4M3^&$YUF3.XM^0HO=HNMAC3/SU]O#H:53[%`SW/H'0/>.-Y +M$K=&9HX'`(P!``",`0```@```$4``8A>3```0!$``,"H`0'`J`$"`?0!]`%T +M!UFM,EOS#.^[62:E+1ID!&I +M!!>'S&,IZ*HKW-5(B0X31JA0[.5>WTE?GJP))[[OZ+?B%LHH4_'H`<]QP4X[ +M-IJXC.I=]L+&OC&Y,H`",O(@H'+9[",I3)J.,4DFB%$@?O\H?&-:DDB>Q/<% +M[7JOXK9"`7KI+'6:TN26@/A8G(JC;-30#\GWB9(!UW'.*3J5VS7)>U8;3+,Q +M9R!+%C8)KZX8JP#S,G37C':(IE?:$)G?UTD_N6'U/TNF-)GD#A;%0DO0Q2O. +M3^=@`OH,@(,W..SAE'9T3_W@`JA)%-)A/07W\7:\+>0$H5_]`(N\A^\ +MR:>:'\AQSQ&PGKR3_Z`C[%"9/Y7K".Y("K95WQU^WA6;\&@$_5`#'8Q9]ZEN +MC^I^B:<8>1*W1LG#!P!<`0``7`$```(```!%``%87DT``$`1``#`J`$!P*@! +M`@'T`?0!1`&V]S12DMTQAC:X2H7U[9=`I8V2KF4\QZ"1R#9;9OSO+S5^!83;V2OA +M-M].=52TU1IG$UVPC@ZX>Y@ZP:4ML7%K$]+&4/NH5K>>O6WC"$MT4]L*VS$N +MMVI0>F5*!@?/Z;>]^<$$PU(E@Y%71)A*CH+WA\IM4&[^9'@YRT&QH!5(A!!5 +MX64]8)8`#5V69^/O-"9KYC9E,VWO;V,I',-] +M2?B=F`R?=X"=B`"<-Z`;VQ+4L>1C[L\0V$1YQP'>`A4V4M#.I%\Q0.;WC$9>8NX76WM0._J2E1L&6-$,)_T#8:B%M=7XYL4[+\ +MJO:C1NGW9-E\Y'D2MT9[ZP<`?````'P````"````10``>%Y.``!`$0``P*@! +M`<"H`0(!]`'T`&0&22@T@?]8.T'VKC89\/H[.PHN("4(`````````%PJ``!` +MIC[UU!,2MJ@O4&_@:+?0L7MU.NDVJ?HT.T.RO5=>4+:H(6XO>^!:1J'U1)D0 +MIR.[BD9.3@.F;[;[SDB+>1*W1MSV!P!L````;`````(```!%``!H7D\``$`1 +M``#`J`$!P*@!`@'T`?0`5`8Y*#2!_U@[0?:N-AGP^CL["BX@)2`````````` +M3````##RR.M&\EWSY2:W%T]UGPQF^@6%(ZI&OXI-40``0!$``,"H`0'`J`$"`?0!]`!4!CDH-('_ +M6#M!]JXV&?#Z.SL*+B`E(`````$```!,````,,LGG.=,J.B%C1*W1D"(``'@`_P!T`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``#WE;;.3WAS\2V1P(MAG7,$=*WGER-P+1/LE[%CJJ`":U"[+U5XUG +MM#Q#EPY.!6G*H?F@CK=Q]O=QVN(#RS87++'-YS2_1DR`LN?',[&U<%O`&/PD +MGJ-.5Q.VE*RNTYT2.#4QY<1:F>M3(-Z`G;*.)__;&W@WZ#X>,@+W?.!'<)\I +M```DD1JL`.)6=M`.1S&'DT-IA@*7L1G<->:@J,A*K%\Q46@I```<``!`!+R* +MV*I!U#W)@M8:@M\(W3"%!0?I````'```0`7IE&5L8N&8_**0C=1/I\VOKFEU +MB'D2MT9I'@D`7````%P````"````10``6%Y3``!`$0``P*@!`<"H`0(!]`'T +M`$0&*;U3I\_M3&$Z```````````I("(@`````````#P````@``!`!@````>' +MMC_TA.'0Y5G]J1T;KU]"Z`U.Y7D2MT8M+@D`N`$``+@!```"````10`!M%Y4 +M``!`$0``P*@!`<"H`0(!]`'T`:`'A;U3I\_M3&$Z```````````I("((```` +M`````9@A```@``!`!@````>'MC_TA.'0Y5G]J1T;KU]"Z`U.Y2(``'@```!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``#WE;;.3WAS\2V1P(MAG7 +M,$=*WGER-P+1/LE[%CJJ`":U"[+U5XUGM#Q#EPY.!6G*H?F@CK=Q]O=QVN(# +MRS87++'-YS2_1DR`LN?',[&U<%O`&/PDGJ-.5Q.VE*RNTYT2.#4QY<1:F>M3 +M(-Z`G;*.)__;&W@WZ#X>,@+W?.!'<)\I```DD1JL`.)6=M`.1S&'DT-IA@*7 +ML1G<->:@J,A*K%\Q46@I```<``!`!+R*V*I!U#W)@M8:@M\(W3"%!0?I```` +M'```0`7IE&5L8N&8_**0C=1/I\VOKFEUB'D2MT8A4@D`4`$``%`!```"```` +M10`!3%Y5``!`$0``P*@!`<"H`0(!]`'T`3@'';U3I\_M3&$Z7B4E0^'ZU:PA +M("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,` +M``@#```"````"`0```(H``"(``(``([4&QX)0CJ[,R3=#+8VZ66T`\D7R*`X +MX`//.&R66736!6R%&W.:>,!*&&H6;%U\R:9?F4`U\`\)8+H3L$NRGM`H0CHL +MVORCR:^U%O]J-^6->12RT>B+-/RL8WNX/4^J_,]KAKX#S;B>R+_4:WCTQ%;C +M].:#RVGY2X:F?%^FE.Y0*0``)'B$!=4=]8_$GN-)%6=J4!_SQV5@`` +M0!$``,"H`0'`J`$"`?0!]`#T!]F]4Z?/[4QA.EXE)4/A^M6L+B`C"`````$` +M``#L(P``T-JN'.W2+LZ3Z#>H6)V1`"K+\3H(;GR828B<5_S&>(HKZ2O^BYW1 +MOH#T7^4.^/4:ST>*"%TV)8[_\7(OY-C(T[[SF0:TR]P7_UM +M01)BL/G4GMX%EEJ(2V6T5EG,DMKAX.Y>#AE2CA-Y3GD2MT:#F@D`O````+P` +M```"````10``N%Y9``!`$0``P*@!`<"H`0(!]`'T`*0&B;U3I\_M3&$Z7B4E +M0^'ZU:PN(",@`````0```)PD``"`-^7B*']TJ[L@Y8"0]>MG@JY15N`8I?19!$;[GN$Z(SU9Z-DR4_'`LDAFV,!D`MQ:I-\1!$N +MMF'V/C!Z832F6CQ@T>_]?:/4>2(8UV^AMH$/Q`,H.*HH8^YFA@$K+NO`-BZ$X!7H'C(%S][A"&=CEK:0>Y +M($7;16`ZBAXVT7V2O-\$ND2?&H&HDQTX`9X)35MX'E:,9W[,\S?=;?D_TM!X +MH5$Q@,PR"(:<.4NZB243MO\`!2$3JHWT^V?]9V-X6U(^VE]J-'"32\)#U7,% +M0C/%^=>7Y9Z.H?GYEZA%[4#DF\;8K.M09KYJ!IR;CL>??@5:I\B8=-^^+'OD +M/ZQL"R7/=$Z],%R8/Q.]NS1$-[79LZ(O2O5/@^392W$Q*LS$L&O9,GD2MT:) +MQ`D`_````/P````"````10``^%Y;``!`$0``P*@!`<"H`0(!]`'T`.0&R;U3 +MI\_M3&$Z7B4E0^'ZU:PN("0(`````P```-PA``#`<\V4"!@O)^P.^PM;_K]" +M\5D[H'EZ:>99?+:`1[L31P?A@&"46^`*SIR)P[EV,MQ3-L4?>H6>#;R#(H8"`8X^15=$$&?MS?$"RA_4"5]4O>="]__4[>4RI +MT<*"ZTE[,#@B>+[+S-YD:Y@VMKJ+B#R16P`UC-K>9P8=^K14AT9Y$K=&],\) +M`&P```!L`````@```$4``&A>7```0!$``,"H`0'`J`$"`?0!]`!4!CF]4Z?/ +M[4QA.EXE)4/A^M6L+B`D(`````(```!,*0``,$_-''8P#3D0N`\5:<.9>%5N +MA:!^87W(/;K!<+,8>0)DTY=/+20%``Z7H?:`>1*W1C#K"0!L````;`````(` +M``!%``!H7ET``$`1``#`J`$!P*@!`@'T`?0`5`8YO5.GS^U,83I>)25#X?K5 +MK"X@)"`````#````3"D``#!?KC-.&KILN:!&[Y>E%,HZZ9P%:9[YAFM[GJZ+ +M*[A4*VARL=/(>G]'$@Y-%7D2MT;2!@H`/`$``#P!```"````10`!.%Y>``!` +M$0``P*@!`<"H`0(!]`'T`20'";U3I\_M3&$Z7B4E0^'ZU:PN("0(````!``` +M`1PA``$`0,0OI>@TW;KGOI(SW3E)`PK*,(FW#L\4_=7)FP)%76ER_C9VB_,> +M:"_ZK>,"X-=5&V8F$Z4#[\?)62#CX[O4^'9C5D2%UA +M,:=\QV_--EVPL_*9IW:L"0)!"6XA1RBE=Q6D%7PW7U\Z%I1*W1FX2"@`<`0`` +M'`$```(```!%``$87E\``$`1``#`J`$!P*@!`@'T`?0!!`?IO5.GS^U,83I> +M)25#X?K5K"X@)`@````%````_"$``.""A'^)\[,W\:\K_D>S@A[*C-X-Q&/< +M7]_7E=&T>=#,N]9[*5YN@!Y6AB8``(DZ(J@XD"6]1@(L-V$9:*-($!D_K"`!:=G?0( +M!_;*K+`4GK?#ZEK(Y&,XVY68+8;DYT3_P06)M;@H3J_2V;8IZOQ70B%4'56[ +MXLWRR\]R@UOG$S@@_]EQLL#F_N04`I*LDV*F!6UW)AL'1M^/#;B10&;+O);6 +MP=1*W1OTA"@#L````[`````(```!%``#H7F`` +M`$`1``#`J`$!P*@!`@'T`?0`U`:YO5.GS^U,83I>)25#X?K5K"X@)"`````$ +M````S"$``+"\/K1>L8)V-LD\L+;Q:^,T$+\L`GP4SCR%A2!1A1(J5CM.=0DD=#N2E..7"".OW4/J/"] +MKCXU-0QL>OOH$.')L'L:(Z6O#4J]71-@G\3=?5'!1J:MORJ<'1N2^S1PWG;H +M>1*W1I!#"@#L````[`````(```!%``#H7F$``$`1``#`J`$!P*@!`@'T`?0` +MU`:YO5.GS^U,83I>)25#X?K5K"X@)"`````%````S"$``+"N=NF:Y-^Z]W2! +MC>*B]FP#EFH#VJMNJ].TI0E^,N"9WI*&=#PB"):&-\-;2K0.IA0VWZ.%K/HR +MRC6K!O0J*VUIV;O.R4HPS]T)Q)EMGXBO3JC_X^^;9H(_3-/-YMH8),F6,"\Q +M8]Z[_9T\6K!YWC&W)?QV+OT&04+&TU04VB$2.3 +M+>7J)T%-[MUJB$Z[%18@F[/.:LP=81Q?9+(L>1*W1MA@"@`\`0``/`$```(` +M``!%``$X7F(``$`1``#`J`$!P*@!`@'T`?0!)`<)O5.GS^U,83I>)25#X?K5 +MK"X@)`@````&```!'"$``0!E%$W50X;R\G%VD"'QQ]:L8CQ81G%Y6YU$;4_] +M&;,,E"6CLZA97S?E:.?`:O$-N$MG9@&TIA.J]*\8(6DK6?N'$XBVQB#47Q!#TT65`&?";75P57`[ZT_7IGR(7> +M@HB/M#R!9+XVF_X/O?;88$0E:K#)UJ["$=2_5&B,(/8M-W,(&8C@UN2:!(:0 +M)*)CNVF?`D@J8(&;`H1<0.SDAZ[5N(PGBGU:'/14=-3)R*M'S7W)DWFY:8P``0!$``,"H`0'`J`$"`?0!]`$$ +M!^F]4Z?/[4QA.EXE)4/A^M6L+B`D"`````<```#\(0``X(BQ`"Q#76ZO4ZVQ +M<176&2RUN#Z*PV^>3LG0%4H^=WR;^#^>%O"G8]$XT.1E&B;,E!(&78PW1&NHE,-W$_6>5QDG`M:SDJ$[3FY>T1Q*\O7#MGH0K-H2*WD; +MRC+ME9UHHSB%"/VHJ6.<275(;V==(E8!Q4@8];0``0!$``,"H`0'`J`$"`?0!]`#4!KF]4Z?/[4QA.EXE)4/A +M^M6L+B`D(`````8```#,(0``L"Q0,09;%]NXSL)6A0_,ED>Z]>@OL8GCT2V# +MF2A!\87Z&:H8W]F*1=D5!&M=\?<_7?E[=W&J>KPRS +M$F6J.*A)=OAVNB__:`.O\@1[#/]K')\^G,O&OD.2&V)R996RQ$])C@@U^G$^ +M[J+`K5O[]I(EG:_FP,C$UF>Q!WH(0HS#Z/5EQ(>PGGQ']R$/O>QG$5^4-<$\ +M.'&9!Y`O1R=VRLMY$K=&::0*`.P```#L`````@```$4``.A>;@``0!$``,"H +M`0'`J`$"`?0!]`#4!KF]4Z?/[4QA.EXE)4/A^M6L+B`D(`````<```#,(0`` +ML`U1%SW10W2#(A8[V2"X7D@<:[HRAP+Q1)_:N +MAPW;U+QFG,%W'K&((5YNAL$0$/!L+Z.ML_.P%+`+W(U*-F,Z;#S+2T+R^"`: +M)*+!.*;T)JR^YY$K=&9;P``0!$``,"H`0'`J`$"`?0!]`%T!UF]4Z?/ +M[4QA.EXE)4/A^M6L+B`D"`````@```%L(0`!4'X/K/JE+1;MN049IL*Z$DVU;+X\9XI8UW9;VI92XG'$)/@ +M^B>557QXM?-E^<>R&=%\GF#V;V_?>@5/A3W`9PJZW2\(ZZ?C.,,-B%Q6,IP& +MHU*-'A*"+5[USM&`)B;M9F3Y?]^_"U;'*&8@[E=^X8)AY9G!A+,LQ@56$7AU83X,&/XN +M[3PH,$V\D:)/>*8;M]?V?O:]`N.]+P9WJBJ![1,JS(EPO)Q,`H6U)"J%/X,[4#BD72T&KA7\ +M3.>W3FE9,>`T/7C/:3C]W+2>[3Z=(;W:A.5";ML]1;!N$0]E-ER!OG:`9\8^ +M>1*W1M[^"@!<`0``7`$```(```!%``%87G```$`1``#`J`$!P*@!`@'T`?0! +M1`)25#X?K5K"X@)"`````(```!/"$``2#HQQ`M+9S-_VM# +M0NG38^HZG.*`5J:GY:@/C!L0BYWZ-6TD!._/PTT./<*@.(($__":/J#`5[F? +MBO<*ST_=W/FY@L`Y?WW8(CM32CRM!QM_CENC9NY*37YWT-68E)GEH99F63$< +M33-PX@&+E=AI`<3A_(,L0\4K8$AK8>?*`R'_ZU33L.-O[R\CYL9>GUM)'-SN +M6"%>$QV>-!_S3G"@9U#U]J=5%U'P'Q4@/$N&/HW:_;8BUG&JA=&BA-[([FEG +MMA<4XD:@65\/E<]WPS/Y7NX/Z"%;/U2WT,KOC9%MO".?P3&''&`J@YJAY7Y! +M(W\[Y]^6JFM`/B,`%3+D?12%L9"3`[_VDO;NH5,#PI-&R(P3DH&D::N&5EPO +M+%YQ``!`$0``P*@!`<"H`0(! +M]`'T`&0&28B'9(.YJE^U41*W1A(Q"P!L````;`````(```!%``!H7G(``$`1``#`J`$! +MP*@!`@'T`?0`5`8YB(=D@[FJ7[51R(GLW1_%J"X@)2``````````3````#`( +MI-RZ-':XU&>SD"`*()G619.:"-$BY9,F4G=>2YM21GODYA;+AAG#&!UR+GD2 +MMT850`L`;````&P````"````10``:%YS``!`$0``P*@!`<"H`0(!]`'T`%0& +M.8B'9(.YJE^U4\)%Y4& +M'VWN]438K*IJQ?)W8SK5V6QT^A[)XCHCX7/WBEB?\))Y$K=&7$T+`&P```!L +M`````@```$4``&A>=```0!$``,"H`0'`J`$"`?0!]`!4!CF(AV2#N:I?M5'( +MB>S='\6H+B`E(`````$```!,````,,KXS<%\L+`+TNQ+&JO+W4^T8\#OMR*( +MNOL#(!/,B(3W)(!E'?S*#6*,QO[B>1*W1IE0#`"8`0``F`$```(```!%``&4 +M7G<``$`1``#`J`$!P*@!`@'T`?0!@`=E))'E6G^?8QP``````````"$@(@@` +M```````!>"(``'@`@`!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MF4T;GO]S'G]A>YA36V#N"M7+/@S5@TOG7F["HKGNNGCN5_< +M:P^'H&I"@'X4,$$^:Y%?TF7,9`A/E\MQ.)B;^R-_-6-4'&F/"S,I```DG;=& +MS!>V;0*A#7_YK6;`^S$J+Z2-5Q:?9!S;K;?>U/4I```<``!`!(G&7$\_JOH% +M&?$39IN(Y^SBZO*B````'```0`6J.]O6C?=\VTQ7(!8!Y%Z$4+]EL7D2MT8B +M8`P`7````%P````"````10``6%YX``!`$0``P*@!`<"H`0(!]`'T`$0&*221 +MY5I_GV,<```````````I("(@`````````#P````@``!`!@````<7*K%M1<[O +M:V.=/1:V)GQWY'RS''D2MT;F;PP`N`$``+@!```"````10`!M%YY``!`$0`` +MP*@!`<"H`0(!]`'T`:`'A221Y5I_GV,<```````````I("((`````````9@A +M```@``!`!@````<7*K%M1<[O:V.=/1:V)GQWY'RS'"(``'@```!T`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``F4T;GO]S'G]A>YA +M36V#N"M7+/@S5@TOG7F["HKGNNGCN5_<:P^'H&I"@'X4,$$^:Y%?TF7,9`A/ +ME\MQ.)B;^R-_-6-4'&F/"S,I```DG;=&S!>V;0*A#7_YK6;`^S$J+Z2-5Q:? +M9!S;K;?>U/4I```<``!`!(G&7$\_JOH%&?$39IN(Y^SBZO*B````'```0`6J +M.]O6C?=\VTQ7(!8!Y%Z$4+]EL7D2MT;_DPP`4`$``%`!```"````10`!3%YZ +M``!`$0``P*@!`<"H`0(!]`'T`3@''221Y5I_GV,<4"1X5OX'HX\A("(@```` +M`````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```" +M````"`0```(H``"(``(``%ZQ4WB?QVI>\+`U?XAM3 +MU(%F)/[HK-V7I'$S91U?(;P<B# +M*0``'```0`1^R6_!\MCQ/F)4%.*S"%P```!P``$`%`@VI78D.%EFO +M]P0PDN[49A,^^?9Y$K=&O,`,``P!```,`0```@```$4``0A>>P``0!$``,"H +M`0'`J`$"`?0!]`#T!]DDD>5:?Y]C'%`D>%;^!Z./+B`C"`````$```#L(P`` +MT#CUF31(9I*6HLHL\EEBZW=#>7$U!K;KJQ"[H50B#4AS]EN[S6!S0U1`F/AZ +MG(7PC&!>H$FGDD5Y;#@&F`;Z*:Y>GZ=Q1?X6-522_I:)5S;G"4=HDUT-,8J< +M>\BQ[K`UJK)J.8L8FIMC'\;:%84FPS"Y,/`_Q2G;P'=4%@#`RO3.1&P4AD/P +M6OUW``V%H+DOGY%&JY33_+AP:?Z2^8L[;^6U[(3:CS(FO[#;7Q1(^N4S^T-8 +M&WK.IQ6['9>OT,?;Z\5LUQ%TE*-3X.D:PGD2MT9BV0P`O````+P````"```` +M10``N%Y\``!`$0``P*@!`<"H`0(!]`'T`*0&B221Y5I_GV,<4"1X5OX'HX\N +M(",@`````0```)PD``"`!"!V>6\PK?DH%ZXR900C'4C5..ZD$%)DEQV=K2\C +MIF(N_L$=U=[E)\;X!T'$Q7J2`@(>(M@*$C/]) +M';'8B7A??]&J#XI/.$O0('7:(QQ'33U\-%5C)\CI@I=9Y:<"RW]['P,VRDGA +M6R^U8'D2MT;%^`P`'`$``!P!```"````10`!&%Y]``!`$0``P*@!`<"H`0(! +M]`'T`00'Z221Y5I_GV,<4"1X5OX'HX\N("0(`````@```/PA``#@M0,6;K9; +MB%6Q-`D6(9N"QF)>`V8DC<,!=1GRI+HTAW0Z&F3,D8N5XSYD,.L^F`B7Y1W5 +MR\[,ZYL;YLT3.Y!*9I49G@;Q70IF]K[`$_8(G'(7P6DBZBLT/>+G0@+4A@)+ +M[BU"!V3@&ZS8.321LU%"@X*D&ZF)OD:7M?'NA8Z0L,E=*W&,Y]LI+'O:"U*J +M6=ZOL.H*!*4MQ]$R]V>9P&7*9ON*#JPX]X-J*YA+&6H*(;R`;=9CMF">^!I+P'D2MT9N`PT`_``` +M`/P````"````10``^%Y^``!`$0``P*@!`<"H`0(!]`'T`.0&R221Y5I_GV,< +M4"1X5OX'HX\N("0(`````P```-PA``#`$B9F69<$8\*WK`UQ%T2-,@&KOFP$ +M-75%/'#?JJ*E7L9&5U%)NQ<;!Q4U87P^4?+ZFT,,D9NVZ:9-<0V7(3%WIB%+ +MBY0P7[5G2E.\FJM5#0$]5'#S1YZ:&`=_/`[P24'%EZ0(I$"MKLO( +MC$#3FES94#EY^HXE,DYI;W#*&\EN'P`O/EWM#%/9"04MF-?$QG8V":.%R?C! +M?&".^14VI"_[V!#Z+5-*E6\4$*?DN/)!3]I'%IM'1:-Y$K=&20X-`&P```!L +M`````@```$4``&A>?P``0!$``,"H`0'`J`$"`?0!]`!4!CDDD>5:?Y]C'%`D +M>%;^!Z./+B`D(`````(```!,*0``,'T@^03@_#SNNTGJ,<[X#L@AT>0*4Q[I +MD[?*;0+^NWQ,6,4O=Q=0(.7PT(KG>1*W1KLJ#0!L````;`````(```!%``!H +M7H```$`1``#`J`$!P*@!`@'T`?0`5`8Y))'E6G^?8QQ0)'A6_@>CCRX@)"`` +M```#````3"D``##!EUU#(KB@3TA?V?PQ3>FJ$45IN&TWI6`Q;115YCW9*BP" +MB-,>/T@S`G%//#PG\1P-U#!5=VNAH-1S5XA`&#&`RY95P, +M^4UDJAA@6^C^/7D-5XJSE)(@W.+P&IMXL&,9YP,L;M(DOBK#64G!.D#\'Z7OQ.E/^\S&@60F\8?N5`XRT/)!U#R8-FB![G1;&9=U)V[_UG +MJ=CWJH1?KC(/0(3',,.U8[93C[IDU&@-GA7K:F65IT8`X"SB(MS8L`)W("S6 +M[X=U_@!*D'&"QXT->SNB)HDIKFA6C3B-PZQD$Z:N?LQ&'PJ<:;5#N1*W1MY1#0`<`0``'`$```(` +M``!%``$87H(``$`1``#`J`$!P*@!`@'T`?0!!`?I))'E6G^?8QQ0)'A6_@>C +MCRX@)`@````%````_"$``.`=6P:E8\+$@F0:#-*V+>/40&M$+32)NY#E84'= +M*7.]T$"!BQB`J,-(N\ZTKL9%O'%,2?:T9W#)8J_%+S_'I1L:#INE=_WO/AM8 +M<9G:!ZW/HT3L7=$!&L^#50;^Y$2R**:QG0$QLD?'8E8*7/&7HTJ*O_0E +M8%X1/L4UI];S=-QU>&!`&.=O?W,O.^+H"$INFS(/T0=A\5[7AL@_(8F3QQHZU=)X5Y:7\ +M7Z!@90?0/!"@H5[?>1*W1F-A#0#L````[`````(```!%``#H7H0``$`1``#` +MJ`$!P*@!`@'T`?0`U`:Y))'E6G^?8QQ0)'A6_@>CCRX@)"`````$````S"$` +M`+">==^*+QF;-,',;F($^YF\OM/FM7X&I&TRIJ/AT]!YD@M,ZE8\/T7OW,?I6J>>#8?S"SN1+?!2R29CF[D!"JP\!><:.9R`>`S +M'-;ZA1*W1I># +M#0#L````[`````(```!%``#H7H4``$`1``#`J`$!P*@!`@'T`?0`U`:Y))'E +M6G^?8QQ0)'A6_@>CCRX@)"`````%````S"$``+"L]J\"UN4?&?[+C1H28;LV +M+R1L9"%8R;H]PT3)X4JW%:$0-;FN4DC;HO2I>OYH:P- +MMN'AV1<'S(EW0AN-%?G^$R.?*R?Q/7FH5<4JOZ\5]3CUX'^YL&3*_(X1*W1DVA#0`\`0``/`$```(```!%``$X +M7H8``$`1``#`J`$!P*@!`@'T`?0!)`<)))'E6G^?8QQ0)'A6_@>CCRX@)`@` +M```&```!'"$``0"M?WM"K3_[$4F2__-Q-G!V^,(AC,I,(&N9`3K7`Y`*+RWDDZSQ>!0S\,-[`5DXC/KUR_(";8F"YE7+/6>-A`XG5U7X(4[9:3 +MI&=U#([R@\9+X72J[&%G:@LO'DW9%\AV79Y@!":#A-AN)1:&E@]S;T4;5RIW +MY0XJUYL!-F0=#&)?3AAJKL/:*"R4N#+NQ[X:IT07WW@WKZ#S5+O8!@T5M`(1 +M&:K>->VE)5/.Y2:XV:SK,^T#JWAM]BL[2H3)&1^GW=D\&=\?)(KPX!]BEE7L +M)9'0>F-@Q>MMC3,\9.=1,C2!O['PC1I#D#EB;:04ZJK&H'N&1LMY$K=&"ZT- +M`!P!```<`0```@```$4``1A>AP``0!$``,"H`0'`J`$"`?0!]`$$!^DDD>5: +M?Y]C'%`D>%;^!Z./+B`D"`````<```#\(0``X#_3`'=(*N!EJGP>Z,W&66S- +MGGQN-J'4W[<4H>)C:B;>BB/@4LW-19D"&V"AIJM+O=9W(D=T@BBTN>OBRU_3 +MW[YP[D'EBVPV(C*7!@]2F"T/CJG_!(MF.,<`3<-&MM4GT6Y/PN2%63[L-Q/K>;@3R`MO:36UMKSXC;+]EKJ;:<"] +M5^SVHL,X)N
/E!@6(JB\,-DLC)_(M(T +M"5['$VX#B&1^!ZGG[J`LG1;Q,?W8R0MY$K=&BKP-`.P```#L`````@```$4` +M`.A>B```0!$``,"H`0'`J`$"`?0!]`#4!KDDD>5:?Y]C'%`D>%;^!Z./+B`D +M(`````8```#,(0``L``9?:2KC+>/9E.'`CX.LN03TH&$&_WGX;AZS.\I]HJ< +MQ)&E)R51(\>&D'[Z%HF^<&79'0V>#^5G@TTX,;Q2E#Q0HY(?N23K)>I(,M5D +M8X-<1P3XWH4..^;7P:(]9B\KJNQ8F/!^5EA=3!;_3G$-4ICW%MRDX;$KKF9N +M,W"*BB0``0!$``,"H`0'`J`$" +M`?0!]`#4!KDDD>5:?Y]C'%`D>%;^!Z./+B`D(`````<```#,(0``L%W;THI+ +M'3)\XM@@-8R2DZJRJ-<9"EP2M2A-1")Q/.BT&,CD"S/858PG7UC"E#4@EIW( +ML]3U('U.6B+Q=/#7>8?*G^(M^N7NVSQ?"5`>=7,;$?]^UO,$H.MHUHW@=7;Z +M?6-(P.2,79GU?QL4BY7GWFA>D!9,Q7[87@4=`JA,XK*.T,C/"D+GQ:Y(8U(P +M0/XB*0B@``0!$``,"H`0'`J`$"`?0!]`%T!UDDD>5:?Y]C'%`D +M>%;^!Z./+B`D"`````@```%L(0`!4(@GQI0WE62AW=Y;/C.; +M-9Z.\Y1"P''S017HE]PT,YWUY3UL"WQW0OQ?+,`-K7H&U6*-]9&>(:XX49_5 +M1R#%PVX4KVO%(8/ADEPL%V2NJ&.%:"(?6/WI$,%=C\Z<+DVC]D.2%"*"01&< +M!C[&=X?.!!Q[A`2AVXG665#A/#C5]_AF<&N3ZY0V+"@3..$@'@C/3[OH\81! +M9]1P>FOK#DK@C4#I+'!*U7AJY#SY1QDCH[)C!#RLX[V&]S?VUP;:\!QR[&[Z +M3AJ'O[QM]EK=M!O_2A^G+\CR8J&BC6.CJ_[+Y9)&?(&J),[.I"LY>1*W1BLY +M#@!<`0``7`$```(```!%``%87HL``$`1``#`J`$!P*@!`@'T`?0!1`CCRX@)"`````(```!/"$``2":4?H#'D7CHJ:F$0YN$!LJ +MK'!YXP*X1_XF;WA9\B)#B,F%'::W^P?HT,4DD*,Y4DKQOO""I5C+5=ZJ\26Q +M;,B=SV-."%_@`E0:R08]S&GOG7P +M<,F04ZV)J,P+F.V4A0("4GGI[,L0MH +MK\*2[5V9`T&%QQ:`D`^VTJ(#7'N;H2E0%-+$1VCQ2'"/1>UXXZ+%=FZI4S6: +M,].@S_9QDQWF3LGY&8Z:2"1G#7=SN.;J0(V6;UTH9K%F"Y!T#BX!$?RO52!_ +M%Z,``!`$0``P*@!`<"H`0(!]`'T`&0& +M2:M`8ZD7Z4M"NYG0]=.W3*PN("4(`````````%PJ``!`A*&"[NF8"S#L[$E9 +MT+B_>!1PP?+UW]">+B781@J6@!BZ#S3P>EY9$=(O$L4PK7'LZ3P@U?""+/9[ +MD.RX>1*W1D-L#@!L````;`````(```!%``!H7HT``$`1``#`J`$!P*@!`@'T +M`?0`5`8YJT!CJ1?I2T*[F=#UT[=,K"X@)2``````````3````##SJCG=6%\( +MA\@`[@Z;M"P`B?N"AM>[8@-W3D`H@(FC-3LTUKB3F;ZB4F\6!7D2MT;1>PX` +M;````&P````"````10``:%Z0``!`$0``P*@!`<"H`0(!]`'T`%0&.:M`8ZD7 +MZ4M"NYG0]=.W3*PN("4(`````0```$PJ```P@O`_2%NVJ&$L)9BQLA]^"FTS +MJ*)I9B]9XV@8?XU\L)W)J0W/_'P["Y>`(25Y$K=&(XD.`&P```!L`````@`` +M`$4``&A>D0``0!$``,"H`0'`J`$"`?0!]`!4!CFK0&.I%^E+0KN9T/73MTRL +M+B`E(`````$```!,````,'%74+X^;HQU45I:!%Q?&-/Y]MB4!3@N9>B^EO2! +M%^M2],$(=C:KMZP]I)KY>A*W1J9"``"8`0``F`$```(```!%``&47I,``$`1 +M``#`J`$!P*@!`@'T`?0!@`=E:SGX4"]@[#D``````````"$@(@@````````! +M>"(``'@``````0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``H*4GVD;9 +MB:49]>',\$(JTH^,_EV19BR"JVL2+1%IMAGK;JP2*_U%E_U1?KPR9:Y^T\*< +M"H]FVQ9L26[/4(2O^T2HP/S!QK$F1QZ5KZW"5805HI```D0DIV5;/&GV-$ +MCCME9[FRA\/-*?,8C")0D[3$@TXH6&4I```<``!`!$Q&`7'0GC)VC2G+\!)K +M*BB'V=/H````'```0`4XP8"<.U_%^?R$?JSLU@S\_Q?$M7H2MT;5=0,`F`$` +M`)@!```"````10`!E%Z9``!`$0``P*@!`<"H`0(!]`'T`8`'96LY^%`O8.PY +M```````````A("((`````````7@B``!X``````$!``P#```,`0``#(`.`(`# +M```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(` +M``$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"```` +M"`0```XH``"(``(``*"E)]I&V8FE&?7AS/!"*M*/C/Y=D68L@JMK$BT1:;89 +MZVZL$BO]19?]47Z\,F6N?M/"G`J/9ML7)C$.!BMUMEJE: +M^MPE6$%:*0``)$)*=E6SQI]C1(X[96>YLH?#S2GS&(PB4).TQ(-.*%AE*0`` +M'```0`1,1@%QT)XR=HTIR_`2:RHHA]G3Z````!P``$`%.,&`G#M?Q?G\A'ZL +M[-8,_/\7Q+5Z$K=&9[<)`)@!``"8`0```@```$4``91>L0``0!$``,"H`0'` +MJ`$"`?0!]`&`!V5K.?A0+V#L.0``````````(2`B"`````````%X(@``>``` +M```!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P`` +M"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```! +M`P``"`,```4#```(!````@````@$```.*```B``"``"@I2?:1MF)I1GUXMNK!(K_467_5%^O#)EKG[3PIP*CV;;%R8Q +M#@8K=;9:G(<0PO&(7:7Q;:Q?RJD)!B9H0**7'VKFW^TXK%,%0[.DW[[+@9YF +MQ);L]0A*_[1*C`_,'&L29''I6OK<)5A!6BD``"1"2G95L\:?8T2..V5GN;*' +MP\TI\QB,(E"3M,2#3BA892D``!P``$`$3$8!<=">,G:-*Q*W1G;#!P"8`0``F`$```(` +M``!%``&47KX``$`1``#`J`$!P*@!`@'T`?0!@`=E0L;T@&A1"^H````````` +M`"$@(@@````````!>"(``'@````!`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``XYE9=L/CKK\C#.\_.'=4NUF^IV=L`:HA5P0.R?%^6A+#2J0&O.=2 +MIUSGV(3Y&)`?K1KKJ;WM:ON>[-R[O\"$A]BU6MH:(XZ!".?C_)+\31^[^TB&M9 +MYZ6;^/5%*%/10_;?:53AFE&**0``)!:IU*W]D^(P<+BZ/K?*F5#FBJ`L24SS +MPG(P/\FO1BBY*0``'```0`2QFC5D%(441(KM,>8 +MT```0!$``,"H`0'`J`$"`?0!]`&`!V5"QO2`:%$+Z@``````````(2`B"``` +M``````%X(@``>`````$!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P`` +M#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```( +M`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``#C +MF5EVP^.NOR,,[S\X=U2[6;ZG9VP!JB%7!`[)\7Y:$L-*I`:\YU*G7.?8A/D8 +MD!^M&NNIO>UR<3"K\2>EF_CU12A3T4/VWVE4X9I1BBD``"06J=2M +M_9/B,'"XNCZWRIE0YHJ@+$E,\\)R,#_)KT8HN2D``!P``$`$L9HU9!2%%$2* +M[3'F'(]*5<=QN:T````<``!`!5D*4X*C"(``'@````"`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``,J?AOUC?DG"*Z#] +MA(6V9SPF3<^4;*.U-_@&W%+->.TJA`\)E_(5!4#'Q%`8K)D6TT93VA??I:QX +M2.IK*/B<(T:R^RQ$Z?VUCZ,=N,HU3XP5"))P,`F`$``)@!```"````10`!E%[W``!`$0`` +MP*@!`<"H`0(!]`'T`8`'9$CJ:RCXG"-&LOLL1.G]M8^C';C*-4^,%0B7 +M,&E:PF"1'33?D;H1K%Q5ZFPMU5%KSN%"[G^#5N(D*0``),-7S[8*ZSR`[E?` +MDMI-K.)7.**)Z,2G8TL:6SB#`TCN*0``'```0`08!YJ=+JW4:.5!FFZ*TE*, +MXSUVSP```!P``$`%J8-;&G+*(P[F9TV4!YZ<).HHV&M]$K=&+FD)`)@!``"8 +M`0```@```$4``91?"0``0!$``,"H`0'`J`$"`?0!]`&`!V7(4`\?`,T;5P`` +M````````(2`B"`````````%X(@``>`````(!`0`,`P``#`$```R`#@"``P`` +M#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```! +M`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$ +M```.*```B``"```RI^%RK]ATIBA%&0/WPP^`=D%Z_6-^2<(KH/V$A;9G/"9- +MSY1LH[4W^`;<4LUX[2J$#PF7\A4%0,?$4!BLF1;31E/:%]^EK'A(ZFLH^)PC +M1K+[+$3I_;6/HQVXRC5/C!4(ES!I6L)@D1TTWY&Z$:Q<5>IL+=51:\[A0NY_ +M@U;B)"D``"3#5\^V"NL\@.Y7P)+:3:SB5SBBB>C$IV-+&ELX@P-([BD``!P` +M`$`$&`>:G2ZMU&CE09INBM)2C.,]=L\````<``!`!:F#6QIRRB,.YF=-E`>> +MG"3J*-AK?A*W1L5T!P"8`0``F`$```(```!%``&47R,``$`1``#`J`$!P*@! +M`@'T`?0!@`=E-+K1HCE%HDL``````````"$@(@@````````!>"(``'@````# +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``P&IEF2FY_Z*24=V_Y/HK +M\JEG7AXH)^U,*4B)%ZQI.2/OP@[:36^4"5ZH0:BT*)P%`2>?+V]QY6-0PB;` +MMH(R'CWIT*O1P*X.")._D_4A.9G>^1U^K05A.0FZ9+#$`JHQ>6:C"VLS;```` +M'```0`54(H"2(*/'>LT1[E]P9?0?."ZG''X2MT:&H0H`F`$``)@!```"```` +M10`!E%\D``!`$0``P*@!`<"H`0(!]`'T`8`'932ZT:(Y1:)+```````````A +M("((`````````7@B``!X`````P$!``P#```,`0``#(`.`(`#```,`0``#(`. +M`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@`` +M!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"( +M``(``,!J99DIN?^BDE'=O^3Z*_*I9UX>*"?M3"E(B1>L:3DC[\(.VDUOE`E> +MJ$&HM"B5C4,(FP+:",AX]Z="KT<"N#@B3OY/U(3F9WOD=?JT% +M83D)NF2PQ`*J,7EFHW*%QY42U\M\[_^DV&+7;%X]!9J/:!C3R(O\Y!L/*0`` +M)%.+9Y?<&7T'S@NIQQ_ +M$K=&X*`!`)@!``"8`0```@```$4``91?*```0!$``,"H`0'`J`$"`?0!]`&` +M!V4TNM&B.46B2P``````````(2`B"`````````%X(@``>`````,!`0`,`P`` +M#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```( +M`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4# +M```(!````@````@$```.*```B``"``#`:F69*;G_HI)1W;_D^BORJ6=>'B@G +M[4PI2(D7K&DY(^_"#MI-;Y0)7JA!J+0HG`4!)Y\O;W'E8U#")L"V@C(>/>G0 +MJ]'`K@X(D[^3]2$YF=[Y'7ZM!6$Y";IDL,0"JC%Y9J-RA<>5$M?+?.__I-AB +MUVQ>/06:CV@8T\B+_.0;#RD``"13BV7+X3T^9VZ[A&@Q/^^@,(PW):W:DUBL +MT)M_&]M>HBD``!P``$`$Z>:Q;YIRJ88V-UN=WP7Z9X+:S-L````<``!`!50B +M@)(@H\=ZS1'N7W!E]!\X+J<"(``'@````$`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``VK=\ +MI,2JW6A#O*O9:Z3G,E/P\@!V&3XC-.0@VO7ZVJML0`G8EAC'AI8,7(E8SZ(= +M`\8]5%?%9LW#6/ZUAM='<=M;G)L%D+ANB<=XP"^MO9;S>%9GFK0_$S%LO)_\ +MK?9';TSA&!3(%UH;NE)*?9]DP-[K$"V42.L\Q&V@X0TS;U,I```DQ5,WW)1V +M'K_)8FMNW;U]13P37._4^Q)X9ZZ+(8B&$P$I```<``!`!/S2Y2=AE&V@X:P' +M[2ROMNX?PG$)````'```0`467X,2?T(39`8UH.5+>MX(%(#B*X`2MT9!V0(` +MF`$``)@!```"````10`!E%\Y``!`$0``P*@!`<"H`0(!]`'T`8`'9?U>QV2< +MJ%+E```````````A("((`````````7@B``!X````!`$!``P#```,`0``#(`. +M`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P`` +M"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```" +M````"`0```XH``"(``(``-JW?*3$JMUH0[RKV6NDYS)3\/(`=AD^(S3D(-KU +M^MJK;$`)V)88QX:6#%R)6,^B'0/&/517Q6;-PUC^M8;71W';6YR;!9"X;HG' +M>,`OK;V6\WA69YJT/Q,Q;+R?_*WV1V],X1@4R!=:&[I22GV?9,#>ZQ`ME$CK +M/,1MH.$-,V]3*0``),53-]R4=AZ_R6)K;MV]?44\$USOU/L2>&>NBR&(AA,! +M*0``'```0`3\TN4G891MH.&L!^TLK[;N'\)Q"0```!P``$`%%E^#$G]"$V0& +M-:#E2WK>"!2`XBN`$K=&U1H)`)@!``"8`0```@```$4``91?.@``0!$``,"H +M`0'`J`$"`?0!]`&`!V7]7L=DG*A2Y0``````````(2`B"`````````%X(@`` +M>`````0!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#` +M`P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@# +M```!`P``"`,```4#```(!````@````@$```.*```B``"``#:MWRDQ*K=:$.\ +MJ]EKI.&E@Q:M#\3,6R\G_RM]D=O3.$8 +M%,@76ANZ4DI]GV3`WNL0+91(ZSS$;:#A#3-O4RD``"3%4S?O\EB:V[= +MO7U%/!-<[]3[$GAGKHLAB(83`2D``!P``$`$_-+E)V&4;:#AK`?M+*^V[A_" +M<0D````<``!`!19?@Q)_0A-D!C6@Y4MZW@@4@.(K@1*W1J4I!P"8`0``F`$` +M``(```!%``&47ST``$`1``#`J`$!P*@!`@'T`?0!@`=E^('74]R8#/D````` +M`````"$@(@@````````!>"(``'@````'`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``(PNH@ZI;N:,@AFUL"PQ!4(S[I#K:@!C#ZNG)XTP"@@0ROH+3 +M\#KO?D'(V?,H\;J_JRV$"O'`,(:-6+&KG;LED_.9Y9>:5OD%2?5I1\<@/'$5 +MJ50GPO_91H4VKN8/L.8%\+(!F'4O4*$05O5^[O^]>YR#/W;K^0Q)L:N;(W8*IN:C1["=.IF%'7?^P.C````'```0`7]J^1[!,2#IQ9`30L[EYCS +M!8C@[8$2MT964PH`F`$``)@!```"````10`!E%\_``!`$0``P*@!`<"H`0(! +M]`'T`8`'9?B!UU/-,`H($,KZ"T_`Z[WY!R-GS*/&ZOZLMA`KQP#"&C5BQJYV[ +M)9/SF>67FE;Y!4GU:4?'(#QQ%:E4)\+_V4:%-J[F#[#F!?"R`9AU+U"A$%;U +M?N[_O7N<@S]VZ_D,2;&KFW-8G3"5*0``)+$@!-G+);V!A&XR<=&5T[$]$@;X +M^)OOBZ#N:K(#[O>[*0``'```0`3BYGB-V"J;FHT>PG3J9A1UW_L#HP```!P` +M`$`%_:OD>P3$@Z<60$T+.Y>8\P6(X.V"$K=&L%(!`)@!``"8`0```@```$4` +M`91?0@``0!$``,"H`0'`J`$"`?0!]`&`!V7X@==3W)@,^0``````````(2`B +M"`````````%X(@``>`````"(``'@````(`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``.!/DAF"*87?*X]BTN*4N8G*KN1>`$2N/4<96Q7/VPJ">&!;3&*A29+H/*_-"E(+EPN8N( +M#>.O)#_BG2L;UO@HA````'```0`419R[^ +MZB2]"75/3I)\D`NS%#8=K(,2MT8*BP(`F`$``)@!```"````10`!E%]D``!` +M$0``P*@!`<"H`0(!]`'T`8`'96WQIUE4>8BI```````````A("((```````` +M`7@B``!X````"`$!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0`` +M#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```" +M`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``#@3Y(9@ +MBF%WRN/8M+BE+F'.-/F8JF]DURA#;!B^*?H2WIRJ[D7@!$KCU'&5L5S]L*@G +MA@6TQBH4F2Z#ROS0I2"Y<+F+B`WCKR0_XITK&];X'.4VLER:1(S$R-QI:QK: +MXRBQ1@N]AN=<7U/#,OP;OTTA"2D\W*4H\,:![,0V)H1"*0``)$=:DPV.ZN^& +M].1J/!EZ?&NAE5K=J^/`=\?O:#\"7`````@!`0`,`P``#`$```R`#@"` +M`P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@" +M```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@`` +M``@$```.*```B``"```X$^2&8(IA=\KCV+2XI2YASC3YF*IO9-S$-B:$0BD``"1'6I,-CNKOAO3D:CP9>GQKH95:W:OCP'?'[V@_`EW(]"D` +M`!P``$`$/;XU:L(@T0%3JPF;>[2!+(5QZB$````<``!`!1%G+O[J)+T)=4]. +MDGR0"[,4-AVLA!*W1F_9!@"8`0``F`$```(```!%``&47XD``$`1``#`J`$! +MP*@!`@'T`?0!@`=EI&1L_!HMDHP``````````"$@(@@````````!>"(``'@` +M```)`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``W/N%=/%B.KC3>H2" +M+D@3E'`&!0Y="W+"NM=2>/N64!O[>/.+`@: +MP<\AUFZ@I(^[9Y-QQ1N^$C\C0I>'H?OP.YK_V8&%HKDNCYN#6&^J5IJ++C[) +M+"YR@"B>I?:W&/-WXTLU6FG";6WM54D0OI`I```D]S]O[J/H=D@3CPJ5`>_. +M@^A0NZ3%>@`J)'Q3`5NK'#4I```<``!`!/ZB6;=09O=VXED"7B1(1`R#SH%- +M````'```0`5;K&^`5SG^2@YB1TYWN%=&(T[,E(02MT95!0H`F`$``)@!```" +M````10`!E%^=``!`$0``P*@!`<"H`0(!]`'T`8`'9:1D;/P:+9*,```````` +M```A("((`````````7@B``!X````"0$!``P#```,`0``#(`.`(`#```,`0`` +M#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```( +M`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH +M``"(``(``-S[A73Q8CJXTWJ$@BY($Y1P!@4.70MRPKK74GC[EE`;^WCW*0BK +M]@/=X'T/A`Z4XV.0C<[7CBP(&L'/(=9NH*2/NV>3<<4;OA(_(T*7AZ'[\#N: +M_]F!A:*Y+H^;@UAOJE::BRX^R2PN`````D!`0`, +M`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,# +M```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,` +M``4#```(!````@````@$```.*```B``"``#<^X5T\6(ZN--ZA((N2!.4<`8% +M#ET+!]#X0.E.-CD(W.UXXL"!K!SR'6;J"D +MC[MGDW'%&[X2/R-"EX>A^_`[FO_9@86BN2Z/FX-8;ZI6FHLN/LDL+G*`*)ZE +M]K<8\W?C2S5::<)M;>U521"^D"D``"3W/V_NH^AV2!./"I4![\Z#Z%"[I,5Z +M`"HD?%,!6ZL<-2D``!P``$`$_J)9MU!F]W;B60)>)$A$#(/.@4T````<``!` +M!5NL;X!7.?Y*#F)'3G>X5T8C3LR4A1*W1NYD#@"8`0``F`$```(```!%``&4 +M7\4``$`1``#`J`$!P*@!`@'T`?0!@`=EJX+#7N*AX:H``````````"$@(@@` +M```````!>"(``'@```!K`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M.9*6E`/C;-ICY]T2:\J>_49=FN84E'J_`37]%O!;]AH-@V\?*S=O>W22/"W^ +M2ZCQR.F]'<:O"&47=,[DJ&E<78-1%]"\[AQOD;T2\KA^*Y1C#/U\.H0F>K;] +M4Y8/:X_OGI+>W9[<9M8WL3=0LO=!WF#^!\<_2MWT6):W8L^A_DGI+:S1/MM%XYDR%F*F7A5X4G<=0I```<``!`!/OZ785(*BR[ +MN#1FTGOZS,#$QB))````'```0`6_>5MLQH$;][0X6Z:;><_?@;*+4882MT;& +M/`(`F`$``)@!```"````10`!E%_(``!`$0``P*@!`<"H`0(!]`'T`8`'9:N" +MPU[BH>&J```````````A("((`````````7@B``!X````:P$!``P#```,`0`` +M#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```" +M`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$ +M```"````"`0```XH``"(``(``#F2EI0#XVS:8^?=$FO*GOU&79KF%)1ZOP$U +M_1;P6_8:#8-O'RLW;WMTDCPM_DNH\W&;6-[$W4++W0=Y@_@?' +M/TK=]%B6MV+/H?Y'*0``),"[4VI#Q.J17T0'7IZ2VLT3[;1>.9,A9BIEX5>% +M)W'4*0``'```0`3[^EV%2"HLN[@T9M)[^LS`Q,8B20```!P``$`%OWE;;,:! +M&_>T.%NFFWG/WX&RBU&&$K=&?7X(`)@!``"8`0```@```$4``91?R0``0!$` +M`,"H`0'`J`$"`?0!]`&`!V6K@L->XJ'AJ@``````````(2`B"`````````%X +M(@``>````&L!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R` +M#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,` +M``@#```!`P``"`,```4#```(!````@````@$```.*```B``"```YDI:4`^-L +MVF/GW1)KRI[]1EV:YA24>K\!-?T6\%OV&@V#;Q\K-V][=)(\+?Y+J/'(Z;T= +MQJ\(91=TSN2H:5Q=@U$7T+SN'&^1O1+RN'XKE&,,_7PZA"9ZMOU3E@]KC^^> +MDM[=GMQFUC>Q-U"R]T'>8/X'QS]*W?18EK=BSZ'^1RD``"3`NU-J0\3JD5]$ +M!UZ>DMK-$^VT7CF3(68J9>%7A2=QU"D``!P``$`$^_I=A4@J++NX-&;2>_K, +MP,3&(DD````<``!`!;]Y6VS&@1OWM#A;IIMYS]^!LHM1AQ*W1D:+!@"8`0`` +MF`$```(```!%``&47\H``$`1``#`J`$!P*@!`@'T`?0!@`=E57>?7Q:1*JX` +M`````````"$@(@@````````!>"(``'@```!L`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``8+0'"K`G8))LR,Z2SVO>_1B6ZX04<[:]P*TU(FO=KG,3 +MV66-A_:[P8GF_`+3JL._.?<'&=RP!5'@`;9`/*['G+97L@4E;\V-`X^DED'P +MZ>L38!'S9,5&I-?M&Y90E1:-]'S'<+MTJ9.3ONRV"7*M7_CYB<$[@-/RUDHA +MBANOSG4I```D=$1,2H9`&651$ENQ;X[TYZA1,<6`AR0*X:*H31KTS5@I```< +M``!`!%/R?@(%Q\-J(#U<0S'+ZIT%^:OM````'```0`7Q;=X]BO^3_P4LEP^M +M;N%>X@*19(<2MT;GM@D`F`$``)@!```"````10`!E%_+``!`$0``P*@!`<"H +M`0(!]`'T`8`'955WGU\6D2JN```````````A("((`````````7@B``!X```` +M;`$!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```( +M`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$# +M```(`P``!0,```@$```"````"`0```XH``"(``(``&"T!PJP)V"2;,C.DL]K +MWOT8ENN$%'.VO<"M-2)KW:YS$]EEC8?VN\&)YOP"TZK#OSGW!QGH +M43'%@(/8K_D_\%+)````&P!`0`,`P``#`$```R`#@"``P``#`$```R` +M#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(` +M``0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*``` +MB``"``!@M`<*L"=@DFS(SI+/:][]&);KA!1SMKW`K34B:]VN;\`M.JP[\Y]P<9W+`%4>`!MD`\KL>R!25OS8T#CZ260?#IZQ-@$?-D +MQ4:DU^T;EE"5%HWT?,=PNW2IDY.^[+8)"(``'@```!M`0$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``'[/H^_&)33-3F9#.]8JU_,`I3KFJ +M`T30NTQVUSD>V28'=ZBB)4`;9M3ORF82P7[)@ +MFXY)C(+/E'%3SGG;]0*B0J-2-#^_G(]9^9]4WN4TE.&\0D;76:<13D^::ESF +MZ-O]S-JH5I8\>;8U12`7U?(I```DUZ@9VT"/CV.P'++C&1G8:4?*T9V_6H[G +M(1>%`;=)4.(66'%`A\=,?A.+?[C"ZXD2MT:8[@$`F`$``)@!```"````10`!E%_. +M``!`$0``P*@!`<"H`0(!]`'T`8`'929[^3&^6##R```````````A("((```` +M`````7@B``!X````;0$!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```, +M`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@# +M```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``!^S +MZ/OQB4TS4YF0SO6*M?S`*4ZYJ@-$T+M,=MG,1:JX-)CS&Q2A;.$ +M\K;".7HHB5`&V;4[\IF$L%^R8)N.28R"SY1Q4\YYV_4"HD*C4C0_OYR/6?F? +M5-[E-)3AO$)&UUFG$4Y/FFIH&=M` +MCX]CL!RRXQD9V&E'RM&=OUJ.YR$7A0&W25#G*0``'```0`0I$!>_DQ +MOE@P\@``````````(2`B"`````````%X(@``>````&T!`0`,`P``#`$```R` +M#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,` +M``@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!``` +M`@````@$```.*```B``"```?L^C[\8E-,U.9D,[UBK7\P"E.N:H#1-"[3';7 +M.1[9)@=WIS$6JN#28\QL4H6SA/*VPCEZ*(E0!MFU._*9A+!?LF";CDF,@L^4 +M<5/.>=OU`J)"HU(T/[^Y324X;Q"1M=9IQ%.3YIJ7.;HV_W,VJA6 +MECQYMC5%(!?5\BD``"37J!G;0(^/8[`^!];`````<``!`!0-I3EI5XA98 +M<4"'QTQ^$XM_N,+KBA*W1N`Z!@"8`0``F`$```(```!%``&47]```$`1``#` +MJ`$!P*@!`@'T`?0!@`=EN@Z"R8:E;I@``````````"$@(@@````````!>"(` +M`'@```!P`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``<,TPM_$]-T63 +MA$C*[N\R%=[2Y^A=?S7H=\^2[#YRRT4!Q<$8+,./$KV//IZ'2YT#(5)1--_)K]O&IA;H,FO*5K!+`'6O_\!&+^51 +M45V!B&+"`5S$&QVF8I(#OL/SV`M5KN6G_XO9!:Q!QSZ?T,$VZ&UC(H2MT;':`D`F`$``)@! +M```"````10`!E&`[``!`$0``P*@!`<"H`0(!]`'T`8`'9;H.@LF&I6Z8```` +M```````A("((`````````7@B``!X````<`$!``P#```,`0``#(`.`(`#```, +M`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$# +M```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0` +M``XH``"(``(``'#-,+?Q/3=%DX1(RN[O,A7>TN?H77\UZ'?/DNP^CP.%\M22(.5[E*8GCSZ>ATN=`R%2433?R:_; +MQJ86Z#)KRE:P2P!UK__`1B_E45%=@8ABP@%08B*0``'``` +M0`0+[T$FN3-:J[;2A2TO3MN6!.(2F0```!P``$`%UB0,WI_^+V06L0<<^G]# +M!-NAM8R+$K=&"F@``)@!``"8`0```@```$4``91@0```0!$``,"H`0'`J`$" +M`?0!]`&`!V6Z#H+)AJ5NF```````````(2`B"`````````%X(@``>````'`! +M`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$` +M``,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P`` +M"`,```4#```(!````@````@$```.*```B``"``!PS3"W\3TW19.$2,KN[S(5 +MWM+GZ%U_->AWSY+L/G++10'%P1@LPX\2O9R3.R"&&RAD8L=V'H\#A?+4DB#E +M>Y2F)X\^GH=+G0,A4E$TW\FOV\:F%N@R:\I6L$L`=:__P$8OY5%178&(8L(! +M7,0;':9BDAR9BNCMX.^P_/8"U6NY9RD``"3)']F^3#PKI+\[9<3NF(VUOKW% +M$$X$H3P&Y_0;KGD&(BD``!P``$`$"^]!)KDS6JNVTH4M+T[;E@3B$ID````< +M``!`!=8D#-Z?_B]D%K$''/I_0P3;H;6,BQ*W1NO3#0"8`0``F`$```(```!% +M``&484<``$`1``#`J`$!P*@!`@'T`?0!@`=EPE2U(M\35F4``````````"$@ +M(@@````````!>"(``'@```!Q`0$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@```?&WO);=;T*4:M<0:1!L,1,#05]5RY=!CK&,69U=3AN\I```<``!`!-]*$TR' +M@3J[:(%(!+)[=_^)ZG?H````'```0`4X:<[Y:#S25Q=J&VJ[%)7HVB?N9HP2 +MMT:IQP$`F`$``)@!```"````10`!E&'W``!`$0``P*@!`<"H`0(!]`'T`8`' +M9<)4M2+?$U9E```````````A("((`````````7@B``!X````<0$!``P#```, +M`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@" +M```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,` +M``@$```"````"`0```XH``"(``(```'QM[R6W6]"E&K7$&D07,PVDOVUO):] +MF?T-/.K\H-(FJ6:\0>_K6Q[2;]D(`OA/O)HAC2 +M/;O?[Z'5A?U'QV"31E!H(?M++,R+99?W?_B>IWZ````!P``$`%.&G. +M^6@\TE<7:AMJNQ25Z-HG[F:,$K=&+`D(`)@!``"8`0```@```$4``91B>0`` +M0!$``,"H`0'`J`$"`?0!]`&`!V7"5+4BWQ-690``````````(2`B"``````` +M``%X(@``>````'$!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$` +M``R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P`` +M`@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"```!\;>\ +MEMUO0I1JUQ!I$%S,-I+]M;R6O9G]#3SJ_*#2)JEFG'R+%FZ:NL3($+X\B]_Y +M:'O$'OZUL>TF_9"`+X3[R:(8TCV[W^^AU87]1W.D07;O2-J\MK5"\W^AJC)=0<$=NBD``"0^/=S#1O5* +MS?Z\W5QIZPQ$P-!7U7+ET&.L8Q9G5U.&[RD``!P``$`$WTH33(>!.KMH@4@$ +MLGMW_XGJ=^@````<``!`!3AISOEH/-)7%VH;:KL4E>C:)^YFC1*W1I`;!@"8 +M`0``F`$```(```!%``&48PH``$`1``#`J`$!P*@!`@'T`?0!@`=E);I>R;%1 +MJS@``````````"$@(@@````````!>"(``'@```!R`0$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``S7FNHB]X@=1>L[&%1PR9SGQ;A0)YC7'K.=AIZWAR"RN1 +MWF/HZ)E"^,R+.E%1WG1!BOY(%'5),@)CL,%Q5K8T2MT:\00D`F`$``)@!```"````10`!E&,8``!`$0``P*@! +M`<"H`0(!]`'T`8`'926Z7LFQ4:LX```````````A("((`````````7@B``!X +M````<@$!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`# +M```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,` +M``$#```(`P``!0,```@$```"````"`0```XH``"(``(``,UYKJ(O>('47K.Q +MA4<,F8UQZSG8:>MX<@LKD=YCZ.B90OC,BSI14=YW,N/`4JUS'=0FG!K' +MD08K^2!1U23("7.IQEQU?"(!O0>%L7W28+2W*0``)/QO?RU\#Z1NX9&6?)-Q +M3[7!VIV3'$IP+[FP`X8)".M$*0``'```0`1A,"AZ@V%S3S4,08MM?T^46XJ; +MJ````!P``$`%X->C#^NK*AG6(CV@6ZGH[#!<5:V.$K=&[4```)@!``"8`0`` +M`@```$4``91C,```0!$``,"H`0'`J`$"`?0!]`&`!V4ENE[)L5&K.``````` +M````(2`B"`````````%X(@``>````'(!`0`,`P``#`$```R`#@"``P``#`$` +M``R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P`` +M"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```. +M*```B``"``#->:ZB+WB!U%ZSL85'#)G.?%N%!RNQS2%S?:HJGR6\CLYV&GK>'(+*Y'>8^CHF4+X +MS(LZ45'>=S+CP%*MH-A#7HP_KJRH9UB(]H%NIZ.PP +M7%6MCA*W1L^,#0"8`0``F`$```(```!%``&48V4``$`1``#`J`$!P*@!`@'T +M`?0!@`=E"F9524Z"DP(``````````"$@(@@````````!>"(``'@```!S`0$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``68T>G8TG@Q2]W2=36MZN-UI(XL_VO.B@^R7T^#J +MFH>C`R@+EX@)E1U0MSI58-;)GX6%U(3@.5230$`F`$``)@!```"````10`! +ME&-N``!`$0``P*@!`<"H`0(!]`'T`8`'90IF54E.@I,"```````````A("(( +M`````````7@B``!X````KC=:2.+/]KSHH/LE]/@ZIJ'HP,H"Y>("94=4+>`-]QFL/;,L893KWQNC,L*0``'```0`2O&;./#*.P +MT$I````',!`0`,`P``#`$` +M``R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@`` +M`@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```( +M!````@````@$```.*```B``"``!9C1Z=AS(&(7$;0X)V)=F^&ES/D/6);@8( +MR$>8V#:,5BC#%+W=)U-:WJXW6DCBS_:\Z*#[)?3X.J:AZ,#*`N7 +MB`F5'5"W.E5@ULF?A874A.`Y5)-S,JV!79#@3[L]83?P7U\8G/7XG#@12:8F +M!LT?MIHY"[H6>8R8!"D``"09`TJX[I>_)@"&94X+X(IWG@#?<9K#VS+&&4Z] +M\;HS+"D``!P``$`$KQFSCPRCL-!*7*#$I=D?,`ND6@$````<``!`!>9/_A=H +M<+>M78JV^0*ZR@N`*^T(D!*W1LO&!0"8`0``F`$```(```!%``&48[D``$`1 +M``#`J`$!P*@!`@'T`?0!@`=E_YN-E>Y_]Y4``````````"$@(@@````````! +M>"(``'@```!U`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``?8LXYB=V +MDAOW;G7$D9!TWYO>Q9JOF[AS:$SU-TOU^[4V%_N1=OA?*7D**RC4V"HY/WO1 +M:Z[8RYP!T.KL2VFNYP?V.'WW.S\TA"%:7=3Z_@0F-<4PNUQTNG%P-*L^@,[^.6Q3H(75%4QBM8$(I```D$5:OI@`IF/=9 +M)MD!/@0@G.M?WUSU%S_2P)>]2JT21]DI```<``!`!/+.U;1)XJJ!)812K@-2 +MANC"G*E#````'```0`6&L>N[YR7>S#-LD/\Y+0I&?,^[U9`2MT9R\P@`F`$` +M`)@!```"````10`!E&._``!`$0``P*@!`<"H`0(!]`'T`8`'9?^;C97N?_>5 +M```````````A("((`````````7@B``!X````=0$!``P#```,`0``#(`.`(`# +M```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(` +M``$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"```` +M"`0```XH``"(``(``'V+..8G=I(;]VYUQ)&0=-^;WL6:KYNX*J@26$4JX#4H;HPIRI0P```!P``$`%AK'KN^``` +M`'4!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P`` +M"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```! +M`P``"`,```4#```(!````@````@$```.*```B``"``!]BSCF)W:2&_=N=<21 +MD'3?F][%FJ^;N'-H3/4W2_7[M387^Y%V^%\I>0HK*-38*CD_>]%KKMC+G`'0 +MZNQ+::[G!_8X??<[/S2$(5I=U/K^!"8UQ3"[7'1RA'AEK3O(&N3Y9!Q.ZE_[ +M+>.+-ZZ<7`TJSZ`SOXY;%.@A=453&*U@0BD``"015J^F`"F8]UDFV0$^!""< +MZU_?7/47/]+`E[U*K1)'V2D``!P``$`$\L[5M$GBJH$EA%*N`U*&Z,*"(``'@```!V`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``P6KF5)&@]V.8\RT1_(E;\#N@-^*!J\(H">_,R@!$\\G];1%Q;`*_ +MY@8K1R\/Q6+IQF2R2&7_ZK69AFS\OQGZS8WL^2?N%)2S_R=.7\<%0/#C7-ZR +MO8"O8&46M^236*JW:'TO`J9I=',+XF\.""YN>%^484P08@2`NA>MRVH:FV`I +M```D1*HLR[FW-$$I&?@9U!1TG*4:/\'H@227U.V=@-(Y_K4I```<``!`!/2L +MP@S>,A?F;]CJ9W_3,L=<%6LJ````'```0`7&S5LKV`KV!E%K?DDUBJMVA]+P*F:71S"^)O#@@N +M;GA?E&%,$&($@+H7K````'8!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P`` +M#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```( +M`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``#! +M:N94D:#W8YCS+1'\B5OP.Z`WXH&KPB@)[\S*`$3SR?UM$7%L`K_F!BM'+P_% +M8NG&9+)(9?_JM9F&;/R_&?K-C>SY)^X4E+/_)TY?QP5`\.-B!))?4[9V`TCG^M2D``!P``$`$]*S"#-XR%^9O +MV.IG?],RQUP5:RH````<``!`!<;-5RU_U"ICUN/.J-%+G81)+!"\DQ*W1EJ# +M!0"8`0``F`$```(```!%``&48_@``$`1``#`J`$!P*@!`@'T`?0!@`=E(;LC +M@P:H_AD``````````"$@(@@````````!>"(``'@```!W`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``EDNP\W9FS[:H:CQ*P93?"-!F:.9XC=@@0:ZS +M+HDI"?Y>+HSNQW0EA7'7'];27`#OI!]V7WMP!$76=S.,)&?4P![W5#;@X&0; +MHRQ\E_X]MN*H=S$&IVF5?]@+:M?G%);T2URVUIL0QV?AXFR##(PU"X*21JW\ +M"WX\1.>G]>=M/-XI```DA;4HG4R"L74#8UV=P8!_/GPF*EV`CGPK3C73Z,N@ +M`5,4:TO41^=4````'```0`4UL4]#Y-#0 +MT+5OBQD62_[=&_)>&Y,2MT8$I0@`F`$``)@!```"````10`!E&/Z``!`$0`` +MP*@!`<"H`0(!]`'T`8`'92&[(X,&J/X9```````````A("((`````````7@B +M``!X````=P$!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`. +M`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P`` +M"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``)9+L/-V9L^V +MJ&H\2L&4WPC09FCF>(W8($&NLRZ)*0G^7BZ,[L=T)85QUQ_6TEP`[Z0?=E][ +M<`1%UG]U0VX.!D&Z,L?)?^/;;BJ')L@PR,-0N"DD:M_`M^/$3GI_7G;3S>*0``)(6U*)U,@K%U`V-= +MG<&`?SY\)BI=@(Y\*TXUT^C+H'*C*0``'```0`0^(\>4-L>4Q\9X'@%3%&M+ +MU$?G5````!P``$`%-;%/0^30T-"U;XL9%DO^W1OR7AN3$K=&EN8.`)@!``"8 +M`0```@```$4``91C^P``0!$``,"H`0'`J`$"`?0!]`&`!V4ANR.#!JC^&0`` +M````````(2`B"`````````%X(@``>````'W`$1=9W,XPD9]3`'O=4-N#@9!NC+'R7_CVV +MXJAW,0:G:95_V`MJU^<4EO1+7+;6FQ#'9^'B;(,,C#4+@I)&K?P+?CQ$YZ?U +MYVT\WBD``"2%M2B=3(*Q=0-C79W!@'\^?"8J78".?"M.-=/HRZ!RHRD``!P` +M`$`$/B/'E#;'E,?&>!X!4Q1K2]1'YU0````<``!`!36Q3T/DT-#0M6^+&19+ +M_MT;\EX;E!*W1K+R#`"8`0``F`$```(```!%``&48_X``$`1``#`J`$!P*@! +M`@'T`?0!@`=E^:"D$FFP"(``'@```!X +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``&:;EH!0N')FU;T:/ONMH +M))E2V7P%W9]+H5_(J316(A#+1WMR)HLT0QWMQKF +M-YZ1Q,$!$4J`_M\V(L$I```<``!`!)<4-V50S#.IV*!FP7V&3I*P0,;2```` +M'```0`64C[%^/+_06\IV5942MT;2W```F`$``)@!```"```` +M10`!E&/_``!`$0``P*@!`<"H`0(!]`'T`8`'9?F@I!)IL'+R```````````A +M("((`````````7@B``!X````>`$!``P#```,`0``#(`.`(`#```,`0``#(`. +M`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@`` +M!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"( +M``(``!FFY:`4+AR9M6]&C[[K:"294ME\!=V?2Z%?R*DT5B(0RT=[K,J&:W]2R"99,+')][[B;+@7U1=F-T[+A["%S!81MBX:?8,:E-&';,*0`` +M)%KQ&QY[$_G//6*I*BIJ8ZF7IC>>D<3!`1%*@/[?-B+!*0``'```0`27%#=E +M4,PSJ=B@9L%]ADZ2L$#&T@```!P``$`%E(W.:9Q\&V\[@'NQ?CR_T%O*=E65 +M$K=&````'@!`0`,`P`` +M#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```( +M`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4# +M```(!````@````@$```.*```B``"```9IN6@%"XW(FBS1#'>W&MSDB+S.[C3P4[^U8#.WT^CCF;@;-A6'( +M',K>1-.=K%62@9W9WTS`92)6-AGJS*AFM_4L@F63"QR?>^XFRX%]479C=.RX +M>PA>Q/YSSUBJ2HJ:F.IEZ8WGI'$P0$1 +M2H#^WS8BP2D``!P``$`$EQ0W95#,,ZG8H&;!?89.DK!`QM(````<``!`!92- +MSFF"(``'@```![`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``L8OJ +MRL)M7):8:*OB4V(B&IYDE%#QQ;)VKR"O1I:C;!H\T1^KV6*IQ&0N*%2W]2C1 +MIN4'#+M4%S-&'N!4*O=G1T`QNS^HUG"#EI[3GKRRRY#E-6Q#HN0I54?(W^1A +M05U[(3HJ][2\GM6OBGG(Z!]A9)((&!Z?AP!\M&&$XD?`X\HI```DI,:>$U80 +MX/$:F%RTDR.Z59XE)"`;?LZ[)5]45AA0J'(I```<``!`!*UY8@M-WS>GT283 +M$WR=#"9`TZWE````'```0`47O/N2'T+$#7^>%Q("5@K\!Q^66)82MT;25@@` +MF`$``)@!```"````10`!E&0.``!`$0``P*@!`<"H`0(!]`'T`8`'96`K]<$9 +MNS_X```````````A("((`````````7@B``!X````>P$!``P#```,`0``#(`. +M`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P`` +M"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```" +M````"`0```XH``"(``(``+&+ZLK";5R6F&BKXE-B(AJ>9)10\<6R=J\@KT:6 +MHVP:/-$?J]EBJ<1D+BA4M_4HT:;E!PR[5! +MTYZ\LLN0Y35L0Z+D*55'R-_D84%=>R$Z*O>TO)[5KXIYR.@?8622"!@>GX<` +M?+1AA.)'P./**0``)*3&GA-6$.#Q&IA)20@&W[.NR5?5%884*AR +M*0``'```0`2M>6(+3=\WI]$F$Q-\G0PF0-.MY0```!P``$`%%[S[DA]"Q`U_ +MGA<2`E8*_`````'L!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#` +M`P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@# +M```!`P``"`,```4#```(!````@````@$```.*```B``"``"QB^K*PFUX%0J]V='0#&[/ZC6<(.6GM.>O+++D.4U;$.BY"E51\C?Y&%!77LA.BKW +MM+R>U:^*>4````<``!`!1>\^Y(?0L0-?YX7$@)6"OP''Y98EQ*W1I*A#`"8`0``F`$` +M``(```!%``&49"```$`1``#`J`$!P*@!`@'T`?0!@`=EAU,J.O#CV=4````` +M`````"$@(@@````````!>"(``'@```!\`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``2L"EM:%/5>4SR6]_Z:-@]ZM8JVMUH6M(GH!<&Z.QQFQ3F@-^ +MDB.8SD\N.F842UNIWXW2N65+D"!1I$-X_^=>"IT\$\"H0Q/5!ED8WS$_"M3O +M_>JHX&SUHC3#LASUZ1NWC*F1.=7H-@8(8]/R5[.>0*0+*^F_EU,D&#`.;/:* +M.U(I```D.8`:Z2F1TJKZ?T,;O*(>1%_Z[I_SHT:YL?@I&4]6M"0I```<``!` +M!%@3O@3B=-Z%^T0?DLUHQ+$C`PT?````'```0`5!6-+J13.VH5\3(3S\AKAW +M4[,H+Y@2MT:KC@``F`$``)@!```"````10`!E&0A``!`$0``P*@!`<"H`0(! +M]`'T`8`'98=3*CKPX]G5```````````A("((`````````7@B``!X````?`$! +M``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0`` +M`P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```( +M`P``!0,```@$```"````"`0```XH``"(``(``$K`I;6A3U7E,\EO?^FC8/>K +M6*MK=:%K2)Z`7!NCL<9L4YH#?I(CF,Y/+CIF%$M;J=^-TKEE2Y`@4:1#>/_G +M7@J=/!/`J$,3U099&-\Q/PK4[_WJJ.!L]:(TP[(<]>D;MXRID3G5Z#8&"&/3 +M\E>SGD"D"ROIOY=3)!@P#FSVBCM2*0``)#F`&NDID=*J^G]#&[RB'D1?^NZ? +M\Z-&N;'X*1E/5K0D*0``'```0`18$[X$XG3>A?M$'Y+-:,2Q(P,-'P```!P` +M`$`%05C2ZD4SMJ%?$R$\_(:X=U.S*"^8$K=&(]`&`)@!``"8`0```@```$4` +M`91D(@``0!$``,"H`0'`J`$"`?0!]`&`!V6'4RHZ\./9U0``````````(2`B +M"`````````%X(@``>````'P!`0`,`P``#`$```R`#@"``P``#`$```R`#@$` +M`P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0# +M```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``" +M``!*P*6UH4]5Y3/);W_IHV#WJUBK:W6A:TB>@%P;H['&;%.:`WZ2(YC.3RXZ +M9A1+6ZG?C=*Y94N0(%&D0WC_YUX*G3P3P*A#$]4&61C?,3\*U._]ZJC@;/6B +M-,.R'/7I&[>,J9$YU>@V!@ACT_)7LYY`I`LKZ;^74R08,`YL]HH[4BD``"0Y +M@!KI*9'2JOI_0QN\HAY$7_KNG_.C1KFQ^"D93U:T)"D``!P``$`$6!.^!.)T +MWH7[1!^2S6C$L2,##1\````<``!`!4%8TNI%,[:A7Q,A//R&N'=3LR@OF1*W +M1@/9!`"8`0``F`$```(```!%``&49",``$`1``#`J`$!P*@!`@'T`?0!@`=E +MU:A&8`.*8W4``````````"$@(@@````````!>"(``'@```!]`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``.2@:JI.63ET`AJ@%58DF6H``J"L-%1%( +MNWDI*?__(\]2*)JCC:/\[7#A]4[O,VDLHNTO +M%<)4^ZZ38Z8V*$2![C]Q11=J(>%=VVA%.WOR0O:\>`S=_LS?-W"O5G4,N`,B +MP-Q,9]6C=\1@;KGVE3(I```DZ`6V-'R1$V^B%`.HM'$[1*G:07`Y-'L"/7U+ +MEJ=O,<,I```<``!`!-#`M>Q.WO57)D5;X_<447:B'A7=MH13M[ +M\D+VO'@,W?[,WS=PKU9U#+@#(L#<3&?5HW?$8&ZY]I4R*0``).@%MC1\D1-O +MHA0#J+1Q.T2IVD%P.31[`CU]2Y:G;S'#*0``'```0`30P+7L3M[U5R9%6W#] +MC_8Y3_\W#0```!P``$`%.AJ)]*>W/FZT^QV]8Y2F?W>UUM>9$K=&34H.`)@! +M``"8`0```@```$4``91D)0``0!$``,"H`0'`J`$"`?0!]`&`!V75J$9@`XIC +M=0``````````(2`B"`````````%X(@``>````'T!`0`,`P``#`$```R`#@"` +M`P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@" +M```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@`` +M``@$```.*```B``"```Y*!JJDY9.70"&J`55B29:@`"H*PT5$4B[>2DI__\C +MSU(HFJ.-H_SM<.'U3N\QR'/J>CZL,VA`Y0]E^+#/!S9[:2RB[2\5PE3[KI-C +MIC8H1('N/W%%%VHAX5W;:$4[>_)"]KQX#-W^S-\W<*]6=0RX`R+`W$QGU:-W +MQ&!NN?:5,BD``"3H!;8T?)$3;Z(4`ZBT<3M$J=I!<#DT>P(]?4N6IV\QPRD` +M`!P``$`$T,"U[$[>]5"(``'@` +M`/__`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``M*^#!%0A^/T+'J=] +MU+D:I!>9+:[JU)P1<3_](+(67E/>\QE&)6HPAPTQ(F(]APOZSU#\A'G4IZ4U-$)3Y&1@'N?6>T(N<9^[+C$A9W1"4S34+K$! +M$K6?'O=O?$SZ3`R/%_>X(@JZS1E!@(6ZPBDI```D`*.,CDFHCC8F%<==S,A$ +MVZ07.7NL]E27-58!BZ@H0```F`$``)@!```" +M````10`!E&0L``!`$0``P*@!`<"H`0(!]`'T`8`'93+LK.V6*C#]```````` +M```A("((`````````7@B``!X``#__P$!``P#```,`0``#(`.`(`#```,`0`` +M#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```( +M`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH +M``"(``(``+2O@P14(?C]"QZG?=2Y&J07F2VNZM2<$7$__2"R%EY3WO,91B5J +M,(<-,2)B/8<+^L]7,K4>%'/E\`]#370-1.E:>.'@_(1YU*>E-31"4^1D8![G +MUGM"+G&?NRXQ(6=T0E,TU"ZQ`1*UGQ[W;WQ,^DP,CQ?WN"(*NLT908"%NL(I +M*0``)`"CC(Y)J(XV)A7'7C````!P``$`%=H59PPYKZ!ZOI+N[YB(1`"-P +MA36;$K=&_H$&`)@!``"8`0```@```$4``91D-```0!$``,"H`0'`J`$"`?0! +M]`&`!V4R[*SMEBHP_0``````````(2`B"`````````%X(@``>```__\!`0`, +M`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,# +M```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,` +M``4#```(!````@````@$```.*```B``"``"TKX,$5"'X_0L>IWW4N1JD%YDM +MKNK4G!%Q/_T@LA9>4][S&48E:C"'#3$B8CV'"_K/5S*U'A1SY?`/0TUT#43I +M6GCAX/R$>=2GI34T0E/D9&`>Y]9[0BYQG[LN,2%G=$)3--0NL0$2M9\>]V]\ +M3/I,#(\7][@B"KK-&4&`A;K"*2D``"0`HXR.2:B.-B85QUW,R$3;I!ZSV +M5)KZ2[N^8B$0`C<(4UG!*W1MJ-!`"8`0``F`$```(```!%``&4 +M9'$``$`1``#`J`$!P*@!`@'T`?0!@`=E+B+0&]%]H5```````````"$@(@@` +M```````!>"(``'@``(```0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M9^J^2>C2^3X=&F^YU3)[>B0@C_!\#"V7_)4&+/C.`#9FR"@0P?/SAM0DS^F= +M9[>+9&J%&ICTO-JFV+R.M26@D\:@6_'G=E`=18P>A1/8W["'(^D\WA2=S:R# +MD4\'._*-.!7(^,?/GT#FZ])TWHD((_P?`PME_R5 +M!BSXS@`V9L@H$,'S\X;4),_IG6>WBV1JA1J8]+S:IMB\CK4EH)/&H%OQYW90 +M'46,'H43V-^PAR/I/-X4G"0)-"H)]\/I\L(0)VH"/%.%/E +MSAM#*0``'```0`1%"@7Q/94?#9,HXPY)$JA2N,A%,````!P``$`%S_Q=6?V( +M'/$R0SVE2C7\&024>LZ<$K=&>?P-`)@!``"8`0```@```$4``91D?P``0!$` +M`,"H`0'`J`$"`?0!]`&`!V4N(M`;T7VA4```````````(2`B"`````````%X +M(@``>```@``!`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R` +M#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,` +M``@#```!`P``"`,```4#```(!````@````@$```.*```B``"``!GZKY)Z-+Y +M/AT:;[G5,GMZ)""/\'P,+9?\E08L^,X`-F;(*!#!\_.&U"3/Z9UGMXMD:H4: +MF/2\VJ;8O(ZU):"3QJ!;\>=V4!U%C!Z%$]C?L(%)W-K(.13P<[\HTX +M%NRD``"34_>SQRF4_VM^' +M@D"30J"??#Z?+"$"=J`CQ3A3Y"(``'@```!T``$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``;**S2:1PPAVT*;<@0W`0O_'B6.B#-X"7Q24+Q2]!?#&3 +MA-(B8&(G0.?D#-6"6,Y7;@@*G@1=E-]0S[S,\+U0[2(CE(UY'N5N:6P&MD]4FCDWG!S.Y$UICWMRMH(F7(T+;B_0`QTE2$HTEZ#U_=%>NN\]IJ:#$M,[."QIH=B(T,I```< +M``!`!/YLD^GOP,2UAX,=M@;XXX%[1G[+````'```0`4KD3E0C9@T?4=\*=W_ +M_7"U9DL.0YT2MT:5-`\`F`$``)@!```"````10`!E&2Q``!`$0``P*@!`<"H +M`0(!]`'T`8`'9=06_#(.*`>````````````A("((`````````7@B``!X```` +M=``!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```( +M`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$# +M```(`P``!0,```@$```"````"`0```XH``"(``(``&RBLTFD<,(=M"FW($-P +M$+_QXECH@S>`E\4E"\4O07PQDX32(F!B)T#GY`S5@EC.5VX("IX$793?4,^\ +MS/"]4.TB(Y2->1[E;FEL''RPSX.=BQ3E.H[WAK9/5)HY-YP@]?W17KK +MO/::F@Q+3.S@L::'8B-#*0``'```0`3^;)/I[\#$M8>#';8&^..!>T9^RP`` +M`!P``$`%*Y$Y4(V8-'U'?"G=__UPM69+#D.>$K=&Q3,&`)@!``"8`0```@`` +M`$4``91EFP``0!$``,"H`0'`J`$"`?0!]`&`!V74%OPR#B@'@``````````` +M(2`B"`````````%X(@``>````'0``0`,`P``#`$```R`#@"``P``#`$```R` +M#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(` +M``0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*``` +MB``"``!LHK-)I'#"';0IMR!#)8Z(,W@)?%)0O%+T%\,9.$TB)@8B=` +MY^0,U8)8SE=N"`J>!%V4WU#/O,SPO5#M(B.4C7D>Y6YI;!Q\L,^#G8L4Y3J. +M]X:V3U2:.3><',[D36F/>W*V@B9_TM2K]N@.9Q21L?I:82D` +M`"3!Z+]`#'25(2C27H/7]T5ZZ[SVFIH,2TSLX+&FAV(C0RD``!P``$`$_FR3 +MZ>_`Q+6'@QVV!OCC@7M&?LL````<``!`!2N1.5"-F#1]1WPIW?_]<+5F2PY# +MGQ*W1E!"!`"8`0``F`$```(```!%``&49N8``$`1``#`J`$!P*@!`@'T`?0! +M@`=E>?]B!O<.OA<``````````"$@(@@````````!>"(``'@```!T`@$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``]!>83ZV\'AS3BR50U3,R*UQ\T/25 +M9F$'-P7[F.N8C!C!B,NYQ,[=@FO1'IK=B"'Y;?KYR3XXTFQTYK7EMDT,)M4/ +M"Q\E*XAHJAU:XK)8<4<;DWNH:&L.(M3O,!A,WPO.I[C3,2_:FT$T!1$'<*B" +M^RNY"^W2[Z<].@T'9HNNZ>DI```D:Q-H7%Y,)M;+CEUP+)H$ADQPNMLU"W.[ +M6ZD?+*SEZ`,I```<``!`!/\)3FH7WAQL21*+Y1Q(HGH,+I;O````'```0`5U +M2GB__KA\<#8<[1XJ\W<^)D6$RY\2MT9';`<`F`$``)@!```"````10`!E&;R +M``!`$0``P*@!`<"H`0(!]`'T`8`'97G_8@;W#KX7```````````A("((```` +M`````7@B``!X````=`(!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```, +M`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@# +M```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``/07 +MF$^MO!XXTS$OVIM!-`41!W"H@OLKN0OMTN^G/3H-!V:+KNGI*0``)&L3:%Q> +M3";6RXY=<"R:!(9,<+K;-0MSNUNI'RRLY>@#*0``'```0`3_"4YJ%]X<;$D2 +MB^4<2*)Z#"Z6[P```!P``$`%=4IXO_ZX?'`V'.T>*O-W/B9%A,N?$K=&UJT- +M`)@!``"8`0```@```$4``91F^@``0!$``,"H`0'`J`$"`?0!]`&`!V5Y_V(& +M]PZ^%P``````````(2`B"`````````%X(@``>````'0"`0`,`P``#`$```R` +M#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,` +M``@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!``` +M`@````@$```.*```B``"``#T%YA/K;P>'-.+)5#5,S(K7'S0])5F80FMV((?EM^OG)/CC2;'3FM>6V30PFU0\+'R4KB&BJ +M'5KBLEAQ1QN3>ZAH:PXBU.\P&$S?"\ZGN-,Q+]J;030%$0=PJ(+[*[D+[=+O +MISTZ#0=FBZ[IZ2D``"1K$VA<7DPFULN.77`LF@2&3'"ZVS4+<[M;J1\LK.7H +M`RD``!P``$`$_PE.:A?>'&Q)$HOE'$BB>@PNEN\````<``!`!75*>+_^N'QP +M-ASM'BKS=SXF183+H!*W1E*Y"P"8`0``F`$```(```!%``&49TT``$`1``#` +MJ`$!P*@!`@'T`?0!@`=E4567_"(` +M`'@```!T`@$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``@+K%%XGPUV)& +M#7_3O58JVSW!&<2WUP<[*7Z\4]YA*^.,)V#Q,8%`2^9J]IE +M)"-+````'```0`5U9@>8K)\-=B1@U_T[U6*ML]P1G$M]<'.RE^O%/>82OCC"=@ +M\3&!7*1U!RLT>U95FI7WYTBDQITO):EHX6:%]O[E>KDD-PX##D'VG=[>8XGU +MP/^N2!!#"#)4]`-_!I;F/)+@F017`J5Y*E_/((DT8VONSDO-5\D]AF(ZK1+/ +M(HC`*0``)#!\;ESM[85%_Q`-#$0&`[A*>!@\J5T.['>%WT@$M6V'*0``'``` +M0`0*6&(H&Z#^MRH)7@$OF:O:920C2P```!P``$`%=68'F*W**U%L4_>@4%`)@!``"8`0```@```$4``91G3P``0!$``,"H`0'`J`$" +M`?0!]`&`!V5159?]RAHXT@``````````(2`B"`````````%X(@``>````'0" +M`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$` +M``,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P`` +M"`,```4#```(!````@````@$```.*```B``"``"`NL47B?#78D8-?].]5BK; +M/<$9Q+?7!SLI?KQ3WF$KXXPG8/$Q@5RD=0WF.)]<#_KD@00P@R5/0#?P:6YCR2X)D$5P*E>2I? +MSR")-&-K[LY+S5?)/89B.JT2SR*(P"D``"0P?&Y<[>V%1?\0#0Q$!@.X2G@8 +M/*E=#NQWA=](!+5MARD``!P``$`$"EAB*!N@_K#KBL``````````"$@ +M(@@````````!>"(``'@```!T`P$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``TBJ;2:@L(:"])^D3>]D8]ZQY1A":B,]*W0[<+P\-7!VV5`>R54(;>$BZ +MRUKXV#=AWEK92?`MDRU1"[*EFO4;;!)J!U_%^KUB_?,[9>S`VXSTK$>;\197 +M2I@8AV3I=0P`EF""$&SS-_=@6;F?;)HB+-B7MFOC.VE*?XSSG27*0EXI```D +MHU\TS3R2AZ'42X90TF%)67KR#LN$QE3`\>B?Q&!.LU\I```<``!`!,FYF[>; +MJ+FQQMP.$^US+[Q:00R!````'```0`7D9Y+GBWAIH5!OP\7APV?O``!`$0``P*@!`<"H`0(!]`'T`8`' +M936,DL-'@ZXK```````````A("((`````````7@B``!X````=`,!``P#```, +M`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@" +M```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,` +M``@$```"````"`0```XH``"(``(``-(JFTFH+"&@O2?I$WO9&/>L>480FHC/ +M2MT.W"\/#5P=ME0'LE5"&WA(NLM:^-@W8=Y:V4GP+9,M40NRI9KU&VP2:@=? +MQ?J]8OWS.V7LP-N,]*Q'F_$65TJ8&(=DZ74,`)9@@A!L\S?W8%FYGVR:(BS8 +ME[9KXSMI2G^,\YTERD)>*0``)*-?-,T\DH>AU$N&4-)A25EZ\@[+A,94P/'H +MG\1@3K-?*0``'```0`3)N9NWFZBYL<;<#A/M2 +MYXMX::%0;\/%X<-GW)Q;YR6B$K=&IU\-`)@!``"8`0```@```$4``91GL``` +M0!$``,"H`0'`J`$"`?0!]`&`!V4UC)+#1X.N*P``````````(2`B"``````` +M``%X(@``>````'0#`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$` +M``R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P`` +M`@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``#2*IM) +MJ"PAH+TGZ1-[V1CWK'E&$)J(STK=#MPO#PU<';94![)50AMX2+K+6OC8-V'> +M6ME)\"V3+5$+LJ6:]1ML$FH'7\7ZO6+]\SME[,#;C/2L1YOQ%E=*F!B'9.EU +M#`"68((0;/,W]V!9N9]LFB(LV)>V:^,[:4I_C/.=)O(.RX3&5,#QZ)_$8$ZS7RD``!P``$`$R;F;MYNHN;'&W`X3 +M[7,OO%I!#($````<``!`!>1GDN>+>&FA4&_#Q>'#9]R<6^"(``'@```!T!`$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``29-:O[K9&EZG4/5SR=!UXQT4&7#ZG1%^0PDD\U8L +M677J%V@#@R3L]$T9?]URLX[ALCU5#`%.9/?]\P;I#:WV4A-H#2T?=R<9U/YY632)C3P/W +M8=M#&`VN.API```D0IC![8=*8P!E7]3V#^X7UR/:$I,RXCTH,;L?@B(^H<`I +M```<``!`!+)"AW*"`R_V!X\&DSYR&7(LG$\H````'```0`7@HHK8=F!8PC@X +MG^,,WEPN9[.]?*,2MT80F`X`F`$``)@!```"````10`!E&@2``!`$0``P*@! +M`<"H`0(!]`'T`8`'9==XXG_([J0H```````````A("((`````````7@B``!X +M````=`0!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`# +M```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,` +M``$#```(`P``!0,```@$```"````"`0```XH``"(``(``$F36K^ZV1I>IU#U +M<\G0=>,=%!EP^IT1?D,))/-6+%EUZA=H`X,D[/1-&7_=5DTB8T\#]V';0Q@-KCH<*0``)$*8P>V'2F,`95_4]@_N +M%]/!I,^SO7RD$K=&W9<%`)@!``"8`0`` +M`@```$4``91H&@``0!$``,"H`0'`J`$"`?0!]`&`!V77>.)_R.ZD*``````` +M````(2`B"`````````%X(@``>````'0$`0`,`P``#`$```R`#@"``P``#`$` +M``R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P`` +M"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```. +M*```B``"``!)DUJ_NMD:7J=0]7/)T'7C'109H7:`.# +M).ST31E_W7*SCN%RAZR/55S/6]Q.K2G]&Q-89MUBW9VE/+J`BF_&?L:C>:`W +M6[>A)K=))X,`4YD]_WS!ND-K?92$V@-+1]W)QG4_GE9-(F-/`_=AVT,8#:XZ +M'"D``"1"F,'MATIC`&5?U/8/[A?7(]H2DS+B/2@QNQ^"(CZAP"D``!P``$`$ +MLD*'"BBMAV8%C".#B?XPS>7"YG +ML[U\I1*W1L"B`P"8`0``F`$```(```!%``&4:!\``$`1``#`J`$!P*@!`@'T +M`?0!@`=E0K^WN.=KWYH``````````"$@(@@````````!>"(``'@```!T!P$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``V4FR4/N#H^9(Y=VTY\5.=<.E +M"DE5_;Y8E=0,#Q1#(57,9:TR +M6(+%U+]\^AW+1C"K>C=GNN+TZCFRPHCHM7N"<@MVPC(M;X?GX'QTUW3664<@ +M*J6>.OZ@U&7JRHQ:IGUJ^@]O5G0H"X&H#<(:42MT:KSP8`F`$``)@!```"````10`! +ME&@@``!`$0``P*@!`<"H`0(!]`'T`8`'94*_M[CG:]^:```````````A("(( +M`````````7@B``!X````=`@```!P``$`%Z,XYVO?F@``````````(2`B"`````````%X(@``>````'0'`0`,`P``#`$` +M``R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@`` +M`@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```( +M!````@````@$```.*```B``"``#92;)0^X.CYDCEW;3GQ4YUPZ4*257]R(3> +MAHLPLZ%`O[8M;(YKO!I2@B6!&=A')P]YOEB5U`P/%$,A5ZXO3J.;+"B.BU>X)R"W;",BUOA^?@?'37=-991R`JI9XZ_J#4 +M9>K*C%JF=R]I/__T8RD``"3@C47")K;Q.(2F9!%?@=$>_?MLPQ`G2B-;,P#Y +M+*9QJ"D``!P``$`$7^VSYH)+^*7?32O!T[YP9#\(/7H````<``!`!>C'*%PG +M#I[6KZ#V]6="@+@:@-PAIA*W1H\>"P"8`0``F`$```(```!%``&4:"P``$`1 +M``#`J`$!P*@!`@'T`?0!@`=E3&UB<`W"(``'@```!T"`$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``--#)HZ,= +MM3.BUF75Q!CE'V^'3^^1"VS6C,`OCNPS7DL)2+5KVX,DF66NA;4,)O@@.*FH +M:&XIN?6]D$R0F]J23G#0$I@Z*PG#1C`9U0AWGH8QB&Z(L3Q6R>^).LY):)I= +MV7OQAVV?9]5,`+9>(7*A91B(*L>T1=SF'X0@```!P``$`%CD+V*58QZ=44%"DU +M>H8Z3D4+;8*G$K=&+TD%`)@!``"8`0```@```$4``91H.P``0!$``,"H`0'` +MJ`$"`?0!]`&`!V5,;6)P#=SJD0``````````(2`B"`````````%X(@``>``` +M`'0(`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P`` +M"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```! +M`P``"`,```4#```(!````@````@$```.*```B``"```TT,FCHQVU,Z+69=7$ +M&.4?;X=/[Y$+;-:,P"^.[#->2PE(M6O;@R299:Z%M0PF^"`XJ:AH;BFY];V0 +M3)";VI).<-`2F#HK"<-&,!G5"'>>AC&(;HBQ/%;)[XDZSDEHFEW9>_&'9P%# +MQU@MW(WMGV?53`"V7B%W(H==45VVA:-G3RD``"3=AV&L!V/JR&K5P58&@D"- +MNHYF2TS$#2MJ&0S<&9+";BD``!P``$`$0,BAD#+;7BH648B"K'M$7G5%!0I-7J&.DY%"VV"J!*W1HI5`P"8`0``F`$```(` +M``!%``&4:#T``$`1``#`J`$!P*@!`@'T`?0!@`=E+:GTMV*?#HL````````` +M`"$@(@@````````!>"(``'@```!T"0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``H$Q5[Z@A!4/3J/?WR!9KQ>.14Y+RFFB5_I_CV3\P#V7FIOD\QTU( +MV(("#!:+;XWJ[LWC\!)9`I```<``!`!&$; +M.1P"%?_!$L#0CERX+!$X?-ZU````'```0`7NE:"]M#7,Y,?0]Y57M^H(05#TZCW]\@6:\7CD5.2 +M\IIHE?Z?X]D_,`]EYJ;Y/,=-2-B"`@P6BV^-ZN[-W#_59"/+A1-!6L?XF*=P +M37Q(QYE0M3KZ:V%8W4Q1&]CF;-H]Z$0\_N)5?(?2MS[TK8B7T38IHQYI[-^- +M%&^L):2UJ,QX#'6@#OA/UM$>*0``)*6'X8^O>D@_6CWQ81(,+TKV:ND\\.@U +M5C=%JWH_`260*0``'```0`1A&SD<`A7_P1+`T(YM0```!P``$`% +M[I6@O;0US.3'T/>55[7.2R-F,@*H$K=&+<,,`)@!``"8`0```@```$4``91H +M10``0!$``,"H`0'`J`$"`?0!]`&`!V4MJ?2W8I\.BP``````````(2`B"``` +M``````%X(@``>````'0)`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P`` +M#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```( +M`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``"@ +M3%7OJ"$%0].H]_?(%FO%XY%3DO*::)7^G^/9/S`/9>:F^3S'34C8@@(,%HMO +MC>KNS=P_U60CRX4305K'^)BG<$U\2,>94+4Z^FMA6-U,41O8YFS:/>A$//[B +M57R'TK<^]*V(E]$V*:,>:>S?C11OK"6DM:C,>`QUH`[X3];1'BD``"2EA^&/ +MKWI(/UH]\6$2#"]*]FKI//#H-58W1:MZ/P$ED"D``!P``$`$81LY'`(5_\$2 +MP-".7+@L$3A\WK4````<``!`!>Z5H+VT-USDLC9C("J1*W1N0[ +M"P"8`0``F`$```(```!%``&4:-$``$`1``#`J`$!P*@!`@'T`?0!@`=E[X9? +M[F*,X4(``````````"$@(@@````````!>"(``'@```!T^`$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``8'8'VN:J3&+GZ/ID:$2UO\3K^%[/;_\Y3FH: +MH(UC/_!_P+?>227QJ6LC350!`>E*'+CCO``&%>.1%W8+[0%9>88PJ^JH@]I$ +M*;0'('5;:M:Z?^!=N3.2A3TT7-=W)`\J>]"6EW#GDM74AC\IJ`+DC%RQ?F3# +ML>;CPH4UW)KZ&>(I```DH5,C;FTW)!%&;&+Q0,F1@W^;MNL>?U&&TFKK.U$" +M9;0I```<``!`!-L&L2=#XV]*4DO7GAR!PVBD6WSS````'```0`5\G7FF8#3G +M.IS1R9>'KJU_EZ$F^&7^YBC.%"```````````A("((`````````7@B +M``!X````=/@!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`. +M`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P`` +M"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``&!V!]KFJDQB +MY^CZ9&A$M;_$Z_A>SV__.4YJ&J"-8S_P?\"WWDDE\:EK(TU4`0'I2ARXX[P` +M!A7CD1=V"^T!67F&,*OJJ(/:1"FT!R!U6VK6NG_@7;DSDH4]-%S7=R0/*GO0 +MEI=PYY+5U(8_*:@"Y(QA)G.J$K=&$W`%`)@!``"8 +M`0```@```$4``91HU```0!$``,"H`0'`J`$"`?0!]`&`!V7OAE_N8HSA0@`` +M````````(2`B"`````````%X(@``>````'3X`0`,`P``#`$```R`#@"``P`` +M#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```! +M`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$ +M```.*```B``"``!@=@?:YJI,8N?H^F1H1+6_Q.OX7L]O_SE.:AJ@C6,_\'_` +MM]Y))?&I:R--5`$!Z4H2U=2&/RFH`N2,7+%^9,.QYN/"A37< +MFOH9XBD``"2A4R-N;3>'('#:*1;?/,````<``!`!7R=>:9@-.N +MK7^7H29SJQ*W1N)Z`P"8`0``F`$```(```!%``&4:-4``$`1``#`J`$!P*@! +M`@'T`?0!@`=EK86F^]W"*>P``````````"$@(@@````````!>"(``'@```!T +M^0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``C?&A.:E_JJY'65:,A2@9 +MWV@U3:V3M;UV'Z%`3(0@XIN:YDZZ^[)+,%&2\[0OCB8IP7X9.R +M[2S-[E(MQPBKS&```` +M'```0`5>*>>&RYX$Z^+:S[W$@V.S#(I[6:L2MT:@J`8`F`$``)@!```"```` +M10`!E&C:``!`$0``P*@!`<"H`0(!]`'T`8`'9:V%IOO=PBGL```````````A +M("((`````````7@B``!X````=/D!``P#```,`0``#(`.`(`#```,`0``#(`. +M`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@`` +M!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"( +M``(``(WQH3FI?ZJN1UE6C(4H&=]H-4VMD[6]=G(A3U'"IPGA^A0$R$(.*;FN +M9.NONR2S!1DO.T+XXF*<%^&3LG(OOZ.*D4$]''*H8I3GNTLS>Y2+<<(J\Q@```!P``$`%7BGGALN>!.OBVL^]Q(-CLPR*>UFK +M$K=&+^H,`)@!``"8`0```@```$4``91HXP``0!$``,"H`0'`J`$"`?0!]`&` +M!V6MA:;[W<(I[```````````(2`B"`````````%X(@``>````'3Y`0`,`P`` +M#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```( +M`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4# +M```(!````@````@$```.*```B``"``"-\:$YJ7^JKD=95HR%*!G?:#5-K9.U +MO79R(4]1PJ<)X?H4!,A"#BFYKF3KK[LDLP49+SM"^.)BG!?AD[)R+[^CBI%! +M/1QRG,>/DTXN^V"\;2 +M!VLTG:8^'"D``!P``$`$-]_G3A7J&*4Y[M+,WN4BW'"*O,8````<``!`!5XI +MYX;+G@3KXMK/O<2#8[,,BGM9K!*W1H7U"@"8`0``F`$```(```!%``&4:/4` +M`$`1``#`J`$!P*@!`@'T`?0!@`=E*#>4BK."(``'@```!T^@$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``'.I< +MVV7'2G7,/':GJ4B4R&RO+IIZ*'GH8TG'C;D6(R5;UV,8Z!`E8E% +M)2SE05*'OA03RU8OQD2(?"O.Q4:$<]`-_I7?J_WN63!T7!,I```D=Y7$Y[]P9UUW`_"&[OZZP2MT:T(@X` +MF`$``)@!```"````10`!E&D%``!`$0``P*@!`<"H`0(!]`'T`8`'92@WE(JS +MG(I4```````````A("((`````````7@B``!X````=/H!``P#```,`0``#(`. +M`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P`` +M"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```" +M````"`0```XH``"(``(``!SJ7-MEQTIUS#QVIZE(E,ALKRZ:>BAYZ&-)QXVY +M'*]38^T-<+^N-MP?@KU:[#;/Z%5W:0<<2&G%$41X>',*&RZ^`6+&,-,9D+]< +M0C':`S6L'EB,E6]=C&.@0)6)124LY4%2A[X4$\M6+\9$B'PKSL5&A'/0#?Z5 +MWZO][EDP=%P3*0``)'>5W*H*1[-4K<*NR5BO&-S#@A%$"'A.7-#&Y6>?#3A; +M*0``'```0`2H[T#,Z\Q>TR@<'\A>[!`SG4Y"O````!P``$`%MJ:F18#-C&=G +MN_<&===P/PAN[^NM$K=&["$%`)@!``"8`0```@```$4``91I"```0!$``,"H +M`0'`J`$"`?0!]`&`!V4H-Y2*LYR*5```````````(2`B"`````````%X(@`` +M>````'3Z`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#` +M`P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@# +M```!`P``"`,```4#```(!````@````@$```.*```B``"```I2)3(;*\NFGHH>>AC2<>-N1RO4V/M#7"_KC;<'X*]6NPVS^A5=VD''$AI +MQ1%$>'AS"ALNO@%BQC#3&9"_7$(QV@,UK!Y8C)5O78QCH$"5B44E+.5!4H>^ +M%!/+5B_&1(A\*\[%1H1ST`W^E=^K_>Y9,'1<$RD``"1WE=RJ"D>S5*W"KLE8 +MKQC"(``'@```!T_0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``&.?G+Z,Y6N\VE\?D+_A2W,](P$%-T.O49\;-S^9:%!X$L@D2 +M2L'%%;+[SP/>P%DT.1K:THG<.HW8JKN_6E5@=Y(3S[-LSTU<=%WZ^G)%(]56 +MH0F*<)4DXR1/[.X"]HG_`:#\S,<&-0>0\!?X(&,\\&,'=#N808,'`QQK>A*8 +MV$XI```DF=:..Q2J)1KM7XZ3TU7.@!@!!Q2E1,;:5F%!$^P7X?PI```<``!` +M!.]]GZ8N!-ZJA'M"[-)EI.D0#!MM````'```0`6#+&"B>SC7F#[R$ZLL!+()$DK!Q16R^\\#WL!9-#D:VM*)W#J-V*J[OUI5 +M8'>2$\^S;,]-7'1=^OIR12/55J$)BG"5).,D3^SN`O:)_P&@_,S'!C4'D/`7 +M^"!C//!C!W0[F$&#!P,<:WH2F-A.*0``))G6CCL4JB4:[5^.D]-5SH`8`0<4 +MI43&VE9A01/L%^'\*0``'```0`3O?9^F+@3>JH1[0NS29:3I$`P;;0```!P` +M`$`%@RQ@HGLXUY@^\A.K+',)160P;_&N$K=&WIL,`)@!``"8`0```@```$4` +M`91I*P``0!$``,"H`0'`J`$"`?0!]`&`!V67U\ZYV]-5,@``````````(2`B +M"`````````%X(@``>````'3]`0`,`P``#`$```R`#@"``P``#`$```R`#@$` +M`P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0# +M```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``" +M```8Y^T+LTF6DZ1`,&VT````<``!`!8,L8*)[.->8/O(3JRQS"45D,&_QKQ*W +M1@2H"@"8`0``F`$```(```!%``&4:2T``$`1``#`J`$!P*@!`@'T`?0!@`=E +MMA.+4>O;#7<``````````"$@(@@````````!>"(``'@```!T_@$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``2#S+H;PQ,5/F,(\5'\&?_)B"MT"X1TK( +M92?)&+:!C:/2C,;6*0%`2JGP;V5BO]:8OD!\#X>01H=BP%NA`?_N>7"3@^D^ +MQFC5H*NA[?(V]J6NA&UNST/9!^,M&03!LDN+ZX&@[>@8'CMR7,)5#U$T=4(` +MJA/M/X,RN^09\2&R0_TI```D&V.`&T\ZOL[%UE#E,3V/Z]L_(I^Q??>\C5GA +M-.T\&Y8I```<``!`!","4CV15L9-"3B$9>V7QK"2%X=W````'```0`7[X67E +M=.CF2+W'JEQV4KAWF/"7CJ\2MT9,U`T`F`$``)@!```"````10`!E&DN``!` +M$0``P*@!`<"H`0(!]`'T`8`'9;83BU'KVPUW```````````A("((```````` +M`7@B``!X````=/X!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0`` +M#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```" +M`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``$@\RZ&\ +M,3%3YC"/%1_!G_R8@K=`N$=*R&4GR1BV@8VCTHS&UBD!0$JI\&]E8K_6F+Y` +M?`^'D$:'8L!;H0'_[GEPDX/I/L9HU:"KH>WR-O:EKH1M;L]#V0?C+1D$P;)+ +MB^N!H.WH&!X['=P```!P``$`%^^%EY73HYDB]QZI<=E*X=YCPEXZP$K=&G],$`)@! +M``"8`0```@```$4``91I+P``0!$``,"H`0'`J`$"`?0!]`&`!V6V$XM1Z]L- +M=P``````````(2`B"`````````%X(@``>````'3^`0`,`P``#`$```R`#@"` +M`P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@" +M```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@`` +M``@$```.*```B``"``!(/,NAO#$Q4^8PCQ4?P9_\F(*W0+A'2LAE)\D8MH&- +MH]*,QM8I`4!*J?!O96*_UIB^0'P/AY!&AV+`6Z$!_^YY<).#Z3[&:-6@JZ'M +M\C;VI:Z$;6[/0]D'XRT9!,&R2XOK@:#MZ!@>.W)$T[3P;EBD` +M`!P``$`$(P)2/9%6QDT).(1E[9?&L)(7AW<````<``!`!?OA9>5TZ.9(O<>J +M7'92N'>8\)>.L1*W1N+?`@"8`0``F`$```(```!%``&4:3```$`1``#`J`$! +MP*@!`@'T`?0!@`=E1N"(``'@` +M``!T_P$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``KJK2PQ2='ZN!:7$: +MNXQ,1I85373?S+>"_)Q66V?%GCXRZJA$LD3,2`MCT&-ZU>.8/5Z +MV)J`Y030`1XIN/AAD43.V.VUHU:'#)";\M@I```DL0Q=G.)&EZ5-&FJ=V0J= +MGD/)<_E\B$`S[X[6(9!L*MDI```<``!`!%XFY<;R^2$(3:M)6R!#JKC\5MR= +M````'```0`53*T90/$-GNC'78:IAPK'TD(C49K$2MT84#`8`F`$``)@!```" +M````10`!E&DQ``!`$0``P*@!`<"H`0(!]`'T`8`'94;G+FN-L$YO```````` +M```A("((`````````7@B``!X````=/\!``P#```,`0``#(`.`(`#```,`0`` +M#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```( +M`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH +M``"(``(``*ZJTL,4G1^K@6EQ&KN,3$:6%4UTW\RW@OR<5G-QH"NWZ< +MB6,`@T#F`V;)86:C_`?42VXXPK3[,62^E3@';"B)$J,(P7[/DODMX7EMGQ9X +M^,NJH1+)$S$@+8]!C>M7CF#U>MB:@.4$T`$>*;CX89%$SMCMM:-6APR0F_+8 +M*0``)+$,79SB1I>E31IJG=D*G9Y#R7/Y?(A`,^^.UB&0;"K9*0``'```0`1> +M)N7&\ODA"$VK25L@0ZJX_%;````'3_`0`, +M`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,# +M```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,` +M``4#```(!````@````@$```.*```B``"``"NJM+#%)T?JX%I<1J[C$Q&EA5- +M=-_,MX+\G%9S<:`KM^G'.*"OWHEC`(-`Y@-FR6%FH_P'U$MN.,*T^S%DOI4X +M!VPHB1*C",%^SY+Y+>%Y;9\6>/C+JJ$2R1,Q("V/08WK5XY@]7K8FH#E!-`! +M'BFX^&&11,[8[;6C5H<,D)ORV"D``"2Q#%V0\ES^7R( +M0#/OCM8AD&PJV2D``!P``$`$7B;EQO+Y(0A-JTE;($.JN/Q6W)T````<``!` +M!5,K1E`\0V>Z,==AJF'"L?20B-1FLA*W1IA="@"8`0``F`$```(```!%``&4 +M:3<``$`1``#`J`$!P*@!`@'T`?0!@`=E>`2M9JJ24/\``````````"$@(@@` +M```````!>"(``'@```!T``$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M0#L>L.*]XQ+T[&4W*./`ROL7X-1JXP"DP)\\\?,/2MQ'@Y\K@HI.E6B6%(!\ +M(Q!Z)?>:0*^0U/C)@5'<2G&GUC%NZC&2VGP7,:!<;2=W[-AEB>V4\U4DA6/1 +MCK$?RE7RN9@D*M\@DI8+)H2NN!M'?J)2\>L?D"BGW\A=H/,2].QE-RCCP,K[%^#4:N,`I,"? +M//'S#TK<1X.?*X**3I5HEA2`?",0>B7WFD"OD-3XR8%1W$IQI]8Q;NHQDMI\ +M%S&@7&TG=^S898GME/-5)(5CT8ZQ'\I5\KF8)"K?()*6"R:$KK@;1WZB4O'K +M'Y`HI]_(7:#W-E?%*0``)#R2ARXB':G\^R9/C!!^"1-[LK#HM54]>_NS$K=&?(4$`)@!``"8`0```@```$4``91I00``0!$` +M`,"H`0'`J`$"`?0!]`&`!V5X!*UFJI)0_P``````````(2`B"`````````%X +M(@``>````'0``0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R` +M#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,` +M``@#```!`P``"`,```4#```(!````@````@$```.*```B``"``!`.QZPXKWC +M$O3L93#GRN"BDZ5:)84@'PC$'HE]YI` +MKY#4^,F!4=Q*<:?6,6[J,9+:?![*PZ+55/7OW+_J&CKHE:2D``!P``$`$@J$/8-E\7RC[?L9\''[H +MU3%IO68````<``!`!;7SXE.=B(S?]@A,3C,M"#=-N3GKM!*W1I22`@"8`0`` +MF`$```(```!%``&4:4D``$`1``#`J`$!P*@!`@'T`?0!@`=EL[45*532?]P` +M`````````"$@(@@````````!>"(``'@```!T`@$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``;9RH\C??@04IW3V5:#GZGXCF2B]&%[$ZRK3=VWK8?X&HM"4OGD?.]$,B0YS%6%^O4YIWV,A5HXN9LCF4*5_. +M@VY*DTSX2NEPQ]\NQR1-_6:3C]:&,LX[ANZNL>3%:FU7G+`H:NNCYGW5X0K1 +M3CJ_K*DI```DIX-H+5OQ#&/.Z,HX7W<'%>_<-E$XJAFNJ%PK5U-0=W,I```< +M``!`!.-N0B0<\3->7I+7<\H+H*/`R)[)````'```0`4S?7U]\I(^6Y/,SA#A +M@N&M)TW#DK02MT;KO04`F`$``)@!```"````10`!E&E+``!`$0``P*@!`<"H +M`0(!]`'T`8`'9;.U%2E4TG_<```````````A("((`````````7@B``!X```` +M=`(!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```( +M`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$# +M```(`P``!0,```@$```"````"`0```XH``"(``(``&VQ.LJTW=MZW($*T4XZOZRI*0``)*>#:"U;\0QCSNC*.%]W!Q7O +MW#91.*H9KJA<*U=34'=S*0``'```0`3C;D(D'/$S7EZ2UW/*"Z"CP,B>R0`` +M`!P``$`%,WU]??*2/EN3S,X0X8+AK2=-PY*T$K=&:O\+`)@!``"8`0```@`` +M`$4``91I30``0!$``,"H`0'`J`$"`?0!]`&`!V6SM14I5-)_W``````````` +M(2`B"`````````%X(@``>````'0"`0`,`P``#`$```R`#@"``P``#`$```R` +M#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(` +M``0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*``` +MB``"``!MG*CR-]^!!2G=/95H.?J?B.9*+T87L3K*M-W;>MR'#[P#:TPQ:X!V +M[/97YYA_@:BT)2^>1\[T0R)#G,587Z]3FG?8R%6CBYFR.90I7\Z#;DJ33/A* +MZ7#'WR[')$W]9I./UH8RSCN&[JZQY,5J;5>DM=SR@N@H\#(GLD````<``!`!3-]?7WRDCY;D\S.$.&"X:TG3<.2 +MM1*W1DX/"@"8`0``F`$```(```!%``&4:5D``$`1``#`J`$!P*@!`@'T`?0! +M@`=E[M`0Q#RKL6@``````````"$@(@@````````!>"(``'@```!T`P$`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``X=$].@0[Y9EN6NC91E70D`,'6"$4 +MR\?D6WZ]`4L!4+4T4H"I6KU8"W;K=6:E9.":B8XXYK6A%>T,N2WI +M,F(\>\WM60X3>U<:AK8%X_.!6W*IG%"2]=/#^K]6%[A:O%E9_N:9KY3M:S_Y +M-T6GI4?X7>RCD\F+VY8Q/3$I```D.C?:A_B"YKJ@R%>(N30K2P^L4BE-)YB*R.?````'```0`63 +M-DT!6\V@O',O=NJ^WD`':0-VA;42MT;R-PT`F`$``)@!```"````10`!E&E< +M``!`$0``P*@!`<"H`0(!]`'T`8`'9>[0$,0\J[%H```````````A("((```` +M`````7@B``!X````=`,!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```, +M`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@# +M```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``.'1 +M/3H$.^69;EKHV495T)`#!U@A%,O'Y%M^O0%+`5"U'.F_&YN7M%*`J5J]6`MV +MZW5FI63@FHF...:UH17M#+DMZ3)B/'O-[5D.$WM7&H:V!>/S@5MRJ9Q0DO73 +MP_J_5A>X6KQ96?[FF:^4[6L_^3=%IZ5'^%WLHY/)B]N6,3TQ*0``)#HWVH?X +M@N:ZH,A7B+DT*TL/G*`7`M0.]4P%7"C(H=90*0``'```0`0K;;MZUY3.`I&' +M7K%(I32>8BLCGP```!P``$`%DS9-`5O-H+QS+W;JOMY`!VD#=H6V$K=&4C<$ +M`)@!``"8`0```@```$4``91I8P``0!$``,"H`0'`J`$"`?0!]`&`!V7NT!#$ +M/*NQ:```````````(2`B"`````````%X(@``>````'0#`0`,`P``#`$```R` +M#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,` +M``@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!``` +M`@````@$```.*```B``"``#AT3TZ!#OEF6Y:Z-E&5="0`P=8(13+Q^1;?KT! +M2P%0M1SIOQN;E[12@*E:O5@+=NMU9J5DX)J)CCCFM:$5[0RY+>DR8CQ[S>U9 +M#A-[5QJ&M@7C\X%;E1_A= +M[*.3R8O;EC$],2D``"0Z-]J'^(+FNJ#(5XBY-"M+#YR@%P+4#O5,!5PHR*'6 +M4"D``!P``$`$*VV[>M>4S@*1AUZQ2*4TGF(K(Y\````<``!`!9,V30%;S:"\ +M0`=I`W:%MQ*W1KM#`@"8`0``F`$```(```!%``&4:64``$`1``#` +MJ`$!P*@!`@'T`?0!@`=E[SV!8AW#15P``````````"$@(@@````````!>"(` +M`'@```!T!`$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``\V%L*H')3QEW +M*ORK?@HV`H%X0`"29W!@%ZLT&2UU=*;-[F#T"XL*PV8?7`[1\_PU8#I?X[DW +MK`(0B>JC.=<0R("0Q[0@TI,65X!NT?;W!9G?#'#)M"C[K&K2G=NZ;TU#`9,W +M0?:WW?OA:J3-@%+/KC*=C.WJ)N_2-TE(BO(\1.@I```D=!']P&H[FDDXP*K* +MV,"F\0/PE/$7J2XRS\'EX/`TKW\I```<``!`!&4QDI8_*2KP[I%N95(7(LO) +MFO8T````'```0`7IE/"5?@S\(M1SH]3H"K9;+_#JEK<2MT:N;P4`F`$``)@! +M```"````10`!E&EF``!`$0``P*@!`<"H`0(!]`'T`8`'9>\]@6(=PT5<```` +M```````A("((`````````7@B``!X````=`0!``P#```,`0``#(`.`(`#```, +M`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$# +M```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0` +M``XH``"(``(``/-A;"J!R4\9=RK\JWX*-@*!>$``DF=P8!>K-!DM=72FS>Y@ +M]`N+"L-F'UP.T?/\-6`Z7^.Y-ZP"$(GJHSG7$,B`D,>T(-*3%E>`;M'V]P69 +MWPQPR;0H^ZQJTIW;NF]-0P&3-T'VM]W[X6JDS8!2SZXRG8SMZB;OTC=)2(KR +M/$3H*0``)'01_#P-*]_*0``'``` +M0`1E,9*6/RDJ\.Z1;F52%R++R9KV-````!P``$`%Z93PE7X,_"+4````'0$ +M`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$` +M``,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P`` +M"`,```4#```(!````@````@$```.*```B``"``#S86PJ@L`A")ZJ,Y +MUQ#(@)#'M"#2DQ97@&[1]O<%F=\,<,FT*/NL:M*=V[IO34,!DS=!]K?=^^%J +MI,V`4L^N,IV,[>HF[](W24B*\CQ$Z"D``"1T$?W`:CN:23C`JLK8P*;Q`_"4 +M\1>I+C+/P>7@\#2O?RD``!P``$`$93&2EC\I*O#ND6YE4AF4\)5^#/PBU'.CU.@*MELO\.J6N!*W1A6]"0"8`0``F`$```(```!% +M``&4:6H``$`1``#`J`$!P*@!`@'T`?0!@`=E.O/5@#`=3!4``````````"$@ +M(@@````````!>"(``'@```!T!0$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``C-)FKD)JN_P&+WEKRA5X-&E6_%Q8HS&1U\=O1<:)[KXS53),2(6_(/'2B\%0-ZA]>/B#7KJ,4I```<``!`!)XJZQ&2 +MJ6=3F"CX4V3GR[.=/`)#````'```0`6+38!R7=;,[,!"8N<#HR>FY11'];@2 +MMT:HZ0P`F`$``)@!```"````10`!E&EK``!`$0``P*@!`<"H`0(!]`'T`8`' +M93KSU8`P'4P5```````````A("((`````````7@B``!X````=`4!``P#```, +M`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@" +M```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,` +M``@$```"````"`0```XH``"(``(``(S29JY":KO\!B]Y:\H5>#1G)C1&^I6W +M+.O:&96B0@7Z1>\,415ZWT*=VHAXI`IQ<^/E!BLHP#R+3WR.@J7_HP%I#8C: +MF@93CQACKAWI5OQ<6*,QG+(Z^,U4R3$B%OR#QTHO!4#>H?7 +MCX@UZZC%*0``'```0`2>*NL1DJEG4Y@H^%-DY\NSG3P"0P```!P``$`%BTV` +M````'0%`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$` +M``R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P`` +M`@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``",TF:N +M0FJ[_`8O>6O*%7@T9R8T1OJ5MRSKVAF5HD(%^D7O#%$5>M]"G=J(>*0*<7/C +MY08K*,`\BT]\CH*E_Z,!:0V(VIH&4X\88ZX=Z5;\7%BC,9RR'.HLMNP3?S>\ +MP+T6C-;6^RY!!"40XVMSR,/#P$[@7/AAD,EK5PEA&R$N9BD``"1Y'7QV]%QH +MGNOC-5,DQ(A;\@\=*+P5`WJ'UX^(->NHQ2D``!P``$`$GBKK$9*I9U.8*/A3 +M9.?+LYT\`D,````<``!`!8M-@')=ULSLP$)BYP.C)Z;E%$?UNA*W1G[W`0"8 +M`0``F`$```(```!%``&4:6X``$`1``#`J`$!P*@!`@'T`?0!@`=E&[])+1EZ +MI:X``````````"$@(@@````````!>"(``'@```!T"`$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``54E\0:%A.;M6RER2*0FPH,7+!L@Z'37>"````'```0`5S//[M9'YV&!0L +MH"^[;G;^'#(#%KH2MT:=(04`F`$``)@!```"````10`!E&EQ``!`$0``P*@! +M`<"H`0(!]`'T`8`'91N_22T9>J6N```````````A("((`````````7@B``!X +M````=`@!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`# +M```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,` +M``$#```(`P``!0,```@$```"````"`0```XH``"(``(``%5)?$&A83F[5LI7 +M,DD6,&SO%/<9K%3^IU!9N>T9X&Y7R,\(2PNA!Y[`-!I59N<[9*0``)`_*0TV-_J/V"8.Z^6#6 +M-O6A'\0FX:M+P-.#+U@2CE;Y*0``'```0`3&NEUZ-'LDBD)L*#%RP;(.ATUW +M@@```!P``$`%````'0(`0`,`P``#`$```R`#@"``P``#`$` +M``R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P`` +M"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```. +M*```B``"``!527Q!H6$YNU;*5S))%C!L[Q3W&:Q4_J7,^C.T@A?`;HX"U"1; +M:YS/K'M06;GM'*BA0++HCNAU#L!A/!N5\C/"$L+H0>>P#0:56;G. +MV2D``"0/RD--C?ZC]@F#NOE@UC;UH1_$)N&K2\#3@R]8$HY6^2D``!P``$`$ +MQKI=>C1[)(I";"@QX``````````"$@(@@````````!>"(``'@```!T"0$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``\RP=>[Q>7OSPK_U#U/^TW^?3 +M"-.TRD.A\RBA@;\@Z,C'O,*FGB;(Z*T-?RSG7*^[Q="R4"=1\EB@"$WN9+"' +MR*X39*JRRBGSKE!<]3V>+L2MT:%FPP`F`$``)@!```"````10`! +ME&E\``!`$0``P*@!`<"H`0(!]`'T`8`'959$9@,X>.WN```````````A("(( +M`````````7@B``!X````=`D!``P#```,`0``#(`.`(`#```,`0``#(`.`0`# +M```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,` +M``@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(` +M`/,L'7N\7E[\\*_]0]3_M-_GTPC3M,I#H?,HH8&_(.C(Q[S"IIXFR.BM#7\L +MYURON\70LE`G4?)8H`A-[F2PA\BN$V2JLLHI\W.">OG]9.#-3=MT#%CA6=IF5]$.N%8+3Q@-_V5V6\+BI/%31_FD]DQ_V-B!N:T]:N^7*0``)&6U +M*)3+?>6*%919\%FY@B@&3R2S(U4@4U7#W"XA/1&M*0``'```0`33KLQ8G$#B +MVN_S5EUW7XQK"8I]G````!P``$`%.#(G02!6$%RXO.:'*WJY07/4]GB\$K=& +MPYH#`)@!``"8`0```@```$4``91I?@``0!$``,"H`0'`J`$"`?0!]`&`!V56 +M1&8#.'CM[@``````````(2`B"`````````%X(@``>````'0)`0`,`P``#`$` +M``R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@`` +M`@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```( +M!````@````@$```.*```B``"``#S+!U[O%Y>_/"O_4/4_[3?Y],(T[3*0Z'S +M**&!OR#HR,>\PJ:>)LCHK0U_+.=YDL(?(KA-DJK+* +M*?-S@GKY_63@S4W;=`W(J5\BC'A8X5G:9E?1#KA6"T\8#?]E=EO"XJ3Q4T?Y +MI/9,?]C8@;FM/6KOERD``"1EM2B4RWWEBA646?!9N8(H!D\DLR-5(%-5P]PN +M(3T1K2D``!P``$`$TZ[,6)Q`XMKO\U9==U^,:PF*?9P````<``!`!3@R)T$@ +M5A!"(``'@```!T"@$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``VQ3\!*;/ +MX9,!+9>;E7D!#1D;M#!YX(/?K/()%]1%X*5IJNDUV?((_U[`^S<2>"#WZSR"1?41>"E +M::KI-=GR"/]>P/LW$G*I06[NJ]^1FKZYPZA_TW:_Z%]D,.OSIF-"FOB.J8LK +MJSJ_WP5?Z#?!-]3(VK&$G5[H/-OVRYQ0(N5`_ZW;A)59G=K!RG_)3Y&#VZ_7 +M8O=L6KGX*0``))Y^&;?*>J5H[_2<1$:`2">%E&0B:O4%<)2T1>``` +M`'0*`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P`` +M"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```! +M`P``"`,```4#```(!````@````@$```.*```B``"``#;%/P$IL_ADP$MEYN5 +M>0$-&1NT,'G@@]^L\@D7U$7@I6FJZ379\@C_7L#[-Q)RJ4%N[JO?D9J^N<.H +M?]-VO^A?9##K\Z9C0IKXCJF+*ZLZO]\%7^@WP3?4R-JQA)U>Z#S;]LN<4"+E +M0/^MVX2569W:P?AFWRGJE:._TG$1&@$@G +MA91D(FKU!7"4M$7G.HT/#2D``!P``$`$11D8+D87P+?.,9@_^&<%"67R80`` +M```<``!`!8>I,8HCXO'76I&Z#$\"(&'<:OF3OA*W1F@A"0"8`0``F`$```(` +M``!%``&4:80``$`1``#`J`$!P*@!`@'T`?0!@`=E?*Y1;CYAVQT````````` +M`"$@(@@````````!>"(``'@```!T_P$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``@4YH\)3@A^..U`>V\HLEZ4;`R/V#EFQLGJ.EN;@K"UCEX#B[E'_0 +M)QN\F;<)D3X(PS.Y$(62_1WZX+/W7<,8F!0\YIKX,\`$6%^)THN18'*D3V[] +M"2RZE1]DX'\JF)(+1XKG8(1__5BOVK?(3Q0Z8#!IMJNA)J0):\5QUHJ/"`0I +M```D%[*-[W<\5K6AAK)IPM&>[)R_P!$S?Z.NH-7/B`JT5(\I```<``!`!(P( +M[M1Q3-$-T^8]-*)8\^!$*_+FN+H21<+E&P,C] +M@Y9L;)ZCI;FX*PM8Y>`XNY1_T"<;O)FW"9$^",,SN1"%DOT=^N"S]UW#&)@4 +M/.::^#/`!%A?B=*+D6!RI$]N_0DLNI4?9.!_*IB2"T>*YV"$?_U8K]JWR$\4 +M.F`P:;:KH2:D"6O%<=:*CP@$*0``)!>RC>]W/%:UH8:R:<+1GNR-2P^_$K=&HTP#`)@!``"8`0```@```$4``91I +MBP``0!$``,"H`0'`J`$"`?0!]`&`!V5\KE%N/F';'0``````````(2`B"``` +M``````%X(@``>````'3_`0`,`P``#`$```R`#@"``P``#`$```R`#@$``P`` +M#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```( +M`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``"! +M3FCPE."'XX[4![;RBR7I1L#(_8.6;&R>HZ6YN"L+6.7@.+N4?]`G&[R9MPF1 +M/@C#,[D0A9+]'?K@L_==PQB8%#SFFO@SP`187XG2BY%@"(``'@```!T@`$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``M+9:6>L'D64E>G+O8LNL^K$[`Q^SHKTI_ +M[(3VIAU)YPL4G0YQ0:OR)!<#5;YS,BH'E(ILRB=XC;A@/%]G\5)Q[\6N?G9( +M]2T"G3T;J49;*9^4&HFNX(0O/%FGATNLY(%AJMHFAK$K_LH5XJT4B`(`FB.< +M;N#9T?=TS>D(NG\I```D1+JV%8.75;&"O=CY,.^?M1]T#R'%JM6\:51:,SQ2 +M/E,I```<``!`!!J3M(E1U=<\G"B/Y!1O%.T6BU#2````'```0`6#$],6*4/: +M6-D-J3GXB`WU\]6L8L`2MT8(A00`F`$``)@!```"````10`!E&F1``!`$0`` +MP*@!`<"H`0(!]`'T`8`'9370JIA>9=[F```````````A("((`````````7@B +M``!X````=(`!``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`. +M`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P`` +M"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``+2V6EGK!Y'+ +M'EE)7IR[V++K/JQ.P,?LZ*]*?^R$]J8=2><+%)T.<4&K\B07`U6^(VX8#Q?9_%2<>_%KGYV2/4M`IT]&ZE&6RF?E!J)KN"$+SQ9IX=+K.2! +M8:K:)H:Q*_[*%>*M%(@"`)HCG&[@V='W=,WI"+I_*0``)$2ZMA6#EU6Q@KW8 +M^3#OG[4?=`\AQ:K5O&E46C,\4CY3*0``'```0`0:D[2)4=77/)PHC^04;Q3M +M%HM0T@```!P``$`%@Q/3%BE#VEC9#:DY^(@-]?/5K&+`$K=&G,8*`)@!``"8 +M`0```@```$4``91IEP``0!$``,"H`0'`J`$"`?0!]`&`!V4UT*J87F7>Y@`` +M````````(2`B"`````````%X(@``>````'2``0`,`P``#`$```R`#@"``P`` +M#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```! +M`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$ +M```.*```B``"``"TMEI9ZP>1RQY925Z4BFS*)WB-N&`\7V?Q4G'OQ:Y^=DCU+0*=/1NI +M1ELIGY0:B:[@A"\\6:>'2ZSD@6&JVB:&L2O^RA7BK12(`@":(YQNX-G1]W3- +MZ0BZ?RD``"1$NK85@Y=5L8*]V/DP[Y^U'W0/(<6JU;QI5%HS/%(^4RD``!P` +M`$`$&I.TB5'5USR<*(_D%&\4[1:+4-(````<``!`!8,3TQ8I0]I8V0VI.?B( +M#?7SU:QBP1*W1G?2"`"8`0``F`$```(```!%``&4:9\``$`1``#`J`$!P*@! +M`@'T`?0!@`=E+P_'*/C"(``'@```!T +M`0``#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``XL$>!,PN/`;L`\)5^(V# +M@A]@N)RLPLE8I`ZL6R6Z?#KG2`X;%]:Y5__I0HOK$=\NSO?`2I[LO +M[:>]LZK+_,.(SA!]5#=F?IKZ:,#%#FY1WLJN)CM0SS/Q +M+YFC*N/Q7_`-L$2MT;N_@L`F`$``)@!```"```` +M10`!E&F@``!`$0``P*@!`<"H`0(!]`'T`8`'92\/QRCXW(YX```````````A +M("((`````````7@B``!X````=`$```P#```,`0``#(`.`(`#```,`0``#(`. +M`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@`` +M!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"( +M``(``.+!'@3,+CP&[`/"5?B-@X(?8+B[+^VGO;.JR_S#B,X0?50W9GZ:^FC`Q0YN4=[* +MKB8[7#R'SQ/94(I`3#K+H6DT2/*0`` +M)!T;P^LAX5IY[C$"`RZWD,\S\2^9HRKC\5_W+]1B^-'R*0``'```0`2SI3```````````(2`B"`````````%X(@``>````'0!```,`P`` +M#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```( +M`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4# +M```(!````@````@$```.*```B``"``#BP1X$S"X\!NP#PE7XC8."'V"XG*S" +MR5BD#JQ9RB13#9[);I\.N=(#AL7UKE7_^E"B^L1WR[.]\!*GNR_MI[VSJLO\ +MPXC.$'U4-V9^FOIHP,4.;E'>RJXF.UP\A\\3V5"*7`%:>>XQ`@,NMY#/,_$OF:,JX_%? +M]R_48OC1\BD``!P``$`$LZ4W(\E`HQ58ZZ(5.B\OPJ?*&48````<``!`!2\$ +M`LI;0,51+:HWV/E0_3ILEX`VPQ*W1H8-`0"8`0``F`$```(```!%``&4:;8` +M`$`1``#`J`$!P*@!`@'T`?0!@`=E\;[69&DX>^P``````````"$@(@@````` +M```!>"(``'@```!T`0(`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``>.M( +M4M+P(4]M\[?N,>^K=M=W?]"R6.-+U$00B&CFRB``R#5$%>_@)]X6?K<^2*QJ +M*KG&&N[E.-I]M:[^B8(Z^"5?[&0-&=0`V*&JD=4\@FRH)^)7UO`\#/:_$1R< +MMWGL6.MJW`OOYZRYS.6>\CLBY_@>/O1\K5#%$Q.6+].0#.4I```DC$W'V8BM +MK8C0&<$GSW$X($NB-YJ0;''Z+XJ0$8Z; +M"!+U6Y=E*]Z*````'```0`7Q$LXFQ@;!&)YSYW>%%C*$*4%-S\,2MT;9-@0` +MF`$``)@!```"````10`!E&FX``!`$0``P*@!`<"H`0(!]`'T`8`'9?&^UF1I +M.'OL```````````A("((`````````7@B``!X````=`$"``P#```,`0``#(`. +M`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P`` +M"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```" +M````"`0```XH``"(``(``'CK2%+2\"%/;?.W[C'OJW;7=W_0LECC2]1$$(AH +MYLH@`,@U1!7OX"?>%GZW/DBL:BJYQAKNY3C:?;6N_HF".O@E7^QD#1G4`-BA +MJI'5/()LJ"?B5];P/`SVOQ$LN:D&QQ^B^*D!&.G,F5 +M*0``'```0`3$"J4!&T@.`ON7FP@2]5N792O>B@```!P``$`%\1+.)L8&P1B> +M<^=WA18RA"E!3<_#$K=&='@*`)@!``"8`0```@```$4``91INP``0!$``,"H +M`0'`J`$"`?0!]`&`!V7QOM9D:3A[[```````````(2`B"`````````%X(@`` +M>````'0!`@`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#` +M`P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@# +M```!`P``"`,```4#```(!````@````@$```.*```B``"``!XZTA2TO`A3VWS +MM^XQ[ZMVUW=_T+)8XTO41!"(:.;*(`#(-405[^`GWA9^MSY(K&HJN<8:[N4X +MVGVUKOZ)@CKX)5_L9`T9U`#8H:J1U3R";*@GXE?6\#P,]K\1')RW>>Q8ZVK< +M"^_GK+G,Y9[R.R+G^!X^]'RM4,43$Y8OTY`,Y2D``"2,3"(``'@```!T`0(`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``])_,`R&-"4'ZLN)$IJ-9SHR(C(M!IK>>_;[RU[K#L/NT;.YS +M0-_/]]%QYF$X+ZB7@)@[P8'BI<#[NA7"6[!#LS0@SN[M`P2US)9571MU59"Q"7S%CN!>1\HUMHN?%"Z-&'AW1M7NJ-]UU +M@>,I```DH1L]"_4&7I.DQNR[D@+<`Y7;S/6$=!S..X_]3P!(#`TI```<``!` +M!"&3D+170X(\=0*"P0\X;?X$8GJ%````'```0`5[?6=`0,NV&D":E*<<0R0) +MJ7)-<,02MT:QL`L`F`$``)@!```"````10`!E&G>``!`$0``P*@!`<"H`0(! +M]`'T`8`'9>*`?`P>U34R```````````A("((`````````7@B``!X````=`$" +M``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0`` +M`P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```( +M`P``!0,```@$```"````"`0```XH``"(``(``/2?S`,AC0E!^K+B1*:C6ZP[#[M&SN9A."^HEX"8.\&!XJ7`^[H5PENP +M0[,T(,[N[0,$MWUG0$#+MAI`FI2G'$,D":ER37#%$K=&%K`"`)@!``"8`0```@```$4` +M`91IWP``0!$``,"H`0'`J`$"`?0!]`&`!V7B@'P,'M4U,@``````````(2`B +M"`````````%X(@``>````'0!`@`,`P``#`$```R`#@"``P``#`$```R`#@$` +M`P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0# +M```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``" +M``#TG\P#(8T)0?JRXD2FHUG.C(B,BT&FMY[]OO+7NL.P^[1L[G-`W\_WT7'F +M83@OJ)>`F#O!@>*EP/NZ%<);L$.S-"#.[NT#!+7,EES5F5>L3'>XDZ%K,ORT +M&.?S?Z(]Y5=&W55D+$)?,6.X%Y'RC6VBY\4+HT8>'=&U>ZHWW76!XRD``"2A +M&ST+]09>DZ3&[+N2`MP#E=O,]81T',X[C_U/`$@,#2D``!P``$`$(9.0M%=# +M@CQU`H+!#SAM_@1B>H4````<``!`!7M]9T!`R[8:0)J4IQQ#)`FI```$`1``#`J`$!P*@!`@'T`?0!@`=E +MRQ0'?GB@7NT``````````"$@(@@````````!>"(``'@```!T`0,`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``BIWYT6BP4+H7D3>=6T)/ZG"W\M][BS`) +MF]98E]A7E971#2]M!7G@TYK-]2;IVERG]>AA5/01FHFF?B]QL,"A%\ICF]C[ +MN.^^%8,Q*O-D-K0JRIH'(./M0!X1%4]'&NO+#XL797\F?'TLF($T>&&B<\"5 +MQ@,\3<+Y%!Z3'8IU`_PI```D0/2%9L9[5M^MQ1'!F3ZOO&!/E+]7U=/(2XG< +M4Q?K@3TI```<``!`!),-2R/F?ZI08&&8B>ZHX4K4:'I%````'```0`5E"*MV +M-ZCQ<40RJ1W"+1J7"SD:3,82MT:&Z`,`F`$``)@!```"````10`!E&GA``!` +M$0``P*@!`<"H`0(!]`'T`8`'9XLP"9O66)?85Y65T0TO;05YX-.:S?4FZ=I$15/1QKK +MRP^+%V5_)GQ]+)B!-'AAHG/`E<8#/$W"^10>DQV*=0/\*0``)$#TA6;&>U;? +MK<41P9D^K[Q@3Y2_5]73R$N)W%,7ZX$]*0``'```0`23#4LCYG^J4&!AF(GN +MJ.%*U&AZ10```!P``$`%90BK=C>H\7%$,JD=PBT:EPLY&DS&$K=&9BH*`)@! +M``"8`0```@```$4``91IZ0``0!$``,"H`0'`J`$"`?0!]`&`!V7+%`=^>*!> +M[0``````````(2`B"`````````%X(@``>````'0!`P`,`P``#`$```R`#@"` +M`P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@" +M```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@`` +M``@$```.*```B``"``"*G?G1:+!0NA>1-YU;0D_J<+?RWWN+,`F;UEB7V%>5 +ME=$-+VT%>>#3FLWU)NG:7*?UZ&%4]!&:B:9^+W&PP*$7RF.;V/NX[[X5@S$J +M\V0VM"K*F@<@X^U`'A$53T<:Z\L/BQ=E?R9\?2R8@31X8:)SP)7&`SQ-POD4 +M'I,=BG4#_"D``"1`](5FQGM6WZW%$<&9/J^\8$^4OU?5T\A+B=Q3%^N!/2D` +M`!P``$`$DPU+(^9_JE!@89B)[JCA2M1H>D4````<``!`!64(JW8WJ/%Q1#*I +M'<(M&I<+.1I,QQ*W1CLX"`"8`0``F`$```(```!%``&4:?L``$`1``#`J`$! +MP*@!`@'T`?0!@`=EK'3)=VO+\^T``````````"$@(@@````````!>"(``'@` +M``!T`00`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``C%`^1@J_ZVP<%/V>?W[9%9[E +ME>F*?+EB($ZC\]JRRA)QR#7D4/E=D76K$<8I```D^0I5\O.$\<2/NGHG!7;T +M.L]C9;NW_4$K]UF+:V,'JE\I```<``!`!"G/2)>MZ,)G-P^NTS[]^\\803*/ +M````'```0`74K3ZE60V;+(R=.!;M$:]TY473VCD?*K=BH/R"D#, +M#O*O)_"'QO2)GA3]GG]^V16>Y97IBGRY8B!.H_/:LLH2<<@UY%#Y79%UJQ'& +M*0``)/D*5?+SA/'$C[IZ)P5V]#K/8V6[M_U!*_=9BVMC!ZI?*0``'```0`0I +MSTB7K>C"9S,(3I0!2;9*AK +M4S+($K=&_&$"`)@!``"8`0```@```$4``91J#```0!$``,"H`0'`J`$"`?0! +M]`&`!V6L=,EW:\OS[0``````````(2`B"`````````%X(@``>````'0!!``, +M`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,# +M```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,` +M``4#```(!````@````@$```.*```B``"``",4#Y&"K_K;!QR,,`%2?NYVX") +M#EQ><,/3?U5>K;122E#[**N&10^5V1=:L1QBD``"3Y"E7R\X3QQ(^Z>B<%=O0ZSV-EN[?] +M02OW68MK8P>J7RD``!P``$`$*<](EZWHPF"CBV\``````````"$@(@@` +M```````!>"(``'@```!T`0<`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MCL])JCCR%LV78.Y<'V:I8CT,,H\@`*[U3;S)VD$&FPE:0U/[W;;.SC$7\I```<``!`!$;.[4;O((B> +M\D2MT9Q +MF@,`F`$``)@!```"````10`!E&J8``!`$0``P*@!`<"H`0(!]`'T`8`'93V: +MI:W@HXMO```````````A("((`````````7@B``!X````=`$'``P#```,`0`` +M#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```" +M`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$ +M```"````"`0```XH``"(``(``([/2:HX\A;-EV#N7!]FJ6(]##*/(`"N]4V\ +MR=I!!IL)6D-3^W,8[!_RYJ=D4,+E;S'U1!K=^)'?;5@P.4P-(6J4J9;E.K\7 +M^H8.EC<0XD&.Y$-4`G;D!\G7`_(X[1/66EC;84GMVVSL +MXQ%_*0``'```0`1&SNU&[R"(GG+>C\?(IQQZ0:LHT````!P``$`%@UP*````'0!!P`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R` +M#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,` +M``@#```!`P``"`,```4#```(!````@````@$```.*```B``"``".STFJ./(6 +MS9=@[EP?9JEB/0PRCR``KO5-O,G:00:;"5I#4_MS&.P?\N:G9%#"Y6\Q]40: +MW?B1WVU8,#E,#2%JE*F6Y3J_%_J&#I8W$.)!CN1#5`)VY`?)UP/R..T3UEI7 +M+)OG)HBI(`(G\\]22'S"]/_1`/WRDEQ^*D&K*-`````<``!`!8-<"G)0YSDJ)[RA*W1FKI!P"8`0`` +MF`$```(```!%``&4:JT``$`1``#`J`$!P*@!`@'T`?0!@`=E#=D/M0^P`<$` +M`````````"$@(@@````````!>"(``'@```!T`0@`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``G;0HYEJ@HL%]!W7<]LG$_4%=U7@12$C:/6B"NE.MS$B0BZ.]M`!_^G-X3#< +M%,35LXL_$<^@)?#<`=````'```0`6X]P"T'DAYKU,#A5-" +MOVI!?:F:;,H2MT9M%`L`F`$``)@!```"````10`!E&JR``!`$0``P*@!`<"H +M`0(!]`'T`8`'90W9#[4/L`'!```````````A("((`````````7@B``!X```` +M=`$(``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```( +M`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$# +M```(`P``!0,```@$```"````"`0```XH``"(``(``)VT*.9:H*+!?0=UW/;' +M+%6M_;KY6<*+ML1<*'2=_2-5$W-S)0XY04-I6W<]-V5WIQ/U!7=5X$4A(VCU +MH@KI3K$PW'*2D,.>\016P4+?ZBRF@5S],:9/MU!"9/(P +MTY&GW-Q1JL:5K6DY33I&LX&2PO2;`6#]*0``)&SSD"(->QXN:4%ZMP+VM/_5 +M'#><5LOY3=.7"KG=<)DS*0``'```0`22LE]JRD7A3$U;.+/Q'/H"7PW`'0`` +M`!P``$`%N/<`M!Y(>:]3`X530K]J07VIFFS+$K=&R!,"`)@!``"8`0```@`` +M`$4``91JQP``0!$``,"H`0'`J`$"`?0!]`&`!V4-V0^U#[`!P0`````````` +M(2`B"`````````%X(@``>````'0!"``,`P``#`$```R`#@"``P``#`$```R` +M#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(` +M``0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*``` +MB``"``"=M"CF6J"BP7T'==SVQRQ5K?VZ^5G"B[;$7"ATG?TC51-S!%(2-H]:(*Z4ZW,2)"+H[VT`'_Z+FE!>K<"]K3_U1PWG%;+^4W3EPJYW7"9,RD``!P``$`$DK)? +M:LI%X4Q-6SBS\1SZ`E\-P!T````<``!`!;CW`+0>2'FO4P.%4T*_:D%]J9IL +MS!*W1L8?``"8`0``F`$```(```!%``&4:L\``$`1``#`J`$!P*@!`@'T`?0! +M@`=EQ8N5_6W+.T@``````````"$@(@@````````!>"(``'@```!T`0D`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``T*4-7Z9:1#`#SRLZ0QI)EKIUE&)] +M*#6E]LLJHYK]8'-=172W%52X991;%Y2PAF(J3.%MS:!4J9ODK+JC2T9>`\]0 +M?\L?$DF20_[73Y_S2U3WW:9-Q@(D@E[]O>K!7PR">I&_$GU/%W>3J5;3=^?@G&,KOSIIC@P%*/9 +M^,#A_I9HSI\I```<``!`!".6S]?4.6#=T[>OAM$UO#0E7,7;````'```0`6@ +MEK)O"65'?!EIMJ.M(?QVN)N0B,P2MT8?3`,`F`$``)@!```"````10`!E&K0 +M``!`$0``P*@!`<"H`0(!]`'T`8`'9<6+E?UMRSM(```````````A("((```` +M`````7@B``!X````=`$)``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```, +M`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@# +M```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``-"E +M#5^F6D0P`\\K.D,:29:Z=91B?2@UI?;+*J.:_6!S745TMQ54N&646Q>4L(9B +M*DSA;_;WJ +MP5\,@GJ1OQ)]3Q=WDZE6TW?G(FLBU))*-!BR'Y%%2'UF/0>8*0``)*PZ/?B. +M&6W*I)1'GX)QC*[\Z:8X,!2CV?C`X?Z6:,Z?*0``'```0`0CEL_7U#E@W=.W +MKX;1-;PT)5S%VP```!P``$`%H):R;PEE1WP9:;:CK2'\=KB;D(C,$K=&M(T) +M`)@!``"8`0```@```$4``91JT0``0!$``,"H`0'`J`$"`?0!]`&`!V7%BY7] +M;````'0!"0`,`P``#`$```R` +M#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,` +M``@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!``` +M`@````@$```.*```B``"``#0I0U?IEI$,`//*SI#&DF6NG648GTH-:7VRRJC +MFOU@"(` +M`'@```!T`?@`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``7Y5J]G(G<216 +M+JMD;L^N&DN7W=7DVW,',P$OF\_<$B5W*95.O.2]R%LD.#UTN,,]/EN\X-E. +M)N_M\H;2[/V&8Z$`H+=\+PF65D_.WF07+1_2]$7]`<3Z\1+`+WL +M>!SKE3)?AP[R5`?YTPXD?\0ZV!4I```<``!`!$;AFJW3>E,!3*30&JO%L`/< +M'5IQ````'```0`49=\]QAGT1,D/AY@;N+5^(VF:\$\T2MT8+Q@H`F`$``)@! +M```"````10`!E&K4``!`$0``P*@!`<"H`0(!]`'T`8`'98&[BU? +MB-IFO!/.$K=&9\4!`)@!``"8`0```@```$4``91JU0``0!$``,"H`0'`J`$" +M`?0!]`&`!V7)^R6(L<+>&@``````````(2`B"`````````%X(@``>````'0! +M^``,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$` +M``,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P`` +M"`,```4#```(!````@````@$```.*```B``"``!?E6KV3;9!Q214PG6(+'?BFY4D]^4OP_QKRD``"1[T1?T!Q/KQ$L`O>QX'.N5,E^' +M#O)4!_G3#B1_Q#K8%2D``!P``$`$1N&:K=-Z4P%,I-`:J\6P`]P=6G$````< +M``!`!1EWSW&&?1$R0^'F!NXM7XC:9KP3SA*W1O80#P"8`0``F`$```(```!% +M``&4:M\``$`1``#`J`$!P*@!`@'T`?0!@`=E?%A-J>%;].X``````````"$@ +M(@@````````!>"(``'@```!T`?D`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``X>A1]L_[`NHDC0"',:"\/YCRZJ(A:4`#6=/(:*64"VM[U#]K-'+\*@F\ +M[$(=,CES1;B!-L7@/GM2SP40.M+(D'92])?^M@")>I3"8(OPZ\\2 +MMT8$_@(`F`$``)@!```"````10`!E&KB``!`$0``P*@!`<"H`0(!]`'T`8`' +M97Q83:GA6_3N```````````A("((`````````7@B``!X````=`'Y``P#```, +M`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@" +M```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,` +M``@$```"````"`0```XH``"(``(``.'H4?;/^P+J)(T`AS&@O#^8\NJB(6E` +M`UG3R&BEE`MK>]0_:S1R_"H)O.Q"'3(Y+=*,7?:$SZ?4F/19$P4B>:3I1<5EG(1%:3HH!8QW(CHY3 +M<2@U*DQM*0``'```0`0(#QP".*%J_+$V4U48_KIX;3X"L0```!P``$`%%Z````'0!^0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$` +M``R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P`` +M`@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``#AZ%'V +MS_L"ZB2-`(`^>U+/!1`ZTLB0=E+TES/C6D&FHA9P\YO3;1B1O7^&T^`K$````<``!`!1>G+L.O??:1Y_ZV`(EZE,)@B_#KT!*W1A=/!P"8 +M`0``F`$```(```!%``&4:NP``$`1``#`J`$!P*@!`@'T`?0!@`=E(F@!'`_# +M*F$``````````"$@(@@````````!>"(``'@```!T`?H`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``J="O5V_6K0<-5=/E>2T-#S\K@C/OFWTQDX>DAEVSAD;X +M60!E`0U&,10I```D=Q,39+J.M_2K\#GCRCK'H.*%4N5LU:VYFD([H+%;N$\I +M```<``!`!,"&7\M!P8CQ(E*Z'8T(%\]W@2&(````'```0`7XY#8BIK%`=+;> +M9+Y]YI'14W54JM`2MT8*>`H`F`$``)@!```"````10`!E&KP``!`$0``P*@! +M`<"H`0(!]`'T`8`'92)H`1P/PRIA```````````A("((`````````7@B``!X +M````=`'Z``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`# +M```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,` +M``$#```(`P``!0,```@$```"````"`0```XH``"(``(``*G0KU=OUJW*#!!: +MB]M'-F$UVZ1OT%=.N;0:1T5-U5*K1$K=&-7````'0!^@`,`P``#`$```R`#@"``P``#`$` +M``R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P`` +M"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```. +M*```B``"``"IT*]7;]:MR@P06HO;1S9A-=ND;]!73KFT'*^Q):1N(07,[P@, +M87!^PX:?43YI!))59=#++)'"LS:CNU*6!%>G/SZ +MYF\??\D0Y54+D]1Y!PU5T^5Y+0T//RN",^^;?3&3AZ2&7;.&1OA9`&4!#48Q +M%"D``"1W$Q-DNHZW]*OP.>/*.L>@XH52Y6S5K;F:0CN@L5NX3RD``!P``$`$ +MP(9?RT'!B/$B4KH=C0@7SW>!(8@````<``!`!?CD-B*FL4!TMMYDOGWFD=%3 +M=52JT1*W1H;$#@"8`0``F`$```(```!%``&4:OH``$`1``#`J`$!P*@!`@'T +M`?0!@`=E"&UXC%V1@H4``````````"$@(@@````````!>"(``'@```!T`?T` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``U63"TF0U?C?G75[2%;UFU*%T +MR4D5J[;4=($X=<%A^[-P%5?=`FHDM/15@6!+0N8-==3[=UB7&`J<$(Q=D8*%```````````A("(( +M`````````7@B``!X````=`']``P#```,`0``#(`.`(`#```,`0``#(`.`0`# +M```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,` +M``@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(` +M`-5DPM)D-7XWYUU>TA6]9M2A=,E)%:NVU'2!.'7!8?NSX*0``)$GY +MK$?35^?MV')N,Z"4NBX>P6"U&I^KROK>52FC1M_:*0``'```0`1Z!.WP4'8F +MY;2ZCS^,BU71R8@6,0```!P``$`%]N!#J3S$1A:BQBM.G2:12?LH@#C2$K=& +M4_$(`)@!``"8`0```@```$4``91K!```0!$``,"H`0'`J`$"`?0!]`&`!V4( +M;7B,79&"A0``````````(2`B"`````````%X(@``>````'0!_0`,`P``#`$` +M``R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@`` +M`@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```( +M!````@````@$```.*```B``"``#59,+29#5^-^==7M(5O6;4H73)216KMM1T +M@3AUP6'[LW`55]T":B2T]%6!8$M"Y@UUU/MUS!U\ZAU"]K[3@3M\%!V)N6TNH\_C(M5T"(``'@```!T`?X`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``U10=<4(J +M9`9VR9E]Y%@WY2\`6#P@$&*H=X-?+,(SZ^&9!RJ:=(T3(\0RP!B$G:;+!P-D +M=D8L**.X-7:N`66+1P>IT1@?*DF+'?W6G?YS>@9+RQ0?R-M2'Z,AH[LK<)-> +M55[\R#111%-I*0D"S.-/HHJ(N!%QLD-Z?_%!WM_(T$,I```D0F6DS=&_X[IK +M,<`(&QCM<@^?U"H,FS#/`@]LN+2A=Z4I```<``!`!,42#RC5AA]BOV*U#RT5 +MM-R_V^Q,````'```0`5&6=U%YC2HD)]1H>OI,WMU6092HM,2MT:L*0H`F`$` +M`)@!```"````10`!E&L+``!`$0``P*@!`<"H`0(!]`'T`8`'9=X'"AL5T>;[ +M```````````A("((`````````7@B``!X````=`'^``P#```,`0``#(`.`(`# +M```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(` +M``$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"```` +M"`0```XH``"(``(``-44'7%"*F0&=LF9?>18-^4O`%@\(!!BJ'>#7RS",^OA +MF0_,@T4413:2D)`LSC3Z**B+@1<;)#>G_Q +M0=[?R-!#*0``)$)EI,W1O^.Z:S'`"!L8[7(/G]0J#)LPSP(/;+BTH7>E*0`` +M'```0`3%$@\HU88?8K]BM0\M%;38TJ)"?4:'K +MZ3-[=5D&4J+4$K=&+"D!`)@!``"8`0```@```$4``91K$@``0!$``,"H`0'` +MJ`$"`?0!]`&`!V7>!PH;%='F^P``````````(2`B"`````````%X(@``>``` +M`'0!_@`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P`` +M"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```! +M`P``"`,```4#```(!````@````@$```.*```B``"``#5%!UQ0BID!G;)F7WD +M6#?E+P!8/"`08JAW@U\LPC/KX9D'*IITC1,CQ#+`&(2=ILL'`V1V1BPHH[@U +M=JX!98M'!ZG1&!\J28L=_=:=_G-Z!DO+%!_(VU(?HR&CNRMPDUY57OS(-%%$ +M4VDI"0+,XT^BBHBX$7&R0WI_\4'>W\C00RD``"1"9:3-T;_CNFLQP`@;&.UR +M#Y_4*@R;,,\"#VRXM*%WI2D``!P``$`$Q1(/*-6&'V*_8K4/+16TW+_;[$P` +M```<``!`!499W47F-*B0GU&AZ^DS>W59!E*BU!*W1G]X#@"8`0``F`$```(` +M``!%``&4:R$``$`1``#`J`$!P*@!`@'T`?0!@`=E"^5U0NT@^=L````````` +M`"$@(@@````````!>"(``'@```!T`?\`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``Y\J!,4HY818[6&CL?;C&TIY1`LBQC.-N.A5K]^+F@BSU%;'6U;U4 +MF,8+#F>?NPC&(:C'1?&+2TZ9Y38PK9ETK4ZI4!ZL=GL[G%50WW'4J=/GS)RN +M(I_N"D&$*'(*:M6A'QR````'```0`4LX2]:N;\K^A=.X\5N<$OP)-(. +M`]42MT:280(`F`$``)@!```"````10`!E&LD``!`$0``P*@!`<"H`0(!]`'T +M`8`'90OE=4+M(/G;```````````A("((`````````7@B``!X````=`'_``P# +M```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,` +M``@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P`` +M!0,```@$```"````"`0```XH``"(``(``.?*@3%*.6$6.UAH['VXQM*>40+( +ML8SC;CH5:_?BYH(L]16QUM6]5)C&"PYGG[L(QB&HQT7QBTM.F>4V,*V9=*U. +MJ5`>K'9[.YQ54-]QU*G3Y\R)];\BV +MVE%<*K,VA+.**0``'```0`0\VPFP-JI````'0!_P`,`P``#`$```R`#@"``P``#`$```R`#@$``P`` +M#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```( +M`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``#G +MRH$Q2CEA%CM8:.Q]N,;2GE$"R+&,XVXZ%6OWXN:"+/45L=;5O528Q@L.9Y^[ +M",8AJ,=%\8M+3IGE-C"MF72M3JE0'JQV>SN<55#?<=2IT^?,G*XBG^X*080H +M<@IJUSIS0-/9VE#J`$JG?_^)NX`2MY:%R+.B[FH0@HB:L.X]32D``"0>Q"7+ +M]\>;([]U4-'R0SUD2*7B?6_(MMI17"JS-H2SBBD``!P``$`$/-L)L#:J7,!9 +MMB@=3ZQ=::5X?'(````<``!`!2SA+UJYOROZ%T[CQ6YP2_`DT@X#UA*W1I:U +M!@"8`0``F`$```(```!%``&4:X\``$`1``#`J`$!P*@!`@'T`?0!@`=EW7=B +M(^@JI#D``````````"$@(@@````````!>"(``'@```!T`0``#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``*.;V$>Z?=JV$<(+0LMI/&IVDX0_7XYW)@RMG?`ML][4L_".5DKT59^RM:,6WW,2/U'T +MO`=N.Q110^,&B-I#4H%,^)##?>!Q,@"+`8Y/T>SC#<-XI```D:T:,EGDG//'2RZI3HP8]=]MN7DW73/(N=!*V3*R! +MU*HI```<``!`!%J(&"1._RN\=AE*%-_>S8CDPO#"````'```0`5NM=U`:>)D +MAIWR@P.ZCV=W=LK*1M82MT:%VPD`F`$``)@!```"````10`!E&N0``!`$0`` +MP*@!`<"H`0(!]`'T`8`'9=UW8B/H*J0Y```````````A("((`````````7@B +M``!X````=`$```P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`. +M`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P`` +M"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``"CF]A'NGW:M +MA'""T++:3QJ=I.$/U^'+!X_Q;&,1!PZB7Q[K`X\>6($BV\GN=R8,K9WP+;/> +MU+/PCE9*]%6?LK6C%M]S$C]1]+P';CL444/C!HC:0U*!3/B0PWW.9/=X`S@I +M-)1WG@<3('-2DH;J-"VL>V,=Z7@BP&.3]'LXPW#>*0``)&M&C)9Y)SSQTLNJ +M4Z,&/7?;;EY-UTSR+G02MDRL@=2J*0``'```0`1:B!@D3O\KO'892A3?WLV( +MY,+PP@```!P``$`%;K7=0&GB9(:=\H,#NH]G=W;*RD;7$K=&P=H``)@!``"8 +M`0```@```$4``91KDP``0!$``,"H`0'`J`$"`?0!]`&`!V7==V(CZ"JD.0`` +M````````(2`B"`````````%X(@``>````'0!```,`P``#`$```R`#@"``P`` +M#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```! +M`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$ +M```.*```B``"```HYO81[I]VK81P@M"RVD\:G:3A#]?ARP>/\6QC$0<.HE\> +MZP./'EB!(MO)[G`,X*324=YX'$R!S4I*&ZC0MK'MC'>EX(L!CD_1[ +M.,-PWBD``"1K1HR6>2<\\=++JE.C!CUWVVY>3==,\BYT$K9,K('4JBD``!P` +M`$`$6H@8)$[_*[QV&4H4W][-B.3"\,(````<``!`!6ZUW4!IXF2&G?*#`[J/ +M9W=VRLI&UQ*W1A0I#@"8`0``F`$```(```!%``&4:Y<``$`1``#`J`$!P*@! +M`@'T`?0!@`=EQJ*Q_AZX"1P``````````"$@(@@````````!>"(``'@```!T +M`0(`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``3C8M;+XK,('Z7]YL.'?Z +M13T+]N1S&3!.PA4K`$0:L)#UF*[G8Q!DEX4>6L(TR+P;&&1<`%UL5^BQQ<_3 +M4L]#OYU@QGK$MBYVU>Y$&M&GBC0^N\8B;@FC:[SKT)RQ,(F-D(784:+AC(MZ +M!K!26]#@2BK42*!1>9M%VP&/^M9:8VLI```D=9V)UN..HN8N`D<```````````A +M("((`````````7@B``!X````=`$"``P#```,`0``#(`.`(`#```,`0``#(`. +M`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@`` +M!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"( +M``(``$XV+6R^*S"!^E_>;#AW^D4]"_;D% +M'EK"-,B\&QAD7`!=;%?HL<7/TU+/0[^=8,9ZQ+8N=M7N1!K1IXHT/KO&(FX) +MHVN\Z]"@:P4EO0X$HJU$B@47F;1=L!C_K66F-K*0`` +M)'6=B=;CCJ+F'+5_ACM%/;*(YXU*=RR71Q5K_3K4UW&H*0``'```0`0V579# +M7YV2&I(-+$LGZZ````'0!`@`,`P`` +M#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```( +M`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4# +M```(!````@````@$```.*```B``"``!.-BULOBLP@?I?WFPX=_I%/0OVY',9 +M,$["%2L`1!JPD/68KN=C$&27A1Y:PC3(O!L89%P`76Q7Z+'%S]-2ST._G6#& +M>L2V+G;5[D0:T:>*-#Z[QB)N":-KO.O0G+$PB8V0A=A1HN&,BWH&L%);T.!* +M*M1(H%%YFT7;`8_ZUEIC:RD``"1UG8G6XXZBYARU?X8[13VRB.>-2G"(``'@```!T`0,`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``E2L5 +MH_X7;0_`SKB;Y6Z*,M"$7K:Z%@LF/+7\5D1D'N45!9,DC0:?T',\`]SBUE4E +MC-[[!F^,/]41P,Z?'%;;::&HZ!#(/54KET'T=6^?5?M-&/'C.B&]7@E=G0>% +M(IA)TVZ_BXOJH_IXCE),67O<78ZEDQOO8KQY%7_B,C!_DJ4I```D%CJ"0R.KYZ]_Z````'```0`6H^P9OC#_5$<#.GQQ6VVFAJ.@0R#U5*Y=! +M]'5OGU7[31CQXSHAO5X)79T'A2*82=-NOXN+ZJ/Z>(Y23%E[W%V.I9,;[V*\ +M>15_XC(P?Y*E*0``)!8W)Q[-9/"X=1[?:Z."C@PUY)(CB,2F_;S9196BC^BS +M*0``'```0`08D"O?^@```!P``$`%J'+KU=````'0!`P`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#` +M`P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@# +M```!`P``"`,```4#```(!````@````@$```.*```B``"``"5*Q6C_A=M#\#. +MN)OE;HHRT(1>MKH6"R8\M?Q61&0>Y14%DR2-!I_0,Z(;U>"5V=!X4BF$G3;K^+ +MB^JC^GB.4DQ9>]Q=CJ63&^]BO'D5?^(R,'^2I2D``"06-R<>S63PN'4>WVNC +M@HX,->22(XC$IOV\V465HH_HLRD``!P``$`$&)`G*.T;DXBU:P=ZH)#(ZOGK +MW_H````<``!`!:ARZ]77)+_0/@P2]`;L^NA9,&9RVA*W1DH$#@"8`0``F`$` +M``(```!%``&4;`,``$`1``#`J`$!P*@!`@'T`?0!@`=E@Y?8-M)OT.H````` +M`````"$@(@@````````!>"(``'@```!T`00`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``_S*C0NBQ0@Q[-8.'KUB=@U`:Y._IO3%C;D!-SZ]CDTYQX.RQ +MT8H7)54]5@+_V_<\9H74TYE2DENROU(L##1\EG$`VK2.3SMV)/I>;FF@!?18 +M]0&)B_4GCZH'-H??LC8)P9!V*OSA+LZNHP4<^JX^]5$X7;$-.0]68=7M+0QB +M^B@I```DV/K="\Q%!88[UYNZZ-"+[QIO[>`+\\68L>Z+KX-O<[@I```<``!` +M!&%)!1)&M88Q/*E*CI)T2$`&!ZZ=````'```0`6/K"M@@L(S6#AZ]8G8-0 +M&N3OZ;TQ8VY`3<^O8Y-.<>#LL=&*%R55/58"_]OW/&:%U-.94I);LK]2+`PT +M?)9Q`-JTCD\[=B3Z7FYIH`7T6/4!B8OU)X^J!S:'W[(V"<&0=BK\X2[.KJ,% +M'/JN/O51.%VQ#3D/5F'5[2T,8OHH*0``)-CZW0O,106&.]>;NNC0B^\:;^W@ +M"_/%F+'NBZ^#;W.X*0``'```0`1A20421K6&,3RI2HZ2=$A`!@>NG0```!P` +M`$`%CZPK8(+"')B.'(=````'0!!``,`P``#`$```R`#@"``P``#`$```R`#@$` +M`P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0# +M```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``" +M``#_,J-"Z+%"#'LU@X>O6)V#4!KD[^F],6-N0$W/KV.33G'@[+'1BA/ +MJ@TM#&+Z*"D``"38 +M^MT+S$4%ACO7F[KHT(OO&F_MX`OSQ9BQ[HNO@V]SN"D``!P``$`$84D%$D:U +MAC$\J4J.DG1(0`8'KIT````<``!`!8^L*V""PAR8CAR'7-&G&9^HO[O5W!*W +M1EL[!@"8`0``F`$```(```!%``&4;!L``$`1``#`J`$!P*@!`@'T`?0!@`=E +MHF7FO05SP9\``````````"$@(@@````````!>"(``'@```!T`04`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``Q1,=0EAHUJ.E6RR0\9\-Q&7GJ;ZM#F'U +M<%S!BMM_*UUY258LR"B(D]>E"+Z`E/&T,OU?&YJY-;G+SYPVAXLI@R60D[CU +MW@XM1P=]Q:K&.)FD<2`D]F`Q[\9VJ@0:7UB\X."8CY@ZH2Y)M32^9BZ)24(V +MQ7_._8Q%IG#Y;3YV<3$I```DPQ;E1CKFAYS2"]_!>P!W8_MM'%)[;^D\U!`; +M\@\+NS@I```<``!`!-M,L9!,Z.DE:04I1@>+V.05:X]C````'```0`4(QK14 +M,%;`T$=:+%G,0][?(3-%^=P2MT8Y9@D`F`$``)@!```"````10`!E&P=``!` +M$0``P*@!`<"H`0(!]`'T`8`'9:)EYKT%<\&?```````````A("((```````` +M`7@B``!X````=`$%``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0`` +M#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```" +M`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``,43'4)8 +M:-:CI5LLD/&?#<1EYZF^K0YA]7!4E6+,@HB)/7I0B^@)3QM#+] +M7QN:N36YR\^<-H>+*8,ED).X]=X.+4<'?<6JQCB9I'$@)/9@,>_&=JH$&E]8 +MO.#@F(^8.J$N2;4TOF8NB4E"-L5_SOV,1:9P^6T^=G$Q*0``),,6Y48ZYH>< +MT@O?P7L`=V/[;1Q2>V_I/-00&_(/"[LX*0``'```0`3;3+&03.CI)6D%*48' +MB]CD%6N/8P```!P``$`%",:T5#!6P-!'6BQ9S$/>WR$S1?G=$K=&CV4``)@! +M``"8`0```@```$4``91L)0``0!$``,"H`0'`J`$"`?0!]`&`!V6B9>:]!7/! +MGP``````````(2`B"`````````%X(@``>````'0!!0`,`P``#`$```R`#@"` +M`P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@" +M```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@`` +M``@$```.*```B``"``#%$QU"6&C6HZ5;+)#QGPW$9>>IOJT.8?5P7,&*VW\K +M77E)5BS(*(B3UZ4(OH"4\;0R_5\;FKDUN#BU'!WW% +MJL8XF:1Q("3V8#'OQG:J!!I?6+S@X)B/F#JA+DFU-+YF+HE)0C;%?\[]C$6F +M"(``'@` +M``!T`0@`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``E3N!&;N5[LS[5B>M(:]NWW+D^&+8 +M=S>&CW&&S,7ACA6@'L7B^GHI```<``!`!&9;@>Z"6`!X3N:4/*G5!QD,1/J] +M````'```0`7;*[38C?V40[-=3\$1!IA=%BU+P-X2MT;TG0$`F`$``)@!```" +M````10`!E&PQ``!`$0``P*@!`<"H`0(!]`'T`8`'97+9_>Y"Z:+7```````` +M```A("((`````````7@B``!X````=`$(``P#```,`0``#(`.`(`#```,`0`` +M#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```( +M`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH +M``"(``(``)4[@1F[E>[,^U7-=](?2QX&$,#AHNS+MC)+`3U+./*!Q\,_EI[X +M[`0-17^M)DEJYH2X:=];QRJD=*"P"[)4^"_=PZ4)%Q/"O_BN%)+S1!]8D.#&I08`""'="D.P!$570OKY&7,,MS`VS`S +M*0``)/E(,7HGK2&O;M]RY/ABV'$[FE#RIU0<9#$3ZO0```!P``$`%VRNTV(W]E$.S74_!$0:8718M +M2\#>$K=&>-\'`)@!``"8`0```@```$4``91L,P``0!$``,"H`0'`J`$"`?0! +M]`&`!V5RV?WN0NFBUP``````````(2`B"`````````%X(@``>````'0!"``, +M`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,# +M```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,` +M``4#```(!````@````@$```.*```B``"``"5.X$9NY7NS/M5S7?2'TL>!A#` +MX:+LR[8R2P$]2SCR@^.P$#45_K29):N:$N&G?6\7)!,LUO(H9P:F\).)#06_8NGO6)#@QJ4&``@ +MAW0I#L`1%5T+Z^1ES#+&.%:`>Q>+Z>BD``!P``$`$9EN![H)8`'A.YI0\J=4'&0Q$^KT````<``!` +M!=LKM-B-_91#LUU/P1$&F%T6+4O`WQ*W1K+N!0"8`0``F`$```(```!%``&4 +M;#L``$`1``#`J`$!P*@!`@'T`?0!@`=E4."=9$OB@K```````````"$@(@@` +M```````!>"(``'@```!T`0D`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M"`M(KG:"C63G7L/Y4U)`]PFP&&],&(S*0058WN\7S=>ZVXC/5D$9:6^PH;RH +M1XWV=%$"+)$7@0--*632J7'`EX-]JJ>4JZ))F%Y=S(8)1[A2X=U"UV-#JO?G +MV/Q!GP>-IFX]ZZTBRGV0/RJU6:1;>5;\JLG?Z;OO&$65V.I!]"\I```DWMO* +M<6-]G11`BR1%X$#32EDTJEQP)>#?:JGE*NB +M29A>7X4N'=0M=C0ZKWY]C\09\'C:9N/>NM(LI]D#\JM5FD6WE6_*K) +MW^F[[QA%E=CJ0?0O*0``)-[;RG%G.$]E&\[>AI$HZ[G?KB(>__O2]0`.1L%L +MT4%@*0``'```0`2LA(`.SD^FP2R..S5FJ.!.@+&T[@```!P``$`%W8MOYX8X +MY+M_!:>KZL$_PAC&TUK@$K=&(A<``)@!``"8`0```@```$4``91L0@``0!$` +M`,"H`0'`J`$"`?0!]`&`!V50X)UD2^*"L```````````(2`B"`````````%X +M(@``>````'0!"0`,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R` +M#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,` +M``@#```!`P``"`,```4#```(!````@````@$```.*```B``"```("TBN=H*- +M9.=>P_E34D#W";`8;TP8C,I!!5C>[Q?-U[K;B,]601EI;["AO*A'C?9T40(L +MD1>!`TTI9-*I<<"7@WVJIY2KHDF87EW,A@E'N%+AW4+78T.J]^?8_$&?!XVF +M;CWKK2+*?9`_*K59I%MY5ORJR=_IN^\81978ZD'T+RD``"3>V\IQ9SA/91O. +MWH:1*.NYWZXB'O_[TO4`#D;!;-%!8"D``!P``$`$K(2`#LY/IL$LCCLU9JC@ +M3H"QM.X````<``!`!=V+;^>&..2[?P6GJ^K!/\(8QM-:X!*W1K9C#0"8`0`` +MF`$```(```!%``&4;%@``$`1``#`J`$!P*@!`@'T`?0!@`=ETKN_O;+(%J,` +M`````````"$@(@@````````!>"(``'@```!T`0H`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``^]`?-B2/!+01:.#'GOQ2VRYFIX!L[PW]H+6&T\.E')@) +M5YOAWK/UJ6(?>X]Y8!-=5 +MESLYL@5$&BX,\@.+.W2JHL6\FY8MLNQJD12K[$W(I+ +M,N>)^(8I```D7<=CF.K%I*0>`>PO8LSP3_H,AHK?:H'45!MA2V=U.U$I```< +M``!`!+CD1RJ1KM%<.%9MOFM8PN.23+(O````'```0`7F\&)T.F6Q#'$H+I^S +M:O+DNFK+@.$2MT;53P$`F`$``)@!```"````10`!E&Q>``!`$0``P*@!`<"H +M`0(!]`'T`8`'9=*[O[VRR!:C```````````A("((`````````7@B``!X```` +M=`$*``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```( +M`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$# +M```(`P``!0,```@$```"````"`0```XH``"(``(``/O0'S8DCP2T$6C@QY[\ +M4MLN9J>`;.\-_:"UAM/#I1R8"5>;X=ZS]:EB'WN/>6'-J_<47G-2:UNN-)W& +MOB(R=B*C`Y32O9W?+HTKG@3759<[.;(%1!HN#/(#BSMTJJ+%O')2CH?)>Z4@ +M#!`O6L7IN6+;+L:I$4J^Q-R*2S+GB?B&*0``)%W'8YCJQ:2D'@'L+V+,\$_Z +M#(:*WVJ!U%0;84MG=3M1*0``'```0`2XY$````'0!"@`,`P``#`$```R`#@"``P``#`$```R` +M#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(` +M``0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*``` +MB``"``#[T!\V)(\$M!%HX,>>_%+;+F:G@&SO#?V@M8;3PZ4L_6I +M8A][CWEAS:OW%%YS4FM;KC2=QKXB,G8BHP.4TKV=WRZ-*YX$UU67.SFR!40: +M+@SR`XL[=*JBQ;QR4HZ'R7NE(`P0+UK%Z;EBVR[&J1%*OL3;P8G0Z9;$,<2@NG[-J\N2Z:LN` +MXA*W1IN=!0"8`0``F`$```(```!%``&4;&X``$`1``#`J`$!P*@!`@'T`?0! +M@`=E6)!'=6H-X_D``````````"$@(@@````````!>"(``'@```!T`?\`#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``A7*SX&)@@>>+7TL@\\P5I/L[\%-3 +MSU'Y!9"!STB7&/*]VWP1GVB@V+WILQQMNU2BW//F\(LJ/PC0ZJ6N,8(+1C7O +M@L`C5_[S@+>&\ZN/V`"_.U9:I.=*E>B((>7\].1A@JF:`2LXF$8B+'ORKJ;2 +MLL4!-8AG7````'```0`4[ +MR$PHR618#PW.;3R;$ZRKU,?VEN(2MT;/R0@`F`$``)@!```"````10`!E&QQ +M``!`$0``P*@!`<"H`0(!]`'T`8`'95B01W5J#>/Y```````````A("((```` +M`````7@B``!X````=`'_``P#```,`0``#(`.`(`#```,`0``#(`.`0`#```, +M`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@# +M```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``(5R +ML^!B8('GBU]+(//,%:3[._!34\]1^060@<](EQCRO=M\$9]HH-B]Z;,<;;M4 +MHMSSYO"+*C\(T.JEKC&""T8U[X+`(U?^\X"WAO.KC]@`OSM66J3G2I7HB"'E +M_/3D88*IF@$K.)A&(BQ[\JZFTK+%`36(9W,!'`_118\&&.!C*0``)&AR=?0_ +M/`9Z%J&YPSA-$_Q"8G&&7RGS^<;,`Y3QY_>.*0``'```0`1,R"\.G#*7`;C2 +MAE<;W4!A&54WEP```!P``$`%.\A,*,ED6`\-SFT\FQ.LJ]3']I;B$K=&8`L/ +M`)@!``"8`0```@```$4``91L=P``0!$``,"H`0'`J`$"`?0!]`&`!V58D$=U +M:@WC^0``````````(2`B"`````````%X(@``>````'0!_P`,`P``#`$```R` +M#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,` +M``@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!``` +M`@````@$```.*```B``"``"%FS'&V[5*+<\^;PBRH_"-#JI:XQ@@M&->^"P"-7_O.` +MMX;SJX_8`+\[5EJDYTJ5Z(@AY?STY&&"J9H!*SB81B(L>_*NIM*RQ0$UB&=S +M`1P/T46/!AC@8RD``"1HA:AN<,X31/\0F)QAE\I\_G&S`.4\>?W +MCBD``!P``$`$3,@O#IPREP&XTH97&]U`81E5-Y<````<``!`!3O(3"C)9%@/ +M#"(` +M`'@```!T`8``#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``'*HA@CIKPS7S +M"L!^RHDWK;WUH*WI+68()4ZG&<8&+C.4A"\-*-T[8I-6MG3W'K9&&K9'_L@# +MYI'N%F!H.ZGC7FU+,TKDZ4.&#\A3R8HT4^N=75$QF'>N$- +MN[DP````'```0`6W54-\PI?M`92*0``'``` +M0`0\A#Q_TQL[)V0M!032_WKA#;NY,````!P``$`%MW(Q.72M+UW!;^[BA`ZD +M+99K3R3D$K=&`T,'`)@!``"8`0```@```$4``91L@@``0!$``,"H`0'`J`$" +M`?0!]`&`!V4#2PTLND'Z/@``````````(2`B"`````````%X(@``>````'0! +M@``,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$` +M``,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P`` +M"`,```4#```(!````@````@$```.*```B``"```M +MO?6@K>DM9@@E3J<9Q@8N,Y2$+PTHW3MBDU:V=/<>MD8:MD?^R`/FD>X68&@[ +MJ>->;4LS2N3I0X8/R%/)BC13ZYU=43&8=YR3PL@$,_/R:R$O#XT=CU>=K94! +M\KL:""XB?(.J!8DTS9PK[EG4I.:2&RD``"3/:19%`Y4G<7Y%73&.K%*CS#N3 +M\]USWWE5#?,*7[0&4BD``!P``$`$/(0\?],;.R=D+04$TO]ZX0V[N3`````< +M``!`!;=R,3ETK2]=P6_NXH0.I"V6:T\DY1*W1C]1!0"8`0``F`$```(```!% +M``&4;(P``$`1``#`J`$!P*@!`@'T`?0!@`=EHIX7"(``'@```!T`0$!#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``O')GI$SV'8"?(9EZ\F#3`X=?ZABBZA?H\8L+2:OK:2MY;08>N0(60[=` +M$'*U6"43&V-*(3KI85-;--YO\37]?4K%MT2B>-6YW20B.K_)!9'K*9,&>>%$ +MOC1GQUF!#?S/R6'VR<_)H@)[^Y@$[%)\,+N4?:,F/O4^Q"U\[P)5Y70I```D +M!N-!H*%B8*/_UYF`1_"PVP%L/X2L2X'7T%G!^/)JS=8I```<``!`!)EE3RVZ +M?SNHC%Y9'*:02I]\WF[-````'```0`5?0D=J%=FF'A842D1&^)H/U1`,QN42 +MMT:.>P@`F`$``)@!```"````10`!E&R/``!`$0``P*@!`<"H`0(!]`'T`8`' +M9:*>%W.&ERK5```````````A("((`````````7@B``!X````=`$!`0P#```, +M`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@" +M```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,` +M``@$```"````"`0```XH``"(``(``+QR9Z1,]AV`GR&9>O)@TP.'7^H8HNH7 +MZ/&+"TFKZVDK>6T&'KD"%D.W0!!RM5@E$QMC2B$ZZ6%36S3>;_$U_7U*Q;=$ +MHGC5N=TD(CJ_R061ZRF3!GGA1+XT9\=9@0W\S\EA]LG/R:(">_N8!.Q2?#"[ +ME'VC)C[U/L0M?.\"5>5T*0``)`;C0:"A8F"C_]>9@$?PL-L!;#^$K$N!U]!9 +MP?CR:LW6*0``'```0`2994\MNG\[J(Q>61RFD$J??-YNS0```!P``$`%7T)' +M:A79IAX6%$I$1OB:#]40#,;E$K=&%;T.`)@!``"8`0```@```$4``91LDP`` +M0!$``,"H`0'`J`$"`?0!]`&`!V6BGA=SAI````'0!`0$,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$` +M``R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P`` +M`@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``"\D +M3/8=@)\AF7KR8-,#AU_J&*+J%^CQBPM)J^MI*WEM!AZY`A9#MT`0LIDP9YX42^-&?'68$- +M_,_)8?;)S\FB`GO[F`3L4GPPNY1]HR8^]3[$+7SO`E7E="D``"0&XT&@H6)@ +MH__7F8!'\+#;`6P_A*Q+@=?06<'X\FK-UBD``!P``$`$F65/+;I_.ZB,7ED< +MII!*GWS>;LT````<``!`!5]"1VH5V:8>%A1*1$;XF@_5$`S&YA*W1L#,#`"8 +M`0``F`$```(```!%``&4;*$``$`1``#`J`$!P*@!`@'T`?0!@`=E@1&`1!X? +MP"(``'@```!T`0$!#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``5HKHZPF?A%_;R@S#=$ICSE2PC/G)U`<'W0<%U(RK +M$;5$T6+C(2>O$'=K1[]\P;V:@Z@(WM,,.O!TV,#!!7^*__ZRU$49:'*6;3(Q +M?AG5/8I=KO%_5:7C9^)JZ2CK/["P,5(!/20-;`;MX000X54EUKG,MUZI7HEF +MSX.A"+;\77HI```DAH$]XM5)7RB4913QMS<:/[1^`?"!"B46@0WCG#GN6ZTI +M```<``!`!*;QV1T1S&1"Z,*75A%67U[^%&B>````'```0`7E"BL%[$%F^<+S +MYSNJ!3XZR]FH8.<2MT9/LP``F`$``)@!```"````10`!E&RF``!`$0``P*@! +M`<"H`0(!]`'T`8`'98$1@$0>'\',```````````A("((`````````7@B``!X +M````=`$!`0P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`# +M```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,` +M``$#```(`P``!0,```@$```"````"`0```XH``"(``(``%:*Z.L)GX1?V\H, +MPW1*8\Y4L(SYR=0'!]T'!=2,JQ&U1-%BXR$GKQ!W:T>_?,&]FH.H"-[3##KP +M=-C`P05_BO_^LM1%&6AREFTR,7X9U3V*7:[Q?U6EXV?B:NDHZS^PL#%2`3TD +M#6P&[>$$$.%5)=:YS+=>J5Z)9L^#H0BV_%UZ*0``)(:!/>+525\HE&44\;_A1H +MG@```!P``$`%Y0HK!>Q!9OG"\^<[J@4^.LO9J&#G$K=&X/0&`)@!``"8`0`` +M`@```$4``91LK@``0!$``,"H`0'`J`$"`?0!]`&`!V6!$8!$'A_!S``````` +M````(2`B"`````````%X(@``>````'0!`0$,`P``#`$```R`#@"``P``#`$` +M``R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P`` +M"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```. +M*```B``"``!6BNCK"9^$7]O*#,-T2F/.5+",^TPPZ\'38P,$%?XK__K+411EH-GXFKI*.L_L+`Q4@$])`UL!NWA!!#A5276NB6;/@Z$(MOQ= +M>BD``"2&@3WBU4E?*)1E%/&W-QH_M'X!\($*)1:!#>.<.>Y;K2D``!P``$`$ +MIO'9'1',9$+HPI=6$59?7OX4:)X````<``!`!>4**P7L06;YPO/G.ZH%/CK+ +MV:A@Z!*W1K'_!`"8`0``F`$```(```!%``&4;+8``$`1``#`J`$!P*@!`@'T +M`?0!@`=E1%1Q^1Q'K$```````````"$@(@@````````!>"(``'@```!T`0$" +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``:+DA*7GGZKYV1A]ATW6:1BYM +MJO"W].F8@TC%N4]K@$,L_?S$B%_,>H_MC*.Y[?34*<-*B8NED/(WE0NM.ZGL +MY4LV.YC.KK:!T(8*QF>ZE,Z`?HVUG*T4O[.YTRA+@1Z1A7DN_C$]1'KRQEB# +MIZ3VND69C>M2FA>/SEU%IQX7XTLI```DRX65N1LCY]N77@S(4P42&.ZUOC'5 +MN;,1N289E0O/AU\I```<``!`!"*5,.`D17&@RV.@2MT90+0@`F`$``)@!```"````10`! +ME&RX``!`$0``P*@!`<"H`0(!]`'T`8`'9414WTU"G#2HF+I9#R-Y4+K3NI[.5+-CN8SJZV@="&"L9GNI3.@'Z-M9RM%+^S +MN=,H2X$>D85Y+OXQ/41Z\L98@Z>D]KI%F8WK4IH7C\Y=1:<>%^-+*0``),N% +ME;D;(^?;EUX,R%,%$ACNM;XQU;FS$;DF&94+SX=?*0``'```0`0BE3#G,LD, +MZ>3!QIL"K!T0`3*&]P```!P``$`%]+]S!-H9BS!`0XM-S'@)$5QH,MCH$K=& +MZVX.`)@!``"8`0```@```$4``91LP0``0!$``,"H`0'`J`$"`?0!]`&`!V5$ +M5''Y'$>L0```````````(2`B"`````````%X(@``>````'0!`0(,`P``#`$` +M``R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@`` +M`@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```( +M!````@````@$```.*```B``"``!HN2$I>>?JOG9&'V'3=9I&+FVJ\+?TZ9B# +M2,6Y3VN`0RS]_,2(7\QZC^V,H[GM]-0IPTJ)BZ60\C>5"ZT[J>SE2S8[F,ZN +MMH'0A@K&9[J4SH!^C;62[^,3U$>O+&6(.GI/:Z19F- +MZU*:%X_.746G'A?C2RD``"3+A96Y&R/GVY=>#,A3!1(8[K6^,=6YLQ&Y)AF5 +M"\^'7RD``!P``$`$(I4PYS+)#.GDP<:;`JP=$`$RAO<````<``!`!?2_"(``'@```!T`0$##`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``K4.Q0@*: +MU1G(N.YQUFH6&<;-@`=\ZCGY]M?DHZ$3Z!>V-$B;V.2I;8I@QC'/E,HHI```D:PE!VB]OOYP, +MT7*?2)I26/76ATUD@I]>W:-F,^SA_[4I```<``!`!`U;VA<`:@((*5.9R?%A +MUW_=0UV>````'```0`5'Y-BY]?,&'I=9<_;T&MRI!QI6(NH2MT8490``F`$` +M`)@!```"````10`!E&S)``!`$0``P*@!`<"H`0(!]`'T`8`'9:JN_&<"T>7: +M```````````A("((`````````7@B``!X````=`$!`PP#```,`0``#(`.`(`# +M```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(` +M``$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"```` +M"`0```XH``"(``(``*U#L4("FM49R+CN<=9J%AG&S7)="\&7:`W$_ZN^7PTF +M%NS*J)O#=@%U&F_56:FT3OC4=?(`'>^J6=LSI>;+[EC"1H2-_JTKZ!,AU>NI +M5:W=[#M((DZOM2.8II6^ZIC']8K'H`'?.HY^?;7Y*.A$^@7MC1(F]CDJ6V*8 +M,8QSY3***0``)&L)0=HO;[^<#-%RGTB:4ECUUH=-9(*?7MVC9C/LX?^U*0`` +M'```0`0-6]H7`&H"""E3F``` +M`'0!`0,,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P`` +M"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```! +M`P``"`,```4#```(!````@````@$```.*```B``"``"M0[%"`IK5&P[2").K[4CF*:5ONJ8Q_6*QZ`!WSJ. +M?GVU^2CH1/H%[8T2)O8Y*EMBF#&,<^4RBBD``"1K"4':+V^_G`S1EUES]O0:W*D'&E8BZQ*W1G*P!`"8`0``F`$```(` +M``!%``&4;-D``$`1``#`J`$!P*@!`@'T`?0!@`=E@;TO85HE1XX````````` +M`"$@(@@````````!>"(``'@```!T`0$$#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``QIO'WDLZ!QT7F]OA?8U6SZQ[%.4` +M-(^BPBB_%29BHCQX3>0J^Q>%90`O0ZZ%)(*-LT"I7%B_IK*U"U*IZAM:;*PI +M```DMN:?J>$_7*TEXULO1G&..MJ/(*6,5&VVJI!`G?O:+I4I```<``!`!%=5 +MIC:M$.Q6)4:;JI7@`2U^(UZG````'```0`4MNC/]PC+$-HY8Z$I8I25)NY?$ +MG^L2MT8>WP<`F`$``)@!```"````10`!E&S<``!`$0``P*@!`<"H`0(!]`'T +M`8`'98&]+V%:)4>.```````````A("((`````````7@B``!X````=`$!!`P# +M```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,` +M``@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P`` +M!0,```@$```"````"`0```XH``"(``(``,:;Q]W*`UL)DP\&ROM6()\%N0BN +M87>N?T.%"HUP>@$W[(_HV-#(M1-YJ8?++,F'7Z(N9']++D.EXI^>_%5=G7`[ +MI7I+.@<=%YO;X7V-5L^L>Q3E`#2/HL(HOQ4F8J(\>$WD*OL7A64`+T.NA22" +MC;-`J5Q8OZ:RM0M2J>H;6FRL*0``)+;FGZGA/URM)>-;+T9QCCK:CR"EC%1M +MMJJ00)W[VBZ5*0``'```0`175:8VK1#L5B5&FZJ5X`$M?B->IP```!P``$`% +M+;HS_<(RQ#:.6.A*6*4E2;N7Q)_K$K=&K2`.`)@!``"8`0```@```$4``91L +MXP``0!$``,"H`0'`J`$"`?0!]`&`!V6!O2]A6B5'C@``````````(2`B"``` +M``````%X(@``>````'0!`00,`P``#`$```R`#@"``P``#`$```R`#@$``P`` +M#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```( +M`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``#& +MF\?=R@-;"9,/!LK[5B"?!;D(KF%WKG]#A0J-<'H!-^R/Z-C0R+43>:F'RRS) +MAU^B+F1_2RY#I>*?GOQ579UP.Z5Z2SH''1>;V^%]C5;/K'L4Y0`TCZ+"*+\5 +M)F*B/'A-Y"K[%X5E`"]#KH4D@HVS0*E<6+^FLK4+4JGJ&UILK"D``"2VYI^I +MX3]`!+7XC7J<````<``!`!2VZ,_W",L0VCECH2EBE)4F[E\2?[!*W1ITM +M#`"8`0``F`$```(```!%``&4;.8``$`1``#`J`$!P*@!`@'T`?0!@`=E/VR> +M*?YE_%```````````"$@(@@````````!>"(``'@```!T`0$'#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``#I+I.IT9"6>CLTYYX6"+>KG3%/GVT1;O`Q.* +M#XBYJ').K%3/!1\)3_M<83!^]$H5TM$8$OJXE-TUJ@+5PJS`CIQVQR,4/R>B +MT6,_181J;\A-_@@2B3WW[_)D3>/`GXGOB?;V\$KQI0)1]/R$Q(J7*T53*K-I +MS!L.,XLLYNR`M+TI```DSVP>_9H7/++#V$8!````'```0`5)'V'<2L?T +M^.2[L;G8>+U`Z!6,>%@BWJYTQ3Y]M$6[P,3B@^(N:AR3JQ4SP4?"4_[7&$P?O1*%=+1&!+Z +MN)3=-:H"U<*LP(Z<=LN9+6ITM!H.?8]V:U__RZM````'0!`0<,`P``#`$```R`#@"``P`` +M#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```! +M`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$ +M```.*```B``"```.DNDZG1D)9Z.S3GGA8(MZN=,4^?;1%N\#$XH/B+FH^)]O;P2O&E`E'T_(3$BI9R!```````````"$@(@@````````!>"(``'@```!T +M`0$(#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``YR?.H+(YRG4(?$&'%@RJ +M!B1H6XQIR/LW_

[OJ+:TB +M4HGMD>Z3%.&E'E1;?_]\;1VO_[GOUYV!\0^/QW'!Z/'ZHC6#-7-LNRIV9E#` +M*64HXU?@-J-,!Q&@=Y[A4*UKW+)[9JKM0V=E`J,!]]I-_"EX?Q.H?U*-8S9( +MGNCH8RYID;MXJWQLL96L`U@<J/D`_N,&-B@\DEP\Z'Q4N("0(`````P```-PA``#`5Z1BD6[$$17?]]7J +M).85V\=,`HMH0_O8U'G8%M8N_&X8YU_2:X)Q?7+;XH6Y7F!]S\:_NC +MW#O>-T2)+2H;3_)(>%DH0/?QWNL`@(OU$MAK:-MTE2G\CJ.BR;8&Y_A2$[=& +M?AT,`&P```!L`````@```$4``&B$8P``0!$``,"H`0'`J`$"`?0!]`!4!CEG +MJCY`/[C!C8H/))$7"6%K#O=W]=:4K<*I6">3&P^P0R +MA$5D$XGDLQ#:)7086ZQZO!_5I%(3MT;D4PP`/`$``#P!```"````10`!.(1E +M``!`$0``P*@!`<"H`0(!]`'T`20'"6>J/D`_N,&-B@\DEP\Z'Q4N("0(```` +M!````1PA``$`4HFT2!YXT%RNG8=$[V."IZ\SB#0!:43N$F:FM'%NZGAN[,PC +MBX*2`!@[[=8*[R$`2O,%E!P)&5(R0''DK^Q30N>+Z558J2@$4:P1:O^2`A/1 +M'_0E)"A)(9E*Z>*$D_,]G8K#K']5DMRSM@0416#(.55!'TRNS^W:Z<;K>L$8 +M[!]/C)R:D_>/<\[;Z="G')/I^)19@_J_[+&$-3I[8N(L;TM^W\>,('!WCE'B +MY%H1+,)P0R_M4TY4.._5/=\5/0]Y:I,%IM8C&W$56DY?RUZ+?')XB\=^H&6` +MDQ3@!3Y_%C[2F%'1'DQVY)NE5>(]1PC`^WYZ2CP6`92D8`0N4A.W1L1?#``< +M`0``'`$```(```!%``$8A&8``$`1``#`J`$!P*@!`@'T`?0!!`?I9ZH^0#^X +MP8V*#R27#SH?%2X@)`@````%````_"$``.`H!3$``(FA))G'M7"L2AA*47F2 +M[',/%))_B&F=3$[TWWH>B!IH0O)CC9@GC9_"[\;O5E6K.W +M__A/_YW_Y6:!FA<2I\N33K;XOK)1V]DMN67([23`@KDJSBEO;&;OE8LY<]0/ +M/`;AW%-\6Q5?F+DVY&,'561:VO]8#W)B?Y;.DPJ5'KVFGQ"W:P\2J2@3O8`I +MM->C_,X.;,Y>7I3%NR.\PW`KTG*,+AKYMCDG+@%%\++'4Y600!CP_+AC.AEK +M#Y5SBFH?0R:@OLFN)&,EM?D<'&+"4A.W1B%P#`#L````[`````(```!%``#H +MA&<``$`1``#`J`$!P*@!`@'T`?0`U`:Y9ZH^0#^XP8V*#R27#SH?%2X@)"`` +M```$````S"$``+#H]9OM>+DW)C-V&3W4-XQ5[YX#X6>?R:.=-)-(B2+";R$) +M6K5"9MW%BPO)_\.5&289A-/M;JL/L''E$CHQ\\&2`PY^<(5MUVT&7+>N: +MDAN>[_=9<.*99Y(H#<`VX,74"!M^^K^;?/S[[?1M(/`^G7-RTJU!0*=&#_;^ +MUN=@4A.W1CR3#`#L````[`````(```!%``#HA&@``$`1``#`J`$!P*@!`@'T +M`?0`U`:Y9ZH^0#^XP8V*#R27#SH?%2X@)"`````%````S"$``+![JDZ3"W!^ +MVIC[+9@-OBXASR5)?HFA]2O((J*4P3!.T%R1V.KP&CC50_[`5*PR`_K9B#ID +M,.]0)=@7=S3)1W#:@L7^'^U)3=O\,OJUGQ/"9^XDF%C&X5ER9EURO6A(R%#* +M(WP$1GOZL;?\S.3=YJN1K"(,VC32?`".+-;#>F5L&G_>"]3$CJU2X;H\D4C- +M>"D/"^&QIT/F$_?0.`^-W&>,<64#D9%C6^$EP]>(4A.W1E.P#``\`0``/`$` +M``(```!%``$XA&D``$`1``#`J`$!P*@!`@'T`?0!)`<)9ZH^0#^XP8V*#R27 +M#SH?%2X@)`@````&```!'"$``0#[WPNJM\Z,*DXVEMFT'[E<^*/3M=LBC1M< +MZ#E"?ON$-H;M1U,A5_YZI6R98HVTR-(?2?(094[(+='X +MS$SZ +MYZG4KHO;\4544NFFW\?R"!D]BA-[$.(HH,(HS'+D-LYJ49SSR6!UGM(+HS%J +MSF6+\(OCC-*XOTS>0B@(OQ6I8[G*WMJG>O8ZHJ:_N2E+\1D68 +M.([CCOT%'VU@`URB(D:,IZB+UBR>#R4]"4D,%KJR7)F]:^+0&IVEHSW6=("& +M/#9!VWM%*+2WUK-@)O`+VI:NM%0WV'92$[=&#B_3;F5"P=,$A2A9%J[NC@LZ/TY +MI5`B=1:*S<._`)2?*HX`W.-?P\D!0/9W\@;*#5S39ID*@19,%O7P-QJ!9A]4 +M")3GG#5S`W)'-]1(`7WN_5\0NMB5(5L4*1-WF%>)S1#:KSY<)U1RO2(1W!.< +M_"7/?M'-R]"\1;TV%DE697CY8?6/G7$U\TR?"%:62S.$%PC4]`JMN`5NE;D$ +M.<2F4)A<[O9=R$[9O392$[=&?>X,`.P```#L`````@```$4``.B$;```0!$` +M`,"H`0'`J`$"`?0!]`#4!KEGJCY`/[C!C8H/))A;F6=C]6!#-1"W=9,F`,P(Q +M@`:T,+$E/,)#R/.KT;7R>"IM)Q^9HY/ID)KL>D'$A#P2H&96Z^2:4ZL$5WPQ<1I@"ZVY[S\3"^`",]Q6QL +MPH*[%_)^]%1T!N:R`"W,DRJ2Q23V3+X(%B@4IFF7Z.G;W4A+2(P%,EI2$[=& +M-!4-`(P!``",`0```@```$4``8B$;0``0!$``,"H`0'`J`$"`?0!]`%T!UEG +MJCY`/[C!C8H/))])4K/2KE:7%]+N!D3PD=Y0W4D,F)QX&U2D. +MTHD`*?L0*U=#CS(!0Q>\OSV&M#!4\>]:X@Q+BQ>4)W;\PA.TG<->4'HH[T(R +ML7D1J/KAAUM3>0L+<-VJZJI]@<4EU4I")ZHWXHI38XW26^=(:_4X2<,1+NS\ +M#YWY]1@&].^RGY:0O%6RTH.T+#^0]R=5[G;R#*F>.@C^VT_ +MA0_1)D7;O"6SK,:H3.9C+0B#=L6-I&8$93`Z>`2"J^#@PHS&$T7K<@ZSB:+/['';7&YD-C==M'_@#`#T06./D92=,>CW)7HY +MCZS*1QO7XG0^'$`J"Z`O2^&YI*R)=E%;`("YO`Y_CMK2W@%D%90V?W1=>L;+ +MML@7S*&(@AL$DE]6FL"(?1.]+R[AV[=)%\S]Q\TY%^T;#OA5"C!9C9"28QR3 +MF%!4"PAH,EC_,Q6KWC6T_[08'#PPHQ;+ +MH9W3;*)^<5(3MT9S<`T`?````'P````"````10``>(1O``!`$0``P*@!`<"H +M`0(!]`'T`&0&261O1N98B(CT,SMA3&@26Q\N("4(`````````%PJ``!`SAK* +M-;A4>CS#3JJ>SFCC4? +M8#RX5=;SCY7[[8F[4A.W1OE[#0!L````;`````(```!%``!HA'```$`1``#` +MJ`$!P*@!`@'T`?0`5`8Y9&]&YEB(B/0S.V%,:!);'RX@)2``````````3``` +M`#"1N9EX:N6"AI?0]!>CAB%5O0>S"2IH:]8)A1-$W:QR2H#<_8$EPQXF(:*E +M/%(3MT8RBPT`;````&P````"````10``:(1Q``!`$0``P*@!`<"H`0(!]`'T +M`%0&.61O1N98B(CT,SMA3&@26Q\N("4(`````0```$PJ```P-Q^7/O)#6,^? +MD,/?-#*LI6NU)M=P[91P%G]`,6,,S1W_C%J=J\5*P8O%H1U2$[=&;9@-`&P` +M``!L`````@```$4``&B$<@``0!$``,"H`0'`J`$"`?0!]`!4!CED;T;F6(B( +M]#,[84QH$EL?+B`E(`````$```!,````,"(9VST:_LYG&,JF8I%`AH87`QH4 +M8129FQ?I"_EOZ^+CDW]X'P>&T4^\ZQY]4A.W1N.3#@"8`0``F`$```(```!% +M``&4A',``$`1``#`J`$!P*@!`@'T`?0!@`=E84KO#*9$7"D``````````"$@ +M(@@````````!>"(``'@```!T`0$`#`/X``P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``&HR+7-[Z:U$&QU\JUY-2*$75>,>U%.C_[D-724EN?3Z^U6^& +M.)/X9_0&5!IDG`@!K;C2_K"DU[TY45852=]JW:)_(&PNXTKZER^;HT'[B?5L +M=>QR8/[@:S/H0'U.!E3V']&&]:\T2>88*P:HLRWJ.5+AAOZFZ7(1M6\I```D +MKBV`'D/4B.")RR%3S*1Q4ZEO>;@/F"[NR3T%\%4<<>0I```<``!`!/2G-DWI +MC5!-33L8$A,PPTV!#FW;````'```0`7$*_.R"$R9#E*/MZI+E78X"NZD6U(3 +MMT;6H@X`7````%P````"````10``6(1T``!`$0``P*@!`<"H`0(!]`'T`$0& +M*6%*[PRF1%PI```````````I("(@`````````#P````@``!`!@````KGA19/ +M?,>U%.C_[D-724EN?3Z^U6^&.)/X9_0&5!IDG`@!K;C2_K"DU[TY +M45852=]JW:)_(&PNXTKZER^;HT'[B?5L=>QR8/[@:S/H0'U.!E3V']&&]:\T +M2>88*P:HLRWJ.5+AAOZFZ7(1M6\I```DKBV`'D/4B.")RR%3S*1Q4ZEO>;@/ +MF"[NR3T%\%4<<>0I```<``!`!/2G-DWIC5!-33L8$A,PPTV!#FW;````'``` +M0`7$*_.R"$R9#E*/MZI+E78X"NZD6U(3MT;:U@X`4`$``%`!```"````10`! +M3(1V``!`$0``P*@!`<"H`0(!]`'T`3@''6%*[PRF1%PI'07*F[4.7)PA("(@ +M`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@# +M```"````"`0```(H``"(``(```,IG2IRT1PB.TKS]"QGV@I0FK*0``)#5P_V3N*.\3'NI.(S08>%_KZ`'&P3I0NC-XQ8(> +M<M94<`!=X@A^ +M>%:#HCZW;8]:Q7I-]M\AQZKL:/B^!;^;2P=EX]8J#@ +MH6WZF_WA3."CH8[7)Z8_!(C6QH@LHQ.QWCM5W2T(UOA@1\<8H?"\9^=("+"4 +MR1K)^#"G]PY3;H@$LQ+`ON6 +M:!V"-]B&P^;4%@H$X6LM7R`3IQLIOO`8ML2HQQQ\=*,*G$QL`VFRXF9F:6,X +M)Z6Z1;VYZR--$GHTQP[B:]47F]'ZC)O$F8Y.%"R7L`(]60:WP:\M*#(.=VJE +M@]*)[#2?'5(3MT:J/`\`'`$``!P!```"````10`!&(1Y``!`$0``P*@!`<"H +M`0(!]`'T`00'Z6%*[PRF1%PI'07*F[4.7)PN("0(`````@```/PA``#@F\WY +M3'^1/LA0V[]WV,HP"(E4#*NFS+S#O?C.P*D45P0`JIV%.]'&`:RI%6]#B4#9 +MQP8]]^0H<0J(*T;'U$X8K3"'049!)#A0]N.'!(6['+TH:BJ)NSLSI$GD&9IA +MC*0Z)Y5.?X>O4)9NY0WU%"BQ4YG$HJ+_-@FLM0GE,3MT9L"@`` +M;````&P````"````10``:(1Z``!`$0``P*@!`<"H`0(!]`'T`%0&.6%*[PRF +M1%PI'07*F[4.7)PN("0@`````@```$PI```P,-+?K(CN5ZCET[OO8U4U-)"Y +M@++$&>N"-]78:`,W-[/:#T0^^QSM8?C*3_-3$[=&>1```/P```#\`````@`` +M`$4``/B$>P``0!$``,"H`0'`J`$"`?0!]`#D!LEA2N\,ID1<*1T%RINU#ER< +M+B`D"`````,```#<(0``P),!\!XV(%BMZ:58NQ6[C]VC''1R%[1KZY])O- +M6>"NS4^(#-#+4K::O;)`.VJ8L\O"!#@V#+7M@[MRT=]_(K1@V48#@?26? +M\(TINID3&^DQ>)9$O%,3MT8@2```/`$``#P!```"````10`!.(1^``!`$0`` +MP*@!`<"H`0(!]`'T`20'"6%*[PRF1%PI'07*F[4.7)PN("0(````!````1PA +M``$`R(4,.!,(/1&?-`D$#D7[ +M;)95D^+EB5T.R4 +M:$24$*V82+UQ+(IDG8?AYDI:MB(=F,5F6SDXV*1B4Y1@_X@.,`6%AA[VN3^D +M!9C$G10-!.38>P?C@WXZ5S=D&-D[;OQ-#SZ8K8!DXPZNRNN&<0A?:+;5O(&@ +M/2N6045J1$HF')=-OLU^.(LL\(\1]KH4$,E(\H5=,2:KWIA\0LHH=I&0@?G( +M$A5Q,2M0.6S`>6]1JSFGC&G:M^(W-@\<$#"9]X8%=#(H)OV$/ZL+)K.,MWO$M2Q_+%%>#S>W +M<7-M(/6OTJ]`PL!B&T-27'>N\LXK&XT7D*J*2*OBT/\H2^CMA'32C>'\6?*( +M&TA+*OB<=7WTJLK\\Q2>(%&0$<[]1/-P;^+_A]E.>Q-Y`12-G[SUAU<&4-HX +MSKP!^([?4V.?<'MIQL\G@:8R1$O^E8C@[F48;I#]$I3W$2+YY9Z#'-K2E)AI +M`,."EFWJJM)W]8!T)VK]4Q.W1M-C``#L````[`````(```!%``#HA(```$`1 +M``#`J`$!P*@!`@'T`?0`U`:Y84KO#*9$7"D=!)+0;DKEA2MOL>LEOIJ +M$4ULUF9R#X,&N-)&H(?BUP6G13"]`T11Q1;O7+I>!N(UT-@'>2FC&MEV`#_# +M7+R0U:#`'<-PAC(WOK0M%"'[?3L>W?6R)A!X*\'TDCB +M6E&.VBS%C44.:6RYICG%%4_A[\X/I+XY*]#O,F.-"$\PGZ^4_]"6Z32<*Y1_ +M-!=;%Y:1=UDBVCGU:2`,D$'6!L:VQ2I2J+@#!M?.G8`/=T>!>5Q-;<-\'E.@^4Q.W1A"D```\`0``/`$```(```!% +M``$XA((``$`1``#`J`$!P*@!`@'T`?0!)`<)84KO#*9$7"D=!OLU@3&9F%6<%4`2Y"5 +M+1\8KO&(FL618(69QN6DEZTX'GQ9-C&\=&;$N[7*$`MM$&$KN9[^;\_]G8M0 +M7\??#SD`8B\8DQRI1*UMT!;%]_BM[B"*P9\\)4N?696M@Q,P\?#:I\#'@TDK,7?"DG$-1N96:)8L/3_C0E[]'[$,$FC=-%!(9PU7>7W68R9_.K]O'S[2_P'G58O5"EU@*\9( +MTHV85^3)AL/C**OB*M%T4;NI]X70UD.@QM?Z'2Z(!J +M0P`3I&']H(MO;3#&7$/4@ARI;G)!,T.Z``(;==<&I]!'L"5ZB^=:"26#?O:Z +M]-/Y_RU!_^=;&Y3QL5P)1&.FCK%6^9WKB)7-0W^(N/+O;BD3NNHK(/.4QI$3 +MQQMM@ZJ"+^Y3$[=&1.$``.P```#L`````@```$4``.B$A0``0!$``,"H`0'` +MJ`$"`?0!]`#4!KEA2N\,ID1<*1T%RINU#ER<+B`D(`````<```#,(0``L.W$ +M\$WUQ#PDW<"LG[(K1#^MP%S]B,)O%/"K#;$"&Z54>63DK4O3C]2.ZDEL%UK; +MR8K?5$%KN`!>-XXCV>YQHCK,!2[05^Y_T#4=4@%V-I4##N&=H1Y:45`N9:MN +MB-C[^U0Y,\C)OC5YM-V)BGLMP?_C],'6#C2,C>N%KWLA(YP8P%HO^C7W5KF& +M*L5\R73AMIZ@@^/C$,E*@F_S`9E7<3*0.VK&%C,1F/]I_1-3$[=&C0`]X1]J5#W=Q8RK9:(V:`-@*Q/P(FHYSD9J5^Z@`WUE@8 +MZ"T-;05SM$R4YT$+D@2++\AHVV".!AO-5XP?+:H!KF=HV:`]B[ +MB@BKT=MY4\=_$:.1\]*6%NOY!2^CF3$T?Q`>Z'OD/I\B53BD[8[I'C6?`1O[ +MCU5`S^\DL#$#S*5W+GA@_)KF#YKF"X2!\IG#QBG?4V&@JSO%NJ`F)Q +MHROK4/?N7P''O&IC:IQ0RP[!`U:]NZ8:#[`C228](9I6Z+UH3']I`$>MV,RW +M3?:=S>MR$:F;^=(,8.QFP2;C4\E9L@V*3_Y)`!UI/2EAZ$JA)0"E=4)^`5P@ +M-060P/5H%%EWIV>O&>KR8.[`(1M2X^(2(``!`$0``P*@!`<"H`0(!]`'T +M`&0&2=@<_?":3N-1IYC9N!H.="@N("4(`````````%PJ``!`>EJO6TAO*`%? +M`1=WXLG[18LL8<>Z?@K?A=,`CVG.&4NO[C8X"#VXHUZ3E9SK;[?N4B^N'O+W`H`4Q.W1G!O`0!L````;`````(```!%``!HA(D``$`1``#`J`$!P*@! +M`@'T`?0`5`8YV!S]\)I.XU&GF-FX&@YT*"X@)2``````````3````#``E,3H +MPA\V9IGD@BH,:ZL_7.<5;RN"Y2E9&!5!3??/*SB[&M/11+=6?QUCM%,3MT8+ +M?P$`;````&P````"````10``:(2*``!`$0``P*@!`<"H`0(!]`'T`%0&.=@< +M_?":3N-1IYC9N!H.="@N("4(`````0```$PJ```P]G!-M%,FBV`E$8%?%PGS +M]^A2N>L>*,:J@>>;0/#&,8V;@: +M#G0H+B`E(`````$```!,````,+"6<;,"NLFFZC'GG?0KKO$0FZW4RH5(*3T, +MO\1=/X>Y2Y#D+,=AT/<7$1<+4Q.W1EB)`@"8`0``F`$```(```!%``&4A(P` +M`$`1``#`J`$!P*@!`@'T`?0!@`=EX(FE@37V358``````````"$@(@@````` +M```!>"(``'@```!T`0$`#`/Y``P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``4FV! +MU6^S"0/++1BFL7`J"XQ+C,C?I)=6N]NEB#DM=OH;2S++U3 +M8'E=3`:Q:L-OS#)WH4'%4F5ZR]Q/9DW!GWS>A_K`.+V[8A/C3":*?D3#V<5@ +M,'JDAWFY<'#,(O!F##Z)/ZKZI\^\53LE^)HL3F*MMW"/(/XI```DU[\G%>2) +M):S.>]X&"611FE(4T[P%*#]$6H0IC]G015\I```<``!`!!:>.@;.NFFG9V@E +M/;#(5@WPYI^,````'```0`6K%FK#]+(^R#!64QA4&NO60M[#F5,3MT8BF`(` +M7````%P````"````10``6(2-``!`$0``P*@!`<"H`0(!]`'T`$0&*>")I8$U +M]DU6```````````I("(@`````````#P````@``!`!@````JBT[N2?)FY3:M" +M7;)/%4,Q;+JO2E,3MT;&IP(`N`$``+@!```"````10`!M(2.``!`$0``P*@! +M`<"H`0(!]`'T`:`'A>")I8$U]DU6```````````I("((`````````9@A```@ +M``!`!@````JBT[N2?)FY3:M"7;)/%4,Q;+JO2B(``'@```!T`0$`#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``4FV!U6^S"0/++1BFL7`J"XQ+C,C?I)=6 +MN]NEB#DM=OH;2S++U38'E=3`:Q:L-OS#)WH4'%4F5ZR]Q/ +M9DW!GWS>A_K`.+V[8A/C3":*?D3#V<5@,'JDAWFY<'#,(O!F##Z)/ZKZI\^\ +M53LE^)HL3F*MMW"/(/XI```DU[\G%>2)):S.>]X&"611FE(4T[P%*#]$6H0I +MC]G015\I```<``!`!!:>.@;.NFFG9V@E/;#(5@WPYI^,````'```0`6K%FK# +M]+(^R#!64QA4&NO60M[#F5,3MT83S`(`4`$``%`!```"````10`!3(2/``!` +M$0``P*@!`<"H`0(!]`'T`3@''>")I8$U]DU6O#(?A^R$=4TA("(@```````` +M`3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"```` +M"`0```(H``"(``(``+Z\4;)?#&L\/V-"8H.W*M?^3`T&E0]JYP\$V/&@6.#S +M,M#K*+$H2#VF(34ZR\.TNM3`W7]XAFTW3B!AD/G3`,]__0K&&K[KK_I_S+HJ +M!7ECCHV#'=DR(%?Q0FV0P5V9+!]15&!H)P3CF,Z1-P(2>D+C_^$\RU1M8EU\ +MO+6*9:T**0``)#0,;HF#S>\VKR]$@7$63E)G/U?Z^FA1#J6QQ1#L?)O)*0`` +M'```0`0(>3.S\#-XA5Z)E\2A66>Q(NJ()P```!P``$`%G[Q'+&BZ&)\F2((= +M4_YFX>;)(PI3$[=&-OD"``P!```,`0```@```$4``0B$D```0!$``,"H`0'` +MJ`$"`?0!]`#T!]G@B:6!-?9-5KPR'X?LA'5-+B`C"`````$```#L(P``T'SZ +M3PGX/#.C@"UXG!47X:S%[OVW?&9 +MW'&??MI_++L^3VO&S&)^[8O%\4R0M:;DT5J$?;%9YL;T\\1Z:IMHJ`H\1V#4 +MP`.=M"Y0*(T[\3`UH-LFKA*YI66WK@#)4'8UE(XBKHG@L9H;0$%%EQ;(W@$$ +MH;3[FFJF=M'6$2Q1UW@?[O(QZ^$DZ\`D>'Y>&@MME6%.S.4`QZ=!3D=+6]"] +M1>(;144\TI,@^?M\'%?(2A(I;TS$X%,3MT9P$@,`O````+P````"````10`` +MN(21``!`$0``P*@!`<"H`0(!]`'T`*0&B>")I8$U]DU6O#(?A^R$=4TN(",@ +M`````0```)PD``"`"YB;R#2PW6B&O3^73-0R&!I!O:U_T=G'F&G']G/= +M,,."(=^V$;'(5^;_GTRM,Y'IDC&/7%?2?6*@[30VK-PD),XML\WHTOI")I8$U]DU6O#(?A^R$=4TN("0(`````@```/PA``#@7]2#3KTHCX$N +M13[SHG+C]07$F^(-0.>+Y(H4;"2?HYJY[]Q7>].?]^A";FOS[%=8"$;'YQ`"-WCKV"71FIEF6%L`T6_,(U,7%%XB$6EA[[Z)DIFGNY&11?=U[.4@K +M(_>&2">\<7.$=+CW)_'#41]$'.3.NW&7?6K#92JE&YO[G[OWP[X=]!1(L/V_ +M6R>Z/A'>ZHU)QJJ9^L'=ZT:T.FD6IVJR^#5;%"1@]U,3MT9U/`,`_````/P` +M```"````10``^(24``!`$0``P*@!`<"H`0(!]`'T`.0&R>")I8$U]DU6O#(? +MA^R$=4TN("0(`````P```-PA``#`Z"W^S!;\F=>ARA^6E^NZ9_OZ]Y\':Q@@ +M4O!T!XV;TCB]EDE4)]*893N):T>R,^5-03\Z$&=%WXQTN\6&W&[T/.YU\;;. +MVY2SF;JK]37-S''^OB?B=K7`TQXF\P9+)WJ=#',,E32D5R<-R9N10@.=UM]93$[=&DT<#`&P```!L```` +M`@```$4``&B$E0``0!$``,"H`0'`J`$"`?0!]`!4!CG@B:6!-?9-5KPR'X?L +MA'5-+B`D(`````(```!,*0``,/$OH[*F#T8+(V[/3X@6B^YZ%N&%;(C]#9?< +M%FI^$$.;?^VA_64^_3KX9?,M4Q.W1KIB`P!L````;`````(```!%``!HA)8` +M`$`1``#`J`$!P*@!`@'T`?0`5`8YX(FE@37V35:\,A^'[(1U32X@)"`````# +M````3"D``#`NYS>V+=\#X,4#5U'H0U')L!TQF-G0)+(%/3U$+:6MVZP]\)IO +M_LQ<*REH]E,3MT9+?0,`/`$``#P!```"````10`!.(27``!`$0``P*@!`<"H +M`0(!]`'T`20'">")I8$U]DU6O#(?A^R$=4TN("0(````!````1PA``$`)R;' +MM7P=QKU<#IYPWSKYE'O6V]_"J9`@.I'O%]#*NCT@_:T68#`@77.%Z`D[:U`5 +MO\E4.O`^&&B;[9Q@TPL!0@P4ED81+2(4/@..@'^\O+D?:2A\X`ZGVE%JX>0( +M,L*U\JX2P)%(Z30L\9K<9AUY=)=TN=J6D4HOX&]Y1Y.\53IK\(+'''-0(9$B +MJ#CCY\O&\!Q'N#?&-E;V^,&0 +M)23EA@]!U-IS#ZM,`'C5*=0(LTIRF,M[$BH.*PX:)1*7YUGQY@YV++V4^I:>0P=_%O;T#Y_^UL4Q.W1OJ)`P`<`0``'`$```(```!% +M``$8A)@``$`1``#`J`$!P*@!`@'T`?0!!`?IX(FE@37V35:\,A^'[(1U32X@ +M)`@````%````_"$``.#?H0)2Z5RF1?37&#$T'Q<9:=O,T89,JUE/[WQB:+W/ +MUS;;Y#NX7LZH*SYFK&MWR[8U%GG`1G+U`UDD^(\C'4Z;F4Y':>1_/?]0;T6ID>180DE6;[<@P+2N`_W3>TH&2*,LUY&$6\R7*T8H&^=&`7QZ +M_[(+OO=;T_9>.MPG@::5*Z$8.#>,Y(::S`8&-]HOT+`C1$_6NB3@6Y`7Q+'M +MA-(J8V)LL*A#4Q.W1G*9`P#L````[`````(```!%``#HA)D``$`1``#`J`$! +MP*@!`@'T`?0`U`:YX(FE@37V35:\,A^'[(1U32X@)"`````$````S"$``+!Y +M5]+>]%04E6R_/V@AV38C8;?@?G(TUR+E@H8!!BDV'0@GC/Y4'5SUS!*J:JJ/ +MLLZC&3IH(NW=.,[P=2$:05\'M+"1^K6SA&XVLWS?^&L\)$?8TM6A43!]`+F9 +M:F85;4`&&+P2ZS6H/3F.]*`=J$_IY&U+V9WT94ZDQW2\G%`R/$9!+8K17%"2 +MSY8M:T4HR=R%(@?J3;X@?BU:X?3._H:7A)(RE4U(<3X`<'H&4Q.W1GF[`P#L +M````[`````(```!%``#HA)H``$`1``#`J`$!P*@!`@'T`?0`U`:YX(FE@37V +M35:\,A^'[(1U32X@)"`````%````S"$``+`+:Y([$X")TZA%&IM3M$L:C4%+ +MM>_Y1$O@[C/=C'^Z*#/+AUQK"RMN!L)]D,DY,S6<$0%AZV+&/E4=I?>Y2S3# +M@17Z>(7B:?%B7R0:65HHH#[(%A0WH-V:MG:\.!6)R3@82DEP7>?B9/1' +MC+6;Y`[.IKSZ>XP`POW(#V3P&Z\3.&(07+ZX,P11C1?)M:H!8__B]TO2A'12 +M]+!J0:E4/":_-2L-$4Q.W1LO8`P`\`0``/`$```(```!%``$XA)L` +M`$`1``#`J`$!P*@!`@'T`?0!)`<)X(FE@37V35:\,A^'[(1U32X@)`@````& +M```!'"$``0`SZF?TBQ((42VCF90I$7-=_#-S"'/4"HX2XR!V]1LYR8\$MS[G +M)D60BF39!7URKV3R7"%JA-Q9,IB:GT$F-1G6>6EW;\X^QNO/1JTSY/S.^JR9 +M^>[RU`7E*E#!*3DI*^RR'K13_H!B=?X@13HO4#8S-:"`X +M]&@2FE(6A6*`F4/;KB[,M[>2U#/G;VZ:/*/XKT`%8'47BKI3$[=&C>0#`!P! +M```<`0```@```$4``1B$G```0!$``,"H`0'`J`$"`?0!]`$$!^G@B:6!-?9- +M5KPR'X?LA'5-+B`D"`````<```#\(0``X*:$GTO/99;_BNS"MV=)M#'G!6G0 +M;(+8&0!]J9RKITQZ!US]1Y)[#7<;^J+(:FR;)JSXQFO9PV#`E]:D +MDC;82/K&X30UC_XIHW7\9QQR9K[WZ&C3R^`7DS"9I:%/.'/(X9XO>&%HFS&S +MT?>@C#O>2OQ8_M3$[=&+?0#`.P```#L`````@```$4``.B$ +MG0``0!$``,"H`0'`J`$"`?0!]`#4!KG@B:6!-?9-5KPR'X?LA'5-+B`D(``` +M``8```#,(0``L-`(:<&G5A'FE^KA`IQ;X:-0/X]M3$W@##_RW?-O)J[F0&:3 +ME;CVF#"JCMIVKACJ5J[]]M=U?YWC)FI]C+`0*)\WHOJGE]@U[Y10O(:@L@69 +MU@L@5Z:>8F5G;W);M9M??;>\H5P-7%2UOVV+/<=:Q +MNH[S<"[!P8"+G5@5K<2HU$%]2UXL"`(/%DDT\DOMU9ALIRHWPP03L"SP49,T8MY# +MBI_&/:1\3ZL&)NN^2R;FY8[4)O`N0XJ=E^;/V'E?!WS#\;U8D8UM2SD?DM-X +M''3Q/+LLOPBE7#%A_V[C,/6Z8>@1$=\Y,^$#1"N%),7\J(0<8K0/5FC?'8). +MI,U%(+FXH22IB&)+<408A;QB%!,^92JCW(,T*J53$[=&AST$`(P!``",`0`` +M`@```$4``8B$GP``0!$``,"H`0'`J`$"`?0!]`%T!UG@B:6!-?9-5KPR'X?L +MA'5-+B`D"`````@```%L(0`!4(5*2!;I=X-_N^V&=3>?R5\YJ/"0\,>\+XIZ +M)X'2.P#9NJXV#*2"GU!O\S+!]AI='[WA((=:+E";:B +M[P1GKM^FI%AO&C'F@>H!3=EB1,E(8M&_QC!!N\EO@))I=EX.*PI_`H"\U085 +M\YC8.O[9M#6!23V+SG.!\@]U]EM&>MUU%F/H$GQ5W,EWXJO0&B;)/#2OO8A& +M0EZIVZZY#>HJ&[6_KM2T:AKTOQI$<#VJ5+4QP9G&?C?)YRN_@(4UK\=WNO&P +M'@+71OF#V)*CL7+A2S+9,LVS/0GH%[Y'ZQ.T[373#\DNB.U74Q.W1D%Q!`!< +M`0``7`$```(```!%``%8A*```$`1``#`J`$!P*@!`@'T`?0!1`TQN-)ZH +MT=)+<8_R,'2Z('72,0(+OI +M,3?0(4[:494GFS'//.+6+/G/C!?)XHS(#_OV,FBI)-@B$JA[?>W+Y]Y*`*E1 +M,5_G0D":]9O&IW>8U2><*SJY%M@D`GYP6TG-1<.E\B0=>4RM/I7C\M=O`_0O +M^=+P5Q8L)L$`/.RLSTP?#RG':;KE\6VF3)S%)N=>.MHS(_V*S]9M6])]RY0% +M=5!H!*[KU;RV>CX>Z60`BQL>;9C&'4"WZJ:JZ\E.GU$:)+X4>Z@H)*QI80NE +ML1M\36G6I->Y$TL&\(;?&J"DSHC%MR`;OOM>BA>^@;^09?7-*[0L)E,3MT9` +MF`0`?````'P````"````10``>(2A``!`$0``P*@!`<"H`0(!]`'T`&0&2;G* +MVZ.-<:0]#_.X#K$=WJ\N("4(`````````%PJ``!`_1%,_4KL9P=T%KRX@)2``````````3````##^")B!3`MTC"W/2932GVC5H%8A[:9&FCE3$[=&E,`$`&P```!L`````@```$4` +M`&B$I```0!$``,"H`0'`J`$"`?0!]`!4!CFYRMNCC7&D/0_SN`ZQ'=ZO+B`E +M(`````$```!,````,#'FNS2H_3+:SK_;#*\KQ\2R=)I@<']')I][:=X,"E*7 +M.^?FO+?!D*PTKA374Q.W1E[D!0"8`0``F`$```(```!%``&4A-X``$`1``#` +MJ`$!P*@!`@'T`?0!@`=E5=XOG8,`3-H``````````"$@(@@````````!>"(` +M`'@```!T`0$`#`/\``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``288R*T==I$], +MYW2CT<^>PO-$F:EK#W74K'1D`6MK>KU`Z*:]X.ID+A8L4-C]H?8HQ;X`X3?9 +MXY@O@R4QJ1R3^YP\$(FF=H:VLH9N4$_8KLQ,[@Z04D_\*@G.5?]R&?[/6'20 +M>:*_P]Q^5H^$?7^&X'IOY[_+0XM3PU0JV4I```D\%P.FD)EE]EI*F-2 +M#VOV")1ZI5%]C#]2P3.PT?&CQE0I```<``!`!&+YM.\I509E)!?\[(>@*U#; +M?W-F````'```0`7@R4I5#Z+VSCNVHR$B.:'0>M9K`%,3MT:7\P4`7````%P` +M```"````10``6(3?``!`$0``P*@!`<"H`0(!]`'T`$0&*57>+YV#`$S:```` +M```````I("(@`````````#P````@``!`!@````J!&0YB44-G$1&)P>(LXS<& +MKJ,7/E,3MT;<`@8`N`$``+@!```"````10`!M(3@``!`$0``P*@!`<"H`0(! +M]`'T`:`'A57>+YV#`$S:```````````I("((`````````9@A```@``!`!@`` +M``J!&0YB44-G$1&)P>(LXS<&KJ,7/B(``'@```!T`0$`#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``288R*T==I$],YW2CT<^>PO-$F:EK#W74K'1D`6MK +M>KU`Z*:]X.ID+A8L4-C]H?8HQ;X`X3?9XY@O@R4QJ1R3^YP\$(FF=H:VLH9N +M4$_8KLQ,[@Z04D_\*@G.5?]R&?[/6'20>:*_P]Q^5H^$?7^&X'IOY[_+0XM3 +MPU0JV4I```D\%P.FD)EE]EI*F-2#VOV")1ZI5%]C#]2P3.PT?&CQE0I +M```<``!`!&+YM.\I509E)!?\[(>@*U#;?W-F````'```0`7@R4I5#Z+VSCNV +MHR$B.:'0>M9K`%,3MT9J)P8`4`$``%`!```"````10`!3(3A``!`$0``P*@! +M`<"H`0(!]`'T`3@''57>+YV#`$S:7@3U"^M8E_8A("(@`````````3`B```P +M````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H +M``"(``(``!_0S:\E@C9=.R!>4*[J-B2]&&ATYE,F?N'5+N=\:]QO%9;?F5^F +M1"7$X2,[?5VXL`KO;-#_+0T%9J/!+'9$/<(0G-_((NL'F_1@V/H3AFMJ8Z*% +MY(&38CU#S3>2GQ4R036""X-0*#%HY%W$Z=>U9(!("S&FOG6'L:?1Q$XD^E)F +M*0``)%+-/(X3TCPS\'L,PQ'HC@5I(D&(QV$#2'`QN$GIPU]M@GIUP)%3_O#RMR\=_0(B7H<5Z' +M7-C&=5DB,.0X>-03A\$Z\[5;[()I%!2M-^*DW"P=/BKJILES/`W44 +M09PC(T;6,D,V\T+:`WJP)Y`2EXK_38(!<%7?%>@'OX8?)F'X*`K+H`PH=^ +M9DB\B"Y=M\O)B%GY&PF>,5,3MT81;P8`O````+P````"````10``N(3D``!` +M$0``P*@!`<"H`0(!]`'T`*0&B57>+YV#`$S:7@3U"^M8E_8N(",@`````0`` +M`)PD``"`<\I_-,A"V$34L'CWR3(AT<$E$]:U+HJ*-_9XXY[KD?9R]^ONI3XI +MV522+^,,#+'$!/JTSZB\U,U-%;!I3:^=VE)TPENKI;W(QO;_"E7_%=,^459( +M:.^ICKOC=V)]EB[CN#0#@9@T"KU5]RKQ&[UJ#3,N]-3PMC]I4JR32E,3MT:2 +MC@8`'`$``!P!```"````10`!&(3F``!`$0``P*@!`<"H`0(!]`'T`00'Z57> +M+YV#`$S:7@3U"^M8E_8N("0(`````@```/PA``#@A0I?FV"(S1B&>8W4@.'\.W//:DV^%V1H"@K>.C*V&!UV9-8YL2P +M(3H"[F'/R>QZ;"AT_!]]V2`W[ZUN#.SW_;#Q%9&:)$]KQ&E>9]RD1$_\JHQK +M]:U33(&7P1^(NV"A7=/HC%5*Z-$EKDIPP>H3ZYI-'8_:O$>=_/O;%.:FT(W! +M&_;!`\`HQP%A?]_]RM/";;`;];%^CA5H_]'=AS%8M_M#%\Y9=9\P^28]YD^M +MM2@Q.@*(-VE`<.W7\S5C^.>4S?QMQL(!OE,3MT:/F@8`_````/P````"```` +M10``^(3G``!`$0``P*@!`<"H`0(!]`'T`.0&R57>+YV#`$S:7@3U"^M8E_8N +M("0(`````P```-PA``#`DI('#01M"]";UZI734@D0N=ZGM*I%_;D4"1O-$B9 +M3NH0Y`UZ]AR^&U$)GE[S&/%%R_7@N<\D<3-(%W"RA9Z]1'@9/C\Y\K0OD/@Q +MZRCFL>)CBJS/UY,N:"FD]J`:*#Z#GS;AUIQB`M91LZ"=W"BI,S)VC5.6X_R3 +M9,,SO`,0R?;.4^^[WH6MK9/+IE-#7+.&]A9"\NP+BOQ[&ZZ!*,/-0#0;NDXE +MDOP][;E-=K,K,*<8CR`,(H,&`*DM"^53$[=&%:8&`&P```!L`````@```$4` +M`&B$Z```0!$``,"H`0'`J`$"`?0!]`!4!CE5WB^=@P!,VEX$]0OK6)?V+B`D +M(`````(```!,*0``,/=`%=#\,#\L7?!&NQN\1:LL&/`A!4VZDXD'/&RJ]^O2 +M)="D"?!/4+ZUB7]BX@)"`````#````3"D` +M`#!R^#""&8AX>;KP)B-WV!\")=;Q.^I51K=+!KN>N\QR9$46T>4+YV#`$S:7@3U"^M8E_8N("0(````!````1PA``$`OZK"&-.S^<)` +M2XM)I+/3^T`;=*-#!9=PHQH0*,I*7::O\I.=;ET&/+YY'JU`YLUMP^K]SZV0 +ME_#\HJA_,,W)!3(6#K5-N$20#[*)-HENI+EWICKPK+[78>H\C?@80GSM+CH6 +MG)6=A^Y=P6XOW@\T8/E`JWNL![2&-T5YJ7(+KB,RT70Z`.P/AAZXQ-$4@&A= +M4VSCF"++%8*'? +M<)9@=T-;OY@"48#B:>KIDJ_H4Q.W1B'I!@`<`0``'`$```(```!%``$8A.L` +M`$`1``#`J`$!P*@!`@'T`?0!!`?I5=XOG8,`3-I>!/4+ZUB7]BX@)`@````% +M````_"$``.`5?K+-5U)!@]+\*/'528LD"D&".6+Y\TT/0[%R775ZIB><>GBI +M!-3TFL.:'E]B6%+K=>(\]C3M3XWQ'A8VN5/"=G\0D`UOL0M#^Y0,3"UBQ4$N +M1K5U':A+S)3K:;BUR!S7\_!KO$@6)-G4R\'0_T/F6<%:!!P+%6%W&+A=[[)Z +M[P@14Q.W1KSX!@#L````[`````(```!%``#HA.P``$`1``#`J`$!P*@!`@'T +M`?0`U`:Y5=XOG8,`3-I>!/4+ZUB7]BX@)"`````$````S"$``+!6%,E7DA&1 +M#=#TE"4Z9%5K`@UO,?5O"]KW3>$G`!P$K1N$D0=Q)5J%0HF&ZFGCR$81&IMN:7@W.5:Y"AIX8?VHI!/4+ +MZUB7]BX@)"`````%````S"$``+`]^D5W_3;<'9OVJWVFR64:V.^]#;S)E\]M +M9NT&S'OZB"J4%.[_SE^U*&"`BX/SVAC\4A]01_J>$$B=C":*(8T*WSHJG]R4 +M5-`JTB7/P5.S-%ZG'6K&>"E:DP>I`XQP,.'*-`DM2V+I#L^A!E)(,G"T+SBYCY9ASN>57E:U53*T,^V4>!'D<=34;!$ +MU.]&R@,_K08).AD[4Q.W1H8Y!P`\`0``/`$```(```!%``$XA.\``$`1``#` +MJ`$!P*@!`@'T`?0!)`<)5=XOG8,`3-I>!/4+ZUB7]BX@)`@````&```!'"$` +M`0`WXGO"]T;O)N636JH!T]#F=:]1V'QA*D^1RO4W,6#8$6F&,@0A=P76=?X!S8U +M7!Q:.;F;E%\/&>_V!O![G-N5!4U-ZR=*'\_\WQOW9QKW+4P7><]QH/8?2FEW +MLCK]R=CP7#IY7Y%>.F,3_S$E'X5:?JNJ69MD_]OV<8=U>Z4>#(DI`!S[A":3 +M%9$V8!*YMFPCB],&_ZPHG;73%B/YX`M!#?77$.MNNFV;U[YYNB)6Y_^#9(W&.V[4"'54< +M467T<(?OWH_`L5G:VA]3$[=&858'`.P```#L`````@```$4``.B$\0``0!$` +M`,"H`0'`J`$"`?0!]`#4!KE5WB^=@P!,VEX$]0OK6)?V+B`D(`````8```#, +M(0``L&5J4,_Q@&H.R8I#,22<=DE3 +M=(R5S)P>=WDN1A0F3@)G)PQ[0=&]";[7\Q"+3*+=+5$\;6$#ME0?)HB5B.IX +M,7NY;IZ!EN(+W[Y=8O-M-784^D'4EM8-D1:/ZS3'MJ<"15`'^(0F+OUX,!-UNY6[,,)A+ +M9>,"3BR=HCW4P%/Y98"7/.!B*;T[+;_1-=I[U4;>V.Y%SX^;CNYUD>/#(!L) +M]:$:;*1)R=]VDO7I,/>T\D:?0NXN+J^91Q=Q3G2_T2Q!;U(*A?L9%GI[9@`# +M#\=+Y4J,VG5@5P>S-@'])^7D@J2%/,7`=J``+S:#`G'`PW!_U5"0"D>CN@-KXLL_/J8-\>A\!L<_@>GL7Z +MQ4=9]:\@Z9.J:)O;KB.OO^#8@FG/7Y0@\;":&NG:O24*MX:YMN_T=MF'21D&(( +MM2.>B89_':UVW#=1FF/]*V.;=3/IZ+G,1%1XPISWVZ?M.A7?,P/:#HKB!6NP +M\I=R<&_>:Z-,!BT$(4YQI/T?$A-`0AZ+:=4BULUG4Q.W1K/4!P!<`0``7`$` +M``(```!%``%8A/4``$`1``#`J`$!P*@!`@'T`?0!1`!/4+ +MZUB7]BX@)"`````(```!/"$``2!"A^V[[>)AM6`$^PD@'C:)\7WBLMZB4^?H +M@)K<'8"2*GX@R"$?!)NW$E+M0C:9OW_&-B,V+=1[!Z5OJ$7W/36B!8O4Y$=: +M3L#$!YP4!Q=5!U9[Z`/8X#%3&.8?&:2XELX;K+1%M*Y(5?7@0?.,7[T%IK;6 +M[F#*L2_EE,3MT8^_`<`?``` +M`'P````"````10``>(3V``!`$0``P*@!`<"H`0(!]`'T`&0&28WO(75U9]WI +MP#0ICL'L4:\A +M=75GW>G`-"F.P>Q1IRX@)2``````````3````#"OJ*Y]T\F#J?-2.EZI>U5' +M$W8*G:NOF8_WXVJ[*^'_Z,'W7@#ILG$=QUI;H%,3MT8D%P@`;````&P````" +M````10``:(3X``!`$0``P*@!`<"H`0(!]`'T`%0&.8WO(75U9]WIP#0ICL'L +M4:Z<":U=E(>-66U4ZL_&$=T-PCRETVW=-3$[=&8"0(`&P```!L`````@```$4``&B$^0`` +M0!$``,"H`0'`J`$"`?0!]`!4!CF-[R%U=6?=Z<`T*8[![%&G+B`E(`````$` +M``!,````,'J9=O)XRN5QR-Z@F,;N+G#4!G[W1T7L&3"?#`(XE,_ULECU%$%V +M3PBT+Z$44Q.W1FH>"0"8`0``F`$```(```!%``&4A/T``$`1``#`J`$!P*@! +M`@'T`?0!@`=E\4$]F5`$Q`D``````````"$@(@@````````!>"(``'@```!T +M`0$`#`/]``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``%)V&5+H[ID76>A3Q-HR8 +MV8Z4`_!VBQOY`OXQ(_$JKC'PBU*FRK>8, +M'$2";R`/TTFQOEKLGX,/08\M+K'&E%5A&.T52!E).ST9[&];9<*2<9/O+HI7 +M*'QM=SG;U@Z^`%0&1$OD^\IM\,UR2H(I```DTW7B2[6M@G9R2$=ES!=2[V17 +M5*"3.0EPTUW0&S4WM>XI```<``!`!*Q^0"EV"-2^SZ.&(J:(]]-P"6;_```` +M'```0`50_.*4G#M&CFZ?OA74`=&\+*C3\U,3MT8&+@D`7````%P````"```` +M10``6(3^``!`$0``P*@!`<"H`0(!]`'T`$0&*?%!/9E0!,0)```````````I +M("(@`````````#P````@``!`!@````JE2,ZLVU-C>:KO(Y*NE,@_5>EN]E,3 +MMT;_0@D`N`$``+@!```"````10`!M(4#``!`$0``P*@!`<"H`0(!]`'T`:`' +MA?%!/9E0!,0)```````````I("((`````````9@A```@``!`!@````JE2,ZL +MVU-C>:KO(Y*NE,@_5>EN]B(``'@```!T`0$`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``%)V&5+H[ID76>A3Q-HR8V8Z4`_!VBQOY`OXQ(_$JKC'PBU*FRK>8,'$2";R`/TTFQOEKLGX,/08\M+K'& +ME%5A&.T52!E).ST9[&];9<*2<9/O+HI7*'QM=SG;U@Z^`%0&1$OD^\IM\,UR +M2H(I```DTW7B2[6M@G9R2$=ES!=2[V175*"3.0EPTUW0&S4WM>XI```<``!` +M!*Q^0"EV"-2^SZ.&(J:(]]-P"6;_````'```0`50_.*4G#M&CFZ?OA74`=&\ +M+*C3\U,3MT9.9PD`4`$``%`!```"````10`!3(4$``!`$0``P*@!`<"H`0(! +M]`'T`3@''?%!/9E0!,0)6(6HST?Y)^4A("(@`````````3`B```P````+`$! +M``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(` +M`$C.8BFN5)W4&!Z*3%N;[E&,= +M1F]KW$R]E-W_2ZHDU<#!LL_W+;7&\/9PB7]@<`KE761Q&F4O +MJ:I`%UUT`T&^(@-'G?[R_-R(20^:J:WL:QL'(;?U3P]%QHT^25TC*0``)(?$ +M##/-%47$Y*4Z8`9%JE5]^08TZ:S[(12S$7\\RM1[*0``'```0`3F9OV1[@)P +MG?>8+;*D'6R-_Y.*%````!P``$`%+6HCQ8K-X#\E5=C91P]<;=@XMDI3$[=& +M>I4)``P!```,`0```@```$4``0B%!0``0!$``,"H`0'`J`$"`?0!]`#T!]GQ +M03V94`3$"5B%J,]'^2?E+B`C"`````$```#L(P``T'P@B6:(5M+R-P-;"&#N +MRY(6U.*NT5+L>6IT"IM``*#M]Z[+/+`9/D13YZ174K350/>V/!='[]G>&/'# +M,[F_H305ZI@:C8:6:>O2R0!Z:>"B@,H^I:FD9;[8B&T%%FF=(,RG0Y+P\-!P +M7R40*5$^N$D=[8XQ2XF3F"!OZE:$/HZ)YJGYG6WC8I0[/Y&C`_4/`D'1/ +MRMNC)[*+<%(`Y'+2'B/[IL:8Z=TWH6U#_(-R`/Q_^+[A99\!I2_G>!!R'E>O +MV'?FB&?7_B^SL5,3MT8]K@D`O````+P````"````10``N(4&``!`$0``P*@! +M`<"H`0(!]`'T`*0&B?%!/9E0!,0)6(6HST?Y)^4N(",@`````0```)PD``"` +MQN`Y_5.Z!&D!-VPLIV1V2_(4A9TZNGV6(HR26*?=NKF(/):9!`O9IKG+EE)(ZLIV*-4['A^%U:_49Z&;J2`9TOFRL[]-(&) +MP^ZR:5ZZ:%!9\9)S_+FV$P>WA"2)%-70T^'';:^^MCHW;,B,+$8&#:(/3SB1 +M/,!Y:X>GTJAJ>[]'#9+#3A33'S/G-4<[;'Y<%ZR6YH)@*P&'CXL+6*M +M=6T(WR.ZZB#=%#RT996BN7K:7,;4.%@P'!R+*R_!F-&'^3;B;L>5K--GP0K; +M\B;;C71L3ZF,6Q&>+9VXM=H,2X3A'EA#VT$8]7WC+-Z\K]\SSKOR$(U7+\^' +M!6);/_0N6D]B=G>".^LL6_'>,5,3MT9;V`D`_````/P````"````10``^(4( +M``!`$0``P*@!`<"H`0(!]`'T`.0&R?%!/9E0!,0)6(6HST?Y)^4N("0(```` +M`P```-PA``#`=2^E\.6\1X9.!3D;Y;/(*E+5;H?^_!@@?0:ES4M-P./PC\(E +M-'BA2=9Y7I#6>;;:2=&S;;,>%957#9..APM@FXA&0]GI1,"GW-DGA"7X0Z]A +M%=A`P0L_R)NI\4!V6!$6F#13,Q\4E:"-O::HU"#`5F3JJ3KBM^%18[ZXD/UU +MD-B@#8/GAS7IE;[9KOF86,T!]/*VBJET8C,IZ(:M(VW3?Z_!=I('%^R+P/?23@7\4#[6[53&/[H!;4;H96AS\_PX;E,3MT9@ +M&@H`/`$``#P!```"````10`!.(4+``!`$0``P*@!`<"H`0(!]`'T`20'"?%! +M/9E0!,0)6(6HST?Y)^4N("0(````!````1PA``$`\&A1:%,X8#&R[/OU?%>5 +MVBH.21L+P8V<9"#M?&-MCI&I[A!:]T[K_^]KE)DFM)A4#JE;',/%0@H4R]&2 +M.X88'T3=,UFP+N_-S_QIY-G?-V07< +MCHO/H\-IU8!(AUU[(S^>5K?T)-"-9H*WD?L:#1.=P2/S!\31$V.^V13/2C21 +M?33I"X+/&1[EIW<@@6>LD`;?G0W:Q4,S;DL(=?_A=?9A=YS7[3M9-)*1L;LU +MCR:+0/*4`3E+Q7<$UCN*S3/LZ_Z0B@+(#O4PD*2:0:89\`DDH0!#38(GU#F' +MXDT=#]G"<[71$M@04Q.W1@0F"@`<`0``'`$```(```!%``$8A0P``$`1``#` +MJ`$!P*@!`@'T`?0!!`?I\4$]F5`$Q`E8A:C/1_DGY2X@)`@````%````_"$` +M`.#$*A'E:S6"K\_4C!H0)1NK[6[)"63%-9H]>2B[MU+IK`LUUYA9[,/CPZC1 +MBN'.@?3Z-?FXXW*<7S3HFW;(-=+GCE0^W1P:%(&`[E)-(D.9$ZIU[U`>[-KC +MD@LJ&=N+HHPP)I:TD];9.+F`]KV0.;!Z(K=P;"F"8Y&+-D'#U==8J&Y%>S\M +MOC,[BL<4P-ZE)QVV<5!PZ+YD0NS&\$80"EA94-I8B"9$,6D>,%40M1YS+[#A77BLNY6XQND[/P0\R0;+?%;\F0N9*O1ZZC;IAF1.&P2V9@4FV+3+UY +M\6BCIF5TV58_%M#F0R"--[,D+@7X027S0C@9_.T4@YB182=*.,51.391]H^4 +MQ1N(17+"'/3T,UT!`$AEE->?A:6K1RO::<)Z!8!QV0>7#3/"M".H4;W9BB/6 +M(J1*J90#!7`\9*17@?S-<=6;Z*.UPH``4Q.W1LA9"@#L````[`````(```!% +M``#HA1```$`1``#`J`$!P*@!`@'T`?0`U`:Y\4$]F5`$Q`E8A:C/1_DGY2X@ +M)"`````%````S"$``+!LFN)4;+S3#`Z1Q8\7-3(=)Z5XWY_0ZC8PK(/REB`! +ML\Q/S`7!R_R90U!"(2`5RCK6&HA;W_SF*"FPD;>2Z- +M\9#L@MS?4Q.W1E%V"@`\`0``/`$```(```!%``$XA1$``$`1``#`J`$!P*@! +M`@'T`?0!)`<)\4$]F5`$Q`E8A:C/1_DGY2X@)`@````&```!'"$``0"-,H\P +M68_$0^!EI#ZQ@1!%TSUMIMV\LP$=@;U,=]GDY[T\X!/ +M>6/4[3-*[P!"$>U45%]CYP)8%@7.@%$')I[.,.KK_S=Y&%2"44J%9,+K!YN. +MG@%[IA@YFFAP@'\^KL=L'Z\(WJ`^8,B@7R2C?9%#Q+M(D-"KKHQ-3[_A\Z;$ +M#Y?(,7BEFQ`H!>)H*!(N(@8C9JR2`9FJU!/;ZGCF7+QT@;GDZN:J1">T6'-3 +M`MK$])'KD&1F4JR@.G%J']VB,YT`KJO&Q;B#;MJJGV,;3H%]M@;S[JM'`!^T +M:,2!5"-GZC +M!8>)A2HN_;_:)X1 +M!>GA76JP['(3H>#$C911_D%/WB&[JI!D+T\X3-N16X0^UER5S34%,,'F$J +MAZQDX+?4=/!3$[=&8Y$*`.P```#L`````@```$4``.B%$P``0!$``,"H`0'` +MJ`$"`?0!]`#4!KGQ03V94`3$"5B%J,]'^2?E+B`D(`````8```#,(0``L*0( +M\Q(G;-=WLK34R>P[L)O(^$U*YO(49R9U]-IVT0!AXQWBJ7X/=$0EUIY)7:+F +M&G;V[XJ4P436\.<+!P3D#`R-M0FW]U8%A"8>*3[=VLD^\S7;&[(N9KNWS0F. +MLU6<8HO:WO?AHO;B9EGB7&,B[TW:\@M]5I05I694&)1*@YEW##<1GOI944%$ +MR!=ZA-F]O3@"-K"\IY<7?LA&ST_"I=K;:CYFM8AN)T3,$-MIYMM9 +M[^$QP9"4""!G%?]-S6=+R;"U2P+"QU*N,,\GI\7-9,FZ'A/E!_83]L$$#T7) +M6,ZCS13U"8#Y1+,=T%VCSGA"!8?#J[\(K(^Z'=>-U3M +MB62()!Q7IFK(][VXV&R,.$Y3$[=&TMH*`(P!``",`0```@```$4``8B%%0`` +M0!$``,"H`0'`J`$"`?0!]`%T!UGQ03V94`3$"5B%J,]'^2?E+B`D"`````@` +M``%L(0`!4+!`6VU?9@H*D+_%&F073"LHVXE"R]*!G +MA6N&E>O%-[;ZU:Z+LI+:;4USQ!=9RUMH95LQ\+MGA]%L6X0:4)N)!IU@/0`^Q&9E+O2PZM_'#J/C'X#4,"1`XM4@9SB`Q)Q)&-?YY).VK2C^.9!;M +M]R+KZUF06M6YP2'2_K4E?APNXR[^O>0C2*L[& +M\A+PH&BAH7`D-5B88#E`XA!>12;0G="J^W_TZF:F\.5*.X41*F>&$`VT.KY0 +M8GA.2MMS9<'`BD(8W-04S$8>[3D[ +M7'C2BU!'@HBIG-!KGC/$A5SEB;$(J6M!4Q.W1MP/"P!<`0``7`$```(```!% +M``%8A18``$`1``#`J`$!P*@!`@'T`?0!1`I7AD$'DKAFO+_R/?M9!3$S>4$IH +MCHA.Z7$9VH?IW%.M14M_XF:SW]IW/%$^2#U4'?J509)P]S? +MU"=QN;?^CYRCP%WNN++@$2B0A/138OODF]<2Q,8[@EAOSFE6H*CNB8<(HB$4 +M]3%MQX'R&E`1`WR0F"]U/Q-!#!A<,&NDL!-A?54L=Z/E\'B&%I@F,-HXS'"OP%AKCD80<'L]5WX$L'<7DO0FG+/OXBJV'9T,"NH38 +MZ^)R,*^#:`KUWX).$5HVJDXM314Y_5ZY.GUE?0[HCJL:;2@6Y,I,,+4O-/8= +M)B!R$$!W:LJ/G]IS`N?-S_0)0J:2&'?B[>O+.5,3MT8S-PL`?````'P````" +M````10``>(47``!`$0``P*@!`<"H`0(!]`'T`&0&22S*Z&M[`&'"V\2M-8_L +M2[#-QRE +M*`L]WT8L_WW20\Q3$[=&UUX+`&P```!L`````@```$4``&B%&@``0!$``,"H +M`0'`J`$"`?0!]`!4!CDLRNAK>P!APMO$K36/['-)+B`E(`````$```!,```` +M,*A%XEJ5DQZ$.#Q4(95O?BR:(5,#:N=JK!I['+I]D\QD+*FMH!:KKLO"QJ;S +M4Q.W1HI:#`"8`0``F`$```(```!%``&4A1P``$`1``#`J`$!P*@!`@'T`?0! +M@`=E97O@[4\;W6H``````````"$@(@@````````!>"(``'@```!T`0$`#`/^ +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``2D4G@K]@=Q)U]KK/MT@>,M9:8(^4 +MJQB(!;0J0,@3+-4JITIUU_)[)8^6AJ=R[&;O_-I_D#>'>:R*1P>.=!,A.MTZ>NF +MX)4E0$D*BK)?D+I@0J_F'54I```D:`&?E%T[B9NVYC)[IG"`$M_TO\=+L;K, +MW@88=1QL"1TI```<``!`!,4;A:YLZ.(8&O[;"]I'`IWKR*(R````'```0`4K +MMZ[].>-E]\GM-X$)86M!4SFWCE,3MT9_:0P`7````%P````"````10``6(4= +M``!`$0``P*@!`<"H`0(!]`'T`$0&*65[X.U/&]UJ```````````I("(@```` +M`````#P````@``!`!@````K\+.)I@9$!$\I_%N"L0P` +MN`$``+@!```"````10`!M(4>``!`$0``P*@!`<"H`0(!]`'T`:`'A65[X.U/ +M&]UJ```````````I("((`````````9@A```@``!`!@````K\+.)I@9$!$\I_ +M%N"L,M9:8(^4JQB(!;0J0,@3+-4JITIUU_)[)8^6AJ= +MR[&;O_-I_D#>'>:R*1P>.=!,A.MTZ>NFX)4E0$D*BK)?D+I@0J_F'54I```D +M:`&?E%T[B9NVYC)[IG"`$M_TO\=+L;K,W@88=1QL"1TI```<``!`!,4;A:YL +MZ.(8&O[;"]I'`IWKR*(R````'```0`4KMZ[].>-E]\GM-X$)86M!4SFWCE,3 +MMT:YG0P`4`$``%`!```"````10`!3(4?``!`$0``P*@!`<"H`0(!]`'T`3@' +M'65[X.U/&]UJ+,$`75`V-M8A("(@`````````3`B```P````+`$!``0#```, +M`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``"-!*W>@ +M8;-(L%X*<<2`\D!B1E*VIC*?E)J($W!2,\5.KW,BG+=6.H)H9M1^&`\_KF.I +M-TM9V4`F`SC-U?3RV^JL.BFE59X@QP0]Z$ZP3_:E$G/*XXP*S3"0Z$S58O@M +M*OZ)6,)NP'"VEVW!L+H_:N89UV9-_=5]L?RV%P!XNB"/*0``)$[D&^%]/-/; +MB/&0%2?<0D@=@<]B8.B9L2,.'@#9=28'*0``'```0`10^VC`8F2V#"O#]O$X +M&20;T13%!0```!P``$`%9T'_+(BBJ[8>(HH&$+0?;P.I^DE3$[=&V,H,``P! +M```,`0```@```$4``0B%(```0!$``,"H`0'`J`$"`?0!]`#T!]EE>^#M3QO= +M:BS!`%U0-C;6+B`C"`````$```#L(P``T$+5%OA#U:;14-BP1D%B-V@O]X&2 +M_S^S63J6Z68O*J`6$CA($,&O,F,)IYA3SJ&_YRKWX%O_J9`)B9*5W2[9&"21 +MLP@IH2O/'QQ3]K@IP?;^P8#ODK7=GA$P%WY4< +MRFL\Q9G^J[A#)IMY-I!@PY+%_(WSO-.UG@Z5SXT%:]VH,` +M8&J(*E,3MT:[XPP`O````+P````"````10``N(4A``!`$0``P*@!`<"H`0(! +M]`'T`*0&B65[X.U/&]UJ+,$`75`V-M8N(",@`````0```)PD``"`HJW9BP%. +M(Q31Y;%".L`JN.>3$T/1>FZ`:_PEM$W*3*%;I*Z4$$"4(S9+ +M!7<<(?([<;G.#Q7$'"O_H)3.UI"/,^^"Q>$1&U,3MT;D`@T`'`$``!P!```" +M````10`!&(4B``!`$0``P*@!`<"H`0(!]`'T`00'Z65[X.U/&]UJ+,$`75`V +M-M8N("0(`````@```/PA``#@'.=L#<%P%"?P(N>:%Q]^-3%]&$^]S;*WNUG.]%L2X\@OI6=SI2N-V]XW/.57/\S`ZL#; +M^H]V(S*;[2UP&PK[S!9!7%]C)BLV\$%61`G@M\,@&^#M3QO=:BS!`%U0-C;6+B`D(`````(```!,*0`` +M,)(@/)`>FX>)]<%[=PD#GC"V'&?@D]X'O$9_C$`(J-P'4B=]1\ET(IWA6A54 +M4Q.W1OHU#0!L````;`````(```!%``!HA28``$`1``#`J`$!P*@!`@'T`?0` +M5`8Y97O@[4\;W6HLP0!=4#8VUBX@)"`````#````3"D``#!T\"C0S2MF>[#"2>E,3MT964`T`/`$` +M`#P!```"````10`!.(4G``!`$0``P*@!`<"H`0(!]`'T`20'"65[X.U/&]UJ +M+,$`75`V-M8N("0(````!````1PA``$`!CJ^)PZ`;+A\7(+BQ5AGXHL +MT>?>MW3GY50A&CFVF&^NU/?&9L]_(,4*^5;^0"ZY@6)DD"![(TP,B#%:[@I5 +MS$\FF+5;4Q.W1@Q>#0`<`0``'`$```(```!%``$8A2D``$`1``#`J`$!P*@! +M`@'T`?0!!`?I97O@[4\;W6HLP0!=4#8VUBX@)`@````%````_"$``."B(:*V +MV^12]:?]_;A>8GS"-L+8=TDJ^*;'TL,X5SVVAF>.XFS83*'C!FWJ-:K3\CF+ +M.0,T>+`"BMXGOKLP9#N^:0LTF[UNH[U#\ESX237F)51?P",[V[1;_T.QL`"O +MFEUC.+_+#@WW6PG$\QK8D$4)!+&J6U>TGT4-*R)28*B%&+\\J,@5ZVR!Z2NA +M@1#5,(K_"@-^3@)]#!15]S[B!ZKZ@6JHPUB?%V?+)(5FRF*>>L>0T(CK.7K# +MOET-=@WC.^I3ROGYX@%OXQM3.:3!=QW,I3T(?JNJ,IYI94=A4Q.W1N]L#0#L +M````[`````(```!%``#HA2H``$`1``#`J`$!P*@!`@'T`?0`U`:Y97O@[4\; +MW6HLP0!=4#8VUBX@)"`````$````S"$``+"[<VVD,Y5R)NUK +M51>REU;.ZV5F(";N=T9OCMU2T?[#X;]R5F#+O*28-\C`C7TK,FK:#$@NYBC_ +M<]E*Y#J'SC#D"@IKP%7R?Y37N>\,7[$.%H$2+7H(V5'@D=E1))+Y(^=Z(/DD +M1QL@HE%85`L[@Z$X)&KI!DL4+`";0@XKS^34]BZC4.,2=7^[%GCR\DFPL+"G +M_B[?U;^9ND`J*?-0H):U2"3J4Q.W1D2/#0#L````[`````(```!%``#HA2L` +M`$`1``#`J`$!P*@!`@'T`?0`U`:Y97O@[4\;W6HLP0!=4#8VUBX@)"`````% +M````S"$``+#4N!S%@@?S08D[$R!=>2EJFJ<6:2BZZJR1G.ZE_ +M*OPD3=>6*<:E56O[9_CR?;R/%7;D\"*U1AG5W[;41.(&<12MSI(B-R*<0])8 +MLF:JHY(8VZ;L"\N+)4#W'RSTV$[:6;*L)HZ4VG)^12^ZH3W[13.Q71!>X8HN +M4Q.W1L.L#0`\`0``/`$```(```!%``$XA2P``$`1``#`J`$!P*@!`@'T`?0! +M)`<)97O@[4\;W6HLP0!=4#8VUBX@)`@````&```!'"$``0"+X-.5Y6G(SO/< +M)M:46`DXV*!Z<36YV?E`F#C\:[. +M8?%?HR3`6C,>)4YU!_GZC]0@J3&.D;1M$B+^=5I8!+R +MR\_D276QN>;*C+B'E-=\G"T3D^+1?[X4&VC+DPPL[#9I3$[=&"[D-`!P!```<`0```@```$4``1B%+0`` +M0!$``,"H`0'`J`$"`?0!]`$$!^EE>^#M3QO=:BS!`%U0-C;6+B`D"`````<` +M``#\(0``X)>1ABP,>>I6SK;B(E04C'A_%0'IBM3M\0";<#0[4`?=/SPY!?JN +M&OU&1F>YZYAKY]X2U_23LWS;)=*KWUMD9DM11Y!7:YM40%K:5CWJIT#,&+G\ +M`I>2UXPP5Z*"XQKU=6%S9NC@"4!Y][I-6>8`E76(>*B$/(OOJ.34/$6)D+S'F"7ZE(G%,O5A,, +M!UB(I]:#5--6EJM"*[B[3]3)$B&U&ERM)$M`,&B`DDW)W>_ZYB>PD#76;F4J +M!1A3$[=&7,@-`.P```#L`````@```$4``.B%+@``0!$``,"H`0'`J`$"`?0! +M]`#4!KEE>^#M3QO=:BS!`%U0-C;6+B`D(`````8```#,(0``L&X9'DL..+C< +MBPA5A=T,1XZL<-0/WSUN15$<]Q!1SUYUJ&6G4^S>_RG>]EXV'&FNEMSVYU<: +MEK?V[1NU7(TG`'="3SL*TB*PW+1OY[G7L^K4$$>TL`-Y,@:'EA=NC)J]'=9I;@S]\F>Y29K?;J!G-BG2TQ)S +M_>5?J^>'Y##%P645KA104(-7)=XVE^:JWB!D(NE3$[=&:NH-`.P```#L```` +M`@```$4``.B%+P``0!$``,"H`0'`J`$"`?0!]`#4!KEE>^#M3QO=:BS!`%U0 +M-C;6+B`D(`````<```#,(0``L.C.G]1]G>0R*>1",/[EK<'7"MUTS$0\@0ZS +MW]%[4=)V)HX5YF-:>AFR&2687>+5VCN(Q_\@$;2JPR3L%-&V]:S&>01L%CV[ +M%`O1X`@J_Z_UH1*,Q8?FL7(`X_5K9'Z],5G7<&^C2!IWV5T:[AYI&1.W^DC' +M>FFH"VS_$^"1QJ/]5'=%7/C(+G\]`ND2 +M(@FP,(;M[.X]"AU3$[=&-Q$.`(P!``",`0```@```$4``8B%,```0!$``,"H +M`0'`J`$"`?0!]`%T!UEE>^#M3QO=:BS!`%U0-C;6+B`D"`````@```%L(0`! +M4*7R/&6\44J=*4O#&W3QUDEK/)^T.,[:MKSC +M?E4U\<,^@GR.<`&&A1:*_Z.M@!O.Y]*-)<&XBV.W"#K:$^27@Y_TP%J%U,7"J4^QN!]6@,&8^G9172IG[C:UL1+\\6 +M:O0;\1H"\6>%IC@?=6%A+F^MK4\KAQ,+E^&)!\'Q.X0O+TDQI!8KH.8\/F3J +MJAAU,)X85G1?)UK`=V6[FC[?^)%$KG@&#SQ.@I/.WVV?'`/1K)L+L1Y"DONH +M+6U5+A3)W9Z?'U,;!F'"V=Y81;YY"'6$9Z=N$;SNOI=I,EQM#$(USC+UD.>] +M6`\XI=66`D"U2RAR\XA2):&L4Q.W1O)'#@!<`0``7`$```(```!%``%8A3$` +M`$`1``#`J`$!P*@!`@'T`?0!1`,5[U6G1PQ/5ROA!3R>XVU7[Z#;6PM#BJS\Q&`HNM>\8H7L[ +M3.\/ES\7E^7"?P9"I!X\XY-/!0V1\#(=TN!V):G3P?[`D=X%<@B46$)N'!W@ +M:*2'.X=H,Y9F1C^7XKY8>*$4];\RL,5V[.==,J([WQ8`B;O7JS"^(4R``!`$0``P*@!`<"H`0(!]`'T`&0&27>I7\4$&*F4\&9EXE-Z"HXN("4( +M`````````%PJ``!`:Z(-#X$WGK?.5WG9O2HM`&[@48B(!*639\32-OOGB9FI +M_+/V_UA4!DN)R'/5A?Q3Q?'%9!1D'@4N^]CI4Q.W1@-[#@!L````;`````(` +M``!%``!HA3,``$`1``#`J`$!P*@!`@'T`?0`5`8Y=ZE?Q008J93P9F7B4WH* +MCBX@)2``````````3````#"@D(2O/#R`;3Z(/]]JII#]P4R*@5G(H6+-$<27 +M_E7=G=ESNF*3AWQ&&>2@UE,3MT:DB0X`;````&P````"````10``:(4T``!` +M$0``P*@!`<"H`0(!]`'T`%0&.7>I7\4$&*F4\&9EXE-Z"HXN("4(`````0`` +M`$PJ```PH0'J*-?9L:+JAXO(?../[A&T!?R)3>@J.+B`E(`````$```!,````,"U2.V)> +M,T"Y`4%!&.>=W_869/\I%52AHRV@F'+"\0!N(&^E<@@L$)2L-:"(``'@```!T`0$`#`/_``P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``H_IR"JUGK_-UKJ673H=P&5F[C].VP +M,LM="4YOMV4Z<1HE(_O^##1I"U1/FK7Z:HK-J+>.-A +M_L9F":*HU:H&\>XG[EPRDCKS$C$4A-HR$7Y1;50/`]=XZ?9*W/Y%'1CXNTF3 +M$4\4?S+Y!RS2O8\I%03MT:3;P``N`$``+@! +M```"````10`!M(4Z``!`$0``P*@!`<"H`0(!]`'T`:`'A0=8M@YIV/D^```` +M```````I("((`````````9@A```@``!`!@````KI*_QX.=N6/2IC`W\\3>RS +M2O8\I"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``H_IR +M"JUGK_-UKJ673H=P&5F[C].VP,LM="4YOMV4Z<1HE(_O^##1I"U1/ +MFK7Z:HK-J+>.-A_L9F":*HU:H&\>XG[EPRDCKS$C$4 +MA-HR$7Y1;50/`]=XZ?9*W/Y%'1CXNTF3$4\4?S+Y!NYN)]-:'X#;:I_,,3*+E0:1QM>K[H/4M(PBRQ`M.#6?L +MEB-HKQ_<%#W\#.]XNWOU;'G&\HUI^^_&P@40*0``)/.F4^^U9.`%"&IQ_C!A +MZ?M0(`E5U,!.+*DXKPT+/1J1*0``'```0`2[GPT*JR95@W.R$3G)'BH&1?WK +MP0```!P``$`%EWP7U<2X-8"GH&_+$ODUV2\9);54$[=&M<(```P!```,`0`` +M`@```$4``0B%/```0!$``,"H`0'`J`$"`?0!]`#T!]D'6+8.:=CY/O8/B.8B +M?,7R69/&WH23ETES3)+9>X(F,1*TB8W,LXA;S%/R8>]>')RN&M;4"K*N6H" +MTQZN0+0Y24V(M+]#(L&E':,C:X8FJ&(Y,>'.N*#B: +M1/.N1I,5:Y&HF$Z$A&\V_AL]7DUW"X?<^I5=M-MC'*CL75]3JW/JAVA>T6I? +MY3GP&=B2EQR8WE?-$K[L_H')X)P`"'%Z-[=:!1G'E""=JX.W<3L)0]G)LE03 +MMT:\VP``O````+P````"````10``N(4]``!`$0``P*@!`<"H`0(!]`'T`*0& +MB0=8M@YIV/D^]@^(YB)R&O,N(",@`````0```)PD``"`W>K2WRP6#&SA- +MD[&O7&DQ6*]?_YX3K`51&`^J==PQK^0LK,;39%B:I$CJW1O:02AET_(CV$TM +M1TJ]=#6M".#W$][H47[F&RC.F4M_;'R2(IKE$C>EM#(]^$NP62;*YS5M6[.@ +MANRZL8=<>Y#"]R3WA3PU;/EQ>W_!\%03MT8/^@``'`$``!P!```"````10`! +M&(4^``!`$0``P*@!`<"H`0(!]`'T`00'Z0=8M@YIV/D^]@^(YB)R&O,N("0( +M`````@```/PA``#@QY=23`1R@-B!^@MEVOQ[6\_D'B9K,5MAEE/OO9"'SHL, +MZ/6>%4AS%U_OS!Z@&P0.1@=\K1462C(`KC1>91.F(#G!3,#C?'Y%@(LG&`;\ +MV,75T1$4WYADPS:XL6<.ZJ%RJ4?`584'8H>OXZKJ+:^'N)L$FSQ +MB@F^UKI0/L-+J$O`OND,H@)5>_E@R+?W#;%@L:.;6?\G,'ZRPH$F1]+*DAX5 +MB;->>((LW%03MT9#!@$`_````/P````"````10``^(4_``!`$0``P*@!`<"H +M`0(!]`'T`.0&R0=8M@YIV/D^]@^(YB)R&O,N("0(`````P```-PA``#`(`.& +MO[?M^O?/R3ZQW_YL^\6ADE +M/8#2NUK/9-!'S$[')_@I,5T*DDA($=\>.11I2E'V6N4X'6MC_FF-Q)`$P\BP +M,MJ96QT-W/:E@?-[?A@;3:1.&"-8QD +MX9>+YR/A]8B>9WI"Y]&6962KX=Q1&5)T5)+"!B!`A\O1"1'G,+O@"M2=CL'C +MY#'(:S]4$[=&!1$!`&P```!L`````@```$4``&B%0```0!$``,"H`0'`J`$" +M`?0!]`!4!CD'6+8.:=CY/O8/B.8B<+3EW.!)W@AY_$.IIL7<_I5!.W1D(M +M`0!L````;`````(```!%``!HA4$``$`1``#`J`$!P*@!`@'T`?0`5`8Y!UBV +M#FG8^3[V#XCF(G(:\RX@)"`````#````3"D``##3PW;'6J-K9N%G91!#PNF4 +MP[&E&."%159!KYXGW?>,1/$+ET.HT?DV5SSOD`Y.-&2XU]>R;^ZCPVM/VMP1G&[JDW7WFN/VI$&[Q/SOHT-^*4A,"9]&TT#\" +MB6VE+NX'/+X) +M&?=1Z!ZN$/MR)\$4`ON[KDP#8M-SX0B$!E>\ZN.G>E[C(WTCHN9X/(BLOBY) +MOPD=A613/',UX/I9!SH*)"(U0Z.FO>QS39+E8U;_HO_G<54, +M`NZH,><2KP07F41M-5_ME[5*?C_+0HK8PQ;37,FKQO_OYV[4+B9#@XIA+0B[ +MHU$(!?=-L[?-(75NI#L4:Z16$YH;1CS/T%8Q)`:N;.695!.W1FN'`0#L````[`````(```!%``#HA44``$`1``#` +MJ`$!P*@!`@'T`?0`U`:Y!UBV#FG8^3[V#XCF(G(:\RX@)"`````%````S"$` +M`+#2OQ>QGP"._^H.K\6I.5S65?411;LHFFOZK\'5O-BKQELCP0N:4X)R7#FP +MOOAK`WA+CQ^`?;89J#Z<$\UKO;$"I],M@_U!MS!>\DB7OEN[5$'\O(CO9"^= +M=]%C&6_IQ'*2Y,AJ]=,%Z52Y0W4#<975L(QI+H"X)%W]8YQ6VB'$_PW&6$]P/OD8RZ?W#L(QDQ,+JU3$6*LNS!KKMOOYV(6(9.28F$D:>M +M00@,Z[!&.OU&$T2U6S/[QC>BK&'!U>KVB:B[W0CJQHAF3#6XSR9%DBL\IP[1 +M5AO:*U`:M7)GB9U4$[=&\J\!`!P!```<`0```@```$4``1B%1P``0!$``,"H +M`0'`J`$"`?0!]`$$!^D'6+8.:=CY/O8/B.8B +M_*`Z4+H]+,Z_A'#S-BNY2=,,&\J#N6-8KXN(;LH=+;F6E$T4[_\?E?%4$[=& +MJ;\!`.P```#L`````@```$4``.B%2```0!$``,"H`0'`J`$"`?0!]`#4!KD' +M6+8.:=CY/O8/B.8BHBK0MB\]N)^6FW/STB;E93T.^6IQBJDPJ<) +M%ENP4YU>"[*O@6`T>+Q)H8-WDH4J*"K<`L^G2*K(P@_0(WWBNYU,L+N2RO1- +MI*$SJX:&UMRU*EF*2_\KM1\Q1Q\[QR#$?UJ9">+*R(!+R +M33UZ:U[6Y+2L22!-:$H]BH7MO#$M`_L.?SP;NY[JFXS%8#1C&+,'OSM_\K&5 +M'QL[\O6-@V*D6'`^]"K:V*OG+:^$R;Y5;RDC6WP5)5:.G8[[P]]`X_@KA9+& +MR"0MXHZK%]]-T4)]%PDJGA`Y2>@9&D5C$1;D[#H48D@$$"#38^'2:YCU^T#> +M.#YVX754$[=&"@D"`(P!``",`0```@```$4``8B%2@``0!$``,"H`0'`J`$" +M`?0!]`%T!UD'6+8.:=CY/O8/B.8B+50##.'SQ\2'X,$-_N4E8=J"+*Z6%].%B,!)\@/K;DF5>]?"QF%H7TUHJX +M4[N'S.>KG#NTAZAD)?7`7W2Y(K3N5@R%`J='D%D`KS" +M?2F!)(,/X=-:*9%HO1L!#M#=W1%#CY\-\ +MK:P:B<73HZ9,?>DJ18W'RYN/HS/[2X@W^'!'HZ05=-,BI)%J*KFB>6,3)#27C`NU;H%9*8,OZ%$`=7ULC1(:H=[8KHYPTQGB/+NR3'B0[)/UF +M095]M8O4!XZ&(2([T`\I$,_\4-0BQI6(NX#G@\\1(2S"J<110R,("@PZ$SX_ +M0-?,&`-;-=Z]=Y01>E7M7"6FL__"!3;G<#VM%^&-7B/3^3D!WI&P'6KE,29, +M-@1(!"EY(<<_=UF*6VPZZE03MT8>90(`?````'P````"````10``>(5,``!` +M$0``P*@!`<"H`0(!]`'T`&0&2?XFN_+YZE?KX.U"7+Z\9C@N("4(```````` +M`%PJ``!`&9+S9%'$[2$?\8OX1>+]9:*;)V[P>_?V_C"*.6V[[//`71AFKH#J +M:0S5A*IE>*1PV_O;^$K'O"Q_H";"5!.W1G1P`@!L````;`````(```!%``!H +MA4T``$`1``#`J`$!P*@!`@'T`?0`5`8Y_B:[\OGJ5^O@[4)?0G#4JYEN8=YM.80!5*UTL90!C-"WS_0R:RA4 +M$[=&L8X"`&P```!L`````@```$4``&B%40``0!$``,"H`0'`J`$"`?0!]`!4 +M!CG^)KOR^>I7Z^#M0ER^O&8X+B`E(`````$```!,````,+.I0E,,&EP`;WC; +M3;9VM_XH!!2(Q;TOX.1\S``,YH<2>-/#JAMT:Y+I#9IL5!.W1N:,`P"8`0`` +MF`$```(```!%``&4A5(``$`1``#`J`$!P*@!`@'T`?0!@`=E1Z%IZEH=NJH` +M`````````"$@(@@````````!>"(``'@```!T`0$`#`,!``P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``D\CEL%3K/&V:S,0/3!CHI/65L#&ZF=7Z;TYY%8>8*^9F6?Q(P&JF\UU,=%FOOG`LI8(?IT:F@5\? +M-PT-W_0I```DUF,%)Q`U+G;$9GL$%LWTLH^[N+`@N&5;-C7ET-<+?O`I```< +M``!`!!+'/5;_2+:%,(7%AFH656)*<9-W````'```0`43UYZ)E#)L=8FCG55K +M^`+>>;CC)%03MT;JFP,`7````%P````"````10``6(53``!`$0``P*@!`<"H +M`0(!]`'T`$0&*4>A:>I:';JJ```````````I("(@`````````#P````@``!` +M!@````JW!9$A:>I:';JJ```````````I +M("((`````````9@A```@``!`!@````JW!9$8*^9F +M6?Q(P&JF\UU,=%FOOG`LI8(?IT:F@5\?-PT-W_0I```DUF,%)Q`U+G;$9GL$ +M%LWTLH^[N+`@N&5;-C7ET-<+?O`I```<``!`!!+'/5;_2+:%,(7%AFH656)* +M<9-W````'```0`43UYZ)E#)L=8FCG55K^`+>>;CC)%03MT:$SP,`4`$``%`! +M```"````10`!3(55``!`$0``P*@!`<"H`0(!]`'T`3@''4>A:>I:';JJ6'*X +M_<$SAH\A("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```( +M`@```@,```@#```"````"`0```(H``"(``(```$A>TZ_FQ+.0W`IJMY+2/4S +M`RU]:C?^4`*@PEX\XT0P(\J3AQR3:,)CNQ1F)T3P;JB&V\+?^>WZ4^5)"5,2 +MB9:$:3:CY>*)%T^"+Z(^JWI\QUH]BGD./DV>QTG-XQ97A=70::+-X`@VJ/S3 +MKX)R.`,9&/Y=TDBFB1!9>@X^<54=*0``)$0?JX::P[8:WD77>;UJ.D`5C$<# +MAZWX27@5\W;O>D\Y*0``'```0`2@$]R+VRG^"$,?JB3_&.A,[HZ=T````!P` +M`$`%0/GC%,M=Z0V#$BN)*'Y2#[.D<&Q4$[=&/?P#``P!```,`0```@```$4` +M`0B%5@``0!$``,"H`0'`J`$"`?0!]`#T!]E'H6GJ6AVZJEARN/W!,X:/+B`C +M"`````$```#L(P``T";)"YPJ@M\HO!W!'+*8"*RN[ICPOSBJ!645WKQV%0"# +MNU%;.G3^L6CMHH.\-'".S<9!D8FX8)_3QTL7.K3U@HR#]P7.X,DP'#X'%G7) +M)UAYTZU4Q*+8'_Z&@?)=A0RBUOU!I57V47!!S#4(LN#3#9\__V"0_VY/YGC< +MT6Q[*?.(H-EA4>7_&?OR[""\6I&'OE&+/;P7F;5F)1OCAQG>#([:P!*]GPX' +M6K-I:A?E#$_.A`I,](SZ)IUI]X:1H$C']J4]R%N[2L[-5NBQE%03MT8(%@0` +MO````+P````"````10``N(57``!`$0``P*@!`<"H`0(!]`'T`*0&B4>A:>I: +M';JJ6'*X_<$SAH\N(",@`````0```)PD``"`K0D-*6A<5,'8JZGS,O-C:Z8L +M-JZUI?S?,SR\+>4NZ#RE!HOE=>RP^"WH[34H+%'=J?3(\OX?&E7HH2E7]XA9 +MBQSNM50Z%DD&($AGF08R%ERK)"?-/0A2>YWI`C%03MT8G-00`'`$``!P!```"````10`!&(58``!` +M$0``P*@!`<"H`0(!]`'T`00'Z4>A:>I:';JJ6'*X_<$SAH\N("0(`````@`` +M`/PA``#@0$Q`+"OG+L]4-Y!WB6XYKP+QLFN!L`H43U80*N)(C8[$/_U'Q`*J^25(G\E38+%"];QS7$$6_..\E(DG]*<@0I#,; +M*FN1NNT!00<($+=\NZX/#ZWVD6\$1.\)=I@TU>NC +M#0^K=ZP+BCR^ES2AX:.<.Y-;O#>&?F_*#TE`#PS`,/TA9N4EZ%5X2%LE&-Y& +M?.>BI9RN8+SDZSS9Y8`=-,*.JDM>Q)O(X]-A:>I:';JJ6'*X_<$SAH\N("0(`````P```-PA``#`AF\&T[SA;:W* +M?D)T9^#X,'G];*BD9H]FNM&]6.ELK2N>[:ELL[MQ<)D\!D4>[W5-"E45#DN? +M+"GEJ,[_8^%'$8SJAB=)F1ER3'!\[H0*L4KU0ZF\RK5_32M4 +M$[=&]$H$`&P```!L`````@```$4``&B%6@``0!$``,"H`0'`J`$"`?0!]`!4 +M!CE'H6GJ6AVZJEARN/W!,X:/+B`D(`````(```!,*0``,'EK^+`VDHL(/9TL +M5=12@<(J<%M4N1&*(9WFM[N`Q%HR=*W,Q/HS57,A>,`O5!.W1J-F!`!L```` +M;`````(```!%``!HA5L``$`1``#`J`$!P*@!`@'T`?0`5`8Y1Z%IZEH=NJI8 +MJ9;9$IYIRH2#95:YT[2&RUY+E.%03MT86@00`/`$``#P!```"````10`! +M.(5<``!`$0``P*@!`<"H`0(!]`'T`20'"4>A:>I:';JJ6'*X_<$SAH\N("0( +M````!````1PA``$`PS*\)5R4(!1>CA-74`7#IA_Q96F**\E&8XJ)L"ITA5TC +MWMI(,8@A,E#;:>0A*E9_*FRE5F^G)A8!NIF54T=U?"P0CH-;]FD#C3RS!'^1 +MQCPTYB%!:E0+=%;PA3XJ&T59_+&?TCXM_7&=CX_O'MV)!ASR-5\SW)6;108] +M+YOQ.BFN.7I(@#0>36P%& +M9@G''%\?=?&F^#2-?U70YVQ)RCBB#2?Q5!,0@WP!XXHGC\-/`,9"5!.W1A*- +M!``<`0``'`$```(```!%``$8A5T``$`1``#`J`$!P*@!`@'T`?0!!`?I1Z%I +MZEH=NJI8D?V"1N^ +M59<.WYA1#.B0#QH3VBE.`6O`#MW=L//%)A%N04YDAYS)\[M)8PCG?$7,;KH@ +M,AJ=!9:*#7G/8195P_YH7/CRYG>)D37EB%!)%T(S)3O[0A&"C?43$P*5^3KY +M76S)&[4'93?ZQ1\1=ZI"7!;=GW`&AX98(`@1&"QWKD(;0(?EF(WR*&+Q!#TT +MVO>Q';)/25UM4M**=-[*+\[SGX7NX#N=22C8/_YUOHJ?ZB(@6 +M2L*9VICIK]@!,^#4^02:KA+\51^W5?.*5!.W1J:>!`#L````[`````(```!% +M``#HA6```$`1``#`J`$!P*@!`@'T`?0`U`:Y1Z%IZEH=NJI8M)['L?GW4F(P(V6BO>=J3KH +M06QZB(W5QF*N0,9DP"%+Y(#MS!C\B6WE&\/=*\?ND<<(1)Z[MEQ+XR:7RL*+ +M96#B\9":5!.W1G7!!`#L````[`````(```!%``#HA6$``$`1``#`J`$!P*@! +M`@'T`?0`U`:Y1Z%IZEH=NJI8]-^T +M4IA"(?,KD=4W,S<8\:V.#'6>-AO1^_M>-5D*8CF!T;_W/'2)N@RQMT(U@NA# +M*XT\]I,7G\^4G@QY!38^,FT"%NAUKT"F0\M]9VL//=+HYMGTHKS<.=KU[9#X8PR+\5$Q?`$X'77$!.@1=(=<!``\`0`` +M/`$```(```!%``$XA6(``$`1``#`J`$!P*@!`@'T`?0!)`<)1Z%IZEH=NJI8 +M>T$>GC::E +M;K-%3#B7&P8%O*R;KFYG2@%NS1Y4S:+L)7(JT8YK<4L2M47&1FNPZNYJK(." +M^HB:K<_[Z4L>TQ>Y#/_NXCU=1D-"6L')28$.18*N.9!JH(I%YU_T]=[`5XR^ +M0A1<#R1;X[2VA/[46O2FN]&XU3W>3#O?6'"]`R^UV$[[ZFH'#F&.Y9X!+*^N +MI7R*[K`G7N'7Y>FU=3MH*#A\]*N8L9_LR>5*U8/#ZG]S:"[G=%#%;JQ%I6`: +M<^\*3U56\OEL5@7[2G)HF4#-YAIBM0]9Y2DWM%8?)!#!T2X!PVX0(PF!`3-V +M'554-WA4$[=&J.H$`!P!```<`0```@```$4``1B%8P``0!$``,"H`0'`J`$" +M`?0!]`$$!^E'H6GJ6AVZJEARN/W!,X:/+B`D"`````<```#\(0``X#1/G[TE +MX0LDXLA##S3,_,=$W.F3205PT4R]DSSO^>.4^QZ#!I2LKW7(-'8C4M<= +M!=\(5M"'7A8,1D6+Z_+[>LU)KE6T@VZ)87DNR9?QXQ0S63#B`$*TKT+H#EK0 +MCV]FLA@VS]34-]' +M=Y_U79!)S?@+:&7\XF.D;E,83"Y,`1KBF=1(4GNXMXJ[=@AHO`VZE,D>S"0H +M?DL?_N57)QW".YU/,=;ZEJUQ_G/\9%56];M\(9!K<([L;V14$[=&D?H$`.P` +M``#L`````@```$4``.B%9```0!$``,"H`0'`J`$"`?0!]`#4!KE'H6GJ6AVZ +MJEARN/W!,X:/+B`D(`````8```#,(0``L'8N!\B2+>SKY=S;H4+;8:XLUQK` +MZ(/]FP96C@V-PAOC708(]U$?Z:0^MS+KZ!UCH$*H&*:!CY.3)+[J`@YU:L9LO^'`@8QC\1.'#[]T-^D4)Z_?B:7")H`5IA^$"=6D +M%O7,X>$8\.J)6>-IW1D)@$Y:%MK1*"Z;*C?FA%`6F!\[(,+LO/B^\9+Y),`1'^`.P%FE49N+GA5@)' +M?P9;(68!"?Z<='>,Q?[]<0`!<\+4A)'"]J1HDZ$=5MW\"--3W"87>QY':5M+ +M2P]^B1R1_@NO)_Z_ZL,+NLIZ7IU:&=H39>3VX6Z30?-S[?3WE_:4B)MUN6]4 +M$[=&[T(%`(P!``",`0```@```$4``8B%9@``0!$``,"H`0'`J`$"`?0!]`%T +M!UE'H6GJ6AVZJEARN/W!,X:/+B`D"`````@```%L(0`!4(1.N&85&6P=7'80 +MYQ%GCK-,3\@7D/9@PJO`9A`=C179HA>*V93Z7[;1Z+UAQIYTPH/G^ZX[[93( +MUVA*K8#4&L4'C]"C>Y1>G.SM`AR!`]22:8# +M2W"WN\^QY;3:>I>T=:O(YJ9#OAW%/X>*0,\D12U9"["'NJ1X;IV3M@=>VW<3 +MAD%P?YL/"0(MK^!(V`C(V_KME&S7QF%3M^4MYI4"^Y<$L?;-P;-K*`^=XF#Y +M.JD8D'1A&``1VZ?A?.ER;Z)&D*353=!W/EP./$F\>NLV4&H!3*7\/2G'I+M^ +M^<'?*3&C\`U\"KZ(3AG:9-;PCAZ58:5$+9M?%1OL@438?*??734';=`$"1BN*FJK1LFRX;/FC +M%-&8/;=#5!.W1N5V!0!<`0``7`$```(```!%``%8A6<``$`1``#`J`$!P*@! +M`@'T`?0!1`9U +MH,1E6Y$B/5?IO\++!'J/0("YA5F`WCIEM)+TF,)!6 +M*B/MT!>L1(\D+-O6O1'CVD\(6H +M;5]N4F&"3,A5_<2]!NG[[X&B?%MO>\4@_@DKX@MCP6ZB8$+U%(@NS +MGPG$VHJ?%TMDW=O;#1P8Z[`;^\!>^<^)4F6I9G60N+EJT$R.Y-77N^0+9\\2 +M.POJA6-OHB,BW4/ABT10<:8A(5H``!`$0``P*@! +M`<"H`0(!]`'T`&0&2;M)@I;N-A$X/](=]E'5$ZXN("4(`````````%PJ``!` +M_I9P&2$8YEMG/9)4P)IC#S)Y\[F"9=`DMPBAK6FS9D/BW6CO%O^0)LF$%YVD +MWT2]7O4Z"1?ZA-XHKB2[V%#,]$(&R0Z.;E4Z_'0=4$[=&0,8% +M`&P```!L`````@```$4``&B%:P``0!$``,"H`0'`J`$"`?0!]`!4!CF[28*6 +M[C81.#_2'?91U1.N+B`E(`````$```!,````,%VVKYCYD0_IUO3T>6%%Z1C" +M3RM?7[Z$C,'>[.B5KP"(``'@```!T`0$`#`,"``P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``@8>L/V$PN)NU]@(2Z,+6KXRU>\IB0ML<6'#IG&TP +M>$$:9_4D!1OW%RV^UC:"YSJ6)<'7#\G+3:#-28[O32M3Z"O:24I3V*RKVL1- +M:Y[1EW:&]W);QL`R5RKB3%(T*;)H<`8F5VBU5TI[WT>S.HDU,938>.Q.TK$I +M```D)7Z_&!8>O;/+^04B)3V2E;NHN+W9D4[N_U*"S40%+'(I```<``!`!&X1 +M]NB8"/H7:`"5MZ&8#;@K?E\G````'```0`5P84W`[DWC$)++&FC)`]A[;QW* +M8503MT;8T08`7````%P````"````10``6(5M``!`$0``P*@!`<"H`0(!]`'T +M`$0&*=-E;(A2",\Y```````````I("(@`````````#P````@``!`!@````KU +MY`*BZ<%Y5'HX'>P@C)/+]=IDLE03MT8@X@8`N`$``+@!```"````10`!M(5N +M``!`$0``P*@!`<"H`0(!]`'T`:`'A=-E;(A2",\Y```````````I("((```` +M`````9@A```@``!`!@````KUY`*BZ<%Y5'HX'>P@C)/+]=IDLB(``'@```!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``@8>L/V$PN)NU]@(2Z,+6 +MKXRU>\IB0ML<6'#IG&TP>$$:9_4D!1OW%RV^UC:"YSJ6)<'7 +M#\G+3:#-28[O32M3Z"O:24I3V*RKVL1-:Y[1EW:&]W);QL`R5RKB3%(T*;)H +M<`8F5VBU5TI[WT>S.HDU,938>.Q.TK$I```D)7Z_&!8>O;/+^04B)3V2E;NH +MN+W9D4[N_U*"S40%+'(I```<``!`!&X1]NB8"/H7:`"5MZ&8#;@K?E\G```` +M'```0`5P84W`[DWC$)++&FC)`]A[;QW*8503MT8E!@<`4`$``%`!```"```` +M10`!3(5O``!`$0``P*@!`<"H`0(!]`'T`3@''=-E;(A2",\Y2480.SS);VDA +M("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,` +M``@#```"````"`0```(H``"(``(``,L$;7?$+-OUP:>QII;H4P'JN_;K_74` +M61\0EO87''%$*6]*(,U^2I"'I0AW`/QS>.$F!W$4DSG9N+0&+C_)*G +M=\8&-G9#E\953OLW:5Y/H$*IT2M'&T,>LDYK^5N"8R40&E4DS:AI4'#]:PO] +M[(YCM,$NL2"_%P&>QK9]'KYHZ/3Q9ZR.Z +MHSI(N&QN*0``'```0`0>9&UFHGO<"%U43,T6FF_8JB#Y)_N[6=ZX^N)_ +M)))XL;E2OF +M+EHYS;.SNR)/[4_/*G>2!?\5BJ7E)N2FSAW-%[L]A%03MT9R3`<`O````+P` +M```"````10``N(5Q``!`$0``P*@!`<"H`0(!]`'T`*0&B=-E;(A2",\Y2480 +M.SS);VDN(",@`````0```)PD``"`IC0<,=H!D`:A7;CHS>Z/`D&-L)WT]ZF8,4)CY'=BJ&='E='`I,);?'V&\,VB8R-3Q'Q+9 +M%'RHLYSQM%&A+CG>>C@O882NQ>;"5?T'CW%<:J(PF>(PG>`H!E2 +M&)/OY:=]W=^-M7L86K`?KNPQ(X<$B4]/48J_5NAF<0L>,&FVB\1XNA52G7IM +MSO_.-2`3V`>D2J)DN#%C.RJDG8E)AES?\4W,&NYC^\,E)[R%2+DK^!05[@+6 +MS1D>JZ:76N9^/4D@58K,2%/])05+J9[F*3A?JF]8665+UTUNS\'GSI`_DN4H +M$Q%^R8CP_K?/C,A,#F[J[NN9*NFIU8Z7"\PY&Y5#]#*@@O]SKDI8QE03MT8[ +M>`<`_````/P````"````10``^(5S``!`$0``P*@!`<"H`0(!]`'T`.0&R=-E +M;(A2",\Y2480.SS);VDN("0(`````P```-PA``#`2@]N29+M3VO@_O-[;IR@ +MK4(*C@GAHT.:&>D`T^OKGJP[Y!!<@>Z]Z,1,;BR1[QJ7A!)A=T21)J^N^$S' +M452'U9`DA*2[94W]N8YR=AF_C56X)I0LQ*K]R*!\[SB?2!Q&QY?=L?NHFICJ +M0D<%[3A\>W<7OQRV:,JDQ9Y2[,SF0'>\8'*<`M+K"GX2EP<'H*KL:]KY_(!U +M/K[`8>>_<`5`KHB4^N@'56\^^W]6;PZ#LZIN`%NL3K+1.T3VP))4$[=&:H$' +M`&P```!L`````@```$4``&B%=```0!$``,"H`0'`J`$"`?0!]`!4!CG396R( +M4@C/.4E&$#L\R6]I+B`D(`````(```!,*0``,)+P`<,>[M-B:-'#+G_XI2G# +MM4+X*P/4][->7\,''O=C_,=F6'DY&&[W_ZHO5!.W1A"=!P!L````;`````(` +M``!%``!HA78``$`1``#`J`$!P*@!`@'T`?0`5`8YTV5LB%((SSE)1A`[/,EO +M:2X@)"`````#````3"D``#`GRA=65M&SIBSJ;#Z8I]0W(JO@(431*ENF[2\5 +M7)Q7JA656)Y%%_/CO*&G5%[,3Q.DS\$:1*[@L1^';%%P>EDH$U5(+$*K**]X& +ML:('4S(9?M?H+>;/I1T-0<=)3N'(;]!N,8VE/HW'_W745!.W1E;$!P`<`0`` +M'`$```(```!%``$8A7@``$`1``#`J`$!P*@!`@'T`?0!!`?ITV5LB%((SSE) +M1A`[/,EO:2X@)`@````%````_"$``.#S(MV#Z;K>$QL*=[B6K>B4,$_YA^.T +M0[02!]R`/#O*)N2KGXWAKL/;AF@"PM;2P5^*$VEZS5?V$2VQ9QEVHG'R^G@U +M.RM[.GAF^7%0<*43NN\'U5=XGM9P&KQ5@)DUIEC.<&T:AO3H*TSC-4G8KQ?3 +M`F'1%EMPP-!`MJ*8(E9(S.P8LLE*O'J2K-$I1W11D>E_)M=KK/&_6$CY2L)X +MG.M_SCC:G2:Q2U*^)9T36Z.73(09A%.S:M.ZG"1H_1\3J1J@\B0QSX:JYK:Q +M6XBL;?N2T!H@!/NM86^1E@CX5!.W1NS3!P#L````[`````(```!%``#HA7D` +M`$`1``#`J`$!P*@!`@'T`?0`U`:YTV5LB%((SSE)1A`[/,EO:2X@)"`````$ +M````S"$``+`O`WU:925LP*#=(10?^2E)!,1_403>Y,5OBZU9FO^.YURBSB?6 +M#C^%_/[J)P%^7].`:5\L-I?52(]`*SH08:=J.(Y*0*+]3/-40%F?Z*DJI*_6 +MS/>),&P9_N!RO['%T.]GQ\S;`)KMJV$U>H*A++>[G12O45C$P\T<7EAV-Q2^ +MN>$<>?QK5$Y*BG\+"&LB3OKS1)871#7?LR5.FX&3&_/Z30B@B=J(=6X"/67: +M5!.W1LWV!P#L````[`````(```!%``#HA7H``$`1``#`J`$!P*@!`@'T`?0` +MU`:YTV5LB%((SSE)1A`[/,EO:2X@)"`````%````S"$``+"'EU=K'32".RU4 +MFI\'BD>[^5:Z7@ +M"Z$QG.ZTT<_'S&)@L&$0?EX"42\T==X?\8X0(@M/\:*>0D0B>XQEW_^MY(%> +M(;;@L9MC1=-4+F;1I-E@4C$F*OWAB-YBEY>26?SDQRPPI[0FHX"ZRY7BTG=S +MQ]_NW*TC9P$AD@&+R@E]B%I4I;0G9#4WSX5`5!.W1F83"``\`0``/`$```(` +M``!%``$XA7L``$`1``#`J`$!P*@!`@'T`?0!)`<)TV5LB%((SSE)1A`[/,EO +M:2X@)`@````&```!'"$``0"@_#]3_-<(R]X]2G/^A0F5)K<81ZP^'`9,UE +MU_VL1*+F?I>91K0!#/^KMW`K8O6S@&Y)OAHC[@@")@@FQ6UEZX%-;*P2""5_ +MMG4#9;^Z!70+>9KT(2XGS0)]=HZJ*TQ;O!AF2C(`XS>4E,W\<7O-U@,,,JT. +M_]>`[C?G(T:', +M@`[TX%(8$:/[ZD61*IROFGZS2LSV7HL-7S<<\R[WQ*&!2S1X[DH2&K/+1"E4 +M$[=&W1X(`!P!```<`0```@```$4``1B%?```0!$``,"H`0'`J`$"`?0!]`$$ +M!^G396R(4@C/.4E&$#L\R6]I+B`D"`````<```#\(0``X!('BL"M[J6K((:- +MR%KIQQP2[+!EDVO=EI)K;B>C00RQP*)T#,*IK5[G?:I*AF`N/`R!U`TP_YM/ +M0JS%73NDY@TMZ>J_="^[(U#T_4>G2VM::"_TN0(VW271D8,+-9D)PP%\('?( +M2^7K_4)%3"7*7&F7)=/"JO,DYR;0G<)1M;UZI$J%Q.\&U +MP.X@C+ZJUVT_49RP\4^WF]@/3E:]1%BKJ$NL>7TI$3PO#WY5E["VQ#*X3QR3 +M/GWI63J'`3&J-9:LC`$II\[?[P5-ZVCI;[QX_;)4$[=&#"\(`.P```#L```` +M`@```$4``.B%?0``0!$``,"H`0'`J`$"`?0!]`#4!KG396R(4@C/.4E&$#L\ +MR6]I+B`D(`````8```#,(0``L/.;Z#\F-=E^/S9D*/"`8!WS+\FQG(7I#B#^`S'&/G!"[+#14)9\U;==@-!D +M^R4?TK0IZS`8<\-R)_Q]R<35QHA'MARC(CKZ5:[ZB%/:W)P.8"0*,L=/UP7) +MT.2PR5^/#M!Q4/5:I-!T&;I*KUKR^P?WL0Y=*+/O5UJV?F&XO3YNNR/((?"S +M83@C6KD;]]A_U."4-EFY%[,8LD@"6:QY4$[=&0GD( +M`(P!``",`0```@```$4``8B%@0``0!$``,"H`0'`J`$"`?0!]`%T!UG396R( +M4@C/.4E&$#L\R6]I+B`D"`````@```%L(0`!4#0Z>!(:3EX-(%2,7#$2E9+< +MEO&9*RQE\V)KGISK_;IY;'4,R5T:`\PSIW@K?.I&H?#A +MH+7&[L0 +MCP-NC>6^N:>TP(UU)Z%^[#3%BN.H6P9)H-Z%CG.!U-R"MV,O)\2:[DMAM@=T +M=?2Y7-(=^%]H*[8EIGK;>4($M=;C;+9>.7L_QV]3T>K7F;T>J,'@]V-!FFVE +M!Y7DNCFDB/.$_J%;O7))2U3K1P)JGRA`Q*6+2Z9"/@YW +M2BSZ5&T).)8&^\+9M><39T)Q@A4>C?73N&!I#2\M]@#F)J$YGM(IFDD,`: +M5!.W1DNM"`!<`0``7`$```(```!%``%8A8(``$`1``#`J`$!P*@!`@'T`?0! +M1`Y1^/6EF8X@ +M@DSYF-2'![?#';/!"=EJV"A/%_;ZNQ#[]RP:@D)@IRMF&4Q%&>LJ8?'Z%`>> +M+`Z>H8U1"B9W_S)0I>!S6P%.<:0<&54\F`4?O&=&"Q;G^(^B5AQE=U``E0FJ;O8,&J\)!CEH8BBU[33EVY +MR*0@F%03MT;PU`@`?````'P````"````10``>(6#``!`$0``P*@!`<"H`0(! +M]`'T`&0&263C*>N"T5#'9P!6(2V;XJ,N("4(`````````%PJ``!`\T7`K@2F +MK'PCEQ(!R0#RK;^X+'OCHY*?E,KX>>3Z16,CX)5XUVST/SJ0%T8=#`$#>&^3 +ME2!)F?=9!!4D5!.W1HO@"`!L````;`````(```!%``!HA80``$`1``#`J`$! +MP*@!`@'T`?0`5`8Y9.,IZX+14,=G`%8A+9OBHRX@)2``````````3````#"Q +M=W<,?:KU<7"NA23]!4P#GR>V,V/)ALN,)J'0)._)-'AE03 +MMT8)[P@`;````&P````"````10``:(6%``!`$0``P*@!`<"H`0(!]`'T`%0& +M.63C*>N"T5#'9P!6(2V;XJ,N("4(`````0```$PJ```P,Y)B'$CV4`@U74D9 +M)$Z&S6>Z\TO)R(:8&UN]L#^*5@62%TU#ZN%P?1MF-6E4$[=&V?P(`&P```!L +M`````@```$4``&B%A@``0!$``,"H`0'`J`$"`?0!]`!4!CEDXRGK@M%0QV<` +M5B$MF^*C+B`E(`````$```!,````,/B(EH/NQT4VO3AG`82ELE0)VK>RW07@ +MW8HDWSHGF(F_\8YD:WS5*)`UPF8;5!.W1C?Y"0"8`0``F`$```(```!%``&4 +MA8<``$`1``#`J`$!P*@!`@'T`?0!@`=EW5DHJ=-+Q*,``````````"$@(@@` +M```````!>"(``'@```!T`0$`#`,#``P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M%`W*)6:1C3.$V:5+\4)O\K1SE)N3L4I+5\\NHR=BW[9T`X?!)2+:"DQ;8FS8 +MV$6R3N@R@^:30\J)/&+D@7@9\8EP5I58YVP2^!X9/O2"WLG%JK+(<^5AM\J/L-K4Y_V,(1UHA4/+%0"FMK'ZLI```D0>M1 +M&%PU.`32_LG6+&;QRF@V<5ODM%6%3@E1Y<'XO<\I```<``!`!"Q08);%IER& +M>MI80)/O2"WLG%JK+(<^5AM\J/L- +MK4Y_V,(1UHA4/+%0"FMK'ZLI```D0>M1&%PU.`32_LG6+&;QRF@V<5ODM%6% +M3@E1Y<'XO<\I```<``!`!"Q08);%IER&>MI80)MHD$`A("(@```` +M`````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```" +M````"`0```(H``"(``(``)3VW.6-_,(SB]U_CEKNGL4O^L$`DL4&V8]\EB<` +MW,='S^PKDV"1IS;ONY8XACUVY-`0%CZ3E43BG/WU\@@6%!EF<';&8F32N_6" +MID(CYLS2_Y\:WI70RC`FXVC)^=<@X(3EXM@5I6V4'=&'9!L-D+>Y!T_TW['B +MCD`]_R'CVX<**0``)+HT:8<7N-++UPI5@M351%OT\G +M*0``'```0`3W'5K^ +M:?[!O_"\(*JCJ +M3!)%P8/Z4D;$CE^",WRW?/6N'C3HV(X+@'TE86LUU2,#:/7G3*B=._,F.]B# +MTHKL!J"L?P=%IIST8F9!E*>*A+0+3HS_-H/'1^,'\>,M_.TZ61C2SX+T++;/ +MW.VDINY%G[?*A9BIL?PS5AX;?O-KU_MPSE03MT:W@0H`O````+P````"```` +M10``N(6,``!`$0``P*@!`<"H`0(!]`'T`*0&B=U9**G32\2CGULE_>MHD$`N +M(",@`````0```)PD``"`N86MG,E3F'T.B=6!O+0RH?2L@UCBA=XR\E#7^G6O +MU,2\)#S'E*2]^`%Q(8EN/;:`R378KA?F:`$I=?:3]_\=RM)8\P%9&5Z9S99\ +MY[DKH&U(&7-Z-<;3C@<<(@A0`QMB("X#X@'4`(;T_PC&*S?. +M_)3&M%03MT;2H`H`'`$``!P!```"````10`!&(6-``!`$0``P*@!`<"H`0(! +M]`'T`00'Z=U9**G32\2CGULE_>MHD$`N("0(`````@```/PA``#@A#5],1D, +MXEXT-UUD%X1DJ<,'M,HU\/N-'>Z6;<+?GA!')J^`.80()[J@-63L2 +MI^GD)N/3^[H9Y@&@!4;G998U+R1O\0'5$M5IV]\>2/>5E^Y'0"`50?8;J7BM +M[GML!]$V!!F0%Z.*4 +M^C)NC4=/%7+XV=%R.1M68$&YU'9$3H\;E@?_77J_!)+UF503MT:@JPH`_``` +M`/P````"````10``^(6.``!`$0``P*@!`<"H`0(!]`'T`.0&R=U9**G32\2C +MGULE_>MHD$`N("0(`````P```-PA``#`<46^94`U+.T`SV;MWO'BVK]KIOM: +M64X?1^";)'J.-V#TX;P$KGB6BMJ*QN,VE7G@2=SG#$6,E`(R>>;O52B\"K+OHH:5J8WE--/Z7E +M=&WXZ8A)C7NV`M58L^.FQ.K4MSM;"[#1LN%"F&IE-WPXG.(1W,J!%\UT,&=M +M$-W8.0%3"`']X1;NN+NR>#UFPR1YXOL`=90<AH$K-RY9WU#O"K:Z(9ZCV)Y +MF9PSE%20(#$][=)@;1.@E>94[QB35!.W1@?2"@!L````;`````(```!%``!H +MA9```$`1``#`J`$!P*@!`@'T`?0`5`8YW5DHJ=-+Q*.?6R7]ZVB00"X@)"`` +M```#````3"D``#!C"M79U-P[LSBI+&HD.]!H7QZ-H70PY=TT36&4XYQ/Q6LM +M#A;ANK4SL"G?4503MT8+[0H`/`$``#P!```"````10`!.(61``!`$0``P*@! +M`<"H`0(!]`'T`20'"=U9**G32\2CGULE_>MHD$`N("0(````!````1PA``$` +M&F*D%83G_2+C%>H#[>5N'Q?=H\S_E9#);,%Y!T-7X +M84(8DYFQ=CLESPY'!0R5*.7[:&WG,6)MX]#7;F:(B.']N6R5=D\'<)`O`><( +M[7)]6T2=%44+>XD^VOY(W$=$FV6O>VB=,B,R/X,[63SS,2[O@]]3N[2M%=PGRR%?(@]351O@2C):&!IF'_4NRGY0]>TB6B)>W4.DWK +M4R*/A(Y<.3, +M(LP?>Q`K\>Z8XM.6_2[:#IUUQ_"\@0="N\!(5ZEG\@%*ZBS'8;M]('M0EK%\ +M(^3(O +M.H553^SZ3((.P':'5!.W1G`("P#L````[`````(```!%``#HA9,``$`1``#` +MJ`$!P*@!`@'T`?0`U`:YW5DHJ=-+Q*.?6R7]ZVB00"X@)"`````$````S"$` +M`+#E2J%$9PBP%&;#/ZM=!\)SC%NJ+,P_E--,N`@< +M6S/O=LFPQNRGH-M5Q@?#]&?<<\8&G9:@+1"T(BMKLE4OGB+,?]<"J]03NZ=#5,^OLFOAB<@;#^?#R+WPRD?]I><1^L=)D-VV>.8E+;V$ +M4%!!,'#KA*).:,IKINF14^8=;JS'H(`F*EQN$(Q+NV0)O:F3VE#F5!.W1J8K +M"P#L````[`````(```!%``#HA90``$`1``#`J`$!P*@!`@'T`?0`U`:YW5DH +MJ=-+Q*.?6R7]ZVB00"X@)"`````%````S"$``+""?YV0DEV/)&_G9N>,HF7VO+K>J>?1= +MT!OEG5R:,V9L,]\NQCI,]5>JC(EN^#4"B#13KG/P!E;C2W[2E_`HI0(@1;,: +ML;;P"9[7P;)(=]]1J6`5K*IO!0L"II]'%FYOE +MLS*.N3BC-DP!3Q6.R&]-WQ:Z845L1T)!X;__CH7P`8I^N)&%H2,*\L^2TF*^ +MZR(#R9K<+\1ZD0_S\B5)U'U;73RWPGNH:\5;"F6_)3W6&5EY`N=G]W)25B_T +MKE7U;Z%&R&J07RL?Q4-^?%1;N"3E*YVXC#B5-+T$+)+E$6V%LK14$[=&DE0+ +M`!P!```<`0```@```$4``1B%E@``0!$``,"H`0'`J`$"`?0!]`$$!^G=62BI +MTTO$HY];)?WK:)!`+B`D"`````<```#\(0``X.;4L^CX7L#PRV-]T&BJ-?P! +M-R*1>FW'B>'$^AEQQ:")*SX9+B"*S6HXEXD_LP@]3&H$RN2NY+@^#X"N1:(+ +MZZBU5]\<,BIIN.^15##_7'M.U=X"S=Q*,EP:0,D9`!!CTVC#U1E;JC)!'^L( +MK/`SW_BW[4\5(F0&K8^Y,UNZH/9+KZ035Z5#\8H1H!KM97'Q%\5<7LT\[H`L +MX!2:;/.:U7M5UF0`0&/HOD@5V8T)I?-L7CPC?S+I1WTBL]-UWUQ/+20CM//0 +M;7?@(AE(6BKJP:9=Y$Q<# +M]^%=PAD2,*B1]U9@1,#K!7`V!EZ+*1/,1Z(#,B%3)?Z"DI9$WM!UH);H^3`Y +M:1WG%MIT/F;A$_UA222@3<>8Z15/PA"6VEZ3^(U]>/.GB-H#*"ET!8`:MO_E +M?(C+2>?UAY2WL#=*)7/(0HB-<2Q6\DHBU.H218N6M_'P",,%D0;T3*JY`V-' +MC8X,]:I4$[=&OX8+`.P```#L`````@```$4``.B%F0``0!$``,"H`0'`J`$" +M`?0!]`#4!KG=62BITTO$HY];)?WK:)!`+B`D(`````<```#,(0``L*3FD/L4 +MU]Q,%"$F/YO.?F/6;`#%K=<*E+,@1E99JCE%9_ET*L[_,[M&6H%I(#5*VA@Y +M08LEX(@57),@2,>MY->?HJP36KX(*M +M_E)QTKOK_;YW8=A^!,*O;JDJ#\@GGV,+I&A?W>1X)TA4$[=&A:P+`(P!``", +M`0```@```$4``8B%F@``0!$``,"H`0'`J`$"`?0!]`%T!UG=62BITTO$HY]; +M)?WK:)!`+B`D"`````@```%L(0`!4&!P_2([M:!T$R^Q+PKN@85?R@>HP<%: +MRE-)+:1ZBL5*DS#09=PU1R"]QMFMM\S25-H><(L]74\[;V8X$(+J3+FG&(K; +MB^]5--<864$_G(+8&G0W]+H!2X7W-S[-)M$TX<."D'I*J4I_5TQER'Q9>[0F +M('61>;/QTX#Z:@X:@8NXW5>?O['[)?"9X9=LBB`&5GC,(=3MEB?W,OD?$8+Q +M/4V85=?]6'H*F`&8=\PA,U\1C"WQO4X'8X)`AV-`TQCJ$?<='E=_(T`)>$.@ +MS9EVOW"$K'SA3:#%-UFP6^&EZQJPE;L[U@,*#)TD9?@U9H1J8]^P#OJ);,]&P:-C'\OA`90[GN_!Y'-T^LTY@R6TZI!ECJ5!.W1B#A +M"P!<`0``7`$```(```!%``%8A9L``$`1``#`J`$!P*@!`@'T`?0!1`U\4/RAZ@1AA$7LAG)ON<-;&&\0Z,$-*380B] +M@'4`.'O,X!\*%T*_G!%WW2&V.#J"I:-%4&TIV0$O*\(U'F?K\[(MM-I]W;$M +MOOD1?B!BZ/QG.[T\YLC-\F2(,>4L&BC[PW2`X,#-Q)52*22.$3M3W3#<(Z[R +MINSDR_]`F=KY4.^*7X(P^N8N=9`/[N8(X"&4\CG,E\&J>VQHF2E&AD,N&P%03 +MMT8;"0P`?````'P````"````10``>(6<``!`$0``P*@!`<"H`0(!]`'T`&0& +M27Z:;FL3N=5&?/A,ZHHAV&#/T5DV_"(``'@```!T`0$`#`,$``P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``SG,"'=!F +M\MP%L!$MO`J@1VD/-&Y-3/*K3A,(]$8^?;X=^8X83WY3GI3Q\7Z5M'?Q5=*8981\HN,/F4W\9&C:/GZ23??&[4195K)X1J1NH1\) +M@.R,LL9X%C:Y.4E8*"';HK7S(I```D=C:WI?W5%A;0 +MQJ6$V,5=U+W!HZVY`;,5\)=RS&\AA"@I```<``!`!*P]=E7=Y)$0!VW8+/,Z +M'6L'V`Y<````'```0`7C7<0$P4V1AERA3N%;#J%I\06MS503MT:H00T`7``` +M`%P````"````10``6(6E``!`$0``P*@!`<"H`0(!]`'T`$0&*8J_Z'^O#2#\ +M```````````I("(@`````````#P````@``!`!@````K^#[?JN&UO$>_M$UM6 +ML\<@DI!<)E03MT844@T`N`$``+@!```"````10`!M(6F``!`$0``P*@!`<"H +M`0(!]`'T`:`'A8J_Z'^O#2#\```````````I("((`````````9@A```@``!` +M!@````K^#[?JN&UO$>_M$UM6L\<@DI!<)B(``'@```!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``SG,"'=!F\MP%L!$MO`J@1VD/-&Y-3/*K3A,( +M]$8^?;X=^8X83WY3GI3Q\7Z5M'?Q5=*8981\HN,/ +MF4W\9&C:/GZ23??&[4195K)X1J1NH1\)@.R,LL9X%C:Y.4E8*"';HK7S(I```D=C:WI?W5%A;0QJ6$V,5=U+W!HZVY`;,5\)=RS&\A +MA"@I```<``!`!*P]=E7=Y)$0!VW8+/,Z'6L'V`Y<````'```0`7C7<0$P4V1 +MAERA3N%;#J%I\06MS503MT89=@T`4`$``%`!```"````10`!3(6G``!`$0`` +MP*@!`<"H`0(!]`'T`3@''8J_Z'^O#2#\P1,\B'`A']LA("(@`````````3`B +M```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0` +M``(H``"(``(``#;I_FAMA32/WH:2=*\4S-7)ZS7E'T)"4,[4B#-+*3Y4WGF> +MP<_`4V`>-N]-SAE=?54#:]AS'5L*MN,Z=6]GL3$(;U]DKHGY8_IYIAL@$@=Z +M>M]*/KTJ4_,@OGV"+AN_KY*E/2>B<55-7PH$2\A5;?2H6`X:.R'C6&/4>B3[ +M(I%**0``)/"GN@S3EHL4QXU8=B)W*/Q)(<`I;0I30E-MXPO%T]V^*0``'``` +M0`1TB +MX_AT?1X&>S7(OM2LWH#2<)D1V#KR(NFCGS>51^?O#MF9TS=M+;[0,(8_9,:PTMV`H4;I'QB3S;\'BL=\&7P9L&6@\48:FG(FT\Q?3W"S\Q2LQ +MN6^"+0L4KR#^N#4"NM/ZW3M%EZMV8@IL6#@Q:VW/\&0V>'B^J\#"=II;V[^C +M21HCF(9BG[%,3OL'PMG\?6XL2E03MT;GNPT`O````+P````"````10``N(6I +M``!`$0``P*@!`<"H`0(!]`'T`*0&B8J_Z'^O#2#\P1,\B'`A']LN(",@```` +M`0```)PD``"`:SNO-RZ"9_6)/\6\B9@$M1UL*8$QJ*UEU=%@4.#H23"-8U]2 +M,[S\*[M\ZM!*8',SS?:B?C$8E$_.QYLAU^1O'5^M9<1`A0?X'\[ZD9D#2\JB +M\%(^%.HJF>1A.,![TG/Y%&Y-R'GGMQX26Z.YY_.J+`;OVXM!Y@Y#\W@>7503 +MMT9OV@T`'`$``!P!```"````10`!&(6J``!`$0``P*@!`<"H`0(!]`'T`00' +MZ8J_Z'^O#2#\P1,\B'`A']LN("0(`````@```/PA``#@3U2.`B>H>>`>/1MO +M#85X5!Y]S4M1RY89BGW'^",-H7QCI8Q8O(H!W_<.1U-@$Y%,J6Z*`DDG%]VG +MCFB6BR.'IRZ* +MFL-Y4E'`[QPQM5L+B_&6K[.I\89_\*RNW/_HHWF2DYM8Q6Y%'UAV$M,<-?Y[&])LYW$<[T):C(BX14^0[-] +M[[[LM80JF($NZH(2"WRNW=U1>]\EOE1?$XFG_+%`,+C._6ZGH/8/0I( +M^%ZO>N!F#789#A7P7/S>6;::NJAI'F_@/DJ.U;C?P'V*Z[RMF?ISH1T]#S/] +M`AO_.&V*Z`?)2=@DON_K_@,CF:A7S:RSOF)4$[=&+/$-`&P```!L`````@`` +M`$4``&B%K```0!$``,"H`0'`J`$"`?0!]`!4!CF*O^A_KPT@_,$3/(AP(1_; +M+B`D(`````(```!,*0``,,UO#[YG,V-/P-\#9)_R.(O6QR47>@7)873MBS'# +M2K3N34B*'4CM?NGS5A/X5!.W1OH-#@!L````;`````(```!%``!HA:T``$`1 +M``#`J`$!P*@!`@'T`?0`5`8YBK_H?Z\-(/S!$SR(<"$?VRX@)"`````#```` +M3"D``#!N72RB:.C3"MB@_R=+1XME4ACVK%YL!!N]64U(72EI;P5(-.YU]/XV +MC47 +M'Y=_3++@FS!EEAFN^"CU=\!EGC05,Q_\R+MNQB2*Y7.<"(K`E;M!@-W2_6G] +M`?+L22&3T'ID-=+1KL5Z@_J1ZVVIVAWE&,0(1LKZJ(N@\"N5*35LL5H5J+[* +MB@;?VG1.B0;ZJ8OZM=OWMEH/3'EK5!.W1G\T#@`<`0``'`$```(```!%``$8 +MA:\``$`1``#`J`$!P*@!`@'T`?0!!`?IBK_H?Z\-(/S!$SR(<"$?VRX@)`@` +M```%````_"$``.!,ORLD81$;'V00V^%285L^<\WC$&W:YAI5EH/L&)25B@AE +M%)M7Q:&@@[3K,+U&W'U.\]N[V#0VP_F8+N"W@3\T?S/<,;/LZ!@N;8C +M<+-9JH=][&+O="-25X>JPE(H_RU*!S\]/Y-3'Z!0BS$-6C,S0C4G.]JM@PV( +MMO:)H@>B^\G98W[LNBT\_RD]O!#7H-BL7<$:J;$*U.[(&+%Z&_U+N#6$]4_8 +M+.>\K4)[]=]3/P9<5!.W1BUG#@#L```` +M[`````(```!%``#HA;$``$`1``#`J`$!P*@!`@'T`?0`U`:YBK_H?Z\-(/S! +M$SR(<"$?VRX@)"`````%````S"$``+#^L%Z'Y+&1Z]LZSE8$@SS^D^:1C5'U +M%:0'66.J[GT+65 +M/`-.7(U@=G*6U@\BZE)FR3;9>#'<,DRVEGKLLK6RO(^Y]7'ZE#N?E$&TQF7GSH<+F_%0T7&9["TBN&#T7<"[E+S[7J.S$D6CRGOBB\YLX +M63?HOO[,BWY/$8KYOPQK:)&"9XN.."JG33.'4\*1(W1\M7P5%?"/D:D+G>$` +ME*8B-`B +M@3?D+Z9%4QW;`MF[H3!<)U5_$;;)I/G5T>2[AU$7A,W!6[E]?M:$Q"^)?I#) +M?J;B-OO,07UMMG[N\8S&*U(P4DBP";OZK%S,?#C[J@_J;ZUX)O]N?-9G76DO +M]S%L#LS7Y(_L)3(<CN=>J6.O(*P`:V;61S]X@DMJIY93U5 +M2.]1LB?!>VO""/[CCL*L$T#Q"^7<(XC2R,J,6N;DAA8$U6R&:14"R7,VDWU) +M4X:+MOA,/G>Z#O;/91(]*A]4$[=&H9\.`.P```#L`````@```$4``.B%M``` +M0!$``,"H`0'`J`$"`?0!]`#4!KF*O^A_KPT@_,$3/(AP(1_;+B`D(`````8` +M``#,(0``L$HMK`/LE]4V$5K^Q@\@"44K;V4+:EM+?BT*'@_'M>X+(GCC+.I0 +M/[ADN9QZ0)#BXA7PX+*"`8K44-!Q4=@+UEE._FF23.4U;3NCKJX%C">ZS"28 +M6[OSM@)-O)$S&,6-XEV(,OR:,:_PY:-%4@%5^VRM%67*^9;&?#XFX?@^I5XA +M7\HP>T2@75^:=;L,$&NM5;$`F2Z^+-;=81Z:+;$ +M?E:X'V1O'.QZ'G6LZ6SG%R*T`*8K.V]*.1,#H6(:JOOX\J:6YB7V%.MSG4OX +MA4IJV3.W[?&V1,!*9QOT2`/0T1=_DR#EE6$/XR4[MA.F(TX@#0+3D[1&-?F_ +M\^ON9Z>691N$?AUP[*GE,"RQ``\@=.4]61%4$[=&HU@]8U) +M(FZI,(U\4]9J_ZD[]PM,8<KL9`^Z`6UZ`,C??+DD`/!JE\ZZK,-"`)2@U)(&80GRR-I89[M$0`>Y^]%- +M"@=_;TN'7';YN,/R1HDH],B&$7@$W%'&%RMY\S0J/;6@5!.W1NP=#P!<`0`` +M7`$```(```!%``%8A;<``$`1``#`J`$!P*@!`@'T`?0!1`/"U6#5=^5Y@P^*@$V:N1C +M_Y4*]Y"#C1^(9ME0IECW`6P]<;9!7D.`W`822=!#[\(Q+JG4'<^`*A1#;H)( +MQ80%M:^!<,("X`7HWJ."K)-HIPZ76,:R#_&BM4`1IYIR'+]?)@(D\U9>%)YH +M7&Z.%G<6>%VPU3Y7ID<57X18V'C4(\,^GZ'(\*B(V/;Z;,[06T&4Q1_P,P0R +MB&#N`1>0P29-,_,0:`EBRHYQM*$V/S"4D7596?4G<=^D'91S/J4*^8?VJF9" +MMF6(E%J8%_KC/#LLBOT:\:<Z1-(7BQ^Z!W-(';9[3"[W,Y\3<#]LG=ZHN +MFX11R\-9T>55;%*#KMQ&+/'R;%)5)XBO,`)>".(9?"0+BAZVNU43MT:.`P`` +M?````'P````"````10``>(6X``!`$0``P*@!`<"H`0(!]`'T`&0&29TL,4O. +M7><@-F>+T'NJ\"(N("4(`````````%PJ``!`%I-:D0N+9SIJTGKYJ:<.$H$6 +M@:$L#@E=I\D5ML7@K:/R_V0HKOF4NP]SN8L0T[0!@NQBB8#,P=R\FL6=51.W +M1NH.``!L````;`````(```!%``!HA;D``$`1``#`J`$!P*@!`@'T`?0`5`8Y +MG2PQ2\Y=YR`V9XO0>ZKP(BX@)2``````````3````#`7BM#OD>&IY&6J()GC +M,_W[G!KL!"'T.Y98!#3^)J8;G@^/P:#39(F#3OLQJU43MT;;'@``;````&P` +M```"````10``:(6Z``!`$0``P*@!`<"H`0(!]`'T`%0&.9TL,4O.7><@-F>+ +MT'NJ\"(N("4(`````0```$PJ```PNG!R%(^Q&&HC8YAEC/EB$G;?""UT3FP> +M\15Q.V4[W:,9F^^/P9OJ@(+/1:15$[=&2RP``&P```!L`````@```$4``&B% +MNP``0!$``,"H`0'`J`$"`?0!]`!4!CF=+#%+SEWG(#9GB]![JO`B+B`E(``` +M``$```!,````,,U--I^HW?,)1\YH^Q"U[C,O6F6F>T#=.8F"!$H8\)RGJ,<2 +M]LTK7!2%?,&M51.W1FPI`0"8`0``F`$```(```!%``&4A;\``$`1``#`J`$! +MP*@!`@'T`?0!@`=EL8BBX,+N$#D``````````"$@(@@````````!>"(``'@` +M``!T`0$`#`,'``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``PVY(PIWQ^*HP2O#D +M^8F448IC\!N=3+-P1:QW$$,4LRXN5H,8=1WUY.\JDEU-<"U=.*9RB,(S&I!1 +M&P4XT(LR6M@?>\Z9M#JN^%$=1ZKMJ#'N5X:X0K^>$8HH/`[APL*J5J5L;K)F +M?$&"@FE$CCB4'@B,-W<<9Q).G,3TPH"0:_XI```D_R4)X#5R/8+;FC +M:2'Q.E_K__:)_^=JGZ4#2O(I```<``!`!$7&J&&K6-1.O3:R%)JM-'<\*$1L +M````'```0`4H1?5?MOV#.^[SQ4XD.HSL5J&"WU43MT:H.`$`7````%P````" +M````10``6(7```!`$0``P*@!`<"H`0(!]`'T`$0&*;&(HN#"[A`Y```````` +M```I("(@`````````#P````@``!`!@````KP>T\T\\Z9M#JN^%$=1ZKM +MJ#'N5X:X0K^>$8HH/`[APL*J5J5L;K)F?$&"@FE$CCB4'@B,-W<<9Q).G,3T +MPH"0:_XI```D_R4)X#5R/8+;FC:2'Q.E_K__:)_^=JGZ4#2O(I```< +M``!`!$7&J&&K6-1.O3:R%)JM-'<\*$1L````'```0`4H1?5?MOV#.^[SQ4XD +M.HSL5J&"WU43MT96;0$`4`$``%`!```"````10`!3(7"``!`$0``P*@!`<"H +M`0(!]`'T`3@'';&(HN#"[A`Y^9>GK+VA`W4A("(@`````````3`B```P```` +M+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"( +M``(``"R3^_3F+"5]A<`QR&0&PUD7@G&6L+05.Z,Q@5;PA8LV=E5T=<\7U_'T +M!(=4*>!6UN.AG4HQ>-!>/2BE6O37HL(R!@.CROA@W;`1%(F.D=ER;K(5DUH= +MQ)^[X:UA-D@^ZB.9(UB>6!HG:E+RSG]5XYX8HIA=PQ#"I);!$KD3N]N9;T5#A=,Z-*0``'```0`1).-?, +MZG&S-#\")'*LXB\UI?`#)@```!P``$`%P;`6GWNS'@B.S_-L6,"SJ5.<7695 +M$[=&RYH!``P!```,`0```@```$4``0B%PP``0!$``,"H`0'`J`$"`?0!]`#T +M!]FQB*+@PNX0.?F7IZR]H0-U+B`C"`````$```#L(P``T"[:1HFI-/]>_)#Z +M[42'/WZ,V@VL@YQ=)5A;1__4M>IWE"3/>0?VQL0LVM[F+D7I:B?M%Z8:8ZP"KK2EIE375)O'SP-,C2O#![FQ.QD +M1!%`0P_[K^,(NFF3M'V`'%4_0\EH8C5;QK-K0>VD3R&PS;*X=U$]JZH@(Q^+ +MCAN6"4:&?^^B\GYM0"*/N.^#;,(9?O@+BULG,E8[!>YYT2=S$ZHB)RYGZ=-E +M/@D[IFFM^&%;*UG&3U43MT;CMP$`O````+P````"````10``N(7$``!`$0`` +MP*@!`<"H`0(!]`'T`*0&B;&(HN#"[A`Y^9>GK+VA`W4N(",@`````0```)PD +M``"`+7A"(S&/&C\]CTM0M03.^%,%ZI$N-*KU43MT9BUP$` +M'`$``!P!```"````10`!&(7%``!`$0``P*@!`<"H`0(!]`'T`00'Z;&(HN#" +M[A`Y^9>GK+VA`W4N("0(`````@```/PA``#@4-`U-?0`36NG*:*H&]=#]4=> +M@Q?G/%E)==ILI0I-WPB/S0D?5"M(K&6B&YBJ7VBA2!-?[CAJ..1OI8:K?/["\'W#PC#2KQW-DMK*% +MFD**FX0]FK0BOH;D9Z_X8`W+'0)-#)^U3]81IWXTUVRO;TO!_M'D$`:$-Z?$ +MXCL)N`S%V1$JH<3CTQ9DU\9^0[96---SA'75M/+$?A(Y4W(9ZK\,CC(%CS>< +ME)TB-Q?0(U[R+1VMY>,P4*XU#IF'SE43MT9WX@$`_````/P````"````10`` +M^(7&``!`$0``P*@!`<"H`0(!]`'T`.0&R;&(HN#"[A`Y^9>GK+VA`W4N("0( +M`````P```-PA``#`6)1^'O*.)W@`X:8(UQ:!Q*$1@.VH5NX(R-?:2]NSVEZ6 +M7_EI^%,AXP6)Q,"J#(6L_L,6[EF`M$?FO4>1'%4V^_@$KG58?H^DWQTOHT +MZ*W4U\'IE7UX)C#\>1A5@CIQS`T4)10!"$-X:*53"S,:[=@BT4`,&1#ANF=% +M(Y]XYVN(:J1@9(G,I`<'TDZWH]15$[=&E>T!`&P```!L`````@```$4``&B% +MQP``0!$``,"H`0'`J`$"`?0!]`!4!CFQB*+@PNX0.?F7IZR]H0-U+B`D(``` +M``(```!,*0``,/*9Z+20^@YYGT!$C`;!9/`!T!]UU',:A/7-7]]LO:$#=2X@)"`````#````3"D``##B +MTEB7-/,#U+T?'WDM8CU!4A\@A)=?B::S!JS6P@SF?),*#0$RWG1W4&X*W543 +MMT;](@(`/`$``#P!```"````10`!.(7)``!`$0``P*@!`<"H`0(!]`'T`20' +M";&(HN#"[A`Y^9>GK+VA`W4N("0(````!````1PA``$`P[=\@65J#$`\A10* +M]."!NR%$6(ZBHB]W1F.P8V$DTBH&L<$*NO_'*I1R4?4S\'M4TZH2M4"M**UF +MNYRU?B`X+\6N'3?)^#+@M1\JDV?)$"*B;\8CS[HF$T)N21H<=+\0NO*).!>*0C@ZI5<)Q,JO*,)8YVM'\)_ +M8'657%06*#/,]+PFU;!L>*XL(WGLA4H.?WLEK9MPHFCV0#5C-=LAHOW;T]^* +MLO:$#=2X@)`@````%```` +M_"$``.#,8U!P*Q$HSSE5$J=?(58GHX5=K2VB1K)N@$W#63BCGT1_*VYFE+%* +MVUF[@^:YP/">3FD#/_O1&V7-G#79Q.GCC-H/Y@>$\R<4@CHIV&5WMSTS8&SQ +M9:X3WUKDFF"4U@\^'///AZG"&]UI@"<_@MBT_JUC*W2A1XL(L@1;+-NF)+P$ +M6Q!H_](8)SGX9N`+$9O4WFIA1W:'9<2R0L1AWP`#N)6;&/Y5BT-K#TA&6,S: +M1P2.8Z\=N=]0`,+01Z"#+Y1?03PI?>N.YZ&O$:^HG58_&FFUL5WLO:$#=2X@)"`````$````S"$``+"^-WCM,1Z`KKWY +M@KDH1RFYC>>F-\Z'3I^*K[0]T;SU92THV"*574.KPE% +MOA-+7W-5J>39>C1'VL6N/4PJ/2]?W_<4Y-M`>T9FU@QXG[8I:L?O"C[<[T33 +MKG)MMS+\LK8:9K%%&7/>D+`'V/:_#<9W.*G*\,#5>4]?EB65:J52*FJIT,&0 +M$U[B4-\;LT0D^>NL1[O>.-X3PX,_NE>$KUO*51.W1BMB`@#L````[`````(` +M``!%``#HALO:$# +M=2X@)"`````%````S"$``+#VN/L2^&<>'`&PA,0@AG[43.O#_:@<8FQG^JT4 +M@O+.^+]1OB2P%:$"VUEXSV_Y47_GS*9W@`#A*OU)5"U1VX6W_QU"&\L/;'F/ +MFPX[4ZJ]4ZTO/!5?C6.A\^-7C[PAON[;]Y,I?T('!7K\0TC/2!NG;'!-1=3/ +M5F63V2\TPR5R+N0AOVX@04497,Y6'4*`B?SS@&B4OH]?#O"8EG.7ELV#93S& +MAG(M4;<-A]#151.W1N]^`@`\`0``/`$```(```!%``$XALO:$#=2X@)`@````&```!'"$``0!. +M-D"E.,'Q-<.26Q22;D/D1N1B +M\@1"^AE_<>Z?3A,!2.%^G;;H)]`=2VH5HIQD8=^8!]&>9@!X9KC:&Z..NM1A +M,YM#5`@YXWV7`:NG8S$-%/4&!&\\:\"_Q)/.]T>&ZZNGRU=31QZ\,M/0>VWY +M;C);^WA'@SSM4R!/'IL@("JWU$;;D%5\U@#]%M-CN'%R_4V,N=/GG#<3\U>U +MYA[/?+PM+`IW4T'VM@P;-!+$0>Q^N;PN(/T=>1+&?(>AW-\Q*7[9TM'XOT=> +M,JW79D;&(<.6^6V9$2*']05FQ3N&5^K",E!5$[=&I(H"`!P!```<`0```@`` +M`$4``1B%S@``0!$``,"H`0'`J`$"`?0!]`$$!^FQB*+@PNX0.?F7IZR]H0-U +M+B`D"`````<```#\(0``X`&'#$3NGT*W6-<;&*)D$$8BW^AP7RN<(X#M4ND3 +ME:*+MWW_ZA?"(=9UQ;@1J^TO2/L@2H<\61'@5(WDFC^;O^QKJMH/'`*H!CX+ +MW#$LRV:36[!&+<84JI0XC(HK$E`=XI+#HMK2O[OQ<&&C-]MENY4WI/385IU7 +MB%]G":!%JE[8?JZ)'[-"BW]/:VX*P'606>_4MXAY-M/B/"VQIJGYRUN,E*\Q +M?2B=^1/ZK>#%RQ>GM.<%#;B>)5WCT,]N^`$-Z\D._JNOOA$]B8O +ME7UO6,O>C)X$:?@,'O!'3@5-SA,HU^G8LLE4O(=_J.9S,47] +MPR^:_-;AE\`<1(C0G:I$W*[9-0PI/70`L>$S:W(OIS'L5]F:WW)5$[=&@+P" +M`.P```#L`````@```$4``.B%T```0!$``,"H`0'`J`$"`?0!]`#4!KFQB*+@ +MPNX0.?F7IZR]H0-U+B`D(`````<```#,(0``L$=K7/X['#;HJMB;G8'PCD.G +MLA&C)E&H/:4QR&,+;#ZZ>OU[@F)NRMS[SK,8S3L`:5Z%ZE +M2[_8.'IX"/'MWYZIQE-(H<'')O0&M$F!_#.9D%J[_U!@J#/Q^`PSG@3M84DT +M>&!>TNLU8@<$P=5SJP\%U@E^,GU5$[=&Z^("`(P!``",`0```@```$4``8B% +MT0``0!$``,"H`0'`J`$"`?0!]`%T!UFQB*+@PNX0.?F7IZR]H0-U+B`D"``` +M``@```%L(0`!4&L0OOZS`:"E$,/L$Y$'3+6RL[[27+!=D^'*M>X+'$I09;J[ +MF$*5H/I$:TW&7EL,\>(M_4(\$I[<^4WRWX](J03H2F!^BW5!05P"O(06`J>0 +MOBJIL6(>\.223+6>V>;=NP"'\;.0[!7OK)`2$3%V1/_=FB``5O]3A9E5\3I!2I^^U,NP(&S0>=@!X:79I@P'8JX$(>,.,?A +M[2$QB?-G*)L67AATU290`*6LKL[S3>OX.:=GNR^>L;FTC95_R`R+@?)HRLYM +MEU[(\&[Y%'L"T_UVG)%5C-381[1MK$B>9@%W$^AA[]S_F02X!9`1@K2 +M[%29]W.KJ%KVY\G=>G`49TY/RZ7#UB#^'XE;%A5SBMT^(.-K:!:1?(,R(6^Z +MU%EZ]M?P%')Q\^4J;OG"A)]2>+1N]T%8!JS$51.W1C$8`P!<`0``7`$```(` +M``!%``%8A=(``$`1``#`J`$!P*@!`@'T`?0!1`LO:$# +M=2X@)"`````(```!/"$``2"2D!2\`E`?+OM&W#>#D4'^,T`3B6-W0`C[*MEI +MOL$7\[M^T1DMHI5[F@(?OY%7>61;'H0G)V=0,679D753>8&^+)DO46IE827H +M5+/H_H2('YAM$'+0Y8FT5-5F$D>*_9W.9,3U8UFB4\Y;DS%MI:CI^E_KG/F68H':1,>[HE(8_Y0AT +M@&Y>YE]P+I1%6#/._"<&L22KAFS)470@WHXAVR&FIY%K:[9'N#($ZW<"RYXT +M8,2W773V0DPR@FLG>@V24IR:'LM5EPX6#I!7C[7%_U43MT:K/@,`?````'P` +M```"````10``>(73``!`$0``P*@!`<"H`0(!]`'T`&0&29OJC,R]+ZBKZ=<2 +M"'^@P.LN("4(`````````%PJ``!`.4$_>N#`-FJ%.<'DQ4TN*6)V-[I8ON1! +M'#!0XT5]>A4UVVO[J)U)543MT;Y6`,`;````&P````"```` +M10``:(75``!`$0``P*@!`<"H`0(!]`'T`%0&.9OJC,R]+ZBKZ=<2"'^@P.LN +M("4(`````0```$PJ```P]-!FO=.]#]%A;*J@R@^NN%U*@.':@YW@*YL=8P)P +M4"(``'@```!T`0$` +M#`,(``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``2P^1XRWC`]0AQR(C&>7DI4S[ +MP!KUPXU@HPTW2UE9D'5?)].\)6-OP=$;0T%"ZM$ZTQ72>_'1OX:%JU/>](7&&[\ +M&5V;K6W,.S08?NE7X"$G"NRZDK$I```DXI?_<+50R<,LI;.!N28GPD'AT@PP +MLY=[&29E3IV:(;(I```<``!`!+1?&GB<;1&W`_!OGX3/U:IPZ6\GB>O5U*ICL%43MT;E<00`7````%P````"````10`` +M6(79``!`$0``P*@!`<"H`0(!]`'T`$0&*5,GTHK/-7,=```````````I("(@ +M`````````#P````@``!`!@````HJ_^2A>1[U41BLB,I\6,#S&M%";543MT8] +M@00`N`$``+@!```"````10`!M(7:``!`$0``P*@!`<"H`0(!]`'T`:`'A5,G +MTHK/-7,=```````````I("((`````````9@A```@``!`!@````HJ_^2A>1[U +M41BLB,I\6,#S&M%";2(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``2P^1XRWC`]0AQR(C&>7DI4S[P!KUPXU@HPTW2UE9D'5?)].\)6-O +MP=$;0T%"ZM$ZTQ72>_'1OX:%JU/>](7&&[\&5V;K6W,.S08?NE7X"$G"NRZDK$I +M```DXI?_<+50R<,LI;.!N28GPD'AT@PPLY=[&29E3IV:(;(I```<``!`!+1? +M&GB<;1&W`_!OGX3/U:IPZ6\GB>O5U*IC +ML%43MT:"J`0`4`$``%`!```"````10`!3(7>``!`$0``P*@!`<"H`0(!]`'T +M`3@''5,GTHK/-7,=A@P4?,%FTZTA("(@`````````3`B```P````+`$!``0# +M```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``.'E +M^0#DW0N===[1&ZI+Y>`3I*L;TR6[AWO_$@V]9"^X8*0``)#QFQ[YJ +M*O?\%$%;6SVL.)NK'5T/=>WG">`X;2W1VG6I*0``'```0`2*N0M6'$CX#7)- +M9.PUZ;X#=.P?[````!P``$`%R,-1(K]1.I"F4/?X[:Y`0#>H7XA5$[=&S-4$ +M``P!```,`0```@```$4``0B%WP``0!$``,"H`0'`J`$"`?0!]`#T!]E3)]** +MSS5S'88,%'S!9M.M+B`C"`````$```#L(P``T`_2IPFMSYR!DZ9_='7+08^5 +M[=GIK`-BI=0O0;)AOGZJ,E4;I$[H3&SODBH=WP5`IHB,@7H@&CO.XJOG"AE& +M011@9@_`Q!5;'/V9F*./]>B9J$O$Z.J:A-]#@XRP;6FC_+G1T'7E7L!$73PW[4AI5=!3`=6_,U!GWC)F#M6]EX&'C +MCR8%`ID%3E43MT8D[P0`O````+P````"````10``N(7@``!`$0``P*@!`<"H +M`0(!]`'T`*0&B5,GTHK/-7,=A@P4?,%FTZTN(",@`````0```)PD``"`)>D7 +M4Z!HO7"C9,QS=,:?[""#U+$:#R +M]R,,S=]M4:@8ILS8V>@"N9!5"WB\V]OTTL[B0LZ6-Y$TKZ]837O'EIXP+X#F +M@U%;,%"C/1R$YVC5K(P$%'ZY"T?\/I>Y=;X:&7\!7E43MT;`#04`'`$``!P! +M```"````10`!&(7A``!`$0``P*@!`<"H`0(!]`'T`00'Z5,GTHK/-7,=A@P4 +M?,%FTZTN("0(`````@```/PA``#@H_<[_L5WM6',JD$')9S.ZMWGT5-]*3'S +M@J4=90PF1XK?=M+J50VRR/>YUEYK>;?@C[$N8&T/E1RV/0\.-V"!:^"VY/.( +M^!W#RP+T%EU]\LYT=;ZH1$N6ZU'2`RAB1G](=#P&J>@*:?P%=]JBG`>M']O*R.YE3LKI@+8YL.H,;0H) +MD9^'QI,+,&-ZB?,@R=C7$PGJ=KK'Y!0B`E +MG*VK%C5C*FQM"HM6@IG.MU43MT9_$P4`_````/P````"````10``^(7B``!` +M$0``P*@!`<"H`0(!]`'T`.0&R5,GTHK/-7,=A@P4?,%FTZTN("0(`````P`` +M`-PA``#`LK+:IF!_N"B[/1-0=IF5^DH70(X6`[2M#,I+`E?+`O%83+ZP;F8> +ML`D`"'F&F8Y-I^HR>/BC)`N\VF%^Y(@B1\>.^1H&UG),/RL3AL=BJ(_-SU47 +M?7Y#>V:WOF81,AO!<_`,V-6=1-X(/O^'(YEAMBU>27IIH8V"3L+!^U74&NN> +M3T@&1/!2&2;,PJ:5;F\@V(*(;3DFRXG@/_JN;G";P^N1UP",Y2#N"<^(=/@2 +M5:SA[]0:*#VX@\JN[0I5$[=&^R,%`&P```!L`````@```$4``&B%XP``0!$` +M`,"H`0'`J`$"`?0!]`!4!CE3)]**SS5S'88,%'S!9M.M+B`D(`````(```!, +M*0``,'&2\EMBVG(&F?BDM_]_URY!URD`R=X(@H?V]GLE.\X]X9I)[]5I*J'% +M.G0``$`1``#`J`$!P*@!`@'T +M`?0`5`8Y4R?2BL\U:WQ +M(;#!]1_$O%>=@IM0WXYRJT:8V`5*+P\=>C8+*4YX5'L62_O&`U43MT;P6@4` +M/`$``#P!```"````10`!.(7E``!`$0``P*@!`<"H`0(!]`'T`20'"5,GTHK/ +M-7,=A@P4?,%FTZTN("0(````!````1PA``$`]7]&GW.2KQA5V^C3?-C_CG9% +MF?OG+_GM:TTC,M#@T2\J%6QR=#1JJ"5#K%EGTAI[L47#YM:-W%[LF?%?-QE\ +MA.5?8?F[Z"5FR*6KY">0#!N(FO.=A0)P&7>9CR'O+-A'5_3`]-2$T9,#-FE]X$N)8U"F=C9 +M7;35$I)MOMC(ZYZ[F/(&,!'0'Z977C=`)%9,42!,6_V"5+UP_M&UU_G%M[BCWM`,PGK +MI?N"OK6`6C$M51.W1OMF!0`<`0``'`$```(```!%``$8A>8``$`1``#`J`$! +MP*@!`@'T`?0!!`?I4R?2BL\UIL]*M1P9:J;OD]9XTBYV6E6SA$$1?FT_YG?,(4LCE'7&^+<\_L#JPF.&G*+'C$KW. +M8'=%U3#'S,/OZ#5_'6^E"&!H/-G:K`Q%!01^5S__]_P9DJZF]U(U>LE42(UK +ML5)[K!$*KX;;S=?1P*KF^V^"IHX9Q%/-R[[KI,-/PM$/I.\S$SBX51.W1I%V +M!0#L````[`````(```!%``#HA><``$`1``#`J`$!P*@!`@'T`?0`U`:Y4R?2 +MBL\U`)`$.1B%2\N\HX2_#SWV\5(IZ +M!*[>^/I'F"\S"#^Z16\(7O)4`N^*5E8J<..L`[BG].J%+:GHZ)!X51.W1NF8!0#L````[`````(```!%``#H +MA>@``$`1``#`J`$!P*@!`@'T`?0`U`:Y4R?2BL\UME^*MC_>NYT +M"YT)KF_79+@$NOF9EV/CT&);\5S8)0(ZV\@8*^9PPB#KCB$#3-%&+B+0'0!% +M\&4+_3[94&]7F4ASKJ/NID``$`1``#`J`$!P*@!`@'T +M`?0!)`<)4R?2BL\UXELQE(K<-YM?AT@R\3TE!!'=3HS0:*(#2R7>72E_* +M"G'?M`JIK!'I4]"F:N=3Y7DF=\>3R/=7QC-4!Z@"?!I-HJ%Y&\*>+5Q[:1FY +M0'$S\]BU[-,U5:2:)+&?;E1@!EUD&&=NM8*B!7[HCOK(`[@T9+K +MBTSTY:0,ZY@Z4I*..1Z6OR9-`8:**+5>IT@012\4M!,WO:[^PIEYL8U:A![8 +M;%Z%;B`;OO)W5"XIU'<,SW%<@M:G;I".O-M$S]*=L-H2$`!%B9[Z(!IBP'B7 +MX/ZW)-*P%&XIF@/$DF:FUQA*K[=5$[=&[<(%`!P!```<`0```@```$4``1B% +MZ@``0!$``,"H`0'`J`$"`?0!]`$$!^E3)]**SS5S'88,%'S!9M.M+B`D"``` +M``<```#\(0``X(DTJYJ9^>G7H2Z6%\NZEL+XQ1N7@/I")6WZ$64$>J5IO!BF +M3"!,G57X';"BS[&4Q$H9(T<5.B7\HW;WXO^Q>KR:.8[*!F\MB/9V20<@S&\* +MQRV$!6I`^AP?#=3;78L(/F&W_39N-(:PN06U7QO:%^E`&.;8[##C1T$/P)WV +M#\\JW26M%POVB;^*^VO$JZ7-D8HD$EVB>C?U#P%3X?=RT;\(C0L"""^C\^(YZE`U&TZU_]=''P;,VDM(=$@Q;T&%'/3=^'L=G!"7VB-2..DW;.:2KC4@;)` +M-N*=O9I:#E\(_"Q`ARN011B?_95-9RRO^/SBL\/QE/RT5N^BKPF'+RFDF6[X +M+;\3+Y>4NZ_#5`-=1[S1J`I*_X,O1OM:XTU173GYZ]=5$[=&6_0%`.P```#L +M`````@```$4``.B%[```0!$``,"H`0'`J`$"`?0!]`#4!KE3)]**SS5S'88, +M%'S!9M.M+B`D(`````<```#,(0``L)'CQSZ_\C)3N'*?$@[A.B_6:^/.Q_WA +M]($'\FTF2IBL<4*7A!^LBHW^(E,W8WL'W;#4N2M/B(,]ZEOR6`RCS7E)3K*# +M'W`-]T]U=&$N^A":'AFCV%/,7%$!;A>E',[,?3PMGL?+WKNWFL2_-GO +M\.Y=PA#^6[=EIBB29VD`\U;0?Y/=6MI$-QGL-A>`\R+B +MKLQ^&$"./!R-Z0:TX*`X;S=,!RK?.FCXH<*_2("G((;)Q"<<-]IM;J/=JIYD +ME<=N.@1XL^65Y;VQ>_-^F@>WU0OIT>54D01(>&DNHG4*P#EN)`![3#P2?",. +MU'#XC+8W7(?5*N?ZJ[`W_2IBP;,J%6'[4]?LJ%`SX``$`1``#`J`$!P*@!`@'T`?0!1`LEV)<@8;@\63J"D\GA$Y%.`OALT>Z`('E4P@<:Q]-)(:A5!PT,WRQ.M8SN"ZJOH8('X<';AXFN0\9=H'A +M4R<#:NYTD5T.KQH`K!)1,U#@KUNX3Z_\=1?4H1#&N5<"B/Q_.B-J#82[V+A0 +MCFIJ/6S]D;UEQ8!^%\9);&;:%40>'C'B;%43MT;A=08`?````'P````"```` +M10``>(7O``!`$0``P*@!`<"H`0(!]`'T`&0&2;H:T#U:,>?M;'U:P^HG0@DN +M("4(`````````%PJ``!`:)*8\Y%?F$[=Y9P8%>YGN:0V[WVCEF'K3U43MT9[D08`;````&P````"````10``:(7Q +M``!`$0``P*@!`<"H`0(!]`'T`%0&.;H:T#U:,>?M;'U:P^HG0@DN("4(```` +M`0```$PJ```P9TN3*$INB,I63+]U62[W+G\A]D^[_HGXO(P/<@L$)>AE06,R +M1RC-M_`E_D!5$[=&!Y\&`&P```!L`````@```$4``&B%\@``0!$``,"H`0'` +MJ`$"`?0!]`!4!CFZ&M`]6C'G[6Q]6L/J)T()+B`E(`````$```!,````,'5P +MT3ID#O$KO7OWQ1+ZZV0+VVTDL&+R\Z\.6L)5V4^ZU0M'7_%19H,I2;3?51.W +M1L&=!P"8`0``F`$```(```!%``&4A?4``$`1``#`J`$!P*@!`@'T`?0!@`=E +MP`/.<\:B33X``````````"$@(@@````````!>"(``'@```!T`0$`#`,)``P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``G=7JO$;!B;"4)>R-25/O*Q&3`==`A6[U!I`+*-^-MDU(XZ=WF +M'/?*WAX,%=U$5>%PNGDI```D`$QB5HA'HSK:TS`($5\4-.<,98$W\?"V`'FV +MB7J$1;\I```<``!`!!.(:*VGE-K>P2RK^?.!L<@G?`O1````'```0`57NH?/ +M?/?V7",@`+R^'NE,053*J543MT:+K`<`7````%P````"````10``6(7V``!` +M$0``P*@!`<"H`0(!]`'T`$0&*<`#SG/&HDT^```````````I("(@```````` +M`#P````@``!`!@````KE=,+%[+E(+?M110!N0FL$94`Q8543MT8LO`<`N`$` +M`+@!```"````10`!M(7W``!`$0``P*@!`<"H`0(!]`'T`:`'A<`#SG/&HDT^ +M```````````I("((`````````9@A```@``!`!@````KE=,+%[+E(+?M110!N +M0FL$94`Q82(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MG=7JO$;!B;"4)>R-2 +M5/O*Q&3`==`A6[U!I`+*-^-MDU(XZ=WF'/?*WAX,%=U$5>%PNGDI```D`$QB +M5HA'HSK:TS`($5\4-.<,98$W\?"V`'FVB7J$1;\I```<``!`!!.(:*VGE-K> +MP2RK^?.!L<@G?`O1````'```0`57NH?/?/?V7",@`+R^'NE,053*J543MT;D +MWP<`4`$``%`!```"````10`!3(7X``!`$0``P*@!`<"H`0(!]`'T`3@''<`# +MSG/&HDT^2*V(@S9_R-XA("(@`````````3`B```P````+`$!``0#```,`0`` +M#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``)TPK(%FM<4W +M\UY!;CTI-HA3-"G/\OC`N89LS2HSXF)WGI!EI.94+G2>I_[8M_CD="(^99UL +M9I#3?-WVU,#;&=05'ROP3\+-C9J#C:KLV!N;!`V!5"C-!Z?F&,D,X_HQX.Y! +MHL,%3_1*#FP/B$I7',%G]XR9HV2D:S]W`K0;KBB3*0``)-+N]TF5#0F&5QLY +MS:2A"HG9.LWG00KOOD[<0O";$)*K*0``'```0`36%0[61GW'/(7I254^RS+? +MO3@TG@```!P``$`%@\@UC?T_?E!PRLL5/=>UY@4PY8!5$[=&<@T(``P!```, +M`0```@```$4``0B%^0``0!$``,"H`0'`J`$"`?0!]`#T!]G``\YSQJ)-/DBM +MB(,V?\C>+B`C"`````$```#L(P``T%$&MHV2]$B)>NAY;CD`C#Z8U+Y@C)D@ +M0Q_(@*.N6OU$4[XJ]V`>O_3Z#]"3L^ +M#+^T"WY=U[XC5Y9^M06&1Z0N\[F/;-KZS36/,3_Q;:K:A//*0ZVA9O1OT0K^ +M#;O=]JRFZ<1\"(=W(!E`4EG36[P.]8/BZI,N-7T;VNNPY=STJ[M+40AN\\$- +M?E43MT;T)@@`O````+P````"````10``N(7Z``!`$0``P*@!`<"H`0(!]`'T +M`*0&B<`#SG/&HDT^2*V(@S9_R-XN(",@`````0```)PD``"`XVU,8AO4Z@SQ +M6\4;)$B/BVJ;V].IXXNJ?Y=M,61"IEJIIDS'^P!)2Q%S`M47&(5OD)^%F[%Z +M]T_C6'&.PDPH]30Y:$$>N89*?MB[Z5E^`2CM#0B%\MY9NAT5 +MM<)WKC+4FRT3;<1^;#BN.R^)9%X)PU[S>]GZ>S_!1J&HB>4Q+=6M[;DH6YQ-)/2[$NHQ'<]W0B?EH +M\2!!0%^5K?,KBE43MT9%5P@`_````/P````"````10``^(7\``!`$0``P*@! +M`<"H`0(!]`'T`.0&R<`#SG/&HDT^2*V(@S9_R-XN("0(`````P```-PA``#` +M+`NLG?10*'_BF^$/Y$XPBFA12GPS&?;K-P>2)B-)_)*Y*R;LYC/\N.8N(G53QA%TLD**:W'`B_K-V,9KX"86W7ZZ$ +M!H^B_[ILB9?,T83</]TY)?82`5.+B`D(`````(```!,*0``,*I8 +MG<:*[#XT3Z_-FGQ!$T\MB/+9SR[(^()E24I!>JI\,2:>:H8\K2HVE5CI51.W +M1IEV"`!L````;`````(```!%``!HA?X``$`1``#`J`$!P*@!`@'T`?0`5`8Y +MP`/.<\:B33Y(K8B#-G_(WBX@)"`````#````3"D``#"<=Y1&6X0#WWFV-YO +M/"G]0IRH[`[E%94SB"*IE:"<5^E*(`7/I+;:;HZ-3EA]Z-Q``0-2^N2:$_#?MJR)JC +MAB%:;9XF\24NH`1AB`G)JSCF,HM@O[Y*>7-0U=M1$1X*@>,6"%2^QOO2+2EW +M-9-D)`\:>9-J'F(\\&KKTX]!,@E]@CHY,_H[WLFO]/8WK&8/6IX6VE]LI0T9VU'VV"U4*)3C +M\,2&51.W1K:="``<`0``'`$```(```!%``$8A@```$`1``#`J`$!P*@!`@'T +M`?0!!`?IP`/.<\:B33Y(K8B#-G_(WBX@)`@````%````_"$``.!X?ZJ;)UX$ +M.!&K*9.W"G&&C`ON1Y[POM3Q?S)-6PI2G)XXF[K$8L6,:-XQ\U`X]>B];#_A +M\$0DCQ"<"-HUG`[G=AJI93\4.W%VGK,Z4-Q&)V%H +MWV*).Z3[9Z6LKI91&^[_S,C;G^HVW6`6Y@:>N=FJ;JX$51.W1A:M"`#L```` +M[`````(```!%``#HA@$``$`1``#`J`$!P*@!`@'T`?0`U`:YP`/.<\:B33Y( +MK8B#-G_(WBX@)"`````$````S"$``+#)B,G#/DX!=CGL%2BR**`U^D"Q +MPP>`48=3S-E.PIL3*33S.E]U$@M)*#$B125=]AV?MZ_AX5QFLHGB?,/TZ&(' +M?AHW\AVF$>JR-L8:L>B<.8#A&Q@`LLMCFZ+IS3Q@LG)WT1O*N@QKQ;?%;U.`9TD/"OQ!49:(-"UG.@ +MWI`JT3-S!S`MI`^1Q$^+51.W1OC."`#L````[`````(```!%``#HA@(``$`1 +M``#`J`$!P*@!`@'T`?0`U`:YP`/.<\:B33Y(K8B#-G_(WBX@)"`````%```` +MS"$``+##YH/I-'2T/S?<&V5K';M0;;2M_E?Z26@XO*RZG*6MJKJ<^*9+XF6- +M@Y]778(WPIY_F;>G1&+PSV4I7_Y.L?/MN.(V +M0&13."D"[H/*T2EO&X2]W,`$4OT]!*)1QE>2BJ[6QJB@4`(0K"&X&YTB(M^G +MD%O7[U^;X0(YAWY3=TL$W\@??\N8#^[5A[V=0<^W>^1ON3UD3*.Y^)LG51.W +M1G7K"``\`0``/`$```(```!%``$XA@,``$`1``#`J`$!P*@!`@'T`?0!)`<) +MP`/.<\:B33Y(K8B#-G_(WBX@)`@````&```!'"$``0!\V2VT]C>'75%LM0,3 +M<-E2$< +MQCF^7`VO?X->_4VM5T@_2E(04_M=`1^1<>.'Z<[&H1R%&E*%5-0?%,0FR+TR +MV*D20IT,0L!EPCWG5@-_+&>MJ"J+RV0N8)2@T(_[LU'@T +M'2+/KJA)UF0!1,NHGSJ3F7.#KR,`@.Y[(IY_^,M.W`M//K%$^@^9-6[JU^B5 +M,_]`O,@1[X?`P[5QXE!5$[=&RO<(`!P!```<`0```@```$4``1B&!```0!$` +M`,"H`0'`J`$"`?0!]`$$!^G``\YSQJ)-/DBMB(,V?\C>+B`D"`````<```#\ +M(0``X!QFJ0'1GP8A=3UH<_]Z42-SL:BWW@CF]:JT@14KG$&:`\!-`JD]L +ME#=2H\%1(>U0>W6Z#.XP%.`<'GUO*\P%"!_\U('_<+QKZZ7.UE""C5%4@HR? +MX]&$43OP+IQWH(&?JA26U%9VCV/%VU^U7IVS$Q[_1B7+RRK03+G47>1?<5$. +M^>#"XP,HQ172_GD3^,#;`M\+$1*:#0@D$Z%TZ^Y;.0Y,UI0:69R]&4%L;]AX +MEN+>WN[)(XZEFS0-@*A>/QIB177&323PZA5&UV(AGXLM18K?YW/U)T,QNM]5 +M$[=&0P<)`.P```#L`````@```$4``.B&!0``0!$``,"H`0'`J`$"`?0!]`#4 +M!KG``\YSQJ)-/DBMB(,V?\C>+B`D(`````8```#,(0``L`D[HD40<_%-DZ`$ +MV<$T`&,1YU!:RRP'`82MZOVWN-IU43').J3U2$Z3A,3'"G$:WAY3?*#^J<[F +M]7^^/Q^:7%>)WAU7OACE5CY;5.;KJ5?Z#=M0,L2QZB&RN%S2+<\`O-?I07G@ +M:1#"OARYG5Y*@]7T?1<4.-1@OS'*A]1:BCM]]SP7,S2C2.")JFCA6X5,BQB" +MOJ\2K84A3M>);]:W-2W!I7+]65ZF1XX/MWM5$[=&T"D)`.P```#L`````@`` +M`$4``.B&!@``0!$``,"H`0'`J`$"`?0!]`#4!KG``\YSQJ)-/DBMB(,V?\C> +M+B`D(`````<```#,(0``L%@TP$V1=DCNWL'6,O@DC02*.\0*:HX-Q3>2^X&Z +M?>J1.O/Q\4W_I&Y5V*M*V*/X%Q9\$C(J(+813$JM1G$]MR8@>A+NELQ,,(C0/(@;294@=,-,*1#TTPW"3&L +MJ:51V(CI9I#&88G[E+7>Q@=HQ/Q<+B`D"`````@```%L(0`!4/>6 +MZV]7RF7XMW.*)\)=/84S]#^'/AI!8T#J?MU_B;DI7@B.G3@3.->C,X4EECHH=<("15F41:ZO[IKC/6IM,HV)V09P3 +M?K8.5D=930E]#"@*4Q$HD5S'47HNZ7'Y/U`5GX5V!'36;]2UCRU^R=^UI\H3 +MFH$91`\]T0=)8'.?9L*ST$)R1]+3HW&SPQU>OOC2`5F0`E;J+9A,RVF;0$"J +M?C65A$-K,D/WL$2L[C0VQ_8L!'[QO?S54NH[&7,]^>YM@C:RQ[3M`'=H)CPR#Q&%ZE/+ +MK!<+F(JQ#8KE"@,]4N$T54)V`Z\T7%L$O*41K+DWX0I*][.6IF.+7QE*]!DZ +M=@TI'Y,LHG2AP'L&KIO"Z'!%'U43MT:5J@D`?````'P````"````10``>(8) +M``!`$0``P*@!`<"H`0(!]`'T`&0&28,6Q30ZB%3E!@L=:5;2V4LN("4(```` +M`````%PJ``!`>^L)<#NIZTCX(;$R<#+"I(>4]\'MN6$]`6\3]:QRYJR---'` +M:5H(OM\#H*?D6.;<;2J(#FK/]@EP`H2Y51.W1NRU"0!L````;`````(```!% +M``!HA@H``$`1``#`J`$!P*@!`@'T`?0`5`8Y@Q;%-#J(5.4&"QUI5M+92RX@ +M)2``````````3````#!U:MX+#_PJ\B6KV,#PKQ.[BG=]D]K3\4YMV__F=@"E +MW_?<`KUP89GPK0XB7%43MT90Q`D`;````&P````"````10``:(8+``!`$0`` +MP*@!`<"H`0(!]`'T`%0&.8,6Q30ZB%3E!@L=:5;2V4LN("4(`````0```$PJ +M```P\@[+21.NC.B$MR/NV3&X6/5B_JMH6S4`SZ\W$_.B[I`Z'P)F7GJBAT2) +M#%!5$[=&&=4)`&P```!L`````@```$4``&B&#```0!$``,"H`0'`J`$"`?0! +M]`!4!CF#%L4T.HA4Y08+'6E6TME++B`E(`````$```!,````,!DX$>&V3R;9 +M_;)"(``'@```!T`0$`#`/_``P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``SN4@D71TKC]S[HM@TT77-2T,(PF/>8<"F:4(7CDD%E^QKS:-A`8Z.U"L[P+K-&`&*\7X=4 +M\F%+^E%JXBJ9F30.TD''8A_3J&J,ZJ>J'6X-9F[9S/.L1P54'D8B?,K])5=7````'```0`4^BBD&,J8F:2P\ +M%=$9L\'%+I:M,%43MT:^X@H`7````%P````"````10``6(8.``!`$0``P*@! +M`<"H`0(!]`'T`$0&*>T=Z&_SRM&G```````````I("(@`````````#P````@ +M``!`!@````K!D2N"KVZLMIT=Z&_SRM&G```````` +M```I("((`````````9@A```@``!`!@````K!D2N"KVZLMI/>8<"F:4(7C +MDD%E^QKS:-A`8Z.U"L[P+K-&`&*\7X=4\F%+^E%JXBJ9F30.TD''8A_3J&J, +MZJ>J'6X-9F[9S/.L1P54'D8B +M?,K])5=7````'```0`4^BBD&,J8F:2P\%=$9L\'%+I:M,%43MT8*%@L`4`$` +M`%`!```"````10`!3(80``!`$0``P*@!`<"H`0(!]`'T`3@''>T=Z&_SRM&G +MW<5`D@('/O(A("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`# +M```(`@```@,```@#```"````"`0```(H``"(``(``/]JC@L"[647QEW7)+N^ +M`.CA*;_@E3S4YWL(-37_/0A]5M1JFLBC=7^.-]*^Z@WDYEQ%2A1>/&2UW+A_ +MN_OO-Y&WMC$C(ZB2HH-HFSN'GT$\4$(W;"O+H%D##VW'5&0N&HIDJ?;1C4!K +MIUIAK4Y^WYVTV7IK);D]QC2M8SA]400T*0``)`%('I$2FB6_XW##RF]RHW&G +M"':Z[LC=JUE_PD8,?@SG*0``'```0`0WGEA'(-;YJ@\;LVZ.XU#Z+I%/@@`` +M`!P``$`%.AU1C%@UWH'+*R<)AO\\K1I]W%0)("!S[R +M+B`C"`````$```#L(P``T%[NR]6.>SW71#AXL04A7^LDPQ3%;RQ4CDODO0'" +MI>S4T_OS7<>.[;/V58*VU]'A%BP"HLEE;,0T)HOP[>2`$>E9,K1U1L^+6CLN +M'6BKOW0KO3B7"[(>+:+8[0@H-,\C#-Y:J[ZY^>=#G>V#?"(ZOF+1LJG#UU*Q +M'MRO+NDZ"D&+38JI`LI89F;H\K'BV19U-<$1YC*F^?/!AK=?A^`'3YSAM'_[ +MGK$H0BT49WM+T= +MZ&_SRM&GW<5`D@('/O(N(",@`````0```)PD``"`%$>V6F-VA.@E!Z*.\0_( +MM`B&>BB7_UEYU@92K=:#?#&3V.OV?$HR[\.H3O<5^]7IR#N"Z?%JZLOP^Z17 +M*?*5GDHO4ZQ[DS`;;T_/5E43MT9<>@L`'`$``!P!```"````10`!&(83 +M``!`$0``P*@!`<"H`0(!]`'T`00'Z>T=Z&_SRM&GW<5`D@('/O(N("0(```` +M`@```/PA``#@^^;.P-W:_.PF94P(."AZ7=%`;-PEQ6HU[BR9O61Y=4Q[LI;: +M<:/(B&)[UU'":+TL*$JPF<@^GG>2;BO%.2O!W/`RWB(02/CX!)<8/1.6`J&PDR_O3L13[\1W$'C=H2K9?B)-T%C/I;)5A%-<.`:O\P +M^SL+EK]'`@-,X"+]RR\K6H[?OK9?G.D7ZC#5%;H2+G%`,0O9^=^Y?VDGT5@K +MC<0RJE43MT9MA0L`_````/P````"````10``^(84``!`$0``P*@!`<"H`0(! +M]`'T`.0&R>T=Z&_SRM&GW<5`D@('/O(N("0(`````P```-PA``#`GE&U'6'- +M1EC=,J'C4DH,ON:&H!7S=G!?PAP82W`?NJ%O9YSF\4/*#'0^B#S>10;H50;) +MZS2B@FV=/LP&'ZS"=32YM?#^7P\O!UO#4<8D:I%Q`$KX1N-\_"5K/XP]TF+/ +M.2N6A+T(AJ\%:"L7`Z?OF**[(#VTF$$K[1U^WS6\\5@2Q%-M65&OW97]64\" +M3]<@)YMDR>N9`Z3[JM2L^R;\V?;;!O%[B'=%`=Q09?AO\\K1I]W%0)("!S[R+B`D(`````(```!,*0``,%.09.5V'/2* +MRQKN`">5SG.T@JFZ8&8\`7U%*2$:OZ=`(:]Q@4XF165>LF8X51.W1ABM"P!L +M````;`````(```!%``!HAA8``$`1``#`J`$!P*@!`@'T`?0`5`8Y[1WH;_/* +MT:?=Q4"2`@<^\BX@)"`````#````3"D``##Q1HGQS3[8#=G.H]:H^V/';)^* +M/S(@SL6(#:ZL2(;IZR89"N'9#E_"%6EFOU43MT:T=Z&_SRM&GW<5`D@('/O(N +M("0(````!````1PA``$`["7,JV6UJ25#FQ6V'CQT!(>P,64?TEP<:KTT>Z`I>K&&2A:/,2[ +M+3.VM'X@#K3#GL:W+-RH.YQW&NKL32G?>__,9._Z[Y_;I=;[H#STH$C;+H;8 +M@%Q@,`'FB#K.0M&_Y("FH6F,PS)E+\'O)Q0(C3H +MUV\4,]C&])[HVW-;IP)M>)P:_$["0>%[_HQ>#3KM;R35X$$`1\I_Z9ZX+,`1 +MOC-(0.&4QPLE95@#)/_0:]AJ;55H2RJY=G@<-[[_8)2TU6EQ1"MW/=+#51.W +M1B;3"P`<`0``'`$```(```!%``$8AA@``$`1``#`J`$!P*@!`@'T`?0!!`?I +M[1WH;_/*T:?=Q4"2`@<^\BX@)`@````%````_"$``.`T.0E@M6:]D4)U4#8L +M&+32V>.$I$Y0F&)8->;S(!W">?<;^.#UJ\.@;+!R0;_5OE65.ZX5@PMO4@_J +MO`,=_'DV&46$YL(CGQC#$PB1X<4-PV`KTQ'1-/`DQ.B&)QX#$L;EY:PI3F?U +M(#9PDTF3[##N7O*I%)VLI>(I&K0-5S=Q.]+$DHOT#'L`AP14=W)^?E?QMN%R +MX\R+>I^%RP1?<"OQ1D!Y)4O,(P62#,9-U +MAC=FV?>QE*PO5/I5%2(J*^KO=<7JK$6F$``X!PR#_%RO0;`/^VSH4H7:J;L+ +M;H$XEYL":D4-VR:-B8RD7,!)F\L96M4<>2T=GMG +MPW==IK)#/@4'51.W1@T%#`#L````[`````(```!%``#HAAH``$`1``#`J`$! +MP*@!`@'T`?0`U`:Y[1WH;_/*T:?=Q4"2`@<^\BX@)"`````%````S"$``+#[ +M4M-";QG=NU.D-[-#8JX;(-2NW26'>YSN5_6^?\B2!F>']W2#@.P$0:D9A+RM$!-X)FF&J66KV)QL6:,'::.;/Y0-A0G"0 +ML33UU5Z;0&@S16FW)4LB[>@=0GW"Z.5,BO.163\-1;]$YKI4$FVU'_7-BSV) +M"8%!E-\85*3C5O[@R12'D4)5>/=LU"/_D+O9(VMOS(H`E:HSO9GC8N@W/N=Q +MHQ5VKG]+UR`?=,,4&=R,4(@KV3>M=T^[1]O#-E0;U61J&-P('F,P!/98)59X +M[FX\'\C0*'!5$[=&XBT,`!P!```<`0```@```$4``1B&'```0!$``,"H`0'` +MJ`$"`?0!]`$$!^GM'>AO\\K1I]W%0)("!S[R+B`D"`````<```#\(0``X`)` +M%>T?A\2%6`I'A7W6F7RH;D*,SQ/[HZ%I;]3+!+4W6>^I6+T?@D"@-00#]7:] +M8".(:WY7#GDH;4Q1,V<4&ML[UF(OC1Q4EX4?`F"/ +MWCI.MYKC[>,H]^A&B"U.$$]D:K>UIJ\:0*I+']7GCR]\BOID_:I'A?TJD,1M +M*P:KFG*3L(DN_Y+;;64=8?'M`:-J')`LCS8&U+0&M(@\P:D!AG,*)_@<.TO& +MAO +M\\K1I]W%0)("!S[R+B`D(`````8```#,(0``L/AX9=?S;%?40KM0$CI^7NEU95"IEO["X_ +MX[[^#QXB5QL&T=VYD/ZO:N2'[?5>IX^K37_,;S\P.3?,$[@Q5Y%[N\.P:,KU +M#K.@J+CM17.>8T:E]0_3;"473.=5$[=&D6`,`.P```#L`````@```$4``.B& +M'@``0!$``,"H`0'`J`$"`?0!]`#4!KGM'>AO\\K1I]W%0)("!S[R+B`D(``` +M``<```#,(0``L((JU$=*:CY.<^.2]C9Q.NI]Q$C)#I(IEU#P%FK%8Q$?9Y^T +MWI.&V02DVBM)4.;`6_C1G\QT@/KGQ^2?UA=\\WYY1X6]A1.4Z#[Z3)\P"/I@ +M4;VS&X"2"^I8$S;&TQ^&#V#G=FLODX\!F7RUVK7.50A*J?)Q*=46A6,59!`0 +M"&ZIAU8;J0.-(YHLKD%[]'DEE()#@-[*K\:*_4FTYJ?, +M9%Y5$[=&@X8,`(P!``",`0```@```$4``8B&'P``0!$``,"H`0'`J`$"`?0! +M]`%T!UGM'>AO\\K1I]W%0)("!S[R+B`D"`````@```%L(0`!4%M4=]^0C7V, +M.4#MR==RZ6J#IB0:IHG!N6F%-J;`WDZIT-/91G8?L(C]7_"GB7:2Q!M-.`1S +M.0"N:OK+O(Y+C1E,JTZ!$MK^>JU/+54\8FB.*B*=CW1B!)@&T&,RXD$&_9^P +M!O23L2;L^U>0TF>P=;-A,V*T\2MX<*S\9[54KBNB%EA/-\GY5]](PDHEWAGY +M+^0PO\.+2'B-7^,%21[EL&W$+<9/+IY!]MV>@IW=3PNF32`0MYFUC.R)U1G@ +ME1O/7P3T_4VN9#W2.-A!F-0\Q%8,VU(/OY4'3SMUC/"R8$/";>;V;@_"+&N. +MPIQ5BKW6:_FH1K2"KW3KG+-!`\(\TR+X%:@^@,W8*5?PC4D>CS3D)/`&+ALW +M?64SY?>YD2"L/FG>!?*X4BD@71ITQN%AO-E`'Q:RA3/]5)"0@?8,Y.9@.X=' +MZTPHT33J$5H$51.W1O2Z#`!<`0``7`$```(```!%``%8AB```$`1``#`J`$! +MP*@!`@'T`?0!1`H](+@=0^,P&50PM+""%383B?FY`M`_ +MIO#4(WW)FG?YDDGZTYZ>LGM%.^VJA[K_+J5?*L961%5:+OK'U8JV+9=P:>'S +MO*(78.J0?&\1!=NLBQ\.V/-?U(03JWV;TI$!QXPZR7H91,<7_%V9.8XC6(KE +M*.75/C/HFK0/UVS'^>)`&ZXXR`PRJ*R(#!K9 +MCJTB(M`:)>0/,0[RIW9]L\\?><+;]MDR'I"KYS?PFOQ8K':)X"G_",D98.DY +M9*:._9QAI7**2AB66LDXX/(9T +M`7G,)#4>,<]T/&>=/%43MT8*X@P`?````'P````"````10``>(8A``!`$0`` +MP*@!`<"H`0(!]`'T`&0&2;IJ'6-,NU;KRN4;9U"N;>\N("4(`````````%PJ +M``!``V/KQ*V,EK5\4':B9I.?PQWXF01A?GE#>451.W1A[M#`!L````;`````(```!%``!HAB(` +M`$`1``#`J`$!P*@!`@'T`?0`5`8YNFH=8TR[5NO*Y1MG4*YM[RX@)2`````` +M````3````#"FN$[4]/TWD';Z]DM>/4Z\N("4(`````0```$PJ```P!&W9 +M'FWLS-XUP6LV#2XQRM'+$[S4/%"Q.JI[0>@2)'GZ6TFF'&ZSE=)>(J15$[=& +MA0D-`&P```!L`````@```$4``&B&)```0!$``,"H`0'`J`$"`?0!]`!4!CFZ +M:AUC3+M6Z\KE&V=0KFWO+B`E(`````$```!,````,(5V"Z(8BP?K$S.KP+>@ +MF[`/R*GVL8H*S-M3.B1]$?HSGJM`4VUJSXM;C7J:51.W1IP$#@"8`0``F`$` +M``(```!%``&4AB4``$`1``#`J`$!P*@!`@'T`?0!@`=E>9,?Z,3RGR<````` +M`````"$@(@@````````!>"(``'@```!T`0$`#`.```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``6RX.:E(H_U,_^:)7;6L$G&@?=&Y]LQ>'=$"F53V,V%@$:2R/ +MR'[Z>[;Y?5F]`)JL:6+1(8`(33:L,_2BJ0@7;&;P]8,B;G_C)VSRHI```<``!` +M!%4)J?(:O&]<]AX]6'=$"F53V,V%@$:2R/R'[Z>[;Y?5F]`)JL:6+1(8`(33:L +M,_ +M2BJ0@7;&;P]8,B;G_C)VSRHI```<``!`!%4)J?(:O&]<]AX]6"!,ZH(`30NE3*0``)(V_>Q1=\M5P::KAI9@2,Z6-&&KO;E#M +MVZO;RBU>D7&6*0``'```0`0C`B[/L[.0!:L54_FUC^Y94(''N@```!P``$`% +MCH_23TV^63P(6XVU0ETGD*W4UFFVAM"(45:B/XR +M(S&L>B_VRK>CP^\!RV5\#T:HFQ/G]-(>'ZW=^8[F=QXFI729PH(.RC;K6S_, +M1"7HBJ=6Q('*$T]:\F->8M\OC,OU3FJ1Y1/C4&D7_A$'GFU#-'T-FS9IE?G: +M?XM0,U`H"RPM3^2N4GWI?WT#?YS]?JT*X@O.EBQ^3J?)(?^Q;TCGB&ZXX!3I +MBEZOGN"&C%CM;.)D<\KIDPUO-X^26E&GV:5IPB9G'EP5V%43MT9%DPX`O``` +M`+P````"````10``N(8J``!`$0``P*@!`<"H`0(!]`'T`*0&B7F3'^C$\I\G +M(VK\G8E1W-@N(",@`````0```)PD``"`[@='H70[C@@CXN[;4OC1!4[NB3", +M'&]*WNEA59>Z0VMNG2.I4-\K)NXO0V0:H&,]/DKH=!)U1\`DDGJZ%I^W0N6U +MS!\:F@(SSX)'K]+&>N*"F4VH'`VG*Z`:'W$:8:S\BZ5@($N+CE>OP13_#Q.U +MI6S-IR'GD5=BM7].-543MT:&L0X`'`$``!P!```"````10`!&(8K``!`$0`` +MP*@!`<"H`0(!]`'T`00'Z7F3'^C$\I\G(VK\G8E1W-@N("0(`````@```/PA +M``#@S>(/+R/!>KPOTC4&C#0N>P=/)']Y76$J)1#1*#8/N'5(>CX/PPBOU;&A +M\Z76ON)PUN[9SBFNN)D@$>MI#!GQYFWJZM=##KF\$.@QH6&5D.PY5J +MHGS3V&-87"Y5L?AD,)=!,&?<:/VM9%CN,%ZMFK)O^;)A_#E43 +MMT;'O`X`_````/P````"````10``^(8L``!`$0``P*@!`<"H`0(!]`'T`.0& +MR7F3'^C$\I\G(VK\G8E1W-@N("0(`````P```-PA``#`*0_V9HT,AUL8CT*E +MHF)Q(V;*]U`DHR/D=F#7$:5`TZI/[7"/5)/^T<<$$\"WDLTZJ6[_UT$<6R-S3AV9%8E'"42#`Q=X*0<6=\I)8,B +M)G"8D5=8D(`W:EQ1J/%(`.:ZO)Q)`C/C(FWUK!E[I@J9LF&"^R!\V7&]K&!* +MZ2%Y\EJU=^%":4>HJO2E!!4Y6(3X"K,HF&]5@PO/2Z(CYWW)_B#@^NA5$[=& +MZ<<.`&P```!L`````@```$4``&B&+0``0!$``,"H`0'`J`$"`?0!]`!4!CEY +MDQ_HQ/*?)R-J_)V)4=S8+B`D(`````(```!,*0``,/]SY^H[FZP13VAHOS/] +M5IPXIP-GCB6Q;>F:!ZVV+HS0B&9+%4\YBY5TFO\751.W1G?D#@!L````;``` +M``(```!%``!HABX``$`1``#`J`$!P*@!`@'T`?0`5`8Y>9,?Z,3RGR;Y9J[VJP,=G*SITYP$]Z##_(VO +M6UL*8!P$>:3$^6SSREO@]!J/I3PD;KN>@8-)99&-YQM'/#& +M&)=-O`/'J+_B0B +M2JM6J81!<*ON*,Z7R:R^F(&1J3'-P)P*CP4.;R#,55\MM2V"A&^D)84>MW^_ +MJY$L6]!X.A-`KR5OE6-=;IO])UC4YU?C94:0Z/_+":B=X-@SEAIP1*L=-6%. +M5,I![GQG7R3T1G?MW0)YU2/IFAG\CX\;"U9(*&L+HAWF\&PQ51.W1@T+#P`< +M`0``'`$```(```!%``$8AC```$`1``#`J`$!P*@!`@'T`?0!!`?I>9,?Z,3R +MGR, +M%'6$X2[7[65B<6P^0G4PR<]7-7XCQ(F>PJM3X(K>%*1RW$,)Z7W'VPS#'O5? +M;7",B9@@NB@(!XD4@3-$(F2 +M:#C^,G\@?<=V)+."Q&T%FD@!F#P>51.W1IT:#P#L````[`````(```!%``#H +MAC$``$`1``#`J`$!P*@!`@'T`?0`U`:Y>9,?Z,3RGR$JR32+$H$9(_R\ +ME\U!WJ1T7Y%MW_'*=BUP@7S&EI7?>0Y@%XR`Q0',K,EJ8--A&I]3>6ZX5<+N +M""YXHHH;*\M03FA&=_`-452ZLP::J_S4G`DX]#JK!H-@'^:["/A9&'G[Y9,?Z,3RGRY%RL7`O5A^G+@>F0]>\]G:+.DC@/U5A.W1LH8```\`0``/`$` +M``(```!%``$XAC,``$`1``#`J`$!P*@!`@'T`?0!)`<)>9,?Z,3RGR/6VV+*+ +M;]ITA\(&?PE%KV8<0:%1>$7BT5129(IJN-&2G#96,&_H&OJ$<]G"1<6_6L!F +M3T;$6I7HY8C!]>=\A@/(1HL4F%`U'#DKZ6_*#'SS9>2K_ +MP^[XP0[Z3XY&[T90F]R>:E:ZN'T,2.E<8]\"V#[V2M3S.]DYE52'VI!XD%)V>C#_W +MV')E51[#7D]@S'^(A3>(_R[P%0&AFL5ZBL!JDMT@,E,(>@XV?%C._8R-[/TB7:?G%E3"2S6`\O,+"2W*^:;,3:]W +M)W9`<,RQPNV!F;G"I(TA\+\XJ3-PL)NF;M00,9[#6I1EH6-`"H_OJ6^^">.2 +MV^Y!KNT=`)=&KU@JS8\6*T;-4=48")(^Q1K*J1`;4716$[=&3S0``.P```#L +M`````@```$4``.B&-0``0!$``,"H`0'`J`$"`?0!]`#4!KEYDQ_HQ/*?)R-J +M_)V)4=S8+B`D(`````8```#,(0``L-6K>K43#BZFX6*6_MK[^J83;6+%R6O5 +M(=JG3MRP^[#D!8^!+FY*AV>82,N*"#B;G-KY9VX%_P"`7REYNEA+FM[ +MGHZ(>$S[S!LX`'V_J9+66@/;DEZQM$X2(7V>8(47?8!A@2"5T7L=>?1='[N#@[.3^`QTVY`UY]DFMSDP`O]"91%IZZ+)=5 +M;H-R2L,PZ\.Z-7-&;[A6$[=&NU@``.P```#L`````@```$4``.B&-@``0!$` +M`,"H`0'`J`$"`?0!]`#4!KEYDQ_HQ/*?)R-J_)V)4=S8+B`D(`````<```#, +M(0``L);^GYDQ@THIE>-AD31R*NDP'I_"N`2:%I5'A1^OW"7)L99*(O`684VI +M`@HR=2!68B(6J8IC-17RI780)ZRU0+DI^D0>^`)R@L\J\IKL,2'&G*_=1VPYW2-O0!Y9;RFEM2DU8+ZOWV(OE"#P4B%=;*S%2.A +M>(,;4X$K@:SN*XF/,5Z\69\53=7\08E>?#`KZI[\8%<5T-J9"=FR%.I(+QCH +M?A=G5A.W1B&S``!<`0``7`$```(```!%``%8AC@``$`1``#`J`$!P*@!`@'T +M`?0!1`9,?Z,3RGRE3>BAY0$B%=[@[(*F"CX3Z?0MBWZ??GVE!D6XPPS2W82$F]\3PW +MRU@18C9\X(_\R..J[>#=ZW\>RN:32]0*0X:HRL1PJG)G;I`'_?Q,/H$V)3ZS +M_H=V]UIN+>".#XFM1[.I)^%]CD-G0.#&9@SJE+Y_G3['I>HYZ\3!S.@E&GV" +M!AU>!4DW\V_E$9X42OZJ<>//(8X",V5CA4VS]Y.B,'W"@T,E=AI?(J8X]5C8 +M5#$W[:=N%9+^0N:5C[@$R)?M`'6!E`E*"1,7I0AFH-7%-ZM`,DN]\8+J&3/R +M)PY(8Y``!`$0``P*@!`<"H +M`0(!]`'T`&0&2?Y_P8Z9:NBSA'-S-91G*WHN("4(`````````%PJ``!`YE=Q +M<94\(SJ8^+IE^*R>Z#!\EM^?^V]3$0@=W7J)-Q>_TTOY-\S;1";MZ+40 +MXLLOZ2B5/`HW,OO45A.W1D/E``!L````;`````(```!%``!HACH``$`1``#` +MJ`$!P*@!`@'T`?0`5`8Y_G_!CIEJZ+.$BX@)2``````````3``` +M`#!X0L^C*\IJCT/W&D-T(;!>F[/5<$%!3A9FA)WIE()XK'A'":Y)<,==6XA+V24&K*N?[D;YU;1S24F-S7AU7Y6$[=&9@$!`&P` +M``!L`````@```$4``&B&/```0!$``,"H`0'`J`$"`?0!]`!4!CG^?\&.F6KH +MLX1S"(``'@```!T`0$`#`,````!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``?NDP#$B!T4:DOW+,>67!4W4PR\I&PN]^8/OS$\Z)5E?"Z-]].,?-9H"K +MJ081,Q@H&B3Z6T71,A$6_67X`XLP8,&M`).?=2>5,4(N4NJB_+QE[AM[]6:: +MV+^O=>9V;,FH@*Y<%]?\N:!B+7&O-,DE0D"7;H(+^,':JS!1)?\WZ.TI```D +M&_T0F_G4QL,*0"SHVKBYU$OIXF2R?A&2A%3T,Z-\TY8I```<``!`!.O20CAU +MA$`\J?;<>7QSOMW452(5````'```0`5TC1:=JYRP1$X;>_5FFMB_KW7F=FS)J("N7!?7_+F@8BUQKS3))4)` +MEVZ""_C!VJLP427_-^CM*0``)!O]$)OYU,;#"D`LZ-JXN=1+Z>)DLGX1DH14 +M]#.C?-.6*0``'```0`3KTD(X=81`/*GVW'E\<[[=U%4B%0```!P``$`%=(T6 +MG:NV]=.R(AM.RI!]6$[=&A%X+`)@!``"8`0```@```$4``92&1@`` +M0!$``,"H`0'`J`$"`?0!]`&`!V6S=2]8/@GTT0``````````(2`B"``````` +M``%X(@``>````'0!`0`,`P````$```R`#@"``P``#`$```R`#@$``P``#`$` +M``R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P`` +M`@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``!^Z3`, +M2('11J2_"(``'@```!T`0$`#`,```$!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``?UR]*-V="?G740%M4BI;`M[:/;$'E/E,"-`3BJD7 +MIP`=3P%VQV"LYJ\B$BE'&3&U]T?LH=R_S.5VXMLX$8V?[O9,.?Y)^UZ`S`=Z +M2[&Q9R`Y<#-'(0Z$G_.@W))QX!U]6A.)CJ&SPOS?;TV42K+DJ]9>FTOF;NE" +MTU5VYLD2.8\I```DS'DE@#N%OC4',>=$3R+\X_*5SF3.%^Z=C(E./R"A5H@I +M```<``!`!`,*M:U&*B=-*XA5F5^'!M#\MCXF````'```0`6A-=V]>,2/X($N +M)G@C[J&Q2#$-,U<3MT:XE@P`F`$``)@!```"````10`!E(9+``!`$0``P*@! +M`<"H`0(!]`'T`8`'91:#XQ$Q0_X````````````A("((`````````7@B``!X +M````=`$!``P#```!`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`# +M```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,` +M``$#```(`P``!0,```@$```"````"`0```XH``"(``(``']VCVQ!Y3Y3`C0$XJI%Z<`'4\!=L=@K.:O(A(I1QDQM?='[*'@,P'>DNQL6<@.7`S1R$.A)_SH-R2<>`=?5H3B8ZA +ML\+\WV]-E$JRY*O67IM+YF[I0M-5=N;)$CF/*0``),QY)8`[A;XU!S'G1$\B +M_./RE````'0!`0`,`P```0$```R`#@"``P``#`$` +M``R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P`` +M"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```. +M*```B``"``!_7+THW9T)^==1`6U2*EL"WMH]L0>4^4P(T!.*J1>G`!U/`7;' +M8*SFKR(2*4<9,;7W1^RAW+_,Y7;BVS@1C9_N]DPY_DG[7H#,!WI+L;%G(#EP +M,T26`.X6^-0"/NH;%( +M,0TS61.W1LS!`0"8`0``F`$```(```!%``&4AFH``$`1``#`J`$!P*@!`@'T +M`?0!@`=EY2,J$SU-,F4``````````"$@(@@````````!>"(``'@```!T`0$` +M#`,```(!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``0]T"Z=UCA-RP$T/,5>8&S.,- +MIJY=Q2=QA/WR'4A4TE;9EE"G(*8/!DE6DA#3+?1VS:'S_=%>;;X+RCF)=?<[ +M/#'0599SP8+#`?D\""E`%D\)DB +MDED=#T0HAF#C-*D8O]E%%QUD3MT9O]00`F`$``)@!```"````10`! +ME(9L``!`$0``P*@!`<"H`0(!]`'T`8`'9>4C*A,]33)E```````````A("(( +M`````````7@B``!X````=`$!``P#```"`0``#(`.`(`#```,`0``#(`.`0`# +M```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,` +M``@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(` +M`$/=`NG=8X3````'0!`0`,`P```@$` +M``R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@`` +M`@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```( +M!````@````@$```.*```B``"``!#W0+IW6.$W+`30\Q5Y@;,XPVFKEW%)W&$ +M_?(=2%325MF64*<@I@\&25:2$-,M]';-H?/]T5YMO@O*.8EU]SL\,=!5EG/! +MR9=)$JTKLY)5W-3D\_[)A]0^X]_7_[(BE02TJ!++AY@L,!^1P]=6#1IP@B1` +MZ;K%22D``!P``$`$QSQT$B-Z%R,625`W71H#7'98X"8````<``!`!,TD-Z8.,TJ1B_V447'6A.W1@Y$"0"8`0``F`$```(```!%``&4AG,``$`1 +M``#`J`$!P*@!`@'T`?0!@`=E_:!\\<..#/8``````````"$@(@@````````! +M>"(``'@```!T`0$`#`,```,!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@```X8`P`!_ +M8G3+535?$JI8)-ZB[O3;1CK/_%FN=IMG@7QDE;WVZ@X:")HF+G>F55;M7KC_%@I```D@F;L5HYJIQTP +M&OUP(]_;!]U73*?!ZR(S$!`!GGWA(U@I```<``!`!([KIG`3>]N45`Y#%$[R +M[@8M=5\7````'```0`5<-"&(FB`!45HN[TVT8ZS_Q9G*)3+\97 +MT<^&:_%S;B`?5T5KQIY"/]TYA[N7R5&N*SR +MN:`L+Z*T!5DW8NNDKY+BU]T(4P#LS^0^WKG:;9X%\9)6]]NH.&@B:)BYWIE5 +M6[5ZX_Q8*0``)()F[%:.:J<=,!K]<"/?VP?=5TRGP>LB,Q`0`9Y]X2-8*0`` +M'```0`2.ZZ9P$WO;E%0.0Q1.\NX&+75?%P```!P``$`%7#0AB)H@`5%7*ZQ& +M6T\=6``` +M`'0!`0`,`P```P$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P`` +M"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```! +M`P``"`,```4#```(!````@````@$```.*```B``"```#A@#``']B=,M5-5\2 +MJE@DWJ+N]-M&.L_\69RB4R_&5]'/AFOQ0C_=.8>[E\E1KBL\KF@+"^BM`59-V+KI*^2XM?="%,`[,_D/MZY +MVFV>!?&25O?;J#AH(FB8N=Z955NU>N/\6"D``"2"9NQ6CFJG'3`:_7`CW]L' +MW5=,I\'K(C,0$`&>?>$C6"D``!P``$`$CNNF$8````````` +M`"$@(@@````````!>"(``'@```!T`0$`#`,```0!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``#`IT9$-EV=4;[2C2V--`=,ECM-%#1U]B];S?I?T4'_(L! +MG^AD;4@RA62)YI2#;(4E+\@F-^E%)Q^NNSM_D9NCB.D@CD,_!RR5D,)CR7PI +M```D2J+V)"1$G)CV;HA;;^H'(#1I:5S/PE"^,4%L_4U+TIY`YO80@CRGHTMC30 +M'3)8[310T=?8O6\WZ7]%!_R+`9_H9&U(,H5DB>:4@VR%)2_()C?I12D=B[UZ"-R10"QM>YHQ)#0P```!P``$`% +M<[$S5HK(::5?](*0SY@E1E(X5)U<$[=&Z>@*`)@!``"8`0```@```$4``92& +M@```0!$``,"H`0'`J`$"`?0!]`&`!V6H`](!5DYX1@``````````(2`B"``` +M``````%X(@``>````'0!`0`,`P``!`$```R`#@"``P``#`$```R`#@$``P`` +M#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```( +M`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"```, +M"G1D0V79U1OM)RH<&X_&)09"P,!;F+5H._#Q540H(>=#YFGB`T:6E0.;V$((\IZ-+8TT!TR6.TT4-'7V+UO-^E_10?\BP&?Z&1M2#*% +M9(GFE(-LA24OR"8WZ44G'ZZ[.W^1FZ.(Z2".0S\'+)60PF/)?"D``"1*HO8D +M)$2]<4:=F()4E+YQ-K!'2D``!P``$`$)`AK7I'8N]>@ +MC"(``'@```!T`0$`#`,```C--?0X<2K'K5!0,HQ@> +MKZY?(^D4%$0:OZ:]$2O-@60^M_@\H0"QN#5/'2AH'Q'Y=PD_3$*N),YTOS[' +M)1\A5RGN9GGZB+K(D?\O.$*O6A"%?%4I$7K6E):S!OTQ8.J +MMR9E&UIY<@#.SN`I```D<)F.843K,R4,$0>W_=&"_`4\BT=:D!1#:>J1H>J) +M]I,I```<``!`!*W[);1S.!_Q(A+5[`%LJCS6/6Q1````'```0`6[$'#<`&:Q +MGJQ@)L?'2],_7(`SL[@*0``)'"9CF%$ZS,E#!$' +MM_W1@OP%/(M'6I`40VGJD:'JB?:3*0``'```0`2M^R6TP!;*H\ +MUCUL40```!P``$`%NQ!PW`!FL9ZL8";'QTO3/W#UW(Q>$[=&+[T#`)@!``"8 +M`0```@```$4``921HP``0!$``,"H`0'`J`$"`?0!]`&`!V6L+13-=MV&%0`` +M````````(2`B"`````````%X(@``>````'0!`0`,`P``!P$```R`#@"``P`` +M#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```! +M`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$ +M```.*```B``"``"*T-PBQ&01=SRFL41Z,TU]#AQ*L>M4%`RC&!ZOKE\CZ104 +M1!J_IKT1*\V!9#ZW^#RA`+&X-4\=*&@?$?EW"3],0JXDSG2_/LYF +M>?J(NLB1_R\X0J]:$(5\52D1>M:4EK-R[?-I$'3/>^=X&_3%@ZJW)F4;6GER +M`,[.X"D``"1PF8YA1.LS)0P1![?]T8+\!3R+1UJ0%$-IZI&AZHGVDRD``!P` +M`$`$K?LEM',X'_$B$M7L`6RJ/-8];%$````<``!`!;L0<-P`9K&>K&`FQ\=+ +MTS]P]=R,7Q.W1F_)`0"8`0``F`$```(```!%``&4JID``$`1``#`J`$!P*@! +M`@'T`?0!@`=E`+H:G<..AHX``````````"$@(@@````````!>"(``'@```!T +M`0$`#`,```@!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``0`;_8)'"''MH1$\U;7?_ +M992'90DN4#7KPLO1J`$ +M*R%1D<57\$')+"D3"GN+1!R/-63D+)^$!=@):X@7/#G#UT\"T47U-TU&7V7$ +M?G/WCZ$*(FE\Z#&R@GO.P(W++0KX.\DI```D&-5F6N)"?WY$0S2S)&C[%D>! +MI;P9&0P()'>_'.U!'6,I```<``!`!"HWIL_<89X(G(EW\R'57=_`)?L:```` +M'```0`4-DBB=QY>VM7[``MP5S[A_<7"M")R)=_,AU5W?P"7[&@```!P``$`%#9(HG7,`&18#?7L>7G,$BL`TA'!? +M$[=&W38+`)@!``"8`0```@```$4``92JH@``0!$``,"H`0'`J`$"`?0!]`&` +M!V4`NAJ=PXZ&C@``````````(2`B"`````````%X(@``>````'0!`0`,`P`` +M"`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```( +M`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4# +M```(!````@````@$```.*```B``"``!`!O]@D<(<>VA$3S5M=_]EE(=E"2Y0 +M->O"R]&IR@`7MK5^P`+<%<^X?W%PK7-X`0K(5&1Q5?P +M0XM$'(\U9.0LGX0%V`EKB!<\./H0HB +M:7SH,;*">\[`CFS]QAG@B%.@``````````"$@(@@````` +M```!>"(``'@```!T`0$`#`,```D!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``/>Q$ +MSBYX_$$I!6F1^331779LV)FTN3)C#WN.G9=5<.>#0;4H`&%T!A#MWW'?9A^: +M=*`V5%12?`X=3V@^QY3%F^WM2Q`UO\BVDGFL?Y\WAFHEB&W.#R@&U=?I:"#Z +M[!?HMGHMGSC[K+^9(8-#V;SHTMU"_G1:A.Q'#K>K)_L,,C$I```D:U1%\?;; +M/?#.5%'3S6=UJ^Y"T4<&#?;3MGQD'1N*/1\I```<``!`!(BF5D($-<#MC_`E +M.'#WGA.BGM]T````'```0`4C*E5DV([N:N;GI;7(M&1E;7NQP&`3MT9(;PP` +MF`$``)@!```"````10`!E*JR``!`$0``P*@!`<"H`0(!]`'T`8`'99PELAXO +MWA3H```````````A("((`````````7@B``!X````=`$!``P#```)`0``#(`. +M`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P`` +M"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```" +M````"`0```XH``"(``(``#WL1,XN>/Q!*05ID?DTT5UV;-B9M+DR8P][CIV7 +M57#G@T&U*`!A=`80[=]QWV8?FG2@-E144GP.'4]H/L>4Q9OM[4L0-;_(MI)Y +MK'^?-X9J)8AMS@\H!M77Z6@@^NP7Z+9Z+9\X^ZR_F2�]F\Z-+=0OYT6H3L +M1PZWJR?[##(Q*0``)&M41?'VVSWPSE11T\UG=:ON0M%'!@WVT[9\9!T;BCT? +M*0``'```0`2(IE9"!#7`[8_P)3AP]YX3HI[?=````!P``$`%(RI59-B.[FKF +MYZ6UR+1D96U[L+]X4Z```````````(2`B"`````````%X(@`` +M>````'0!`0`,`P``"0$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#` +M`P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@# +M```!`P``"`,```4#```(!````@````@$```.*```B``"```][$3.+GC\02D% +M:9'Y--%==FS8F;2Y,F,/>XZ=EU5PYX-!M2@`870&$.W?<=]F'YITH#945%)\ +M#AU/:#['E,6;[>U+$#6_R+:2>:Q_GS>&:B6(;BV? +M./NLOYDA@T/9O.C2W4+^=%J$[$<.MZLG^PPR,2D``"1K5$7Q]ML]\,Y44=/- +M9W6K[D+11P8-]M.V?&0=&XH]'RD``!P``$`$B*960@0UP.V/\"4X>$Z*> +MWW0````<``!`!2,J5638CNYJYN>EM['`8A.W1H%Y`0"8`0``F`$` +M``(```!%``&4K-D``$`1``#`J`$!P*@!`@'T`?0!@`=E0!K:5/C:O'\````` +M`````"$@(@@````````!>"(``'@```!T`0$`#`,```,!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``S\-4&(J1ZOAP@M[YGEMB`E(H\;05)WW+TCOG"8]8L6+.P:2B +MYSSI/."CF5?`H0K5)Q!8M?@HOAMC%&^KX$TB?)];*)\*"V+]\.*@3SE(M +M;%8I```D.E9SG'1A^RJ`U1&$!1SCLR+?":P(+O4#`#FWIL.$:#HI```<``!` +M!-L[/[7MS;AL[R)%_Z]4;(B4PLR9O3 +M_86F[F(3MT:HIP0`F`$``)@!```"````10`!E*T:``!`$0``P*@!`<"H`0(! +M]`'T`8`'94`:VE3XVKQ_```````````A("((`````````7@B``!X````=`$! +M``P#```#`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0`` +M`P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```( +M`P``!0,```@$```"````"`0```XH``"(``(``,_#5!B*D>KX<(+>^9Y;8@)2 +M*/&T%2=]R]([YPF/6+%BSL&DHN<\Z3S@HYE7P*$*U2<06+7X*+X;8Q1OJ^!- +M(GR?6W*5@FDU,.B!FR +MF!Z28E*7BB?"@MB_?#BH$\Y2+6Q6*0``)#I6@*`)@!``"8`0```@```$4` +M`92NE```0!$``,"H`0'`J`$"`?0!]`&`!V5`&MI4^-J\?P``````````(2`B +M"`````````%X(@``>````'0!`0`,`P```P$```R`#@"``P``#`$```R`#@$` +M`P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0# +M```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``" +M``#/PU08BI'J^'""WOF>6V("4BCQM!4G?T5N#!-*L6TWM3#H@9LI@>DF)2EXHGPH+8OWPXJ!/.4BUL5BD``"0Z +M5G.<=&'[*H#5$80%'..S(M\)K`@N]0,`.;>FPX1H.BD``!P``$`$VSL_M>W- +MN&SO(ES$PU0A$E,")'$````<``!`!>CN-)5X7_KU1LB)3"S)F]/]A:;N8Q.W +M1EOV"`"8`0``F`$```(```!%``&4L%(``$`1``#`J`$!P*@!`@'T`?0!@`=E +M0_8=V@SQU?8``````````"$@(@@````````!>"(``'@```!T`0$`#`,```0! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``(B_RI5=@&TS]HZV!V7EB&O"7+KM]097F +M&`(_2E^_*`(_SW:%%Q!`?ULF1FB#(66%9#6.X4[KW'UQKTBPYZXK^`?N85N& +MN=^G7>'(TCWBM8'?`5$-.AY6"=Z^W>L;![ +M^OSH"]M1)E'%%N%,J#\I```D3QR5L1#]&\:V>ZW])].]N*_@'[F%;AKG?IUWAR-(]XK6!WP%1#3H7+[[;$"MZ:8M! +MF$Y#0,BNNZHKWN5@G>OMWK&P>_K\Z`O;4291Q1;A3*@_*0``)$\KGU(].U;"9)^D;>:E9*0``'```0`3VZMZ;WV[O3%*R"JRH +MPJ24YUP^Q````!P``$`%-0RO`'R">$&7%GXZA_O.;>2`2+ED$[=&9B`#`)@! +M``"8`0```@```$4``92P70``0!$``,"H`0'`J`$"`?0!]`&`!V5#]AW:#/'5 +M]@``````````(2`B"`````````%X(@``>````'0!`0`,`P``!`$```R`#@"` +M`P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@" +M```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@`` +M``@$```.*```B``"```B+_*E5V`;3/VCK8'9>6(:\)88`C]*7[\H +M`C_/=H47$$!_6R9&:(,A985D-8[A3NO*U@=\!40TZ%R^^VQ`K>FF+09A.0T#(KKNJ*][E8)WK[=ZQL'OZ_.@+VU$F +M4<46X4RH/RD``"1/')6Q$/T;QK9[K?TGT[USIMWJY]2/3M6PF2?I&WFI62D` +M`!P``$`$]NK>F]]N[TQ2L@JLJ,*DE.="F%!#\``````````"$@(@@````````!>"(``'@` +M``!T`0$`#`,```4!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``8V[=/WI3F,&WHKMT +M&CAE24_0^\>>)8.%>G&`KKU_J/6-FZ#D2?T5""2%T1PD882KVMV9[-KE),B9)D2-GP^MZK7_>Z +M_B))]D67TPW3Q/NU3(6<7S1N%-?CBS(2_"LI```D,(V'"6B6$#!W1-#F)W>P +M!6[>Q?I8#8MA`_([UJ5#G0<;NY(X\E4*1O(S0P&MV43MT;*?P0`F`$``)@!```" +M````10`!E+#-``!`$0``P*@!`<"H`0(!]`'T`8`'9?(Z,W@IA00_```````` +M```A("((`````````7@B``!X````=`$!``P#```%`0``#(`.`(`#```,`0`` +M#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```( +M`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH +M``"(``(``&-NW3]Z4YC!MZ*[=!HX94E/T/O'GB6#A7IQ@*ZW**+O5&K9+GP* +M`P+&ZDASOM)3*^4VA5T>@_W`!UAI)47$GM?ZCUC9N@Y$G]%0@DA=$<)&&$J] +MK=F>S:Y23(F29$C9\/K>JU_WNOXB2?9%E],-T\3[M4R%G%\T;A37XXLR$OPK +M*0``)#"-APEHEA`P=T30YB=WL`5NWL7Z6`V+80/R.]:E0YT'*0``'```0`0O +MJY4/LL1J(-X&J6=PM*^6#O=`#P```!P``$`%/`N78567G&[N2./)5"D;R,T, +M!K=E$[=&I,$*`)@!``"8`0```@```$4``92Q$```0!$``,"H`0'`J`$"`?0! +M]`&`!V7R.C-X*84$/P``````````(2`B"`````````%X(@``>````'0!`0`, +M`P``!0$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,# +M```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,` +M``4#```(!````@````@$```.*```B``"``!C;MT_>E.8P;>BNW0:.&5)3]#[ +MQYXE@X5Z<8"NMRBB[U1JV2Y\"@,"QNI(<[[24ROE-H5='H/]P`=8:25%Q)[7 +M^H]8V;H.1)_14()(71'"1AA*O:W9GLVN4DR)DF1(V?#ZWJM?][K^(DGV19?3 +M#=/$^[5,A9Q?-&X4U^.+,A+\*RD``"0PC8<):)80,'=$T.8G=[`%;M[%^E@- +MBV$#\CO6I4.=!RD``!P``$`$+ZN5#[+$:B#>!JEG<+2OE@[W0`\````<``!` +M!3P+EV%5EYQN[DCCR50I&\C-#`:W9A.W1NK-"`"8`0``F`$```(```!%``&4 +ML2(``$`1``#`J`$!P*@!`@'T`?0!@`=EDQ(VQ]9Q-P0``````````"$@(@@` +M```````!>"(``'@```!T`0$`#`,```@!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M4B$F2Y\S`JT,4CXGBOVMS@%4MW('PBQ.D'_J`,B6S^!8M=%=%%PZY)D`8:_% +MK1\/5K1PX7O'X@+#*Z:H#-#-]-4Y[)[U>;@FWJ=2P]@%4@8,\\##L:%$CR#A +M",97#0^`-\/E;^5_9)S.<^0D.7AM]H-5$/)HRZ8^QY"TV(>FO$@I```D0\@0 +MR>]7FX +M)MZG4L/8!5(&#//`P[&A1(\@X0C&5PT/@#?#Y6_E?V20M-B'IKQ(*0``)$/($'(?/8-C=?(587G(PZ$S`!C-O@F(J<1ZO\B3 +M!F"0*0``'```0`2QI9L3`3<%YCMDU+HN#`>W2=6X>0```!P``$`%$JI>3V0Q +MI1FZS`J&V:70EE)#SPAG$[=&5?D"`)@!``"8`0```@```$4``92Q*P``0!$` +M`,"H`0'`J`$"`?0!]`&`!V63$C;'UG$W!```````````(2`B"`````````%X +M(@``>````'0!`0`,`P``"`$```R`#@"``P``#`$```R`#@$``P``#`$```R` +M#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,` +M``@#```!`P``"`,```4#```(!````@````@$```.*```B``"``!2(29+GS," +MK0Q2/B>*_:W.`52W<@?"+$Z0?^H`R);/X%BUT5T47#KDF0!AK\6M'P]6M'#A +M>\?B`L,KIJ@,T,WTU3GLGO5YN";>IU+#V`52!@SSP,.QH42/(.$(QE<-#X`W +MP^5OY7]DG,YSY"0Y>&WV@U40\FC+IC['D+38AZ:\2"D``"1#R!!R'SV#8W7R +M%6%YR,.A,P`8S;X)B*G$>K_(DP9@D"D``!P``$`$L:6;$P$W!>8[9-2Z+@P' +MMTG5N'D````<``!`!1*J7D]D,:49NLP*AMFET)920\\(:!.W1OL%`0"8`0`` +MF`$```(```!%``&4L3\``$`1``#`J`$!P*@!`@'T`?0!@`=E3"JBXRW!NF,` +M`````````"$@(@@````````!>"(``'@```!T`0$`#`,```D!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``$P"^',.<.6]#%/NLG$R<3JQ:!78!3*=+MCY6B*%0:9#$ +M%5M.7'8'QY+LZ.!"K&A`SZD!XNGH!#BG%:`SV!!;?=/!)$&J==F7!.9T/M,H +M+1+8`GANE4F[22#R&0GR0/;;'6=@+6M/VAMS_O1VSNNU^^+/8]RN7[Y/(.52 +MKRS"/UHI```DOPN;K8NDMI#,O06U7!YW1Z-,K$3OIMO5%6<&GG\7O^(I```< +M``!`!#I)).Y1BR+EWE/H;*R^\+A2[.C@0JQH0,^I`>+IZ`0XIQ6@ +M,]@06WW3P21!JG79EP3F=#[3*"T2V`)X;I5)NTD@\AD)\D#VVQUG8"UK3]H; +M<_[T=L[KM?OBSV/=T>C +M3*Q$[Z;;U15G!IY_%[_B*0``'```0`0Z223N48LBY=Y3Z&RLOG,Y2Z,FU0`` +M`!P``$`%!B````'0!`0`,`P``"0$```R`#@"``P``#`$```R` +M#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(` +M``0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*``` +MB``"```3`+X@$.*<5H#/8$%M]T\$D0:IUV9<$YG0^TR@M$M@">&Z5 +M2;M)(/(9"?)`]ML=9V`M:T_:&W/^]';.Z[7[XL]CW*Y?OD\@Y5*O+,(_6BD` +M`"2_"YNMBZ2VD,R]!;5<'G='HTRL1.^FV]459P:>?Q>_XBD``!P``$`$.DDD +M[E&+(N7>4^ALK+YS.4NC)M4````<``!`!08G)9[PN%R]"3(QFHTOR&HIM_DL +M:1.W1BB`"`"8`0``F`$```(```!%``&4L4P``$`1``#`J`$!P*@!`@'T`?0! +M@`=EQ>[;H@D"`#L``````````"$@(@@````````!>"(``'@```!T`0$`#`,` +M``H!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@```&7L[6NKM]:.CSM4'+K>7_T,P>9H +M5/%`2;N'2S!R(/L0Q$%C"&1@,LK(WB7@+V9#">_I\,4?OK+X,L[3]IZ$FQ)* +M0J$=G\W[`L3#@;N-1?6$E>8]@:5@B_-MCFU&$4@&X'U1VT+A=N!`]6S*JI\[ +MLG"S:+IN9MRU^WOQ.+R]/!RD80?54+X]=J$ +MA)L22D*A'9_-^P+$PX&[C47UA)7F/8&E8(OS;8YM +M1A%(!N!]4=M"X7;@0/5LRJJ?.[)PLVBZ;F;AJ$[=&$*L" +M`)@!``"8`0```@```$4``92Q50``0!$``,"H`0'`J`$"`?0!]`&`!V7%[MNB +M"0(`.P``````````(2`B"`````````%X(@``>````'0!`0`,`P``"@$```R` +M#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,` +M``@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!``` +M`@````@$```.*```B``"````9>SM:ZNWUHZ/.U0)>`O9D,)[^GPQ1^^LO@RSM/VGH2;$DI"H1V?S?L" +MQ,.!NXU%]825YCV!I6"+\VV.;4812`;@?5';0N%VX$#U;,JJGSNR<+-HNFYF +MW+7[>_$XMS@NK2D``"06=1O\DCD?N?4N=[+T\'*1A!]50OCUVH1P%DI=79FH +M32D``!P``$`$02G\K1*A8SEH"1.[^.=22PCO--0````<``!`!;>,JXY*`?0" +M;R,0A.V%C<6OA:7H:Q.W1LRY``"8`0``F`$```(```!%``&4L6,``$`1``#` +MJ`$!P*@!`@'T`?0!@`=EM,2KG3,'$9P``````````"$@(@@````````!>"(` +M`'@```!T`0$`#`,```L!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``X?N0J'T$D:X^(P9]IABO7GUSMT13<26^PM2U.`G6+B#8&U=(93H^LL)>-,BA. +M4%^80I>(3-/SPEM7NMOB2N@D0DP=>O")W!B*ZY$I```D0V(L+7'/H`/L)FL? +MH(NI6`/G_##+UGQ?DD6Z!+S]<_8I```<``!`!!8#++-EA$\61>1PDLU4@/#O +M.9ZG````'```0`4$DR6>K+G9?R0,Q;6/M5H[.-@<_VL3MT:)XP,`F`$``)@! +M```"````10`!E+%G``!`$0``P*@!`<"H`0(!]`'T`8`'9;3$JYTS!Q&<```` +M```````A("((`````````7@B``!X````=`$!``P#```+`0``#(`.`(`#```, +M`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$# +M```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0` +M``XH``"(``(``.'[D*AW*5QNL#VY5T3R_%(5'R,B_#TVM*9@5;/:4Q@H4/^` +M]V)#IM?4W[?X&T[*=-,>DU!D[^)4#GM!)&N/B,&?:88KUY]<[=$4W$EOL+4M +M3@)UBX@V!M72&4Z/K+"7C3(H3E!?F$*7B$S3\\);5[K;XDKH)$),'7KPB=P8 +MBNN1*0``)$-B+"UQSZ`#["9K'Z"+J5@#Y_PPR]9\7Y)%N@2\_7/V*0``'``` +M0`06`RRS981/%D7D<)+-5(#P[SF>IP```!P``$`%!),EGJRYV7\D#,6UC[5: +M.SC8'/]K$[=&'B4*`)@!``"8`0```@```$4``92Q;0``0!$``,"H`0'`J`$" +M`?0!]`&`!V6TQ*N=,P<1G```````````(2`B"`````````%X(@``>````'0! +M`0`,`P``"P$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$` +M``,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P`` +M"`,```4#```(!````@````@$```.*```B``"``#A^Y"H=RE<;K`]N5=$\OQ2 +M%1\C(OP]-K2F8%6SVE,8*%#_@/=B0Z;7U-^W^!M.RG33'I-09._B5`Y[021K +MCXC!GVF&*]>?7.W1%-Q);["U+4X"=8N(-@;5TAE.CZRPEXTR*$Y07YA"EXA, +MT_/"6U>ZV^)*Z"1"3!UZ\(G<&(KKD2D``"1#8BPM<<^@`^PF:Q^@BZE8`^?\ +M,,O6?%^21;H$O/US]BD``!P``$`$%@,LLV6$3Q9%Y'"2S52`\.\YGJ<````< +M``!`!023)9ZLN=E_)`S%M8^U6CLXV!S_;!.W1N(N"`"8`0``F`$```(```!% +M``&4L7$``$`1``#`J`$!P*@!`@'T`?0!@`=E48]G_\X]S+X``````````"$@ +M(@@````````!>"(``'@```!T`0$`#`,```T!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``SQ8>6E,O3JUI-8!*8USKZ9EP4(GE."&#:?5?G&!J@FN,:W,>`L0Y8S)& +MB(ROF*+D?4&I:!D@[1_8G@',_+JIGZGL=R$1M$AK@Z=+KS66WW7_HTG_B5E= +M+*3&#P+8MR`Q$5!QEI0&XEZP*PCE$HP$C3L8-:L;U#-OZF0Z)B]&$*XI```D +M&@>^GGZ)$#A]5%FNEMBP^W\*Q8+UD[[3S3\"^+M+7,`I```<``!`!/;3/'"& +M3Q0W8W=Z$E$P+U:Q:'BY````'```0`7RU'[CH5YUX/A$`[G0\*<]TG&=AVP3 +MMT:"70L`F`$``)@!```"````10`!E+%S``!`$0``P*@!`<"H`0(!]`'T`8`' +M95&/9__./L"L(Y1*,!(T[ +MK&]0S;^ID.B8O1A"N*0``)!H'OIY^B1`X?519KI;8L/M_"L6"]9.^T\T_ +M`OB[2US`*0``'```0`3VTSQPAD\4-V-W>A)1,"]6L6AXN0```!P``$`%\M1^ +MXZ%>=>#X1`.YT/"G/=)QG8=M$[=&UUP"`)@!``"8`0```@```$4``92Q>``` +M0!$``,"H`0'`J`$"`?0!]`&`!V51CV?_SCW,O@``````````(2`B"``````` +M``%X(@``>````'0!`0`,`P``#0$```R`#@"``P``#`$```R`#@$``P``#`$` +M``R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P`` +M`@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``#/%AY: +M4R].K6DU@$IC7.OIF7!0B>4X(8-I]5^<8&J":XQK`QW(1&T2&N#ITNO-9;?=?^C2?^)65TLI,8/`MBW +M(#$14'&6E`;B7K`K".42C`2-.Q@UJQO4,V_J9#HF+T80KBD``"0:![Z>?HD0 +M.'U46:Z6V+#[?PK%@O63OM/-/P+XNTM+D````<``!`!?+4?N.A7G7@^$0#N=#PISW2<9V';A.W1B'2``"8 +M`0``F`$```(```!%``&4M3\``$`1``#`J`$!P*@!`@'T`?0!@`=E,(1P?:=J +M&,<``````````"$@(@@````````!>"(``'@```!T`0$`#`,```X!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``T27%!ZD`F;M]6H*2E1QKCWC7["]K +M:R";!&S0$C^J+VX3MT;(^`,`F`$``)@!```"````10`!E+5M``!`$0``P*@! +M`<"H`0(!]`'T`8`'93"$<'VG:AC'```````````A("((`````````7@B``!X +M````=`$!``P#```.`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`# +M```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,` +M``$#```(`P``!0,```@$```"````"`0```XH``"(``(``-$EQ0>I`)F[?5J" +MDI7+6/5XM!._J&&!_K?PW,@:%[&P`T1M'1;&NW=1$/`^9X33L,+?GD<:W'U] +M$F4P6VG`(SLG`S&%;N[PXU<;NAH!.G\X2!L15CFSA$*#/06IU!6NXQ=7\P"= +M01NS5ENFX71!XHSD(?A\O/Q=&,=WR-S?ATO<*0``)-L+PCV6KH?-NQ8EP>-1 +M\>*#5[+(+DCX@Q[[A87Z7/A$*0``'```0`1PW[2QH`96B`P[->N-3O`QKGX/ +M]````!P``$`%D/'S7H]XU^PO:VL@FP1LT!(_JB]N$[=&B"4*`)@!``"8`0`` +M`@```$4``92XB@``0!$``,"H`0'`J`$"`?0!]`&`!V4PA'!]IVH8QP`````` +M````(2`B"`````````%X(@``>````'0!`0`,`P``#@$```R`#@"``P``#`$` +M``R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P`` +M"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```. +M*```B``"``#1)<4'J0"9NWU:@I*5RUCU>+03OZAA@?ZW\-S(&A>QL`-$;1T6 +MQKMW41#P/F>$T[#"WYY'&MQ]?1)E,%MIP",[)P,QA6[N\.-7&[H:`3I_.$@; +M$58YLX1"@ST%J=05KN,75_,`G4$;LU9;IN%T0>*,Y"'X?+S\71C'=\CRR"Y(^(,>^X6%^ESX1"D``!P``$`$ +M<-^TL:`&5H@,.S7KC4[P,:Y^#_0````<``!`!9#Q\UZ/>-?L+VMK()L$;-`2 +M/ZHO;Q.W1L4Q"`"8`0``F`$```(```!%``&4N)8``$`1``#`J`$!P*@!`@'T +M`?0!@`=E'#K_@GI>"(``'@```!T`0$` +M#`,```\!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``P4B-V;A6[-AR]D?3158(BO3@ +M>CLTMVRR"ZQ5"P8QQC!Q!M"[\=.L2>]OJ:&'^Q8FY)N.!/60-^'D7C#9\;O8 +M_+GF[8\RY*'?1/5Z:$GS7D+;H`7":P'9->MA^22=L62Y='PPW]>Q40X)2K8I +M+G9Z')&FQ%W_)[HS8L'VY@%_$"LI```D%H7<#,V;%LT=.K^I?11@`C+F8)ZD +M887P-&%2I0?EL[PI```<``!`!![=T+!0`I-U\FL72YW)2+=GXLZ%````'``` +M0`5FV2:&_'VDB*8LH..=4L;5E`UW?V\3MT:170L`F`$``)@!```"````10`! +ME+B7``!`$0``P*@!`<"H`0(!]`'T`8`'91PZ_X)Z7G-#```````````A("(( +M`````````7@B``!X````=`$!``P#```/`0``#(`.`(`#```,`0``#(`.`0`# +M```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,` +M``@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(` +M`,%(C=FX5NS8FA)\UY"VZ`%PFL!V37K +M8?DDG;%DN71\,-_7L5$."4JV*2YV>AR1IL1=_R>Z,V+!]N8!?Q`K*0``)!:% +MW`S-FQ;-'3J_J7T48`(RYF">I&&%\#1A4J4'Y;.\*0``'```0`0>W="P4`*3 +M=?)K%TN=R4BW9^+.A0```!P``$`%9MDFAOQ]I(BF+*#CG5+&U90-=W]P$[=& +MKUP"`)@!``"8`0```@```$4``92XG0``0!$``,"H`0'`J`$"`?0!]`&`!V4< +M.O^">EYS0P``````````(2`B"`````````%X(@``>````'0!`0`,`P``#P$` +M``R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@`` +M`@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```( +M!````@````@$```.*```B``"``#!2(W9N%;LV'+V1]-%5@B*].!Z.S2W;+(+ +MK%4+!C'&,'$&T+OQTZQ)[V^IH8?[%B;DFXX$]9`WX>1>,-GQN]C\N>;MCS+D +MH=]$]7IH2?->0MN@!<)K`=DUZV'Y))VQ9+ET?##?U[%1#@E*MBDN=GH"(``'@```!T`0$`#`,``!`!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``UA]ML:9M +MS,]96(YU?2=\^\!I4#B&O_"8L(T@PYB0`:6>7DH\'NG[%8?J#&CM2M +M]+'(;G?I=HA6NY>TP7C$][;BE0K7*GH,W'B1%6"ZSY,I```D8X$L6WM7_<>F +M107A@?M'7G*GKCR4TLF;5>[\L^1S([EB65YD2`1NP!,99P\7$3MT;CE0,`F`$` +M`)@!```"````10`!E+CM``!`$0``P*@!`<"H`0(!]`'T`8`'9:+8R#C8^AW3 +M```````````A("((`````````7@B``!X````=`$!``P#```0`0``#(`.`(`# +M```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(` +M``$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"```` +M"`0```XH``"(``(``-8?;;&F;VXI4*URIZ#-QX +MD15@NL^3*0``)&.!+%M[5_W'ID4%X8'[1UYRIZX\E-+)FU7N_+/D7-6$*0`` +M'```0`12E1`N];XGW"8)JLZS*S;J1.L2JP```!P``$`%Y+W65WLR.Y8EE>9$ +M@$;L`3&6``` +M`'0!`0`,`P``$`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P`` +M"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```! +M`P``"`,```4#```(!````@````@$```.*```B``"``#6'VVQIFW,SUE8CG5] +M)WSYR-I'-T2CP>Z?L5A^H,:.U*WTL,3WMN*5"M@S<>)$58+K/DRD``"1C@2Q;>U?]QZ9%!>&!^T=> +MN/)32R9M5[ORSY%S5A"D``!P``$`$4I40+O6^)]PF":K.LRLVZD3K$JL` +M```<``!`!>2]UE=[,CN6)97F1(!&[`$QEG#Q"(``'@```!T`0$`#`,``!,!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``+1N"&R.!!]G7I9XY2XH#M:*\(UNUU'`_FXX79$1Q0R;/>9Q`C,E) +M>.*N%/BV,ZP/J32U:D"1)QNLD[R,Y7!?28J[5:9E1R`MW=2'C53<6)7&'J&( +MX$SBK."Q[4&%+NUFMD)#95(IXJ*X.>@#TI +M```D!"(AE#&://^@I```<``!`!/7_ +M=$P[,&PELH[*DANV:3]#UI"\````'```0`62('Z&:^R5",EMQZMM9&?,1[*( +M3'(3MT8K#PL`F`$``)@!```"````10`!E+IM``!`$0``P*@!`<"H`0(!]`'T +M`8`'9<3;A]@A4MIG```````````A("((`````````7@B``!X````=`$!``P# +M```3`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,` +M``@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P`` +M!0,```@$```"````"`0```XH``"(``(``"T;@ALC@0?9UZ6>.4N*`[6BO"-; +MM=1P/YN.%V1$<4,FSWF<0(S)27CBKA3XMC.L#ZDTM6I`D2<;K).\C.5P7TF* +MNU6F94<@+=W4AXU4W%B5QAZAB.!,XJW-EN5%_>)_NV90])%*O,'W:E2WC@L> +MU!A2[M9K9"0V52*>*BN#GH`]*0``)`0G`6/[5X$!^3`9FA8U@?BX;#]9R/K3 +M1WB(90QFCS_H*0``'```0`3U_W1,.S!L);*.RI(;MFD_0]:0O````!P``$`% +MDB!^AFOLE0C);<>K;61GS$>RB$QS$[=&=@X"`)@!``"8`0```@```$4``92Z +M=@``0!$``,"H`0'`J`$"`?0!]`&`!V7$VX?8(5+:9P``````````(2`B"``` +M``````%X(@``>````'0!`0`,`P``$P$```R`#@"``P``#`$```R`#@$``P`` +M#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```( +M`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"```M +M&X(;(X$'V=>EGCE+B@.UHKPC6[74<#^;CA=D1'%#)L]YG$",R4EXXJX4^+8S +MK`^I-+5J0)$G&ZR3O(SE<%])BKM5IF5'("W=U(>-5-Q8E<8>H8C@3.*MS9;E +M1?WB?[MF4/212KS!]VI4MXX+'M084N[6:V0D-E4BGBHK@YZ`/2D``"0$)P%C +M^U>!`?DP&9H6-8'XN&P_6"(``'@```!T`0$`#`,``!0!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``:(DC4B)DC>WU&PW&;83SSX7[3*@J>ZUHK2Q"!J>9E3O-J8+A7&JM),-6%11 +M9[B>CSU[V22;TT4?\/OXGKR+B2V$.K0]>AEYRUH1*HOT%'T-%D'G\O,EQ%Q< +M_`*PVF+!H`("3M8I```DXWETZ<7;[;G6]TLANK>O[S82+J(G=DN*]4T>LY8* +M54HI```<``!`!!Q]]5#IGI-E[T13C9*2=FI'.X`Q````'```0`5,S-S="WF% +M;*L^2S3R[,A/:WT>*703MT8E1P,`F`$``)@!```"````10`!E+KO``!`$0`` +MP*@!`<"H`0(!]`'T`8`'94RVT#1YL%L$```````````A("((`````````7@B +M``!X````=`$!``P#```4`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`. +M`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P`` +M"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``&B)(U(B9(WM +M]1L-QFV$\\^%^W(1O31@M]^)?8!!_?XGH\]>]DDF]-%'_#[^)Z\BXDMA#JT/7H9 +M>]$4XV2DG9J +M1SN`,0```!P``$`%3,S;!;!``` +M````````(2`B"`````````%X(@``>````'0!`0`,`P``%`$```R`#@"``P`` +M#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```! +M`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$ +M```.*```B``"``!HB2-2(F2-[?4;#<9MA///A?MR$;TT8+??B7V`0?WW+B[F +MR5JVO]\YRA07XW-Y,J"I[K6BM+$(&IYF5.\VI@N%<:JTDPU85%%GN)Z//7O9 +M))O311_P^_B>O(N)+80ZM#UZ&7G+6A$JB_04?0T60>?R\R7$7%S\`K#:8L&@ +M`@).UBD``"3C>73IQ=OMN=;W2R&ZMZ_O-A(NHB=V2XKU31ZSE@I52BD``!P` +M`$`$''WU4.F>DV7O1%.-DI)V:D<[@#$````<``!`!4S,W-T+>85LJSY+-/+L +MR$]K?1XI=1.W1I"9!P"8`0``F`$```(```!%``&4NS\``$`1``#`J`$!P*@! +M`@'T`?0!@`=E$@=5"HXPU$4``````````"$@(@@````````!>"(``'@```!T +M`0$`#`,``!4!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``FOS$VX8$5"=P0%V%J3+# +MCXBE*&Q/R#/2YLD>3CL\Y4](Y[N"_8XEMWVK>ERN=[R;:0_R>S-/?%7YA;E[F;#*TH1'P +M0"*B".Z4:QH\_E[-;YT[M'@'5(RT#^,I```DIQS[8^CJ&X'-F`(M->A5O4N+ +MBZ+K'%4YHG"(3GQ(UDXI```<``!`!#R"-G3_OQ:A0WHA7-S#!^GG"WB%```` +M'```0`4'K#>"[\4J'5R;G#!8X)0J)?>C-G43MT8#P0H`F`$``)@!```"```` +M10`!E+M#``!`$0``P*@!`<"H`0(!]`'T`8`'91('50J.,-1%```````````A +M("((`````````7@B``!X````=`$!``P#```5`0``#(`.`(`#```,`0``#(`. +M`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@`` +M!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"( +M``(``)K\Q-N&!%0G<$!=A:DRPX^(I2AL3\@STN;)'`2Q!6:DQP0^S#U/Q+$' +M?`*Q$9;DCN_@9LP9":,RNZ*2C/LJ]87GDX[/.5/2.>[@OV.);=]JWI\F +MVD/\GLS3WQ5^86Y>YFPRM*$1\$`BH@CNE&L://Y>S6^=.[1X!U2,M`_C*0`` +M)*<<^V/HZAN!S9@"+37H5;U+BXNBZQQ5.:)PB$Y\2-9.*0``'```0`0\@C9T +M_[\6H4-Z(5S````'0!`0`,`P`` +M%0$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```( +M`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4# +M```(!````@````@$```.*```B``"``":_,3;A@14)W!`786I,L./B*4H;$_( +M,]+FR1P$L05FI,<$/LP]3\2Q!WP"L1&6Y([OX&;,&0FC,KNBDHS[*O6%YY.. +MSSE3TCGNX+]CB6W?:MZ7*YWO)MI#_)[,T]\5?F%N7N9L,K2A$?!`(J(([I1K +M&CS^7LUOG3NT>`=4C+0/XRD``"2G'/MCZ.H;@B%<+>(4````<``!`!0>L +M-X+OQ2H=7)N<,%C@E"HE]Z,V=A.W1F0.#P"8`0``F`$```(```!%``&4NU$` +M`$`1``#`J`$!P*@!`@'T`?0!@`=EX;T"(``'@```!T`0$`#`,`__\!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``SW,H +M$+D)J5L#&?0@NNS61CU9&/@(90+@WX<[MXZ\].K`'6Z";F'2G>G`DMT\;"$;Y6N$OMW>KI=['.W483:`+$@JHU* +MRWSN+8F]OSP^%9J5=W?L**,@*?SGRQFP.-KN4,%MU]3R@$4I```D60:,%`]% +M_V,XU`/.2^9^Z(LHG_"JT)C**G/N]7L4&W\I```<``!`!"$@P@J855-\]-^4^`````'```0`42B_7G8>2$S-M7VN8%DRZ^"G]@LW<3MT;#^`(` +MF`$``)@!```"````10`!E+M3``!`$0``P*@!`<"H`0(!]`'T`8`'9>&]',N4 +M.%1@```````````A("((`````````7@B``!X````=`$!``P#`/__`0``#(`. +M`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P`` +M"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```" +M````"`0```XH``"(``(``,]S*!"Y":E;`QGT(+KLUD8]61CX"&4"X-^'.:C# +MP&^I7X2*T76W&5?#%DF`0D#*5_$'G.[>.O/3JP!UN@FYATIWIP)+=/&PA&^5 +MKA+[=WJZ7>QSMU&$V@"Q(*J-2LM\[BV)O;\\/A6:E7=W["BC("G\Y\L9L#C: +M[E#!;=?4\H!%*0``)%D&C!0/1?]C.-0#SDOF?NB+*)_PJM"8RBIS[O5[%!M_ +M*0``'```0`0A(,(*F%57([9G,ONBWC?/3?E/@````!P``$`%$HOUYV'DA,S; +M5]KF!9,NO@I_8+-W$[=&<#H)`)@!``"8`0```@```$4``92[7P``0!$``,"H +M`0'`J`$"`?0!]`&`!V7AO1S+E#A48```````````(2`B"`````````%X(@`` +M>````'0!`0`,`P#__P$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#` +M`P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@# +M```!`P``"`,```4#```(!````@````@$```.*```B``"``#/Q0;?RD``!P``$`$(2#""IA55R.V9S+[HMXWSTWY +M3X`````<``!`!1*+]>=AY(3,VU?:Y@63+KX*?V"S>!.W1OM&!P"8`0``F`$` +M``(```!%``&4NV,``$`1``#`J`$!P*@!`@'T`?0!@`=E0?.A9'1+8B<````` +M`````"$@(@@````````!>"(``'@```!T`0$`#`,`@``!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``\C`5K+.[4^;2R[]:V`(]S"ZRMO0_2HA'>9@^P9)W$BK\VEL@ +M_-BSZ..;@5M/19V+,&R0T`(5'CD>VF;F4$R`L\ +M^T7^`#+'1BH\TR1&00T;!]4XW:&Q^X09$)^_J61;?ZD^%>,`Z[2I602A3')Y +MDL$I```D?%B)`G3UG*!J"[,6-&$>]Z5M7@R=7_7AOM1::^$V4SDI```<``!` +M!'O]1C8*<[?;+J$,P_)Q41E]9;@^````'```0`62M8)NE>AN8Q2N'"7B9Z;* +MYW/]S7@3MT;*<@H`F`$``)@!```"````10`!E+MD``!`$0``P*@!`<"H`0(! +M]`'T`8`'94'SH61T2V(G```````````A("((`````````7@B``!X````=`$! +M``P#`(```0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0`` +M`P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```( +M`P``!0,```@$```"````"`0```XH``"(``(``/(P%:RSNU/FTLN_6M@"/9+!*0``)'Q8B0)T]9R@:@NS%C1A'O>E;5X, +MG5_UX;[46FOA-E,Y*0``'```0`1[_48V"G.WVRZA#,/R<5$9?66X/@```!P` +M`$`%DK6";I7H;F,4KAPEXF>FRN=S_````'0!`0`,`P"```$```R`#@"``P``#`$```R`#@$` +M`P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0# +M```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``" +M``#R,!6LL[M3YM++OUK8`CW,+K*V]#]*B$=YF#[!DG<2*OS:6R#\V+/HXYN! +M5R(+(&3TNTIU#'6*Q@*:/]ZT]%G8LP;)#0`A4>.1[:9N903("SS[1?X`,L=& +M*CS3)$9!#1L'U3C=H;'[A!D0G[^I9%M_J3X5XP#KM*E9!*%,#)U?]>&^U%IKX393.2D``!P``$`$>_U&-@IS +MM]LNH0S#\G%1&7UEN#X````<``!`!9*U@FZ5Z&YC%*X<)>)GILKG<_W->1.W +M1M[!#@"8`0``F`$```(```!%``&4NW8``$`1``#`J`$!P*@!`@'T`?0!@`=E +MK&*8C?+@39P``````````"$@(@@````````!>"(``'@```!T`0$`#`,```P` +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``%&`04LR()6'67;P%5`AL1!<_D-A[&^ +M1;X^ZH7_MA>(\/-KCOWB@P^F-1\DTM(EG%P>-Y'O1"XZSI"S1N-*E/,@AG+& +MW8FRU76",1\QKF\+Z9/IFE-AQ0`A,;DB.Z(!,DNMPS-ECU$HD]9%IU2]:;(7 +M&%9X\O'7?7<3=JU@<(HI```D]A'(:M'YH&8@_Z4;-5[FQ'G\:W?S])`8F>"B +MUMST!(DI```<``!`!)'AQ>KD-&2S]X0]!>WD3MT8.X`X`N`$` +M`+@!```"````10`!M+MX``!`$0``P*@!`<"H`0(!]`'T`:`'A:QBF(WRX$V< +M```````````I("((`````````9@A```@``!`!@````QNT=?'Z6OM;>AQ>KD- +M&2S]X0]!>R(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M%&`04LR()6'67;P%5`AL1!<_D-A[&^1;X^ZH7_MA>(\/-KCOWB@P^F-1\D +MTM(EG%P>-Y'O1"XZSI"S1N-*E/,@AG+&W8FRU76",1\QKF\+Z9/IFE-AQ0`A +M,;DB.Z(!,DNMPS-ECU$HD]9%IU2]:;(7&%9X\O'7?7<3=JU@<(HI```D]A'( +M:M'YH&8@_Z4;-5[FQ'G\:W?S])`8F>"BUMST!(DI```<``!`!)'2ZI7LAA#I +MUG$.35W-"$#^E?#D;0<;NR"0\H(!Z +M=8P%9]G'H@/5>B3E5?Z",^_U4\D_]Y$[=&!S,/``P!```, +M`0```@```$4``0B[?```0!$``,"H`0'`J`$"`?0!]`#T!]FL8IB-\N!-G&$6 +MDFN"R<.W+B`C"`````$```#L(P``T''3>4T,4H%%(I+X1>)5@._ACPF,_Z-1 +MKIW0_>'S4'K^X74U\TMO58>F6?`)9Z&HKC)4"?B,N&`(25[.&Z5##!UWG\@= +M_8I,OM1\K40!B%$U%(8NEB,:AR(+]-W)9R8K8,AEKTV=VK1NG;7^8V5`'GAY +MZXRRO54V\W8<^J]`1C;IKR-Z!V%8`UGV%M9(>+QCU;^6*8=E>US`>0L!)T`> +M!0]41&+N:E6*S$!(P?G980W/-+7&3\@C:7/?7KY>)X9"S+@/'9O-H'$=V!K2 +!'P`` +` +end diff --git a/tests/ikev2four.out b/tests/ikev2four.out new file mode 100644 index 0000000..db2e8ef --- /dev/null +++ b/tests/ikev2four.out @@ -0,0 +1,107 @@ +IP (tos 0x0, ttl 64, id 19908, offset 0, flags [none], proto UDP (17), length 404) + 192.168.1.2.500 > 192.168.1.1.500: isakmp 2.0 msgid 00000000: parent_sa ikev2_init[I]: + (sa: len=116 + (p: #1 protoid=isakmp transform=12 len=116 + (t: #1 type=encr id=aes (type=keylen value=0080)) + (t: #2 type=encr id=aes (type=keylen value=0100)) + (t: #3 type=encr id=aes (type=keylen value=00c0)) + (t: #4 type=encr id=3des ) + (t: #5 type=prf id=hmac-sha ) + (t: #6 type=prf id=hmac-md5 ) + (t: #7 type=prf id=aes128_xcbc ) + (t: #8 type=integ id=hmac-sha ) + (t: #9 type=integ id=hmac-md5 ) + (t: #10 type=integ id=aes-xcbc ) + (t: #11 type=dh id=modp1024 ) + (t: #12 type=dh id=modp2048 ))) + (v2ke: len=128 group=modp1024) + (nonce: len=32 data=(6128ebd023a864e94a7f...ba041b5de59955900d818ac54e18b236739d9e8b)) + (n: prot_id=#0 type=16388(nat_detection_source_ip)) + (n: prot_id=#0 type=16389(nat_detection_destination_ip)) +IP (tos 0x0, ttl 64, id 19909, offset 0, flags [none], proto UDP (17), length 88) + 192.168.1.1.500 > 192.168.1.2.500: isakmp 2.0 msgid 00000000: parent_sa ikev2_init[R]: + (n: prot_id=#0 type=16390(cookie) data=(00000001c2221e50c16e123f2b0c71aefcf0cb3b798782c6)) +IP (tos 0x0, ttl 64, id 19910, offset 0, flags [none], proto UDP (17), length 436) + 192.168.1.2.500 > 192.168.1.1.500: isakmp 2.0 msgid 00000000: parent_sa ikev2_init[I]: + (n: prot_id=#0 type=16390(cookie) data=(00000001c2221e50c16e...ba041b5de59955900d818ac54e18b236739d9e8b)) + (sa: len=116 + (p: #1 protoid=isakmp transform=12 len=116 + (t: #1 type=encr id=aes (type=keylen value=0080)) + (t: #2 type=encr id=aes (type=keylen value=0100)) + (t: #3 type=encr id=aes (type=keylen value=00c0)) + (t: #4 type=encr id=3des ) + (t: #5 type=prf id=hmac-sha ) + (t: #6 type=prf id=hmac-md5 ) + (t: #7 type=prf id=aes128_xcbc ) + (t: #8 type=integ id=hmac-sha ) + (t: #9 type=integ id=hmac-md5 ) + (t: #10 type=integ id=aes-xcbc ) + (t: #11 type=dh id=modp1024 ) + (t: #12 type=dh id=modp2048 ))) + (v2ke: len=128 group=modp1024) + (nonce: len=32 data=(6128ebd023a864e94a7f...ba041b5de59955900d818ac54e18b236739d9e8b)) + (n: prot_id=#0 type=16388(nat_detection_source_ip)) + (n: prot_id=#0 type=16389(nat_detection_destination_ip)) +IP (tos 0x0, ttl 64, id 19911, offset 0, flags [none], proto UDP (17), length 332) + 192.168.1.1.500 > 192.168.1.2.500: isakmp 2.0 msgid 00000000: parent_sa ikev2_init[R]: + (sa: len=44 + (p: #1 protoid=isakmp transform=4 len=44 + (t: #1 type=encr id=aes (type=keylen value=0080)) + (t: #2 type=prf id=hmac-sha ) + (t: #3 type=integ id=hmac-sha ) + (t: #4 type=dh id=modp1024 ))) + (v2ke: len=128 group=modp1024) + (nonce: len=32 data=(b31c379f272ce2984bd1...905954a783be2c37e2ccc4fdd270a532dbe6f428)) + (n: prot_id=#0 type=16388(nat_detection_source_ip)) + (n: prot_id=#0 type=16389(nat_detection_destination_ip)) +IP (tos 0x0, ttl 64, id 19912, offset 0, flags [none], proto UDP (17), length 264) + 192.168.1.2.500 > 192.168.1.1.500: isakmp 2.0 msgid 00000001: child_sa ikev2_auth[I]: + (v2e: len=204) +IP (tos 0x0, ttl 64, id 19913, offset 0, flags [none], proto UDP (17), length 184) + 192.168.1.1.500 > 192.168.1.2.500: isakmp 2.0 msgid 00000001: child_sa ikev2_auth[R]: + (v2e: len=124) +IP (tos 0x0, ttl 64, id 19914, offset 0, flags [none], proto UDP (17), length 280) + 192.168.1.2.500 > 192.168.1.1.500: isakmp 2.0 msgid 00000002: child_sa child_sa[I]: + (v2e: len=220) +IP (tos 0x0, ttl 64, id 19915, offset 0, flags [none], proto UDP (17), length 248) + 192.168.1.2.500 > 192.168.1.1.500: isakmp 2.0 msgid 00000003: child_sa child_sa[I]: + (v2e: len=188) +IP (tos 0x0, ttl 64, id 19916, offset 0, flags [none], proto UDP (17), length 104) + 192.168.1.1.500 > 192.168.1.2.500: isakmp 2.0 msgid 00000002: child_sa child_sa[R]: + (v2e: len=44) +IP (tos 0x0, ttl 64, id 19917, offset 0, flags [none], proto UDP (17), length 104) + 192.168.1.1.500 > 192.168.1.2.500: isakmp 2.0 msgid 00000003: child_sa child_sa[R]: + (v2e: len=44) +IP (tos 0x0, ttl 64, id 19918, offset 0, flags [none], proto UDP (17), length 312) + 192.168.1.2.500 > 192.168.1.1.500: isakmp 2.0 msgid 00000004: child_sa child_sa[I]: + (v2e: len=252) +IP (tos 0x0, ttl 64, id 19919, offset 0, flags [none], proto UDP (17), length 280) + 192.168.1.2.500 > 192.168.1.1.500: isakmp 2.0 msgid 00000005: child_sa child_sa[I]: + (v2e: len=220) +IP (tos 0x0, ttl 64, id 19920, offset 0, flags [none], proto UDP (17), length 232) + 192.168.1.1.500 > 192.168.1.2.500: isakmp 2.0 msgid 00000004: child_sa child_sa[R]: + (v2e: len=172) +IP (tos 0x0, ttl 64, id 19921, offset 0, flags [none], proto UDP (17), length 232) + 192.168.1.1.500 > 192.168.1.2.500: isakmp 2.0 msgid 00000005: child_sa child_sa[R]: + (v2e: len=172) +IP (tos 0x0, ttl 64, id 19922, offset 0, flags [none], proto UDP (17), length 312) + 192.168.1.2.500 > 192.168.1.1.500: isakmp 2.0 msgid 00000006: child_sa child_sa[I]: + (v2e: len=252) +IP (tos 0x0, ttl 64, id 19923, offset 0, flags [none], proto UDP (17), length 280) + 192.168.1.2.500 > 192.168.1.1.500: isakmp 2.0 msgid 00000007: child_sa child_sa[I]: + (v2e: len=220) +IP (tos 0x0, ttl 64, id 19924, offset 0, flags [none], proto UDP (17), length 232) + 192.168.1.1.500 > 192.168.1.2.500: isakmp 2.0 msgid 00000006: child_sa child_sa[R]: + (v2e: len=172) +IP (tos 0x0, ttl 64, id 19925, offset 0, flags [none], proto UDP (17), length 232) + 192.168.1.1.500 > 192.168.1.2.500: isakmp 2.0 msgid 00000007: child_sa child_sa[R]: + (v2e: len=172) +IP (tos 0x0, ttl 64, id 19926, offset 0, flags [none], proto UDP (17), length 392) + 192.168.1.2.500 > 192.168.1.1.500: isakmp 2.0 msgid 00000008: child_sa child_sa[I]: + (v2e: len=332) +IP (tos 0x0, ttl 64, id 19927, offset 0, flags [none], proto UDP (17), length 344) + 192.168.1.1.500 > 192.168.1.2.500: isakmp 2.0 msgid 00000008: child_sa child_sa[R]: + (v2e: len=284) +IP (tos 0x0, ttl 64, id 19928, offset 0, flags [none], proto UDP (17), length 120) + 192.168.1.2.500 > 192.168.1.1.500: isakmp 2.0 msgid 00000000: parent_sa inf2[I]: + (v2e: len=60) diff --git a/tests/ikev2four.puu b/tests/ikev2four.puu new file mode 100644 index 0000000..b9c607a --- /dev/null +++ b/tests/ikev2four.puu @@ -0,0 +1,134 @@ +begin 644 ikev2four.pcap +MU,.RH0(`!````````````-P%````````1!*W1JWG!0"8`0``F`$```(```!% +M``&43<0``$`1J$'`J`$"P*@!`0'T`?0!@`=EJ(AUJ!F)DJ8``````````"$@ +M(@@````````!>"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``M41;U@SLYOW-/):E++M[M":HQZ#U:IPXT;'$\,.FZ.?;I<'[_$%BT02 +MMT9`]@4`7````%P````"````10``6$W%``!`$:E\P*@!`<"H`0(!]`'T`$0& +M*:B(=:@9B9*F```````````I("(@`````````#P````@``!`!@````'"(AY0 +MP6X2/RL,<:[\\,L[>8>"QD02MT8;!08`N`$``+@!```"````10`!M$W&``!` +M$:@?P*@!`L"H`0$!]`'T`:`'A:B(=:@9B9*F```````````I("((```````` +M`9@A```@``!`!@````'"(AY0P6X2/RL,<:[\\,L[>8>"QB(``'@```!T`0$` +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``M41;U@SLYOW-/):E++M[M":H +MQZ#U:IPXT;'$\,.FZ.?;I<'[_$%BT02MT9-*`8`4`$``%`!```"````10`! +M3$W'``!`$:B&P*@!`<"H`0(!]`'T`3@'':B(=:@9B9*F<;Z#6.^N=F,A("(@ +M`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@# +M```"````"`0```(H``"(``(``%I6<4TZOV3CH_0!ZMGU,C_PMW^J7QZ9&9L3 +MK((?"@Q/A4>&R@FWIVJE"+SN$?%C::%M7Z!!RBV:C?J"*,8?)(+2%UQ<&I21 +M_"(;['H?II]E;4R8NDFNG7(=[?2@+7[-_"`=QX6A/M=.3SF"=BHG(/_?PV7N +M3C'MO`@:%/L/9\_X%R'? +M[L'Y*0``'```0`3^*_M\+('M"V'W5K5_K'BG7.V*]@```!P``$`%D%E4IX.^ +M+#?BS,3]TG"E,MOF]"A$$K=&E%0&``P!```,`0```@```$4``0A-R```0!&H +MR<"H`0+`J`$!`?0!]`#T!]FHB'6H&8F2IG&^@UCOKG9C+B`C"`````$```#L +M(P``T/8&$UK3<^<(-OVI&V/*3&".&M6"&$B,)D?_'HJ1*5BJ=^^\,&BBKFJW +MP]#+'F^X9-^9QB\LP$5P@(1P@52CD\+TR^^M'VA(4EU)VU8^$S1:3FXOT&;` +M3BSBD?1Q2Z[&OS*#5L1&)'RK@UO:/HX:KEEG)(\!ZSH<`J5!M-H)LR=K0`U0 +MH&=4*F>$:,7T'E0!?`"63Q`#^,B(EJ;Q(A6E\:!@<3S(.`+*XZON&$%\##7< +M;UB@&MN6[1P`G&CC!IKG#TL0K[=S;!$:WDV";D02MT;S:P8`O````+P````" +M````10``N$W)``!`$:D8P*@!`<"H`0(!]`'T`*0&B:B(=:@9B9*F<;Z#6.^N +M=F,N(",@`````0```)PD``"`:OZ5O%%'L*U^3,N10<%@I$]\;MW&LIU!2M7B +MN()43]QL/N:8.N%`BU=DL6230X=D5-&_35%:KP/!7J_G&^:TSU&K8&,,1;SP +MXJ+;CNYP"5I.`0_;-"K;;0/:Y=[YU)!\W\C,UO/:FW27Q8Z$J5+9@[K[E!JQ +MWAL+N?^M.T02MT8RB@8`'`$``!P!```"````10`!&$W*``!`$:BWP*@!`L"H +M`0$!]`'T`00'Z:B(=:@9B9*F<;Z#6.^N=F,N("0(`````@```/PA``#@4\QL +M"T'Q3D_`5\?VHU)*W>A2'R;V?`6$,*D"VQI2[1;3(F,-+K45-RW!+9?5'S?YI]JIQ:;H)UK6QHAP#+?TO-;[@"7I +M.[;=7U@?KKR^RWF,AV%Z3L&P:Z*0K%_!UN3"GQ +M?;]$A\:2//`+<$#5.;R4?'!7D.3IFX-*>N*HUY]6(.$6%>"G8HB:JX(>#0,3 +M+?N,QK-QA8)!&\V8PD*HL0IF)TVN'.!5^S"DT^9,EIOFX(MB:5CT1&QN2@R- +M>B12*5G&%2YCI77`:3#""74YO[W_",<%,T*,]K12X+BP)9PBDI)=+M8NB5:\ +M?CJ1&F%0F^&LCWM\U&-A=N4D]-#Q=7/RKMW.(E'];5V7NO>T +M'G@T(KQ-J_70.K)"#2=].R\HT?`#VIC11!*W1A"[!@!L````;`````(```!% +M``!H36&N!*].1Z=P)@UAXIT8^Q/."3I'EP!H +MVLLT+WF9S#T-6?=ZE$02MT9=U`8`/`$``#P!```"````10`!.$W.``!`$:B3 +MP*@!`L"H`0$!]`'T`20'":B(=:@9B9*F<;Z#6.^N=F,N("0(````!````1PA +M``$`Q_+QS$F7LPIA8C(BU+^U-;JC`AF<38P?W/IT6PLIM>=AC_`U:$A$324! +M#EK4('8(D.W@9L@X)ILBV>,-3^P:`2YS&B$,)#^`.V89<-,NF8Z1GU<\5T+2 +M*(E)!2Q:1J#-?$H:*5[>*6Q/V8.;9-Q)1.$:-?0JC.&+1'(`_0/;U8IQ6#LZ +M)\.`%(R`'.%$4O?75K'U6Q"X2EC/J5)@`?_W%7%49%`BY$5@A5%\[MF+>>(. +MTS*7SUK8`H?G@G**C&N'TK0BY^[:''*S/KQ1I;=M[YI9_]&T^7WLB,(J3U1( +MIQKNWR#(?:Y;1,TN>E&=<9I0GX/SLOKV]<8'VF"?1!*W1A7@!@`<`0``'`$` +M``(```!%``$83<\``$`1J++`J`$"P*@!`0'T`?0!!`?IJ(AUJ!F)DJ9QOH-8 +M[ZYV8RX@)`@````%````_"$``.#:YA-*G/\:3CS%FGG@&:D_A&G=3B^JJM'# +MK[HB[-$H_;'HE4QU/X]BKK:JR7,O04L&7L.5::9POFF`R!ZSY$O)/L8^FG5- +M!%;&<#S7&#<>WN]G22@8#YT4PYY2SZ2E%S:.?;+Z"_VT'/5MEP!B,Q`_(F4/ +MW-7_JX08Y`D#Y'2>$FT&Z=PJ&,_5O]H`$^/IZU/GF[XPZM\/3=SONK#`CH<+ +M*=.;)`''6VC\1J!F>"A7RDC51^00K!7*NV'.F8.+G4T1(H=&14-QL,QN +MP&?A3AY<5E*$#/VN#JA,?PIN>9_W^Q,=%78_[O1>@/)'%LWD?2-2?VC@5:?# +MK<L$[MO$`F''>J9)_!&0RS0&P0C0@30%8.Z\Z1!*W +M1G4.!P#L````[`````(```!%``#H3=$``$`1J.#`J`$!P*@!`@'T`?0`U`:Y +MJ(AUJ!F)DJ9QOH-8[ZYV8RX@)"`````%````S"$``+#V_($3\TN2ZWU96@2/ +M5]1EDT0:V:89&>61GGWD14^C6(*3?3MTR#JY6?T%/&H2I1L$H.DN`6@W@F6+ +MN:\KO,>DO5X>[RV\W'<5RL;J[/O,!1I&\B8]&X.'O:U^:,;DNAOI>4X6/DA' +M:)E:GTH8[!UNV[=Z-I +MJ$1-Q'I-P)7KTZP['<,W5PO$+)/-;>A.EC.%\9;&%Z& +MWO@]9O3$W<0SYFNOE0I9G$U>E$YL+8^OS+F4M\).+K>I:E@[A=8X`^J9# +MOMA?>M[BXN=;KNR>#?B(5Z9\I?*B])&="R1ZW7^RA175J#,KC9`[I +MC!9HG?411#(HA&TL6X@PZFT4G!J^T1K0HHRC.9,#;I&674BH*HF!1:VIE*]5 +MEX:62`JVRVE^$^9Y:*=TC#,X>&[[=R4.5!&SI^K(3-(A,DO7N1"=FFE$$K=& +M=S8'`!P!```<`0```@```$4``1A-TP``0!&HKL"H`0+`J`$!`?0!]`$$!^FH +MB'6H&8F2IG&^@UCOKG9C+B`D"`````<```#\(0``X`+'`_2]V#)&K<9^'*!] +M?GS^(;:]Z48W:`HS*!.XI,I'-!J].IPW)CB6P()2O['J;'ZD1X.Y*L4JRT^_ +M[%/P-50H'&-W90P)((\]=XL1YWM?O9@[X>EFF2,CDN\QI0']ISQA4/S"Z`NK +M'@U)A%O5U1'WR2A>P(-2:'HJR-<-#>PT=DD<0+E\N=I`5@;\7HU&N^&9YMD: +MZ9.W^J!8/L0I:H"!+[?@KHC3O53$HPY>VR=XR6#SX,M;$VGIF?A-Y-QRM=`& +M@%[[?BTNU`,^$?^5>`$M(I0N-YG)."4&H"%$$K=&#D8'`.P```#L`````@`` +M`$4``.A-U```0!&HW<"H`0'`J`$"`?0!]`#4!KFHB'6H&8F2IG&^@UCOKG9C +M+B`D(`````8```#,(0``L'XN9B/&;A8=Z60:Q^&VW]SSI?1;OM$COHCS=4T2 +M440$K\!4L\?WB>M2I#*D.#6=WC$5+!&XT@D@/6)WG*!D@CUP4VQ`^$;4/6:4 +MHO$J,7;U<`>C4&R"__KSV[<3N]NU]4"WLYKN/)<45G%00U8)7WJPQ:A#1\`F +MB\XEG*4;2BW76GXZ?N>?.__%C2_`K#9H8BGR,)M=F-'A_G=P3C&>2^J!TOBZ\M#^#]$ +M0DEGD!CL;QN>3:LF*0RI27"0&WI0+,X +MR12SK:&MNW"_%P=&0^WY?F.MY>T']T9T\FQ(TM:I!$1W +M[I\@,(3";H5`68?LBY:3WJZB#.>,*D4;].@TU[S#Q4P3(K7RBZ,'\LXQH`52 +MN7N/P0.BG^XN`$#,W?H0OSJST2">9#PBC>Q74D#'O74,]-;0;)6/9KV*>8,= +M^''V^]D^`EL6O0/>-?_-NKK&57#2-GYB39^.A6#:F\.B%"MU`(M\ZXZ#G;]" +M7:=,2^%\:QO9<(W4$+<^6@M]T)9N,1#?7[HWQG^INP=6]210)S')V +MUP[@NI%RM!=_O.?Z*!<:(VRHXN#!2>8"R<:@H_]?!4*']4M\,4L'S?;21B0= +MTV3'09S`9'0BT(]5$;$^>URW&6%D9N'&EF]UB-:[/][SY(/,+P%8P'!QUM^N]SW,MLW/>E=8Y!=XVLZW'/9S +M/A<6B^_V[R`5UG#`ME=/QRZ7U"@I"99O.4J?G@_.V.)IN_8.D_#R"`](W-3@ +M+_$2FY3VBR:-W9S_0V\XYX^GF&V'YB+1\]H[/">55PZ\)]/#U1\I[P__`:Z) +MO7'2X0JX^NY]>[2UOHJ>X.J;7C1[NO/KWZ\9S_N +M98A1*)EIQ5[<;587&*#'8;";#V?);F'0"G^BDI`CM:W/W3-#;V.D>!0=4;4C +M,T02MT9GY@<`?````'P````"````10``>$W8``!`$:E)P*@!`L"H`0$!]`'T +M`&0&21V;Z44=3Y>H9**DM=#A>VHN("4(`````````%PJ``!`:1M(@IML76W9 +M/ZCC/#C=3`#U0TW"*T)1P(=O"]M=NZ/=!B@Y!U6:)R\'['<)N=66HDS8_FFX +&*A]EV_;R +` +end diff --git a/tests/ikev2fourv.out b/tests/ikev2fourv.out new file mode 100644 index 0000000..1162649 --- /dev/null +++ b/tests/ikev2fourv.out @@ -0,0 +1,107 @@ +IP (tos 0x0, ttl 64, id 19908, offset 0, flags [none], proto UDP (17), length 404) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum 7aee!] isakmp 2.0 msgid 00000000 cookie a88875a8198992a6->0000000000000000: parent_sa ikev2_init[I]: + (sa: len=116 + (p: #1 protoid=isakmp transform=12 len=116 + (t: #1 type=encr id=aes (type=keylen value=0080)) + (t: #2 type=encr id=aes (type=keylen value=0100)) + (t: #3 type=encr id=aes (type=keylen value=00c0)) + (t: #4 type=encr id=3des ) + (t: #5 type=prf id=hmac-sha ) + (t: #6 type=prf id=hmac-md5 ) + (t: #7 type=prf id=aes128_xcbc ) + (t: #8 type=integ id=hmac-sha ) + (t: #9 type=integ id=hmac-md5 ) + (t: #10 type=integ id=aes-xcbc ) + (t: #11 type=dh id=modp1024 ) + (t: #12 type=dh id=modp2048 ))) + (v2ke: len=128 group=modp1024 b5445bd60cece6fdcd3c96a52cbb7bb426a8c7a0f56a9c38d1b1c4f0c3a6e8e7dba5c7339b6ed02e757119dfb5b6933ce93b604987fbbc77221b2a0c7cdd32787eff10572bef546c361462f9da34847969a42e51c755996beac42e6fba961a75de0fc1b23f099380896ee89202122dedac1bd54aa8494ac3d740be4d2a4cf39d) + (nonce: len=32 nonce=(6128ebd023a864e94a7ffb74bf7cce2fd4367322b8b073f942282bd52ebfe3e6) ) + (n: prot_id=#0 type=16388(nat_detection_source_ip)) + (n: prot_id=#0 type=16389(nat_detection_destination_ip)) +IP (tos 0x0, ttl 64, id 19909, offset 0, flags [none], proto UDP (17), length 88) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum a706!] isakmp 2.0 msgid 00000000 cookie a88875a8198992a6->0000000000000000: parent_sa ikev2_init[R]: + (n: prot_id=#0 type=16390(cookie) data=(00000001c2221e50c16e123f2b0c71aefcf0cb3b798782c6)) +IP (tos 0x0, ttl 64, id 19910, offset 0, flags [none], proto UDP (17), length 436) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum 7d6f!] isakmp 2.0 msgid 00000000 cookie a88875a8198992a6->0000000000000000: parent_sa ikev2_init[I]: + (n: prot_id=#0 type=16390(cookie) data=(00000001c2221e50c16e...ba041b5de59955900d818ac54e18b236739d9e8b)) + (sa: len=116 + (p: #1 protoid=isakmp transform=12 len=116 + (t: #1 type=encr id=aes (type=keylen value=0080)) + (t: #2 type=encr id=aes (type=keylen value=0100)) + (t: #3 type=encr id=aes (type=keylen value=00c0)) + (t: #4 type=encr id=3des ) + (t: #5 type=prf id=hmac-sha ) + (t: #6 type=prf id=hmac-md5 ) + (t: #7 type=prf id=aes128_xcbc ) + (t: #8 type=integ id=hmac-sha ) + (t: #9 type=integ id=hmac-md5 ) + (t: #10 type=integ id=aes-xcbc ) + (t: #11 type=dh id=modp1024 ) + (t: #12 type=dh id=modp2048 ))) + (v2ke: len=128 group=modp1024 b5445bd60cece6fdcd3c96a52cbb7bb426a8c7a0f56a9c38d1b1c4f0c3a6e8e7dba5c7339b6ed02e757119dfb5b6933ce93b604987fbbc77221b2a0c7cdd32787eff10572bef546c361462f9da34847969a42e51c755996beac42e6fba961a75de0fc1b23f099380896ee89202122dedac1bd54aa8494ac3d740be4d2a4cf39d) + (nonce: len=32 nonce=(6128ebd023a864e94a7ffb74bf7cce2fd4367322b8b073f942282bd52ebfe3e6) ) + (n: prot_id=#0 type=16388(nat_detection_source_ip)) + (n: prot_id=#0 type=16389(nat_detection_destination_ip)) +IP (tos 0x0, ttl 64, id 19911, offset 0, flags [none], proto UDP (17), length 332) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum 337f!] isakmp 2.0 msgid 00000000 cookie a88875a8198992a6->71be8358efae7663: parent_sa ikev2_init[R]: + (sa: len=44 + (p: #1 protoid=isakmp transform=4 len=44 + (t: #1 type=encr id=aes (type=keylen value=0080)) + (t: #2 type=prf id=hmac-sha ) + (t: #3 type=integ id=hmac-sha ) + (t: #4 type=dh id=modp1024 ))) + (v2ke: len=128 group=modp1024 5a56714d3abf64e3a3f401ead9f5323ff0b77faa5f1e99199b13ac821f0a0c4f854786ca09b7a76aa508bcee11f16369a16d5fa041ca2d9a8dfa8228c61f2482d2175c5c1a9491fc221bec7a1fa69f656d4c98ba49ae9d721dedf4a02d7ecdfc201dc785a13ed74e4f3982762a2720ffdfc365ee4e37279af496cd86f881fd15) + (nonce: len=32 nonce=(b31c379f272ce2984bd17ca38c8729e1edbc081a14fb0f67cff81721dfeec1f9) ) + (n: prot_id=#0 type=16388(nat_detection_source_ip)) + (n: prot_id=#0 type=16389(nat_detection_destination_ip)) +IP (tos 0x0, ttl 64, id 19912, offset 0, flags [none], proto UDP (17), length 264) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum fdaa!] isakmp 2.0 msgid 00000001 cookie a88875a8198992a6->71be8358efae7663: child_sa ikev2_auth[I]: + (v2e: len=204 f606135ad373e70836fda91b63ca4c608e1ad58218488c2647ff1e8a912958aa77efbc3068a2ae6ab7c3d0cb1e6fb864df99c62f2cc045708084708154a393c2f4cbefad1f6848525d49db563e13345a4e6e2fd066c04e2ce291f4714baec6bf328356c446247cab835bda3e8e1aae5967248f01eb3a1c02a541b4da09b3276b400d50a067542a678468c5f41e54017c00964f1003f8c88896a6f12215a5f1a060713cc83802cae3abee18417c0c35dc6f58a01adb96ed1c009c68e3069ae70f4b10afb7736c111ade4d826e) +IP (tos 0x0, ttl 64, id 19913, offset 0, flags [none], proto UDP (17), length 184) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum bf00!] isakmp 2.0 msgid 00000001 cookie a88875a8198992a6->71be8358efae7663: child_sa ikev2_auth[R]: + (v2e: len=124 6afe95bc5147b0ad7e4ccb9141c160a44f7c6eddc6b29d414ad5e2b882544fdc6c3ee6983ae1408b5764b1649343876454d1bf4d515aaf03c15eafe71be6b4cf51ab60630c45bcf0e2a2db8eee70095a4e010fdb342adb6d03dae5def9d4907cdfc8ccd6f3da9b7497c58e84a952d983bafb941ab1de1b0bb9ffad3b) +IP (tos 0x0, ttl 64, id 19914, offset 0, flags [none], proto UDP (17), length 280) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum c32d!] isakmp 2.0 msgid 00000002 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[I]: + (v2e: len=220 53cc6c0b41f14e4fc057c7f6a3524adde8521f26f67c058430a902db1a52ed16d322630d2eb515372dc12d97dc7c20552607e2ed193d9b33939e10aa2fc37b6199f0a629c6b58135f5b6f9e07906cd30dc3cae7d55fe08d95d3e660a623731c396a325adbff11c490f9fd102224391a65fb7bbe862945b64cf1fb833b9ce68c83df0b9d2ce7bd54f650864af9445e547cdfe5caa393344ae5274933b7efcf616821ea7daa9c5a6e8275ad6c688700cb7f4bcd6fb8025e93bb6dd5f581faebcbecb798c87617a4ec1b06ba290ac5fc1d6e4c2725c1f9f0e10b144fbbe) +IP (tos 0x0, ttl 64, id 19915, offset 0, flags [none], proto UDP (17), length 248) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum e6d7!] isakmp 2.0 msgid 00000003 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[I]: + (v2e: len=188 9603e03f280964782717da15a502f0a9e9f17dbf4487c6923cf00b7040d539bc947c705790e4e99b834a7ae2a8d79f5620e11615e0a762889aab821e0d03132dfb8cc6b3718582411bcd98c242a8b10a66274dae1ce055fb30a4d3e64c969be6e08b626958f4446c6e4a0c8d7a24522959c6152e63a575c06930c2097539bfbdff08c70533428cf6b452e0b8b0259c2292925d2ed62e8956bc7e3a911a61509be1ac8f7b7cd4636176e524f4d0f17573f2aeddce2251fd6d5d9cd54d) +IP (tos 0x0, ttl 64, id 19916, offset 0, flags [none], proto UDP (17), length 104) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum f2c0!] isakmp 2.0 msgid 00000002 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[R]: + (v2e: len=44 5bd2d26cb43b6cec30dec13fa387359797baf7b41e783422bc4dabf5d03ab2420d277d3b2f28d1f003da98d1) +IP (tos 0x0, ttl 64, id 19917, offset 0, flags [none], proto UDP (17), length 104) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum e03a!] isakmp 2.0 msgid 00000003 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[R]: + (v2e: len=44 38f60ab69110967961ae04af4e47a770260d61e29d18fb13ce093a47970068dacb342f7999cc3d0d59f77a94) +IP (tos 0x0, ttl 64, id 19918, offset 0, flags [none], proto UDP (17), length 312) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum 661c!] isakmp 2.0 msgid 00000004 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[I]: + (v2e: len=252 c7f2f1cc4997b30a61623222d4bfb535baa302199c4d8c1fdcfa745b0b29b5e7618ff0356848444d25010e5ad420760890ede066c838269b22d9e30d4fec1a012e731a210c243f803b661970d32e998e919f573c5742d2288949052c5a46a0cd7c4a1a295ede296c4fd9839b64dc4944e11a35f42a8ce18b447200fd03dbd58a71583b3a27c380148c801ce14452f7d756b1f55b10b84a58cfa9526001fff7157154645022e4456085517ceed98b79e20ed33297cf5ad80287e782728a8c6b87d2b422e7eeda1c72b33ebc51a5b76def9a59ffd1b4f97dec88c22a4f5448a71aeedf20c87dae5b44cd2e7a519d719a509f83f3b2faf6f5c607da609f) +IP (tos 0x0, ttl 64, id 19919, offset 0, flags [none], proto UDP (17), length 280) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum d1d0!] isakmp 2.0 msgid 00000005 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[I]: + (v2e: len=220 dae6134a9cff1a4e3cc59a79e019a93f8469dd4e2faaaad1c3afba22ecd128fdb1e8954c753f8f62aeb6aac9732f414b065ec39569a670be6980c81eb3e44bc93ec63e9a754d0456c6703cd718371edeef674928180f9d14c39e52cfa4a517368e7db2fa0bfdb41cf56d97006233103f22650fdcd5ffab8418e40903e4749e126d06e9dc2a18cfd5bfda0013e3e9eb53e79bbe30eadf0f4ddcefbab0c08e870b29d39b2401c75b68fc46a066782857ca48d547e410ac15cabb6738875200b535cbd9ae1e1ce99839c9c25639070e5ed977809c50b6bb9550b50b49bb) +IP (tos 0x0, ttl 64, id 19920, offset 0, flags [none], proto UDP (17), length 232) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum db6a!] isakmp 2.0 msgid 00000004 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[R]: + (v2e: len=172 1fd8516b57b1ab1bdbcdba1930a5097decc023c5c534497ca53f178b9d4d11228746454371b0cc6ec067e14e1e5c5652840cfdae0ea84c7f0a6e799ff7fb131d15763feef45e80f24716cde47d23527f68e055a7c3adc7225489295e1bc3f1029b63822872865df55c6c275dead8a6f64bda8ae44f42c318fa71eb04eed7312dafd2dd8665fd5d3225f3aae6f7335b581c3a89c07af1009871dea9927f046432cd01b04234204d01583baf3a) +IP (tos 0x0, ttl 64, id 19921, offset 0, flags [none], proto UDP (17), length 232) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum 9a59!] isakmp 2.0 msgid 00000005 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[R]: + (v2e: len=172 f6fc8113f34b92eb7d595a048f57d46593441ad9a61919e5919e7de4454fa35882937d3b74c83ab959fd053c6a12a51b04a0e92e01683782658bb9af2bbcc7a4bd5e1eef2dbcdc7715cac6eaecfbcc051a46f2263d1b8387bdad7e68c6e4ba1be9794e163e484768995a9f4a18edcbc6a44f0a74cb01c318e7848562e0866f388b8d04f14f1af87de7de6cee1f889d4330d82932a7127b7d1a934e641c32b76e33b37706d50286f8cbe335ba) +IP (tos 0x0, ttl 64, id 19922, offset 0, flags [none], proto UDP (17), length 312) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum 5ff4!] isakmp 2.0 msgid 00000006 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[I]: + (v2e: len=252 0aa2636a3b897ff3fa8093282ad1724ec9f326b64bf998e781d6edbb77a369a8444dc47a4dc095ebd3ac3b1dc337570bc42c93cd6dcb7289bc99a90874e66cc4ede7a13a58ce17c65b185e86def83d66f4c4ddc433e66baf1834e54296671357a5139b0b63ebf32e652df0938badea5a960ee1758e00faa643bed85f7adee2e2e75baeec9e0df88857a67ca5f2a2f4919d0b272313d42c791eb75feca145756a0ccae3640ee98c16689df511443228846d2c5b8830ea6d149c1abed11ad0a28ca33993036e91965d48a82a898145ada994af55978696480ab6cb697e13e67968a7748c3338786efb77250e5411b3a7eac84cd221324bd7b9109d9a69) +IP (tos 0x0, ttl 64, id 19923, offset 0, flags [none], proto UDP (17), length 280) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum 9890!] isakmp 2.0 msgid 00000007 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[I]: + (v2e: len=220 02c703f4bdd83246adc67e1ca07d7e7cfe21b6bde94637680a332813b8a4ca47341abd3a9c37263896c08252bfb1ea6c7ea44783b92ac52acb4fbfec53f03554281c6377650c09208f3d778b11e77b5fbd983be1e96699232392ef31a501fda73c6150fcc2e80bab1e0d49845bd5d511f7c9285ec08352687a2ac8d70d0dec3476491c40b97cb9da405606fc5e8d46bbe199e6d91ae993b7faa0583ec4296a80812fb7e0ae88d3bd54c4a30e5edb2778c960f3e0cb5b1369e999f84de4dc72b5d006805efb7e2d2ed4033e11ff9578012d22942e3799c9382506a021) +IP (tos 0x0, ttl 64, id 19924, offset 0, flags [none], proto UDP (17), length 232) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum 902e!] isakmp 2.0 msgid 00000006 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[R]: + (v2e: len=172 7e2e6623c66e161de9641ac7e1b6dfdcf3a5f45bbed123be88f3754d12514404afc054b3c7f789eb52a432a438359dde31152c11b8d209203d62779ca064823d70536c40f846d43d6694a2f12a3176f57007a3506c82fffaf3dbb713bbdbb5f540b7b39aee3c97145671504356095f7ab0c5a84347c0268bce259ca51b4a2dd75a7e3a7ee79f3bffc58d2fc0ac36686229f2309b5cd0c0dcc2af798664c14f5f166ab5e3c1f693092121aa44) +IP (tos 0x0, ttl 64, id 19925, offset 0, flags [none], proto UDP (17), length 232) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum 49dd!] isakmp 2.0 msgid 00000007 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[R]: + (v2e: len=172 7b545033a2d35df2ab9f26c4bc444713910a32e60fb04cb10a9e76634787f9ddc138c6792faa074be2ebcb43f83f444249679018ec6dc7d4e2247dd8cb915778d90fa5597f1ecba8471db53e3b4da8f73d1eb60c23ca9fb5fa599dc526a961364471b49e5288fcef6a24d02a084d29c4a5c5d1fa305310dba01d09c9c36c86c0af297e05d3fc8559a11666a4363bacc354e96c941349b3f60dd397eb4c2bb09f381831167c0b33686c6bb5d8) +IP (tos 0x0, ttl 64, id 19926, offset 0, flags [none], proto UDP (17), length 392) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum 1d29!] isakmp 2.0 msgid 00000008 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[I]: + (v2e: len=332 c4bf89ec6e7936ac98a432a525c2406de940b338c9149ce19cb1bf23a69dfd481df7b3ada1adbb70bf17074643edf97e63ade5ed07f74674f26c48d2d6a9044477ee9f203084c26e85405987ec8b9693deaea20ce78c2a451bf4e834d7bcc3c54c1322b5f28ba307f2ce31a00552b97b8fc103a29fee2e0040ccddfa10bf3ab3d1209e643c228dec575240c7bd750cf4d6d06c958f66bd8a79831df871f6fbd93e025b16bd03de35ffcdbabac65570d2367e624d9f8e8560da9bc3a2142b75008b7ceb8e839dbf425da74c4be15c9dc31735ef1ac6f65c2375042dcf9682df74259b8c4437d7ee8df19fea6ec1d5bd491409cc7276d70ee0ba9172b4177fbce7fa28171a236ca8e2e0c149e602c9c6a0a3ff5f054287f54b7c314b07cdf6d246241dd364c7419cc0647422d08f5511b13e7b5cb719616466e1c6966f5ccd4d2ca2b12dda7047c6f63af5dd47) +IP (tos 0x0, ttl 64, id 19927, offset 0, flags [none], proto UDP (17), length 344) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum 25cf!] isakmp 2.0 msgid 00000008 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[R]: + (v2e: len=284 2c1ac864ae2c8499b3c7af8c61a8c4dc9e1af23577b588d6bb3fdef3e483cc2f0158c07071d6dfaef73dccb6cdcf7a5758e41778daceb71cf6733e17168beff6ef2015d670c0b6574fc72e97d4282909966f394a9f9e0fced8e269bbf60e93f0f2080f48dcd4e02ff1129b94f68b268ddd9cff436f38e78fa7986d87e622d1f3da3b3c2795570ebc27d3c3d51f29ef0fff01ae89bd71d2e10ab8faee7d7bb4b5be8a9ee0ea9b5e347bbaf3ebdfaf19735d75e6faa020d6ea72826c2aa5cb2ee648de6b36cbb25087428dea44bd34504e05f2d4fef43c48e2a690510e9278ca8ff2f775792af061b5ccbcf77b3fee658851289969c55edc6d561718a0c761b09b0f67c96e61d00a7fa2929023b5adcfdd33436f63a478141d51b52333) +IP (tos 0x0, ttl 64, id 19928, offset 0, flags [none], proto UDP (17), length 120) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum 6e7f!] isakmp 2.0 msgid 00000000 cookie 1d9be9451d4f97a8->64a2a4b5d0e17b6a: parent_sa inf2[I]: + (v2e: len=60 691b48829b6c5d6dd93fa8e33c38dd4c00f5434dc22b4251c0876f0bdb5dbba3dd06283907559a272f07ec7709b9d596a24cd8fe69b82a1f65dbf6f2) diff --git a/tests/ikev2fourv4.out b/tests/ikev2fourv4.out new file mode 100644 index 0000000..d001fc8 --- /dev/null +++ b/tests/ikev2fourv4.out @@ -0,0 +1,107 @@ +IP (tos 0x0, ttl 64, id 19908, offset 0, flags [none], proto UDP (17), length 404) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum 7aee!] isakmp 2.0 msgid 00000000 cookie a88875a8198992a6->0000000000000000: parent_sa ikev2_init[I]: + (sa: len=116 + (p: #1 protoid=isakmp transform=12 len=116 + (t: #1 type=encr id=aes (type=keylen value=0080)) + (t: #2 type=encr id=aes (type=keylen value=0100)) + (t: #3 type=encr id=aes (type=keylen value=00c0)) + (t: #4 type=encr id=3des ) + (t: #5 type=prf id=hmac-sha ) + (t: #6 type=prf id=hmac-md5 ) + (t: #7 type=prf id=aes128_xcbc ) + (t: #8 type=integ id=hmac-sha ) + (t: #9 type=integ id=hmac-md5 ) + (t: #10 type=integ id=aes-xcbc ) + (t: #11 type=dh id=modp1024 ) + (t: #12 type=dh id=modp2048 ))) + (v2ke: len=128 group=modp1024 b5445bd60cece6fdcd3c96a52cbb7bb426a8c7a0f56a9c38d1b1c4f0c3a6e8e7dba5c7339b6ed02e757119dfb5b6933ce93b604987fbbc77221b2a0c7cdd32787eff10572bef546c361462f9da34847969a42e51c755996beac42e6fba961a75de0fc1b23f099380896ee89202122dedac1bd54aa8494ac3d740be4d2a4cf39d) + (nonce: len=32 nonce=(6128ebd023a864e94a7ffb74bf7cce2fd4367322b8b073f942282bd52ebfe3e6) ) + (n: prot_id=#0 type=16388(nat_detection_source_ip) data=(442ffe5aea0cee4dbacc758e801233bdc09a0abf0000001c00004005ba041b5de59955900d818ac54e18b236739d9e8b)) + (n: prot_id=#0 type=16389(nat_detection_destination_ip) data=(ba041b5de59955900d818ac54e18b236739d9e8b)) +IP (tos 0x0, ttl 64, id 19909, offset 0, flags [none], proto UDP (17), length 88) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum a706!] isakmp 2.0 msgid 00000000 cookie a88875a8198992a6->0000000000000000: parent_sa ikev2_init[R]: + (n: prot_id=#0 type=16390(cookie) data=(00000001c2221e50c16e123f2b0c71aefcf0cb3b798782c6)) +IP (tos 0x0, ttl 64, id 19910, offset 0, flags [none], proto UDP (17), length 436) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum 7d6f!] isakmp 2.0 msgid 00000000 cookie a88875a8198992a6->0000000000000000: parent_sa ikev2_init[I]: + (n: prot_id=#0 type=16390(cookie) data=(00000001c2221e50c16e123f2b0c71aefcf0cb3b798782c622000078000000740101000c0300000c0100000c800e00800300000c0100000c800e01000300000c0100000c800e00c003000008010000030300000802000002030000080200000103000008020000040300000803000002030000080300000103000008030000050300000804000002000000080400000e2800008800020000b5445bd60cece6fdcd3c96a52cbb7bb426a8c7a0f56a9c38d1b1c4f0c3a6e8e7dba5c7339b6ed02e757119dfb5b6933ce93b604987fbbc77221b2a0c7cdd32787eff10572bef546c361462f9da34847969a42e51c755996beac42e6fba961a75de0fc1b23f099380896ee89202122dedac1bd54aa8494ac3d740be4d2a4cf39d290000246128ebd023a864e94a7ffb74bf7cce2fd4367322b8b073f942282bd52ebfe3e62900001c00004004442ffe5aea0cee4dbacc758e801233bdc09a0abf0000001c00004005ba041b5de59955900d818ac54e18b236739d9e8b)) + (sa: len=116 + (p: #1 protoid=isakmp transform=12 len=116 + (t: #1 type=encr id=aes (type=keylen value=0080)) + (t: #2 type=encr id=aes (type=keylen value=0100)) + (t: #3 type=encr id=aes (type=keylen value=00c0)) + (t: #4 type=encr id=3des ) + (t: #5 type=prf id=hmac-sha ) + (t: #6 type=prf id=hmac-md5 ) + (t: #7 type=prf id=aes128_xcbc ) + (t: #8 type=integ id=hmac-sha ) + (t: #9 type=integ id=hmac-md5 ) + (t: #10 type=integ id=aes-xcbc ) + (t: #11 type=dh id=modp1024 ) + (t: #12 type=dh id=modp2048 ))) + (v2ke: len=128 group=modp1024 b5445bd60cece6fdcd3c96a52cbb7bb426a8c7a0f56a9c38d1b1c4f0c3a6e8e7dba5c7339b6ed02e757119dfb5b6933ce93b604987fbbc77221b2a0c7cdd32787eff10572bef546c361462f9da34847969a42e51c755996beac42e6fba961a75de0fc1b23f099380896ee89202122dedac1bd54aa8494ac3d740be4d2a4cf39d) + (nonce: len=32 nonce=(6128ebd023a864e94a7ffb74bf7cce2fd4367322b8b073f942282bd52ebfe3e6) ) + (n: prot_id=#0 type=16388(nat_detection_source_ip) data=(442ffe5aea0cee4dbacc758e801233bdc09a0abf0000001c00004005ba041b5de59955900d818ac54e18b236739d9e8b)) + (n: prot_id=#0 type=16389(nat_detection_destination_ip) data=(ba041b5de59955900d818ac54e18b236739d9e8b)) +IP (tos 0x0, ttl 64, id 19911, offset 0, flags [none], proto UDP (17), length 332) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum 337f!] isakmp 2.0 msgid 00000000 cookie a88875a8198992a6->71be8358efae7663: parent_sa ikev2_init[R]: + (sa: len=44 + (p: #1 protoid=isakmp transform=4 len=44 + (t: #1 type=encr id=aes (type=keylen value=0080)) + (t: #2 type=prf id=hmac-sha ) + (t: #3 type=integ id=hmac-sha ) + (t: #4 type=dh id=modp1024 ))) + (v2ke: len=128 group=modp1024 5a56714d3abf64e3a3f401ead9f5323ff0b77faa5f1e99199b13ac821f0a0c4f854786ca09b7a76aa508bcee11f16369a16d5fa041ca2d9a8dfa8228c61f2482d2175c5c1a9491fc221bec7a1fa69f656d4c98ba49ae9d721dedf4a02d7ecdfc201dc785a13ed74e4f3982762a2720ffdfc365ee4e37279af496cd86f881fd15) + (nonce: len=32 nonce=(b31c379f272ce2984bd17ca38c8729e1edbc081a14fb0f67cff81721dfeec1f9) ) + (n: prot_id=#0 type=16388(nat_detection_source_ip) data=(fe2bfb7c2c81ed0b61f756b57fac78a75ced8af60000001c00004005905954a783be2c37e2ccc4fdd270a532dbe6f428)) + (n: prot_id=#0 type=16389(nat_detection_destination_ip) data=(905954a783be2c37e2ccc4fdd270a532dbe6f428)) +IP (tos 0x0, ttl 64, id 19912, offset 0, flags [none], proto UDP (17), length 264) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum fdaa!] isakmp 2.0 msgid 00000001 cookie a88875a8198992a6->71be8358efae7663: child_sa ikev2_auth[I]: + (v2e: len=204 f606135ad373e70836fda91b63ca4c608e1ad58218488c2647ff1e8a912958aa77efbc3068a2ae6ab7c3d0cb1e6fb864df99c62f2cc045708084708154a393c2f4cbefad1f6848525d49db563e13345a4e6e2fd066c04e2ce291f4714baec6bf328356c446247cab835bda3e8e1aae5967248f01eb3a1c02a541b4da09b3276b400d50a067542a678468c5f41e54017c00964f1003f8c88896a6f12215a5f1a060713cc83802cae3abee18417c0c35dc6f58a01adb96ed1c009c68e3069ae70f4b10afb7736c111ade4d826e) +IP (tos 0x0, ttl 64, id 19913, offset 0, flags [none], proto UDP (17), length 184) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum bf00!] isakmp 2.0 msgid 00000001 cookie a88875a8198992a6->71be8358efae7663: child_sa ikev2_auth[R]: + (v2e: len=124 6afe95bc5147b0ad7e4ccb9141c160a44f7c6eddc6b29d414ad5e2b882544fdc6c3ee6983ae1408b5764b1649343876454d1bf4d515aaf03c15eafe71be6b4cf51ab60630c45bcf0e2a2db8eee70095a4e010fdb342adb6d03dae5def9d4907cdfc8ccd6f3da9b7497c58e84a952d983bafb941ab1de1b0bb9ffad3b) +IP (tos 0x0, ttl 64, id 19914, offset 0, flags [none], proto UDP (17), length 280) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum c32d!] isakmp 2.0 msgid 00000002 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[I]: + (v2e: len=220 53cc6c0b41f14e4fc057c7f6a3524adde8521f26f67c058430a902db1a52ed16d322630d2eb515372dc12d97dc7c20552607e2ed193d9b33939e10aa2fc37b6199f0a629c6b58135f5b6f9e07906cd30dc3cae7d55fe08d95d3e660a623731c396a325adbff11c490f9fd102224391a65fb7bbe862945b64cf1fb833b9ce68c83df0b9d2ce7bd54f650864af9445e547cdfe5caa393344ae5274933b7efcf616821ea7daa9c5a6e8275ad6c688700cb7f4bcd6fb8025e93bb6dd5f581faebcbecb798c87617a4ec1b06ba290ac5fc1d6e4c2725c1f9f0e10b144fbbe) +IP (tos 0x0, ttl 64, id 19915, offset 0, flags [none], proto UDP (17), length 248) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum e6d7!] isakmp 2.0 msgid 00000003 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[I]: + (v2e: len=188 9603e03f280964782717da15a502f0a9e9f17dbf4487c6923cf00b7040d539bc947c705790e4e99b834a7ae2a8d79f5620e11615e0a762889aab821e0d03132dfb8cc6b3718582411bcd98c242a8b10a66274dae1ce055fb30a4d3e64c969be6e08b626958f4446c6e4a0c8d7a24522959c6152e63a575c06930c2097539bfbdff08c70533428cf6b452e0b8b0259c2292925d2ed62e8956bc7e3a911a61509be1ac8f7b7cd4636176e524f4d0f17573f2aeddce2251fd6d5d9cd54d) +IP (tos 0x0, ttl 64, id 19916, offset 0, flags [none], proto UDP (17), length 104) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum f2c0!] isakmp 2.0 msgid 00000002 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[R]: + (v2e: len=44 5bd2d26cb43b6cec30dec13fa387359797baf7b41e783422bc4dabf5d03ab2420d277d3b2f28d1f003da98d1) +IP (tos 0x0, ttl 64, id 19917, offset 0, flags [none], proto UDP (17), length 104) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum e03a!] isakmp 2.0 msgid 00000003 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[R]: + (v2e: len=44 38f60ab69110967961ae04af4e47a770260d61e29d18fb13ce093a47970068dacb342f7999cc3d0d59f77a94) +IP (tos 0x0, ttl 64, id 19918, offset 0, flags [none], proto UDP (17), length 312) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum 661c!] isakmp 2.0 msgid 00000004 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[I]: + (v2e: len=252 c7f2f1cc4997b30a61623222d4bfb535baa302199c4d8c1fdcfa745b0b29b5e7618ff0356848444d25010e5ad420760890ede066c838269b22d9e30d4fec1a012e731a210c243f803b661970d32e998e919f573c5742d2288949052c5a46a0cd7c4a1a295ede296c4fd9839b64dc4944e11a35f42a8ce18b447200fd03dbd58a71583b3a27c380148c801ce14452f7d756b1f55b10b84a58cfa9526001fff7157154645022e4456085517ceed98b79e20ed33297cf5ad80287e782728a8c6b87d2b422e7eeda1c72b33ebc51a5b76def9a59ffd1b4f97dec88c22a4f5448a71aeedf20c87dae5b44cd2e7a519d719a509f83f3b2faf6f5c607da609f) +IP (tos 0x0, ttl 64, id 19919, offset 0, flags [none], proto UDP (17), length 280) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum d1d0!] isakmp 2.0 msgid 00000005 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[I]: + (v2e: len=220 dae6134a9cff1a4e3cc59a79e019a93f8469dd4e2faaaad1c3afba22ecd128fdb1e8954c753f8f62aeb6aac9732f414b065ec39569a670be6980c81eb3e44bc93ec63e9a754d0456c6703cd718371edeef674928180f9d14c39e52cfa4a517368e7db2fa0bfdb41cf56d97006233103f22650fdcd5ffab8418e40903e4749e126d06e9dc2a18cfd5bfda0013e3e9eb53e79bbe30eadf0f4ddcefbab0c08e870b29d39b2401c75b68fc46a066782857ca48d547e410ac15cabb6738875200b535cbd9ae1e1ce99839c9c25639070e5ed977809c50b6bb9550b50b49bb) +IP (tos 0x0, ttl 64, id 19920, offset 0, flags [none], proto UDP (17), length 232) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum db6a!] isakmp 2.0 msgid 00000004 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[R]: + (v2e: len=172 1fd8516b57b1ab1bdbcdba1930a5097decc023c5c534497ca53f178b9d4d11228746454371b0cc6ec067e14e1e5c5652840cfdae0ea84c7f0a6e799ff7fb131d15763feef45e80f24716cde47d23527f68e055a7c3adc7225489295e1bc3f1029b63822872865df55c6c275dead8a6f64bda8ae44f42c318fa71eb04eed7312dafd2dd8665fd5d3225f3aae6f7335b581c3a89c07af1009871dea9927f046432cd01b04234204d01583baf3a) +IP (tos 0x0, ttl 64, id 19921, offset 0, flags [none], proto UDP (17), length 232) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum 9a59!] isakmp 2.0 msgid 00000005 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[R]: + (v2e: len=172 f6fc8113f34b92eb7d595a048f57d46593441ad9a61919e5919e7de4454fa35882937d3b74c83ab959fd053c6a12a51b04a0e92e01683782658bb9af2bbcc7a4bd5e1eef2dbcdc7715cac6eaecfbcc051a46f2263d1b8387bdad7e68c6e4ba1be9794e163e484768995a9f4a18edcbc6a44f0a74cb01c318e7848562e0866f388b8d04f14f1af87de7de6cee1f889d4330d82932a7127b7d1a934e641c32b76e33b37706d50286f8cbe335ba) +IP (tos 0x0, ttl 64, id 19922, offset 0, flags [none], proto UDP (17), length 312) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum 5ff4!] isakmp 2.0 msgid 00000006 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[I]: + (v2e: len=252 0aa2636a3b897ff3fa8093282ad1724ec9f326b64bf998e781d6edbb77a369a8444dc47a4dc095ebd3ac3b1dc337570bc42c93cd6dcb7289bc99a90874e66cc4ede7a13a58ce17c65b185e86def83d66f4c4ddc433e66baf1834e54296671357a5139b0b63ebf32e652df0938badea5a960ee1758e00faa643bed85f7adee2e2e75baeec9e0df88857a67ca5f2a2f4919d0b272313d42c791eb75feca145756a0ccae3640ee98c16689df511443228846d2c5b8830ea6d149c1abed11ad0a28ca33993036e91965d48a82a898145ada994af55978696480ab6cb697e13e67968a7748c3338786efb77250e5411b3a7eac84cd221324bd7b9109d9a69) +IP (tos 0x0, ttl 64, id 19923, offset 0, flags [none], proto UDP (17), length 280) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum 9890!] isakmp 2.0 msgid 00000007 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[I]: + (v2e: len=220 02c703f4bdd83246adc67e1ca07d7e7cfe21b6bde94637680a332813b8a4ca47341abd3a9c37263896c08252bfb1ea6c7ea44783b92ac52acb4fbfec53f03554281c6377650c09208f3d778b11e77b5fbd983be1e96699232392ef31a501fda73c6150fcc2e80bab1e0d49845bd5d511f7c9285ec08352687a2ac8d70d0dec3476491c40b97cb9da405606fc5e8d46bbe199e6d91ae993b7faa0583ec4296a80812fb7e0ae88d3bd54c4a30e5edb2778c960f3e0cb5b1369e999f84de4dc72b5d006805efb7e2d2ed4033e11ff9578012d22942e3799c9382506a021) +IP (tos 0x0, ttl 64, id 19924, offset 0, flags [none], proto UDP (17), length 232) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum 902e!] isakmp 2.0 msgid 00000006 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[R]: + (v2e: len=172 7e2e6623c66e161de9641ac7e1b6dfdcf3a5f45bbed123be88f3754d12514404afc054b3c7f789eb52a432a438359dde31152c11b8d209203d62779ca064823d70536c40f846d43d6694a2f12a3176f57007a3506c82fffaf3dbb713bbdbb5f540b7b39aee3c97145671504356095f7ab0c5a84347c0268bce259ca51b4a2dd75a7e3a7ee79f3bffc58d2fc0ac36686229f2309b5cd0c0dcc2af798664c14f5f166ab5e3c1f693092121aa44) +IP (tos 0x0, ttl 64, id 19925, offset 0, flags [none], proto UDP (17), length 232) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum 49dd!] isakmp 2.0 msgid 00000007 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[R]: + (v2e: len=172 7b545033a2d35df2ab9f26c4bc444713910a32e60fb04cb10a9e76634787f9ddc138c6792faa074be2ebcb43f83f444249679018ec6dc7d4e2247dd8cb915778d90fa5597f1ecba8471db53e3b4da8f73d1eb60c23ca9fb5fa599dc526a961364471b49e5288fcef6a24d02a084d29c4a5c5d1fa305310dba01d09c9c36c86c0af297e05d3fc8559a11666a4363bacc354e96c941349b3f60dd397eb4c2bb09f381831167c0b33686c6bb5d8) +IP (tos 0x0, ttl 64, id 19926, offset 0, flags [none], proto UDP (17), length 392) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum 1d29!] isakmp 2.0 msgid 00000008 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[I]: + (v2e: len=332 c4bf89ec6e7936ac98a432a525c2406de940b338c9149ce19cb1bf23a69dfd481df7b3ada1adbb70bf17074643edf97e63ade5ed07f74674f26c48d2d6a9044477ee9f203084c26e85405987ec8b9693deaea20ce78c2a451bf4e834d7bcc3c54c1322b5f28ba307f2ce31a00552b97b8fc103a29fee2e0040ccddfa10bf3ab3d1209e643c228dec575240c7bd750cf4d6d06c958f66bd8a79831df871f6fbd93e025b16bd03de35ffcdbabac65570d2367e624d9f8e8560da9bc3a2142b75008b7ceb8e839dbf425da74c4be15c9dc31735ef1ac6f65c2375042dcf9682df74259b8c4437d7ee8df19fea6ec1d5bd491409cc7276d70ee0ba9172b4177fbce7fa28171a236ca8e2e0c149e602c9c6a0a3ff5f054287f54b7c314b07cdf6d246241dd364c7419cc0647422d08f5511b13e7b5cb719616466e1c6966f5ccd4d2ca2b12dda7047c6f63af5dd47) +IP (tos 0x0, ttl 64, id 19927, offset 0, flags [none], proto UDP (17), length 344) + 192.168.1.1.500 > 192.168.1.2.500: [bad udp cksum 25cf!] isakmp 2.0 msgid 00000008 cookie a88875a8198992a6->71be8358efae7663: child_sa child_sa[R]: + (v2e: len=284 2c1ac864ae2c8499b3c7af8c61a8c4dc9e1af23577b588d6bb3fdef3e483cc2f0158c07071d6dfaef73dccb6cdcf7a5758e41778daceb71cf6733e17168beff6ef2015d670c0b6574fc72e97d4282909966f394a9f9e0fced8e269bbf60e93f0f2080f48dcd4e02ff1129b94f68b268ddd9cff436f38e78fa7986d87e622d1f3da3b3c2795570ebc27d3c3d51f29ef0fff01ae89bd71d2e10ab8faee7d7bb4b5be8a9ee0ea9b5e347bbaf3ebdfaf19735d75e6faa020d6ea72826c2aa5cb2ee648de6b36cbb25087428dea44bd34504e05f2d4fef43c48e2a690510e9278ca8ff2f775792af061b5ccbcf77b3fee658851289969c55edc6d561718a0c761b09b0f67c96e61d00a7fa2929023b5adcfdd33436f63a478141d51b52333) +IP (tos 0x0, ttl 64, id 19928, offset 0, flags [none], proto UDP (17), length 120) + 192.168.1.2.500 > 192.168.1.1.500: [bad udp cksum 6e7f!] isakmp 2.0 msgid 00000000 cookie 1d9be9451d4f97a8->64a2a4b5d0e17b6a: parent_sa inf2[I]: + (v2e: len=60 691b48829b6c5d6dd93fa8e33c38dd4c00f5434dc22b4251c0876f0bdb5dbba3dd06283907559a272f07ec7709b9d596a24cd8fe69b82a1f65dbf6f2) diff --git a/tests/ikev2pI2-secrets.txt b/tests/ikev2pI2-secrets.txt new file mode 100644 index 0000000..efe9636 --- /dev/null +++ b/tests/ikev2pI2-secrets.txt @@ -0,0 +1,2 @@ +ikev2 I 0x0001020304050607 0xc02e7a3031a03188 sha1:0x4ea8e662b07cdd430f6944c6723e4b82d5722418 aes128:0x3f44bf47cafd8150591deb088199fcbf +ikev2 R 0x0001020304050607 0xc02e7a3031a03188 sha1:0x515b0bd22e6d76b34fdb760aa7bfad80b109b75d aes128:0xbedb67ec7dc3d00cccac42e70cd63bde diff --git a/tests/ikev2pI2.out b/tests/ikev2pI2.out new file mode 100644 index 0000000..7940e8c --- /dev/null +++ b/tests/ikev2pI2.out @@ -0,0 +1,41 @@ +IP (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 536, bad cksum 0 (->f48e)!) + 192.1.2.45.500 > 192.1.2.23.500: [no cksum] isakmp 2.0 msgid 00000000 cookie 0001020304050607->0000000000000000: parent_sa ikev2_init[I]: + (sa[C]: len=240 + (p: #1 protoid=isakmp transform=4 len=40 + (t: #1 type=encr id=aes ) + (t: #2 type=integ id=hmac-sha ) + (t: #3 type=prf id=hmac-sha ) + (t: #4 type=dh id=modp1536 )) + (p: #2 protoid=isakmp transform=4 len=40 + (t: #1 type=encr id=aes ) + (t: #2 type=integ id=hmac-sha ) + (t: #3 type=prf id=hmac-md5 ) + (t: #4 type=dh id=modp1536 )) + (p: #3 protoid=isakmp transform=4 len=40 + (t: #1 type=encr id=3des ) + (t: #2 type=integ id=hmac-sha ) + (t: #3 type=prf id=hmac-sha ) + (t: #4 type=dh id=modp1536 )) + (p: #4 protoid=isakmp transform=4 len=40 + (t: #1 type=encr id=3des ) + (t: #2 type=integ id=hmac-sha ) + (t: #3 type=prf id=hmac-md5 ) + (t: #4 type=dh id=modp1536 )) + (p: #5 protoid=isakmp transform=4 len=40 + (t: #1 type=encr id=3des ) + (t: #2 type=integ id=hmac-sha ) + (t: #3 type=prf id=hmac-sha ) + (t: #4 type=dh id=modp1024 )) + (p: #6 protoid=isakmp transform=4 len=40 + (t: #1 type=encr id=3des ) + (t: #2 type=integ id=hmac-sha ) + (t: #3 type=prf id=hmac-md5 ) + (t: #4 type=dh id=modp1024 ))) + (v2ke: len=192 group=modp1536 ffbc6a92a6b9559b05fa96a7a43507b4c1e1c0861a5871d9ba73a163113788c0debb3979e7ff0c52b4ce6050eb05369ea4300d2bff3b1b299f3b802ccb13318c2ab9e3b5627cb4b35eb939982076b57c050d7b35c3c5c7cc8c0feab7b64a7d7b6b8f6b4dabf4ac406dd20126b90a98ac766efa37a7890c4394ff9a77615b58f52d651bbfa58d2a549af8b01aa4bca3d762426663b155d4ebda9f60a6a13573e6a888135cdc673dd483029903f3a90eca23e1ec1e270331b2d050f4f758f49927) + (nonce[C]: len=16 nonce=(b5ce8419095c6e2b6b62d3055305b3c4) ) + (v2vid: len=12 vid=OErlA\nQukSR 4f45726c415c6e51756b5352) +IP (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 312, bad cksum 0 (->f56e)!) + 192.1.2.45.500 > 192.1.2.23.500: [no cksum] isakmp 2.0 msgid 00000000 cookie 0001020304050607->c02e7a3031a03188: parent_sa ikev2_auth[I]: + (v2e[C]: len=252 000102030405060708090a0b0c0d0e0f4bcf2da20444caca5fb591c1ab4b9b4d4f22ac7cb49e6b08d2738884fb3efd8eebc607accc1f80f890e24df65e53d61e899f1d319d89c033524d036fd4ea7e0345def93356e2865e5481a6a20a7604083de04595e1071a2e98179eefb4e6ae4708e6875ae297b4dc5b2602d971e36f66cef12303946eea897d86bbb5903115281a266f4dcb627e146972ff2f7102931df82f24a2e40df594afc11e0a85eb1c56b9eddb7e2de52fa95cf51f4b4c9b5d53237ae39f64519413d201374a987fa8d1ce460fa2d67c417462203f2948c0b9ed8b734a69a015ff63bde767f44f83c3cfe5119d72d74e695b1032b957 + (v2IDi: len=8 0200000077657374 fqdn:west) + (v2auth: len=196 method=rsasig authdata=(000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) )) diff --git a/tests/ikev2pI2.puu b/tests/ikev2pI2.puu new file mode 100644 index 0000000..314188e --- /dev/null +++ b/tests/ikev2pI2.puu @@ -0,0 +1,24 @@ +begin 644 ikev2pI2.pcap +MU,.RH0(`!````````````-P%````````@%$!```````<`@``'`(```(```!% +M``(8`````$`1``#``0(MP`$"%P'T`?0"!`````$"`P0%!@<``````````"$@ +M(@@````````!_"*``/0"```H`0$`!`,```@!```,`P``"`,```(#```(`@`` +M`@````@$```%`@``*`(!``0#```(`0``#`,```@#```"`P``"`(```$````( +M!```!0(``"@#`0`$`P``"`$```,#```(`P```@,```@"```"````"`0```4" +M```H!`$`!`,```@!```#`P``"`,```(#```(`@```0````@$```%`@``*`4! +M``0#```(`0```P,```@#```"`P``"`(```(````(!````@```"@&`0`$`P`` +M"`$```,#```(`P```@,```@"```!````"`0```(H``#(``4``/^\:I*FN56; +M!?J6IZ0U![3!X<"&&EAQV;ISH6,1-XC`WKLY>>?_#%*TSF!0ZP4VGJ0P#2O_ +M.QLIGSN`+,L3,8PJN>.U8GRTLUZY.9@@=K5\!0U[-VN/ +M:TVK]*Q`;=(!)KD*F*QV;OHWIXD,0Y3_FG=A6UCU+64;OZ6-*E2:^+`:I+RC +MUV)"9F.Q5=3KVI]@IJ$U<^:HB!-!%E>$'&BZ8 +M%Y[OM.:N1PCFAUKBE[3<6R8"V7'C;V;.\2,#E&[JB7V&N[60,14H&B9O3"H7K'%:Y[=M^+>4OJ5SU'TM,FUU3(WKC +MGV11E!/2`3=*F'^HTV+ 127.0.0.1.500: isakmp: diff --git a/tests/isakmp2.out b/tests/isakmp2.out new file mode 100644 index 0000000..44c28db --- /dev/null +++ b/tests/isakmp2.out @@ -0,0 +1 @@ +IP 129.170.249.126.500 > 129.170.249.87.500: isakmp: phase 1 ? base diff --git a/tests/isakmp3.out b/tests/isakmp3.out new file mode 100644 index 0000000..8619263 --- /dev/null +++ b/tests/isakmp3.out @@ -0,0 +1,3 @@ +IP (tos 0x0, ttl 255, id 41068, offset 0, flags [none], proto UDP (17), length 312) + 127.0.0.1.501 > 127.0.0.1.500: isakmp 1.0 msgid 00000000: phase 1 I ident: + (id: idtype=FQDN protoid=0 port=0 len=248 \0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00) diff --git a/tests/isakmp4.out b/tests/isakmp4.out new file mode 100644 index 0000000..0de3ebc --- /dev/null +++ b/tests/isakmp4.out @@ -0,0 +1,35 @@ +ARP, Request who-has 192.1.2.23 tell 192.1.2.254, length 28 +ARP, Reply 192.1.2.23 is-at 10:00:00:64:64:23, length 28 +IP 192.1.2.254.500 > 192.1.2.23.500: isakmp: phase 1 I ident +IP 192.1.2.23.500 > 192.1.2.254.500: isakmp: phase 1 R ident +IP 192.1.2.254.500 > 192.1.2.23.500: isakmp: phase 1 I ident +IP 192.1.2.23.500 > 192.1.2.254.500: isakmp: phase 1 R ident +IP 192.1.2.254.4500 > 192.1.2.23.4500: NONESP-encap: isakmp: phase 1 I ident[E] +IP 192.1.2.23.4500 > 192.1.2.254.4500: NONESP-encap: isakmp: phase 1 R ident[E] +IP 192.1.2.254.4500 > 192.1.2.23.4500: NONESP-encap: isakmp: phase 2/others I oakley-quick[E] +IP 192.1.2.23.4500 > 192.1.2.254.4500: NONESP-encap: isakmp: phase 2/others R oakley-quick[E] +IP 192.1.2.254.4500 > 192.1.2.23.4500: NONESP-encap: isakmp: phase 2/others I oakley-quick[E] +IP 192.1.2.254.4500 > 192.1.2.23.4500: UDP-encap: ESP(spi=0xf4dc0ae5,seq=0x1), length 132 +ARP, Request who-has 192.1.2.254 tell 192.1.2.23, length 28 +ARP, Reply 192.1.2.254 is-at 10:00:00:de:ad:ba, length 28 +IP 192.1.2.23.4500 > 192.1.2.254.4500: NONESP-encap: isakmp: phase 2/others R oakley-quick[E] +IP 192.1.2.254.4500 > 192.1.2.23.4500: NONESP-encap: isakmp: phase 2/others I oakley-quick[E] +IP 192.1.2.254.4500 > 192.1.2.23.4500: UDP-encap: ESP(spi=0xf4dc0ae5,seq=0x2), length 132 +IP 192.1.2.254.4500 > 192.1.2.23.4500: isakmp-nat-keep-alive +IP 192.1.2.254.4500 > 192.1.2.23.4500: UDP-encap: ESP(spi=0xf4dc0ae5,seq=0x3), length 132 +IP 192.1.2.23.4500 > 192.1.2.254.4500: NONESP-encap: isakmp: phase 2/others R oakley-quick[E] +IP 192.1.2.254.4500 > 192.1.2.23.4500: NONESP-encap: isakmp: phase 2/others I oakley-quick[E] +IP 192.1.2.254.4500 > 192.1.2.23.4500: UDP-encap: ESP(spi=0xf4dc0ae5,seq=0x4), length 132 +IP 192.1.2.254.4500 > 192.1.2.23.4500: isakmp-nat-keep-alive +IP 192.1.2.254.4500 > 192.1.2.23.4500: UDP-encap: ESP(spi=0xf4dc0ae5,seq=0x5), length 132 +IP 192.1.2.254.4500 > 192.1.2.23.4500: UDP-encap: ESP(spi=0xf4dc0ae5,seq=0x6), length 132 +ARP, Request who-has 192.1.2.23 tell 192.1.2.254, length 28 +ARP, Reply 192.1.2.23 is-at 10:00:00:64:64:23, length 28 +IP 192.1.2.254.4500 > 192.1.2.23.4500: isakmp-nat-keep-alive +IP 192.1.2.254.4500 > 192.1.2.23.4500: UDP-encap: ESP(spi=0xf4dc0ae5,seq=0x7), length 132 +IP 192.1.2.23.4500 > 192.1.2.254.4500: NONESP-encap: isakmp: phase 2/others R oakley-quick[E] +IP 192.1.2.254.4500 > 192.1.2.23.4500: UDP-encap: ESP(spi=0xf4dc0ae5,seq=0x8), length 132 +ARP, Request who-has 192.1.2.254 tell 192.1.2.23, length 28 +ARP, Reply 192.1.2.254 is-at 10:00:00:de:ad:ba, length 28 +IP 192.1.2.254.4500 > 192.1.2.23.4500: isakmp-nat-keep-alive +IP 192.1.2.23.4500 > 192.1.2.254.4500: NONESP-encap: isakmp: phase 2/others R inf[E] diff --git a/tests/isakmp4500.puu b/tests/isakmp4500.puu new file mode 100644 index 0000000..0b55dcc --- /dev/null +++ b/tests/isakmp4500.puu @@ -0,0 +1,155 @@ +begin 644 isakmp4500.pcap +MU,.RH0(`!``````````````&```!```````````````J````*@```/______ +M_Q```-ZMN@@&``$(``8$``$0``#>K;K``0+^````````P`$"%P`````````` +M*@```"H````0``#>K;H0``!D9",(!@`!"``&!``"$```9&0CP`$"%Q```-ZM +MNL`!`OX``````````$X!``!.`0``$```9&0C$```WJVZ"`!%``%```!``#\1 +MM97``0+^P`$"%P'T`?0!+)6LGHGR.(^0O!X```````````$0`@`````````! +M)`T``)0````!`````0```(@``0`$`P``(``!``"`"P`!@`P.$(`!``6``@`! +M@`,``X`$``4#```@`0$``(`+``&`#`X0@`$`!8`"``*``P`#@`0`!0,``"`" +M`0``@`L``8`,#A"``0`%@`(``H`#``.`!``"````(`,!``"`"P`!@`P.$(`! +M``6``@`!@`,``X`$``(-```03T5K4F)'6%)V;5!%#0``%*_*UQ-HH?'):X:6 +M_'=7`0`-```42A,<@0<#6$5<5RCR#I5%+PT``!1]E!FF4Q#*;RP7G9(54IU6 +M#0``%,U@1D,UWR'X?/VR_&BVI$@````41(45+1BVN\T+Z*A&E7G=S``````` +M````L@```+(````0``#>K;H0``!D9",(`$4``*0``$``0!&U,<`!`A?``0+^ +M`?0!]`"08%.>B?(XCY"\'@IT-7SCT:2_`1`"``````````"(#0``-`````$` +M```!````*``!``$````@``$``(`+``&`#`X0@`$`!8`"``&``P`#@`0`!0T` +M`!!/16M28D=84G9M4$4-```4K\K7$VBA\"G0U?./1I+\$$`(````` +M`````1P*``#$M]N'X4E&AEMT*7(UA)]?Z:M`RW>TPRPR/2V-U^-O'ST7,9K7 +MCQQFQ`#^2/PP0G^@]QHR=9!Y7?/EL'O(\L(I'#51V6N1?)1J+6P-A6&T0Y@" +M-KJ[,_WPC+W%H'KSV>J_(W#3`3A4&A^4Q*T^3Q*2'^M#9[XHW-IVWO.#J=M? +MDHTX?/DS#]CDJG;?BC_E:$W:3AD]N9+!U'[+6UU.`,)4^&ASH2SO\CU.=2!# +MH'UY(FI*395>I?Z@4```4 +M;OX2\$KY#?O/L5UQN$&[G@```!1$]1?@/[.!^`^$+14XS/^L``````````!& +M`0``1@$``!```-ZMNA```&1D(P@`10`!.```0`!`$;2=P`$"%\`!`OX!]`'T +M`20!UYZ)\CB/D+P>"G0U?./1I+\$$`(``````````1P*``#$YYI?^#V[%WO* +M+,?[XKU\"YVFZ0UCMOA'6Y:C93#4^M&/)'3",1Q/"&7*"D0_<1SX#@"KRZDV +M\_XCB4O9XNS0"_O8-'[C&AG5O;G^G_N*#?4,"OA'?R><"WN68Q(H<1EONM3! +MS3=]U]MRZ(4UBM]&:I\KW&3X;LQ%M[B0:,/"]DTM1^J8+8CESE'6JEFCE,,$ +M?$W5P,^5=1K1AT@YX0J-9%/E]`MY&<%C?*Y*K\'5X#2B5OD6+FTGJ)^V299# +M*>H6%```%&Q^7ZRJ16$T%<6UJE;P`` +M`!1N_A+P2OD-^\^Q77&X0;N>``````````!R`0``<@$``!```&1D(Q```-ZM +MN@@`10`!9```0``_$;5QP`$"_L`!`A<1E!&4`5!RH0````">B?(XCY"\'@IT +M-7SCT:2_!1`"`0````````%$H"1@W`ZTW:4&'Z=!K*`IRTNLK:3J/^$DD/B4 +M>Q,F?M5`3=(?!HGW$/M)`\W8Z/'FXK6$!(9!7BL9!@QV=(^E7><\)R8EVE3F +M6`.O^:2F!(>LD7%71N]`LA?B!/!0\*H2"YOJ0]_W9#9DJYZ).M/.;+8A?L[O +M`J-'HV_0*'&&^P\8:$'I^"13SN]VT%5\8O8;P2VV=`+&9+4]'MH+/&:'PR!H +M4O#,GI+1=+*MRN"5.-8D&$16)"G0U?./1I+\%$`(!`````````2S" +M8Z5]+<^-M8Q9P&X;^%JN2^*NYC1"AZ%4J-PIMZM611WA:Z$*6IBWC.3.9037)L`[ADSH`K&0*^[6)>")$E3;"4;U="I",2*`1TP_=5+%B"II3>( +M'@``````````V@$``-H!```0``!D9",0``#>K;H(`$4``4YQ5SAO`10)\84&I?],R2.?5M +MZ/Y^Y"#*%+0.<9KX(/Z$'&M,-)/2I7U^,!G,*G!E_O.D;7F_;D^V#&&*(R.+ +MH;YSI'1@I8GV%+\'*6,1(8`8D(VUP[,(R?PQ7#,5WQY3[HT+IFF"3?.+;(*M +M_?C;JQ#]O'9522*ZO7>'TEDYLLA`*L$8(XJ$!T>_HYS?G=WR11E($-021FMS +MB[NXAJ^CQVGO87[B@^I6THHW-%Z8%PTH&BCO^.[@K_NS8RVTE7CE&MA]6C@> +MEDIDM&T^.41?F(\X$Z-5[547$HC='*\>8``"[9.IHT)+[,^LZ?_6(6I\L32# +MF-JM7U".L4?X/8=G*KFA<>THJ-622W,;J`IW2^MLBI?_O<"G0U?./1I+\($"`!BWZ)1P```5RM:&N4 +MQ1;W19+;77%JE,,H'8&F6ITJM=R5O>KL1%[]#E/LJ#&./WFJ`#,3C!H=I_'* +M34/)_E+)(`!A&W00*T\"9O9JX0N">$#'(ZL<$'\P=GHB.0:\AXT/!^^*%U.'5#'2IX:7/2KZ$%^3W;%R4[&2T>'?2(@FF +M#T/=+2O[?Q4.(\@Q;]3V=L5Q2XFG)^E)0J:1AX`J4%E3_Y]^6='!R-ENY%9# +M3!XD:5K?/V&.!&X#>I_$96Y;P_!5']070(D3N#$47!AZ^VCW-?I?JT2AL5YOWBO5[D!"OV)46(FK)9" +M$C40GNJ7*A,SE6%6A(4>KPE(-$)=L6=2VQLO>Y12N8QBH3V%(90.\5YL`R,O +M1@``````````8@```&(````0``!D9",0``#>K;H(`$4``%0``$``/Q&V@<`! +M`O[``0(7$901E`!`KQ<`````GHGR.(^0O!X*=#5\X]&DOP@0(`&+?HE'```` +M-"4[,88.:.R$%:1S6K/XK;H(`$4``*"JM```/Q%+@<`!`O[``0(7$901E`",``#TW`KE```` +M`?SD"<11-X_=FBX7J&]'/C[B>;BA23X"^A;(BA/H;8_\0'U,E@M&;+=R&*LY +MAF.NT6/*J.SL[UR2)+H^A6#5<38R;!FY\:AV_6ZV)FQ2! +M1T\L:`GPK6U?_?TVHSK[6(WSF?Q"XF5K/0U,A.Y+D\RP]G(``````````"H` +M```J````$```WJVZ$```9&0C"`8``0@`!@0``1```&1D(\`!`A<```````#` +M`0+^```````````J````*@```!```&1D(Q```-ZMN@@&``$(``8$``(0``#> +MK;K``0+^$```9&0CP`$"%P``````````B@$``(H!```0``#>K;H0``!D9",( +M`$4``7P``$``0!&T6<`!`A?``0+^$901E`%HRNX`````GHGR.(^0O!X*=#5\ +MX]&DOP@0(`&+?HE'```!7*UH:Y3%%O=%DMM=<6J4PR@=@:9:G2JUW)6]ZNQ$ +M7OT.4^RH,8X_>:H`,Q.,&AVG\B(Y!KR'C0\'[XIS!(%P&'QX74X=4,=*GAS%MDNE:?+;+?\O0S-Y +MI<]*OH07Y/=L7)3L9+1X=](B":8/0]TM*_M_%0XCR#%OU/9VQ7%+B:*]7N0$*_8E18B:LED(2-1">ZIB?(XCY"\ +M'@IT-7SCT:2_"!`@`8M^B4<````T)3LQA@YH[(05I'-:L_AR6CWGJ@DY)*0" +M``````````"N````K@```!```&1D(Q```-ZMN@@`10``H*JU```_$4N`P`$" +M_L`!`A<1E!&4`(P``/3<"N4````";5_]_3:C.OM8C?.9_$+B9;KU/R+D"U^- +MLGB)>"40ZCMW:+^A4%UI1Y)\.O4B]`44T(2XS\S=2[[[X.6A-PCDZP*3XFAD +M294>+W:M%%+\`)?XP#[:6]NHG>#;FFF-RMAA7D"KQ-&OX3Z5S'CBYC"740``````````*P```"L````0``!D9",0``#>K;H(`$4``!T` +M`$``/Q&VN,`!`O[``0(7$901E``)6)O_``````````"N````K@```!```&1D +M(Q```-ZMN@@`10``H*JV```_$4M_P`$"_L`!`A<1E!&4`(P``/3<"N4````# +M7D"KQ-&OX1F0#F$^I@1V5E>.`*!H=Z?(&*,.MS]E4H#P+2"^MMG?%@Y3*L%D'7$>LLOA,HUEB3IB;87,\:-0``````````B@$` +M`(H!```0``#>K;H0``!D9",(`$4``7P``$``0!&T6<`!`A?``0+^$901E`%H +MRNX`````GHGR.(^0O!X*=#5\X]&DOP@0(`&+?HE'```!7*UH:Y3%%O=%DMM= +M<6J4PR@=@:9:G2JUW)6]ZNQ$7OT.4^RH,8X_>:H`,Q.,&AVG\B(Y!KR'C0\'[XIS!(%P&'QX74X= +M4,=*GAS%MDNE:?+;+?\O0S-YI<]*OH07Y/=L7)3L9+1X=](B":8/0]TM*_M_ +M%0XCR#%OU/9VQ7%+B:*]7N0$*_8E18B:LED(2-1">ZIB?(XCY"\'@IT-7SCT:2_"!`@`8M^B4<````T)3LQA@YH +M[(05I'-:L_AR6CWGJ@DY)*0"``````````"N````K@```!```&1D(Q```-ZM +MN@@`10``H*JW```_$4M^P`$"_L`!`A<1E!&4`(P``/3<"N4````$"^MMG?%@ +MY3*L%D'7$>LLOHFXH,6B3<'M/]A_UT%X.MP;F`ZT@=\62*]W'/Y5@1,(8+`W +MTIZ(C;8G'VC<"+'VM:$K/=:VI +MD#:KB^/G$BB@:+=TSV\S)T5-E#UOBKZ"E5_,%P``````````*P```"L````0 +M``!D9",0``#>K;H(`$4``!T``$``/Q&VN,`!`O[``0(7$901E``)6)O_```` +M``````"N````K@```!```&1D(Q```-ZMN@@`10``H*JX```_$4M]P`$"_L`! +M`A<1E!&4`(P``/3<"N4````%D#:KB^/G$BB@:+=TSV\S)XZ>X,YAOI/W1_BS +M7:N%MO?3J+1\I=>O-36N1GBDD+HMR]D8U)G(OJ] +MMX!><$3'U0``````````K@```*X````0``!D9",0``#>K;H(`$4``*"JN0`` +M/Q%+?,`!`O[``0(7$901E`",``#TW`KE````!HUKYV'DUKD9XI)"Z+@>3:9638^IH_2\8CVE-BL2&43,3ZAY3'1@3Z:+\)XSXDSO]L,@? +MCOL6@]+&+X^#H(D.X>B;)<%[E4:S:#.D70:!#<8Q\QZFH`K;H(`$4``!T``$``/Q&VN,`!`O[` +M`0(7$901E``)6)O_``````````"N````K@```!```&1D(Q```-ZMN@@`10`` +MH*JZ```_$4M[P`$"_L`!`A<1E!&4`(P``/3<"N4````'$-QC'S'J:@!R,;Z< +M<"K%#ST!-8\O2;F**R/9Z%HAZ`2#KQIW*9'HI9C067ZK-G^XAL^O0I7Z/'H( +M<.`7P@/P'/E0@``````````B@$``(H!```0``#>K;H0 +M``!D9",(`$4``7P``$``0!&T6<`!`A?``0+^$901E`%HRNX`````GHGR.(^0 +MO!X*=#5\X]&DOP@0(`&+?HE'```!7*UH:Y3%%O=%DMM=<6J4PR@=@:9:G2JU +MW)6]ZNQ$7OT.4^RH,8X_>:H`,Q.,&AVG\B(Y!KR'C0\'[XIS!(%P&'QX74X=4,=*GAS%MDNE:?+; +M+?\O0S-YI<]*OH07Y/=L7)3L9+1X=](B":8/0]TM*_M_%0XCR#%OU/9VQ7%+ +MB:*]7N0$*_8E18B:LED(2-1">ZIGVJ+F +M#M/G_FP&NANM[W@`)Y9\\Z?F4SX%'E.^2BCP\9+!/`25PK%+G'U@$&1+=@%( +M#9RV^U"B8-5,EXJ0-QZTLOJ/L^F\).BC@++XQGOL8JC_`L;'=``````````` +M*@```"H````0``#>K;H0``!D9",(!@`!"``&!``!$```9&0CP`$"%P`````` +M`,`!`OX``````````"H````J````$```9&0C$```WJVZ"`8``0@`!@0``A`` +M`-ZMNL`!`OX0``!D9"/``0(7```````````K````*P```!```&1D(Q```-ZM +MN@@`10``'0``0``_$;:XP`$"_L`!`A<1E!&4``E8F_\``````````'H```!Z +M````$```WJVZ$```9&0C"`!%``!L``!``$`1M6G``0(7P`$"_A&4$90`6,G# +M`````)Z)\CB/D+P>"G0U?./1I+\($`4!`KW&3P```$S_T\^1(\?(IVCQDA]J +C20SF@.^<&]2'1D(_3FHHKW7PKQJ'!!.01QV>?]$9K_EN`N<` +` +end diff --git a/tests/isis-infinite-loop.pcap b/tests/isis-infinite-loop.pcap new file mode 100644 index 0000000000000000000000000000000000000000..b482fc850d01ee6a08554d4bce1838e59f1d60a5 GIT binary patch literal 454 zcmca|c+)~A1{MYwNB}Ylfw<>tzLUX3W(GGP8-y8Hn1IANEfAA|frG)7fx(P{!GXa+ zztZ7v1(W%K6^x8PiGR(~jBG-T|Jnaz07iC*sfGzGM40;L>#GeDJ&8B9$cvQ-Q;%3Y pjJ_OAyr~;Z*a({1px^d)!4W|{;!XW3$4-Q)Q+|Ehy4IdJQvtHCpl<*G literal 0 HcmV?d00001 diff --git a/tests/ldp-infinite-loop.pcap b/tests/ldp-infinite-loop.pcap new file mode 100644 index 0000000000000000000000000000000000000000..ea31f0c06f3ec61999b1de0186618b81e0627283 GIT binary patch literal 414 zcmca|c+)~A1{MYwNB}Ylf!P0QzEjg0HU>K&8-y8Hn1IANEfAA|frG)7fkBUf!GXa+ zuq{%zK Za1miz`Fq~0p94Xr-RA+B79ECZ8UW>vh+F^w literal 0 HcmV?d00001 diff --git a/tests/lmp.out b/tests/lmp.out new file mode 100644 index 0000000..2739d9f --- /dev/null +++ b/tests/lmp.out @@ -0,0 +1,36 @@ +IP (tos 0x0, ttl 1, id 44530, offset 0, flags [none], proto UDP (17), length 84) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 56 +IP (tos 0x0, ttl 1, id 44531, offset 0, flags [none], proto UDP (17), length 56) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 28 +IP (tos 0x0, ttl 1, id 44532, offset 0, flags [none], proto UDP (17), length 84) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 56 +IP (tos 0x0, ttl 1, id 44533, offset 0, flags [none], proto UDP (17), length 76) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 48 +IP (tos 0x0, ttl 1, id 44534, offset 0, flags [none], proto UDP (17), length 68) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 40 +IP (tos 0x0, ttl 1, id 44535, offset 0, flags [none], proto UDP (17), length 44) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 16 +IP (tos 0x0, ttl 1, id 44536, offset 0, flags [none], proto UDP (17), length 124) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 96 +IP (tos 0x0, ttl 1, id 44537, offset 0, flags [none], proto UDP (17), length 68) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 40 +IP (tos 0x0, ttl 1, id 44538, offset 0, flags [none], proto UDP (17), length 60) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 32 +IP (tos 0x0, ttl 1, id 44539, offset 0, flags [none], proto UDP (17), length 52) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 24 +IP (tos 0x0, ttl 1, id 44540, offset 0, flags [none], proto UDP (17), length 52) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 24 +IP (tos 0x0, ttl 1, id 44541, offset 0, flags [none], proto UDP (17), length 52) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 24 +IP (tos 0x0, ttl 1, id 44542, offset 0, flags [none], proto UDP (17), length 52) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 24 +IP (tos 0x0, ttl 1, id 44543, offset 0, flags [none], proto UDP (17), length 52) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 24 +IP (tos 0x0, ttl 1, id 44544, offset 0, flags [none], proto UDP (17), length 44) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 16 +IP (tos 0x0, ttl 1, id 44545, offset 0, flags [none], proto UDP (17), length 64) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 36 +IP (tos 0x0, ttl 1, id 44546, offset 0, flags [none], proto UDP (17), length 72) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 44 +IP (tos 0x0, ttl 1, id 44547, offset 0, flags [none], proto UDP (17), length 64) + 10.0.12.1.49998 > 10.0.12.2.49998: [no cksum] UDP, length 36 diff --git a/tests/lmp.puu b/tests/lmp.puu new file mode 100644 index 0000000..c14cd56 --- /dev/null +++ b/tests/lmp.puu @@ -0,0 +1,42 @@ +begin 644 lmp.pcap +MU,.RH0(`!````````````/__```!````I!J-0&;J``!B````8@`````%75SJ +MQ@`$=="&2@@`10``5*WR```!$=^D"@`,`0H`#`+#3L-.`$```!````4`.``` +M`0,`"`$````!!0`(`````P(#``@!````@0@`&````!0````>")*``$+(```` +M```(I!J-0#SQ``!&````1@`````%75SJQ@`$=="&2@@`10``.*WS```!$=^_ +M"@`,`0H`#`+#3L-.`"0``!````0`'````0$`"`````$!!P`,````,@```#RD +M&HU`@/(``&(```!B``````5=7.K&``1UT(9*"`!%``!4K?0```$1WZ(*``P! +M"@`,`L-.PTX`0```$````P`X```!`0`(`````0$"``@*`#(!`@$`"`````(" +M!0`(`````P("``@*`#("@08`"``%``^D&HU`?_,``%H```!:``````5=7.K& +M``1UT(9*"`!%``!,K?4```$1WZD*``P!"@`,`L-.PTX`.```$````@`P```! +M`0`(`````0$"``@*`#(!`@$`"`````("!0`(`````P("``@*`#("I!J-0'+T +M``!2````4@`````%75SJQ@`$=="&2@@`10``1*WV```!$=^P"@`,`0H`#`+# +M3L-.`#```!````$`*````0$`"`````$!!0`(`````P$"``@*`#(!@08`"``% +M``^D&HU`0_4``#H````Z``````5=7.K&``1UT(9*"`!%```LK?<```$1W\<* +M``P!"@`,`L-.PTX`&```$```#P`0```"!0`(`````:0:C4"E]P``B@```(H` +M````!5Ulmp.new +if diff lmp.new lmp.out +then + echo passed. +else + echo failed. +fi + + diff --git a/tests/lspping-fec-ldp.pcap b/tests/lspping-fec-ldp.pcap new file mode 100644 index 0000000000000000000000000000000000000000..87e86c79e6d974f2a523186347bf0813a84e71db GIT binary patch literal 1190 zcmZ{jJ4ho@6o${8%xILEXyPLg6%-N^EEkI{f{caOh>M_NA=oTzp=@Fy79ki5Ed*E4 zRSSz?q1Y)&v=BCk0SiG9UzK*tT8Nb>t3k(e?<52Fk~wf-UVQ&IKQmXk)P@8y6z5g} zsKArf*r`7Ls=_xsrfWE)8Q-#|cOODevI;;i+doldSyr7+XSEFJpZET)-H${t;nU&0 z5r7b9rJ`kgiWbir!a$AeNBrFxfdNF*W%!jUqZ^<%S%Y|Y?<~bnBgvD}cHryU5)eF* z@L_X^ej4)wIh!nA!22q$q7p({@FLAPzaXIFFGBBnLjp#^RefSHCDP_(S6>SuIpjM=SYr!79Q0@*7BdFFi-?;ol>)l5wqA$zBhT z_c5Unqfp7zqYJ{APM1|;;yaS{4F6ZaUn4$}sMg_ozlHAysUi?S)rDu9dcCaP8NS|V zMyOZ9*A4)AMsi_sa|3gp=A9$=g0llz zZ9ra{ipqGO`y^;a?zM#T5p(wN&O-}=v&A=a@^eAtb=f)NUx1%+oOh181ZNppLG1a- z&Y5P+mvYWAXSd+|AUIomGbi5{Lf)dCb2D>}@y?M0!C6682z$oAwJ<`@G$ZgJUU$8|1O1MCsVYr)yn8kmwC`6v8?LT|9|F zmq00(f|M-+FG24idIj5mX4!=uc4G$y9C!SGKZ+Cc{#J$xcYVizI33Cj%Xn>RIHuQZ z+lqXVY0cO<;OJ%#F!cTHq^hdtfTZ_QUFGzk$f?uXt6=?kxH}apK_3WPj|CsyZet-Kx@Ov$%`8%xAykVICfcrND ze^c-)G^{qozjObT-~aX~_`R0XH0SCx?=Z|?;{G+izc>;6F`89}Hkgm%XT8fHKYe@p|0{xj MNAP 224.0.0.2.646: + LDP, Label-Space-ID: 10.1.0.2:0, pdu-length: 38 + Hello Message (0x0100), length: 28, Message ID: 0x00011970, Flags: [ignore if unknown] + Common Hello Parameters TLV (0x0400), length: 4, Flags: [ignore and don't forward if unknown] + Hold Time: 15s, Flags: [Link Hello] + IPv4 Transport Address TLV (0x0401), length: 4, Flags: [ignore and don't forward if unknown] + IPv4 Transport Address: 10.1.0.2 + Configuration Sequence Number TLV (0x0402), length: 4, Flags: [ignore and don't forward if unknown] + Sequence Number: 1 diff --git a/tests/mpls-ldp-hello.puu b/tests/mpls-ldp-hello.puu new file mode 100644 index 0000000..b7f3b62 --- /dev/null +++ b/tests/mpls-ldp-hello.puu @@ -0,0 +1,6 @@ +begin 644 mpls-ldp-hello.pcap +MU,.RH0(`!````````````.H%```)````1UFZ/E2'#`!*````2@```/\#`"%% +MP`!&/-L```$1D08*`0$#X````@*&`H8`,M2>``$`)@H!``(```$``!P``1EP +8!```!``/```$`0`$"@$``@0"``0````! +` +end diff --git a/tests/mpls-traceroute.pcap b/tests/mpls-traceroute.pcap new file mode 100644 index 0000000000000000000000000000000000000000..ac0b6b3a1ed04f2c8ccce107310ca86bd91e9610 GIT binary patch literal 1956 zcmb`|%`XE%7zXfn_9Ia$vP!~*x==Sq5s^mXAQZ*LsYl=3NhJIcC8>{=G%At!IJ)Ad zBGIEbNgN!U5Jl^qw_3BivrP}%WYW%Io_T(|v)jz&c|rjVik}A^z=M;)m2~j-PJ=G| z%|~8U)|;Y?4FCj^!vM_qSoUg~=4Ff}hc;r+P)sO%^YuUX8XV)4kGu+PxHjdB1|iQv zXVp3|zP<+1w0Whu=3U&I`QbVORg7^X*&iM3A+j$C_HCK{A}g_PlKoV$t6V_#3Ub}k znv<;d&Tj|%2-z0}`;N>W&q?fCWIqw?O37Y9uDP*$Gpl_HbnBT{=>CiXD8~DOVBeM5 z`&8X_=AT=FkYlTXY7LaXGtWwP%*AJ^Y_5A+bCMsfp7@z>HVS8c&EsGnBm2By-;>#2 zYb5qovUdn}DnZv2bJ1Ql*WB2>nbqD?>tGL)eNM2)W%fj!#O^11`@j7r&jn=1T(pV+=ZQWwm{F1B3WB^q| 224.0.0.5: OSPFv2, LS-Update, length 152 + Router-ID 10.255.245.35, Backbone Area, Authentication Type: none (0), 1 LSA + LSA #1 + Advertising Router 10.255.245.37, seq 0x80000002, age 9s, length 104 + Area Local Opaque LSA (10), Opaque-Type Traffic Engineering LSA (1), Opaque-ID 8 + Options: [External] + Link TLV (2), length: 100 + Link Type subTLV (1), length: 1, Point-to-point (1) + Link ID subTLV (2), length: 4, 10.255.245.69 (0x0afff545) + Local Interface IP address subTLV (3), length: 4, 10.9.142.1 + Remote Interface IP address subTLV (4), length: 4, 10.9.142.2 + Traffic Engineering Metric subTLV (5), length: 4, Metric 63 + Maximum Bandwidth subTLV (6), length: 4, 622.080 Mbps + Maximum Reservable Bandwidth subTLV (7), length: 4, 622.080 Mbps + Unreserved Bandwidth subTLV (8), length: 32 + TE-Class 0: 622.080 Mbps + TE-Class 1: 622.080 Mbps + TE-Class 2: 622.080 Mbps + TE-Class 3: 622.080 Mbps + TE-Class 4: 622.080 Mbps + TE-Class 5: 622.080 Mbps + TE-Class 6: 622.080 Mbps + TE-Class 7: 622.080 Mbps + Administrative Group subTLV (9), length: 4, 0x00000000 +IP (tos 0xc0, ttl 1, id 4106, offset 0, flags [none], proto OSPF (89), length 172) + 40.35.1.2 > 224.0.0.5: OSPFv2, LS-Update, length 152 + Router-ID 10.255.245.35, Backbone Area, Authentication Type: none (0), 1 LSA + LSA #1 + Advertising Router 10.255.245.37, seq 0x80000002, age 9s, length 104 + Area Local Opaque LSA (10), Opaque-Type Traffic Engineering LSA (1), Opaque-ID 9 + Options: [External] + Link TLV (2), length: 100 + Link Type subTLV (1), length: 1, Point-to-point (1) + Link ID subTLV (2), length: 4, 10.255.245.69 (0x0afff545) + Local Interface IP address subTLV (3), length: 4, 10.9.143.1 + Remote Interface IP address subTLV (4), length: 4, 10.9.143.2 + Traffic Engineering Metric subTLV (5), length: 4, Metric 63 + Maximum Bandwidth subTLV (6), length: 4, 622.080 Mbps + Maximum Reservable Bandwidth subTLV (7), length: 4, 622.080 Mbps + Unreserved Bandwidth subTLV (8), length: 32 + TE-Class 0: 622.080 Mbps + TE-Class 1: 622.080 Mbps + TE-Class 2: 622.080 Mbps + TE-Class 3: 622.080 Mbps + TE-Class 4: 622.080 Mbps + TE-Class 5: 622.080 Mbps + TE-Class 6: 622.080 Mbps + TE-Class 7: 622.080 Mbps + Administrative Group subTLV (9), length: 4, 0x00000000 +IP (tos 0xc0, ttl 1, id 4160, offset 0, flags [none], proto OSPF (89), length 212) + 40.35.1.2 > 224.0.0.5: OSPFv2, LS-Update, length 192 + Router-ID 10.255.245.35, Backbone Area, Authentication Type: none (0), 1 LSA + LSA #1 + Advertising Router 10.255.245.35, seq 0x80000003, age 3s, length 144 + Area Local Opaque LSA (10), Opaque-Type Traffic Engineering LSA (1), Opaque-ID 3 + Options: [External] + Link TLV (2), length: 140 + Link Type subTLV (1), length: 1, Point-to-point (1) + Link ID subTLV (2), length: 4, 10.255.245.40 (0x0afff528) + Local Interface IP address subTLV (3), length: 4, 10.40.35.14 + Remote Interface IP address subTLV (4), length: 4, 10.40.35.13 + Traffic Engineering Metric subTLV (5), length: 4, Metric 1 + Maximum Bandwidth subTLV (6), length: 4, 100.000 Mbps + Maximum Reservable Bandwidth subTLV (7), length: 4, 100.000 Mbps + Unreserved Bandwidth subTLV (8), length: 32 + TE-Class 0: 0.000 Mbps + TE-Class 1: 0.000 Mbps + TE-Class 2: 0.000 Mbps + TE-Class 3: 0.000 Mbps + TE-Class 4: 0.000 Mbps + TE-Class 5: 0.000 Mbps + TE-Class 6: 0.000 Mbps + TE-Class 7: 0.000 Mbps + Interface Switching Capability subTLV (15), length: 44 + Interface Switching Capability: Packet-Switch Capable-1 + LSP Encoding: Ethernet V2/DIX + Max LSP Bandwidth: + priority level 0: 0.000 Mbps + priority level 1: 0.000 Mbps + priority level 2: 0.000 Mbps + priority level 3: 0.000 Mbps + priority level 4: 0.000 Mbps + priority level 5: 0.000 Mbps + priority level 6: 0.000 Mbps + priority level 7: 0.000 Mbps diff --git a/tests/ospf-gmpls.puu b/tests/ospf-gmpls.puu new file mode 100644 index 0000000..691e38e --- /dev/null +++ b/tests/ospf-gmpls.puu @@ -0,0 +1,18 @@ +begin 644 ospf-gmpls.pcap +MU,.RH0(`!````````````'81````````KME#X`?``"`&0``0`!`0`````"``0*__5%``,` +M!`H)C@$`!``$"@F.`@`%``0````_``8`!$R44,``!P`$3)10P``(`"!,E%#` +M3)10P$R44,!,E%#`3)10P$R44,!,E%#`3)10P``)``0`````Y-E 127.0.0.1.80: Flags [S], seq 928549246, win 32767, options [mss 16396,sackOK,TS val 1306300950 ecr 0,nop,wscale 2], length 0 +E..<.h@.@.!R.........p.P7X.~.........!....@.... +M........... +22:57:35.938122 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [S.], seq 930778609, ack 928549247, win 32767, options [mss 16396,sackOK,TS val 1306300950 ecr 1306300950,nop,wscale 2], length 0 +E..<..@.@.<..........P.p7z..7X......n.....@.... +M...M....... +22:57:35.938167 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 1, win 8192, options [nop,nop,TS val 1306300950 ecr 1306300950], length 0 +E..4.j@.@.!X.........p.P7X..7z.... .7...... +M...M... +22:57:35.939423 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [P.], seq 1:203, ack 1, win 8192, options [nop,nop,TS val 1306300951 ecr 1306300950], length 202 +E....l@.@. ..........p.P7X..7z.... ........ +M...M...GET / HTTP/1.1 +Host: localhost +User-Agent: ELinks/0.10.4-7-debian (textmode; Linux 2.6.11-1-686-smp i686; 132x56-2) +Accept: */* +Accept-Encoding: gzip +Accept-Language: en +Connection: Keep-Alive + + +22:57:35.940474 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [.], ack 203, win 8192, options [nop,nop,TS val 1306300952 ecr 1306300951], length 0 +E..4..@.@............P.p7z..7X.I.. .7...... +M...M... +22:57:35.941232 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [P.], seq 1:5560, ack 203, win 8192, options [nop,nop,TS val 1306300953 ecr 1306300951], length 5559 +E.....@.@..%.........P.p7z..7X.I.. ........ +M...M...HTTP/1.1 200 OK +Date: Wed, 06 Jul 2005 03:57:35 GMT +Server: Apache/1.3.33 +Last-Modified: Sun, 15 Aug 2004 00:43:41 GMT +ETag: "6e80f0-148a-411eb1bd" +Accept-Ranges: bytes +Content-Length: 5258 +Keep-Alive: timeout=15, max=100 +Connection: Keep-Alive +Content-Type: text/html; charset=iso-8859-1 + + + + + + + Placeholder page + + + +

Placeholder page

+

If you are just browsing the web

+ +

The owner of this web site has not put up any web pages yet. +Please come back later.

+ +

Move along, nothing to see here... :-)

+ +

If you are trying to locate the administrator of this machine

+ +

If you want to report something about this host's behavior, please +contact the Internet Service Provider (ISP) involved directly.

+ +

See the Network Abuse +Clearinghouse for how to do this.

+ +

If you are the administrator of this machine

+ +

The initial installation of Debian's +apache web server package was successful.

+ +

You should replace this page with your own web pages as +soon as possible.

+ +

Unless you changed its configuration, your new server is configured as follows: +

    +
  • +Configuration files can be found in /etc/apache.
  • + +
  • +The DocumentRoot, which is the directory under which all your +HTML files should exist, is set to /var/www.
  • + +
  • +CGI scripts are looked for in /usr/lib/cgi-bin, which is where +Debian packages will place their scripts.
  • + +
  • +Log files are placed in /var/log/apache, and will be rotated +weekly. The frequency of rotation can be easily changed by editing +/etc/logrotate.d/apache.
  • + +
  • +The default directory index is index.html, meaning that requests +for a directory /foo/bar/ will give the contents of the file /var/www/foo/bar/index.html +if it exists (assuming that /var/www is your DocumentRoot).
  • + +
  • +User directories are enabled, and user documents will be looked for +in the public_html directory of the users' homes. These dirs +should be under /home, and users will not be able to symlink +to files they don't own.
  • + +
+All the standard apache modules are available with this release and are +now managed with debconf. Type dpkg-reconfigure apache to +select which modules you want enabled. Many other modules are available +through the Debian package system with the names libapache-mod-*. +If you need to compile a module yourself, you will need to install the +apache-dev package. + +

More documentation on Apache can be found on: +

+ +

You can also consult the list of World +Wide Web Frequently Asked Questions for information. + +

Let other people know about this server

+ +Netcraft provides an interesting free +service for web site monitoring and statistic collection. +You can let them know about your server using their +interface. +Enabling the monitoring of your server will provide a better global overview +of who is using what and where, and it would give Debian a better +overview of the apache package usage. + +

About this page

+ + + +

This is a placeholder page installed by the Debian +release of the apache Web server package. + +

This computer has installed the Debian GNU/Linux operating system, +but it has nothing to do with the Debian +Project. Please do not contact the Debian +Project about it.

+ +

If you find a bug in this apache package, or in Apache itself, +please file a bug report on it. Instructions on doing this, and the +list of known bugs of this +package, can be found in the +Debian Bug Tracking System. + +

Thanks for using this package, and congratulations for your choice of +a Debian system!

+ +
+ +Debian + + +Apache + +
+ + + + + + +22:57:35.941260 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 5560, win 12383, options [nop,nop,TS val 1306300953 ecr 1306300953], length 0 +E..4.n@.@.!T.........p.P7X.I7z....0_....... +M...M... +22:57:37.229575 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [F.], seq 203, ack 5560, win 12383, options [nop,nop,TS val 1306302241 ecr 1306300953], length 0 +E..4.p@.@.!R.........p.P7X.I7z....0_....... +M..!M... +22:57:37.230839 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [F.], seq 5560, ack 204, win 8192, options [nop,nop,TS val 1306302243 ecr 1306302241], length 0 +E..4..@.@............P.p7z..7X.J.. ..5..... +M..#M..! +22:57:37.230900 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 5561, win 12383, options [nop,nop,TS val 1306302243 ecr 1306302243], length 0 +E..4.r@.@.!P.........p.P7X.J7z....0_....... +M..#M..# diff --git a/tests/print-AA.out b/tests/print-AA.out new file mode 100644 index 0000000..6a22df2 --- /dev/null +++ b/tests/print-AA.out @@ -0,0 +1,193 @@ +22:57:35.938066 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [S], seq 928549246, win 32767, options [mss 16396,sackOK,TS val 1306300950 ecr 0,nop,wscale 2], length 0 +..............E..<.h@.@.!R.........p.P7X.~.........!....@.... +M........... +22:57:35.938122 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [S.], seq 930778609, ack 928549247, win 32767, options [mss 16396,sackOK,TS val 1306300950 ecr 1306300950,nop,wscale 2], length 0 +..............E..<..@.@.<..........P.p7z..7X......n.....@.... +M...M....... +22:57:35.938167 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 1, win 8192, options [nop,nop,TS val 1306300950 ecr 1306300950], length 0 +..............E..4.j@.@.!X.........p.P7X..7z.... .7...... +M...M... +22:57:35.939423 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [P.], seq 1:203, ack 1, win 8192, options [nop,nop,TS val 1306300951 ecr 1306300950], length 202 +..............E....l@.@. ..........p.P7X..7z.... ........ +M...M...GET / HTTP/1.1 +Host: localhost +User-Agent: ELinks/0.10.4-7-debian (textmode; Linux 2.6.11-1-686-smp i686; 132x56-2) +Accept: */* +Accept-Encoding: gzip +Accept-Language: en +Connection: Keep-Alive + + +22:57:35.940474 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [.], ack 203, win 8192, options [nop,nop,TS val 1306300952 ecr 1306300951], length 0 +..............E..4..@.@............P.p7z..7X.I.. .7...... +M...M... +22:57:35.941232 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [P.], seq 1:5560, ack 203, win 8192, options [nop,nop,TS val 1306300953 ecr 1306300951], length 5559 +..............E.....@.@..%.........P.p7z..7X.I.. ........ +M...M...HTTP/1.1 200 OK +Date: Wed, 06 Jul 2005 03:57:35 GMT +Server: Apache/1.3.33 +Last-Modified: Sun, 15 Aug 2004 00:43:41 GMT +ETag: "6e80f0-148a-411eb1bd" +Accept-Ranges: bytes +Content-Length: 5258 +Keep-Alive: timeout=15, max=100 +Connection: Keep-Alive +Content-Type: text/html; charset=iso-8859-1 + + + + + + + Placeholder page + + + +

Placeholder page

+

If you are just browsing the web

+ +

The owner of this web site has not put up any web pages yet. +Please come back later.

+ +

Move along, nothing to see here... :-)

+ +

If you are trying to locate the administrator of this machine

+ +

If you want to report something about this host's behavior, please +contact the Internet Service Provider (ISP) involved directly.

+ +

See the Network Abuse +Clearinghouse for how to do this.

+ +

If you are the administrator of this machine

+ +

The initial installation of Debian's +apache web server package was successful.

+ +

You should replace this page with your own web pages as +soon as possible.

+ +

Unless you changed its configuration, your new server is configured as follows: +

    +
  • +Configuration files can be found in /etc/apache.
  • + +
  • +The DocumentRoot, which is the directory under which all your +HTML files should exist, is set to /var/www.
  • + +
  • +CGI scripts are looked for in /usr/lib/cgi-bin, which is where +Debian packages will place their scripts.
  • + +
  • +Log files are placed in /var/log/apache, and will be rotated +weekly. The frequency of rotation can be easily changed by editing +/etc/logrotate.d/apache.
  • + +
  • +The default directory index is index.html, meaning that requests +for a directory /foo/bar/ will give the contents of the file /var/www/foo/bar/index.html +if it exists (assuming that /var/www is your DocumentRoot).
  • + +
  • +User directories are enabled, and user documents will be looked for +in the public_html directory of the users' homes. These dirs +should be under /home, and users will not be able to symlink +to files they don't own.
  • + +
+All the standard apache modules are available with this release and are +now managed with debconf. Type dpkg-reconfigure apache to +select which modules you want enabled. Many other modules are available +through the Debian package system with the names libapache-mod-*. +If you need to compile a module yourself, you will need to install the +apache-dev package. + +

More documentation on Apache can be found on: +

+ +

You can also consult the list of World +Wide Web Frequently Asked Questions for information. + +

Let other people know about this server

+ +Netcraft provides an interesting free +service for web site monitoring and statistic collection. +You can let them know about your server using their +interface. +Enabling the monitoring of your server will provide a better global overview +of who is using what and where, and it would give Debian a better +overview of the apache package usage. + +

About this page

+ + + +

This is a placeholder page installed by the Debian +release of the apache Web server package. + +

This computer has installed the Debian GNU/Linux operating system, +but it has nothing to do with the Debian +Project. Please do not contact the Debian +Project about it.

+ +

If you find a bug in this apache package, or in Apache itself, +please file a bug report on it. Instructions on doing this, and the +list of known bugs of this +package, can be found in the +Debian Bug Tracking System. + +

Thanks for using this package, and congratulations for your choice of +a Debian system!

+ +
+ +Debian + + +Apache + +
+ + + + + + +22:57:35.941260 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 5560, win 12383, options [nop,nop,TS val 1306300953 ecr 1306300953], length 0 +..............E..4.n@.@.!T.........p.P7X.I7z....0_....... +M...M... +22:57:37.229575 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [F.], seq 203, ack 5560, win 12383, options [nop,nop,TS val 1306302241 ecr 1306300953], length 0 +..............E..4.p@.@.!R.........p.P7X.I7z....0_....... +M..!M... +22:57:37.230839 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [F.], seq 5560, ack 204, win 8192, options [nop,nop,TS val 1306302243 ecr 1306302241], length 0 +..............E..4..@.@............P.p7z..7X.J.. ..5..... +M..#M..! +22:57:37.230900 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 5561, win 12383, options [nop,nop,TS val 1306302243 ecr 1306302243], length 0 +..............E..4.r@.@.!P.........p.P7X.J7z....0_....... +M..#M..# diff --git a/tests/print-capX.out b/tests/print-capX.out new file mode 100644 index 0000000..f95a9e9 --- /dev/null +++ b/tests/print-capX.out @@ -0,0 +1,409 @@ +22:57:35.938066 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [S], seq 928549246, win 32767, options [mss 16396,sackOK,TS val 1306300950 ecr 0,nop,wscale 2], length 0 + 0x0000: 4500 003c 1b68 4000 4006 2152 7f00 0001 E..<.h@.@.!R.... + 0x0010: 7f00 0001 da70 0050 3758 897e 0000 0000 .....p.P7X.~.... + 0x0020: a002 7fff 1421 0000 0204 400c 0402 080a .....!....@..... + 0x0030: 4ddc 9216 0000 0000 0103 0302 M........... +22:57:35.938122 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [S.], seq 930778609, ack 928549247, win 32767, options [mss 16396,sackOK,TS val 1306300950 ecr 1306300950,nop,wscale 2], length 0 + 0x0000: 4500 003c 0000 4000 4006 3cba 7f00 0001 E..<..@.@.<..... + 0x0010: 7f00 0001 0050 da70 377a 8df1 3758 897f .....P.p7z..7X.. + 0x0020: a012 7fff 6eb1 0000 0204 400c 0402 080a ....n.....@..... + 0x0030: 4ddc 9216 4ddc 9216 0103 0302 M...M....... +22:57:35.938167 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 1, win 8192, options [nop,nop,TS val 1306300950 ecr 1306300950], length 0 + 0x0000: 4500 0034 1b6a 4000 4006 2158 7f00 0001 E..4.j@.@.!X.... + 0x0010: 7f00 0001 da70 0050 3758 897f 377a 8df2 .....p.P7X..7z.. + 0x0020: 8010 2000 37d0 0000 0101 080a 4ddc 9216 ....7.......M... + 0x0030: 4ddc 9216 M... +22:57:35.939423 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [P.], seq 1:203, ack 1, win 8192, options [nop,nop,TS val 1306300951 ecr 1306300950], length 202 + 0x0000: 4500 00fe 1b6c 4000 4006 208c 7f00 0001 E....l@.@....... + 0x0010: 7f00 0001 da70 0050 3758 897f 377a 8df2 .....p.P7X..7z.. + 0x0020: 8018 2000 fef2 0000 0101 080a 4ddc 9217 ............M... + 0x0030: 4ddc 9216 4745 5420 2f20 4854 5450 2f31 M...GET./.HTTP/1 + 0x0040: 2e31 0d0a 486f 7374 3a20 6c6f 6361 6c68 .1..Host:.localh + 0x0050: 6f73 740d 0a55 7365 722d 4167 656e 743a ost..User-Agent: + 0x0060: 2045 4c69 6e6b 732f 302e 3130 2e34 2d37 .ELinks/0.10.4-7 + 0x0070: 2d64 6562 6961 6e20 2874 6578 746d 6f64 -debian.(textmod + 0x0080: 653b 204c 696e 7578 2032 2e36 2e31 312d e;.Linux.2.6.11- + 0x0090: 312d 3638 362d 736d 7020 6936 3836 3b20 1-686-smp.i686;. + 0x00a0: 3133 3278 3536 2d32 290d 0a41 6363 6570 132x56-2)..Accep + 0x00b0: 743a 202a 2f2a 0d0a 4163 6365 7074 2d45 t:.*/*..Accept-E + 0x00c0: 6e63 6f64 696e 673a 2067 7a69 700d 0a41 ncoding:.gzip..A + 0x00d0: 6363 6570 742d 4c61 6e67 7561 6765 3a20 ccept-Language:. + 0x00e0: 656e 0d0a 436f 6e6e 6563 7469 6f6e 3a20 en..Connection:. + 0x00f0: 4b65 6570 2d41 6c69 7665 0d0a 0d0a Keep-Alive.... +22:57:35.940474 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [.], ack 203, win 8192, options [nop,nop,TS val 1306300952 ecr 1306300951], length 0 + 0x0000: 4500 0034 1fe4 4000 4006 1cde 7f00 0001 E..4..@.@....... + 0x0010: 7f00 0001 0050 da70 377a 8df2 3758 8a49 .....P.p7z..7X.I + 0x0020: 8010 2000 3703 0000 0101 080a 4ddc 9218 ....7.......M... + 0x0030: 4ddc 9217 M... +22:57:35.941232 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [P.], seq 1:5560, ack 203, win 8192, options [nop,nop,TS val 1306300953 ecr 1306300951], length 5559 + 0x0000: 4500 15eb 1fe6 4000 4006 0725 7f00 0001 E.....@.@..%.... + 0x0010: 7f00 0001 0050 da70 377a 8df2 3758 8a49 .....P.p7z..7X.I + 0x0020: 8018 2000 13e0 0000 0101 080a 4ddc 9219 ............M... + 0x0030: 4ddc 9217 4854 5450 2f31 2e31 2032 3030 M...HTTP/1.1.200 + 0x0040: 204f 4b0d 0a44 6174 653a 2057 6564 2c20 .OK..Date:.Wed,. + 0x0050: 3036 204a 756c 2032 3030 3520 3033 3a35 06.Jul.2005.03:5 + 0x0060: 373a 3335 2047 4d54 0d0a 5365 7276 6572 7:35.GMT..Server + 0x0070: 3a20 4170 6163 6865 2f31 2e33 2e33 330d :.Apache/1.3.33. + 0x0080: 0a4c 6173 742d 4d6f 6469 6669 6564 3a20 .Last-Modified:. + 0x0090: 5375 6e2c 2031 3520 4175 6720 3230 3034 Sun,.15.Aug.2004 + 0x00a0: 2030 303a 3433 3a34 3120 474d 540d 0a45 .00:43:41.GMT..E + 0x00b0: 5461 673a 2022 3665 3830 6630 2d31 3438 Tag:."6e80f0-148 + 0x00c0: 612d 3431 3165 6231 6264 220d 0a41 6363 a-411eb1bd"..Acc + 0x00d0: 6570 742d 5261 6e67 6573 3a20 6279 7465 ept-Ranges:.byte + 0x00e0: 730d 0a43 6f6e 7465 6e74 2d4c 656e 6774 s..Content-Lengt + 0x00f0: 683a 2035 3235 380d 0a4b 6565 702d 416c h:.5258..Keep-Al + 0x0100: 6976 653a 2074 696d 656f 7574 3d31 352c ive:.timeout=15, + 0x0110: 206d 6178 3d31 3030 0d0a 436f 6e6e 6563 .max=100..Connec + 0x0120: 7469 6f6e 3a20 4b65 6570 2d41 6c69 7665 tion:.Keep-Alive + 0x0130: 0d0a 436f 6e74 656e 742d 5479 7065 3a20 ..Content-Type:. + 0x0140: 7465 7874 2f68 746d 6c3b 2063 6861 7273 text/html;.chars + 0x0150: 6574 3d69 736f 2d38 3835 392d 310d 0a0d et=iso-8859-1... + 0x0160: 0a3c 2144 4f43 5459 5045 2048 544d 4c20 . + 0x01a0: 0a3c 4854 4d4c 3e0a 3c48 4541 443e 0a20 .... + 0x01b0: 2020 3c4d 4554 4120 4854 5450 2d45 5155 .......... + 0x0250: 3c54 4954 4c45 3e50 6c61 6365 686f 6c64 Placehold + 0x0260: 6572 2070 6167 653c 2f54 4954 4c45 3e0a er.page. + 0x0270: 3c2f 4845 4144 3e0a 3c42 4f44 5920 5445 ... + 0x02d0: 3c48 313e 506c 6163 6568 6f6c 6465 7220

Placeholder. + 0x02e0: 7061 6765 3c2f 4831 3e0a 3c48 323e 4966 page

.

If + 0x02f0: 2079 6f75 2061 7265 206a 7573 7420 6272 .you.are.just.br + 0x0300: 6f77 7369 6e67 2074 6865 2077 6562 3c2f owsing.the.web..

The.owne + 0x0320: 7220 6f66 2074 6869 7320 7765 6220 7369 r.of.this.web.si + 0x0330: 7465 2068 6173 206e 6f74 2070 7574 2075 te.has.not.put.u + 0x0340: 7020 616e 7920 7765 6220 7061 6765 7320 p.any.web.pages. + 0x0350: 7965 742e 0a50 6c65 6173 6520 636f 6d65 yet..Please.come + 0x0360: 2062 6163 6b20 6c61 7465 722e 3c2f 503e .back.later.

+ 0x0370: 0a0a 3c50 3e3c 534d 414c 4c3e 3c43 4954 ..

Move.along,.no + 0x0390: 7468 696e 6720 746f 2073 6565 2068 6572 thing.to.see.her + 0x03a0: 652e 2e2e 3c2f 4349 5445 3e20 3a2d 293c e....:-)< + 0x03b0: 2f53 4d41 4c4c 3e3c 2f50 3e0a 0a3c 4832 /SMALL>

..

If.you.are.tryi + 0x03d0: 6e67 2074 6f20 6c6f 6361 7465 2074 6865 ng.to.locate.the + 0x03e0: 2061 646d 696e 6973 7472 6174 6f72 206f .administrator.o + 0x03f0: 6620 7468 6973 206d 6163 6869 6e65 3c2f f.this.machine..

If.you.w + 0x0410: 616e 7420 746f 2072 6570 6f72 7420 736f ant.to.report.so + 0x0420: 6d65 7468 696e 6720 6162 6f75 7420 7468 mething.about.th + 0x0430: 6973 2068 6f73 7427 7320 6265 6861 7669 is.host's.behavi + 0x0440: 6f72 2c20 706c 6561 7365 0a63 6f6e 7461 or,.please.conta + 0x0450: 6374 2074 6865 2049 6e74 6572 6e65 7420 ct.the.Internet. + 0x0460: 5365 7276 6963 6520 5072 6f76 6964 6572 Service.Provider + 0x0470: 2028 4953 5029 2069 6e76 6f6c 7665 6420 .(ISP).involved. + 0x0480: 6469 7265 6374 6c79 2e3c 2f50 3e0a 0a3c directly.

..< + 0x0490: 503e 5365 6520 7468 6520 3c41 2068 7265 P>See.the.Networ + 0x04c0: 6b20 4162 7573 650a 436c 6561 7269 6e67 k.Abuse.Clearing + 0x04d0: 686f 7573 653c 2f41 3e20 666f 7220 686f house.for.ho + 0x04e0: 7720 746f 2064 6f20 7468 6973 2e3c 2f50 w.to.do.this.

..

If.you.ar + 0x0500: 6520 7468 6520 6164 6d69 6e69 7374 7261 e.the.administra + 0x0510: 746f 7220 6f66 2074 6869 7320 6d61 6368 tor.of.this.mach + 0x0520: 696e 653c 2f48 323e 0a0a 3c50 3e54 6865 ine

..

The + 0x0530: 2069 6e69 7469 616c 2069 6e73 7461 6c6c .initial.install + 0x0540: 6174 696f 6e20 6f66 203c 4120 6872 6566 ation.of.Debian + 0x0570: 2773 0a61 7061 6368 653c 2f41 3e20 7765 's.apache.we + 0x0580: 6220 7365 7276 6572 2070 6163 6b61 6765 b.server.package + 0x0590: 2077 6173 2073 7563 6365 7373 6675 6c2e .was.successful. + 0x05a0: 3c2f 503e 0a0a 3c50 3e3c 5354 524f 4e47

..

You.should.repl + 0x05c0: 6163 6520 7468 6973 2070 6167 6520 7769 ace.this.page.wi + 0x05d0: 7468 2079 6f75 7220 6f77 6e20 7765 6220 th.your.own.web. + 0x05e0: 7061 6765 7320 6173 0a73 6f6f 6e20 6173 pages.as.soon.as + 0x05f0: 2070 6f73 7369 626c 652e 3c2f 5354 524f .possible.

..

Unle + 0x0610: 7373 2079 6f75 2063 6861 6e67 6564 2069 ss.you.changed.i + 0x0620: 7473 2063 6f6e 6669 6775 7261 7469 6f6e ts.configuration + 0x0630: 2c20 796f 7572 206e 6577 2073 6572 7665 ,.your.new.serve + 0x0640: 7220 6973 2063 6f6e 6669 6775 7265 6420 r.is.configured. + 0x0650: 6173 2066 6f6c 6c6f 7773 3a0a 3c55 4c3e as.follows:.

    + 0x0660: 0a3c 4c49 3e0a 436f 6e66 6967 7572 6174 .
  • .Configurat + 0x0670: 696f 6e20 6669 6c65 7320 6361 6e20 6265 ion.files.can.be + 0x0680: 2066 6f75 6e64 2069 6e20 3c54 543e 2f65 .found.in./e + 0x0690: 7463 2f61 7061 6368 653c 2f54 543e 2e3c tc/apache.< + 0x06a0: 2f4c 493e 0a0a 3c4c 493e 0a54 6865 203c /LI>..
  • .The.< + 0x06b0: 5454 3e44 6f63 756d 656e 7452 6f6f 743c TT>DocumentRoot< + 0x06c0: 2f54 543e 2c20 7768 6963 6820 6973 2074 /TT>,.which.is.t + 0x06d0: 6865 2064 6972 6563 746f 7279 2075 6e64 he.directory.und + 0x06e0: 6572 2077 6869 6368 2061 6c6c 2079 6f75 er.which.all.you + 0x06f0: 720a 4854 4d4c 2066 696c 6573 2073 686f r.HTML.files.sho + 0x0700: 756c 6420 6578 6973 742c 2069 7320 7365 uld.exist,.is.se + 0x0710: 7420 746f 203c 5454 3e2f 7661 722f 7777 t.to./var/ww + 0x0720: 773c 2f54 543e 2e3c 2f4c 493e 0a0a 3c4c w.
  • ...CGI.scripts.a + 0x0740: 7265 206c 6f6f 6b65 6420 666f 7220 696e re.looked.for.in + 0x0750: 203c 5454 3e2f 7573 722f 6c69 622f 6367 ./usr/lib/cg + 0x0760: 692d 6269 6e3c 2f54 543e 2c20 7768 6963 i-bin,.whic + 0x0770: 6820 6973 2077 6865 7265 0a44 6562 6961 h.is.where.Debia + 0x0780: 6e20 7061 636b 6167 6573 2077 696c 6c20 n.packages.will. + 0x0790: 706c 6163 6520 7468 6569 7220 7363 7269 place.their.scri + 0x07a0: 7074 732e 3c2f 4c49 3e0a 0a3c 4c49 3e0a pts...
  • . + 0x07b0: 4c6f 6720 6669 6c65 7320 6172 6520 706c Log.files.are.pl + 0x07c0: 6163 6564 2069 6e20 3c54 543e 2f76 6172 aced.in./var + 0x07d0: 2f6c 6f67 2f61 7061 6368 653c 2f54 543e /log/apache + 0x07e0: 2c20 616e 6420 7769 6c6c 2062 6520 726f ,.and.will.be.ro + 0x07f0: 7461 7465 640a 7765 656b 6c79 2e20 2054 tated.weekly...T + 0x0800: 6865 2066 7265 7175 656e 6379 206f 6620 he.frequency.of. + 0x0810: 726f 7461 7469 6f6e 2063 616e 2062 6520 rotation.can.be. + 0x0820: 6561 7369 6c79 2063 6861 6e67 6564 2062 easily.changed.b + 0x0830: 7920 6564 6974 696e 670a 3c54 543e 2f65 y.editing./e + 0x0840: 7463 2f6c 6f67 726f 7461 7465 2e64 2f61 tc/logrotate.d/a + 0x0850: 7061 6368 653c 2f54 543e 2e3c 2f4c 493e pache.
  • + 0x0860: 0a0a 3c4c 493e 0a54 6865 2064 6566 6175 ..
  • .The.defau + 0x0870: 6c74 2064 6972 6563 746f 7279 2069 6e64 lt.directory.ind + 0x0880: 6578 2069 7320 3c54 543e 696e 6465 782e ex.is.index. + 0x0890: 6874 6d6c 3c2f 5454 3e2c 206d 6561 6e69 html,.meani + 0x08a0: 6e67 2074 6861 7420 7265 7175 6573 7473 ng.that.requests + 0x08b0: 0a66 6f72 2061 2064 6972 6563 746f 7279 .for.a.directory + 0x08c0: 203c 5454 3e2f 666f 6f2f 6261 722f 3c2f ./foo/bar/.will.give.th + 0x08e0: 6520 636f 6e74 656e 7473 206f 6620 7468 e.contents.of.th + 0x08f0: 6520 6669 6c65 203c 5454 3e2f 7661 722f e.file./var/ + 0x0900: 7777 772f 666f 6f2f 6261 722f 696e 6465 www/foo/bar/inde + 0x0910: 782e 6874 6d6c 3c2f 5454 3e0a 6966 2069 x.html.if.i + 0x0920: 7420 6578 6973 7473 2028 6173 7375 6d69 t.exists.(assumi + 0x0930: 6e67 2074 6861 7420 3c54 543e 2f76 6172 ng.that./var + 0x0940: 2f77 7777 3c2f 5454 3e20 6973 2079 6f75 /www.is.you + 0x0950: 7220 3c54 543e 446f 6375 6d65 6e74 526f r.DocumentRo + 0x0960: 6f74 3c2f 5454 3e29 2e3c 2f4c 493e 0a0a ot).
  • .. + 0x0970: 3c4c 493e 0a55 7365 7220 6469 7265 6374
  • .User.direct + 0x0980: 6f72 6965 7320 6172 6520 656e 6162 6c65 ories.are.enable + 0x0990: 642c 2061 6e64 2075 7365 7220 646f 6375 d,.and.user.docu + 0x09a0: 6d65 6e74 7320 7769 6c6c 2062 6520 6c6f ments.will.be.lo + 0x09b0: 6f6b 6564 2066 6f72 0a69 6e20 7468 6520 oked.for.in.the. + 0x09c0: 3c54 543e 7075 626c 6963 5f68 746d 6c3c public_html< + 0x09d0: 2f54 543e 2064 6972 6563 746f 7279 206f /TT>.directory.o + 0x09e0: 6620 7468 6520 7573 6572 7327 2068 6f6d f.the.users'.hom + 0x09f0: 6573 2e20 2054 6865 7365 2064 6972 730a es...These.dirs. + 0x0a00: 7368 6f75 6c64 2062 6520 756e 6465 7220 should.be.under. + 0x0a10: 3c54 543e 2f68 6f6d 653c 2f54 543e 2c20 /home,. + 0x0a20: 616e 6420 7573 6572 7320 7769 6c6c 206e and.users.will.n + 0x0a30: 6f74 2062 6520 6162 6c65 2074 6f20 7379 ot.be.able.to.sy + 0x0a40: 6d6c 696e 6b0a 746f 2066 696c 6573 2074 mlink.to.files.t + 0x0a50: 6865 7920 646f 6e27 7420 6f77 6e2e 3c2f hey.don't.own...
.All.t + 0x0a70: 6865 2073 7461 6e64 6172 6420 6170 6163 he.standard.apac + 0x0a80: 6865 206d 6f64 756c 6573 2061 7265 2061 he.modules.are.a + 0x0a90: 7661 696c 6162 6c65 2077 6974 6820 7468 vailable.with.th + 0x0aa0: 6973 2072 656c 6561 7365 2061 6e64 2061 is.release.and.a + 0x0ab0: 7265 0a6e 6f77 206d 616e 6167 6564 2077 re.now.managed.w + 0x0ac0: 6974 6820 6465 6263 6f6e 662e 2020 5479 ith.debconf...Ty + 0x0ad0: 7065 203c 5454 3e64 706b 672d 7265 636f pe.dpkg-reco + 0x0ae0: 6e66 6967 7572 6520 6170 6163 6865 3c2f nfigure.apache.to.select.wh + 0x0b00: 6963 6820 6d6f 6475 6c65 7320 796f 7520 ich.modules.you. + 0x0b10: 7761 6e74 2065 6e61 626c 6564 2e20 204d want.enabled...M + 0x0b20: 616e 7920 6f74 6865 7220 6d6f 6475 6c65 any.other.module + 0x0b30: 7320 6172 6520 6176 6169 6c61 626c 650a s.are.available. + 0x0b40: 7468 726f 7567 6820 7468 6520 4465 6269 through.the.Debi + 0x0b50: 616e 2070 6163 6b61 6765 2073 7973 7465 an.package.syste + 0x0b60: 6d20 7769 7468 2074 6865 206e 616d 6573 m.with.the.names + 0x0b70: 203c 5454 3e6c 6962 6170 6163 6865 2d6d .libapache-m + 0x0b80: 6f64 2d2a 3c2f 5454 3e2e 0a49 6620 796f od-*..If.yo + 0x0b90: 7520 6e65 6564 2074 6f20 636f 6d70 696c u.need.to.compil + 0x0ba0: 6520 6120 6d6f 6475 6c65 2079 6f75 7273 e.a.module.yours + 0x0bb0: 656c 662c 2079 6f75 2077 696c 6c20 6e65 elf,.you.will.ne + 0x0bc0: 6564 2074 6f20 696e 7374 616c 6c20 7468 ed.to.install.th + 0x0bd0: 650a 3c54 543e 6170 6163 6865 2d64 6576 e.apache-dev + 0x0be0: 3c2f 5454 3e20 7061 636b 6167 652e 0a0a .package... + 0x0bf0: 3c50 3e4d 6f72 6520 646f 6375 6d65 6e74

More.document + 0x0c00: 6174 696f 6e20 6f6e 2041 7061 6368 6520 ation.on.Apache. + 0x0c10: 6361 6e20 6265 2066 6f75 6e64 206f 6e3a can.be.found.on: + 0x0c20: 0a3c 554c 3e0a 3c4c 493e 0a54 6865 203c .

    .
  • .The.< + 0x0c30: 4120 4852 4546 3d22 2f64 6f63 2f61 7061 A.HREF="/doc/apa + 0x0c40: 6368 652d 646f 632f 6d61 6e75 616c 2f22 che-doc/manual/" + 0x0c50: 3e41 7061 6368 6520 646f 6375 6d65 6e74 >Apache.document + 0x0c60: 6174 696f 6e3c 2f41 3e20 7374 6f72 6564 ation.stored + 0x0c70: 206f 6e20 796f 7572 2073 6572 7665 722e .on.your.server. + 0x0c80: 3c2f 4c49 3e0a 0a3c 4c49 3e0a 5468 6520
  • ..
  • .The. + 0x0c90: 3c41 2048 5245 463d 2268 7474 703a 2f2f Apache.Project< + 0x0cc0: 2f41 3e20 686f 6d65 2073 6974 652e 3c2f /A>.home.site...
  • .The.Apache-SSL.home.site.
  • ..
  • .The.mo + 0x0d50: 6420 7065 726c 3c2f 413e 2068 6f6d 6520 d.perl.home. + 0x0d60: 7369 7465 2e3c 2f4c 493e 0a0a 3c4c 493e site.
  • ..
  • + 0x0d70: 0a54 6865 203c 4120 4852 4546 3d22 6874 .The.Apache + 0x0da0: 5765 656b 3c2f 413e 206e 6577 736c 6574 Week.newslet + 0x0db0: 7465 722e 3c2f 4c49 3e0a 0a3c 4c49 3e0a ter.
  • ..
  • . + 0x0dc0: 5468 6520 3c41 2048 5245 463d 2268 7474 The.Debian. + 0x0df0: 5072 6f6a 6563 740a 446f 6375 6d65 6e74 Project.Document + 0x0e00: 6174 696f 6e3c 2f41 3e20 7768 6963 6820 ation.which. + 0x0e10: 636f 6e74 6169 6e73 2048 4f57 544f 732c contains.HOWTOs, + 0x0e20: 2046 4151 732c 2061 6e64 2073 6f66 7477 .FAQs,.and.softw + 0x0e30: 6172 6520 7570 6461 7465 732e 3c2f 4c49 are.updates.
  • .
..

You. + 0x0e50: 6361 6e20 616c 736f 2063 6f6e 7375 6c74 can.also.consult + 0x0e60: 2074 6865 206c 6973 7420 6f66 203c 4120 .the.list.of.World.Wide.We + 0x0ea0: 6220 4672 6571 7565 6e74 6c79 2041 736b b.Frequently.Ask + 0x0eb0: 6564 2051 7565 7374 696f 6e73 3c2f 413e ed.Questions + 0x0ec0: 2066 6f72 2069 6e66 6f72 6d61 7469 6f6e .for.information + 0x0ed0: 2e0a 0a3c 4832 3e4c 6574 206f 7468 6572 ...

Let.other + 0x0ee0: 2070 656f 706c 6520 6b6e 6f77 2061 626f .people.know.abo + 0x0ef0: 7574 2074 6869 7320 7365 7276 6572 3c2f ut.this.server..Netcraft + 0x0f30: 2070 726f 7669 6465 7320 616e 2069 6e74 .provides.an.int + 0x0f40: 6572 6573 7469 6e67 2066 7265 650a 7365 eresting.free.se + 0x0f50: 7276 6963 6520 666f 7220 7765 6220 7369 rvice.for.web.si + 0x0f60: 7465 206d 6f6e 6974 6f72 696e 6720 616e te.monitoring.an + 0x0f70: 6420 7374 6174 6973 7469 6320 636f 6c6c d.statistic.coll + 0x0f80: 6563 7469 6f6e 2e0a 596f 7520 6361 6e20 ection..You.can. + 0x0f90: 6c65 7420 7468 656d 206b 6e6f 7720 6162 let.them.know.ab + 0x0fa0: 6f75 7420 796f 7572 2073 6572 7665 7220 out.your.server. + 0x0fb0: 7573 696e 6720 7468 6569 720a 3c41 2048 using.their.interface. + 0x0ff0: 0a45 6e61 626c 696e 6720 7468 6520 6d6f .Enabling.the.mo + 0x1000: 6e69 746f 7269 6e67 206f 6620 796f 7572 nitoring.of.your + 0x1010: 2073 6572 7665 7220 7769 6c6c 2070 726f .server.will.pro + 0x1020: 7669 6465 2061 2062 6574 7465 7220 676c vide.a.better.gl + 0x1030: 6f62 616c 206f 7665 7276 6965 770a 6f66 obal.overview.of + 0x1040: 2077 686f 2069 7320 7573 696e 6720 7768 .who.is.using.wh + 0x1050: 6174 2061 6e64 2077 6865 7265 2c20 616e at.and.where,.an + 0x1060: 6420 6974 2077 6f75 6c64 2067 6976 6520 d.it.would.give. + 0x1070: 4465 6269 616e 2061 2062 6574 7465 720a Debian.a.better. + 0x1080: 6f76 6572 7669 6577 206f 6620 7468 6520 overview.of.the. + 0x1090: 6170 6163 6865 2070 6163 6b61 6765 2075 apache.package.u + 0x10a0: 7361 6765 2e0a 0a3c 4832 3e41 626f 7574 sage...

About + 0x10b0: 2074 6869 7320 7061 6765 3c2f 4832 3e0a .this.page

. + 0x10c0: 0a3c 494d 4720 414c 4947 4e3d 2272 6967 ...

+ 0x1110: 5468 6973 2069 7320 6120 706c 6163 6568 This.is.a.placeh + 0x1120: 6f6c 6465 7220 7061 6765 2069 6e73 7461 older.page.insta + 0x1130: 6c6c 6564 2062 7920 7468 6520 3c41 0a48 lled.by.the.Deb + 0x1160: 6961 6e3c 2f41 3e0a 7265 6c65 6173 6520 ian.release. + 0x1170: 6f66 2074 6865 2061 7061 6368 6520 5765 of.the.apache.We + 0x1180: 6220 7365 7276 6572 2070 6163 6b61 6765 b.server.package + 0x1190: 2e0a 0a3c 503e 5468 6973 2063 6f6d 7075 ...

This.compu + 0x11a0: 7465 7220 6861 7320 696e 7374 616c 6c65 ter.has.installe + 0x11b0: 6420 7468 6520 4465 6269 616e 2047 4e55 d.the.Debian.GNU + 0x11c0: 2f4c 696e 7578 206f 7065 7261 7469 6e67 /Linux.operating + 0x11d0: 2073 7973 7465 6d2c 0a62 7574 2069 7420 .system,.but.it. + 0x11e0: 6861 7320 3c73 7472 6f6e 673e 6e6f 7468 has.noth + 0x11f0: 696e 6720 746f 2064 6f20 7769 7468 2074 ing.to.do.with.t + 0x1200: 6865 2044 6562 6961 6e0a 5072 6f6a 6563 he.Debian.Projec + 0x1210: 743c 2f73 7472 6f6e 673e 2e20 506c 6561 t..Plea + 0x1220: 7365 2064 6f20 3c73 7472 6f6e 673e 6e6f se.do.no + 0x1230: 743c 2f73 7472 6f6e 673e 2063 6f6e 7461 t.conta + 0x1240: 6374 2074 6865 2044 6562 6961 6e0a 5072 ct.the.Debian.Pr + 0x1250: 6f6a 6563 7420 6162 6f75 7420 6974 2e3c oject.about.it.< + 0x1260: 2f50 3e0a 0a3c 503e 4966 2079 6f75 2066 /P>..

If.you.f + 0x1270: 696e 6420 6120 6275 6720 696e 2074 6869 ind.a.bug.in.thi + 0x1280: 7320 6170 6163 6865 2070 6163 6b61 6765 s.apache.package + 0x1290: 2c20 6f72 2069 6e20 4170 6163 6865 2069 ,.or.in.Apache.i + 0x12a0: 7473 656c 662c 0a70 6c65 6173 6520 6669 tself,.please.fi + 0x12b0: 6c65 2061 2062 7567 2072 6570 6f72 7420 le.a.bug.report. + 0x12c0: 6f6e 2069 742e 2020 496e 7374 7275 6374 on.it...Instruct + 0x12d0: 696f 6e73 206f 6e20 646f 696e 6720 7468 ions.on.doing.th + 0x12e0: 6973 2c20 616e 6420 7468 650a 6c69 7374 is,.and.the.list + 0x12f0: 206f 6620 3c41 2048 5245 463d 2268 7474 .of. + 0x1320: 6b6e 6f77 6e20 6275 6773 3c2f 413e 206f known.bugs.o + 0x1330: 6620 7468 6973 0a70 6163 6b61 6765 2c20 f.this.package,. + 0x1340: 6361 6e20 6265 2066 6f75 6e64 2069 6e20 can.be.found.in. + 0x1350: 7468 6520 0a3c 4120 4852 4546 3d22 6874 the..Debian.Bug.T + 0x1390: 7261 636b 696e 6720 5379 7374 656d 3c2f racking.System...

Thanks.f + 0x13b0: 6f72 2075 7369 6e67 2074 6869 7320 7061 or.using.this.pa + 0x13c0: 636b 6167 652c 2061 6e64 2063 6f6e 6772 ckage,.and.congr + 0x13d0: 6174 756c 6174 696f 6e73 2066 6f72 2079 atulations.for.y + 0x13e0: 6f75 7220 6368 6f69 6365 206f 660a 6120 our.choice.of.a. + 0x13f0: 4465 6269 616e 2073 7973 7465 6d21 3c2f Debian.system!...........< + 0x1520: 212d 2d0a 2020 5468 6973 2070 6167 6520 !--...This.page. + 0x1530: 7761 7320 696e 6974 6961 6c6c 7920 6372 was.initially.cr + 0x1540: 6561 7465 6420 6279 204a 6f68 6e69 6520 eated.by.Johnie. + 0x1550: 496e 6772 616d 2028 6874 7470 3a2f 2f6e Ingram.(http://n + 0x1560: 6574 676f 642e 6e65 742f 290a 2020 4974 etgod.net/)...It + 0x1570: 2077 6173 206c 6174 6572 2065 6469 7465 .was.later.edite + 0x1580: 6420 6279 204d 6174 7468 6577 2057 696c d.by.Matthew.Wil + 0x1590: 636f 7820 616e 6420 4a6f 7369 7020 526f cox.and.Josip.Ro + 0x15a0: 6469 6e2e 0a20 204c 6173 7420 6d6f 6469 din....Last.modi + 0x15b0: 6669 6564 3a20 2444 6174 653a 2032 3030 fied:.$Date:.200 + 0x15c0: 342f 3036 2f32 3020 3135 3a33 333a 3537 4/06/20.15:33:57 + 0x15d0: 2024 2e0a 2020 2d2d 3e0a 0a3c 2f42 4f44 .$....-->.... +22:57:35.941260 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 5560, win 12383, options [nop,nop,TS val 1306300953 ecr 1306300953], length 0 + 0x0000: 4500 0034 1b6e 4000 4006 2154 7f00 0001 E..4.n@.@.!T.... + 0x0010: 7f00 0001 da70 0050 3758 8a49 377a a3a9 .....p.P7X.I7z.. + 0x0020: 8010 305f 10ea 0000 0101 080a 4ddc 9219 ..0_........M... + 0x0030: 4ddc 9219 M... +22:57:37.229575 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [F.], seq 203, ack 5560, win 12383, options [nop,nop,TS val 1306302241 ecr 1306300953], length 0 + 0x0000: 4500 0034 1b70 4000 4006 2152 7f00 0001 E..4.p@.@.!R.... + 0x0010: 7f00 0001 da70 0050 3758 8a49 377a a3a9 .....p.P7X.I7z.. + 0x0020: 8011 305f 0be1 0000 0101 080a 4ddc 9721 ..0_........M..! + 0x0030: 4ddc 9219 M... +22:57:37.230839 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [F.], seq 5560, ack 204, win 8192, options [nop,nop,TS val 1306302243 ecr 1306302241], length 0 + 0x0000: 4500 0034 1fe8 4000 4006 1cda 7f00 0001 E..4..@.@....... + 0x0010: 7f00 0001 0050 da70 377a a3a9 3758 8a4a .....P.p7z..7X.J + 0x0020: 8011 2000 1735 0000 0101 080a 4ddc 9723 .....5......M..# + 0x0030: 4ddc 9721 M..! +22:57:37.230900 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 5561, win 12383, options [nop,nop,TS val 1306302243 ecr 1306302243], length 0 + 0x0000: 4500 0034 1b72 4000 4006 2150 7f00 0001 E..4.r@.@.!P.... + 0x0010: 7f00 0001 da70 0050 3758 8a4a 377a a3aa .....p.P7X.J7z.. + 0x0020: 8010 305f 06d4 0000 0101 080a 4ddc 9723 ..0_........M..# + 0x0030: 4ddc 9723 M..# diff --git a/tests/print-capXX.out b/tests/print-capXX.out new file mode 100644 index 0000000..5062a85 --- /dev/null +++ b/tests/print-capXX.out @@ -0,0 +1,419 @@ +22:57:35.938066 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [S], seq 928549246, win 32767, options [mss 16396,sackOK,TS val 1306300950 ecr 0,nop,wscale 2], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. + 0x0010: 003c 1b68 4000 4006 2152 7f00 0001 7f00 .<.h@.@.!R...... + 0x0020: 0001 da70 0050 3758 897e 0000 0000 a002 ...p.P7X.~...... + 0x0030: 7fff 1421 0000 0204 400c 0402 080a 4ddc ...!....@.....M. + 0x0040: 9216 0000 0000 0103 0302 .......... +22:57:35.938122 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [S.], seq 930778609, ack 928549247, win 32767, options [mss 16396,sackOK,TS val 1306300950 ecr 1306300950,nop,wscale 2], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. + 0x0010: 003c 0000 4000 4006 3cba 7f00 0001 7f00 .<..@.@.<....... + 0x0020: 0001 0050 da70 377a 8df1 3758 897f a012 ...P.p7z..7X.... + 0x0030: 7fff 6eb1 0000 0204 400c 0402 080a 4ddc ..n.....@.....M. + 0x0040: 9216 4ddc 9216 0103 0302 ..M....... +22:57:35.938167 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 1, win 8192, options [nop,nop,TS val 1306300950 ecr 1306300950], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. + 0x0010: 0034 1b6a 4000 4006 2158 7f00 0001 7f00 .4.j@.@.!X...... + 0x0020: 0001 da70 0050 3758 897f 377a 8df2 8010 ...p.P7X..7z.... + 0x0030: 2000 37d0 0000 0101 080a 4ddc 9216 4ddc ..7.......M...M. + 0x0040: 9216 .. +22:57:35.939423 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [P.], seq 1:203, ack 1, win 8192, options [nop,nop,TS val 1306300951 ecr 1306300950], length 202 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. + 0x0010: 00fe 1b6c 4000 4006 208c 7f00 0001 7f00 ...l@.@......... + 0x0020: 0001 da70 0050 3758 897f 377a 8df2 8018 ...p.P7X..7z.... + 0x0030: 2000 fef2 0000 0101 080a 4ddc 9217 4ddc ..........M...M. + 0x0040: 9216 4745 5420 2f20 4854 5450 2f31 2e31 ..GET./.HTTP/1.1 + 0x0050: 0d0a 486f 7374 3a20 6c6f 6361 6c68 6f73 ..Host:.localhos + 0x0060: 740d 0a55 7365 722d 4167 656e 743a 2045 t..User-Agent:.E + 0x0070: 4c69 6e6b 732f 302e 3130 2e34 2d37 2d64 Links/0.10.4-7-d + 0x0080: 6562 6961 6e20 2874 6578 746d 6f64 653b ebian.(textmode; + 0x0090: 204c 696e 7578 2032 2e36 2e31 312d 312d .Linux.2.6.11-1- + 0x00a0: 3638 362d 736d 7020 6936 3836 3b20 3133 686-smp.i686;.13 + 0x00b0: 3278 3536 2d32 290d 0a41 6363 6570 743a 2x56-2)..Accept: + 0x00c0: 202a 2f2a 0d0a 4163 6365 7074 2d45 6e63 .*/*..Accept-Enc + 0x00d0: 6f64 696e 673a 2067 7a69 700d 0a41 6363 oding:.gzip..Acc + 0x00e0: 6570 742d 4c61 6e67 7561 6765 3a20 656e ept-Language:.en + 0x00f0: 0d0a 436f 6e6e 6563 7469 6f6e 3a20 4b65 ..Connection:.Ke + 0x0100: 6570 2d41 6c69 7665 0d0a 0d0a ep-Alive.... +22:57:35.940474 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [.], ack 203, win 8192, options [nop,nop,TS val 1306300952 ecr 1306300951], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. + 0x0010: 0034 1fe4 4000 4006 1cde 7f00 0001 7f00 .4..@.@......... + 0x0020: 0001 0050 da70 377a 8df2 3758 8a49 8010 ...P.p7z..7X.I.. + 0x0030: 2000 3703 0000 0101 080a 4ddc 9218 4ddc ..7.......M...M. + 0x0040: 9217 .. +22:57:35.941232 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [P.], seq 1:5560, ack 203, win 8192, options [nop,nop,TS val 1306300953 ecr 1306300951], length 5559 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. + 0x0010: 15eb 1fe6 4000 4006 0725 7f00 0001 7f00 ....@.@..%...... + 0x0020: 0001 0050 da70 377a 8df2 3758 8a49 8018 ...P.p7z..7X.I.. + 0x0030: 2000 13e0 0000 0101 080a 4ddc 9219 4ddc ..........M...M. + 0x0040: 9217 4854 5450 2f31 2e31 2032 3030 204f ..HTTP/1.1.200.O + 0x0050: 4b0d 0a44 6174 653a 2057 6564 2c20 3036 K..Date:.Wed,.06 + 0x0060: 204a 756c 2032 3030 3520 3033 3a35 373a .Jul.2005.03:57: + 0x0070: 3335 2047 4d54 0d0a 5365 7276 6572 3a20 35.GMT..Server:. + 0x0080: 4170 6163 6865 2f31 2e33 2e33 330d 0a4c Apache/1.3.33..L + 0x0090: 6173 742d 4d6f 6469 6669 6564 3a20 5375 ast-Modified:.Su + 0x00a0: 6e2c 2031 3520 4175 6720 3230 3034 2030 n,.15.Aug.2004.0 + 0x00b0: 303a 3433 3a34 3120 474d 540d 0a45 5461 0:43:41.GMT..ETa + 0x00c0: 673a 2022 3665 3830 6630 2d31 3438 612d g:."6e80f0-148a- + 0x00d0: 3431 3165 6231 6264 220d 0a41 6363 6570 411eb1bd"..Accep + 0x00e0: 742d 5261 6e67 6573 3a20 6279 7465 730d t-Ranges:.bytes. + 0x00f0: 0a43 6f6e 7465 6e74 2d4c 656e 6774 683a .Content-Length: + 0x0100: 2035 3235 380d 0a4b 6565 702d 416c 6976 .5258..Keep-Aliv + 0x0110: 653a 2074 696d 656f 7574 3d31 352c 206d e:.timeout=15,.m + 0x0120: 6178 3d31 3030 0d0a 436f 6e6e 6563 7469 ax=100..Connecti + 0x0130: 6f6e 3a20 4b65 6570 2d41 6c69 7665 0d0a on:.Keep-Alive.. + 0x0140: 436f 6e74 656e 742d 5479 7065 3a20 7465 Content-Type:.te + 0x0150: 7874 2f68 746d 6c3b 2063 6861 7273 6574 xt/html;.charset + 0x0160: 3d69 736f 2d38 3835 392d 310d 0a0d 0a3c =iso-8859-1....< + 0x0170: 2144 4f43 5459 5045 2048 544d 4c20 5055 !DOCTYPE.HTML.PU + 0x0180: 424c 4943 2022 2d2f 2f57 3343 2f2f 4454 BLIC."-//W3C//DT + 0x0190: 4420 4854 4d4c 2034 2e30 3120 5472 616e D.HTML.4.01.Tran + 0x01a0: 7369 7469 6f6e 616c 2f2f 454e 223e 0a3c sitional//EN">.< + 0x01b0: 4854 4d4c 3e0a 3c48 4541 443e 0a20 2020 HTML>..... + 0x01c0: 3c4d 4554 4120 4854 5450 2d45 5155 4956 ........Placeholder + 0x0270: 2070 6167 653c 2f54 4954 4c45 3e0a 3c2f .page....Placeholder.pa + 0x02f0: 6765 3c2f 4831 3e0a 3c48 323e 4966 2079 ge

.

If.y + 0x0300: 6f75 2061 7265 206a 7573 7420 6272 6f77 ou.are.just.brow + 0x0310: 7369 6e67 2074 6865 2077 6562 3c2f 6832 sing.the.web

..

The.owner. + 0x0330: 6f66 2074 6869 7320 7765 6220 7369 7465 of.this.web.site + 0x0340: 2068 6173 206e 6f74 2070 7574 2075 7020 .has.not.put.up. + 0x0350: 616e 7920 7765 6220 7061 6765 7320 7965 any.web.pages.ye + 0x0360: 742e 0a50 6c65 6173 6520 636f 6d65 2062 t..Please.come.b + 0x0370: 6163 6b20 6c61 7465 722e 3c2f 503e 0a0a ack.later.

.. + 0x0380: 3c50 3e3c 534d 414c 4c3e 3c43 4954 453e

+ 0x0390: 4d6f 7665 2061 6c6f 6e67 2c20 6e6f 7468 Move.along,.noth + 0x03a0: 696e 6720 746f 2073 6565 2068 6572 652e ing.to.see.here. + 0x03b0: 2e2e 3c2f 4349 5445 3e20 3a2d 293c 2f53 ...:-)

..

I + 0x03d0: 6620 796f 7520 6172 6520 7472 7969 6e67 f.you.are.trying + 0x03e0: 2074 6f20 6c6f 6361 7465 2074 6865 2061 .to.locate.the.a + 0x03f0: 646d 696e 6973 7472 6174 6f72 206f 6620 dministrator.of. + 0x0400: 7468 6973 206d 6163 6869 6e65 3c2f 4832 this.machine

..

If.you.wan + 0x0420: 7420 746f 2072 6570 6f72 7420 736f 6d65 t.to.report.some + 0x0430: 7468 696e 6720 6162 6f75 7420 7468 6973 thing.about.this + 0x0440: 2068 6f73 7427 7320 6265 6861 7669 6f72 .host's.behavior + 0x0450: 2c20 706c 6561 7365 0a63 6f6e 7461 6374 ,.please.contact + 0x0460: 2074 6865 2049 6e74 6572 6e65 7420 5365 .the.Internet.Se + 0x0470: 7276 6963 6520 5072 6f76 6964 6572 2028 rvice.Provider.( + 0x0480: 4953 5029 2069 6e76 6f6c 7665 6420 6469 ISP).involved.di + 0x0490: 7265 6374 6c79 2e3c 2f50 3e0a 0a3c 503e rectly.

..

+ 0x04a0: 5365 6520 7468 6520 3c41 2068 7265 663d See.the.Network. + 0x04d0: 4162 7573 650a 436c 6561 7269 6e67 686f Abuse.Clearingho + 0x04e0: 7573 653c 2f41 3e20 666f 7220 686f 7720 use.for.how. + 0x04f0: 746f 2064 6f20 7468 6973 2e3c 2f50 3e0a to.do.this.

. + 0x0500: 0a3c 4832 3e49 6620 796f 7520 6172 6520 .

If.you.are. + 0x0510: 7468 6520 6164 6d69 6e69 7374 7261 746f the.administrato + 0x0520: 7220 6f66 2074 6869 7320 6d61 6368 696e r.of.this.machin + 0x0530: 653c 2f48 323e 0a0a 3c50 3e54 6865 2069 e

..

The.i + 0x0540: 6e69 7469 616c 2069 6e73 7461 6c6c 6174 nitial.installat + 0x0550: 696f 6e20 6f66 203c 4120 6872 6566 3d22 ion.of.Debian's + 0x0580: 0a61 7061 6368 653c 2f41 3e20 7765 6220 .apache.web. + 0x0590: 7365 7276 6572 2070 6163 6b61 6765 2077 server.package.w + 0x05a0: 6173 2073 7563 6365 7373 6675 6c2e 3c2f as.successful...

Y + 0x05c0: 6f75 2073 686f 756c 6420 7265 706c 6163 ou.should.replac + 0x05d0: 6520 7468 6973 2070 6167 6520 7769 7468 e.this.page.with + 0x05e0: 2079 6f75 7220 6f77 6e20 7765 6220 7061 .your.own.web.pa + 0x05f0: 6765 7320 6173 0a73 6f6f 6e20 6173 2070 ges.as.soon.as.p + 0x0600: 6f73 7369 626c 652e 3c2f 5354 524f 4e47 ossible.

..

Unless + 0x0620: 2079 6f75 2063 6861 6e67 6564 2069 7473 .you.changed.its + 0x0630: 2063 6f6e 6669 6775 7261 7469 6f6e 2c20 .configuration,. + 0x0640: 796f 7572 206e 6577 2073 6572 7665 7220 your.new.server. + 0x0650: 6973 2063 6f6e 6669 6775 7265 6420 6173 is.configured.as + 0x0660: 2066 6f6c 6c6f 7773 3a0a 3c55 4c3e 0a3c .follows:.

    .< + 0x0670: 4c49 3e0a 436f 6e66 6967 7572 6174 696f LI>.Configuratio + 0x0680: 6e20 6669 6c65 7320 6361 6e20 6265 2066 n.files.can.be.f + 0x0690: 6f75 6e64 2069 6e20 3c54 543e 2f65 7463 ound.in./etc + 0x06a0: 2f61 7061 6368 653c 2f54 543e 2e3c 2f4c /apache...
  • .The.DocumentRoot,.which.is.the + 0x06e0: 2064 6972 6563 746f 7279 2075 6e64 6572 .directory.under + 0x06f0: 2077 6869 6368 2061 6c6c 2079 6f75 720a .which.all.your. + 0x0700: 4854 4d4c 2066 696c 6573 2073 686f 756c HTML.files.shoul + 0x0710: 6420 6578 6973 742c 2069 7320 7365 7420 d.exist,.is.set. + 0x0720: 746f 203c 5454 3e2f 7661 722f 7777 773c to./var/www< + 0x0730: 2f54 543e 2e3c 2f4c 493e 0a0a 3c4c 493e /TT>.
  • ..
  • + 0x0740: 0a43 4749 2073 6372 6970 7473 2061 7265 .CGI.scripts.are + 0x0750: 206c 6f6f 6b65 6420 666f 7220 696e 203c .looked.for.in.< + 0x0760: 5454 3e2f 7573 722f 6c69 622f 6367 692d TT>/usr/lib/cgi- + 0x0770: 6269 6e3c 2f54 543e 2c20 7768 6963 6820 bin,.which. + 0x0780: 6973 2077 6865 7265 0a44 6562 6961 6e20 is.where.Debian. + 0x0790: 7061 636b 6167 6573 2077 696c 6c20 706c packages.will.pl + 0x07a0: 6163 6520 7468 6569 7220 7363 7269 7074 ace.their.script + 0x07b0: 732e 3c2f 4c49 3e0a 0a3c 4c49 3e0a 4c6f s.
  • ..
  • .Lo + 0x07c0: 6720 6669 6c65 7320 6172 6520 706c 6163 g.files.are.plac + 0x07d0: 6564 2069 6e20 3c54 543e 2f76 6172 2f6c ed.in./var/l + 0x07e0: 6f67 2f61 7061 6368 653c 2f54 543e 2c20 og/apache,. + 0x07f0: 616e 6420 7769 6c6c 2062 6520 726f 7461 and.will.be.rota + 0x0800: 7465 640a 7765 656b 6c79 2e20 2054 6865 ted.weekly...The + 0x0810: 2066 7265 7175 656e 6379 206f 6620 726f .frequency.of.ro + 0x0820: 7461 7469 6f6e 2063 616e 2062 6520 6561 tation.can.be.ea + 0x0830: 7369 6c79 2063 6861 6e67 6564 2062 7920 sily.changed.by. + 0x0840: 6564 6974 696e 670a 3c54 543e 2f65 7463 editing./etc + 0x0850: 2f6c 6f67 726f 7461 7465 2e64 2f61 7061 /logrotate.d/apa + 0x0860: 6368 653c 2f54 543e 2e3c 2f4c 493e 0a0a che.
  • .. + 0x0870: 3c4c 493e 0a54 6865 2064 6566 6175 6c74
  • .The.default + 0x0880: 2064 6972 6563 746f 7279 2069 6e64 6578 .directory.index + 0x0890: 2069 7320 3c54 543e 696e 6465 782e 6874 .is.index.ht + 0x08a0: 6d6c 3c2f 5454 3e2c 206d 6561 6e69 6e67 ml,.meaning + 0x08b0: 2074 6861 7420 7265 7175 6573 7473 0a66 .that.requests.f + 0x08c0: 6f72 2061 2064 6972 6563 746f 7279 203c or.a.directory.< + 0x08d0: 5454 3e2f 666f 6f2f 6261 722f 3c2f 5454 TT>/foo/bar/.will.give.the. + 0x08f0: 636f 6e74 656e 7473 206f 6620 7468 6520 contents.of.the. + 0x0900: 6669 6c65 203c 5454 3e2f 7661 722f 7777 file./var/ww + 0x0910: 772f 666f 6f2f 6261 722f 696e 6465 782e w/foo/bar/index. + 0x0920: 6874 6d6c 3c2f 5454 3e0a 6966 2069 7420 html.if.it. + 0x0930: 6578 6973 7473 2028 6173 7375 6d69 6e67 exists.(assuming + 0x0940: 2074 6861 7420 3c54 543e 2f76 6172 2f77 .that./var/w + 0x0950: 7777 3c2f 5454 3e20 6973 2079 6f75 7220 ww.is.your. + 0x0960: 3c54 543e 446f 6375 6d65 6e74 526f 6f74 DocumentRoot + 0x0970: 3c2f 5454 3e29 2e3c 2f4c 493e 0a0a 3c4c ).
  • ...User.director + 0x0990: 6965 7320 6172 6520 656e 6162 6c65 642c ies.are.enabled, + 0x09a0: 2061 6e64 2075 7365 7220 646f 6375 6d65 .and.user.docume + 0x09b0: 6e74 7320 7769 6c6c 2062 6520 6c6f 6f6b nts.will.be.look + 0x09c0: 6564 2066 6f72 0a69 6e20 7468 6520 3c54 ed.for.in.the.public_html.directory.of. + 0x09f0: 7468 6520 7573 6572 7327 2068 6f6d 6573 the.users'.homes + 0x0a00: 2e20 2054 6865 7365 2064 6972 730a 7368 ...These.dirs.sh + 0x0a10: 6f75 6c64 2062 6520 756e 6465 7220 3c54 ould.be.under./home
    ,.an + 0x0a30: 6420 7573 6572 7320 7769 6c6c 206e 6f74 d.users.will.not + 0x0a40: 2062 6520 6162 6c65 2074 6f20 7379 6d6c .be.able.to.syml + 0x0a50: 696e 6b0a 746f 2066 696c 6573 2074 6865 ink.to.files.the + 0x0a60: 7920 646f 6e27 7420 6f77 6e2e 3c2f 4c49 y.don't.own...
.All.the + 0x0a80: 2073 7461 6e64 6172 6420 6170 6163 6865 .standard.apache + 0x0a90: 206d 6f64 756c 6573 2061 7265 2061 7661 .modules.are.ava + 0x0aa0: 696c 6162 6c65 2077 6974 6820 7468 6973 ilable.with.this + 0x0ab0: 2072 656c 6561 7365 2061 6e64 2061 7265 .release.and.are + 0x0ac0: 0a6e 6f77 206d 616e 6167 6564 2077 6974 .now.managed.wit + 0x0ad0: 6820 6465 6263 6f6e 662e 2020 5479 7065 h.debconf...Type + 0x0ae0: 203c 5454 3e64 706b 672d 7265 636f 6e66 .dpkg-reconf + 0x0af0: 6967 7572 6520 6170 6163 6865 3c2f 5454 igure.apache.to.select.whic + 0x0b10: 6820 6d6f 6475 6c65 7320 796f 7520 7761 h.modules.you.wa + 0x0b20: 6e74 2065 6e61 626c 6564 2e20 204d 616e nt.enabled...Man + 0x0b30: 7920 6f74 6865 7220 6d6f 6475 6c65 7320 y.other.modules. + 0x0b40: 6172 6520 6176 6169 6c61 626c 650a 7468 are.available.th + 0x0b50: 726f 7567 6820 7468 6520 4465 6269 616e rough.the.Debian + 0x0b60: 2070 6163 6b61 6765 2073 7973 7465 6d20 .package.system. + 0x0b70: 7769 7468 2074 6865 206e 616d 6573 203c with.the.names.< + 0x0b80: 5454 3e6c 6962 6170 6163 6865 2d6d 6f64 TT>libapache-mod + 0x0b90: 2d2a 3c2f 5454 3e2e 0a49 6620 796f 7520 -*..If.you. + 0x0ba0: 6e65 6564 2074 6f20 636f 6d70 696c 6520 need.to.compile. + 0x0bb0: 6120 6d6f 6475 6c65 2079 6f75 7273 656c a.module.yoursel + 0x0bc0: 662c 2079 6f75 2077 696c 6c20 6e65 6564 f,.you.will.need + 0x0bd0: 2074 6f20 696e 7374 616c 6c20 7468 650a .to.install.the. + 0x0be0: 3c54 543e 6170 6163 6865 2d64 6576 3c2f apache-dev.package...

More.documentat + 0x0c10: 696f 6e20 6f6e 2041 7061 6368 6520 6361 ion.on.Apache.ca + 0x0c20: 6e20 6265 2066 6f75 6e64 206f 6e3a 0a3c n.be.found.on:.< + 0x0c30: 554c 3e0a 3c4c 493e 0a54 6865 203c 4120 UL>.

  • .The.A + 0x0c60: 7061 6368 6520 646f 6375 6d65 6e74 6174 pache.documentat + 0x0c70: 696f 6e3c 2f41 3e20 7374 6f72 6564 206f ion.stored.o + 0x0c80: 6e20 796f 7572 2073 6572 7665 722e 3c2f n.your.server...
  • .The.A + 0x0cc0: 7061 6368 6520 5072 6f6a 6563 743c 2f41 pache.Project.home.site.
  • ..
  • .The.Apache-SSL. + 0x0d20: 686f 6d65 2073 6974 652e 3c2f 4c49 3e0a home.site.
  • . + 0x0d30: 0a3c 4c49 3e0a 5468 6520 3c41 2048 5245 .
  • .The.mod. + 0x0d60: 7065 726c 3c2f 413e 2068 6f6d 6520 7369 perl.home.si + 0x0d70: 7465 2e3c 2f4c 493e 0a0a 3c4c 493e 0a54 te.
  • ..
  • .T + 0x0d80: 6865 203c 4120 4852 4546 3d22 6874 7470 he.ApacheWe + 0x0db0: 656b 3c2f 413e 206e 6577 736c 6574 7465 ek.newslette + 0x0dc0: 722e 3c2f 4c49 3e0a 0a3c 4c49 3e0a 5468 r.
  • ..
  • .Th + 0x0dd0: 6520 3c41 2048 5245 463d 2268 7474 703a e.Debian.Pr + 0x0e00: 6f6a 6563 740a 446f 6375 6d65 6e74 6174 oject.Documentat + 0x0e10: 696f 6e3c 2f41 3e20 7768 6963 6820 636f ion.which.co + 0x0e20: 6e74 6169 6e73 2048 4f57 544f 732c 2046 ntains.HOWTOs,.F + 0x0e30: 4151 732c 2061 6e64 2073 6f66 7477 6172 AQs,.and.softwar + 0x0e40: 6520 7570 6461 7465 732e 3c2f 4c49 3e0a e.updates.
  • . + 0x0e50: 3c2f 554c 3e0a 0a3c 503e 596f 7520 6361 ..

    You.ca + 0x0e60: 6e20 616c 736f 2063 6f6e 7375 6c74 2074 n.also.consult.t + 0x0e70: 6865 206c 6973 7420 6f66 203c 4120 4852 he.list.of.World.Wide.Web. + 0x0eb0: 4672 6571 7565 6e74 6c79 2041 736b 6564 Frequently.Asked + 0x0ec0: 2051 7565 7374 696f 6e73 3c2f 413e 2066 .Questions.f + 0x0ed0: 6f72 2069 6e66 6f72 6d61 7469 6f6e 2e0a or.information.. + 0x0ee0: 0a3c 4832 3e4c 6574 206f 7468 6572 2070 .

    Let.other.p + 0x0ef0: 656f 706c 6520 6b6e 6f77 2061 626f 7574 eople.know.about + 0x0f00: 2074 6869 7320 7365 7276 6572 3c2f 4832 .this.server

    ..Netcraft.p + 0x0f40: 726f 7669 6465 7320 616e 2069 6e74 6572 rovides.an.inter + 0x0f50: 6573 7469 6e67 2066 7265 650a 7365 7276 esting.free.serv + 0x0f60: 6963 6520 666f 7220 7765 6220 7369 7465 ice.for.web.site + 0x0f70: 206d 6f6e 6974 6f72 696e 6720 616e 6420 .monitoring.and. + 0x0f80: 7374 6174 6973 7469 6320 636f 6c6c 6563 statistic.collec + 0x0f90: 7469 6f6e 2e0a 596f 7520 6361 6e20 6c65 tion..You.can.le + 0x0fa0: 7420 7468 656d 206b 6e6f 7720 6162 6f75 t.them.know.abou + 0x0fb0: 7420 796f 7572 2073 6572 7665 7220 7573 t.your.server.us + 0x0fc0: 696e 6720 7468 6569 720a 3c41 2048 5245 ing.their. + 0x0ff0: 696e 7465 7266 6163 653c 2f41 3e2e 0a45 interface..E + 0x1000: 6e61 626c 696e 6720 7468 6520 6d6f 6e69 nabling.the.moni + 0x1010: 746f 7269 6e67 206f 6620 796f 7572 2073 toring.of.your.s + 0x1020: 6572 7665 7220 7769 6c6c 2070 726f 7669 erver.will.provi + 0x1030: 6465 2061 2062 6574 7465 7220 676c 6f62 de.a.better.glob + 0x1040: 616c 206f 7665 7276 6965 770a 6f66 2077 al.overview.of.w + 0x1050: 686f 2069 7320 7573 696e 6720 7768 6174 ho.is.using.what + 0x1060: 2061 6e64 2077 6865 7265 2c20 616e 6420 .and.where,.and. + 0x1070: 6974 2077 6f75 6c64 2067 6976 6520 4465 it.would.give.De + 0x1080: 6269 616e 2061 2062 6574 7465 720a 6f76 bian.a.better.ov + 0x1090: 6572 7669 6577 206f 6620 7468 6520 6170 erview.of.the.ap + 0x10a0: 6163 6865 2070 6163 6b61 6765 2075 7361 ache.package.usa + 0x10b0: 6765 2e0a 0a3c 4832 3e41 626f 7574 2074 ge...

    About.t + 0x10c0: 6869 7320 7061 6765 3c2f 4832 3e0a 0a3c his.page

    ..< + 0x10d0: 494d 4720 414c 4947 4e3d 2272 6967 6874 IMG.ALIGN="right + 0x10e0: 2220 414c 543d 2222 2048 4549 4748 543d ".ALT="".HEIGHT= + 0x10f0: 2232 3437 2220 5749 4454 483d 2232 3738 "247".WIDTH="278 + 0x1100: 2220 5352 433d 2269 636f 6e73 2f6a 6865 ".SRC="icons/jhe + 0x1110: 3036 312e 706e 6722 3e0a 0a3c 503e 5468 061.png">..

    Th + 0x1120: 6973 2069 7320 6120 706c 6163 6568 6f6c is.is.a.placehol + 0x1130: 6465 7220 7061 6765 2069 6e73 7461 6c6c der.page.install + 0x1140: 6564 2062 7920 7468 6520 3c41 0a48 5245 ed.by.the.Debia + 0x1170: 6e3c 2f41 3e0a 7265 6c65 6173 6520 6f66 n.release.of + 0x1180: 2074 6865 2061 7061 6368 6520 5765 6220 .the.apache.Web. + 0x1190: 7365 7276 6572 2070 6163 6b61 6765 2e0a server.package.. + 0x11a0: 0a3c 503e 5468 6973 2063 6f6d 7075 7465 .

    This.compute + 0x11b0: 7220 6861 7320 696e 7374 616c 6c65 6420 r.has.installed. + 0x11c0: 7468 6520 4465 6269 616e 2047 4e55 2f4c the.Debian.GNU/L + 0x11d0: 696e 7578 206f 7065 7261 7469 6e67 2073 inux.operating.s + 0x11e0: 7973 7465 6d2c 0a62 7574 2069 7420 6861 ystem,.but.it.ha + 0x11f0: 7320 3c73 7472 6f6e 673e 6e6f 7468 696e s.nothin + 0x1200: 6720 746f 2064 6f20 7769 7468 2074 6865 g.to.do.with.the + 0x1210: 2044 6562 6961 6e0a 5072 6f6a 6563 743c .Debian.Project< + 0x1220: 2f73 7472 6f6e 673e 2e20 506c 6561 7365 /strong>..Please + 0x1230: 2064 6f20 3c73 7472 6f6e 673e 6e6f 743c .do.not< + 0x1240: 2f73 7472 6f6e 673e 2063 6f6e 7461 6374 /strong>.contact + 0x1250: 2074 6865 2044 6562 6961 6e0a 5072 6f6a .the.Debian.Proj + 0x1260: 6563 7420 6162 6f75 7420 6974 2e3c 2f50 ect.about.it.

    ..

    If.you.fin + 0x1280: 6420 6120 6275 6720 696e 2074 6869 7320 d.a.bug.in.this. + 0x1290: 6170 6163 6865 2070 6163 6b61 6765 2c20 apache.package,. + 0x12a0: 6f72 2069 6e20 4170 6163 6865 2069 7473 or.in.Apache.its + 0x12b0: 656c 662c 0a70 6c65 6173 6520 6669 6c65 elf,.please.file + 0x12c0: 2061 2062 7567 2072 6570 6f72 7420 6f6e .a.bug.report.on + 0x12d0: 2069 742e 2020 496e 7374 7275 6374 696f .it...Instructio + 0x12e0: 6e73 206f 6e20 646f 696e 6720 7468 6973 ns.on.doing.this + 0x12f0: 2c20 616e 6420 7468 650a 6c69 7374 206f ,.and.the.list.o + 0x1300: 6620 3c41 2048 5245 463d 2268 7474 703a f.kn + 0x1330: 6f77 6e20 6275 6773 3c2f 413e 206f 6620 own.bugs.of. + 0x1340: 7468 6973 0a70 6163 6b61 6765 2c20 6361 this.package,.ca + 0x1350: 6e20 6265 2066 6f75 6e64 2069 6e20 7468 n.be.found.in.th + 0x1360: 6520 0a3c 4120 4852 4546 3d22 6874 7470 e..Debian.Bug.Tra + 0x13a0: 636b 696e 6720 5379 7374 656d 3c2f 413e cking.System + 0x13b0: 2e0a 0a3c 503e 5468 616e 6b73 2066 6f72 ...

    Thanks.for + 0x13c0: 2075 7369 6e67 2074 6869 7320 7061 636b .using.this.pack + 0x13d0: 6167 652c 2061 6e64 2063 6f6e 6772 6174 age,.and.congrat + 0x13e0: 756c 6174 696f 6e73 2066 6f72 2079 6f75 ulations.for.you + 0x13f0: 7220 6368 6f69 6365 206f 660a 6120 4465 r.choice.of.a.De + 0x1400: 6269 616e 2073 7973 7465 6d21 3c2f 503e bian.system!

    + 0x1410: 0a0a 3c44 4956 2061 6c69 676e 3d22 6365 ........ + 0x1520: 3c2f 613e 0a3c 2f44 4956 3e0a 0a3c 212d ..... + 0x15f0: 0a3c 2f48 544d 4c3e 0a .. +22:57:35.941260 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 5560, win 12383, options [nop,nop,TS val 1306300953 ecr 1306300953], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. + 0x0010: 0034 1b6e 4000 4006 2154 7f00 0001 7f00 .4.n@.@.!T...... + 0x0020: 0001 da70 0050 3758 8a49 377a a3a9 8010 ...p.P7X.I7z.... + 0x0030: 305f 10ea 0000 0101 080a 4ddc 9219 4ddc 0_........M...M. + 0x0040: 9219 .. +22:57:37.229575 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [F.], seq 203, ack 5560, win 12383, options [nop,nop,TS val 1306302241 ecr 1306300953], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. + 0x0010: 0034 1b70 4000 4006 2152 7f00 0001 7f00 .4.p@.@.!R...... + 0x0020: 0001 da70 0050 3758 8a49 377a a3a9 8011 ...p.P7X.I7z.... + 0x0030: 305f 0be1 0000 0101 080a 4ddc 9721 4ddc 0_........M..!M. + 0x0040: 9219 .. +22:57:37.230839 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [F.], seq 5560, ack 204, win 8192, options [nop,nop,TS val 1306302243 ecr 1306302241], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. + 0x0010: 0034 1fe8 4000 4006 1cda 7f00 0001 7f00 .4..@.@......... + 0x0020: 0001 0050 da70 377a a3a9 3758 8a4a 8011 ...P.p7z..7X.J.. + 0x0030: 2000 1735 0000 0101 080a 4ddc 9723 4ddc ...5......M..#M. + 0x0040: 9721 .! +22:57:37.230900 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 5561, win 12383, options [nop,nop,TS val 1306302243 ecr 1306302243], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 ..............E. + 0x0010: 0034 1b72 4000 4006 2150 7f00 0001 7f00 .4.r@.@.!P...... + 0x0020: 0001 da70 0050 3758 8a4a 377a a3aa 8010 ...p.P7X.J7z.... + 0x0030: 305f 06d4 0000 0101 080a 4ddc 9723 4ddc 0_........M..#M. + 0x0040: 9723 .# diff --git a/tests/print-flags.puu b/tests/print-flags.puu new file mode 100644 index 0000000..bcd8b99 --- /dev/null +++ b/tests/print-flags.puu @@ -0,0 +1,151 @@ +begin 644 print-flags.pcap +MU,.RH0(`!````````````/__```!````KU;+0E)0#@!*````2@`````````` +M``````````@`10``/!MH0`!`!B%2?P```7\```':<`!0-UB)?@````"@`G__ +M%"$```($0`P$`@@*3=R2%@`````!`P,"KU;+0HI0#@!*````2@`````````` +M``````````@`10``/```0`!`!CRZ?P```7\```$`4-IP-WJ-\3=8B7^@$G__ +M;K$```($0`P$`@@*3=R2%DWHWR@!@@`/[R```!`0@* +M3=R2%TW?P```7\```$`4-IP-WJ-\C=8 +MBDF`$"``-P,```$!"`I-W)(83=R2%Z]6RT*P7`X`^14``/D5```````````` +M```````(`$4`%>L?YD``0`8')7\```%_```!`%#:<#=ZC?(W6(I)@!@@`!/@ +M```!`0@*3=R2&4W71E#TQ,#`-"D-O;FYE8W1I;VXZ($ME97`M06QI=F4-"D-O +M;G1E;G0M5'EP93H@=&5X="]H=&UL.R!C:&%R7!E(B!#3TY414Y4/2)T97AT+VAT;6P[(&-H +M87)S970]:7-O+3@X-3DM,2(^"B`@(#Q-151!($Y!344](D1E2!W96(@<&%G97,@ +M>65T+@I0;&5A6EN9R!T;R!L +M;V-A=&4@=&AE(&%D;6EN:7-T6]U(&%R92!T:&4@861M:6YI2!E9&ET:6YG"CQ4 +M5#XO971C+VQO9W)O=&%T92YD+V%P86-H93PO5%0^+CPO3$D^"@H\3$D^"E1H +M92!D969A=6QT(&1I2!I;F1E>"!I6]U2!O9B!T:&4@=7-E6]U('=A;G0@96YA8FQE9"X@($UA;GD@;W1H97(@;6]D=6QE6]U6]U2!T:&4@/$$*2%)%1CTB:'1T<#HO+W=W=RYD96)I86XN;W)G+R(^1&5B +M:6%N/"]!/@IR96QE87-E(&]F('1H92!A<&%C:&4@5V5B('-E7-T96TL"F)U="!I="!H87,@/'-T +M6]U +M(&9I;F0@82!B=6<@:6X@=&AI6]U2!*;VAN:64@26YG2!-871T:&5W(%=I;&-O>"!A;F0@ +M2F]S:7`@4F]D:6XN"B`@3&%S="!M;V1I9FEE9#H@)$1A=&4Z(#(P,#0O,#8O +M,C`@,34Z,S,Z-3<@)"X*("`M+3X*"CPO0D]$63X*/"](5$U,/@JO5LM"S%P. +M`$(```!"````````````````````"`!%```T&VY``$`&(51_```!?P```=IP +M`%`W6(I)-WJCJ8`0,%\0Z@```0$("DW``P!"````0@`` +M``````````````````@`10``-!MP0`!`!B%2?P```7\```':<`!0-UB*23=Z +MHZF`$3!?"^$```$!"`I-W)DIFF/print-$i.out.diff ) + then + echo print-$i passed. + else + echo print-$i failed. + fi +done diff --git a/tests/print-x.out b/tests/print-x.out new file mode 100644 index 0000000..7794223 --- /dev/null +++ b/tests/print-x.out @@ -0,0 +1,409 @@ +22:57:35.938066 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [S], seq 928549246, win 32767, options [mss 16396,sackOK,TS val 1306300950 ecr 0,nop,wscale 2], length 0 + 0x0000: 4500 003c 1b68 4000 4006 2152 7f00 0001 + 0x0010: 7f00 0001 da70 0050 3758 897e 0000 0000 + 0x0020: a002 7fff 1421 0000 0204 400c 0402 080a + 0x0030: 4ddc 9216 0000 0000 0103 0302 +22:57:35.938122 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [S.], seq 930778609, ack 928549247, win 32767, options [mss 16396,sackOK,TS val 1306300950 ecr 1306300950,nop,wscale 2], length 0 + 0x0000: 4500 003c 0000 4000 4006 3cba 7f00 0001 + 0x0010: 7f00 0001 0050 da70 377a 8df1 3758 897f + 0x0020: a012 7fff 6eb1 0000 0204 400c 0402 080a + 0x0030: 4ddc 9216 4ddc 9216 0103 0302 +22:57:35.938167 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 1, win 8192, options [nop,nop,TS val 1306300950 ecr 1306300950], length 0 + 0x0000: 4500 0034 1b6a 4000 4006 2158 7f00 0001 + 0x0010: 7f00 0001 da70 0050 3758 897f 377a 8df2 + 0x0020: 8010 2000 37d0 0000 0101 080a 4ddc 9216 + 0x0030: 4ddc 9216 +22:57:35.939423 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [P.], seq 1:203, ack 1, win 8192, options [nop,nop,TS val 1306300951 ecr 1306300950], length 202 + 0x0000: 4500 00fe 1b6c 4000 4006 208c 7f00 0001 + 0x0010: 7f00 0001 da70 0050 3758 897f 377a 8df2 + 0x0020: 8018 2000 fef2 0000 0101 080a 4ddc 9217 + 0x0030: 4ddc 9216 4745 5420 2f20 4854 5450 2f31 + 0x0040: 2e31 0d0a 486f 7374 3a20 6c6f 6361 6c68 + 0x0050: 6f73 740d 0a55 7365 722d 4167 656e 743a + 0x0060: 2045 4c69 6e6b 732f 302e 3130 2e34 2d37 + 0x0070: 2d64 6562 6961 6e20 2874 6578 746d 6f64 + 0x0080: 653b 204c 696e 7578 2032 2e36 2e31 312d + 0x0090: 312d 3638 362d 736d 7020 6936 3836 3b20 + 0x00a0: 3133 3278 3536 2d32 290d 0a41 6363 6570 + 0x00b0: 743a 202a 2f2a 0d0a 4163 6365 7074 2d45 + 0x00c0: 6e63 6f64 696e 673a 2067 7a69 700d 0a41 + 0x00d0: 6363 6570 742d 4c61 6e67 7561 6765 3a20 + 0x00e0: 656e 0d0a 436f 6e6e 6563 7469 6f6e 3a20 + 0x00f0: 4b65 6570 2d41 6c69 7665 0d0a 0d0a +22:57:35.940474 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [.], ack 203, win 8192, options [nop,nop,TS val 1306300952 ecr 1306300951], length 0 + 0x0000: 4500 0034 1fe4 4000 4006 1cde 7f00 0001 + 0x0010: 7f00 0001 0050 da70 377a 8df2 3758 8a49 + 0x0020: 8010 2000 3703 0000 0101 080a 4ddc 9218 + 0x0030: 4ddc 9217 +22:57:35.941232 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [P.], seq 1:5560, ack 203, win 8192, options [nop,nop,TS val 1306300953 ecr 1306300951], length 5559 + 0x0000: 4500 15eb 1fe6 4000 4006 0725 7f00 0001 + 0x0010: 7f00 0001 0050 da70 377a 8df2 3758 8a49 + 0x0020: 8018 2000 13e0 0000 0101 080a 4ddc 9219 + 0x0030: 4ddc 9217 4854 5450 2f31 2e31 2032 3030 + 0x0040: 204f 4b0d 0a44 6174 653a 2057 6564 2c20 + 0x0050: 3036 204a 756c 2032 3030 3520 3033 3a35 + 0x0060: 373a 3335 2047 4d54 0d0a 5365 7276 6572 + 0x0070: 3a20 4170 6163 6865 2f31 2e33 2e33 330d + 0x0080: 0a4c 6173 742d 4d6f 6469 6669 6564 3a20 + 0x0090: 5375 6e2c 2031 3520 4175 6720 3230 3034 + 0x00a0: 2030 303a 3433 3a34 3120 474d 540d 0a45 + 0x00b0: 5461 673a 2022 3665 3830 6630 2d31 3438 + 0x00c0: 612d 3431 3165 6231 6264 220d 0a41 6363 + 0x00d0: 6570 742d 5261 6e67 6573 3a20 6279 7465 + 0x00e0: 730d 0a43 6f6e 7465 6e74 2d4c 656e 6774 + 0x00f0: 683a 2035 3235 380d 0a4b 6565 702d 416c + 0x0100: 6976 653a 2074 696d 656f 7574 3d31 352c + 0x0110: 206d 6178 3d31 3030 0d0a 436f 6e6e 6563 + 0x0120: 7469 6f6e 3a20 4b65 6570 2d41 6c69 7665 + 0x0130: 0d0a 436f 6e74 656e 742d 5479 7065 3a20 + 0x0140: 7465 7874 2f68 746d 6c3b 2063 6861 7273 + 0x0150: 6574 3d69 736f 2d38 3835 392d 310d 0a0d + 0x0160: 0a3c 2144 4f43 5459 5045 2048 544d 4c20 + 0x0170: 5055 424c 4943 2022 2d2f 2f57 3343 2f2f + 0x0180: 4454 4420 4854 4d4c 2034 2e30 3120 5472 + 0x0190: 616e 7369 7469 6f6e 616c 2f2f 454e 223e + 0x01a0: 0a3c 4854 4d4c 3e0a 3c48 4541 443e 0a20 + 0x01b0: 2020 3c4d 4554 4120 4854 5450 2d45 5155 + 0x01c0: 4956 3d22 436f 6e74 656e 742d 5479 7065 + 0x01d0: 2220 434f 4e54 454e 543d 2274 6578 742f + 0x01e0: 6874 6d6c 3b20 6368 6172 7365 743d 6973 + 0x01f0: 6f2d 3838 3539 2d31 223e 0a20 2020 3c4d + 0x0200: 4554 4120 4e41 4d45 3d22 4465 7363 7269 + 0x0210: 7074 696f 6e22 2043 4f4e 5445 4e54 3d22 + 0x0220: 5468 6520 696e 6974 6961 6c20 696e 7374 + 0x0230: 616c 6c61 7469 6f6e 206f 6620 4465 6269 + 0x0240: 616e 2061 7061 6368 652e 223e 0a20 2020 + 0x0250: 3c54 4954 4c45 3e50 6c61 6365 686f 6c64 + 0x0260: 6572 2070 6167 653c 2f54 4954 4c45 3e0a + 0x0270: 3c2f 4845 4144 3e0a 3c42 4f44 5920 5445 + 0x0280: 5854 3d22 2330 3030 3030 3022 2042 4743 + 0x0290: 4f4c 4f52 3d22 2346 4646 4646 4622 204c + 0x02a0: 494e 4b3d 2223 3030 3030 4546 2220 564c + 0x02b0: 494e 4b3d 2223 3535 3138 3841 2220 414c + 0x02c0: 494e 4b3d 2223 4646 3030 3030 223e 0a0a + 0x02d0: 3c48 313e 506c 6163 6568 6f6c 6465 7220 + 0x02e0: 7061 6765 3c2f 4831 3e0a 3c48 323e 4966 + 0x02f0: 2079 6f75 2061 7265 206a 7573 7420 6272 + 0x0300: 6f77 7369 6e67 2074 6865 2077 6562 3c2f + 0x0310: 6832 3e0a 0a3c 503e 5468 6520 6f77 6e65 + 0x0320: 7220 6f66 2074 6869 7320 7765 6220 7369 + 0x0330: 7465 2068 6173 206e 6f74 2070 7574 2075 + 0x0340: 7020 616e 7920 7765 6220 7061 6765 7320 + 0x0350: 7965 742e 0a50 6c65 6173 6520 636f 6d65 + 0x0360: 2062 6163 6b20 6c61 7465 722e 3c2f 503e + 0x0370: 0a0a 3c50 3e3c 534d 414c 4c3e 3c43 4954 + 0x0380: 453e 4d6f 7665 2061 6c6f 6e67 2c20 6e6f + 0x0390: 7468 696e 6720 746f 2073 6565 2068 6572 + 0x03a0: 652e 2e2e 3c2f 4349 5445 3e20 3a2d 293c + 0x03b0: 2f53 4d41 4c4c 3e3c 2f50 3e0a 0a3c 4832 + 0x03c0: 3e49 6620 796f 7520 6172 6520 7472 7969 + 0x03d0: 6e67 2074 6f20 6c6f 6361 7465 2074 6865 + 0x03e0: 2061 646d 696e 6973 7472 6174 6f72 206f + 0x03f0: 6620 7468 6973 206d 6163 6869 6e65 3c2f + 0x0400: 4832 3e0a 0a3c 503e 4966 2079 6f75 2077 + 0x0410: 616e 7420 746f 2072 6570 6f72 7420 736f + 0x0420: 6d65 7468 696e 6720 6162 6f75 7420 7468 + 0x0430: 6973 2068 6f73 7427 7320 6265 6861 7669 + 0x0440: 6f72 2c20 706c 6561 7365 0a63 6f6e 7461 + 0x0450: 6374 2074 6865 2049 6e74 6572 6e65 7420 + 0x0460: 5365 7276 6963 6520 5072 6f76 6964 6572 + 0x0470: 2028 4953 5029 2069 6e76 6f6c 7665 6420 + 0x0480: 6469 7265 6374 6c79 2e3c 2f50 3e0a 0a3c + 0x0490: 503e 5365 6520 7468 6520 3c41 2068 7265 + 0x04a0: 663d 2268 7474 703a 2f2f 7777 772e 6162 + 0x04b0: 7573 652e 6e65 742f 223e 4e65 7477 6f72 + 0x04c0: 6b20 4162 7573 650a 436c 6561 7269 6e67 + 0x04d0: 686f 7573 653c 2f41 3e20 666f 7220 686f + 0x04e0: 7720 746f 2064 6f20 7468 6973 2e3c 2f50 + 0x04f0: 3e0a 0a3c 4832 3e49 6620 796f 7520 6172 + 0x0500: 6520 7468 6520 6164 6d69 6e69 7374 7261 + 0x0510: 746f 7220 6f66 2074 6869 7320 6d61 6368 + 0x0520: 696e 653c 2f48 323e 0a0a 3c50 3e54 6865 + 0x0530: 2069 6e69 7469 616c 2069 6e73 7461 6c6c + 0x0540: 6174 696f 6e20 6f66 203c 4120 6872 6566 + 0x0550: 3d22 6874 7470 3a2f 2f77 7777 2e64 6562 + 0x0560: 6961 6e2e 6f72 672f 223e 4465 6269 616e + 0x0570: 2773 0a61 7061 6368 653c 2f41 3e20 7765 + 0x0580: 6220 7365 7276 6572 2070 6163 6b61 6765 + 0x0590: 2077 6173 2073 7563 6365 7373 6675 6c2e + 0x05a0: 3c2f 503e 0a0a 3c50 3e3c 5354 524f 4e47 + 0x05b0: 3e59 6f75 2073 686f 756c 6420 7265 706c + 0x05c0: 6163 6520 7468 6973 2070 6167 6520 7769 + 0x05d0: 7468 2079 6f75 7220 6f77 6e20 7765 6220 + 0x05e0: 7061 6765 7320 6173 0a73 6f6f 6e20 6173 + 0x05f0: 2070 6f73 7369 626c 652e 3c2f 5354 524f + 0x0600: 4e47 3e3c 2f50 3e0a 0a3c 503e 556e 6c65 + 0x0610: 7373 2079 6f75 2063 6861 6e67 6564 2069 + 0x0620: 7473 2063 6f6e 6669 6775 7261 7469 6f6e + 0x0630: 2c20 796f 7572 206e 6577 2073 6572 7665 + 0x0640: 7220 6973 2063 6f6e 6669 6775 7265 6420 + 0x0650: 6173 2066 6f6c 6c6f 7773 3a0a 3c55 4c3e + 0x0660: 0a3c 4c49 3e0a 436f 6e66 6967 7572 6174 + 0x0670: 696f 6e20 6669 6c65 7320 6361 6e20 6265 + 0x0680: 2066 6f75 6e64 2069 6e20 3c54 543e 2f65 + 0x0690: 7463 2f61 7061 6368 653c 2f54 543e 2e3c + 0x06a0: 2f4c 493e 0a0a 3c4c 493e 0a54 6865 203c + 0x06b0: 5454 3e44 6f63 756d 656e 7452 6f6f 743c + 0x06c0: 2f54 543e 2c20 7768 6963 6820 6973 2074 + 0x06d0: 6865 2064 6972 6563 746f 7279 2075 6e64 + 0x06e0: 6572 2077 6869 6368 2061 6c6c 2079 6f75 + 0x06f0: 720a 4854 4d4c 2066 696c 6573 2073 686f + 0x0700: 756c 6420 6578 6973 742c 2069 7320 7365 + 0x0710: 7420 746f 203c 5454 3e2f 7661 722f 7777 + 0x0720: 773c 2f54 543e 2e3c 2f4c 493e 0a0a 3c4c + 0x0730: 493e 0a43 4749 2073 6372 6970 7473 2061 + 0x0740: 7265 206c 6f6f 6b65 6420 666f 7220 696e + 0x0750: 203c 5454 3e2f 7573 722f 6c69 622f 6367 + 0x0760: 692d 6269 6e3c 2f54 543e 2c20 7768 6963 + 0x0770: 6820 6973 2077 6865 7265 0a44 6562 6961 + 0x0780: 6e20 7061 636b 6167 6573 2077 696c 6c20 + 0x0790: 706c 6163 6520 7468 6569 7220 7363 7269 + 0x07a0: 7074 732e 3c2f 4c49 3e0a 0a3c 4c49 3e0a + 0x07b0: 4c6f 6720 6669 6c65 7320 6172 6520 706c + 0x07c0: 6163 6564 2069 6e20 3c54 543e 2f76 6172 + 0x07d0: 2f6c 6f67 2f61 7061 6368 653c 2f54 543e + 0x07e0: 2c20 616e 6420 7769 6c6c 2062 6520 726f + 0x07f0: 7461 7465 640a 7765 656b 6c79 2e20 2054 + 0x0800: 6865 2066 7265 7175 656e 6379 206f 6620 + 0x0810: 726f 7461 7469 6f6e 2063 616e 2062 6520 + 0x0820: 6561 7369 6c79 2063 6861 6e67 6564 2062 + 0x0830: 7920 6564 6974 696e 670a 3c54 543e 2f65 + 0x0840: 7463 2f6c 6f67 726f 7461 7465 2e64 2f61 + 0x0850: 7061 6368 653c 2f54 543e 2e3c 2f4c 493e + 0x0860: 0a0a 3c4c 493e 0a54 6865 2064 6566 6175 + 0x0870: 6c74 2064 6972 6563 746f 7279 2069 6e64 + 0x0880: 6578 2069 7320 3c54 543e 696e 6465 782e + 0x0890: 6874 6d6c 3c2f 5454 3e2c 206d 6561 6e69 + 0x08a0: 6e67 2074 6861 7420 7265 7175 6573 7473 + 0x08b0: 0a66 6f72 2061 2064 6972 6563 746f 7279 + 0x08c0: 203c 5454 3e2f 666f 6f2f 6261 722f 3c2f + 0x08d0: 5454 3e20 7769 6c6c 2067 6976 6520 7468 + 0x08e0: 6520 636f 6e74 656e 7473 206f 6620 7468 + 0x08f0: 6520 6669 6c65 203c 5454 3e2f 7661 722f + 0x0900: 7777 772f 666f 6f2f 6261 722f 696e 6465 + 0x0910: 782e 6874 6d6c 3c2f 5454 3e0a 6966 2069 + 0x0920: 7420 6578 6973 7473 2028 6173 7375 6d69 + 0x0930: 6e67 2074 6861 7420 3c54 543e 2f76 6172 + 0x0940: 2f77 7777 3c2f 5454 3e20 6973 2079 6f75 + 0x0950: 7220 3c54 543e 446f 6375 6d65 6e74 526f + 0x0960: 6f74 3c2f 5454 3e29 2e3c 2f4c 493e 0a0a + 0x0970: 3c4c 493e 0a55 7365 7220 6469 7265 6374 + 0x0980: 6f72 6965 7320 6172 6520 656e 6162 6c65 + 0x0990: 642c 2061 6e64 2075 7365 7220 646f 6375 + 0x09a0: 6d65 6e74 7320 7769 6c6c 2062 6520 6c6f + 0x09b0: 6f6b 6564 2066 6f72 0a69 6e20 7468 6520 + 0x09c0: 3c54 543e 7075 626c 6963 5f68 746d 6c3c + 0x09d0: 2f54 543e 2064 6972 6563 746f 7279 206f + 0x09e0: 6620 7468 6520 7573 6572 7327 2068 6f6d + 0x09f0: 6573 2e20 2054 6865 7365 2064 6972 730a + 0x0a00: 7368 6f75 6c64 2062 6520 756e 6465 7220 + 0x0a10: 3c54 543e 2f68 6f6d 653c 2f54 543e 2c20 + 0x0a20: 616e 6420 7573 6572 7320 7769 6c6c 206e + 0x0a30: 6f74 2062 6520 6162 6c65 2074 6f20 7379 + 0x0a40: 6d6c 696e 6b0a 746f 2066 696c 6573 2074 + 0x0a50: 6865 7920 646f 6e27 7420 6f77 6e2e 3c2f + 0x0a60: 4c49 3e0a 0a3c 2f55 4c3e 0a41 6c6c 2074 + 0x0a70: 6865 2073 7461 6e64 6172 6420 6170 6163 + 0x0a80: 6865 206d 6f64 756c 6573 2061 7265 2061 + 0x0a90: 7661 696c 6162 6c65 2077 6974 6820 7468 + 0x0aa0: 6973 2072 656c 6561 7365 2061 6e64 2061 + 0x0ab0: 7265 0a6e 6f77 206d 616e 6167 6564 2077 + 0x0ac0: 6974 6820 6465 6263 6f6e 662e 2020 5479 + 0x0ad0: 7065 203c 5454 3e64 706b 672d 7265 636f + 0x0ae0: 6e66 6967 7572 6520 6170 6163 6865 3c2f + 0x0af0: 5454 3e20 746f 0a73 656c 6563 7420 7768 + 0x0b00: 6963 6820 6d6f 6475 6c65 7320 796f 7520 + 0x0b10: 7761 6e74 2065 6e61 626c 6564 2e20 204d + 0x0b20: 616e 7920 6f74 6865 7220 6d6f 6475 6c65 + 0x0b30: 7320 6172 6520 6176 6169 6c61 626c 650a + 0x0b40: 7468 726f 7567 6820 7468 6520 4465 6269 + 0x0b50: 616e 2070 6163 6b61 6765 2073 7973 7465 + 0x0b60: 6d20 7769 7468 2074 6865 206e 616d 6573 + 0x0b70: 203c 5454 3e6c 6962 6170 6163 6865 2d6d + 0x0b80: 6f64 2d2a 3c2f 5454 3e2e 0a49 6620 796f + 0x0b90: 7520 6e65 6564 2074 6f20 636f 6d70 696c + 0x0ba0: 6520 6120 6d6f 6475 6c65 2079 6f75 7273 + 0x0bb0: 656c 662c 2079 6f75 2077 696c 6c20 6e65 + 0x0bc0: 6564 2074 6f20 696e 7374 616c 6c20 7468 + 0x0bd0: 650a 3c54 543e 6170 6163 6865 2d64 6576 + 0x0be0: 3c2f 5454 3e20 7061 636b 6167 652e 0a0a + 0x0bf0: 3c50 3e4d 6f72 6520 646f 6375 6d65 6e74 + 0x0c00: 6174 696f 6e20 6f6e 2041 7061 6368 6520 + 0x0c10: 6361 6e20 6265 2066 6f75 6e64 206f 6e3a + 0x0c20: 0a3c 554c 3e0a 3c4c 493e 0a54 6865 203c + 0x0c30: 4120 4852 4546 3d22 2f64 6f63 2f61 7061 + 0x0c40: 6368 652d 646f 632f 6d61 6e75 616c 2f22 + 0x0c50: 3e41 7061 6368 6520 646f 6375 6d65 6e74 + 0x0c60: 6174 696f 6e3c 2f41 3e20 7374 6f72 6564 + 0x0c70: 206f 6e20 796f 7572 2073 6572 7665 722e + 0x0c80: 3c2f 4c49 3e0a 0a3c 4c49 3e0a 5468 6520 + 0x0c90: 3c41 2048 5245 463d 2268 7474 703a 2f2f + 0x0ca0: 7777 772e 6170 6163 6865 2e6f 7267 2f22 + 0x0cb0: 3e41 7061 6368 6520 5072 6f6a 6563 743c + 0x0cc0: 2f41 3e20 686f 6d65 2073 6974 652e 3c2f + 0x0cd0: 4c49 3e0a 0a3c 4c49 3e0a 5468 6520 3c41 + 0x0ce0: 2048 5245 463d 2268 7474 703a 2f2f 7777 + 0x0cf0: 772e 6170 6163 6865 2d73 736c 2e6f 7267 + 0x0d00: 2f22 3e41 7061 6368 652d 5353 4c3c 2f41 + 0x0d10: 3e20 686f 6d65 2073 6974 652e 3c2f 4c49 + 0x0d20: 3e0a 0a3c 4c49 3e0a 5468 6520 3c41 2048 + 0x0d30: 5245 463d 2268 7474 703a 2f2f 7065 726c + 0x0d40: 2e61 7061 6368 652e 6f72 672f 223e 6d6f + 0x0d50: 6420 7065 726c 3c2f 413e 2068 6f6d 6520 + 0x0d60: 7369 7465 2e3c 2f4c 493e 0a0a 3c4c 493e + 0x0d70: 0a54 6865 203c 4120 4852 4546 3d22 6874 + 0x0d80: 7470 3a2f 2f77 7777 2e61 7061 6368 6577 + 0x0d90: 6565 6b2e 636f 6d2f 223e 4170 6163 6865 + 0x0da0: 5765 656b 3c2f 413e 206e 6577 736c 6574 + 0x0db0: 7465 722e 3c2f 4c49 3e0a 0a3c 4c49 3e0a + 0x0dc0: 5468 6520 3c41 2048 5245 463d 2268 7474 + 0x0dd0: 703a 2f2f 7777 772e 6465 6269 616e 2e6f + 0x0de0: 7267 2f64 6f63 2f22 3e44 6562 6961 6e20 + 0x0df0: 5072 6f6a 6563 740a 446f 6375 6d65 6e74 + 0x0e00: 6174 696f 6e3c 2f41 3e20 7768 6963 6820 + 0x0e10: 636f 6e74 6169 6e73 2048 4f57 544f 732c + 0x0e20: 2046 4151 732c 2061 6e64 2073 6f66 7477 + 0x0e30: 6172 6520 7570 6461 7465 732e 3c2f 4c49 + 0x0e40: 3e0a 3c2f 554c 3e0a 0a3c 503e 596f 7520 + 0x0e50: 6361 6e20 616c 736f 2063 6f6e 7375 6c74 + 0x0e60: 2074 6865 206c 6973 7420 6f66 203c 4120 + 0x0e70: 4852 4546 3d22 6874 7470 3a2f 2f77 7777 + 0x0e80: 2e62 6f75 7465 6c6c 2e63 6f6d 2f66 6171 + 0x0e90: 2f22 3e57 6f72 6c64 0a57 6964 6520 5765 + 0x0ea0: 6220 4672 6571 7565 6e74 6c79 2041 736b + 0x0eb0: 6564 2051 7565 7374 696f 6e73 3c2f 413e + 0x0ec0: 2066 6f72 2069 6e66 6f72 6d61 7469 6f6e + 0x0ed0: 2e0a 0a3c 4832 3e4c 6574 206f 7468 6572 + 0x0ee0: 2070 656f 706c 6520 6b6e 6f77 2061 626f + 0x0ef0: 7574 2074 6869 7320 7365 7276 6572 3c2f + 0x0f00: 4832 3e0a 0a3c 4120 4852 4546 3d22 6874 + 0x0f10: 7470 3a2f 2f6e 6574 6372 6166 742e 636f + 0x0f20: 6d2f 223e 4e65 7463 7261 6674 3c2f 413e + 0x0f30: 2070 726f 7669 6465 7320 616e 2069 6e74 + 0x0f40: 6572 6573 7469 6e67 2066 7265 650a 7365 + 0x0f50: 7276 6963 6520 666f 7220 7765 6220 7369 + 0x0f60: 7465 206d 6f6e 6974 6f72 696e 6720 616e + 0x0f70: 6420 7374 6174 6973 7469 6320 636f 6c6c + 0x0f80: 6563 7469 6f6e 2e0a 596f 7520 6361 6e20 + 0x0f90: 6c65 7420 7468 656d 206b 6e6f 7720 6162 + 0x0fa0: 6f75 7420 796f 7572 2073 6572 7665 7220 + 0x0fb0: 7573 696e 6720 7468 6569 720a 3c41 2048 + 0x0fc0: 5245 463d 2268 7474 703a 2f2f 7570 7469 + 0x0fd0: 6d65 2e6e 6574 6372 6166 742e 636f 6d2f + 0x0fe0: 223e 696e 7465 7266 6163 653c 2f41 3e2e + 0x0ff0: 0a45 6e61 626c 696e 6720 7468 6520 6d6f + 0x1000: 6e69 746f 7269 6e67 206f 6620 796f 7572 + 0x1010: 2073 6572 7665 7220 7769 6c6c 2070 726f + 0x1020: 7669 6465 2061 2062 6574 7465 7220 676c + 0x1030: 6f62 616c 206f 7665 7276 6965 770a 6f66 + 0x1040: 2077 686f 2069 7320 7573 696e 6720 7768 + 0x1050: 6174 2061 6e64 2077 6865 7265 2c20 616e + 0x1060: 6420 6974 2077 6f75 6c64 2067 6976 6520 + 0x1070: 4465 6269 616e 2061 2062 6574 7465 720a + 0x1080: 6f76 6572 7669 6577 206f 6620 7468 6520 + 0x1090: 6170 6163 6865 2070 6163 6b61 6765 2075 + 0x10a0: 7361 6765 2e0a 0a3c 4832 3e41 626f 7574 + 0x10b0: 2074 6869 7320 7061 6765 3c2f 4832 3e0a + 0x10c0: 0a3c 494d 4720 414c 4947 4e3d 2272 6967 + 0x10d0: 6874 2220 414c 543d 2222 2048 4549 4748 + 0x10e0: 543d 2232 3437 2220 5749 4454 483d 2232 + 0x10f0: 3738 2220 5352 433d 2269 636f 6e73 2f6a + 0x1100: 6865 3036 312e 706e 6722 3e0a 0a3c 503e + 0x1110: 5468 6973 2069 7320 6120 706c 6163 6568 + 0x1120: 6f6c 6465 7220 7061 6765 2069 6e73 7461 + 0x1130: 6c6c 6564 2062 7920 7468 6520 3c41 0a48 + 0x1140: 5245 463d 2268 7474 703a 2f2f 7777 772e + 0x1150: 6465 6269 616e 2e6f 7267 2f22 3e44 6562 + 0x1160: 6961 6e3c 2f41 3e0a 7265 6c65 6173 6520 + 0x1170: 6f66 2074 6865 2061 7061 6368 6520 5765 + 0x1180: 6220 7365 7276 6572 2070 6163 6b61 6765 + 0x1190: 2e0a 0a3c 503e 5468 6973 2063 6f6d 7075 + 0x11a0: 7465 7220 6861 7320 696e 7374 616c 6c65 + 0x11b0: 6420 7468 6520 4465 6269 616e 2047 4e55 + 0x11c0: 2f4c 696e 7578 206f 7065 7261 7469 6e67 + 0x11d0: 2073 7973 7465 6d2c 0a62 7574 2069 7420 + 0x11e0: 6861 7320 3c73 7472 6f6e 673e 6e6f 7468 + 0x11f0: 696e 6720 746f 2064 6f20 7769 7468 2074 + 0x1200: 6865 2044 6562 6961 6e0a 5072 6f6a 6563 + 0x1210: 743c 2f73 7472 6f6e 673e 2e20 506c 6561 + 0x1220: 7365 2064 6f20 3c73 7472 6f6e 673e 6e6f + 0x1230: 743c 2f73 7472 6f6e 673e 2063 6f6e 7461 + 0x1240: 6374 2074 6865 2044 6562 6961 6e0a 5072 + 0x1250: 6f6a 6563 7420 6162 6f75 7420 6974 2e3c + 0x1260: 2f50 3e0a 0a3c 503e 4966 2079 6f75 2066 + 0x1270: 696e 6420 6120 6275 6720 696e 2074 6869 + 0x1280: 7320 6170 6163 6865 2070 6163 6b61 6765 + 0x1290: 2c20 6f72 2069 6e20 4170 6163 6865 2069 + 0x12a0: 7473 656c 662c 0a70 6c65 6173 6520 6669 + 0x12b0: 6c65 2061 2062 7567 2072 6570 6f72 7420 + 0x12c0: 6f6e 2069 742e 2020 496e 7374 7275 6374 + 0x12d0: 696f 6e73 206f 6e20 646f 696e 6720 7468 + 0x12e0: 6973 2c20 616e 6420 7468 650a 6c69 7374 + 0x12f0: 206f 6620 3c41 2048 5245 463d 2268 7474 + 0x1300: 703a 2f2f 6275 6773 2e64 6562 6961 6e2e + 0x1310: 6f72 672f 7372 633a 6170 6163 6865 223e + 0x1320: 6b6e 6f77 6e20 6275 6773 3c2f 413e 206f + 0x1330: 6620 7468 6973 0a70 6163 6b61 6765 2c20 + 0x1340: 6361 6e20 6265 2066 6f75 6e64 2069 6e20 + 0x1350: 7468 6520 0a3c 4120 4852 4546 3d22 6874 + 0x1360: 7470 3a2f 2f77 7777 2e64 6562 6961 6e2e + 0x1370: 6f72 672f 4275 6773 2f52 6570 6f72 7469 + 0x1380: 6e67 223e 4465 6269 616e 2042 7567 2054 + 0x1390: 7261 636b 696e 6720 5379 7374 656d 3c2f + 0x13a0: 413e 2e0a 0a3c 503e 5468 616e 6b73 2066 + 0x13b0: 6f72 2075 7369 6e67 2074 6869 7320 7061 + 0x13c0: 636b 6167 652c 2061 6e64 2063 6f6e 6772 + 0x13d0: 6174 756c 6174 696f 6e73 2066 6f72 2079 + 0x13e0: 6f75 7220 6368 6f69 6365 206f 660a 6120 + 0x13f0: 4465 6269 616e 2073 7973 7465 6d21 3c2f + 0x1400: 503e 0a0a 3c44 4956 2061 6c69 676e 3d22 + 0x1410: 6365 6e74 6572 223e 0a3c 6120 6872 6566 + 0x1420: 3d22 6874 7470 3a2f 2f77 7777 2e64 6562 + 0x1430: 6961 6e2e 6f72 672f 223e 0a3c 494d 4720 + 0x1440: 616c 6967 6e3d 226d 6964 646c 6522 2068 + 0x1450: 6569 6768 743d 2233 3022 2077 6964 7468 + 0x1460: 3d22 3235 2220 7372 633d 2269 636f 6e73 + 0x1470: 2f64 6562 6961 6e2f 6f70 656e 6c6f 676f + 0x1480: 2d32 352e 6a70 6722 2061 6c74 3d22 4465 + 0x1490: 6269 616e 223e 0a3c 2f61 3e0a 3c61 2068 + 0x14a0: 7265 663d 2268 7474 703a 2f2f 7777 772e + 0x14b0: 6170 6163 6865 2e6f 7267 2f22 3e0a 3c49 + 0x14c0: 4d47 2061 6c69 676e 3d22 6d69 6464 6c65 + 0x14d0: 2220 6865 6967 6874 3d22 3332 2220 7769 + 0x14e0: 6474 683d 2232 3539 2220 7372 633d 2269 + 0x14f0: 636f 6e73 2f61 7061 6368 655f 7062 2e70 + 0x1500: 6e67 2220 616c 743d 2241 7061 6368 6522 + 0x1510: 3e0a 3c2f 613e 0a3c 2f44 4956 3e0a 0a3c + 0x1520: 212d 2d0a 2020 5468 6973 2070 6167 6520 + 0x1530: 7761 7320 696e 6974 6961 6c6c 7920 6372 + 0x1540: 6561 7465 6420 6279 204a 6f68 6e69 6520 + 0x1550: 496e 6772 616d 2028 6874 7470 3a2f 2f6e + 0x1560: 6574 676f 642e 6e65 742f 290a 2020 4974 + 0x1570: 2077 6173 206c 6174 6572 2065 6469 7465 + 0x1580: 6420 6279 204d 6174 7468 6577 2057 696c + 0x1590: 636f 7820 616e 6420 4a6f 7369 7020 526f + 0x15a0: 6469 6e2e 0a20 204c 6173 7420 6d6f 6469 + 0x15b0: 6669 6564 3a20 2444 6174 653a 2032 3030 + 0x15c0: 342f 3036 2f32 3020 3135 3a33 333a 3537 + 0x15d0: 2024 2e0a 2020 2d2d 3e0a 0a3c 2f42 4f44 + 0x15e0: 593e 0a3c 2f48 544d 4c3e 0a +22:57:35.941260 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 5560, win 12383, options [nop,nop,TS val 1306300953 ecr 1306300953], length 0 + 0x0000: 4500 0034 1b6e 4000 4006 2154 7f00 0001 + 0x0010: 7f00 0001 da70 0050 3758 8a49 377a a3a9 + 0x0020: 8010 305f 10ea 0000 0101 080a 4ddc 9219 + 0x0030: 4ddc 9219 +22:57:37.229575 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [F.], seq 203, ack 5560, win 12383, options [nop,nop,TS val 1306302241 ecr 1306300953], length 0 + 0x0000: 4500 0034 1b70 4000 4006 2152 7f00 0001 + 0x0010: 7f00 0001 da70 0050 3758 8a49 377a a3a9 + 0x0020: 8011 305f 0be1 0000 0101 080a 4ddc 9721 + 0x0030: 4ddc 9219 +22:57:37.230839 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [F.], seq 5560, ack 204, win 8192, options [nop,nop,TS val 1306302243 ecr 1306302241], length 0 + 0x0000: 4500 0034 1fe8 4000 4006 1cda 7f00 0001 + 0x0010: 7f00 0001 0050 da70 377a a3a9 3758 8a4a + 0x0020: 8011 2000 1735 0000 0101 080a 4ddc 9723 + 0x0030: 4ddc 9721 +22:57:37.230900 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 5561, win 12383, options [nop,nop,TS val 1306302243 ecr 1306302243], length 0 + 0x0000: 4500 0034 1b72 4000 4006 2150 7f00 0001 + 0x0010: 7f00 0001 da70 0050 3758 8a4a 377a a3aa + 0x0020: 8010 305f 06d4 0000 0101 080a 4ddc 9723 + 0x0030: 4ddc 9723 diff --git a/tests/print-xx.out b/tests/print-xx.out new file mode 100644 index 0000000..d9d24db --- /dev/null +++ b/tests/print-xx.out @@ -0,0 +1,419 @@ +22:57:35.938066 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [S], seq 928549246, win 32767, options [mss 16396,sackOK,TS val 1306300950 ecr 0,nop,wscale 2], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 + 0x0010: 003c 1b68 4000 4006 2152 7f00 0001 7f00 + 0x0020: 0001 da70 0050 3758 897e 0000 0000 a002 + 0x0030: 7fff 1421 0000 0204 400c 0402 080a 4ddc + 0x0040: 9216 0000 0000 0103 0302 +22:57:35.938122 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [S.], seq 930778609, ack 928549247, win 32767, options [mss 16396,sackOK,TS val 1306300950 ecr 1306300950,nop,wscale 2], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 + 0x0010: 003c 0000 4000 4006 3cba 7f00 0001 7f00 + 0x0020: 0001 0050 da70 377a 8df1 3758 897f a012 + 0x0030: 7fff 6eb1 0000 0204 400c 0402 080a 4ddc + 0x0040: 9216 4ddc 9216 0103 0302 +22:57:35.938167 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 1, win 8192, options [nop,nop,TS val 1306300950 ecr 1306300950], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 + 0x0010: 0034 1b6a 4000 4006 2158 7f00 0001 7f00 + 0x0020: 0001 da70 0050 3758 897f 377a 8df2 8010 + 0x0030: 2000 37d0 0000 0101 080a 4ddc 9216 4ddc + 0x0040: 9216 +22:57:35.939423 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [P.], seq 1:203, ack 1, win 8192, options [nop,nop,TS val 1306300951 ecr 1306300950], length 202 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 + 0x0010: 00fe 1b6c 4000 4006 208c 7f00 0001 7f00 + 0x0020: 0001 da70 0050 3758 897f 377a 8df2 8018 + 0x0030: 2000 fef2 0000 0101 080a 4ddc 9217 4ddc + 0x0040: 9216 4745 5420 2f20 4854 5450 2f31 2e31 + 0x0050: 0d0a 486f 7374 3a20 6c6f 6361 6c68 6f73 + 0x0060: 740d 0a55 7365 722d 4167 656e 743a 2045 + 0x0070: 4c69 6e6b 732f 302e 3130 2e34 2d37 2d64 + 0x0080: 6562 6961 6e20 2874 6578 746d 6f64 653b + 0x0090: 204c 696e 7578 2032 2e36 2e31 312d 312d + 0x00a0: 3638 362d 736d 7020 6936 3836 3b20 3133 + 0x00b0: 3278 3536 2d32 290d 0a41 6363 6570 743a + 0x00c0: 202a 2f2a 0d0a 4163 6365 7074 2d45 6e63 + 0x00d0: 6f64 696e 673a 2067 7a69 700d 0a41 6363 + 0x00e0: 6570 742d 4c61 6e67 7561 6765 3a20 656e + 0x00f0: 0d0a 436f 6e6e 6563 7469 6f6e 3a20 4b65 + 0x0100: 6570 2d41 6c69 7665 0d0a 0d0a +22:57:35.940474 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [.], ack 203, win 8192, options [nop,nop,TS val 1306300952 ecr 1306300951], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 + 0x0010: 0034 1fe4 4000 4006 1cde 7f00 0001 7f00 + 0x0020: 0001 0050 da70 377a 8df2 3758 8a49 8010 + 0x0030: 2000 3703 0000 0101 080a 4ddc 9218 4ddc + 0x0040: 9217 +22:57:35.941232 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [P.], seq 1:5560, ack 203, win 8192, options [nop,nop,TS val 1306300953 ecr 1306300951], length 5559 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 + 0x0010: 15eb 1fe6 4000 4006 0725 7f00 0001 7f00 + 0x0020: 0001 0050 da70 377a 8df2 3758 8a49 8018 + 0x0030: 2000 13e0 0000 0101 080a 4ddc 9219 4ddc + 0x0040: 9217 4854 5450 2f31 2e31 2032 3030 204f + 0x0050: 4b0d 0a44 6174 653a 2057 6564 2c20 3036 + 0x0060: 204a 756c 2032 3030 3520 3033 3a35 373a + 0x0070: 3335 2047 4d54 0d0a 5365 7276 6572 3a20 + 0x0080: 4170 6163 6865 2f31 2e33 2e33 330d 0a4c + 0x0090: 6173 742d 4d6f 6469 6669 6564 3a20 5375 + 0x00a0: 6e2c 2031 3520 4175 6720 3230 3034 2030 + 0x00b0: 303a 3433 3a34 3120 474d 540d 0a45 5461 + 0x00c0: 673a 2022 3665 3830 6630 2d31 3438 612d + 0x00d0: 3431 3165 6231 6264 220d 0a41 6363 6570 + 0x00e0: 742d 5261 6e67 6573 3a20 6279 7465 730d + 0x00f0: 0a43 6f6e 7465 6e74 2d4c 656e 6774 683a + 0x0100: 2035 3235 380d 0a4b 6565 702d 416c 6976 + 0x0110: 653a 2074 696d 656f 7574 3d31 352c 206d + 0x0120: 6178 3d31 3030 0d0a 436f 6e6e 6563 7469 + 0x0130: 6f6e 3a20 4b65 6570 2d41 6c69 7665 0d0a + 0x0140: 436f 6e74 656e 742d 5479 7065 3a20 7465 + 0x0150: 7874 2f68 746d 6c3b 2063 6861 7273 6574 + 0x0160: 3d69 736f 2d38 3835 392d 310d 0a0d 0a3c + 0x0170: 2144 4f43 5459 5045 2048 544d 4c20 5055 + 0x0180: 424c 4943 2022 2d2f 2f57 3343 2f2f 4454 + 0x0190: 4420 4854 4d4c 2034 2e30 3120 5472 616e + 0x01a0: 7369 7469 6f6e 616c 2f2f 454e 223e 0a3c + 0x01b0: 4854 4d4c 3e0a 3c48 4541 443e 0a20 2020 + 0x01c0: 3c4d 4554 4120 4854 5450 2d45 5155 4956 + 0x01d0: 3d22 436f 6e74 656e 742d 5479 7065 2220 + 0x01e0: 434f 4e54 454e 543d 2274 6578 742f 6874 + 0x01f0: 6d6c 3b20 6368 6172 7365 743d 6973 6f2d + 0x0200: 3838 3539 2d31 223e 0a20 2020 3c4d 4554 + 0x0210: 4120 4e41 4d45 3d22 4465 7363 7269 7074 + 0x0220: 696f 6e22 2043 4f4e 5445 4e54 3d22 5468 + 0x0230: 6520 696e 6974 6961 6c20 696e 7374 616c + 0x0240: 6c61 7469 6f6e 206f 6620 4465 6269 616e + 0x0250: 2061 7061 6368 652e 223e 0a20 2020 3c54 + 0x0260: 4954 4c45 3e50 6c61 6365 686f 6c64 6572 + 0x0270: 2070 6167 653c 2f54 4954 4c45 3e0a 3c2f + 0x0280: 4845 4144 3e0a 3c42 4f44 5920 5445 5854 + 0x0290: 3d22 2330 3030 3030 3022 2042 4743 4f4c + 0x02a0: 4f52 3d22 2346 4646 4646 4622 204c 494e + 0x02b0: 4b3d 2223 3030 3030 4546 2220 564c 494e + 0x02c0: 4b3d 2223 3535 3138 3841 2220 414c 494e + 0x02d0: 4b3d 2223 4646 3030 3030 223e 0a0a 3c48 + 0x02e0: 313e 506c 6163 6568 6f6c 6465 7220 7061 + 0x02f0: 6765 3c2f 4831 3e0a 3c48 323e 4966 2079 + 0x0300: 6f75 2061 7265 206a 7573 7420 6272 6f77 + 0x0310: 7369 6e67 2074 6865 2077 6562 3c2f 6832 + 0x0320: 3e0a 0a3c 503e 5468 6520 6f77 6e65 7220 + 0x0330: 6f66 2074 6869 7320 7765 6220 7369 7465 + 0x0340: 2068 6173 206e 6f74 2070 7574 2075 7020 + 0x0350: 616e 7920 7765 6220 7061 6765 7320 7965 + 0x0360: 742e 0a50 6c65 6173 6520 636f 6d65 2062 + 0x0370: 6163 6b20 6c61 7465 722e 3c2f 503e 0a0a + 0x0380: 3c50 3e3c 534d 414c 4c3e 3c43 4954 453e + 0x0390: 4d6f 7665 2061 6c6f 6e67 2c20 6e6f 7468 + 0x03a0: 696e 6720 746f 2073 6565 2068 6572 652e + 0x03b0: 2e2e 3c2f 4349 5445 3e20 3a2d 293c 2f53 + 0x03c0: 4d41 4c4c 3e3c 2f50 3e0a 0a3c 4832 3e49 + 0x03d0: 6620 796f 7520 6172 6520 7472 7969 6e67 + 0x03e0: 2074 6f20 6c6f 6361 7465 2074 6865 2061 + 0x03f0: 646d 696e 6973 7472 6174 6f72 206f 6620 + 0x0400: 7468 6973 206d 6163 6869 6e65 3c2f 4832 + 0x0410: 3e0a 0a3c 503e 4966 2079 6f75 2077 616e + 0x0420: 7420 746f 2072 6570 6f72 7420 736f 6d65 + 0x0430: 7468 696e 6720 6162 6f75 7420 7468 6973 + 0x0440: 2068 6f73 7427 7320 6265 6861 7669 6f72 + 0x0450: 2c20 706c 6561 7365 0a63 6f6e 7461 6374 + 0x0460: 2074 6865 2049 6e74 6572 6e65 7420 5365 + 0x0470: 7276 6963 6520 5072 6f76 6964 6572 2028 + 0x0480: 4953 5029 2069 6e76 6f6c 7665 6420 6469 + 0x0490: 7265 6374 6c79 2e3c 2f50 3e0a 0a3c 503e + 0x04a0: 5365 6520 7468 6520 3c41 2068 7265 663d + 0x04b0: 2268 7474 703a 2f2f 7777 772e 6162 7573 + 0x04c0: 652e 6e65 742f 223e 4e65 7477 6f72 6b20 + 0x04d0: 4162 7573 650a 436c 6561 7269 6e67 686f + 0x04e0: 7573 653c 2f41 3e20 666f 7220 686f 7720 + 0x04f0: 746f 2064 6f20 7468 6973 2e3c 2f50 3e0a + 0x0500: 0a3c 4832 3e49 6620 796f 7520 6172 6520 + 0x0510: 7468 6520 6164 6d69 6e69 7374 7261 746f + 0x0520: 7220 6f66 2074 6869 7320 6d61 6368 696e + 0x0530: 653c 2f48 323e 0a0a 3c50 3e54 6865 2069 + 0x0540: 6e69 7469 616c 2069 6e73 7461 6c6c 6174 + 0x0550: 696f 6e20 6f66 203c 4120 6872 6566 3d22 + 0x0560: 6874 7470 3a2f 2f77 7777 2e64 6562 6961 + 0x0570: 6e2e 6f72 672f 223e 4465 6269 616e 2773 + 0x0580: 0a61 7061 6368 653c 2f41 3e20 7765 6220 + 0x0590: 7365 7276 6572 2070 6163 6b61 6765 2077 + 0x05a0: 6173 2073 7563 6365 7373 6675 6c2e 3c2f + 0x05b0: 503e 0a0a 3c50 3e3c 5354 524f 4e47 3e59 + 0x05c0: 6f75 2073 686f 756c 6420 7265 706c 6163 + 0x05d0: 6520 7468 6973 2070 6167 6520 7769 7468 + 0x05e0: 2079 6f75 7220 6f77 6e20 7765 6220 7061 + 0x05f0: 6765 7320 6173 0a73 6f6f 6e20 6173 2070 + 0x0600: 6f73 7369 626c 652e 3c2f 5354 524f 4e47 + 0x0610: 3e3c 2f50 3e0a 0a3c 503e 556e 6c65 7373 + 0x0620: 2079 6f75 2063 6861 6e67 6564 2069 7473 + 0x0630: 2063 6f6e 6669 6775 7261 7469 6f6e 2c20 + 0x0640: 796f 7572 206e 6577 2073 6572 7665 7220 + 0x0650: 6973 2063 6f6e 6669 6775 7265 6420 6173 + 0x0660: 2066 6f6c 6c6f 7773 3a0a 3c55 4c3e 0a3c + 0x0670: 4c49 3e0a 436f 6e66 6967 7572 6174 696f + 0x0680: 6e20 6669 6c65 7320 6361 6e20 6265 2066 + 0x0690: 6f75 6e64 2069 6e20 3c54 543e 2f65 7463 + 0x06a0: 2f61 7061 6368 653c 2f54 543e 2e3c 2f4c + 0x06b0: 493e 0a0a 3c4c 493e 0a54 6865 203c 5454 + 0x06c0: 3e44 6f63 756d 656e 7452 6f6f 743c 2f54 + 0x06d0: 543e 2c20 7768 6963 6820 6973 2074 6865 + 0x06e0: 2064 6972 6563 746f 7279 2075 6e64 6572 + 0x06f0: 2077 6869 6368 2061 6c6c 2079 6f75 720a + 0x0700: 4854 4d4c 2066 696c 6573 2073 686f 756c + 0x0710: 6420 6578 6973 742c 2069 7320 7365 7420 + 0x0720: 746f 203c 5454 3e2f 7661 722f 7777 773c + 0x0730: 2f54 543e 2e3c 2f4c 493e 0a0a 3c4c 493e + 0x0740: 0a43 4749 2073 6372 6970 7473 2061 7265 + 0x0750: 206c 6f6f 6b65 6420 666f 7220 696e 203c + 0x0760: 5454 3e2f 7573 722f 6c69 622f 6367 692d + 0x0770: 6269 6e3c 2f54 543e 2c20 7768 6963 6820 + 0x0780: 6973 2077 6865 7265 0a44 6562 6961 6e20 + 0x0790: 7061 636b 6167 6573 2077 696c 6c20 706c + 0x07a0: 6163 6520 7468 6569 7220 7363 7269 7074 + 0x07b0: 732e 3c2f 4c49 3e0a 0a3c 4c49 3e0a 4c6f + 0x07c0: 6720 6669 6c65 7320 6172 6520 706c 6163 + 0x07d0: 6564 2069 6e20 3c54 543e 2f76 6172 2f6c + 0x07e0: 6f67 2f61 7061 6368 653c 2f54 543e 2c20 + 0x07f0: 616e 6420 7769 6c6c 2062 6520 726f 7461 + 0x0800: 7465 640a 7765 656b 6c79 2e20 2054 6865 + 0x0810: 2066 7265 7175 656e 6379 206f 6620 726f + 0x0820: 7461 7469 6f6e 2063 616e 2062 6520 6561 + 0x0830: 7369 6c79 2063 6861 6e67 6564 2062 7920 + 0x0840: 6564 6974 696e 670a 3c54 543e 2f65 7463 + 0x0850: 2f6c 6f67 726f 7461 7465 2e64 2f61 7061 + 0x0860: 6368 653c 2f54 543e 2e3c 2f4c 493e 0a0a + 0x0870: 3c4c 493e 0a54 6865 2064 6566 6175 6c74 + 0x0880: 2064 6972 6563 746f 7279 2069 6e64 6578 + 0x0890: 2069 7320 3c54 543e 696e 6465 782e 6874 + 0x08a0: 6d6c 3c2f 5454 3e2c 206d 6561 6e69 6e67 + 0x08b0: 2074 6861 7420 7265 7175 6573 7473 0a66 + 0x08c0: 6f72 2061 2064 6972 6563 746f 7279 203c + 0x08d0: 5454 3e2f 666f 6f2f 6261 722f 3c2f 5454 + 0x08e0: 3e20 7769 6c6c 2067 6976 6520 7468 6520 + 0x08f0: 636f 6e74 656e 7473 206f 6620 7468 6520 + 0x0900: 6669 6c65 203c 5454 3e2f 7661 722f 7777 + 0x0910: 772f 666f 6f2f 6261 722f 696e 6465 782e + 0x0920: 6874 6d6c 3c2f 5454 3e0a 6966 2069 7420 + 0x0930: 6578 6973 7473 2028 6173 7375 6d69 6e67 + 0x0940: 2074 6861 7420 3c54 543e 2f76 6172 2f77 + 0x0950: 7777 3c2f 5454 3e20 6973 2079 6f75 7220 + 0x0960: 3c54 543e 446f 6375 6d65 6e74 526f 6f74 + 0x0970: 3c2f 5454 3e29 2e3c 2f4c 493e 0a0a 3c4c + 0x0980: 493e 0a55 7365 7220 6469 7265 6374 6f72 + 0x0990: 6965 7320 6172 6520 656e 6162 6c65 642c + 0x09a0: 2061 6e64 2075 7365 7220 646f 6375 6d65 + 0x09b0: 6e74 7320 7769 6c6c 2062 6520 6c6f 6f6b + 0x09c0: 6564 2066 6f72 0a69 6e20 7468 6520 3c54 + 0x09d0: 543e 7075 626c 6963 5f68 746d 6c3c 2f54 + 0x09e0: 543e 2064 6972 6563 746f 7279 206f 6620 + 0x09f0: 7468 6520 7573 6572 7327 2068 6f6d 6573 + 0x0a00: 2e20 2054 6865 7365 2064 6972 730a 7368 + 0x0a10: 6f75 6c64 2062 6520 756e 6465 7220 3c54 + 0x0a20: 543e 2f68 6f6d 653c 2f54 543e 2c20 616e + 0x0a30: 6420 7573 6572 7320 7769 6c6c 206e 6f74 + 0x0a40: 2062 6520 6162 6c65 2074 6f20 7379 6d6c + 0x0a50: 696e 6b0a 746f 2066 696c 6573 2074 6865 + 0x0a60: 7920 646f 6e27 7420 6f77 6e2e 3c2f 4c49 + 0x0a70: 3e0a 0a3c 2f55 4c3e 0a41 6c6c 2074 6865 + 0x0a80: 2073 7461 6e64 6172 6420 6170 6163 6865 + 0x0a90: 206d 6f64 756c 6573 2061 7265 2061 7661 + 0x0aa0: 696c 6162 6c65 2077 6974 6820 7468 6973 + 0x0ab0: 2072 656c 6561 7365 2061 6e64 2061 7265 + 0x0ac0: 0a6e 6f77 206d 616e 6167 6564 2077 6974 + 0x0ad0: 6820 6465 6263 6f6e 662e 2020 5479 7065 + 0x0ae0: 203c 5454 3e64 706b 672d 7265 636f 6e66 + 0x0af0: 6967 7572 6520 6170 6163 6865 3c2f 5454 + 0x0b00: 3e20 746f 0a73 656c 6563 7420 7768 6963 + 0x0b10: 6820 6d6f 6475 6c65 7320 796f 7520 7761 + 0x0b20: 6e74 2065 6e61 626c 6564 2e20 204d 616e + 0x0b30: 7920 6f74 6865 7220 6d6f 6475 6c65 7320 + 0x0b40: 6172 6520 6176 6169 6c61 626c 650a 7468 + 0x0b50: 726f 7567 6820 7468 6520 4465 6269 616e + 0x0b60: 2070 6163 6b61 6765 2073 7973 7465 6d20 + 0x0b70: 7769 7468 2074 6865 206e 616d 6573 203c + 0x0b80: 5454 3e6c 6962 6170 6163 6865 2d6d 6f64 + 0x0b90: 2d2a 3c2f 5454 3e2e 0a49 6620 796f 7520 + 0x0ba0: 6e65 6564 2074 6f20 636f 6d70 696c 6520 + 0x0bb0: 6120 6d6f 6475 6c65 2079 6f75 7273 656c + 0x0bc0: 662c 2079 6f75 2077 696c 6c20 6e65 6564 + 0x0bd0: 2074 6f20 696e 7374 616c 6c20 7468 650a + 0x0be0: 3c54 543e 6170 6163 6865 2d64 6576 3c2f + 0x0bf0: 5454 3e20 7061 636b 6167 652e 0a0a 3c50 + 0x0c00: 3e4d 6f72 6520 646f 6375 6d65 6e74 6174 + 0x0c10: 696f 6e20 6f6e 2041 7061 6368 6520 6361 + 0x0c20: 6e20 6265 2066 6f75 6e64 206f 6e3a 0a3c + 0x0c30: 554c 3e0a 3c4c 493e 0a54 6865 203c 4120 + 0x0c40: 4852 4546 3d22 2f64 6f63 2f61 7061 6368 + 0x0c50: 652d 646f 632f 6d61 6e75 616c 2f22 3e41 + 0x0c60: 7061 6368 6520 646f 6375 6d65 6e74 6174 + 0x0c70: 696f 6e3c 2f41 3e20 7374 6f72 6564 206f + 0x0c80: 6e20 796f 7572 2073 6572 7665 722e 3c2f + 0x0c90: 4c49 3e0a 0a3c 4c49 3e0a 5468 6520 3c41 + 0x0ca0: 2048 5245 463d 2268 7474 703a 2f2f 7777 + 0x0cb0: 772e 6170 6163 6865 2e6f 7267 2f22 3e41 + 0x0cc0: 7061 6368 6520 5072 6f6a 6563 743c 2f41 + 0x0cd0: 3e20 686f 6d65 2073 6974 652e 3c2f 4c49 + 0x0ce0: 3e0a 0a3c 4c49 3e0a 5468 6520 3c41 2048 + 0x0cf0: 5245 463d 2268 7474 703a 2f2f 7777 772e + 0x0d00: 6170 6163 6865 2d73 736c 2e6f 7267 2f22 + 0x0d10: 3e41 7061 6368 652d 5353 4c3c 2f41 3e20 + 0x0d20: 686f 6d65 2073 6974 652e 3c2f 4c49 3e0a + 0x0d30: 0a3c 4c49 3e0a 5468 6520 3c41 2048 5245 + 0x0d40: 463d 2268 7474 703a 2f2f 7065 726c 2e61 + 0x0d50: 7061 6368 652e 6f72 672f 223e 6d6f 6420 + 0x0d60: 7065 726c 3c2f 413e 2068 6f6d 6520 7369 + 0x0d70: 7465 2e3c 2f4c 493e 0a0a 3c4c 493e 0a54 + 0x0d80: 6865 203c 4120 4852 4546 3d22 6874 7470 + 0x0d90: 3a2f 2f77 7777 2e61 7061 6368 6577 6565 + 0x0da0: 6b2e 636f 6d2f 223e 4170 6163 6865 5765 + 0x0db0: 656b 3c2f 413e 206e 6577 736c 6574 7465 + 0x0dc0: 722e 3c2f 4c49 3e0a 0a3c 4c49 3e0a 5468 + 0x0dd0: 6520 3c41 2048 5245 463d 2268 7474 703a + 0x0de0: 2f2f 7777 772e 6465 6269 616e 2e6f 7267 + 0x0df0: 2f64 6f63 2f22 3e44 6562 6961 6e20 5072 + 0x0e00: 6f6a 6563 740a 446f 6375 6d65 6e74 6174 + 0x0e10: 696f 6e3c 2f41 3e20 7768 6963 6820 636f + 0x0e20: 6e74 6169 6e73 2048 4f57 544f 732c 2046 + 0x0e30: 4151 732c 2061 6e64 2073 6f66 7477 6172 + 0x0e40: 6520 7570 6461 7465 732e 3c2f 4c49 3e0a + 0x0e50: 3c2f 554c 3e0a 0a3c 503e 596f 7520 6361 + 0x0e60: 6e20 616c 736f 2063 6f6e 7375 6c74 2074 + 0x0e70: 6865 206c 6973 7420 6f66 203c 4120 4852 + 0x0e80: 4546 3d22 6874 7470 3a2f 2f77 7777 2e62 + 0x0e90: 6f75 7465 6c6c 2e63 6f6d 2f66 6171 2f22 + 0x0ea0: 3e57 6f72 6c64 0a57 6964 6520 5765 6220 + 0x0eb0: 4672 6571 7565 6e74 6c79 2041 736b 6564 + 0x0ec0: 2051 7565 7374 696f 6e73 3c2f 413e 2066 + 0x0ed0: 6f72 2069 6e66 6f72 6d61 7469 6f6e 2e0a + 0x0ee0: 0a3c 4832 3e4c 6574 206f 7468 6572 2070 + 0x0ef0: 656f 706c 6520 6b6e 6f77 2061 626f 7574 + 0x0f00: 2074 6869 7320 7365 7276 6572 3c2f 4832 + 0x0f10: 3e0a 0a3c 4120 4852 4546 3d22 6874 7470 + 0x0f20: 3a2f 2f6e 6574 6372 6166 742e 636f 6d2f + 0x0f30: 223e 4e65 7463 7261 6674 3c2f 413e 2070 + 0x0f40: 726f 7669 6465 7320 616e 2069 6e74 6572 + 0x0f50: 6573 7469 6e67 2066 7265 650a 7365 7276 + 0x0f60: 6963 6520 666f 7220 7765 6220 7369 7465 + 0x0f70: 206d 6f6e 6974 6f72 696e 6720 616e 6420 + 0x0f80: 7374 6174 6973 7469 6320 636f 6c6c 6563 + 0x0f90: 7469 6f6e 2e0a 596f 7520 6361 6e20 6c65 + 0x0fa0: 7420 7468 656d 206b 6e6f 7720 6162 6f75 + 0x0fb0: 7420 796f 7572 2073 6572 7665 7220 7573 + 0x0fc0: 696e 6720 7468 6569 720a 3c41 2048 5245 + 0x0fd0: 463d 2268 7474 703a 2f2f 7570 7469 6d65 + 0x0fe0: 2e6e 6574 6372 6166 742e 636f 6d2f 223e + 0x0ff0: 696e 7465 7266 6163 653c 2f41 3e2e 0a45 + 0x1000: 6e61 626c 696e 6720 7468 6520 6d6f 6e69 + 0x1010: 746f 7269 6e67 206f 6620 796f 7572 2073 + 0x1020: 6572 7665 7220 7769 6c6c 2070 726f 7669 + 0x1030: 6465 2061 2062 6574 7465 7220 676c 6f62 + 0x1040: 616c 206f 7665 7276 6965 770a 6f66 2077 + 0x1050: 686f 2069 7320 7573 696e 6720 7768 6174 + 0x1060: 2061 6e64 2077 6865 7265 2c20 616e 6420 + 0x1070: 6974 2077 6f75 6c64 2067 6976 6520 4465 + 0x1080: 6269 616e 2061 2062 6574 7465 720a 6f76 + 0x1090: 6572 7669 6577 206f 6620 7468 6520 6170 + 0x10a0: 6163 6865 2070 6163 6b61 6765 2075 7361 + 0x10b0: 6765 2e0a 0a3c 4832 3e41 626f 7574 2074 + 0x10c0: 6869 7320 7061 6765 3c2f 4832 3e0a 0a3c + 0x10d0: 494d 4720 414c 4947 4e3d 2272 6967 6874 + 0x10e0: 2220 414c 543d 2222 2048 4549 4748 543d + 0x10f0: 2232 3437 2220 5749 4454 483d 2232 3738 + 0x1100: 2220 5352 433d 2269 636f 6e73 2f6a 6865 + 0x1110: 3036 312e 706e 6722 3e0a 0a3c 503e 5468 + 0x1120: 6973 2069 7320 6120 706c 6163 6568 6f6c + 0x1130: 6465 7220 7061 6765 2069 6e73 7461 6c6c + 0x1140: 6564 2062 7920 7468 6520 3c41 0a48 5245 + 0x1150: 463d 2268 7474 703a 2f2f 7777 772e 6465 + 0x1160: 6269 616e 2e6f 7267 2f22 3e44 6562 6961 + 0x1170: 6e3c 2f41 3e0a 7265 6c65 6173 6520 6f66 + 0x1180: 2074 6865 2061 7061 6368 6520 5765 6220 + 0x1190: 7365 7276 6572 2070 6163 6b61 6765 2e0a + 0x11a0: 0a3c 503e 5468 6973 2063 6f6d 7075 7465 + 0x11b0: 7220 6861 7320 696e 7374 616c 6c65 6420 + 0x11c0: 7468 6520 4465 6269 616e 2047 4e55 2f4c + 0x11d0: 696e 7578 206f 7065 7261 7469 6e67 2073 + 0x11e0: 7973 7465 6d2c 0a62 7574 2069 7420 6861 + 0x11f0: 7320 3c73 7472 6f6e 673e 6e6f 7468 696e + 0x1200: 6720 746f 2064 6f20 7769 7468 2074 6865 + 0x1210: 2044 6562 6961 6e0a 5072 6f6a 6563 743c + 0x1220: 2f73 7472 6f6e 673e 2e20 506c 6561 7365 + 0x1230: 2064 6f20 3c73 7472 6f6e 673e 6e6f 743c + 0x1240: 2f73 7472 6f6e 673e 2063 6f6e 7461 6374 + 0x1250: 2074 6865 2044 6562 6961 6e0a 5072 6f6a + 0x1260: 6563 7420 6162 6f75 7420 6974 2e3c 2f50 + 0x1270: 3e0a 0a3c 503e 4966 2079 6f75 2066 696e + 0x1280: 6420 6120 6275 6720 696e 2074 6869 7320 + 0x1290: 6170 6163 6865 2070 6163 6b61 6765 2c20 + 0x12a0: 6f72 2069 6e20 4170 6163 6865 2069 7473 + 0x12b0: 656c 662c 0a70 6c65 6173 6520 6669 6c65 + 0x12c0: 2061 2062 7567 2072 6570 6f72 7420 6f6e + 0x12d0: 2069 742e 2020 496e 7374 7275 6374 696f + 0x12e0: 6e73 206f 6e20 646f 696e 6720 7468 6973 + 0x12f0: 2c20 616e 6420 7468 650a 6c69 7374 206f + 0x1300: 6620 3c41 2048 5245 463d 2268 7474 703a + 0x1310: 2f2f 6275 6773 2e64 6562 6961 6e2e 6f72 + 0x1320: 672f 7372 633a 6170 6163 6865 223e 6b6e + 0x1330: 6f77 6e20 6275 6773 3c2f 413e 206f 6620 + 0x1340: 7468 6973 0a70 6163 6b61 6765 2c20 6361 + 0x1350: 6e20 6265 2066 6f75 6e64 2069 6e20 7468 + 0x1360: 6520 0a3c 4120 4852 4546 3d22 6874 7470 + 0x1370: 3a2f 2f77 7777 2e64 6562 6961 6e2e 6f72 + 0x1380: 672f 4275 6773 2f52 6570 6f72 7469 6e67 + 0x1390: 223e 4465 6269 616e 2042 7567 2054 7261 + 0x13a0: 636b 696e 6720 5379 7374 656d 3c2f 413e + 0x13b0: 2e0a 0a3c 503e 5468 616e 6b73 2066 6f72 + 0x13c0: 2075 7369 6e67 2074 6869 7320 7061 636b + 0x13d0: 6167 652c 2061 6e64 2063 6f6e 6772 6174 + 0x13e0: 756c 6174 696f 6e73 2066 6f72 2079 6f75 + 0x13f0: 7220 6368 6f69 6365 206f 660a 6120 4465 + 0x1400: 6269 616e 2073 7973 7465 6d21 3c2f 503e + 0x1410: 0a0a 3c44 4956 2061 6c69 676e 3d22 6365 + 0x1420: 6e74 6572 223e 0a3c 6120 6872 6566 3d22 + 0x1430: 6874 7470 3a2f 2f77 7777 2e64 6562 6961 + 0x1440: 6e2e 6f72 672f 223e 0a3c 494d 4720 616c + 0x1450: 6967 6e3d 226d 6964 646c 6522 2068 6569 + 0x1460: 6768 743d 2233 3022 2077 6964 7468 3d22 + 0x1470: 3235 2220 7372 633d 2269 636f 6e73 2f64 + 0x1480: 6562 6961 6e2f 6f70 656e 6c6f 676f 2d32 + 0x1490: 352e 6a70 6722 2061 6c74 3d22 4465 6269 + 0x14a0: 616e 223e 0a3c 2f61 3e0a 3c61 2068 7265 + 0x14b0: 663d 2268 7474 703a 2f2f 7777 772e 6170 + 0x14c0: 6163 6865 2e6f 7267 2f22 3e0a 3c49 4d47 + 0x14d0: 2061 6c69 676e 3d22 6d69 6464 6c65 2220 + 0x14e0: 6865 6967 6874 3d22 3332 2220 7769 6474 + 0x14f0: 683d 2232 3539 2220 7372 633d 2269 636f + 0x1500: 6e73 2f61 7061 6368 655f 7062 2e70 6e67 + 0x1510: 2220 616c 743d 2241 7061 6368 6522 3e0a + 0x1520: 3c2f 613e 0a3c 2f44 4956 3e0a 0a3c 212d + 0x1530: 2d0a 2020 5468 6973 2070 6167 6520 7761 + 0x1540: 7320 696e 6974 6961 6c6c 7920 6372 6561 + 0x1550: 7465 6420 6279 204a 6f68 6e69 6520 496e + 0x1560: 6772 616d 2028 6874 7470 3a2f 2f6e 6574 + 0x1570: 676f 642e 6e65 742f 290a 2020 4974 2077 + 0x1580: 6173 206c 6174 6572 2065 6469 7465 6420 + 0x1590: 6279 204d 6174 7468 6577 2057 696c 636f + 0x15a0: 7820 616e 6420 4a6f 7369 7020 526f 6469 + 0x15b0: 6e2e 0a20 204c 6173 7420 6d6f 6469 6669 + 0x15c0: 6564 3a20 2444 6174 653a 2032 3030 342f + 0x15d0: 3036 2f32 3020 3135 3a33 333a 3537 2024 + 0x15e0: 2e0a 2020 2d2d 3e0a 0a3c 2f42 4f44 593e + 0x15f0: 0a3c 2f48 544d 4c3e 0a +22:57:35.941260 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 5560, win 12383, options [nop,nop,TS val 1306300953 ecr 1306300953], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 + 0x0010: 0034 1b6e 4000 4006 2154 7f00 0001 7f00 + 0x0020: 0001 da70 0050 3758 8a49 377a a3a9 8010 + 0x0030: 305f 10ea 0000 0101 080a 4ddc 9219 4ddc + 0x0040: 9219 +22:57:37.229575 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [F.], seq 203, ack 5560, win 12383, options [nop,nop,TS val 1306302241 ecr 1306300953], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 + 0x0010: 0034 1b70 4000 4006 2152 7f00 0001 7f00 + 0x0020: 0001 da70 0050 3758 8a49 377a a3a9 8011 + 0x0030: 305f 0be1 0000 0101 080a 4ddc 9721 4ddc + 0x0040: 9219 +22:57:37.230839 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [F.], seq 5560, ack 204, win 8192, options [nop,nop,TS val 1306302243 ecr 1306302241], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 + 0x0010: 0034 1fe8 4000 4006 1cda 7f00 0001 7f00 + 0x0020: 0001 0050 da70 377a a3a9 3758 8a4a 8011 + 0x0030: 2000 1735 0000 0101 080a 4ddc 9723 4ddc + 0x0040: 9721 +22:57:37.230900 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 5561, win 12383, options [nop,nop,TS val 1306302243 ecr 1306302243], length 0 + 0x0000: 0000 0000 0000 0000 0000 0000 0800 4500 + 0x0010: 0034 1b72 4000 4006 2150 7f00 0001 7f00 + 0x0020: 0001 da70 0050 3758 8a4a 377a a3aa 8010 + 0x0030: 305f 06d4 0000 0101 080a 4ddc 9723 4ddc + 0x0040: 9723 diff --git a/tests/rsvp-infinite-loop.pcap b/tests/rsvp-infinite-loop.pcap new file mode 100644 index 0000000000000000000000000000000000000000..dc03dacc8b1c9afedf1499f73708c018f09358d3 GIT binary patch literal 384 zcmca|c+)~A1{MYwNB}Ylfw=l=zEjFPRt5_o8-y8Hn1IANEfAA|frG)7fkA_T!GWPc zPn!9{1z+t0D;OCCL}r|GU|DTVNOj^a`sF`eCBMk<|M+Lr7?T-#7l6Q0|4B{Jk|gJ literal 0 HcmV?d00001 diff --git a/tftp.h b/tftp.h new file mode 100644 index 0000000..6a092e0 --- /dev/null +++ b/tftp.h @@ -0,0 +1,82 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/tftp.h,v 1.2 2008-04-11 16:47:38 gianluca Exp $ (LBL) */ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)tftp.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _TFTP_H_ +#define _TFTP_H_ + +/* + * Trivial File Transfer Protocol (IEN-133) + */ +#define SEGSIZE 512 /* data segment size */ + +/* + * Packet types. + */ +#define RRQ 01 /* read request */ +#define WRQ 02 /* write request */ +#define DATA 03 /* data packet */ +#define ACK 04 /* acknowledgement */ +#define TFTP_ERROR 05 /* error code */ +#define OACK 06 /* option acknowledgement */ + +struct tftphdr { + unsigned short th_opcode; /* packet type */ + union { + unsigned short tu_block; /* block # */ + unsigned short tu_code; /* error code */ + char tu_stuff[1]; /* request packet stuff */ + } th_u; + char th_data[1]; /* data or error string */ +}; + +#define th_block th_u.tu_block +#define th_code th_u.tu_code +#define th_stuff th_u.tu_stuff +#define th_msg th_data + +/* + * Error codes. + */ +#define EUNDEF 0 /* not defined */ +#define ENOTFOUND 1 /* file not found */ +#define EACCESS 2 /* access violation */ +#define ENOSPACE 3 /* disk full or allocation exceeded */ +#define EBADOP 4 /* illegal TFTP operation */ +#define EBADID 5 /* unknown transfer ID */ +#define EEXISTS 6 /* file already exists */ +#define ENOUSER 7 /* no such user */ + +#endif /* !_TFTP_H_ */ diff --git a/timed.h b/timed.h new file mode 100644 index 0000000..f8d5a11 --- /dev/null +++ b/timed.h @@ -0,0 +1,97 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/timed.h,v 1.6 2008-02-05 19:46:19 guy Exp $ (LBL) */ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)timed.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _PROTOCOLS_TIMED_H_ +#define _PROTOCOLS_TIMED_H_ + +/* + * Time Synchronization Protocol + */ + +#define TSPVERSION 1 +#define ANYADDR NULL + +struct tsp_timeval { + u_int32_t tv_sec; + u_int32_t tv_usec; +}; + +struct tsp { + u_int8_t tsp_type; + u_int8_t tsp_vers; + u_int16_t tsp_seq; + union { + struct tsp_timeval tspu_time; + int8_t tspu_hopcnt; + } tsp_u; + int8_t tsp_name[256]; +}; + +#define tsp_time tsp_u.tspu_time +#define tsp_hopcnt tsp_u.tspu_hopcnt + +/* + * Command types. + */ +#define TSP_ANY 0 /* match any types */ +#define TSP_ADJTIME 1 /* send adjtime */ +#define TSP_ACK 2 /* generic acknowledgement */ +#define TSP_MASTERREQ 3 /* ask for master's name */ +#define TSP_MASTERACK 4 /* acknowledge master request */ +#define TSP_SETTIME 5 /* send network time */ +#define TSP_MASTERUP 6 /* inform slaves that master is up */ +#define TSP_SLAVEUP 7 /* slave is up but not polled */ +#define TSP_ELECTION 8 /* advance candidature for master */ +#define TSP_ACCEPT 9 /* support candidature of master */ +#define TSP_REFUSE 10 /* reject candidature of master */ +#define TSP_CONFLICT 11 /* two or more masters present */ +#define TSP_RESOLVE 12 /* masters' conflict resolution */ +#define TSP_QUIT 13 /* reject candidature if master is up */ +#define TSP_DATE 14 /* reset the time (date command) */ +#define TSP_DATEREQ 15 /* remote request to reset the time */ +#define TSP_DATEACK 16 /* acknowledge time setting */ +#define TSP_TRACEON 17 /* turn tracing on */ +#define TSP_TRACEOFF 18 /* turn tracing off */ +#define TSP_MSITE 19 /* find out master's site */ +#define TSP_MSITEREQ 20 /* remote master's site request */ +#define TSP_TEST 21 /* for testing election algo */ +#define TSP_SETDATE 22 /* New from date command */ +#define TSP_SETDATEREQ 23 /* New remote for above */ +#define TSP_LOOP 24 /* loop detection packet */ + +#define TSPTYPENUMBER 25 + +#endif /* !_TIMED_H_ */ diff --git a/token.h b/token.h new file mode 100644 index 0000000..73a8271 --- /dev/null +++ b/token.h @@ -0,0 +1,52 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/token.h,v 1.6 2002-12-11 07:14:12 guy Exp $ (LBL) */ +/* + * Copyright (c) 1998, Larry Lile + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#define TOKEN_HDRLEN 14 +#define TOKEN_RING_MAC_LEN 6 +#define ROUTING_SEGMENT_MAX 16 +#define IS_SOURCE_ROUTED(trp) ((trp)->token_shost[0] & 0x80) +#define FRAME_TYPE(trp) (((trp)->token_fc & 0xC0) >> 6) +#define TOKEN_FC_LLC 1 + +#define BROADCAST(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0xE000) >> 13) +#define RIF_LENGTH(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0x1f00) >> 8) +#define DIRECTION(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0x0080) >> 7) +#define LARGEST_FRAME(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0x0070) >> 4) +#define RING_NUMBER(trp, x) ((EXTRACT_16BITS(&(trp)->token_rseg[x]) & 0xfff0) >> 4) +#define BRIDGE_NUMBER(trp, x) ((EXTRACT_16BITS(&(trp)->token_rseg[x]) & 0x000f)) +#define SEGMENT_COUNT(trp) ((int)((RIF_LENGTH(trp) - 2) / 2)) + +struct token_header { + u_int8_t token_ac; + u_int8_t token_fc; + u_int8_t token_dhost[TOKEN_RING_MAC_LEN]; + u_int8_t token_shost[TOKEN_RING_MAC_LEN]; + u_int16_t token_rcf; + u_int16_t token_rseg[ROUTING_SEGMENT_MAX]; +}; diff --git a/udp.h b/udp.h new file mode 100644 index 0000000..fb45d68 --- /dev/null +++ b/udp.h @@ -0,0 +1,93 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/udp.h,v 1.13 2007-08-08 17:20:58 hannes Exp $ (LBL) */ +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)udp.h 8.1 (Berkeley) 6/10/93 + */ + +/* + * Udp protocol header. + * Per RFC 768, September, 1981. + */ +struct udphdr { + u_int16_t uh_sport; /* source port */ + u_int16_t uh_dport; /* destination port */ + u_int16_t uh_ulen; /* udp length */ + u_int16_t uh_sum; /* udp checksum */ +}; + +#define TFTP_PORT 69 /*XXX*/ +#define KERBEROS_PORT 88 /*XXX*/ +#define SUNRPC_PORT 111 /*XXX*/ +#define SNMP_PORT 161 /*XXX*/ +#define NTP_PORT 123 /*XXX*/ +#define SNMPTRAP_PORT 162 /*XXX*/ +#define ISAKMP_PORT 500 /*XXX*/ +#define SYSLOG_PORT 514 /* rfc3164 */ +#define TIMED_PORT 525 /*XXX*/ +#define RIP_PORT 520 /*XXX*/ +#define LDP_PORT 646 +#define AODV_PORT 654 /*XXX*/ +#define OLSR_PORT 698 /* rfc3626 */ +#define KERBEROS_SEC_PORT 750 /*XXX*/ +#define L2TP_PORT 1701 /*XXX*/ +#define SIP_PORT 5060 +#define ISAKMP_PORT_NATT 4500 /* rfc3948 */ +#define ISAKMP_PORT_USER1 7500 /*XXX - nonstandard*/ +#define ISAKMP_PORT_USER2 8500 /*XXX - nonstandard*/ +#define RX_PORT_LOW 7000 /*XXX*/ +#define RX_PORT_HIGH 7009 /*XXX*/ +#define NETBIOS_NS_PORT 137 +#define NETBIOS_DGRAM_PORT 138 +#define CISCO_AUTORP_PORT 496 /*XXX*/ +#define RADIUS_PORT 1645 +#define RADIUS_NEW_PORT 1812 +#define RADIUS_ACCOUNTING_PORT 1646 +#define RADIUS_NEW_ACCOUNTING_PORT 1813 +#define HSRP_PORT 1985 /*XXX*/ +#define LMP_PORT 701 /* rfc4204 */ +#define LWRES_PORT 921 +#define VQP_PORT 1589 +#define ZEPHYR_SRV_PORT 2103 +#define ZEPHYR_CLT_PORT 2104 +#define MPLS_LSP_PING_PORT 3503 /* draft-ietf-mpls-lsp-ping-02.txt */ +#define BFD_CONTROL_PORT 3784 /* draft-katz-ward-bfd-v4v6-1hop-00.txt */ +#define BFD_ECHO_PORT 3785 /* draft-katz-ward-bfd-v4v6-1hop-00.txt */ +#define SFLOW_PORT 6343 /* http://www.sflow.org/developers/specifications.php */ +#define LWAPP_DATA_PORT 12222 /* draft-ohara-capwap-lwapp-04.txt */ +#define LWAPP_CONTROL_PORT 12223 /* draft-ohara-capwap-lwapp-04.txt */ + +#ifdef INET6 +#define RIPNG_PORT 521 /*XXX*/ +#define DHCP6_SERV_PORT 546 /*XXX*/ +#define DHCP6_CLI_PORT 547 /*XXX*/ +#endif diff --git a/util.c b/util.c new file mode 100644 index 0000000..a2ef36d --- /dev/null +++ b/util.c @@ -0,0 +1,608 @@ +/* + * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.109 2007-01-29 09:59:42 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include +#ifdef HAVE_FCNTL_H +#include +#endif +#include +#include +#include +#include +#include + +#include "interface.h" + +char * ts_format(register int, register int); + +/* + * Print out a null-terminated filename (or other ascii string). + * If ep is NULL, assume no truncation check is needed. + * Return true if truncated. + */ +int +fn_print(register const u_char *s, register const u_char *ep) +{ + register int ret; + register u_char c; + + ret = 1; /* assume truncated */ + while (ep == NULL || s < ep) { + c = *s++; + if (c == '\0') { + ret = 0; + break; + } + if (!isascii(c)) { + c = toascii(c); + putchar('M'); + putchar('-'); + } + if (!isprint(c)) { + c ^= 0x40; /* DEL to ?, others to alpha */ + putchar('^'); + } + putchar(c); + } + return(ret); +} + +/* + * Print out a counted filename (or other ascii string). + * If ep is NULL, assume no truncation check is needed. + * Return true if truncated. + */ +int +fn_printn(register const u_char *s, register u_int n, + register const u_char *ep) +{ + register u_char c; + + while (n > 0 && (ep == NULL || s < ep)) { + n--; + c = *s++; + if (!isascii(c)) { + c = toascii(c); + putchar('M'); + putchar('-'); + } + if (!isprint(c)) { + c ^= 0x40; /* DEL to ?, others to alpha */ + putchar('^'); + } + putchar(c); + } + return (n == 0) ? 0 : 1; +} + +/* + * Print out a null-padded filename (or other ascii string). + * If ep is NULL, assume no truncation check is needed. + * Return true if truncated. + */ +int +fn_printzp(register const u_char *s, register u_int n, + register const u_char *ep) +{ + register int ret; + register u_char c; + + ret = 1; /* assume truncated */ + while (n > 0 && (ep == NULL || s < ep)) { + n--; + c = *s++; + if (c == '\0') { + ret = 0; + break; + } + if (!isascii(c)) { + c = toascii(c); + putchar('M'); + putchar('-'); + } + if (!isprint(c)) { + c ^= 0x40; /* DEL to ?, others to alpha */ + putchar('^'); + } + putchar(c); + } + return (n == 0) ? 0 : ret; +} + +/* + * Format the timestamp + */ +char * +ts_format(register int sec, register int usec) +{ + static char buf[sizeof("00:00:00.000000")]; + (void)snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%06u", + sec / 3600, (sec % 3600) / 60, sec % 60, usec); + + return buf; +} + +/* + * Print the timestamp + */ +void +ts_print(register const struct timeval *tvp) +{ + register int s; + struct tm *tm; + time_t Time; + static unsigned b_sec; + static unsigned b_usec; + int d_usec; + int d_sec; + + switch (tflag) { + + case 0: /* Default */ + s = (tvp->tv_sec + thiszone) % 86400; + (void)printf("%s ", ts_format(s, tvp->tv_usec)); + break; + + case 1: /* No time stamp */ + break; + + case 2: /* Unix timeval style */ + (void)printf("%u.%06u ", + (unsigned)tvp->tv_sec, + (unsigned)tvp->tv_usec); + break; + + case 3: /* Microseconds since previous packet */ + case 5: /* Microseconds since first packet */ + if (b_sec == 0) { + /* init timestamp for first packet */ + b_usec = tvp->tv_usec; + b_sec = tvp->tv_sec; + } + + d_usec = tvp->tv_usec - b_usec; + d_sec = tvp->tv_sec - b_sec; + + while (d_usec < 0) { + d_usec += 1000000; + d_sec--; + } + + (void)printf("%s ", ts_format(d_sec, d_usec)); + + if (tflag == 3) { /* set timestamp for last packet */ + b_sec = tvp->tv_sec; + b_usec = tvp->tv_usec; + } + break; + + case 4: /* Default + Date*/ + s = (tvp->tv_sec + thiszone) % 86400; + Time = (tvp->tv_sec + thiszone) - s; + tm = gmtime (&Time); + if (!tm) + printf("Date fail "); + else + printf("%04d-%02d-%02d %s ", + tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, + ts_format(s, tvp->tv_usec)); + break; + } +} + +/* + * Print a relative number of seconds (e.g. hold time, prune timer) + * in the form 5m1s. This does no truncation, so 32230861 seconds + * is represented as 1y1w1d1h1m1s. + */ +void +relts_print(int secs) +{ + static const char *lengths[] = {"y", "w", "d", "h", "m", "s"}; + static const int seconds[] = {31536000, 604800, 86400, 3600, 60, 1}; + const char **l = lengths; + const int *s = seconds; + + if (secs == 0) { + (void)printf("0s"); + return; + } + if (secs < 0) { + (void)printf("-"); + secs = -secs; + } + while (secs > 0) { + if (secs >= *s) { + (void)printf("%d%s", secs / *s, *l); + secs -= (secs / *s) * *s; + } + s++; + l++; + } +} + +/* + * this is a generic routine for printing unknown data; + * we pass on the linefeed plus indentation string to + * get a proper output - returns 0 on error + */ + +int +print_unknown_data(const u_char *cp,const char *ident,int len) +{ + if (len < 0) { + printf("%sDissector error: print_unknown_data called with negative length", + ident); + return(0); + } + if (snapend - cp < len) + len = snapend - cp; + if (len < 0) { + printf("%sDissector error: print_unknown_data called with pointer past end of packet", + ident); + return(0); + } + hex_print(ident,cp,len); + return(1); /* everything is ok */ +} + +/* + * Convert a token value to a string; use "fmt" if not found. + */ +const char * +tok2strbuf(register const struct tok *lp, register const char *fmt, + register int v, char *buf, size_t bufsize) +{ + if (lp != NULL) { + while (lp->s != NULL) { + if (lp->v == v) + return (lp->s); + ++lp; + } + } + if (fmt == NULL) + fmt = "#%d"; + + (void)snprintf(buf, bufsize, fmt, v); + return (const char *)buf; +} + +/* + * Convert a token value to a string; use "fmt" if not found. + */ +const char * +tok2str(register const struct tok *lp, register const char *fmt, + register int v) +{ + static char buf[4][128]; + static int idx = 0; + char *ret; + + ret = buf[idx]; + idx = (idx+1) & 3; + return tok2strbuf(lp, fmt, v, ret, sizeof(buf[0])); +} + +/* + * Convert a bit token value to a string; use "fmt" if not found. + * this is useful for parsing bitfields, the output strings are seperated + * if the s field is positive. + */ +static char * +bittok2str_internal(register const struct tok *lp, register const char *fmt, + register int v, register int sep) +{ + static char buf[256]; /* our stringbuffer */ + int buflen=0; + register int rotbit; /* this is the bit we rotate through all bitpositions */ + register int tokval; + + while (lp != NULL && lp->s != NULL) { + tokval=lp->v; /* load our first value */ + rotbit=1; + while (rotbit != 0) { + /* + * lets AND the rotating bit with our token value + * and see if we have got a match + */ + if (tokval == (v&rotbit)) { + /* ok we have found something */ + buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s", + lp->s, sep ? ", " : ""); + break; + } + rotbit=rotbit<<1; /* no match - lets shift and try again */ + } + lp++; + } + + /* user didn't want string seperation - no need to cut off trailing seperators */ + if (!sep) { + return (buf); + } + + if (buflen != 0) { /* did we find anything */ + /* yep, set the the trailing zero 2 bytes before to eliminate the last comma & whitespace */ + buf[buflen-2] = '\0'; + return (buf); + } + else { + /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */ + if (fmt == NULL) + fmt = "#%d"; + (void)snprintf(buf, sizeof(buf), fmt, v); + return (buf); + } +} + +/* + * Convert a bit token value to a string; use "fmt" if not found. + * this is useful for parsing bitfields, the output strings are not seperated. + */ +char * +bittok2str_nosep(register const struct tok *lp, register const char *fmt, + register int v) +{ + return (bittok2str_internal(lp, fmt, v, 0)); +} + +/* + * Convert a bit token value to a string; use "fmt" if not found. + * this is useful for parsing bitfields, the output strings are comma seperated. + */ +char * +bittok2str(register const struct tok *lp, register const char *fmt, + register int v) +{ + return (bittok2str_internal(lp, fmt, v, 1)); +} + +/* + * Convert a value to a string using an array; the macro + * tok2strary() in is the public interface to + * this function and ensures that the second argument is + * correct for bounds-checking. + */ +const char * +tok2strary_internal(register const char **lp, int n, register const char *fmt, + register int v) +{ + static char buf[128]; + + if (v >= 0 && v < n && lp[v] != NULL) + return lp[v]; + if (fmt == NULL) + fmt = "#%d"; + (void)snprintf(buf, sizeof(buf), fmt, v); + return (buf); +} + +/* + * Convert a 32-bit netmask to prefixlen if possible + * the function returns the prefix-len; if plen == -1 + * then conversion was not possible; + */ + +int +mask2plen(u_int32_t mask) +{ + u_int32_t bitmasks[33] = { + 0x00000000, + 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, + 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000, + 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000, + 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, + 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000, + 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00, + 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, + 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff + }; + int prefix_len = 32; + + /* let's see if we can transform the mask into a prefixlen */ + while (prefix_len >= 0) { + if (bitmasks[prefix_len] == mask) + break; + prefix_len--; + } + return (prefix_len); +} + +#ifdef INET6 +int +mask62plen(const u_char *mask) +{ + u_char bitmasks[9] = { + 0x00, + 0x80, 0xc0, 0xe0, 0xf0, + 0xf8, 0xfc, 0xfe, 0xff + }; + int byte; + int cidr_len = 0; + + for (byte = 0; byte < 16; byte++) { + u_int bits; + + for (bits = 0; bits < (sizeof (bitmasks) / sizeof (bitmasks[0])); bits++) { + if (mask[byte] == bitmasks[bits]) { + cidr_len += bits; + break; + } + } + + if (mask[byte] != 0xff) + break; + } + return (cidr_len); +} +#endif /* INET6 */ + +/* VARARGS */ +void +error(const char *fmt, ...) +{ + va_list ap; + + (void)fprintf(stderr, "%s: ", program_name); + va_start(ap, fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + if (*fmt) { + fmt += strlen(fmt); + if (fmt[-1] != '\n') + (void)fputc('\n', stderr); + } + exit(1); + /* NOTREACHED */ +} + +/* VARARGS */ +void +warning(const char *fmt, ...) +{ + va_list ap; + + (void)fprintf(stderr, "%s: WARNING: ", program_name); + va_start(ap, fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + if (*fmt) { + fmt += strlen(fmt); + if (fmt[-1] != '\n') + (void)fputc('\n', stderr); + } +} + +/* + * Copy arg vector into a new buffer, concatenating arguments with spaces. + */ +char * +copy_argv(register char **argv) +{ + register char **p; + register u_int len = 0; + char *buf; + char *src, *dst; + + p = argv; + if (*p == 0) + return 0; + + while (*p) + len += strlen(*p++) + 1; + + buf = (char *)malloc(len); + if (buf == NULL) + error("copy_argv: malloc"); + + p = argv; + dst = buf; + while ((src = *p++) != NULL) { + while ((*dst++ = *src++) != '\0') + ; + dst[-1] = ' '; + } + dst[-1] = '\0'; + + return buf; +} + +/* + * On Windows, we need to open the file in binary mode, so that + * we get all the bytes specified by the size we get from "fstat()". + * On UNIX, that's not necessary. O_BINARY is defined on Windows; + * we define it as 0 if it's not defined, so it does nothing. + */ +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +char * +read_infile(char *fname) +{ + register int i, fd, cc; + register char *cp; + struct stat buf; + + fd = open(fname, O_RDONLY|O_BINARY); + if (fd < 0) + error("can't open %s: %s", fname, pcap_strerror(errno)); + + if (fstat(fd, &buf) < 0) + error("can't stat %s: %s", fname, pcap_strerror(errno)); + + cp = malloc((u_int)buf.st_size + 1); + if (cp == NULL) + error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1, + fname, pcap_strerror(errno)); + cc = read(fd, cp, (u_int)buf.st_size); + if (cc < 0) + error("read %s: %s", fname, pcap_strerror(errno)); + if (cc != buf.st_size) + error("short read %s (%d != %d)", fname, cc, (int)buf.st_size); + + close(fd); + /* replace "# comment" with spaces */ + for (i = 0; i < cc; i++) { + if (cp[i] == '#') + while (i < cc && cp[i] != '\n') + cp[i++] = ' '; + } + cp[cc] = '\0'; + return (cp); +} + +void +safeputs(const char *s, int maxlen) +{ + int idx = 0; + + while (*s && idx < maxlen) { + safeputchar(*s); + idx++; + s++; + } +} + +void +safeputchar(int c) +{ + unsigned char ch; + + ch = (unsigned char)(c & 0xff); + if (ch < 0x80 && isprint(ch)) + printf("%c", ch); + else + printf("\\0x%02x", ch); +} diff --git a/vfprintf.c b/vfprintf.c new file mode 100644 index 0000000..6f8407a --- /dev/null +++ b/vfprintf.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1995 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/vfprintf.c,v 1.6 2003-11-16 09:36:45 guy Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include +#include + +#include "interface.h" + +/* + * Stock 4.3 doesn't have vfprintf. + * This routine is due to Chris Torek. + */ +vfprintf(f, fmt, args) + FILE *f; + char *fmt; + va_list args; +{ + int ret; + + if ((f->_flag & _IOWRT) == 0) { + if (f->_flag & _IORW) + f->_flag |= _IOWRT; + else + return EOF; + } + ret = _doprnt(fmt, args, f); + return ferror(f) ? EOF : ret; +} diff --git a/win32/Include/Arpa/tftp.h b/win32/Include/Arpa/tftp.h new file mode 100644 index 0000000..6f21045 --- /dev/null +++ b/win32/Include/Arpa/tftp.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)tftp.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _ARPA_TFTP_H +#define _ARPA_TFTP_H + +/* + * Trivial File Transfer Protocol (IEN-133) + */ +#define SEGSIZE 512 /* data segment size */ + +/* + * Packet types. + */ +#define RRQ 01 /* read request */ +#define WRQ 02 /* write request */ +#define DATA 03 /* data packet */ +#define ACK 04 /* acknowledgement */ + +#ifdef ERROR +#undef ERROR +#define ERROR 05 /* error code */ +#endif + +struct tftphdr { + short th_opcode; /* packet type */ + union { + short tu_block; /* block # */ + short tu_code; /* error code */ + char tu_stuff[1]; /* request packet stuff */ + } th_u; + char th_data[1]; /* data or error string */ +}; + +#define th_block th_u.tu_block +#define th_code th_u.tu_code +#define th_stuff th_u.tu_stuff +#define th_msg th_data + +/* + * Error codes. + */ +#define EUNDEF 0 /* not defined */ +#define ENOTFOUND 1 /* file not found */ +#define EACCESS 2 /* access violation */ +#define ENOSPACE 3 /* disk full or allocation exceeded */ +#define EBADOP 4 /* illegal TFTP operation */ +#define EBADID 5 /* unknown transfer ID */ +#define EEXISTS 6 /* file already exists */ +#define ENOUSER 7 /* no such user */ + +#endif /* _ARPA_TFTP_H */ diff --git a/win32/Include/Netinet/in_systm.h b/win32/Include/Netinet/in_systm.h new file mode 100644 index 0000000..d9a7c3e --- /dev/null +++ b/win32/Include/Netinet/in_systm.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)in_systm.h 8.1 (Berkeley) 6/10/93 + */ + +/* + * Miscellaneous internetwork + * definitions for kernel. + */ + +/* + * Network types. + * + * Internally the system keeps counters in the headers with the bytes + * swapped so that VAX instructions will work on them. It reverses + * the bytes before transmission at each protocol level. The n_ types + * represent the types with the bytes in ``high-ender'' order. + */ +typedef u_short n_short; /* short as received from the net */ +typedef u_int n_long; /* long as received from the net */ + +typedef u_int n_time; /* ms since 00:00 GMT, byte rev */ + +#ifdef KERNEL +n_time iptime __P((void)); +#endif diff --git a/win32/Include/Netinet/ip.h b/win32/Include/Netinet/ip.h new file mode 100644 index 0000000..78dfa87 --- /dev/null +++ b/win32/Include/Netinet/ip.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ip.h 8.2 (Berkeley) 6/1/94 + */ +#ifndef WIN32 +#include +#else +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#define BIG_ENDIAN 4321 +#define BYTE_ORDER LITTLE_ENDIAN +#endif +#endif + +/* + * Definitions for internet protocol version 4. + * Per RFC 791, September 1981. + */ +#define IPVERSION 4 + +/* + * Structure of an internet header, naked of options. + * + * We declare ip_len and ip_off to be short, rather than u_short + * pragmatically since otherwise unsigned comparisons can result + * against negative integers quite easily, and fail in subtle ways. + */ +struct ip { +#if BYTE_ORDER == LITTLE_ENDIAN + u_char ip_hl:4, /* header length */ + ip_v:4; /* version */ +#endif +#if BYTE_ORDER == BIG_ENDIAN + u_char ip_v:4, /* version */ + ip_hl:4; /* header length */ +#endif + u_char ip_tos; /* type of service */ + short ip_len; /* total length */ + u_short ip_id; /* identification */ + short ip_off; /* fragment offset field */ +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + u_char ip_ttl; /* time to live */ + u_char ip_p; /* protocol */ + u_short ip_sum; /* checksum */ + struct in_addr ip_src,ip_dst; /* source and dest address */ +}; + +#define IP_MAXPACKET 65535 /* maximum packet size */ + +/* + * Definitions for IP type of service (ip_tos) + */ +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_RELIABILITY 0x04 + +/* + * Definitions for IP precedence (also in ip_tos) (hopefully unused) + */ +#define IPTOS_PREC_NETCONTROL 0xe0 +#define IPTOS_PREC_INTERNETCONTROL 0xc0 +#define IPTOS_PREC_CRITIC_ECP 0xa0 +#define IPTOS_PREC_FLASHOVERRIDE 0x80 +#define IPTOS_PREC_FLASH 0x60 +#define IPTOS_PREC_IMMEDIATE 0x40 +#define IPTOS_PREC_PRIORITY 0x20 +#define IPTOS_PREC_ROUTINE 0x00 + +/* + * Definitions for options. + */ +#define IPOPT_COPIED(o) ((o)&0x80) +#define IPOPT_CLASS(o) ((o)&0x60) +#define IPOPT_NUMBER(o) ((o)&0x1f) + +#define IPOPT_CONTROL 0x00 +#define IPOPT_RESERVED1 0x20 +#define IPOPT_DEBMEAS 0x40 +#define IPOPT_RESERVED2 0x60 + +#define IPOPT_EOL 0 /* end of option list */ +#define IPOPT_NOP 1 /* no operation */ + +#define IPOPT_RR 7 /* record packet route */ +#define IPOPT_TS 68 /* timestamp */ +#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */ +#define IPOPT_LSRR 131 /* loose source route */ +#define IPOPT_SATID 136 /* satnet id */ +#define IPOPT_SSRR 137 /* strict source route */ + +/* + * Offsets to fields in options other than EOL and NOP. + */ +#define IPOPT_OPTVAL 0 /* option ID */ +#define IPOPT_OLEN 1 /* option length */ +#define IPOPT_OFFSET 2 /* offset within option */ +#define IPOPT_MINOFF 4 /* min value of above */ + +/* + * Time stamp option structure. + */ +struct ip_timestamp { + u_char ipt_code; /* IPOPT_TS */ + u_char ipt_len; /* size of structure (variable) */ + u_char ipt_ptr; /* index of current entry */ +#if BYTE_ORDER == LITTLE_ENDIAN + u_char ipt_flg:4, /* flags, see below */ + ipt_oflw:4; /* overflow counter */ +#endif +#if BYTE_ORDER == BIG_ENDIAN + u_char ipt_oflw:4, /* overflow counter */ + ipt_flg:4; /* flags, see below */ +#endif + union ipt_timestamp { + n_long ipt_time[1]; + struct ipt_ta { + struct in_addr ipt_addr; + n_long ipt_time; + } ipt_ta[1]; + } ipt_timestamp; +}; + +/* flag bits for ipt_flg */ +#define IPOPT_TS_TSONLY 0 /* timestamps only */ +#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ +#define IPOPT_TS_PRESPEC 3 /* specified modules only */ + +/* bits for security (not byte swapped) */ +#define IPOPT_SECUR_UNCLASS 0x0000 +#define IPOPT_SECUR_CONFID 0xf135 +#define IPOPT_SECUR_EFTO 0x789a +#define IPOPT_SECUR_MMMM 0xbc4d +#define IPOPT_SECUR_RESTR 0xaf13 +#define IPOPT_SECUR_SECRET 0xd788 +#define IPOPT_SECUR_TOPSECRET 0x6bc5 + +/* + * Internet implementation parameters. + */ +#define MAXTTL 255 /* maximum time to live (seconds) */ +#define IPDEFTTL 64 /* default ttl, from RFC 1340 */ +#define IPFRAGTTL 60 /* time to live for frags, slowhz */ +#define IPTTLDEC 1 /* subtracted when forwarding */ + +#define IP_MSS 576 /* default maximum segment size */ diff --git a/win32/Include/errno.h b/win32/Include/errno.h new file mode 100644 index 0000000..7cf599f --- /dev/null +++ b/win32/Include/errno.h @@ -0,0 +1,132 @@ +#ifndef _I386_ERRNO_H +#define _I386_ERRNO_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ + +#endif diff --git a/win32/Include/getopt.h b/win32/Include/getopt.h new file mode 100644 index 0000000..b439ab1 --- /dev/null +++ b/win32/Include/getopt.h @@ -0,0 +1,138 @@ +/* Declarations for getopt. + Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. + +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _GETOPT_H +#define _GETOPT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +#ifndef WIN32 +extern char *optarg; +#endif + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +#ifndef WIN32 +extern int optind; +#endif + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +#ifndef WIN32 +extern int opterr; +#endif + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +#if __STDC__ + const char *name; +#else + char *name; +#endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#if __STDC__ +#if defined(__GNU_LIBRARY__) +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); +#else /* not __GNU_LIBRARY__ */ +extern int getopt (); +#endif /* not __GNU_LIBRARY__ */ +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); +#else /* not __STDC__ */ +extern int getopt (); +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +#endif /* not __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* _GETOPT_H */ diff --git a/win32/Include/inetprivate.h b/win32/Include/inetprivate.h new file mode 100644 index 0000000..1052acf --- /dev/null +++ b/win32/Include/inetprivate.h @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +//#include + +#include + +extern void _sethtent(int f); +extern void _endhtent(void); +extern struct hostent *_gethtent(void); +extern struct hostent *_gethtbyname(const char *name); +extern struct hostent *_gethtbyaddr(const char *addr, int len, + int type); +extern int _validuser(FILE *hostf, const char *rhost, + const char *luser, const char *ruser, int baselen); +extern int _checkhost(const char *rhost, const char *lhost, int len); +#if 0 +extern void putlong(u_long l, u_char *msgp); +extern void putshort(u_short l, u_char *msgp); +extern u_int32_t _getlong(register const u_char *msgp); +extern u_int16_t _getshort(register const u_char *msgp); +extern void p_query(char *msg); +extern void fp_query(char *msg, FILE *file); +extern char *p_cdname(char *cp, char *msg, FILE *file); +extern char *p_rr(char *cp, char *msg, FILE *file); +extern char *p_type(int type); +extern char * p_class(int class); +extern char *p_time(u_long value); +#endif +extern char * hostalias(const char *name); +extern void sethostfile(char *name); +extern void _res_close (void); +extern void ruserpass(const char *host, char **aname, char **apass); diff --git a/win32/Include/telnet.h b/win32/Include/telnet.h new file mode 100644 index 0000000..3309e5d --- /dev/null +++ b/win32/Include/telnet.h @@ -0,0 +1,320 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)telnet.h 8.2 (Berkeley) 12/15/93 + */ + +#ifndef _ARPA_TELNET_H +#define _ARPA_TELNET_H 1 + +/* + * Definitions for the TELNET protocol. + */ +#define IAC 255 /* interpret as command: */ +#define DONT 254 /* you are not to use option */ +#define DO 253 /* please, you use option */ +#define WONT 252 /* I won't use option */ +#define WILL 251 /* I will use option */ +#define SB 250 /* interpret as subnegotiation */ +#define GA 249 /* you may reverse the line */ +#define EL 248 /* erase the current line */ +#define EC 247 /* erase the current character */ +#define AYT 246 /* are you there */ +#define AO 245 /* abort output--but let prog finish */ +#define IP 244 /* interrupt process--permanently */ +#define BREAK 243 /* break */ +#define DM 242 /* data mark--for connect. cleaning */ +#define NOP 241 /* nop */ +#define SE 240 /* end sub negotiation */ +#define EOR 239 /* end of record (transparent mode) */ +#define ABORT 238 /* Abort process */ +#define SUSP 237 /* Suspend process */ +#define xEOF 236 /* End of file: EOF is already used... */ + +#define SYNCH 242 /* for telfunc calls */ + +#ifdef TELCMDS +char *telcmds[] = { + "EOF", "SUSP", "ABORT", "EOR", + "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC", + "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0, +}; +#else +extern char *telcmds[]; +#endif + +#define TELCMD_FIRST xEOF +#define TELCMD_LAST IAC +#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \ + (unsigned int)(x) >= TELCMD_FIRST) +#define TELCMD(x) telcmds[(x)-TELCMD_FIRST] + +/* telnet options */ +#define TELOPT_BINARY 0 /* 8-bit data path */ +#define TELOPT_ECHO 1 /* echo */ +#define TELOPT_RCP 2 /* prepare to reconnect */ +#define TELOPT_SGA 3 /* suppress go ahead */ +#define TELOPT_NAMS 4 /* approximate message size */ +#define TELOPT_STATUS 5 /* give status */ +#define TELOPT_TM 6 /* timing mark */ +#define TELOPT_RCTE 7 /* remote controlled transmission and echo */ +#define TELOPT_NAOL 8 /* negotiate about output line width */ +#define TELOPT_NAOP 9 /* negotiate about output page size */ +#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */ +#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */ +#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */ +#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */ +#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */ +#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */ +#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */ +#define TELOPT_XASCII 17 /* extended ascii character set */ +#define TELOPT_LOGOUT 18 /* force logout */ +#define TELOPT_BM 19 /* byte macro */ +#define TELOPT_DET 20 /* data entry terminal */ +#define TELOPT_SUPDUP 21 /* supdup protocol */ +#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */ +#define TELOPT_SNDLOC 23 /* send location */ +#define TELOPT_TTYPE 24 /* terminal type */ +#define TELOPT_EOR 25 /* end or record */ +#define TELOPT_TUID 26 /* TACACS user identification */ +#define TELOPT_OUTMRK 27 /* output marking */ +#define TELOPT_TTYLOC 28 /* terminal location number */ +#define TELOPT_3270REGIME 29 /* 3270 regime */ +#define TELOPT_X3PAD 30 /* X.3 PAD */ +#define TELOPT_NAWS 31 /* window size */ +#define TELOPT_TSPEED 32 /* terminal speed */ +#define TELOPT_LFLOW 33 /* remote flow control */ +#define TELOPT_LINEMODE 34 /* Linemode option */ +#define TELOPT_XDISPLOC 35 /* X Display Location */ +#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */ +#define TELOPT_AUTHENTICATION 37/* Authenticate */ +#define TELOPT_ENCRYPT 38 /* Encryption option */ +#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */ +#define TELOPT_EXOPL 255 /* extended-options-list */ + + +#define NTELOPTS (1+TELOPT_NEW_ENVIRON) +#ifdef TELOPTS +char *telopts[NTELOPTS+1] = { + "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME", + "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP", + "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS", + "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO", + "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT", + "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD", + "TACACS UID", "OUTPUT MARKING", "TTYLOC", + "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW", + "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION", + "ENCRYPT", "NEW-ENVIRON", + 0, +}; +#define TELOPT_FIRST TELOPT_BINARY +#define TELOPT_LAST TELOPT_NEW_ENVIRON +#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST) +#define TELOPT(x) telopts[(x)-TELOPT_FIRST] +#endif + +/* sub-option qualifiers */ +#define TELQUAL_IS 0 /* option is... */ +#define TELQUAL_SEND 1 /* send option */ +#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */ +#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */ +#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */ + +#define LFLOW_OFF 0 /* Disable remote flow control */ +#define LFLOW_ON 1 /* Enable remote flow control */ +#define LFLOW_RESTART_ANY 2 /* Restart output on any char */ +#define LFLOW_RESTART_XON 3 /* Restart output only on XON */ + +/* + * LINEMODE suboptions + */ + +#define LM_MODE 1 +#define LM_FORWARDMASK 2 +#define LM_SLC 3 + +#define MODE_EDIT 0x01 +#define MODE_TRAPSIG 0x02 +#define MODE_ACK 0x04 +#define MODE_SOFT_TAB 0x08 +#define MODE_LIT_ECHO 0x10 + +#define MODE_MASK 0x1f + +/* Not part of protocol, but needed to simplify things... */ +#define MODE_FLOW 0x0100 +#define MODE_ECHO 0x0200 +#define MODE_INBIN 0x0400 +#define MODE_OUTBIN 0x0800 +#define MODE_FORCE 0x1000 + +#define SLC_SYNCH 1 +#define SLC_BRK 2 +#define SLC_IP 3 +#define SLC_AO 4 +#define SLC_AYT 5 +#define SLC_EOR 6 +#define SLC_ABORT 7 +#define SLC_EOF 8 +#define SLC_SUSP 9 +#define SLC_EC 10 +#define SLC_EL 11 +#define SLC_EW 12 +#define SLC_RP 13 +#define SLC_LNEXT 14 +#define SLC_XON 15 +#define SLC_XOFF 16 +#define SLC_FORW1 17 +#define SLC_FORW2 18 + +#define NSLC 18 + +/* + * For backwards compatibility, we define SLC_NAMES to be the + * list of names if SLC_NAMES is not defined. + */ +#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \ + "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \ + "LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0, +#ifdef SLC_NAMES +char *slc_names[] = { + SLC_NAMELIST +}; +#else +extern char *slc_names[]; +#define SLC_NAMES SLC_NAMELIST +#endif + +#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC) +#define SLC_NAME(x) slc_names[x] + +#define SLC_NOSUPPORT 0 +#define SLC_CANTCHANGE 1 +#define SLC_VARIABLE 2 +#define SLC_DEFAULT 3 +#define SLC_LEVELBITS 0x03 + +#define SLC_FUNC 0 +#define SLC_FLAGS 1 +#define SLC_VALUE 2 + +#define SLC_ACK 0x80 +#define SLC_FLUSHIN 0x40 +#define SLC_FLUSHOUT 0x20 + +#define OLD_ENV_VAR 1 +#define OLD_ENV_VALUE 0 +#define NEW_ENV_VAR 0 +#define NEW_ENV_VALUE 1 +#define ENV_ESC 2 +#define ENV_USERVAR 3 + +/* + * AUTHENTICATION suboptions + */ + +/* + * Who is authenticating who ... + */ +#define AUTH_WHO_CLIENT 0 /* Client authenticating server */ +#define AUTH_WHO_SERVER 1 /* Server authenticating client */ +#define AUTH_WHO_MASK 1 + +/* + * amount of authentication done + */ +#define AUTH_HOW_ONE_WAY 0 +#define AUTH_HOW_MUTUAL 2 +#define AUTH_HOW_MASK 2 + +#define AUTHTYPE_NULL 0 +#define AUTHTYPE_KERBEROS_V4 1 +#define AUTHTYPE_KERBEROS_V5 2 +#define AUTHTYPE_SPX 3 +#define AUTHTYPE_MINK 4 +#define AUTHTYPE_CNT 5 + +#define AUTHTYPE_TEST 99 + +#ifdef AUTH_NAMES +char *authtype_names[] = { + "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0, +}; +#else +extern char *authtype_names[]; +#endif + +#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT) +#define AUTHTYPE_NAME(x) authtype_names[x] + +/* + * ENCRYPTion suboptions + */ +#define ENCRYPT_IS 0 /* I pick encryption type ... */ +#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */ +#define ENCRYPT_REPLY 2 /* Initial setup response */ +#define ENCRYPT_START 3 /* Am starting to send encrypted */ +#define ENCRYPT_END 4 /* Am ending encrypted */ +#define ENCRYPT_REQSTART 5 /* Request you start encrypting */ +#define ENCRYPT_REQEND 6 /* Request you send encrypting */ +#define ENCRYPT_ENC_KEYID 7 +#define ENCRYPT_DEC_KEYID 8 +#define ENCRYPT_CNT 9 + +#define ENCTYPE_ANY 0 +#define ENCTYPE_DES_CFB64 1 +#define ENCTYPE_DES_OFB64 2 +#define ENCTYPE_CNT 3 + +#ifdef ENCRYPT_NAMES +char *encrypt_names[] = { + "IS", "SUPPORT", "REPLY", "START", "END", + "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID", + 0, +}; +char *enctype_names[] = { + "ANY", "DES_CFB64", "DES_OFB64", 0, +}; +#else +extern char *encrypt_names[]; +extern char *enctype_names[]; +#endif + + +#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT) +#define ENCRYPT_NAME(x) encrypt_names[x] + +#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT) +#define ENCTYPE_NAME(x) enctype_names[x] + +#endif /* arpa/telnet.h */ diff --git a/win32/Include/w32_fzs.h b/win32/Include/w32_fzs.h new file mode 100644 index 0000000..8b5e598 --- /dev/null +++ b/win32/Include/w32_fzs.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 1999 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _WINSOCKAPI_ +#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */ +#endif /* _WINSOCKAPI_ */ +#include +#include + +extern int progress; +int wsockinit(); +void InitP(); +void PrintCapBegins (char* program_name, char* device); +extern char* AdapterName1; +#ifndef WIN95 +WCHAR* SChar2WChar(char* nome); +#else +BOOLEAN StartPacketDriver(LPTSTR ServiceName); +#endif diff --git a/win32/Src/getopt.c b/win32/Src/getopt.c new file mode 100644 index 0000000..be74ef0 --- /dev/null +++ b/win32/Src/getopt.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +int opterr = 1, /* if error message should be printed */ + optind = 1, /* index into parent argv vector */ + optopt, /* character checked for validity */ + optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +getopt(nargc, nargv, ostr) + int nargc; + char * const *nargv; + const char *ostr; +{ + extern char *program_name; + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return (-1); + } + if (place[1] && *++place == '-') { /* found "--" */ + ++optind; + place = EMSG; + return (-1); + } + } /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' || + !(oli = strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means -1. + */ + if (optopt == (int)'-') + return (-1); + if (!*place) + ++optind; + if (opterr && *ostr != ':') + (void)fprintf(stderr, + "%s: illegal option -- %c\n", program_name, optopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } + else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if (*ostr == ':') + return (BADARG); + if (opterr) + (void)fprintf(stderr, + "%s: option requires an argument -- %c\n", + program_name, optopt); + return (BADCH); + } + else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return (optopt); /* dump back option letter */ +} diff --git a/win32/prj/GNUmakefile b/win32/prj/GNUmakefile new file mode 100644 index 0000000..9f13675 --- /dev/null +++ b/win32/prj/GNUmakefile @@ -0,0 +1,177 @@ +# Makefile for cygwin gcc +# Nate Lawson + +# Location of your pcap src tree, build it first +PCAP_DIR = ../../../winpcap + +# OPTFLAGS = -g +OPTFLAGS = -O +# -O2 may break things. Use at your own risk. + +CFLAGS = -I ${PCAP_DIR}/wpcap/libpcap/bpf \ + -I ${PCAP_DIR}/wpcap/libpcap \ + -I ${PCAP_DIR}/wpcap/libpcap/Win32/Include \ + -I ${PCAP_DIR}/wpcap/libpcap/Win32/Include/net \ + -I ../../Win32/Include -I ../../linux-Include \ + -I ../../lbl -I../.. \ + -DWIN32 -DINET6 -DHAVE_ADDRINFO=1 -DHAVE_SOCKADDR_STORAGE=1 \ + -DHAVE_PCAP_LIST_DATALINKS=1 -DHAVE_PCAP_SET_DATALINK=1 \ + -DHAVE_PCAP_DATALINK_NAME_TO_VAL=1 \ + -DHAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION=1 \ + -DHAVE_PCAP_DUMP_FTELL=1 -DHAVE_BPF_DUMP=1 \ + -DHAVE_PCAP_DUMP_FLUSH=1 -DHAVE_PCAP_FINDALLDEVS=1 \ + -DHAVE_PCAP_IF_T=1 -DHAVE_PCAP_LIB_VERSION=1 \ + -DSIZEOF_CHAR=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 \ + -DSIZEOF_LONG_LONG=8 \ + -D_U_="__attribute__((unused))" \ + -D_WIN32_WINNT=0x0501 \ + -mno-cygwin ${OPTFLAGS} +LDFLAGS = +LIBS = -L ${PCAP_DIR}/WPCAP/LIB -lwpcap -lws2_32 +OBJS = \ + ../../addrtoname.o \ + ../../af.o \ + ../../checksum.o \ + ../../gmpls.o \ + ../../gmt2local.o \ + ../../missing/inet_aton.o \ + ../../missing/inet_ntop.o \ + ../../missing/strlcpy.o \ + ../../missing/dlnames.o \ + ../../missing/datalinks.o \ + ../../missing/strsep.o \ + ../../missing/inet_pton.o \ + ../../machdep.o \ + ../../oui.o \ + ../../parsenfsfh.o \ + ../../print-802_11.o \ + ../../print-ah.o \ + ../../print-aodv.o \ + ../../print-ap1394.o \ + ../../print-arcnet.o \ + ../../print-arp.o \ + ../../print-ascii.o \ + ../../print-atalk.o \ + ../../print-atm.o \ + ../../print-beep.o \ + ../../print-bfd.o \ + ../../print-bgp.o \ + ../../print-bootp.o \ + ../../print-cdp.o \ + ../../print-cfm.o \ + ../../print-chdlc.o \ + ../../print-cip.o \ + ../../print-cnfp.o \ + ../../print-decnet.o \ + ../../print-dhcp6.o \ + ../../print-domain.o \ + ../../print-dtp.o \ + ../../print-dvmrp.o \ + ../../print-egp.o \ + ../../print-enc.o \ + ../../print-esp.o \ + ../../print-ether.o \ + ../../print-fddi.o \ + ../../print-fr.o \ + ../../print-frag6.o \ + ../../print-gre.o \ + ../../print-hsrp.o \ + ../../print-icmp.o \ + ../../print-icmp6.o \ + ../../print-igmp.o \ + ../../print-igrp.o \ + ../../print-ip.o \ + ../../print-ip6.o \ + ../../print-ip6opts.o \ + ../../print-ipcomp.o \ + ../../print-ipfc.o \ + ../../print-ipx.o \ + ../../print-isakmp.o \ + ../../print-isoclns.o \ + ../../print-krb.o \ + ../../print-l2tp.o \ + ../../print-lane.o \ + ../../print-ldp.o \ + ../../print-lldp.o \ + ../../print-llc.o \ + ../../print-lwapp.o \ + ../../print-lwres.o \ + ../../print-mobile.o \ + ../../print-mobility.o \ + ../../print-mpcp.o \ + ../../print-mpls.o \ + ../../print-msdp.o \ + ../../print-nfs.o \ + ../../print-ntp.o \ + ../../print-null.o \ + ../../print-olsr.o \ + ../../print-ospf.o \ + ../../print-ospf6.o \ + ../../print-pim.o \ + ../../print-pgm.o \ + ../../print-ppp.o \ + ../../print-pppoe.o \ + ../../print-pptp.o \ + ../../print-radius.o \ + ../../print-raw.o \ + ../../print-rrcp.o \ + ../../print-rip.o \ + ../../print-ripng.o \ + ../../print-rsvp.o \ + ../../print-rt6.o \ + ../../print-rx.o \ + ../../print-sctp.o \ + ../../print-sflow.o \ + ../../print-sl.o \ + ../../print-sll.o \ + ../../print-slow.o \ + ../../print-smb.o \ + ../../print-snmp.o \ + ../../print-stp.o \ + ../../print-sunatm.o \ + ../../print-sunrpc.o \ + ../../print-symantec.o \ + ../../print-tcp.o \ + ../../print-telnet.o \ + ../../print-tftp.o \ + ../../print-timed.o \ + ../../print-token.o \ + ../../print-udld.o \ + ../../print-udp.o \ + ../../print-vjc.o \ + ../../print-vqp.o \ + ../../print-vrrp.o \ + ../../print-vtp.o \ + ../../print-wb.o \ + ../../print-zephyr.o \ + ../../setsignal.o \ + ../../smbutil.o \ + ../../tcpdump.o \ + ../../util.o \ + ../../Win32/src/getopt.o \ + ../../cpack.o \ + ../../ipproto.o \ + ../../l2vpn.o \ + ../../nlpid.o \ + ../../print-eigrp.o \ + ../../print-juniper.o \ + ../../print-lspping.o \ + ../../print-sip.o \ + ../../print-eap.o \ + ../../print-lmp.o \ + ../../print-syslog.o \ + ../../print-dccp.o \ + ../../print-bt.o \ + ../../signature.o + +main: ${OBJS} + ${CC} ${CFLAGS} ${LDFLAGS} -o windump.exe ${OBJS} ${LIBS} + +install: windump.exe + cp windump.exe c:/windows + +clean: + rm -f ${OBJS} windump.exe + +.c.o: + ${CC} ${CFLAGS} -o $*.o -c $< diff --git a/win32/prj/WinDump.dsp b/win32/prj/WinDump.dsp new file mode 100644 index 0000000..9bb9b47 --- /dev/null +++ b/win32/prj/WinDump.dsp @@ -0,0 +1,635 @@ +# Microsoft Developer Studio Project File - Name="WinDump" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=WinDump - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "WinDump.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "WinDump.mak" CFG="WinDump - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "WinDump - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "WinDump - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 1 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "WinDump - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "../../" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../winpcap/wpcap/libpcap/bpf" /I "../../../winpcap/wpcap/libpcap" /I "../../../winpcap/wpcap/libpcap/Win32/Include" /I "../../../winpcap/wpcap/libpcap/Win32/Include/net" /I "../../Win32/Include" /I "../../linux-Include" /I "../../lbl" /I "../../" /I "../../../winpcap/wpcap/win32-extensions" /D "NDEBUG" /D "INET6" /D "WIN32" /D "_MBCS" /D "_CONSOLE" /D "__STDC__" /D "WPCAP" /D HAVE_ADDRINFO=1 /D HAVE_SOCKADDR_STORAGE=1 /D HAVE_PCAP_LIST_DATALINKS=1 /D HAVE_PCAP_SET_DATALINK=1 /D HAVE_PCAP_DATALINK_NAME_TO_VAL=1 /D HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION=1 /D HAVE_PCAP_DUMP_FTELL=1 /D HAVE_BPF_DUMP=1 /D HAVE_PCAP_DUMP_FLUSH=1 /D HAVE_PCAP_FINDALLDEVS=1 /D HAVE_PCAP_IF_T=1 /D HAVE_PCAP_LIB_VERSION=1 /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_REMOTE" /D _U_= /YX /FD /c +# ADD BASE RSC /l 0x410 /d "NDEBUG" +# ADD RSC /l 0x410 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib wpcap.lib /nologo /subsystem:console /machine:I386 /out:"release/WinDump.exe" /libpath:"../../../winpcap/wpcap/lib" + +!ELSEIF "$(CFG)" == "WinDump - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "WinDump_" +# PROP BASE Intermediate_Dir "WinDump_" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "../../" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /Gm /Gi /GX /ZI /I "../../../winpcap/wpcap/libpcap/bpf" /I "../../../winpcap/wpcap/libpcap" /I "../../../winpcap/wpcap/libpcap/Win32/Include" /I "../../../winpcap/wpcap/libpcap/Win32/Include/net" /I "../../Win32/Include" /I "../../linux-Include" /I "../../lbl" /I "../../" /I "../../../winpcap/wpcap/win32-extensions" /D "_DEBUG" /D "_WINDOWS" /D "INET6" /D "WIN32" /D "_MBCS" /D "_CONSOLE" /D "__STDC__" /D "WPCAP" /D HAVE_ADDRINFO=1 /D HAVE_SOCKADDR_STORAGE=1 /D HAVE_PCAP_LIST_DATALINKS=1 /D HAVE_PCAP_SET_DATALINK=1 /D HAVE_PCAP_DATALINK_NAME_TO_VAL=1 /D HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION=1 /D HAVE_PCAP_DUMP_FTELL=1 /D HAVE_BPF_DUMP=1 /D HAVE_PCAP_DUMP_FLUSH=1 /D HAVE_PCAP_FINDALLDEVS=1 /D HAVE_PCAP_IF_T=1 /D HAVE_PCAP_LIB_VERSION=1 /D SIZEOF_CHAR=1 /D SIZEOF_SHORT=2 /D SIZEOF_INT=4 /D "HAVE_REMOTE" /D _U_= /FR /YX /FD /c +# ADD BASE RSC /l 0x410 /d "_DEBUG" +# ADD RSC /l 0x410 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 wpcap.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /map /debug /debugtype:both /machine:I386 /out:"debug/WinDump.exe" /pdbtype:sept /libpath:"../../../winpcap/wpcap/lib" +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "WinDump - Win32 Release" +# Name "WinDump - Win32 Debug" +# Begin Source File + +SOURCE=..\..\addrtoname.c +# End Source File +# Begin Source File + +SOURCE=..\..\af.c +# End Source File +# Begin Source File + +SOURCE=..\..\bpf_dump.c +# End Source File +# Begin Source File + +SOURCE=..\..\checksum.c +# End Source File +# Begin Source File + +SOURCE=..\..\cpack.c +# End Source File +# Begin Source File + +SOURCE=..\..\missing\datalinks.c +# End Source File +# Begin Source File + +SOURCE=..\..\missing\dlnames.c +# End Source File +# Begin Source File + +SOURCE=..\Src\getopt.c +# End Source File +# Begin Source File + +SOURCE=..\..\gmpls.c +# End Source File +# Begin Source File + +SOURCE=..\..\gmt2local.c +# End Source File +# Begin Source File + +SOURCE=..\..\missing\inet_aton.c +# End Source File +# Begin Source File + +SOURCE=..\..\missing\inet_ntop.c +# End Source File +# Begin Source File + +SOURCE=..\..\missing\inet_pton.c +# End Source File +# Begin Source File + +SOURCE=..\..\ipproto.c +# End Source File +# Begin Source File + +SOURCE=..\..\l2vpn.c +# End Source File +# Begin Source File + +SOURCE=..\..\machdep.c +# End Source File +# Begin Source File + +SOURCE=..\..\nlpid.c +# End Source File +# Begin Source File + +SOURCE=..\..\oui.c +# End Source File +# Begin Source File + +SOURCE=..\..\parsenfsfh.c +# End Source File +# Begin Source File + +SOURCE="..\..\print-802_11.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ah.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-aodv.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ap1394.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-arcnet.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-arp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ascii.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-atalk.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-atm.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-beep.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-bfd.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-bgp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-bootp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-bt.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-cdp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-cfm.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-chdlc.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-cip.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-cnfp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-dccp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-decnet.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-dhcp6.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-domain.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-dtp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-dvmrp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-eap.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-egp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-eigrp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-enc.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-esp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ether.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-fddi.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-fr.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-frag6.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-gre.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-hsrp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-icmp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-icmp6.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-igmp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-igrp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ip.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ip6.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ip6opts.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ipcomp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ipfc.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ipx.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-isakmp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-isoclns.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-juniper.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-krb.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-l2tp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-lane.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ldp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-llc.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-lldp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-lmp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-lspping.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-lwapp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-lwres.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-mobile.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-mobility.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-mpcp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-mpls.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-msdp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-netbios.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-nfs.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ntp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-null.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-olsr.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ospf.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ospf6.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-pgm.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-pim.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ppp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-pppoe.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-pptp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-radius.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-raw.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-rrcp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-rip.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-ripng.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-rsvp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-rt6.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-rx.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-sctp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-sflow.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-sip.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-sl.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-sll.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-slow.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-smb.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-snmp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-stp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-sunatm.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-sunrpc.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-symantec.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-syslog.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-tcp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-telnet.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-tftp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-timed.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-token.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-udld.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-udp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-vjc.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-vqp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-vrrp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-vtp.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-wb.c" +# End Source File +# Begin Source File + +SOURCE="..\..\print-zephyr.c" +# End Source File +# Begin Source File + +SOURCE=..\..\setsignal.c +# End Source File +# Begin Source File + +SOURCE=..\..\smbutil.c +# End Source File +# Begin Source File + +SOURCE=..\..\strcasecmp.c +# End Source File +# Begin Source File + +SOURCE=..\..\missing\strlcat.c +# End Source File +# Begin Source File + +SOURCE=..\..\missing\strlcpy.c +# End Source File +# Begin Source File + +SOURCE=..\..\missing\strsep.c +# End Source File +# Begin Source File + +SOURCE=..\..\Tcpdump.c +# End Source File +# Begin Source File + +SOURCE=..\..\util.c +# End Source File +# End Target +# End Project diff --git a/win32/prj/WinDump.dsw b/win32/prj/WinDump.dsw new file mode 100644 index 0000000..6bf7408 --- /dev/null +++ b/win32/prj/WinDump.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "WinDump"=".\WinDump.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + -- 2.7.4

    A&:ICVPTC,L**@XNU[]B4PRBC)U=6.ZI'DF-8I;)'C$] +MEEL9P5LE*VKX7!^,(^I$(X9CU.-E[U%5%K\+Y$(H?"6,8N)ES,B+E/>P'AL; +M5;V%^2G5WN^L(3[:\2S<6>#A\SY+QDDI```D41+/BV%)?$+)QIXY*#Z'&+T[ +M;N5._Y#$J#0<:0ED0-_ +M8E,,HHR=75CNJ1Y)C6*6R1XQ/99;&<%;)2MJ^%P?C"/J1".&8]3C9>]151:_ +M"^1"*'PEC&+B9.2@^AQB].V[E3O^0Q*@T'&D)9$#7*0``'```0`2TQ9Q! +M2+NYH'&>AI065]E:@)`SN +M$K=&==(-`)@!``"8`0```@```$4``91M!P``0!$``,"H`0'`J`$"`?0!]`&` +M!V4.8L$=AYG($```````````(2`B"`````````%X(@``>````'0!`0@,`P`` +M#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```( +M`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4# +M```(!````@````@$```.*```B``"``#G)\Z@LCG*=0A\08<6#*H&)&A;C&G( +M^S?]S!Z$9JF/;#2,RPHJ#B[7OV)3#**,G5U8[JD>28UBELD>,3V66QG!6R4K +M:OA<'XPCZD0CAF/4XV7O4546OPOD0BA\)8QBXF7,R(N4][`>&QM5O87Y*=7> +M[ZPA/MKQ+-Q9X.'S/DO&22D``"11$L^+84E\0LG&GCDH/H<8O3MNY4[_D,2H +M-!QI"61`URD``!P``$`$M,6<04B[N:!QGH:4%E?96H'+=$\````<``!`!4R. +M^V>J"-7;7-^9,TMT5?>O'B0,[Q*W1H/@"P"8`0``F`$```(```!%``&4;0D` +M`$`1``#`J`$!P*@!`@'T`?0!@`=E\#E9-<3I$R8``````````"$@(@@````` +M```!>"(``'@```!T`0$)#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``:R@* +MWG'2Q,%(#V&;-LI2"_7'BI#\@-3-*RS_\+O3JBUG8YTP)H/>;PNH*:@KDF;] +MP7^_F$F_>N9ZA:\=!EJ`JSJ8/^9$[I`59=:]YX65&^^5)U"*T)GC11CFBMU#[X:0I```DL1*+-M7< +M"3OZ*'%/`B"K%V^6HGBE/KV*F_IKEW\8LIP_4S)JI]A5 +MD]NUEO.R=`&?````'```0`4,01H6[^FN9,-`Q+TKL\9LD]D&2^\2MT;`"@\` +MF`$``)@!```"````10`!E&T*``!`$0``P*@!`<"H`0(!]`'T`8`'9?`Y637$ +MZ1,F```````````A("((`````````7@B``!X````=`$!"0P#```,`0``#(`. +M`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P`` +M"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```" +M````"`0```XH``"(``(``&LH"MYQTL3!2`]AFS;*4@OUQXJ0_(#4S2LL__"[ +MTZHM9V.=,":#WF\+J"FH*Y)F_<%_OYA)OWKF>H6O'09:@*LZF#_F1.Z0%676 +MO>>%E1G,'.<;B((E$0"TN89E1VF!!#JI]7,*LG!`YRDI8B/^'OOE2=0BM"9X +MT48YHK=0^^&D*0``)+$2BS;5W`D[^BAQ3P(@JQ=OEJ)XI3Z]BIOZ:Y=_&+*7 +M*0``'```0`2.`*7L/U,R:J?859/;M9;SLG0!GP```!P``$`%#$$:%N_IKF3# +M0,2]*[/&;)/9!DOP$K=&3@H&`)@!``"8`0```@```$4``91M#P``0!$``,"H +M`0'`J`$"`?0!]`&`!V7P.5DUQ.D3)@``````````(2`B"`````````%X(@`` +M>````'0!`0D,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#` +M`P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@# +M```!`P``"`,```4#```(!````@````@$```.*```B``"``!K*`K><=+$P4@/ +M89LVRE(+]<>*D/R`U,TK+/_PN].J+6=CG3`F@]YO"Z@IJ"N29OW!?[^82;]Z +MYGJ%KQT&6H"K.I@_YD3ND!5EUKWGA949S!SG&XB")1$`M+F&94=I@00ZJ?5S +M"K)P0.-%&.:*W4/OAI"D``"2Q$HLVU=P)._HH<4\" +M(*L7;Y:B>*4^O8J;^FN7?QBRERD``!P``$`$C@"E[#]3,FJGV%63V[66\[)T +M`9\````<``!`!0Q!&A;OZ:YDPT#$O2NSQFR3V09+\1*W1O`4!`"8`0``F`$` +M``(```!%``&4;14``$`1``#`J`$!P*@!`@'T`?0!@`=E]7Z9DU&>E,$````` +M`````"$@(@@````````!>"(``'@```!T`0'W#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``J)KPN[80LY(4K$(F=-.T]/5[`F(6'9-:>RBRL[]$"*'K.=8; +M-G'U^%I\B?V8EXZFR5S+WR=M$;BG@(S=&O%`B&K8^.IN6EJ/4=9$*-^66N*R +MNL69T*!5%1[$SW8$`<=/ZKLO\IZAS:.!`$.8S5>GU;08-1)AV-SN>;1!5_P\ +MK87S4I:RZOH"U6-H==AW$#%P(_UY8]'6+\-VSGSL=````'```0`4&Y,-B_QN13%:%EXME+W5B +M3A:D0/$2MT::0@<`F`$``)@!```"````10`!E&T6``!`$0``P*@!`<"H`0(! +M]`'T`8`'9?5^F9-1GI3!```````````A("((`````````7@B``!X````=`$! +M]PP#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0`` +M`P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```( +M`P``!0,```@$```"````"`0```XH``"(``(``*B:\+NV$+.2%*Q")G33M/3U +M>P)B%AV36GLHLK._1`BAZSG6&S9Q]?A:?(G]F)>.ILE6/1UB_#=G*0``'```0`2.C1..[3S9I\-H-G\-H_T'LY\['0```!P` +M`$`%!N3#8O\;D4Q6A9>+92]U8DX6I$#Q$K=&.H0-`)@!``"8`0```@```$4` +M`91M%P``0!$``,"H`0'`J`$"`?0!]`&`!V7U?IF349Z4P0``````````(2`B +M"`````````%X(@``>````'0!`?<,`P``#`$```R`#@"``P``#`$```R`#@$` +M`P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0# +M```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``" +M``"HFO"[MA"SDA2L0B9TT[3T]7L"8A8=DUI[*+*SOT0(H>LYUALV`C-T:\4"(:MCXZFY:6H]1UD0HWY9:XK*ZQ9G0H%45 +M'L3/=@0!QT_JNR_RGJ'-HX$`0YC-5Z?5M!@U$F'8W.YYM$%7_#RMARD``"1; +MW.^H#=Y?-2EK+J^@+58VAUV'<0,7`C_7ECT=8OPW9RD``!P``$`$CHT3CNT\ +MV:?#:#9_#:/]![.?.QT````<``!`!0;DPV+_&Y%,5H67BV4O=6).%J1`\A*W +M1CR2"P"8`0``F`$```(```!%``&4;24``$`1``#`J`$!P*@!`@'T`?0!@`=E +M\:(:EDZ'#F4``````````"$@(@@````````!>"(``'@```!T`0'X#`,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``C+9#W&NNY#VF5F9DZE>.9(,.65*BP>-E +MXPR:.]RZJZ,C$\^XJ`S.P?71$9I;B0?X<>C>3NQ\X0`AX)S^NKV6P2_`#\`Z +MAG?YX'9(D54#-^(+9\47L'(3^7=$GUNPFQCOPB4T/1"`?,!"E4.*/$:&%.4W.L`R"YL$BG$*4I +M_@@"BUG'X!#"\````'```0`720*KM +M%L/O3?9(90LZ/[V:T=>*/?(2MT:=O`X`F`$``)@!```"````10`!E&TG``!` +M$0``P*@!`<"H`0(!]`'T`8`'9?&B&I9.APYE```````````A("((```````` +M`7@B``!X````=`$!^`P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0`` +M#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```" +M`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``(RV0]QK +MKN0]IE9F9.I7CF2##EE2HL'C9>,,FCO"<_KJ]EL$OP`_`.H9W^>!V2)%5`S?B"V?%%[!R$_EW1)];L)L8 +M[\(E-#W):,IO86PB/YX,-,?I&(-+N_EO^]W2IND2JZD?*0``)#E7D0@'S`0I +M5#BCQ&AA3E-SK`,@N;!(IQ"E*?X(`G,3*0``'```0`1^+"159S1UG6?I01.W +MHM9Q^`0PO````!P``$`%TD"J[1;#[TWV2&4+.C^]FM'7BCWS$K=&V[L%`)@! +M``"8`0```@```$4``91M*```0!$``,"H`0'`J`$"`?0!]`&`!V7QHAJ63H<. +M90``````````(2`B"`````````%X(@``>````'0!`?@,`P``#`$```R`#@"` +M`P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@" +M```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@`` +M``@$```.*```B``"``",MD/<:Z[D/:969F3J5XYD@PY94J+!XV7C#)H[W+JK +MHR,3S[BH#,[!]=$1FEN)!_AQZ-Y.['SA`"'@G/ZZO9;!+\`/P#J&=_G@=DB1 +M50,WX@MGQ1>P##3'Z1B#2[OY;_O= +MTJ;I$JNI'RD``"0Y5Y$(!\P$*50XH\1H84Y3"(``'@` +M``!T`0'Y#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``]B5],M=L^0N?#:T. +MQMGJ1*MA&&PZ;J#Q!Q;Z?1T1X./"^DSM-'^ +M`V-X?(*EMCO&D@>#(PR1Y.I/3H[N%'FY/WPI```DA[3(>B<0@F;"G^`UZXFG +ME^%+X%LB^E7.R.)1.%4E0\XI```<``!`!&NWGG+P_$R>-_;FDM!YDW')"2A! +M````'```0`7NJ[!4X./ZTA+BO7'UUY5"RG_0#/02MT:H]`8`F`$``)@!```" +M````10`!E&TV``!`$0``P*@!`<"H`0(!]`'T`8`'94O-%6LCSZ#3```````` +M```A("((`````````7@B``!X````=`$!^0P#```,`0``#(`.`(`#```,`0`` +M#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```( +M`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH +M``"(``(``/8E?3+7;/D+GPVM#L;9ZD2K81AL.FZ@\0<6^GT=$>#CPOI,W+&8 +ML=0]%86X&%M\O<@8"U!?2^0_6TL$+EHH1JY*#8")4Y)-)><2>'-%&&.=8 +MK^U;F%P9-(GK31_@-C>'R"I;8[QI('@R,,D>3J3TZ.[A1YN3]\ +M*0``)(>TR'HG$()FPI_@->N)IY?A2^!;(OI5SLCB43A5)4/.*0``'```0`1K +MMYYR\/Q,GC?VYI+0>9-QR0DH00```!P``$`%[JNP5.#C^M(2XKUQ]=>50LI_ +MT`ST$K=&]C4-`)@!``"8`0```@```$4``91M.```0!$``,"H`0'`J`$"`?0! +M]`&`!V5+S15K(\^@TP``````````(2`B"`````````%X(@``>````'0!`?D, +M`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,# +M```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,` +M``4#```(!````@````@$```.*```B``"``#V)7TRUVSY"Y\-K0[&V>I$JV$8 +M;#INH/$'%OI]'1'@X\+Z3-RQF+'4/16%N!A;?+W(&`M07TA@T_D/UM+!"Y:* +M$:N2@V`B5.2327G$GAS11ACG6*_G+)^MA^SIGM6YA<&32)ZTT?X#8WA\@J6V +M.\:2!X,C#)'DZD].CNX4>;D_?"D``"2'M,AZ)Q""9L*?X#7KB:>7X4O@6R+Z +M5<[(XE$X525#SBD``!P``$`$:[>>ZKL%3@X_K2$N*]"(``'@```!T`0'\#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MLZJ@,VQ%^+X[$(*[B>.I4LQBY@IF`UQ[T11"J+%TR)>!<4;FHPXNGF@1+3Z9 +MNVKRA=<[X752J^Z011Q/EM+\O:^[7-XI```DU:N& +ML@J(GB9UIK:[[+6F/1)EVK+9T.4%\24680UMFLPI```<``!`!-5=6=Z<>#$S +MLQZ712$O5Q>:BR\8````'```0`68XY2-YG=YX:`P.MG;N)1].[26L/42MT:* +M;@X`F`$``)@!```"````10`!E&U```!`$0``P*@!`<"H`0(!]`'T`8`'90M& +M6B[KYXNP```````````A("((`````````7@B``!X````=`$!_`P#```,`0`` +M#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```" +M`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$ +M```"````"`0```XH``"(``(``+.JH#-L1?B^.Q""NXGCJ5+,8N8*9@-<>]$4 +M0JBQ=,B7@7%&YJ,.+IYH$2T^F;MJ\H77.^%U4JOG)4G1W7,:H*=P]8:O\9PI +M!,%$#`"5U/[4D-.95@6GXE^EUEC.MP#<"O0[5=84QLC`ANFF:-5'8H9W527N +MD$4<3Y;2_+VONUS>*0``)-6KAK(*B)XF=::VN^RUICT29=JRV=#E!?$E%F$- +M;9K,*0``'```0`3575G>G'@Q,[,>ET4A+U<7FHLO&````!P``$`%F..4C>9W +M>>&@,#K9V[B4?3NTEK#V$K=&I6T%`)@!``"8`0```@```$4``91M0@``0!$` +M`,"H`0'`J`$"`?0!]`&`!V4+1EHNZ^>+L```````````(2`B"`````````%X +M(@``>````'0!`?P,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R` +M#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,` +M``@#```!`P``"`,```4#```(!````@````@$```.*```B``"``"SJJ`S;$7X +MOCL0@KN)XZE2S&+F"F8#7'O1%$*HL73(EX%Q1N:C#BZ>:!$M/IF[:O*%USOA +M=5*KYR5)T=US&J"G)G6F +MMKOLM:8]$F7:LMG0Y07Q)19A#6V:S"D``!P``$`$U5U9WIQX,3.S'I=%(2]7 +M%YJ++Q@````<``!`!9CCE(WF=WGAH#`ZV=NXE'T[M):P]Q*W1H5Y`P"8`0`` +MF`$```(```!%``&4;4H``$`1``#`J`$!P*@!`@'T`?0!@`=E_55LP`@=01$` +M`````````"$@(@@````````!>"(``'@```!T`0']#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@```=$%$IU?P@O6'=BT03'J_,`<],5-C\X4B*R6VO\QB^=6 +M4I[4G0/"GPR'@AEH/M+->8I'GUZ%=&Q>%8;6Q8JF+4$A0>(G(Y*H[$\=H9\2 +MC->J7>1EJ6B=2:!1)7E*:^Z)B)66/*2&/&^R8SZ73A![BZ,"'XG8!5;8N.W1 +MYCTKT?,I```D14K*X.,R*A*^J=<.G8(Q=L3JN'B)U7@MI6O=>ELM\&HI```< +M``!`!&=T:M!KGP;O?)DJP6!V@+-+_HA:````'```0`5W^JG^N#-L+2P)\/"" +MTT!HN[^<8_<2MT8AI@8`F`$``)@!```"````10`!E&U+``!`$0``P*@!`<"H +M`0(!]`'T`8`'9?U5;,`('4$1```````````A("((`````````7@B``!X```` +M=`$!_0P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```( +M`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$# +M```(`P``!0,```@$```"````"`0```XH``"(``(```'1!1*=7\(+UAW8M$$Q +MZOS`'/3%38_.%(BLEMK_,8OG5E*>U)T#PI\,AX(9:#[2S7F*1Y]>A71L7A6& +MUL6*IBU!(4'B)R.2J.Q/':&?$HS7JEWD9:EHG4F@425Y2FONB8B5ECRDACQO +MLF,^ETX0>XNC`A^)V`56V+CMT>8]*]'S*0``)$5*RN#C,BH2OJG7#IV",7;$ +MZKAXB=5X+:5KW7I;+?!J*0``'```0`1G=&K0:Y\&[WR9*L%@=H"S2_Z(6@`` +M`!P``$`%=_JI_K@S;"TL"?#P@M-`:+N_G&/W$K=&U><,`)@!``"8`0```@`` +M`$4``91M40``0!$``,"H`0'`J`$"`?0!]`&`!V7]56S`"!U!$0`````````` +M(2`B"`````````%X(@``>````'0!`?T,`P``#`$```R`#@"``P``#`$```R` +M#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(` +M``0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*``` +MB``"```!T042G5_""]8=V+1!,>K\P!STQ4V/SA2(K);:_S&+YU92GM2=`\*? +M#(>"&6@^TLUYBD>?7H5T;%X5AM;%BJ8M02%!XB4IK[HF(E98\I(8\;[)C/I=.$'N+HP(?B=@%5MBX[='F/2O1\RD` +M`"1%2LK@XS(J$KZIUPZ=@C%VQ.JX>(G5>"VE:]UZ6RWP:BD``!P``$`$9W1J +MT&N?!N]\F2K!8':`LTO^B%H````<``!`!7?ZJ?ZX,VPM+`GP\(+30&B[OYQC +M^!*W1I/T"@"8`0``F`$```(```!%``&4;54``$`1``#`J`$!P*@!`@'T`?0! +M@`=E]""QR9U:%+H``````````"$@(@@````````!>"(``'@```!T`0'^#`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``,Y+;2T;LF]ONCP.6'LHN((?D'@P2 +M/\]SN&ZAT6O:,R50T&?I7]6"IF&^DTG0?B%4@4:)*BQ5]B'9XHZ9;PC$M'I1 +M[:!/R:.CHU[&'T[7Q59!Y=#+9-5CGHC,T=;D#$/?O\]5(E+6B70RB +M!'&G@14%B2"Z3^V@YM[.V2@I```DI=NS%2*EYSSQ;3=^]_%1JIA#K$V#(1?, +M\KNQS/*ZL:PI```<``!`!*:.71GU^8IP&")VPA;9=_2ADT__````'```0`4L +M($Y**.F6\(Q+1Z4>V@3\FCHZ->QA].U\560>70RV358YZ(S-'6 +MY`Q#W[_/52)7(N'6OWBUHET,H@1QIX$5!8D@ND_MH.;>SMDH*0``)*7;LQ4B +MI><\\6TW?O?Q4:J80ZQ-@R$7S/*[L````'0!`?X,`P``#`$```R` +M#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,` +M``@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!``` +M`@````@$```.*```B``"```SDMM+1NR;V^Z/`Y8>RBX@A^0>#!(_SW.X;J'1 +M:]HS)5#09^E?U8*F8;Z32=!^(52!1HDJ+%7V(=GBCIEO",2T>E'MH$_)HZ.C +M7L8?3M?%5D'ET,MDU6.>B,S1UN0,0]^_SU4B5R+AUK]XM:)=#*($<:>!%06) +M(+I/[:#FWL[9*"D``"2EV[,5(J7G//%M-W[W\5&JF$.L38,A%\SRN[',\KJQ +MK"D``!P``$`$IHY=&?7YBG`8(G;"%MEW]*&33_\````<``!`!2P@3DIRRNA3 +M9:WRLHV,ST);H?70^A*W1H,K`P"8`0``F`$```(```!%``&4;64``$`1``#` +MJ`$!P*@!`@'T`?0!@`=E-<4"\C"D'G(``````````"$@(@@````````!>"(` +M`'@```!T`0'_#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``&I;$BK`.,&QO +M,_]-J6?G33*DY$([TB$]&0_XSG/L1AZU#(*Y:UP:!>]C'@AAA+^/YC!8QK;% +MB].BO,&4\IZ;U?8(&J2+`0`WA5RT[JDX*]"E,J'1Y\DY_DNHG2.V0_-E[RW2 +M/S,;E@,EB@BJA1O)[L9VO);:G%?[=FN!$9W#\``I```D6N9?@@0C:F(VGO6J +MH_Z-^-BKK3V@;B0PY,MO0U@+`-@I```<``!`!(,8G1U8VG82N-^RA[V]P_T% +MTA8R````'```0`7GU8F/96/H`AV6.<>\T2?EJI`)/OH2MT826`8`F`$``)@! +M```"````10`!E&UJ``!`$0``P*@!`<"H`0(!]`'T`8`'937%`O(PI!YR```` +M```````A("((`````````7@B``!X````=`$!_PP#```,`0``#(`.`(`#```, +M`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$# +M```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0` +M``XH``"(``(``!J6Q(JP#C!L;S/_3:EGYTTRI.1".](A/1D/^,YS[$8>M0R" +MN6M<&@7O8QX(882_C^8P6,:VQ8O3HKS!E/*>F]7V"!JDBP$`-X5?).?Y+J)TCMD/S9>\MTC\S&Y8#)8H(JH4;R>[&=KR6VIQ7^W9K@1&= +MP_``*0``)%KF7X($(VIB-I[UJJ/^C?C8JZT]H&XD,.3+;T-8"P#8*0``'``` +M0`2#&)T=6-IV$KC?LH>]O<@``````````(2`B"`````````%X(@``>````'0! +M`?\,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$` +M``,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P`` +M"`,```4#```(!````@````@$```.*```B``"```:EL2*L`XP;&\S_TVI9^=- +M,J3D0CO2(3T9#_C.<^Q&'K4,@KEK7!H%[V,>"&&$OX_F,%C&ML6+TZ*\P93R +MGIO5]@@:I(L!`#>%7+3NJ3@KT*4RH='GR3G^2ZB=([9#\V7O+=(_,QN6`R6* +M"*J%&\GNQG:\EMJ<5_MV:X$1G]:JC_HWXV*NM +M/:!N)##DRV]#6`L`V"D``!P``$`$@QB='5C:=A*XW[*'O;W#_072%C(````< +M``!`!>?5B8]E8^@"'98YQ[S1)^6JD`D^^Q*W1E>F"@"8`0``F`$```(```!% +M``&4;7D``$`1``#`J`$!P*@!`@'T`?0!@`=E>U<>BM&;C5X``````````"$@ +M(@@````````!>"(``'@```!T`0$!#`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``FUA9Y:!F9!2M,#J&_//_%__"A_AHLOZ7Z)UX +M"1@3G58I;D<]U<@%M1U)L1J')>Q">L9R0]R70'9>?/7,HE&/L2 +MMT8>T@T`F`$``)@!```"````10`!E&U\``!`$0``P*@!`<"H`0(!]`'T`8`' +M97M7'HK1FXU>```````````A("((`````````7@B``!X````=`$!`0P#```, +M`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@" +M```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,` +M``@$```"````"`0```XH``"(``(``)M86>6@9F04K3`ZAG.@WP1&;R4WW[@: +M2D5$1#KRN5CC*4F/Z?#6?1/5L0]>,KJ3JC9L`D8$YU6*6Y'/=7(!;4=2;$7(W&0/3_11)5\ +MYYO@URK^BBI!RO/HIH9+*0``)`"_8O45:%5FRV:WTBN6W$[9+VF?H#!83_2C +M0#>^,4P#*0``'```0`0EKT````'0!`0$,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$` +M``R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P`` +M`@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``";6%GE +MH&9D%*TP.H9SH-\$1F\E-]^X&DI%1$0Z\KE8XRE)C^GPUGT3U;$/7C*ZDZHV +M;'(B/A#3M$8G_3%4ZXRQHD39"?V)LI[\\_\7_\*'^&BR_I?HG7@)&!.=5BEN +M1SW5R`6U'4FQ%R-QD#T_T425?.>;X-=H````<``!`!9ZH"(``'@```!T`0$"#`,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``;[?5);,/#*/Z6%3Z/,#YYG@A2]0S9")SH&R!\^Q4 +M:X5ZZ'`>0:BB:P2O>JJC#M^!0`F,8AER4+8P:8F@<;;=?GOMC!'@5N_B8L^/ +M?W*US1-U$QQ_H.=CFLV<>(;HPWQ/@^6.,!,*@@<($H-M$@(!K5=E#X->+LUI +MUB5Y3V\WAXPI```DR&;T9`\=K]@QE&W6JY`V^\>R@HHFO*I02F(16`BV5@,I +M```<``!`!+^A_VHTN5A>V!D&IK]SAZD]G58V````'```0`68KQMWBQTRRA#4 +M`/":-MO*RL/.Z?T2MT;#"08`F`$``)@!```"````10`!E&V*``!`$0``P*@! +M`<"H`0(!]`'T`8`'96?R1O?4KD1Z```````````A("((`````````7@B``!X +M````=`$!`@P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`# +M```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,` +M``$#```(`P``!0,```@$```"````"`0```XH``"(``(``&^WU26S#PRC^EA4 +M^CS`^>9X(4O4,V0BNAP'D&HHFL$KWJJHP[?@4`)C&(94]O-X>,*0``),AF]&0/':_8,91MUJN0 +M-OO'LH**)KRJ4$IB$5@(ME8#*0``'```0`2_H?]J-+E87M@9!J:_I/9U6 +M-@```!P``$`%F*\;=XL=,LH0U`#PFC;;RLK#SNG]$K=&8TL,`)@!``"8`0`` +M`@```$4``91MEP``0!$``,"H`0'`J`$"`?0!]`&`!V5G\D;WU*Y$>@`````` +M````(2`B"`````````%X(@``>````'0!`0(,`P``#`$```R`#@"``P``#`$` +M``R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P`` +M"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```. +M*```B``"``!OM]4ELP\,H_I85/H\P/GF>"%+U#-D(G.@;('S[%1KA7KH^V,$>!6[^)BSX]_' +MC"D``"3(9O1D#QVOV#&4;=:KD#;[Q[*"BB:\JE!*8A%8"+96`RD``!P``$`$ +MOZ'_:C2Y6%[8&0:FOW.'J3V=5C8````<``!`!9BO&W>+'3+*$-0`\)HVV\K* +MP\[I_A*W1B95"@"8`0``F`$```(```!%``&4;9T``$`1``#`J`$!P*@!`@'T +M`?0!@`=EC;-:LPUC`M0``````````"$@(@@````````!>"(``'@```!T`0$# +M#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``)`CJHJ"&PZ63;QT&UP&U1'4) +MC==I//XPP&:M!DHW@>1X=[]_%B]]'K8RH[[1HR%0_&ET/IE\,5MS+D5!!6+R +MN+*X_\_@U'-.7;AO+_[B&FIL"'YF][I,00\;J#+DO+ +M?[/NHN2'$QJ`:S`I```<``!`!/CC;TC?^,_U-*KH,$A,X:\U;NWD````'``` +M0`5=]@%ZRPYFFP;I$0:%.#.]SV/8OOX2MT:K@PT`F`$``)@!```"````10`! +ME&V>``!`$0``P*@!`<"H`0(!]`'T`8`'98VS6K,-8P+4```````````A("(( +M`````````7@B``!X````=`$!`PP#```,`0``#(`.`(`#```,`0``#(`.`0`# +M```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,` +M``@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(` +M`"0(ZJ*@AL.EDV\=!M'>_?Q8O?1ZV,J.^ +MT:,A4/QI=#Z9?#%;Z3$$/&Z@RY+RW^S[J+DAQ,:@&LP*0``'```0`3XXV](W_C/ +M]32JZ#!(3.&O-6[MY````!P``$`%7?8!>LL.9IL&Z1$&A3@SO<]CV+[_$K=& +M&(,$`)@!``"8`0```@```$4``91MHP``0!$``,"H`0'`J`$"`?0!]`&`!V6- +MLUJS#6,"U```````````(2`B"`````````%X(@``>````'0!`0,,`P``#`$` +M``R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@`` +M`@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```( +M!````@````@$```.*```B``"```D".JBH(;#I9-O'0;7`;5$=0F-UVD\_C#` +M9JT&2C>!Y'AWOW\6+WT>MC*COM&C(5#\:70^F7PQ6W,N14$%8O*XLKC_S^#4 +ME*: +MM"?L#26:9O`/8/6%U2D``"3IXO_N(::FP(?F;WNDQ!#QNH,N2\M_L^ZBY(<3 +M&H!K,"D``!P``$`$^.-O2-_XS_4TJN@P2$SAKS5N[>0````<``!`!5WV`7K+ +M#F:;!ND1!H4X,[W/8]B^`!.W1G./`@"8`0``F`$```(```!%``&4;:\``$`1 +M``#`J`$!P*@!`@'T`?0!@`=E<,;E<@I`PY$``````````"$@(@@````````! +M>"(``'@```!T`0$$#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``KE.S+T!E +MT$XPJDQ8%I+9-WX:K=F.I[(]HD1;4D0338Q6`N4.J',?F51/Y^JR]#(EEEPT +M"`H(WA6.$E+;!"I>L?967.DMU,SMB/K)C(0KL&,<&#R+$XOEQ[5.:=W.Y%]L +M_)@2Z`5S=D;9`.P(W,`41(#AD"CEVA?%P`/^9]Z@-D(I```D5^M-J^J.AL,8 +M0S4;P%S_D)3)%&AF,B6F$(:MSM"TM!4I```<``!`!*J-`;ZT>/@Y("4WQPM_ +MBUJFJKZ&````'```0`6&P,GE9\M:I!SOD$]@UKWJ)?>1?``3MT:.NP4`F`$` +M`)@!```"````10`!E&VR``!`$0``P*@!`<"H`0(!]`'T`8`'97#&Y7(*0,.1 +M```````````A("((`````````7@B``!X````=`$!!`P#```,`0``#(`.`(`# +M```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(` +M``$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"```` +M"`0```XH``"(``(``*Y3LR]`9=!.,*I,6!:2V3=^&JW9CJ>R/:)$6U)$$TV, +M5@+E#JAS'YE43^?JLO0R)99<-`@*"-X5CA)2VP0J7K'V5ESI+=3,[8CZR8R$ +M*[!C'!@\BQ.+Y<>U3FG=SN1?;/R8$N@%H#9"*0``)%?K3:OJCH;#&$,U&\!<_Y"4R11H9C(EIA"&K<[0M+05*0`` +M'```0`2JC0&^M'CX.2`E-\<+?XM:IJJ^A@```!P``$`%AL#)Y6?+6J0<[Y!/ +M8-:]ZB7WD7P`$[=&)_T+`)@!``"8`0```@```$4``91MN@``0!$``,"H`0'` +MJ`$"`?0!]`&`!V5PQN5R"D##D0``````````(2`B"`````````%X(@``>``` +M`'0!`00,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P`` +M"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```! +M`P``"`,```4#```(!````@````@$```.*```B``"``"N4[,O0&703C"J3%@6 +MDMDW?AJMV8ZGLCVB1%M21!--C%8"Y0ZH%8X2 +M4ML$*EZQ]E95GRUJD'.^03V#6O>HE]Y%\`1.W1I`*"@"8`0``F`$```(` +M``!%``&4;=(``$`1``#`J`$!P*@!`@'T`?0!@`=EU/ZI.@R5L*8````````` +M`"$@(@@````````!>"(``'@```!T`0$'#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``,QD2V%";MNAT&[1:5D=4PSHQ^(S6*4;5\E4A!/A#FL,RULW&C\55 +ME'1TYP9%3G@Z\3(0(Q/H!4]1RUD(*-O[G8K'\/E;G,>UFWLZB7YN2YV7D6W: +M2^8UQ!>8M(Z.),>Z%2>)($QJ(I +M```D)@&:^5/>6:KPNVON1\"/5)99'FFR.*/(&ADWZKX"F_,I```<``!`!%@) +MQ4@>N=7QU%P.8A7>>+YF=V43````'```0`5SV-9#'I7!WZ*0,+2M`X"#:+E! +MZP$3MT9\-0T`F`$``)@!```"````10`!E&W4``!`$0``P*@!`<"H`0(!]`'T +M`8`'9=3^J3H,E;"F```````````A("((`````````7@B``!X````=`$!!PP# +M```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,` +M``@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P`` +M!0,```@$```"````"`0```XH``"(``(``#,9$MA0F[;H=!NT6E9'5,,Z,?B, +MUBE&U?)5(03X0YK#,M;-QH_%591T=.<&14YX.O$R$",3Z`5/4L"$[=&&C4$`)@!``"8`0```@```$4``91M +MU0``0!$``,"H`0'`J`$"`?0!]`&`!V74_JDZ#)6PI@``````````(2`B"``` +M``````%X(@``>````'0!`0<,`P``#`$```R`#@"``P``#`$```R`#@$``P`` +M#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```( +M`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"```S +M&1+84)NVZ'0;M%I61U3#.C'XC-8I1M7R52$$^$.:PS+6S<:/Q564='3G!D5. +M>#KQ,A`C$^@%3U'+60@HV_N=BL?P^5NSJ)?FY+G9>1;=I+YC7$%YBT +MCHXDQ[IR\-V\AH[,ATZ5?YKG!!N;G+/*3]+OL4#5X5)XD@3&HBD``"0F`9KY +M4]Y9JO"[:^Y'P(]4EED>:;(XH\@:&3?JO@*;\RD``!P``$`$6`G%2!ZYU?'4 +M7`YB%=YXOF9W91,````<``!`!7/8UD,>E<'?HI`PM*T#@(-HN4'K`Q.W1B<_ +M`@"8`0``F`$```(```!%``&4;=8``$`1``#`J`$!P*@!`@'T`?0!@`=E,L]8 +M>P:U&5T``````````"$@(@@````````!>"(``'@```!T`0$(#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``19G`*8.P02*/=D44`.$/6/AF%7Q%5U5^8?\[ +MRPB1Q.\K0;"S4-L-()``1%S\="8))T;T;9FJY_,2IS.X)`7NW`>O5-+X6WMA +MLHH.O#!!A`Z[.]>S=:W4%\2O\T$1L\;;>K5BINBTP@35;2*]7!@`M77M*LX^ +MW\JOII_O=Y=7M88I```D$\/;^1=KM`L]PH`1&[".4`C'-6,^Y*J8@-@UIO:- +MXY@I```<``!`!&DP==D,4`Y<^UO7127&QL]/OOY"````'```0`68&>^4E3?? +M_`4XD4V8GWD.0-&4E@,3MT8S;04`F`$``)@!```"````10`!E&W7``!`$0`` +MP*@!`<"H`0(!]`'T`8`'93+/6'L&M1E=```````````A("((`````````7@B +M``!X````=`$!"`P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`. +M`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P`` +M"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``$69P"F#L$$B +MCW9%%`#A#UCX9A5\15=5?F'_.\L(D<3O*T&PLU#;#2"0`$1<_'0F"2=&]&V9 +MJN?S$J75[6&*0``)!/#V_D7:[0+/<*` +M$1NPCE`(QS5C/N2JF(#8-:;VC>.8*0``'```0`1I,'79#%`.7/M;UT4EQL;/ +M3[[^0@```!P``$`%F!GOE)4WW_P%.)%-F)]Y#D#1E)8#$[=&VJX+`)@!``"8 +M`0```@```$4``91MV```0!$``,"H`0'`J`$"`?0!]`&`!V4RSUA[!K4970`` +M````````(2`B"`````````%X(@``>````'0!`0@,`P``#`$```R`#@"``P`` +M#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```! +M`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$ +M```.*```B``"``!%F<`I@[!!(H]V110`X0]8^&85?$5757YA_SO+")'$[RM! +ML+-0VPT@D`!$7/QT)@DG1O1MF:KG\Q*G,[@D!>[V&RB@Z\,$&$ +M#KL[U[-UK=07Q*_S01&SQMMZM6*FZ+3"!-5M(KU<&`"U=>TJSC[?RJ^FG^]W +MEU>UABD``"03P]OY%VNT"SW"@!$;L(Y0",0Y`T926!!.W1B&["0"8`0``F`$```(```!%``&4;=D``$`1``#`J`$!P*@! +M`@'T`?0!@`=EUP.6OR<961X``````````"$@(@@````````!>"(``'@```!T +M`0$)#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``*)XO)L*V!41FI$N*;S6! +MP^*,'EARRTD_B3^UB?("HZ!/FRIT;@LA<"8T&;=[@QGESU,6,V@>MMH?/W^\ +M9E9SHQ-SEM)];^'7Q;1?VY'O3S\'EO3KP&04TSG]W8[:"5'LM3$(X;>]2!>, +MPEDH@:4;:MLF(&CQ0X&Q +M_7S?#<6YB&R2IL'EU```````````A +M("((`````````7@B``!X````=`$!"0P#```,`0``#(`.`(`#```,`0``#(`. +M`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@`` +M!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"( +M``(``"B>+R;"M@5$9J1+BF\U@X,9Y<]3%C-H'K;:'S]_O&96!C1(E`!`% +M$[=&HN8#`)@!``"8`0```@```$4``91MVP``0!$``,"H`0'`J`$"`?0!]`&` +M!V77`Y:_)QE9'@``````````(2`B"`````````%X(@``>````'0!`0D,`P`` +M#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```( +M`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4# +M```(!````@````@$```.*```B``"```HGB\FPK8%1&:D2XIO-8'#XHP>6'++ +M23^)/[6)\@*CH$^;*G1N"R%P)C09MWN#&>7/4Q8S:!ZVVA\_?[QF5G.C$W.6 +MTGUOX=?%M%_;D>]//P>6].O`9!33.?W=CMH)4>RU,0CAM[U(%XS"62B!I1MJ +MVR8@:/%!R=(!F?3<&5H(4BD``"2V7;GQ->CB4DW5JX_!V:Q[@;']?-\-Q;F( +M;)*FP>75RBD``!P``$`$2_RH.H/W\L_ZQH3IE0C!-SO.1=,````<``!`!3?< +M+.)0"NKAC"@D1&,W@8T2)0`0!A.W1O#R`0"8`0``F`$```(```!%``&4;=T` +M`$`1``#`J`$!P*@!`@'T`?0!@`=E]'M'"(``'@```!T`0'_#`,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``PKQY +M,'?U=TP+C:3T8[7^3\3BXT7\3W,G/KH#OI.T!^#-Z.6\1?S\V]S5V!`0<3S& +M1>TQH(@D"NLS6^#JE'T+RN[T]@"'Y6(7F&:B[EX\1,-.V1)%'N"U\MBZOMD/ +M)BGM".S"([JM-<@1T.M#]FRGU_D\I7;0LX=8A[M;#RT@\&\I```D4V.F(14^ +MIH*U2_@Q!L66$VN@SEI5D"'")T6A_3L?^T``!`$0``P*@!`<"H`0(!]`'T`8`'9?1[1W.% +M=T81```````````A("((`````````7@B``!X````=`$!_PP#```,`0``#(`. +M`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P`` +M"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```" +M````"`0```XH``"(``(``,*\>3!W]7=,"XVD]&.U_D_$XN-%_$]S)SZZ`[Z3 +MM`?@S>CEO$7\_-O/$3#3MD211[@M?+8NK[9#R8I[0CLPB.ZK37($=#K0_9LI]?Y/*5VT+.' +M6(>[6P\M(/!O*0``)%-CIB$5/J:"M4OX,0;%EA-KH,Y:59`APB=%H?T['_M' +M*0``'```0`1FC5R=#L5P,EL(DT`P)Q/>F><[I````!P``$`%]9VEI^5@_^CS +M#H`9,J28@)]*_I,&$[=&!&$+`)@!``"8`0```@```$4``91MWP``0!$``,"H +M`0'`J`$"`?0!]`&`!V7T>T=SA7=&$0``````````(2`B"`````````%X(@`` +M>````'0!`?\,`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#` +M`P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@# +M```!`P``"`,```4#```(!````@````@$```.*```B``"``#"O'DP=_5W3`N- +MI/1CM?Y/Q.+C1?Q/89J+N7CQ$PT[9$D4>X+7RV+J^V0\F*>T([,(C +MNJTUR!'0ZT/V;*?7^3RE=M"SAUB'NUL/+2#P;RD``"138Z8A%3ZF@K5+^#$& +MQ983:Z#.6E60(<(G1:'].Q_[1RD``!P``$`$9HU$``$`1``#`J`$!P*@!`@'T`?0!@`=E2?2_U@V5\\P````` +M`````"$@(@@````````!>"(``'@```!T`0&`#`,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``;[@[K8JU)R*%;>TR.^M5>-.&N#G3/W!JO2B5^;N.O<"WUNE( +M6E3?^AEBV!V+>;._!YI.!C0)WQ[;[J8ZS-X';04:5(D,*[7GNRE7-P8,DP\9 +MN4V\5`"_X>9MJ+8O5QZX3&Y5[+\@=Q]P]X4HS.K#< +MYK4I```DL@DR@(!!3E7LO'%!W&L!H<\]P)S`^QU!92^]6KJ`$]LI```<``!` +M!!!O[YM@)IT\@_X,;/$)C?>6_"4V````'```0`7K6J-W-H?8+GX_`I>[E=J$ +M:.UH9`<3MT81F0P`F`$``)@!```"````10`!E&WB``!`$0``P*@!`<"H`0(! +M]`'T`8`'94GTO]8-E?/,```````````A("((`````````7@B``!X````=`$! +M@`P#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0`` +M`P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```( +M`P``!0,```@$```"````"`0```XH``"(``(``&^X.ZV*M2:3@8T"=\>V^ZF.LS> +M!VT%&E2)#"NUY[LI5S<&#),/&;E-O%0`O^'F;:BV+U<>N$QN5>R_('%*,SJPW.:U*0``)+(),H"`04Y5[+QQ0=QK`:'//<"< +MP/L=064OO5JZ@!/;*0``'```0`00;^^;8":=/(/^#&SQ"8WWEOPE-@```!P` +M`$`%ZUJC=S:'V"Y^/P*7NY7:A&CM:&0($[=&7Y@#`)@!``"8`0```@```$4` +M`91MXP``0!$``,"H`0'`J`$"`?0!]`&`!V5)]+_6#97SS```````````(2`B +M"`````````%X(@``>````'0!`8`,`P``#`$```R`#@"``P``#`$```R`#@$` +M`P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0# +M```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``" +M``!ON#NMBK4G(H5M[3([ZU5XTX:X.=,_<&J]*)7YNXZ]P+?6Z4A:5-_Z&6+8 +M'8MYL[\'FDX&-`G?'MONICK,W@=M!1I4B0PKM>>[*5R\<4'<:P&ASSW`G,#['4%E+[U:NH`3VRD``!P``$`$$&_OFV`F +MG3R#_@QL\0F-]Y;\)38````<``!`!>M:HW0``$`1``#`J`$!P*@!`@'T`?0!@`=E +M-E(9L,5Z3PH``````````"$@(@@````````!>"(``'@```!T`0$```,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``PO+>&5=;:_M>XYHE,IOYW\.:[I6CD%A` +M-,>_6[,68^?0D@Q2=RI:5=-SBD6N'>I_1$$331VV[X8,-&PNO_V^910@ZDGU +M.@`N[DETLQAHA\Q)UL4?V'R:937AHV#4F#\((#1(2I+1JFNC,.+9RG./@O\K +M68=G05:^?,MBO5Y?9C(I```D]`D4.\VF&2NYKP@Y3!\*'2?*6?_X%PS9K@F3 +MGR@`:T@I```<``!`!)/8O?2J^!SG':A6YPS22&E0BW2G````'```0`4E:MA" +M)!P-@"E07,R0KL=80K[J90D3MT;/T`0`F`$``)@!```"````10`!E&WE``!` +M$0``P*@!`<"H`0(!]`'T`8`'9392&;#%>D\*```````````A("((```````` +M`7@B``!X````=`$!```#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0`` +M#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```" +M`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``,+RWAE7 +M6VO[7N.:)3*;^=_#FNZ5HY!80#3'OUNS%F/GT)(,4G7V8R*0``)/0)%#O-IADK +MN:\(.4P?"ATGREG_^!<,V:X)DY\H`&M(*0``'```0`23V+WTJO@````'0!`0```P``#`$```R`#@"` +M`P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@" +M```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@`` +M``@$```.*```B``"``#"\MX95UMK^U[CFB4RF_G?PYKNE:.06$`TQ[];LQ9C +MY]"2#%)W*EI5TW.*1:X=ZG]$01--';;OA@PT;"Z__;YE%"#J2?4Z`"[N272S +M&&B'S$G6Q1_8?)IE->&C8-28/P@@-$A*DM&J:Z,PXMG*"0"8`0``F`$```(```!%``&4;><``$`1``#`J`$! +MP*@!`@'T`?0!@`=EIQA;?"*9C38``````````"$@(@@````````!>"(``'@` +M``!T`0$``0,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``IETU:R=5%E&(&5ZK +M,@&U054"H!4\(P6-S9JTC0WY6)!&Z^=V`"(X<;?BAPZFBT`*MEX3R5`HU-SY +MLD[!Q:F#;KRBG@9#*0L[G[JB)2^FOSS=H;_P#,(E"5PTO1"`SAZ/^JB7>!C$ +M_/[R/W2;T<0JZHY\`B/*.<)%YI!J/PQUD?HI```DQEKK8%T9?JN?/?E3JI7T +M9#7PS(U<;PPG9H$A"`;\D@DI```<``!`!"IQ@=Q#G_PA^PT2WVV +M````'```0`7\OD4@0GS>JAI/2*)@P("P9Z490@H3MT;82@P`F`$``)@!```" +M````10`!E&WH``!`$0``P*@!`<"H`0(!]`'T`8`'9:<86WPBF8TV```````` +M```A("((`````````7@B``!X````=`$!``$#```,`0``#(`.`(`#```,`0`` +M#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```( +M`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH +M``"(``(``*9=-6LG5191B!E>JS(!M4%5`J`5/",%C$\E0*-3<^;).P<6I@VZ\HIX&0RD+.Y^ZHB4OIK\\W:&_ +M\`S")0E<-+T0@,X>C_JHEW@8Q/S^\C]TF]'$*NJ.?`(CRCG"1>:0:C\,=9'Z +M*0``),9:ZV!=&7ZKGSWY4ZJ5]&0U\,R-7&\,)V:!(0@&_)()*0``'```0`0J +M<8'<0YW+K2R+TH7O\(?L-$M]M@```!P``$`%_+Y%($)\WJH:3TBB8,"`L&>E +M&4(+$[=&+$H#`)@!``"8`0```@```$4``91MZ0``0!$``,"H`0'`J`$"`?0! +M]`&`!V6G&%M\(IF--@``````````(2`B"`````````%X(@``>````'0!`0`! +M`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,# +M```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,` +M``4#```(!````@````@$```.*```B``"``"F735K)U4648@97JLR`;5!50*@ +M%3PC!8W-FK2-#?E8D$;KYW8`(CAQM^*'#J:+0`JV7A/)4"C4W/FR3L'%J8-N +MO**>!D,I"SN?NJ(E+Z:_/-VAO_`,PB4)7#2]$(#.'H_ZJ)=X&,3\_O(_=)O1 +MQ"KJCGP"(\HYPD7FD&H_#'61^BD``"3&6NM@71E^JY\]^5.JE?1D-?#,C5QO +M#"=F@2$(!OR2"2D``!P``$`$*G&!W$.=RZTLB]*%[_"'[#1+?;8````<``!` +M!?R^12!"?-ZJ&D](HF#`@+!GI1E"#!.W1O5P`0"8`0``F`$```(```!%``&4 +M;?D``$`1``#`J`$!P*@!`@'T`?0!@`=E5+`_?1Y7]@<``````````"$@(@@` +M```````!>"(``'@```!T`0$``@,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M7ADG[1C.[F)/=_31JFJ\/H$J&<_()*ZZZSX%M%L*D +M8GJ9KK=DZA````'```0`7MI9=P31W,PPD":TN5_8'```````````A("((`````````7@B``!X````=`$!``(#```,`0`` +M#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```" +M`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$ +M```"````"`0```XH``"(``(``%X9'+U+A_\'S`K)C8R53=7I^T8SNYB3W?TT +M:IJO#Z!*AG/R"2NNNL^!;1;"I&)ZF7,*E4C^4"'1XG4780^. +M4/BX*%,55\+P6+PM*A)<&"Z[U40WRPI#52?1,AX/TO$KOJ';A\Q5G#KZ0=W+ +MD:"30A8==>V#AF=/*0``)#Z./Y*9$D`>9I(Z=CM9HPPXK7W\.$]B)Q12.L43 +M?/\X*0``'```0`2MM`O`I\!I)R'JW)Q0YN,'JW9.H0```!P``$`%[:67<$T= +MS,,)`FM+G)0#S:A^#><,$[=&5.L*`)@!``"8`0```@```$4``91M^P``0!$` +M`,"H`0'`J`$"`?0!]`&`!V54L#]]'E?V!P``````````(2`B"`````````%X +M(@``>````'0!`0`"`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R` +M#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,` +M``@#```!`P``"`,```4#```(!````@````@$```.*```B``"``!>&1R]2X?_ +M!\P*R8V,E4W5Z?M&,[N8D]W]-&J:KP^@2H9S\@DKKKK/@6T6PJ1B>IES',#H +MI?8'37X'BI5(_E`AT>)U%V$/CE#XN"A3%5?"\%B\+2H27!@NN]5$-\L*0U4G +MT3(>#]+Q*[ZAVX?,59PZ^D'=RY&@DT(6'77M@X9G3RD``"0^CC^2F1)`'F:2 +M.G8[6:,,.*U]_#A/8B<44CK%$WS_."D``!P``$`$K;0+P*?`:2VEEW!-'"(``'@```!T`0$``P,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``[1A!I#VT0WJ.(AC,A(?);>UCK\18.R=^Q':[.FOY/`VU +M9&W6F[RW=N<&%,X+2S(:B`8:L4@?P-DL`"J4JDJHDI```< +M``!`!-C&F),2()U#(%$1H^J-G:`^:+T=````'```0`4:`.`$<,\<0LQG`*!! +M3)V:YW*=8PT3MT:H(PP`F`$``)@!```"````10`!E&W^``!`$0``P*@!`<"H +M`0(!]`'T`8`'9;?L+E3M-.QX```````````A("((`````````7@B``!X```` +M=`$!``,#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```( +M`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$# +M```(`P``!0,```@$```"````"`0```XH``"(``(``.T80:0]M$-ZCB(8S(2' +MR6WM8Z_$6#LG?L1VNSIK^3P-M61MUIN\MW;G!A3."TLR&H@&&K'*2%.F'TMR +M1;Z5B@`4-D9(N8.;?OI.];V-"FN,3Y]Y[[?+IO6\^/SVEME980,LVFTP,6=R +M?`02M,VS1DEDM`Z&2@L%00[`58O\-6QC*0``)*^QN?H[ZA/Z=56K%SH%IY4P +MZ"S'E('\#9+``JE*I*J)*0``'```0`38QIB3$B"=0R!1$:/JC9V@/FB]'0`` +M`!P``$`%&@#@!'#/'$+,9P"@04R=FN=RG6,.$[=&'2,#`)@!``"8`0```@`` +M`$4``91M_P``0!$``,"H`0'`J`$"`?0!]`&`!V6W["Y4[33L>``````````` +M(2`B"`````````%X(@``>````'0!`0`#`P``#`$```R`#@"``P``#`$```R` +M#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(` +M``0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*``` +MB``"``#M&$&D/;1#>HXB&,R$A\EM[6.OQ%@[)W[$=KLZ:_D\#;5D;=:;O+=V +MYP84S@M+,AJ(!AJQRDA3IA]+>^W +MRZ;UO/C\]I;966$#+-IM,#%G5,.@LQY2!_`V2P`*I2J2JB2D``!P``$`$V,:8 +MDQ(@G4,@41&CZHV=H#YHO1T````<``!`!1H`X`1PSQQ"S&<`H$%,G9KG"(``'@```!T`0$`!`,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``M?0=8#=^N_&@SUW4&[O_U1H98`+VB-5YR/:@;L%7P(%13 +M,;6/!OGU@Y;Z*/$2J;XN,*G#JB5$%#0A%4YWU?*HSU'S(Y;W+@'38#STBJKI +M]@VX#U*?:D\/(BQR%/V6-P$I```D$#V;=.37/]<1"UA/J>6+-BYR_J-Z*K@# +M9ZY$3,1>Z5?7+SO\$#ZJ<;!-6,='#K.V0 +MS'J&6`"]HC5>BJX`W*D$'5AHSZ-$"5I`./````'0!`0`$`P``#`$```R` +M#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,` +M``@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!``` +M`@````@$```.*```B``"``"U]!U@-WZ[\:#/7=0;N__5%S>4S5&GF>N1$S$7 +MNE7UR\[_!`^JG&P35C'1PZSMD,QZAE@`O:(U7G(]J!NP5?`@5%,QM8\&^?6# +MEOHH\1*IOBXPJ<.J)404-"$53G?5\JC/4?,CEO +M:BD``!P``$`$MC_KY`"U;!6ZN#"#(6]]BN@;3F`````<``!`!7)&,7RD'A!U +M8:,^C1`E:0#CW-.U$!.W1C6I"`"8`0``F`$```(```!%``&4;@,``$`1``#` +MJ`$!P*@!`@'T`?0!@`=E-#H<@XJQTFT``````````"$@(@@````````!>"(` +M`'@```!T`0$`!P,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``?3A<+&Y<@^P7 +M4O52O:5\D7[3#DZ#*N`LQ-']C&[\(#N&41#6ZD6!KB/Z2=EMG7R!BZQY^Y,G +MV:)^?A!\<*D/U1WAY9$7<:UB^N.BIPI'*L+<2"W5&,^B)Z"10/C%MEHK=XMX +M#_54JBVY]PT@-J+&O43S75"^LEH*-9]P)D^,/X0I```D1)A`M#.3C(BS1:.R +M6.E03*`@[N?>XH()`?N3)]FB?GX0?'"I#]4=X>61%W&M8OKCHJ<*1RK" +MW$@MU1C/HB>@D4#XQ;9:*W>+>`_U5*HMN?<-(#:BQKU$\UU0OK):"C6?<"9/ +MC#^$*0``)$280+0SDXR(LT6CLECI4$R@(.[GWN*""0'+P````'0! +M`0`'`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$` +M``,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P`` +M"`,```4#```(!````@````@$```.*```B``"``!].%PL;ER#[!=2]5*]I7R1 +M?M,.3H,JX"S$T?V,;OP@.X91$-;J18&N(_I)V6V=?(&+K'G[DR?9HGY^$'QP +MJ0_5'>'ED1=QK6+ZXZ*G"D"(``'@```!T`0$`"`,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``P;T:]E$02XCYO*\TJ#WE&8093XO1J0_ND:R2K,D!DT,GD;1?Y4#.WLNN4';(F1/[WU +M&U)U8]LA$BI,+=(+5MNS.HUK.TKJ,C%]U(?%T'5QS#AO5M\@6UFWD\@I```D +MV3?/+A!;$XB3D[`0<;R];TWN?I>=^$UT>PX!GC?LS/,I```<``!`!.Q@X2Q? +M#$)"JR$VH[/Z9YPD\'M+````'```0`6?HW'WT>LRIA6-U4,Z%W^P6OU'BO-*@]Y1F$&4^+T:D/[I&LDJS)`9 +M-#)Y&T7^5`SM[+KE!VR)D3^]]1M2=6/;(1(J3"W2"U;;LSJ-:SM*ZC(Q?=2' +MQ=!U<<)/![2P```!P``$`%GZ-Q +MW,\SKFQ)Q2=-^DH=/[&4SE42$[=&TTX*`)@!``"8`0```@```$4``91N"``` +M0!$``,"H`0'`J`$"`?0!]`&`!V7!>^1G'7##[P``````````(2`B"``````` +M``%X(@``>````'0!`0`(`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$` +M``R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P`` +M`@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``#!O1KV +M41!+B/F]R9VS!T[CL@N*"BJ]2]:U*XVJJ#:WM]'K,J85C=5#.A=_L%K]1XKS +M2H/>49A!E/B]&I#^Z1K)*LR0&30R>1M%_E0,[>RZY0=LB9$_O?4;4G5CVR$2 +M*DPMT@M6V[,ZC6L[2NHR,7W4A\70=7',.&]6WR!;6;>3R"D``"39-\\N$%L3 +MB).3L!!QO+UO3>Y^EYWX371[#@&>-^S,\RD``!P``$`$[&#A+%\,0D*K(3:C +ML_IGG"3P>TL````<``!`!9^C<=S/,ZYL2<4G3?I*'3^QE,Y5$Q.W1J-="`"8 +M`0``F`$```(```!%``&4;AL``$`1``#`J`$!P*@!`@'T`?0!@`=E]9S48[ZQ +M`F@``````````"$@(@@````````!>"(``'@```!T`0$`"0,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``K38\*#:U.?#>RWA>I/G!X$\\Q,GVKAM$/3.^=CP_ +M#\!F@LL4!V`E?5I+HC75",`6*&V\ET43Y0Y3G+AS.)N'H@0'#-+8/$/!9MAZ +MV-$XZ.@SZ0B*:MT@B[L:]AVL@T,;0<#);_JI7/0Y@DRTF<7#H`YX;0*AN=9&QQE*?THI +M```<``!`!)FEB];52EC/^_90RA6`1D\G1.?6````'```0`50F#,7&P0-BG1^ +MXHAK,4+WQB@@HQ,3MT:.APL`F`$``)@!```"````10`!E&X=``!`$0``P*@! +M`<"H`0(!]`'T`8`'9?6!//,3)]JX;1#TSOG8\/P_`9H++%`=@)7U:2Z(UU0C`%BAMO)=%$^4. +M4YRXMC1..CH,^D(BFK=((N[&O8=K(-#&T'`R6_Z +MJ5ST.8),M)G%PZ`.>&T'-B:"HY&B:UL[P%9C*0``)#W-$Y:C@;"T8'X9K"=0 +M0)H8)2JN).'BH;G61L<92G]**0``'```0`29I8O6U4I8S_OV4,H5@$9/)T3G +MU@```!P``$`%4)@S%QL$#8IT?N*(:S%"]\8H(*,4$[=&L88"`)@!``"8`0`` +M`@```$4``91N(0``0!$``,"H`0'`J`$"`?0!]`&`!V7UG-1COK$":``````` +M````(2`B"`````````%X(@``>````'0!`0`)`P``#`$```R`#@"``P``#`$` +M``R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P`` +M"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```. +M*```B``"``"M-CPH-K4Y\-[+>%ZD^<'@3SS$R?:N&T0],[YV/#\/P&:"RQ0' +M8"5]6DNB-=4(P!8H;;R711/E#E.B!`<,TM@\0\%FV'K8T3CHZ#/I +M"(IJW2"+NQKV':R#0QM!P,EO^JE<]#F"3+29Q<.@#GAM!S8F@J.1HFM;.\!6 +M8RD``"0]S1.6HX&PM&!^&:PG4$":&"4JKB3AXJ&YUD;'&4I_2BD``!P``$`$ +MF:6+UM5*6,_[]E#*%8!&3R=$Y]8````<``!`!5"8,Q<;!`V*='[BB&LQ0O?& +M*""C%1.W1N20``"8`0``F`$```(```!%``&4;B(``$`1``#`J`$!P*@!`@'T +M`?0!@`=E$[X*D(`5^*8``````````"$@(@@````````!>"(``'@```!T`0$` +M`P,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``5L`!?-6\?'O/$VLP&9@`V0LY +M*$>RNBZ=1J01.2_F%%B2MZ5F9[H*'O/)G#]IU7VW>CL^$?Z2;I&1_L!4I$-! +M'^A*Z-S+2I/#=O0^>_!L+Y*RJNLIEE;8=C\;WK57-R]"._)*P*RV'LF8 +M$^$;R8&]GGO,@I4I```<``!`!">R3$-$PXRPJ4P'MWDD%*7WK[AI````'``` +M0`4[*6*Q20+0UC.Z7;$H+C-,I#RDP143MT8@OP,`F`$``)@!```"````10`! +ME&XG``!`$0``P*@!`<"H`0(!]`'T`8`'91.^"I"`%?BF```````````A("(( +M`````````7@B``!X````=`$!``,#```,`0``#(`.`(`#```,`0``#(`.`0`# +M```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,` +M``@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(` +M`%;``7S5O'Q[SQ-K,!F8`-D+.2A'LKHNG4:D$3DOYA18DK>E9F>Z"A[SR9P_ +M:=5]MWH[/A'^DFZ1D?[`5*1#01_H2NC_Y/#@=AX,0\@@Z5L!MW6A(A.P0F@??9)*0``)+B" +M&[=Q:9$^&:+.46MWBL"LMA[)F!/A&\F!O9Y[S(*5*0``'```0`0GLDQ#1,., +ML*E,![=Y)!2E]Z^X:0```!P``$`%.REBL4D"T-8SNEVQ*"XS3*0\I,$5$[=& +MH@`*`)@!``"8`0```@```$4``91N+```0!$``,"H`0'`J`$"`?0!]`&`!V43 +MO@J0@!7XI@``````````(2`B"`````````%X(@``>````'0!`0`#`P``#`$` +M``R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@`` +M`@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```( +M!````@````@$```.*```B``"``!6P`%\U;Q\>\\3:S`9F`#9"SDH1[*Z+IU& +MI!$Y+^846)*WI69GN@H>\\FM5#$/((.E +M;`;=UH2(3L$)H'WV22D``"2X@ANW<6F1/AFBSE%K=XK`K+8>R9@3X1O)@;V> +M>\R"E2D``!P``$`$)[),0T3#C+"I3`>W>204I?>ON&D````<``!`!3LI8K%) +M`M#6,[I=L2@N,TRD/*3!%A.W1DL."`"8`0``F`$```(```!%``&4;C0``$`1 +M``#`J`$!P*@!`@'T`?0!@`=EA/IUV/3)9MD``````````"$@(@@````````! +M>"(``'@```!T`0$`!`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``Q?H"?Z)6 +MZ='^!V?XLJ*S8*J/7.X&!9?A\SSH?R4=<5]XY*"#B:DAT7Q2G=_#?OS.2MP9 +ME=83>YGBS:`45D#0H^>13[N.(MA344X-*@D4MW>[`O#I##B5J6FM%0WM//T" +MWX!6`LV*8Y$.VI$(2.M(&`+Z5>9VXQYT'7Q_,4NM-?8I```D<(H]F6*.W3P^ +MIX>:J3)"I[SF]+>C0)':<$@O85;)!0XI```<``!`!*!0AYS2L"NIP\HFYR%! +M\-Y;0JZ,````'```0`5),<,^<2Q62/-H\FO.C`DQ<)8&6Q83MT8..0L`F`$` +M`)@!```"````10`!E&XV``!`$0``P*@!`<"H`0(!]`'T`8`'983Z==CTR6;9 +M```````````A("((`````````7@B``!X````=`$!``0#```,`0``#(`.`(`# +M```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(` +M``$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"```` +M"`0```XH``"(``(``,7Z`G^B5NG1_@=G^+*BLV"JCUSN!@67X?,\Z'\E'7%? +M>.2@@XFI(=%\4IW?PW[\SDK<&976$WN9XLV@%%9`T*/GD4^[CB+84U%.#2H) +M%+=WNP+PZ0PXE:EIK14-[3S]`M^`5@+-BF.1#MJ1"$CK2!@"^E7F=N,>=!U\ +M?S%+K37V*0``)'"*/9EBCMT\/J>'FJDR0J>\YO2WHT"1VG!(+V%6R04.*0`` +M'```0`2@4(>6T*NC````!P``$`%23'#/G$L5DCS:/)K +MSHP),7"6!EL7$[=&@3@"`)@!``"8`0```@```$4``91N.0``0!$``,"H`0'` +MJ`$"`?0!]`&`!V6$^G78],EFV0``````````(2`B"`````````%X(@``>``` +M`'0!`0`$`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P`` +M"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```! +M`P``"`,```4#```(!````@````@$```.*```B``"``#%^@)_HE;IT?X'9_BR +MHK-@JH]<[@8%E^'S/.A_)1UQ7WCDH(.)J2'1?%*=W\-^_,Y*W!F5UA-[F>+- +MH!160-"CYY%/NXXBV%-13@TJ"12W=[L"\.D,.)6I::T5#>T\_0+?@%8"S8IC +MD0[:D0A(ZT@8`OI5YG;C'G0=?'\Q2ZTU]BD``"1PBCV98H[=/#ZGAYJI,D*G +MO.;TMZ-`D=IP2"]A5LD%#BD``!P``$`$H%"'G-*P*ZG#RB;G(4'PWEM"KHP` +M```<``!`!4DQPSYQ+%9(\VCR:\Z,"3%PE@9;&!.W1E]&``"8`0``F`$```(` +M``!%``&4;D```$`1``#`J`$!P*@!`@'T`?0!@`=E%SR3M1:FP=8````````` +M`"$@(@@````````!>"(``'@```!T`0$`!0,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``<;QRVXK8.D\^K!>>ANF*_&`UC:%4&NQ5;+$Q]*7C;XD42M*>"!,4H76%&\Z4)#5N'A5!KL56RQ,?2G+A5=DCBHM0()B>E6:4 +MUK*XJ_I'2*=@6(*]/.KYD24"*0``)-PN-K87EXW,I/NXO=0B$T848?,F[\TD +M]>(X2JM6NS+G*0``'```0`1V+W[Q3>TS%T,+$C._&3\GRR)TY@```!P``$`% +M[W1TL:N)>4K$`8@.ITN@Y\1ZX_(8$[=&4K()`)@!``"8`0```@```$4``91N +M0@``0!$``,"H`0'`J`$"`?0!]`&`!V47/).U%J;!U@``````````(2`B"``` +M``````%X(@``>````'0!`0`%`P``#`$```R`#@"``P``#`$```R`#@$``P`` +M#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```( +M`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``!Q +MO'+;BM@Z3SZL%YZ&Z8K\8#6-IRMUI\7R^5EFN2OA()EB2,)`MV8(2VX>U2CC +M9B#VRS7U9>'!4A7!('!*LV%UBN@ZGF^)%$K2G@@3%*%UA1O.E"0U;AX50:[% +M5LL3'TIRX579(XJ+4""8GI5FE-:RN*OZ1TBG8%B"O3SJ^9$E`BD``"3<+C:V +M%Y>-S*3[N+W4(A-&%&'S)N_-)/7B.$JK5KLRYRD``!P``$`$=B]^\4WM,Q=# +M"Q(SOQD_)\LB=.8````<``!`!>]T=+&KB7E*Q`&(#J=+H.?$>N/R&1.W1AN^ +M!P"8`0``F`$```(```!%``&4;D0``$`1``#`J`$!P*@!`@'T`?0!@`=E=-1L +M,,7"UTP``````````"$@(@@````````!>"(``'@```!T`0$`"`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``('68/\_DVDXUY[K1@C%4*A*U88B2-MFE8@>0 +M1KG2\`3,JT$I9V:,WE6975+Y[W6/_]&T]QL*-[ZOLZN?_WXVL3VQG;%E%AT- +M+DP0GH#^IH_CU!?:H695CMH)\LJ`0=99J*^-]%5!#P'QU$.6]H3*H,E?CL,I +MAC+A(-`YL2',-G\I```D#HV#>ZT8(Q5"H2M6&(DC;9I6('D$:YTO`$S*M!*6=FC-Y5F5U2^>]UC__1M/<; +M"C>^K[.KG_]^-K$]L9VQ918=#2Y,$)Z`_J:/X]07VJ%F58[:"?+*@$'66:BO +MC?1500\!\=1#EO:$RJ#)7X[#*88RX2#0.;$AS#9_*0``)`Z-@W.7P'>@Q\BY +MS09T$SG,/+UEE>=&\I@R)%TYL?%H*0``'```0`0E4-J73;;Z1UYJ;!T589IV +M%F248````!P``$`%I8^;Y_OR>11118[FJ`+W1X[.'````'0!`0`(`P``#`$```R`#@"``P`` +M#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```! +M`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$ +M```.*```B``"```@=9@_S^3:3C7GNM&",50J$K5AB)(VV:5B!Y!&N=+P!,RK +M02EG9HS>59E=4OGO=8__T;3W&PHWOJ^SJY__?C:Q/;&=L646'0TN3!">@/ZF +MC^/4%]JA9E6.V@GRRH!!UEFHKXWT54$/`?'40Y;VA,J@R5^.PRF&,N$@T#FQ +M(:FP=%6&:=A9DE&`````<``!`!:6/F^?[\GD4446.YJ@" +M]T>.SAW-&A.W1F,X#P"8`0``F`$```(```!%``&4;E$``$`1``#`J`$!P*@! +M`@'T`?0!@`=E^GC!EZ,+PI<``````````"$@(@@````````!>"(``'@```!T +M`0$`"0,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``/$7> +MEN?E%2*B926>='E=0_IJ7`6-[FTUA1[@QL4$9:O`D+8R9$=@M0.AN98K#TZT +MDV4]$3*8!O5?7B-V>^WJ@50U)QVOH)HVQZ(R+3VOCP06:+8)#`1,3.G7R/-@>JQL3MT:*(@,`F`$``)@!```"```` +M10`!E&Y3``!`$0``P*@!`<"H`0(!]`'T`8`'9?IXP9>C"\*7```````````A +M("((`````````7@B``!X````=`$!``D#```,`0``#(`.`(`#```,`0``#(`. +M`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@`` +M!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"( +M``(``#Q%W#Q7-Z8B/,42A]NGGI;GY14BHF4EGG1Y74/Z:EP%C>YM-84>X,;% +M!&6KP)"V,F1'8+4#H;F6*P].M)-E/1$RF`;U7UXC=GOMZH%4-2<=KZ":-L>B +M,BT]KX\$%FBV"0P$3$SIW(=T1N,MX0`D-GXX9*NKG=(NIM!:<14J`KIK*0`` +M)$9<0J=JVU%=6FAQ]!R-I>T+%!Z2A#XU((38V0C23VTE*0``'```0`0`#>6< +M!MQ8^[?*N'V%A;#/&Q)FQP```!P``$`%8ZX.SCQ51#N,RVBP9I7E\CS8'JL; +M$[=&&V0)`)@!``"8`0```@```$4``91N5```0!$``,"H`0'`J`$"`?0!]`&` +M!V7Z>,&7HPO"EP``````````(2`B"`````````%X(@``>````'0!`0`)`P`` +M#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```( +M`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4# +M```(!````@````@$```.*```B``"```\1=P\5S>F(CS%$H?;IYZ6Y^45(J)E +M)9YT>5U#^FI(W9[[>J!5#4G':^@FC;'HC(M/:^/!!9HM@D,!$Q,Z=R'=$;C+>$`)#9^ +M.&2KJYW2+J;06G$5*@*Z:RD``"1&7$*G:MM175IHDH0^-2"$ +MV-D(TD]M)2D``!P``$`$``WEG`;<6/NWRKA]A86PSQL29L<````<``!`!6.N +M#LX\540[C,MHL&:5Y?(\V!ZK'!.W1N-Q!P"8`0``F`$```(```!%``&4;ET` +M`$`1``#`J`$!P*@!`@'T`?0!@`=E>9I]X`\$$?$``````````"$@(@@````` +M```!>"(``'@```!T`0$`"@,```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``9&[Q +MX.?8-I=+.!(7H]*]QL'0='54!_7_W^$E/VY!%A[]Z?P35->9EAL]$>=^)P9C +ME[E*+30;*NL,!3.>I\:_O7%VN8[6#!R08$]E?9?0.O`GBQLEM[NP&]V\0SCI +MU3,E;$95;LQLB7=+$"6T1<6]X>B^$@J]HMX)+/[1^T)0ZN`I```D9HHT/6_; +M!8[%QL>PQQ&/-G.OTLY2A]&'DS^X8>OQ?VHI```<``!`!'0_'M]I&_G@;<@. +M,H258ML;*.7+````'```0`48W21+Q/^U@[DZZ5?M(GB-+>JQXAP3MT:=G`H` +MF`$``)@!```"````10`!E&Y>``!`$0``P*@!`<"H`0(!]`'T`8`'97F:?>`/ +M!!'Q```````````A("((`````````7@B``!X````=`$!``H#```,`0``#(`. +M`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P`` +M"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```" +M````"`0```XH``"(``(``&1N\>#GV#:72S@2%Z/2O<;!T'1U5`?U_]_A)3]N +M018>_>G\$U37F98;/1'G?B<&8Y>Y2BTT&RKK#`4SGJ?&O[UQ=KF.U@P[L!O=O$,XZ=4S)6Q&56[,;(EW2Q`EM$7%O>'HOA(*O:+> +M"2S^T?M"4.K@*0``)&:*-#UOVP6.Q<;'L,<1CS9SK]+.4H?1AY,_N&'K\7]J +M*0``'```0`1T/Q[?:1OYX&W(#C*$E6+;&RCERP```!P``$`%&-TD2\3_M8.Y +M.NE7[2)XC2WJL>(=$[=&W9L!`)@!``"8`0```@```$4``91N7P``0!$``,"H +M`0'`J`$"`?0!]`&`!V5YFGW@#P01\0``````````(2`B"`````````%X(@`` +M>````'0!`0`*`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#` +M`P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@# +M```!`P``"`,```4#```(!````@````@$```.*```B``"``!D;O'@Y]@VETLX +M$A>CTKW&P=!T=50']?_?X24_;D$6'OWI_!-4UYF6&ST1YWXG!F.7N4HM-!LJ +MZPP%,YZGQK^]<7:YCM8,')!@3V5]E]`Z\">+&R6WN[`;W;Q#..G5,R5L1E5N +MS&R)=TL0);1%Q;WAZ+X2"KVBW@DL_M'[0E#JX"D``"1FBC0];]L%CL7&Q[#' +M$8\V3/[AAZ_%_:BD``!P``$`$=#\>WVD;^>!MR`XRA)5BVQLH +MY(TMZK'B'1.W1@/K#@"8`0``F`$` +M``(```!%``&4;F```$`1``#`J`$!P*@!`@'T`?0!@`=EJHU7TT[0UCD````` +M`````"$@(@@````````!>"(``'@```!T`0$`"P,```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``,Z]!_!5BR]W3]]"9P)!(Q$V&'\V%Z+>.B@[WWCQ+.1T4,&6CPL3H!"\@.4/*:U;&`8"8 +MX4\I```D.,822%]O^Q$FS^FCG>S*]"HT4SHHR!/6Y_8@@@XSW$$I```<``!` +M!(,A5J%\RY1IE%_O:RH%CPJF#\)+````'```0`5FAD876WDORGD<3UDP>:R' +M6);O-!X3MT9[U`(`F`$``)@!```"````10`!E&YC``!`$0``P*@!`<"H`0(! +M]`'T`8`'9:J-5]-.T-8Y```````````A("((`````````7@B``!X````=`$! +M``L#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0`` +M`P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```( +M`P``!0,```@$```"````"`0```XH``"(``(``#.O0?P58LO=T_?0F<"02,1- +MAA_-A>BWCHH'-UE^-Z?>*[-96`XI&#`NF&[QLXFV+Z!42Z\G&MBAG:3/0@3C +MX*)C.EZG:72X;*7Q,R``BK+#/4MTTK96Q#:=$=T(L4@Z?-N@H/GN]]X\2SD= +M%#!EH\+$Z`0O(#E#RFM6Q@&`F.%/*0``)#C&$DA?;_L1)L_IHYWLRO0J-%,Z +M*,@3UN?V(((.,]Q!*0``'```0`2#(5:A?,N4:91?[VLJ!8\*I@_"2P```!P` +M`$`%9H9&%UMY+\IY'$]9,'FLAUB6[S0>$[=&"Q8)`)@!``"8`0```@```$4` +M`91N:P``0!$``,"H`0'`J`$"`?0!]`&`!V6JC5?33M#6.0``````````(2`B +M"`````````%X(@``>````'0!`0`+`P``#`$```R`#@"``P``#`$```R`#@$` +M`P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0# +M```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``" +M```SKT'\%6++W=/WT)G`D$C$388?S87HMXZ*!S=9?C>GWBNS65@.*1@P+IAN +M\;.)MB^@5$NO)QK8H9VDST($X^"B8SI>IVETN&RE\3,@`(JRPSU+=-*V5L0V +MG1'="+%(.GS;H*#Y[O?>/$LY'10P9:/"Q.@$+R`Y0\IK5L8!@)CA3RD``"0X +MQA)(7V_[$2;/Z:.=[,KT*C13.BC($];G]B""#C/<02D``!P``$`$@R%6H7S+ +ME&F47^]K*@6/"J8/PDL````<``!`!6:&1A=;>2_*>1Q/63!YK(=8EN\T'Q.W +M1B(B!P"8`0``F`$```(```!%``&4;G<``$`1``#`J`$!P*@!`@'T`?0!@`=E +M;11P('J$`"0``````````"$@(@@````````!>"(``'@```!T`0$`#0,```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``F>Z:XW*'%.W1H(V=/DZ`@0<-@0:U(C^6>/\FFPF3<(\1AFQW`SZ!?2_E'1%BI\8^IZHEY<1 +M$/"VO._)AS-0@FU#=O$I```DV4R'5VO#H3=EK=S:@NW0O%$K2$,8'M>0DL;[ +M-;B0")Y8I/4BJ[2P.[S818!%%.M+]0MP6"3$.GB(_EGC_)IL)DW"/$89 +ML=P,^@7TOY1T18J?&/J>J)>7$1#PMKSOR8@``0!$``,"H`0'`J`$"`?0!]`&`!V5M%'`@>H0` +M)```````````(2`B"`````````%X(@``>````'0!`0`-`P``#`$```R`#@"` +M`P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@" +M```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@`` +M``@$```.*```B``"``"9[IKCUY"2QOLUN)`(ERD` +M`!P``$`$=B!O.6J!.7%5"#!&CFC/+F?;A7$````<``!`!5=7R*^%9(>2M2A@ +M.$S&7['^,("-(!.W1G6<#@"8`0``F`$```(```!%``&4;GL``$`1``#`J`$! +MP*@!`@'T`?0!@`=E#$\;H2=>V_8``````````"$@(@@````````!>"(``'@` +M``!T`0$`#@,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``Y@H0)YQ#>MMWQ^0P +M+**;?FJ%N*M+-OFV):*%71N(OR983M&D=_?AQ,A"([B#^./MY07R= +MFNC?"I>$S!LN/JF^C*BXR%MFTT)J/VL,KX9K>Y]OD6%ZSJ*I@V1O&U79=Q7` +M````'```0`605^V0^V1P`@/C>!IYQT4.TMU$]"$3MT8@A@(`F`$``)@!```" +M````10`!E&Y\``!`$0``P*@!`<"H`0(!]`'T`8`'90Q/&Z$G7MOV```````` +M```A("((`````````7@B``!X````=`$!``X#```,`0``#(`.`(`#```,`0`` +M#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```( +M`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH +M``"(``(``.8*$"><0WK;=\?D,"RBFWYJA;BK2S;YMB6BA5T7,]]FUGKB+\F6 +M$[1I'?WX<3(0B.X@_CC[>4%\G9KHWPJ7A,P;+CZIOHRHN,A;9M-":CW,+G4K +M=-F4$#1T))M",\&P>;%73R_/Z^39R>E"//BQ#YI3\7,'MK#*^&:WN?;Y%A>G +M*0``),JG$!=,IJNG/?^,HR")OJ8,Z;I;^HL`SU9L&0;ZFZCH*0``'```0`2K +MXDLI`)M3'LZBJ8-D;QM5V7<5P````!P``$`%D%?MD/MD<`(#XW@:><=%#M+= +M1/0A$[=&R<<(`)@!``"8`0```@```$4``91N?0``0!$``,"H`0'`J`$"`?0! +M]`&`!V4,3QNA)U[;]@``````````(2`B"`````````%X(@``>````'0!`0`. +M`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,# +M```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,` +M``4#```(!````@````@$```.*```B``"``#F"A`GG$-ZVW?'Y#`LHIM^:H6X +MJTLV^;8EHH5=%S/?9M9ZXB_)EA.T:1W]^'$R$(CN(/XX^WE!?)V:Z-\*EX3, +M&RX^J;Z,J+C(6V;30FH]S"YU*W39E!`T="2;0C/!L'FQ5T\OS^ODV"(``'@```!T`0$`#P,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M2XJ2[Z>G3%0,*(?^V.VK:X;K[LF\P8S2H +M(Y-&Q1='F91OK()HRE9P4#H.08844P"+T>[6;7-X417-C.AOW3KRTPC^[2$# +M\3\(I@@^50/\T/KS;*JJNB8\P+I;VHO2&1UYOT?Z52JQ9QU!&>LI```DR:L] +M#;#+8IXPG%L"%%"LMV,Z$@#G,53<_%"Z[3O4L@T167R(3MT8> +M``H`F`$``)@!```"````10`!E&Z)``!`$0``P*@!`<"H`0(!]`'T`8`'91#& +M1%'+\Y!1```````````A("((`````````7@B``!X````=`$!``\#```,`0`` +M#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```" +M`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$ +M```"````"`0```XH``"(``(``$N*DN^GITQ4#"B'_MCMJVG-_2>@K71XQ,@; +M+X7(0*ZRL8H[7N&Z^[)O,&,TJ".31L471YF4;ZR":,I6<%`Z#D&&%%,`B]'N +MUFUS>%$5S8SH;]TZ\M,(_NTA`_$_"*8(/E4#_-#Z\VRJJKHF/,"Z6]J+TAD= +M>;]'^E4JL6<=01GK*0``),FK/0VPRV*>,)Q;`A10K+=C.A(`YS%4W/Q0NNT[ +MU+('*0``'```0`1IM9T=H?C:J^`(:O&4"G2*N!*>+@```!P``$`%.&@NM1>V +MA\\.:*R/_S/CGWM$5E\C$[=&=/\``)@!``"8`0```@```$4``91NB@``0!$` +M`,"H`0'`J`$"`?0!]`&`!V40QD11R_.040``````````(2`B"`````````%X +M(@``>````'0!`0`/`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R` +M#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,` +M``@#```!`P``"`,```4#```(!````@````@$```.*```B``"``!+BI+OIZ=, +M5`PHA_[8[:MIS?TGH*UT>,3(&R^%R$"NLK&*.U[ANONR;S!C-*@CDT;%%T>9 +ME&^L@FC*5G!0.@Y!AA13`(O1[M9M[_D` +M`````````"$@(@@````````!>"(``'@```!T`0$`$`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``GZRXN(LB,Z!LE&PUXZL-=/)IM96*\@N,"P>:.6^[W>+M +M"^KDVT?R$`]NF<;O3%.X)<:OY$K1X!VFWD0BWYR_D8Z`^S4`*2H/,,BJ\7IT +M][88,[_L2WLKU)WQ[/WI750JO4M-C_I`CLU(%/36D]K5T.=KSR[-$5+,X6:% +MT/Y7<,@I```DA1_$)?Z\^8^<_/QP4T]S)K`$"5E1B,<5AA0FW*"&8H@I```< +M``!`!*[_`3KX6#Z_U?P +MH*Q$LB:1^203MT8-.`(`F`$``)@!```"````10`!E&Z2``!`$0``P*@!`<"H +M`0(!]`'T`8`'9:D!4YX2'N_Y```````````A("((`````````7@B``!X```` +M=`$!`!`#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```( +M`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$# +M```(`P``!0,```@$```"````"`0```XH``"(``(``)^LN+B+(C.@;)1L->.K +M#73R:;65BO(+C`L'FCEON]WB[0OJY-M'\A`/;IG&[TQ3N"7&K^1*T>`=IMY$ +M(M^V&#._[$M[*]2=\>S]Z5U4*KU+38_Z0([- +M2!3TUI/:U=#G:\\NS1%2S.%FA=#^5W#(*0``)(4?Q"7^O/F/G/S\<%-/$A[O^0`````````` +M(2`B"`````````%X(@``>````'0!`0`0`P``#`$```R`#@"``P``#`$```R` +M#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(` +M``0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*``` +MB``"``"?K+BXBR(SH&R4;#7CJPUT\FFUE8KR"XP+!YHY;[O=XNT+ZN3;1_(0 +M#VZ9QN],4[@EQJ_D2M'@':;>1"+?G+^1CH#[-0`I*@\PR*KQ>G3WMA@SO^Q+ +M>RO4G?'L_>E=5"J]2TV/^D".S4@4]-:3VM70YVO/+LT14LSA9H70_E=PR"D` +M`"2%'\0E_KSYCYS\_'!33W,FL`0)65&(QQ6&%";"(``'@```!T`0$`$P,` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``4\)NGR%:?#Y!_,/M:+N;ISH7XM\! +M9^!A#_MP*5YEUJP>!-:E;CW+,YA).4_*\.O!)1]QJR[N?R1;10H,GW7SNC]8 +MW>Z[12#^S:GF"CQ:Z=YA.1H9(G[15SP9S`4R>]\KM+,7V&P$D&'1K'\D6M7=)O4._D6Z_.Y%KV+<41:81"FK +MN9=:L'@36I6X]RS.823E/RO#K +MP24?<:LN[G\D6T4*#)]U\[H_6-WNNT4@_LVIY@H\6NG>83D:&2)^T5<\&8FFM +MH09+4_L`)XGG+P```!P``$`%:CV8;`ZA!DLRRE)BPUICB-`6H=(F$[=&0;$` +M`)@!``"8`0```@```$4``91NHP``0!$``,"H`0'`J`$"`?0!]`&`!V4BA/*U +M!U&#!```````````(2`B"`````````%X(@``>````'0!`0`3`P``#`$```R` +M#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,` +M``@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!``` +M`@````@$```.*```B``"``!3PFZ?(5I\/D'\P^UHNYNG.A?BWP%GX&$/^W`I +M7F76K!X$UJ5N/8*/%KIWF$Y&ADB?M%7/!G,!3)[WRNTLQ?8;`208=&L=R*\L_@[U[R1:U=T +MF]0[^1;K\[D6MRD``"2TI8#/`SMQQ(Y8'UH@D#9[8MQ1%IA$*:NYR40JJS2^ +M:2D``!P``$`$403'F)IG(F\7K:$&2U/[`">)YR\````<``!`!6H]F&P.H09+ +M,LI28L-:8XC0%J'2)A.W1IG]#0"8`0``F`$```(```!%``&4;J@``$`1``#` +MJ`$!P*@!`@'T`?0!@`=ERT^7%Q3Z*F0``````````"$@(@@````````!>"(` +M`'@```!T`0$`%`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``WR!-ADMSME%G +MF"/@J7QQW"?,EF?DZ-<@EGW:$P7!$N")F;LQK3S9Q_H*3-")7@KMJ\Y@.HND +MO:-)*NZT:TOI&/%G\L'['6/$=-I59C&Q;W_YMPOK:I"X"`>_!7-T+18\31F0 +M`PUF',4/:)ACTHE"J:QM#=5ZZW1O'!^JUX0&[6(I```DE?PZ>[6Z4F[@0)(: +M;ED#![+@W!@%R3@"P:NB&A\10W8I```<``!`!"Z.[`L]C4DLE41MLM&".?3* +M`.=K````'```0`7\.#QK^=]/$SB2.#(!IW\`XI)PKB<3MT;6Z0$`F`$``)@! +M```"````10`!E&ZK``!`$0``P*@!`<"H`0(!]`'T`8`'9RX-P8!````'0! +M`0`4`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$` +M``,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P`` +M"`,```4#```(!````@````@$```.*```B``"``#?($V&2W.V46>8(^"I?''< +M)\R69^3HUR"6?=H3!<$2X(F9NS&M/-G'^@I,T(E>"NVKSF`ZBZ2]HTDJ[K1K +M2^D8\6?RP?L=8\1TVE5F,;%O?_FW"^MJD+@(![\%"(``'@```!T`0$`%0,```P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``+7)?/#BE2*9W.[C?@50"47)U@:6=]U*>+!4LQR"COLT;!_&+!*I7Z%1P +MT^:$ZVQM\.)W#@C#>ZID@?&($-"YY@G>;)*GF"TJZWPI```D +M^OA*+R/H@0RZ1>_^T2"*S<"-8SP0*`:&"NDP>_(WJ8\I```<``!`!)1YL,J5 +MZBNVO,RN_E9PJ"E)D,;?````'```0`7#`S"OB!X?2^_\U(E.(,&D'OU6"R@3 +MMT;N8PD`F`$``)@!```"````10`!E&Z[``!`$0``P*@!`<"H`0(!]`'T`8`' +M981+@OKH]II2```````````A("((`````````7@B``!X````=`$!`!4#```, +M`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@" +M```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,` +M``@$```"````"`0```XH``"(``(``"UR7SPXI4BF=SNXWX%4`E%R=8&EG?=2 +MGBP5+,<@H[[-&P?QBP2J5^A4<-/FA.ML;?#B=PX(PWNJ9('QB!#0N>8)WFR2 +MIY@G+C;A^C*T+BO?49#G5[Y>;1V0J+I)K58N<*T9,N%Z`Z:YR,DH>_GS_-ET +M/W^FPN^15GM*NM\*0``)/KX2B\CZ($,ND7O_M$@BLW`C6,\$"@&A@KI +M,'OR-ZF/*0``'```0`24>;#*E>HKMKS,KOY6<*@I29#&WP```!P``$`%PP,P +MKX@>'TOO_-2)3B#!I![]5@LI$[=&$V,``)@!``"8`0```@```$4``91NO@`` +M0!$``,"H`0'`J`$"`?0!]`&`!V6$2X+ZZ/::4@``````````(2`B"``````` +M``%X(@``>````'0!`0`5`P``#`$```R`#@"``P``#`$```R`#@$``P``#`$` +M``R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P`` +M`@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"```M8)RXVX?HRM"XKWU&0YU>^7FT=D*BZ2:U6 +M+G"M&3+A>@.FNICRD``!P``$`$E'FPRI7J*[:\S*[^ +M5G"H*4F0QM\````<``!`!<,#,*^('A]+[_S4B4X@P:0>_58+*1.W1M>Q#0"8 +M`0``F`$```(```!%``&4;L0``$`1``#`J`$!P*@!`@'T`?0!@`=E+;JZ)+U% +M0(,``````````"$@(@@````````!>"(``'@```!T`0$`_P,```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``2LVHN)*GV=H,+QZ`N)[,)F`BJ+-!324E4<)_]++/ +M8+XWE[&M/HN(U=CG';6 +M7Q3#)WMDHH&#U,&N#0`EPPT!:)(55_:HF21`?%"*7GT71]^YV<4GE;)?2:V/ +M#N$+(!-^E.0G.C'^$6P4S2H3MT:,FP$`F`$``)@!```"````10`!E&[%``!`$0``P*@! +M`<"H`0(!]`'T`8`'92VZNB2]14"#```````````A("((`````````7@B``!X +M````=`$!`/\#```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`# +M```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,` +M``$#```(`P``!0,```@$```"````"`0```XH``"(``(``$K-J+B2I]G:#"\> +M@+B>S"9@(JBS04TE)5'"?_2RSV"^-Y7+2G&P-DYZ.9=3VQA5GU:\35,(_*4Y +M/%*F&!`.7#'NQK3Z+B-78YQVUE\4PR=[9**!@]3!K@T`)<,-`6B2%5?VJ)DD +M0'Q0BEY]%T??N=G%)Y6R7TFMCP[A"R')$"W1*0``)`F44"+[RO=>E'@3?I3D +M',XI;R.GUUA,HRR1$)(H??S&*0``'```0`1K)ZS?BFWIW,,9ND.^PU'T:2;M +M-0```!P``$`%;\(E[M)G[!ZPI^(?7CHQ_A%L%,TJ$[=&*=T'`)@!``"8`0`` +M`@```$4``91NR@``0!$``,"H`0'`J`$"`?0!]`&`!V4MNKHDO45`@P`````` +M````(2`B"`````````%X(@``>````'0!`0#_`P``#`$```R`#@"``P``#`$` +M``R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P`` +M"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```. +M*```B``"``!*S:BXDJ?9V@PO'H"XGLPF8"*HLT%-)251PG_TLL]@OC>5RTIQ +ML#9.>CF74]L859]6O$U3"/RE.3Q2IA@0#EPQ[L:T^BXC5V.<=M9?%,,G>V2B +M@8/4P:X-`"7##0%HDA57]JB9)$!\4(I>?1='W[G9Q2>5LE])K8\.X0LAR1`M +MT2D``"0)E%`B^\KW7I1X$WZ4Y!S.*6\CI]=83*,LD1"2*'W\QBD``!P``$`$ +M:R>LWXIMZ=S#&;I#OL-1]&DF[34````<``!`!6_")>[29^P>L*?B'UXZ,?X1 +M;!3-*Q.W1JGH!0"8`0``F`$```(```!%``&4;M@``$`1``#`J`$!P*@!`@'T +M`?0!@`=E/V`_:D6GF3,``````````"$@(@@````````!>"(``'@```!T`0$` +M@`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``!:)MO:WLS4$-J\*2IW]&T1P1 +M;3GC0W$2?J?,V5#LZ%5L]LG.%,>#R)J3S +M+:)G[![#K\DJAY/N"YY]/5;#/`1X````'``` +M0`5[5]4L$S.M64XU7=A^B47EK(JAA2L3MT:?%0D`F`$``)@!```"````10`! +ME&[;``!`$0``P*@!`<"H`0(!]`'T`8`'93]@/VI%IYDS```````````A("(( +M`````````7@B``!X````=`$!`(`#```,`0``#(`.`(`#```,`0``#(`.`0`# +M```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,` +M``@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(` +M``6B;;VM[,U!#:O"DJ=_1M$<$6TYXT-Q$GZGS-E0W`3D>J%=VRGP)'(%KE:9 +MT5D^S*X*A6E_G^S$4:,^],>(N"HMNK5BPZ_)*H>3[@N>?3U6PW(9*0``)-NJ +MD&`ZKND&T.-GR=QP[[_"\CW!9V("FG"HX5FZ3B03*0``'```0`22E^#%Y[XW +M%EP2/8G8-YY$7CP$>````!P``$`%>U?5+!,SK5E.-5W8?HE%Y:R*H84L$[=& +M_A0``)@!``"8`0```@```$4``91O6@``0!$``,"H`0'`J`$"`?0!]`&`!V4_ +M8#]J1:>9,P``````````(2`B"`````````%X(@``>````'0!`0"``P``#`$` +M``R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@`` +M`@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```( +M!````@````@$```.*```B``"```%HFV]K>S-00VKPI*G?T;1'!%M.>-#<1)^ +MI\S94-P$Y'JA7=LI\"1R!:Y6F=%9/LRN"H5I?Y_LQ%&C/O3'B+@J+;JU8G+) +MN\Y#6$F^\!7*JVP2-I8"-GY&4,K>_!KUZSH56SVR>^-Q9<$CV)V#>>1%X\!'@````<``!`!7M7U2P3 +M,ZU93C5=V'Z)1>6LBJ&%+!.W1M-@#0"8`0``F`$```(```!%``&4;UL``$`1 +M``#`J`$!P*@!`@'T`?0!@`=EXX]=?34"7<(``````````"$@(@@````````! +M>"(``'@```!T`0$`#`````P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``:2[VB/;6 +M2'A]VN]'B0),`N6U-1H'I^\;#2?'TYY6;;C7SY;$:AA1_XL7)6KZ8?<6ND^#K\>Y(FXS*/&8,H; +MBB4#'FF#5G5!R.PP;OZW.@"GRX.EZ,I[)A_/*?)4D +MS*\K]:KS````'```0`7EX#RTITEUM-&A*?G14S4)S+8&;BT3MT9;30$`F`$` +M`)@!```"````10`!E&]<``!`$0``P*@!`<"H`0(!]`'T`8`'9>./77TU`EW" +M```````````A("((`````````7@B``!X````=`$!``P````,`0``#(`.`(`# +M```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(` +M``$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"```` +M"`0```XH``"(``(``&DN]HCVUDAX?=KO1XD"3`+EM34:!Z?O&PTGQ].>5FVX +MW,U.F@^`OZU9,B_6X`ZW(1!QOC5H:_`?Q$!\+-^NW6\67E\^6Q&H84?^+%R5 +MJ^F'W%KI/@Z_'N2)N,RCQF#*&XHE`QYI@U9U0C*>R8? +MSW)1_]17*0``)`J8O?I%O[B?E-`"<8!Z=>P0[G0D,G6(PWD)@RQCPJ2L*0`` +M'```0`1UPG#=`[]=)"VWBGR5),RO*_6J\P```!P``$`%Y>`\M*=)=;31H2GY +MT5,U"``` +M`'0!`0`,````#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P`` +M"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```! +M`P``"`,```4#```(!````@````@$```.*```B``"``!I+O:(]M9(>'W:[T>) +M`DP"Y;4U&@>G[QL-)\?3GE9MN-S-3IH/@+^M63(OUN`.MR$0<;XU:&OP'\1` +M?"S?KMUO%EY?/EL1J&%'_BQ:8-6 +M=4'([#!N_KG7L +M$.YT)#)UB,-Y"8,L8\*DK"D``!P``$`$=<)PW0._720MMXI\E23,KROUJO,` +M```<``!`!>7@/+2G276TT:$I^=%3-0G,M@9N+A.W1FR:!0"8`0``F`$```(` +M``!%``&4;VL``$`1``#`J`$!P*@!`@'T`?0!@`=E4UM^=966N1@````````` +M`"$@(@@````````!>"(``'@```!T`0$`#`$```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``K8SP%\"2N2S5<`)A7L(-A![5_BN#1?AGN&6E66XH>/L'Y##/Q=_GG8 +M?"X3MT9?QP@`F`$``)@!```"````10`!E&]L``!`$0``P*@!`<"H`0(!]`'T +M`8`'95-;?G65EKD8```````````A("((`````````7@B``!X````=`$!``P! +M```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,` +M``@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P`` +M!0,```@$```"````"`0```XH``"(``(``*V,\!?`DKDLU7`"85['-HI(Z"7$KU?XK@T7X9[AEI5EN*'C +M[!^0PS\7?YW(B_YB"F+STH_3J9])4V`[\/T#K=YH,,^:>33.Q"5"_9?G%Z9) +M&"SFW"[[\[]*>%%KW.^!1%OO*0``)&,=>/D;=+MN1YC````'0!`0`,`0``#`$```R`#@"``P``#`$```R`#@$``P`` +M#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```( +M`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``"M +MC/`7P)*Y+-5P`F%>QS7(Z0XBDZNH[2K[!8[EF\6GJ*2.@EQ*W,Z-1KH'0T'5 +MAX@V$'M7^*X-%^&>X9:59;BAX^P?D,,_%W^=R(O^8@IB\]*/TZF?25-@._#] +M`ZW>:##/FGDTSL0E0OV7YQ>F21@LYMPN^_._2GA1:]SO@41;[RD``"1C'7CY +M&W2[;D>8W,12B2HP,SJ;+P&JB0\6]O$^#L1?B>AZ=A\+Q.W1B(1 +M#0"8`0``F`$```(```!%``&4;VX``$`1``#`J`$!P*@!`@'T`?0!@`=EH[;8 +MDK)JX^D``````````"$@(@@````````!>"(``'@```!T`0$`#`(```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``._[#\QG?O8Z7$U]9']<0!C+643GF!JJ\]2O1 +M>'"-'8[W:?2XF95/C/MO%?N60,^]WA3%>QS8QY%-SO;7:Z.E!*1+=;6\(ONR +M*LA`A%7^`;!5[D:<`&;N#@"TV`"%>%&FNESF)585>#!0%*C)^R&13>);MRZ.K6?HA[.:T*,&+V$+\ZD+0-RM +MF)8I```<``!`!*'F(0#6*-^&2,!>1",GZV!6C_YD````'```0`5O_PFM8D'Y +MC'[^$#?,%\/?&A:<^3`3MT8I_P``F`$``)@!```"````10`!E&]O``!`$0`` +MP*@!`<"H`0(!]`'T`8`'9:.VV)*R:N/I```````````A("((`````````7@B +M``!X````=`$!``P"```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`. +M`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P`` +M"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``#O^P_,9W[V. +MEQ-?61_7$`8RUE$YY@:JO/4KT7APC1V.]VGTN)F53XS[;Q7[ED#/O=X4Q7L< +MV,>13<[VUVNCI02D2W6UO"+[LBK(0(15_@&P5>Y&G`!F[@X`M-@`A7A1IKI< +MYB56%7@P4!2HR?LAD4WB7(9*,QZ+[([R:,P+^1)**0``)%-)U5NH[@6WF[SFM"C!B]A"_.I"T#````'0!`0`,`@``#`$```R`#@"``P`` +M#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```! +M`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$ +M```.*```B``"```[_L/S&=^]CI<37UD?UQ`&,M91.>8&JKSU*]%X<(T=CO=I +M]+B9E4^,^V\5^Y9`S[W>%,5['-C'D4W.]M=KHZ4$I$MUM;PB^[(JR$"$5?X! +ML%7N1IP`9NX.`+38`(5X4::Z7.8E5A5X,%`4J,G[(9%-XER&2C,>B^R.\FC, +M"_D22BD``"132=5;J.X%MYNW+HZM9^B'LYK0HP8O80OSJ0M`W*V8EBD``!P` +M`$`$H>8A`-8HWX9(P%Y$(R?K8%:/_F0````<``!`!6__":UB0?F,?OX0-\P7 +MP]\:%ISY,1.W1CI-!0"8`0``F`$```(```!%``&4;W(``$`1``#`J`$!P*@! +M`@'T`?0!@`=EK560S/8G_WH``````````"$@(@@````````!>"(``'@```!T +M`0$`#`0```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``43$P5?7B@GL(VNMZ`*7Q +MAT;RL&&;HO(\K_JV<6Y;6U[781S'&]_Y<[::^DY-J0[Q_3,B4DMS.O8B/1<# +M2UE3+-G?BFQ0FV*-A-RAL-N<;63;$?T@HXO_!;L1X<;A+0XYEKJ&K_?+9*(! +MQ+'U2O;%F,'HFUR/??#H1US88-9"DZTI```DFC[D2AX2$@)VU;KX5(4*!3F0 +MI76`FLBBJ.Q=,R_.,L@I```<``!`!%'4RVZ!A#\A/.%QZ2WQP9U,_XM&```` +M'```0`4JIY+R3@AR43%<:`O&\(2$`CUS_#$3MT8N>0@`F`$``)@!```"```` +M10`!E&]S``!`$0``P*@!`<"H`0(!]`'T`8`'9:U5D,SV)_]Z```````````A +M("((`````````7@B``!X````=`$!``P$```,`0``#(`.`(`#```,`0``#(`. +M`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@`` +M!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"( +M``(``%$Q,%7UXH)["-KK>@"E\8=&\K!AFZ+R/*_ZMG%N6UM>UV$'&X2T..9:ZAJ_WRV2B`<2Q]4KVQ9C!Z)M$A("=M6Z^%2%"@4YD*5U@)K(HJCL73,OSC+(*0``'```0`11U,MN +M@80_(3SA<>DM\<&=3/^+1@```!P``$`%*J>2\DX(```0!$``,"H`0'`J`$"`?0!]`&` +M!V6M59#,]B?_>@``````````(2`B"`````````%X(@``>````'0!`0`,!``` +M#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```( +M`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4# +M```(!````@````@$```.*```B``"``!1,3!5]>*">PC:ZWH`I?&'1O*P89NB +M\CRO^K9Q;EM;7M=A',<;W_ESMIKZ3DVI#O'],R)22W,Z]B(]%P-+65,LV=^* +M;%";8HV$W*&PVYQM9-L1_2"CB_\%NQ'AQN$M#CF6NH:O]\MDH@'$L?5*]L68 +MP>B;7(]]\.A'7-A@UD*3K2D``"2:/N1*'A(2`G;5NOA4A0H%.9"E=8":R**H +M[%TS+\XRR"D``!P``$`$4=3+;H&$/R$\X7'I+?'!G4S_BT8````<``!`!2JG +MDO)."')1,5QH"\;PA(0"/7/\,A.W1N/$#`"8`0``F`$```(```!%``&4;X,` +M`$`1``#`J`$!P*@!`@'T`?0!@`=E?Q3.@T=ML3(``````````"$@(@@````` +M```!>"(``'@```!T`0$`#`0```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``_VZ2 +M&LDZ#>4#(A&QC'Q_X2H)`0&4QCP"&"[B5"!;JR"O_XE;%EBS;U$%^#F83V,* +M7U4A;80<6*&)^)5AB%&T3!7]"<'DBZK_1B[8SEN'5'_*]X/U".F/+)5MO^%U +MRR7L4-X&$,@KL3T-F43GQR+HC/IG-6SBG/`+'*RAG1://8`I```DM=`O(_5[CH"P.4J_I&D:0SN2^CC7DB",&C:C`(I```<``!`!'9!!>7-0\:R[Z[" +M?C&P"PB_FJR#````'```0`5>>7#]0CICRR5;;_A=!A#(*[$]#9E$Y\XZ`L#E*OZ1I&D,[DOHXUY(@C!HVHP" +M*0``'```0`1V007ES4/&LN^NPGXQL`L(OYJL@P```!P``$`%7GEW.8\N$>01 +M6\NF=-KD"Q(?*STS$[=&FO(&`)@!``"8`0```@```$4``91OC@``0!$``,"H +M`0'`J`$"`?0!]`&`!V5_%,Z#1VVQ,@``````````(2`B"`````````%X(@`` +M>````'0!`0`,!```#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#` +M`P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@# +M```!`P``"`,```4#```(!````@````@$```.*```B``"``#_;I(:R3H-Y0,B +M$;&,?'_A*@D!`93&/`(8+N)4(%NK(*__B5L66+-O407X.9A/8PI?52%MA!Q8 +MH8GXE6&(4;1,%?T)P>2+JO]&+MC.6X=4?\KW@_4(Z8\LE6V_X77+)>Q0W@80 +MR"NQ/0V91.?'(NB,^F2((P:-J,`BD``!P``$`$=D$%Y"(``'@```!T`0$`#`<```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``-$Z_)=\!`9V;MJ,>M081L,QO&IH>_U+/GP)R%^MD@B"\-KJX +MODK?8]D^9=H9&B;1P>;L7+FL:U15J%^#LD*CU/R09!/B4H=I_+_]:MR.)&$3+:M!N'053IDY!QM'[ +M"PPI```DF4>.=$FM+Y^64]2Z83(I**`,;5]3XN651X"\7P^=AY`I```<``!` +M!'RB58:R!8UI>8F4_LCR*$SV,WLS````'```0`4R/`*<0NM#A_#.YW>$[!,8 +MPH>>]C03MT85*P@`F`$``)@!```"````10`!E&^=``!`$0``P*@!`<"H`0(! +M]`'T`8`'98,G#RI1TX4,```````````A("((`````````7@B``!X````=`$! +M``P'```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0`` +M`P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```( +M`P``!0,```@$```"````"`0```XH``"(``(``#1.OR7?`0&=F[:C'K4&$;#, +M;QJ:'O]2SY\"`O%\/G8>0*0``'```0`1\HE6&L@6-:7F)E/[(\BA,]C-[,P```!P` +M`$`%,CP"G$+K0X?PSN=WA.P3&,*'GO8T$[=&;6P.`)@!``"8`0```@```$4` +M`91OH0``0!$``,"H`0'`J`$"`?0!]`&`!V6#)P\J4=.%#```````````(2`B +M"`````````%X(@``>````'0!`0`,!P``#`$```R`#@"``P``#`$```R`#@$` +M`P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0# +M```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``" +M```T3K\EWP$!G9NVHQZU!A&PS&\:FA[_4L^?`G(7ZV2"(+PVNKB^2M]CV3YE +MVAD:)M'!YNQ^K,X=NKJ4T:VB+(\EX^ +M)2AVG\O]R7*^C0<[+M^7V^25[UJW(XD81,MJT&X=!5.F3D'&T?L+#"D``"29 +M1XYT2:TOGY93U+IA,BDHH`QM7U/BY95'@+Q?#YV'D"D``!P``$`$?*)5AK(% +MC6EYB93^R/(H3/8S>S,````<``!`!3(\`IQ"ZT.'\,[G=X3L$QC"AY[V-1.W +M1DEZ#`"8`0``F`$```(```!%``&4;ZH``$`1``#`J`$!P*@!`@'T`?0!@`=E +MB1@RG%1ZW=\``````````"$@(@@````````!>"(``'@```!T`0$`#`@```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``YEUPCYD'IGT&(L6?+%QI/#2$`&(>:7"5 +MXE@EY.AC7P>8F4?V#QW\\!KUL=!.=;BT2[PG7:YVF+;41\J\SX'?N7NL8%&'M8:UI/[L1G +MJ-859=0I```<``!`!%V$5Y?VRHS2"6UR9O;.>,XIVPQU````'```0`4S_(_- +M_DE$L?8EET*H@WCO=TMC.C83MT;`8@``F`$``)@!```"````10`!E&^M``!` +M$0``P*@!`<"H`0(!]`'T`8`'98D8,IQ4>MW?```````````A("((```````` +M`7@B``!X````=`$!``P(```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0`` +M#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```" +M`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``.9=<(^9 +M!Z9]!B+%GRQ<:3PTA`!B'FEPE>)8)>3H8U\'F)E']@\=_/`:];'03G6XM$N\ +M''_.:DPR,)D%\&DQQ3IFW;G?AOU90A&'Q?C$%S]_G%0\NVD2JI<,M^HM!@Y* +M$DJL-*W-OHYJN?M65/5\-MO>*0``)'IUVN=IBVU$ +M?*O,^!W[E[K&!1A[6&M:3^[$9ZC6%674*0``'```0`1=A%>7]LJ,T@EM````'0!`0`,"```#`$```R`#@"` +M`P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@" +M```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@`` +M``@$```.*```B``"``#F77"/F0>F?08BQ9\L7&D\-(0`8AYI<)7B6"7DZ&-? +M!YB91_8/'?SP&O6QT$YUN+1+O!Q_SFI,,C"9!?!I,<4Z9MVYWX;]64(1A\7X +MQ!<_?YQ4/+MI$JJ7#+?J+08.2A)*K#2MS;Z.:KGW+C_F=&&6X;$\H[X$2=7K +M5E3U?#;;WBD``"1Z==KG:8MM1'RKS/@=^Y>ZQ@48>UAK6D_NQ&>HUA5EU"D` +M`!P``$`$7817E_;*C-();7)F]LYXSBG;#'4````<``!`!3/\C\W^242Q]B67 +M0JB#>.]W2V,Z-Q.W1B&Q!`"8`0``F`$```(```!%``&4;[@``$`1``#`J`$! +MP*@!`@'T`?0!@`=E\+,U=K='8&\``````````"$@(@@````````!>"(``'@` +M``!T`0$`#`D```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``#O+Y[YA8&Q2)`&8= +METE&:N==46#6I<.]')"G5#[PY7(=_(%B,L>Z]G._U8OJDBY.$2)/13<3MT:9W`<`F`$``)@!```" +M````10`!E&^Y``!`$0``P*@!`<"H`0(!]`'T`8`'9?"S-7:W1V!O```````` +M```A("((`````````7@B``!X````=`$!``P)```,`0``#(`.`(`#```,`0`` +M#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```( +M`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH +M``"(``(```[R^>^86!L4B0!F'9=)1FKG75%@UJ7#O1R0IU0^\.5R'?R!8C+' +MNO9SO]6+ZI(N7,MYD^<])S:L@>1+.!#VTVMOG#U22Z+>B[?U51OS>SUC&>7G +M*/57%P(TG7_Q>.>#%X:('WQ'V.R,76=H@K9JP"\Z&=@:CK(X:-U<'ZGX]X?W +M*0``)#FL6-)V;U.X3HQ5\UX+9OE`[T"%XY8?O"M"=)[>F9UL*0``'```0`1( +MVETN"@^X.Q2[\:7P:<;$&S6)B````!P``$`%,12+TFF&:]Y7/9V'CA$B +M3T4W$[=&0!X.`)@!``"8`0```@```$4``91ON@``0!$``,"H`0'`J`$"`?0! +M]`&`!V7PLS5VMT=@;P``````````(2`B"`````````%X(@``>````'0!`0`, +M"0``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,# +M```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,` +M``4#```(!````@````@$```.*```B``"```.\OGOF%@;%(D`9AV7249JYUU1 +M8-:EP[T9/G/2&B!]\1]CLC%UG:(*V +M:L`O.AG8&HZR.&C=7!^I^/>']RD``"0YK%C2=F]3N$Z,5?->"V;Y0.]`A>.6 +M'[PK0G2>WIF=;"D``!P``$`$2-I=+@H/N#L4N_&E\&G&Q!LUB8@````<``!` +M!3$4B])IAFO>5W(SWCV=AXX1(D]%.!.W1K`J#`"8`0``F`$```(```!%``&4 +M;[\``$`1``#`J`$!P*@!`@'T`?0!@`=EEORT.M:R#C8``````````"$@(@@` +M```````!>"(``'@```!T`0$`#/H```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MGY72G!J5(3G(PUK<),T]\DYP2:=O-#`6&#OO"YQ=E]&OW$!!T1V?/^P<."[I +M!YFL0RS3NA$"E(VL+86M$8^Y?2$QB*,XC[X<>K[Z*Y/:X)K+R\JSH"S4>T^R +MIU#6^Y]'ULSD'J(]EW[)\!'J6\-`=S@NH.:.KB5"F2-#!0(HNB`I```D-(RS +M+:)M"(_/Q>2E%I58PEG9X)S`EZW*2VKJ.KX6J7,I```<``!`!'$+&ZT9C4/^ +MCCI)G'0J7^0TPEM*````'```0`5'##K'A$]`+I9?943;@W9K/P2/C#D3MT9I +M%```F`$``)@!```"````10`!E&_!``!`$0``P*@!`<"H`0(!]`'T`8`'99;\ +MM#K6L@XV```````````A("((`````````7@B``!X````=`$!``SZ```,`0`` +M#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```" +M`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$ +M```"````"`0```XH``"(``(``)^5TIP:E2$YR,-:W"3-/?).<$FG;S0P%A@[ +M[PN<79?1K]Q`0=$=GS_L'#@NZ0>9K$,LT[H1`I2-K"V%K1&/N7TA,8BC.(^^ +M''J^^BN3VN":R\O*LZ`LU'M/LJ=0UON?1];,Y!ZB/9=^R?`1ZEO#0'"MRDMJZCJ^ +M%JES*0``'```0`1Q"QNM&8U#_HXZ29QT*E_D-,);2@```!P``$`%1PPZQX1/ +M0"Z67V5$VX-V:S\$CXPY$[=&'58&`)@!``"8`0```@```$4``91OQP``0!$` +M`,"H`0'`J`$"`?0!]`&`!V66_+0ZUK(.-@``````````(2`B"`````````%X +M(@``>````'0!`0`,^@``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R` +M#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,` +M``@#```!`P``"`,```4#```(!````@````@$```.*```B``"``"?E=*<&I4A +M.HCV7?LGP$>I;PT!W."Z@YHZN)4*9(T,%`BBZ("D``"0TC+,MHFT(C\_% +MY*46E5C"6=G@G,"7K$3T`NEE]E1-N#=FL_!(^,.A.W1B5B!`"8`0`` +MF`$```(```!%``&4;](``$`1``#`J`$!P*@!`@'T`?0!@`=EZ8T%SM[T*_,` +M`````````"$@(@@````````!>"(``'@```!T`0$`#/L```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``W)#P-3C5!MG&X]@M'-Q5R4HE)DT>8^?"Q/ZE)XB.'$:< +MHHGJ=][\W7#*C3$,\>911U"Y7,SYS:4@CW/$U5>_X+C%`[&8*#M^H)AQM!/! +M_XX2N-8I```D>Y_;N&OWGT"ZK#"ZI!SUH2GB<"@DZ1>V5OZ`&,`>+NPI```< +M``!`!"5OB\Q(6.8B>[/^W%AV%\[2-L(@````'```0`4B+R?W4#:P4`5W.)*( +M%N544STXO3H3MT:?C@<`F`$``)@!```"````10`!E&_:``!`$0``P*@!`<"H +M`0(!]`'T`8`'9>F-!<[>]"OS```````````A("((`````````7@B``!X```` +M=`$!``S[```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```( +M`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$# +M```(`P``!0,```@$```"````"`0```XH``"(``(``-R0\#4XU0;9QN/8+1S7 +M)9,KB+Q#N`]I.4:09Z&QNKO'96XVL]:%1%XKC77&3/FOVR#X9[J)=S/U*)GL +M5(CAQ&G**)ZG?>_-UPRHTQ#/'F44=0N5S,^````'0!`0`,^P``#`$```R`#@"``P``#`$```R` +M#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(` +M``0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*``` +MB``"``#AL;J[QV5N-K/6A41> +M*XUUQDSYK]L@^&>ZB7IWWOS= +M<,J-,0SQYE%'4+E?0+JL,+JD'/6A*>)P*"3I%[96_H`8P!XN["D``!P``$`$)6^+ +MS$A8YB)[L_[<6'87SM(VPB`````<``!`!2(O)_=0-K!0!7NHC)G)?%)4``````````"$@(@@````````!>"(``'@```!T`0$`#/P` +M``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P`` +M"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```% +M`P``"`0```(````(!```#B@``(@``@``HESGO+?B_'.CZ%VMX([[WM,SL@+` +MVSL1J&?Q7D@+>O;3K&T`8)AWQ]8N&D^:H],!DDR^5?X?7QW\.Y^X#1"VF_!& +MNH26&2KU`O+`2&>U6VMM8/7)8LQE0F2$#EX7F^IQL:)#`P&@V>=2\?29'VE5 +M]L5G&>M*F?R)_>,XE+T=1-,I```DJ=T[1$YFCI*C/A5;O.)(%J*,,@J5[H#: +M+L94JJD&W\LI```<``!`!%/H.(Z@1*+K>^2]EQR`3".^][3,[("P-L[$:AG\5Y("WKVTZQM`&"8=\?6+AI/FJ/3 +M`9),OE7^'U\=_#N?N`T0MIOP1KJ$EADJ]0+RP$AGM5MK;6#UR6+,94)DA`Y> +M%YOJ<;&B0P,!H-GG4O'TF1]I5?;%9QGK2IG\B?WC.)2]'433*0``)*G=.T1. +M9HZ2HSX56[SB2!:BC#(*E>Z`VB[&5*JI!M_+*0``'```0`13Z#B.H$2BZWOD +MO9<<@$W,_U=FXP```!P``$`%.).U)F\YH_S'W!9%P?L0RR+M+]L\$[=&U@<& +M`)@!``"8`0```@```$4``91O[```0!$``,"H`0'`J`$"`?0!]`&`!V5ZZB,F +M````'0!`0`,_```#`$```R` +M#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,` +M``@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!``` +M`@````@$```.*```B``"``"B7.>\M^+\TS.R`L#;.Q&H9_%> +M2`MZ]M.L;0!@F'?'UBX:3YJCTP&23+Y5_A]?'?P[G[@-$+:;\$:ZA)89*O4" +M\L!(9[5;:VU@];ZG&QHD,#`:#9YU+Q])D?:57VQ6<9ZTJ9 +M_(G]XSB4O1U$TRD``"2IW3M$3F:.DJ,^%5N\XD@6HHPR"I7N@-HNQE2JJ0;? +MRRD``!P``$`$4^@XCJ!$HNM[Y+V7'(!-S/]79N,````<``!`!3B3M29O.:/\ +MQ]P61<'[$,LB[2_;/1.W1B80!`"8`0``F`$```(```!%``&4;^T``$`1``#` +MJ`$!P*@!`@'T`?0!@`=ESA,W*QJ[0L,``````````"$@(@@````````!>"(` +M`'@```!T`0$`#/\```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``A>)<$$IV,?>E +M."'1A=7&]N@Q*B*V*7C__Q4'4="VNYU\QB?R*J*5"EE][X;XX+_L>T8,JYP` +M"0KP.A.5)+T,R4]6U@8U>HS_]V-=^D%-+Q.E]!P!OJ)DER7X8&J&+9&H"\W[ +M<+[PUZOEG5E4^TH.J//7_""U\&U73(A1@"CE9)\<^M +M\[:[````'```0`5Y(;E;C*%*654I:=6KGRN$7A/\Z3T3MT9)0`<`F`$``)@! +M```"````10`!E&_N``!`$0``P*@!`<"H`0(!]`'T`8`'9^&^."_['M&#*N<``D*\#H3E22]#,E/5M8&-7J,__=C7?I!32\3 +MI?0<`;ZB9)KY9U95/M*#JCSU_P@M?!M5TR(48'* +M3"FR*0``)%4#36(VP9O(F@0DY\9@M:W^TNA<@/B35=L:!0&)S//<*0``'``` +M0`1OG]C=C(B1O;H'@HY62?'/K?.VNP```!P``$`%>2&Y6XRA2EE5*6G5JY\K +MA%X3_.D]$[=&_8$-`)@!``"8`0```@```$4``91O]```0!$``,"H`0'`J`$" +M`?0!]`&`!V7.$S````'0! +M`0`,_P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$` +M``,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P`` +M"`,```4#```(!````@````@$```.*```B``"``"%XEP02G8Q]Z4X(=&%U<;V +MZ#$J(K8I>/__%0=1T+:[G7S&)_(JHI4*67WOAOC@O^Q[1@RKG``)"O`Z$Y4D +MO0S)3U;6!C5ZC/_W8UWZ04TO$Z7T'`&^HF27)?A@:H8MD:@+S?MPOO#7J^6= +M653[2@ZH\]?\(+7P;5=,B%&!RDPILBD``"15`TUB-L&;R)H$).?&8+6M_M+H +M7(#XDU7;&@4!B$_SI/A.W1H*6"P"8`0``F`$```(```!% +M``&4;_\``$`1``#`J`$!P*@!`@'T`?0!@`=E47_$74;MIX<``````````"$@ +M(@@````````!>"(``'@```!T`0$`#`````P!```,@`X`@`,```P!```,@`X! +M``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$ +M`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@` +M`@``]%?U?=&CHR[CIRRV!QGDFGJUDX3H9B1V-Y\8@8EL,%>TW*_^9.WQ4')% +M*USVFBT7[5QS/4BI5)!EZ&X0V/J,/-U(QCBQ!&:+'#I^X_HU`.$E[335I5MB +M8#Y(@$UD=,Z.>MB;5\P^M'!$$/PA-G8*#0"38Z74^&Y*LU`2*^QXQ2HI```D +M9CHB`7#(:6)KMAS@4R*ABE?_>U2BKDLLRM=)9>1__!PI```<``!`!"_T!5[I +M\\680&O^IDD%8BDY='+X````'```0`6Y'E@W^<1?%UKN)@K)=TK-EAZ6P3X3 +MMT9-N@X`F`$``)@!```"````10`!E'````!`$0``P*@!`<"H`0(!]`'T`8`' +M95%_Q%U&[:>'```````````A("((`````````7@B``!X````=`$!``P````, +M`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@" +M```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,` +M``@$```"````"`0```XH``"(``(``/17]7W1HZ,NXZ?&(&);#!7M-RO_F3M\5!R12M<]IHM%^U<AN$-CZC#S=2,8X +ML01FBQPZ?N/Z-0#A)>TTU:5;8F`^2(!-9'3.CGK8FU?,/K1P1!#\(39V"@T` +MDV.EU/AN2K-0$BOL>,4J*0``)&8Z(@%PR&EB:[8Z?/%F$!K_J9)!6(I.71R^````!P``$`%N1Y8 +M-_G$7Q=:[B8*R7=*S98>EL$_$[=&K;D%`)@!``"8`0```@```$4``91P'P`` +M0!$``,"H`0'`J`$"`?0!]`&`!V51?\1=1NVGAP``````````(2`B"``````` +M``%X(@``>````'0!`0`,````#`$```R`#@"``P``#`$```R`#@$``P``#`$` +M``R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P`` +M`@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``#T5_5] +MT:.C+N.G++8'&>2:>K63A.AF)'8WGQB!B6PP5[36#?YQ%\76NXF"LEW2LV6'I;!0!.W1OSM`P"8 +M`0``F`$```(```!%``&4<+X``$`1``#`J`$!P*@!`@'T`?0!@`=EHDV/[5Y< +MX$H``````````"$@(@@````````!>"(``'@```!T`0$`#`$```P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``:_NLW\CV:T682BR6`?S5KN%['7-<5)C/CQ1+'NI9 +MS,:<#W^;&)F//SE88XQ3!GNMI`HK[5(G<&5C_XW3N8%$#O\ +M,@/)GI4?N\XI```D'+UH!IK>V[[[D:R!B:_2Y)+#XR-W@1OX7V)`DV6['(8I +M```<``!`!,P$BG&K^P-O^4?'&`(CDT<.AR04````'```0`5I\F'I,VE3:0J? +MLP2X/\<^4J#HOT`3MT8]&@<`F`$``)@!```"````10`!E'),``!`$0``P*@! +M`<"H`0(!]`'T`8`'9:)-C^U>7.!*```````````A("((`````````7@B``!X +M````=`$!``P!```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`# +M```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,` +M``$#```(`P``!0,```@$```"````"`0```XH``"(``(``&O[K-_(]FM%F$HL +ME@'\U:[A>QUS7%28SX\42Q[J6").*HUH!)1'`U+!E_%:@5OP+ZD[_-K5W!T9KB4 +MA!\O5>5N2S3A?I:'````'0!`0`,`0``#`$```R`#@"``P``#`$` +M``R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P`` +M"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```. +M*```B``"``!K^ZS?R/9K19A*+)8!_-6NX7L=ZEG,QIP/?YL8 +MF8\_.5ACC%,&>ZVD"BOM4B=P96/_C=.Y@40.]P&C8YJC$,G@B3BJ-:`241P- +M2P9?Q6H%;\"^I._S:U=P=&:XE(0?+U7E;DLTX7Z6AW.7XL63A[PR`\F>E1^[ +MSBD``"0!&_A?8D"39;LDS:5-I"I^S!+@_QSY2 +MH.B_01.W1J*M"P"8`0``F`$```(```!%``&4=````$`1``#`J`$!P*@!`@'T +M`?0!@`=EB?#`//PC(>(``````````"$@(@@````````!>"(``'@```!T`0$` +M#`(```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``2%TZ3A_!]1EU!'^21D3O*WW4 +MZ=CBSTR/#0%1PSUA?OC4!'=T80NRQ,>M\7XE5A[*LND +M61NQ:\EC>8;6SH$I```<``!`!(QI,Z1P&>X.272:_//RKPR`7_!S";#FXDQQA?V>.TV%Y4$3MT9QX0X`F`$``)@!```"````10`! +ME'11``!`$0``P*@!`<"H`0(!]`'T`8`'98GPP#S\(R'B```````````A("(( +M`````````7@B``!X````=`$!``P"```,`0``#(`.`(`#```,`0``#(`.`0`# +M```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,` +M``@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(` +M`$A=.DX?W,0H@U["BF4CANV0.L/JW^*8T&ZQ)EZJL0Z;8A +MV3TM$M$),*QR7Y>8!8_PZDHD)+'@?7)FIV`IY^$2COQF5\7`JG\W658J+_M& +M2O5BU&RF%7D9=01_DD9$[RM]U.G8XL],CPT!4<,]87[XU`1W=&$'*0``))F$ +M)("RL["GKLL3'K?%^)58>RK+I%D;L6O)8WF&ULZ!*0``'```0`2,:3.D5"$[=& +MD^$%`)@!``"8`0```@```$4``91V0```0!$``,"H`0'`J`$"`?0!]`&`!V6) +M\,`\_",AX@``````````(2`B"`````````%X(@``>````'0!`0`,`@``#`$` +M``R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@`` +M`@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```( +M!````@````@$```.*```B``"``!(73I.']S$*(->PHIE(X;MD#K#ZM_BF-!N +ML29>JK$.FW*A$N:M^UF$/87F(=D]+1+1"3"L?A$H[\9E?%P*I_-UE6*B_[1DKU8M1LIA5Y&74$?Y)&1.\K?=3IV.+/3(\- +M`5'#/6%^^-0$=W1A!RD``"29A"2`LK.PIZ[+$QZWQ?B56'LJRZ19&[%KR6-Y +MAM;.@2D``!P``$`$C&DSI'`9[@Y)=)K\\_*O!R[BK9P````<``!`!2?-[(!? +M\',)L.;B3'&%_9X[387E0Q.W1I7M`P"8`0``F`$```(```!%``&4=S,``$`1 +M``#`J`$!P*@!`@'T`?0!@`=E>JBJG&>TP2X``````````"$@(@@````````! +M>"(``'@```!T`0$`#`0```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``/--/$(*# +M/TL3[%F".=TG[X`)?Z@L +MFNJ\(]PWT,_H!+#J86'S$?[`MU@/LMN!'+JA52Y]ZAI,QE,F=Q2UDVW\(!,. +M^E'X6"T#E,3144%4+LIUH4HV0J-;0=;/_,$'F)091RTI```D5B[#$P2="X`7 +M4C,(,GJ0P?]-H7>2F2,FUC'Q]5BQ(.PI```<``!`!#G@EX/(CS+;6M)LYK\4 +M2(!JH1-S````'```0`6R;]KI.Q]D)FQR%":E2REZ\ACS/D,3MT9/&@<`F`$` +M`)@!```"````10`!E'=```!`$0``P*@!`<"H`0(!]`'T`8`'97JHJIQGM,$N +M```````````A("((`````````7@B``!X````=`$!``P$```,`0``#(`.`(`# +M```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(` +M``$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"```` +M"`0```XH``"(``(``#S33Q""@S]+$^Q9@CG=)^^`"7+B2W,`PB],H?@#R?KD +M*<[]BE2:?NYE$R\#N:U%GG^H+)KJO"/<-]#/Z`2PZF%A\Q'^P+=8#[+;@1RZ +MH54N?>H:3,93)G<4M9-M_"`3#OI1^%@M`Y3$T5%!5"[*=:%*-D*C6T'6S_S! +M!YB4&4#R(\RVUK2;.:_%$B`:J$3O(8\SY#$[=&I5H-`)@!``"8`0```@```$4``91W3@``0!$``,"H`0'` +MJ`$"`?0!]`&`!V5ZJ*J<9[3!+@``````````(2`B"`````````%X(@``>``` +M`'0!`0`,!```#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P`` +M"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```! +M`P``"`,```4#```(!````@````@$```.*```B``"```\TT\0@H,_2Q/L68(Y +MW2?O@`ERXDMS`,(O3*'X`\GZY"G._8I4FG[N91,O`[FM19Y_J"R:ZKPCW#?0 +MS^@$L.IA8?,1_L"W6`^RVX$8E!E'+2D``"16+L,3!)T+@!=2,P@R>I#! +M_TVA=Y*9(R;6,?'U6+$@["D``!P``$`$.>"7@\B/,MM:TFSFOQ1(@&JA$W,` +M```<``!`!;)OVND['V0F;'(4)J5+*7KR&/,^1!.W1L]L"P"8`0``F`$```(` +M``!%``&4=UD``$`1``#`J`$!P*@!`@'T`?0!@`=E):DG8K.)Y7H````````` +M`"$@(@@````````!>"(``'@```!T`0$`#`4```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``7ZZNE4?P71B]'W=SA2>BIZ_V(NOBG9PR+W#DR-!PIZV*?_N8=],Q +MU,C99`"G=X)"?*E7;]C#_CL9/E+UE<7+P99X'>8&>(1)47,NSC;][/2-:G-8 +M3=7QR'.DZ`6G<-Z>,@YUH_18W<4)=/KG@_TM]1L32XI +M```DU-!\W\[ZMDAOKG6MC&<`]8K5Z```````````A("((`````````7@B``!X````=`$!``P% +M```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,` +M``@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P`` +M!0,```@$```"````"`0```XH``"(``(``%^NKI5'\%T8O1]WO]B+K +MXIV<,B]PY,C0<*>MBG_[F'?3,=3(V60`IW>"0GRI5V_8P_X[&3Y2]97%R\&6 +M>!WF!GB$25%S+LXV_>STC6IS6$W5\GC(.=:/T7*-QFT\ZZ_P> +M^YZCGF-W%"73ZYX/]+?4;$TN*0``)-30?-_.^K9(;ZYUK8QG`/6*W,%'R\EH +MQ`-\68EIM;6P*0``'```0`0**K.CW688&J%^!WQ.^E*-PC1_&@```!P``$`% +MJD#61W&1-8@``````````(2`B"``` +M``````%X(@``>````'0!`0`,!0``#`$```R`#@"``P``#`$```R`#@$``P`` +M#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```( +M`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``"``!? +MKJZ51_!=&+T?=W.%)Z*GK_8BZ^*=G#(O<.3(T'"GK8I_^YAWTS'4R-ED`*=W +M@D)\J5=OV,/^.QD^4O65QHYYC=Q0ET^N>#_2WU&Q-+BD``"34T'S? +MSOJV2&^N=:V,9P#UBMS!1\O):,0#?%F):;6UL"D``!P``$`$"BJSH]UF&!JA +M?@=\3OI2C<(T?QH````<``!`!:I`UD=QD36',DI#?_O&,_^7)\T.1A.W1CJ? +M`P"8`0``F`$```(```!%``&4>&,``$`1``#`J`$!P*@!`@'T`?0!@`=E4!%O +M![K>D9(``````````"$@(@@````````!>"(``'@```!T`0$`#`8```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``;%B554[4SFU<+.@(MA1Y9[',%W> +MW;,J@,#L,V[:-;*_>VI+HTS@]$$$H>&[Y=!JY6PL]#"A)3"CCHN>*(V"D[IY +MA6GL62P%3#H-IG4I```D":J"ZA=F5;9L'>R4M34]N5+>[CY-H<(DG02=^9%1)PT83MT;LR@8`F`$``)@!```"````10`!E'AH``!`$0`` +MP*@!`<"H`0(!]`'T`8`'95`1;P>ZWI&2```````````A("((`````````7@B +M``!X````=`$!``P&```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`. +M`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P`` +M"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``&Q8E55.U,Q@ +MUIM7"SH"+84>6>W-0:SKAR)4&$4L'?E?*7SH0!=5SX&""S7[K@V$RU1]U;3V +M=+E(LU?)-M5`9/M%*E@GAS!=WMVS*H#`[#-NVC6ROWMJ2Z-,X/1!!*'AN^70 +M:N5L+/0PH24PHXZ+GBB-@I.Z>85I[%DL!4PZ#:9U*0``)`FJ@NH79E6V;!WL +ME+4U/;E2WNX^7)9?GX99I)6`"=6**0``'```0`1@Z:11SN^SOG;TPV`H!:]5 +M:C@[-0```!P``$`%J````'0!`0`,!@``#`$```R`#@"``P`` +M#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```! +M`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@````@$ +M```.*```B``"``!L6)553M3,8-:;5PLZ`BV%'EGMS4&LZXQ9+`5, +M.@VF=2D``"0)JH+J%V95MFP=[)2U-3VY4M[N/ER67Y^&6:25@`G5BBD``!P` +M`$`$8.FD4<[OL[YV],-@*`6O56HX.S4````<``!`!:G*EO0<2*,1XVAPB2=! +M)WYD5$G#1Q.W1H48"P"8`0``F`$```(```!%``&4>-P``$`1``#`J`$!P*@! +M`@'T`?0!@`=EH?9U[BO1HH```````````"$@(@@````````!>"(``'@```!T +M`0$`#`<```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``#03"`XNE/='J;U#6&[-L +M&,\IASOZLIF52^"YN0T,%V+(79QTY*IO".001'S;X'_M5%%]I>,=`L5J4S,A +M1H_O>"-I]?`+@6CN+@"VLRQ?/FE@`QXXL'W?:[CX),:K=I+_PPPN);1E"+!> +M8B5,[U7A(B**EAJHR_?:;;<.)AQ/[@7 +MRV=8G72I(N=F-'R]IAXKT:*````````````A +M("((`````````7@B``!X````=`$!``P'```,`0``#(`.`(`#```,`0``#(`. +M`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@`` +M!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"( +M``(```T$P@.+I3W1ZF]0UANS;!C/*8<[^K*9E4O@N;D-#!=BR%V<=.2J;PCD +M$$1\V^!_[511?:7C'0+%:E,S(4:/[W@C:?7P"X%H[BX`MK,L7SYI8`,>.+!] +MWVNX^"3&JW:2_\,,+B6T90BP7F(E3.]5X2(BBI8:J,OWVFW'ZV]5\^#>*0`` +M)`PAZ2'<>=73QFWFW#B8<3^X%\MG6)UTJ2+G9C1\O:87*0``'```0`1M.##. +ME&?=&N$\CVZ2Q8LWQ.[/3P```!P``$`%^HD!&U7+,/P?/.[TF1:QQ"L8(W-( +M$[=&-T0%`)@!``"8`0```@```$4``91Y-@``0!$``,"H`0'`J`$"`?0!]`&` +M!V6A]G7N*]&B@```````````(2`B"`````````%X(@``>````'0!`0`,!P`` +M#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```( +M`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4# +M```(!````@````@$```.*```B``"```-!,(#BZ4]T>IO4-8;LVP8SRF'._JR +MF95+X+FY#0P78LA=G'3DJF\(Y!!$?-O@?^U447VEXQT"Q6I3,R%&C^]X(VGU +M\`N!:.XN`+:S+%\^:6`#'CBP?=]KN/@DQJMVDO_##"XEM&4(L%YB)4SO5>$B +M(HJ6&JC+]]IMQ^MO5?/@WBD``"0,(>DAW'G5T\9MYMPXF'$_N!?+9UB==*DB +MYV8T?+VF%RD``!P``$`$;3@PSI1GW1KA/(]NDL6+-\3NST\````<``!`!?J) +M`1M5RS#\'SSN])D6L<0K&"-S21.W1J51`P"8`0``F`$```(```!%``&4>4<` +M`$`1``#`J`$!P*@!`@'T`?0!@`=ETT4OPV"8@M$``````````"$@(@@````` +M```!>"(``'@```!T`0$`#`H```P!```,@`X`@`,```P!```,@`X!``,```P! +M```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,` +M``(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``&$&M +M6#GCJM3BU.-HX3P7J8@8WP4W=7`%I==OJEP@-M>D8+96YS(H+*2O9B&=\OQ0 +M:I$]8-AM60A5K27NW/K^E5*RI/<[PF.IT&03W/6&`$@-J/O<%N,.G5@D1>IG +MUKI'')6F.WHKY)_"'3UXX9>^(FF7@[`J[LP`:>YAU2`IZ#0I```DT(92!9`7 +M>E@+$H;ZE(SQ4VN'0RKM=B1))-VEV9H$JZ4I```<``!`!)Y5>*!8OF1=O9K( +MO%X+KTN1`S(I````'```0`4$WL!1,MEV'LO]5?2B')`/0J&L>TD3MT:C?`8` +MF`$``)@!```"````10`!E'E*``!`$0``P*@!`<"H`0(!]`'T`8`'9=-%+\-@ +MF(+1```````````A("((`````````7@B``!X````=`$!``P*```,`0``#(`. +M`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P`` +M"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```" +M````"`0```XH``"(``(``!A!K5@YXZK4XM3C:.$\%ZF(&-\%-W5P!:77;ZI< +M(#;7I&"V5N.&7OB)IEX.P*N[, +M`&GN8=4@*>@T*0``)-"&4@60%WI8"Q*&^I2,\5-KAT,J[78D223=I=F:!*NE +M*0``'```0`2>57B@6+YD7;V:R+Q>"Z]+D0,R*0```!P``$`%!-[`43+9=A[+ +M_57THAR0#T*AK'M)$[=&-;X,`)@!``"8`0```@```$4``91Y4P``0!$``,"H +M`0'`J`$"`?0!]`&`!V7312_#8)B"T0``````````(2`B"`````````%X(@`` +M>````'0!`0`,"@``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#` +M`P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@# +M```!`P``"`,```4#```(!````@````@$```.*```B``"```80:U8.>.JU.+4 +MXVCA/!>IB!C?!3=U<`6EUV^J7"`VUZ1@ME;G,B@LI*]F(9WR_%!JD3U@V&U9 +M"%6M)>[<^OZ54K*D]SO"8ZG09!/<]88`2`VH^]P6XPZ=6"1%ZF?6ND<BODG\(=/7CAE[XB:9>#L"KNS`!I[F'5("GH-"D``"30AE(%D!=Z6`L2AOJ4 +MC/%3:X=#*NUV)$DDW:79F@2KI2D``!P``$`$GE5XH%B^9%V]FLB\7@NO2Y$# +M,BD````<``!`!03>P%$RV78>R_U5]*(5X``$`1``#`J`$!P*@!`@'T`?0!@`=E"(``'@```!T`0$`#`L```P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``R2GYLT&K:CP]OF8Q7[ZZW#!1$=?CCUG#J"^1?M_K6N290=(2`^ZP]S'%'3^[@2( +MN1\I```D/LB!$O#HCU+./,IJZF>/O0B#J-^1-EFVSWE75BIXSZ?[!````'```0`5+7&:N#T)M%',&\`W9[)JL +MH/]IM$H3MT:C]@T`F`$``)@!```"````10`!E'EA``!`$0``P*@!`<"H`0(! +M]`'T`8`'97(;7*=R,*&R```````````A("((`````````7@B``!X````=`$! +M``P+```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0`` +M`P,```@"```"`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```( +M`P``!0,```@$```"````"`0```XH``"(``(``,DI^;-'#Y4,R8Q47;SZ[NU/ +M<8+8#O&Z?@/+HE:B*1U&[.A0]E/YRUS`YQ&,'`3V[?R%4(PC#=E/QI&49;$S +ME8P/Q4M2.#I]6K'^B(_[JSU9Q#"WAJVH\/;YF,5^^NMPP41'7XX]9PZ@OD7[ +M?ZUKDF4'2$@/NL/,^G*0``'```0`0<^R2@N^(!7:,B;B9_R;B"A'G^P0```!P` +M`$`%2UQFK@]";11S!O`-V>R:K*#_:;1+$[=&^O4$`)@!``"8`0```@```$4` +M`91Y:0``0!$``,"H`0'`J`$"`?0!]`&`!V5R&URG````'0!`0`,"P``#`$```R`#@"``P``#`$```R`#@$` +M`P``#`$```R`#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0# +M```(`P```@,```@#```!`P``"`,```4#```(!````@````@$```.*```B``" +M``#)*?FS1P^5#,F,5%V\^N[M3W&"V`[QNGX#RZ)6HBD=1NSH4/93^5=6*GC/IRD``!P``$`$'/LDH+OB +M`5VC(FXF?\FX@H1Y_L$````<``!`!4M<9JX/0FT4"(``'@```!T`0$`#`P```P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``^W5;N`G^%`A;8X^DI+%')NTIB><>&-HE +M@L@'9]`RU"PW^B)'P+T/ZFSUITK`G#5PP5C\3U$(WL9-NQO/8Q]&JQT0/9P5 +M[-ANXQL(S]W8=]I>#9X31MR$+DS$"6^[NONL`>VS=!OX)#$K%5MB1G5*:,X' +M&&YHU8(^08/@J*^NZ!U5CDW#````'```0`6`IDT' +MSGJ):.8]!VQ_CXQ_O]2$H4P3MT:AHP8`F`$``)@!```"````10`!E'T3``!` +M$0``P*@!`<"H`0(!]`'T`8`'96H%GY(/`HI,```````````A("((```````` +M`7@B``!X````=`$!``P,```,`0``#(`.`(`#```,`0``#(`.`0`#```,`0`` +M#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```(`@``!`,```@#```" +M`P``"`,```$#```(`P``!0,```@$```"````"`0```XH``"(``(``/MU6[@) +M_A0(6V./I*2Q1R;M*8GG'AC:)8+(!V?0,M0L-_HB1\"]#^IL]:=*P)PU<,%8 +M_$]1"-[&3;L;SV,?1JL=$#V<%>S8;N,;",_=V'?:7@V>$T;````'0!`0`,#```#`$```R`#@"` +M`P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,#```(`@```@,```@" +M```!`P``"`(```0#```(`P```@,```@#```!`P``"`,```4#```(!````@`` +M``@$```.*```B``"``#[=5NX"?X4"%MCCZ2DL4QDV[&\]C'T:K'1`]G!7LV&[C&PC/ +MW=AWVEX-GA-&W(0N3,0);[NZ^ZP![;-T&_@D,2L56V)&=4IHS@<8;FC5Q\RU +M8`>"IT^T!BD``"28/MU!B,DS_V+-7,/99W>M&993@*3:A_T^PSBL:"MDF2D` +M`!P``$`$K6`1R-=Y@CY!@^"HKZ[H'56.3<,````<``!`!8"F30?.>HEHYCT' +M;'^/C'^_U(2A31.W1H+R"@"8`0``F`$```(```!%``&4?E(``$`1``#`J`$! +MP*@!`@'T`?0!@`=E`)GS&-6\9V<``````````"$@(@@````````!>"(``'@` +M``!T`0$`#/\```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``99MX@#N_^O[+]^.Q +M%.2$C>/^[0V4;:LR$/>Y4D:__)>WI[HP=<4Y:?I\?WH08B$A4D*22?5!6P-F"^\+Q3:.@M(`+]T[7U@X8;-BWYO5/D)/VFT1H +M2_H\;M'&?@4=F_U*P1%<=X,I1+-/F@Z4#14I```D+9**L@B'+V]O$+FP@UM. +M$DY<;HAB1_*MN>^MAH-UBVTI```<``!`!,DX9Z*SG>("U248U\/-HE%-\G.4 +M````'```0`5X.W8UF'BK24J^1SF;;$/L@,W:/4T3MT:)'0X`F`$``)@!```" +M````10`!E'Y3``!`$0``P*@!`<"H`0(!]`'T`8`'90"9\QC5O&=G```````` +M```A("((`````````7@B``!X````=`$!``S_```,`0``#(`.`(`#```,`0`` +M#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```"`P``"`(```$#```( +M`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$```"````"`0```XH +M``"(``(``&6;>(`[O_K^R_?CL13DA(WC_NT-E&VK,A#WN5)&O_R7MZ>Z,'7% +M.6GZ?']W-(JT:6/=E90@V+A;`I.@VWJ$&(A(5)"DDGU05L#9@OO"\4VCH+2` +M"_=.U]8.&&S8M^;U3Y"3]IM$:$OZ/&[1QGX%'9O]2L$17'>#*42S3YH.E`T5 +M*0``)"V2BK((AR]O;Q"YL(-;3A).7&Z(8D?RK;GOK8:#=8MM*0``'```0`3) +M.&>BLYWB`M4E&-?#S:)13?)SE````!P``$`%>#MV-9AXJTE*OD````'0!`0`, +M_P``#`$```R`#@"``P``#`$```R`#@$``P``#`$```R`#@#``P``"`$```,# +M```(`@```@,```@"```!`P``"`(```0#```(`P```@,```@#```!`P``"`,` +M``4#```(!````@````@$```.*```B``"``!EFWB`.[_Z_LOWX[$4Y(2-X_[M +M#91MJS(0][E21K_\E[>GNC!UQ3EI^GQ_=S2*M&ECW964(-BX6P*3H-MZA!B( +M2%20I))]4%;`V8+[PO%-HZ"T@`OW3M?6#AALV+?F]4^0D_:;1&A+^CQNT<9^ +M!1V;_4K!$5QW@RE$LT^:#I0-%2D``"0MDHJR"(*M)2KY'.9ML0^R`S=H]3Q.W1@@H`P"8`0``F`$```(```!%``&4 +M?J<``$`1``#`J`$!P*@!`@'T`?0!@`=E*B!>X3O@UUP``````````"$@(@@` +M```````!>"(``'@```!T`0$`#(````P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +M@IZLP^&WHOKP*4.<7#)048_!N[[UR&05784SV8RHWA6-P9'4!`&2F2%Y679< +MQA5#+T)EMBO;FVAE`I!;1Q4$0T.R:2']*L'2=2'XQ7@S/K]4Q$0>S?NFB7WN +MXHXJ1NII^7<#3<;:UBN4M>MO;%AE/RA%S\@GP-WU38TV^LI?=V$I```DKO;V +M_WUU$V4G(1KF$-37[LY*#*@19GY.<-!`:!%3H04I```<``!`!)'P#T#R%_+Q +M)POEL^OI*)H(U(4P````'```0`6$G=4C/4[)M>UNL0_6AV2\6JBOM4\3MT9C +M508`F`$``)@!```"````10`!E'ZM``!`$0``P*@!`<"H`0(!]`'T`8`'92H@ +M7N$[X-=<```````````A("((`````````7@B``!X````=`$!``R````,`0`` +M#(`.`(`#```,`0``#(`.`0`#```,`0``#(`.`,`#```(`0```P,```@"```" +M`P``"`(```$#```(`@``!`,```@#```"`P``"`,```$#```(`P``!0,```@$ +M```"````"`0```XH``"(``(``(*>K,/AMZ+Z\"E#G%PR4%&/P;N^]5EV7,850R]"9;8KVYMH90*06T<5!$-#LFDA_2K! +MTG4A^,5X,SZ_5,1$'LW[IHE][N*.*D;J:?EW`TW&VM8KE+7K;VQ893\H1<_( +M)\#=]4V--OK*7W=A*0``)*[V]O]]=1-E)R$:YA#4U^[.2@RH$69^3G#00&@1 +M4Z$%*0``'```0`21\`]`\A?R\2<+Y;/KZ2B:"-2%,````!P``$`%A)W5(SU. +MR;7M;K$/UH=DO%JHK[5/$[=&#Y<,`)@!``"8`0```@```$4``91^M0``0!$` +M`,"H`0'`J`$"`?0!]`&`!V4J(%[A.^#77```````````(2`B"`````````%X +M(@``>````'0!`0`,@```#`$```R`#@"``P``#`$```R`#@$``P``#`$```R` +M#@#``P``"`$```,#```(`@```@,```@"```!`P``"`(```0#```(`P```@,` +M``@#```!`P``"`,```4#```(!````@````@$```.*```B``"``""GJS#X;>B +M^O`I0YQ<,E!1C\&[OO7(9!5=A3/9C*C>%8W!D=0$`9*9(7E9=ES&%4,O0F6V +M*]N;:&4"D%M'%01#0[)I(?TJP=)U(?C%>#,^OU3$1![-^Z:)?>[BCBI&ZFGY +M=P--QMK6*Y2UZV]L6&4_*$7/R"?`W?5-C3;ZRE]W82D``"2N]O;_?74392"(``'@```!T`0$`#`,!``P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``PBPTK(W7@X9+RS:0LN`/Q`#;T:)G:.P\IN6R0%,_?KJ$?MB=]BN?*4X"VR7N@@_SG/[),XK@:$+ATJ7#N3B: +M'*I9>(@I```D`-0?%\%CL"+E`A;2<\4E>;)DIAU`3MT;,6`L`N`$``+@!```"```` +M10`!M(&7``!`$0``P*@!`<"H`0(!]`'T`:`'A76+D`]\8F3\```````````I +M("((`````````9@A```@``!`!@````G9]V,J9FVC8+`#>;2<\4E>;)DIAR(` +M`'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X` +MP`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```( +M`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``PBPTK(W7@X9+ +MRS:0LN`/Q`#;T:)G:.P\IN6R0%,_?KJ$?MB=]BN?*4X"VR7N@@_SG/[),XK@:$+ATJ7#N3B:'*I9>(@I```D`-0?%\%CL"+E`AE0L`4`$``%`! +M```"````10`!3(&>``!`$0``P*@!`<"H`0(!]`'T`3@''76+D`]\8F3\M>DU +M++*1HP(A("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```( +M`@```@,```@#```"````"`0```(H``"(``(``'Z=5$+)RNG,Y_YK,"5+0^9\ +MAR>,"7#.:IFV.@9JD_\H;90Q;_0Q.R$,F:00+_KZ&5^1WW%1<@P)%"KNX=D) +MBFM`\8'BTQA19W30@KE.R#,L%<\-Q$N!CWH_"@D,L]>>%9#5'E25UOTHV?"M +MJ@HRNL,\J-=C$@_3/0),WVY%.D!!,35& +M_CEY7XEL*ZL?<6=O12H3L:'Z*UE2A4(ELN&$^"1C7VGQVD!8DU++*1HP(N(",@`````0```)PD``"`DZ",E>IA-Q$)4/^#*;$\4U7B +M2=])\]Y5XA&OM5TA`S4/8#I5\J1---*!Q]2PT:D=TQ8#MKC8H*)@"]RWHC&: +M>L[>:/E:_9>[?:6F632IM;K^98P0ZYP+JECV8$L+#D^O$!N[PA9XFD&P@244 +MVFDU++*1HP(N("0(`````@`` +M`/PA``#@T5TF@;5?G@A<;84Q'Y_!N&X:7WI2K4*(BO^]5%=S#IK*MYU`Q]%F +MUVP52_8O[9<:5JV;<)#>V-_S%.B3CR1`PC^HW#Y)9C>@1$;+L_^HY'X8-(GT.&M%D6T +M-*F`O1D#ZOP,(4VSFX$"_$/^U=J9+^3K'>_C,IIO85SR4.]$]5`AQKZ4R+U* +M25`3MT;!1PP`_````/P````"````10``^(&F``!`$0``P*@!`<"H`0(!]`'T +M`.0&R76+D`]\8F3\M>DU++*1HP(N("0(`````P```-PA``#`HU%9>0DS&_KE +M68'F(21-1Q]T0@_)0J5VW&M&V]91RC9;1E8:]ZOE/MN>9LGI+4XG%H]*+5R/ +M@K+KM02,A0I3>PQF.NR6GSH^L>84;QO*/[:25I,%8=L12HTQQB-G`A%_2[7= +M2C=OQ!38)Z`*]R@*,UQJ-2"+GW.!DJ.Y4!.W1N:)#`!L```` +M;`````(```!%``!H@:H``$`1``#`J`$!P*@!`@'T`?0`5`8Y=8N0#WQB9/RU +MZ34LLI&C`BX@)"`````#````3"D``#!-=:_NB:.TZ>I8?3WY;=D\TP@N5L5? +MHP[.GN6NY2FGGFGK-:_;AX9'B@H25%`3MT8OMPP`/`$``#P!```"````10`! +M.(&K``!`$0``P*@!`<"H`0(!]`'T`20'"76+D`]\8F3\M>DU++*1HP(N("0( +M````!````1PA``$`CVV[9`FD1E3#'YJ5WO)IG9<$$1'!.-HNO0UAHPP;+FW' +M2$@O3EZH#;84T,<2S7NZ^:3)^>LQX37]TS8& +MTHXOFV[]\DR05@JEROE7,4(&78RRJR3FV(CK:%Y)["("W;7./E[/U<@>.JU6 +MX'(_YI]=R]I0\-_D\&;;-"6\I(G`BO(O7O!#/]3CW9E +MM`.$!)PR-'.DZ@F0,Q"GSYPYM):5LP:G3RO=.9$X1,ZT1.!M.SL!4!.W1F[9 +M#`#L````[`````(```!%``#H@:X``$`1``#`J`$!P*@!`@'T`?0`U`:Y=8N0 +M#WQB9/RUZ34LLI&C`BX@)"`````$````S"$``+"0;1?/O:N?>9,RKB6-(SG- +M`Q06)+YQ<-:^ZELNMMVIFMP(I+$A'+B1DJ&"_RR75XC(N4]46/!F=\`D^^;K +M>:G,Q@KBIKA$Y&ND!0$JU8;8G7`1@:=`?JY2<=$SZ6NIG=W$$8_BU;__9\;/ +MJM%;1$9``L.Q@)C:108G26_#A!V-%1G%O6X\$,T@1K?FX!J\8$7X5D.,6OW& +MQ_7+W/ZU&X3E'U@G._J`*][:![M*4!.W1N3C#``<`0``'`$```(```!%``$8 +M@;```$`1``#`J`$!P*@!`@'T`?0!!`?I=8N0#WQB9/RUZ34LLI&C`BX@)`@` +M```%````_"$``.!0^ZQS=35C;N0=H[^E5T;.FUVR,(,I:N"@#:5;'+7UR";, +M_'V"$_^:6$&W,R31S5;_*._*,;+M:V?HM4,=9AL7\<5+W! +M:O/4>?E,9Y3U?64%B&$2,4D54UINKK@5O]Q!/UGSO&,J2;20DP$+J,S&4N+( +MS,A7':!EM#T'V3?"4<`.(NLCJSAJD;'8?96^KCKVCA1`L0_US7[H7MT#D$7Z +M)NX[IOA6\_AL;+8;J3T!Y/@JI/&J0'^+V:)-W8K2BM7V%EEALG#(G"S +MBP>:HM5B4!.W1GL)#0#L````[`````(```!%``#H@;0``$`1``#`J`$!P*@! +M`@'T`?0`U`:Y=8N0#WQB9/RUZ34LLI&C`BX@)"`````%````S"$``+!((Q:I +M_B42`%O)=!#`OE"+(YYK4\Q#O.J]D,D_,0NZ+B,Q8 +M-Z+I?N&E.%0+D\/?Q=E_E.T3]E;&68>">$$4?*N2^`C04!.W1L`V#0`\`0`` +M/`$```(```!%``$X@;4``$`1``#`J`$!P*@!`@'T`?0!)`<)=8N0#WQB9/RU +MZ34LLI&C`BX@)`@````&```!'"$``0#'4SOCS:3.O[%F[F2\W>-RB5./F_I; +M34W8:<8>@P)#,%*6L +M1II4T8!1205E?LA/]BHY6_CB^%.??@8M+!HXYNV%-%%J\#WA5U_/=5SZ,Z?* +MKA4;SO5.^1QHPVO2IG./_-SHGP6HHH:S"2NZF+O<;WNGYE^8VFBG!IL8+@*< +MX*'$04,6^W<3@*9%^AU`#T'7NW!%G-P/=9*/.M'&C([^6^M`C`J[U0$[=&'&4-`!P!```< +M`0```@```$4``1B!O0``0!$``,"H`0'`J`$"`?0!]`$$!^EUBY`/?&)D_+7I +M-2RRD:,"+B`D"`````<```#\(0``X+:\E_"&8)JTY7A,MM9@F3OU">%G%&.474`S0/(!A+ZE[%1FL./] +MD$.][8"-\4QLT]UM):4(-L/8Q@UXX](B!86$BTVH&S,_OYEKC%.$40`7T09J +MUU^\::EE3B+@G#)9"W4#1UXD\*Z%'>U'5"*R&"'VL:UJ1M5!>0M')-,BD/^H +MW=IO'IGSHP4QIEGK77R-F8Y0$[=&KH0-`.P```#L`````@```$4``.B!O@`` +M0!$``,"H`0'`J`$"`?0!]`#4!KEUBY`/?&)D_+7I-2RRD:,"+B`D(`````<` +M``#,(0``L"F4,KR:B<`L24Y)@;AHB5"0&?3/=K1X_Y!/'VT3SC^P><9#Q75XE2QR(CMMM&TS]GZ9QZF@\F4AA(TJCMT#09:&7<6DH9XZ;#*R!R9QS:GKZ=YC1.SD,*:(??;^H_1=T3#?Y0 +M$[=&U-<-`(P!``",`0```@```$4``8B!P@``0!$``,"H`0'`J`$"`?0!]`%T +M!UEUBY`/?&)D_+7I-2RRD:,"+B`D"`````@```%L(0`!4`2&,%2K3"]3B>(0 +MJSE3UK`;`@FTQFA-1`U$?WGW!)%^97[]5Q-B[>9W#!=RK:#)3BCY=W/2^TMZNS66&M0\P>'=9$E +M$+L)TWUNB;6:!%MJ@_:,?5-I534@A[)JC?9B7$DE+<)\H.(=TUH+QJ=YIE45 +MA)K*PLCY%;J3!TR<]%!ROMB&F50P1_"VR=0I0K,PBQ^KZ&"3SIB`I>RZ\+MM +MUK=G3YRP>\#R*3#]+/\2L"%%&?WST0&WFBFM9>/^P\*Y4-5J;6`I@FS;1[_I +M;\#D3I!]7BS3/VIB"##SQ/(I`['DQK='V0)_UHZQIM+X?B;A&"U36X5-DX"U +M:-\G)5H3B^5NQ_`O_]XY>64D85?DCV<]HF(9L'TSJ9SD`OT`C2IM#_DGA+HS +MIG]W7+''4!.W1M0M#@!<`0``7`$```(```!%``%8@<8``$`1``#`J`$!P*@! +M`@'T`?0!1`L>'XW%.6$FMQW1/5B+CK +MC9_N1!CBKHJ%Q,<@O*$VT*)U*@G>,R`LLWWFG[EUA3]MR27;:&J">6BP6;?@ +M,\70C"L[^D%U\+8H5_>D)`%41$?*/5(0+IZ/!#U)<`W<9:KSL@K'FCK>?M+< +MHETBPUT8)YA/?6'_)0="'"\R#._X_(''SS\!^83.)==K+N<_!(N%X8Q3RI.C +M5@RMAB?D//N>(S'AR'3P9HJ96C17.QT*^T/;V>? +M>UK`D0^`9.R15U`3MT;@:PX`?````'P````"````10``>('-``!`$0``P*@! +M`<"H`0(!]`'T`&0&262A\R+$4^'L`\7[7AG:+AXN("4(`````````%PJ``!` +M0I%8T+0KR2>I!$[:VM-P\@9USZWV2LE"N'')RXR95R(_#TCVY7WF-`! +MR_^9\)<`$'MU9\&%;8C14!.W1AI]#@!L````;`````(```!%``!H@P#Q?M>&=HN'BX@)2`````````` +M3````#!MTU('?C$3I6P0PPIZT?,A:%:%!UHC[5JG3CSWH#-(T^+3$G;E8TWQ +MIL$*25`3MT9JE`X`;````&P````"````10``:('/``!`$0``P*@!`<"H`0(! +M]`'T`%0&.62A\R+$4^'L`\7[7AG:+AXN("4(`````0```$PJ```P@,X0"8PN +MR&>C2*!H$[9!2IH8:*N*OUA9;`LPB9$*'2)P[#XTO@YY0$[=&#:@. +M`&P```!L`````@```$4``&B!T```0!$``,"H`0'`J`$"`?0!]`!4!CEDH?,B +MQ%/A[`/%^UX9VBX>+B`E(`````$```!,````,)B\*\G%)0*_"!&/#ABGXB58 +M+F:4"?<0:U_Q641.W1KSL``"8`0``F`$```(` +M``!%``&4@>D``$`1``#`J`$!P*@!`@'T`?0!@`=E(ZXD5#YLX,X````````` +M`"$@(@@````````!>"(``'@```!T`0$`#`,!``P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``-$CL'F;O.9[0RD'?%%OJ]FAA+JSI24PW@+T.Z*&M+3@X&A[S)R`; +M0X_>QQ[]TY><"">;LQI9B&D(2`.U?VB:7_?NA"O7Y:LW*'A4,WB#DG&Y4N(, +MS0B0+O279*TCN@UA^;0*CF7R16((Z59THV&"8%0'F!97`$UAT!*]"F)>R(6W",CS;^BU-9$D4QH[QL%Q+TI```<``!`!(M" +MW[>&ZDB-B.JO/EC"'P-US6*X````'```0`54HURB_7(UL%)1"L&XHQY`-H0R +ME5$3MT;B!`$`7````%P````"````10``6('J``!`$0``P*@!`<"H`0(!]`'T +M`$0&*2.N)%0^;.#.```````````I("(@`````````#P````@``!`!@````EC +MGR3=);`X-8^9"U[RQG@0(X68!%$3MT:S(`$`N`$``+@!```"````10`!M('K +M``!`$0``P*@!`<"H`0(!]`'T`:`'A2.N)%0^;.#.```````````I("((```` +M`````9@A```@``!`!@````ECGR3=);`X-8^9"U[RQG@0(X68!"(``'@```!T +M`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@! +M```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,` +M``@#```%`P``"`0```(````(!```#B@``(@``@``-$CL'F;O.9[0RD'?%%OJ +M]FAA+JSI24PW@+T.Z*&M+3@X&A[S)R`;0X_>QQ[]TY><"">;LQI9B&D(2`.U +M?VB:7_?NA"O7Y:LW*'A4,WB#DG&Y4N(,S0B0+O279*TCN@UA^;0*CF7R16(( +MZ59THV&"8%0'F!97`$UAT!*]"F)>R(6W",C +MS;^BU-9$D4QH[QL%Q+TI```<``!`!(M"W[>&ZDB-B.JO/EC"'P-US6*X```` +M'```0`54HURB_7(UL%)1"L&XHQY`-H0RE5$3MT;]:`$`4`$``%`!```"```` +M10`!3('R``!`$0``P*@!`<"H`0(!]`'T`3@''2.N)%0^;.#.NM"5'$;]Z+\A +M("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,` +M``@#```"````"`0```(H``"(``(``"L7C--P+>:V/RZC0R]A@"_O]XS096D? +M$X.>ITDJ&\QUP^:I!#B@HTTYQ#"14Z/D-^Y-_SW1$^A;D0UE5\0:D]R"V5;D +M;-$61+^?SY!4#[@5@`>A5#F(>@5W!XRZJ@0$%@91A4"I5*^#;7LI@W*J?]*0``)!3_#M"P@=]6I#I(,55GSQE2/Y;PI]&Q.3>? +MUKZ,VUZ>*0``'```0`2-0C%LH`Y$E*>(!YYU#0*J1CIF/P```!P``$`%<>%+ +MVUFECW4!.R6(^3+$T,&(E"U1$[=&,*D!``P!```,`0```@```$4``0B!\P`` +M0!$``,"H`0'`J`$"`?0!]`#T!]DCKB14/FS@SKK0E1Q&_>B_+B`C"`````$` +M``#L(P``T-]R^'"(S/TST`8&G")U;S#Z6$_"9]Q'W%@,%QSZV;?,,LY5`?\^ +M/.@1HX]A%\/62XJ%/XS->8^\_S^<^Q7$IB9[/JGU;3L'*3.Z2G!PP4/Q-"56 +M/X/[G69'(KC*"0U!7U:@*[%>@^\7XKJNDPTF`21@-4AT2ELW-M2-&*W62:%= +M\VG_\<`'TAP]?/9`U!"<\-.W%G8>@>D_5'8DVZ=[[;+;,2]\[E;3P0E($"(M/F[[%^HQ5$3MT8BW0$`O````+P` +M```"````10``N('W``!`$0``P*@!`<"H`0(!]`'T`*0&B2.N)%0^;.#.NM"5 +M'$;]Z+\N(",@`````0```)PD``"`7T1J70?'&'FTR\6TLG4VH1B!\&@[O;A# +M?DKJ&F0R]+P-H0FK'*TL_96KK8)BXI'H?/>-E.%4FJV0:W/4C-^:`02'CAE, +M>STF+5;FE'8A(N(V*L,AT>4C.["(QP9VD=_V>/J-?1@WMJV.(JFNM6L#-H=EJ3 +M#4RL1#([G^U.LT/-]%Q_6NG0Y2=!?BZ;!>@KN$CO&3_NBU^7FM@O.JE_YS$* +MSB(\P^@U!T/DQYJ>VR +M21$N?EAQ,IM86<(B,;^7`?'F=N*P1T\/9E[2"3J%VX_+:-^$`QQE%??,3#U# +M937"<_.]+-4L3V6F?,YT\IE#OH849L3<)>OC&RX5K.YTFUF*.>'+>5$3MT80 +M)P(`_````/P````"````10``^('Y``!`$0``P*@!`<"H`0(!]`'T`.0&R2.N +M)%0^;.#.NM"5'$;]Z+\N("0(`````P```-PA``#`[#W^K[]MTRH]`372[>PP +M9ES&'+]MVYF;`*+(Y<1P+MS_*7\S'Z_WE4+2/0Z7)2^[C3JA65< +M?:T%+7,;3Q]#>BDMUR4U0P/B_,?L"\EPG_LEQQ]^)Q2]#.<;+2KL]4X0SO$> +M)$]*<`/#)8L$PFHJGTY*SV9$\WR^E2_#F6A-\GD_':MTUQ9V?'A1$[=&K#P" +M`&P```!L`````@```$4``&B!^@``0!$``,"H`0'`J`$"`?0!]`!4!CDCKB14 +M/FS@SKK0E1Q&_>B_+B`D(`````(```!,*0``,`N/&D=@O4/P8B<1/>6))/N! +M)GN6S0&!3`8A9&/T$YV,4A*Y_C.FS7XD%;>.41.W1BAA`@!L````;`````(` +M``!%``!H@?X``$`1``#`J`$!P*@!`@'T`?0`5`8Y(ZXD5#YLX,ZZT)4<1OWH +MORX@)"`````#````3"D``##/U[_URTHTHG_MX$I'$M<@,T1)OP>.*SY7`\J$ +M4`V`R3SFXIG=US#)>_MO.U$3MT8#FP(`/`$``#P!```"````10`!.('_``!` +M$0``P*@!`<"H`0(!]`'T`20'"2.N)%0^;.#.NM"5'$;]Z+\N("0(````!``` +M`1PA``$`M`#=>L3#BV+]F_>FP84U$_W0&1KK.MPYGBUU!TR;6#,1K'W88WN\D(%"PSNP`H#PK+C(C>2C832K`OI?L9J\7QMM`F +M1CA@T<^(R:2D1DNLY>[Y0P,A-O:=.(#H#%X4"W%.<]1I;O-")RJ_PWRCT4P9 +M`J'9BX2B\95MQ,<:Q44K,U/)I0;6U)"X0$R%'3![17$.E?5V?G!\@@6?]./U/;>[4S+]%=?+!`73?`6.$XG\CV8CUR==* +MOFRH`:BS3_^%!FT>BM/5F?0G48%5BCEUYDLA["9[>@-041.W1MVG`@`<`0`` +M'`$```(```!%``$8@@```$`1``#`J`$!P*@!`@'T`?0!!`?I(ZXD5#YLX,ZZ +MT)4<1OWHORX@)`@````%````_"$``.`'LQ!-*T"=1)T$XWGC'A?UT\E19N[4 +M#CW5-5&+74O+QN`2^ZC^^2E'+B#H<]&E5/TP=(YU3?#!"-C#/Q +MS\$9`B]P;>_!=*1T@I;H!'!#>8P4X&/WNPQG&5-\RA`]^0F)9I1Q`3B0O<`; +M85PS/P=X6TN8L1,\EO?&4>7AT93-^E.L6LFK;+>>Y>'BYJUKVS&G?C;K[T.M +MHLP_.$&6'>79+81QL,*>>FAB]%%X3@V'LAL,@B"H!6%::,4':`L9M$P^[OOT +M'E*F!BT=>BE84L-8H*FOJ`<.41.W1GG(`@#L````[`````(```!%``#H@@0` +M`$`1``#`J`$!P*@!`@'T`?0`U`:Y(ZXD5#YLX,ZZT)4<1OWHORX@)"`````$ +M````S"$``+`\1`^7$*&]2&".9?@WZ26QTH0DV]' +M41.W1I#R`@#L````[`````(```!%``#H@@4``$`1``#`J`$!P*@!`@'T`?0` +MU`:Y(ZXD5#YLX,ZZT)4<1OWHORX@)"`````%````S"$``+#"O0E\P_`7"[CZ +M20@PQ>TX)*).NGW$/^+Z#VBX=0>E"YMS44?4B*P(XF2GO-D#K-S^WG89`*$=0($+./YI1!&?O> +M_H:*)5\%$5A<(06_FIV"ZO_SK>S@]]AK>1&PZV%@! +M4JK#.XB!;2784SEZAC^2>NL(K[2;5626Y(6&41.W1CDQ`P`\`0``/`$```(` +M``!%``$X@@8``$`1``#`J`$!P*@!`@'T`?0!)`<)(ZXD5#YLX,ZZT)4<1OWH +MORX@)`@````&```!'"$``0!IW[Y52O6ZY+8XCG*PAIGF?:=_>B"%0Z2WJL]MXV/L)@=B:AA%I=9\]Z>>;/5N$'ABZ<50)4[)#) +M30\A25\U2<7.`UMW\L.HC#I&4>IC&BW8)9ITE +M]M7K\^-`!CRPO]L.I=`]PWA)T`X/=;*3ILR,$`<^7(0`BH@)U8HU0E.41[?] +MGL+,!,ECV,;+UI;K:B&'0D<;\-9ZBKTA.):,B)?N:^G[53U#"#6,D;%%%XY1 +M$[=&=S\#`!P!```<`0```@```$4``1B""@``0!$``,"H`0'`J`$"`?0!]`$$ +M!^DCKB14/FS@SKK0E1Q&_>B_+B`D"`````<```#\(0``X*KR#GH5PZ@9,O]* +MI!:-SMG9)&D3BF>IL;LQU0:P5Q9J?KL$B&U;HJ!N"4HH5$+F/,"T.4T]$QOWI)3@UC3`KJ5V_F/97I& +M+)#EI1$[=&TUP#`.P```#L```` +M`@```$4``.B""P``0!$``,"H`0'`J`$"`?0!]`#4!KDCKB14/FS@SKK0E1Q& +M_>B_+B`D(`````8```#,(0``L(TI>W`L*WLX*,$X3GNR!L8F@"9XT"I5+BRB +M9-"_:#'M4*OSNT-:N:T%00*8HX#RU9<'AXLD;]9:>P@J]X/U2PC/!.L)A@,U +MM$HN!T78\:UL!O$C2,"U4(W2A7?R"'G=+_3^&!?N8XLU^`5S@_`$F+XH-[/D +M7=C,>FVQ%D1=\GIJ@WTVKF#W`_W>N3E5[.)[3ZR/BZ`,($X'6(7J_);UAAU& +M_0$P1J`ER^>]KSQ1$[=&Q(8#`.P```#L`````@```$4``.B"#```0!$``,"H +M`0'`J`$"`?0!]`#4!KDCKB14/FS@SKK0E1Q&_>B_+B`D(`````<```#,(0`` +ML%X%/[=)&J,U55VI3JX+`Q/;E,R[.^@"D&0H&"$!>8\@_Q:;'=X<:?=@:8)P +M=1]C2(!Q-ZM'314)RI"):&S8@1PPEQ!V4?07A^@;E"!W8(B19W'M=GB_+B`D"`````@```%L(0`!4"+CG^F=926FD8IED]U&K#E= +MT>?%?,(%QO2ZI;0C,2OY%(_C1Q*+@D_:.DB[149>AC>MC(-_`-]^$$OE.&W4 +MHOE8$;V4`$*=K[`89^.&<-1=J5QOTAD_G,?HC)\Q!AGONX1_X&P:7VK?;7F&WY_;J9F?PI2REKTLHMW"!U%RMVX6V63"IIE@KKF7.)3@J2OT[ +M:^MHY]3Q=N_EX7?DK_,TW_S&5D>F3OG`;?X,>*=IRS],:390;7%S:8T8)KH; +MIQ26DB9Z[&R^@:MK^T*QCAN4]V"M4;O*(B>H7T:N7HF&#CVV7XT3PE%`\;QJ5E +MVP1&1+F+UBY"X\=@QO8U0TQAMT3:>!R^%)U)_3S<8P_V'Y"[AXB$YNLI((SF36'W-LW4+ +MO]K:5OL-JN6W<&7T@CVRK:L+D>8"?]VWPE*N+-OLPWHS[]4,CJ9&>Y#`E%2" +MU@16IN0TD\'#BNRBXPA^"`8US4:G=QJL&5NG5I%KTEQ,%DW*:11 +MYI>_XU$3MT;>CP0`?````'P````"````10``>((4``!`$0``P*@!`<"H`0(! +M]`'T`&0&2=I,%X,J::>BRRRZM8<,Y=4N("4(`````````%PJ``!`+]/>#_H/ +MXG6WN<$(^997W=3N@B=-=A'IDB'K\/-+*'TV%,+DZ1`WYFP6Z<7=L9;]*#TJ +M"DH)$S_*U7JZ41.W1IFH!`!L````;`````(```!%``!H@A4``$`1``#`J`$! +MP*@!`@'T`?0`5`8YVDP7@RIIIZ++++JUAPSEU2X@)2``````````3````#!8 +MB-H<)HR6#JX9K2A%[NJ6*^U,T8WI%$:[&&`M8BW@B^M/148YBE$3 +MMT:JR00`;````&P````"````10``:((6``!`$0``P*@!`<"H`0(!]`'T`%0& +M.=I,%X,J::>BRRRZM8<,Y=4N("4(`````0```$PJ```P6`'@BSS\H/F#*FFGHLLL +MNK6'#.75+B`E(`````$```!,````,%?]!X-*^9B#\+<@`/$(,7,-2C\EIPJ` +M5+*(U:,"(-E]_*O;MJPAU#B5P"0.41.W1BM9!@"8`0``F`$```(```!%``&4 +M@J8``$`1``#`J`$!P*@!`@'T`?0!@`=EG+(0TB=A%W```````````"$@(@@` +M```````!>"(``'@```!T`0$`#`,"``P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MKU]P!8^O_MH6EVY8*%XCT/O]+O:N-PF#)-/%U)9)A?:68?948W25131PO&2@ +M0>GV\Y97"MQ.#2%S=F.&'<8"`=EAKRAYZ@KE%M`RH+$KA\WR7!HD+`CXK>ISN]`5%S0)G$AA'YP!Z_M_>8I```DQ4]5 +M849#-Z0>?1WPNHDB1MBVL]G(=)DF4<5<)7YL3JHI```<``!`!*\T4/HCN0Y$ +MS/6Z&"-&8`>O<)AK_(I;E$3MT;> +M9P8`7````%P````"````10``6(*G``!`$0``P*@!`<"H`0(!]`'T`$0&*9RR +M$-(G81=P```````````I("(@`````````#P````@``!`!@````H.N+TM!1'0 +MGV\Y97"MQ.#2%S=F.&'<8"`=EA +MKRAYZ@KE%M`RH+$KA\WR7!HD+`CXK>I +MSN]`5%S0)G$AA'YP!Z_M_>8I```DQ4]5849#-Z0>?1WPNHDB1MBVL]G(=)DF +M4<5<)7YL3JHI```<``!`!*\T4/HCN0Y$S/6Z&"-&8`>O<)AK_(I;E$3MT8*G08`4`$``%`!```"````10`!3(*I +M``!`$0``P*@!`<"H`0(!]`'T`3@''9RR$-(G81=P*XZRS4.9F`@A("(@```` +M`````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```" +M````"`0```(H``"(``(``!KMY)KM;LE/W-+'/X[XDJQM-]XU["3%&L-5Q&A2 +M5PB-ZT/U/^PJ-76K,.V,N*U6^^"4&]&6W$J_SRT_9W>:Q+^M.C^_!+J29!H/ +M2[&)2*P]P8LP$ZZY]X2P;=Z^[7"S7P*0``)*C#^/.\H?OS435-9$T.ZC*^V4?KHNHH9PI+3CN#9U1\ +M*0``'```0`0_XJ1;X!U3$_U85_1I)8\!RE#)$````!P``$`%#P[Y`IPE9Q]2 +M5"L'9UP]Y2?L(Y51$[=&G]`&``P!```,`0```@```$4``0B"J@``0!$``,"H +M`0'`J`$"`?0!]`#T!]FGG[!`(R)HC[7LI +MW50HQ_RQG"`J*B:Y@S'*`U"KT/@G&:J8_GUM6X'=B&8ORX@N;_>H;)HIM$?A +MVO+_8NK$6-#3)[Z92DFX.S^]ZCF3]$B<),HPV%*V,T*6+MV705GG"0@>4',8 +M=POX81`A:&DGPF4/CRK0C?.@C&0FAKEEK$<3ZL7?<=;K\;J9=O-B/KVH?OB! +M*)#S,-ZQ5!72E&H."*S3NA4G=BL`QR=W+I2YU&GI_>-_`_KG[0D!6YR^>1(Y:86#L#*N. +MR&[_]5$3MT9Q"`<`'`$``!P!```"````10`!&(*L``!`$0``P*@!`<"H`0(! +M]`'T`00'Z9RR$-(G81=P*XZRS4.9F`@N("0(`````@```/PA``#@'-Z`TBP< +MHE\*G_$OL),E%_/DOE@,Q5KNL)64:\20),\+;[3ZG>I&*5F>-E]573;L0WT\ +M](5!T+1G03(H'/?N.4&9VU]V$+-[2X`5.:$/QQ,MQ5P<#_(Z;5O%G.=H9_7P +MDT.[X3#NYBS''1/:,(H0JT?9$M1]G\I*4NUU_GX,\[5$]EW$``5-26R6CC?J +M*[HQ7UB]1MITXI)*^R_2R5(8[`>>$NR!GMF8LUS?NE%7OJC)PGL:_4_ZYE(X +MJ0H]WE?<_5$VT3\8\XA6<%"Z[:N,?JG#>@GP*?H/(1:9G%$3MT:^$P<`_``` +M`/P````"````10``^(*M``!`$0``P*@!`<"H`0(!]`'T`.0&R9RR$-(G81=P +M*XZRS4.9F`@N("0(`````P```-PA``#`R:_JP[(]$JK+9=&8P'U>#J*.O`TD +M\*&2FE+ZXCP[Q;VI""I7)3*_QCC[? +MKRDDI>$85OH)[!P7L"F.V>;8HMY)*)GZ*5`2/MO4GJR8F$,W8\NWV2A2MD+* +MTM"LK/U[U#5L+O66Q5&"T\$2PS/>%QKR\JSA,O<,\>^(6#<`',SYQIX.H1O& +M>H]!VWD])!*FM.D%/>A:#NUXVX':X.C@9I_`)>R`B4[4DPZ3\-GP1A(VAKMY4J\SG.?"ELGC_% +M6/`DED/SF&`E%@I`#ZW>(E)]Y`REU&`^$@-==K2N$NH[L,7CF4+$]SZ$7JC3 +MM`)C1VY)0)&V")#?#3_A<67?;N:D*L4C#B[2#3LWD(*MY`&6B?JL!"BPC(NB +MG%[DE.9IDR:)]M87$T!JP8BI-MSE>&21.<49&01)Z"N,@)@C;`0)8R!XA="= +M7T86V-5Z%"!7>T8>A.(B5Z88*G9"/_Q:9!O!41.W1G==!P`<`0``'`$```(` +M``!%``$8@K,``$`1``#`J`$!P*@!`@'T`?0!!`?IG+(0TB=A%W`KCK+-0YF8 +M""X@)`@````%````_"$``.`E^R*5%HQ)_.``IO%VN9W$0OD.G;!T7)O\:RCU +MQM,J2@BSK!=5IG&92\6.9D_XE'^SX(@)*,FE+#]TGJ[@)'J_(,G-"YMFYRSU>C+;ZH\0:'&5_KQ+ +MVB]*T\MJS1D4M._QFOS!)HB^\P[&UH#&0_\1H-M`6G#Q18TH/_V=Z0GR +MD@N9)MV@;\FJ$8?Z88=J?X_MN1C$NYM-MKSN6DUE#IZJ86"9JR%C41.W1G9S!P#L````[`````(```!%``#H@K0``$`1``#` +MJ`$!P*@!`@'T`?0`U`:YG+(0TB=A%W`KCK+-0YF8""X@)"`````$````S"$` +M`+"3$L!M^8C;M*0V*B%?,1J$/6NA1X%+,7=<3EX9N(U]E':0?!W4$0^GK880 +M[D`C0V:9T:3!7T1C4E41.W1B26 +M!P#L````[`````(```!%``#H@K4``$`1``#`J`$!P*@!`@'T`?0`U`:YG+(0 +MTB=A%W`KCK+-0YF8""X@)"`````%````S"$``+#&.'X?_QIY9MP(Z72C3YD,/`N+,"G)_-VHJB)^FA%L, +M::.@-Z\*@_ARY#SHCWO,&D@J$X5/#/U6?AC?!3?!@/:$UI4UFR#*^R:']%G" +M"#&)$_49#U687E!E(N]R<]PB:X.N41.W1I"S!P`\`0``/`$```(```!%``$X +M@K8``$`1``#`J`$!P*@!`@'T`?0!)`<)G+(0TB=A%W`KCK+-0YF8""X@)`@` +M```&```!'"$``0!0[S";BSDK!LGX+@&8K +MQT2PS2&O"P4O8&UWCN:W:GMDO&6I"7"#9O/@?($+NIV#'UW+U#)MH=8%<+4Z +MX300$T^\N)8)0A<^P$D$N61B+`6\*KLCU4%^C,G%^!.8:@Z2(ZY1$[=&?+\' +M`!P!```<`0```@```$4``1B"MP``0!$``,"H`0'`J`$"`?0!]`$$!^F_X5C/C'56_DT`L(%I2V"4T@&M3N60>25$WUO>O +M?"?0"N\(`#4\I24!8I74$F5V`7^B1%\E;F-'[Q5^4XYTJ*GKAGX3?3YWO7T* +M08F@X@9%"@1VAEYOECFR#J,UOH*NPO"=1&V8+8K/&1YU.LRWK"AEYT$24RZN +M_'G-=<*$3RV>/+V&(4$LUDW+_<0P+N-@O5CF*U%`6C^:2I +M^OOS`_3J">*ET8>LI@UR.LK::@@$J7@&.D/QR[7BZ +M5I(^!E4T2F\Q!!XD`T;.MQ)<,R]S+)X8#\H +MHZE7%\<(?C675>BQ6RX,/9_0D+Z`W!\?_1K?VS0T@._R&N>RP+$4VV/D\]W$ +MK3@%#C-1$[=&1O,'`.P```#L`````@```$4``.B"N0``0!$``,"H`0'`J`$" +M`?0!]`#4!KF[$-HSF)F(V?:6+;;IIDM,2+TEJ:='J/S,C8 +M?C.=FN-OP"([E10(I!!J>F@^>;?.!Q[9=$*PUJK;SUDX+"PL0U8SB/FY[LQ\)RM!!U_ +M\+0E78@+I@.S[FU#W%-N/&G5]"?C!W,=GIWN%%I>LL!1$[=&S!D(`(P!``", +M`0```@```$4``8B"N@``0!$``,"H`0'`J`$"`?0!]`%T!UFR\YJC/K.70%17-LX"M5JMY^ +MD/_EAJ]S0-3\7=G\F.I"0VNGU,_)E<=0S@Y+<'=F+(EEBA$%"(I<6<0J5.W6 +M*W1"2?6^=)"72Q6.SI=]^KM1P5)6\).P6C="#?@4'TD]$3)TABI6VZ#H%9;& +M^>E64D?ZHDK..#7>\XW\8NFW%D/^L,_:Q@=9ZLWZW*M-O^>='N/*L5BTDP_Y +MO#T,+23W&1J`H(L6S7T!*#6!"N3:=^?M=G5PT`RN:UYRK8<,'<89D#%2GMMP +M>"NB4*AYBZ'_`>ZV/`'O&TI[9WE[$2_N86>S62M^,I#WAX>(?- +M%@-,^R%S/#>GI?A?V3^S,9)!R.F\L/E][CQ)W<):JMJOK/)6`LZV-%:^:.%6 +MDYRUPP`6,!%V'/G,61$K493WN#]^XE)^_H.EAHCW-;?$`(EGO0TI41.W1D=. +M"`!<`0``7`$```(```!%``%8@KL``$`1``#`J`$!P*@!`@'T`?0!1`.LD=4!ZD'X?^!F,&.T,3NP@E%XV![2X/=^T>O>Q7 +MV1)60)I"F_0`)PC.^6`$VX_H&&4"6.GLUN:U_N@"Z0??V.Q`%8/WJRFHEH*B9#T))A26XZ`;V[WZ2Y$^;+`- +M!Q$+L$/*_3>/-DN*.$).I?IJ7AR[ESF:!KR,A+9P7N>USWSU)_E!Y13I>-:0 +MRBQQ1O1GP!"4??!AX\03LLD"_G678?]Y7'V\+P(7)RWW*$J*LM'MC(*\``!`$0``P*@!`<"H`0(!]`'T`&0& +M227VP3D4_0@?`CAF-;%Q0_J +M!->_0?1F3%6T0U*!$7O,0Z_P,EN)20X+#1+U5"E2N$'=97DK5$NNDV-A"H4` +MDF-141.W1HR""`!L````;`````(```!%``!H@KT``$`1``#`J`$!P*@!`@'T +M`?0`5`8Y)?;!.13]"!\".&8UL7%!SBX@)2``````````3````#`IHT7>9$DU +M!\@/2.<_4BKE(WP:"(1>%KO,ID(\NB,+4)/BE$'X,)82^Z--3,!K__45_`H0U6R/K51$[=&\9X(`&P```!L`````@`` +M`$4``&B"OP``0!$``,"H`0'`J`$"`?0!]`!4!CDE]L$Y%/T('P(X9C6Q<4'. +M+B`E(`````$```!,````,'34#ZT.'VT4GO4;8V0,541.W1O?M"0"8`0``F`$```(```!%``&4@L,``$`1 +M``#`J`$!P*@!`@'T`?0!@`=ES2"%[][#R\$``````````"$@(@@````````! +M>"(``'@```!T`0$`#`,#``P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``"H\/8;": +MRE/C0W.)1"NPT0I0\&"G;<%$74;>GNG*7P8#-X0E2*KF/+C9G_4*%?4";=04[1DU-*/Z$;>AP\F"%:`I```DLUGHSV_;EA:B +M?/&Q.=&`EWX1GFK=)9J*1+Y)%E(U>BDI```<``!`!':>PJ#7A="O%^[]:$.2 +M3XN>)Z=N````'```0`6[Y:L.N!#:0U&L]I!"'$@BB`RII%$3MT8,_0D`7``` +M`%P````"````10``6(+$``!`$0``P*@!`<"H`0(!]`'T`$0&*_>P\O! +M```````````I("(@`````````#P````@``!`!@````HM?./%FC;MG347UNPY +MA'FA.&T!*U$3MT:C#`H`N`$``+@!```"````10`!M(+%``!`$0``P*@!`<"H +M`0(!]`'T`:`'A_>P\O!```````````I("((`````````9@A```@``!` +M!@````HM?./%FC;MG347UNPYA'FA.&T!*R(``'@```!T`0$`#`,```P!```, +M@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(# +M```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0` +M``(````(!```#B@``(@``@``"H\/8;":RE/C0W.)1"NPT0I0\&"G;<%$74;> +MGNG*7P8#-X0E2*KF/+C9G_4*%?4";=04[1DU +M-*/Z$;>AP\F"%:`I```DLUGHSV_;EA:B?/&Q.=&`EWX1GFK=)9J*1+Y)%E(U +M>BDI```<``!`!':>PJ#7A="O%^[]:$.23XN>)Z=N````'```0`6[Y:L.N!#: +M0U&L]I!"'$@BB`RII%$3MT:&,0H`4`$``%`!```"````10`!3(+&``!`$0`` +MP*@!`<"H`0(!]`'T`3@''_>P\O!4TXMCC(/D0::/O2C_.OJ/C!`52L*10V;4.3HRK)+X1K$8FP?:0T5VHM%22 +M^%'7S1#!]X>WSTDGZ+"X8SPTMMFTL'KBC1R60P^22N1/1UP2I-[`9_5N'S'8 +MMN%P*0``))%)MM$^_AUMQLZJ2(.]K'NGP+]1GC+[[Q_48_IVW(FX.S^Z" +M6S@1O]YC7*WK@<=O%YC"RP'>#QFZ"SQ,#%N*.T=&[LE3$-S1A[%*%1KP:PSD +M8$D.RO\DN0>&+*Z$2P?:RC?25%$3MT;S=PH`O````+P````"````10``N(+( +M``!`$0``P*@!`<"H`0(!]`'T`*0&B_>P\O!4TXMCC(/D0:VB>0!!3F)KH46B-?[%MZ'4#Z^I31$S\WJ +MKNY40"$O1TSA.E"6:SX#1//AF#B7>3GH`=N*9[31`B,%\@_D[IZ'N=SC4^;0,,V,_(@+K>T4N;)L;K."9SO9VKF9$*IE$3 +MMT8YE@H`'`$``!P!```"````10`!&(+)``!`$0``P*@!`<"H`0(!]`'T`00' +MZ_>P\O!4TXMCC(/D0Y:(BJ3%UX'KK$M>14XC*R'><" +MR),%R]I1^BG^%<#:RCZQM\D_08JCQ_Y$"3[`E=UXXCU5H`<):W0Z$]);TJMA +MT`"5;,-[`/POSZ""]Z6;(Q\QI8O4?\7[X^RR&K1MY&3^WJQ7U\^,02*7@]@) +M\G@YG&(+.[8A=8OOUE1](%7:A][-,$H%KR>S[S&_+&\^F.'&$";]%[H45I*B +M$H%/'#G]6JFS;C64@\FKVDQO&&*[89>)2W8HNE$3MT8IH0H`_````/P````" +M````10``^(+*``!`$0``P*@!`<"H`0(!]`'T`.0&R_>P\O!4TXMCC(/ +MD0O+8]\;*RAV&6:*< +MI>4TJD+XSS6D`C]ROE))-S>92)RD^K-#$1S&7FFM_$RKA8SG^Y]L% +MU#;8@NQGW?I5A]F43??041.W1L3'"@!L````;`````(```!%``!H@LP``$`1 +M``#`J`$!P*@!`@'T`?0`5`8YS2"%[][#R\%33BV.,@^1!RX@)"`````#```` +M3"D``#"SCMT_LQ"$9"D=)(J;G#&=!P()_DL<*U,1GF!BQ:=9F8C\1Z>X\#RS +MX)\,\%$3MT;1X@H`/`$``#P!```"````10`!.(+-``!`$0``P*@!`<"H`0(! +M]`'T`20'"_>P\O!4TXMCC(/D0F`36/T\#-AJA1@T'WC:HWWSG]^2J\=`OZV\;5VJ#;!X)5*@=9W.>D?A_#3 +M2K4CCT/&/?/YYS-U#`KXK=HAHVH-':W0M2'-ZT=["!I>!BTE'9H5SS9EVC./ +MS.8(S@``?;C#X.ED7H@E9@Q9>MKY41.W1D[N"@`<`0``'`$```(```!%``$8 +M@LX``$`1``#`J`$!P*@!`@'T`?0!!`?IS2"%[][#R\%33BV.,@^1!RX@)`@` +M```%````_"$``.",XJURN]:2@U4G%8VJ$"OQ$(P;?\BJYVW57IG)4-.V98HP +MCE[,=CK6-K8`U$Q%I/"@3?"M[A-$\NT@HO4;JRN>C#(LP#^$!3-9Y4D\YJ[" +MV]#6V\GNCAEYX5F4L#\UZ"--B$DP*8-8OQQZ@J;GIN[^@OKG>IA +M_@>W=HYWQ9R"IO2=W6W(0DO'UAN5D5X+#)$(Z,6WYDNRCB^9VM*M]]VYW2'L +M0BM,/7V!41.W1F[^"@#L````[`````(```!%``#H@L\``$`1``#`J`$!P*@! +M`@'T`?0`U`:YS2"%[][#R\%33BV.,@^1!RX@)"`````$````S"$``+"@>N$S +MI\1JSPEIH^&XZ@X9AU0'X(K=A-X^C@D4NM(VQ`L@*35_K" +M/YET1>PGNW#'#DHIE*92!P7)+=0:29(AS31K6E2[GL2A+0P8&QE?%J'>4)9L +M>`@/R]]-`<&3AS.)$RCU26^(NB[Q7J`+!.E.::QBFCJ"S$(M8,8>D>$)93*^ +MK"2LB_^>=/-KJDF)-"703M)OO+`$=2\PNV\Y2#4PE_92NB9DG6P`O#>8MN8._W;/2.,H:2D1*+V,M);+\_;P5?R0G3XVN3&Z&?@0KW^*9F6$3IQM&Y-C#]):I +MZR,]G+#[',&`6AW=-&9N41.W1DL]"P`\`0``/`$```(```!%``$X@M$``$`1 +M``#`J`$!P*@!`@'T`?0!)`<)S2"%[][#R\%33BV.,@^1!RX@)`@````&```! +M'"$``0#@TRQ':,,NLWUCJP?L19(T.=J^TV+[`!^ +M@967=6*307`[7)FSWK%I.A:[75"6AHI]=*A'''`O3!WY%Y8BBD +M;U6-B=Q1;"DF0YQ;)^F+$PT+`B^9SO%&O6!\#*>/TQONNI9_`-%!#&1]R*7A +M<9S>B=!7@YV`B&.^IN;FAD%2@(TD8I?$D-(N`I"(_W[^=-')$S"UX+!VAIUQ!Q&1SV<=XP:5H\#%C/0",^`^+>>>G[5410AJ5Y%:&X1.\,5RI]Z2&;4<>7PD"?3R&`W;!N_"8'+. +MH&(+Y&ST9E*^+5CR2[H(FPQG1[F7!C$PAQT';37`KH8^[@\Q\UH]R4P^M(RM +MT/TDBR,>BZ`:,H2A50+G8JP#"(2]R@50GZ5&=$)!!61`G)VO +M4V0*V7RNX,F'8`YRK+6RNM-4<7#_`>/CRUO&HYU)!>/QKBTF:10_V7ZJO0D% +MY1W`Z'P11\U2R\LA5;_:`Q]I,%'@:6O%MB#D$1V]+-$_;^^'\:XF"K:B@*38 +M4>0TZ]'RLZ=Q\Y71HJ&ZU$'^9Y[-K1*/>BB42U'38"C?I;]NFZ)[0[L%U"'[W2K\.^-!$D!EV2ZIZY-LB'.!75-GB;EO$>*!Y_+%E +MQ9QS\<$ZSV]SIYP>B-]#K05BC`*'D_0,8#)1$[=&U9\+`(P!``",`0```@`` +M`$4``8B"U0``0!$``,"H`0'`J`$"`?0!]`%T!UG-((7OWL/+P5-.+8XR#Y$' +M+B`D"`````@```%L(0`!4);_6V=-K<)?YN(RP%3[Q/[O'/FL9XGK.O-OA[/P +M#Q#^TSY8Z5X([+$DJM4$49&HJJS\HL:B?5K+0.!04=%4@]Y')+RS@AHD\P*J +M93,`?8&M9NHCY.%V/-_MPT.G,(HM*G?QFO(8F85WZT&`QT$R8$,[JKD^IDI; +MQ^;A*:*#A([@'SRR*LO,KDA4&C%_%:K$[9L]GMBZX5^3B8,\-F3DH9D<-\6. +M;JIE?3_W7MDZ#RYV@&^.L. +M+78WV-;PY\B'-R,A=[Y:/ZE>N7:-'R)QS+V:'.ZEB727Q3T'C%##5BZ^VJ1S +M$#_)MHX-.^/U:_YF.VQ,Z[!=`"3`07@_B4@W48.JN6>:5!A%(39:0CC-3UJ\F>5MG`P6Q>1T35JRM`[R/GK/ +M1S/9&8!:LKB^E+!9@?6.IHF/1O%U0I^P('0CEE);#>ZM2I%% +MJ7B17SR$KBBC8&EMS4FW[_0[K.<_\_.-7C9K49``(,ABE597[YO1,Z%:FJ8G +M/'5]JHQ32KP3B6U\.==SOGM?922JJ19TVR@V&A%WV8W'R`\I/E$3MT9Y^PL` +M?````'P````"````10``>(+7``!`$0``P*@!`<"H`0(!]`'T`&0&23'?V$L2 +M,&B2FID7&%AJXELN("4(`````````%PJ``!`]@:5I5+UT(Q=394^PAY/2U%< +M1.$"/,!XIQ:CM.O=:)[\1D8D./O4O#IV:-/-87BR#&,&5]1LLA)DV5?Z41.W +M1KT&#`!L````;`````(```!%``!H@M@``$`1``#`J`$!P*@!`@'T`?0`5`8Y +M,=_82Q(P:)*:F1<86&KB6RX@)2``````````3````##^.=NMK!=.E*M3^KW_ +MZY_X6CS*"_@H6,B-,)+NCATDAA4O>J8GI&!>8/(FQE$3MT9D%0P`;````&P` +M```"````10``:(+9``!`$0``P*@!`<"H`0(!]`'T`%0&.3'?V$L2,&B2FID7 +M&%AJXELN("4(`````0```$PJ```PXL4R\H8S(\3?/.Z[@?$)4L?03#.'75L[ +M`Y8@-1ZKQ2@(5&RU8=>-*9+A)J51$[=&Y"(,`&P```!L`````@```$4``&B" +MV@``0!$``,"H`0'`J`$"`?0!]`!4!CDQW]A+$C!HDIJ9%QA8:N);+B`E(``` +M``$```!,````,(L@H9!_(_M`4/+D9F091[&/OO9\;R'EG;QD`0B>($M^[$+= +M7)82O'MZ:;/S41.W1EL?#0"8`0``F`$```(```!%``&4@ML``$`1``#`J`$! +MP*@!`@'T`?0!@`=E9%QOF$I+]3(``````````"$@(@@````````!>"(``'@` +M``!T`0$`#`,$``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``VI]2=2]EK$)0)@PR +M!&7J2/I`JQS<]HP_4+'IG^0I3$6FQBR#$OTP!B3=QR+;IP1K^/(R,JDJI)&R +M@73.T-?MTEM%]4S!1+T=K\.B3%B3\7ZO"+"(T4N_\2Z5"D"L_QJY+B]-^3E2 +MK8O.D@3Z5MTGOE,7`;;,0T'_`R7KL+=J>LHI```D68((PQ((`T`#/.O-=CX@ +M.^_;?U1Z57A4=_]92OX+=W/:I6.T +M````'```0`5F&3*C%UL^@W^T-0'GE7QE@P(K^E$3MT9A+@T`7````%P````" +M````10``6(+<``!`$0``P*@!`<"H`0(!]`'T`$0&*61<;YA*2_4R```````` +M```I("(@`````````#P````@``!`!@````J04GWB<*P2,3F#NIJI?*[W'C08 +M>U$3MT;V/0T`N`$``+@!```"````10`!M(+=``!`$0``P*@!`<"H`0(!]`'T +M`:`'A61<;YA*2_4R```````````I("((`````````9@A```@``!`!@````J0 +M4GWB<*P2,3F#NIJI?*[W'C08>R(``'@```!T`0$`#`,```P!```,@`X`@`,` +M``P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@`` +M`0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````( +M!```#B@``(@``@``VI]2=2]EK$)0)@PR!&7J2/I`JQS<]HP_4+'IG^0I3$6F +MQBR#$OTP!B3=QR+;IP1K^/(R,JDJI)&R@73.T-?MTEM%]4S!1+T=K\.B3%B3 +M\7ZO"+"(T4N_\2Z5"D"L_QJY+B]-^3E2K8O.D@3Z5MTGOE,7`;;,0T'_`R7K +ML+=J>LHI```D68((PQ((`T`#/.O-=CX@.^_;?U1Z57A4=_]92OX+=W/:I6.T````'```0`5F&3*C%UL^@W^T-0'G +ME7QE@P(K^E$3MT8X8@T`4`$``%`!```"````10`!3(+>``!`$0``P*@!`<"H +M`0(!]`'T`3@''61<;YA*2_4R3V-IN&\0-+\A("(@`````````3`B```P```` +M+`$!``0#```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"( +M``(``.R(Q$1 +M1$!A,LK2%P+J&7=))AV?W*X5NF5>GK^RR-,:&^L8-2^Y^.+Z+=$HW*LM:^^T +MFIGP#H6J3QFB,Z.G7FH=J;H98*_JU`&^/=M1`0F_#?7OL!5.5/B-RW`.*0`` +M)+,C>J>(!FBG.7/N[L6OH'`Q;E80J!;G^KJ5YG`PN\Y*M)S]@2#U,?@DAD[ +M]E7X;*?]_['MO#]LK;+?=#1VTBTB$*!RM(!4AQS>`^1.G#F3BD<7$J+L4G8L\4M[%.6N[+<:UY4YC)],OL+W4P@H^>YMGBJ>+M +M&>3J^XCF'.F'PW#GBTFZ\$ +MNOG*Y@[>X-EAG/WTEU$3MT8MJ`T`O````+P````"````10``N(+@``!`$0`` +MP*@!`<"H`0(!]`'T`*0&B61<;YA*2_4R3V-IN&\0-+\N(",@`````0```)PD +M``"`:*GX6SG27[T/!UG!3HB+3>6M?+V7),B'(7@AKRZJ4\6FE#1DC.J'849D +M6`=<>;NL8NI41(3Z3-U%RP;[OG6Y`DJ_\'+ROE%ML>#97_V\;"`KG7X56`_G +M>Z^31R)7TES'&.#FA[];%L^*6Q2DNP6FP11:I"7H[*1C:M[2X%$3MT86QPT` +M'`$``!P!```"````10`!&(+A``!`$0``P*@!`<"H`0(!]`'T`00'Z61<;YA* +M2_4R3V-IN&\0-+\N("0(`````@```/PA``#@5;D4;RP^BMCDPZXJ/NW5RI`K +M/W[6,_@SB,?:OHI034;X-!Y*37UV/ZE?Q@5]@`J^C6*[W7I/VY.0MN@Z?]SK0$60O5M)H`4`_77(<$;/W&$[H9<*7LK'Y; +MG/\5S3V2208R:_2`>B"4895MKY-V?+D&7W?[&=TV.]]&$H2U7;^=TH(8*A3Q +M<_\I%=09$F51]U_**2W:H8!BE>>GF.23:R*OJ#1\5M`7-/^@K#C&AA]?6`$9 +MK763Y]2?1?GE&C'.\Z>ZS5^/+OCX0E$3MT9FT@T`_````/P````"````10`` +M^(+B``!`$0``P*@!`<"H`0(!]`'T`.0&R61<;YA*2_4R3V-IN&\0-+\N("0( +M`````P```-PA``#`,]P==R6Q)X<;^9];4,J%DKLQMF2#W/8&SJSHC"L;&LE\-+XB+.!Q^`L$G?/N@'?"1`:("5:>;(GQ'`@4$%X_,[Q +MZ%W'5"9`RZFXCEYLIW]#G3DH-%`?DH[655@YB<<;\7GDHUUB<2C#/5>9@!0C +M]?_J@1R5,$"`6^%Y;IR.3\!)_@5"!/&OL5G%'D9,DARU>6SPZNCBB_KH)@@\ +M^*;>I$+ECP(@,4NRU<`#%[;+?QBJ9""M45#IS\3M68F+A]3`I5OQ3$@*U#/7 +MO1-,C]X:PZR_?=JDXVZM7=/\8%I4V"<7IL(2P^BSZ-J62C,R&"G@]-LT3'P) +M2O*L!ON;)UP`\23=W>2Z?Z%&!G0`YM0I8&OC%WR0?/*<]]Y7'Y.WVQJ-PR2A +M^O7?-GT'7BRDO4'$Z>NW41.W1ML>#@`<`0``'`$```(```!%``$8@N8``$`1 +M``#`J`$!P*@!`@'T`?0!!`?I9%QOF$I+]3)/8VFX;Q`TORX@)`@````%```` +M_"$``."@SD3)8Y)8=X-O$I>N71DL^W5':KV`ZTZP^RK*8U.0`VJ""(96KNXL +MSVNJKA%E)I,WZU)O_]$6R=M@/;\(Z0)RK`$?_'HR7R3@D>VC'=_YWQ-98.!" +M6;:Q4PW.#+JFMKNPG.3-Z/O.^]QHL$B>M42.CF:V[-/S8+2C%[.I +M6>)=2$;^Y=V=(1!Y#-C4;GC,E1+91!4',RDZ=>C)P4$&HE6_U^$!%#=&(&F%B[^R=MH-"=R/GS7,5C>V:N#$GP+Q@4" +M41.W1K,N#@#L````[`````(```!%``#H@N<``$`1``#`J`$!P*@!`@'T`?0` +MU`:Y9%QOF$I+]3)/8VFX;Q`TORX@)"`````$````S"$``+#`1J$^VN/N*'A) +M-%TSL8Q!3"RVVJ7J!4/ZC++,E^FQB/DL90^P76UE?L=9J0F('H_3&4CU^X47 +M#[17`-<]@D!5=ZHW.75`HV^IQ`UX>MUI^S=6.E,JRW+W'B!4KWVQ#6OL3E3( +M]&"-M<$`H846=&I0N478MI2M4,41I'30)F/\YOD +M*GTL30XP,E7@I:4*D.E&(WBZ6J(OE8-8DZ:<41.W1KQ1#@#L````[`````(` +M``!%``#H@N@``$`1``#`J`$!P*@!`@'T`?0`U`:Y9%QOF$I+]3)/8VFX;Q`T +MORX@)"`````%````S"$``+!IVCHU$@JJ*#17U1>2S0-]R-^_>,]W+Z=M``J\ +M +M1&N1`299B),>4(N9>5=6$*,N"-C]VFH7R5XW)Q_)$#;G,^F_#K#JM[Z:1G3?-4 +M2$\,`LK5?8!N41.W1G1O#@`\`0``/`$```(```!%``$X@ND``$`1``#`J`$! +MP*@!`@'T`?0!)`<)9%QOF$I+]3)/8VFX;Q`TORX@)`@````&```!'"$``0`& +M.SVR>M;T6;/X/#*$7,W,8:6>`Y*E>3PMK`AM^<"E`46_]^@8UY/2*UZT50!:,[I+#':Y +MT\61\P?#7NCF)487ZG6_EK9*I1E86>N;^@%1$[=&5GL.`!P!```<`0```@`` +M`$4``1B"Z@``0!$``,"H`0'`J`$"`?0!]`$$!^ED7&^82DOU,D]C:;AO$#2_ +M+B`D"`````<```#\(0``X"3;]%*S'U)K8RE239#>I'30#BO1GUS>P0ZP +M;J&C/@N)'.5QDD.SF@BY';$TQ%<,/4;6%21RU1M/_R#PY="B_+EV9SO-),HU +MR6Q".7BG,SI2%NPH33`OU]L3<"IH.$*<)%XN^H#_G`1J7+./E.N,U0_0\7T= +MV'H[&.?J\'D:TIJ(0"$]G"5NNZ()#YE1R94H@!>UW[.`W%Q)NJ/1& +M^!;(RL +MJ7@X2\2[I,/A#/#H0M;]3` +M?B*0I,O^_*Q]D*_]X>T$/SL;>M,S(VU)S,22@M%O\F3WF1$,=FI1$[=&8:T. +M`.P```#L`````@```$4``.B"[0``0!$``,"H`0'`J`$"`?0!]`#4!KED7&^8 +M2DOU,D]C:;AO$#2_+B`D(`````<```#,(0``L'>6+=Z/XHL"+H-09*KE3L_? +M`=S>"T#)C[5TR;?D><2?AP&F@<".$VI6&7C$Q'=!0+>RIEM-LT#\* +M\*90CSBFEQTQ&M>$>U!3?1$=2L/&`TLXL\@<:UGKM^M)1$[=&T=,.`(P!``",`0```@```$4``8B" +M[@``0!$``,"H`0'`J`$"`?0!]`%T!UED7&^82DOU,D]C:;AO$#2_+B`D"``` +M``@```%L(0`!4#H#YV'BD+$":"L;74O.C04/K^GF(\*H=X[>YWH[OBR. +M10X##N7R8$QR/1=*[#H`U8H?D\&M5[@>Y!N.TI-ENP"V+\3X)>(#$UF:5\^F +MQG*#?!-L#1='ENE()WY0-^*&Y7*A5;7DO>O\5S3C%>DGRI>EW?1]9E5(O&H' +M'CK&J_!\?43C%(<)N*<\#"+2"-0/CWJ^>KMT0`V0YY$^442Y+L +M00O-R60,`+UD:KR-^MA-(3%XQA-!;[ON<`UY``+=?,(%"N":3^ +MCBT/_AME&Z=B4EF?R^I7/!>CZT"^JF,<(.0:MD8UX`UY!RXH$*G.8$,O^!EW +MD=2@XABK6;?.W=W&>%J0OWZK3-/5)$74*3`W41.W1CX)#P!<`0``7`$```(` +M``!%``%8@N\``$`1``#`J`$!P*@!`@'T`?0!1`S']E]RD'2.E*_$']Q]6=5[!Q1 +M='U&_S)`KA0T=`>_\A`GE$YD/N70:=RYN>( +M=%YG5`S-3>.VUA:KW6`*W2S&/CEK#6%+!A2#%RSC-%\;P'3+?4><'NMPLCO4 +M+YN*TAR6X`=\UNMK$1/?#'_!*.,HL[T95*KM>B[:>F\W[W?/2?=3L+1ZH%\A +M2T]^PD?>.)/A;'3SJ1<-D*N]Q'BA,%(MP)3U>W*10\PY;2-F,Y=])T!U_VX# +M#U(+P``!`$0``P*@!`<"H`0(!]`'T`&0&227ZG]KRFGF#,D++ +M"HMMDW,N("4(`````````%PJ``!`2I2A>]?OIAAAN(PP0#4;#.A@0ID7]5!$ +MO/G7J"8`28BR?`%DPM@%J,L$KBH7F43>Z4_WB'"]WT:UY[(`41.W1D(_#P!L +M````;`````(```!%``!H@O,``$`1``#`J`$!P*@!`@'T`?0`5`8Y)?J?VO*: +M>8,R0LL*BVV3#+W98DB+@W7J_VZ,1](7@Q^'E1E +M+*)#I9$UDK1M@3HIV^12$[=&1!D``&P```!L`````@```$4``&B"]0``0!$` +M`,"H`0'`J`$"`?0!]`!4!CDE^I_:\IIY@S)"RPJ+;9-S+B`E(`````$```!, +M````,(^R0Q6DN"^\!^#\QZ&W"1"-*W>`I^7<3))SK^[8]#03,+_4,6[.E4!) +M:*CJ4A.W1C$7`0"8`0``F`$```(```!%``&4@O8``$`1``#`J`$!P*@!`@'T +M`?0!@`=E1FR2NJ.5`FD``````````"$@(@@````````!>"(``'@```!T`0$` +M#`,'``P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```# +M`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@# +M```%`P``"`0```(````(!```#B@``(@``@``@`V;)@21V?C]26``Z.RD+5BI +M\R#PVM5:H)(7PZ?1@`,40"+MYS66E$DY#I"EZQUQ3D$"7=LZ!('03N$+ +M.&NA-1E +M(!))/6^Y\BA9\=DI```<``!`!&'C3Q>28F&V[]ST^L0VS;=3,(WV````'``` +M0`5\%2S2-4!.(*N?F#(1KVY"X-AKME(3MT8Q)P$`7````%P````"````10`` +M6(+W``!`$0``P*@!`<"H`0(!]`'T`$0&*49LDKJCE0)I```````````I("(@ +M`````````#P````@``!`!@````J8)2K-]9N#`9C4Y?ADZ0=QQ=(+FE(3MT;# +M-@$`N`$``+@!```"````10`!M(+X``!`$0``P*@!`<"H`0(!]`'T`:`'A49L +MDKJCE0)I```````````I("((`````````9@A```@``!`!@````J8)2K-]9N# +M`9C4Y?ADZ0=QQ=(+FB(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```, +M@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@" +M```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@` +M`(@``@``@`V;)@21V?C]26``Z.RD+5BI\R#PVM5:H)(7PZ?1@`,40"+M +MYS66E$DY#I"EZQUQ3D$"7=LZ!('03N$+.&NA-1E(!))/6^Y\BA9\=DI```<``!`!&'C +M3Q>28F&V[]ST^L0VS;=3,(WV````'```0`5\%2S2-4!.(*N?F#(1KVY"X-AK +MME(3MT:D6P$`4`$``%`!```"````10`!3(+Y``!`$0``P*@!`<"H`0(!]`'T +M`3@''49LDKJCE0)IAK@;?JI(\!8A("(@`````````3`B```P````+`$!``0# +M```,`0``#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``(YL +M(P"<4AS\Z)43#5JYCV6#*BE2Q<'G9A\A]5<25ZLJ''I[7%C*FP*)-WZXY(N- +MPX?&&J=2B_R(1C"^;-I7DYL"E","Q:SJ$G,PF>@8[%%BRE"*)\RT*KOU9*+K +MAY]1"7!:_R'IKW[+N.[AK,G%,3H("1E5!MQ24`4?$@M8$S3R*0``)*L+`G+D +MS^KP`U7YOR7P/*J)!8E]RQ#0DG=78N5:#$*G*0``'```0`37B])C^B6$&&/= +MZM*UR5_E)_'Y(````!P``$`%2Y37@*?IN=2Q,@GY[C#M'%^Z4WE2$[=&V8@! +M``P!```,`0```@```$4``0B"^@``0!$``,"H`0'`J`$"`?0!]`#T!]E&;)*Z +MHY4":8:X&WZJ2/`6+B`C"`````$```#L(P``T*T'2$)8IB&]8ACLR +MV%)MD]%Y'>!/X8E?PL-UG#5(`+K!A_\D,AVN;3%L4@#IKQ-2#8E,QZF^D>XB +MJ0U?^@5AVN(@U="MQ)YR[AV^&9^^SJ`2,V%*CX1TJ.-J*-MN_ZBV. +MXWJO6EBY,;6T'+_Z.X^6076C(CVO?^@6O3^K@N%`U(3MT;;H@$`O````+P````"````10``N(+[``!`$0``P*@!`<"H +M`0(!]`'T`*0&B49LDKJCE0)IAK@;?JI(\!8N(",@`````0```)PD``"`&(&! +ML6(O[DKW]1#,J>+(MCLQ)HG)1T;3N988V/9N;4X!$6^1:*;P0$`'`$``!P! +M```"````10`!&(+\``!`$0``P*@!`<"H`0(!]`'T`00'Z49LDKJCE0)IAK@; +M?JI(\!8N("0(`````@```/PA``#@==U#A?86TPNJL6P!M!V,OOHD)K=B%28%CF5A); +M.QIO4AQ^T.PU8![X;EFXFT?^8&#D!&S-6"CD`KQ,1*.% +M=-8]8))BG!%ZPS[3`40Q?%(3MT;\S`$`_````/P````"````10``^(+]``!` +M$0``P*@!`<"H`0(!]`'T`.0&R49LDKJCE0)IAK@;?JI(\!8N("0(`````P`` +M`-PA``#`"Y*4:EO@-=],7X$M[871Y)"SX#L[X<=R:GV,,/^F05+[3WY@+^AZ +MVE'JW:*#DVAL2U=R`AI31[QQ#84 +MHN$)5/1>`6C1,(+M//)<:BLB&M__6KS[!'T^)&JHC$"?CD6.7CR.:SNJSBOM +M=.=+,&V!`O7:%F0\8:I2$[=&J=/V43O"`9K/&,Q0Q2:^ +MB/;W]PO.Z-9E8LQMSICSV-K=-?/LK[P8EFT$26+_26U1Z:=@KKWA2FF7O7B. +M"B5P@T!Q4?3R9M$'*3:)-M_2T8_%1:[#51EE>_P\,>JCB=%500#XQ],^*7\` +MP6-CX^C\"_GQ>L(\@`^X2[5Z-8?56"1/)+M6O!_A18]/)N-3:GDW0N0J\$W# +M#@N?L2.SLA$HX\73A^$D5<*EKZF>V-5RQ,OJM_U6TT1$:.HWN932L04A.W1D$:`@`<`0``'`$```(```!%``$8@P$``$`1``#`J`$! +MP*@!`@'T`?0!!`?I1FR2NJ.5`FF&N!M^JDCP%BX@)`@````%````_"$``.`W +M;:Y_*==/KQGJ:;"TD(/Z\&)!G%]7I>0HW*?I]%N>5P93!\2QA\UU1CD`?8TO +M##\(A`R-?0RU(/B'JR@%3=)1FS9?\DV(9D6J#X99%F-KT4CPT33T9^@IH)QD +M-3A@EI.^BO+3<>]ZTU+P"RGI$KUM+MQ,;_'%W6/V+^3-][!TF-P";J1`F14B +M9:+VT^SL[,K7)B)[T?YX68V#I7U`\MK9&-(4VF"?0+Z#-UR]"H +MD"YQ%7=BO4S\/%A)945"-VLTLZFK(;.232NAS>C1R^,I#.VTMO/@\?P@Q +M4TSXD<"5'\NBFD#-;D"QP%6$IG584A.W1LM,`@#L````[`````(```!%``#H +M@P,``$`1``#`J`$!P*@!`@'T`?0`U`:Y1FR2NJ.5`FF&N!M^JDCP%BX@)"`` +M```%````S"$``+`(2&FS'\4!J5EDU$`J&9J#_&(I:\H<0=2B2A8*)IZ4*:F +M0+\G4A.W1I5I`@`\`0``/`$```(```!%``$X@P0``$`1``#`J`$!P*@!`@'T +M`?0!)`<)1FR2NJ.5`FF&N!M^JDCP%BX@)`@````&```!'"$``0!F6A)+1/^) +MWWDG:\&P"X_\GV(%IJU_0IX]8GB8HV^9,99!QC^='7$- +M9&@?Y.RDB3'>Q +M%RV5D16@!J6;"W_X3V%MTD)YT7FL6T+O;!2_+'J7[K&V#3_\PZ>QLFKZ_QR]S&MEQ+?L@MAOE5&+#4VC3"T3!W-?/;5#!+\Y +M`BS0(.>-6FP](>BA*JOTO!_Y%-]2$[=&"G4"`!P!```<`0```@```$4``1B# +M!0``0!$``,"H`0'`J`$"`?0!]`$$!^E&;)*ZHY4":8:X&WZJ2/`6+B`D"``` +M``<```#\(0``X.F>=FU8?WWL]F^_'X"V$:F2'Q+>(@C8YJ&_:V"4)7GH!)GM +MRF^(HKQKV.0Z0IT.`7B8L&QS3CWD(A-]H\G;;=K8>[WIE0:,WUD']-F<2!;JY)^U[6E4+Z8&"<-Q-(MU]YPNB-)I17JA:42W7>.IIW]M.+U? +M5!KCNL];9.+^&3\M@9>3HVOQ/O_90?5'V;-#JD+\2%D$$I^06$QIC;?M";*( +MS`Z$&[0U%/$63S"#S2K,N2XYXGU=]T>7_00@P2;1S"!2$[=&@J@"`.P```#L +M`````@```$4``.B#!P``0!$``,"H`0'`J`$"`?0!]`#4!KE&;)*ZHY4":8:X +M&WZJ2/`6+B`D(`````<```#,(0``L!XLUP--NQ12.O2?UZ:JV)S]> +MBZ:5%3T;&9NEM'3U3?S[7MG&Q)50LN@([%"'QT)?6@1"=:T8_?_)H@.%^*1; +M5>0W8`B\^&*/$C^K%J9'J/]?`C$[`SMK?]^5I>N,#]O0J$ +M=_G/K+Z@L<%UP;X"2N92$[=&,,X"`(P!``",`0```@```$4``8B#"```0!$` +M`,"H`0'`J`$"`?0!]`%T!UE&;)*ZHY4":8:X&WZJ2/`6+B`D"`````@```%L +M(0`!4+//L>6-IA@10HR):H<-UAU%C1QSVXVC7W:FX[4YZJ;D`YI\+R,?HY4) +MH:WG?,=<4EI5=5=1C^8X;Z:$PE=SJ/K&+,^).:B6_HB38@P&>-7`E]@@;41D +MOZ*9R@EVGH*7G`$O:)@WZS+R!W9CD$=)$=,X%V\'CJR3MNIO2T&8;,"`<_J!(K/U@M+YHF*'@Q&W6!]KZG+$]\9%8 +MT6U!J6?2K=7G6<_D\GWU*LZ*0F\7ZH?'"L5@3P)#K;5.3[`2_N#+7.HKQ@D*CYL/N'V&'2_VNVK\/T6 +M3!+$ODOP3Y&5/9J5M$+1&PF`O67/U5HI+FZ^2_#2)<^D7B#59A-SY%-Q"!09 +MXZLUWR=JC-V\Q^<*ZA!YD)D"O(OG4A.W1F,#`P!<`0``7`$```(```!%``%8 +M@PD``$`1``#`J`$!P*@!`@'T`?0!1`N12`NS==ZY!1T&JZ35G>&GD?T +MMZ(%D\O)@QJB\L-RE-3@&F<4NSI#&TV.<6AN'0V.#F363'51-C7;\:23(,*``!`$0``P*@!`<"H`0(!]`'T`&0&2;T%EB]4\L<^=S?BI/#'$(,N +M("4(`````````%PJ``!`B=`^P'&+U1"XHR7"%?\D2/$VO(AH(J8!9=Z!B(*Q +MD-P_0S*I@W>[;M$=]JN$"!7+O+J,Q6P/K3LK'Y1N4A.W1L\U`P!L````;``` +M``(```!%``!H@PL``$`1``#`J`$!P*@!`@'T`?0`5`8YO066+U3RQSYW-^*D +M\,<0@RX@)2``````````3````#"[/[%)\Y+F8'O#DBN5"F<<<,B3(:(L6A.* +M&,DB1)OXFD>-S[5C0T0?+MC7`%(3MT9U1`,`;````&P````"````10``:(,, +M``!`$0``P*@!`<"H`0(!]`'T`%0&.;T%EB]4\L<^=S?BI/#'$(,N("4(```` +M`0```$PJ```P0;;TX5>+H2:_X63=1OMETD1]Y8)'OUTVU)GE$$?*&93L7&"; +M$`YELEK\_XM2$[=&=E(#`&P```!L`````@```$4``&B##0``0!$``,"H`0'` +MJ`$"`?0!]`!4!CF]!98O5/+'/G?*G>E_>G#6UEH\=^:YZ(A:Q;?*&-(*"V9+@(+S9F4A.W +M1G1/!`"8`0``F`$```(```!%``&4@PX``$`1``#`J`$!P*@!`@'T`?0!@`=E +MW18[AP=8\Z4``````````"$@(@@````````!>"(``'@```!T`0$`#`,(``P! +M```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(` +M``(#```(`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P`` +M"`0```(````(!```#B@``(@``@``GD3^I_[<7@O?=@X%+B?C]8GY"%TJL36D +MP]VC)[`LTNMU6,)A%.IFS,8/9%E#(`SB2J#!W(H2LLSCCV1/, +MA='`=T4&%-9W^:-;1<\?DQHD]VZ!4C1,^(D3=%^6.1HD.7\>^'Q"'>7.+/LG +M%]NOFMC6@`YN2=D/"JTI```D@26!_>3+Z!\`J#A^1QZ($=$$(]93(]IJLH,4 +MN=(G*2`I```<``!`!)$62KFR$>4XX_W*6\NVNN.OTJC7````'```0`5A>"7; +MU"0NDN7(R)3+39,',\O3N%(3MT:>7@0`7````%P````"````10``6(,/``!` +M$0``P*@!`<"H`0(!]`'T`$0&*=T6.X<'6/.E```````````I("(@```````` +M`#P````@``!`!@````IK@>D00E&K5]Y&,NK?`;1"D*D)+%(3MT;M;00`N`$` +M`+@!```"````10`!M(,0``!`$0``P*@!`<"H`0(!]`'T`:`'A=T6.X<'6/.E +M```````````I("((`````````9@A```@``!`!@````IK@>D00E&K5]Y&,NK? +M`;1"D*D)+"(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,` +M``P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P`` +M"`,```(#```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@`` +MGD3^I_[<7@O?=@X%+B?C]8GY"%TJL36DP]VC)[`LTNMU6,)A%.IFS,8/9%E#(`SB2J#!W(H2LLSCCV1/,A='`=T4&%-9W^:-;1<\?DQHD]VZ! +M4C1,^(D3=%^6.1HD.7\>^'Q"'>7.+/LG%]NOFMC6@`YN2=D/"JTI```D@26! +M_>3+Z!\`J#A^1QZ($=$$(]93(]IJLH,4N=(G*2`I```<``!`!)$62KFR$>4X +MX_W*6\NVNN.OTJC7````'```0`5A>"7;U"0NDN7(R)3+39,',\O3N%(3MT8F +MD@0`4`$``%`!```"````10`!3(,1``!`$0``P*@!`<"H`0(!]`'T`3@''=T6 +M.X<'6/.E'J5/>YE`Q_$A("(@`````````3`B```P````+`$!``0#```,`0`` +M#(`.`(`#```(`@```@,```@#```"````"`0```(H``"(``(``)?T2S'ZDLJ@ +M^ZDU_XG5V-V:$]">#XVSHJE&T`K`OR_J7.P;I*0``'```0`3)0J*:OICA#Q!WV^J>^P<9 +MOW;$?P```!P``$`%3KJG[>Q&_+C4'_UQ31.`9/YF=O12$[=&-[\$``P!```, +M`0```@```$4``0B#$@``0!$``,"H`0'`J`$"`?0!]`#T!]G=%CN'!UCSI1ZE +M3WN90,?Q+B`C"`````$```#L(P``T&JXM@_O)QU-S)K=$89??.0&`U,PN.OI,Y\'2[$ +M(Y!_75H+S7FJ4I2EC=NK9SYVYF$JQ`RTUEYYV=!Z!3 +MT]$I??HU115*K1X;3[%1'%DIS>5A\3R4M(83__EC965R>.,80YM: +MO%(3MT;HV`0`O````+P````"````10``N(,3``!`$0``P*@!`<"H`0(!]`'T +M`*0&B=T6.X<'6/.E'J5/>YE`Q_$N(",@`````0```)PD``"`#/(EGS4O_![_ +M?4.\(>7).2CRN1F##I-19V=75"N$`O?[OX +MY=$M3'[&).'CP1(U*D@[9!0#!R-\UQ.C_U(3MT;2]P0`'`$``!P!```"```` +M10`!&(,4``!`$0``P*@!`<"H`0(!]`'T`00'Z=T6.X<'6/.E'J5/>YE`Q_$N +M("0(`````@```/PA``#@YS+OUHM!A9Z'?S@OZ^II.<7@]9-%UQ.TJ,TP_?<9 +M*V&A%UMU\_Z`X69@32[1@N5*<(CY2;)FZ%JV`L`P]+E0#9FJL373Z+9FJLMC +M%>$[[5,"F"'1VJIV8[HS$$9-3GUDJ.!6*CBMKIJERU5#PA%D"IL>;NQYE`Q_$N("0(`````P```-PA``#` +MQ_SU,@_-S84M]Y68+92H8?Y:2:#"*MMLKX86AZ$$=UY4%[/K76F`E@>WW/>4 +MNAORV%R4\JC-,&A!L'W]?.+>*T4H'7Y]J$]WYD!,"LJZ_CR`?G$1ED?J],/. +M)W%(:=B?SQ`>^]*;3W1*!]C$UF/KP*3>?9MJQ8I$)E%Y3Z2%`:^HL95607Z; +M=^ICR_.(J@S)+_=-Y84%OV_`J'$@[;L]]2>\6XT'U]SN(@R<#+8%L_!,TE<= +M@[I+Q`H(IVQ2$[=&7`X%`&P```!L`````@```$4``&B#%@``0!$``,"H`0'` +MJ`$"`?0!]`!4!CG=%CN'!UCSI1ZE3WN90,?Q+B`D(`````(```!,*0``,"BP +MZN1TQ0*[Z8]4J0!=$QQU?D@>ZY&6*$4L$(ML64.07BP>>XA=@)(_ISS]4A.W +M1L8I!0!L````;`````(```!%``!H@Q<``$`1``#`J`$!P*@!`@'T`?0`5`8Y +MW18[AP=8\Z4>I4][F4#'\2X@)"`````#````3"D``##I13R&S\L6Y.J>5(Q( +MJ5]E[I..1MO5UE%K)64F3TM?*BV-E/>#7QV255^J>%(3MT:*1`4`/`$``#P! +M```"````10`!.(,8``!`$0``P*@!`<"H`0(!]`'T`20'"=T6.X<'6/.E'J5/ +M>YE`Q_$N("0(````!````1PA``$`TR1-&:>H#92411_]F_OO;9AFCVY0@X5S +M(VQP#0+AF]?=03-_18*5Q0IW'S9MB?EN,0O-3<)-CN\SUAVPDM,`NVMXP;DN +M5`;KW`V%P1O&XPAO!3F6[_408>$?;!Y7JX%&#-B*A.0X?LPS.6G<$AHX$/R) +MD,I,+U%O,6*+,B`GWR>M;KKRUMJ&AAD+)$\K!RJ?U8=AW)&K"AC_@D3V>F[Y +ML$04<'*,U_)X2)+\,"9];K*OH)%9'"F[85.\I#O_KH3YK1GJV[B/8X'%ZX"V +M@[X;WZ0130WICB/V@-,^).QQ^&A4R^:4@%7X,BAG!3CH/M29'4I4][F4#'\2X@)`@````%````_"$``.")"QWB-#N+ +MKHD>S+YAB-\LB_8Y)1KMTZZ_U26K@<^TY>2DR;90<3VRBSF#]TL<,O6&XS#8 +M[:39`"ADW?JD#*90*%+1V@'.;A9I<&WU-IYK5$ML+G"_^W"I_`1)]00G68:? +MDZ-N+$F2,,62MD+;;*GY25Z[B,S^>K9,ENM@AIFSF..DV=5X*O.H3YR!9%8! +M,WSF1Q/FEWWP +MI4][F4#'\2X@)"`````$````S"$``+`A4C5=]('/?-SWM*XX>#)J20[*](M, +MC^&4\/TO=1@9B$;$.AXQ?1"%]QZH%ME9_Q.J'.J,&MBN`@]JK!:WPX9'1QRJ +MM"2:UFY^A#K7=05M].?":^%N]P/$4_@+?R53QY,32#2=2PQ7^#YM$,.8^_0GX4LI@>LOG9!YQIW@#"S(V)&BDOZLD* +M%J@RRFF_*.M5?H,`00$/4A.W1JB!!0#L````[`````(```!%``#H@QL``$`1 +M``#`J`$!P*@!`@'T`?0`U`:YW18[AP=8\Z4>I4][F4#'\2X@)"`````%```` +MS"$``+!EQB;>$O=:T0;@R0]D(6H8%0%^5B)RS8`-4A.W +M1AZ?!0`\`0``/`$```(```!%``$X@QP``$`1``#`J`$!P*@!`@'T`?0!)`<) +MW18[AP=8\Z4>I4][F4#'\2X@)`@````&```!'"$``0"<_BIBODFS^/@@2AN\ +M("FT,CY,9T$P:K\,8&KIDM<7=Y(3.I"VCP"7?X%8-A1(]?U5Q93@.8[W>EX$ +MKF"*&!MM2#\R#].B%V\]PK"!7?9$VD8R<_?@S,\P7_^18ZJ(BW>^3P$`12[T +MIC;OQG;/M%A5,F;82#\.Z+OB?%NFL'L&U#YFM2M8+V-?/[^JYE86`N,,OKZJ +M`V!%A6["I0D7=Z:ZA;K23G]Z(Y*[$<"(,B,]KB5LGX>>CR*F])LL4M.DF/=A +MH'7VDX0J3^NL7B011S2?>$-L"@LB-ZF/@=PUZ`D,=#P71DD%0"7`P/[[:;\> +M7$)TNWR)$;(7DL#*UFM2$[=&/*L%`!P!```<`0```@```$4``1B#'0``0!$` +M`,"H`0'`J`$"`?0!]`$$!^G=%CN'!UCSI1ZE3WN90,?Q+B`D"`````<```#\ +M(0``X,?U$JP[S)C)XRHPBE0V3H0C'00&[KM1BC'1C9[7!"S37V8] +MCA0J^"#>4$TJ1]\*'$BN9Q+KQ*WR(&$TB\'?ZD/Y>TL9W6'^BI'0LWSQV_:: +M#@F`09"DOPND)?2C!+=6@T+8S6!BD+(-$K'8C`T2?\8#FR(QM,N=.HZRU6*- +M9@?-,-M]06%<>'12*H[06FL+Z*]`NULJ&`)JO,_;.$WUVEM<,8<=YQWA6`5R +M72:MZ^TN(">&BKKY'QJH]+,_BF;D2ZYQNO+TO".L*-7*U$N`&A852 +M$[=&Q;P%`.P```#L`````@```$4``.B#(```0!$``,"H`0'`J`$"`?0!]`#4 +M!KG=%CN'!UCSI1ZE3WN90,?Q+B`D(`````8```#,(0``L!2$)W$7SH%8X0#] +MQ*C@O)[KC[;$]Z:QB0P+./(A\$#?`R[SBLF2S;QN8?11KLP7X$IBJ'AW^,7* +M.D86;0.2_"Q@!$P)_>LB:C,*O-U9:S'Q0IN3_?5!#W34.&E*)XY@2XM$7^T" +MVCK)ZD4`,NGC,Z,*,O;0$:OFF!I%UP>MLS"_[K0+VG^!]GO+(..I<.&J'E;/ +M3W)MUCQ&2,VF#?%(IF[3>/C%18+7),D8^"M2$[=&+>`%`.P```#L`````@`` +M`$4``.B#(0``0!$``,"H`0'`J`$"`?0!]`#4!KG=%CN'!UCSI1ZE3WN90,?Q +M+B`D(`````<```#,(0``L/[F87W9&R>LSCQN2T!(_HF"%T'+D"L28BP_7I&3 +M7`@BB#@H5N3^8_PK2%/G\M#%@4=!^L\6_E>A!F*-O6HX?*2[>`/4+#(\E;O* +M=$61$`X$@').VVT)0A3&+/TNFL#:$,CO\ZFH[)M^HE^L76^=EJ@C.C`\6=ZQ +MLQQD>[2/1":F4_#(K)%XN`K"2]I'*4%=EVD" +MX:'@ZLO92$[=&\@\&`(P!``",`0```@```$4``8B#4P``0!$``,"H`0'` +MJ`$"`?0!]`%T!UG=%CN'!UCSI1ZE3WN90,?Q+B`D"`````@```%L(0`!4$C' +MR_7&;/>W`*QS#AH,D\VB>QY-K_1#%O<>MV?`F?&2#GU';_[D0J5Y3(E,/%B;I7JD60//"DGM4(C#8 +M8Z90-&TR?<-W$U*,]:DC04/7WU6$$;H'1K&&JOA4%T7& +M7'DH/\=XXM`1U%Q-DC?47[6*4(Y??73R:6%E?3=&*K8^"@*N5B)>SOD>DGA; +M8=SWSC@\T7K10I4][F4#'\2X@)"`````(```! +M/"$``2#YCC4.+2@TAN( +MAU:P`\2D5;==,$]7_6Y2Y/O)[VSGYHO,G7L1N8I:4V+7\A%PQBAQX/C4#&SW +MWH'"59\-T;$*NH%3(.^ +M``!`$0``P*@!`<"H`0(!]`'T`&0&20G!DQQP\S8_>K%`Y$\P&%@N("4(```` +M`````%PJ``!`A"$V.JD>B'VGGBI!B\YCK$2>+H'0%=GKC%*9L6+I:C@,JB!3 +M&R_-^H.HP%V8)%MB0Q@[M$M6(8L=AW'F4A.W1KS*!@!L````;`````(```!% +M``!H@[\``$`1``#`J`$!P*@!`@'T`?0`5`8Y"<&3''#S-C]ZL4#D3S`86"X@ +M)2``````````3````##2T"=1BC9QE10S@3A>%X3;WGT_SD%(3MT8PX@8`;````&P````"````10``:(/+``!`$0`` +MP*@!`<"H`0(!]`'T`%0&.0G!DQQP\S8_>K%`Y$\P&%@N("4(`````0```$PJ +M```PB78WYN<>*Y>+-,YUCC8WVS_$FU2I3:$4I[_?+]I?,+UBSJTU>G50>W-% +MMZ]2$[=&908'`&P```!L`````@```$4``&B$$P``0!$``,"H`0'`J`$"`?0! +M]`!4!CD)P9,<!X?Y=.(.HB?R_8S-:H1.B=I,_'/VW\=HV>YY4A.W1K0E"`"8 +M`0``F`$```(```!%``&4A$$``$`1``#`J`$!P*@!`@'T`?0!@`=E;#4V5*QD +ML50``````````"$@(@@````````!>"(``'@```!T`0$`#`,)``P!```,@`X` +M@`,```P!```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```( +M`@```0,```@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(` +M```(!```#B@``(@``@``BB5$W#OQ1MW1$*?3A:*AE/%`-]O+Z$T7A9)0=!U[ +MA5@@>[U!$TZGH%KQL.=3AD`D"@J(X!=:2ZL9GJ7]U0O#V]N5I[TDYC**D&"? +M[7,@">.L.5BD:X,-@T?@-;0OYY7)25LG_TF^>X=0%UPMOX09YFQB)O5(,.AI +M["+0NM7U>S(I```DU/=1-F.%1QACR,7HU(3MT9,1@@`N`$``+@!```" +M````10`!M(1#``!`$0``P*@!`<"H`0(!]`'T`:`'A6PU-E2L9+%4```````` +M```I("((`````````9@A```@``!`!@````ID"C"M?_7NL+>=1-F.%1QACR,7 +MHR(``'@```!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```, +M@`X`P`,```@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(# +M```(`P```0,```@#```%`P``"`0```(````(!```#B@``(@``@``BB5$W#OQ +M1MW1$*?3A:*AE/%`-]O+Z$T7A9)0=!U[A5@@>[U!$TZGH%KQL.=3AD`D"@J( +MX!=:2ZL9GJ7]U0O#V]N5I[TDYC**D&"?[7,@">.L.5BD:X,-@T?@-;0OYY7) +M25LG_TF^>X=0%UPMOX09YFQB)O5(,.AI["+0NM7U>S(I```DU/>,A("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`# +M```(`@```@,```@#```"````"`0```(H``"(``(``(FU193STV__T=]N+!X7 +MB,<:M.J@W_FG(#3N@``FTSS_&I)I/XCBC$.^/CC;OVCM4*A(TKE,HLI!1_&C +MJUP)FZH7;.T@I4W:]ZS&P#4$PY<-S&AQI';N,6JW#&&>R@W!U!06AZ^3J*%1 +MZ\B4^5*`!LG:0+7A:9P[CLTOH)C&20J"*0``),[#;.\)LZQ,SL,H(QI-X![_ +MV`.%*R%HXLB0F=.3S0L!*0``'```0`03F5[_Z86:=5VXRPH3`V2MWK]1I@`` +M`!P``$`%#K];:J=]508G/RD;,&H4CG2DZ,U2$[=&>ID(``P!```,`0```@`` +M`$4``0B$10``0!$``,"H`0'`J`$"`?0!]`#T!]EL-394K&2Q5(=[Q804U7GC +M+B`C"`````$```#L(P``T"EGQ-8>(>G(I>#`5GJC5YFC-='0AKRD515QEQ*\ +MTFZ+`$!R,S$3HBAMD8'0E;BQ#=NV,(9'R%/]8[5<5[<_#1($?0],62S)5-:U +MFPAOPNX^1">HRBN;B*2B"0XPXE6[C_\(:@ETDO3O+\8[K_--IOU4J9B\VS8- +M^[)G$SMCN;B\!OY`*IGP&K2?"@C0AO7@EO%X\1FKK$Q&/\Y=?K&6QT;$\78V +M)9IBF[&Y9-@$N&K^V`F?MV.3IHBKR%N8(\%M;KF-ZV[ZX&>,N(",@`````0```)PD``"`\J8J&I(=-_3(/=1VJ$X@ +M[`59.`D770NBW]I]EA"'\DSFN]P'=8:YKJ<'XFM2XV>` +MU-;L>KD^YRSU55$B5UAZO-"$D%Y2OEI"82/U'[6M4V7S,VV]X8GZ5*=;*K:8 +MYWPT8HKDH,#QE0U)A)P*(;=Z)U(3MT;@T0@`'`$``!P!```"````10`!&(1' +M``!`$0``P*@!`<"H`0(!]`'T`00'Z6PU-E2L9+%4AWO%A!35>>,N("0(```` +M`@```/PA``#@`!<:7^DN!\&3!+1N;]:1M&I)-DZ15L9S7?PH_0<"A7MFW[<] +M*F8%#X;=6(H+)>+@-S<$S%(/'F.3U#5V?F5(0`Z\,^YN&OY\(8RV3GIQ;"50 +MM@]9?7B3,(Q_',]GK*>+%LDI[7OTH_ON-:^,IGM)U:]LJ<1JE_^W"D9*9*)! +M93*/<&E%2-'-5Q*ZZ?OQHTOO;*[_FXW1S$"1X8C8(Z:_*>F%0Y5PW;3W5-ZT +M^;`9,:P6'8[L<*2:0OK2]5Y;H!U">P6C:RSNM[]MP->*"C[#6ZFAZL''#8"7 +M$*,@]5(3MT8>,N("0(`````P```-PA``#`3.G0;KQ? +M2DJUT^C.Q%F@N^*]5/I#ZJ*`C,OINDE\Q-R_13F[<72B;@_X4**S-7'`"6=I +M^,"(B'7^/I5\!QV]NGQ?HQV^+186BB*:U]USL\S0SS<,?)QFJA4:3"",N0%\ +M(V,.>*3IR3@#0J.1RRQ&SC9#I>Q*`$Q:>8@@IJ`,)[@FS&3DV(OYQ)4T:KEC +MCP''J@2[P`1"0T^@.KW9KVOF3YET_++=`KY\I8M$%U91L1K%3Q=Z$$S(JZW. +M)%U2$[=&[N<(`&P```!L`````@```$4``&B$20``0!$``,"H`0'`J`$"`?0! +M]`!4!CEL-394K&2Q5(=[Q804U7GC+B`D(`````(```!,*0``,(,I_P1$.6-A +M8U9-*HU)^4^AN.;C4O`!_[(X/P1NDY=15/G?*70=VZ?;Y7WU4A.W1KP#"0!L +M````;`````(```!%``!HA$H``$`1``#`J`$!P*@!`@'T`?0`5`8Y;#4V5*QD +ML52'>\6$%-5YXRX@)"`````#````3"D``#"GLSH^T;C0J407CYO"$65Y-(MT +MJ"67G?]S712[F2N#EFT(Q6E@#N]A>,N +M("0(````!````1PA``$`6%09P)(#\],9NKO[P!D/I@1&;FV8`H3.3M*WO<2A +M4^H;*%?3>?S1T9$X`+.`/`VC+C6L]UK>73X!W=!&>Y/IX2W*N+!ZC5NP\BSO +M9HOKI#UQ:_0O$0JW+AKU7+Y0S(GE+3/R:(],1:(!#W>]>;.>X9 +M>^F;)HTY*9=Y#7C$-Y@A=A-??//$2?\S&8;/,+FE\@ZE`?`KLE\:;<[QP3Q= +MA.7\6$%-5YXRX@)`@````%````_"$``.`=,J)/MH@UK(,]CC0C +M&->3IWP!'@^""OT(PT_6AB'XE<;=GHDSP*DV/X#[2A3E,"-'#_X[X`8W<\%7 +MDC-W?6IZ$00<`HT7ZD]PNU(:JV4XL`IC]4&32)!4<7PEG`Y67V$QWL%FGW-% +M_&_Z%4(&9M6+-!8E'KSI$=_9O95MQ[3X+LO6W=D+L07[CS=6:43]RI/*S-?? +MYRE8G;NT"(ZGA,$ON_DMK;_VE8OJ8*7WLC(2+<82$&:TSFF$P)AM[&:\,=XM +MW+4A.W1A,["0#L````[`````(` +M``!%``#HA$T``$`1``#`J`$!P*@!`@'T`?0`U`:Y;#4V5*QDL52'>\6$%-5Y +MXRX@)"`````$````S"$``+`$6[KSE4.#BO!GTPP?;DYN:GP2)K0(%A;YIT5CX.8@M>`5Z +MH*GS\\B[R+REBS-<8V\"Q$N&QGH[3%C$,:&KF/4MC42A$6%7!)3?WF$N'2)` +MEM&_4=,'6_HT4A.W1B)="0#L````[`````(```!%``#HA$X``$`1``#`J`$! +MP*@!`@'T`?0`U`:Y;#4V5*QDL52'>\6$%-5YXRX@)"`````%````S"$``+#T +M9V7Z?S4U#KM>(>R_52OS]O7U5=-'M^$ZB]N]T@*?.+9&3$J/@9]N?X#V +M3#9'HFZG;9+0AKKT^>U0+^F)!H>/0V`R1IRV(_`8^0#[P"MVPTX3OUM\6$%-5YXRX@)`@````&```!'"$``0#4*QQM&R^&+&_,LQ0`PN7@8YYH +M7H[S_]"9`#+@75\=<.I$W4QJ4TD3=A=AXK(%VE7@RALF*."I)`PZ:1<=^K)4 +M[O;M]OQK1:U$5GH]+,NTV2!#^>-7=C)Z=D]\B&_VX"SW?4OI,R@&NH8_#$)' +M/(X3?7H%O\W_I\X&AN=#3*:@9X[?:D[]VP[X;1!3RGD8(P=MSQT-=KCVQOKX +MX'5+W_M2BU/T@]7]O\1^FQ&2D5PQ'H893S(2062(`X'+&G[-+\?WM]S$R%UU +M=>A6S)].=R^`^8J(60GC0MJ@7 +MZ2N+HQ)![W07Y0^S9+M#M`NG/M":=J5U@A=\FZ):RILMCG`]7`H,%$20>RP +MR!-.WH-R7K34X1I5[EBU5QE1R-M2_(*99P +MG7Q-PK>MV%_.8:K<9B?8\@ECD*S=_6YWN1;_A(ZXAC3>J;?8!]M"3G&;K*<< +MR3AO_E>38L!MNI2:0-7SNT6!;85);)]IRS..F5V\5IL](N?RFMI2$[=&QY4) +M`.P```#L`````@```$4``.B$40``0!$``,"H`0'`J`$"`?0!]`#4!KEL-394 +MK&2Q5(=[Q804U7GC+B`D(`````8```#,(0``L%)JL-*>A8+T87UJ3\3:^T`$ +MVZ:I2F0X3)EDC5:@%<1/8WFW;4+)"0O(7,V?@Y;D@XA#5K51M'^/')MWP]<0 +MCE_,'LTW4=64.&5]<$[2Z6::"$8L7K@6+D])!F`\G>Q@MJVWB'L7`K`ZM-W+ +M?HEL?;U3NIH),V;959#[3#]INMJ?/?/5?B$F;:`D6KU.X(.&.'.DOVZN3B7/ +MC=P?_\B?2>6S#[#`G=2$[=&S[D)`.P```#L`````@```$4``.B$ +M4@``0!$``,"H`0'`J`$"`?0!]`#4!KEL-394K&2Q5(=[Q804U7GC+B`D(``` +M``<```#,(0``L)4<\'2Q(E/EI:?EC95:LU5`ANJ79M3T3C[ +MQ68_;1;:*B%^)G;"/@/O%_7+D&#,%92;Z;`0\).W7+R;T&*)3!./BY'*KZGA +M-]M2$[=&^M\)`(P!``",`0```@```$4``8B$50``0!$``,"H`0'`J`$"`?0! +M]`%T!UEL-394K&2Q5(=[Q804U7GC+B`D"`````@```%L(0`!4$$<`/0LY$FF +M][P89&]C_18FS(4H8'*?GJOM&_H?&%1X:^C:1=$`M(PUM39AMAR;0C^Z4)4& +M9^UFG2)KZ[@L=WQ6CTXXL@IHZBEBI)N#`&:GPA]_*J6S:*R0C=^V]5JXE"Y[ +M*Y7QNC!!Q&&>`+I];E9[[=BW5D$*Y70EW +MXV.B32K+T_*,^2J!;+P04WSOQ?:NEP3E?B^WY#F\PHS)H='<0=.)!,C!U:=' +MV9DE?D6!TN[9,\C[9^VYQ`[I`BO&CGQGPN`77;<>2%*('R7@ME8[AO["5E\< +MG0RTXU!4OL@;R'H5>9F0SX>:RY(((M;A.MD/#%',KF2@3N +MEFX(WU)`:3:H4A.W1B04"@!<`0``7`$```(```!%``%8A%8``$`1``#`J`$! +MP*@!`@'T`?0!1`\6$%-5YXRX@)"`````(```!/"$``2#6 +M]CR#&)G0#?[K`)EM((]\A.*MRLC]H3?N8L""755K:0'_12%7CW%7^4='(SED +M\Z+!),_XV-"0_VZMRH53-JT_-P9;]2-`&UAG&TC;E8?1*],EZY#WW@8-$=Z5 +M>%<*1)T[M?II)XI'Z@=-M"DA:4K?-++@;?0%/2)O`R?BZU6V/HFB<:>[T4+0 +MQ9/PPCW1V?4Z,\F'0H^MT=#>'-BVO,C@Q?/FL=W>IYA7VI.,Q@.4Y,_L5?@Q +M#^D]9>#0VQZU>Z']0W<-<6F_>YOBL##GY#*.CG8C!1F.E*_L::3QGP7J&"\D +MW0AK6R^)U&*3"XS%\J!9?A9ELG4.87L1[4>%,?Z8OBV!4=>PNC@5;D)_6X(L +MXEQO6)S><`>3%\MZ\U(3MT8M.PH`?````'P````"````10``>(17``!`$0`` +MP*@!`<"H`0(!]`'T`&0&29Q\3YTTU51S$MBQ@K%D3?8N("4(`````````%PJ +M``!`(/"5CD^4%3G_>Q1Z&W:<"U$'=>NBWP78\!L/\J6AYL??X6S=@0E)]]I# +M32T<'<,!'K/E>BWLW5>FI"H@4A.W1KM&"@!L````;`````(```!%``!HA%@` +M`$`1``#`J`$!P*@!`@'T`?0`5`8YG'Q/G3355',2V+&"L61-]BX@)2`````` +M````3````#!<.'PD7,,I,!!T&][UEKA%SJ.7^8K-X*(:G'.%!C>07@D%"#-^ +M\)NK6IVH?U(3MT9H50H`;````&P````"````10``:(19``!`$0``P*@!`<"H +M`0(!]`'T`%0&.9Q\3YTTU51S$MBQ@K%D3?8N("4(`````0```$PJ```PJHH< +MF;454NN4`IQ3S4KC>E0"8:GT2C2BSFOD66G2J-34;JI;TB-2$[=& +MB&(*`&P```!L`````@```$4``&B$6@``0!$``,"H`0'`J`$"`?0!]`!4!CF< +M?$^=--54"(``'@```!T`0$`#`/W``P!```,@`X`@`,```P! +M```,@`X!``,```P!```,@`X`P`,```@!```#`P``"`(```(#```(`@```0,` +M``@"```$`P``"`,```(#```(`P```0,```@#```%`P``"`0```(````(!``` +M#B@``(@``@``^+(?S7P^;M:_U]L4`@8!0S?,2N&>GI6?U$+/JQ\Z+W%9F4(R +MH2=5KAX,?_-A2LS)03]\@I2=S\.[?KIU'S[_(3)OHZR]Q=X)W(:A_J#V&M?3.U70JL)S$P&YH!-"JRDV<$W#R7P,4_G+CD8I```<``!` +M!`ACZT]E!7.4````'```0`7-891HG,""I3O+.;C&J&+" +M$D]/)%(3MT;#;@L`7````%P````"````10``6(1<``!`$0``P*@!`<"H`0(! +M]`'T`$0&*6>J/D`_N,&-```````````I("(@`````````#P````@``!`!@`` +M``HV_$UXDHU,X00A,+-&&(U(3MT9(?@L`N`$``+@!```"````10`! +MM(1=``!`$0``P*@!`<"H`0(!]`'T`:`'A6>J/D`_N,&-```````````I("(( +M`````````9@A```@``!`!@````HV_$UXDHU,X00A,+-&&(R(``'@` +M``!T`0$`#`,```P!```,@`X`@`,```P!```,@`X!``,```P!```,@`X`P`,` +M``@!```#`P``"`(```(#```(`@```0,```@"```$`P``"`,```(#```(`P`` +M`0,```@#```%`P``"`0```(````(!```#B@``(@``@``^+(?S7P^;M:_U]L4 +M`@8!0S?,2N&>GI6?U$+/JQ\Z+W%9F4(RH2=5KAX,?_-A2LS)03]\@I2=S\.[ +M?KIU'S[_(3)OHZR]Q=X)W(:A_J#V&M?3.U70JL)S$P&Y +MH!-"JRDV<$W#R7P,4_G+CD8I```<``!`!`ACZT]E!7.4 +M````'```0`7-891HG,""I3O+.;C&J&+"$D]/)%(3MT;NH@L`4`$``%`!```" +M````10`!3(1>``!`$0``P*@!`<"H`0(!]`'T`3@''6>J/D`_N,&-B@\DEP\Z +M'Q4A("(@`````````3`B```P````+`$!``0#```,`0``#(`.`(`#```(`@`` +M`@,```@#```"````"`0```(H``"(``(``-3#%I]1R>`'`.4.)BE^^%!ST1Q? +M^=&KAD8+"(@50EX'K`L\#`YL$BSG0'R\J9,&A^XU'%9,*YXVL3D7J:>G'S[LWA^@`WI'+!N/ +MC<5#59$^2R#S7]MDANDC>E;Q*0``)$=@W4/W"^L8P)9:>8TYD?/HBXRSJW22 +MAQ0?/"?B<@DN*0``'```0`3_L[P38BJ;"Q$J@4C_5M3Q2$[=&2=`+``P!```,`0```@```$4``0B$ +M7P``0!$``,"H`0'`J`$"`?0!]`#T!]EGJCY`/[C!C8H/))2(,G+)D@.U@0WKO,2]@T3[YA+6,Y>`E/1 +MOGQAHY7W.@]8VNC'-\^IU>S,XV)#9?;5Y.=73QIC"MXDZBE13 +MG7U'M=UG[M3.`C,2"Q^]F8XOZL&CV^U14Q&U$Z&X'V30">QI<_Z%0GU!/=FP +MQ\44`'H5=VW_H*P@WN:='T3",HCWK#:,L>^O3L*7(R!7.WZ9%_?.ZDWZX-KM +MG-W.SB24@?[N<8;/QG\#<'+NZ-/=YBH7O9EE#?5(3MT8CZ0L`O``` +M`+P````"````10``N(1@``!`$0``P*@!`<"H`0(!]`'T`*0&B6>J/D`_N,&- +MB@\DEP\Z'Q4N(",@`````0```)PD``"`+S]8[8D9I:K(!&IIH)K&%ZFFSXV= +M`48#5ZD?)#"M9^13[>*5/4_64R0U5]M&IAT]B/\BY'2Z@)OOF8O +MA*=#H@V.X4.M;3HJW,MMB8/&]?>!-P\N6:.0@#XGKUDA]P1`%(3MT8#"`P`'`$``!P!```"````10`!&(1A``!`$0`` +MP*@!`<"H`0(!]`'T`00'Z6>J/D`_N,&-B@\DEP\Z'Q4N("0(`````@```/PA +M``#@@A6?]?R7A_)#,YHVQ#YZ:4S1,,"A>\3DN*@EB/(;9(1 +MHG;F_02"13(F,&W`2`\CLRR%)47O@41