PPP協議的LCP數據報文
對于PPP協議的基礎內容,PPP數據幀以及PPP模式我們都做了介紹。那么這里我們再來講解一下PPP協議的LCP數據報文的內容。通過前面的文章,我們知道,LCP數據報文是在鏈路建立階段被交換的,它作為PPP的凈載荷被封裝在PPP數據幀的信息域中。在鏈路建立階段的整個過程中信息域的內容是在變化的,它包括很多種類型的報文,所以這些報文也要通過相應的字段來區分。
PPP數據幀的協議域固定填充0xC021。
代碼域的長度為一個字節,主要是用來標識LCP數據報文的類型的。在鏈路建立階段時,接收方收到LCP數據報文的代碼域無法識別時,就會向對端發送一個LCP的代碼拒絕報文(Code-Reject報文)。
標識域也是一個字節,其目的是用來匹配請求和響應報文。一般而言在進入鏈路建立階段時,通信雙方無論哪一端都會連續發送幾個配置請求報文(Config-Request報文),而這幾個請求報文的數據域可能是完全一樣的,而僅僅是它們的標識域不同罷了。通常一個配置請求報文的ID是從0x01開始逐步加1的,當對端接收到該配置請求報文后,無論使用何種報文(回應報文可能是Config-Ack、Config-Nak和Config-Reject三種報文中的一種)來回應對方,但必須要求回應報文中的ID(標識域)要與接收報文中的ID一致,當通信設備收到回應后就可以將該回應與發送時的進行比較來決定下一步的操作。
長度域的內容 = 總字節數據(代碼域+標志域+長度域+數據域)。長度域所指示字節數之外的字節將被當作填充字節而忽略掉,而且該域的內容不能超過MRU的值。
數據域的內容根據不同的LCP數據報文的內容也是不一樣的。
下面說一下LCP包括的幾種報文類型,不同的報文在標識域中所填充的內容也不同。
LCP報文主要分為1、鏈路配置報文;2、鏈路終止報文;3、鏈路維護報文。
鏈路配置報文主要包括Config-Request、Config-Ack、Config-Nak和Config-Reject四種報文。
當通信雙方需要建立鏈路時,無論哪一方都需要發送Config-Request報文并攜帶每一端自已所希望協商的配置參數選項。
當接收方收到Config-Request報文時,會在剩下的三種類型的報文中選擇一種來響應對方的請求報文,到底選擇哪種報文來響應對方需依據以下兩個條件:
不能完全識別配置參數選項的類型域,我們知道一個Config-Request報文中會同時攜帶多個配置參數選項,而對于一個支持PPP協議的通信設備也不一定會支持上表中所有列出的配置選項,即使支持,也可能在實際應用中關閉掉某些選項功能。(例如:當使用PPP協議通信的一端可能將一些無用的配置選項都關閉了,而僅支持0x01和0x03兩個配置參數選項,因此當對方發送的Config-Request報文中含有0x04配置選項時,對于本端而言這個配置參數選項就無法識別,也即是不支持這個配置參數選項的協商)。
如果能支持完全識別配置參數選項,但接收端也可能不認可Config-Request報文中配置參數選項數據域中的內容(例如:當一端發送魔術字配置參數選項中的魔術字為全0,而對端認為應該為其它值,這種情況就屬于不支持配置參數選項中的內容)。
所以依據上面的兩個條件,我們就可以明確在回應對方配置請求報文時,采用何種報文回應。
當接收Config-Request報文的一端能識別發送過來的所有配置參數選項且認可所有配置參數選項數據域的內容時,接收端將會給對端回一個Config-Ack報文并將配置請求報文中的配置參數選項原封不動的放置在Config-Ack報文的數據域內(根據協議的規定是不可改變配置參數選項的順序)。當配置請求報文的發送端收到Config-Ack報后,則會從當前階段進入到下一個階段。
當接收Config-Request報文的一端能識別發送端所發送過來的所有配置參數選項,但對部分配置參數選項數據域中的內容不認可時,接收端將會給對端回應一個Config-Nak報文,(注意,是能夠識別,只是對部分參數內容不認可,所以不是Config-Reject報文)該報文中只攜帶不認可的配置參數選項,而這些配置參數選項的數據內容為本端希望的值。然而當接收端收到Config-Nak報文后,會重新發送Config-Request報文,而這個Config-Request報文與上一次所發送的Config-Request報文區別在于那些被對端不認可的配置參數選項的內容被填寫到剛剛協商完后再次發送的Config-Request報文中(Config-Nak報文發送回來的那些配置參數選項)。
當接收Config-Request報文的一端不能識別所有的發送端發送過來的配置參數選項時,此時接收端將會向對端回一個Config-Reject報文,該報文中的數據域只攜帶那些不能識別的配置參數選項(當配置參數選項的類型域不識別時)。當對端接收到Config-Reject報文后,同樣會再次發送一個Config-Request報文,這個配置請求報文與上一次發送的區別在于將不可識別的那些配置參數選項給刪除了。
鏈路終止報文分為Terminate-Request和Terminate-Reply兩種報文。LCP報文中提供了一種機制來關閉一個點對點的連接,想要關斷鏈路的一端會持續發送Terminate-Request報文,直到收到一個Terminate-Reply為止。接收端一旦收到了一個Terminate-Request報文后,必須回應一個Terminate-Reply報文,同時等待對端先將鏈路斷開后,再完成本端的所有斷開的操作。
LCP的鏈路終止報文的數據域與鏈路配置報文的數據域不一樣,鏈路終止報文中無需攜帶各配置參數選項。對于鏈路終止報文也同樣需要ID一致,當接收到Terminate-Reply報文才會做鏈路終止操作。
最后說一下魔術字的含義,這是在鏈路建立過程中比較重要的一個參數,這個參數是在Config-Request里面被協商的,主要的作用是防止環路,如果在雙方不協商魔術字的情況下,某些LCP的數據報文需要使用魔術字時,那么只能是將魔術字的內容填充為全0;反之,則填充為配置參數選項協商后的結果。
魔術字在目前所有的設備當中都是需要進行協商的,它被放在Config-Request的配置選項參數中進行發送,而且需要由自身的通信設備獨立產生,協議為了避免雙方可能產生同樣的魔術字,從而導致通信出現不必要的麻煩,因此要求由設備采用一些隨機方法產生一個獨一無二的魔術字。一般來說魔術字的選擇會采用設備的系列號、網絡硬件地址或時鐘。雙方產生相同魔術字的可能性不能說是沒有的,但應盡量避免,通常這種情況是發產在相同廠商的設備進行互連時,因為一個廠商所生產的設備產生魔術字的方法是一樣的。
我們知道魔術字產生的作用是用來幫助檢測鏈路是否存在環路,當接收端收到一個Config-Request報文時,會將此報文與上一次所接收到的Config-Request進行比較,如果兩個報文中所含的魔術字不一致的話,表明鏈路不存在環路。但如果一致的話,接收端認為鏈路可能存在環路,但不一定存在環路,還需進一步確認。此時接收端將發送一個Config-Nak報文,并在該報文中攜帶一個重新產生的魔術字,而且此時在未接收到任何Config-Request或Config-Nak報文之前,接收端也不會發送任何的Config-Request報文。這時我們假設可能會有以下兩種情況發生:
1.鏈路實際不存在環路,而是由于對方在產生魔術字時與接收端產生的一致,但實際這種情況出現的概率是很小的。當Config-Nak被對端接收到后,應該發送一個Config-Request報文(此報文中的魔術字為Nak報文中的),當對端接收到后,與上次比較,由于接收端已經在Nak報文中產生了一個不同的魔術字,此時接收端收到的Config-Request報文中的魔術字與上次配置請求報文中不一樣,所以接收端可斷定鏈路不存在環路。
2.鏈路實際上確實存在環路,一段時間后Config-Nak報文會返回到發送該報文的同一端。這時接收端比較這個Config-Nak報文與上一次發出去的一樣,因此鏈路存在環路的可能性又增大了。我們知道當一端收到了一個Config-Nak報文時,又會發送一個Config-Request報文(該報文中的魔術字與Config-Nak中的一致),這樣又回到了最初的狀態,在這條鏈路上就會不斷的出現Config-Request、Config-Nak報文,因此這樣周而復始下去,接收端就會認為PPP鏈路存在環路的可能性在不斷增加,當達到一定數量級時,就可認為此鏈路存在環路。(注意,不是第一次受到相同的魔術字就判斷有環路的)
但在實際應用中根據不同設備實現PPP協議的方法,我們在鏈路環路檢測時可采用兩種方法。第一種機制就是如上面所述的,這個過程不斷地重復,最終可能會給LCP狀態機發一個Down事件,這時可能會使LCP的狀態機又回到初始化階段,又開始新一輪的協商。當然對于某些設備還會采用第二種機制,就是不產生任何事件去影響當前LCP的狀態機,而是停留在請求發送狀態。但這時認為鏈路有環路的一端設備需要不斷的向鏈路上發送Echo-Request報文來檢測鏈路環路是否被解除,當接收端收到Echo-Reply報文時,就認為鏈路環路被解除,從而就可能進行后續的PPP的過程。
好了,基本上通過3篇PPP閑談,我們可以比較徹底的了解PPP協議的工作機制和特點,其實,會者不難,協議都是人制訂的,只有簡單易用的協議才會最終保留下來,就像TCP/IP打敗OSI一樣。所以,只要靜下心來,沒有什么高深的。可能這3篇文章里面有部分個人理解錯誤的地方,希望大家可以多提意見,大家共同進步。