* Added column formatting functionality.
[obnox/wireshark/wip.git] / packet-lpd.c
1 /* packet-lpr.c
2  * Routines for LPR and LPRng packet disassembly
3  * Gilbert Ramirez <gram@verdict.uthscsa.edu>
4  *
5  * $Id: packet-lpd.c,v 1.5 1998/11/17 04:28:57 gerald Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@unicom.net>
9  * Copyright 1998 Gerald Combs
10  *
11  * 
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <gtk/gtk.h>
32
33 #include <stdio.h>
34 #include <string.h>
35
36 #ifdef HAVE_SYS_TYPES_H
37 # include <sys/types.h>
38 #endif
39
40 #ifdef HAVE_NETINET_IN_H
41 # include <netinet/in.h>
42 #endif
43
44
45 #include "ethereal.h"
46 #include "packet.h"
47 #include "etypes.h"
48
49 enum lpr_type { request, response };
50
51 void
52 dissect_lpd(const u_char *pd, int offset, frame_data *fd, GtkTree *tree)
53 {
54         GtkWidget       *lpd_tree, *ti;
55         enum lpr_type   lpr_packet_type;
56         char            *newline, *printer, *line_pos;
57         int                     substr_len, curr_offset;
58
59         /* This information comes from the LPRng HOWTO, which also describes
60                 RFC 1179. http://www.astart.com/lprng/LPRng-HOWTO.html */
61         char            *lpd_client_code[] = {
62                 "Unknown command",
63                 "LPC: start print",
64                 "LPR: transfer a printer job",
65                 "LPQ: print short form of queue status",
66                 "LPQ: print long form of queue status",
67                 "LPRM: remove jobs",
68                 "LPRng lpc: do control operation",
69                 "LPRng lpr: transfer a block format print job",
70                 "LPRng lpc: secure command transfer",
71                 "LPRng lpq: verbose status information"
72         };
73         char            *lpd_server_code[] = {
74                 "Success: accepted, proceed",
75                 "Queue not accepting jobs",
76                 "Queue temporarily full, retry later",
77                 "Bad job format, do not retry"
78         };
79
80
81         if (pd[offset+1] == '\n') {
82                 lpr_packet_type = response;
83         }
84         else if (pd[offset] <= 9) {
85                 lpr_packet_type = request;
86         }
87         else {
88                 lpr_packet_type = response;
89         }
90
91
92         if (check_col(fd, COL_PROTOCOL))
93                 col_add_str(fd, COL_PROTOCOL, "LPD");
94         if (check_col(fd, COL_INFO)) {
95                 if (lpr_packet_type == request) {
96                         col_add_str(fd, COL_INFO, lpd_client_code[pd[offset]]);
97                 }
98                 else {
99                         col_add_str(fd, COL_INFO, "LPD response");
100                 }
101         }
102
103         if (tree) {
104                 ti = add_item_to_tree(GTK_WIDGET(tree), offset, fd->cap_len - offset,
105                   "Line Printer Daemon Protocol");
106                 lpd_tree = gtk_tree_new();
107                 add_subtree(ti, lpd_tree, ETT_LPD);
108
109                 if (lpr_packet_type == request) {
110                         if (pd[offset] <= 9) {
111                                 add_item_to_tree(lpd_tree, offset,              1,
112                                         lpd_client_code[pd[offset]]);
113                         }
114                         else {
115                                 add_item_to_tree(lpd_tree, offset,              1,
116                                         lpd_client_code[0]);
117                         }
118                         printer = strdup(&pd[offset+1]);
119
120                         /* get rid of the new-line so that the tree prints out nicely */
121                         if (printer[fd->cap_len - offset - 2] == 0x0a) {
122                                 printer[fd->cap_len - offset - 2] = 0;
123                         }
124                         add_item_to_tree(lpd_tree, offset+1, fd->cap_len - (offset+1),
125                                         /*"Printer/options: %s", &pd[offset+1]);*/
126                                         "Printer/options: %s", printer);
127                         free(printer);
128                 }
129                 else {
130                         if (pd[offset] <= 3) {
131                                 add_item_to_tree(lpd_tree, offset, 2, "Response: %s",
132                                         lpd_server_code[pd[offset]]);
133                         }
134                         else {
135                                 printer = strdup(&pd[offset]);
136                                 line_pos = printer;
137                                 curr_offset = offset;
138                                 while (fd->cap_len > curr_offset) {
139                                         newline = strchr(line_pos, '\n');
140                                         if (!newline) {
141                                                 add_item_to_tree(lpd_tree, curr_offset,
142                                                         fd->cap_len - offset, "Text: %s", line_pos);
143                                                 break;
144                                         }
145                                         *newline = 0;
146                                         substr_len = strlen(line_pos);
147                                         add_item_to_tree(lpd_tree, curr_offset, substr_len + 1,
148                                                 "Text: %s", line_pos);
149                                         curr_offset += substr_len + 1;
150                                         line_pos = newline + 1;
151                                 }
152                         }
153                 }
154         }
155 }
156