]> git.zerfleddert.de Git - amt/blob - amtterm.c
translate 0x0a to 0x0d 0x0a in SOL
[amt] / amtterm.c
1 /*
2 * amtterm -- Intel AMT serial-over-lan client, console version.
3 *
4 * Copyright (C) 2007 Gerd Hoffmann <kraxel@redhat.com
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <termios.h>
28 #include <signal.h>
29 #include <sys/ioctl.h>
30
31 #include "redir.h"
32
33 #define APPNAME "amtterm"
34 #define BUFSIZE 512
35
36 /* ------------------------------------------------------------------ */
37
38 static int recv_tty(void *cb_data, unsigned char *buf, int len)
39 {
40 // struct redir *r = cb_data;
41
42 return write(0, buf, len);
43 }
44
45 static void state_tty(void *cb_data, enum redir_state old, enum redir_state new)
46 {
47 struct redir *r = cb_data;
48
49 if (r->verbose)
50 fprintf(stderr, APPNAME ": %s -> %s (%s)\n",
51 redir_state_name(old), redir_state_name(new),
52 redir_state_desc(new));
53 switch (new) {
54 case REDIR_RUN_SOL:
55 if (r->verbose)
56 fprintf(stderr,
57 "serial-over-lan redirection ok\n"
58 "connected now, use ^] to escape\n");
59 break;
60 case REDIR_ERROR:
61 fprintf(stderr, APPNAME ": ERROR: %s\n", r->err);
62 break;
63 default:
64 break;
65 }
66 }
67
68 static int redir_loop(struct redir *r)
69 {
70 unsigned char buf[BUFSIZE+1];
71 struct timeval tv;
72 int rc;
73 fd_set set;
74
75 for(;;) {
76 if (r->state == REDIR_CLOSED ||
77 r->state == REDIR_ERROR)
78 break;
79
80 FD_ZERO(&set);
81 if (r->state == REDIR_RUN_SOL)
82 FD_SET(0,&set);
83 FD_SET(r->sock,&set);
84 tv.tv_sec = HEARTBEAT_INTERVAL * 4 / 1000;
85 tv.tv_usec = 0;
86 switch (select(r->sock+1,&set,NULL,NULL,&tv)) {
87 case -1:
88 perror("select");
89 return -1;
90 case 0:
91 fprintf(stderr,"select: timeout\n");
92 return -1;
93 }
94
95 if (FD_ISSET(0,&set)) {
96 /* stdin has data */
97 rc = read(0,buf,BUFSIZE);
98 switch (rc) {
99 case -1:
100 perror("read(stdin)");
101 return -1;
102 case 0:
103 fprintf(stderr,"EOF from stdin\n");
104 return -1;
105 default:
106 if (buf[0] == 0x1d) {
107 if (r->verbose)
108 fprintf(stderr, "\n" APPNAME ": saw ^], exiting\n");
109 redir_sol_stop(r);
110 }
111 if (-1 == redir_sol_send(r, buf, rc))
112 return -1;
113 break;
114 }
115 }
116
117 if (FD_ISSET(r->sock,&set)) {
118 if (-1 == redir_data(r))
119 return -1;
120 }
121 }
122 return 0;
123 }
124
125 /* ------------------------------------------------------------------ */
126
127 struct termios saved_attributes;
128 int saved_fl;
129
130 static void tty_save(void)
131 {
132 fcntl(0,F_GETFL,&saved_fl);
133 tcgetattr (0, &saved_attributes);
134 }
135
136 static void tty_noecho(void)
137 {
138 struct termios tattr;
139
140 memcpy(&tattr,&saved_attributes,sizeof(struct termios));
141 tattr.c_lflag &= ~(ECHO);
142 tcsetattr (0, TCSAFLUSH, &tattr);
143 }
144
145 static void tty_raw(void)
146 {
147 struct termios tattr;
148
149 fcntl(0,F_SETFL,O_NONBLOCK);
150 memcpy(&tattr,&saved_attributes,sizeof(struct termios));
151 tattr.c_lflag &= ~(ISIG|ICANON|ECHO);
152 tattr.c_cc[VMIN] = 1;
153 tattr.c_cc[VTIME] = 0;
154 tcsetattr (0, TCSAFLUSH, &tattr);
155 }
156
157 static void tty_restore(void)
158 {
159 fcntl(0,F_SETFL,saved_fl);
160 tcsetattr (0, TCSANOW, &saved_attributes);
161 }
162
163 /* ------------------------------------------------------------------ */
164
165 static void usage(FILE *fp)
166 {
167 fprintf(fp,
168 "\n"
169 "This is " APPNAME ", release " VERSION ", I'll establish\n"
170 "serial-over-lan (sol) connections to your Intel AMT boxes.\n"
171 "\n"
172 "usage: " APPNAME " [options] host [port]\n"
173 "options:\n"
174 " -h print this text\n"
175 " -v verbose (default)\n"
176 " -q quiet\n"
177 " -u user username (default: admin)\n"
178 " -p pass password (default: $AMT_PASSWORD)\n"
179 "\n"
180 "By default port 16994 is used.\n"
181 "If no password is given " APPNAME " will ask for one.\n"
182 "\n"
183 "-- \n"
184 "(c) 2007 Gerd Hoffmann <kraxel@redhat.com>\n"
185 "\n");
186 }
187
188 int main(int argc, char *argv[])
189 {
190 struct redir r;
191 char *h;
192 int c;
193
194 memset(&r, 0, sizeof(r));
195 r.verbose = 1;
196 memcpy(r.type, "SOL ", 4);
197 strcpy(r.user, "admin");
198
199 r.cb_data = &r;
200 r.cb_recv = recv_tty;
201 r.cb_state = state_tty;
202
203 if (NULL != (h = getenv("AMT_PASSWORD")))
204 snprintf(r.pass, sizeof(r.pass), "%s", h);
205
206 for (;;) {
207 if (-1 == (c = getopt(argc, argv, "hvqu:p:")))
208 break;
209 switch (c) {
210 case 'v':
211 r.verbose = 1;
212 break;
213 case 'q':
214 r.verbose = 0;
215 break;
216 case 'u':
217 snprintf(r.user, sizeof(r.user), "%s", optarg);
218 break;
219 case 'p':
220 snprintf(r.pass, sizeof(r.pass), "%s", optarg);
221 memset(optarg,'*',strlen(optarg)); /* rm passwd from ps list */
222 break;
223
224 case 'h':
225 usage(stdout);
226 exit(0);
227 default:
228 usage(stderr);
229 exit(1);
230 }
231 }
232
233 if (optind < argc)
234 snprintf(r.host, sizeof(r.host), "%s", argv[optind]);
235 if (optind+1 < argc)
236 snprintf(r.port, sizeof(r.port), "%s", argv[optind+1]);
237 if (0 == strlen(r.host)) {
238 usage(stderr);
239 exit(1);
240 }
241
242 tty_save();
243 if (0 == strlen(r.pass)) {
244 tty_noecho();
245 fprintf(stderr, "AMT password for host %s: ", r.host);
246 fgets(r.pass, sizeof(r.pass), stdin);
247 fprintf(stderr, "\n");
248 if (NULL != (h = strchr(r.pass, '\r')))
249 *h = 0;
250 if (NULL != (h = strchr(r.pass, '\n')))
251 *h = 0;
252 }
253
254 if (-1 == redir_connect(&r)) {
255 tty_restore();
256 exit(1);
257 }
258
259 tty_raw();
260 redir_start(&r);
261 redir_loop(&r);
262 tty_restore();
263
264 exit(0);
265 }
Impressum, Datenschutz