diff --git a/src/.output/xdp_filter.bpf.o b/src/.output/xdp_filter.bpf.o index 8a789c7..4b77ed7 100644 Binary files a/src/.output/xdp_filter.bpf.o and b/src/.output/xdp_filter.bpf.o differ diff --git a/src/.output/xdp_filter.o b/src/.output/xdp_filter.o index 4f368d8..9025010 100644 Binary files a/src/.output/xdp_filter.o and b/src/.output/xdp_filter.o differ diff --git a/src/.output/xdp_filter.skel.h b/src/.output/xdp_filter.skel.h index e4e74f0..d6cc5be 100644 --- a/src/.output/xdp_filter.skel.h +++ b/src/.output/xdp_filter.skel.h @@ -29,7 +29,13 @@ struct xdp_filter_bpf { char xdp_receive_____fmt_6[2]; char xdp_receive_____fmt_7[54]; char xdp_receive_____fmt_8[2]; - char xdp_receive_____fmt_9[15]; + char xdp_receive_____fmt_9[38]; + char xdp_receive_____fmt_10[38]; + char xdp_receive_____fmt_11[38]; + char xdp_receive_____fmt_12[53]; + char xdp_receive_____fmt_13[38]; + char xdp_receive_____fmt_14[41]; + char expand_tcp_packet_payload_____fmt[52]; } *rodata; }; @@ -140,281 +146,431 @@ xdp_filter_bpf__create_skeleton(struct xdp_filter_bpf *obj) s->progs[0].prog = &obj->progs.xdp_receive; s->progs[0].link = &obj->links.xdp_receive; - s->data_sz = 7128; + s->data_sz = 10744; s->data = (void *)"\ \x7f\x45\x4c\x46\x02\x01\x01\0\0\0\0\0\0\0\0\0\x01\0\xf7\0\x01\0\0\0\0\0\0\0\0\ -\0\0\0\0\0\0\0\0\0\0\0\x98\x18\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\x40\0\x0d\0\ -\x0c\0\x61\x12\x04\0\0\0\0\0\x61\x11\0\0\0\0\0\0\xbf\x13\0\0\0\0\0\0\x07\x03\0\ -\0\x0e\0\0\0\x3d\x32\x04\0\0\0\0\0\x18\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb7\x02\ -\0\0\x13\0\0\0\x05\0\x11\0\0\0\0\0\xbf\x16\0\0\0\0\0\0\x07\x06\0\0\x22\0\0\0\ -\x3d\x62\x03\0\0\0\0\0\x18\x01\0\0\x13\0\0\0\0\0\0\0\0\0\0\0\x05\0\x0a\0\0\0\0\ -\0\x71\x13\x17\0\0\0\0\0\x15\x03\x03\0\x06\0\0\0\x18\x01\0\0\x15\0\0\0\0\0\0\0\ -\0\0\0\0\x05\0\x05\0\0\0\0\0\xbf\x13\0\0\0\0\0\0\x07\x03\0\0\x36\0\0\0\x3d\x32\ -\x06\0\0\0\0\0\x18\x01\0\0\x17\0\0\0\0\0\0\0\0\0\0\0\xb7\x02\0\0\x02\0\0\0\x85\ -\0\0\0\x06\0\0\0\xb7\0\0\0\x02\0\0\0\x95\0\0\0\0\0\0\0\x69\x13\x24\0\0\0\0\0\ -\x15\x03\x06\0\x23\x28\0\0\xdc\x03\0\0\x10\0\0\0\x18\x01\0\0\x19\0\0\0\0\0\0\0\ -\0\0\0\0\xb7\x02\0\0\x06\0\0\0\x85\0\0\0\x06\0\0\0\x05\0\xf6\xff\0\0\0\0\x69\ -\x13\x2e\0\0\0\0\0\x77\x03\0\0\x02\0\0\0\x57\x03\0\0\x3c\0\0\0\x69\x14\x10\0\0\ -\0\0\0\xdc\x04\0\0\x10\0\0\0\x1f\x34\0\0\0\0\0\0\x71\x11\x0e\0\0\0\0\0\x67\x01\ -\0\0\x02\0\0\0\x57\x01\0\0\x3c\0\0\0\x1f\x14\0\0\0\0\0\0\x15\x04\x03\0\x04\0\0\ -\0\x18\x01\0\0\x1f\0\0\0\0\0\0\0\0\0\0\0\x05\0\xe6\xff\0\0\0\0\x0f\x36\0\0\0\0\ -\0\0\xbf\x61\0\0\0\0\0\0\x07\x01\0\0\x04\0\0\0\x3d\x12\x03\0\0\0\0\0\x18\x01\0\ -\0\x21\0\0\0\0\0\0\0\0\0\0\0\x05\0\xdf\xff\0\0\0\0\x18\x01\0\0\x23\0\0\0\0\0\0\ -\0\0\0\0\0\xb7\x02\0\0\x36\0\0\0\xbf\x63\0\0\0\0\0\0\xb7\x04\0\0\x04\0\0\0\x85\ -\0\0\0\x06\0\0\0\x71\x61\0\0\0\0\0\0\x15\x01\x03\0\x74\0\0\0\x18\x01\0\0\x59\0\ -\0\0\0\0\0\0\0\0\0\0\x05\0\xd4\xff\0\0\0\0\x71\x61\x01\0\0\0\0\0\x55\x01\xfb\ -\xff\x65\0\0\0\x71\x61\x02\0\0\0\0\0\x55\x01\xf9\xff\x73\0\0\0\x71\x61\x03\0\0\ -\0\0\0\x55\x01\xf7\xff\x74\0\0\0\x18\x01\0\0\x5b\0\0\0\0\0\0\0\0\0\0\0\xb7\x02\ -\0\0\x0f\0\0\0\x85\0\0\0\x06\0\0\0\xb7\x01\0\0\x62\0\0\0\x73\x16\x01\0\0\0\0\0\ -\x05\0\xc9\xff\0\0\0\0\x44\x75\x61\x6c\x20\x42\x53\x44\x2f\x47\x50\x4c\0\x42\ -\x6f\x75\x6e\x64\x20\x63\x68\x65\x63\x6b\x20\x66\x61\x69\x6c\x20\x41\0\x42\0\ -\x43\0\x44\0\x45\x20\x25\x69\x0a\0\x46\0\x47\0\x52\x65\x63\x65\x69\x76\x65\x64\ -\x20\x76\x61\x6c\x69\x64\x20\x54\x43\x50\x20\x70\x61\x63\x6b\x65\x74\x20\x77\ -\x69\x74\x68\x20\x70\x61\x79\x6c\x6f\x61\x64\x20\x25\x73\x20\x6f\x66\x20\x73\ -\x69\x7a\x65\x20\x25\x69\x0a\0\x48\0\x42\x50\x46\x20\x66\x69\x6e\x69\x73\x68\ -\x65\x64\x0a\x20\0\x9f\xeb\x01\0\x18\0\0\0\0\0\0\0\xb4\x02\0\0\xb4\x02\0\0\x26\ -\x07\0\0\0\0\0\0\0\0\0\x02\x02\0\0\0\x01\0\0\0\x06\0\0\x04\x18\0\0\0\x08\0\0\0\ -\x03\0\0\0\0\0\0\0\x0d\0\0\0\x03\0\0\0\x20\0\0\0\x16\0\0\0\x03\0\0\0\x40\0\0\0\ -\x20\0\0\0\x03\0\0\0\x60\0\0\0\x30\0\0\0\x03\0\0\0\x80\0\0\0\x3f\0\0\0\x03\0\0\ -\0\xa0\0\0\0\x4e\0\0\0\0\0\0\x08\x04\0\0\0\x54\0\0\0\0\0\0\x01\x04\0\0\0\x20\0\ -\0\0\0\0\0\0\x01\0\0\x0d\x06\0\0\0\x61\0\0\0\x01\0\0\0\x65\0\0\0\0\0\0\x01\x04\ -\0\0\0\x20\0\0\x01\x69\0\0\0\x01\0\0\x0c\x05\0\0\0\x1b\x06\0\0\0\0\0\x01\x01\0\ -\0\0\x08\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x08\0\0\0\x0a\0\0\0\x0d\0\0\0\x20\ -\x06\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\0\x34\x06\0\0\0\0\0\x0e\x09\0\0\0\x01\0\0\ -\0\0\0\0\0\0\0\0\x0a\x08\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x0c\0\0\0\x0a\0\0\0\ -\x13\0\0\0\x3c\x06\0\0\0\0\0\x0e\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\ -\x0c\0\0\0\x0a\0\0\0\x02\0\0\0\x50\x06\0\0\0\0\0\x0e\x0f\0\0\0\0\0\0\0\x66\x06\ -\0\0\0\0\0\x0e\x0f\0\0\0\0\0\0\0\x7c\x06\0\0\0\0\0\x0e\x0f\0\0\0\0\0\0\0\0\0\0\ -\0\0\0\0\x03\0\0\0\0\x0c\0\0\0\x0a\0\0\0\x06\0\0\0\x92\x06\0\0\0\0\0\x0e\x13\0\ -\0\0\0\0\0\0\xa8\x06\0\0\0\0\0\x0e\x0f\0\0\0\0\0\0\0\xbe\x06\0\0\0\0\0\x0e\x0f\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x0c\0\0\0\x0a\0\0\0\x36\0\0\0\xd4\x06\ -\0\0\0\0\0\x0e\x17\0\0\0\0\0\0\0\xea\x06\0\0\0\0\0\x0e\x0f\0\0\0\0\0\0\0\0\0\0\ -\0\0\0\0\x03\0\0\0\0\x0c\0\0\0\x0a\0\0\0\x0f\0\0\0\0\x07\0\0\0\0\0\x0e\x1a\0\0\ -\0\0\0\0\0\x16\x07\0\0\x0a\0\0\x0f\0\0\0\0\x0e\0\0\0\0\0\0\0\x13\0\0\0\x10\0\0\ -\0\x13\0\0\0\x02\0\0\0\x11\0\0\0\x15\0\0\0\x02\0\0\0\x12\0\0\0\x17\0\0\0\x02\0\ -\0\0\x14\0\0\0\x19\0\0\0\x06\0\0\0\x15\0\0\0\x1f\0\0\0\x02\0\0\0\x16\0\0\0\x21\ -\0\0\0\x02\0\0\0\x18\0\0\0\x23\0\0\0\x36\0\0\0\x19\0\0\0\x59\0\0\0\x02\0\0\0\ -\x1b\0\0\0\x5b\0\0\0\x0f\0\0\0\x1e\x07\0\0\x01\0\0\x0f\0\0\0\0\x0b\0\0\0\0\0\0\ -\0\x0d\0\0\0\0\x78\x64\x70\x5f\x6d\x64\0\x64\x61\x74\x61\0\x64\x61\x74\x61\x5f\ -\x65\x6e\x64\0\x64\x61\x74\x61\x5f\x6d\x65\x74\x61\0\x69\x6e\x67\x72\x65\x73\ -\x73\x5f\x69\x66\x69\x6e\x64\x65\x78\0\x72\x78\x5f\x71\x75\x65\x75\x65\x5f\x69\ -\x6e\x64\x65\x78\0\x65\x67\x72\x65\x73\x73\x5f\x69\x66\x69\x6e\x64\x65\x78\0\ -\x5f\x5f\x75\x33\x32\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\0\x63\ +\0\0\0\0\0\0\0\0\0\0\0\xb8\x26\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\x40\0\x0d\0\ +\x0c\0\xbf\x17\0\0\0\0\0\0\x61\x76\x04\0\0\0\0\0\x61\x79\0\0\0\0\0\0\xbf\x91\0\ +\0\0\0\0\0\x07\x01\0\0\x0e\0\0\0\x3d\x16\x04\0\0\0\0\0\x18\x01\0\0\0\0\0\0\0\0\ +\0\0\0\0\0\0\xb7\x02\0\0\x13\0\0\0\x05\0\x11\0\0\0\0\0\xbf\x98\0\0\0\0\0\0\x07\ +\x08\0\0\x22\0\0\0\x3d\x86\x03\0\0\0\0\0\x18\x01\0\0\x13\0\0\0\0\0\0\0\0\0\0\0\ +\x05\0\x0a\0\0\0\0\0\x71\x91\x17\0\0\0\0\0\x15\x01\x03\0\x06\0\0\0\x18\x01\0\0\ +\x15\0\0\0\0\0\0\0\0\0\0\0\x05\0\x05\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x07\x01\0\0\ +\x36\0\0\0\x3d\x16\x06\0\0\0\0\0\x18\x01\0\0\x17\0\0\0\0\0\0\0\0\0\0\0\xb7\x02\ +\0\0\x02\0\0\0\x85\0\0\0\x06\0\0\0\xb7\0\0\0\x02\0\0\0\x95\0\0\0\0\0\0\0\x69\ +\x93\x24\0\0\0\0\0\x15\x03\x06\0\x23\x28\0\0\xdc\x03\0\0\x10\0\0\0\x18\x01\0\0\ +\x19\0\0\0\0\0\0\0\0\0\0\0\xb7\x02\0\0\x06\0\0\0\x85\0\0\0\x06\0\0\0\x05\0\xf6\ +\xff\0\0\0\0\x69\x91\x2e\0\0\0\0\0\x77\x01\0\0\x02\0\0\0\x57\x01\0\0\x3c\0\0\0\ +\x69\x92\x10\0\0\0\0\0\xdc\x02\0\0\x10\0\0\0\x1f\x12\0\0\0\0\0\0\x71\x93\x0e\0\ +\0\0\0\0\x67\x03\0\0\x02\0\0\0\x57\x03\0\0\x3c\0\0\0\x1f\x32\0\0\0\0\0\0\x15\ +\x02\x03\0\x04\0\0\0\x18\x01\0\0\x1f\0\0\0\0\0\0\0\0\0\0\0\x05\0\xe6\xff\0\0\0\ +\0\x0f\x18\0\0\0\0\0\0\xbf\x81\0\0\0\0\0\0\x07\x01\0\0\x04\0\0\0\x3d\x16\x03\0\ +\0\0\0\0\x18\x01\0\0\x21\0\0\0\0\0\0\0\0\0\0\0\x05\0\xdf\xff\0\0\0\0\x18\x01\0\ +\0\x23\0\0\0\0\0\0\0\0\0\0\0\xb7\x02\0\0\x36\0\0\0\xbf\x83\0\0\0\0\0\0\xb7\x04\ +\0\0\x04\0\0\0\x85\0\0\0\x06\0\0\0\x71\x81\0\0\0\0\0\0\x15\x01\x03\0\x74\0\0\0\ +\x18\x01\0\0\x59\0\0\0\0\0\0\0\0\0\0\0\x05\0\xd4\xff\0\0\0\0\x71\x81\x01\0\0\0\ +\0\0\x55\x01\xfb\xff\x65\0\0\0\x71\x81\x02\0\0\0\0\0\x55\x01\xf9\xff\x73\0\0\0\ +\x71\x81\x03\0\0\0\0\0\x55\x01\xf7\xff\x74\0\0\0\xbf\x71\0\0\0\0\0\0\xb7\x02\0\ +\0\x02\0\0\0\x85\0\0\0\x41\0\0\0\x15\0\x14\0\0\0\0\0\x18\x01\0\0\x51\x01\0\0\0\ +\0\0\0\0\0\0\0\xb7\x02\0\0\x34\0\0\0\xb7\x03\0\0\x02\0\0\0\x85\0\0\0\x06\0\0\0\ +\x18\x01\0\0\x02\x01\0\0\0\0\0\0\0\0\0\0\xb7\x02\0\0\x26\0\0\0\x85\0\0\0\x06\0\ +\0\0\xbf\x97\0\0\0\0\0\0\xbf\x68\0\0\0\0\0\0\x1f\x96\0\0\0\0\0\0\x1f\x78\0\0\0\ +\0\0\0\x18\x01\0\0\x28\x01\0\0\0\0\0\0\0\0\0\0\xb7\x02\0\0\x29\0\0\0\xbf\x63\0\ +\0\0\0\0\0\xbf\x84\0\0\0\0\0\0\x85\0\0\0\x06\0\0\0\x05\0\xb8\xff\0\0\0\0\x61\ +\x78\x04\0\0\0\0\0\x61\x77\0\0\0\0\0\0\xbf\x71\0\0\0\0\0\0\x07\x01\0\0\x0e\0\0\ +\0\x3d\x18\x03\0\0\0\0\0\x18\x01\0\0\x5b\0\0\0\0\0\0\0\0\0\0\0\x05\0\x0b\0\0\0\ +\0\0\xbf\x74\0\0\0\0\0\0\x07\x04\0\0\x22\0\0\0\x3d\x48\x03\0\0\0\0\0\x18\x01\0\ +\0\x81\0\0\0\0\0\0\0\0\0\0\0\x05\0\x05\0\0\0\0\0\xbf\x71\0\0\0\0\0\0\x07\x01\0\ +\0\x36\0\0\0\x3d\x18\x04\0\0\0\0\0\x18\x01\0\0\xa7\0\0\0\0\0\0\0\0\0\0\0\xb7\ +\x02\0\0\x26\0\0\0\x05\0\xa2\xff\0\0\0\0\x69\x75\x10\0\0\0\0\0\xdc\x05\0\0\x10\ +\0\0\0\x69\x71\x2e\0\0\0\0\0\x77\x01\0\0\x02\0\0\0\x57\x01\0\0\x3c\0\0\0\x0f\ +\x14\0\0\0\0\0\0\x1f\x15\0\0\0\0\0\0\x71\x71\x0e\0\0\0\0\0\x67\x01\0\0\x02\0\0\ +\0\x57\x01\0\0\x3c\0\0\0\x1f\x15\0\0\0\0\0\0\x18\x01\0\0\xcd\0\0\0\0\0\0\0\0\0\ +\0\0\xb7\x02\0\0\x35\0\0\0\xb7\x03\0\0\0\0\0\0\x85\0\0\0\x06\0\0\0\x05\0\xd1\ +\xff\0\0\0\0\x44\x75\x61\x6c\x20\x42\x53\x44\x2f\x47\x50\x4c\0\x42\x6f\x75\x6e\ +\x64\x20\x63\x68\x65\x63\x6b\x20\x66\x61\x69\x6c\x20\x41\0\x42\0\x43\0\x44\0\ +\x45\x20\x25\x69\x0a\0\x46\0\x47\0\x52\x65\x63\x65\x69\x76\x65\x64\x20\x76\x61\ +\x6c\x69\x64\x20\x54\x43\x50\x20\x70\x61\x63\x6b\x65\x74\x20\x77\x69\x74\x68\ +\x20\x70\x61\x79\x6c\x6f\x61\x64\x20\x25\x73\x20\x6f\x66\x20\x73\x69\x7a\x65\ +\x20\x25\x69\x0a\0\x48\0\x42\x6f\x75\x6e\x64\x20\x63\x68\x65\x63\x6b\x20\x41\ +\x20\x66\x61\x69\x6c\x65\x64\x20\x77\x68\x69\x6c\x65\x20\x65\x78\x70\x61\x6e\ +\x64\x69\x6e\x67\x0a\0\x42\x6f\x75\x6e\x64\x20\x63\x68\x65\x63\x6b\x20\x42\x20\ +\x66\x61\x69\x6c\x65\x64\x20\x77\x68\x69\x6c\x65\x20\x65\x78\x70\x61\x6e\x64\ +\x69\x6e\x67\x0a\0\x42\x6f\x75\x6e\x64\x20\x63\x68\x65\x63\x6b\x20\x44\x20\x66\ +\x61\x69\x6c\x65\x64\x20\x77\x68\x69\x6c\x65\x20\x65\x78\x70\x61\x6e\x64\x69\ +\x6e\x67\x0a\0\x42\x50\x46\x20\x66\x69\x6e\x69\x73\x68\x65\x64\x20\x77\x69\x74\ +\x68\x20\x72\x65\x74\x20\x25\x69\x20\x61\x6e\x64\x20\x70\x61\x79\x6c\x6f\x61\ +\x64\x20\x25\x73\x20\x6f\x66\x20\x73\x69\x7a\x65\x20\x25\x69\x0a\x20\0\x42\x50\ +\x46\x20\x66\x69\x6e\x69\x73\x68\x65\x64\x20\x77\x69\x74\x68\x20\x65\x72\x72\ +\x6f\x72\x20\x6f\x6e\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e\x0a\0\x50\x72\x65\ +\x76\x69\x6f\x75\x73\x20\x6c\x65\x6e\x67\x74\x68\x3a\x20\x25\x69\x2c\x20\x63\ +\x75\x72\x72\x65\x6e\x74\x20\x6c\x65\x6e\x67\x74\x68\x3a\x20\x25\x69\x0a\0\x46\ +\x61\x69\x6c\x65\x64\x20\x74\x6f\x20\x65\x78\x70\x61\x6e\x64\x20\x61\x20\x74\ +\x63\x70\x20\x70\x61\x63\x6b\x65\x74\x20\x72\x65\x73\x65\x72\x76\x65\x64\x20\ +\x62\x79\x74\x65\x73\x20\x62\x79\x20\x25\x69\x0a\0\x9f\xeb\x01\0\x18\0\0\0\0\0\ +\0\0\xa4\x03\0\0\xa4\x03\0\0\x97\x0b\0\0\0\0\0\0\0\0\0\x02\x02\0\0\0\x01\0\0\0\ +\x06\0\0\x04\x18\0\0\0\x08\0\0\0\x03\0\0\0\0\0\0\0\x0d\0\0\0\x03\0\0\0\x20\0\0\ +\0\x16\0\0\0\x03\0\0\0\x40\0\0\0\x20\0\0\0\x03\0\0\0\x60\0\0\0\x30\0\0\0\x03\0\ +\0\0\x80\0\0\0\x3f\0\0\0\x03\0\0\0\xa0\0\0\0\x4e\0\0\0\0\0\0\x08\x04\0\0\0\x54\ +\0\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\0\0\0\0\0\x01\0\0\x0d\x06\0\0\0\x61\0\0\0\ +\x01\0\0\0\x65\0\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\x01\x69\0\0\0\x01\0\0\x0c\x05\ +\0\0\0\xf7\x09\0\0\0\0\0\x01\x01\0\0\0\x08\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\ +\x08\0\0\0\x0a\0\0\0\x0d\0\0\0\xfc\x09\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\0\x10\ +\x0a\0\0\0\0\0\x0e\x09\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\x0a\x08\0\0\0\0\0\0\0\0\0\ +\0\x03\0\0\0\0\x0c\0\0\0\x0a\0\0\0\x13\0\0\0\x18\x0a\0\0\0\0\0\x0e\x0d\0\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x0c\0\0\0\x0a\0\0\0\x02\0\0\0\x2c\x0a\0\0\0\0\ +\0\x0e\x0f\0\0\0\0\0\0\0\x42\x0a\0\0\0\0\0\x0e\x0f\0\0\0\0\0\0\0\x58\x0a\0\0\0\ +\0\0\x0e\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x0c\0\0\0\x0a\0\0\0\x06\0\ +\0\0\x6e\x0a\0\0\0\0\0\x0e\x13\0\0\0\0\0\0\0\x84\x0a\0\0\0\0\0\x0e\x0f\0\0\0\0\ +\0\0\0\x9a\x0a\0\0\0\0\0\x0e\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x0c\0\ +\0\0\x0a\0\0\0\x36\0\0\0\xb0\x0a\0\0\0\0\0\x0e\x17\0\0\0\0\0\0\0\xc6\x0a\0\0\0\ +\0\0\x0e\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x0c\0\0\0\x0a\0\0\0\x26\0\ +\0\0\xdc\x0a\0\0\0\0\0\x0e\x1a\0\0\0\0\0\0\0\xf2\x0a\0\0\0\0\0\x0e\x1a\0\0\0\0\ +\0\0\0\x09\x0b\0\0\0\0\0\x0e\x1a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x0c\0\ +\0\0\x0a\0\0\0\x35\0\0\0\x20\x0b\0\0\0\0\0\x0e\x1e\0\0\0\0\0\0\0\x37\x0b\0\0\0\ +\0\0\x0e\x1a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x0c\0\0\0\x0a\0\0\0\x29\0\ +\0\0\x4e\x0b\0\0\0\0\0\x0e\x21\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x0c\0\0\ +\0\x0a\0\0\0\x34\0\0\0\x65\x0b\0\0\0\0\0\x0e\x23\0\0\0\0\0\0\0\x87\x0b\0\0\x10\ +\0\0\x0f\0\0\0\0\x0e\0\0\0\0\0\0\0\x13\0\0\0\x10\0\0\0\x13\0\0\0\x02\0\0\0\x11\ +\0\0\0\x15\0\0\0\x02\0\0\0\x12\0\0\0\x17\0\0\0\x02\0\0\0\x14\0\0\0\x19\0\0\0\ +\x06\0\0\0\x15\0\0\0\x1f\0\0\0\x02\0\0\0\x16\0\0\0\x21\0\0\0\x02\0\0\0\x18\0\0\ +\0\x23\0\0\0\x36\0\0\0\x19\0\0\0\x59\0\0\0\x02\0\0\0\x1b\0\0\0\x5b\0\0\0\x26\0\ +\0\0\x1c\0\0\0\x81\0\0\0\x26\0\0\0\x1d\0\0\0\xa7\0\0\0\x26\0\0\0\x1f\0\0\0\xcd\ +\0\0\0\x35\0\0\0\x20\0\0\0\x02\x01\0\0\x26\0\0\0\x22\0\0\0\x28\x01\0\0\x29\0\0\ +\0\x24\0\0\0\x51\x01\0\0\x34\0\0\0\x8f\x0b\0\0\x01\0\0\x0f\0\0\0\0\x0b\0\0\0\0\ +\0\0\0\x0d\0\0\0\0\x78\x64\x70\x5f\x6d\x64\0\x64\x61\x74\x61\0\x64\x61\x74\x61\ +\x5f\x65\x6e\x64\0\x64\x61\x74\x61\x5f\x6d\x65\x74\x61\0\x69\x6e\x67\x72\x65\ +\x73\x73\x5f\x69\x66\x69\x6e\x64\x65\x78\0\x72\x78\x5f\x71\x75\x65\x75\x65\x5f\ +\x69\x6e\x64\x65\x78\0\x65\x67\x72\x65\x73\x73\x5f\x69\x66\x69\x6e\x64\x65\x78\ +\0\x5f\x5f\x75\x33\x32\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\0\x63\ \x74\x78\0\x69\x6e\x74\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\0\x78\x64\ \x70\x5f\x70\x72\x6f\x67\0\x2f\x68\x6f\x6d\x65\x2f\x6f\x73\x62\x6f\x78\x65\x73\ \x2f\x54\x46\x47\x2f\x73\x72\x63\x2f\x65\x62\x70\x66\x2f\x78\x64\x70\x5f\x66\ -\x69\x6c\x74\x65\x72\x2e\x62\x70\x66\x2e\x63\0\x20\x20\x20\x20\x76\x6f\x69\x64\ -\x20\x2a\x64\x61\x74\x61\x5f\x65\x6e\x64\x20\x3d\x20\x28\x76\x6f\x69\x64\x20\ -\x2a\x29\x28\x6c\x6f\x6e\x67\x29\x63\x74\x78\x2d\x3e\x64\x61\x74\x61\x5f\x65\ -\x6e\x64\x3b\0\x20\x20\x20\x20\x76\x6f\x69\x64\x20\x2a\x64\x61\x74\x61\x20\x3d\ -\x20\x28\x76\x6f\x69\x64\x20\x2a\x29\x28\x6c\x6f\x6e\x67\x29\x63\x74\x78\x2d\ -\x3e\x64\x61\x74\x61\x3b\0\x2f\x68\x6f\x6d\x65\x2f\x6f\x73\x62\x6f\x78\x65\x73\ -\x2f\x54\x46\x47\x2f\x73\x72\x63\x2f\x69\x6e\x63\x6c\x75\x64\x65\x2f\x70\x61\ -\x63\x6b\x65\x74\x2f\x70\x61\x63\x6b\x65\x74\x5f\x6d\x61\x6e\x61\x67\x65\x72\ -\x2e\x68\0\x20\x20\x20\x20\x69\x66\x20\x28\x28\x76\x6f\x69\x64\x20\x2a\x29\x65\ -\x74\x68\x20\x2b\x20\x73\x69\x7a\x65\x6f\x66\x28\x73\x74\x72\x75\x63\x74\x20\ -\x65\x74\x68\x68\x64\x72\x29\x20\x3e\x20\x64\x61\x74\x61\x5f\x65\x6e\x64\x29\ -\x7b\0\x20\x20\x20\x20\x69\x66\x28\x65\x74\x68\x65\x72\x6e\x65\x74\x5f\x68\x65\ -\x61\x64\x65\x72\x5f\x62\x6f\x75\x6e\x64\x5f\x63\x68\x65\x63\x6b\x28\x65\x74\ -\x68\x2c\x20\x64\x61\x74\x61\x5f\x65\x6e\x64\x29\x3c\x30\x29\x7b\0\x20\x20\x20\ -\x20\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x42\x6f\ -\x75\x6e\x64\x20\x63\x68\x65\x63\x6b\x20\x66\x61\x69\x6c\x20\x41\x22\x29\x3b\0\ -\x20\x20\x20\x20\x69\x66\x20\x28\x28\x76\x6f\x69\x64\x20\x2a\x29\x69\x70\x20\ -\x2b\x20\x73\x69\x7a\x65\x6f\x66\x28\x2a\x69\x70\x29\x20\x3e\x20\x64\x61\x74\ -\x61\x5f\x65\x6e\x64\x29\x7b\0\x20\x20\x20\x20\x69\x66\x20\x28\x69\x70\x5f\x68\ +\x69\x6c\x74\x65\x72\x2e\x62\x70\x66\x2e\x63\0\x69\x6e\x74\x20\x78\x64\x70\x5f\ +\x72\x65\x63\x65\x69\x76\x65\x28\x73\x74\x72\x75\x63\x74\x20\x78\x64\x70\x5f\ +\x6d\x64\x20\x2a\x63\x74\x78\x29\0\x20\x20\x20\x20\x76\x6f\x69\x64\x20\x2a\x64\ +\x61\x74\x61\x5f\x65\x6e\x64\x20\x3d\x20\x28\x76\x6f\x69\x64\x20\x2a\x29\x28\ +\x6c\x6f\x6e\x67\x29\x63\x74\x78\x2d\x3e\x64\x61\x74\x61\x5f\x65\x6e\x64\x3b\0\ +\x20\x20\x20\x20\x76\x6f\x69\x64\x20\x2a\x64\x61\x74\x61\x20\x3d\x20\x28\x76\ +\x6f\x69\x64\x20\x2a\x29\x28\x6c\x6f\x6e\x67\x29\x63\x74\x78\x2d\x3e\x64\x61\ +\x74\x61\x3b\0\x2f\x68\x6f\x6d\x65\x2f\x6f\x73\x62\x6f\x78\x65\x73\x2f\x54\x46\ +\x47\x2f\x73\x72\x63\x2f\x69\x6e\x63\x6c\x75\x64\x65\x2f\x70\x61\x63\x6b\x65\ +\x74\x2f\x70\x61\x63\x6b\x65\x74\x5f\x6d\x61\x6e\x61\x67\x65\x72\x2e\x68\0\x20\ +\x20\x20\x20\x69\x66\x20\x28\x28\x76\x6f\x69\x64\x20\x2a\x29\x65\x74\x68\x20\ +\x2b\x20\x73\x69\x7a\x65\x6f\x66\x28\x73\x74\x72\x75\x63\x74\x20\x65\x74\x68\ +\x68\x64\x72\x29\x20\x3e\x20\x64\x61\x74\x61\x5f\x65\x6e\x64\x29\x7b\0\x20\x20\ +\x20\x20\x69\x66\x28\x65\x74\x68\x65\x72\x6e\x65\x74\x5f\x68\x65\x61\x64\x65\ +\x72\x5f\x62\x6f\x75\x6e\x64\x5f\x63\x68\x65\x63\x6b\x28\x65\x74\x68\x2c\x20\ +\x64\x61\x74\x61\x5f\x65\x6e\x64\x29\x3c\x30\x29\x7b\0\x20\x20\x20\x20\x20\x20\ +\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x42\x6f\x75\x6e\x64\ +\x20\x63\x68\x65\x63\x6b\x20\x66\x61\x69\x6c\x20\x41\x22\x29\x3b\0\x20\x20\x20\ +\x20\x69\x66\x20\x28\x28\x76\x6f\x69\x64\x20\x2a\x29\x69\x70\x20\x2b\x20\x73\ +\x69\x7a\x65\x6f\x66\x28\x2a\x69\x70\x29\x20\x3e\x20\x64\x61\x74\x61\x5f\x65\ +\x6e\x64\x29\x7b\0\x20\x20\x20\x20\x69\x66\x20\x28\x69\x70\x5f\x68\x65\x61\x64\ +\x65\x72\x5f\x62\x6f\x75\x6e\x64\x5f\x63\x68\x65\x63\x6b\x28\x69\x70\x2c\x20\ +\x64\x61\x74\x61\x5f\x65\x6e\x64\x29\x3c\x30\x29\x7b\0\x20\x20\x20\x20\x20\x20\ +\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x42\x22\x29\x3b\0\x20\ +\x20\x20\x20\x73\x77\x69\x74\x63\x68\x28\x69\x70\x2d\x3e\x70\x72\x6f\x74\x6f\ +\x63\x6f\x6c\x29\x7b\0\x20\x20\x20\x20\x69\x66\x20\x28\x67\x65\x74\x5f\x70\x72\ +\x6f\x74\x6f\x63\x6f\x6c\x28\x64\x61\x74\x61\x29\x20\x21\x3d\x20\x49\x50\x50\ +\x52\x4f\x54\x4f\x5f\x54\x43\x50\x29\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x62\ +\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x43\x22\x29\x3b\0\x20\x20\x20\x20\ +\x69\x66\x20\x28\x28\x76\x6f\x69\x64\x20\x2a\x29\x74\x63\x70\x20\x2b\x20\x73\ +\x69\x7a\x65\x6f\x66\x28\x2a\x74\x63\x70\x29\x20\x3e\x20\x64\x61\x74\x61\x5f\ +\x65\x6e\x64\x29\x7b\0\x20\x20\x20\x20\x69\x66\x20\x28\x74\x63\x70\x5f\x68\x65\ +\x61\x64\x65\x72\x5f\x62\x6f\x75\x6e\x64\x5f\x63\x68\x65\x63\x6b\x28\x74\x63\ +\x70\x2c\x20\x64\x61\x74\x61\x5f\x65\x6e\x64\x29\x29\x7b\0\x20\x20\x20\x20\x20\ +\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x44\x22\x29\x3b\0\ +\x7d\0\x2f\x68\x6f\x6d\x65\x2f\x6f\x73\x62\x6f\x78\x65\x73\x2f\x54\x46\x47\x2f\ +\x73\x72\x63\x2f\x69\x6e\x63\x6c\x75\x64\x65\x2f\x70\x61\x63\x6b\x65\x74\x2f\ +\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x2f\x74\x63\x70\x5f\x68\x65\x6c\x70\x65\x72\ +\x2e\x68\0\x20\x20\x20\x20\x72\x65\x74\x75\x72\x6e\x20\x6e\x74\x6f\x68\x73\x28\ +\x74\x63\x70\x2d\x3e\x64\x65\x73\x74\x29\x3b\0\x20\x20\x20\x20\x69\x66\x20\x28\ +\x67\x65\x74\x5f\x74\x63\x70\x5f\x64\x65\x73\x74\x5f\x70\x6f\x72\x74\x28\x74\ +\x63\x70\x29\x20\x21\x3d\x20\x53\x45\x43\x52\x45\x54\x5f\x50\x41\x43\x4b\x45\ +\x54\x5f\x44\x45\x53\x54\x5f\x50\x4f\x52\x54\x29\x7b\0\x20\x20\x20\x20\x20\x20\ +\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x45\x20\x25\x69\x5c\ +\x6e\x22\x2c\x20\x6e\x74\x6f\x68\x73\x28\x74\x63\x70\x2d\x3e\x64\x65\x73\x74\ +\x29\x29\x3b\0\x20\x20\x20\x20\x70\x61\x79\x6c\x6f\x61\x64\x5f\x73\x69\x7a\x65\ +\x20\x3d\x20\x6e\x74\x6f\x68\x73\x28\x69\x70\x2d\x3e\x74\x6f\x74\x5f\x6c\x65\ +\x6e\x29\x20\x2d\x20\x28\x74\x63\x70\x2d\x3e\x64\x6f\x66\x66\x20\x2a\x20\x34\ +\x29\x20\x2d\x20\x28\x69\x70\x2d\x3e\x69\x68\x6c\x20\x2a\x20\x34\x29\x3b\0\x20\ +\x20\x20\x20\x69\x66\x20\x28\x70\x61\x79\x6c\x6f\x61\x64\x5f\x73\x69\x7a\x65\ +\x20\x21\x3d\x20\x73\x69\x7a\x65\x6f\x66\x28\x6d\x61\x74\x63\x68\x5f\x70\x61\ +\x74\x74\x65\x72\x6e\x29\x20\x2d\x20\x31\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\ +\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x46\x22\x29\x3b\0\x20\ +\x20\x20\x20\x69\x66\x20\x28\x28\x76\x6f\x69\x64\x20\x2a\x29\x70\x61\x79\x6c\ +\x6f\x61\x64\x20\x2b\x20\x70\x61\x79\x6c\x6f\x61\x64\x5f\x73\x69\x7a\x65\x20\ +\x3e\x20\x64\x61\x74\x61\x5f\x65\x6e\x64\x29\x7b\0\x20\x20\x20\x20\x69\x66\x20\ +\x28\x74\x63\x70\x5f\x70\x61\x79\x6c\x6f\x61\x64\x5f\x62\x6f\x75\x6e\x64\x5f\ +\x63\x68\x65\x63\x6b\x28\x70\x61\x79\x6c\x6f\x61\x64\x2c\x20\x70\x61\x79\x6c\ +\x6f\x61\x64\x5f\x73\x69\x7a\x65\x2c\x20\x64\x61\x74\x61\x5f\x65\x6e\x64\x29\ +\x29\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\ +\x6b\x28\x22\x47\x22\x29\x3b\0\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\ +\x74\x6b\x28\x22\x52\x65\x63\x65\x69\x76\x65\x64\x20\x76\x61\x6c\x69\x64\x20\ +\x54\x43\x50\x20\x70\x61\x63\x6b\x65\x74\x20\x77\x69\x74\x68\x20\x70\x61\x79\ +\x6c\x6f\x61\x64\x20\x25\x73\x20\x6f\x66\x20\x73\x69\x7a\x65\x20\x25\x69\x5c\ +\x6e\x22\x2c\x20\x70\x61\x79\x6c\x6f\x61\x64\x2c\x20\x70\x61\x79\x6c\x6f\x61\ +\x64\x5f\x73\x69\x7a\x65\x29\x3b\0\x2f\x68\x6f\x6d\x65\x2f\x6f\x73\x62\x6f\x78\ +\x65\x73\x2f\x54\x46\x47\x2f\x73\x72\x63\x2f\x69\x6e\x63\x6c\x75\x64\x65\x2f\ +\x63\x6f\x6d\x6d\x6f\x6e\x2f\x63\x6f\x6d\x6d\x6f\x6e\x5f\x75\x74\x69\x6c\x73\ +\x2e\x68\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x73\x74\x72\x31\x5b\ +\x69\x69\x5d\x20\x21\x3d\x20\x73\x74\x72\x32\x5b\x69\x69\x5d\x29\x7b\0\x20\x20\ +\x20\x20\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x48\ +\x22\x29\x3b\0\x2f\x68\x6f\x6d\x65\x2f\x6f\x73\x62\x6f\x78\x65\x73\x2f\x54\x46\ +\x47\x2f\x73\x72\x63\x2f\x69\x6e\x63\x6c\x75\x64\x65\x2f\x78\x64\x70\x2f\x78\ +\x64\x70\x5f\x68\x65\x6c\x70\x65\x72\x2e\x68\0\x20\x20\x20\x20\x69\x66\x20\x28\ +\x62\x70\x66\x5f\x78\x64\x70\x5f\x61\x64\x6a\x75\x73\x74\x5f\x74\x61\x69\x6c\ +\x28\x63\x74\x78\x2c\x20\x28\x69\x6e\x74\x29\x28\x73\x69\x7a\x65\x6f\x66\x28\ +\x63\x68\x61\x72\x29\x2a\x6d\x6f\x72\x65\x5f\x62\x79\x74\x65\x73\x29\x29\x20\ +\x21\x3d\x20\x30\x29\0\x20\x20\x20\x20\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\ +\x69\x6e\x74\x6b\x28\x22\x46\x61\x69\x6c\x65\x64\x20\x74\x6f\x20\x65\x78\x70\ +\x61\x6e\x64\x20\x61\x20\x74\x63\x70\x20\x70\x61\x63\x6b\x65\x74\x20\x72\x65\ +\x73\x65\x72\x76\x65\x64\x20\x62\x79\x74\x65\x73\x20\x62\x79\x20\x25\x69\x5c\ +\x6e\x22\x2c\x20\x6d\x6f\x72\x65\x5f\x62\x79\x74\x65\x73\x29\x3b\0\x20\x20\x20\ +\x20\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x42\x50\ +\x46\x20\x66\x69\x6e\x69\x73\x68\x65\x64\x20\x77\x69\x74\x68\x20\x65\x72\x72\ +\x6f\x72\x20\x6f\x6e\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e\x5c\x6e\x22\x29\ +\x3b\0\x20\x20\x20\x20\x64\x61\x74\x61\x5f\x6c\x65\x6e\x5f\x6e\x65\x78\x74\x20\ +\x3d\x20\x64\x61\x74\x61\x5f\x65\x6e\x64\x2d\x64\x61\x74\x61\x3b\0\x20\x20\x20\ +\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x50\x72\x65\x76\x69\x6f\ +\x75\x73\x20\x6c\x65\x6e\x67\x74\x68\x3a\x20\x25\x69\x2c\x20\x63\x75\x72\x72\ +\x65\x6e\x74\x20\x6c\x65\x6e\x67\x74\x68\x3a\x20\x25\x69\x5c\x6e\x22\x2c\x20\ +\x64\x61\x74\x61\x5f\x6c\x65\x6e\x5f\x70\x72\x65\x76\x2c\x20\x64\x61\x74\x61\ +\x5f\x6c\x65\x6e\x5f\x6e\x65\x78\x74\x29\x3b\0\x20\x20\x20\x20\x72\x65\x74\x2e\ +\x72\x65\x74\x5f\x6d\x64\x20\x3d\x20\x2a\x63\x74\x78\x3b\0\x20\x20\x20\x20\x20\ +\x20\x20\x20\x69\x66\x28\x65\x74\x68\x65\x72\x6e\x65\x74\x5f\x68\x65\x61\x64\ +\x65\x72\x5f\x62\x6f\x75\x6e\x64\x5f\x63\x68\x65\x63\x6b\x28\x65\x74\x68\x2c\ +\x20\x64\x61\x74\x61\x5f\x65\x6e\x64\x29\x3c\x30\x29\x7b\0\x20\x20\x20\x20\x20\ +\x20\x20\x20\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\ +\x42\x6f\x75\x6e\x64\x20\x63\x68\x65\x63\x6b\x20\x41\x20\x66\x61\x69\x6c\x65\ +\x64\x20\x77\x68\x69\x6c\x65\x20\x65\x78\x70\x61\x6e\x64\x69\x6e\x67\x5c\x6e\ +\x22\x29\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x69\x70\x5f\x68\ \x65\x61\x64\x65\x72\x5f\x62\x6f\x75\x6e\x64\x5f\x63\x68\x65\x63\x6b\x28\x69\ \x70\x2c\x20\x64\x61\x74\x61\x5f\x65\x6e\x64\x29\x3c\x30\x29\x7b\0\x20\x20\x20\ -\x20\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x42\x22\ -\x29\x3b\0\x20\x20\x20\x20\x73\x77\x69\x74\x63\x68\x28\x69\x70\x2d\x3e\x70\x72\ -\x6f\x74\x6f\x63\x6f\x6c\x29\x7b\0\x20\x20\x20\x20\x69\x66\x20\x28\x67\x65\x74\ -\x5f\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x28\x64\x61\x74\x61\x29\x20\x21\x3d\x20\ -\x49\x50\x50\x52\x4f\x54\x4f\x5f\x54\x43\x50\x29\x7b\0\x20\x20\x20\x20\x20\x20\ -\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x43\x22\x29\x3b\0\x20\ -\x20\x20\x20\x69\x66\x20\x28\x28\x76\x6f\x69\x64\x20\x2a\x29\x74\x63\x70\x20\ -\x2b\x20\x73\x69\x7a\x65\x6f\x66\x28\x2a\x74\x63\x70\x29\x20\x3e\x20\x64\x61\ -\x74\x61\x5f\x65\x6e\x64\x29\x7b\0\x20\x20\x20\x20\x69\x66\x20\x28\x74\x63\x70\ -\x5f\x68\x65\x61\x64\x65\x72\x5f\x62\x6f\x75\x6e\x64\x5f\x63\x68\x65\x63\x6b\ -\x28\x74\x63\x70\x2c\x20\x64\x61\x74\x61\x5f\x65\x6e\x64\x29\x29\x7b\0\x20\x20\ -\x20\x20\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x44\ -\x22\x29\x3b\0\x7d\0\x2f\x68\x6f\x6d\x65\x2f\x6f\x73\x62\x6f\x78\x65\x73\x2f\ -\x54\x46\x47\x2f\x73\x72\x63\x2f\x69\x6e\x63\x6c\x75\x64\x65\x2f\x70\x61\x63\ -\x6b\x65\x74\x2f\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x2f\x74\x63\x70\x5f\x68\x65\ -\x6c\x70\x65\x72\x2e\x68\0\x20\x20\x20\x20\x72\x65\x74\x75\x72\x6e\x20\x6e\x74\ -\x6f\x68\x73\x28\x74\x63\x70\x2d\x3e\x64\x65\x73\x74\x29\x3b\0\x20\x20\x20\x20\ -\x69\x66\x20\x28\x67\x65\x74\x5f\x74\x63\x70\x5f\x64\x65\x73\x74\x5f\x70\x6f\ -\x72\x74\x28\x74\x63\x70\x29\x20\x21\x3d\x20\x53\x45\x43\x52\x45\x54\x5f\x50\ -\x41\x43\x4b\x45\x54\x5f\x44\x45\x53\x54\x5f\x50\x4f\x52\x54\x29\x7b\0\x20\x20\ -\x20\x20\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x45\ -\x20\x25\x69\x5c\x6e\x22\x2c\x20\x6e\x74\x6f\x68\x73\x28\x74\x63\x70\x2d\x3e\ -\x64\x65\x73\x74\x29\x29\x3b\0\x20\x20\x20\x20\x70\x61\x79\x6c\x6f\x61\x64\x5f\ -\x73\x69\x7a\x65\x20\x3d\x20\x6e\x74\x6f\x68\x73\x28\x69\x70\x2d\x3e\x74\x6f\ -\x74\x5f\x6c\x65\x6e\x29\x20\x2d\x20\x28\x74\x63\x70\x2d\x3e\x64\x6f\x66\x66\ -\x20\x2a\x20\x34\x29\x20\x2d\x20\x28\x69\x70\x2d\x3e\x69\x68\x6c\x20\x2a\x20\ -\x34\x29\x3b\0\x20\x20\x20\x20\x69\x66\x20\x28\x70\x61\x79\x6c\x6f\x61\x64\x5f\ -\x73\x69\x7a\x65\x20\x21\x3d\x20\x73\x69\x7a\x65\x6f\x66\x28\x6d\x61\x74\x63\ -\x68\x5f\x70\x61\x74\x74\x65\x72\x6e\x29\x20\x2d\x20\x31\x29\x20\x7b\0\x20\x20\ -\x20\x20\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x46\ -\x22\x29\x3b\0\x20\x20\x20\x20\x69\x66\x20\x28\x28\x76\x6f\x69\x64\x20\x2a\x29\ -\x70\x61\x79\x6c\x6f\x61\x64\x20\x2b\x20\x70\x61\x79\x6c\x6f\x61\x64\x5f\x73\ -\x69\x7a\x65\x20\x3e\x20\x64\x61\x74\x61\x5f\x65\x6e\x64\x29\x7b\0\x20\x20\x20\ -\x20\x69\x66\x20\x28\x74\x63\x70\x5f\x70\x61\x79\x6c\x6f\x61\x64\x5f\x62\x6f\ -\x75\x6e\x64\x5f\x63\x68\x65\x63\x6b\x28\x70\x61\x79\x6c\x6f\x61\x64\x2c\x20\ -\x70\x61\x79\x6c\x6f\x61\x64\x5f\x73\x69\x7a\x65\x2c\x20\x64\x61\x74\x61\x5f\ -\x65\x6e\x64\x29\x29\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x62\x70\x66\x5f\x70\ -\x72\x69\x6e\x74\x6b\x28\x22\x47\x22\x29\x3b\0\x20\x20\x20\x20\x62\x70\x66\x5f\ -\x70\x72\x69\x6e\x74\x6b\x28\x22\x52\x65\x63\x65\x69\x76\x65\x64\x20\x76\x61\ -\x6c\x69\x64\x20\x54\x43\x50\x20\x70\x61\x63\x6b\x65\x74\x20\x77\x69\x74\x68\ -\x20\x70\x61\x79\x6c\x6f\x61\x64\x20\x25\x73\x20\x6f\x66\x20\x73\x69\x7a\x65\ -\x20\x25\x69\x5c\x6e\x22\x2c\x20\x70\x61\x79\x6c\x6f\x61\x64\x2c\x20\x70\x61\ -\x79\x6c\x6f\x61\x64\x5f\x73\x69\x7a\x65\x29\x3b\0\x2f\x68\x6f\x6d\x65\x2f\x6f\ -\x73\x62\x6f\x78\x65\x73\x2f\x54\x46\x47\x2f\x73\x72\x63\x2f\x69\x6e\x63\x6c\ -\x75\x64\x65\x2f\x63\x6f\x6d\x6d\x6f\x6e\x2f\x63\x6f\x6d\x6d\x6f\x6e\x5f\x75\ -\x74\x69\x6c\x73\x2e\x68\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x73\ -\x74\x72\x31\x5b\x69\x69\x5d\x20\x21\x3d\x20\x73\x74\x72\x32\x5b\x69\x69\x5d\ -\x29\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\ -\x6b\x28\x22\x48\x22\x29\x3b\0\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\ -\x74\x6b\x28\x22\x42\x50\x46\x20\x66\x69\x6e\x69\x73\x68\x65\x64\x5c\x6e\x20\ -\x22\x29\x3b\0\x20\x20\x20\x20\x70\x61\x79\x6c\x6f\x61\x64\x5b\x31\x5d\x20\x3d\ -\x20\x27\x62\x27\x3b\0\x63\x68\x61\x72\0\x5f\x5f\x41\x52\x52\x41\x59\x5f\x53\ -\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\0\x4c\x49\x43\x45\x4e\x53\x45\0\x78\ -\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\0\x78\ -\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\ -\x31\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\ -\x74\x2e\x32\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\ -\x66\x6d\x74\x2e\x33\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\ -\x5f\x5f\x66\x6d\x74\x2e\x34\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\ -\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x35\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\ -\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x36\0\x78\x64\x70\x5f\x72\x65\x63\x65\ -\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x37\0\x78\x64\x70\x5f\x72\x65\ -\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x38\0\x78\x64\x70\x5f\ -\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x39\0\x2e\x72\ -\x6f\x64\x61\x74\x61\0\x6c\x69\x63\x65\x6e\x73\x65\0\x9f\xeb\x01\0\x20\0\0\0\0\ -\0\0\0\x14\0\0\0\x14\0\0\0\xcc\x02\0\0\xe0\x02\0\0\0\0\0\0\x08\0\0\0\x75\0\0\0\ -\x01\0\0\0\0\0\0\0\x07\0\0\0\x10\0\0\0\x75\0\0\0\x2c\0\0\0\0\0\0\0\x7e\0\0\0\ -\xaa\0\0\0\x29\xf4\0\0\x08\0\0\0\x7e\0\0\0\xdc\0\0\0\x25\xf8\0\0\x10\0\0\0\x06\ -\x01\0\0\x3c\x01\0\0\x15\x28\0\0\x20\0\0\0\x7e\0\0\0\x75\x01\0\0\x08\x24\x01\0\ -\x28\0\0\0\x7e\0\0\0\xab\x01\0\0\x09\x28\x01\0\x48\0\0\0\x06\x01\0\0\xd5\x01\0\ -\0\x14\x44\0\0\x58\0\0\0\x7e\0\0\0\x03\x02\0\0\x09\x3c\x01\0\x60\0\0\0\x7e\0\0\ -\0\x33\x02\0\0\x09\x40\x01\0\x78\0\0\0\x06\x01\0\0\x4c\x02\0\0\x10\xb0\0\0\x80\ -\0\0\0\x7e\0\0\0\x66\x02\0\0\x09\x50\x01\0\x88\0\0\0\x7e\0\0\0\x92\x02\0\0\x09\ -\x54\x01\0\xa0\0\0\0\x06\x01\0\0\xab\x02\0\0\x15\x60\0\0\xb0\0\0\0\x7e\0\0\0\ -\xdb\x02\0\0\x09\x68\x01\0\xb8\0\0\0\x7e\0\0\0\x0b\x03\0\0\x09\x6c\x01\0\xc8\0\ -\0\0\x7e\0\0\0\0\0\0\0\0\0\0\0\xd8\0\0\0\x7e\0\0\0\x24\x03\0\0\x01\x20\x02\0\ -\xe8\0\0\0\x26\x03\0\0\x61\x03\0\0\x0c\x34\0\0\xf0\0\0\0\x7e\0\0\0\x7e\x03\0\0\ -\x09\x7c\x01\0\0\x01\0\0\x7e\0\0\0\xba\x03\0\0\x09\x80\x01\0\x28\x01\0\0\x7e\0\ -\0\0\xea\x03\0\0\x2f\x90\x01\0\x30\x01\0\0\x7e\0\0\0\xea\x03\0\0\x34\x90\x01\0\ -\x40\x01\0\0\x7e\0\0\0\xea\x03\0\0\x14\x90\x01\0\x50\x01\0\0\x7e\0\0\0\xea\x03\ -\0\0\x27\x90\x01\0\x58\x01\0\0\x7e\0\0\0\xea\x03\0\0\x40\x90\x01\0\x60\x01\0\0\ -\x7e\0\0\0\xea\x03\0\0\x44\x90\x01\0\x70\x01\0\0\x7e\0\0\0\xea\x03\0\0\x39\x90\ -\x01\0\x78\x01\0\0\x7e\0\0\0\x33\x04\0\0\x09\xa0\x01\0\x80\x01\0\0\x7e\0\0\0\ -\x68\x04\0\0\x09\xa4\x01\0\x98\x01\0\0\x7e\0\0\0\0\0\0\0\0\0\0\0\xa0\x01\0\0\ -\x06\x01\0\0\x81\x04\0\0\x19\x7c\0\0\xb0\x01\0\0\x7e\0\0\0\xb5\x04\0\0\x09\xb8\ -\x01\0\xb8\x01\0\0\x7e\0\0\0\xf8\x04\0\0\x09\xbc\x01\0\xd0\x01\0\0\x7e\0\0\0\ -\x11\x05\0\0\x05\xcc\x01\0\0\x02\0\0\x72\x05\0\0\xa6\x05\0\0\x0d\x6c\0\0\x08\ -\x02\0\0\x72\x05\0\0\xa6\x05\0\0\x0d\x6c\0\0\x10\x02\0\0\x7e\0\0\0\xc9\x05\0\0\ -\x09\xdc\x01\0\x28\x02\0\0\x72\x05\0\0\xa6\x05\0\0\x0d\x6c\0\0\x30\x02\0\0\x72\ -\x05\0\0\xa6\x05\0\0\x0d\x6c\0\0\x38\x02\0\0\x72\x05\0\0\xa6\x05\0\0\x0d\x6c\0\ -\0\x40\x02\0\0\x72\x05\0\0\xa6\x05\0\0\x0d\x6c\0\0\x48\x02\0\0\x72\x05\0\0\xa6\ -\x05\0\0\x0d\x6c\0\0\x50\x02\0\0\x72\x05\0\0\xa6\x05\0\0\x0d\x6c\0\0\x58\x02\0\ -\0\x7e\0\0\0\xe2\x05\0\0\x05\xec\x01\0\x80\x02\0\0\x7e\0\0\0\x05\x06\0\0\x10\ -\xf0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9a\ -\x01\0\0\0\0\x02\0\x28\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x66\x01\0\0\0\0\x02\0\ -\x98\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2b\x01\0\0\0\0\x02\0\xd0\x01\0\0\0\0\0\0\ -\0\0\0\0\0\0\0\0\x06\x01\0\0\0\0\x02\0\x10\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe8\ -\0\0\0\0\0\x02\0\xc8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc3\0\0\0\0\0\x02\0\xd0\0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\xa5\0\0\0\0\0\x02\0\xd8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ -\0\x80\0\0\0\0\0\x02\0\x28\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5f\x01\0\0\0\0\x02\ -\0\x48\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x24\x01\0\0\0\0\x02\0\x78\0\0\0\0\0\0\0\0\ -\0\0\0\0\0\0\0\xe1\0\0\0\0\0\x02\0\xa0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9e\0\0\0\ -\0\0\x02\0\xe8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x14\0\0\0\x01\0\x04\0\0\0\0\0\0\0\ -\0\0\x13\0\0\0\0\0\0\0\x84\x01\0\0\x01\0\x04\0\x13\0\0\0\0\0\0\0\x02\0\0\0\0\0\ -\0\0\x6e\x01\0\0\x01\0\x04\0\x15\0\0\0\0\0\0\0\x02\0\0\0\0\0\0\0\x49\x01\0\0\ -\x01\0\x04\0\x17\0\0\0\0\0\0\0\x02\0\0\0\0\0\0\0\x33\x01\0\0\x01\0\x04\0\x19\0\ -\0\0\0\0\0\0\x06\0\0\0\0\0\0\0\x0e\x01\0\0\x01\0\x04\0\x1f\0\0\0\0\0\0\0\x02\0\ -\0\0\0\0\0\0\xf0\0\0\0\x01\0\x04\0\x21\0\0\0\0\0\0\0\x02\0\0\0\0\0\0\0\xcb\0\0\ -\0\x01\0\x04\0\x23\0\0\0\0\0\0\0\x36\0\0\0\0\0\0\0\xad\0\0\0\x01\0\x04\0\x59\0\ -\0\0\0\0\0\0\x02\0\0\0\0\0\0\0\x88\0\0\0\x01\0\x04\0\x5b\0\0\0\0\0\0\0\x0f\0\0\ -\0\0\0\0\0\0\0\0\0\x03\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\ -\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x78\0\0\0\x11\0\x03\0\0\0\0\0\0\0\0\0\ -\x0d\0\0\0\0\0\0\0\x43\0\0\0\x12\0\x02\0\0\0\0\0\0\0\0\0\x90\x02\0\0\0\0\0\0\ -\x28\0\0\0\0\0\0\0\x01\0\0\0\x18\0\0\0\x60\0\0\0\0\0\0\0\x01\0\0\0\x18\0\0\0\ -\x88\0\0\0\0\0\0\0\x01\0\0\0\x18\0\0\0\xb8\0\0\0\0\0\0\0\x01\0\0\0\x18\0\0\0\0\ -\x01\0\0\0\0\0\0\x01\0\0\0\x18\0\0\0\x80\x01\0\0\0\0\0\0\x01\0\0\0\x18\0\0\0\ -\xb8\x01\0\0\0\0\0\0\x01\0\0\0\x18\0\0\0\xd0\x01\0\0\0\0\0\0\x01\0\0\0\x18\0\0\ -\0\x10\x02\0\0\0\0\0\0\x01\0\0\0\x18\0\0\0\x58\x02\0\0\0\0\0\0\x01\0\0\0\x18\0\ -\0\0\x40\x02\0\0\0\0\0\0\x0a\0\0\0\x18\0\0\0\x4c\x02\0\0\0\0\0\0\x0a\0\0\0\x18\ -\0\0\0\x58\x02\0\0\0\0\0\0\x0a\0\0\0\x18\0\0\0\x64\x02\0\0\0\0\0\0\x0a\0\0\0\ -\x18\0\0\0\x70\x02\0\0\0\0\0\0\x0a\0\0\0\x18\0\0\0\x7c\x02\0\0\0\0\0\0\x0a\0\0\ -\0\x18\0\0\0\x88\x02\0\0\0\0\0\0\x0a\0\0\0\x18\0\0\0\x94\x02\0\0\0\0\0\0\x0a\0\ -\0\0\x18\0\0\0\xa0\x02\0\0\0\0\0\0\x0a\0\0\0\x18\0\0\0\xac\x02\0\0\0\0\0\0\x0a\ -\0\0\0\x18\0\0\0\xc4\x02\0\0\0\0\0\0\0\0\0\0\x19\0\0\0\x2c\0\0\0\0\0\0\0\0\0\0\ -\0\x17\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\x50\0\0\0\0\0\0\0\0\0\0\0\x17\ -\0\0\0\x60\0\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\x70\0\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\ -\x80\0\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\x90\0\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\xa0\0\ -\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\xb0\0\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\xc0\0\0\0\0\ -\0\0\0\0\0\0\0\x17\0\0\0\xd0\0\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\xe0\0\0\0\0\0\0\0\ -\0\0\0\0\x17\0\0\0\xf0\0\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\ -\0\x17\0\0\0\x10\x01\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\x20\x01\0\0\0\0\0\0\0\0\0\0\ -\x17\0\0\0\x30\x01\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\x40\x01\0\0\0\0\0\0\0\0\0\0\ -\x17\0\0\0\x50\x01\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\x60\x01\0\0\0\0\0\0\0\0\0\0\ -\x17\0\0\0\x70\x01\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\x80\x01\0\0\0\0\0\0\0\0\0\0\ -\x17\0\0\0\x90\x01\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\xa0\x01\0\0\0\0\0\0\0\0\0\0\ -\x17\0\0\0\xb0\x01\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\xc0\x01\0\0\0\0\0\0\0\0\0\0\ -\x17\0\0\0\xd0\x01\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\xe0\x01\0\0\0\0\0\0\0\0\0\0\ -\x17\0\0\0\xf0\x01\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\x17\ -\0\0\0\x10\x02\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\x20\x02\0\0\0\0\0\0\0\0\0\0\x17\0\ -\0\0\x30\x02\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\x40\x02\0\0\0\0\0\0\0\0\0\0\x17\0\0\ -\0\x50\x02\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\x60\x02\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\ -\x70\x02\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\x80\x02\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\ -\x90\x02\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\xa0\x02\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\ -\xb0\x02\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\xc0\x02\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\ -\xd0\x02\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\xe0\x02\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\ -\xf0\x02\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\x21\x20\x0e\x0f\x10\x11\x12\x13\x14\x15\ -\x16\x17\0\x2e\x74\x65\x78\x74\0\x2e\x72\x65\x6c\x2e\x42\x54\x46\x2e\x65\x78\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\ +\x28\x22\x42\x6f\x75\x6e\x64\x20\x63\x68\x65\x63\x6b\x20\x42\x20\x66\x61\x69\ +\x6c\x65\x64\x20\x77\x68\x69\x6c\x65\x20\x65\x78\x70\x61\x6e\x64\x69\x6e\x67\ +\x5c\x6e\x22\x29\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x74\x63\ +\x70\x5f\x68\x65\x61\x64\x65\x72\x5f\x62\x6f\x75\x6e\x64\x5f\x63\x68\x65\x63\ +\x6b\x28\x74\x63\x70\x2c\x20\x64\x61\x74\x61\x5f\x65\x6e\x64\x29\x29\x7b\0\x20\ +\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\ +\x74\x6b\x28\x22\x42\x6f\x75\x6e\x64\x20\x63\x68\x65\x63\x6b\x20\x44\x20\x66\ +\x61\x69\x6c\x65\x64\x20\x77\x68\x69\x6c\x65\x20\x65\x78\x70\x61\x6e\x64\x69\ +\x6e\x67\x5c\x6e\x22\x29\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x70\x61\x79\x6c\ +\x6f\x61\x64\x5f\x73\x69\x7a\x65\x20\x3d\x20\x6e\x74\x6f\x68\x73\x28\x69\x70\ +\x2d\x3e\x74\x6f\x74\x5f\x6c\x65\x6e\x29\x20\x2d\x20\x28\x74\x63\x70\x2d\x3e\ +\x64\x6f\x66\x66\x20\x2a\x20\x34\x29\x20\x2d\x20\x28\x69\x70\x2d\x3e\x69\x68\ +\x6c\x20\x2a\x20\x34\x29\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x70\x61\x79\x6c\ +\x6f\x61\x64\x20\x3d\x20\x28\x76\x6f\x69\x64\x20\x2a\x29\x74\x63\x70\x20\x2b\ +\x20\x74\x63\x70\x2d\x3e\x64\x6f\x66\x66\x2a\x34\x3b\0\x20\x20\x20\x20\x20\x20\ +\x20\x20\x62\x70\x66\x5f\x70\x72\x69\x6e\x74\x6b\x28\x22\x42\x50\x46\x20\x66\ +\x69\x6e\x69\x73\x68\x65\x64\x20\x77\x69\x74\x68\x20\x72\x65\x74\x20\x25\x69\ +\x20\x61\x6e\x64\x20\x70\x61\x79\x6c\x6f\x61\x64\x20\x25\x73\x20\x6f\x66\x20\ +\x73\x69\x7a\x65\x20\x25\x69\x5c\x6e\x20\x22\x2c\x20\x72\x65\x74\x2e\x63\x6f\ +\x64\x65\x2c\x20\x70\x61\x79\x6c\x6f\x61\x64\x2c\x20\x70\x61\x79\x6c\x6f\x61\ +\x64\x5f\x73\x69\x7a\x65\x29\x3b\0\x63\x68\x61\x72\0\x5f\x5f\x41\x52\x52\x41\ +\x59\x5f\x53\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\0\x4c\x49\x43\x45\x4e\x53\ +\x45\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\ \x74\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\ -\x74\0\x2e\x72\x65\x6c\x78\x64\x70\x5f\x70\x72\x6f\x67\0\x2e\x6c\x6c\x76\x6d\ -\x5f\x61\x64\x64\x72\x73\x69\x67\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\ -\0\x6c\x69\x63\x65\x6e\x73\x65\0\x2e\x73\x74\x72\x74\x61\x62\0\x2e\x73\x79\x6d\ -\x74\x61\x62\0\x2e\x72\x6f\x64\x61\x74\x61\0\x2e\x72\x65\x6c\x2e\x42\x54\x46\0\ -\x4c\x49\x43\x45\x4e\x53\x45\0\x4c\x42\x42\x30\x5f\x31\x39\0\x78\x64\x70\x5f\ -\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x39\0\x4c\x42\ -\x42\x30\x5f\x38\0\x4c\x42\x42\x30\x5f\x31\x38\0\x78\x64\x70\x5f\x72\x65\x63\ -\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x38\0\x4c\x42\x42\x30\x5f\ -\x31\x37\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\ -\x6d\x74\x2e\x37\0\x4c\x42\x42\x30\x5f\x36\0\x4c\x42\x42\x30\x5f\x31\x36\0\x78\ +\x74\x2e\x31\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\ +\x66\x6d\x74\x2e\x32\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\ +\x5f\x5f\x66\x6d\x74\x2e\x33\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\ +\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x34\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\ +\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x35\0\x78\x64\x70\x5f\x72\x65\x63\x65\ +\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x36\0\x78\x64\x70\x5f\x72\x65\ +\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x37\0\x78\x64\x70\x5f\ +\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x38\0\x78\x64\ +\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x39\0\ +\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\ +\x2e\x31\x30\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\ +\x66\x6d\x74\x2e\x31\x31\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\ +\x5f\x5f\x5f\x66\x6d\x74\x2e\x31\x32\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\ +\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x31\x33\0\x78\x64\x70\x5f\x72\x65\x63\ +\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x31\x34\0\x65\x78\x70\x61\ +\x6e\x64\x5f\x74\x63\x70\x5f\x70\x61\x63\x6b\x65\x74\x5f\x70\x61\x79\x6c\x6f\ +\x61\x64\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\0\x2e\x72\x6f\x64\x61\x74\x61\0\x6c\ +\x69\x63\x65\x6e\x73\x65\0\x9f\xeb\x01\0\x20\0\0\0\0\0\0\0\x14\0\0\0\x14\0\0\0\ +\x6c\x04\0\0\x80\x04\0\0\0\0\0\0\x08\0\0\0\x75\0\0\0\x01\0\0\0\0\0\0\0\x07\0\0\ +\0\x10\0\0\0\x75\0\0\0\x46\0\0\0\0\0\0\0\x7e\0\0\0\xaa\0\0\0\0\xe8\0\0\x08\0\0\ +\0\x7e\0\0\0\xce\0\0\0\x29\xf8\0\0\x10\0\0\0\x7e\0\0\0\0\x01\0\0\x25\xfc\0\0\ +\x18\0\0\0\x2a\x01\0\0\x60\x01\0\0\x15\x28\0\0\x28\0\0\0\x7e\0\0\0\x99\x01\0\0\ +\x08\x28\x01\0\x30\0\0\0\x7e\0\0\0\xcf\x01\0\0\x09\x2c\x01\0\x50\0\0\0\x2a\x01\ +\0\0\xf9\x01\0\0\x14\x44\0\0\x60\0\0\0\x7e\0\0\0\x27\x02\0\0\x09\x40\x01\0\x68\ +\0\0\0\x7e\0\0\0\x57\x02\0\0\x09\x44\x01\0\x80\0\0\0\x2a\x01\0\0\x70\x02\0\0\ +\x10\xb0\0\0\x88\0\0\0\x7e\0\0\0\x8a\x02\0\0\x09\x54\x01\0\x90\0\0\0\x7e\0\0\0\ +\xb6\x02\0\0\x09\x58\x01\0\xa8\0\0\0\x2a\x01\0\0\xcf\x02\0\0\x15\x60\0\0\xb8\0\ +\0\0\x7e\0\0\0\xff\x02\0\0\x09\x6c\x01\0\xc0\0\0\0\x7e\0\0\0\x2f\x03\0\0\x09\ +\x70\x01\0\xd0\0\0\0\x7e\0\0\0\0\0\0\0\0\0\0\0\xe0\0\0\0\x7e\0\0\0\x48\x03\0\0\ +\x01\xd0\x02\0\xf0\0\0\0\x4a\x03\0\0\x85\x03\0\0\x0c\x34\0\0\xf8\0\0\0\x7e\0\0\ +\0\xa2\x03\0\0\x09\x80\x01\0\x08\x01\0\0\x7e\0\0\0\xde\x03\0\0\x09\x84\x01\0\ +\x30\x01\0\0\x7e\0\0\0\x0e\x04\0\0\x2f\x94\x01\0\x38\x01\0\0\x7e\0\0\0\x0e\x04\ +\0\0\x34\x94\x01\0\x48\x01\0\0\x7e\0\0\0\x0e\x04\0\0\x14\x94\x01\0\x58\x01\0\0\ +\x7e\0\0\0\x0e\x04\0\0\x27\x94\x01\0\x60\x01\0\0\x7e\0\0\0\x0e\x04\0\0\x40\x94\ +\x01\0\x68\x01\0\0\x7e\0\0\0\x0e\x04\0\0\x44\x94\x01\0\x78\x01\0\0\x7e\0\0\0\ +\x0e\x04\0\0\x39\x94\x01\0\x80\x01\0\0\x7e\0\0\0\x57\x04\0\0\x09\xa4\x01\0\x88\ +\x01\0\0\x7e\0\0\0\x8c\x04\0\0\x09\xa8\x01\0\xa0\x01\0\0\x7e\0\0\0\0\0\0\0\0\0\ +\0\0\xa8\x01\0\0\x2a\x01\0\0\xa5\x04\0\0\x19\x7c\0\0\xb8\x01\0\0\x7e\0\0\0\xd9\ +\x04\0\0\x09\xbc\x01\0\xc0\x01\0\0\x7e\0\0\0\x1c\x05\0\0\x09\xc0\x01\0\xd8\x01\ +\0\0\x7e\0\0\0\x35\x05\0\0\x05\xd0\x01\0\x08\x02\0\0\x96\x05\0\0\xca\x05\0\0\ +\x0d\x6c\0\0\x10\x02\0\0\x96\x05\0\0\xca\x05\0\0\x0d\x6c\0\0\x18\x02\0\0\x7e\0\ +\0\0\xed\x05\0\0\x09\xdc\x01\0\x30\x02\0\0\x96\x05\0\0\xca\x05\0\0\x0d\x6c\0\0\ +\x38\x02\0\0\x96\x05\0\0\xca\x05\0\0\x0d\x6c\0\0\x40\x02\0\0\x96\x05\0\0\xca\ +\x05\0\0\x0d\x6c\0\0\x48\x02\0\0\x96\x05\0\0\xca\x05\0\0\x0d\x6c\0\0\x50\x02\0\ +\0\x96\x05\0\0\xca\x05\0\0\x0d\x6c\0\0\x58\x02\0\0\x96\x05\0\0\xca\x05\0\0\x0d\ +\x6c\0\0\x60\x02\0\0\x06\x06\0\0\x35\x06\0\0\x09\xac\0\0\x78\x02\0\0\x06\x06\0\ +\0\x35\x06\0\0\x09\xac\0\0\x80\x02\0\0\x06\x06\0\0\x7c\x06\0\0\x09\xb8\0\0\xa8\ +\x02\0\0\x7e\0\0\0\xd4\x06\0\0\x09\x88\x02\0\xc8\x02\0\0\x7e\0\0\0\0\0\0\0\0\0\ +\0\0\xe0\x02\0\0\x7e\0\0\0\x12\x07\0\0\x1d\x90\x02\0\xe8\x02\0\0\x7e\0\0\0\x35\ +\x07\0\0\x05\x94\x02\0\x20\x03\0\0\x06\x06\0\0\x90\x07\0\0\x12\xec\0\0\x30\x03\ +\0\0\x2a\x01\0\0\x60\x01\0\0\x15\x28\0\0\x40\x03\0\0\x7e\0\0\0\xa7\x07\0\0\x0c\ +\x0c\x02\0\x48\x03\0\0\x7e\0\0\0\xe1\x07\0\0\x0d\x10\x02\0\x60\x03\0\0\x2a\x01\ +\0\0\xf9\x01\0\0\x14\x44\0\0\x70\x03\0\0\x7e\0\0\0\x23\x08\0\0\x0d\x24\x02\0\ +\x78\x03\0\0\x7e\0\0\0\x57\x08\0\0\x0d\x28\x02\0\x90\x03\0\0\x2a\x01\0\0\xcf\ +\x02\0\0\x15\x60\0\0\xa0\x03\0\0\x7e\0\0\0\x99\x08\0\0\x0d\x50\x02\0\xa8\x03\0\ +\0\x7e\0\0\0\xcd\x08\0\0\x0d\x54\x02\0\xb8\x03\0\0\x7e\0\0\0\0\0\0\0\0\0\0\0\ +\xc8\x03\0\0\x7e\0\0\0\x0f\x09\0\0\x18\x64\x02\0\xd8\x03\0\0\x7e\0\0\0\x0f\x09\ +\0\0\x33\x64\x02\0\xe0\x03\0\0\x7e\0\0\0\x0f\x09\0\0\x38\x64\x02\0\xf0\x03\0\0\ +\x7e\0\0\0\x5c\x09\0\0\x1f\x68\x02\0\xf8\x03\0\0\x7e\0\0\0\x0f\x09\0\0\x2b\x64\ +\x02\0\0\x04\0\0\x7e\0\0\0\x0f\x09\0\0\x44\x64\x02\0\x08\x04\0\0\x7e\0\0\0\x0f\ +\x09\0\0\x48\x64\x02\0\x18\x04\0\0\x7e\0\0\0\x0f\x09\0\0\x3d\x64\x02\0\x20\x04\ +\0\0\x7e\0\0\0\x89\x09\0\0\x09\x80\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +\0\0\0\0\0\0\0\0\x47\x02\0\0\0\0\x02\0\xe0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x12\ +\x02\0\0\0\0\x02\0\xf0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x99\x01\0\0\0\0\x02\0\x30\ +\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3f\x01\0\0\0\0\x02\0\xa0\x01\0\0\0\0\0\0\0\0\ +\0\0\0\0\0\0\xfc\0\0\0\0\0\x02\0\xd8\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd6\0\0\0\ +\0\0\x02\0\x18\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb1\0\0\0\0\0\x02\0\x30\x02\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\0\xce\x01\0\0\0\0\x02\0\x50\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +\0\x64\x01\0\0\0\0\x02\0\xd8\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x37\x01\0\0\0\0\ +\x02\0\x20\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf4\0\0\0\0\0\x02\0\x60\x03\0\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\xa9\0\0\0\0\0\x02\0\x90\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +\x0a\x02\0\0\0\0\x02\0\xb8\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd5\x01\0\0\0\0\x02\ +\0\xc8\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5d\x01\0\0\0\0\x02\0\x80\0\0\0\0\0\0\0\ +\0\0\0\0\0\0\0\0\x1a\x01\0\0\0\0\x02\0\xa8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xcf\0\ +\0\0\0\0\x02\0\xd0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa2\0\0\0\0\0\x02\0\xd8\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\0\x28\0\0\0\x01\0\x04\0\x51\x01\0\0\0\0\0\0\x34\0\0\0\0\ +\0\0\0\x14\0\0\0\x01\0\x04\0\0\0\0\0\0\0\0\0\x13\0\0\0\0\0\0\0\x31\x02\0\0\x01\ +\0\x04\0\x13\0\0\0\0\0\0\0\x02\0\0\0\0\0\0\0\x4f\x02\0\0\x01\0\x04\0\x81\0\0\0\ +\0\0\0\0\x26\0\0\0\0\0\0\0\x1a\x02\0\0\x01\0\x04\0\xa7\0\0\0\0\0\0\0\x26\0\0\0\ +\0\0\0\0\xdd\x01\0\0\x01\0\x04\0\xcd\0\0\0\0\0\0\0\x35\0\0\0\0\0\0\0\xa1\x01\0\ +\0\x01\0\x04\0\x02\x01\0\0\0\0\0\0\x26\0\0\0\0\0\0\0\x6c\x01\0\0\x01\0\x04\0\ +\x28\x01\0\0\0\0\0\0\x29\0\0\0\0\0\0\0\xf4\x01\0\0\x01\0\x04\0\x15\0\0\0\0\0\0\ +\0\x02\0\0\0\0\0\0\0\xb8\x01\0\0\x01\0\x04\0\x17\0\0\0\0\0\0\0\x02\0\0\0\0\0\0\ +\0\x83\x01\0\0\x01\0\x04\0\x19\0\0\0\0\0\0\0\x06\0\0\0\0\0\0\0\x47\x01\0\0\x01\ +\0\x04\0\x1f\0\0\0\0\0\0\0\x02\0\0\0\0\0\0\0\x21\x01\0\0\x01\0\x04\0\x21\0\0\0\ +\0\0\0\0\x02\0\0\0\0\0\0\0\x04\x01\0\0\x01\0\x04\0\x23\0\0\0\0\0\0\0\x36\0\0\0\ +\0\0\0\0\xde\0\0\0\x01\0\x04\0\x59\0\0\0\0\0\0\0\x02\0\0\0\0\0\0\0\xb9\0\0\0\ +\x01\0\x04\0\x5b\0\0\0\0\0\0\0\x26\0\0\0\0\0\0\0\0\0\0\0\x03\0\x02\0\0\0\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9a\ +\0\0\0\x11\0\x03\0\0\0\0\0\0\0\0\0\x0d\0\0\0\0\0\0\0\x65\0\0\0\x12\0\x02\0\0\0\ +\0\0\0\0\0\0\x50\x04\0\0\0\0\0\0\x30\0\0\0\0\0\0\0\x01\0\0\0\x24\0\0\0\x68\0\0\ +\0\0\0\0\0\x01\0\0\0\x24\0\0\0\x90\0\0\0\0\0\0\0\x01\0\0\0\x24\0\0\0\xc0\0\0\0\ +\0\0\0\0\x01\0\0\0\x24\0\0\0\x08\x01\0\0\0\0\0\0\x01\0\0\0\x24\0\0\0\x88\x01\0\ +\0\0\0\0\0\x01\0\0\0\x24\0\0\0\xc0\x01\0\0\0\0\0\0\x01\0\0\0\x24\0\0\0\xd8\x01\ +\0\0\0\0\0\0\x01\0\0\0\x24\0\0\0\x18\x02\0\0\0\0\0\0\x01\0\0\0\x24\0\0\0\x80\ +\x02\0\0\0\0\0\0\x01\0\0\0\x24\0\0\0\xa8\x02\0\0\0\0\0\0\x01\0\0\0\x24\0\0\0\ +\xe8\x02\0\0\0\0\0\0\x01\0\0\0\x24\0\0\0\x48\x03\0\0\0\0\0\0\x01\0\0\0\x24\0\0\ +\0\x78\x03\0\0\0\0\0\0\x01\0\0\0\x24\0\0\0\xa8\x03\0\0\0\0\0\0\x01\0\0\0\x24\0\ +\0\0\x20\x04\0\0\0\0\0\0\x01\0\0\0\x24\0\0\0\xe8\x02\0\0\0\0\0\0\x0a\0\0\0\x24\ +\0\0\0\xf4\x02\0\0\0\0\0\0\x0a\0\0\0\x24\0\0\0\0\x03\0\0\0\0\0\0\x0a\0\0\0\x24\ +\0\0\0\x0c\x03\0\0\0\0\0\0\x0a\0\0\0\x24\0\0\0\x18\x03\0\0\0\0\0\0\x0a\0\0\0\ +\x24\0\0\0\x24\x03\0\0\0\0\0\0\x0a\0\0\0\x24\0\0\0\x30\x03\0\0\0\0\0\0\x0a\0\0\ +\0\x24\0\0\0\x3c\x03\0\0\0\0\0\0\x0a\0\0\0\x24\0\0\0\x48\x03\0\0\0\0\0\0\x0a\0\ +\0\0\x24\0\0\0\x54\x03\0\0\0\0\0\0\x0a\0\0\0\x24\0\0\0\x60\x03\0\0\0\0\0\0\x0a\ +\0\0\0\x24\0\0\0\x6c\x03\0\0\0\0\0\0\x0a\0\0\0\x24\0\0\0\x78\x03\0\0\0\0\0\0\ +\x0a\0\0\0\x24\0\0\0\x84\x03\0\0\0\0\0\0\x0a\0\0\0\x24\0\0\0\x90\x03\0\0\0\0\0\ +\0\x0a\0\0\0\x24\0\0\0\x9c\x03\0\0\0\0\0\0\x0a\0\0\0\x24\0\0\0\xb4\x03\0\0\0\0\ +\0\0\0\0\0\0\x25\0\0\0\x2c\0\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x40\0\0\0\0\0\0\0\0\ +\0\0\0\x23\0\0\0\x50\0\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x60\0\0\0\0\0\0\0\0\0\0\0\ +\x23\0\0\0\x70\0\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x80\0\0\0\0\0\0\0\0\0\0\0\x23\0\ +\0\0\x90\0\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xa0\0\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\ +\xb0\0\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xc0\0\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xd0\0\ +\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xe0\0\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xf0\0\0\0\0\ +\0\0\0\0\0\0\0\x23\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x10\x01\0\0\0\0\0\ +\0\0\0\0\0\x23\0\0\0\x20\x01\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x30\x01\0\0\0\0\0\0\ +\0\0\0\0\x23\0\0\0\x40\x01\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x50\x01\0\0\0\0\0\0\0\ +\0\0\0\x23\0\0\0\x60\x01\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x70\x01\0\0\0\0\0\0\0\0\ +\0\0\x23\0\0\0\x80\x01\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x90\x01\0\0\0\0\0\0\0\0\0\ +\0\x23\0\0\0\xa0\x01\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xb0\x01\0\0\0\0\0\0\0\0\0\0\ +\x23\0\0\0\xc0\x01\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xd0\x01\0\0\0\0\0\0\0\0\0\0\ +\x23\0\0\0\xe0\x01\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xf0\x01\0\0\0\0\0\0\0\0\0\0\ +\x23\0\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x10\x02\0\0\0\0\0\0\0\0\0\0\x23\ +\0\0\0\x20\x02\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x30\x02\0\0\0\0\0\0\0\0\0\0\x23\0\ +\0\0\x40\x02\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x50\x02\0\0\0\0\0\0\0\0\0\0\x23\0\0\ +\0\x60\x02\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x70\x02\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\ +\x80\x02\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x90\x02\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\ +\xa0\x02\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xb0\x02\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\ +\xc0\x02\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xd0\x02\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\ +\xe0\x02\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xf0\x02\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\0\ +\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x10\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x20\ +\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x30\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x40\ +\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x50\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x60\ +\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x70\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x80\ +\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x90\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xa0\ +\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xb0\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xc0\ +\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xd0\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xe0\ +\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\xf0\x03\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\0\x04\ +\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x10\x04\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x20\x04\0\ +\0\0\0\0\0\0\0\0\0\x23\0\0\0\x30\x04\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x40\x04\0\0\ +\0\0\0\0\0\0\0\0\x23\0\0\0\x50\x04\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x60\x04\0\0\0\ +\0\0\0\0\0\0\0\x23\0\0\0\x70\x04\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x80\x04\0\0\0\0\ +\0\0\0\0\0\0\x23\0\0\0\x90\x04\0\0\0\0\0\0\0\0\0\0\x23\0\0\0\x2d\x2c\x15\x16\ +\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x17\x18\x19\x1a\x1b\x14\0\x2e\x74\x65\x78\x74\ +\0\x2e\x72\x65\x6c\x2e\x42\x54\x46\x2e\x65\x78\x74\0\x78\x64\x70\x5f\x72\x65\ +\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\0\x65\x78\x70\x61\x6e\x64\ +\x5f\x74\x63\x70\x5f\x70\x61\x63\x6b\x65\x74\x5f\x70\x61\x79\x6c\x6f\x61\x64\ +\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\0\x2e\x72\x65\x6c\x78\x64\x70\x5f\x70\x72\x6f\ +\x67\0\x2e\x6c\x6c\x76\x6d\x5f\x61\x64\x64\x72\x73\x69\x67\0\x78\x64\x70\x5f\ +\x72\x65\x63\x65\x69\x76\x65\0\x6c\x69\x63\x65\x6e\x73\x65\0\x2e\x73\x74\x72\ +\x74\x61\x62\0\x2e\x73\x79\x6d\x74\x61\x62\0\x2e\x72\x6f\x64\x61\x74\x61\0\x2e\ +\x72\x65\x6c\x2e\x42\x54\x46\0\x4c\x49\x43\x45\x4e\x53\x45\0\x4c\x42\x42\x30\ +\x5f\x39\0\x4c\x42\x42\x30\x5f\x32\x39\0\x4c\x42\x42\x30\x5f\x31\x39\0\x78\x64\ +\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x39\0\ +\x4c\x42\x42\x30\x5f\x38\0\x4c\x42\x42\x30\x5f\x31\x38\0\x78\x64\x70\x5f\x72\ +\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x38\0\x4c\x42\x42\ +\x30\x5f\x32\x37\0\x4c\x42\x42\x30\x5f\x31\x37\0\x78\x64\x70\x5f\x72\x65\x63\ +\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x37\0\x4c\x42\x42\x30\x5f\ +\x36\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\ +\x74\x2e\x36\0\x4c\x42\x42\x30\x5f\x32\x35\0\x4c\x42\x42\x30\x5f\x31\x35\0\x78\ \x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\ -\x36\0\x4c\x42\x42\x30\x5f\x31\x35\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\ -\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x35\0\x4c\x42\x42\x30\x5f\x34\0\x4c\ -\x42\x42\x30\x5f\x31\x34\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\ -\x5f\x5f\x5f\x66\x6d\x74\x2e\x34\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\ -\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x33\0\x4c\x42\x42\x30\x5f\x32\0\x4c\x42\ -\x42\x30\x5f\x31\x32\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\ -\x5f\x5f\x66\x6d\x74\x2e\x32\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\ -\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x31\0\x4c\x42\x42\x30\x5f\x31\x30\0\0\0\0\0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\x01\0\0\0\x06\0\0\0\0\0\ -\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\x2c\0\0\0\x01\0\0\0\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ -\0\x40\0\0\0\0\0\0\0\x90\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\0\ -\0\0\0\0\0\0\x4f\0\0\0\x01\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd0\x02\0\0\ -\0\0\0\0\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ -\x67\0\0\0\x01\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xdd\x02\0\0\0\0\0\0\x6a\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x73\0\0\0\x01\ -\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x47\x03\0\0\0\0\0\0\xf2\x09\0\0\0\0\0\0\ -\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x01\0\0\0\0\0\0\0\ -\0\0\0\0\0\0\0\0\0\0\0\0\x39\x0d\0\0\0\0\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ -\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5f\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ -\0\0\0\0\x40\x10\0\0\0\0\0\0\x88\x02\0\0\0\0\0\0\x0c\0\0\0\x19\0\0\0\x08\0\0\0\ -\0\0\0\0\x18\0\0\0\0\0\0\0\x28\0\0\0\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ -\xc8\x12\0\0\0\0\0\0\xa0\0\0\0\0\0\0\0\x07\0\0\0\x02\0\0\0\x08\0\0\0\0\0\0\0\ -\x10\0\0\0\0\0\0\0\x6f\0\0\0\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x68\x13\ -\0\0\0\0\0\0\xb0\0\0\0\0\0\0\0\x07\0\0\0\x05\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\ -\0\0\0\0\x07\0\0\0\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\x14\0\0\0\0\0\ -\0\xd0\x02\0\0\0\0\0\0\x07\0\0\0\x06\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\ -\x35\0\0\0\x03\x4c\xff\x6f\0\0\0\x80\0\0\0\0\0\0\0\0\0\0\0\0\xe8\x16\0\0\0\0\0\ -\0\x0c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x57\0\0\ -\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf4\x16\0\0\0\0\0\0\xa2\x01\0\0\0\ -\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; +\x35\0\x4c\x42\x42\x30\x5f\x34\0\x4c\x42\x42\x30\x5f\x32\x34\0\x78\x64\x70\x5f\ +\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x31\x34\0\x78\ +\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\ +\x34\0\x4c\x42\x42\x30\x5f\x31\x33\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\ +\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x31\x33\0\x78\x64\x70\x5f\x72\x65\x63\ +\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x33\0\x4c\x42\x42\x30\x5f\ +\x32\0\x4c\x42\x42\x30\x5f\x33\x32\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\ +\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x31\x32\0\x78\x64\x70\x5f\x72\x65\x63\ +\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x32\0\x4c\x42\x42\x30\x5f\ +\x33\x31\0\x4c\x42\x42\x30\x5f\x31\x31\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\ +\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x31\x31\0\x78\x64\x70\x5f\x72\x65\ +\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\x66\x6d\x74\x2e\x31\0\x4c\x42\x42\x30\ +\x5f\x31\x30\0\x78\x64\x70\x5f\x72\x65\x63\x65\x69\x76\x65\x2e\x5f\x5f\x5f\x5f\ +\x66\x6d\x74\x2e\x31\x30\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +\x01\0\0\0\x01\0\0\0\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4e\0\0\0\x01\0\0\ +\0\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\0\0\x50\x04\0\0\0\0\0\0\0\0\ +\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x71\0\0\0\x01\0\0\0\x03\0\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\x90\x04\0\0\0\0\0\0\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x89\0\0\0\x01\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\ +\0\0\0\0\0\x9d\x04\0\0\0\0\0\0\x85\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\x95\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x22\ +\x06\0\0\0\0\0\0\x53\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\ +\0\0\0\0\x0b\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x75\x15\0\0\0\0\0\ +\0\xa0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81\0\ +\0\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\x1a\0\0\0\0\0\0\xa8\x03\0\0\ +\0\0\0\0\x0c\0\0\0\x25\0\0\0\x08\0\0\0\0\0\0\0\x18\0\0\0\0\0\0\0\x4a\0\0\0\x09\ +\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc0\x1d\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\ +\x07\0\0\0\x02\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x91\0\0\0\x09\0\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc0\x1e\0\0\0\0\0\0\x10\x01\0\0\0\0\0\0\x07\0\0\ +\0\x05\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x07\0\0\0\x09\0\0\0\0\0\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\xd0\x1f\0\0\0\0\0\0\x70\x04\0\0\0\0\0\0\x07\0\0\0\x06\0\ +\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x57\0\0\0\x03\x4c\xff\x6f\0\0\0\x80\0\ +\0\0\0\0\0\0\0\0\0\0\0\x40\x24\0\0\0\0\0\0\x12\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x79\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +\0\0\0\0\x52\x24\0\0\0\0\0\0\x66\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\ +\0\0\0\0\0\0\0\0\0\0"; return 0; err: diff --git a/src/bin/xdp_filter b/src/bin/xdp_filter index 3fd0193..37be83e 100755 Binary files a/src/bin/xdp_filter and b/src/bin/xdp_filter differ diff --git a/src/ebpf/xdp_filter.bpf.c b/src/ebpf/xdp_filter.bpf.c index 99247ba..d7df1a3 100644 --- a/src/ebpf/xdp_filter.bpf.c +++ b/src/ebpf/xdp_filter.bpf.c @@ -26,6 +26,7 @@ #include "packet/packet_manager.h" #include "packet/protocol/tcp_helper.h" +#include "xdp/xdp_helper.h" #include "common/common_utils.h" @@ -118,9 +119,53 @@ int xdp_receive(struct xdp_md *ctx) bpf_printk("H"); return XDP_PASS; } + int data_len_prev = data_end-data; + int data_len_next = -1; - bpf_printk("BPF finished\n "); - payload[1] = 'b'; + struct expand_return ret = expand_tcp_packet_payload(ctx, eth, ip, tcp, 2); + if(ret.code == 0){ + //We must check bounds again, otherwise the verifier gets angry + data = (void*)(long)ret.ret_md.data; + data_end = (void*)(long)ret.ret_md.data_end; + eth = data; + if(ethernet_header_bound_check(eth, data_end)<0){ + bpf_printk("Bound check A failed while expanding\n"); + return XDP_PASS; + } + + ip = data + sizeof(*eth); + if (ip_header_bound_check(ip, data_end)<0){ + bpf_printk("Bound check B failed while expanding\n"); + return XDP_PASS; + } + + tcp = (void *)ip + sizeof(*ip); + /*if (get_protocol(data_end) != IPPROTO_TCP){ + bpf_printk("Bound check C failed while expanding\n"); + return XDP_PASS; + }*/ + + if (tcp_header_bound_check(tcp, data_end)){ + bpf_printk("Bound check D failed while expanding\n"); + return XDP_PASS; + } + + payload_size = ntohs(ip->tot_len) - (tcp->doff * 4) - (ip->ihl * 4); + payload = (void *)tcp + tcp->doff*4; + + /*if (tcp_payload_bound_check(payload, payload_size, data_end)){ + bpf_printk("Bound check E failed while expanding\n"); + return XDP_PASS; + }*/ + bpf_printk("BPF finished with ret %i and payload %s of size %i\n ", ret.code, payload, payload_size); + }else{ + bpf_printk("BPF finished with error on expansion\n"); + } + data_len_next = data_end-data; + bpf_printk("Previous length: %i, current length: %i\n", data_len_prev, data_len_next); + //payload[4] = 'A'; + //payload[6] = '\0'; + //payload[1] = 'b'; /*if(!payload){ bpf_probe_read_str(&rb_event->payload, sizeof(rb_event->payload), (void *)payload); bpf_ringbuf_submit(rb_event, 0); diff --git a/src/include/packet/protocol/ip_helper.h b/src/include/packet/protocol/ip_helper.h new file mode 100644 index 0000000..70effb6 --- /dev/null +++ b/src/include/packet/protocol/ip_helper.h @@ -0,0 +1,31 @@ +#ifndef __IP_HELPER_H__ +#define __IP_HELPER_H__ + +#include + +/** + * IP checksum calculation. + * Following RFC 1071. + * In essence 1's complement of 16-bit groups. + * Taken from my own library https://github.com/h3xduck/RawTCP_Lib/blob/master/src/packet.c + */ +static __always_inline unsigned short checksum(unsigned short *addr, int nbytes){ + long sum = 0; + unsigned short checksum; + while(nbytes>1){ + sum += (unsigned short) *addr++; + nbytes -= 2; + } + if(nbytes>0){ + sum +=htons((unsigned char)*addr); + } + + while (sum>>16){ + sum = (sum & 0xffff) + (sum >> 16); + } + + checksum = ~sum; + return checksum; +} + +#endif \ No newline at end of file diff --git a/src/include/packet/protocol/tcp_helper.h b/src/include/packet/protocol/tcp_helper.h index 8c6cfd0..54e601d 100644 --- a/src/include/packet/protocol/tcp_helper.h +++ b/src/include/packet/protocol/tcp_helper.h @@ -13,4 +13,29 @@ static __always_inline int get_tcp_dest_port(struct tcphdr *tcp){ return ntohs(tcp->dest); } +/** + * TCP checksum calculation. + * Following RFC 1071. + * In essence 1's complement of 16-bit groups. + * Taken from my own library https://github.com/h3xduck/RawTCP_Lib/blob/master/src/segment.c + */ +static __always_inline unsigned short tcp_checksum(unsigned short *addr, int nbytes){ + long sum = 0; + unsigned short checksum; + while(nbytes>1){ + sum += (unsigned short) *addr++; + nbytes -= 2; + } + if(nbytes>0){ + sum += htons((unsigned char)*addr); + } + + while (sum>>16){ + sum = (sum & 0xffff) + (sum >> 16); + } + + checksum = ~sum; + return checksum; +} + #endif \ No newline at end of file diff --git a/src/include/xdp/xdp_helper.h b/src/include/xdp/xdp_helper.h new file mode 100644 index 0000000..bf77726 --- /dev/null +++ b/src/include/xdp/xdp_helper.h @@ -0,0 +1,66 @@ +#ifndef __XDP_HELPER_H__ +#define __XDP_HELPER_H__ + +#include + +#include "packet/protocol/ip_helper.h" +#include "packet/protocol/tcp_helper.h" +#include "packet/packet_manager.h" + +static struct expand_return{ + int code; + struct xdp_md ret_md; + void *data; + void *data_end; + struct ethhdr eth; + struct iphdr ip; + struct tcphdr tcp; +}expand_return; + +/** +* Increases the packet payload reserved size by more_bytes bytes +* @param ctx XDP hook metadata +* @param eth start of ethernet header. Points inside ctx struct +* @param ip start of internet protocol header. Points inside ctx struct +* @param tcp start of tcp header. Points inside ctx struct +* @param more_bytes Number bytes to add +* @param +*/ +static __always_inline struct expand_return expand_tcp_packet_payload(struct xdp_md *ctx, struct ethhdr *eth, struct iphdr *ip, struct tcphdr *tcp, int more_bytes){ + //We might be able to reuse some data from old headers, + //but we will have to recompute checksums still + struct ethhdr eth_copy; + struct iphdr ip_copy; + struct tcphdr tcp_copy; + + struct expand_return ret; + + //Copy the header for later before expanding ctx + __builtin_memcpy(ð_copy, eth, sizeof(struct ethhdr)); + __builtin_memcpy(&ip_copy, ip, sizeof(struct iphdr)); + __builtin_memcpy(&tcp_copy, tcp, sizeof(struct tcphdr)); + + if (bpf_xdp_adjust_tail(ctx, (int)(sizeof(char)*more_bytes)) != 0) + { + //Failed to expand + bpf_printk("Failed to expand a tcp packet reserved bytes by %i\n", more_bytes); + ret.code = -1;//The rest is undefined + return ret; + } + + //We now have to readjust the packet headers, checksums have changed + //Note that we do not care about ctx->data_meta or any other extra field + //since we will not be using any communication here + __builtin_memcpy(&(ret.eth), ð_copy, sizeof(struct ethhdr)); + __builtin_memcpy(&(ret.ip), &ip_copy, sizeof(struct iphdr)); + __builtin_memcpy(&(ret.tcp), &tcp_copy, sizeof(struct tcphdr)); + + + ret.ret_md = *ctx; + ret.code = 0; + ret.data = (void *)(long)ctx->data; + ret.data_end = (void *)(long)ctx->data_end; + return ret; +} + +#endif \ No newline at end of file