]>
Commit | Line | Data |
---|---|---|
1c79356b A |
1 | /* From ddp.c: |
2 | ||
3 | ddp_shrink_hdr() | |
4 | ddp_extend_hdr() | |
5 | ||
6 | Saved from xnu/bsd/bsd/netat/ddp.c on 4/14/99. | |
7 | */ | |
8 | ||
9 | #ifdef NOT_USED | |
10 | /* This routine shrinks the ddp header from long to short, | |
11 | * It also prepends ALAP header and fills up some of the | |
12 | * fields as appropriate. | |
13 | */ | |
14 | static at_ddp_short_t *ddp_shrink_hdr (mp) | |
15 | register gbuf_t *mp; | |
16 | { | |
17 | register at_ddp_t *ddp; | |
18 | register at_ddp_short_t *ddp_short; | |
19 | register at_llap_hdr_t *llap; | |
20 | gbuf_t *newmp; | |
21 | ||
22 | if ((newmp = (gbuf_t *)gbuf_copym((gbuf_t *) mp)) == (gbuf_t *)NULL) | |
23 | return ((at_ddp_short_t *)NULL); | |
24 | gbuf_freem(mp); | |
25 | mp = newmp; | |
26 | ||
27 | ddp = (at_ddp_t *)gbuf_rptr(mp); | |
28 | gbuf_rinc(mp,((DDP_X_HDR_SIZE - DDP_HDR_SIZE) - LLAP_HDR_SIZE)); | |
29 | llap = (at_llap_hdr_t *)gbuf_rptr(mp); | |
30 | ddp_short = (at_ddp_short_t *)(gbuf_rptr(mp) + LLAP_HDR_SIZE); | |
31 | ||
32 | llap->destination = ddp->dst_node; | |
33 | llap->type = LLAP_TYPE_DDP; | |
34 | ddp_short->length = ddp->length - (DDP_X_HDR_SIZE - DDP_HDR_SIZE); | |
35 | ddp_short->unused = 0; | |
36 | return ((at_ddp_short_t *)mp); | |
37 | } | |
38 | ||
39 | ||
40 | /* mp points to message of the form {llap, short ddp, ...}. | |
41 | * Get rid of llap, extend ddp header to make it of the form | |
42 | * {extended ddp, ... } | |
43 | */ | |
44 | static gbuf_t *ddp_extend_hdr(mp) | |
45 | register gbuf_t *mp; | |
46 | { | |
47 | register at_llap_hdr_t *llap; | |
48 | register at_ddp_short_t *ddp_short; | |
49 | register at_ddp_t *ddp; | |
50 | char buf[DDP_HDR_SIZE + LLAP_HDR_SIZE]; | |
51 | gbuf_t *m1, *m2; | |
52 | ||
53 | /* We need to remove the llap header from the packet and extend the | |
54 | * short DDP header in to a long one. 5 bytes of additional space | |
55 | * is required in effect, but we can not afford to put these 5 bytes | |
56 | * in a separate buffer, since the ddp buffer would end up being | |
57 | * fragmented into two pieces, which is a no-no. So, we first get | |
58 | * rid of the llap and ddp short headers and then add the extended | |
59 | * header. | |
60 | */ | |
61 | ||
62 | /* Assuming that the llap and ddp short headers are placed next | |
63 | * to each other in the same buffer | |
64 | */ | |
65 | bcopy(gbuf_rptr(mp), buf, LLAP_HDR_SIZE + DDP_HDR_SIZE); | |
66 | m1 = ddp_adjmsg(mp, LLAP_HDR_SIZE+DDP_HDR_SIZE) ? mp : 0; | |
67 | ||
68 | /* If the message did not contain any ddp data bytes, then m would | |
69 | * be NULL at this point... and we can't just grow a NULL message, | |
70 | * we need to ALLOC a new one. | |
71 | */ | |
72 | if (m1) { | |
73 | if ((m2 = (gbuf_t *)ddp_growmsg(m1, -DDP_X_HDR_SIZE)) == NULL) { | |
74 | dPrintf(D_M_DDP, D_L_WARNING, | |
75 | ("Dropping packet - no bufs to extend hdr")); | |
76 | at_ddp_stats.rcv_dropped_nobuf++; | |
77 | gbuf_freem(m1); | |
78 | return(NULL); | |
79 | } | |
80 | } else | |
81 | /* Original message mp has already been freed by ddp_adjmsg if we | |
82 | * managed to arrive here... this case occurs only when the | |
83 | * message mp did not contain any ddp data bytes, only lap and | |
84 | * ddp headers | |
85 | */ | |
86 | if ((m2 = gbuf_alloc(AT_WR_OFFSET+DDP_X_HDR_SIZE, PRI_MED)) == NULL) { | |
87 | dPrintf(D_M_DDP,D_L_WARNING, | |
88 | ("Packet (no data) dropped - no bufs to extend hdr")); | |
89 | at_ddp_stats.rcv_dropped_nobuf++; | |
90 | return(NULL); | |
91 | } else { | |
92 | gbuf_rinc(m2,AT_WR_OFFSET); | |
93 | gbuf_wset(m2,DDP_X_HDR_SIZE); | |
94 | } | |
95 | ||
96 | /* By the time we arrive here, m2 points to message of the form | |
97 | * {Extended DDP, ... } | |
98 | * mp and m1 are either non-existent or irrelevant. | |
99 | */ | |
100 | ddp = (at_ddp_t *)gbuf_rptr(m2); | |
101 | llap = (at_llap_hdr_t *)buf; | |
102 | ddp_short = (at_ddp_short_t *)(buf + LLAP_HDR_SIZE); | |
103 | ||
104 | ddp->unused = ddp->hopcount = 0; | |
105 | ddp->length = ddp_short->length + DDP_X_HDR_SIZE - DDP_HDR_SIZE; | |
106 | UAS_ASSIGN(ddp->checksum, 0); | |
107 | NET_NET(ddp->dst_net, ifID_home->ifThisNode.atalk_net); | |
108 | NET_NET(ddp->src_net, ifID_home->ifThisNode.atalk_net); | |
109 | ddp->src_node = llap->source; | |
110 | ddp->dst_node = llap->destination; | |
111 | ddp->dst_socket = ddp_short->dst_socket; | |
112 | ddp->src_socket = ddp_short->src_socket; | |
113 | ddp->type = ddp_short->type; | |
114 | return (m2); | |
115 | } | |
116 | #endif | |
117 | ||
118 | From sys_dep.c: | |
119 | ||
120 | #ifdef _AIX /* This AIX code (to the end of this file) is no longer supported. */ | |
121 | ||
122 | int ATsocket(proto) /* AIX version */ | |
123 | int proto; | |
124 | { | |
125 | int err, rc = -1; | |
126 | ||
127 | if (sys_ATsocket) | |
128 | rc = (*sys_ATsocket)(proto, &err, 0); | |
129 | else | |
130 | err = ENXIO; | |
131 | if (err) | |
132 | setuerror(err); | |
133 | return rc; | |
134 | } | |
135 | ||
136 | int ATgetmsg(fd, ctlptr, datptr, flags) /* AIX version */ | |
137 | int fd; | |
138 | void *ctlptr; | |
139 | void *datptr; | |
140 | int *flags; | |
141 | { | |
142 | int err, rc = -1; | |
143 | ||
144 | if (sys_ATgetmsg) | |
145 | rc = (*sys_ATgetmsg)(fd, ctlptr, datptr, flags, &err, 0); | |
146 | else | |
147 | err = ENXIO; | |
148 | if (err) | |
149 | setuerror(err); | |
150 | return rc; | |
151 | } | |
152 | ||
153 | int ATputmsg(fd, ctlptr, datptr, flags) /* AIX version */ | |
154 | int fd; | |
155 | void *ctlptr; | |
156 | void *datptr; | |
157 | int flags; | |
158 | { | |
159 | int err, rc = -1; | |
160 | ||
161 | if (sys_ATputmsg) | |
162 | rc = (*sys_ATputmsg)(fd, ctlptr, datptr, flags, &err, 0); | |
163 | else | |
164 | err = ENXIO; | |
165 | if (err) | |
166 | setuerror(err); | |
167 | return rc; | |
168 | } | |
169 | ||
170 | int ATPsndreq(fd, buf, len, nowait) /* AIX version */ | |
171 | int fd; | |
172 | unsigned char *buf; | |
173 | int len; | |
174 | int nowait; | |
175 | { | |
176 | int err, rc = -1; | |
177 | ||
178 | if (sys_ATPsndreq) | |
179 | rc = (*sys_ATPsndreq)(fd, buf, len, nowait, &err, 0); | |
180 | else | |
181 | err = ENXIO; | |
182 | if (err) | |
183 | setuerror(err); | |
184 | return rc; | |
185 | } | |
186 | ||
187 | int ATPsndrsp(fd, respbuff, resplen, datalen) /* AIX version */ | |
188 | int fd; | |
189 | unsigned char *respbuff; | |
190 | int resplen; | |
191 | int datalen; | |
192 | { | |
193 | int err, rc = -1; | |
194 | ||
195 | if (sys_ATPsndrsp) | |
196 | rc = (*sys_ATPsndrsp)(fd, respbuff, resplen, datalen, &err, 0); | |
197 | else | |
198 | err = ENXIO; | |
199 | if (err) | |
200 | setuerror(err); | |
201 | return rc; | |
202 | } | |
203 | ||
204 | int ATPgetreq(fd, buf, buflen) /* AIX version */ | |
205 | int fd; | |
206 | unsigned char *buf; | |
207 | int buflen; | |
208 | { | |
209 | int err, rc = -1; | |
210 | ||
211 | if (sys_ATPgetreq) | |
212 | rc = (*sys_ATPgetreq)(fd, buf, buflen, &err, 0); | |
213 | else | |
214 | err = ENXIO; | |
215 | if (err) | |
216 | setuerror(err); | |
217 | return rc; | |
218 | } | |
219 | ||
220 | int ATPgetrsp(fd, bdsp) /* AIX version */ | |
221 | int fd; | |
222 | unsigned char *bdsp; | |
223 | { | |
224 | int err, rc = -1; | |
225 | ||
226 | if (sys_ATPgetrsp) | |
227 | rc = (*sys_ATPgetrsp)(fd, bdsp, &err, 0); | |
228 | else | |
229 | err = ENXIO; | |
230 | if (err) | |
231 | setuerror(err); | |
232 | return rc; | |
233 | } | |
234 | ||
235 | void *atalk_kalloc(size) /* AIX version */ | |
236 | int size; | |
237 | { | |
238 | return (void *)xmalloc(size, 2, pinned_heap); | |
239 | } | |
240 | ||
241 | void atalk_kfree(buf) /* AIX version */ | |
242 | void *buf; | |
243 | { | |
244 | xmfree(buf, pinned_heap); | |
245 | } | |
246 | ||
247 | int atalk_closeref(fp, grefp) /* AIX version */ | |
248 | struct file *fp; | |
249 | gref_t **grefp; | |
250 | { | |
251 | *grefp = (gref_t *)fp->f_data; | |
252 | fp->f_data = 0; | |
253 | return 0; | |
254 | } | |
255 | ||
256 | int atalk_openref(gref, retfd, proc) /* AIX version */ | |
257 | gref_t *gref; | |
258 | int *retfd; | |
259 | void *proc; | |
260 | { | |
261 | extern int _ATrw(), _ATioctl(), _ATselect(), _ATclose(), _ATstat(); | |
262 | static struct fileops fileops = {_ATrw, _ATioctl, _ATselect, _ATclose, _ATstat}; | |
263 | int err, fd; | |
264 | struct file *fp; | |
265 | void *crp; | |
266 | ||
267 | crp = (void *)crref(); | |
268 | #ifdef _AIX | |
269 | if ((err = ufdcreate(FREAD|FWRITE, | |
270 | &fileops, 0, DTYPE_OTHER, &fd, crp)) != 0) | |
271 | #else | |
272 | if ((err = ufdcreate(FREAD|FWRITE, | |
273 | &fileops, 0, DTYPE_ATALK, &fd, crp)) != 0) | |
274 | #endif | |
275 | return err; | |
276 | *retfd = fd; | |
277 | fp = U.U_ufd[fd].fp; | |
278 | fp->f_data = (void *)gref; | |
279 | gref->next = (void *)fp; | |
280 | return 0; | |
281 | } | |
282 | ||
283 | int atalk_getref(fp, fd, grefp, proc) /* AIX version */ | |
284 | struct file *fp; | |
285 | int fd; | |
286 | gref_t **grefp; | |
287 | struct proc *proc; | |
288 | { | |
289 | if (fp == 0) { | |
290 | if ((fd < 0) || (fd > U.U_maxofile) || ((fp = U.U_ufd[fd].fp) == 0)) { | |
291 | *grefp = (gref_t *)0; | |
292 | return EBADF; | |
293 | } | |
294 | } | |
295 | if ((*grefp = (gref_t *)fp->f_data) == 0) | |
296 | return EBADF; | |
297 | return 0; | |
298 | } | |
299 | ||
300 | gbuf_t *gbuf_alloc(size, pri) /* AIX version */ | |
301 | int size; | |
302 | int pri; | |
303 | { | |
304 | gbuf_t *m; | |
305 | ||
306 | m = (size > MHLEN) ? (gbuf_t *)m_getclustm(M_DONTWAIT, MSG_DATA, size) | |
307 | : (gbuf_t *)m_gethdr(M_DONTWAIT, MSG_DATA); | |
308 | #ifdef APPLETALK_DEBUG | |
309 | kprintf("gbuf_alloc: for size = %d m=%x\n", size, m); | |
310 | #endif | |
311 | gbuf_next(m) = 0; | |
312 | gbuf_cont(m) = 0; | |
313 | gbuf_wset(m,0); | |
314 | return m; | |
315 | } | |
316 | ||
317 | void gbuf_freeb(m) /* AIX version */ | |
318 | gbuf_t *m; | |
319 | { | |
320 | if (m) | |
321 | m_free(m); | |
322 | } | |
323 | ||
324 | static struct trb *trb_freehead = 0; | |
325 | static struct trb *trb_freetail = 0; | |
326 | static struct trb *trb_pendhead = 0; | |
327 | static int trb_cnt = 0; | |
328 | static atlock_t trb_lock; | |
329 | ||
330 | static void atalk_rem_timeoutcf() /* AIX version */ | |
331 | { | |
332 | register int s; | |
333 | register struct trb *trb; | |
334 | register struct trb *tmp_freehead, *tmp_pendhead; | |
335 | ||
336 | ATDISABLE(s, trb_lock); | |
337 | tmp_freehead = trb_freehead; | |
338 | trb_freehead = 0; | |
339 | tmp_pendhead = trb_pendhead; | |
340 | trb_pendhead = 0; | |
341 | trb_cnt = 0; | |
342 | ATENABLE(s, trb_lock); | |
343 | while ((trb = tmp_pendhead) != 0) { | |
344 | tmp_pendhead = trb->to_next; | |
345 | while (tstop(trb)); | |
346 | tfree(trb); | |
347 | } | |
348 | while ((trb = tmp_freehead) != 0) { | |
349 | tmp_freehead = trb->to_next; | |
350 | tfree(trb); | |
351 | } | |
352 | dPrintf(D_M_ATP,D_L_ERROR, "atalk: timer stopped!\n",0,0,0,0,0); | |
353 | } | |
354 | ||
355 | static void atalk_timeoutcf(cnt) /* AIX version */ | |
356 | int cnt; | |
357 | { | |
358 | register int i; | |
359 | register struct trb *trb; | |
360 | ||
361 | if (trb_freehead == 0) { | |
362 | for (i=0; i < cnt-1; i++) { | |
363 | trb = (struct trb *)talloc(); | |
364 | trb->to_next = trb_freehead; | |
365 | trb_freehead = trb; | |
366 | if (!i) trb_freetail = trb; | |
367 | trb_cnt++; | |
368 | } | |
369 | } | |
370 | ATLOCKINIT(trb_lock); | |
371 | } | |
372 | ||
373 | static void atalk_clock(trb) /* AIX version */ | |
374 | register struct trb *trb; | |
375 | { | |
376 | register int s; | |
377 | register struct trb *next; | |
378 | void (*tof)(); | |
379 | void *arg; | |
380 | ||
381 | ATDISABLE(s, trb_lock); | |
382 | if (trb_pendhead && trb->func) { | |
383 | /* | |
384 | * remove the timeout from the pending queue | |
385 | */ | |
386 | if (trb_pendhead == trb) | |
387 | trb_pendhead = trb->to_next; | |
388 | else { | |
389 | for (next=trb_pendhead; next->to_next; next=next->to_next) { | |
390 | if (next->to_next == trb) { | |
391 | next->to_next = trb->to_next; | |
392 | trb->func = 0; | |
393 | break; | |
394 | } | |
395 | } | |
396 | if (trb->func) { | |
397 | dPrintf(D_M_ATP,D_L_WARNING, | |
398 | "atalk_clock: %d,%x,%x\n", trb_cnt,trb,trb_pendhead,0,0); | |
399 | /* | |
400 | * we have not found the trb in the pending list - something | |
401 | * has gone wrong here. maybe the trb has been returned to | |
402 | * the free list; in which case, we should simply ignore | |
403 | * this timeout event! | |
404 | */ | |
405 | for (next=trb_freehead; next; next=next->to_next) { | |
406 | if (next == trb) | |
407 | { | |
408 | ATENABLE(s, trb_lock); | |
409 | return; | |
410 | } | |
411 | } | |
412 | /* | |
413 | * the trb is not in the free list either - something has | |
414 | * really gone wacky here! all we can do now is put the | |
415 | * trb back into the free list and hope that it will be ok. | |
416 | */ | |
417 | trb->to_next = 0; | |
418 | if (trb_freehead) | |
419 | trb_freetail->to_next = trb; | |
420 | else | |
421 | trb_freehead = trb; | |
422 | trb_freetail = trb; | |
423 | trb_cnt++; | |
424 | ATENABLE(s, trb_lock); | |
425 | return; | |
426 | } | |
427 | } | |
428 | ||
429 | /* | |
430 | * process the timeout | |
431 | */ | |
432 | trb->func = 0; | |
433 | trb->to_next = 0; | |
434 | tof = trb->tof; | |
435 | trb->tof = 0; | |
436 | arg = (void *)trb->func_data; | |
437 | trb->func_data = 999; | |
438 | if (trb_freehead) | |
439 | trb_freetail->to_next = trb; | |
440 | else | |
441 | trb_freehead = trb; | |
442 | trb_freetail = trb; | |
443 | trb_cnt++; | |
444 | ATENABLE(s, trb_lock); | |
445 | if (tof) { | |
446 | dPrintf(D_M_ATP,D_L_VERBOSE, "atalk_clock: func=%x, arg=%x, %d\n", | |
447 | tof,arg,trb_cnt,0,0); | |
448 | (*tof)(arg); | |
449 | } else { | |
450 | dPrintf(D_M_ATP,D_L_ERROR, "atalk_clock: func=%x, arg=%x, %d\n", | |
451 | tof,arg,trb_cnt,0,0); | |
452 | } | |
453 | } else | |
454 | ATENABLE(s, trb_lock); | |
455 | } | |
456 | ||
457 | void *atalk_timeout(func, arg, ticks) /* AIX version */ | |
458 | void (*func)(); | |
459 | void *arg; | |
460 | int ticks; | |
461 | { | |
462 | register int s; | |
463 | register struct trb *trb; | |
464 | ||
465 | dPrintf(D_M_ATP,D_L_VERBOSE, | |
466 | "atalk_timeout: func=%x,arg=%x,time=%d, %d,%x\n", func,arg,ticks,trb_cnt,trb_pendhead); | |
467 | /* | |
468 | * set up the timeout request | |
469 | */ | |
470 | ATDISABLE(s, trb_lock); | |
471 | if ((trb = trb_freehead) == 0) { | |
472 | ATENABLE(s, trb_lock); | |
473 | dPrintf(D_M_ATP,D_L_WARNING, | |
474 | "atalk_timeout: NO TRB! time=%d, %d\n", ticks,trb_cnt,0,0,0); | |
475 | return 0; | |
476 | } | |
477 | trb_freehead = trb->to_next; | |
478 | trb->to_next = trb_pendhead; | |
479 | trb_pendhead = trb; | |
480 | trb_cnt--; | |
481 | trb->timeout.it_value.tv_sec = ticks / HZ; | |
482 | trb->timeout.it_value.tv_nsec = (ticks % HZ) * (NS_PER_SEC / HZ); | |
483 | trb->knext = 0; | |
484 | trb->kprev = 0; | |
485 | trb->flags = 0; | |
486 | trb->tof = func; | |
487 | trb->func = (void (*)())atalk_clock; | |
488 | trb->func_data = (ulong)arg; | |
489 | trb->ipri = PL_IMP; | |
490 | trb->id = -1; | |
491 | ||
492 | /* | |
493 | * start the timeout | |
494 | */ | |
495 | ATENABLE(s, trb_lock); | |
496 | tstart(trb); | |
497 | return (void *)trb; | |
498 | } | |
499 | ||
500 | void atalk_untimeout(func, arg, trb) /* AIX version */ | |
501 | void (*func)(); | |
502 | void *arg; | |
503 | register struct trb *trb; | |
504 | { | |
505 | register int s; | |
506 | register struct trb *next; | |
507 | ||
508 | dPrintf(D_M_ATP,D_L_VERBOSE, | |
509 | "atalk_untimeout: func=%x,arg=%x, %d\n", func,arg,trb_cnt,0,0); | |
510 | ||
511 | ATDISABLE(s, trb_lock); | |
512 | if (trb == 0) { | |
513 | for (trb=trb_pendhead; trb; trb=trb->to_next) { | |
514 | if ((func == trb->tof) && (arg == (void *)trb->func_data)) | |
515 | break; | |
516 | } | |
517 | } | |
518 | if (trb && (trb->func == (void (*)())atalk_clock) | |
519 | && (func == trb->tof) && (arg == (void *)trb->func_data)) { | |
520 | trb->func_data = 999; | |
521 | if (!(trb->flags & T_PENDING)) | |
522 | { | |
523 | trb->tof = 0; | |
524 | ATENABLE(s, trb_lock); | |
525 | return; | |
526 | } | |
527 | trb->func = 0; | |
528 | while (tstop(trb)); | |
529 | if (trb_pendhead == trb) | |
530 | trb_pendhead = trb->to_next; | |
531 | else { | |
532 | for (next=trb_pendhead; next->to_next != trb; next=next->to_next) { | |
533 | if (next->to_next == 0) { | |
534 | ATENABLE(s, trb_lock); | |
535 | dPrintf(D_M_ATP,D_L_WARNING, | |
536 | "atalk_untimeout: UNKNOWN TRB %x...\n",trb,0,0,0,0); | |
537 | return; | |
538 | } | |
539 | } | |
540 | next->to_next = trb->to_next; | |
541 | } | |
542 | trb->to_next = 0; | |
543 | trb_freetail->to_next = trb; | |
544 | trb_freetail = trb; | |
545 | trb_cnt++; | |
546 | } | |
547 | ATENABLE(s, trb_lock); | |
548 | } | |
549 | ||
550 | int config_atalk(dev, cmd, uiop) /* AIX only */ | |
551 | dev_t dev; | |
552 | int cmd; | |
553 | void *uiop; | |
554 | { | |
555 | static int loaded = 0; | |
556 | int err, nest; | |
557 | ||
558 | err = 0; | |
559 | nest = lockl(&kernel_lock, LOCK_SHORT); | |
560 | ||
561 | if (cmd == CFG_INIT) { | |
562 | if (loaded) | |
563 | goto out; | |
564 | vm_protect(0, 4096, 3); | |
565 | atalk_timeoutcf(256); | |
566 | atalk_load(); | |
567 | loaded = 1; | |
568 | ||
569 | } else if (cmd == CFG_TERM) { | |
570 | if (!loaded) | |
571 | goto out; | |
572 | atalk_rem_timeoutcf(); | |
573 | atalk_unload(); | |
574 | loaded = 0; | |
575 | ||
576 | } else | |
577 | err = EINVAL; | |
578 | ||
579 | out: | |
580 | if (nest != LOCK_NEST) | |
581 | unlockl(&kernel_lock); | |
582 | return(err); | |
583 | } | |
584 | ||
585 | #endif | |
586 | ||
587 | From sys_glue.c: | |
588 | ||
589 | #ifdef _AIX /* AIX code, to the end of this file, is no longer supported. */ | |
590 | ||
591 | int _ATselect(fp, corl, reqevents, retevents, notify) /* AIX version */ | |
592 | void *fp; | |
593 | int corl; | |
594 | unsigned short reqevents; | |
595 | unsigned short *retevents; | |
596 | void (*notify)(); | |
597 | { | |
598 | int s, err, rc = 0; | |
599 | gref_t *gref; | |
600 | unsigned short sevents = 0; | |
601 | ||
602 | if ((err = atalk_getref(fp, 0, &gref, 0)) != 0) | |
603 | return err; | |
604 | ||
605 | ATDISABLE(s, gref->lock); | |
606 | if (reqevents & POLLIN) { | |
607 | if (gref->rdhead || (gref->readable && (*gref->readable)(gref))) | |
608 | sevents |= POLLIN; | |
609 | } | |
610 | ||
611 | if (reqevents & POLLOUT) { | |
612 | if (gref->writeable) { | |
613 | if ((*gref->writeable)(gref)) | |
614 | sevents |= POLLOUT; | |
615 | } else | |
616 | sevents |= POLLOUT; | |
617 | } | |
618 | ||
619 | if ((sevents == 0) && ((reqevents & POLLSYNC) == 0)) { | |
620 | if (rc = selreg(corl, 99, gref, reqevents, notify)) { | |
621 | ATENABLE(s, gref->lock); | |
622 | goto l_done; | |
623 | } | |
624 | ||
625 | if (reqevents & POLLIN) { | |
626 | if (gref->rdhead || (gref->readable && (*gref->readable)(gref))) | |
627 | sevents |= POLLIN; | |
628 | else | |
629 | gref->sevents |= POLLIN; | |
630 | } | |
631 | ||
632 | if (reqevents & POLLOUT) { | |
633 | if (gref->writeable) { | |
634 | if ((*gref->writeable)(gref)) | |
635 | sevents |= POLLOUT; | |
636 | else | |
637 | gref->sevents |= POLLOUT; | |
638 | } else | |
639 | sevents |= POLLOUT; | |
640 | } | |
641 | } | |
642 | ATENABLE(s, gref->lock); | |
643 | *retevents = sevents; | |
644 | ||
645 | l_done: | |
646 | return rc; | |
647 | } | |
648 | #endif /* end AIX section */ | |
649 | ||
650 | From drv_dep.c: | |
651 | ||
652 | ||
653 | ||
654 | ||
655 | #ifdef _AIX | |
656 | /* AIX section to end of file (not supported) */ | |
657 | ||
658 | /* from beginning of file ... */ | |
659 | #include <sys/cdli.h> | |
660 | #include <sys/ndd.h> | |
661 | static struct ns_8022 elap_link; /* The SNAP header description */ | |
662 | static struct ns_user elap_user; /* The interface to the demuxer */ | |
663 | ||
664 | int | |
665 | pat_ifpresent(name) /* AIX */ | |
666 | char *name; | |
667 | { | |
668 | return (int)ifunit(name); | |
669 | } | |
670 | ||
671 | int | |
672 | pat_output(pat_id, mlist, dst_addr, type) /* AIX */ | |
673 | int pat_id; | |
674 | gbuf_t *mlist; | |
675 | unsigned char *dst_addr; | |
676 | int type; | |
677 | { | |
678 | int len; | |
679 | pat_unit_t *patp; | |
680 | gbuf_t *m, *m_prev, *new_mlist, *m_temp; | |
681 | struct ndd *nddp; | |
682 | short size; | |
683 | enet_header_t *enet_header; | |
684 | llc_header_t *llc_header; | |
685 | ||
686 | patp = (pat_unit_t *)&pat_units[pat_id]; | |
687 | if (patp->state != PAT_ONLINE) { | |
688 | gbuf_freel(mlist); | |
689 | return ENOTREADY; | |
690 | } | |
691 | ||
692 | if (patp->xtype == IFTYPE_NULLTALK) { | |
693 | gbuf_freel(mlist); | |
694 | return 0; | |
695 | } | |
696 | ||
697 | nddp = (void *)patp->nddp; | |
698 | new_mlist = 0; | |
699 | ||
700 | for (m = mlist; m; m = mlist) { | |
701 | mlist = gbuf_next(m); | |
702 | gbuf_next(m) = 0; | |
703 | ||
704 | gbuf_prepend(m,ENET_LLC_SIZE); | |
705 | if (m == 0) { | |
706 | if (mlist) | |
707 | gbuf_freel(mlist); | |
708 | if (new_mlist) | |
709 | gbuf_freel(new_mlist); | |
710 | return 0; | |
711 | } | |
712 | ||
713 | enet_header = (enet_header_t *)gbuf_rptr(m); | |
714 | bcopy(dst_addr, enet_header->dst, sizeof(enet_header->dst)); | |
715 | bcopy(patp->xaddr, enet_header->src, sizeof(enet_header->src)); | |
716 | size = gbuf_msgsize(m); | |
717 | enet_header->len = size - sizeof(enet_header_t); | |
718 | llc_header = (llc_header_t *)(gbuf_rptr(m)+sizeof(enet_header_t)); | |
719 | *llc_header = (type == AARP_AT_TYPE) ? snap_hdr_aarp : snap_hdr_at; | |
720 | ||
721 | m->m_pkthdr.len = size; | |
722 | m->m_pkthdr.rcvif = 0; | |
723 | ||
724 | if (new_mlist) | |
725 | gbuf_next(m_prev) = m; | |
726 | else | |
727 | new_mlist = m; | |
728 | m_prev = m; | |
729 | pktsOut++; | |
730 | } | |
731 | ||
732 | if (new_mlist) | |
733 | (*nddp->ndd_output)(nddp, new_mlist); | |
734 | ||
735 | return 0; | |
736 | } | |
737 | ||
738 | int | |
739 | pat_online (ifName, ifType) /* AIX */ | |
740 | char *ifName; | |
741 | char *ifType; | |
742 | { | |
743 | void pat_input(); | |
744 | int pat_id; | |
745 | pat_unit_t *patp; | |
746 | struct ndd *nddp; | |
747 | char ns_name[8]; | |
748 | ||
749 | if ((pat_id = pat_ID(ifName)) == -1) | |
750 | return (-1); | |
751 | patp = &pat_units[pat_id]; | |
752 | ||
753 | if (patp->xtype == IFTYPE_ETHERTALK) { | |
754 | ns_name[0] = ifName[0]; | |
755 | ns_name[1] = 'n'; | |
756 | strcpy(&ns_name[2], &ifName[1]); | |
757 | } else if (patp->xtype == IFTYPE_NULLTALK) { | |
758 | patp->xaddrlen = 6; | |
759 | bzero(patp->xaddr, patp->xaddrlen); | |
760 | if (ifType) | |
761 | *ifType = patp->xtype; | |
762 | patp->nddp = (void *)0; | |
763 | patp->state = PAT_ONLINE; | |
764 | at_statep->flags |= AT_ST_IF_CHANGED; | |
765 | return (pat_id); | |
766 | } else | |
767 | return -1; | |
768 | ||
769 | if (ns_alloc(ns_name, &nddp)) | |
770 | return -1; | |
771 | ||
772 | bzero(&elap_user, sizeof(elap_user)); | |
773 | elap_user.isr = pat_input; | |
774 | elap_user.pkt_format = NS_HANDLE_HEADERS|NS_INCLUDE_MAC; | |
775 | ||
776 | elap_link.filtertype = NS_8022_LLC_DSAP_SNAP; | |
777 | elap_link.orgcode[0] = 0; | |
778 | elap_link.orgcode[2] = 0; | |
779 | elap_link.dsap = DSAP_SNAP; | |
780 | elap_link.ethertype = 0x80f3; /* AARP SNAP code */ | |
781 | if (ns_add_filter(nddp, &elap_link, sizeof(elap_link), &elap_user)) | |
782 | return -1; | |
783 | ||
784 | elap_link.orgcode[0] = 0x08; | |
785 | elap_link.orgcode[2] = 0x07; | |
786 | elap_link.ethertype = 0x809b; /* DDP SNAP code */ | |
787 | if (ns_add_filter(nddp, &elap_link, sizeof(elap_link), &elap_user)) { | |
788 | elap_link.orgcode[0] = 0; | |
789 | elap_link.orgcode[2] = 0; | |
790 | elap_link.ethertype = 0x80f3; /* AARP SNAP code */ | |
791 | (void)ns_del_filter(nddp, &elap_link, sizeof(elap_link)); | |
792 | return -1; | |
793 | } | |
794 | ||
795 | patp->xaddrlen = nddp->ndd_addrlen; | |
796 | bcopy(nddp->ndd_physaddr, patp->xaddr, patp->xaddrlen); | |
797 | ||
798 | if (ifType) | |
799 | *ifType = patp->xtype; | |
800 | ||
801 | patp->nddp = (void *)nddp; | |
802 | patp->state = PAT_ONLINE; | |
803 | at_statep->flags |= AT_ST_IF_CHANGED; | |
804 | ||
805 | return (pat_id); | |
806 | } | |
807 | ||
808 | void | |
809 | pat_offline(pat_id) /* AIX */ | |
810 | int pat_id; | |
811 | { | |
812 | pat_unit_t *patp = &pat_units[pat_id]; | |
813 | ||
814 | if (patp->state == PAT_ONLINE) { | |
815 | if (patp->xtype != IFTYPE_NULLTALK) { | |
816 | elap_link.filtertype = NS_8022_LLC_DSAP_SNAP; | |
817 | elap_link.orgcode[0] = 0; | |
818 | elap_link.orgcode[2] = 0; | |
819 | elap_link.dsap = DSAP_SNAP; | |
820 | elap_link.ethertype = 0x80f3; /* AARP SNAP code */ | |
821 | (void)ns_del_filter(patp->nddp, &elap_link, sizeof(elap_link)); | |
822 | elap_link.orgcode[0] = 0x08; | |
823 | elap_link.orgcode[2] = 0x07; | |
824 | elap_link.ethertype = 0x809b; /* DDP SNAP code */ | |
825 | (void)ns_del_filter(patp->nddp, &elap_link, sizeof(elap_link)); | |
826 | ns_free(patp->nddp); | |
827 | } | |
828 | at_statep->flags |= AT_ST_IF_CHANGED; | |
829 | bzero(patp, sizeof(pat_unit_t)); | |
830 | } | |
831 | } | |
832 | ||
833 | int | |
834 | pat_mcast(pat_id, control, data) /* AIX */ | |
835 | int pat_id; | |
836 | int control; | |
837 | unsigned char *data; | |
838 | { | |
839 | struct ndd *nddp; | |
840 | ||
841 | nddp = (struct ndd *)pat_units[pat_id].nddp; | |
842 | return (*nddp->ndd_ctl)(nddp, (control == PAT_REG_MCAST) ? | |
843 | NDD_ENABLE_ADDRESS : NDD_DISABLE_ADDRESS, | |
844 | data, nddp->ndd_addrlen); | |
845 | } | |
846 | ||
847 | void | |
848 | pat_input(nddp, m, unused) /* AIX */ | |
849 | struct ndd *nddp; | |
850 | gbuf_t *m; | |
851 | void *unused; | |
852 | { | |
853 | extern int ddprunning_flag; | |
854 | llc_header_t *llc_header; | |
855 | int pat_id; | |
856 | pat_unit_t *patp; | |
857 | char src[6]; | |
858 | enet_header_t *enet_header = (enet_header_t *)gbuf_rptr(m); | |
859 | ||
860 | for (pat_id=0, patp = &pat_units[pat_id]; | |
861 | pat_id < xpatcnt; pat_id++, patp++) { | |
862 | if ((patp->state == PAT_ONLINE) && (patp->nddp == nddp)) | |
863 | break; | |
864 | } | |
865 | if (pat_id == xpatcnt) { | |
866 | gbuf_freem(m); | |
867 | return; | |
868 | } | |
869 | ||
870 | /* Ignore multicast packets from local station */ | |
871 | if (patp->xtype == IFTYPE_ETHERTALK) { | |
872 | bcopy((char *)enet_header->src, src, sizeof(src)); | |
873 | if ((enet_header->dst[0] & 1) && | |
874 | (bcmp(src, patp->xaddr, sizeof(src)) == 0)) { | |
875 | gbuf_freem(m); | |
876 | return; | |
877 | } | |
878 | llc_header = (llc_header_t *)(enet_header+1); | |
879 | } | |
880 | ||
881 | gbuf_rinc(m,(ENET_LLC_SIZE)); | |
882 | (void)fetch_and_add((atomic_p)&ddprunning_flag, 1); | |
883 | pktsIn++; | |
884 | if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_aarp)) { | |
885 | patp->aarp_func(gbuf_rptr(m), patp->context); | |
886 | gbuf_freem(m); | |
887 | } else if (LLC_PROTO_EQUAL(llc_header->protocol,snap_proto_ddp)) { | |
888 | /* if we're a router take all pkts */ | |
889 | if (!ROUTING_MODE) { | |
890 | if (patp->addr_check(gbuf_rptr(m), patp->context) | |
891 | == AARP_ERR_NOT_OURS) { | |
892 | gbuf_freem(m); | |
893 | (void)fetch_and_add((atomic_p)&ddprunning_flag, -1); | |
894 | return; | |
895 | } | |
896 | } | |
897 | gbuf_set_type(m, MSG_DATA); | |
898 | elap_input(m, patp->context, src); | |
899 | } else | |
900 | gbuf_freem(m); | |
901 | (void)fetch_and_add((atomic_p)&ddprunning_flag, -1); | |
902 | } | |
903 | #endif /* AIX */ |