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

Collapse All | Expand All

(-)a/src/dhcp.c (-18 / +35 lines)
Lines 164-171 dhcp_printoptions(const struct dhcpcd_ctx *ctx, Link Here
164
	}
164
	}
165
}
165
}
166
166
167
#define get_option_raw(ctx, bootp, bootp_len, opt)	\
168
	get_option((ctx), (bootp), (bootp_len), NULL)
169
static const uint8_t *
167
static const uint8_t *
170
get_option(struct dhcpcd_ctx *ctx,
168
get_option(struct dhcpcd_ctx *ctx,
171
    const struct bootp *bootp, size_t bootp_len,
169
    const struct bootp *bootp, size_t bootp_len,
Lines 3275-3300 is_packet_udp_bootp(void *packet, size_t plen) Link Here
3275
{
3273
{
3276
	struct ip *ip = packet;
3274
	struct ip *ip = packet;
3277
	size_t ip_hlen;
3275
	size_t ip_hlen;
3278
	struct udphdr *udp;
3276
	struct udphdr udp;
3279
3277
3280
	if (sizeof(*ip) > plen)
3278
	if (plen < sizeof(*ip))
3281
		return false;
3279
		return false;
3282
3280
3283
	if (ip->ip_v != IPVERSION || ip->ip_p != IPPROTO_UDP)
3281
	if (ip->ip_v != IPVERSION || ip->ip_p != IPPROTO_UDP)
3284
		return false;
3282
		return false;
3285
3283
3286
	/* Sanity. */
3284
	/* Sanity. */
3287
	if (ntohs(ip->ip_len) != plen)
3285
	if (ntohs(ip->ip_len) > plen)
3288
		return false;
3286
		return false;
3289
3287
3290
	ip_hlen = (size_t)ip->ip_hl * 4;
3288
	ip_hlen = (size_t)ip->ip_hl * 4;
3289
	if (ip_hlen < sizeof(*ip))
3290
		return false;
3291
3291
	/* Check we have a UDP header and BOOTP. */
3292
	/* Check we have a UDP header and BOOTP. */
3292
	if (ip_hlen + sizeof(*udp) + offsetof(struct bootp, vend) > plen)
3293
	if (ip_hlen + sizeof(udp) + offsetof(struct bootp, vend) > plen)
3294
		return false;
3295
3296
	/* Sanity. */
3297
	memcpy(&udp, (char *)ip + ip_hlen, sizeof(udp));
3298
	if (ntohs(udp.uh_ulen) < sizeof(udp))
3299
		return false;
3300
	if (ip_hlen + ntohs(udp.uh_ulen) > plen)
3293
		return false;
3301
		return false;
3294
3302
3295
	/* Check it's to and from the right ports. */
3303
	/* Check it's to and from the right ports. */
3296
	udp = (struct udphdr *)(void *)((char *)ip + ip_hlen);
3304
	if (udp.uh_dport != htons(BOOTPC) || udp.uh_sport != htons(BOOTPS))
3297
	if (udp->uh_dport != htons(BOOTPC) || udp->uh_sport != htons(BOOTPS))
3298
		return false;
3305
		return false;
3299
3306
3300
	return true;
3307
	return true;
Lines 3313-3319 checksums_valid(void *packet, Link Here
3313
	};
3320
	};
3314
	size_t ip_hlen;
3321
	size_t ip_hlen;
3315
	uint16_t udp_len, uh_sum;
3322
	uint16_t udp_len, uh_sum;
3316
	struct udphdr *udp;
3323
	struct udphdr udp;
3324
	char *udpp, *uh_sump;
3317
	uint32_t csum;
3325
	uint32_t csum;
3318
3326
3319
	if (from != NULL)
3327
	if (from != NULL)
Lines 3324-3344 checksums_valid(void *packet, Link Here
3324
		return false;
3332
		return false;
3325
3333
3326
	if (flags & BPF_PARTIALCSUM)
3334
	if (flags & BPF_PARTIALCSUM)
3327
		return 0;
3335
		return true;
3328
3336
3329
	udp = (struct udphdr *)(void *)((char *)ip + ip_hlen);
3337
	udpp = (char *)ip + ip_hlen;
3330
	if (udp->uh_sum == 0)
3338
	memcpy(&udp, udpp, sizeof(udp));
3331
		return 0;
3339
	if (udp.uh_sum == 0)
3340
		return true;
3332
3341
3333
	/* UDP checksum is based on a pseudo IP header alongside
3342
	/* UDP checksum is based on a pseudo IP header alongside
3334
	 * the UDP header and payload. */
3343
	 * the UDP header and payload. */
3335
	udp_len = ntohs(udp->uh_ulen);
3344
	udp_len = ntohs(udp.uh_ulen);
3336
	uh_sum = udp->uh_sum;
3345
	uh_sum = udp.uh_sum;
3337
	udp->uh_sum = 0;
3346
3338
	pseudo_ip.ip_len = udp->uh_ulen;
3347
	/* Need to zero the UDP sum in the packet for the checksum to work. */
3348
	uh_sump = udpp + offsetof(struct udphdr, uh_sum);
3349
	memset(uh_sump, 0, sizeof(udp.uh_sum));
3350
3351
	pseudo_ip.ip_len = udp.uh_ulen;
3339
	csum = 0;
3352
	csum = 0;
3340
	in_cksum(&pseudo_ip, sizeof(pseudo_ip), &csum);
3353
	in_cksum(&pseudo_ip, sizeof(pseudo_ip), &csum);
3341
	csum = in_cksum(udp, udp_len, &csum);
3354
	csum = in_cksum(udpp, udp_len, &csum);
3355
3356
	/* Put the checksum back. */
3357
	memcpy(uh_sump, &uh_sum, sizeof(udp.uh_sum));
3358
3342
	return csum == uh_sum;
3359
	return csum == uh_sum;
3343
}
3360
}
3344
3361

Return to bug 697672