166 |
return sendmsg(pkt_fd, &msg, 0); |
return sendmsg(pkt_fd, &msg, 0); |
167 |
} |
} |
168 |
|
|
169 |
/* |
void packet_discard(struct netdev *dev) |
|
* Fetches a bootp packet, but doesn't remove it. |
|
|
* Returns: |
|
|
* 0 = Error |
|
|
* >0 = A packet of size "ret" is available for interface ifindex |
|
|
*/ |
|
|
int packet_peek(int *ifindex) |
|
|
{ |
|
|
struct sockaddr_ll sll; |
|
|
struct iphdr iph; |
|
|
int ret, sllen = sizeof(struct sockaddr_ll); |
|
|
|
|
|
/* |
|
|
* Peek at the IP header. |
|
|
*/ |
|
|
ret = recvfrom(pkt_fd, &iph, sizeof(struct iphdr), |
|
|
MSG_PEEK, (struct sockaddr *)&sll, &sllen); |
|
|
if (ret == -1) |
|
|
return 0; |
|
|
|
|
|
if (sll.sll_family != AF_PACKET) |
|
|
goto discard_pkt; |
|
|
|
|
|
if (iph.ihl < 5 || iph.version != IPVERSION) |
|
|
goto discard_pkt; |
|
|
|
|
|
*ifindex = sll.sll_ifindex; |
|
|
|
|
|
return ret; |
|
|
|
|
|
discard_pkt: |
|
|
packet_discard(); |
|
|
return 0; |
|
|
} |
|
|
|
|
|
void packet_discard(void) |
|
170 |
{ |
{ |
171 |
struct iphdr iph; |
struct iphdr iph; |
172 |
struct sockaddr_ll sll; |
struct sockaddr_ll sll; |
173 |
socklen_t sllen = sizeof(sll); |
socklen_t sllen = sizeof(sll); |
174 |
|
|
175 |
|
sll.sll_ifindex = dev->ifindex; |
176 |
|
|
177 |
recvfrom(pkt_fd, &iph, sizeof(iph), 0, |
recvfrom(pkt_fd, &iph, sizeof(iph), 0, |
178 |
(struct sockaddr *)&sll, &sllen); |
(struct sockaddr *)&sll, &sllen); |
179 |
} |
} |
182 |
* Receive a bootp packet. The options are listed in iov[1...iov_len]. |
* Receive a bootp packet. The options are listed in iov[1...iov_len]. |
183 |
* iov[0] must point to the bootp packet header. |
* iov[0] must point to the bootp packet header. |
184 |
* Returns: |
* Returns: |
185 |
* 0 = Error, try again later |
* -1 = Error, try again later |
186 |
|
* 0 = Discarded packet (non-DHCP/BOOTP traffic) |
187 |
* >0 = Size of packet |
* >0 = Size of packet |
188 |
*/ |
*/ |
189 |
int packet_recv(struct iovec *iov, int iov_len) |
int packet_recv(struct netdev* dev, struct iovec *iov, int iov_len) |
190 |
{ |
{ |
191 |
struct iphdr *ip, iph; |
struct iphdr *ip, iph; |
192 |
struct udphdr *udp; |
struct udphdr *udp; |
200 |
.msg_flags = 0 |
.msg_flags = 0 |
201 |
}; |
}; |
202 |
int ret, iphl; |
int ret, iphl; |
203 |
|
struct sockaddr_ll sll; |
204 |
|
socklen_t sllen = sizeof(sll); |
205 |
|
|
206 |
|
sll.sll_ifindex = dev->ifindex; |
207 |
|
msg.msg_name = &sll; |
208 |
|
msg.msg_namelen = sllen; |
209 |
|
|
210 |
ret = recvfrom(pkt_fd, &iph, sizeof(struct iphdr), |
ret = recvfrom(pkt_fd, &iph, sizeof(struct iphdr), |
211 |
MSG_PEEK, NULL, NULL); |
MSG_PEEK, (struct sockaddr *)&sll, &sllen); |
212 |
if (ret == -1) |
if (ret == -1) |
213 |
return 0; |
return -1; |
214 |
|
|
215 |
if (iph.ihl < 5 || iph.version != IPVERSION) |
if (iph.ihl < 5 || iph.version != IPVERSION) |
216 |
goto discard_pkt; |
goto discard_pkt; |
266 |
|
|
267 |
discard_pkt: |
discard_pkt: |
268 |
dprintf("discarded\n"); |
dprintf("discarded\n"); |
269 |
packet_discard(); |
packet_discard(dev); |
270 |
return 0; |
return 0; |
271 |
} |
} |