Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 340267 | Differences between
and this patch

Collapse All | Expand All

(-)ppp-2.4.5.org/pppd/plugins/rp-pppoe/discovery.c (-73 / +99 lines)
Lines 37-42 Link Here
37
#endif
37
#endif
38
38
39
#include <signal.h>
39
#include <signal.h>
40
#include <time.h>
40
41
41
/**********************************************************************
42
/**********************************************************************
42
*%FUNCTION: parseForHostUniq
43
*%FUNCTION: parseForHostUniq
Lines 196-201 Link Here
196
    }
197
    }
197
}
198
}
198
199
200
201
/**********************************************************************
202
*%FUNCTION: recvPacketForMe
203
*%ARGUMENTS:
204
* packet -- output parameter
205
* len -- output parameter length
206
* conn -- connection 
207
* timeout -- don't wait more than timeout
208
*%RETURNS:
209
* -1:	error
210
*  0:	timed out
211
*  1:	packet recived
212
*%DESCRIPTION:
213
* recive and filter junk packets
214
***********************************************************************/
215
216
static int
217
recvPacketForMe(PPPoEPacket *packet, int *len, PPPoEConnection *conn, int timeout)
218
{
219
220
    fd_set readable;
221
    int r;
222
    struct timeval tv;
223
    time_t start, now;
224
    int time_remain;
225
226
    start = time(&now);
227
    do {
228
	time(&now);
229
	time_remain = timeout - (int)difftime(now, start);
230
	if (time_remain > timeout) time_remain = timeout;
231
232
	if (time_remain <= 0) /* Timed out */
233
	    return 0;
234
    
235
        if (BPF_BUFFER_IS_EMPTY) {
236
            tv.tv_sec = time_remain;
237
            tv.tv_usec = 0;
238
239
            FD_ZERO(&readable);
240
            FD_SET(conn->discoverySocket, &readable);
241
242
	    r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv);
243
	    if (r < 0)
244
	    {
245
		if (errno == EINTR)
246
		{
247
		    continue;	/* interrupted, so retry */
248
		}else     	/* select error */
249
		{
250
		    error("pppoe: recvPacketForMe: select: %m");
251
		    return -1;
252
		}
253
	    }
254
255
            if (r == 0) return 0;        /* Timed out */
256
        }
257
258
        /* Get the packet */
259
        receivePacket(conn->discoverySocket, packet, len);
260
261
        /* Check length */
262
        if (ntohs(packet->length) + HDR_SIZE > *len) {
263
            error("Bogus PPPoE length field (%u)",
264
                   (unsigned int) ntohs(packet->length));
265
            continue;
266
        }
267
268
#ifdef USE_BPF
269
        /* If it's not a Discovery packet, loop again */
270
        if (etherType(&packet) != Eth_PPPOE_Discovery) continue;
271
#endif
272
273
        /* If it's not for us, loop again */
274
        }while ( ! packetIsForMe(conn, packet));
275
276
        return 1;
277
}
278
279
199
/***********************************************************************
280
/***********************************************************************
200
*%FUNCTION: sendPADI
281
*%FUNCTION: sendPADI
201
*%ARGUMENTS:
282
*%ARGUMENTS:
Lines 277-287 Link Here
277
void
358
void
278
waitForPADO(PPPoEConnection *conn, int timeout)
359
waitForPADO(PPPoEConnection *conn, int timeout)
279
{
360
{
280
    fd_set readable;
281
    int r;
361
    int r;
282
    struct timeval tv;
283
    PPPoEPacket packet;
362
    PPPoEPacket packet;
284
    int len;
363
    int len;
364
    time_t start, now;
365
    int time_remain;
285
366
286
    struct PacketCriteria pc;
367
    struct PacketCriteria pc;
287
    pc.conn          = conn;
368
    pc.conn          = conn;
Lines 291-332 Link Here
291
    pc.seenServiceName = 0;
372
    pc.seenServiceName = 0;
292
    conn->error = 0;
373
    conn->error = 0;
293
374
375
    start = time(&now);
294
    do {
376
    do {
295
	if (BPF_BUFFER_IS_EMPTY) {
377
	time(&now);
296
	    tv.tv_sec = timeout;
378
	time_remain = timeout - (int)difftime(now, start);
297
	    tv.tv_usec = 0;
379
	if (time_remain > timeout) time_remain = timeout;
298
299
	    FD_ZERO(&readable);
300
	    FD_SET(conn->discoverySocket, &readable);
301
302
	    while(1) {
303
		r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv);
304
		if (r >= 0 || errno != EINTR) break;
305
	    }
306
	    if (r < 0) {
307
		error("select (waitForPADO): %m");
308
		return;
309
	    }
310
	    if (r == 0) return;        /* Timed out */
