hid_mouse.bpf.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include "vmlinux.h"
  3. #include <bpf/bpf_helpers.h>
  4. #include <bpf/bpf_tracing.h>
  5. #include "hid_bpf_helpers.h"
  6. static int hid_y_event(struct hid_bpf_ctx *hctx)
  7. {
  8. s16 y;
  9. __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
  10. if (!data)
  11. return 0; /* EPERM check */
  12. bpf_printk("event: size: %d", hctx->size);
  13. bpf_printk("incoming event: %02x %02x %02x",
  14. data[0],
  15. data[1],
  16. data[2]);
  17. bpf_printk(" %02x %02x %02x",
  18. data[3],
  19. data[4],
  20. data[5]);
  21. bpf_printk(" %02x %02x %02x",
  22. data[6],
  23. data[7],
  24. data[8]);
  25. y = data[3] | (data[4] << 8);
  26. y = -y;
  27. data[3] = y & 0xFF;
  28. data[4] = (y >> 8) & 0xFF;
  29. bpf_printk("modified event: %02x %02x %02x",
  30. data[0],
  31. data[1],
  32. data[2]);
  33. bpf_printk(" %02x %02x %02x",
  34. data[3],
  35. data[4],
  36. data[5]);
  37. bpf_printk(" %02x %02x %02x",
  38. data[6],
  39. data[7],
  40. data[8]);
  41. return 0;
  42. }
  43. static int hid_x_event(struct hid_bpf_ctx *hctx)
  44. {
  45. s16 x;
  46. __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
  47. if (!data)
  48. return 0; /* EPERM check */
  49. x = data[1] | (data[2] << 8);
  50. x = -x;
  51. data[1] = x & 0xFF;
  52. data[2] = (x >> 8) & 0xFF;
  53. return 0;
  54. }
  55. SEC("struct_ops/hid_device_event")
  56. int BPF_PROG(hid_event, struct hid_bpf_ctx *hctx, enum hid_report_type type)
  57. {
  58. int ret = hid_y_event(hctx);
  59. if (ret)
  60. return ret;
  61. return hid_x_event(hctx);
  62. }
  63. SEC("struct_ops/hid_rdesc_fixup")
  64. int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx)
  65. {
  66. __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */);
  67. if (!data)
  68. return 0; /* EPERM check */
  69. bpf_printk("rdesc: %02x %02x %02x",
  70. data[0],
  71. data[1],
  72. data[2]);
  73. bpf_printk(" %02x %02x %02x",
  74. data[3],
  75. data[4],
  76. data[5]);
  77. bpf_printk(" %02x %02x %02x ...",
  78. data[6],
  79. data[7],
  80. data[8]);
  81. /*
  82. * The original report descriptor contains:
  83. *
  84. * 0x05, 0x01, // Usage Page (Generic Desktop) 30
  85. * 0x16, 0x01, 0x80, // Logical Minimum (-32767) 32
  86. * 0x26, 0xff, 0x7f, // Logical Maximum (32767) 35
  87. * 0x09, 0x30, // Usage (X) 38
  88. * 0x09, 0x31, // Usage (Y) 40
  89. *
  90. * So byte 39 contains Usage X and byte 41 Usage Y.
  91. *
  92. * We simply swap the axes here.
  93. */
  94. data[39] = 0x31;
  95. data[41] = 0x30;
  96. return 0;
  97. }
  98. SEC(".struct_ops.link")
  99. struct hid_bpf_ops mouse_invert = {
  100. .hid_rdesc_fixup = (void *)hid_rdesc_fixup,
  101. .hid_device_event = (void *)hid_event,
  102. };
  103. char _license[] SEC("license") = "GPL";