source: rtems-libbsd/dhcpcd/lpf.c @ b43517b

55-freebsd-126-freebsd-12
Last change on this file since b43517b was f2ed769, checked in by Sebastian Huber <sebastian.huber@…>, on 01/30/14 at 12:29:46

DHCPCD(8): Import

Import DHCPCD(8) from:

http://roy.marples.name/projects/dhcpcd/

The upstream sources can be obtained via:

fossil clone http://roy.marples.name/projects/dhcpcd

The imported version is 2014-01-29 19:46:44 [6b209507bb].

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