xref: /original-bsd/sys/netccitt/pk_input.c (revision 9052d23a)
1 /*
2  * Copyright (c) University of British Columbia, 1984
3  * Copyright (c) 1990 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * the Laboratory for Computation Vision and the Computer Science Department
8  * of the University of British Columbia.
9  *
10  * %sccs.include.redist.c%
11  *
12  *	@(#)pk_input.c	7.5 (Berkeley) 08/30/90
13  */
14 
15 #include "param.h"
16 #include "systm.h"
17 #include "mbuf.h"
18 #include "socket.h"
19 #include "protosw.h"
20 #include "socketvar.h"
21 #include "errno.h"
22 
23 #include "../net/if.h"
24 
25 #include "x25.h"
26 #include "pk.h"
27 #include "pk_var.h"
28 
29 /*
30  *  This procedure is called by the link level whenever the link
31  *  becomes operational, is reset, or when the link goes down.
32  */
33 
34 pk_ctlinput (code, pkp)
35 register struct pkcb *pkp;
36 {
37 
38 	if (pkp == 0)
39 		return (EINVAL);
40 	switch (code) {
41 	case PRC_LINKUP:
42 		if (pkp -> pk_state == DTE_WAITING)
43 			pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
44 		break;
45 
46 	case PRC_LINKDOWN:
47 		pk_restart (pkp, -1);	/* Clear all active circuits */
48 		pkp -> pk_state = DTE_WAITING;
49 		break;
50 
51 	case PRC_LINKRESET:
52 		pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
53 		break;
54 
55 	}
56 	return (0);
57 }
58 
59 /*
60  *  X.25 PACKET INPUT
61  *
62  *  This procedure is called by a link level procedure whenever
63  *  an information frame is received. It decodes the packet and
64  *  demultiplexes based on the logical channel number.
65  *
66  */
67 
68 pk_input (m, xcp)
69 register struct mbuf *m;
70 struct x25config *xcp;
71 {
72 	register struct x25_packet *xp;
73 	register struct pklcd *lcp;
74 	register struct socket *so = 0;
75 	register struct pkcb *pkp;
76 	int  ptype, lcn, lcdstate = LISTEN;
77 	static struct x25config *lastxcp;
78 	static struct pkcb *lastpkp;
79 
80 	if (xcp == lastxcp)
81 		pkp = lastpkp;
82 	else {
83 		for (pkp = pkcbhead; ; pkp = pkp -> pk_next) {
84 			if (pkp == 0) {
85 				pk_message (0, xcp, "pk_input: unknown network");
86 				m_freem (m);
87 				return;
88 			}
89 			if (pkp -> pk_xcp == xcp)
90 				break;
91 		}
92 		lastxcp = xcp;
93 		lastpkp = pkp;
94 	}
95 
96 	xp = mtod (m, struct x25_packet *);
97 	ptype = pk_decode (xp);
98 	lcn = xp -> logical_channel_number;
99 	lcp = pkp -> pk_chan[lcn];
100 
101 	/*
102 	 *  If the DTE is in Restart  state, then it will ignore data,
103 	 *  interrupt, call setup and clearing, flow control and reset
104 	 *  packets.
105 	 */
106 	if (lcn < 0 || lcn > pkp -> pk_maxlcn) {
107 		pk_message (lcn, pkp -> pk_xcp, "illegal lcn");
108 		m_freem (m);
109 		return;
110 	}
111 
112 	pk_trace (pkp -> pk_xcp, xp, "P-In");
113 
114 	if (pkp -> pk_state != DTE_READY && ptype != RESTART && ptype != RESTART_CONF) {
115 		m_freem (m);
116 		return;
117 	}
118 	if (lcp) {
119 		so = lcp -> lcd_so;
120 		lcdstate = lcp -> lcd_state;
121 	} else {
122 		if (ptype == CLEAR) {	/* idle line probe (Datapac specific) */
123 			/* send response on lcd 0's output queue */
124 			lcp -> lcd_template = pk_template (lcn, X25_CLEAR_CONFIRM);
125 			pk_output (lcp);
126 			m_freem (m);
127 			return;
128 		}
129 		if (ptype != CALL)
130 			ptype = INVALID_PACKET;
131 	}
132 
133 	if (lcn == 0 && ptype != RESTART && ptype != RESTART_CONF) {
134 		pk_message (0, pkp -> pk_xcp, "illegal ptype (%s) on lcn 0",
135 			pk_name[ptype / MAXSTATES]);
136 		m_freem (m);
137 		return;
138 	}
139 
140 	switch (ptype + lcdstate) {
141 	/*
142 	 *  Incoming Call packet received.
143 	 */
144 	case CALL + LISTEN:
145 		incoming_call (pkp, xp, m -> m_len);
146 		break;
147 
148 	/*
149 	 *  Call collision: Just throw this "incoming call" away since
150 	 *  the DCE will ignore it anyway.
151 	 */
152 	case CALL + SENT_CALL:
153 		pk_message ((int)xp -> logical_channel_number, pkp -> pk_xcp,
154 			"incoming call collision");
155 		break;
156 
157 	/*
158 	 *  Call confirmation packet received. This usually means our
159 	 *  previous connect request is now complete.
160 	 */
161 	case CALL_ACCEPTED + SENT_CALL:
162 		call_accepted (lcp, xp, m -> m_len);
163 		break;
164 
165 	/*
166 	 *  This condition can only happen if the previous state was
167 	 *  SENT_CALL. Just ignore the packet, eventually a clear
168 	 *  confirmation should arrive.
169 	 */
170 	case CALL_ACCEPTED + SENT_CLEAR:
171 		break;
172 
173 	/*
174 	 *  Clear packet received. This requires a complete tear down
175 	 *  of the virtual circuit.  Free buffers and control blocks.
176 	 *  and send a clear confirmation.
177 	 */
178 	case CLEAR + READY:
179 	case CLEAR + RECEIVED_CALL:
180 	case CLEAR + SENT_CALL:
181 	case CLEAR + DATA_TRANSFER:
182 		lcp -> lcd_state = RECEIVED_CLEAR;
183 		lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CLEAR_CONFIRM);
184 		pk_output (lcp);
185 		pk_clearcause (pkp, xp);
186 		pk_close (lcp);
187 		break;
188 
189 	/*
190 	 *  Clear collision: Treat this clear packet as a confirmation.
191 	 */
192 	case CLEAR + SENT_CLEAR:
193 		pk_close (lcp);
194 		break;
195 
196 	/*
197 	 *  Clear confirmation received. This usually means the virtual
198 	 *  circuit is now completely removed.
199 	 */
200 	case CLEAR_CONF + SENT_CLEAR:
201 		pk_close (lcp);
202 		break;
203 
204 	/*
205 	 *  A clear confirmation on an unassigned logical channel - just
206 	 *  ignore it. Note: All other packets on an unassigned channel
207 	 *  results in a clear.
208 	 */
209 	case CLEAR_CONF + READY:
210 		break;
211 
212 	/*
213 	 *  Data packet received. Pass on to next level. Move the Q and M
214 	 *  bits into the data portion for the next level.
215 	 */
216 	case DATA + DATA_TRANSFER:
217 		if (lcp -> lcd_reset_condition) {
218 			ptype = DELETE_PACKET;
219 			break;
220 		}
221 
222 		/*
223 		 *  Process the P(S) flow control information in this Data packet.
224 		 *  Check that the packets arrive in the correct sequence and that
225 		 *  they are within the "lcd_input_window". Input window rotation is
226 		 *  initiated by the receive interface.
227 		 */
228 
229 		if (PS(xp) != ((lcp -> lcd_rsn + 1) % MODULUS) ||
230 			PS(xp) == ((lcp -> lcd_input_window + lcp->lcd_windowsize) % MODULUS)) {
231 			m_freem (m);
232 			pk_procerror (RESET, lcp, "p(s) flow control error");
233 			break;
234 		}
235 		lcp -> lcd_rsn = PS(xp);
236 
237 		if (pk_ack (lcp, PR(xp)) != PACKET_OK) {
238 			m_freem (m);
239 			break;
240 		}
241 
242 		m -> m_data += PKHEADERLN;
243 		m -> m_len -= PKHEADERLN;
244 		if (lcp -> lcd_flags & X25_MQBIT) {
245 			octet *t;
246 
247 			m -> m_data -= 1;
248 			m -> m_len += 1;
249 			t = mtod (m, octet *);
250 			*t = 0x00;
251 			if (xp -> q_bit)
252 				*t |= 0x80;
253 			if (MBIT(xp))
254 				*t |= 0x40;
255 		}
256 
257 		/*
258 		 * Discard Q-BIT packets if the application
259 		 * doesn't want to be informed of M and Q bit status
260 		 */
261 		if (xp -> q_bit && (lcp -> lcd_flags & X25_MQBIT) == 0) {
262 			m_freem (m);
263 			lcp -> lcd_rxcnt++;
264 			/*
265 			 * NB.  This is dangerous: sending a RR here can
266 			 * cause sequence number errors if a previous data
267 			 * packet has not yet been passed up to the application
268 			 * (RR's are normally generated via PRU_RCVD).
269 			 */
270 			lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RR);
271 			pk_output (lcp);
272 		} else {
273 #ifdef BSD4_3
274 			sbappendrecord (&so -> so_rcv, m);
275 #else
276 			sbappend (&so -> so_rcv, m);
277 #endif
278 			sorwakeup (so);
279 		}
280 		break;
281 
282 	/*
283 	 *  Interrupt packet received.
284 	 */
285 	case INTERRUPT + DATA_TRANSFER:
286 		if (lcp -> lcd_reset_condition)
287 			break;
288 		lcp -> lcd_intrdata = xp -> packet_data;
289 		sohasoutofband (so);
290 		lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM);
291 		pk_output (lcp);
292 		break;
293 
294 	/*
295 	 *  Interrupt confirmation packet received.
296 	 */
297 	case INTERRUPT_CONF + DATA_TRANSFER:
298 		if (lcp -> lcd_reset_condition)
299 			break;
300 		if (lcp -> lcd_intrconf_pending == TRUE)
301 			lcp -> lcd_intrconf_pending = FALSE;
302 		else
303 			pk_procerror (RESET, lcp, "unexpected packet");
304 		break;
305 
306 	/*
307 	 *  Receiver ready received. Rotate the output window and output
308 	 *  any data packets waiting transmission.
309 	 */
310 	case RR + DATA_TRANSFER:
311 		if (lcp -> lcd_reset_condition)
312 			break;
313 		if (pk_ack (lcp, PR(xp)) != PACKET_OK)
314 			break;
315 		if (lcp -> lcd_rnr_condition == TRUE)
316 			lcp -> lcd_rnr_condition = FALSE;
317 		pk_output (lcp);
318 		break;
319 
320 	/*
321 	 *  Receiver Not Ready received. Packets up to the P(R) can be
322 	 *  be sent. Condition is cleared with a RR.
323 	 */
324 	case RNR + DATA_TRANSFER:
325 		if (lcp -> lcd_reset_condition)
326 			break;
327 		if (pk_ack (lcp, PR(xp)) != PACKET_OK)
328 			break;
329 		lcp -> lcd_rnr_condition = TRUE;
330 		break;
331 
332 	/*
333 	 *  Reset packet received. Set state to FLOW_OPEN.  The Input and
334 	 *  Output window edges ar set to zero. Both the send and receive
335 	 *  numbers are reset. A confirmation is returned.
336 	 */
337 	case RESET + DATA_TRANSFER:
338 		if (lcp -> lcd_reset_condition)
339 			/* Reset collision. Just ignore packet. */
340 			break;
341 
342 		pk_resetcause (pkp, xp);
343 		sbflush (&so -> so_snd);
344 		sbflush (&so -> so_rcv);
345 
346 		wakeup ((caddr_t) & so -> so_timeo);
347 		sorwakeup (so);
348 		sowwakeup (so);
349 
350 		lcp -> lcd_window_condition = lcp -> lcd_rnr_condition =
351 			lcp -> lcd_intrconf_pending = FALSE;
352 		lcp -> lcd_output_window = lcp -> lcd_input_window =
353 			lcp -> lcd_last_transmitted_pr = 0;
354 		lcp -> lcd_ssn = 0;
355 		lcp -> lcd_rsn = MODULUS - 1;
356 
357 		lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM);
358 		pk_output (lcp);
359 		break;
360 
361 	/*
362 	 *  Reset confirmation received.
363 	 */
364 	case RESET_CONF + DATA_TRANSFER:
365 		if (lcp -> lcd_reset_condition) {
366 			lcp -> lcd_reset_condition = FALSE;
367 			pk_output (lcp);
368 		}
369 		else
370 			pk_procerror (RESET, lcp, "unexpected packet");
371 		break;
372 
373 	case DATA + SENT_CLEAR:
374 		ptype = DELETE_PACKET;
375 	case RR + SENT_CLEAR:
376 	case RNR + SENT_CLEAR:
377 	case INTERRUPT + SENT_CLEAR:
378 	case INTERRUPT_CONF + SENT_CLEAR:
379 	case RESET + SENT_CLEAR:
380 	case RESET_CONF + SENT_CLEAR:
381 		/* Just ignore packet if we have sent a CLEAR already.
382 		   */
383 		break;
384 
385 	/*
386 	 *  Restart sets all the permanent virtual circuits to the "Data
387 	 *  Transfer" stae and  all the switched virtual circuits to the
388 	 *  "Ready" state.
389 	 */
390 	case RESTART + READY:
391 		switch (pkp -> pk_state) {
392 		case DTE_SENT_RESTART:
393 			/* Restart collision. */
394 			pkp -> pk_state = DTE_READY;
395 			pk_message (0, pkp -> pk_xcp,
396 				"Packet level operational");
397 			break;
398 
399 		default:
400 			pk_restart (pkp, -1);
401 			pk_restartcause (pkp, xp);
402 			pkp -> pk_chan[0] -> lcd_template = pk_template (0,
403 				X25_RESTART_CONFIRM);
404 			pk_output (pkp -> pk_chan[0]);
405 		}
406 		break;
407 
408 	/*
409 	 *  Restart confirmation received. All logical channels are set
410 	 *  to READY.
411 	 */
412 	case RESTART_CONF + READY:
413 		switch (pkp -> pk_state) {
414 		case DTE_SENT_RESTART:
415 			pkp -> pk_state = DTE_READY;
416 			pk_message (0, pkp -> pk_xcp,
417 				"Packet level operational");
418 			break;
419 
420 		default:
421 			/* Restart local procedure error. */
422 			pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR);
423 			pkp -> pk_state = DTE_SENT_RESTART;
424 		}
425 		break;
426 
427 	default:
428 		if (lcp) {
429 			pk_procerror (CLEAR, lcp, "unknown packet error");
430 			pk_message (lcn, pkp -> pk_xcp,
431 				"\"%s\" unexpected in \"%s\" state",
432 				pk_name[ptype/MAXSTATES], pk_state[lcdstate]);
433 		}
434 		else	/* Packets arrived on an unassigned channel.
435 			*/
436 			pk_message ((int)xp->logical_channel_number, pkp -> pk_xcp,
437 				"packet arrived on unassigned lcn");
438 		break;
439 	}
440 	if (ptype != DATA)
441 		m_freem (m);
442 }
443 
444 
445 /*
446  * This routine handles incoming call packets. It matches the protocol
447  * field on the Call User Data field (usually the first four bytes) with
448  * sockets awaiting connections.
449  */
450 
451 static
452 incoming_call (pkp, xp, len)
453 struct pkcb *pkp;
454 struct x25_packet *xp;
455 {
456 	register struct pklcd *lcp = 0, *l;
457 	register struct sockaddr_x25 *sa;
458 	register struct x25_calladdr *a;
459 	register struct socket *so = 0;
460 	struct mbuf *m;
461 	register int l1, l2;
462 	char *e, *errstr = "server unavailable";
463 	octet *u;
464 	int lcn = xp -> logical_channel_number;
465 
466 	/* First, copy the data from the incoming call packet to a X25_socket
467 	   descriptor. */
468 
469 	a = (struct x25_calladdr *) &xp -> packet_data;
470 	l1 = a -> calling_addrlen;
471 	l2 = a -> called_addrlen;
472 	if ((m = m_getclr (M_DONTWAIT, MT_HEADER)) == 0)
473 		return;
474 	sa = mtod (m, struct sockaddr_x25 *);
475 	u = (octet *) (a -> address_field + l2 / 2);
476 	e = sa -> x25_addr;
477 	if (l2 & 0x01) {
478 		*e++ = *u++ & 0x0f;
479 		l1--;
480 	}
481 	from_bcd (e, &u, l1);
482 	if (l1 & 0x01)
483 		u++;
484 
485 	parse_facilities (u, sa);
486 	u += *u + 1;
487 	sa -> x25_udlen = min (16, ((octet *)xp) + len - u);
488 	if (sa -> x25_udlen < 0)
489 		sa -> x25_udlen = 0;
490 	bcopy ((caddr_t)u, sa -> x25_udata, (unsigned)sa -> x25_udlen);
491 
492 	/*
493 	 * Now, loop through the  listen sockets looking for a match on the
494 	 * PID. That is  the first  four octets  of the user data field.  This
495 	 * is the closest thing to a port number for X.25 packets. What it
496 	 * does provide is away of  multiplexing  services at the user level.
497 	 */
498 
499 	for (l = pk_listenhead; l; l = l -> lcd_listen) {
500 		struct sockaddr_x25 *sxp = l -> lcd_ceaddr;
501 
502 		if (bcmp (sxp -> x25_udata, sa -> x25_udata, sxp->x25_udlen))
503 			continue;
504 		if (sxp -> x25_net &&
505 		    sxp -> x25_net != pkp->pk_xc.xc_addr.x25_net)
506 			continue;
507 		/*
508 		 * don't accept incoming collect calls unless
509 		 * the server sets the reverse charging option.
510 		 */
511 		if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 &&
512 			sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) {
513 			errstr = "incoming collect call refused";
514 			break;
515 		}
516 		if (l -> lcd_so) {
517 			if (so = sonewconn (l -> lcd_so, SS_ISCONNECTED))
518 				    lcp = (struct pklcd *) so -> so_pcb;
519 		} else
520 			lcp = pk_attach((struct socket *) 0);
521 		if (lcp == 0) {
522 			/*
523 			 * Insufficient space or too many unaccepted
524 			 * connections.  Just throw the call away.
525 			 */
526 			errstr = "server malfunction";
527 			break;
528 		}
529 		lcp -> lcd_upper = l -> lcd_upper;
530 		lcp -> lcd_upnext = l -> lcd_upnext;
531 		lcp -> lcd_lcn = lcn;
532 		lcp -> lcd_state = RECEIVED_CALL;
533 		lcp -> lcd_craddr = sa;
534 		sa -> x25_opts.op_flags |= sxp -> x25_opts.op_flags &
535 			~X25_REVERSE_CHARGE;
536 		pk_assoc (pkp, lcp, sa);
537 		lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED);
538 		if (so) {
539 			pk_output (lcp);
540 			soisconnected (so);
541 		} else if (lcp->lcd_upper)
542 			(*lcp->lcd_upper)(lcp);
543 		return;
544 	}
545 
546 	/*
547 	 * If the call fails for whatever reason, we still need to build a
548 	 * skeleton LCD in order to be able to properly  receive the CLEAR
549 	 * CONFIRMATION.
550 	 */
551 #ifdef WATERLOO		/* be explicit */
552 	if (l == 0 && bcmp(sa->x25_udata, "ean", 3) == 0)
553 		pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s",
554 			sa->x25_addr, sa->x25_udata[3] & 0xff, errstr);
555 	else if (l == 0 && bcmp(sa->x25_udata, "\1\0\0\0", 4) == 0)
556 		pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s",
557 			sa->x25_addr, errstr);
558 	else
559 #endif
560 	pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s",
561 		sa -> x25_addr, sa -> x25_udata[0] & 0xff,
562 		sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff,
563 		sa -> x25_udata[3] & 0xff, errstr);
564 	if ((m = m_getclr (M_DONTWAIT, MT_HEADER)) == 0) {
565 		(void) m_free (dtom (sa));
566 		return;
567 	}
568 	lcp = mtod (m, struct pklcd *);
569 	lcp -> lcd_lcn = lcn;
570 	lcp -> lcd_state = RECEIVED_CALL;
571 	pk_assoc (pkp, lcp, sa);
572 	(void) m_free (dtom (sa));
573 	pk_clear (lcp);
574 }
575 
576 static
577 call_accepted (lcp, xp, len)
578 struct pklcd *lcp;
579 struct x25_packet *xp;
580 {
581 	register struct x25_calladdr *ap;
582 	register octet *fcp;
583 
584 	lcp -> lcd_state = DATA_TRANSFER;
585 	soisconnected (lcp -> lcd_so);
586 	if (len > 3) {
587 		ap = (struct x25_calladdr *) &xp -> packet_data;
588 		fcp = (octet *) ap -> address_field + (ap -> calling_addrlen +
589 			ap -> called_addrlen + 1) / 2;
590 		if (fcp + *fcp <= ((octet *)xp) + len)
591 			parse_facilities (fcp, lcp -> lcd_ceaddr);
592 	}
593 	pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr);
594 }
595 
596 static
597 parse_facilities (fcp, sa)
598 register octet *fcp;
599 register struct sockaddr_x25 *sa;
600 {
601 	register octet *maxfcp;
602 
603 	maxfcp = fcp + *fcp;
604 	fcp++;
605 	while (fcp < maxfcp) {
606 		/*
607 		 * Ignore national DCE or DTE facilities
608 		 */
609 		if (*fcp == 0 || *fcp == 0xff)
610 			break;
611 		switch (*fcp) {
612 		case FACILITIES_WINDOWSIZE:
613 			sa -> x25_opts.op_wsize = fcp[1];
614 			fcp += 3;
615 			break;
616 
617 		case FACILITIES_PACKETSIZE:
618 			sa -> x25_opts.op_psize = fcp[1];
619 			fcp += 3;
620 			break;
621 
622 		case FACILITIES_THROUGHPUT:
623 			sa -> x25_opts.op_speed = fcp[1];
624 			fcp += 2;
625 			break;
626 
627 		case FACILITIES_REVERSE_CHARGE:
628 			if (fcp[1] & 01)
629 				sa -> x25_opts.op_flags |= X25_REVERSE_CHARGE;
630 			/*
631 			 * Datapac specific: for a X.25(1976) DTE, bit 2
632 			 * indicates a "hi priority" (eg. international) call.
633 			 */
634 			if (fcp[1] & 02 && sa -> x25_opts.op_psize == 0)
635 				sa -> x25_opts.op_psize = X25_PS128;
636 			fcp += 2;
637 			break;
638 
639 		default:
640 /*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/
641 			switch ((*fcp & 0xc0) >> 6) {
642 			case 0:			/* class A */
643 				fcp += 2;
644 				break;
645 
646 			case 1:
647 				fcp += 3;
648 				break;
649 
650 			case 2:
651 				fcp += 4;
652 				break;
653 
654 			case 3:
655 				fcp++;
656 				fcp += *fcp;
657 			}
658 		}
659 	}
660 }
661 
662 from_bcd (a, x, len)
663 register char *a;
664 register octet **x;
665 register int len;
666 {
667 	register int posn = 0;
668 
669 	while (--len >= 0) {
670 		if (posn++ & 0x01)
671 			*a = *(*x)++ & 0x0f;
672 		else
673 			*a = (**x >> 4) & 0x0F;
674 		*a++ |= 0x30;
675 	}
676 }
677