static int loop_timeout = -1;
static int configured;
static int bringup_first = 0;
+static int n_devices = 0;
/* DHCP vendor class identifier */
char vendor_class_identifier[260];
configure_device(dev);
dump_device_config(dev);
print_device_config(dev);
+ packet_close(dev);
++configured;
* 0 = No dhcp/bootp packet was received
* 1 = A packet was received and handled
*/
-static int do_pkt_recv(int pkt_fd, time_t now)
+static int do_pkt_recv(int nr, struct pollfd *fds, time_t now)
{
- int ret = 0;
+ int i, ret = 0;
struct state *s;
- for (s = slist; s; s = s->next)
- ret |= process_receive_event(s, now);
+ for (i = 0, s = slist; s && nr; s = s->next, i++) {
+ if (fds[i].revents & POLLRDNORM) {
+ ret |= process_receive_event(s, now);
+ nr--;
+ }
+ }
return ret;
}
static int loop(void)
{
-#define NR_FDS 1
- struct pollfd fds[NR_FDS];
+ struct pollfd *fds;
struct state *s;
- int pkt_fd;
- int nr = 0, rc = 0;
+ int i, nr = 0, rc = 0;
struct timeval now, prev;
time_t start;
- pkt_fd = packet_open();
- if (pkt_fd == -1) {
- perror("packet_open");
- return -1;
+ fds = malloc(sizeof(struct pollfd) * n_devices);
+ if (!fds) {
+ fprintf(stderr, "malloc failed\n");
+ goto bail;
}
- fds[0].fd = pkt_fd;
- fds[0].events = POLLRDNORM;
+ memset(fds, 0, sizeof(*fds));
gettimeofday(&now, NULL);
start = now.tv_sec;
int timeout_ms;
int x;
- for (s = slist; s; s = s->next) {
+ for (i = 0, s = slist; s; s = s->next, i++) {
dprintf("%s: state = %d\n", s->dev->name, s->state);
+ fds[i].fd = s->dev->pkt_fd;
+ fds[i].events = POLLRDNORM;
+
if (s->state == DEVST_COMPLETE) {
done++;
continue;
if (timeout_ms <= 0)
timeout_ms = 100;
- nr = poll(fds, NR_FDS, timeout_ms);
+ nr = poll(fds, n_devices, timeout_ms);
prev = now;
gettimeofday(&now, NULL);
- if ((nr > 0) && (fds[0].revents & POLLRDNORM)) {
- if (do_pkt_recv(pkt_fd, now.tv_sec) == 1)
- break;
- }
+ if ((nr > 0) && do_pkt_recv(nr, fds, now.tv_sec))
+ break;
if (loop_timeout >= 0 &&
now.tv_sec - start >= loop_timeout) {
}
}
bail:
- packet_close();
-
+ if (fds)
+ free(fds);
return rc;
}
state->next = slist;
slist = state;
+ n_devices++;
+
return 0;
}
if (bootp_init_if(dev) == -1)
goto bail;
+ if (packet_open(dev) == -1)
+ goto bail;
+
printf("IP-Config: %s hardware address", dev->name);
for (i = 0; i < dev->hwlen; i++)
printf("%c%02x", i == 0 ? ' ' : ':', dev->hwaddr[i]);
+#include <errno.h>/*XXX*/
/*
* Packet socket handling glue.
*/
#include "netdev.h"
#include "packet.h"
-static int pkt_fd = -1;
-
uint16_t cfg_local_port = LOCAL_PORT;
uint16_t cfg_remote_port = REMOTE_PORT;
-int packet_open(void)
+int packet_open(struct netdev *dev)
{
- int fd, one = 1;
-
- if (pkt_fd != -1)
- return pkt_fd;
+ struct sockaddr_ll sll;
+ int fd, rv, one = 1;
/*
* Get a PACKET socket for IP traffic.
sizeof(one)) == -1) {
perror("SO_BROADCAST");
close(fd);
- fd = -1;
+ return -1;
}
- pkt_fd = fd;
+ memset(&sll, 0, sizeof(sll));
+ sll.sll_family = AF_PACKET;
+ sll.sll_ifindex = dev->ifindex;
+
+ rv = bind(fd, (struct sockaddr *)&sll, sizeof(sll));
+ if (-1 == rv) {
+ perror("bind");
+ close(fd);
+ return -1;
+ }
+ dev->pkt_fd = fd;
return fd;
}
-void packet_close(void)
+void packet_close(struct netdev *dev)
{
- close(pkt_fd);
- pkt_fd = -1;
+ close(dev->pkt_fd);
+ dev->pkt_fd = -1;
}
static unsigned int ip_checksum(uint16_t *hdr, int len)
dprintf("\n bytes %d\n", len);
- return sendmsg(pkt_fd, &msg, 0);
+ return sendmsg(dev->pkt_fd, &msg, 0);
}
void packet_discard(struct netdev *dev)
sll.sll_ifindex = dev->ifindex;
- recvfrom(pkt_fd, &iph, sizeof(iph), 0,
+ recvfrom(dev->pkt_fd, &iph, sizeof(iph), 0,
(struct sockaddr *)&sll, &sllen);
}
msg.msg_name = &sll;
msg.msg_namelen = sllen;
- ret = recvfrom(pkt_fd, &iph, sizeof(struct iphdr),
+ ret = recvfrom(dev->pkt_fd, &iph, sizeof(struct iphdr),
MSG_PEEK, (struct sockaddr *)&sll, &sllen);
if (ret == -1)
return -1;
iov[0].iov_base = ip;
iov[0].iov_len = iphl + sizeof(struct udphdr);
- ret = recvmsg(pkt_fd, &msg, 0);
+ ret = recvmsg(dev->pkt_fd, &msg, 0);
if (ret == -1)
goto free_pkt;