1f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project/*
2f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * dhcpcd - DHCP client daemon
3a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt * Copyright (c) 2006-2011 Roy Marples <roy@marples.name>
4f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *
5f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * Redistribution and use in source and binary forms, with or without
6f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * modification, are permitted provided that the following conditions
7f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * are met:
8f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
9f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
10f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
11f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
12f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *    documentation and/or other materials provided with the distribution.
13f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *
14f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * SUCH DAMAGE.
25f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project */
26f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
27f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <sys/types.h>
28f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <sys/ioctl.h>
29f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <sys/socket.h>
30f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
31f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <net/if.h>
32f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <netinet/in_systm.h>
33f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <netinet/in.h>
34f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <arpa/inet.h>
35f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
36f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#ifdef __linux__
37f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project# include <asm/types.h> /* needed for 2.4 kernels for the below header */
38f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project# include <linux/filter.h>
39a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt# include <linux/if_packet.h>
40e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt# define bpf_insn		sock_filter
41f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project# define BPF_SKIPTYPE
42f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project# define BPF_ETHCOOK		-ETH_HLEN
43f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project# define BPF_WHOLEPACKET	0x0fffffff /* work around buggy LPF filters */
44f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#endif
45f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
46f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <errno.h>
47f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <fcntl.h>
48f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <stdio.h>
49f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <stdlib.h>
50f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <string.h>
51f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <time.h>
52f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include <unistd.h>
53f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
54f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include "config.h"
55f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include "common.h"
56f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include "dhcp.h"
57f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include "net.h"
58f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include "bpf-filter.h"
59f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
60f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project/* Broadcast address for IPoIB */
61f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatic const uint8_t ipv4_bcast_addr[] = {
62f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	0x00, 0xff, 0xff, 0xff,
63f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
64f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
65f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project};
66f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
67f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectint
68f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectopen_socket(struct interface *iface, int protocol)
69f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{
70f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	int s;
71f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	union sockunion {
72f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		struct sockaddr sa;
73f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		struct sockaddr_in sin;
74f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		struct sockaddr_ll sll;
75f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		struct sockaddr_storage ss;
76f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	} su;
77f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	struct sock_fprog pf;
78f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	int *fd;
79a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#ifdef PACKET_AUXDATA
80a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	int n;
81a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#endif
82f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
83f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	if ((s = socket(PF_PACKET, SOCK_DGRAM, htons(protocol))) == -1)
84f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		return -1;
85f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
86f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	memset(&su, 0, sizeof(su));
87f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	su.sll.sll_family = PF_PACKET;
88f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	su.sll.sll_protocol = htons(protocol);
89f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	if (!(su.sll.sll_ifindex = if_nametoindex(iface->name))) {
90f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		errno = ENOENT;
91f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		goto eexit;
92f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	}
93f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	/* Install the DHCP filter */
94f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	memset(&pf, 0, sizeof(pf));
95f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	if (protocol == ETHERTYPE_ARP) {
96f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		pf.filter = UNCONST(arp_bpf_filter);
97f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		pf.len = arp_bpf_filter_len;
98f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	} else {
99f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		pf.filter = UNCONST(dhcp_bpf_filter);
100f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		pf.len = dhcp_bpf_filter_len;
101f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	}
102f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &pf, sizeof(pf)) != 0)
103f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		goto eexit;
104a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#ifdef PACKET_AUXDATA
105a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	n = 1;
106a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	if (setsockopt(s, SOL_PACKET, PACKET_AUXDATA, &n, sizeof(n)) != 0) {
107a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt		if (errno != ENOPROTOOPT)
108a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt			goto eexit;
109a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	}
110a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#endif
111f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	if (set_cloexec(s) == -1)
112f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		goto eexit;
113f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	if (set_nonblock(s) == -1)
114f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		goto eexit;
115f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	if (bind(s, &su.sa, sizeof(su)) == -1)
116f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		goto eexit;
117f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	if (protocol == ETHERTYPE_ARP)
118f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		fd = &iface->arp_fd;
119f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	else
120f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		fd = &iface->raw_fd;
121f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	if (*fd != -1)
122f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		close(*fd);
123f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	*fd = s;
124f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	return s;
125f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
126f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projecteexit:
127f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	close(s);
128f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	return -1;
129f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project}
130f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
131f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectssize_t
132f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectsend_raw_packet(const struct interface *iface, int protocol,
133e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    const void *data, ssize_t len)
134f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{
135f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	union sockunion {
136f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		struct sockaddr sa;
137f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		struct sockaddr_ll sll;
138f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		struct sockaddr_storage ss;
139f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	} su;
140f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	int fd;
141f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
142f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	memset(&su, 0, sizeof(su));
143f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	su.sll.sll_family = AF_PACKET;
144f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	su.sll.sll_protocol = htons(protocol);
145f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	if (!(su.sll.sll_ifindex = if_nametoindex(iface->name))) {
146f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		errno = ENOENT;
147f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		return -1;
148f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	}
149f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	su.sll.sll_hatype = htons(iface->family);
150f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	su.sll.sll_halen = iface->hwlen;
151f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	if (iface->family == ARPHRD_INFINIBAND)
152f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		memcpy(&su.sll.sll_addr,
153e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt		    &ipv4_bcast_addr, sizeof(ipv4_bcast_addr));
154f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	else
155f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		memset(&su.sll.sll_addr, 0xff, iface->hwlen);
156f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	if (protocol == ETHERTYPE_ARP)
157f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		fd = iface->arp_fd;
158f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	else
159f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		fd = iface->raw_fd;
160f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
161f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	return sendto(fd, data, len, 0, &su.sa, sizeof(su));
162f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project}
163f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
164f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectssize_t
165a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidtget_raw_packet(struct interface *iface, int protocol,
166a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt    void *data, ssize_t len, int *partialcsum)
167f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{
168a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	struct iovec iov = {
169a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt		.iov_base = data,
170a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt		.iov_len = len,
171a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	};
172a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	struct msghdr msg = {
173a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt		.msg_iov = &iov,
174a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt		.msg_iovlen = 1,
175a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	};
176a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#ifdef PACKET_AUXDATA
177a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
178a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	struct cmsghdr *cmsg;
179a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	struct tpacket_auxdata *aux;
180a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#endif
181a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt
182f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	ssize_t bytes;
183f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	int fd = -1;
184f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
185a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#ifdef PACKET_AUXDATA
186a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	msg.msg_control = cmsgbuf;
187a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	msg.msg_controllen = sizeof(cmsgbuf);
188a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#endif
189a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt
190f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	if (protocol == ETHERTYPE_ARP)
191f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		fd = iface->arp_fd;
192f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	else
193f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		fd = iface->raw_fd;
194a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	bytes = recvmsg(fd, &msg, 0);
195f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	if (bytes == -1)
196f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project		return errno == EAGAIN ? 0 : -1;
197a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	if (partialcsum != NULL) {
198a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt		*partialcsum = 0;
199a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#ifdef PACKET_AUXDATA
200a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt		for (cmsg = CMSG_FIRSTHDR(&msg);
201a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt		     cmsg;
202a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt		     cmsg = CMSG_NXTHDR(&msg, cmsg))
203a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt		{
204a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt			if (cmsg->cmsg_level == SOL_PACKET &&
205a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt			    cmsg->cmsg_type == PACKET_AUXDATA) {
206a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt				aux = (void *)CMSG_DATA(cmsg);
207a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt				*partialcsum = aux->tp_status &
208a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt				    TP_STATUS_CSUMNOTREADY;
209a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt			}
210a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt		}
211a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt#endif
212a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt	}
213f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project	return bytes;
214f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project}
215