~ubuntu-branches/ubuntu/karmic/vzctl/karmic

« back to all changes in this revision

Viewing changes to src/ndsend.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2007-04-10 18:08:16 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070410180816-0uuzj9fnna7gmzxv
Tags: 3.0.16-4
Etch has been released which means that this version can be uploaded
to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2000-2007 SWsoft. All rights reserved.
 
3
 *
 
4
 * This code is public domain.
 
5
 *
 
6
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
7
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
8
 */
 
9
 
 
10
#include <stdio.h>
 
11
#include <ctype.h>
 
12
#include <stdlib.h>
 
13
#include <string.h>
 
14
#include <errno.h>
 
15
#include <sys/types.h>
 
16
 
 
17
#include <netdb.h>
 
18
#include <sys/socket.h>
 
19
#include <netinet/in.h>
 
20
#include <linux/types.h>
 
21
#include <linux/if.h>
 
22
#include <netinet/icmp6.h>
 
23
 
 
24
#include <sys/ioctl.h>
 
25
#include <arpa/inet.h>
 
26
 
 
27
#include <getopt.h>
 
28
#include <unistd.h>
 
29
#include <signal.h>
 
30
 
 
31
#define EXC_OK 0
 
32
#define EXC_USAGE       1
 
33
#define EXC_SYS         2
 
34
#define EXC_RECV        3
 
35
#define EXC_NORECV      4
 
36
 
 
37
char* iface = NULL;
 
38
 
 
39
struct in6_addr src_ipaddr;
 
40
int ifindex;
 
41
__u8 real_hwaddr[6];
 
42
 
 
43
struct nd_packet {
 
44
        __u8            icmp6_type;
 
45
        __u8            icmp6_code;
 
46
        __u16           icmp6_cksum;
 
47
 
 
48
        __u32           reserved:5,
 
49
                        override:1,
 
50
                        solicited:1,
 
51
                        router:1,
 
52
                        reserved2:24;
 
53
        struct in6_addr target;
 
54
        __u8            otype;
 
55
        __u8            ospace;
 
56
        __u8            obits[6];
 
57
};
 
58
 
 
59
int init_device_addresses(int sock, const char* device)
 
60
{
 
61
        struct ifreq ifr;
 
62
 
 
63
        memset(&ifr, 0, sizeof(ifr));
 
64
        strncpy(ifr.ifr_name, device, IFNAMSIZ-1);
 
65
 
 
66
        if (ioctl(sock, SIOCGIFINDEX, &ifr) != 0) {
 
67
                fprintf(stderr, "unknown iface %s : %m", device);
 
68
                return -1;
 
69
        }
 
70
        ifindex = ifr.ifr_ifindex;
 
71
 
 
72
        /* get interface HW address */
 
73
        if (ioctl(sock, SIOCGIFHWADDR, &ifr) != 0) {
 
74
                fprintf(stderr, "can't get iface '%s' HW address : %m", device);
 
75
                return -1;
 
76
        }
 
77
        memcpy(real_hwaddr, ifr.ifr_hwaddr.sa_data, 6);
 
78
 
 
79
        return 0;
 
80
}
 
81
 
 
82
int sock;
 
83
struct nd_packet pkt;
 
84
 
 
85
void create_nd_packet(struct nd_packet* pkt)
 
86
{
 
87
        pkt->icmp6_type = ND_NEIGHBOR_ADVERT;
 
88
        pkt->icmp6_code = 0;
 
89
        pkt->icmp6_cksum = 0;
 
90
        pkt->reserved = 0;
 
91
        pkt->override = 1;
 
92
        pkt->solicited = 0;
 
93
        pkt->router = 0;
 
94
        pkt->reserved = 0;
 
95
        memcpy(&pkt->target, &src_ipaddr, 16);
 
96
        pkt->otype = ND_OPT_SOURCE_LINKADDR; 
 
97
        pkt->ospace = 1;
 
98
        memcpy(&pkt->obits, real_hwaddr, 6);
 
99
}
 
100
 
 
101
void sender(void)
 
102
{
 
103
        struct sockaddr_in6 to;
 
104
 
 
105
        to.sin6_family = AF_INET6;
 
106
        to.sin6_port = 0;
 
107
        ((__u32*)&to.sin6_addr)[0] = htonl(0xFF020000);
 
108
        ((__u32*)&to.sin6_addr)[1] = 0;
 
109
        ((__u32*)&to.sin6_addr)[2] = 0;
 
110
        ((__u32*)&to.sin6_addr)[3] = htonl(0x1);
 
111
        to.sin6_scope_id = ifindex;
 
112
 
 
113
        if (sendto(sock, &pkt, sizeof(pkt), 0,
 
114
            (struct sockaddr*) &to, sizeof(to)) < 0) {
 
115
                fprintf(stderr, "sendto : %m");
 
116
                exit(EXC_SYS);
 
117
        }
 
118
}
 
119
 
 
120
int main(int argc,char** argv)
 
121
{
 
122
        int value;
 
123
 
 
124
        if (inet_pton(AF_INET6, argv[1], &src_ipaddr) <= 0)
 
125
                return -1;
 
126
        iface = argv[2];
 
127
 
 
128
        sock = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
 
129
        if (sock < 0) {
 
130
                fprintf(stderr, "socket : %m");
 
131
                exit(EXC_SYS);
 
132
        }
 
133
 
 
134
        if (init_device_addresses(sock, iface) < 0)
 
135
                exit(EXC_SYS);
 
136
 
 
137
        value = 255;
 
138
        setsockopt (sock, SOL_IPV6, IPV6_MULTICAST_HOPS,
 
139
                    &value, sizeof (value));
 
140
 
 
141
        create_nd_packet(&pkt);
 
142
        sender();
 
143
        exit(EXC_OK);
 
144
}