iPXE
af_packet.c File Reference

The AF_PACKET driver. More...

#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <ipxe/linux_api.h>
#include <ipxe/list.h>
#include <ipxe/linux.h>
#include <ipxe/malloc.h>
#include <ipxe/device.h>
#include <ipxe/netdevice.h>
#include <ipxe/iobuf.h>
#include <ipxe/ethernet.h>
#include <ipxe/settings.h>
#include <ipxe/socket.h>
#include <linux/socket.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <byteswap.h>

Go to the source code of this file.

Data Structures

struct  af_packet_nic

Macros

#define _SYS_SOCKET_H
#define __GLIBC__   2
#define LINUX_AF_PACKET   17
#define LINUX_SOCK_RAW   3
#define LINUX_SIOCGIFINDEX   0x8933
#define LINUX_SIOCGIFHWADDR   0x8927
#define RX_BUF_SIZE   1536

Functions

static int af_packet_nic_open (struct net_device *netdev)
 Open the linux interface.
static void af_packet_nic_close (struct net_device *netdev)
 Close the packet socket.
static int af_packet_nic_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit an ethernet packet.
static void af_packet_nic_poll (struct net_device *netdev)
 Poll for new packets.
static void af_packet_nic_irq (struct net_device *netdev, int enable)
 Set irq.
static int af_packet_update_properties (struct net_device *netdev)
static int af_packet_nic_probe (struct linux_device *device, struct linux_device_request *request)
 Handle a device request for the af_packet driver.
static void af_packet_nic_remove (struct linux_device *device)
 Remove the device.
 LINUX_ROM ("af_packet", "AF_PACKET binding NIC")

Variables

static struct net_device_operations af_packet_nic_operations
 AF_PACKET operations.
struct linux_driver af_packet_nic_driver __linux_driver
 AF_PACKET linux_driver.

Detailed Description

The AF_PACKET driver.

Bind to an existing linux network interface.

Definition in file af_packet.c.

Macro Definition Documentation

◆ _SYS_SOCKET_H

#define _SYS_SOCKET_H

Definition at line 34 of file af_packet.c.

◆ __GLIBC__

#define __GLIBC__   2

Definition at line 35 of file af_packet.c.

◆ LINUX_AF_PACKET

#define LINUX_AF_PACKET   17

◆ LINUX_SOCK_RAW

#define LINUX_SOCK_RAW   3

Definition at line 45 of file af_packet.c.

Referenced by af_packet_nic_open(), and af_packet_update_properties().

◆ LINUX_SIOCGIFINDEX

#define LINUX_SIOCGIFINDEX   0x8933

Definition at line 46 of file af_packet.c.

Referenced by af_packet_nic_open().

◆ LINUX_SIOCGIFHWADDR

#define LINUX_SIOCGIFHWADDR   0x8927

Definition at line 47 of file af_packet.c.

Referenced by af_packet_update_properties().

◆ RX_BUF_SIZE

#define RX_BUF_SIZE   1536

Definition at line 49 of file af_packet.c.

Function Documentation

◆ af_packet_nic_open()

int af_packet_nic_open ( struct net_device * netdev)
static

Open the linux interface.

Definition at line 68 of file af_packet.c.

