ppp.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #define _GNU_SOURCE
  14. #include <stdio.h>
  15. #include <errno.h>
  16. #include <unistd.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include "parser.h"
  20. #define PPP_U8(frm) (get_u8(frm))
  21. #define PPP_U16(frm) (btohs(htons(get_u16(frm))))
  22. #define PPP_U32(frm) (btohl(htonl(get_u32(frm))))
  23. static int ppp_traffic = 0;
  24. static unsigned char ppp_magic1[] = { 0x7e, 0xff, 0x03, 0xc0, 0x21 };
  25. static unsigned char ppp_magic2[] = { 0x7e, 0xff, 0x7d, 0x23, 0xc0, 0x21 };
  26. static unsigned char ppp_magic3[] = { 0x7e, 0x7d, 0xdf, 0x7d, 0x23, 0xc0, 0x21 };
  27. static inline int check_for_ppp_traffic(unsigned char *data, int size)
  28. {
  29. unsigned int i;
  30. for (i = 0; i < size - sizeof(ppp_magic1); i++)
  31. if (!memcmp(data + i, ppp_magic1, sizeof(ppp_magic1))) {
  32. ppp_traffic = 1;
  33. return i;
  34. }
  35. for (i = 0; i < size - sizeof(ppp_magic2); i++)
  36. if (!memcmp(data + i, ppp_magic2, sizeof(ppp_magic2))) {
  37. ppp_traffic = 1;
  38. return i;
  39. }
  40. for (i = 0; i < size - sizeof(ppp_magic3); i++)
  41. if (!memcmp(data + i, ppp_magic3, sizeof(ppp_magic3))) {
  42. ppp_traffic = 1;
  43. return i;
  44. }
  45. return -1;
  46. }
  47. static inline char *dir2str(uint8_t in)
  48. {
  49. return in ? "DCE" : "DTE";
  50. }
  51. static inline char *proto2str(uint16_t proto)
  52. {
  53. switch (proto) {
  54. case 0x0001:
  55. return "Padding Protocol";
  56. case 0x0021:
  57. return "IP";
  58. case 0x8021:
  59. return "IP Control Protocol";
  60. case 0x80fd:
  61. return "Compression Control Protocol";
  62. case 0xc021:
  63. return "Link Control Protocol";
  64. case 0xc023:
  65. return "Password Authentication Protocol";
  66. case 0xc025:
  67. return "Link Quality Report";
  68. case 0xc223:
  69. return "Challenge Handshake Authentication Protocol";
  70. default:
  71. return "Unknown Protocol";
  72. }
  73. }
  74. static void hdlc_dump(int level, struct frame *frm)
  75. {
  76. uint8_t addr = p_get_u8(frm);
  77. uint8_t ctrl = p_get_u8(frm);
  78. uint16_t fcs, proto;
  79. fcs = get_unaligned((uint16_t *) (frm->ptr + frm->len - 2));
  80. frm->len -= 2;
  81. p_indent(level, frm);
  82. if (addr != 0xff || ctrl != 0x03) {
  83. frm->ptr -= 2;
  84. frm->len += 2;
  85. printf("HDLC: %s: len %d fcs 0x%04x\n",
  86. dir2str(frm->in), frm->len, fcs);
  87. } else
  88. printf("HDLC: %s: addr 0x%02x ctrl 0x%02x len %d fcs 0x%04x\n",
  89. dir2str(frm->in), addr, ctrl, frm->len, fcs);
  90. if (*((uint8_t *) frm->ptr) & 0x80)
  91. proto = p_get_u16(frm);
  92. else
  93. proto = p_get_u8(frm);
  94. p_indent(level + 1, frm);
  95. printf("PPP: %s (0x%04x): len %d\n", proto2str(proto), proto, frm->len);
  96. raw_dump(level + 1, frm);
  97. }
  98. static inline void unslip_frame(int level, struct frame *frm, int len)
  99. {
  100. struct frame msg;
  101. unsigned char *data, *ptr;
  102. int i, p = 0;
  103. data = malloc(len * 2);
  104. if (!data)
  105. return;
  106. ptr = frm->ptr;
  107. for (i = 0; i < len; i++) {
  108. if (ptr[i] == 0x7d) {
  109. data[p++] = ptr[i + 1] ^ 0x20;
  110. i++;
  111. } else
  112. data[p++] = ptr[i];
  113. }
  114. memset(&msg, 0, sizeof(msg));
  115. msg.data = data;
  116. msg.data_len = len * 2;
  117. msg.ptr = msg.data;
  118. msg.len = p;
  119. msg.in = frm->in;
  120. msg.ts = frm->ts;
  121. msg.handle = frm->handle;
  122. msg.cid = frm->cid;
  123. hdlc_dump(level, &msg);
  124. free(data);
  125. }
  126. void ppp_dump(int level, struct frame *frm)
  127. {
  128. void *ptr, *end;
  129. int err, len, pos = 0;
  130. if (frm->pppdump_fd > fileno(stderr)) {
  131. unsigned char id;
  132. uint16_t len = htons(frm->len);
  133. uint32_t ts = htonl(frm->ts.tv_sec & 0xffffffff);
  134. id = 0x07;
  135. err = write(frm->pppdump_fd, &id, 1);
  136. if (err < 0)
  137. return;
  138. err = write(frm->pppdump_fd, &ts, 4);
  139. if (err < 0)
  140. return;
  141. id = frm->in ? 0x02 : 0x01;
  142. err = write(frm->pppdump_fd, &id, 1);
  143. if (err < 0)
  144. return;
  145. err = write(frm->pppdump_fd, &len, 2);
  146. if (err < 0)
  147. return;
  148. err = write(frm->pppdump_fd, frm->ptr, frm->len);
  149. if (err < 0)
  150. return;
  151. }
  152. if (!ppp_traffic) {
  153. pos = check_for_ppp_traffic(frm->ptr, frm->len);
  154. if (pos < 0) {
  155. raw_dump(level, frm);
  156. return;
  157. }
  158. if (pos > 0) {
  159. raw_ndump(level, frm, pos);
  160. frm->ptr += pos;
  161. frm->len -= pos;
  162. }
  163. }
  164. frm = add_frame(frm);
  165. while (frm->len > 0) {
  166. ptr = memchr(frm->ptr, 0x7e, frm->len);
  167. if (!ptr)
  168. break;
  169. if (frm->ptr != ptr) {
  170. frm->len -= (ptr - frm->ptr);
  171. frm->ptr = ptr;
  172. }
  173. end = memchr(frm->ptr + 1, 0x7e, frm->len - 1);
  174. if (!end)
  175. break;
  176. len = end - ptr - 1;
  177. frm->ptr++;
  178. frm->len--;
  179. if (len > 0) {
  180. unslip_frame(level, frm, len);
  181. frm->ptr += len;
  182. frm->len -= len;
  183. }
  184. }
  185. }