Deleted Added
sdiff udiff text old ( 102500 ) new ( 102558 )
full compact
1/*-
2 * Copyright (c) 2001 Brian Somers <brian@Awfulhak.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/usr.sbin/ppp/ipv6cp.c 102500 2002-08-27 20:11:58Z brian $
27 */
28
29#include <sys/param.h>
30#include <netinet/in_systm.h>
31#include <netinet/in.h>
32#include <netinet/ip.h>
33#include <sys/socket.h>
34#include <net/route.h>
35#include <net/if.h>
36#include <sys/un.h>
37
38#include <stdarg.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42#include <termios.h>
43
44#include "layer.h"
45#include "defs.h"
46#include "mbuf.h"
47#include "timer.h"
48#include "fsm.h"
49#include "iplist.h"
50#include "throughput.h"

--- 47 unchanged lines hidden (view full) ---

98 ipv6cp_SendConfigReq,
99 ipv6cp_SentTerminateReq,
100 ipv6cp_SendTerminateAck,
101 ipv6cp_DecodeConfig,
102 fsm_NullRecvResetReq,
103 fsm_NullRecvResetAck
104};
105
106static u_int32_t
107GenerateToken(void)
108{
109 /* Generate random number which will be used as negotiation token */
110 randinit();
111
112 return random() + 1;
113}
114
115static int
116ipcp_SetIPv6address(struct ipv6cp *ipv6cp, u_int32_t mytok, u_int32_t histok)
117{
118 struct bundle *bundle = ipv6cp->fsm.bundle;
119 struct in6_addr myaddr, hisaddr;
120 struct ncprange myrange;
121 struct sockaddr_storage ssdst, ssgw, ssmask;
122 struct sockaddr *sadst, *sagw, *samask;
123
124 sadst = (struct sockaddr *)&ssdst;
125 sagw = (struct sockaddr *)&ssgw;
126 samask = (struct sockaddr *)&ssmask;
127
128 memset(&myaddr, '\0', sizeof myaddr);
129 memset(&hisaddr, '\0', sizeof hisaddr);
130
131 myaddr.s6_addr[0] = 0xfe;
132 myaddr.s6_addr[1] = 0x80;
133 *(u_int32_t *)(myaddr.s6_addr + 12) = htonl(mytok);
134
135 hisaddr.s6_addr[0] = 0xfe;
136 hisaddr.s6_addr[1] = 0x80;
137 *(u_int32_t *)(hisaddr.s6_addr + 12) = htonl(histok);
138
139 ncpaddr_setip6(&ipv6cp->myaddr, &myaddr);
140 ncpaddr_setip6(&ipv6cp->hisaddr, &hisaddr);
141 ncprange_sethost(&myrange, &ipv6cp->myaddr);
142
143 if (!iface_Add(bundle->iface, &bundle->ncp, &myrange, &ipv6cp->hisaddr,
144 IFACE_ADD_FIRST|IFACE_FORCE_ADD|IFACE_SYSTEM))
145 return 0;

--- 33 unchanged lines hidden (view full) ---

179
180 fsm_Init(&ipv6cp->fsm, "IPV6CP", PROTO_IPV6CP, 1, IPV6CP_MAXCODE, LogIPV6CP,
181 bundle, l, parent, &ipv6cp_Callbacks, timer_names);
182
183 ipv6cp->cfg.fsm.timeout = DEF_FSMRETRY;
184 ipv6cp->cfg.fsm.maxreq = DEF_FSMTRIES;
185 ipv6cp->cfg.fsm.maxtrm = DEF_FSMTRIES;
186
187 ipv6cp->my_token = GenerateToken();
188 while ((ipv6cp->peer_token = GenerateToken()) == ipv6cp->my_token)
189 ;
190
191 if (probe.ipv6_available) {
192 n = 100;
193 while (n &&
194 !ipcp_SetIPv6address(ipv6cp, ipv6cp->my_token, ipv6cp->peer_token)) {
195 n--;
196 while (n && (ipv6cp->my_token = GenerateToken()) == ipv6cp->peer_token)
197 n--;
198 }
199 }
200
201 throughput_init(&ipv6cp->throughput, SAMPLE_PERIOD);
202 memset(ipv6cp->Queue, '\0', sizeof ipv6cp->Queue);
203 ipv6cp_Setup(ipv6cp);
204}
205

--- 82 unchanged lines hidden (view full) ---

