OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [userland/] [route/] [lib/] [inet.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 745 simons
/*
2
 * lib/inet.c This file contains an implementation of the "INET"
3
 *              support functions for the net-tools.
4
 *              (NET-3 base distribution).
5
 *
6
 * Version:    $Id: inet.c,v 1.1 2002-03-17 19:58:53 simons Exp $
7
 *
8
 * Author:      Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
9
 *              Copyright 1993 MicroWalt Corporation
10
 *
11
 * Modified:
12
 *960113 {1.21} Bernd Eckenfels :       rresolve cache bug.
13
 *960128 {1.22} Bernd Eckenfels :       endian bug in print
14
 *960203 {1.23} Bernd Eckenfels :       net-features support
15
 *960217 {1.24} Bernd Eckenfels :       get_sname
16
 *960219 {1.25} Bernd Eckenfels :       extern int h_errno
17
 *960329 {1.26} Bernd Eckenfels :       resolve 255.255.255.255
18
 *980101 {1.27} Bernd Eckenfels :       resolve raw sockets in /etc/protocols
19
 *990302 {1.28} Phil Blundell   :       add netmask to INET_rresolve
20
 *
21
 *              This program is free software; you can redistribute it
22
 *              and/or  modify it under  the terms of  the GNU General
23
 *              Public  License as  published  by  the  Free  Software
24
 *              Foundation;  either  version 2 of the License, or  (at
25
 *              your option) any later version.
26
 */
27
#include "config.h"
28
 
29
/* FIXME.  Split this file into inet4.c for the IPv4 specific parts
30
   and inet.c for those shared between IPv4 and IPv6.  */
31
 
32
#if HAVE_AFINET || HAVE_AFINET6
33
#include <netinet/in.h>
34
#include <sys/types.h>
35
#include <sys/socket.h>
36
#include <arpa/inet.h>
37
#include <arpa/nameser.h>
38
#include <ctype.h>
39
#include <errno.h>
40
#include <netdb.h>
41
#include <resolv.h>
42
#include <stdlib.h>
43
#include <string.h>
44
#include <stdio.h>
45
#include <unistd.h>
46
#include "version.h"
47
#include "net-support.h"
48
#include "pathnames.h"
49
#include "intl.h"
50
#include "util.h"
51
 
52
extern int h_errno;             /* some netdb.h versions don't export this */
53
 
54
struct addr {
55
    struct sockaddr_in addr;
56
    char *name;
57
    struct addr *next;
58
};
59
 
60
struct service {
61
    int number;
62
    char *name;
63
    struct service *next;
64
};
65
 
66
static struct service *tcp_name = NULL, *udp_name = NULL, *raw_name = NULL;
67
 
68
#if HAVE_AFINET
69
 
70
static struct addr *INET_nn = NULL;     /* addr-to-name cache           */
71
 
72
 
73
static int INET_resolve(char *name, struct sockaddr_in *sin)
74
{
75
    struct hostent *hp;
76
    struct netent *np;
77
 
78
    /* Grmpf. -FvK */
79
    sin->sin_family = AF_INET;
80
    sin->sin_port = 0;
81
 
82
    /* Default is special, meaning 0.0.0.0. */
83
    if (!strcmp(name, "default")) {
84
        sin->sin_addr.s_addr = INADDR_ANY;
85
        return (1);
86
    }
87
    /* Look to see if it's a dotted quad. */
88
    if (inet_aton(name, &sin->sin_addr)) {
89
        return 0;
90
    }
91
#ifdef EMBED
92
    return(-1);
93
#else
94
    /* Try the NETWORKS database to see if this is a known network. */
95
    if ((np = getnetbyname(name)) != (struct netent *) NULL) {
96
        sin->sin_addr.s_addr = htonl(np->n_net);
97
        strcpy(name, np->n_name);
98
        return 1;
99
    }
100
#ifdef DEBUG
101
    res_init();
102
    _res.options |= RES_DEBUG;
103
#endif
104
 
105
    if ((hp = gethostbyname(name)) == (struct hostent *) NULL) {
106
        errno = h_errno;
107
        return -1;
108
    }
109
    memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0], hp->h_length);
110
    strcpy(name, hp->h_name);
111
    return 0;
112
#endif
113
}
114
 
115
 
116
static int INET_rresolve(char *name, struct sockaddr_in *sin, int numeric,
117
                         unsigned int netmask)
