1511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
2511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
3511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *	The Regents of the University of California.  All rights reserved.
4511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *
5511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Redistribution and use in source and binary forms, with or without
6511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * modification, are permitted provided that: (1) source code distributions
7511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * retain the above copyright notice and this paragraph in its entirety, (2)
8511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * distributions including binary code include the above copyright notice and
9511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * this paragraph in its entirety in the documentation or other materials
10511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * provided with the distribution, and (3) all advertising materials mentioning
11511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * features or use of this software display the following acknowledgement:
12511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * ``This product includes software developed by the University of California,
13511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the University nor the names of its contributors may be used to endorse
15511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * or promote products derived from this software without specific prior
16511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * written permission.
17511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
21511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
22511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef lint
23511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic const char copyright[] =
24511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
25511eca30a483e912c274e1d8ba3a0f8f081e2227JP AbgrallThe Regents of the University of California.  All rights reserved.\n";
26511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
27511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
28511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <pcap.h>
29511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdio.h>
30511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdlib.h>
31511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <string.h>
32511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdarg.h>
33511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <unistd.h>
34511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <errno.h>
35511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/types.h>
36511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/select.h>
37511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <poll.h>
38511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
39511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallchar *program_name;
40511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
41511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* Forwards */
42511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void countme(u_char *, const struct pcap_pkthdr *, const u_char *);
43511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void usage(void) __attribute__((noreturn));
44511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void error(const char *, ...);
45511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void warning(const char *, ...);
46511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic char *copy_argv(char **);
47511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
48511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic pcap_t *pd;
49511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
50511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallextern int optind;
51511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallextern int opterr;
52511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallextern char *optarg;
53511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
54511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint
55511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallmain(int argc, char **argv)
56511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
57511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	register int op;
58511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32 localnet, netmask;
59511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	register char *cp, *cmdbuf, *device;
60511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct bpf_program fcode;
61511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	char ebuf[PCAP_ERRBUF_SIZE];
62511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int status;
63511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int packet_count;
64511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
65511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	device = NULL;
66511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if ((cp = strrchr(argv[0], '/')) != NULL)
67511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		program_name = cp + 1;
68511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	else
69511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		program_name = argv[0];
70511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
71511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	opterr = 0;
72511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	while ((op = getopt(argc, argv, "i:")) != -1) {
73511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		switch (op) {
74511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
75511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case 'i':
76511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			device = optarg;
77511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
78511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
79511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		default:
80511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			usage();
81511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* NOTREACHED */
82511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
83511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
84511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
85511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (device == NULL) {
86511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		device = pcap_lookupdev(ebuf);
87511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (device == NULL)
88511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			error("%s", ebuf);
89511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
90511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	*ebuf = '\0';
91511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	pd = pcap_open_live(device, 65535, 0, 1000, ebuf);
92511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (pd == NULL)
93511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		error("%s", ebuf);
94511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	else if (*ebuf)
95511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		warning("%s", ebuf);
96511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
97511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		localnet = 0;
98511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		netmask = 0;
99511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		warning("%s", ebuf);
100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
101511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	cmdbuf = copy_argv(&argv[optind]);
102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0)
104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		error("%s", pcap_geterr(pd));
105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (pcap_setfilter(pd, &fcode) < 0)
107511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		error("%s", pcap_geterr(pd));
108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (pcap_setnonblock(pd, 1, ebuf) == -1)
109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		error("pcap_setnonblock failed: %s", ebuf);
110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	printf("Listening on %s\n", device);
111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	for (;;) {
112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		packet_count = 0;
113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		status = pcap_dispatch(pd, -1, countme,
114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    (u_char *)&packet_count);
115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (status < 0)
116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (status != 0) {
118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			printf("%d packets seen, %d packets counted after pcap_dispatch returns\n",
119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    status, packet_count);
120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (status == -2) {
123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * We got interrupted, so perhaps we didn't
125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * manage to finish a line we were printing.
126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Print an extra newline, just in case.
127511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
128511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		putchar('\n');
129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	(void)fflush(stdout);
131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (status == -1) {
132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Error.  Report it.
134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		(void)fprintf(stderr, "%s: pcap_loop: %s\n",
136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    program_name, pcap_geterr(pd));
137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	pcap_close(pd);
139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	exit(status == -1 ? 1 : 0);
140511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void
143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallcountme(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
145511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int *counterp = (int *)user;
146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	(*counterp)++;
148511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
149511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void
151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallusage(void)
152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	(void)fprintf(stderr, "Usage: %s [ -sptn ] [ -i interface ] [expression]\n",
154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	    program_name);
155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	exit(1);
156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* VARARGS */
159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void
160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallerror(const char *fmt, ...)
161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	va_list ap;
163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	(void)fprintf(stderr, "%s: ", program_name);
165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	va_start(ap, fmt);
166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	(void)vfprintf(stderr, fmt, ap);
167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	va_end(ap);
168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (*fmt) {
169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		fmt += strlen(fmt);
170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (fmt[-1] != '\n')
171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			(void)fputc('\n', stderr);
172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	exit(1);
174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* NOTREACHED */
175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* VARARGS */
178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void
179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallwarning(const char *fmt, ...)
180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	va_list ap;
182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	(void)fprintf(stderr, "%s: WARNING: ", program_name);
184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	va_start(ap, fmt);
185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	(void)vfprintf(stderr, fmt, ap);
186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	va_end(ap);
187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (*fmt) {
188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		fmt += strlen(fmt);
189511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (fmt[-1] != '\n')
190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			(void)fputc('\n', stderr);
191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Copy arg vector into a new buffer, concatenating arguments with spaces.
196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic char *
198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallcopy_argv(register char **argv)
199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	register char **p;
201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	register u_int len = 0;
202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	char *buf;
203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	char *src, *dst;
204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p = argv;
206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (*p == 0)
207511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return 0;
208511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
209511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	while (*p)
210511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		len += strlen(*p++) + 1;
211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	buf = (char *)malloc(len);
213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (buf == NULL)
214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		error("copy_argv: malloc");
215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p = argv;
217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	dst = buf;
218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	while ((src = *p++) != NULL) {
219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		while ((*dst++ = *src++) != '\0')
220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			;
221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		dst[-1] = ' ';
222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	dst[-1] = '\0';
224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return buf;
226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
227