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.2 (Berkeley) 06/22/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 "syscontext.h" 26 #include "kernel.h" 27 #include "proc.h" 28 #include "file.h" 29 #include "mbuf.h" 30 #include "socket.h" 31 #include "socketvar.h" 32 #include "ktrace.h" 33 #include "hpux.h" 34 35 #define MINBSDIPCCODE 0x3EE 36 #define NUMBSDIPC 32 37 38 /* 39 * HPUX netioctl() to BSD syscall map. 40 * Indexed by callno - MINBSDIPCCODE 41 */ 42 extern int socket(), listen(), bind(), accept(), connect(), orecv(); 43 extern int osend(), shutdown(), getsockname(), sendto(); 44 extern int recvfrom(), getpeername(); 45 int hpuxgetsockopt(), hpuxsetsockopt(); 46 struct file *getsock(); 47 48 struct hpuxtobsdipc { 49 int (*rout)(); 50 int nargs; 51 } hpuxtobsdipc[NUMBSDIPC] = { 52 socket, 3, /* 3ee */ listen, 2, /* 3ef */ 53 bind, 3, /* 3f0 */ accept, 3, /* 3f1 */ 54 connect, 3, /* 3f2 */ orecv, 4, /* 3f3 */ 55 osend, 4, /* 3f4 */ shutdown, 2, /* 3f5 */ 56 getsockname, 3, /* 3f6 */ hpuxsetsockopt, 5, /* 3f7 */ 57 sendto, 6, /* 3f8 */ recvfrom, 6, /* 3f9 */ 58 getpeername, 3, /* 3fa */ NULL, 0, /* 3fb */ 59 NULL, 0, /* 3fc */ NULL, 0, /* 3fd */ 60 NULL, 0, /* 3fe */ NULL, 0, /* 3ff */ 61 NULL, 0, /* 400 */ NULL, 0, /* 401 */ 62 NULL, 0, /* 402 */ NULL, 0, /* 403 */ 63 NULL, 0, /* 404 */ NULL, 0, /* 405 */ 64 NULL, 0, /* 406 */ NULL, 0, /* 407 */ 65 NULL, 0, /* 408 */ NULL, 0, /* 409 */ 66 NULL, 0, /* 40a */ hpuxgetsockopt, 5, /* 40b */ 67 NULL, 0, /* 40c */ NULL, 0, /* 40d */ 68 }; 69 70 /* 71 * Single system call entry to BSD style IPC. 72 * Gleened from disassembled libbsdipc.a syscall entries. 73 */ 74 hpuxnetioctl(p, uap, retval) 75 struct proc *p; 76 struct args { 77 int call; 78 int *args; 79 } *uap; 80 int *retval; 81 { 82 int *args, i; 83 register int code; 84 int error; 85 86 args = uap->args; 87 code = uap->call - MINBSDIPCCODE; 88 if (code < 0 || code >= NUMBSDIPC || hpuxtobsdipc[code].rout == NULL) 89 RETURN (EINVAL); 90 if ((i = hpuxtobsdipc[code].nargs * sizeof (int)) && 91 (error = copyin((caddr_t)args, (caddr_t)uap, (u_int)i))) { 92 #ifdef KTRACE 93 if (KTRPOINT(p, KTR_SYSCALL)) 94 ktrsyscall(p->p_tracep, code + MINBSDIPCCODE, 95 hpuxtobsdipc[code].nargs); 96 #endif 97 RETURN (error); 98 } 99 #ifdef KTRACE 100 if (KTRPOINT(p, KTR_SYSCALL)) 101 ktrsyscall(p->p_tracep, code + MINBSDIPCCODE, 102 hpuxtobsdipc[code].nargs); 103 #endif 104 RETURN ((*hpuxtobsdipc[code].rout)(p, uap, retval)); 105 } 106 107 hpuxsetsockopt(p, uap, retval) 108 struct proc *p; 109 struct args { 110 int s; 111 int level; 112 int name; 113 caddr_t val; 114 int valsize; 115 } *uap; 116 int *retval; 117 { 118 struct file *fp; 119 struct mbuf *m = NULL; 120 int tmp, error; 121 122 fp = getsock(uap->s, &error); 123 if (fp == 0) 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 fp = getsock(uap->s, &error); 171 if (fp == 0) 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