/*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 1995 Apple Computer, Inc.
#include <sys/socketvar.h>
#include <sys/ioccom.h>
#include <sys/uio_internal.h>
+#include <sys/file.h>
+#include <sys/vnode.h>
#include <sys/sysctl.h>
#include <netat/at_pcb.h>
#include <netat/at_var.h>
#include <netat/routing_tables.h>
+#include <netat/adsp.h>
+#include <netat/adsp_internal.h>
+#include <netat/asp.h>
+#include <netat/atp.h>
#include <netat/debug.h>
+int _ATkqfilter(struct fileproc *, struct knote *, vfs_context_t);
+int _ATselect(struct fileproc *, int, void *, vfs_context_t);
+int _ATioctl(struct fileproc *, u_long, caddr_t, vfs_context_t);
+int _ATwrite(struct fileproc *, struct uio *, int, vfs_context_t);
+int _ATread(struct fileproc *, struct uio *, int, vfs_context_t);
+int _ATclose(struct fileglob *, vfs_context_t);
+
+int _ATrw(struct fileproc *, enum uio_rw, struct uio *, vfs_context_t);
+
extern struct atpcb ddp_head;
extern lck_mtx_t * atalk_mutex;
-
-extern void
- ddp_putmsg(gref_t *gref, gbuf_t *m),
- elap_wput(gref_t *gref, gbuf_t *m),
- atp_wput(gref_t *gref, gbuf_t *m),
- asp_wput(gref_t *gref, gbuf_t *m),
-#ifdef AURP_SUPPORT
- aurp_wput(gref_t *gref, gbuf_t *m),
-#endif
- adsp_wput(gref_t *gref, gbuf_t *m);
int atp_free_cluster_timeout_set = 0;
+int gref_alloc(gref_t **);
+
-void atalk_putnext(gref_t *gref, gbuf_t *m);
/* bms: make gref_close non static so its callable from kernel */
int gref_close(gref_t *gref);
dbgBits_t dbgBits;
SYSCTL_STRUCT(_net_appletalk, OID_AUTO, debug, CTLFLAG_WR,
&dbgBits, dbgBits, "AppleTalk Debug Flags");
-volatile int RouterMix = RT_MIX_DEFAULT; /* default for nbr of ppsec */
+int RouterMix = RT_MIX_DEFAULT; /* default for nbr of ppsec */
SYSCTL_INT(_net_appletalk, OID_AUTO, routermix, CTLFLAG_WR,
- (int *)&RouterMix, 0, "Appletalk RouterMix");
+ &RouterMix, 0, "Appletalk RouterMix");
at_ddp_stats_t at_ddp_stats; /* DDP statistics */
-SYSCTL_STRUCT(_net_appletalk, OID_AUTO, ddpstats, CTLFLAG_RD,
+SYSCTL_STRUCT(_net_appletalk, OID_AUTO, ddpstats, CTLFLAG_RD | CTLFLAG_LOCKED,
&at_ddp_stats, at_ddp_stats, "AppleTalk DDP Stats");
+extern int atp_resp_seqno2big;
+SYSCTL_INT(_net_appletalk, OID_AUTO, atp_resp_seqno2big, CTLFLAG_RD | CTLFLAG_LOCKED,
+ &atp_resp_seqno2big, 0, "Appletalk ATP seqno too big count");
static void ioccmd_t_32_to_64( ioccmd_t *from_p, user_ioccmd_t *to_p );
static void ioccmd_t_64_to_32( user_ioccmd_t *from_p, ioccmd_t *to_p );
+extern lck_mtx_t *atalk_cluster_lock;
+caddr_t atp_free_cluster_list = NULL;
-caddr_t atp_free_cluster_list = 0;
+void gref_wput(gref_t *, gbuf_t *m);
void gref_wput(gref, m)
gref_t *gref;
case ATPROTO_ATP:
case ATPROTO_ASP:
+#ifdef AURP_SUPPORT
case ATPROTO_AURP:
+#endif
case ATPROTO_ADSP:
break;
default:
return rc;
}
-int _ATclose(fg, proc)
- struct fileglob *fg;
- struct proc *proc;
+int _ATclose(
+ struct fileglob *fg,
+ __unused vfs_context_t ctx)
{
int err;
gref_t *gref;
return err;
}
-int _ATrw(fp, rw, uio, p)
- void *fp;
+int _ATrw(fp, rw, uio, ctx)
+ struct fileproc *fp;
enum uio_rw rw;
struct uio *uio;
- struct proc *p;
+ vfs_context_t ctx;
{
int err, len, clen = 0, res;
gref_t *gref;
gbuf_t *m, *mhead, *mprev;
+ proc_t p = vfs_context_proc(ctx);
/* no need to get/drop iocount as the fp already has one */
if ((err = atalk_getref_locked(fp, 0, &gref, p, 1)) != 0)
return 0;
} /* _ATrw */
-int _ATread(fp, uio, cred, flags, p)
- struct fileproc *fp;
- struct uio *uio;
- void *cred;
- int flags;
- struct proc *p;
+int _ATread(
+ struct fileproc *fp,
+ struct uio *uio,
+ __unused int flags,
+ vfs_context_t ctx)
{
int stat;
atalk_lock();
- stat = _ATrw(fp, UIO_READ, uio, p);
+ stat = _ATrw(fp, UIO_READ, uio, ctx);
atalk_unlock();
return stat;
}
-int _ATwrite(fp, uio, cred, flags, p)
- struct fileproc *fp;
- struct uio *uio;
- void *cred;
- int flags;
- struct proc *p;
+int _ATwrite(
+ struct fileproc *fp,
+ struct uio *uio,
+ __unused int flags,
+ vfs_context_t ctx)
{
- int stat;
+ int stat;
atalk_lock();
- stat = _ATrw(fp, UIO_WRITE, uio, p);
+ stat = _ATrw(fp, UIO_WRITE, uio, ctx);
atalk_unlock();
return stat;
return err;
} /* at_ioctl */
-int _ATioctl(fp, cmd, arg, proc)
- void *fp;
- u_long cmd;
- register caddr_t arg;
- void *proc;
+int _ATioctl(
+ struct fileproc *fp,
+ u_long cmd,
+ register caddr_t arg,
+ __unused vfs_context_t ctx)
{
int err;
gref_t *gref;
return err;
}
-int _ATselect(fp, which, wql, proc)
+int _ATselect(fp, which, wql, ctx)
struct fileproc *fp;
int which;
void * wql;
- struct proc *proc;
+ vfs_context_t ctx;
{
int err, rc = 0;
gref_t *gref;
+ proc_t proc = vfs_context_proc(ctx);
/* Radar 4128949: Drop the proc_fd lock here to avoid lock inversion issues with the other AT calls
* select() is already holding a reference on the fd, so it won't go away during the time it is unlocked.
return rc;
}
-int _ATkqfilter(fp, kn, p)
- struct fileproc *fp;
- struct knote *kn;
- struct proc *p;
+int _ATkqfilter(
+ __unused struct fileproc *fp,
+ __unused struct knote *kn,
+ __unused vfs_context_t ctx)
{
return (EOPNOTSUPP);
}
return rc;
}
+#if 0
static gbuf_t *trace_msg;
-void atalk_settrace(str, p1, p2, p3, p4, p5)
- char *str;
+void atalk_settrace(char * str, p1, p2, p3, p4, p5)
{
int len;
gbuf_t *m, *nextm;
trace_msg = 0;
}
}
+#endif /* 0 */
#define GREF_PER_BLK 32
static gref_t *gref_free_list = 0;
+extern gbuf_t *atp_resource_m;
int gref_alloc(grefp)
gref_t **grefp;
{
- extern gbuf_t *atp_resource_m;
int i;
gbuf_t *m;
gref_t *gref, *gref_array;
return rc;
}
\f
-/*
- Buffer Routines
-
- *** Some to be replaced with mbuf routines, some to be re-written
- as mbuf routines (and moved to kern/uicp_mbuf.c or sys/mbuf.h?).
- ***
-
-*/
-
-/*
- * LD 5/12/97 Added for MacOSX, defines a m_clattach function that:
- * "Allocates an mbuf structure and attaches an external cluster."
- */
-
-struct mbuf *m_clattach(extbuf, extfree, extsize, extarg, wait)
- caddr_t extbuf;
- void (*extfree)(caddr_t , u_int, caddr_t);
- u_int extsize;
- caddr_t extarg;
- int wait;
-{
- struct mbuf *m;
-
- if ((m = m_gethdr(wait, MSG_DATA)) == NULL)
- return (NULL);
-
- m->m_ext.ext_buf = extbuf;
- m->m_ext.ext_free = extfree;
- m->m_ext.ext_size = extsize;
- m->m_ext.ext_arg = extarg;
- m->m_ext.ext_refs.forward =
- m->m_ext.ext_refs.backward = &m->m_ext.ext_refs;
- m->m_data = extbuf;
- m->m_flags |= M_EXT;
-
- return (m);
-}
-
-
-
/*
temp fix for bug 2731148 - until this code is re-written to use standard clusters
Deletes any free clusters on the free list.
*/
-void atp_delete_free_clusters()
+void atp_delete_free_clusters(__unused void *junk)
{
caddr_t cluster;
caddr_t cluster_list;
-
-
+
/* check for free clusters on the free_cluster_list to be deleted */
- MBUF_LOCK(); /* lock used by mbuf routines */
- untimeout(&atp_delete_free_clusters, NULL);
- atp_free_cluster_timeout_set = 0;
+ untimeout(&atp_delete_free_clusters, NULL);
- cluster_list = atp_free_cluster_list;
- atp_free_cluster_list = 0;
-
- MBUF_UNLOCK();
-
- while (cluster = cluster_list)
+ lck_mtx_lock(atalk_cluster_lock);
+
+ atp_free_cluster_timeout_set = 0;
+
+ cluster_list = atp_free_cluster_list;
+ atp_free_cluster_list = NULL;
+
+ lck_mtx_unlock(atalk_cluster_lock);
+
+ while ((cluster = cluster_list))
{
cluster_list = *((caddr_t*)cluster);
FREE(cluster, M_MCLUST);
}
-
}
/*
Used as the "free" routine for over-size clusters allocated using
- m_lgbuf_alloc(). Called by m_free while under MBUF_LOCK.
+ m_lgbuf_alloc().
*/
-void m_lgbuf_free(buf, size, arg)
- caddr_t buf;
- u_int size;
- caddr_t arg; /* not needed, but they're in m_free() */
+void m_lgbuf_free(caddr_t, u_int, caddr_t);
+
+void m_lgbuf_free(
+ caddr_t buf,
+ __unused u_int size,
+ __unused caddr_t arg) /* not needed, but they're in m_free() */
{
- /* FREE(buf, M_MCLUST); - can't free here - called from m_free while under lock */
-
+ int t;
+
/* move to free_cluster_list to be deleted later */
caddr_t cluster = (caddr_t)buf;
-
- /* don't need a lock because this is only called called from m_free which */
- /* is under MBUF_LOCK */
+
+ lck_mtx_lock(atalk_cluster_lock);
+
*((caddr_t*)cluster) = atp_free_cluster_list;
atp_free_cluster_list = cluster;
-
- if (atp_free_cluster_timeout_set == 0)
- {
+
+ if ((t = atp_free_cluster_timeout_set) == 0)
atp_free_cluster_timeout_set = 1;
+
+ lck_mtx_unlock(atalk_cluster_lock);
+
+ if (t == 0)
timeout(&atp_delete_free_clusters, NULL, (1 * HZ));
- }
}
/*
struct mbuf *m;
if (atp_free_cluster_list)
- atp_delete_free_clusters(); /* delete any free clusters on the free list */
-
+ atp_delete_free_clusters(NULL); /* delete any free clusters on the free list */
+
+ /* Radar 5398094
+ * check that the passed size is within admissible boundaries
+ * The max data size being ASP of 4576 (8 * ATP_DATA_SIZE),
+ * allow for extra space for control data
+ */
+
+ if (size < 0 || size > (ATP_DATA_SIZE * 10))
+ return(NULL);
+
/* If size is too large, allocate a cluster, otherwise, use the
standard mbuf allocation routines.*/
if (size > MCLBYTES) {
return(NULL);
}
if (NULL ==
- (m = m_clattach(buf, m_lgbuf_free, size, 0,
+ (m = m_clattach(NULL, MSG_DATA, buf, m_lgbuf_free, size, 0,
(wait)? M_WAIT: M_DONTWAIT))) {
m_lgbuf_free(buf, 0, 0);
return(NULL);
}
} else {
m = m_gethdr(((wait)? M_WAIT: M_DONTWAIT), MSG_DATA);
- if (m && (size > MHLEN)) {
+ if (m && ((size_t)size > MHLEN)) {
MCLGET(m, ((wait)? M_WAIT: M_DONTWAIT));
if (!(m->m_flags & M_EXT)) {
(void)m_free(m);
/* Standard mbuf allocation routines assume that the caller
will set the size. */
if (m) {
- (struct mbuf *)m->m_pkthdr.len = size;
- (struct mbuf *)m->m_len = size;
+ m->m_pkthdr.len = size;
+ m->m_len = size;
}
return(m);
len -= buf_len;
goto l_cont;
- } else
- return 1;
+ }
+
+ return 1;
}
/*