2014年5月13日 星期二

USB HID for Visual C++

主要是DDK的安裝和設定,安裝忽略,設定的部份,主要是路徑的設定

For Visual C++ 6.0


For Visual Studio 2008


2013年2月8日 星期五

SSL/TLS 密鑰和自我簽核憑證

在Linux有openssl的套件,可以產生密鑰和自我簽核憑證

#產生密鑰
openssl genrsa -out server.key
#產生自我簽核憑證
openssl req -new -x509 -key server.key -out server.crt -days 365
#會有些資料要填,至少填入Common Name

在windows時,安裝apache httpd時,也有openssl的執行檔在bin目錄下,還有openssl.cnf的檔案在conf目錄下,需要先設定環境變數OPENSSL_CONF給openssl.cnf所在的路徑
執行cmd.exe,然後切換到conf的目錄下
set OPENSSL_CONF=openssl.cnf
#確認有設定對
echo %OPENSSL_CONF%
然後確定openssl執行檔的路徑
例如:
..\bin\openssl.exe genrsa -out server.key
..\bin\openssl.exe req -new -x509 -key server.key -out server.crt -days 365

有在httpd-2.2.22-win32-x86-openssl-0.9.8t.msi這個版本試過

另外還有兩個Java的程式可以產生
keytool ,這是java內建的,還沒用過...
portecle GUI的程式,有用過

2010年7月20日 星期二

IPv6 Prefix delegation 不完整報告

IPv6的主要特色,就是地址多到不行...所以之前的IPv4的NAT,就不需要了,且之前的NAT對於雙向對等溝通(主動,從外部連到內部)不太方便,雖然有很多的解決辦法(STUN.或使用者透過設定NAT,允許某些應用程式的溝通),不過這些動作都代表需要多些運算能力來處理...如果使用IPv6就可以讓Router的工作減輕(地址太多了,每個人,甚至是裝置,都是真實的IP),也不用再實做STUN到應用程式裡...當然NAT對於安全性還是有幫助的...

IPv6的裝置,一般透過和Router的溝通(NDP),可以得到一個Prefix,再加上裝置的MAC位址,就可以得到一個連上Internet的網路位址
目前radvd,是linux這方面的實作

如果用戶端有一個Router,想要得到一個Prefix來分配給用戶端的裝置,可以透過DHCPv6來得到Prefix,然後分配給底下的裝置使用
我們選用Dibbler來練習

環境:
vmware-1.0.9
centos 4.8
設一張網卡接到Host-only

實做DHCPv6 Server:
首先實做DHCPv6 Server,下載dibbler-0.7.3-src.tar.gz, 解壓縮, make server client relay, make install

修改設定檔:
在/etc/dibbler底下有許多server或client的設定檔範例,我們拿server-prefix-delegation.conf來修改,並把檔名修改成server.conf


#
# Example server configuration file: Prefix Delegation
#
# Server is able to grant prefixes for clients, who ask for it.
# Prefixes can be assigned besides of or instead of addresses.
# It depends what client asks for.

# Logging level range: 1(Emergency)-8(Debug)
log-level 8

# Don't log full date
log-mode short

iface "eth0" {


# clients should renew every half an hour
T1 1800

# In case of troubles, after 45 minutes, ask any server
T2 2700

# Addresses should be prefered for an hour
prefered-lifetime 3600

# and should be valid for 2 hours
valid-lifetime 7200

class {
  pool 5000::/48
}

# the following lines instruct server to grant each client
# 1 or 2 prefixes (if you have uncommented second line with pd-pool or not).
# For example, client might get
# 2222:2222:2222:222:2222:993f:6485:0/112 and
# 1111:1111:1111:1111:1111::993f:6485:0/112
pd-class {
       pd-pool 2001:1234:5678::/48

       // uncomment following line to assign 2 prefixes for 2 different pools
// Note: each client will receive 1 prefix from each pool.
// pd-pool 1111:1111:1111:1111:1111::/80
       pd-length 64
       T1 11111
       T2 22222
   }

}


PS : prefix 2001:1234:5678::/48這是隨便給的,主要是為了測試用

啟動dibbler-server:
dibbler-server start

觀察dibbler-server:
dibbler-server status

