1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 2002-2012 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Eclipse Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.eclipse.org/org/documents/epl-v10.html *
11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Aman Shaikh <ashaikh@research.att.com> *
18 * *
19 ***********************************************************************/
20 /********************************************************************
21 * File name : ospf_text_lsa.c
22 * Objective : Defines functions for dealing with LSA logs in text
23 * format.
24 *********************************************************************/
25
26 #include "./include.h"
27
28 static const char magic_name[] = "OSPF LSAs (text format)\n";
29 static const char magic_version[] = "20030214\n";
30
31 /*
32 * identf for 'text_lsa_format'.
33 * Determines if a file contains text LSA logs
34 * given 'buff_p' holding first 'size' bytes.
35 * Looks for proper MAGIC_NAME, MAGIC_TYPE and record size.
36 */
37 static int identf_text_lsa_file(Dssfile_t *fp, void *buff_p, size_t size,
38 Dssdisc_t *disc);
39
40 /*
41 * openf for 'text_lsa_format'.
42 * Allocates space for reading LSAR LSA records.
43 */
44 static int open_text_lsa_file(Dssfile_t *fp, Dssdisc_t *disc);
45
46 /*
47 * closef for 'text_lsa_format'.
48 * Frees space for reading LSAR LSA records.
49 */
50 static int close_text_lsa_file(Dssfile_t *fp, Dssdisc_t *disc);
51
52 /*
53 * readf for 'text_lsa_format'.
54 * Reads a text OSPF LSA record and returns
55 * a ptr to 'ospf_lsa_can_t' object.
56 * Returns NULL if can't read further.
57 */
58 static int read_text_lsa_rec(Dssfile_t *fp, Dssrecord_t *rp,
59 Dssdisc_t *disc);
60
61 /*
62 * writef for 'text_lsa_format'.
63 * Writes canonical OSPF LSA record (in host order).
64 */
65 static int write_text_lsa_rec(Dssfile_t *fp, Dssrecord_t *rp,
66 Dssdisc_t *disc);
67
68 #define FORMAT_NAME "text"
69
70 /* Type object for file formats containing text lsa logs */
71 Dssformat_t text_lsa_format = {
72 FORMAT_NAME, /* name */
73 "OSPF lsa text format", /* description */
74 CXH,
75 identf_text_lsa_file, /* identf */
76 open_text_lsa_file, /* openf */
77 NULL, /* readf */
78 write_text_lsa_rec, /* writef */
79 NULL, /* seekf */
80 close_text_lsa_file, /* closef */
81 NULL, /* savef */
82 NULL, /* dropf */
83 /* private stuff */
84 OSPF_TEXT_LSA_NEXT /* next */
85 };
86
87 static int
identf_text_lsa_file(Dssfile_t * fp,void * buff_p,size_t size,Dssdisc_t * disc)88 identf_text_lsa_file(Dssfile_t *fp, void *buff_p, size_t size,
89 Dssdisc_t *disc) {
90 char *s;
91 size_t n;
92
93 ASSERT(fp);
94 ASSERT(buff_p);
95 ASSERT(disc);
96
97 /* Check if first line is ascii-readable or not */
98 s = (char *)buff_p;
99 n = sizeof(magic_name) + sizeof(magic_version);
100 if (size < n) {
101 if (disc->errorf && (fp->dss->flags & DSS_DEBUG)) {
102 (*disc->errorf)(NULL, disc, 2,
103 "%s: not enough bytes for magic name and version",
104 FORMAT_NAME);
105 }
106 return 0;
107 }
108 if (!strneq(s, magic_name, sizeof(magic_name) - 1)) {
109 if (disc->errorf && (fp->dss->flags & DSS_DEBUG)) {
110 (*disc->errorf)(NULL, disc, 2, "%s: magic name \"%-.*s\" does not match expected \"%s\"", FORMAT_NAME, strlen(magic_name), s, magic_name);
111 }
112 return 0;
113 }
114 s += sizeof(magic_name);
115 if (!strneq(s, magic_version, sizeof(magic_name) - 1)) {
116 if (disc->errorf && (fp->dss->flags & DSS_DEBUG)) {
117 (*disc->errorf)(NULL, disc, 2, "%s: magic version \"%-.*s\" is not the expected \"%s\"", FORMAT_NAME, strlen(magic_version), s, magic_version);
118 }
119 return 0;
120 }
121 if (disc->errorf && (fp->dss->flags & DSS_DEBUG))
122 (*disc->errorf)(NULL, disc, 2, "%s: format \"%s\" type \"%s\" version %s", fp->path, FORMAT_NAME, magic_name, magic_version);
123 return 1;
124 }
125
126 static int
open_text_lsa_file(Dssfile_t * fp,Dssdisc_t * disc)127 open_text_lsa_file(Dssfile_t *fp, Dssdisc_t *disc) {
128 if (fp->flags & DSS_FILE_WRITE) {
129 if (!BIT_TEST(fp->flags, DSS_FILE_APPEND)) {
130 sfprintf(fp->io, "%s%s", magic_name, magic_version);
131 }
132 } else {
133 #if 0
134 /* Want to support read?? */
135 /*XXX*/
136 #endif
137 }
138 return 0;
139 }
140
141 static int
close_text_lsa_file(Dssfile_t * fp,Dssdisc_t * disc)142 close_text_lsa_file(Dssfile_t *fp, Dssdisc_t *disc) {
143 return 0;
144 }
145
146 static int
read_text_lsa_rec(Dssfile_t * fp,Dssrecord_t * rp,Dssdisc_t * disc)147 read_text_lsa_rec(Dssfile_t *fp, Dssrecord_t *rp, Dssdisc_t *disc) {
148 /* Want to support read? */
149 /*XXX*/
150 return 0;
151 }
152
153 static int
write_text_lsa_rec(Dssfile_t * fp,Dssrecord_t * rp,Dssdisc_t * disc)154 write_text_lsa_rec(Dssfile_t *fp, Dssrecord_t *rp, Dssdisc_t *disc) {
155 Sfio_t *iop;
156 ospf_lsa_can_t *lsa_can_p;
157 uint32_t i;
158 uint8_t *data_p;
159
160 ASSERT(fp);
161 ASSERT(rp);
162 ASSERT(disc);
163 iop = fp->io;
164 ASSERT(iop);
165 lsa_can_p = (ospf_lsa_can_t *)(rp->data);
166 ASSERT(lsa_can_p);
167
168 /* Write LSU header parameters */
169 sfprintf(iop, "%u.%06u|%s|%s|%u|%s|%s|%u|",
170 lsa_can_p->sec, lsa_can_p->micro_sec,
171 ipaddr_to_dotted_decimal(lsa_can_p->src_ip_addr),
172 ipaddr_to_dotted_decimal(lsa_can_p->dest_ip_addr),
173 lsa_can_p->lsu_len,
174 ipaddr_to_dotted_decimal(lsa_can_p->lsu_rtid),
175 ipaddr_to_dotted_decimal(lsa_can_p->lsu_areaid),
176 lsa_can_p->lsu_no_lsas);
177
178 /* Write LSA header */
179 sfprintf(iop, "%u|%s|%s|%u|0x%x|0x%x|%u|%u|",
180 lsa_can_p->lsa_type,
181 ipaddr_to_dotted_decimal(lsa_can_p->lsa_advrt),
182 ipaddr_to_dotted_decimal(lsa_can_p->lsa_id),
183 lsa_can_p->lsa_age,
184 lsa_can_p->lsa_seq,
185 lsa_can_p->lsa_cksum,
186 lsa_can_p->lsa_len,
187 lsa_can_p->lsu_lsa_no);
188
189 /* Write LSA instance type */
190 switch (lsa_can_p->lsa_inst_type) {
191 case LSA_INST_NEW:
192 sfprintf(iop, "new|");
193 break;
194
195 case LSA_INST_DUP:
196 sfprintf(iop, "dup|");
197 break;
198
199 case LSA_INST_OLD:
200 sfprintf(iop, "old|");
201 break;
202
203 case LSA_INST_REQ:
204 sfprintf(iop, "req|");
205 break;
206
207 case LSA_INST_CKSUM_ERR:
208 sfprintf(iop, "cksum_err|");
209 break;
210
211 case LSA_INST_BAD_RTR:
212 sfprintf(iop, "bad_rtr|");
213 break;
214
215 case LSA_INST_ASE_IN_STUB:
216 sfprintf(iop, "ase_in_stub|");
217 break;
218
219 case LSA_INST_TYPE7_IN_NONNSSA:
220 sfprintf(iop, "type7_in_nonnssa|");
221 break;
222
223 default:
224 sfprintf(iop, "unknown|");
225 break;
226 } /* End of switch */
227
228 /* Write LSA data as a string of bytes in hex-format. */
229 sfprintf(iop, "%u|", lsa_can_p->lsa_data_size);
230 for (i = 0, data_p = lsa_can_p->lsa_data_p;
231 i < lsa_can_p->lsa_data_size; i++) {
232 sfprintf(iop, "%.2x", data_p[i]);
233 } /* End of for (i) */
234 sfprintf(iop, "|\n");
235
236 return 0;
237 }
238