288void
289ipv6cp_IfaceAddrDeleted(struct ipv6cp *ipv6cp, const struct iface_addr *addr)
290{
291}
292
293int
294ipv6cp_InterfaceUp(struct ipv6cp *ipv6cp)
295{
296 if (!ipcp_SetIPv6address(ipv6cp, ipv6cp->my_token, ipv6cp->peer_token)) {
297 log_Printf(LogERROR, "ipv6cp_InterfaceUp: unable to set ipv6 address\n");
298 return 0;
299 }
300
301 if (!iface_SetFlags(ipv6cp->fsm.bundle->iface->name, IFF_UP)) {
302 log_Printf(LogERROR, "ipv6cp_InterfaceUp: Can't set the IFF_UP"
303 " flag on %s\n", ipv6cp->fsm.bundle->iface->name);
304 return 0;

--- 145 unchanged lines hidden (view full) ---

450}
451
452static void
453ipv6cp_SendConfigReq(struct fsm *fp)
454{
455 /* Send config REQ please */
456 struct physical *p = link2physical(fp->link);
457 struct ipv6cp *ipv6cp = fsm2ipv6cp(fp);
458 u_char buff[6];
459 struct fsm_opt *o;
460
461 o = (struct fsm_opt *)buff;
462
463 if ((p && !physical_IsSync(p)) || !REJECTED(ipv6cp, TY_TOKEN)) {
464 memcpy(o->data, &ipv6cp->my_token, 4);
465 INC_FSM_OPT(TY_TOKEN, 6, o);
466 }
467
468 fsm_Output(fp, CODE_CONFIGREQ, fp->reqid, buff, (u_char *)o - buff,
469 MB_IPV6CPOUT);
470}
471
472static void
473ipv6cp_SentTerminateReq(struct fsm *fp)

--- 6 unchanged lines hidden (view full) ---

480{
481 /* Send Term ACK please */
482 fsm_Output(fp, CODE_TERMACK, id, NULL, 0, MB_IPV6CPOUT);
483}
484
485static const char *
486protoname(int proto)
487{
488 static const char *cftypes[] = { "TOKEN", "COMPPROTO" };
489
490 if (proto > 0 && proto <= sizeof cftypes / sizeof *cftypes)
491 return cftypes[proto - 1];
492
493 return NumStr(proto, NULL, 0);
494}
495
496static void
497ipv6cp_ValidateToken(struct ipv6cp *ipv6cp, u_int32_t token,
498 struct fsm_decode *dec)
499{
500 struct fsm_opt opt;
501
502 if (token != 0 && token != ipv6cp->my_token)
503 ipv6cp->peer_token = token;
504
505 opt.hdr.id = TY_TOKEN;
506 opt.hdr.len = 6;
507 memcpy(opt.data, &ipv6cp->peer_token, 4);
508 if (token == ipv6cp->peer_token)
509 fsm_ack(dec, &opt);
510 else
511 fsm_nak(dec, &opt);
512}
513
514static void
515ipv6cp_DecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type,
516 struct fsm_decode *dec)
517{
518 /* Deal with incoming PROTO_IPV6CP */
519 struct ipv6cp *ipv6cp = fsm2ipv6cp(fp);
520 int n;
521 char tbuff[100];
522 u_int32_t token;
523 struct fsm_opt *opt;
524
525 while (end - cp >= sizeof(opt->hdr)) {
526 if ((opt = fsm_readopt(&cp)) == NULL)
527 break;
528
529 snprintf(tbuff, sizeof tbuff, " %s[%d]", protoname(opt->hdr.id),
530 opt->hdr.len);
531
532 switch (opt->hdr.id) {
533 case TY_TOKEN:
534 memcpy(&token, opt->data, 4);
535 log_Printf(LogIPV6CP, "%s 0x%08lx\n", tbuff, (unsigned long)token);
536
537 switch (mode_type) {
538 case MODE_REQ:
539 ipv6cp->peer_tokenreq = 1;
540 ipv6cp_ValidateToken(ipv6cp, token, dec);
541 break;
542
543 case MODE_NAK:
544 if (token == 0) {
545 log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE,
546 "0x00000000: Unacceptable token!\n");
547 fsm_Close(&ipv6cp->fsm);
548 } else if (token == ipv6cp->peer_token)
549 log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE,
550 "0x%08lx: Unacceptable token!\n", (unsigned long)token);
551 else if (token != ipv6cp->my_token) {
552 n = 100;
553 while (n && !ipcp_SetIPv6address(ipv6cp, token, ipv6cp->peer_token)) {
554 n--;
555 while (n && (token = GenerateToken()) == ipv6cp->peer_token)
556 n--;
557 }
558
559 if (n == 0) {
560 log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE,
561 "0x00000000: Unacceptable token!\n");
562 fsm_Close(&ipv6cp->fsm);
563 } else {
564 log_Printf(LogIPV6CP, "%s changing token: 0x%08lx --> 0x%08lx\n",
565 tbuff, (unsigned long)ipv6cp->my_token,
566 (unsigned long)token);
567 ipv6cp->my_token = token;
568 bundle_AdjustFilters(fp->bundle, &ipv6cp->myaddr, NULL);
569 }
570 }
571 break;
572
573 case MODE_REJ:
574 ipv6cp->his_reject |= (1 << opt->hdr.id);
575 break;

--- 16 unchanged lines hidden (view full) ---

592 * Pretend the peer has requested a TOKEN.
593 * We do this to ensure that we only send one NAK if the only
594 * reason for the NAK is because the peer isn't sending a
595 * TY_TOKEN REQ. This stops us from repeatedly trying to tell
596 * the peer that we have to have an IP address on their end.
597 */
598 ipv6cp->peer_tokenreq = 1;
599 }
600 ipv6cp_ValidateToken(ipv6cp, 0, dec);
601 }
602 fsm_opt_normalise(dec);
603 }
604}
605#endif