]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/ipfilter/lib/ipft_sn.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / ipfilter / lib / ipft_sn.c
1 /*      $FreeBSD$       */
2
3 /*
4  * Copyright (C) 2000-2003 by Darren Reed.
5  *
6  * See the IPFILTER.LICENCE file for details on licencing.
7  *
8  * $Id: ipft_sn.c,v 1.7.4.1 2006/06/16 17:21:03 darrenr Exp $
9  */
10
11 /*
12  * Written to comply with the recent RFC 1761 from Sun.
13  */
14 #include "ipf.h"
15 #include "snoop.h"
16 #include "ipt.h"
17
18 #if !defined(lint)
19 static const char rcsid[] = "@(#)$Id: ipft_sn.c,v 1.7.4.1 2006/06/16 17:21:03 darrenr Exp $";
20 #endif
21
22 struct  llc     {
23         int     lc_sz;  /* LLC header length */
24         int     lc_to;  /* LLC Type offset */
25         int     lc_tl;  /* LLC Type length */
26 };
27
28 /*
29  * While many of these maybe the same, some do have different header formats
30  * which make this useful.
31  */
32 static  struct  llc     llcs[SDL_MAX+1] = {
33         { 0, 0, 0 },    /* SDL_8023 */
34         { 0, 0, 0 },    /* SDL_8024 */
35         { 0, 0, 0 },    /* SDL_8025 */
36         { 0, 0, 0 },    /* SDL_8026 */
37         { 14, 12, 2 },  /* SDL_ETHER */
38         { 0, 0, 0 },    /* SDL_HDLC */
39         { 0, 0, 0 },    /* SDL_CHSYNC */
40         { 0, 0, 0 },    /* SDL_IBMCC */
41         { 0, 0, 0 },    /* SDL_FDDI */
42         { 0, 0, 0 },    /* SDL_OTHER */
43 };
44
45 static  int     snoop_open __P((char *));
46 static  int     snoop_close __P((void));
47 static  int     snoop_readip __P((char *, int, char **, int *));
48
49 static  int     sfd = -1, s_type = -1;
50 static  int     snoop_read_rec __P((struct snooppkt *));
51
52 struct  ipread  snoop = { snoop_open, snoop_close, snoop_readip, 0 };
53
54
55 static  int     snoop_open(fname)
56 char    *fname;
57 {
58         struct  snoophdr sh;
59         int     fd;
60         int s_v;
61
62         if (sfd != -1)
63                 return sfd;
64
65         if (!strcmp(fname, "-"))
66                 fd = 0;
67         else if ((fd = open(fname, O_RDONLY)) == -1)
68                 return -1;
69
70         if (read(fd, (char *)&sh, sizeof(sh)) != sizeof(sh))
71                 return -2;
72
73         s_v = (int)ntohl(sh.s_v);
74         s_type = (int)ntohl(sh.s_type);
75
76         if (s_v != SNOOP_VERSION ||
77             s_type < 0 || s_type > SDL_MAX) {
78                 (void) close(fd);
79                 return -2;
80         }
81
82         sfd = fd;
83         printf("opened snoop file %s:\n", fname);
84         printf("\tid: %8.8s version: %d type: %d\n", sh.s_id, s_v, s_type);
85
86         return fd;
87 }
88
89
90 static  int     snoop_close()
91 {
92         return close(sfd);
93 }
94
95
96 /*
97  * read in the header (and validate) which should be the first record
98  * in a snoop file.
99  */
100 static  int     snoop_read_rec(rec)
101 struct  snooppkt *rec;
102 {
103         int     n, plen, ilen;
104
105         if (read(sfd, (char *)rec, sizeof(*rec)) != sizeof(*rec))
106                 return -2;
107
108         ilen = (int)ntohl(rec->sp_ilen);
109         plen = (int)ntohl(rec->sp_plen);
110         if (ilen > plen || plen < sizeof(*rec))
111                 return -2;
112
113         plen -= sizeof(*rec);
114         n = MIN(plen, ilen);
115         if (!n || n < 0)
116                 return -3;
117
118         return plen;
119 }
120
121
122 #ifdef  notyet
123 /*
124  * read an entire snoop packet record.  only the data part is copied into
125  * the available buffer, with the number of bytes copied returned.
126  */
127 static  int     snoop_read(buf, cnt)
128 char    *buf;
129 int     cnt;
130 {
131         struct  snooppkt rec;
132         static  char    *bufp = NULL;
133         int     i, n;
134
135         if ((i = snoop_read_rec(&rec)) <= 0)
136                 return i;
137
138         if (!bufp)
139                 bufp = malloc(i);
140         else
141                 bufp = realloc(bufp, i);
142
143         if (read(sfd, bufp, i) != i)
144                 return -2;
145
146         n = MIN(i, cnt);
147         bcopy(bufp, buf, n);
148         return n;
149 }
150 #endif
151
152
153 /*
154  * return only an IP packet read into buf
155  */
156 static  int     snoop_readip(buf, cnt, ifn, dir)
157 char    *buf, **ifn;
158 int     cnt, *dir;
159 {
160         static  char    *bufp = NULL;
161         struct  snooppkt rec;
162         struct  llc     *l;
163         char    ty[4], *s;
164         int     i, n;
165
166         do {
167                 if ((i = snoop_read_rec(&rec)) <= 0)
168                         return i;
169
170                 if (!bufp)
171                         bufp = malloc(i);
172                 else
173                         bufp = realloc(bufp, i);
174                 s = bufp;
175
176                 if (read(sfd, s, i) != i)
177                         return -2;
178
179                 l = &llcs[s_type];
180                 i -= l->lc_to;
181                 s += l->lc_to;
182                 /*
183                  * XXX - bogus assumption here on the part of the time field
184                  * that it won't be greater than 4 bytes and the 1st two will
185                  * have the values 8 and 0 for IP.  Should be a table of
186                  * these too somewhere.  Really only works for SDL_ETHER.
187                  */
188                 bcopy(s, ty, l->lc_tl);
189         } while (ty[0] != 0x8 && ty[1] != 0);
190
191         i -= l->lc_tl;
192         s += l->lc_tl;
193         n = MIN(i, cnt);
194         bcopy(s, buf, n);
195
196         return n;
197 }