停止dibbler-server:
dibbler-server stop

實做DHCPv6 Client:
vmware-1.0.9
centos 4.8
設一張網卡接到Host-only
再設另一張網卡接到NAT

修改設定檔:
參考client-prefix-delegation.conf,並修改,然後將檔名修改成client.conf(完全沒改)


#
# Example client configuration file: Prefix Delegation
#

# This is an example configuration file with prefix delegation
# enabled. To ask for prefixes, use 'pd' (or 'prefix-delegation') keyword.

log-mode short

# 7 = omit debug messages
log-level 7

iface "eth0" {
 ia
 pd

# it is also possible to define parameters for prefix delegation
# pd {
#    t1 1000
#    t2 2000
#}

}



啟動dibbler-client
dibbler-client start

觀察dibbler-client
dibbler-client status

停止dibbler-client
dibbler-client stop

radvd的設定:
從client啟動dibbler-client,有一個檔案會更新,/etc/dibbler/radvd.conf,這個檔案是radvd的設定檔,讓這個檔案,可以對其它的介面或接收prefix的介面來發出router advertisement

PS : 若有打開IPv6 routing, echo “1” > /proc/sys/net/ipv6/conf/all/forwarding,則會在其它的介面上(不包括接收prefix的介面)發出router advertisement,若沒有打開IPv6 routing,則會在同樣接收prefix的介面發出router advertisement

不過dibbler只是產生一個設定檔,啟動停止radvd還是要靠radvd daemon且若radvd.conf的設定檔有變動,好像也不會讓radvd重新reload設定檔

我有測試radvd-1.6.tar.gz,發現一個問題,就是dibbler產生的radvd.conf會有語法不合的情形...所以需要修改dibbler的source code
修改./Port-linux/lowlevel-options-linux.c,找到fprintf(f, "         AdvAutonomous false;\n");這一行
改成fprintf(f, "         AdvAutonomous on;\n");...然後重新編譯,安裝

PS: 我用win xp 做client,AdvAutonomous 一定要on,才能得到IPv6的位址,至於其他radvd.conf的參數,看情況加入

還有radvd source code安裝時, 解壓縮, ./configure --sysconfdir=/etc/dibbler, make, make install,configure下的參數,可以讓radvd去/etc/dibbler/radvd.conf找設定檔

結論:
dibbler + radvd,目前還不算是完整的解決方案,不過至少有雛形了...也許過陣子再來關心,看看有沒有高手來解決!!!

相關連結:
http://en.wikipedia.org/wiki/Radvd
http://en.wikipedia.org/wiki/Neighbor_Discovery_Protocol
NDP : RFC1970 -> RFC2461 -> RFC4861 . RFC5006 (RDNSS)

http://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol
http://en.wikipedia.org/wiki/DHCPv6
DHCPv6 : RFC3315 . RFC3319 . RFC3633 . RFC3646 . RFC3736 . RFC4242 . RFC5007

2010年7月12日 星期一

Linux PPTP 實作報告

PPTP(Point to Point Tunneling Protocol),是VPN(Virtual Private Network)的一種,這裡PPTP的設定(MPPE. MPPC MS-CHAPv2)主要是為了Windows環境所設置的(Windows的OS還是大部份人在使用),方便員工在外地存取公司網路資源,...其它像是L2TP或L2TP/IPSec之類的VPN也許有機會可以試試看...

環境:
VMware-server 1.0.10
Fedora Core 5(記得要把selinux關掉)
由於FC5的核心已經包括了MPPE&MPPC的module功能,且ppp-2.4.3-6.2.1的RPM也預設安裝,所以只剩下pptpd for Server,和pptp for client.

首先實做Server:
下載pptpd-1.3.4.tar.gz,./configure,./make,./make install

編輯/etc/pptpd.conf(這個是pptpd的預設設定檔,可以man pptpd.conf或man pptpd參考)
localip 192.168.1.1
remoteip 192.168.1.10-19
#這是告訴pppd,它的設定檔是這一個,否則會預設用/etc/ppp/options
option /etc/ppp/options.pptpd