118
{
119
    struct hostent *ent;
120
    struct netent *np;
121
    struct addr *pn;
122
    unsigned long ad, host_ad;
123
 
124
    /* Grmpf. -FvK */
125
    if (sin->sin_family != AF_INET) {
126
#ifdef DEBUG
127
        fprintf(stderr, _("rresolve: unsupport address family %d !\n"), sin->sin_family);
128
#endif
129
        errno = EAFNOSUPPORT;
130
        return (-1);
131
    }
132
    ad = (unsigned long) sin->sin_addr.s_addr;
133
    if (ad == INADDR_ANY) {
134
        if ((numeric & 0x7FFF) == 0) {
135
            if (numeric & 0x8000)
136
                strcpy(name, "default");
137
            else
138
                strcpy(name, "*");
139
            return (0);
140
        }
141
    }
142
    if (numeric & 0x7FFF) {
143
        strcpy(name, inet_ntoa(sin->sin_addr));
144
        return (0);
145
    }
146
#if 0
147
    INET_nn = NULL;
148
#endif
149
    pn = INET_nn;
150
    while (pn != NULL) {
151
        if (pn->addr.sin_addr.s_addr == ad) {
152
            strcpy(name, pn->name);
153
            return (0);
154
        }
155
        pn = pn->next;
156
    }
157
 
158
    host_ad = ntohl(ad);
159
    np = NULL;
160
    ent = NULL;
161
#ifndef EMBED
162
    if ((ad & (~ netmask)) != 0) {
163
        ent = gethostbyaddr((char *) &ad, 4, AF_INET);
164
        if (ent != NULL)
165
            strcpy(name, ent->h_name);
166
    } else {
167
        np = getnetbyaddr(host_ad, AF_INET);
168
        if (np != NULL) {
169
            strcpy(name, np->n_name);
170
        }
171
    }
172
#endif
173
    if ((ent == NULL) && (np == NULL)) {
174
        strcpy(name, inet_ntoa(sin->sin_addr));
175
    }
176
    pn = (struct addr *) malloc(sizeof(struct addr));
177
    pn->addr = *sin;
178
    pn->next = INET_nn;
179
    pn->name = (char *) malloc(strlen(name) + 1);
180
    strcpy(pn->name, name);
181
    INET_nn = pn;
182
 
183
    return (0);
184
}
185
 
186
 
187
static void INET_reserror(char *text)
188
{
189
#ifdef EMBED
190
    printf(text);
191
#else
192
    herror(text);
193
#endif
194
}
195
 
196
 
197
/* Display an Internet socket address. */
198
static char *INET_print(unsigned char *ptr)
199
{
200
    return (inet_ntoa((*(struct in_addr *) ptr)));
201
}
202
 
203
 
204
/* Display an Internet socket address. */
205
static char *INET_sprint(struct sockaddr *sap, int numeric)
206
{
207
    static char buff[128];
208
 
209
    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
210
        return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff));
211
    if (INET_rresolve(buff, (struct sockaddr_in *) sap, numeric,
212
                      0xffffff00) != 0)
213
        return (NULL);
214
    return (buff);
215
}
216
 
217
char *INET_sprintmask(struct sockaddr *sap, int numeric,
218
                      unsigned int netmask)
219
{
220
    static char buff[128];
221
 
222
    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
223
        return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff));
224
    if (INET_rresolve(buff, (struct sockaddr_in *) sap, numeric,
225
                      netmask) != 0)
226
        return (NULL);
227
    return (buff);
228
}
229
 
230
 
231
static int INET_getsock(char *bufp, struct sockaddr *sap)
232
{
233
    char *sp = bufp, *bp;
234
    unsigned int i;
235
    unsigned val;
236
    struct sockaddr_in *sin;
237
 
238
    sin = (struct sockaddr_in *) sap;
239
    sin->sin_family = AF_INET;
240
    sin->sin_port = 0;
241
 
242
    val = 0;
243
    bp = (char *) &val;
244
    for (i = 0; i < sizeof(sin->sin_addr.s_addr); i++) {
245
        *sp = toupper(*sp);
246
 
247
        if ((*sp >= 'A') && (*sp <= 'F'))
248
            bp[i] |= (int) (*sp - 'A') + 10;
249
        else if ((*sp >= '0') && (*sp <= '9'))
250
            bp[i] |= (int) (*sp - '0');
251
        else
252
            return (-1);
253
 
254
        bp[i] <<= 4;
255
        sp++;
256
        *sp = toupper(*sp);
257
 
258
        if ((*sp >= 'A') && (*sp <= 'F'))
259
            bp[i] |= (int) (*sp - 'A') + 10;
260
        else if ((*sp >= '0') && (*sp <= '9'))
261
            bp[i] |= (int) (*sp - '0');
262
        else
263
            return (-1);
264
 
265
        sp++;
266
    }
267
    sin->sin_addr.s_addr = htonl(val);
268
 
269
    return (sp - bufp);
270
}
271
 
