2012-04-03 15 views
5

में है मैं आईपी पते (ipNumeric) अहस्ताक्षरित ints के रूप में जमा है और सबनेट के साथ एक मेज बी (subnetNumeric) के साथ एक मेज एक है:जांच करें कि आईपी सबनेट

INET_NTOA(ipNumeric) = 192.168.0.1 
INET_NTOA(subnetNumeric) = 192.168.0.0 

मैं अगर यह आईपी जांच करना चाहते हैं एक सबनेट का सदस्य है।

सबनेट क्लास ए, बी और सी

हैं

इस मक्खी पर MySQL में उचित समय में क्या करना संभव है या सबनेट पर्वतमाला precomputed किया जाना चाहिए?

उत्तर

11

निश्चित रूप से, यह करने योग्य है। विचार यह है कि हम सबसे महत्वपूर्ण बिट्स को 1 तक सेट करके सबनेट मास्क की गणना करते हैं, जितना कि सबनेट क्लास द्वारा निर्धारित किया गया है। कक्षा सी के लिए, यह

SELECT -1 << 8; 

फिर, और आपके पास आईपी पते के साथ सबनेट मास्क होगा; यदि आईपी सबनेट के अंदर है, तो परिणाम सबनेट पते के बराबर होना चाहिए - मानक नेटवर्किंग सामान।

SELECT (-1 << 8) & INET_ATON("192.168.0.1") = INET_ATON("192.168.0.0"); 

अपडेट:: तो हम अंत हाँ, यह नेटवर्क वर्ग या सबनेट मास्क (जो बराबर जानकारी है) पता करने के लिए आवश्यक है। अगर आपके पास यह जानकारी नहीं है तो इस बात पर विचार करें कि आप उस मामले को कैसे संभालें जहां सबनेट X.Y.0.0 है। क्या यह X.Y.0.0/16 या X.Y.0.0/8 है जहां तीसरा ऑक्टेट 0 होने के लिए होता है? जानने का कोई तरीका नहीं है।

आप सबनेट मास्क जानते हैं तो फिर क्वेरी

SELECT (-1 << (33 - INSTR(BIN(INET_ATON("255.255.255.0")), "0"))) & 
     INET_ATON("192.168.0.1") = INET_ATON("192.168.0.0"); 
+0

धन्यवाद, लेकिन इस सबनेट वर्ग जानने पर निर्भर है? – matiasf

+0

@matiasf: यह है। अद्यतन पर एक नज़र डालें। – Jon

+0

ग्रेट उत्तर - लेकिन आईपीवी 6 के बारे में क्या? क्या यह भी संभव है? – TSG

0

पहले टेबल परीक्षण का समर्थन करने के लिए बनाने के रूप में लिखा जा सकता है।

CREATE TABLE a (ipNumeric INT UNSIGNED); 
INSERT INTO a (ipNumeric) VALUES(INET_ATON("172.16.40.101")); 
INSERT INTO a (ipNumeric) VALUES(INET_ATON("192.168.1.12")); 
INSERT INTO a (ipNumeric) VALUES(INET_ATON("10.1.5.51")); 
INSERT INTO a (ipNumeric) VALUES(INET_ATON("10.7.1.78"));  
CREATE TABLE b (subnetNumeric INT UNSIGNED); 
INSERT INTO b (subnetNumeric) VALUES (INET_ATON("192.168.0.0")); 
INSERT INTO b (subnetNumeric) VALUES (INET_ATON("10.1.0.0")); 
INSERT INTO b (subnetNumeric) VALUES (INET_ATON("172.16.0.0")); 

अब कुछ चुने हुए खोज पर पता & मुखौटा = सबनेट आधारित तालिकाओं के बीच से मेल खाता है। यहां हम कक्षा बी सबनेट्स (255.255.0.0) मानते हैं। बिट-शिफ्ट करने की कोई आवश्यकता नहीं है क्योंकि हम INET_ATON() फ़ंक्शन का उपयोग कर सकते हैं।

SELECT INET_NTOA(a.ipNumeric),INET_NTOA(b.subnetNumeric) FROM a,b 
     WHERE (a.ipNumeric & INET_ATON("255.255.0.0")) = b.subnetNumeric; 

