~ubuntu-branches/debian/sid/net-tools/sid

« back to all changes in this revision

Viewing changes to .pc/fix-fprintf.patch/rarp.c

  • Committer: Package Import Robot
  • Author(s): Martín Ferrari
  • Date: 2015-09-07 01:54:07 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20150907015407-v2tfsgxayjd3iq4i
Tags: 1.60+git20150829.73cef8a-1
* After 14 years without an upstream release, I am producing a new package
  based on today's upstream repository.
  Closes: #391495, #486448, #323261, #260587, #545328, #511395.
* Remove many patches now merged upstream, delete unmaintainable and
  undocumented local changes, and update the rest.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * rarp               This file contains an implementation of the command
3
 
 *              that maintains the kernel's RARP cache.  It is derived
4
 
 *              from Fred N. van Kempen's arp command.
5
 
 *
6
 
 * Version:     $Id: rarp.c,v 1.9 2007/12/02 02:19:52 ecki Exp $
7
 
 *
8
 
 * Usage:       rarp -d hostname                      Delete entry
9
 
 *              rarp -s hostname ethernet_address     Add entry
10
 
 *              rarp -a                               Print entries
11
 
 *              rarp -f                               Add frop /etc/ethers
12
 
 *
13
 
 * Rewritten: Phil Blundell <Philip.Blundell@pobox.com>  1997-08-03
14
 
 * gettext instead of catgets: Arnaldo Carvalho de Melo <acme@conectiva.com.br> 1998-06-29
15
 
 * 1998-01-01 Bernd Eckenfels   reorganised usage()
16
 
 * 2001-04-04 Arnaldo Carvalho de Melo - use setlocale
17
 
 *
18
 
 */
19
 
 
20
 
#include <sys/types.h>
21
 
#include <sys/socket.h>
22
 
#include <sys/ioctl.h>
23
 
#include <netinet/in.h>
24
 
#include <arpa/inet.h>
25
 
#include <net/if.h>
26
 
#include <net/if_arp.h>
27
 
#include <stdlib.h>
28
 
#include <stdio.h>
29
 
#include <errno.h>
30
 
#include <fcntl.h>
31
 
#include <netdb.h>
32
 
#include <string.h>
33
 
#include <unistd.h>
34
 
#include <getopt.h>
35
 
 
36
 
#define DFLT_HW "ether"
37
 
 
38
 
#include "config.h"
39
 
#include "intl.h"
40
 
#include "net-support.h"
41
 
#include "version.h"
42
 
#include "pathnames.h"
43
 
#include "proc.h"
44
 
 
45
 
static char no_rarp_message[] = N_("This kernel does not support RARP.\n");
46
 
 
47
 
static char version_string[] = RELEASE "\nrarp 1.03 (2001-04-04)\n";
48
 
 
49
 
static struct hwtype *hardware = NULL;
50
 
 
51
 
/* Delete an entry from the RARP cache. */
52
 
static int rarp_delete(int fd, struct hostent *hp)
53
 
{
54
 
    struct arpreq req;
55
 
    struct sockaddr_in *si;
56
 
    unsigned int found = 0;
57
 
    char **addr;
58
 
 
59
 
    /* The host can have more than one address, so we loop on them. */
60
 
    for (addr = hp->h_addr_list; *addr != NULL; addr++) {
61
 
        memset((char *) &req, 0, sizeof(req));
62
 
        si = (struct sockaddr_in *) &req.arp_pa;
63
 
        si->sin_family = hp->h_addrtype;
64
 
        memcpy((char *) &si->sin_addr, *addr, hp->h_length);
65
 
 
66
 
        /* Call the kernel. */
67
 
        if (ioctl(fd, SIOCDRARP, &req) == 0) {
68
 
            found++;
69
 
        } else {
70
 
            switch (errno) {
71
 
            case ENXIO:
72
 
                break;
73
 
            case ENODEV:
74
 
                fputs(_(no_rarp_message), stderr);
75
 
                return 1;
76
 
            default:
77
 
                perror("SIOCDRARP");
78
 
                return 1;
79
 
            }
80
 
        }
81
 
    }
82
 
 
83
 
    if (found == 0)
84
 
        printf(_("no RARP entry for %s.\n"), hp->h_name);
85
 
    return 0;
86
 
}
87
 
 
88
 
 
89
 
/* Set an entry in the RARP cache. */
90
 
static int rarp_set(int fd, struct hostent *hp, char *hw_addr)
91
 
