1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department. 9 * 10 * %sccs.include.redist.c% 11 * 12 * from: Utah $Hdr: hpux_net.c 1.33 89/08/23$ 13 * 14 * @(#)hpux_net.c 7.7 (Berkeley) 02/13/91 15 */ 16 17 /* 18 * Network related HP-UX compatibility routines 19 */ 20 21 #ifdef HPUXCOMPAT 22 23 #include "sys/param.h" 24 #include "sys/systm.h" 25 #include "sys/kernel.h" 26 #include "sys/time.h" 27 #include "sys/errno.h" 28 #include "sys/proc.h" 29 #include "sys/file.h" 30 #include "sys/mbuf.h" 31 #include "sys/socket.h" 32 #include "sys/socketvar.h" 33 #include "sys/uio.h" 34 #include "sys/ktrace.h" 35 #include "hpux.h" 36 37 #define MINBSDIPCCODE 0x3EE 38 #define NUMBSDIPC 32 39 40 /* 41 * HPUX netioctl() to BSD syscall map. 42 * Indexed by callno - MINBSDIPCCODE 43 */ 44 extern int socket(), listen(), bind(), oaccept(), connect(), orecv(); 45 extern int osend(), shutdown(), ogetsockname(), sendto(); 46 extern int orecvfrom(), ogetpeername(); 47 int hpuxgetsockopt(), hpuxsetsockopt(); 48 49 struct hpuxtobsdipc { 50 int (*rout)(); 51 int nargs; 52 } hpuxtobsdipc[NUMBSDIPC] = { 53 socket, 3, /* 3ee */ listen, 2, /* 3ef */ 54 bind, 3, /* 3f0 */ oaccept, 3, /* 3f1 */ 55 connect, 3, /* 3f2 */ orecv, 4, /* 3f3 */ 56 osend, 4, /* 3f4 */ shutdown, 2, /* 3f5 */ 57 ogetsockname, 3, /* 3f6 */ hpuxsetsockopt, 5, /* 3f7 */ 58 sendto, 6, /* 3f8 */ orecvfrom, 6, /* 3f9 */ 59 ogetpeername, 3, /* 3fa */ NULL, 0, /* 3fb */ 60 NULL, 0, /* 3fc */ NULL, 0, /* 3fd */ 61 NULL, 0, /* 3fe */ NULL, 0, /* 3ff */ 62 NULL, 0, /* 400 */ NULL, 0, /* 401 */ 63 NULL, 0, /* 402 */ NULL, 0, /* 403 */ 64 NULL, 0, /* 404 */ NULL, 0, /* 405 */ 65 NULL, 0, /* 406 */ NULL, 0, /* 407 */ 66 NULL, 0, /* 408 */ NULL, 0, /* 409 */ 67 NULL, 0, /* 40a */ hpuxgetsockopt, 5, /* 40b */ 68 NULL, 0, /* 40c */ NULL, 0, /* 40d */ 69 }; 70 71 /* 72 * Single system call entry to BSD style IPC. 73 * Gleened from disassembled libbsdipc.a syscall entries. 74 */ 75 hpuxnetioctl(p, uap, retval) 76 struct proc *p; 77 struct args { 78 int call; 79 int *args; 80 } *uap; 81 int *retval; 82 { 83 int *args, i; 84 register int code; 85 int error; 86 87 args = uap->args; 88 code = uap->call - MINBSDIPCCODE; 89 if (code < 0 || code >= NUMBSDIPC || hpuxtobsdipc[code].rout == NULL) 90 return (EINVAL); 91 if ((i = hpuxtobsdipc[code].nargs * sizeof (int)) && 92 (error = copyin((caddr_t)args, (caddr_t)uap, (u_int)i))) { 93 #ifdef KTRACE 94 if (KTRPOINT(p, KTR_SYSCALL)) 95 ktrsyscall(p->p_tracep, code + MINBSDIPCCODE, 96 hpuxtobsdipc[code].nargs); 97 #endif 98 return (error); 99 } 100 #ifdef KTRACE 101 if (KTRPOINT(p, KTR_SYSCALL)) 102 ktrsyscall(p->p_tracep, code + MINBSDIPCCODE, 103 hpuxtobsdipc[code].nargs); 104 #endif 105 return ((*hpuxtobsdipc[code].rout)(p, uap, retval)); 106 } 107 108 hpuxsetsockopt(p, uap, retval) 109 struct proc *p; 110 struct args { 111 int s; 112 int level; 113 int name; 114 caddr_t val; 115 int valsize; 116 } *uap; 117 int *retval; 118 { 119 struct file *fp; 120 struct mbuf *m = NULL; 121 int tmp, error; 122 123 if (error = getsock(p->p_fd, uap->s, &fp)) 124 return (error); 125 if (uap->valsize > MLEN) 126 return (EINVAL); 127 if (uap->val) { 128 m = m_get(M_WAIT, MT_SOOPTS); 129 if (m == NULL) 130 return (ENOBUFS); 131 if (error = copyin(uap->val, mtod(m, caddr_t), 132 (u_int)uap->valsize)) { 133 (void) m_free(m); 134 return (error); 135 } 136 if (uap->name == SO_LINGER) { 137 tmp = *mtod(m, int *); 138 mtod(m, struct linger *)->l_onoff = 1; 139 mtod(m, struct linger *)->l_linger = tmp; 140 m->m_len = sizeof(struct linger); 141 } else 142 m->m_len = uap->valsize; 143 } else if (uap->name == ~SO_LINGER) { 144 m = m_get(M_WAIT, MT_SOOPTS); 145 if (m) { 146 uap->name = SO_LINGER; 147 mtod(m, struct linger *)->l_onoff = 0; 148 m->m_len = sizeof(struct linger); 149 } 150 } 151 return (sosetopt((struct socket *)fp->f_data, uap->level, 152 uap->name, m)); 153 } 154 155 hpuxgetsockopt(p, uap, retval) 156 struct proc *p; 157 struct args { 158 int s; 159 int level; 160 int name; 161 caddr_t val; 162 int *avalsize; 163 } *uap; 164 int *retval; 165 { 166 struct file *fp; 167 struct mbuf *m = NULL; 168 int valsize, error; 169 170 if (error = getsock(p->p_fd, uap->s, &fp)) 171 return (error); 172 if (uap->val) { 173 if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize, 174 sizeof (valsize))) 175 return (error); 176 } else 177 valsize = 0; 178 if (error = sogetopt((struct socket *)fp->f_data, uap->level, 179 uap->name, &m)) 180 goto bad; 181 if (uap->val && valsize && m != NULL) { 182 if (uap->name == SO_LINGER) { 183 if (mtod(m, struct linger *)->l_onoff) 184 *mtod(m, int *) = mtod(m, struct linger *)->l_linger; 185 else 186 *mtod(m, int *) = 0; 187 m->m_len = sizeof(int); 188 } 189 if (valsize > m->m_len) 190 valsize = m->m_len; 191 error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize); 192 if (error == 0) 193 error = copyout((caddr_t)&valsize, 194 (caddr_t)uap->avalsize, sizeof (valsize)); 195 } 196 bad: 197 if (m != NULL) 198 (void) m_free(m); 199 return (error); 200 } 201 #endif 202