272
static int INET_input(int type, char *bufp, struct sockaddr *sap)
273
{
274
    switch (type) {
275
    case 1:
276
        return (INET_getsock(bufp, sap));
277
    default:
278
        return (INET_resolve(bufp, (struct sockaddr_in *) sap));
279
    }
280
}
281
 
282
static int INET_getnetmask(char *adr, struct sockaddr *m, char *name)
283
{
284
    struct sockaddr_in *mask = (struct sockaddr_in *) m;
285
    char *slash, *end;
286
    int prefix;
287
 
288
    if ((slash = strchr(adr, '/')) == NULL)
289
        return 0;
290
 
291
    *slash++ = '\0';
292
    prefix = strtoul(slash, &end, 0);
293
    if (*end != '\0')
294
        return -1;
295
 
296
    if (name) {
297
        sprintf(name, "/%d", prefix);
298
    }
299
    mask->sin_family = AF_INET;
300
    mask->sin_addr.s_addr = htonl(~(0xffffffffU >> prefix));
301
    return 1;
302
}
303
 
304
 
305
struct aftype inet_aftype =
306
{
307
    "inet", NULL, /*"DARPA Internet", */ AF_INET, sizeof(unsigned long),
308
    INET_print, INET_sprint, INET_input, INET_reserror,
309
    NULL /*INET_rprint */ , NULL /*INET_rinput */ ,
310
    INET_getnetmask,
311
    -1,
312
    NULL
313
};
314
 
315
#endif                          /* HAVE_AFINET */
316
 
317
static void add2list(struct service **namebase, struct service *item)
318
{
319
    if (*namebase == NULL) {
320
        *namebase = item;
321
        item->next = NULL;
322
    } else {
323
        item->next = *namebase;
324
        *namebase = item;
325
    }
326
}
327
 
328
 
329
static struct service *searchlist(struct service *servicebase, int number)
330
{
331
    struct service *item;
332
 
333
    for (item = servicebase; item != NULL; item = item->next) {
334
        if (item->number == number)
335
            return (item);
336
    }
337
    return (NULL);
338
}
339
 
340
 
341
#ifndef EMBED
342
static int read_services(void)
343
{
344
    struct servent *se;
345
    struct protoent *pe;
346
    struct service *item;
347
 
348
    setservent(1);
349
    while ((se = getservent())) {
350
        /* Allocate a service entry. */
351
        item = (struct service *) malloc(sizeof(struct service));
352
        if (item == NULL)
353
            perror("netstat");
354
        item->name = strdup(se->s_name);
355
        item->number = se->s_port;
356
 
357
        /* Fill it in. */
358
        if (!strcmp(se->s_proto, "tcp")) {
359
            add2list(&tcp_name, item);
360
        } else if (!strcmp(se->s_proto, "udp")) {
361
            add2list(&udp_name, item);
362
        } else if (!strcmp(se->s_proto, "raw")) {
363
            add2list(&raw_name, item);
364
        }
365
    }
366
    endservent();
367
    setprotoent(1);
368
    while ((pe = getprotoent())) {
369
        /* Allocate a service entry. */
370
        item = (struct service *) malloc(sizeof(struct service));
371
        if (item == NULL)
372
            perror("netstat");
373
        item->name = strdup(pe->p_name);
374
        item->number = htons(pe->p_proto);
375
        add2list(&raw_name, item);
376
    }
377
    endprotoent();
378
    return (0);
379
}
380
#endif
381
 
382
 
383
char *get_sname(int socknumber, char *proto, int numeric)
384
{
385
    static char buffer[64], init = 0;
386
    struct service *item;
387
 
388
    if (socknumber == 0)
389
        return ("*");
390
    if (numeric) {
391
        sprintf(buffer, "%d", ntohs(socknumber));
392
        return (buffer);
393
    }
394
#ifndef EMBED
395
    if (!init) {
396
        (void) read_services();
397
        init = 1;
398
    }
399
#endif
400
    buffer[0] = '\0';
401
    if (!strcmp(proto, "tcp")) {
402
        if ((item = searchlist(tcp_name, socknumber)) != NULL)
403
            sprintf(buffer, "%s", item->name);
404
    } else if (!strcmp(proto, "udp")) {
405
        if ((item = searchlist(udp_name, socknumber)) != NULL)
406
            sprintf(buffer, "%s", item->name);
407
    } else if (!strcmp(proto, "raw")) {
408
        if ((item = searchlist(raw_name, socknumber)) != NULL)
409
            sprintf(buffer, "%s", item->name);
410
 
411
    }
412
    if (!buffer[0])
413
        sprintf(buffer, "%d", ntohs(socknumber));
414
    return (buffer);
415
}
416
 
417
#endif                          /* HAVE_AFINET || HAVE_AFINET6 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.