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*56506Sbostic * @(#)hpux_net.c 7.8 (Berkeley) 10/11/92 1541486Smckusick */ 1641486Smckusick 1741486Smckusick /* 1841486Smckusick * Network related HP-UX compatibility routines 1941486Smckusick */ 2041486Smckusick 2141486Smckusick #ifdef HPUXCOMPAT 2241486Smckusick 23*56506Sbostic #include <sys/param.h> 24*56506Sbostic #include <sys/systm.h> 25*56506Sbostic #include <sys/kernel.h> 26*56506Sbostic #include <sys/time.h> 27*56506Sbostic #include <sys/errno.h> 28*56506Sbostic #include <sys/proc.h> 29*56506Sbostic #include <sys/file.h> 30*56506Sbostic #include <sys/mbuf.h> 31*56506Sbostic #include <sys/socket.h> 32*56506Sbostic #include <sys/socketvar.h> 33*56506Sbostic #include <sys/uio.h> 34*56506Sbostic #include <sys/ktrace.h> 3541486Smckusick 36*56506Sbostic #include <hp/hpux/hpux.h> 37*56506Sbostic 3841486Smckusick #define MINBSDIPCCODE 0x3EE 3941486Smckusick #define NUMBSDIPC 32 4041486Smckusick 4141486Smckusick /* 4241486Smckusick * HPUX netioctl() to BSD syscall map. 4341486Smckusick * Indexed by callno - MINBSDIPCCODE 4441486Smckusick */ 4545054Skarels extern int socket(), listen(), bind(), oaccept(), connect(), orecv(); 4645054Skarels extern int osend(), shutdown(), ogetsockname(), sendto(); 4745054Skarels extern int orecvfrom(), ogetpeername(); 4841486Smckusick int hpuxgetsockopt(), hpuxsetsockopt(); 4941486Smckusick 5041486Smckusick struct hpuxtobsdipc { 5141486Smckusick int (*rout)(); 5241486Smckusick int nargs; 5341486Smckusick } hpuxtobsdipc[NUMBSDIPC] = { 5441486Smckusick socket, 3, /* 3ee */ listen, 2, /* 3ef */ 5545054Skarels bind, 3, /* 3f0 */ oaccept, 3, /* 3f1 */ 5641486Smckusick connect, 3, /* 3f2 */ orecv, 4, /* 3f3 */ 5741486Smckusick osend, 4, /* 3f4 */ shutdown, 2, /* 3f5 */ 5845054Skarels ogetsockname, 3, /* 3f6 */ hpuxsetsockopt, 5, /* 3f7 */ 5945054Skarels sendto, 6, /* 3f8 */ orecvfrom, 6, /* 3f9 */ 6045054Skarels ogetpeername, 3, /* 3fa */ NULL, 0, /* 3fb */ 6141486Smckusick NULL, 0, /* 3fc */ NULL, 0, /* 3fd */ 6241486Smckusick NULL, 0, /* 3fe */ NULL, 0, /* 3ff */ 6341486Smckusick NULL, 0, /* 400 */ NULL, 0, /* 401 */ 6441486Smckusick NULL, 0, /* 402 */ NULL, 0, /* 403 */ 6541486Smckusick NULL, 0, /* 404 */ NULL, 0, /* 405 */ 6641486Smckusick NULL, 0, /* 406 */ NULL, 0, /* 407 */ 6741486Smckusick NULL, 0, /* 408 */ NULL, 0, /* 409 */ 6841486Smckusick NULL, 0, /* 40a */ hpuxgetsockopt, 5, /* 40b */ 6941486Smckusick NULL, 0, /* 40c */ NULL, 0, /* 40d */ 7041486Smckusick }; 7141486Smckusick 7241486Smckusick /* 7341486Smckusick * Single system call entry to BSD style IPC. 7441486Smckusick * Gleened from disassembled libbsdipc.a syscall entries. 7541486Smckusick */ 7643453Shibler hpuxnetioctl(p, uap, retval) 7743453Shibler struct proc *p; 7843453Shibler struct args { 7941486Smckusick int call; 8041486Smckusick int *args; 8143453Shibler } *uap; 8243453Shibler int *retval; 8343453Shibler { 8441486Smckusick int *args, i; 8541486Smckusick register int code; 8643453Shibler int error; 8741486Smckusick 8841486Smckusick args = uap->args; 8941486Smckusick code = uap->call - MINBSDIPCCODE; 9043453Shibler if (code < 0 || code >= NUMBSDIPC || hpuxtobsdipc[code].rout == NULL) 9144421Skarels return (EINVAL); 9241486Smckusick if ((i = hpuxtobsdipc[code].nargs * sizeof (int)) && 9343453Shibler (error = copyin((caddr_t)args, (caddr_t)uap, (u_int)i))) { 9441486Smckusick #ifdef KTRACE 9543453Shibler if (KTRPOINT(p, KTR_SYSCALL)) 9643453Shibler ktrsyscall(p->p_tracep, code + MINBSDIPCCODE, 9741486Smckusick hpuxtobsdipc[code].nargs); 9841486Smckusick #endif 9944421Skarels return (error); 10041486Smckusick } 10141486Smckusick #ifdef KTRACE 10243453Shibler if (KTRPOINT(p, KTR_SYSCALL)) 10343453Shibler ktrsyscall(p->p_tracep, code + MINBSDIPCCODE, 10441486Smckusick hpuxtobsdipc[code].nargs); 10541486Smckusick #endif 10644421Skarels return ((*hpuxtobsdipc[code].rout)(p, uap, retval)); 10741486Smckusick } 10841486Smckusick 10943453Shibler hpuxsetsockopt(p, uap, retval) 11043453Shibler struct proc *p; 11143453Shibler struct args { 11241486Smckusick int s; 11341486Smckusick int level; 11441486Smckusick int name; 11541486Smckusick caddr_t val; 11641486Smckusick int valsize; 11743453Shibler } *uap; 11843453Shibler int *retval; 11943453Shibler { 12041486Smckusick struct file *fp; 12141486Smckusick struct mbuf *m = NULL; 12243453Shibler int tmp, error; 12341486Smckusick 12446403Smckusick if (error = getsock(p->p_fd, uap->s, &fp)) 12544421Skarels return (error); 12643453Shibler if (uap->valsize > MLEN) 12744421Skarels return (EINVAL); 12841486Smckusick if (uap->val) { 12941486Smckusick m = m_get(M_WAIT, MT_SOOPTS); 13043453Shibler if (m == NULL) 13144421Skarels return (ENOBUFS); 13243453Shibler if (error = copyin(uap->val, mtod(m, caddr_t), 13343453Shibler (u_int)uap->valsize)) { 13441486Smckusick (void) m_free(m); 13544421Skarels return (error); 13641486Smckusick } 13741486Smckusick if (uap->name == SO_LINGER) { 13841486Smckusick tmp = *mtod(m, int *); 13941486Smckusick mtod(m, struct linger *)->l_onoff = 1; 14041486Smckusick mtod(m, struct linger *)->l_linger = tmp; 14141486Smckusick m->m_len = sizeof(struct linger); 14241486Smckusick } else 14341486Smckusick m->m_len = uap->valsize; 14441486Smckusick } else if (uap->name == ~SO_LINGER) { 14541486Smckusick m = m_get(M_WAIT, MT_SOOPTS); 14641486Smckusick if (m) { 14741486Smckusick uap->name = SO_LINGER; 14841486Smckusick mtod(m, struct linger *)->l_onoff = 0; 14941486Smckusick m->m_len = sizeof(struct linger); 15041486Smckusick } 15141486Smckusick } 15244421Skarels return (sosetopt((struct socket *)fp->f_data, uap->level, 15343453Shibler uap->name, m)); 15441486Smckusick } 15541486Smckusick 15643453Shibler hpuxgetsockopt(p, uap, retval) 15743453Shibler struct proc *p; 15843453Shibler struct args { 15941486Smckusick int s; 16041486Smckusick int level; 16141486Smckusick int name; 16241486Smckusick caddr_t val; 16341486Smckusick int *avalsize; 16443453Shibler } *uap; 16543453Shibler int *retval; 16643453Shibler { 16741486Smckusick struct file *fp; 16841486Smckusick struct mbuf *m = NULL; 16943453Shibler int valsize, error; 17041486Smckusick 17146403Smckusick if (error = getsock(p->p_fd, uap->s, &fp)) 17244421Skarels return (error); 17341486Smckusick if (uap->val) { 17443453Shibler if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize, 17543453Shibler sizeof (valsize))) 17644421Skarels return (error); 17741486Smckusick } else 17841486Smckusick valsize = 0; 17943453Shibler if (error = sogetopt((struct socket *)fp->f_data, uap->level, 18043453Shibler 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; 19243453Shibler error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize); 19343453Shibler if (error == 0) 19443453Shibler error = copyout((caddr_t)&valsize, 19543453Shibler (caddr_t)uap->avalsize, sizeof (valsize)); 19641486Smckusick } 19741486Smckusick bad: 19841486Smckusick if (m != NULL) 19941486Smckusick (void) m_free(m); 20044421Skarels return (error); 20141486Smckusick } 20241486Smckusick #endif 203