Compare commits

...

40 commits

Author SHA1 Message Date
Simon Wunderlich
648753932d
Merge pull request #1046 from ecsv/batadv-for-23.05
openwrt-23.05: batman-adv: Provide teardown hook for batadv_vlan proto
2024-02-05 10:54:10 +01:00
Sven Eckelmann
5a7cac9b4e batman-adv: Provide teardown hook for batadv_vlan proto
The batadv_vlan proto doesn't need to do anything when it gets teared down.
But the scripts are still trying to call the teardown function of this
proto. This results in warnings like:

    daemon.notice netifd: batmesh1 (18940): ./batadv_vlan.sh: eval: line 37: proto_batadv_vlan_teardown: not found

Just providing a stub function avoids this log spam.

Fixes: #1044
Reported-by: Rani Hod <rani.hod@gmail.com>
Fixes: f5205d7d24 ("batman-adv: upgrade package to latest release 2014.2.0")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
2024-02-05 08:58:48 +01:00
Simon Wunderlich
c287445f37
Merge pull request #1041 from ecsv/batadv-for-23.05
openwrt-23.05: batctl: Merge bugfixes from 2024.0
2024-02-04 11:52:34 +01:00
Sven Eckelmann
75e1614d06 batctl: Merge bugfixes from 2024.0
* tcpdump: Fix missing sanity check for batman-adv header
* tcpdump: Add missing throughput header length check
* tcpdump: Fix IPv4 header length check
* tcpdump: Add missing ICMPv6 Neighbor Advert length check
* tcpdump: Add missing ICMPv6 Neighbor Solicit length check
* tcpdump: Fix ICMPv4 inner IPv4 header length check

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2024-02-02 23:03:42 +01:00
Simon Wunderlich
2a3bad8349
Merge pull request #1039 from ecsv/batadv-for-23.05
openwrt-23.05: batman-adv: compat: Fix skb_vlan_eth_hdr conflict in stable kernels
2023-12-23 18:05:49 +01:00
Sven Eckelmann
b848b61afa batman-adv: compat: Fix skb_vlan_eth_hdr conflict in stable kernels
The newest Linux stable kernel releases:

* v5.10.205
* v5.15.144
* v6.1.69