69{
70 struct af_packet_nic * nic = netdev->priv;
71 struct sockaddr_ll socket_address;
72 struct ifreq if_data;
73 int ret;
74
76 htons(ETH_P_ALL));
77 if (nic->fd < 0) {
78 DBGC(nic, "af_packet %p socket(AF_PACKET) = %d (%s)\n",
80 return nic->fd;
81 }
82
83 /* resolve ifindex of ifname */
84 memset(&if_data, 0, sizeof(if_data));
85 strncpy(if_data.ifr_name, nic->ifname, sizeof(if_data.ifr_name));
86 ret = linux_ioctl(nic->fd, LINUX_SIOCGIFINDEX, &if_data);
87 if (ret < 0) {
88 DBGC(nic, "af_packet %p ioctl(SIOCGIFINDEX) = %d (%s)\n",
90 linux_close(nic->fd);
91 return ret;
92 }
93
94 nic->ifindex = if_data.ifr_ifindex;
95
96 /* bind to interface */
97 memset(&socket_address, 0, sizeof(socket_address));
98 socket_address.sll_family = LINUX_AF_PACKET;
99 socket_address.sll_ifindex = nic->ifindex;
100 socket_address.sll_protocol = htons(ETH_P_ALL);
101 ret = linux_bind(nic->fd, (void *) &socket_address,
102 sizeof(socket_address));
103 if (ret == -1) {
104 DBGC(nic, "af_packet %p bind() = %d (%s)\n",
106 linux_close(nic->fd);
107 return ret;
108 }
109
110 /* Set nonblocking mode to make af_packet_nic_poll() easier */
111 ret = linux_fcntl(nic->fd, F_SETFL, O_NONBLOCK);
112 if (ret != 0) {
113 DBGC(nic, "af_packet %p fcntl(%d, ...) = %d (%s)\n",
114 nic, nic->fd, ret, linux_strerror(linux_errno));
115 linux_close(nic->fd);
116 return ret;
117 }
118
119 return 0;
120}
#define LINUX_AF_PACKET
Definition af_packet.c:44
#define LINUX_SOCK_RAW
Definition af_packet.c:45
#define LINUX_SIOCGIFINDEX
Definition af_packet.c:46
static struct net_device * netdev
Definition gdbudp.c:53
#define DBGC(...)
Definition compiler.h:505
#define htons(value)
Definition byteswap.h:136
void * memset(void *dest, int character, size_t len) __nonnull
int linux_errno
int __asmcall linux_bind(int sockfd, const struct sockaddr *addr, size_t addrlen)
int __asmcall linux_ioctl(int fd, unsigned long request,...)
int __asmcall linux_close(int fd)
int __asmcall linux_fcntl(int fd, int cmd,...)
int __asmcall linux_socket(int domain, int type, int protocol)
const char *__asmcall linux_strerror(int linux_errno)
char * strncpy(char *dest, const char *src, size_t max)
Copy string.
Definition string.c:361
Definition nic.h:49

References DBGC, htons, LINUX_AF_PACKET, linux_bind(), linux_close(), linux_errno, linux_fcntl(), linux_ioctl(), LINUX_SIOCGIFINDEX, LINUX_SOCK_RAW, linux_socket(), linux_strerror(), memset(), netdev, and strncpy().

◆ af_packet_nic_close()

void af_packet_nic_close ( struct net_device * netdev)
static

Close the packet socket.

Definition at line 123 of file af_packet.c.

124{
125 struct af_packet_nic * nic = netdev->priv;
126 linux_close(nic->fd);
127}

References linux_close(), and netdev.

◆ af_packet_nic_transmit()

int af_packet_nic_transmit ( struct net_device * netdev,
struct io_buffer * iobuf )
static

Transmit an ethernet packet.

The packet can be written to the socket and marked as complete immediately.

Definition at line 134 of file af_packet.c.

136{
137 struct af_packet_nic * nic = netdev->priv;
138 struct sockaddr_ll socket_address;
139 const struct ethhdr * eh;
140 int rc;
141
142 memset(&socket_address, 0, sizeof(socket_address));
143 socket_address.sll_family = LINUX_AF_PACKET;
144 socket_address.sll_ifindex = nic->ifindex;
145 socket_address.sll_halen = ETH_ALEN;
146
147 eh = iobuf->data;
148 memcpy(socket_address.sll_addr, eh->h_dest, ETH_ALEN);
149
150 rc = linux_sendto(nic->fd, iobuf->data, iobuf->tail - iobuf->data,
151 0, (struct sockaddr *)&socket_address,
152 sizeof(socket_address));
153
154 DBGC2(nic, "af_packet %p wrote %d bytes\n", nic, rc);
156
157 return 0;
158}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define DBGC2(...)
Definition compiler.h:522
#define ETH_ALEN
Definition if_ether.h:9
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ssize_t __asmcall linux_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, size_t addrlen)
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
Definition netdevice.h:767
An Ethernet link-layer header.
Definition if_ether.h:32
uint8_t h_dest[ETH_ALEN]
Destination MAC address.
Definition if_ether.h:34
void * data
Start of data.
Definition iobuf.h:53
void * tail
End of data.
Definition iobuf.h:55
Generalized socket address structure.
Definition socket.h:97

References io_buffer::data, DBGC2, ETH_ALEN, ethhdr::h_dest, LINUX_AF_PACKET, linux_sendto(), memcpy(), memset(), netdev, netdev_tx_complete(), rc, and io_buffer::tail.

◆ af_packet_nic_poll()

void af_packet_nic_poll ( struct net_device * netdev)
static

Poll for new packets.

Definition at line 161 of file af_packet.c.

162{
163 struct af_packet_nic * nic = netdev->priv;
164 struct pollfd pfd;
165 struct io_buffer * iobuf;
166 int r;
167
168 pfd.fd = nic->fd;
169 pfd.events = POLLIN;
170 if (linux_poll(&pfd, 1, 0) == -1) {
171 DBGC(nic, "af_packet %p poll failed (%s)\n",
173 return;
174 }
175 if ((pfd.revents & POLLIN) == 0)
176 return;
177
178 /* At this point we know there is at least one new packet to be read */
179
180 iobuf = alloc_iob(RX_BUF_SIZE);
181 if (! iobuf)
182 goto allocfail;
183
184 while ((r = linux_read(nic->fd, iobuf->data, RX_BUF_SIZE)) > 0) {
185 DBGC2(nic, "af_packet %p read %d bytes\n", nic, r);
186
187 iob_put(iobuf, r);
188 netdev_rx(netdev, iobuf);
189
190 iobuf = alloc_iob(RX_BUF_SIZE);
191 if (! iobuf)
192 goto allocfail;
193 }
194
195 free_iob(iobuf);
196 return;
197
198allocfail:
199 DBGC(nic, "af_packet %p alloc_iob failed\n", nic);
200}
#define RX_BUF_SIZE
Definition 3c90x.h:269
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_put(iobuf, len)
Definition iobuf.h:125
ssize_t __asmcall linux_read(int fd, void *buf, size_t count)
int __asmcall linux_poll(struct pollfd *fds, unsigned int nfds, int timeout)
static const uint8_t r[3][4]
MD4 shift amounts.
Definition md4.c:54
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549
A persistent I/O buffer.
Definition iobuf.h:38

References alloc_iob(), io_buffer::data, DBGC, DBGC2, free_iob(), iob_put, linux_errno, linux_poll(), linux_read(), linux_strerror(), netdev, netdev_rx(), r, and RX_BUF_SIZE.

◆ af_packet_nic_irq()

void af_packet_nic_irq ( struct net_device * netdev,
int enable )
static

Set irq.

Not used on linux, provide a dummy implementation.

Definition at line 207 of file af_packet.c.

208{
209 struct af_packet_nic *nic = netdev->priv;
210
211 DBGC(nic, "af_packet %p irq enable = %d\n", nic, enable);
212}

References DBGC, and netdev.

◆ af_packet_update_properties()

int af_packet_update_properties ( struct net_device * netdev)
static

Definition at line 215 of file af_packet.c.

216{
217 struct af_packet_nic *nic = netdev->priv;
218 struct ifreq if_data;
219 int ret;
220
221 /* retrieve default MAC address */
223 if (fd < 0) {
224 DBGC(nic, "af_packet %p cannot create raw socket (%s)\n",
226 return fd;
227 }
228
229 /* retrieve host's MAC address */
230 memset(&if_data, 0, sizeof(if_data));
231 strncpy(if_data.ifr_name, nic->ifname, sizeof(if_data.ifr_name));
232 ret = linux_ioctl(fd, LINUX_SIOCGIFHWADDR, &if_data);
233 if (ret < 0) {
234 DBGC(nic, "af_packet %p cannot get mac addr (%s)\n",
236 linux_close(fd);
237 return ret;
238 }
239
240 linux_close(fd);
241 /* struct sockaddr = { u16 family, u8 pad[14] (equiv. sa_data) }; */
242 memcpy(netdev->ll_addr, if_data.ifr_hwaddr.pad, ETH_ALEN);
243 return 0;
244}
#define LINUX_SIOCGIFHWADDR
Definition af_packet.c:47

References DBGC, ETH_ALEN, LINUX_AF_PACKET, linux_close(), linux_errno, linux_ioctl(), LINUX_SIOCGIFHWADDR, LINUX_SOCK_RAW, linux_socket(), linux_strerror(), memcpy(), memset(), netdev, and strncpy().

Referenced by af_packet_nic_probe().

◆ af_packet_nic_probe()

int af_packet_nic_probe ( struct linux_device * device,
struct linux_device_request * request )
static

Handle a device request for the af_packet driver.

Definition at line 256 of file af_packet.c.

258{
259 struct linux_setting *if_setting;
260 struct net_device *netdev;
261 struct af_packet_nic *nic;
262 int rc;
263
264 netdev = alloc_etherdev(sizeof(*nic));
265 if (! netdev)
266 return -ENOMEM;
267
269 nic = netdev->priv;
271 netdev->dev = &device->dev;
272
273 memset(nic, 0, sizeof(*nic));
274
275 /* Look for the mandatory if setting */
276 if_setting = linux_find_setting("if", &request->settings);
277
278 /* No if setting */
279 if (! if_setting) {
280 printf("af_packet missing a mandatory if setting\n");
281 rc = -EINVAL;
282 goto err_settings;
283 }
284
285 nic->ifname = if_setting->value;
286 snprintf ( device->dev.name, sizeof ( device->dev.name ), "%s",
287 nic->ifname );
290 if_setting->applied = 1;
291
292 /* Apply rest of the settings */
293 linux_apply_settings(&request->settings, &netdev->settings.settings);
294
295 /* Register network device */
296 if ((rc = register_netdev(netdev)) != 0)
297 goto err_register;
298
300
301 return 0;
302
304err_register:
305err_settings:
308 return rc;
309}
static struct net_device_operations af_packet_nic_operations
AF_PACKET operations.
Definition af_packet.c:247
static int af_packet_update_properties(struct net_device *netdev)
Definition af_packet.c:215
#define BUS_TYPE_TAP
TAP bus type.
Definition device.h:59
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOMEM
Not enough space.
Definition errno.h:535
u8 request[0]
List of IEs requested.
Definition ieee80211.h:2
static void linux_set_drvdata(struct linux_device *device, void *priv)
Set linux device driver-private data.
Definition linux.h:78
void linux_apply_settings(struct list_head *new_settings, struct settings *settings_block)
Apply a list of linux settings to a settings block.
struct linux_setting * linux_find_setting(char *name, struct list_head *settings)
Look for the last occurrence of a setting with the specified name.
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:942
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition netdevice.h:789
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:519
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:532
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
unsigned int bus_type
Bus type.
Definition device.h:25
A hardware device.
Definition device.h:77
struct device_description desc
Device description.
Definition device.h:83
char name[40]
Name.
Definition device.h:79
A device request setting.
Definition linux.h:109
int applied
Was the setting already applied?
Definition linux.h:115
char * value
Value.
Definition linux.h:113
A network device.
Definition netdevice.h:353
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition vsprintf.c:465
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

References af_packet_nic_operations, af_packet_update_properties(), alloc_etherdev(), linux_setting::applied, device_description::bus_type, BUS_TYPE_TAP, device::desc, EINVAL, ENOMEM, linux_apply_settings(), linux_find_setting(), linux_set_drvdata(), memset(), device::name, netdev, netdev_init(), netdev_link_up(), netdev_nullify(), netdev_put(), printf(), rc, register_netdev(), request, snprintf(), unregister_netdev(), and linux_setting::value.

◆ af_packet_nic_remove()

void af_packet_nic_remove ( struct linux_device * device)
static

Remove the device.

Definition at line 312 of file af_packet.c.

313{
318}
static void * linux_get_drvdata(struct linux_device *device)
Get linux device driver-private data.
Definition linux.h:89

References linux_get_drvdata(), netdev, netdev_nullify(), netdev_put(), and unregister_netdev().

◆ LINUX_ROM()

LINUX_ROM ( "af_packet" ,
"AF_PACKET binding NIC"  )

Variable Documentation

◆ af_packet_nic_operations

struct net_device_operations af_packet_nic_operations
static
Initial value:
= {
}
static void af_packet_nic_poll(struct net_device *netdev)
Poll for new packets.
Definition af_packet.c:161
static void af_packet_nic_close(struct net_device *netdev)
Close the packet socket.
Definition af_packet.c:123
static void af_packet_nic_irq(struct net_device *netdev, int enable)
Set irq.
Definition af_packet.c:207
static int af_packet_nic_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit an ethernet packet.
Definition af_packet.c:134
static int af_packet_nic_open(struct net_device *netdev)
Open the linux interface.
Definition af_packet.c:68

AF_PACKET operations.

Definition at line 247 of file af_packet.c.

247 {
248 .open = af_packet_nic_open,
249 .close = af_packet_nic_close,
250 .transmit = af_packet_nic_transmit,
251 .poll = af_packet_nic_poll,
252 .irq = af_packet_nic_irq,
253};

Referenced by af_packet_nic_probe().

◆ __linux_driver

struct linux_driver af_packet_nic_driver __linux_driver
Initial value:
= {
.name = "af_packet",
}
static int af_packet_nic_probe(struct linux_device *device, struct linux_device_request *request)
Handle a device request for the af_packet driver.
Definition af_packet.c:256
static void af_packet_nic_remove(struct linux_device *device)
Remove the device.
Definition af_packet.c:312

AF_PACKET linux_driver.

Definition at line 321 of file af_packet.c.

321 {
322 .name = "af_packet",
323 .probe = af_packet_nic_probe,
324 .remove = af_packet_nic_remove,
325};