{
92
 
    struct arpreq req;
93
 
    struct sockaddr_in *si;
94
 
    struct sockaddr sap;
95
 
 
96
 
    if (hardware->input(hw_addr, &sap)) {
97
 
        fprintf(stderr, _("%s: bad hardware address\n"), hw_addr);
98
 
        return 1;
99
 
    }
100
 
    /* Clear and fill in the request block. */
101
 
    memset((char *) &req, 0, sizeof(req));
102
 
    si = (struct sockaddr_in *) &req.arp_pa;
103
 
    si->sin_family = hp->h_addrtype;
104
 
    memcpy((char *) &si->sin_addr, hp->h_addr_list[0], hp->h_length);
105
 
    req.arp_ha.sa_family = hardware->type;
106
 
    memcpy(req.arp_ha.sa_data, sap.sa_data, hardware->alen);
107
 
 
108
 
    /* Call the kernel. */
109
 
    if (ioctl(fd, SIOCSRARP, &req) < 0) {
110
 
        if (errno == ENODEV)
111
 
            fputs(_(no_rarp_message), stderr);
112
 
        else
113
 
            perror("SIOCSRARP");
114
 
        return 1;
115
 
    }
116
 
    return 0;
117
 
}
118
 
 
119
 
/* Process an EtherFile */
120
 
static int rarp_file(int fd, const char *name)
121
 
{
122
 
    char buff[1024];
123
 
    char *host, *addr;
124
 
    int linenr;
125
 
    FILE *fp;
126
 
    struct hostent *hp;
127
 
 
128
 
    if ((fp = fopen(name, "r")) == NULL) {
129
 
        fprintf(stderr, _("rarp: cannot open file %s:%s.\n"), name, strerror(errno));
130
 
        return -1;
131
 
    }
132
 
    /* Read the lines in the file. */
133
 
    linenr = 0;
134
 
    while (fgets(buff, sizeof(buff), fp)) {
135
 
        ++linenr;
136
 
        if (buff[0] == '#' || buff[0] == '\0')
137
 
            continue;
138
 
        if ((addr = strtok(buff, "\n \t")) == NULL)
139
 
            continue;
140
 
        if ((host = strtok(NULL, "\n \t")) == NULL) {
141
 
            fprintf(stderr, _("rarp: format error at %s:%u\n"), name, linenr);
142
 
            continue;
143
 
        }
144
 
        if ((hp = gethostbyname(host)) == NULL) {
145
 
            fprintf(stderr, _("rarp: %s: unknown host\n"), host);
146
 
        }
147
 
        if (rarp_set(fd, hp, addr) != 0) {
148
 
            fprintf(stderr, _("rarp: cannot set entry from %s:%u\n"), name, linenr);
149
 
        }
150
 
    }
151
 
 
152
 
    (void) fclose(fp);
153
 
    return 0;
154
 
}
155
 
 
156
 
static int display_cache(void)
157
 
{
158
 
    FILE *fd = proc_fopen(_PATH_PROCNET_RARP);
159
 
    char buffer[256];
160
 
    if (fd == NULL) {
161
 
        if (errno == ENOENT)
162
 
            fputs(_(no_rarp_message), stderr);
163
 
        else
164
 
            perror(_PATH_PROCNET_RARP);
165
 
        return 1;
166
 
    }
167
 
    while (feof(fd) == 0) {
168
 
        if (fgets(buffer, 255, fd))
169
 
            fputs(buffer, stdout);
170
 
    }
171
 
    fclose(fd);
172
 
    return 0;
173
 
}
174
 
 
175
 
static void usage(void)
176
 
{
177
 
    fprintf(stderr, _("Usage: rarp -a                               list entries in cache.\n"));
178
 
    fprintf(stderr, _("       rarp -d <hostname>                    delete entry from cache.\n"));
179
 
    fprintf(stderr, _("       rarp [<HW>] -s <hostname> <hwaddr>    add entry to cache.\n"));
180
 
    fprintf(stderr, _("       rarp -f                               add entries from /etc/ethers.\n"));
181
 
    fprintf(stderr, _("       rarp -V                               display program version.\n\n"));
182
 
 
183
 
    fprintf(stderr, _("  <HW>=Use '-H <hw>' to specify hardware address type. Default: %s\n"), DFLT_HW);
184
 
    fprintf(stderr, _("  List of possible hardware types (which support ARP):\n"));
185
 
    print_hwlist(1); /* 1 = ARPable */
186
 
    exit(E_USAGE);
187
 
}
188
 
 
189
 
#define MODE_DISPLAY   1
190
 
