b8963e9e3ca0a65c7aaf5ad3a1a0b699301ef1b6
[oweals/nmrpflash.git] / main.c
1 /**
2  * nmrp-flash - Netgear Unbrick Utility
3  * Copyright (C) 2016 Joseph Lehner <joseph.c.lehner@gmail.com>
4  *
5  * nmrp-flash is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * nmrp-flash is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with nmrp-flash.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19
20 #include <unistd.h>
21 #include <getopt.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include "nmrpd.h"
25
26 #define NMRPFLASH_TFTP_TEST
27
28 int verbosity = 0;
29
30 void usage(FILE *fp)
31 {
32         fprintf(fp,
33                         "Usage: nmrp-flash [OPTIONS...]\n"
34                         "\n"
35                         "Options (-a, -i and -f are mandatory):\n"
36                         " -a <ipaddr>     IP address to assign to target device\n"
37                         " -f <firmware>   Firmware file\n"
38                         " -i <interface>  Network interface directly connected to device\n"
39                         " -m <mac>        MAC address of target device (xx:xx:xx:xx:xx:xx)\n"
40                         " -M <netmask>    Subnet mask to assign to target device\n"
41                         " -t <timeout>    Timeout (in milliseconds) for regular messages\n"
42                         " -T <timeout>    Time to wait after successfull TFTP upload\n"
43                         " -p <port>       Port to use for TFTP upload\n"
44 #ifdef NMRPFLASH_TFTP_TEST
45                         " -U              Test TFTP upload\n"
46 #endif
47                         " -v              Be verbose\n"
48                         " -V              Print version and exit\n"
49                         " -L              List network interfaces\n"
50                         " -h              Show this screen\n"
51                         "\n"
52                         "Example:\n"
53                         "\n"
54 #ifndef NMRPFLASH_WINDOWS
55                         "$ sudo nmrp-flash -i eth0 -a 192.168.1.254 -f firmware.bin\n"
56 #else
57                         "C:\\> nmrp-flash.exe -i net0 -a 192.168.1.254 -f firmware.bin\n"
58 #endif
59                         "\n"
60                         "nmrp-flash v%s, Copyright (C) 2016 Joseph C. Lehner\n"
61                         "nmrp-flash is free software, licensed under the GNU GPLv3.\n"
62                         "Source code at https://github.com/jclehner/nmrp-flash\n"
63                         "\n",
64                         NMRPD_VERSION
65           );
66 }
67
68 int main(int argc, char **argv)
69 {
70         int c, val, max;
71         struct nmrpd_args args = {
72                 .rx_timeout = 200,
73                 .ul_timeout = 60000,
74                 .tftpcmd = NULL,
75                 .filename = NULL,
76                 .ipaddr = NULL,
77                 .ipmask = "255.255.255.0",
78                 .intf = NULL,
79                 .mac = "ff:ff:ff:ff:ff:ff",
80                 .op = NMRP_UPLOAD_FW,
81                 .port = 69,
82                 .force_root = 1
83         };
84 #ifdef NMRPFLASH_WINDOWS
85         WSADATA wsa;
86
87         val = WSAStartup(MAKEWORD(2, 2), &wsa);
88         if (val != 0) {
89                 win_perror2("WSAStartup", val);
90                 return 1;
91         }
92 #endif
93
94         opterr = 0;
95
96         while ((c = getopt(argc, argv, "a:f:i:m:M:p:t:T:hLVvU")) != -1) {
97                 max = 0x7fffffff;
98                 switch (c) {
99                         case 'a':
100                                 args.ipaddr = optarg;
101                                 break;
102                         case 'f':
103                                 args.filename = optarg;
104                                 break;
105                         case 'i':
106                                 args.intf = optarg;
107                                 break;
108                         case 'm':
109                                 args.mac = optarg;
110                                 break;
111                         case 'M':
112                                 args.ipmask = optarg;
113                                 break;
114                         case 'p':
115                                 max = 0xffff;
116                         case 'T':
117                         case 't':
118                                 val = atoi(optarg);
119                                 if (val <= 0 || val > max) {
120                                         fprintf(stderr, "Invalid numeric value for -%c.\n", c);
121                                         return 1;
122                                 }
123
124                                 if (c == 'p') {
125                                         args.port = val;
126                                 } else if (c == 't') {
127                                         args.rx_timeout = val;
128                                 } else {
129                                         args.ul_timeout = val;
130                                 }
131
132                                 break;
133                         case 'V':
134                                 printf("nmrp-flash v%s\n", NMRPD_VERSION);
135                                 val = 0;
136                                 goto out;
137                         case 'v':
138                                 ++verbosity;
139                                 break;
140                         case 'L':
141                                 val = ethsock_list_all();
142                                 goto out;
143                         case 'h':
144                                 usage(stdout);
145                                 val = 0;
146                                 goto out;
147 #ifdef NMRPFLASH_TFTP_TEST
148                         case 'U':
149                                 if (args.ipaddr && args.filename) {
150                                         val = tftp_put(&args);
151                                         goto out;
152                                 }
153                                 /* fall through */
154 #endif
155                         default:
156                                 usage(stderr);
157                                 val = 1;
158                                 goto out;
159                 }
160         }
161
162         if (!args.filename || !args.intf || !args.ipaddr) {
163                 usage(stderr);
164                 return 1;
165         }
166
167 #ifndef NMRPFLASH_WINDOWS
168         if (geteuid() != 0) {
169                 fprintf(stderr, "This program must be run as root!\n");
170                 return 1;
171         }
172 #endif
173
174         val = nmrp_do(&args);
175
176 out:
177 #ifdef NMRPFLASH_WINDOWS
178         WSACleanup();
179 #endif
180         return val;
181 }