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*46403Smckusick * @(#)hpux_net.c 7.7 (Berkeley) 02/13/91 1541486Smckusick */ 1641486Smckusick 1741486Smckusick /* 1841486Smckusick * Network related HP-UX compatibility routines 1941486Smckusick */ 2041486Smckusick 2141486Smckusick #ifdef HPUXCOMPAT 2241486Smckusick 2345788Sbostic #include "sys/param.h" 2445788Sbostic #include "sys/systm.h" 2545788Sbostic #include "sys/kernel.h" 2645788Sbostic #include "sys/time.h" 2745788Sbostic #include "sys/errno.h" 2845788Sbostic #include "sys/proc.h" 2945788Sbostic #include "sys/file.h" 3045788Sbostic #include "sys/mbuf.h" 3145788Sbostic #include "sys/socket.h" 3245788Sbostic #include "sys/socketvar.h" 3345788Sbostic #include "sys/uio.h" 3445788Sbostic #include "sys/ktrace.h" 3545816Smckusick #include "hpux.h" 3641486Smckusick 3741486Smckusick #define MINBSDIPCCODE 0x3EE 3841486Smckusick #define NUMBSDIPC 32 3941486Smckusick 4041486Smckusick /* 4141486Smckusick * HPUX netioctl() to BSD syscall map. 4241486Smckusick * Indexed by callno - MINBSDIPCCODE 4341486Smckusick */ 4445054Skarels extern int socket(), listen(), bind(), oaccept(), connect(), orecv(); 4545054Skarels extern int osend(), shutdown(), ogetsockname(), sendto(); 4645054Skarels extern int orecvfrom(), ogetpeername(); 4741486Smckusick int hpuxgetsockopt(), hpuxsetsockopt(); 4841486Smckusick 4941486Smckusick struct hpuxtobsdipc { 5041486Smckusick int (*rout)(); 5141486Smckusick int nargs; 5241486Smckusick } hpuxtobsdipc[NUMBSDIPC] = { 5341486Smckusick socket, 3, /* 3ee */ listen, 2, /* 3ef */ 5445054Skarels bind, 3, /* 3f0 */ oaccept, 3, /* 3f1 */ 5541486Smckusick connect, 3, /* 3f2 */ orecv, 4, /* 3f3 */ 5641486Smckusick osend, 4, /* 3f4 */ shutdown, 2, /* 3f5 */ 5745054Skarels ogetsockname, 3, /* 3f6 */ hpuxsetsockopt, 5, /* 3f7 */ 5845054Skarels sendto, 6, /* 3f8 */ orecvfrom, 6, /* 3f9 */ 5945054Skarels ogetpeername, 3, /* 3fa */ NULL, 0, /* 3fb */ 6041486Smckusick NULL, 0, /* 3fc */ NULL, 0, /* 3fd */ 6141486Smckusick NULL, 0, /* 3fe */ NULL, 0, /* 3ff */ 6241486Smckusick NULL, 0, /* 400 */ NULL, 0, /* 401 */ 6341486Smckusick NULL, 0, /* 402 */ NULL, 0, /* 403 */ 6441486Smckusick NULL, 0, /* 404 */ NULL, 0, /* 405 */ 6541486Smckusick NULL, 0, /* 406 */ NULL, 0, /* 407 */ 6641486Smckusick NULL, 0, /* 408 */ NULL, 0, /* 409 */ 6741486Smckusick NULL, 0, /* 40a */ hpuxgetsockopt, 5, /* 40b */ 6841486Smckusick NULL, 0, /* 40c */ NULL, 0, /* 40d */ 6941486Smckusick }; 7041486Smckusick 7141486Smckusick /* 7241486Smckusick * Single system call entry to BSD style IPC. 7341486Smckusick * Gleened from disassembled libbsdipc.a syscall entries. 7441486Smckusick */ 7543453Shibler hpuxnetioctl(p, uap, retval) 7643453Shibler struct proc *p; 7743453Shibler struct args { 7841486Smckusick int call; 7941486Smckusick int *args; 8043453Shibler } *uap; 8143453Shibler int *retval; 8243453Shibler { 8341486Smckusick int *args, i; 8441486Smckusick register int code; 8543453Shibler int error; 8641486Smckusick 8741486Smckusick args = uap->args; 8841486Smckusick code = uap->call - MINBSDIPCCODE; 8943453Shibler if (code < 0 || code >= NUMBSDIPC || hpuxtobsdipc[code].rout == NULL) 9044421Skarels return (EINVAL); 9141486Smckusick if ((i = hpuxtobsdipc[code].nargs * sizeof (int)) && 9243453Shibler (error = copyin((caddr_t)args, (caddr_t)uap, (u_int)i))) { 9341486Smckusick #ifdef KTRACE 9443453Shibler if (KTRPOINT(p, KTR_SYSCALL)) 9543453Shibler ktrsyscall(p->p_tracep, code + MINBSDIPCCODE, 9641486Smckusick hpuxtobsdipc[code].nargs); 9741486Smckusick #endif 9844421Skarels return (error); 9941486Smckusick } 10041486Smckusick #ifdef KTRACE 10143453Shibler if (KTRPOINT(p, KTR_SYSCALL)) 10243453Shibler ktrsyscall(p->p_tracep, code + MINBSDIPCCODE, 10341486Smckusick hpuxtobsdipc[code].nargs); 10441486Smckusick #endif 10544421Skarels return ((*hpuxtobsdipc[code].rout)(p, uap, retval)); 10641486Smckusick } 10741486Smckusick 10843453Shibler hpuxsetsockopt(p, uap, retval) 10943453Shibler struct proc *p; 11043453Shibler struct args { 11141486Smckusick int s; 11241486Smckusick int level; 11341486Smckusick int name; 11441486Smckusick caddr_t val; 11541486Smckusick int valsize; 11643453Shibler } *uap; 11743453Shibler int *retval; 11843453Shibler { 11941486Smckusick struct file *fp; 12041486Smckusick struct mbuf *m = NULL; 12143453Shibler int tmp, error; 12241486Smckusick 123*46403Smckusick if (error = getsock(p->p_fd, uap->s, &fp)) 12444421Skarels return (error); 12543453Shibler if (uap->valsize > MLEN) 12644421Skarels return (EINVAL); 12741486Smckusick if (uap->val) { 12841486Smckusick m = m_get(M_WAIT, MT_SOOPTS); 12943453Shibler if (m == NULL) 13044421Skarels return (ENOBUFS); 13143453Shibler if (error = copyin(uap->val, mtod(m, caddr_t), 13243453Shibler (u_int)uap->valsize)) { 13341486Smckusick (void) m_free(m); 13444421Skarels 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 } 15144421Skarels return (sosetopt((struct socket *)fp->f_data, uap->level, 15243453Shibler uap->name, m)); 15341486Smckusick } 15441486Smckusick 15543453Shibler hpuxgetsockopt(p, uap, retval) 15643453Shibler struct proc *p; 15743453Shibler struct args { 15841486Smckusick int s; 15941486Smckusick int level; 16041486Smckusick int name; 16141486Smckusick caddr_t val; 16241486Smckusick int *avalsize; 16343453Shibler } *uap; 16443453Shibler int *retval; 16543453Shibler { 16641486Smckusick struct file *fp; 16741486Smckusick struct mbuf *m = NULL; 16843453Shibler int valsize, error; 16941486Smckusick 170*46403Smckusick if (error = getsock(p->p_fd, uap->s, &fp)) 17144421Skarels return (error); 17241486Smckusick if (uap->val) { 17343453Shibler if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize, 17443453Shibler sizeof (valsize))) 17544421Skarels return (error); 17641486Smckusick } else 17741486Smckusick valsize = 0; 17843453Shibler if (error = sogetopt((struct socket *)fp->f_data, uap->level, 17943453Shibler uap->name, &m)) 18041486Smckusick goto bad; 18141486Smckusick if (uap->val && valsize && m != NULL) { 18241486Smckusick if (uap->name == SO_LINGER) { 18341486Smckusick if (mtod(m, struct linger *)->l_onoff) 18441486Smckusick *mtod(m, int *) = mtod(m, struct linger *)->l_linger; 18541486Smckusick else 18641486Smckusick *mtod(m, int *) = 0; 18741486Smckusick m->m_len = sizeof(int); 18841486Smckusick } 18941486Smckusick if (valsize > m->m_len) 19041486Smckusick valsize = m->m_len; 19143453Shibler error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize); 19243453Shibler if (error == 0) 19343453Shibler error = copyout((caddr_t)&valsize, 19443453Shibler (caddr_t)uap->avalsize, sizeof (valsize)); 19541486Smckusick } 19641486Smckusick bad: 19741486Smckusick if (m != NULL) 19841486Smckusick (void) m_free(m); 19944421Skarels return (error); 20041486Smckusick } 20141486Smckusick #endif 202