2012年2月1日 星期三

位元處理函式

/******************************************************
function name :bitclr
description :清除指定位元(0)
Ex: bitclr(0xff,3)
11111111 -> 11110111
bitaddr :0~31
******************************************************/
unsigned int bitclr(unsigned int srcvalue,unsigned char bitaddr)
{
unsigned int mask=1;
return srcvalue&(~(mask< 01011101
bitaddr :0~31
******************************************************/
unsigned int bitset(unsigned int srcvalue,unsigned char bitaddr)
{
unsigned int mask=1;
return srcvalue|(mask< 10001001
bitaddr :0~31
******************************************************/
unsigned int bitinv(unsigned int srcvalue,unsigned char bitaddr)
{
unsigned int mask=1;

if((srcvalue>>bitaddr)&0x00000001==1)
return srcvalue&(~(mask< false
bitaddr :0~31
return : 1:true , 0:false
******************************************************/
unsigned char bitcmp(unsigned int srcvalue,unsigned char bitaddr)
{

if((srcvalue>>bitaddr)&0x00000001==1)
return 1;
else
return 0;
}

/******************************************************
function name :bitget
description :回指定bit 為 0 或 1
Ex: bitget(0x55,3)
01010101 -> 0
bitaddr :0~31
return : get bit value
******************************************************/
unsigned char bitget(unsigned int srcvalue,unsigned char bitaddr)
{
return (srcvalue>>bitaddr)&0x00000001;
}

/******************************************************
function name :bitput
description :設定指定bit 為 0 或 1
Ex: bitget(0x55,3,1)
01010101 -> 01011101
bitaddr :0~31
return : put bit value
******************************************************/
unsigned int bitput(unsigned int srcvalue,unsigned char bitaddr,unsigned char value)
{
if (value==1)
return bitset(srcvalue,bitaddr);
else
return bitclr(srcvalue,bitaddr);

}

/******************************************************
function name :bitSwap
description :將傳入數值low 與 high 位元完全互換
Ex: bitSwap(0x55)
01010101 -> 10101010
return : swap bit value
******************************************************/
unsigned int bitSwap(unsigned int value)
{
unsigned int tmpbit;
unsigned char i;

tmpbit=value;
for (i=0;i<32;i++) { tmpbit=bitput(tmpbit,31-i,bitget(value,i)); } return tmpbit; } 





C語言不定參數

在C 語言我們常常見到不定參數的使用,像是 prinft() 與 scanf() 
這些函數的定義使用符號 ... 來表示不定參數,如int printf( const char* format, ...);
在內部則是使用 va 系列巨集來實現的
   va_list                                          //不定長度型態

   void va_start( va_list arg_ptr, prev_param );    //啟始不定長度引數的巨集
   type va_arg( va_list arg_ptr, type );            //讀取不定長度引數的巨集
   void va_end( va_list arg_ptr );                  //結束不定長度引數的巨集 


va 系列的巨集定義如下:
#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int)-1)) 

#define va_start(ap,v) ( ap=(va_list)&v + _INTSIZEOF(v)) 
#define va_arg(ap,t) (*(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t))) 
#define va_end(ap) (ap = (va_list)0 )

簡單的範例:

#include 
#include 
#include 
void CLI_TMP(unsigned int type,...);

int main(int argc, char *argv[])
{
    char d[10]="ABC";
    
    CLI_TMP(0,10,20,30,d,"ddsfssf",'c');


    system("PAUSE");
    return 0;
}

void CLI_TMP(unsigned int type,...)
{
    va_list argptr;
    char temp_buf[256];
    int a,b,c;
    char *d,*e;
    char f;
    
    va_start(argptr, type);

    a = va_arg (argptr,int);
    b = va_arg (argptr,int);
    c = va_arg (argptr,int);
    d = va_arg (argptr,char*);
    e = va_arg (argptr,char*);
    f = va_arg (argptr,int);
    
    strcat(d,"aaa");
    va_end(argptr);
    
    printf("%d,%d,%d,%s,%s,%c\n",a,b,c,d,e,f);
} 

link from:http://blog.yam.com/ddy1280/article/2095414

使用awk 解析資料

使用 Linux 愈久,愈深深的被 Linux 的系統架構與極具彈性的 script 與工具吸引
原來,解決問題只要短短的一行指令,相信這是許多程式設計人員嚮往的事

最近工作上需要從dhcpcd 取得一些額外的資訊,所以在system call 所沒有有提供的部份,就要從記錄檔裡分析
通常,我們在 linux 下常見的文字檔是DSV 格式(Delimiter-Separated Values)像是/etc/passwd 或是以Space 分隔
在Windows 則常見 INI 格式

以往要取得這類文件的某行或某列的特定資料,通常會寫個程式,然後開檔,一行一行讀取,讀到某行,再進行分析,這樣的做法真的很累,以前我就是這樣做的
而現在,grep 與 sed ,或是 awk 幫我完成大部份工作
例1: 
資料檔 aa.txt
Destination    Gateway       Genmask         Flags Metric Ref

192.168.100.0  *             255.255.255.0   U     3      1  
172.16.100.0   *             255.255.255.0   U     5      0  
172.16.200.0   *             255.255.255.0   U     3      0  
default        172.16.100.73 255.255.255.0   U     3      0  


        FILE *fp;

    fp = popen("cat aa.txt | grep default |awk '{print $2}'","r");
    if (fp !=NULL)
    {
        fgets(buf,16,fp);
        pclose(fp);
    }
使用grep 與 awk 分析資料再使用popen()開啟管線,取回的buf,就是172.16.100.73


例2:
資料檔  dhcpcd.info
[dhcpcd]
IPADDR=172.16.100.239
NETMASK=255.255.255.0
NETWORK=172.16.100.0
BROADCAST=172.16.100.255
GATEWAY=172.16.100.73
DNS=192.168.1.254
DHCPSIADDR=172.16.100.73
DHCPCHADDR=00:05:65:71:1F:EA
DHCPSHADDR=00:90:CC:40:25:F9

    FILE *fp;

    fp = popen("cat dhcpcd.info |awk -F = '/GATEWAY/{print $2}'","r");
    if (fp !=NULL)
    {
        fgets(buf,16,fp);
        pclose(fp);
    }
使用awk 取得 Name=Value 格式的資料,這種格式常見於 windows INI 
最後的結果buf 就是我們要的 172.16.100.73  (Gateway Address)

解說: awk -F fs   意指,設定分隔的字串,在這個例子裡,資料是以 = 符號區分欄位的
所以 fs 要設為 = 符號,/GATEWAY 意指,搜尋GATEWAY 的那一行,
/{print $2}  意指,列印出第二欄的資料



awk 真的是很值得學習的script ,不只在 linux 才有,windows 平台也有喔(按此下載)

參考資料:
Scripts 大集合
AWK Tutorial Guide


使用C 取得外部shell script回傳值(linux)

有時候我們為了提高程式的彈性,會使用shell script 來做部份的工作
再取得回傳值來判定正常或是異常
以下面的例子…使用script 判斷目錄是否存在~

#!/bin/sh
#check directory

if [ -d $1 ];then
   #do something...
   ls $1
   exit 0
else
   exit 2
fi

可直接在shell 下觀察回傳值

echo $?

而在C 語言程式裡…若要取得執行外部shell script 的回傳值的話,如下所示 

#include

int main (int argc,char **argv)
{
    int ret=0;
    ret=system("./checkdir dir1");
    ret >>= 8;
    if (ret==2)
        printf("dir1 does not exist\n");
}

說明:
1.在shell script 裡是透過exit 返回時帶回傳值, 在C 與 shell 裡的慣例 0 為正常結束,非0 則為異常
2.在C 程式裡其中 ret 值要除以256才會得到與shell 傳回相符的值




【C語言】一堆子轉換函式

對許多初學者而言,資料的轉換仍然是一個問題,在此整理一些函式說明如下:

大概分為三類
  1. 字串與數值轉換
  2. 位元順序轉換
  3. 網路位址轉換

字串與數值轉換
    常見的就是atoi(),atol(),atof(),itoa() ... 之類的,其中itoa() 不被gcc所支援,可透過sprintf()來實現轉換,並僅以atoi()與sprintf()為例
  
原型宣告使用方法使用時機
#include 
int atoi (const char *str);
int a;
a=atoi("100");
將數值字串轉換成整數
#include 
int sprintf (char *str,const char *format,...);
char s[10];
sprintf(s,"%s",100);
將數值轉換為字串


位元順序轉換
    位元序序轉換是因為x86 cpu讀取記憶體的順序與磁碟上存放的順序不同而造成的,x86架構是所謂的Little-Endian,在磁碟上儲存的位元組是照順序的,然而以32位元記憶體存取而言,會先從低位元開始讀取,例如…在磁碟上存放的資料是0x12345678,那麼讀進記憶體之後,就會是0x78 0x56 0x34 0x12
所以,從在儲存媒體與記憶體之間的資料需要轉換。另外就是用於Host Byte Order 與 Network Byte Order 互換,因為網路跨平台的特性,無論主機端是Big-Endian 或是Little-Endian 都要能正確地透過網路交換資料,所以在Socket定義上,Network Byte Order 採用 Big-Endian 。以下函式可達成轉換:
#include 

uint32_t htonl(uint32_t hostlong);//32位元資料轉換
uint16_t htons(uint16_t hostshort);//16位元資料轉換
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

僅以host 中32位元記憶體中資料 0x78563412 為例:
原型宣告使用方法使用時機
#include 
uint32_t htonl(uint32_t hostlong);
unsigned int a,b;
a=0x78563412;
b=htonl(a);
1.host轉換成network 順序
2.memory 資料寫入磁碟的轉換
(0x78563412-->0x12345678)
#include 
uint32_t ntohl(uint32_t netlong);
unsigned int a,b;
b=0x12345678;
a=ntohl(b);
1.network 轉換成host順序(0x12345678-->0x12345678)

網路位址轉換 
    網路位址轉換是32位元IP值與IP字串的轉換,例如我們所輸入的IP 192.168.100.111 是一組字串,但是socket api 接受的是32位元IP值,所以需要轉換,或是從socket api 取得的32位元IP值,要轉換成可顯示的字串格式,可例用下列函式:
#include 
#include 
#include 

char *inet_ntoa(struct in_addr in);
int inet_aton(const char *cp, struct in_addr *inp);
in_addr_t inet_addr(const char *cp);

原型宣告使用方法使用時機
#include 
#include 
#include  
char *inet_ntoa(struct in_addr in); 
char ipbuf[16];
struct in_addr addr;
addr.s_addr =0xC0A86401;
sprintf(ipbuf,"%s",inet_ntoa(addr));
32位元IP Address 轉換為IP字串

            
#include 
#include 
#include 
int inet_aton(const char *cp, \ struct in_addr *inp);
struct in_addr addr;
unsigned int ip;
ip=inet_aton("192.168.100,1",&addr);
IP字串轉換為32位元IP Address

2012年1月30日 星期一

Qos + CBQ

單一主機的上傳,即 Client的下載(如瀏覽網頁)

[ client ] <---------- ech0 -[ server ]
 
[1.] 下載 CBQ的 script,cbq.init-v0.7.3
         https://sourceforge.net/projects/cbqinit

[2.] cbq.init 的初始預設作業
         mkdir /etc/sysconfig/cbq
         chmod u+x cbq.init
         cp cbq.init /sbin
 
[3.] cd /etc/sysconfig/cbq
         vi cbq-0002.eth0-80
DEVICE=eth0,100Mbit,10Mbit
RATE=100Kbit
WEIGHT=10Kbit
PRIO=5
RULE=*:80,
BOUNDED=yes
ISOLATED=no
[4.] 顯示 tc格式結果
         cbq.init compile           

      啟動
         cbq.init start
 
[5.] 從 Client端測試下載 web檔,限制在10KByte/s下載
         wget http://server/xxxfiles

NAT環境,以PORT number設置內部網路的上下載
模擬頻寬 512Kbps/512Kbps
attachments/month_200611/1163513806.png

[1.] 從 eth2出去的,目的為 25、20 port,分配各為 256Kbit、256Kbit,這對內部來說是上傳
         而從 eth1出去的,來源為110、80、20 port,分配各為 128Kbit、256Kbit、128Kbit,這對內部來看是下載
[2.] 下載的設定
         vi cbq-0002.eth1-110
DEVICE=eth1,100Mbit,10Mbit
RATE=128Kbit
WEIGHT=12Kbit
PRIO=5
RULE=:110,
BOUNDED=yes
ISOLATED=yes
         vi cbq-0003.eth1-80
DEVICE=eth1
RATE=256Kbit
WEIGHT=25Kbit
PRIO=7
RULE=:80,
BOUNDED=yes
ISOLATED=yes
PARENT=0002
         vi cbq-0004.eth1-20
DEVICE=eth1
RATE=128Kbit
WEIGHT=12Kbit
PRIO=8
RULE=:20,
BOUNDED=yes
ISOLATED=yes
PARENT=0002
[3.] 上傳設定
         vi cbq-0102.eth2-25
DEVICE=eth2,100Mbit,10Mbit
RATE=256Kbit
WEIGHT=25Kbit
PRIO=6
RULE=:25
BOUNDED=yes
ISOLATED=yes
         vi cbq-0103.eth2-20
DEVICE=eth2
RATE=256Kbit
WEIGHT=25Kbit
PRIO=8
RULE=:20
BOUNDED=yes
ISOLATED=yes
PARENT=0102
附註1:
cbq作用在流出的封包上
依整個linux box來看,從eht2出去是限制到上傳,從eth1出去限制到下傳

附註2:
cbq設定檔中的 RULE參數,如果”沒”加逗點的話為目的,”有”加逗點為來源

參數說明:
DEVICE=,,
DEVICE=eth0,10Mbit,1Mbit               # ifname = 網卡名稱
                                                         # bandwidth = 網卡上限頻寬
                                                         # weight = bandwidth / 10

RATE=2Mbit
WEIGHT=200Kbit                              # ADSL 2Mbits/256Kbits,即下載200kbytes,上傳25kbytes

PRIO=5                                             # 優先權 ,1到8,預設為5

PARENT=0002                                   # 上層,預設沒設

LEAF=none | tbf | sfq                        # 預設為tbf

BOUNDED=yes | no                           # 設成 yes,將在超出限制的情況下不允許從它的上層借入頻寬,
                                                          # 當設成 no,為允許時,LEAF必設 none 或 sfq
                                                          # 預設為 yes

ISOLATED=yes | no                            # 設成 yes,將不會借出沒用到的頻寬給下層使用
                                                           # 預設為 no

RULE=10.1.1.0/24:80                         # 目的為10.1.1.0的網段,且port為80
RULE=10.2.2.5                                    # 目的為10.2.2.5的主機
RULE=10.2.2.5:20/0xfffe                     # 目的為10.2.2.5的主機,且port為20和21
RULE=:25,10.2.2.128/26:5000            # 來源port為25,到目的網段為10.2.2.128,且port為5000
RULE=10.5.5.5:80,                               # 來源主機為10.5.5.5,且port 為80
      附註: RULE參數可以多個設定

NAT環境(延續上面的環境),FTP passive mode,有些 FTP並非全用 port number 20來傳輸資料,大部份會動用到 port numbers 1024以上的 port
 
關於 ftp的 passive mode,需搭配 iptables的 MARK才能有效限制到流量
iptables -t mangle -A POSTROUTING -o eth2 -p tcp --dport 1024:65535 -j MARK --set-mark 30
iptables -t mangle -A POSTROUTING -o eth1 -p tcp --sport 1024:65535 -j MARK --set-mark 20
 
   vi cbq-0103.eth2-20
DEVICE=eth2
RATE=256Kbit
WEIGHT=25Kbit
PRIO=8
RULE=:20
BOUNDED=yes
ISOLATED=yes
PARENT=0102
MARK=30         # <-- 加入MARK這行
   vi cbq-0004.eth1-20
DEVICE=eth1
RATE=128Kbit
WEIGHT=12Kbit
PRIO=8
RULE=:20,
BOUNDED=yes
ISOLATED=yes
PARENT=0002
MARK=20         # <-- 加入MARK這行
   附註: 為了限制 ftp的 passive mode,但也限制了 1024以上所有的 port
 

NAT環境
限制內部單一主機
attachments/month_200611/1163513824.png

   vi cbq-0002.eth2-host
DEVICE=eth2,100Mbit,10Mbit
RATE=100Kbit
WEIGHT=10Kbit
PRIO=5
RULE=192.168.1.1,
BOUNDED=yes
ISOLATED=yes
   vi cbq-0003.eth1-host
DEVICE=eth1,100Mbit,10Mbit
RATE=256Kbit
WEIGHT=25Kbit
PRIO=6
RULE=192.168.1.1
BOUNDED=yes
ISOLATED=yes
引用:
但此時上傳卻不受限制,因為封包進入 QOS EGRESS之前,
來源 IP已變成 Linux Box對外的 IP,所以 192.168.1.1主機是不受上傳限制,
所以要配合 iptables的 MARK
iptables -t mangle -A PREROUTING -i eth1 -s 192.168.1.1 -j MARK --set-mark 40
   再修改 cbq-0002.eth2檔
DEVICE=eth2,100Mbit,10Mbit
RATE=100Kbit
WEIGHT=10Kbit
PRIO=5
BOUNDED=yes
ISOLATED=yes
MARK=40         # <-- RULE拿掉,加入MARK
或者搭配方式
iptables -t mangle -A FORWARD -o eth2 -s 192.168.1.1 -j MARK --set-mark 40
或者
iptables -t mangle -A POSTROUTING -o eth2 -s 192.168.1.1 -j MARk --set-mark 40

NAT環境
分別限制入部單一主機與整個內部網段
 
全 Subnet 限制在 512k/64k,而 10.1.1.1主機則 100Mbps/10Mbit
                                                                           +---------[ 10.1.1.1 ]
                                 +-------------------+              |
[ internet ] -----ppp0 |                         | eth0-----+
                                 +-------------------+              |
                                                                           +-----------[ 10.1.1.0/24 ]
 
iptables設定
iptables -t mangle -A POSTROUTING          -s 10.1.1.1      -j MARK --set-mark 30
iptables -t mangle -A PREROUTING -i eth0 -s 10.1.1.0/24 -j MARK --set-mark 50
 
vi cbq-0002.ppp0
DEVICE=ppp0,100Mbit,10Mbit
RATE=100Mbit
WEIGHT=10Mbit
PRIO=5
BOUNDED=yes
ISOLATED=yes
MARK=30
vi cbq-0003.eth0
DEVICE=eth0,100Mbit,10Mbit
RATE=100Mbit
WEIGHT=10Mbit
PRIO=5
BOUNDED=yes
ISOLATED=yes
RULE=10.1.1.1
vi cbq-0007.ppp0
DEVICE=ppp0
RATE=64Kbit
WEIGHT=6Kbit
PRIO=7
BOUNDED=yes
ISOLATED=yes
parent=0002
MARK=50
vi  cbq-0008.eth0
DEVICE=eth0
RATE=512Kbit
WEIGHT=50Kbit
PRIO=7
BOUNDED=yes
ISOLATED=yes
parent=0003
RULE=10.1.1.0/24
--- 我是分隔線 ---
NAT環境
iptables的 MARK另設定方式
                                  +-----------+
[ internet ]-------eth1-|               |-eth0---------[ subnet ]
                                  +-----------+
 
限制下載
iptables -t mangle -A FORWARD -o eth0 -d 192.168.1.0/24 -j MARK --set-mark 10
 
vi cbq-0002.download
DEVICE=eth0,100Mbit,10Mbit
RATE=200Kbit
WEIGHT=20Kbit
PRIO=5
MARK=10
限制上傳
iptables -t mangle -A FORWARD -o eth1 -s 192.168.1.0/24 -j MARK --set-mark 20
 
vi cbq-0003.upload
DEVICE=eth1,100Mbit,10Mbit
RATE=50Kbit
WEIGHT=5Kbit
PRIO=5
MARK=20
--- 我是分隔線 ---

Bridge mode環境:
Br0        10.10.1.100/255.0.0.0
Eth0對外 0.0.0.0
Eth1對內 0.0.0.0
10.10.1.100 為 bridge server
10.10.1.78 透過 bridge server連外
以下為 bridge mode server的 ifconfig
br0   Link encap:Ethernet HWaddr 00:E0:81:50:36:3C
         inet addr:10.10.1.100 Bcast:10.255.255.255 Mask:255.0.0.0

eth0  Link encap:Ethernet HWaddr 00:E0:81:50:36:3D
         inet6 addr: fe80::2e0:81ff:fe50:363d/64 Scope:Link

eth1  Link encap:Ethernet HWaddr 00:E0:81:50:36:3C
         inet6 addr: fe80::2e0:81ff:fe50:363c/64 Scope:Link
情況一
外部 pc下載內部 pc 10.10.1.78上的 web檔案,即內部 pc上傳,經由 Bridge
作法一
vi cbq-0002.eth0
DEVICE=eth0,100Mbit,10Mbit
RATE=100Kbit
WEIGHT=10Kbit
PRIO=5
MARK=50
BOUNDED=yes
ISOLATED=yes
搭配MARK
iptables -t mangle -I POSTROUTING -o br0 -s 10.10.1.78 -j MARK --set-mark 50
 
注意 : 出去的介面是br0,才能對內部 PC上傳有限制

作法二
vi cbq-0002.eth0
# 介面需設eth0,br0無效
DEVICE=eth0,100Mbit,10Mbit
RATE=100Kbit
WEIGHT=10Kbit
PRIO=5
BOUNDED=yes
ISOLATED=yes
RULE=10.10.1.78,
# 或者RULE=:80,
情況二,內部 pc 10.10.1.78下載外部 pc上的web檔案,即內部 pc下傳,經由 Bridge
作法一
vi cbq-0002.eth1
DEVICE=eth1,100Mbit,10Mbit
RATE=100Kbit
WEIGHT=10Kbit
PRIO=5
BOUNDED=yes
ISOLATED=yes
RULE=10.10.1.78
# 或者可設為
#RULE=:80,
作法二
iptables -t mangle -I POSTROUTING -o br0 -d 10.10.1.78 -j MARK --set-mark 50

vi cbq-0002.eth1
DEVICE=eth1,100Mbit,10Mbit
RATE=100Kbit
WEIGHT=10Kbit
PRIO=5
MARK=50
BOUNDED=yes
ISOLATED=yes


頻寬管理/限制 QOS + HTB 指令

HOST + upload

50kbyte/s for upload
25kbyte/s for http -> class 10:100
15kbyte/s for ftp -> class 10:200
10kbyte/s for others -> class 10:20

rate = 保證頻寬
ceil = 最大頻寬
attachments/month_200611/1163600502.png


# 刪除現有的規則
tc qdisc del dev eth0 root

# 定義頂層root規則
tc qdisc add dev eth0 root handle 10: htb default 20

# 定義class 10:1,這裡的50kbps即為50KByte/s
tc class add dev eth0 parent 10: classid 10:1 htb rate 50kbps ceil 50kbps

# 定義class 10:10
tc class add dev eth0 parent 10:1 classid 10:10 htb rate 40kbps ceil 40kbps

# 定義class 10:100
tc class add dev eth0 parent 10:10 classid 10:100 htb rate 25kbps ceil 40kbps
tc qdisc add dev eth0 parent 10:100 handle 101: pfifo
tc filter add dev eth0 parent 10: protocol ip prio 100 handle 100 fw classid 10:100

# 定義class 10:200
tc class add dev eth0 parent 10:10 classid 10:200 htb rate 15kbps ceil 40kbps
tc qdisc add dev eth0 parent 10:200 handle 102: pfifo
tc filter add dev eth0 paent 10: protocol ip prio 100 handle 200 fw classid 10:200

# 定義class 10:20
tc class add dev eth0 parent 10:1 classid 10:20 htb rate 10kbps ceil 50kbps
tc qdisc add dev eth0 parent 10:20 handle 103: pfifo

#
iptables -t mangle -A OUTPUT -p tcp --sport 80 -j MARK --set-mark 100
iptables -t mangle -A OUTPUT -m owner --uid-owner ftp -j MARK --set-mark 200



NAT + download

200KByte/s for download

class 10:10 prio 0 for 優先使用者或伺服器
class 10:20 prio 1 for 一般 ''
class 10:30 prio 2 for 濫用 ''

attachments/month_200611/1163600506.png


# 刪除現有的規則
tc qdisc del dev eth0 root

# root
tc qdisc add dev eth0 root handle 10: htb default 20

# root 10:1 class
tc class add dev eth0 parent 10: classid 10:1 htb rate 200kbps ceil 200kbps

# 10:10 class
tc class add dev eth0 parent 10:1 classid 10:10 htb rate 100kbps ceil 200kbps prio 0
tc qdisc add dev eth0 parent 10:10 handle 101: pfifo
# 將 MARK為 10的歸類於 class 10:10
tc filter add dev eth0 parent 10: protocol ip prio 100 handle 10 fw classid 10:10

# 10:20 class
tc class add dev eth0 parent 10:1 classid 10:20 htb rate 70kbps ceil 150kbps prio 1
tc qdisc add dev eth0 parent 10:20 handle 102: pfifo

# 10:30 class
tc class add dev eth0 parent 10:1 classid 10:30 htb rate 30kbps ceil 100kbps prio 2
tc qdisc add dev eth0 parent 10:30 handle 103: pfifo
# 將 MARK為 30的歸類於 class 10:30
tc filter add dev eth0 parent 10: protocol ip prio 100 handle 30 fw classid 10:30

iptables -t mangle -A POSTROUTING -d 192.168.0.135 -j MARK --set-mark 10
iptables -t mangle -A POSTROUTING -d 192.168.0.32 -j MARK --set-mark 30



NAT + upload

25KByte/s for upload

class 20:100 for HTTP
class 20:200 for 高優先權
class 20:20  for 一般
class 20:30  for 濫用

attachments/month_200611/1163600509.png


#
tc qdisc del dev ppp0 root

#
tc qdisc add dev ppp0 root handle 20: htb default 20
tc class add dev ppp0 parent 20: classid 20:1 htb rate 25kbps ceil 25kbps
tc class add dev ppp0 parent 20:1 classid 20:10 htb rate 15kbps ceil 25kbps
tc class add dev ppp0 parent 20:1 classid 20:20 htb rate 7kbps ceil 20kbps prio 2
tc class add dev ppp0 parent 20:1 classid 20:30 htb rate 3kbps ceil 10kbps prio 3
tc class add dev ppp0 parent 20:10 classid 20:100 htb rate 8kbps ceil 25kbps prio 0
tc class add dev ppp0 parent 20:10 classid 20:200 htb rate 7kbps ceil 25kbps prio 1

#
tc qdisc add dev ppp0 parent 20:20 handle 101: pfifo
tc qdisc add dev ppp0 parent 20:30 handle 102: pfifo
tc qdisc add dev ppp0 parent 20:100 handle 201: pfifo
tc qdisc add dev ppp0 parent 20:200 handle 202: pfifo

#
tc filter add dev ppp0 parent 20: protocol ip prio 100 handle 20 fw classid 20:20
tc filter add dev ppp0 parent 20: protocol ip prio 100 handle 30 fw classid 20:30
tc filter add dev ppp0 parent 20: protocol ip prio 100 handle 100 fw classid 20:100
tc filter add dev ppp0 parent 20: protocol ip prio 100 handle 200 fw classid 20:200

#
iptables -t mangle -A OUTPUT -p tcp --sport 80 -j MARK --set-mark 100
iptables -t mangle -A PREROUTING -i eth0 -s 192.168.0.135 -j MARK --set-mark 200
iptables -t mangle -A PREROUTING -i eth0 -s 192.168.0.32 -j MARK --set-mark 30


How to repair and clone disk with ddrescue

  ddrescue  is a tool that can be used to repair and clone disks on a  Linux system . This includes hard drives, partitions, DVD discs, flas...