+------------------------+----------------------------+ 
| INET_NTOA(a.ipNumeric) | INET_NTOA(b.subnetNumeric) | 
+------------------------+----------------------------+ 
| 192.168.1.12   | 192.168.0.0    | 
| 10.1.5.51    | 10.1.0.0     | 
| 172.16.40.101   | 172.16.0.0     | 
+------------------------+----------------------------+ 
0

यह हमारा MySQL फ़ंक्शन है जिसका उपयोग हम करते हैं।

DELIMITER $$ 
DROP FUNCTION IF EXISTS `ip_in_subnet_mask`$$ 
CREATE DEFINER=`root`@`%` FUNCTION `ip_in_subnet_mask`(ip VARCHAR(20), subnet VARCHAR(20), netmask VARCHAR(20)) RETURNS TINYINT(1) 
    DETERMINISTIC 
BEGIN 
    RETURN (INET_ATON(ip) & INET_ATON(netmask)) = INET_ATON(subnet); 
END$$ 
DELIMITER ; 

उदा। सभी पंक्तियों का पता लगाएं जहां t.ip रेंज 192.168.0.x जहां 0 < = एक्स < = 255

SELECT * 
FROM t 
WHERE 
    ip_in_subnet_mask(t.ip, "192.168.0.0", "255.255.255.0") 
0

मैं जब पतों तारों के रूप में जमा हो जाती है के लिए एक समाधान है में है। तो यदि आप अपने एल्गोरिदम के उस हिस्से को बनाना चाहते हैं, तो आप यहां मेरे समाधान का उपयोग कर सकते हैं।

यह थोड़ा मुश्किल है, खासकर आईपीवी 6 के लिए। आईपीवी 6 में वैकल्पिक रूप से संपीड़ित सेगमेंट हो सकते हैं, जैसे 1 :: 1 जो 1: 0: 0: 0: 0: 0: 0: 1 के बराबर है, जो मुख्य कारण है कि यह मुश्किल है।

The IPAddress Java library किसी दिए गए सबनेट में पते खोजने के लिए mysql SQL उत्पन्न करेगा। लिंक इस समस्या का अधिक विस्तार से वर्णन करता है। अस्वीकरण: मैं प्रोजेक्ट मैनेजर हूं।

मूल एल्गोरिदम सबनेट पते का नेटवर्क अनुभाग लेना है, फिर उस खंड के प्रत्येक संस्करण को लें (उदाहरण के लिए ऊपर दो स्ट्रिंग पूर्ण पते 1 :: 1 के रूप हैं), फिर सेगमेंट की संख्या गिनें विभाजक, फिर मेल खाने वाले पते पर एक MySQL प्रतिलिपि करें, लेकिन मेल खाने वाले पते में कुल विभाजक भी गिनें।

public static void main(String[] args) throws IPAddressStringException { 
    System.out.println(getSearchSQL("columnX", "1.2.3.4/16")); 
    System.out.println(getSearchSQL("columnX", "1:2:3:4:5:6:7:8/64")); 
    System.out.println(getSearchSQL("columnX", "1::8/64")); 
} 

static String getSearchSQL(String expression, String ipAddressStr) throws IPAddressStringException { 
    IPAddressString ipAddressString = new IPAddressString(ipAddressStr); 
    IPAddress ipAddress = ipAddressString.toAddress(); 
    IPAddressSection networkPrefix = ipAddress.getNetworkSection(ipAddress.getNetworkPrefixLength(), false); 
    StringBuilder sql = new StringBuilder("Select rows from table where "); 
    networkPrefix.getStartsWithSQLClause(sql, expression); 
    return sql.toString(); 
} 

ouptut:

यहाँ नमूना कोड है

Select rows from table where (substring_index(columnX,'.',2) = '1.2') 
Select rows from table where (substring_index(columnX,':',4) = '1:2:3:4') 
Select rows from table where ((substring_index(columnX,':',4) = '1:0:0:0') OR ((substring_index(columnX,':',2) = '1:') AND (LENGTH (columnX) - LENGTH(REPLACE(columnX, ':', '')) <= 5))) 
संबंधित मुद्दे