diff options
author | julian <julian@FreeBSD.org> | 1999-11-21 10:43:05 +0000 |
---|---|---|
committer | julian <julian@FreeBSD.org> | 1999-11-21 10:43:05 +0000 |
commit | ff227a07ea9a4c70d2185c81b1cfc4e65ecca43b (patch) | |
tree | 928215c016507b96e031aceda605a2ae2096f60a /sys/netgraph/ng_socket.c | |
parent | 34ed7085e34b1f01e590848167fde695bd86edbd (diff) | |
download | FreeBSD-src-ff227a07ea9a4c70d2185c81b1cfc4e65ecca43b.zip FreeBSD-src-ff227a07ea9a4c70d2185c81b1cfc4e65ecca43b.tar.gz |
Fixes from brian. With some changes from me.
Allows FreeBSD to run as a PPPOE server
One patch still not included.
Diffstat (limited to 'sys/netgraph/ng_socket.c')
-rw-r--r-- | sys/netgraph/ng_socket.c | 60 |
1 files changed, 38 insertions, 22 deletions
diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c index 65e09f5..76fd38b 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; - } - - /* 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'; + /* + * 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; + } - /* Find the correct hook from 'hookname' */ - LIST_FOREACH(hook, &pcbp->sockdata->node->hooks, hooks) { - if (strcmp(hookname, hook->name) == 0) - break; + /* + * 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; + } + 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. |