2014年4月22日 星期二

IPv6的封包傳送的情境

目前正在研究,IPv6封包傳送的方式。

依IPv4的經驗,
當我要傳送出去的目的端位址,
是依目前的route table來判斷,
要送去哪一個介面。

命令提示字元輸入
route print

而要判斷是否為同一個network,則必需要使用到網路位址(IP)與網路遮罩做AND運算元的動作。
例如我要傳送一個封包到192.168.1.89,
則我route table要由下往上看。
先把網路遮罩(255.255.255.255)與192.168.1.89做AND運算元的動作,
255.255.255.255 & 192.168.1.89 = 192.168.1.89
並不與網路目的地255.255.255.255相同,
因此再往上比對上一個。

一直到比對到了倒數第7個,
先把網路遮罩(255.255.255.0)與192.168.1.89做AND運算元的動作,
255.255.255.0 & 192.168.1.89 = 192.168.1.0
與網路目的地192.168.1.0相同,因此會把這一個封包送到介面(192.168.1.100)

而當我要傳送一個封包到168.95.1.1(HiNet DNS),
一樣是由最底下開始比對,
一直到最上面那一筆做運算,
0.0.0.0 & 168.95.1.1 = 0.0.0.0
與網路目的地0.0.0.0相同,因此會把這一個封包送到介面(192.168.1.100)
並且透過把封包傳給Gateway(192.168.1.254)

以上是IPv4的情況。

在IPv6其實是差不多的。

命令提示字元輸入
route print


而要判斷要把封包傳送到哪一個介面,一樣要使用網路目的地這個東東。
而這一個組成結構是IPv6/Prefix
而運算的方式跟IPv4差不多。
若我要傳送資料到目的位址(2001:470:871c:581:bd81:7828:ca57:8888)
prefix是8的意思是說IPv6的128 bit前8bit是1,其餘的都是0。
則把目的位址PrefixAND運算元的動作。
2001:470:871c:581:bd81:7828:ca57:8888 & FF00:: = 2000::
結果並不等於ff00::
因此,再往上尋找。

一直到了到數第10個,
2001:470:871c:581:bd81:7828:ca57:8888 & FFFF:FFFF:FFFF:FFFF:: = 2001:470:871c:581::
結果與網路目的(2001:470:871c:581::)相同,
因此就把封包送到介面16。

若我想把封包送到2001:4860:4860::8888 (Google IPv6 DNS)
一樣是由最底下開始比對,
一直到最上面那一筆做運算,
:: & 2001:4860:4860::8888 = ::
與網路目的地::相同,因此會把這一個封包送到介面16,
並且透過把封包傳給Gateway(fe80::250:18ff:fe22:4491)
而這個fe80::250:18ff:fe22:4491剛好會是router的LAN port的IPv6 Link-Local Address

而若想知道介面代號指的是哪一個介面的話,可以使用下面的指令
netsh interface ipv6 show interface

2014年4月21日 星期一

tracert

在windows下要了解我的封包是如何傳送的,
可以使用tracert這一個指令。

若想知道對方的server是否還活著,
也可以使用ping這一個指令。

2014年4月18日 星期五

如何查詢目前的網路狀態

在windows下要查詢本機端的網路狀態,
最簡單的方式就到「命令提示字元」輸入ipconfig /all指令,
最完整的本機端完路設定就會出現了。

而若要透過視窗的方式表示出來的話,
則依「控制台」→「網路和網際網路」→「網路連線」
對「區域連線」按右鍵,
選擇「狀態」,再選擇「詳細資料」即可。



參考資料:
Windows 7 無法使用分享器上網時,應如何檢查設定?

2014年4月16日 星期三

RAMDisk on win7

之前的操作環境都是在XP,
一直到今年四月,
M$確定開始不支援XP了,
因此開始把操作環境改成Windows 7,
用到今天,突然我用的VSuite Ramdisk突然沒有辦法使用了。
看了一下,原來在Windows 7只能使用30天,
本來想支持一下正版的,
看了一下價錢,
3千多元,
因為我不是重度使用者,
若1千多元我就可以接受。

找到一個可以在windows 7下面使用的RamDisk軟體。
看起來不錯。
先用一陣子再說。

[2014.06.24 補充]
用了一陣子之後,
覺得跟之前的沒有什麼不一樣,
重點是免費的!!!
官方網頁

