summaryrefslogtreecommitdiffstats
path: root/isys/inet.c
blob: b31dbc3cbc137686076f394cfba485e6cfca81c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/route.h>
#include <sys/ioctl.h>

#include "inet.h"

int configureNetDevice(struct intfInfo * intf) {
    struct ifreq req;
    int s;
    struct sockaddr_in addr;
    struct in_addr ia;
    char ip[20], nm[20], nw[20], bc[20];
#if 0 /* 2.0 kernels only */
    struct rtentry route;
#endif
	
    addr.sin_family = AF_INET;
    addr.sin_port = 0;

    memcpy(&ia, &intf->ip, sizeof(intf->ip));
    strcpy(ip, inet_ntoa(ia));

    memcpy(&ia, &intf->netmask, sizeof(intf->netmask));
    strcpy(nm, inet_ntoa(ia));

    memcpy(&ia, &intf->broadcast, sizeof(intf->broadcast));
    strcpy(bc, inet_ntoa(ia));

    memcpy(&ia, &intf->network, sizeof(intf->network));
    strcpy(nw, inet_ntoa(ia));

    s = socket(AF_INET, SOCK_DGRAM, 0);
    if (s < 0) {
	perror("socket");
        return 1;
    }
    
    strcpy(req.ifr_name, intf->device);
    req.ifr_flags &= ~(IFF_UP | IFF_RUNNING); /* Take down iface */
    if (ioctl(s, SIOCSIFFLAGS, &req)) {
        perror("SIOCSIFFLAGS");
        close(s);
        return 1;
    }

    addr.sin_port = 0;
    memcpy(&addr.sin_addr, &intf->ip, sizeof(intf->ip));
    memcpy(&req.ifr_addr, &addr, sizeof(addr));
    if (ioctl(s, SIOCSIFADDR, &req)) {
        perror("SIOCSIFADDR");
        close(s);
        return 1;
    }

    memcpy(&addr.sin_addr, &intf->broadcast, sizeof(intf->broadcast));
    memcpy(&req.ifr_broadaddr, &addr, sizeof(addr));
    if (ioctl(s, SIOCSIFBRDADDR, &req)) {
        perror("SIOCSIFNETMASK");
        close(s);
        return 1;
    }

    memcpy(&addr.sin_addr, &intf->netmask, sizeof(intf->netmask));
    memcpy(&req.ifr_netmask, &addr, sizeof(addr));
    if (ioctl(s, SIOCSIFNETMASK, &req)) {
        perror("SIOCSIFNETMASK\n");
        close(s);
        return 1;
    }

    if (intf->isPtp)
        req.ifr_flags = IFF_UP | IFF_RUNNING | IFF_POINTOPOINT | IFF_NOARP;
    else
        req.ifr_flags = IFF_UP | IFF_RUNNING | IFF_BROADCAST;

    if (ioctl(s, SIOCSIFFLAGS, &req)) {
        perror("SIOCSIFFLAGS");
        close(s);
        return 1;
    }

#if 0 /* kernel 2.0 only */
    memset(&route, 0, sizeof(route));
    route.rt_dev = intf->device;
    route.rt_flags = RTF_UP;

    memcpy(&addr.sin_addr, &intf->network, sizeof(intf->netmask));
    memcpy(&route.rt_dst, &addr, sizeof(addr));

    memcpy(&addr.sin_addr, &intf->netmask, sizeof(intf->netmask));
    memcpy(&route.rt_genmask, &addr, sizeof(addr));

    if (ioctl(s, SIOCADDRT, &route)) {
        perror("SIOCADDRT");
        close(s);
        return 1;

    }
#endif
    
    intf->isUp = 1;

    return 0;
}