您的位置:首页 > 其它

OSPF的lsa校验和计算方法!

2015-04-02 22:51 211 查看
这几天在写一个OSPF的自动报文工具,生成LSA时,需要计算校验和,不然设备不会处理LSU报文。各处查找校验和生成的方法,未果!

只知道LSA的校验和是叫Fletcher Checksum, http://en.wikipedia.org/wiki/Fletcher%27s_checksum。刚开始没看懂,后来查了其他blog, 就是

出自RFC905:

ISO Transport Protocol Specification ISO DP 8073,附录B,摘录如下:

ANNEX B - CHECKSUM ALGORITHMS

(This annex is provided for information for implementors and is

not an integral part of the body of the standard.)

B.1 SYMBOLS ----用到的变量

The following symbols are used:

C0 variables used in the algorithms ----存储校验码

C1

i number (i.e. position) of an octet within the TPDU (see

12.1)

n number (i.e. position) of the first octet of the checksum

parameter

L length of the complete TPDU

X value of the first octet of the checksum parameter

Y value of the second octet of the checksum parameter.

B.2 ARITHMETIC CONVENTIONS ----运算说明

Addition is performed in one of the two following modes:

a) modulo 255 arithmetic; ----模运算

b) one's complement arithmetic in which if any of the

variables has the value minus zero (i.e. 255) it shall be

regarded as though it was plus zero (i.e. 0).

B.3 ALGORITHM FOR GENERATING CHECKSUM PARAMETERS

B.3.1 Set up the complete TPDU with the value of the checksum

parameter field set to zero.
----报文中的校验码字段设置为0

B.3.2 Initialize C0 and C1 to zero. ----初始化C0, C1

B.3.3 Process each octet sequentially from i = 1 to L by:----根据报文的长度,8bit一个单元

a) adding the value of the octet to C0; then ----C0 = C0 + TPDU[i]

b) adding the value of C0 to C1. ----C1 = C1 + C0

B.3.4 Calculate X and Y such that ----下面这两步没看懂

X = -C1 + (L-n).CO

Y = C1 - (L-n+1).C0

B.3.5 Place the values X and Y in octets n and (n + 1) ----校验码就是XY

respectively.

[A Note describing the above algorithm in mathematical notation

has been omitted from this copy.]

B.4 ALGORITHM FOR CHECKING CHECKSUM PARAMETERS

B.4.1 Initialize C0 and C1 to zero.

B.4.2 Process each octet of the TPDU sequentially from i = 1 to

L by:

a) adding the value of the octet to C0; then

b) adding the value of C0 to C1.

B.4.3 If, when all the octets have been processed, either or

both of C0 and C1 does not have the value zero, the checksum

formulas in 6.17 have not been satisfied.

NOTE - The nature of the algorithm is such that it is not

necessary to compare explicitly the stored checksum bytes.

=================================================================

其实看了上面还是不明白,就是因为上面一部没看懂。

然后找了开发的同事,估计就是网上说的Zebra中的方法。代码如下:

u_int16_t
fletcher_checksum(u_char * buffer, const size_t len, const uint16_t offset)
{
u_int8_t *p;
int x, y, c0, c1;
u_int16_t checksum;
u_int16_t *csum;
size_t partial_len, i, left = len;

checksum = 0;

ROS_ASSERT(offset < len);

/*
* Zero the csum in the packet.
*/
csum = (u_int16_t *) (buffer + offset);
*(csum) = 0;

p = buffer;
c0 = 0;
c1 = 0;

while (left != 0)
{
partial_len = MIN(left, MODX);

for (i = 0; i < partial_len; i++)
{
c0 = c0 + *(p++);
c1 += c0;
}

c0 = c0 % 255;
c1 = c1 % 255;

left -= partial_len;
}

/* The cast is important, to ensure the mod is taken as a signed value. */
x = (int)((len - offset - 1) * c0 - c1) % 255;

if (x <= 0)
x += 255;
y = 510 - c0 - x;
if (y > 255)
y -= 255;

/*
* Now we write this to the packet.
* We could skip this step too, since the checksum returned would
* be stored into the checksum field by the caller.
*/
buffer[offset] = x;
buffer[offset + 1] = y;

/* Take care of the endian issue */
checksum = htons((x << 8) | (y & 0xFF));

return checksum;
}

只看懂了一部分。不明白算法,也没有python的现成方法,只好拿已知的正确报文,试一试。

#buf = [0x02,0x01,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x80,0x00,0x00,0x05,0x00,0x00,0x00,0x24,

#0x00,0x00,0x00,0x01,0x0a,0x01,0x00,0x01,0x0a,0x01,0x00,0x01,0x02,0x00,0x00,0x01] #校验码dc2a

#buf1 = [0x02,0x01,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x80,0x00,0x00,0x04,0x00,0x00,0x00,0x24,

#0x00,0x00,0x00,0x01,0x0a,0x01,0x00,0x00,0xff,0xff,0x00,0x00,0x03,0x00,0x00,0x01] #校验码5bb8
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: