kernel: Remove now obsolete CPU_AMD64X2_INTR_SPAM option.
[dragonfly.git] / sys / netgraph / async / ng_async.c
CommitLineData
984263bc
MD
1
2/*
3 * ng_async.c
4 *
5 * Copyright (c) 1996-1999 Whistle Communications, Inc.
6 * All rights reserved.
7 *
8 * Subject to the following obligations and disclaimer of warranty, use and
9 * redistribution of this software, in source or object code forms, with or
10 * without modifications are expressly permitted by Whistle Communications;
11 * provided, however, that:
12 * 1. Any and all reproductions of the source or object code must include the
13 * copyright notice above and the following disclaimer of warranties; and
14 * 2. No rights are granted, in any manner or form, to use Whistle
15 * Communications, Inc. trademarks, including the mark "WHISTLE
16 * COMMUNICATIONS" on advertising, endorsements, or otherwise except as
17 * such appears in the above copyright notice or in the software.
18 *
19 * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
20 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
21 * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
22 * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
24 * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
25 * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
26 * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
27 * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
28 * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
29 * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
30 * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
35 * OF SUCH DAMAGE.
36 *
37 * Author: Archie Cobbs <archie@freebsd.org>
38 *
39 * $FreeBSD: src/sys/netgraph/ng_async.c,v 1.6.2.5 2002/07/02 23:44:02 archie Exp $
40 * $Whistle: ng_async.c,v 1.17 1999/11/01 09:24:51 julian Exp $
41 */
42
43/*
44 * This node type implements a PPP style sync <-> async converter.
45 * See RFC 1661 for details of how asynchronous encoding works.
46 */
47
48#include <sys/param.h>
49#include <sys/systm.h>
50#include <sys/kernel.h>
51#include <sys/mbuf.h>
52#include <sys/malloc.h>
53#include <sys/errno.h>
54
55#include <netgraph/ng_message.h>
56#include <netgraph/netgraph.h>
1f2de5d4 57#include "ng_async.h"
984263bc
MD
58#include <netgraph/ng_parse.h>
59
d2438d69 60#include <net/ppp_layer/ppp_defs.h>
984263bc
MD
61
62/* Async decode state */
63#define MODE_HUNT 0
64#define MODE_NORMAL 1
65#define MODE_ESC 2
66
67/* Private data structure */
68struct ng_async_private {
69 node_p node; /* Our node */
70 hook_p async; /* Asynchronous side */
71 hook_p sync; /* Synchronous side */
72 u_char amode; /* Async hunt/esape mode */
73 u_int16_t fcs; /* Decoded async FCS (so far) */
74 u_char *abuf; /* Buffer to encode sync into */
75 u_char *sbuf; /* Buffer to decode async into */
76 u_int slen; /* Length of data in sbuf */
77 long lasttime; /* Time of last async packet sent */
78 struct ng_async_cfg cfg; /* Configuration */
79 struct ng_async_stat stats; /* Statistics */
80};
81typedef struct ng_async_private *sc_p;
82
83/* Useful macros */
84#define ASYNC_BUF_SIZE(smru) (2 * (smru) + 10)
85#define SYNC_BUF_SIZE(amru) ((amru) + 10)
86#define ERROUT(x) do { error = (x); goto done; } while (0)
87
88/* Netgraph methods */
89static ng_constructor_t nga_constructor;
90static ng_rcvdata_t nga_rcvdata;
91static ng_rcvmsg_t nga_rcvmsg;
92static ng_shutdown_t nga_shutdown;
93static ng_newhook_t nga_newhook;
94static ng_disconnect_t nga_disconnect;
95
96/* Helper stuff */
97static int nga_rcv_sync(const sc_p sc, struct mbuf *m, meta_p meta);
98static int nga_rcv_async(const sc_p sc, struct mbuf *m, meta_p meta);
99
100/* Parse type for struct ng_async_cfg */
101static const struct ng_parse_struct_field nga_config_type_fields[]
102 = NG_ASYNC_CONFIG_TYPE_INFO;
103static const struct ng_parse_type nga_config_type = {
104 &ng_parse_struct_type,
105 &nga_config_type_fields
106};
107
108/* Parse type for struct ng_async_stat */
109static const struct ng_parse_struct_field nga_stats_type_fields[]
110 = NG_ASYNC_STATS_TYPE_INFO;
111static const struct ng_parse_type nga_stats_type = {
112 &ng_parse_struct_type,
113 &nga_stats_type_fields
114};
115
116/* List of commands and how to convert arguments to/from ASCII */
117static const struct ng_cmdlist nga_cmdlist[] = {
118 {
119 NGM_ASYNC_COOKIE,
120 NGM_ASYNC_CMD_SET_CONFIG,
121 "setconfig",
122 &nga_config_type,
123 NULL
124 },
125 {
126 NGM_ASYNC_COOKIE,
127 NGM_ASYNC_CMD_GET_CONFIG,
128 "getconfig",
129 NULL,
130 &nga_config_type
131 },
132 {
133 NGM_ASYNC_COOKIE,
134 NGM_ASYNC_CMD_GET_STATS,
135 "getstats",
136 NULL,
137 &nga_stats_type
138 },
139 {
140 NGM_ASYNC_COOKIE,
141 NGM_ASYNC_CMD_CLR_STATS,
142 "clrstats",
143 &nga_stats_type,
144 NULL
145 },
146 { 0 }
147};
148
149/* Define the netgraph node type */
150static struct ng_type typestruct = {
151 NG_VERSION,
152 NG_ASYNC_NODE_TYPE,
153 NULL,
154 nga_constructor,
155 nga_rcvmsg,
156 nga_shutdown,
157 nga_newhook,
158 NULL,
159 NULL,
160 nga_rcvdata,
161 nga_rcvdata,
162 nga_disconnect,
163 nga_cmdlist
164};
165NETGRAPH_INIT(async, &typestruct);
166
167/* CRC table */
168static const u_int16_t fcstab[];
169
170/******************************************************************
171 NETGRAPH NODE METHODS
172******************************************************************/
173
174/*
175 * Initialize a new node
176 */
177static int
178nga_constructor(node_p *nodep)
179{
180 sc_p sc;
181 int error;
182
183 if ((error = ng_make_node_common(&typestruct, nodep)))
184 return (error);
884717e1 185 sc = kmalloc(sizeof(*sc), M_NETGRAPH, M_NOWAIT | M_ZERO);
984263bc
MD
186 if (sc == NULL)
187 return (ENOMEM);
984263bc
MD
188 sc->amode = MODE_HUNT;
189 sc->cfg.accm = ~0;
190 sc->cfg.amru = NG_ASYNC_DEFAULT_MRU;
191 sc->cfg.smru = NG_ASYNC_DEFAULT_MRU;
884717e1 192 sc->abuf = kmalloc(ASYNC_BUF_SIZE(sc->cfg.smru), M_NETGRAPH, M_NOWAIT);
984263bc
MD
193 if (sc->abuf == NULL)
194 goto fail;
884717e1 195 sc->sbuf = kmalloc(SYNC_BUF_SIZE(sc->cfg.amru), M_NETGRAPH, M_NOWAIT);
984263bc 196 if (sc->sbuf == NULL) {
884717e1 197 kfree(sc->abuf, M_NETGRAPH);
984263bc 198fail:
884717e1 199 kfree(sc, M_NETGRAPH);
984263bc
MD
200 return (ENOMEM);
201 }
202 (*nodep)->private = sc;
203 sc->node = *nodep;
204 return (0);
205}
206
207/*
208 * Reserve a hook for a pending connection
209 */
210static int
211nga_newhook(node_p node, hook_p hook, const char *name)
212{
213 const sc_p sc = node->private;
214 hook_p *hookp;
215
216 if (!strcmp(name, NG_ASYNC_HOOK_ASYNC))
217 hookp = &sc->async;
218 else if (!strcmp(name, NG_ASYNC_HOOK_SYNC))
219 hookp = &sc->sync;
220 else
221 return (EINVAL);
222 if (*hookp)
223 return (EISCONN);
224 *hookp = hook;
225 return (0);
226}
227
228/*
229 * Receive incoming data
230 */
231static int
232nga_rcvdata(hook_p hook, struct mbuf *m, meta_p meta)
233{
234 const sc_p sc = hook->node->private;
235
236 if (hook == sc->sync)
237 return (nga_rcv_sync(sc, m, meta));
238 if (hook == sc->async)
239 return (nga_rcv_async(sc, m, meta));
5e2195bf 240 panic(__func__);
984263bc
MD
241}
242
243/*
244 * Receive incoming control message
245 */
246static int
247nga_rcvmsg(node_p node, struct ng_mesg *msg,
248 const char *rtn, struct ng_mesg **rptr)
249{
250 const sc_p sc = (sc_p) node->private;
251 struct ng_mesg *resp = NULL;
252 int error = 0;
253
254 switch (msg->header.typecookie) {
255 case NGM_ASYNC_COOKIE:
256 switch (msg->header.cmd) {
257 case NGM_ASYNC_CMD_GET_STATS:
258 NG_MKRESPONSE(resp, msg, sizeof(sc->stats), M_NOWAIT);
259 if (resp == NULL)
260 ERROUT(ENOMEM);
261 *((struct ng_async_stat *) resp->data) = sc->stats;
262 break;
263 case NGM_ASYNC_CMD_CLR_STATS:
264 bzero(&sc->stats, sizeof(sc->stats));
265 break;
266 case NGM_ASYNC_CMD_SET_CONFIG:
267 {
268 struct ng_async_cfg *const cfg =
269 (struct ng_async_cfg *) msg->data;
270 u_char *buf;
271
272 if (msg->header.arglen != sizeof(*cfg))
273 ERROUT(EINVAL);
274 if (cfg->amru < NG_ASYNC_MIN_MRU
275 || cfg->amru > NG_ASYNC_MAX_MRU
276 || cfg->smru < NG_ASYNC_MIN_MRU
277 || cfg->smru > NG_ASYNC_MAX_MRU)
278 ERROUT(EINVAL);
279 cfg->enabled = !!cfg->enabled; /* normalize */
280 if (cfg->smru > sc->cfg.smru) { /* reallocate buffer */
884717e1
SW
281 buf = kmalloc(ASYNC_BUF_SIZE(cfg->smru),
282 M_NETGRAPH, M_NOWAIT);
984263bc
MD
283 if (!buf)
284 ERROUT(ENOMEM);
884717e1 285 kfree(sc->abuf, M_NETGRAPH);
984263bc
MD
286 sc->abuf = buf;
287 }
288 if (cfg->amru > sc->cfg.amru) { /* reallocate buffer */
884717e1
SW
289 buf = kmalloc(SYNC_BUF_SIZE(cfg->amru),
290 M_NETGRAPH, M_NOWAIT);
984263bc
MD
291 if (!buf)
292 ERROUT(ENOMEM);
884717e1 293 kfree(sc->sbuf, M_NETGRAPH);
984263bc
MD
294 sc->sbuf = buf;
295 sc->amode = MODE_HUNT;
296 sc->slen = 0;
297 }
298 if (!cfg->enabled) {
299 sc->amode = MODE_HUNT;
300 sc->slen = 0;
301 }
302 sc->cfg = *cfg;
303 break;
304 }
305 case NGM_ASYNC_CMD_GET_CONFIG:
306 NG_MKRESPONSE(resp, msg, sizeof(sc->cfg), M_NOWAIT);
307 if (!resp)
308 ERROUT(ENOMEM);
309 *((struct ng_async_cfg *) resp->data) = sc->cfg;
310 break;
311 default:
312 ERROUT(EINVAL);
313 }
314 break;
315 default:
316 ERROUT(EINVAL);
317 }
318 if (rptr)
319 *rptr = resp;
320 else if (resp)
884717e1 321 kfree(resp, M_NETGRAPH);
984263bc
MD
322
323done:
884717e1 324 kfree(msg, M_NETGRAPH);
984263bc
MD
325 return (error);
326}
327
328/*
329 * Shutdown this node
330 */
331static int
332nga_shutdown(node_p node)
333{
334 const sc_p sc = node->private;
335
336 ng_cutlinks(node);
337 ng_unname(node);
884717e1
SW
338 kfree(sc->abuf, M_NETGRAPH);
339 kfree(sc->sbuf, M_NETGRAPH);
984263bc 340 bzero(sc, sizeof(*sc));
884717e1 341 kfree(sc, M_NETGRAPH);
984263bc
MD
342 node->private = NULL;
343 ng_unref(node);
344 return (0);
345}
346
347/*
348 * Lose a hook. When both hooks go away, we disappear.
349 */
350static int
351nga_disconnect(hook_p hook)
352{
353 const sc_p sc = hook->node->private;
354 hook_p *hookp;
355
356 if (hook == sc->async)
357 hookp = &sc->async;
358 else if (hook == sc->sync)
359 hookp = &sc->sync;
360 else
5e2195bf 361 panic(__func__);
984263bc 362 if (!*hookp)
5e2195bf 363 panic("%s2", __func__);
984263bc
MD
364 *hookp = NULL;
365 bzero(&sc->stats, sizeof(sc->stats));
366 sc->lasttime = 0;
367 if (hook->node->numhooks == 0)
368 ng_rmnode(hook->node);
369 return (0);
370}
371
372/******************************************************************
373 INTERNAL HELPER STUFF
374******************************************************************/
375
376/*
377 * Encode a byte into the async buffer
378 */
379static __inline__ void
380nga_async_add(const sc_p sc, u_int16_t *fcs, u_int32_t accm, int *len, u_char x)
381{
382 *fcs = PPP_FCS(*fcs, x);
383 if ((x < 32 && ((1 << x) & accm))
384 || (x == PPP_ESCAPE)
385 || (x == PPP_FLAG)) {
386 sc->abuf[(*len)++] = PPP_ESCAPE;
387 x ^= PPP_TRANS;
388 }
389 sc->abuf[(*len)++] = x;
390}
391
392/*
393 * Receive incoming synchronous data.
394 */
395static int
396nga_rcv_sync(const sc_p sc, struct mbuf *m, meta_p meta)
397{
398 struct ifnet *const rcvif = m->m_pkthdr.rcvif;
399 int alen, error = 0;
400 struct timeval time;
401 u_int16_t fcs, fcs0;
402 u_int32_t accm;
403
404#define ADD_BYTE(x) nga_async_add(sc, &fcs, accm, &alen, (x))
405
406 /* Check for bypass mode */
407 if (!sc->cfg.enabled) {
408 NG_SEND_DATA(error, sc->async, m, meta);
409 return (error);
410 }
411
412 /* Get ACCM; special case LCP frames, which use full ACCM */
413 accm = sc->cfg.accm;
414 if (m->m_pkthdr.len >= 4) {
415 static const u_char lcphdr[4] = {
416 PPP_ALLSTATIONS,
417 PPP_UI,
418 (u_char)(PPP_LCP >> 8),
419 (u_char)(PPP_LCP & 0xff)
420 };
421 u_char buf[4];
422
423 m_copydata(m, 0, 4, (caddr_t)buf);
424 if (bcmp(buf, &lcphdr, 4) == 0)
425 accm = ~0;
426 }
427
428 /* Check for overflow */
429 if (m->m_pkthdr.len > sc->cfg.smru) {
430 sc->stats.syncOverflows++;
431 NG_FREE_DATA(m, meta);
432 return (EMSGSIZE);
433 }
434
435 /* Update stats */
436 sc->stats.syncFrames++;
437 sc->stats.syncOctets += m->m_pkthdr.len;
438
439 /* Initialize async encoded version of input mbuf */
440 alen = 0;
441 fcs = PPP_INITFCS;
442
443 /* Add beginning sync flag if it's been long enough to need one */
444 getmicrotime(&time);
445 if (time.tv_sec >= sc->lasttime + 1) {
446 sc->abuf[alen++] = PPP_FLAG;
447 sc->lasttime = time.tv_sec;
448 }
449
450 /* Add packet payload */
451 while (m != NULL) {
452 while (m->m_len > 0) {
453 ADD_BYTE(*mtod(m, u_char *));
454 m->m_data++;
455 m->m_len--;
456 }
457 m = m_free(m);
458 }
459
460 /* Add checksum and final sync flag */
461 fcs0 = fcs;
462 ADD_BYTE(~fcs0 & 0xff);
463 ADD_BYTE(~fcs0 >> 8);
464 sc->abuf[alen++] = PPP_FLAG;
465
466 /* Put frame in an mbuf and ship it off */
467 if (!(m = m_devget(sc->abuf, alen, 0, rcvif, NULL))) {
468 NG_FREE_META(meta);
469 error = ENOBUFS;
470 } else
471 NG_SEND_DATA(error, sc->async, m, meta);
472 return (error);
473}
474
475/*
476 * Receive incoming asynchronous data
477 * XXX Technically, we should strip out incoming characters
478 * that are in our ACCM. Not sure if this is good or not.
479 */
480static int
481nga_rcv_async(const sc_p sc, struct mbuf * m, meta_p meta)
482{
483 struct ifnet *const rcvif = m->m_pkthdr.rcvif;
484 int error;
485
486 if (!sc->cfg.enabled) {
487 NG_SEND_DATA(error, sc->sync, m, meta);
488 return (error);
489 }
490 NG_FREE_META(meta);
491 while (m) {
492 struct mbuf *n;
493
494 for (; m->m_len > 0; m->m_data++, m->m_len--) {
495 u_char ch = *mtod(m, u_char *);
496
497 sc->stats.asyncOctets++;
498 if (ch == PPP_FLAG) { /* Flag overrides everything */
499 int skip = 0;
500
501 /* Check for runts */
502 if (sc->slen < 2) {
503 if (sc->slen > 0)
504 sc->stats.asyncRunts++;
505 goto reset;
506 }
507
508 /* Verify CRC */
509 if (sc->fcs != PPP_GOODFCS) {
510 sc->stats.asyncBadCheckSums++;
511 goto reset;
512 }
513 sc->slen -= 2;
514
515 /* Strip address and control fields */
516 if (sc->slen >= 2
517 && sc->sbuf[0] == PPP_ALLSTATIONS
518 && sc->sbuf[1] == PPP_UI)
519 skip = 2;
520
521 /* Check for frame too big */
522 if (sc->slen - skip > sc->cfg.amru) {
523 sc->stats.asyncOverflows++;
524 goto reset;
525 }
526
527 /* OK, ship it out */
528 if ((n = m_devget(sc->sbuf + skip,
529 sc->slen - skip, 0, rcvif, NULL)))
530 NG_SEND_DATA(error, sc->sync, n, meta);
531 sc->stats.asyncFrames++;
532reset:
533 sc->amode = MODE_NORMAL;
534 sc->fcs = PPP_INITFCS;
535 sc->slen = 0;
536 continue;
537 }
538 switch (sc->amode) {
539 case MODE_NORMAL:
540 if (ch == PPP_ESCAPE) {
541 sc->amode = MODE_ESC;
542 continue;
543 }
544 break;
545 case MODE_ESC:
546 ch ^= PPP_TRANS;
547 sc->amode = MODE_NORMAL;
548 break;
549 case MODE_HUNT:
550 default:
551 continue;
552 }
553
554 /* Add byte to frame */
555 if (sc->slen >= SYNC_BUF_SIZE(sc->cfg.amru)) {
556 sc->stats.asyncOverflows++;
557 sc->amode = MODE_HUNT;
558 sc->slen = 0;
559 } else {
560 sc->sbuf[sc->slen++] = ch;
561 sc->fcs = PPP_FCS(sc->fcs, ch);
562 }
563 }
564 m = m_free(m);
565 }
566 return (0);
567}
568
569/*
570 * CRC table
571 *
572 * Taken from RFC 1171 Appendix B
573 */
574static const u_int16_t fcstab[256] = {
575 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
576 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
577 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
578 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
579 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
580 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
581 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
582 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
583 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
584 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
585 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
586 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
587 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
588 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
589 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
590 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
591 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
592 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
593 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
594 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
595 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
596 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
597 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
598 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
599 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
600 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
601 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
602 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
603 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
604 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
605 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
606 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
607};