summaryrefslogtreecommitdiffstats
path: root/sys/netgraph
diff options
context:
space:
mode:
authorarchie <archie@FreeBSD.org>2001-11-28 19:39:58 +0000
committerarchie <archie@FreeBSD.org>2001-11-28 19:39:58 +0000
commit5ede7a3e25680029d8ae5518ff9a6f1a1542a512 (patch)
tree0a894e57a068629aae32b884b5997e7017796cb9 /sys/netgraph
parent131d4937c052fb318f46eb59e2116c99268f455a (diff)
downloadFreeBSD-src-5ede7a3e25680029d8ae5518ff9a6f1a1542a512.zip
FreeBSD-src-5ede7a3e25680029d8ae5518ff9a6f1a1542a512.tar.gz
When a socket is not connected, allow the peer "struct sockaddr"
to be included in the meta information that is associated with incoming and outgoing packets. Reviewed by: julian MFC after: 1 week
Diffstat (limited to 'sys/netgraph')
-rw-r--r--sys/netgraph/ng_ksocket.c87
-rw-r--r--sys/netgraph/ng_ksocket.h3
2 files changed, 77 insertions, 13 deletions
diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c
index 41ab532..a642122 100644
--- a/sys/netgraph/ng_ksocket.c
+++ b/sys/netgraph/ng_ksocket.c
@@ -885,12 +885,38 @@ ng_ksocket_rcvdata(hook_p hook, item_p item)
const node_p node = NG_HOOK_NODE(hook);
const priv_p priv = NG_NODE_PRIVATE(node);
struct socket *const so = priv->so;
+ struct sockaddr *sa = NULL;
+ meta_p meta;
int error;
struct mbuf *m;
+ /* Extract data and meta information */
NGI_GET_M(item, m);
+ NGI_GET_META(item, meta);
NG_FREE_ITEM(item);
- error = (*so->so_proto->pr_usrreqs->pru_sosend)(so, 0, 0, m, 0, 0, td);
+
+ /* If any meta info, look for peer socket address */
+ if (meta != NULL) {
+ struct meta_field_header *field;
+
+ /* Look for peer socket address */
+ for (field = &meta->options[0];
+ (caddr_t)field < (caddr_t)meta + meta->used_len;
+ field = (struct meta_field_header *)
+ ((caddr_t)field + field->len)) {
+ if (field->cookie != NGM_KSOCKET_COOKIE
+ || field->type != NG_KSOCKET_META_SOCKADDR)
+ continue;
+ sa = (struct sockaddr *)field->data;
+ break;
+ }
+ }
+
+ /* Send packet */
+ error = (*so->so_proto->pr_usrreqs->pru_sosend)(so, sa, 0, m, 0, 0, td);
+
+ /* Clean up and exit */
+ NG_FREE_META(meta);
return (error);
}
@@ -1056,20 +1082,55 @@ ng_ksocket_incoming2(node_p node, hook_p hook, void *arg1, int waitflag)
auio.uio_td = NULL;
auio.uio_resid = 1000000000;
flags = MSG_DONTWAIT;
- do {
+ while (1) {
+ struct sockaddr *sa = NULL;
+ meta_p meta = NULL;
+ struct mbuf *n;
+
+ /* Try to get next packet from socket */
if ((error = (*so->so_proto->pr_usrreqs->pru_soreceive)
- (so, (struct sockaddr **)0, &auio, &m,
- (struct mbuf **)0, &flags)) == 0
- && m != NULL) {
- struct mbuf *n;
-
- /* Don't trust the various socket layers to get the
- packet header and length correct (eg. kern/15175) */
- for (n = m, m->m_pkthdr.len = 0; n; n = n->m_next)
- m->m_pkthdr.len += n->m_len;
- NG_SEND_DATA_ONLY(error, priv->hook, m);
+ (so, (so->so_state & SS_ISCONNECTED) ? NULL : &sa,
+ &auio, &m, (struct mbuf **)0, &flags)) != 0)
+ break;
+
+ /* See if we got anything */
+ if (m == NULL) {
+ if (sa != NULL)
+ FREE(sa, M_SONAME);
+ break;
}
- } while (error == 0 && m != NULL);
+
+ /* Don't trust the various socket layers to get the
+ packet header and length correct (eg. kern/15175) */
+ for (n = m, m->m_pkthdr.len = 0; n != NULL; n = n->m_next)
+ m->m_pkthdr.len += n->m_len;
+
+ /* Put peer's socket address (if any) into a meta info blob */
+ if (sa != NULL) {
+ struct meta_field_header *mhead;
+ u_int len;
+
+ len = sizeof(*meta) + sizeof(*mhead) + sa->sa_len;
+ MALLOC(meta, meta_p, len, M_NETGRAPH_META, M_NOWAIT);
+ if (meta == NULL) {
+ FREE(sa, M_SONAME);
+ goto sendit;
+ }
+ mhead = &meta->options[0];
+ bzero(meta, sizeof(*meta));
+ bzero(mhead, sizeof(*mhead));
+ meta->allocated_len = len;
+ meta->used_len = len;
+ mhead->cookie = NGM_KSOCKET_COOKIE;
+ mhead->type = NG_KSOCKET_META_SOCKADDR;
+ mhead->len = sizeof(*mhead) + sa->sa_len;
+ bcopy(sa, mhead->data, sa->sa_len);
+ FREE(sa, M_SONAME);
+ }
+
+sendit: /* Forward data with optional peer sockaddr as meta info */
+ NG_SEND_DATA(error, priv->hook, m, meta);
+ }
/*
* If the peer has closed the connection, forward a 0-length mbuf
diff --git a/sys/netgraph/ng_ksocket.h b/sys/netgraph/ng_ksocket.h
index efb65aa..6caf752 100644
--- a/sys/netgraph/ng_ksocket.h
+++ b/sys/netgraph/ng_ksocket.h
@@ -98,4 +98,7 @@ enum {
NGM_KSOCKET_GETOPT,
};
+/* Meta information ID's */
+#define NG_KSOCKET_META_SOCKADDR 1 /* data is struct sockaddr */
+
#endif /* _NETGRAPH_KSOCKET_H_ */
OpenPOWER on IntegriCloud