編輯/etc/ppp/options.pptpd(pppd的設定檔,裡面的參數,可以man pppd參考)
#這裡name的定義可以對應到/etc/ppp/chap-secrets
name test
#Microsoft定義兩種handshake protocol,MS-CHAPv1 for win95,之後就用MS-CHAPv2,所以這裡用較新的
require-mschap-v2
#這是通道加密的方法,開啟這個,可以使用40bits或128bits的加密方式,(參考Microsoft的加密等級)
require-mppe
ms-dns 192.168.1.1
ms-wins 192.168.1.1
 
編輯/etc/ppp/chap-secrets
“user_name”    “pptpd_hostname”    “password”    “allow-source-ip”
第二欄可以關聯/etc/ppp/options.pptpd的name的設定,所以這裡設定為test,也可以設定”*”,代表wildcard
第四欄設為”*”,可以不限制pptp client的來源ip

啟動pptpd
pptpd
#可以cat /var/log/messages,查看運作情形,如果有client連結成功,可以透過ifconifg可以看到ppp的介面

關閉pptpd
ps -e | grep pptpd #找出pptpd的process_id
kill process_id

利用windows client來連上
應該不困難,忽略...

Routing for Server:
當然不是clinet連得上來就好,封包還要能路由到用戶希望到的機器,所以第一步就是打開linux的路由功能
echo 1 > /proc/sys/net/ipv4/ip_forward
然後就是設定適當的路由,還有加入防火牆,保險一些...PPTP使用TCP port 1723

參考連結:
http://ericbbs.blogspot.com/2007/10/vpn-pptp.html
http://cha.homeip.net/blog/archives/2006/10/pptp_vpn.html
http://www.phparchitecture.com/howto_show.php?id=3&showall
http://en.wikipedia.org/wiki/Microsoft_Point-to-Point_Encryption
http://en.wikipedia.org/wiki/MS-CHAP

然後實做client:
下載pptp-1.7.2.tar.gz,make,install
安裝後,除了執行檔,還會產生一個設定檔/etc/ppp/options.pptp,裡面有註解,其看起來像是為了連到Microsoft VPN所設定的...

編輯/etc/ppp/options

編輯/etc/ppp/peer/$TUNNEL
pty "pptp $SERVER --nolaunchpppd"
name $DOMAIN\\$USERNAME
#這裡remotename的定義可以對應到/etc/ppp/chap-secrets
remotename PPTP
#這是通道加密的方法,開啟這個,可以使用40bits或128bits的加密方式,(參考Microsoft的加密等級)
require-mppe
file /etc/ppp/options.pptp
ipparam $IPPARAM

註解: $TUNNEL  所要呼叫的設定檔,裡面有server的位置,還有相關設定
        $SERVER  server的IP位置
        $DOMAIN   還不了解...可以省略
        $USERNAME  帳號的名稱,需對應/etc/ppp/chap-secrets內的某一列的”user_name”
        $IPPARAM 這個參數,會變成ip-up script的第六個輸入參數,我們可以在ip-up.local建立自己的script,並且使用它

編輯/etc/ppp/chap-secrets
“user_name”    “pptpd_hostname”    “password”    “allow-source-ip”
第二欄可以關聯/etc/ppp/options.pptpd的name的設定,所以這裡設定為PPTP,也可設定”*”,代表wildcard
第四欄設為”*”,應該代表不限制pptp server的目的ip

啟動pptp-client
pppd call $TUNNEL
#可以cat /var/log/messages,查看運作情形, 如果成功連結到server,可以透過ifconifg可以看到ppp的介面

關閉pptp-client
ps -e | grep pppd #找出pppd的process_id
kill process_id

Routing table for Client:
對於client,當connection建立起來,會有一個host routing entry(就是另一端的IP位址),對於一些簡單的使用情境,像是從家裡連到公司網路,基本上還是需要手動設定routing table,才能使用公司的網路資源,而pppd的package(for FC5 or RedHat),有提供機制來自己寫script增加所需要的routing entry...
在/etc/ppp目錄下,可以看ip-up和ip-down及其他的script,例如只要加入ip-up.local檔案就可以寫自己的script...細節可以man pppd和看if-up的script內容....
這裡要記錄的是,其script的執行時,stdin.stdout and stderror都導到/dev/null,要注意
這樣就可以客製化自己的routing table