參考資料:
RAM Disk for Windows XP, Vista, 7 and 8
[更新]Ramdisk Windows 7 筆電加速與優化(使用SoftPerfect RAM Disk)
RamDisk on XP

PackEth

這個東西看起來可以自訂測試封包,
或許之後會用的到!



參考資料:
PackEth for Windows!

2014年4月9日 星期三

如何自定bool type

現在的code竟然沒有bool type,
上網找了一下,
有以下幾個方式可以自己定義。

Option 1

typedef int bool;
#define true 1
#define false 0

Option 2
typedef int bool;
enum { false, true };

Option 3
typedef enum { false, true } bool;

Option 4 (C99)
#include <stdbool.h>

Explanation
Options 1, 2 and 3 will have in practice the same identical behavior. #2 and #3 don't use #defines though, which in my opinion is better.
Option 4 will work only if you use C99 and it's the "standard way" to do it. Choose this if possible.
If you are undecided, go with #3!

參考資料:
C doesn't have any built in boolean types. What's the best way to use them in C?

typedef 與 link list的配合使用

今天要建立一個link list,
必定要使用到struct,
例如:

struct node_tag {
  int data;
  struct node_tag *link;
};
就是建立一個struct,而這一個struct裡面也有一個成員,
剛好就是這一個建立的struct。

而在使用這一個struct時,
直接宣告
struct node_tag Object;
Object.data = 2;
Object.link = NULL;

就可以了。

但是為了讓可讀性更好,
我嘗試修改為
typedef struct node_tag {
  int data;
  struct node_tag *link;
} node;
如此一來,在使用這一個struct時,
直接宣告
node Object;
Object.data = 2;
Object.link = NULL;


雖然這樣已經很不錯了,
但是,我希望可以更簡化。

修改如下
typedef struct node_tag {
  int data;
  node *link;
} node;

但是,這樣會有錯誤,
error: expected specifier-qualifier-list before 'node'
因為在宣告link的時候,
typedef struct node_tag node;
還沒有被建立完成。

此時,我天馬行空的想了一下,
typedef應該是標記某兩個label是同一個東西,
這個東西應該在compiler的時候不會被檢查,而是在link的時候,被指到同一個地方。
因此,我把內容改成如下:
typedef struct node_tag node;
struct node_tag {
  int data;
  node *link;
};
這樣就可以過了,
而且還蠻簡化的。

而我另外還看到另一個寫法
typedef struct node {
  int data;
  struct node *link;
} node;
這樣雖然完成typedef前跟完成type後,都是使用node為名稱,
但是,在定義node的內容仍出現struct node *link;
因此,這一個方式我個人不會採用。

========== 外記 ==========
另外有額外遇到一個情況,我宣告完typedef在h檔之後,
自定的函式的第一個參數Compiler仍出現錯誤。
error: expected ')' before '*' token
這一個錯誤就是沒有認到這一個typedef,
不過,我覺得很奇怪,
我定義typedef在a.h
而b.h宣告這一個function,
同時,b.h也有include a.h,
為什麼會認不到呢?

最後找到原因是,
我在b.h也有include a.h
因此在這一次的Compiler事實上是a.h去include b.h,
然後拿去Compiler,
因此,此宣告的函式是在typdef位置的上面,所以才會出現Compiler ERROR。

解法是在a.h拿掉b.h,
而直接把b.h加在a.c裡面。

之前我的習慣是把要加的.h檔都加在.h裡面,
原來還會遇到這個問題啊~

參考資料:
typedef
Linked list: function with a struct ptr parameter in header file error
LinkedList Struct Typedef in C

2014年4月3日 星期四

C/C++ 字串分析函式

========== 檔案相關 ==========
開啟檔案
FILE * fopen ( const char * filename, const char * mode );
fopen - C++ Reference
C 語言標準函數庫分類導覽 - stdio.h fopen()

關閉檔案
int fclose ( FILE * stream );
fclose - C++ Reference
C 語言標準函數庫分類導覽 - stdio.h fclose()

讀取資料
char * fgets ( char * str, int num, FILE * stream );
stdio.h 中的 fgets() 從檔案一行一行的讀取資料,共需三個參數,第一個參數為儲存輸入資料的陣列,第二個參數為該行最多幾個字元,第三個參數為指向結構 FILE 的指標。
fgets - C++ Reference
C 語言標準函數庫分類導覽 - stdio.h fgets()

