Author: WhoAmI
Date: 20220801
E-mail: kccddb@gmail.com
Copyright: CC BY-NC-SA
這裡寫的是非標準 Fedo***, Deb***, Ubun***, 用法
你要看他們的標準用法, 那請別看這裡, 請離開別浪費時間, 這裡只有簡單但複雜的東西
這裡的 ppp, rp-pppoe 都是自己 source compile, 沒有那些
adsl-start, adsl-stop, … 那些東西
連 /etc/ppp/pap-secrets, /etc/ppp/chap-secret 都沒有
因此如要看他們的標準用法, 那也別看這裡了, 也請離開, 不用浪費時間
以下 是 pppd 與 pppoe 的 DIY, 相信能看懂以下內容者的能力. 若想看Protocol 可以找其它資料. pppoe 事實上昰透過 Ethernet 進行 PPP 連線
/*
pppd, pppoe
*/
這裡用的是很小的 Linux系統 (pppd, pppoe DIY)
pppd 很麻煩, 若不想改原來 HOST 設定需要 chroot 一起配合
以下是x86 版, 改成 Beaglebone, Sitara, Raspberry Pi…不是問題
編譯好 rp-pppoe, pppd , 其中 pppd pppoe也加入 PATH 中
上面xxxxxx部分自己改
Advanced user: linkname 也請看 Multiple PPPoE connections
[sudo] password for laikc:
Using interface ppp0
Connect: ppp0 <–> /dev/pts/5
PAP authentication succeeded
local IP address 114.26.44.207
remote IP address 168.95.98.254
沒 DNS 因此再來
laikc@laikc-virtual:~/x86/rp-pppoe-3.11$ pppd pty 'pppoe -I eth0 -T 100 -U -m 1412' linkname adsl0 user xxxxxx@hinet.net password xxxxxxx default-asyncmap hide-password nodetach mtu 1492 usepeerdns
Using interface ppp0
Connect: ppp0 <–> /dev/pts/5
PAP authentication succeeded
local IP address 111.246.97.7
remote IP address 168.95.98.254
primary DNS address 168.95.192.1
secondary DNS address 168.95.1.1
但是這樣 route, 與 NAT 還不能動, 還有MTU 問題, MTU 以後再談, MTU 是可能的大問題
route, nat 是小問題, 除了多路 VPN bonding 與 load balancing
您當然可以依照 pppd 的結果自己手動設定 routing, NAT 的問題, 但是
pppd 會始用 /etc/ppp/ip-up 幫忙設定, ppp-2.4.6 為例 source code
static void
ipcp_script(script, wait)
char *script;
int wait;
{
char strspeed[32], strlocal[32], strremote[32];
char *argv[8];
slprintf(strspeed, sizeof(strspeed), "%d", baud_rate);
slprintf(strlocal, sizeof(strlocal), "%I", ipcp_gotoptions[0].ouraddr);
slprintf(strremote, sizeof(strremote), "%I", ipcp_hisoptions[0].hisaddr);
argv[0] = script;
argv[1] = ifname;
argv[2] = devnam;
argv[3] = strspeed;
argv[4] = strlocal;
argv[5] = strremote;
argv[6] = ipparam;
argv[7] = NULL;
if (wait)
run_program(script, argv, 0, NULL, NULL, 1);
else
ipcp_script_pid = run_program(script, argv, 0, ipcp_script_done,
NULL, 0);
}
內定使用 script
#define _PATH_UPAPFILE _ROOT_PATH "/etc/ppp/pap-secrets"
#define _PATH_CHAPFILE _ROOT_PATH "/etc/ppp/chap-secrets"
#define _PATH_SRPFILE _ROOT_PATH "/etc/ppp/srp-secrets"
#define _PATH_SYSOPTIONS _ROOT_PATH "/etc/ppp/options"
#define _PATH_IPUP _ROOT_PATH "/etc/ppp/ip-up"
#define _PATH_IPDOWN _ROOT_PATH "/etc/ppp/ip-down"
#define _PATH_IPPREUP _ROOT_PATH "/etc/ppp/ip-pre-up"
#define _PATH_AUTHUP _ROOT_PATH "/etc/ppp/auth-up"
#define _PATH_AUTHDOWN _ROOT_PATH "/etc/ppp/auth-down"
#define _PATH_TTYOPT _ROOT_PATH "/etc/ppp/options."
#define _PATH_CONNERRS _ROOT_PATH "/etc/ppp/connect-errors"
#define _PATH_PEERFILES _ROOT_PATH "/etc/ppp/peers/"
#define _PATH_RESOLV _ROOT_PATH "/etc/ppp/resolv.conf"
pppd 啟動的環境變數 (當然正常只有 …child process 可以用)
Search for "script_setenv"…, 我用 Windows Jens' File Editor 找出來
E:\src\ppp-2.4.6\pppd\auth.c(974,5): script_setenv("PEERNAME", peer_authname, 0);
E:\src\ppp-2.4.6\pppd\ipcp.c(1816,5): script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0);
E:\src\ppp-2.4.6\pppd\ipcp.c(1818,2): script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1);
E:\src\ppp-2.4.6\pppd\ipcp.c(1825,2): script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0);
E:\src\ppp-2.4.6\pppd\ipcp.c(1827,2): script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0);
E:\src\ppp-2.4.6\pppd\ipcp.c(1829,2): script_setenv("USEPEERDNS", "1", 0);
E:\src\ppp-2.4.6\pppd\ipcp.c(1855,3): script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0);
E:\src\ppp-2.4.6\pppd\ipcp.c(1861,3): script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0);
E:\src\ppp-2.4.6\pppd\ipv6cp.c(1213,5): script_setenv("LLLOCAL", llv6_ntoa(go->ourid), 0);
E:\src\ppp-2.4.6\pppd\ipv6cp.c(1214,5): script_setenv("LLREMOTE", llv6_ntoa(ho->hisid), 0);
E:\src\ppp-2.4.6\pppd\main.c(339,5): script_setenv("ORIG_UID", numbuf, 0);
E:\src\ppp-2.4.6\pppd\main.c(467,5): script_setenv("PPPLOGNAME", p, 0);
E:\src\ppp-2.4.6\pppd\main.c(470,2): script_setenv("DEVICE", devnam, 1);
E:\src\ppp-2.4.6\pppd\main.c(472,5): script_setenv("PPPD_PID", numbuf, 1);
E:\src\ppp-2.4.6\pppd\main.c(742,5): script_setenv("IFNAME", ifname, iskey);
E:\src\ppp-2.4.6\pppd\main.c(786,5): script_setenv("PPPD_PID", numbuf, 1);
E:\src\ppp-2.4.6\pppd\main.c(832,5): script_setenv("LINKNAME", linkname, 1);
E:\src\ppp-2.4.6\pppd\main.c(1249,5): script_setenv("CONNECT_TIME", numbuf, 0);
E:\src\ppp-2.4.6\pppd\main.c(1251,5): script_setenv("BYTES_SENT", numbuf, 0);
E:\src\ppp-2.4.6\pppd\main.c(1253,5): script_setenv("BYTES_RCVD", numbuf, 0);
E:\src\ppp-2.4.6\pppd\main.c(1731,37): * exec. It is not possible to use script_setenv() or
E:\src\ppp-2.4.6\pppd\main.c(2016,4): * script_setenv - set an environment variable value to be used
E:\src\ppp-2.4.6\pppd\main.c(2020,1):script_setenv(var, value, iskey)
E:\src\ppp-2.4.6\pppd\multilink.c(188,3): script_setenv("BUNDLE", bundle_id + 7, 1);
E:\src\ppp-2.4.6\pppd\multilink.c(222,4): script_setenv("BUNDLE", bundle_id + 7, 0);
E:\src\ppp-2.4.6\pppd\multilink.c(235,2): script_setenv("BUNDLE", bundle_id + 7, 1);
E:\src\ppp-2.4.6\pppd\plugins\radius\radius.c(596,16): script_setenv("RADIUS_FILTER_ID", vp->strvalue, 1);
E:\src\ppp-2.4.6\pppd\plugins\radius\radius.c(600,16): script_setenv("RADIUS_FRAMED_ROUTE", vp->strvalue, 1);
E:\src\ppp-2.4.6\pppd\plugins\rp-pppoe\plugin.c(221,5): script_setenv("MACREMOTE", remote_number, 0);
E:\src\ppp-2.4.6\pppd\tty.c(739,2): script_setenv("SPEED", numbuf, 0);
重要的就是上面紅色這兩個, 其餘沒有也沒關係, 直接用 pppd command
#define _PATH_IPUP _ROOT_PATH "/etc/ppp/ip-up"
#define _PATH_IPDOWN _ROOT_PATH "/etc/ppp/ip-down"
可以來設定 route, 與 NAT, 等, 其餘再說, 很煩的…
設計網路設備的 BUNDLE 應該很有興趣吧? 哈, 其實還有很多要寫程式要配合沒那麼簡單
…真正實用也非 如此簡單 up ,down…
為了打造與原來 Host Linux 無關的 rootfs
我們用了最簡單的 busybox, 放在 home/x86 中, tftpboot 不用理, 那是我 pxe, 與 tftp 用的
root@laikc-virtual:/home/laikc/x86# chroot . bin/sh
/ # ls
ib tftp.sh usr linuxrc
bin sbin tftpboot
etc src tmp
src 都是放該 cpu arch 的 source, 有些要改makefile
root@laikc-virtual:/home/laikc/x86# mkdir proc sys dev var
因為用 host 的系統, 因此 mount 原來 3 個主要系統, 若是真正版子, 要自己來, 不是用以下的 command, 也就是proc, dev, sys 要自己來
chroot pppd 注意事項: 因為pppd 用了一堆kernel device 功能, 因此須要額外 proc, sys, dev
請看 ppp source code
設定 dev, proc, sys
root@laikc-virtual:/home/laikc/x86# mount -t proc proc proc/
root@laikc-virtual:/home/laikc/x86# mount –rbind /sys sys/
root@laikc-virtual:/home/laikc/x86# mount –rbind /dev dev/
–rbind "Bind Mounts" recursive bind mount. Please see wiki.
Maybe you must know this problem in detail.
看 pppd source 也需要 var/run
root@laikc-virtual:/home/laikc/x86# mkdir var/run
因為 pppd 需要 proc, dev, sys (kernel modules), var, var/run
很多程式需要 /var, /var/run , embedded system 可用 ramdisk mount /var, /tmp
我把 pppd pppoe dynamic lib 都cp 至 root@laikc-virtual:/home/laikc/x86/lib
還有 linux-gate.so.1是 kernel 的, 不用 cp
laikc@laikc-virtual:~/x86$ ldd bin/pppoe
linux-gate.so.1 => (0x00634000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x0072e000)
/lib/ld-linux.so.2 (0x00bfb000)
laikc@laikc-virtual:~/x86$ ldd bin/pppd
linux-gate.so.1 => (0x00bbb000)
libcrypt.so.1 => /lib/i386-linux-gnu/libcrypt.so.1 (0x00d2e000)
libutil.so.1 => /lib/i386-linux-gnu/libutil.so.1 (0x002ce000)
libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0x00ff5000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x008b6000)
/lib/ld-linux.so.2 (0x0081f000)
laikc@laikc-virtual:~/x86$
chroot . bin/sh
(因為我的busybox 沒有 bash, lubutu12.04 chroot 內定 /bin/bash 因此要加 shell, 如果您只用
chroot . 會出問題, 沒有shell )
沒設 PATH 就要完整 path
/bin/pppd pty '/bin/pppoe -I eth0 -T 30 -U -m 1412' linkname adsl2 user xxxxxxxxx password xxxxxxx default-asyncmap hide-password nodetach mtu 1492 usepeerdns
Connect: ppp0 <–> /dev/pts/5
PAP authentication succeeded
local IP address 111.246.97.7
remote IP address 168.95.98.254
primary DNS address 168.95.192.1
secondary DNS address 168.95.1.1
這樣您就可以寫自己的 ip-up 與 ip-down 與原HOST Linux 沒有衝突
其實您看 ppp source, 沒有那些 script 也可以自己改
做這個不是很無聊嗎? 不是的! 因為與網路相關先用 x86 測完再移植 別的 CPU 比較方便, 實際不是每人手有一片版子, 真正最跨平台的是 C. Java 只是應用層, import LIB 不一樣, java 能跨平台嗎? 累死人, 您把 C# 移植Android 看看? 但是 C 很好移植.
簡單原則: 與UI 無關用 C, 與UI 有關可用 Java等
還有 Linux IEEE80211 wifi 也可以如此使用來測試, 沒有udev, 就要手動 insmod
ip-up , ip-down 寫法請看
http://wiki.openwrt.org/doc/howto/vpn.client.pptp
很好資料, 這就不提了, 上面寫的很好, 雖然非PPPoE, 原理一樣
pppd 有點複雜的這老的好東西, 可以用到現在
但是 route 請改 ip route (check replace parameters ), 不要用 route 了
…
正常檢察網路通不通不是用ping 固定IP方法, 檢察WAN網路斷線也不是只用 ifconfig 方法
其中有用的方法 AF_PACKET (不是用ping) 與 Netlink Socket 判斷 route change