Annotation of embedaddon/mpd/src/udp.c, revision 1.1.1.1
1.1 misho 1:
2: /*
3: * udp.c
4: *
5: * Written by Alexander Motin <mav@FreeBSD.org>
6: */
7:
8: #include "ppp.h"
9: #include "phys.h"
10: #include "mbuf.h"
11: #include "udp.h"
12: #include "ngfunc.h"
13: #include "util.h"
14: #include "log.h"
15:
16: #include <netgraph/ng_message.h>
17: #include <netgraph/ng_socket.h>
18: #include <netgraph/ng_ksocket.h>
19: #include <netgraph.h>
20:
21: /*
22: * XXX this device type not completely correct,
23: * as it can deliver out-of-order frames. This can make problems
24: * for different compression and encryption protocols.
25: */
26:
27: /*
28: * DEFINITIONS
29: */
30:
31: #define UDP_MTU 2048
32: #define UDP_MRU 2048
33:
34: #define UDP_MAXPARENTIFS 256
35:
36: struct udpinfo {
37: struct {
38: struct optinfo options;
39: struct u_addr self_addr; /* Configured local IP address */
40: struct u_range peer_addr; /* Configured peer IP address */
41: in_port_t self_port; /* Configured local port */
42: in_port_t peer_port; /* Configured peer port */
43: char *fqdn_peer_addr; /* FQDN Peer address */
44: } conf;
45:
46: /* State */
47: u_char incoming; /* incoming vs. outgoing */
48: struct UdpIf *If;
49: struct u_addr peer_addr;
50: in_port_t peer_port;
51: ng_ID_t node_id;
52: };
53: typedef struct udpinfo *UdpInfo;
54:
55: /* Set menu options */
56:
57: enum {
58: SET_PEERADDR,
59: SET_SELFADDR,
60: SET_ENABLE,
61: SET_DISABLE
62: };
63:
64: /* Binary options */
65: enum {
66: UDP_CONF_RESOLVE_ONCE /* Only once resolve peer_addr */
67: };
68:
69: /*
70: * INTERNAL FUNCTIONS
71: */
72:
73: static int UdpInit(Link l);
74: static int UdpInst(Link l, Link lt);
75: static void UdpOpen(Link l);
76: static void UdpClose(Link l);
77: static void UdpStat(Context ctx);
78: static int UdpOrigination(Link l);
79: static int UdpIsSync(Link l);
80: static int UdpSelfAddr(Link l, void *buf, size_t buf_len);
81: static int UdpPeerAddr(Link l, void *buf, size_t buf_len);
82: static int UdpPeerPort(Link l, void *buf, size_t buf_len);
83: static int UdpCallingNum(Link l, void *buf, size_t buf_len);
84: static int UdpCalledNum(Link l, void *buf, size_t buf_len);
85:
86: static void UdpDoClose(Link l);
87: static void UdpShutdown(Link l);
88: static int UdpSetCommand(Context ctx, int ac, char *av[], void *arg);
89: static void UdpNodeUpdate(Link l);
90: static int UdpListen(Link l);
91: static int UdpUnListen(Link l);
92:
93: /*
94: * GLOBAL VARIABLES
95: */
96:
97: const struct phystype gUdpPhysType = {
98: .name = "udp",
99: .descr = "PPP over UDP",
100: .mtu = UDP_MTU,
101: .mru = UDP_MRU,
102: .tmpl = 1,
103: .init = UdpInit,
104: .inst = UdpInst,
105: .open = UdpOpen,
106: .close = UdpClose,
107: .update = UdpNodeUpdate,
108: .shutdown = UdpShutdown,
109: .showstat = UdpStat,
110: .originate = UdpOrigination,
111: .issync = UdpIsSync,
112: .selfaddr = UdpSelfAddr,
113: .peeraddr = UdpPeerAddr,
114: .peerport = UdpPeerPort,
115: .callingnum = UdpCallingNum,
116: .callednum = UdpCalledNum,
117: };
118:
119: const struct cmdtab UdpSetCmds[] = {
120: { "self {ip} [{port}]", "Set local IP address",
121: UdpSetCommand, NULL, 2, (void *) SET_SELFADDR },
122: { "peer {ip} [{port}]", "Set remote IP address",
123: UdpSetCommand, NULL, 2, (void *) SET_PEERADDR },
124: { "enable [opt ...]", "Enable option",
125: UdpSetCommand, NULL, 2, (void *) SET_ENABLE },
126: { "disable [opt ...]", "Disable option",
127: UdpSetCommand, NULL, 2, (void *) SET_DISABLE },
128: { NULL },
129: };
130:
131: struct UdpIf {
132: struct u_addr self_addr;
133: in_port_t self_port;
134: int refs;
135: int csock; /* netgraph Control socket */
136: EventRef ctrlEvent; /* listen for ctrl messages */
137: };
138: struct UdpIf UdpIfs[UDP_MAXPARENTIFS];
139:
140: int UdpListenUpdateSheduled=0;
141: struct pppTimer UdpListenUpdateTimer;
142:
143: /*
144: * INTERNAL VARIABLES
145: */
146:
147: static struct confinfo gConfList[] = {
148: { 0, UDP_CONF_RESOLVE_ONCE, "resolve-once" },
149: { 0, 0, NULL },
150: };
151:
152:
153: /*
154: * UdpInit()
155: */
156:
157: static int
158: UdpInit(Link l)
159: {
160: UdpInfo pi;
161:
162: pi = (UdpInfo) (l->info = Malloc(MB_PHYS, sizeof(*pi)));
163:
164: u_addrclear(&pi->conf.self_addr);
165: u_rangeclear(&pi->conf.peer_addr);
166: pi->conf.self_port=0;
167: pi->conf.peer_port=0;
168:
169: pi->incoming = 0;
170: pi->If = NULL;
171:
172: u_addrclear(&pi->peer_addr);
173: pi->peer_port=0;
174: pi->conf.fqdn_peer_addr = NULL;
175: Enable(&pi->conf.options, UDP_CONF_RESOLVE_ONCE);
176:
177: return(0);
178: }
179:
180: /*
181: * UdpInst()
182: */
183:
184: static int
185: UdpInst(Link l, Link lt)
186: {
187: UdpInfo pi;
188: UdpInfo const pit = (UdpInfo) lt->info;
189:
190: /* Initialize this link */
191: pi = (UdpInfo) (l->info = Mdup(MB_PHYS, lt->info, sizeof(*pi)));
192: if (pit->conf.fqdn_peer_addr != NULL)
193: pi->conf.fqdn_peer_addr =
194: Mstrdup(MB_PHYS, pit->conf.fqdn_peer_addr);
195:
196: if (pi->If)
197: pi->If->refs++;
198:
199: return(0);
200: }
201:
202: /*
203: * UdpOpen()
204: */
205:
206: static void
207: UdpOpen(Link l)
208: {
209: UdpInfo const pi = (UdpInfo) l->info;
210: char path[NG_PATHSIZ];
211: char hook[NG_HOOKSIZ];
212: struct ngm_mkpeer mkp;
213: struct ngm_name nm;
214: struct sockaddr_storage addr;
215: union {
216: u_char buf[sizeof(struct ng_ksocket_sockopt) + sizeof(int)];
217: struct ng_ksocket_sockopt ksso;
218: } u;
219: struct ng_ksocket_sockopt *const ksso = &u.ksso;
220: int csock;
221:
222: /* Create a new netgraph node to control TCP ksocket node. */
223: if (NgMkSockNode(NULL, &csock, NULL) < 0) {
224: Perror("[%s] TCP can't create control socket", l->name);
225: goto fail;
226: }
227: (void)fcntl(csock, F_SETFD, 1);
228:
229: if (!PhysGetUpperHook(l, path, hook)) {
230: Log(LG_PHYS, ("[%s] UDP: can't get upper hook", l->name));
231: goto fail;
232: }
233:
234: /* Attach ksocket node to PPP node */
235: memset(&mkp, 0, sizeof(mkp));
236: strcpy(mkp.type, NG_KSOCKET_NODE_TYPE);
237: strlcpy(mkp.ourhook, hook, sizeof(mkp.ourhook));
238: if ((pi->conf.self_addr.family==AF_INET6) ||
239: (pi->conf.self_addr.family==AF_UNSPEC && pi->conf.peer_addr.addr.family==AF_INET6)) {
240: snprintf(mkp.peerhook, sizeof(mkp.peerhook), "%d/%d/%d", PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
241: } else {
242: snprintf(mkp.peerhook, sizeof(mkp.peerhook), "inet/dgram/udp");
243: }
244: if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
245: NGM_MKPEER, &mkp, sizeof(mkp)) < 0) {
246: Perror("[%s] can't attach %s node",
247: l->name, NG_KSOCKET_NODE_TYPE);
248: goto fail;
249: }
250:
251: strlcat(path, ".", sizeof(path));
252: strlcat(path, hook, sizeof(path));
253:
254: /* Give it a name */
255: memset(&nm, 0, sizeof(nm));
256: snprintf(nm.name, sizeof(nm.name), "mpd%d-%s-kso", gPid, l->name);
257: if (NgSendMsg(csock, path,
258: NGM_GENERIC_COOKIE, NGM_NAME, &nm, sizeof(nm)) < 0) {
259: Perror("[%s] can't name %s node", l->name, NG_KSOCKET_NODE_TYPE);
260: }
261:
262: if ((pi->node_id = NgGetNodeID(csock, path)) == 0) {
263: Perror("[%s] Cannot get %s node id", l->name, NG_KSOCKET_NODE_TYPE);
264: goto fail;
265: };
266:
267: if ((pi->incoming) || (pi->conf.self_port != 0)) {
268: /* Setsockopt socket. */
269: ksso->level=SOL_SOCKET;
270: ksso->name=SO_REUSEPORT;
271: ((int *)(ksso->value))[0]=1;
272: if (NgSendMsg(csock, path, NGM_KSOCKET_COOKIE,
273: NGM_KSOCKET_SETOPT, &u, sizeof(u)) < 0) {
274: Perror("[%s] can't setsockopt() %s node",
275: l->name, NG_KSOCKET_NODE_TYPE);
276: goto fail;
277: }
278:
279: if ((!Enabled(&pi->conf.options, UDP_CONF_RESOLVE_ONCE)) &&
280: (pi->conf.fqdn_peer_addr != NULL)) {
281: struct u_range rng;
282: if (ParseRange(pi->conf.fqdn_peer_addr, &rng, ALLOW_IPV4|ALLOW_IPV6))
283: pi->conf.peer_addr = rng;
284: }
285:
286: /* Bind socket */
287: u_addrtosockaddr(&pi->conf.self_addr, pi->conf.self_port, &addr);
288: if (NgSendMsg(csock, path, NGM_KSOCKET_COOKIE,
289: NGM_KSOCKET_BIND, &addr, addr.ss_len) < 0) {
290: Perror("[%s] can't bind() %s node", l->name, NG_KSOCKET_NODE_TYPE);
291: goto fail;
292: }
293: }
294:
295: if (!pi->incoming) {
296: if ((!u_rangeempty(&pi->conf.peer_addr)) && (pi->conf.peer_port != 0)) {
297: u_addrcopy(&pi->conf.peer_addr.addr,&pi->peer_addr);
298: pi->peer_port = pi->conf.peer_port;
299: } else {
300: Log(LG_ERR, ("[%s] Can't connect without peer specified", l->name));
301: goto fail;
302: }
303: }
304: u_addrtosockaddr(&pi->peer_addr, pi->peer_port, &addr);
305:
306: /* Connect socket if peer address and port is specified */
307: if (NgSendMsg(csock, path, NGM_KSOCKET_COOKIE,
308: NGM_KSOCKET_CONNECT, &addr, addr.ss_len) < 0) {
309: Perror("[%s] can't connect() %s node", l->name, NG_KSOCKET_NODE_TYPE);
310: goto fail;
311: }
312:
313: close(csock);
314:
315: /* OK */
316: l->state = PHYS_STATE_UP;
317: PhysUp(l);
318: return;
319:
320: fail:
321: UdpDoClose(l);
322: pi->incoming=0;
323: l->state = PHYS_STATE_DOWN;
324: u_addrclear(&pi->peer_addr);
325: pi->peer_port=0;
326: if (csock>0)
327: close(csock);
328:
329: PhysDown(l, STR_ERROR, NULL);
330: }
331:
332: /*
333: * UdpClose()
334: */
335:
336: static void
337: UdpClose(Link l)
338: {
339: UdpInfo const pi = (UdpInfo) l->info;
340: if (l->state != PHYS_STATE_DOWN) {
341: UdpDoClose(l);
342: pi->incoming=0;
343: l->state = PHYS_STATE_DOWN;
344: u_addrclear(&pi->peer_addr);
345: pi->peer_port=0;
346: PhysDown(l, STR_MANUALLY, NULL);
347: }
348: }
349:
350: /*
351: * UdpShutdown()
352: */
353:
354: static void
355: UdpShutdown(Link l)
356: {
357: UdpInfo const pi = (UdpInfo) l->info;
358:
359: if (pi->conf.fqdn_peer_addr)
360: Freee(pi->conf.fqdn_peer_addr);
361:
362: UdpDoClose(l);
363: UdpUnListen(l);
364: Freee(l->info);
365: }
366:
367: /*
368: * UdpDoClose()
369: */
370:
371: static void
372: UdpDoClose(Link l)
373: {
374: UdpInfo const pi = (UdpInfo) l->info;
375: char path[NG_PATHSIZ];
376: int csock;
377:
378: if (pi->node_id == 0)
379: return;
380:
381: /* Get a temporary netgraph socket node */
382: if (NgMkSockNode(NULL, &csock, NULL) == -1) {
383: Perror("UDP: NgMkSockNode");
384: return;
385: }
386:
387: /* Disconnect session hook. */
388: snprintf(path, sizeof(path), "[%lx]:", (u_long)pi->node_id);
389: NgFuncShutdownNode(csock, l->name, path);
390:
391: close(csock);
392:
393: pi->node_id = 0;
394: }
395:
396: /*
397: * UdpOrigination()
398: */
399:
400: static int
401: UdpOrigination(Link l)
402: {
403: UdpInfo const pi = (UdpInfo) l->info;
404:
405: return (pi->incoming ? LINK_ORIGINATE_REMOTE : LINK_ORIGINATE_LOCAL);
406: }
407:
408: /*
409: * UdpIsSync()
410: */
411:
412: static int
413: UdpIsSync(Link l)
414: {
415: return (1);
416: }
417:
418: static int
419: UdpSelfAddr(Link l, void *buf, size_t buf_len)
420: {
421: UdpInfo const pi = (UdpInfo) l->info;
422:
423: if (!u_addrempty(&pi->conf.self_addr)) {
424: if (u_addrtoa(&pi->conf.self_addr, buf, buf_len))
425: return (0);
426: else {
427: ((char*)buf)[0]=0;
428: return (-1);
429: }
430: }
431: ((char*)buf)[0]=0;
432: return (0);
433: }
434:
435: static int
436: UdpPeerAddr(Link l, void *buf, size_t buf_len)
437: {
438: UdpInfo const pi = (UdpInfo) l->info;
439:
440: if (u_addrtoa(&pi->peer_addr, buf, buf_len))
441: return(0);
442: else
443: return(-1);
444: }
445:
446: static int
447: UdpPeerPort(Link l, void *buf, size_t buf_len)
448: {
449: UdpInfo const pi = (UdpInfo) l->info;
450:
451: if (snprintf(buf, buf_len, "%d", pi->peer_port))
452: return(0);
453: else
454: return(-1);
455: }
456:
457: static int
458: UdpCallingNum(Link l, void *buf, size_t buf_len)
459: {
460: UdpInfo const pi = (UdpInfo) l->info;
461:
462: if (pi->incoming) {
463: if (u_addrtoa(&pi->peer_addr, buf, buf_len))
464: return (0);
465: else
466: return (-1);
467: } else {
468: if (u_addrtoa(&pi->conf.self_addr, buf, buf_len))
469: return (0);
470: else
471: return (-1);
472: }
473: }
474:
475: static int
476: UdpCalledNum(Link l, void *buf, size_t buf_len)
477: {
478: UdpInfo const pi = (UdpInfo) l->info;
479:
480: if (!pi->incoming) {
481: if (u_addrtoa(&pi->peer_addr, buf, buf_len))
482: return (0);
483: else
484: return (-1);
485: } else {
486: if (u_addrtoa(&pi->conf.self_addr, buf, buf_len))
487: return (0);
488: else
489: return (-1);
490: }
491: }
492:
493: /*
494: * UdpStat()
495: */
496:
497: void
498: UdpStat(Context ctx)
499: {
500: UdpInfo const pi = (UdpInfo) ctx->lnk->info;
501: char buf[48];
502:
503: Printf("UDP configuration:\r\n");
504: Printf("\tPeer FQDN : %s\r\n", pi->conf.fqdn_peer_addr);
505: Printf("\tSelf address : %s, port %u\r\n",
506: u_addrtoa(&pi->conf.self_addr, buf, sizeof(buf)), pi->conf.self_port);
507: Printf("\tPeer address : %s, port %u\r\n",
508: u_rangetoa(&pi->conf.peer_addr, buf, sizeof(buf)), pi->conf.peer_port);
509: Printf("UDP state:\r\n");
510: if (ctx->lnk->state != PHYS_STATE_DOWN) {
511: Printf("\tIncoming : %s\r\n", (pi->incoming?"YES":"NO"));
512: Printf("\tCurrent peer : %s, port %u\r\n",
513: u_addrtoa(&pi->peer_addr, buf, sizeof(buf)), pi->peer_port);
514: }
515: }
516:
517: /*
518: * UdpAcceptEvent() triggers when we accept incoming connection.
519: */
520:
521: static void
522: UdpAcceptEvent(int type, void *cookie)
523: {
524: struct sockaddr_storage saddr;
525: socklen_t saddrlen;
526: struct u_addr addr;
527: in_port_t port;
528: char buf[48];
529: char buf1[48];
530: int k;
531: struct UdpIf *If=(struct UdpIf *)(cookie);
532: Link l = NULL;
533: UdpInfo pi = NULL;
534:
535: char pktbuf[UDP_MRU+100];
536: ssize_t pktlen;
537:
538: assert(type == EVENT_READ);
539:
540: saddrlen = sizeof(saddr);
541: if ((pktlen = recvfrom(If->csock, pktbuf, sizeof(pktbuf), MSG_DONTWAIT, (struct sockaddr *)(&saddr), &saddrlen)) < 0) {
542: Log(LG_PHYS, ("recvfrom() error: %s", strerror(errno)));
543: }
544:
545: sockaddrtou_addr(&saddr, &addr, &port);
546:
547: Log(LG_PHYS, ("Incoming UDP connection from %s %u to %s %u",
548: u_addrtoa(&addr, buf, sizeof(buf)), port,
549: u_addrtoa(&If->self_addr, buf1, sizeof(buf1)), If->self_port));
550:
551: if (gShutdownInProgress) {
552: Log(LG_PHYS, ("Shutdown sequence in progress, ignoring request."));
553: goto failed;
554: }
555:
556: if (OVERLOAD()) {
557: Log(LG_PHYS, ("Daemon overloaded, ignoring request."));
558: goto failed;
559: }
560:
561: /* Examine all UDP links. */
562: for (k = 0; k < gNumLinks; k++) {
563: Link l2;
564: UdpInfo pi2;
565:
566: if (!gLinks[k] || gLinks[k]->type != &gUdpPhysType)
567: continue;
568:
569: l2 = gLinks[k];
570: pi2 = (UdpInfo)l2->info;
571:
572: if ((!PhysIsBusy(l2)) &&
573: Enabled(&l2->conf.options, LINK_CONF_INCOMING) &&
574: (pi2->If == If) &&
575: IpAddrInRange(&pi2->conf.peer_addr, &addr) &&
576: (pi2->conf.peer_port == 0 || pi2->conf.peer_port == port)) {
577:
578: if (pi == NULL || pi2->conf.peer_addr.width > pi->conf.peer_addr.width) {
579: l = l2;
580: pi = pi2;
581: if (u_rangehost(&pi->conf.peer_addr)) {
582: break; /* Nothing could be better */
583: }
584: }
585: }
586: }
587: if (l != NULL && l->tmpl)
588: l = LinkInst(l, NULL, 0, 0);
589:
590: if (l != NULL) {
591: pi = (UdpInfo)l->info;
592: Log(LG_PHYS, ("[%s] Accepting UDP connection from %s %u to %s %u",
593: l->name, u_addrtoa(&addr, buf, sizeof(buf)), port,
594: u_addrtoa(&If->self_addr, buf1, sizeof(buf1)), If->self_port));
595:
596: sockaddrtou_addr(&saddr, &pi->peer_addr, &pi->peer_port);
597:
598: pi->incoming=1;
599: l->state = PHYS_STATE_READY;
600:
601: PhysIncoming(l);
602: } else {
603: Log(LG_PHYS, ("No free UDP link with requested parameters "
604: "was found"));
605: }
606:
607: failed:
608: EventRegister(&If->ctrlEvent, EVENT_READ, If->csock,
609: 0, UdpAcceptEvent, If);
610: }
611:
612: static int
613: UdpListen(Link l)
614: {
615: UdpInfo const pi = (UdpInfo) l->info;
616: struct sockaddr_storage addr;
617: char buf[48];
618: int opt, i, j = -1, free = -1;
619:
620: if (pi->If)
621: return(1);
622:
623: for (i = 0; i < UDP_MAXPARENTIFS; i++) {
624: if (UdpIfs[i].self_port == 0)
625: free = i;
626: else if ((u_addrcompare(&UdpIfs[i].self_addr, &pi->conf.self_addr) == 0) &&
627: (UdpIfs[i].self_port == pi->conf.self_port)) {
628: j = i;
629: break;
630: }
631: }
632:
633: if (j >= 0) {
634: UdpIfs[j].refs++;
635: pi->If=&UdpIfs[j];
636: return(1);
637: }
638:
639: if (free < 0) {
640: Log(LG_ERR, ("[%s] UDP: Too many different listening ports! ",
641: l->name));
642: return (0);
643: }
644:
645: UdpIfs[free].refs = 1;
646: pi->If=&UdpIfs[free];
647:
648: u_addrcopy(&pi->conf.self_addr,&pi->If->self_addr);
649: pi->If->self_port=pi->conf.self_port;
650:
651: /* Make listening UDP socket. */
652: if (pi->If->self_addr.family==AF_INET6) {
653: pi->If->csock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
654: } else {
655: pi->If->csock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
656: }
657: (void)fcntl(pi->If->csock, F_SETFD, 1);
658:
659: /* Setsockopt socket. */
660: opt = 1;
661: if (setsockopt(pi->If->csock, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt))) {
662: Perror("UDP: can't setsockopt socket");
663: goto fail2;
664: };
665:
666: /* Bind socket. */
667: u_addrtosockaddr(&pi->If->self_addr, pi->If->self_port, &addr);
668: if (bind(pi->If->csock, (struct sockaddr *)(&addr), addr.ss_len)) {
669: Perror("UDP: can't bind socket");
670: goto fail2;
671: }
672:
673: Log(LG_PHYS, ("UDP: waiting for connection on %s %u",
674: u_addrtoa(&pi->If->self_addr, buf, sizeof(buf)), pi->If->self_port));
675: EventRegister(&pi->If->ctrlEvent, EVENT_READ, pi->If->csock,
676: 0, UdpAcceptEvent, pi->If);
677:
678: return (1);
679: fail2:
680: close(pi->If->csock);
681: pi->If->csock = -1;
682: pi->If->self_port = 0;
683: pi->If = NULL;
684: return (0);
685: }
686:
687:
688: static int
689: UdpUnListen(Link l)
690: {
691: UdpInfo const pi = (UdpInfo) l->info;
692: char buf[48];
693:
694: if (!pi->If)
695: return(1);
696:
697: pi->If->refs--;
698: if (pi->If->refs == 0) {
699: Log(LG_PHYS, ("UDP: stop waiting for connection on %s %u",
700: u_addrtoa(&pi->If->self_addr, buf, sizeof(buf)), pi->If->self_port));
701: EventUnRegister(&pi->If->ctrlEvent);
702: close(pi->If->csock);
703: pi->If->csock = -1;
704: pi->If->self_port = 0;
705: pi->If = NULL;
706: }
707:
708: return (1);
709: }
710:
711: /*
712: * UdpNodeUpdate()
713: */
714:
715: static void
716: UdpNodeUpdate(Link l)
717: {
718: UdpInfo const pi = (UdpInfo) l->info;
719: if (!pi->If) {
720: if (Enabled(&l->conf.options, LINK_CONF_INCOMING))
721: UdpListen(l);
722: } else {
723: if (!Enabled(&l->conf.options, LINK_CONF_INCOMING))
724: UdpUnListen(l);
725: }
726: }
727:
728: /*
729: * UdpSetCommand()
730: */
731:
732: static int
733: UdpSetCommand(Context ctx, int ac, char *av[], void *arg)
734: {
735: UdpInfo const pi = (UdpInfo) ctx->lnk->info;
736: char **fqdn_peer_addr = &pi->conf.fqdn_peer_addr;
737: struct u_range rng;
738: int port;
739:
740: switch ((intptr_t)arg) {
741: case SET_PEERADDR:
742: case SET_SELFADDR:
743: if ((ac == 1 || ac == 2) && (intptr_t)arg == SET_PEERADDR) {
744: if (*fqdn_peer_addr)
745: Freee(*fqdn_peer_addr);
746: *fqdn_peer_addr = Mstrdup(MB_PHYS, av[0]);
747: }
748: if (ac < 1 || ac > 2 || !ParseRange(av[0], &rng, ALLOW_IPV4|ALLOW_IPV6))
749: return(-1);
750: if (ac > 1) {
751: if ((port = atoi(av[1])) < 0 || port > 0xffff)
752: return(-1);
753: } else {
754: port = 0;
755: }
756: if ((intptr_t)arg == SET_SELFADDR) {
757: pi->conf.self_addr = rng.addr;
758: pi->conf.self_port = port;
759: } else {
760: pi->conf.peer_addr = rng;
761: pi->conf.peer_port = port;
762: }
763: if (pi->If) {
764: UdpUnListen(ctx->lnk);
765: UdpListen(ctx->lnk);
766: }
767: break;
768: case SET_ENABLE:
769: EnableCommand(ac, av, &pi->conf.options, gConfList);
770: UdpNodeUpdate(ctx->lnk);
771: break;
772: case SET_DISABLE:
773: DisableCommand(ac, av, &pi->conf.options, gConfList);
774: UdpNodeUpdate(ctx->lnk);
775: break;
776: default:
777: assert(0);
778: }
779: return(0);
780: }
781:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>