311
	}
312
313
	/* Get the packet */
314
	receivePacket(conn->discoverySocket, &packet, &len);
315
316
	/* Check length */
317
	if (ntohs(packet.length) + HDR_SIZE > len) {
318
	    error("Bogus PPPoE length field (%u)",
319
		   (unsigned int) ntohs(packet.length));
320
	    continue;
321
	}
322
380
323
#ifdef USE_BPF
381
	if (time_remain <= 0) return; /* Timed out */
324
	/* If it's not a Discovery packet, loop again */
325
	if (etherType(&packet) != Eth_PPPOE_Discovery) continue;
326
#endif
327
382
328
	/* If it's not for us, loop again */
383
	r = recvPacketForMe(&packet, &len, conn, time_remain);
329
	if (!packetIsForMe(conn, &packet)) continue;
384
	if (r<=0) return;  /* Timed out or error */
330
385
331
	if (packet.code == CODE_PADO) {
386
	if (packet.code == CODE_PADO) {
332
	    if (NOT_UNICAST(packet.ethHdr.h_source)) {
387
	    if (NOT_UNICAST(packet.ethHdr.h_source)) {
Lines 447-498 Link Here
447
static void
502
static void
448
waitForPADS(PPPoEConnection *conn, int timeout)
503
waitForPADS(PPPoEConnection *conn, int timeout)
449
{
504
{
450
    fd_set readable;
451
    int r;
505
    int r;
452
    struct timeval tv;
453
    PPPoEPacket packet;
506
    PPPoEPacket packet;
454
    int len;
507
    int len;
508
    time_t start, now;
509
    int time_remain;
455
510
511
    start = time(&now);
456
    conn->error = 0;
512
    conn->error = 0;
457
    do {
513
    do {
458
	if (BPF_BUFFER_IS_EMPTY) {
514
	time(&now);
459
	    tv.tv_sec = timeout;
515
	time_remain = timeout - (int)difftime(now, start);
460
	    tv.tv_usec = 0;
516
	if (time_remain > timeout) time_remain = timeout;
461
462
	    FD_ZERO(&readable);
463
	    FD_SET(conn->discoverySocket, &readable);
464
465
	    while(1) {
466
		r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv);
467
		if (r >= 0 || errno != EINTR) break;
468
	    }
469
	    if (r < 0) {
470
		error("select (waitForPADS): %m");
471
		return;
472
	    }
473
	    if (r == 0) return;
474
	}
475
476
	/* Get the packet */
477
	receivePacket(conn->discoverySocket, &packet, &len);
478
479
	/* Check length */
480
	if (ntohs(packet.length) + HDR_SIZE > len) {
481
	    error("Bogus PPPoE length field (%u)",
482
		   (unsigned int) ntohs(packet.length));
483
	    continue;
484
	}
485
486
#ifdef USE_BPF
487
	/* If it's not a Discovery packet, loop again */
488
	if (etherType(&packet) != Eth_PPPOE_Discovery) continue;
489
#endif
490
517
491
	/* If it's not from the AC, it's not for me */
518
	if (time_remain <= 0) return; /* Timed out */
492
	if (memcmp(packet.ethHdr.h_source, conn->peerEth, ETH_ALEN)) continue;
493
519
494
	/* If it's not for us, loop again */
520
	r = recvPacketForMe(&packet, &len, conn, time_remain);
495
	if (!packetIsForMe(conn, &packet)) continue;
521
	if (r<=0) return;  /* Timed out or error */
496
522
497
	/* Is it PADS?  */
523
	/* Is it PADS?  */
498
	if (packet.code == CODE_PADS) {
524
	if (packet.code == CODE_PADS) {

Return to bug 340267