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