summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_pppoe.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/sys/net/if_pppoe.c b/sys/net/if_pppoe.c
index 8d18f98e8bb..18f213d3581 100644
--- a/sys/net/if_pppoe.c
+++ b/sys/net/if_pppoe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_pppoe.c,v 1.14 2008/02/20 09:37:52 brad Exp $ */
+/* $OpenBSD: if_pppoe.c,v 1.15 2008/03/12 17:27:03 canacar Exp $ */
/* $NetBSD: if_pppoe.c,v 1.51 2003/11/28 08:56:48 keihan Exp $ */
/*
@@ -144,6 +144,8 @@ struct pppoe_softc {
char *sc_concentrator_name; /* if != NULL: requested concentrator id */
u_int8_t *sc_ac_cookie; /* content of AC cookie we must echo back */
size_t sc_ac_cookie_len; /* length of cookie data */
+ u_int8_t *sc_relay_sid; /* content of relay SID we must echo back */
+ size_t sc_relay_sid_len; /* length of relay SID data */
#ifdef PPPOE_SERVER
u_int8_t *sc_hunique; /* content of host unique we must echo back */
size_t sc_hunique_len; /* length of host unique */
@@ -290,6 +292,8 @@ pppoe_clone_destroy(struct ifnet *ifp)
free(sc->sc_service_name, M_DEVBUF);
if (sc->sc_ac_cookie)
free(sc->sc_ac_cookie, M_DEVBUF);
+ if (sc->sc_relay_sid)
+ free(sc->sc_relay_sid, M_DEVBUF);
free(sc, M_DEVBUF);
@@ -395,10 +399,12 @@ static void pppoe_dispatch_disc_pkt(struct mbuf *m, int off)
struct ether_header *eh;
const char *err_msg, *devname;
size_t ac_cookie_len;
+ size_t relay_sid_len;
int noff, err, errortag;
u_int16_t tag, len;
u_int16_t session, plen;
u_int8_t *ac_cookie;
+ u_int8_t *relay_sid;
#ifdef PPPOE_SERVER
u_int8_t *hunique;
size_t hunique_len;
@@ -418,6 +424,8 @@ static void pppoe_dispatch_disc_pkt(struct mbuf *m, int off)
ac_cookie = NULL;
ac_cookie_len = 0;
+ relay_sid = NULL;
+ relay_sid_len = 0;
#ifdef PPPOE_SERVER
hunique = NULL;
hunique_len = 0;
@@ -510,6 +518,19 @@ static void pppoe_dispatch_disc_pkt(struct mbuf *m, int off)
ac_cookie_len = len;
}
break;
+ case PPPOE_TAG_RELAYSID:
+ if (relay_sid == NULL) {
+ n = m_pulldown(m, off + sizeof(*pt), len,
+ &noff);
+ if (n == NULL) {
+ err_msg = "TAG RELAYSID ERROR";
+ m = NULL;
+ break;
+ }
+ relay_sid = mtod(n, caddr_t) + noff;
+ relay_sid_len = len;
+ }
+ break;
case PPPOE_TAG_SNAME_ERR:
err_msg = "SERVICE NAME ERROR";
errortag = 1;
@@ -648,6 +669,16 @@ breakbreak:
sc->sc_ac_cookie_len = ac_cookie_len;
memcpy(sc->sc_ac_cookie, ac_cookie, ac_cookie_len);
}
+ if (relay_sid) {
+ if (sc->sc_relay_sid)
+ free(sc->sc_relay_sid, M_DEVBUF);
+ sc->sc_relay_sid = malloc(relay_sid_len, M_DEVBUF,
+ M_DONTWAIT);
+ if (sc->sc_relay_sid == NULL)
+ goto done;
+ sc->sc_relay_sid_len = relay_sid_len;
+ memcpy(sc->sc_relay_sid, relay_sid, relay_sid_len);
+ }
memcpy(&sc->sc_dest, eh->ether_shost, sizeof(sc->sc_dest));
timeout_del(&sc->sc_timeout);
@@ -690,7 +721,12 @@ breakbreak:
free(sc->sc_ac_cookie, M_DEVBUF);
sc->sc_ac_cookie = NULL;
}
+ if (sc->sc_relay_sid) {
+ free(sc->sc_relay_sid, M_DEVBUF);
+ sc->sc_relay_sid = NULL;
+ }
sc->sc_ac_cookie_len = 0;
+ sc->sc_relay_sid_len = 0;
sc->sc_session = 0;
sc->sc_session_time.tv_sec = 0;
sc->sc_session_time.tv_usec = 0;
@@ -1190,6 +1226,11 @@ pppoe_disconnect(struct pppoe_softc *sc)
sc->sc_ac_cookie = NULL;
}
sc->sc_ac_cookie_len = 0;
+ if (sc->sc_relay_sid) {
+ free(sc->sc_relay_sid, M_DEVBUF);
+ sc->sc_relay_sid = NULL;
+ }
+ sc->sc_relay_sid_len = 0;
#ifdef PPPOE_SERVER
if (sc->sc_hunique) {
free(sc->sc_hunique, M_DEVBUF);
@@ -1241,6 +1282,8 @@ pppoe_send_padr(struct pppoe_softc *sc)
}
if (sc->sc_ac_cookie_len > 0)
len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */
+ if (sc->sc_relay_sid_len > 0)
+ len += 2 + 2 + sc->sc_relay_sid_len; /* Relay SID */
m0 = pppoe_get_mbuf(len + PPPOE_HEADERLEN);
if (m0 == NULL)
@@ -1263,6 +1306,12 @@ pppoe_send_padr(struct pppoe_softc *sc)
memcpy(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len);
p += sc->sc_ac_cookie_len;
}
+ if (sc->sc_relay_sid_len > 0) {
+ PPPOE_ADD_16(p, PPPOE_TAG_RELAYSID);
+ PPPOE_ADD_16(p, sc->sc_relay_sid_len);
+ memcpy(p, sc->sc_relay_sid, sc->sc_relay_sid_len);
+ p += sc->sc_relay_sid_len;
+ }
PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
PPPOE_ADD_16(p, sizeof(sc->sc_unique));
memcpy(p, &sc->sc_unique, sizeof(sc->sc_unique));