From cb2d110ccf282f5d947fdae7ceabd094c0882d00 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Wed, 9 Nov 2011 16:08:35 +0100 Subject: adding some more options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bjørn Mork --- dhcpv6.h | 5 --- ldra.c | 115 +++++++++++++++++++++++++++++++++++---------------------------- 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 #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 = ≪ - 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 = ≪ + 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); -- cgit v1.2.3