* Fix for unsigned overflows on Solaris
[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.3 1998/09/27 22:12:32 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 #include <pcap.h>
45
46 #include "ethereal.h"
47 #include "packet.h"
48 #include "etypes.h"
49
50 enum lpr_type { request, response };
51
52 void
53 dissect_lpd(const u_char *pd, int offset, frame_data *fd, GtkTree *tree)
54 {
55         GtkWidget       *lpd_tree, *ti;
56         enum lpr_type   lpr_packet_type;
57         char            *newline, *printer, *line_pos;
58         int                     substr_len, curr_offset;
59
60         /* This information comes from the LPRng HOWTO, which also describes
61                 RFC 1179. http://www.astart.com/lprng/LPRng-HOWTO.html */
62         char            *lpd_client_code[] = {
63                 "Unknown command",
64                 "LPC: start print",
65                 "LPR: transfer a printer job",
66                 "LPQ: print short form of queue status",
67                 "LPQ: print long form of queue status",
68                 "LPRM: remove jobs",
69                 "LPRng lpc: do control operation",
70                 "LPRng lpr: transfer a block format print job",
71                 "LPRng lpc: secure command transfer",
72                 "LPRng lpq: verbose status information"
73         };
74         char            *lpd_server_code[] = {
75                 "Success: accepted, proceed",
76                 "Queue not accepting jobs",
77                 "Queue temporarily full, retry later",
78                 "Bad job format, do not retry"
79         };
80
81
82         if (pd[offset+1] == '\n') {
83                 lpr_packet_type = response;
84         }
85         else if (pd[offset] <= 9) {
86                 lpr_packet_type = request;
87         }
88         else {
89                 lpr_packet_type = response;
90         }
91
92
93         if (fd->win_info[COL_NUM]) {
94                 strcpy(fd->win_info[COL_PROTOCOL], "LPD");
95                 if (lpr_packet_type == request) {
96                         strcpy(fd->win_info[COL_INFO], lpd_client_code[pd[offset]]);
97                 }
98                 else {
99                         strcpy(fd->win_info[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