summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dhcpv6.h5
-rw-r--r--ldra.c115
2 files changed, 64 insertions, 56 deletions
diff --git a/dhcpv6.h b/dhcpv6.h
index ebfa93a..4a1d9d0 100644
--- a/dhcpv6.h
+++ b/dhcpv6.h
@@ -35,11 +35,6 @@ static struct dhcpv6_option *nextopt(const struct dhcpv6_option *opt) {
}
-#define NEXTOPT(x) \
- x = ((struct dhcpv6_option *)x)->len ? \
- (struct dhcpv6_option *)((char *)x + (ntohs(((struct dhcpv6_option *)x)->len) + sizeof(struct dhcpv6_option))) : \
- NULL
-
/* all the following are ref http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xml */
/* message types */
diff --git a/ldra.c b/ldra.c
index a4cf69b..20dcbc4 100644
--- a/ldra.c
+++ b/ldra.c
@@ -61,12 +61,6 @@ http://aschauf.landshut.org/fh/linux/udp_vs_raw/ch01s03.html
#include <netinet/udp.h>
#include "dhcpv6.h"
-/* total size of packet headers - include VLAN tag as well? */
-#define PKTHDRZ (sizeof(struct ethhdr) + sizeof(struct ip6_hdr) + sizeof(struct udphdr))
-
-/* 802.1q tag size */
-#define VLANTAGZ 4
-
/* attempting to filter out IPv6 to udp port 547
NOTE: This filter is created as short as possible for sorting out
the interesting packets. The packets need further sanity checking
@@ -265,8 +259,9 @@ int sendit(int s, char *txbuf, int len, int ifidx)
fprintf(stderr, "sending %d bytes to %s on ifid=%d:\n", len, macstr((char *)ll.sll_addr), ll.sll_ifindex);
- if (len < 1000)
+/* if (len < 1000)
print_hex(txbuf, len);
+*/
if (ret = sendto(s, txbuf, len, 0, (struct sockaddr *)&ll, sizeof(ll)) == -1)
fprintf(stderr, "sendto() failed: %m\n");
@@ -412,58 +407,56 @@ Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory.
txbuf = malloc(ETH_FRAME_LEN);
- for (i = 0; i<20; i++) {
-
- /* get the VLAN tag etc */
- memset(&msg, 0, sizeof(msg));
- msg.msg_name = &ll;
- msg.msg_namelen = sizeof(ll);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = &cmsg_buf;
- msg.msg_controllen = sizeof(cmsg_buf);
- msg.msg_flags = 0;
-
- iov.iov_len = ETH_FRAME_LEN;
- iov.iov_base = buf;
-
- len = recvmsg(s, &msg, MSG_TRUNC);
-
- if (len == -1) {
- fprintf(stderr, "%s(): recvfrom failed: %m\n", __FUNCTION__);
- return(0);
- }
-
-
- /* ignore outgoing packets */
- if (ll.sll_pkttype == PACKET_OUTGOING)
- continue;
+// for (i = 0; i<20; i++) {
- /* reset before continuing */
- vlan=0;
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
- struct tpacket_auxdata *aux;
+ for (;;) {
- /* only looking for the PACKET_AUXDATA msg */
- if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct tpacket_auxdata)) ||
- cmsg->cmsg_level != SOL_PACKET ||
- cmsg->cmsg_type != PACKET_AUXDATA)
+ /* get the VLAN tag etc */
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = &ll;
+ msg.msg_namelen = sizeof(ll);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = &cmsg_buf;
+ msg.msg_controllen = sizeof(cmsg_buf);
+ msg.msg_flags = 0;
+
+ iov.iov_len = ETH_FRAME_LEN;
+ iov.iov_base = buf;
+
+ len = recvmsg(s, &msg, MSG_TRUNC);
+
+ if (len == -1) {
+ fprintf(stderr, "%s(): recvfrom failed: %m\n", __FUNCTION__);
+ return(0);
+ }
+
+
+ /* ignore outgoing packets */
+ if (ll.sll_pkttype == PACKET_OUTGOING)
continue;
-
- aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg);
- if (aux->tp_status & TP_STATUS_VLAN_VALID)
- vlan = aux->tp_vlan_tci;
- }
+
+ /* get the VLAN tag */
+ vlan=0;
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ struct tpacket_auxdata *aux;
+
+ /* only looking for the PACKET_AUXDATA msg */
+ if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct tpacket_auxdata)) ||
+ cmsg->cmsg_level != SOL_PACKET ||
+ cmsg->cmsg_type != PACKET_AUXDATA)
+ continue;
+
+ aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg);
+ if (aux->tp_status & TP_STATUS_VLAN_VALID)
+ vlan = aux->tp_vlan_tci;
+ }
/* do some common checks before knowing whether this packet goes up or down */
/* NOTE: Not necessarily a relay message, but we only look at msg_type until we know for sure */
- dhcpv6 = (struct dhcpv6_relay_msg *)(buf + PKTHDRZ);
-
- fprintf(stderr, "received %d bytes from %s on interface %d (vlan=%d) with DHCPv6 type=%hhd\n",
- len, macstr((char *)ll.sll_addr), ll.sll_ifindex, vlan, dhcpv6->msg_type);
+ dhcpv6 = (struct dhcpv6_relay_msg *)(buf + sizeof(struct ethhdr) + sizeof(struct ip6_hdr) + sizeof(struct udphdr));
-
/* packets from upstream are simple to discard */
if (ll.sll_ifindex == idx_up) {
struct dhcpv6_option *opt;
@@ -489,6 +482,10 @@ Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory.
if (txintf < 0)
continue;
+ fprintf(stderr, "received %d bytes from %s on interface %d (vlan=%d) with DHCPv6 type=%hhd\n",
+ len, macstr((char *)ll.sll_addr), ll.sll_ifindex, vlan, dhcpv6->msg_type);
+
+
/* create tx packet header */
size = copyheader(txbuf, buf, txintf & 0xfff);
@@ -554,6 +551,10 @@ Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory.
verify that message type is not one of the forbidden ones
*/
+
+ fprintf(stderr, "received %d bytes from %s on interface %d (vlan=%d) with DHCPv6 type=%hhd\n",
+ len, macstr((char *)ll.sll_addr), ll.sll_ifindex, vlan, dhcpv6->msg_type);
+
/* create tx packet header */
size = copyheader(txbuf, buf, 0); /* no VLAN */
@@ -580,6 +581,18 @@ Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory.
val = (int *)&opt->data;
*val = htonl((ll.sll_ifindex) << 16 | (vlan & 0xfff));
+ /* fill in REMOTE-ID */
+ opt = nextopt(opt);
+ opt->code = htons(OPTION_REMOTE_ID);
+ opt->len = htons(sprintf((char *)&opt->data, "xxxx%08d", vlan));
+ val = (int *)&opt->data;
+ *val = htonl(32434);
+
+ /* fill in SUBSCRIBER-ID */
+ opt = nextopt(opt);
+ opt->code = htons(OPTION_SUBSCRIBER_ID);
+ opt->len = htons(sprintf((char *)&opt->data, "sub%d", vlan));
+
/* fill in OPTION_RELAY_MSG */
opt = nextopt(opt);
opt->code = htons(OPTION_RELAY_MSG);