From 6faf164ce90e5a30225002a1bad41834a6a5fc8b Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Sun, 21 Nov 1999 10:43:05 +0000 Subject: [PATCH] Fixes from brian. With some changes from me. Allows FreeBSD to run as a PPPOE server One patch still not included. --- sys/netgraph/ng_pppoe.c | 55 +++++++++++++++++++++++-------------- sys/netgraph/ng_socket.c | 58 +++++++++++++++++++++++++--------------- sys/netgraph/ng_socket.h | 2 +- 3 files changed, 73 insertions(+), 42 deletions(-) diff --git a/sys/netgraph/ng_pppoe.c b/sys/netgraph/ng_pppoe.c index 5cc7983f3f53..6499e8fc3638 100644 --- a/sys/netgraph/ng_pppoe.c +++ b/sys/netgraph/ng_pppoe.c @@ -98,12 +98,12 @@ NETGRAPH_INIT(pppoe, &typestruct); */ enum state { PPPOE_SNONE=0, /* [both] Initial state */ + PPPOE_LISTENING, /* [Daemon] Listening for discover initiation pkt */ PPPOE_SINIT, /* [Client] Sent discovery initiation */ - PPPOE_PRIMED, /* [Server] Received discovery initiation */ - PPPOE_SOFFER, /* [Server] Sent offer message */ + PPPOE_PRIMED, /* [Server] Awaiting PADI from daemon */ + PPPOE_SOFFER, /* [Server] Sent offer message (got PADI)*/ PPPOE_SREQ, /* [Client] Sent a Request */ - PPPOE_LISTENING, /* [Server] Listening for discover initiation msg */ - PPPOE_NEWCONNECTED, /* [Both] Connection established, No data received */ + PPPOE_NEWCONNECTED, /* [Server] Connection established, No data received */ PPPOE_CONNECTED, /* [Both] Connection established, Data received */ PPPOE_DEAD /* [Both] */ }; @@ -833,7 +833,7 @@ AAA */ printf("packet fragmented\n"); LEAVE(EMSGSIZE); - } + } switch(code) { case PADI_CODE: @@ -975,8 +975,8 @@ AAA insert_tag(sp, utag); /* ac_cookie */ scan_tags(sp, ph); make_packet(sp); - sendpacket(sp); sp->state = PPPOE_NEWCONNECTED; + sendpacket(sp); /* * Having sent the last Negotiation header, * Set up the stored packet header to @@ -1245,7 +1245,7 @@ ng_pppoe_connect(hook_p hook) /* * Hook disconnection * - * Clean up all dangling links and infirmation about the session/hook. + * Clean up all dangling links and information about the session/hook. * For this type, removal of the last link destroys the node */ static int @@ -1284,18 +1284,28 @@ AAA /* generate a packet of that type */ MGETHDR(m, M_DONTWAIT, MT_DATA); - m->m_pkthdr.rcvif = NULL; - m->m_pkthdr.len = m->m_len = sizeof(*wh); - bcopy((caddr_t)wh, mtod(m, caddr_t), sizeof(*wh)); - /* Add a General error message and adjust sizes */ - wh = mtod(m, struct pppoe_full_hdr *); - tag = wh->ph.tag; - tag->tag_type = PTT_GEN_ERR; - tag->tag_len = htons((u_int16_t)msglen); - strncpy(tag->tag_data, SIGNOFF, msglen); - m->m_pkthdr.len = (m->m_len += sizeof(*tag) + msglen); - wh->ph.length = htons(sizeof(*tag) + msglen); - NG_SEND_DATA(error, privp->ethernet_hook, m, dummy); + if(m == NULL) + printf("pppoe: Session out of mbufs\n"); + else { + m->m_pkthdr.rcvif = NULL; + m->m_pkthdr.len = m->m_len = sizeof(*wh); + bcopy((caddr_t)wh, mtod(m, caddr_t), + sizeof(*wh)); + /* + * Add a General error message and adjust + * sizes + */ + wh = mtod(m, struct pppoe_full_hdr *); + tag = wh->ph.tag; + tag->tag_type = PTT_GEN_ERR; + tag->tag_len = htons((u_int16_t)msglen); + strncpy(tag->tag_data, SIGNOFF, msglen); + m->m_pkthdr.len = (m->m_len += sizeof(*tag) + + msglen); + wh->ph.length = htons(sizeof(*tag) + msglen); + NG_SEND_DATA(error, privp->ethernet_hook, m, + dummy); + } } if (sp->neg) { untimeout(pppoe_ticker, hook, sp->neg->timeout_handle); @@ -1384,11 +1394,16 @@ AAA case PPPOE_LISTENING: case PPPOE_DEAD: case PPPOE_SNONE: - case PPPOE_NEWCONNECTED: case PPPOE_CONNECTED: printf("pppoe: sendpacket: unexpected state\n"); break; + case PPPOE_NEWCONNECTED: + /* send the PADS without a timeout - we're now connected */ + m0 = m_copypacket(sp->neg->m, M_DONTWAIT); + NG_SEND_DATA( error, privp->ethernet_hook, m0, dummy); + break; + case PPPOE_PRIMED: /* No packet to send, but set up the timeout */ neg->timeout_handle = timeout(pppoe_ticker, diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c index 65e09f5a1ce0..76fd38bfe819 100644 --- a/sys/netgraph/ng_socket.c +++ b/sys/netgraph/ng_socket.c @@ -306,10 +306,10 @@ ngd_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, { struct ngpcb *const pcbp = sotongpcb(so); struct sockaddr_ng *const sap = (struct sockaddr_ng *) addr; - char *hookname = NULL; meta_p mp = NULL; int len, error; - hook_p hook; + hook_p hook = NULL; + char hookname[NG_HOOKLEN + 1]; if ((pcbp == NULL) || (control != NULL)) { error = EINVAL; @@ -319,26 +319,42 @@ ngd_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, error = ENOTCONN; goto release; } - if (addr == NULL) { - error = EDESTADDRREQ; - goto release; - } + /* + * If the user used any of these ways to not specify an address + * then handle specially. + */ + if ((sap == NULL) + || ((len = sap->sg_len) <= 2) + || (*sap->sg_data == '\0')) { + if (pcbp->sockdata->node->numhooks != 1) { + error = EDESTADDRREQ; + goto release; + } + /* + * if exactly one hook exists, just use it. + * Special case to allow write(2) to work on an ng_socket. + */ + hook = LIST_FIRST(&pcbp->sockdata->node->hooks); + } else { + if (len > NG_HOOKLEN) { + error = EINVAL; + goto release; + } - /* Allocate an expendable buffer for the hook name, chop off - * the sockaddr header, and make sure it's NUL terminated */ - len = sap->sg_len - 2; - MALLOC(hookname, char *, len + 1, M_NETGRAPH, M_WAITOK); - if (hookname == NULL) { - error = ENOMEM; - goto release; - } - bcopy(sap->sg_data, hookname, len); - hookname[len] = '\0'; + /* + * chop off the sockaddr header, and make sure it's NUL + * terminated + */ + bcopy(sap->sg_data, hookname, len); + hookname[len] = '\0'; - /* Find the correct hook from 'hookname' */ - LIST_FOREACH(hook, &pcbp->sockdata->node->hooks, hooks) { - if (strcmp(hookname, hook->name) == 0) - break; + /* Find the correct hook from 'hookname' */ + LIST_FOREACH(hook, &pcbp->sockdata->node->hooks, hooks) { + if (strcmp(hookname, hook->name) == 0) + break; + } + if (hook == NULL) + error = EHOSTUNREACH; } /* Send data (OK if hook is NULL) */ @@ -817,7 +833,7 @@ ngs_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) } /* - * Dook disconnection + * Hook disconnection * * For this type, removal of the last link destroys the node * if the NOLINGER flag is set. diff --git a/sys/netgraph/ng_socket.h b/sys/netgraph/ng_socket.h index 1aacdf37b4de..517b316b91de 100644 --- a/sys/netgraph/ng_socket.h +++ b/sys/netgraph/ng_socket.h @@ -53,7 +53,7 @@ /* Commands */ enum { - NGM_SOCK_CMD_NOLINGER = 1, /* close the soket on with last hook */ + NGM_SOCK_CMD_NOLINGER = 1, /* close the socket with last hook */ NGM_SOCK_CMD_LINGER /* Keep socket even if 0 hooks */ };