linux_socket.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512
  1. /* $OpenBSD: linux_socket.c,v 1.61 2015/05/06 08:52:17 mpi Exp $ */
  2. /* $NetBSD: linux_socket.c,v 1.14 1996/04/05 00:01:50 christos Exp $ */
  3. /*
  4. * Copyright (c) 1995 Frank van der Linden
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. All advertising materials mentioning features or use of this software
  16. * must display the following acknowledgement:
  17. * This product includes software developed for the NetBSD Project
  18. * by Frank van der Linden
  19. * 4. The name of the author may not be used to endorse or promote products
  20. * derived from this software without specific prior written permission
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  23. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  24. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  25. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  27. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  31. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. #include <sys/param.h>
  34. #include <sys/domain.h>
  35. #include <sys/kernel.h>
  36. #include <sys/systm.h>
  37. #include <sys/buf.h>
  38. #include <sys/malloc.h>
  39. #include <sys/ioctl.h>
  40. #include <sys/tty.h>
  41. #include <sys/file.h>
  42. #include <sys/filedesc.h>
  43. #include <sys/mbuf.h>
  44. #include <sys/selinfo.h>
  45. #include <sys/protosw.h>
  46. #include <sys/socket.h>
  47. #include <sys/socketvar.h>
  48. #include <sys/un.h>
  49. #include <net/if.h>
  50. #include <net/if_var.h>
  51. #include <net/if_types.h>
  52. #include <net/if_dl.h>
  53. #include <netinet/in.h>
  54. #include <netinet/ip.h>
  55. #include <netinet/tcp.h>
  56. #include <sys/mount.h>
  57. #include <sys/proc.h>
  58. #include <sys/vnode.h>
  59. #include <sys/device.h>
  60. #include <sys/syscallargs.h>
  61. #include <compat/linux/linux_types.h>
  62. #include <compat/linux/linux_util.h>
  63. #include <compat/linux/linux_signal.h>
  64. #include <compat/linux/linux_syscallargs.h>
  65. #include <compat/linux/linux_ioctl.h>
  66. #include <compat/linux/linux_socket.h>
  67. #include <compat/linux/linux_socketcall.h>
  68. #include <compat/linux/linux_sockio.h>
  69. /*
  70. * All the calls in this file are entered via one common system
  71. * call in Linux, represented here by linux_socketcall().
  72. * Arguments for the various calls are on the user stack. A pointer
  73. * to them is the only thing that is passed. It is up to the various
  74. * calls to copy them in themselves. To make it look better, they
  75. * are copied to structures.
  76. */
  77. static int linux_to_bsd_domain (int);
  78. static int bsd_to_linux_domain(int);
  79. static int linux_to_bsd_msg_flags(int);
  80. int linux_socket(struct proc *, void *, register_t *);
  81. int linux_bind(struct proc *, void *, register_t *);
  82. int linux_connect(struct proc *, void *, register_t *);
  83. int linux_listen(struct proc *, void *, register_t *);
  84. int linux_accept(struct proc *, void *, register_t *);
  85. int linux_getsockname(struct proc *, void *, register_t *);
  86. int linux_getpeername(struct proc *, void *, register_t *);
  87. int linux_socketpair(struct proc *, void *, register_t *);
  88. int linux_send(struct proc *, void *, register_t *);
  89. int linux_recv(struct proc *, void *, register_t *);
  90. int linux_sendto(struct proc *, void *, register_t *);
  91. int linux_recvfrom(struct proc *, void *, register_t *);
  92. int linux_shutdown(struct proc *, void *, register_t *);
  93. int linux_to_bsd_sopt_level(int);
  94. int linux_to_bsd_so_sockopt(int);
  95. int linux_to_bsd_ip_sockopt(int);
  96. int linux_to_bsd_tcp_sockopt(int);
  97. int linux_to_bsd_udp_sockopt(int);
  98. int linux_setsockopt(struct proc *, void *, register_t *);
  99. int linux_getsockopt(struct proc *, void *, register_t *);
  100. int linux_recvmsg(struct proc *, void *, register_t *);
  101. int linux_sendmsg(struct proc *, void *, register_t *);
  102. int linux_check_hdrincl(struct proc *, int, register_t *, caddr_t *);
  103. int linux_sendto_hdrincl(struct proc *, struct sys_sendto_args *,
  104. register_t *, caddr_t *);
  105. int linux_sa_get(struct proc *, caddr_t *, struct sockaddr **,
  106. const struct linux_sockaddr *, int *);
  107. int linux_sa_put(struct sockaddr *);
  108. static const int linux_to_bsd_domain_[LINUX_AF_MAX] = {
  109. AF_UNSPEC,
  110. AF_UNIX,
  111. AF_INET,
  112. -1, /* LINUX_AF_AX25 */
  113. -1, /* IPX */
  114. -1 /* APPLETALK */
  115. -1, /* LINUX_AF_NETROM */
  116. -1, /* LINUX_AF_BRIDGE */
  117. -1, /* LINUX_AF_ATMPVC */
  118. -1, /* LINUX_AF_X25 */
  119. AF_INET6,
  120. -1, /* LINUX_AF_ROSE */
  121. AF_DECnet,
  122. -1, /* LINUX_AF_NETBEUI */
  123. -1, /* LINUX_AF_SECURITY */
  124. -1, /* pseudo_AF_KEY */
  125. AF_ROUTE, /* LINUX_AF_NETLINK */
  126. -1, /* LINUX_AF_PACKET */
  127. -1, /* LINUX_AF_ASH */
  128. -1, /* LINUX_AF_ECONET */
  129. -1, /* LINUX_AF_ATMSVC */
  130. AF_SNA,
  131. /* rest up to LINUX_AF_MAX-1 is not allocated */
  132. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  133. };
  134. static const int bsd_to_linux_domain_[AF_MAX] = {
  135. LINUX_AF_UNSPEC,
  136. LINUX_AF_UNIX,
  137. LINUX_AF_INET,
  138. -1, /* AF_IMPLINK */
  139. -1, /* AF_PUP */
  140. -1, /* AF_CHAOS */
  141. -1, /* AF_NS */
  142. -1, /* AF_ISO */
  143. -1, /* AF_ECMA */
  144. -1, /* AF_DATAKIT */
  145. -1, /* AF_CCITT */
  146. -1, /* LINUX_AF_SNA */
  147. -1, /* LINUX_AF_DECnet */
  148. -1, /* AF_DLI */
  149. -1, /* AF_LAT */
  150. -1, /* AF_HYLINK */
  151. LINUX_AF_APPLETALK,
  152. -1, /* LINUX_AF_NETLINK */
  153. -1, /* AF_LINK */
  154. -1, /* AF_XTP */
  155. -1, /* AF_COIP */
  156. -1, /* AF_CNT */
  157. -1, /* pseudo_AF_RTIP */
  158. LINUX_AF_IPX,
  159. LINUX_AF_INET6,
  160. -1, /* pseudo_AF_PIP */
  161. -1, /* AF_ISDN */
  162. -1, /* AF_NATM */
  163. -1, /* AF_ARP */
  164. -1, /* LINUX_pseudo_AF_KEY */
  165. -1, /* pseudo_AF_HDRCMPLT */
  166. };
  167. /*
  168. * Convert from Linux to BSD socket domain values
  169. */
  170. static int
  171. linux_to_bsd_domain(ldom)
  172. int ldom;
  173. {
  174. if (ldom < 0 || ldom >= LINUX_AF_MAX)
  175. return (-1);
  176. return linux_to_bsd_domain_[ldom];
  177. }
  178. /*
  179. * Convert from BSD to Linux socket domain values
  180. */
  181. static int
  182. bsd_to_linux_domain(bdom)
  183. int bdom;
  184. {
  185. if (bdom < 0 || bdom >= AF_MAX)
  186. return (-1);
  187. return bsd_to_linux_domain_[bdom];
  188. }
  189. /*
  190. * Convert from Linux to BSD MSG_XXX flags
  191. */
  192. static int
  193. linux_to_bsd_msg_flags(int lflags)
  194. {
  195. int flags = 0;
  196. if (lflags & LINUX_MSG_OOB)
  197. flags |= MSG_OOB;
  198. if (lflags & LINUX_MSG_PEEK)
  199. flags |= MSG_PEEK;
  200. if (lflags & LINUX_MSG_DONTWAIT)
  201. flags |= MSG_DONTWAIT;
  202. if (lflags & LINUX_MSG_WAITALL)
  203. flags |= MSG_WAITALL;
  204. if (lflags & LINUX_MSG_NOSIGNAL)
  205. flags |= MSG_NOSIGNAL;
  206. return (flags);
  207. }
  208. int
  209. linux_socket(p, v, retval)
  210. struct proc *p;
  211. void *v;
  212. register_t *retval;
  213. {
  214. struct linux_socket_args /* {
  215. syscallarg(int) domain;
  216. syscallarg(int) type;
  217. syscallarg(int) protocol;
  218. } */ *uap = v;
  219. struct linux_socket_args lsa;
  220. struct sys_socket_args bsa;
  221. int error;
  222. if ((error = copyin(uap, &lsa, sizeof lsa)))
  223. return error;
  224. SCARG(&bsa, protocol) = lsa.protocol;
  225. SCARG(&bsa, type) = lsa.type & LINUX_SOCKET_TYPE_MASK;
  226. SCARG(&bsa, domain) = linux_to_bsd_domain(lsa.domain);
  227. if (SCARG(&bsa, domain) == -1)
  228. return (EINVAL);
  229. if (lsa.type & ~(LINUX_SOCKET_TYPE_MASK | LINUX_SOCK_CLOEXEC |
  230. LINUX_SOCK_NONBLOCK))
  231. return (EINVAL);
  232. if (lsa.type & LINUX_SOCK_CLOEXEC)
  233. SCARG(&bsa, type) |= SOCK_CLOEXEC;
  234. if (lsa.type & LINUX_SOCK_NONBLOCK)
  235. SCARG(&bsa, type) |= SOCK_NONBLOCK;
  236. return (sys_socket(p, &bsa, retval));
  237. }
  238. int
  239. linux_bind(p, v, retval)
  240. struct proc *p;
  241. void *v;
  242. register_t *retval;
  243. {
  244. struct linux_bind_args /* {
  245. syscallarg(int) s;
  246. syscallarg(struct linux_sockaddr *) name;
  247. syscallarg(int) namelen;
  248. } */ *uap = v;
  249. struct linux_bind_args lba;
  250. struct sys_bind_args bba;
  251. int error;
  252. int namlen;
  253. if ((error = copyin((caddr_t) uap, (caddr_t) &lba, sizeof lba)))
  254. return error;
  255. SCARG(&bba, s) = lba.s;
  256. namlen = lba.namelen;
  257. if (lba.name) {
  258. struct sockaddr *sa;
  259. caddr_t sg = stackgap_init(p);
  260. error = linux_sa_get(p, &sg, &sa, lba.name, &namlen);
  261. if (error)
  262. return (error);
  263. SCARG(&bba, name) = sa;
  264. } else
  265. SCARG(&bba, name) = NULL;
  266. SCARG(&bba, namelen) = namlen;
  267. return sys_bind(p, &bba, retval);
  268. }
  269. int
  270. linux_connect(p, v, retval)
  271. struct proc *p;
  272. void *v;
  273. register_t *retval;
  274. {
  275. struct linux_connect_args /* {
  276. syscallarg(int) s;
  277. syscallarg(struct linux_sockaddr *) name;
  278. syscallarg(int) namelen;
  279. } */ *uap = v;
  280. struct linux_connect_args lca;
  281. struct sys_connect_args bca;
  282. struct sockaddr *sa;
  283. caddr_t sg = stackgap_init(p);
  284. int namlen;
  285. int error;
  286. if ((error = copyin((caddr_t) uap, (caddr_t) &lca, sizeof lca)))
  287. return error;
  288. namlen = lca.namelen;
  289. error = linux_sa_get(p, &sg, &sa, lca.name, &namlen);
  290. if (error)
  291. return (error);
  292. SCARG(&bca, s) = lca.s;
  293. SCARG(&bca, name) = sa;
  294. SCARG(&bca, namelen) = (unsigned int)namlen;
  295. error = sys_connect(p, &bca, retval);
  296. if (error == EISCONN) {
  297. struct sys_getsockopt_args bga;
  298. #if 0
  299. struct sys_fcntl_args fca;
  300. #endif
  301. void *status, *statusl;
  302. int stat, statl = sizeof stat;
  303. #if 0
  304. SCARG(&fca, fd) = lca.s;
  305. SCARG(&fca, cmd) = F_GETFL;
  306. SCARG(&fca, arg) = 0;
  307. if (sys_fcntl(p, &fca, retval) == -1 ||
  308. (*retval & O_NONBLOCK) == 0)
  309. return error;
  310. #endif
  311. status = stackgap_alloc(&sg, sizeof stat);
  312. statusl = stackgap_alloc(&sg, sizeof statl);
  313. if ((error = copyout(&statl, statusl, sizeof statl)))
  314. return error;
  315. SCARG(&bga, s) = lca.s;
  316. SCARG(&bga, level) = SOL_SOCKET;
  317. SCARG(&bga, name) = SO_ERROR;
  318. SCARG(&bga, val) = status;
  319. SCARG(&bga, avalsize) = statusl;
  320. error = sys_getsockopt(p, &bga, retval);
  321. if (error)
  322. return error;
  323. if ((error = copyin(status, &stat, sizeof stat)))
  324. return error;
  325. return stat;
  326. }
  327. return error;
  328. }
  329. int
  330. linux_listen(p, v, retval)
  331. struct proc *p;
  332. void *v;
  333. register_t *retval;
  334. {
  335. struct linux_listen_args /* {
  336. syscallarg(int) s;
  337. syscallarg(int) backlog;
  338. } */ *uap = v;
  339. struct linux_listen_args lla;
  340. struct sys_listen_args bla;
  341. int error;
  342. if ((error = copyin((caddr_t) uap, (caddr_t) &lla, sizeof lla)))
  343. return error;
  344. SCARG(&bla, s) = lla.s;
  345. SCARG(&bla, backlog) = lla.backlog;
  346. return sys_listen(p, &bla, retval);
  347. }
  348. int
  349. linux_accept(p, v, retval)
  350. struct proc *p;
  351. void *v;
  352. register_t *retval;
  353. {
  354. struct linux_accept_args /* {
  355. syscallarg(int) s;
  356. syscallarg(struct sockaddr *) addr;
  357. syscallarg(int *) namelen;
  358. } */ *uap = v;
  359. struct linux_accept_args laa;
  360. int error;
  361. if ((error = copyin((caddr_t) uap, (caddr_t) &laa, sizeof laa)))
  362. return error;
  363. if ((error = doaccept(p, laa.s, laa.addr, laa.namelen, 0, retval)))
  364. return (error);
  365. return (linux_sa_put(laa.addr));
  366. }
  367. int
  368. linux_getsockname(p, v, retval)
  369. struct proc *p;
  370. void *v;
  371. register_t *retval;
  372. {
  373. struct linux_getsockname_args /* {
  374. syscallarg(int) s;
  375. syscallarg(struct sockaddr *) addr;
  376. syscallarg(int *) namelen;
  377. } */ *uap = v;
  378. struct linux_getsockname_args lga;
  379. struct sys_getsockname_args bga;
  380. int error;
  381. if ((error = copyin((caddr_t) uap, (caddr_t) &lga, sizeof lga)))
  382. return error;
  383. SCARG(&bga, fdes) = lga.s;
  384. SCARG(&bga, asa) = lga.addr;
  385. SCARG(&bga, alen) = lga.namelen;
  386. error = sys_getsockname(p, &bga, retval);
  387. if (error)
  388. return (error);
  389. return (linux_sa_put(lga.addr));
  390. }
  391. int
  392. linux_getpeername(p, v, retval)
  393. struct proc *p;
  394. void *v;
  395. register_t *retval;
  396. {
  397. struct linux_getpeername_args /* {
  398. syscallarg(int) s;
  399. syscallarg(struct sockaddr *) addr;
  400. syscallarg(int *) namelen;
  401. } */ *uap = v;
  402. struct linux_getpeername_args lga;
  403. struct sys_getpeername_args bga;
  404. int error;
  405. if ((error = copyin(uap, &lga, sizeof lga)))
  406. return error;
  407. SCARG(&bga, fdes) = lga.s;
  408. SCARG(&bga, asa) = lga.addr;
  409. SCARG(&bga, alen) = lga.namelen;
  410. error = sys_getpeername(p, &bga, retval);
  411. if (error)
  412. return (error);
  413. return (linux_sa_put(lga.addr));
  414. }
  415. int
  416. linux_socketpair(p, v, retval)
  417. struct proc *p;
  418. void *v;
  419. register_t *retval;
  420. {
  421. struct linux_socketpair_args /* {
  422. syscallarg(int) domain;
  423. syscallarg(int) type;
  424. syscallarg(int) protocol;
  425. syscallarg(int *) rsv;
  426. } */ *uap = v;
  427. struct linux_socketpair_args lsa;
  428. struct sys_socketpair_args bsa;
  429. int error;
  430. if ((error = copyin((caddr_t) uap, &lsa, sizeof lsa)))
  431. return error;
  432. SCARG(&bsa, domain) = linux_to_bsd_domain(lsa.domain);
  433. if (SCARG(&bsa, domain) == -1)
  434. return EINVAL;
  435. SCARG(&bsa, type) = lsa.type;
  436. SCARG(&bsa, protocol) = lsa.protocol;
  437. SCARG(&bsa, rsv) = lsa.rsv;
  438. return sys_socketpair(p, &bsa, retval);
  439. }
  440. int
  441. linux_send(p, v, retval)
  442. struct proc *p;
  443. void *v;
  444. register_t *retval;
  445. {
  446. struct linux_send_args /* {
  447. syscallarg(int) s;
  448. syscallarg(void *) msg;
  449. syscallarg(int) len;
  450. syscallarg(int) flags;
  451. } */ *uap = v;
  452. struct linux_send_args lsa;
  453. struct msghdr msg;
  454. struct iovec aiov;
  455. int error;
  456. if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa)))
  457. return error;
  458. msg.msg_name = 0;
  459. msg.msg_namelen = 0;
  460. msg.msg_iov = &aiov;
  461. msg.msg_iovlen = 1;
  462. aiov.iov_base = lsa.msg;
  463. aiov.iov_len = lsa.len;
  464. msg.msg_control = 0;
  465. msg.msg_flags = 0;
  466. return (sendit(p, lsa.s, &msg, linux_to_bsd_msg_flags(lsa.flags),
  467. retval));
  468. }
  469. int
  470. linux_recv(p, v, retval)
  471. struct proc *p;
  472. void *v;
  473. register_t *retval;
  474. {
  475. struct linux_recv_args /* {
  476. syscallarg(int) s;
  477. syscallarg(void *) msg;
  478. syscallarg(int) len;
  479. syscallarg(int) flags;
  480. } */ *uap = v;
  481. struct linux_recv_args lra;
  482. struct msghdr msg;
  483. struct iovec aiov;
  484. int error;
  485. if ((error = copyin((caddr_t) uap, (caddr_t) &lra, sizeof lra)))
  486. return error;
  487. msg.msg_name = 0;
  488. msg.msg_namelen = 0;
  489. msg.msg_iov = &aiov;
  490. msg.msg_iovlen = 1;
  491. aiov.iov_base = lra.msg;
  492. aiov.iov_len = lra.len;
  493. msg.msg_control = 0;
  494. msg.msg_flags = linux_to_bsd_msg_flags(lra.flags);
  495. return (recvit(p, lra.s, &msg, NULL, retval));
  496. }
  497. int
  498. linux_check_hdrincl(p, fd, retval, sgp)
  499. struct proc *p;
  500. int fd;
  501. register_t *retval;
  502. caddr_t *sgp;
  503. {
  504. struct sys_getsockopt_args /* {
  505. int s;
  506. int level;
  507. int name;
  508. caddr_t val;
  509. int *avalsize;
  510. } */ gsa;
  511. int error;
  512. caddr_t val;
  513. int *valsize;
  514. int size_val = sizeof val;
  515. int optval;
  516. val = stackgap_alloc(sgp, sizeof(optval));
  517. valsize = stackgap_alloc(sgp, sizeof(size_val));
  518. if ((error = copyout(&size_val, valsize, sizeof(size_val))))
  519. return (error);
  520. SCARG(&gsa, s) = fd;
  521. SCARG(&gsa, level) = IPPROTO_IP;
  522. SCARG(&gsa, name) = IP_HDRINCL;
  523. SCARG(&gsa, val) = val;
  524. SCARG(&gsa, avalsize) = valsize;
  525. if ((error = sys_getsockopt(p, &gsa, retval)))
  526. return (error);
  527. if ((error = copyin(val, &optval, sizeof(optval))))
  528. return (error);
  529. return (optval == 0);
  530. }
  531. /*
  532. * linux_ip_copysize defines how many bytes we should copy
  533. * from the beginning of the IP packet before we customize it for BSD.
  534. * It should include all the fields we modify (ip_len and ip_off)
  535. * and be as small as possible to minimize copying overhead.
  536. */
  537. #define linux_ip_copysize 8
  538. int
  539. linux_sendto_hdrincl(p, bsa, retval, sgp)
  540. struct proc *p;
  541. struct sys_sendto_args *bsa;
  542. register_t *retval;
  543. caddr_t *sgp;
  544. {
  545. struct sys_sendmsg_args ssa;
  546. struct ip *packet, rpacket;
  547. struct msghdr *msg, rmsg;
  548. struct iovec *iov, riov[2];
  549. int error;
  550. /* Check the packet isn't too small before we mess with it */
  551. if (SCARG(bsa, len) < linux_ip_copysize)
  552. return EINVAL;
  553. /*
  554. * Tweaking the user buffer in place would be bad manners.
  555. * We create a corrected IP header with just the needed length,
  556. * then use an iovec to glue it to the rest of the user packet
  557. * when calling sendmsg().
  558. */
  559. packet = (struct ip *)stackgap_alloc(sgp, linux_ip_copysize);
  560. msg = (struct msghdr *)stackgap_alloc(sgp, sizeof(*msg));
  561. iov = (struct iovec *)stackgap_alloc(sgp, sizeof(*iov)*2);
  562. /* Make a copy of the beginning of the packet to be sent */
  563. if ((error = copyin(SCARG(bsa, buf), (caddr_t)&rpacket,
  564. linux_ip_copysize)))
  565. return error;
  566. /* Convert fields from Linux to BSD raw IP socket format */
  567. rpacket.ip_len = SCARG(bsa, len);
  568. error = copyout(&rpacket, packet, linux_ip_copysize);
  569. if (error)
  570. return (error);
  571. riov[0].iov_base = (char *)packet;
  572. riov[0].iov_len = linux_ip_copysize;
  573. riov[1].iov_base = (caddr_t)SCARG(bsa, buf) + linux_ip_copysize;
  574. riov[1].iov_len = SCARG(bsa, len) - linux_ip_copysize;
  575. error = copyout(&riov[0], iov, sizeof(riov));
  576. if (error)
  577. return (error);
  578. /* Prepare the msghdr and iovec structures describing the new packet */
  579. rmsg.msg_name = (void *)SCARG(bsa, to);
  580. rmsg.msg_namelen = SCARG(bsa, tolen);
  581. rmsg.msg_iov = iov;
  582. rmsg.msg_iovlen = 2;
  583. rmsg.msg_control = NULL;
  584. rmsg.msg_controllen = 0;
  585. rmsg.msg_flags = 0;
  586. error = copyout(&riov[0], iov, sizeof(riov));
  587. if (error)
  588. return (error);
  589. SCARG(&ssa, s) = SCARG(bsa, s);
  590. SCARG(&ssa, msg) = msg;
  591. SCARG(&ssa, flags) = SCARG(bsa, flags);
  592. return sys_sendmsg(p, &ssa, retval);
  593. }
  594. int
  595. linux_sendto(p, v, retval)
  596. struct proc *p;
  597. void *v;
  598. register_t *retval;
  599. {
  600. struct linux_sendto_args /* {
  601. syscallarg(int) s;
  602. syscallarg(void *) msg;
  603. syscallarg(int) len;
  604. syscallarg(int) flags;
  605. syscallarg(linux_sockaddr *) to;
  606. syscallarg(int) tolen;
  607. } */ *uap = v;
  608. struct linux_sendto_args lsa;
  609. struct sys_sendto_args bsa;
  610. int error;
  611. int tolen;
  612. caddr_t sg = stackgap_init(p);
  613. if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa)))
  614. return error;
  615. SCARG(&bsa, s) = lsa.s;
  616. SCARG(&bsa, buf) = lsa.msg;
  617. SCARG(&bsa, len) = lsa.len;
  618. SCARG(&bsa, flags) = linux_to_bsd_msg_flags(lsa.flags);
  619. tolen = lsa.tolen;
  620. if (lsa.to) {
  621. struct sockaddr *sa;
  622. if ((error = linux_sa_get(p, &sg, &sa, lsa.to, &tolen)))
  623. return (error);
  624. SCARG(&bsa, to) = sa;
  625. } else
  626. SCARG(&bsa, to) = NULL;
  627. SCARG(&bsa, tolen) = tolen;
  628. if (linux_check_hdrincl(p, lsa.s, retval, &sg) == 0)
  629. return linux_sendto_hdrincl(p, &bsa, retval, &sg);
  630. return sys_sendto(p, &bsa, retval);
  631. }
  632. int
  633. linux_recvfrom(p, v, retval)
  634. struct proc *p;
  635. void *v;
  636. register_t *retval;
  637. {
  638. struct linux_recvfrom_args /* {
  639. syscallarg(int) s;
  640. syscallarg(void *) buf;
  641. syscallarg(int) len;
  642. syscallarg(int) flags;
  643. syscallarg(struct sockaddr *) from;
  644. syscallarg(int *) fromlen;
  645. } */ *uap = v;
  646. struct linux_recvfrom_args lra;
  647. struct sys_recvfrom_args bra;
  648. int error;
  649. if ((error = copyin((caddr_t) uap, (caddr_t) &lra, sizeof lra)))
  650. return error;
  651. SCARG(&bra, s) = lra.s;
  652. SCARG(&bra, buf) = lra.buf;
  653. SCARG(&bra, len) = lra.len;
  654. SCARG(&bra, flags) = linux_to_bsd_msg_flags(lra.flags);
  655. SCARG(&bra, from) = lra.from;
  656. SCARG(&bra, fromlenaddr) = lra.fromlen;
  657. if ((error = sys_recvfrom(p, &bra, retval)))
  658. return (error);
  659. if (lra.from && (error = linux_sa_put(lra.from)))
  660. return (error);
  661. return (0);
  662. }
  663. int
  664. linux_shutdown(p, v, retval)
  665. struct proc *p;
  666. void *v;
  667. register_t *retval;
  668. {
  669. struct linux_shutdown_args /* {
  670. syscallarg(int) s;
  671. syscallarg(int) how;
  672. } */ *uap = v;
  673. struct linux_shutdown_args lsa;
  674. struct sys_shutdown_args bsa;
  675. int error;
  676. if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa)))
  677. return error;
  678. SCARG(&bsa, s) = lsa.s;
  679. SCARG(&bsa, how) = lsa.how;
  680. return sys_shutdown(p, &bsa, retval);
  681. }
  682. /*
  683. * Convert socket option level from Linux to OpenBSD value. Only SOL_SOCKET
  684. * is different, the rest matches IPPROTO_* on both systems.
  685. */
  686. int
  687. linux_to_bsd_sopt_level(llevel)
  688. int llevel;
  689. {
  690. switch (llevel) {
  691. case LINUX_SOL_SOCKET:
  692. return SOL_SOCKET;
  693. case LINUX_SOL_IP:
  694. return IPPROTO_IP;
  695. case LINUX_SOL_TCP:
  696. return IPPROTO_TCP;
  697. case LINUX_SOL_UDP:
  698. return IPPROTO_UDP;
  699. default:
  700. return -1;
  701. }
  702. }
  703. /*
  704. * Convert Linux socket level socket option numbers to OpenBSD values.
  705. */
  706. int
  707. linux_to_bsd_so_sockopt(lopt)
  708. int lopt;
  709. {
  710. switch (lopt) {
  711. case LINUX_SO_DEBUG:
  712. return SO_DEBUG;
  713. case LINUX_SO_REUSEADDR:
  714. /*
  715. * Linux does not implement SO_REUSEPORT, but allows reuse
  716. * of a host:port pair through SO_REUSEADDR even if the
  717. * address is not a multicast-address. Effectively, this
  718. * means that we should use SO_REUSEPORT to allow Linux
  719. * applications to not receive EADDRINUSE.
  720. */
  721. return SO_REUSEPORT;
  722. case LINUX_SO_TYPE:
  723. return SO_TYPE;
  724. case LINUX_SO_ERROR:
  725. return SO_ERROR;
  726. case LINUX_SO_DONTROUTE:
  727. return SO_DONTROUTE;
  728. case LINUX_SO_BROADCAST:
  729. return SO_BROADCAST;
  730. case LINUX_SO_SNDBUF:
  731. return SO_SNDBUF;
  732. case LINUX_SO_RCVBUF:
  733. return SO_RCVBUF;
  734. case LINUX_SO_KEEPALIVE:
  735. return SO_KEEPALIVE;
  736. case LINUX_SO_OOBINLINE:
  737. return SO_OOBINLINE;
  738. case LINUX_SO_LINGER:
  739. return SO_LINGER;
  740. case LINUX_SO_PRIORITY:
  741. case LINUX_SO_NO_CHECK:
  742. default:
  743. return -1;
  744. }
  745. }
  746. /*
  747. * Convert Linux IP level socket option number to OpenBSD values.
  748. */
  749. int
  750. linux_to_bsd_ip_sockopt(lopt)
  751. int lopt;
  752. {
  753. switch (lopt) {
  754. case LINUX_IP_TOS:
  755. return IP_TOS;
  756. case LINUX_IP_TTL:
  757. return IP_TTL;
  758. case LINUX_IP_MULTICAST_TTL:
  759. return IP_MULTICAST_TTL;
  760. case LINUX_IP_MULTICAST_LOOP:
  761. return IP_MULTICAST_LOOP;
  762. case LINUX_IP_MULTICAST_IF:
  763. return IP_MULTICAST_IF;
  764. case LINUX_IP_ADD_MEMBERSHIP:
  765. return IP_ADD_MEMBERSHIP;
  766. case LINUX_IP_DROP_MEMBERSHIP:
  767. return IP_DROP_MEMBERSHIP;
  768. case LINUX_IP_HDRINCL:
  769. return IP_HDRINCL;
  770. default:
  771. return -1;
  772. }
  773. }
  774. /*
  775. * Convert Linux TCP level socket option number to OpenBSD values.
  776. */
  777. int
  778. linux_to_bsd_tcp_sockopt(lopt)
  779. int lopt;
  780. {
  781. switch (lopt) {
  782. case LINUX_TCP_NODELAY:
  783. return TCP_NODELAY;
  784. case LINUX_TCP_MAXSEG:
  785. return TCP_MAXSEG;
  786. default:
  787. return -1;
  788. }
  789. }
  790. /*
  791. * Convert Linux UDP level socket option number to OpenBSD values.
  792. */
  793. int
  794. linux_to_bsd_udp_sockopt(lopt)
  795. int lopt;
  796. {
  797. switch (lopt) {
  798. default:
  799. return -1;
  800. }
  801. }
  802. /*
  803. * Another reasonably straightforward function: setsockopt(2).
  804. * The level and option numbers are converted; the values passed
  805. * are not (yet) converted, the ones currently implemented don't
  806. * need conversion, as they are the same on both systems.
  807. */
  808. int
  809. linux_setsockopt(p, v, retval)
  810. struct proc *p;
  811. void *v;
  812. register_t *retval;
  813. {
  814. struct linux_setsockopt_args /* {
  815. syscallarg(int) s;
  816. syscallarg(int) level;
  817. syscallarg(int) optname;
  818. syscallarg(void *) optval;
  819. syscallarg(int) optlen;
  820. } */ *uap = v;
  821. struct linux_setsockopt_args lsa;
  822. struct file *fp;
  823. struct mbuf *m = NULL;
  824. struct socket *so;
  825. int error, level, name;
  826. if ((error = copyin((caddr_t) uap, (caddr_t) &lsa, sizeof lsa)))
  827. return error;
  828. if ((error = getsock(p, lsa.s, &fp)) != 0)
  829. return error;
  830. level = linux_to_bsd_sopt_level(lsa.level);
  831. switch (level) {
  832. case SOL_SOCKET:
  833. name = linux_to_bsd_so_sockopt(lsa.optname);
  834. break;
  835. case IPPROTO_IP:
  836. name = linux_to_bsd_ip_sockopt(lsa.optname);
  837. break;
  838. case IPPROTO_TCP:
  839. name = linux_to_bsd_tcp_sockopt(lsa.optname);
  840. break;
  841. case IPPROTO_UDP:
  842. name = linux_to_bsd_udp_sockopt(lsa.optname);
  843. break;
  844. default:
  845. error = EINVAL;
  846. goto bad;
  847. }
  848. if (name == -1) {
  849. error = EINVAL;
  850. goto bad;
  851. }
  852. if (lsa.optlen > MLEN) {
  853. error = EINVAL;
  854. goto bad;
  855. }
  856. if (lsa.optval != NULL) {
  857. m = m_get(M_WAIT, MT_SOOPTS);
  858. error = copyin(lsa.optval, mtod(m, caddr_t), lsa.optlen);
  859. if (error)
  860. goto bad;
  861. m->m_len = lsa.optlen;
  862. }
  863. so = (struct socket *)fp->f_data;
  864. if (so->so_proto && level == IPPROTO_TCP && name == TCP_NODELAY &&
  865. so->so_proto->pr_domain->dom_family == AF_LOCAL &&
  866. so->so_proto->pr_protocol == PF_LOCAL) {
  867. /* ignore it */
  868. error = 0;
  869. goto bad;
  870. }
  871. error = sosetopt(so, level, name, m);
  872. m = NULL;
  873. bad:
  874. if (m)
  875. m_free(m);
  876. FRELE(fp, p);
  877. return (error);
  878. }
  879. /*
  880. * getsockopt(2) is very much the same as setsockopt(2) (see above)
  881. */
  882. int
  883. linux_getsockopt(p, v, retval)
  884. struct proc *p;
  885. void *v;
  886. register_t *retval;
  887. {
  888. struct linux_getsockopt_args /* {
  889. syscallarg(int) s;
  890. syscallarg(int) level;
  891. syscallarg(int) optname;
  892. syscallarg(void *) optval;
  893. syscallarg(int) *optlen;
  894. } */ *uap = v;
  895. struct linux_getsockopt_args lga;
  896. struct sys_getsockopt_args bga;
  897. int error, name;
  898. if ((error = copyin((caddr_t) uap, (caddr_t) &lga, sizeof lga)))
  899. return error;
  900. SCARG(&bga, s) = lga.s;
  901. SCARG(&bga, level) = linux_to_bsd_sopt_level(lga.level);
  902. SCARG(&bga, val) = lga.optval;
  903. SCARG(&bga, avalsize) = lga.optlen;
  904. switch (SCARG(&bga, level)) {
  905. case SOL_SOCKET:
  906. name = linux_to_bsd_so_sockopt(lga.optname);
  907. break;
  908. case IPPROTO_IP:
  909. name = linux_to_bsd_ip_sockopt(lga.optname);
  910. break;
  911. case IPPROTO_TCP:
  912. name = linux_to_bsd_tcp_sockopt(lga.optname);
  913. break;
  914. case IPPROTO_UDP:
  915. name = linux_to_bsd_udp_sockopt(lga.optname);
  916. break;
  917. default:
  918. return EINVAL;
  919. }
  920. if (name == -1)
  921. return EINVAL;
  922. SCARG(&bga, name) = name;
  923. return sys_getsockopt(p, &bga, retval);
  924. }
  925. int
  926. linux_recvmsg(p, v, retval)
  927. struct proc *p;
  928. void *v;
  929. register_t *retval;
  930. {
  931. struct linux_recvmsg_args /* {
  932. syscallarg(int) s;
  933. syscallarg(caddr_t) msg;
  934. syscallarg(int) flags;
  935. } */ *uap = v;
  936. struct linux_recvmsg_args lla;
  937. struct sys_recvmsg_args bla;
  938. struct msghdr msg;
  939. int error;
  940. if ((error = copyin((caddr_t) uap, (caddr_t) &lla, sizeof lla)))
  941. return error;
  942. SCARG(&bla, s) = lla.s;
  943. SCARG(&bla, msg) = (struct msghdr *)lla.msg;
  944. SCARG(&bla, flags) = linux_to_bsd_msg_flags(lla.flags);
  945. error = sys_recvmsg(p, &bla, retval);
  946. if (error)
  947. return (error);
  948. error = copyin(lla.msg, (caddr_t)&msg, sizeof(msg));
  949. if (!error && msg.msg_name && msg.msg_namelen > 2)
  950. error = linux_sa_put(msg.msg_name);
  951. return (error);
  952. }
  953. int
  954. linux_sendmsg(p, v, retval)
  955. struct proc *p;
  956. void *v;
  957. register_t *retval;
  958. {
  959. struct linux_sendmsg_args /* {
  960. syscallarg(int) s;
  961. syscallarg(struct msghdr *) msg;
  962. syscallarg(int) flags;
  963. } */ *uap = v;
  964. struct linux_sendmsg_args lla;
  965. struct sys_sendmsg_args bla;
  966. struct msghdr msg, *nmsg = NULL;
  967. int error;
  968. caddr_t control;
  969. int level = -1;
  970. if ((error = copyin((caddr_t) uap, (caddr_t) &lla, sizeof lla)))
  971. return error;
  972. if ((error = copyin(lla.msg, (caddr_t) &msg, sizeof(msg))))
  973. return (error);
  974. if (msg.msg_name) {
  975. struct sockaddr *sa;
  976. caddr_t sg = stackgap_init(p);
  977. nmsg = (struct msghdr *)stackgap_alloc(&sg,
  978. sizeof(struct msghdr));
  979. if (!nmsg)
  980. return (ENOMEM);
  981. error = linux_sa_get(p, &sg, &sa,
  982. (struct linux_sockaddr *)msg.msg_name, &msg.msg_namelen);
  983. if (error)
  984. return (error);
  985. msg.msg_name = sa;
  986. if ((error = copyout(&msg, nmsg, sizeof(struct msghdr))))
  987. return (error);
  988. lla.msg = nmsg;
  989. }
  990. SCARG(&bla, s) = lla.s;
  991. SCARG(&bla, msg) = lla.msg;
  992. SCARG(&bla, flags) = linux_to_bsd_msg_flags(lla.flags);
  993. error = copyin(lla.msg->msg_control, &control, sizeof(caddr_t));
  994. if (error)
  995. return error;
  996. if (control == NULL)
  997. goto done;
  998. error = copyin(&((struct cmsghdr *)control)->cmsg_level,
  999. &level, sizeof(int));
  1000. if (error)
  1001. return error;
  1002. if (level == 1) {
  1003. /*
  1004. * Linux thinks that SOL_SOCKET is 1; we know that it's really
  1005. * 0xffff, of course.
  1006. */
  1007. level = SOL_SOCKET;
  1008. /*
  1009. * XXX should use stack gap!
  1010. * We don't because the control header is variable length
  1011. * up to 2048 bytes, and there's only 512 bytes of gap.
  1012. */
  1013. error = copyout(&level, &((struct cmsghdr *)control)->
  1014. cmsg_level, sizeof(int));
  1015. if (error)
  1016. return error;
  1017. }
  1018. done:
  1019. error = sys_sendmsg(p, &bla, retval);
  1020. /* replace level, just in case somebody cares. */
  1021. if (level == SOL_SOCKET) {
  1022. level = 1;
  1023. /* don't worry about the error */
  1024. copyout(&level, &((struct cmsghdr *)control)->cmsg_level,
  1025. sizeof(int));
  1026. }
  1027. return (error);
  1028. }
  1029. /*
  1030. * Copy the linux_sockaddr structure pointed to by osa to kernel, adjust
  1031. * family and convert to sockaddr, allocate stackgap and put the
  1032. * the converted structure there. Address on stackgap returned in sap.
  1033. */
  1034. int
  1035. linux_sa_get(struct proc *p, caddr_t *sgp, struct sockaddr **sap,
  1036. const struct linux_sockaddr *osa, int *osalen)
  1037. {
  1038. int error, bdom;
  1039. struct sockaddr *sa, *usa;
  1040. struct linux_sockaddr *kosa;
  1041. int alloclen;
  1042. #ifdef INET6
  1043. int oldv6size;
  1044. struct sockaddr_in6 *sin6;
  1045. #endif
  1046. if (*osalen < 2 || *osalen > UCHAR_MAX || !osa) {
  1047. return (EINVAL);
  1048. }
  1049. if (osa->sa_family == AF_UNIX && *osalen > sizeof(struct sockaddr_un))
  1050. alloclen = sizeof(struct sockaddr_un);
  1051. else
  1052. alloclen = *osalen;
  1053. #ifdef INET6
  1054. oldv6size = 0;
  1055. /*
  1056. * Check for old (pre-RFC2553) sockaddr_in6. We may accept it
  1057. * if it's a v4-mapped address, so reserve the proper space
  1058. * for it.
  1059. */
  1060. if (alloclen == sizeof (struct sockaddr_in6) - sizeof (u_int32_t)) {
  1061. alloclen = sizeof (struct sockaddr_in6);
  1062. oldv6size = 1;
  1063. }
  1064. #endif
  1065. kosa = malloc(alloclen, M_TEMP, M_WAITOK);
  1066. if ((error = copyin(osa, (caddr_t) kosa, *osalen))) {
  1067. goto out;
  1068. }
  1069. bdom = linux_to_bsd_domain(kosa->sa_family);
  1070. if (bdom == -1) {
  1071. error = EINVAL;
  1072. goto out;
  1073. }
  1074. #ifdef INET6
  1075. /*
  1076. * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6,
  1077. * which lacks the scope id compared with RFC2553 one. If we detect
  1078. * the situation, reject the address.
  1079. *
  1080. * Still accept addresses for which the scope id is not used.
  1081. */
  1082. if (oldv6size && bdom == AF_INET6) {
  1083. sin6 = (struct sockaddr_in6 *)kosa;
  1084. if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ||
  1085. (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
  1086. !IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&
  1087. !IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) &&
  1088. !IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
  1089. !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) {
  1090. sin6->sin6_scope_id = 0;
  1091. } else {
  1092. error = EINVAL;
  1093. goto out;
  1094. }
  1095. } else
  1096. #endif
  1097. if (bdom == AF_INET) {
  1098. alloclen = sizeof(struct sockaddr_in);
  1099. }
  1100. sa = (struct sockaddr *) kosa;
  1101. sa->sa_family = bdom;
  1102. sa->sa_len = alloclen;
  1103. usa = (struct sockaddr *) stackgap_alloc(sgp, alloclen);
  1104. if (!usa) {
  1105. error = ENOMEM;
  1106. goto out;
  1107. }
  1108. if ((error = copyout(sa, usa, alloclen))) {
  1109. goto out;
  1110. }
  1111. *sap = usa;
  1112. out:
  1113. *osalen = alloclen;
  1114. free(kosa, M_TEMP, 0);
  1115. return (error);
  1116. }
  1117. int
  1118. linux_sa_put(struct sockaddr *osa)
  1119. {
  1120. struct sockaddr sa;
  1121. struct linux_sockaddr *kosa;
  1122. int error, bdom, len;
  1123. /*
  1124. * Only read/write the sockaddr family and length part, the rest is
  1125. * not changed.
  1126. */
  1127. len = sizeof(sa.sa_len) + sizeof(sa.sa_family);
  1128. error = copyin((caddr_t) osa, (caddr_t) &sa, len);
  1129. if (error)
  1130. return (error);
  1131. bdom = bsd_to_linux_domain(sa.sa_family);
  1132. if (bdom == -1)
  1133. return (EINVAL);
  1134. /* Note: we convert from sockaddr to linux_sockaddr here, too */
  1135. kosa = (struct linux_sockaddr *) &sa;
  1136. kosa->sa_family = bdom;
  1137. error = copyout(kosa, osa, len);
  1138. if (error)
  1139. return (error);
  1140. return (0);
  1141. }
  1142. /*
  1143. * Entry point to all Linux socket calls. Just check which call to
  1144. * make and take appropriate action.
  1145. */
  1146. int
  1147. linux_sys_socketcall(p, v, retval)
  1148. struct proc *p;
  1149. void *v;
  1150. register_t *retval;
  1151. {
  1152. struct linux_sys_socketcall_args /* {
  1153. syscallarg(int) what;
  1154. syscallarg(void *) args;
  1155. } */ *uap = v;
  1156. switch (SCARG(uap, what)) {
  1157. case LINUX_SYS_socket:
  1158. return linux_socket(p, SCARG(uap, args), retval);
  1159. case LINUX_SYS_bind:
  1160. return linux_bind(p, SCARG(uap, args), retval);
  1161. case LINUX_SYS_connect:
  1162. return linux_connect(p, SCARG(uap, args), retval);
  1163. case LINUX_SYS_listen:
  1164. return linux_listen(p, SCARG(uap, args), retval);
  1165. case LINUX_SYS_accept:
  1166. return linux_accept(p, SCARG(uap, args), retval);
  1167. case LINUX_SYS_getsockname:
  1168. return linux_getsockname(p, SCARG(uap, args), retval);
  1169. case LINUX_SYS_getpeername:
  1170. return linux_getpeername(p, SCARG(uap, args), retval);
  1171. case LINUX_SYS_socketpair:
  1172. return linux_socketpair(p, SCARG(uap, args), retval);
  1173. case LINUX_SYS_send:
  1174. return linux_send(p, SCARG(uap, args), retval);
  1175. case LINUX_SYS_recv:
  1176. return linux_recv(p, SCARG(uap, args), retval);
  1177. case LINUX_SYS_sendto:
  1178. return linux_sendto(p, SCARG(uap, args), retval);
  1179. case LINUX_SYS_recvfrom:
  1180. return linux_recvfrom(p, SCARG(uap, args), retval);
  1181. case LINUX_SYS_shutdown:
  1182. return linux_shutdown(p, SCARG(uap, args), retval);
  1183. case LINUX_SYS_setsockopt:
  1184. return linux_setsockopt(p, SCARG(uap, args), retval);
  1185. case LINUX_SYS_getsockopt:
  1186. return linux_getsockopt(p, SCARG(uap, args), retval);
  1187. case LINUX_SYS_sendmsg:
  1188. return linux_sendmsg(p, SCARG(uap, args), retval);
  1189. case LINUX_SYS_recvmsg:
  1190. return linux_recvmsg(p, SCARG(uap, args), retval);
  1191. default:
  1192. return ENOSYS;
  1193. }
  1194. }
  1195. int
  1196. linux_ioctl_socket(p, v, retval)
  1197. register struct proc *p;
  1198. void *v;
  1199. register_t *retval;
  1200. {
  1201. struct linux_sys_ioctl_args /* {
  1202. syscallarg(int) fd;
  1203. syscallarg(u_long) com;
  1204. syscallarg(caddr_t) data;
  1205. } */ *uap = v;
  1206. u_long com;
  1207. struct sys_ioctl_args ia;
  1208. struct file *fp;
  1209. struct filedesc *fdp;
  1210. struct vnode *vp;
  1211. int (*ioctlf)(struct file *, u_long, caddr_t, struct proc *);
  1212. struct ioctl_pt pt;
  1213. void *data = SCARG(uap, data);
  1214. int error = 0, isdev = 0, dosys = 1;
  1215. fdp = p->p_fd;
  1216. if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
  1217. return (EBADF);
  1218. FREF(fp);
  1219. if (fp->f_type == DTYPE_VNODE) {
  1220. vp = (struct vnode *)fp->f_data;
  1221. isdev = vp->v_type == VCHR;
  1222. }
  1223. /*
  1224. * Don't try to interpret socket ioctl calls that are done
  1225. * on a device file descriptor, just pass them through, to
  1226. * emulate Linux behaviour. Use PTIOCLINUX so that the
  1227. * device will only handle these if it's prepared to do
  1228. * so, to avoid unexpected things from happening.
  1229. */
  1230. if (isdev) {
  1231. dosys = 0;
  1232. ioctlf = fp->f_ops->fo_ioctl;
  1233. pt.com = SCARG(uap, com);
  1234. pt.data = data;
  1235. error = ioctlf(fp, PTIOCLINUX, (caddr_t)&pt, p);
  1236. /*
  1237. * XXX hack: if the function returns EJUSTRETURN,
  1238. * it has stuffed a sysctl return value in pt.data.
  1239. */
  1240. if (error == EJUSTRETURN) {
  1241. retval[0] = (register_t)pt.data;
  1242. error = 0;
  1243. }
  1244. goto out;
  1245. }
  1246. com = SCARG(uap, com);
  1247. retval[0] = 0;
  1248. switch (com) {
  1249. case LINUX_FIOSETOWN:
  1250. SCARG(&ia, com) = FIOSETOWN;
  1251. break;
  1252. case LINUX_SIOCSPGRP:
  1253. SCARG(&ia, com) = SIOCSPGRP;
  1254. break;
  1255. case LINUX_FIOGETOWN:
  1256. SCARG(&ia, com) = FIOGETOWN;
  1257. break;
  1258. case LINUX_SIOCGPGRP:
  1259. SCARG(&ia, com) = SIOCGPGRP;
  1260. break;
  1261. case LINUX_SIOCATMARK:
  1262. SCARG(&ia, com) = SIOCATMARK;
  1263. break;
  1264. #if 0
  1265. case LINUX_SIOCGSTAMP:
  1266. SCARG(&ia, com) = SIOCGSTAMP;
  1267. break;
  1268. #endif
  1269. case LINUX_SIOCGIFCONF:
  1270. SCARG(&ia, com) = OSIOCGIFCONF;
  1271. break;
  1272. case LINUX_SIOCGIFFLAGS:
  1273. SCARG(&ia, com) = SIOCGIFFLAGS;
  1274. break;
  1275. case LINUX_SIOCGIFADDR:
  1276. SCARG(&ia, com) = SIOCGIFADDR;
  1277. break;
  1278. case LINUX_SIOCGIFDSTADDR:
  1279. SCARG(&ia, com) = SIOCGIFDSTADDR;
  1280. break;
  1281. case LINUX_SIOCGIFBRDADDR:
  1282. SCARG(&ia, com) = SIOCGIFBRDADDR;
  1283. break;
  1284. case LINUX_SIOCGIFNETMASK:
  1285. SCARG(&ia, com) = SIOCGIFNETMASK;
  1286. break;
  1287. case LINUX_SIOCGIFMETRIC:
  1288. SCARG(&ia, com) = SIOCGIFMETRIC;
  1289. break;
  1290. case LINUX_SIOCGIFMTU:
  1291. SCARG(&ia, com) = SIOCGIFMTU;
  1292. break;
  1293. case LINUX_SIOCADDMULTI:
  1294. SCARG(&ia, com) = SIOCADDMULTI;
  1295. break;
  1296. case LINUX_SIOCDELMULTI:
  1297. SCARG(&ia, com) = SIOCDELMULTI;
  1298. break;
  1299. case LINUX_SIOCGIFHWADDR: {
  1300. struct linux_ifreq *ifr = data;
  1301. struct sockaddr_dl *sdl;
  1302. struct ifnet *ifp;
  1303. /*
  1304. * Note that we don't actually respect the name in the ifreq
  1305. * structure, as Linux interface names are all different.
  1306. */
  1307. TAILQ_FOREACH(ifp, &ifnet, if_list) {
  1308. if (ifp->if_type != IFT_ETHER)
  1309. continue;
  1310. if ((sdl = ifp->if_sadl) &&
  1311. (sdl->sdl_family == AF_LINK) &&
  1312. (sdl->sdl_type == IFT_ETHER)) {
  1313. error = copyout(LLADDR(sdl),
  1314. &ifr->ifr_hwaddr.sa_data,
  1315. LINUX_IFHWADDRLEN);
  1316. dosys = 0;
  1317. goto out;
  1318. }
  1319. }
  1320. error = ENOENT;
  1321. break;
  1322. }
  1323. default:
  1324. error = EINVAL;
  1325. }
  1326. out:
  1327. if (error == 0 && dosys) {
  1328. SCARG(&ia, fd) = SCARG(uap, fd);
  1329. SCARG(&ia, data) = data;
  1330. error = sys_ioctl(p, &ia, retval);
  1331. if (error == 0) {
  1332. struct ifreq *ifr = data;
  1333. switch (com) {
  1334. case LINUX_SIOCGIFADDR:
  1335. case LINUX_SIOCGIFDSTADDR:
  1336. case LINUX_SIOCGIFBRDADDR:
  1337. case LINUX_SIOCGIFNETMASK:
  1338. error = linux_sa_put(&ifr->ifr_addr);
  1339. break;
  1340. }
  1341. }
  1342. }
  1343. FRELE(fp, p);
  1344. return (error);
  1345. }