aoerr.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <ip.h>
  4. #include "dat.h"
  5. #include "protos.h"
  6. typedef struct {
  7. uchar cmd;
  8. uchar nea;
  9. } Hdr;
  10. enum {
  11. Ocmd,
  12. Onea,
  13. Oea,
  14. Hsize = 2,
  15. };
  16. static Field p_fields[] = {
  17. {"cmd", Fnum, Ocmd, "command", },
  18. {"nea", Fnum, Onea, "ea count", },
  19. {"ea", Fnum, Onea, "ethernet addr", },
  20. nil
  21. };
  22. static void
  23. p_compile(Filter *f)
  24. {
  25. if(f->op == '='){
  26. compile_cmp(aoerr.name, f, p_fields);
  27. return;
  28. }
  29. sysfatal("unknown aoerr field: %s", f->s);
  30. }
  31. static int
  32. p_filter(Filter *f, Msg *m)
  33. {
  34. uchar buf[6];
  35. int i;
  36. Hdr *h;
  37. if(m->pe - m->ps < Hsize)
  38. return 0;
  39. h = (Hdr*)m->ps;
  40. m->ps += Hsize;
  41. switch(f->subop){
  42. case Ocmd:
  43. return h->cmd == f->ulv;
  44. case Onea:
  45. return h->nea == f->ulv;
  46. case Oea:
  47. if(m->pe - m->ps < 6*h->nea)
  48. return 0;
  49. for(i = 0; i < 6; i++)
  50. buf[i] = f->ulv >> ((5 - i)*8);
  51. for(i = 0; i < h->nea; i++)
  52. if(memcmp(m->ps + 6*i, buf, 6) == 0)
  53. return 1;
  54. return 0;
  55. }
  56. return 0;
  57. }
  58. static char *ctab[] = {
  59. "read",
  60. "write",
  61. "force",
  62. };
  63. static int
  64. p_seprint(Msg *m)
  65. {
  66. char *s;
  67. int i;
  68. Hdr *h;
  69. if(m->pe - m->ps < Hsize)
  70. return 0;
  71. h = (Hdr*)m->ps;
  72. m->ps += Hsize;
  73. /* no next protocol */
  74. m->pr = nil;
  75. s = "unk";
  76. if(h->cmd < nelem(ctab))
  77. s = ctab[h->cmd];
  78. m->p = seprint(m->p, m->e, "cmd=%d %s nea=%d", h->cmd, s, h->nea);
  79. for(i = 0;; i++){
  80. if(h->nea < i)
  81. break;
  82. if(i == 3){
  83. m->p = seprint(m->p, m->e, " ...");
  84. break;
  85. }
  86. if(m->pe - m->ps < 6*i){
  87. m->p = seprint(m->p, m->e, " *short*");
  88. break;
  89. }
  90. m->p = seprint(m->p, m->e, " %E", m->pe + 6*i);
  91. }
  92. m->p = seprint(m->p, m->e, "\n");
  93. return 0;
  94. }
  95. Proto aoerr = {
  96. "aoerr",
  97. p_compile,
  98. p_filter,
  99. p_seprint,
  100. nil,
  101. nil,
  102. p_fields,
  103. defaultframer,
  104. };