PS:一般的情形,都是default routing entry設成另一端VPN的IP位址,或是介面ppp0之類,總之,除了特別的設定,大部分的流量都希望經由VPN...所以pppd也提供一個選項defaultroute來做這樣的事,幫你增加default routing entry到介面ppp0...
所以我一開始很高興的用,不過不會增加...後來想一下,才知道原因
因為我們的pppd就是利用原來default routing entry才能連接到VPN server的,如果真的多增加default routing entry,就代表有兩個default routing entry,當然可以用metric來決定優先權,不過不管用哪一個,對於VPN的建立和流量的導向,都有一個是我們不希望的(因為routing table是所有程式共用的).....所以pppd不會多增加一個default routing entry(/var/log/messages有顯示),除非VPN的建立不是透過default routing entry,而是透過自己LAN上的一台VPN Server

參考連結:
http://pptpclient.sourceforge.net/howto-debian.phtml#configure_by_hand
http://ppc52776.blogspot.com/2008/12/linux-pptp-client-windows-vpn-server.html
http://www.cyberciti.biz/tips/howto-configure-ubuntu-fedora-linux-pptp-client.html

2009年12月12日 星期六

unix shell script來處理時間

#!/bin/bash

now_sec=$(expr `date +%H` \* 60 \* 60 + `date +%M` \* 60 + `date +%S`) 
echo $now_sec 

time_stamp=$(date +"%H %M %S"); 
now_sec=$(expr $(echo $time_stamp | awk '{print $1}') \* 3600) 
now_sec=$(expr $now_sec + $(echo $time_stamp | awk '{print $2}') \* 60) 
now_sec=$(expr $now_sec + $(echo $time_stamp | awk '{print $3}') ) 
echo $now_sec 

#the MSYS doesn't have bc command 
#now_sec=$(echo "$(date +'%H * 3600 + %M * 60 + %S')" | bc ) 
#echo $now_sec 

now_sec=$(($(date +' 10#%H * 3600 + 10#%M * 60 + 10#%S'))) 
echo $now_sec 


這裡列出如何用linux shell script,算出,現在是一天開始的第幾秒,有四個做法,除了第一個做法有疑慮,其它應該都沒問題,不過這樣的演變是有些心路歷程,所以紀錄一下... 

第一個方法,可以看到使用date指令三次,有一種可能錯誤的狀況,就是當時間為1:59:59,第一次date +%H抓到 1, 第二次好死不死,時間變成2:00:00,所以date +%M變成 00,然後date +%S,也許抓到01或02,所以結果可想而知和事實差了1個小時...所以不太好 

第二個方法,就先把時間的字串紀錄下來,然後再透過awk來各別處理...雖然沒問題,但是有點冗長 

第三個方法是我發現date輸出的格式,可以有些調整,所以加了一些輔助的字元,然後轉向給bc這指令算出... 
其實在考慮bc指令前,我有想過expr指令,不過我發現有些困難... 
首先expr指令的算式,各個operator and operand都需要空白隔開...這應該對shell script熟的人,覺得是常識,我還算菜鳥...CC 
再來這個*的運算符號,必須要這樣\*,前面加個escape符號隔開,否則會告訴你說syntax error... 
然後我想出了這個$(expr `date +'%H \* 360 + %M \* 60 + %S'`) 或者這樣$(expr $(date +'%H \* 360 + %M \* 60 + %S')),結果都是syntax error,我搞了半天,還是參不出道理...結果是放棄,換了bc這指令 

其實搞這些,主要是做些實驗,每隔固定時間,做一些存取動作,然後將結果和時間標記存成.csv的格式,而我是在vmware的linux環境下做的,當我開心的寫好script,開始給它一天時間,去收集資料後,才發現到vmware有個bug,就是vmware下的guest os,時間會不準,所以我那個收集資料的script,就破功了...嗚嗚...我google了一下,好像有解決方法,不過我沒去試,因為我想到,如果某個條件後,就可以停止收集資料,那電腦就會一直開著,直到我發現,然後才有機會關掉電腦,這樣有點不環保,浪費電...而在vmware的linux環境下,雖然有指令可以關機,不過關的是vmware的linux,而不是把電腦關機,所以我選擇在windows上執行這個script,當然,windows認不得這個linux shell script,而我也不太想學windows的shell script,所以弄了個MSYS的東東,用它來解譯我之前寫的linux shell script,同時找出在windows下如何透過cmd下命令,來關機,然後加進我寫的shell scirpt,這樣就蠻順心如意了...哈哈 

