FreeBSD/Linux Kernel Cross Reference
sys/netiso/tp_inet.c
1 /* $NetBSD: tp_inet.c,v 1.26 2003/08/22 21:53:11 itojun Exp $ */
2
3 /*-
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. 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. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)tp_inet.c 8.1 (Berkeley) 6/10/93
32 */
33
34 /***********************************************************
35 Copyright IBM Corporation 1987
36
37 All Rights Reserved
38
39 Permission to use, copy, modify, and distribute this software and its
40 documentation for any purpose and without fee is hereby granted,
41 provided that the above copyright notice appear in all copies and that
42 both that copyright notice and this permission notice appear in
43 supporting documentation, and that the name of IBM not be
44 used in advertising or publicity pertaining to distribution of the
45 software without specific, written prior permission.
46
47 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
48 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
49 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
50 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
51 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
52 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
53 SOFTWARE.
54
55 ******************************************************************/
56
57 /*
58 * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
59 */
60 /*
61 * Here is where you find the inet-dependent code. We've tried keep all
62 * net-level and (primarily) address-family-dependent stuff out of the tp
63 * source, and everthing here is reached indirectly through a switch table
64 * (struct nl_protosw *) tpcb->tp_nlproto (see tp_pcb.c). The routines here
65 * are: in_getsufx: gets transport suffix out of an inpcb structure.
66 * in_putsufx: put transport suffix into an inpcb structure. in_putnetaddr:
67 * put a whole net addr into an inpcb. in_getnetaddr: get a whole net addr
68 * from an inpcb. in_cmpnetaddr: compare a whole net addr from an isopcb.
69 * in_recycle_suffix: clear suffix for reuse in inpcb tpip_mtu: figure out
70 * what size tpdu to use tpip_input: take a pkt from ip, strip off its ip
71 * header, give to tp tpip_output_dg: package a pkt for ip given 2 addresses
72 * & some data tpip_output: package a pkt for ip given an inpcb & some data
73 */
74
75 #include <sys/cdefs.h>
76 __KERNEL_RCSID(0, "$NetBSD: tp_inet.c,v 1.26 2003/08/22 21:53:11 itojun Exp $");
77
78 #include "opt_inet.h"
79 #include "opt_iso.h"
80
81 #ifdef INET
82
83 #include <sys/param.h>
84 #include <sys/socket.h>
85 #include <sys/socketvar.h>
86 #include <sys/mbuf.h>
87 #include <sys/errno.h>
88 #include <sys/time.h>
89 #include <sys/systm.h>
90
91 #include <net/if.h>
92
93 #include <netiso/tp_param.h>
94 #include <netiso/argo_debug.h>
95 #include <netiso/tp_stat.h>
96 #include <netiso/tp_ip.h>
97 #include <netiso/tp_pcb.h>
98 #include <netiso/tp_trace.h>
99 #include <netiso/tp_stat.h>
100 #include <netiso/tp_tpdu.h>
101 #include <netiso/tp_var.h>
102 #include <netinet/in_var.h>
103
104 #ifndef ISO
105 #include <netiso/iso_chksum.c>
106 #endif
107
108 #include <machine/stdarg.h>
109
110 /*
111 * NAME: in_getsufx()
112 *
113 * CALLED FROM: pr_usrreq() on PRU_BIND,
114 * PRU_CONNECT, PRU_ACCEPT, and PRU_PEERADDR
115 *
116 * FUNCTION, ARGUMENTS, and RETURN VALUE:
117 * Get a transport suffix from an inpcb structure (inp).
118 * The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
119 *
120 * RETURNS: internet port / transport suffix
121 * (CAST TO AN INT)
122 *
123 * SIDE EFFECTS:
124 *
125 * NOTES:
126 */
127 void
128 in_getsufx(v, lenp, data_out, which)
129 void *v;
130 u_short *lenp;
131 caddr_t data_out;
132 int which;
133 {
134 struct inpcb *inp = v;
135 *lenp = sizeof(u_short);
136 switch (which) {
137 case TP_LOCAL:
138 *(u_short *) data_out = inp->inp_lport;
139 return;
140
141 case TP_FOREIGN:
142 *(u_short *) data_out = inp->inp_fport;
143 }
144
145 }
146
147 /*
148 * NAME: in_putsufx()
149 *
150 * CALLED FROM: tp_newsocket(); i.e., when a connection
151 * is being established by an incoming CR_TPDU.
152 *
153 * FUNCTION, ARGUMENTS:
154 * Put a transport suffix (found in name) into an inpcb structure (inp).
155 * The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
156 *
157 * RETURNS: Nada
158 *
159 * SIDE EFFECTS:
160 *
161 * NOTES:
162 */
163 /* ARGSUSED */
164 void
165 in_putsufx(v, sufxloc, sufxlen, which)
166 void *v;
167 caddr_t sufxloc;
168 int sufxlen;
169 int which;
170 {
171 struct inpcb *inp = v;
172 if (which == TP_FOREIGN) {
173 bcopy(sufxloc, (caddr_t) & inp->inp_fport, sizeof(inp->inp_fport));
174 }
175 }
176
177 /*
178 * NAME: in_recycle_tsuffix()
179 *
180 * CALLED FROM: tp.trans whenever we go into REFWAIT state.
181 *
182 * FUNCTION and ARGUMENT:
183 * Called when a ref is frozen, to allow the suffix to be reused.
184 * (inp) is the net level pcb.
185 *
186 * RETURNS: Nada
187 *
188 * SIDE EFFECTS:
189 *
190 * NOTES: This really shouldn't have to be done in a NET level pcb
191 * but... for the internet world that just the way it is done in BSD...
192 * The alternative is to have the port unusable until the reference
193 * timer goes off.
194 */
195 void
196 in_recycle_tsuffix(v)
197 void *v;
198 {
199 struct inpcb *inp = v;
200 inp->inp_fport = inp->inp_lport = 0;
201 }
202
203 /*
204 * NAME: in_putnetaddr()
205 *
206 * CALLED FROM:
207 * tp_newsocket(); i.e., when a connection is being established by an
208 * incoming CR_TPDU.
209 *
210 * FUNCTION and ARGUMENTS:
211 * Copy a whole net addr from a struct sockaddr (name).
212 * into an inpcb (inp).
213 * The argument (which) takes values TP_LOCAL or TP_FOREIGN
214 *
215 * RETURNS: Nada
216 *
217 * SIDE EFFECTS:
218 *
219 * NOTES:
220 */
221 void
222 in_putnetaddr(v, nm, which)
223 void *v;
224 struct sockaddr *nm;
225 int which;
226 {
227 struct inpcb *inp = v;
228 struct sockaddr_in *name = (struct sockaddr_in *) nm;
229 switch (which) {
230 case TP_LOCAL:
231 bcopy((caddr_t) & name->sin_addr,
232 (caddr_t) & inp->inp_laddr, sizeof(struct in_addr));
233 /* won't work if the dst address (name) is INADDR_ANY */
234
235 break;
236 case TP_FOREIGN:
237 if (name != (struct sockaddr_in *) 0) {
238 bcopy((caddr_t) & name->sin_addr,
239 (caddr_t) & inp->inp_faddr, sizeof(struct in_addr));
240 }
241 }
242 }
243
244 /*
245 * NAME: in_cmpnetaddr()
246 *
247 * CALLED FROM:
248 * tp_input() when a connection is being established by an
249 * incoming CR_TPDU, and considered for interception.
250 *
251 * FUNCTION and ARGUMENTS:
252 * Compare a whole net addr from a struct sockaddr (name),
253 * with that implicitly stored in an inpcb (inp).
254 * The argument (which) takes values TP_LOCAL or TP_FOREIGN
255 *
256 * RETURNS: Nada
257 *
258 * SIDE EFFECTS:
259 *
260 * NOTES:
261 */
262 int
263 in_cmpnetaddr(v, nm, which)
264 void *v;
265 struct sockaddr *nm;
266 int which;
267 {
268 struct inpcb *inp = v;
269 struct sockaddr_in *name = (struct sockaddr_in *) nm;
270 if (which == TP_LOCAL) {
271 if (name->sin_port && name->sin_port != inp->inp_lport)
272 return 0;
273 return (name->sin_addr.s_addr == inp->inp_laddr.s_addr);
274 }
275 if (name->sin_port && name->sin_port != inp->inp_fport)
276 return 0;
277 return (name->sin_addr.s_addr == inp->inp_faddr.s_addr);
278 }
279
280 /*
281 * NAME: in_getnetaddr()
282 *
283 * CALLED FROM:
284 * pr_usrreq() PRU_SOCKADDR, PRU_ACCEPT, PRU_PEERADDR
285 * FUNCTION and ARGUMENTS:
286 * Copy a whole net addr from an inpcb (inp) into
287 * an mbuf (name);
288 * The argument (which) takes values TP_LOCAL or TP_FOREIGN.
289 *
290 * RETURNS: Nada
291 *
292 * SIDE EFFECTS:
293 *
294 * NOTES:
295 */
296
297 void
298 in_getnetaddr(v, name, which)
299 void *v;
300 struct mbuf *name;
301 int which;
302 {
303 struct inpcb *inp = v;
304 struct sockaddr_in *sin = mtod(name, struct sockaddr_in *);
305 bzero((caddr_t) sin, sizeof(*sin));
306 switch (which) {
307 case TP_LOCAL:
308 sin->sin_addr = inp->inp_laddr;
309 sin->sin_port = inp->inp_lport;
310 break;
311 case TP_FOREIGN:
312 sin->sin_addr = inp->inp_faddr;
313 sin->sin_port = inp->inp_fport;
314 break;
315 default:
316 return;
317 }
318 name->m_len = sin->sin_len = sizeof(*sin);
319 sin->sin_family = AF_INET;
320 }
321
322 /*
323 * NAME: tpip_mtu()
324 *
325 * CALLED FROM:
326 * tp_route_to() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT
327 *
328 * FUNCTION, ARGUMENTS, and RETURN VALUE:
329 *
330 * Perform subnetwork dependent part of determining MTU information.
331 * It appears that setting a double pointer to the rtentry associated with
332 * the destination, and returning the header size for the network protocol
333 * suffices.
334 *
335 * SIDE EFFECTS:
336 * Sets tp_routep pointer in pcb.
337 *
338 * NOTES:
339 */
340 int
341 tpip_mtu(v)
342 void *v;
343 {
344 struct tp_pcb *tpcb = v;
345 struct inpcb *inp = (struct inpcb *) tpcb->tp_npcb;
346
347 #ifdef ARGO_DEBUG
348 if (argo_debug[D_CONN]) {
349 printf("tpip_mtu(tpcb %p)\n", tpcb);
350 printf("tpip_mtu routing to addr 0x%x\n", inp->inp_faddr.s_addr);
351 }
352 #endif
353 tpcb->tp_routep = &(inp->inp_route.ro_rt);
354 return (sizeof(struct ip));
355
356 }
357
358 /*
359 * NAME: tpip_output()
360 *
361 * CALLED FROM: tp_emit()
362 *
363 * FUNCTION and ARGUMENTS:
364 * Take a packet(m0) from tp and package it so that ip will accept it.
365 * This means prepending space for the ip header and filling in a few
366 * of the fields.
367 * inp is the inpcb structure; datalen is the length of the data in the
368 * mbuf string m0.
369 * RETURNS:
370 * whatever (E*) is returned form the net layer output routine.
371 *
372 * SIDE EFFECTS:
373 *
374 * NOTES:
375 */
376
377 int
378 #if __STDC__
379 tpip_output(struct mbuf *m0, ...)
380 #else
381 tpip_output(m0, va_alist)
382 struct mbuf *m0;
383 va_dcl
384 #endif
385 {
386 int datalen;
387 struct inpcb *inp;
388 int nochksum;
389 va_list ap;
390
391 va_start(ap, m0);
392 datalen = va_arg(ap, int);
393 inp = va_arg(ap, struct inpcb *);
394 nochksum = va_arg(ap, int);
395 va_end(ap);
396
397 return tpip_output_dg(m0, datalen, &inp->inp_laddr, &inp->inp_faddr,
398 &inp->inp_route, nochksum);
399 }
400
401 /*
402 * NAME: tpip_output_dg()
403 *
404 * CALLED FROM: tp_error_emit()
405 *
406 * FUNCTION and ARGUMENTS:
407 * This is a copy of tpip_output that takes the addresses
408 * instead of a pcb. It's used by the tp_error_emit, when we
409 * don't have an in_pcb with which to call the normal output rtn.
410 *
411 * RETURNS: ENOBUFS or whatever (E*) is
412 * returned form the net layer output routine.
413 *
414 * SIDE EFFECTS:
415 *
416 * NOTES:
417 */
418
419 /* ARGSUSED */
420 int
421 #if __STDC__
422 tpip_output_dg(struct mbuf *m0, ...)
423 #else
424 tpip_output_dg(m0, va_alist)
425 struct mbuf *m0;
426 va_dcl
427 #endif
428 {
429 int datalen;
430 struct in_addr *laddr, *faddr;
431 struct route *ro;
432 int nochksum;
433 struct mbuf *m;
434 struct ip *ip;
435 int error;
436 va_list ap;
437
438 va_start(ap, m0);
439 datalen = va_arg(ap, int);
440 laddr = va_arg(ap, struct in_addr *);
441 faddr = va_arg(ap, struct in_addr *);
442 ro = va_arg(ap, struct route *);
443 nochksum = va_arg(ap, int);
444 va_end(ap);
445
446 #ifdef ARGO_DEBUG
447 if (argo_debug[D_EMIT]) {
448 printf("tpip_output_dg datalen 0x%x m0 %p\n", datalen, m0);
449 }
450 #endif
451
452
453 MGETHDR(m, M_DONTWAIT, TPMT_IPHDR);
454 if (m == 0) {
455 error = ENOBUFS;
456 goto bad;
457 }
458 m->m_next = m0;
459 MH_ALIGN(m, sizeof(struct ip));
460 m->m_len = sizeof(struct ip);
461
462 ip = mtod(m, struct ip *);
463 bzero((caddr_t) ip, sizeof *ip);
464
465 ip->ip_p = IPPROTO_TP;
466 if (sizeof(struct ip) + datalen > IP_MAXPACKET) {
467 error = EMSGSIZE;
468 goto bad;
469 }
470 m->m_pkthdr.len = sizeof(struct ip) + datalen;
471 ip->ip_len = htons(sizeof(struct ip) + datalen);
472 ip->ip_ttl = MAXTTL;
473 /*
474 * don't know why you need to set ttl; overlay doesn't even make this
475 * available
476 */
477
478 ip->ip_src = *laddr;
479 ip->ip_dst = *faddr;
480
481 IncStat(ts_tpdu_sent);
482 #ifdef ARGO_DEBUG
483 if (argo_debug[D_EMIT]) {
484 dump_mbuf(m, "tpip_output_dg before ip_output\n");
485 }
486 #endif
487
488 error = ip_output(m, (struct mbuf *) 0, ro, IP_ALLOWBROADCAST,
489 (struct ip_moptions *)NULL, (struct socket *)NULL);
490
491 #ifdef ARGO_DEBUG
492 if (argo_debug[D_EMIT]) {
493 printf("tpip_output_dg after ip_output\n");
494 }
495 #endif
496
497 return error;
498
499 bad:
500 m_freem(m);
501 IncStat(ts_send_drop);
502 return error;
503 }
504
505 /*
506 * NAME: tpip_input()
507 *
508 * CALLED FROM:
509 * ip's input routine, indirectly through the protosw.
510 *
511 * FUNCTION and ARGUMENTS:
512 * Take a packet (m) from ip, strip off the ip header and give it to tp
513 *
514 * RETURNS: No return value.
515 *
516 * SIDE EFFECTS:
517 *
518 * NOTES:
519 */
520 void
521 #if __STDC__
522 tpip_input(struct mbuf *m, ...)
523 #else
524 tpip_input(m, va_alist)
525 struct mbuf *m;
526 va_dcl
527 #endif
528 {
529 int iplen;
530 struct sockaddr_in src, dst;
531 struct ip *ip;
532 int s = splsoftnet(), hdrlen;
533 va_list ap;
534
535 va_start(ap, m);
536 iplen = va_arg(ap, int);
537 va_end(ap);
538
539 IncStat(ts_pkt_rcvd);
540
541 /*
542 * IP layer has already pulled up the IP header,
543 * but the first byte after the IP header may not be there,
544 * e.g. if you came in via loopback, so you have to do an
545 * m_pullup to before you can even look to see how much you
546 * really need. The good news is that m_pullup will round
547 * up to almost the next mbuf's worth.
548 */
549
550
551 if ((m = m_pullup(m, iplen + 1)) == NULL)
552 goto discard;
553 CHANGE_MTYPE(m, TPMT_DATA);
554
555 /*
556 * Now pull up the whole tp header:
557 * Unfortunately, there may be IP options to skip past so we
558 * just fetch it as an unsigned char.
559 */
560 hdrlen = iplen + 1 + mtod(m, u_char *)[iplen];
561
562 if (m->m_len < hdrlen) {
563 if ((m = m_pullup(m, hdrlen)) == NULL) {
564 #ifdef ARGO_DEBUG
565 if (argo_debug[D_TPINPUT]) {
566 printf("tp_input, pullup 2!\n");
567 }
568 #endif
569 goto discard;
570 }
571 }
572 /*
573 * cannot use tp_inputprep() here 'cause you don't have quite the
574 * same situation
575 */
576
577 #ifdef ARGO_DEBUG
578 if (argo_debug[D_TPINPUT]) {
579 dump_mbuf(m, "after tpip_input both pullups");
580 }
581 #endif
582 /*
583 * m_pullup may have returned a different mbuf
584 */
585 ip = mtod(m, struct ip *);
586
587 /*
588 * drop the ip header from the front of the mbuf
589 * this is necessary for the tp checksum
590 */
591 m->m_len -= iplen;
592 m->m_data += iplen;
593
594 src.sin_addr = *(struct in_addr *) & (ip->ip_src);
595 src.sin_family = AF_INET;
596 src.sin_len = sizeof(src);
597 dst.sin_addr = *(struct in_addr *) & (ip->ip_dst);
598 dst.sin_family = AF_INET;
599 dst.sin_len = sizeof(dst);
600
601 tp_input(m, sintosa(&src), sintosa(&dst), 0, tpip_output_dg, 0);
602 return;
603
604 discard:
605 #ifdef ARGO_DEBUG
606 if (argo_debug[D_TPINPUT]) {
607 printf("tpip_input DISCARD\n");
608 }
609 #endif
610 #ifdef TPPT
611 if (tp_traceflags[D_TPINPUT]) {
612 tptrace(TPPTmisc, "tpip_input DISCARD m", m, 0, 0, 0);
613 }
614 #endif
615 m_freem(m);
616 IncStat(ts_recv_drop);
617 splx(s);
618 }
619
620
621 #include <sys/protosw.h>
622 #include <netinet/ip_icmp.h>
623
624 /*
625 * NAME: tpin_quench()
626 *
627 * CALLED FROM: tpip_ctlinput()
628 *
629 * FUNCTION and ARGUMENTS: find the tpcb pointer and pass it to tp_quench
630 *
631 * RETURNS: Nada
632 *
633 * SIDE EFFECTS:
634 *
635 * NOTES:
636 */
637
638 void
639 tpin_quench(inp, dummy)
640 struct inpcb *inp;
641 int dummy;
642 {
643 tp_quench((struct inpcb *) inp->inp_socket->so_pcb, PRC_QUENCH);
644 }
645
646 /*
647 * NAME: tpip_ctlinput()
648 *
649 * CALLED FROM:
650 * The network layer through the protosw table.
651 *
652 * FUNCTION and ARGUMENTS:
653 * When clnp gets an ICMP msg this gets called.
654 * It either returns an error status to the user or
655 * causes all connections on this address to be aborted
656 * by calling the appropriate xx_notify() routine.
657 * (cmd) is the type of ICMP error.
658 * (sa) the address of the sender
659 *
660 * RETURNS: Nothing
661 *
662 * SIDE EFFECTS:
663 *
664 * NOTES:
665 */
666 void *
667 tpip_ctlinput(cmd, sa, dummy)
668 int cmd;
669 struct sockaddr *sa;
670 void *dummy;
671 {
672 void (*notify) __P((struct inpcb *, int));
673 int errno;
674
675 if ((unsigned)cmd >= PRC_NCMDS)
676 return NULL;
677 errno = inetctlerrmap[cmd];
678 switch (cmd) {
679
680 case PRC_QUENCH:
681 notify = tp_quench;
682 break;
683
684 case PRC_ROUTEDEAD:
685 case PRC_HOSTUNREACH:
686 case PRC_UNREACH_NET:
687 case PRC_IFDOWN:
688 case PRC_HOSTDEAD:
689 notify = in_rtchange;
690 break;
691
692 default:
693 /*
694 case PRC_MSGSIZE:
695 case PRC_UNREACH_HOST:
696 case PRC_UNREACH_PROTOCOL:
697 case PRC_UNREACH_PORT:
698 case PRC_UNREACH_NEEDFRAG:
699 case PRC_UNREACH_SRCFAIL:
700 case PRC_REDIRECT_NET:
701 case PRC_REDIRECT_HOST:
702 case PRC_REDIRECT_TOSNET:
703 case PRC_REDIRECT_TOSHOST:
704 case PRC_TIMXCEED_INTRANS:
705 case PRC_TIMXCEED_REASS:
706 case PRC_PARAMPROB:
707 */
708 notify = tpin_abort;
709 break;
710 }
711 in_pcbnotifyall(&tp_inpcb, satosin(sa)->sin_addr, errno, notify);
712 return NULL;
713 }
714
715 /*
716 * NAME: tpin_abort()
717 *
718 * CALLED FROM:
719 * xxx_notify() from tp_ctlinput() when
720 * net level gets some ICMP-equiv. type event.
721 *
722 * FUNCTION and ARGUMENTS:
723 * Cause the connection to be aborted with some sort of error
724 * reason indicating that the network layer caused the abort.
725 * Fakes an ER TPDU so we can go through the driver.
726 *
727 * RETURNS: Nothing
728 *
729 * SIDE EFFECTS:
730 *
731 * NOTES:
732 */
733
734 void
735 tpin_abort(inp, n)
736 struct inpcb *inp;
737 int n;
738 {
739 struct tp_event e;
740
741 e.ev_number = ER_TPDU;
742 e.TPDU_ATTR(ER).e_reason = ENETRESET;
743 tp_driver((struct tp_pcb *) inp->inp_ppcb, &e);
744 }
745
746 #ifdef ARGO_DEBUG
747 void
748 dump_inaddr(addr)
749 struct sockaddr_in *addr;
750 {
751 printf("INET: port 0x%x; addr 0x%x\n", addr->sin_port, addr->sin_addr.s_addr);
752 }
753 #endif /* ARGO_DEBUG */
754 #endif /* INET */
Cache object: 327b5aba2dc6ffe3ee986dfc2e4d65fd
|