gre.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /* GRE flag bits */
  2. enum {
  3. GRE_chksum = (1<<15),
  4. GRE_routing = (1<<14),
  5. GRE_key = (1<<13),
  6. GRE_seq = (1<<12),
  7. GRE_srcrt = (1<<11),
  8. GRE_recur = (7<<8),
  9. GRE_ack = (1<<7),
  10. GRE_ver = 0x7,
  11. };
  12. /* GRE protocols */
  13. enum {
  14. GRE_sna = 0x0004,
  15. GRE_osi = 0x00fe,
  16. GRE_pup = 0x0200,
  17. GRE_xns = 0x0600,
  18. GRE_ip = 0x0800,
  19. GRE_chaos = 0x0804,
  20. GRE_rfc826 = 0x0806,
  21. GRE_frarp = 0x0808,
  22. GRE_vines = 0x0bad,
  23. GRE_vinesecho = 0x0bae,
  24. GRE_vinesloop = 0x0baf,
  25. GRE_decnetIV = 0x6003,
  26. GRE_ppp = 0x880b,
  27. };
  28. int
  29. sprintgre(void *a, char *buf, int len)
  30. {
  31. int flag, prot, chksum, offset, key, seq, ack;
  32. int n;
  33. uchar *p = a;
  34. chksum = offset = key = seq = ack = 0;
  35. flag = NetS(p);
  36. prot = NetS(p+2);
  37. p += 4; len -= 4;
  38. if(flag & (GRE_chksum|GRE_routing)){
  39. chksum = NetS(p);
  40. offset = NetS(p+2);
  41. p += 4; len -= 4;
  42. }
  43. if(flag&GRE_key){
  44. key = NetL(p);
  45. p += 4; len -= 4;
  46. }
  47. if(flag&GRE_seq){
  48. seq = NetL(p);
  49. p += 4; len -= 4;
  50. }
  51. if(flag&GRE_ack){
  52. ack = NetL(p);
  53. p += 4; len -= 4;
  54. }
  55. /* skip routing if present */
  56. if(flag&GRE_routing) {
  57. while(len >= 4 && (n=p[3]) != 0) {
  58. len -= n;
  59. p += n;
  60. }
  61. }
  62. USED(offset);
  63. USED(chksum);
  64. n = sprint(buf, "GRE(f %4.4ux p %ux k %ux", flag, prot, key);
  65. if(flag&GRE_seq)
  66. n += sprint(buf+n, " s %ux", seq);
  67. if(flag&GRE_ack)
  68. n += sprint(buf+n, " a %ux", ack);
  69. n += sprint(buf+n, " len = %d/%d) ", len, key>>16);
  70. if(prot == GRE_ppp && len > 0)
  71. n += sprintppp(p, buf+n, len);
  72. else
  73. n += sprintx(p, buf+n, len);
  74. return n;
  75. }