-
Notifications
You must be signed in to change notification settings - Fork 34
/
iptvscanner.cpp
executable file
·153 lines (138 loc) · 4.03 KB
/
iptvscanner.cpp
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
*
* *iptvscanner.cpp - 多播的客户端
*
* */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <string.h>
#include <pcap.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
using namespace std;
char nicname[1024] = {0};
int iptvscan(unsigned int ip)
{
char errBuf[PCAP_ERRBUF_SIZE];
int s; /*套接字文件描述符*/
int err = -1;
ip = htonl(ip);
s = socket(AF_INET, SOCK_DGRAM, 0); /*建立套接字*/
if (s == -1)
{
return -1;
}
struct ip_mreq mreq; /*加入多播组*/
mreq.imr_multiaddr.s_addr = ip; /*多播地址*/
mreq.imr_interface.s_addr = htonl(INADDR_ANY); /*网络接口为默认*/
err = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&mreq, sizeof(mreq));
if (err < 0)
{
return -1;
}
pcap_t *device = pcap_open_live(nicname, 65535, 1, 1, errBuf); //1ms超时,下边会留出时间填充数据包
if (!device)
{
cout << "error: pcap_open_live():" << errBuf << endl;
close(s);
return -1;
}
char strfilter[64] = "udp and host ";
char *strip = strfilter + strlen("udp and host ");
inet_ntop(AF_INET, &ip, strip, 16);
/* construct a filter */
struct bpf_program filter;
pcap_compile(device, &filter, strfilter, 1, 0);
pcap_setfilter(device, &filter);
usleep(150000);
struct pcap_pkthdr packet;
const u_char *pktStr = pcap_next(device, &packet);
if (pktStr)
{
struct udphdr *udphdr = NULL;
udphdr = (struct udphdr *)(pktStr + 14 + 20);
#ifdef __linux
printf("#EXTINF:-1,%s:%d\nrtp://%s:%d\n", strip, ntohs(udphdr->dest), strip, ntohs(udphdr->dest));
#elif __APPLE__
printf("#EXTINF:-1,%s:%d\nrtp://%s:%d\n", strip, ntohs(udphdr->uh_dport), strip, ntohs(udphdr->uh_dport));
#endif
}
pcap_close(device);
err = setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char *)&mreq, sizeof(mreq));
if (err < 0)
{
close(s);
return -1;
}
close(s);
return 0;
}
int main(int argc, char *argv[])
{
pcap_if_t *alldevs;
int i = 0;
char errbuf[PCAP_ERRBUF_SIZE];
int inum;
if (argc != 3)
{
cout << "usage:" << endl
<< "\t" << argv[0] <<" \"start of ip\" \"end of ip\" " << endl;
cout << "\t eg.. " << argv[0] << " 239.3.1.1 239.3.1.254" << endl;
return -1;
}
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
/* 打印列表 */
pcap_if_t *d;
for (d = alldevs; d; d = d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
if (i == 0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return -1;
}
cout << "Enter the interface number (1-%d):";
cin >> inum;
if (inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
cout << "#EXTM3U name=\"bj-unicom-iptv\"" << endl;
/* 跳转到选中的适配器 */
for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++)
;
strncpy(nicname, d->name, sizeof(nicname));
pcap_freealldevs(alldevs);
unsigned int ipstart = 0, ipend = 0;
inet_pton(AF_INET, argv[1], &ipstart);
inet_pton(AF_INET, argv[2], &ipend);
ipstart = ntohl(ipstart);
ipend = ntohl(ipend);
for (int ip = ipstart; ip <= ipend; ip++)
{
iptvscan(ip);
}
}