int pppWrite(int pd, const u_char *s, int n)
为了将数据转化成PPP协议中的数据格式需要在调用pppWrite函数之前对一些数据初始化
for(i=0;i<4;i++) {
pc->outACCM[i] = 0xFF;
}
pc->outACCM[15] = 0x60;
详细分析如下:
在转换数据的时候都调用函数
static struct pbuf *pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM)
而在判断哪些数据不转换,哪些数据需要转换的时候由以下函数实现
if (outACCM && ESCAPE_P(*outACCM, c)) {
*((u_char*)nb->payload + nb->len++) = PPP_ESCAPE;
*((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS;
} else {
*((u_char*)nb->payload + nb->len++) = c;
}//end else
只有outACCM && ESCAPE_P(*outACCM, c) 这个满足1的条件下才进行数据的转换,否则直接输出该数据;而在PPP协议中规定,当传输的数据小于0x20的时候需要将数据格式转换成[0x7D,0x20^该数据],故只要将数据小于0x20的时候将outACCM && ESCAPE_P(*outACCM, c)得1即可;
#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & pppACCMMask[c & 0x07])
static u_char pppACCMMask[] = {
0x01,
0x02,
0x04,
0x08,
0x10,
0x20,
0x40,
0x80
};
outACCM ESCAPE_P(*outACCM, c)
outACCM (accm)[(c) >> 3] pppACCMMask[c & 0x07]
0xFF c=0x00 c>>3=0x00 (accm)[00]=? pppACCMMask[00&0x07]=0x01
0xFF c=0x01 c>>3=0x00 (accm)[00]=? pppACCMMask[01&0x07]=0x02
0xFF c=0x02 c>>3=0x00 (accm)[00]=? pppACCMMask[02&0x07]=0x04
0xFF c=0x03 c>>3=0x00 (accm)[00]=? pppACCMMask[03&0x07]=0x08
0xFF c=0x04 c>>3=0x00 (accm)[00]=? pppACCMMask[04&0x07]=0x10
0xFF c=0x05 c>>3=0x00 (accm)[00]=? pppACCMMask[05&0x07]=0x20
0xFF c=0x06 c>>3=0x00 (accm)[00]=? pppACCMMask[06&0x07]=0x40
0xFF c=0x07 c>>3=0x00 (accm)[00]=? pppACCMMask[07&0x07]=0x80
0xFF c=0x08 c>>3=0x01 (accm)[01]=? pppACCMMask[08&0x07]=0x01
0xFF c=0x09 c>>3=0x01 (accm)[01]=? pppACCMMask[09&0x07]=0x02
0xFF c=0x0a c>>3=0x01 (accm)[01]=? pppACCMMask[0a&0x07]=0x04
0xFF c=0x0b c>>3=0x01 (accm)[01]=? pppACCMMask[0b&0x07]=0x08
0xFF c=0x0c c>>3=0x01 (accm)[01]=? pppACCMMask[0c&0x07]=0x10
0xFF c=0x0d c>>3=0x01 (accm)[01]=? pppACCMMask[0d&0x07]=0x20
0xFF c=0x0e c>>3=0x01 (accm)[01]=? pppACCMMask[0e&0x07]=0x40
0xFF c=0x0f c>>3=0x01 (accm)[01]=? pppACCMMask[0f&0x07]=0x80
由此数据可以找到一些数据的规律,当c每8次循环变换,c>>3位才有一次变化,而pppACCMMask[c&0x07]则重复变化,也就是说,我们要求在c小于0x20的时候才进行数据转换只要满足c小于0x20所有数据在进行c>>3运算后得到的数据(accm)[(c) >> 3]使得该数据里面的数据为0xff即可,因为只有0xff&pppACCMMask[c & 0x07]才能满足条件得1,使得程序进行数据转换。0x00~0x08 0x09~0x0F 0x10~0x18 0x19~0x1F 需要使得(accm[0],accm[1],accm[2],accm[3]的初始值得0xFF).
在RFC1661中有规定,当PPP数据在传输的时候,如果数据域里面包含0x7E 0x7D需要对其进行转换,转换的结果为0x7E -> 0x7D 0x5E
0x7D -> 0x7D 0x5D
这就需要我们再次初始化accm[]的值 经过以上的规律可以找到0x7D 0x7E是在accm[15]中进行初始化因为
0x00~0x08 -> accm[0]
0x09~0x0F -> accm[1]
0x10~0x18 -> accm[2]
0x19~0x1F -> accm[3]
...... -> ......
0x79~0x7F -> accm[15]
而0x7D和0x7E位于数据位的第6位和第7位,所以需要将accm[15]的值得0x60 这样才能与0x20 0x40相与的值得1满足条件使得程序进入数据转化过程。。。。。。