141486Smckusick /* 241486Smckusick * Copyright (c) 1988 University of Utah. 341486Smckusick * Copyright (c) 1990 The Regents of the University of California. 441486Smckusick * All rights reserved. 541486Smckusick * 641486Smckusick * This code is derived from software contributed to Berkeley by 741486Smckusick * the Systems Programming Group of the University of Utah Computer 841486Smckusick * Science Department. 941486Smckusick * 1041486Smckusick * %sccs.include.redist.c% 1141486Smckusick * 1241486Smckusick * from: Utah $Hdr: hpux_net.c 1.33 89/08/23$ 1341486Smckusick * 14*43453Shibler * @(#)hpux_net.c 7.2 (Berkeley) 06/22/90 1541486Smckusick */ 1641486Smckusick 1741486Smckusick /* 1841486Smckusick * Network related HP-UX compatibility routines 1941486Smckusick */ 2041486Smckusick 2141486Smckusick #ifdef HPUXCOMPAT 2241486Smckusick 2341486Smckusick #include "param.h" 2441486Smckusick #include "systm.h" 25*43453Shibler #include "syscontext.h" 2641486Smckusick #include "kernel.h" 2741486Smckusick #include "proc.h" 2841486Smckusick #include "file.h" 2941486Smckusick #include "mbuf.h" 3041486Smckusick #include "socket.h" 3141486Smckusick #include "socketvar.h" 3241486Smckusick #include "ktrace.h" 3341486Smckusick #include "hpux.h" 3441486Smckusick 3541486Smckusick #define MINBSDIPCCODE 0x3EE 3641486Smckusick #define NUMBSDIPC 32 3741486Smckusick 3841486Smckusick /* 3941486Smckusick * HPUX netioctl() to BSD syscall map. 4041486Smckusick * Indexed by callno - MINBSDIPCCODE 4141486Smckusick */ 4241486Smckusick extern int socket(), listen(), bind(), accept(), connect(), orecv(); 4341486Smckusick extern int osend(), shutdown(), getsockname(), sendto(); 4441486Smckusick extern int recvfrom(), getpeername(); 4541486Smckusick int hpuxgetsockopt(), hpuxsetsockopt(); 4641486Smckusick struct file *getsock(); 4741486Smckusick 4841486Smckusick struct hpuxtobsdipc { 4941486Smckusick int (*rout)(); 5041486Smckusick int nargs; 5141486Smckusick } hpuxtobsdipc[NUMBSDIPC] = { 5241486Smckusick socket, 3, /* 3ee */ listen, 2, /* 3ef */ 5341486Smckusick bind, 3, /* 3f0 */ accept, 3, /* 3f1 */ 5441486Smckusick connect, 3, /* 3f2 */ orecv, 4, /* 3f3 */ 5541486Smckusick osend, 4, /* 3f4 */ shutdown, 2, /* 3f5 */ 5641486Smckusick getsockname, 3, /* 3f6 */ hpuxsetsockopt, 5, /* 3f7 */ 5741486Smckusick sendto, 6, /* 3f8 */ recvfrom, 6, /* 3f9 */ 5841486Smckusick getpeername, 3, /* 3fa */ NULL, 0, /* 3fb */ 5941486Smckusick NULL, 0, /* 3fc */ NULL, 0, /* 3fd */ 6041486Smckusick NULL, 0, /* 3fe */ NULL, 0, /* 3ff */ 6141486Smckusick NULL, 0, /* 400 */ NULL, 0, /* 401 */ 6241486Smckusick NULL, 0, /* 402 */ NULL, 0, /* 403 */ 6341486Smckusick NULL, 0, /* 404 */ NULL, 0, /* 405 */ 6441486Smckusick NULL, 0, /* 406 */ NULL, 0, /* 407 */ 6541486Smckusick NULL, 0, /* 408 */ NULL, 0, /* 409 */ 6641486Smckusick NULL, 0, /* 40a */ hpuxgetsockopt, 5, /* 40b */ 6741486Smckusick NULL, 0, /* 40c */ NULL, 0, /* 40d */ 6841486Smckusick }; 6941486Smckusick 7041486Smckusick /* 7141486Smckusick * Single system call entry to BSD style IPC. 7241486Smckusick * Gleened from disassembled libbsdipc.a syscall entries. 7341486Smckusick */ 74*43453Shibler hpuxnetioctl(p, uap, retval) 75*43453Shibler struct proc *p; 76*43453Shibler struct args { 7741486Smckusick int call; 7841486Smckusick int *args; 79*43453Shibler } *uap; 80*43453Shibler int *retval; 81*43453Shibler { 8241486Smckusick int *args, i; 8341486Smckusick register int code; 84*43453Shibler int error; 8541486Smckusick 8641486Smckusick args = uap->args; 8741486Smckusick code = uap->call - MINBSDIPCCODE; 88*43453Shibler if (code < 0 || code >= NUMBSDIPC || hpuxtobsdipc[code].rout == NULL) 89*43453Shibler RETURN (EINVAL); 9041486Smckusick if ((i = hpuxtobsdipc[code].nargs * sizeof (int)) && 91*43453Shibler (error = copyin((caddr_t)args, (caddr_t)uap, (u_int)i))) { 9241486Smckusick #ifdef KTRACE 93*43453Shibler if (KTRPOINT(p, KTR_SYSCALL)) 94*43453Shibler ktrsyscall(p->p_tracep, code + MINBSDIPCCODE, 9541486Smckusick hpuxtobsdipc[code].nargs); 9641486Smckusick #endif 97*43453Shibler RETURN (error); 9841486Smckusick } 9941486Smckusick #ifdef KTRACE 100*43453Shibler if (KTRPOINT(p, KTR_SYSCALL)) 101*43453Shibler ktrsyscall(p->p_tracep, code + MINBSDIPCCODE, 10241486Smckusick hpuxtobsdipc[code].nargs); 10341486Smckusick #endif 104*43453Shibler RETURN ((*hpuxtobsdipc[code].rout)(p, uap, retval)); 10541486Smckusick } 10641486Smckusick 107*43453Shibler hpuxsetsockopt(p, uap, retval) 108*43453Shibler struct proc *p; 109*43453Shibler struct args { 11041486Smckusick int s; 11141486Smckusick int level; 11241486Smckusick int name; 11341486Smckusick caddr_t val; 11441486Smckusick int valsize; 115*43453Shibler } *uap; 116*43453Shibler int *retval; 117*43453Shibler { 11841486Smckusick struct file *fp; 11941486Smckusick struct mbuf *m = NULL; 120*43453Shibler int tmp, error; 12141486Smckusick 122*43453Shibler fp = getsock(uap->s, &error); 12341486Smckusick if (fp == 0) 124*43453Shibler RETURN (error); 125*43453Shibler if (uap->valsize > MLEN) 126*43453Shibler RETURN (EINVAL); 12741486Smckusick if (uap->val) { 12841486Smckusick m = m_get(M_WAIT, MT_SOOPTS); 129*43453Shibler if (m == NULL) 130*43453Shibler RETURN (ENOBUFS); 131*43453Shibler if (error = copyin(uap->val, mtod(m, caddr_t), 132*43453Shibler (u_int)uap->valsize)) { 13341486Smckusick (void) m_free(m); 134*43453Shibler RETURN (error); 13541486Smckusick } 13641486Smckusick if (uap->name == SO_LINGER) { 13741486Smckusick tmp = *mtod(m, int *); 13841486Smckusick mtod(m, struct linger *)->l_onoff = 1; 13941486Smckusick mtod(m, struct linger *)->l_linger = tmp; 14041486Smckusick m->m_len = sizeof(struct linger); 14141486Smckusick } else 14241486Smckusick m->m_len = uap->valsize; 14341486Smckusick } else if (uap->name == ~SO_LINGER) { 14441486Smckusick m = m_get(M_WAIT, MT_SOOPTS); 14541486Smckusick if (m) { 14641486Smckusick uap->name = SO_LINGER; 14741486Smckusick mtod(m, struct linger *)->l_onoff = 0; 14841486Smckusick m->m_len = sizeof(struct linger); 14941486Smckusick } 15041486Smckusick } 151*43453Shibler RETURN (sosetopt((struct socket *)fp->f_data, uap->level, 152*43453Shibler uap->name, m)); 15341486Smckusick } 15441486Smckusick 155*43453Shibler hpuxgetsockopt(p, uap, retval) 156*43453Shibler struct proc *p; 157*43453Shibler struct args { 15841486Smckusick int s; 15941486Smckusick int level; 16041486Smckusick int name; 16141486Smckusick caddr_t val; 16241486Smckusick int *avalsize; 163*43453Shibler } *uap; 164*43453Shibler int *retval; 165*43453Shibler { 16641486Smckusick struct file *fp; 16741486Smckusick struct mbuf *m = NULL; 168*43453Shibler int valsize, error; 16941486Smckusick 170*43453Shibler fp = getsock(uap->s, &error); 17141486Smckusick if (fp == 0) 172*43453Shibler RETURN (error); 17341486Smckusick if (uap->val) { 174*43453Shibler if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize, 175*43453Shibler sizeof (valsize))) 176*43453Shibler RETURN (error); 17741486Smckusick } else 17841486Smckusick valsize = 0; 179*43453Shibler if (error = sogetopt((struct socket *)fp->f_data, uap->level, 180*43453Shibler uap->name, &m)) 18141486Smckusick goto bad; 18241486Smckusick if (uap->val && valsize && m != NULL) { 18341486Smckusick if (uap->name == SO_LINGER) { 18441486Smckusick if (mtod(m, struct linger *)->l_onoff) 18541486Smckusick *mtod(m, int *) = mtod(m, struct linger *)->l_linger; 18641486Smckusick else 18741486Smckusick *mtod(m, int *) = 0; 18841486Smckusick m->m_len = sizeof(int); 18941486Smckusick } 19041486Smckusick if (valsize > m->m_len) 19141486Smckusick valsize = m->m_len; 192*43453Shibler error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize); 193*43453Shibler if (error == 0) 194*43453Shibler error = copyout((caddr_t)&valsize, 195*43453Shibler (caddr_t)uap->avalsize, sizeof (valsize)); 19641486Smckusick } 19741486Smckusick bad: 19841486Smckusick if (m != NULL) 19941486Smckusick (void) m_free(m); 200*43453Shibler RETURN (error); 20141486Smckusick } 20241486Smckusick #endif 203