pppoe_disc.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <ip.h>
  4. #include "dat.h"
  5. #include "protos.h"
  6. typedef struct Hdr Hdr;
  7. struct Hdr {
  8. uchar verstype;
  9. uchar code;
  10. uchar sessid[2];
  11. uchar length[2]; /* of payload */
  12. };
  13. enum
  14. {
  15. HDRSIZE = 1+1+2+2
  16. };
  17. static Mux p_mux[] =
  18. {
  19. {"ppp", 0, } ,
  20. {0}
  21. };
  22. enum
  23. {
  24. Overs,
  25. Otype,
  26. Ocode,
  27. Osess,
  28. };
  29. static Field p_fields[] =
  30. {
  31. {"v", Fnum, Overs, "version", } ,
  32. {"t", Fnum, Otype, "type", } ,
  33. {"c", Fnum, Ocode, "code" } ,
  34. {"s", Fnum, Osess, "sessid" } ,
  35. {0}
  36. };
  37. static void
  38. p_compilesess(Filter *f)
  39. {
  40. // Mux *m;
  41. if(f->op == '='){
  42. compile_cmp(pppoe_sess.name, f, p_fields);
  43. return;
  44. }
  45. /*
  46. for(m = p_mux; m->name != nil; m++)
  47. if(strcmp(f->s, m->name) == 0){
  48. f->pr = m->pr;
  49. f->ulv = m->val;
  50. f->subop = Ot;
  51. return;
  52. }
  53. */
  54. sysfatal("unknown pppoe field or protocol: %s", f->s);
  55. }
  56. static void
  57. p_compiledisc(Filter *f)
  58. {
  59. // Mux *m;
  60. if(f->op == '='){
  61. compile_cmp(pppoe_disc.name, f, p_fields);
  62. return;
  63. }
  64. /*
  65. for(m = p_mux; m->name != nil; m++)
  66. if(strcmp(f->s, m->name) == 0){
  67. f->pr = m->pr;
  68. f->ulv = m->val;
  69. f->subop = Ot;
  70. return;
  71. }
  72. */
  73. sysfatal("unknown pppoe field or protocol: %s", f->s);
  74. }
  75. static int
  76. p_filter(Filter *f, Msg *m)
  77. {
  78. Hdr *h;
  79. if(m->pe - m->ps < HDRSIZE)
  80. return 0;
  81. h = (Hdr*)m->ps;
  82. m->ps += HDRSIZE;
  83. switch(f->subop){
  84. case Overs:
  85. return (h->verstype>>4) == f->ulv;
  86. case Otype:
  87. return (h->verstype&0xF) == f->ulv;
  88. case Ocode:
  89. return h->code == f->ulv;
  90. case Osess:
  91. return NetS(h->sessid) == f->ulv;
  92. }
  93. return 0;
  94. }
  95. /* BUG: print all the discovery types */
  96. static int
  97. p_seprintdisc(Msg *m)
  98. {
  99. Hdr *h;
  100. int len;
  101. len = m->pe - m->ps;
  102. if(len < HDRSIZE)
  103. return -1;
  104. h = (Hdr*)m->ps;
  105. m->ps += HDRSIZE;
  106. m->pr = nil;
  107. m->p = seprint(m->p, m->e, "v=%d t=%d c=0x%x s=0x%ux, len=%d",
  108. h->verstype>>4, h->verstype&0xF, h->code, NetS(h->sessid), NetS(h->length));
  109. return 0;
  110. }
  111. static int
  112. p_seprintsess(Msg *m)
  113. {
  114. Hdr *h;
  115. int len;
  116. len = m->pe - m->ps;
  117. if(len < HDRSIZE)
  118. return -1;
  119. h = (Hdr*)m->ps;
  120. m->ps += HDRSIZE;
  121. /* this will call ppp for me */
  122. demux(p_mux, 0, 0, m, &dump);
  123. m->p = seprint(m->p, m->e, "v=%d t=%d c=0x%x s=0x%ux, len=%d",
  124. h->verstype>>4, h->verstype&0xF, h->code, NetS(h->sessid), NetS(h->length));
  125. return 0;
  126. }
  127. Proto pppoe_disc =
  128. {
  129. "pppoe_disc",
  130. p_compiledisc,
  131. p_filter,
  132. p_seprintdisc,
  133. p_mux,
  134. "%lud",
  135. p_fields,
  136. defaultframer
  137. };
  138. Proto pppoe_sess =
  139. {
  140. "pppoe_sess",
  141. p_compilesess,
  142. p_filter,
  143. p_seprintsess,
  144. p_mux,
  145. "%lud",
  146. p_fields,
  147. defaultframer
  148. };