source: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_subr.c@ 321

Last change on this file since 321 was 321, checked in by coas-nagasima, 7 years ago

文字コードを設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 17.4 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
5 * Tomakomai National College of Technology, JAPAN
6 *
7 * 上記著作権者は,以下の (1)~(4) の条件か,Free Software Foundation
8 * によって公表されている GNU General Public License の Version 2 に記
9 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
10 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
11 * 利用と呼ぶ)することを無償で許諾する.
12 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
13 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
14 * スコード中に含まれていること.
15 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
16 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
17 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
18 * の無保証規定を掲載すること.
19 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
20 * 用できない形で再配布する場合には,次の条件を満たすこと.
21 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
22 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 *
26 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
27 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
28 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
29 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
30 *
31 * @(#) $Id$
32 */
33
34/*
35 * Copyright (c) 1982, 1986, 1988, 1993
36 * The Regents of the University of California. All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by the University of
49 * California, Berkeley and its contributors.
50 * 4. Neither the name of the University nor the names of its contributors
51 * may be used to endorse or promote products derived from this software
52 * without specific prior written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * SUCH DAMAGE.
65 */
66
67#include <string.h>
68
69#ifdef TARGET_KERNEL_ASP
70
71#include <kernel.h>
72#include <sil.h>
73#include <t_syslog.h>
74#include "kernel_cfg.h"
75
76#endif /* of #ifdef TARGET_KERNEL_ASP */
77
78#ifdef TARGET_KERNEL_JSP
79
80#include <s_services.h>
81#include <t_services.h>
82#include "kernel_id.h"
83
84#endif /* of #ifdef TARGET_KERNEL_JSP */
85
86#include <tinet_defs.h>
87#include <tinet_config.h>
88
89#include <net/if.h>
90#include <net/if_loop.h>
91#include <net/if_ppp.h>
92#include <net/ethernet.h>
93#include <net/ppp_ipcp.h>
94#include <net/net.h>
95#include <net/net_var.h>
96#include <net/net_buf.h>
97#include <net/net_timer.h>
98
99#include <netinet/in.h>
100#include <netinet6/in6.h>
101#include <netinet/in_var.h>
102#include <netinet/in_itron.h>
103#include <netinet/ip.h>
104#include <netinet/ip_var.h>
105#include <netinet/tcp_timer.h>
106
107#include <net/if_var.h>
108
109#if defined(SUPPORT_INET4)
110
111/*
112 * in4_get_ifaddr -- インタフェースに設定されているアドレスを返す。
113 */
114
115const T_IN4_ADDR *
116in4_get_ifaddr (int_t index)
117{
118 T_IFNET *ifp = IF_GET_IFNET();
119
120 return &ifp->in_ifaddr.addr;
121 }
122
123/*
124 * ip2str -- IPv4 アドレスを文字列に変換する。
125 */
126
127char *
128ip2str (char *buf, const T_IN4_ADDR *ipaddr)
129{
130 static char addr_sbuf[NUM_IPV4ADDR_STR_BUFF][sizeof("123.123.123.123")];
131 static int_t bix = NUM_IPV4ADDR_STR_BUFF;
132
133 char *start;
134
135 if (buf == NULL) {
136 syscall(wai_sem(SEM_IP2STR_BUFF_LOCK));
137 buf = addr_sbuf[-- bix];
138 if (bix <= 0)
139 bix = NUM_IPV4ADDR_STR_BUFF;
140 syscall(sig_sem(SEM_IP2STR_BUFF_LOCK));
141 }
142
143 start = buf;
144 buf += convert_hexdigit(buf, (uint_t)((*ipaddr >> 24) & 0xff), 10, 0, ' ');
145 *(buf ++) = '.';
146 buf += convert_hexdigit(buf, (uint_t)((*ipaddr >> 16) & 0xff), 10, 0, ' ');
147 *(buf ++) = '.';
148 buf += convert_hexdigit(buf, (uint_t)((*ipaddr >> 8) & 0xff), 10, 0, ' ');
149 *(buf ++) = '.';
150 buf += convert_hexdigit(buf, (uint_t)((*ipaddr ) & 0xff), 10, 0, ' ');
151 *buf = '\0';
152 return start;
153 }
154
155/*
156 * in4_set_header -- IPv4 ヘッダを設定する。
157 */
158
159ER
160in4_set_header (T_NET_BUF *nbuf, uint_t len,
161 T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr, uint8_t proto, uint8_t ttl)
162{
163 T_IP4_HDR *ip4h = GET_IP4_HDR(nbuf);
164 T_IFNET *ifp = IF_GET_IFNET();
165
166 /* IP ヘッダを設定する。*/
167 ip4h->vhl = IP4_MAKE_VHL(IPV4_VERSION, IP4_HDR_SIZE >> 2);
168 ip4h->len = htons(IP4_HDR_SIZE + len);
169 ip4h->proto = proto;
170 ip4h->ttl = ttl;
171 ip4h->type = 0;
172 ip4h->id = ip4h->flg_off = ip4h->sum = 0;
173
174 /* IP アドレスを設定する。*/
175 ip4h->dst = htonl(*dstaddr);
176
177 if (srcaddr == NULL || *srcaddr == IPV4_ADDRANY)
178 ip4h->src = htonl(ifp->in_ifaddr.addr);
179 else
180 ip4h->src = htonl(*srcaddr);
181
182 return E_OK;
183 }
184
185/*
186 * in4_get_datagram -- IPv4 データグラムを獲得し、ヘッダを設定する。
187 */
188
189ER
190in4_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
191 T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr,
192 uint8_t proto, uint8_t ttl, ATR nbatr, TMO tmout)
193{
194 ER error;
195 uint_t align;
196
197 /* データ長を 4 オクテット境界に調整する。*/
198 align = (len + 3) >> 2 << 2;
199
200 /* ネットワークバッファを獲得する。*/
201 if ((error = tget_net_buf_ex(nbuf, (uint_t)(IF_IP4_HDR_SIZE + align),
202 (uint_t)(IF_IP4_HDR_SIZE + maxlen), nbatr, tmout)) != E_OK)
203 return error;
204
205 /*
206 * より大きなサイズのネットワークバッファを獲得する場合のみ長さを調整する。
207 * より小さなサイズのネットワークバッファの獲得は、送信ウィンドバッファの
208 * 省コピー機能で使用され、実際に送信するまで、データサイズは決定できない。
209 */
210 if ((nbatr & NBA_SEARCH_ASCENT) != 0)
211 (*nbuf)->len = (uint16_t)(IF_IP4_HDR_SIZE + len);
212
213 /* IP ヘッダを設定する。*/
214 if ((error = in4_set_header(*nbuf, len, dstaddr, srcaddr, proto, ttl)) != E_OK)
215 return error;
216
217 /* 4 オクテット境界までパディングで埋める。*/
218 if (align > len)
219 memset((GET_IP4_SDU(*nbuf) + len), 0, (size_t)(align - len));
220
221 return E_OK;
222 }
223
224/*
225 * in4_cksum -- IPv4 のトランスポート層ヘッダのチェックサムを計算する。
226 *
227 * 注意: 戻り値はネットワークバイトオーダ
228 */
229
230uint16_t
231in4_cksum (T_NET_BUF *nbuf, uint8_t proto, uint_t off, uint_t len)
232{
233 uint32_t sum;
234 uint_t align;
235
236 /* 4 オクテット境界のデータ長 */
237 align = (len + 3) >> 2 << 2;
238
239 /* 4 オクテット境界までパディングで埋める。*/
240 if (align > len)
241 memset((uint8_t*)nbuf->buf + off + len, 0, (size_t)(align - len));
242
243 sum = in_cksum_sum(nbuf->buf + off, align)
244 + in_cksum_sum(&GET_IP4_HDR(nbuf)->src, sizeof(T_IN4_ADDR) * 2)
245 + len + proto;
246 sum = in_cksum_carry(sum);
247
248 return (uint16_t)(~htons((uint16_t)sum));
249 }
250
251/*
252 * in_cksum -- チェックサム計算関数、IPv4、ICMPv4 用
253 *
254 * 注意: data は 4 オクテット単位でパディングすること。
255 * data が 2 オクテット単位にアラインされていないと
256 * 例外が発生する可能性がある。
257 * len は 4 オクテット単位にアラインされていること。
258 *
259 * 戻り値はネットワークバイトオーダ
260 */
261
262uint16_t
263in_cksum (void *data, uint_t len /*オクテット単位*/)
264{
265 uint16_t sum;
266
267 sum = (uint16_t)in_cksum_carry(in_cksum_sum(data, len));
268 return (uint16_t)(~htons(sum));
269 }
270
271/*
272 * in4_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
273 *
274 * 注意: dstaddr は、
275 * TINET-1.2 からネットワークバイトオーダ、
276 * TINET-1.1 までは、ホストバイトオーダ
277 */
278
279bool_t
280in4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr)
281{
282 if (*myaddr == IPV4_ADDRANY)
283 return ntohl(*dstaddr) == IF_GET_IFNET()->in_ifaddr.addr;
284 else
285 return ntohl(*dstaddr) == *myaddr;
286 }
287
288/*
289 * in4_ifawithifp -- 宛先アドレスにふさわしい送信元アドレスを、
290 * ネットワークインタフェースから探索する。
291 * in6_ifawithifp をシミュレートするだけで、
292 * エラーを返すことはない。
293 */
294
295T_IN4_IFADDR *
296in4_ifawithifp (T_IFNET *ifp, T_IN4_ADDR *dst)
297{
298 return &ifp->in_ifaddr;
299 }
300
301/*
302 * in4_add_ifaddr -- インタフェースに IPv4 アドレスを設定する。
303 */
304
305ER
306in4_add_ifaddr (T_IN4_ADDR addr, T_IN4_ADDR mask)
307{
308 T_IFNET *ifp = IF_GET_IFNET();
309
310 ifp->in_ifaddr.addr = addr;
311 ifp->in_ifaddr.mask = mask;
312 return E_OK;
313 }
314
315#if NUM_ROUTE_ENTRY > 0
316
317/*
318 * in4_add_route -- 経路表にエントリを設定する。
319 */
320
321ER
322in4_add_route (int_t index, T_IN4_ADDR target, T_IN4_ADDR mask, T_IN4_ADDR gateway)
323{
324
325 if (0 <= index && index < NUM_STATIC_ROUTE_ENTRY) {
326 routing_tbl[index].target = target;
327 routing_tbl[index].mask = mask;
328 routing_tbl[index].gateway = gateway;
329 return E_OK;
330 }
331 else
332 return E_PAR;
333 }
334
335#endif /* of #if NUM_ROUTE_ENTRY > 0 */
336
337/*
338 * in4_rtalloc -- ルーティング表を探索する。
339 */
340
341T_IN4_ADDR
342in4_rtalloc (T_IN4_ADDR dst)
343{
344 int_t ix;
345
346 for (ix = NUM_ROUTE_ENTRY; ix --; )
347 if ((routing_tbl[ix].flags & IN_RTF_DEFINED) &&
348 (dst & routing_tbl[ix].mask) == routing_tbl[ix].target) {
349 if (routing_tbl[ix].gateway == 0)
350 return dst;
351 else {
352 return routing_tbl[ix].gateway;
353 }
354 }
355 return dst;
356 }
357
358#if NUM_REDIRECT_ROUTE_ENTRY > 0
359
360/*
361 * in4_rtredirect -- ルーティング表にエントリを登録する。
362 *
363 * 注意: 引数 tmo の単位は [ms]。
364 */
365
366void
367in4_rtredirect (T_IN4_ADDR gateway, T_IN4_ADDR target, uint8_t flags, uint32_t tmo)
368{
369 T_IN_RTENTRY *frt;
370
371 frt = in_rtnewentry(flags, tmo);
372 frt->gateway = gateway;
373 frt->target = target;
374 frt->mask = 0xffffffff;
375 }
376
377#endif /* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
378
379/*
380 * in4_timer -- IPv4 共通タイマー
381 *
382 * 1秒周期で起動される。
383 */
384
385static void
386in4_timer (void *ignore)
387{
388#if NUM_REDIRECT_ROUTE_ENTRY > 0
389
390 in_rttimer();
391
392#endif /* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
393
394#ifdef IP4_CFG_FRAGMENT
395
396 ip_frag_timer();
397
398#endif /* of #ifdef IP4_CFG_FRAGMENT */
399
400 timeout(in4_timer, NULL, IN_TIMER_TMO);
401 }
402
403/*
404 * in4_init -- IPv4 共通機能を初期化する。
405 */
406
407void
408in4_init (void)
409{
410#if NUM_REDIRECT_ROUTE_ENTRY > 0
411
412 in_rtinit();
413
414#endif /* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
415
416 timeout(in4_timer, NULL, IN_TIMER_TMO);
417 }
418
419#endif /* of #if defined(SUPPORT_INET4) */
420
421#if NUM_REDIRECT_ROUTE_ENTRY > 0
422
423/*
424 * in_rtinit -- ルーティング表を初期化する。
425 */
426
427void
428in_rtinit (void)
429{
430 int_t ix;
431
432 for (ix = 0; ix < NUM_STATIC_ROUTE_ENTRY; ix ++)
433 routing_tbl[ix].flags = IN_RTF_DEFINED;
434
435 for ( ; ix < NUM_ROUTE_ENTRY; ix ++)
436 routing_tbl[ix].flags = 0;
437 }
438
439/*
440 * in_rtnewentry -- 新しいエントリを獲得する。
441 */
442
443T_IN_RTENTRY *
444in_rtnewentry (uint8_t flags, uint32_t tmo)
445{
446 SYSTIM now;
447 T_IN_RTENTRY *rt, *frt = NULL;
448 int_t ix;
449
450 /* 空きエントリを探す。*/
451 for (ix = NUM_STATIC_ROUTE_ENTRY; ix < NUM_ROUTE_ENTRY; ix ++) {
452 rt = &routing_tbl[ix];
453 if ((routing_tbl[ix].flags & IN_RTF_DEFINED) == 0) {
454 frt = rt;
455 break;
456 }
457 }
458
459 /* expire の単位は [s]。*/
460 syscall(get_tim(&now));
461 now /= SYSTIM_HZ;
462
463 if (frt == NULL) {
464 /* 空きがなければ、有効時間がもっとも短いエントリを空きにする。*/
465 T_IN_RTENTRY *srt = NULL;
466 int_t diff, sdiff = INT_MAX;
467
468 syscall(wai_sem(SEM_IN_ROUTING_TBL));
469 for (ix = NUM_STATIC_ROUTE_ENTRY; ix < NUM_ROUTE_ENTRY; ix ++) {
470 rt = &routing_tbl[ix];
471 diff = (int_t)(rt->expire - now);
472 if (diff <= 0) { /* rt->expire <= now */
473 /* 既に、有効時間が過ぎている。*/
474 frt = rt;
475 break;
476 }
477 else if (diff < sdiff) {
478 srt = rt;
479 sdiff = diff;
480 }
481 }
482 if (frt == NULL)
483 frt = srt;
484 frt->flags = 0;
485 syscall(sig_sem(SEM_IN_ROUTING_TBL));
486 }
487
488 frt->flags = (uint8_t)(flags | IN_RTF_DEFINED);
489 frt->expire = now + tmo / SYSTIM_HZ;
490 return frt;
491 }
492
493/*
494 * in_rttimer -- ルーティング表の管理タイマー
495 */
496
497void
498in_rttimer (void)
499{
500 SYSTIM now;
501 int_t ix;
502
503 /* expire の単位は [s]。*/
504 syscall(get_tim(&now));
505 now /= SYSTIM_HZ;
506
507 syscall(wai_sem(SEM_IN_ROUTING_TBL));
508 for (ix = NUM_STATIC_ROUTE_ENTRY; ix < NUM_ROUTE_ENTRY; ix ++)
509 if ((routing_tbl[ix].flags & IN_RTF_DEFINED) &&
510 (int_t)(routing_tbl[ix].expire - now) <= 0)
511 routing_tbl[ix].flags = 0;
512 syscall(sig_sem(SEM_IN_ROUTING_TBL));
513 }
514
515#endif /* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
516
517/*
518 * in_cksum_sum -- チェックサムの合計計算関数
519 *
520 * 注意: data は 4 オクテット単位でパディングすること。
521 * data が 2 オクテット単位にアラインされていないと
522 * 例外が発生する可能性がある。
523 * len は 4 オクテット単位にアラインされていること。
524 *
525 * 戻り値はホストバイトオーダ
526 */
527
528uint32_t
529in_cksum_sum (void *data, uint_t len /*オクテット単位*/)
530{
531 uint32_t sum = 0;
532
533 for ( ; len > 0; len -= 2) {
534 sum += *((uint16_t*)data);
535 data = (uint8_t*)data + 2;
536 }
537
538#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
539 return sum;
540#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN
541 return ((sum >> 8) & 0xffff) + ((sum & 0xff) << 8) + ((sum >> 24) & 0xff);
542#endif /* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
543
544 }
545
546/*
547 * in_cksum_carry -- チェックサムの桁上げ計算関数
548 *
549 * 注意: data は 4 オクテット単位でパディングすること。
550 * data が 2 オクテット単位にアラインされていないと
551 * 例外が発生する可能性がある。
552 * len は 4 オクテット単位にアラインされていること。
553 */
554
555uint32_t
556in_cksum_carry (uint32_t sum)
557{
558 uint32_t carry;
559
560 while (sum >= 0x00010000) {
561 carry = sum >> 16;
562 sum = (sum & 0xffff) + carry;
563 }
564
565 return sum;
566 }
567
568/*
569 * in_strtfn -- API 機能コードの文字表現を返す。
570 */
571
572const char *
573in_strtfn (FN fncd)
574{
575 switch (fncd) {
576
577 /* TCP 関係 */
578
579 case TFN_TCP_CRE_REP:
580 return "TFN_TCP_CRE_REP";
581 break;
582 case TFN_TCP_DEL_REP:
583 return "TFN_TCP_DEL_REP";
584 break;
585 case TFN_TCP_CRE_CEP:
586 return "TFN_TCP_CRE_CEP";
587 break;
588 case TFN_TCP_DEL_CEP:
589 return "TFN_TCP_DEL_CEP";
590 break;
591 case TFN_TCP_ACP_CEP:
592 return "TFN_TCP_ACP_CEP";
593 break;
594 case TFN_TCP_CON_CEP:
595 return "TFN_TCP_CON_CEP";
596 break;
597 case TFN_TCP_SHT_CEP:
598 return "TFN_TCP_SHT_CEP";
599 break;
600 case TFN_TCP_CLS_CEP:
601 return "TFN_TCP_CLS_CEP";
602 break;
603 case TFN_TCP_SND_DAT:
604 return "TFN_TCP_SND_DAT";
605 break;
606 case TFN_TCP_RCV_DAT:
607 return "TFN_TCP_RCV_DAT";
608 break;
609 case TFN_TCP_GET_BUF:
610 return "TFN_TCP_GET_BUF";
611 break;
612 case TFN_TCP_SND_BUF:
613 return "TFN_TCP_SND_BUF";
614 break;
615 case TFN_TCP_RCV_BUF:
616 return "TFN_TCP_RCV_BUF";
617 break;
618 case TFN_TCP_REL_BUF:
619 return "TFN_TCP_REL_BUF";
620 break;
621 case TFN_TCP_SND_OOB:
622 return "TFN_TCP_SND_OOB";
623 break;
624 case TFN_TCP_RCV_OOB:
625 return "TFN_TCP_RCV_OOB";
626 break;
627 case TFN_TCP_CAN_CEP:
628 return "TFN_TCP_CAN_CEP";
629 break;
630 case TFN_TCP_SET_OPT:
631 return "TFN_TCP_SET_OPT";
632 break;
633 case TFN_TCP_GET_OPT:
634 return "TFN_TCP_GET_OPT";
635 break;
636 case TFN_TCP_ALL:
637 return "ALL";
638 break;
639
640 /* UDP 関係 */
641
642 case TFN_UDP_CRE_CEP:
643 return "TFN_UDP_CRE_CEP";
644 break;
645 case TFN_UDP_DEL_CEP:
646 return "TFN_UDP_DEL_CEP";
647 break;
648 case TFN_UDP_SND_DAT:
649 return "TFN_UDP_SND_DAT";
650 break;
651 case TFN_UDP_RCV_DAT:
652 return "TFN_UDP_RCV_DAT";
653 break;
654 case TFN_UDP_CAN_CEP:
655 return "TFN_UDP_CAN_CEP";
656 break;
657 case TFN_UDP_SET_OPT:
658 return "TFN_UDP_SET_OPT";
659 break;
660 case TFN_UDP_GET_OPT:
661 return "TFN_UDP_GET_OPT";
662 break;
663
664 default:
665 return "unknown TFN";
666 }
667 }
Note: See TracBrowser for help on using the repository browser.