pptpgre.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. /*
  2. * pptpgre.c
  3. *
  4. * originally by C. S. Ananian
  5. * Modified for PoPToP
  6. *
  7. * $Id: pptpgre.c,v 1.9 2007/04/16 00:21:02 quozl Exp $
  8. */
  9. #ifdef HAVE_CONFIG_H
  10. #include "config.h"
  11. #endif
  12. #ifdef __linux__
  13. #define _GNU_SOURCE 1 /* broken arpa/inet.h */
  14. #endif
  15. #include "our_syslog.h"
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <sys/types.h>
  19. #include <sys/socket.h>
  20. #include <netinet/in.h>
  21. #include <arpa/inet.h>
  22. #include <sys/stat.h>
  23. #include <time.h>
  24. #include <sys/time.h>
  25. #include <unistd.h>
  26. #include <string.h>
  27. #include <errno.h>
  28. #include <fcntl.h>
  29. #ifdef HAVE_SYS_UIO_H
  30. #include <sys/uio.h>
  31. #endif
  32. #include "ppphdlc.h"
  33. #include "pptpgre.h"
  34. #include "pptpdefs.h"
  35. #include "pptpctrl.h"
  36. #include "defaults.h"
  37. #include "pqueue.h"
  38. #ifndef HAVE_STRERROR
  39. #include "compat.h"
  40. #endif
  41. #define PACKET_MAX 8196
  42. typedef int (*callback_t)(int cl, void *pack, unsigned int len);
  43. /* test for a 32 bit counter overflow */
  44. #define WRAPPED( curseq, lastseq) \
  45. ((((curseq) & 0xffffff00) == 0) && \
  46. (((lastseq) & 0xffffff00 ) == 0xffffff00))
  47. static struct gre_state gre;
  48. gre_stats_t stats;
  49. static uint64_t time_now_usecs()
  50. {
  51. struct timeval tv;
  52. gettimeofday(&tv, NULL);
  53. return (tv.tv_sec * 1000000) + tv.tv_usec;
  54. }
  55. int pptp_gre_init(u_int32_t call_id_pair, int pty_fd, struct in_addr *inetaddrs)
  56. {
  57. struct sockaddr_in addr;
  58. int gre_fd;
  59. /* Open IP protocol socket */
  60. gre_fd = socket(AF_INET, SOCK_RAW, PPTP_PROTO);
  61. if (gre_fd < 0) {
  62. syslog(LOG_ERR, "GRE: socket() failed");
  63. return -1;
  64. }
  65. memset(&addr, 0, sizeof(addr));
  66. addr.sin_family = AF_INET;
  67. addr.sin_addr = inetaddrs[0];
  68. addr.sin_port = 0;
  69. if (bind(gre_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  70. syslog(LOG_ERR, "GRE: bind() failed: %s", strerror(errno));
  71. syslog(LOG_ERR, "GRE: continuing, but may not work if multi-homed");
  72. }
  73. addr.sin_family = AF_INET;
  74. addr.sin_addr = inetaddrs[1];
  75. addr.sin_port = 0;
  76. if (connect(gre_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  77. syslog(LOG_ERR, "GRE: connect() failed: %s", strerror(errno));
  78. return -1;
  79. }
  80. gre.seq_sent = 0;
  81. gre.ack_sent = gre.ack_recv = gre.seq_recv = 0xFFFFFFFF;
  82. /* seq_recv is -1, therefore next packet expected is seq 0,
  83. to comply with RFC 2637: 'The sequence number for each
  84. user session is set to zero at session startup.' */
  85. gre.call_id_pair = call_id_pair; /* network byte order */
  86. return gre_fd;
  87. }
  88. /* ONE blocking read per call; dispatches all packets possible */
  89. /* returns 0 on success, or <0 on read failure */
  90. int decaps_hdlc(int fd, int (*cb) (int cl, void *pack, unsigned len), int cl)
  91. {
  92. static unsigned char buffer[PACKET_MAX], copy[PACKET_MAX];
  93. static unsigned start = 0, end = 0;
  94. static unsigned len = 0, escape = 0;
  95. static u_int16_t fcs = PPPINITFCS16;
  96. static unsigned char err = 0;
  97. unsigned char c;
  98. int status;
  99. /* we do one read only, since it may block. and only if the
  100. * buffer is empty (start == end)
  101. */
  102. if (fd == -1) {
  103. if(cb == NULL) {
  104. /* peek mode */
  105. return err ? -1 : 0;
  106. } else if (!err) {
  107. /* re-xmit and nothing queued */
  108. syslog(LOG_ERR, "GRE: Re-xmit called with nothing queued");
  109. return -1;
  110. }
  111. }
  112. if (!err) {
  113. /* All known data is processed. This true unless the last
  114. * network write failed.
  115. */
  116. if ((status = read(fd, buffer, sizeof(buffer))) <= 0) {
  117. syslog(LOG_ERR, "GRE: read(fd=%d,buffer=%lx,len=%d) from PTY failed: status = %d error = %s%s",
  118. fd, (unsigned long) buffer, sizeof(buffer),
  119. status, status ? strerror(errno) : "No error",
  120. errno != EIO ? "" : ", usually caused by unexpected termination of pppd, check option syntax and pppd logs");
  121. /* FAQ: mistakes in pppd option spelling in
  122. * /etc/ppp/options.pptpd often cause EIO,
  123. * with pppd not reporting the problem to any
  124. * logs. Termination of pppd by signal can
  125. * *also* cause this situation. -- James Cameron
  126. */
  127. return -1;
  128. }
  129. end = status;
  130. start = 0;
  131. } else {
  132. /* We're here because of a network write failure. Try again.
  133. * Then do what we would do normally and enter the loop as if
  134. * just continuing the while(1). Not sure that this ever
  135. * really happens, but since we error-check status then we
  136. * should have the code to handle an error :-)
  137. */
  138. err = 0;
  139. if ((status = cb(cl, copy, len)) < 0) {
  140. syslog(LOG_ERR, "GRE: re-xmit failed from decaps_hdlc: %s", strerror(errno));
  141. err = 1;
  142. return status; /* return error */
  143. }
  144. /* Great! Let's do more! */
  145. fcs = PPPINITFCS16;
  146. len = 0;
  147. escape = 0;
  148. }
  149. while (1) {
  150. /* Infinite loop, we return when we're out of data */
  151. /* Check if out of data */
  152. if (start == end)
  153. return 0;
  154. /* Add to the packet up till the next HDLC_FLAG (start/end of
  155. * packet marker). Copy to 'copy', un-escape and checksum as we go.
  156. */
  157. while (buffer[start] != HDLC_FLAG) {
  158. /* Dispose of 'too long' packets */
  159. if (len >= PACKET_MAX) {
  160. syslog(LOG_ERR, "GRE: Received too long packet from pppd.");
  161. while (buffer[start] != HDLC_FLAG && start < end)
  162. start++;
  163. if (start < end) {
  164. goto newpacket;
  165. } else
  166. return 0;
  167. }
  168. /* Read a character, un-escaping if needed */
  169. if (buffer[start] == HDLC_ESCAPE && !escape)
  170. escape = 1;
  171. else {
  172. if (escape) {
  173. copy[len] = c = buffer[start] ^ 0x20;
  174. escape = 0;
  175. } else
  176. copy[len] = c = buffer[start];
  177. fcs = (fcs >> 8) ^ fcstab[(fcs ^ c) & 0xff];
  178. len++;
  179. }
  180. start++;
  181. /* Check if out of data */
  182. if (start == end)
  183. return 0;
  184. }
  185. /* Found flag. Skip past it */
  186. start++;
  187. /* Check for over-short packets and silently discard, as per RFC1662 */
  188. if ((len < 4) || (escape == 1)) {
  189. /* len == 0 is possible, we generate it :-) [using HDLC_ESCAPE at
  190. * start and end of packet]. Others are worth recording.
  191. */
  192. if (len && len < 4)
  193. syslog(LOG_ERR, "GRE: Received too short packet from pppd.");
  194. if (escape)
  195. syslog(LOG_ERR, "GRE: Received bad packet from pppd.");
  196. goto newpacket;
  197. }
  198. /* Check, then remove the 16-bit FCS checksum field */
  199. if (fcs != PPPGOODFCS16) {
  200. syslog(LOG_ERR, "GRE: Bad checksum from pppd.");
  201. goto newpacket;
  202. }
  203. len -= sizeof(u_int16_t);
  204. /* So now we have a packet of length 'len' in 'copy' */
  205. if ((status = cb(cl, copy, len)) < 0) {
  206. syslog(LOG_ERR, "GRE: xmit failed from decaps_hdlc: %s", strerror(errno));
  207. err = 1;
  208. return status; /* return error */
  209. }
  210. newpacket:
  211. /* Great! Let's do more! */
  212. fcs = PPPINITFCS16;
  213. len = 0;
  214. escape = 0;
  215. }
  216. }
  217. #define seq_greater(A,B) ((A)>(B) || \
  218. (((u_int32_t)(A)<0xff) && ((~((u_int32_t)(B)))<0xff)))
  219. /* Macro used in encaps_hdlc(). add "val" to "dest" at position "pos",
  220. * incrementing "pos" to point after the added value. set "tmp" to "val"
  221. * as a side-effect.
  222. */
  223. #define ADD_CHAR(dest, pos, val, tmp) \
  224. tmp = (val); \
  225. if ((tmp<0x20) || (tmp==HDLC_FLAG) || (tmp==HDLC_ESCAPE)) { \
  226. dest[pos++]=HDLC_ESCAPE; \
  227. dest[pos++]=tmp^0x20; \
  228. } else \
  229. dest[pos++]=tmp
  230. /* Make stripped packet into HDLC packet */
  231. int encaps_hdlc(int fd, void *pack, unsigned len)
  232. {
  233. unsigned char *source = (unsigned char *) pack;
  234. /* largest expansion possible - double all + double fcs + 2 flags */
  235. static unsigned char dest[2 * PACKET_MAX + 6];
  236. unsigned pos = 1, i;
  237. u_int16_t fcs;
  238. unsigned char c;
  239. fcs = PPPINITFCS16;
  240. /* make sure overflow is impossible so we don't have to bounds check
  241. * in loop. drop large packets.
  242. */
  243. if (len > PACKET_MAX) {
  244. syslog(LOG_ERR, "GRE: Asked to encapsulate too large packet (len = %d)", len);
  245. return -1;
  246. }
  247. /* start character */
  248. dest[0] = HDLC_FLAG;
  249. /* escape the payload */
  250. for (i = 0; i < len; i++) {
  251. ADD_CHAR(dest, pos, source[i], c);
  252. fcs = (fcs >> 8) ^ fcstab[(fcs ^ c) & 0xff];
  253. }
  254. fcs ^= 0xFFFF;
  255. ADD_CHAR(dest, pos, fcs & 0xFF, c);
  256. ADD_CHAR(dest, pos, fcs >> 8, c);
  257. /* tack on the end-flag */
  258. dest[pos++] = HDLC_FLAG;
  259. /* now write this packet */
  260. return write(fd, dest, pos);
  261. }
  262. #undef ADD_CHAR
  263. static int dequeue_gre (callback_t callback, int cl)
  264. {
  265. pqueue_t *head;
  266. int status;
  267. /* process packets in the queue that either are expected or
  268. have timed out. */
  269. head = pqueue_head();
  270. while ( head != NULL &&
  271. ( (head->seq == gre.seq_recv + 1) || /* wrap-around safe */
  272. (pqueue_expiry_time(head) <= 0)
  273. )
  274. ) {
  275. /* if it is timed out... */
  276. if (head->seq != gre.seq_recv + 1 ) { /* wrap-around safe */
  277. stats.rx_lost += head->seq - gre.seq_recv - 1;
  278. if (pptpctrl_debug)
  279. syslog(LOG_DEBUG,
  280. "GRE: timeout waiting for %d packets",
  281. head->seq - gre.seq_recv - 1);
  282. }
  283. if (pptpctrl_debug)
  284. syslog(LOG_DEBUG, "GRE: accepting #%d from queue",
  285. head->seq);
  286. gre.seq_recv = head->seq;
  287. status = callback(cl, head->packet, head->packlen);
  288. pqueue_del(head);
  289. if (status < 0) return status;
  290. head = pqueue_head();
  291. }
  292. return 0;
  293. }
  294. int decaps_gre(int fd, int (*cb) (int cl, void *pack, unsigned len), int cl)
  295. {
  296. static unsigned char buffer[PACKET_MAX + 64 /*ip header */ ];
  297. struct pptp_gre_header *header;
  298. int status, ip_len = 0;
  299. dequeue_gre(cb, cl);
  300. if ((status = read(fd, buffer, sizeof(buffer))) <= 0) {
  301. syslog(LOG_ERR, "GRE: read(fd=%d,buffer=%lx,len=%d) from network failed: status = %d error = %s",
  302. fd, (unsigned long) buffer, sizeof(buffer), status, status ? strerror(errno) : "No error");
  303. stats.rx_errors++;
  304. return -1;
  305. }
  306. /* strip off IP header, if present */
  307. if ((buffer[0] & 0xF0) == 0x40)
  308. ip_len = (buffer[0] & 0xF) * 4;
  309. header = (struct pptp_gre_header *) (buffer + ip_len);
  310. /* verify packet (else discard) */
  311. if (((ntoh8(header->ver) & 0x7F) != PPTP_GRE_VER) || /* version should be 1 */
  312. (ntoh16(header->protocol) != PPTP_GRE_PROTO) || /* GRE protocol for PPTP */
  313. PPTP_GRE_IS_C(ntoh8(header->flags)) || /* flag C should be clear */
  314. PPTP_GRE_IS_R(ntoh8(header->flags)) || /* flag R should be clear */
  315. (!PPTP_GRE_IS_K(ntoh8(header->flags))) || /* flag K should be set */
  316. ((ntoh8(header->flags) & 0xF) != 0)) { /* routing and recursion ctrl = 0 */
  317. /* if invalid, discard this packet */
  318. syslog(LOG_ERR, "GRE: Discarding packet by header check");
  319. stats.rx_invalid++;
  320. return 0;
  321. }
  322. if (header->call_id != GET_VALUE(PAC, gre.call_id_pair)) {
  323. /*
  324. * Discard silently to allow more than one GRE tunnel from
  325. * the same IP address in case clients are behind the
  326. * firewall.
  327. *
  328. * syslog(LOG_ERR, "GRE: Discarding for incorrect call");
  329. */
  330. return 0;
  331. }
  332. if (PPTP_GRE_IS_A(ntoh8(header->ver))) { /* acknowledgement present */
  333. u_int32_t ack = (PPTP_GRE_IS_S(ntoh8(header->flags))) ?
  334. ntoh32(header->ack) : ntoh32(header->seq);
  335. /* ack in different place if S=0 */
  336. if (seq_greater(ack, gre.ack_recv))
  337. gre.ack_recv = ack;
  338. /* also handle sequence number wrap-around */
  339. if (WRAPPED(ack,gre.ack_recv)) gre.ack_recv = ack;
  340. if (gre.ack_recv == stats.pt.seq) {
  341. int rtt = time_now_usecs() - stats.pt.time;
  342. stats.rtt = (stats.rtt + rtt) / 2;
  343. }
  344. }
  345. if (PPTP_GRE_IS_S(ntoh8(header->flags))) { /* payload present */
  346. unsigned headersize = sizeof(*header);
  347. unsigned payload_len = ntoh16(header->payload_len);
  348. u_int32_t seq = ntoh32(header->seq);
  349. if (!PPTP_GRE_IS_A(ntoh8(header->ver)))
  350. headersize -= sizeof(header->ack);
  351. /* check for incomplete packet (length smaller than expected) */
  352. if (status - headersize < payload_len) {
  353. stats.rx_truncated++;
  354. return 0;
  355. }
  356. /* check for out-of-order sequence number
  357. * N.B.: some client implementations violate RFC 2637
  358. * and start their sequence numbers at 1 instead of 0,
  359. * so we have to introduce a kludge to deal with it.
  360. * on wrap we may allow an out of order packet to pass
  361. */
  362. if (seq == gre.seq_recv + 1 || seq == 1) {
  363. if (pptpctrl_debug)
  364. syslog(LOG_DEBUG, "GRE: accepting packet #%d",
  365. seq);
  366. stats.rx_accepted++;
  367. gre.seq_recv = seq;
  368. return cb(cl, buffer + ip_len + headersize, payload_len);
  369. } else if (!seq_greater(seq, gre.seq_recv)) {
  370. if (pptpctrl_debug)
  371. syslog(LOG_DEBUG,
  372. "GRE: discarding duplicate or old packet #%d (expecting #%d)",
  373. seq, gre.seq_recv + 1);
  374. return 0; /* discard duplicate packets */
  375. } else {
  376. stats.rx_buffered++;
  377. if (pptpctrl_debug)
  378. syslog(LOG_DEBUG,
  379. "GRE: buffering packet #%d (expecting #%d, lost or reordered)",
  380. seq, gre.seq_recv + 1);
  381. pqueue_add(seq, buffer + ip_len + headersize, payload_len);
  382. return 0; /* discard out-of-order packets */
  383. }
  384. }
  385. return 0; /* ack, but no payload */
  386. }
  387. int encaps_gre(int fd, void *pack, unsigned len)
  388. {
  389. static union {
  390. struct pptp_gre_header header;
  391. unsigned char buffer[PACKET_MAX + sizeof(struct pptp_gre_header)];
  392. } u;
  393. unsigned header_len;
  394. ssize_t status;
  395. #ifdef HAVE_WRITEV
  396. struct iovec iovec[2];
  397. #endif
  398. if(fd == -1)
  399. /* peek mode */
  400. return (gre.ack_sent == gre.seq_recv) ? 0 : -1;
  401. /* package this up in a GRE shell. */
  402. u.header.flags = hton8(PPTP_GRE_FLAG_K);
  403. u.header.ver = hton8(PPTP_GRE_VER);
  404. u.header.protocol = hton16(PPTP_GRE_PROTO);
  405. u.header.payload_len = hton16(len);
  406. u.header.call_id = GET_VALUE(PNS, gre.call_id_pair);
  407. /* special case ACK with no payload */
  408. if (pack == NULL) {
  409. if (gre.ack_sent != gre.seq_recv) {
  410. u.header.ver |= hton8(PPTP_GRE_FLAG_A);
  411. u.header.payload_len = hton16(0);
  412. u.header.seq = hton32(gre.seq_recv); /* ack is in odd place because S=0 */
  413. gre.ack_sent = gre.seq_recv;
  414. /* don't sent ACK field, ACK is in SYN field */
  415. return write(fd, u.buffer, sizeof(u.header) - sizeof(u.header.ack));
  416. } else
  417. return 0; /* we don't need to send ACK */
  418. }
  419. /* send packet with payload */
  420. u.header.flags |= hton8(PPTP_GRE_FLAG_S);
  421. u.header.seq = hton32(gre.seq_sent);
  422. gre.seq_sent++;
  423. if (gre.ack_sent != gre.seq_recv) { /* send ack with this message */
  424. u.header.ver |= hton8(PPTP_GRE_FLAG_A);
  425. u.header.ack = hton32(gre.seq_recv);
  426. gre.ack_sent = gre.seq_recv;
  427. header_len = sizeof(u.header);
  428. } else { /* don't send ack */
  429. header_len = sizeof(u.header) - sizeof(u.header.ack);
  430. }
  431. if (len > PACKET_MAX) {
  432. syslog(LOG_ERR, "GRE: packet is too large %d", len);
  433. stats.tx_oversize++;
  434. return 0; /* drop this, it's too big */
  435. }
  436. #ifdef HAVE_WRITEV
  437. /* write header and buffer without copying. */
  438. iovec[0].iov_base = u.buffer;
  439. iovec[0].iov_len = header_len;
  440. iovec[1].iov_base = pack;
  441. iovec[1].iov_len = len;
  442. status = writev(fd, iovec, 2);
  443. #else
  444. /* copy payload into buffer */
  445. memcpy(u.buffer + header_len, pack, len);
  446. /* record and increment sequence numbers */
  447. /* write this baby out to the net */
  448. status = write(fd, u.buffer, header_len + len);
  449. #endif
  450. if ((status >= 0) || (errno != ENOBUFS)) {
  451. return status;
  452. }
  453. // if ENOBUFS, do not close the connection
  454. gre.seq_sent--;
  455. return 0;
  456. }