可是問題又來了,bc這指令沒有也,雖然我可以找到bc的source code透過MinGW編譯出來,或著用cygwin這個比較完善的unix環境(我想它應該有bc),不過我沒選擇前兩條路,我又在shell script這裡下工夫,我又發現,如果這樣寫$((...)),裡面的...會當作算式處理,然後我一開始時是這樣寫的$(($(date +' %H * 3600 + %M * 60 + %S'))),結果跑一段時間就會停掉,檢查一下,發現是因為如果像是01. 02. 012, 其實是被當八進位處理,所以實際十進位是1. 2. 10, 而如果出現08. 09,就會沒法處理,因為八進位只允許0~7,結果再google一下,發現到只要前面加個10#就會告訴shell interpreter,這個數值就會被用十進位來解釋 

看來我希望的目的是達到了...還有一個"date +%s"(小寫),它是給出從1970/1/1到現在的時間秒數,也是可以考慮的時間處理方法 

最後附上windows的關機指令 
關機 shutdown -s 
重開機 shutdown -r 
shutdont -?,查一下,說的很清楚

補充(20091228):
把bash的wildcard(*)關掉,也可以(注意空白)
#!/bin/bash
set -f
now_sec=$(expr $(date +'%H * 360 + %M * 60 + %S'))
echo $now_sec

相關連結:

2009年7月30日 星期四

C 的字串...char* 和 char[]

#include <stdio.h>
#include <string.h>

typedef struct {
    char name[20];
    long id;
    long long salary;
} Personal1;

typedef struct {
    char *name;
    long id;
    long long salary;
} Personal2;

Personal1 p1={"Charlie", 1l, 45000l};
Personal2 p2={"Richard", 2l, 45000l};

int main(void)
{
    printf("name:%s id:%ld salary:%ld\n", p1.name, p1.id, p1.salary);
    printf("name:%s id:%ld salary:%ld\n", p2.name, p2.id, p2.salary);

    strcpy(p1.name, "test1");
    //strcpy(p2.name, "test2");  //這行可以compiler過,不過程式執行會當在這

    printf("name:%s id:%ld salary:%ld\n", p1.name, p1.id, p1.salary);
    printf("name:%s id:%ld salary:%ld\n", p2.name, p2.id, p2.salary);

    return 0;
}


首先,這程式有個錯誤的理解,就是在宣告p1.p2同時填入struct裡的內容時,p2的填入過程會填錯...意思是name.id及salary會互相覆蓋之類的...
不過結果不會也,compiler會很聰明的配置一塊區域,給name,然後指向它,其它就正確的填入應該的位置...
接下來又發生一個問題,就是註解掉的那一行,雖然可以編譯通過,不過執行時,會發生Access violation的錯誤....
猜測,這代表編譯器會配置空間放字串,不過是放在唯讀區域

另外又讓我弄了一個實驗,程式如下:
#include <stdio.h>

char test1[]="Charlie";
char *test2="Richard";

int main(void)
{
    printf("%s\n",test1);
    printf("%s\n",test2);
    strcpy(test1,"test1");
    //strcpy(test2,"test2");  //這行可以compiler過,不過程式執行會當在這
    printf("%s\n",test1);
    printf("%s\n",test2);
    return 0;
}

現在我們知道,這兩種預宣告字串內容的方法,對於compiler配置的方法是不同的...

char test1[]="Charlie"; 配置剛好的記憶體空間,並且從literal constant區域複製字串內容過來,而test1只是個常數,代表這個配置空間的第一個位置

char *test2="Richard"; 配置一個指標變數,並且複製literal constant區域內某字串的第一個位置值,所以*test2指向literal constant這個區域,由於唯讀,所以對其修改會產生Access violuation....

另外這些區域的保護作用,也不是編譯器說了算,是要OS(認出來做處裡)和CPU(的機制)互相配合,才可以實現....
若是某些embedded system的情境下,有可能是literal constant的區域(section)是放在唯讀記憶體(或flash),所以無法寫入,或者寫也寫不進,如果經過適當的處理(Relocate 和適當的搬移),把literal constant區域複製到RAM上,則存取就沒問題了

相關連結:
http://twpug.net/docs/ccfaq/node16.html#q:1.32
http://www.yuanma.org/data/2007/0305/article_2375.htm
http://birdegg.wordpress.com/2006/10/21/re-問題-cc中char與char的差異/

2009年5月15日 星期五

Wake on LAN 軟體和介紹

Wake on LAN,就是透過Ethernet來啟動主機,主機有些需求及設定(參考相關文章),
軟體方面就是送個magic packet...
可以在LAN運作,也可以跨網來運作,不過跨網運作,需要Router支援

基本上這個magic packet是個UDP封包,不過它的DATAGRAM,包括了一串6個位元組的0xFF同步串流(Sync Stream),然後是重複16次要喚醒主機的MAC位址,所以DATAGRAM長度是102個位元組

建議是用UDP port 7,不過用Wireshark來監看時,它會以為是ECHO協定的request...
PS : 在公司測試時,發現有一台機器會回我ECHO協定的Response(我又不方便問這台機器是做啥的),不過也許是這個原因,讓Solarwind的Wake-On-LAN軟體(只能用port 7),沒法成功喚醒我希望喚醒的主機


例如AMD的magic_pkt.exe是用Port 2304,Wireshark可以辨識出來,
基本上,如果不是用了一些有名號的協定所用的port,Wireshark都可以分辨出來
或者,用Port 9,也是建議選項(也許我應該找協定規格看看....)

關於Router的支援:

就我的認知,Router(或IP分享器)的支援,需要開放一個Port(7或9),所有進來的封包,都要修改IP目的位址為255.255.255.255,這樣封包的目的MAC位址也會變成FF-FF-FF-FF-FF-FF,然後送到LAN廣播去

我們不需要將目的MAC位址換成要喚醒主機的MAC位址,被喚醒的主機是檢查UDP的DATAGRAM來確定是否要喚醒,當然,也許置換成喚醒主機的MAC位址,也可以,不過沒試過...

這樣的設定,有很大的風險,只要透過這個Port,就可以對LAN內的機器做廣播,要是某一台機器有一些漏洞,那就中招了,所以應該多些規則來限制,例如只能是UDP封包,還有能辨識出Magic Packet的封包,取出要喚醒機器的MAC位址,來和設定允許主機的MAC位址列表來比對,不過這樣Router的Loading就大了(或者稱是特殊型的NAT)

PS 1:出個題目,用Linux主機來設定這樣的功能,有機會試試看!!!
PS 2:我不知道有哪些IP分享器有支援,事實上,跨網的運作我也沒試過...
PS 3:下面連結,介紹了三款軟體,在LAN內測試時,
        若有需要IP位址,就輸入255.255.255.255,若有需要NETMASK,也輸入255.255.255.255

注意事項:
1. 有些舊機型,雖然有支援,不過如果有斷電的情形(像是插頭拔掉再插回去),會無法initial,監控magic packet
2. 如果機器是按著power鍵來關掉的,即使有支援,機器也會無法監控magic packet

Qt Creator練習:這個題目很簡單,拿來練習工具的使用,蠻好的,之後也許寫篇"Qt Creator的使用心得"
下載

用C++ Builder寫Wake on LAN的功能:
http://hugolin888.blogspot.com/2007/02/wake-on-lan.html

透過網站服務來傳送magic packet...蠻方便的,不過還沒試過
http://www.dslreports.com/wakeup
http://www.wakeonlan.me/

軟體:
http://www.amd.com/us-en/assets/content_type/utilities/magic_pkt.exe
http://www.solarwinds.com/products/freetools/wake_on_lan.aspx
http://www.depicus.com/wake-on-lan/wake-on-lan-gui.aspx

參考連結:
http://www.wretch.cc/blog/josephphoto/3511150
http://www.wells.hk/ws_toolsdetail.php?tools_id=1103103253
http://myhome.ethome.com.tw/xanche/p200708300.htm
http://www.smallnetbuilder.com/content/view/29941/53/
http://wordpress.morezman.com/?p=100
維基百科