received a backported version of commit 1f5020acb33f ("net: vlan: introduce
skb_vlan_eth_hdr()"). batman-adv must therefore not provide this function
any longer for these kernel versions.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2023-12-23 15:34:41 +01:00
Rob White
81cdbd3b62 opennds: update to version 10.2.0
Maintainer: Rob White rob@blue-wave.net

Compile tested: arm_cortex-a7_neon-vfpv4, mipsel_24kc, x86-64

Run tested: arm_cortex-a7_neon-vfpv4, mipsel_24kc, x86-64; on snapshot, 23.05, 22.03

Description:
opennds (10.2.0) - This version is a minor upgrade that introduces some significant additional functionality.
In addition it includes numerous enhancements bug fixes and cosmetic fixes.

Additional functionality includes:

 * Pre-emptive Client Lists
 * Autonomous Block Lists
 * Internet hosted https FAS support for resource limited routers
 * Fair Usage Policy

Details can be found here:
https://github.com/openNDS/openNDS/releases/tag/v10.2.0

Signed-off-by: Rob White <rob@blue-wave.net>
(cherry picked from commit a5ec54aee3)
2023-11-29 05:01:25 +01:00
Moritz Warning
83ef3784a9 nodogsplash: explicit file copy
Signed-off-by: Moritz Warning <moritzwarning@web.de>
(cherry picked from commit 2a725e7cbe)
2023-10-23 13:21:02 +02:00
Moritz Warning
eb2a29e825 nodogsplash: update to version 5.0.2
Fix a buffer overflow in case the
query string is too long.

Signed-off-by: Moritz Warning <moritzwarning@web.de>
(cherry picked from commit fe1c67fb3d)
2023-10-23 13:21:02 +02:00
Josef Schlehofer
2272106e08 luci-app-bmx6: drop this because of security vulnerabilities
DependencyBot, which are using is sending us emails about these CVEs:
CVE-2012-6708
CVE-2020-23064
CVE-2019-11358

This was reported to maintainer in April 2023, but no one stepped it to fix that,
so let's drop this.

Replacement could be luci-app-bmx7.

Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
(cherry picked from commit c2124dd2ad)
2023-09-29 12:26:25 +02:00
Josef Schlehofer
828e764250 bmx6: drop package
This package is no longer maintained by us or by upstream developers.
The last version in the GitHub repository is from 2020 with no activity so far.
We are using version 0.1-alpha.

Because LuCI app is vulnerable to several CVEs and DependencyBot still
sends emails about it, let's drop it.

If anyone wants, they can use bmx7.

Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
(cherry picked from commit 9fb9d9343e)
2023-09-29 12:26:15 +02:00
Rob White
ad787a920c opennds: update to version 10.1.3
Maintainer: Rob White rob@blue-wave.net

Compile tested: arm_cortex-a7_neon-vfpv4, mipsel_24kc, x86-64

Run tested: arm_cortex-a7_neon-vfpv4, mipsel_24kc, x86-64; on snapshot, 23.05, 22.03

Description:
opennds (10.1.3)

Security Advisory. This version contains fixes for multiple potential security vulnerabilities
Credit - Stanislav Dashevskyi - standash.github.io [standash]
It also contains some minor bug fixes

  * Fix - Buffer overflow causing segfault - CVE-2023-41101 [bluewavenet]
  * Fix - Memory leaks due to passing allocated buffer into safe_asprintf() - CVE-2023-41102 [bluewavenet]
  * Fix - Remove deprecated preauth option [bluewavenet]
  * Fix - missing free in show_preauth_page if MHD does not respond [bluewavenet]
  * Fix - more safe_asprintf memory leaks [bluewavenet]
  * Fix - missing free for mark_auth [bluewavenet]
  * Fix - memory leak after starting authmon daemon [bluewavenet]
  * Fix - memory leak in encode_and_redirect_to_splashpage [bluewavenet]
  * Fix - Community themespec, voucher css and logo image [bluewavenet]
  * Fix - ThemeSpec, path to logo in page footer [bluewavenet]
  * Fix - ensure gatewayurl is urldecoded to fix broken css and images in themespec [bluewavenet]
  * Add - set default fas remote fqdn to disabled [bluewavenet]

Signed-off-by: Rob White <rob@blue-wave.net>
(cherry picked from commit 88c98c910a)
2023-08-31 18:10:50 +02:00
Simon Wunderlich
7f2a3681e3
Merge pull request #1016 from ecsv/batadv-for-23.05
openwrt-23.05: batman-adv: Fix lock assert after fragmentation change
2023-08-23 09:24:08 +02:00
Sven Eckelmann
78ac6ee418 batman-adv: Fix lock assert after fragmentation change
The automatic recalculation of the maximum allowed MTU is usually triggered
by code sections which are already rtnl lock protected by callers outside
of batman-adv. But when the fragmentation setting is changed via
batman-adv's own batadv genl family, then the rtnl lock is not yet taken.

But dev_set_mtu requires that the caller holds the rtnl lock because it
uses netdevice notifiers. And this code will then fail the check for this
lock:

  RTNL: assertion failed at net/core/dev.c (1953)

Fixes: c738e4751e ("batman-adv: Merge bugfixes from 2023.2")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
2023-08-22 18:53:57 +02:00
Simon Wunderlich
b844d67864
Merge pull request #1013 from ecsv/batadv-for-23.05
openwrt-23.05: batman-adv: Merge bugfixes from 2023.2
2023-08-18 17:06:30 +02:00
Sven Eckelmann
c738e4751e batman-adv: Merge bugfixes from 2023.2
* Broken sync while rescheduling delayed work
* compat: Use native kstrtox.h for 5.10.185
* Do not get eth header before batadv_check_management_packet
* Trigger events for auto adjusted MTU
* Don't increase MTU when set by user
* Fix TT global entry leak when client roamed back
* Fix batadv_v_ogm_aggr_send memory leak

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2023-08-18 15:58:48 +02:00
Rob White
36d862e94a mesh11sd: Release v2.0.0
Maintainer: Rob White rob@blue-wave.net
Compile tested: All
Run tested: arm_cortex-a7_neon-vfpv4, mipsel_24kc, x86-64, on 21.02, 22.03 and snapshot.

Description:
mesh11sd (2.0.0)

This release contains new functionality.

Autonomous portal mode is introduced. This simplifies the rollout of meshnodes allowing a common configuration to be used on all nodes.
Remote administration is introduced, allowing files to be copied and terminal sessions to be opened on established meshnodes, identifying remote nodes by mac address.

 * Add - Update config file [bluewavenet]
 * Add - implementation of remote copy [bluewavenet]
 * Add - implementation of remote connect [bluewavenet]
 * Add - Autonomous portal mode [bluewavenet]

-- Rob White dot@blue-wave.net Mon, 31 Jul 2023 16:59:52 +0000

Signed-off-by: Rob White <rob@blue-wave.net>
(cherry picked from commit 5beb3be9b8)
2023-08-09 12:47:56 +02:00
Rob White
e571e58785 opennds: Release v10.1.2
Maintainer: Rob White rob@blue-wave.net

Compile tested: arm_cortex-a7_neon-vfpv4, mipsel_24kc, x86-64

Run tested: arm_cortex-a7_neon-vfpv4, mipsel_24kc, x86-64; on snapshot, 23.05, 22.03

Description:
opennds (10.1.2)

Security Advisory. This version contains fixes for multiple potential security vulnerabilities
Credit - Stanislav Dashevskyi - standash.github.io [standash]
It also contains some minor bug fixes
  * Fix - Generate unique sha256 faskey if not set in config - CVE-2023-38324 [bluewavenet]
  * Fix - NULL pointer dereference if user_agent is NULL - CVE-2023-38320, CVE-2023-38322 [bluewavenet]
  * Fix - NULL pointer dereference if authdir is called with an incomplete or missing query string - CVE-2023-38313, CVE-2023-38314, CVE-2023-38315 [bluewavenet]
  * Fix - remove deprecated and non-functioning unescape callback - CVE-2023-38316 [bluewavenet]
  * Fix - prevent potential recursive dependency and detect if conflicting package is installed [bluewavenet]

Signed-off-by: Rob White <rob@blue-wave.net>
(cherry picked from commit 3eb9aa3056)
2023-08-04 17:58:23 +02:00
Nick Hainke
02cbc8f61b babeld: update to 1.13.1
Announcement:
https://alioth-lists.debian.net/pipermail/babel-users/2023-July/004125.html

Remove upstreamed patch:
- 100-local-make-local_kind-function-accessible.patch

Refresh patch:
- 600-add-ubus.patch

Signed-off-by: Nick Hainke <vincent@systemli.org>
(cherry picked from commit eb8978ebf7)
2023-07-31 08:29:47 +02:00
Nick Hainke
3f746aa089 babeld: update to 1.13
Announcement:
https://alioth-lists.debian.net/pipermail/babel-users/2023-July/004100.html

Babeld removed diversity routing [0], so we need to adjust ubus
bindings. Further. we need to add a patch that makes local_kind
accessible again: "100-local-make-local_kind-function-accessible.patch"

Refresh patches:
- 600-add-ubus.patch

[0] - a081608335

Signed-off-by: Nick Hainke <vincent@systemli.org>
(cherry picked from commit 9e13652bbf)
2023-07-31 08:29:47 +02:00
Moritz Warning
527fe47ceb nodogsplash: remove opennds from conflicts
OpenNDS lists nodogsplash a conflict as well.
This causes a circular reference that is not allowed.

Signed-off-by: Moritz Warning <moritzwarning@web.de>
2023-07-29 19:09:38 +02:00
Moritz Warning
55187d4486 nodogsplash: update to 5.0.1
Signed-off-by: Moritz Warning <moritzwarning@web.de>
(cherry picked from commit 91e07907fa)
2023-07-27 11:57:05 +02:00
Rob White
b71e865cca opennds: Release v10.1.1
Maintainer: Rob White rob@blue-wave.net

Compile tested: arm_cortex-a7_neon-vfpv4, mipsel_24kc, x86-64

Run tested: arm_cortex-a7_neon-vfpv4, mipsel_24kc, x86-64; on snapshot, 23.05, 22.03

opennds (10.1.1)
  * This version contains some minor bug fixes and documentation updates
  * Fix - send only contents of buffer, not entire buffer when serving page511 [bluewavenet]
  * Fix - Set fas_remotefqdn to gw_fqdn when overriding FAS settings [bluewavenet]
  * Fix - use absolute path for css and images in ThemeSpec [bluewavenet]
  * Fix - revert to old option names without underscores [bluewavenet]
  * Fix - FAS URL when fas_remotefqdn is not set [bluewavenet]

Signed-off-by: Rob White <rob@blue-wave.net>
(cherry picked from commit 26f5f0f812)
2023-07-19 21:35:29 +02:00
Maciej Krüger
ff834a87c0 oonf-olsrd2: add support to check if service is running
Signed-off-by: Maciej Krüger <mkg20001@gmail.com>
(cherry picked from commit 618e80a06a)
2023-07-06 14:31:47 +02:00
Josef Schlehofer
1b720129f7
Merge pull request #982 from PolynomialDivision/23-05-ci-backports
[23.05] CI - GitHub actions sync with the latest changes from OpenWrt packages repository
2023-07-05 20:03:49 +02:00
Rob White
4918a57b0e opennds: Release v10.1.0
Maintainer: Rob White rob@blue-wave.net

Compile tested: arm_cortex-a7_neon-vfpv4, mipsel_24kc, x86-64

Run tested: arm_cortex-a7_neon-vfpv4, mipsel_24kc, x86-64; on snapshot, 23.05, 22.03

opennds (10.1.0)

  This version is a major upgrade including full migration to nftables and native
  uci configuration support even for generic Linux distributions.
  It also includes a significant refactoring of inbuilt memory management,
  improving long term reliability, fixing several memory leaks, buffer overflows and several edge case crashes.

  * Add - support for included custom binauth script [bluewavenet]
  * Add - emit a useful stderr message if auth_restore fails [bluewavenet]
  * Add - procd respawn threshold, respawn timeout and respawn retry parameters [bluewavenet]
  * Add - user friendly commandline message if already running [bluewavenet]
  * Fix - Enabling of Data volume quotas [bluewavenet]
  * Fix - use get_list_from_config instead of get_option_from_config [bluewavenet]
  * Fix - compiler warning - unused variable [bluewavenet]
  * Fix - remove redundant function call ipsetconf [bluewavenet]
  * Fix - walledgarden for both nftset and ipset on OpenWrt [bluewavenet]
  * Add - more meaningful output if attempt is made to restart when already running [bluewavenet]
  * Fix - resolve gatewayfqdn after startup [bluewavenet]
  * Fix - Choose forground or background running according to commandline arguments [bluewavenet]
  * Fix - remove superfluous debug message [bluewavenet]
  * Fix - replace sleep with procd_set_param term_timeout [bluewavenet]
  * Fix - make option enabled default to enabled [bluewavenet]
  * Fix - report authmon pid instead of opennds pid from authmon [bluewavenet]
  * Fix - ensure correct pid obtained for opennds [bluewavenet]
  * Add - StartLimitIntervalSec and StartLimitBurst to systemd service script [bluewavenet]
  * Fix - refactor remote downloads [bluewavenet]
  * Fix - suppress error message on ipset test failure [bluewavenet]
  * Fix - send non-syslog debug information to stdout by default [bluewavenet]
  * Add - C function to check heartbeat watchdog [bluewavenet]
  * Fix - Update generic Linux makefile [bluewavenet]
  * Fix - remove redundant ruleset struct definition [bluewavenet]
  * Fix - potential buffer overflow issue during config stage [bluewavenet]
  * Fix - remove unnecessary calls to free() in page 404 processing [bluewavenet]
  * Fix - remove redundant code from fw_iptables [bluewavenet]
  * Add - updates to binauth_log script [bluewavenet]
  * Add - updates for service startup, systemd and procd [bluewavenet]
  * Add - refactoring of commandline processing [bluewavenet]
  * Fix - remove debugging message [bluewavenet]
  * Fix - typo in client ruleset [bluewavenet]
  * Add - Refactor to use uci config directly even for Generic Linux [bluewavenet]
  * Add - Parsing for multi item lists with spaces in items [bluewavenet]
  * Add - use common library call get_option_fom_config [bluewavenet]
  * Add - support for direct use of uci format config file - string and integer parameters [bluewavenet]
  * Fix - Remove deprecated syslog_facility config setting [bluewavenet]
  * Add - thread busy message to ndsctl [bluewavenet]
  * Add - refactor configure_log_location [bluewavenet]
  * Fix - suppress LOG_NOTICE message when getting mac of interface [bluewavenet]
  * Fix - ndsctl error message [bluewavenet]
  * Fix - get_client_interface for levels 2 and 3 [bluewavenet]
  * Add - use common library write_log function [bluewavenet]
  * Add - Refactor memory management [bluewavenet]
  * Fix - fix and refactor upload rate limiting rules [bluewavenet]
  * Fix - Change a debug message from err to info [bluewavenet]
  * Add - refine common buffer sizes [bluewavenet]
  * Add - use initialised heap memory for redirect_to_splashpage [bluewavenet]
  * Add - user message to themespec [bluewavenet]
  * Add - auth_restore support ie reauth clients after a restart by default. [bluewavenet]
  * Add - Library call to preemptively re-auth clients after a restart or crash [bluewavenet]
  * Add - BinAuth, write an authenticated clients list [bluewavenet]
  * Add - library call "check_heartbeat" [bluewavenet]
  * Fix - Tidy up redundant code [bluewavenet]
  * Fix - change warning message to debug message when iw not installed [bluewavenet]
  * Add - library call to log to syslog [bluewavenet]
  * Fix - use initialised heap memory for client list entries [bluewavenet]
  * Fix - ignore legacy ipset firewall rule [bluewavenet]
  * Fix - refactor memory management for MHD calls - use heap memory for buffers etc [bluewavenet]
  * Fix - missing free causing memory leak [bluewavenet]
  * Fix  - predefine and initialise buffer for send_redirect_temp [bluewavenet]
  * Add - support protocol "all" in firewall ruleset [bluewavenet]
  * Add - pre-allocation of initialised buffers [bluewavenet]
  * Fix  - prevent buffer overrun on removing client [bluewavenet]
  * Add - update MHD connection timeout and connection limit [bluewavenet]
  * Add - chain ndsDLR for dynamic client download rate limiting rules [bluewavenet]
  * Add - Use Internal Polling Thread / Thread Per Connection in MHD [bluewavenet]
  * Add - some new default values [bluewavenet]
  * Fix - remove some redundant code and fix some compiler warnings [bluewavenet]
  * Fix - remove redundant library command string [bluewavenet]
  * Fix - Tidy up redundant iptables code [bluewavenet]
  * Add - convert trusted client support to nftables [bluewavenet]
  * Add - refer to nftables [bluewavenet]
  * Add - move code for generating authentication mark string to initial setup [bluewavenet]
  * Add - full nftset support with ipset import where required [bluewavenet]
  * Add - nftset support library calls [bluewavenet]
  * Add - ipset_to_nftset library call [bluewavenet]
  * Add - support for nftables version of append_ruleset and nftables_compile [bluewavenet]
  * Fix - buffer overflow in page_511 generation [bluewavenet]
  * Add - more nftables migration including rate quotas [bluewavenet]
  * Fix - change GatewayInterface to lower case [bluewavenet]
  * Add - upload and download limiting client flags for future use [bluewavenet]
  * add - lib calls "pad_string" and "replace_client_rule" [bluewavenet]
  * Add - further nftables migration [bluewavenet]
  * Fix - correctly parse options from legacy conf file [bluewavenet]
  * Fix - some compiler warnings and set min iptables version [bluewavenet]
  * Add - Generic Linux configure walledgarden [bluewavenet]
  * Add - Implementation of nftsets for walledgarden [bluewavenet]
  * Add - migration to nftables, next phase. [bluewavenet]
  * Add - library function delete_client_rule [bluewavenet]
  * Fix - remove duplicate definition [bluewavenet]
  * Add - First stage migration to nftables [bluewavenet]

Signed-off-by: Rob White <rob@blue-wave.net>
(cherry picked from commit 7b1911020b)
2023-06-30 23:39:09 +02:00
Bradford Zhang
51c01c3c4b bird2: bump to version 2.13.1
Signed-off-by: Bradford Zhang <zyc@zyc.name>
(cherry picked from commit d98b9b5052)
2023-06-30 01:17:27 +02:00
Tianling Shen
ea8de65fb7 CI: update build architectures
- armvirt target has been renamed to armsr (Arm SystemReady) [1].
- armsr-armv8 has been switched to aarch64_generic architecture [2].

1. 40b02a2301
2. e0f06ddc23

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
(cherry picked from commit 04a287eea0)
2023-06-26 11:48:02 +02:00
Jeffery To
565e1cbdd9 CI: Add build test for riscv64_riscv64
Signed-off-by: Jeffery To <jeffery.to@gmail.com>
(cherry picked from commit f165789ced)
2023-06-26 11:48:02 +02:00
Jeffery To
0de5679741 CI: Sort build architectures in alphabetical order
Signed-off-by: Jeffery To <jeffery.to@gmail.com>
(cherry picked from commit 06b7d9b665)
2023-06-26 11:48:02 +02:00
Christian Marangi
ad46bbb4a6 CI: add concurrency rules to skip redundant build
Add concurrency rules to skip redundant build to skip extra build test
on force push on pull request.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
(cherry picked from commit 5aa683be13)
2023-06-26 11:48:02 +02:00
Jeffery To
30b11070ad CI: Do package run-tests only if target packages were built
Currently, the package run-test phase will fail for PRs that only
add/update host-only packages, as no target packages (*.ipk) are built.

This checks if any target packages are built before attempting the
run-tests.

Signed-off-by: Jeffery To <jeffery.to@gmail.com>
(cherry picked from commit 299ee2b1cf)
2023-06-26 11:48:02 +02:00
Jeffery To
6ed96f5be1 CI: Run "apt-get update" before installing signify-openbsd
Signed-off-by: Jeffery To <jeffery.to@gmail.com>
(cherry picked from commit 89cf0d5619)
2023-06-26 11:48:02 +02:00
Van Waholtz
68987a112f CI: Enable runtime_test for mips_24kc
Signed-off-by: Van Waholtz <brvphoenix@gmail.com>
(cherry picked from commit 28d204148a)
2023-06-26 11:48:02 +02:00
Gerard Ryan
c960329d0e cache-domains: added pre-test.sh CI step
Some packages variants have conflicting dependencies with the
base packages and the CI test will fail to install before anything
can be done by the packages to setup the system for install.

This change adds a pre-test.sh that runs before the install so things
like the default libustream variant can be swapped out as shown in the
updated cache-domains.

Signed-off-by: Gerard Ryan <G.M0N3Y.2503@gmail.com>
(cherry picked from commit 61997c86b0)
2023-06-26 11:48:02 +02:00
Jeffery To
2ae05f5841 CI: Add local feed for CI-built packages
To test each package, the CI-built target package (ipk) file is
installed, but currently the target package's dependencies are installed
from the standard opkg feeds.

There are cases when the CI-built target packages should be
installed/tested together:

* If a pull request contains several new packages that depend on each
  other, the test step will fail as the new dependencies cannot be found
  in the current packages feed.

* If a pull request upgrades a source package that builds several target
  packages that depend on each other, the test step may fail due to the
  version/ABI mismatch between a newer target package and the older
  dependencies installed from the packages feed.

This sets up a local feed for the CI-built packages so that dependencies
are also installed from the same set of packages.

Signed-off-by: Jeffery To <jeffery.to@gmail.com>
(cherry picked from commit f818fe716e)
2023-06-26 11:48:02 +02:00
Jeffery To
9934454586 CI: Add --autoremove, ignore removal errors
836b4e1c734f9705bfd8db0da0c04214c2647932 added
--force-removal-of-dependent-packages but it does not do what the commit
message says it does.

When package A depends on package B (package B is a dependency of
package A; package A is a dependent of package B), trying to remove
package B while package A is installed will result in an error. Adding
--force-removal-of-dependent-packages in this case will cause the
removal of package B and package A (package B's dependent).

But in the case of the CI testing step, it is package A that is being
installed and removed. Removing package A with
--force-removal-of-dependent-packages will not cause package B (package
A's dependency) to be removed.

This adds --autoremove to actually remove the package's dependencies.

This also ignores any errors returned by opkg remove as --autoremove can
sometimes falsely return an error[1].

[1]: https://github.com/openwrt/openwrt/issues/12241

Fixes: 836b4e1c734f ("github-ci: add --force-removal-of-dependent-packages")
Signed-off-by: Jeffery To <jeffery.to@gmail.com>
(cherry picked from commit 53a53b8ee3)
2023-06-26 11:48:02 +02:00
Tianling Shen
fa213a15a7 CI: update build architectures
Removed arc_archs - archs38 was marked as source-only [1].
Renamed powerpc_8540 to powerpc_8548 [2].

1. https://git.openwrt.org/?p=openwrt/openwrt.git;a=commit;h=c01641bcc7236d2e2de3ea65444b0cf2898df351
2. https://git.openwrt.org/?p=openwrt/openwrt.git;a=commit;h=2cad88b99fdae9766de84e6c1cb56f111eb53748

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
(cherry picked from commit 7928f7d399)
2023-06-26 11:48:02 +02:00
Paul Spooren
0348b1b2e5 ci: only comment AUTORELEASE deprecation if exists
If it doesn't exists, don't confuse the contributors.

Signed-off-by: Paul Spooren <mail@aparcar.org>
(cherry picked from commit b3b01af314)
2023-06-26 11:47:57 +02:00
Nick Hainke
6bbcdd7f1f olsrd: update to 2023-06-12
Update to latest version.

Remove upstreamed patch:
- 100-rename-avl-to-olsrd_avl.patch

Signed-off-by: Nick Hainke <vincent@systemli.org>
(cherry picked from commit aab3b64e09)
2023-06-14 10:06:51 +02:00
74 changed files with 1251 additions and 6548 deletions

View file

@ -0,0 +1,91 @@
name: Check autorelease deprecation
on:
pull_request_target:
types: [opened, synchronize, converted_to_draft, ready_for_review, edited]
jobs:
build:
name: Check autorelease deprecation
runs-on: ubuntu-latest
strategy:
fail-fast: false
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Determine branch name
run: |
BRANCH="${GITHUB_BASE_REF#refs/heads/}"
echo "Building for $BRANCH"
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
- name: Determine changed packages
run: |
RET=0
# only detect packages with changes
PKG_ROOTS=$(find . -name Makefile | \
grep -v ".*/src/Makefile" | \
sed -e 's@./\(.*\)/Makefile@\1/@')
CHANGES=$(git diff --diff-filter=d --name-only origin/$BRANCH...)
for ROOT in $PKG_ROOTS; do
for CHANGE in $CHANGES; do
if [[ "$CHANGE" == "$ROOT"* ]]; then
if grep -q '$(AUTORELEASE)' "$ROOT/Makefile"; then
CONTAINS_AUTORELEASE+="$ROOT"
fi
break
fi
done
done
if [ -n "$CONTAINS_AUTORELEASE" ]; then
RET=1
cat > "$GITHUB_WORKSPACE/pr_comment.md" << EOF
Please do no longer set *PKG_RELEASE* to *AUTORELEASE* as the
feature is deprecated. Please use an integer instead. Below is a
list of affected packages including correct *PKG_RELEASE*:
EOF
fi
for ROOT in $CONTAINS_AUTORELEASE; do
echo -n " - ${ROOT}Makefile: PKG_RELEASE:=" >> "$GITHUB_WORKSPACE/pr_comment.md"
last_bump="$(git log --pretty=format:'%h %s' "$ROOT" |
grep --max-count=1 -e ': [uU]pdate to ' -e ': [bB]ump to ' |
cut -f 1 -d ' ')"
if [ -n "$last_bump" ]; then
echo -n $(($(git rev-list --count "$last_bump..HEAD" "$ROOT") + 2)) >> "$GITHUB_WORKSPACE/pr_comment.md"
else
echo -n $(($(git rev-list --count HEAD "$ROOT") + 2)) >> "$GITHUB_WORKSPACE/pr_comment.md"
fi
echo >> "$GITHUB_WORKSPACE/pr_comment.md"
done
exit $RET
- name: Find Comment
uses: peter-evans/find-comment@v2
if: ${{ failure() }}
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
- name: Create or update comment
uses: peter-evans/create-or-update-comment@v2
if: ${{ failure() }}
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body-file: 'pr_comment.md'
edit-mode: replace

View file

@ -2,7 +2,12 @@
# not enabling `errtrace` and `pipefail` since those are bash specific
set -o errexit # failing commands causes script to fail
set -o nounset # undefined variables causes script to fail
set -o nounset # undefined variables causes script to fail
echo "src/gz packages_ci file:///ci" >> /etc/opkg/distfeeds.conf
FINGERPRINT="$(usign -F -p /ci/packages_ci.pub)"
cp /ci/packages_ci.pub "/etc/opkg/keys/$FINGERPRINT"
mkdir -p /var/lock/
@ -11,7 +16,7 @@ opkg update
[ -n "${CI_HELPER:=''}" ] || CI_HELPER="/ci/.github/workflows/ci_helpers.sh"
for PKG in /ci/*.ipk; do
tar -xzOf "$PKG" ./control.tar.gz | tar xzf - ./control
tar -xzOf "$PKG" ./control.tar.gz | tar xzf - ./control
# package name including variant
PKG_NAME=$(sed -ne 's#^Package: \(.*\)$#\1#p' ./control)
# package version without release
@ -21,10 +26,24 @@ for PKG in /ci/*.ipk; do
echo "Testing package $PKG_NAME in version $PKG_VERSION from $PKG_SOURCE"
opkg install "$PKG"
export PKG_NAME PKG_VERSION CI_HELPER
PRE_TEST_SCRIPT=$(find /ci/ -name "$PKG_SOURCE" -type d)/pre-test.sh
if [ -f "$PRE_TEST_SCRIPT" ]; then
echo "Use package specific pre-test.sh"
if sh "$PRE_TEST_SCRIPT" "$PKG_NAME" "$PKG_VERSION"; then
echo "Pre-test successful"
else
echo "Pre-test failed"
exit 1
fi
else
echo "No pre-test.sh script available"
fi
opkg install "$PKG"
TEST_SCRIPT=$(find /ci/ -name "$PKG_SOURCE" -type d)/test.sh
if [ -f "$TEST_SCRIPT" ]; then
@ -39,5 +58,5 @@ for PKG in /ci/*.ipk; do
echo "No test.sh script available"
fi
opkg remove "$PKG_NAME" --force-removal-of-dependent-packages --force-remove
opkg remove "$PKG_NAME" --force-removal-of-dependent-packages --force-remove --autoremove || true
done

View file

@ -3,6 +3,10 @@ name: Test Build
on:
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
build:
name: Test ${{ matrix.arch }}
@ -11,37 +15,37 @@ jobs:
fail-fast: false
matrix:
include:
- arch: arc_archs
target: archs38-generic
runtime_test: false
- arch: aarch64_generic
target: armsr-armv8
runtime_test: true
- arch: arm_cortex-a15_neon-vfpv4
target: armsr-armv7
runtime_test: true
- arch: arm_cortex-a9_vfpv3-d16
target: mvebu-cortexa9
runtime_test: false
- arch: i386_pentium-mmx
target: x86-geode
runtime_test: true
- arch: mips_24kc
target: ath79-generic
runtime_test: false
runtime_test: true
- arch: powerpc_464fp
target: apm821xx-nand
runtime_test: false
- arch: powerpc_8540
- arch: powerpc_8548
target: mpc85xx-p1010
runtime_test: false
- arch: aarch64_cortex-a53
target: mvebu-cortexa53
runtime_test: true
- arch: arm_cortex-a15_neon-vfpv4
target: armvirt-32
runtime_test: true
- arch: i386_pentium-mmx
target: x86-geode
runtime_test: true
- arch: riscv64_riscv64
target: sifiveu-generic
runtime_test: false
- arch: x86_64
target: x86-64
@ -82,20 +86,36 @@ jobs:
echo "Building $PACKAGES"
echo "PACKAGES=$PACKAGES" >> $GITHUB_ENV
- name: Generate build keys
run: |
sudo apt-get update
sudo apt-get install -y signify-openbsd
signify-openbsd -G -n -c 'DO NOT USE - OpenWrt packages feed CI' -p packages_ci.pub -s packages_ci.sec
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "KEY_BUILD<<$EOF" >> $GITHUB_ENV
cat packages_ci.sec >> $GITHUB_ENV
echo "$EOF" >> $GITHUB_ENV
- name: Build
uses: openwrt/gh-action-sdk@v5
env:
ARCH: ${{ matrix.arch }}-${{ env.BRANCH }}
FEEDNAME: packages_ci
INDEX: 1
KEY_BUILD: ${{ env.KEY_BUILD }}
- name: Move created packages to project dir
run: cp bin/packages/${{ matrix.arch }}/packages_ci/*.ipk . || true
run: cp bin/packages/${{ matrix.arch }}/packages_ci/* . || true
- name: Store packages
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.arch}}-packages
path: "*.ipk"
name: ${{env.ARCHIVE_NAME}}-packages
path: |
Packages
Packages.*
*.ipk
PKG-INFO
- name: Store logs
uses: actions/upload-artifact@v3
@ -106,19 +126,32 @@ jobs:
- name: Remove logs
run: sudo rm -rf logs/ || true
- name: Register QEMU
if: ${{ matrix.runtime_test }}
- name: Check if any packages were built
run: |
sudo docker run --rm --privileged aptman/qus -s -- -p
if [ -n "$(find . -maxdepth 1 -type f -name '*.ipk' -print -quit)" ]; then
echo "Found *.ipk files"
HAVE_IPKS=true
else
echo "No *.ipk files found"
HAVE_IPKS=false
fi
echo "HAVE_IPKS=$HAVE_IPKS" >> $GITHUB_ENV
- name: Register QEMU
if: ${{ matrix.runtime_test && fromJSON(env.HAVE_IPKS) }}
run: |
sudo apt-get update
sudo apt-get install -y qemu-user-static binfmt-support
sudo update-binfmts --import
- name: Build Docker container
if: ${{ matrix.runtime_test }}
if: ${{ matrix.runtime_test && fromJSON(env.HAVE_IPKS) }}
run: |
docker build -t test-container --build-arg ARCH .github/workflows/
env:
ARCH: ${{ matrix.arch }}-${{ env.BRANCH }}
- name: Test via Docker container
if: ${{ matrix.runtime_test }}
if: ${{ matrix.runtime_test && fromJSON(env.HAVE_IPKS) }}
run: |
docker run --rm -v $GITHUB_WORKSPACE:/ci test-container

View file

@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=babeld
PKG_VERSION:=1.12.2
PKG_VERSION:=1.13.1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.irif.fr/~jch/software/files/
PKG_HASH:=1db22b6193070ea2450a1ab51196fd72f58a1329f780cb0388e2e4b2e7768cbb
PKG_HASH:=15f24d26da0ccfc073abcdef0309f281e4684f2aa71126f826572c4c845e8dd9
PKG_MAINTAINER:=Gabriel Kerneis <gabriel@kerneis.info>, \
Baptiste Jonglez <openwrt-pkg@bitsofnetworks.org>, \

View file

@ -9,7 +9,7 @@
struct timeval now;
unsigned char myid[8];
@@ -521,6 +523,9 @@ main(int argc, char **argv)
@@ -505,6 +507,9 @@ main(int argc, char **argv)
}
}
@ -19,7 +19,7 @@
init_signals();
rc = resize_receive_buffer(1500);
if(rc < 0)
@@ -616,6 +621,8 @@ main(int argc, char **argv)
@@ -597,6 +602,8 @@ main(int argc, char **argv)
FD_SET(local_sockets[i].fd, &readfds);
maxfd = MAX(maxfd, local_sockets[i].fd);
}
@ -28,7 +28,7 @@
rc = select(maxfd + 1, &readfds, NULL, NULL, &tv);
if(rc < 0) {
if(errno != EINTR) {
@@ -684,6 +691,9 @@ main(int argc, char **argv)
@@ -665,6 +672,9 @@ main(int argc, char **argv)
i++;
}
@ -57,7 +57,7 @@
static struct filter *input_filters = NULL;
static struct filter *output_filters = NULL;
static struct filter *redistribute_filters = NULL;
@@ -1036,7 +1038,8 @@ parse_option(int c, gnc_t gnc, void *clo
@@ -1024,7 +1026,8 @@ parse_option(int c, gnc_t gnc, void *clo
strcmp(token, "daemonise") == 0 ||
strcmp(token, "skip-kernel-setup") == 0 ||
strcmp(token, "ipv6-subtrees") == 0 ||
@ -67,7 +67,7 @@
int b;
c = getbool(c, &b, gnc, closure);
if(c < -1)
@@ -1054,6 +1057,8 @@ parse_option(int c, gnc_t gnc, void *clo
@@ -1042,6 +1045,8 @@ parse_option(int c, gnc_t gnc, void *clo
has_ipv6_subtrees = b;
else if(strcmp(token, "reflect-kernel-metric") == 0)
reflect_kernel_metric = b;

View file

@ -245,23 +245,6 @@ static int babeld_ubus_get_xroutes(struct ubus_context *ctx_local,
static void babeld_add_route_buf(struct babel_route *route,
struct blob_buf *b) {
void *prefix;
char channels[100];
if (route->channels_len == 0) {
channels[0] = '\0';
} else {
int i, j = 0;
snprintf(channels, sizeof(channels), " chan (");
j = strlen(channels);
for (i = 0; i < route->channels_len; i++) {
if (i > 0)
channels[j++] = ',';
snprintf(channels + j, sizeof(channels) - j, "%u",
(unsigned)route->channels[i]);
j = strlen(channels);
}
snprintf(channels + j, sizeof(channels) - j, ")");
}
prefix = blobmsg_open_table(
b, format_prefix(route->src->prefix, route->src->plen));
@ -274,7 +257,6 @@ static void babeld_add_route_buf(struct babel_route *route,
blobmsg_add_u32(b, "refmetric", route->refmetric);
blobmsg_add_string(b, "id", format_eui64(route->src->id));
blobmsg_add_u32(b, "seqno", (uint32_t)route->seqno);
blobmsg_add_string(b, "channels", channels);
blobmsg_add_u32(b, "age", (int)(now.tv_sec - route->time));
blobmsg_add_string(b, "via", format_address(route->neigh->address));
if (memcmp(route->nexthop, route->neigh->address, 16) != 0)
@ -357,7 +339,6 @@ static void babeld_add_neighbour_buf(struct neighbour *neigh,
blobmsg_add_u32(b, "rxcost", neighbour_rxcost(neigh));
blobmsg_add_u32(b, "txcost", neigh->txcost);
blobmsg_add_string(b, "rtt", format_thousands(neigh->rtt));
blobmsg_add_u32(b, "channel", neigh->ifp->channel);
blobmsg_add_u8(b, "if_up", if_up(neigh->ifp));
blobmsg_close_table(b, neighbour);
}

View file

@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=batctl
PKG_VERSION:=2023.1
PKG_RELEASE:=1
PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)

View file

@ -0,0 +1,26 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Sat, 27 Jan 2024 13:48:59 +0100
Subject: batctl: tcpdump: Fix missing sanity check for batman-adv header
parse_eth_hdr() is assuming that every ETH_P_BATMAN ethernet packet has a
valid, minimal batman-adv header (packet_type, version, ttl) attached. But
it doesn't actually check if the received buffer has enough bytes to access
the two bytes packet_type + version. So it is possible that it tries to
read outside of the received data.
Fixes: 3bdfc388e74b ("implement simple tcpdump, first only batman packets")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/7ae3bdb59a7501197e12d3a7ab0d9924341e9ca8
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -1068,6 +1068,9 @@ static void parse_eth_hdr(unsigned char
dump_vlan(packet_buff, buff_len, read_opt, time_printed);
break;
case ETH_P_BATMAN:
+ /* check for batman-adv packet_type + version */
+ LEN_CHECK(buff_len, sizeof(*eth_hdr) + 2, "BAT HEADER")
+
batman_ogm_packet = (struct batadv_ogm_packet *)(packet_buff + ETH_HLEN);
if ((read_opt & COMPAT_FILTER) &&

View file

@ -0,0 +1,34 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Sat, 27 Jan 2024 13:49:00 +0100
Subject: batctl: tcpdump: Add missing throughput header length check
dump_batman_icmp() is only doing a length check for the original ICMP
packet length. But the throughput packet (which is also handled by this
function) is accessed without doing an additional length check. So it is
possible that it tries to read outside of the received data.
Fixes: f109b3473f86 ("batctl: introduce throughput meter support")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/189b66496309bc1a54b4821292da2428de8ceb1c
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -863,7 +863,6 @@ static void dump_batman_icmp(unsigned ch
LEN_CHECK((size_t)buff_len - sizeof(struct ether_header), sizeof(struct batadv_icmp_packet), "BAT ICMP");
icmp_packet = (struct batadv_icmp_packet *)(packet_buff + sizeof(struct ether_header));
- tp = (struct batadv_icmp_tp_packet *)icmp_packet;
if (!time_printed)
print_time();
@@ -894,6 +893,10 @@ static void dump_batman_icmp(unsigned ch
(size_t)buff_len - sizeof(struct ether_header));
break;
case BATADV_TP:
+ LEN_CHECK((size_t)buff_len - sizeof(struct ether_header), sizeof(*tp), "BAT TP");
+
+ tp = (struct batadv_icmp_tp_packet *)icmp_packet;
+
printf("%s: ICMP TP type %s (%hhu), id %hhu, seq %u, ttl %2d, v %d, length %zu\n",
name, tp->subtype == BATADV_TP_MSG ? "MSG" :
tp->subtype == BATADV_TP_ACK ? "ACK" : "N/A",

View file

@ -0,0 +1,27 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Sat, 27 Jan 2024 13:49:01 +0100
Subject: batctl: tcpdump: Fix IPv4 header length check
dump_ip() is directly accessing the header in the header length check and
assumes that ihl can be trusted. But when when ihl is set to something less
than 5 then it would not even be possible to store the basic IPv4 header in
it. But dump_ip would have still accepted it because it didn't check if
there are at least enough bytes available to read the basic IPv4 header. So
it is possible that it tries to read outside of the received data.
Fixes: 75d68356f3fa ("[batctl] tcpdump - add basic IPv4 support")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/ddb254bd51aa43d216159f3be9c575369b041d35
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -646,7 +646,9 @@ static void dump_ip(unsigned char *packe
struct icmphdr *icmphdr;
iphdr = (struct iphdr *)packet_buff;
+ LEN_CHECK((size_t)buff_len, sizeof(*iphdr), ip_string);
LEN_CHECK((size_t)buff_len, (size_t)(iphdr->ihl * 4), ip_string);
+ LEN_CHECK((size_t)(iphdr->ihl * 4), sizeof(*iphdr), ip_string);
if (!time_printed)
print_time();

View file

@ -0,0 +1,25 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Sat, 27 Jan 2024 13:49:02 +0100
Subject: batctl: tcpdump: Add missing ICMPv6 Neighbor Advert length check
dump_ipv6() is doing a length check for the original ICMPv6 header length.
But the neighbor advertisement (which is also handled by this function) is
accessed without doing an additional length check. So it is possible that
it tries to read outside of the received data.
Fixes: 35b37756f4a3 ("add IPv6 support to tcpdump parser")
Cc: Marco Dalla Torre <marco.dallato@gmail.com>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/da75747d435ca8a32a74895655a1d5bff8b7709b
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -611,6 +611,8 @@ static void dump_ipv6(unsigned char *pac
nd_nas_target, buff_len);
break;
case ND_NEIGHBOR_ADVERT:
+ LEN_CHECK((size_t)buff_len - (size_t)(sizeof(struct ip6_hdr)),
+ sizeof(*nd_advert), "ICMPv6 Neighbor Advertisement");
nd_advert = (struct nd_neighbor_advert *)icmphdr;
inet_ntop(AF_INET6, &(nd_advert->nd_na_target),
nd_nas_target, 40);

View file

@ -0,0 +1,25 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Sat, 27 Jan 2024 13:49:03 +0100
Subject: batctl: tcpdump: Add missing ICMPv6 Neighbor Solicit length check
dump_ipv6() is doing a length check for the original ICMPv6 header length.
But the neighbor solicitation (which is also handled by this function) is
accessed without doing an additional length check. So it is possible that
it tries to read outside of the received data.
Fixes: 35b37756f4a3 ("add IPv6 support to tcpdump parser")
Cc: Marco Dalla Torre <marco.dallato@gmail.com>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/83025933cb502192d22edc89de3c57103968c4ed
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -604,6 +604,8 @@ static void dump_ipv6(unsigned char *pac
(size_t)buff_len - sizeof(struct icmp6_hdr));
break;
case ND_NEIGHBOR_SOLICIT:
+ LEN_CHECK((size_t)buff_len - (size_t)(sizeof(struct ip6_hdr)),
+ sizeof(*nd_neigh_sol), "ICMPv6 Neighbor Solicitation");
nd_neigh_sol = (struct nd_neighbor_solicit *)icmphdr;
inet_ntop(AF_INET6, &(nd_neigh_sol->nd_ns_target),
nd_nas_target, 40);

View file

@ -0,0 +1,41 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Sat, 27 Jan 2024 13:49:04 +0100
Subject: batctl: tcpdump: Fix ICMPv4 inner IPv4 header length check
dump_ip() is doing a length check for the inner (inside ICMP) IPv4 header
length. But it is just assuming that the inner ICMPv4 header has ihl set to
5 - without actually checking for this. The more complex IPv4 header length
check for the outer IPv4 header is missing before it tries to access the
UDP header using the inner ihl IPv4 header length information. So it is
possible that it tries to read outside of the received data.
Fixes: 75d68356f3fa ("[batctl] tcpdump - add basic IPv4 support")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/fb7a51466bf46a4914a32edd8e1be6ba0733cd49
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -682,12 +682,20 @@ static void dump_ip(unsigned char *packe
(size_t)buff_len - (iphdr->ihl * 4));
break;
case ICMP_DEST_UNREACH:
- LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct icmphdr),
- sizeof(struct iphdr) + 8, "ICMP DEST_UNREACH");
-
switch (icmphdr->code) {
case ICMP_PORT_UNREACH:
+ LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct icmphdr),
+ sizeof(struct iphdr), "ICMP DEST_UNREACH");
+
+ /* validate inner IP header information */
tmp_iphdr = (struct iphdr *)(((char *)icmphdr) + sizeof(struct icmphdr));
+ LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct icmphdr),
+ (size_t)(tmp_iphdr->ihl * 4), "ICMP DEST_UNREACH");
+ LEN_CHECK((size_t)(tmp_iphdr->ihl * 4), sizeof(*iphdr), "ICMP DEST_UNREACH");
+
+ LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct icmphdr) - (tmp_iphdr->ihl * 4),
+ sizeof(*tmp_udphdr), "ICMP DEST_UNREACH");
+
tmp_udphdr = (struct udphdr *)(((char *)tmp_iphdr) + (tmp_iphdr->ihl * 4));
printf("%s: ICMP ", ipdst);

