1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45:
46:
47: 48: 49: 50:
51:
52:
53:
54: #include <tk/tkernel.h>
55:
56: #include <sys/param.h>
57: #ifndef T2EX
58: #include <sys/ucred.h>
59: #endif
60: #include <sys/systm.h>
61: #include <sys/sysctl.h>
62: #include <sys/malloc.h>
63: #include <sys/sleepq.h>
64: #include <sys/filedesc.h>
65: #include <sys/syscallargs.h>
66:
67: #include <net/if.h>
68: #include <net/route.h>
69: #include <netmain/if_tkn.h>
70: #include "tkn.h"
71:
72: #include <ifaddrs.h>
73:
74: lwp_t lwp0;
75: proc_t proc;
76: filedesc_t* filedesc0;
77:
78: static lwp_t *tskid_lwp_table;
79: static int tskid_lwp_table_maxid;
80:
81: kmutex_t spc_lock;
82:
83: EXPORT ER tkn_lwp_init(void)
84: {
85: int i;
86: int error;
87: ER ercd;
88:
89: error = mutex_init(&spc_lock, 0, IPL_NONE);
90: if ( error != 0 ) {
91: ercd = ERRNOtoER(error);
92: goto err_ret0;
93: }
94:
95: if (tk_get_cfn("TMaxTskId", &tskid_lwp_table_maxid, 1) < 1) {
96: ercd = E_SYS;
97: goto err_ret1;
98: }
99:
100: tskid_lwp_table = (lwp_t *)malloc(sizeof(lwp_t)*tskid_lwp_table_maxid, M_KMEM, M_NOWAIT | M_ZERO);
101: if (tskid_lwp_table == NULL) {
102: ercd = E_NOMEM;
103: goto err_ret1;
104: }
105:
106: for(i = 0; i < tskid_lwp_table_maxid; i++) {
107: tskid_lwp_table[i].l_proc = &proc;
108: tskid_lwp_table[i].l_mutex = &spc_lock;
109:
110: callout_init(&tskid_lwp_table[i].l_timeout_ch, 0);
111: callout_setfunc(&tskid_lwp_table[i].l_timeout_ch, sleepq_timeout, &tskid_lwp_table[i]);
112: }
113:
114: return E_OK;
115:
116: err_ret1:
117: mutex_destroy(&spc_lock);
118: err_ret0:
119: return ercd;
120: }
121:
122: EXPORT ER tkn_lwp_setfd(void)
123: {
124: int i;
125:
126: for(i = 0; i < tskid_lwp_table_maxid; i++) {
127: tskid_lwp_table[i].l_fd = filedesc0;
128: }
129:
130: proc.p_fd = filedesc0;
131:
132: return E_OK;
133: }
134:
135: EXPORT ER tkn_lwp_finish(void)
136: {
137: int i;
138:
139: for(i = 0; i < tskid_lwp_table_maxid; i++) {
140: callout_destroy(&tskid_lwp_table[i].l_timeout_ch);
141: }
142:
143: free(tskid_lwp_table, M_KMEM);
144:
145: mutex_destroy(&spc_lock);
146:
147: return E_OK;
148: }
149:
150: static lwp_t*
151: get_lwp(ID tskid)
152: {
153: return &tskid_lwp_table[tskid - 1];
154: }
155:
156: lwp_t*
157: tkn_curlwp(void)
158: {
159: ID tskid = tk_get_tid();
160:
161: lwp_t* re = get_lwp(tskid);
162:
163: return re;
164: }
165:
166: 167: 168: 169: 170: 171:
172: int
173: uiomove(void *buf, size_t n, struct uio *uio)
174: {
175: #ifndef T2EX
176: struct vmspace *vm = uio->uio_vmspace;
177: #endif
178: struct iovec *iov;
179: size_t cnt;
180: int error = 0;
181: char *cp = buf;
182:
183: ASSERT_SLEEPABLE();
184:
185: #ifdef DIAGNOSTIC
186: if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)
187: panic("uiomove: mode");
188: #endif
189: while (n > 0 && uio->uio_resid) {
190: iov = uio->uio_iov;
191: cnt = iov->iov_len;
192: if (cnt == 0) {
193: KASSERT(uio->uio_iovcnt > 0);
194: uio->uio_iov++;
195: uio->uio_iovcnt--;
196: continue;
197: }
198: if (cnt > n)
199: cnt = n;
200: #ifndef T2EX
201: if (!VMSPACE_IS_KERNEL_P(vm)) {
202: if (curcpu()->ci_schedstate.spc_flags &
203: SPCF_SHOULDYIELD)
204: preempt();
205: }
206:
207: if (uio->uio_rw == UIO_READ) {
208: error = copyout_vmspace(vm, cp, iov->iov_base,
209: cnt);
210: } else {
211: error = copyin_vmspace(vm, iov->iov_base, cp,
212: cnt);
213: }
214: #else
215: if (uio->uio_rw == UIO_READ) {
216: error = copyout(cp, iov->iov_base, cnt);
217: } else {
218: error = copyin(iov->iov_base, cp, cnt);
219: }
220: #endif
221: if (error) {
222: break;
223: }
224: iov->iov_base = (char *)iov->iov_base + cnt;
225: iov->iov_len -= cnt;
226: uio->uio_resid -= cnt;
227: uio->uio_offset += cnt;
228: cp += cnt;
229: KDASSERT(cnt <= n);
230: n -= cnt;
231: }
232:
233: return (error);
234: }
235:
236: int
237: sys_select_us(struct lwp *l, const struct sys_select_us_args *uap, register_t *retval)
238: {
239: struct timeval tv;
240: struct sys_select_args a = {
241: .a = {
242: .nfds = SCARG(uap, nfds),
243: .readfds = SCARG(uap, readfds),
244: .writefds = SCARG(uap, writefds),
245: .exceptfds = SCARG(uap, exceptfds),
246: }
247: };
248:
249: if (SCARG(uap, tmout_u) == TMO_FEVR) {
250: a.a.tv = NULL;
251: }
252: else if (SCARG(uap, tmout_u) >= 0) {
253: tv.tv_sec = SCARG(uap, tmout_u) / 1000000;
254: tv.tv_usec = SCARG(uap, tmout_u) % 1000000;
255: a.a.tv = &tv;
256: }
257: else {
258: return EINVAL;
259: }
260:
261: return sys_select(l, &a, retval);
262: }
263:
264: int
265: sys_select_ms(struct lwp *l, const struct sys_select_ms_args *uap, register_t *retval)
266: {
267: struct timeval tv;
268: struct sys_select_args a = {
269: .a = {
270: .nfds = SCARG(uap, nfds),
271: .readfds = SCARG(uap, readfds),
272: .writefds = SCARG(uap, writefds),
273: .exceptfds = SCARG(uap, exceptfds),
274: }
275: };
276:
277: if (SCARG(uap, tmout) == TMO_FEVR) {
278: a.a.tv = NULL;
279: }
280: else if (SCARG(uap, tmout) >= 0) {
281: tv.tv_sec = SCARG(uap, tmout) / 1000;
282: tv.tv_usec = (SCARG(uap, tmout) % 1000) * 1000;
283: a.a.tv = &tv;
284: }
285: else {
286: return EINVAL;
287: }
288:
289: return sys_select(l, &a, retval);
290: }
291:
292: static char sys_hostname[MAXHOSTNAMELEN];
293:
294: int
295: sys_gethostname(struct lwp *l, const struct sys_gethostname_args *uap, register_t *retval)
296: {
297: ER ercd;
298:
299: (void)l;
300:
301: ercd = ChkSpaceRW(SCARG(uap, name), SCARG(uap, len));
302: if ( ercd < E_OK ) {
303: return EFAULT;
304: }
305:
306: strlcpy(SCARG(uap, name), sys_hostname, SCARG(uap, len));
307:
308: *retval = 0;
309: return 0;
310: }
311:
312: int
313: sys_sethostname(struct lwp *l, const struct sys_sethostname_args *uap, register_t *retval)
314: {
315: ER ercd;
316:
317: (void)l;
318:
319: ercd = ChkSpaceR(SCARG(uap, name), SCARG(uap, len));
320: if ( ercd < E_OK ) {
321: return EFAULT;
322: }
323:
324: if ( SCARG(uap, len) > MAXHOSTNAMELEN ) {
325: *retval = -1;
326: return EINVAL;
327: }
328:
329: strlcpy(sys_hostname, SCARG(uap, name), MAXHOSTNAMELEN);
330:
331: *retval = 0;
332: return 0;
333: }
334:
335: IMPORT int sockatmark(int s);
336: int
337: sys_sockatmark(struct lwp *l, const struct sys_sockatmark_args *uap, register_t *retval)
338: {
339: int re;
340:
341: (void)l;
342:
343: re = sockatmark(SCARG(uap, sd));
344: *retval = re;
345: return 0;
346: }
347:
348:
349:
350: 351: 352: 353: 354: 355:
356: static int do_sys_break_task(ID tskid)
357: {
358: int cnt = 0;
359:
360: if( get_lwp(tskid)->is_waiting != 0 ) {
361: tk_dis_wai(tskid, TTW_FLG | TTW_CAL | TTW_RDV );
362: cnt = 1;
363: }
364:
365: return cnt;
366: }
367:
368: int
369: sys_break(struct lwp *l, const struct sys_break_args *uap, register_t *retval)
370: {
371: 372: 373:
374: int tskid = SCARG(uap, tskid);
375: int cnt = 0;
376: int err = 0;
377: int i;
378: T_RTSK rtsk;
379:
380: (void)l;
381:
382: tk_dis_dsp();
383:
384: if(tskid == TSK_ALL) {
385: for(i=1; i<=tskid_lwp_table_maxid; i++) {
386: cnt += do_sys_break_task(tskid);
387: }
388: }
389: else {
390: err = tk_ref_tsk(tskid, &rtsk);
391: if ( err == E_OK ) {
392: cnt = do_sys_break_task(tskid);
393: }
394: }
395:
396: tk_ena_dsp();
397:
398: *retval = cnt;
399: return err;
400: }
401:
402: int
403: gettimeofday(struct timeval *tv, struct timezone *tz)
404: {
405: if (tz != NULL)
406: goto err_param;
407:
408: microtime(tv);
409:
410: return 0;
411:
412: err_param:
413: return EINVAL;
414: }
415:
416: static struct tkn_nif_info tkn_dev_info[TKN_NIFDEV_MAX];
417:
418: int
419: sys_ifattach(struct lwp *l, const struct sys_ifattach_args *uap, register_t *retval)
420: {
421: const char* devname = SCARG(uap, devnm);
422: int dev_num;
423: int error = 0;
424: int ret;
425: T_RDEV rdev;
426: struct tkn_nif_info *nif;
427:
428: (void)l;
429:
430: ret = ChkSpaceBstrR(devname, 0);
431: if ( ret < 0 ) {
432: return EFAULT;
433: }
434:
435: for (nif = tkn_nif_mng.nifm_list; nif; nif = nif->nif_next) {
436: if (strncmp((char*)nif->nif_dev, devname, TKN_NIFNAMESIZE) == 0) {
437: break;
438: }
439: }
440: if( nif != 0 ) {
441:
442: error = EBUSY;
443: goto error;
444: }
445:
446: ret = tk_ref_dev((UB*)devname, &rdev);
447: if (ret < 0) {
448: error = EINVAL;
449: goto error;
450: }
451:
452: dev_num = tkn_nif_mng.nifm_nifmax;
453: strncpy((char*)tkn_dev_info[dev_num].nif_dev, devname, TKN_NIFNAMESIZE);
454:
455: ret = tkn_nif_attach(&tkn_dev_info[dev_num]);
456: if (ret != 0) {
457: error = EINVAL;
458: }
459:
460: error:
461: *retval = 0;
462:
463: return error;
464: }
465:
466: int
467: sys_ifdetach(struct lwp *l, const struct sys_ifdetach_args *uap, register_t *retval)
468: {
469: const char* devname = SCARG(uap, devnm);
470: int error = 0;
471: int ret;
472: T_RDEV rdev;
473: struct tkn_nif_info *nif;
474:
475: (void)l;
476:
477: ret = ChkSpaceBstrR(devname, 0);
478: if ( ret < 0 ) {
479: return EFAULT;
480: }
481:
482: ret = tk_ref_dev((UB*)devname, &rdev);
483: if (ret < 0) {
484: error = EINVAL;
485: goto error;
486: }
487:
488: for (nif = tkn_nif_mng.nifm_list; nif != NULL; nif = nif->nif_next) {
489: if (strncmp((char*)nif->nif_dev, devname, TKN_NIFNAMESIZE) == 0) {
490: break;
491: }
492: }
493: if( nif == 0 ) {
494:
495: error = ENOENT;
496: goto error;
497: }
498:
499: ret = tkn_nif_detach(nif);
500: if (ret != 0) {
501: error = EINVAL;
502: }
503:
504: error:
505: *retval = 0;
506:
507: return error;
508: }
509:
510: int
511: sys_rtlist(struct lwp *l, const struct sys_rtlist_args *uap, register_t *retval)
512: {
513: int error;
514: size_t len;
515:
516: (void)l;
517:
518: if ( SCARG(uap, buf) != NULL ) {
519: error = ChkSpaceRW(SCARG(uap, buf), SCARG(uap, bufsz));
520: if ( error < E_OK ) {
521: return EFAULT;
522: }
523: }
524:
525: len = SCARG(uap, bufsz);
526: error = sysctl_rtable(SCARG(uap,af), SCARG(uap,cmd), SCARG(uap,flags),
527: SCARG(uap,buf), &len );
528:
529: if (error == 0) {
530: *retval = len;
531: }
532:
533: return error;
534: }
535:
536: int
537: sys_getifaddrs(struct lwp *l, const struct sys_getifaddrs_args *uap, register_t *retval)
538: {
539: int error;
540: size_t asize;
541:
542: (void)l;
543:
544: if ( SCARG(uap, buf) != NULL ) {
545: error = ChkSpaceRW(SCARG(uap, buf), SCARG(uap, bufsz));
546: if ( error < E_OK ) {
547: return EFAULT;
548: }
549: }
550:
551: error = getifaddrs(SCARG(uap,ifap), SCARG(uap,buf), SCARG(uap,bufsz),
552: &asize);
553:
554: if (error == 0) {
555: *retval = asize;
556: }
557:
558: return error;
559: }
560:
561: int
562: sys_ifindextoname(struct lwp *l, const struct sys_ifindextoname_args *uap, register_t *retval)
563: {
564: int error;
565:
566: (void)l;
567:
568: error = ChkSpaceBstrRW(SCARG(uap, ifname), 0);
569: if ( error < 0 ) {
570: return EFAULT;
571: }
572:
573: error = if_indextoname(SCARG(uap,ifindex), SCARG(uap,ifname));
574: if (error == 0) {
575: *retval = 0;
576: }
577:
578: return error;
579: }
580:
581: int
582: sys_ifnametoindex(struct lwp *l, const struct sys_ifnametoindex_args *uap, register_t *retval)
583: {
584: int error;
585: unsigned int ifindex;
586:
587: (void)l;
588:
589: error = ChkSpaceBstrR(SCARG(uap, ifname), 0);
590: if ( error < 0 ) {
591: return EFAULT;
592: }
593:
594: error = if_nametoindex(SCARG(uap,ifname), &ifindex);
595: if (error == 0) {
596: *retval = ifindex;
597: }
598:
599: return error;
600: }
601:
602: int sys_bpfopen(struct lwp *l, const struct sys_bpfopen_args *uap, register_t *retval)
603: {
604: int error;
605: struct file* fp;
606: int indx;
607:
608: error = ChkSpaceBstrR(SCARG(uap, path), 0);
609: if ( error < E_OK ) {
610: return EFAULT;
611: }
612:
613: if ((error = fd_allocfile(&fp, &indx)) != 0)
614: return (error);
615:
616: if ((error = tkn_bpf_open(SCARG(uap, path), SCARG(uap, oflag), fp)) != 0) {
617: fd_abort(l->l_proc, fp, indx);
618: if ((error == EDUPFD || error == EMOVEFD) &&
619: l->l_dupfd >= 0 &&
620: (error =
621: fd_dupopen(l->l_dupfd, &indx, SCARG(uap, oflag), error)) == 0) {
622: *retval = indx;
623: return (0);
624: }
625: if (error == ERESTART)
626: error = EINTR;
627: return (error);
628: }
629:
630: return ENOTSUP;
631: }
632:
633: int sys_tunopen(struct lwp *l, const struct sys_tunopen_args *uap, register_t *retval)
634: {
635: int error;
636: struct file* fp;
637: int indx;
638:
639: error = ChkSpaceBstrR(SCARG(uap, path), 0);
640: if ( error < E_OK ) {
641: return EFAULT;
642: }
643:
644: if ((error = fd_allocfile(&fp, &indx)) != 0)
645: return (error);
646:
647: if ((error = tkn_tun_open(SCARG(uap, path), SCARG(uap, oflag), fp)) != 0) {
648: fd_abort(l->l_proc, fp, indx);
649: if ((error == EDUPFD || error == EMOVEFD) &&
650: l->l_dupfd >= 0 &&
651: (error =
652: fd_dupopen(l->l_dupfd, &indx, SCARG(uap, oflag), error)) == 0) {
653: *retval = indx;
654: return (0);
655: }
656: if (error == ERESTART)
657: error = EINTR;
658: return (error);
659: }
660:
661: return ENOTSUP;
662: }