├── .github └── workflows │ └── build-release.yml ├── Makefile ├── README.md ├── compile.sh ├── files ├── 18-edgerouter ├── cbi_tab.lua ├── edgerouter.config ├── edgerouter.fw ├── edgerouter.init └── edgerouter.lua └── src ├── Makefile ├── api.c ├── arp.c ├── arp.h └── arpspoof.c /.github/workflows/build-release.yml: -------------------------------------------------------------------------------- 1 | name: Build and Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - "*" 7 | 8 | jobs: 9 | release: 10 | name: Build for ${{ matrix.arch }} 11 | runs-on: ubuntu-latest 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | include: 16 | - arch: aarch64_cortex-a53 17 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/bcm27xx/bcm2710 18 | sdk_name: -sdk-bcm27xx-bcm2710_ 19 | - arch: aarch64_cortex-a72 20 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/mvebu/cortexa72 21 | sdk_name: -sdk-mvebu-cortexa72_ 22 | - arch: aarch64_generic 23 | sdk_url_path: http://downloads.openwrt.org/snapshots/targets/layerscape/armv8_64b 24 | sdk_name: -sdk-layerscape-armv8_64b_ 25 | - arch: arm_arm1176jzf-s_vfp 26 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/bcm27xx/bcm2708 27 | sdk_name: -sdk-bcm27xx-bcm2708_ 28 | - arch: arm_arm926ej-s 29 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/at91/legacy 30 | sdk_name: -sdk-at91-legacy_ 31 | - arch: arm_cortex-a15_neon-vfpv4 32 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/ipq806x/generic 33 | sdk_name: -sdk-ipq806x-generic_ 34 | - arch: arm_cortex-a5-vfpv4 35 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/at91/sama5 36 | sdk_name: -sdk-at91-sama5_ 37 | - arch: arm_cortex-a7_neon-vfpv4 38 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/bcm27xx/bcm2709 39 | sdk_name: -sdk-bcm27xx-bcm2709_ 40 | - arch: arm_cortex-a8_vfpv3 41 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/sunxi/cortexa8 42 | sdk_name: -sdk-sunxi-cortexa8_ 43 | - arch: arm_cortex-a9 44 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/bcm53xx/generic 45 | sdk_name: -sdk-bcm53xx-generic_ 46 | - arch: arm_cortex-a9_neon 47 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/imx6/generic 48 | sdk_name: -sdk-imx6_ 49 | - arch: arm_cortex-a9_vfpv3 50 | sdk_url_path: https://downloads.openwrt.org/releases/19.07.2/targets/mvebu/cortexa9 51 | sdk_name: -sdk-19.07.2-mvebu-cortexa9_ 52 | - arch: arm_cortex-a9_vfpv3-d16 53 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/mvebu/cortexa9 54 | sdk_name: -sdk-mvebu-cortexa9_ 55 | - arch: arm_fa526 56 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/gemini/generic 57 | sdk_name: -sdk-gemini_ 58 | - arch: arm_mpcore 59 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/oxnas/ox820 60 | sdk_name: -sdk-oxnas-ox820_ 61 | - arch: arm_mpcore_vfp 62 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/cns3xxx/generic 63 | sdk_name: -sdk-cns3xxx_ 64 | - arch: arm_xscale 65 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/kirkwood/generic 66 | sdk_name: -sdk-kirkwood_ 67 | - arch: i386_pentium 68 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/x86/legacy 69 | sdk_name: -sdk-x86-legacy_ 70 | - arch: i386_pentium4 71 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/x86/generic 72 | sdk_name: -sdk-x86-generic_ 73 | - arch: mips64_octeon 74 | sdk_url_path: http://downloads.openwrt.org/releases/18.06.5/targets/octeon/generic 75 | sdk_name: -sdk-18.06.5-octeon_ 76 | - arch: mips64_octeonplus 77 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/octeon/generic 78 | sdk_name: -sdk-octeon_ 79 | - arch: mipsel_24kc 80 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/ramips/mt7620 81 | sdk_name: -sdk-ramips-mt7620_ 82 | - arch: mipsel_24kc_24kf 83 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/pistachio/generic 84 | sdk_name: -sdk-pistachio_ 85 | - arch: mipsel_74kc 86 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/bcm47xx/mips74k 87 | sdk_name: -sdk-bcm47xx-mips74k_ 88 | - arch: mipsel_mips32 89 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/bcm47xx/generic 90 | sdk_name: -sdk-bcm47xx-generic_ 91 | - arch: mips_24kc 92 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/ath79/generic 93 | sdk_name: -sdk-ath79-generic_ 94 | - arch: mips_mips32 95 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/bcm63xx/generic 96 | sdk_name: -sdk-bcm63xx-generic_ 97 | - arch: x86_64 98 | sdk_url_path: https://downloads.openwrt.org/snapshots/targets/x86/64 99 | sdk_name: -sdk-x86-64_ 100 | # - arch: arc_arc700 101 | # sdk_url_path: https://downloads.openwrt.org/snapshots/targets/arc770/generic 102 | # sdk_name: -sdk-arc770-generic_ 103 | # - arch: arc_archs 104 | # sdk_url_path: https://downloads.openwrt.org/snapshots/targets/archs38/generic 105 | # sdk_name: -sdk-archs38-generic_ 106 | # - arch: armeb_xscale 107 | # sdk_url_path: https://downloads.openwrt.org/snapshots/targets/ixp4xx/generic 108 | # sdk_name: -sdk-ixp4xx-generic_ 109 | # - arch: powerpc_464fp 110 | # sdk_url_path: https://downloads.openwrt.org/snapshots/targets/apm821xx/nand 111 | # sdk_name: -sdk-apm821xx-nand_ 112 | # - arch: powerpc_8540 113 | # sdk_url_path: https://downloads.openwrt.org/snapshots/targets/mpc85xx/generic 114 | # sdk_name: -sdk-mpc85xx-generic_ 115 | 116 | env: 117 | SDK_URL_PATH: ${{ matrix.sdk_url_path }} 118 | SDK_NAME: ${{ matrix.sdk_name }} 119 | ARCH: ${{ matrix.arch }} 120 | CACHE_DIR: ~/cache 121 | steps: 122 | - name: Checkout 123 | uses: actions/checkout@v2 124 | 125 | - name: Setup Cache 126 | uses: actions/cache@v2 127 | with: 128 | path: ${{ env.CACHE_DIR }} 129 | key: ${{ runner.os }}:edgerouter:${{ env.ARCH }}:release:cache:${{ github.run_number }} 130 | restore-keys: | 131 | ${{ runner.os }}:edgerouter:${{ env.ARCH }}:cache: 132 | 133 | - name: Install Dependencies 134 | run: | 135 | sudo apt-get update && \ 136 | sudo apt-get install -yq gettext libncurses5-dev xsltproc 137 | 138 | - name: Prepare SDK Home 139 | run: | 140 | echo "SDK_HOME=$(mktemp -d)" >> $GITHUB_ENV 141 | 142 | - name: Build package 143 | run: sh compile.sh 144 | 145 | - name: Release and Upload Assets 146 | uses: softprops/action-gh-release@v1 147 | with: 148 | files: "*.ipk" 149 | env: 150 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 151 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # Copyright (C) 2017 OpenWrt.org 4 | # 5 | # This is free software, licensed under the GNU General Public License v2. 6 | # See /LICENSE for more information. 7 | # 8 | 9 | include $(TOPDIR)/rules.mk 10 | 11 | PKG_NAME:=edgerouter 12 | PKG_VERSION:=1.0.0 13 | PKG_RELEASE:=1 14 | 15 | include $(INCLUDE_DIR)/package.mk 16 | 17 | define Package/edgerouter 18 | SECTION:=base 19 | CATEGORY:=gl-inet 20 | TITLE:=GL iNet edgerouter mode 21 | DEPENDS:=+luci-compat 22 | endef 23 | 24 | define Package/edgerouter/description 25 | Openvpn server endpoint api for gl-inet. 26 | endef 27 | 28 | ifdef CONFIG_TARGET_ipq806x 29 | ifeq ($(CONFIG_GCC_VERSION_4_8),y) 30 | TARGET_CFLAGS += -std=gnu99 31 | endif 32 | MAKE_FLAGS += \ 33 | CFLAGS+="$(TARGET_CFLAGS) -Wall -DIPQ40XX" 34 | endif 35 | 36 | define Build/Prepare 37 | mkdir -p $(PKG_BUILD_DIR) 38 | $(CP) ./src/* $(PKG_BUILD_DIR) 39 | endef 40 | 41 | define Build/Compile 42 | $(call Build/Compile/Default) 43 | endef 44 | 45 | 46 | define Package/edgerouter/install 47 | $(INSTALL_DIR) $(1)/usr/bin 48 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/lancover $(1)/usr/bin 49 | 50 | $(INSTALL_DIR) $(1)/etc/init.d 51 | $(INSTALL_BIN) ./files/edgerouter.init $(1)/etc/init.d/edgerouter 52 | $(INSTALL_BIN) ./files/edgerouter.fw $(1)/etc/ 53 | 54 | $(INSTALL_DIR) $(1)/etc/hotplug.d/iface 55 | $(INSTALL_BIN) ./files/18-edgerouter $(1)/etc/hotplug.d/iface 56 | 57 | $(INSTALL_DIR) $(1)/etc/config 58 | $(INSTALL_DATA) ./files/edgerouter.config $(1)/etc/config/edgerouter 59 | 60 | $(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/edgerouter 61 | $(INSTALL_DATA) ./files/cbi_tab.lua $(1)/usr/lib/lua/luci/model/cbi/edgerouter 62 | 63 | $(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller/admin 64 | $(INSTALL_DATA) ./files/edgerouter.lua $(1)/usr/lib/lua/luci/controller/admin 65 | 66 | #$(INSTALL_DIR) $(1)/usr/lib/gl 67 | #$(INSTALL_BIN) $(PKG_BUILD_DIR)/libedgerouterapi.so $(1)/usr/lib/gl 68 | #$(LN) /usr/lib/gl/libedgerouterapi.so $(1)/usr/lib/ 69 | endef 70 | 71 | define Package/edgerouter/postinst 72 | #!/bin/sh 73 | uci add ucitrack edgerouter 74 | uci set ucitrack.@edgerouter[0]=edgerouter 75 | uci set ucitrack.@edgerouter[0].exec="/bin/sh /etc/rc.common /etc/init.d/edgerouter restart" 76 | uci commit ucitrack 77 | /etc/init.d/ucitrack restart 78 | 79 | exit 0 80 | endef 81 | 82 | 83 | $(eval $(call BuildPackage,edgerouter)) 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # edgerouter 2 | 使用这个插件,可以一键设置旁路由,解决旁路由设置过程中的所有烦恼 3 | 4 | ## 使用方法 5 | 详情见glinet中文论坛 https://forum.gl-inet.cn/forum.php?mod=viewthread&tid=154&extra=page%3D1 6 | -------------------------------------------------------------------------------- /compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | # 3 | # Copyright (C) 2021 luochongjun 4 | # 5 | 6 | dir="$(cd "$(dirname "$0")" ; pwd)" 7 | 8 | package_name="edgerouter" 9 | 10 | cache_dir=${CACHE_DIR:-"~/cache"} 11 | 12 | sdk_url_path=${SDK_URL_PATH:-"https://downloads.openwrt.org/snapshots/targets/x86/64"} 13 | sdk_name=${SDK_NAME:-"-sdk-x86-64_"} 14 | 15 | sdk_home=${SDK_HOME:-"~/sdk"} 16 | 17 | sdk_home_dir="$(eval echo "$sdk_home")" 18 | 19 | test -d "$sdk_home_dir" || mkdir -p "$sdk_home_dir" 20 | 21 | sdk_dir="$(eval echo "$cache_dir/sdk")" 22 | dl_dir="$(eval echo "$cache_dir/dl")" 23 | feeds_dir="$(eval echo "$cache_dir/feeds")" 24 | 25 | test -d "$sdk_dir" || mkdir -p "$sdk_dir" 26 | test -d "$dl_dir" || mkdir -p "$dl_dir" 27 | test -d "$feeds_dir" || mkdir -p "$feeds_dir" 28 | 29 | cd "$sdk_dir" 30 | 31 | if ! ( wget -q -O - "$sdk_url_path/sha256sums" | \ 32 | grep -- "$sdk_name" > sha256sums.small 2>/dev/null ) ; then 33 | echo "Can not find ${sdk_name} file in sha256sums." 34 | exit 1 35 | fi 36 | 37 | sdk_file="$(cut -d' ' -f2 < sha256sums.small | sed 's/*//g')" 38 | 39 | if ! sha256sum -c ./sha256sums.small >/dev/null 2>&1 ; then 40 | wget -q -O "$sdk_file" "$sdk_url_path/$sdk_file" 41 | 42 | if ! sha256sum -c ./sha256sums.small >/dev/null 2>&1 ; then 43 | echo "SDK can not be verified!" 44 | exit 1 45 | fi 46 | fi 47 | 48 | cd "$dir" 49 | 50 | file "$sdk_dir/$sdk_file" 51 | tar -Jxf "$sdk_dir/$sdk_file" -C "$sdk_home_dir" --strip=1 52 | 53 | cd "$sdk_home_dir" 54 | 55 | ( test -d "dl" && rm -rf "dl" ) || true 56 | ( test -d "feeds" && rm -rf "feeds" ) || true 57 | 58 | ln -sf "$dl_dir" "dl" 59 | ln -sf "$feeds_dir" "feeds" 60 | 61 | cp -f feeds.conf.default feeds.conf 62 | 63 | # use github repositories 64 | sed -i \ 65 | -e 's#git.openwrt.org/openwrt/openwrt#github.com/openwrt/openwrt#' \ 66 | -e 's#git.openwrt.org/feed/packages#github.com/openwrt/packages#' \ 67 | -e 's#git.openwrt.org/project/luci#github.com/openwrt/luci#' \ 68 | -e 's#git.openwrt.org/feed/telephony#github.com/openwrt/telephony#' \ 69 | feeds.conf 70 | 71 | ./scripts/feeds update -a 72 | 73 | ( test -d "feeds/packages/net/$package_name" && \ 74 | rm -rf "feeds/packages/net/$package_name" ) || true 75 | 76 | 77 | ln -sf "$dir" "package/$package_name" 78 | 79 | ./scripts/feeds install -a 80 | 81 | make defconfig 82 | 83 | make package/${package_name}/clean 84 | make package/${package_name}/compile V=s 85 | 86 | cd "$dir" 87 | 88 | find "$sdk_home_dir/bin/" -type f -exec ls -lh {} \; 89 | 90 | find "$sdk_home_dir/bin/" -type f -name "${package_name}*.ipk" -exec cp -f {} "$dir" \; 91 | -------------------------------------------------------------------------------- /files/18-edgerouter: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | [ "$ACTION" == "ifup" -o "$ACTION" == "ifdown" ] || exit 1 4 | [ -n "$INTERFACE" ] || exit 2 5 | 6 | [ "$INTERFACE" = "wan" -o "$INTERFACE" = "wwan" ] || exit 1 7 | 8 | if [ "$ACTION" == "ifup" ]; then 9 | [ -n "$DEVICE" ] || exit 3 10 | fi 11 | 12 | [ "$ACTION" == "ifdown" ] && { 13 | /etc/init.d/edgerouter stop 14 | } 15 | 16 | [ "$ACTION" == "ifup" ] && { 17 | /etc/init.d/edgerouter restart 18 | } 19 | -------------------------------------------------------------------------------- /files/cbi_tab.lua: -------------------------------------------------------------------------------- 1 | m = Map("edgerouter", translate("旁路由模式"), translate("使用一键旁路由模式请将设备的WAN口连接到上游路由器的LAN口,勾选启用并保存应用")) -- cbi_file is the config file in /etc/config 2 | d = m:section(TypedSection, "global", translate("全局设置")) -- info is the section called info in cbi_file 3 | a = d:option(Flag, "enabled", translate("启用")); a.optional=false; a.rmempty = false; -- name is the option in the cbi_file 4 | return m 5 | -------------------------------------------------------------------------------- /files/edgerouter.config: -------------------------------------------------------------------------------- 1 | config global 'global' 2 | option enabled '0' 3 | -------------------------------------------------------------------------------- /files/edgerouter.fw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | create() 4 | { 5 | local LANIP=$(uci get network.lan.ipaddr) 6 | 7 | iptables -N EDGEROUTER_INPUT 2>/dev/null 8 | iptables -C INPUT -j EDGEROUTER_INPUT 9 | [ ! "$?" = "0" ] && iptables -I INPUT -j EDGEROUTER_INPUT 10 | iptables -F EDGEROUTER_INPUT 2>/dev/null 11 | iptables -I EDGEROUTER_INPUT -j ACCEPT 12 | 13 | iptables -N EDGEROUTER_FORWARD 2>/dev/null 14 | iptables -C FORWARD -j EDGEROUTER_FORWARD 15 | [ ! "$?" = "0" ] && iptables -I FORWARD -j EDGEROUTER_FORWARD 16 | iptables -F EDGEROUTER_FORWARD 2>/dev/null 17 | iptables -I EDGEROUTER_FORWARD -j ACCEPT 18 | 19 | [ -z "$LANIP" ] && return 20 | iptables -t nat -N EDGEROUTER_PREROUTING 2>/dev/null 21 | iptables -t nat -C PREROUTING -j EDGEROUTER_PREROUTING 22 | [ ! "$?" = "0" ] && iptables -t nat -I PREROUTING -j EDGEROUTER_PREROUTING 23 | iptables -t nat -F EDGEROUTER_PREROUTING 2>/dev/null 24 | iptables -t nat -I EDGEROUTER_PREROUTING -p udp --dport 53 -j DNAT --to "$LANIP" 25 | iptables -t nat -I EDGEROUTER_PREROUTING -p tcp --dport 53 -j DNAT --to "$LANIP" 26 | } 27 | 28 | remove() 29 | { 30 | iptables -t nat -D PREROUTING -j EDGEROUTER_PREROUTING 2>/dev/null 31 | iptables -t nat -F EDGEROUTER_PREROUTING 2>/dev/null 32 | iptables -t nat -X EDGEROUTER_PREROUTING 2>/dev/null 33 | 34 | iptables -D FORWARD -j EDGEROUTER_FORWARD 2>/dev/null 35 | iptables -F EDGEROUTER_FORWARD 2>/dev/null 36 | iptables -X EDGEROUTER_FORWARD 2>/dev/null 37 | 38 | iptables -D INPUT -j EDGEROUTER_INPUT 2>/dev/null 39 | iptables -F EDGEROUTER_INPUT 2>/dev/null 40 | iptables -X EDGEROUTER_INPUT 2>/dev/null 41 | } 42 | 43 | enabled=`uci get edgerouter.global.enabled` 44 | if [ "$enabled" = "1" ];then 45 | create 46 | else 47 | remove 48 | fi 49 | 50 | -------------------------------------------------------------------------------- /files/edgerouter.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | 3 | START=99 4 | STOP=1 5 | USE_PROCD=1 6 | 7 | start_service() { 8 | local enabled=`uci get edgerouter.global.enabled` 9 | local wanif=`uci get network.wan.ifname` 10 | if [ "$enabled" != "1" ];then 11 | return 12 | fi 13 | [ -z "$wanif" ] && wanif="eth0" 14 | 15 | ROUTEINFO="$(route -n |grep "$wanif\|wlan-sta" |grep -m 1 '^0.0.0.0\s')" 16 | GATEWAYIP=$(echo $ROUTEINFO | awk '{ print $2}') 17 | DEVICE=$(echo $ROUTEINFO | awk '{ print $8}') 18 | 19 | [ -z "$DEVICE" ] && return 20 | [ -z "$GATEWAYIP" ] && return 21 | 22 | /etc/edgerouter.fw 23 | 24 | procd_open_instance 25 | procd_set_param command /usr/bin/lancover -i "$DEVICE" -t 0.0.0.0 -s "$GATEWAYIP" -l 1 26 | procd_set_param respawn ${threshold:-1} ${timeout:-5} ${retry:-0} 27 | 28 | procd_close_instance 29 | } 30 | 31 | stop_service() { 32 | /etc/edgerouter.fw 33 | } 34 | -------------------------------------------------------------------------------- /files/edgerouter.lua: -------------------------------------------------------------------------------- 1 | module("luci.controller.admin.edgerouter", package.seeall) 2 | function index() 3 | entry({"admin", "network", "edgerouter"}, cbi("edgerouter/cbi_tab"), translate("一键旁路由"), 1) 4 | end 5 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS+= 3 | LDFLAGS+= 4 | 5 | all: lancover 6 | @echo "compile done" 7 | 8 | lancover: arpspoof.o arp.o 9 | $(CC) arpspoof.o arp.o -o $@ $(LDFLAGS) 10 | 11 | clean: 12 | rm $(PROC) $(OBJS) 13 | 14 | .PHONY:all clean 15 | -------------------------------------------------------------------------------- /src/api.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define APPNMAE "SideRouter" 14 | 15 | char *get_package_name(void) 16 | { 17 | return APPNMAE; 18 | } 19 | 20 | /*** 21 | * @api {post} /siderouter/set_config /siderouter/set_config 22 | * @apiGroup siderouter 23 | * @apiVersion 1.0.0 24 | * @apiDescription Remove the software. 25 | * @apiHeader {string} Authorization Users unique token. 26 | * @apiSuccess {integer} code return code. 27 | * @apiSuccess (Code) {integer} 0 success. 28 | * @apiSuccess (Code) {integer} -1 Invalid user, permission denied or not logged in! 29 | */ 30 | int set_config(json_object* input,json_object* output) 31 | { 32 | bool enable = gjson_get_boolean(input, "enabled"); 33 | 34 | struct uci_context* ctx = guci2_init(); 35 | if(enable){ 36 | guci2_set(ctx, "siderouter.global.enabled", "1"); 37 | guci2_commit(ctx, "siderouter"); 38 | guci2_free(ctx); 39 | execCommand("/etc/init.d/siderouter start"); 40 | } 41 | else 42 | { 43 | guci2_set(ctx, "siderouter.global.enabled", "0"); 44 | guci2_commit(ctx, "siderouter"); 45 | guci2_free(ctx); 46 | execCommand("/etc/init.d/siderouter stop"); 47 | } 48 | 49 | 50 | return 0; 51 | 52 | } 53 | 54 | /*** 55 | * @api {get} /siderouter/get_config /siderouter/get_config 56 | * @apiGroup siderouter 57 | * @apiVersion 1.0.0 58 | * @apiDescription Get the list of user installed software. 59 | * @apiHeader {string} Authorization Users unique token. 60 | * @apiSuccess {integer} code return code. 61 | * @apiSuccess (Code) {integer} 0 success. 62 | * @apiSuccess (Code) {integer} -1 Invalid user, permission denied or not logged in! 63 | */ 64 | int get_config(json_object* input,json_object* output) 65 | { 66 | char enable[3]={0}; 67 | 68 | struct uci_context* ctx = guci2_init(); 69 | guci2_get(ctx, "siderouter.global.enabled", enable ); 70 | guci2_free(ctx); 71 | 72 | if(strcmp(enable,"1")==0){ 73 | gjson_add_boolean(output, "enabled",1); 74 | } 75 | else 76 | { 77 | gjson_add_boolean(output, "enabled",0); 78 | } 79 | 80 | return 0; 81 | } 82 | 83 | /** The implementation of the GetAPIFunctions function **/ 84 | #include 85 | 86 | static api_info_t gl_lstCgiApiFuctionInfo[]={ 87 | map("/siderouter/set_config","post",set_config), 88 | map("/siderouter/get_config","get",get_config), 89 | }; 90 | 91 | api_info_t* get_api_entity(int* pLen) 92 | { 93 | (*pLen)=sizeof(gl_lstCgiApiFuctionInfo)/sizeof(gl_lstCgiApiFuctionInfo[0]); 94 | return gl_lstCgiApiFuctionInfo; 95 | } 96 | -------------------------------------------------------------------------------- /src/arp.c: -------------------------------------------------------------------------------- 1 | #include "arp.h" 2 | 3 | #include /* socket() */ 4 | #include /* ioctl() */ 5 | #include /* inet_aton(), inet_addr(), etc. */ 6 | #include /* ether_aton() etc. */ 7 | #include /* struct ifreq */ 8 | #include /* struct sockaddr_ll */ 9 | #include /* close() */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | int arp_cache_lookup(in_addr_t ip, const char* dev_name, 17 | int* arp_flags_out, struct ether_addr* ether_out) 18 | { 19 | int sock = socket(AF_INET, SOCK_DGRAM, 0); 20 | if (sock < 0) { 21 | perror("socket()"); 22 | close(sock); 23 | return -1; 24 | } 25 | 26 | struct arpreq arp; 27 | struct sockaddr_in* sin; 28 | 29 | memset((void*) &arp, 0, sizeof(arp)); 30 | strncpy(arp.arp_dev, dev_name, sizeof(arp.arp_dev)); 31 | 32 | sin = (struct sockaddr_in*) &arp.arp_pa; 33 | sin->sin_family = AF_INET; 34 | sin->sin_addr.s_addr = ip; 35 | 36 | if (ioctl(sock, SIOCGARP, (void*) &arp) < 0) { 37 | perror("SIOCGARP"); 38 | close(sock); 39 | return -1; 40 | } 41 | 42 | close(sock); 43 | if (ether_out) 44 | memcpy(ether_out->ether_addr_octet, arp.arp_ha.sa_data, ETH_ALEN); 45 | 46 | if (arp_flags_out) 47 | *arp_flags_out = arp.arp_flags; 48 | 49 | return 1; 50 | } 51 | 52 | static int force_arp(in_addr_t dst_ip) 53 | { 54 | int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 55 | if (fd < 0) { 56 | perror("socket()"); 57 | return -1; 58 | } 59 | 60 | struct sockaddr_in sin; 61 | memset((void*) &sin, 0, sizeof(sin)); 62 | 63 | sin.sin_family = AF_INET; 64 | sin.sin_addr.s_addr = dst_ip; 65 | sin.sin_port = htons(67); 66 | 67 | sendto(fd, NULL, 0, 0, (struct sockaddr*) &sin, sizeof(sin)); 68 | close(fd); 69 | 70 | return 1; 71 | } 72 | 73 | int find_mac_addr(in_addr_t ip, const char* dev_name, struct ether_addr* ether_out) 74 | { 75 | int max_loop = 3; 76 | int arp_flags = 0; 77 | do { 78 | if (arp_cache_lookup(ip, dev_name, &arp_flags, ether_out) > 0 && arp_flags == 0x2) 79 | return 1; 80 | 81 | force_arp(ip); 82 | sleep(1); 83 | } while (--max_loop > 0 && !arp_flags); 84 | 85 | return arp_cache_lookup(ip, dev_name, NULL, ether_out); 86 | } 87 | 88 | int send_arp_to(const struct arp_packet* pkt, int raw_sock_fd, int if_index) 89 | { 90 | struct sockaddr_ll dst_addr; 91 | memset((void*) &dst_addr, 0, sizeof(dst_addr)); 92 | 93 | dst_addr.sll_ifindex = if_index; 94 | dst_addr.sll_halen = ETH_ALEN; 95 | 96 | dst_addr.sll_addr[0] = pkt->ap_eth_dhost[0]; 97 | dst_addr.sll_addr[1] = pkt->ap_eth_dhost[1]; 98 | dst_addr.sll_addr[2] = pkt->ap_eth_dhost[2]; 99 | dst_addr.sll_addr[3] = pkt->ap_eth_dhost[3]; 100 | dst_addr.sll_addr[4] = pkt->ap_eth_dhost[4]; 101 | dst_addr.sll_addr[5] = pkt->ap_eth_dhost[5]; 102 | 103 | ssize_t sent = sendto(raw_sock_fd, (void*) pkt, sizeof(struct arp_packet), 104 | 0, (struct sockaddr*) &dst_addr, sizeof(dst_addr)); 105 | 106 | if (sent < 0) { 107 | perror("sendto()"); 108 | return -1; 109 | } 110 | 111 | return sent; 112 | } 113 | 114 | struct arp_packet* create_arp_packet(const char* eth_dhost, const char* eth_shost, 115 | int op_code, 116 | const char* sendr_mac, const char* sendr_ip, 117 | const char* trgt_mac, const char* trgt_ip) 118 | { 119 | struct arp_packet* ap = (struct arp_packet*) malloc(sizeof(struct arp_packet)); 120 | 121 | /* setup Ethernet frame header */ 122 | memcpy(ap->ap_eth_dhost, ether_aton(eth_dhost)->ether_addr_octet, ETH_ALEN); 123 | memcpy(ap->ap_eth_shost, ether_aton(eth_shost)->ether_addr_octet, ETH_ALEN); 124 | ap->ap_eth_type = htons(ETHERTYPE_ARP); 125 | 126 | int spa = inet_addr(sendr_ip); 127 | int tpa = inet_addr(trgt_ip); 128 | 129 | ap->ap_hrd = htons(1); /* Ethernet */ 130 | ap->ap_pro = htons(0x0800); /* Ipv4 */ 131 | ap->ap_hln = ETH_ALEN; 132 | ap->ap_pln = 4; 133 | ap->ap_op = htons(op_code); 134 | memcpy(ap->ap_sha, ether_aton(sendr_mac)->ether_addr_octet, ETH_ALEN); 135 | memcpy(ap->ap_spa, (void*) &spa, sizeof(ap->ap_spa)); 136 | memcpy(ap->ap_tha, ether_aton(trgt_mac)->ether_addr_octet, ETH_ALEN); 137 | memcpy(ap->ap_tpa, (void*) &tpa, sizeof(ap->ap_tpa)); 138 | 139 | return ap; 140 | } 141 | 142 | struct arp_packet* create_arp_reply_packet(const char* sendr_mac, const char* sendr_ip, 143 | const char* trgt_mac, const char* trgt_ip) 144 | { 145 | return create_arp_packet(trgt_mac, sendr_mac, ARPOP_REPLY, 146 | sendr_mac, sendr_ip, trgt_mac, trgt_ip); 147 | } 148 | 149 | struct arp_packet* create_arp_request_packet(const char* sendr_mac, const char* sendr_ip, const char* trgt_ip) 150 | { 151 | return create_arp_packet("ff:ff:ff:ff:ff:ff", sendr_mac, ARPOP_REQUEST, 152 | sendr_mac, sendr_ip, "00:00:00:00:00:00", trgt_ip); 153 | } 154 | -------------------------------------------------------------------------------- /src/arp.h: -------------------------------------------------------------------------------- 1 | #ifndef ARP_H 2 | #define ARP_H 3 | 4 | #include 5 | #include /* struct ether_header */ 6 | #include /* struct arphdr, etc. */ 7 | #include /* in_addr_t, struct in_addr, sockaddr_in, etc. */ 8 | 9 | struct arp_packet 10 | { 11 | struct ether_header ap_eth; /* ethernet frame header */ 12 | 13 | struct arphdr ap_f_hdr; /* fixed-size header */ 14 | u_int8_t ap_sha[ETH_ALEN]; /* sender hardware address */ 15 | u_int8_t ap_spa[4]; /* sender protocol address */ 16 | u_int8_t ap_tha[ETH_ALEN]; /* target hardware address */ 17 | u_int8_t ap_tpa[4]; /* target protocol address */ 18 | } __attribute__ ((__packed__)); 19 | 20 | #define ap_eth_dhost ap_eth.ether_dhost 21 | #define ap_eth_shost ap_eth.ether_shost 22 | #define ap_eth_type ap_eth.ether_type 23 | 24 | #define ap_hrd ap_f_hdr.ar_hrd 25 | #define ap_pro ap_f_hdr.ar_pro 26 | #define ap_hln ap_f_hdr.ar_hln 27 | #define ap_pln ap_f_hdr.ar_pln 28 | #define ap_op ap_f_hdr.ar_op 29 | 30 | 31 | int arp_cache_lookup(in_addr_t ip, const char* dev_name, 32 | int* arp_flags, struct ether_addr* ether_out); 33 | 34 | int find_mac_addr(in_addr_t ip, const char* dev_name, struct ether_addr* ether_out); 35 | 36 | int send_arp_to(const struct arp_packet* pkt, int raw_sock_fd, int if_index); 37 | 38 | struct arp_packet* create_arp_packet(const char* eth_dhost, const char* eth_shost, 39 | int op_code, 40 | const char* sendr_mac, const char* sendr_ip, 41 | const char* trgt_mac, const char* trgt_ip); 42 | 43 | struct arp_packet* create_arp_reply_packet(const char* sendr_mac, const char* sendr_ip, 44 | const char* trgt_mac, const char* trgt_ip); 45 | 46 | struct arp_packet* create_arp_request_packet(const char* sendr_mac, const char* sendr_ip, const char* trgt_ip); 47 | 48 | #endif // ARP_H 49 | -------------------------------------------------------------------------------- /src/arpspoof.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "arp.h" 16 | 17 | int mac_from_iface(const char* iface_name, struct ether_addr* ether_out) 18 | { 19 | int sock = socket(AF_INET, SOCK_DGRAM, 0); 20 | if (sock < 0) { 21 | perror("socket()"); 22 | return -1; 23 | } 24 | 25 | struct ifreq ifr; 26 | memset((void*) &ifr, 0, sizeof(ifr)); 27 | 28 | strncpy(ifr.ifr_name, iface_name, sizeof(ifr.ifr_name)); 29 | 30 | if (ioctl(sock, SIOCGIFHWADDR, (void*) &ifr) < 0) { 31 | perror("ioctl()"); 32 | return -1; 33 | } 34 | 35 | memcpy(ether_out->ether_addr_octet, ifr.ifr_hwaddr.sa_data, ETH_ALEN); 36 | return 1; 37 | } 38 | 39 | void usage() 40 | { 41 | printf("Usage:\n"); 42 | printf(" lancover -i interface -t target_ip -s spoofing_host [-l interval]\n"); 43 | printf("Example:\n"); 44 | printf(" lancover -i eth00 -t 192.168.0.101 -s 192.168.0.1\n"); 45 | } 46 | 47 | int main(int argc, char* argv[]) 48 | { 49 | if (argc < 7) { 50 | usage(); 51 | return 0; 52 | } 53 | 54 | int ifname_idx = -1; 55 | int targetip_idx = -1; 56 | int hostip_idx = -1; 57 | int interval = -1; 58 | 59 | for (int i = 1; i < argc; i++) { 60 | if (argv[i][0] == '-') { 61 | switch (argv[i][1]) { 62 | case 'i' : ifname_idx = ++i; 63 | break; 64 | case 't' : targetip_idx = ++i; 65 | break; 66 | case 's' : hostip_idx = ++i; 67 | break; 68 | case 'l' : interval = atoi(argv[++i]); 69 | } 70 | } 71 | } 72 | 73 | if (ifname_idx < 0 || targetip_idx < 0 || hostip_idx < 0) { 74 | usage(); 75 | return 0; 76 | } 77 | 78 | if (interval <= 0) 79 | interval = 2; 80 | 81 | struct ether_addr iface_hwaddr; 82 | if (mac_from_iface(argv[ifname_idx], &iface_hwaddr) < 0) { 83 | return -1; 84 | } 85 | 86 | struct ether_addr target_hwaddr; 87 | if (strcmp(argv[targetip_idx],"0.0.0.0")==0){ 88 | memset(&target_hwaddr,0xff,sizeof(target_hwaddr)); 89 | } 90 | else if (find_mac_addr(inet_addr(argv[targetip_idx]), argv[ifname_idx], &target_hwaddr) < 0) { 91 | return -1; 92 | } 93 | 94 | char sendr_mac[18]; /* e.g. 'aa:bb:cc:11:22:33' = 17 chars + \0 = 18 chars */ 95 | char target_mac[18]; 96 | 97 | memset(sendr_mac, 0, sizeof(sendr_mac)); 98 | memset(target_mac, 0, sizeof(target_mac)); 99 | 100 | strncpy(sendr_mac, ether_ntoa(&iface_hwaddr), sizeof(sendr_mac)); 101 | strncpy(target_mac, ether_ntoa(&target_hwaddr), sizeof(target_mac)); 102 | 103 | struct arp_packet* arp = create_arp_reply_packet(sendr_mac, argv[hostip_idx], 104 | target_mac, argv[targetip_idx]); 105 | 106 | int sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); 107 | if (sock < 0) { 108 | perror("socket()"); 109 | return -1; 110 | } 111 | 112 | int if_idx = if_nametoindex(argv[ifname_idx]); 113 | if (if_idx == 0) { 114 | perror("if_nametoindex()"); 115 | return -1; 116 | } 117 | 118 | printf("Interval: per %ds\n", interval); 119 | while (1) { 120 | if (send_arp_to(arp, sock, if_idx) > 0) { 121 | //printf("send ARP Reply: %s is at %s --to-> %s\n", argv[hostip_idx], sendr_mac, argv[targetip_idx]); 122 | } 123 | 124 | usleep(interval*1000); 125 | } 126 | 127 | return 0; 128 | } 129 | --------------------------------------------------------------------------------