View file

@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=batman-adv
PKG_VERSION:=2023.1
PKG_RELEASE:=2
PKG_RELEASE:=6
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)

View file

@ -22,4 +22,8 @@ proto_batadv_vlan_setup() {
proto_send_update "$config"
}
proto_batadv_vlan_teardown() {
local cfg="$1"
}
add_protocol batadv_vlan

View file

@ -0,0 +1,48 @@
From: Vladislav Efanov <VEfanov@ispras.ru>
Date: Fri, 26 May 2023 19:16:32 +0300
Subject: batman-adv: Broken sync while rescheduling delayed work
Syzkaller got a lot of crashes like:
KASAN: use-after-free Write in *_timers*
All of these crashes point to the same memory area:
The buggy address belongs to the object at ffff88801f870000
which belongs to the cache kmalloc-8k of size 8192
The buggy address is located 5320 bytes inside of
8192-byte region [ffff88801f870000, ffff88801f872000)
This area belongs to :
batadv_priv->batadv_priv_dat->delayed_work->timer_list
The reason for these issues is the lack of synchronization. Delayed
work (batadv_dat_purge) schedules new timer/work while the device
is being deleted. As the result new timer/delayed work is set after
cancel_delayed_work_sync() was called. So after the device is freed
the timer list contains pointer to already freed memory.
Found by Linux Verification Center (linuxtesting.org) with syzkaller.
Fixes: f6badf9eb582 ("batman-adv: Distributed ARP Table - implement local storage")
Signed-off-by: Vladislav Efanov <VEfanov@ispras.ru>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/177ba85fb2d4ca2ecd30ca16803560e80e916fac
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -101,7 +101,6 @@ static void batadv_dat_purge(struct work
*/
static void batadv_dat_start_timer(struct batadv_priv *bat_priv)
{
- INIT_DELAYED_WORK(&bat_priv->dat.work, batadv_dat_purge);
queue_delayed_work(batadv_event_workqueue, &bat_priv->dat.work,
msecs_to_jiffies(10000));
}
@@ -819,6 +818,7 @@ int batadv_dat_init(struct batadv_priv *
if (!bat_priv->dat.hash)
return -ENOMEM;
+ INIT_DELAYED_WORK(&bat_priv->dat.work, batadv_dat_purge);
batadv_dat_start_timer(bat_priv);
batadv_tvlv_handler_register(bat_priv, batadv_dat_tvlv_ogm_handler_v1,

View file

@ -0,0 +1,29 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Tue, 11 Jul 2023 11:46:30 +0200
Subject: batman-adv: compat: Use native kstrtox.h for 5.10.185
Upstream stable commit 6e2e551e39fd ("kernel.h: split out kstrtox() and
simple_strtox() to a separate header") backported the support for
linux/kstrtox.h. Unfortunately, the compat support via linux/kernel.h was
dropped and thus references to kstrtou64 caused build errors
batman-adv/net/batman-adv/gateway_common.c: In function batadv_parse_throughput:
batman-adv/net/batman-adv/gateway_common.c:55:15: error: implicit declaration of function kstrtou64 [-Werror=implicit-function-declaration]
55 | ret = kstrtou64(buff, 10, &lthroughput);
| ^~~~~~~~~
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/8924adbdf993cd0521f9d0024b43e3b23af5114f
--- a/compat-include/linux/kstrtox.h
+++ b/compat-include/linux/kstrtox.h
@@ -11,7 +11,8 @@
#define _NET_BATMAN_ADV_COMPAT_LINUX_KSTRTOX_H_
#include <linux/version.h>
-#if LINUX_VERSION_IS_GEQ(5, 14, 0)
+#if (LINUX_VERSION_IS_GEQ(5, 10, 185) && LINUX_VERSION_IS_LESS(5, 11, 0)) || \
+ LINUX_VERSION_IS_GEQ(5, 14, 0)
#include_next <linux/kstrtox.h>
#else
#include <linux/kernel.h>

View file

@ -0,0 +1,111 @@
From: Remi Pommarel <repk@triplefau.lt>
Date: Fri, 28 Jul 2023 15:38:50 +0200
Subject: batman-adv: Do not get eth header before batadv_check_management_packet
If received skb in batadv_v_elp_packet_recv or batadv_v_ogm_packet_recv
is either cloned or non linearized then its data buffer will be
reallocated by batadv_check_management_packet when skb_cow or
skb_linearize get called. Thus geting ethernet header address inside
skb data buffer before batadv_check_management_packet had any chance to
reallocate it could lead to the following kernel panic:
Unable to handle kernel paging request at virtual address ffffff8020ab069a
Mem abort info:
ESR = 0x96000007
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x07: level 3 translation fault
Data abort info:
ISV = 0, ISS = 0x00000007
CM = 0, WnR = 0
swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000040f45000
[ffffff8020ab069a] pgd=180000007fffa003, p4d=180000007fffa003, pud=180000007fffa003, pmd=180000007fefe003, pte=0068000020ab0706
Internal error: Oops: 96000007 [#1] SMP
Modules linked in: ahci_mvebu libahci_platform libahci dvb_usb_af9035 dvb_usb_dib0700 dib0070 dib7000m dibx000_common ath11k_pci ath10k_pci ath10k_core mwl8k_new nf_nat_sip nf_conntrack_sip xhci_plat_hcd xhci_hcd nf_nat_pptp nf_conntrack_pptp at24 sbsa_gwdt
CPU: 1 PID: 16 Comm: ksoftirqd/1 Not tainted 5.15.42-00066-g3242268d425c-dirty #550
Hardware name: A8k (DT)
pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : batadv_is_my_mac+0x60/0xc0
lr : batadv_v_ogm_packet_recv+0x98/0x5d0
sp : ffffff8000183820
x29: ffffff8000183820 x28: 0000000000000001 x27: ffffff8014f9af00
x26: 0000000000000000 x25: 0000000000000543 x24: 0000000000000003
x23: ffffff8020ab0580 x22: 0000000000000110 x21: ffffff80168ae880
x20: 0000000000000000 x19: ffffff800b561000 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000 x15: 00dc098924ae0032
x14: 0f0405433e0054b0 x13: ffffffff00000080 x12: 0000004000000001
x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
x8 : 0000000000000000 x7 : ffffffc076dae000 x6 : ffffff8000183700
x5 : ffffffc00955e698 x4 : ffffff80168ae000 x3 : ffffff80059cf000
x2 : ffffff800b561000 x1 : ffffff8020ab0696 x0 : ffffff80168ae880
Call trace:
batadv_is_my_mac+0x60/0xc0
batadv_v_ogm_packet_recv+0x98/0x5d0
batadv_batman_skb_recv+0x1b8/0x244
__netif_receive_skb_core.isra.0+0x440/0xc74
__netif_receive_skb_one_core+0x14/0x20
netif_receive_skb+0x68/0x140
br_pass_frame_up+0x70/0x80
br_handle_frame_finish+0x108/0x284
br_handle_frame+0x190/0x250
__netif_receive_skb_core.isra.0+0x240/0xc74
__netif_receive_skb_list_core+0x6c/0x90
netif_receive_skb_list_internal+0x1f4/0x310
napi_complete_done+0x64/0x1d0
gro_cell_poll+0x7c/0xa0
__napi_poll+0x34/0x174
net_rx_action+0xf8/0x2a0
_stext+0x12c/0x2ac
run_ksoftirqd+0x4c/0x7c
smpboot_thread_fn+0x120/0x210
kthread+0x140/0x150
ret_from_fork+0x10/0x20
Code: f9403844 eb03009f 54fffee1 f94
Thus ethernet header address should only be fetched after
batadv_check_management_packet has been called.
Fixes: 632835348e65 ("batman-adv: OGMv2 - add basic infrastructure")
Signed-off-by: Remi Pommarel <repk@triplefau.lt>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/670971ac7e9a47ee952848e0ea9128180e8fb991
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -505,7 +505,7 @@ int batadv_v_elp_packet_recv(struct sk_b
struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct batadv_elp_packet *elp_packet;
struct batadv_hard_iface *primary_if;
- struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
+ struct ethhdr *ethhdr;
bool res;
int ret = NET_RX_DROP;
@@ -513,6 +513,7 @@ int batadv_v_elp_packet_recv(struct sk_b
if (!res)
goto free_skb;
+ ethhdr = eth_hdr(skb);
if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
goto free_skb;
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -985,7 +985,7 @@ int batadv_v_ogm_packet_recv(struct sk_b
{
struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
struct batadv_ogm2_packet *ogm_packet;
- struct ethhdr *ethhdr = eth_hdr(skb);
+ struct ethhdr *ethhdr;
int ogm_offset;
u8 *packet_pos;
int ret = NET_RX_DROP;
@@ -999,6 +999,7 @@ int batadv_v_ogm_packet_recv(struct sk_b
if (!batadv_check_management_packet(skb, if_incoming, BATADV_OGM2_HLEN))
goto free_skb;
+ ethhdr = eth_hdr(skb);
if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
goto free_skb;

View file

@ -0,0 +1,28 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Wed, 19 Jul 2023 10:15:05 +0200
Subject: batman-adv: Trigger events for auto adjusted MTU
If an interface changes the MTU, it is expected that an NETDEV_PRECHANGEMTU
and NETDEV_CHANGEMTU notification events is triggered. This worked fine for
.ndo_change_mtu based changes because core networking code took care of it.
But for auto-adjustments after hard-interfaces changes, these events were
simply missing.
Due to this problem, non-batman-adv components weren't aware of MTU changes
and thus couldn't perform their own tasks correctly.
Fixes: 8009e9f7ac4f ("set bat0 MTU according to the MTUs of the hard interfaces")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/27c4d7c1c7fa39d71ea6ccf1c23bcb4773243800
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -629,7 +629,7 @@ out:
*/
void batadv_update_min_mtu(struct net_device *soft_iface)
{
- soft_iface->mtu = batadv_hardif_min_mtu(soft_iface);
+ dev_set_mtu(soft_iface, batadv_hardif_min_mtu(soft_iface));
/* Check if the local translate table should be cleaned up to match a
* new (and smaller) MTU.

View file

@ -0,0 +1,71 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Wed, 19 Jul 2023 10:15:06 +0200
Subject: batman-adv: Don't increase MTU when set by user
If the user set an MTU value, it usually means that there are special
requirements for the MTU. But if an interface gots activated, the MTU was
always recalculated and then the user set value was overwritten.
The only reason why this user set value has to be overwritten, is when the
MTU has to be decreased because batman-adv is not able to transfer packets
with the user specified size.
Fixes: 88861ea9acb7 ("[batman-adv] replacing if up/down timer with kernel notifications")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/2745af592150b758ee96abf9329dd5f42cf22c25
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -629,7 +629,19 @@ out:
*/
void batadv_update_min_mtu(struct net_device *soft_iface)
{
- dev_set_mtu(soft_iface, batadv_hardif_min_mtu(soft_iface));
+ struct batadv_priv *bat_priv = netdev_priv(soft_iface);
+ int limit_mtu;
+ int mtu;
+
+ mtu = batadv_hardif_min_mtu(soft_iface);
+
+ if (bat_priv->mtu_set_by_user)
+ limit_mtu = bat_priv->mtu_set_by_user;
+ else
+ limit_mtu = ETH_DATA_LEN;
+
+ mtu = min(mtu, limit_mtu);
+ dev_set_mtu(soft_iface, mtu);
/* Check if the local translate table should be cleaned up to match a
* new (and smaller) MTU.
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -153,11 +153,14 @@ static int batadv_interface_set_mac_addr
static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu)
{
+ struct batadv_priv *bat_priv = netdev_priv(dev);
+
/* check ranges */
if (new_mtu < 68 || new_mtu > batadv_hardif_min_mtu(dev))
return -EINVAL;
dev->mtu = new_mtu;
+ bat_priv->mtu_set_by_user = new_mtu;
return 0;
}
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1547,6 +1547,12 @@ struct batadv_priv {
struct net_device *soft_iface;
/**
+ * @mtu_set_by_user: MTU was set once by user
+ * protected by rtnl_lock
+ */
+ int mtu_set_by_user;
+
+ /**
* @bat_counters: mesh internal traffic statistic counters (see
* batadv_counters)
*/

View file

@ -0,0 +1,76 @@
From: Remi Pommarel <repk@triplefau.lt>
Date: Fri, 4 Aug 2023 11:39:36 +0200
Subject: batman-adv: Fix TT global entry leak when client roamed back
When a client roamed back to a node before it got time to destroy the
pending local entry (i.e. within the same originator interval) the old
global one is directly removed from hash table and left as such.
But because this entry had an extra reference taken at lookup (i.e using
batadv_tt_global_hash_find) there is no way its memory will be reclaimed
at any time causing the following memory leak:
unreferenced object 0xffff0000073c8000 (size 18560):
comm "softirq", pid 0, jiffies 4294907738 (age 228.644s)
hex dump (first 32 bytes):
06 31 ac 12 c7 7a 05 00 01 00 00 00 00 00 00 00 .1...z..........
2c ad be 08 00 80 ff ff 6c b6 be 08 00 80 ff ff ,.......l.......
backtrace:
[<00000000ee6e0ffa>] kmem_cache_alloc+0x1b4/0x300
[<000000000ff2fdbc>] batadv_tt_global_add+0x700/0xe20
[<00000000443897c7>] _batadv_tt_update_changes+0x21c/0x790
[<000000005dd90463>] batadv_tt_update_changes+0x3c/0x110
[<00000000a2d7fc57>] batadv_tt_tvlv_unicast_handler_v1+0xafc/0xe10
[<0000000011793f2a>] batadv_tvlv_containers_process+0x168/0x2b0
[<00000000b7cbe2ef>] batadv_recv_unicast_tvlv+0xec/0x1f4
[<0000000042aef1d8>] batadv_batman_skb_recv+0x25c/0x3a0
[<00000000bbd8b0a2>] __netif_receive_skb_core.isra.0+0x7a8/0xe90
[<000000004033d428>] __netif_receive_skb_one_core+0x64/0x74
[<000000000f39a009>] __netif_receive_skb+0x48/0xe0
[<00000000f2cd8888>] process_backlog+0x174/0x344
[<00000000507d6564>] __napi_poll+0x58/0x1f4
[<00000000b64ef9eb>] net_rx_action+0x504/0x590
[<00000000056fa5e4>] _stext+0x1b8/0x418
[<00000000878879d6>] run_ksoftirqd+0x74/0xa4
unreferenced object 0xffff00000bae1a80 (size 56):
comm "softirq", pid 0, jiffies 4294910888 (age 216.092s)
hex dump (first 32 bytes):
00 78 b1 0b 00 00 ff ff 0d 50 00 00 00 00 00 00 .x.......P......
00 00 00 00 00 00 00 00 50 c8 3c 07 00 00 ff ff ........P.<.....
backtrace:
[<00000000ee6e0ffa>] kmem_cache_alloc+0x1b4/0x300
[<00000000d9aaa49e>] batadv_tt_global_add+0x53c/0xe20
[<00000000443897c7>] _batadv_tt_update_changes+0x21c/0x790
[<000000005dd90463>] batadv_tt_update_changes+0x3c/0x110
[<00000000a2d7fc57>] batadv_tt_tvlv_unicast_handler_v1+0xafc/0xe10
[<0000000011793f2a>] batadv_tvlv_containers_process+0x168/0x2b0
[<00000000b7cbe2ef>] batadv_recv_unicast_tvlv+0xec/0x1f4
[<0000000042aef1d8>] batadv_batman_skb_recv+0x25c/0x3a0
[<00000000bbd8b0a2>] __netif_receive_skb_core.isra.0+0x7a8/0xe90
[<000000004033d428>] __netif_receive_skb_one_core+0x64/0x74
[<000000000f39a009>] __netif_receive_skb+0x48/0xe0
[<00000000f2cd8888>] process_backlog+0x174/0x344
[<00000000507d6564>] __napi_poll+0x58/0x1f4
[<00000000b64ef9eb>] net_rx_action+0x504/0x590
[<00000000056fa5e4>] _stext+0x1b8/0x418
[<00000000878879d6>] run_ksoftirqd+0x74/0xa4
Releasing the extra reference from batadv_tt_global_hash_find even at
roam back when batadv_tt_global_free is called fixes this memory leak.
Cc: stable@vger.kernel.org
Fixes: 2443ba383c7d ("batman-adv: roaming handling mechanism redesign")
Signed-off-by: Remi Pommarel <repk@triplefau.lt>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/26fce59c70729e07034de966ac5fd2d5c1f2d597
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -774,7 +774,6 @@ check_roaming:
if (roamed_back) {
batadv_tt_global_free(bat_priv, tt_global,
"Roaming canceled");
- tt_global = NULL;
} else {
/* The global entry has to be marked as ROAMING and
* has to be kept for consistency purpose

View file

@ -0,0 +1,47 @@
From: Remi Pommarel <repk@triplefau.lt>
Date: Wed, 9 Aug 2023 17:29:13 +0200
Subject: batman-adv: Fix batadv_v_ogm_aggr_send memory leak
When batadv_v_ogm_aggr_send is called for an inactive interface, the skb
is silently dropped by batadv_v_ogm_send_to_if() but never freed causing
the following memory leak:
unreferenced object 0xffff00000c164800 (size 512):
comm "kworker/u8:1", pid 2648, jiffies 4295122303 (age 97.656s)
hex dump (first 32 bytes):
00 80 af 09 00 00 ff ff e1 09 00 00 75 01 60 83 ............u.`.
1f 00 00 00 b8 00 00 00 15 00 05 00 da e3 d3 64 ...............d
backtrace:
[<0000000007ad20f6>] __kmalloc_track_caller+0x1a8/0x310
[<00000000d1029e55>] kmalloc_reserve.constprop.0+0x70/0x13c
[<000000008b9d4183>] __alloc_skb+0xec/0x1fc
[<00000000c7af5051>] __netdev_alloc_skb+0x48/0x23c
[<00000000642ee5f5>] batadv_v_ogm_aggr_send+0x50/0x36c
[<0000000088660bd7>] batadv_v_ogm_aggr_work+0x24/0x40
[<0000000042fc2606>] process_one_work+0x3b0/0x610
[<000000002f2a0b1c>] worker_thread+0xa0/0x690
[<0000000059fae5d4>] kthread+0x1fc/0x210
[<000000000c587d3a>] ret_from_fork+0x10/0x20
Free the skb in that case to fix this leak.
Cc: stable@vger.kernel.org
Fixes: 632835348e65 ("batman-adv: OGMv2 - add basic infrastructure")
Signed-off-by: Remi Pommarel <repk@triplefau.lt>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/9024db261180f73fc687a9ecc7e79e3b0ccf50dc
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -123,8 +123,10 @@ static void batadv_v_ogm_send_to_if(stru
{
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
- if (hard_iface->if_status != BATADV_IF_ACTIVE)
+ if (hard_iface->if_status != BATADV_IF_ACTIVE) {
+ kfree_skb(skb);
return;
+ }
batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_TX);
batadv_add_counter(bat_priv, BATADV_CNT_MGMT_TX_BYTES,

View file

@ -0,0 +1,35 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Mon, 21 Aug 2023 21:48:48 +0200
Subject: batman-adv: Hold rtnl lock during MTU update via netlink
The automatic recalculation of the maximum allowed MTU is usually triggered
by code sections which are already rtnl lock protected by callers outside
of batman-adv. But when the fragmentation setting is changed via
batman-adv's own batadv genl family, then the rtnl lock is not yet taken.
But dev_set_mtu requires that the caller holds the rtnl lock because it
uses netdevice notifiers. And this code will then fail the check for this
lock:
RTNL: assertion failed at net/core/dev.c (1953)
Cc: stable@vger.kernel.org
Reported-by: syzbot+f8812454d9b3ac00d282@syzkaller.appspotmail.com
Fixes: 27c4d7c1c7fa ("batman-adv: Trigger events for auto adjusted MTU")
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/aeb35331aa9a17f9affd84c1a5b020aeb4a976f4
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -495,7 +495,10 @@ static int batadv_netlink_set_mesh(struc
attr = info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED];
atomic_set(&bat_priv->fragmentation, !!nla_get_u8(attr));
+
+ rtnl_lock();
batadv_update_min_mtu(bat_priv->soft_iface);
+ rtnl_unlock();
}
if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN]) {

View file

@ -28,7 +28,10 @@ static inline u32 batadv_get_random_u32_below(u32 ep_ro)
#endif /* LINUX_VERSION_IS_LESS(6, 2, 0) */
#if LINUX_VERSION_IS_LESS(6, 4, 0)
#if LINUX_VERSION_IS_LESS(6, 4, 0) && \
!(LINUX_VERSION_IS_GEQ(5, 10, 205) && LINUX_VERSION_IS_LESS(5, 11, 0)) && \
!(LINUX_VERSION_IS_GEQ(5, 15, 144) && LINUX_VERSION_IS_LESS(5, 16, 0)) && \
!(LINUX_VERSION_IS_GEQ(6, 1, 69) && LINUX_VERSION_IS_LESS(6, 2, 0))
#include <linux/if_vlan.h>

View file

@ -7,12 +7,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bird2
PKG_VERSION:=2.13
PKG_VERSION:=2.13.1
PKG_RELEASE:=1
PKG_SOURCE:=bird-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=ftp://bird.network.cz/pub/bird
PKG_HASH:=8d895e3e311880e9efb888b4386cbec2f7e18bfb8334e8d4c8ca7c4341092638
PKG_HASH:=97bb8d57be9bc5083e2b566416d27e314162856a12ca7c77e202e467d20d4080
PKG_MAINTAINER:=Toke Høiland-Jørgensen <toke@toke.dk>
PKG_LICENSE:=GPL-2.0-or-later

View file

@ -1,150 +0,0 @@
# Copyright (C) 2011 Fundacio Privada per a la Xarxa Oberta, Lliure i Neutral guifi.net
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# The full GNU General Public License is included in this distribution in
# the file called "COPYING".
#
# Contibutors:
# Axel Neumann, Simó Albert i Beltran, Pau Escrich
#
include $(TOPDIR)/rules.mk
PKG_NAME:=bmx6
PKG_VERSION:=0.1-alpha
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/bmx-routing/bmx6.git
PKG_SOURCE_DATE:=2020-06-08
PKG_SOURCE_VERSION:=65cb0d542f16a4b4689f5ad2542c9f24215a6616
PKG_MIRROR_HASH:=45501cfe9f82e08e8082147f90b94ba5b6bd11771a9140412bfbf5523a796177
PKG_MAINTAINER:=Axel Neumann <neumann@cgws.de>
PKG_LICENSE:=GPL-2.0-or-later
include $(INCLUDE_DIR)/package.mk
TARGET_CFLAGS += $(FPIC)
MAKE_ARGS += \
EXTRA_CFLAGS="$(TARGET_CFLAGS) -I. -I$(STAGING_DIR)/usr/include -DNO_DEBUG_ALL -DNO_DEBUG_DUMP" \
EXTRA_LDFLAGS="-L$(STAGING_DIR)/usr/lib " \
GIT_REV="$(PKG_REV)" \
CC="$(TARGET_CC)" \
INSTALL_DIR="$(PKG_INSTALL_DIR)" \
STRIP="/bin/false" \
build_all
define Package/bmx6/Default
SECTION:=net
CATEGORY:=Network
SUBMENU:=Routing and Redirection
TITLE:=BMX6 layer 3 routing daemon
URL:=https://bmx6.net/projects/bmx6
DEPENDS:=+kmod-ip6-tunnel +kmod-iptunnel6 +kmod-tun
endef
define Package/bmx6/description
BMX6 layer 3 routing daemon supporting IPv4, IPv6, and IPv4 over IPv6
endef
define Package/bmx6
$(call Package/bmx6/Default)
MENU:=1
endef
define Package/bmx6-uci-config
$(call Package/bmx6/Default)
DEPENDS:=bmx6 +libuci
TITLE:=configuration plugin based on uci (recommended!)
endef
define Package/bmx6-json
$(call Package/bmx6/Default)
DEPENDS:=bmx6 +libjson-c
TITLE:=json plugin based on json-c
endef
define Package/bmx6-sms
$(call Package/bmx6/Default)
DEPENDS:=bmx6
TITLE:=sms plugin
endef
#define Package/bmx6-quagga
# $(call Package/bmx6/Default)
# DEPENDS:=bmx6 +qmp-quagga @BROKEN
# TITLE:=bmx6 quagga plugin to redistribute/export routes (needs manet/bmx6 patched quagga 0.99.21)
#endef
define Package/bmx6-table
$(call Package/bmx6/Default)
DEPENDS:=bmx6
TITLE:=bmx6 table plugin to automatic announce routing-table routes via ip6ip tunnels
endef
define Build/Configure
mkdir -p $(PKG_INSTALL_DIR)
endef
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_ARGS)
endef
define Package/bmx6/install
$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/config $(1)/etc/init.d
$(INSTALL_BIN) $(PKG_BUILD_DIR)/bmx6 $(1)/usr/sbin/bmx6
endef
define Package/bmx6-uci-config/conffiles
/etc/config/bmx6
endef
define Package/bmx6-uci-config/install
$(INSTALL_DIR) $(1)/usr/lib $(1)/etc/config $(1)/etc/init.d
$(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/bmx6_uci_config/bmx6_config.so $(1)/usr/lib/bmx6_config.so
$(INSTALL_BIN) ./files/etc/init.d/bmx6 $(1)/etc/init.d/bmx6
$(INSTALL_DATA) ./files/etc/config/bmx6 $(1)/etc/config/bmx6
endef
define Package/bmx6-json/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/bmx6_json/bmx6_json.so $(1)/usr/lib/bmx6_json.so
endef
define Package/bmx6-sms/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/bmx6_sms/bmx6_sms.so $(1)/usr/lib/bmx6_sms.so
endef
define Package/bmx6-table/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/bmx6_table/bmx6_table.so $(1)/usr/lib/bmx6_table.so
endef
#define Package/bmx6-quagga/install
# $(INSTALL_DIR) $(1)/usr/lib
# $(INSTALL_BIN) $(PKG_BUILD_DIR)/lib/bmx6_quagga/bmx6_quagga.so $(1)/usr/lib/bmx6_quagga.so
#endef
$(eval $(call BuildPackage,bmx6))
$(eval $(call BuildPackage,bmx6-uci-config))
$(eval $(call BuildPackage,bmx6-json))
$(eval $(call BuildPackage,bmx6-sms))
#$(eval $(call BuildPackage,bmx6-quagga))
$(eval $(call BuildPackage,bmx6-table))

View file

@ -1,82 +0,0 @@
# for more information:
# http://bmx6.net/projects/bmx6/wiki
# options execute: bmx6 --help
config 'bmx6' 'general'
# option 'runtimeDir' '/var/run/bmx6'
# option 'tun4Address' '10.202.0.116/32'
# option 'tun4Address' '10.254.10.0/32'
# option 'tun6Address' '2012:0:0:1000::1/64'
#config 'ipVersion' 'ipVersion'
# option 'ipVersion' '6' # default is 4
# option 'throwRules' '0'
#config 'plugin'
# option 'plugin' 'bmx6_config.so'
#config 'plugin'
# option 'plugin' 'bmx6_json.so'
#config 'plugin'
# option 'plugin' 'bmx6_sms.so'
config 'dev' 'mesh_1'
option 'dev' 'eth0.12'
config 'dev' 'mesh_2'
option 'dev' 'ath0.12'
#config 'hna' 'my_global_prefix'
# option 'hna' '2012:0:0:74:0:0:0:0/64'
#config 'tunOut'
# option 'tunOut' 'ip6'
# option 'network' '2012::/16'
# option 'exportDistance' '0'
#config 'tunOut'
# option 'tunOut' 'ip4'
# option 'network' '10.254.0.0/16'
# option 'exportDistance' '0' # requires quagga plugin !
# option 'minPrefixLen' '27'
#config 'plugin'
# option 'plugin' 'bmx6_quagga.so'
#config 'redistribute'
# option 'redistribute' 'ospf6'
# option 'network' '10.0.0.0/8'
# option 'minPrefixLen' '10'
# option 'bandwidth' '10000000'
# option 'ospf6' '1'
# option 'aggregatePrefixLen' '16'
#config 'redistribute'
# option 'redistribute' 'bgp'
# option 'network' '0.0.0.0/0'
# option 'minPrefixLen' '0'
# option 'maxPrefixLen' '24'
# option 'bandwidth' '10000000'
# option 'bgp' '1'
# option 'aggregatePrefixLen' '8'

View file

@ -1,37 +0,0 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2017 Gui Iribarren <gui@altermundi.net>
# Copyright (C) 2011 Fundacio Privada per a la Xarxa Oberta, Lliure i Neutral guifi.net
#
# This is free software, licensed under the GNU General Public License v3.
START=91
STOP=91
USE_PROCD=1
NAME=bmx6
BIN=/usr/sbin/bmx6
CONF=/etc/config/bmx6
PID=/var/run/bmx6/pid
DEBUG=0
start_service() {
procd_open_instance "$NAME"
procd_set_param command "$BIN" -f "$CONF" -d "$DEBUG"
### Respawn automatically when process dies, after waiting respawn_timeout seconds
### If respawn_retry consecutives respawns die before respawn_threshold seconds (i.e. they crash)
### it will stop trying and leave it dead.
procd_set_param respawn ${respawn_threshold:-60} ${respawn_timeout:-3} ${respawn_retry:-5}
procd_set_param limits core="20000" # Equivalent to 'ulimit -c 20000'
procd_close_instance
}
reload_service() {
"$BIN" -c configReload
}
service_triggers()
{
procd_add_reload_trigger "bmx6" # Call reload_service() when /etc/config/bmx6 changed and reload_config is run
}

View file

@ -1,40 +0,0 @@
--- a/schedule.c
+++ b/schedule.c
@@ -356,7 +356,9 @@ loop4Event:
continue;
}
+#ifdef SIOCGSTAMP
ioctl(pb.i.iif->rx_mcast_sock, SIOCGSTAMP, &(pb.i.tv_stamp)) ;
+#endif
rx_packet( &pb );
@@ -381,8 +383,10 @@ loop4Event:
continue;
}
-
+
+#ifdef SIOCGSTAMP
ioctl(pb.i.iif->rx_fullbrc_sock, SIOCGSTAMP, &(pb.i.tv_stamp)) ;
+#endif
rx_packet( &pb );
@@ -432,10 +436,15 @@ loop4Event:
}
}
#endif
+#ifdef SIOCGSTAMP
if ( tv_stamp == NULL )
ioctl( pb.i.iif->unicast_sock, SIOCGSTAMP, &(pb.i.tv_stamp) );
else
timercpy( tv_stamp, &(pb.i.tv_stamp) );
+#else
+ if (tv_stamp)
+ timercpy( tv_stamp, &(pb.i.tv_stamp) );
+#endif
rx_packet( &pb );

View file

@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View file

@ -1,99 +0,0 @@
# Copyright (C) 2011 Pau Escrich <pau@dabax.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# The full GNU General Public License is included in this distribution in
# the file called "COPYING".
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-bmx6
PKG_RELEASE:=6
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
PKG_LICENSE:=GPL-2.0+
include $(INCLUDE_DIR)/package.mk
define Package/luci-app-bmx6
SECTION:=luci
CATEGORY:=LuCI
SUBMENU:=3. Applications
TITLE:= bmx6 configuration, status and visualization module
DEPENDS:=+luci-lib-json +luci-base +luci-lib-httpclient +bmx6 +luci-lib-jquery-1-4 +luci-lib-dracula
MAINTAINER:= Pau Escrich <p4u@dabax.net>
endef
define Package/luci-lib-jquery-1-4
SECTION:=luci
CATEGORY:=LuCI
TITLE:=LuCI - Lua Configuration Interface
MAINTAINER:=Gui Iribarren <gui@altermundi.net>
SUBMENU:=6. Libraries
TITLE:=jQuery 1.4 javascript library
endef
define Package/luci-lib-dracula
SECTION:=luci
CATEGORY:=LuCI
TITLE:=LuCI - Lua Configuration Interface
MAINTAINER:=Pau Escrich <p4u@dabax.net>
SUBMENU:=6. Libraries
TITLE:=dracula graph javascript library
endef
define Package/luci-app-bmx6/description
bmx6 web application (status and configuration) for LuCi web interface
endef
define Package/luci-lib-jquery-1-4/description
minified javascript jQuery 1.4 library
endef
define Package/luci-lib-dracula-graph/description
minified dracula javascript graph library
endef
define Package/luci-app-bmx6/conffiles
/etc/config/luci-bmx6
endef
define Build/Prepare
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/luci-app-bmx6/install
$(CP) ./bmx6/* $(1)/
chmod 755 $(1)/www/cgi-bin/bmx6-info
endef
define Package/luci-lib-jquery-1-4/install
$(INSTALL_DIR) $(1)/www/luci-static/resources/jquery/
$(CP) ./jquery/* $(1)/www/luci-static/resources/jquery/
endef
define Package/luci-lib-dracula/install
$(INSTALL_DIR) $(1)/www/luci-static/resources/dracula
$(CP) ./dracula/* $(1)/www/luci-static/resources/dracula/
endef
$(eval $(call BuildPackage,luci-app-bmx6))
$(eval $(call BuildPackage,luci-lib-jquery-1-4))
$(eval $(call BuildPackage,luci-lib-dracula))

View file

@ -1,7 +0,0 @@
config 'bmx6' 'luci'
option ignore '0'
option place 'admin network BMX6'
#option place 'qmp Mesh'
option position '3'
#option json 'http://127.0.0.1/cgi-bin/bmx6-info?'
option json 'exec:/www/cgi-bin/bmx6-info -s'

View file

@ -1,277 +0,0 @@
--[[
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
Contributors Jo-Philipp Wich <xm@subsignal.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
--]]
local bmx6json = require("luci.model.bmx6json")
module("luci.controller.bmx6", package.seeall)
function index()
local place = {}
local ucim = require "luci.model.uci"
local uci = ucim.cursor()
-- checking if ignore is on
if uci:get("luci-bmx6","luci","ignore") == "1" then
return nil
end
-- getting value from uci database
local uci_place = uci:get("luci-bmx6","luci","place")
-- default values
if uci_place == nil then
place = {"bmx6"}
else
local util = require "luci.util"
place = util.split(uci_place," ")
end
-- getting position of menu
local uci_position = uci:get("luci-bmx6","luci","position")
---------------------------
-- Starting with the pages
---------------------------
--- status (default)
entry(place,call("action_nodes_j"),place[#place],tonumber(uci_position))
table.insert(place,"Status")
entry(place,call("action_status_j"),"Status",0)
table.remove(place)
--- nodes
table.insert(place,"Nodes")
entry(place,call("action_nodes_j"),"Nodes",1)
table.remove(place)
--- links
table.insert(place,"Links")
entry(place,call("action_links"),"Links",2).leaf = true
table.remove(place)
-- Tunnels
table.insert(place,"Tunnels")
entry(place,call("action_tunnels_j"), "Tunnels", 3).leaf = true
table.remove(place)
--- Chat
table.insert(place,"Chat")
entry(place,call("action_chat"),"Chat",5)
table.remove(place)
--- Graph
table.insert(place,"Graph")
entry(place, template("bmx6/graph"), "Graph",4)
table.remove(place)
--- Topology (hidden)
table.insert(place,"topology")
entry(place, call("action_topology"), nil)
table.remove(place)
--- configuration (CBI)
table.insert(place,"Configuration")
entry(place, cbi("bmx6/main"), "Configuration",6).dependent=false
table.insert(place,"General")
entry(place, cbi("bmx6/main"), "General",1)
table.remove(place)
table.insert(place,"Advanced")
entry(place, cbi("bmx6/advanced"), "Advanced",5)
table.remove(place)
table.insert(place,"Interfaces")
entry(place, cbi("bmx6/interfaces"), "Interfaces",2)
table.remove(place)
table.insert(place,"Tunnels")
entry(place, cbi("bmx6/tunnels"), "Tunnels",3)
table.remove(place)
table.insert(place,"Plugins")
entry(place, cbi("bmx6/plugins"), "Plugins",6)
table.remove(place)
table.insert(place,"HNAv6")
entry(place, cbi("bmx6/hna"), "HNAv6",4)
table.remove(place)
table.remove(place)
end
function action_status_j()
luci.template.render("bmx6/status_j", {})
end
function action_nodes_j()
local http = require "luci.http"
local link_non_js = "/cgi-bin/luci" .. http.getenv("PATH_INFO") .. '/nodes_nojs'
luci.template.render("bmx6/nodes_j", {link_non_js=link_non_js})
end
function action_gateways_j()
luci.template.render("bmx6/gateways_j", {})
end
function action_tunnels_j()
luci.template.render("bmx6/tunnels_j", {})
end
function action_links(host)
local links = bmx6json.get("links", host)
local devlinks = {}
local _,l
if links ~= nil then
links = links.links
for _,l in ipairs(links) do
devlinks[l.viaDev] = {}
end
for _,l in ipairs(links) do
l.name = luci.util.split(l.name,'.')[1]
table.insert(devlinks[l.viaDev],l)
end
end
luci.template.render("bmx6/links", {links=devlinks})
end
function action_topology()
local originators = bmx6json.get("originators/all")
local o,i,l,i2
local first = true
local topology = '[ '
local cache = '/tmp/bmx6-topology.json'
local offset = 60
local cachefd = io.open(cache,r)
local update = false
if cachefd ~= nil then
local lastupdate = tonumber(cachefd:read("*line")) or 0
if os.time() >= lastupdate + offset then
update = true
else
topology = cachefd:read("*all")
end
cachefd:close()
end
if cachefd == nil or update then
for i,o in ipairs(originators) do
local links = bmx6json.get("links",o.primaryIp)
if links then
if first then
first = false
else
topology = topology .. ', '
end
topology = topology .. '{ "name": "%s", "links": [' %o.name
local first2 = true
for i2,l in ipairs(links.links) do
if first2 then
first2 = false
else
topology = topology .. ', '
end
name = l.name or l.llocalIp or "unknown"
topology = topology .. '{ "name": "%s", "rxRate": %s, "txRate": %s }'
%{ name, l.rxRate, l.txRate }
end
topology = topology .. ']}'
end
end
topology = topology .. ' ]'
-- Upgrading the content of the cache file
cachefd = io.open(cache,'w+')
cachefd:write(os.time()..'\n')
cachefd:write(topology)
cachefd:close()
end
luci.http.prepare_content("application/json")
luci.http.write(topology)
end
function action_chat()
local sms_dir = "/var/run/bmx6/sms"
local rcvd_dir = sms_dir .. "/rcvdSms"
local send_file = sms_dir .. "/sendSms/chat"
local sms_list = bmx6json.get("rcvdSms")
local sender = ""
local sms_file = ""
local chat = {}
local to_send = nil
local sent = ""
local fd = nil
if luci.sys.call("test -d " .. sms_dir) ~= 0 then
luci.template.render("bmx6/error", {txt="sms plugin disabled or some problem with directory " .. sms_dir})
return nil
end
sms_list = luci.util.split(luci.util.exec("ls "..rcvd_dir.."/*:chat"))
for _,sms_path in ipairs(sms_list) do
if #sms_path > #rcvd_dir then
sms_file = luci.util.split(sms_path,'/')
sms_file = sms_file[#sms_file]
sender = luci.util.split(sms_file,':')[1]
-- Trying to clean the name
if string.find(sender,".") ~= nil then
sender = luci.util.split(sender,".")[1]
end
fd = io.open(sms_path,"r")
chat[sender] = fd:read()
fd:close()
end
end
to_send = luci.http.formvalue("toSend")
if to_send ~= nil and #to_send > 1 then
fd = io.open(send_file,"w")
fd:write(to_send)
fd:close()
sent = to_send
else
sent = luci.util.exec("cat "..send_file)
end
luci.template.render("bmx6/chat", {chat=chat,sent=sent})
end

View file

@ -1,224 +0,0 @@
--[[
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
Contributors Jo-Philipp Wich <xm@subsignal.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
--]]
local ltn12 = require("luci.ltn12")
local json = require("luci.json")
local util = require("luci.util")
local uci = require("luci.model.uci")
local sys = require("luci.sys")
local template = require("luci.template")
local http = require("luci.http")
local string = require("string")
local table = require("table")
local nixio = require("nixio")
local nixiofs = require("nixio.fs")
local ipairs = ipairs
module "luci.model.bmx6json"
-- Returns a LUA object from bmx6 JSON daemon
function get(field, host)
local url
if host ~= nil then
if host:match(":") then
url = 'http://[%s]/cgi-bin/bmx6-info?' % host
else
url = 'http://%s/cgi-bin/bmx6-info?' % host
end
else
url = uci.cursor():get("luci-bmx6","luci","json")
end
if url == nil then
print_error("bmx6 json url not configured, cannot fetch bmx6 daemon data",true)
return nil
end
local json_url = util.split(url,":")
local raw = ""
if json_url[1] == "http" then
raw,err = wget(url..field,1000)
sys.exec("")
else
if json_url[1] == "exec" then
raw = sys.exec(json_url[2]..' '..field)
else
print_error("bmx6 json url not recognized, cannot fetch bmx6 daemon data. Use http: or exec:",true)
return nil
end
end
local data = nil
if raw and raw:len() > 10 then
local decoder = json.Decoder()
ltn12.pump.all(ltn12.source.string(raw), decoder:sink())
data = decoder:get()
-- else
-- print_error("Cannot get data from bmx6 daemon",true)
-- return nil
end
return data
end
function print_error(txt,popup)
util.perror(txt)
sys.call("logger -t bmx6json " .. txt)
if popup then
http.write('<script type="text/javascript">alert("Some error detected, please check it: '..txt..'");</script>')
else
http.write("<h1>Dammit! some error detected</h1>")
http.write("bmx6-luci: " .. txt)
http.write('<p><FORM><INPUT TYPE="BUTTON" VALUE="Go Back" ONCLICK="history.go(-1)"></FORM></p>')
end
end
function text2html(txt)
txt = string.gsub(txt,"<","{")
txt = string.gsub(txt,">","}")
txt = util.striptags(txt)
return txt
end
function wget(url, timeout)
local rfd, wfd = nixio.pipe()
local pid = nixio.fork()
if pid == 0 then
rfd:close()
nixio.dup(wfd, nixio.stdout)
-- candidates for wget, try first ones with SSL support
local candidates = {{"/usr/bin/wget-ssl",1},{"/usr/bin/wget",0},{"/bin/wget",0}}
local _, bin
for _, bin in ipairs(candidates) do
if nixiofs.access(bin[1], "x") then
if bin[2] == 0 then
nixio.exec(bin[1], "-q", "-O", "-", url)
else
nixio.exec(bin[1], "--no-check-certificate", "-q", "-O", "-", url)
end
end
end
return
else
wfd:close()
rfd:setblocking(false)
local buffer = { }
local err1, err2
while true do
local ready = nixio.poll({{ fd = rfd, events = nixio.poll_flags("in") }}, timeout)
if not ready then
nixio.kill(pid, nixio.const.SIGKILL)
err1 = "timeout"
break
end
local rv = rfd:read(4096)
if rv then
-- eof
if #rv == 0 then
break
end
buffer[#buffer+1] = rv
else
-- error
if nixio.errno() ~= nixio.const.EAGAIN and
nixio.errno() ~= nixio.const.EWOULDBLOCK then
err1 = "error"
err2 = nixio.errno()
end
end
end
nixio.waitpid(pid, "nohang")
if not err1 then
return table.concat(buffer)
else
return nil, err1, err2
end
end
end
function getOptions(name)
-- Getting json and Checking if bmx6-json is avaiable
local options = get("options")
if options == nil or options.OPTIONS == nil then
m.message = "bmx6-json plugin is not running or some mistake in luci-bmx6 configuration, check /etc/config/luci-bmx6"
return nil
else
options = options.OPTIONS
end
-- Filtering by the option name
local i,_
local namedopt = nil
if name ~= nil then
for _,i in ipairs(options) do
if i.name == name and i.CHILD_OPTIONS ~= nil then
namedopt = i.CHILD_OPTIONS
break
end
end
end
return namedopt
end
-- Rturns a help string formated to be used in HTML scope
function getHtmlHelp(opt)
if opt == nil then return nil end
local help = ""
if opt.help ~= nil then
help = text2html(opt.help)
end
if opt.syntax ~= nil then
help = help .. "<br/><b>Syntax: </b>" .. text2html(opt.syntax)
end
return help
end
function testandreload()
local test = sys.call('bmx6 -c --test > /tmp/bmx6-luci.err.tmp')
if test ~= 0 then
return sys.exec("cat /tmp/bmx6-luci.err.tmp")
end
local err = sys.call('bmx6 -c --configReload > /tmp/bmx6-luci.err.tmp')
if err ~= 0 then
return sys.exec("cat /tmp/bmx6-luci.err.tmp")
end
return nil
end

View file

@ -1,75 +0,0 @@
--[[
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
--]]
m = Map("bmx6", "bmx6")
local bmx6json = require("luci.model.bmx6json")
local util = require("luci.util")
local http = require("luci.http")
local sys = require("luci.sys")
local options = bmx6json.get("options")
if options == nil or options.OPTIONS == nil then
m.message = "bmx6-json plugin is not running or some mistake in luci-bmx6 configuration, check /etc/config/luci-bmx6"
options = {}
else
options = options.OPTIONS
end
local general = m:section(NamedSection,"general","bmx6")
general.addremove = true
local name = ""
local help = ""
local value = nil
local _,o
for _,o in ipairs(options) do
if o.name ~= nil and o.CHILD_OPTIONS == nil and o.configurable == 1 then
help = ""
name = o.name
if o.help ~= nil then
help = bmx6json.text2html(o.help)
end
if o.syntax ~= nil then
help = help .. "<br/><strong>Syntax: </strong>" .. bmx6json.text2html(o.syntax)
end
if o.def ~= nil then
help = help .. "<strong> Default: </strong>" .. o.def
end
value = general:option(Value,name,name,help)
end
end
function m.on_commit(self,map)
local err = sys.call('bmx6 -c --configReload > /tmp/bmx6-luci.err.tmp')
if err ~= 0 then
m.message = sys.exec("cat /tmp/bmx6-luci.err.tmp")
end
end
return m

View file

@ -1,47 +0,0 @@
--[[
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
--]]
local sys = require("luci.sys")
m = Map("bmx6", "bmx6")
local hna = m:section(TypedSection,"unicastHna","IPv6 HNA")
hna.addremove = true
hna.anonymous = true
local hna_option = hna:option(Value,"unicastHna", "IPv6 Host Network Announcement. Syntax <NETADDR>/<PREFIX>")
--function hna_option:validate(value)
-- local err = sys.call('bmx6 -c --test -a ' .. value)
-- if err ~= 0 then
-- return nil
-- end
-- return value
--end
function m.on_commit(self,map)
local err = sys.call('bmx6 -c --configReload > /tmp/bmx6-luci.err.tmp')
if err ~= 0 then
m.message = sys.exec("cat /tmp/bmx6-luci.err.tmp")
end
end
return m

View file

@ -1,77 +0,0 @@
--[[
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
--]]
local sys = require("luci.sys")
local bmx6json = require("luci.model.bmx6json")
local m = Map("bmx6", "bmx6")
local eth_int = sys.net.devices()
local interfaces = m:section(TypedSection,"dev","Devices","")
interfaces.addremove = true
interfaces.anonymous = true
local intlv = interfaces:option(ListValue,"dev","Device")
for _,i in ipairs(eth_int) do
intlv:value(i,i)
end
-- Getting json and looking for device section
local json = bmx6json.get("options")
if json == nil or json.OPTIONS == nil then
m.message = "bmx6-json plugin is not running or some mistake in luci-bmx6 configuration, check /etc/config/luci-bmx6"
json = {}
else
json = json.OPTIONS
end
local dev = {}
for _,j in ipairs(json) do
if j.name == "dev" and j.CHILD_OPTIONS ~= nil then
dev = j.CHILD_OPTIONS
break
end
end
local help = ""
local name = ""
for _,o in ipairs(dev) do
if o.name ~= nil then
help = ""
name = o.name
if o.help ~= nil then
help = bmx6json.text2html(o.help)
end
if o.syntax ~= nil then
help = help .. "<br/><strong>Syntax: </strong>" .. bmx6json.text2html(o.syntax)
end
value = interfaces:option(Value,name,name,help)
value.optional = true
end
end
return m

View file

@ -1,105 +0,0 @@
--[[
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
--]]
local sys = require("luci.sys")
local bmx6json = require("luci.model.bmx6json")
m = Map("bmx6", "bmx6")
-- Getting json and Checking if bmx6-json is avaiable
local options = bmx6json.get("options")
if options == nil or options.OPTIONS == nil then
m.message = "bmx6-json plugin is not running or some mistake in luci-bmx6 configuration, check /etc/config/luci-bmx6"
return m
else
options = options.OPTIONS
end
-- Getting a list of interfaces
local eth_int = luci.sys.net.devices()
local tunDev = m:section(TypedSection,"tunDev",translate("Tunnel device"),translate("Define incoming ipip tunnel interface name"))
tunDev.addremove = true
tunDev.anonymous = true
tunDev:option(Value,"tunDev",translate("Name"),translate("Name for the tunnel network device"))
tunDev:option(Value,"tun4Address", translate("IPv4 address/length"),translate("Specify default IPv4 tunnel address and announced range (ex. 10.1.2.3/24)"))
tunDev:option(Value,"tun6Address", translate("IPv6 address/length"),translate("Specify default IPv6 tunnel address and announced range (ex. 2012:0:0:123:0:0:0:1/64)"))
-- IP section
local ipV = m:section(NamedSection,"ipVersion","ipVersion",translate("Miscellaneous IP options"))
ipV.addremove = false
local lipv = ipV:option(ListValue,"ipVersion",translate("IP version"))
lipv:value("6","6")
lipv.default = "6"
-- rest of ip options are optional, getting them from json
local ipoptions = {}
for _,o in ipairs(options) do
if o.name == "ipVersion" and o.CHILD_OPTIONS ~= nil then
ipoptions = o.CHILD_OPTIONS
break
end
end
local help = ""
local name = ""
local value = nil
for _,o in ipairs(ipoptions) do
if o.name ~= nil then
help = ""
name = o.name
if o.help ~= nil then
help = bmx6json.text2html(o.help)
end
if o.syntax ~= nil then
help = help .. "<br/><strong>Syntax: </strong>" .. bmx6json.text2html(o.syntax)
end
if o.def ~= nil then
help = help .. "<br/><strong> Default: </strong>" .. bmx6json.text2html(o.def)
end
value = ipV:option(Value,name,name,help)
value.optional = true
end
end
-- Interfaces section
local interfaces = m:section(TypedSection,"dev",translate("Devices"),translate("Network devices to mesh with"))
interfaces.addremove = true
interfaces.anonymous = true
local intlv = interfaces:option(ListValue,"dev",translate("Device"))
for _,i in ipairs(eth_int) do
intlv:value(i,i)
end
function m.on_commit(self,map)
local err = sys.call('bmx6 -c --configReload > /tmp/bmx6-luci.err.tmp')
if err ~= 0 then
m.message = sys.exec("cat /tmp/bmx6-luci.err.tmp")
end
end
return m

View file

@ -1,50 +0,0 @@
--[[
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
--]]
local sys = require("luci.sys")
m = Map("bmx6", "bmx6")
plugins_dir = {"/usr/lib/","/var/lib","/lib"}
plugin = m:section(TypedSection,"plugin","Plugin")
plugin.addremove = true
plugin.anonymous = true
plv = plugin:option(ListValue,"plugin", "Plugin")
for _,d in ipairs(plugins_dir) do
pl = luci.sys.exec("cd "..d..";ls bmx6_*")
if #pl > 6 then
for _,v in ipairs(luci.util.split(pl,"\n")) do
plv:value(v,v)
end
end
end
function m.on_commit(self,map)
local err = sys.call('/etc/init.d/bmx6 restart')
if err ~= 0 then
m.message = sys.exec("Cannot restart bmx6")
end
end
return m

View file

@ -1,70 +0,0 @@
--[[
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
--]]
local sys = require("luci.sys")
local bmx6json = require("luci.model.bmx6json")
m = Map("bmx6", "bmx6")
-- tunOut
local tunnelsOut = m:section(TypedSection,"tunOut",translate("Networks to fetch"),translate("Gateways announcements to fetch"))
tunnelsOut.addremove = true
tunnelsOut.anonymous = true
tunnelsOut:option(Value,"tunOut","Name")
tunnelsOut:option(Value,"network", translate("Network to fetch"))
local tunoptions = bmx6json.getOptions("tunOut")
local _,o
for _,o in ipairs(tunoptions) do
if o.name ~= nil and o.name ~= "network" then
help = bmx6json.getHtmlHelp(o)
value = tunnelsOut:option(Value,o.name,o.name,help)
value.optional = true
end
end
-- tunOut
local tunnelsIn = m:section(TypedSection,"tunIn",translate("Networks to offer"),translate("Gateways to announce in the network"))
tunnelsIn.addremove = true
tunnelsIn.anonymous = true
tunnelsIn:option(Value,"tunIn","Name")
tunnelsIn:option(Value,"network", translate("Network to offer"))
local tunInoptions = bmx6json.getOptions("tunIn")
local _,o
for _,o in ipairs(tunInoptions) do
if o.name ~= nil and o.name ~= "network" then
help = bmx6json.getHtmlHelp(o)
value = tunnelsIn:option(Value,o.name,o.name,help)
value.optional = true
end
end
function m.on_commit(self,map)
--Not working. If test returns error the changes are still commited
local msg = bmx6json.testandreload()
if msg ~= nil then
m.message = msg
end
end
return m

View file

@ -1,108 +0,0 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(5, '/cgi-bin/bmx6-info', { 'neighbours': '' },
function(x, st)
{
var originators = st.neighbours[0].originators;
var descriptions = st.neighbours[1].descriptions;
var tb = document.getElementById('descriptions_table');
if ( originators.length != descriptions.length )
{
var tr = tb.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
td.colSpan = 7;
td.innerHTML = '<em><br /><%:Some problem with JSON: lenght of originators and descriptions different. %></em>';
return 1;
}
if ( originators && descriptions && tb)
{
/* clear all rows */
while( tb.rows.length > 1 )
tb.deleteRow(1);
for( var i = 0; i < descriptions.length; i++ )
{
var tr = tb.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
tr.insertCell(-1).innerHTML = descriptions[i].DESC_ADV.globalId.replace(/\.[^\.]+$/,"");
var extensions = descriptions[i].DESC_ADV.extensions;
//Looking for the extensions
var hna6 = [];
for( var e = 0; e < extensions.length; e++)
{
if( extensions[e].HNA6_EXTENSION )
{
hna6 = extensions[e].HNA6_EXTENSION;
break;
}
}
//Adding first HNA with prefix=128 as main address
var ipstxt = '';
var address;
var prefix;
for( var e = 0; e < hna6.length; e++ )
{
address = hna6[e].address;
prefix = hna6[e].prefixlen;
if ( prefix == '128' )
{
ipstxt += address;
break;
}
}
tr.insertCell(-1).innerHTML = ipstxt;
tr.insertCell(-1).innerHTML = originators[i].viaDev;
tr.insertCell(-1).innerHTML = originators[i].metric;
tr.insertCell(-1).innerHTML = originators[i].lastDesc;
tr.insertCell(-1).innerHTML = originators[i].lastRef;
tr.insertCell(-1).innerHTML = originators[i].blocked;
}
if( tb.rows.length == 1 )
{
var tr = tb.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
td.colSpan = 7;
td.innerHTML = '<em><br /><%:There are no nodes available.%></em>';
}
}
}
);
//]]></script>
<div class="cbi-map">
<fieldset class="cbi-section">
<legend><%:Mesh nodes%></legend>
<table class="cbi-section-table" id="descriptions_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Hostname%></th>
<th class="cbi-section-table-cell"><%:Primary IP%></th>
<th class="cbi-section-table-cell"><%:Via Device%></th>
<th class="cbi-section-table-cell"><%:Metric%></th>
<th class="cbi-section-table-cell"><%:Last Desc%></th>
<th class="cbi-section-table-cell"><%:Last Ref%></th>
<th class="cbi-section-table-cell"><%:Blocked%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="7"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
</fieldset>
</div>

View file

@ -1,35 +0,0 @@
<%+header%>
<meta http-equiv="refresh" content="60" />
<h2><a id="content" name="content"><%:Chat%></a></h2>
<p>This is sms a chat where all bmx6 nodes can participate. The data is replayed using routing packets, so there is a limit of 2040 bytes. Use it only to send short messages.</p>
<p>Each participant can only send one sms at same time.</p>
<br />
<strong>Received SMS</strong>
<br />
<pre style="background-color:#dadbe6;">
<% for orig,sms in pairs(chat) do %>
<u><%=orig%></u>:<%=sms%>
<% end %>
</pre>
<form action=".">
<input type="submit" value="refresh" />
</form>
<br />
<form action="." method="post">
<input type="text" name="toSend" />
<input type="submit" value="send sms" />
</form>
<br />
<table>
<tr>
<td><strong>Your last sms: </strong></td>
<td><pre><%=sent%></pre></td>
</tr>
</table>
<%+footer%>

View file

@ -1,10 +0,0 @@
<%+header%>
<h2><a id="content" name="content"><%:ERROR%></a></h2>
<strong>Some error has occurred</strong>
<br />
<pre>
<%=txt%>
</pre>
<br />
<%+footer%>

View file

@ -1,120 +0,0 @@
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript">//<![CDATA[
var displayExtraInfo = function ( id ) {
document.getElementById('extra-info').innerHTML = document.getElementById(id).innerHTML;
}
XHR.poll(5, '/cgi-bin/bmx6-info', { 'descriptions/all': '' },
function(x, st)
{
var tb = document.getElementById('descriptions_table');
var rowcount = 0;
var tunicon = "<%=resource%>/icons/tunnel.png";
/* clear all rows */
while( tb.rows.length > 1 ) tb.deleteRow(1);
for ( var k in st )
{
var description = st[k].DESC_ADV;
var tun4in6;
for ( var k in description.extensions )
{
var value = description.extensions[k];
if ( value.TUN4IN6_NET_EXTENSION )
{
tun4in6 = value.TUN4IN6_NET_EXTENSION;
break;
}
}
if ( tun4in6 )
{
var nodename = description.globalId.replace(/\..+$/,'');
for( var i = 0; i < tun4in6.length; i++ )
{
var tr = tb.insertRow(-1);
var network = tun4in6[i].network;
var network_len = tun4in6[i].networklen;
var network_bw = tun4in6[i].bandwidth;
if ( network_len >= 32 ) continue;
tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((rowcount++ % 2) + 1);
tr.insertCell(-1).innerHTML = String.format('<a href="/cgi-bin/bmx6control?function=gwselect&amp;node=%s"><img src="%s" /></a>',nodename,tunicon);
tr.insertCell(-1).innerHTML = nodename;
tr.insertCell(-1).innerHTML = network + '/' + network_len;
tr.insertCell(-1).innerHTML = network_bw;
}
if( tb.rows.length == 1 )
{
var tr = tb.insertRow(-1);
tr.className = 'cbi-section-table-row';
var td = tr.insertCell(-1);
td.colSpan = 4;
td.innerHTML = '<em><br /><%:There are no gateways announced in the network.%></em>';
}
}
}
}
);
//]]></script>
<style>
div.hideme{
display: none;
}
div.info{
background: #FFF;
border: solid 1px;
height: 80px;
display: block;
overflow: auto;
}
div.inforow{
text-align:left;
display:inline-block;
width:20%;
margin:5px;
vertical-align:top;
}
#extra-info ul { list-style: none outside none; margin-left: 0em; }
</style>
<div class="cbi-map">
<h2>Originators</h2>
<div class="cbi-map-descr"></div>
<fieldset class="cbi-section">
<legend><%:Mesh gateways%></legend>
<table class="cbi-section-table" id="descriptions_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"></th>
<th class="cbi-section-table-cell"><%:Node%></th>
<th class="cbi-section-table-cell"><%:Network%></th>
<th class="cbi-section-table-cell"><%:Bandwidth%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="4"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
</fieldset>
</div>
<%+footer%>

View file

@ -1,49 +0,0 @@
<%#
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
Contributors Jo-Philip
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
-%>
<%
luci.http.prepare_content("text/html")
local location = { unpack(luci.dispatcher.context.path) }
location[#location] = "topology"
%>
<%+header%>
<button id="redraw" onclick="redraw();">&nbsp redraw &nbsp</button>
<div id="wait" style="text-align: center">
<br /><br />
<img src="<%=resource%>/icons/loading.gif" />
<%:Collecting data...%>
</div>
<div id="canvas" style="min-width:1024px; min-height:1024px"></div>
<script type="text/javascript" src="<%=resource%>/jquery/jquery-1.4.js"></script>
<script type="text/javascript" src="<%=resource%>/dracula/raphael-min.js"></script>
<script type="text/javascript" src="<%=resource%>/dracula/dracula_graffle.js"></script>
<script type="text/javascript" src="<%=resource%>/dracula/dracula_graph.js"></script>
<script type="text/javascript" src="<%=resource%>/bmx6/js/bmx6-graph.js"></script>
<%+footer%>

View file

@ -1,55 +0,0 @@
<%+header%>
<meta http-equiv="refresh" content="10" />
<h2><a id="content" name="content"><%:Links%></a></h2>
<br />
<div id="links" style="position:relative;padding-left:2px">
<% for j,d in pairs(links) do %>
<table>
<tr>
<td><img src="/luci-static/resources/bmx6/wifi.png"/></td>
<td><strong><%=j%></strong></td>
</tr>
</table>
<div style="display:table">
<% for i,l in ipairs(d) do %>
<div id="link" style="background-color:#dadbe9;left:50px;width:300px;margin:10px;float:left;position:relative">
<table>
<tr><th colspan="2">
<span style="color:grey;font-weight:700;text-align:left;">
<%=l.name%>
<br />
</span>
</th></tr>
<tr>
<td><img src="/luci-static/resources/bmx6/link.png"/></td>
<td>
<ul>
<li>Local IP: <a href="[<%=l.llocalIp%>]"><%=l.llocalIp%></a></li>
<li>Device: <%=l.viaDev%></li>
<li>Rate (rx/tx):
<% if l.rxRate+l.txRate < 120 then %>
<span style="color:red;">
<% else %>
<span style="color:green;">
<% end %>
<%=l.rxRate%>/<%=l.txRate%>
</span>
</li>
<li>Routes: <%=l.routes%></li>
</ul>
</td>
</tr>
</table>
</div>
<% end %>
</div>
<% end %>
</div>
<br />
<br />
<%+footer%>

View file

@ -1,204 +0,0 @@
<%#
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
Contributors Lluis Esquerda <eskerda@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
-%>
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript" src="<%=resource%>/bmx6/js/polling.js"></script>
<style>
div.hideme{
display: none;
}
div.info{
background: #FFF;
border: solid 0px;
height: 90px;
display: block;
overflow: auto;
}
div.inforow{
text-align:left;
display:inline-block;
width:20%;
margin:5px;
vertical-align:top;
}
#extra-info ul { list-style: none outside none; margin-left: 0em; }
</style>
<div class="cbi-map">
<h2>Node originators</h2>
<div class="cbi-map-descr"></div>
<div id="extra-info" class="info">
<br />
<center>
Click icon <img src="<%=resource%>/bmx6/world.png" /> to see individual node information
</center>
</div>
<fieldset class="cbi-section">
<legend><%:Mesh nodes%></legend>
<table class="cbi-section-table" id="descriptions_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"></th>
<th class="cbi-section-table-cell"><%:Hostname%></th>
<th class="cbi-section-table-cell"><%:Primary IP%></th>
<th class="cbi-section-table-cell"><%:Via Device%></th>
<th class="cbi-section-table-cell"><%:Metric%></th>
<th class="cbi-section-table-cell"><%:Last Desc%></th>
<th class="cbi-section-table-cell"><%:Last Ref%></th>
<th class="cbi-section-table-cell"><%:Blocked%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="8"><br /><center><em><%:Collecting data...%></em></center></td>
</tr>
</table>
</fieldset>
</div>
<script type="text/javascript">//<![CDATA[
var displayExtraInfo = function ( id ) {
document.getElementById('extra-info').innerHTML = document.getElementById(id).innerHTML;
}
new TablePooler(5,"/cgi-bin/bmx6-info", {'neighbours':''}, "descriptions_table", function(st){
var infoicon = "<%=resource%>/bmx6/world_small.png";
var nodeicon = "<%=resource%>/bmx6/world.png";
var originators = st.neighbours[0].originators;
var descriptions = st.neighbours[1].descriptions;
var res = Array();
var error = "";
if ( originators.length != descriptions.length )
{
error = '<em><br /><%:Some problem with JSON: lenght of originators and descriptions differs. %> \
<%: Please perform a cache flush from a console it this persists: bmx6 -c --flushAll %></em>';
res.push([[error,7]]);
return res;
}
for ( var i = 0; i < descriptions.length; i++ ){
var nodename = descriptions[i].DESC_ADV.globalId.replace(/\.[^\.]+$/,"");
var extensions = descriptions[i].DESC_ADV.extensions;
//var extrainfo = '<a onclick="displayExtraInfo(\'ip-' + i + '\')"><img src="' + infoicon + '" / ></a>';
var extrainfo_link = '<a onclick="displayExtraInfo(\'ip-' + i + '\')">' + '<img src="' + infoicon + '" />' + '</a>';
// Looking for the extensions
var hna6 = [];
var tun4in6 = [];
var tun6in6 = [];
for( var e = 0; e < extensions.length; e++)
{
if( extensions[e].HNA6_EXTENSION )
hna6 = extensions[e].HNA6_EXTENSION;
if ( extensions[e].TUN4IN6_NET_EXTENSION )
tun4in6 = extensions[e].TUN4IN6_NET_EXTENSION;
tun6in6 = extensions[e].TUN6IN6_NET_EXTENSION;
}
// Gateways
var gateways = '<ul>';
if ( typeof(tun4in6) !== "undefined" && tun4in6 !== null )
for ( var t = 0; t < tun4in6.length; t++)
{
if ( tun4in6[t].networklen == "32" )
gateways += '<li><a href="http://' + tun4in6[t].network + '">' + tun4in6[t].network + '</a></li>';
else
gateways += "<li>"+tun4in6[t].network+'/'+tun4in6[t].networklen + ' | ' + tun4in6[t].bandwidth+'</li>';
}
if ( typeof(tun6in6) !== "undefined" && tun6in6 !== null )
for ( var t = 0; t < tun6in6.length; t++)
{
if ( tun6in6[t].networklen == "128" )
gateways += '<li><a href="http://' + tun6in6[t].network + '">' + tun6in6[t].network + '</a></li>';
else
gateways += "<li>"+tun6in6[t].network+'/'+tun6in6[t].networklen + ' | ' + tun6in6[t].bandwidth+'</li>';
}
gateways += '</ul>';
//Adding HNAs with prefix=128 as main address
var ipstxt = '';
var address;
var first = 1;
var ipstxt_hidden = '<ul>';
var hna6list = '<ul>';
var extrainfo = "";
for( var e = 0; e < hna6.length; e++ )
{
address = hna6[e].address;
prefix = hna6[e].prefixlen;
if ( prefix == '128' )
{
if (first)
{
ipstxt += address;
ipstxt_hidden += '<li><a href="http://['+address+']" >'+address+"</a></li>";
first = 0;
}
else {
ipstxt_hidden += '<li><a href="http://['+address+']" >'+address+"</a></li>";
}
}
else {
hna6list += '<li>'+address+'/'+prefix+'</li>';
}
}
hna6list += '</ul>';
ipstxt_hidden += '</ul>';
extrainfo = '<div id="ip-'+ i +'" class="hideme">'
+ "<div class='inforow'>"
+ "<h4>" + nodename + '</h4>\n' + '<img src="' + nodeicon + '" />'+ "</div>"
+ "<div class='inforow'>"
+ "<h5>Available IPs</h5>\n"
+ ipstxt_hidden + "</div>\n"
+ "<div class='inforow'>"
+ "<h5>Gateways announced</h5>\n"
+ gateways + "</div>\n"
+ "<div class='inforow'>"
+ "<h5>Networks announced</h5>\n"
+ hna6list + "</div>\n"
+ "\n</div>";
res.push([extrainfo_link,nodename, ipstxt, originators[i].viaDev, originators[i].metric,
originators[i].lastDesc, originators[i].lastRef, originators[i].blocked, extrainfo]);
}
return res;
});
//]]></script>
<%+footer%>

View file

@ -1,88 +0,0 @@
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript" src="<%=resource%>/bmx6/js/polling.js"></script>
<style>
div.hideme{
display: none;
}
div.info{
background: #FFF;
border: solid 1px;
height: 80px;
display: block;
overflow: auto;
}
div.inforow{
text-align:left;
display:inline-block;
width:20%;
margin:5px;
vertical-align:top;
}
#extra-info ul { list-style: none outside none; margin-left: 0em; }
</style>
<div class="cbi-map">
<center>
<img src="<%=resource%>/bmx6/bmx6logo.png" />
<br />
<br />
a mesh routing protocol for Linux devices.<br />
Visit <a href="http://bmx6.net">bmx6.net</a> for more info.
<br />
<br />
</center>
<h2>status</h2>
<div class="cbi-map-descr"></div>
<fieldset class="cbi-section">
<legend><%:status%></legend>
<table class="cbi-section-table" id="status_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"><%:Version%></th>
<th class="cbi-section-table-cell"><%:Primary IP%></th>
<th class="cbi-section-table-cell"><%:Tun6Address%></th>
<th class="cbi-section-table-cell"><%:Tun4Address%></th>
<th class="cbi-section-table-cell"><%:Uptime%></th>
<th class="cbi-section-table-cell"><%:Cpu load%></th>
<th class="cbi-section-table-cell"><%:Nodes seen%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="7"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
</fieldset>
</div>
<script type="text/javascript">//<![CDATA[
new TablePooler(5,"/cgi-bin/bmx6-info", {'info':''}, "status_table", function(st){
var res = Array();
var sta = st.info[0].status;
var ifaces = st.info[1].interfaces;
res.push([sta.version+'/'+sta.compat,sta.primaryIp,sta.tun6Address,
sta.tun4Address,sta.uptime,sta.cpu,sta.nodes]);
res.push(['<br/>','','','','','','',''])
res.push(['','','','','','','',''])
res.push(['<b>Interface Name</b>','<b>State</b>','<b>Type</b>','<b>Rate</b>','<b>Local IP</b>','<b>Global IP</b>','<b>is Primary</b>'])
for ( var i = 0; i < ifaces.length; i++)
{
res.push([ifaces[i].devName,ifaces[i].state,ifaces[i].type,ifaces[i].rateMin+"/"+ifaces[i].rateMax,
ifaces[i].llocalIp,ifaces[i].globalIp,ifaces[i].primary],'');
}
return res;
});
//]]></script>
<%+footer%>

View file

@ -1,106 +0,0 @@
<%#
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
Contributors Lluis Esquerda <eskerda@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
-%>
<%+header%>
<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
<script type="text/javascript" src="<%=resource%>/bmx6/js/polling.js"></script>
<style>
div.hideme{
display: none;
}
div.info{
background: #FFF;
border: solid 1px;
height: 80px;
display: block;
overflow: auto;
}
div.inforow{
text-align:left;
display:inline-block;
width:20%;
margin:5px;
vertical-align:top;
}
#extra-info ul { list-style: none outside none; margin-left: 0em; }
</style>
<div class="cbi-map">
<h2>Gateways tunnel announcements</h2>
<div class="cbi-map-descr"></div>
<fieldset class="cbi-section">
<legend><%:Mesh gateways%></legend>
<table class="cbi-section-table" id="descriptions_table">
<tr class="cbi-section-table-titles">
<th class="cbi-section-table-cell"></th>
<th class="cbi-section-table-cell"><%:Tunnel%></th>
<th class="cbi-section-table-cell"><%:Node%></th>
<th class="cbi-section-table-cell"><%:Network%></th>
<th class="cbi-section-table-cell"><%:Bandwidth%></th>
<th class="cbi-section-table-cell"><%:SearchNet%></th>
<th class="cbi-section-table-cell"><%:Path Metric%></th>
<th class="cbi-section-table-cell"><%:Tun metric%></th>
<th class="cbi-section-table-cell"><%:Rating%></th>
<th class="cbi-section-table-cell"><%:Src%></th>
<th class="cbi-section-table-cell"><%:Search id%></th>
</tr>
<tr class="cbi-section-table-row">
<td colspan="10"><em><br /><%:Collecting data...%></em></td>
</tr>
</table>
</fieldset>
</div>
<script type="text/javascript">//<![CDATA[
new TablePooler(5,"/cgi-bin/bmx6-info", {'tunnels':''}, "descriptions_table", function(st){
var tunicon = "<%=resource%>/icons/tunnel.png";
var tunicon_dis = "<%=resource%>/icons/tunnel_disabled.png";
var applyicon = "<%=resource%>/cbi/apply.gif";
var res = Array();
for ( var k in st.tunnels ){
var tunnel = st.tunnels[k];
var nodename = tunnel.remoteName.replace(/\..+$/,'');
var advnet = tunnel.advNet;
var status = '<img src="'+tunicon_dis+'"/>';
if ( tunnel.tunName != "---" ) status = '<img src="'+tunicon+'"/>';
if ( advnet == "0.0.0.0/0" ) advnet = "<b>Internet</b>";
res.push([status, tunnel.name, nodename, advnet, tunnel.advBw, tunnel.net,
tunnel.pathMtc, tunnel.tunMtc, tunnel.rating, tunnel.srcIngress, tunnel.id]);
}
return res;
});
//]]></script>
<%+footer%>

View file

@ -1,126 +0,0 @@
#!/bin/sh
# This script gives information about bmx6
# Can be executed from a linux shell: ./bmx6-info -s links
# Or from web interfae (with cgi enabled): http://host/cgi-bin/bmx6-info?links
# Special methods are tagged with '$', like $myself or $neighbours: http://host/cgi-bin/bmx6-info?$myself
# When '$' is not used, raw bmx6 information from the filesystem is returned (/var/runb/bmx6/json/)
BMX6_DIR="$(uci get bmx6.general.runtimeDir 2>/dev/null)" || BMX6_DIR="/var/run/bmx6/json"
#Checking if shell mode or cgi-bin mode
if [ "$1" == "-s" ]; then
QUERY="$2"
else
QUERY="${QUERY_STRING%%=*}"
QUERY="${QUERY%%\?*}"
QUERY="${QUERY%%\&*}"
echo "Content-type: application/json"
echo ""
fi
# workaround to support old format starting with '$'
QUERY="$(echo "$QUERY" | sed s/'\$'//)"
check_path() {
[ -d "$1" ] && path=$(cd $1; pwd)
[ -f "$1" ] && path=$(cd $1/..; pwd)
[ $(echo "$path" | grep -c "^$BMX6_DIR") -ne 1 ] && exit 1
}
print_query() {
# If the query is a directory
[ -d "$BMX6_DIR/$1" ] &&
{
# If /all has not been specified
[ -z "$QALL" ] &&
{
total=$(ls $BMX6_DIR/$1 | wc -w)
i=1
echo -n "{ \"$1\": [ "
for f in $(ls $BMX6_DIR/$1); do
echo -n "{ \"name\": \"$f\" }"
[ $i -lt $total ] && echo -n ','
i=$(( $i + 1 ))
done
echo -n " ] }"
# If /all has been specified, printing all the files together
} || {
comma=""
echo -n "[ "
for entry in "$BMX6_DIR/$1/"*; do
[ -f "$entry" ] &&
{
${comma:+echo -n "$comma"}
tr -d '\n' < "$entry"
comma=","
}
done
echo -n " ]"
}
}
# If the query is a file, just printing the file
[ -f "$BMX6_DIR/$1" ] && cat "$BMX6_DIR/$1";
}
if [ "${QUERY##*/}" == "all" ]; then
QUERY="${QUERY%/all}"
QALL=1
fi
if [ "$QUERY" == 'myself' ]; then
hostname="$(cat /proc/sys/kernel/hostname)"
ip6="$(bmx6 -c show=status | grep ^BMX | awk '{print $5}')"
ip4="$(bmx6 -c show=status | grep ^BMX | awk '{print $6}')"
cidr6=$(lua -l luci.ip -e "ip=luci.ip.new(\"$ip6\"); print(ip:network():string()..'/'..ip:prefix())")
cidr4=$(lua -l luci.ip -e "ip=luci.ip.new(\"$ip4\"); print(ip:network():string()..'/'..ip:prefix())")
echo -n "{\"myself\":{\"hostname\":\"$hostname\",\"ip6\":\"$ip6\",\"ip4\":\"$ip4\",\"net6\":\"$cidr6\",\"net4\":\"$cidr4\"}}"
exit 0
fi
if [ "$QUERY" == 'info' ]; then
echo -n '{ "info": [ '
print_query status
echo -n ","
print_query interfaces
echo -n "] }"
exit 0
fi
if [ "$QUERY" == 'neighbours' ]; then
QALL=1
echo -n '{ "neighbours": [ '
echo -n '{ "originators": '
print_query originators
echo -n '}, '
echo -n '{ "descriptions": '
print_query descriptions
echo -n "} ] }"
exit 0
fi
if [ "$QUERY" == 'tunnels' ]; then
tunnels=$(bmx6 -c --jshow tunnels /r=0)
if [ -z "$tunnels" ]; then
echo '{ "tunnels" : [] }'
else
echo $tunnels
fi
exit 0
fi
if [ "$QUERY" == "" ]; then
echo -n '{ "queries": ['
echo -n '{ "name": "myself", "info": "basic network information of self node" },'
echo -n '{ "name": "info", "info": "full network and device information of self node" },'
echo -n '{ "name": "tunnels", "info": "accnouncements (tunnels) published by the mesh network" },'
echo -n '{ "name": "neighbours", "info": "list of all my neighbours and their information" },'
echo -n '{ "name": "/", "info": "raw bmx6 json API" }]}'
exit 0
fi
check_path "$BMX6_DIR/$QUERY"
print_query $QUERY
#ls -1F "$BMX6_DIR"
exit 0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -1,234 +0,0 @@
var graph, canvas, layouter, renderer, divwait, nodes, announcements, nodesIndex, palette, localInfo;
document.addEventListener( "DOMContentLoaded", init, false);
/**
* Returns an index of nodes by name
*/
function createNodeIndex(nodes) {
var inode, index = {};
for (inode in nodes)
index[nodes[inode].name] = nodes[inode];
return index;
}
/**
* Updates to have announcements in nodes list
*/
function processNodeAnnouncements(nodes, announcements) {
var iannouncement, remoteNode, announcement;
nodesIndex = createNodeIndex(nodes);
for(iannouncement in announcements) {
announcement = announcements[iannouncement];
if (announcement.remoteName == '---' ) continue;
if (!( announcement.remoteName in nodesIndex )) {
newNode = {
name: announcement.remoteName,
links: []
};
nodes.push(newNode);
nodesIndex[newNode.name] = newNode;
};
remoteNode = nodesIndex[announcement.remoteName];
if (!( 'announcements' in remoteNode )) remoteNode.announcements = [];
remoteNode.announcements.push(announcement);
};
}
function init() {
palette = generatePalette(200);
graph = new Graph();
canvas = document.getElementById('canvas');
layouter = new Graph.Layout.Spring(graph);
renderer = new Graph.Renderer.Raphael(canvas.id, graph, canvas.offsetWidth, canvas.offsetHeight);
divwait = document.getElementById("wait");
XHR.get('/cgi-bin/luci/admin/network/BMX6/topology', null, function(nodesRequest, nodesData) {
nodes = nodesData;
XHR.get('/cgi-bin/bmx6-info?$myself&', null, function(myselfRequest, myselfData) {
if (myselfData)
localAnnouncements = [
{remoteName: myselfData.myself.hostname, advNet: myselfData.myself.net4},
{remoteName: myselfData.myself.hostname, advNet: myselfData.myself.net6}
];
XHR.get('/cgi-bin/bmx6-info?$tunnels=&', null, function(tunnelsRequest, tunnelsData) {
var iAnnouncement;
announcements = tunnelsData.tunnels;
for(iAnnouncement in localAnnouncements) {
announcements.push(localAnnouncements[iAnnouncement])
};
processNodeAnnouncements(nodes, announcements);
divwait.parentNode.removeChild(divwait);
draw(nodes);
});
});
});
}
function hashCode(str) {
var hash = 0;
if (str.length == 0) return hash;
for (i = 0; i < str.length; i++) {
char = str.charCodeAt(i);
hash = ((hash<<5)-hash)+char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
function generatePalette(size) {
var i, arr = [];
Raphael.getColor(); // just to remove the grey one
for(i = 0; i < size; i++) {
arr.push(Raphael.getColor())
}
return arr;
}
function getFillFromHash(hash) {
return palette[Math.abs(hash % palette.length)];
}
function hashAnnouncementsNames(announcementsNames) {
return hashCode(announcementsNames.sort().join('-'));
}
function getNodeAnnouncements(networkNode) {
return networkNode.announcements;
}
function nodeRenderer(raphael, node) {
var nodeFill, renderedNode, options;
options = {
'fill': 'announcements' in node.networkNode ? getFillFromHash(
hashAnnouncementsNames(
getNodeAnnouncements(node.networkNode).map(function(ann) {return ann.advNet;})
)
) : '#bfbfbf',
'stroke-width': 1,
};
renderedNode = raphael.set();
renderedNode.push(raphael.ellipse(node.point[0], node.point[1], 30, 20).attr({"fill": options['fill'], "stroke-width": options['stroke-width']}));
renderedNode.push(raphael.text(node.point[0], node.point[1] + 30, node.networkNode.name).attr({}));
renderedNode.items.forEach(function(el) {
var announcements, tooltip = raphael.set();
tooltip.push(raphael.rect(-60, -60, 120, 60).attr({"fill": "#fec", "stroke-width": 1, r : "9px"}));
announcements = getNodeAnnouncements(node.networkNode);
if (announcements) {
announcements = announcements.map(function(ann) {return ann.advNet});
tooltip.push(raphael.text(0, -40, 'announcements\n' + announcements.join('\n')).attr({}));
};
el.tooltip(tooltip);
});
return renderedNode;
}
function genericNodeRenderer(raphael, node) {
var renderedNode;
renderedNode = raphael.set();
renderedNode.push(raphael.ellipse(node.point[0], node.point[1], 30, 20).attr({"fill": '#bfbfbf', "stroke-width": 1}));
renderedNode.push(raphael.text(node.point[0], node.point[1] + 30, node.networkNode.name).attr({}));
return renderedNode;
}
function redraw() {
layouter.layout();
renderer.draw();
}
function interpolateColor(minColor,maxColor,maxDepth,depth){
function d2h(d) {return d.toString(16);}
function h2d(h) {return parseInt(h,16);}
if(depth == 0){
return minColor;
}
if(depth == maxDepth){
return maxColor;
}
var color = "#";
for(var i=1; i <= 6; i+=2){
var minVal = new Number(h2d(minColor.substr(i,2)));
var maxVal = new Number(h2d(maxColor.substr(i,2)));
var nVal = minVal + (maxVal-minVal) * (depth/maxDepth);
var val = d2h(Math.floor(nVal));
while(val.length < 2){
val = "0"+val;
}
color += val;
}
return color;
}
function draw(nodes) {
var node, neighbourNode, seenKey, rxRate, txRate, seen, i, j, currentName, linkQuality;
seen = { };
for (i = 0; i < (nodes.length); i++) {
node = nodes[i];
graph.addNode(node.name, {
networkNode: node,
render: nodeRenderer
});
};
for (i = 0; i < (nodes.length); i++) {
node = nodes[i];
if (! node.name) continue;
currentName = node.name;
for (j = 0; j < (node.links.length); j++) {
neighbourNode = node.links[j];
graph.addNode(neighbourNode.name, {render: genericNodeRenderer, networkNode: neighbourNode});
seenKey = (node.name < neighbourNode.name) ? node.name + '|' + neighbourNode.name : neighbourNode.name + '|' + node.name;
rxRate = neighbourNode.rxRate;
txRate = neighbourNode.txRate;
if (!seen[seenKey] && rxRate > 0 && txRate > 0) {
linkQuality = ( rxRate + txRate ) / 2;
graph.addEdge(node.name, neighbourNode.name, {
'label': rxRate + '/' + txRate,
'directed': false,
'stroke': interpolateColor('FF0000','00FF00', 5, 5 * ( linkQuality - 1 )/100),
'fill': interpolateColor('FF0000','00FF00', 5, 5 * ( linkQuality - 1 )/100),
'label-style': { 'font-size': 8 }
});
seen[seenKey] = true;
}
}
}
redraw();
}

View file

@ -1,81 +0,0 @@
/*
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
Contributors Lluis Esquerda <eskerda@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
*/
/*
Table pooler is a function to easy call XHR poller.
new TablePooler(5,"/cgi-bin/bmx6-info", {'status':''}, "status_table", function(st){
var table = Array()
table.push(st.first,st.second)
return table
}
Parameters are:
polling_time: time between pollings
json_url: the json url to fetch the data
json_call: the json call
output_table_id: the table where javascript will put the data
callback_function: the function that will be executed each polling_time
The callback_function must return an array of arrays (matrix).
In the code st is the data obtained from the json call
*/
function TablePooler (time, jsonurl, getparams, table_id, callback) {
this.table = document.getElementById(table_id);
this.callback = callback;
this.jsonurl = jsonurl;
this.getparams = getparams;
this.time = time;
this.clear = function(){
/* clear all rows */
while( this.table.rows.length > 1 ) this.table.deleteRow(1);
}
this.start = function(){
XHR.poll(this.time, this.jsonurl, this.getparams, function(x, st){
var data = this.callback(st);
var content, tr, td;
this.clear();
for (var i = 0; i < data.length; i++){
tr = this.table.insertRow(-1);
tr.className = 'cbi-section-table-row cbi-rowstyle-' + ((i % 2) + 1);
for (var j = 0; j < data[i].length; j++){
td = tr.insertCell(-1);
if (data[i][j].length == 2) {
td.colSpan = data[i][j][1];
content = data[i][j][0];
}
else content = data[i][j];
td.innerHTML = content;
}
}
}.bind(this));
}
this.start();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -1,22 +0,0 @@
table {
width:90%;
border-top:1px solid #e5eaf8;
border-right:1px solid #e5eaf8;
margin:1em auto;
border-collapse:collapse;
}
td {
color:#678197;
border-bottom:1px solid #e6eff8;
border-left:1px solid #e6eff8;
padding:.3em 1em;
text-align:center;
}
th {
background:#f4f9fe;
text-align:center;
font:bold 1.2em/2em Century Gothic,Trebuchet MS,Arial,Helvetica,sans-serif;
color:#66a3d3;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 923 B

View file

@ -1 +0,0 @@
Raphael.fn.connection=function(a,b,c){var d=this,e={draw:function(){for(var f=a.getBBox(),g=b.getBBox(),h=0,i=0,j=[{x:f.x+f.width/2,y:f.y-h},{x:f.x+f.width/2,y:f.y+f.height+h},{x:f.x-h,y:f.y+f.height/2},{x:f.x+f.width+h,y:f.y+f.height/2},{x:g.x+g.width/2,y:g.y-i},{x:g.x+g.width/2,y:g.y+g.height+i},{x:g.x-i,y:g.y+g.height/2},{x:g.x+g.width+i,y:g.y+g.height/2}],k={},l=[],m=0;m<4;m++)for(var n=4;n<8;n++){var o=Math.abs(j[m].x-j[n].x),p=Math.abs(j[m].y-j[n].y);(m==n-4||(3!=m&&6!=n||j[m].x<j[n].x)&&(2!=m&&7!=n||j[m].x>j[n].x)&&(0!=m&&5!=n||j[m].y>j[n].y)&&(1!=m&&4!=n||j[m].y<j[n].y))&&(l.push(o+p),k[l[l.length-1].toFixed(3)]=[m,n])}var q=0==l.length?[0,4]:k[Math.min.apply(Math,l).toFixed(3)],r=j[q[0]].x,s=j[q[0]].y,t=j[q[1]].x,u=j[q[1]].y,o=Math.max(Math.abs(r-t)/2,10),p=Math.max(Math.abs(s-u)/2,10),v=[r,r,r-o,r+o][q[0]].toFixed(3),w=[s-p,s+p,s,s][q[0]].toFixed(3),x=[0,0,0,0,t,t,t-o,t+o][q[1]].toFixed(3),y=[0,0,0,0,s+p,s-p,u,u][q[1]].toFixed(3),z=["M",r.toFixed(3),s.toFixed(3),"C",v,w,x,y,t.toFixed(3),u.toFixed(3)].join(",");if(c&&c.directed){var A=Math.sqrt((u-y)*(u-y)+(t-x)*(t-x)),B=function(a,b){return-a*(b||5)/A},C=[{x:(B(t-x)+B(u-y)+t).toFixed(3),y:(B(u-y)+B(t-x)+u).toFixed(3)},{x:(B(t-x)-B(u-y)+t).toFixed(3),y:(B(u-y)-B(t-x)+u).toFixed(3)}];z=z+",M"+C[0].x+","+C[0].y+",L"+t+","+u+",L"+C[1].x+","+C[1].y}var D="attr";e.fg&&e.fg[D]({path:z})||(e.fg=d.path(z).attr({stroke:c&&c.stroke||"#000",fill:"none"}).toBack()),e.bg&&e.bg[D]({path:z})||c&&c.fill&&(e.bg=c.fill.split&&d.path(z).attr({stroke:c.fill.split("|")[0],fill:"none","stroke-width":c.fill.split("|")[1]||3}).toBack()),c&&c.label&&(e.label&&e.label.attr({x:(r+t)/2,y:(s+u)/2})||(e.label=d.text((r+t)/2,(s+u)/2,c.label).attr({fill:"#000","font-size":c["font-size"]||"12px"}))),c&&c.label&&c["label-style"]&&e.label&&e.label.attr(c["label-style"]),c&&c.callback&&c.callback(e)}};return e.draw(),e};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,154 +0,0 @@
/*!
* jQuery JavaScript Library v1.4.2
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Sat Feb 13 22:33:48 2010 -0500
*/
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);

View file

@ -8,8 +8,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mesh11sd
PKG_VERSION:=1.2.0
PKG_RELEASE:=3
PKG_VERSION:=2.0.0
PKG_RELEASE:=1
PKG_MAINTAINER:=Rob White <rob@blue-wave.net>
PKG_LICENSE:=GPL-2.0-or-later
@ -17,7 +17,7 @@ PKG_LICENSE_FILES:=LICENSE
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/opennds/mesh11sd/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=b719eaacf63eb3684d0cd6a026f4357a4f400f2339f5d5a6cf74ba3744fe30d8
PKG_HASH:=741d219ea9c6fcb5e58771130c319c5b983274caf08f5c1cd5a458864e928649
PKG_BUILD_DIR:=$(BUILD_DIR)/mesh11sd-$(PKG_VERSION)
include $(INCLUDE_DIR)/package.mk
@ -41,6 +41,9 @@ define Package/mesh11sd/description
Without mesh11sd, many mesh parameters cannot be set in the uci wireless config file as the mesh interface must be up before the parameters can be set.
Some of those that are supported, would fail to be implemented when the network is (re)started resulting in errors or dropped nodes.
The mesh11sd daemon dynamically checks configured parameters and sets them as required.
Upstream wan connectivity is checked (eg Internet feed) and when not present, layer 2 peer mode is autonomously enabled,
and when it is present, layer 3 portal mode is enabled. This allows the same simple router configuration to be used on all meshnodes in the layer 2 mesh.
Remote terminal sessions and remote file transfers are supported using the meshnode mac address as an identifier.
This version does not require a Captive Portal to be running.
endef

View file

@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=nodogsplash
PKG_VERSION:=5.0.0
PKG_VERSION:=5.0.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/nodogsplash/nodogsplash/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=a7665f4a42997746a31e9217f2f54e360aa7fc4bc72bd89faa08f1ccf7875b5e
PKG_HASH:=908d3674e93726fdcefb4c3b6705c745753435df9d46425781a57e3f6b417797
PKG_MAINTAINER:=Moritz Warning <moritzwarning@web.de>
PKG_LICENSE:=GPL-2.0-or-later
@ -26,39 +26,37 @@ define Package/nodogsplash
SUBMENU:=Captive Portals
SECTION:=net
CATEGORY:=Network
DEPENDS:=+libpthread +iptables-mod-ipopt +libmicrohttpd-no-ssl
DEPENDS:=+libpthread +libmicrohttpd-no-ssl +iptables-nft \
+iptables-mod-nat-extra +iptables-mod-ipopt \
+iptables-mod-conntrack-extra
TITLE:=Open public network gateway daemon
URL:=https://github.com/nodogsplash/nodogsplash
CONFLICTS:=nodogsplash2
endef
define Package/nodogsplash/description
Nodogsplash is a Captive Portal that offers a simple way to
provide restricted access to the Internet by showing a splash
page to the user before Internet access is granted.
It also incorporates an API that allows the creation of
sophisticated authentication applications.
endef
define Package/nodogsplash/install
$(INSTALL_DIR) $(1)/usr/lib/nodogsplash
$(INSTALL_BIN) ./files/usr/lib/nodogsplash/restart.sh $(1)/usr/lib/nodogsplash/
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/nodogsplash $(1)/usr/bin/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ndsctl $(1)/usr/bin/
$(INSTALL_DIR) $(1)/etc/nodogsplash/htdocs/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/resources/splash.html $(1)/etc/nodogsplash/htdocs/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/resources/splash.css $(1)/etc/nodogsplash/htdocs/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/resources/status.html $(1)/etc/nodogsplash/htdocs/
$(INSTALL_DIR) $(1)/etc/nodogsplash/htdocs/images
$(INSTALL_DATA) $(PKG_BUILD_DIR)/resources/splash.jpg $(1)/etc/nodogsplash/htdocs/images/
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/etc/config/nodogsplash $(1)/etc/config/
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/etc/init.d/nodogsplash $(1)/etc/init.d/
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DIR) $(1)/usr/lib/nodogsplash
$(CP) $(PKG_BUILD_DIR)/resources/splash.html $(1)/etc/nodogsplash/htdocs/
$(CP) $(PKG_BUILD_DIR)/resources/splash.css $(1)/etc/nodogsplash/htdocs/
$(CP) $(PKG_BUILD_DIR)/resources/status.html $(1)/etc/nodogsplash/htdocs/
$(CP) $(PKG_BUILD_DIR)/resources/splash.jpg $(1)/etc/nodogsplash/htdocs/images/
$(CP) $(PKG_BUILD_DIR)/openwrt/nodogsplash/files/etc/config/nodogsplash $(1)/etc/config/
$(CP) $(PKG_BUILD_DIR)/openwrt/nodogsplash/files/etc/init.d/nodogsplash $(1)/etc/init.d/
$(CP) $(PKG_BUILD_DIR)/openwrt/nodogsplash/files/etc/uci-defaults/40_nodogsplash $(1)/etc/uci-defaults/
$(CP) $(PKG_BUILD_DIR)/openwrt/nodogsplash/files/usr/lib/nodogsplash/restart.sh $(1)/usr/lib/nodogsplash/
$(INSTALL_BIN) ./files/etc/uci-defaults/40_nodogsplash $(1)/etc/uci-defaults/
endef
define Package/nodogsplash/postrm

View file

@ -0,0 +1,152 @@
# The options available here are an adaptation of the settings used in nodogsplash.conf.
# See https://github.com/nodogsplash/nodogsplash/blob/master/resources/nodogsplash.conf
config nodogsplash
# Set to 0 to disable nodogsplash
option enabled 1
# Set to 0 to disable hook that makes nodogsplash restart when the firewall restarts.
# This hook is needed as a restart of Firewall overwrites nodogsplash iptables entries.
option fwhook_enabled '1'
# WebRoot
# Default: /etc/nodogsplash/htdocs
#
# The local path where the splash page content resides.
# ie. Serve the file splash.html from this directory
#option webroot '/etc/nodogsplash/htdocs'
# Use plain configuration file
#option config '/etc/nodogsplash/nodogsplash.conf'
# Use this option to set the device nodogsplash will bind to.
# The value may be an interface section in /etc/config/network or a device name such as br-lan.
option gatewayinterface 'br-lan'
# GatewayPort
# Default: 2050
#
# Nodogsplash's own http server uses gateway address as its IP address.
# The port it listens to at that IP can be set here; default is 2050.
#
#option gatewayport '2050'
option gatewayname 'OpenWrt Nodogsplash'
option maxclients '250'
# Enables debug output (0-3)
#option debuglevel '1'
# Client timeouts in minutes
option preauthidletimeout '30'
option authidletimeout '120'
# Session Timeout is the interval after which clients are forced out (a value of 0 means never)
option sessiontimeout '1200'
# The interval in seconds at which nodogsplash checks client timeout status
option checkinterval '600'
# Enable BinAuth Support.
# If set, a program is called with several parameters on authentication (request) and deauthentication.
# Request for authentication:
# $<BinAuth> auth_client <client_mac> '<username>' '<password>'
#
# The username and password values may be empty strings and are URL encoded.
# The program is expected to output the number of seconds the client
# is to be authenticated. Zero or negative seconds will cause the authentification request
# to be rejected. The same goes for an exit code that is not 0.
# The output may contain a user specific download and upload limit in KBit/s:
# <seconds> <upload> <download>
#
# Called on authentication or deauthentication:
# $<BinAuth> <*auth|*deauth> <incoming_bytes> <outgoing_bytes> <session_start> <session_end>
#
# "client_auth": Client authenticated via this script.
# "client_deauth": Client deauthenticated by the client via splash page.
# "idle_deauth": Client was deauthenticated because of inactivity.
# "timeout_deauth": Client was deauthenticated because the session timed out.
# "ndsctl_auth": Client was authenticated manually by the ndsctl tool.
# "ndsctl_deauth": Client was deauthenticated by the ndsctl tool.
# "shutdown_deauth": Client was deauthenticated by Nodogsplash terminating.
#
# Values session_start and session_start are in seconds since 1970 or 0 for unknown/unlimited.
#
#option binauth '/bin/myauth.sh'
# Enable PreAuth Support.
#
# A simple login script is provided in the package.
# This generates a login page asking for usename and email address.
# User logins are recorded in the log file /tmp/ndslog.log
# Details of how the script works are contained in comments in the script itself.
#
# The Preauth program will output html code that will be served to the client by NDS
# Using html GET the Preauth program may call:
# /nodogsplash_preauth/ to ask the client for more information
# or
# /nodogsplash_auth/ to authenticate the client
#
# The Preauth program should append at least the client ip to the query string
# (using html input type hidden) for all calls to /nodogsplash_preauth/
# It must also obtain the client token using ndsctl (or the original query string if fas_secure_enabled=0)
# for NDS authentication when calling /nodogsplash_auth/
#
#option preauth '/usr/lib/nodogsplash/login.sh'
# Your router may have several interfaces, and you
# probably want to keep them private from the gatewayinterface.
# If so, you should block the entire subnets on those interfaces, e.g.:
#list authenticated_users 'block to 192.168.0.0/16'
#list authenticated_users 'block to 10.0.0.0/8'
# Typical ports you will probably want to open up.
#list authenticated_users 'allow tcp port 22'
#list authenticated_users 'allow tcp port 53'
#list authenticated_users 'allow udp port 53'
#list authenticated_users 'allow tcp port 80'
#list authenticated_users 'allow tcp port 443'
# Or for happy customers allow all
list authenticated_users 'allow all'
# For preauthenticated users to resolve IP addresses in their
# initial request not using the router itself as a DNS server,
# Leave commented to help prevent DNS tunnelling
#list preauthenticated_users 'allow tcp port 53'
#list preauthenticated_users 'allow udp port 53'
# Allow ports for SSH/Telnet/DNS/DHCP/HTTP/HTTPS
list users_to_router 'allow tcp port 22'
list users_to_router 'allow tcp port 23'
list users_to_router 'allow tcp port 53'
list users_to_router 'allow udp port 53'
list users_to_router 'allow udp port 67'
list users_to_router 'allow tcp port 80'
# MAC addresses that are / are not allowed to access the splash page
# Value is either 'allow' or 'block'. The allowedmac or blockedmac list is used.
#option macmechanism 'allow'
#list allowedmac '00:00:C0:01:D0:0D'
#list allowedmac '00:00:C0:01:D0:1D'
#list blockedmac '00:00:C0:01:D0:2D'
# MAC addresses that do not need to authenticate
#list trustedmac '00:00:C0:01:D0:1D'
# Nodogsplash uses specific HEXADECIMAL values to mark packets used by iptables as a bitwise mask.
# This mask can conflict with the requirements of other packages such as mwan3, sqm etc
# Any values set here are interpreted as in hex format.
#
# List: fw_mark_authenticated
# Default: 30000 (0011|0000|0000|0000|0000 binary)
#
# List: fw_mark_trusted
# Default: 20000 (0010|0000|0000|0000|0000 binary)
#
# List: fw_mark_blocked
# Default: 10000 (0001|0000|0000|0000|0000 binary)
#
#option fw_mark_authenticated '30000'
#option fw_mark_trusted '20000'
#option fw_mark_blocked '10000'

View file

@ -0,0 +1,215 @@
#!/bin/sh /etc/rc.common
#
# Startup/shutdown script for nodogsplash captive portal
#
START=95
STOP=95
USE_PROCD=1
IPT=/usr/sbin/iptables
WD_DIR=/usr/bin
# Run in PROCD (-f) and log to SYSLOG (-s)
OPTIONS="-f -s"
#
CONFIG=""
addline() {
append CONFIG "$1" "$N"
}
setup_mac_lists() {
local cfg="$1"
local macs=""
local val
append_mac() {
append macs "$1" ","
}
config_get val "$cfg" macmechanism
if [ -z "$val" ]; then
# Check if we have AllowedMACList or BlockedMACList defined they will be ignored
config_get val "$cfg" allowedmac
if [ -n "$val" ]; then
echo "Ignoring allowedmac - macmechanism not \"allow\"" >&2
fi
config_get val "$cfg" blockedmac
if [ -n "$val" ]; then
echo "Ignoring blockedmac - macmechanism not \"block\"" >&2
fi
elif [ "$val" = "allow" ]; then
config_list_foreach "$cfg" allowedmac append_mac
addline "MACmechanism allow"
addline "AllowedMACList $macs"
elif [ "$val" = "block" ]; then
config_list_foreach "$cfg" blockedmac append_mac
addline "MACmechanism block"
addline "BlockedMACList $macs"
else
echo "Invalid macmechanism '$val' - allow or block are valid." >&2
return 1
fi
macs=""
config_list_foreach "$cfg" trustedmac append_mac
if [ -n "$macs" ]; then
addline "TrustedMACList $macs"
fi
return 0
}
setup_firewall() {
local cfg="$1"
local uci_name
local val
append_firewall() {
addline " FirewallRule $1"
}
for rule in authenticated-users preauthenticated-users users-to-router trusted-users trusted-users-to-router; do
# uci does not allow dashes
uci_name=${rule//-/_}
addline "FirewallRuleSet $rule {"
config_list_foreach "$cfg" "$uci_name" append_firewall
addline "}"
config_get val "$cfg" "policy_${uci_name}"
if [ -n "$val" ]; then
addline "EmptyRuleSetPolicy $rule $val"
fi
done
}
wait_for_interface() {
local ifname="$1"
local timeout=10
for i in $(seq $timeout); do
if [ $(ip -4 addr show dev $ifname 2> /dev/null | grep -c inet) -ne 0 ]; then
break
fi
sleep 1
if [ $i = $timeout ]; then
echo "Interface $ifname not detected." >&2
return 1
fi
done
return 0
}
generate_uci_config() {
local cfg="$1"
local val
local ifname
local download
local upload
# Init config file content
CONFIG="# auto-generated config file from /etc/config/nodogsplash"
config_get val "$cfg" config
if [ -n "$val" ]; then
if [ ! -f "$val" ]; then
echo "Configuration file '$file' doesn't exist." >&2
return 1
fi
addline "$(cat $val)"
fi
config_get ifname "$cfg" gatewayinterface
# Get device name if interface name is a section name in /etc/config/network
if network_get_device tmp "$ifname"; then
ifname="$tmp"
fi
if [ -z "$ifname" ]; then
echo "Option network or gatewayinterface missing." >&2
return 1
fi
wait_for_interface "$ifname" || return 1
addline "GatewayInterface $ifname"
for option in preauth binauth \
daemon debuglevel maxclients gatewayname gatewayinterface gatewayiprange \
gatewayaddress gatewayport webroot splashpage statuspage \
redirecturl sessiontimeout preauthidletimeout authidletimeout checkinterval \
setmss mssvalue trafficcontrol downloadlimit uploadlimit \
syslogfacility ndsctlsocket fw_mark_authenticated \
fw_mark_blocked fw_mark_trusted
do
config_get val "$cfg" "$option"
if [ -n "$val" ]; then
addline "$option $val"
fi
done
for option in fasport fasremoteip faspath fas_secure_enabled ; do
config_get val "$cfg" "$option"
if [ -n "$val" ]; then
echo "Warning: nodogsplash does not support $val"
return 1
fi
done
config_get download "$cfg" downloadlimit
config_get upload "$cfg" uploadlimit
if [ -n "$upload" -o -n "$download" ]; then
addline "TrafficControl yes"
fi
setup_mac_lists "$cfg" || return 1
setup_firewall "$cfg"
echo "$CONFIG" > "/tmp/etc/nodogsplash_$cfg.conf"
return 0
}
# setup configuration and start instance
create_instance() {
local cfg="$1"
local val
config_get_bool val "$cfg" enabled 0
[ $val -gt 0 ] || return 0
if ! generate_uci_config "$cfg"; then
echo "Can not generate uci config. Will not start instance $cfg." >&2
return 1
fi
procd_open_instance $cfg
procd_set_param command /usr/bin/nodogsplash -c "/tmp/etc/nodogsplash_$cfg.conf" $OPTIONS
procd_set_param respawn
procd_set_param file "/tmp/etc/nodogsplash_$cfg.conf"
procd_close_instance
}
start_service() {
# For network_get_device()
include /lib/functions
# For nodogsplash.conf file
mkdir -p /tmp/etc/
config_load nodogsplash
config_foreach create_instance nodogsplash
}
stop_service() {
# When procd terminates nodogsplash, it does not exit fast enough.
# Otherwise procd will restart nodogsplash twice. First time starting
# nodogsplash fails, second time it succeeds.
sleep 1
}

View file

@ -0,0 +1,9 @@
#!/bin/sh
uci -q batch <<-EOF
delete firewall.nodogsplash
set firewall.nodogsplash=include
set firewall.nodogsplash.type=script
set firewall.nodogsplash.path=/usr/lib/nodogsplash/restart.sh
commit firewall
EOF

View file

@ -0,0 +1,8 @@
#!/bin/sh
# Check if nodogsplash is running
if ndsctl status &> /dev/null; then
if [ "$(uci -q get nodogsplash.@nodogsplash[0].fwhook_enabled)" = "1" ]; then
/etc/init.d/nodogsplash restart
fi
fi

View file

@ -6,13 +6,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=olsrd
PKG_SOURCE_DATE:=2022-03-18
PKG_RELEASE:=5
PKG_SOURCE_DATE:=2023-06-12
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/OLSR/olsrd.git
PKG_SOURCE_VERSION:=1e771b4d31e36f9ffd0a04c3f8f83abb803ec309
PKG_MIRROR_HASH:=2b238b179bc873902a0d094c0d3e43e0a373710763bdca4b6fec5eed431d4a8d
PKG_SOURCE_VERSION:=a9b3f1ac6e73a39b5bd97d1e66b1e039998314f5
PKG_MIRROR_HASH:=b7e1cd4b43a4d8607d6761267f23d28fb09c577d746c22ca60d2ed2fc19b1ea8
PKG_MAINTAINER:=Nick Hainke <vincent@systemli.org>
PKG_BUILD_PARALLEL:=0

File diff suppressed because it is too large Load diff

View file

@ -118,3 +118,20 @@ reload()
oonf_add_devices_to_configuration
oonf_reread_config
}
running()
{
# check if we have a pidfile and then check if that pid still exists.
# since we don't use -e this has to be explicitly returned. exit would stop the process.
test -e "/tmp/run/olsrd2.pid" && test -e "/proc/$(cat "/tmp/run/olsrd2.pid")" && return 0
return 1
}
status()
{
if running; then
echo "running"
else
echo "stopped"
fi
}

View file

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=oonf-olsrd2
PKG_RELEASE:=1
PKG_RELEASE:=2
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/OLSR/OONF.git

View file

@ -5,4 +5,7 @@ DAEMON='olsrd2'
[ -n "$IPKG_INSTROOT" ] || {
. /lib/functions/oonf_init.sh
extra_command "running" "Check if service is running"
extra_command "status" "Service status"
}

View file

@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=opennds
PKG_VERSION:=9.10.0
PKG_VERSION:=10.2.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/opennds/opennds/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=0508a52ea6b2a18365ae071c623f923680bb926605f7b0678f14ea58bbfb2aba
PKG_HASH:=c2da51e3051e390fc1ddae2a4fa751f7b62919eb8e5526710067ca4622331017
PKG_BUILD_DIR:=$(BUILD_DIR)/openNDS-$(PKG_VERSION)
PKG_MAINTAINER:=Rob White <rob@blue-wave.net>
@ -27,8 +27,8 @@ define Package/opennds
SUBMENU:=Captive Portals
SECTION:=net
CATEGORY:=Network
DEPENDS:=+iptables-nft +kmod-ipt-conntrack +kmod-ipt-nat +libmicrohttpd-no-ssl
TITLE:=Open public network gateway daemon
DEPENDS:=+libmicrohttpd-no-ssl
TITLE:=open Network Demarcation Service
URL:=https://github.com/opennds/opennds
CONFLICTS:=nodogsplash
endef
@ -38,7 +38,7 @@ define Package/opennds/description
It provides a border control gateway between a public local area network and the Internet.
It supports all scenarios ranging from small stand alone venues through to large mesh networks with multiple portal entry points.
Both the client driven Captive Portal Detection method (CPD) and gateway driven Captive Portal Identification method (CPI - RFC 8910 and RFC 8908) are supported.
This version requires iptables-nft.
This version uses nftables.
endef
define Package/opennds/install
@ -58,6 +58,7 @@ define Package/opennds/install
$(CP) $(PKG_BUILD_DIR)/linux_openwrt/opennds/files/etc/uci-defaults/40_opennds $(1)/etc/uci-defaults/
$(CP) $(PKG_BUILD_DIR)/linux_openwrt/opennds/files/usr/lib/opennds/restart.sh $(1)/usr/lib/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/binauth/binauth_log.sh $(1)/usr/lib/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/binauth/custombinauth.sh $(1)/usr/lib/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/libs/libopennds.sh $(1)/usr/lib/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/PreAuth/theme_click-to-continue-basic.sh $(1)/usr/lib/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/PreAuth/theme_click-to-continue-custom-placeholders.sh $(1)/usr/lib/opennds/
@ -65,13 +66,13 @@ define Package/opennds/install
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/PreAuth/theme_user-email-login-custom-placeholders.sh $(1)/usr/lib/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/libs/get_client_interface.sh $(1)/usr/lib/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/libs/client_params.sh $(1)/usr/lib/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/libs/unescape.sh $(1)/usr/lib/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/libs/authmon.sh $(1)/usr/lib/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/libs/dnsconfig.sh $(1)/usr/lib/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/libs/download_resources.sh $(1)/usr/lib/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/libs/post-request.php $(1)/usr/lib/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/fas-aes/fas-aes.php $(1)/etc/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/fas-hid/fas-hid.php $(1)/etc/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/fas-hid/fas-hid-https.php $(1)/etc/opennds/
$(CP) $(PKG_BUILD_DIR)/forward_authentication_service/fas-aes/fas-aes-https.php $(1)/etc/opennds/
endef