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