#define MODE_DELETE    2
191
 
#define MODE_SET       3
192
 
#define MODE_ETHERS    4
193
 
 
194
 
static struct option longopts[] =
195
 
{
196
 
    {"version", 0, NULL, 'V'},
197
 
    {"verbose", 0, NULL, 'v'},
198
 
    {"list", 0, NULL, 'a'},
199
 
    {"set", 0, NULL, 's'},
200
 
    {"delete", 0, NULL, 'd'},
201
 
    {"help", 0, NULL, 'h'},
202
 
    {NULL, 0, NULL, 0}
203
 
};
204
 
 
205
 
int main(int argc, char **argv)
206
 
{
207
 
    int result = 0, mode = 0, c, nargs = 0, verbose = 0;
208
 
    char *args[3];
209
 
    struct hostent *hp;
210
 
    int fd;
211
 
 
212
 
#if I18N
213
 
    setlocale (LC_ALL, "");
214
 
    bindtextdomain("net-tools", "/usr/share/locale");
215
 
    textdomain("net-tools");
216
 
#endif
217
 
 
218
 
    /* Get a default hardware type.  */
219
 
    hardware = get_hwtype(DFLT_HW);
220
 
 
221
 
    do {
222
 
        c = getopt_long(argc, argv, "-ht:aHdsVvf", longopts, NULL);
223
 
        switch (c) {
224
 
        case EOF:
225
 
            break;
226
 
        case 'h':
227
 
            usage();
228
 
        case 'V':
229
 
            fprintf(stderr, version_string);
230
 
            exit(E_VERSION);
231
 
            break;
232
 
        case 'v':
233
 
            verbose++;
234
 
            break;
235
 
        case 'a':
236
 
        case 's':
237
 
        case 'd':
238
 
            if (mode) {
239
 
                fprintf(stderr, _("%s: illegal option mix.\n"), argv[0]);
240
 
                usage();
241
 
            } else {
242
 
                mode = (c == 'a' ? MODE_DISPLAY : (c == 'd' ? MODE_DELETE : MODE_SET));
243
 
            }
244
 
            break;
245
 
        case 'f':
246
 
            mode = MODE_ETHERS;
247
 
            break;
248
 
        case 'H':
249
 
        case 't':
250
 
            if (optarg) {
251
 
                hardware = get_hwtype(optarg);
252
 
            } else {
253
 
                usage();
254
 
            }
255
 
            break;
256
 
        case 1:
257
 
            if (nargs == 2) {
258
 
                usage();
259
 
                exit(1);
260
 
            } else {
261
 
                args[nargs++] = optarg;
262
 
            }
263
 
            break;
264
 
        default:
265
 
            usage();
266
 
        }
267
 
    } while (c != EOF);
268
 
 
269
 
    if (hardware == NULL) {
270
 
        fprintf(stderr, _("rarp: %s: unknown hardware type.\n"), optarg);
271
 
        exit(1);
272
 
    }
273
 
    switch (mode) {
274
 
    case 0:
275
 
        usage();
276
 
 
277
 
    case MODE_DISPLAY:
278
 
        if (nargs != (mode - 1)) {
279
 
            usage();
280
 
        }
281
 
        result = display_cache();
282
 
        break;
283
 
 
284
 
    case MODE_DELETE:
285
 
    case MODE_SET:
286
 
        if (nargs != (mode - 1)) {
287
 
            usage();
288
 
        }
289
 
        if ((hp = gethostbyname(args[0])) == NULL) {
290
 
            fprintf(stderr, _("rarp: %s: unknown host\n"), args[0]);
291
 
            exit(1);
292
 
        }
293
 
        if (fd = socket(PF_INET, SOCK_DGRAM, 0), fd < 0) {
294
 
            perror("socket");
295
 
            exit(1);
296
 
        }
297
 
        result = (mode == MODE_DELETE) ? rarp_delete(fd, hp) : rarp_set(fd, hp, args[1]);
298
 
        close(fd);
299
 
        break;
300
 
 
301
 
    case MODE_ETHERS:
302
 
        if (nargs != 0 && nargs != 1)
303
 
            usage();
304
 
        if (fd = socket(PF_INET, SOCK_DGRAM, 0), fd < 0) {
305
 
            perror("socket");
306
 
            exit(1);
307
 
        }
308
 
        result = rarp_file(fd, nargs ? args[0] : _PATH_ETHERS);
309
 
        close(fd);
310
 
 
311
 
    }
312
 
    exit(result);
313
 
}