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