main-loop.c 1.76 KB
Newer Older
1 2 3 4 5 6 7 8

/*
 * Alessandro Rubini for CERN, 2011 -- GNU LGPL v2.1 or later
 */

/*
 * This is the main loop for "freestanding" stuff under Linux.
 */
9
#include <pptp/pptp.h>
10 11 12
#include "bare-linux.h"

/* Define other hackish stuff */
13 14 15
struct bare_fd_set {
	unsigned long bits[1024/32];
};
16

17 18 19 20 21 22 23
#define FD_ZERO(p)	memset(p, 0, sizeof(p))
#define FD_SET(bit, p)	((p)->bits[0] |= (1 << (bit)))

struct bare_timeval {
	unsigned long tv_sec;
	unsigned long tv_usec;
};
24 25 26 27 28 29 30 31 32 33 34 35 36 37

#define NULL 0

void bare_main_loop(struct pp_instance *ppi)
{
	int delay_ms;

	/*
	 * The main loop here is based on select. While we are not
	 * doing anything else but the protocol, this allows extra stuff
	 * to fit.
	 */
	delay_ms = pp_state_machine(ppi, NULL, 0);
	while (1) {
38
		struct bare_fd_set set;
39
		int i, maxfd;
40 41 42 43 44 45 46 47 48
		struct bare_timeval tv;
		unsigned char packet[1500];

		/* Wait for a packet or for the timeout */
		tv.tv_sec = delay_ms / 1000;
		tv.tv_usec = (delay_ms % 1000) * 1000;

	again:
		FD_ZERO(&set);
49 50 51 52 53
		FD_SET(NP(ppi)->ch[PP_NP_GEN].fd, &set);
		FD_SET(NP(ppi)->ch[PP_NP_EVT].fd, &set);
		maxfd = NP(ppi)->ch[PP_NP_GEN].fd;
		if (NP(ppi)->ch[PP_NP_EVT].fd > maxfd)
			maxfd = NP(ppi)->ch[PP_NP_EVT].fd;
54 55

		i = sys_select(maxfd + 1, &set, NULL, NULL, &tv);
56 57 58 59 60 61 62 63 64 65 66 67
		if (i < 0 && bare_errno != 4 /* EINTR */)
			sys_exit(__LINE__);
		if (i < 0)
			continue;

		if (i == 0) {
			delay_ms = pp_state_machine(ppi, NULL, 0);
			continue;
		}

		/*
		 * We got a packet. If it's not ours, continue consuming
68 69 70
		 * the pending timeout.
		 *
		 * FIXME: we don't know which socket to receive from
71 72
		 */
		i = bare_recv_packet(ppi, packet, sizeof(packet));
73
		/* FIXME: PP_PROTO_NR is a legacy number */
74
		if (((struct bare_ethhdr *)packet)->h_proto
75 76 77 78 79 80
		     != htons(PP_PROTO_NR))
			goto again;

		delay_ms = pp_state_machine(ppi, packet, i);
	}
}