/*
- * Copyright (c) 1997-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 1997-2008, 2012 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/ioctl.h>
+#include <sys/sysctl.h>
#include <sys/errno.h>
#include <sys/syslog.h>
#include <sys/proc.h>
#include <machine/spl.h>
+static unsigned int ndrv_multi_max_count = NDRV_DMUX_MAX_DESCR;
+SYSCTL_UINT(_net, OID_AUTO, ndrv_multi_max_count, CTLFLAG_RW | CTLFLAG_LOCKED,
+ &ndrv_multi_max_count, 0, "Number of allowed multicast addresses per NRDV socket");
+
static int ndrv_do_detach(struct ndrv_cb *);
static int ndrv_do_disconnect(struct ndrv_cb *);
static struct ndrv_cb *ndrv_find_inbound(struct ifnet *ifp, u_int32_t protocol_family);
extern struct domain ndrvdomain;
extern struct protosw ndrvsw;
-extern lck_mtx_t *domain_proto_mtx;
#define NDRV_PROTODEMUX_COUNT 10
}
/* Hackery - return a string version of a decimal number */
-static char *
+static void
sprint_d(u_int n, char *buf, int buflen)
{ char dbuf[IFNAMSIZ];
char *cp = dbuf+IFNAMSIZ-1;
n /= 10;
} while (n != 0 && buflen > 0);
strncpy(buf, cp, IFNAMSIZ-buflen);
- return (cp);
+ return;
}
/*
len = strlen(ifnet_name(ifp));
strncpy(r, ifnet_name(ifp), IFNAMSIZ);
r += len;
- (void)sprint_d(ifnet_unit(ifp), r, IFNAMSIZ-(r-buf));
+ sprint_d(ifnet_unit(ifp), r, IFNAMSIZ-(r-buf));
#if NDRV_DEBUG
kprintf("Comparing %s, %s\n", buf, q);
#endif
int result;
if (sopt->sopt_val == 0 || sopt->sopt_valsize < 2 ||
- sopt->sopt_level != SOL_NDRVPROTO)
+ sopt->sopt_level != SOL_NDRVPROTO || sopt->sopt_valsize > SOCK_MAXADDRLEN)
return EINVAL;
if (np->nd_if == NULL)
return ENXIO;
+ if (!(np->nd_dlist_cnt < ndrv_multi_max_count))
+ return EPERM;
// Allocate storage
MALLOC(ndrv_multi, struct ndrv_multiaddr*, sizeof(struct ndrv_multiaddr) -
// Add to our linked list
ndrv_multi->next = np->nd_multiaddrs;
np->nd_multiaddrs = ndrv_multi;
+ np->nd_dlist_cnt++;
}
else
{
if (sopt->sopt_val == 0 || sopt->sopt_valsize < 2 ||
sopt->sopt_level != SOL_NDRVPROTO)
return EINVAL;
- if (np->nd_if == NULL)
+ if (np->nd_if == NULL || np->nd_dlist_cnt == 0)
return ENXIO;
// Allocate storage
}
}
+ np->nd_dlist_cnt--;
+
// Free the memory
FREE(ndrv_entry, M_IFADDR);
}