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.3 (Berkeley) 06/28/90 15 */ 16 17 /* 18 * Network related HP-UX compatibility routines 19 */ 20 21 #ifdef HPUXCOMPAT 22 23 #include "param.h" 24 #include "systm.h" 25 #include "kernel.h" 26 #include "time.h" 27 #include "errno.h" 28 #include "proc.h" 29 #include "file.h" 30 #include "mbuf.h" 31 #include "socket.h" 32 #include "socketvar.h" 33 #include "uio.h" 34 #include "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(), accept(), connect(), orecv(); 45 extern int osend(), shutdown(), getsockname(), sendto(); 46 extern int recvfrom(), getpeername(); 47 int hpuxgetsockopt(), hpuxsetsockopt(); 48 struct file *getsock(); 49 50 struct hpuxtobsdipc { 51 int (*rout)(); 52 int nargs; 53 } hpuxtobsdipc[NUMBSDIPC] = { 54 socket, 3, /* 3ee */ listen, 2, /* 3ef */ 55 bind, 3, /* 3f0 */ accept, 3, /* 3f1 */ 56 connect, 3, /* 3f2 */ orecv, 4, /* 3f3 */ 57 osend, 4, /* 3f4 */ shutdown, 2, /* 3f5 */ 58 getsockname, 3, /* 3f6 */ hpuxsetsockopt, 5, /* 3f7 */ 59 sendto, 6, /* 3f8 */ recvfrom, 6, /* 3f9 */ 60 getpeername, 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 fp = getsock(uap->s, &error); 125 if (fp == 0) 126 return (error); 127 if (uap->valsize > MLEN) 128 return (EINVAL); 129 if (uap->val) { 130 m = m_get(M_WAIT, MT_SOOPTS); 131 if (m == NULL) 132 return (ENOBUFS); 133 if (error = copyin(uap->val, mtod(m, caddr_t), 134 (u_int)uap->valsize)) { 135 (void) m_free(m); 136 return (error); 137 } 138 if (uap->name == SO_LINGER) { 139 tmp = *mtod(m, int *); 140 mtod(m, struct linger *)->l_onoff = 1; 141 mtod(m, struct linger *)->l_linger = tmp; 142 m->m_len = sizeof(struct linger); 143 } else 144 m->m_len = uap->valsize; 145 } else if (uap->name == ~SO_LINGER) { 146 m = m_get(M_WAIT, MT_SOOPTS); 147 if (m) { 148 uap->name = SO_LINGER; 149 mtod(m, struct linger *)->l_onoff = 0; 150 m->m_len = sizeof(struct linger); 151 } 152 } 153 return (sosetopt((struct socket *)fp->f_data, uap->level, 154 uap->name, m)); 155 } 156 157 hpuxgetsockopt(p, uap, retval) 158 struct proc *p; 159 struct args { 160 int s; 161 int level; 162 int name; 163 caddr_t val; 164 int *avalsize; 165 } *uap; 166 int *retval; 167 { 168 struct file *fp; 169 struct mbuf *m = NULL; 170 int valsize, error; 171 172 fp = getsock(uap->s, &error); 173 if (fp == 0) 174 return (error); 175 if (uap->val) { 176 if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize, 177 sizeof (valsize))) 178 return (error); 179 } else 180 valsize = 0; 181 if (error = sogetopt((struct socket *)fp->f_data, uap->level, 182 uap->name, &m)) 183 goto bad; 184 if (uap->val && valsize && m != NULL) { 185 if (uap->name == SO_LINGER) { 186 if (mtod(m, struct linger *)->l_onoff) 187 *mtod(m, int *) = mtod(m, struct linger *)->l_linger; 188 else 189 *mtod(m, int *) = 0; 190 m->m_len = sizeof(int); 191 } 192 if (valsize > m->m_len) 193 valsize = m->m_len; 194 error = copyout(mtod(m, caddr_t), uap->val, (u_int)valsize); 195 if (error == 0) 196 error = copyout((caddr_t)&valsize, 197 (caddr_t)uap->avalsize, sizeof (valsize)); 198 } 199 bad: 200 if (m != NULL) 201 (void) m_free(m); 202 return (error); 203 } 204 #endif 205