LSA校验和计算(java源码)

最近在写一个路由模拟工具,由于没有找到java的相关代码,jpcap又没有提供路由协议包解析的类,所以在git开了一个基于jpcap的路由工具包的工程,链接如下:点击打开链接

今天在写这个工具与路由器交互动作时发现lsa的校验和算法找不到java的源码,于是花了一晚上把quagga的校验和计算代码改成了java的。亲测可用,源码如下:

public class lsaChecksum {
	
	public static short	ospf_lsa_checksum (byte[] data)
	{

	  /* Skip the AGE field */
	  int len = data.length; 

	  /* Checksum offset starts from "options" field, not the beginning of the
	     lsa_header struct. The offset is 14, rather than 16. */
	  int checksum_offset = 14;

	  return fletcher_checksum(data, len, checksum_offset);
	}
	/* Fletcher Checksum -- Refer to RFC1008. */
	private static final int MODX=4102;   /* 5802 should be fine */
	private static final int FLETCHER_CHECKSUM_VALIDATE=0xffff;
	/* To be consistent, offset is 0-based index, rather than the 1-based 
	   index required in the specification ISO 8473, Annex C.1 */
	/* calling with offset == FLETCHER_CHECKSUM_VALIDATE will validate the checksum
	   without modifying the buffer; a valid checksum returns 0 */
	public static short	fletcher_checksum(byte[] buffer, int len, int offset)
	{
	  byte[] p;
	  int x, y, c0, c1;
	  short checksum;
	  int partial_len, i, left = len;
	  
	  checksum = 0;
	  p = buffer;
	  c0 = 0;
	  c1 = 0;

	  while (left != 0)
	    {
	      partial_len =left<MODX?left:MODX;// MIN(left, MODX);

	      for (i = 0; i < partial_len; i++)
		{
		  c0 = c0 + (p[i]&0xff);
		  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;

	  if (offset == FLETCHER_CHECKSUM_VALIDATE)
	    {
	      checksum = (short) ((c1 << 8) + c0);
	    }
	  else
	    {
	      /*
	       * 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] = (byte) x;
	      buffer[offset + 1] = (byte) y;
	      for(int ii=0;ii<len;ii++){
	    	  System.out.printf("%x ",buffer[ii]);
	      }
	      /* Take care of the endian issue */
	      checksum = (short) ((x << 8) | (y & 0xFF));
	    }

	  return checksum;
	}
}

单元测试代码如下:

public class lsaChecksumTest {

	@Before
	public void setUp() throws Exception {
	}

	@Test
	public void testOspf_lsa_checksum() {
		byte[] data={0x22,0x02,0x01,0x01,0x03,0x02,0x01,0x01,
				0x03,0x02,(byte) 0x80,0x00,0x00,0x01,0x00,0x00,
				0x00,0x20,(byte) 0xff,(byte) 0xff,(byte) 0xff,0x00,0x01,0x01,
				0x03,0x02,0x01,0x01,0x03,0x01};
		short result=lsaChecksum.ospf_lsa_checksum(data);
		if(result!=(short)0xa975)
			fail("wrong checksum");
	}

}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值