========== 字串相關 ==========
搜尋函式:
const char * strchr ( const char * str, int character );
string.h 的函數 strchr() ,需要一個字串及一個字元當作參數,然後搜尋字元在字串中第一次出現的位置,回傳該位置的指標。
strchr - C++ Reference
C 語言標準函數庫分類導覽 - string.h strchr()

const char * strstr ( const char * str1, const char * str2 );
Parameters 1 是輸入字串,Parameters 2 是找尋字串,strstr 會先將頭一次比對成功的 pointer 回傳,也就是如果要找尋 appleboyappleboy 字串中的 boy,函式會回傳第一次比對成功的 boy pointer,而並非回傳最後一個比對到的。
strstr - C++ Reference
[C/C++] cstring (string.h) 搜尋函式:strstr, strchr


size_t strspn ( const char * str1, const char * str2 );
這有兩個解釋
1. 由字串開始,str1哪一個位置開始不包含str2裡面的字元,若第一個字元就不包含在str2裡面,當然就是回傳0(0 base)
2. strspn()會傳回兩個字串開始不匹配的第一個字元索引位置,否則傳回0
我覺得應該是1的這一個解釋比較正確,若有空可以來做一個實驗。
strspn - C++ Reference
C 語言標準函數庫分類導覽 - string.h strspn()
strspn()—返回从字符串开头连续包含特定字符的字符数目

切割函式
char * strtok ( char * str, const char * delimiters );
string.h 的函數 strtok() ,需要兩個字串參數,以第二個參數字串的內容切割第一個參數字串。
strtok - C++ Reference
C 語言標準函數庫分類導覽 - string.h strtok()
[C&C++] strtok
若一開始字串為
char buffer[] = "a string,of ,,tokens";
char *token = NULL;
char *line = NULL;
char *final = NULL;
原本記憶體內容為
a string,of ,,tokens
當執行完一次
token = strtok (buffer, " ,");
則記憶體內容為
a'\0'string,of ,,tokens
因此,若列印token的話,結果為a

再執行一次
line = strtok (NULL, " ,")
則記憶體內容為
a'\0'string'\0'of ,,tokens
因此,若列印line的話,結果為string

若這個時候,執行
final = strtok (NULL, "");
則記憶體內容不變,但,
列印final的話,結果為of ,,tokens

複製函數
char * strcpy ( char * destination, const char * source );
string.h 的函數strcpy() ,需要兩個字串當作參數,然後把第二個參數的字串複製到第一個參數的字串中,然後回傳第一個參數。
strcpy - C++ Reference
C 語言標準函數庫分類導覽 - string.h strcpy()

長度計算
size_t strlen ( const char * str );
strlen - C++ Reference
C 語言標準函數庫分類導覽 - string.h strlen()

字串比對
int strcmp (const char * str1, const char * str2 );
string.h 的函數strcmp() ,需要兩個字串當作參數,比較兩個字串是否相等,相等就回傳0,第一個字串大於第二個字串回傳正值,反之回傳負值。
strcmp - C++ Reference
C 語言標準函數庫分類導覽 - string.h strcmp()

int strcasecmp (const char * str1, const char * str2 ); // 非標準函式
strcasecmp()—判断字符串是否相等(忽略大小写)

判斷字元
int isspace (int c );
判斷此字元是否為空白
For the "C" locale, white-space characters are any of:

' ' (0x20) space (SPC)
'\t' (0x09) horizontal tab (TAB)
'\n' (0x0a) newline (LF)
'\v' (0x0b) vertical tab (VT)
'\f' (0x0c) feed (FF)
'\r' (0x0d) carriage return (CR)

isspace - C++ Reference
C 語言標準函數庫分類導覽 - ctype.h isspace()

int isalpha (int c );
Check if character is alphabetic (function )

int isdigit (int c );
Check if character is decimal digit (function )

2014年4月2日 星期三

vim - 複製

想要把第5行到第10行的內容貼到第12行之後,
要使用下面的指令
:5,10 co 12

參考資料:
[保留] 请问如何用vi 复制第5行到第10行并粘贴到第12行之后?

2014年4月1日 星期二

xshell軟體

之前遠端連到linux server都是使用putty或pietty(中文支援比較好)

最近又開始在玩linux了,
發現xshell這個新東西實在非常好用。

其中最好用的就是tab視窗,
尤其是我們常常一次就連很多個連線的人非常的需要。

參考資料如下: [網路工具] Xshell 4 超好用的 SSH 連線工具 - 強力推薦 xshell & xftp